xterm-399/0000755000000000000000000000000015012470763011242 5ustar rootrootxterm-399/resize.man0000644000000000000000000001730414550063146013244 0ustar rootroot.\" $XTermId: resize.man,v 1.40 2024/01/11 22:06:30 tom Exp $ .\" .\" Copyright 1998-2023,2024 by Thomas E. Dickey .\" .\" All Rights Reserved .\" .\" Permission is hereby granted, free of charge, to any person obtaining a .\" copy of this software and associated documentation files (the .\" "Software"), to deal in the Software without restriction, including .\" without limitation the rights to use, copy, modify, merge, publish, .\" distribute, sublicense, and/or sell copies of the Software, and to .\" permit persons to whom the Software is furnished to do so, subject to .\" the following conditions: .\" .\" The above copyright notice and this permission notice shall be included .\" in all copies or substantial portions of the Software. .\" .\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS .\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF .\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. .\" IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY .\" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, .\" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE .\" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .\" .\" Except as contained in this notice, the name(s) of the above copyright .\" holders shall not be used in advertising or otherwise to promote the .\" sale, use or other dealings in this Software without prior written .\" authorization. .\" .\" updated by Thomas E. Dickey for XFree86, 1998-2006. .\" .ds N Resize .ds n resize . .TH RESIZE 1 "__app_date__" "__app_version__" "X Window System" .\" .ie n .ds CW R .el \{ .ie \n(.g .ds CW CR .el .ds CW CW .\} . .ie \n(.g \{\ .ds `` \(lq .ds '' \(rq .ds ' \(aq .\} .el \{\ .ie t .ds `` `` .el .ds `` "" .ie t .ds '' '' .el .ds '' "" .ie t .ds ' \(aq .el .ds ' ' .\} .de bP .ie n .IP \(bu 4 .el .IP \(bu 2 .. .de NE .fi .ft R .ie n .in -4 .el .in -2 .. .de NS .ie n .sp .el .sp .5 .ie n .in +4 .el .in +2 .nf .ft \*(CW .. .SH NAME resize \- set environment and terminal settings to current xterm window size .SH SYNOPSIS .B \*n [ \fB\-v\fP | \fB\-u\fP | \fB\-c\fP ] [ \fB\-s\fP [ \fIrow col\fP ] ] .SH DESCRIPTION .I \*N prints a shell command for setting the appropriate environment variables to indicate the current size of \fIxterm\fP window from which the command is run. .PP .I \*N determines the command through several steps: .bP first, it finds the name of the user's shell program. It uses the \fBSHELL\fP variable if set, otherwise it uses the user's data from /etc/passwd. .bP then it decides whether to use Bourne shell syntax or C-Shell syntax. It uses a built-in table of known shells, which can be overridden by the \fB\-u\fP and \fB\-c\fP options. .bP then \fI\*n\fP asks the operating system for the terminal settings. This is the same information which can be manipulated using \fIstty\fP. .bP then \fI\*n\fP asks the terminal for its size in characters. Depending on whether the "\fB\-s\fP option is given, \fI\*n\fP uses a different escape sequence to ask for this information. .bP at this point, \fI\*n\fP attempts to update the terminal settings to reflect the terminal window's size in pixels: .RS .bP if the \fB\-s\fP option is used, \fI\*n\fP then asks the terminal for its size in pixels. .bP otherwise, \fI\*n\fP asks the operating system for the information and updates that after ensuring that the window's dimensions are a multiple of the character height and width. .bP in either case, the updated terminal settings are done using a different system call than used for \fIstty\fP. .RE .bP then \fI\*n\fP updates the terminal settings to reflect any altered values such as its size in rows or columns. This affects the values shown by \fIstty\fP. .bP finally, \fI\*n\fP generates shell commands for setting the environment variables, and writes that to the standard output. .SH OPTIONS The following options may be used with \fI\*n\fP: .TP 8 .B \-c This option indicates that C shell commands should be generated even if the user's current shell does not appear to use C shell syntax. .TP 8 .B \-s \fR[\fIrows columns\fP] This option indicates that Sun console escape sequences will be used instead of the VT100-style \fIxterm\fP escape codes. If \fIrows\fP and \fIcolumns\fP are given, \fI\*n\fP will ask the \fIxterm\fP to resize itself using those values. .IP Both of the escape sequences used for this option (first to obtain the window size and second to modify it) are subject to \fIxterm\fP's \fBallowWindowOps\fP resource setting. The window manager may also choose to disallow the change. .IP The VT100-style escape sequence used to determine the screen size always works for VT100-compatible terminals. VT100s have no corresponding way to modify the screensize. .TP 8 .B \-u This option indicates that Bourne shell commands should be generated even if the user's current shell does not appear to use Bourne shell syntax. .TP 8 .B \-v This causes \fI\*n\fP to print a version number to the standard output, and then exit. .PP Note that the Sun console escape sequences are recognized by XFree86 \fIxterm\fP and by \fIdtterm\fP. The \fI\*n\fP program may be installed as \fIsunsize\fP, which causes makes it assume the \fB\-s\fP option. .PP The \fIrows\fP and \fIcolumns\fP arguments must appear last; though they are normally associated with the \fB\-s\fP option, they are parsed separately. .SH ENVIRONMENT .TP 15 SHELL Unless overridden by the \fB\-c\fP option, \fI\*n\fP determines the user's current shell by .RS .bP first checking if \fB$SHELL\fP is set, and using that, .bP otherwise \fI\*n\fP looks in the password file (/etc/passwd). .RE .IP Generally Bourne-shell variants (including \fIksh\fP) do not modify \fB$SHELL\fP, so it is possible for \fI\*n\fP to be confused if one runs \fI\*n\fP from a Bourne shell spawned from a C shell. .IP After determining the user's shell, \fI\*n\fP checks the shell's name against a table of known shell names. If it does not find the name in its table, \fI\*n\fP will use C shell syntax for the generated commands to set environment variables. .TP 15 TERM .IR \*N 's generated shell command sets this to "__default_termname__" if not already set. .TP 15 TERMCAP .IR \*N 's generated shell command sets this variable on systems using termcap, e.g., when \fI\*n\fP is linked with the \fItermcap\fP library rather than a \fIterminfo\fP library. The latter does not provide the complete text for a termcap entry. .TP 15 COLUMNS, LINES .IR \*N 's generated shell command sets these variables on systems using terminfo. Many applications (including the curses library) use those variables when set to override their screensize. .SH FILES .TP 15 /etc/termcap for the base termcap entry to modify. .TP 15 ~/.cshrc user's alias for the command. .SH EXAMPLES For \fI\*n\fP's output to take effect, \fI\*n\fP must either be evaluated as part of the command line (usually done with a shell alias or function) or else redirected to a file which can then be read in. From the C shell (usually known as \fI/bin/csh\fP), the following alias could be defined in the user's \fI.cshrc\fP: .NS % alias rs \*'set noglob; eval \`\*n\`\*' .NE .PP After resizing the window, the user would type: .NS % rs .NE .PP Users of versions of the Bourne shell (usually known as \fI/bin/sh\fP) that don't have command functions will need to send the output to a temporary file and then read it back in with the \*(``.\*('' command: .NS $ \*n > /tmp/out $ .\0/tmp/out .NE .SH AUTHORS Mark Vandevoorde (MIT-Athena), Edward Moy (Berkeley) .br Thomas Dickey (invisible-island.net). .br Copyright (c) 1984, 1985 by X Consortium .br See .IR X (__miscmansuffix__) for a complete copyright notice. .SH "SEE ALSO" use_env(3x) .br csh(1), stty(1), tset(1) .br xterm(__mansuffix__) xterm-399/tabs.c0000644000000000000000000001224313563107545012345 0ustar rootroot/* $XTermId: tabs.c,v 1.47 2019/11/13 23:19:01 tom Exp $ */ /* * Copyright 2000-2018,2019 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * * * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* tabs.c */ #include #include #define TAB_INDEX(n) ((n) >> TAB_BITS_SHIFT) #define TAB_MASK(n) (1U << ((n) & (TAB_BITS_WIDTH-1))) #define SET_TAB(tabs,n) UIntSet(tabs[TAB_INDEX(n)], TAB_MASK(n)) #define CLR_TAB(tabs,n) UIntClr(tabs[TAB_INDEX(n)], TAB_MASK(n)) #define TST_TAB(tabs,n) (tabs[TAB_INDEX(n)] & (unsigned) TAB_MASK(n)) /* * places tabstops at only every 8 columns */ void TabReset(Tabs tabs) { int i; TabZonk(tabs); for (i = 0; i < MAX_TABS; i += 8) TabSet(tabs, i); } /* * places a tabstop at col */ void TabSet(Tabs tabs, int col) { if (OkTAB(col)) { SET_TAB(tabs, col); } } /* * clears a tabstop at col */ void TabClear(Tabs tabs, int col) { if (OkTAB(col)) { CLR_TAB(tabs, col); } } /* * returns the column of the next tabstop * (or MAX_TABS - 1 if there are no more). * A tabstop at col is ignored. */ static int TabNext(XtermWidget xw, Tabs tabs, int col) { TScreen *screen = TScreenOf(xw); if (screen->curses && screen->do_wrap && (xw->flags & WRAPAROUND)) { xtermIndex(xw, 1); set_cur_col(screen, 0); col = 0; ResetWrap(screen); } for (++col; col < MAX_TABS; ++col) if (TST_TAB(tabs, col)) return (col); return (MAX_TABS - 1); } /* * returns the column of the previous tabstop * (or 0 if there are no more). * A tabstop at col is ignored. */ static int TabPrev(Tabs tabs, int col) { for (--col; col >= 0; --col) if ((col < MAX_TABS) && TST_TAB(tabs, col)) return (col); return (0); } /* * Tab to the next stop, returning true if the cursor moved */ Bool TabToNextStop(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int saved_column = screen->cur_col; int next = TabNext(xw, xw->tabs, screen->cur_col); int max = LineMaxCol(screen, getLineData(screen, screen->cur_row)); if (IsLeftRightMode(xw)) max = TScreenOf(xw)->rgt_marg; if (next > max) next = max; set_cur_col(screen, next); return (screen->cur_col > saved_column); } /* * Tab to the previous stop, returning true if the cursor moved */ Bool TabToPrevStop(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int saved_column = screen->cur_col; int next_column = TabPrev(xw->tabs, screen->cur_col); if (xw->flags & ORIGIN) { int left = ScrnLeftMargin(xw); if (next_column < left) next_column = left; } set_cur_col(screen, next_column); return (screen->cur_col < saved_column); } /* * clears all tabs */ void TabZonk(Tabs tabs) { memset(tabs, 0, sizeof(*tabs) * TAB_ARRAY_SIZE); } /* * Check if a tab is set for the given column */ Bool TabIsSet(Tabs tabs, int col) { return TST_TAB(tabs, col) ? True : False; } xterm-399/ctlseqs.txt0000644000000000000000000047450514772331715013505 0ustar rootroot XTerm Control Sequences Edward Moy University of California, Berkeley Revised by Stephen Gildea X Consortium (1994) Thomas Dickey XFree86 Project (1996-2006) invisible-island.net (2006-2025) updated for XTerm Patch #398 (2025/03/30) Definitions Many controls use parameters, shown in italics. If a control uses a single parameter, only one parameter name is listed. Some parameters (along with separating ; characters) may be optional. Other characters in the control are required. C A single (required) character. Ps A single (usually optional) numeric parameter, composed of one or more digits. Pm Any number of single numeric parameters, separated by ; character(s). Individual values for the parameters are listed with Ps . Pt A text parameter composed of printable characters. Control Bytes, Characters, and Sequences ECMA-48 (aka "ISO 6429") documents C1 (8-bit) and C0 (7-bit) codes. Those are respectively codes 128 to 159 and 0 to 31. ECMA-48 avoids referring to these codes as characters, because that term is associated with graphic characters. Instead, it uses "bytes" and "codes", with occasional lapses to "characters" where the meaning cannot be mistaken. Controls (including the escape code 27) are processed once: o This means that a C1 control can be mistaken for badly-formed UTF-8 when the terminal runs in UTF-8 mode because C1 controls are valid continuation bytes of a UTF-8 encoded (multibyte) value. o It is not possible to use a C1 control obtained from decoding the UTF-8 text, because that would require reprocessing the data. Consequently there is no ambiguity in the way this document uses the term "character" to refer to bytes in a control sequence. The order of processing is a necessary consequence of the way ECMA-48 is designed: o Each byte sent to the terminal can be unambiguously determined to fall into one of a few categories (C0, C1 and graphic characters). o ECMA-48 is modal; once it starts processing a control sequence, the terminal continues until the sequence is complete, or some byte is found which is not allowed in the sequence. o Intermediate, parameter and final bytes may use the same codes as graphic characters, but they are processed as part of a control sequence and are not actually graphic characters. o Eight-bit controls can have intermediate, etc., bytes in the range 160 to 255. Those can be treated as their counterparts in the range 32 to 127. o Single-byte controls can be handled separately from multi-byte control sequences because ECMA-48's rules are unambiguous. As a special case, ECMA-48 (section 9) mentions that the control functions shift-in and shift-out are allowed to occur within a 7-bit multibyte control sequence because those cannot alter the meaning of the control sequence. o Some controls (such as OSC ) introduce a string mode, which is ended on a ST (string terminator). Section 9 of ECMA-48, like DEC STD 070, chapter 3, goes into detail to explain that when processing 8-bit controls, the eighth bit of each byte is ignored. This applies to the content of APC, DCS, OSC, and PM strings, as well as to the terminating bytes such as the two- byte string terminator. Quoting from the latter, 3.5.4.5 GR Graphic Characters within Control Strings: GR (8-bit) graphic characters in APC, OSC, and PM control strings will be treated as their 7-bit equivalent (the eighth bit will be ignored). GR (8-bit) graphic characters are permitted within Device Control Strings, and the graphic character's interpretation will be dependent on the internal control string format. When they occur in the introducer sequence to a Device Control String, the eighth bit will be ignored, and they will be treated as their 7-bit equivalent. (Note that this is the same way 8-bit graphic characters are handled within control sequences.) The reason for that is because ECMA-48 presents 7-bit controls as an alternative to 8-bit controls. It says this: The control functions defined in this Standard can be coded in a 7-bit code as well as in an 8-bit code; both forms of coded representation are equivalent and in accordance with Standard ECMA-35. and in turn, ECMA-35 9.1 says A 7-bit code shall have a structure which is based on a 7-bit code table arranged in separate areas as follows (see figure 7): In short, a standard-compliant implementation of ECMA-48 ignores the eighth bit of bytes in control strings other than the C1 controls. XTerm does this. ECMA-48 describes only correct behavior, telling what types of characters are expected at each stage of the control sequences. It says that the action taken in error recovery is implementation- dependent. XTerm decodes control sequences using a state machine. It handles errors in decoding i.e., unexpected characters, by resetting to the initial (ground) state. That is different from the treatment of unimplemented (but correctly formatted) features. If an application does not send the string terminator, that is also an error from the standpoint of a user. To accommodate users of those applications, xterm has resource settings which allow workarounds: o The Linux console's palette sequences do not use a string terminator. The brokenLinuxOSC resource setting tells xterm to ignore those particular sequences. o The terminal should accept single-byte controls within the string. But some applications omit a string terminator, like the Linux console. The brokenStringTerm resource setting tells xterm to exit string mode if it decodes a common control character such as carriage return before the string terminator. C1 (8-Bit) Control Characters The xterm program recognizes both 8-bit and 7-bit control characters. It generates 7-bit controls (by default) or 8-bit if S8C1T is enabled. The following pairs of 7-bit and 8-bit control characters are equivalent: ESC D Index (IND is 0x84). ESC E Next Line (NEL is 0x85). ESC H Tab Set (HTS is 0x88). ESC M Reverse Index (RI is 0x8d). ESC N Single Shift Select of G2 Character Set (SS2 is 0x8e), VT220. This affects next character only. ESC O Single Shift Select of G3 Character Set (SS3 is 0x8f), VT220. This affects next character only. ESC P Device Control String (DCS is 0x90). ESC V Start of Guarded Area (SPA is 0x96). ESC W End of Guarded Area (EPA is 0x97). ESC X Start of String (SOS is 0x98). ESC Z Return Terminal ID (DECID is 0x9a). Obsolete form of CSI c (DA). ESC [ Control Sequence Introducer (CSI is 0x9b). ESC \ String Terminator (ST is 0x9c). ESC ] Operating System Command (OSC is 0x9d). ESC ^ Privacy Message (PM is 0x9e). ESC _ Application Program Command (APC is 0x9f). These control characters are used in the vtXXX emulation. VT100-related terminals In this document, "VT100" refers not only to VT100/VT102, but also to the succession of upward-compatible terminals produced by DEC (Digital Equipment Corporation) from the mid-1970s for about twenty years. For brevity, the document refers to the related models: "VT200" as VT220/VT240, "VT300" as VT320/VT340, "VT400" as VT420, and "VT500" as VT510/VT520/VT525. Most of these control sequences are standard VT102 control sequences, but there is support for later DEC VT terminals (i.e., VT220, VT320, VT420, VT510), as well as ECMA-48 and aixterm color controls. The only VT102 feature not supported is auto-repeat, since the only way X provides for this will affect all windows. There are additional control sequences to provide xterm-dependent functions, such as the scrollbar or window size. Where the function is specified by DEC or ECMA-48, the mnemonic assigned to it is given in parentheses. The escape codes to designate and invoke character sets are specified by ISO 2022 (see that document for a discussion of character sets). Many of the features are optional; xterm can be configured and built without support for them. VT100 Mode Single-character functions BEL Bell (BEL is Ctrl-G). BS Backspace (BS is Ctrl-H). CR Carriage Return (CR is Ctrl-M). ENQ Return Terminal Status (ENQ is Ctrl-E). Default response is an empty string, but may be overridden by a resource answerbackString. FF Form Feed or New Page (NP ). (FF is Ctrl-L). FF is treated the same as LF . LF Line Feed or New Line (NL). (LF is Ctrl-J). SI Switch to Standard Character Set (Ctrl-O is Shift In or LS0). This invokes the G0 character set (the default) as GL. VT200 and up implement LS0. SO Switch to Alternate Character Set (Ctrl-N is Shift Out or LS1). This invokes the G1 character set as GL. VT200 and up implement LS1. SP Space. TAB Horizontal Tab (HTS is Ctrl-I). VT Vertical Tab (VT is Ctrl-K). This is treated the same as LF. Controls beginning with ESC This excludes controls where ESC is part of a 7-bit equivalent to 8-bit C1 controls, ordered by the final character(s). ESC SP F 7-bit controls (S7C1T), VT220. This tells the terminal to send C1 control characters as 7-bit sequences, e.g., its responses to queries. DEC VT200 and up always accept 8-bit control sequences except when configured for VT100 mode. ESC SP G 8-bit controls (S8C1T), VT220. This tells the terminal to send C1 control characters as 8-bit sequences, e.g., its responses to queries. DEC VT200 and up always accept 8-bit control sequences except when configured for VT100 mode. ESC SP L Set ANSI conformance level 1, ECMA-43. ESC SP M Set ANSI conformance level 2, ECMA-43. ESC SP N Set ANSI conformance level 3, ECMA-43. ESC # 3 DEC double-height line, top half (DECDHL), VT100. ESC # 4 DEC double-height line, bottom half (DECDHL), VT100. ESC # 5 DEC single-width line (DECSWL), VT100. ESC # 6 DEC double-width line (DECDWL), VT100. ESC # 8 DEC Screen Alignment Test (DECALN), VT100. ESC % @ Select default character set. That is ISO 8859-1 (ISO 2022). ESC % G Select UTF-8 character set, ISO 2022. ESC ( C Designate G0 Character Set, VT100, ISO 2022. Final character C for designating 94-character sets. In this list, o 0 , A and B were introduced in the VT100, o most were introduced in the VT200 series, o a few were introduced in the VT300 series, and o a few more were introduced in the VT500 series. The VT220 character sets, together with a few others (such as Portuguese) are activated by the National Replacement Character Set (NRCS) controls. The term "replacement" says that the character set is formed by replacing some of the characters in a set (termed the Multinational Character Set) with more useful ones for a given language. The ASCII and DEC Supplemental character sets make up the two halves of the Multinational Character set, initially mapped to GL and GR. The valid final characters C for this control are: C = A -> United Kingdom (UK), VT100. C = B -> United States (USASCII), VT100. C = C or 5 -> Finnish, VT200. C = H or 7 -> Swedish, VT200. C = K -> German, VT200. C = Q or 9 -> French Canadian, VT200. C = R or f -> French, VT200. C = Y -> Italian, VT200. C = Z -> Spanish, VT200. C = 4 -> Dutch, VT200. C = " > -> Greek, VT500. C = % 2 -> Turkish, VT500. C = % 6 -> Portuguese, VT300. C = % = -> Hebrew, VT500. C = = -> Swiss, VT200. C = ` , E or 6 -> Norwegian/Danish, VT200. The final character A is a special case, since the same final character is used by the VT300-control for the 96-character British Latin-1. There are a few other 94-character sets: C = 0 -> DEC Special Character and Line Drawing Set, VT100. C = < -> DEC Supplemental, VT200. C = < -> User Preferred Selection Set, VT300. C = > -> DEC Technical, VT300. These are documented as 94-character sets (like USASCII) without NRCS: C = " 4 -> DEC Hebrew, VT500. C = " ? -> DEC Greek, VT500. C = % 0 -> DEC Turkish, VT500. C = % 5 -> DEC Supplemental Graphics, VT300. C = & 4 -> DEC Cyrillic, VT500. C = I -> JIS-Katakana, VT382. C = J -> JIS-Roman, VT382. The VT520 reference manual lists a few more, but no documentation has been found for the mappings: C = % 3 -> SCS NRCS, VT500. C = & 5 -> DEC Russian, VT500. ESC ) C Designate G1 Character Set, ISO 2022, VT100. The same character sets apply as for ESC ( C. ESC * C Designate G2 Character Set, ISO 2022, VT220. The same character sets apply as for ESC ( C. ESC + C Designate G3 Character Set, ISO 2022, VT220. The same character sets apply as for ESC ( C. ESC - C Designate G1 Character Set, VT300. These controls apply only to 96-character sets. Unlike the 94-character sets, these can have different values than ASCII space and DEL for the mapping of 0x20 and 0x7f. The valid final characters C for this control are: C = A -> ISO Latin-1 Supplemental, VT300. C = B -> ISO Latin-2 Supplemental, VT500. C = F -> ISO Greek Supplemental, VT500. C = H -> ISO Hebrew Supplemental, VT500. C = L -> ISO Latin-Cyrillic, VT500. C = M -> ISO Latin-5 Supplemental, VT500. ESC . C Designate G2 Character Set, VT300. The same character sets apply as for ESC - C. ESC / C Designate G3 Character Set, VT300. The same character sets apply as for ESC - C. ESC 6 Back Index (DECBI), VT420 and up. ESC 7 Save Cursor (DECSC), VT100. ESC 8 Restore Cursor (DECRC), VT100. ESC 9 Forward Index (DECFI), VT420 and up. ESC = Application Keypad (DECKPAM). ESC > Normal Keypad (DECKPNM), VT100. ESC F Cursor to lower left corner of screen. This is enabled by the hpLowerleftBugCompat resource. ESC c Full Reset (RIS), VT100. ESC l Memory Lock (per HP terminals). Locks memory above the cursor. ESC m Memory Unlock (per HP terminals). ESC n Invoke the G2 Character Set as GL (LS2). ESC o Invoke the G3 Character Set as GL (LS3). ESC | Invoke the G3 Character Set as GR (LS3R). ESC } Invoke the G2 Character Set as GR (LS2R). ESC ~ Invoke the G1 Character Set as GR (LS1R), VT100. Application Program-Command functions APC Pt ST None. xterm implements no APC functions; Pt is ignored. Pt need not be printable characters. Device-Control functions DCS Ps ; Ps | Pt ST User-Defined Keys (DECUDK), VT220 and up. The first parameter: Ps = 0 -> Clear all UDK definitions before starting (default). Ps = 1 -> Erase Below (default). The second parameter: Ps = 0 <- Lock the keys (default). Ps = 1 <- Do not lock. The third parameter is a ";"-separated list of strings denoting the key-code separated by a "/" from the hex-encoded key value. The key codes correspond to the DEC function-key codes (e.g., F6=17). DCS Ps ! u Pt ST Assigning User-Preferred Supplemental Sets (DECAUPSS), VT320, VT510. XTerm ignores this in UTF-8 mode, and uses the preferLatin1 resource to choose the default setting. VT320 provides these: DCS 0 ! u % 5 ST -> DEC Supplemental Graphic DCS 1 ! u A ST -> ISO Latin-1 supplemental VT510 adds these: DCS 0 ! u " ? ST -> DEC Greek DCS 0 ! u " 4 ST -> DEC Hebrew DCS 0 ! u % 0 ST -> DEC Turkish DCS 0 ! u & 4 ST -> DEC Cyrillic DCS 1 ! u B ST -> ISO Latin-2 Supplemental DCS 1 ! u F ST -> ISO Greek Supplemental DCS 1 ! u H ST -> ISO Hebrew Supplemental DCS 1 ! u M ST -> ISO Latin-5 Supplemental DCS 1 ! u L ST -> ISO Latin-Cyrillic VT520 accepts a few others (undocumented); xterm adds these: DCS 0 ! u B ST -> United States (USASCII). DCS 0 ! u 0 ST -> DEC Special Character and Line Drawing Set. DCS 0 ! u > ST -> DEC Technical. DCS $ q Pt ST Request Status String (DECRQSS), VT420 and up. The string following the "q" is one of the following: m -> SGR " p -> DECSCL SP q -> DECSCUSR " q -> DECSCA r -> DECSTBM s -> DECSLRM t -> DECSLPP $ | -> DECSCPP $ } -> DECSASD $ ~ -> DECSSDT ) { -> DECSTGLT (VT525 only) * x -> DECSACE * | -> DECSNLS , | -> DECAC (VT525 only) , } -> DECATC (VT525 only) > Pm f -> XTQFMTKEYS (xterm) > Pm m -> XTQMODKEYS (xterm) > Pm t -> XTSMTITLE (xterm) xterm responds with DCS 1 $ r Pt ST for valid requests, replacing the Pt with the corresponding CSI string, or DCS 0 $ r ST for invalid requests. DCS Ps $ t Pt ST Restore presentation status (DECRSPS), VT320 and up. The control can be converted from a response from DECCIR or DECTABSR by changing the first "u" to a "t" Ps = 1 -> DECCIR Ps = 2 -> DECTABSR DCS + Q Pt ST Request resource values (XTGETXRES), xterm. The string following the "Q" is a list of names encoded in hexadecimal (2 digits per character) separated by ; which correspond to xterm resource names. xterm responds with DCS 1 + R Pt ST for valid requests, adding to Pt an = , and the value of the corresponding xterm resource, or DCS 0 + R Pt ST for invalid requests. The strings are encoded in hexadecimal (2 digits per character). Only boolean, numeric and string resources for the VT100 widget are supported by this query. XTerm evaluates resources at startup time. Several of xterm's state variables use resources to determine their initial value. Because the resource variable may not reflect the current state, xterm provides control sequences for querying the state directly: o XTQALLOWED o XTQFMTKEYS o XTQMODKEYS DCS + p Pt ST Set Termcap/Terminfo Data (XTSETTCAP), xterm. The string following the "p" is encoded in hexadecimal. After decoding it, xterm will use the name to retrieve data from the terminal database. If successful, that overrides the termName resource when handling the "tcap" keyboard configuration's function- and special-keys, as well as by the Request Termcap/Terminfo String control. DCS + q Pt ST Request Termcap/Terminfo String (XTGETTCAP), xterm. The string following the "q" is a list of names encoded in hexadecimal (2 digits per character) separated by ; which correspond to termcap or terminfo key names. A few special features are also recognized, which are not key names: o Co for termcap colors (or colors for terminfo colors), and o TN for termcap name (or name for terminfo name). o RGB for the ncurses direct-color extension. Only a terminfo name is provided, since termcap applications cannot use this information. xterm responds with DCS 1 + r Pt ST for valid requests, adding to Pt an = , and the value of the corresponding string that xterm would send, or DCS 0 + r ST for invalid requests. The strings are encoded in hexadecimal (2 digits per character). If more than one name is given, xterm replies with each name/value pair in the same response. An invalid name (one not found in xterm's tables) ends processing of the list of names. Functions using CSI , ordered by the final character(s) CSI Ps @ Insert Ps (Blank) Character(s) (default = 1) (ICH). CSI Ps SP @ Shift left Ps columns(s) (default = 1) (SL), ECMA-48. CSI Ps A Cursor Up Ps Times (default = 1) (CUU). CSI Ps SP A Shift right Ps columns(s) (default = 1) (SR), ECMA-48. CSI Ps B Cursor Down Ps Times (default = 1) (CUD). CSI Ps C Cursor Forward Ps Times (default = 1) (CUF). CSI Ps D Cursor Backward Ps Times (default = 1) (CUB). CSI Ps E Cursor Next Line Ps Times (default = 1) (CNL). CSI Ps F Cursor Preceding Line Ps Times (default = 1) (CPL). CSI Ps G Cursor Character Absolute [column] (default = [row,1]) (CHA). CSI Ps ; Ps H Cursor Position [row;column] (default = [1,1]) (CUP). CSI Ps I Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). CSI Ps J Erase in Display (ED), VT100. Ps = 0 -> Erase Below (default). Ps = 1 -> Erase Above. Ps = 2 -> Erase All. Ps = 3 -> Erase Saved Lines, xterm. CSI ? Ps J Erase in Display (DECSED), VT220. Ps = 0 -> Selective Erase Below (default). Ps = 1 -> Selective Erase Above. Ps = 2 -> Selective Erase All. Ps = 3 -> Selective Erase Saved Lines, xterm. CSI Ps K Erase in Line (EL), VT100. Ps = 0 -> Erase to Right (default). Ps = 1 -> Erase to Left. Ps = 2 -> Erase All. CSI ? Ps K Erase in Line (DECSEL), VT220. Ps = 0 -> Selective Erase to Right (default). Ps = 1 -> Selective Erase to Left. Ps = 2 -> Selective Erase All. CSI Ps L Insert Ps Line(s) (default = 1) (IL). CSI Ps M Delete Ps Line(s) (default = 1) (DL). CSI Ps P Delete Ps Character(s) (default = 1) (DCH). CSI # P CSI Pm # P Push current dynamic- and ANSI-palette colors onto stack (XTPUSHCOLORS), xterm. Parameters (integers in the range 1 through 10, since the default 0 will push) may be used to store the palette into the stack without pushing. CSI # Q CSI Pm # Q Pop stack to set dynamic- and ANSI-palette colors (XTPOPCOLORS), xterm. Parameters (integers in the range 1 through 10, since the default 0 will pop) may be used to restore the palette from the stack without popping. CSI # R Report the current entry on the palette stack, and the number of palettes stored on the stack, using the same form as XTPOPCOLOR (default = 0) (XTREPORTCOLORS), xterm. CSI Ps S Scroll up Ps lines (default = 1) (SU), VT420, ECMA-48. CSI # S Report position on title-stack (XTTITLEPOS), xterm. Response is the same format, with parameters: CSI Pn; Pm # S where Pn is the current index into the title stack Pm is the maximum index for the title stack CSI ? Pi ; Pa ; Pv S Set or request graphics attribute (XTSMGRAPHICS), xterm. If configured to support either Sixel Graphics or ReGIS Graphics, xterm accepts a three-parameter control sequence, where Pi, Pa and Pv are the item, action and value: Pi = 1 -> item is number of color registers. Pi = 2 -> item is Sixel graphics geometry (in pixels). Pi = 3 -> item is ReGIS graphics geometry (in pixels). Pa = 1 -> read attribute. Pa = 2 -> reset to default. Pa = 3 -> set to value in Pv. Pa = 4 -> read the maximum allowed value. Pv is ignored by xterm except when setting (Pa == 3 ). Pv = n <- A single integer is used for color registers. Pv = width ; height <- Two integers for graphics geometry. xterm replies with a control sequence of the same form: CSI ? Pi ; Ps ; Pv S where Ps is the status: Ps = 0 <- success. Ps = 1 <- error in Pi. Ps = 2 <- error in Pa. Ps = 3 <- failure. On success, Pv represents the value read or set. Notes: o The current implementation allows reading the graphics sizes, but disallows modifying those sizes because that is done once, using resource-values. o Graphics geometry is not necessarily the same as "window size" (see the XTWINOPS window manipulation extensions). XTerm limits the maximum graphics geometry according to the maxGraphicSize resource. The maxGraphicSize resource can be either an explicit heightxwidth (default: 1000x1000 as of version 328) or the word "auto" (telling XTerm to use limits the decGraphicsID or decTerminalID resource to determine the limits). o XTerm uses the minimum of the window size and the graphic size to obtain the maximum geometry. o While resizing a window will always change the current graphics geometry, the reverse is not true. Setting graphics geometry does not affect the window size. o If xterm is able to support graphics (compile-time), but is not configured (runtime) for graphics, these responses will indicate a failure. Other implementations which do not use the maximum graphics dimensions but are configured for graphics should report zeroes for the maximum geometry rather than a failure. CSI Ps T Scroll down Ps lines (default = 1) (SD), VT420. CSI Ps ; Ps ; Ps ; Ps ; Ps T Initiate highlight mouse tracking (XTHIMOUSE), xterm. Parameters are [func;startx;starty;firstrow;lastrow]. See the section Mouse Tracking. CSI > Pm T Reset title mode features to default value (XTRMTITLE), xterm. Normally, "reset" disables the feature. It is possible to disable the ability to reset features by compiling a different default for the title modes into xterm. If no parameters are given, all title mode features are reset to the initial (compiled-in) default. Ps = 0 -> Do not set window/icon labels using hexadecimal. Ps = 1 -> Do not query window/icon labels using hexadecimal. Ps = 2 -> Do not set window/icon labels using UTF-8. Ps = 3 -> Do not query window/icon labels using UTF-8. (See discussion of Title Modes). CSI ? 5 W Reset tab stops to start with column 9, every 8 columns (DECST8C), VT510. CSI Ps X Erase Ps Character(s) (default = 1) (ECH). CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). CSI Ps ^ Scroll down Ps lines (default = 1) (SD), ECMA-48. This was a publication error in the original ECMA-48 5th edition (1991) corrected in 2003. CSI Ps ` Character Position Absolute [column] (default = [row,1]) (HPA). CSI Ps a Character Position Relative [columns] (default = [row,col+1]) (HPR). CSI Ps b Repeat the preceding graphic character Ps times (REP). CSI Ps c Send Device Attributes (Primary DA). Ps = 0 or omitted -> request attributes from terminal. The response depends on the decTerminalID resource setting. -> CSI ? 1 ; 2 c ("VT100 with Advanced Video Option") -> CSI ? 1 ; 0 c ("VT101 with No Options") -> CSI ? 4 ; 6 c ("VT132 with Advanced Video and Graphics") -> CSI ? 6 c ("VT102") -> CSI ? 7 c ("VT131") -> CSI ? 1 2 ; Ps c ("VT125") -> CSI ? 6 2 ; Ps c ("VT220") -> CSI ? 6 3 ; Ps c ("VT320") -> CSI ? 6 4 ; Ps c ("VT420") -> CSI ? 6 5 ; Ps c ("VT510" to ("VT525") The VT100-style response parameters do not mean anything by themselves. VT220 (and higher) parameters do, telling the host what features the terminal supports: Ps = 1 -> 132-columns. Ps = 2 -> Printer. Ps = 3 -> ReGIS graphics. Ps = 4 -> Sixel graphics. Ps = 6 -> Selective erase. Ps = 8 -> User-defined keys. Ps = 9 -> National Replacement Character sets. Ps = 1 5 -> Technical characters. Ps = 1 6 -> Locator port. Ps = 1 7 -> Terminal state interrogation. Ps = 1 8 -> User windows. Ps = 2 1 -> Horizontal scrolling. Ps = 2 2 -> ANSI color, e.g., VT525. Ps = 2 8 -> Rectangular editing. Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode). XTerm supports part of the User windows feature, providing a single page (which corresponds to its visible window). Rather than resizing the font to change the number of lines/columns in a fixed-size display, xterm uses the window extension controls (DECSNLS, DECSCPP, DECSLPP) to adjust its visible window's size. The "cursor coupling" controls (DECHCCM, DECPCCM, DECVCCM) are ignored. CSI = Ps c Send Device Attributes (Tertiary DA). Ps = 0 -> report Terminal Unit ID (default), VT400. XTerm uses zeros for the site code and serial number in its DECRPTUI response. CSI > Ps c Send Device Attributes (Secondary DA). Ps = 0 or omitted -> request the terminal's identification code. The response depends on the decTerminalID resource setting. It should apply only to VT220 and up, but xterm extends this to VT100. -> CSI > Pp ; Pv ; Pc c where Pp denotes the terminal type Pp = 0 -> "VT100". Pp = 1 -> "VT220". Pp = 2 -> "VT240" or "VT241". Pp = 1 8 -> "VT330". Pp = 1 9 -> "VT340". Pp = 2 4 -> "VT320". Pp = 3 2 -> "VT382". Pp = 4 1 -> "VT420". Pp = 6 1 -> "VT510". Pp = 6 4 -> "VT520". Pp = 6 5 -> "VT525". and Pv is the firmware version (for xterm, this was originally the XFree86 patch number, starting with 95). In a DEC terminal, Pc indicates the ROM cartridge registration number and is always zero. CSI Ps d Line Position Absolute [row] (default = [1,column]) (VPA). CSI Ps e Line Position Relative [rows] (default = [row+1,column]) (VPR). CSI Ps ; Ps f Horizontal and Vertical Position [row;column] (default = [1,1]) (HVP). CSI > Pp ; Pv f CSI > Pp f Set/reset key format options (XTFMTKEYS), xterm. Set or reset resource-values used by xterm to decide how to format escape sequences holding information about the modifiers pressed with a given key. The first parameter Pp identifies the resource to set/reset. The second parameter Pv is the value to assign to the resource. If the second parameter is omitted, the resource is reset to its initial value. Value 5 is reserved for input via the string action. Pp = 0 -> formatKeyboard. Pp = 1 -> formatCursorKeys. Pp = 2 -> formatFunctionKeys. Pp = 3 -> formatKeypadKeys. Pp = 4 -> formatOtherKeys. Pp = 6 -> formatModifierKeys. Pp = 7 -> formatSpecialKeys. If no parameters are given, all resources are reset to their initial values. See Alt and Meta Keys for more details on the formatOtherKeys feature. CSI Ps g Tab Clear (TBC). ECMA-48 defines additional codes, but the VT100 user manual notes that it ignores other codes. DEC's later terminals (and xterm) do the same, for compatibility. Ps = 0 -> Clear Current Column (default). Ps = 3 -> Clear All. CSI ? Pp g Query key modifier options (XTQFMTKEYS), xterm. The parameter Pp identifies the resource to query. Pp = 0 -> formatKeyboard. Pp = 1 -> formatCursorKeys. Pp = 2 -> formatFunctionKeys. Pp = 3 -> formatKeypadKeys. Pp = 4 -> formatOtherKeys. Pp = 6 -> formatModifierKeys. Pp = 7 -> formatSpecialKeys. XTerm's response can be used to restore this state, because it is formatted as an XTFMTKEYS control, i.e., CSI > Pp f where Pp = 0 -> formatKeyboard. Pp = 1 -> formatCursorKeys. Pp = 2 -> formatFunctionKeys. Pp = 3 -> formatKeypadKeys. Pp = 4 -> formatOtherKeys. Pp = 6 -> formatModifierKeys. Pp = 7 -> formatSpecialKeys. CSI Pm h Set Mode (SM). Ps = 2 -> Keyboard Action Mode (KAM). Ps = 4 -> Insert Mode (IRM). Ps = 1 2 -> Send/receive (SRM). Ps = 2 0 -> Automatic Newline (LNM). CSI ? Pm h DEC Private Mode Set (DECSET). Ps = 1 -> Application Cursor Keys (DECCKM), VT100. Ps = 2 -> Designate USASCII for character sets G0-G3 (DECANM), VT100, and set VT100 mode. Ps = 3 -> 132 Column Mode (DECCOLM), VT100. Ps = 4 -> Smooth (Slow) Scroll (DECSCLM), VT100. Ps = 5 -> Reverse Video (DECSCNM), VT100. Ps = 6 -> Origin Mode (DECOM), VT100. Ps = 7 -> Auto-Wrap Mode (DECAWM), VT100. Ps = 8 -> Auto-Repeat Keys (DECARM), VT100. Ps = 9 -> Send Mouse X & Y on button press. See the section Mouse Tracking. This is the X10 xterm mouse protocol. Ps = 1 0 -> Show toolbar (rxvt). Ps = 1 2 -> Start blinking cursor (AT&T 610). Ps = 1 3 -> Start blinking cursor (set only via resource or menu). Ps = 1 4 -> Enable XOR of blinking cursor control sequence and menu. Ps = 1 8 -> Print Form Feed (DECPFF), VT220. Ps = 1 9 -> Set print extent to full screen (DECPEX), VT220. Ps = 2 5 -> Show cursor (DECTCEM), VT220. Ps = 3 0 -> Show scrollbar (rxvt). Ps = 3 5 -> Enable font-shifting functions (rxvt). Ps = 3 8 -> Enter Tektronix mode (DECTEK), VT240, xterm. Ps = 4 0 -> Allow 80 -> 132 mode, xterm. Ps = 4 1 -> more(1) fix (see curses resource). Ps = 4 2 -> Enable National Replacement Character sets (DECNRCM), VT220. Ps = 4 3 -> Enable Graphic Expanded Print Mode (DECGEPM), VT340. Ps = 4 4 -> Turn on margin bell, xterm. Ps = 4 4 -> Enable Graphic Print Color Mode (DECGPCM), VT340. Ps = 4 5 -> Reverse-wraparound mode (XTREVWRAP), xterm. Ps = 4 5 -> Enable Graphic Print Color Syntax (DECGPCS), VT340. Ps = 4 6 -> Start logging (XTLOGGING), xterm. This is normally disabled by a compile-time option. Ps = 4 6 -> Graphic Print Background Mode, VT340. Ps = 4 7 -> Use Alternate Screen Buffer, xterm. This may be disabled by the titeInhibit resource. Ps = 4 7 -> Enable Graphic Rotated Print Mode (DECGRPM), VT340. Ps = 6 6 -> Application keypad mode (DECNKM), VT320. Ps = 6 7 -> Backarrow key sends backspace (DECBKM), VT340, VT420. This sets the backarrowKey resource to "true". Ps = 6 9 -> Enable left and right margin mode (DECLRMM), VT420 and up. Ps = 8 0 -> Enable Sixel Display Mode (DECSDM), VT330, VT340, VT382. Ps = 9 5 -> Do not clear screen when DECCOLM is set/reset (DECNCSM), VT510 and up. Ps = 1 0 0 0 -> Send Mouse X & Y on button press and release. See the section Mouse Tracking. This is the X11 xterm mouse protocol. Ps = 1 0 0 1 -> Use Hilite Mouse Tracking, xterm. Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking, xterm. See the section Button-event tracking. Ps = 1 0 0 3 -> Use All Motion Mouse Tracking, xterm. See the section Any-event tracking. Ps = 1 0 0 4 -> Send FocusIn/FocusOut events, xterm. Ps = 1 0 0 5 -> Enable UTF-8 Mouse Mode, xterm. Ps = 1 0 0 6 -> Enable SGR Mouse Mode, xterm. Ps = 1 0 0 7 -> Enable Alternate Scroll Mode, xterm. This corresponds to the alternateScroll resource. Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt). This sets the scrollTtyOutput resource to "true". Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt). This sets the scrollKey resource to "true". Ps = 1 0 1 4 -> Enable fastScroll resource, xterm. Ps = 1 0 1 5 -> Enable urxvt Mouse Mode. Ps = 1 0 1 6 -> Enable SGR Mouse PixelMode, xterm. Ps = 1 0 3 4 -> Interpret "meta" key, xterm. This sets the eighth bit of keyboard input (and enables the eightBitInput resource). Ps = 1 0 3 5 -> Enable special modifiers for Alt and NumLock keys, xterm. This enables the numLock resource. Ps = 1 0 3 6 -> Send ESC when Meta modifies a key, xterm. This enables the metaSendsEscape resource. Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete key, xterm. Ps = 1 0 3 9 -> Send ESC when Alt modifies a key, xterm. This enables the altSendsEscape resource, xterm. Ps = 1 0 4 0 -> Keep selection even if not highlighted, xterm. This enables the keepSelection resource. Ps = 1 0 4 1 -> Use the CLIPBOARD selection, xterm. This enables the selectToClipboard resource. Ps = 1 0 4 2 -> Enable Urgency window manager hint when Control-G is received, xterm. This enables the bellIsUrgent resource. Ps = 1 0 4 3 -> Enable raising of the window when Control-G is received, xterm. This enables the popOnBell resource. Ps = 1 0 4 4 -> Reuse the most recent data copied to CLIPBOARD, xterm. This enables the keepClipboard resource. Ps = 1 0 4 5 -> Extended Reverse-wraparound mode (XTREVWRAP2), xterm. Ps = 1 0 4 6 -> Enable switching to/from Alternate Screen Buffer, xterm. This works for terminfo-based systems, updating the titeInhibit resource. Ps = 1 0 4 7 -> Use Alternate Screen Buffer, xterm. This may be disabled by the titeInhibit resource. Ps = 1 0 4 8 -> Save cursor as in DECSC, xterm. This may be disabled by the titeInhibit resource. Ps = 1 0 4 9 -> Save cursor as in DECSC, xterm. After saving the cursor, switch to the Alternate Screen Buffer, clearing it first. This may be disabled by the titeInhibit resource. This control combines the effects of the 1 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based applications rather than the 4 7 mode. Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode, xterm. Ps = 1 0 5 1 -> Set Sun function-key mode, xterm. Ps = 1 0 5 2 -> Set HP function-key mode, xterm. Ps = 1 0 5 3 -> Set SCO function-key mode, xterm. Ps = 1 0 6 0 -> Set legacy keyboard emulation, i.e, X11R6, xterm. Ps = 1 0 6 1 -> Set VT220 keyboard emulation, xterm. Ps = 2 0 0 1 -> Enable readline mouse button-1, xterm. Ps = 2 0 0 2 -> Enable readline mouse button-2, xterm. Ps = 2 0 0 3 -> Enable readline mouse button-3, xterm. Ps = 2 0 0 4 -> Set bracketed paste mode, xterm. Ps = 2 0 0 5 -> Enable readline character-quoting, xterm. Ps = 2 0 0 6 -> Enable readline newline pasting, xterm. CSI Ps i Media Copy (MC). Ps = 0 -> Print screen (default). Ps = 4 -> Turn off printer controller mode. Ps = 5 -> Turn on printer controller mode. Ps = 1 0 -> HTML screen dump, xterm. Ps = 1 1 -> SVG screen dump, xterm. CSI ? Ps i Media Copy (MC), DEC-specific. Ps = 1 -> Print line containing cursor. Ps = 4 -> Turn off autoprint mode. Ps = 5 -> Turn on autoprint mode. Ps = 1 0 -> Print composed display, ignores DECPEX. Ps = 1 1 -> Print all pages. CSI Pm l Reset Mode (RM). Ps = 2 -> Keyboard Action Mode (KAM). Ps = 4 -> Replace Mode (IRM). Ps = 1 2 -> Send/receive (SRM). Ps = 2 0 -> Normal Linefeed (LNM). CSI ? Pm l DEC Private Mode Reset (DECRST). Ps = 1 -> Normal Cursor Keys (DECCKM), VT100. Ps = 2 -> Designate VT52 mode (DECANM), VT100. Ps = 3 -> 80 Column Mode (DECCOLM), VT100. Ps = 4 -> Jump (Fast) Scroll (DECSCLM), VT100. Ps = 5 -> Normal Video (DECSCNM), VT100. Ps = 6 -> Normal Cursor Mode (DECOM), VT100. Ps = 7 -> No Auto-Wrap Mode (DECAWM), VT100. Ps = 8 -> No Auto-Repeat Keys (DECARM), VT100. Ps = 9 -> Don't send Mouse X & Y on button press, xterm. Ps = 1 0 -> Hide toolbar (rxvt). Ps = 1 2 -> Stop blinking cursor (AT&T 610). Ps = 1 3 -> Disable blinking cursor (reset only via resource or menu). Ps = 1 4 -> Disable XOR of blinking cursor control sequence and menu. Ps = 1 8 -> Don't Print Form Feed (DECPFF), VT220. Ps = 1 9 -> Limit print to scrolling region (DECPEX), VT220. Ps = 2 5 -> Hide cursor (DECTCEM), VT220. Ps = 3 0 -> Don't show scrollbar (rxvt). Ps = 3 5 -> Disable font-shifting functions (rxvt). Ps = 4 0 -> Disallow 80 -> 132 mode, xterm. Ps = 4 1 -> No more(1) fix (see curses resource). Ps = 4 2 -> Disable National Replacement Character sets (DECNRCM), VT220. Ps = 4 3 -> Disable Graphic Expanded Print Mode (DECGEPM), VT340. Ps = 4 4 -> Turn off margin bell, xterm. Ps = 4 4 -> Disable Graphic Print Color Mode (DECGPCM), VT340. Ps = 4 5 -> No Reverse-wraparound mode (XTREVWRAP), xterm. Ps = 4 5 -> Disable Graphic Print Color Syntax (DECGPCS), VT340. Ps = 4 6 -> Stop logging (XTLOGGING), xterm. This is normally disabled by a compile-time option. Ps = 4 7 -> Use Normal Screen Buffer, xterm. Ps = 4 7 -> Disable Graphic Rotated Print Mode (DECGRPM), VT340. Ps = 6 6 -> Numeric keypad mode (DECNKM), VT320. Ps = 6 7 -> Backarrow key sends delete (DECBKM), VT340, VT420. This sets the backarrowKey resource to "false". Ps = 6 9 -> Disable left and right margin mode (DECLRMM), VT420 and up. Ps = 8 0 -> Disable Sixel Display Mode (DECSDM), VT330, VT340, VT382. Turns on "Sixel Scrolling". See the section Sixel Graphics and mode 8 4 5 2 . Ps = 9 5 -> Clear screen when DECCOLM is set/reset (DECNCSM), VT510 and up. Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and release. See the section Mouse Tracking. Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking, xterm. Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking, xterm. See the section Button-event tracking. Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking, xterm. See the section Any-event tracking. Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events, xterm. Ps = 1 0 0 5 -> Disable UTF-8 Mouse Mode, xterm. Ps = 1 0 0 6 -> Disable SGR Mouse Mode, xterm. Ps = 1 0 0 7 -> Disable Alternate Scroll Mode, xterm. This corresponds to the alternateScroll resource. Ps = 1 0 1 0 -> Don't scroll to bottom on tty output (rxvt). This sets the scrollTtyOutput resource to "false". Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt). This sets the scrollKey resource to "false". Ps = 1 0 1 4 -> Disable fastScroll resource, xterm. Ps = 1 0 1 5 -> Disable urxvt Mouse Mode. Ps = 1 0 1 6 -> Disable SGR Mouse Pixel-Mode, xterm. Ps = 1 0 3 4 -> Don't interpret "meta" key, xterm. This disables the eightBitInput resource. Ps = 1 0 3 5 -> Disable special modifiers for Alt and NumLock keys, xterm. This disables the numLock resource. Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key, xterm. This disables the metaSendsEscape resource. Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad Delete key, xterm. Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key, xterm. This disables the altSendsEscape resource. Ps = 1 0 4 0 -> Do not keep selection when not highlighted, xterm. This disables the keepSelection resource. Ps = 1 0 4 1 -> Use the PRIMARY selection, xterm. This disables the selectToClipboard resource. Ps = 1 0 4 2 -> Disable Urgency window manager hint when Control-G is received, xterm. This disables the bellIsUrgent resource. Ps = 1 0 4 3 -> Disable raising of the window when Control- G is received, xterm. This disables the popOnBell resource. Ps = 1 0 4 5 -> No Extended Reverse-wraparound mode (XTREVWRAP2), xterm. Ps = 1 0 4 6 -> Disable switching to/from Alternate Screen Buffer, xterm. This works for terminfo-based systems, updating the titeInhibit resource. If currently using the Alternate Screen Buffer, xterm switches to the Normal Screen Buffer. Ps = 1 0 4 7 -> Use Normal Screen Buffer, xterm. Clear the screen first if in the Alternate Screen Buffer. This may be disabled by the titeInhibit resource. Ps = 1 0 4 8 -> Restore cursor as in DECRC, xterm. This may be disabled by the titeInhibit resource. Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor as in DECRC, xterm. This may be disabled by the titeInhibit resource. This combines the effects of the 1 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based applications rather than the 4 7 mode. Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode, xterm. Ps = 1 0 5 1 -> Reset Sun function-key mode, xterm. Ps = 1 0 5 2 -> Reset HP function-key mode, xterm. Ps = 1 0 5 3 -> Reset SCO function-key mode, xterm. Ps = 1 0 6 0 -> Reset legacy keyboard emulation, i.e, X11R6, xterm. Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style, xterm. Ps = 2 0 0 1 -> Disable readline mouse button-1, xterm. Ps = 2 0 0 2 -> Disable readline mouse button-2, xterm. Ps = 2 0 0 3 -> Disable readline mouse button-3, xterm. Ps = 2 0 0 4 -> Reset bracketed paste mode, xterm. Ps = 2 0 0 5 -> Disable readline character-quoting, xterm. Ps = 2 0 0 6 -> Disable readline newline pasting, xterm. CSI Pm m Character Attributes (SGR). Ps = 0 -> Normal (default), VT100. Ps = 1 -> Bold, VT100. Ps = 2 -> Faint, decreased intensity, ECMA-48 2nd. Ps = 3 -> Italicized, ECMA-48 2nd. Ps = 4 -> Underlined, VT100. Ps = 5 -> Blink, VT100. This appears as Bold in X11R6 xterm. Ps = 7 -> Inverse, VT100. Ps = 8 -> Invisible, i.e., hidden, ECMA-48 2nd, VT300. Ps = 9 -> Crossed-out characters, ECMA-48 3rd. Ps = 2 1 -> Doubly-underlined, ECMA-48 3rd. Ps = 2 2 -> Normal (neither bold nor faint), ECMA-48 3rd. Ps = 2 3 -> Not italicized, ECMA-48 3rd. Ps = 2 4 -> Not underlined, ECMA-48 3rd. Ps = 2 5 -> Steady (not blinking), ECMA-48 3rd. Ps = 2 7 -> Positive (not inverse), ECMA-48 3rd. Ps = 2 8 -> Visible, i.e., not hidden, ECMA-48 3rd, VT300. Ps = 2 9 -> Not crossed-out, ECMA-48 3rd. Ps = 3 0 -> Set foreground color to Black. Ps = 3 1 -> Set foreground color to Red. Ps = 3 2 -> Set foreground color to Green. Ps = 3 3 -> Set foreground color to Yellow. Ps = 3 4 -> Set foreground color to Blue. Ps = 3 5 -> Set foreground color to Magenta. Ps = 3 6 -> Set foreground color to Cyan. Ps = 3 7 -> Set foreground color to White. Ps = 3 9 -> Set foreground color to default, ECMA-48 3rd. Ps = 4 0 -> Set background color to Black. Ps = 4 1 -> Set background color to Red. Ps = 4 2 -> Set background color to Green. Ps = 4 3 -> Set background color to Yellow. Ps = 4 4 -> Set background color to Blue. Ps = 4 5 -> Set background color to Magenta. Ps = 4 6 -> Set background color to Cyan. Ps = 4 7 -> Set background color to White. Ps = 4 9 -> Set background color to default, ECMA-48 3rd. Some of the above note the edition of ECMA-48 which first describes a feature. In its successive editions from 1979 to 1991 (2nd 1979, 3rd 1984, 4th 1986, and 5th 1991), ECMA-48 listed codes through 6 5 (skipping several toward the end of the range). Most of the ECMA-48 codes not implemented in xterm were never implemented in a hardware terminal. Several (such as 3 9 and 4 9 ) are either noted in ECMA-48 as implementation defined, or described in vague terms. The successive editions of ECMA-48 give little attention to changes from one edition to the next, except to comment on features which have become obsolete. ECMA-48 1st (1976) is unavailable; there is no reliable source of information which states whether "ANSI" color was defined in that edition, or later (1979). The VT100 (1978) implemented the most commonly used non-color video attributes which are given in the 2nd edition. While 8-color support is described in ECMA-48 2nd edition, the VT500 series (introduced in 1993) were the first DEC terminals implementing "ANSI" color. The DEC terminal's use of color is known to differ from xterm; useful documentation on this series became available too late to influence xterm. If 16-color support is compiled, the following aixterm controls apply. Assume that xterm's resources are set so that the ISO color codes are the first 8 of a set of 16. Then the aixterm colors are the bright versions of the ISO colors: Ps = 9 0 -> Set foreground color to Black. Ps = 9 1 -> Set foreground color to Red. Ps = 9 2 -> Set foreground color to Green. Ps = 9 3 -> Set foreground color to Yellow. Ps = 9 4 -> Set foreground color to Blue. Ps = 9 5 -> Set foreground color to Magenta. Ps = 9 6 -> Set foreground color to Cyan. Ps = 9 7 -> Set foreground color to White. Ps = 1 0 0 -> Set background color to Black. Ps = 1 0 1 -> Set background color to Red. Ps = 1 0 2 -> Set background color to Green. Ps = 1 0 3 -> Set background color to Yellow. Ps = 1 0 4 -> Set background color to Blue. Ps = 1 0 5 -> Set background color to Magenta. Ps = 1 0 6 -> Set background color to Cyan. Ps = 1 0 7 -> Set background color to White. If xterm is compiled with the 16-color support disabled, it supports the following, from rxvt: Ps = 1 0 0 -> Set foreground and background color to default. XTerm maintains a color palette whose entries are identified by an index beginning with zero. If 88- or 256-color support is compiled, the following apply: o All parameters are decimal integers. o RGB values range from zero (0) to 255. o The 88- and 256-color support uses subparameters described in ISO-8613-6 for indexed color. ISO-8613-6 also mentions direct color, using a similar scheme. xterm supports that, too. o xterm allows either colons (standard) or semicolons (legacy) to separate the subparameters (but after the first colon, colons must be used). The indexed- and direct-color features are summarized in the FAQ, which explains why semicolon is accepted as a subparameter delimiter: Can I set a color by its number? These ISO-8613-6 controls (marked in ECMA-48 5th edition as "reserved for future standardization") are supported by xterm: Ps = 3 8 : 2 : Pi : Pr : Pg : Pb -> Set foreground color using RGB values. If xterm is not compiled with direct-color support, it uses the closest match in its palette for the given RGB Pr/Pg/Pb. The color space identifier Pi is ignored. Ps = 3 8 : 5 : Ps -> Set foreground color to Ps, using indexed color. Ps = 4 8 : 2 : Pi : Pr : Pg : Pb -> Set background color using RGB values. If xterm is not compiled with direct-color support, it uses the closest match in its palette for the given RGB Pr/Pg/Pb. The color space identifier Pi is ignored. Ps = 4 8 : 5 : Ps -> Set background color to Ps, using indexed color. This variation on ISO-8613-6 is supported for compatibility with KDE konsole: Ps = 3 8 ; 2 ; Pr ; Pg ; Pb -> Set foreground color using RGB values. If xterm is not compiled with direct-color support, it uses the closest match in its palette for the given RGB Pr/Pg/Pb. Ps = 4 8 ; 2 ; Pr ; Pg ; Pb -> Set background color using RGB values. If xterm is not compiled with direct-color support, it uses the closest match in its palette for the given RGB Pr/Pg/Pb. In each case, if xterm is compiled with direct-color support, and the resource directColor is true, then rather than choosing the closest match, xterm asks the X server to directly render a given color. CSI > Pp ; Pv m CSI > Pp m Set/reset key modifier options (XTMODKEYS), xterm. Set or reset resource-values used by xterm to decide whether to construct escape sequences holding information about the modifiers pressed with a given key. The first parameter Pp identifies the resource to set/reset. The second parameter Pv is the value to assign to the resource. If the second parameter is omitted, the resource is reset to its initial value. Value 5 is reserved for input via the string action. Pp = 0 -> modifyKeyboard. Pp = 1 -> modifyCursorKeys. Pp = 2 -> modifyFunctionKeys. Pp = 3 -> modifyKeypadKeys. Pp = 4 -> modifyOtherKeys. Pp = 6 -> modifyModifierKeys. Pp = 7 -> modifySpecialKeys. If no parameters are given, all resources are reset to their initial values. See Alt and Meta Keys for more details on the modifyOtherKeys feature. CSI ? Pp m Query key modifier options (XTQMODKEYS), xterm. The parameter Pp identifies the resource to query. Pp = 0 -> modifyKeyboard. Pp = 1 -> modifyCursorKeys. Pp = 2 -> modifyFunctionKeys. Pp = 3 -> modifyKeypadKeys. Pp = 4 -> modifyOtherKeys. Pp = 6 -> modifyModifierKeys. Pp = 7 -> modifySpecialKeys. XTerm's response can be used to restore this state, because it is formatted as an XTMODKEYS control, i.e., CSI > Pp m where Pp = 0 -> modifyKeyboard. Pp = 1 -> modifyCursorKeys. Pp = 2 -> modifyFunctionKeys. Pp = 3 -> modifyKeypadKeys. Pp = 4 -> modifyOtherKeys. Pp = 6 -> modifyModifierKeys. Pp = 7 -> modifySpecialKeys. CSI Ps n Device Status Report (DSR). Ps = 5 -> Status Report. Result ("OK") is CSI 0 n Ps = 6 -> Report Cursor Position (CPR) [row;column]. Result is CSI r ; c R Note: it is possible for this sequence to be sent by a function key. For example, with the default keyboard configuration the shifted F3 key may send (with shift-, control-, alt-modifiers) CSI 1 ; 2 R , or CSI 1 ; 5 R , or CSI 1 ; 6 R , etc. The second parameter encodes the modifiers; values range from 2 to 16. See the section PC-Style Function Keys for the codes. The modifyFunctionKeys and modifyKeyboard resources can change the form of the string sent from the modified F3 key. CSI > Ps n Disable key modifier options, xterm. These modifiers may be enabled via the CSI > Pm m sequence. This control sequence corresponds to a resource value of "-1", which cannot be set with the other sequence. The parameter identifies the resource to be disabled: Ps = 0 -> modifyKeyboard. Ps = 1 -> modifyCursorKeys. Ps = 2 -> modifyFunctionKeys. Ps = 3 -> modifyKeypadKeys. Ps = 4 -> modifyOtherKeys. Ps = 6 -> modifyModifierKeys. Ps = 7 -> modifySpecialKeys. If the parameter is omitted, modifyFunctionKeys is disabled. When modifyFunctionKeys is disabled, xterm uses the modifier keys to make an extended sequence of function keys rather than adding a parameter to each function key to denote the modifiers. CSI ? Ps n Device Status Report (DSR, DEC-specific). Ps = 6 -> Report Cursor Position (DECXCPR). The response [row;column] is returned as CSI ? r ; c R (assumes the default page, i.e., "1"). Ps = 1 5 -> Report Printer status. The response is CSI ? 1 0 n (ready). or CSI ? 1 1 n (not ready). Ps = 2 5 -> Report UDK status. The response is CSI ? 2 0 n (unlocked) or CSI ? 2 1 n (locked). Ps = 2 6 -> Report Keyboard status. The response is CSI ? 2 7 ; 1 ; 0 ; 0 n (North American). The last two parameters apply to VT300 & up (keyboard ready) and VT400 & up (LK01) respectively. Ps = 5 5 -> Report Locator status. The response is CSI ? 5 0 n Locator available, if compiled-in, or CSI ? 5 3 n No Locator, if not. Ps = 5 6 -> Report Locator type. The response is CSI ? 5 7 ; 1 n Mouse, if compiled-in, or CSI ? 5 7 ; 0 n Cannot identify, if not. Ps = 6 2 -> Report macro space (DECMSR). The response is CSI Pn * { . Ps = 6 3 -> Report memory checksum (DECCKSR), VT420 and up. The response is DCS Pt ! ~ x x x x ST . Pt is the request id (from an optional parameter to the request). The x's are hexadecimal digits 0-9 and A-F. Ps = 7 5 -> Report data integrity. The response is CSI ? 7 0 n (ready, no errors). Ps = 8 5 -> Report multi-session configuration. The response is CSI ? 8 3 n (not configured for multiple-session operation). CSI > Ps p Set resource value pointerMode (XTSMPOINTER), xterm. This is used by xterm to decide whether to hide the pointer cursor as the user types. Valid values for the parameter: Ps = 0 -> never hide the pointer. Ps = 1 -> hide if the mouse tracking mode is not enabled. Ps = 2 -> always hide the pointer, except when leaving the window. Ps = 3 -> always hide the pointer, even if leaving/entering the window. If no parameter is given, xterm uses the default, which is 1 . CSI ! p Soft terminal reset (DECSTR), VT220 and up. CSI Pl ; Pc " p Set conformance level (DECSCL), VT220 and up. The first parameter selects the conformance level. Valid values are: Pl = 6 1 -> level 1, e.g., VT100. Pl = 6 2 -> level 2, e.g., VT200. Pl = 6 3 -> level 3, e.g., VT300. Pl = 6 4 -> level 4, e.g., VT400. Pl = 6 5 -> level 5, e.g., VT500. The second parameter selects the C1 control transmission mode. This is an optional parameter, ignored in conformance level 1. Valid values are: Pc = 0 -> 8-bit controls. Pc = 1 -> 7-bit controls (DEC factory default). Pc = 2 -> 8-bit controls. The 7-bit and 8-bit control modes can also be set by S7C1T and S8C1T, but DECSCL is preferred. CSI Ps $ p Request ANSI mode (DECRQM). For VT300 and up, reply DECRPM is CSI Ps ; Pm $ y where Ps is the mode number as in SM/RM, and Pm is the mode value: 0 - not recognized 1 - set 2 - reset 3 - permanently set 4 - permanently reset CSI ? Ps $ p Request DEC private mode (DECRQM). For VT300 and up, reply DECRPM is CSI ? Ps ; Pm $ y where Ps is the mode number as in DECSET/DECSET, Pm is the mode value as in the ANSI DECRQM. Two private modes are read-only (i.e., 1 3 and 1 4 ), provided only for reporting their values using this control sequence. They correspond to the resources cursorBlink and cursorBlinkXOR. CSI # p CSI Pm # p Push video attributes onto stack (XTPUSHSGR), xterm. This is an alias for CSI # { , used to work around language limitations of C#. CSI > Ps q Ps = 0 -> Report xterm name and version (XTVERSION). The response is a DSR sequence identifying the version: DCS > | text ST CSI Ps q Load LEDs (DECLL), VT100. Ps = 0 -> Clear all LEDS (default). Ps = 1 -> Light Num Lock. Ps = 2 -> Light Caps Lock. Ps = 3 -> Light Scroll Lock. Ps = 2 1 -> Extinguish Num Lock. Ps = 2 2 -> Extinguish Caps Lock. Ps = 2 3 -> Extinguish Scroll Lock. CSI Ps SP q Set cursor style (DECSCUSR), VT520. Ps = 0 -> blinking block. Ps = 1 -> blinking block (default). Ps = 2 -> steady block. Ps = 3 -> blinking underline. Ps = 4 -> steady underline. Ps = 5 -> blinking bar, xterm. Ps = 6 -> steady bar, xterm. CSI Ps " q Select character protection attribute (DECSCA), VT220. Valid values for the parameter: Ps = 0 -> DECSED and DECSEL can erase (default). Ps = 1 -> DECSED and DECSEL cannot erase. Ps = 2 -> DECSED and DECSEL can erase. CSI # q Pop video attributes from stack (XTPOPSGR), xterm. This is an alias for CSI # } , used to work around language limitations of C#. CSI Ps ; Ps r Set Scrolling Region [top;bottom] (default = full size of window) (DECSTBM), VT100. CSI ? Pm r Restore DEC Private Mode Values (XTRESTORE), xterm. The value of Ps previously saved is restored. Ps values are the same as for DECSET. Like Restore Cursor (DECRC), this uses a one-level cache. Unlike Restore Cursor, specific settings can be saved and restored independently. Only those modes listed as parameters are restored. CSI Pt ; Pl ; Pb ; Pr ; Pm $ r Change Attributes in Rectangular Area (DECCARA), VT400 and up. Pt ; Pl ; Pb ; Pr denotes the rectangle. Pm denotes the SGR attributes to change: 0 , 1 , 4 , 5 , 7 , 8 . Setting SGR 0 resets modes 1 , 4 , 5 , 7 . Those modes can be individually reset with SGR 2 2 , 2 4 , 2 5 and 2 7 . Setting SGR 8 is an xterm extension; it may be reset with SGR 2 8 . See DECSACE. CSI s Save cursor, available only when DECLRMM is disabled (SCOSC, also ANSI.SYS). CSI Pl ; Pr s Set left and right margins (DECSLRM), VT420 and up. This is available only when DECLRMM is enabled. CSI > Ps s Set/reset shift-escape options (XTSHIFTESCAPE), xterm. This corresponds to the shiftEscape resource. Valid values for the parameter: Ps = 0 -> allow shift-key to override mouse protocol. Ps = 1 -> conditionally allow shift-key as modifier in mouse protocol. These resource values are disallowed in the control sequence: Ps = 2 -> always allow shift-key as modifier in mouse protocol. Ps = 3 -> never allow shift-key as modifier in mouse protocol. If no parameter is given, xterm uses the default, which is 0 . CSI ? Pm s Save DEC Private Mode Values (XTSAVE), xterm. Ps values are the same as for DECSET. Like Save Cursor (DECSC), this uses a one-level cache. Unlike Save Cursor, specific settings can be saved and restored independently. Only those modes listed as parameters are saved. CSI Ps ; Ps ; Ps t Window manipulation (XTWINOPS), dtterm, extended by xterm. These controls may be disabled using the allowWindowOps resource. xterm uses Extended Window Manager Hints (EWMH) to maximize the window. Some window managers have incomplete support for EWMH. For instance, fvwm, flwm and quartz-wm advertise support for maximizing windows horizontally or vertically, but in fact equate those to the maximize operation. Valid values for the first (and any additional parameters) are: Ps = 1 -> De-iconify window. Ps = 2 -> Iconify window. Ps = 3 ; x ; y -> Move window to [x, y]. Ps = 4 ; height ; width -> Resize the xterm window to given height and width in pixels. Omitted parameters reuse the current height or width. Zero parameters use the display's height or width. Ps = 5 -> Raise the xterm window to the front of the stacking order. Ps = 6 -> Lower the xterm window to the bottom of the stacking order. Ps = 7 -> Refresh the xterm window. Ps = 8 ; height ; width -> Resize the text area to given height and width in characters. Omitted parameters reuse the current height or width. Zero parameters use the display's height or width. Ps = 9 ; 0 -> Restore maximized window. Ps = 9 ; 1 -> Maximize window (i.e., resize to screen size). Ps = 9 ; 2 -> Maximize window vertically. Ps = 9 ; 3 -> Maximize window horizontally. Ps = 1 0 ; 0 -> Undo full-screen mode. Ps = 1 0 ; 1 -> Change to full-screen. Ps = 1 0 ; 2 -> Toggle full-screen. Ps = 1 1 -> Report xterm window state. If the xterm window is non-iconified, it returns CSI 1 t . If the xterm window is iconified, it returns CSI 2 t . Ps = 1 3 -> Report xterm window position. Note: X Toolkit positions can be negative, but the reported values are unsigned, in the range 0-65535. Negative values correspond to 32768-65535. Result is CSI 3 ; x ; y t Ps = 1 3 ; 2 -> Report xterm text-area position. Result is CSI 3 ; x ; y t Ps = 1 4 -> Report xterm text area size in pixels. Result is CSI 4 ; height ; width t Ps = 1 4 ; 2 -> Report xterm window size in pixels. Normally xterm's window is larger than its text area, since it includes the frame (or decoration) applied by the window manager, as well as the area used by a scroll-bar. Result is CSI 4 ; height ; width t Ps = 1 5 -> Report size of the screen in pixels. Result is CSI 5 ; height ; width t Ps = 1 6 -> Report xterm character cell size in pixels. Result is CSI 6 ; height ; width t Ps = 1 8 -> Report the size of the text area in characters. Result is CSI 8 ; height ; width t Ps = 1 9 -> Report the size of the screen in characters. Result is CSI 9 ; height ; width t Ps = 2 0 -> Report xterm window's icon label. Result is OSC L label ST Ps = 2 1 -> Report xterm window's title. Result is OSC l label ST Ps = 2 2 ; 0 -> Save xterm icon and window title on stack. Ps = 2 2 ; 1 -> Save xterm icon title on stack. Ps = 2 2 ; 2 -> Save xterm window title on stack. Ps = 2 3 ; 0 -> Restore xterm icon and window title from stack. Ps = 2 3 ; 1 -> Restore xterm icon title from stack. Ps = 2 3 ; 2 -> Restore xterm window title from stack. Ps >= 2 4 -> Resize to Ps lines (DECSLPP), VT340 and VT420. xterm adapts this by resizing its window. XTWINOPS 2 2 (save/push title) and 2 3 (restore/pop title) accept an optional third parameter for direct access to the stack. Parameters in the range 1 through 10, may be used to store the title into the stack or retrieve the title from the stack without pushing/popping. CSI > Pm t This xterm control sets one or more features of the title modes (XTSMTITLE), xterm. Each parameter enables a single feature. Ps = 0 -> Set window/icon labels using hexadecimal. Ps = 1 -> Query window/icon labels using hexadecimal. Ps = 2 -> Set window/icon labels using UTF-8. Ps = 3 -> Query window/icon labels using UTF-8. (See discussion of Title Modes) If no parameters are given, title mode features are set to the initial (compiled-in) default. CSI Ps SP t Set warning-bell volume (DECSWBV), VT520. Ps = 0 or 1 -> off. Ps = 2 , 3 or 4 -> low. Ps = 5 , 6 , 7 , or 8 -> high. CSI Pt ; Pl ; Pb ; Pr ; Pm $ t Reverse Attributes in Rectangular Area (DECRARA), VT400 and up. Pt ; Pl ; Pb ; Pr denotes the rectangle. Pm denotes the attributes to reverse, i.e., 0, 1, 4, 5, 7, 8. Reversing SGR 0 reverses modes 1, 4, 5, 7. Reversing SGR 8 is an xterm extension. See DECSACE. CSI u Restore cursor (SCORC, also ANSI.SYS). CSI & u User-Preferred Supplemental Set (DECRQUPSS), VT320, VT510. Response is DECAUPSS. CSI Ps SP u Set margin-bell volume (DECSMBV), VT520. Ps = 0 , 5 , 6 , 7 , or 8 -> high. Ps = 1 -> off. Ps = 2 , 3 or 4 -> low. CSI " v Request Displayed Extent (DECRQDE), VT340, VT420. Response is CSI Ph ; Pw ; Pc ; Pr ; Pp " w where Ph is the number of lines of the current page Pw is the number of columns of the current page Pc is the column number at the top-left of the window Pr is the row number at the top-left of the window Pp is the current page number CSI Pt ; Pl ; Pb ; Pr ; Pp ; Pt ; Pl ; Pp $ v Copy Rectangular Area (DECCRA), VT400 and up. Pt ; Pl ; Pb ; Pr denotes the rectangle. Pp denotes the source page. Pt ; Pl denotes the target location. Pp denotes the target page. CSI Ps $ w Request presentation state report (DECRQPSR), VT320 and up. Ps = 0 -> error. Ps = 1 -> cursor information report (DECCIR). Response is DCS 1 $ u Pt ST Refer to the VT420 programming manual, which requires six pages to document the data string Pt, Ps = 2 -> tab stop report (DECTABSR). Response is DCS 2 $ u Pt ST The data string Pt is a list of the tab-stops, separated by "/" characters. CSI Pt ; Pl ; Pb ; Pr ' w Enable Filter Rectangle (DECEFR), VT420 and up. Parameters are [top;left;bottom;right]. Defines the coordinates of a filter rectangle and activates it. Anytime the locator is detected outside of the filter rectangle, an outside rectangle event is generated and the rectangle is disabled. Filter rectangles are always treated as "one-shot" events. Any parameters that are omitted default to the current locator position. If all parameters are omitted, any locator motion will be reported. DECELR always cancels any previous rectangle definition. CSI Ps x Request Terminal Parameters (DECREQTPARM). if Ps is a "0" (default) or "1", and xterm is emulating VT100, the control sequence elicits a response of the same form whose parameters describe the terminal: Ps -> the given Ps incremented by 2. Pn = 1 <- no parity. Pn = 1 <- eight bits. Pn = 1 <- 2 8 transmit 38.4k baud. Pn = 1 <- 2 8 receive 38.4k baud. Pn = 1 <- clock multiplier. Pn = 0 <- STP flags. CSI Ps * x Select Attribute Change Extent (DECSACE), VT420 and up. Ps = 0 -> from start to end position, wrapped. Ps = 1 -> from start to end position, wrapped. Ps = 2 -> rectangle (exact). Modes 0 and 1 are the stream modes of the DECCARA and DECRARA controls. There are several aspects to stream versus rectangle modes: 1) In both stream and rectangle modes, the row- and column- positions are affected by Origin Mode. 2) In rectangle mode, cells outside the row- and column- positions are unaffected. In stream mode, the row- and column-positions are the starting and ending cells, with wrapping which ignores Origin Mode. 3) In stream mode, those controls affect only cells where a character was drawn. In rectangle mode, cells where no character was drawn are first filled in with a space. CSI Pc ; Pt ; Pl ; Pb ; Pr $ x Fill Rectangular Area (DECFRA), VT420 and up. Pc is the character to use. Pt ; Pl ; Pb ; Pr denotes the rectangle. CSI Ps # y Select checksum extension (XTCHECKSUM), xterm. The bits of Ps modify the calculation of the checksum returned by DECRQCRA: 0 -> do not negate the result. 1 -> do not report the VT100 video attributes. 2 -> do not omit checksum for blanks. 3 -> omit checksum for cells not explicitly initialized. 4 -> do not mask cell value to 8 bits or ignore combining characters. CSI Pi ; Pg ; Pt ; Pl ; Pb ; Pr * y Request Checksum of Rectangular Area (DECRQCRA), VT420 and up. Response is DCS Pi ! ~ x x x x ST Pi is the request id. Pg is the page number. Pt ; Pl ; Pb ; Pr denotes the rectangle. The x's are hexadecimal digits 0-9 and A-F. CSI Ps ; Pu ' z Enable Locator Reporting (DECELR). Valid values for the first parameter: Ps = 0 -> Locator disabled (default). Ps = 1 -> Locator enabled. Ps = 2 -> Locator enabled for one report, then disabled. The second parameter specifies the coordinate unit for locator reports. Valid values for the second parameter: Pu = 0 or omitted -> default to character cells. Pu = 1 <- device physical pixels. Pu = 2 <- character cells. CSI Pt ; Pl ; Pb ; Pr $ z Erase Rectangular Area (DECERA), VT400 and up. Pt ; Pl ; Pb ; Pr denotes the rectangle. CSI Pm ' { Select Locator Events (DECSLE). Valid values for the first (and any additional parameters) are: Ps = 0 -> only respond to explicit host requests (DECRQLP). This is default. It also cancels any filter rectangle. Ps = 1 -> report button down transitions. Ps = 2 -> do not report button down transitions. Ps = 3 -> report button up transitions. Ps = 4 -> do not report button up transitions. CSI # { CSI Pm # { Push video attributes onto stack (XTPUSHSGR), xterm. The optional parameters correspond to the SGR encoding for video attributes, except for colors (which do not have a unique SGR code): Ps = 1 -> Bold. Ps = 2 -> Faint. Ps = 3 -> Italicized. Ps = 4 -> Underlined. Ps = 5 -> Blink. Ps = 7 -> Inverse. Ps = 8 -> Invisible. Ps = 9 -> Crossed-out characters. Ps = 2 1 -> Doubly-underlined. Ps = 3 0 -> Foreground color. Ps = 3 1 -> Background color. If no parameters are given, all of the video attributes are saved. The stack is limited to 10 levels. CSI Pt ; Pl ; Pb ; Pr $ { Selective Erase Rectangular Area (DECSERA), VT400 and up. Pt ; Pl ; Pb ; Pr denotes the rectangle. CSI Pt ; Pl ; Pb ; Pr # | Report selected graphic rendition (XTREPORTSGR), xterm. The response is an SGR sequence which contains the attributes which are common to all cells in a rectangle. Pt ; Pl ; Pb ; Pr denotes the rectangle. CSI Ps $ | Select columns per page (DECSCPP), VT340. Ps = 0 -> 80 columns, default if Ps omitted. Ps = 8 0 -> 80 columns. Ps = 1 3 2 -> 132 columns. CSI Ps ' | Request Locator Position (DECRQLP). Valid values for the parameter are: Ps = 0 , 1 or omitted -> transmit a single DECLRP locator report. If Locator Reporting has been enabled by a DECELR, xterm will respond with a DECLRP Locator Report. This report is also generated on button up and down events if they have been enabled with a DECSLE, or when the locator is detected outside of a filter rectangle, if filter rectangles have been enabled with a DECEFR. <- CSI Pe ; Pb ; Pr ; Pc ; Pp & w Parameters are [event;button;row;column;page]. Valid values for the event: Pe = 0 <- locator unavailable - no other parameters sent. Pe = 1 <- request - xterm received a DECRQLP. Pe = 2 <- left button down. Pe = 3 <- left button up. Pe = 4 <- middle button down. Pe = 5 <- middle button up. Pe = 6 <- right button down. Pe = 7 <- right button up. Pe = 8 <- M4 button down. Pe = 9 <- M4 button up. Pe = 1 0 <- locator outside filter rectangle. The "button" parameter is a bitmask indicating which buttons are pressed: Pb = 0 <- no buttons down. Pb & 1 <- right button down. Pb & 2 <- middle button down. Pb & 4 <- left button down. Pb & 8 <- M4 button down. The "row" and "column" parameters are the coordinates of the locator position in the xterm window, encoded as ASCII decimal. The "page" parameter is not used by xterm. CSI Ps * | Select number of lines per screen (DECSNLS), VT420 and up. CSI # } Pop video attributes from stack (XTPOPSGR), xterm. Popping restores the video-attributes which were saved using XTPUSHSGR to their previous state. CSI Ps ; Pf ; Pb , | Assign Color (DECAC), VT525 only. Ps selects the color item Pf is the foreground color index 0..15 Pb is the background color index 0..15 Color items: Ps = 1 -> normal text Ps = 2 -> window frame xterm uses the SGR color palette with DECAC color item 1 to update the VT100 window colors, like OSC 1 0 and 1 1 . CSI Ps ; Pf ; Pb , } Alternate Text Color (DECATC), VT525 only. This feature specifies the colors to use when DECSTGLT is selected to 1 or 2. Ps selects attribute combinations Pf is the foreground color index 0..15 Pb is the background color index 0..15 Attribute combinations: Ps = 0 -> normal text Ps = 1 -> bold Ps = 2 -> reverse Ps = 3 -> underline Ps = 4 -> blink Ps = 5 -> bold reverse Ps = 6 -> bold underline Ps = 7 -> bold blink Ps = 8 -> reverse underline Ps = 9 -> reverse blink Ps = 1 0 -> underline blink Ps = 1 1 -> bold reverse underline Ps = 1 2 -> bold reverse blink Ps = 1 3 -> bold underline blink Ps = 1 4 -> reverse underline blink Ps = 1 5 -> bold reverse underline blink CSI Ps ' } Insert Ps Column(s) (default = 1) (DECIC), VT420 and up. CSI Ps $ } Select active status display (DECSASD), VT320 and up. Ps = 0 -> main (default) Ps = 1 -> status line CSI Ps ' ~ Delete Ps Column(s) (default = 1) (DECDC), VT420 and up. CSI Ps $ ~ Select status line type (DECSSDT), VT320 and up. Ps = 0 -> none Ps = 1 -> indicator (default) Ps = 2 -> host-writable. Operating System Commands OSC Ps ; Pt BEL OSC Ps ; Pt ST Set Text Parameters, xterm. Some control sequences return information: o For colors and font, if Pt is a "?", the control sequence elicits a response which consists of the control sequence which would set the corresponding value. o A few of these control sequences began with dtterm (codes 0 , 1 , and 2 ). Code 3 in dtterm sets the working directory for the next session. XTerm does that with the spawn-new-terminal action. XTerm accepts either BEL or ST for terminating OSC sequences, and when returning information, uses the same terminator used in a query. While the latter is preferred, the former is supported for legacy applications: o Although documented in the changes for X.V10R4 (December 1986), BEL as a string terminator dates from X11R4 (December 1989). o Since XFree86-3.1.2Ee (August 1996), xterm has accepted ST (the documented string terminator in ECMA-48). Ps specifies the type of operation to perform: Ps = 0 -> Change Icon Name and Window Title to Pt. Ps = 1 -> Change Icon Name to Pt. Ps = 2 -> Change Window Title to Pt. Ps = 3 -> Set X property on top-level window. Pt should be in the form "prop=value", or just "prop" to delete the property. Ps = 4 ; c ; spec -> Change Color Number c to the color specified by spec. The spec can be a name or RGB specification as per XParseColor. Any number of c/spec pairs may be given. The color numbers correspond to the ANSI colors 0-7, their bright versions 8-15, and if supported, the remainder of the 88-color or 256-color table. If a "?" is given rather than a name or RGB specification, xterm replies with a control sequence of the same form which can be used to set the corresponding color. Because more than one pair of color number and specification can be given in one control sequence, xterm can make more than one reply. Ps = 5 ; c ; spec -> Change Special Color Number c to the color specified by spec. The spec parameter can be a name or RGB specification as per XParseColor. Any number of c/spec pairs may be given. The special colors can also be set by adding the maximum number of colors (e.g., 88 or 256) to these codes in an OSC 4 control: Pc = 0 <- resource colorBD (BOLD). Pc = 1 <- resource colorUL (UNDERLINE). Pc = 2 <- resource colorBL (BLINK). Pc = 3 <- resource colorRV (REVERSE). Pc = 4 <- resource colorIT (ITALIC). Ps = 6 ; c ; f -> Enable/disable Special Color Number c. The second parameter tells xterm to enable the corresponding color mode if nonzero, disable it if zero. OSC 6 is the same as OSC 1 0 6 . If no parameters are given, this control has no effect. The 10 colors (below) which may be set or queried using 1 0 through 1 9 are denoted dynamic colors, since the corresponding control sequences were the first means for setting xterm's colors dynamically, i.e., after it was started. They are not the same as the ANSI colors (however, the dynamic text foreground and background colors are used when ANSI colors are reset using SGR 3 9 and 4 9 , respectively). These controls may be disabled using the allowColorOps resource. At least one parameter is expected for Pt. Each successive parameter changes the next color in the list. The value of Ps tells the starting point in the list. The colors are specified by name or RGB specification as per XParseColor. Resource Description -----------------------+----------------------------- foreground | VT100 text foreground color background | VT100 text background color cursorColor | text cursor color pointerColor | pointer foreground color pointerColorBackground | pointer background (foreground) | Tektronix foreground color (background) | Tektronix background color highlightColor | highlight background color (cursorColor) | Tektronix cursor color highlightTextColor | highlight foreground color -----------------------+----------------------------- The Tektronix colors are initially set from the VT100 colors, but after that can be set independently using these control sequences. If a "?" is given rather than a name or RGB specification, xterm replies with a control sequence of the same form which can be used to set the corresponding dynamic color. Because more than one pair of color number and specification can be given in one control sequence, xterm can make more than one reply. Ps = 1 0 -> Change VT100 text foreground color to Pt. Ps = 1 1 -> Change VT100 text background color to Pt. Ps = 1 2 -> Change text cursor color to Pt. Ps = 1 3 -> Change pointer foreground color to Pt. Ps = 1 4 -> Change pointer background color to Pt. Ps = 1 5 -> Change Tektronix foreground color to Pt. Ps = 1 6 -> Change Tektronix background color to Pt. Ps = 1 7 -> Change highlight background color to Pt. Ps = 1 8 -> Change Tektronix cursor color to Pt. Ps = 1 9 -> Change highlight foreground color to Pt. Ps = 2 2 -> Change pointer cursor shape to Pt. The parameter Pt sets the pointerShape resource. If Pt is empty, or does not match any of the standard names, xterm uses the resource's default "xterm" shape. Ps = 4 6 -> Change Log File to Pt. The parameter Pt sets the logFile resource. Logging is normally disabled by a compile-time option. Ps = 5 0 -> Set Font to Pt. These controls may be disabled using the allowFontOps resource. If Pt begins with a "#", index in the font menu, relative (if the next character is a plus or minus sign) or absolute. A number is expected but not required after the sign (the default is the current entry for relative, zero for absolute indexing). The same rule (plus or minus sign, optional number) is used when querying the font. The remainder of Pt is ignored. A font can be specified after a "#" index expression, by adding a space and then the font specifier. If the TrueType Fonts menu entry is set (the renderFont resource), then this control sets/queries the faceName resource. Ps = 5 1 -> reserved for Emacs shell. Ps = 5 2 -> Manipulate Selection Data. These controls may be disabled using the allowWindowOps resource. The parameter Pt is parsed as Pc ; Pd The first, Pc, may contain zero or more characters from the set c , p , q , s , 0 , 1 , 2 , 3 , 4 , 5 , 6 , and 7 . It is used to construct a list of selection parameters for clipboard, primary, secondary, select, or cut-buffers 0 through 7 respectively, in the order given. If the parameter is empty, xterm uses s 0 , to specify the configurable primary/clipboard selection and cut-buffer 0. The second parameter, Pd, gives the selection data. Normally this is a string encoded in base64 (RFC-4648). The data becomes the new selection, which is then available for pasting by other applications. If the second parameter is a ? , xterm replies to the host with the selection data encoded using the same protocol. It uses the first selection found by asking successively for each item from the list of selection parameters. If the second parameter is neither a base64 string nor ? , then the selection is cleared. Ps = 6 0 -> Query allowed features (XTQALLOWED). XTerm replies with OSC 6 0 ; Pt ST where Pt is a comma-separated list of the allowed optional runtime features, i.e., zero or more of these resource names: allowColorOps allowFontOps allowMouseOps allowPasteControls allowTcapOps allowTitleOps allowWindowOps Ps = 6 1 -> Query disallowed features (XTQDISALLOWED). The second parameter (i.e., the main feature) must be one of the resource names returned by OSC 6 0 . XTerm replies with OSC 6 1 ; Pt ST where Pt is a comma-separated list of the optional runtime features which would be disallowed if the main feature is disabled. Ps = 1 0 4 ; c -> Reset Color Number c. It is reset to the color specified by the corresponding X resource. Any number of c parameters may be given. These parameters correspond to the ANSI colors 0-7, their bright versions 8-15, and if supported, the remainder of the 88-color or 256-color table. If no parameters are given, the entire table will be reset. Ps = 1 0 5 ; c -> Reset Special Color Number c. It is reset to the color specified by the corresponding X resource. Any number of c parameters may be given. These parameters correspond to the special colors which can be set using an OSC 5 control (or by adding the maximum number of colors using an OSC 4 control). If no parameters are given, all special colors will be reset. Ps = 1 0 6 ; c ; f -> Enable/disable Special Color Number c. The second parameter tells xterm to enable the corresponding color mode if nonzero, disable it if zero. Pc = 0 <- resource colorBDMode (BOLD). Pc = 1 <- resource colorULMode (UNDERLINE). Pc = 2 <- resource colorBLMode (BLINK). Pc = 3 <- resource colorRVMode (REVERSE). Pc = 4 <- resource colorITMode (ITALIC). Pc = 5 <- resource colorAttrMode (Override ANSI). If no parameters are given, this control has no effect. The dynamic colors can also be reset to their default (resource) values: Ps = 1 1 0 -> Reset VT100 text foreground color. Ps = 1 1 1 -> Reset VT100 text background color. Ps = 1 1 2 -> Reset text cursor color. Ps = 1 1 3 -> Reset pointer foreground color. Ps = 1 1 4 -> Reset pointer background color. Ps = 1 1 5 -> Reset Tektronix foreground color. Ps = 1 1 6 -> Reset Tektronix background color. Ps = 1 1 7 -> Reset highlight color. Ps = 1 1 8 -> Reset Tektronix cursor color. Ps = 1 1 9 -> Reset highlight foreground color. Ps = I ; c -> Set icon to file. Sun shelltool, CDE dtterm. The file is expected to be XPM format, and uses the same search logic as the iconHint resource. Ps = l ; c -> Set window title. Sun shelltool, CDE dtterm. Ps = L ; c -> Set icon label. Sun shelltool, CDE dtterm. Privacy Message PM Pt ST xterm implements no PM functions; Pt is ignored. Pt need not be printable characters. Special Keyboard Keys Terminal keyboards have two types of keys: o ordinary keys, which you would use as data, e.g., in a text file, and o special keys, which you would use to tell xterm to perform some action. XTerm detects all of these keys via X key-press and key-release events. It uses the translations resource to decide what to do with these events. o Ordinary keys are handled with the insert-seven-bit action, or the insert-eight-bit action. o Special keys may be handled with other resources. However, xterm also has built-in logic to map commonly-used special keys into characters which your keypress sends to the application running in xterm. Special keyboard keys send control characters or escape sequences. This is a convention, making it convenient for applications to detect these keys, rather than a standard. Alt and Meta Keys Many keyboards have keys labeled "Alt". Few have keys labeled "Meta". However, xterm's default translations use the Meta modifier. Common keyboard configurations assign the Meta modifier to an "Alt" key. By using xmodmap one may have the modifier assigned to a different key, and have "real" alt and meta keys. Here is an example: ! put meta on mod3 to distinguish it from alt keycode 64 = Alt_L clear mod1 add mod1 = Alt_L keycode 115 = Meta_L clear mod3 add mod3 = Meta_L The metaSendsEscape resource (and altSendsEscape if altIsNotMeta is set) can be used to control the way the Meta modifier applies to ordinary keys unless the modifyOtherKeys resource is set: o prefix a key with the ESC character. o shift the key from codes 0-127 to 128-255 by adding 128. The table shows the result for a given character "x" with modifiers according to the default translations with the resources set on or off. This assumes altIsNotMeta is set: key altSendsEscape metaSendsEscape result -----------+----------------+-----------------+------------ x | off | off | x Meta-x | off | off | shift Alt-x | off | off | shift Alt+Meta-x | off | off | shift x | ON | off | x Meta-x | ON | off | shift Alt-x | ON | off | ESC x Alt+Meta-x | ON | off | ESC shift x | off | ON | x Meta-x | off | ON | ESC x Alt-x | off | ON | shift Alt+Meta-x | off | ON | ESC shift x | ON | ON | x Meta-x | ON | ON | ESC x Alt-x | ON | ON | ESC x Alt+Meta-x | ON | ON | ESC x -----------+----------------+-----------------+------------ When modifyOtherKeys is set, ordinary keys may be sent as escape sequences: o When modifyOtherKeys is set to 1, the usual shift- and control- modifiers work as expected, but other modifiers (such as alt- and meta-modifiers) cause ordinary keys to be encoded as if they were function-keys. For example, alt-Tab sends CSI 2 7 ; 3 ; 9 ~ (the second parameter is "3" for alt, and the third parameter is the ASCII value of tab, "9"). Ordinary characters can have non-ASCII values. XTerm uses the X11 libraries to obtain the character encoding used for a given keysym (key symbol). The X11 keysymdef.h header lists 2104 predefined key symbols, as well as documenting how arbitrary Unicode values are represented. The other *keysym.h headers add 480 symbols. o When modifyOtherKeys is set to 2, all of the modifiers apply. For example, shift-Tab sends CSI 2 7 ; 2 ; 9 ~ rather than CSI Z (the second parameter is "2" for shift). o If modifyOtherKeys is set to 3, unmodified keys also are sent as escape sequences. For example, space sends CSI 2 7 ; 1 ; 3 2 ~ There are a few variations available; they can be set statically with resource values or dynamically using control sequences: o The formatOtherKeys resource tells xterm to change the format of the escape sequences sent when modifyOtherKeys applies. When modifyOtherKeys is set to 1, for example alt-Tab sends CSI 9 ; 3 u (changing the order of parameters). One drawback to this format is that applications may confuse it with CSI u (restore-cursor). The resource value can be updated with a corresponding control sequence. o The modifyOtherKeys resource can be updated via a corresponding control sequence. The control sequence accepts a single subparameter, which is interpreted as a mask of modifier bits to factor out of the parameter encoding of the escape sequence. For example CSI > 4 : 1 m factors out the shift modifier. Some of the predefined key symbols can be automatically derived, or are duplicates. That leaves about half of the key symbols which xterm may encounter. Most of these are non-character key symbols which may be assigned to positions on a keyboard. o The most common non-character key symbols are in the range 0xfd00 to 0xffff. XTerm maps them to the Unicode BMP private use area beginning at U+E001. These account for about a quarter (329) of the non-character symbols. o The other non-character key symbols are vendor/platform specific. Those use codes above 0x10000000. XTerm maps them to the Unicode BMP private use area beginning at U+F0000. o The remaining non-Unicode values are characters used in the DEC Technical character set. XTerm maps them to the Unicode BMP private use area beginning at U+EEEE. XTerm has additional resource settings (and control sequences) to send these non-character symbols as escape sequences. The Xutil.h header defines some of the macros which xterm uses for categorizing these non- character symbols: IsKeypadKey(keysym) is used for the numeric keypad (see modifyKeypadKeys and formatKeypadKeys). IsPrivateKeypadKey(keysym) is unused. IsCursorKey(keysym) is used for the cursor keys, including Home and End (see modifyCursorKeys and formatCursorKeys). XTerm makes a special check for the PC keyboard's editing keypad, which is not handled by the Xutil.h macros. IsPFKey(keysym) IsFunctionKey(keysym) IsMiscFunctionKey(keysym) are used for function keys (see modifyFunctionKeys and formatFunctionKeys). IsModifierKey(keysym) is used for modifier keys (see modifyModifierKeys and formatModifierKeys). These macros account for 162 of the 329 non-Unicode values in the BMP. The xterm FAQ sections How can my program distinguish control-I from tab? XTerm - "Other" Modified Keys go into greater detail on this topic. PC-Style Function Keys If xterm does minimal translation of the function keys, it usually does this with a PC-style keyboard, so PC-style function keys result. Sun keyboards are similar to PC keyboards. Both have cursor and scrolling operations printed on the keypad, which duplicate the smaller cursor and scrolling keypads. X does not predefine NumLock (used for VT220 keyboards) or Alt (used as an extension for the Sun/PC keyboards) as modifiers. These keys are recognized as modifiers when enabled by the numLock resource, or by the "DECSET 1 0 3 5 " control sequence. The cursor keys transmit the following escape sequences depending on the mode specified via the DECCKM escape sequence. Key Normal Application -------------+----------+------------- Cursor Up | CSI A | SS3 A Cursor Down | CSI B | SS3 B Cursor Right | CSI C | SS3 C Cursor Left | CSI D | SS3 D -------------+----------+------------- The home- and end-keys (unlike PageUp and other keys also on the 6-key editing keypad) are considered "cursor keys" by xterm. Their mode is also controlled by the DECCKM escape sequence: Key Normal Application ---------+----------+------------- Home | CSI H | SS3 H End | CSI F | SS3 F ---------+----------+------------- The application keypad transmits the following escape sequences depending on the mode specified via the DECKPNM and DECKPAM escape sequences. Use the NumLock key to override the application mode. Not all keys are present on the Sun/PC keypad (e.g., PF1, Tab), but are supported by the program. Key Numeric Application Terminfo Termcap ---------------+----------+-------------+----------+---------- Space | SP | SS3 SP | - | - Tab | TAB | SS3 I | - | - Enter | CR | SS3 M | kent | @8 PF1 | SS3 P | SS3 P | kf1 | k1 PF2 | SS3 Q | SS3 Q | kf2 | k2 PF3 | SS3 R | SS3 R | kf3 | k3 PF4 | SS3 S | SS3 S | kf4 | k4 * (multiply) | * | SS3 j | - | - + (add) | + | SS3 k | - | - , (comma) | , | SS3 l | - | - - (minus) | - | SS3 m | - | - . (Delete) | . | CSI 3 ~ | - | - / (divide) | / | SS3 o | - | - 0 (Insert) | 0 | CSI 2 ~ | - | - 1 (End) | 1 | SS3 F | kc1 | K4 2 (DownArrow) | 2 | CSI B | - | - 3 (PageDown) | 3 | CSI 6 ~ | kc3 | K5 4 (LeftArrow) | 4 | CSI D | - | - 5 (Begin) | 5 | CSI E | kb2 | K2 6 (RightArrow) | 6 | CSI C | - | - 7 (Home) | 7 | SS3 H | ka1 | K1 8 (UpArrow) | 8 | CSI A | - | - 9 (PageUp) | 9 | CSI 5 ~ | ka3 | K3 = (equal) | = | SS3 X | - | - ---------------+----------+-------------+----------+---------- They also provide 12 function keys, as well as a few other special- purpose keys: Key Escape Sequence ---------+----------------- F1 | SS3 P F2 | SS3 Q F3 | SS3 R F4 | SS3 S F5 | CSI 1 5 ~ F6 | CSI 1 7 ~ F7 | CSI 1 8 ~ F8 | CSI 1 9 ~ F9 | CSI 2 0 ~ F10 | CSI 2 1 ~ F11 | CSI 2 3 ~ F12 | CSI 2 4 ~ ---------+----------------- Note that F1 through F4 are prefixed with SS3 , while the other keys are prefixed with CSI . Older versions of xterm implement different escape sequences for F1 through F4, with a CSI prefix. These can be activated by setting the oldXtermFKeys resource. However, since they do not correspond to any hardware terminal, they have been deprecated. (The DEC VT220 reserves F1 through F5 for local functions such as Setup). Key Escape Sequence ---------+----------------- F1 | CSI 1 1 ~ F2 | CSI 1 2 ~ F3 | CSI 1 3 ~ F4 | CSI 1 4 ~ ---------+----------------- In normal mode, i.e., a Sun/PC keyboard when the sunKeyboard resource is false (and none of the other keyboard resources such as oldXtermFKeys resource is set), xterm encodes function key modifiers as parameters appended before the final character of the control sequence. As a special case, the SS3 sent before F1 through F4 is altered to CSI when sending a function key modifier as a parameter. Code Modifiers ---------+--------------------------- 2 | Shift 3 | Alt 4 | Shift + Alt 5 | Control 6 | Shift + Control 7 | Alt + Control 8 | Shift + Alt + Control 9 | Meta 10 | Meta + Shift 11 | Meta + Alt 12 | Meta + Alt + Shift 13 | Meta + Ctrl 14 | Meta + Ctrl + Shift 15 | Meta + Ctrl + Alt 16 | Meta + Ctrl + Alt + Shift ---------+--------------------------- For example, shift-F5 would be sent as CSI 1 5 ; 2 ~ If the alwaysUseMods resource is set, the Meta modifier also is recognized, making parameters 9 through 16. The codes used for the PC-style function keys were inspired by a feature of the VT510, referred to in its reference manual as DECFNK. In the DECFNK scheme, codes 2-8 identify modifiers for function-keys and cursor-, editing-keypad keys. Unlike xterm, the VT510 limits the modifiers which can be used with cursor- and editing-keypad keys. Although the name "DECFNK" implies that it is a mode, the VT510 manual mentions it only as a feature, which (like xterm) interacts with the DECUDK feature. Unlike xterm, VT510/VT520 provide an extension to DECUDK (DECPFK and DECPAK) which apparently was the reason for the feature in those terminals, i.e., for identifying a programmable key rather than making it simple for applications to obtain modifier information. It is not described in the related VT520 manual. Neither manual was readily available at the time the feature was added to xterm. On the other hand, the VT510 and VT520 reference manuals do document a related feature. That is its emulation of the SCO console, which is similar to the "xterm-sco" terminal description. The SCO console function-keys are less useful to applications developers than the approach used by xterm because o the relationship between modifiers and the characters sent by function-keys is not readily apparent, and o the scheme is not extensible, i.e., it is an ad hoc assignment limited to two modifiers (shift and control). VT220-Style Function Keys However, xterm is most useful as a DEC VT102 or VT220 emulator. Set the sunKeyboard resource to true to force a Sun/PC keyboard to act like a VT220 keyboard. The VT102/VT220 application keypad transmits unique escape sequences in application mode, which are distinct from the cursor and scrolling keypad: Key Numeric Application VT100? -------------+----------+-------------+---------- Space | SP | SS3 SP | no Tab | TAB | SS3 I | no Enter | CR | SS3 M | yes PF1 | SS3 P | SS3 P | yes PF2 | SS3 Q | SS3 Q | yes PF3 | SS3 R | SS3 R | yes PF4 | SS3 S | SS3 S | yes * (multiply) | * | SS3 j | no + (add) | + | SS3 k | no , (comma) | , | SS3 l | yes - (minus) | - | SS3 m | yes . (period) | . | SS3 n | yes / (divide) | / | SS3 o | no 0 | 0 | SS3 p | yes 1 | 1 | SS3 q | yes 2 | 2 | SS3 r | yes 3 | 3 | SS3 s | yes 4 | 4 | SS3 t | yes 5 | 5 | SS3 u | yes 6 | 6 | SS3 v | yes 7 | 7 | SS3 w | yes 8 | 8 | SS3 x | yes 9 | 9 | SS3 y | yes = (equal) | = | SS3 X | no -------------+----------+-------------+---------- The VT100/VT220 keypad did not have all of those keys. They were implemented in xterm in X11R1 (1987), defining a mapping of all X11 keys which might be provided on a keypad. For instance, a Sun4/II type-4 keyboard provided "=" (equal), "/" (divide), and "*" (multiply). While the VT420 provided the same keypad, the VT520 used a PC-keyboard. Because that keyboard's keypad lacks the "," (comma), it was not possible to use EDT's delete-character function with the keypad. XTerm solves that problem for the VT220-keyboard configuration by mapping Ctrl + to , and Ctrl - to - The VT220 provides a 6-key editing keypad, which is analogous to that on the PC keyboard. It is not affected by DECCKM or DECKPNM/DECKPAM: Key Normal Application ---------+----------+------------- Insert | CSI 2 ~ | CSI 2 ~ Delete | CSI 3 ~ | CSI 3 ~ Home | CSI 1 ~ | CSI 1 ~ End | CSI 4 ~ | CSI 4 ~ PageUp | CSI 5 ~ | CSI 5 ~ PageDown | CSI 6 ~ | CSI 6 ~ ---------+----------+------------- The VT220 provides 8 additional function keys. With a Sun/PC keyboard, access these keys by Control/F1 for F13, etc. Key Escape Sequence ---------+----------------- F13 | CSI 2 5 ~ F14 | CSI 2 6 ~ F15 | CSI 2 8 ~ F16 | CSI 2 9 ~ F17 | CSI 3 1 ~ F18 | CSI 3 2 ~ F19 | CSI 3 3 ~ F20 | CSI 3 4 ~ ---------+----------------- VT52-Style Function Keys A VT52 does not have function keys, but it does have a numeric keypad and cursor keys. They differ from the other emulations by the prefix. Also, the cursor keys do not change: Key Normal/Application -------------+-------------------- Cursor Up | ESC A Cursor Down | ESC B Cursor Right | ESC C Cursor Left | ESC D -------------+-------------------- The keypad is similar: Key Numeric Application VT52? -------------+----------+-------------+---------- Space | SP | ESC ? SP | no Tab | TAB | ESC ? I | no Enter | CR | ESC ? M | no PF1 | ESC P | ESC P | yes PF2 | ESC Q | ESC Q | yes PF3 | ESC R | ESC R | yes PF4 | ESC S | ESC S | no * (multiply) | * | ESC ? j | no + (add) | + | ESC ? k | no , (comma) | , | ESC ? l | no - (minus) | - | ESC ? m | no . (period) | . | ESC ? n | yes / (divide) | / | ESC ? o | no 0 | 0 | ESC ? p | yes 1 | 1 | ESC ? q | yes 2 | 2 | ESC ? r | yes 3 | 3 | ESC ? s | yes 4 | 4 | ESC ? t | yes 5 | 5 | ESC ? u | yes 6 | 6 | ESC ? v | yes 7 | 7 | ESC ? w | yes 8 | 8 | ESC ? x | yes 9 | 9 | ESC ? y | yes = (equal) | = | ESC ? X | no -------------+----------+-------------+---------- Sun-Style Function Keys The xterm program provides support for Sun keyboards more directly, by a menu toggle that causes it to send Sun-style function key codes rather than VT220. Note, however, that the sun and VT100 emulations are not really compatible. For example, their wrap-margin behavior differs. Only function keys are altered; keypad and cursor keys are the same. The emulation responds identically. See the xterm-sun terminfo entry for details. HP-Style Function Keys Similarly, xterm can be compiled to support HP keyboards. See the xterm-hp terminfo entry for details. Non-Function Keys On a DEC terminal keyboard, some of the keys which one would expect to see labeled as function keys had special names. The keys actually send character sequences as if they were the expected function keys, but the special names are used in documentation. Because other keyboards may use those names, xterm maps the X key symbols which have the corresponding names into the character sequences which the original DEC keyboard would send. These mappings are used for the DEC (VT220) and other keyboards: Label DEC SUN HP SCO --------------+------------+--------------+----------+---------- Up | SS3 A | SS3 A | ESC A | CSI A Down | SS3 B | SS3 B | ESC B | CSI B Right | SS3 C | SS3 C | ESC C | CSI C Left | SS3 D | SS3 D | ESC D | CSI D Clear | - | - | ESC J | - Find | CSI 1 ~ | CSI 1 z | ESC h | - Insert | CSI 2 ~ | CSI 2 z | ESC Q | CSI L Delete | CSI 3 ~ | CSI 3 z | ESC P | - Keypad Insert | CSI 2 ~ | CSI 2 z | ESC Q | CSI L Keypad Delete | CSI 3 ~ | CSI 3 z | ESC P | - Remove | CSI 3 ~ | CSI 3 z | ESC P | - Select | CSI 4 ~ | CSI 4 z | ESC F | - Prior | CSI 5 ~ | CSI 2 1 6 z | ESC T | CSI I Next | CSI 6 ~ | CSI 2 2 2 z | ESC S | CSI G Help | CSI 2 8 ~ | CSI 1 9 6 z | - | - Menu | CSI 2 9 ~ | CSI 1 9 7 z | - | - Home | - | CSI 2 1 4 z | ESC h | CSI H End | - | CSI 2 2 0 z | ESC F | CSI F Begin | - | CSI 2 1 8 z | - | CSI E --------------+------------+--------------+----------+---------- The Alternate Screen Buffer XTerm maintains two screen buffers. The Normal Screen Buffer allows you to scroll back to view saved lines of output up to the maximum set by the saveLines resource. The Alternate Screen Buffer is exactly as large as the display, contains no additional saved lines. When the Alternate Screen Buffer is active, you cannot scroll back to view saved lines. XTerm provides control sequences and menu entries for switching between the two. Most full-screen applications use terminfo or termcap to obtain strings used to start/stop full-screen mode, i.e., smcup and rmcup for terminfo, or the corresponding ti and te for termcap. The titeInhibit resource removes the ti and te strings from the TERMCAP string which is set in the environment for some platforms. That is not done when xterm is built with terminfo libraries because terminfo does not provide the whole text of the termcap data in one piece. It would not work for terminfo anyway, since terminfo data is not passed in environment variables; setting an environment variable in this manner would have no effect on the application's ability to switch between Normal and Alternate Screen buffers. Instead, the newer private mode controls (such as 1 0 4 9 ) for switching between Normal and Alternate Screen buffers simply disable the switching. They add other features such as clearing the display for the same reason: to make the details of switching independent of the application that requests the switch. Bracketed Paste Mode When bracketed paste mode is set, pasted text is bracketed with control sequences so that the program can differentiate pasted text from typed- in text. When bracketed paste mode is set, the program will receive: ESC [ 2 0 0 ~ , followed by the pasted text, followed by ESC [ 2 0 1 ~ . For background and discussion, see the FAQ: XTerm - bracketed-paste Readline Modes Several modes provide support for mouse button events in readline. Bracketed paste is one of these readline modes, but is used more widely. Some assumptions (particular mouse buttons) and limitations (the mouse is clicked on the current row on the screen) apply: 2 0 0 1 If mouse button 1 is used to end or extend a selection (the select-end action), and if the cursor position is on the same row as the mouse-click, send left/right cursor control sequences to the host to adjust the cursor position to match the mouse click. 2 0 0 2 When pasting text (the insert-selection action which is normally bound to mouse button 2), if mouse protocol is not enabled, and if the cursor position is on the same row as the mouse-click, send left/right cursor control sequences to the host to adjust the cursor position to match the mouse click. 2 0 0 3 If mouse button 3 is double-clicked when ending or extending a selection, (the select-end action), and if the cursor position is on the same line as the mouse-click: o Send left/right cursor control sequences to the host to adjust the cursor position to match the mouse click. o In addition to the same row, the selection may be part of a wrapped line as in other xterm selections (see the Selection Functions section in the manual page). o After adjusting the cursor position, xterm sends erase- characters (one for each character in the selection) to tell the host to delete the selected text. 2 0 0 5 When writing a selection to the host (i.e., pasting text), escape each character with the literal-next (Ctrl-V) character. 2 0 0 6 Normally when xterm writes selections to the host, it translates newlines to carriage returns. This mode disables the translation, passing newlines literally. Title Modes The window- and icon-labels can be set or queried using control sequences. As a VT220-emulator, xterm "should" limit the character encoding for the corresponding strings to ISO-8859-1. Indeed, it used to be the case (and was documented) that window titles had to be ISO-8859-1. This is no longer the case. However, there are many applications which still assume that titles are set using ISO-8859-1. So that is the default behavior. If xterm is running with UTF-8 encoding, it is possible to use window- and icon-labels encoded using UTF-8. That is because the underlying X libraries (and many, but not all) window managers support this feature. The utf8Title X resource setting tells xterm to disable a reconversion of the title string back to ISO-8859-1, allowing the title strings to be interpreted as UTF-8. The same feature can be enabled using the title mode control sequence described in this summary. Separate from the ability to set the titles, xterm provides the ability to query the titles, returning them either in ISO-8859-1 or UTF-8. This choice is available only while xterm is using UTF-8 encoding. Finally, the characters sent to, or returned by a title control are less constrained than the rest of the control sequences. To make them more manageable (and constrained), for use in shell scripts, xterm has an optional feature which decodes the string from hexadecimal (for setting titles) or for encoding the title into hexadecimal when querying the value. Mouse Tracking The VT widget can be set to send the mouse position and other information on button presses. These modes are typically used by editors and other full-screen applications that want to make use of the mouse. There are two sets of mutually exclusive modes: o mouse protocol o protocol encoding The mouse protocols include DEC Locator mode, enabled by the DECELR CSI Ps ; Ps ' z control sequence, and is not described here (control sequences are summarized above). The remaining five modes of the mouse protocols are each enabled (or disabled) by a different parameter in the "DECSET CSI ? Pm h " or "DECRST CSI ? Pm l " control sequence. Manifest constants for the parameter values are defined in xcharmouse.h as follows: #define SET_X10_MOUSE 9 #define SET_VT200_MOUSE 1000 #define SET_VT200_HIGHLIGHT_MOUSE 1001 #define SET_BTN_EVENT_MOUSE 1002 #define SET_ANY_EVENT_MOUSE 1003 #define SET_FOCUS_EVENT_MOUSE 1004 #define SET_ALTERNATE_SCROLL 1007 #define SET_EXT_MODE_MOUSE 1005 #define SET_SGR_EXT_MODE_MOUSE 1006 #define SET_URXVT_EXT_MODE_MOUSE 1015 #define SET_PIXEL_POSITION_MOUSE 1016 The motion reporting modes are strictly xterm extensions, and are not part of any standard, though they are analogous to the DEC VT200 DECELR locator reports. Normally, parameters (such as pointer position and button number) for all mouse tracking escape sequences generated by xterm encode numeric parameters in a single character as value+32. For example, ! specifies the value 1. The upper left character position on the terminal is denoted as 1,1. This scheme dates back to X10, though the normal mouse- tracking (from X11) is more elaborate. X10 compatibility mode X10 compatibility mode sends an escape sequence only on button press, encoding the location and the mouse button pressed. It is enabled by specifying parameter 9 to DECSET. On button press, xterm sends CSI M CbCxCy (6 characters). o Cb is button-1, where button is 1, 2 or 3. o Cx and Cy are the x and y coordinates of the mouse when the button was pressed. Normal tracking mode Normal tracking mode sends an escape sequence on both button press and release. Modifier key (shift, ctrl, meta) information is also sent. It is enabled by specifying parameter 1000 to DECSET. On button press or release, xterm sends CSI M CbCxCy. o The low two bits of Cb encode button information: 0=MB1 pressed, 1=MB2 pressed, 2=MB3 pressed, and 3=release. o The next three bits encode the modifiers which were down when the button was pressed and are added together: 4=Shift, 8=Meta, and 16=Control. The shift and control modifiers are normally irrelevant because xterm uses the control modifier with mouse for popup menus, and the shift modifier is used in the default translations for button events. There is no predefined meta modifier. XTerm checks first if the keysyms listed in the predefined modifiers include Meta_L or Meta_R. If found, xterm uses that modifier for meta. Next, it tries Alt_L or Alt_R. If none of those are found, xterm uses the mod1 modifier, This is not necessarily the "Meta" key according to xmodmap(1). o Cx and Cy are the x and y coordinates of the mouse event, encoded as in X10 mode. Wheel mice Wheel mice may return buttons 4 and 5. Those buttons are represented by the same event codes as buttons 1 and 2 respectively, except that 64 is added to the event code. Release events for the wheel buttons are not reported. By default, the wheel mouse events (buttons 4 and 5) are translated to scroll-back and scroll-forw actions, respectively. Those actions normally scroll the whole window, as if the scrollbar was used. However if Alternate Scroll mode is set, then cursor up/down controls are sent when the terminal is displaying the Alternate Screen Buffer. The initial state of Alternate Scroll mode is set using the alternateScroll resource. Other buttons Some wheel mice can send additional button events, e.g., by tilting the scroll wheel left and right. Additional buttons are encoded like the wheel mice, o by adding 64 (for buttons 6 and 7), or o by adding 128 (for buttons 8 through 11). Past button 11, the encoding is ambiguous because the same code may correspond to different button/modifier combinations. It is not possible to use these buttons (6-11) in xterm's translations resource because their names are not in the X Toolkit's symbol table. However, applications can check for the reports, e.g., button 7 (left) and button 6 (right) with a Logitech mouse. Highlight tracking Mouse highlight tracking notifies a program of a button press, receives a range of lines from the program, highlights the region covered by the mouse within that range until button release, and then sends the program the release coordinates. It is enabled by specifying parameter 1001 to DECSET. Highlighting is performed only for button 1, though other button events can be received. Warning: this mode requires a cooperating program, else xterm will hang. On button press, the same information as for normal tracking is generated; xterm then waits for the program to send mouse tracking information. All X events are ignored until the proper escape sequence is received from the pty: CSI Ps ; Ps ; Ps ; Ps ; Ps T The parameters are func, startx, starty, firstrow, and lastrow: o func is non-zero to initiate highlight tracking and zero to abort. o startx and starty give the starting x and y location for the highlighted region. o The ending location tracks the mouse, but will never be above row firstrow and will always be above row lastrow. (The top of the screen is row 1.) When the button is released, xterm reports the ending position one of two ways: o if the start and end coordinates are the same locations: CSI t CxCy o otherwise: CSI T CxCyCxCyCxCy The parameters are startx, starty, endx, endy, mousex, and mousey: o startx, starty, endx, and endy give the starting and ending character positions of the region. o mousex and mousey give the location of the mouse at button up, which may not be over a character. Button-event tracking Button-event tracking is essentially the same as normal tracking, but xterm also reports button-motion events. Motion events are reported only if the mouse pointer has moved to a different character cell. It is enabled by specifying parameter 1002 to DECSET. On button press or release, xterm sends the same codes used by normal tracking mode. o On button-motion events, xterm adds 32 to the event code (the third character, Cb). o The other bits of the event code specify button and modifier keys as in normal mode. For example, motion into cell x,y with button 1 down is reported as CSI M @ CxCy ( @ = 32 + 0 (button 1) + 32 (motion indicator) ). Similarly, motion with button 3 down is reported as CSI M B CxCy ( B = 32 + 2 (button 3) + 32 (motion indicator) ). Any-event tracking Any-event mode is the same as button-event mode, except that all motion events are reported, even if no mouse button is down. It is enabled by specifying 1003 to DECSET. FocusIn/FocusOut FocusIn/FocusOut can be combined with any of the mouse events since it uses a different protocol. When set, it causes xterm to send CSI I when the terminal gains focus, and CSI O when it loses focus. Extended coordinates The original X10 mouse protocol limits the Cx and Cy ordinates to 223 (=255 - 32). XTerm supports more than one scheme for extending this range, by changing the protocol encoding: UTF-8 (1005) This enables UTF-8 encoding for Cx and Cy under all tracking modes, expanding the maximum encodable position from 223 to 2015. For positions less than 95, the resulting output is identical under both modes. Under extended mouse mode, positions greater than 95 generate "extra" bytes which will confuse applications which do not treat their input as a UTF-8 stream. Likewise, Cb will be UTF-8 encoded, to reduce confusion with wheel mouse events. Under normal mouse mode, positions outside (160,94) result in byte pairs which can be interpreted as a single UTF-8 character; applications which do treat their input as UTF-8 will almost certainly be confused unless extended mouse mode is active. This scheme has the drawback that the encoded coordinates will not pass through luit(1) unchanged, e.g., for locales using non-UTF-8 encoding. SGR (1006) The normal mouse response is altered to use o CSI < followed by semicolon-separated o encoded button value, o Px and Py ordinates and o a final character which is M for button press and m for button release. The encoded button value in this case does not add 32 since that was useful only in the X10 scheme for ensuring that the byte containing the button value is a printable code. o The modifiers are encoded in the same way. o A different final character is used for button release to resolve the X10 ambiguity regarding which button was released. The highlight tracking responses are also modified to an SGR- like format, using the same SGR-style scheme and button- encodings. URXVT (1015) The normal mouse response is altered to use o CSI followed by semicolon-separated o encoded button value, o the Px and Py ordinates and final character M . This uses the same button encoding as X10, but printing it as a decimal integer rather than as a single byte. However, CSI M can be mistaken for DL (delete lines), while the highlight tracking CSI T can be mistaken for SD (scroll down), and the Window manipulation controls. For these reasons, the 1015 control is not recommended; it is not an improvement over 1006. SGR-Pixels (1016) Use the same mouse response format as the 1006 control, but report position in pixels rather than character cells. Graphics Sixel Graphics If xterm is configured as VT240, VT241, VT330, VT340 or VT382 using the decTerminalID or decGraphicsID resource, it supports Sixel Graphics controls, a paletted bitmap graphics system using sets of six vertical pixels as the basic element. CSI Ps c Send Device Attributes (Primary DA), DEC graphics terminals, xterm. xterm responds to Send Device Attributes (Primary DA) with these additional codes: Ps = 4 -> Sixel graphics. CSI ? Pm h Set Mode (with corresponding Reset Mode CSI ? Pm l ): Ps = 8 0 -> Sixel Display Mode (DECSDM), VT330, VT340, VT382. Ps = 1 0 7 0 -> use private color registers for each graphic, xterm. Ps = 8 4 5 2 -> Sixel scrolling leaves cursor to right of graphic, RLogin, xterm. DCS Pa ; Pb ; Ph q Ps..Ps ST Send SIXEL image, DEC graphics terminals, VT330, VT340, VT382. See: VT330/VT340 Programmer Reference Manual Volume 2: Graphics Programming Chapter 14 Graphics Programming The sixel data device control string has three positional parameters, following the q with sixel data. Pa -> pixel aspect ratio Pb -> background color option Ph -> horizontal grid size (ignored). Ps -> sixel data ReGIS Graphics If xterm is configured as VT125, VT240, VT241, VT330 or VT340 using the decTerminalID or decGraphicsID resource, it supports Remote Graphic Instruction Set, a graphics description language. CSI Ps c Send Device Attributes (Primary DA), DEC graphics terminals, xterm. xterm responds to Send Device Attributes (Primary DA) with these additional codes: Ps = 3 -> ReGIS graphics. CSI ? Pm h Set Mode, xterm. xterm has these additional private Set Mode values: Ps = 1 0 7 0 -> use private color registers for each graphic. DCS Pm p Pr..Pr ST Enter or exit ReGIS, VT300, xterm. See: VT330/VT340 Programmer Reference Manual Volume 2: Graphics Programming Chapter 1 Introduction to ReGIS The ReGIS data device control string has one positional parameter with four possible values: Pm = 0 -> resume command, use fullscreen mode. Pm = 1 -> start new command, use fullscreen mode. Pm = 2 -> resume command, use command display mode. Pm = 3 -> start new command, use command display mode. A few of the VT330/VT340 private modes conflict with xterm. Codes 4 0 to 4 7 were first used by xterm in X10R4 (December 1986). While X11R1 xterm dropped codes 4 1 and 4 2 , the remaining ones are still used. The VT330/VT340 introduced in April 1987 uses 4 4 to 4 7 for color graphics printing controls. When configured for ReGIS, xterm uses the VT330/VT340 interpretation of these private modes. Non-VT100 Modes Tektronix 4014 Mode Most of these sequences are standard Tektronix 4014 control sequences. Graph mode supports the 12-bit addressing of the Tektronix 4014. The major features missing are the write-through and defocused modes. This document does not describe the commands used in the various Tektronix plotting modes but does describe the commands to switch modes. Some of the sequences are specific to xterm. The Tektronix emulation was added in X10R4 (1986). The VT240, introduced two years earlier, also supported Tektronix 4010/4014. Unlike xterm, the VT240 documentation implies (there is an obvious error in section 6.9 "Entering and Exiting 4010/4014 Mode") that exiting back to ANSI mode is done by resetting private mode 3 8 (DECTEK) rather than ESC ETX . A real Tektronix 4014 would not respond to either. BEL Bell (Ctrl-G). BS Backspace (Ctrl-H). TAB Horizontal Tab (Ctrl-I). LF Line Feed or New Line (Ctrl-J). VT Cursor up (Ctrl-K). FF Form Feed or New Page (Ctrl-L). CR Carriage Return (Ctrl-M). ESC ETX Switch to VT100 Mode (ESC Ctrl-C). ESC ENQ Return Terminal Status (ESC Ctrl-E). ESC FF PAGE (Clear Screen) (ESC Ctrl-L). ESC SO Begin 4015 APL mode (ESC Ctrl-N). This is ignored by xterm. ESC SI End 4015 APL mode (ESC Ctrl-O). This is ignored by xterm. ESC ETB COPY (Save Tektronix Codes to file COPYyyyy-mm-dd.hh:mm:ss). ETB (end transmission block) is the same as Ctrl-W. ESC CAN Bypass Condition (ESC Ctrl-X). ESC SUB GIN mode (ESC Ctrl-Z). ESC FS Special Point Plot Mode (ESC Ctrl-\). ESC 8 Select Large Character Set. ESC 9 Select #2 Character Set. ESC : Select #3 Character Set. ESC ; Select Small Character Set. OSC Ps ; Pt BEL Set Text Parameters of VT window. Ps = 0 -> Change Icon Name and Window Title to Pt. Ps = 1 -> Change Icon Name to Pt. Ps = 2 -> Change Window Title to Pt. Ps = 4 6 -> Change Log File to Pt. This is normally disabled by a compile-time option. ESC ` Normal Z Axis and Normal (solid) Vectors. ESC a Normal Z Axis and Dotted Line Vectors. ESC b Normal Z Axis and Dot-Dashed Vectors. ESC c Normal Z Axis and Short-Dashed Vectors. ESC d Normal Z Axis and Long-Dashed Vectors. ESC h Defocused Z Axis and Normal (solid) Vectors. ESC i Defocused Z Axis and Dotted Line Vectors. ESC j Defocused Z Axis and Dot-Dashed Vectors. ESC k Defocused Z Axis and Short-Dashed Vectors. ESC l Defocused Z Axis and Long-Dashed Vectors. ESC p Write-Thru Mode and Normal (solid) Vectors. ESC q Write-Thru Mode and Dotted Line Vectors. ESC r Write-Thru Mode and Dot-Dashed Vectors. ESC s Write-Thru Mode and Short-Dashed Vectors. ESC t Write-Thru Mode and Long-Dashed Vectors. FS Point Plot Mode (Ctrl-\). GS Graph Mode (Ctrl-]). RS Incremental Plot Mode (Ctrl-^ ). US Alpha Mode (Ctrl-_). VT52 Mode Parameters for cursor movement are at the end of the ESC Y escape sequence. Each ordinate is encoded in a single character as value+32. For example, ! is 1. The screen coordinate system is 0-based. ESC < Exit VT52 mode (Enter VT100 mode). ESC = Enter alternate keypad mode. ESC > Exit alternate keypad mode. ESC A Cursor up. ESC B Cursor down. ESC C Cursor right. ESC D Cursor left. ESC F Enter graphics mode. ESC G Exit graphics mode. ESC H Move the cursor to the home position. ESC I Reverse line feed. ESC J Erase from the cursor to the end of the screen. ESC K Erase from the cursor to the end of the line. ESC Y Ps Ps Move the cursor to given row and column. ESC Z Identify. -> ESC / Z ("I am a VT52 emulated by VT100."). or -> ESC / K ("I am a VT52."). depending on whether xterm is started as a VT52 by setting the decTerminalID resource to "52" or not. Further reading Technical manuals Manuals for hardware terminals are more readily available than similarly-detailed documentation for terminal emulators such as aixterm, shelltool, dtterm. However long, the technical manuals have problems: o DEC's manuals did not provide a comprehensive comparison of the features in different model. Host Interface Functions Checklist by Peter Sichel (January 12, 1994) is helpful. This spreadsheet is useful for noting which model introduced a given feature (although there are a few apparent errors such as the DECRQSS feature cited for VT320 whereas the technical manual omits it). o Sometimes the manuals disagree. For example, DEC's standard document (DEC STD 070) for terminals says that DECSCL performs a soft reset (DECSTR), while the VT420 manual says it does a hard reset (RIS). o Sometimes the manuals are simply incorrect. For example, testing a DEC VT420 in 1996 showed that the documented code for a valid or invalid response to DECRQSS was reversed. The VT420 test results were incorporated into the vttest program. At the time, DEC STD 070 was not available, but it also agrees with vttest. Later, documentation for the DEC VT525 was shown to have the same flaw. o The VT330/VT340 reference manual for graphics programming documents sixel graphics in some detail in chapter 14. Overlooked in the first edition, the second edition mentions Sixel Scrolling. The VT382 Kanji and Thai manuals provide less information, about sixel graphics, but do mention DECSDM. They differ in their comment about the private mode DECSDM (CSI ? 8 0 h ), which each manual agrees should set the Sixel Scrolling feature. The VT330/VT340 graphics programming manual (second edition, March 1988) says When sixel display mode is set, the Sixel Scrolling feature is enabled. When sixel display mode is reset, the Sixel Scrolling feature is disabled. while the VT382 Kanji manual (page 6-6, undated) says Disable sixel scroll and the VT382 Thai manual (page C-30, August 1989) says No Sixel scrolling The standard (DEC STD 070) in chapter 9 (August 3, 1990) states on page 17 that video devices will scroll when advancing the Sixel active position past the bottom margin, but on page 19, in the section on deviations, states that VT125 and VT240 did not scroll in this situation. The standard does not mention VT330/VT340 or VT382. Nor does it document DECSDM. o Not all details are clear even in DEC STD 070 (which is more than twice the length of the VT520 programmer's reference manual, and almost three times longer than the VT420 reference manual). However, as an internal standards document, DEC STD 070 is more likely to describe the actual behavior of DEC's terminals than the more polished user's guides. That said, here are technical manuals which have been used in developing xterm. Not all were available initially. In August 1996 for instance, the technical references were limited to EK-VT220-HR-002 and EK- VT420-UG.002. Shortly after, Richard Shuford sent a copy of EK-VT3XX- TP-001. Still later (beginning in 2003), Paul Williams' vt100.net site provided EK-VT102-UG-003, EK-VT220-RM-002, EK-VT420-RM-002, EK-VT520-RM A01, EK-VT100-TM-003, and EK-VT102-UG-003. In addition, several documents were found on the bitsavers site. o DECscope User's Manual. Digital Equipment Corporation (EK-VT5X-OP-001 1975). o VT100 Series Video Terminal Technical Manual. Digital Equipment Corporation (EK-VT100-TM-003, July 1982). o VT100 User Guide. Digital Equipment Corporation (EK-VT100-UG-003, June 1981). o VT102 User Guide. Digital Equipment Corporation (EK-VT102-UG-003, February 1982). o VT220 Programmer Pocket Guide. Digital Equipment Corporation (EK-VT220-HR-002, July 1984). o VT220 Programmer Reference Manual. Digital Equipment Corporation (EK-VT220-RM-002, August 1984). o VT240 Programmer Reference Manual. Digital Equipment Corporation (EK-VT240-RM-002, October 1984). o VT330/VT340 Programmer Reference Manual Volume 1: Text Programming. Digital Equipment Corporation (EK-VT3XX-TP-001, March 1987). o VT330/VT340 Programmer Reference Manual Volume 2: Graphics Programming. Digital Equipment Corporation (EK-VT3XX-GP-001, March 1987). o VT330/VT340 Programmer Reference Manual Volume 2: Graphics Programming. Digital Equipment Corporation (EK-VT3XX-GP-002, May 1988). o VT382 Kanji Display Terminal Programmer Reference Manual. Digital Equipment Corporation (EK-VT382-RM-001, undated). o VT382 Thai Display Terminal Installing and Using Manual. Digital Equipment Corporation (EK-VT38T-UG-001, August 1989). o Installing and Using The VT420 Video Terminal (North American Model). Digital Equipment Corporation (EK-VT420-UG.002, February 1990). o VT420 Programmer Reference Manual. Digital Equipment Corporation (EK-VT420-RM-002, February 1992). o VT510 Video Terminal Programmer Information. Digital Equipment Corporation (EK-VT510-RM B01, November 1993). o VT520/VT525 Video Terminal Programmer Information. Digital Equipment Corporation (EK-VT520-RM A01, July 1994). o Digital ANSI-Compliant Printing Protocol Level 2 Programming Reference Manual Digital Equipment Corporation (EK-PPLV2-PM B01, August 1994). o Disk Operating System DOS 2.00 Microsoft, Inc. First edition, January 1983. o 4014 and 4014-1 Computer Display Terminal User's Manual. Tektronix, Inc. (070-1647-00, November 1979). Standards The DEC terminal family (VT100 through VT525) is upward-compatible, using standards plus extensions, e.g., "private modes". Not all commonly-used features are standard. For example, scrolling regions are not found in ECMA-48. On the other hand, ECMA-48 was not intended to be all-encompassing. Quoting from the second edition: Full conformance to a standard means that all its requirements are met. For such conformance to be unique the standard must contain no options. This is typically the case for hardware standards, for instance Standard ECMA-10 for data interchange on punched tapes. This Standard ECMA-48 is of a different nature and as a result, it is only practicable to envisage limited conformance to it, as defined hereunder. This Standard addresses a whole class of devices which can vary greatly from each other depending on the application for which a device has been specifically designed. Obviously, a product which implements all facilities described in this standard - thus being in "full conformance" with it - whilst theoretically possible, would be technically and economically unthinkable. Again, it is possible to find discrepancies in the standards: o The printed ECMA-48 5th edition (1991) and the first PDF produced for that edition (April 1998) state that SD (scroll down) ends with 05/14, i.e., ^ , which disagrees with DEC's VT420 hardware implementation and DEC's manuals which use 05/04 T . (A few other terminals such as AT&T 5620 and IBM 5151 also used 05/04, but the documentation and dates are lacking). ECMA created a new PDF in April 2003 which changed that detail to use T , and later in 2008 provided PDFs of the earlier editions which used T . o The first edition of ECMA-48 has not been available, to compare. As of September 2021, ECMA's website provides a copy of ECMA-46 in its place. Earlier versions of ISO 6429 have never been available. The first three editions of ISO 6429 were issued in 1983, 1988, and 1992. o ANSI X3.64-1979 does not list color as a feature of the SGR sequence (page 49). In Appendix A, it mentions ECMA-48: (8) This document represents a coordinated effort to develop a single technical standard in the United States and Europe (see ECMA-48 standard entitled Additional Controls for Character Imaging Input/Output Devices). Appendix H clarifies the relationship between these documents somewhat though it confuses the first two editions of ECMA-48. The typo for "work" versus "owkr" appears in the original document: ANSI X3.64-1979, and ECMA-48, Additional Controls for Character- Imaging I/O Devices, were developed in parallel, with close liaison. ISO DP 6429, Additional Control Functions for Character-Imaging Devices, was developed as a synthesis of X3.64 and ECMA-48. During this process, some control functions as well as additional selective parameters were added. Except for point 1 below, X3.64 is a subset of ISO 6429. Although the two standards use different language, the intent is that the subset is technically identical. X3.64 was balloted and forwarded prior to the final resolution of ISO 6429 and does not incorporate the owkr of IS0/TC97/SC2 in completing ISO 6429. Revision of X3.64 will attempt to incorporate those elements and assumptions of X3.64. ANSI X3.64 goes on to say that the SGR codes 8, 30-47 are in ISO 6429. It includes 38 and 39, but omits 48 and 49. At the time, ISO 6429's first edition was still four years in the future. The writer probably was referring to the ongoing process of making ECMA-48 second edition into the ISO standard. o The VT320, VT420, VT520 manuals claim that DECSCL does a hard reset (RIS). Both the VT220 manual and DEC STD 070 (which documents levels 1-4 in detail) state that it is a soft reset, e.g., DECSTR. Here are the relevant standards: o Additional Controls for Use with American National Standard Code for Information Interchange, ANSI X3.64-1979 FIPS Publication 86. July 18, 1979. American National Standards Institute, Inc. o ECMA-35: Character Code Structure and Extension Techniques (6th Edition, December 1994). o ECMA-43: 8-bit Coded Character Set Structure and Rules (3rd Edition, December 1991). o ECMA-48: Control Functions for Coded Character Sets (5th Edition, June 1991). o DEC STD 070 Video Systems Reference Manual. Digital Equipment Corporation (A-MN-ELSM070-00-0000 Rev H, December 3, 1991). Miscellaneous A few hardware terminals survived into the 1990s only as terminal emulators. Documentation for these and other terminal emulators which have influenced xterm are generally available only in less-accessible and less-detailed manual pages. o XTerm supports control sequences for manipulating its window which were implemented by Sun's shelltool program. This was part of SunView (SunOS 3.0, 1986). The change-notes for xterm's resize program in X10.4 (1986) mention its use of these "Sun tty emulation escape sequences" for resizing the window. The X10.4 xterm program recognized these sequences for resizing the terminal, except for the iconify/deiconify pair. SunView also introduced the SIGWINCH signal, used by the X10.4 xterm and mentioned in its CHANGES file: The window size is passed to the operating system via TIOCSWINSZ (4.3) or TIOCSSIZE (sun). A SIGWINCH signal is sent if the vtXXX window is resized. While support for the Sun control-sequences remained in resize, the next release of xterm (X11R1 in 1987) omitted the code for interpreting them. Later, the SunView program was adapted for the OPEN LOOK environment introduced 1988-1990. Still later, in 1995, OPEN LOOK was abandoned in favor of CDE. The CDE terminal emulator dtterm implemented those controls, with a couple of additions. Starting in July 1996, xterm re-implemented those control sequences (based on the dtterm manual pages) and further extended the group of window controls. There were two sets of controls (CSI Ps [ ; Pm ; Pm ] t , and OSC Ps text ST ) implemented by shelltool, documented in appendix E of both PHIGS Programming Manual (1992), and the unpublished X Window System User's Guide (OPEN LOOK Edition) (1995). The CDE program kept those, and added a few new ones. Code Sun CDE XTerm Description -----------+-----+-----+-------+--------------------------------- CSI 1 t | yes | yes | yes | de-iconify CSI 2 t | yes | yes | yes | iconify CSI 3 t | yes | yes | yes | move window to pixel-position CSI 4 t | yes | yes | yes | resize window in pixels CSI 5 t | yes | yes | yes | raise window to front of stack CSI 6 t | yes | yes | yes | raise window to back of stack CSI 7 t | yes | yes | yes | refresh window CSI 8 t | yes | yes | yes | resize window in chars CSI 9 t | - | - | yes | maximize/unmaximize window CSI 1 0 t | - | - | yes | to/from full-screen CSI 1 1 t | yes | yes | yes | report if window is iconified CSI 1 2 t | - | - | - | - CSI 1 3 t | yes | yes | yes | report window position CSI 1 4 t | yes | yes | yes | report window size in pixels CSI 1 5 t | - | - | yes | report screen size in pixels CSI 1 6 t | - | - | yes | report character cell in pixels CSI 1 7 t | - | - | - | - CSI 1 8 t | yes | yes | yes | report window size in chars CSI 1 9 t | - | - | yes | report screen size in chars CSI 2 0 t | - | yes | yes | report icon label CSI 2 1 t | - | yes | yes | report window title CSI 2 2 t | - | - | yes | save window/icon title CSI 2 3 t | - | - | yes | restore window/icon title CSI 2 4 t | - | - | yes | resize window (DECSLPP) OSC 0 ST | - | yes | yes | set window and icon title OSC 1 ST | - | yes | yes | set icon label OSC 2 ST | - | yes | yes | set window title OSC 3 ST | - | n/a | yes | set X server property OSC I ST | yes | yes | yes | set icon to file OSC l ST | yes | yes | yes | set window title OSC L ST | yes | yes | yes | set icon label -----------+-----+-----+-------+--------------------------------- Besides the Sun-derived OSC controls for setting window title and icon label, dtterm also supported the xterm controls for the same feature. The CDE source was unavailable for inspection until 2012, so that clarification of the details of the window operations relied upon vttest. However, the manual page for the control sequences (i.e., dtterm(5) in the file formats section) was readily available. DEC adapted the control sequences for setting the window and icon labels in the VT525. In doing so, DEC's VT520/VT525 manual changed the letter l to a number 1, and added a parameter 2 before the l/L (or 1/L) code used to distinguish the window and icon labels. o The SCOSC/SCORC control sequences for saving/restoring the cursor and for saving/restoring "DEC Private Mode Values" (XTSAVE and XTRESTORE) may appear to be related (since the "save" controls both end with s ), but that is coincidental. The latter was introduced in X10.4 (December 1986): Most Dec Private mode settings can be saved away internally using \E[?ns, where n is the same number to set or reset the Dec Private mode. The mode can be restored using \E[?nr. This can be used in termcap for vi(1), for example, to turn off saving of lines, but restore whatever the original state was on exit. while the SCOSC/SCORC pair was added in 1995 by XFree86 (and documented long afterwards). The SCO ANSI console terminal descriptions did not use these controls (they used the VT100-compatible SC/RC pair). SCOSC/SCORC were an artifact of DOS 2.00 (January 1983), by Microsoft and later supported by SCO and other vendors. The SCOSC/SCORC pair is considered a private mode because the final characters (s and u ) fall in the range from "`" to "~" (octal 0140 to octal 0176). Other private control sequences can be constructed by using octets 074 to 077 (characters "<", "=", ">", or "?") at the beginning of the parameter string. The XTSAVE and XTRESTORE controls use "?") in this manner. Because the XTSAVE and XTRESTORE controls are private, other terminals may behave differently. For example, DEC (a contributor to the early xterm as well as a manufacturer of terminals) used an incompatible private control in one of its terminals more than five years later (for the VT420 PCTerm, announced in February 1992). In that model of the VT420, CSI ? Pm ; Pc r selects the PC TERM emulation mode. When this mode is enabled, the keyboard sends scan codes rather than characters (analogous to X keyboard events). The first parameter of this private control enables or disables PC TERM mode, while the second selects a character set. An ambiguity arises if an application omits the second parameter. In that special case, it cannot be distinguished from XTRESTORE. DEC did not take this into account when designing the feature. If there were potential users, xterm could accommodate this by a resource setting. In retrospect (thirty years later), there have been no uses of PC TERM, while the XTRESTORE feature is still in use. o The aixterm manual page gives the format of the control sequence for foreground and background colors 8-15, but does not specify what those colors are. That is implied by the description's mention of HFT: The aixterm command provides a standard terminal type for programs that do not interact directly with Enhanced X-Windows. This command provides an emulation for a VT102 terminal or a high function terminal (HFT). The VT102 mode is activated by the -v flag. Unlike xterm, there are no resource names for the 16 colors, leaving the reader to assume that the mapping is hard-coded. The control sequences for colors 8-15 are not specified by ECMA-48, but rather (as done in other instances by xterm) chosen to not conflict with current or future standards. xterm-399/trace.h0000644000000000000000000002045514773616775012541 0ustar rootroot/* $XTermId: trace.h,v 1.98 2025/04/03 23:47:09 tom Exp $ */ /* * Copyright 1997-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ /* * Common/useful definitions for XTERM application */ #ifndef included_trace_h #define included_trace_h /* *INDENT-OFF* */ #include #if OPT_TRACE #include extern void Trace ( const char *, ... ) GCC_PRINTFLIKE(1,2); extern void TraceVA ( const char *fmt, va_list ap ); extern void TraceXError (Display *d, XErrorEvent *ev); #undef if_TRACE #define if_TRACE(stmt) stmt #undef TRACE #define TRACE(p) Trace p #undef TRACE_VA #define TRACE_VA(p) TraceVA p #define TRACE_X_ERR(d,e) TraceXError(d,e) extern void TraceClose (void); #undef TRACE_CLOSE #define TRACE_CLOSE TraceClose #if OPT_TRACE > 1 #define TRACE2(p) Trace p #endif #define TRACE_L "{{" #define TRACE_R "}}" extern const char * visibleChars(const Char * /* buf */, size_t /* len */); extern const char * visibleEventMode(EventMode); extern const char * visibleIChars(const IChar * /* buf */, size_t /* len */); extern const char * visibleUChar(unsigned); extern const char * visibleDblChrset(unsigned /* chrset */); extern const char * visibleEventType (int); extern const char * visibleFont(XFontStruct * /* fs */); extern const char * visibleMappingMode (int); extern const char * visibleNotifyDetail(int /* code */); extern const char * visibleNotifyMode (int /* code */); extern const char * visibleScsCode(DECNRCM_codes /* chrset */); extern const char * visibleSelectionTarget(Display * /* d */, Atom /* a */); extern const char * visibleTekparse (int); extern const char * visibleVTparse (int); extern const char * visibleXError (int /* code */); extern const char * TraceAtomName(Display * /* d */, Atom /* a */); extern void TraceArgv(const char * /* tag */, char ** /* argv */); #undef TRACE_ARGV #define TRACE_ARGV(tag,argv) TraceArgv(tag,argv) extern const char *trace_who; #undef TRACE_CHILD #define TRACE_CHILD int tracing_child = (trace_who = "child") != NULL; (void) tracing_child extern void TraceEvent(const char *, XEvent *, String *, const Cardinal *); #undef TRACE_EVENT #define TRACE_EVENT(t,e,s,n) TraceEvent(t, (XEvent *)e, s, n) #undef TRACE_FALLBACK #if OPT_RENDERFONT && OPT_WIDE_CHARS extern void TraceFallback(XtermWidget, const char *, unsigned, int, XftFont *); #define TRACE_FALLBACK(w,t,c,n,f) TraceFallback(w, t, c, n, f) #else #define TRACE_FALLBACK(w,t,c,n,f) /*nothing*/ #endif extern void TraceFocus(Widget, XEvent *); #undef TRACE_FOCUS #define TRACE_FOCUS(w,e) TraceFocus((Widget)w, (XEvent *)e) extern void TraceSizeHints(XSizeHints *); #undef TRACE_HINTS #define TRACE_HINTS(hints) TraceSizeHints(hints) extern void TraceIds(const char * /* fname */, int /* lnum */); #undef TRACE_IDS #define TRACE_IDS TraceIds(__FILE__, __LINE__) extern void TraceTime(const char * /* fname */, int /* lnum */); #undef TRACE_TIME #define TRACE_TIME TraceTime(__FILE__, __LINE__) extern void TraceOptions(OptionHelp * /* options */, XrmOptionDescRec * /* resources */, Cardinal /* count */); #undef TRACE_OPTS #define TRACE_OPTS(opts,ress,lens) TraceOptions(opts,ress,lens) extern void TraceTranslations(const char *, Widget); #undef TRACE_TRANS #define TRACE_TRANS(name,w) TraceTranslations(name,w) extern void TraceWindowAttributes(XWindowAttributes *); #undef TRACE_WIN_ATTRS #define TRACE_WIN_ATTRS(a) TraceWindowAttributes(a) extern void TraceWMSizeHints(XtermWidget); #undef TRACE_WM_HINTS #define TRACE_WM_HINTS(w) TraceWMSizeHints(w) extern void TraceXtermResources(void); #undef TRACE_XRES #define TRACE_XRES() TraceXtermResources() extern XtGeometryResult TraceResizeRequest(const char * /* fn */, int /* ln */, Widget /* w */, unsigned /* reqwide */, unsigned /* reqhigh */, Dimension * /* gotwide */, Dimension * /* gothigh */); #undef REQ_RESIZE #define REQ_RESIZE(w, reqwide, reqhigh, gotwide, gothigh) \ TraceResizeRequest(__FILE__, __LINE__, w, \ (reqwide), (reqhigh), \ (gotwide), (gothigh)) extern const char * ModifierName(unsigned /* modifier */); #define FMT_MODIFIER_NAMES "%s%s%s%s%s%s%s%s" #define ARG_MODIFIER_NAMES(state) \ ModifierName(state & ShiftMask), \ ModifierName(state & LockMask), \ ModifierName(state & ControlMask), \ ModifierName(state & Mod1Mask), \ ModifierName(state & Mod2Mask), \ ModifierName(state & Mod3Mask), \ ModifierName(state & Mod4Mask), \ ModifierName(state & Mod5Mask) #else #define REQ_RESIZE(w, reqwide, reqhigh, gotwide, gothigh) \ XtMakeResizeRequest((Widget) (w), \ (Dimension) (reqwide), (Dimension) (reqhigh), \ (gotwide), (gothigh)) #define if_TRACE(stmt) /*nothing*/ #define TRACE(p) /*nothing*/ #define TRACE_CLOSE() /*nothing*/ #define TRACE_ARGV(tag,argv) /*nothing*/ #define TRACE_CHILD /*nothing*/ #define TRACE_EVENT(t,e,s,n) /*nothing*/ #define TRACE_FALLBACK(w,t,c,n,f) /*nothing*/ #define TRACE_FOCUS(w,e) /*nothing*/ #define TRACE_HINTS(hints) /*nothing*/ #define TRACE_IDS /*nothing*/ #define TRACE_OPTS(opts,ress,lens) /*nothing*/ #define TRACE_TRANS(name,w) /*nothing*/ #define TRACE_WIN_ATTRS(w) /*nothing*/ #define TRACE_WM_HINTS(w) /*nothing*/ #define TRACE_X_ERR(d,e) /*nothing*/ #define TRACE_XRES() /*nothing*/ #endif #ifndef TRACE2 #define TRACE2(p) /*nothing*/ #endif extern void TraceScreen(XtermWidget /* xw */, int /* whichBuf */); /* * The whole wnew->screen struct is zeroed in VTInitialize. Use these macros * where applicable for copying the pieces from the request widget into the * new widget. We do not have to use them for wnew->misc, but the associated * traces are very useful for debugging. */ #if OPT_TRACE #define init_Bres(name) \ TRACE(("init " #name " = %s\n", \ BtoS(wnew->name = request->name))) #define init_Dres(name) \ TRACE(("init " #name " = %f\n", \ wnew->name = request->name)) #define init_Dres2(name,i) \ TRACE(("init " #name "[%d] = %f\n", i, \ wnew->name[i] = request->name[i])) #define init_Ires(name) \ TRACE(("init " #name " = %d\n", \ wnew->name = request->name)) #define init_Mres(name) \ TRACE(("init " #name " = %s\n", \ MtoS(wnew->name = request->name))) #define init_Sres(name) \ TRACE(("init " #name " = \"%s\"\n", \ (wnew->name = x_strtrim(request->name)) != NULL \ ? wnew->name : "")) #define init_Sres2(name,i) \ TRACE(("init " #name "[%d] = \"%s\"\n", i, \ (wnew->name(i) = x_strtrim(request->name(i))) != NULL \ ? wnew->name(i) : "")) #define init_Tres(offset) \ TRACE(("init screen.Tcolors[" #offset "] = %#lx\n", \ fill_Tres(wnew, request, offset))) #else #define init_Bres(name) wnew->name = request->name #define init_Dres(name) wnew->name = request->name #define init_Dres2(name,i) wnew->name[i] = request->name[i] #define init_Ires(name) wnew->name = request->name #define init_Mres(name) wnew->name = request->name #define init_Sres(name) wnew->name = x_strtrim(request->name) #define init_Sres2(name,i) wnew->name(i) = x_strtrim(request->name(i)) #define init_Tres(offset) fill_Tres(wnew, request, offset) #endif /* *INDENT-ON* */ #endif /* included_trace_h */ xterm-399/xterm_io.h0000644000000000000000000001715214676455510013257 0ustar rootroot/* $XTermId: xterm_io.h,v 1.71 2024/09/30 08:03:20 tom Exp $ */ /* * Copyright 2000-2023,2024 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #ifndef included_xterm_io_h #define included_xterm_io_h #include /* * System-specific definitions (keep these chunks one-per-system!). * * FIXME: some, such as those defining USE_TERMIOS should be moved to xterm.h * as they are integrated with the configure script. */ #if defined(__minix) #define USE_POSIX_TERMIOS 1 #undef HAVE_POSIX_OPENPT /* present, does not work */ #endif #ifdef CSRG_BASED #define USE_TERMIOS #endif #ifdef __CYGWIN__ #define ATT #define SVR4 #define SYSV #define USE_SYSV_TERMIO #endif #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__INTERIX) || defined(__APPLE__) || defined(__UNIXWARE__) || defined(__hpux) #ifndef USE_POSIX_TERMIOS #define USE_POSIX_TERMIOS #endif #endif #if defined(AIXV4) #define USE_POSIX_TERMIOS #ifndef SYSV #define SYSV #endif #endif #ifdef __linux__ #define USE_TERMIOS #define HAVE_POSIX_OPENPT 1 #define HAVE_PTSNAME 1 #define HAVE_GRANTPT_PTY_ISATTY 1 #endif #ifdef __SCO__ #define USE_TERMIOS #ifndef _SVID3 #define _SVID3 #endif #endif #ifdef Lynx #define USE_SYSV_TERMIO #endif #ifdef macII #undef SYSV /* pretend to be bsd (sgtty.h) */ #endif /* macII */ #ifdef __GNU__ #define USE_POSIX_TERMIOS #define HAVE_POSIX_OPENPT 1 #define HAVE_PTSNAME 1 #define HAVE_GRANTPT_PTY_ISATTY 1 #endif #if defined(__GLIBC__) && !(defined(__linux__) || defined(__GNU__)) #define USE_POSIX_TERMIOS /* GNU/KFreeBSD and GNU/KNetBSD */ #endif #ifdef __QNX__ #define USE_POSIX_TERMIOS #endif #if defined(__osf__) #define USE_POSIX_TERMIOS #undef SYSV #endif /* * Indirect system dependencies */ #if defined(SVR4) && !defined(__sgi) #define USE_TERMIOS #endif #ifdef SYSV #define USE_SYSV_TERMIO #endif #if defined(USE_POSIX_TERMIOS) && !defined(USE_TERMIOS) #define USE_TERMIOS #endif /* * Low-level ioctl, where it is needed or non-conflicting with termio/etc. */ #ifdef __QNX__ #include #else #include #endif /* * Terminal I/O includes (termio, termios, sgtty headers). */ #if defined(USE_POSIX_TERMIOS) && !defined(__hpux) #include #elif defined(USE_TERMIOS) #include /* this hacked termios support only works on SYSV */ #define USE_ANY_SYSV_TERMIO #define termio termios #ifndef __CYGWIN__ #undef TCGETA #define TCGETA TCGETS #undef TCSETA #define TCSETA TCSETS #undef TCSETAW #define TCSETAW TCSETSW #endif #elif defined(USE_SYSV_TERMIO) # define USE_ANY_SYSV_TERMIO # ifdef Lynx # include # else # include # endif #elif defined(SYSV) || defined(ISC) # include #endif /* USE_POSIX_TERMIOS */ /* * Stream includes, which declare struct winsize or ttysize. */ #ifdef SYSV #ifdef USE_USG_PTYS #include /* get typedef used in ptem.h */ #ifdef HAVE_SYS_PTEM_H #include /* get struct winsize */ #endif #endif /* USE_USG_PTYS */ #endif /* SYSV */ /* * Special cases (structures and definitions that have to be adjusted). */ #if defined(__CYGWIN__) && !defined(TIOCSPGRP) #include #define TIOCSPGRP (_IOW('t', 118, pid_t)) #endif #ifdef __hpux #include /* defines TIOCSLTC */ #endif #ifdef ISC #define TIOCGPGRP TCGETPGRP #define TIOCSPGRP TCSETPGRP #endif #ifdef Lynx #include #elif !(defined(SYSV) || defined(__linux__) || (defined(__QNX__)&&!defined(__QNXNTO__))) #include #endif #ifdef macII #undef FIOCLEX #undef FIONCLEX #endif /* macII */ #if defined(__QNX__) || defined(__GNU__) || defined(__osf__) #undef TIOCSLTC /* conflicts with */ #undef TIOCSLTC #endif #if defined (__sgi) || (defined(__linux__) && defined(__sparc__)) || defined(__UNIXWARE__) #undef TIOCLSET /* defined, but not usable */ #endif #if defined(sun) || defined(__UNIXWARE__) #include #endif #if defined(TIOCSLTC) && ! (defined(__linux__) || defined(Lynx) || defined(SVR4)) #define HAS_LTCHARS #endif #if !defined(TTYSIZE_STRUCT) #if defined(TIOCSWINSZ) #define USE_STRUCT_WINSIZE 1 #define TTYSIZE_STRUCT struct winsize #define GET_TTYSIZE(fd, data) ioctl(fd, TIOCGWINSZ, (char *) &data) #define SET_TTYSIZE(fd, data) ioctl(fd, TIOCSWINSZ, (char *) &data) #define TTYSIZE_COLS(data) data.ws_col #define TTYSIZE_ROWS(data) data.ws_row #endif /* TIOCSWINSZ */ #endif /* TTYSIZE_STRUCT */ #ifndef USE_STRUCT_WINSIZE #error "There is a configuration error with struct winsize ifdef" #endif /* "resize" depends upon order of assignments in this macro */ #ifdef USE_STRUCT_WINSIZE #define setup_winsize(ts, rows, cols, height, width) \ (ts).ws_xpixel = (ttySize_t) (width), \ (ts).ws_ypixel = (ttySize_t) (height), \ TTYSIZE_ROWS(ts) = (ttySize_t) (rows), \ TTYSIZE_COLS(ts) = (ttySize_t) (cols) #else #define setup_winsize(ts, rows, cols, height, width) \ TTYSIZE_ROWS(ts) = (ttySize_t) (rows), \ TTYSIZE_COLS(ts) = (ttySize_t) (cols) #endif #if OPT_TRACE #ifdef USE_STRUCT_WINSIZE #define trace_winsize(ts, id) \ TRACE(("%s@%d, TTYSIZE %s chars %dx%d pixels %dx%d\n", \ __FILE__, __LINE__, id, \ TTYSIZE_ROWS(ts), TTYSIZE_COLS(ts), (ts).ws_ypixel, (ts).ws_xpixel)) #else #define trace_winsize(ts, id) \ TRACE(("%s@%d, TTYSIZE %s chars %dx%d\n", __FILE__, __LINE__, id, \ TTYSIZE_ROWS(ts), TTYSIZE_COLS(ts))) #endif #define TRACE_GET_TTYSIZE(fd, id) { \ TTYSIZE_STRUCT debug_ttysize; \ if (GET_TTYSIZE(fd, debug_ttysize) == 0) \ trace_winsize(debug_ttysize, id); \ else \ TRACE(("%s@%d, TTYSIZE failed %s\n", __FILE__, __LINE__, strerror(errno))); \ } #else #define trace_winsize(ts, id) /* nothing */ #define TRACE_GET_TTYSIZE(fd, id) /* nothing */ #endif typedef unsigned short ttySize_t; #ifdef USE_ANY_SYSV_TERMIO #define TERMIO_STRUCT struct termio #define ttySetAttr(fd, datap) ioctl(fd, TCSETA, datap) #define ttyGetAttr(fd, datap) ioctl(fd, TCGETA, datap) #define ttyFlush(fd) ioctl(fd, TCFLSH, 1) #elif defined(USE_POSIX_TERMIOS) #define TERMIO_STRUCT struct termios #define ttySetAttr(fd, datap) tcsetattr(fd, TCSANOW, datap) #define ttyGetAttr(fd, datap) tcgetattr(fd, datap) #define ttyFlush(fd) tcflush(fd, TCOFLUSH) #else #error Neither termio or termios is enabled #endif /* USE_ANY_SYSV_TERMIO */ #endif /* included_xterm_io_h */ xterm-399/terminfo0000644000000000000000000016344515011573117013021 0ustar rootroot# $XTermId: terminfo,v 1.210 2025/05/16 08:24:47 tom Exp $ # # Updates/notes/new entries (e.g., xterm-8bit, xterm-16color, xterm-256color) # - Thomas E. Dickey # #------------------------------------------------------------------------------ # Copyright 1996-2024,2025 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. #------------------------------------------------------------------------------ # format (ncurses 6.1): tic -I -W -1 -f -x terminfo #------------------------------------------------------------------------------ # # Special Capabilities: # -------------------- # ich has a corresponding capability that inserts a single blank. We could # have used ich1=\E[@, which works with ncurses, but that is not standard # behavior. If it is set, then SVr4 vi (e.g., Solaris 2.6) emits both # smir/rmir and ich1. # meml locks memory above the cursor; memu unlocks (ala HP terminals). This # is not recognized by some older (e.g., SVr3) tic programs, but none # do more than warn about it. Ignore the warning. # smcup clears memory before switching to the alternate screen. The older # (deprecated) \E[?47h did not do this, requiring applications to # embed a \E[2J in the rmcup string. However, that behavior cannot # be disabled via titeInhibit, making that resource not function as # intended on systems with terminfo. # rs2/is2 are shorter with XFree86 xterm because it supports DECSTR. We # use the shorter sequence for compatibility with the termcap, which # is trimmed to keep it shorter than 1023 characters. It (escape \E[!p) # replaces these in the conventional vt100 reset-string: # \E7 - save cursor (fixes origin-mode side-effect) # \E[r - reset scrolling margins # \E[m - reset SGR (including color) # \E[?7h - reset wraparound mode (DECAWM) # \E[?1l - reset application cursor keys (DECCKM) # \E[?6l - reset origin mode (DECOM) # \E8 - restore cursor # DECSTR is recognized by XFree86 xterm even in vt52 mode. # # Editing Keypad: # -------------- # XFree86 xterm emulates vt220 if the decTerminalID resource is set to 200 or # higher. Otherwise it emulates a vt100 or vt52 depending on the value of the # resource. When emulating a vt220, we support the editing keypad. Sun and PC # keyboards have an editing keypad which is similar to the vt220: # # VT220 editing keypad # ---------------------------- # Find Insert Remove # Select Prev Next # ---------------------------- # # Sun/PC editing keypad # ---------------------------- # Insert Home PageUp # Delete End PageDn # ---------------------------- # # If the sunKeyboard resource is true, we map it this way (adjusting the values # of Home, End and Delete): # VT220 Sun/PC # ---------------------------- # Find Home # Select End # Insert Insert # Remove Delete # Prev PageUp # Next PageDn # ---------------------------- # # Note that all of the keys on the editing keypad transmit escape sequences. A # vt220 does this only when in vt220 mode; when emulating a vt100 the editing # keypad is inactive. # # Alternative keycodes: # -------------------- # Several of the function keys have alternative names, depending on the type of # host which your xterm is connected to. DEC (i.e., the VMS system) uses F15 # as the HELP key, F16 as the DO key. Unix applications generally do not do # this. Curses applications in particular, assign a unique keycode to each # capability string. These terminal descriptions do not have conflicting # definitions, to ensure that Unix curses applications use a consistent set of # keycodes. To get a VMS-bias, make these substitutions: # 1. change khome to kfnd # 2. change kend to kslt # The original xterm-r6 entry does in fact have a VMS bias. # # Some legacy applications using the termcap emulation may expect kll where # we have specified kend. # # Function keys with modifiers (Sun/PC): # ------------------------------------- # Shift-Fx - kf{12+x} # Control-Fx - kf{24+x} # Shift-Control-Fx - kf{36+x} # # The terminfo defines some special keys which are documented as "shifted", # e.g., kDC is shifted-delete-character. # # Note however, that even though the terminfo says a key might be sent, there # may be conflicts which prevent this. For example, it is common to use # shifted pageup and pagedown for window manager functions. The default # translation for xterm since X11R4 has overridden shifted Insert, Select, # PageUp and PageDown, which correspond to terminfo kIC, kEND, kPRV and kNXT # respectively. # xterm-new|modern xterm terminal emulator, rv=\E\\[>41;[1-6][0-9][0-9];0c, xr=\EP>\\|XTerm\\(([1-9][0-9]+) \\)\E\\\\, use=dec+sl, use=ecma+index, use=xterm+keypad, use=vt420+lrmm, use=xterm+sm+1006, use=ansi+rep, use=ecma+strikeout, use=xterm+pcfkeys, use=xterm+tmux, use=xterm+nofkeys, use=bracketed+paste, use=report+version, use=xterm+focus, # Left/right margins are supported in xterm since patch #279 (2012/05/10) vt420+lrmm|VT420 left/right margins, mgc=\E[?69l, smglp=\E[?69h\E[%i%p1%ds, smglr=\E[?69h\E[%i%p1%d;%p2%ds, smgrp=\E[?69h\E[%i;%p1%ds, # These "ansi+XXX" blocks were added in ncurses 5.0 or 5.1: ansi+arrows|ANSI normal-mode home and cursor-keys, kbs=^H, kcub1=\E[D, kcud1=\E[B, kcuf1=\E[C, kcuu1=\E[A, khome=\E[H, ansi+csr|ANSI scroll-region plus cursor save & restore, csr=\E[%i%p1%d;%p2%dr, rc=\E8, sc=\E7, ansi+cup|ANSI absolute cursor-addressing, cup=\E[%i%p1%d;%p2%dH, home=\E[H, ansi+enq|ncurses extension for ANSI ENQ, u6=\E[%i%d;%dR, u7=\E[6n, u8=\E[?%[;0123456789]c, u9=\E[c, ansi+erase|ANSI clear screen/line, clear=\E[H\E[J, ed=\E[J, el=\E[K, ansi+idc1|ANSI insert/delete one character, dch1=\E[P, ich1=\E[@, rmir=\E[4l, smir=\E[4h, ansi+idc|ANSI insert/delete characters, dch=\E[%p1%dP, ich=\E[%p1%d@, use=ansi+idc1, ansi+idl1|ANSI insert/delete one line, dl1=\E[M, il1=\E[L, ansi+idl|ANSI insert/delete lines, dl=\E[%p1%dM, il=\E[%p1%dL, use=ansi+idl1, ansi+inittabs|ANSI initial tab-stops, it#8, use=ansi+tabs, ansi+local1|ANSI normal-mode cursor-keys, cub1=\E[D, cud1=\E[B, cuf1=\E[C, cuu1=\E[A, ansi+local|ANSI normal-mode parameterized cursor-keys, cub=\E[%p1%dD, cud=\E[%p1%dB, cuf=\E[%p1%dC, cuu=\E[%p1%dA, use=ansi+local1, ansi+pp|ANSI printer port, mc5i, mc0=\E[i, mc4=\E[4i, mc5=\E[5i, ansi+rep|ANSI repeat-character, rep=%p1%c\E[%p2%{1}%-%db, ansi+sgr|ANSI graphic renditions, blink=\E[5m, invis=\E[8m, rev=\E[7m, sgr=\E[0 %? %p3 %t;7 %; %? %p4 %t;5 %; %? %p7 %t;8 %; m, sgr0=\E[0m, ansi+sgrso|ANSI standout only, rmso=\E[m, smso=\E[7m, ansi+sgrul|ANSI underline only, rmul=\E[m, smul=\E[4m, ansi+sgrbold|ANSI graphic renditions; assuming terminal has bold; not dim, bold=\E[1m, sgr=\E[ %? %p1 %t7; %; %? %p2 %t4; %; %? %p3 %t7; %; %? %p4 %t5; %; %? %p6 %t1; %; %? %p7 %t8; %; m, use=ansi+sgr, use=ansi+sgrso, use=ansi+sgrul, ansi+sgrdim|ANSI graphic renditions; assuming terminal has dim; not bold, dim=\E[2m, sgr=\E[ %? %p1 %t7; %; %? %p2 %t4; %; %? %p3 %t7; %; %? %p4 %t5; %; %? %p5 %t2; %; %? %p7 %t8; %; m, use=ansi+sgr, use=ansi+sgrso, use=ansi+sgrul, ansi+tabs|ANSI tab-stops, cbt=\E[Z, ht=^I, hts=\EH, tbc=\E[3g, # These were added after ncurses 6.0: ansi+apparrows|ANSI application-mode home and cursor-keys, kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA, khome=\EOH, use=ansi+arrows, ansi+cpr|ncurses extension for ANSI CPR, u6=\E[%i%d;%dR, u7=\E[6n, ansi+rca2|ANSI relative cursor-addressing, hpa=\E[%i%p1%dG, vpa=\E[%i%p1%dd, # Encode modifiers using parameters (see "Xterm Control Sequences" ctlseqs.ms). # Note that this is unrelated to PCTERM. # # Some names are extensions allowed by ncurses, e.g., # kDN, kDN5, kDN6, kLFT5, kLFT6, kRIT5, kRIT6, kUP, kUP5, kUP6 # # The uppercase names are made up, since there are no standards that apply. # If they were limited to two characters, they could in principle be translated # to termcap. However, termcap sizes are limited to 1023 bytes, so there is # little point in ensuring that extended key names can be translated to # termcap. A terminfo file can be up to 4096 bytes; using all extended keys # that xterm can generate would in fact exceed that limit. # # The numbers correspond to the modifier parameters documented in Xterm # Control Sequences: # # 2 Shift # 3 Alt # 4 Shift + Alt # 5 Control # 6 Shift + Control # 7 Alt + Control # 8 Shift + Alt + Control # # X/Open Curses defines some shift combinations, which are also used here # where applicable. Since it does define some shift combinations, no number # (2) is used for suffixing the made-up names. Some combinations are not # useful, e.g., they may reboot your computer, or they may require too many # fingers. I stopped at modifier 7, just to keep things simple -TD # # XTerm resources: # --------------- # The xterm+pcfn, xterm+pcf0, xterm+pcf1, xterm+pcf2 and xterm+pcf3 fragments # correspond to default resource settings for xterm on a 104-key PC keyboard # with 12 function-keys: # # *sunKeyboard:false # *oldXtermFKeys:false # *modifyCursorKeys:2 # *modifyFunctionKeys:2 # *ctrlFKeys:10 # # The key numbers are computed based on the modifiers: # # kf1-kf12 are F1-F12 # kf13-kf24 are shift F1-F12 # kf25-kf36 are control F1-F12 # kf37-kf48 are control+shift F1-F12 # kf49-kf60 are alt F1-F12 # kf61-kf63 are shift-alt F1-F3 # # Note that ncurses would allow definition of kf64 and beyond, if there were # an application that required it. # xterm+pcfkeys|fragment for PC-style keys, use=xterm+app, use=xterm+pcf2, use=xterm+pce2, use=xterm+pcc2, # This chunk is based on suggestions by Ailin Nemui and Nicholas Marriott, who # asked for some of xterm's advanced features to be added to its terminfo # entry. It defines extended capabilities not found in standard terminfo or # termcap. These are useful in tmux, for instance, hence the name. # # One caveat in adding extended capabilities in ncurses is that if the names # are longer than two characters, then they will not be visible through the # termcap interface. # # Ms modifies the selection/clipboard. Its parameters are # p1 = the storage unit (clipboard, selection or cut buffer) # p2 = the base64-encoded clipboard content. # # Ss is used to set the cursor style as described by the DECSCUSR # function to a block or underline. # Se resets the cursor style to the terminal power-on default. # # Cs and Ce set and reset the cursor colour. xterm+tmux|advanced xterm features used in tmux, Cr=\E]112\007, Cs=\E]12;%p1%s\007, Ms=\E]52;%p1%s;%p2%s \007, Se=\E[2\sq, Ss=\E[%p1%d\sq, # # The ctrlFKeys resource is only relevant to the xterm+pcfn and xterm+pcfN # entries, since the modifyFunctionKeys resource overrides ctrlFKeys when it is # positive. A different choice of ctrlFKeys would give a different set of # function-key strings. xterm+pcfn|fragment with modifyFunctionKeys:-1 and ctrlFKeys:10, kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, kf15=\E[28~, kf16=\E[29~, kf17=\E[31~, kf18=\E[32~, kf19=\E[33~, kf2=\EOQ, kf20=\E[34~, kf21=\E[42~, kf22=\E[43~, kf23=\E[44~, kf24=\E[45~, kf25=\E[46~, kf26=\E[47~, kf27=\E[48~, kf28=\E[49~, kf29=\E[50~, kf3=\EOR, kf30=\E[51~, kf31=\E[52~, kf32=\E[53~, kf33=\E[54~, kf34=\E[55~, kf35=\E[56~, kf36=\E[57~, kf37=\E[58~, kf38=\E[59~, kf39=\E[60~, kf4=\EOS, kf40=\E[61~, kf41=\E[62~, kf42=\E[63~, kf43=\E[64~, kf44=\E[65~, kf45=\E[66~, kf46=\E[67~, kf47=\E[68~, kf48=\E[69~, kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, # Changing ctrlFKeys to 12 would let us number the keys using just shift- and # control- modifiers: # kf1-kf12 are F1-F12 # kf13-kf24 are shift F1-F12 # kf25-kf36 are control F1-F12 # kf37-kf48 are control+shift F1-F12 xterm+pcfN|fragment with modifyFunctionKeys:-1 and ctrlFKeys:12, kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, kf15=\E[28~, kf16=\E[29~, kf17=\E[31~, kf18=\E[32~, kf19=\E[33~, kf2=\EOQ, kf20=\E[34~, kf21=\E[42~, kf22=\E[43~, kf23=\E[44~, kf24=\E[45~, kf25=\E[46~, kf26=\E[47~, kf27=\E[48~, kf28=\E[49~, kf29=\E[50~, kf3=\EOR, kf30=\E[51~, kf31=\E[52~, kf32=\E[53~, kf33=\E[54~, kf34=\E[55~, kf35=\E[56~, kf36=\E[57~, kf37=\E[58~, kf38=\E[59~, kf39=\E[60~, kf4=\EOS, kf40=\E[61~, kf41=\E[62~, kf42=\E[63~, kf43=\E[64~, kf44=\E[65~, kf45=\E[66~, kf46=\E[67~, kf47=\E[68~, kf48=\E[69~, kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, xterm+pcf0|fragment with modifyFunctionKeys:0, kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\EO2P, kf14=\EO2Q, kf15=\EO2R, kf16=\EO2S, kf17=\E[15;2~, kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~, kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~, kf25=\EO5P, kf26=\EO5Q, kf27=\EO5R, kf28=\EO5S, kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, kf31=\E[18;5~, kf32=\E[19;5~, kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~, kf36=\E[24;5~, kf37=\EO6P, kf38=\EO6Q, kf39=\EO6R, kf4=\EOS, kf40=\EO6S, kf41=\E[15;6~, kf42=\E[17;6~, kf43=\E[18;6~, kf44=\E[19;6~, kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~, kf48=\E[24;6~, kf49=\EO3P, kf5=\E[15~, kf50=\EO3Q, kf51=\EO3R, kf52=\EO3S, kf53=\E[15;3~, kf54=\E[17;3~, kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~, kf58=\E[21;3~, kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~, kf61=\EO4P, kf62=\EO4Q, kf63=\EO4R, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, # This is almost the same as xterm+pcf2 because the unmodified keys all happen # to have a pattern that forces the modifier to the same position. xterm+pcf1|fragment with modifyFunctionKeys:1, kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[2P, kf14=\E[2Q, kf15=\E[2R, kf16=\E[2S, kf17=\E[15;2~, kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~, kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~, kf25=\E[5P, kf26=\E[5Q, kf27=\E[5R, kf28=\E[5S, kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, kf31=\E[18;5~, kf32=\E[19;5~, kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~, kf36=\E[24;5~, kf37=\E[6P, kf38=\E[6Q, kf39=\E[6R, kf4=\EOS, kf40=\E[6S, kf41=\E[15;6~, kf42=\E[17;6~, kf43=\E[18;6~, kf44=\E[19;6~, kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~, kf48=\E[24;6~, kf49=\E[3P, kf5=\E[15~, kf50=\E[3Q, kf51=\E[3R, kf52=\E[3S, kf53=\E[15;3~, kf54=\E[17;3~, kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~, kf58=\E[21;3~, kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~, kf61=\E[4P, kf62=\E[4Q, kf63=\E[4R, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, xterm+pcf2|fragment with modifyFunctionKeys:2, kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[1;2P, kf14=\E[1;2Q, kf15=\E[1;2R, kf16=\E[1;2S, kf17=\E[15;2~, kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~, kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~, kf25=\E[1;5P, kf26=\E[1;5Q, kf27=\E[1;5R, kf28=\E[1;5S, kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, kf31=\E[18;5~, kf32=\E[19;5~, kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~, kf36=\E[24;5~, kf37=\E[1;6P, kf38=\E[1;6Q, kf39=\E[1;6R, kf4=\EOS, kf40=\E[1;6S, kf41=\E[15;6~, kf42=\E[17;6~, kf43=\E[18;6~, kf44=\E[19;6~, kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~, kf48=\E[24;6~, kf49=\E[1;3P, kf5=\E[15~, kf50=\E[1;3Q, kf51=\E[1;3R, kf52=\E[1;3S, kf53=\E[15;3~, kf54=\E[17;3~, kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~, kf58=\E[21;3~, kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~, kf61=\E[1;4P, kf62=\E[1;4Q, kf63=\E[1;4R, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, xterm+pcf3|fragment with modifyFunctionKeys:3, kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[>1;2P, kf14=\E[>1;2Q, kf15=\E[>1;2R, kf16=\E[>1;2S, kf17=\E[>15;2~, kf18=\E[>17;2~, kf19=\E[>18;2~, kf2=\EOQ, kf20=\E[>19;2~, kf21=\E[>20;2~, kf22=\E[>21;2~, kf23=\E[>23;2~, kf24=\E[>24;2~, kf25=\E[>1;5P, kf26=\E[>1;5Q, kf27=\E[>1;5R, kf28=\E[>1;5S, kf29=\E[>15;5~, kf3=\EOR, kf30=\E[>17;5~, kf31=\E[>18;5~, kf32=\E[>19;5~, kf33=\E[>20;5~, kf34=\E[>21;5~, kf35=\E[>23;5~, kf36=\E[>24;5~, kf37=\E[>1;6P, kf38=\E[>1;6Q, kf39=\E[>1;6R, kf4=\EOS, kf40=\E[>1;6S, kf41=\E[>15;6~, kf42=\E[>17;6~, kf43=\E[>18;6~, kf44=\E[>19;6~, kf45=\E[>20;6~, kf46=\E[>21;6~, kf47=\E[>23;6~, kf48=\E[>24;6~, kf49=\E[>1;3P, kf5=\E[15~, kf50=\E[>1;3Q, kf51=\E[>1;3R, kf52=\E[>1;3S, kf53=\E[>15;3~, kf54=\E[>17;3~, kf55=\E[>18;3~, kf56=\E[>19;3~, kf57=\E[>20;3~, kf58=\E[>21;3~, kf59=\E[>23;3~, kf6=\E[17~, kf60=\E[>24;3~, kf61=\E[>1;4P, kf62=\E[>1;4Q, kf63=\E[>1;4R, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, # # The "PC-style" modifier scheme was introduced in xterm patch #94 (1999/3/27) # and revised in patch #167 (2002/8/24). # # The original assignments from patch #94 for cursor-keys had some technical # issues: # # A parameter for a function-key to represent a modifier is just more # bits. But for a cursor-key it may change the behavior of the # application. For instance, emacs decodes the first parameter of a # cursor-key as a repeat count. # # A parameterized string should (really) not begin with SS3 (\EO). # Rather, CSI (\E[) should be used. # # For these reasons, the original assignments were deprecated. For # compatibility reasons, they are still available as a setting of xterm's # modifyCursorKeys resource. These fragments list the modified cursor-keys # that might apply to xterm+pcfkeys with different values of that resource. xterm+pcc3|fragment with modifyCursorKeys:3, kLFT=\E[>1;2D, kRIT=\E[>1;2C, kind=\E[>1;2B, kri=\E[>1;2A, kDN=\E[>1;2B, kDN3=\E[>1;3B, kDN4=\E[>1;4B, kDN5=\E[>1;5B, kDN6=\E[>1;6B, kDN7=\E[>1;7B, kLFT3=\E[>1;3D, kLFT4=\E[>1;4D, kLFT5=\E[>1;5D, kLFT6=\E[>1;6D, kLFT7=\E[>1;7D, kRIT3=\E[>1;3C, kRIT4=\E[>1;4C, kRIT5=\E[>1;5C, kRIT6=\E[>1;6C, kRIT7=\E[>1;7C, kUP=\E[>1;2A, kUP3=\E[>1;3A, kUP4=\E[>1;4A, kUP5=\E[>1;5A, kUP6=\E[>1;6A, kUP7=\E[>1;7A, xterm+pcc2|fragment with modifyCursorKeys:2, kLFT=\E[1;2D, kRIT=\E[1;2C, kind=\E[1;2B, kri=\E[1;2A, kDN=\E[1;2B, kDN3=\E[1;3B, kDN4=\E[1;4B, kDN5=\E[1;5B, kDN6=\E[1;6B, kDN7=\E[1;7B, kLFT3=\E[1;3D, kLFT4=\E[1;4D, kLFT5=\E[1;5D, kLFT6=\E[1;6D, kLFT7=\E[1;7D, kRIT3=\E[1;3C, kRIT4=\E[1;4C, kRIT5=\E[1;5C, kRIT6=\E[1;6C, kRIT7=\E[1;7C, kUP=\E[1;2A, kUP3=\E[1;3A, kUP4=\E[1;4A, kUP5=\E[1;5A, kUP6=\E[1;6A, kUP7=\E[1;7A, xterm+pcc1|fragment with modifyCursorKeys:1, kLFT=\E[2D, kRIT=\E[2C, kind=\E[2B, kri=\E[2A, kDN=\E[2B, kDN3=\E[3B, kDN4=\E[4B, kDN5=\E[5B, kDN6=\E[6B, kDN7=\E[7B, kLFT3=\E[3D, kLFT4=\E[4D, kLFT5=\E[5D, kLFT6=\E[6D, kLFT7=\E[7D, kRIT3=\E[3C, kRIT4=\E[4C, kRIT5=\E[5C, kRIT6=\E[6C, kRIT7=\E[7C, kUP=\E[2A, kUP3=\E[3A, kUP4=\E[4A, kUP5=\E[5A, kUP6=\E[6A, kUP7=\E[7A, xterm+pcc0|fragment with modifyCursorKeys:0, kLFT=\EO2D, kRIT=\EO2C, kind=\EO2B, kri=\EO2A, kDN=\EO2B, kDN3=\EO3B, kDN4=\EO4B, kDN5=\EO5B, kDN6=\EO6B, kDN7=\EO7B, kLFT3=\EO3D, kLFT4=\EO4D, kLFT5=\EO5D, kLFT6=\EO6D, kLFT7=\EO7D, kRIT3=\EO3C, kRIT4=\EO4C, kRIT5=\EO5C, kRIT6=\EO6C, kRIT7=\EO7C, kUP=\EO2A, kUP3=\EO3A, kUP4=\EO4A, kUP5=\EO5A, kUP6=\EO6A, kUP7=\EO7A, # The home/end keys on the editing keypad are also treated as cursor keys. xterm+pce3|fragment with modifyCursorKeys:3, kDC=\E[>3;2~, kEND=\E[>1;2F, kHOM=\E[>1;2H, kIC=\E[>2;2~, kNXT=\E[>6;2~, kPRV=\E[>5;2~, kDC3=\E[>3;3~, kDC4=\E[>3;4~, kDC5=\E[>3;5~, kDC6=\E[>3;6~, kDC7=\E[>3;7~, kEND3=\E[>1;3F, kEND4=\E[>1;4F, kEND5=\E[>1;5F, kEND6=\E[>1;6F, kEND7=\E[>1;7F, kHOM3=\E[>1;3H, kHOM4=\E[>1;4H, kHOM5=\E[>1;5H, kHOM6=\E[>1;6H, kHOM7=\E[>1;7H, kIC3=\E[>2;3~, kIC4=\E[>2;4~, kIC5=\E[>2;5~, kIC6=\E[>2;6~, kIC7=\E[>2;7~, kNXT3=\E[>6;3~, kNXT4=\E[>6;4~, kNXT5=\E[>6;5~, kNXT6=\E[>6;6~, kNXT7=\E[>6;7~, kPRV3=\E[>5;3~, kPRV4=\E[>5;4~, kPRV5=\E[>5;5~, kPRV6=\E[>5;6~, kPRV7=\E[>5;7~, use=xterm+pce0, xterm+pce2|fragment with modifyCursorKeys:2, kDC=\E[3;2~, kEND=\E[1;2F, kHOM=\E[1;2H, kIC=\E[2;2~, kNXT=\E[6;2~, kPRV=\E[5;2~, kDC3=\E[3;3~, kDC4=\E[3;4~, kDC5=\E[3;5~, kDC6=\E[3;6~, kDC7=\E[3;7~, kEND3=\E[1;3F, kEND4=\E[1;4F, kEND5=\E[1;5F, kEND6=\E[1;6F, kEND7=\E[1;7F, kHOM3=\E[1;3H, kHOM4=\E[1;4H, kHOM5=\E[1;5H, kHOM6=\E[1;6H, kHOM7=\E[1;7H, kIC3=\E[2;3~, kIC4=\E[2;4~, kIC5=\E[2;5~, kIC6=\E[2;6~, kIC7=\E[2;7~, kNXT3=\E[6;3~, kNXT4=\E[6;4~, kNXT5=\E[6;5~, kNXT6=\E[6;6~, kNXT7=\E[6;7~, kPRV3=\E[5;3~, kPRV4=\E[5;4~, kPRV5=\E[5;5~, kPRV6=\E[5;6~, kPRV7=\E[5;7~, use=xterm+pce0, xterm+pce1|fragment with modifyCursorKeys:1, kDC=\E[3;2~, kEND=\E[2F, kHOM=\E[2H, kIC=\E[2;2~, kNXT=\E[6;2~, kPRV=\E[5;2~, kDC3=\E[3;3~, kDC4=\E[3;4~, kDC5=\E[3;5~, kDC6=\E[3;6~, kDC7=\E[3;7~, kEND3=\E[3F, kEND4=\E[4F, kEND5=\E[5F, kEND6=\E[6F, kEND7=\E[7F, kHOM3=\E[3H, kHOM4=\E[4H, kHOM5=\E[5H, kHOM6=\E[6H, kHOM7=\E[7H, kIC3=\E[2;3~, kIC4=\E[2;4~, kIC5=\E[2;5~, kIC6=\E[2;6~, kIC7=\E[2;7~, kNXT3=\E[6;3~, kNXT4=\E[6;4~, kNXT5=\E[6;5~, kNXT6=\E[6;6~, kNXT7=\E[6;7~, kPRV3=\E[5;3~, kPRV4=\E[5;4~, kPRV5=\E[5;5~, kPRV6=\E[5;6~, kPRV7=\E[5;7~, use=xterm+pce0, xterm+pce0|fragment with modifyCursorKeys:0, kDC=\E[3;2~, kEND=\EO2F, kHOM=\EO2H, kIC=\E[2;2~, kNXT=\E[6;2~, kPRV=\E[5;2~, kDC3=\E[3;3~, kDC4=\E[3;4~, kDC5=\E[3;5~, kDC6=\E[3;6~, kDC7=\E[3;7~, kEND3=\EO3F, kEND4=\EO4F, kEND5=\EO5F, kEND6=\EO6F, kEND7=\EO7F, kHOM3=\EO3H, kHOM4=\EO4H, kHOM5=\EO5H, kHOM6=\EO6H, kHOM7=\EO7H, kIC3=\E[2;3~, kIC4=\E[2;4~, kIC5=\E[2;5~, kIC6=\E[2;6~, kIC7=\E[2;7~, kNXT3=\E[6;3~, kNXT4=\E[6;4~, kNXT5=\E[6;5~, kNXT6=\E[6;6~, kNXT7=\E[6;7~, kPRV3=\E[5;3~, kPRV4=\E[5;4~, kPRV5=\E[5;5~, kPRV6=\E[5;6~, kPRV7=\E[5;7~, use=vt220+pcedit, ecma+italics|ECMA-48 italics, ritm=\E[23m, sitm=\E[3m, # The rmxx/smxx capabilities are an ncurses extension ecma+strikeout|ECMA-48 strikeout/crossed-out, rmxx=\E[29m, smxx=\E[9m, # ECMA-48 does not include the VT100 indexing and scroll-margins. It has its # own variation. ecma+index|ECMA-48 scroll up/down, indn=\E[%p1%dS, rin=\E[%p1%dT, # The XM capability is an ncurses extension xterm+sm+1006|xterm SGR-mouse, kmous=\E[<, XM=\E[?1006;1000 %? %p1%{1}%= %th %e l %;, xm=\E[<%i %p3%d; %p1%d; %p2%d; %? %p4 %tM %e m %;, # By default, ncurses knows that xterm private mode 1000 enables/disables # the X11 xterm mouse protocol. So XM is not needed here, except for clarity. xterm+x11mouse|X11 xterm mouse protocol, kmous=\E[M, XM=\E[?1000 %? %p1%{1}%= %th %e l %;, xm=\E[M %? %p4 %t %p3 %e%{3} %; %'\s'%+%c %p2%'!'%+%c %p1%'!'%+%c, # xterm patch #224 2007/2/11 added private mode 1004, for enabling/disabling # focus in/out event reporting. The 1004 is normally part of XM in a different # building-block, e.g., for reporting any events. xterm+focus|xterm focus-in/out event "keys", XF, fd=\E[?1004l, fe=\E[?1004h, kxIN=\E[I, kxOUT=\E[O, # https://invisible-island.net/xterm/xterm-paste64.html # # Bracketed paste was introduced by xterm patch #203 in May 2005, as part of a # larger feature for manipulating the clipboard selection. Few terminals aside # from xterm fully implement the clipboard feature, but several copy this # detail. The names for the extended capabilities here were introduced by vim # in January 2017, but used internally. In 2023, vim patch 9.0.1117 is needed # to work with this change. bracketed+paste|xterm bracketed paste, BD=\E[?2004l, BE=\E[?2004h, PE=\E[201~, PS=\E[200~, # https://invisible-island.net/xterm/xterm.log.html#xterm_354 # # The response is a DSR sequence identifying the version: DCS > | text ST # For example: # ^[P>|XTerm(354)^[\ # This generic building-block matches ncurses. report+version|Report xterm name and version (XTVERSION)., XR=\E[>0q, xr=\EP>\\|[\s-~]+\E\\\\, use=report+da2, # Vim uses RV to denote the secondary device attributes. Xterm documents the # - first parameter as the terminal type (extending it to VT100), # - the second as the patch number for xterm, and # - the third parameter as zero. # Other terminals may provide useful responses, though few are documented. # # Since patch #280 2012/06/24, xterm by default reports itself as a VT420. # This generic building-block matches ncurses. report+da2|report secondary device attributes (DA2), RV=\E[>c, rv=\E\\[>[0-9]+;[0-9]+;[0-9]+c, # This chunk is used for building the VT220/Sun/PC keyboard variants. xterm-basic|modern xterm terminal emulator - common, OTbs, am, bce, km, mir, msgr, xenl, AX, XT, colors#8, cols#80, lines#24, pairs#64, acsc=``aaffggiijjkkllmmnnooppqqr rssttuuvvwwxxyyzz{{||}}~~, bel=^G, civis=\E[?25l, clear=\E[H\E[2J, cnorm=\E[?12l\E[?25h, cr=\r, cub1=^H, cud1=\n, cup=\E[%i%p1%d;%p2%dH, cvvis=\E[?12;25h, dch=\E[%p1%dP, dch1=\E[P, ech=\E[%p1%dX, ed=\E[J, el=\E[K, el1=\E[1K, flash=\E[?5h$<100/>\E[?5l, home=\E[H, ich=\E[%p1%d@, ind=\n, is2=\E[!p\E[?3;4l\E[4l\E>, kmous=\E[M, meml=\El, memu=\Em, op=\E[39;49m, ri=\EM, rmacs=\E(B, rmam=\E[?7l, rmir=\E[4l, rmkx=\E[?1l\E>, rmm=\E[?1034l, rmso=\E[27m, rmul=\E[24m, rs1=\Ec, rs2=\E[!p\E[?3;4l\E[4l\E>, setab=\E[4%p1%dm, setaf=\E[3%p1%dm, setb=\E[4 %? %p1%{1}%= %t4 %e %p1%{3}%= %t6 %e %p1%{4}%= %t1 %e %p1%{6}%= %t3 %e %p1%d %; m, setf=\E[3 %? %p1%{1}%= %t4 %e %p1%{3}%= %t6 %e %p1%{4}%= %t1 %e %p1%{6}%= %t3 %e %p1%d %; m, sgr= %? %p9 %t\E(0 %e \E(B %; \E[0 %? %p6 %t;1 %; %? %p5 %t;2 %; %? %p2 %t;4 %; %? %p1 %p3%| %t;7 %; %? %p4 %t;5 %; %? %p7 %t;8 %; m, sgr0=\E(B\E[m, smacs=\E(0, smam=\E[?7h, smir=\E[4h, smkx=\E[?1h\E=, smm=\E[?1034h, E3=\E[3J, use=ansi+csr, use=ansi+enq, use=ansi+idl, use=ansi+inittabs, use=ansi+local, use=ansi+pp, use=ansi+rca2, use=ansi+sgrbold, use=ansi+sgrdim, use=xterm+alt+title, use=xterm+kbs, xterm+nofkeys|building block for xterm fkey-variants, npc, kcbt=\E[Z, kent=\EOM, nel=\EE, use=ecma+index, use=ansi+rep, use=ecma+strikeout, use=vt420+lrmm, use=xterm+sm+1006, use=xterm+tmux, use=xterm+focus, use=ecma+italics, use=xterm+keypad, use=xterm-basic, # # The xterm-new description has all of the features, but is not completely # compatible with vt220. If you are using a Sun or PC keyboard, set the # sunKeyboard resource to true: # + maps the editing keypad # + interprets control-function-key as a second array of keys, so a # 12-fkey keyboard can support vt220's 20-fkeys. # + maps numeric keypad "+" to ",". # + uses DEC-style control sequences for the application keypad. # # Some packagers modify xterm's resource definitions to provide extra function # keys by using the shift-modifier in the translations resource. However, that # interferes with the DECUDK functionality. # xterm-vt220|xterm emulating vt220, npc, kcbt=\E[Z, kend=\E[4~, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, kf15=\E[28~, kf16=\E[29~, kf17=\E[31~, kf18=\E[32~, kf19=\E[33~, kf20=\E[34~, kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, khome=\E[1~, kmous=\E[M, nel=\EE, use=xterm+app, use=vt220+keypad, use=vt220+pcedit, use=ecma+italics, use=ecma+index, use=ansi+rep, use=ecma+strikeout, use=xterm+focus, use=xterm+sm+1006, use=xterm+tmux, use=xterm+keypad, use=xterm-basic, # xterm-vt52|xterm emulating dec vt52, cols#80, it#8, lines#24, acsc=``aaffggjjkkllmmnnooppqqrrs sttuuvvwwxxyyzz{{||}}~~, bel=^G, clear=\EH\EJ, cr=\r, cub1=\ED, cud1=\EB, cuf1=\EC, cup=\EY%p1%'\s'%+%c%p2%'\s'%+%c, cuu1=\EA, ed=\EJ, el=\EK, home=\EH, ht=^I, ind=\n, kcub1=\ED, kcud1=\EB, kcuf1=\EC, kcuu1=\EA, nel=\r\n, ri=\EI, rmacs=\EG, smacs=\EF, use=xterm+kbs, use=vt52+keypad, # from ncurses 6.2: # DECScope of course had no "function keys", but this building block assigns # the three blank keys at the top of the auxiliary (numeric) keypad, using # the same analogy as vt100 (also lacking function-keys). # # These assignments use the same layout for 0-9 as vt100+keypad; the vt52 # keypad had its cursor-keys on the right-column as shown -TD # _______________________________________ # | PF1 | PF2 | PF3 | c-up | # | \EP | \EQ | \ER | \EA | # |_kf1__k1_|_kf2__k2_|_kf3__k3_|kcuu1_k4_| # | 7 8 9 c-down | # | \E?w | \E?x | \E?y | \EB | # |_kf9__k9_|_kf10_k;_|_kf0__k0_|kcud1____| # | 4 | 5 | 6 | c-right | # | \E?t | \E?u | \E?v | \EC | # |_kf5__k5_|_kf6__k6_|_kf7__k7_|kcuf1_k8_| # | 1 | 2 | 3 | c-left | # | \E?q | \E?r | \E?s | \ED | # |_ka1__K1_|_kb2__K2_|_ka3__K3_|kcub1____| # | 0 | . | enter | # | \E?p | \E?n | \E?M | # |___kc1_______K4____|_kc3__K5_|_kent_@8_| # vt52+keypad|DECScope auxiliary keypad, ka1=\E?q, ka3=\E?s, kb2=\E?r, kc1=\E?p, kc3=\E?n, kf0=\E?y, kf1=\EP, kf2=\EQ, kf3=\ER, kf5=\E?t, kf6=\E?u, kf7=\E?v, kf8=\E?w, kf9=\E?x, # # Sun does not number the function keys this way in their sparse termcap; their # terminal descriptions ignore the keypads. kb(7M) states that there are codes # reserved for 64 function keys, 16 each in left, right, top and bottom. Each # keyboard type has a different number of function keys in different # arrangements. Using xkeycaps for reference: # # Type 3: left 10, top 9, right 15 # ------ # kf1-kf9 are XK_F1-XK_F9 # There is no kf10 on this keyboard type. # kf11-kf20 are keysyms XK_L1 through XK_L10. # kf31-kf45 are keysyms XK_R1 through XK_R15. # # However, X's keysymdef.h is hard-coded to make # XK_L1==XK_F11 and # XK_R1==XK_F21, # by someone who was unfamiliar with terminal types other than Sun's. So # xterm uses the internal X keysymbols, but the terminfo entry uses the Sun # numbering scheme. # # Type 4: left 11, top 12, right 15 # ------ # The left-keypad contains an unnumbered Help-key. # The right-keypad also contains NumLock, Ins, Del, Enter, + and - keys which # do not appear to be part of the R-sequence. # # Type 5: left 9, top 12, right (more than one keypad) # ------ # These keyboards do not use the same naming convention, look like a hybrid of # the type 4 and IBM keyboards. # # XTerm resources: # --------------- # Set the modifyFunctionKeys resource to negative (-1) to make it simple to # enter the higher function-key values using shift- and control-modifiers. # xterm-sun|xterm with sun function keys, kb2=\E[218z, kcpy=\E[197z, kdch1=\E[3z, kend=\E[220z, kf1=\E[224z, kf10=\E[233z, kf11=\E[192z, kf12=\E[193z, kf13=\E[194z, kf14=\E[195z, kf15=\E[196z, kf17=\E[198z, kf18=\E[199z, kf19=\E[200z, kf2=\E[225z, kf20=\E[201z, kf3=\E[226z, kf31=\E[208z, kf32=\E[209z, kf33=\E[210z, kf34=\E[211z, kf35=\E[212z, kf36=\E[213z, kf38=\E[215z, kf4=\E[227z, kf40=\E[217z, kf42=\E[219z, kf44=\E[221z, kf45=\E[222z, kf46=\E[234z, kf47=\E[235z, kf5=\E[228z, kf6=\E[229z, kf7=\E[230z, kf8=\E[231z, kf9=\E[232z, kfnd=\E[200z, khlp=\E[196z, khome=\E[214z, kich1=\E[2z, knp=\E[222z, kpp=\E[216z, kund=\E[195z, use=xterm+kbs, use=ansi+apparrows, use=xterm+nopcfkeys, use=xterm+nofkeys, # Note: normally xterm supports modified function-keys as described in # XTerm - "Other" modified keys # https://invisible-island.net/xterm/modified-keys.html # # However, xterm-hp, xterm-sco and xterm-sun assume no modifiers. Here is # a simple script which demonstrates these descriptions: # #!/bin/sh # export TERM=xterm-$1 # xterm \ # -kt $1 \ # -fs 16 -fa mono \ # -title $TERM \ # -tn $TERM \ # -xrm '*modifyCursorKeys:-1' \ # -xrm '*modifyFunctionKeys:-1' \ # -e tack # e.g., "foo sun" if the script is named "foo" -TD xterm-hp|xterm with hpterm function keys, kclr=\EJ, kcub1=\ED, kcud1=\EB, kcuf1=\EC, kcuu1=\EA, kdch1=\EP, kend=\EF, kf1=\Ep, kf2=\Eq, kf3=\Er, kf4=\Es, kf5=\Et, kf6=\Eu, kf7=\Ev, kf8=\Ew, khome=\Eh, kich1=\EQ, knp=\ES, kpp=\ET, use=xterm+nofkeys, use=xterm+nopcfkeys, # # scoterm implements 48 function-keys using shift- and control-modifiers to # multiple 12 function-keys. X has a hard-coded limit of 35 function-keys, # but xterm can represent larger values. # # XTerm resources: # --------------- # Set the modifyFunctionKeys resource to negative (-1) to make it simple to # enter the higher function-key values using shift- and control-modifiers. # # Also, set ctrlFKeys resource to 12 (the default is 10) to make xterm see 48 # function-keys on a keyboard with 12 function-keys and 4 control/shift # modifier combinations. # xterm-sco|xterm with SCO function keys, kbeg=\E[E, kdch1=^?, kf1=\E[M, kf10=\E[V, kf11=\E[W, kf12=\E[X, kf13=\E[Y, kf14=\E[Z, kf15=\E[a, kf16=\E[b, kf17=\E[c, kf18=\E[d, kf19=\E[e, kf2=\E[N, kf20=\E[f, kf21=\E[g, kf22=\E[h, kf23=\E[i, kf24=\E[j, kf25=\E[k, kf26=\E[l, kf27=\E[m, kf28=\E[n, kf29=\E[o, kf3=\E[O, kf30=\E[p, kf31=\E[q, kf32=\E[r, kf33=\E[s, kf34=\E[t, kf35=\E[u, kf36=\E[v, kf37=\E[w, kf38=\E[x, kf39=\E[y, kf4=\E[P, kf40=\E[z, kf41=\E[@, kf42=\E[[, kf43=\E[\\, kf44=\E[], kf45=\E[\^, kf46=\E[_, kf47=\E[`, kf48=\E[{, kf5=\E[Q, kf6=\E[R, kf7=\E[S, kf8=\E[T, kf9=\E[U, kich1=\E[L, kmous=\E[>M, knp=\E[G, kpp=\E[I, use=vt100+noapp, use=xterm+nofkeys, # # Other variants (these are all very old entries, from X11R5): xterm-24|xterms|vs100|xterm terminal emulator (X Window System), lines#24, use=xterm-old, xterm-65|xterm with tall window 65x80 (X Window System), lines#65, use=xterm-old, xterm-bold|xterm with bold instead of underline (X Window System), sgr= %? %p9 %t\016 %e \017 %; B\E[0 %? %p6 %t;1 %; %? %p2 %t;1 %; %? %p1 %p3%| %t;7 %; m, smso=\E[7m, smul=\E[1m, use=xterm-old, xterm-boldso|xterm with bold for standout (X Window System), rmso=\E[m, smso=\E[1m, use=xterm-old, xterm-mono|monochrome xterm, use=xterm-old, # # VTxxx terminals are usually set up so that full-screen applications will use # the cursor application mode strings. This is good for full-screen # applications, including legacy applications which may have hard-coded # behavior, but bad for interactive shells (e.g., tcsh, bash) which use arrow # keys to scroll through a history of command strings. # # To see the difference between normal/application modes, consider this example: # + In normal (non-application) mode, the terminal transmits a down-arrow # as \E[C, which happens to echo as a down-arrow. # + In application mode the terminal transmits \EOC, which echoes as C. # That is because the \EO is the SS3 control, which says to use the # character from the G3 character set for the next cell. # # One example of hard-coded behavior would be for applications written to work # with VT52 and VT100 terminals. If the application's parser ignores 'O' and # '?' characters after the escape, then the cursor and keypad strings for the # two terminals are the same. (Indeed, one of the first curses applications # which I used did something like this to cover "ANSI" terminals -TD). # # To make this work (leaving the cursor keys in normal mode), we have to adjust # the terminal initialization sequences: # # smkx/rmkx set/reset the cursor and keypad application modes. We retain # the latter (otherwise many applications fail). # # smcup/rmcup set/restore cursor-addressing mode for full-screen # applications. For xterm, this normally means the alternate # screen, which is not compatible with interactive shells. Some # programs are "smart" and disable these. # xterm-noapp|xterm with cursor keys in normal mode, rmcup@, rmkx=\E>, smcup@, smkx=\E=, use=vt100+noapp, use=xterm, vt100+noapp|fragment with cursor keys in normal mode, kcub1=\E[D, kcud1=\E[B, kcuf1=\E[C, kcuu1=\E[A, use=vt100+noapp+pc, xterm+acs|ISO-2022 alternate character-switching for xterm, acsc=``aaffggiijjkkllmmnnooppqqr rssttuuvvwwxxyyzz{{||}}~~, enacs@, rmacs=\E(B, smacs=\E(0, xterm+app|fragment with cursor keys in application mode, kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA, use=xterm+app+pc, vt100+noapp+pc|fragment for noapp pc-style home/end, kend=\E[F, khome=\E[H, xterm+app+pc|fragment for app pc-style home/end, kend=\EOF, khome=\EOH, vt220+pcedit|fragment for 6-key editing-keypad, kdch1=\E[3~, kich1=\E[2~, knp=\E[6~, kpp=\E[5~, use=xterm+pc+edit, xterm+decedit|fragment for vt220 6-key editing-keypad, kdch1=\E[3~, kich1=\E[2~, knp=\E[6~, kpp=\E[5~, use=xterm+vt+edit, xterm+pc+edit|fragment for pc-style editing keypad, kend=\E[4~, khome=\E[1~, xterm+vt+edit|fragment for vt220-style editing keypad, kfnd=\E[1~, kslt=\E[4~, xterm+alt1049|xterm 90 feature, rmcup=\E[?1049l, smcup=\E[?1049h, xterm+titlestack|xterm 251 feature, rmcup=\E[23;0;0t, smcup=\E[22;0;0t, xterm+alt+title|xterm 90 and 251 features combined, rmcup=\E[?1049l\E[23;0;0t, smcup=\E[?1049h\E[22;0;0t, # The xterm ctrlFKeys resource defaults to 10, so without the "pc-style" # feature, e.g., setting the modifyCursorKeys and modifyFunctionKeys resources # to -1 to disable them, one gets 42 function-keys on a 12-function-key # keyboard, e.g., # kf1 = \E[11~ # kf11 shift f1 = \E[23~ # kf21 control f1 = \E[42~ # kf31 shift control f1 = \E[52~ xterm+nopcfkeys|fragment without PC-style fkeys, kf1=\E[11~, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, kf15=\E[28~, kf16=\E[29~, kf17=\E[31~, kf18=\E[32~, kf19=\E[33~, kf2=\E[12~, kf20=\E[34~, kf21=\E[42~, kf22=\E[43~, kf23=\E[44~, kf24=\E[45~, kf25=\E[46~, kf26=\E[47~, kf27=\E[48~, kf28=\E[49~, kf29=\E[50~, kf3=\E[13~, kf30=\E[51~, kf31=\E[52~, kf32=\E[53~, kf33=\E[54~, kf34=\E[55~, kf35=\E[56~, kf36=\E[57~, kf37=\E[58~, kf38=\E[59~, kf39=\E[60~, kf4=\E[14~, kf40=\E[61~, kf41=\E[62~, kf42=\E[63~, kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, # from development after ncurses 6.1: # Xterm's emulation of the VT100 numeric keypad on a PC-keyboard runs into the # problem that the keypad layout is different, and that the natural choice for # PF1 is NumLock (which happens to be reserved for other use). To work around # that, PF1-PF4 are emulated via F1-F4, which leaves the "/", "*" and "+" not # directly related to VT100. # # With the VT220 keypad block that uses the 1-9 keys as suggested in # terminfo(5), the other keys can be handled with user-defined capabilities: # # _______________________________________ # | NumLock | / | * | - | # | | $Oo | $Oj | $OS | # |_________|__kpDIV__|__kpMUL__|__kpSUB__| # | 7 8 9 | + | # | $Ow | $Ox | $Oy | $Ok | # |_ka1__K1_|_________|_ka3__K3_| kpADD | # | 4 | 5 | 6 | | # | $Ot | $Ou | $Ov | | # |_________|_kb2__K2_|_________|_________| # | 1 | 2 | 3 | | # | $Oq | $Or | $Os | | # |_kc1__K4_|_________|_kc3__K5_| enter | # | 0 | . | $OM | # | $Op | $On | | # |_______kpZRO_______|__kpDOT__|_kent_@8_| # # ka2, kb1, kb3 and kc2 are extensions, as are the mixed-case names. # There are no termcap equivalents for these extensions. # # kpCMA (comma) is used here for the VT100 keypad, which xterm emulates with # shifted-keypad-plus, though normally that invokes a font-size change. # # Old versions of xterm, e.g., xterm-xfree86, documented \EOE as kb2, which # does not fit into this layout. The extension kp5 fits, but is not visible # to termcap applications. As an alternative, kbeg (which does have a termcap # equivalent) is provided. xterm+keypad|xterm emulating VT100/VT220 numeric keypad, kbeg=\EOE, kp5=\EOE, kpADD=\EOk, kpCMA=\EOl, kpDIV=\EOo, kpDOT=\EOn, kpMUL=\EOj, kpSUB=\EOm, kpZRO=\EOp, use=vt220+keypad, # from development after ncurses 5.2: # A better adaptation to modern keyboards such as the PC's, which have a dozen # function keys and the keypad 2,4,6,8 keys are labeled with arrows keys, is to # use the 5-key arrangement to model the arrow keys as suggested in the # terminfo guidelines: # _______________________________________ # | PF1 | PF2 | PF3 | PF4 | # | $OP | $OQ | $OR | $OS | # |_kf1__k1_|_kf2__k2_|_kf3__k3_|_kf4__k4_| # | 7 8 9 - | # | $Ow | $Ox | $Oy | $Om | # |_ka1__K1_|_________|_ka3__K3_|_________| # | 4 | 5 | 6 | , | # | $Ot | $Ou | $Ov | $Ol | # |_________|_kb2__K2_|_________|_________| # | 1 | 2 | 3 | | # | $Oq | $Or | $Os | enter | # |_kc1__K4_|_________|_kc3__K5_| $OM | # | 0 | . | | # | $Op | $On | | # |___________________|_________|_kent_@8_| vt220+keypad|dec vt220 numeric keypad, ka1=\EOw, ka3=\EOy, kb2=\EOu, kc1=\EOq, kc3=\EOs, kent=\EOM, kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS, ka2=\EOx, kb1=\EOt, kb3=\EOv, kc2=\EOr, # # This should work for the commonly used "color xterm" variations (XFree86 # xterm, color_xterm, nxterm, rxvt). Note that it does not set 'bce', so for # XFree86 and and rxvt, some applications that use colors will be less # efficient, and in a few special cases (with "smart" optimization) the wrong # color will be painted in spots. xterm-color|generic "ANSI" color xterm (X Window System), colors#8, ncv@, pairs#64, op=\E[m, setab=\E[4%p1%dm, setaf=\E[3%p1%dm, use=xterm-r6, # # vi may work better with this entry, because vi # doesn't use insert mode much xterm-ic|xterm-vi|xterm with insert character instead of insert mode, mir@, ich=\E[%p1%d@, ich1=\E[@, rmir@, smir@, use=xterm, # # This is used only for testing (it's not relevant to DEC VTxxx terminals, but # to ncurses). xterm-xmc|xterm with magic-cookie glitch, xmc#1, use=xterm-new, # # This one was originally for testing ncurses. While the ISO 6429 defines the # REP control, none of the DEC VTxxx terminals (VT52 through VT525) support it. # # The feature's inclusion in xterm was prompted by changes in ncurses to # support testing repeat_char by Alexander Lukyanov, since no readily-available # terminal supported this: # # + Alexander's patch was integrated in ncurses 1996/09/28 # + xterm patch #32 1996/11/21 was released in XFree86 3.2A 1997/01/26 # # In July 2017, the feature was added to xterm-new in ncurses, making this # entry obsolete (but it is kept for reference). xterm-rep|xterm with repeat-character control, rep=%p1%c\E[%p2%{1}%-%db, use=xterm-new, # # This is mainly for testing xterm; the real VT220 will not let you switch # character sets without first altering the keyboard language in the setup # screen. Some emulators allow this anyway. (Note that these strings are # normally used only for printers). The parameter to csnm and scs is the same # in both cases: the keyboard language parameter returned by CSI ? 2 6 n. xterm-nrc|xterm with VT220 national replacement character sets, csnm= %? %p1%{1}%= %tNorth\sAmerican %e %p1%{2}%= %tBritish %e %p1%{3}%= %tFlemish %e %p1%{4}%= %tFrench\sCanadian %e %p1%{5}%= %tDanish %e %p1%{6}%= %tFinnish %e %p1%{7}%= %tGerman %e %p1%{8}%= %tDutch %e %p1%{9}%= %tItalian %e %p1%{10}%= %tSwiss\s(French) %e %p1%{11}%= %tSwiss\s(German) %e %p1%{12}%= %tSwedish %e %p1%{13}%= %tNorwegian %e %p1%{14}%= %tFrench/Belgian %e %p1%{15}%= %tSpanish %;, scs= %? %p1%{1}%= %t\E(B %e %p1%{2}%= %t\E(A %e %p1%{3}%= %t\E(R %e %p1%{4}%= %t\E(9 %e %p1%{5}%= %t\E(E %e %p1%{6}%= %t\E(5 %e %p1%{7}%= %t\E(K %e %p1%{8}%= %t\E(4 %e %p1%{9}%= %t\E(Y %e %p1%{10}%= %t\E(= %e %p1%{11}%= %t\E(= %e %p1%{12}%= %t\E(7 %e %p1%{13}%= %t\E(E %e %p1%{14}%= %t\E(R %e %p1%{15}%= %t\E(Z %;, use=xterm-new, # # Foreground 0-15 maps (with toggles) into 30-37 & 90-97 # Background 0-15 maps (with toggles) into 40-47 & 100-107 # # Originally I suppressed setaf/setab, since ANSI specifies only 8 colors, but # Stephen Marley persuaded me to allow the "ANSI" color controls to extend to # 16 colors. (Note that ncurses 4.2 uses setf/setb from this description; # however 5.0 selects either according to their availability). - T.Dickey # # SVr4 curses does not use more than 8 colors anyway, so using 16 colors is # either for terminfo-level applications or via ncurses. xterm-16color|xterm with 16 colors, colors#16, pairs#0x100, setab=\E[ %? %p1%{8}%< %t %p1%{40}%+ %e %p1%{92}%+ %; %dm, setaf=\E[ %? %p1%{8}%< %t %p1%{30}%+ %e %p1%{82}%+ %; %dm, setb= %p1%{8}%/%{6}%*%{4}%+\E[%d %p1%{8}%m%Pa %?%ga%{1}%= %t4 %e%ga%{3}%= %t6 %e%ga%{4}%= %t1 %e%ga%{6}%= %t3 %e%ga%d %; m, setf= %p1%{8}%/%{6}%*%{3}%+\E[%d %p1%{8}%m%Pa %?%ga%{1}%= %t4 %e%ga%{3}%= %t6 %e%ga%{4}%= %t1 %e%ga%{6}%= %t3 %e%ga%d %; m, use=xterm+256color2, use=xterm+osc104, use=xterm-new, # xterm OSC 104 resets the color palette. Using it as part of xterm+256color # has the drawback that some of the xterm-alikes which use that building block # require a different approach to rs1 -TD xterm+osc104|reset color palette, oc=\E]104\007, rs1=\Ec\E]104\007, # "indexed color" is mentioned without definition in ISO 8613-6 (ITU T.416). # # This implementation uses a 256-element color map where the first 16 entries # are shared with the aixterm-compatible colors (and in turn the first 8 are # shared with the ANSI colors). The three levels (256, 16, 8) account for the # use of a conditional expression in setaf/setab which reduces the number of # characters sent to the screen for typical applications. # # 256 colors should give 65536 pairs, but SVr4 (legacy) terminfo stores numbers # in a signed short. Most people will not notice problems with only 32767 # pairs. With ncurses 6.1, numbers are stored in a signed integer (at least # 32-bits), and the inconsistency regarding pairs is eliminated. xterm+256color|original xterm 256-color feature, ccc, colors#0x100, pairs#0x10000, initc=\E]4; %p1%d;rgb: %p2%{255}%*%{1000}%/%2.2X/ %p3%{255}%*%{1000}%/%2.2X/ %p4%{255}%*%{1000}%/%2.2X\E\\, oc=\E]104\007, setab=\E[ %? %p1%{8}%< %t4 %p1%d %e %p1%{16}%< %t10 %p1%{8}%-%d %e48;5; %p1%d %; m, setaf=\E[ %? %p1%{8}%< %t3 %p1%d %e %p1%{16}%< %t9 %p1%{8}%-%d %e38;5; %p1%d %; m, setb@, setf@, xterm+256color2|xterm 256-color feature, setab=\E[ %? %p1%{8}%< %t4 %p1%d %e %p1%{16}%< %t10 %p1%{8}%-%d %e48:5: %p1%d %; m, setaf=\E[ %? %p1%{8}%< %t3 %p1%d %e %p1%{16}%< %t9 %p1%{8}%-%d %e38:5: %p1%d %; m, use=xterm+256color, xterm-256color|xterm with 256 colors, use=xterm+256color, use=xterm+osc104, use=xterm-new, xterm-88color|xterm with 88 colors, colors#88, pairs#7744, use=xterm-256color, # "direct color" is mentioned without definition in ISO 8613-6 (ITU T.416). # # This is a particular implementation which assume 8-bit values for red, green, # and blue. Other encodings are possible; none are addressed by that standard. # # The "RGB" flag is an ncurses 6.1 extension which tells the library how to # quickly compute the color-content for a given color value. # # Like xterm+256color, this uses a conditional expression. But it does that # for a different reason: to make it readily usable for applications which # print text but also use RGB colors, it uses a color map for the usual ANSI # colors (0-7) and RGB colors for the remaining range of the color value. xterm+direct|xterm with direct-color indexing, RGB, colors#0x1000000, pairs#0x10000, CO#8, initc@, op=\E[39;49m, setab=\E[ %? %p1%{8}%< %t4 %p1%d %e48:2:: %p1%{65536}%/%d: %p1%{256}%/%{255}%&%d: %p1%{255}%&%d %; m, setaf=\E[ %? %p1%{8}%< %t3 %p1%d %e38:2:: %p1%{65536}%/%d: %p1%{256}%/%{255}%&%d: %p1%{255}%&%d %; m, setb@, setf@, xterm-direct|xterm with direct-color indexing, use=xterm+direct, use=xterm, # # This is an 8-bit version of xterm, which emulates DEC vt220 with ANSI color. # To use it, your decTerminalID resource must be set to 200 or above, and the # sunKeyboard resource set to true. # # HTS \E H \210 # RI \E M \215 # SS3 \E O \217 # CSI \E [ \233 # xterm-8bit|xterm terminal emulator with 8-bit controls (X Window System), OTbs, am, bce, km, mc5i, mir, msgr, npc, xenl, AX, colors#8, cols#80, it#8, lines#24, pairs#64, bel=^G, blink=\2335m, bold=\2331m, cbt=\233Z, civis=\233?25l, clear=\233H\2332J, cnorm=\233?25l\233?25h, cr=\r, csr=\233%i%p1%d;%p2%dr, cub=\233%p1%dD, cub1=^H, cud=\233%p1%dB, cud1=\n, cuf=\233%p1%dC, cuf1=\233C, cup=\233%i%p1%d;%p2%dH, cuu=\233%p1%dA, cuu1=\233A, cvvis=\233?12;25h, dch=\233%p1%dP, dch1=\233P, dl=\233%p1%dM, dl1=\233M, ech=\233%p1%dX, ed=\233J, el=\233K, el1=\2331K, flash=\233?5h$<100/>\233?5l, home=\233H, hpa=\233%i%p1%dG, ht=^I, hts=\210, ich=\233%p1%d@, il=\233%p1%dL, il1=\233L, ind=\n, invis=\2338m, is2=\E[62"p\E\sG\233m\233?7h\E> \E7\233?1;3;4;6l\2334l\233r \E8, ka1=\217w, ka3=\217u, kb2=\217y, kbeg=\217E, kc1=\217q, kc3=\217s, kcbt=\233Z, kcub1=\217D, kcud1=\217B, kcuf1=\217C, kcuu1=\217A, kdch1=\2333~, kend=\2334~, kent=\217M, kf1=\23311~, kf10=\23321~, kf11=\23323~, kf12=\23324~, kf13=\23325~, kf14=\23326~, kf15=\23328~, kf16=\23329~, kf17=\23331~, kf18=\23332~, kf19=\23333~, kf2=\23312~, kf20=\23334~, kf3=\23313~, kf4=\23314~, kf5=\23315~, kf6=\23317~, kf7=\23318~, kf8=\23319~, kf9=\23320~, khome=\2331~, kich1=\2332~, kmous=\233M, knp=\2336~, kpp=\2335~, mc0=\233i, mc4=\2334i, mc5=\2335i, meml=\El, memu=\Em, op=\23339;49m, rc=\E8, rev=\2337m, ri=\215, rmam=\233?7l, rmcup=\233?1049l, rmir=\2334l, rmkx=\233?1l\E>, rmso=\23327m, rmul=\23324m, rs1=\Ec, rs2=\E[62"p\E\sG\233m\233?7h\E> \E7\233?1;3;4;6l\2334l\233r \E8, sc=\E7, setab=\2334%p1%dm, setaf=\2333%p1%dm, setb=\2334 %? %p1%{1}%= %t4 %e %p1%{3}%= %t6 %e %p1%{4}%= %t1 %e %p1%{6}%= %t3 %e %p1%d %; m, setf=\2333 %? %p1%{1}%= %t4 %e %p1%{3}%= %t6 %e %p1%{4}%= %t1 %e %p1%{6}%= %t3 %e %p1%d %; m, sgr=\2330 %? %p6 %t;1 %; %? %p2 %t;4 %; %? %p1 %p3%| %t;7 %; %? %p4 %t;5 %; %? %p7 %t;8 %; m %? %p9 %t\E(0 %e \E(B %;, sgr0=\2330m\E(B, smam=\233?7h, smcup=\233?1049h, smir=\2334h, smkx=\233?1h\E=, smso=\2337m, smul=\2334m, tbc=\2333g, u6=\233[%i%d;%dR, u7=\E[6n, u8=\233[?%[;0123456789]c, u9=\E[c, vpa=\233%i%p1%dd, use=xterm+acs, use=xterm+kbs, # xterm-xf86-v44|xterm terminal emulator (XFree86 4.4 Window System), OTbs, am, bce, km, mir, msgr, npc, xenl, AX, XT, colors#8, cols#80, lines#24, pairs#64, acsc=``aaffggiijjkkllmmnnooppqqr rssttuuvvwwxxyyzz{{||}}~~, bel=^G, civis=\E[?25l, clear=\E[H\E[2J, cnorm=\E[?12l\E[?25h, cr=\r, cub1=^H, cud1=\n, cvvis=\E[?12;25h, dch=\E[%p1%dP, dch1=\E[P, ech=\E[%p1%dX, ed=\E[J, el=\E[K, el1=\E[1K, enacs=\E(B\E)0, flash=\E[?5h$<100/>\E[?5l, hpa=\E[%i%p1%dG, ich=\E[%p1%d@, ind=\n, indn=\E[%p1%dS, is2=\E[!p\E[?3;4l\E[4l\E>, kDC=\E[3;2~, kEND=\E[1;2F, kHOM=\E[1;2H, kIC=\E[2;2~, kLFT=\E[1;2D, kNXT=\E[6;2~, kPRV=\E[5;2~, kRIT=\E[1;2C, kb2=\EOE, kcbt=\E[Z, kdch1=\E[3~, kend=\EOF, kent=\EOM, kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\EO2P, kf14=\EO2Q, kf15=\EO2R, kf16=\EO2S, kf17=\E[15;2~, kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~, kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~, kf25=\EO5P, kf26=\EO5Q, kf27=\EO5R, kf28=\EO5S, kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, kf31=\E[18;5~, kf32=\E[19;5~, kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~, kf36=\E[24;5~, kf37=\EO6P, kf38=\EO6Q, kf39=\EO6R, kf4=\EOS, kf40=\EO6S, kf41=\E[15;6~, kf42=\E[17;6~, kf43=\E[18;6~, kf44=\E[19;6~, kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~, kf48=\E[24;6~, kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~, meml=\El, memu=\Em, op=\E[39;49m, ri=\EM, rin=\E[%p1%dT, rmacs=^O, rmam=\E[?7l, rmir=\E[4l, rmkx=\E[?1l\E>, rmso=\E[27m, rmul=\E[24m, rs1=\Ec, rs2=\E[!p\E[?3;4l\E[4l\E>, setab=\E[4%p1%dm, setaf=\E[3%p1%dm, setb=\E[4 %? %p1%{1}%= %t4 %e %p1%{3}%= %t6 %e %p1%{4}%= %t1 %e %p1%{6}%= %t3 %e %p1%d %; m, setf=\E[3 %? %p1%{1}%= %t4 %e %p1%{3}%= %t6 %e %p1%{4}%= %t1 %e %p1%{6}%= %t3 %e %p1%d %; m, sgr=\E[0 %? %p6 %t;1 %; %? %p2 %t;4 %; %? %p1 %p3%| %t;7 %; %? %p4 %t;5 %; %? %p7 %t;8 %; m %? %p9 %t\016 %e \017 %;, sgr0=\E[m\017, smacs=^N, smam=\E[?7h, smir=\E[4h, smkx=\E[?1h\E=, u8=\E[?1;2c, vpa=\E[%i%p1%dd, ka2=\EOx, kb1=\EOt, kb3=\EOv, kc2=\EOr, use=xterm+kbs, use=ansi+apparrows, use=ansi+csr, use=ansi+cup, use=ansi+enq, use=ansi+idl, use=ansi+inittabs, use=ansi+local, use=ansi+pp, use=ansi+sgrbold, use=xterm+alt1049, xterm-xfree86|xterm terminal emulator (XFree86 4.4 Window System), use=xterm-xf86-v44, # # Compatible with the R6 xterm, with the following changes: # + added acsc (perhaps some versions of tic assume the standard vt100 # alternate character set) # + added u6, u7, u8, u9 strings for Daniel Weaver's tack program. # + added kmous string for ncurses. # + added khome/kend strings (which conflict with kfnd/kslt, see note). xterm-r6|xterm X11R6 version, OTbs, am, km, mir, msgr, xenl, cols#80, it#8, lines#24, acsc=``aaffggiijjkkllmmnnooppqqr rssttuuvvwwxxyyzz{{||}}~~, bel=^G, bold=\E[1m, clear=\E[H\E[2J, cr=\r, cub=\E[%p1%dD, cub1=^H, cud=\E[%p1%dB, cud1=\n, cuf=\E[%p1%dC, cuf1=\E[C, cuu=\E[%p1%dA, cuu1=\E[A, dch=\E[%p1%dP, dch1=\E[P, dl=\E[%p1%dM, dl1=\E[M, enacs=\E)0, ht=^I, hts=\EH, il=\E[%p1%dL, il1=\E[L, ind=\n, is2=\E[m\E[?7h\E[4l\E>\E7\E[r\E[ ?1;3;4;6l\E8, kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA, kf1=\E[11~, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, kf15=\E[28~, kf16=\E[29~, kf17=\E[31~, kf18=\E[32~, kf19=\E[33~, kf2=\E[12~, kf20=\E[34~, kf3=\E[13~, kf4=\E[14~, kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, kmous=\E[M, meml=\El, memu=\Em, rev=\E[7m, ri=\EM, rmacs=^O, rmcup=\E[2J\E[?47l\E8, rmir=\E[4l, rmkx=\E[?1l\E>, rmso=\E[m, rmul=\E[m, rs2=\E[m\E[?7h\E[4l\E>\E7\E[r\E[ ?1;3;4;6l\E8, sgr0=\E[m, smacs=^N, smcup=\E7\E[?47h, smir=\E[4h, smkx=\E[?1h\E=, smso=\E[7m, smul=\E[4m, tbc=\E[3g, u8=\E[?1;2c, u9=\E[c, use=ansi+cpr, use=ansi+csr, use=ansi+cup, use=ansi+erase, use=xterm+kbs, use=xterm+decedit, xterm-old|antique xterm version, use=xterm-r6, # # Compatible with the R5 xterm, with the following changes: # + changed 'blink=@', to 'blink@' (the former meant that "@" would start # a blink, the latter that it is not supported). # + changed kf1 through kf4 to correspond with actual usage. Though X # supports keypad symbols for PF1 to PF4, and xterm interprets these # correctly, the F1 to F4 codes are commonly (but incorrectly) used. # + moved reset string from rs1 to rs2, to correlate better with termcap. # + make khome consistent with other entries. # + use rmul/smul, rmir/smir from termcap, but not rmcup/smcup because # not everyone wants the alternate screen. # + added u6, u7, u8, u9 strings for Daniel Weaver's tack program. # + added kmous string for ncurses. xterm-r5|xterm R5 version, OTbs, am, km, msgr, xenl, cols#80, it#8, lines#24, bel=^G, bold=\E[1m, clear=\E[H\E[2J, cr=\r, cub1=^H, cud1=\n, cup=\E[%i%p1%d;%p2%dH, ed=\E[J, el=\E[K, home=\E[H, ht=^I, hts=\EH, ind=\n, kdch1=\E[3~, kdl1=\E[31~, kel=\E[8~, kend=\E[4~, kf0=\EOq, kf1=\E[11~, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf2=\E[12~, kf3=\E[13~, kf4=\E[14~, kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, khome=\E[1~, kich1=\E[2~, kil1=\E[30~, kmous=\E[M, knp=\E[6~, kpp=\E[5~, rev=\E[7m, ri=\EM, rmkx=\E[?1l\E>, rmul=\E[m, rs2=\E>\E[?1;3;4;5;6l\E[4l\E[?7h \E[m\E[r\E[2J\E[H, sgr=\E[ %? %p1 %t;7 %; %? %p2 %t;4 %; %? %p3 %t;7 %; %? %p4 %t;5 %; %? %p6 %t;1 %; m, sgr0=\E[m, smkx=\E[?1h\E=, smul=\E[4m, tbc=\E[3g, u8=\E[?1;2c, use=xterm+kbs, use=ansi+apparrows, use=ansi+csr, use=ansi+enq, use=ansi+idc, use=ansi+idl, use=ansi+local, use=ansi+sgrso, # DEC status-line is an extension for VT220, and standard with VT320 and up. dec+sl|DEC VTxx status line, eslok, hs, dsl=\E[0$~, fsl=\E[0$}, tsl=\E[2$~\E[1$}\E[%i%p1%d`, # # # Customization begins here. # # This is the only entry which you should have to customize, since "xterm" # is widely used for a variety of incompatible terminal emulations including # color_xterm and rxvt. xterm|X11 terminal emulator, use=xterm-new, # use=xterm-r6, # This fragment is for people who cannot agree on what the backspace key # should send. xterm+kbs|fragment for backspace key, kbs=^H, # kbs=^?, xterm-399/charsets.h0000644000000000000000000036333514775323076013255 0ustar rootroot/* * $XTermId: charsets.h,v 1.36 2025/04/08 22:42:06 tom Exp $ */ /* * Copyright 2023-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #ifndef included_charsets_h #define included_charsets_h 1 /* * According to * Digital ANSI-Compliant Printing Protocol * Level 2 Programming Reference Manual * EK-PPLV2-PM. B01 * * the supplementary character sets Greek, Hebrew, Latin-5 and Latin/Cyrillic * are standardized by ISO: * ISO Greek is 8859-7 * ISO Hebrew is 8859-8 * ISO Latin-5 is 8859-9 * ISO Latin/Cyrillic is 8859-5 * * These are derived from the data at * ftp://www.unicode.org/Public/MAPPINGS/ISO8859/ * * Note: the "figure A-xx" comments refer to EK-PPLV2-PM. */ #ifndef PUA #define PUA(n) (0xEEEE + (n)) #endif #define UNDEF 0x2426 /* rendered as a backwards "?" */ /* * A "codepage" is treated different from the NRC mode: it is always enabled. * Reuse the UNI() macros by temporarily setting its state. */ #if OPT_WIDE_CHARS #define begin_CODEPAGE(size) \ if (!(xw->flags & NATIONAL)) { \ screen->utf8_nrc_mode++; \ } #define end_CODEPAGE() \ if (!(xw->flags & NATIONAL)) { \ screen->utf8_nrc_mode--; \ } #else #define begin_CODEPAGE(size) /* nothing */ #define end_CODEPAGE() /* nothing */ #endif /* * xterm's original implementation of NRCS in 1998 was before Unicode became * prevalent. Most of the necessary mappings could be done using definitions * from X11/keysymdef.h, using ISO-8859-1 as the default. */ #define map_ASCII(code) \ switch (code) { \ XXX(0xA0, UNDEF) \ XXX(0xFF, UNDEF) \ } #define unmap_ASCII(code,dft) \ switch (code) { \ MAP(0xA0, 0x1B) \ MAP(0xFF, 0x10000) \ default: dft; break; \ } #define map_DEC_Spec_Graphic_VT52(code) \ begin_CODEPAGE(94) \ switch (code) { \ XXX(0x5F, UNDEF) \ UNI(0x60, 0x0020) /* nbsp, treat as blank */ \ UNI(0x61, 0x0020) /* reserved, treat as blank */ \ UNI(0x62, 0x25AE) /* black vertical rectangle */ \ UNI(0x63, 0x215F) /* "1/" */ \ UNI(0x64, 0x0020) /* "3/", not in Unicode, ignore */ \ UNI(0x65, 0x0020) /* "5/", not in Unicode, ignore */ \ UNI(0x66, 0x0020) /* "7/", not in Unicode, ignore */ \ UNI(0x67, 0x00B0) /* degree sign */ \ UNI(0x68, 0x00B1) /* plus-minus sign */ \ UNI(0x69, 0x2192) /* right-arrow */ \ UNI(0x6A, 0x2026) /* ellipsis */ \ UNI(0x6B, 0x00F7) /* divide by */ \ UNI(0x6C, 0x2193) /* down arrow */ \ UNI(0x6D, 0x23BA) /* bar at scan 0 */ \ UNI(0x6E, 0x23BA) /* bar at scan 1 */ \ UNI(0x6F, 0x23BB) /* bar at scan 2 */ \ UNI(0x70, 0x23BB) /* bar at scan 3 */ \ UNI(0x71, 0x23BC) /* bar at scan 4 */ \ UNI(0x72, 0x23BC) /* bar at scan 5 */ \ UNI(0x73, 0x23BD) /* bar at scan 6 */ \ UNI(0x74, 0x23BD) /* bar at scan 7 */ \ UNI(0x75, 0x2080) /* subscript 0 */ \ UNI(0x76, 0x2081) /* subscript 1 */ \ UNI(0x77, 0x2082) /* subscript 2 */ \ UNI(0x78, 0x2083) /* subscript 3 */ \ UNI(0x79, 0x2084) /* subscript 4 */ \ UNI(0x7A, 0x2085) /* subscript 5 */ \ UNI(0x7B, 0x2086) /* subscript 6 */ \ UNI(0x7C, 0x2087) /* subscript 7 */ \ UNI(0x7D, 0x2088) /* subscript 8 */ \ UNI(0x7E, 0x2089) /* subscript 9 */ \ } \ end_CODEPAGE() #define unmap_DEC_Spec_Graphic_VT52(code,dft) \ switch (code) { \ MAP(0x5F, 0x10000) \ MAP(0x60, 0x14) /* nbsp, treat as blank */ \ MAP(0x61, 0x78) /* reserved, treat as blank */ \ MAP(0x62, 0x0A) /* black vertical rectangle */ \ MAP(0x63, 0x0D) /* "1/" */ \ MAP(0x64, 0x0E) /* "3/", not in Unicode, ignore */ \ MAP(0x65, 0x0B) /* "5/", not in Unicode, ignore */ \ MAP(0x66, 0xB0) /* "7/", not in Unicode, ignore */ \ MAP(0x67, 0xB1) /* degree sign */ \ MAP(0x68, 0x15) /* plus-minus sign */ \ MAP(0x69, 0x0C) /* right-arrow */ \ MAP(0x6A, 0x16) /* ellipsis */ \ MAP(0x6B, 0x17) /* divide by */ \ MAP(0x6C, 0x18) /* down arrow */ \ MAP(0x6D, 0x19) /* bar at scan 0 */ \ MAP(0x6E, 0x1A) /* bar at scan 1 */ \ MAP(0x6F, 0x1B) /* bar at scan 2 */ \ MAP(0x70, 0x1C) /* bar at scan 3 */ \ MAP(0x71, 0x1D) /* bar at scan 4 */ \ MAP(0x72, 0x1E) /* bar at scan 5 */ \ MAP(0x73, 0x1F) /* bar at scan 6 */ \ MAP(0x74, 0x80) /* bar at scan 7 */ \ MAP(0x75, 0x81) /* subscript 0 */ \ MAP(0x76, 0x82) /* subscript 1 */ \ MAP(0x77, 0x83) /* subscript 2 */ \ MAP(0x78, 0x84) /* subscript 3 */ \ MAP(0x79, 0x85) /* subscript 4 */ \ MAP(0x7A, 0x86) /* subscript 5 */ \ MAP(0x7B, 0xC6) /* subscript 6 */ \ MAP(0x7C, 0x87) /* subscript 7 */ \ MAP(0x7D, 0xA3) /* subscript 8 */ \ MAP(0x7E, 0xB7) /* subscript 9 */ \ default: dft; break; \ } #define map_DEC_Spec_Graphic(code) \ begin_CODEPAGE(94) \ switch (code) { \ XXX(0x5F, UNDEF) \ UNI(0x60, 0x25c6) /* black diamond */ \ UNI(0x61, 0x2592) /* medium shade */ \ UNI(0x62, 0x2409) /* symbol for horizontal tabulation */ \ UNI(0x63, 0x240C) /* symbol for form feed */ \ UNI(0x64, 0x240D) /* symbol for carriage return */ \ UNI(0x65, 0x240A) /* symbol for line feed */ \ UNI(0x66, 0x00B0) /* degree sign */ \ UNI(0x67, 0x00B1) /* plus-minus sign */ \ UNI(0x68, 0x2424) /* symbol for newline */ \ UNI(0x69, 0x240B) /* symbol for vertical tabulation */ \ UNI(0x6A, 0x2518) /* box drawings light up and left */ \ UNI(0x6B, 0x2510) /* box drawings light down and left */ \ UNI(0x6C, 0x250C) /* box drawings light down and right */ \ UNI(0x6D, 0x2514) /* box drawings light up and right */ \ UNI(0x6E, 0x253C) /* box drawings light vertical and horizontal */ \ UNI(0x6F, 0x23BA) /* box drawings scan 1 */ \ UNI(0x70, 0x23BB) /* box drawings scan 3 */ \ UNI(0x71, 0x2500) /* box drawings light horizontal */ \ UNI(0x72, 0x23BC) /* box drawings scan 7 */ \ UNI(0x73, 0x23BD) /* box drawings scan 9 */ \ UNI(0x74, 0x251C) /* box drawings light vertical and right */ \ UNI(0x75, 0x2524) /* box drawings light vertical and left */ \ UNI(0x76, 0x2534) /* box drawings light up and horizontal */ \ UNI(0x77, 0x252C) /* box drawings light down and horizontal */ \ UNI(0x78, 0x2502) /* box drawings light vertical */ \ UNI(0x79, 0x2264) /* less-than or equal to */ \ UNI(0x7A, 0x2265) /* greater-than or equal to */ \ UNI(0x7B, 0x03C0) /* greek small letter pi */ \ UNI(0x7C, 0x2260) /* not equal to */ \ UNI(0x7D, 0x00A3) /* pound sign */ \ UNI(0x7E, 0x00B7) /* middle dot */ \ } \ end_CODEPAGE() #define unmap_DEC_Spec_Graphic(code,dft) \ switch (code) { \ MAP(0x5F, 0x10000) \ MAP(0x60, 0x14) /* black diamond */ \ MAP(0x61, 0x78) /* medium shade */ \ MAP(0x62, 0x0A) /* symbol for horizontal tabulation */ \ MAP(0x63, 0x0D) /* symbol for form feed */ \ MAP(0x64, 0x0E) /* symbol for carriage return */ \ MAP(0x65, 0x0B) /* symbol for line feed */ \ MAP(0x66, 0xB0) /* degree sign */ \ MAP(0x67, 0xB1) /* plus-minus sign */ \ MAP(0x68, 0x15) /* symbol for newline */ \ MAP(0x69, 0x0C) /* symbol for vertical tabulation */ \ MAP(0x6A, 0x16) /* box drawings light up and left */ \ MAP(0x6B, 0x17) /* box drawings light down and left */ \ MAP(0x6C, 0x18) /* box drawings light down and right */ \ MAP(0x6D, 0x19) /* box drawings light up and right */ \ MAP(0x6E, 0x1A) /* box drawings light vertical and horizontal */ \ MAP(0x6F, 0x1B) /* box drawings scan 1 */ \ MAP(0x70, 0x1C) /* box drawings scan 3 */ \ MAP(0x71, 0x1D) /* box drawings light horizontal */ \ MAP(0x72, 0x1E) /* box drawings scan 7 */ \ MAP(0x73, 0x1F) /* box drawings scan 9 */ \ MAP(0x74, 0x80) /* box drawings light vertical and right */ \ MAP(0x75, 0x81) /* box drawings light vertical and left */ \ MAP(0x76, 0x82) /* box drawings light up and horizontal */ \ MAP(0x77, 0x83) /* box drawings light down and horizontal */ \ MAP(0x78, 0x84) /* box drawings light vertical */ \ MAP(0x79, 0x85) /* less-than or equal to */ \ MAP(0x7A, 0x86) /* greater-than or equal to */ \ MAP(0x7B, 0xC6) /* greek small letter pi */ \ MAP(0x7C, 0x87) /* not equal to */ \ MAP(0x7D, 0xA3) /* pound sign */ \ MAP(0x7E, 0xB7) /* middle dot */ \ default: dft; break; \ } #define map_ISO_Latin_1(code) \ begin_CODEPAGE(96) \ switch (code) { \ } \ end_CODEPAGE() #define unmap_ISO_Latin_1(code,dft) /* nothing */ #define map_NRCS_Dutch(code) \ switch (code) { \ MAP(0x23, XK_sterling) /* U+00A3 POUND SIGN */ \ MAP(0x40, XK_threequarters) /* U+00BE VULGAR FRACTION THREE QUARTERS */ \ UNI(0x5B, 0x0133) /* LATIN SMALL LIGATURE IJ */ \ MAP(0x5C, XK_onehalf) /* U+00BD VULGAR FRACTION ONE HALF */ \ MAP(0x5D, XK_bar) /* U+007C VERTICAL LINE */ \ MAP(0x7B, XK_diaeresis) /* U+00A8 DIAERESIS */ \ UNI(0x7C, 0x0192) /* LATIN SMALL LETTER F WITH HOOK (florin) */ \ MAP(0x7D, XK_onequarter) /* U+00BC VULGAR FRACTION ONE QUARTER */ \ MAP(0x7E, XK_acute) /* U+00B4 ACUTE ACCENT */ \ } #define unmap_NRCS_Dutch(code,dft) /* nothing */ #define map_NRCS_Finnish(code) \ switch (code) { \ MAP(0x5B, XK_Adiaeresis) /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ \ MAP(0x5C, XK_Odiaeresis) /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ \ MAP(0x5D, XK_Aring) /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ \ MAP(0x5E, XK_Udiaeresis) /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ \ MAP(0x60, XK_eacute) /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ \ MAP(0x7B, XK_adiaeresis) /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ \ MAP(0x7C, XK_odiaeresis) /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ \ MAP(0x7D, XK_aring) /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ \ MAP(0x7E, XK_udiaeresis) /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ \ } #define unmap_NRCS_Finnish(code,dft) /* nothing */ #define map_NRCS_French(code) \ switch (code) { \ MAP(0x23, XK_sterling) /* U+00A3 POUND SIGN */ \ MAP(0x40, XK_agrave) /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ \ MAP(0x5B, XK_degree) /* U+00B0 DEGREE SIGN */ \ MAP(0x5C, XK_ccedilla) /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ \ MAP(0x5D, XK_section) /* U+00A7 SECTION SIGN */ \ MAP(0x7B, XK_eacute) /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ \ MAP(0x7C, XK_ugrave) /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ \ MAP(0x7D, XK_egrave) /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ \ MAP(0x7E, XK_diaeresis) /* U+00A8 DIAERESIS */ \ } #define unmap_NRCS_French(code,dft) /* nothing */ #define map_NRCS_French_Canadian(code) \ switch (code) { \ MAP(0x40, XK_agrave) /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ \ MAP(0x5B, XK_acircumflex) /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ \ MAP(0x5C, XK_ccedilla) /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ \ MAP(0x5D, XK_ecircumflex) /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ \ MAP(0x5E, XK_icircumflex) /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ \ MAP(0x60, XK_ocircumflex) /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ \ MAP(0x7B, XK_eacute) /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ \ MAP(0x7C, XK_ugrave) /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ \ MAP(0x7D, XK_egrave) /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ \ MAP(0x7E, XK_ucircumflex) /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ \ } #define unmap_NRCS_French_Canadian(code,dft) /* nothing */ #define map_NRCS_German(code) \ switch (code) { \ MAP(0x40, XK_section) /* U+00A7 SECTION SIGN */ \ MAP(0x5B, XK_Adiaeresis) /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ \ MAP(0x5C, XK_Odiaeresis) /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ \ MAP(0x5D, XK_Udiaeresis) /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ \ MAP(0x7B, XK_adiaeresis) /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ \ MAP(0x7C, XK_odiaeresis) /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ \ MAP(0x7D, XK_udiaeresis) /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ \ MAP(0x7E, XK_ssharp) /* U+00DF LATIN SMALL LETTER SHARP S */ \ } #define unmap_NRCS_German(code,dft) /* nothing */ #define map_NRCS_Italian(code) \ switch (code) { \ MAP(0x23, XK_sterling) /* U+00A3 POUND SIGN */ \ MAP(0x40, XK_section) /* U+00A7 SECTION SIGN */ \ MAP(0x5B, XK_degree) /* U+00B0 DEGREE SIGN */ \ MAP(0x5C, XK_ccedilla) /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ \ MAP(0x5D, XK_eacute) /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ \ MAP(0x60, XK_ugrave) /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ \ MAP(0x7B, XK_agrave) /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ \ MAP(0x7C, XK_ograve) /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ \ MAP(0x7D, XK_egrave) /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ \ MAP(0x7E, XK_igrave) /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ \ } #define unmap_NRCS_Italian(code,dft) /* nothing */ #define map_NRCS_Norwegian_Danish(code) \ switch (code) { \ MAP(0x40, XK_Adiaeresis) /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ \ MAP(0x5B, XK_AE) /* U+00C6 LATIN CAPITAL LETTER AE */ \ MAP(0x5C, XK_Ooblique) /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ \ MAP(0x5D, XK_Aring) /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ \ MAP(0x5E, XK_Udiaeresis) /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ \ MAP(0x60, XK_adiaeresis) /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ \ MAP(0x7B, XK_ae) /* U+00E6 LATIN SMALL LETTER AE */ \ MAP(0x7C, XK_oslash) /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ \ MAP(0x7D, XK_aring) /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ \ MAP(0x7E, XK_udiaeresis) /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ \ } #define unmap_NRCS_Norwegian_Danish(code,dft) /* nothing */ #define map_NRCS_Portuguese(code) \ switch (code) { \ MAP(0x5B, XK_Atilde) /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ \ MAP(0x5C, XK_Ccedilla) /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ \ MAP(0x5D, XK_Otilde) /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ \ MAP(0x7B, XK_atilde) /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ \ MAP(0x7C, XK_ccedilla) /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ \ MAP(0x7D, XK_otilde) /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ \ } #define unmap_NRCS_Portuguese(code,dft) /* nothing */ #define map_NRCS_Spanish(code) \ switch (code) { \ MAP(0x23, XK_sterling) /* U+00A3 POUND SIGN */ \ MAP(0x40, XK_section) /* U+00A7 SECTION SIGN */ \ MAP(0x5B, XK_exclamdown) /* U+00A1 INVERTED EXCLAMATION MARK */ \ MAP(0x5C, XK_Ntilde) /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ \ MAP(0x5D, XK_questiondown) /* U+00BF INVERTED QUESTION MARK */ \ MAP(0x7B, XK_degree) /* U+00B0 DEGREE SIGN */ \ MAP(0x7C, XK_ntilde) /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ \ MAP(0x7D, XK_ccedilla) /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ \ } #define unmap_NRCS_Spanish(code,dft) /* nothing */ #define map_NRCS_Swedish(code) \ switch (code) { \ MAP(0x40, XK_Eacute) \ MAP(0x5B, XK_Adiaeresis) /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ \ MAP(0x5C, XK_Odiaeresis) /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ \ MAP(0x5D, XK_Aring) /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ \ MAP(0x5E, XK_Udiaeresis) /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ \ MAP(0x60, XK_eacute) /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ \ MAP(0x7B, XK_adiaeresis) /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ \ MAP(0x7C, XK_odiaeresis) /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ \ MAP(0x7D, XK_aring) /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ \ MAP(0x7E, XK_udiaeresis) /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ \ } #define unmap_NRCS_Swedish(code,dft) /* nothing */ #define map_NRCS_Swiss(code) \ switch (code) { \ MAP(0x23, XK_ugrave) /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ \ MAP(0x40, XK_agrave) /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ \ MAP(0x5B, XK_eacute) /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ \ MAP(0x5C, XK_ccedilla) /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ \ MAP(0x5D, XK_ecircumflex) /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ \ MAP(0x5E, XK_icircumflex) /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ \ MAP(0x5F, XK_egrave) /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ \ MAP(0x60, XK_ocircumflex) /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ \ MAP(0x7B, XK_adiaeresis) /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ \ MAP(0x7C, XK_odiaeresis) /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ \ MAP(0x7D, XK_udiaeresis) /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ \ MAP(0x7E, XK_ucircumflex) /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ \ } #define unmap_NRCS_Swiss(code,dft) /* nothing */ /* * Unlike NRCS, which splices a few characters onto ISO-8859-1, the * supplementary character sets are complete, normally mapped to GR. Most of * these mappings rely upon glyphs not found in ISO-8859-1. We can display most * of those using Unicode, thereby supporting specialized applications that use * SCS with luit, subject to the limitation that select/paste will give * meaningless results in terms of the application which uses these mappings. * * Since the codepages introduced with VT320, etc, use 8-bit encodings, there is * no plausible argument to be made that these mappings "use" UTF-8, even though * there is a hidden step in the terminal emulator which relies upon UTF-8. */ #define map_DEC_Supp_Graphic(code,dft) \ begin_CODEPAGE(94) \ switch (code) { \ XXX(0x24, UNDEF) \ XXX(0x26, UNDEF) \ UNI(0x28, 0x00A4) /* CURRENCY SIGN */ \ XXX(0x2C, UNDEF) \ XXX(0x2D, UNDEF) \ XXX(0x2E, UNDEF) \ XXX(0x2F, UNDEF) \ XXX(0x34, UNDEF) \ XXX(0x38, UNDEF) \ XXX(0x3E, UNDEF) \ XXX(0x50, UNDEF) \ UNI(0x57, 0x0152) /* LATIN CAPITAL LIGATURE OE */ \ UNI(0x5D, 0x0178) /* LATIN CAPITAL LETTER Y WITH DIAERESIS */ \ XXX(0x5E, UNDEF) \ UNI(0x5F, 0x005F) \ XXX(0x70, UNDEF) \ UNI(0x77, 0x0153) /* LATIN SMALL LIGATURE OE */ \ UNI(0x7D, 0x00FF) /* LATIN SMALL LETTER Y WITH DIAERESIS */ \ XXX(0x7E, UNDEF) \ default: dft; break; \ } \ end_CODEPAGE() #define unmap_DEC_Supp_Graphic(code,dft) \ switch (code) { \ MAP(0x24, 0x1B) \ MAP(0x26, 0x1B) \ MAP(0x28, 0xA4) /* CURRENCY SIGN */ \ MAP(0x2C, 0x1B) \ MAP(0x2D, 0x1B) \ MAP(0x2E, 0x1B) \ MAP(0x2F, 0x1B) \ MAP(0x34, 0x1B) \ MAP(0x38, 0x1B) \ MAP(0x3E, 0x1B) \ MAP(0x50, 0x1B) \ MAP(0x57, 0x97) /* LATIN CAPITAL LIGATURE OE */ \ MAP(0x5D, 0x98) /* LATIN CAPITAL LETTER Y WITH DIAERESIS */ \ MAP(0x5E, 0x1B) \ MAP(0x5F, 0xDF) \ MAP(0x70, 0x1B) \ MAP(0x77, 0x99) /* LATIN SMALL LIGATURE OE */ \ MAP(0x7D, 0xFF) /* LATIN SMALL LETTER Y WITH DIAERESIS */ \ MAP(0x7E, 0x1B) \ default: dft; break; \ } #if OPT_WIDE_CHARS /* * derived from http://www.vt100.net/charsets/technical.html */ #define map_DEC_Technical(code) \ begin_CODEPAGE(94) \ switch (code) { \ UNI(0x21, 0x23B7) /* RADICAL SYMBOL BOTTOM Centred left to right, so that it joins up with 02/02 */ \ UNI(0x22, 0x250C) /* BOX DRAWINGS LIGHT DOWN AND RIGHT */ \ UNI(0x23, 0x2500) /* BOX DRAWINGS LIGHT HORIZONTAL */ \ UNI(0x24, 0x2320) /* TOP HALF INTEGRAL with the proviso that the stem is vertical, to join with 02/06 */ \ UNI(0x25, 0x2321) /* BOTTOM HALF INTEGRAL with the proviso above. */ \ UNI(0x26, 0x2502) /* BOX DRAWINGS LIGHT VERTICAL */ \ UNI(0x27, 0x23A1) /* LEFT SQUARE BRACKET UPPER CORNER Joins vertically to 02/06, 02/08. Doesn't join to its right. */ \ UNI(0x28, 0x23A3) /* LEFT SQUARE BRACKET LOWER CORNER Joins vertically to 02/06, 02/07. Doesn't join to its right. */ \ UNI(0x29, 0x23A4) /* RIGHT SQUARE BRACKET UPPER CORNER Joins vertically to 026, 02a. Doesn't join to its left. */ \ UNI(0x2A, 0x23A6) /* RIGHT SQUARE BRACKET LOWER CORNER Joins vertically to 026, 029. Doesn't join to its left. */ \ UNI(0x2B, 0x23A7) /* LEFT CURLY BRACKET UPPER HOOK Joins vertically to 026, 02c, 02/15. Doesn't join to its right. */ \ UNI(0x2C, 0x23A9) /* LEFT CURLY BRACKET LOWER HOOK Joins vertically to 026, 02b, 02/15. Doesn't join to its right. */ \ UNI(0x2D, 0x23AB) /* RIGHT CURLY BRACKET UPPER HOOK Joins vertically to 026, 02e, 03/00. Doesn't join to its left. */ \ UNI(0x2E, 0x23AD) /* RIGHT CURLY BRACKET LOWER HOOK Joins vertically to 026, 02d, 03/00. Doesn't join to its left. */ \ UNI(0x2F, 0x23A8) /* LEFT CURLY BRACKET MIDDLE PIECE Joins vertically to 026, 02b, 02c. */ \ UNI(0x30, 0x23AC) /* RIGHT CURLY BRACKET MIDDLE PIECE Joins vertically to 02/06, 02d, 02e. */ \ XXX(0x31, PUA(0)) /* Top Left Sigma. Joins to right with 02/03, 03/05. Joins diagonally below right with 03/03, 03/07. */ \ XXX(0x32, PUA(1)) /* Bottom Left Sigma. Joins to right with 02/03, 03/06. Joins diagonally above right with 03/04, 03/07. */ \ XXX(0x33, PUA(2)) /* Top Diagonal Sigma. Line for joining 03/01 to 03/04 or 03/07. */ \ XXX(0x34, PUA(3)) /* Bottom Diagonal Sigma. Line for joining 03/02 to 03/03 or 03/07. */ \ XXX(0x35, PUA(4)) /* Top Right Sigma. Joins to left with 02/03, 03/01. */ \ XXX(0x36, PUA(5)) /* Bottom Right Sigma. Joins to left with 02/03, 03/02. */ \ XXX(0x37, PUA(6)) /* Middle Sigma. Joins diagonally with 03/01, 03/02, 03/03, 03/04. */ \ XXX(0x38, UNDEF) /* undefined */ \ XXX(0x39, UNDEF) /* undefined */ \ XXX(0x3A, UNDEF) /* undefined */ \ XXX(0x3B, UNDEF) /* undefined */ \ UNI(0x3C, 0x2264) /* LESS-THAN OR EQUAL TO */ \ UNI(0x3D, 0x2260) /* NOT EQUAL TO */ \ UNI(0x3E, 0x2265) /* GREATER-THAN OR EQUAL TO */ \ UNI(0x3F, 0x222B) /* INTEGRAL */ \ UNI(0x40, 0x2234) /* THEREFORE */ \ UNI(0x41, 0x221D) /* PROPORTIONAL TO */ \ UNI(0x42, 0x221E) /* INFINITY */ \ UNI(0x43, 0x00F7) /* DIVISION SIGN */ \ UNI(0x44, 0x0394) /* GREEK CAPITAL DELTA */ \ UNI(0x45, 0x2207) /* NABLA */ \ UNI(0x46, 0x03A6) /* GREEK CAPITAL LETTER PHI */ \ UNI(0x47, 0x0393) /* GREEK CAPITAL LETTER GAMMA */ \ UNI(0x48, 0x223C) /* TILDE OPERATOR */ \ UNI(0x49, 0x2243) /* ASYMPTOTICALLY EQUAL TO */ \ UNI(0x4A, 0x0398) /* GREEK CAPITAL LETTER THETA */ \ UNI(0x4B, 0x00D7) /* MULTIPLICATION SIGN */ \ UNI(0x4C, 0x039B) /* GREEK CAPITAL LETTER LAMDA */ \ UNI(0x4D, 0x21D4) /* LEFT RIGHT DOUBLE ARROW */ \ UNI(0x4E, 0x21D2) /* RIGHTWARDS DOUBLE ARROW */ \ UNI(0x4F, 0x2261) /* IDENTICAL TO */ \ UNI(0x50, 0x03A0) /* GREEK CAPITAL LETTER PI */ \ UNI(0x51, 0x03A8) /* GREEK CAPITAL LETTER PSI */ \ XXX(0x52, UNDEF) /* undefined */ \ UNI(0x53, 0x03A3) /* GREEK CAPITAL LETTER SIGMA */ \ XXX(0x54, UNDEF) /* undefined */ \ XXX(0x55, UNDEF) /* undefined */ \ UNI(0x56, 0x221A) /* SQUARE ROOT */ \ UNI(0x57, 0x03A9) /* GREEK CAPITAL LETTER OMEGA */ \ UNI(0x58, 0x039E) /* GREEK CAPITAL LETTER XI */ \ UNI(0x59, 0x03A5) /* GREEK CAPITAL LETTER UPSILON */ \ UNI(0x5A, 0x2282) /* SUBSET OF */ \ UNI(0x5B, 0x2283) /* SUPERSET OF */ \ UNI(0x5C, 0x2229) /* INTERSECTION */ \ UNI(0x5D, 0x222A) /* UNION */ \ UNI(0x5E, 0x2227) /* LOGICAL AND */ \ UNI(0x5F, 0x2228) /* LOGICAL OR */ \ UNI(0x60, 0x00AC) /* NOT SIGN */ \ UNI(0x61, 0x03B1) /* GREEK SMALL LETTER ALPHA */ \ UNI(0x62, 0x03B2) /* GREEK SMALL LETTER BETA */ \ UNI(0x63, 0x03C7) /* GREEK SMALL LETTER CHI */ \ UNI(0x64, 0x03B4) /* GREEK SMALL LETTER DELTA */ \ UNI(0x65, 0x03B5) /* GREEK SMALL LETTER EPSILON */ \ UNI(0x66, 0x03C6) /* GREEK SMALL LETTER PHI */ \ UNI(0x67, 0x03B3) /* GREEK SMALL LETTER GAMMA */ \ UNI(0x68, 0x03B7) /* GREEK SMALL LETTER ETA */ \ UNI(0x69, 0x03B9) /* GREEK SMALL LETTER IOTA */ \ UNI(0x6A, 0x03B8) /* GREEK SMALL LETTER THETA */ \ UNI(0x6B, 0x03BA) /* GREEK SMALL LETTER KAPPA */ \ UNI(0x6C, 0x03BB) /* GREEK SMALL LETTER LAMDA */ \ XXX(0x6D, UNDEF) /* undefined */ \ UNI(0x6E, 0x03BD) /* GREEK SMALL LETTER NU */ \ UNI(0x6F, 0x2202) /* PARTIAL DIFFERENTIAL */ \ UNI(0x70, 0x03C0) /* GREEK SMALL LETTER PI */ \ UNI(0x71, 0x03C8) /* GREEK SMALL LETTER PSI */ \ UNI(0x72, 0x03C1) /* GREEK SMALL LETTER RHO */ \ UNI(0x73, 0x03C3) /* GREEK SMALL LETTER SIGMA */ \ UNI(0x74, 0x03C4) /* GREEK SMALL LETTER TAU */ \ XXX(0x75, UNDEF) /* undefined */ \ UNI(0x76, 0x0192) /* LATIN SMALL LETTER F WITH HOOK Probably chosen for its meaning of "function" */ \ UNI(0x77, 0x03C9) /* GREEK SMALL LETTER OMEGA */ \ UNI(0x78, 0x03BE) /* GREEK SMALL LETTER XI */ \ UNI(0x79, 0x03C5) /* GREEK SMALL LETTER UPSILON */ \ UNI(0x7A, 0x03B6) /* GREEK SMALL LETTER ZETA */ \ UNI(0x7B, 0x2190) /* LEFTWARDS ARROW */ \ UNI(0x7C, 0x2191) /* UPWARDS ARROW */ \ UNI(0x7D, 0x2192) /* RIGHTWARDS ARROW */ \ UNI(0x7E, 0x2193) /* DOWNWARDS ARROW */ \ } \ end_CODEPAGE() #define unmap_DEC_Technical(code,dft) \ switch (code) { \ MAP(0x21, 0xD5) /* RADICAL SYMBOL BOTTOM Centred left to right, so that it joins up with 02/02 */ \ MAP(0x22, 0xD6) /* BOX DRAWINGS LIGHT DOWN AND RIGHT */ \ MAP(0x23, 0x1D) /* BOX DRAWINGS LIGHT HORIZONTAL */ \ MAP(0x24, 0xD7) /* TOP HALF INTEGRAL with the proviso that the stem is vertical, to join with 02/06 */ \ MAP(0x25, 0xD8) /* BOTTOM HALF INTEGRAL with the proviso above. */ \ MAP(0x26, 0x84) /* BOX DRAWINGS LIGHT VERTICAL */ \ MAP(0x27, 0xD9) /* LEFT SQUARE BRACKET UPPER CORNER Joins vertically to 02/06, 02/08. Doesn't join to its right. */ \ MAP(0x28, 0xDA) /* LEFT SQUARE BRACKET LOWER CORNER Joins vertically to 02/06, 02/07. Doesn't join to its right. */ \ MAP(0x29, 0xDB) /* RIGHT SQUARE BRACKET UPPER CORNER Joins vertically to 026, 02a. Doesn't join to its left. */ \ MAP(0x2A, 0xDC) /* RIGHT SQUARE BRACKET LOWER CORNER Joins vertically to 026, 029. Doesn't join to its left. */ \ MAP(0x2B, 0xDD) /* LEFT CURLY BRACKET UPPER HOOK Joins vertically to 026, 02c, 02/15. Doesn't join to its right. */ \ MAP(0x2C, 0xDE) /* LEFT CURLY BRACKET LOWER HOOK Joins vertically to 026, 02b, 02/15. Doesn't join to its right. */ \ MAP(0x2D, 0xDF) /* RIGHT CURLY BRACKET UPPER HOOK Joins vertically to 026, 02e, 03/00. Doesn't join to its left. */ \ MAP(0x2E, 0xE0) /* RIGHT CURLY BRACKET LOWER HOOK Joins vertically to 026, 02d, 03/00. Doesn't join to its left. */ \ MAP(0x2F, 0xE1) /* LEFT CURLY BRACKET MIDDLE PIECE Joins vertically to 026, 02b, 02c. */ \ MAP(0x30, 0xE2) /* RIGHT CURLY BRACKET MIDDLE PIECE Joins vertically to 02/06, 02d, 02e. */ \ MAP(0x31, 0xE3) /* Top Left Sigma. Joins to right with 02/03, 03/05. Joins diagonally below right with 03/03, 03/07. */ \ MAP(0x32, 0xE4) /* Bottom Left Sigma. Joins to right with 02/03, 03/06. Joins diagonally above right with 03/04, 03/07. */ \ MAP(0x33, 0xE5) /* Top Diagonal Sigma. Line for joining 03/01 to 03/04 or 03/07. */ \ MAP(0x34, 0xE6) /* Bottom Diagonal Sigma. Line for joining 03/02 to 03/03 or 03/07. */ \ MAP(0x35, 0xE7) /* Top Right Sigma. Joins to left with 02/03, 03/01. */ \ MAP(0x36, 0xE8) /* Bottom Right Sigma. Joins to left with 02/03, 03/02. */ \ MAP(0x37, 0xE9) /* Middle Sigma. Joins diagonally with 03/01, 03/02, 03/03, 03/04. */ \ MAP(0x38, 0x1B) /* undefined */ \ MAP(0x39, 0x1B) /* undefined */ \ MAP(0x3A, 0x1B) /* undefined */ \ MAP(0x3B, 0x1B) /* undefined */ \ MAP(0x3C, 0x85) /* LESS-THAN OR EQUAL TO */ \ MAP(0x3D, 0x87) /* NOT EQUAL TO */ \ MAP(0x3E, 0x86) /* GREATER-THAN OR EQUAL TO */ \ MAP(0x3F, 0xEA) /* INTEGRAL */ \ MAP(0x40, 0xEB) /* THEREFORE */ \ MAP(0x41, 0xEC) /* PROPORTIONAL TO */ \ MAP(0x42, 0xED) /* INFINITY */ \ MAP(0x43, 0xF7) /* DIVISION SIGN */ \ MAP(0x44, 0xEE) /* GREEK CAPITAL DELTA */ \ MAP(0x45, 0xEF) /* NABLA */ \ MAP(0x46, 0xAC) /* GREEK CAPITAL LETTER PHI */ \ MAP(0x47, 0x78) /* GREEK CAPITAL LETTER GAMMA */ \ MAP(0x48, 0xF0) /* TILDE OPERATOR */ \ MAP(0x49, 0xF1) /* ASYMPTOTICALLY EQUAL TO */ \ MAP(0x4A, 0x7D) /* GREEK CAPITAL LETTER THETA */ \ MAP(0x4B, 0xD7) /* MULTIPLICATION SIGN */ \ MAP(0x4C, 0xA2) /* GREEK CAPITAL LETTER LAMDA */ \ MAP(0x4D, 0xF2) /* LEFT RIGHT DOUBLE ARROW */ \ MAP(0x4E, 0xF3) /* RIGHTWARDS DOUBLE ARROW */ \ MAP(0x4F, 0xF4) /* IDENTICAL TO */ \ MAP(0x50, 0xA7) /* GREEK CAPITAL LETTER PI */ \ MAP(0x51, 0xAE) /* GREEK CAPITAL LETTER PSI */ \ MAP(0x52, 0x1B) /* undefined */ \ MAP(0x53, 0xA9) /* GREEK CAPITAL LETTER SIGMA */ \ MAP(0x54, 0x1B) /* undefined */ \ MAP(0x55, 0x1B) /* undefined */ \ MAP(0x56, 0xF5) /* SQUARE ROOT */ \ MAP(0x57, 0xAF) /* GREEK CAPITAL LETTER OMEGA */ \ MAP(0x58, 0xA5) /* GREEK CAPITAL LETTER XI */ \ MAP(0x59, 0xAB) /* GREEK CAPITAL LETTER UPSILON */ \ MAP(0x5A, 0xF6) /* SUBSET OF */ \ MAP(0x5B, 0xF7) /* SUPERSET OF */ \ MAP(0x5C, 0xF8) /* INTERSECTION */ \ MAP(0x5D, 0xF9) /* UNION */ \ MAP(0x5E, 0xFA) /* LOGICAL AND */ \ MAP(0x5F, 0xFB) /* LOGICAL OR */ \ MAP(0x60, 0xAC) /* NOT SIGN */ \ MAP(0x61, 0xB7) /* GREEK SMALL LETTER ALPHA */ \ MAP(0x62, 0xB8) /* GREEK SMALL LETTER BETA */ \ MAP(0x63, 0xCD) /* GREEK SMALL LETTER CHI */ \ MAP(0x64, 0xBA) /* GREEK SMALL LETTER DELTA */ \ MAP(0x65, 0xBB) /* GREEK SMALL LETTER EPSILON */ \ MAP(0x66, 0xCC) /* GREEK SMALL LETTER PHI */ \ MAP(0x67, 0xB9) /* GREEK SMALL LETTER GAMMA */ \ MAP(0x68, 0xBD) /* GREEK SMALL LETTER ETA */ \ MAP(0x69, 0xBF) /* GREEK SMALL LETTER IOTA */ \ MAP(0x6A, 0xBE) /* GREEK SMALL LETTER THETA */ \ MAP(0x6B, 0xC0) /* GREEK SMALL LETTER KAPPA */ \ MAP(0x6C, 0xC1) /* GREEK SMALL LETTER LAMDA */ \ MAP(0x6D, 0x1B) /* undefined */ \ MAP(0x6E, 0xC3) /* GREEK SMALL LETTER NU */ \ MAP(0x6F, 0xFC) /* PARTIAL DIFFERENTIAL */ \ MAP(0x70, 0xC6) /* GREEK SMALL LETTER PI */ \ MAP(0x71, 0xCE) /* GREEK SMALL LETTER PSI */ \ MAP(0x72, 0xC7) /* GREEK SMALL LETTER RHO */ \ MAP(0x73, 0xC9) /* GREEK SMALL LETTER SIGMA */ \ MAP(0x74, 0xCA) /* GREEK SMALL LETTER TAU */ \ MAP(0x75, 0x1B) /* undefined */ \ MAP(0x76, 0xFD) /* LATIN SMALL LETTER F WITH HOOK Probably chosen for its meaning of "function" */ \ MAP(0x77, 0xCF) /* GREEK SMALL LETTER OMEGA */ \ MAP(0x78, 0xC4) /* GREEK SMALL LETTER XI */ \ MAP(0x79, 0xCB) /* GREEK SMALL LETTER UPSILON */ \ MAP(0x7A, 0xBC) /* GREEK SMALL LETTER ZETA */ \ MAP(0x7B, 0xFE) /* LEFTWARDS ARROW */ \ MAP(0x7C, 0xFF) /* UPWARDS ARROW */ \ MAP(0x7D, 0x100) /* RIGHTWARDS ARROW */ \ MAP(0x7E, 0x02) /* DOWNWARDS ARROW */ \ default: dft; break; \ } #define map_JIS_Roman(code) \ begin_CODEPAGE(94) \ switch (code) { \ UNI(0x5C, 0x00A5) /* YEN SIGN */ \ UNI(0x7E, 0x203E) /* OVERLINE */ \ } \ end_CODEPAGE() #define unmap_JIS_Roman(code,dft) /* nothing */ /* * Documented as if only GR, but encoded here to allow assignment to GL and GR. */ #define map_JIS_Katakana(code) \ begin_CODEPAGE(94) \ switch (code) { \ UNI(0x21, 0xFF61) /* HALFWIDTH IDEOGRAPHIC FULL STOP */ \ UNI(0x22, 0xFF62) /* HALFWIDTH LEFT CORNER BRACKET */ \ UNI(0x23, 0xFF63) /* HALFWIDTH RIGHT CORNER BRACKET */ \ UNI(0x24, 0xFF64) /* HALFWIDTH IDEOGRAPHIC COMMA */ \ UNI(0x25, 0xFF65) /* HALFWIDTH KATAKANA MIDDLE DOT */ \ UNI(0x26, 0xFF66) /* HALFWIDTH KATAKANA LETTER WO */ \ UNI(0x27, 0xFF67) /* HALFWIDTH KATAKANA LETTER SMALL A */ \ UNI(0x28, 0xFF68) /* HALFWIDTH KATAKANA LETTER SMALL I */ \ UNI(0x29, 0xFF69) /* HALFWIDTH KATAKANA LETTER SMALL U */ \ UNI(0x2A, 0xFF6A) /* HALFWIDTH KATAKANA LETTER SMALL E */ \ UNI(0x2B, 0xFF6B) /* HALFWIDTH KATAKANA LETTER SMALL O */ \ UNI(0x2C, 0xFF6C) /* HALFWIDTH KATAKANA LETTER SMALL YA */ \ UNI(0x2D, 0xFF6D) /* HALFWIDTH KATAKANA LETTER SMALL YU */ \ UNI(0x2E, 0xFF6E) /* HALFWIDTH KATAKANA LETTER SMALL YO */ \ UNI(0x2F, 0xFF6F) /* HALFWIDTH KATAKANA LETTER SMALL TU */ \ UNI(0x30, 0xFF70) /* HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK */ \ UNI(0x31, 0xFF71) /* HALFWIDTH KATAKANA LETTER A */ \ UNI(0x32, 0xFF72) /* HALFWIDTH KATAKANA LETTER I */ \ UNI(0x33, 0xFF73) /* HALFWIDTH KATAKANA LETTER U */ \ UNI(0x34, 0xFF74) /* HALFWIDTH KATAKANA LETTER E */ \ UNI(0x35, 0xFF75) /* HALFWIDTH KATAKANA LETTER O */ \ UNI(0x36, 0xFF76) /* HALFWIDTH KATAKANA LETTER KA */ \ UNI(0x37, 0xFF77) /* HALFWIDTH KATAKANA LETTER KI */ \ UNI(0x38, 0xFF78) /* HALFWIDTH KATAKANA LETTER KU */ \ UNI(0x39, 0xFF79) /* HALFWIDTH KATAKANA LETTER KE */ \ UNI(0x3A, 0xFF7A) /* HALFWIDTH KATAKANA LETTER KO */ \ UNI(0x3B, 0xFF7B) /* HALFWIDTH KATAKANA LETTER SA */ \ UNI(0x3C, 0xFF7C) /* HALFWIDTH KATAKANA LETTER SI */ \ UNI(0x3D, 0xFF7D) /* HALFWIDTH KATAKANA LETTER SU */ \ UNI(0x3E, 0xFF7E) /* HALFWIDTH KATAKANA LETTER SE */ \ UNI(0x3F, 0xFF7F) /* HALFWIDTH KATAKANA LETTER SO */ \ UNI(0x40, 0xFF80) /* HALFWIDTH KATAKANA LETTER TA */ \ UNI(0x41, 0xFF81) /* HALFWIDTH KATAKANA LETTER TI */ \ UNI(0x42, 0xFF82) /* HALFWIDTH KATAKANA LETTER TU */ \ UNI(0x43, 0xFF83) /* HALFWIDTH KATAKANA LETTER TE */ \ UNI(0x44, 0xFF84) /* HALFWIDTH KATAKANA LETTER TO */ \ UNI(0x45, 0xFF85) /* HALFWIDTH KATAKANA LETTER NA */ \ UNI(0x46, 0xFF86) /* HALFWIDTH KATAKANA LETTER NI */ \ UNI(0x47, 0xFF87) /* HALFWIDTH KATAKANA LETTER NU */ \ UNI(0x48, 0xFF88) /* HALFWIDTH KATAKANA LETTER NE */ \ UNI(0x49, 0xFF89) /* HALFWIDTH KATAKANA LETTER NO */ \ UNI(0x4A, 0xFF8A) /* HALFWIDTH KATAKANA LETTER HA */ \ UNI(0x4B, 0xFF8B) /* HALFWIDTH KATAKANA LETTER HI */ \ UNI(0x4C, 0xFF8C) /* HALFWIDTH KATAKANA LETTER HU */ \ UNI(0x4D, 0xFF8D) /* HALFWIDTH KATAKANA LETTER HE */ \ UNI(0x4E, 0xFF8E) /* HALFWIDTH KATAKANA LETTER HO */ \ UNI(0x4F, 0xFF8F) /* HALFWIDTH KATAKANA LETTER MA */ \ UNI(0x50, 0xFF90) /* HALFWIDTH KATAKANA LETTER MI */ \ UNI(0x51, 0xFF91) /* HALFWIDTH KATAKANA LETTER MU */ \ UNI(0x52, 0xFF92) /* HALFWIDTH KATAKANA LETTER ME */ \ UNI(0x53, 0xFF93) /* HALFWIDTH KATAKANA LETTER MO */ \ UNI(0x54, 0xFF94) /* HALFWIDTH KATAKANA LETTER YA */ \ UNI(0x55, 0xFF95) /* HALFWIDTH KATAKANA LETTER YU */ \ UNI(0x56, 0xFF96) /* HALFWIDTH KATAKANA LETTER YO */ \ UNI(0x57, 0xFF97) /* HALFWIDTH KATAKANA LETTER RA */ \ UNI(0x58, 0xFF98) /* HALFWIDTH KATAKANA LETTER RI */ \ UNI(0x59, 0xFF99) /* HALFWIDTH KATAKANA LETTER RU */ \ UNI(0x5A, 0xFF9A) /* HALFWIDTH KATAKANA LETTER RE */ \ UNI(0x5B, 0xFF9B) /* HALFWIDTH KATAKANA LETTER RO */ \ UNI(0x5C, 0xFF9C) /* HALFWIDTH KATAKANA LETTER WA */ \ UNI(0x5D, 0xFF9D) /* HALFWIDTH KATAKANA LETTER N */ \ UNI(0x5E, 0xFF9E) /* HALFWIDTH KATAKANA VOICED SOUND MARK */ \ UNI(0x5F, 0xFF9F) /* HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK */ \ XXX(0x60, UNDEF) \ XXX(0x61, UNDEF) \ XXX(0x62, UNDEF) \ XXX(0x63, UNDEF) \ XXX(0x64, UNDEF) \ XXX(0x65, UNDEF) \ XXX(0x66, UNDEF) \ XXX(0x67, UNDEF) \ XXX(0x68, UNDEF) \ XXX(0x69, UNDEF) \ XXX(0x6A, UNDEF) \ XXX(0x6B, UNDEF) \ XXX(0x6C, UNDEF) \ XXX(0x6D, UNDEF) \ XXX(0x6E, UNDEF) \ XXX(0x6F, UNDEF) \ XXX(0x70, UNDEF) \ XXX(0x71, UNDEF) \ XXX(0x72, UNDEF) \ XXX(0x73, UNDEF) \ XXX(0x74, UNDEF) \ XXX(0x75, UNDEF) \ XXX(0x76, UNDEF) \ XXX(0x77, UNDEF) \ XXX(0x78, UNDEF) \ XXX(0x79, UNDEF) \ XXX(0x7A, UNDEF) \ XXX(0x7B, UNDEF) \ XXX(0x7C, UNDEF) \ XXX(0x7D, UNDEF) \ } \ end_CODEPAGE() #define unmap_JIS_Katakana(code,dft) /* nothing */ /* * ISO Latin/Cyrillic is 8859-5 */ #define map_ISO_Latin_Cyrillic(code) \ begin_CODEPAGE(96) \ switch (code) { \ UNI(0x20, 0x00A0) /* NO-BREAK SPACE */ \ UNI(0x21, 0x0401) /* CYRILLIC CAPITAL LETTER IO */ \ UNI(0x22, 0x0402) /* CYRILLIC CAPITAL LETTER DJE */ \ UNI(0x23, 0x0403) /* CYRILLIC CAPITAL LETTER GJE */ \ UNI(0x24, 0x0404) /* CYRILLIC CAPITAL LETTER UKRAINIAN IE */ \ UNI(0x25, 0x0405) /* CYRILLIC CAPITAL LETTER DZE */ \ UNI(0x26, 0x0406) /* CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ \ UNI(0x27, 0x0407) /* CYRILLIC CAPITAL LETTER YI */ \ UNI(0x28, 0x0408) /* CYRILLIC CAPITAL LETTER JE */ \ UNI(0x29, 0x0409) /* CYRILLIC CAPITAL LETTER LJE */ \ UNI(0x2A, 0x040A) /* CYRILLIC CAPITAL LETTER NJE */ \ UNI(0x2B, 0x040B) /* CYRILLIC CAPITAL LETTER TSHE */ \ UNI(0x2C, 0x040C) /* CYRILLIC CAPITAL LETTER KJE */ \ UNI(0x2D, 0x00AD) /* SOFT HYPHEN */ \ UNI(0x2E, 0x040E) /* CYRILLIC CAPITAL LETTER SHORT U */ \ UNI(0x2F, 0x040F) /* CYRILLIC CAPITAL LETTER DZHE */ \ UNI(0x30, 0x0410) /* CYRILLIC CAPITAL LETTER A */ \ UNI(0x31, 0x0411) /* CYRILLIC CAPITAL LETTER BE */ \ UNI(0x32, 0x0412) /* CYRILLIC CAPITAL LETTER VE */ \ UNI(0x33, 0x0413) /* CYRILLIC CAPITAL LETTER GHE */ \ UNI(0x34, 0x0414) /* CYRILLIC CAPITAL LETTER DE */ \ UNI(0x35, 0x0415) /* CYRILLIC CAPITAL LETTER IE */ \ UNI(0x36, 0x0416) /* CYRILLIC CAPITAL LETTER ZHE */ \ UNI(0x37, 0x0417) /* CYRILLIC CAPITAL LETTER ZE */ \ UNI(0x38, 0x0418) /* CYRILLIC CAPITAL LETTER I */ \ UNI(0x39, 0x0419) /* CYRILLIC CAPITAL LETTER SHORT I */ \ UNI(0x3A, 0x041A) /* CYRILLIC CAPITAL LETTER KA */ \ UNI(0x3B, 0x041B) /* CYRILLIC CAPITAL LETTER EL */ \ UNI(0x3C, 0x041C) /* CYRILLIC CAPITAL LETTER EM */ \ UNI(0x3D, 0x041D) /* CYRILLIC CAPITAL LETTER EN */ \ UNI(0x3E, 0x041E) /* CYRILLIC CAPITAL LETTER O */ \ UNI(0x3F, 0x041F) /* CYRILLIC CAPITAL LETTER PE */ \ UNI(0x40, 0x0420) /* CYRILLIC CAPITAL LETTER ER */ \ UNI(0x41, 0x0421) /* CYRILLIC CAPITAL LETTER ES */ \ UNI(0x42, 0x0422) /* CYRILLIC CAPITAL LETTER TE */ \ UNI(0x43, 0x0423) /* CYRILLIC CAPITAL LETTER U */ \ UNI(0x44, 0x0424) /* CYRILLIC CAPITAL LETTER EF */ \ UNI(0x45, 0x0425) /* CYRILLIC CAPITAL LETTER HA */ \ UNI(0x46, 0x0426) /* CYRILLIC CAPITAL LETTER TSE */ \ UNI(0x47, 0x0427) /* CYRILLIC CAPITAL LETTER CHE */ \ UNI(0x48, 0x0428) /* CYRILLIC CAPITAL LETTER SHA */ \ UNI(0x49, 0x0429) /* CYRILLIC CAPITAL LETTER SHCHA */ \ UNI(0x4A, 0x042A) /* CYRILLIC CAPITAL LETTER HARD SIGN */ \ UNI(0x4B, 0x042B) /* CYRILLIC CAPITAL LETTER YERU */ \ UNI(0x4C, 0x042C) /* CYRILLIC CAPITAL LETTER SOFT SIGN */ \ UNI(0x4D, 0x042D) /* CYRILLIC CAPITAL LETTER E */ \ UNI(0x4E, 0x042E) /* CYRILLIC CAPITAL LETTER YU */ \ UNI(0x4F, 0x042F) /* CYRILLIC CAPITAL LETTER YA */ \ UNI(0x50, 0x0430) /* CYRILLIC SMALL LETTER A */ \ UNI(0x51, 0x0431) /* CYRILLIC SMALL LETTER BE */ \ UNI(0x52, 0x0432) /* CYRILLIC SMALL LETTER VE */ \ UNI(0x53, 0x0433) /* CYRILLIC SMALL LETTER GHE */ \ UNI(0x54, 0x0434) /* CYRILLIC SMALL LETTER DE */ \ UNI(0x55, 0x0435) /* CYRILLIC SMALL LETTER IE */ \ UNI(0x56, 0x0436) /* CYRILLIC SMALL LETTER ZHE */ \ UNI(0x57, 0x0437) /* CYRILLIC SMALL LETTER ZE */ \ UNI(0x58, 0x0438) /* CYRILLIC SMALL LETTER I */ \ UNI(0x59, 0x0439) /* CYRILLIC SMALL LETTER SHORT I */ \ UNI(0x5A, 0x043A) /* CYRILLIC SMALL LETTER KA */ \ UNI(0x5B, 0x043B) /* CYRILLIC SMALL LETTER EL */ \ UNI(0x5C, 0x043C) /* CYRILLIC SMALL LETTER EM */ \ UNI(0x5D, 0x043D) /* CYRILLIC SMALL LETTER EN */ \ UNI(0x5E, 0x043E) /* CYRILLIC SMALL LETTER O */ \ UNI(0x5F, 0x043F) /* CYRILLIC SMALL LETTER PE */ \ UNI(0x60, 0x0440) /* CYRILLIC SMALL LETTER ER */ \ UNI(0x61, 0x0441) /* CYRILLIC SMALL LETTER ES */ \ UNI(0x62, 0x0442) /* CYRILLIC SMALL LETTER TE */ \ UNI(0x63, 0x0443) /* CYRILLIC SMALL LETTER U */ \ UNI(0x64, 0x0444) /* CYRILLIC SMALL LETTER EF */ \ UNI(0x65, 0x0445) /* CYRILLIC SMALL LETTER HA */ \ UNI(0x66, 0x0446) /* CYRILLIC SMALL LETTER TSE */ \ UNI(0x67, 0x0447) /* CYRILLIC SMALL LETTER CHE */ \ UNI(0x68, 0x0448) /* CYRILLIC SMALL LETTER SHA */ \ UNI(0x69, 0x0449) /* CYRILLIC SMALL LETTER SHCHA */ \ UNI(0x6A, 0x044A) /* CYRILLIC SMALL LETTER HARD SIGN */ \ UNI(0x6B, 0x044B) /* CYRILLIC SMALL LETTER YERU */ \ UNI(0x6C, 0x044C) /* CYRILLIC SMALL LETTER SOFT SIGN */ \ UNI(0x6D, 0x044D) /* CYRILLIC SMALL LETTER E */ \ UNI(0x6E, 0x044E) /* CYRILLIC SMALL LETTER YU */ \ UNI(0x6F, 0x044F) /* CYRILLIC SMALL LETTER YA */ \ UNI(0x70, 0x2116) /* NUMERO SIGN */ \ UNI(0x71, 0x0451) /* CYRILLIC SMALL LETTER IO */ \ UNI(0x72, 0x0452) /* CYRILLIC SMALL LETTER DJE */ \ UNI(0x73, 0x0453) /* CYRILLIC SMALL LETTER GJE */ \ UNI(0x74, 0x0454) /* CYRILLIC SMALL LETTER UKRAINIAN IE */ \ UNI(0x75, 0x0455) /* CYRILLIC SMALL LETTER DZE */ \ UNI(0x76, 0x0456) /* CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ \ UNI(0x77, 0x0457) /* CYRILLIC SMALL LETTER YI */ \ UNI(0x78, 0x0458) /* CYRILLIC SMALL LETTER JE */ \ UNI(0x79, 0x0459) /* CYRILLIC SMALL LETTER LJE */ \ UNI(0x7A, 0x045A) /* CYRILLIC SMALL LETTER NJE */ \ UNI(0x7B, 0x045B) /* CYRILLIC SMALL LETTER TSHE */ \ UNI(0x7C, 0x045C) /* CYRILLIC SMALL LETTER KJE */ \ UNI(0x7D, 0x00A7) /* SECTION SIGN */ \ UNI(0x7E, 0x045E) /* CYRILLIC SMALL LETTER SHORT U */ \ UNI(0x7F, 0x045F) /* CYRILLIC SMALL LETTER DZHE */ \ } \ end_CODEPAGE() #define unmap_ISO_Latin_Cyrillic(code,dft) \ switch (code) { \ MAP(0x21, 0x03) /* CYRILLIC CAPITAL LETTER IO */ \ MAP(0x22, 0x04) /* CYRILLIC CAPITAL LETTER DJE */ \ MAP(0x23, 0x05) /* CYRILLIC CAPITAL LETTER GJE */ \ MAP(0x24, 0x06) /* CYRILLIC CAPITAL LETTER UKRAINIAN IE */ \ MAP(0x25, 0x07) /* CYRILLIC CAPITAL LETTER DZE */ \ MAP(0x26, 0x08) /* CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ \ MAP(0x27, 0x09) /* CYRILLIC CAPITAL LETTER YI */ \ MAP(0x28, 0x0A) /* CYRILLIC CAPITAL LETTER JE */ \ MAP(0x29, 0x0B) /* CYRILLIC CAPITAL LETTER LJE */ \ MAP(0x2A, 0x0C) /* CYRILLIC CAPITAL LETTER NJE */ \ MAP(0x2B, 0x0D) /* CYRILLIC CAPITAL LETTER TSHE */ \ MAP(0x2C, 0x0E) /* CYRILLIC CAPITAL LETTER KJE */ \ MAP(0x2E, 0x0F) /* CYRILLIC CAPITAL LETTER SHORT U */ \ MAP(0x2F, 0x10) /* CYRILLIC CAPITAL LETTER DZHE */ \ MAP(0x30, 0x11) /* CYRILLIC CAPITAL LETTER A */ \ MAP(0x31, 0x12) /* CYRILLIC CAPITAL LETTER BE */ \ MAP(0x32, 0x13) /* CYRILLIC CAPITAL LETTER VE */ \ MAP(0x33, 0x14) /* CYRILLIC CAPITAL LETTER GHE */ \ MAP(0x34, 0x15) /* CYRILLIC CAPITAL LETTER DE */ \ MAP(0x35, 0x16) /* CYRILLIC CAPITAL LETTER IE */ \ MAP(0x36, 0x17) /* CYRILLIC CAPITAL LETTER ZHE */ \ MAP(0x37, 0x18) /* CYRILLIC CAPITAL LETTER ZE */ \ MAP(0x38, 0x19) /* CYRILLIC CAPITAL LETTER I */ \ MAP(0x39, 0x1A) /* CYRILLIC CAPITAL LETTER SHORT I */ \ MAP(0x3A, 0x1B) /* CYRILLIC CAPITAL LETTER KA */ \ MAP(0x3B, 0x1C) /* CYRILLIC CAPITAL LETTER EL */ \ MAP(0x3C, 0x1D) /* CYRILLIC CAPITAL LETTER EM */ \ MAP(0x3D, 0x1E) /* CYRILLIC CAPITAL LETTER EN */ \ MAP(0x3E, 0x1F) /* CYRILLIC CAPITAL LETTER O */ \ MAP(0x3F, 0x20) /* CYRILLIC CAPITAL LETTER PE */ \ MAP(0x40, 0x21) /* CYRILLIC CAPITAL LETTER ER */ \ MAP(0x41, 0x22) /* CYRILLIC CAPITAL LETTER ES */ \ MAP(0x42, 0x23) /* CYRILLIC CAPITAL LETTER TE */ \ MAP(0x43, 0x24) /* CYRILLIC CAPITAL LETTER U */ \ MAP(0x44, 0x25) /* CYRILLIC CAPITAL LETTER EF */ \ MAP(0x45, 0x26) /* CYRILLIC CAPITAL LETTER HA */ \ MAP(0x46, 0x27) /* CYRILLIC CAPITAL LETTER TSE */ \ MAP(0x47, 0x28) /* CYRILLIC CAPITAL LETTER CHE */ \ MAP(0x48, 0x29) /* CYRILLIC CAPITAL LETTER SHA */ \ MAP(0x49, 0x2A) /* CYRILLIC CAPITAL LETTER SHCHA */ \ MAP(0x4A, 0x2B) /* CYRILLIC CAPITAL LETTER HARD SIGN */ \ MAP(0x4B, 0x2C) /* CYRILLIC CAPITAL LETTER YERU */ \ MAP(0x4C, 0x2D) /* CYRILLIC CAPITAL LETTER SOFT SIGN */ \ MAP(0x4D, 0x2E) /* CYRILLIC CAPITAL LETTER E */ \ MAP(0x4E, 0x2F) /* CYRILLIC CAPITAL LETTER YU */ \ MAP(0x4F, 0x30) /* CYRILLIC CAPITAL LETTER YA */ \ MAP(0x50, 0x31) /* CYRILLIC SMALL LETTER A */ \ MAP(0x51, 0x32) /* CYRILLIC SMALL LETTER BE */ \ MAP(0x52, 0x33) /* CYRILLIC SMALL LETTER VE */ \ MAP(0x53, 0x34) /* CYRILLIC SMALL LETTER GHE */ \ MAP(0x54, 0x35) /* CYRILLIC SMALL LETTER DE */ \ MAP(0x55, 0x36) /* CYRILLIC SMALL LETTER IE */ \ MAP(0x56, 0x37) /* CYRILLIC SMALL LETTER ZHE */ \ MAP(0x57, 0x38) /* CYRILLIC SMALL LETTER ZE */ \ MAP(0x58, 0x39) /* CYRILLIC SMALL LETTER I */ \ MAP(0x59, 0x3A) /* CYRILLIC SMALL LETTER SHORT I */ \ MAP(0x5A, 0x3B) /* CYRILLIC SMALL LETTER KA */ \ MAP(0x5B, 0x3C) /* CYRILLIC SMALL LETTER EL */ \ MAP(0x5C, 0x3D) /* CYRILLIC SMALL LETTER EM */ \ MAP(0x5D, 0x3E) /* CYRILLIC SMALL LETTER EN */ \ MAP(0x5E, 0x3F) /* CYRILLIC SMALL LETTER O */ \ MAP(0x5F, 0x40) /* CYRILLIC SMALL LETTER PE */ \ MAP(0x60, 0x41) /* CYRILLIC SMALL LETTER ER */ \ MAP(0x61, 0x42) /* CYRILLIC SMALL LETTER ES */ \ MAP(0x62, 0x43) /* CYRILLIC SMALL LETTER TE */ \ MAP(0x63, 0x44) /* CYRILLIC SMALL LETTER U */ \ MAP(0x64, 0x45) /* CYRILLIC SMALL LETTER EF */ \ MAP(0x65, 0x46) /* CYRILLIC SMALL LETTER HA */ \ MAP(0x66, 0x47) /* CYRILLIC SMALL LETTER TSE */ \ MAP(0x67, 0x48) /* CYRILLIC SMALL LETTER CHE */ \ MAP(0x68, 0x49) /* CYRILLIC SMALL LETTER SHA */ \ MAP(0x69, 0x4A) /* CYRILLIC SMALL LETTER SHCHA */ \ MAP(0x6A, 0x4B) /* CYRILLIC SMALL LETTER HARD SIGN */ \ MAP(0x6B, 0x4C) /* CYRILLIC SMALL LETTER YERU */ \ MAP(0x6C, 0x4D) /* CYRILLIC SMALL LETTER SOFT SIGN */ \ MAP(0x6D, 0x4E) /* CYRILLIC SMALL LETTER E */ \ MAP(0x6E, 0x4F) /* CYRILLIC SMALL LETTER YU */ \ MAP(0x6F, 0x50) /* CYRILLIC SMALL LETTER YA */ \ MAP(0x70, 0x51) /* NUMERO SIGN */ \ MAP(0x71, 0x52) /* CYRILLIC SMALL LETTER IO */ \ MAP(0x72, 0x53) /* CYRILLIC SMALL LETTER DJE */ \ MAP(0x73, 0x54) /* CYRILLIC SMALL LETTER GJE */ \ MAP(0x74, 0x55) /* CYRILLIC SMALL LETTER UKRAINIAN IE */ \ MAP(0x75, 0x56) /* CYRILLIC SMALL LETTER DZE */ \ MAP(0x76, 0x57) /* CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ \ MAP(0x77, 0x58) /* CYRILLIC SMALL LETTER YI */ \ MAP(0x78, 0x59) /* CYRILLIC SMALL LETTER JE */ \ MAP(0x79, 0x5A) /* CYRILLIC SMALL LETTER LJE */ \ MAP(0x7A, 0x5B) /* CYRILLIC SMALL LETTER NJE */ \ MAP(0x7B, 0x5C) /* CYRILLIC SMALL LETTER TSHE */ \ MAP(0x7C, 0x5D) /* CYRILLIC SMALL LETTER KJE */ \ MAP(0x7D, 0xA7) /* SECTION SIGN */ \ MAP(0x7E, 0x5E) /* CYRILLIC SMALL LETTER SHORT U */ \ MAP(0x7F, 0x5F) /* CYRILLIC SMALL LETTER DZHE */ \ default: dft; break; \ } /* * ISO Greek is 8859-7 */ #define map_ISO_Greek_Supp(code) \ begin_CODEPAGE(96) \ switch (code) { \ UNI(0x20, 0x00A0) /* NO-BREAK SPACE */ \ UNI(0x21, 0x2018) /* LEFT SINGLE QUOTATION MARK */ \ UNI(0x22, 0x2019) /* RIGHT SINGLE QUOTATION MARK */ \ UNI(0x23, 0x00A3) /* POUND SIGN */ \ XXX(0x24, UNDEF) /* undefined */ \ XXX(0x25, UNDEF) /* undefined */ \ UNI(0x26, 0x00A6) /* BROKEN BAR */ \ UNI(0x27, 0x00A7) /* SECTION SIGN */ \ UNI(0x28, 0x00A8) /* DIAERESIS */ \ UNI(0x29, 0x00A9) /* COPYRIGHT SIGN */ \ XXX(0x2A, UNDEF) /* undefined */ \ UNI(0x2B, 0x00AB) /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ UNI(0x2C, 0x00AC) /* NOT SIGN */ \ UNI(0x2D, 0x00AD) /* SOFT HYPHEN */ \ XXX(0x2E, UNDEF) /* undefined */ \ UNI(0x2F, 0x2015) /* HORIZONTAL BAR */ \ UNI(0x30, 0x00B0) /* DEGREE SIGN */ \ UNI(0x31, 0x00B1) /* PLUS-MINUS SIGN */ \ UNI(0x32, 0x00B2) /* SUPERSCRIPT TWO */ \ UNI(0x33, 0x00B3) /* SUPERSCRIPT THREE */ \ UNI(0x34, 0x0384) /* GREEK TONOS */ \ UNI(0x35, 0x0385) /* GREEK DIALYTIKA TONOS */ \ UNI(0x36, 0x0386) /* GREEK CAPITAL LETTER ALPHA WITH TONOS */ \ UNI(0x37, 0x00B7) /* MIDDLE DOT */ \ UNI(0x38, 0x0388) /* GREEK CAPITAL LETTER EPSILON WITH TONOS */ \ UNI(0x39, 0x0389) /* GREEK CAPITAL LETTER ETA WITH TONOS */ \ UNI(0x3A, 0x038A) /* GREEK CAPITAL LETTER IOTA WITH TONOS */ \ UNI(0x3B, 0x00BB) /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ UNI(0x3C, 0x038C) /* GREEK CAPITAL LETTER OMICRON WITH TONOS */ \ UNI(0x3D, 0x00BD) /* VULGAR FRACTION ONE HALF */ \ UNI(0x3E, 0x038E) /* GREEK CAPITAL LETTER UPSILON WITH TONOS */ \ UNI(0x3F, 0x038F) /* GREEK CAPITAL LETTER OMEGA WITH TONOS */ \ UNI(0x40, 0x0390) /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ \ UNI(0x41, 0x0391) /* GREEK CAPITAL LETTER ALPHA */ \ UNI(0x42, 0x0392) /* GREEK CAPITAL LETTER BETA */ \ UNI(0x43, 0x0393) /* GREEK CAPITAL LETTER GAMMA */ \ UNI(0x44, 0x0394) /* GREEK CAPITAL LETTER DELTA */ \ UNI(0x45, 0x0395) /* GREEK CAPITAL LETTER EPSILON */ \ UNI(0x46, 0x0396) /* GREEK CAPITAL LETTER ZETA */ \ UNI(0x47, 0x0397) /* GREEK CAPITAL LETTER ETA */ \ UNI(0x48, 0x0398) /* GREEK CAPITAL LETTER THETA */ \ UNI(0x49, 0x0399) /* GREEK CAPITAL LETTER IOTA */ \ UNI(0x4A, 0x039A) /* GREEK CAPITAL LETTER KAPPA */ \ UNI(0x4B, 0x039B) /* GREEK CAPITAL LETTER LAMDA */ \ UNI(0x4C, 0x039C) /* GREEK CAPITAL LETTER MU */ \ UNI(0x4D, 0x039D) /* GREEK CAPITAL LETTER NU */ \ UNI(0x4E, 0x039E) /* GREEK CAPITAL LETTER XI */ \ UNI(0x4F, 0x039F) /* GREEK CAPITAL LETTER OMICRON */ \ UNI(0x50, 0x03A0) /* GREEK CAPITAL LETTER PI */ \ UNI(0x51, 0x03A1) /* GREEK CAPITAL LETTER RHO */ \ XXX(0x52, UNDEF) /* undefined */ \ UNI(0x53, 0x03A3) /* GREEK CAPITAL LETTER SIGMA */ \ UNI(0x54, 0x03A4) /* GREEK CAPITAL LETTER TAU */ \ UNI(0x55, 0x03A5) /* GREEK CAPITAL LETTER UPSILON */ \ UNI(0x56, 0x03A6) /* GREEK CAPITAL LETTER PHI */ \ UNI(0x57, 0x03A7) /* GREEK CAPITAL LETTER CHI */ \ UNI(0x58, 0x03A8) /* GREEK CAPITAL LETTER PSI */ \ UNI(0x59, 0x03A9) /* GREEK CAPITAL LETTER OMEGA */ \ UNI(0x5A, 0x03AA) /* GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ \ UNI(0x5B, 0x03AB) /* GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ \ UNI(0x5C, 0x03AC) /* GREEK SMALL LETTER ALPHA WITH TONOS */ \ UNI(0x5D, 0x03AD) /* GREEK SMALL LETTER EPSILON WITH TONOS */ \ UNI(0x5E, 0x03AE) /* GREEK SMALL LETTER ETA WITH TONOS */ \ UNI(0x5F, 0x03AF) /* GREEK SMALL LETTER IOTA WITH TONOS */ \ UNI(0x60, 0x03B0) /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ \ UNI(0x61, 0x03B1) /* GREEK SMALL LETTER ALPHA */ \ UNI(0x62, 0x03B2) /* GREEK SMALL LETTER BETA */ \ UNI(0x63, 0x03B3) /* GREEK SMALL LETTER GAMMA */ \ UNI(0x64, 0x03B4) /* GREEK SMALL LETTER DELTA */ \ UNI(0x65, 0x03B5) /* GREEK SMALL LETTER EPSILON */ \ UNI(0x66, 0x03B6) /* GREEK SMALL LETTER ZETA */ \ UNI(0x67, 0x03B7) /* GREEK SMALL LETTER ETA */ \ UNI(0x68, 0x03B8) /* GREEK SMALL LETTER THETA */ \ UNI(0x69, 0x03B9) /* GREEK SMALL LETTER IOTA */ \ UNI(0x6A, 0x03BA) /* GREEK SMALL LETTER KAPPA */ \ UNI(0x6B, 0x03BB) /* GREEK SMALL LETTER LAMDA */ \ UNI(0x6C, 0x03BC) /* GREEK SMALL LETTER MU */ \ UNI(0x6D, 0x03BD) /* GREEK SMALL LETTER NU */ \ UNI(0x6E, 0x03BE) /* GREEK SMALL LETTER XI */ \ UNI(0x6F, 0x03BF) /* GREEK SMALL LETTER OMICRON */ \ UNI(0x70, 0x03C0) /* GREEK SMALL LETTER PI */ \ UNI(0x71, 0x03C1) /* GREEK SMALL LETTER RHO */ \ UNI(0x72, 0x03C2) /* GREEK SMALL LETTER FINAL SIGMA */ \ UNI(0x73, 0x03C3) /* GREEK SMALL LETTER SIGMA */ \ UNI(0x74, 0x03C4) /* GREEK SMALL LETTER TAU */ \ UNI(0x75, 0x03C5) /* GREEK SMALL LETTER UPSILON */ \ UNI(0x76, 0x03C6) /* GREEK SMALL LETTER PHI */ \ UNI(0x77, 0x03C7) /* GREEK SMALL LETTER CHI */ \ UNI(0x78, 0x03C8) /* GREEK SMALL LETTER PSI */ \ UNI(0x79, 0x03C9) /* GREEK SMALL LETTER OMEGA */ \ UNI(0x7A, 0x03CA) /* GREEK SMALL LETTER IOTA WITH DIALYTIKA */ \ UNI(0x7B, 0x03CB) /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ \ UNI(0x7C, 0x03CC) /* GREEK SMALL LETTER OMICRON WITH TONOS */ \ UNI(0x7D, 0x03CD) /* GREEK SMALL LETTER UPSILON WITH TONOS */ \ UNI(0x7E, 0x03CE) /* GREEK SMALL LETTER OMEGA WITH TONOS */ \ XXX(0x7F, UNDEF) /* undefined */ \ } \ end_CODEPAGE() #define unmap_ISO_Greek_Supp(code,dft) \ switch (code) { \ MAP(0x21, 0x60) /* LEFT SINGLE QUOTATION MARK */ \ MAP(0x22, 0x27) /* RIGHT SINGLE QUOTATION MARK */ \ MAP(0x24, 0x1B) /* undefined */ \ MAP(0x25, 0x1B) /* undefined */ \ MAP(0x2A, 0x1B) /* undefined */ \ MAP(0x2E, 0x1B) /* undefined */ \ MAP(0x2F, 0x2D) /* HORIZONTAL BAR */ \ MAP(0x34, 0x96) /* GREEK TONOS */ \ MAP(0x35, 0x95) /* GREEK DIALYTIKA TONOS */ \ MAP(0x36, 0x6E) /* GREEK CAPITAL LETTER ALPHA WITH TONOS */ \ MAP(0x38, 0x6F) /* GREEK CAPITAL LETTER EPSILON WITH TONOS */ \ MAP(0x39, 0x70) /* GREEK CAPITAL LETTER ETA WITH TONOS */ \ MAP(0x3A, 0x71) /* GREEK CAPITAL LETTER IOTA WITH TONOS */ \ MAP(0x3C, 0x72) /* GREEK CAPITAL LETTER OMICRON WITH TONOS */ \ MAP(0x3E, 0x73) /* GREEK CAPITAL LETTER UPSILON WITH TONOS */ \ MAP(0x3F, 0x74) /* GREEK CAPITAL LETTER OMEGA WITH TONOS */ \ MAP(0x40, 0x75) /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ \ MAP(0x41, 0x76) /* GREEK CAPITAL LETTER ALPHA */ \ MAP(0x42, 0x77) /* GREEK CAPITAL LETTER BETA */ \ MAP(0x43, 0x78) /* GREEK CAPITAL LETTER GAMMA */ \ MAP(0x44, 0x79) /* GREEK CAPITAL LETTER DELTA */ \ MAP(0x45, 0x7A) /* GREEK CAPITAL LETTER EPSILON */ \ MAP(0x46, 0x7B) /* GREEK CAPITAL LETTER ZETA */ \ MAP(0x47, 0x7C) /* GREEK CAPITAL LETTER ETA */ \ MAP(0x48, 0x7D) /* GREEK CAPITAL LETTER THETA */ \ MAP(0x49, 0x7E) /* GREEK CAPITAL LETTER IOTA */ \ MAP(0x4A, 0x7F) /* GREEK CAPITAL LETTER KAPPA */ \ MAP(0x4B, 0xA2) /* GREEK CAPITAL LETTER LAMDA */ \ MAP(0x4C, 0xA3) /* GREEK CAPITAL LETTER MU */ \ MAP(0x4D, 0xA4) /* GREEK CAPITAL LETTER NU */ \ MAP(0x4E, 0xA5) /* GREEK CAPITAL LETTER XI */ \ MAP(0x4F, 0xA6) /* GREEK CAPITAL LETTER OMICRON */ \ MAP(0x50, 0xA7) /* GREEK CAPITAL LETTER PI */ \ MAP(0x51, 0xA8) /* GREEK CAPITAL LETTER RHO */ \ MAP(0x52, 0x1B) /* undefined */ \ MAP(0x53, 0xA9) /* GREEK CAPITAL LETTER SIGMA */ \ MAP(0x54, 0xAA) /* GREEK CAPITAL LETTER TAU */ \ MAP(0x55, 0xAB) /* GREEK CAPITAL LETTER UPSILON */ \ MAP(0x56, 0xAC) /* GREEK CAPITAL LETTER PHI */ \ MAP(0x57, 0xAD) /* GREEK CAPITAL LETTER CHI */ \ MAP(0x58, 0xAE) /* GREEK CAPITAL LETTER PSI */ \ MAP(0x59, 0xAF) /* GREEK CAPITAL LETTER OMEGA */ \ MAP(0x5A, 0xB0) /* GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ \ MAP(0x5B, 0xB1) /* GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ \ MAP(0x5C, 0xB2) /* GREEK SMALL LETTER ALPHA WITH TONOS */ \ MAP(0x5D, 0xB3) /* GREEK SMALL LETTER EPSILON WITH TONOS */ \ MAP(0x5E, 0xB4) /* GREEK SMALL LETTER ETA WITH TONOS */ \ MAP(0x5F, 0xB5) /* GREEK SMALL LETTER IOTA WITH TONOS */ \ MAP(0x60, 0xB6) /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ \ MAP(0x61, 0xB7) /* GREEK SMALL LETTER ALPHA */ \ MAP(0x62, 0xB8) /* GREEK SMALL LETTER BETA */ \ MAP(0x63, 0xB9) /* GREEK SMALL LETTER GAMMA */ \ MAP(0x64, 0xBA) /* GREEK SMALL LETTER DELTA */ \ MAP(0x65, 0xBB) /* GREEK SMALL LETTER EPSILON */ \ MAP(0x66, 0xBC) /* GREEK SMALL LETTER ZETA */ \ MAP(0x67, 0xBD) /* GREEK SMALL LETTER ETA */ \ MAP(0x68, 0xBE) /* GREEK SMALL LETTER THETA */ \ MAP(0x69, 0xBF) /* GREEK SMALL LETTER IOTA */ \ MAP(0x6A, 0xC0) /* GREEK SMALL LETTER KAPPA */ \ MAP(0x6B, 0xC1) /* GREEK SMALL LETTER LAMDA */ \ MAP(0x6C, 0xC2) /* GREEK SMALL LETTER MU */ \ MAP(0x6D, 0xC3) /* GREEK SMALL LETTER NU */ \ MAP(0x6E, 0xC4) /* GREEK SMALL LETTER XI */ \ MAP(0x6F, 0xC5) /* GREEK SMALL LETTER OMICRON */ \ MAP(0x70, 0xC6) /* GREEK SMALL LETTER PI */ \ MAP(0x71, 0xC7) /* GREEK SMALL LETTER RHO */ \ MAP(0x72, 0xC8) /* GREEK SMALL LETTER FINAL SIGMA */ \ MAP(0x73, 0xC9) /* GREEK SMALL LETTER SIGMA */ \ MAP(0x74, 0xCA) /* GREEK SMALL LETTER TAU */ \ MAP(0x75, 0xCB) /* GREEK SMALL LETTER UPSILON */ \ MAP(0x76, 0xCC) /* GREEK SMALL LETTER PHI */ \ MAP(0x77, 0xCD) /* GREEK SMALL LETTER CHI */ \ MAP(0x78, 0xCE) /* GREEK SMALL LETTER PSI */ \ MAP(0x79, 0xCF) /* GREEK SMALL LETTER OMEGA */ \ MAP(0x7A, 0xD0) /* GREEK SMALL LETTER IOTA WITH DIALYTIKA */ \ MAP(0x7B, 0xD1) /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ \ MAP(0x7C, 0xD2) /* GREEK SMALL LETTER OMICRON WITH TONOS */ \ MAP(0x7D, 0xD3) /* GREEK SMALL LETTER UPSILON WITH TONOS */ \ MAP(0x7E, 0xD4) /* GREEK SMALL LETTER OMEGA WITH TONOS */ \ MAP(0x7F, 0x1B) /* undefined */ \ default: dft; break; \ } /* * figure A-23 "ISO Latin-Hebrew Supplemental Character Set" */ #define map_ISO_Hebrew(code) \ begin_CODEPAGE(96) \ switch (code) { \ UNI(0x20, 0x00A0) /* NO-BREAK SPACE */ \ XXX(0x21, UNDEF) /* undefined */ \ UNI(0x22, 0x00A2) /* CENT SIGN */ \ UNI(0x23, 0x00A3) /* POUND SIGN */ \ UNI(0x24, 0x00A4) /* CURRENCY SIGN */ \ UNI(0x25, 0x00A5) /* YEN SIGN */ \ UNI(0x26, 0x00A6) /* BROKEN BAR */ \ UNI(0x27, 0x00A7) /* SECTION SIGN */ \ UNI(0x28, 0x00A8) /* DIAERESIS */ \ UNI(0x29, 0x00A9) /* COPYRIGHT SIGN */ \ UNI(0x2A, 0x00D7) /* MULTIPLICATION SIGN */ \ UNI(0x2B, 0x00AB) /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ UNI(0x2C, 0x00AC) /* NOT SIGN */ \ UNI(0x2D, 0x00AD) /* SOFT HYPHEN */ \ UNI(0x2E, 0x00AE) /* REGISTERED SIGN */ \ UNI(0x2F, 0x00AF) /* MACRON */ \ UNI(0x30, 0x00B0) /* DEGREE SIGN */ \ UNI(0x31, 0x00B1) /* PLUS-MINUS SIGN */ \ UNI(0x32, 0x00B2) /* SUPERSCRIPT TWO */ \ UNI(0x33, 0x00B3) /* SUPERSCRIPT THREE */ \ UNI(0x34, 0x00B4) /* ACUTE ACCENT */ \ UNI(0x35, 0x00B5) /* MICRO SIGN */ \ UNI(0x36, 0x00B6) /* PILCROW SIGN */ \ UNI(0x37, 0x00B7) /* MIDDLE DOT */ \ UNI(0x38, 0x00B8) /* CEDILLA */ \ UNI(0x39, 0x00B9) /* SUPERSCRIPT ONE */ \ UNI(0x3A, 0x00F7) /* DIVISION SIGN */ \ UNI(0x3B, 0x00BB) /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ UNI(0x3C, 0x00BC) /* VULGAR FRACTION ONE QUARTER */ \ UNI(0x3D, 0x00BD) /* VULGAR FRACTION ONE HALF */ \ UNI(0x3E, 0x00BE) /* VULGAR FRACTION THREE QUARTERS */ \ XXX(0x3F, UNDEF) /* undefined */ \ XXX(0x40, UNDEF) /* undefined */ \ XXX(0x41, UNDEF) /* undefined */ \ XXX(0x42, UNDEF) /* undefined */ \ XXX(0x43, UNDEF) /* undefined */ \ XXX(0x44, UNDEF) /* undefined */ \ XXX(0x45, UNDEF) /* undefined */ \ XXX(0x46, UNDEF) /* undefined */ \ XXX(0x47, UNDEF) /* undefined */ \ XXX(0x48, UNDEF) /* undefined */ \ XXX(0x49, UNDEF) /* undefined */ \ XXX(0x4A, UNDEF) /* undefined */ \ XXX(0x4B, UNDEF) /* undefined */ \ XXX(0x4C, UNDEF) /* undefined */ \ XXX(0x4D, UNDEF) /* undefined */ \ XXX(0x4E, UNDEF) /* undefined */ \ XXX(0x4F, UNDEF) /* undefined */ \ XXX(0x50, UNDEF) /* undefined */ \ XXX(0x51, UNDEF) /* undefined */ \ XXX(0x52, UNDEF) /* undefined */ \ XXX(0x53, UNDEF) /* undefined */ \ XXX(0x54, UNDEF) /* undefined */ \ XXX(0x55, UNDEF) /* undefined */ \ XXX(0x56, UNDEF) /* undefined */ \ XXX(0x57, UNDEF) /* undefined */ \ XXX(0x58, UNDEF) /* undefined */ \ XXX(0x59, UNDEF) /* undefined */ \ XXX(0x5A, UNDEF) /* undefined */ \ XXX(0x5B, UNDEF) /* undefined */ \ XXX(0x5C, UNDEF) /* undefined */ \ XXX(0x5D, UNDEF) /* undefined */ \ XXX(0x5E, UNDEF) /* undefined */ \ UNI(0x5F, 0x2017) /* DOUBLE LOW LINE */ \ UNI(0x60, 0x05D0) /* HEBREW LETTER ALEF */ \ UNI(0x61, 0x05D1) /* HEBREW LETTER BET */ \ UNI(0x62, 0x05D2) /* HEBREW LETTER GIMEL */ \ UNI(0x63, 0x05D3) /* HEBREW LETTER DALET */ \ UNI(0x64, 0x05D4) /* HEBREW LETTER HE */ \ UNI(0x65, 0x05D5) /* HEBREW LETTER VAV */ \ UNI(0x66, 0x05D6) /* HEBREW LETTER ZAYIN */ \ UNI(0x67, 0x05D7) /* HEBREW LETTER HET */ \ UNI(0x68, 0x05D8) /* HEBREW LETTER TET */ \ UNI(0x69, 0x05D9) /* HEBREW LETTER YOD */ \ UNI(0x6A, 0x05DA) /* HEBREW LETTER FINAL KAF */ \ UNI(0x6B, 0x05DB) /* HEBREW LETTER KAF */ \ UNI(0x6C, 0x05DC) /* HEBREW LETTER LAMED */ \ UNI(0x6D, 0x05DD) /* HEBREW LETTER FINAL MEM */ \ UNI(0x6E, 0x05DE) /* HEBREW LETTER MEM */ \ UNI(0x6F, 0x05DF) /* HEBREW LETTER FINAL NUN */ \ UNI(0x70, 0x05E0) /* HEBREW LETTER NUN */ \ UNI(0x71, 0x05E1) /* HEBREW LETTER SAMEKH */ \ UNI(0x72, 0x05E2) /* HEBREW LETTER AYIN */ \ UNI(0x73, 0x05E3) /* HEBREW LETTER FINAL PE */ \ UNI(0x74, 0x05E4) /* HEBREW LETTER PE */ \ UNI(0x75, 0x05E5) /* HEBREW LETTER FINAL TSADI */ \ UNI(0x76, 0x05E6) /* HEBREW LETTER TSADI */ \ UNI(0x77, 0x05E7) /* HEBREW LETTER QOF */ \ UNI(0x78, 0x05E8) /* HEBREW LETTER RESH */ \ UNI(0x79, 0x05E9) /* HEBREW LETTER SHIN */ \ UNI(0x7A, 0x05EA) /* HEBREW LETTER TAV */ \ XXX(0x7B, UNDEF) /* undefined */ \ XXX(0x7C, UNDEF) /* undefined */ \ XXX(0x7D, UNDEF) /* undefined */ \ XXX(0x7E, UNDEF) /* undefined */ \ XXX(0x7F, UNDEF) /* undefined */ \ } \ end_CODEPAGE() #define unmap_ISO_Hebrew(code,dft) \ switch (code) { \ MAP(0x21, 0x1B) /* undefined */ \ MAP(0x2A, 0xD7) /* MULTIPLICATION SIGN */ \ MAP(0x3A, 0xF7) /* DIVISION SIGN */ \ MAP(0x3F, 0x1B) /* undefined */ \ MAP(0x40, 0x1B) /* undefined */ \ MAP(0x41, 0x1B) /* undefined */ \ MAP(0x42, 0x1B) /* undefined */ \ MAP(0x43, 0x1B) /* undefined */ \ MAP(0x44, 0x1B) /* undefined */ \ MAP(0x45, 0x1B) /* undefined */ \ MAP(0x46, 0x1B) /* undefined */ \ MAP(0x47, 0x1B) /* undefined */ \ MAP(0x48, 0x1B) /* undefined */ \ MAP(0x49, 0x1B) /* undefined */ \ MAP(0x4A, 0x1B) /* undefined */ \ MAP(0x4B, 0x1B) /* undefined */ \ MAP(0x4C, 0x1B) /* undefined */ \ MAP(0x4D, 0x1B) /* undefined */ \ MAP(0x4E, 0x1B) /* undefined */ \ MAP(0x4F, 0x1B) /* undefined */ \ MAP(0x50, 0x1B) /* undefined */ \ MAP(0x51, 0x1B) /* undefined */ \ MAP(0x52, 0x1B) /* undefined */ \ MAP(0x53, 0x1B) /* undefined */ \ MAP(0x54, 0x1B) /* undefined */ \ MAP(0x55, 0x1B) /* undefined */ \ MAP(0x56, 0x1B) /* undefined */ \ MAP(0x57, 0x1B) /* undefined */ \ MAP(0x58, 0x1B) /* undefined */ \ MAP(0x59, 0x1B) /* undefined */ \ MAP(0x5A, 0x1B) /* undefined */ \ MAP(0x5B, 0x1B) /* undefined */ \ MAP(0x5C, 0x1B) /* undefined */ \ MAP(0x5D, 0x1B) /* undefined */ \ MAP(0x5E, 0x1B) /* undefined */ \ MAP(0x5F, 0x52) /* DOUBLE LOW LINE */ \ MAP(0x60, 0x53) /* HEBREW LETTER ALEF */ \ MAP(0x61, 0x54) /* HEBREW LETTER BET */ \ MAP(0x62, 0x55) /* HEBREW LETTER GIMEL */ \ MAP(0x63, 0x56) /* HEBREW LETTER DALET */ \ MAP(0x64, 0x57) /* HEBREW LETTER HE */ \ MAP(0x65, 0x58) /* HEBREW LETTER VAV */ \ MAP(0x66, 0x59) /* HEBREW LETTER ZAYIN */ \ MAP(0x67, 0x5A) /* HEBREW LETTER HET */ \ MAP(0x68, 0x5B) /* HEBREW LETTER TET */ \ MAP(0x69, 0x5C) /* HEBREW LETTER YOD */ \ MAP(0x6A, 0x5D) /* HEBREW LETTER FINAL KAF */ \ MAP(0x6B, 0x5E) /* HEBREW LETTER KAF */ \ MAP(0x6C, 0x5F) /* HEBREW LETTER LAMED */ \ MAP(0x6D, 0x60) /* HEBREW LETTER FINAL MEM */ \ MAP(0x6E, 0x61) /* HEBREW LETTER MEM */ \ MAP(0x6F, 0x62) /* HEBREW LETTER FINAL NUN */ \ MAP(0x70, 0x63) /* HEBREW LETTER NUN */ \ MAP(0x71, 0x64) /* HEBREW LETTER SAMEKH */ \ MAP(0x72, 0x65) /* HEBREW LETTER AYIN */ \ MAP(0x73, 0x66) /* HEBREW LETTER FINAL PE */ \ MAP(0x74, 0x67) /* HEBREW LETTER PE */ \ MAP(0x75, 0x68) /* HEBREW LETTER FINAL TSADI */ \ MAP(0x76, 0x69) /* HEBREW LETTER TSADI */ \ MAP(0x77, 0x6A) /* HEBREW LETTER QOF */ \ MAP(0x78, 0x6B) /* HEBREW LETTER RESH */ \ MAP(0x79, 0x6C) /* HEBREW LETTER SHIN */ \ MAP(0x7A, 0x6D) /* HEBREW LETTER TAV */ \ MAP(0x7B, 0x1B) /* undefined */ \ MAP(0x7C, 0x1B) /* undefined */ \ MAP(0x7D, 0x1B) /* undefined */ \ MAP(0x7E, 0x1B) /* undefined */ \ MAP(0x7F, 0x1B) /* undefined */ \ default: dft; break; \ } /* * ISO Latin-2 is 8859-2 */ #define map_ISO_Latin_2(code) \ begin_CODEPAGE(96) \ switch (code) { \ UNI(0x20, 0x00A0) /* NO-BREAK SPACE */ \ UNI(0x21, 0x0104) /* LATIN CAPITAL LETTER A WITH OGONEK */ \ UNI(0x22, 0x02D8) /* BREVE */ \ UNI(0x23, 0x0141) /* LATIN CAPITAL LETTER L WITH STROKE */ \ UNI(0x24, 0x00A4) /* CURRENCY SIGN */ \ UNI(0x25, 0x013D) /* LATIN CAPITAL LETTER L WITH CARON */ \ UNI(0x26, 0x015A) /* LATIN CAPITAL LETTER S WITH ACUTE */ \ UNI(0x27, 0x00A7) /* SECTION SIGN */ \ UNI(0x28, 0x00A8) /* DIAERESIS */ \ UNI(0x29, 0x0160) /* LATIN CAPITAL LETTER S WITH CARON */ \ UNI(0x2A, 0x015E) /* LATIN CAPITAL LETTER S WITH CEDILLA */ \ UNI(0x2B, 0x0164) /* LATIN CAPITAL LETTER T WITH CARON */ \ UNI(0x2C, 0x0179) /* LATIN CAPITAL LETTER Z WITH ACUTE */ \ UNI(0x2D, 0x00AD) /* SOFT HYPHEN */ \ UNI(0x2E, 0x017D) /* LATIN CAPITAL LETTER Z WITH CARON */ \ UNI(0x2F, 0x017B) /* LATIN CAPITAL LETTER Z WITH DOT ABOVE */ \ UNI(0x30, 0x00B0) /* DEGREE SIGN */ \ UNI(0x31, 0x0105) /* LATIN SMALL LETTER A WITH OGONEK */ \ UNI(0x32, 0x02DB) /* OGONEK */ \ UNI(0x33, 0x0142) /* LATIN SMALL LETTER L WITH STROKE */ \ UNI(0x34, 0x00B4) /* ACUTE ACCENT */ \ UNI(0x35, 0x013E) /* LATIN SMALL LETTER L WITH CARON */ \ UNI(0x36, 0x015B) /* LATIN SMALL LETTER S WITH ACUTE */ \ UNI(0x37, 0x02C7) /* CARON */ \ UNI(0x38, 0x00B8) /* CEDILLA */ \ UNI(0x39, 0x0161) /* LATIN SMALL LETTER S WITH CARON */ \ UNI(0x3A, 0x015F) /* LATIN SMALL LETTER S WITH CEDILLA */ \ UNI(0x3B, 0x0165) /* LATIN SMALL LETTER T WITH CARON */ \ UNI(0x3C, 0x017A) /* LATIN SMALL LETTER Z WITH ACUTE */ \ UNI(0x3D, 0x02DD) /* DOUBLE ACUTE ACCENT */ \ UNI(0x3E, 0x017E) /* LATIN SMALL LETTER Z WITH CARON */ \ UNI(0x3F, 0x017C) /* LATIN SMALL LETTER Z WITH DOT ABOVE */ \ UNI(0x40, 0x0154) /* LATIN CAPITAL LETTER R WITH ACUTE */ \ UNI(0x41, 0x00C1) /* LATIN CAPITAL LETTER A WITH ACUTE */ \ UNI(0x42, 0x00C2) /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ \ UNI(0x43, 0x0102) /* LATIN CAPITAL LETTER A WITH BREVE */ \ UNI(0x44, 0x00C4) /* LATIN CAPITAL LETTER A WITH DIAERESIS */ \ UNI(0x45, 0x0139) /* LATIN CAPITAL LETTER L WITH ACUTE */ \ UNI(0x46, 0x0106) /* LATIN CAPITAL LETTER C WITH ACUTE */ \ UNI(0x47, 0x00C7) /* LATIN CAPITAL LETTER C WITH CEDILLA */ \ UNI(0x48, 0x010C) /* LATIN CAPITAL LETTER C WITH CARON */ \ UNI(0x49, 0x00C9) /* LATIN CAPITAL LETTER E WITH ACUTE */ \ UNI(0x4A, 0x0118) /* LATIN CAPITAL LETTER E WITH OGONEK */ \ UNI(0x4B, 0x00CB) /* LATIN CAPITAL LETTER E WITH DIAERESIS */ \ UNI(0x4C, 0x011A) /* LATIN CAPITAL LETTER E WITH CARON */ \ UNI(0x4D, 0x00CD) /* LATIN CAPITAL LETTER I WITH ACUTE */ \ UNI(0x4E, 0x00CE) /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ \ UNI(0x4F, 0x010E) /* LATIN CAPITAL LETTER D WITH CARON */ \ UNI(0x50, 0x0110) /* LATIN CAPITAL LETTER D WITH STROKE */ \ UNI(0x51, 0x0143) /* LATIN CAPITAL LETTER N WITH ACUTE */ \ UNI(0x52, 0x0147) /* LATIN CAPITAL LETTER N WITH CARON */ \ UNI(0x53, 0x00D3) /* LATIN CAPITAL LETTER O WITH ACUTE */ \ UNI(0x54, 0x00D4) /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ \ UNI(0x55, 0x0150) /* LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ \ UNI(0x56, 0x00D6) /* LATIN CAPITAL LETTER O WITH DIAERESIS */ \ UNI(0x57, 0x00D7) /* MULTIPLICATION SIGN */ \ UNI(0x58, 0x0158) /* LATIN CAPITAL LETTER R WITH CARON */ \ UNI(0x59, 0x016E) /* LATIN CAPITAL LETTER U WITH RING ABOVE */ \ UNI(0x5A, 0x00DA) /* LATIN CAPITAL LETTER U WITH ACUTE */ \ UNI(0x5B, 0x0170) /* LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ \ UNI(0x5C, 0x00DC) /* LATIN CAPITAL LETTER U WITH DIAERESIS */ \ UNI(0x5D, 0x00DD) /* LATIN CAPITAL LETTER Y WITH ACUTE */ \ UNI(0x5E, 0x0162) /* LATIN CAPITAL LETTER T WITH CEDILLA */ \ UNI(0x5F, 0x00DF) /* LATIN SMALL LETTER SHARP S */ \ UNI(0x60, 0x0155) /* LATIN SMALL LETTER R WITH ACUTE */ \ UNI(0x61, 0x00E1) /* LATIN SMALL LETTER A WITH ACUTE */ \ UNI(0x62, 0x00E2) /* LATIN SMALL LETTER A WITH CIRCUMFLEX */ \ UNI(0x63, 0x0103) /* LATIN SMALL LETTER A WITH BREVE */ \ UNI(0x64, 0x00E4) /* LATIN SMALL LETTER A WITH DIAERESIS */ \ UNI(0x65, 0x013A) /* LATIN SMALL LETTER L WITH ACUTE */ \ UNI(0x66, 0x0107) /* LATIN SMALL LETTER C WITH ACUTE */ \ UNI(0x67, 0x00E7) /* LATIN SMALL LETTER C WITH CEDILLA */ \ UNI(0x68, 0x010D) /* LATIN SMALL LETTER C WITH CARON */ \ UNI(0x69, 0x00E9) /* LATIN SMALL LETTER E WITH ACUTE */ \ UNI(0x6A, 0x0119) /* LATIN SMALL LETTER E WITH OGONEK */ \ UNI(0x6B, 0x00EB) /* LATIN SMALL LETTER E WITH DIAERESIS */ \ UNI(0x6C, 0x011B) /* LATIN SMALL LETTER E WITH CARON */ \ UNI(0x6D, 0x00ED) /* LATIN SMALL LETTER I WITH ACUTE */ \ UNI(0x6E, 0x00EE) /* LATIN SMALL LETTER I WITH CIRCUMFLEX */ \ UNI(0x6F, 0x010F) /* LATIN SMALL LETTER D WITH CARON */ \ UNI(0x70, 0x0111) /* LATIN SMALL LETTER D WITH STROKE */ \ UNI(0x71, 0x0144) /* LATIN SMALL LETTER N WITH ACUTE */ \ UNI(0x72, 0x0148) /* LATIN SMALL LETTER N WITH CARON */ \ UNI(0x73, 0x00F3) /* LATIN SMALL LETTER O WITH ACUTE */ \ UNI(0x74, 0x00F4) /* LATIN SMALL LETTER O WITH CIRCUMFLEX */ \ UNI(0x75, 0x0151) /* LATIN SMALL LETTER O WITH DOUBLE ACUTE */ \ UNI(0x76, 0x00F6) /* LATIN SMALL LETTER O WITH DIAERESIS */ \ UNI(0x77, 0x00F7) /* DIVISION SIGN */ \ UNI(0x78, 0x0159) /* LATIN SMALL LETTER R WITH CARON */ \ UNI(0x79, 0x016F) /* LATIN SMALL LETTER U WITH RING ABOVE */ \ UNI(0x7A, 0x00FA) /* LATIN SMALL LETTER U WITH ACUTE */ \ UNI(0x7B, 0x0171) /* LATIN SMALL LETTER U WITH DOUBLE ACUTE */ \ UNI(0x7C, 0x00FC) /* LATIN SMALL LETTER U WITH DIAERESIS */ \ UNI(0x7D, 0x00FD) /* LATIN SMALL LETTER Y WITH ACUTE */ \ UNI(0x7E, 0x0163) /* LATIN SMALL LETTER T WITH CEDILLA */ \ UNI(0x7F, 0x02D9) /* DOT ABOVE */ \ } \ end_CODEPAGE() #define unmap_ISO_Latin_2(code,dft) \ switch (code) { \ MAP(0x21, 0x9A) /* LATIN CAPITAL LETTER A WITH OGONEK */ \ MAP(0x22, 0x90) /* BREVE */ \ MAP(0x23, 0x9B) /* LATIN CAPITAL LETTER L WITH STROKE */ \ MAP(0x25, 0x9C) /* LATIN CAPITAL LETTER L WITH CARON */ \ MAP(0x26, 0x9D) /* LATIN CAPITAL LETTER S WITH ACUTE */ \ MAP(0x29, 0x9E) /* LATIN CAPITAL LETTER S WITH CARON */ \ MAP(0x2A, 0x9F) /* LATIN CAPITAL LETTER S WITH CEDILLA */ \ MAP(0x2B, 0x21) /* LATIN CAPITAL LETTER T WITH CARON */ \ MAP(0x2C, 0x22) /* LATIN CAPITAL LETTER Z WITH ACUTE */ \ MAP(0x2E, 0x23) /* LATIN CAPITAL LETTER Z WITH CARON */ \ MAP(0x2F, 0x24) /* LATIN CAPITAL LETTER Z WITH DOT ABOVE */ \ MAP(0x31, 0x25) /* LATIN SMALL LETTER A WITH OGONEK */ \ MAP(0x32, 0x91) /* OGONEK */ \ MAP(0x33, 0x26) /* LATIN SMALL LETTER L WITH STROKE */ \ MAP(0x35, 0x27) /* LATIN SMALL LETTER L WITH CARON */ \ MAP(0x36, 0x28) /* LATIN SMALL LETTER S WITH ACUTE */ \ MAP(0x37, 0x92) /* CARON */ \ MAP(0x39, 0x29) /* LATIN SMALL LETTER S WITH CARON */ \ MAP(0x3A, 0x2A) /* LATIN SMALL LETTER S WITH CEDILLA */ \ MAP(0x3B, 0x2B) /* LATIN SMALL LETTER T WITH CARON */ \ MAP(0x3C, 0x2C) /* LATIN SMALL LETTER Z WITH ACUTE */ \ MAP(0x3D, 0x93) /* DOUBLE ACUTE ACCENT */ \ MAP(0x3E, 0x2D) /* LATIN SMALL LETTER Z WITH CARON */ \ MAP(0x3F, 0x2E) /* LATIN SMALL LETTER Z WITH DOT ABOVE */ \ MAP(0x40, 0x2F) /* LATIN CAPITAL LETTER R WITH ACUTE */ \ MAP(0x43, 0x30) /* LATIN CAPITAL LETTER A WITH BREVE */ \ MAP(0x45, 0x31) /* LATIN CAPITAL LETTER L WITH ACUTE */ \ MAP(0x46, 0x32) /* LATIN CAPITAL LETTER C WITH ACUTE */ \ MAP(0x48, 0x33) /* LATIN CAPITAL LETTER C WITH CARON */ \ MAP(0x4A, 0x34) /* LATIN CAPITAL LETTER E WITH OGONEK */ \ MAP(0x4C, 0x35) /* LATIN CAPITAL LETTER E WITH CARON */ \ MAP(0x4F, 0x36) /* LATIN CAPITAL LETTER D WITH CARON */ \ MAP(0x51, 0x37) /* LATIN CAPITAL LETTER N WITH ACUTE */ \ MAP(0x52, 0x38) /* LATIN CAPITAL LETTER N WITH CARON */ \ MAP(0x55, 0x39) /* LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ \ MAP(0x58, 0x3A) /* LATIN CAPITAL LETTER R WITH CARON */ \ MAP(0x59, 0x3B) /* LATIN CAPITAL LETTER U WITH RING ABOVE */ \ MAP(0x5B, 0x3C) /* LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ \ MAP(0x5E, 0x3D) /* LATIN CAPITAL LETTER T WITH CEDILLA */ \ MAP(0x60, 0x3E) /* LATIN SMALL LETTER R WITH ACUTE */ \ MAP(0x63, 0x3F) /* LATIN SMALL LETTER A WITH BREVE */ \ MAP(0x65, 0x40) /* LATIN SMALL LETTER L WITH ACUTE */ \ MAP(0x66, 0x41) /* LATIN SMALL LETTER C WITH ACUTE */ \ MAP(0x68, 0x42) /* LATIN SMALL LETTER C WITH CARON */ \ MAP(0x6A, 0x43) /* LATIN SMALL LETTER E WITH OGONEK */ \ MAP(0x6C, 0x44) /* LATIN SMALL LETTER E WITH CARON */ \ MAP(0x6F, 0x45) /* LATIN SMALL LETTER D WITH CARON */ \ MAP(0x70, 0x46) /* LATIN SMALL LETTER D WITH STROKE */ \ MAP(0x71, 0x47) /* LATIN SMALL LETTER N WITH ACUTE */ \ MAP(0x72, 0x48) /* LATIN SMALL LETTER N WITH CARON */ \ MAP(0x75, 0x49) /* LATIN SMALL LETTER O WITH DOUBLE ACUTE */ \ MAP(0x78, 0x4A) /* LATIN SMALL LETTER R WITH CARON */ \ MAP(0x79, 0x4B) /* LATIN SMALL LETTER U WITH RING ABOVE */ \ MAP(0x7B, 0x4C) /* LATIN SMALL LETTER U WITH DOUBLE ACUTE */ \ MAP(0x7E, 0x4D) /* LATIN SMALL LETTER T WITH CEDILLA */ \ MAP(0x7F, 0x94) /* DOT ABOVE */ \ default: dft; break; \ } /* * ISO Latin-5 is 8859-9 */ #define map_ISO_Latin_5(code) \ begin_CODEPAGE(96) \ switch (code) { \ UNI(0x20, 0x00A0) /* NO-BREAK SPACE */ \ UNI(0x21, 0x00A1) /* INVERTED EXCLAMATION MARK */ \ UNI(0x22, 0x00A2) /* CENT SIGN */ \ UNI(0x23, 0x00A3) /* POUND SIGN */ \ UNI(0x24, 0x00A4) /* CURRENCY SIGN */ \ UNI(0x25, 0x00A5) /* YEN SIGN */ \ UNI(0x26, 0x00A6) /* BROKEN BAR */ \ UNI(0x27, 0x00A7) /* SECTION SIGN */ \ UNI(0x28, 0x00A8) /* DIAERESIS */ \ UNI(0x29, 0x00A9) /* COPYRIGHT SIGN */ \ UNI(0x2A, 0x00AA) /* FEMININE ORDINAL INDICATOR */ \ UNI(0x2B, 0x00AB) /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ UNI(0x2C, 0x00AC) /* NOT SIGN */ \ UNI(0x2D, 0x00AD) /* SOFT HYPHEN */ \ UNI(0x2E, 0x00AE) /* REGISTERED SIGN */ \ UNI(0x2F, 0x00AF) /* MACRON */ \ UNI(0x30, 0x00B0) /* DEGREE SIGN */ \ UNI(0x31, 0x00B1) /* PLUS-MINUS SIGN */ \ UNI(0x32, 0x00B2) /* SUPERSCRIPT TWO */ \ UNI(0x33, 0x00B3) /* SUPERSCRIPT THREE */ \ UNI(0x34, 0x00B4) /* ACUTE ACCENT */ \ UNI(0x35, 0x00B5) /* MICRO SIGN */ \ UNI(0x36, 0x00B6) /* PILCROW SIGN */ \ UNI(0x37, 0x00B7) /* MIDDLE DOT */ \ UNI(0x38, 0x00B8) /* CEDILLA */ \ UNI(0x39, 0x00B9) /* SUPERSCRIPT ONE */ \ UNI(0x3A, 0x00BA) /* MASCULINE ORDINAL INDICATOR */ \ UNI(0x3B, 0x00BB) /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ UNI(0x3C, 0x00BC) /* VULGAR FRACTION ONE QUARTER */ \ UNI(0x3D, 0x00BD) /* VULGAR FRACTION ONE HALF */ \ UNI(0x3E, 0x00BE) /* VULGAR FRACTION THREE QUARTERS */ \ UNI(0x3F, 0x00BF) /* INVERTED QUESTION MARK */ \ UNI(0x40, 0x00C0) /* LATIN CAPITAL LETTER A WITH GRAVE */ \ UNI(0x41, 0x00C1) /* LATIN CAPITAL LETTER A WITH ACUTE */ \ UNI(0x42, 0x00C2) /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ \ UNI(0x43, 0x00C3) /* LATIN CAPITAL LETTER A WITH TILDE */ \ UNI(0x44, 0x00C4) /* LATIN CAPITAL LETTER A WITH DIAERESIS */ \ UNI(0x45, 0x00C5) /* LATIN CAPITAL LETTER A WITH RING ABOVE */ \ UNI(0x46, 0x00C6) /* LATIN CAPITAL LETTER AE */ \ UNI(0x47, 0x00C7) /* LATIN CAPITAL LETTER C WITH CEDILLA */ \ UNI(0x48, 0x00C8) /* LATIN CAPITAL LETTER E WITH GRAVE */ \ UNI(0x49, 0x00C9) /* LATIN CAPITAL LETTER E WITH ACUTE */ \ UNI(0x4A, 0x00CA) /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ \ UNI(0x4B, 0x00CB) /* LATIN CAPITAL LETTER E WITH DIAERESIS */ \ UNI(0x4C, 0x00CC) /* LATIN CAPITAL LETTER I WITH GRAVE */ \ UNI(0x4D, 0x00CD) /* LATIN CAPITAL LETTER I WITH ACUTE */ \ UNI(0x4E, 0x00CE) /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ \ UNI(0x4F, 0x00CF) /* LATIN CAPITAL LETTER I WITH DIAERESIS */ \ UNI(0x50, 0x011E) /* LATIN CAPITAL LETTER G WITH BREVE */ \ UNI(0x51, 0x00D1) /* LATIN CAPITAL LETTER N WITH TILDE */ \ UNI(0x52, 0x00D2) /* LATIN CAPITAL LETTER O WITH GRAVE */ \ UNI(0x53, 0x00D3) /* LATIN CAPITAL LETTER O WITH ACUTE */ \ UNI(0x54, 0x00D4) /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ \ UNI(0x55, 0x00D5) /* LATIN CAPITAL LETTER O WITH TILDE */ \ UNI(0x56, 0x00D6) /* LATIN CAPITAL LETTER O WITH DIAERESIS */ \ UNI(0x57, 0x00D7) /* MULTIPLICATION SIGN */ \ UNI(0x58, 0x00D8) /* LATIN CAPITAL LETTER O WITH STROKE */ \ UNI(0x59, 0x00D9) /* LATIN CAPITAL LETTER U WITH GRAVE */ \ UNI(0x5A, 0x00DA) /* LATIN CAPITAL LETTER U WITH ACUTE */ \ UNI(0x5B, 0x00DB) /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ \ UNI(0x5C, 0x00DC) /* LATIN CAPITAL LETTER U WITH DIAERESIS */ \ UNI(0x5D, 0x0130) /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ \ UNI(0x5E, 0x015E) /* LATIN CAPITAL LETTER S WITH CEDILLA */ \ UNI(0x5F, 0x00DF) /* LATIN SMALL LETTER SHARP S */ \ UNI(0x60, 0x00E0) /* LATIN SMALL LETTER A WITH GRAVE */ \ UNI(0x61, 0x00E1) /* LATIN SMALL LETTER A WITH ACUTE */ \ UNI(0x62, 0x00E2) /* LATIN SMALL LETTER A WITH CIRCUMFLEX */ \ UNI(0x63, 0x00E3) /* LATIN SMALL LETTER A WITH TILDE */ \ UNI(0x64, 0x00E4) /* LATIN SMALL LETTER A WITH DIAERESIS */ \ UNI(0x65, 0x00E5) /* LATIN SMALL LETTER A WITH RING ABOVE */ \ UNI(0x66, 0x00E6) /* LATIN SMALL LETTER AE */ \ UNI(0x67, 0x00E7) /* LATIN SMALL LETTER C WITH CEDILLA */ \ UNI(0x68, 0x00E8) /* LATIN SMALL LETTER E WITH GRAVE */ \ UNI(0x69, 0x00E9) /* LATIN SMALL LETTER E WITH ACUTE */ \ UNI(0x6A, 0x00EA) /* LATIN SMALL LETTER E WITH CIRCUMFLEX */ \ UNI(0x6B, 0x00EB) /* LATIN SMALL LETTER E WITH DIAERESIS */ \ UNI(0x6C, 0x00EC) /* LATIN SMALL LETTER I WITH GRAVE */ \ UNI(0x6D, 0x00ED) /* LATIN SMALL LETTER I WITH ACUTE */ \ UNI(0x6E, 0x00EE) /* LATIN SMALL LETTER I WITH CIRCUMFLEX */ \ UNI(0x6F, 0x00EF) /* LATIN SMALL LETTER I WITH DIAERESIS */ \ UNI(0x70, 0x011F) /* LATIN SMALL LETTER G WITH BREVE */ \ UNI(0x71, 0x00F1) /* LATIN SMALL LETTER N WITH TILDE */ \ UNI(0x72, 0x00F2) /* LATIN SMALL LETTER O WITH GRAVE */ \ UNI(0x73, 0x00F3) /* LATIN SMALL LETTER O WITH ACUTE */ \ UNI(0x74, 0x00F4) /* LATIN SMALL LETTER O WITH CIRCUMFLEX */ \ UNI(0x75, 0x00F5) /* LATIN SMALL LETTER O WITH TILDE */ \ UNI(0x76, 0x00F6) /* LATIN SMALL LETTER O WITH DIAERESIS */ \ UNI(0x77, 0x00F7) /* DIVISION SIGN */ \ UNI(0x78, 0x00F8) /* LATIN SMALL LETTER O WITH STROKE */ \ UNI(0x79, 0x00F9) /* LATIN SMALL LETTER U WITH GRAVE */ \ UNI(0x7A, 0x00FA) /* LATIN SMALL LETTER U WITH ACUTE */ \ UNI(0x7B, 0x00FB) /* LATIN SMALL LETTER U WITH CIRCUMFLEX */ \ UNI(0x7C, 0x00FC) /* LATIN SMALL LETTER U WITH DIAERESIS */ \ UNI(0x7D, 0x0131) /* LATIN SMALL LETTER DOTLESS I */ \ UNI(0x7E, 0x015F) /* LATIN SMALL LETTER S WITH CEDILLA */ \ UNI(0x7F, 0x00FF) /* LATIN SMALL LETTER Y WITH DIAERESIS */ \ } \ end_CODEPAGE() #define unmap_ISO_Latin_5(code,dft) \ switch (code) { \ MAP(0x50, 0x4E) /* LATIN CAPITAL LETTER G WITH BREVE */ \ MAP(0x5D, 0x4F) /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ \ MAP(0x5E, 0x9F) /* LATIN CAPITAL LETTER S WITH CEDILLA */ \ MAP(0x70, 0x50) /* LATIN SMALL LETTER G WITH BREVE */ \ MAP(0x7D, 0x51) /* LATIN SMALL LETTER DOTLESS I */ \ MAP(0x7E, 0x2A) /* LATIN SMALL LETTER S WITH CEDILLA */ \ default: dft; break; \ } /* * DEC Cyrillic from screenshot */ #define map_DEC_Cyrillic(code) \ begin_CODEPAGE(94) \ switch (code) { \ XXX(0x21, UNDEF) /* undefined */ \ XXX(0x22, UNDEF) /* undefined */ \ XXX(0x23, UNDEF) /* undefined */ \ XXX(0x24, UNDEF) /* undefined */ \ XXX(0x25, UNDEF) /* undefined */ \ XXX(0x26, UNDEF) /* undefined */ \ XXX(0x27, UNDEF) /* undefined */ \ XXX(0x28, UNDEF) /* undefined */ \ XXX(0x29, UNDEF) /* undefined */ \ XXX(0x2A, UNDEF) /* undefined */ \ XXX(0x2B, UNDEF) /* undefined */ \ XXX(0x2C, UNDEF) /* undefined */ \ XXX(0x2D, UNDEF) /* undefined */ \ XXX(0x2E, UNDEF) /* undefined */ \ XXX(0x2F, UNDEF) /* undefined */ \ XXX(0x30, UNDEF) /* undefined */ \ XXX(0x31, UNDEF) /* undefined */ \ XXX(0x32, UNDEF) /* undefined */ \ XXX(0x33, UNDEF) /* undefined */ \ XXX(0x34, UNDEF) /* undefined */ \ XXX(0x35, UNDEF) /* undefined */ \ XXX(0x36, UNDEF) /* undefined */ \ XXX(0x37, UNDEF) /* undefined */ \ XXX(0x38, UNDEF) /* undefined */ \ XXX(0x39, UNDEF) /* undefined */ \ XXX(0x3A, UNDEF) /* undefined */ \ XXX(0x3B, UNDEF) /* undefined */ \ XXX(0x3C, UNDEF) /* undefined */ \ XXX(0x3D, UNDEF) /* undefined */ \ XXX(0x3E, UNDEF) /* undefined */ \ XXX(0x3F, UNDEF) /* undefined */ \ UNI(0x40, 0x044E) /* CYRILLIC SMALL LETTER YU */ \ UNI(0x41, 0x0430) /* CYRILLIC SMALL LETTER A */ \ UNI(0x42, 0x0431) /* CYRILLIC SMALL LETTER BE */ \ UNI(0x43, 0x0446) /* CYRILLIC SMALL LETTER TSE */ \ UNI(0x44, 0x0434) /* CYRILLIC SMALL LETTER DE */ \ UNI(0x45, 0x0435) /* CYRILLIC SMALL LETTER IE */ \ UNI(0x46, 0x0444) /* CYRILLIC SMALL LETTER EF */ \ UNI(0x47, 0x0433) /* CYRILLIC SMALL LETTER GHE */ \ UNI(0x48, 0x0445) /* CYRILLIC SMALL LETTER HA */ \ UNI(0x49, 0x0438) /* CYRILLIC SMALL LETTER I */ \ UNI(0x4A, 0x0439) /* CYRILLIC SMALL LETTER SHORT I */ \ UNI(0x4B, 0x043A) /* CYRILLIC SMALL LETTER KA */ \ UNI(0x4C, 0x043B) /* CYRILLIC SMALL LETTER EL */ \ UNI(0x4D, 0x043C) /* CYRILLIC SMALL LETTER EM */ \ UNI(0x4E, 0x043D) /* CYRILLIC SMALL LETTER EN */ \ UNI(0x4F, 0x043E) /* CYRILLIC SMALL LETTER O */ \ UNI(0x50, 0x043F) /* CYRILLIC SMALL LETTER PE */ \ UNI(0x51, 0x044F) /* CYRILLIC SMALL LETTER YA */ \ UNI(0x52, 0x0440) /* CYRILLIC SMALL LETTER ER */ \ UNI(0x53, 0x0441) /* CYRILLIC SMALL LETTER ES */ \ UNI(0x54, 0x0442) /* CYRILLIC SMALL LETTER TE */ \ UNI(0x55, 0x0443) /* CYRILLIC SMALL LETTER U */ \ UNI(0x56, 0x0436) /* CYRILLIC SMALL LETTER ZHE */ \ UNI(0x57, 0x0432) /* CYRILLIC SMALL LETTER VE */ \ UNI(0x58, 0x044C) /* CYRILLIC SMALL LETTER SOFT SIGN */ \ UNI(0x59, 0x044B) /* CYRILLIC SMALL LETTER YERU */ \ UNI(0x5A, 0x0437) /* CYRILLIC SMALL LETTER ZE */ \ UNI(0x5B, 0x0448) /* CYRILLIC SMALL LETTER SHA */ \ UNI(0x5C, 0x044D) /* CYRILLIC SMALL LETTER E */ \ UNI(0x5D, 0x0449) /* CYRILLIC SMALL LETTER SHCHA */ \ UNI(0x5E, 0x0447) /* CYRILLIC SMALL LETTER CHE */ \ UNI(0x5F, 0x044A) /* CYRILLIC SMALL LETTER HARD SIGN */ \ UNI(0x60, 0x042E) /* CYRILLIC CAPITAL LETTER YU */ \ UNI(0x61, 0x0410) /* CYRILLIC CAPITAL LETTER A */ \ UNI(0x62, 0x0411) /* CYRILLIC CAPITAL LETTER BE */ \ UNI(0x63, 0x0426) /* CYRILLIC CAPITAL LETTER TSE */ \ UNI(0x64, 0x0414) /* CYRILLIC CAPITAL LETTER DE */ \ UNI(0x65, 0x0415) /* CYRILLIC CAPITAL LETTER IE */ \ UNI(0x66, 0x0424) /* CYRILLIC CAPITAL LETTER EF */ \ UNI(0x67, 0x0413) /* CYRILLIC CAPITAL LETTER GHE */ \ UNI(0x68, 0x0425) /* CYRILLIC CAPITAL LETTER HA */ \ UNI(0x69, 0x0418) /* CYRILLIC CAPITAL LETTER I */ \ UNI(0x6A, 0x0419) /* CYRILLIC CAPITAL LETTER SHORT I */ \ UNI(0x6B, 0x041A) /* CYRILLIC CAPITAL LETTER KA */ \ UNI(0x6C, 0x041B) /* CYRILLIC CAPITAL LETTER EL */ \ UNI(0x6D, 0x041C) /* CYRILLIC CAPITAL LETTER EM */ \ UNI(0x6E, 0x041D) /* CYRILLIC CAPITAL LETTER EN */ \ UNI(0x6F, 0x041E) /* CYRILLIC CAPITAL LETTER O */ \ UNI(0x70, 0x041F) /* CYRILLIC CAPITAL LETTER PE */ \ UNI(0x71, 0x042F) /* CYRILLIC CAPITAL LETTER YA */ \ UNI(0x72, 0x0420) /* CYRILLIC CAPITAL LETTER ER */ \ UNI(0x73, 0x0421) /* CYRILLIC CAPITAL LETTER ES */ \ UNI(0x74, 0x0422) /* CYRILLIC CAPITAL LETTER TE */ \ UNI(0x75, 0x0423) /* CYRILLIC CAPITAL LETTER U */ \ UNI(0x76, 0x0416) /* CYRILLIC CAPITAL LETTER ZHE */ \ UNI(0x77, 0x0412) /* CYRILLIC CAPITAL LETTER VE */ \ UNI(0x78, 0x042C) /* CYRILLIC CAPITAL LETTER SOFT SIGN */ \ UNI(0x79, 0x042B) /* CYRILLIC CAPITAL LETTER YERU */ \ UNI(0x7A, 0x0417) /* CYRILLIC CAPITAL LETTER ZE */ \ UNI(0x7B, 0x0428) /* CYRILLIC CAPITAL LETTER SHA */ \ UNI(0x7C, 0x042D) /* CYRILLIC CAPITAL LETTER E */ \ UNI(0x7D, 0x0429) /* CYRILLIC CAPITAL LETTER SHCHA */ \ UNI(0x7E, 0x0427) /* CYRILLIC CAPITAL LETTER CHE */ \ } \ end_CODEPAGE() #define unmap_DEC_Cyrillic(code,dft) \ switch (code) { \ MAP(0x21, 0x1B) /* undefined */ \ MAP(0x22, 0x1B) /* undefined */ \ MAP(0x23, 0x1B) /* undefined */ \ MAP(0x24, 0x1B) /* undefined */ \ MAP(0x25, 0x1B) /* undefined */ \ MAP(0x26, 0x1B) /* undefined */ \ MAP(0x27, 0x1B) /* undefined */ \ MAP(0x28, 0x1B) /* undefined */ \ MAP(0x29, 0x1B) /* undefined */ \ MAP(0x2A, 0x1B) /* undefined */ \ MAP(0x2B, 0x1B) /* undefined */ \ MAP(0x2C, 0x1B) /* undefined */ \ MAP(0x2D, 0x1B) /* undefined */ \ MAP(0x2E, 0x1B) /* undefined */ \ MAP(0x2F, 0x1B) /* undefined */ \ MAP(0x30, 0x1B) /* undefined */ \ MAP(0x31, 0x1B) /* undefined */ \ MAP(0x32, 0x1B) /* undefined */ \ MAP(0x33, 0x1B) /* undefined */ \ MAP(0x34, 0x1B) /* undefined */ \ MAP(0x35, 0x1B) /* undefined */ \ MAP(0x36, 0x1B) /* undefined */ \ MAP(0x37, 0x1B) /* undefined */ \ MAP(0x38, 0x1B) /* undefined */ \ MAP(0x39, 0x1B) /* undefined */ \ MAP(0x3A, 0x1B) /* undefined */ \ MAP(0x3B, 0x1B) /* undefined */ \ MAP(0x3C, 0x1B) /* undefined */ \ MAP(0x3D, 0x1B) /* undefined */ \ MAP(0x3E, 0x1B) /* undefined */ \ MAP(0x3F, 0x1B) /* undefined */ \ MAP(0x40, 0x4F) /* CYRILLIC SMALL LETTER YU */ \ MAP(0x41, 0x31) /* CYRILLIC SMALL LETTER A */ \ MAP(0x42, 0x32) /* CYRILLIC SMALL LETTER BE */ \ MAP(0x43, 0x47) /* CYRILLIC SMALL LETTER TSE */ \ MAP(0x44, 0x35) /* CYRILLIC SMALL LETTER DE */ \ MAP(0x45, 0x36) /* CYRILLIC SMALL LETTER IE */ \ MAP(0x46, 0x45) /* CYRILLIC SMALL LETTER EF */ \ MAP(0x47, 0x34) /* CYRILLIC SMALL LETTER GHE */ \ MAP(0x48, 0x46) /* CYRILLIC SMALL LETTER HA */ \ MAP(0x49, 0x39) /* CYRILLIC SMALL LETTER I */ \ MAP(0x4A, 0x3A) /* CYRILLIC SMALL LETTER SHORT I */ \ MAP(0x4B, 0x3B) /* CYRILLIC SMALL LETTER KA */ \ MAP(0x4C, 0x3C) /* CYRILLIC SMALL LETTER EL */ \ MAP(0x4D, 0x3D) /* CYRILLIC SMALL LETTER EM */ \ MAP(0x4E, 0x3E) /* CYRILLIC SMALL LETTER EN */ \ MAP(0x4F, 0x3F) /* CYRILLIC SMALL LETTER O */ \ MAP(0x50, 0x40) /* CYRILLIC SMALL LETTER PE */ \ MAP(0x51, 0x50) /* CYRILLIC SMALL LETTER YA */ \ MAP(0x52, 0x41) /* CYRILLIC SMALL LETTER ER */ \ MAP(0x53, 0x42) /* CYRILLIC SMALL LETTER ES */ \ MAP(0x54, 0x43) /* CYRILLIC SMALL LETTER TE */ \ MAP(0x55, 0x44) /* CYRILLIC SMALL LETTER U */ \ MAP(0x56, 0x37) /* CYRILLIC SMALL LETTER ZHE */ \ MAP(0x57, 0x33) /* CYRILLIC SMALL LETTER VE */ \ MAP(0x58, 0x4D) /* CYRILLIC SMALL LETTER SOFT SIGN */ \ MAP(0x59, 0x4C) /* CYRILLIC SMALL LETTER YERU */ \ MAP(0x5A, 0x38) /* CYRILLIC SMALL LETTER ZE */ \ MAP(0x5B, 0x49) /* CYRILLIC SMALL LETTER SHA */ \ MAP(0x5C, 0x4E) /* CYRILLIC SMALL LETTER E */ \ MAP(0x5D, 0x4A) /* CYRILLIC SMALL LETTER SHCHA */ \ MAP(0x5E, 0x48) /* CYRILLIC SMALL LETTER CHE */ \ MAP(0x5F, 0x4B) /* CYRILLIC SMALL LETTER HARD SIGN */ \ MAP(0x60, 0x2F) /* CYRILLIC CAPITAL LETTER YU */ \ MAP(0x61, 0x11) /* CYRILLIC CAPITAL LETTER A */ \ MAP(0x62, 0x12) /* CYRILLIC CAPITAL LETTER BE */ \ MAP(0x63, 0x27) /* CYRILLIC CAPITAL LETTER TSE */ \ MAP(0x64, 0x15) /* CYRILLIC CAPITAL LETTER DE */ \ MAP(0x65, 0x16) /* CYRILLIC CAPITAL LETTER IE */ \ MAP(0x66, 0x25) /* CYRILLIC CAPITAL LETTER EF */ \ MAP(0x67, 0x14) /* CYRILLIC CAPITAL LETTER GHE */ \ MAP(0x68, 0x26) /* CYRILLIC CAPITAL LETTER HA */ \ MAP(0x69, 0x19) /* CYRILLIC CAPITAL LETTER I */ \ MAP(0x6A, 0x1A) /* CYRILLIC CAPITAL LETTER SHORT I */ \ MAP(0x6B, 0x1B) /* CYRILLIC CAPITAL LETTER KA */ \ MAP(0x6C, 0x1C) /* CYRILLIC CAPITAL LETTER EL */ \ MAP(0x6D, 0x1D) /* CYRILLIC CAPITAL LETTER EM */ \ MAP(0x6E, 0x1E) /* CYRILLIC CAPITAL LETTER EN */ \ MAP(0x6F, 0x1F) /* CYRILLIC CAPITAL LETTER O */ \ MAP(0x70, 0x20) /* CYRILLIC CAPITAL LETTER PE */ \ MAP(0x71, 0x30) /* CYRILLIC CAPITAL LETTER YA */ \ MAP(0x72, 0x21) /* CYRILLIC CAPITAL LETTER ER */ \ MAP(0x73, 0x22) /* CYRILLIC CAPITAL LETTER ES */ \ MAP(0x74, 0x23) /* CYRILLIC CAPITAL LETTER TE */ \ MAP(0x75, 0x24) /* CYRILLIC CAPITAL LETTER U */ \ MAP(0x76, 0x17) /* CYRILLIC CAPITAL LETTER ZHE */ \ MAP(0x77, 0x13) /* CYRILLIC CAPITAL LETTER VE */ \ MAP(0x78, 0x2D) /* CYRILLIC CAPITAL LETTER SOFT SIGN */ \ MAP(0x79, 0x2C) /* CYRILLIC CAPITAL LETTER YERU */ \ MAP(0x7A, 0x18) /* CYRILLIC CAPITAL LETTER ZE */ \ MAP(0x7B, 0x29) /* CYRILLIC CAPITAL LETTER SHA */ \ MAP(0x7C, 0x2E) /* CYRILLIC CAPITAL LETTER E */ \ MAP(0x7D, 0x2A) /* CYRILLIC CAPITAL LETTER SHCHA */ \ MAP(0x7E, 0x28) /* CYRILLIC CAPITAL LETTER CHE */ \ default: dft; break; \ } /* * figure A-24 "DEC Greek Supplemental Character Set" */ #define map_DEC_Greek_Supp(code) \ begin_CODEPAGE(94) \ switch (code) { \ UNI(0x21, 0x00A1) /* LEFT SINGLE QUOTATION MARK */ \ UNI(0x22, 0x00A2) /* RIGHT SINGLE QUOTATION MARK */ \ UNI(0x23, 0x00A3) /* POUND SIGN */ \ XXX(0x24, UNDEF) /* EURO SIGN */ \ UNI(0x25, 0x00A5) /* YEN SIGN */ \ XXX(0x26, UNDEF) /* BROKEN BAR */ \ UNI(0x27, 0x00A7) /* SECTION SIGN */ \ UNI(0x28, 0x00A4) /* CURRENCY SIGN */ \ UNI(0x29, 0x00A9) /* COPYRIGHT SIGN */ \ UNI(0x2A, 0x00AA) /* FEMININE ORDINAL INDICATOR */ \ UNI(0x2B, 0x00AB) /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ XXX(0x2C, UNDEF) /* reserved */ \ XXX(0x2D, UNDEF) /* reserved */ \ XXX(0x2E, UNDEF) /* reserved */ \ XXX(0x2F, UNDEF) /* reserved */ \ UNI(0x30, 0x00B0) /* DEGREE SIGN */ \ UNI(0x31, 0x00B1) /* PLUS-MINUS SIGN */ \ UNI(0x32, 0x00B2) /* SUPERSCRIPT TWO */ \ UNI(0x33, 0x00B3) /* SUPERSCRIPT THREE */ \ XXX(0x34, UNDEF) /* reserved */ \ UNI(0x35, 0x00B5) /* MICRO SIGN */ \ UNI(0x36, 0x00B6) /* PILCROW SIGN */ \ UNI(0x37, 0x00B7) /* MIDDLE DOT */ \ XXX(0x38, UNDEF) /* reserved */ \ UNI(0x39, 0x00B9) /* SUPERSCRIPT ONE */ \ UNI(0x3A, 0x00BA) /* MASCULINE ORDINAL INDICATOR */ \ UNI(0x3B, 0x00BB) /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ UNI(0x3C, 0x00BC) /* VULGAR FRACTION ONE QUARTER */ \ UNI(0x3D, 0x00BD) /* VULGAR FRACTION ONE HALF */ \ XXX(0x3E, UNDEF) /* reserved */ \ UNI(0x3F, 0x00BF) /* INVERTED QUESTION MARK */ \ UNI(0x40, 0x03CA) /* GREEK SMALL LETTER IOTA WITH DIALYTIKA */ \ UNI(0x41, 0x0391) /* GREEK CAPITAL LETTER ALPHA */ \ UNI(0x42, 0x0392) /* GREEK CAPITAL LETTER BETA */ \ UNI(0x43, 0x0393) /* GREEK CAPITAL LETTER GAMMA */ \ UNI(0x44, 0x0394) /* GREEK CAPITAL LETTER DELTA */ \ UNI(0x45, 0x0395) /* GREEK CAPITAL LETTER EPSILON */ \ UNI(0x46, 0x0396) /* GREEK CAPITAL LETTER ZETA */ \ UNI(0x47, 0x0397) /* GREEK CAPITAL LETTER ETA */ \ UNI(0x48, 0x0398) /* GREEK CAPITAL LETTER THETA */ \ UNI(0x49, 0x0399) /* GREEK CAPITAL LETTER IOTA */ \ UNI(0x4A, 0x039A) /* GREEK CAPITAL LETTER KAPPA */ \ UNI(0x4B, 0x039B) /* GREEK CAPITAL LETTER LAMDA */ \ UNI(0x4C, 0x039C) /* GREEK CAPITAL LETTER MU */ \ UNI(0x4D, 0x039D) /* GREEK CAPITAL LETTER NU */ \ UNI(0x4E, 0x039E) /* GREEK CAPITAL LETTER XI */ \ UNI(0x4F, 0x039F) /* GREEK CAPITAL LETTER OMICRON */ \ XXX(0x50, UNDEF) /* reserved */ \ UNI(0x51, 0x03A0) /* GREEK CAPITAL LETTER PI */ \ UNI(0x52, 0x03A1) /* GREEK CAPITAL LETTER RHO */ \ UNI(0x53, 0x03A3) /* GREEK CAPITAL LETTER SIGMA */ \ UNI(0x54, 0x03A4) /* GREEK CAPITAL LETTER TAU */ \ UNI(0x55, 0x03A5) /* GREEK CAPITAL LETTER UPSILON */ \ UNI(0x56, 0x03A6) /* GREEK CAPITAL LETTER PHI */ \ UNI(0x57, 0x03A7) /* GREEK CAPITAL LETTER CHI */ \ UNI(0x58, 0x03A8) /* GREEK CAPITAL LETTER PSI */ \ UNI(0x59, 0x03A9) /* GREEK CAPITAL LETTER OMEGA */ \ UNI(0x5A, 0x03AC) /* GREEK SMALL LETTER ALPHA WITH TONOS */ \ UNI(0x5B, 0x03AD) /* GREEK SMALL LETTER EPSILON WITH TONOS */ \ UNI(0x5C, 0x03AE) /* GREEK SMALL LETTER ETA WITH TONOS */ \ UNI(0x5D, 0x03AF) /* GREEK SMALL LETTER IOTA WITH TONOS */ \ XXX(0x5E, UNDEF) /* reserved */ \ UNI(0x5F, 0x03CC) /* GREEK SMALL LETTER OMICRON WITH TONOS */ \ UNI(0x60, 0x03CB) /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ \ UNI(0x61, 0x03B1) /* GREEK SMALL LETTER ALPHA */ \ UNI(0x62, 0x03B2) /* GREEK SMALL LETTER BETA */ \ UNI(0x63, 0x03B3) /* GREEK SMALL LETTER GAMMA */ \ UNI(0x64, 0x03B4) /* GREEK SMALL LETTER DELTA */ \ UNI(0x65, 0x03B5) /* GREEK SMALL LETTER EPSILON */ \ UNI(0x66, 0x03B6) /* GREEK SMALL LETTER ZETA */ \ UNI(0x67, 0x03B7) /* GREEK SMALL LETTER ETA */ \ UNI(0x68, 0x03B8) /* GREEK SMALL LETTER THETA */ \ UNI(0x69, 0x03B9) /* GREEK SMALL LETTER IOTA */ \ UNI(0x6A, 0x03BA) /* GREEK SMALL LETTER KAPPA */ \ UNI(0x6B, 0x03BB) /* GREEK SMALL LETTER LAMDA */ \ UNI(0x6C, 0x03BC) /* GREEK SMALL LETTER MU */ \ UNI(0x6D, 0x03BD) /* GREEK SMALL LETTER NU */ \ UNI(0x6E, 0x03BE) /* GREEK SMALL LETTER XI */ \ UNI(0x6F, 0x03BF) /* GREEK SMALL LETTER OMICRON */ \ XXX(0x70, UNDEF) /* reserved */ \ UNI(0x71, 0x03C0) /* GREEK SMALL LETTER PI */ \ UNI(0x72, 0x03C1) /* GREEK SMALL LETTER RHO */ \ UNI(0x73, 0x03C3) /* GREEK SMALL LETTER SIGMA */ \ UNI(0x74, 0x03C4) /* GREEK SMALL LETTER TAU */ \ UNI(0x75, 0x03C5) /* GREEK SMALL LETTER UPSILON */ \ UNI(0x76, 0x03C6) /* GREEK SMALL LETTER PHI */ \ UNI(0x77, 0x03C7) /* GREEK SMALL LETTER CHI */ \ UNI(0x78, 0x03C8) /* GREEK SMALL LETTER PSI */ \ UNI(0x79, 0x03C9) /* GREEK SMALL LETTER OMEGA */ \ UNI(0x7A, 0x03C2) /* GREEK SMALL LETTER FINAL SIGMA */ \ UNI(0x7B, 0x03CD) /* GREEK SMALL LETTER UPSILON WITH TONOS */ \ UNI(0x7C, 0x03CE) /* GREEK SMALL LETTER OMEGA WITH TONOS */ \ UNI(0x7D, 0x0384) /* GREEK TONOS */ \ XXX(0x7E, UNDEF) /* reserved */ \ } \ end_CODEPAGE() #define unmap_DEC_Greek_Supp(code,dft) \ switch (code) { \ MAP(0x24, 0x1B) /* EURO SIGN */ \ MAP(0x26, 0x1B) /* BROKEN BAR */ \ MAP(0x28, 0xA4) /* CURRENCY SIGN */ \ MAP(0x2C, 0x1B) /* reserved */ \ MAP(0x2D, 0x1B) /* reserved */ \ MAP(0x2E, 0x1B) /* reserved */ \ MAP(0x2F, 0x1B) /* reserved */ \ MAP(0x34, 0x1B) /* reserved */ \ MAP(0x38, 0x1B) /* reserved */ \ MAP(0x3E, 0x1B) /* reserved */ \ MAP(0x40, 0xD0) /* GREEK SMALL LETTER IOTA WITH DIALYTIKA */ \ MAP(0x41, 0x76) /* GREEK CAPITAL LETTER ALPHA */ \ MAP(0x42, 0x77) /* GREEK CAPITAL LETTER BETA */ \ MAP(0x43, 0x78) /* GREEK CAPITAL LETTER GAMMA */ \ MAP(0x44, 0x79) /* GREEK CAPITAL LETTER DELTA */ \ MAP(0x45, 0x7A) /* GREEK CAPITAL LETTER EPSILON */ \ MAP(0x46, 0x7B) /* GREEK CAPITAL LETTER ZETA */ \ MAP(0x47, 0x7C) /* GREEK CAPITAL LETTER ETA */ \ MAP(0x48, 0x7D) /* GREEK CAPITAL LETTER THETA */ \ MAP(0x49, 0x7E) /* GREEK CAPITAL LETTER IOTA */ \ MAP(0x4A, 0x7F) /* GREEK CAPITAL LETTER KAPPA */ \ MAP(0x4B, 0xA2) /* GREEK CAPITAL LETTER LAMDA */ \ MAP(0x4C, 0xA3) /* GREEK CAPITAL LETTER MU */ \ MAP(0x4D, 0xA4) /* GREEK CAPITAL LETTER NU */ \ MAP(0x4E, 0xA5) /* GREEK CAPITAL LETTER XI */ \ MAP(0x4F, 0xA6) /* GREEK CAPITAL LETTER OMICRON */ \ MAP(0x50, 0x1B) /* reserved */ \ MAP(0x51, 0xA7) /* GREEK CAPITAL LETTER PI */ \ MAP(0x52, 0xA8) /* GREEK CAPITAL LETTER RHO */ \ MAP(0x53, 0xA9) /* GREEK CAPITAL LETTER SIGMA */ \ MAP(0x54, 0xAA) /* GREEK CAPITAL LETTER TAU */ \ MAP(0x55, 0xAB) /* GREEK CAPITAL LETTER UPSILON */ \ MAP(0x56, 0xAC) /* GREEK CAPITAL LETTER PHI */ \ MAP(0x57, 0xAD) /* GREEK CAPITAL LETTER CHI */ \ MAP(0x58, 0xAE) /* GREEK CAPITAL LETTER PSI */ \ MAP(0x59, 0xAF) /* GREEK CAPITAL LETTER OMEGA */ \ MAP(0x5A, 0xB2) /* GREEK SMALL LETTER ALPHA WITH TONOS */ \ MAP(0x5B, 0xB3) /* GREEK SMALL LETTER EPSILON WITH TONOS */ \ MAP(0x5C, 0xB4) /* GREEK SMALL LETTER ETA WITH TONOS */ \ MAP(0x5D, 0xB5) /* GREEK SMALL LETTER IOTA WITH TONOS */ \ MAP(0x5E, 0x1B) /* reserved */ \ MAP(0x5F, 0xD2) /* GREEK SMALL LETTER OMICRON WITH TONOS */ \ MAP(0x60, 0xD1) /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ \ MAP(0x61, 0xB7) /* GREEK SMALL LETTER ALPHA */ \ MAP(0x62, 0xB8) /* GREEK SMALL LETTER BETA */ \ MAP(0x63, 0xB9) /* GREEK SMALL LETTER GAMMA */ \ MAP(0x64, 0xBA) /* GREEK SMALL LETTER DELTA */ \ MAP(0x65, 0xBB) /* GREEK SMALL LETTER EPSILON */ \ MAP(0x66, 0xBC) /* GREEK SMALL LETTER ZETA */ \ MAP(0x67, 0xBD) /* GREEK SMALL LETTER ETA */ \ MAP(0x68, 0xBE) /* GREEK SMALL LETTER THETA */ \ MAP(0x69, 0xBF) /* GREEK SMALL LETTER IOTA */ \ MAP(0x6A, 0xC0) /* GREEK SMALL LETTER KAPPA */ \ MAP(0x6B, 0xC1) /* GREEK SMALL LETTER LAMDA */ \ MAP(0x6C, 0xC2) /* GREEK SMALL LETTER MU */ \ MAP(0x6D, 0xC3) /* GREEK SMALL LETTER NU */ \ MAP(0x6E, 0xC4) /* GREEK SMALL LETTER XI */ \ MAP(0x6F, 0xC5) /* GREEK SMALL LETTER OMICRON */ \ MAP(0x70, 0x1B) /* reserved */ \ MAP(0x71, 0xC6) /* GREEK SMALL LETTER PI */ \ MAP(0x72, 0xC7) /* GREEK SMALL LETTER RHO */ \ MAP(0x73, 0xC9) /* GREEK SMALL LETTER SIGMA */ \ MAP(0x74, 0xCA) /* GREEK SMALL LETTER TAU */ \ MAP(0x75, 0xCB) /* GREEK SMALL LETTER UPSILON */ \ MAP(0x76, 0xCC) /* GREEK SMALL LETTER PHI */ \ MAP(0x77, 0xCD) /* GREEK SMALL LETTER CHI */ \ MAP(0x78, 0xCE) /* GREEK SMALL LETTER PSI */ \ MAP(0x79, 0xCF) /* GREEK SMALL LETTER OMEGA */ \ MAP(0x7A, 0xC8) /* GREEK SMALL LETTER FINAL SIGMA */ \ MAP(0x7B, 0xD3) /* GREEK SMALL LETTER UPSILON WITH TONOS */ \ MAP(0x7C, 0xD4) /* GREEK SMALL LETTER OMEGA WITH TONOS */ \ MAP(0x7D, 0x96) /* GREEK TONOS */ \ MAP(0x7E, 0x1B) /* reserved */ \ default: dft; break; \ } /* * figure A-22 "DEC Hebrew Supplemental Character Set" */ #define map_DEC_Hebrew_Supp(code) \ begin_CODEPAGE(94) \ switch (code) { \ UNI(0x21, 0x00A1) /* INVERTED EXCLAMATION MARK */ \ UNI(0x22, 0x00A2) /* CENT SIGN */ \ UNI(0x23, 0x00A3) /* POUND SIGN */ \ XXX(0x24, UNDEF) /* CURRENCY SIGN */ \ UNI(0x25, 0x00A5) /* YEN SIGN */ \ XXX(0x26, UNDEF) /* BROKEN BAR */ \ UNI(0x27, 0x00A7) /* SECTION SIGN */ \ UNI(0x28, 0x00A8) /* DIAERESIS */ \ UNI(0x29, 0x00A9) /* COPYRIGHT SIGN */ \ UNI(0x2A, 0x00D7) /* MULTIPLICATION SIGN */ \ UNI(0x2B, 0x00AB) /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ XXX(0x2C, UNDEF) /* NOT SIGN */ \ XXX(0x2D, UNDEF) /* SOFT HYPHEN */ \ XXX(0x2E, UNDEF) /* REGISTERED SIGN */ \ XXX(0x2F, UNDEF) /* MACRON */ \ UNI(0x30, 0x00B0) /* DEGREE SIGN */ \ UNI(0x31, 0x00B1) /* PLUS-MINUS SIGN */ \ UNI(0x32, 0x00B2) /* SUPERSCRIPT TWO */ \ UNI(0x33, 0x00B3) /* SUPERSCRIPT THREE */ \ XXX(0x34, UNDEF) /* ACUTE ACCENT */ \ UNI(0x35, 0x00B5) /* MICRO SIGN */ \ UNI(0x36, 0x00B6) /* PILCROW SIGN */ \ UNI(0x37, 0x00B7) /* MIDDLE DOT */ \ XXX(0x38, UNDEF) /* CEDILLA */ \ UNI(0x39, 0x00B9) /* SUPERSCRIPT ONE */ \ UNI(0x3A, 0x00F7) /* DIVISION SIGN */ \ UNI(0x3B, 0x00BB) /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ UNI(0x3C, 0x00BC) /* VULGAR FRACTION ONE QUARTER */ \ UNI(0x3D, 0x00BD) /* VULGAR FRACTION ONE HALF */ \ XXX(0x3E, UNDEF) /* VULGAR FRACTION THREE QUARTERS */ \ UNI(0x3F, 0x00BF) /* INVERTED QUESTION MARK */ \ XXX(0x40, UNDEF) /* reserved */ \ XXX(0x41, UNDEF) /* reserved */ \ XXX(0x42, UNDEF) /* reserved */ \ XXX(0x43, UNDEF) /* reserved */ \ XXX(0x44, UNDEF) /* reserved */ \ XXX(0x45, UNDEF) /* reserved */ \ XXX(0x46, UNDEF) /* reserved */ \ XXX(0x47, UNDEF) /* reserved */ \ XXX(0x48, UNDEF) /* reserved */ \ XXX(0x49, UNDEF) /* reserved */ \ XXX(0x4A, UNDEF) /* reserved */ \ XXX(0x4B, UNDEF) /* reserved */ \ XXX(0x4C, UNDEF) /* reserved */ \ XXX(0x4D, UNDEF) /* reserved */ \ XXX(0x4E, UNDEF) /* reserved */ \ XXX(0x4F, UNDEF) /* reserved */ \ XXX(0x50, UNDEF) /* reserved */ \ XXX(0x51, UNDEF) /* reserved */ \ XXX(0x52, UNDEF) /* reserved */ \ XXX(0x53, UNDEF) /* reserved */ \ XXX(0x54, UNDEF) /* reserved */ \ XXX(0x55, UNDEF) /* reserved */ \ XXX(0x56, UNDEF) /* reserved */ \ XXX(0x57, UNDEF) /* reserved */ \ XXX(0x58, UNDEF) /* reserved */ \ XXX(0x59, UNDEF) /* reserved */ \ XXX(0x5A, UNDEF) /* reserved */ \ XXX(0x5B, UNDEF) /* reserved */ \ XXX(0x5C, UNDEF) /* reserved */ \ XXX(0x5D, UNDEF) /* reserved */ \ XXX(0x5E, UNDEF) /* reserved */ \ XXX(0x5F, UNDEF) /* reserved */ \ UNI(0x60, 0x05D0) /* HEBREW LETTER ALEF */ \ UNI(0x61, 0x05D1) /* HEBREW LETTER BET */ \ UNI(0x62, 0x05D2) /* HEBREW LETTER GIMEL */ \ UNI(0x63, 0x05D3) /* HEBREW LETTER DALET */ \ UNI(0x64, 0x05D4) /* HEBREW LETTER HE */ \ UNI(0x65, 0x05D5) /* HEBREW LETTER VAV */ \ UNI(0x66, 0x05D6) /* HEBREW LETTER ZAYIN */ \ UNI(0x67, 0x05D7) /* HEBREW LETTER HET */ \ UNI(0x68, 0x05D8) /* HEBREW LETTER TET */ \ UNI(0x69, 0x05D9) /* HEBREW LETTER YOD */ \ UNI(0x6A, 0x05DA) /* HEBREW LETTER FINAL KAF */ \ UNI(0x6B, 0x05DB) /* HEBREW LETTER KAF */ \ UNI(0x6C, 0x05DC) /* HEBREW LETTER LAMED */ \ UNI(0x6D, 0x05DD) /* HEBREW LETTER FINAL MEM */ \ UNI(0x6E, 0x05DE) /* HEBREW LETTER MEM */ \ UNI(0x6F, 0x05DF) /* HEBREW LETTER FINAL NUN */ \ UNI(0x70, 0x05E0) /* HEBREW LETTER NUN */ \ UNI(0x71, 0x05E1) /* HEBREW LETTER SAMEKH */ \ UNI(0x72, 0x05E2) /* HEBREW LETTER AYIN */ \ UNI(0x73, 0x05E3) /* HEBREW LETTER FINAL PE */ \ UNI(0x74, 0x05E4) /* HEBREW LETTER PE */ \ UNI(0x75, 0x05E5) /* HEBREW LETTER FINAL TSADI */ \ UNI(0x76, 0x05E6) /* HEBREW LETTER TSADI */ \ UNI(0x77, 0x05E7) /* HEBREW LETTER QOF */ \ UNI(0x78, 0x05E8) /* HEBREW LETTER RESH */ \ UNI(0x79, 0x05E9) /* HEBREW LETTER SHIN */ \ UNI(0x7A, 0x05EA) /* HEBREW LETTER TAV */ \ XXX(0x7B, UNDEF) /* reserved */ \ XXX(0x7C, UNDEF) /* reserved */ \ XXX(0x7D, UNDEF) /* reserved */ \ XXX(0x7E, UNDEF) /* reserved */ \ } \ end_CODEPAGE() #define unmap_DEC_Hebrew_Supp(code,dft) \ switch (code) { \ MAP(0x24, 0x1B) /* CURRENCY SIGN */ \ MAP(0x26, 0x1B) /* BROKEN BAR */ \ MAP(0x28, 0xA4) /* DIAERESIS */ \ MAP(0x2C, 0x1B) /* NOT SIGN */ \ MAP(0x2D, 0x1B) /* SOFT HYPHEN */ \ MAP(0x2E, 0x1B) /* REGISTERED SIGN */ \ MAP(0x2F, 0x1B) /* MACRON */ \ MAP(0x34, 0x1B) /* ACUTE ACCENT */ \ MAP(0x38, 0x1B) /* CEDILLA */ \ MAP(0x3E, 0x1B) /* VULGAR FRACTION THREE QUARTERS */ \ MAP(0x40, 0x1B) /* reserved */ \ MAP(0x41, 0x1B) /* reserved */ \ MAP(0x42, 0x1B) /* reserved */ \ MAP(0x43, 0x1B) /* reserved */ \ MAP(0x44, 0x1B) /* reserved */ \ MAP(0x45, 0x1B) /* reserved */ \ MAP(0x46, 0x1B) /* reserved */ \ MAP(0x47, 0x1B) /* reserved */ \ MAP(0x48, 0x1B) /* reserved */ \ MAP(0x49, 0x1B) /* reserved */ \ MAP(0x4A, 0x1B) /* reserved */ \ MAP(0x4B, 0x1B) /* reserved */ \ MAP(0x4C, 0x1B) /* reserved */ \ MAP(0x4D, 0x1B) /* reserved */ \ MAP(0x4E, 0x1B) /* reserved */ \ MAP(0x4F, 0x1B) /* reserved */ \ MAP(0x50, 0x1B) /* reserved */ \ MAP(0x51, 0x1B) /* reserved */ \ MAP(0x52, 0x1B) /* reserved */ \ MAP(0x53, 0x1B) /* reserved */ \ MAP(0x54, 0x1B) /* reserved */ \ MAP(0x55, 0x1B) /* reserved */ \ MAP(0x56, 0x1B) /* reserved */ \ MAP(0x57, 0x1B) /* reserved */ \ MAP(0x58, 0x1B) /* reserved */ \ MAP(0x59, 0x1B) /* reserved */ \ MAP(0x5A, 0x1B) /* reserved */ \ MAP(0x5B, 0x1B) /* reserved */ \ MAP(0x5C, 0x1B) /* reserved */ \ MAP(0x5D, 0x1B) /* reserved */ \ MAP(0x5E, 0x1B) /* reserved */ \ MAP(0x5F, 0x1B) /* reserved */ \ MAP(0x60, 0x53) /* HEBREW LETTER ALEF */ \ MAP(0x61, 0x54) /* HEBREW LETTER BET */ \ MAP(0x62, 0x55) /* HEBREW LETTER GIMEL */ \ MAP(0x63, 0x56) /* HEBREW LETTER DALET */ \ MAP(0x64, 0x57) /* HEBREW LETTER HE */ \ MAP(0x65, 0x58) /* HEBREW LETTER VAV */ \ MAP(0x66, 0x59) /* HEBREW LETTER ZAYIN */ \ MAP(0x67, 0x5A) /* HEBREW LETTER HET */ \ MAP(0x68, 0x5B) /* HEBREW LETTER TET */ \ MAP(0x69, 0x5C) /* HEBREW LETTER YOD */ \ MAP(0x6A, 0x5D) /* HEBREW LETTER FINAL KAF */ \ MAP(0x6B, 0x5E) /* HEBREW LETTER KAF */ \ MAP(0x6C, 0x5F) /* HEBREW LETTER LAMED */ \ MAP(0x6D, 0x60) /* HEBREW LETTER FINAL MEM */ \ MAP(0x6E, 0x61) /* HEBREW LETTER MEM */ \ MAP(0x6F, 0x62) /* HEBREW LETTER FINAL NUN */ \ MAP(0x70, 0x63) /* HEBREW LETTER NUN */ \ MAP(0x71, 0x64) /* HEBREW LETTER SAMEKH */ \ MAP(0x72, 0x65) /* HEBREW LETTER AYIN */ \ MAP(0x73, 0x66) /* HEBREW LETTER FINAL PE */ \ MAP(0x74, 0x67) /* HEBREW LETTER PE */ \ MAP(0x75, 0x68) /* HEBREW LETTER FINAL TSADI */ \ MAP(0x76, 0x69) /* HEBREW LETTER TSADI */ \ MAP(0x77, 0x6A) /* HEBREW LETTER QOF */ \ MAP(0x78, 0x6B) /* HEBREW LETTER RESH */ \ MAP(0x79, 0x6C) /* HEBREW LETTER SHIN */ \ MAP(0x7A, 0x6D) /* HEBREW LETTER TAV */ \ MAP(0x7B, 0x1B) /* reserved */ \ MAP(0x7C, 0x1B) /* reserved */ \ MAP(0x7D, 0x1B) /* reserved */ \ MAP(0x7E, 0x1B) /* reserved */ \ default: dft; break; \ } /* * figure A-27 "DEC 8-Bit Turkish Supplemental Character Set" */ #define map_DEC_Turkish_Supp(code) \ begin_CODEPAGE(94) \ switch (code) { \ UNI(0x21, 0x00A1) /* INVERTED EXCLAMATION MARK */ \ UNI(0x22, 0x00A2) /* CENT SIGN */ \ UNI(0x23, 0x00A3) /* POUND SIGN */ \ XXX(0x24, UNDEF) /* reserved */ \ UNI(0x25, 0x00A5) /* YEN SIGN */ \ XXX(0x26, UNDEF) /* reserved */ \ UNI(0x27, 0x00A7) /* SECTION SIGN */ \ UNI(0x28, 0x00A8) /* DIAERESIS */ \ UNI(0x29, 0x00A9) /* COPYRIGHT SIGN */ \ UNI(0x2A, 0x00AA) /* FEMININE ORDINAL INDICATOR */ \ UNI(0x2B, 0x00AB) /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ XXX(0x2C, UNDEF) /* reserved */ \ XXX(0x2D, UNDEF) /* reserved */ \ UNI(0x2E, 0x0130) /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ \ XXX(0x2F, UNDEF) /* reserved */ \ UNI(0x30, 0x00B0) /* DEGREE SIGN */ \ UNI(0x31, 0x00B1) /* PLUS-MINUS SIGN */ \ UNI(0x32, 0x00B2) /* SUPERSCRIPT TWO */ \ UNI(0x33, 0x00B3) /* SUPERSCRIPT THREE */ \ XXX(0x34, UNDEF) /* reserved */ \ UNI(0x35, 0x00B5) /* MICRO SIGN */ \ UNI(0x36, 0x00B6) /* PILCROW SIGN */ \ UNI(0x37, 0x00B7) /* MIDDLE DOT */ \ XXX(0x38, UNDEF) /* reserved */ \ UNI(0x39, 0x00B9) /* SUPERSCRIPT ONE */ \ UNI(0x3A, 0x00BA) /* MASCULINE ORDINAL INDICATOR */ \ UNI(0x3B, 0x00BB) /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ \ UNI(0x3C, 0x00BC) /* VULGAR FRACTION ONE QUARTER */ \ UNI(0x3D, 0x00BD) /* VULGAR FRACTION ONE HALF */ \ UNI(0x3E, 0x0131) /* LATIN SMALL LETTER DOTLESS I */ \ UNI(0x3F, 0x00BF) /* INVERTED QUESTION MARK */ \ UNI(0x40, 0x00C0) /* LATIN CAPITAL LETTER A WITH GRAVE */ \ UNI(0x41, 0x00C1) /* LATIN CAPITAL LETTER A WITH ACUTE */ \ UNI(0x42, 0x00C2) /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ \ UNI(0x43, 0x00C3) /* LATIN CAPITAL LETTER A WITH TILDE */ \ UNI(0x44, 0x00C4) /* LATIN CAPITAL LETTER A WITH DIAERESIS */ \ UNI(0x45, 0x00C5) /* LATIN CAPITAL LETTER A WITH RING ABOVE */ \ UNI(0x46, 0x00C6) /* LATIN CAPITAL LETTER AE */ \ UNI(0x47, 0x00C7) /* LATIN CAPITAL LETTER C WITH CEDILLA */ \ UNI(0x48, 0x00C8) /* LATIN CAPITAL LETTER E WITH GRAVE */ \ UNI(0x49, 0x00C9) /* LATIN CAPITAL LETTER E WITH ACUTE */ \ UNI(0x4A, 0x00CA) /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ \ UNI(0x4B, 0x00CB) /* LATIN CAPITAL LETTER E WITH DIAERESIS */ \ UNI(0x4C, 0x00CC) /* LATIN CAPITAL LETTER I WITH GRAVE */ \ UNI(0x4D, 0x00CD) /* LATIN CAPITAL LETTER I WITH ACUTE */ \ UNI(0x4E, 0x00CE) /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ \ UNI(0x4F, 0x00CF) /* LATIN CAPITAL LETTER I WITH DIAERESIS */ \ UNI(0x50, 0x011E) /* LATIN CAPITAL LETTER G WITH BREVE */ \ UNI(0x51, 0x00D1) /* LATIN CAPITAL LETTER N WITH TILDE */ \ UNI(0x52, 0x00D2) /* LATIN CAPITAL LETTER O WITH GRAVE */ \ UNI(0x53, 0x00D3) /* LATIN CAPITAL LETTER O WITH ACUTE */ \ UNI(0x54, 0x00D4) /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ \ UNI(0x55, 0x00D5) /* LATIN CAPITAL LETTER O WITH TILDE */ \ UNI(0x56, 0x00D6) /* LATIN CAPITAL LETTER O WITH DIAERESIS */ \ UNI(0x57, 0x0152) /* LATIN CAPITAL LIGATURE OE */ \ UNI(0x58, 0x00D8) /* LATIN CAPITAL LETTER O WITH STROKE */ \ UNI(0x59, 0x00D9) /* LATIN CAPITAL LETTER U WITH GRAVE */ \ UNI(0x5A, 0x00DA) /* LATIN CAPITAL LETTER U WITH ACUTE */ \ UNI(0x5B, 0x00DB) /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ \ UNI(0x5C, 0x00DC) /* LATIN CAPITAL LETTER U WITH DIAERESIS */ \ UNI(0x5D, 0x0178) /* LATIN CAPITAL LETTER Y WITH DIAERESIS */ \ UNI(0x5E, 0x015E) /* LATIN CAPITAL LETTER S WITH CEDILLA */ \ UNI(0x5F, 0x00DF) /* LATIN SMALL LETTER SHARP S */ \ UNI(0x60, 0x00E0) /* LATIN SMALL LETTER A WITH GRAVE */ \ UNI(0x61, 0x00E1) /* LATIN SMALL LETTER A WITH ACUTE */ \ UNI(0x62, 0x00E2) /* LATIN SMALL LETTER A WITH CIRCUMFLEX */ \ UNI(0x63, 0x00E3) /* LATIN SMALL LETTER A WITH TILDE */ \ UNI(0x64, 0x00E4) /* LATIN SMALL LETTER A WITH DIAERESIS */ \ UNI(0x65, 0x00E5) /* LATIN SMALL LETTER A WITH RING ABOVE */ \ UNI(0x66, 0x00E6) /* LATIN SMALL LETTER AE */ \ UNI(0x67, 0x00E7) /* LATIN SMALL LETTER C WITH CEDILLA */ \ UNI(0x68, 0x00E8) /* LATIN SMALL LETTER E WITH GRAVE */ \ UNI(0x69, 0x00E9) /* LATIN SMALL LETTER E WITH ACUTE */ \ UNI(0x6A, 0x00EA) /* LATIN SMALL LETTER E WITH CIRCUMFLEX */ \ UNI(0x6B, 0x00EB) /* LATIN SMALL LETTER E WITH DIAERESIS */ \ UNI(0x6C, 0x00EC) /* LATIN SMALL LETTER I WITH GRAVE */ \ UNI(0x6D, 0x00ED) /* LATIN SMALL LETTER I WITH ACUTE */ \ UNI(0x6E, 0x00EE) /* LATIN SMALL LETTER I WITH CIRCUMFLEX */ \ UNI(0x6F, 0x00EF) /* LATIN SMALL LETTER I WITH DIAERESIS */ \ UNI(0x70, 0x011F) /* LATIN SMALL LETTER G WITH BREVE */ \ UNI(0x71, 0x00F1) /* LATIN SMALL LETTER N WITH TILDE */ \ UNI(0x72, 0x00F2) /* LATIN SMALL LETTER O WITH GRAVE */ \ UNI(0x73, 0x00F3) /* LATIN SMALL LETTER O WITH ACUTE */ \ UNI(0x74, 0x00F4) /* LATIN SMALL LETTER O WITH CIRCUMFLEX */ \ UNI(0x75, 0x00F5) /* LATIN SMALL LETTER O WITH TILDE */ \ UNI(0x76, 0x00F6) /* LATIN SMALL LETTER O WITH DIAERESIS */ \ UNI(0x77, 0x0153) /* LATIN SMALL LIGATURE OE */ \ UNI(0x78, 0x00F8) /* LATIN SMALL LETTER O WITH STROKE */ \ UNI(0x79, 0x00F9) /* LATIN SMALL LETTER U WITH GRAVE */ \ UNI(0x7A, 0x00FA) /* LATIN SMALL LETTER U WITH ACUTE */ \ UNI(0x7B, 0x00FB) /* LATIN SMALL LETTER U WITH CIRCUMFLEX */ \ UNI(0x7C, 0x00FC) /* LATIN SMALL LETTER U WITH DIAERESIS */ \ UNI(0x7D, 0x00FF) /* LATIN SMALL LETTER Y WITH DIAERESIS */ \ UNI(0x7E, 0x015F) /* LATIN SMALL LETTER S WITH CEDILLA */ \ } \ end_CODEPAGE() #define unmap_DEC_Turkish_Supp(code,dft) \ switch (code) { \ MAP(0x24, 0x1B) /* reserved */ \ MAP(0x26, 0x1B) /* reserved */ \ MAP(0x28, 0xA4) /* DIAERESIS */ \ MAP(0x2C, 0x1B) /* reserved */ \ MAP(0x2D, 0x1B) /* reserved */ \ MAP(0x2E, 0x4F) /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ \ MAP(0x2F, 0x1B) /* reserved */ \ MAP(0x34, 0x1B) /* reserved */ \ MAP(0x38, 0x1B) /* reserved */ \ MAP(0x3E, 0x51) /* LATIN SMALL LETTER DOTLESS I */ \ MAP(0x50, 0x4E) /* LATIN CAPITAL LETTER G WITH BREVE */ \ MAP(0x57, 0x97) /* LATIN CAPITAL LIGATURE OE */ \ MAP(0x5D, 0x98) /* LATIN CAPITAL LETTER Y WITH DIAERESIS */ \ MAP(0x5E, 0x9F) /* LATIN CAPITAL LETTER S WITH CEDILLA */ \ MAP(0x70, 0x50) /* LATIN SMALL LETTER G WITH BREVE */ \ MAP(0x77, 0x99) /* LATIN SMALL LIGATURE OE */ \ MAP(0x7D, 0xFF) /* LATIN SMALL LETTER Y WITH DIAERESIS */ \ MAP(0x7E, 0x2A) /* LATIN SMALL LETTER S WITH CEDILLA */ \ default: dft; break; \ } /* * mentioned, but not documented in VT510 manual, etc., this uses * the ELOT927 table from Kermit 95: */ #define map_NRCS_Greek(code) \ switch (code) { \ UNI(0x61, 0x0391) /* CAPITAL GREEK LETTER ALPHA */ \ UNI(0x62, 0x0392) /* CAPITAL GREEK LETTER BETA */ \ UNI(0x63, 0x0393) /* CAPITAL GREEK LETTER GAMMA */ \ UNI(0x64, 0x0394) /* CAPITAL GREEK LETTER DELTA */ \ UNI(0x65, 0x0395) /* CAPITAL GREEK LETTER EPSILON */ \ UNI(0x66, 0x0396) /* CAPITAL GREEK LETTER ZETA */ \ UNI(0x67, 0x0397) /* CAPITAL GREEK LETTER ETA */ \ UNI(0x68, 0x0398) /* CAPITAL GREEK LETTER THETA */ \ UNI(0x69, 0x0399) /* CAPITAL GREEK LETTER IOTA */ \ UNI(0x6a, 0x039A) /* CAPITAL GREEK LETTER KAPPA */ \ UNI(0x6b, 0x039B) /* CAPITAL GREEK LETTER LAMDA */ \ UNI(0x6c, 0x039C) /* CAPITAL GREEK LETTER MU */ \ UNI(0x6d, 0x039D) /* CAPITAL GREEK LETTER NU */ \ UNI(0x6e, 0x03A7) /* CAPITAL GREEK LETTER KSI (CHI) */ \ UNI(0x6f, 0x039F) /* CAPITAL GREEK LETTER OMICRON */ \ UNI(0x70, 0x03A0) /* CAPITAL GREEK LETTER PI */ \ UNI(0x71, 0x03A1) /* CAPITAL GREEK LETTER RHO */ \ UNI(0x72, 0x03A3) /* CAPITAL GREEK LETTER SIGMA */ \ UNI(0x73, 0x03A4) /* CAPITAL GREEK LETTER TAU */ \ UNI(0x74, 0x03A5) /* CAPITAL GREEK LETTER UPSILON */ \ UNI(0x75, 0x03A6) /* CAPITAL GREEK LETTER FI (PHI) */ \ UNI(0x76, 0x039E) /* CAPITAL GREEK LETTER XI */ \ UNI(0x77, 0x03A8) /* CAPITAL GREEK LETTER PSI */ \ UNI(0x78, 0x03A9) /* CAPITAL GREEK LETTER OMEGA */ \ XXX(0x79, UNDEF) /* unused */ \ XXX(0x7a, UNDEF) /* unused */ \ } #define unmap_NRCS_Greek(code,dft) \ switch (code) { \ MAP(0x79, 0x1B) /* unused */ \ MAP(0x7a, 0x1B) /* unused */ \ default: dft; break; \ } /* * figure A-21 "DEC 7-Bit Hebrew Character Set" */ #define map_NRCS_Hebrew(code) \ switch (code) { \ UNI(0x60, 0x05D0) /* HEBREW LETTER ALEF */ \ UNI(0x61, 0x05D1) /* HEBREW LETTER BET */ \ UNI(0x62, 0x05D2) /* HEBREW LETTER GIMEL */ \ UNI(0x63, 0x05D3) /* HEBREW LETTER DALET */ \ UNI(0x64, 0x05D4) /* HEBREW LETTER HE */ \ UNI(0x65, 0x05D5) /* HEBREW LETTER VAV */ \ UNI(0x66, 0x05D6) /* HEBREW LETTER ZAYIN */ \ UNI(0x67, 0x05D7) /* HEBREW LETTER HET */ \ UNI(0x68, 0x05D8) /* HEBREW LETTER TET */ \ UNI(0x69, 0x05D9) /* HEBREW LETTER YOD */ \ UNI(0x6a, 0x05DA) /* HEBREW LETTER FINAL KAF */ \ UNI(0x6b, 0x05DB) /* HEBREW LETTER KAF */ \ UNI(0x6c, 0x05DC) /* HEBREW LETTER LAMED */ \ UNI(0x6d, 0x05DD) /* HEBREW LETTER FINAL MEM */ \ UNI(0x6e, 0x05DE) /* HEBREW LETTER MEM */ \ UNI(0x6f, 0x05DF) /* HEBREW LETTER FINAL NUN */ \ UNI(0x70, 0x05E0) /* HEBREW LETTER NUN */ \ UNI(0x71, 0x05E1) /* HEBREW LETTER SAMEKH */ \ UNI(0x72, 0x05E2) /* HEBREW LETTER AYIN */ \ UNI(0x73, 0x05E3) /* HEBREW LETTER FINAL PE */ \ UNI(0x74, 0x05E4) /* HEBREW LETTER PE */ \ UNI(0x75, 0x05E5) /* HEBREW LETTER FINAL TSADI */ \ UNI(0x76, 0x05E6) /* HEBREW LETTER TSADI */ \ UNI(0x77, 0x05E7) /* HEBREW LETTER QOF */ \ UNI(0x78, 0x05E8) /* HEBREW LETTER RESH */ \ UNI(0x79, 0x05E9) /* HEBREW LETTER SHIN */ \ UNI(0x7a, 0x05EA) /* HEBREW LETTER TAV */ \ } #define unmap_NRCS_Hebrew(code,dft) /* nothing */ /* * VT520/VT525 manual p 4-35 explains "SCS" as Serbo-Croatian. The remaining * "S" may be Slovene. With that clue, choose ISO-IR-141, which provides a * chart with names of suitable replacement characters. */ #define map_NRCS_Serbo_Croatian(code) \ switch (code) { \ UNI(0x40, 0x017D) /* LATIN CAPITAL LETTER Z WITH CARON */ \ UNI(0x5B, 0x0160) /* LATIN CAPITAL LETTER S WITH CARON */ \ UNI(0x5C, 0x0110) /* LATIN CAPITAL LETTER D WITH STROKE */ \ UNI(0x5D, 0x0106) /* LATIN CAPITAL LETTER C WITH ACUTE */ \ UNI(0x5E, 0x010C) /* LATIN CAPITAL LETTER C WITH CARON */ \ UNI(0x60, 0x017E) /* LATIN SMALL LETTER Z WITH CARON */ \ UNI(0x7B, 0x0161) /* LATIN SMALL LETTER S WITH CARON */ \ UNI(0x7C, 0x0111) /* LATIN SMALL LETTER D WITH STROKE */ \ UNI(0x7D, 0x0107) /* LATIN SMALL LETTER C WITH ACUTE */ \ UNI(0x7E, 0x010D) /* LATIN SMALL LETTER C WITH CARON */ \ } #define unmap_NRCS_Serbo_Croatian(code,dft) /* nothing */ /* * VT520/VT525 manual p 7-2 explains "Russian" as KOI-7, though the dialect * is unknown. Choose the one Kermit used. */ #define map_NRCS_Russian(code) \ switch (code) { \ UNI(0x60, 0x042E) /* CYRILLIC CAPITAL LETTER YU */ \ UNI(0x61, 0x0410) /* CYRILLIC CAPITAL LETTER A */ \ UNI(0x62, 0x0411) /* CYRILLIC CAPITAL LETTER BE */ \ UNI(0x63, 0x0426) /* CYRILLIC CAPITAL LETTER TSE */ \ UNI(0x64, 0x0414) /* CYRILLIC CAPITAL LETTER DE */ \ UNI(0x65, 0x0415) /* CYRILLIC CAPITAL LETTER IE */ \ UNI(0x66, 0x0424) /* CYRILLIC CAPITAL LETTER EF */ \ UNI(0x67, 0x0413) /* CYRILLIC CAPITAL LETTER GHE */ \ UNI(0x68, 0x0425) /* CYRILLIC CAPITAL LETTER HA */ \ UNI(0x69, 0x0418) /* CYRILLIC CAPITAL LETTER I */ \ UNI(0x6A, 0x0419) /* CYRILLIC CAPITAL LETTER SHORT I */ \ UNI(0x6B, 0x041A) /* CYRILLIC CAPITAL LETTER KA */ \ UNI(0x6C, 0x041B) /* CYRILLIC CAPITAL LETTER EL */ \ UNI(0x6D, 0x041C) /* CYRILLIC CAPITAL LETTER EM */ \ UNI(0x6E, 0x041D) /* CYRILLIC CAPITAL LETTER EN */ \ UNI(0x6F, 0x041E) /* CYRILLIC CAPITAL LETTER O */ \ UNI(0x70, 0x041F) /* CYRILLIC CAPITAL LETTER PE */ \ UNI(0x71, 0x042F) /* CYRILLIC CAPITAL LETTER YA */ \ UNI(0x72, 0x0420) /* CYRILLIC CAPITAL LETTER ER */ \ UNI(0x73, 0x0421) /* CYRILLIC CAPITAL LETTER ES */ \ UNI(0x74, 0x0422) /* CYRILLIC CAPITAL LETTER TE */ \ UNI(0x75, 0x0423) /* CYRILLIC CAPITAL LETTER U */ \ UNI(0x76, 0x0416) /* CYRILLIC CAPITAL LETTER ZHE */ \ UNI(0x77, 0x0412) /* CYRILLIC CAPITAL LETTER VE */ \ UNI(0x78, 0x042C) /* CYRILLIC CAPITAL LETTER SOFT SIGN */ \ UNI(0x79, 0x042B) /* CYRILLIC CAPITAL LETTER YERU */ \ UNI(0x7A, 0x0417) /* CYRILLIC CAPITAL LETTER ZE */ \ UNI(0x7B, 0x0428) /* CYRILLIC CAPITAL LETTER SHA */ \ UNI(0x7C, 0x042D) /* CYRILLIC CAPITAL LETTER E */ \ UNI(0x7D, 0x0429) /* CYRILLIC CAPITAL LETTER SHCHA */ \ UNI(0x7E, 0x0427) /* CYRILLIC CAPITAL LETTER CHE */ \ } #define unmap_NRCS_Russian(code,dft) /* nothing */ /* * figure A-26 "DEC 7-Bit Turkish Character Set" */ #define map_NRCS_Turkish(code) \ switch (code) { \ UNI(0x26, 0x011F) /* LATIN SMALL LETTER G WITH BREVE */ \ UNI(0x40, 0x0130) /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ \ UNI(0x5b, 0x015E) /* LATIN CAPITAL LETTER S WITH CEDILLA */ \ UNI(0x5c, 0x00D6) /* LATIN CAPITAL LETTER O WITH DIAERESIS */ \ UNI(0x5d, 0x00C7) /* LATIN CAPITAL LETTER C WITH CEDILLA */ \ UNI(0x5e, 0x00dC) /* LATIN CAPITAL LETTER U WITH DIAERESIS */ \ UNI(0x60, 0x011E) /* LATIN CAPITAL LETTER G WITH BREVE */ \ UNI(0x7b, 0x015F) /* LATIN SMALL LETTER S WITH CEDILLA */ \ UNI(0x7c, 0x00F6) /* LATIN SMALL LETTER O WITH DIAERESIS */ \ UNI(0x7d, 0x00E7) /* LATIN SMALL LETTER C WITH CEDILLA */ \ UNI(0x7e, 0x00FC) /* LATIN SMALL LETTER U WITH DIAERESIS */ \ } #define unmap_NRCS_Turkish(code,dft) /* nothing */ #else #define map_DEC_Cyrillic(code) /* nothing */ #define unmap_DEC_Cyrillic(code,dft) dft #define map_DEC_Greek_Supp(code) /* nothing */ #define unmap_DEC_Greek_Supp(code,dft) dft #define map_DEC_Hebrew_Supp(code) /* nothing */ #define unmap_DEC_Hebrew_Supp(code,dft) dft #define map_DEC_Technical(code) /* nothing */ #define unmap_DEC_Technical(code,dft) dft #define map_DEC_Turkish_Supp(code) /* nothing */ #define unmap_DEC_Turkish_Supp(code,dft) dft #define map_ISO_Greek_Supp(code) /* nothing */ #define unmap_ISO_Greek_Supp(code,dft) dft #define map_ISO_Hebrew(code) /* nothing */ #define unmap_ISO_Hebrew(code,dft) dft #define map_ISO_Latin_2(code) /* nothing */ #define unmap_ISO_Latin_2(code,dft) dft #define map_ISO_Latin_5(code) /* nothing */ #define unmap_ISO_Latin_5(code,dft) dft #define map_ISO_Latin_Cyrillic(code) /* nothing */ #define unmap_ISO_Latin_Cyrillic(code,dft) dft #define map_JIS_Katakana(code) /* nothing */ #define unmap_JIS_Katakana(code,dft) dft #define map_JIS_Roman(code) /* nothing */ #define unmap_JIS_Roman(code,dft) dft #define map_NRCS_Greek(code) /* nothing */ #define unmap_NRCS_Greek(code,dft) dft #define map_NRCS_Hebrew(code) /* nothing */ #define unmap_NRCS_Hebrew(code,dft) dft #define map_NRCS_Russian(code) /* nothing */ #define unmap_NRCS_Russian(code,dft) dft #define map_NRCS_Serbo_Croatian(code) /* nothing */ #define unmap_NRCS_Serbo_Croatian(code,dft) dft #define map_NRCS_Turkish(code) /* nothing */ #define unmap_NRCS_Turkish(code,dft) dft #endif /* OPT_WIDE_CHARS */ #endif /* included_charsets_h */ xterm-399/xterm.appdata.xml0000644000000000000000000000341515012470675014541 0ustar rootroot xterm.desktop CC-BY-3.0 X11 XTerm Terminal emulator for the X Window System

XTerm is the standard terminal emulator for the X Window System. It provides DEC VT102/VT220 and selected features from higher-level terminals such as VT320/VT420/VT520 (VTxxx). It also provides Tektronix 4014 emulation for programs that cannot use the window system directly.

You would use xterm to get a shell prompt, to run command-line programs.

https://invisible-island.net/xterm/images/merged-xterm-menus-16x9.png XTerm with its popup menus superimposed shell prompt command commandline cmd terminal https://invisible-island.net/xterm/ dickey@invisible-island.net Thomas E. Dickey https://invisible-island.net/xterm/xterm.faq.html#report_bugs https://invisible-island.net/xterm/xterm.faq.html
xterm-399/configure.in0000644000000000000000000012036215012457327013560 0ustar rootrootdnl $XTermId: configure.in,v 1.405 2025/05/18 22:27:35 tom Exp $ dnl dnl ----------------------------------------------------------------------------- dnl this file is part of xterm dnl dnl Copyright 1997-2024,2025 by Thomas E. Dickey dnl dnl All Rights Reserved dnl dnl Permission is hereby granted, free of charge, to any person obtaining a dnl copy of this software and associated documentation files (the dnl "Software"), to deal in the Software without restriction, including dnl without limitation the rights to use, copy, modify, merge, publish, dnl distribute, sublicense, and/or sell copies of the Software, and to dnl permit persons to whom the Software is furnished to do so, subject to dnl the following conditions: dnl dnl The above copyright notice and this permission notice shall be included dnl in all copies or substantial portions of the Software. dnl dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. dnl IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY dnl CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, dnl TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE dnl SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. dnl dnl Except as contained in this notice, the name(s) of the above copyright dnl holders shall not be used in advertising or otherwise to promote the dnl sale, use or other dealings in this Software without prior written dnl authorization. dnl --------------------------------------------------------------------------- dnl Process this file with autoconf to produce a configure script. dnl AC_PREREQ(2.52.20210509) AC_INIT AC_CONFIG_SRCDIR([charproc.c]) AC_CONFIG_HEADER(xtermcfg.h:xtermcfg.hin) CF_CHECK_CACHE ### checks for alternative programs dnl Only add to this case statement when a system has a compiler that is not dnl detected by AC_PROG_CC. case "$host_os" in (openedition) : "${CFLAGS=\"-O2 -Wc,dll -Wl,EDIT=NO\"}" : "${CPPFLAGS=\"-D_ALL_SOURCE\"}" : "${LIBS=\"/usr/lib/Xaw.x /usr/lib/SM.x /usr/lib/ICE.x /usr/lib/X11.x\"}" : "${CC=c89}";; (darwin*) : "${LDFLAGS}=\"${LDFLAGS} -Wl,-bind_at_load\"";; esac CF_PROG_CC AC_C_INLINE AC_PROG_CPP AC_PROG_AWK AC_PROG_INSTALL AC_PROG_LN_S AC_ARG_PROGRAM CF_PROG_LINT ### checks for compiler characteristics CF_XOPEN_SOURCE(700) CF_SIGWINCH ### checks for header files AC_CHECK_DECL(exit) AC_CHECK_HEADERS( \ ncurses/curses.h \ ncurses/term.h \ sys/ptem.h \ sys/ttydefaults.h \ term.h \ termios.h \ wchar.h \ ) AC_HEADER_TIME AM_LANGINFO_CODESET ### checks for typedefs CF_SIG_ATOMIC_T AC_CHECK_TYPE(time_t, long) CF_TYPE_CC_T CF_TYPE_NFDS_T AC_TYPE_MODE_T AC_TYPE_PID_T AC_TYPE_UID_T AC_TYPE_OFF_T ### checks for library functions AC_CHECK_FUNCS( \ gethostname \ getusershell \ endusershell \ getlogin \ initgroups \ mkdtemp \ putenv \ unsetenv \ sched_yield \ setpgid \ setsid \ tcgetattr \ waitpid \ wcswidth \ wcwidth ) CF_FUNC_GETTIME CF_FUNC_STRFTIME CF_MKSTEMP CF_SETITIMER CF_UTMP CF_STRUCT_LASTLOG CF_POSIX_SAVED_IDS CF_HELP_MESSAGE(Compile/Install Options:) CF_FUNC_TGETENT CF_WITH_APP_CLASS(XTerm) CF_WITH_APP_DEFAULTS CF_WITH_ICON_NAME(mini.xterm) CF_WITH_ICON_SYMLINK(xterm) # Install all icons except for the overused "terminal". cf_cv_icon_list= for my_item in $srcdir/icons/*.svg do test -f "$my_item" || continue cf_icon_name=`echo "$my_item" |sed -e "s,.svg,," -e "s,^$srcdir/,,"` case $cf_icon_name in (*_48x48) continue ;; esac CF_VERBOSE(adding $cf_icon_name to icon-list) cf_cv_icon_list="$cf_cv_icon_list $cf_icon_name" if test -f "${cf_icon_name}_48x48.png" then CF_VERBOSE(adding ${cf_icon_name}_48x48 to icon-list) cf_cv_icon_list="$cf_cv_icon_list ${cf_icon_name}_48x48" fi done CF_WITH_ICON_THEME([$cf_cv_icon_list],,,icons/${ICON_NAME}_48x48) CF_DISABLE_DESKTOP(xterm) CF_WITH_DESKTOP_CATEGORY(xterm, [*rxvt*|*konsole|*[[Tt]]erminal], [System|TerminalEmulator|*]) AC_MSG_CHECKING(for install-permissions reference) AC_ARG_WITH(reference, [ --with-reference=XXX program to use as permissions-reference], [with_reference=$withval], [with_reference=xterm]) AC_MSG_RESULT($with_reference) with_full_paths=yes CF_PATH_PROG(XTERM_PATH,$with_reference) # If any of --program-prefix, --program-suffix or --program-transform-name is # given, accept an option tell the makefile to create a symbolic link, e.g., # to "xterm" on install. XTERM_SYMLINK=NONE AC_SUBST(XTERM_SYMLINK) if test "$program_transform_name" != "'s,,,'" ; then cf_name=`echo "$program_transform_name" | sed -e '[s,\\$\\$,$,g]'` cf_name=`echo xterm |sed -e "$cf_name"` AC_MSG_CHECKING(for symbolic link to create to $cf_name) AC_ARG_WITH(xterm-symlink, [[ --with-xterm-symlink[=XXX] make symbolic link to installed xterm]], [with_symlink=$withval], [with_symlink=xterm]) AC_MSG_RESULT($with_symlink) test "$with_symlink" = yes && with_symlink=xterm test -n "$with_symlink" && \ test "$with_symlink" != no && \ test "$with_symlink" != "$cf_name" && \ XTERM_SYMLINK="$with_symlink" fi AC_MSG_CHECKING(if you want to disable openpty) CF_ARG_DISABLE(openpty, [ --disable-openpty disable openpty, prefer other interfaces], [disable_openpty=yes], [disable_openpty=no], no) AC_MSG_RESULT($disable_openpty) AC_MSG_CHECKING(if you want to disable setuid) CF_ARG_DISABLE(setuid, [ --disable-setuid disable setuid in xterm, do not install setuid/setgid], [disable_setuid=yes], [disable_setuid=no], no) AC_MSG_RESULT($disable_setuid) AC_MSG_CHECKING(if you want to disable setgid) CF_ARG_DISABLE(setgid, [ --disable-setgid disable setgid in xterm, do not install setuid/setgid], [disable_setgid=yes], [disable_setgid=no], no) AC_MSG_RESULT($disable_setgid) AC_MSG_CHECKING(if you want to run xterm setuid to a given user) AC_ARG_WITH(setuid, [[ --with-setuid[=XXX] use the given setuid user]], [use_given_setuid=$withval], [use_given_setuid=no]) AC_MSG_RESULT($use_given_setuid) if test "$use_given_setuid" != no ; then if test "$use_given_setuid" = yes ; then cf_cv_given_setuid=root else cf_cv_given_setuid=$use_given_setuid fi # inherit SINSTALL_OPTS from environment to allow packager to customize it. SINSTALL_OPTS="$SINSTALL_OPTS u+s -u $cf_cv_given_setuid" fi AC_MSG_CHECKING(if you want to run xterm setgid to match utmp/utmpx file) AC_ARG_WITH(utmp-setgid, [[ --with-utmp-setgid[=XXX] use setgid to match utmp/utmpx file]], [use_utmp_setgid=$withval], [use_utmp_setgid=no]) AC_MSG_RESULT($use_utmp_setgid) if test "$use_utmp_setgid" != no ; then if test "$use_utmp_setgid" = yes ; then CF_UTMP_GROUP else cf_cv_utmp_group=$use_utmp_setgid fi if test "$cf_cv_posix_saved_ids" != yes ; then AC_MSG_ERROR(Your system does not support POSIX saved-ids) fi AC_DEFINE(USE_UTMP_SETGID,1,[Define to 1 if we should use setgid to access utmp/utmpx]) SINSTALL_OPTS="$SINSTALL_OPTS g+s -g $cf_cv_utmp_group" fi AC_SUBST(SINSTALL_OPTS) AC_MSG_CHECKING(if you want to link with utempter) AC_ARG_WITH(utempter, [ --with-utempter use utempter library for access to utmp], [use_utempter=$withval], [use_utempter=no]) AC_MSG_RESULT($use_utempter) if test "$use_utempter" = yes ; then CF_UTEMPTER test "$cf_cv_have_utempter" != yes && use_utempter=no else use_utempter=no fi # Some configurations permit (or require) either setuid or setgid mode. # Let the user decide. if test "$use_utempter" = yes ; then if test "${enable_setuid+set}" != set ; then disable_setuid=yes CF_VERBOSE([No --disable-setuid option given, force to yes]) fi fi # We use these for the manpage: CF_WITH_UTMP_PATH CF_WITH_WTMP_PATH ### checks for external data CF_ERRNO CF_TTY_GROUP ### checks for system services and user specified options AC_PATH_XTRA CF_POSIX_WAIT CF_SYSV CF_SVR4 CF_X_TOOLKIT AC_CHECK_HEADERS( \ X11/DECkeysym.h \ X11/Sunkeysym.h \ X11/XF86keysym.h \ X11/XKBlib.h \ X11/TranslateI.h \ X11/Xpoll.h \ X11/extensions/XKB.h \ ) CF_WITH_XPM CF_WITH_XINERAMA CF_X_ATHENA CF_TYPE_FD_MASK CF_TERMIO_C_ISPEED CF_TERMIOS_TYPES # The Xcursor library is normally (weakly) linked via the X11 library rather # than directly to applications. xterm can select a cursor theme; users can # also use environment variables to select cursor size. We would only notice # the library if there are development files for it. Provide a way to disable # the feature if it is unwanted. AC_MSG_CHECKING(if we expect to use the Xcursor library) CF_ARG_DISABLE(xcursor, [ --disable-xcursor disable cursorTheme resource], [enable_xcursor=no], [enable_xcursor=yes]) AC_MSG_RESULT($enable_xcursor) if test "$enable_xcursor" = yes; then AC_DEFINE(HAVE_LIB_XCURSOR,1,[Define to 1 if we expect to use the Xcursor library]) fi LIBS="$LIBS $X_EXTRA_LIBS" CF_FUNC_GRANTPT CF_XKB_QUERY_EXTENSION CF_XKB_KEYCODE_TO_KEYSYM CF_XKB_BELL_EXT AC_CHECK_FUNCS(Xutf8LookupString, [],[ EXTRAHDRS="$EXTRAHDRS xutf8.h" EXTRASRCS="$EXTRASRCS xutf8.c" EXTRAOBJS="$EXTRAOBJS xutf8.o" ]) CF_WITH_IMAKE_CFLAGS($(MAIN_DEFINES) $(VENDORMANDEFS)) CF_WITH_MAN2HTML # If we have already established that there is a full termcap implementation, # suppress the definitions for terminfo that we make have imported from the # imake-file. if test "x$cf_cv_lib_tgetent" != xno || test "x$cf_cv_lib_part_tgetent" != xno ; then case "$IMAKE_CFLAGS" in (*-DUSE_TERMINFO\ -DHAVE_TIGETSTR*) CF_UNDO_CFLAGS(IMAKE_CFLAGS,terminfo,[-DUSE_TERMINFO[[ ]]*-DHAVE_TIGETSTR[[ ]]*]) CF_UNDO_CFLAGS(CPPFLAGS,terminfo,[-DUSE_TERMINFO[[ ]]*-DHAVE_TIGETSTR[[ ]]*]) ;; esac fi CF_HELP_MESSAGE(Terminal Configuration:) AC_MSG_CHECKING(for default terminal-id) AC_ARG_WITH(terminal-id, [ --with-terminal-id=V set default decTerminalID (default: vt420)], [default_termid=$withval], [default_termid=vt420]) AC_MSG_RESULT($default_termid) case $default_termid in (vt*) default_termid=`echo $default_termid | sed -e 's/^..//'` ;; ([[1-9]][[0-9]][[0-9]]|[[1-9]][[0-9]]) ;; (*) AC_MSG_ERROR([expected a number, not $default_termid]) ;; esac AC_DEFINE_UNQUOTED(DFT_DECID,"$default_termid",[default terminal-id]) AC_SUBST(default_termid) AC_MSG_CHECKING(for default terminal-type) AC_ARG_WITH(terminal-type, [ --with-terminal-type=T set default $TERM (default: xterm)], [default_TERM=$withval], [default_TERM=xterm]) AC_MSG_RESULT($default_TERM) AC_DEFINE_UNQUOTED(DFT_TERMTYPE,"$default_TERM",[default terminal-type]) AC_SUBST(default_TERM) ############################################################################### AC_MSG_CHECKING(if backarrow-key should be BS) CF_ARG_DISABLE(backarrow-key, [ --enable-backarrow-key set default backarrowKey resource (default: true)], [backarrow_is_bs=$enableval], [backarrow_is_bs=yes]) CF_XBOOL_RESULT(DEF_BACKARO_BS,backarrow_is_bs,[Define to 1 if backarrow-key should be BS]) AC_MSG_CHECKING(if backarrow-key should be treated as erase) CF_ARG_ENABLE(backarrow-is-erase, [ --enable-backarrow-is-erase set default backarrowKeyIsErase resource (default: false)], [backarrow_is_erase=$enableval], [backarrow_is_erase=no]) CF_XBOOL_RESULT(DEF_BACKARO_ERASE,backarrow_is_erase,[Define to 1 if backarrow-key should be treated as erase]) AC_MSG_CHECKING(for default backspace/DEL setting) AC_ARG_ENABLE(delete-is-del, [ --enable-delete-is-del set default deleteIsDEL resource (default: maybe)], [delete_is_del=$enableval], [delete_is_del=maybe]) CF_XBOOL_RESULT(DEFDELETE_DEL,delete_is_del,[Define to 1 if default backspace/DEL setting is DEL]) AC_MSG_CHECKING(for default pty initial erase setting) AC_ARG_ENABLE(pty-erase, [ --enable-pty-erase set default ptyInitialErase resource (default: maybe)], [initial_erase=$enableval], [initial_erase=False]) CF_XBOOL_RESULT(DEF_INITIAL_ERASE,initial_erase,[Define to 1 if default pty initial erase setting is TRUE]) AC_MSG_CHECKING(if alt should send ESC) CF_ARG_ENABLE(alt-sends-esc, [ --enable-alt-sends-esc set default altSendsEscape resource (default: no)], [alt_sends_esc=$enableval], [alt_sends_esc=no]) CF_XBOOL_RESULT(DEF_ALT_SENDS_ESC,alt_sends_esc,[Define to 1 if alt should send ESC]) AC_MSG_CHECKING(if meta should send ESC) CF_ARG_ENABLE(meta-sends-esc, [ --enable-meta-sends-esc set default metaSendsEscape resource (default: no)], [meta_sends_esc=$enableval], [meta_sends_esc=no]) CF_XBOOL_RESULT(DEF_META_SENDS_ESC,meta_sends_esc,[Define to 1 if meta should send ESC]) ############################################################################### AC_CHECK_PROG(cf_tic_prog,tic,yes,no) if test "$cf_tic_prog" = yes ; then if test -n "$TERMINFO" then case "$TERMINFO" in (/*) test -d "$TERMINFO" || unset TERMINFO ;; (*) unset TERMINFO ;; esac fi AC_MSG_CHECKING(for private terminfo-directory) AC_ARG_WITH(own-terminfo, [[ --with-own-terminfo[=P] set default $TERMINFO (default: from environment)]], [TERMINFO_DIR=$withval], [TERMINFO_DIR=${TERMINFO-none}]) AC_MSG_RESULT($TERMINFO_DIR) if test "$TERMINFO_DIR" = yes ; then AC_MSG_WARN(no value given) elif test "$TERMINFO_DIR" != none ; then if test -d "$TERMINFO_DIR" ; then AC_DEFINE_UNQUOTED(OWN_TERMINFO_DIR,"$TERMINFO_DIR",[Define to override default TERMINFO value]) AC_MSG_CHECKING(if \$TERMINFO should also be set) AC_ARG_ENABLE(env-terminfo, [ --enable-env-terminfo setenv $TERMINFO if --with-own-terminfo gives value], [cf_env_terminfo=yes], [cf_env_terminfo=no]) AC_MSG_RESULT($cf_env_terminfo) test $cf_env_terminfo = yes && AC_DEFINE(OWN_TERMINFO_ENV,1,[Define to 1 to enable setenv of $TERMINFO value]) else AC_MSG_WARN(not a directory) fi elif test "$prefix" != NONE ; then TERMINFO_DIR='${prefix}/lib/terminfo' elif test -d /usr/lib/terminfo ; then TERMINFO_DIR=/usr/lib/terminfo else TERMINFO_DIR= fi SET_TERMINFO= if test -n "$TERMINFO_DIR" ; then TERMINFO_DIR='${DESTDIR}'$TERMINFO_DIR SET_TERMINFO='TERMINFO=${TERMINFO_DIR}' fi no_ticprog= else no_ticprog="#" TERMINFO_DIR= SET_TERMINFO= fi AC_SUBST(no_ticprog) AC_SUBST(TERMINFO_DIR) AC_SUBST(SET_TERMINFO) ############################################################################### CF_HELP_MESSAGE(Optional Features:) AC_MSG_CHECKING(if you want active-icons) CF_ARG_DISABLE(active-icon, [ --disable-active-icon disable X11R6.3 active-icon feature], [enable_active_icon=no], [enable_active_icon=yes]) AC_MSG_RESULT($enable_active_icon) if test "$enable_active_icon" = no ; then AC_DEFINE(NO_ACTIVE_ICON,1,[Define to 1 to disable X11R6.3 active-icon feature]) fi AC_MSG_CHECKING(if you want ANSI color) CF_ARG_DISABLE(ansi-color, [ --disable-ansi-color disable ANSI color], [enable_ansi_color=no], [enable_ansi_color=yes]) AC_MSG_RESULT($enable_ansi_color) test "$enable_ansi_color" = no && AC_DEFINE(OPT_ISO_COLORS,0,[Define to 0 to disable ANSI color]) if test "$enable_ansi_color" = yes ; then AC_MSG_CHECKING(if you want 16 colors like aixterm) CF_ARG_DISABLE(16-color, [ --disable-16-color disable 16-color support], [enable_16_color=no], [enable_16_color=yes]) AC_MSG_RESULT($enable_16_color) test "$enable_16_color" = no && AC_DEFINE(OPT_AIX_COLORS,0,[Define to 0 to disable 16-color support]) AC_MSG_CHECKING(if you want 256 colors) CF_ARG_DISABLE(256-color, [ --disable-256-color disable 256-color support], [enable_256_color=no], [enable_256_color=yes]) AC_MSG_RESULT($enable_256_color) if test "$enable_256_color" = yes ; then CHARPROC_DEPS="$CHARPROC_DEPS 256colres.h" EXTRAHDRS="$EXTRAHDRS 256colres.h" AC_DEFINE(OPT_256_COLORS,1,[Define to 1 to enable 256-color support]) AC_MSG_CHECKING(if you want direct-color support) CF_ARG_DISABLE(direct-color, [ --disable-direct-color disable direct-color support], [enable_direct_color=no], [enable_direct_color=yes]) AC_MSG_RESULT($enable_direct_color) if test "$enable_direct_color" = yes ; then AC_DEFINE(OPT_DIRECT_COLOR,1,[Define to 1 to enable direct-color support]) fi else AC_MSG_CHECKING(if you want 88 colors) CF_ARG_DISABLE(88-color, [ --disable-88-color disable 88-color support], [enable_88_color=no], [enable_88_color=yes]) AC_MSG_RESULT($enable_88_color) if test "$enable_88_color" = yes ; then CHARPROC_DEPS="$CHARPROC_DEPS 88colres.h" EXTRAHDRS="$EXTRAHDRS 88colres.h" AC_DEFINE(OPT_88_COLORS,1,[Define to 1 to enable 88-color support]) fi fi fi AC_MSG_CHECKING(if you want blinking cursor) CF_ARG_DISABLE(blink-cursor, [ --disable-blink-cursor disable support for blinking cursor], [enable_blink_curs=no], [enable_blink_curs=yes]) AC_MSG_RESULT($enable_blink_curs) test "$enable_blink_curs" = no && AC_DEFINE(OPT_BLINK_CURS,0,[Define to 0 to disable support for blinking cursor]) AC_MSG_CHECKING(if you want support for block-selection) CF_ARG_ENABLE(block-select, [ --enable-block-select meta-button1 begins block-selection], [enable_block_select=yes], [enable_block_select=no]) AC_MSG_RESULT($enable_block_select) if test "$enable_block_select" = yes ; then AC_DEFINE(OPT_BLOCK_SELECT,1,[Define to 1 to allow block-selections]) else AC_DEFINE(OPT_BLOCK_SELECT,0,[Define to 0 to disallow block-selections]) fi AC_MSG_CHECKING(if you want to ignore Linux's broken palette-strings) case $host_os in (linux*) assume_broken_osc=yes ;; (*) assume_broken_osc=no ;; esac CF_ARG_OPTION(broken-osc, [ --enable-broken-osc allow broken Linux OSC-strings], [enable_broken_osc=$enableval], [enable_broken_osc=$enableval], [$assume_broken_osc]) AC_MSG_RESULT($enable_broken_osc) if test "$enable_broken_osc" = yes ; then AC_DEFINE(OPT_BROKEN_OSC,1,[Define to 1 to allow broken Linux OSC-strings]) else AC_DEFINE(OPT_BROKEN_OSC,0,[Define to 0 to disallow broken Linux OSC-strings]) fi AC_MSG_CHECKING(if you want to allow broken string-terminators) CF_ARG_ENABLE(broken-st, [ --disable-broken-st disallow broken string-terminators], [enable_broken_st=no], [enable_broken_st=yes]) AC_MSG_RESULT($enable_broken_st) test "$enable_broken_st" = no && AC_DEFINE(OPT_BROKEN_ST,0,[Define to 0 to disallow broken string-terminators]) AC_MSG_CHECKING(if you want to compile-in icon data) CF_ARG_ENABLE(builtin-xpms, [ --enable-builtin-xpms compile-in icon data], [enable_builtin_xpms=yes], [enable_builtin_xpms=no]) AC_MSG_RESULT($enable_builtin_xpms) test "$enable_builtin_xpms" = yes && AC_DEFINE(OPT_BUILTIN_XPMS,1,[Define to 1 to compile-in icon data]) AC_MSG_CHECKING(if you want printable 128-159) CF_ARG_DISABLE(c1-print, [ --disable-c1-print disallow -k8 option for printable 128-159], [enable_c1_print=no], [enable_c1_print=yes]) AC_MSG_RESULT($enable_c1_print) test "$enable_c1_print" = no && AC_DEFINE(OPT_C1_PRINT,0,[Define to 0 to disallow -k8 option for printable 128-159]) if test "$enable_ansi_color" = yes ; then AC_MSG_CHECKING(if you want bold colors mapped like IBM PC) CF_ARG_DISABLE(bold-color, [ --disable-bold-color disable PC-style mapping of bold colors], [enable_pc_color=no], [enable_pc_color=yes]) AC_MSG_RESULT($enable_pc_color) test "$enable_pc_color" = no && AC_DEFINE(OPT_PC_COLORS,0,[Define to 0 to disable PC-style mapping of bold colors]) AC_MSG_CHECKING(if you want separate color-classes) CF_ARG_DISABLE(color-class, [ --disable-color-class disable separate color class resources], [enable_color_class=no], [enable_color_class=yes]) AC_MSG_RESULT($enable_color_class) test "$enable_color_class" = no && AC_DEFINE(OPT_COLOR_CLASS,0,[Define to 0 to disable separate color class resources]) AC_MSG_CHECKING(if you want color-mode enabled by default) CF_ARG_DISABLE(color-mode, [ --disable-color-mode disable default colorMode resource], [default_colormode=no], [default_colormode=yes]) AC_MSG_RESULT($default_colormode) test "$default_colormode" = no && AC_DEFINE(DFT_COLORMODE,0,[Define to 0 if you want color-mode enabled by default]) fi AC_MSG_CHECKING(if you want support for color highlighting) CF_ARG_DISABLE(highlighting, [ --disable-highlighting disable support for color highlighting], [default_highlight=no], [default_highlight=yes]) AC_MSG_RESULT($default_highlight) test "$default_highlight" = no && AC_DEFINE(OPT_HIGHLIGHT_COLOR,0,[Define to 1 if you want support for color highlighting]) AC_MSG_CHECKING(if you want support for doublesize characters) CF_ARG_DISABLE(doublechars, [ --disable-doublechars disable support for double-size chars], [enable_doublechars=no], [enable_doublechars=yes]) AC_MSG_RESULT($enable_doublechars) test "$enable_doublechars" = no && AC_DEFINE(OPT_DEC_CHRSET,0,[Define to 0 to disable support for double-size chars]) AC_MSG_CHECKING(if you want fallback-support for box characters) CF_ARG_DISABLE(boxchars, [ --disable-boxchars disable fallback-support for box chars], [enable_boxchars=no], [enable_boxchars=yes]) AC_MSG_RESULT($enable_boxchars) test "$enable_boxchars" = no && AC_DEFINE(OPT_BOX_CHARS,0,[Define to 0 to disable fallback-support for box chars]) AC_MSG_CHECKING(if you want to allow spawning commands to process selections) CF_ARG_DISABLE(exec-selection, [ --disable-exec-selection disable "exec-formatted" and "exec-selection" actions], [enable_exec_selection=no], [enable_exec_selection=yes]) AC_MSG_RESULT($enable_exec_selection) if test "$enable_exec_selection" = no ; then AC_DEFINE(OPT_EXEC_SELECTION,0,[Define to 0 to disable "exec-selection" action]) fi AC_MSG_CHECKING(if you want to allow spawning new xterms) CF_ARG_ENABLE(exec-xterm, [ --enable-exec-xterm enable "spawn-new-terminal" action], [enable_exec_xterm=yes], [enable_exec_xterm=no]) AC_MSG_RESULT($enable_exec_xterm) if test "$enable_exec_xterm" = yes ; then CF_PROCFS_CWD if test "$cf_cv_procfs_cwd" = no ; then AC_MSG_WARN(no suitable proc filesystem found) else AC_DEFINE_UNQUOTED(PROCFS_ROOT,"$cf_cv_procfs_cwd",[This is defined via the --enable-exec-xterm option]) AC_DEFINE(OPT_EXEC_XTERM,1,[Define to 1 to enable "spawn-new-terminal" action]) fi fi CF_X_EXT CF_X_EXT_DOUBLE_BUFFER double_buffer=False if test "$cf_x_ext_double_buffer" = yes ; then AC_MSG_CHECKING(if you want to enable double-buffering in default resources) CF_ARG_ENABLE(double-buffer, [ --enable-double-buffer enable double-buffering in default resources], [enable_double_bfr=yes], [enable_double_bfr=no]) AC_MSG_RESULT($enable_double_bfr) if test "$enable_double_bfr" = yes ; then AC_DEFINE(OPT_DOUBLE_BUFFER,1,[Define to 1 to enable double-buffering in default resources]) double_buffer=True fi fi AC_SUBST(double_buffer) AC_MSG_CHECKING(if you want to use FreeType library) CF_ARG_DISABLE(freetype, [ --disable-freetype disable freetype library-support], [enable_freetype=no], [enable_freetype=yes]) AC_MSG_RESULT($enable_freetype) if test "$enable_freetype" = yes ; then CF_X_FONTCONFIG else CPPFLAGS=`echo "$CPPFLAGS" | sed -e s/-DXRENDERFONT//` fi AC_MSG_CHECKING(if you want support for HP-style function keys) CF_ARG_ENABLE(hp-fkeys, [ --enable-hp-fkeys enable support for HP-style function keys], [enable_hp_fkeys=yes], [enable_hp_fkeys=no]) AC_MSG_RESULT($enable_hp_fkeys) if test "$enable_hp_fkeys" = yes ; then AC_DEFINE(OPT_HP_FUNC_KEYS,1,[Define to 1 to enable support for HP-style function keys]) fi AC_MSG_CHECKING(if you want support for SCO-style function keys) CF_ARG_ENABLE(sco-fkeys, [ --enable-sco-fkeys enable support for SCO-style function keys], [enable_sco_fkeys=yes], [enable_sco_fkeys=no]) AC_MSG_RESULT($enable_sco_fkeys) if test "$enable_sco_fkeys" = yes ; then AC_DEFINE(OPT_SCO_FUNC_KEYS,1,[Define to 1 to enable support for SCO-style function keys]) fi AC_MSG_CHECKING(if you want support for Sun-style function keys) CF_ARG_DISABLE(sun-fkeys, [ --disable-sun-fkeys disable support for Sun-style function keys], [enable_sun_fkeys=no], [enable_sun_fkeys=yes]) AC_MSG_RESULT($enable_sun_fkeys) if test "$enable_sun_fkeys" = no ; then AC_DEFINE(OPT_SUN_FUNC_KEYS,0,[Define to 0 to disable support for Sun-style function keys]) fi AC_MSG_CHECKING(if you want saved-lines stored as a FIFO) CF_ARG_DISABLE(fifo-lines, [ --disable-fifo-lines disable FIFO-storage for saved-lines], [enable_fifo_lines=no], [enable_fifo_lines=yes]) AC_MSG_RESULT($enable_fifo_lines) if test "$enable_fifo_lines" != yes ; then AC_MSG_WARN(this option has been deprecated) fi AC_MSG_CHECKING(if you want support for internationalization) CF_ARG_DISABLE(i18n, [ --disable-i18n disable internationalization], [enable_i18n=no], [enable_i18n=yes]) AC_MSG_RESULT($enable_i18n) if test "$enable_i18n" = no ; then AC_DEFINE(OPT_I18N_SUPPORT,0,[Define to 0 to disable internationalization]) fi AC_MSG_CHECKING(if you want support for initial-erase setup) CF_ARG_DISABLE(initial-erase, [ --disable-initial-erase disable setup for stty erase], [enable_ie=no], [enable_ie=yes]) AC_MSG_RESULT($enable_ie) if test "$enable_ie" = no ; then AC_DEFINE(OPT_INITIAL_ERASE,0,[Define to 0 to disable setup for stty erase]) fi AC_MSG_CHECKING(if you want support for input-method) CF_ARG_DISABLE(input-method, [ --disable-input-method disable input-method], [enable_ximp=no], [enable_ximp=$enable_i18n]) AC_MSG_RESULT($enable_ximp) CF_INPUT_METHOD test "$cf_cv_input_method" = no && enable_ximp=no if test "$enable_ximp" != no ; then if test "$enable_i18n" = no ; then AC_MSG_WARN(input-method relies upon internationalization) enable_ximp=no fi fi if test "$enable_ximp" = no ; then AC_DEFINE(OPT_INPUT_METHOD,0,[Define to 0 to disable input-method]) fi AC_MSG_CHECKING(if you want support for load-vt-fonts) CF_ARG_ENABLE(load-vt-fonts, [ --enable-load-vt-fonts enable load-vt-fonts() action], [enable_load_vt_fonts=yes], [enable_load_vt_fonts=no]) AC_MSG_RESULT($enable_load_vt_fonts) if test "$enable_load_vt_fonts" = yes ; then AC_DEFINE(OPT_LOAD_VTFONTS,1,[Define to 1 to enable load-vt-fonts() action]) fi AC_MSG_CHECKING(if you want support for logging) CF_ARG_ENABLE(logging, [ --enable-logging enable logging], [enable_logging=yes], [enable_logging=no]) AC_MSG_RESULT($enable_logging) if test "$enable_logging" = yes ; then AC_DEFINE(ALLOWLOGGING,1,[if you want support for logging]) AC_MSG_CHECKING(if you want to allow logging via a pipe) CF_ARG_ENABLE(logfile-exec, [ --enable-logfile-exec enable exec'd logfile filter], [enable_log_exec=yes], [enable_log_exec=no]) AC_MSG_RESULT($enable_log_exec) if test "$enable_log_exec" = yes ; then AC_DEFINE(ALLOWLOGFILEEXEC,1,[if you want to allow logging via a pipe]) fi fi AC_MSG_CHECKING(if you want support for iconify/maximize translations) CF_ARG_DISABLE(maximize, [ --disable-maximize disable actions for iconify/deiconify/maximize/restore], [enable_maximize=no], [enable_maximize=yes]) AC_MSG_RESULT($enable_maximize) test "$enable_maximize" = no && AC_DEFINE(OPT_MAXIMIZE,0,[Define to 0 to disable actions for iconify/deiconify/maximize/restore]) AC_MSG_CHECKING(if you want NumLock to override keyboard tables) CF_ARG_DISABLE(num-lock, [ --disable-num-lock disable NumLock keypad support], [enable_numlock=no], [enable_numlock=yes]) AC_MSG_RESULT($enable_numlock) test "$enable_numlock" = no && AC_DEFINE(OPT_NUM_LOCK,0,[Define to 0 to disable NumLock keypad support]) AC_MSG_CHECKING(if you want support for get/set of base64 selection data) CF_ARG_DISABLE(paste64, [ --disable-paste64 disable get/set base64 selection data], [enable_paste64=no], [enable_paste64=yes]) AC_MSG_RESULT($enable_paste64) if test "$enable_paste64" = yes ; then AC_DEFINE(OPT_PASTE64,1,[Define to 1 to disable get/set base64 selection data]) else AC_DEFINE(OPT_PASTE64,0,[Define to 0 to disable get/set base64 selection data]) fi AC_MSG_CHECKING(if you want support for pty-handshaking) CF_ARG_DISABLE(pty-handshake, [ --disable-pty-handshake disable pty-handshake support], [enable_pty_handshake=no], [enable_pty_handshake=yes]) AC_MSG_RESULT($enable_pty_handshake) if test "$enable_pty_handshake" = yes ; then AC_DEFINE(OPT_PTY_HANDSHAKE,1,[Define to 1 to disable pty-handshake support]) else AC_DEFINE(OPT_PTY_HANDSHAKE,0,[Define to 0 to disable pty-handshake support]) fi AC_MSG_CHECKING(if you want support for mouse in readline applications) CF_ARG_DISABLE(readline-mouse, [ --disable-readline-mouse disable support for mouse in readline applications], [enable_readline_mouse=no], [enable_readline_mouse=yes]) AC_MSG_RESULT($enable_readline_mouse) if test "$enable_readline_mouse" = yes ; then AC_DEFINE(OPT_READLINE,1,[Define to 1 to enable support for mouse in readline applications]) fi AC_MSG_CHECKING(if you want support for regular-expression selections) CF_ARG_DISABLE(regex, [ --disable-regex disable regular-expression selections], [enable_regex=no], [enable_regex=yes]) AC_MSG_RESULT($enable_regex) if test "$enable_regex" = yes ; then CF_WITH_PCRE2 if test "$with_pcre2" = no ; then CF_WITH_PCRE if test "$with_pcre" = no ; then CF_REGEX if test "X$cf_cv_regex_hdrs" != "Xregex.h" ; then AC_MSG_ERROR([Only POSIX, PCRE, or PCRE2 regular expressions are supported]) fi fi fi AC_DEFINE(OPT_SELECT_REGEX,1,[Define to 1 to enable regular-expression selections]) fi AC_MSG_CHECKING(if you want support for right-scrollbar) CF_ARG_DISABLE(rightbar, [ --disable-rightbar disable right-scrollbar support], [enable_rightbar=no], [enable_rightbar=yes]) AC_MSG_RESULT($enable_rightbar) if test "$enable_rightbar" = yes ; then AC_DEFINE(SCROLLBAR_RIGHT,1,[Define to 1 to enable right-scrollbar support]) fi AC_MSG_CHECKING(if you want check for redundant name-change) CF_ARG_DISABLE(samename, [ --disable-samename disable check for redundant name-change], [enable_samename=no], [enable_samename=yes]) AC_MSG_RESULT($enable_samename) test "$enable_samename" = no && AC_DEFINE(OPT_SAME_NAME,0,[Define to 0 to disable check for redundant name-change]) AC_MSG_CHECKING(if you want support for selection-actions) CF_ARG_DISABLE(selection-ops, [ --disable-selection-ops disable selection-action operations], [enable_selection_ops=no], [enable_selection_ops=yes]) AC_MSG_RESULT($enable_selection_ops) test "$enable_selection_ops" = no && AC_DEFINE(OPT_SELECTION_OPS,0,[Define to 0 disable selection-action operations]) AC_MSG_CHECKING(if you want support for session management) CF_ARG_DISABLE(session-mgt, [ --disable-session-mgt disable support for session management], [enable_session_mgt=no], [enable_session_mgt=yes]) AC_MSG_RESULT($enable_session_mgt) test "$enable_session_mgt" = no && AC_DEFINE(OPT_SESSION_MGT,0,[Define to 0 to disable support for session management]) AC_MSG_CHECKING(if you want support for status-line) CF_ARG_ENABLE(status-line, [ --enable-status-line enable support for status-line], [enable_status_line=yes], [enable_status_line=no]) AC_MSG_RESULT($enable_status_line) test "$enable_status_line" = yes && AC_DEFINE(OPT_STATUS_LINE,1,[Define to 1 to enable support for status-line]) AC_MSG_CHECKING(if you want to use termcap function-keys) CF_ARG_DISABLE(tcap-fkeys, [ --disable-tcap-fkeys disable termcap function-keys support], [enable_tcap_fkeys=no], [enable_tcap_fkeys=yes]) AC_MSG_RESULT($enable_tcap_fkeys) test "$enable_tcap_fkeys" = no && AC_DEFINE(OPT_TCAP_FKEYS,0,[Define to 0 to disable termcap function-keys support]) AC_MSG_CHECKING(if you want to use termcap-query/report) CF_ARG_DISABLE(tcap-query, [ --disable-tcap-query disable compiled-in termcap-query support], [enable_tcap_query=no], [enable_tcap_query=yes]) AC_MSG_RESULT($enable_tcap_query) test "$enable_tcap_query" = no && AC_DEFINE(OPT_TCAP_QUERY,0,[Define to 0 to disable compiled-in termcap-query support]) AC_MSG_CHECKING(if you want support for tek4014) CF_ARG_DISABLE(tek4014, [ --disable-tek4014 disable tek4014 emulation], [enable_tek4014=no], [enable_tek4014=yes]) AC_MSG_RESULT($enable_tek4014) if test "$enable_tek4014" = no ; then AC_DEFINE(OPT_TEK4014,0,[Define to 0 to disable tek4014 emulation]) else EXTRAHDRS="$EXTRAHDRS Tekparse.h" EXTRASRCS="$EXTRASRCS TekPrsTbl.c Tekproc.c" EXTRAOBJS="$EXTRAOBJS TekPrsTbl.o Tekproc.o" fi AC_MSG_CHECKING(if you want pulldown menus with a toolbar) CF_ARG_ENABLE(toolbar, [ --enable-toolbar compile-in toolbar for pulldown menus], [enable_toolbar=yes], [enable_toolbar=no]) AC_MSG_RESULT($enable_toolbar) if test "$enable_toolbar" = yes ; then AC_DEFINE(OPT_TOOLBAR,1,[Define to 1 to compile-in toolbar for pulldown menus]) fi AC_MSG_CHECKING(if you want VT52 emulation) CF_ARG_DISABLE(vt52, [ --disable-vt52 disable VT52 emulation], [enable_vt52=no], [enable_vt52=yes]) AC_MSG_RESULT($enable_vt52) test "$enable_vt52" = no && AC_DEFINE(OPT_VT52_MODE,0,[Define to 0 to disable VT52 emulation]) AC_MSG_CHECKING(if you want wide-attribute support) CF_ARG_DISABLE(wide-attrs, [ --disable-wide-attrs disable wide-attribute support], [enable_wattr=no], [enable_wattr=yes]) AC_MSG_RESULT($enable_wattr) if test x$enable_wattr = xno && test x$enable_direct_color = xyes ; then AC_MSG_WARN(overriding wide-attributes to support direct color) enable_wattr=yes fi AC_MSG_CHECKING(if you want wide-character support) CF_ARG_DISABLE(wide-chars, [ --disable-wide-chars disable wide-character support], [enable_wchar=no], [enable_wchar=yes]) AC_MSG_RESULT($enable_wchar) test "x$enable_wattr" = xno && AC_DEFINE(OPT_WIDE_ATTRS,0,[Define to 0 to disable rarely-used SGR features]) AC_MSG_CHECKING(if you want only 16-bit character support) CF_ARG_ENABLE(16bit-chars, [ --enable-16bit-chars enable 16-bit character support], [enable_16bit_chars=yes], [enable_16bit_chars=no]) AC_MSG_RESULT($enable_16bit_chars) if test "$enable_16bit_chars" = yes ; then AC_DEFINE(OPT_WIDER_ICHAR,0,[Define to 0 to enable 16-bit character support]) enable_wchar=yes fi if test "$enable_wchar" = yes ; then AC_MSG_CHECKING(if you want to use mini-luit/Latin9 built-in support) CF_ARG_ENABLE(mini-luit, [ --enable-mini-luit enable mini-luit (built-in Latin9 support)], [enable_mini_luit=yes], [enable_mini_luit=no]) AC_MSG_RESULT($enable_mini_luit) if test "$enable_mini_luit" = yes ; then AC_DEFINE(OPT_MINI_LUIT,1,[Define to 1 to enable mini-luit (built-in Latin9 support)]) fi AC_MSG_CHECKING(if you want to use luit) CF_ARG_DISABLE(luit, [ --disable-luit enable luit filter (Unicode translation)], [enable_luit=no], [enable_luit=yes]) AC_MSG_RESULT($enable_luit) if test "$enable_luit" = yes ; then AC_DEFINE(OPT_LUIT_PROG,1,[Define to 1 to enable luit filter (Unicode translation)]) CF_PATH_PROG(LUIT,xterm-filter,bluit luit) fi AC_DEFINE(OPT_WIDE_CHARS,1,[Define to 1 to enable wide-character support]) EXTRAHDRS="$EXTRAHDRS charclass.h precompose.h wcwidth.h" EXTRASRCS="$EXTRASRCS charclass.c precompose.c wcwidth.c" EXTRAOBJS="$EXTRAOBJS charclass.o precompose.o wcwidth.o" fi AC_MSG_CHECKING(if you want dynamic-abbreviation support) CF_ARG_ENABLE(dabbrev, [ --enable-dabbrev enable dynamic-abbreviation support], [enable_dabbrev=yes], [enable_dabbrev=no]) AC_MSG_RESULT($enable_dabbrev) if test "$enable_dabbrev" = yes ; then AC_DEFINE(OPT_DABBREV,1,[Define to 1 to enable dynamic-abbreviation support]) fi AC_MSG_CHECKING(if you want DECterm Locator support) CF_ARG_ENABLE(dec-locator, [ --enable-dec-locator enable DECterm Locator support], [enable_dec_locator=yes], [enable_dec_locator=no]) AC_MSG_RESULT($enable_dec_locator) if test "$enable_dec_locator" = yes ; then AC_DEFINE(OPT_DEC_LOCATOR,1,[Define to 1 to enable DECterm Locator support]) fi AC_MSG_CHECKING(if you want XHTML and SVG screen dump support) CF_ARG_DISABLE(screen-dumps, [ --disable-screen-dumps disable XHTML and SVG screen dumps], [enable_screen_dumps=no], [enable_screen_dumps=yes]) AC_MSG_RESULT($enable_screen_dumps) if test "$enable_screen_dumps" = yes ; then EXTRASRCS="$EXTRASRCS html.c svg.c" EXTRAOBJS="$EXTRAOBJS html.o svg.o" else AC_DEFINE(OPT_SCREEN_DUMPS,0,[Define to 0 to disable XHTML and SVG screen dump support]) fi AC_MSG_CHECKING(if you want ReGIS graphics support) CF_ARG_ENABLE(regis-graphics, [ --enable-regis-graphics enable ReGIS graphics support], [enable_regis_graphics=yes], [enable_regis_graphics=no]) AC_MSG_RESULT($enable_regis_graphics) if test "$enable_regis_graphics" = yes ; then AC_DEFINE(OPT_REGIS_GRAPHICS,1,[Define to 1 to enable ReGIS graphics support]) EXTRAHDRS="$EXTRAHDRS graphics_regis.h" EXTRASRCS="$EXTRASRCS graphics_regis.c" EXTRAOBJS="$EXTRAOBJS graphics_regis.o" CF_MATH_LIB fi AC_MSG_CHECKING(if you want sixel graphics support) CF_ARG_DISABLE(sixel-graphics, [ --disable-sixel-graphics disable sixel graphics support], [enable_sixel_graphics=no], [enable_sixel_graphics=yes]) AC_MSG_RESULT($enable_sixel_graphics) if test "$enable_sixel_graphics" = yes ; then AC_DEFINE(OPT_SIXEL_GRAPHICS,1,[Define to 1 to enable sixel graphics support]) EXTRAHDRS="$EXTRAHDRS graphics_sixel.h" EXTRASRCS="$EXTRASRCS graphics_sixel.c" EXTRAOBJS="$EXTRAOBJS graphics_sixel.o" fi if test "$enable_regis_graphics" = yes || test "$enable_sixel_graphics" = yes ; then AC_DEFINE(OPT_GRAPHICS,1,[Defined to 1 to if any graphics mode is enabled]) EXTRAHDRS="$EXTRAHDRS graphics.h" EXTRASRCS="$EXTRASRCS graphics.c" EXTRAOBJS="$EXTRAOBJS graphics.o" STRINGS_MAX=600000 else STRINGS_MAX=20000 fi AC_SUBST(STRINGS_MAX) AC_MSG_CHECKING(if you want sixel screen dump support) CF_ARG_DISABLE(print-graphics, [ --disable-print-graphics disable screen dump to sixel support], [enable_print_graphics=no], [enable_print_graphics=$enable_regis_graphics]) AC_MSG_RESULT($enable_print_graphics) if test "$enable_print_graphics" = yes ; then AC_DEFINE(OPT_PRINT_GRAPHICS,1,[Define to 1 to enable screen dump to sixel support]) fi AC_MSG_CHECKING(if you want VT420 rectangle support) CF_ARG_DISABLE(rectangles, [ --disable-rectangles disable VT420 rectangle support], [enable_rectangles=no], [enable_rectangles=yes]) AC_MSG_RESULT($enable_rectangles) if test "$enable_rectangles" = no ; then AC_DEFINE(OPT_DEC_RECTOPS,0,[Define to 0 to disable VT420 rectangle support]) fi AC_MSG_CHECKING(if you want -ziconbeep option) CF_ARG_DISABLE(ziconbeep, [ --disable-ziconbeep disable -ziconbeep option], [enable_ziconbeep=no], [enable_ziconbeep=yes]) AC_MSG_RESULT($enable_ziconbeep) test "$enable_ziconbeep" = no && AC_DEFINE(OPT_ZICONBEEP,0,[Define to 0 to disable -ziconbeep option]) ############################################################################### CF_HELP_MESSAGE(Testing/development Options:) AC_MSG_CHECKING(if you want debugging traces) CF_ARG_ENABLE(trace, [ --enable-trace test: set to enable debugging traces], [enable_trace=yes], [enable_trace=no]) AC_MSG_RESULT($enable_trace) if test "$enable_trace" = yes ; then AC_DEFINE(OPT_TRACE,1,[Define to 1 to enable debugging traces]) EXTRASRCS="$EXTRASRCS trace.c" EXTRAOBJS="$EXTRAOBJS trace.o" fi CF_DISABLE_LEAKS CF_DISABLE_ECHO AC_MSG_CHECKING(if you want magic cookie emulation) CF_ARG_ENABLE(xmc-glitch, [ --enable-xmc-glitch test: enable xmc magic-cookie emulation], [enable_xmc=yes], [enable_xmc=no]) AC_MSG_RESULT($enable_xmc) if test "$enable_xmc" = yes ; then AC_DEFINE(OPT_XMC_GLITCH,1,[Define to 1 to enable xmc magic-cookie emulation]) EXTRASRCS="$EXTRASRCS testxmc.c" EXTRAOBJS="$EXTRAOBJS testxmc.o" fi dnl FIXME - extra test needed to make tcap-fkeys work on HPUX AC_CHECK_FUNCS(tigetstr) dnl only check for ncurses' use_extended_names if really not using termcap if test -n "$cf_cv_lib_part_tgetent"; then AC_CHECK_FUNCS(use_extended_names) fi CF_ENABLE_WARNINGS(Wdeclaration-after-statement Wextra Wno-unknown-pragmas Wswitch-enum Wno-cast-qual,yes) AC_SUBST(EXTRA_CFLAGS) AC_SUBST(CHARPROC_DEPS) AC_SUBST(EXTRAHDRS) AC_SUBST(EXTRASRCS) AC_SUBST(EXTRAOBJS) test "$disable_setuid" = yes && AC_DEFINE(DISABLE_SETUID,1,[Define to 1 if you want to disable setuid]) test "$disable_setgid" = yes && AC_DEFINE(DISABLE_SETGID,1,[Define to 1 if you want to disable setgid]) if test $disable_setuid = yes ; then MAY_SETUID="#" NOT_SETUID= elif test $disable_setgid = yes ; then MAY_SETUID="#" NOT_SETUID= else MAY_SETUID= NOT_SETUID="#" fi AC_SUBST(MAY_SETUID) AC_SUBST(NOT_SETUID) ### remove from CPPFLAGS the optional features we define in xtermcfg.h ### or other conflicting symbols that may be defined via imake: for cf_def in \ __STDC__ \ ALLOWLOGGING \ ALLOWLOGFILEEXEC \ OPT_LUIT_PROG \ OPT_WIDE_CHARS \ SCROLLBAR_RIGHT \ USE_TTY_GROUP \ USE_UTEMPTER \ XRENDERFONT do CPPFLAGS=`echo "$CPPFLAGS" | sed -e s/-D$cf_def//` done CF_MAKE_TAGS CF_DISABLE_RPATH_HACK # Force plink.sh to not trim pcre's libraries, which have the same symbol # names as the system regexp. if test "$with_pcre" != no then LIBS=`echo "$LIBS" | sed -e 's/-lpcre/-kpcre/g'` fi ### output xtermcfg.h, etc AC_CONFIG_FILES([Makefile df-install minstall:minstall.in run-tic.sh:run-tic.in]) AC_OUTPUT xterm-399/keysym2ucs.c0000644000000000000000000040140314772264024013531 0ustar rootroot/* $XTermId: keysym2ucs.c,v 1.25 2025/03/30 15:49:40 tom Exp $ * ---------------------------------------------------------------------------- * this file is part of xterm * * Copyright 2007-2018,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * ---------------------------------------------------------------------------- * Note: * ---- * This file has been updated and revised to provide for mapping all keysyms * to UCS. The BMP private use area is used for keysyms which do not map to * characters. * * Original header: * --------------- * This module converts keysym values into the corresponding ISO 10646 * (UCS, Unicode) values. * * The array keysymtab[] contains pairs of X11 keysym values for graphical * characters and the corresponding Unicode value. The function * keysym2ucs() maps a keysym onto a Unicode value using a binary search, * therefore keysymtab[] must remain SORTED by keysym value. * * The keysym -> UTF-8 conversion will hopefully one day be provided * by Xlib via XmbLookupString() and should ideally not have to be * done in X applications. But we are not there yet. * * We allow to represent any UCS character in the range U-00000000 to * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff. * This admittedly does not cover the entire 31-bit space of UCS, but * it does cover all of the characters up to U-10FFFF, which can be * represented by UTF-16, and more, and it is very unlikely that higher * UCS codes will ever be assigned by ISO. So to get Unicode character * U+ABCD you can directly use keysym 0x0100abcd. * * NOTE: The comments in the table below contain the actual character * encoded in UTF-8, so for viewing and editing best use an editor in * UTF-8 mode. * * Author: Markus G. Kuhn , University of Cambridge, April 2001 * * Special thanks to Richard Verhoeven for preparing * an initial draft of the mapping table. * * This software is in the public domain. Share and enjoy! * * AUTOMATICALLY GENERATED FILE, DO NOT EDIT !!! (unicode/convmap.pl) */ #include static struct codepair { unsigned keysym; unsigned ucs; } keysymtab[] = { /* *INDENT-OFF* */ { 0x01a1, 0x0104 }, /* Aogonek Ä„ LATIN CAPITAL LETTER A WITH OGONEK */ { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ { 0x01a3, 0x0141 }, /* Lstroke Å LATIN CAPITAL LETTER L WITH STROKE */ { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ { 0x01a6, 0x015a }, /* Sacute Åš LATIN CAPITAL LETTER S WITH ACUTE */ { 0x01a9, 0x0160 }, /* Scaron Å  LATIN CAPITAL LETTER S WITH CARON */ { 0x01aa, 0x015e }, /* Scedilla Åž LATIN CAPITAL LETTER S WITH CEDILLA */ { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ { 0x01af, 0x017b }, /* Zabovedot Å» LATIN CAPITAL LETTER Z WITH DOT ABOVE */ { 0x01b1, 0x0105 }, /* aogonek Ä… LATIN SMALL LETTER A WITH OGONEK */ { 0x01b2, 0x02db }, /* ogonek Ë› OGONEK */ { 0x01b3, 0x0142 }, /* lstroke Å‚ LATIN SMALL LETTER L WITH STROKE */ { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ { 0x01b6, 0x015b }, /* sacute Å› LATIN SMALL LETTER S WITH ACUTE */ { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ { 0x01b9, 0x0161 }, /* scaron Å¡ LATIN SMALL LETTER S WITH CARON */ { 0x01ba, 0x015f }, /* scedilla ÅŸ LATIN SMALL LETTER S WITH CEDILLA */ { 0x01bb, 0x0165 }, /* tcaron Å¥ LATIN SMALL LETTER T WITH CARON */ { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ { 0x01bd, 0x02dd }, /* doubleacute Ë DOUBLE ACUTE ACCENT */ { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ { 0x01c0, 0x0154 }, /* Racute Å” LATIN CAPITAL LETTER R WITH ACUTE */ { 0x01c3, 0x0102 }, /* Abreve Ä‚ LATIN CAPITAL LETTER A WITH BREVE */ { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ { 0x01c8, 0x010c }, /* Ccaron ÄŒ LATIN CAPITAL LETTER C WITH CARON */ { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ { 0x01cc, 0x011a }, /* Ecaron Äš LATIN CAPITAL LETTER E WITH CARON */ { 0x01cf, 0x010e }, /* Dcaron ÄŽ LATIN CAPITAL LETTER D WITH CARON */ { 0x01d0, 0x0110 }, /* Dstroke Ä LATIN CAPITAL LETTER D WITH STROKE */ { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ { 0x01d5, 0x0150 }, /* Odoubleacute Å LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ { 0x01d9, 0x016e }, /* Uring Å® LATIN CAPITAL LETTER U WITH RING ABOVE */ { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ { 0x01de, 0x0162 }, /* Tcedilla Å¢ LATIN CAPITAL LETTER T WITH CEDILLA */ { 0x01e0, 0x0155 }, /* racute Å• LATIN SMALL LETTER R WITH ACUTE */ { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ { 0x01e8, 0x010d }, /* ccaron Ä LATIN SMALL LETTER C WITH CARON */ { 0x01ea, 0x0119 }, /* eogonek Ä™ LATIN SMALL LETTER E WITH OGONEK */ { 0x01ec, 0x011b }, /* ecaron Ä› LATIN SMALL LETTER E WITH CARON */ { 0x01ef, 0x010f }, /* dcaron Ä LATIN SMALL LETTER D WITH CARON */ { 0x01f0, 0x0111 }, /* dstroke Ä‘ LATIN SMALL LETTER D WITH STROKE */ { 0x01f1, 0x0144 }, /* nacute Å„ LATIN SMALL LETTER N WITH ACUTE */ { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ { 0x01f5, 0x0151 }, /* odoubleacute Å‘ LATIN SMALL LETTER O WITH DOUBLE ACUTE */ { 0x01f8, 0x0159 }, /* rcaron Å™ LATIN SMALL LETTER R WITH CARON */ { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ { 0x01fe, 0x0163 }, /* tcedilla Å£ LATIN SMALL LETTER T WITH CEDILLA */ { 0x01ff, 0x02d9 }, /* abovedot Ë™ DOT ABOVE */ { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ { 0x02ab, 0x011e }, /* Gbreve Äž LATIN CAPITAL LETTER G WITH BREVE */ { 0x02ac, 0x0134 }, /* Jcircumflex Ä´ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ { 0x02b6, 0x0125 }, /* hcircumflex Ä¥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ { 0x02bb, 0x011f }, /* gbreve ÄŸ LATIN SMALL LETTER G WITH BREVE */ { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ { 0x02c5, 0x010a }, /* Cabovedot ÄŠ LATIN CAPITAL LETTER C WITH DOT ABOVE */ { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ { 0x02d5, 0x0120 }, /* Gabovedot Ä  LATIN CAPITAL LETTER G WITH DOT ABOVE */ { 0x02d8, 0x011c }, /* Gcircumflex Äœ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ { 0x02de, 0x015c }, /* Scircumflex Åœ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ { 0x02e5, 0x010b }, /* cabovedot Ä‹ LATIN SMALL LETTER C WITH DOT ABOVE */ { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ { 0x02f5, 0x0121 }, /* gabovedot Ä¡ LATIN SMALL LETTER G WITH DOT ABOVE */ { 0x02f8, 0x011d }, /* gcircumflex Ä LATIN SMALL LETTER G WITH CIRCUMFLEX */ { 0x02fd, 0x016d }, /* ubreve Å­ LATIN SMALL LETTER U WITH BREVE */ { 0x02fe, 0x015d }, /* scircumflex Å LATIN SMALL LETTER S WITH CIRCUMFLEX */ { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ { 0x03a3, 0x0156 }, /* Rcedilla Å– LATIN CAPITAL LETTER R WITH CEDILLA */ { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ { 0x03a6, 0x013b }, /* Lcedilla Ä» LATIN CAPITAL LETTER L WITH CEDILLA */ { 0x03aa, 0x0112 }, /* Emacron Ä’ LATIN CAPITAL LETTER E WITH MACRON */ { 0x03ab, 0x0122 }, /* Gcedilla Ä¢ LATIN CAPITAL LETTER G WITH CEDILLA */ { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ { 0x03b3, 0x0157 }, /* rcedilla Å— LATIN SMALL LETTER R WITH CEDILLA */ { 0x03b5, 0x0129 }, /* itilde Ä© LATIN SMALL LETTER I WITH TILDE */ { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ { 0x03ba, 0x0113 }, /* emacron Ä“ LATIN SMALL LETTER E WITH MACRON */ { 0x03bb, 0x0123 }, /* gcedilla Ä£ LATIN SMALL LETTER G WITH CEDILLA */ { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ { 0x03bd, 0x014a }, /* ENG ÅŠ LATIN CAPITAL LETTER ENG */ { 0x03bf, 0x014b }, /* eng Å‹ LATIN SMALL LETTER ENG */ { 0x03c0, 0x0100 }, /* Amacron Ä€ LATIN CAPITAL LETTER A WITH MACRON */ { 0x03c7, 0x012e }, /* Iogonek Ä® LATIN CAPITAL LETTER I WITH OGONEK */ { 0x03cc, 0x0116 }, /* Eabovedot Ä– LATIN CAPITAL LETTER E WITH DOT ABOVE */ { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ { 0x03d1, 0x0145 }, /* Ncedilla Å… LATIN CAPITAL LETTER N WITH CEDILLA */ { 0x03d2, 0x014c }, /* Omacron ÅŒ LATIN CAPITAL LETTER O WITH MACRON */ { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ { 0x03e0, 0x0101 }, /* amacron Ä LATIN SMALL LETTER A WITH MACRON */ { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ { 0x03ec, 0x0117 }, /* eabovedot Ä— LATIN SMALL LETTER E WITH DOT ABOVE */ { 0x03ef, 0x012b }, /* imacron Ä« LATIN SMALL LETTER I WITH MACRON */ { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ { 0x03f2, 0x014d }, /* omacron Å LATIN SMALL LETTER O WITH MACRON */ { 0x03f3, 0x0137 }, /* kcedilla Ä· LATIN SMALL LETTER K WITH CEDILLA */ { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ { 0x03fd, 0x0169 }, /* utilde Å© LATIN SMALL LETTER U WITH TILDE */ { 0x03fe, 0x016b }, /* umacron Å« LATIN SMALL LETTER U WITH MACRON */ { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ { 0x04a3, 0x300d }, /* kana_closingbracket 〠RIGHT CORNER BRACKET */ { 0x04a4, 0x3001 }, /* kana_comma 〠IDEOGRAPHIC COMMA */ { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ { 0x04a7, 0x30a1 }, /* kana_a ã‚¡ KATAKANA LETTER SMALL A */ { 0x04a8, 0x30a3 }, /* kana_i ã‚£ KATAKANA LETTER SMALL I */ { 0x04a9, 0x30a5 }, /* kana_u ã‚¥ KATAKANA LETTER SMALL U */ { 0x04aa, 0x30a7 }, /* kana_e ã‚§ KATAKANA LETTER SMALL E */ { 0x04ab, 0x30a9 }, /* kana_o ã‚© KATAKANA LETTER SMALL O */ { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ { 0x04b1, 0x30a2 }, /* kana_A ã‚¢ KATAKANA LETTER A */ { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ { 0x04b6, 0x30ab }, /* kana_KA ã‚« KATAKANA LETTER KA */ { 0x04b7, 0x30ad }, /* kana_KI ã‚­ KATAKANA LETTER KI */ { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ { 0x04bc, 0x30b7 }, /* kana_SHI ã‚· KATAKANA LETTER SI */ { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ { 0x04be, 0x30bb }, /* kana_SE ã‚» KATAKANA LETTER SE */ { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ { 0x04c0, 0x30bf }, /* kana_TA ã‚¿ KATAKANA LETTER TA */ { 0x04c1, 0x30c1 }, /* kana_CHI ムKATAKANA LETTER TI */ { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ { 0x04c8, 0x30cd }, /* kana_NE ムKATAKANA LETTER NE */ { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ { 0x04ca, 0x30cf }, /* kana_HA ムKATAKANA LETTER HA */ { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ { 0x04de, 0x309b }, /* voicedsound ã‚› KATAKANA-HIRAGANA VOICED SOUND MARK */ { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ { 0x05ac, 0x060c }, /* Arabic_comma ØŒ ARABIC COMMA */ { 0x05bb, 0x061b }, /* Arabic_semicolon Ø› ARABIC SEMICOLON */ { 0x05bf, 0x061f }, /* Arabic_question_mark ØŸ ARABIC QUESTION MARK */ { 0x05c1, 0x0621 }, /* Arabic_hamza Ø¡ ARABIC LETTER HAMZA */ { 0x05c2, 0x0622 }, /* Arabic_maddaonalef Ø¢ ARABIC LETTER ALEF WITH MADDA ABOVE */ { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef Ø£ ARABIC LETTER ALEF WITH HAMZA ABOVE */ { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef Ø¥ ARABIC LETTER ALEF WITH HAMZA BELOW */ { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta Ø© ARABIC LETTER TEH MARBUTA */ { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ { 0x05cb, 0x062b }, /* Arabic_theh Ø« ARABIC LETTER THEH */ { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ { 0x05cd, 0x062d }, /* Arabic_hah Ø­ ARABIC LETTER HAH */ { 0x05ce, 0x062e }, /* Arabic_khah Ø® ARABIC LETTER KHAH */ { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ { 0x05d4, 0x0634 }, /* Arabic_sheen Ø´ ARABIC LETTER SHEEN */ { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ { 0x05d7, 0x0637 }, /* Arabic_tah Ø· ARABIC LETTER TAH */ { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ { 0x05e0, 0x0640 }, /* Arabic_tatweel Ù€ ARABIC TATWEEL */ { 0x05e1, 0x0641 }, /* Arabic_feh Ù ARABIC LETTER FEH */ { 0x05e2, 0x0642 }, /* Arabic_qaf Ù‚ ARABIC LETTER QAF */ { 0x05e3, 0x0643 }, /* Arabic_kaf Ùƒ ARABIC LETTER KAF */ { 0x05e4, 0x0644 }, /* Arabic_lam Ù„ ARABIC LETTER LAM */ { 0x05e5, 0x0645 }, /* Arabic_meem Ù… ARABIC LETTER MEEM */ { 0x05e6, 0x0646 }, /* Arabic_noon Ù† ARABIC LETTER NOON */ { 0x05e7, 0x0647 }, /* Arabic_ha Ù‡ ARABIC LETTER HEH */ { 0x05e8, 0x0648 }, /* Arabic_waw Ùˆ ARABIC LETTER WAW */ { 0x05e9, 0x0649 }, /* Arabic_alefmaksura Ù‰ ARABIC LETTER ALEF MAKSURA */ { 0x05ea, 0x064a }, /* Arabic_yeh ÙŠ ARABIC LETTER YEH */ { 0x05eb, 0x064b }, /* Arabic_fathatan Ù‹ ARABIC FATHATAN */ { 0x05ec, 0x064c }, /* Arabic_dammatan ÙŒ ARABIC DAMMATAN */ { 0x05ed, 0x064d }, /* Arabic_kasratan Ù ARABIC KASRATAN */ { 0x05ee, 0x064e }, /* Arabic_fatha ÙŽ ARABIC FATHA */ { 0x05ef, 0x064f }, /* Arabic_damma Ù ARABIC DAMMA */ { 0x05f0, 0x0650 }, /* Arabic_kasra Ù ARABIC KASRA */ { 0x05f1, 0x0651 }, /* Arabic_shadda Ù‘ ARABIC SHADDA */ { 0x05f2, 0x0652 }, /* Arabic_sukun Ù’ ARABIC SUKUN */ { 0x06a1, 0x0452 }, /* Serbian_dje Ñ’ CYRILLIC SMALL LETTER DJE */ { 0x06a2, 0x0453 }, /* Macedonia_gje Ñ“ CYRILLIC SMALL LETTER GJE */ { 0x06a3, 0x0451 }, /* Cyrillic_io Ñ‘ CYRILLIC SMALL LETTER IO */ { 0x06a4, 0x0454 }, /* Ukrainian_ie Ñ” CYRILLIC SMALL LETTER UKRAINIAN IE */ { 0x06a5, 0x0455 }, /* Macedonia_dse Ñ• CYRILLIC SMALL LETTER DZE */ { 0x06a6, 0x0456 }, /* Ukrainian_i Ñ– CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ { 0x06a7, 0x0457 }, /* Ukrainian_yi Ñ— CYRILLIC SMALL LETTER YI */ { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ { 0x06a9, 0x0459 }, /* Cyrillic_lje Ñ™ CYRILLIC SMALL LETTER LJE */ { 0x06aa, 0x045a }, /* Cyrillic_nje Ñš CYRILLIC SMALL LETTER NJE */ { 0x06ab, 0x045b }, /* Serbian_tshe Ñ› CYRILLIC SMALL LETTER TSHE */ { 0x06ac, 0x045c }, /* Macedonia_kje Ñœ CYRILLIC SMALL LETTER KJE */ { 0x06ad, 0x0491 }, /* Ukrainian_ghe_with_upturn Ò‘ CYRILLIC SMALL LETTER GHE WITH UPTURN */ { 0x06ae, 0x045e }, /* Byelorussian_shortu Ñž CYRILLIC SMALL LETTER SHORT U */ { 0x06af, 0x045f }, /* Cyrillic_dzhe ÑŸ CYRILLIC SMALL LETTER DZHE */ { 0x06b0, 0x2116 }, /* numerosign â„– NUMERO SIGN */ { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ { 0x06b3, 0x0401 }, /* Cyrillic_IO Ð CYRILLIC CAPITAL LETTER IO */ { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ { 0x06b5, 0x0405 }, /* Macedonia_DSE Ð… CYRILLIC CAPITAL LETTER DZE */ { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ { 0x06bc, 0x040c }, /* Macedonia_KJE ÐŒ CYRILLIC CAPITAL LETTER KJE */ { 0x06bd, 0x0490 }, /* Ukrainian_GHE_WITH_UPTURN Ò CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ { 0x06be, 0x040e }, /* Byelorussian_SHORTU ÐŽ CYRILLIC CAPITAL LETTER SHORT U */ { 0x06bf, 0x040f }, /* Cyrillic_DZHE Ð CYRILLIC CAPITAL LETTER DZHE */ { 0x06c0, 0x044e }, /* Cyrillic_yu ÑŽ CYRILLIC SMALL LETTER YU */ { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ { 0x06c6, 0x0444 }, /* Cyrillic_ef Ñ„ CYRILLIC SMALL LETTER EF */ { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ { 0x06c8, 0x0445 }, /* Cyrillic_ha Ñ… CYRILLIC SMALL LETTER HA */ { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ { 0x06d1, 0x044f }, /* Cyrillic_ya Ñ CYRILLIC SMALL LETTER YA */ { 0x06d2, 0x0440 }, /* Cyrillic_er Ñ€ CYRILLIC SMALL LETTER ER */ { 0x06d3, 0x0441 }, /* Cyrillic_es Ñ CYRILLIC SMALL LETTER ES */ { 0x06d4, 0x0442 }, /* Cyrillic_te Ñ‚ CYRILLIC SMALL LETTER TE */ { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ { 0x06d8, 0x044c }, /* Cyrillic_softsign ÑŒ CYRILLIC SMALL LETTER SOFT SIGN */ { 0x06d9, 0x044b }, /* Cyrillic_yeru Ñ‹ CYRILLIC SMALL LETTER YERU */ { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ { 0x06dc, 0x044d }, /* Cyrillic_e Ñ CYRILLIC SMALL LETTER E */ { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ { 0x06df, 0x044a }, /* Cyrillic_hardsign ÑŠ CYRILLIC SMALL LETTER HARD SIGN */ { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ { 0x06e1, 0x0410 }, /* Cyrillic_A Ð CYRILLIC CAPITAL LETTER A */ { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ { 0x06e8, 0x0425 }, /* Cyrillic_HA Ð¥ CYRILLIC CAPITAL LETTER HA */ { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ { 0x06ee, 0x041d }, /* Cyrillic_EN Ð CYRILLIC CAPITAL LETTER EN */ { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ { 0x06f7, 0x0412 }, /* Cyrillic_VE Ð’ CYRILLIC CAPITAL LETTER VE */ { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ { 0x07a7, 0x038c }, /* Greek_OMICRONaccent ÎŒ GREEK CAPITAL LETTER OMICRON WITH TONOS */ { 0x07a8, 0x038e }, /* Greek_UPSILONaccent ÎŽ GREEK CAPITAL LETTER UPSILON WITH TONOS */ { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Î GREEK CAPITAL LETTER OMEGA WITH TONOS */ { 0x07ae, 0x0385 }, /* Greek_accentdieresis Î… GREEK DIALYTIKA TONOS */ { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ { 0x07b5, 0x03ca }, /* Greek_iotadieresis ÏŠ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis Î GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ { 0x07b7, 0x03cc }, /* Greek_omicronaccent ÏŒ GREEK SMALL LETTER OMICRON WITH TONOS */ { 0x07b8, 0x03cd }, /* Greek_upsilonaccent Ï GREEK SMALL LETTER UPSILON WITH TONOS */ { 0x07b9, 0x03cb }, /* Greek_upsilondieresis Ï‹ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ { 0x07bb, 0x03ce }, /* Greek_omegaaccent ÏŽ GREEK SMALL LETTER OMEGA WITH TONOS */ { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ { 0x07c2, 0x0392 }, /* Greek_BETA Î’ GREEK CAPITAL LETTER BETA */ { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ { 0x07cb, 0x039b }, /* Greek_LAMDA Λ GREEK CAPITAL LETTER LAMDA */ { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ { 0x07cd, 0x039d }, /* Greek_NU Î GREEK CAPITAL LETTER NU */ { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ { 0x07d5, 0x03a5 }, /* Greek_UPSILON Î¥ GREEK CAPITAL LETTER UPSILON */ { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ { 0x07eb, 0x03bb }, /* Greek_lamda λ GREEK SMALL LETTER LAMDA */ { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ { 0x07f0, 0x03c0 }, /* Greek_pi Ï€ GREEK SMALL LETTER PI */ { 0x07f1, 0x03c1 }, /* Greek_rho Ï GREEK SMALL LETTER RHO */ { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma Ï‚ GREEK SMALL LETTER FINAL SIGMA */ { 0x07f4, 0x03c4 }, /* Greek_tau Ï„ GREEK SMALL LETTER TAU */ { 0x07f5, 0x03c5 }, /* Greek_upsilon Ï… GREEK SMALL LETTER UPSILON */ { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ { 0x08a1, 0x23b7 }, /* leftradical ⎷ RADICAL SYMBOL BOTTOM */ { 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ { 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */ { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ { 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ LEFT SQUARE BRACKET UPPER CORNER */ { 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ LEFT SQUARE BRACKET LOWER CORNER */ { 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ RIGHT SQUARE BRACKET UPPER CORNER */ { 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ RIGHT SQUARE BRACKET LOWER CORNER */ { 0x08ab, 0x239b }, /* topleftparens ⎛ LEFT PARENTHESIS UPPER HOOK */ { 0x08ac, 0x239d }, /* botleftparens ⎠LEFT PARENTHESIS LOWER HOOK */ { 0x08ad, 0x239e }, /* toprightparens ⎞ RIGHT PARENTHESIS UPPER HOOK */ { 0x08ae, 0x23a0 }, /* botrightparens ⎠ RIGHT PARENTHESIS LOWER HOOK */ { 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ LEFT CURLY BRACKET MIDDLE PIECE */ { 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ RIGHT CURLY BRACKET MIDDLE PIECE */ /*{ 0x08b1, 0xeeee }, ** topleftsummation ? PUA */ /*{ 0x08b2, 0xeeef }, ** botleftsummation ? PUA */ /*{ 0x08b3, 0xeef0 }, ** topvertsummationconnector ? PUA */ /*{ 0x08b4, 0xeef1 }, ** botvertsummationconnector ? PUA */ /*{ 0x08b5, 0xeef2 }, ** toprightsummation ? PUA */ /*{ 0x08b6, 0xeef3 }, ** botrightsummation ? PUA */ /*{ 0x08b7, 0xeef4 }, ** rightmiddlesummation ? PUA */ { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ { 0x08c1, 0x221d }, /* variation ∠PROPORTIONAL TO */ { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ { 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */ { 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */ { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ { 0x08dd, 0x222a }, /* union ∪ UNION */ { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ { 0x08f6, 0x0192 }, /* function Æ’ LATIN SMALL LETTER F WITH HOOK */ { 0x08fb, 0x2190 }, /* leftarrow ↠LEFTWARDS ARROW */ { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ { 0x09df, 0x2422 }, /* blank ⢠BLANK SYMBOL */ { 0x09e0, 0x25c6 }, /* soliddiamond â—† BLACK DIAMOND */ { 0x09e1, 0x2592 }, /* checkerboard â–’ MEDIUM SHADE */ { 0x09e2, 0x2409 }, /* ht ≠SYMBOL FOR HORIZONTAL TABULATION */ { 0x09e3, 0x240c }, /* ff ⌠SYMBOL FOR FORM FEED */ { 0x09e4, 0x240d }, /* cr â SYMBOL FOR CARRIAGE RETURN */ { 0x09e5, 0x240a }, /* lf ⊠SYMBOL FOR LINE FEED */ { 0x09e8, 0x2424 }, /* nl ⤠SYMBOL FOR NEWLINE */ { 0x09e9, 0x240b }, /* vt â‹ SYMBOL FOR VERTICAL TABULATION */ { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ { 0x09eb, 0x2510 }, /* uprightcorner â” BOX DRAWINGS LIGHT DOWN AND LEFT */ { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ { 0x09ed, 0x2514 }, /* lowleftcorner â”” BOX DRAWINGS LIGHT UP AND RIGHT */ { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ { 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 */ { 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 */ { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ { 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 */ { 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 */ { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ { 0x09f6, 0x2534 }, /* bott â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ { 0x0aaa, 0x2013 }, /* endash – EN DASH */ { 0x0aac, 0x2423 }, /* signifblank ⣠OPEN BOX */ { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ { 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */ { 0x0ab0, 0x2153 }, /* onethird â…“ VULGAR FRACTION ONE THIRD */ { 0x0ab1, 0x2154 }, /* twothirds â…” VULGAR FRACTION TWO THIRDS */ { 0x0ab2, 0x2155 }, /* onefifth â…• VULGAR FRACTION ONE FIFTH */ { 0x0ab3, 0x2156 }, /* twofifths â…– VULGAR FRACTION TWO FIFTHS */ { 0x0ab4, 0x2157 }, /* threefifths â…— VULGAR FRACTION THREE FIFTHS */ { 0x0ab5, 0x2158 }, /* fourfifths â…˜ VULGAR FRACTION FOUR FIFTHS */ { 0x0ab6, 0x2159 }, /* onesixth â…™ VULGAR FRACTION ONE SIXTH */ { 0x0ab7, 0x215a }, /* fivesixths â…š VULGAR FRACTION FIVE SIXTHS */ { 0x0ab8, 0x2105 }, /* careof â„… CARE OF */ { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ /* 0x0abf marker ? ??? */ { 0x0ac3, 0x215b }, /* oneeighth â…› VULGAR FRACTION ONE EIGHTH */ { 0x0ac4, 0x215c }, /* threeeighths â…œ VULGAR FRACTION THREE EIGHTHS */ { 0x0ac5, 0x215d }, /* fiveeighths â… VULGAR FRACTION FIVE EIGHTHS */ { 0x0ac6, 0x215e }, /* seveneighths â…ž VULGAR FRACTION SEVEN EIGHTHS */ { 0x0ac9, 0x2122 }, /* trademark â„¢ TRADE MARK SIGN */ { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ /* 0x0acb trademarkincircle ? ??? */ { 0x0acc, 0x25c1 }, /* leftopentriangle â— WHITE LEFT-POINTING TRIANGLE */ { 0x0acd, 0x25b7 }, /* rightopentriangle â–· WHITE RIGHT-POINTING TRIANGLE */ { 0x0ace, 0x25cb }, /* emopencircle â—‹ WHITE CIRCLE */ { 0x0acf, 0x25af }, /* emopenrectangle â–¯ WHITE VERTICAL RECTANGLE */ { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ { 0x0ad3, 0x201d }, /* rightdoublequotemark †RIGHT DOUBLE QUOTATION MARK */ { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ { 0x0ad5, 0x2030 }, /* permille ‰ PER MILLE SIGN */ { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ { 0x0ad9, 0x271d }, /* latincross ✠LATIN CROSS */ /* 0x0ada hexagram ? ??? */ { 0x0adb, 0x25ac }, /* filledrectbullet â–¬ BLACK RECTANGLE */ { 0x0adc, 0x25c0 }, /* filledlefttribullet â—€ BLACK LEFT-POINTING TRIANGLE */ { 0x0add, 0x25b6 }, /* filledrighttribullet â–¶ BLACK RIGHT-POINTING TRIANGLE */ { 0x0ade, 0x25cf }, /* emfilledcircle â— BLACK CIRCLE */ { 0x0adf, 0x25ae }, /* emfilledrect â–® BLACK VERTICAL RECTANGLE */ { 0x0ae0, 0x25e6 }, /* enopencircbullet â—¦ WHITE BULLET */ { 0x0ae1, 0x25ab }, /* enopensquarebullet â–« WHITE SMALL SQUARE */ { 0x0ae2, 0x25ad }, /* openrectbullet â–­ WHITE RECTANGLE */ { 0x0ae3, 0x25b3 }, /* opentribulletup â–³ WHITE UP-POINTING TRIANGLE */ { 0x0ae4, 0x25bd }, /* opentribulletdown â–½ WHITE DOWN-POINTING TRIANGLE */ { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ { 0x0ae7, 0x25aa }, /* enfilledsqbullet â–ª BLACK SMALL SQUARE */ { 0x0ae8, 0x25b2 }, /* filledtribulletup â–² BLACK UP-POINTING TRIANGLE */ { 0x0ae9, 0x25bc }, /* filledtribulletdown â–¼ BLACK DOWN-POINTING TRIANGLE */ { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ { 0x0af1, 0x2020 }, /* dagger † DAGGER */ { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ { 0x0af6, 0x266d }, /* musicalflat â™­ MUSIC FLAT SIGN */ { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ { 0x0afb, 0x2117 }, /* phonographcopyright â„— SOUND RECORDING COPYRIGHT */ { 0x0afc, 0x2038 }, /* caret ‸ CARET */ { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ /* 0x0aff cursor ? ??? */ { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD */ { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ { 0x0bcf, 0x25cb }, /* circle â—‹ WHITE CIRCLE */ { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */ { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */ { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ { 0x0ce0, 0x05d0 }, /* hebrew_aleph × HEBREW LETTER ALEF */ { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ { 0x0ce2, 0x05d2 }, /* hebrew_gimel ×’ HEBREW LETTER GIMEL */ { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ { 0x0ce4, 0x05d4 }, /* hebrew_he ×” HEBREW LETTER HE */ { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ { 0x0ce6, 0x05d6 }, /* hebrew_zain ×– HEBREW LETTER ZAYIN */ { 0x0ce7, 0x05d7 }, /* hebrew_chet ×— HEBREW LETTER HET */ { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ { 0x0ce9, 0x05d9 }, /* hebrew_yod ×™ HEBREW LETTER YOD */ { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ { 0x0ceb, 0x05db }, /* hebrew_kaph ×› HEBREW LETTER KAF */ { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ { 0x0ced, 0x05dd }, /* hebrew_finalmem × HEBREW LETTER FINAL MEM */ { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ { 0x0cf0, 0x05e0 }, /* hebrew_nun ×  HEBREW LETTER NUN */ { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ { 0x0cf2, 0x05e2 }, /* hebrew_ayin ×¢ HEBREW LETTER AYIN */ { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ×£ HEBREW LETTER FINAL PE */ { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ×¥ HEBREW LETTER FINAL TSADI */ { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ { 0x0cf7, 0x05e7 }, /* hebrew_qoph ×§ HEBREW LETTER QOF */ { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ { 0x0da1, 0x0e01 }, /* Thai_kokai ภTHAI CHARACTER KO KAI */ { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ { 0x0dad, 0x0e0d }, /* Thai_yoying ภTHAI CHARACTER YO YING */ { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ { 0x0daf, 0x0e0f }, /* Thai_topatak ภTHAI CHARACTER TO PATAK */ { 0x0db0, 0x0e10 }, /* Thai_thothan ภTHAI CHARACTER THO THAN */ { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ { 0x0dbd, 0x0e1d }, /* Thai_fofa ภTHAI CHARACTER FO FA */ { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ Unassigned code point */ { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ { 0x0de1, 0x0e41 }, /* Thai_saraae ๠THAI CHARACTER SARA AE */ { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ { 0x0ded, 0x0e4d }, /* Thai_nikhahit ๠THAI CHARACTER NIKHAHIT */ { 0x0df0, 0x0e50 }, /* Thai_leksun ๠THAI DIGIT ZERO */ { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ { 0x0ea4, 0x3134 }, /* Hangul_Nieun ã„´ HANGUL LETTER NIEUN */ { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ã„¶ HANGUL LETTER NIEUN-HIEUH */ { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ã„· HANGUL LETTER TIKEUT */ { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ { 0x0eab, 0x313b }, /* Hangul_RieulMieum ã„» HANGUL LETTER RIEUL-MIEUM */ { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ã„¿ HANGUL LETTER RIEUL-PHIEUPH */ { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ã…€ HANGUL LETTER RIEUL-HIEUH */ { 0x0eb1, 0x3141 }, /* Hangul_Mieum ã… HANGUL LETTER MIEUM */ { 0x0eb2, 0x3142 }, /* Hangul_Pieub ã…‚ HANGUL LETTER PIEUP */ { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ã…ƒ HANGUL LETTER SSANGPIEUP */ { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ã…„ HANGUL LETTER PIEUP-SIOS */ { 0x0eb5, 0x3145 }, /* Hangul_Sios ã…… HANGUL LETTER SIOS */ { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ã…† HANGUL LETTER SSANGSIOS */ { 0x0eb7, 0x3147 }, /* Hangul_Ieung ã…‡ HANGUL LETTER IEUNG */ { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ã…ˆ HANGUL LETTER CIEUC */ { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ã…‰ HANGUL LETTER SSANGCIEUC */ { 0x0eba, 0x314a }, /* Hangul_Cieuc ã…Š HANGUL LETTER CHIEUCH */ { 0x0ebb, 0x314b }, /* Hangul_Khieuq ã…‹ HANGUL LETTER KHIEUKH */ { 0x0ebc, 0x314c }, /* Hangul_Tieut ã…Œ HANGUL LETTER THIEUTH */ { 0x0ebd, 0x314d }, /* Hangul_Phieuf ã… HANGUL LETTER PHIEUPH */ { 0x0ebe, 0x314e }, /* Hangul_Hieuh ã…Ž HANGUL LETTER HIEUH */ { 0x0ebf, 0x314f }, /* Hangul_A ã… HANGUL LETTER A */ { 0x0ec0, 0x3150 }, /* Hangul_AE ã… HANGUL LETTER AE */ { 0x0ec1, 0x3151 }, /* Hangul_YA ã…‘ HANGUL LETTER YA */ { 0x0ec2, 0x3152 }, /* Hangul_YAE ã…’ HANGUL LETTER YAE */ { 0x0ec3, 0x3153 }, /* Hangul_EO ã…“ HANGUL LETTER EO */ { 0x0ec4, 0x3154 }, /* Hangul_E ã…” HANGUL LETTER E */ { 0x0ec5, 0x3155 }, /* Hangul_YEO ã…• HANGUL LETTER YEO */ { 0x0ec6, 0x3156 }, /* Hangul_YE ã…– HANGUL LETTER YE */ { 0x0ec7, 0x3157 }, /* Hangul_O ã…— HANGUL LETTER O */ { 0x0ec8, 0x3158 }, /* Hangul_WA ã…˜ HANGUL LETTER WA */ { 0x0ec9, 0x3159 }, /* Hangul_WAE ã…™ HANGUL LETTER WAE */ { 0x0eca, 0x315a }, /* Hangul_OE ã…š HANGUL LETTER OE */ { 0x0ecb, 0x315b }, /* Hangul_YO ã…› HANGUL LETTER YO */ { 0x0ecc, 0x315c }, /* Hangul_U ã…œ HANGUL LETTER U */ { 0x0ecd, 0x315d }, /* Hangul_WEO ã… HANGUL LETTER WEO */ { 0x0ece, 0x315e }, /* Hangul_WE ã…ž HANGUL LETTER WE */ { 0x0ecf, 0x315f }, /* Hangul_WI ã…Ÿ HANGUL LETTER WI */ { 0x0ed0, 0x3160 }, /* Hangul_YU ã…  HANGUL LETTER YU */ { 0x0ed1, 0x3161 }, /* Hangul_EU ã…¡ HANGUL LETTER EU */ { 0x0ed2, 0x3162 }, /* Hangul_YI ã…¢ HANGUL LETTER YI */ { 0x0ed3, 0x3163 }, /* Hangul_I ã…£ HANGUL LETTER I */ { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇠHANGUL JONGSEONG PHIEUPH */ { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ã…­ HANGUL LETTER RIEUL-YEORINHIEUH */ { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ã…± HANGUL LETTER KAPYEOUNMIEUM */ { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ã…¸ HANGUL LETTER KAPYEOUNPIEUP */ { 0x0ef2, 0x317f }, /* Hangul_PanSios ã…¿ HANGUL LETTER PANSIOS */ { 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆠHANGUL LETTER YESIEUNG */ { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆠHANGUL LETTER ARAEA */ { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ { 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */ { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ { 0x0eff, 0x20a9 }, /* Korean_Won â‚© WON SIGN */ { 0x13a4, 0x20ac }, /* Euro € EURO SIGN */ { 0x13bc, 0x0152 }, /* OE Å’ LATIN CAPITAL LIGATURE OE */ { 0x13bd, 0x0153 }, /* oe Å“ LATIN SMALL LIGATURE OE */ { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ { 0x20a0, 0x20a0 }, /* EcuSign â‚  EURO-CURRENCY SIGN */ { 0x20a1, 0x20a1 }, /* ColonSign â‚¡ COLON SIGN */ { 0x20a2, 0x20a2 }, /* CruzeiroSign â‚¢ CRUZEIRO SIGN */ { 0x20a3, 0x20a3 }, /* FFrancSign â‚£ FRENCH FRANC SIGN */ { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */ { 0x20a5, 0x20a5 }, /* MillSign â‚¥ MILL SIGN */ { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */ { 0x20a7, 0x20a7 }, /* PesetaSign â‚§ PESETA SIGN */ { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */ { 0x20a9, 0x20a9 }, /* WonSign â‚© WON SIGN */ { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */ { 0x20ab, 0x20ab }, /* DongSign â‚« DONG SIGN */ { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ /*{ 0xfd01, 0xe001 }, ** 3270_Duplicate ? PUA */ /*{ 0xfd02, 0xe002 }, ** 3270_FieldMark ? PUA */ /*{ 0xfd03, 0xe003 }, ** 3270_Right2 ? PUA */ /*{ 0xfd04, 0xe004 }, ** 3270_Left2 ? PUA */ /*{ 0xfd05, 0xe005 }, ** 3270_BackTab ? PUA */ /*{ 0xfd06, 0xe006 }, ** 3270_EraseEOF ? PUA */ /*{ 0xfd07, 0xe007 }, ** 3270_EraseInput ? PUA */ /*{ 0xfd08, 0xe008 }, ** 3270_Reset ? PUA */ /*{ 0xfd09, 0xe009 }, ** 3270_Quit ? PUA */ /*{ 0xfd0a, 0xe00a }, ** 3270_PA1 ? PUA */ /*{ 0xfd0b, 0xe00b }, ** 3270_PA2 ? PUA */ /*{ 0xfd0c, 0xe00c }, ** 3270_PA3 ? PUA */ /*{ 0xfd0d, 0xe00d }, ** 3270_Test ? PUA */ /*{ 0xfd0e, 0xe00e }, ** 3270_Attn ? PUA */ /*{ 0xfd0f, 0xe00f }, ** 3270_CursorBlink ? PUA */ /*{ 0xfd10, 0xe010 }, ** 3270_AltCursor ? PUA */ /*{ 0xfd11, 0xe011 }, ** 3270_KeyClick ? PUA */ /*{ 0xfd12, 0xe012 }, ** 3270_Jump ? PUA */ /*{ 0xfd13, 0xe013 }, ** 3270_Ident ? PUA */ /*{ 0xfd14, 0xe014 }, ** 3270_Rule ? PUA */ /*{ 0xfd15, 0xe015 }, ** 3270_Copy ? PUA */ /*{ 0xfd16, 0xe016 }, ** 3270_Play ? PUA */ /*{ 0xfd17, 0xe017 }, ** 3270_Setup ? PUA */ /*{ 0xfd18, 0xe018 }, ** 3270_Record ? PUA */ /*{ 0xfd19, 0xe019 }, ** 3270_ChangeScreen ? PUA */ /*{ 0xfd1a, 0xe01a }, ** 3270_DeleteWord ? PUA */ /*{ 0xfd1b, 0xe01b }, ** 3270_ExSelect ? PUA */ /*{ 0xfd1c, 0xe01c }, ** 3270_CursorSelect ? PUA */ /*{ 0xfd1d, 0xe01d }, ** 3270_PrintScreen ? PUA */ /*{ 0xfd1e, 0xe01e }, ** 3270_Enter ? PUA */ /*{ 0xfe01, 0xe101 }, ** ISO_Lock ? PUA */ /*{ 0xfe02, 0xe102 }, ** ISO_Level2_Latch ? PUA */ /*{ 0xfe03, 0xe103 }, ** ISO_Level3_Shift ? PUA */ /*{ 0xfe04, 0xe104 }, ** ISO_Level3_Latch ? PUA */ /*{ 0xfe05, 0xe105 }, ** ISO_Level3_Lock ? PUA */ /*{ 0xfe06, 0xe106 }, ** ISO_Group_Latch ? PUA */ /*{ 0xfe07, 0xe107 }, ** ISO_Group_Lock ? PUA */ /*{ 0xfe08, 0xe108 }, ** ISO_Next_Group ? PUA */ /*{ 0xfe09, 0xe109 }, ** ISO_Next_Group_Lock ? PUA */ /*{ 0xfe0a, 0xe10a }, ** ISO_Prev_Group ? PUA */ /*{ 0xfe0b, 0xe10b }, ** ISO_Prev_Group_Lock ? PUA */ /*{ 0xfe0c, 0xe10c }, ** ISO_First_Group ? PUA */ /*{ 0xfe0d, 0xe10d }, ** ISO_First_Group_Lock ? PUA */ /*{ 0xfe0e, 0xe10e }, ** ISO_Last_Group ? PUA */ /*{ 0xfe0f, 0xe10f }, ** ISO_Last_Group_Lock ? PUA */ /*{ 0xfe11, 0xe111 }, ** ISO_Level5_Shift ? PUA */ /*{ 0xfe12, 0xe112 }, ** ISO_Level5_Latch ? PUA */ /*{ 0xfe13, 0xe113 }, ** ISO_Level5_Lock ? PUA */ /*{ 0xfe20, 0xe120 }, ** ISO_Left_Tab ? PUA */ /*{ 0xfe21, 0xe121 }, ** ISO_Move_Line_Up ? PUA */ /*{ 0xfe22, 0xe122 }, ** ISO_Move_Line_Down ? PUA */ /*{ 0xfe23, 0xe123 }, ** ISO_Partial_Line_Up ? PUA */ /*{ 0xfe24, 0xe124 }, ** ISO_Partial_Line_Down ? PUA */ /*{ 0xfe25, 0xe125 }, ** ISO_Partial_Space_Left ? PUA */ /*{ 0xfe26, 0xe126 }, ** ISO_Partial_Space_Right ? PUA */ /*{ 0xfe27, 0xe127 }, ** ISO_Set_Margin_Left ? PUA */ /*{ 0xfe28, 0xe128 }, ** ISO_Set_Margin_Right ? PUA */ /*{ 0xfe29, 0xe129 }, ** ISO_Release_Margin_Left ? PUA */ /*{ 0xfe2a, 0xe12a }, ** ISO_Release_Margin_Right ? PUA */ /*{ 0xfe2b, 0xe12b }, ** ISO_Release_Both_Margins ? PUA */ /*{ 0xfe2c, 0xe12c }, ** ISO_Fast_Cursor_Left ? PUA */ /*{ 0xfe2d, 0xe12d }, ** ISO_Fast_Cursor_Right ? PUA */ /*{ 0xfe2e, 0xe12e }, ** ISO_Fast_Cursor_Up ? PUA */ /*{ 0xfe2f, 0xe12f }, ** ISO_Fast_Cursor_Down ? PUA */ /*{ 0xfe30, 0xe130 }, ** ISO_Continuous_Underline ? PUA */ /*{ 0xfe31, 0xe131 }, ** ISO_Discontinuous_Underline ? PUA */ /*{ 0xfe32, 0xe132 }, ** ISO_Emphasize ? PUA */ /*{ 0xfe33, 0xe133 }, ** ISO_Center_Object ? PUA */ /*{ 0xfe34, 0xe134 }, ** ISO_Enter ? PUA */ { 0xfe50, 0x0300 }, /* dead_grave Ì€ COMBINING GRAVE ACCENT */ { 0xfe51, 0x0301 }, /* dead_acute Ì COMBINING ACUTE ACCENT */ { 0xfe52, 0x0302 }, /* dead_circumflex Ì‚ COMBINING CIRCUMFLEX ACCENT */ { 0xfe53, 0x0303 }, /* dead_tilde ̃ COMBINING TILDE */ { 0xfe54, 0x0304 }, /* dead_macron Ì„ COMBINING MACRON */ { 0xfe55, 0x0306 }, /* dead_breve ̆ COMBINING BREVE */ { 0xfe56, 0x0307 }, /* dead_abovedot ̇ COMBINING DOT ABOVE */ { 0xfe57, 0x0308 }, /* dead_diaeresis ̈ COMBINING DIAERESIS */ { 0xfe58, 0x030a }, /* dead_abovering ÌŠ COMBINING RING ABOVE */ { 0xfe59, 0x030b }, /* dead_doubleacute Ì‹ COMBINING DOUBLE ACUTE ACCENT */ { 0xfe5a, 0x030c }, /* dead_caron ÌŒ COMBINING CARON */ { 0xfe5b, 0x0327 }, /* dead_cedilla ̧ COMBINING CEDILLA */ { 0xfe5c, 0x0328 }, /* dead_ogonek ̨ COMBINING OGONEK */ { 0xfe5d, 0x0345 }, /* dead_iota Í… COMBINING GREEK YPOGEGRAMMENI */ { 0xfe5e, 0x3099 }, /* dead_voiced_sound ã‚™ COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK */ { 0xfe5f, 0x309a }, /* dead_semivoiced_sound ゚ COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ /*{ 0xfe60, 0xe160 }, ** dead_belowdot ? PUA */ /*{ 0xfe61, 0xe161 }, ** dead_hook ? PUA */ /*{ 0xfe62, 0xe162 }, ** dead_horn ? PUA */ /*{ 0xfe63, 0xe163 }, ** dead_stroke ? PUA */ /*{ 0xfe64, 0xe164 }, ** dead_abovecomma ? PUA */ /*{ 0xfe65, 0xe165 }, ** dead_abovereversedcomma ? PUA */ /*{ 0xfe66, 0xe166 }, ** dead_doublegrave ? PUA */ /*{ 0xfe67, 0xe167 }, ** dead_belowring ? PUA */ /*{ 0xfe68, 0xe168 }, ** dead_belowmacron ? PUA */ /*{ 0xfe69, 0xe169 }, ** dead_belowcircumflex ? PUA */ /*{ 0xfe6a, 0xe16a }, ** dead_belowtilde ? PUA */ /*{ 0xfe6b, 0xe16b }, ** dead_belowbreve ? PUA */ /*{ 0xfe6c, 0xe16c }, ** dead_belowdiaeresis ? PUA */ /*{ 0xfe6d, 0xe16d }, ** dead_invertedbreve ? PUA */ /*{ 0xfe6e, 0xe16e }, ** dead_belowcomma ? PUA */ /*{ 0xfe6f, 0xe16f }, ** dead_currency ? PUA */ /*{ 0xfe70, 0xe170 }, ** AccessX_Enable ? PUA */ /*{ 0xfe71, 0xe171 }, ** AccessX_Feedback_Enable ? PUA */ /*{ 0xfe72, 0xe172 }, ** RepeatKeys_Enable ? PUA */ /*{ 0xfe73, 0xe173 }, ** SlowKeys_Enable ? PUA */ /*{ 0xfe74, 0xe174 }, ** BounceKeys_Enable ? PUA */ /*{ 0xfe75, 0xe175 }, ** StickyKeys_Enable ? PUA */ /*{ 0xfe76, 0xe176 }, ** MouseKeys_Enable ? PUA */ /*{ 0xfe77, 0xe177 }, ** MouseKeys_Accel_Enable ? PUA */ /*{ 0xfe78, 0xe178 }, ** Overlay1_Enable ? PUA */ /*{ 0xfe79, 0xe179 }, ** Overlay2_Enable ? PUA */ /*{ 0xfe7a, 0xe17a }, ** AudibleBell_Enable ? PUA */ /*{ 0xfe80, 0xe180 }, ** dead_a ? PUA */ /*{ 0xfe81, 0xe181 }, ** dead_A ? PUA */ /*{ 0xfe82, 0xe182 }, ** dead_e ? PUA */ /*{ 0xfe83, 0xe183 }, ** dead_E ? PUA */ /*{ 0xfe84, 0xe184 }, ** dead_i ? PUA */ /*{ 0xfe85, 0xe185 }, ** dead_I ? PUA */ /*{ 0xfe86, 0xe186 }, ** dead_o ? PUA */ /*{ 0xfe87, 0xe187 }, ** dead_O ? PUA */ /*{ 0xfe88, 0xe188 }, ** dead_u ? PUA */ /*{ 0xfe89, 0xe189 }, ** dead_U ? PUA */ /*{ 0xfe8a, 0xe18a }, ** dead_schwa ? PUA */ /*{ 0xfe8b, 0xe18b }, ** dead_SCHWA ? PUA */ /*{ 0xfe8c, 0xe18c }, ** dead_greek ? PUA */ /*{ 0xfe8d, 0xe18d }, ** dead_hamza ? PUA */ /*{ 0xfe90, 0xe190 }, ** dead_lowline ? PUA */ /*{ 0xfe91, 0xe191 }, ** dead_aboveverticalline ? PUA */ /*{ 0xfe92, 0xe192 }, ** dead_belowverticalline ? PUA */ /*{ 0xfe93, 0xe193 }, ** dead_longsolidusoverlay ? PUA */ /*{ 0xfea0, 0xe1a0 }, ** ch ? PUA */ /*{ 0xfea1, 0xe1a1 }, ** Ch ? PUA */ /*{ 0xfea2, 0xe1a2 }, ** CH ? PUA */ /*{ 0xfea3, 0xe1a3 }, ** c_h ? PUA */ /*{ 0xfea4, 0xe1a4 }, ** C_h ? PUA */ /*{ 0xfea5, 0xe1a5 }, ** C_H ? PUA */ /*{ 0xfed0, 0xe1d0 }, ** First_Virtual_Screen ? PUA */ /*{ 0xfed1, 0xe1d1 }, ** Prev_Virtual_Screen ? PUA */ /*{ 0xfed2, 0xe1d2 }, ** Next_Virtual_Screen ? PUA */ /*{ 0xfed4, 0xe1d4 }, ** Last_Virtual_Screen ? PUA */ /*{ 0xfed5, 0xe1d5 }, ** Terminate_Server ? PUA */ /*{ 0xfee0, 0xe1e0 }, ** Pointer_Left ? PUA */ /*{ 0xfee1, 0xe1e1 }, ** Pointer_Right ? PUA */ /*{ 0xfee2, 0xe1e2 }, ** Pointer_Up ? PUA */ /*{ 0xfee3, 0xe1e3 }, ** Pointer_Down ? PUA */ /*{ 0xfee4, 0xe1e4 }, ** Pointer_UpLeft ? PUA */ /*{ 0xfee5, 0xe1e5 }, ** Pointer_UpRight ? PUA */ /*{ 0xfee6, 0xe1e6 }, ** Pointer_DownLeft ? PUA */ /*{ 0xfee7, 0xe1e7 }, ** Pointer_DownRight ? PUA */ /*{ 0xfee8, 0xe1e8 }, ** Pointer_Button_Dflt ? PUA */ /*{ 0xfee9, 0xe1e9 }, ** Pointer_Button1 ? PUA */ /*{ 0xfeea, 0xe1ea }, ** Pointer_Button2 ? PUA */ /*{ 0xfeeb, 0xe1eb }, ** Pointer_Button3 ? PUA */ /*{ 0xfeec, 0xe1ec }, ** Pointer_Button4 ? PUA */ /*{ 0xfeed, 0xe1ed }, ** Pointer_Button5 ? PUA */ /*{ 0xfeee, 0xe1ee }, ** Pointer_DblClick_Dflt ? PUA */ /*{ 0xfeef, 0xe1ef }, ** Pointer_DblClick1 ? PUA */ /*{ 0xfef0, 0xe1f0 }, ** Pointer_DblClick2 ? PUA */ /*{ 0xfef1, 0xe1f1 }, ** Pointer_DblClick3 ? PUA */ /*{ 0xfef2, 0xe1f2 }, ** Pointer_DblClick4 ? PUA */ /*{ 0xfef3, 0xe1f3 }, ** Pointer_DblClick5 ? PUA */ /*{ 0xfef4, 0xe1f4 }, ** Pointer_Drag_Dflt ? PUA */ /*{ 0xfef5, 0xe1f5 }, ** Pointer_Drag1 ? PUA */ /*{ 0xfef6, 0xe1f6 }, ** Pointer_Drag2 ? PUA */ /*{ 0xfef7, 0xe1f7 }, ** Pointer_Drag3 ? PUA */ /*{ 0xfef8, 0xe1f8 }, ** Pointer_Drag4 ? PUA */ /*{ 0xfef9, 0xe1f9 }, ** Pointer_EnableKeys ? PUA */ /*{ 0xfefa, 0xe1fa }, ** Pointer_Accelerate ? PUA */ /*{ 0xfefb, 0xe1fb }, ** Pointer_DfltBtnNext ? PUA */ /*{ 0xfefc, 0xe1fc }, ** Pointer_DfltBtnPrev ? PUA */ /*{ 0xfefd, 0xe1fd }, ** Pointer_Drag5 ? PUA */ { 0xff08, 0x0008 }, /* BackSpace ^H */ { 0xff09, 0x0009 }, /* Tab ^I */ { 0xff0a, 0x000a }, /* Linefeed ^J */ { 0xff0b, 0x000b }, /* Clear ^K */ { 0xff0d, 0x000d }, /* Return ^M */ { 0xff13, 0x0013 }, /* Pause ^S */ { 0xff14, 0x0014 }, /* Scroll_Lock ^T */ { 0xff15, 0x0015 }, /* Sys_Req ^U */ { 0xff1b, 0x001b }, /* Escape ^[ */ /*{ 0xff20, 0xe220 }, ** Multi_key ? PUA Multi-key character compose */ /*{ 0xff21, 0xe221 }, ** Kanji ? PUA Kanji, Kanji convert */ /*{ 0xff22, 0xe222 }, ** Muhenkan ? PUA Cancel Conversion */ /*{ 0xff23, 0xe223 }, ** Henkan_Mode ? PUA Start/Stop Conversion */ /*{ 0xff24, 0xe224 }, ** Romaji ? PUA to Romaji */ /*{ 0xff25, 0xe225 }, ** Hiragana ? PUA to Hiragana */ /*{ 0xff26, 0xe226 }, ** Katakana ? PUA to Katakana */ /*{ 0xff27, 0xe227 }, ** Hiragana_Katakana ? PUA Hiragana/Katakana toggle */ /*{ 0xff28, 0xe228 }, ** Zenkaku ? PUA to Zenkaku */ /*{ 0xff29, 0xe229 }, ** Hankaku ? PUA to Hankaku */ /*{ 0xff2a, 0xe22a }, ** Zenkaku_Hankaku ? PUA Zenkaku/Hankaku toggle */ /*{ 0xff2b, 0xe22b }, ** Touroku ? PUA Add to Dictionary */ /*{ 0xff2c, 0xe22c }, ** Massyo ? PUA Delete from Dictionary */ /*{ 0xff2d, 0xe22d }, ** Kana_Lock ? PUA Kana Lock */ /*{ 0xff2e, 0xe22e }, ** Kana_Shift ? PUA Kana Shift */ /*{ 0xff2f, 0xe22f }, ** Eisu_Shift ? PUA Alphanumeric Shift */ /*{ 0xff30, 0xe230 }, ** Eisu_toggle ? PUA Alphanumeric toggle */ /*{ 0xff31, 0xe231 }, ** Hangul ? PUA Hangul start/stoptoggle */ /*{ 0xff32, 0xe232 }, ** Hangul_Start ? PUA Hangul start */ /*{ 0xff33, 0xe233 }, ** Hangul_End ? PUA Hangul end, English start */ /*{ 0xff34, 0xe234 }, ** Hangul_Hanja ? PUA Start Hangul->Hanja Conversion */ /*{ 0xff35, 0xe235 }, ** Hangul_Jamo ? PUA Hangul Jamo mode */ /*{ 0xff36, 0xe236 }, ** Hangul_Romaja ? PUA Hangul Romaja mode */ /*{ 0xff37, 0xe237 }, ** Hangul_Codeinput ? PUA */ /*{ 0xff38, 0xe238 }, ** Hangul_Jeonja ? PUA Jeonja mode */ /*{ 0xff39, 0xe239 }, ** Hangul_Banja ? PUA Banja mode */ /*{ 0xff3a, 0xe23a }, ** Hangul_PreHanja ? PUA Pre Hanja conversion */ /*{ 0xff3b, 0xe23b }, ** Hangul_PostHanja ? PUA Post Hanja conversion */ /*{ 0xff3c, 0xe23c }, ** Hangul_SingleCandidate ? PUA */ /*{ 0xff3d, 0xe23d }, ** Hangul_MultipleCandidate ? PUA */ /*{ 0xff3e, 0xe23e }, ** Hangul_PreviousCandidate ? PUA */ /*{ 0xff3f, 0xe23f }, ** Hangul_Special ? PUA Special symbols */ /*{ 0xff50, 0xe250 }, ** Home ? PUA */ /*{ 0xff51, 0xe251 }, ** Left ? PUA Move left, left arrow */ /*{ 0xff52, 0xe252 }, ** Up ? PUA Move up, up arrow */ /*{ 0xff53, 0xe253 }, ** Right ? PUA Move right, right arrow */ /*{ 0xff54, 0xe254 }, ** Down ? PUA Move down, down arrow */ /*{ 0xff55, 0xe255 }, ** Prior ? PUA Prior, previous */ /*{ 0xff56, 0xe256 }, ** Next ? PUA Next */ /*{ 0xff57, 0xe257 }, ** End ? PUA EOL */ /*{ 0xff58, 0xe258 }, ** Begin ? PUA BOL */ /*{ 0xff60, 0xe260 }, ** Select ? PUA Select, mark */ /*{ 0xff61, 0xe261 }, ** Print ? PUA */ /*{ 0xff62, 0xe262 }, ** Execute ? PUA Execute, run, do */ /*{ 0xff63, 0xe263 }, ** Insert ? PUA Insert, insert here */ /*{ 0xff65, 0xe265 }, ** Undo ? PUA */ /*{ 0xff66, 0xe266 }, ** Redo ? PUA Redo, again */ /*{ 0xff67, 0xe267 }, ** Menu ? PUA */ /*{ 0xff68, 0xe268 }, ** Find ? PUA Find, search */ /*{ 0xff69, 0xe269 }, ** Cancel ? PUA Cancel, stop, abort, exit */ /*{ 0xff6a, 0xe26a }, ** Help ? PUA Help */ /*{ 0xff6b, 0xe26b }, ** Break ? PUA */ /*{ 0xff7e, 0xe27e }, ** Mode_switch ? PUA Character set switch */ /*{ 0xff7f, 0xe27f }, ** Num_Lock ? PUA */ /*{ 0xff80, 0xe280 }, ** KP_Space ? PUA */ /*{ 0xff89, 0xe289 }, ** KP_Tab ? PUA */ /*{ 0xff8d, 0xe28d }, ** KP_Enter ? PUA */ /*{ 0xff91, 0xe291 }, ** KP_F1 ? PUA PF1, KP_A, ... */ /*{ 0xff92, 0xe292 }, ** KP_F2 ? PUA */ /*{ 0xff93, 0xe293 }, ** KP_F3 ? PUA */ /*{ 0xff94, 0xe294 }, ** KP_F4 ? PUA */ /*{ 0xff95, 0xe295 }, ** KP_Home ? PUA */ /*{ 0xff96, 0xe296 }, ** KP_Left ? PUA */ /*{ 0xff97, 0xe297 }, ** KP_Up ? PUA */ /*{ 0xff98, 0xe298 }, ** KP_Right ? PUA */ /*{ 0xff99, 0xe299 }, ** KP_Down ? PUA */ /*{ 0xff9a, 0xe29a }, ** KP_Prior ? PUA */ /*{ 0xff9b, 0xe29b }, ** KP_Next ? PUA */ /*{ 0xff9c, 0xe29c }, ** KP_End ? PUA */ /*{ 0xff9d, 0xe29d }, ** KP_Begin ? PUA */ /*{ 0xff9e, 0xe29e }, ** KP_Insert ? PUA */ /*{ 0xff9f, 0xe29f }, ** KP_Delete ? PUA */ /*{ 0xffaa, 0xe2aa }, ** KP_Multiply ? PUA */ /*{ 0xffab, 0xe2ab }, ** KP_Add ? PUA */ /*{ 0xffac, 0xe2ac }, ** KP_Separator ? PUA */ /*{ 0xffad, 0xe2ad }, ** KP_Subtract ? PUA */ /*{ 0xffae, 0xe2ae }, ** KP_Decimal ? PUA */ /*{ 0xffaf, 0xe2af }, ** KP_Divide ? PUA */ /*{ 0xffb0, 0xe2b0 }, ** KP_0 ? PUA */ /*{ 0xffb1, 0xe2b1 }, ** KP_1 ? PUA */ /*{ 0xffb2, 0xe2b2 }, ** KP_2 ? PUA */ /*{ 0xffb3, 0xe2b3 }, ** KP_3 ? PUA */ /*{ 0xffb4, 0xe2b4 }, ** KP_4 ? PUA */ /*{ 0xffb5, 0xe2b5 }, ** KP_5 ? PUA */ /*{ 0xffb6, 0xe2b6 }, ** KP_6 ? PUA */ /*{ 0xffb7, 0xe2b7 }, ** KP_7 ? PUA */ /*{ 0xffb8, 0xe2b8 }, ** KP_8 ? PUA */ /*{ 0xffb9, 0xe2b9 }, ** KP_9 ? PUA */ /*{ 0xffbd, 0xe2bd }, ** KP_Equal ? PUA */ /*{ 0xffbe, 0xe2be }, ** F1 ? PUA */ /*{ 0xffbf, 0xe2bf }, ** F2 ? PUA */ /*{ 0xffc0, 0xe2c0 }, ** F3 ? PUA */ /*{ 0xffc1, 0xe2c1 }, ** F4 ? PUA */ /*{ 0xffc2, 0xe2c2 }, ** F5 ? PUA */ /*{ 0xffc3, 0xe2c3 }, ** F6 ? PUA */ /*{ 0xffc4, 0xe2c4 }, ** F7 ? PUA */ /*{ 0xffc5, 0xe2c5 }, ** F8 ? PUA */ /*{ 0xffc6, 0xe2c6 }, ** F9 ? PUA */ /*{ 0xffc7, 0xe2c7 }, ** F10 ? PUA */ /*{ 0xffc8, 0xe2c8 }, ** F11 ? PUA */ /*{ 0xffc9, 0xe2c9 }, ** F12 ? PUA */ /*{ 0xffca, 0xe2ca }, ** F13 ? PUA */ /*{ 0xffcb, 0xe2cb }, ** F14 ? PUA */ /*{ 0xffcc, 0xe2cc }, ** F15 ? PUA */ /*{ 0xffcd, 0xe2cd }, ** F16 ? PUA */ /*{ 0xffce, 0xe2ce }, ** F17 ? PUA */ /*{ 0xffcf, 0xe2cf }, ** F18 ? PUA */ /*{ 0xffd0, 0xe2d0 }, ** F19 ? PUA */ /*{ 0xffd1, 0xe2d1 }, ** F20 ? PUA */ /*{ 0xffd2, 0xe2d2 }, ** F21 ? PUA */ /*{ 0xffd3, 0xe2d3 }, ** F22 ? PUA */ /*{ 0xffd4, 0xe2d4 }, ** F23 ? PUA */ /*{ 0xffd5, 0xe2d5 }, ** F24 ? PUA */ /*{ 0xffd6, 0xe2d6 }, ** F25 ? PUA */ /*{ 0xffd7, 0xe2d7 }, ** F26 ? PUA */ /*{ 0xffd8, 0xe2d8 }, ** F27 ? PUA */ /*{ 0xffd9, 0xe2d9 }, ** F28 ? PUA */ /*{ 0xffda, 0xe2da }, ** F29 ? PUA */ /*{ 0xffdb, 0xe2db }, ** F30 ? PUA */ /*{ 0xffdc, 0xe2dc }, ** F31 ? PUA */ /*{ 0xffdd, 0xe2dd }, ** F32 ? PUA */ /*{ 0xffde, 0xe2de }, ** F33 ? PUA */ /*{ 0xffdf, 0xe2df }, ** F34 ? PUA */ /*{ 0xffe0, 0xe2e0 }, ** F35 ? PUA */ /*{ 0xffe1, 0xe2e1 }, ** Shift_L ? PUA Left shift */ /*{ 0xffe2, 0xe2e2 }, ** Shift_R ? PUA Right shift */ /*{ 0xffe3, 0xe2e3 }, ** Control_L ? PUA Left control */ /*{ 0xffe4, 0xe2e4 }, ** Control_R ? PUA Right control */ /*{ 0xffe5, 0xe2e5 }, ** Caps_Lock ? PUA Caps lock */ /*{ 0xffe6, 0xe2e6 }, ** Shift_Lock ? PUA Shift lock */ /*{ 0xffe7, 0xe2e7 }, ** Meta_L ? PUA Left meta */ /*{ 0xffe8, 0xe2e8 }, ** Meta_R ? PUA Right meta */ /*{ 0xffe9, 0xe2e9 }, ** Alt_L ? PUA Left alt */ /*{ 0xffea, 0xe2ea }, ** Alt_R ? PUA Right alt */ /*{ 0xffeb, 0xe2eb }, ** Super_L ? PUA Left super */ /*{ 0xffec, 0xe2ec }, ** Super_R ? PUA Right super */ /*{ 0xffed, 0xe2ed }, ** Hyper_L ? PUA Left hyper */ /*{ 0xffee, 0xe2ee }, ** Hyper_R ? PUA Right hyper */ /*{ 0xfff1, 0xe2f1 }, ** braille_dot_1 ? PUA */ /*{ 0xfff2, 0xe2f2 }, ** braille_dot_2 ? PUA */ /*{ 0xfff3, 0xe2f3 }, ** braille_dot_3 ? PUA */ /*{ 0xfff4, 0xe2f4 }, ** braille_dot_4 ? PUA */ /*{ 0xfff5, 0xe2f5 }, ** braille_dot_5 ? PUA */ /*{ 0xfff6, 0xe2f6 }, ** braille_dot_6 ? PUA */ /*{ 0xfff7, 0xe2f7 }, ** braille_dot_7 ? PUA */ /*{ 0xfff8, 0xe2f8 }, ** braille_dot_8 ? PUA */ /*{ 0xfff9, 0xe2f9 }, ** braille_dot_9 ? PUA */ /*{ 0xfffa, 0xe2fa }, ** braille_dot_10 ? PUA */ { 0xffff, 0x007f }, /* Delete  DELETE */ { 0x100000a8, 0x00a8 }, /* mute_acute ¨ DIAERESIS */ { 0x100000a9, 0x00a9 }, /* mute_grave © COPYRIGHT SIGN */ { 0x100000aa, 0x00aa }, /* mute_asciicircum ª FEMININE ORDINAL INDICATOR */ { 0x100000ab, 0x00ab }, /* mute_diaeresis « LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ { 0x100000ac, 0x00ac }, /* mute_asciitilde ¬ NOT SIGN */ { 0x100000af, 0x00af }, /* lira ¯ MACRON */ { 0x100000be, 0x00be }, /* guilder ¾ VULGAR FRACTION THREE QUARTERS */ { 0x100000ee, 0x00ee }, /* Ydiaeresis î LATIN SMALL LETTER I WITH CIRCUMFLEX */ { 0x100000f6, 0x00f6 }, /* longminus ö LATIN SMALL LETTER O WITH DIAERESIS */ { 0x100000fc, 0x00fc }, /* block ü LATIN SMALL LETTER U WITH DIAERESIS */ /*{ 0x1000fe22, 0xf0e22 }, ** diaeresis ? PUA */ /*{ 0x1000fe27, 0xf0e27 }, ** acute_accent ? PUA */ /*{ 0x1000fe2c, 0xf0e2c }, ** cedilla_accent ? PUA */ /*{ 0x1000fe5e, 0xf0e5e }, ** circumflex_accent ? PUA */ /*{ 0x1000fe60, 0xf0e60 }, ** grave_accent ? PUA */ /*{ 0x1000fe7e, 0xf0e7e }, ** tilde ? PUA */ /*{ 0x1000feb0, 0xf0eb0 }, ** ring_accent ? PUA */ /*{ 0x1000ff00, 0xf0f00 }, ** LineDel ? PUA Remove */ /*{ 0x1000ff01, 0xf0f01 }, ** CharDel ? PUA */ /*{ 0x1000ff02, 0xf0f02 }, ** Copy ? PUA */ /*{ 0x1000ff03, 0xf0f03 }, ** Cut ? PUA */ /*{ 0x1000ff04, 0xf0f04 }, ** Paste ? PUA */ /*{ 0x1000ff05, 0xf0f05 }, ** Move ? PUA */ /*{ 0x1000ff06, 0xf0f06 }, ** Grow ? PUA */ /*{ 0x1000ff07, 0xf0f07 }, ** Cmd ? PUA */ /*{ 0x1000ff08, 0xf0f08 }, ** Shell ? PUA */ /*{ 0x1000ff09, 0xf0f09 }, ** LeftBar ? PUA */ /*{ 0x1000ff0a, 0xf0f0a }, ** RightBar ? PUA */ /*{ 0x1000ff0b, 0xf0f0b }, ** LeftBox ? PUA */ /*{ 0x1000ff0c, 0xf0f0c }, ** RightBox ? PUA */ /*{ 0x1000ff0d, 0xf0f0d }, ** UpBox ? PUA */ /*{ 0x1000ff0e, 0xf0f0e }, ** DownBox ? PUA */ /*{ 0x1000ff0f, 0xf0f0f }, ** Pop ? PUA */ /*{ 0x1000ff10, 0xf0f10 }, ** Read ? PUA */ /*{ 0x1000ff11, 0xf0f11 }, ** Edit ? PUA */ /*{ 0x1000ff12, 0xf0f12 }, ** Save ? PUA */ /*{ 0x1000ff13, 0xf0f13 }, ** Exit ? PUA */ /*{ 0x1000ff14, 0xf0f14 }, ** Repeat ? PUA */ /*{ 0x1000ff48, 0xf0f48 }, ** Modelock1 ? PUA */ /*{ 0x1000ff49, 0xf0f49 }, ** Modelock2 ? PUA */ /*{ 0x1000ff6c, 0xf0f6c }, ** Reset ? PUA */ /*{ 0x1000ff6d, 0xf0f6d }, ** System ? PUA */ /*{ 0x1000ff6e, 0xf0f6e }, ** User ? PUA */ /*{ 0x1000ff6f, 0xf0f6f }, ** ClearLine ? PUA */ /*{ 0x1000ff70, 0xf0f70 }, ** InsertLine ? PUA */ /*{ 0x1000ff71, 0xf0f71 }, ** DeleteLine ? PUA */ /*{ 0x1000ff72, 0xf0f72 }, ** InsertChar ? PUA */ /*{ 0x1000ff73, 0xf0f73 }, ** DeleteChar ? PUA */ /*{ 0x1000ff74, 0xf0f74 }, ** BackTab ? PUA */ /*{ 0x1000ff75, 0xf0f75 }, ** KP_BackTab ? PUA */ /*{ 0x1000ffa8, 0xf0fa8 }, ** KP_parenleft ? PUA */ /*{ 0x1000ffa9, 0xf0fa9 }, ** KP_parenright ? PUA */ /*{ 0x1004ff02, 0xf1f02 }, ** Copy ? PUA */ /*{ 0x1004ff03, 0xf1f03 }, ** Cut ? PUA */ /*{ 0x1004ff04, 0xf1f04 }, ** Paste ? PUA */ /*{ 0x1004ff07, 0xf1f07 }, ** BackTab ? PUA */ /*{ 0x1004ff08, 0xf1f08 }, ** BackSpace ? PUA */ /*{ 0x1004ff0b, 0xf1f0b }, ** Clear ? PUA */ /*{ 0x1004ff1b, 0xf1f1b }, ** Escape ? PUA */ /*{ 0x1004ff31, 0xf1f31 }, ** AddMode ? PUA */ /*{ 0x1004ff32, 0xf1f32 }, ** PrimaryPaste ? PUA */ /*{ 0x1004ff33, 0xf1f33 }, ** QuickPaste ? PUA */ /*{ 0x1004ff40, 0xf1f40 }, ** PageLeft ? PUA */ /*{ 0x1004ff41, 0xf1f41 }, ** PageUp ? PUA */ /*{ 0x1004ff42, 0xf1f42 }, ** PageDown ? PUA */ /*{ 0x1004ff43, 0xf1f43 }, ** PageRight ? PUA */ /*{ 0x1004ff44, 0xf1f44 }, ** Activate ? PUA */ /*{ 0x1004ff45, 0xf1f45 }, ** MenuBar ? PUA */ /*{ 0x1004ff51, 0xf1f51 }, ** Left ? PUA */ /*{ 0x1004ff52, 0xf1f52 }, ** Up ? PUA */ /*{ 0x1004ff53, 0xf1f53 }, ** Right ? PUA */ /*{ 0x1004ff54, 0xf1f54 }, ** Down ? PUA */ /*{ 0x1004ff57, 0xf1f57 }, ** EndLine ? PUA */ /*{ 0x1004ff58, 0xf1f58 }, ** BeginLine ? PUA */ /*{ 0x1004ff59, 0xf1f59 }, ** EndData ? PUA */ /*{ 0x1004ff5a, 0xf1f5a }, ** BeginData ? PUA */ /*{ 0x1004ff5b, 0xf1f5b }, ** PrevMenu ? PUA */ /*{ 0x1004ff5c, 0xf1f5c }, ** NextMenu ? PUA */ /*{ 0x1004ff5d, 0xf1f5d }, ** PrevField ? PUA */ /*{ 0x1004ff5e, 0xf1f5e }, ** NextField ? PUA */ /*{ 0x1004ff60, 0xf1f60 }, ** Select ? PUA */ /*{ 0x1004ff63, 0xf1f63 }, ** Insert ? PUA */ /*{ 0x1004ff65, 0xf1f65 }, ** Undo ? PUA */ /*{ 0x1004ff67, 0xf1f67 }, ** Menu ? PUA */ /*{ 0x1004ff69, 0xf1f69 }, ** Cancel ? PUA */ /*{ 0x1004ff6a, 0xf1f6a }, ** Help ? PUA */ /*{ 0x1004ff71, 0xf1f71 }, ** SelectAll ? PUA */ /*{ 0x1004ff72, 0xf1f72 }, ** DeselectAll ? PUA */ /*{ 0x1004ff73, 0xf1f73 }, ** Reselect ? PUA */ /*{ 0x1004ff74, 0xf1f74 }, ** Extend ? PUA */ /*{ 0x1004ff78, 0xf1f78 }, ** Restore ? PUA */ /*{ 0x1004ffff, 0xf1fff }, ** Delete ? PUA */ /*{ 0x1005ff00, 0xf2f00 }, ** FA_Grave ? PUA */ /*{ 0x1005ff01, 0xf2f01 }, ** FA_Circum ? PUA */ /*{ 0x1005ff02, 0xf2f02 }, ** FA_Tilde ? PUA */ /*{ 0x1005ff03, 0xf2f03 }, ** FA_Acute ? PUA */ /*{ 0x1005ff04, 0xf2f04 }, ** FA_Diaeresis ? PUA */ /*{ 0x1005ff05, 0xf2f05 }, ** FA_Cedilla ? PUA */ /*{ 0x1005ff10, 0xf2f10 }, ** F36 ? PUA Labeled F11 */ /*{ 0x1005ff11, 0xf2f11 }, ** F37 ? PUA Labeled F12 */ /*{ 0x1005ff60, 0xf2f60 }, ** Sys_Req ? PUA */ /*{ 0x1005ff70, 0xf2f70 }, ** Props ? PUA */ /*{ 0x1005ff71, 0xf2f71 }, ** Front ? PUA */ /*{ 0x1005ff72, 0xf2f72 }, ** Copy ? PUA */ /*{ 0x1005ff73, 0xf2f73 }, ** Open ? PUA */ /*{ 0x1005ff74, 0xf2f74 }, ** Paste ? PUA */ /*{ 0x1005ff75, 0xf2f75 }, ** Cut ? PUA */ /*{ 0x1005ff76, 0xf2f76 }, ** PowerSwitch ? PUA */ /*{ 0x1005ff77, 0xf2f77 }, ** AudioLowerVolume ? PUA */ /*{ 0x1005ff78, 0xf2f78 }, ** AudioMute ? PUA */ /*{ 0x1005ff79, 0xf2f79 }, ** AudioRaiseVolume ? PUA */ /*{ 0x1005ff7a, 0xf2f7a }, ** VideoDegauss ? PUA */ /*{ 0x1005ff7b, 0xf2f7b }, ** VideoLowerBrightness ? PUA */ /*{ 0x1005ff7c, 0xf2f7c }, ** VideoRaiseBrightness ? PUA */ /*{ 0x1005ff7d, 0xf2f7d }, ** PowerSwitchShift ? PUA */ /*{ 0x100810f4, 0xf40f4 }, ** BrightnessAuto ? PUA v3.16 KEY_BRIGHTNESS_AUTO */ /*{ 0x100810f5, 0xf40f5 }, ** DisplayOff ? PUA v2.6.23 KEY_DISPLAY_OFF */ /*{ 0x10081166, 0xf4166 }, ** Info ? PUA KEY_INFO */ /*{ 0x10081177, 0xf4177 }, ** AspectRatio ? PUA v5.1 KEY_ASPECT_RATIO */ /*{ 0x10081185, 0xf4185 }, ** DVD ? PUA KEY_DVD */ /*{ 0x10081188, 0xf4188 }, ** Audio ? PUA KEY_AUDIO */ /*{ 0x10081192, 0xf4192 }, ** ChannelUp ? PUA KEY_CHANNELUP */ /*{ 0x10081193, 0xf4193 }, ** ChannelDown ? PUA KEY_CHANNELDOWN */ /*{ 0x1008119b, 0xf419b }, ** Break ? PUA KEY_BREAK */ /*{ 0x100811a0, 0xf41a0 }, ** VideoPhone ? PUA v2.6.20 KEY_VIDEOPHONE */ /*{ 0x100811a4, 0xf41a4 }, ** ZoomReset ? PUA v2.6.20 KEY_ZOOMRESET */ /*{ 0x100811a6, 0xf41a6 }, ** Editor ? PUA v2.6.20 KEY_EDITOR */ /*{ 0x100811a8, 0xf41a8 }, ** GraphicsEditor ? PUA v2.6.20 KEY_GRAPHICSEDITOR */ /*{ 0x100811a9, 0xf41a9 }, ** Presentation ? PUA v2.6.20 KEY_PRESENTATION */ /*{ 0x100811aa, 0xf41aa }, ** Database ? PUA v2.6.20 KEY_DATABASE */ /*{ 0x100811ac, 0xf41ac }, ** Voicemail ? PUA v2.6.20 KEY_VOICEMAIL */ /*{ 0x100811ad, 0xf41ad }, ** Addressbook ? PUA v2.6.20 KEY_ADDRESSBOOK */ /*{ 0x100811af, 0xf41af }, ** DisplayToggle ? PUA v2.6.20 KEY_DISPLAYTOGGLE */ /*{ 0x100811b0, 0xf41b0 }, ** SpellCheck ? PUA v2.6.24 KEY_SPELLCHECK */ /*{ 0x100811b6, 0xf41b6 }, ** ContextMenu ? PUA v2.6.24 KEY_CONTEXT_MENU */ /*{ 0x100811b7, 0xf41b7 }, ** MediaRepeat ? PUA v2.6.26 KEY_MEDIA_REPEAT */ /*{ 0x100811b8, 0xf41b8 }, ** 10ChannelsUp ? PUA v2.6.38 KEY_10CHANNELSUP */ /*{ 0x100811b9, 0xf41b9 }, ** 10ChannelsDown ? PUA v2.6.38 KEY_10CHANNELSDOWN */ /*{ 0x100811ba, 0xf41ba }, ** Images ? PUA v2.6.39 KEY_IMAGES */ /*{ 0x100811bc, 0xf41bc }, ** NotificationCenter ? PUA v5.10 KEY_NOTIFICATION_CENTER */ /*{ 0x100811bd, 0xf41bd }, ** PickupPhone ? PUA v5.10 KEY_PICKUP_PHONE */ /*{ 0x100811be, 0xf41be }, ** HangupPhone ? PUA v5.10 KEY_HANGUP_PHONE */ /*{ 0x100811d0, 0xf41d0 }, ** Fn ? PUA KEY_FN */ /*{ 0x100811d1, 0xf41d1 }, ** Fn_Esc ? PUA KEY_FN_ESC */ /*{ 0x100811e5, 0xf41e5 }, ** FnRightShift ? PUA v5.10 KEY_FN_RIGHT_SHIFT */ /*{ 0x10081200, 0xf4200 }, ** Numeric0 ? PUA v2.6.28 KEY_NUMERIC_0 */ /*{ 0x10081201, 0xf4201 }, ** Numeric1 ? PUA v2.6.28 KEY_NUMERIC_1 */ /*{ 0x10081202, 0xf4202 }, ** Numeric2 ? PUA v2.6.28 KEY_NUMERIC_2 */ /*{ 0x10081203, 0xf4203 }, ** Numeric3 ? PUA v2.6.28 KEY_NUMERIC_3 */ /*{ 0x10081204, 0xf4204 }, ** Numeric4 ? PUA v2.6.28 KEY_NUMERIC_4 */ /*{ 0x10081205, 0xf4205 }, ** Numeric5 ? PUA v2.6.28 KEY_NUMERIC_5 */ /*{ 0x10081206, 0xf4206 }, ** Numeric6 ? PUA v2.6.28 KEY_NUMERIC_6 */ /*{ 0x10081207, 0xf4207 }, ** Numeric7 ? PUA v2.6.28 KEY_NUMERIC_7 */ /*{ 0x10081208, 0xf4208 }, ** Numeric8 ? PUA v2.6.28 KEY_NUMERIC_8 */ /*{ 0x10081209, 0xf4209 }, ** Numeric9 ? PUA v2.6.28 KEY_NUMERIC_9 */ /*{ 0x1008120a, 0xf420a }, ** NumericStar ? PUA v2.6.28 KEY_NUMERIC_STAR */ /*{ 0x1008120b, 0xf420b }, ** NumericPound ? PUA v2.6.28 KEY_NUMERIC_POUND */ /*{ 0x1008120c, 0xf420c }, ** NumericA ? PUA v4.1 KEY_NUMERIC_A */ /*{ 0x1008120d, 0xf420d }, ** NumericB ? PUA v4.1 KEY_NUMERIC_B */ /*{ 0x1008120e, 0xf420e }, ** NumericC ? PUA v4.1 KEY_NUMERIC_C */ /*{ 0x1008120f, 0xf420f }, ** NumericD ? PUA v4.1 KEY_NUMERIC_D */ /*{ 0x10081210, 0xf4210 }, ** CameraFocus ? PUA v2.6.33 KEY_CAMERA_FOCUS */ /*{ 0x10081211, 0xf4211 }, ** WPSButton ? PUA v2.6.34 KEY_WPS_BUTTON */ /*{ 0x10081215, 0xf4215 }, ** CameraZoomIn ? PUA v2.6.39 KEY_CAMERA_ZOOMIN */ /*{ 0x10081216, 0xf4216 }, ** CameraZoomOut ? PUA v2.6.39 KEY_CAMERA_ZOOMOUT */ /*{ 0x10081217, 0xf4217 }, ** CameraUp ? PUA v2.6.39 KEY_CAMERA_UP */ /*{ 0x10081218, 0xf4218 }, ** CameraDown ? PUA v2.6.39 KEY_CAMERA_DOWN */ /*{ 0x10081219, 0xf4219 }, ** CameraLeft ? PUA v2.6.39 KEY_CAMERA_LEFT */ /*{ 0x1008121a, 0xf421a }, ** CameraRight ? PUA v2.6.39 KEY_CAMERA_RIGHT */ /*{ 0x1008121b, 0xf421b }, ** AttendantOn ? PUA v3.10 KEY_ATTENDANT_ON */ /*{ 0x1008121c, 0xf421c }, ** AttendantOff ? PUA v3.10 KEY_ATTENDANT_OFF */ /*{ 0x1008121d, 0xf421d }, ** AttendantToggle ? PUA v3.10 KEY_ATTENDANT_TOGGLE */ /*{ 0x1008121e, 0xf421e }, ** LightsToggle ? PUA v3.10 KEY_LIGHTS_TOGGLE */ /*{ 0x10081230, 0xf4230 }, ** ALSToggle ? PUA v3.13 KEY_ALS_TOGGLE */ /*{ 0x10081240, 0xf4240 }, ** Buttonconfig ? PUA v3.16 KEY_BUTTONCONFIG */ /*{ 0x10081241, 0xf4241 }, ** Taskmanager ? PUA v3.16 KEY_TASKMANAGER */ /*{ 0x10081242, 0xf4242 }, ** Journal ? PUA v3.16 KEY_JOURNAL */ /*{ 0x10081243, 0xf4243 }, ** ControlPanel ? PUA v3.16 KEY_CONTROLPANEL */ /*{ 0x10081244, 0xf4244 }, ** AppSelect ? PUA v3.16 KEY_APPSELECT */ /*{ 0x10081245, 0xf4245 }, ** Screensaver ? PUA v3.16 KEY_SCREENSAVER */ /*{ 0x10081246, 0xf4246 }, ** VoiceCommand ? PUA v3.16 KEY_VOICECOMMAND */ /*{ 0x10081247, 0xf4247 }, ** Assistant ? PUA v4.13 KEY_ASSISTANT */ /*{ 0x10081249, 0xf4249 }, ** EmojiPicker ? PUA v5.13 KEY_EMOJI_PICKER */ /*{ 0x1008124a, 0xf424a }, ** Dictate ? PUA v5.17 KEY_DICTATE */ /*{ 0x1008124b, 0xf424b }, ** CameraAccessEnable ? PUA v6.2 KEY_CAMERA_ACCESS_ENABLE */ /*{ 0x1008124c, 0xf424c }, ** CameraAccessDisable ? PUA v6.2 KEY_CAMERA_ACCESS_DISABLE */ /*{ 0x1008124d, 0xf424d }, ** CameraAccessToggle ? PUA v6.2 KEY_CAMERA_ACCESS_TOGGLE */ /*{ 0x10081250, 0xf4250 }, ** BrightnessMin ? PUA v3.16 KEY_BRIGHTNESS_MIN */ /*{ 0x10081251, 0xf4251 }, ** BrightnessMax ? PUA v3.16 KEY_BRIGHTNESS_MAX */ /*{ 0x10081260, 0xf4260 }, ** KbdInputAssistPrev ? PUA v3.18 KEY_KBDINPUTASSIST_PREV */ /*{ 0x10081261, 0xf4261 }, ** KbdInputAssistNext ? PUA v3.18 KEY_KBDINPUTASSIST_NEXT */ /*{ 0x10081262, 0xf4262 }, ** KbdInputAssistPrevgroup ? PUA v3.18 KEY_KBDINPUTASSIST_PREVGROUP */ /*{ 0x10081263, 0xf4263 }, ** KbdInputAssistNextgroup ? PUA v3.18 KEY_KBDINPUTASSIST_NEXTGROUP */ /*{ 0x10081264, 0xf4264 }, ** KbdInputAssistAccept ? PUA v3.18 KEY_KBDINPUTASSIST_ACCEPT */ /*{ 0x10081265, 0xf4265 }, ** KbdInputAssistCancel ? PUA v3.18 KEY_KBDINPUTASSIST_CANCEL */ /*{ 0x10081266, 0xf4266 }, ** RightUp ? PUA v4.7 KEY_RIGHT_UP */ /*{ 0x10081267, 0xf4267 }, ** RightDown ? PUA v4.7 KEY_RIGHT_DOWN */ /*{ 0x10081268, 0xf4268 }, ** LeftUp ? PUA v4.7 KEY_LEFT_UP */ /*{ 0x10081269, 0xf4269 }, ** LeftDown ? PUA v4.7 KEY_LEFT_DOWN */ /*{ 0x1008126a, 0xf426a }, ** RootMenu ? PUA v4.7 KEY_ROOT_MENU */ /*{ 0x1008126b, 0xf426b }, ** MediaTopMenu ? PUA v4.7 KEY_MEDIA_TOP_MENU */ /*{ 0x1008126c, 0xf426c }, ** Numeric11 ? PUA v4.7 KEY_NUMERIC_11 */ /*{ 0x1008126d, 0xf426d }, ** Numeric12 ? PUA v4.7 KEY_NUMERIC_12 */ /*{ 0x1008126e, 0xf426e }, ** AudioDesc ? PUA v4.7 KEY_AUDIO_DESC */ /*{ 0x1008126f, 0xf426f }, ** 3DMode ? PUA v4.7 KEY_3D_MODE */ /*{ 0x10081270, 0xf4270 }, ** NextFavorite ? PUA v4.7 KEY_NEXT_FAVORITE */ /*{ 0x10081271, 0xf4271 }, ** StopRecord ? PUA v4.7 KEY_STOP_RECORD */ /*{ 0x10081272, 0xf4272 }, ** PauseRecord ? PUA v4.7 KEY_PAUSE_RECORD */ /*{ 0x10081273, 0xf4273 }, ** VOD ? PUA v4.7 KEY_VOD */ /*{ 0x10081274, 0xf4274 }, ** Unmute ? PUA v4.7 KEY_UNMUTE */ /*{ 0x10081275, 0xf4275 }, ** FastReverse ? PUA v4.7 KEY_FASTREVERSE */ /*{ 0x10081276, 0xf4276 }, ** SlowReverse ? PUA v4.7 KEY_SLOWREVERSE */ /*{ 0x10081277, 0xf4277 }, ** Data ? PUA v4.7 KEY_DATA */ /*{ 0x10081278, 0xf4278 }, ** OnScreenKeyboard ? PUA v4.12 KEY_ONSCREEN_KEYBOARD */ /*{ 0x10081279, 0xf4279 }, ** PrivacyScreenToggle ? PUA v5.5 KEY_PRIVACY_SCREEN_TOGGLE */ /*{ 0x1008127a, 0xf427a }, ** SelectiveScreenshot ? PUA v5.6 KEY_SELECTIVE_SCREENSHOT */ /*{ 0x1008127b, 0xf427b }, ** NextElement ? PUA v5.18 KEY_NEXT_ELEMENT */ /*{ 0x1008127c, 0xf427c }, ** PreviousElement ? PUA v5.18 KEY_PREVIOUS_ELEMENT */ /*{ 0x1008127d, 0xf427d }, ** AutopilotEngageToggle ? PUA v5.18 KEY_AUTOPILOT_ENGAGE_TOGGLE */ /*{ 0x1008127e, 0xf427e }, ** MarkWaypoint ? PUA v5.18 KEY_MARK_WAYPOINT */ /*{ 0x1008127f, 0xf427f }, ** Sos ? PUA v5.18 KEY_SOS */ /*{ 0x10081280, 0xf4280 }, ** NavChart ? PUA v5.18 KEY_NAV_CHART */ /*{ 0x10081281, 0xf4281 }, ** FishingChart ? PUA v5.18 KEY_FISHING_CHART */ /*{ 0x10081282, 0xf4282 }, ** SingleRangeRadar ? PUA v5.18 KEY_SINGLE_RANGE_RADAR */ /*{ 0x10081283, 0xf4283 }, ** DualRangeRadar ? PUA v5.18 KEY_DUAL_RANGE_RADAR */ /*{ 0x10081284, 0xf4284 }, ** RadarOverlay ? PUA v5.18 KEY_RADAR_OVERLAY */ /*{ 0x10081285, 0xf4285 }, ** TraditionalSonar ? PUA v5.18 KEY_TRADITIONAL_SONAR */ /*{ 0x10081286, 0xf4286 }, ** ClearvuSonar ? PUA v5.18 KEY_CLEARVU_SONAR */ /*{ 0x10081287, 0xf4287 }, ** SidevuSonar ? PUA v5.18 KEY_SIDEVU_SONAR */ /*{ 0x10081288, 0xf4288 }, ** NavInfo ? PUA v5.18 KEY_NAV_INFO */ /*{ 0x10081290, 0xf4290 }, ** Macro1 ? PUA v5.5 KEY_MACRO1 */ /*{ 0x10081291, 0xf4291 }, ** Macro2 ? PUA v5.5 KEY_MACRO2 */ /*{ 0x10081292, 0xf4292 }, ** Macro3 ? PUA v5.5 KEY_MACRO3 */ /*{ 0x10081293, 0xf4293 }, ** Macro4 ? PUA v5.5 KEY_MACRO4 */ /*{ 0x10081294, 0xf4294 }, ** Macro5 ? PUA v5.5 KEY_MACRO5 */ /*{ 0x10081295, 0xf4295 }, ** Macro6 ? PUA v5.5 KEY_MACRO6 */ /*{ 0x10081296, 0xf4296 }, ** Macro7 ? PUA v5.5 KEY_MACRO7 */ /*{ 0x10081297, 0xf4297 }, ** Macro8 ? PUA v5.5 KEY_MACRO8 */ /*{ 0x10081298, 0xf4298 }, ** Macro9 ? PUA v5.5 KEY_MACRO9 */ /*{ 0x10081299, 0xf4299 }, ** Macro10 ? PUA v5.5 KEY_MACRO10 */ /*{ 0x1008129a, 0xf429a }, ** Macro11 ? PUA v5.5 KEY_MACRO11 */ /*{ 0x1008129b, 0xf429b }, ** Macro12 ? PUA v5.5 KEY_MACRO12 */ /*{ 0x1008129c, 0xf429c }, ** Macro13 ? PUA v5.5 KEY_MACRO13 */ /*{ 0x1008129d, 0xf429d }, ** Macro14 ? PUA v5.5 KEY_MACRO14 */ /*{ 0x1008129e, 0xf429e }, ** Macro15 ? PUA v5.5 KEY_MACRO15 */ /*{ 0x1008129f, 0xf429f }, ** Macro16 ? PUA v5.5 KEY_MACRO16 */ /*{ 0x100812a0, 0xf42a0 }, ** Macro17 ? PUA v5.5 KEY_MACRO17 */ /*{ 0x100812a1, 0xf42a1 }, ** Macro18 ? PUA v5.5 KEY_MACRO18 */ /*{ 0x100812a2, 0xf42a2 }, ** Macro19 ? PUA v5.5 KEY_MACRO19 */ /*{ 0x100812a3, 0xf42a3 }, ** Macro20 ? PUA v5.5 KEY_MACRO20 */ /*{ 0x100812a4, 0xf42a4 }, ** Macro21 ? PUA v5.5 KEY_MACRO21 */ /*{ 0x100812a5, 0xf42a5 }, ** Macro22 ? PUA v5.5 KEY_MACRO22 */ /*{ 0x100812a6, 0xf42a6 }, ** Macro23 ? PUA v5.5 KEY_MACRO23 */ /*{ 0x100812a7, 0xf42a7 }, ** Macro24 ? PUA v5.5 KEY_MACRO24 */ /*{ 0x100812a8, 0xf42a8 }, ** Macro25 ? PUA v5.5 KEY_MACRO25 */ /*{ 0x100812a9, 0xf42a9 }, ** Macro26 ? PUA v5.5 KEY_MACRO26 */ /*{ 0x100812aa, 0xf42aa }, ** Macro27 ? PUA v5.5 KEY_MACRO27 */ /*{ 0x100812ab, 0xf42ab }, ** Macro28 ? PUA v5.5 KEY_MACRO28 */ /*{ 0x100812ac, 0xf42ac }, ** Macro29 ? PUA v5.5 KEY_MACRO29 */ /*{ 0x100812ad, 0xf42ad }, ** Macro30 ? PUA v5.5 KEY_MACRO30 */ /*{ 0x100812b0, 0xf42b0 }, ** MacroRecordStart ? PUA v5.5 KEY_MACRO_RECORD_START */ /*{ 0x100812b1, 0xf42b1 }, ** MacroRecordStop ? PUA v5.5 KEY_MACRO_RECORD_STOP */ /*{ 0x100812b2, 0xf42b2 }, ** MacroPresetCycle ? PUA v5.5 KEY_MACRO_PRESET_CYCLE */ /*{ 0x100812b3, 0xf42b3 }, ** MacroPreset1 ? PUA v5.5 KEY_MACRO_PRESET1 */ /*{ 0x100812b4, 0xf42b4 }, ** MacroPreset2 ? PUA v5.5 KEY_MACRO_PRESET2 */ /*{ 0x100812b5, 0xf42b5 }, ** MacroPreset3 ? PUA v5.5 KEY_MACRO_PRESET3 */ /*{ 0x100812b8, 0xf42b8 }, ** KbdLcdMenu1 ? PUA v5.5 KEY_KBD_LCD_MENU1 */ /*{ 0x100812b9, 0xf42b9 }, ** KbdLcdMenu2 ? PUA v5.5 KEY_KBD_LCD_MENU2 */ /*{ 0x100812ba, 0xf42ba }, ** KbdLcdMenu3 ? PUA v5.5 KEY_KBD_LCD_MENU3 */ /*{ 0x100812bb, 0xf42bb }, ** KbdLcdMenu4 ? PUA v5.5 KEY_KBD_LCD_MENU4 */ /*{ 0x100812bc, 0xf42bc }, ** KbdLcdMenu5 ? PUA v5.5 KEY_KBD_LCD_MENU5 */ /*{ 0x1008fe01, 0xf6001 }, ** Switch_VT_1 ? PUA */ /*{ 0x1008fe02, 0xf6002 }, ** Switch_VT_2 ? PUA */ /*{ 0x1008fe03, 0xf6003 }, ** Switch_VT_3 ? PUA */ /*{ 0x1008fe04, 0xf6004 }, ** Switch_VT_4 ? PUA */ /*{ 0x1008fe05, 0xf6005 }, ** Switch_VT_5 ? PUA */ /*{ 0x1008fe06, 0xf6006 }, ** Switch_VT_6 ? PUA */ /*{ 0x1008fe07, 0xf6007 }, ** Switch_VT_7 ? PUA */ /*{ 0x1008fe08, 0xf6008 }, ** Switch_VT_8 ? PUA */ /*{ 0x1008fe09, 0xf6009 }, ** Switch_VT_9 ? PUA */ /*{ 0x1008fe0a, 0xf600a }, ** Switch_VT_10 ? PUA */ /*{ 0x1008fe0b, 0xf600b }, ** Switch_VT_11 ? PUA */ /*{ 0x1008fe0c, 0xf600c }, ** Switch_VT_12 ? PUA */ /*{ 0x1008fe20, 0xf6020 }, ** Ungrab ? PUA force ungrab */ /*{ 0x1008fe21, 0xf6021 }, ** ClearGrab ? PUA kill application with grab */ /*{ 0x1008fe22, 0xf6022 }, ** Next_VMode ? PUA next video mode available */ /*{ 0x1008fe23, 0xf6023 }, ** Prev_VMode ? PUA prev. video mode available */ /*{ 0x1008fe24, 0xf6024 }, ** LogWindowTree ? PUA print window tree to log */ /*{ 0x1008fe25, 0xf6025 }, ** LogGrabInfo ? PUA print all active grabs to log */ /*{ 0x1008ff01, 0xf6101 }, ** ModeLock ? PUA Mode Switch Lock */ /*{ 0x1008ff02, 0xf6102 }, ** MonBrightnessUp ? PUA Monitor/panel brightness */ /*{ 0x1008ff03, 0xf6103 }, ** MonBrightnessDown ? PUA Monitor/panel brightness */ /*{ 0x1008ff04, 0xf6104 }, ** KbdLightOnOff ? PUA Keyboards may be lit */ /*{ 0x1008ff05, 0xf6105 }, ** KbdBrightnessUp ? PUA Keyboards may be lit */ /*{ 0x1008ff06, 0xf6106 }, ** KbdBrightnessDown ? PUA Keyboards may be lit */ /*{ 0x1008ff07, 0xf6107 }, ** MonBrightnessCycle ? PUA Monitor/panel brightness */ /*{ 0x1008ff10, 0xf6110 }, ** Standby ? PUA System into standby mode */ /*{ 0x1008ff11, 0xf6111 }, ** AudioLowerVolume ? PUA Volume control down */ /*{ 0x1008ff12, 0xf6112 }, ** AudioMute ? PUA Mute sound from the system */ /*{ 0x1008ff13, 0xf6113 }, ** AudioRaiseVolume ? PUA Volume control up */ /*{ 0x1008ff14, 0xf6114 }, ** AudioPlay ? PUA Start playing of audio > */ /*{ 0x1008ff15, 0xf6115 }, ** AudioStop ? PUA Stop playing audio */ /*{ 0x1008ff16, 0xf6116 }, ** AudioPrev ? PUA Previous track */ /*{ 0x1008ff17, 0xf6117 }, ** AudioNext ? PUA Next track */ /*{ 0x1008ff18, 0xf6118 }, ** HomePage ? PUA Display user's home page */ /*{ 0x1008ff19, 0xf6119 }, ** Mail ? PUA Invoke user's mail program */ /*{ 0x1008ff1a, 0xf611a }, ** Start ? PUA Start application */ /*{ 0x1008ff1b, 0xf611b }, ** Search ? PUA Search */ /*{ 0x1008ff1c, 0xf611c }, ** AudioRecord ? PUA Record audio application */ /*{ 0x1008ff1d, 0xf611d }, ** Calculator ? PUA Invoke calculator program */ /*{ 0x1008ff1e, 0xf611e }, ** Memo ? PUA Invoke Memo taking program */ /*{ 0x1008ff1f, 0xf611f }, ** ToDoList ? PUA Invoke To Do List program */ /*{ 0x1008ff20, 0xf6120 }, ** Calendar ? PUA Invoke Calendar program */ /*{ 0x1008ff21, 0xf6121 }, ** PowerDown ? PUA Deep sleep the system */ /*{ 0x1008ff22, 0xf6122 }, ** ContrastAdjust ? PUA Adjust screen contrast */ /*{ 0x1008ff23, 0xf6123 }, ** RockerUp ? PUA Rocker switches exist up */ /*{ 0x1008ff24, 0xf6124 }, ** RockerDown ? PUA and down */ /*{ 0x1008ff25, 0xf6125 }, ** RockerEnter ? PUA and let you press them */ /*{ 0x1008ff26, 0xf6126 }, ** Back ? PUA Like back on a browser */ /*{ 0x1008ff27, 0xf6127 }, ** Forward ? PUA Like forward on a browser */ /*{ 0x1008ff28, 0xf6128 }, ** Stop ? PUA Stop current operation */ /*{ 0x1008ff29, 0xf6129 }, ** Refresh ? PUA Refresh the page */ /*{ 0x1008ff2a, 0xf612a }, ** PowerOff ? PUA Power off system entirely */ /*{ 0x1008ff2b, 0xf612b }, ** WakeUp ? PUA Wake up system from sleep */ /*{ 0x1008ff2c, 0xf612c }, ** Eject ? PUA Eject device e.g. DVD */ /*{ 0x1008ff2d, 0xf612d }, ** ScreenSaver ? PUA Invoke screensaver */ /*{ 0x1008ff2e, 0xf612e }, ** WWW ? PUA Invoke web browser */ /*{ 0x1008ff2f, 0xf612f }, ** Sleep ? PUA Put system to sleep */ /*{ 0x1008ff30, 0xf6130 }, ** Favorites ? PUA Show favorite locations */ /*{ 0x1008ff31, 0xf6131 }, ** AudioPause ? PUA Pause audio playing */ /*{ 0x1008ff32, 0xf6132 }, ** AudioMedia ? PUA Launch media collection app */ /*{ 0x1008ff33, 0xf6133 }, ** MyComputer ? PUA Display "My Computer" window */ /*{ 0x1008ff34, 0xf6134 }, ** VendorHome ? PUA Display vendor home web site */ /*{ 0x1008ff35, 0xf6135 }, ** LightBulb ? PUA Light bulb keys exist */ /*{ 0x1008ff36, 0xf6136 }, ** Shop ? PUA Display shopping web site */ /*{ 0x1008ff37, 0xf6137 }, ** History ? PUA Show history of web surfing */ /*{ 0x1008ff38, 0xf6138 }, ** OpenURL ? PUA Open selected URL */ /*{ 0x1008ff39, 0xf6139 }, ** AddFavorite ? PUA Add URL to favorites list */ /*{ 0x1008ff3a, 0xf613a }, ** HotLinks ? PUA Show "hot" links */ /*{ 0x1008ff3b, 0xf613b }, ** BrightnessAdjust ? PUA Invoke brightness adj. UI */ /*{ 0x1008ff3c, 0xf613c }, ** Finance ? PUA Display financial site */ /*{ 0x1008ff3d, 0xf613d }, ** Community ? PUA Display user's community */ /*{ 0x1008ff3e, 0xf613e }, ** AudioRewind ? PUA "rewind" audio track */ /*{ 0x1008ff3f, 0xf613f }, ** BackForward ? PUA ??? */ /*{ 0x1008ff40, 0xf6140 }, ** Launch0 ? PUA Launch Application */ /*{ 0x1008ff41, 0xf6141 }, ** Launch1 ? PUA Launch Application */ /*{ 0x1008ff42, 0xf6142 }, ** Launch2 ? PUA Launch Application */ /*{ 0x1008ff43, 0xf6143 }, ** Launch3 ? PUA Launch Application */ /*{ 0x1008ff44, 0xf6144 }, ** Launch4 ? PUA Launch Application */ /*{ 0x1008ff45, 0xf6145 }, ** Launch5 ? PUA Launch Application */ /*{ 0x1008ff46, 0xf6146 }, ** Launch6 ? PUA Launch Application */ /*{ 0x1008ff47, 0xf6147 }, ** Launch7 ? PUA Launch Application */ /*{ 0x1008ff48, 0xf6148 }, ** Launch8 ? PUA Launch Application */ /*{ 0x1008ff49, 0xf6149 }, ** Launch9 ? PUA Launch Application */ /*{ 0x1008ff4a, 0xf614a }, ** LaunchA ? PUA Launch Application */ /*{ 0x1008ff4b, 0xf614b }, ** LaunchB ? PUA Launch Application */ /*{ 0x1008ff4c, 0xf614c }, ** LaunchC ? PUA Launch Application */ /*{ 0x1008ff4d, 0xf614d }, ** LaunchD ? PUA Launch Application */ /*{ 0x1008ff4e, 0xf614e }, ** LaunchE ? PUA Launch Application */ /*{ 0x1008ff4f, 0xf614f }, ** LaunchF ? PUA Launch Application */ /*{ 0x1008ff50, 0xf6150 }, ** ApplicationLeft ? PUA switch to application, left */ /*{ 0x1008ff51, 0xf6151 }, ** ApplicationRight ? PUA switch to application, right */ /*{ 0x1008ff52, 0xf6152 }, ** Book ? PUA Launch bookreader */ /*{ 0x1008ff53, 0xf6153 }, ** CD ? PUA Launch CD/DVD player */ /*{ 0x1008ff54, 0xf6154 }, ** Calculater ? PUA Launch Calculater */ /*{ 0x1008ff55, 0xf6155 }, ** Clear ? PUA Clear window, screen */ /*{ 0x1008ff56, 0xf6156 }, ** Close ? PUA Close window */ /*{ 0x1008ff57, 0xf6157 }, ** Copy ? PUA Copy selection */ /*{ 0x1008ff58, 0xf6158 }, ** Cut ? PUA Cut selection */ /*{ 0x1008ff59, 0xf6159 }, ** Display ? PUA Output switch key */ /*{ 0x1008ff5a, 0xf615a }, ** DOS ? PUA Launch DOS emulation */ /*{ 0x1008ff5b, 0xf615b }, ** Documents ? PUA Open documents window */ /*{ 0x1008ff5c, 0xf615c }, ** Excel ? PUA Launch spread sheet */ /*{ 0x1008ff5d, 0xf615d }, ** Explorer ? PUA Launch file explorer */ /*{ 0x1008ff5e, 0xf615e }, ** Game ? PUA Launch game */ /*{ 0x1008ff5f, 0xf615f }, ** Go ? PUA Go to URL */ /*{ 0x1008ff60, 0xf6160 }, ** iTouch ? PUA Logitech iTouch- don't use */ /*{ 0x1008ff61, 0xf6161 }, ** LogOff ? PUA Log off system */ /*{ 0x1008ff62, 0xf6162 }, ** Market ? PUA ?? */ /*{ 0x1008ff63, 0xf6163 }, ** Meeting ? PUA enter meeting in calendar */ /*{ 0x1008ff65, 0xf6165 }, ** MenuKB ? PUA distinguish keyboard from PB */ /*{ 0x1008ff66, 0xf6166 }, ** MenuPB ? PUA distinguish PB from keyboard */ /*{ 0x1008ff67, 0xf6167 }, ** MySites ? PUA Favourites */ /*{ 0x1008ff68, 0xf6168 }, ** New ? PUA New (folder, document... */ /*{ 0x1008ff69, 0xf6169 }, ** News ? PUA News */ /*{ 0x1008ff6a, 0xf616a }, ** OfficeHome ? PUA Office home old Staroffice */ /*{ 0x1008ff6b, 0xf616b }, ** Open ? PUA Open */ /*{ 0x1008ff6c, 0xf616c }, ** Option ? PUA ?? */ /*{ 0x1008ff6d, 0xf616d }, ** Paste ? PUA Paste */ /*{ 0x1008ff6e, 0xf616e }, ** Phone ? PUA Launch phone; dial number */ /*{ 0x1008ff70, 0xf6170 }, ** Q ? PUA Compaq's Q - don't use */ /*{ 0x1008ff72, 0xf6172 }, ** Reply ? PUA Reply e.g., mail */ /*{ 0x1008ff73, 0xf6173 }, ** Reload ? PUA Reload web page, file, etc. */ /*{ 0x1008ff74, 0xf6174 }, ** RotateWindows ? PUA Rotate windows e.g. xrandr */ /*{ 0x1008ff75, 0xf6175 }, ** RotationPB ? PUA don't use */ /*{ 0x1008ff76, 0xf6176 }, ** RotationKB ? PUA don't use */ /*{ 0x1008ff77, 0xf6177 }, ** Save ? PUA Save (file, document, state */ /*{ 0x1008ff78, 0xf6178 }, ** ScrollUp ? PUA Scroll window/contents up */ /*{ 0x1008ff79, 0xf6179 }, ** ScrollDown ? PUA Scrool window/contentd down */ /*{ 0x1008ff7a, 0xf617a }, ** ScrollClick ? PUA Use XKB mousekeys instead */ /*{ 0x1008ff7b, 0xf617b }, ** Send ? PUA Send mail, file, object */ /*{ 0x1008ff7c, 0xf617c }, ** Spell ? PUA Spell checker */ /*{ 0x1008ff7d, 0xf617d }, ** SplitScreen ? PUA Split window or screen */ /*{ 0x1008ff7e, 0xf617e }, ** Support ? PUA Get support ?? */ /*{ 0x1008ff7f, 0xf617f }, ** TaskPane ? PUA Show tasks */ /*{ 0x1008ff80, 0xf6180 }, ** Terminal ? PUA Launch terminal emulator */ /*{ 0x1008ff81, 0xf6181 }, ** Tools ? PUA toolbox of desktop/app. */ /*{ 0x1008ff82, 0xf6182 }, ** Travel ? PUA ?? */ /*{ 0x1008ff84, 0xf6184 }, ** UserPB ? PUA ?? */ /*{ 0x1008ff85, 0xf6185 }, ** User1KB ? PUA ?? */ /*{ 0x1008ff86, 0xf6186 }, ** User2KB ? PUA ?? */ /*{ 0x1008ff87, 0xf6187 }, ** Video ? PUA Launch video player */ /*{ 0x1008ff88, 0xf6188 }, ** WheelButton ? PUA button from a mouse wheel */ /*{ 0x1008ff89, 0xf6189 }, ** Word ? PUA Launch word processor */ /*{ 0x1008ff8a, 0xf618a }, ** Xfer ? PUA */ /*{ 0x1008ff8b, 0xf618b }, ** ZoomIn ? PUA zoom in view, map, etc. */ /*{ 0x1008ff8c, 0xf618c }, ** ZoomOut ? PUA zoom out view, map, etc. */ /*{ 0x1008ff8d, 0xf618d }, ** Away ? PUA mark yourself as away */ /*{ 0x1008ff8e, 0xf618e }, ** Messenger ? PUA as in instant messaging */ /*{ 0x1008ff8f, 0xf618f }, ** WebCam ? PUA Launch web camera app. */ /*{ 0x1008ff90, 0xf6190 }, ** MailForward ? PUA Forward in mail */ /*{ 0x1008ff91, 0xf6191 }, ** Pictures ? PUA Show pictures */ /*{ 0x1008ff92, 0xf6192 }, ** Music ? PUA Launch music application */ /*{ 0x1008ff93, 0xf6193 }, ** Battery ? PUA Display battery information */ /*{ 0x1008ff94, 0xf6194 }, ** Bluetooth ? PUA Enable/disable Bluetooth */ /*{ 0x1008ff95, 0xf6195 }, ** WLAN ? PUA Enable/disable WLAN */ /*{ 0x1008ff96, 0xf6196 }, ** UWB ? PUA Enable/disable UWB */ /*{ 0x1008ff97, 0xf6197 }, ** AudioForward ? PUA fast-forward audio track */ /*{ 0x1008ff98, 0xf6198 }, ** AudioRepeat ? PUA toggle repeat mode */ /*{ 0x1008ff99, 0xf6199 }, ** AudioRandomPlay ? PUA toggle shuffle mode */ /*{ 0x1008ff9a, 0xf619a }, ** Subtitle ? PUA cycle through subtitle */ /*{ 0x1008ff9b, 0xf619b }, ** AudioCycleTrack ? PUA cycle through audio tracks */ /*{ 0x1008ff9c, 0xf619c }, ** CycleAngle ? PUA cycle through angles */ /*{ 0x1008ff9d, 0xf619d }, ** FrameBack ? PUA video: go one frame back */ /*{ 0x1008ff9e, 0xf619e }, ** FrameForward ? PUA video: go one frame forward */ /*{ 0x1008ff9f, 0xf619f }, ** Time ? PUA display, or shows an entry for time seeking */ /*{ 0x1008ffa0, 0xf61a0 }, ** Select ? PUA Select button on joypads and remotes */ /*{ 0x1008ffa1, 0xf61a1 }, ** View ? PUA Show a view options/properties */ /*{ 0x1008ffa2, 0xf61a2 }, ** TopMenu ? PUA Go to a top-level menu in a video */ /*{ 0x1008ffa3, 0xf61a3 }, ** Red ? PUA Red button */ /*{ 0x1008ffa4, 0xf61a4 }, ** Green ? PUA Green button */ /*{ 0x1008ffa5, 0xf61a5 }, ** Yellow ? PUA Yellow button */ /*{ 0x1008ffa6, 0xf61a6 }, ** Blue ? PUA Blue button */ /*{ 0x1008ffa7, 0xf61a7 }, ** Suspend ? PUA Sleep to RAM */ /*{ 0x1008ffa8, 0xf61a8 }, ** Hibernate ? PUA Sleep to disk */ /*{ 0x1008ffa9, 0xf61a9 }, ** TouchpadToggle ? PUA Toggle between touchpad/trackstick */ /*{ 0x1008ffb0, 0xf61b0 }, ** TouchpadOn ? PUA The touchpad got switched on */ /*{ 0x1008ffb1, 0xf61b1 }, ** TouchpadOff ? PUA The touchpad got switched off */ /*{ 0x1008ffb2, 0xf61b2 }, ** AudioMicMute ? PUA Mute the Mic from the system */ /*{ 0x1008ffb3, 0xf61b3 }, ** Keyboard ? PUA User defined keyboard related action */ /*{ 0x1008ffb4, 0xf61b4 }, ** WWAN ? PUA Toggle WWAN LTE, UMTS, etc. radio */ /*{ 0x1008ffb5, 0xf61b5 }, ** RFKill ? PUA Toggle radios on/off */ /*{ 0x1008ffb6, 0xf61b6 }, ** AudioPreset ? PUA Select equalizer preset, e.g. theatre-mode */ /*{ 0x1008ffb7, 0xf61b7 }, ** RotationLockToggle ? PUA Toggle screen rotation lock on/off */ /*{ 0x1008ffb8, 0xf61b8 }, ** FullScreen ? PUA Toggle fullscreen */ /* *INDENT-ON* */ }; long keysym2ucs(KeySym keysym) { long result = -1; /* no matching Unicode value found */ int min = 0; int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; if ((keysym >= 0x0020 && keysym <= 0x007e) || (keysym >= 0x00a0 && keysym <= 0x00ff)) { /* found Latin-1 characters (1:1 mapping) */ result = (long) keysym; } else if ((keysym & 0xff000000) == 0x01000000) { /* found directly encoded 24-bit UCS characters */ result = (long) (keysym & 0x00ffffff); } else if (keysym >= 0x08b0 && keysym <= 0x08b7) { result = (long) keysym - 0x8b1 + 0xeeee; } else { /* binary search in table */ while (max >= min) { int mid = (min + max) / 2; if (keysymtab[mid].keysym < keysym) { min = mid + 1; } else if (keysymtab[mid].keysym > keysym) { max = mid - 1; } else { /* found it in table */ result = keysymtab[mid].ucs; break; } } if (result == -1) { long value = (long) keysym; if (keysym >= 0xfd00 && keysym <= 0xffff) { result = value - 0x1d00; } else if (keysym >= 0x10000000 && keysym <= 0x100000ff) { result = value - 0x10000000; } else if (keysym >= 0x1000f000 && keysym <= 0x1000ffff) { result = value - 0x1000f000 + 0xf0000; } else if (keysym >= 0x1004f000 && keysym <= 0x1004ffff) { result = value - 0x1004f000 + 0xf1000; } else if (keysym >= 0x1005f000 && keysym <= 0x1005ffff) { result = value - 0x1005f000 + 0xf2000; } else if (keysym >= 0x10081000 && keysym <= 0x10081fff) { result = value - 0x10081000 + 0xf4000; } else if (keysym >= 0x1008fe00 && keysym <= 0x1008ffff) { result = value - 0x1008fe00 + 0xf6000; } } } return result; } xterm-399/XTerm.ad0000644000000000000000000002527414006373013012611 0ustar rootroot! $XTermId: XTerm.ad,v 1.106 2021/02/03 01:02:03 tom Exp $ ! ----------------------------------------------------------------------------- ! this file is part of xterm ! ! Copyright 1996-2020,2021 by Thomas E. Dickey ! ! All Rights Reserved ! ! Permission is hereby granted, free of charge, to any person obtaining a ! copy of this software and associated documentation files (the ! "Software"), to deal in the Software without restriction, including ! without limitation the rights to use, copy, modify, merge, publish, ! distribute, sublicense, and/or sell copies of the Software, and to ! permit persons to whom the Software is furnished to do so, subject to ! the following conditions: ! ! The above copyright notice and this permission notice shall be included ! in all copies or substantial portions of the Software. ! ! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ! OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ! MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ! IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY ! CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ! TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ! SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ! ! Except as contained in this notice, the name(s) of the above copyright ! holders shall not be used in advertising or otherwise to promote the ! sale, use or other dealings in this Software without prior written ! authorization. ! ----------------------------------------------------------------------------- *saveLines: 1024 *SimpleMenu*BackingStore: NotUseful *SimpleMenu*menuLabel.font: -adobe-helvetica-bold-r-normal--*-120-*-*-*-*-iso8859-* *SimpleMenu*menuLabel.vertSpace: 100 *SimpleMenu*HorizontalMargins: 16 *SimpleMenu*Sme.height: 16 *SimpleMenu*Cursor: left_ptr *mainMenu.Label: Main Options *mainMenu*toolbar*Label: Toolbar *mainMenu*fullscreen*Label: Full Screen *mainMenu*securekbd*Label: Secure Keyboard *mainMenu*allowsends*Label: Allow SendEvents *mainMenu*redraw*Label: Redraw Window *mainMenu*logging*Label: Log to File *mainMenu*print-immediate*Label: Print-All Immediately *mainMenu*print-on-error*Label: Print-All on Error *mainMenu*print*Label: Print Window *mainMenu*print-redir*Label: Redirect to Printer *mainMenu*dump-html*Label: XHTML Screen Dump *mainMenu*dump-svg*Label: SVG Screen Dump *mainMenu*8-bit control*Label: 8-Bit Controls *mainMenu*backarrow key*Label: Backarrow Key (BS/DEL) *mainMenu*num-lock*Label: Alt/NumLock Modifiers *mainMenu*alt-esc*Label: Alt Sends Escape *mainMenu*meta-esc*Label: Meta Sends Escape *mainMenu*delete-is-del*Label: Delete is DEL *mainMenu*oldFunctionKeys*Label: Old Function-Keys *mainMenu*sunFunctionKeys*Label: Sun Function-Keys *mainMenu*sunKeyboard*Label: VT220 Keyboard *mainMenu*hpFunctionKeys*Label: HP Function-Keys *mainMenu*scoFunctionKeys*Label: SCO Function-Keys *mainMenu*tcapFunctionKeys*Label: Termcap Function-Keys *mainMenu*suspend*Label: Send STOP Signal *mainMenu*continue*Label: Send CONT Signal *mainMenu*interrupt*Label: Send INT Signal *mainMenu*hangup*Label: Send HUP Signal *mainMenu*terminate*Label: Send TERM Signal *mainMenu*kill*Label: Send KILL Signal *mainMenu*quit*Label: Quit *vtMenu.Label: VT Options *vtMenu*scrollbar*Label: Enable Scrollbar *vtMenu*jumpscroll*Label: Enable Jump Scroll *vtMenu*reversevideo*Label: Enable Reverse Video *vtMenu*autowrap*Label: Enable Auto Wraparound *vtMenu*reversewrap*Label: Enable Reverse Wraparound *vtMenu*autolinefeed*Label: Enable Auto Linefeed *vtMenu*appcursor*Label: Enable Application Cursor Keys *vtMenu*appkeypad*Label: Enable Application Keypad *vtMenu*scrollkey*Label: Scroll to Bottom on Key Press *vtMenu*scrollttyoutput*Label: Scroll to Bottom on Tty Output *vtMenu*allow132*Label: Allow 80/132 Column Switching *vtMenu*keepSelection*Label: Keep Selection *vtMenu*keepClipboard*Label: Keep Clipboard *vtMenu*selectToClipboard*Label: Select to Clipboard *vtMenu*cursesemul*Label: Enable Curses Emulation *vtMenu*visualbell*Label: Enable Visual Bell *vtMenu*bellIsUrgent*Label: Enable Bell Urgency *vtMenu*poponbell*Label: Enable Pop on Bell *vtMenu*cursorblink*Label: Enable Blinking Cursor *vtMenu*titeInhibit*Label: Enable Alternate Screen Switching *vtMenu*activeicon*Label: Enable Active Icon *vtMenu*softreset*Label: Do Soft Reset *vtMenu*hardreset*Label: Do Full Reset *vtMenu*clearsavedlines*Label: Reset and Clear Saved Lines *vtMenu*tekshow*Label: Show Tek Window *vtMenu*tekmode*Label: Switch to Tek Mode *vtMenu*vthide*Label: Hide VT Window *vtMenu*altscreen*Label: Show Alternate Screen *vtMenu*sixelScrolling*Label: Sixel Scrolling *vtMenu*privateColorRegisters*Label: Private Color Registers *fontMenu.Label: VT Fonts *fontMenu*fontdefault*Label: Default *fontMenu*font1*Label: Unreadable *VT100.font1: nil2 *IconFont: nil2 *fontMenu*font2*Label: Tiny *VT100.font2: 5x7 *fontMenu*font3*Label: Small *VT100.font3: 6x10 *fontMenu*font4*Label: Medium *VT100.font4: 7x13 *fontMenu*font5*Label: Large *VT100.font5: 9x15 *fontMenu*font6*Label: Huge *VT100.font6: 10x20 *fontMenu*font7*Label: Enormous !*VT100.font7: 12x24 *VT100.font7: -adobe-courier-medium-r-normal--24-240-75-75-m-150-iso10646-1 *fontMenu*fontescape*Label: Escape Sequence *fontMenu*fontsel*Label: Selection !fontescape and fontsel overridden by application *fontMenu*allow-bold-fonts*Label: Bold Fonts *fontMenu*font-linedrawing*Label: Line-Drawing Characters *fontMenu*font-doublesize*Label: Doublesized Characters *fontMenu*font-loadable*Label: VT220 Soft Fonts *fontMenu*font-packed*Label: Packed Font *fontMenu*render-font*Label: TrueType Fonts *fontMenu*utf8-mode*Label: UTF-8 Encoding *fontMenu*utf8-fonts*Label: UTF-8 Fonts *fontMenu*utf8-title*Label: UTF-8 Titles *fontMenu*allow-color-ops*Label: Allow Color Ops *fontMenu*allow-font-ops*Label: Allow Font Ops *fontMenu*allow-mouse-ops*Label: Allow Mouse Ops *fontMenu*allow-tcap-ops*Label: Allow Termcap Ops *fontMenu*allow-title-ops*Label: Allow Title Ops *fontMenu*allow-window-ops*Label: Allow Window Ops *VT100.utf8Fonts.font2: -misc-fixed-medium-r-normal--8-80-75-75-c-50-iso10646-1 *VT100.utf8Fonts.font: -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1 *VT100.utf8Fonts.font3: -misc-fixed-medium-r-normal--14-130-75-75-c-70-iso10646-1 *VT100.utf8Fonts.font4: -misc-fixed-medium-r-normal--13-120-75-75-c-80-iso10646-1 *VT100.utf8Fonts.font5: -misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1 *VT100.utf8Fonts.font6: -misc-fixed-medium-r-normal--20-200-75-75-c-100-iso10646-1 ! The default fixed font and font2-font6 are commonly aliased to iso106461 (Unicode) ! with XXX glyphs, but 12x24 is usually just iso8859-1 (about 200 glyphs). ! The adobe-courier is more commonly available than the b&h font. !*VT100.utf8Fonts.font7: -sony-fixed-medium-r-normal--24-170-100-100-c-120-iso8859-1 *VT100.utf8Fonts.font7: -adobe-courier-medium-r-normal--24-240-75-75-m-150-iso10646-1 !*VT100.utf8Fonts.font7: -b&h-lucidatypewriter-medium-r-normal-sans-24-240-75-75-m-140-iso10646-1 *tekMenu.Label: Tek Options *tekMenu*tektextlarge*Label: Large Characters *tekMenu*tektext2*Label: #2 Size Characters *tekMenu*tektext3*Label: #3 Size Characters *tekMenu*tektextsmall*Label: Small Characters *tekMenu*tekpage*Label: PAGE *tekMenu*tekreset*Label: RESET *tekMenu*tekcopy*Label: COPY *tekMenu*vtshow*Label: Show VT Window *tekMenu*vtmode*Label: Switch to VT Mode *tekMenu*tekhide*Label: Hide Tek Window *tek4014*fontLarge: 9x15 *tek4014*font2: 8x13 *tek4014*font3: 6x13 *tek4014*fontSmall: 6x10 ! If xterm is built with a toolbar, the widget hierarchy looks like this, ! showing widget name / class names. The complete menu hierarchy is built ! at startup because it is needed to make the layout work for the menubar: ! ! xterm/XTerm ! form/Form ! menubar/Box ! mainMenuButton/MenuButton ! mainMenu/SimpleMenu ! menuLabel/SmeBSB ! toolbar/SmeBSB ! ... ! vtMenu/SimpleMenu ! menuLabel/SmeBSB ! scrollbar/SmeBSB ! ... ! fontMenu/SimpleMenu ! menuLabel/SmeBSB ! fontdefault/SmeBSB ! ... ! tekMenu/SimpleMenu ! menuLabel/SmeBSB ! fontdefault/SmeBSB ! ... ! vt100/VT100 ! tektronix/TopLevelShell ! shellext/VendorShellExt ! tek4014/Tek4014 ! ! If built without a toolbar, the widget hierarchy is simpler, because there ! is no form, and the popup menu widgets are created only when they are first ! used. ! ! xterm/XTerm ! shellext/VendorShellExt ! mainMenu/SimpleMenu ! menuLabel/SmeBSB ! ... ! ... ! vt100/VT100 ! tektronix/TopLevelShell ! shellext/VendorShellExt ! tek4014/Tek4014 ! ! A more complete list of the widget/class names can be obtained using editres ! to dump a file. Some widget names are not available until the corresponding ! menu has been created. ! These resources reduce space around the menubar, by eliminating padding in ! the enclosing form (Thickness) and the border of the Box which represents ! the menubar widget. *form.Thickness: 0 *menubar.borderWidth: 0 ! If we wanted to eliminate the border of the popup menus, we could do this ! instead, since they are children of the menubar: !*menubar*borderWidth: 0 ! Eliminate the border of the buttons in the menubar, so the only line around ! the text is for the highlighted button: *MenuButton*borderWidth: 0 ! Set a border for the menus to make them simpler to distinguish against the ! vt100 widget: *SimpleMenu*borderWidth: 2 ! xterm can switch at runtime between bitmap (default) and TrueType fonts. ! The "faceSize" resource controls the size of the latter. However, it was ! originally given with a size that makes the two types of fonts different ! sizes. Uncomment this line to use the same size as "fixed". !*faceSize: 8 ! Here is a pattern that is useful for double-clicking on a URL: !*charClass: 33:48,35:48,37-38:48,43-47:48,58:48,61:48,63-64:48,95:48,126:48 ! ! Alternatively, !*on2Clicks: regex [[:alpha:]]+://([[:alnum:]!#+,./=?@_~-]|(%[[:xdigit:]][[:xdigit:]]))+ ! VT100s and similar terminals recognize escape sequences and control ! characters to which they reply to the host with other escape sequences, ! to provide information. The "resize" program uses this feature. ! ! In addition, xterm recognizes several escape sequences which can be used to ! set fonts, window properties, return settings via escape sequences. Some ! find these useful; others are concerned with the possibility of unexpected ! inputs. ! ! All of these features can be enabled or disabled via menus. ! ! Depending on your environment, you may wish to disable those by default by ! uncommenting one or more of the resource settings below: !*allowFontOps: false !*allowTcapOps: false !*allowTitleOps: false !*allowWindowOps: false xterm-399/doublechr.c0000644000000000000000000002217314723135465013367 0ustar rootroot/* $XTermId: doublechr.c,v 1.110 2024/12/01 19:38:29 tom Exp $ */ /* * Copyright 1997-2022,2024 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #include #include #include #include #define WhichCgsId(flag) (((flag) & BOLD) ? gcCBold : gcCNorm) /* * The first column is all that matters for double-size characters (since the * controls apply to a whole line). However, it's easier to maintain the * information for special fonts by writing to all cells. */ #if OPT_DEC_CHRSET static void repaint_line(XtermWidget xw, unsigned newChrSet) { TScreen *screen = TScreenOf(xw); LineData *ld; int curcol = screen->cur_col; int currow = screen->cur_row; int width = MaxCols(screen); unsigned len = (unsigned) width; assert(width > 0); /* * Ignore repetition. */ if (!IsLeftRightMode(xw) && (ld = getLineData(screen, currow)) != NULL) { unsigned oldChrSet = GetLineDblCS(ld); if (oldChrSet != newChrSet) { TRACE(("repaint_line(%2d,%2d) (%s -> %s)\n", currow, screen->cur_col, visibleDblChrset(oldChrSet), visibleDblChrset(newChrSet))); HideCursor(xw); /* If switching from single-width, keep the cursor in the visible part * of the line. */ if (CSET_DOUBLE(newChrSet)) { width /= 2; if (curcol > width) curcol = width; } /* * ScrnRefresh won't paint blanks for us if we're switching between a * single-size and double-size font. So we paint our own. */ ClearCurBackground(xw, currow, 0, 1, len, (unsigned) LineFontWidth(screen, ld)); SetLineDblCS(ld, newChrSet); set_cur_col(screen, 0); ScrnUpdate(xw, currow, 0, 1, (int) len, True); set_cur_col(screen, curcol); } } } #endif /* * Set the line to double-height characters. The 'top' flag denotes whether * we'll be using it for the top (true) or bottom (false) of the line. */ void xterm_DECDHL(XtermWidget xw, Bool top) { #if OPT_DEC_CHRSET repaint_line(xw, (unsigned) (top ? CSET_DHL_TOP : CSET_DHL_BOT)); #else (void) xw; (void) top; #endif } /* * Set the line to single-width characters (the normal state). */ void xterm_DECSWL(XtermWidget xw) { #if OPT_DEC_CHRSET repaint_line(xw, CSET_SWL); #else (void) xw; #endif } /* * Set the line to double-width characters */ void xterm_DECDWL(XtermWidget xw) { #if OPT_DEC_CHRSET repaint_line(xw, CSET_DWL); #else (void) xw; #endif } /* * Reset all lines on the screen to single-width/single-height. */ void xterm_ResetDouble(XtermWidget xw) { #if OPT_DEC_CHRSET TScreen *screen = TScreenOf(xw); Boolean changed = False; unsigned code; int row; for (row = 0; row < screen->max_row; ++row) { LineData *ld; if ((ld = getLineData(screen, ROW2INX(screen, row))) != NULL) { code = GetLineDblCS(ld); if (code != CSET_SWL) { SetLineDblCS(ld, CSET_SWL); changed = True; } } } if (changed) { xtermRepaint(xw); } #else (void) xw; #endif } #if OPT_DEC_CHRSET static void discard_font(XtermWidget xw, int n) { TScreen *screen = TScreenOf(xw); XTermFonts *data = getDoubleFont(screen, n); TRACE(("discard_font chrset=%d %s\n", data->chrset, (data->fn != NULL) ? data->fn : "")); data->chrset = 0; data->flags = 0; FreeAndNull(data->fn); xtermCloseFont(xw, data); screen->fonts_used -= 1; while (n < screen->fonts_used) { screen->double_fonts[n] = screen->double_fonts[n + 1]; ++n; } } /* push back existing fonts and create a new entry */ static XTermFonts * pushback_font(XtermWidget xw, const XTermFonts * source) { TScreen *screen = TScreenOf(xw); XTermFonts *data = getDoubleFont(screen, 0); int n; if (screen->fonts_used >= screen->cache_doublesize) { TRACE(("pushback_font: discard oldest\n")); discard_font(xw, screen->fonts_used - 1); } else { screen->fonts_used += 1; } for (n = screen->fonts_used; n > 0; n--) data[n] = data[n - 1]; data[0] = *source; TRACE(("pushback_font -> (NEW:%d)\n", screen->fonts_used)); return data; } static int xterm_Double_index(const XTermDraw * params) { XTermDraw local = *params; int n; int result = -1; TScreen *screen = TScreenOf(local.xw); XTermFonts *data = getDoubleFont(screen, 0); local.attr_flags &= BOLD; TRACE(("xterm_Double_index chrset=%#x, flags=%#x\n", local.this_chrset, local.attr_flags)); for (n = 0; n < screen->fonts_used; n++) { if (data[n].chrset == (unsigned) local.this_chrset && data[n].flags == local.attr_flags) { if (n != 0) { XTermFonts save; TRACE(("...xterm_Double_index -> %d (OLD:%d)\n", n, screen->fonts_used)); save = data[n]; while (n > 0) { data[n] = data[n - 1]; n--; } data[n] = save; } result = n; break; } } return result; } /* * Lookup/cache a GC for the double-size character display. We save up to * NUM_CHRSET values. */ GC xterm_DoubleGC(XTermDraw * params, GC old_gc, int *inxp) { TScreen *screen = TScreenOf(params->xw); VTwin *cgsWin = WhichVWin(screen); char *name; GC result = NULL; if ((name = xtermSpecialFont(params)) != NULL) { CgsEnum cgsId = WhichCgsId(params->attr_flags); Boolean found = False; XTermFonts *data = NULL; int n; if ((n = xterm_Double_index(params)) >= 0) { data = getDoubleFont(screen, n); if (data->fn != NULL) { if (!strcmp(data->fn, name) && data->fs != NULL) { found = True; FreeAndNull(name); } else { discard_font(params->xw, n); } } } if (!found && name != NULL) { XTermFonts temp; TRACE(("xterm_DoubleGC %s %d: %s\n", (params->attr_flags & BOLD) ? "BOLD" : "NORM", n, name)); memset(&temp, 0, sizeof(temp)); temp.fn = name; temp.chrset = params->this_chrset; temp.flags = (params->attr_flags & BOLD); temp.warn = fwResource; if (!xtermOpenFont(params->xw, name, &temp, NULL, False)) { XTermDraw local = *params; char *nname; /* Retry with * in resolutions */ local.draw_flags |= NORESOLUTION; nname = xtermSpecialFont(&local); if (nname != NULL) { found = (Boolean) xtermOpenFont(params->xw, nname, &temp, NULL, False); free(nname); } } else { found = True; } free(name); if (found) { n = 0; data = pushback_font(params->xw, &temp); } TRACE(("-> %s\n", found ? "OK" : "FAIL")); } if (found) { setCgsCSet(params->xw, cgsWin, cgsId, params->this_chrset); setCgsFont(params->xw, cgsWin, cgsId, data); setCgsFore(params->xw, cgsWin, cgsId, getCgsFore(params->xw, cgsWin, old_gc)); setCgsBack(params->xw, cgsWin, cgsId, getCgsBack(params->xw, cgsWin, old_gc)); result = getCgsGC(params->xw, cgsWin, cgsId); *inxp = n; } else if (params->attr_flags & BOLD) { UIntClr(params->attr_flags, BOLD); result = xterm_DoubleGC(params, old_gc, inxp); } } return result; } #if OPT_RENDERFONT /* * Like xterm_DoubleGC(), but returning an Xft font. */ XTermXftFonts * xterm_DoubleFT(XTermDraw * params, unsigned chrset, unsigned attr_flags) { XTermXftFonts *result; TScreen *screen = TScreenOf(params->xw); unsigned num = (chrset & CSET_DWL); if ((attr_flags &= BOLD) != 0) num |= 4; result = &screen->double_xft_fonts[num]; if (XftFp(result) == NULL) { getDoubleXftFont(params, result, chrset, attr_flags); } return result; } void freeall_DoubleFT(XtermWidget xw) { TScreen *screen = TScreenOf(xw); unsigned num; for (num = 0; num < XtNumber(screen->double_xft_fonts); ++num) { closeCachedXft(screen, XftFp(&screen->double_xft_fonts[num])); XftFp(&screen->double_xft_fonts[num]) = NULL; XftIs(&screen->double_xft_fonts[num]) = xcEmpty; } } #endif /* OPT_RENDERFONT */ #endif /* OPT_DEC_CHRSET */ xterm-399/charproc.c0000644000000000000000000143577315012444015013222 0ustar rootroot/* $XTermId: charproc.c,v 1.2073 2025/05/18 20:50:21 tom Exp $ */ /* * Copyright 1999-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * * * Copyright 1988 X Consortium * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of the X Consortium shall not be * used in advertising or otherwise to promote the sale, use or other dealings * in this Software without prior written authorization from the X Consortium. * */ /* * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* charproc.c */ #include #include #include #include #include #include #include #if OPT_INPUT_METHOD #if defined(HAVE_LIB_XAW) #include #elif defined(HAVE_LIB_XAW3D) #include #elif defined(HAVE_LIB_XAW3DXFT) #include #elif defined(HAVE_LIB_NEXTAW) #include #elif defined(HAVE_LIB_XAWPLUS) #include #endif #endif #if OPT_WIDE_CHARS #include #include #include #ifdef HAVE_LANGINFO_CODESET #include #endif #endif #if USE_DOUBLE_BUFFER #include #endif #include #include #include #if defined(HAVE_SCHED_YIELD) #include #endif #include #include #include #include #include #include #include #include #include #include #ifdef NO_LEAKS #include #endif typedef int (*BitFunc) (unsigned * /* p */ , unsigned /* mask */ ); static IChar doinput(XtermWidget /* xw */ ); static int set_character_class(char * /*s */ ); static void FromAlternate(XtermWidget /* xw */ , Bool /* clearFirst */ ); static void ReallyReset(XtermWidget /* xw */ , Bool /* full */ , Bool /* saved */ ); static void RequestResize(XtermWidget /* xw */ , int /* rows */ , int /* cols */ , Bool /* text */ ); static void SwitchBufs(XtermWidget /* xw */ , int /* toBuf */ , Bool /* clearFirst */ ); static void ToAlternate(XtermWidget /* xw */ , Bool /* clearFirst */ ); static void ansi_modes(XtermWidget /* xw */ , BitFunc /* func */ ); static int bitclr(unsigned *p, unsigned mask); static int bitcpy(unsigned *p, unsigned q, unsigned mask); static int bitset(unsigned *p, unsigned mask); static void dpmodes(XtermWidget /* xw */ , BitFunc /* func */ ); static void restoremodes(XtermWidget /* xw */ ); static void savemodes(XtermWidget /* xw */ ); static void window_ops(XtermWidget /* xw */ ); #if OPT_BLINK_CURS || OPT_BLINK_TEXT #define SettableCursorBlink(screen) \ (((screen)->cursor_blink != cbAlways) && \ ((screen)->cursor_blink != cbNever)) #define UpdateCursorBlink(xw) \ SetCursorBlink(xw, TScreenOf(xw)->cursor_blink) static void SetCursorBlink(XtermWidget /* xw */ , BlinkOps /* enable */ ); static void HandleBlinking(XtPointer /* closure */ , XtIntervalId * /* id */ ); static void StartBlinking(XtermWidget /* xw */ ); static void StopBlinking(XtermWidget /* xw */ ); #else #define StartBlinking(xw) /* nothing */ #define StopBlinking(xw) /* nothing */ #endif #ifndef NO_ACTIVE_ICON static Boolean discount_frame_extents(XtermWidget /* xw */ , int * /* height */ , int * /* width */ ); #else #define discount_frame_extents(xw, height, width) False #endif #if OPT_INPUT_METHOD static void PreeditPosition(XtermWidget /* xw */ ); #endif #define DEFAULT -1 #define BELLSUPPRESSMSEC 200 static ANSI reply; static PARAMS parms; #define nparam parms.count #define InitParams() init_params() #define GetParam(n) parms.params[(n)] #define SetParam(n,v) parms.params[(n)] = v #define ParamPair(n) nparam - (n), parms.params + (n) static jmp_buf vtjmpbuf; /* event handlers */ static void HandleBell PROTO_XT_ACTIONS_ARGS; static void HandleIgnore PROTO_XT_ACTIONS_ARGS; static void HandleKeymapChange PROTO_XT_ACTIONS_ARGS; static void HandleVisualBell PROTO_XT_ACTIONS_ARGS; #if HANDLE_STRUCT_NOTIFY static void HandleStructNotify PROTO_XT_EV_HANDLER_ARGS; #endif /* * NOTE: VTInitialize zeros out the entire ".screen" component of the * XtermWidget, so make sure to add an assignment statement in VTInitialize() * for each new ".screen" field added to this resource list. */ /* Defaults */ #if OPT_ISO_COLORS /* * If we default to colorMode enabled, compile-in defaults for the ANSI colors. */ #if DFT_COLORMODE #define DFT_COLOR(name) name #else #define DFT_COLOR(name) XtDefaultForeground #endif #endif static char _Font_Selected_[] = "yes"; /* string is arbitrary */ static const char *defaultTranslations; /* *INDENT-OFF* */ static XtActionsRec actionsList[] = { { "allow-bold-fonts", HandleAllowBoldFonts }, { "allow-send-events", HandleAllowSends }, { "bell", HandleBell }, { "clear-saved-lines", HandleClearSavedLines }, { "copy-selection", HandleCopySelection }, { "create-menu", HandleCreateMenu }, { "delete-is-del", HandleDeleteIsDEL }, { "dired-button", DiredButton }, { "hard-reset", HandleHardReset }, { "ignore", HandleIgnore }, { "insert", HandleKeyPressed }, /* alias for insert-seven-bit */ { "insert-eight-bit", HandleEightBitKeyPressed }, { "insert-selection", HandleInsertSelection }, { "insert-seven-bit", HandleKeyPressed }, { "interpret", HandleInterpret }, { "keymap", HandleKeymapChange }, { "pointer-motion", HandlePointerMotion }, { "pointer-button", HandlePointerButton }, { "popup-menu", HandlePopupMenu }, { "print", HandlePrintScreen }, { "print-everything", HandlePrintEverything }, { "print-redir", HandlePrintControlMode }, { "quit", HandleQuit }, { "redraw", HandleRedraw }, { "scroll-back", HandleScrollBack }, { "scroll-forw", HandleScrollForward }, { "scroll-to", HandleScrollTo }, { "secure", HandleSecure }, { "select-cursor-end", HandleKeyboardSelectEnd }, { "select-cursor-extend", HandleKeyboardSelectExtend }, { "select-cursor-start", HandleKeyboardSelectStart }, { "select-end", HandleSelectEnd }, { "select-extend", HandleSelectExtend }, { "select-set", HandleSelectSet }, { "select-start", HandleSelectStart }, { "send-signal", HandleSendSignal }, { "set-8-bit-control", Handle8BitControl }, { "set-allow132", HandleAllow132 }, { "set-altscreen", HandleAltScreen }, { "set-appcursor", HandleAppCursor }, { "set-appkeypad", HandleAppKeypad }, { "set-autolinefeed", HandleAutoLineFeed }, { "set-autowrap", HandleAutoWrap }, { "set-backarrow", HandleBackarrow }, { "set-bellIsUrgent", HandleBellIsUrgent }, { "set-cursesemul", HandleCursesEmul }, { "set-jumpscroll", HandleJumpscroll }, { "set-keep-clipboard", HandleKeepClipboard }, { "set-keep-selection", HandleKeepSelection }, { "set-marginbell", HandleMarginBell }, { "set-old-function-keys", HandleOldFunctionKeys }, { "set-pop-on-bell", HandleSetPopOnBell }, { "set-reverse-video", HandleReverseVideo }, { "set-reversewrap", HandleReverseWrap }, { "set-scroll-on-key", HandleScrollKey }, { "set-scroll-on-tty-output", HandleScrollTtyOutput }, { "set-scrollbar", HandleScrollbar }, { "set-select", HandleSetSelect }, { "set-sun-keyboard", HandleSunKeyboard }, { "set-titeInhibit", HandleTiteInhibit }, { "set-visual-bell", HandleSetVisualBell }, { "set-vt-font", HandleSetFont }, { "soft-reset", HandleSoftReset }, { "start-cursor-extend", HandleKeyboardStartExtend }, { "start-extend", HandleStartExtend }, { "string", HandleStringEvent }, { "vi-button", ViButton }, { "visual-bell", HandleVisualBell }, #ifdef ALLOWLOGGING { "set-logging", HandleLogging }, #endif #if OPT_ALLOW_XXX_OPS { "allow-color-ops", HandleAllowColorOps }, { "allow-font-ops", HandleAllowFontOps }, { "allow-mouse-ops", HandleAllowMouseOps }, { "allow-tcap-ops", HandleAllowTcapOps }, { "allow-title-ops", HandleAllowTitleOps }, { "allow-window-ops", HandleAllowWindowOps }, #endif #if OPT_BLINK_CURS { "set-cursorblink", HandleCursorBlink }, #endif #if OPT_BOX_CHARS { "set-font-linedrawing", HandleFontBoxChars }, { "set-font-packed", HandleFontPacked }, #endif #if OPT_DABBREV { "dabbrev-expand", HandleDabbrevExpand }, #endif #if OPT_DEC_CHRSET { "set-font-doublesize", HandleFontDoublesize }, #endif #if OPT_DEC_SOFTFONT { "set-font-loading", HandleFontLoading }, #endif #if OPT_EXEC_XTERM { "spawn-new-terminal", HandleSpawnTerminal }, #endif #if OPT_GRAPHICS { "set-private-colors", HandleSetPrivateColorRegisters }, #endif #if OPT_HP_FUNC_KEYS { "set-hp-function-keys", HandleHpFunctionKeys }, #endif #if OPT_LOAD_VTFONTS { "load-vt-fonts", HandleLoadVTFonts }, #endif #if OPT_MAXIMIZE { "deiconify", HandleDeIconify }, { "fullscreen", HandleFullscreen }, { "iconify", HandleIconify }, { "maximize", HandleMaximize }, { "restore", HandleRestoreSize }, #endif #if OPT_NUM_LOCK { "alt-sends-escape", HandleAltEsc }, { "meta-sends-escape", HandleMetaEsc }, { "set-num-lock", HandleNumLock }, #endif #if OPT_PRINT_ON_EXIT { "print-immediate", HandlePrintImmediate }, { "print-on-error", HandlePrintOnError }, #endif #if OPT_READLINE { "readline-button", ReadLineButton }, #endif #if OPT_RENDERFONT { "set-render-font", HandleRenderFont }, #endif #if OPT_SCO_FUNC_KEYS { "set-sco-function-keys", HandleScoFunctionKeys }, #endif #if OPT_SCREEN_DUMPS { "dump-html", HandleDumpHtml }, { "dump-svg", HandleDumpSvg }, #endif #if OPT_SCROLL_LOCK { "scroll-lock", HandleScrollLock }, #endif #if OPT_SELECTION_OPS #if OPT_EXEC_SELECTION { "exec-formatted", HandleExecFormatted }, { "exec-selectable", HandleExecSelectable }, #endif { "insert-formatted", HandleInsertFormatted }, { "insert-selectable", HandleInsertSelectable }, #endif #if OPT_SHIFT_FONTS { "larger-vt-font", HandleLargerFont }, { "smaller-vt-font", HandleSmallerFont }, #endif #if OPT_SIXEL_GRAPHICS { "set-sixel-scrolling", HandleSixelScrolling }, #endif #if OPT_SUN_FUNC_KEYS { "set-sun-function-keys", HandleSunFunctionKeys }, #endif #if OPT_TEK4014 { "set-terminal-type", HandleSetTerminalType }, { "set-visibility", HandleVisibility }, { "set-tek-text", HandleSetTekText }, { "tek-page", HandleTekPage }, { "tek-reset", HandleTekReset }, { "tek-copy", HandleTekCopy }, #endif #if OPT_TOOLBAR { "set-toolbar", HandleToolbar }, #endif #if OPT_WIDE_CHARS { "set-utf8-mode", HandleUTF8Mode }, { "set-utf8-fonts", HandleUTF8Fonts }, { "set-utf8-title", HandleUTF8Title }, #endif }; /* *INDENT-ON* */ #define SPS screen.printer_state static XtResource xterm_resources[] = { Bres(XtNallowPasteControls, XtCAllowPasteControls, screen.allowPasteControl0, False), Bres(XtNallowSendEvents, XtCAllowSendEvents, screen.allowSendEvent0, False), Bres(XtNallowColorOps, XtCAllowColorOps, screen.allowColorOp0, DEF_ALLOW_COLOR), Bres(XtNallowFontOps, XtCAllowFontOps, screen.allowFontOp0, DEF_ALLOW_FONT), Bres(XtNallowMouseOps, XtCAllowMouseOps, screen.allowMouseOp0, DEF_ALLOW_MOUSE), Bres(XtNallowTcapOps, XtCAllowTcapOps, screen.allowTcapOp0, DEF_ALLOW_TCAP), Bres(XtNallowTitleOps, XtCAllowTitleOps, screen.allowTitleOp0, DEF_ALLOW_TITLE), Bres(XtNallowWindowOps, XtCAllowWindowOps, screen.allowWindowOp0, DEF_ALLOW_WINDOW), Bres(XtNaltIsNotMeta, XtCAltIsNotMeta, screen.alt_is_not_meta, False), Bres(XtNaltSendsEscape, XtCAltSendsEscape, screen.alt_sends_esc, DEF_ALT_SENDS_ESC), Bres(XtNallowBoldFonts, XtCAllowBoldFonts, screen.allowBoldFonts, True), Bres(XtNalwaysBoldMode, XtCAlwaysBoldMode, screen.always_bold_mode, False), Bres(XtNalwaysHighlight, XtCAlwaysHighlight, screen.always_highlight, False), Bres(XtNappcursorDefault, XtCAppcursorDefault, misc.appcursorDefault, False), Bres(XtNappkeypadDefault, XtCAppkeypadDefault, misc.appkeypadDefault, False), Bres(XtNalternateScroll, XtCScrollCond, screen.alternateScroll, False), Bres(XtNautoWrap, XtCAutoWrap, misc.autoWrap, True), Bres(XtNawaitInput, XtCAwaitInput, screen.awaitInput, False), Bres(XtNfreeBoldBox, XtCFreeBoldBox, screen.free_bold_box, False), Bres(XtNbackarrowKey, XtCBackarrowKey, screen.backarrow_key, DEF_BACKARO_BS), Bres(XtNbellIsUrgent, XtCBellIsUrgent, screen.bellIsUrgent, False), Bres(XtNbellOnReset, XtCBellOnReset, screen.bellOnReset, True), Bres(XtNboldMode, XtCBoldMode, screen.bold_mode, True), Bres(XtNbrokenSelections, XtCBrokenSelections, screen.brokenSelections, False), Bres(XtNc132, XtCC132, screen.c132, False), Sres(XtNcdXtraScroll, XtCCdXtraScroll, misc.cdXtraScroll_s, DEF_CD_XTRA_SCROLL), Bres(XtNcolorInnerBorder, XtCColorInnerBorder, misc.color_inner_border, False), Bres(XtNcurses, XtCCurses, screen.curses, False), Bres(XtNcutNewline, XtCCutNewline, screen.cutNewline, True), Bres(XtNcutToBeginningOfLine, XtCCutToBeginningOfLine, screen.cutToBeginningOfLine, True), Bres(XtNdeleteIsDEL, XtCDeleteIsDEL, screen.delete_is_del, DEFDELETE_DEL), Bres(XtNdynamicColors, XtCDynamicColors, misc.dynamicColors, True), Bres(XtNeightBitControl, XtCEightBitControl, screen.control_eight_bits, False), Bres(XtNeightBitInput, XtCEightBitInput, screen.input_eight_bits, True), Bres(XtNeightBitOutput, XtCEightBitOutput, screen.output_eight_bits, True), Bres(XtNeraseSavedLines, XtCEraseSavedLines, screen.eraseSavedLines0, True), Bres(XtNhighlightSelection, XtCHighlightSelection, screen.highlight_selection, False), Bres(XtNshowWrapMarks, XtCShowWrapMarks, screen.show_wrap_marks, False), Bres(XtNhpLowerleftBugCompat, XtCHpLowerleftBugCompat, screen.hp_ll_bc, False), Bres(XtNi18nSelections, XtCI18nSelections, screen.i18nSelections, True), Bres(XtNfastScroll, XtCFastScroll, screen.fastscroll, True), Bres(XtNjumpScroll, XtCJumpScroll, screen.jumpscroll, True), Bres(XtNkeepClipboard, XtCKeepClipboard, screen.keepClipboard, False), Bres(XtNkeepSelection, XtCKeepSelection, screen.keepSelection, True), Bres(XtNloginShell, XtCLoginShell, misc.login_shell, False), Bres(XtNmarginBell, XtCMarginBell, screen.marginbell, False), Bres(XtNmetaSendsEscape, XtCMetaSendsEscape, screen.meta_sends_esc, DEF_META_SENDS_ESC), Bres(XtNmultiScroll, XtCMultiScroll, screen.multiscroll, False), Bres(XtNoldXtermFKeys, XtCOldXtermFKeys, screen.old_fkeys, False), Bres(XtNpopOnBell, XtCPopOnBell, screen.poponbell, False), Bres(XtNpreferLatin1, XtCPreferLatin1, screen.prefer_latin1, True), Bres(XtNprintRawChars, XtCPrintRawChars, screen.print_rawchars, False), Bres(XtNprinterAutoClose, XtCPrinterAutoClose, SPS.printer_autoclose, False), Bres(XtNprinterExtent, XtCPrinterExtent, SPS.printer_extent, False), Bres(XtNprinterFormFeed, XtCPrinterFormFeed, SPS.printer_formfeed, False), Bres(XtNprinterNewLine, XtCPrinterNewLine, SPS.printer_newline, True), Bres(XtNquietGrab, XtCQuietGrab, screen.quiet_grab, False), Bres(XtNresizeByPixel, XtCResizeByPixel, misc.resizeByPixel, False), Bres(XtNreverseVideo, XtCReverseVideo, misc.re_verse, False), Bres(XtNreverseWrap, XtCReverseWrap, misc.reverseWrap, False), Bres(XtNscrollBar, XtCScrollBar, misc.scrollbar, False), Bres(XtNscrollKey, XtCScrollCond, screen.scrollkey, False), Bres(XtNscrollTtyOutput, XtCScrollCond, screen.scrollttyoutput, True), Bres(XtNselectToClipboard, XtCSelectToClipboard, screen.selectToClipboard, False), Bres(XtNsignalInhibit, XtCSignalInhibit, misc.signalInhibit, False), Bres(XtNtiteInhibit, XtCTiteInhibit, misc.titeInhibit, False), Sres(XtNtiXtraScroll, XtCTiXtraScroll, misc.tiXtraScroll_s, DEF_TI_XTRA_SCROLL), Bres(XtNtrimSelection, XtCTrimSelection, screen.trim_selection, False), Bres(XtNunderLine, XtCUnderLine, screen.underline, True), Bres(XtNvisualBell, XtCVisualBell, screen.visualbell, False), Bres(XtNvisualBellLine, XtCVisualBellLine, screen.flash_line, False), Dres(XtNscaleHeight, XtCScaleHeight, screen.scale_height, "1.0"), Ires(XtNbellSuppressTime, XtCBellSuppressTime, screen.bellSuppressTime, BELLSUPPRESSMSEC), Ires(XtNfontWarnings, XtCFontWarnings, misc.fontWarnings, fwResource), Ires(XtNinternalBorder, XtCBorderWidth, screen.border, DEFBORDER), Ires(XtNlimitResize, XtCLimitResize, misc.limit_resize, 1), Ires(XtNlimitResponse, XtCLimitResponse, screen.unparse_max, DEF_LIMIT_RESPONSE), Ires(XtNmaxStringParse, XtCMaxStringParse, screen.strings_max, DEF_STRINGS_MAX), Ires(XtNmultiClickTime, XtCMultiClickTime, screen.multiClickTime, MULTICLICKTIME), Ires(XtNnMarginBell, XtCColumn, screen.nmarginbell, N_MARGINBELL), Ires(XtNpointerMode, XtCPointerMode, screen.pointer_mode, DEF_POINTER_MODE), Ires(XtNprinterControlMode, XtCPrinterControlMode, SPS.printer_controlmode, 0), Ires(XtNtitleModes, XtCTitleModes, screen.title_modes, DEF_TITLE_MODES), Ires(XtNnextEventDelay, XtCNextEventDelay, screen.nextEventDelay, 1), Ires(XtNvisualBellDelay, XtCVisualBellDelay, screen.visualBellDelay, 100), Ires(XtNsaveLines, XtCSaveLines, screen.savelines, DEF_SAVE_LINES), Ires(XtNscrollBarBorder, XtCScrollBarBorder, screen.scrollBarBorder, 1), Ires(XtNscrollLines, XtCScrollLines, screen.scrolllines, DEF_SCROLL_LINES), Sres(XtNinitialFont, XtCInitialFont, screen.initial_font, NULL), Sres(XtNfont1, XtCFont1, screen.MenuFontName(fontMenu_font1), NULL), Sres(XtNfont2, XtCFont2, screen.MenuFontName(fontMenu_font2), NULL), Sres(XtNfont3, XtCFont3, screen.MenuFontName(fontMenu_font3), NULL), Sres(XtNfont4, XtCFont4, screen.MenuFontName(fontMenu_font4), NULL), Sres(XtNfont5, XtCFont5, screen.MenuFontName(fontMenu_font5), NULL), Sres(XtNfont6, XtCFont6, screen.MenuFontName(fontMenu_font6), NULL), Sres(XtNfont7, XtCFont7, screen.MenuFontName(fontMenu_font7), NULL), Sres(XtNanswerbackString, XtCAnswerbackString, screen.answer_back, ""), Sres(XtNboldFont, XtCBoldFont, misc.default_font.f_b, DEFBOLDFONT), Sres(XtNcharClass, XtCCharClass, screen.charClass, NULL), Sres(XtNcolorEvents, XtCColorEvents, screen.colorEvents, DEF_COLOR_EVENTS), Sres(XtNdecTerminalID, XtCDecTerminalID, screen.term_id, DFT_DECID), Sres(XtNdefaultString, XtCDefaultString, screen.default_string, "#"), Sres(XtNdisallowedColorOps, XtCDisallowedColorOps, screen.disallowedColorOps, DEF_DISALLOWED_COLOR), Sres(XtNdisallowedFontOps, XtCDisallowedFontOps, screen.disallowedFontOps, DEF_DISALLOWED_FONT), Sres(XtNdisallowedMouseOps, XtCDisallowedMouseOps, screen.disallowedMouseOps, DEF_DISALLOWED_MOUSE), Sres(XtNdisallowedPasteControls, XtCDisallowedPasteControls, screen.disallowedPasteOps, DEF_DISALLOWED_PASTE_CONTROLS), Sres(XtNdisallowedTcapOps, XtCDisallowedTcapOps, screen.disallowedTcapOps, DEF_DISALLOWED_TCAP), Sres(XtNdisallowedWindowOps, XtCDisallowedWindowOps, screen.disallowedWinOps, DEF_DISALLOWED_WINDOW), Sres(XtNeightBitMeta, XtCEightBitMeta, screen.eight_bit_meta_s, DEF_8BIT_META), Sres(XtNeightBitSelectTypes, XtCEightBitSelectTypes, screen.eightbit_select_types, NULL), Sres(XtNfont, XtCFont, misc.default_font.f_n, DEFFONT), Sres(XtNgeometry, XtCGeometry, misc.geo_metry, NULL), Sres(XtNkeyboardDialect, XtCKeyboardDialect, screen.keyboard_dialect, DFT_KBD_DIALECT), Sres(XtNprinterCommand, XtCPrinterCommand, SPS.printer_command, ""), Sres(XtNtekGeometry, XtCGeometry, misc.T_geometry, NULL), Sres(XtNpointerFont, XtCPointerFont, screen.cursor_font_name, NULL), Tres(XtNcursorColor, XtCCursorColor, TEXT_CURSOR, XtDefaultForeground), Tres(XtNforeground, XtCForeground, TEXT_FG, XtDefaultForeground), Tres(XtNpointerColor, XtCPointerColor, MOUSE_FG, XtDefaultForeground), Tres(XtNbackground, XtCBackground, TEXT_BG, XtDefaultBackground), Tres(XtNpointerColorBackground, XtCBackground, MOUSE_BG, XtDefaultBackground), {XtNresizeGravity, XtCResizeGravity, XtRGravity, sizeof(XtGravity), XtOffsetOf(XtermWidgetRec, misc.resizeGravity), XtRImmediate, (XtPointer) SouthWestGravity}, Sres(XtNpointerShape, XtCCursor, screen.pointer_shape, "xterm"), #ifdef ALLOWLOGGING Bres(XtNlogInhibit, XtCLogInhibit, misc.logInhibit, False), Bres(XtNlogging, XtCLogging, misc.log_on, False), Sres(XtNlogFile, XtCLogfile, screen.logfile, NULL), #endif #ifndef NO_ACTIVE_ICON Sres(XtNactiveIcon, XtCActiveIcon, misc.active_icon_s, "default"), Ires(XtNiconBorderWidth, XtCBorderWidth, misc.icon_border_width, 2), Sres(XtNiconFont, XtCIconFont, screen.icon_fontname, "nil2"), Cres(XtNiconBorderColor, XtCBorderColor, misc.icon_border_pixel, XtDefaultBackground), #endif /* NO_ACTIVE_ICON */ #if OPT_BLINK_CURS Bres(XtNcursorBlinkXOR, XtCCursorBlinkXOR, screen.cursor_blink_xor, True), Sres(XtNcursorBlink, XtCCursorBlink, screen.cursor_blink_s, "false"), #endif Bres(XtNcursorUnderLine, XtCCursorUnderLine, screen.cursor_underline, False), Bres(XtNcursorBar, XtCCursorBar, screen.cursor_bar, False), #if OPT_BLINK_TEXT Bres(XtNshowBlinkAsBold, XtCCursorBlink, screen.blink_as_bold, DEFBLINKASBOLD), #endif #if OPT_BLINK_CURS || OPT_BLINK_TEXT Ires(XtNcursorOnTime, XtCCursorOnTime, screen.blink_on, 600), Ires(XtNcursorOffTime, XtCCursorOffTime, screen.blink_off, 300), #endif #if OPT_BOX_CHARS Bres(XtNforceBoxChars, XtCForceBoxChars, screen.force_box_chars, False), Bres(XtNforcePackedFont, XtCForcePackedFont, screen.force_packed, True), Bres(XtNassumeAllChars, XtCAssumeAllChars, screen.assume_all_chars, True), #endif #if OPT_BOX_CHARS || OPT_WIDE_CHARS Bres(XtNshowMissingGlyphs, XtCShowMissingGlyphs, screen.force_all_chars, True), #endif #if OPT_BROKEN_OSC Bres(XtNbrokenLinuxOSC, XtCBrokenLinuxOSC, screen.brokenLinuxOSC, True), #endif #if OPT_BROKEN_ST Bres(XtNbrokenStringTerm, XtCBrokenStringTerm, screen.brokenStringTerm, False), #endif #if OPT_C1_PRINT Bres(XtNallowC1Printable, XtCAllowC1Printable, screen.c1_printable, False), #endif #if OPT_CLIP_BOLD Bres(XtNuseClipping, XtCUseClipping, screen.use_clipping, True), Bres(XtNuseBorderClipping, XtCUseBorderClipping, screen.use_border_clipping, False), #endif #if OPT_DEC_CHRSET Bres(XtNfontDoublesize, XtCFontDoublesize, screen.font_doublesize, True), Ires(XtNcacheDoublesize, XtCCacheDoublesize, screen.cache_doublesize, NUM_CHRSET), #endif #if OPT_DEC_RECTOPS Ires(XtNchecksumExtension, XtCChecksumExtension, screen.checksum_ext0, csDEC), #endif #if OPT_HIGHLIGHT_COLOR Tres(XtNhighlightColor, XtCHighlightColor, HIGHLIGHT_BG, XtDefaultForeground), Tres(XtNhighlightTextColor, XtCHighlightTextColor, HIGHLIGHT_FG, XtDefaultBackground), Bres(XtNhighlightReverse, XtCHighlightReverse, screen.hilite_reverse, True), Bres(XtNhighlightColorMode, XtCHighlightColorMode, screen.hilite_color, Maybe), #endif /* OPT_HIGHLIGHT_COLOR */ #if OPT_INPUT_METHOD Bres(XtNopenIm, XtCOpenIm, misc.open_im, True), Sres(XtNinputMethod, XtCInputMethod, misc.input_method, NULL), Sres(XtNpreeditType, XtCPreeditType, misc.preedit_type, "OverTheSpot,Root"), Ires(XtNretryInputMethod, XtCRetryInputMethod, misc.retry_im, 3), #endif #if OPT_ISO_COLORS Bres(XtNboldColors, XtCColorMode, screen.boldColors, True), Ires(XtNveryBoldColors, XtCVeryBoldColors, screen.veryBoldColors, 0), Bres(XtNcolorMode, XtCColorMode, screen.colorMode, DFT_COLORMODE), Bres(XtNcolorAttrMode, XtCColorAttrMode, screen.colorAttrMode, False), Bres(XtNcolorBDMode, XtCColorAttrMode, screen.colorBDMode, False), Bres(XtNcolorBLMode, XtCColorAttrMode, screen.colorBLMode, False), Bres(XtNcolorRVMode, XtCColorAttrMode, screen.colorRVMode, False), Bres(XtNcolorULMode, XtCColorAttrMode, screen.colorULMode, False), Bres(XtNitalicULMode, XtCColorAttrMode, screen.italicULMode, False), #if OPT_WIDE_ATTRS Bres(XtNcolorITMode, XtCColorAttrMode, screen.colorITMode, False), #endif #if OPT_DIRECT_COLOR Bres(XtNdirectColor, XtCDirectColor, screen.direct_color, True), #endif COLOR_RES("0", screen.Acolors[COLOR_0], DFT_COLOR("black")), COLOR_RES("1", screen.Acolors[COLOR_1], DFT_COLOR("red3")), COLOR_RES("2", screen.Acolors[COLOR_2], DFT_COLOR("green3")), COLOR_RES("3", screen.Acolors[COLOR_3], DFT_COLOR("yellow3")), COLOR_RES("4", screen.Acolors[COLOR_4], DFT_COLOR(DEF_COLOR4)), COLOR_RES("5", screen.Acolors[COLOR_5], DFT_COLOR("magenta3")), COLOR_RES("6", screen.Acolors[COLOR_6], DFT_COLOR("cyan3")), COLOR_RES("7", screen.Acolors[COLOR_7], DFT_COLOR("gray90")), COLOR_RES("8", screen.Acolors[COLOR_8], DFT_COLOR("gray50")), COLOR_RES("9", screen.Acolors[COLOR_9], DFT_COLOR("red")), COLOR_RES("10", screen.Acolors[COLOR_10], DFT_COLOR("green")), COLOR_RES("11", screen.Acolors[COLOR_11], DFT_COLOR("yellow")), COLOR_RES("12", screen.Acolors[COLOR_12], DFT_COLOR(DEF_COLOR12)), COLOR_RES("13", screen.Acolors[COLOR_13], DFT_COLOR("magenta")), COLOR_RES("14", screen.Acolors[COLOR_14], DFT_COLOR("cyan")), COLOR_RES("15", screen.Acolors[COLOR_15], DFT_COLOR("white")), COLOR_RES("BD", screen.Acolors[COLOR_BD], DFT_COLOR(XtDefaultForeground)), COLOR_RES("BL", screen.Acolors[COLOR_BL], DFT_COLOR(XtDefaultForeground)), COLOR_RES("UL", screen.Acolors[COLOR_UL], DFT_COLOR(XtDefaultForeground)), COLOR_RES("RV", screen.Acolors[COLOR_RV], DFT_COLOR(XtDefaultForeground)), #if OPT_WIDE_ATTRS COLOR_RES("IT", screen.Acolors[COLOR_IT], DFT_COLOR(XtDefaultForeground)), #endif #endif /* OPT_ISO_COLORS */ CLICK_RES("2", screen.onClick[1], "word"), CLICK_RES("3", screen.onClick[2], "line"), CLICK_RES("4", screen.onClick[3], 0), CLICK_RES("5", screen.onClick[4], 0), Sres(XtNshiftEscape, XtCShiftEscape, keyboard.shift_escape_s, "false"), #if OPT_MOD_FKEYS Ires(XtNmodifyKeyboard, XtCModifyKeyboard, keyboard.modify_1st.allow_keys, 0), Ires(XtNmodifyCursorKeys, XtCModifyCursorKeys, keyboard.modify_1st.cursor_keys, mfkParam), Ires(XtNmodifyFunctionKeys, XtCModifyFunctionKeys, keyboard.modify_1st.function_keys, mfkParam), Ires(XtNmodifyKeypadKeys, XtCModifyKeypadKeys, keyboard.modify_1st.keypad_keys, mfkOriginal), Ires(XtNmodifyModifierKeys, XtCModifyModifierKeys, keyboard.modify_1st.modify_keys, mfkOriginal), Ires(XtNmodifyOtherKeys, XtCModifyOtherKeys, keyboard.modify_1st.other_keys, mfkOriginal), Ires(XtNmodifySpecialKeys, XtCModifySpecialKeys, keyboard.modify_1st.special_keys, mfkOriginal), Ires(XtNmodifyStringKeys, XtCModifyStringKeys, keyboard.modify_1st.string_keys, mfkOriginal), Ires(XtNformatCursorKeys, XtCFormatCursorKeys, keyboard.format_1st.cursor_keys, 0), Ires(XtNformatFunctionKeys, XtCFormatFunctionKeys, keyboard.format_1st.function_keys, 0), Ires(XtNformatKeypadKeys, XtCFormatKeypadKeys, keyboard.format_1st.keypad_keys, 0), Ires(XtNformatModifierKeys, XtCFormatModifierKeys, keyboard.format_1st.modify_keys, 0), Ires(XtNformatOtherKeys, XtCFormatOtherKeys, keyboard.format_1st.other_keys, 0), Ires(XtNformatSpecialKeys, XtCFormatSpecialKeys, keyboard.format_1st.special_keys, 0), Ires(XtNformatStringKeys, XtCFormatStringKeys, keyboard.format_1st.string_keys, 0), #endif #if OPT_NUM_LOCK Bres(XtNalwaysUseMods, XtCAlwaysUseMods, misc.alwaysUseMods, False), Bres(XtNnumLock, XtCNumLock, misc.real_NumLock, True), #endif #if OPT_PRINT_COLORS Ires(XtNprintAttributes, XtCPrintAttributes, SPS.print_attributes, 1), #endif #if OPT_REGIS_GRAPHICS Sres(XtNregisDefaultFont, XtCRegisDefaultFont, screen.graphics_regis_default_font, ""), Sres(XtNregisScreenSize, XtCRegisScreenSize, screen.graphics_regis_screensize, "auto"), #endif #if OPT_GRAPHICS Sres(XtNdecGraphicsID, XtCDecGraphicsID, screen.graph_termid, DFT_DECID), Sres(XtNmaxGraphicSize, XtCMaxGraphicSize, screen.graphics_max_size, "1000x1000"), #endif #if OPT_ISO_COLORS && OPT_WIDE_ATTRS && OPT_SGR2_HASH Bres(XtNfaintIsRelative, XtCFaintIsRelative, screen.faint_relative, False), #endif #if OPT_SHIFT_FONTS Bres(XtNshiftFonts, XtCShiftFonts, misc.shift_fonts, True), #endif #if OPT_SIXEL_GRAPHICS Bres(XtNsixelScrolling, XtCSixelScrolling, screen.sixel_scrolling, True), Bres(XtNsixelScrollsRight, XtCSixelScrollsRight, screen.sixel_scrolls_right, False), #endif #if OPT_GRAPHICS Ires(XtNnumColorRegisters, XtCNumColorRegisters, screen.numcolorregisters, 0), Bres(XtNprivateColorRegisters, XtCPrivateColorRegisters, screen.privatecolorregisters, True), Bres(XtNincrementalGraphics, XtCIncrementalGraphics, screen.incremental_graphics, False), #endif #if OPT_STATUS_LINE Sres(XtNindicatorFormat, XtCIndicatorFormat, screen.status_fmt, DEF_SL_FORMAT), #endif #if OPT_SUNPC_KBD Ires(XtNctrlFKeys, XtCCtrlFKeys, misc.ctrl_fkeys, 10), #endif #if OPT_TEK4014 Bres(XtNtekInhibit, XtCTekInhibit, misc.tekInhibit, False), Bres(XtNtekSmall, XtCTekSmall, misc.tekSmall, False), Bres(XtNtekStartup, XtCTekStartup, misc.TekEmu, False), #endif #if OPT_TOOLBAR Wres(XtNmenuBar, XtCMenuBar, VT100_TB_INFO(menu_bar), 0), Ires(XtNmenuHeight, XtCMenuHeight, VT100_TB_INFO(menu_height), 25), #endif #if OPT_WIDE_CHARS Bres(XtNcjkWidth, XtCCjkWidth, misc.cjk_width, False), Bres(XtNmkWidth, XtCMkWidth, misc.mk_width, False), Bres(XtNprecompose, XtCPrecompose, screen.normalized_c, True), Bres(XtNutf8Latin1, XtCUtf8Latin1, screen.utf8_latin1, False), Bres(XtNutf8Weblike, XtCUtf8Weblike, screen.utf8_weblike, False), Bres(XtNvt100Graphics, XtCVT100Graphics, screen.vt100_graphics, True), Bres(XtNwideChars, XtCWideChars, screen.wide_chars, False), Ires(XtNcombiningChars, XtCCombiningChars, screen.max_combining, 2), Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 655), Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 65536), Sres(XtNutf8, XtCUtf8, screen.utf8_mode_s, "default"), Sres(XtNutf8Fonts, XtCUtf8Fonts, screen.utf8_fonts_s, "default"), Sres(XtNutf8Title, XtCUtf8Title, screen.utf8_title_s, "default"), Sres(XtNwideBoldFont, XtCWideBoldFont, misc.default_font.f_wb, DEFWIDEBOLDFONT), Sres(XtNwideFont, XtCWideFont, misc.default_font.f_w, DEFWIDEFONT), Sres(XtNutf8SelectTypes, XtCUtf8SelectTypes, screen.utf8_select_types, NULL), #endif #if OPT_LUIT_PROG Sres(XtNlocale, XtCLocale, misc.locale_str, "medium"), Sres(XtNlocaleFilter, XtCLocaleFilter, misc.localefilter, DEFLOCALEFILTER), #endif #if OPT_INPUT_METHOD Sres(XtNximFont, XtCXimFont, misc.f_x, DEFXIMFONT), #endif #if OPT_SCROLL_LOCK Bres(XtNallowScrollLock, XtCAllowScrollLock, screen.allowScrollLock0, False), Bres(XtNautoScrollLock, XtCAutoScrollLock, screen.autoScrollLock, False), #endif /* these are used only for testing ncurses, not in the manual page */ #if OPT_XMC_GLITCH Bres(XtNxmcInline, XtCXmcInline, screen.xmc_inline, False), Bres(XtNxmcMoveSGR, XtCXmcMoveSGR, screen.move_sgr_ok, True), Ires(XtNxmcAttributes, XtCXmcAttributes, screen.xmc_attributes, 1), Ires(XtNxmcGlitch, XtCXmcGlitch, screen.xmc_glitch, 0), #endif #ifdef SCROLLBAR_RIGHT Bres(XtNrightScrollBar, XtCRightScrollBar, misc.useRight, False), #endif #if OPT_RENDERFONT Bres(XtNforceXftHeight, XtCForceXftHeight, screen.force_xft_height, False), Ires(XtNxftMaxGlyphMemory, XtCXftMaxGlyphMemory, screen.xft_max_glyph_memory, 0), Ires(XtNxftMaxUnrefFonts, XtCXftMaxUnrefFonts, screen.xft_max_unref_fonts, 0), Bres(XtNxftTrackMemUsage, XtCXftTrackMemUsage, screen.xft_track_mem_usage, DEF_TRACK_USAGE), #define RES_FACESIZE(n) Dres(XtNfaceSize #n, XtCFaceSize #n, misc.face_size[n], "0.0") RES_FACESIZE(1), RES_FACESIZE(2), RES_FACESIZE(3), RES_FACESIZE(4), RES_FACESIZE(5), RES_FACESIZE(6), RES_FACESIZE(7), Dres(XtNfaceSize, XtCFaceSize, misc.face_size[0], DEFFACESIZE), Sres(XtNfaceName, XtCFaceName, misc.default_xft.f_n, DEFFACENAME), Sres(XtNrenderFont, XtCRenderFont, misc.render_font_s, "default"), Ires(XtNlimitFontsets, XtCLimitFontsets, misc.limit_fontsets, DEF_XFT_CACHE), Ires(XtNlimitFontHeight, XtCLimitFontHeight, misc.limit_fontheight, 10), Ires(XtNlimitFontWidth, XtCLimitFontWidth, misc.limit_fontwidth, 10), #if OPT_RENDERWIDE Sres(XtNfaceNameDoublesize, XtCFaceNameDoublesize, misc.default_xft.f_w, DEFFACENAME), #endif #endif }; static Boolean VTSetValues(Widget cur, Widget request, Widget new_arg, ArgList args, Cardinal *num_args); static void VTClassInit(void); static void VTDestroy(Widget w); static void VTExpose(Widget w, XEvent *event, Region region); static void VTInitialize(Widget wrequest, Widget new_arg, ArgList args, Cardinal *num_args); static void VTRealize(Widget w, XtValueMask * valuemask, XSetWindowAttributes * values); static void VTResize(Widget w); #if OPT_INPUT_METHOD static void VTInitI18N(XtermWidget); #endif static WidgetClassRec xtermClassRec = { { /* core_class fields */ (WidgetClass) & widgetClassRec, /* superclass */ "VT100", /* class_name */ sizeof(XtermWidgetRec), /* widget_size */ VTClassInit, /* class_initialize */ NULL, /* class_part_initialize */ False, /* class_inited */ VTInitialize, /* initialize */ NULL, /* initialize_hook */ VTRealize, /* realize */ actionsList, /* actions */ XtNumber(actionsList), /* num_actions */ xterm_resources, /* resources */ XtNumber(xterm_resources), /* num_resources */ NULLQUARK, /* xrm_class */ True, /* compress_motion */ False, /* compress_exposure */ True, /* compress_enterleave */ False, /* visible_interest */ VTDestroy, /* destroy */ VTResize, /* resize */ VTExpose, /* expose */ VTSetValues, /* set_values */ NULL, /* set_values_hook */ XtInheritSetValuesAlmost, /* set_values_almost */ NULL, /* get_values_hook */ NULL, /* accept_focus */ XtVersion, /* version */ NULL, /* callback_offsets */ NULL, /* tm_table */ XtInheritQueryGeometry, /* query_geometry */ XtInheritDisplayAccelerator, /* display_accelerator */ NULL /* extension */ } }; WidgetClass xtermWidgetClass = (WidgetClass) & xtermClassRec; /* * Add input-actions for widgets that are overlooked (scrollbar and toolbar): * * a) Sometimes the scrollbar passes through translations, sometimes it * doesn't. We add the KeyPress translations here, just to be sure. * b) In the normal (non-toolbar) configuration, the xterm widget covers * almost all of the window. With a toolbar, there's a relatively * large area that the user would expect to enter keystrokes since the * program can get the focus. */ void xtermAddInput(Widget w) { /* *INDENT-OFF* */ XtActionsRec input_actions[] = { { "insert", HandleKeyPressed }, /* alias */ { "insert-eight-bit", HandleEightBitKeyPressed }, { "insert-seven-bit", HandleKeyPressed }, { "pointer-motion", HandlePointerMotion }, { "pointer-button", HandlePointerButton }, { "secure", HandleSecure }, { "string", HandleStringEvent }, { "scroll-back", HandleScrollBack }, { "scroll-forw", HandleScrollForward }, { "scroll-to", HandleScrollTo }, { "select-cursor-end", HandleKeyboardSelectEnd }, { "select-cursor-extend", HandleKeyboardSelectExtend }, { "select-cursor-start", HandleKeyboardSelectStart }, { "insert-selection", HandleInsertSelection }, { "select-start", HandleSelectStart }, { "select-extend", HandleSelectExtend }, { "start-extend", HandleStartExtend }, { "select-end", HandleSelectEnd }, { "clear-saved-lines", HandleClearSavedLines }, { "popup-menu", HandlePopupMenu }, { "bell", HandleBell }, { "ignore", HandleIgnore }, #if OPT_DABBREV { "dabbrev-expand", HandleDabbrevExpand }, #endif #if OPT_MAXIMIZE { "fullscreen", HandleFullscreen }, #endif #if OPT_SCROLL_LOCK { "scroll-lock", HandleScrollLock }, #endif #if OPT_SHIFT_FONTS { "larger-vt-font", HandleLargerFont }, { "smaller-vt-font", HandleSmallerFont }, #endif }; /* *INDENT-ON* */ TRACE_TRANS("BEFORE", w); XtAppAddActions(app_con, input_actions, XtNumber(input_actions)); XtAugmentTranslations(w, XtParseTranslationTable(defaultTranslations)); TRACE_TRANS("AFTER:", w); #if OPT_EXTRA_PASTE if (term && term->keyboard.extra_translations) XtOverrideTranslations((Widget) term, XtParseTranslationTable(term->keyboard.extra_translations)); #endif } #if OPT_ISO_COLORS #ifdef EXP_BOGUS_FG static Bool CheckBogusForeground(TScreen *screen, const char *tag) { int row = -1, col = -1, pass; Bool isClear = True; (void) tag; for (pass = 0; pass < 2; ++pass) { row = screen->cur_row; for (; isClear && (row <= screen->max_row); ++row) { CLineData *ld = getLineData(screen, row); if (ld != 0) { IAttr *attribs = ld->attribs; col = (row == screen->cur_row) ? screen->cur_col : 0; for (; isClear && (col <= screen->max_col); ++col) { unsigned flags = attribs[col]; if (pass) { flags &= ~FG_COLOR; attribs[col] = (IAttr) flags; } else if ((flags & BG_COLOR)) { isClear = False; } else if ((flags & FG_COLOR)) { unsigned ch = ld->charData[col]; isClear = ((ch == ' ') || (ch == 0)); } else { isClear = False; } } } } } TRACE(("%s checked %d,%d to %d,%d %s pass %d\n", tag, screen->cur_row, screen->cur_col, row, col, isClear && pass ? "cleared" : "unchanged", pass)); return isClear; } #endif /* * The terminal's foreground and background colors are set via two mechanisms: * text (cur_foreground, cur_background values that are passed down to * XDrawImageString and XDrawString) * area (X11 graphics context used in XClearArea and XFillRectangle) */ void SGR_Foreground(XtermWidget xw, int color) { TScreen *screen = TScreenOf(xw); Pixel fg; if (color >= 0) { UIntSet(xw->flags, FG_COLOR); } else { UIntClr(xw->flags, FG_COLOR); } fg = getXtermFG(xw, xw->flags, color); xw->cur_foreground = color; setCgsFore(xw, WhichVWin(screen), gcNorm, fg); setCgsBack(xw, WhichVWin(screen), gcNormReverse, fg); setCgsFore(xw, WhichVWin(screen), gcBold, fg); setCgsBack(xw, WhichVWin(screen), gcBoldReverse, fg); #ifdef EXP_BOGUS_FG /* * If we've just turned off the foreground color, check for blank cells * which have no background color, but do have foreground color. This * could happen due to setting the foreground color just before scrolling. * * Those cells look uncolored, but will confuse ShowCursor(), which looks * for the colors in the current cell, and will see the foreground color. * In that case, remove the foreground color from the blank cells. */ if (color < 0) { CheckBogusForeground(screen, "SGR_Foreground"); } #endif } void SGR_Background(XtermWidget xw, int color) { TScreen *screen = TScreenOf(xw); Pixel bg; /* * An indexing operation may have set screen->scroll_amt, which would * normally result in calling FlushScroll() in WriteText(). However, * if we're changing the background color now, then the new value * should not apply to the pending blank lines. */ if (screen->scroll_amt && (color != xw->cur_background)) FlushScroll(xw); if (color >= 0) { UIntSet(xw->flags, BG_COLOR); } else { UIntClr(xw->flags, BG_COLOR); } bg = getXtermBG(xw, xw->flags, color); xw->cur_background = color; setCgsBack(xw, WhichVWin(screen), gcNorm, bg); setCgsFore(xw, WhichVWin(screen), gcNormReverse, bg); setCgsBack(xw, WhichVWin(screen), gcBold, bg); setCgsFore(xw, WhichVWin(screen), gcBoldReverse, bg); } /* Invoked after updating bold/underline flags, computes the extended color * index to use for foreground. (See also 'extract_fg()'). */ static void setExtendedFG(XtermWidget xw) { int fg = xw->sgr_foreground; if (TScreenOf(xw)->colorAttrMode || (fg < 0)) { fg = MapToColorMode(fg, TScreenOf(xw), xw->flags); } /* This implements the IBM PC-style convention of 8-colors, with one * bit for bold, thus mapping the 0-7 codes to 8-15. It won't make * much sense for 16-color applications, but we keep it to retain * compatibility with ANSI-color applications. */ #if OPT_PC_COLORS /* XXXJTL should be settable at runtime (resource or OSC?) */ if (TScreenOf(xw)->boldColors && (!xw->sgr_38_xcolors) && (fg >= 0) && (fg < 8) && (xw->flags & BOLD)) fg |= 8; #endif SGR_Foreground(xw, fg); } /* Invoked after updating inverse flag, computes the extended color * index to use for background. (See also 'extract_bg()'). */ static void setExtendedBG(XtermWidget xw) { int bg = xw->sgr_background; if (TScreenOf(xw)->colorAttrMode || (bg < 0)) { if (TScreenOf(xw)->colorRVMode && (xw->flags & INVERSE)) bg = COLOR_RV; } SGR_Background(xw, bg); } void setExtendedColors(XtermWidget xw) { setExtendedFG(xw); setExtendedBG(xw); } static void reset_SGR_Foreground(XtermWidget xw) { xw->sgr_foreground = -1; xw->sgr_38_xcolors = False; clrDirectFG(xw->flags); setExtendedFG(xw); } static void reset_SGR_Background(XtermWidget xw) { xw->sgr_background = -1; clrDirectBG(xw->flags); setExtendedBG(xw); } static void reset_SGR_Colors(XtermWidget xw) { reset_SGR_Foreground(xw); reset_SGR_Background(xw); } #endif /* OPT_ISO_COLORS */ #if OPT_WIDE_ATTRS /* * Call this before changing the state of ATR_ITALIC, to update the GC fonts. */ static void setItalicFont(XtermWidget xw, Bool enable) { if (enable) { if ((xw->flags & ATR_ITALIC) == 0) { xtermLoadItalics(xw); TRACE(("setItalicFont: enabling Italics\n")); xtermUpdateFontGCs(xw, getItalicFont); } } else if ((xw->flags & ATR_ITALIC) != 0) { TRACE(("setItalicFont: disabling Italics\n")); xtermUpdateFontGCs(xw, getNormalFont); } } static void ResetItalics(XtermWidget xw) { setItalicFont(xw, False); UIntClr(xw->flags, ATR_ITALIC); } #else #define ResetItalics(xw) /* nothing */ #endif static void initCharset(TScreen *screen, int which, DECNRCM_codes code) { screen->gsets[which] = code; } void saveCharsets(TScreen *screen, DECNRCM_codes * target) { int g; for (g = 0; g < NUM_GSETS2; ++g) { target[g] = screen->gsets[g]; } } void restoreCharsets(TScreen *screen, const DECNRCM_codes * source) { int g; for (g = 0; g < NUM_GSETS2; ++g) { screen->gsets[g] = source[g]; } } void resetCharsets(TScreen *screen) { int dft_upss = ((screen->ansi_level >= 2) ? PreferredUPSS(screen) : nrc_ASCII); #if OPT_WIDE_CHARS /* * User-preferred selection set makes a choice between ISO-8859-1 and * a precursor to it. Those are both single-byte encodings. Because the * multibyte UTF-8 equates to ISO-8859-1, the default (DEC Supplemental) * cannot be used as a default in UTF-8 mode. But we cannot use ISO-8859-1 * either, because that would break the special case in decodeUtf8() that * checks if NRCS is being used, passing 8-bit characters as is. * * In short, UPSS is not available with UTF-8, but DECRQUPSS will say that * ISO-Latin1 is selected. */ if (screen->wide_chars && (screen->utf8_mode || screen->utf8_nrc_mode)) { dft_upss = nrc_ASCII; } #endif TRACE(("resetCharsets: UPSS=%s\n", visibleScsCode(dft_upss))); /* * The assignments for G2/G3 to ASCII differ from the documented DEC * terminal, because xterm also checks GR to decide whether or not to * handle non-Unicode character sets, e.g., NRCS. */ initCharset(screen, 0, nrc_ASCII); initCharset(screen, 1, nrc_ASCII); initCharset(screen, 2, dft_upss); initCharset(screen, 3, dft_upss); initCharset(screen, 4, dft_upss); /* gsets_upss */ screen->curgl = 0; /* G0 => GL. */ screen->curgr = 2; /* G2 => GR. */ screen->curss = 0; /* No single shift. */ #if OPT_VT52_MODE if (screen->vtXX_level == 0) initCharset(screen, 1, nrc_DEC_Spec_Graphic); /* Graphics */ #endif } static void modified_DECNRCM(XtermWidget xw) { #if OPT_WIDE_CHARS TScreen *screen = TScreenOf(xw); if (screen->wide_chars && (screen->utf8_mode || screen->utf8_nrc_mode)) { int enabled = ((xw->flags & NATIONAL) != 0); int modefix; EXCHANGE(screen->utf8_nrc_mode, screen->utf8_mode, modefix); switchPtyData(screen, !enabled); TRACE(("UTF8 mode temporarily %s\n", enabled ? "ON" : "OFF")); } #else (void) xw; #endif } /* * VT300 and up support three ANSI conformance levels, defined according to * ECMA-43 (originally dpANSI X3.134.1). * * VSRM - Documented Exceptions EL-00070-D */ static void set_ansi_conformance(TScreen *screen, int level) { TRACE(("set_ansi_conformance(%d) dec_level %d:%d, ansi_level %d\n", level, screen->vtXX_level * 100, screen->terminal_id, screen->ansi_level)); if (screen->vtXX_level >= 3) { screen->ansi_level = level; } } static void set_vtXX_level(TScreen *screen, int level) { screen->vtXX_level = level; screen->ansi_level = (level > 1) ? 3 : 1; } /* * Set scrolling margins. VTxxx terminals require that the top/bottom are * different, so we have at least two lines in the scrolling region. */ static void set_tb_margins(TScreen *screen, int top, int bottom) { TRACE(("set_tb_margins %d..%d, prior %d..%d\n", top, bottom, screen->top_marg, screen->bot_marg)); if (bottom > top) { screen->top_marg = top; screen->bot_marg = bottom; } if (screen->top_marg > screen->max_row) screen->top_marg = screen->max_row; if (screen->bot_marg > screen->max_row) screen->bot_marg = screen->max_row; } static void set_lr_margins(TScreen *screen, int left, int right) { TRACE(("set_lr_margins %d..%d, prior %d..%d\n", left, right, screen->lft_marg, screen->rgt_marg)); if (right > left) { screen->lft_marg = left; screen->rgt_marg = right; } if (screen->lft_marg > screen->max_col) screen->lft_marg = screen->max_col; if (screen->rgt_marg > screen->max_col) screen->rgt_marg = screen->max_col; } #define reset_tb_margins(screen) set_tb_margins(screen, 0, screen->max_row) #define reset_lr_margins(screen) set_lr_margins(screen, 0, screen->max_col) void resetMargins(XtermWidget xw) { TScreen *screen = TScreenOf(xw); reset_tb_margins(screen); reset_lr_margins(screen); } static void resetMarginMode(XtermWidget xw) { UIntClr(xw->flags, LEFT_RIGHT); resetMargins(xw); } static void resetRendition(XtermWidget xw) { TScreen *screen = TScreenOf(xw); (void) screen; ResetItalics(xw); UIntClr(xw->flags, (SGR_MASK | SGR_MASK2 | INVISIBLE)); } void set_max_col(TScreen *screen, int cols) { TRACE(("set_max_col %d, prior %d\n", cols, screen->max_col)); if (cols < 0) cols = 0; screen->max_col = cols; } void set_max_row(TScreen *screen, int rows) { TRACE(("set_max_row %d, prior %d\n", rows, screen->max_row)); if (rows < 0) rows = 0; screen->max_row = rows; } #if OPT_TRACE #define DATA(name) { name, #name } static const struct { const PARSE_T *table; const char *name; } all_tables[] = { DATA(ansi_table) ,DATA(cigtable) ,DATA(csi2_table) ,DATA(csi_ex_table) ,DATA(csi_amp_table) ,DATA(csi_quo_table) ,DATA(csi_table) ,DATA(dec2_table) ,DATA(dec3_table) ,DATA(dec_table) ,DATA(eigtable) ,DATA(esc_sp_table) ,DATA(esc_table) ,DATA(scrtable) ,DATA(scs96table) ,DATA(scstable) ,DATA(sos_table) #if OPT_BLINK_CURS ,DATA(csi_sp_table) #endif #if OPT_DEC_LOCATOR ,DATA(csi_tick_table) #endif #if OPT_DEC_RECTOPS ,DATA(csi_dollar_table) ,DATA(csi_star_table) ,DATA(csi_dec_dollar_table) #endif #if OPT_VT52_MODE ,DATA(vt52_table) ,DATA(vt52_esc_table) ,DATA(vt52_ignore_table) #endif #if OPT_VT525_COLORS ,DATA(csi_comma_table) #endif #if OPT_WIDE_CHARS ,DATA(esc_pct_table) ,DATA(scs_amp_table) ,DATA(scs_pct_table) ,DATA(scs_2qt_table) #endif #if OPT_XTERM_SGR ,DATA(csi_hash_table) #endif #undef DATA }; #define WHICH_TABLE(name) if (table == name) result = #name static const char * which_table(const PARSE_T * table) { const char *result = "?"; Cardinal n; for (n = 0; n < XtNumber(all_tables); ++n) { if (table == all_tables[n].table) { result = all_tables[n].name; break; } } return result; } static void check_tables(void) { Cardinal n; int ch; int total_codes = 0; int total_ground = 0; int total_ignored = 0; TRACE(("** check_tables\n")); for (n = 0; n < XtNumber(all_tables); ++n) { const PARSE_T *table = all_tables[n].table; TRACE(("*** %s\n", all_tables[n].name)); /* * Most of the tables should use the same codes in 0..31, 128..159 * as the "ansi" table. */ if (strncmp(all_tables[n].name, "ansi", 4) && strncmp(all_tables[n].name, "sos_", 4) && strncmp(all_tables[n].name, "vt52", 4)) { for (ch = 0; ch < 32; ++ch) { int c1 = ch + 128; PARSE_T st_l = table[ch]; PARSE_T st_r = table[c1]; if (st_l != ansi_table[ch]) { TRACE((" %3d: %d vs %d\n", ch, st_l, ansi_table[ch])); } if (st_r != ansi_table[c1]) { TRACE((" %3d: %d vs %d\n", c1, st_r, ansi_table[c1])); } } } /* * All of the tables should have their GL/GR parts encoded the same. * * Originally reported by Paul Williams (patch #171), this is a * standard feature of DEC's terminals, documented in DEC 070 section * 3.5.4.5 "GR Graphic Characters Within Control Strings". */ for (ch = 32; ch < 127; ++ch) { PARSE_T st_l = table[ch]; PARSE_T st_r = table[ch + 128]; if (st_l != st_r) { if (st_r == CASE_IGNORE && !strncmp(all_tables[n].name, "vt52", 4)) { ; } else { TRACE((" %3d: %d vs %d\n", ch, st_l, st_r)); } } } /* * Just for amusement, show how sparse the encoding tables are. */ for (ch = 0; ch < 256; ++ch) { ++total_codes; switch (table[ch]) { case CASE_GROUND_STATE: total_ground++; break; case CASE_ESC_IGNORE: /* FALLTHRU */ case CASE_IGNORE: /* FALLTHRU */ case CASE_VT52_IGNORE: total_ignored++; break; } } } TRACE(("VTPrsTbl:\n")); TRACE(("%d total codes\n", total_codes)); TRACE(("%d total ignored\n", total_ignored)); TRACE(("%d total reset/ground\n", total_ground)); } static void check_bitmasks(void) { #define dMSK 0x100 #define DATA(mode,name) { mode, name, #name } #define DMSK(what) (dMSK | (what)) #define DGRP(offs) (1 << ((offs) - 1)) static struct { int mode; int code; const char *name; } table[] = { DATA(DGRP(1), INVERSE), DATA(DGRP(1), UNDERLINE), DATA(DGRP(1), BOLD), DATA(DGRP(1), BLINK), DATA(DMSK(DGRP(1)), SGR_MASK), DATA(DGRP(2), BG_COLOR), DATA(DGRP(2), FG_COLOR), DATA(DGRP(2), PROTECTED), DATA(DGRP(4), CHARDRAWN), DATA(DGRP(2), INVISIBLE), #if OPT_WIDE_ATTRS DATA(DGRP(2), ATR_FAINT), DATA(DGRP(2), ATR_ITALIC), DATA(DGRP(2), ATR_STRIKEOUT), DATA(DGRP(2), ATR_DBL_UNDER), DATA(DGRP(2), ATR_DIRECT_FG), DATA(DGRP(2), ATR_DIRECT_BG), #endif DATA(DMSK(DGRP(2)), SGR_MASK2), DATA(DMSK(DGRP(3)), ATTRIBUTES), DATA(DGRP(3), REVERSE_VIDEO), DATA(DGRP(3), WRAPAROUND), DATA(DGRP(3), REVERSEWRAP), DATA(DGRP(3), REVERSEWRAP2), DATA(DGRP(3), LINEFEED), DATA(DGRP(3), ORIGIN), DATA(DGRP(3), INSERT), DATA(DGRP(3), SMOOTHSCROLL), DATA(DGRP(3), IN132COLUMNS), DATA(DGRP(5), NATIONAL), DATA(DGRP(5), LEFT_RIGHT), DATA(DGRP(5), NOCLEAR_COLM), DATA(DGRP(4), NOBACKGROUND), DATA(DGRP(4), NOTRANSLATION), DATA(DGRP(4), DOUBLEWFONT), DATA(DGRP(4), DOUBLEHFONT), DATA(DGRP(4), CHARBYCHAR), DATA(DGRP(4), NORESOLUTION), DATA(DMSK(DGRP(1) | DGRP(2) | DGRP(4)), DRAWX_MASK), DATA(-1, EOF) }; #undef DATA int j, k; TRACE(("** check_bitmasks:\n")); for (j = 0; table[j].mode >= 0; ++j) { TRACE(("%4X %8X %s\n", table[j].mode, table[j].code, table[j].name)); if (table[j].mode & dMSK) { int mask = dMSK; for (k = 0; table[k].mode >= 0; ++k) { if (j == k) continue; if (table[k].mode & dMSK) continue; if ((table[j].mode & table[k].mode) != 0) mask |= table[k].mode; } if (mask != table[j].mode) { TRACE(("...expected %08X\n", mask)); } } else { for (k = 0; table[k].mode >= 0; ++k) { if (j == k) continue; if (table[k].mode & dMSK) continue; if ((table[j].code & table[k].code) != 0) { TRACE(("...same bits %s\n", table[k].name)); } } } } } #endif static int init_params(void) { while (parms.count-- > 0) { parms.is_sub[parms.count] = 0; parms.params[parms.count] = 0; } parms.count = 0; parms.has_subparams = 0; return 0; } #if OPT_TRACE > 0 static void dump_params(void) { int n; int arg; TRACE(("params %d (%d)\n", nparam, parms.has_subparams)); for (arg = 1, n = 0; n < nparam; ++n) { TRACE(("%3d.%d %d\n", arg, parms.is_sub[n], parms.params[n])); if (!parms.is_sub[n]) ++arg; } } #define DumpParams() dump_params() #else #define DumpParams() /* nothing */ #endif /* allocate larger buffer if needed/possible */ #define SafeAlloc(type, area, used, size) \ type *new_string = area; \ size_t new_length = size; \ if (new_length == 0) { \ new_length = 1024; \ new_string = TypeMallocN(type, new_length); \ } else if (used+1 >= new_length) { \ new_length = size * 2; \ new_string = TypeMallocN(type, new_length); \ } \ if (new_string != NULL) { \ if (area != NULL && used != 0) { \ memcpy(new_string, area, used * sizeof(type)); \ } else { \ memset(new_string, 0, 3 * sizeof(type)); \ } \ } #define SafeFree(area, size) \ if (area != new_string) { \ free(area); \ area = new_string; \ } \ size = new_length #define WriteNow() { \ unsigned single = 0; \ \ if (screen->curss) { \ if (sp->print_area != NULL) { \ dotext(xw, \ screen->gsets[(int) (screen->curss)], \ sp->print_area, \ (Cardinal) 1); \ single++; \ } \ screen->curss = 0; \ } \ if (sp->print_used > single) { \ if (sp->print_area != NULL) { \ dotext(xw, \ screen->gsets[(int) (screen->curgl)], \ sp->print_area + single, \ (Cardinal) (sp->print_used - single)); \ } \ } \ sp->print_used = 0; \ } \ typedef enum { sa_INIT ,sa_LAST ,sa_REGIS ,sa_SIXEL } StringArgs; struct ParseState { unsigned check_recur; #if OPT_VT52_MODE Bool vt52_cup; #endif const PARSE_T *groundtable; const PARSE_T *parsestate; int scstype; int scssize; Bool private_function; /* distinguish private-mode from standard */ int string_mode; /* nonzero iff we're processing a string */ StringArgs string_args; /* parse-state within string processing */ Bool string_skip; /* true if we will ignore the string */ int lastchar; /* positive iff we had a graphic character */ int nextstate; #if OPT_WIDE_CHARS int last_was_wide; #endif /* Buffer for processing printable text */ IChar *print_area; size_t print_size; size_t print_used; /* Buffer for processing strings (e.g., OSC ... ST) */ Char *string_area; size_t string_size; size_t string_used; /* Buffer for deferring input */ Char *defer_area; size_t defer_size; size_t defer_used; }; static struct ParseState myState; static void init_groundtable(TScreen *screen, struct ParseState *sp) { (void) screen; #if OPT_VT52_MODE if (!(screen->vtXX_level)) { sp->groundtable = vt52_table; } else if (screen->terminal_id >= 100) #endif { sp->groundtable = ansi_table; } } #if OPT_DEC_RECTOPS static DECNRCM_codes current_charset(TScreen *screen, int value) { DECNRCM_codes result = nrc_ASCII; if (IsLatin1(value)) { if (screen->curss != 0) { result = screen->gsets[screen->curss]; } else if (value >= 0x80) { result = screen->gsets[screen->curgr]; } else { result = screen->gsets[screen->curgl]; } } return result; } #endif static void select_charset(struct ParseState *sp, int type, int size) { TRACE(("select_charset G%d size %d -> G%d size %d\n", sp->scstype, sp->scssize, type, size)); sp->scstype = type; sp->scssize = size; if (size == 94) { sp->parsestate = scstable; } else { sp->parsestate = scs96table; } } /* *INDENT-OFF* */ static const struct { DECNRCM_codes result; int prefix; int suffix; int min_level; int max_level; int need_nrc; int sized_96; } scs_table[] = { { nrc_ASCII, 0, 'B', 1, 9, 0, 0 }, { nrc_British, 0, 'A', 1, 9, 0, 0 }, { nrc_DEC_Spec_Graphic, 0, '0', 1, 9, 0, 0 }, { nrc_DEC_Alt_Chars, 0, '1', 1, 1, 0, 0 }, { nrc_DEC_Alt_Graphics, 0, '2', 1, 1, 0, 0 }, /* VT2xx */ { nrc_DEC_Supp, 0, '<', 2, 2, 0, 0 }, { nrc_Dutch, 0, '4', 2, 9, 1, 0 }, { nrc_Finnish, 0, '5', 2, 9, 1, 0 }, { nrc_Finnish2, 0, 'C', 2, 9, 1, 0 }, { nrc_French, 0, 'R', 2, 9, 1, 0 }, { nrc_French2, 0, 'f', 2, 9, 1, 0 }, { nrc_French_Canadian, 0, 'Q', 2, 9, 1, 0 }, { nrc_German, 0, 'K', 2, 9, 1, 0 }, { nrc_Italian, 0, 'Y', 2, 9, 1, 0 }, { nrc_Norwegian_Danish2, 0, 'E', 2, 9, 1, 0 }, { nrc_Norwegian_Danish3, 0, '6', 2, 9, 1, 0 }, { nrc_Spanish, 0, 'Z', 2, 9, 1, 0 }, { nrc_Swedish, 0, '7', 2, 9, 1, 0 }, { nrc_Swedish2, 0, 'H', 2, 9, 1, 0 }, { nrc_Swiss, 0, '=', 2, 9, 1, 0 }, /* VT3xx */ { nrc_DEC_UPSS, 0, '<', 3, 9, 0, 1 }, { nrc_British_Latin_1, 0, 'A', 3, 9, 1, 0 }, { nrc_DEC_Supp_Graphic, '%', '5', 3, 9, 0, 0 }, { nrc_DEC_Technical, 0, '>', 3, 9, 0, 0 }, { nrc_French_Canadian2, 0, '9', 3, 9, 1, 0 }, { nrc_Norwegian_Danish, 0, '`', 3, 9, 1, 0 }, { nrc_Portugese, '%', '6', 3, 9, 1, 0 }, { nrc_ISO_Latin_1_Supp, 0, 'A', 3, 9, 0, 1 }, { nrc_JIS_Katakana, 0, 'I', 3, 3, 0, 0 }, { nrc_JIS_Roman, 0, 'J', 3, 3, 0, 0 }, /* VT5xx */ { nrc_Greek, '"', '>', 5, 9, 1, 0 }, { nrc_Hebrew, '%', '=', 5, 9, 1, 0 }, { nrc_Russian, '&', '5', 5, 9, 1, 0 }, { nrc_SCS_NRCS, '%', '3', 5, 9, 1, 0 }, { nrc_Turkish, '%', '2', 5, 9, 1, 0 }, { nrc_DEC_Cyrillic, '&', '4', 5, 9, 0, 0 }, { nrc_DEC_Greek_Supp, '"', '?', 5, 9, 0, 0 }, { nrc_DEC_Hebrew_Supp, '"', '4', 5, 9, 0, 0 }, { nrc_DEC_Turkish_Supp, '%', '0', 5, 9, 0, 0 }, { nrc_ISO_Greek_Supp, 0, 'F', 5, 9, 0, 1 }, { nrc_ISO_Hebrew_Supp, 0, 'H', 5, 9, 0, 1 }, { nrc_ISO_Latin_2_Supp, 0, 'B', 5, 9, 0, 1 }, { nrc_ISO_Latin_5_Supp, 0, 'M', 5, 9, 0, 1 }, { nrc_ISO_Latin_Cyrillic,0, 'L', 5, 9, 0, 1 }, }; /* *INDENT-ON* */ #if OPT_DEC_RECTOPS static char * encode_scs(DECNRCM_codes value, int *psize) { static char buffer[3]; Cardinal n; char *result = buffer; for (n = 0; n < XtNumber(scs_table); ++n) { if (scs_table[n].result == value) { if (scs_table[n].prefix) *result++ = (char) scs_table[n].prefix; if (scs_table[n].suffix) *result++ = (char) scs_table[n].suffix; *psize = scs_table[n].sized_96; break; } } *result = '\0'; return buffer; } static int is_96charset(DECNRCM_codes value) { Cardinal n; int result = 0; for (n = 0; n < XtNumber(scs_table); ++n) { if (scs_table[n].result == value) { result = scs_table[n].sized_96 ? 1 : 0; break; } } return result; } #endif void xtermDecodeSCS(XtermWidget xw, int which, int sgroup, int prefix, int suffix) { TScreen *screen = TScreenOf(xw); Cardinal n; DECNRCM_codes result = nrc_Unknown; prefix = AsciiOf(prefix); suffix = AsciiOf(suffix); for (n = 0; n < XtNumber(scs_table); ++n) { if (prefix == scs_table[n].prefix && suffix == scs_table[n].suffix && sgroup <= scs_table[n].min_level && screen->vtXX_level >= scs_table[n].min_level && screen->vtXX_level <= scs_table[n].max_level && (scs_table[n].need_nrc == 0 || (xw->flags & NATIONAL) != 0)) { result = scs_table[n].result; break; } } if (result != nrc_Unknown) { initCharset(screen, which, result); TRACE(("setting G%d to table #%d %s", which, n, visibleScsCode((int) result))); } else { TRACE(("...unknown GSET")); initCharset(screen, which, nrc_ASCII); } #if OPT_TRACE TRACE((" (")); if (prefix) TRACE(("prefix='%c', ", prefix)); TRACE(("suffix='%c', sgroup=%d", suffix, sgroup)); TRACE((")\n")); #endif } /* * Given a parameter number, and subparameter (starting in each case from zero) * return the corresponding index into the parameter array. If the combination * is not found, return -1. */ static int subparam_index(int p, int s) { int result = -1; int j, p2, s2; for (j = p2 = 0; j < nparam; ++j, ++p2) { if (parms.is_sub[j]) { s2 = 0; do { if ((p == p2) && (s == s2)) { result = j; break; } ++s2; } while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j])); if (result >= 0) break; --j; /* undo the last "while" */ } else if (p == p2) { if (s == 0) { result = j; } break; } } TRACE2(("...subparam_index %d.%d = %d\n", p + 1, s + 1, result)); return result; } /* * Given an index into the parameter array, return the corresponding parameter * number (starting from zero). */ static int param_number(int item) { int result = -1; int j, p; for (j = p = 0; j < nparam; ++j, ++p) { if (j >= item) { result = p; break; } if (parms.is_sub[j]) { while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j])) { /* EMPTY */ } --j; } } TRACE2(("...param_number(%d) = %d\n", item, result)); return result; } /* * Check if the given index in the parameter array has subparameters. * If so, return the number of subparameters to use as a loop limit, etc. */ static int param_has_subparams(int item) { int result = 0; if (parms.has_subparams) { int p = param_number(item); int n = subparam_index(p, 0); if (n >= 0 && parms.is_sub[n]) { while (++n < nparam && parms.is_sub[n - 1] < parms.is_sub[n]) { result++; } } } TRACE(("...param_has_subparams(%d) ->%d\n", item, result)); return result; } #if OPT_DIRECT_COLOR || OPT_256_COLORS || OPT_88_COLORS || OPT_ISO_COLORS static int get_subparam(int p, int s) { int item = subparam_index(p, s); int result = (item >= 0) ? parms.params[item] : DEFAULT; TRACE(("...get_subparam[%d] = %d\n", item, result)); return result; } /* * Some background - * * Todd Larason provided the initial changes to support 256-colors in July 1999. * I pointed out that the description of SGR 38/48 in ECMA-48 was vague, and * was unsure if there would be some standard using those codes. His response * was that this was documented (it turns out, in equally vague terms) in ITU * T.416 * * Discussing this with Todd Larason in mid-1999, my point was that given the * high cost of obtaining ITU T.416 (ISO-8613-6), the standard was not going * to be effective (more than $100 then, more than $200 in 2012) * * We overlooked the detail about ":" as a subparameter delimiter (documented * in 5.4.2 in ECMA-48). Some discussion in KDE in mid-2006 led Lars Doelle * to discuss the issue with me. Lars' initial concern dealt with the fact * that a sequence such as * CSI 38 ; 5 ; 1 m * violated the principle that SGR parameters could be used in any order. * Further discussion (see KDE #107487) resolved that the standard expected * that the sequence would look like * CSI 38 ; 5 : 1 m * which still violates that principle, since the "5:1" parameter has to * follow the "38" to be useful. * * This function accepts either format (per request by Paul Leonerd Evans). * It also accepts * CSI 38 : 5 : 1 m * according to Lars' original assumption. While implementing that, I added * support for Konsole's interpretation of "CSI 38 : 2" as a 24-bit RGB value. * ISO-8613-6 documents that as "direct color". * * At the time in 2012, no one noticed (or commented) regarding ISO-8613-6's * quirk in the description of direct color: it mentions a color space * identifier parameter which should follow the "2" (as parameter 1). In the * same section, ISO-8613-6 mentions a parameter 6 which can be ignored, as * well as parameters 7 and 8. Like parameter 1, parameters 7 and 8 are not * defined clearly in the standard, and a close reading indicates they are * optional, saying they "may be used". This implementation ignores parameters * 6 (and above), and provides for the color space identifier by checking the * number of parameters: * 3 after "2" (no color space identifier) * 4 or more after "2" (color space identifier) * * By the way - all of the parameters are decimal integers, and missing * parameters represent a default value. ISO-8613-6 is clear about that. * * Aside from ISO-8613-3, there is no standard use of ":" as a delimiter. * ECMA-48 says only: * * 5.4.2 Parameter string format * * A parameter string which does not start with a bit combination in the * range 03/12 to 03/15 shall have the following format: * * a) A parameter string consists of one or more parameter * sub-strings, each of which represents a number in decimal * notation. * * b) Each parameter sub-string consists of one or more bit * combinations from 03/00 to 03/10; the bit combinations from * 03/00 to 03/09 represent the digits ZERO to NINE; bit * combination 03/10 may be used as a separator in a parameter * sub-string, for example, to separate the fractional part of a * decimal number from the integer part of that number. * * That is, there is no mention in ECMA-48 of the possibility that a parameter * string might be a list of parameters, as done in ISO-8613-3 (nor does * ECMA-48 provide an example where the ":" separator might be used). Because * of this, xterm treats other cases than those needed for ISO-8613-3 as an * error, and stops interpreting the sequence. */ #define extended_colors_limit(n) ((n) == 5 ? 1 : ((n) == 2 ? 3 : 0)) static Boolean parse_extended_colors(XtermWidget xw, int *colorp, int *itemp, Boolean *extended) { Boolean result = False; int item = *itemp; int next = item; int base = param_number(item); int code = -1; int values[3]; /* maximum number of subparameters */ int need = 0; /* number of subparameters needed */ int have; int n; /* * On entry, 'item' points to the 38/48 code in the parameter array. * If that has subparameters, we will expect all of the values to * be subparameters of that item. */ if ((have = param_has_subparams(item)) != 0) { /* accept CSI 38 : 5 : 1 m */ /* accept CSI 38 : 2 : 1 : 2 : 3 m */ code = get_subparam(base, 1); need = extended_colors_limit(code); next = item + have; for (n = 0; n < need && n < 3; ++n) { values[n] = get_subparam(base, 2 + n + (have > 4)); } } else if (++item < nparam) { ++base; if ((have = param_has_subparams(item)) != 0) { /* accept CSI 38 ; 5 : 1 m */ /* accept CSI 38 ; 2 : 1 : 2 : 3 m */ code = get_subparam(base, 0); need = extended_colors_limit(code); next = base + have; for (n = 0; n < need && n < 3; ++n) { values[n] = get_subparam(base, 1 + n + (have > 3)); } } else { /* accept CSI 38 ; 5 ; 1 m */ /* accept CSI 38 ; 2 ; 1 ; 2 ; 3 m */ code = GetParam(item); need = extended_colors_limit(code); next = item + need; for (n = 0; n < need && n < 3; ++n) { values[n] = GetParam(item + 1 + n); } } } item = next; *extended = False; switch (code) { case 2: /* direct color in rgb space */ if ((values[0] >= 0 && values[0] < 256) && (values[1] >= 0 && values[1] < 256) && (values[2] >= 0 && values[2] < 256)) { #if OPT_DIRECT_COLOR if (TScreenOf(xw)->direct_color && xw->has_rgb) { *colorp = getDirectColor(xw, values[0], values[1], values[2]); result = True; *extended = True; } else #endif { *colorp = xtermClosestColor(xw, values[0], values[1], values[2]); result = okIndexedColor(*colorp); } } else { *colorp = -1; } break; case 5: /* indexed color */ *colorp = values[0]; result = okIndexedColor(*colorp); break; default: *colorp = -1; break; } TRACE(("...resulting color %d/%d %s\n", *colorp, NUM_ANSI_COLORS, result ? "OK" : "ERR")); *itemp = item; return result; } #endif /* ...extended_colors */ static int optional_param(int which) { return (nparam > which) ? GetParam(which) : DEFAULT; } static int only_default(void) { return (nparam <= 1) && (GetParam(0) == DEFAULT); } static int use_default_value(int which, int default_value) { int result = (nparam > which) ? GetParam(which) : default_value; if (result <= 0) result = default_value; return result; } #define zero_if_default(which) use_default_value(which, 0) #define one_if_default(which) use_default_value(which, 1) #define BeginString(mode) \ do { \ sp->string_mode = mode; \ sp->string_args = sa_LAST; \ sp->parsestate = sos_table; \ } while (0) #define BeginString2(mode) \ do { \ sp->string_mode = mode; \ sp->string_args = sa_INIT; \ sp->parsestate = sos_table; \ } while (0) static void begin_sixel(XtermWidget xw, struct ParseState *sp) { TScreen *screen = TScreenOf(xw); sp->string_args = sa_LAST; if (optSixelGraphics(screen)) { #if OPT_SIXEL_GRAPHICS ANSI params; const char *cp; cp = (const char *) sp->string_area; sp->string_area[sp->string_used] = '\0'; parse_ansi_params(¶ms, &cp); parse_sixel_init(xw, ¶ms); sp->string_args = sa_SIXEL; sp->string_used = 0; #else (void) screen; TRACE(("ignoring sixel graphic (compilation flag not enabled)\n")); #endif } } /* * Color palette changes using the OSC controls require a repaint of the * screen - but not immediately. Do the repaint as soon as we detect a * state which will not lead to another color palette change. */ static void repaintWhenPaletteChanged(XtermWidget xw, struct ParseState *sp) { Boolean ignore = False; switch (sp->nextstate) { case CASE_ESC: ignore = ((sp->parsestate == ansi_table) || (sp->parsestate == sos_table)); #if USE_DOUBLE_BUFFER if (resource.buffered && TScreenOf(xw)->needSwap) { ignore = False; } #endif break; case CASE_OSC: ignore = ((sp->parsestate == ansi_table) || (sp->parsestate == esc_table)); break; case CASE_IGNORE: ignore = (sp->parsestate == sos_table); break; case CASE_ST: ignore = ((sp->parsestate == esc_table) || (sp->parsestate == sos_table)); break; case CASE_ESC_DIGIT: ignore = (sp->parsestate == csi_table); break; case CASE_ESC_SEMI: ignore = (sp->parsestate == csi2_table); break; } if (!ignore) { TRACE(("repaintWhenPaletteChanged\n")); xw->work.palette_changed = False; xtermRepaint(xw); xtermFlushDbe(xw); } } #if OPT_C1_PRINT || OPT_WIDE_CHARS #define ParseSOS(screen) ((screen)->c1_printable == 0) #else #define ParseSOS(screen) 0 #endif #define ResetState(sp) InitParams(), (sp)->parsestate = (sp)->groundtable static void illegal_parse(XtermWidget xw, unsigned c, struct ParseState *sp) { ResetState(sp); sp->nextstate = sp->parsestate[c]; Bell(xw, XkbBI_MinorError, 0); } static void init_parser(XtermWidget xw, struct ParseState *sp) { TScreen *screen = TScreenOf(xw); free(sp->defer_area); free(sp->print_area); free(sp->string_area); memset(sp, 0, sizeof(*sp)); sp->scssize = 94; /* number of printable/nonspace ASCII */ sp->lastchar = -1; /* not a legal IChar */ sp->nextstate = -1; /* not a legal state */ init_groundtable(screen, sp); ResetState(sp); } static void init_reply(unsigned type) { memset(&reply, 0, sizeof(reply)); reply.a_type = (Char) type; } static void deferparsing(unsigned c, struct ParseState *sp) { SafeAlloc(Char, sp->defer_area, sp->defer_used, sp->defer_size); if (new_string == NULL) { xtermWarning("Cannot allocate %lu bytes for deferred parsing of %u\n", (unsigned long) new_length, c); return; } SafeFree(sp->defer_area, sp->defer_size); sp->defer_area[(sp->defer_used)++] = CharOf(c); } #if OPT_MOD_FKEYS static void set_mod_fkeys(XtermWidget xw, int which, int what, Bool enabled, int ignore) { #define SET_MOD_FKEYS(field) \ do { \ xw->keyboard.modify_now.field = ((what == DEFAULT) && enabled) \ ? xw->keyboard.modify_1st.field \ : what; \ xw->keyboard.ignore_now.field = ignore; \ TRACE(("%s modify_now.%s to %d\n", \ ((what == DEFAULT) && enabled) ? "reset" : "set", \ #field, \ xw->keyboard.modify_now.field)); \ TRACE(("%s ignore_now.%s %d\n", \ ((what == DEFAULT) && enabled) ? "reset" : "set", \ #field, xw->keyboard.ignore_now.field)); \ } while (0) switch (which) { case modifyKeyboard: SET_MOD_FKEYS(allow_keys); break; case modifyCursorKeys: SET_MOD_FKEYS(cursor_keys); break; case modifyFunctionKeys: SET_MOD_FKEYS(function_keys); break; case modifyKeypadKeys: SET_MOD_FKEYS(keypad_keys); break; case modifyModifierKeys: SET_MOD_FKEYS(modify_keys); break; case modifyOtherKeys: SET_MOD_FKEYS(other_keys); SET_MIN_MOD(xw, what); TRACE(("set min_mod to %d\n", xw->work.min_mod)); break; case modifySpecialKeys: SET_MOD_FKEYS(special_keys); break; case modifyStringKeys: SET_MOD_FKEYS(string_keys); break; } #undef SET_MOD_FKEYS } static void set_fmt_fkeys(XtermWidget xw, int which, int what, Bool enabled) { #define SET_FMT_FKEYS(field) \ xw->keyboard.format_now.field = ((what == DEFAULT) && enabled) \ ? xw->keyboard.format_1st.field \ : what; \ TRACE(("%s format_now.%s to %d\n", \ ((what == DEFAULT) && enabled) ? "reset" : "set", \ #field, \ xw->keyboard.format_now.field)); switch (which) { case modifyKeyboard: SET_FMT_FKEYS(allow_keys); break; case modifyCursorKeys: SET_FMT_FKEYS(cursor_keys); break; case modifyFunctionKeys: SET_FMT_FKEYS(function_keys); break; case modifyKeypadKeys: SET_FMT_FKEYS(keypad_keys); break; case modifyModifierKeys: SET_FMT_FKEYS(modify_keys); break; case modifyOtherKeys: SET_FMT_FKEYS(other_keys); break; case modifySpecialKeys: SET_FMT_FKEYS(special_keys); break; case modifyStringKeys: SET_FMT_FKEYS(string_keys); break; } #undef SET_FMT_FKEYS } static void report_mod_fkeys(XtermWidget xw, int which) /* XTQMODKEYS */ { #define GET_MOD_FKEYS(field) \ reply.a_param[1] = (ParmType) xw->keyboard.modify_now.field init_reply(ANSI_CSI); reply.a_pintro = '>'; /* replies look like a set-mode */ reply.a_nparam = 2; reply.a_final = 'm'; reply.a_param[1] = DEFAULT; switch (reply.a_param[0] = (ParmType) which) { case modifyKeyboard: GET_MOD_FKEYS(allow_keys); break; case modifyCursorKeys: GET_MOD_FKEYS(cursor_keys); break; case modifyFunctionKeys: GET_MOD_FKEYS(function_keys); break; case modifyKeypadKeys: GET_MOD_FKEYS(keypad_keys); break; case modifyModifierKeys: GET_MOD_FKEYS(modify_keys); break; case modifyOtherKeys: GET_MOD_FKEYS(other_keys); break; case modifySpecialKeys: GET_MOD_FKEYS(special_keys); break; case modifyStringKeys: GET_MOD_FKEYS(string_keys); break; } unparseseq(xw, &reply); #undef GET_MOD_FKEYS } static void report_fmt_fkeys(XtermWidget xw, int which) /* XTQFMTKEYS */ { #define GET_FMT_FKEYS(field) \ reply.a_param[1] = (ParmType) xw->keyboard.format_now.field init_reply(ANSI_CSI); reply.a_pintro = '>'; /* replies look like a set-mode */ reply.a_nparam = 2; reply.a_final = 'f'; reply.a_param[1] = DEFAULT; switch (reply.a_param[0] = (ParmType) which) { case modifyKeyboard: GET_FMT_FKEYS(allow_keys); break; case modifyCursorKeys: GET_FMT_FKEYS(cursor_keys); break; case modifyFunctionKeys: GET_FMT_FKEYS(function_keys); break; case modifyKeypadKeys: GET_FMT_FKEYS(keypad_keys); break; case modifyModifierKeys: GET_FMT_FKEYS(modify_keys); break; case modifyOtherKeys: GET_FMT_FKEYS(other_keys); break; case modifySpecialKeys: GET_FMT_FKEYS(special_keys); break; case modifyStringKeys: GET_FMT_FKEYS(string_keys); break; } unparseseq(xw, &reply); #undef GET_FMT_FKEYS } #endif /* OPT_MOD_FKEYS */ #if OPT_STATUS_LINE typedef enum { SLnone = 0, /* no status-line timer needed */ SLclock = 1, /* status-line updates once/second */ SLcoords = 2, /* status-line shows cursor-position */ SLwritten = 3 /* status-line may need asynchronous repainting */ } SL_MODE; #define SL_BUFSIZ 80 #if OPT_TRACE static const char * visibleStatusType(int code) { const char *result = "?"; switch (code) { case 0: result = "none"; break; case 1: result = "indicator"; break; case 2: result = "writable"; break; } return result; } static void trace_status_line(XtermWidget xw, int lineno, const char *tag) { TScreen *screen = TScreenOf(xw); TRACE(("@%d, %s (%s, %s)%s%s @ (%d,%d) vs %d\n", lineno, tag, screen->status_active ? "active" : "inactive", visibleStatusType(screen->status_type), ((screen->status_type != screen->status_shown) ? " vs " : ""), ((screen->status_type != screen->status_shown) ? visibleStatusType(screen->status_shown) : ""), screen->cur_row, screen->cur_col, LastRowNumber(screen))); } #define TRACE_SL(tag) trace_status_line(xw, __LINE__, tag) #else #define TRACE_SL(tag) /* nothing */ #endif static SL_MODE find_SL_MODE(XtermWidget xw) { TScreen *screen = TScreenOf(xw); SL_MODE result = SLnone; const char *parse; for (parse = screen->status_fmt; *parse != '\0'; ++parse) { const char *found = parse; if (*parse == '%') { if (*++parse == L_CURL) { const char *check = strchr(parse, '%'); size_t length = 0; if (check != NULL && check[1] == R_CURL) { length = (size_t) (2 + check - found); } else { length = strlen(found); } if (!strncmp(found, "%{unixtime%}", length)) { if (result == SLnone) result = SLclock; } else if (!strncmp(found, "%{position%}", length)) { result = SLcoords; } parse = found + length - 1; } #if defined(HAVE_STRFTIME) else if (*parse != '\0') { if (result == SLnone && strchr("cEgOrsSTX+", *parse) != NULL) { result = SLclock; } } #endif } } return result; } static long find_SL_Timeout(XtermWidget xw) { long result = 0; switch (find_SL_MODE(xw)) { case SLnone: case SLwritten: break; case SLclock: result = DEF_SL_CLOCK; break; case SLcoords: result = DEF_SL_COORDS; break; } return result; } static void StatusInit(SavedCursor * data) { memset(data, 0, sizeof(*data)); data->sgr_foreground = -1; data->sgr_background = -1; } #define SL_SAVE(n) \ do { \ TRACE(("@%d saving %s to %d,%d\n", __LINE__, \ (n) ? "status" : "main", \ screen->cur_row, \ screen->cur_col)); \ CursorSave2(xw, &screen->status_data[n]); \ } while (0) #define SL_RESTORE(n) \ do { \ CursorRestore2(xw, &screen->status_data[n]); \ TRACE(("@%d restored %s to %d,%d\n", __LINE__, \ (n) ? "status" : "main", \ screen->status_data[n].row, \ screen->status_data[n].col)); \ } while (0) /* save the status-line position, restore main display */ #define SL_SAVE2() \ do { \ SL_SAVE(1); \ SL_RESTORE(0); \ } while (0) /* save the main-display position, restore status-line */ #define SL_RESTORE2() \ do { \ SL_SAVE(0); \ SL_RESTORE(1); \ screen->cur_row = FirstRowNumber(screen); \ } while (0) static void StatusPutChars(XtermWidget xw, const char *value, int length) { TScreen *screen = TScreenOf(xw); if (length < 0) length = (int) strlen(value); while (length > 0) { IChar buffer[SL_BUFSIZ + 1]; Cardinal n; for (n = 0; n < SL_BUFSIZ && length > 0 && *value != '\0'; ++n) { buffer[n] = CharOf(*value++); if (buffer[n] < 32 || buffer[n] > 126) buffer[n] = ' '; /* FIXME - provide for UTF-8 */ --length; } buffer[n] = 0; dotext(xw, screen->gsets[(int) (screen->curgl)], buffer, n); } } static void show_indicator_status(XtPointer closure, XtIntervalId * id GCC_UNUSED) { XtermWidget xw = (XtermWidget) closure; TScreen *screen = TScreenOf(xw); int right_margin; time_t now; const char *parse; char buffer[SL_BUFSIZ + 1]; long interval; if (screen->status_type != 1) { screen->status_timeout = False; return; } if (screen->status_active && (screen->status_type == screen->status_shown)) { return; } screen->status_active = True; if (screen->status_shown <= 1) { SL_SAVE(0); } screen->cur_row = FirstRowNumber(screen); screen->cur_col = 0; xw->flags |= INVERSE; xw->flags &= (IFlags) (~WRAPAROUND); now = time((time_t *) 0); for (parse = screen->status_fmt; *parse != '\0'; ++parse) { const char *found = parse; if (*parse == '%') { if (*++parse == L_CURL) { const char *check = strchr(parse, '%'); size_t length = 0; if (check != NULL && check[1] == R_CURL) { length = (size_t) (2 + check - found); } else { length = strlen(found); } if (!strncmp(found, "%{version%}", length)) { StatusPutChars(xw, xtermVersion(), -1); } else if (!strncmp(found, "%{unixtime%}", length)) { char *t = x_strtrim(ctime(&now)); if (t != NULL) { StatusPutChars(xw, t, -1); free(t); } } else if (!strncmp(found, "%{position%}", length)) { sprintf(buffer, "(%02d,%03d)", screen->status_data[0].row + 1, screen->status_data[0].col + 1); StatusPutChars(xw, buffer, -1); } else { StatusPutChars(xw, found, (int) length); } parse = found + length - 1; } #if defined(HAVE_STRFTIME) else if (*parse != '\0') { char format[3]; struct tm *tm = localtime(&now); format[0] = '%'; format[1] = *parse; format[2] = '\0'; if (strftime(buffer, sizeof(buffer) - 1, format, tm) != 0) { StatusPutChars(xw, buffer, -1); } else { StatusPutChars(xw, "?", 1); StatusPutChars(xw, parse - 1, 2); } } #endif } else { StatusPutChars(xw, parse, 1); } } right_margin = ScrnRightMargin(xw); memset(buffer, ' ', (size_t) SL_BUFSIZ); while (screen->cur_col < right_margin) { int chunk = Min(SL_BUFSIZ, (right_margin - screen->cur_col)); StatusPutChars(xw, buffer, chunk); } ScrnRefresh(xw, FirstRowNumber(screen), 0, 1, right_margin, True); screen->status_active = False; SL_RESTORE(0); /* if we processed a position or date/time, repeat */ interval = find_SL_Timeout(xw); if (interval > 0) { (void) XtAppAddTimeOut(app_con, (unsigned long) interval, show_indicator_status, xw); } screen->status_timeout = True; } static void clear_status_line(XtermWidget xw) { TScreen *screen = TScreenOf(xw); SavedCursor save_me; SavedCursor clearit; int save_type = screen->status_type; TRACE_SL("clear_status_line"); StatusInit(&clearit); CursorSave2(xw, &save_me); CursorRestore2(xw, &clearit); screen->status_type = 2; set_cur_row(screen, LastRowNumber(screen)); #if 1 ClearLine(xw); #else if (getLineData(screen, screen->cur_row) != NULL) { int n; char buffer[SL_BUFSIZ + 1]; CLineData *ld = getLineData(screen, screen->cur_row); int right_margin = ScrnRightMargin(xw); TRACE(("...text[%d:%d]:%s\n", screen->cur_row, LastRowNumber(screen), visibleIChars(ld->charData, ld->lineSize))); memset(buffer, '#', SL_BUFSIZ); for (n = 0; n < screen->max_col; n += SL_BUFSIZ) { StatusPutChars(xw, buffer, right_margin - n); } } #endif CursorRestore2(xw, &save_me); screen->status_type = save_type; TRACE_SL("clear_status_line (done)"); } static void show_writable_status(XtermWidget xw) { TScreen *screen = TScreenOf(xw); TRACE(("show_writable_status (%d:%d) max=%d\n", FirstRowNumber(screen), LastRowNumber(screen), MaxRows(screen))); screen->cur_row = FirstRowNumber(screen); } /* * Depending the status-type, make the window grow or shrink by one row to * show or hide the status-line. Keep the rest of the window from scrolling * by overriding the resize-gravity. */ static void resize_status_line(XtermWidget xw) { TScreen *screen = TScreenOf(xw); XtGravity savedGravity = xw->misc.resizeGravity; TRACE_SL(screen->status_type ? "...resize to show status-line" : "...resize to hide status-line"); xw->misc.resizeGravity = NorthWestGravity; RequestResize(xw, MaxRows(screen), MaxCols(screen), True); xw->misc.resizeGravity = savedGravity; } /* * DEC STD 070, chapter 14 "VSRM - Status Display Extension" */ static void update_status_line(XtermWidget xw, int new_active, int new_type) { /* *INDENT-EQLS* */ TScreen *screen = TScreenOf(xw); int old_active = screen->status_active; int old_type = screen->status_type; int old_shown = screen->status_shown; TRACE_SL("update_status_line"); if (new_active >= 0 && new_active <= 1) { screen->status_active = new_active; if (old_active == new_active) { goto finish; } if (old_type < 2) { goto finish; } if (new_active && !old_active) { SL_SAVE(0); } } else if (new_type >= 0 && new_type <= 2) { screen->status_type = new_type; } else { goto finish; } if (screen->status_type == 1) { int next_shown = screen->status_type; if (screen->status_type != screen->status_shown) { if (screen->status_shown == 0) { resize_status_line(xw); } else { clear_status_line(xw); } } show_indicator_status(xw, NULL); if (screen->status_shown != next_shown) { screen->status_shown = next_shown; TRACE_SL("...updating shown"); } if (old_shown == 2) { SL_RESTORE(0); } } else if (screen->status_active) { if (screen->status_type != screen->status_shown) { Boolean do_resize = False; if (screen->status_type == 0) { if (screen->status_shown >= 2) { SL_SAVE2(); } do_resize = True; /* shrink... */ clear_status_line(xw); StatusInit(&screen->status_data[1]); } else if (screen->status_shown == 0) { if (screen->status_type >= 2) { SL_RESTORE2(); } do_resize = True; /* grow... */ } else { clear_status_line(xw); } if (do_resize) { resize_status_line(xw); } screen->status_shown = screen->status_type; TRACE_SL("...updating shown"); } show_writable_status(xw); } else { if (screen->status_shown) { if (screen->status_type != 0 && screen->status_type != screen->status_shown) { clear_status_line(xw); } if (screen->status_shown >= 2) { SL_SAVE2(); } if (screen->status_type == 0) { screen->status_timeout = False; clear_status_line(xw); StatusInit(&screen->status_data[1]); resize_status_line(xw); /* shrink... */ } screen->status_shown = screen->status_type; TRACE_SL("...updating shown"); } } finish: TRACE_SL("update_status_line (done)"); return; } /* * If the status-type is "2", we can switch the active status display back and * forth between the main-display and the status-line without clearing the * status-line (unless the status-line was not shown before). * * This has no effect if the status-line displays an indicator (type==1), * or if no status-line type was selected (type==0). */ static void handle_DECSASD(XtermWidget xw, int value) { TRACE(("CASE_DECSASD - select active status display: %s (currently %s)\n", BtoS(value), BtoS(TScreenOf(xw)->status_active))); if (AllowWindowOps(xw, ewStatusLine)) update_status_line(xw, value, -1); } /* * If the status-line is inactive (i.e., only the main-display is used), * changing the status-type between none/writable has no immediate effect. * * But if the status-line is active, setting the status-type reinitializes the * status-line. * * Setting the status-type to indicator overrides the DECSASD active-display * mode. */ static void handle_DECSSDT(XtermWidget xw, int value) { TRACE(("CASE_DECSSDT - select type of status display: %d (currently %d)\n", value, TScreenOf(xw)->status_type)); if (AllowWindowOps(xw, ewStatusLine)) update_status_line(xw, -1, value); } #else #define clear_status_line(xw) /* nothing */ #endif /* OPT_STATUS_LINE */ #if OPT_VT52_MODE static void update_vt52_vt100_settings(void) { update_autowrap(); update_reversewrap(); update_autolinefeed(); update_appcursor(); update_appkeypad(); update_allow132(); } #endif #define TRACE_GSETS(name) TRACE(("CASE_GSETS%s(%d) = '%c'\n", name, sp->scstype, AsciiOf(c))) static Boolean doparsing(XtermWidget xw, unsigned c, struct ParseState *sp) { TScreen *screen = TScreenOf(xw); int item; int count; int value; int laststate; int thischar = -1; XTermRect myRect; #if OPT_DEC_RECTOPS int thispage = 1; #endif if (sp->check_recur) { /* Defer parsing when parser is already running as the parser is not * safe to reenter. */ deferparsing(c, sp); return True; } sp->check_recur++; do { #if OPT_WIDE_CHARS int this_is_wide = 0; int is_formatter = 0; /* * Handle zero-width combining characters. Make it faster by noting * that according to the Unicode charts, the majority of Western * character sets do not use this feature. There are some unassigned * codes at 0x242, but no zero-width characters until past 0x300. */ if (c >= 0x300 && screen->wide_chars && CharWidth(screen, c) == 0 && !(is_formatter = (CharacterClass((int) c) == CNTRL))) { int prev, test; Boolean used = True; int use_row; int use_col; WriteNow(); use_row = (screen->char_was_written ? screen->last_written_row : screen->cur_row); use_col = (screen->char_was_written ? screen->last_written_col : screen->cur_col); /* * Check if the latest data can be added to the base character. * If there is already a combining character stored for the cell, * we cannot, since that would change the order. */ if (screen->normalized_c && !IsCellCombined(screen, use_row, use_col)) { prev = (int) XTERM_CELL(use_row, use_col); test = do_precomposition(prev, (int) c); TRACE(("do_precomposition (U+%04X [%d], U+%04X [%d]) -> U+%04X [%d]\n", prev, CharWidth(screen, prev), (int) c, CharWidth(screen, c), test, CharWidth(screen, test))); } else { prev = -1; test = -1; } /* substitute combined character with precomposed character * only if it does not change the width of the base character */ if (test != -1 && CharWidth(screen, test) == CharWidth(screen, prev)) { putXtermCell(screen, use_row, use_col, test); } else if (screen->char_was_written || getXtermCell(screen, use_row, use_col) >= ' ') { addXtermCombining(screen, use_row, use_col, c); } else { /* * none of the above... we will add the combining character as * a base character. */ used = False; } if (used) { if (!screen->scroll_amt) ScrnUpdate(xw, use_row, use_col, 1, 1, 1); break; } } #endif /* Intercept characters for printer controller mode */ if (PrinterOf(screen).printer_controlmode == 2) { if ((c = (unsigned) xtermPrinterControl(xw, (int) c)) == 0) break; } /* * VT52 is a little ugly in the one place it has a parameterized * control sequence, since the parameter falls after the character * that denotes the type of sequence. */ #if OPT_VT52_MODE if (sp->vt52_cup) { int row, col; if (nparam < NPARAM - 1) { SetParam(nparam++, (int) AsciiOf(c) - 32); parms.is_sub[nparam] = 0; } if (nparam < 2) break; sp->vt52_cup = False; /* * According to EK-VT5X-OP-001 DECscope User's Guide, if the row * is out of range, no vertical movement occurs, while if the * column is out of range, it is set to the rightmost column. * * However, DEC 070 (VSRM - VT52 Emulation EL-00070-0A, page A-28) * differs from that, updating the column only when the parameter * is in range, i.e., not mentioning the rightmost column. */ if ((row = GetParam(0)) > screen->max_row) row = screen->cur_row; if ((col = GetParam(1)) > screen->max_col) col = ((screen->terminal_id < 100) ? screen->max_col /* real VT52 */ : screen->cur_col); /* emulated VT52 */ CursorSet(screen, row, col, xw->flags); sp->parsestate = vt52_table; SetParam(0, 0); SetParam(1, 0); break; } #endif laststate = sp->nextstate; if (c == ANSI_DEL && sp->parsestate == sp->groundtable && sp->scssize == 96 && sp->scstype != 0) { /* * Handle special case of shifts for 96-character sets by checking * if we have a DEL. The other special case for SPACE will always * be printable. */ sp->nextstate = CASE_PRINT; } else #if OPT_WIDE_CHARS if (c > 255) { /* * The parsing tables all have 256 entries. If we're supporting * wide characters, we handle them by treating them the same as * printing characters. */ if (sp->parsestate == sp->groundtable) { sp->nextstate = is_formatter ? CASE_IGNORE : CASE_PRINT; } else if (sp->parsestate == sos_table) { if ((c & WIDEST_ICHAR) > 255) { TRACE(("Found code > 255 while in SOS state: %04X\n", c)); c = BAD_ASCII; } } else { sp->nextstate = CASE_GROUND_STATE; } } else #endif sp->nextstate = sp->parsestate[c]; #if OPT_BROKEN_OSC /* * Linux console palette escape sequences start with an OSC, but do * not terminate correctly. Some scripts do not check before writing * them, making xterm appear to hang (it's awaiting a valid string * terminator). Just ignore these if we see them - there's no point * in emulating bad code. */ if (screen->brokenLinuxOSC && sp->parsestate == sos_table) { if (sp->string_used && sp->string_area) { switch (sp->string_area[0]) { case 'P': if (sp->string_used <= 7) break; /* FALLTHRU */ case 'R': illegal_parse(xw, c, sp); TRACE(("Reset to ground state (brokenLinuxOSC)\n")); break; } } } #endif #if OPT_BROKEN_ST /* * Before patch #171, carriage control embedded within an OSC string * would terminate it. Some (buggy, of course) applications rely on * this behavior. Accommodate them by allowing one to compile xterm * and emulate the old behavior. */ if (screen->brokenStringTerm && sp->parsestate == sos_table && c < 32) { switch (c) { case ANSI_EOT: /* FALLTHRU */ case ANSI_BS: /* FALLTHRU */ case ANSI_HT: /* FALLTHRU */ case ANSI_LF: /* FALLTHRU */ case ANSI_VT: /* FALLTHRU */ case ANSI_FF: /* FALLTHRU */ case ANSI_CR: /* FALLTHRU */ case ANSI_SO: /* FALLTHRU */ case ANSI_SI: /* FALLTHRU */ case ANSI_XON: /* FALLTHRU */ case ANSI_CAN: illegal_parse(xw, c, sp); TRACE(("Reset to ground state (brokenStringTerm)\n")); break; } } #endif #if OPT_C1_PRINT /* * This is not completely foolproof, but will allow an application * with values in the C1 range to use them as printable characters, * provided that they are not intermixed with an escape sequence. */ #if OPT_WIDE_CHARS if (!screen->wide_chars) #endif if (screen->c1_printable && (c >= 128 && c < 256)) { sp->nextstate = (sp->parsestate == esc_table ? CASE_ESC_IGNORE : sp->parsestate[160]); TRACE(("allowC1Printable %04X %s ->%s\n", c, which_table(sp->parsestate), visibleVTparse(sp->nextstate))); } #endif #if OPT_WIDE_CHARS /* * If we have a C1 code and the c1_printable flag is not set, simply * ignore it when it was translated from UTF-8, unless the parse-state * tells us that a C1 would be legal. */ if (screen->wide_chars && (c >= 128 && c < 160)) { #if OPT_C1_PRINT if (screen->c1_printable) { sp->nextstate = CASE_PRINT; TRACE(("allowC1Printable %04X %s ->%s\n", c, which_table(sp->parsestate), visibleVTparse(sp->nextstate))); } else #endif if (sp->parsestate != ansi_table) sp->nextstate = CASE_IGNORE; } /* * If this character is a different width than the last one, put the * previous text into the buffer and draw it now. */ this_is_wide = isWide((int) c); if (this_is_wide != sp->last_was_wide) { WriteNow(); } #endif /* * Accumulate string for printable text. This may be 8/16-bit * characters. */ if (sp->nextstate == CASE_PRINT) { SafeAlloc(IChar, sp->print_area, sp->print_used, sp->print_size); if (new_string == NULL) { xtermWarning("Cannot allocate %lu bytes for printable text\n", (unsigned long) new_length); break; } SafeFree(sp->print_area, sp->print_size); #if OPT_VT52_MODE /* * Strip output text to 7-bits for VT52. We should do this for * VT100 also (which is a 7-bit device), but xterm has been * doing this for so long we shouldn't change this behavior. */ if (screen->vtXX_level < 1) c = AsciiOf(c); #endif sp->print_area[sp->print_used++] = (IChar) c; sp->lastchar = thischar = (int) c; #if OPT_WIDE_CHARS sp->last_was_wide = this_is_wide; #endif if (morePtyData(screen, VTbuffer)) { break; } } if (sp->nextstate == CASE_PRINT || (laststate == CASE_PRINT && sp->print_used)) { WriteNow(); } /* * Accumulate string for DCS, OSC controls * The string content should always be 8-bit characters. * * APC, PM and SOS are ignored; xterm currently does not use those. */ if (sp->parsestate == sos_table) { #if OPT_WIDE_CHARS /* * We cannot display codes above 255, but let's try to * accommodate the application a little by not aborting the * string. */ if ((c & WIDEST_ICHAR) > 255) { sp->nextstate = CASE_PRINT; c = BAD_ASCII; } #endif if (sp->string_mode == ANSI_APC || sp->string_mode == ANSI_PM || sp->string_mode == ANSI_SOS) { /* EMPTY */ } #if OPT_SIXEL_GRAPHICS else if (sp->string_args == sa_SIXEL) { /* avoid adding the string-terminator */ if (sos_table[CharOf(c)] == CASE_IGNORE) parse_sixel_char(AsciiOf(c)); } #endif else if (sp->string_skip) { sp->string_used++; } else if (sp->string_used >= screen->strings_max) { sp->string_skip = True; sp->string_used++; FreeAndNull(sp->string_area); sp->string_size = 0; } else { Boolean utf8Title; SafeAlloc(Char, sp->string_area, sp->string_used, sp->string_size); if (new_string == NULL) { xtermWarning("Cannot allocate %lu bytes for string mode %#02x\n", (unsigned long) new_length, sp->string_mode); break; } SafeFree(sp->string_area, sp->string_size); /* * Provide for special case where xterm allows an OSC string to * contain 8-bit data. Otherwise, ECMA-48 section 9 recommends * parsing controls with a 7-bit table, precluding the use of * 8-bit data. */ #if OPT_WIDE_CHARS utf8Title = (sp->string_mode == ANSI_OSC && IsSetUtf8Title(xw) && (sp->string_used >= 2) && (sp->string_area[0] == '0' || sp->string_area[0] == '2') && sp->string_area[1] == ';'); #else utf8Title = False; #endif /* * ReGIS and SIXEL data can be detected by skipping over (only) * parameters to the first non-parameter character and * inspecting it. Since both are DCS, we can also ignore OSC. */ sp->string_area[(sp->string_used)++] = (utf8Title ? CharOf(c) : AsciiOf(c)); if (sp->string_args < sa_LAST) { switch (c) { case ':': case ';': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break; case 'p': sp->string_args = sa_REGIS; break; case 'q': begin_sixel(xw, sp); break; default: sp->string_args = sa_LAST; break; } } } } else if (sp->parsestate != esc_table) { /* if we were accumulating, we're not any more */ sp->string_mode = 0; sp->string_used = 0; } DumpParams(); TRACE(("parse %04X -> %s %s (used=%lu)\n", c, visibleVTparse(sp->nextstate), which_table(sp->parsestate), (unsigned long) sp->string_used)); /* * If the parameter list has subparameters (tokens separated by ":") * reject any controls that do not accept subparameters. */ if (parms.has_subparams) { switch (sp->nextstate) { case CASE_GROUND_STATE: case CASE_CSI_IGNORE: case CASE_CAN: case CASE_SUB: /* FALLTHRU */ case CASE_ESC_DIGIT: case CASE_ESC_SEMI: case CASE_ESC_COLON: /* these states are required to parse parameter lists */ break; #if OPT_MOD_FKEYS case CASE_SET_MOD_FKEYS: #endif case CASE_SGR: TRACE(("...possible subparam usage\n")); break; case CASE_CSI_DEC_DOLLAR_STATE: case CASE_CSI_DOLLAR_STATE: case CASE_CSI_HASH_STATE: case CASE_CSI_EX_STATE: case CASE_CSI_QUOTE_STATE: case CASE_CSI_SPACE_STATE: case CASE_CSI_STAR_STATE: case CASE_CSI_TICK_STATE: case CASE_DEC2_STATE: case CASE_DEC3_STATE: case CASE_DEC_STATE: /* use this branch when we do not yet have the final character */ TRACE(("...unexpected subparam usage\n")); InitParams(); sp->nextstate = CASE_CSI_IGNORE; break; default: /* use this branch for cases where we have the final character * in the table that processed the parameter list. */ TRACE(("...unexpected subparam usage\n")); ResetState(sp); break; } } if (xw->work.palette_changed) { repaintWhenPaletteChanged(xw, sp); } #if OPT_STATUS_LINE /* * If we are currently writing to the status-line, ignore controls that * apply only to the full screen, or which use features which we will * not support in the status-line. */ if (IsStatusShown(screen) && (screen)->status_active) { switch (sp->nextstate) { case CASE_DECDHL: case CASE_DECSWL: case CASE_DECDWL: case CASE_CUU: case CASE_CUD: case CASE_VPA: case CASE_VPR: case CASE_ED: case CASE_TRACK_MOUSE: case CASE_DECSTBM: case CASE_DECALN: case CASE_GRAPHICS_ATTRIBUTES: case CASE_CAN: case CASE_SUB: case CASE_SPA: case CASE_EPA: case CASE_SU: case CASE_IND: case CASE_CPL: case CASE_CNL: case CASE_NEL: case CASE_RI: #if OPT_DEC_LOCATOR case CASE_DECEFR: case CASE_DECELR: case CASE_DECSLE: case CASE_DECRQLP: #endif #if OPT_DEC_RECTOPS case CASE_DECRQCRA: case CASE_DECCRA: case CASE_DECERA: case CASE_DECFRA: case CASE_DECSERA: case CASE_DECSACE: case CASE_DECCARA: case CASE_DECRARA: #endif ResetState(sp); sp->nextstate = -1; /* not a legal state */ break; } } #endif switch (sp->nextstate) { case CASE_PRINT: TRACE(("CASE_PRINT - printable characters\n")); break; case CASE_GROUND_STATE: TRACE(("CASE_GROUND_STATE - exit ignore mode\n")); ResetState(sp); break; case CASE_IGNORE: TRACE(("CASE_IGNORE - Ignore character %02X\n", c)); break; case CASE_CAN: /* * ECMA-48 5th edition (June 1991) documents CAN thusly: * *> CAN is used to indicate that the data preceding it in the data *> stream is in error. As a result, this data shall be ignored. *> The specific meaning of this control function shall be defined *> for each application and/or between sender and recipient. * * The scope of "preceding" is vague. DEC 070 clarifies it by * saying that the current control sequence is cancelled, and also * page 3-30, 3.5.4.4 Termination Conditions */ if (screen->terminal_id >= 100 && screen->terminal_id < 200) { IChar effect = ( #if OPT_WIDE_CHARS 0x2592 #else 2 #endif ); dotext(xw, screen->gsets[(int) (screen->curgl)], &effect, 1); } ResetState(sp); break; case CASE_SUB: TRACE(("CASE_SUB - substitute/show error\n")); /* * ECMA-48 5th edition (June 1991) documents SUB without describing * its effect. Earlier editions do not mention it. * * DEC's VT100 user guide documents SUB as having the same effect * as CAN (cancel), which displays the error character (see page 39 * for a note under "checkerboard characters", and page 42). * * The VT220 reference improves the visible effect (display as a * reverse "?"), as well as mentioning that device control * sequences also are cancelled. * * DEC 070 comments that a "half-tone blotch" is used with VT100, * etc. * * None of that applies to VT52. */ if (screen->terminal_id >= 100) { IChar effect = ( #if OPT_WIDE_CHARS (screen->terminal_id > 200) ? 0x2426 : 0x2592 #else 2 #endif ); dotext(xw, screen->gsets[(int) (screen->curgl)], &effect, 1); } ResetState(sp); break; case CASE_ENQ: TRACE(("CASE_ENQ - answerback\n")); if (((xw->keyboard.flags & MODE_SRM) == 0) ? (sp->check_recur == 0) : (sp->check_recur <= 1)) { for (count = 0; screen->answer_back[count] != 0; count++) unparseputc(xw, screen->answer_back[count]); unparse_end(xw); } break; case CASE_BELL: TRACE(("CASE_BELL - bell\n")); if (sp->string_mode == ANSI_OSC) { if (sp->string_area) { if (sp->string_used) sp->string_area[--(sp->string_used)] = '\0'; if (sp->check_recur <= 1) do_osc(xw, sp->string_area, sp->string_used, (int) c); } ResetState(sp); } else { /* bell */ Bell(xw, XkbBI_TerminalBell, 0); } break; case CASE_BS: TRACE(("CASE_BS - backspace\n")); CursorBack(xw, 1); break; case CASE_CR: TRACE(("CASE_CR\n")); CarriageReturn(xw); break; case CASE_ESC: if_OPT_VT52_MODE(screen, { sp->parsestate = vt52_esc_table; break; }); sp->parsestate = esc_table; break; #if OPT_VT52_MODE case CASE_VT52_CUP: TRACE(("CASE_VT52_CUP - VT52 cursor addressing\n")); sp->vt52_cup = True; ResetState(sp); break; case CASE_VT52_IGNORE: TRACE(("CASE_VT52_IGNORE - VT52 ignore-character\n")); sp->parsestate = vt52_ignore_table; break; #endif case CASE_VMOT: TRACE(("CASE_VMOT\n")); /* * form feed, line feed, vertical tab */ xtermAutoPrint(xw, c); xtermIndex(xw, 1); if (xw->flags & LINEFEED) CarriageReturn(xw); else if (screen->jumpscroll && !screen->fastscroll) do_xevents(xw); break; case CASE_CBT: TRACE(("CASE_CBT\n")); /* cursor backward tabulation */ count = one_if_default(0); while ((count-- > 0) && (TabToPrevStop(xw))) ; ResetState(sp); break; case CASE_CHT: TRACE(("CASE_CHT\n")); /* cursor forward tabulation */ count = one_if_default(0); while ((count-- > 0) && (TabToNextStop(xw))) ; ResetState(sp); break; case CASE_TAB: /* tab */ TabToNextStop(xw); break; case CASE_SI: screen->curgl = 0; if_OPT_VT52_MODE(screen, { ResetState(sp); }); break; case CASE_SO: screen->curgl = 1; if_OPT_VT52_MODE(screen, { ResetState(sp); }); break; case CASE_DECDHL: TRACE(("CASE_DECDHL - double-height line: %s\n", (AsciiOf(c) == '3') ? "top" : "bottom")); xterm_DECDHL(xw, AsciiOf(c) == '3'); ResetState(sp); break; case CASE_DECSWL: TRACE(("CASE_DECSWL - single-width line\n")); xterm_DECSWL(xw); ResetState(sp); break; case CASE_DECDWL: TRACE(("CASE_DECDWL - double-width line\n")); xterm_DECDWL(xw); ResetState(sp); break; case CASE_SCR_STATE: /* enter scr state */ sp->parsestate = scrtable; break; case CASE_SCS0_STATE: /* enter scs state 0 */ select_charset(sp, 0, 94); break; case CASE_SCS1_STATE: /* enter scs state 1 */ select_charset(sp, 1, 94); break; case CASE_SCS2_STATE: /* enter scs state 2 */ select_charset(sp, 2, 94); break; case CASE_SCS3_STATE: /* enter scs state 3 */ select_charset(sp, 3, 94); break; case CASE_SCS1A_STATE: /* enter scs state 1 */ select_charset(sp, 1, 96); break; case CASE_SCS2A_STATE: /* enter scs state 2 */ select_charset(sp, 2, 96); break; case CASE_SCS3A_STATE: /* enter scs state 3 */ select_charset(sp, 3, 96); break; case CASE_ESC_IGNORE: /* unknown escape sequence */ sp->parsestate = eigtable; break; case CASE_ESC_DIGIT: /* digit in csi or dec mode */ if (nparam > 0) { value = zero_if_default(nparam - 1); SetParam(nparam - 1, (10 * value) + (int) (AsciiOf(c) - '0')); if (GetParam(nparam - 1) > MAX_I_PARAM) SetParam(nparam - 1, MAX_I_PARAM); if (sp->parsestate == csi_table) sp->parsestate = csi2_table; } break; case CASE_ESC_SEMI: /* semicolon in csi or dec mode */ if (nparam < NPARAM) { parms.is_sub[nparam] = 0; SetParam(nparam++, DEFAULT); } if (sp->parsestate == csi_table) sp->parsestate = csi2_table; break; /* * A _few_ commands accept colon-separated subparameters. * Mark the parameter list so that we can exclude (most) bogus * commands with simple/fast checks. */ case CASE_ESC_COLON: if (nparam < NPARAM) { parms.has_subparams = 1; if (nparam == 0) { parms.is_sub[nparam] = 1; SetParam(nparam++, DEFAULT); } else if (parms.is_sub[nparam - 1] == 0) { parms.is_sub[nparam - 1] = 1; parms.is_sub[nparam] = 2; parms.params[nparam] = 0; ++nparam; } else { parms.is_sub[nparam] = 1 + parms.is_sub[nparam - 1]; parms.params[nparam] = 0; ++nparam; } } break; case CASE_DEC_STATE: /* enter dec mode */ sp->parsestate = dec_table; break; case CASE_DEC2_STATE: /* enter dec2 mode */ sp->parsestate = dec2_table; break; case CASE_DEC3_STATE: /* enter dec3 mode */ sp->parsestate = dec3_table; break; case CASE_ICH: TRACE(("CASE_ICH - insert char\n")); InsertChar(xw, (unsigned) one_if_default(0)); ResetState(sp); break; case CASE_CUU: TRACE(("CASE_CUU - cursor up\n")); CursorUp(screen, one_if_default(0)); ResetState(sp); break; case CASE_CUD: TRACE(("CASE_CUD - cursor down\n")); CursorDown(screen, one_if_default(0)); ResetState(sp); break; case CASE_CUF: TRACE(("CASE_CUF - cursor forward\n")); CursorForward(xw, one_if_default(0)); ResetState(sp); break; case CASE_CUB: TRACE(("CASE_CUB - cursor backward\n")); CursorBack(xw, one_if_default(0)); ResetState(sp); break; case CASE_CUP: TRACE(("CASE_CUP - cursor position\n")); if_OPT_XMC_GLITCH(screen, { Jump_XMC(xw); }); CursorSet(screen, one_if_default(0) - 1, one_if_default(1) - 1, xw->flags); ResetState(sp); break; case CASE_VPA: TRACE(("CASE_VPA - vertical position absolute\n")); CursorSet(screen, one_if_default(0) - 1, CursorCol(xw), xw->flags); ResetState(sp); break; case CASE_HPA: TRACE(("CASE_HPA - horizontal position absolute\n")); CursorSet(screen, CursorRow(xw), one_if_default(0) - 1, xw->flags); ResetState(sp); break; case CASE_VPR: TRACE(("CASE_VPR - vertical position relative\n")); CursorSet(screen, CursorRow(xw) + one_if_default(0), CursorCol(xw), xw->flags); ResetState(sp); break; case CASE_HPR: TRACE(("CASE_HPR - horizontal position relative\n")); CursorSet(screen, CursorRow(xw), CursorCol(xw) + one_if_default(0), xw->flags); ResetState(sp); break; case CASE_HP_BUGGY_LL: TRACE(("CASE_HP_BUGGY_LL\n")); /* Some HP-UX applications have the bug that they assume ESC F goes to the lower left corner of the screen, regardless of what terminfo says. */ if (screen->hp_ll_bc) CursorSet(screen, screen->max_row, 0, xw->flags); ResetState(sp); break; case CASE_ED: TRACE(("CASE_ED - erase display\n")); do_cd_xtra_scroll(xw, zero_if_default(0)); do_erase_display(xw, zero_if_default(0), OFF_PROTECT); ResetState(sp); break; case CASE_EL: TRACE(("CASE_EL - erase line\n")); do_erase_line(xw, zero_if_default(0), OFF_PROTECT); ResetState(sp); break; case CASE_ECH: TRACE(("CASE_ECH - erase char\n")); /* ECH */ do_erase_char(xw, one_if_default(0), OFF_PROTECT); ResetState(sp); break; case CASE_IL: TRACE(("CASE_IL - insert line\n")); InsertLine(xw, one_if_default(0)); ResetState(sp); break; case CASE_DL: TRACE(("CASE_DL - delete line\n")); DeleteLine(xw, one_if_default(0), True); ResetState(sp); break; case CASE_DCH: TRACE(("CASE_DCH - delete char\n")); DeleteChar(xw, (unsigned) one_if_default(0)); ResetState(sp); break; case CASE_TRACK_MOUSE: /* * A single parameter other than zero is always scroll-down. * A zero-parameter is used to reset the mouse mode, and is * not useful for scrolling anyway. */ if (nparam > 1 || GetParam(0) == 0) { CELL start; TRACE(("CASE_TRACK_MOUSE\n")); /* Track mouse as long as in window and between * specified rows */ start.row = one_if_default(2) - 1; start.col = GetParam(1) - 1; TrackMouse(xw, GetParam(0), &start, GetParam(3) - 1, GetParam(4) - 2); } else { TRACE(("CASE_SD - scroll down\n")); /* SD */ RevScroll(xw, one_if_default(0)); do_xevents(xw); } ResetState(sp); break; case CASE_SD: /* * Cater to ECMA-48's typographical error... */ TRACE(("CASE_SD - scroll down\n")); RevScroll(xw, one_if_default(0)); do_xevents(xw); ResetState(sp); break; case CASE_DECID: TRACE(("CASE_DECID\n")); if_OPT_VT52_MODE(screen, { /* * If xterm's started in VT52 mode, it's not emulating VT52 * within VT100, etc., so the terminal identifies differently. */ switch (screen->terminal_id) { case 50: value = 'A'; break; case 52: value = 'K'; break; case 55: value = 'C'; break; default: value = 'Z'; break; } unparseputc(xw, ANSI_ESC); unparseputc(xw, '/'); unparseputc(xw, value); unparse_end(xw); ResetState(sp); break; }); SetParam(0, DEFAULT); /* Default ID parameter */ /* FALLTHRU */ case CASE_DA1: TRACE(("CASE_DA1\n")); if (GetParam(0) <= 0) { /* less than means DEFAULT */ count = 0; init_reply(ANSI_CSI); reply.a_pintro = '?'; /* * The first parameter corresponds to the highest operating * level (i.e., service level) of the emulation. A DEC * terminal can be setup to respond with a different DA * response, but there's no control sequence that modifies * this. We set it via a resource. */ if (screen->display_da1 < 200) { switch (screen->display_da1) { case 132: reply.a_param[count++] = 4; /* VT132 */ #if OPT_REGIS_GRAPHICS reply.a_param[count++] = 6; /* no STP, AVO, GPO (ReGIS) */ #else reply.a_param[count++] = 2; /* no STP, AVO, no GPO (ReGIS) */ #endif break; case 131: reply.a_param[count++] = 7; /* VT131 */ break; case 125: reply.a_param[count++] = 12; /* VT125 */ #if OPT_REGIS_GRAPHICS reply.a_param[count++] = 0 | 2 | 1; /* no STP, AVO, GPO (ReGIS) */ #else reply.a_param[count++] = 0 | 2 | 0; /* no STP, AVO, no GPO (ReGIS) */ #endif reply.a_param[count++] = 0; /* no printer */ reply.a_param[count++] = XTERM_PATCH; /* ROM version */ break; case 102: reply.a_param[count++] = 6; /* VT102 */ break; case 101: reply.a_param[count++] = 1; /* VT101 */ reply.a_param[count++] = 0; /* no options */ break; default: /* VT100 */ reply.a_param[count++] = 1; /* VT100 */ reply.a_param[count++] = 2; /* no STP, AVO, no GPO (ReGIS) */ break; } } else { reply.a_param[count++] = (ParmType) (60 + screen->display_da1 / 100); reply.a_param[count++] = 1; /* 132-columns */ reply.a_param[count++] = 2; /* printer */ #if OPT_REGIS_GRAPHICS if (optRegisGraphics(screen)) { reply.a_param[count++] = 3; /* ReGIS graphics */ } #endif #if OPT_SIXEL_GRAPHICS if (optSixelGraphics(screen)) { reply.a_param[count++] = 4; /* sixel graphics */ } #endif reply.a_param[count++] = 6; /* selective-erase */ #if OPT_SUNPC_KBD if (xw->keyboard.type == keyboardIsVT220) #endif reply.a_param[count++] = 8; /* user-defined-keys */ reply.a_param[count++] = 9; /* national replacement charsets */ reply.a_param[count++] = 15; /* technical characters */ reply.a_param[count++] = 16; /* locator port */ if (screen->display_da1 >= 400) { reply.a_param[count++] = 17; /* terminal state interrogation */ reply.a_param[count++] = 18; /* windowing extension */ reply.a_param[count++] = 21; /* horizontal scrolling */ } if_OPT_ISO_COLORS(screen, { reply.a_param[count++] = 22; /* ANSI color, VT525 */ }); reply.a_param[count++] = 28; /* rectangular editing */ #if OPT_DEC_LOCATOR reply.a_param[count++] = 29; /* ANSI text locator */ #endif } reply.a_nparam = (ParmType) count; reply.a_final = 'c'; unparseseq(xw, &reply); } ResetState(sp); break; case CASE_DA2: TRACE(("CASE_DA2\n")); if (GetParam(0) <= 0) { /* less than means DEFAULT */ count = 0; init_reply(ANSI_CSI); reply.a_pintro = '>'; if (screen->terminal_id >= 200) { switch (screen->terminal_id) { case 220: default: reply.a_param[count++] = 1; /* VT220 */ break; case 240: case 241: /* http://www.decuslib.com/DECUS/vax87a/gendyn/vt200_kind.lis */ reply.a_param[count++] = 2; /* VT240 */ break; case 320: /* http://www.vt100.net/docs/vt320-uu/appendixe.html */ reply.a_param[count++] = 24; /* VT320 */ break; case 330: reply.a_param[count++] = 18; /* VT330 */ break; case 340: reply.a_param[count++] = 19; /* VT340 */ break; case 382: reply.a_param[count++] = 32; /* VT382 */ break; case 420: reply.a_param[count++] = 41; /* VT420 */ break; case 510: /* http://www.vt100.net/docs/vt510-rm/DA2 */ reply.a_param[count++] = 61; /* VT510 */ break; case 520: reply.a_param[count++] = 64; /* VT520 */ break; case 525: reply.a_param[count++] = 65; /* VT525 */ break; } } else { reply.a_param[count++] = 0; /* VT100 (nonstandard) */ } reply.a_param[count++] = XTERM_PATCH; /* Version */ reply.a_param[count++] = 0; /* options (none) */ reply.a_nparam = (ParmType) count; reply.a_final = 'c'; unparseseq(xw, &reply); } ResetState(sp); break; case CASE_DECRPTUI: TRACE(("CASE_DECRPTUI\n")); if ((screen->vtXX_level >= 4) && (GetParam(0) <= 0)) { /* less than means DEFAULT */ unparseputc1(xw, ANSI_DCS); unparseputc(xw, '!'); unparseputc(xw, '|'); /* report the "terminal unit id" as 4 pairs of hexadecimal * digits -- meaningless for a terminal emulator, but some * host may care about the format. */ for (count = 0; count < 8; ++count) { unparseputc(xw, '0'); } unparseputc1(xw, ANSI_ST); unparse_end(xw); } ResetState(sp); break; case CASE_TBC: TRACE(("CASE_TBC - tab clear\n")); if ((value = GetParam(0)) <= 0) /* less than means default */ TabClear(xw->tabs, screen->cur_col); else if (value == 3) TabZonk(xw->tabs); ResetState(sp); break; case CASE_SET: TRACE(("CASE_SET - set mode\n")); ansi_modes(xw, bitset); ResetState(sp); break; case CASE_RST: TRACE(("CASE_RST - reset mode\n")); ansi_modes(xw, bitclr); ResetState(sp); break; case CASE_SGR: for (item = 0; item < nparam; ++item) { int op = GetParam(item); int skip; if_OPT_XMC_GLITCH(screen, { Mark_XMC(xw, op); }); TRACE(("CASE_SGR %d\n", op)); /* * Only SGR 38/48 accept subparameters, and in those cases * the values will not be seen at this point. */ if ((skip = param_has_subparams(item)) != 0) { switch (op) { case 38: /* FALLTHRU */ case 48: if_OPT_ISO_COLORS(screen, { break; }); /* FALLTHRU */ default: TRACE(("...unexpected subparameter in SGR\n")); item += skip; /* ignore this */ op = 9999; /* will never use this, anyway */ break; } } switch (op) { case DEFAULT: /* FALLTHRU */ case 0: resetRendition(xw); if_OPT_ISO_COLORS(screen, { reset_SGR_Colors(xw); }); break; case 1: /* Bold */ UIntSet(xw->flags, BOLD); if_OPT_ISO_COLORS(screen, { setExtendedFG(xw); }); break; #if OPT_WIDE_ATTRS case 2: /* faint, decreased intensity or second colour */ UIntSet(xw->flags, ATR_FAINT); if_OPT_ISO_COLORS(screen, { setExtendedFG(xw); }); break; case 3: /* italicized */ setItalicFont(xw, UseItalicFont(screen)); UIntSet(xw->flags, ATR_ITALIC); if_OPT_ISO_COLORS(screen, { setExtendedFG(xw); }); break; #endif case 4: /* Underscore */ UIntSet(xw->flags, UNDERLINE); if_OPT_ISO_COLORS(screen, { setExtendedFG(xw); }); break; case 5: /* Blink (less than 150 per minute) */ /* FALLTHRU */ case 6: /* Blink (150 per minute, or more) */ UIntSet(xw->flags, BLINK); StartBlinking(xw); if_OPT_ISO_COLORS(screen, { setExtendedFG(xw); }); break; case 7: UIntSet(xw->flags, INVERSE); if_OPT_ISO_COLORS(screen, { setExtendedBG(xw); }); break; case 8: UIntSet(xw->flags, INVISIBLE); break; #if OPT_WIDE_ATTRS case 9: /* crossed-out characters */ UIntSet(xw->flags, ATR_STRIKEOUT); break; #endif #if OPT_WIDE_ATTRS case 21: /* doubly-underlined */ UIntSet(xw->flags, ATR_DBL_UNDER); break; #endif case 22: /* reset 'bold' */ UIntClr(xw->flags, BOLD); #if OPT_WIDE_ATTRS UIntClr(xw->flags, ATR_FAINT); #endif if_OPT_ISO_COLORS(screen, { setExtendedFG(xw); }); break; #if OPT_WIDE_ATTRS case 23: /* not italicized */ ResetItalics(xw); if_OPT_ISO_COLORS(screen, { setExtendedFG(xw); }); break; #endif case 24: UIntClr(xw->flags, UNDERLINE); #if OPT_WIDE_ATTRS UIntClr(xw->flags, ATR_DBL_UNDER); #endif if_OPT_ISO_COLORS(screen, { setExtendedFG(xw); }); break; case 25: /* reset 'blink' */ UIntClr(xw->flags, BLINK); if_OPT_ISO_COLORS(screen, { setExtendedFG(xw); }); break; case 27: UIntClr(xw->flags, INVERSE); if_OPT_ISO_COLORS(screen, { setExtendedBG(xw); }); break; case 28: UIntClr(xw->flags, INVISIBLE); break; #if OPT_WIDE_ATTRS case 29: /* not crossed out */ UIntClr(xw->flags, ATR_STRIKEOUT); break; #endif case 30: /* FALLTHRU */ case 31: /* FALLTHRU */ case 32: /* FALLTHRU */ case 33: /* FALLTHRU */ case 34: /* FALLTHRU */ case 35: /* FALLTHRU */ case 36: /* FALLTHRU */ case 37: if_OPT_ISO_COLORS(screen, { xw->sgr_foreground = (op - 30); xw->sgr_38_xcolors = False; clrDirectFG(xw->flags); setExtendedFG(xw); }); break; case 38: /* This is more complicated than I'd like, but it should * properly eat all the parameters for unsupported modes. */ if_OPT_ISO_COLORS(screen, { Boolean extended; if (parse_extended_colors(xw, &value, &item, &extended)) { xw->sgr_foreground = value; xw->sgr_38_xcolors = True; setDirectFG(xw->flags, extended); setExtendedFG(xw); } }); break; case 39: if_OPT_ISO_COLORS(screen, { reset_SGR_Foreground(xw); }); break; case 40: /* FALLTHRU */ case 41: /* FALLTHRU */ case 42: /* FALLTHRU */ case 43: /* FALLTHRU */ case 44: /* FALLTHRU */ case 45: /* FALLTHRU */ case 46: /* FALLTHRU */ case 47: if_OPT_ISO_COLORS(screen, { xw->sgr_background = (op - 40); clrDirectBG(xw->flags); setExtendedBG(xw); }); break; case 48: if_OPT_ISO_COLORS(screen, { Boolean extended; if (parse_extended_colors(xw, &value, &item, &extended)) { xw->sgr_background = value; setDirectBG(xw->flags, extended); setExtendedBG(xw); } }); break; case 49: if_OPT_ISO_COLORS(screen, { reset_SGR_Background(xw); }); break; case 90: /* FALLTHRU */ case 91: /* FALLTHRU */ case 92: /* FALLTHRU */ case 93: /* FALLTHRU */ case 94: /* FALLTHRU */ case 95: /* FALLTHRU */ case 96: /* FALLTHRU */ case 97: if_OPT_AIX_COLORS(screen, { xw->sgr_foreground = (op - 90 + 8); clrDirectFG(xw->flags); setExtendedFG(xw); }); break; case 100: #if !OPT_AIX_COLORS if_OPT_ISO_COLORS(screen, { reset_SGR_Foreground(xw); reset_SGR_Background(xw); }); break; #endif case 101: /* FALLTHRU */ case 102: /* FALLTHRU */ case 103: /* FALLTHRU */ case 104: /* FALLTHRU */ case 105: /* FALLTHRU */ case 106: /* FALLTHRU */ case 107: if_OPT_AIX_COLORS(screen, { xw->sgr_background = (op - 100 + 8); clrDirectBG(xw->flags); setExtendedBG(xw); }); break; default: /* later: skip += NPARAM; */ break; } } ResetState(sp); break; /* DSR (except for the '?') is a superset of CPR */ case CASE_DSR: sp->private_function = True; /* FALLTHRU */ case CASE_CPR: TRACE(("CASE_DSR - device status report\n")); count = 0; init_reply(ANSI_CSI); reply.a_pintro = CharOf(sp->private_function ? '?' : 0); reply.a_final = 'n'; switch (GetParam(0)) { case 5: TRACE(("...request operating status\n")); /* operating status */ reply.a_param[count++] = 0; /* (no malfunction ;-) */ break; case 6: TRACE(("...request %s\n", (sp->private_function ? "DECXCPR" : "CPR"))); /* CPR */ /* DECXCPR (with page=1) */ value = screen->cur_row; if ((xw->flags & ORIGIN) != 0) { value -= screen->top_marg; } if_STATUS_LINE(screen, { if ((value -= LastRowNumber(screen)) < 0) value = 0; }); reply.a_param[count++] = (ParmType) (value + 1); value = (screen->cur_col + 1); if ((xw->flags & ORIGIN) != 0) { value -= screen->lft_marg; } reply.a_param[count++] = (ParmType) value; if (sp->private_function && (screen->vtXX_level >= 4 || (screen->terminal_id >= 330 && screen->vtXX_level >= 3))) { /* VT330 (not VT320) and VT420 */ reply.a_param[count++] = 1; } reply.a_final = 'R'; break; case 15: TRACE(("...request printer status\n")); if (sp->private_function && screen->vtXX_level >= 2) { /* VT220 */ reply.a_param[count++] = 13; /* no printer detected */ } break; case 25: TRACE(("...request UDK status\n")); if (sp->private_function && screen->vtXX_level >= 2) { /* VT220 */ reply.a_param[count++] = 20; /* UDK always unlocked */ } break; case 26: TRACE(("...request keyboard status\n")); if (sp->private_function && screen->vtXX_level >= 2) { /* VT220 */ reply.a_param[count++] = 27; reply.a_param[count++] = 1; /* North American */ if (screen->vtXX_level >= 3) { /* VT320 */ reply.a_param[count++] = 0; /* ready */ } if (screen->vtXX_level >= 4) { /* VT420 */ reply.a_param[count++] = 0; /* LK201 */ } } break; case 55: /* according to the VT330/VT340 Text Programming Manual */ TRACE(("...request locator status\n")); if (sp->private_function && screen->vtXX_level >= 3) { /* VT330 */ #if OPT_DEC_LOCATOR reply.a_param[count++] = 50; /* locator ready */ #else reply.a_param[count++] = 53; /* no locator */ #endif } break; case 56: TRACE(("...request locator type\n")); if (sp->private_function && screen->vtXX_level >= 3) { /* VT330 */ reply.a_param[count++] = 57; #if OPT_DEC_LOCATOR reply.a_param[count++] = 1; /* mouse */ #else reply.a_param[count++] = 0; /* unknown */ #endif } break; case 62: TRACE(("...request DECMSR - macro space\n")); if (sp->private_function && screen->vtXX_level >= 4) { /* VT420 */ reply.a_pintro = 0; reply.a_radix[count] = 16; /* no data */ reply.a_param[count++] = 0; /* no space for macros */ reply.a_inters = '*'; reply.a_final = L_CURL; } break; case 63: TRACE(("...request DECCKSR - memory checksum\n")); /* DECCKSR - Memory checksum */ if (sp->private_function && screen->vtXX_level >= 4) { /* VT420 */ init_reply(ANSI_DCS); reply.a_param[count++] = (ParmType) GetParam(1); /* PID */ reply.a_delim = "!~"; /* delimiter */ reply.a_radix[count] = 16; /* use hex */ reply.a_param[count++] = 0; /* no data */ } break; case 75: TRACE(("...request data integrity\n")); if (sp->private_function && screen->vtXX_level >= 4) { /* VT420 */ reply.a_param[count++] = 70; /* no errors */ } break; case 85: TRACE(("...request multi-session configuration\n")); if (sp->private_function && screen->vtXX_level >= 4) { /* VT420 */ reply.a_param[count++] = 83; /* not configured */ } break; default: break; } if ((reply.a_nparam = (ParmType) count) != 0) unparseseq(xw, &reply); ResetState(sp); sp->private_function = False; break; case CASE_MC: TRACE(("CASE_MC - media control\n")); xtermMediaControl(xw, GetParam(0), False); ResetState(sp); break; case CASE_DEC_MC: TRACE(("CASE_DEC_MC - DEC media control\n")); xtermMediaControl(xw, GetParam(0), True); ResetState(sp); break; case CASE_HP_MEM_LOCK: /* FALLTHRU */ case CASE_HP_MEM_UNLOCK: TRACE(("%s\n", ((sp->parsestate[c] == CASE_HP_MEM_LOCK) ? "CASE_HP_MEM_LOCK" : "CASE_HP_MEM_UNLOCK"))); if (screen->scroll_amt) FlushScroll(xw); if (sp->parsestate[c] == CASE_HP_MEM_LOCK) set_tb_margins(screen, screen->cur_row, screen->bot_marg); else set_tb_margins(screen, 0, screen->bot_marg); ResetState(sp); break; case CASE_DECSTBM: TRACE(("CASE_DECSTBM - set scrolling region\n")); { int top; int bot; top = one_if_default(0); if (nparam < 2 || (bot = GetParam(1)) == DEFAULT || bot > MaxRows(screen) || bot == 0) bot = MaxRows(screen); if (bot > top) { if (screen->scroll_amt) FlushScroll(xw); set_tb_margins(screen, top - 1, bot - 1); CursorSet(screen, 0, 0, xw->flags); } ResetState(sp); } break; case CASE_DECREQTPARM: TRACE(("CASE_DECREQTPARM\n")); if (screen->terminal_id < 200) { /* VT102 */ value = zero_if_default(0); if (value == 0 || value == 1) { init_reply(ANSI_CSI); reply.a_nparam = 7; reply.a_param[0] = (ParmType) (value + 2); reply.a_param[1] = 1; /* no parity */ reply.a_param[2] = 1; /* eight bits */ reply.a_param[3] = 128; /* transmit 38.4k baud */ reply.a_param[4] = 128; /* receive 38.4k baud */ reply.a_param[5] = 1; /* clock multiplier ? */ reply.a_param[6] = 0; /* STP flags ? */ reply.a_final = 'x'; unparseseq(xw, &reply); } } ResetState(sp); break; case CASE_DECSET: /* DECSET */ #if OPT_VT52_MODE if (screen->vtXX_level != 0) #endif dpmodes(xw, bitset); ResetState(sp); #if OPT_TEK4014 if (TEK4014_ACTIVE(xw)) { TRACE(("Tek4014 is now active...\n")); if (sp->check_recur) sp->check_recur--; return False; } #endif break; case CASE_DECRST: /* DECRST */ dpmodes(xw, bitclr); init_groundtable(screen, sp); ResetState(sp); break; case CASE_DECALN: TRACE(("CASE_DECALN - alignment test\n")); if (screen->cursor_state) HideCursor(xw); /* * DEC STD 070 (see pages D-19 to D-20) does not mention left/right * margins. The section is dated March 1985, not updated for the * VT420 (introduced in 1990). */ UIntClr(xw->flags, ORIGIN); screen->do_wrap = False; resetRendition(xw); resetMargins(xw); xterm_ResetDouble(xw); CursorSet(screen, 0, 0, xw->flags); xtermParseRect(xw, 0, NULL, &myRect); ScrnFillRectangle(xw, &myRect, 'E', nrc_ASCII, 0, False); ResetState(sp); break; case CASE_GSETS5: if (screen->vtXX_level >= 5) { TRACE_GSETS("5"); xtermDecodeSCS(xw, sp->scstype, 5, 0, (int) c); } ResetState(sp); break; case CASE_GSETS3: if (screen->vtXX_level >= 3) { TRACE_GSETS("3"); xtermDecodeSCS(xw, sp->scstype, 3, 0, (int) c); } ResetState(sp); break; case CASE_GSETS: if (strchr("012AB", AsciiOf(c)) != NULL) { TRACE_GSETS(""); xtermDecodeSCS(xw, sp->scstype, 1, 0, (int) c); } else if (screen->vtXX_level >= 2) { TRACE_GSETS(""); xtermDecodeSCS(xw, sp->scstype, 2, 0, (int) c); } ResetState(sp); break; case CASE_ANSI_SC: if (IsLeftRightMode(xw)) { int left; int right; TRACE(("CASE_DECSLRM - set left and right margin\n")); left = one_if_default(0); if (nparam < 2 || (right = GetParam(1)) == DEFAULT || right > MaxCols(screen) || right == 0) right = MaxCols(screen); if (right > left) { set_lr_margins(screen, left - 1, right - 1); CursorSet(screen, 0, 0, xw->flags); } } else if (only_default()) { TRACE(("CASE_ANSI_SC - save cursor\n")); CursorSave(xw); } ResetState(sp); break; case CASE_DECSC: TRACE(("CASE_DECSC - save cursor\n")); CursorSave(xw); ResetState(sp); break; case CASE_ANSI_RC: if (!only_default()) break; /* FALLTHRU */ case CASE_DECRC: TRACE(("CASE_%sRC - restore cursor\n", (sp->nextstate == CASE_DECRC) ? "DEC" : "ANSI_")); CursorRestore(xw); if_OPT_ISO_COLORS(screen, { setExtendedFG(xw); }); ResetState(sp); break; case CASE_DECKPAM: TRACE(("CASE_DECKPAM\n")); xw->keyboard.flags |= MODE_DECKPAM; update_appkeypad(); ResetState(sp); break; case CASE_DECKPNM: TRACE(("CASE_DECKPNM\n")); UIntClr(xw->keyboard.flags, MODE_DECKPAM); update_appkeypad(); ResetState(sp); break; case CASE_CSI_QUOTE_STATE: sp->parsestate = csi_quo_table; break; #if OPT_BLINK_CURS case CASE_CSI_SPACE_STATE: sp->parsestate = csi_sp_table; break; case CASE_DECSCUSR: TRACE(("CASE_DECSCUSR\n")); { Boolean change; int blinks = screen->cursor_blink_esc; XtCursorShape shapes = screen->cursor_shape; HideCursor(xw); switch (GetParam(0)) { case DEFAULT: /* FALLTHRU */ case DEFAULT_STYLE: /* FALLTHRU */ case BLINK_BLOCK: blinks = True; screen->cursor_shape = CURSOR_BLOCK; break; case STEADY_BLOCK: blinks = False; screen->cursor_shape = CURSOR_BLOCK; break; case BLINK_UNDERLINE: blinks = True; screen->cursor_shape = CURSOR_UNDERLINE; break; case STEADY_UNDERLINE: blinks = False; screen->cursor_shape = CURSOR_UNDERLINE; break; case BLINK_BAR: blinks = True; screen->cursor_shape = CURSOR_BAR; break; case STEADY_BAR: blinks = False; screen->cursor_shape = CURSOR_BAR; break; } change = (blinks != screen->cursor_blink_esc || shapes != screen->cursor_shape); TRACE(("cursor_shape:%d blinks:%d%s\n", screen->cursor_shape, blinks, change ? " (changed)" : "")); if (change) { xtermSetCursorBox(screen); if (SettableCursorBlink(screen)) { screen->cursor_blink_esc = blinks; UpdateCursorBlink(xw); } } } ResetState(sp); break; #endif #if OPT_SCROLL_LOCK case CASE_DECLL: TRACE(("CASE_DECLL\n")); if (nparam > 0) { for (count = 0; count < nparam; ++count) { int op = zero_if_default(count); switch (op) { case 0: case DEFAULT: xtermClearLEDs(screen); break; case 1: /* FALLTHRU */ case 2: /* FALLTHRU */ case 3: xtermShowLED(screen, (Cardinal) op, True); break; case 21: /* FALLTHRU */ case 22: /* FALLTHRU */ case 23: xtermShowLED(screen, (Cardinal) (op - 20), True); break; } } } else { xtermClearLEDs(screen); } ResetState(sp); break; #endif #if OPT_VT52_MODE case CASE_VT52_FINISH: TRACE(("CASE_VT52_FINISH terminal_id %d, vtXX_level %d\n", screen->terminal_id, screen->vtXX_level)); if (screen->terminal_id >= 100 && screen->vtXX_level == 0) { sp->groundtable = sp->parsestate = ansi_table; /* * On restore, the terminal does not recognize DECRQSS for * DECSCL (per vttest). */ set_vtXX_level(screen, 1); xw->flags = screen->vt52_save_flags; screen->curgl = screen->vt52_save_curgl; screen->curgr = screen->vt52_save_curgr; screen->curss = screen->vt52_save_curss; restoreCharsets(screen, screen->vt52_save_gsets); update_vt52_vt100_settings(); } break; #endif case CASE_ANSI_LEVEL_1: TRACE(("CASE_ANSI_LEVEL_1\n")); set_ansi_conformance(screen, 1); ResetState(sp); break; case CASE_ANSI_LEVEL_2: TRACE(("CASE_ANSI_LEVEL_2\n")); set_ansi_conformance(screen, 2); ResetState(sp); break; case CASE_ANSI_LEVEL_3: TRACE(("CASE_ANSI_LEVEL_3\n")); set_ansi_conformance(screen, 3); ResetState(sp); break; case CASE_DECSCL: TRACE(("CASE_DECSCL(%d,%d)\n", GetParam(0), GetParam(1))); /* * This changes the emulation level, and is not recognized by * VT100s. However, a VT220 or above can be set to conformance * level 1 to act like a VT100. */ if (screen->terminal_id >= 200) { /* * Disallow unrecognized parameters, as well as attempts to set * the operating level higher than the given terminal-id. */ if (GetParam(0) >= 61 && GetParam(0) <= 60 + (screen->terminal_id / 100)) { int new_vtXX_level = GetParam(0) - 60; int case_value = zero_if_default(1); /* * Note: * * The VT300, VT420, VT520 manuals claim that DECSCL does a * hard reset (RIS). * * Both the VT220 manual and DEC STD 070 (which documents * levels 1-4 in detail) state that it is a soft reset. * * Perhaps both sets of manuals are right (unlikely). * Kermit says it's soft. */ ReallyReset(xw, False, False); init_parser(xw, sp); set_vtXX_level(screen, new_vtXX_level); if (new_vtXX_level > 1) { switch (case_value) { case 1: show_8bit_control(False); break; case 0: case 2: show_8bit_control(True); break; } } } } ResetState(sp); break; case CASE_DECSCA: TRACE(("CASE_DECSCA\n")); screen->protected_mode = DEC_PROTECT; if (GetParam(0) <= 0 || GetParam(0) == 2) { UIntClr(xw->flags, PROTECTED); TRACE(("...clear PROTECTED\n")); } else if (GetParam(0) == 1) { xw->flags |= PROTECTED; TRACE(("...set PROTECTED\n")); } ResetState(sp); break; case CASE_DECSED: TRACE(("CASE_DECSED\n")); do_erase_display(xw, zero_if_default(0), DEC_PROTECT); ResetState(sp); break; case CASE_DECSEL: TRACE(("CASE_DECSEL\n")); do_erase_line(xw, zero_if_default(0), DEC_PROTECT); ResetState(sp); break; case CASE_GRAPHICS_ATTRIBUTES: #if OPT_GRAPHICS TRACE(("CASE_GRAPHICS_ATTRIBUTES\n")); { /* request: item, action, value */ /* reply: item, status, value */ if (nparam != 3) { TRACE(("DATA_ERROR: malformed CASE_GRAPHICS_ATTRIBUTES request with %d parameters\n", nparam)); } else { int status = 3; /* assume failure */ int result = 0; int result2 = 0; TRACE(("CASE_GRAPHICS_ATTRIBUTES request: %d, %d, %d\n", GetParam(0), GetParam(1), GetParam(2))); switch (GetParam(0)) { case 1: /* color register count */ switch (GetParam(1)) { case 1: /* read */ status = 0; /* success */ result = (int) get_color_register_count(screen); break; case 2: /* reset */ screen->numcolorregisters = 0; status = 0; /* success */ result = (int) get_color_register_count(screen); break; case 3: /* set */ if (GetParam(2) > 1 && (unsigned) GetParam(2) <= MAX_COLOR_REGISTERS) { screen->numcolorregisters = GetParam(2); status = 0; /* success */ result = (int) get_color_register_count(screen); } break; case 4: /* read maximum */ status = 0; /* success */ result = MAX_COLOR_REGISTERS; break; default: TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES color register count request with unknown action parameter: %d\n", GetParam(1))); status = 2; /* error in Pa */ break; } if (status == 0 && !(optSixelGraphics(screen) || optRegisGraphics(screen))) status = 3; break; # if OPT_SIXEL_GRAPHICS case 2: /* graphics geometry */ switch (GetParam(1)) { case 1: /* read */ TRACE(("Get sixel graphics geometry\n")); status = 0; /* success */ result = Min(Width(screen), (int) screen->graphics_max_wide); result2 = Min(Height(screen), (int) screen->graphics_max_high); break; case 2: /* reset */ /* FALLTHRU */ case 3: /* set */ break; case 4: /* read maximum */ status = 0; /* success */ result = screen->graphics_max_wide; result2 = screen->graphics_max_high; break; default: TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES graphics geometry request with unknown action parameter: %d\n", GetParam(1))); status = 2; /* error in Pa */ break; } if (status == 0 && !optSixelGraphics(screen)) status = 3; break; #endif # if OPT_REGIS_GRAPHICS case 3: /* ReGIS geometry */ switch (GetParam(1)) { case 1: /* read */ status = 0; /* success */ result = screen->graphics_regis_def_wide; result2 = screen->graphics_regis_def_high; break; case 2: /* reset */ /* FALLTHRU */ case 3: /* set */ /* FALLTHRU */ case 4: /* read maximum */ /* not implemented */ break; default: TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES ReGIS geometry request with unknown action parameter: %d\n", GetParam(1))); status = 2; /* error in Pa */ break; } if (status == 0 && !optRegisGraphics(screen)) status = 3; break; #endif default: TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES request with unknown item parameter: %d\n", GetParam(0))); status = 1; break; } init_reply(ANSI_CSI); reply.a_pintro = '?'; count = 0; reply.a_param[count++] = (ParmType) GetParam(0); reply.a_param[count++] = (ParmType) status; if (status == 0) { reply.a_param[count++] = (ParmType) result; if (GetParam(0) >= 2) reply.a_param[count++] = (ParmType) result2; } reply.a_nparam = (ParmType) count; reply.a_final = 'S'; unparseseq(xw, &reply); } } #endif ResetState(sp); break; case CASE_ST: TRACE(("CASE_ST: End of String (%lu bytes) (mode=%d)\n", (unsigned long) sp->string_used, sp->string_mode)); ResetState(sp); if (!sp->string_used && !sp->string_args) break; if (sp->string_skip) { xtermWarning("Ignoring too-long string (%lu) for mode %#02x\n", (unsigned long) sp->string_used, sp->string_mode); sp->string_skip = False; sp->string_used = 0; } else { if (sp->string_used) sp->string_area[--(sp->string_used)] = '\0'; if (sp->check_recur <= 1) { switch (sp->string_mode) { case ANSI_APC: /* ignored */ break; case ANSI_DCS: #if OPT_SIXEL_GRAPHICS if (sp->string_args == sa_SIXEL) { parse_sixel_finished(); TRACE(("DONE parsed sixel data\n")); } else #endif do_dcs(xw, sp->string_area, sp->string_used); break; case ANSI_OSC: do_osc(xw, sp->string_area, sp->string_used, ANSI_ST); break; case ANSI_PM: /* ignored */ break; case ANSI_SOS: /* ignored */ break; default: TRACE(("unknown mode\n")); break; } } } break; case CASE_SOS: TRACE(("CASE_SOS: Start of String\n")); if (ParseSOS(screen)) { BeginString(ANSI_SOS); } else { illegal_parse(xw, c, sp); } break; case CASE_PM: TRACE(("CASE_PM: Privacy Message\n")); if (ParseSOS(screen)) { BeginString(ANSI_PM); } else { illegal_parse(xw, c, sp); } break; case CASE_DCS: TRACE(("CASE_DCS: Device Control String\n")); BeginString2(ANSI_DCS); break; case CASE_APC: TRACE(("CASE_APC: Application Program Command\n")); if (ParseSOS(screen)) { BeginString(ANSI_APC); } else { illegal_parse(xw, c, sp); } break; case CASE_SPA: TRACE(("CASE_SPA - start protected area\n")); screen->protected_mode = ISO_PROTECT; xw->flags |= PROTECTED; ResetState(sp); break; case CASE_EPA: TRACE(("CASE_EPA - end protected area\n")); UIntClr(xw->flags, PROTECTED); ResetState(sp); break; case CASE_SU: TRACE(("CASE_SU - scroll up\n")); xtermScroll(xw, one_if_default(0)); ResetState(sp); break; case CASE_SL: /* ISO 6429, non-DEC */ TRACE(("CASE_SL - scroll left\n")); xtermScrollLR(xw, one_if_default(0), True); ResetState(sp); break; case CASE_SR: /* ISO 6429, non-DEC */ TRACE(("CASE_SR - scroll right\n")); xtermScrollLR(xw, one_if_default(0), False); ResetState(sp); break; case CASE_DECDC: TRACE(("CASE_DC - delete column\n")); if (screen->vtXX_level >= 4) { xtermColScroll(xw, one_if_default(0), True, screen->cur_col); } ResetState(sp); break; case CASE_DECIC: TRACE(("CASE_IC - insert column\n")); if (screen->vtXX_level >= 4) { xtermColScroll(xw, one_if_default(0), False, screen->cur_col); } ResetState(sp); break; case CASE_DECBI: TRACE(("CASE_BI - back index\n")); if (screen->vtXX_level >= 4) { xtermColIndex(xw, True); } ResetState(sp); break; case CASE_DECFI: TRACE(("CASE_FI - forward index\n")); if (screen->vtXX_level >= 4) { xtermColIndex(xw, False); } ResetState(sp); break; case CASE_IND: TRACE(("CASE_IND - index\n")); xtermIndex(xw, 1); do_xevents(xw); ResetState(sp); break; case CASE_CPL: TRACE(("CASE_CPL - cursor prev line\n")); CursorPrevLine(xw, one_if_default(0)); ResetState(sp); break; case CASE_CNL: TRACE(("CASE_CNL - cursor next line\n")); CursorNextLine(xw, one_if_default(0)); ResetState(sp); break; case CASE_NEL: TRACE(("CASE_NEL\n")); xtermIndex(xw, 1); CarriageReturn(xw); ResetState(sp); break; case CASE_HTS: TRACE(("CASE_HTS - horizontal tab set\n")); TabSet(xw->tabs, screen->cur_col); ResetState(sp); break; case CASE_REPORT_VERSION: TRACE(("CASE_REPORT_VERSION - report terminal version\n")); if (GetParam(0) <= 0) { unparseputc1(xw, ANSI_DCS); unparseputc(xw, '>'); unparseputc(xw, '|'); unparseputs(xw, xtermVersion()); unparseputc1(xw, ANSI_ST); unparse_end(xw); } ResetState(sp); break; case CASE_RI: TRACE(("CASE_RI - reverse index\n")); RevIndex(xw, 1); ResetState(sp); break; case CASE_SS2: TRACE(("CASE_SS2\n")); if (screen->vtXX_level > 1) screen->curss = 2; ResetState(sp); break; case CASE_SS3: TRACE(("CASE_SS3\n")); if (screen->vtXX_level > 1) screen->curss = 3; ResetState(sp); break; case CASE_CSI_STATE: /* enter csi state */ InitParams(); SetParam(nparam++, DEFAULT); sp->parsestate = csi_table; break; case CASE_ESC_SP_STATE: /* esc space */ sp->parsestate = esc_sp_table; break; case CASE_CSI_EX_STATE: /* csi exclamation */ sp->parsestate = csi_ex_table; break; case CASE_CSI_TICK_STATE: /* csi tick (') */ sp->parsestate = csi_tick_table; break; #if OPT_DEC_LOCATOR case CASE_DECEFR: TRACE(("CASE_DECEFR - Enable Filter Rectangle\n")); if (okSendMousePos(xw) == DEC_LOCATOR) { MotionOff(screen, xw); if ((screen->loc_filter_top = GetParam(0)) < 1) screen->loc_filter_top = LOC_FILTER_POS; if (nparam < 2 || (screen->loc_filter_left = GetParam(1)) < 1) screen->loc_filter_left = LOC_FILTER_POS; if (nparam < 3 || (screen->loc_filter_bottom = GetParam(2)) < 1) screen->loc_filter_bottom = LOC_FILTER_POS; if (nparam < 4 || (screen->loc_filter_right = GetParam(3)) < 1) screen->loc_filter_right = LOC_FILTER_POS; InitLocatorFilter(xw); } ResetState(sp); break; case CASE_DECELR: MotionOff(screen, xw); if (GetParam(0) <= 0 || GetParam(0) > 2) { screen->send_mouse_pos = MOUSE_OFF; TRACE(("DECELR - Disable Locator Reports\n")); } else { TRACE(("DECELR - Enable Locator Reports\n")); screen->send_mouse_pos = DEC_LOCATOR; xtermShowPointer(xw, True); if (GetParam(0) == 2) { screen->locator_reset = True; } else { screen->locator_reset = False; } if (nparam < 2 || GetParam(1) != 1) { screen->locator_pixels = False; } else { screen->locator_pixels = True; } screen->loc_filter = False; } ResetState(sp); break; case CASE_DECSLE: TRACE(("DECSLE - Select Locator Events\n")); for (count = 0; count < nparam; ++count) { switch (zero_if_default(count)) { case 0: MotionOff(screen, xw); screen->loc_filter = False; screen->locator_events = 0; break; case 1: screen->locator_events |= LOC_BTNS_DN; break; case 2: UIntClr(screen->locator_events, LOC_BTNS_DN); break; case 3: screen->locator_events |= LOC_BTNS_UP; break; case 4: UIntClr(screen->locator_events, LOC_BTNS_UP); break; } } ResetState(sp); break; case CASE_DECRQLP: TRACE(("DECRQLP - Request Locator Position\n")); if (GetParam(0) < 2) { /* Issue DECLRP Locator Position Report */ GetLocatorPosition(xw); } ResetState(sp); break; #endif /* OPT_DEC_LOCATOR */ case CASE_CSI_AMP_STATE: TRACE(("CASE_CSI_AMP_STATE\n")); /* csi ampersand (&) */ if (screen->vtXX_level >= 3) sp->parsestate = csi_amp_table; else sp->parsestate = eigtable; break; #if OPT_DEC_RECTOPS case CASE_CSI_DOLLAR_STATE: TRACE(("CASE_CSI_DOLLAR_STATE\n")); /* csi dollar ($) */ if (screen->vtXX_level >= 3) sp->parsestate = csi_dollar_table; else sp->parsestate = eigtable; break; case CASE_CSI_STAR_STATE: TRACE(("CASE_CSI_STAR_STATE\n")); /* csi star (*) */ if (screen->vtXX_level >= 4) sp->parsestate = csi_star_table; else sp->parsestate = eigtable; break; case CASE_DECRQCRA: if (screen->vtXX_level >= 4 && AllowWindowOps(xw, ewGetChecksum)) { int checksum; int pid; TRACE(("CASE_DECRQCRA - Request checksum of rectangular area\n")); xtermCheckRect(xw, ParamPair(0), &checksum); init_reply(ANSI_DCS); count = 0; checksum &= 0xffff; pid = GetParam(0); reply.a_param[count++] = (ParmType) pid; reply.a_delim = "!~"; /* delimiter */ reply.a_radix[count] = 16; reply.a_param[count++] = (ParmType) checksum; reply.a_nparam = (ParmType) count; TRACE(("...checksum(%d) = %04X\n", pid, checksum)); unparseseq(xw, &reply); } ResetState(sp); break; case CASE_DECCRA: if (screen->vtXX_level >= 4) { TRACE(("CASE_DECCRA - Copy rectangular area\n")); xtermParseRect(xw, ParamPair(0), &myRect); ScrnCopyRectangle(xw, &myRect, ParamPair(5)); } ResetState(sp); break; case CASE_DECERA: if (screen->vtXX_level >= 4) { TRACE(("CASE_DECERA - Erase rectangular area\n")); xtermParseRect(xw, ParamPair(0), &myRect); ScrnFillRectangle(xw, &myRect, ' ', nrc_ASCII, xw->flags, True); } ResetState(sp); break; case CASE_DECFRA: if (screen->vtXX_level >= 4) { value = use_default_value(0, ' '); TRACE(("CASE_DECFRA - Fill rectangular area\n")); /* DEC 070, page 5-170 says the fill-character is either * ASCII or Latin1; xterm allows printable Unicode values. */ if (nparam > 0 && ((value >= 256 && CharWidth(screen, value) > 0) || IsLatin1(value))) { xtermParseRect(xw, ParamPair(1), &myRect); ScrnFillRectangle(xw, &myRect, value, current_charset(screen, value), xw->flags, True); } } ResetState(sp); break; case CASE_DECSERA: if (screen->vtXX_level >= 4) { TRACE(("CASE_DECSERA - Selective erase rectangular area\n")); xtermParseRect(xw, ParamPair(0), &myRect); ScrnWipeRectangle(xw, &myRect); } ResetState(sp); break; case CASE_DECSACE: TRACE(("CASE_DECSACE - Select attribute change extent\n")); screen->cur_decsace = zero_if_default(0); ResetState(sp); break; case CASE_DECCARA: if (screen->vtXX_level >= 4) { TRACE(("CASE_DECCARA - Change attributes in rectangular area\n")); xtermParseRect(xw, ParamPair(0), &myRect); ScrnMarkRectangle(xw, &myRect, False, ParamPair(4)); } ResetState(sp); break; case CASE_DECRARA: if (screen->vtXX_level >= 4) { TRACE(("CASE_DECRARA - Reverse attributes in rectangular area\n")); xtermParseRect(xw, ParamPair(0), &myRect); ScrnMarkRectangle(xw, &myRect, True, ParamPair(4)); } ResetState(sp); break; case CASE_DECSCPP: if (screen->vtXX_level >= 3) { TRACE(("CASE_DECSCPP\n")); /* default and 0 are "80", with "132" as the other legal choice */ switch (zero_if_default(0)) { case 0: case 80: value = 80; break; case 132: value = 132; break; default: value = -1; break; } if (value > 0) { if (screen->cur_col + 1 > value) CursorSet(screen, screen->cur_row, value - 1, xw->flags); UIntClr(xw->flags, IN132COLUMNS); if (value == 132) UIntSet(xw->flags, IN132COLUMNS); RequestResize(xw, -1, value, True); } } ResetState(sp); break; case CASE_DECSNLS: if (screen->vtXX_level >= 4 && AllowWindowOps(xw, ewSetWinLines)) { TRACE(("CASE_DECSNLS\n")); value = zero_if_default(0); if (value >= 1 && value <= 255) { RequestResize(xw, value, -1, True); } } ResetState(sp); break; case CASE_DECRQDE: if (screen->vtXX_level >= 3) { init_reply(ANSI_CSI); count = 0; reply.a_param[count++] = (ParmType) MaxRows(screen); /* number of lines */ reply.a_param[count++] = (ParmType) MaxCols(screen); /* number of columns */ reply.a_param[count++] = 1; /* current page column */ reply.a_param[count++] = 1; /* current page line */ reply.a_param[count++] = 1; /* current page */ reply.a_inters = '"'; reply.a_final = 'w'; reply.a_nparam = (ParmType) count; unparseseq(xw, &reply); } ResetState(sp); break; case CASE_DECRQPSR: #define reply_char(n,c) do { reply.a_radix[(n)] = 1; reply.a_param[(n)++] = (ParmType)(c); } while (0) #define reply_bit(n,c) ((n) ? (c) : 0) if (screen->vtXX_level >= 3) { TRACE(("CASE_DECRQPSR\n")); switch (GetParam(0)) { case 1: TRACE(("...DECCIR\n")); init_reply(ANSI_DCS); count = 0; reply_char(count, '1'); reply_char(count, '$'); reply_char(count, 'u'); reply.a_param[count++] = (ParmType) (screen->cur_row + 1); reply.a_param[count++] = (ParmType) (screen->cur_col + 1); reply.a_param[count++] = (ParmType) thispage; reply_char(count, ';'); reply_char(count, (0x40 | reply_bit(xw->flags & INVERSE, 8) | reply_bit(xw->flags & BLINK, 4) | reply_bit(xw->flags & UNDERLINE, 2) | reply_bit(xw->flags & BOLD, 1) )); reply_char(count, ';'); reply_char(count, 0x40 | reply_bit(screen->protected_mode & DEC_PROTECT, 1) ); reply_char(count, ';'); reply_char(count, (0x40 | reply_bit(screen->do_wrap, 8) | reply_bit((screen->curss == 3), 4) | reply_bit((screen->curss == 2), 2) | reply_bit(xw->flags & ORIGIN, 1) )); reply_char(count, ';'); reply.a_param[count++] = screen->curgl; reply.a_param[count++] = screen->curgr; reply_char(count, ';'); value = 0x40; for (item = 0; item < NUM_GSETS; ++item) { value |= (is_96charset(screen->gsets[item]) << item); } reply_char(count, value); /* encoded charset sizes */ reply_char(count, ';'); for (item = 0; item < NUM_GSETS; ++item) { int ps; char *temp = encode_scs(screen->gsets[item], &ps); while (*temp != '\0') { reply_char(count, *temp++); } } reply.a_nparam = (ParmType) count; unparseseq(xw, &reply); break; case 2: TRACE(("...DECTABSR\n")); init_reply(ANSI_DCS); reply.a_delim = "/"; count = 0; reply_char(count, '2'); reply_char(count, '$'); reply_char(count, 'u'); for (item = 0; item < MAX_TABS; ++item) { if (count + 1 >= NPARAM) break; if (item > screen->max_col) break; if (TabIsSet(xw->tabs, item)) reply.a_param[count++] = (ParmType) (item + 1); } reply.a_nparam = (ParmType) count; unparseseq(xw, &reply); break; } } ResetState(sp); break; case CASE_DECRQUPSS: TRACE(("CASE_DECRQUPSS\n")); if (screen->vtXX_level >= 3) { int psize = 0; char *encoded = encode_scs(screen->gsets_upss, &psize); init_reply(ANSI_DCS); count = 0; reply_char(count, psize ? '1' : '0'); reply_char(count, '!'); reply_char(count, 'u'); reply_char(count, *encoded++); if (*encoded) reply_char(count, *encoded); reply.a_nparam = (ParmType) count; unparseseq(xw, &reply); } break; case CASE_RQM: TRACE(("CASE_RQM\n")); do_ansi_rqm(xw, ParamPair(0)); ResetState(sp); break; case CASE_DECRQM: TRACE(("CASE_DECRQM\n")); do_dec_rqm(xw, ParamPair(0)); ResetState(sp); break; case CASE_CSI_DEC_DOLLAR_STATE: TRACE(("CASE_CSI_DEC_DOLLAR_STATE\n")); /* csi ? dollar ($) */ sp->parsestate = csi_dec_dollar_table; break; case CASE_DECST8C: TRACE(("CASE_DECST8C\n")); if (screen->vtXX_level >= 5 && (GetParam(0) == 5 || GetParam(0) <= 0)) { TabZonk(xw->tabs); for (count = 0; count < MAX_TABS; ++count) { item = (count + 1) * 8; if (item > screen->max_col) break; TabSet(xw->tabs, item); } } ResetState(sp); break; #else case CASE_CSI_DOLLAR_STATE: /* csi dollar ($) */ sp->parsestate = eigtable; break; case CASE_CSI_STAR_STATE: /* csi dollar (*) */ sp->parsestate = eigtable; break; case CASE_CSI_DEC_DOLLAR_STATE: /* csi ? dollar ($) */ sp->parsestate = eigtable; break; case CASE_DECST8C: /* csi ? 5 W */ ResetState(sp); break; #endif /* OPT_DEC_RECTOPS */ #if OPT_VT525_COLORS case CASE_CSI_COMMA_STATE: TRACE(("CASE_CSI_COMMA_STATE\n")); /* csi comma (,) */ if (screen->vtXX_level >= 5) sp->parsestate = csi_comma_table; else sp->parsestate = eigtable; break; case CASE_DECAC: TRACE(("CASE_DECAC\n")); #if OPT_ISO_COLORS if (screen->terminal_id >= 525) { int fg, bg; switch (GetParam(0)) { case 1: fg = GetParam(1); bg = GetParam(2); if (fg >= 0 && fg < 16 && bg >= 0 && bg < 16) { Boolean repaint = False; if (AssignFgColor(xw, GET_COLOR_RES(xw, screen->Acolors[fg]))) repaint = True; if (AssignBgColor(xw, GET_COLOR_RES(xw, screen->Acolors[bg]))) repaint = True; if (repaint) xtermRepaint(xw); screen->assigned_fg = fg; screen->assigned_bg = bg; } break; case 2: /* window frames: not implemented */ break; } } #endif ResetState(sp); break; case CASE_DECATC: #if OPT_ISO_COLORS TRACE(("CASE_DECATC\n")); if (screen->terminal_id >= 525) { int ps = GetParam(0); int fg = GetParam(1); int bg = GetParam(2); if (ps >= 0 && ps < 16 && fg >= 0 && fg < 16 && bg >= 0 && bg < 16) { screen->alt_colors[ps].fg = fg; screen->alt_colors[ps].bg = bg; } } #endif ResetState(sp); break; case CASE_DECTID: TRACE(("CASE_DECTID\n")); switch (GetParam(0)) { case 0: screen->display_da1 = 100; break; case 1: screen->display_da1 = 101; break; case 2: screen->display_da1 = 102; break; case 5: screen->display_da1 = 220; break; case 7: screen->display_da1 = 320; break; case 9: screen->display_da1 = 420; break; case 10: screen->display_da1 = 520; break; } ResetState(sp); break; #else case CASE_CSI_COMMA_STATE: sp->parsestate = eigtable; break; #endif case CASE_DECSASD: #if OPT_STATUS_LINE if (screen->vtXX_level >= 2) { handle_DECSASD(xw, zero_if_default(0)); } #endif ResetState(sp); break; case CASE_DECSSDT: #if OPT_STATUS_LINE if (screen->vtXX_level >= 2) { handle_DECSSDT(xw, zero_if_default(0)); } #endif ResetState(sp); break; #if OPT_XTERM_SGR /* most are related, all use csi_hash_table[] */ case CASE_CSI_HASH_STATE: TRACE(("CASE_CSI_HASH_STATE\n")); /* csi hash (#) */ sp->parsestate = csi_hash_table; break; case CASE_XTERM_CHECKSUM: #if OPT_DEC_RECTOPS if (screen->vtXX_level >= 4 && AllowWindowOps(xw, ewSetChecksum)) { TRACE(("CASE_XTERM_CHECKSUM\n")); screen->checksum_ext = zero_if_default(0); } #endif ResetState(sp); break; case CASE_XTERM_PUSH_SGR: TRACE(("CASE_XTERM_PUSH_SGR\n")); value = 0; if (nparam == 0 || (nparam == 1 && GetParam(0) == DEFAULT)) { value = DEFAULT; } else if (nparam > 0) { for (count = 0; count < nparam; ++count) { item = zero_if_default(count); /* deprecated - for compatibility */ #if OPT_ISO_COLORS if (item == psFG_COLOR_obs) { item = psFG_COLOR; } else if (item == psBG_COLOR_obs) { item = psBG_COLOR; } #endif if (item > 0 && item < MAX_PUSH_SGR) { value |= (1 << (item - 1)); } } } xtermPushSGR(xw, value); ResetState(sp); break; case CASE_XTERM_REPORT_SGR: TRACE(("CASE_XTERM_REPORT_SGR\n")); xtermParseRect(xw, ParamPair(0), &myRect); xtermReportSGR(xw, &myRect); ResetState(sp); break; case CASE_XTERM_POP_SGR: TRACE(("CASE_XTERM_POP_SGR\n")); xtermPopSGR(xw); ResetState(sp); break; case CASE_XTERM_PUSH_COLORS: TRACE(("CASE_XTERM_PUSH_COLORS\n")); if (nparam == 0) { xtermPushColors(xw, DEFAULT); } else { for (count = 0; count < nparam; ++count) { xtermPushColors(xw, GetParam(count)); } } ResetState(sp); break; case CASE_XTERM_POP_COLORS: TRACE(("CASE_XTERM_POP_COLORS\n")); if (nparam == 0) { xtermPopColors(xw, DEFAULT); } else { for (count = 0; count < nparam; ++count) { xtermPopColors(xw, GetParam(count)); } } ResetState(sp); break; case CASE_XTERM_REPORT_COLORS: TRACE(("CASE_XTERM_REPORT_COLORS\n")); xtermReportColors(xw); ResetState(sp); break; case CASE_XTERM_TITLE_STACK: xtermReportTitleStack(xw); ResetState(sp); break; #endif case CASE_S7C1T: TRACE(("CASE_S7C1T\n")); if (screen->vtXX_level >= 2) { show_8bit_control(False); ResetState(sp); } break; case CASE_S8C1T: TRACE(("CASE_S8C1T\n")); if (screen->vtXX_level >= 2) { show_8bit_control(True); ResetState(sp); } break; case CASE_OSC: TRACE(("CASE_OSC: Operating System Command\n")); BeginString(ANSI_OSC); break; case CASE_RIS: TRACE(("CASE_RIS\n")); VTReset(xw, True, True); /* NOTREACHED */ case CASE_DECSTR: TRACE(("CASE_DECSTR\n")); VTReset(xw, False, False); /* NOTREACHED */ case CASE_REP: TRACE(("CASE_REP\n")); if (CharWidth(screen, sp->lastchar) > 0) { IChar repeated[2]; count = one_if_default(0); repeated[0] = (IChar) sp->lastchar; while (count-- > 0) { dotext(xw, screen->gsets[(int) (screen->curgl)], repeated, 1); } } ResetState(sp); break; case CASE_LS2: TRACE(("CASE_LS2\n")); if (screen->ansi_level > 2) screen->curgl = 2; ResetState(sp); break; case CASE_LS3: TRACE(("CASE_LS3\n")); if (screen->ansi_level > 2) screen->curgl = 3; ResetState(sp); break; case CASE_LS3R: TRACE(("CASE_LS3R\n")); if (screen->ansi_level > 2) screen->curgr = 3; ResetState(sp); break; case CASE_LS2R: TRACE(("CASE_LS2R\n")); if (screen->ansi_level > 2) screen->curgr = 2; ResetState(sp); break; case CASE_LS1R: TRACE(("CASE_LS1R\n")); if (screen->ansi_level > 2) screen->curgr = 1; ResetState(sp); break; case CASE_XTERM_SAVE: savemodes(xw); ResetState(sp); break; case CASE_XTERM_RESTORE: restoremodes(xw); ResetState(sp); break; case CASE_XTERM_WINOPS: TRACE(("CASE_XTERM_WINOPS\n")); window_ops(xw); ResetState(sp); break; #if OPT_WIDE_CHARS case CASE_ESC_PERCENT: TRACE(("CASE_ESC_PERCENT\n")); sp->parsestate = esc_pct_table; break; case CASE_UTF8: /* If we did not set UTF-8 mode from resource or the * command-line, allow it to be enabled/disabled by * control sequence. */ TRACE(("CASE_UTF8 wide:%d, utf8:%d, req:%s\n", screen->wide_chars, screen->utf8_mode, BtoS(AsciiOf(c) == 'G'))); if ((!screen->wide_chars) && (AsciiOf(c) == 'G')) { WriteNow(); ChangeToWide(xw); } if (screen->wide_chars && !screen->utf8_always) { switchPtyData(screen, AsciiOf(c) == 'G'); TRACE(("UTF8 mode %s\n", BtoS(screen->utf8_mode))); } else { TRACE(("UTF8 mode NOT turned %s (%s)\n", BtoS(AsciiOf(c) == 'G'), (screen->utf8_mode == uAlways) ? "UTF-8 mode set from command-line" : "wideChars resource was not set")); } ResetState(sp); break; case CASE_SCS_DQUOTE: TRACE(("CASE_SCS_DQUOTE\n")); sp->parsestate = scs_2qt_table; break; case CASE_GSETS_DQUOTE: if (screen->vtXX_level >= 5) { TRACE_GSETS("_DQUOTE"); xtermDecodeSCS(xw, sp->scstype, 5, '"', (int) c); } ResetState(sp); break; case CASE_SCS_AMPRSND: TRACE(("CASE_SCS_AMPRSND\n")); sp->parsestate = scs_amp_table; break; case CASE_GSETS_AMPRSND: if (screen->vtXX_level >= 5) { TRACE_GSETS("_AMPRSND"); xtermDecodeSCS(xw, sp->scstype, 5, '&', (int) c); } ResetState(sp); break; case CASE_SCS_PERCENT: TRACE(("CASE_SCS_PERCENT\n")); sp->parsestate = scs_pct_table; break; case CASE_GSETS_PERCENT: if (screen->vtXX_level >= 3) { TRACE_GSETS("_PERCENT"); switch (AsciiOf(c)) { case '0': /* DEC Turkish */ case '2': /* Turkish */ case '=': /* Hebrew */ value = 5; break; case '5': /* DEC Supplemental Graphics */ case '6': /* Portuguese */ default: value = 3; break; } xtermDecodeSCS(xw, sp->scstype, value, '%', (int) c); } ResetState(sp); break; #endif case CASE_XTERM_SHIFT_ESCAPE: TRACE(("CASE_XTERM_SHIFT_ESCAPE\n")); value = ((nparam == 0) ? 0 : one_if_default(0)); if (value >= 0 && value <= 1) xw->keyboard.shift_escape = value; ResetState(sp); break; #if OPT_MOD_FKEYS case CASE_SET_FMT_KEYS: TRACE(("CASE_SET_FMT_KEYS\n")); if (nparam >= 1) { int first = GetParam(0); int second = ((nparam > 1) ? GetParam(1) : DEFAULT); set_fmt_fkeys(xw, first, second, True); } else { for (value = 1; value <= 5; ++value) set_fmt_fkeys(xw, value, DEFAULT, True); } ResetState(sp); break; case CASE_XTERM_REPORT_FMT_KEYS: TRACE(("CASE_XTERM_REPORT_FMT_KEYS\n")); for (value = 0; value < nparam; ++value) { report_fmt_fkeys(xw, GetParam(value)); } ResetState(sp); break; case CASE_SET_MOD_FKEYS: TRACE(("CASE_SET_MOD_FKEYS\n")); if (nparam >= 1) { int first = GetParam(0); int second = ((nparam > 1) ? GetParam(1) : DEFAULT); if (parms.has_subparams) { if (subparam_index(0, 0) == 0 && subparam_index(1, 0) == 1 && subparam_index(1, 1) == 2) { set_mod_fkeys(xw, first, second, True, parms.params[2]); } } else { set_mod_fkeys(xw, first, second, True, 0); } } else { for (value = 1; value <= 5; ++value) set_mod_fkeys(xw, value, DEFAULT, True, 0); } ResetState(sp); break; case CASE_SET_MOD_FKEYS0: TRACE(("CASE_SET_MOD_FKEYS0\n")); if (nparam >= 1 && GetParam(0) != DEFAULT) { set_mod_fkeys(xw, GetParam(0), DEFAULT, False, 0); } else { xw->keyboard.modify_now.function_keys = DEFAULT; } ResetState(sp); break; case CASE_XTERM_REPORT_MOD_FKEYS: TRACE(("CASE_XTERM_REPORT_MOD_FKEYS\n")); for (value = 0; value < nparam; ++value) { report_mod_fkeys(xw, GetParam(value)); } ResetState(sp); break; #endif case CASE_HIDE_POINTER: TRACE(("CASE_HIDE_POINTER\n")); if (nparam >= 1 && GetParam(0) != DEFAULT) { screen->pointer_mode = GetParam(0); } else { screen->pointer_mode = DEF_POINTER_MODE; } ResetState(sp); break; case CASE_XTERM_SM_TITLE: TRACE(("CASE_XTERM_SM_TITLE\n")); if (nparam >= 1) { for (count = 0; count < nparam; ++count) { value = GetParam(count); if (ValidTitleMode(value)) screen->title_modes |= xBIT(value); } } else { screen->title_modes = DEF_TITLE_MODES; } TRACE(("...title_modes %#x\n", screen->title_modes)); ResetState(sp); break; case CASE_XTERM_RM_TITLE: TRACE(("CASE_XTERM_RM_TITLE\n")); if (nparam >= 1) { for (count = 0; count < nparam; ++count) { value = GetParam(count); if (ValidTitleMode(value)) screen->title_modes &= ~xBIT(value); } } else { screen->title_modes = DEF_TITLE_MODES; } TRACE(("...title_modes %#x\n", screen->title_modes)); ResetState(sp); break; case CASE_CSI_IGNORE: sp->parsestate = cigtable; break; case CASE_DECSWBV: TRACE(("CASE_DECSWBV\n")); switch (zero_if_default(0)) { case 2: /* FALLTHRU */ case 3: /* FALLTHRU */ case 4: screen->warningVolume = bvLow; break; case 5: /* FALLTHRU */ case 6: /* FALLTHRU */ case 7: /* FALLTHRU */ case 8: screen->warningVolume = bvHigh; break; default: screen->warningVolume = bvOff; break; } TRACE(("...warningVolume %d\n", screen->warningVolume)); ResetState(sp); break; case CASE_DECSMBV: TRACE(("CASE_DECSMBV\n")); switch (zero_if_default(0)) { case 2: /* FALLTHRU */ case 3: /* FALLTHRU */ case 4: screen->marginVolume = bvLow; break; case 0: /* FALLTHRU */ case 5: /* FALLTHRU */ case 6: /* FALLTHRU */ case 7: /* FALLTHRU */ case 8: screen->marginVolume = bvHigh; break; default: screen->marginVolume = bvOff; break; } TRACE(("...marginVolume %d\n", screen->marginVolume)); ResetState(sp); break; } if (sp->parsestate == sp->groundtable) sp->lastchar = thischar; } while (0); #if OPT_WIDE_CHARS screen->utf8_inparse = (Boolean) ((screen->utf8_mode != uFalse) && (sp->parsestate != sos_table)); #endif if (sp->check_recur) sp->check_recur--; return True; } static void VTparse(XtermWidget xw) { Boolean keep_running; /* We longjmp back to this point in VTReset() */ (void) setjmp(vtjmpbuf); init_parser(xw, &myState); do { keep_running = doparsing(xw, doinput(xw), &myState); if (myState.check_recur == 0 && myState.defer_used != 0) { while (myState.defer_used) { Char *deferred = myState.defer_area; size_t len = myState.defer_used; size_t i; myState.defer_area = NULL; myState.defer_size = 0; myState.defer_used = 0; for (i = 0; i < len; i++) { (void) doparsing(xw, deferred[i], &myState); } free(deferred); } } else { free(myState.defer_area); } myState.defer_area = NULL; myState.defer_size = 0; myState.defer_used = 0; } while (keep_running); } static Char *v_buffer; /* pointer to physical buffer */ static Char *v_bufstr = NULL; /* beginning of area to write */ static Char *v_bufptr; /* end of area to write */ static Char *v_bufend; /* end of physical buffer */ /* Write data to the pty as typed by the user, pasted with the mouse, or generated by us in response to a query ESC sequence. */ void v_write(int f, const Char *data, size_t len) { TRACE2(("v_write(%d:%s)\n", len, visibleChars(data, len))); if (v_bufstr == NULL) { if (len > 0) { v_buffer = (Char *) XtMalloc((Cardinal) len); v_bufstr = v_buffer; v_bufptr = v_buffer; v_bufend = v_buffer + len; } if (v_bufstr == NULL) { return; } } if_DEBUG({ fprintf(stderr, "v_write called with %lu bytes (%lu left over)", (unsigned long) len, (unsigned long) (v_bufptr - v_bufstr)); if (len > 1 && len < 10) fprintf(stderr, " \"%.*s\"", (int) len, (const char *) data); fprintf(stderr, "\n"); }); if (!FD_ISSET(f, &pty_mask)) { IGNORE_RC(write(f, (const char *) data, (size_t) len)); return; } /* * Append to the block we already have. * Always doing this simplifies the code, and * isn't too bad, either. If this is a short * block, it isn't too expensive, and if this is * a long block, we won't be able to write it all * anyway. */ if (len > 0) { #if OPT_DABBREV TScreenOf(term)->dabbrev_working = False; /* break dabbrev sequence */ #endif if (v_bufend < v_bufptr + len) { /* we've run out of room */ if (v_bufstr != v_buffer) { /* there is unused space, move everything down */ /* possibly overlapping memmove here */ if_DEBUG({ fprintf(stderr, "moving data down %ld\n", (long) (v_bufstr - v_buffer)); }); memmove(v_buffer, v_bufstr, (size_t) (v_bufptr - v_bufstr)); v_bufptr -= v_bufstr - v_buffer; v_bufstr = v_buffer; } if (v_bufend < v_bufptr + len) { /* still won't fit: get more space */ /* Don't use XtRealloc because an error is not fatal. */ size_t size = (size_t) (v_bufptr - v_buffer); v_buffer = TypeRealloc(Char, size + len, v_buffer); if (v_buffer) { if_DEBUG({ fprintf(stderr, "expanded buffer to %lu\n", (unsigned long) (size + len)); }); v_bufstr = v_buffer; v_bufptr = v_buffer + size; v_bufend = v_bufptr + len; } else { /* no memory: ignore entire write request */ xtermWarning("cannot allocate buffer space\n"); v_buffer = v_bufstr; /* restore clobbered pointer */ } } } if (v_bufend >= v_bufptr + len) { /* new stuff will fit */ memmove(v_bufptr, data, (size_t) len); v_bufptr += len; } } /* * Write out as much of the buffer as we can. * Be careful not to overflow the pty's input silo. * We are conservative here and only write * a small amount at a time. * * If we can't push all the data into the pty yet, we expect write * to return a non-negative number less than the length requested * (if some data written) or -1 and set errno to EAGAIN, * EWOULDBLOCK, or EINTR (if no data written). * * (Not all systems do this, sigh, so the code is actually * a little more forgiving.) */ #define MAX_PTY_WRITE 128 /* 1/2 POSIX minimum MAX_INPUT */ if (v_bufptr > v_bufstr) { int riten; riten = (int) write(f, v_bufstr, (size_t) ((v_bufptr - v_bufstr <= MAX_PTY_WRITE) ? v_bufptr - v_bufstr : MAX_PTY_WRITE)); if (riten < 0) { if_DEBUG({ perror("write"); }); riten = 0; } if_DEBUG({ fprintf(stderr, "write called with %ld, wrote %d\n", ((long) ((v_bufptr - v_bufstr) <= MAX_PTY_WRITE) ? (long) (v_bufptr - v_bufstr) : MAX_PTY_WRITE), riten); }); v_bufstr += riten; if (v_bufstr >= v_bufptr) /* we wrote it all */ v_bufstr = v_bufptr = v_buffer; } /* * If we have lots of unused memory allocated, return it */ if (v_bufend - v_bufptr > 1024) { /* arbitrary hysteresis */ /* save pointers across realloc */ size_t start = (size_t) (v_bufstr - v_buffer); size_t size = (size_t) (v_bufptr - v_buffer); size_t allocsize = (size ? size : 1); v_buffer = TypeRealloc(Char, allocsize, v_buffer); if (v_buffer) { v_bufstr = v_buffer + start; v_bufptr = v_buffer + size; v_bufend = v_buffer + allocsize; if_DEBUG({ fprintf(stderr, "shrunk buffer to %lu\n", (unsigned long) allocsize); }); } else { /* should we print a warning if couldn't return memory? */ v_buffer = v_bufstr - start; /* restore clobbered pointer */ } } } static void updateCursor(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->cursor_set != screen->cursor_state) { if (screen->cursor_set) ShowCursor(xw); else HideCursor(xw); } } #if OPT_BLINK_CURS || OPT_BLINK_TEXT static void reallyStopBlinking(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->cursor_state == BLINKED_OFF) { /* force cursor to display if it is enabled */ screen->cursor_state = !screen->cursor_set; updateCursor(xw); xevents(xw); } } #endif static void update_the_screen(XtermWidget xw) { TScreen *screen = TScreenOf(xw); Boolean moved; if (screen->scroll_amt) FlushScroll(xw); moved = CursorMoved(screen); if (screen->cursor_set && moved) { if (screen->cursor_state) HideCursor(xw); ShowCursor(xw); #if OPT_INPUT_METHOD PreeditPosition(xw); #endif } else { #if OPT_INPUT_METHOD if (moved) PreeditPosition(xw); #endif updateCursor(xw); } } static void init_timeval(struct timeval *target, long usecs) { target->tv_sec = 0; target->tv_usec = usecs; while (target->tv_usec > 1000000) { target->tv_usec -= 1000000; target->tv_sec++; } } static Boolean better_timeout(struct timeval *check, struct timeval *against) { Boolean result = False; if (against->tv_sec == 0 && against->tv_usec == 0) { result = True; } else if (check->tv_sec == against->tv_sec) { if (check->tv_usec < against->tv_usec) { result = True; } } else if (check->tv_sec < against->tv_sec) { result = True; } return result; } #if OPT_BLINK_CURS static long smaller_timeout(long value) { /* 1000 for msec/usec, 8 for "much" smaller */ value *= (1000 / 8); if (value < 1) value = 1; return value; } #endif static void in_put(XtermWidget xw) { static PtySelect select_mask; static PtySelect write_mask; TScreen *screen = TScreenOf(xw); int i; int update = VTbuffer->update; #if USE_DOUBLE_BUFFER int should_wait = 1; #endif struct timeval my_timeout; for (;;) { int size; int time_select; if (screen->eventMode == NORMAL && (size = readPtyData(xw, &select_mask, VTbuffer)) != 0) { if (screen->scrollWidget && screen->scrollttyoutput && screen->topline < 0) WindowScroll(xw, 0, False); /* Scroll to bottom */ /* stop speed reading at some point to look for X stuff */ TRACE(("VTbuffer uses %ld/%d\n", (long) (VTbuffer->last - VTbuffer->buffer), BUF_SIZE)); if ((VTbuffer->last - VTbuffer->buffer) > BUF_SIZE) { FD_CLR(screen->respond, &select_mask); break; } #if USE_DOUBLE_BUFFER if (resource.buffered && should_wait) { /* wait for potential extra data (avoids some flickering) */ usleep((unsigned) DbeMsecs(xw)); should_wait = 0; } #endif #if defined(HAVE_SCHED_YIELD) /* * If we've read a full (small/fragment) buffer, let the operating * system have a turn, and we'll resume reading until we've either * read only a fragment of the buffer, or we've filled the large * buffer (see above). Doing this helps keep up with large bursts * of output. */ if (size == FRG_SIZE) { init_timeval(&my_timeout, 0L); i = Select(max_plus1, &select_mask, &write_mask, 0, &my_timeout); if (i > 0 && FD_ISSET(screen->respond, &select_mask)) { sched_yield(); } else break; } else { break; } #else (void) size; /* unused in this branch */ break; #endif } update_the_screen(xw); XFlush(screen->display); /* always flush writes before waiting */ /* Update the masks and, unless X events are already in the queue, wait for I/O to be possible. */ XFD_COPYSET(&Select_mask, &select_mask); /* in selection mode xterm does not read pty */ if (screen->eventMode != NORMAL) FD_CLR(screen->respond, &select_mask); if (v_bufptr > v_bufstr) { XFD_COPYSET(&pty_mask, &write_mask); } else FD_ZERO(&write_mask); init_timeval(&my_timeout, 0L); time_select = 0; /* * if there's either an XEvent or an XtTimeout pending, just take * a quick peek, i.e. timeout from the select() immediately. If * there's nothing pending, let select() block a little while, but * for a shorter interval than the arrow-style scrollbar timeout. * The blocking is optional, because it tends to increase the load * on the host. */ if (xtermAppPending()) { time_select = 1; } else { #define ImproveTimeout(usecs) \ struct timeval try_timeout; \ init_timeval(&try_timeout, usecs); \ if (better_timeout(&try_timeout, &my_timeout)) { \ my_timeout = try_timeout; \ } #if OPT_STATUS_LINE if ((screen->status_type == 1) && screen->status_timeout) { ImproveTimeout(find_SL_Timeout(xw) * 1000L); time_select = 1; } #endif if (screen->awaitInput) { ImproveTimeout(50000L); time_select = 1; } #if OPT_BLINK_CURS if ((screen->blink_timer != 0 && ((screen->select & FOCUS) || screen->always_highlight)) || (screen->cursor_state == BLINKED_OFF)) { /* * Compute the timeout for the blinking cursor to be much * smaller than the "on" or "off" interval. */ long tick = smaller_timeout((long) ((screen->blink_on < screen->blink_off) ? screen->blink_on : screen->blink_off)); ImproveTimeout(tick); time_select = 1; } #endif } #if OPT_SESSION_MGT if (resource.sessionMgt && (ice_fd >= 0)) { FD_SET(ice_fd, &select_mask); } #endif if (need_cleanup) NormalExit(); xtermFlushDbe(xw); i = Select(max_plus1, &select_mask, &write_mask, 0, (time_select ? &my_timeout : NULL)); if (i < 0) { if (errno != EINTR) SysError(ERROR_SELECT); continue; } /* if there is room to write more data to the pty, go write more */ if (FD_ISSET(screen->respond, &write_mask)) { v_write(screen->respond, (Char *) 0, (size_t) 0); /* flush buffer */ } /* if there are X events already in our queue, it counts as being readable */ if (xtermAppPending() || FD_ISSET(ConnectionNumber(screen->display), &select_mask)) { xevents(xw); if (VTbuffer->update != update) /* HandleInterpret */ break; } } } static IChar doinput(XtermWidget xw) { TScreen *screen = TScreenOf(xw); while (!morePtyData(screen, VTbuffer)) in_put(xw); return nextPtyData(screen, VTbuffer); } #if OPT_INPUT_METHOD /* * For OverTheSpot, client has to inform the position for XIM preedit. */ static void PreeditPosition(XtermWidget xw) { TInput *input = lookupTInput(xw, (Widget) xw); TScreen *screen = TScreenOf(xw); CLineData *ld; XPoint spot; XVaNestedList list; if (input && input->xic && (ld = getLineData(screen, screen->cur_row)) != NULL) { spot.x = (short) LineCursorX(screen, ld, screen->cur_col); spot.y = (short) (CursorY(screen, screen->cur_row) + xw->work.xim_fs_ascent); list = XVaCreateNestedList(0, XNSpotLocation, &spot, XNForeground, T_COLOR(screen, TEXT_FG), XNBackground, T_COLOR(screen, TEXT_BG), (void *) 0); XSetICValues(input->xic, XNPreeditAttributes, list, (void *) 0); XFree(list); } } #endif static void WrapLine(XtermWidget xw) { TScreen *screen = TScreenOf(xw); LineData *ld = getLineData(screen, screen->cur_row); if (ld != NULL) { /* mark that we had to wrap this line */ LineSetFlag(ld, LINEWRAPPED); ShowWrapMarks(xw, screen->cur_row, ld); xtermAutoPrint(xw, '\n'); xtermIndex(xw, 1); set_cur_col(screen, ScrnLeftMargin(xw)); } } /* * Process a string of characters according to the character set indicated by * charset. Worry about end of line conditions (wraparound if selected). * * It is possible to use CUP, etc., to move outside margins. In that case, the * right-margin is ineffective until the text (may) wrap and get within the * margins. */ void dotext(XtermWidget xw, DECNRCM_codes charset, IChar *buf, /* start of characters to process */ Cardinal len) /* end */ { TScreen *screen = TScreenOf(xw); #if OPT_WIDE_CHARS Cardinal chars_chomped = 1; int next_col = screen->cur_col; #else int next_col, this_col; /* must be signed */ #endif Cardinal offset; int rmargin = ScrnRightMargin(xw); xw->work.write_text = buf; #if OPT_DEC_RECTOPS xw->work.write_sums = NULL; #endif #if OPT_WIDE_CHARS if (screen->vt100_graphics) #endif { DECNRCM_codes rightset = screen->gsets[(int) (screen->curgr)]; if (charset != nrc_ASCII || rightset != nrc_ASCII) { len = xtermCharSetOut(xw, len, charset); if (len == 0) return; } } if_OPT_XMC_GLITCH(screen, { Cardinal n; if (charset != '?') { for (n = 0; n < len; n++) { if (buf[n] == XMC_GLITCH) buf[n] = XMC_GLITCH + 1; } } }); #if OPT_WIDE_CHARS for (offset = 0; offset < len && (chars_chomped > 0 || screen->do_wrap); offset += chars_chomped) { #if OPT_DEC_CHRSET CLineData *ld = getLineData(screen, screen->cur_row); int real_rmargin = (CSET_DOUBLE(GetLineDblCS(ld)) ? (rmargin / 2) : rmargin); #else int real_rmargin = rmargin; #endif int last_col = LineMaxCol(screen, ld); int width_here = 0; int last_chomp = 0; Boolean force_wrap; chars_chomped = 0; do { int right = ((screen->cur_col > real_rmargin) ? last_col : real_rmargin); int width_available = right + 1 - screen->cur_col; Boolean need_wrap = False; Boolean did_wrap = False; force_wrap = False; if (screen->do_wrap) { screen->do_wrap = False; if ((xw->flags & WRAPAROUND)) { WrapLine(xw); right = ((screen->cur_col > real_rmargin) ? last_col : real_rmargin); width_available = right + 1 - screen->cur_col; next_col = screen->cur_col; did_wrap = True; } } /* * This can happen with left/right margins... */ if (width_available <= 0) { break; } /* * Regarding the soft-hyphen aberration, see * http://archives.miloush.net/michkap/archive/2006/09/02/736881.html */ while (width_here <= width_available && chars_chomped < (len - offset)) { Cardinal n = chars_chomped + offset; if (!screen->utf8_mode || (screen->vt100_graphics && charset == '0')) { last_chomp = 1; } else if (screen->c1_printable && buf[n] >= 0x80 && buf[n] <= 0xa0) { last_chomp = 1; } else { last_chomp = CharWidth(screen, buf[n]); if (last_chomp <= 0) { IChar ch = buf[n]; Bool eat_it = !screen->utf8_mode && (ch > 127); if (ch == 0xad) { /* * Only display soft-hyphen if it happens to be at * the right-margin. While that means that only * the displayed character could be selected for * pasting, a well-behaved application would never * send this, anyway... */ if (width_here < width_available - 1) { eat_it = True; } else { last_chomp = 1; eat_it = False; } TRACE(("...will%s display soft-hyphen\n", eat_it ? " not" : "")); } /* * Supposedly we dealt with combining characters and * control characters in doparse(). Anything left over * is junk that we will not attempt to display. */ if (eat_it) { TRACE(("...will not display U+%04X\n", ch)); --len; while (n < len) { buf[n] = buf[n + 1]; ++n; } last_chomp = 0; chars_chomped--; } } } width_here += last_chomp; chars_chomped++; } if (width_here > width_available) { if (last_chomp > right + 1) { break; /* give up - it is too big */ } else if (chars_chomped-- == 0) { /* This can happen with left/right margins... */ break; } width_here -= last_chomp; if (chars_chomped > 0) { if (!(xw->flags & WRAPAROUND)) { buf[chars_chomped + offset - 1] = buf[len - 1]; } else { need_wrap = True; } } } else if (width_here == width_available) { need_wrap = True; } else if (chars_chomped != (len - offset)) { need_wrap = True; } if (chars_chomped != 0 && next_col <= last_col) { WriteText(xw, offset, chars_chomped); } else if (!did_wrap && len > 0 && (xw->flags & WRAPAROUND) && screen->cur_col > ScrnLeftMargin(xw)) { force_wrap = True; need_wrap = True; } next_col += width_here; screen->do_wrap = need_wrap; } while (force_wrap); } /* * Remember that we wrote something to the screen, for use as a base of * combining characters. The logic above may have called cursor-forward * or carriage-return operations which resets this flag, so we set it at * the very end. */ screen->char_was_written = True; #else /* ! OPT_WIDE_CHARS */ for (offset = 0; offset < len; offset += (Cardinal) this_col) { #if OPT_DEC_CHRSET CLineData *ld = getLineData(screen, screen->cur_row); #endif int right = ((screen->cur_col > rmargin) ? screen->max_col : rmargin); int last_col = LineMaxCol(screen, ld); if (last_col > right) last_col = right; this_col = last_col - screen->cur_col + 1; if (screen->do_wrap) { screen->do_wrap = False; if ((xw->flags & WRAPAROUND)) { WrapLine(xw); } this_col = 1; } if (offset + (Cardinal) this_col > len) { this_col = (int) (len - offset); } next_col = screen->cur_col + this_col; WriteText(xw, offset, (unsigned) this_col); /* * The call to WriteText updates screen->cur_col. * If screen->cur_col is less than next_col, we must have * hit the right margin - so set the do_wrap flag. */ screen->do_wrap = (Boolean) (screen->cur_col < next_col); } #endif /* OPT_WIDE_CHARS */ } #if OPT_WIDE_CHARS unsigned visual_width(const IChar *str, Cardinal len) { /* returns the visual width of a string (doublewide characters count as 2, normalwide characters count as 1) */ unsigned my_len = 0; while (len) { int ch = (int) *str++; if (isWide(ch)) my_len += 2; else my_len++; len--; } return my_len; } #endif #if HANDLE_STRUCT_NOTIFY /* Flag icon name with "***" on window output when iconified. */ static void HandleStructNotify(Widget w GCC_UNUSED, XtPointer closure GCC_UNUSED, XEvent *event, Boolean *cont GCC_UNUSED) { XtermWidget xw = term; TScreen *screen = TScreenOf(xw); (void) screen; TRACE_EVENT("HandleStructNotify", event, NULL, NULL); switch (event->type) { case MapNotify: resetZIconBeep(xw); mapstate = !IsUnmapped; break; case UnmapNotify: mapstate = IsUnmapped; break; case MappingNotify: XRefreshKeyboardMapping(&(event->xmapping)); VTInitModifiers(xw); break; case ConfigureNotify: if (event->xconfigure.window == XtWindow(toplevel)) { #if !OPT_TOOLBAR int height = event->xconfigure.height; int width = event->xconfigure.width; #endif #if USE_DOUBLE_BUFFER discardRenderDraw(screen); #endif /* USE_DOUBLE_BUFFER */ #if OPT_TOOLBAR /* * The notification is for the top-level widget, but we care about * vt100 (ignore the tek4014 window). */ if (screen->Vshow) { VTwin *Vwin = WhichVWin(screen); TbInfo *info = &(Vwin->tb_info); TbInfo save = *info; if (info->menu_bar) { XtVaGetValues(info->menu_bar, XtNheight, &info->menu_height, XtNborderWidth, &info->menu_border, (XtPointer) 0); if (save.menu_height != info->menu_height || save.menu_border != info->menu_border) { TRACE(("...menu_height %d\n", info->menu_height)); TRACE(("...menu_border %d\n", info->menu_border)); TRACE(("...had height %d, border %d\n", save.menu_height, save.menu_border)); /* * Window manager still may be using the old values. * Try to fool it. */ REQ_RESIZE((Widget) xw, screen->fullVwin.fullwidth, (Dimension) (info->menu_height - save.menu_height + screen->fullVwin.fullheight), NULL, NULL); repairSizeHints(); } } } #else if (!xw->work.doing_resize #if OPT_RENDERFONT && USE_DOUBLE_BUFFER && !(resource.buffered && UsingRenderFont(xw)) /* buggyXft */ #endif && (height != xw->hints.height || width != xw->hints.width)) { /* * This is a special case: other calls to RequestResize that * could set the screensize arbitrarily are via escape * sequences, and we've limited resizing. But a configure * notify is from the window manager, presumably under control * of the interactive user (ignoring abuse of wmctrl). Ignore * the limit for this case. */ int saved_limit = xw->misc.limit_resize; xw->misc.limit_resize = 0; RequestResize(xw, height, width, False); xw->misc.limit_resize = saved_limit; } #endif /* OPT_TOOLBAR */ } break; } } #endif /* HANDLE_STRUCT_NOTIFY */ #if OPT_BLINK_CURS static int DoStartBlinking(TScreen *screen) { int actual = ((screen->cursor_blink == cbTrue || screen->cursor_blink == cbAlways) ? 1 : 0); int wanted = screen->cursor_blink_esc ? 1 : 0; int result; if (screen->cursor_blink_xor) { result = actual ^ wanted; } else { result = actual | wanted; } return result; } static void SetCursorBlink(XtermWidget xw, BlinkOps enable) { TScreen *screen = TScreenOf(xw); if (SettableCursorBlink(screen)) { screen->cursor_blink = enable; } if (DoStartBlinking(screen)) { StartBlinking(xw); } else { /* EMPTY */ #if OPT_BLINK_TEXT reallyStopBlinking(xw); #else StopBlinking(xw); #endif } update_cursorblink(); } void ToggleCursorBlink(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->cursor_blink == cbTrue) { SetCursorBlink(xw, cbFalse); } else if (screen->cursor_blink == cbFalse) { SetCursorBlink(xw, cbTrue); } } #endif /* * process ANSI modes set, reset */ static void ansi_modes(XtermWidget xw, BitFunc func) { int i; for (i = 0; i < nparam; ++i) { switch (GetParam(i)) { case 2: /* KAM (if set, keyboard locked */ (*func) (&xw->keyboard.flags, MODE_KAM); break; case 4: /* IRM */ (*func) (&xw->flags, INSERT); break; case 12: /* SRM (if set, local echo */ (*func) (&xw->keyboard.flags, MODE_SRM); break; case 20: /* LNM */ (*func) (&xw->flags, LINEFEED); update_autolinefeed(); break; } } } #define IsSM() (func == bitset) #define set_bool_mode(flag) \ flag = (Boolean) IsSM() static void really_set_mousemode(XtermWidget xw, Bool enabled, XtermMouseModes mode) { TScreenOf(xw)->send_mouse_pos = enabled ? mode : MOUSE_OFF; if (okSendMousePos(xw) != MOUSE_OFF) xtermShowPointer(xw, True); } #define set_mousemode(mode) really_set_mousemode(xw, IsSM(), mode) #if OPT_PASTE64 || OPT_READLINE #define set_mouseflag(f) \ (IsSM() \ ? SCREEN_FLAG_set(screen, f) \ : SCREEN_FLAG_unset(screen, f)) #endif /* * DEC 070, pp 5-29 to 5-30 (DECLRMM). * DEC 070, pp 5-71 to 5-72 (DECCOLM). * * The descriptions for DECLRMM and DECCOLM agree that setting DECLRMM resets * double-sized mode to single-size, and that if DECLRMM is being set, then * double-sized mode is disabled. Resetting DECLRMM has no effect on the * double-sized mode. The description of DECCOLM has an apparent error in its * pseudo-code (because it is inconsistent with the description of DECLRMM), * indicating that left_right_margins_mode is changed to SETABLE no matter * which way DECCOLM is set. */ static void set_column_mode(XtermWidget xw) { TScreen *screen = TScreenOf(xw); /* switch 80/132 columns clears the screen and sets to single-width */ xterm_ResetDouble(xw); resetMargins(xw); CursorSet(screen, 0, 0, xw->flags); } /* * DEC 070, pp 5-29 to 5-30. */ static void set_left_right_margin_mode(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->vtXX_level >= 4) { if (IsLeftRightMode(xw)) { xterm_ResetDouble(xw); } else { reset_lr_margins(screen); } } } /* * process DEC private modes set, reset */ static void dpmodes(XtermWidget xw, BitFunc func) { TScreen *screen = TScreenOf(xw); int i, j; unsigned myflags; TRACE(("changing %d DEC private modes\n", nparam)); if_STATUS_LINE(screen, { return; }); for (i = 0; i < nparam; ++i) { int code = GetParam(i); TRACE(("%s %d\n", IsSM()? "DECSET" : "DECRST", code)); switch ((DECSET_codes) code) { case srm_DECCKM: (*func) (&xw->keyboard.flags, MODE_DECCKM); update_appcursor(); break; case srm_DECANM: /* ANSI/VT52 mode */ #if OPT_STATUS_LINE if (screen->status_type == 2 && screen->status_active) { /* DEC 070, section 14.2.3 item 4 */ /* EMPTY */ ; } else #endif if (IsSM()) { /* ANSI (VT100) */ /* * Setting DECANM should have no effect, since this function * cannot be reached from vt52 mode. */ /* EMPTY */ ; } #if OPT_VT52_MODE else if (screen->terminal_id >= 100) { /* VT52 */ TRACE(("DECANM terminal_id %d, vtXX_level %d\n", screen->terminal_id, screen->vtXX_level)); /* * According to DEC STD 070 section A.5.5, the various VT100 * modes have undefined behavior when entering/exiting VT52 * mode. xterm saves/restores/initializes the most commonly * used settings, but a real VT100 or VT520 may differ. * * For instance, DEC's documentation goes on to comment that * while the VT52 uses hardware tabs (8 columns), the emulation * (e.g., a VT420) does not alter those tab settings when * switching modes. */ set_vtXX_level(screen, 0); screen->vt52_save_flags = xw->flags; xw->flags = 0; screen->vt52_save_curgl = screen->curgl; screen->vt52_save_curgr = screen->curgr; screen->vt52_save_curss = screen->curss; saveCharsets(screen, screen->vt52_save_gsets); resetCharsets(screen); InitParams(); /* ignore the remaining params, if any */ update_vt52_vt100_settings(); if (AllowWindowOps(xw, ewColumnMode)) RequestResize(xw, -1, 80, True); } #endif break; case srm_DECCOLM: if (screen->c132) { Boolean willResize = ((j = IsSM() ? 132 : 80) != ((xw->flags & IN132COLUMNS) ? 132 : 80) || j != MaxCols(screen)); if (!(xw->flags & NOCLEAR_COLM)) { #if OPT_STATUS_LINE if (IsStatusShown(screen)) clear_status_line(xw); #endif ClearScreen(xw); } if (AllowWindowOps(xw, ewColumnMode) && willResize) RequestResize(xw, -1, j, True); (*func) (&xw->flags, IN132COLUMNS); set_column_mode(xw); } break; case srm_DECSCLM: /* (slow scroll) */ if (IsSM()) { screen->jumpscroll = 0; if (screen->scroll_amt) FlushScroll(xw); } else screen->jumpscroll = 1; (*func) (&xw->flags, SMOOTHSCROLL); update_jumpscroll(); break; case srm_DECSCNM: myflags = xw->flags; (*func) (&xw->flags, REVERSE_VIDEO); if ((xw->flags ^ myflags) & REVERSE_VIDEO) ReverseVideo(xw); /* update_reversevideo done in RevVid */ break; case srm_DECOM: (*func) (&xw->flags, ORIGIN); CursorSet(screen, 0, 0, xw->flags); break; case srm_DECAWM: (*func) (&xw->flags, WRAPAROUND); update_autowrap(); break; case srm_DECARM: /* ignore autorepeat * XAutoRepeatOn() and XAutoRepeatOff() can do this, but only * for the whole display - not limited to a given window. */ break; case srm_X10_MOUSE: /* MIT bogus sequence */ MotionOff(screen, xw); set_mousemode(X10_MOUSE); break; #if OPT_TOOLBAR case srm_RXVT_TOOLBAR: ShowToolbar(IsSM()); break; #else case srm_DECEDM: /* vt330:edit */ break; #endif #if OPT_BLINK_CURS case srm_ATT610_BLINK: /* AT&T 610: Start/stop blinking cursor */ if (SettableCursorBlink(screen)) { set_bool_mode(screen->cursor_blink_esc); UpdateCursorBlink(xw); } break; case srm_CURSOR_BLINK_OPS: /* intentionally ignored (this is user-preference) */ break; case srm_XOR_CURSOR_BLINKS: /* intentionally ignored (this is user-preference) */ break; #else case srm_DECKANAM: /* vt382:Katakana shift */ case srm_DECSCFDM: /* vt330:space compression field delimiter */ case srm_DECTEM: /* vt330:transmission execution */ break; #endif case srm_DECPFF: /* print form feed */ set_bool_mode(PrinterOf(screen).printer_formfeed); break; case srm_DECPEX: /* print extent */ set_bool_mode(PrinterOf(screen).printer_extent); break; case srm_DECTCEM: /* Show/hide cursor (VT200) */ set_bool_mode(screen->cursor_set); break; case srm_RXVT_SCROLLBAR: if (screen->fullVwin.sb_info.width != (IsSM()? ON : OFF)) ToggleScrollBar(xw); break; #if OPT_SHIFT_FONTS case srm_RXVT_FONTSIZE: set_bool_mode(xw->misc.shift_fonts); break; #endif #if OPT_TEK4014 case srm_DECTEK: if (IsSM() && !(screen->inhibit & I_TEK)) { FlushLog(xw); TEK4014_ACTIVE(xw) = True; TRACE(("Tek4014 is now active...\n")); update_vttekmode(); } break; #endif case srm_132COLS: /* 132 column mode */ set_bool_mode(screen->c132); update_allow132(); break; case srm_CURSES_HACK: set_bool_mode(screen->curses); update_cursesemul(); break; case srm_DECNRCM: /* national charset (VT220) */ if (screen->vtXX_level >= 2) { if ((*func) (&xw->flags, NATIONAL)) { modified_DECNRCM(xw); } } break; #if OPT_PRINT_GRAPHICS case srm_DECGEPM: /* Graphics Expanded Print Mode */ set_bool_mode(screen->graphics_expanded_print_mode); break; #endif case srm_MARGIN_BELL: /* margin bell (xterm) also DECGPCM (Graphics Print Color Mode) */ if_PRINT_GRAPHICS2(set_bool_mode(screen->graphics_print_color_mode)) { set_bool_mode(screen->marginbell); if (!screen->marginbell) screen->bellArmed = -1; update_marginbell(); } break; case srm_REVERSEWRAP: /* reverse wraparound (xterm) also DECGPCS (Graphics Print Color Syntax) */ if_PRINT_GRAPHICS2(set_bool_mode(screen->graphics_print_color_syntax)) { (*func) (&xw->flags, REVERSEWRAP); update_reversewrap(); } break; case srm_REVERSEWRAP2: /* extended reverse wraparound (xterm) */ (*func) (&xw->flags, REVERSEWRAP2); break; #ifdef ALLOWLOGGING case srm_ALLOWLOGGING: /* logging (xterm) also DECGPBM (Graphics Print Background Mode) */ if_PRINT_GRAPHICS2(set_bool_mode(screen->graphics_print_background_mode)) { #ifdef ALLOWLOGFILEONOFF /* * if this feature is enabled, logging may be * enabled and disabled via escape sequences. */ if (IsSM()) StartLog(xw); else CloseLog(xw); #else Bell(xw, XkbBI_Info, 0); Bell(xw, XkbBI_Info, 0); #endif /* ALLOWLOGFILEONOFF */ } break; #elif OPT_PRINT_GRAPHICS case srm_DECGPBM: /* Graphics Print Background Mode */ set_bool_mode(screen->graphics_print_background_mode); break; #endif /* ALLOWLOGGING */ case srm_OPT_ALTBUF_CURSOR: /* optional alternate buffer and clear (xterm) */ if (!xw->misc.titeInhibit) { if (IsSM()) { CursorSave(xw); ToAlternate(xw, True); ClearScreen(xw); } else { FromAlternate(xw, False); CursorRestore(xw); } } else if (IsSM()) { do_ti_xtra_scroll(xw); } break; case srm_OPT_ALTBUF: /* optional alternate buffer and clear (xterm) */ if (!xw->misc.titeInhibit) { if (IsSM()) { ToAlternate(xw, False); } else { if (screen->whichBuf) ClearScreen(xw); FromAlternate(xw, False); } } else if (IsSM()) { do_ti_xtra_scroll(xw); } break; case srm_ALTBUF: /* alternate buffer (xterm) also DECGRPM (Graphics Rotated Print Mode) */ if_PRINT_GRAPHICS2(set_bool_mode(screen->graphics_rotated_print_mode)) { if (!xw->misc.titeInhibit) { if (IsSM()) { ToAlternate(xw, False); } else { FromAlternate(xw, False); } } else if (IsSM()) { do_ti_xtra_scroll(xw); } } break; case srm_DECNKM: (*func) (&xw->keyboard.flags, MODE_DECKPAM); update_appkeypad(); break; case srm_DECBKM: /* back-arrow mapped to backspace or delete(D) */ (*func) (&xw->keyboard.flags, MODE_DECBKM); TRACE(("DECSET DECBKM %s\n", BtoS(xw->keyboard.flags & MODE_DECBKM))); update_decbkm(); break; case srm_DECLRMM: if (screen->vtXX_level >= 4) { /* VT420 */ (*func) (&xw->flags, LEFT_RIGHT); set_left_right_margin_mode(xw); } break; #if OPT_SIXEL_GRAPHICS case srm_DECSDM: /* sixel display mode (no scrolling) */ if (optSixelGraphics(screen)) { /* FIXME: VT24x did not scroll sixel graphics */ (*func) (&xw->keyboard.flags, MODE_DECSDM); TRACE(("DECSET/DECRST DECSDM %s (resource default is %s)\n", BtoS(xw->keyboard.flags & MODE_DECSDM), BtoS(!screen->sixel_scrolling))); update_decsdm(); } break; #endif case srm_DECNCSM: if (screen->vtXX_level >= 5) { /* VT510 */ (*func) (&xw->flags, NOCLEAR_COLM); } break; case srm_VT200_MOUSE: /* xterm bogus sequence */ MotionOff(screen, xw); set_mousemode(VT200_MOUSE); break; case srm_VT200_HIGHLIGHT_MOUSE: /* xterm sequence w/hilite tracking */ MotionOff(screen, xw); set_mousemode(VT200_HIGHLIGHT_MOUSE); break; case srm_BTN_EVENT_MOUSE: MotionOff(screen, xw); set_mousemode(BTN_EVENT_MOUSE); break; case srm_ANY_EVENT_MOUSE: set_mousemode(ANY_EVENT_MOUSE); if (screen->send_mouse_pos == MOUSE_OFF) { MotionOff(screen, xw); } else { MotionOn(screen, xw); } break; #if OPT_FOCUS_EVENT case srm_FOCUS_EVENT_MOUSE: set_bool_mode(screen->send_focus_pos); break; #endif case srm_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_SGR_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_URXVT_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_PIXEL_POSITION_MOUSE: /* * Rather than choose an arbitrary precedence among the coordinate * modes, they are mutually exclusive. For consistency, a reset is * only effective against the matching mode. */ if (IsSM()) { screen->extend_coords = code; } else if (screen->extend_coords == code) { screen->extend_coords = 0; } break; case srm_ALTERNATE_SCROLL: set_bool_mode(screen->alternateScroll); break; case srm_RXVT_SCROLL_TTY_OUTPUT: set_bool_mode(screen->scrollttyoutput); update_scrollttyoutput(); break; case srm_RXVT_SCROLL_TTY_KEYPRESS: set_bool_mode(screen->scrollkey); update_scrollkey(); break; case srm_EIGHT_BIT_META: if (screen->eight_bit_meta != ebNever) { set_bool_mode(screen->eight_bit_meta); } break; #if OPT_NUM_LOCK case srm_REAL_NUMLOCK: set_bool_mode(xw->misc.real_NumLock); update_num_lock(); break; case srm_META_SENDS_ESC: set_bool_mode(screen->meta_sends_esc); update_meta_esc(); break; #endif case srm_DELETE_IS_DEL: set_bool_mode(screen->delete_is_del); update_delete_del(); break; #if OPT_NUM_LOCK case srm_ALT_SENDS_ESC: set_bool_mode(screen->alt_sends_esc); update_alt_esc(); break; #endif case srm_KEEP_SELECTION: set_bool_mode(screen->keepSelection); update_keepSelection(); break; case srm_SELECT_TO_CLIPBOARD: set_bool_mode(screen->selectToClipboard); update_selectToClipboard(); break; case srm_BELL_IS_URGENT: set_bool_mode(screen->bellIsUrgent); update_bellIsUrgent(); break; case srm_POP_ON_BELL: set_bool_mode(screen->poponbell); update_poponbell(); break; case srm_KEEP_CLIPBOARD: set_bool_mode(screen->keepClipboard); update_keepClipboard(); break; case srm_ALLOW_ALTBUF: if (IsSM()) { xw->misc.titeInhibit = False; } else if (!xw->misc.titeInhibit) { xw->misc.titeInhibit = True; FromAlternate(xw, False); } update_titeInhibit(); break; case srm_SAVE_CURSOR: if (!xw->misc.titeInhibit) { if (IsSM()) CursorSave(xw); else CursorRestore(xw); } break; case srm_FAST_SCROLL: set_bool_mode(screen->fastscroll); break; #if OPT_TCAP_FKEYS case srm_TCAP_FKEYS: set_keyboard_type(xw, keyboardIsTermcap, IsSM()); break; #endif #if OPT_SUN_FUNC_KEYS case srm_SUN_FKEYS: set_keyboard_type(xw, keyboardIsSun, IsSM()); break; #endif #if OPT_HP_FUNC_KEYS case srm_HP_FKEYS: set_keyboard_type(xw, keyboardIsHP, IsSM()); break; #endif #if OPT_SCO_FUNC_KEYS case srm_SCO_FKEYS: set_keyboard_type(xw, keyboardIsSCO, IsSM()); break; #endif case srm_LEGACY_FKEYS: set_keyboard_type(xw, keyboardIsLegacy, IsSM()); break; #if OPT_SUNPC_KBD case srm_VT220_FKEYS: set_keyboard_type(xw, keyboardIsVT220, IsSM()); break; #endif #if OPT_PASTE64 || OPT_READLINE case srm_PASTE_IN_BRACKET: set_mouseflag(paste_brackets); break; #endif #if OPT_READLINE case srm_BUTTON1_MOVE_POINT: set_mouseflag(click1_moves); break; case srm_BUTTON2_MOVE_POINT: set_mouseflag(paste_moves); break; case srm_DBUTTON3_DELETE: set_mouseflag(dclick3_deletes); break; case srm_PASTE_QUOTE: set_mouseflag(paste_quotes); break; case srm_PASTE_LITERAL_NL: set_mouseflag(paste_literal_nl); break; #endif /* OPT_READLINE */ #if OPT_GRAPHICS case srm_PRIVATE_COLOR_REGISTERS: /* private color registers for each graphic */ TRACE(("DECSET/DECRST PRIVATE_COLOR_REGISTERS to %s (resource default is %s)\n", BtoS(screen->privatecolorregisters), BtoS(screen->privatecolorregisters0))); set_bool_mode(screen->privatecolorregisters); update_privatecolorregisters(); break; #endif #if OPT_SIXEL_GRAPHICS case srm_SIXEL_SCROLLS_RIGHT: /* sixel scrolling moves cursor to right */ if (optSixelGraphics(screen)) { /* FIXME: VT24x did not scroll sixel graphics */ set_bool_mode(screen->sixel_scrolls_right); TRACE(("DECSET/DECRST SIXEL_SCROLLS_RIGHT to %s (resource default is %s)\n", BtoS(screen->sixel_scrolls_right), BtoS(TScreenOf(xw)->sixel_scrolls_right))); } break; #endif case srm_DEC131TM: /* ignore */ case srm_DECAAM: /* ignore */ case srm_DECARSM: /* ignore */ case srm_DECATCBM: /* ignore */ case srm_DECATCUM: /* ignore */ case srm_DECBBSM: /* ignore */ case srm_DECCANSM: /* ignore */ case srm_DECCAPSLK: /* ignore */ case srm_DECCRTSM: /* ignore */ case srm_DECECM: /* ignore */ case srm_DECEKEM: /* ignore */ case srm_DECESKM: /* ignore */ case srm_DECFWM: /* ignore */ case srm_DECHCCM: /* ignore */ case srm_DECHDPXM: /* ignore */ case srm_DECHEM: /* ignore */ case srm_DECHWUM: /* ignore */ case srm_DECIPEM: /* ignore */ case srm_DECKBUM: /* ignore */ case srm_DECKLHIM: /* ignore */ case srm_DECKKDM: /* ignore */ case srm_DECKPM: /* ignore */ case srm_DECLTM: /* ignore */ case srm_DECMCM: /* ignore */ case srm_DECNAKB: /* ignore */ case srm_DECNULM: /* ignore */ case srm_DECNUMLK: /* ignore */ case srm_DECOSCNM: /* ignore */ case srm_DECPCCM: /* ignore */ case srm_DECRLCM: /* ignore */ case srm_DECRLM: /* ignore */ case srm_DECRPL: /* ignore */ case srm_DECVCCM: /* ignore */ case srm_DECXRLM: /* ignore */ default: TRACE(("DATA_ERROR: unknown private code %d\n", code)); break; } } } /* * process xterm private modes save */ static void savemodes(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int i; if_STATUS_LINE(screen, { return; }); for (i = 0; i < nparam; i++) { int code = GetParam(i); TRACE(("savemodes %d\n", code)); switch ((DECSET_codes) code) { case srm_DECCKM: DoSM(DP_DECCKM, xw->keyboard.flags & MODE_DECCKM); break; case srm_DECANM: /* ANSI/VT52 mode */ /* no effect */ break; case srm_DECCOLM: if (screen->c132) DoSM(DP_DECCOLM, xw->flags & IN132COLUMNS); break; case srm_DECSCLM: /* (slow scroll) */ DoSM(DP_DECSCLM, xw->flags & SMOOTHSCROLL); break; case srm_DECSCNM: DoSM(DP_DECSCNM, xw->flags & REVERSE_VIDEO); break; case srm_DECOM: DoSM(DP_DECOM, xw->flags & ORIGIN); break; case srm_DECAWM: DoSM(DP_DECAWM, xw->flags & WRAPAROUND); break; case srm_DECARM: /* ignore autorepeat */ break; case srm_X10_MOUSE: /* mouse bogus sequence */ DoSM(DP_X_X10MSE, screen->send_mouse_pos); break; #if OPT_TOOLBAR case srm_RXVT_TOOLBAR: DoSM(DP_TOOLBAR, resource.toolBar); break; #else case srm_DECEDM: /* vt330:edit */ break; #endif #if OPT_BLINK_CURS case srm_ATT610_BLINK: /* AT&T 610: Start/stop blinking cursor */ if (SettableCursorBlink(screen)) { DoSM(DP_CRS_BLINK, screen->cursor_blink_esc); } break; case srm_CURSOR_BLINK_OPS: /* intentionally ignored (this is user-preference) */ break; case srm_XOR_CURSOR_BLINKS: /* intentionally ignored (this is user-preference) */ break; #else case srm_DECKANAM: /* vt382:Katakana shift */ case srm_DECSCFDM: /* vt330:space compression field delimiter */ case srm_DECTEM: /* vt330:transmission execution */ break; #endif case srm_DECPFF: /* print form feed */ DoSM(DP_PRN_FORMFEED, PrinterOf(screen).printer_formfeed); break; case srm_DECPEX: /* print extent */ DoSM(DP_PRN_EXTENT, PrinterOf(screen).printer_extent); break; case srm_DECTCEM: /* Show/hide cursor (VT200) */ DoSM(DP_CRS_VISIBLE, screen->cursor_set); break; case srm_RXVT_SCROLLBAR: DoSM(DP_RXVT_SCROLLBAR, (screen->fullVwin.sb_info.width != 0)); break; #if OPT_SHIFT_FONTS case srm_RXVT_FONTSIZE: DoSM(DP_RXVT_FONTSIZE, xw->misc.shift_fonts); break; #endif #if OPT_TEK4014 case srm_DECTEK: DoSM(DP_DECTEK, TEK4014_ACTIVE(xw)); break; #endif case srm_132COLS: /* 132 column mode */ DoSM(DP_X_DECCOLM, screen->c132); break; case srm_CURSES_HACK: /* curses hack */ DoSM(DP_X_MORE, screen->curses); break; case srm_DECNRCM: /* national charset (VT220) */ if (screen->vtXX_level >= 2) { DoSM(DP_DECNRCM, xw->flags & NATIONAL); } break; #if OPT_PRINT_GRAPHICS case srm_DECGEPM: /* Graphics Expanded Print Mode */ DoSM(DP_DECGEPM, screen->graphics_expanded_print_mode); break; #endif case srm_MARGIN_BELL: /* margin bell (xterm) also DECGPCM (Graphics Print Color Mode) */ if_PRINT_GRAPHICS2(DoSM(DP_DECGPCM, screen->graphics_print_color_mode)) { DoSM(DP_X_MARGIN, screen->marginbell); } break; case srm_REVERSEWRAP: /* reverse wraparound (xterm) also DECGPCS (Graphics Print Color Syntax) */ if_PRINT_GRAPHICS2(DoSM(DP_DECGPCS, screen->graphics_print_color_syntax)) { DoSM(DP_X_REVWRAP, xw->flags & REVERSEWRAP); } break; case srm_REVERSEWRAP2: /* extended reverse wraparound (xterm) */ DoSM(DP_X_REVWRAP2, xw->flags & REVERSEWRAP2); break; #ifdef ALLOWLOGGING case srm_ALLOWLOGGING: /* logging (xterm) also DECGPBM (Graphics Print Background Mode) */ if_PRINT_GRAPHICS2(DoSM(DP_DECGPBM, screen->graphics_print_background_mode)) { #ifdef ALLOWLOGFILEONOFF DoSM(DP_X_LOGGING, screen->logging); #endif /* ALLOWLOGFILEONOFF */ } break; #elif OPT_PRINT_GRAPHICS case srm_DECGPBM: /* Graphics Print Background Mode */ DoSM(DP_DECGPBM, screen->graphics_print_background_mode); break; #endif /* ALLOWLOGGING */ case srm_OPT_ALTBUF_CURSOR: /* optional alternate buffer and clear (xterm) */ /* FALLTHRU */ case srm_OPT_ALTBUF: /* optional alternate buffer and clear (xterm) */ DoSM(DP_X_ALTBUF, screen->whichBuf); break; case srm_ALTBUF: /* alternate buffer (xterm) also DECGRPM (Graphics Rotated Print Mode) */ if_PRINT_GRAPHICS2(DoSM(DP_DECGRPM, screen->graphics_rotated_print_mode)) { DoSM(DP_X_ALTBUF, screen->whichBuf); } break; case srm_DECNKM: DoSM(DP_DECKPAM, xw->keyboard.flags & MODE_DECKPAM); break; case srm_DECBKM: /* backarrow mapping */ DoSM(DP_DECBKM, xw->keyboard.flags & MODE_DECBKM); break; case srm_DECLRMM: /* left-right */ DoSM(DP_X_LRMM, LEFT_RIGHT); break; #if OPT_SIXEL_GRAPHICS case srm_DECSDM: /* sixel display mode (no scroll) */ DoSM(DP_DECSDM, xw->keyboard.flags & MODE_DECSDM); update_decsdm(); break; #endif case srm_DECNCSM: /* noclear */ DoSM(DP_X_NCSM, NOCLEAR_COLM); break; case srm_VT200_MOUSE: /* mouse bogus sequence */ /* FALLTHRU */ case srm_VT200_HIGHLIGHT_MOUSE: /* FALLTHRU */ case srm_BTN_EVENT_MOUSE: /* FALLTHRU */ case srm_ANY_EVENT_MOUSE: DoSM(DP_X_MOUSE, screen->send_mouse_pos); break; #if OPT_FOCUS_EVENT case srm_FOCUS_EVENT_MOUSE: DoSM(DP_X_FOCUS, screen->send_focus_pos); break; #endif case srm_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_SGR_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_URXVT_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_PIXEL_POSITION_MOUSE: DoSM(DP_X_EXT_MOUSE, screen->extend_coords); break; case srm_ALTERNATE_SCROLL: DoSM(DP_ALTERNATE_SCROLL, screen->alternateScroll); break; case srm_RXVT_SCROLL_TTY_OUTPUT: DoSM(DP_RXVT_SCROLL_TTY_OUTPUT, screen->scrollttyoutput); break; case srm_RXVT_SCROLL_TTY_KEYPRESS: DoSM(DP_RXVT_SCROLL_TTY_KEYPRESS, screen->scrollkey); break; case srm_EIGHT_BIT_META: DoSM(DP_EIGHT_BIT_META, screen->eight_bit_meta); break; #if OPT_NUM_LOCK case srm_REAL_NUMLOCK: DoSM(DP_REAL_NUMLOCK, xw->misc.real_NumLock); break; case srm_META_SENDS_ESC: DoSM(DP_META_SENDS_ESC, screen->meta_sends_esc); break; #endif case srm_DELETE_IS_DEL: DoSM(DP_DELETE_IS_DEL, screen->delete_is_del); break; #if OPT_NUM_LOCK case srm_ALT_SENDS_ESC: DoSM(DP_ALT_SENDS_ESC, screen->alt_sends_esc); break; #endif case srm_KEEP_SELECTION: DoSM(DP_KEEP_SELECTION, screen->keepSelection); break; case srm_SELECT_TO_CLIPBOARD: DoSM(DP_SELECT_TO_CLIPBOARD, screen->selectToClipboard); break; case srm_BELL_IS_URGENT: DoSM(DP_BELL_IS_URGENT, screen->bellIsUrgent); break; case srm_POP_ON_BELL: DoSM(DP_POP_ON_BELL, screen->poponbell); break; case srm_KEEP_CLIPBOARD: DoSM(DP_KEEP_CLIPBOARD, screen->keepClipboard); break; #if OPT_TCAP_FKEYS case srm_TCAP_FKEYS: /* FALLTHRU */ #endif #if OPT_SUN_FUNC_KEYS case srm_SUN_FKEYS: /* FALLTHRU */ #endif #if OPT_HP_FUNC_KEYS case srm_HP_FKEYS: /* FALLTHRU */ #endif #if OPT_SCO_FUNC_KEYS case srm_SCO_FKEYS: /* FALLTHRU */ #endif #if OPT_SUNPC_KBD case srm_VT220_FKEYS: /* FALLTHRU */ #endif case srm_LEGACY_FKEYS: DoSM(DP_KEYBOARD_TYPE, xw->keyboard.type); break; case srm_ALLOW_ALTBUF: DoSM(DP_ALLOW_ALTBUF, xw->misc.titeInhibit); break; case srm_SAVE_CURSOR: if (!xw->misc.titeInhibit) { CursorSave(xw); } break; case srm_FAST_SCROLL: DoSM(DP_FAST_SCROLL, screen->fastscroll); break; #if OPT_PASTE64 || OPT_READLINE case srm_PASTE_IN_BRACKET: SCREEN_FLAG_save(screen, paste_brackets); break; #endif #if OPT_READLINE case srm_BUTTON1_MOVE_POINT: SCREEN_FLAG_save(screen, click1_moves); break; case srm_BUTTON2_MOVE_POINT: SCREEN_FLAG_save(screen, paste_moves); break; case srm_DBUTTON3_DELETE: SCREEN_FLAG_save(screen, dclick3_deletes); break; case srm_PASTE_QUOTE: SCREEN_FLAG_save(screen, paste_quotes); break; case srm_PASTE_LITERAL_NL: SCREEN_FLAG_save(screen, paste_literal_nl); break; #endif /* OPT_READLINE */ #if OPT_GRAPHICS case srm_PRIVATE_COLOR_REGISTERS: /* private color registers for each graphic */ TRACE(("save PRIVATE_COLOR_REGISTERS %s\n", BtoS(screen->privatecolorregisters))); DoSM(DP_X_PRIVATE_COLOR_REGISTERS, screen->privatecolorregisters); update_privatecolorregisters(); break; #endif #if OPT_SIXEL_GRAPHICS case srm_SIXEL_SCROLLS_RIGHT: TRACE(("save SIXEL_SCROLLS_RIGHT %s\n", BtoS(screen->sixel_scrolls_right))); DoSM(DP_SIXEL_SCROLLS_RIGHT, screen->sixel_scrolls_right); break; #endif case srm_DEC131TM: /* ignore */ case srm_DECAAM: /* ignore */ case srm_DECARSM: /* ignore */ case srm_DECATCBM: /* ignore */ case srm_DECATCUM: /* ignore */ case srm_DECBBSM: /* ignore */ case srm_DECCANSM: /* ignore */ case srm_DECCAPSLK: /* ignore */ case srm_DECCRTSM: /* ignore */ case srm_DECECM: /* ignore */ case srm_DECEKEM: /* ignore */ case srm_DECESKM: /* ignore */ case srm_DECFWM: /* ignore */ case srm_DECHCCM: /* ignore */ case srm_DECHDPXM: /* ignore */ case srm_DECHEM: /* ignore */ case srm_DECHWUM: /* ignore */ case srm_DECIPEM: /* ignore */ case srm_DECKBUM: /* ignore */ case srm_DECKKDM: /* ignore */ case srm_DECKLHIM: /* ignore */ case srm_DECKPM: /* ignore */ case srm_DECLTM: /* ignore */ case srm_DECMCM: /* ignore */ case srm_DECNAKB: /* ignore */ case srm_DECNULM: /* ignore */ case srm_DECNUMLK: /* ignore */ case srm_DECOSCNM: /* ignore */ case srm_DECPCCM: /* ignore */ case srm_DECRLCM: /* ignore */ case srm_DECRLM: /* ignore */ case srm_DECRPL: /* ignore */ case srm_DECVCCM: /* ignore */ case srm_DECXRLM: /* ignore */ default: break; } } } /* * process xterm private modes restore */ static void restoremodes(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int i, j; if_STATUS_LINE(screen, { return; }); for (i = 0; i < nparam; i++) { int code = GetParam(i); TRACE(("restoremodes %d\n", code)); switch ((DECSET_codes) code) { case srm_DECCKM: bitcpy(&xw->keyboard.flags, screen->save_modes[DP_DECCKM], MODE_DECCKM); update_appcursor(); break; case srm_DECANM: /* ANSI/VT52 mode */ /* no effect */ break; case srm_DECCOLM: if (screen->c132) { if (!(xw->flags & NOCLEAR_COLM)) ClearScreen(xw); CursorSet(screen, 0, 0, xw->flags); if ((j = (screen->save_modes[DP_DECCOLM] & IN132COLUMNS) ? 132 : 80) != ((xw->flags & IN132COLUMNS) ? 132 : 80) || j != MaxCols(screen)) { if (AllowWindowOps(xw, ewColumnMode)) RequestResize(xw, -1, j, True); } bitcpy(&xw->flags, screen->save_modes[DP_DECCOLM], IN132COLUMNS); } break; case srm_DECSCLM: /* (slow scroll) */ if (screen->save_modes[DP_DECSCLM] & SMOOTHSCROLL) { screen->jumpscroll = 0; if (screen->scroll_amt) FlushScroll(xw); } else screen->jumpscroll = 1; bitcpy(&xw->flags, screen->save_modes[DP_DECSCLM], SMOOTHSCROLL); update_jumpscroll(); break; case srm_DECSCNM: if ((screen->save_modes[DP_DECSCNM] ^ xw->flags) & REVERSE_VIDEO) { bitcpy(&xw->flags, screen->save_modes[DP_DECSCNM], REVERSE_VIDEO); ReverseVideo(xw); /* update_reversevideo done in RevVid */ } break; case srm_DECOM: bitcpy(&xw->flags, screen->save_modes[DP_DECOM], ORIGIN); CursorSet(screen, 0, 0, xw->flags); break; case srm_DECAWM: bitcpy(&xw->flags, screen->save_modes[DP_DECAWM], WRAPAROUND); update_autowrap(); break; case srm_DECARM: /* ignore autorepeat */ break; case srm_X10_MOUSE: /* MIT bogus sequence */ DoRM0(DP_X_X10MSE, screen->send_mouse_pos); really_set_mousemode(xw, screen->send_mouse_pos != MOUSE_OFF, (XtermMouseModes) screen->send_mouse_pos); break; #if OPT_TOOLBAR case srm_RXVT_TOOLBAR: DoRM(DP_TOOLBAR, resource.toolBar); ShowToolbar(resource.toolBar); break; #else case srm_DECEDM: /* vt330:edit */ break; #endif #if OPT_BLINK_CURS case srm_ATT610_BLINK: /* Start/stop blinking cursor */ if (SettableCursorBlink(screen)) { DoRM(DP_CRS_BLINK, screen->cursor_blink_esc); UpdateCursorBlink(xw); } break; case srm_CURSOR_BLINK_OPS: /* intentionally ignored (this is user-preference) */ break; case srm_XOR_CURSOR_BLINKS: /* intentionally ignored (this is user-preference) */ break; #else case srm_DECKANAM: /* vt382:Katakana shift */ case srm_DECSCFDM: /* vt330:space compression field delimiter */ case srm_DECTEM: /* vt330:transmission execution */ break; #endif case srm_DECPFF: /* print form feed */ DoRM(DP_PRN_FORMFEED, PrinterOf(screen).printer_formfeed); break; case srm_DECPEX: /* print extent */ DoRM(DP_PRN_EXTENT, PrinterOf(screen).printer_extent); break; case srm_DECTCEM: /* Show/hide cursor (VT200) */ DoRM(DP_CRS_VISIBLE, screen->cursor_set); updateCursor(xw); break; case srm_RXVT_SCROLLBAR: if ((screen->fullVwin.sb_info.width != 0) != screen->save_modes[DP_RXVT_SCROLLBAR]) { ToggleScrollBar(xw); } break; #if OPT_SHIFT_FONTS case srm_RXVT_FONTSIZE: DoRM(DP_RXVT_FONTSIZE, xw->misc.shift_fonts); break; #endif #if OPT_TEK4014 case srm_DECTEK: if (!(screen->inhibit & I_TEK) && (TEK4014_ACTIVE(xw) != (Boolean) screen->save_modes[DP_DECTEK])) { FlushLog(xw); TEK4014_ACTIVE(xw) = (Boolean) screen->save_modes[DP_DECTEK]; update_vttekmode(); } break; #endif case srm_132COLS: /* 132 column mode */ DoRM(DP_X_DECCOLM, screen->c132); update_allow132(); break; case srm_CURSES_HACK: /* curses hack */ DoRM(DP_X_MORE, screen->curses); update_cursesemul(); break; case srm_DECNRCM: /* national charset (VT220) */ if (screen->vtXX_level >= 2) { if (bitcpy(&xw->flags, screen->save_modes[DP_DECNRCM], NATIONAL)) modified_DECNRCM(xw); } break; #if OPT_PRINT_GRAPHICS case srm_DECGEPM: /* Graphics Expanded Print Mode */ DoRM(DP_DECGEPM, screen->graphics_expanded_print_mode); break; #endif case srm_MARGIN_BELL: /* margin bell (xterm) also DECGPCM (Graphics Print Color Mode) */ if_PRINT_GRAPHICS2(DoRM(DP_DECGPCM, screen->graphics_print_color_mode)) { if ((DoRM(DP_X_MARGIN, screen->marginbell)) == 0) screen->bellArmed = -1; update_marginbell(); } break; case srm_REVERSEWRAP: /* reverse wraparound (xterm) also DECGPCS (Graphics Print Color Syntax) */ if_PRINT_GRAPHICS2(DoRM(DP_DECGPCS, screen->graphics_print_color_syntax)) { bitcpy(&xw->flags, screen->save_modes[DP_X_REVWRAP], REVERSEWRAP); update_reversewrap(); } break; case srm_REVERSEWRAP2: /* extended reverse wraparound (xterm) */ bitcpy(&xw->flags, screen->save_modes[DP_X_REVWRAP2], REVERSEWRAP2); break; #ifdef ALLOWLOGGING case srm_ALLOWLOGGING: /* logging (xterm) also DECGPBM (Graphics Print Background Mode) */ if_PRINT_GRAPHICS2(DoRM(DP_DECGPBM, screen->graphics_print_background_mode)) { #ifdef ALLOWLOGFILEONOFF if (screen->save_modes[DP_X_LOGGING]) StartLog(xw); else CloseLog(xw); #endif /* ALLOWLOGFILEONOFF */ /* update_logging done by StartLog and CloseLog */ } break; #elif OPT_PRINT_GRAPHICS case srm_DECGPBM: /* Graphics Print Background Mode */ DoRM(DP_DECGPBM, screen->graphics_print_background_mode); break; #endif /* ALLOWLOGGING */ case srm_OPT_ALTBUF_CURSOR: /* optional alternate buffer and clear (xterm) */ /* FALLTHRU */ case srm_OPT_ALTBUF: /* optional alternate buffer and clear (xterm) */ if (!xw->misc.titeInhibit) { if (screen->save_modes[DP_X_ALTBUF]) ToAlternate(xw, False); else FromAlternate(xw, False); /* update_altscreen done by ToAlt and FromAlt */ } else if (screen->save_modes[DP_X_ALTBUF]) { do_ti_xtra_scroll(xw); } break; case srm_ALTBUF: /* alternate buffer (xterm) also DECGRPM (Graphics Rotated Print Mode) */ if_PRINT_GRAPHICS2(DoRM(DP_DECGRPM, screen->graphics_rotated_print_mode)) { if (!xw->misc.titeInhibit) { if (screen->save_modes[DP_X_ALTBUF]) ToAlternate(xw, False); else FromAlternate(xw, False); /* update_altscreen done by ToAlt and FromAlt */ } else if (screen->save_modes[DP_X_ALTBUF]) { do_ti_xtra_scroll(xw); } } break; case srm_DECNKM: bitcpy(&xw->flags, screen->save_modes[DP_DECKPAM], MODE_DECKPAM); update_appkeypad(); break; case srm_DECBKM: /* backarrow mapping */ bitcpy(&xw->flags, screen->save_modes[DP_DECBKM], MODE_DECBKM); update_decbkm(); break; case srm_DECLRMM: /* left-right */ bitcpy(&xw->flags, screen->save_modes[DP_X_LRMM], LEFT_RIGHT); if (IsLeftRightMode(xw)) { xterm_ResetDouble(xw); } else { reset_lr_margins(screen); } break; #if OPT_SIXEL_GRAPHICS case srm_DECSDM: /* sixel display mode (no scroll) */ bitcpy(&xw->keyboard.flags, screen->save_modes[DP_DECSDM], MODE_DECSDM); update_decsdm(); break; #endif case srm_DECNCSM: /* noclear */ bitcpy(&xw->flags, screen->save_modes[DP_X_NCSM], NOCLEAR_COLM); break; case srm_VT200_MOUSE: /* mouse bogus sequence */ /* FALLTHRU */ case srm_VT200_HIGHLIGHT_MOUSE: /* FALLTHRU */ case srm_BTN_EVENT_MOUSE: /* FALLTHRU */ case srm_ANY_EVENT_MOUSE: DoRM0(DP_X_MOUSE, screen->send_mouse_pos); really_set_mousemode(xw, screen->send_mouse_pos != MOUSE_OFF, (XtermMouseModes) screen->send_mouse_pos); break; #if OPT_FOCUS_EVENT case srm_FOCUS_EVENT_MOUSE: DoRM(DP_X_FOCUS, screen->send_focus_pos); break; #endif case srm_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_SGR_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_URXVT_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_PIXEL_POSITION_MOUSE: DoRM(DP_X_EXT_MOUSE, screen->extend_coords); break; case srm_ALLOW_ALTBUF: DoRM(DP_ALLOW_ALTBUF, xw->misc.titeInhibit); if (xw->misc.titeInhibit) FromAlternate(xw, False); update_titeInhibit(); break; case srm_SAVE_CURSOR: if (!xw->misc.titeInhibit) { CursorRestore(xw); } break; case srm_FAST_SCROLL: DoRM(DP_FAST_SCROLL, screen->fastscroll); break; case srm_ALTERNATE_SCROLL: DoRM(DP_ALTERNATE_SCROLL, screen->alternateScroll); break; case srm_RXVT_SCROLL_TTY_OUTPUT: DoRM(DP_RXVT_SCROLL_TTY_OUTPUT, screen->scrollttyoutput); update_scrollttyoutput(); break; case srm_RXVT_SCROLL_TTY_KEYPRESS: DoRM(DP_RXVT_SCROLL_TTY_KEYPRESS, screen->scrollkey); update_scrollkey(); break; case srm_EIGHT_BIT_META: DoRM(DP_EIGHT_BIT_META, screen->eight_bit_meta); break; #if OPT_NUM_LOCK case srm_REAL_NUMLOCK: DoRM(DP_REAL_NUMLOCK, xw->misc.real_NumLock); update_num_lock(); break; case srm_META_SENDS_ESC: DoRM(DP_META_SENDS_ESC, screen->meta_sends_esc); update_meta_esc(); break; #endif case srm_DELETE_IS_DEL: DoRM(DP_DELETE_IS_DEL, screen->delete_is_del); update_delete_del(); break; #if OPT_NUM_LOCK case srm_ALT_SENDS_ESC: DoRM(DP_ALT_SENDS_ESC, screen->alt_sends_esc); update_alt_esc(); break; #endif case srm_KEEP_SELECTION: DoRM(DP_KEEP_SELECTION, screen->keepSelection); update_keepSelection(); break; case srm_SELECT_TO_CLIPBOARD: DoRM(DP_SELECT_TO_CLIPBOARD, screen->selectToClipboard); update_selectToClipboard(); break; case srm_BELL_IS_URGENT: DoRM(DP_BELL_IS_URGENT, screen->bellIsUrgent); update_bellIsUrgent(); break; case srm_POP_ON_BELL: DoRM(DP_POP_ON_BELL, screen->poponbell); update_poponbell(); break; case srm_KEEP_CLIPBOARD: DoRM(DP_KEEP_CLIPBOARD, screen->keepClipboard); update_keepClipboard(); break; #if OPT_TCAP_FKEYS case srm_TCAP_FKEYS: /* FALLTHRU */ #endif #if OPT_SUN_FUNC_KEYS case srm_SUN_FKEYS: /* FALLTHRU */ #endif #if OPT_HP_FUNC_KEYS case srm_HP_FKEYS: /* FALLTHRU */ #endif #if OPT_SCO_FUNC_KEYS case srm_SCO_FKEYS: /* FALLTHRU */ #endif #if OPT_SUNPC_KBD case srm_VT220_FKEYS: /* FALLTHRU */ #endif case srm_LEGACY_FKEYS: xw->keyboard.type = (xtermKeyboardType) screen->save_modes[DP_KEYBOARD_TYPE]; break; #if OPT_PASTE64 || OPT_READLINE case srm_PASTE_IN_BRACKET: SCREEN_FLAG_restore(screen, paste_brackets); break; #endif #if OPT_READLINE case srm_BUTTON1_MOVE_POINT: SCREEN_FLAG_restore(screen, click1_moves); break; case srm_BUTTON2_MOVE_POINT: SCREEN_FLAG_restore(screen, paste_moves); break; case srm_DBUTTON3_DELETE: SCREEN_FLAG_restore(screen, dclick3_deletes); break; case srm_PASTE_QUOTE: SCREEN_FLAG_restore(screen, paste_quotes); break; case srm_PASTE_LITERAL_NL: SCREEN_FLAG_restore(screen, paste_literal_nl); break; #endif /* OPT_READLINE */ #if OPT_GRAPHICS case srm_PRIVATE_COLOR_REGISTERS: /* private color registers for each graphic */ TRACE(("restore PRIVATE_COLOR_REGISTERS before: %s\n", BtoS(screen->privatecolorregisters))); DoRM(DP_X_PRIVATE_COLOR_REGISTERS, screen->privatecolorregisters); TRACE(("restore PRIVATE_COLOR_REGISTERS after: %s\n", BtoS(screen->privatecolorregisters))); update_privatecolorregisters(); break; #endif #if OPT_SIXEL_GRAPHICS case srm_SIXEL_SCROLLS_RIGHT: TRACE(("restore SIXEL_SCROLLS_RIGHT before: %s\n", BtoS(screen->sixel_scrolls_right))); DoRM(DP_SIXEL_SCROLLS_RIGHT, screen->sixel_scrolls_right); TRACE(("restore SIXEL_SCROLLS_RIGHT after: %s\n", BtoS(screen->sixel_scrolls_right))); break; #endif case srm_DEC131TM: /* ignore */ case srm_DECAAM: /* ignore */ case srm_DECARSM: /* ignore */ case srm_DECATCBM: /* ignore */ case srm_DECATCUM: /* ignore */ case srm_DECBBSM: /* ignore */ case srm_DECCANSM: /* ignore */ case srm_DECCAPSLK: /* ignore */ case srm_DECCRTSM: /* ignore */ case srm_DECECM: /* ignore */ case srm_DECEKEM: /* ignore */ case srm_DECESKM: /* ignore */ case srm_DECFWM: /* ignore */ case srm_DECHCCM: /* ignore */ case srm_DECHDPXM: /* ignore */ case srm_DECHEM: /* ignore */ case srm_DECHWUM: /* ignore */ case srm_DECIPEM: /* ignore */ case srm_DECKBUM: /* ignore */ case srm_DECKKDM: /* ignore */ case srm_DECKLHIM: /* ignore */ case srm_DECKPM: /* ignore */ case srm_DECLTM: /* ignore */ case srm_DECMCM: /* ignore */ case srm_DECNAKB: /* ignore */ case srm_DECNULM: /* ignore */ case srm_DECNUMLK: /* ignore */ case srm_DECOSCNM: /* ignore */ case srm_DECPCCM: /* ignore */ case srm_DECRLCM: /* ignore */ case srm_DECRLM: /* ignore */ case srm_DECRPL: /* ignore */ case srm_DECVCCM: /* ignore */ case srm_DECXRLM: /* ignore */ default: break; } } } /* * Convert an XTextProperty to a string. * * This frees the data owned by the XTextProperty, and returns in its place the * string, which must be freed by the caller. */ static char * property_to_string(XtermWidget xw, XTextProperty * text) { TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; char *result = NULL; char **list = NULL; int length = 0; int rc; TRACE(("property_to_string value %p, encoding %s, format %d, nitems %ld\n", text->value, TraceAtomName(dpy, text->encoding), text->format, text->nitems)); #if OPT_WIDE_CHARS /* * We will use the XmbTextPropertyToTextList call to extract UTF-8 data. * The xtermUtf8ToTextList() call is used to convert UTF-8 explicitly to * ISO-8859-1. */ rc = -1; if ((text->format != 8) || IsTitleMode(xw, tmGetUtf8) || (text->encoding == XA_UTF8_STRING(dpy) && !(screen->wide_chars || screen->c1_printable) && (rc = xtermUtf8ToTextList(xw, text, &list, &length)) < 0) || (rc < 0)) #endif if ((rc = XmbTextPropertyToTextList(dpy, text, &list, &length)) < 0) rc = XTextPropertyToStringList(text, &list, &length); if (rc >= 0) { int n, c, pass; size_t need; for (pass = 0; pass < 2; ++pass) { for (n = 0, need = 0; n < length; n++) { char *s = list[n]; while ((c = *s++) != '\0') { if (pass) result[need] = (char) c; ++need; } } if (pass) result[need] = '\0'; else result = malloc(need + 1); if (result == NULL) break; } XFreeStringList(list); } if (text->value != NULL) XFree(text->value); return result; } static char * get_icon_label(XtermWidget xw) { XTextProperty text; char *result = NULL; if (XGetWMIconName(TScreenOf(xw)->display, VShellWindow(xw), &text)) { result = property_to_string(xw, &text); } return result; } static char * get_window_label(XtermWidget xw) { XTextProperty text; char *result = NULL; if (XGetWMName(TScreenOf(xw)->display, VShellWindow(xw), &text)) { result = property_to_string(xw, &text); } return result; } /* * Report window label (icon or title) in dtterm protocol * ESC ] code label ESC backslash */ static void report_win_label(XtermWidget xw, int code, char *text) { unparseputc(xw, ANSI_ESC); unparseputc(xw, ']'); unparseputc(xw, code); if (text != NULL) { int copy = IsTitleMode(xw, tmGetBase16); if (copy) { TRACE(("Encoding hex:%s\n", text)); text = x_encode_hex(text); } unparseputs(xw, text); if (copy) free(text); } unparseputc(xw, ANSI_ESC); unparseputc(xw, '\\'); /* should be ST */ unparse_end(xw); } /* * Window operations (from CDE dtterm description, as well as extensions). * See also "allowWindowOps" resource. */ static void window_ops(XtermWidget xw) { TScreen *screen = TScreenOf(xw); XWindowChanges values; XWindowAttributes win_attrs; #if OPT_MAXIMIZE unsigned root_width; unsigned root_height; #endif int code = zero_if_default(0); char *label; TRACE(("window_ops %d\n", code)); switch (code) { case ewRestoreWin: /* Restore (de-iconify) window */ if (AllowWindowOps(xw, ewRestoreWin)) { xtermDeiconify(xw); } break; case ewMinimizeWin: /* Minimize (iconify) window */ if (AllowWindowOps(xw, ewMinimizeWin)) { xtermIconify(xw); } break; case ewSetWinPosition: /* Move the window to the given position */ if (AllowWindowOps(xw, ewSetWinPosition)) { unsigned value_mask; values.x = (Position) zero_if_default(1); values.y = (Position) zero_if_default(2); TRACE(("...move window to %d,%d\n", values.x, values.y)); value_mask = (CWX | CWY); XReconfigureWMWindow(screen->display, VShellWindow(xw), DefaultScreen(screen->display), value_mask, &values); } break; case ewSetWinSizePixels: /* Resize the window to given size in pixels */ if (AllowWindowOps(xw, ewSetWinSizePixels)) { RequestResize(xw, optional_param(1), optional_param(2), False); } break; case ewRaiseWin: /* Raise the window to the front of the stack */ if (AllowWindowOps(xw, ewRaiseWin)) { TRACE(("...raise window\n")); XRaiseWindow(screen->display, VShellWindow(xw)); } break; case ewLowerWin: /* Lower the window to the bottom of the stack */ if (AllowWindowOps(xw, ewLowerWin)) { TRACE(("...lower window\n")); XLowerWindow(screen->display, VShellWindow(xw)); } break; case ewRefreshWin: /* Refresh the window */ if (AllowWindowOps(xw, ewRefreshWin)) { TRACE(("...redraw window\n")); Redraw(); } break; case ewSetWinSizeChars: /* Resize the text-area, in characters */ if (AllowWindowOps(xw, ewSetWinSizeChars)) { RequestResize(xw, optional_param(1), optional_param(2), True); } break; #if OPT_MAXIMIZE case ewMaximizeWin: /* Maximize or restore */ if (AllowWindowOps(xw, ewMaximizeWin)) { RequestMaximize(xw, zero_if_default(1)); } break; case ewFullscreenWin: /* Fullscreen or restore */ if (AllowWindowOps(xw, ewFullscreenWin)) { switch (zero_if_default(1)) { default: RequestMaximize(xw, 0); break; case 1: RequestMaximize(xw, 1); break; case 2: RequestMaximize(xw, !(screen->restore_data)); break; } } break; #endif case ewGetWinState: /* Report the window's state */ if (AllowWindowOps(xw, ewGetWinState)) { TRACE(("...get window attributes\n")); init_reply(ANSI_CSI); reply.a_nparam = 1; reply.a_param[0] = (ParmType) (xtermIsIconified(xw) ? 2 : 1); reply.a_final = 't'; unparseseq(xw, &reply); } break; case ewGetWinPosition: /* Report the window's position */ if (AllowWindowOps(xw, ewGetWinPosition)) { Window win; Window result_win; int result_y, result_x; TRACE(("...get window position\n")); init_reply(ANSI_CSI); reply.a_nparam = 3; reply.a_param[0] = 3; switch (zero_if_default(1)) { case 2: /* report the text-window's position */ result_y = 0; result_x = 0; { Widget mw; for (mw = (Widget) xw; mw != NULL; mw = XtParent(mw)) { result_x += mw->core.x; result_y += mw->core.y; if (mw == SHELL_OF(xw)) break; } } result_x += OriginX(screen); result_y += OriginY(screen); break; default: win = WMFrameWindow(xw); xtermGetWinAttrs(screen->display, win, &win_attrs); XTranslateCoordinates(screen->display, VShellWindow(xw), win_attrs.root, -win_attrs.border_width, -win_attrs.border_width, &result_x, &result_y, &result_win); TRACE(("translated position %d,%d vs %d,%d\n", result_y, result_x, win_attrs.y, win_attrs.x)); if (!discount_frame_extents(xw, &result_y, &result_x)) { TRACE(("...cancelled translation\n")); result_y = win_attrs.y; result_x = win_attrs.x; } break; } reply.a_param[1] = (ParmType) result_x; reply.a_param[2] = (ParmType) result_y; reply.a_final = 't'; unparseseq(xw, &reply); } break; case ewGetWinSizePixels: /* Report the window's size in pixels */ if (AllowWindowOps(xw, ewGetWinSizePixels)) { ParmType high = (ParmType) Height(screen); ParmType wide = (ParmType) Width(screen); TRACE(("...get window size in pixels\n")); init_reply(ANSI_CSI); reply.a_nparam = 3; reply.a_param[0] = 4; switch (zero_if_default(1)) { case 2: /* report the shell-window's size */ xtermGetWinAttrs(screen->display, WMFrameWindow(xw), &win_attrs); high = (ParmType) win_attrs.height; wide = (ParmType) win_attrs.width; /* FALLTHRU */ default: reply.a_param[1] = high; reply.a_param[2] = wide; break; } reply.a_final = 't'; unparseseq(xw, &reply); } break; #if OPT_MAXIMIZE case ewGetScreenSizePixels: /* Report the screen's size, in Pixels */ if (AllowWindowOps(xw, ewGetScreenSizePixels)) { TRACE(("...get screen size in pixels\n")); (void) QueryMaximize(xw, &root_width, &root_height); init_reply(ANSI_CSI); reply.a_nparam = 3; reply.a_param[0] = 5; reply.a_param[1] = (ParmType) root_height; reply.a_param[2] = (ParmType) root_width; reply.a_final = 't'; unparseseq(xw, &reply); } break; case ewGetCharSizePixels: /* Report the font's size, in pixel */ if (AllowWindowOps(xw, ewGetScreenSizeChars)) { TRACE(("...get font size in pixels\n")); TRACE(("...using font size %dx%d\n", FontHeight(screen), FontWidth(screen))); init_reply(ANSI_CSI); reply.a_nparam = 3; reply.a_param[0] = 6; reply.a_param[1] = (ParmType) FontHeight(screen); reply.a_param[2] = (ParmType) FontWidth(screen); reply.a_final = 't'; unparseseq(xw, &reply); } break; #endif case ewGetWinSizeChars: /* Report the text's size in characters */ if (AllowWindowOps(xw, ewGetWinSizeChars)) { TRACE(("...get window size in characters\n")); init_reply(ANSI_CSI); reply.a_nparam = 3; reply.a_param[0] = 8; reply.a_param[1] = (ParmType) MaxRows(screen); reply.a_param[2] = (ParmType) MaxCols(screen); reply.a_final = 't'; unparseseq(xw, &reply); } break; #if OPT_MAXIMIZE case ewGetScreenSizeChars: /* Report the screen's size, in characters */ if (AllowWindowOps(xw, ewGetScreenSizeChars)) { TRACE(("...get screen size in characters\n")); TRACE(("...using font size %dx%d\n", FontHeight(screen), FontWidth(screen))); (void) QueryMaximize(xw, &root_width, &root_height); init_reply(ANSI_CSI); reply.a_nparam = 3; reply.a_param[0] = 9; reply.a_param[1] = (ParmType) (root_height / (unsigned) FontHeight(screen)); reply.a_param[2] = (ParmType) (root_width / (unsigned) FontWidth(screen)); reply.a_final = 't'; unparseseq(xw, &reply); } break; #endif case ewGetIconTitle: /* Report the icon's label */ if (AllowWindowOps(xw, ewGetIconTitle)) { TRACE(("...get icon's label\n")); report_win_label(xw, 'L', label = get_icon_label(xw)); free(label); } break; case ewGetWinTitle: /* Report the window's title */ if (AllowWindowOps(xw, ewGetWinTitle)) { TRACE(("...get window's label\n")); report_win_label(xw, 'l', label = get_window_label(xw)); free(label); } break; #define WhichTitle(n) \ ((n) == 0 \ ? "window/icon titles" \ : ((n) == 1 \ ? "icon title" \ : ((n) == 2 \ ? "window title" \ : "no titles"))) case ewPushTitle: /* save the window's title(s) on stack */ if (AllowWindowOps(xw, ewPushTitle)) { SaveTitle item; TRACE(("...push %s onto stack\n", WhichTitle(zero_if_default(1)))); memset(&item, 0, sizeof(item)); switch (zero_if_default(1)) { case 0: item.iconName = get_icon_label(xw); item.windowName = get_window_label(xw); break; case 1: item.iconName = get_icon_label(xw); break; case 2: item.windowName = get_window_label(xw); break; } xtermPushTitle(screen, zero_if_default(2), &item); } break; case ewPopTitle: /* restore the window's title(s) from stack */ if (AllowWindowOps(xw, ewPopTitle)) { SaveTitle item; TRACE(("...%s %s off stack\n", (zero_if_default(2) ? "get" : "pop"), WhichTitle(zero_if_default(1)))); if (xtermPopTitle(screen, zero_if_default(2), &item)) { switch (zero_if_default(1)) { case 0: ChangeIconName(xw, item.iconName); ChangeTitle(xw, item.windowName); break; case 1: ChangeIconName(xw, item.iconName); break; case 2: ChangeTitle(xw, item.windowName); break; } if (!zero_if_default(2)) xtermFreeTitle(&item); } } break; default: /* DECSLPP (24, 25, 36, 48, 72, 144) */ if (AllowWindowOps(xw, ewSetWinLines)) { if (code >= 24) RequestResize(xw, code, -1, True); } break; } } /* * set a bit in a word given a pointer to the word and a mask. */ static int bitset(unsigned *p, unsigned mask) { unsigned before = *p; *p |= mask; return (before != *p); } /* * clear a bit in a word given a pointer to the word and a mask. */ static int bitclr(unsigned *p, unsigned mask) { unsigned before = *p; *p &= ~mask; return (before != *p); } /* * Copy bits from one word to another, given a mask */ static int bitcpy(unsigned *p, unsigned q, unsigned mask) { unsigned before = *p; bitclr(p, mask); bitset(p, q & mask); return (before != *p); } void unparseputc1(XtermWidget xw, int c) { if (c >= 0x80 && c <= 0x9F) { if (!TScreenOf(xw)->control_eight_bits) { unparseputc(xw, ANSI_ESC); c = c - 0x40; } } unparseputc(xw, c); } void unparseseq(XtermWidget xw, ANSI *ap) { int c; assert(ap->a_nparam < NPARAM); unparseputc1(xw, c = ap->a_type); if (c == ANSI_ESC || c == ANSI_DCS || c == ANSI_CSI || c == ANSI_OSC || c == ANSI_PM || c == ANSI_APC || c == ANSI_SS3) { int i; int inters; char temp[8]; if (ap->a_pintro != 0) unparseputc(xw, ap->a_pintro); for (i = 0; i < ap->a_nparam; ++i) { if (i != 0) { if (ap->a_radix[i] == 1 || ap->a_radix[i - 1] == 1) { ; } else if (ap->a_delim) { unparseputs(xw, ap->a_delim); } else { unparseputc(xw, ';'); } } switch (ap->a_radix[i]) { case 16: sprintf(temp, "%04X", UParmOf(ap->a_param[i])); unparseputs(xw, temp); break; case 1: unparseputc(xw, ap->a_param[i]); break; default: unparseputn(xw, UParmOf(ap->a_param[i])); break; } } if ((inters = ap->a_inters) != 0) { for (i = 3; i >= 0; --i) { c = CharOf(inters >> (8 * i)); if (c != 0) unparseputc(xw, c); } } switch (ap->a_type) { case ANSI_DCS: /* FALLTHRU */ case ANSI_OSC: /* FALLTHRU */ case ANSI_PM: /* FALLTHRU */ case ANSI_APC: unparseputc1(xw, ANSI_ST); break; default: unparseputc(xw, (char) ap->a_final); break; } } unparse_end(xw); } void unparseputn(XtermWidget xw, unsigned n) { unsigned q; q = n / 10; if (q != 0) unparseputn(xw, q); unparseputc(xw, (char) ('0' + (n % 10))); } void unparseputs(XtermWidget xw, const char *s) { if (s != NULL) { while (*s) unparseputc(xw, *s++); } } void unparseputc(XtermWidget xw, int c) { TScreen *screen = TScreenOf(xw); IChar *buf = screen->unparse_bfr; unsigned len; if ((screen->unparse_len + 2) >= screen->unparse_max) unparse_end(xw); len = screen->unparse_len; #if OPT_TCAP_QUERY /* * If we're returning a termcap string, it has to be translated since * a DCS must not contain any characters except for the normal 7-bit * printable ASCII (counting tab, carriage return, etc). For now, * just use hexadecimal for the whole thing. */ if (screen->tc_query_code >= 0) { char tmp[3]; sprintf(tmp, "%02X", (unsigned) (c & 0xFF)); buf[len++] = CharOf(tmp[0]); buf[len++] = CharOf(tmp[1]); } else #endif if ((buf[len++] = (IChar) c) == '\r' && (xw->flags & LINEFEED)) { buf[len++] = '\n'; } screen->unparse_len = len; /* If send/receive mode is reset, we echo characters locally */ if ((xw->keyboard.flags & MODE_SRM) == 0) { doparsing(xw, (unsigned) c, &myState); } } void unparse_end(XtermWidget xw) { TScreen *screen = TScreenOf(xw); #if OPT_TCAP_QUERY /* * tcap-query works by simulating key-presses, which ordinarily would be * flushed out at the end of each key. For better efficiency, do not do * the flush unless we are about to fill the buffer used to capture the * response. */ if ((screen->tc_query_code >= 0) && (screen->unparse_len + 2 < screen->unparse_max)) { return; } #endif if (screen->unparse_len) { TRACE(("unparse_end %u:%s\n", screen->unparse_len, visibleIChars(screen->unparse_bfr, (size_t) screen->unparse_len))); writePtyData(screen->respond, screen->unparse_bfr, (size_t) screen->unparse_len); screen->unparse_len = 0; } } void ToggleAlternate(XtermWidget xw) { if (TScreenOf(xw)->whichBuf) FromAlternate(xw, False); else ToAlternate(xw, False); } static void ToAlternate(XtermWidget xw, Bool clearFirst) { TScreen *screen = TScreenOf(xw); if (screen->whichBuf == 0) { TRACE(("ToAlternate\n")); if (!screen->editBuf_index[1]) { screen->editBuf_index[1] = allocScrnBuf(xw, (unsigned) MaxRows(screen), (unsigned) MaxCols(screen), &screen->editBuf_data[1]); } SwitchBufs(xw, 1, clearFirst); screen->visbuf = screen->editBuf_index[screen->whichBuf]; update_altscreen(); } } static void FromAlternate(XtermWidget xw, Bool clearFirst) { TScreen *screen = TScreenOf(xw); if (screen->whichBuf != 0) { TRACE(("FromAlternate\n")); if (screen->scroll_amt) { FlushScroll(xw); } if (clearFirst) ClearScreen(xw); SwitchBufs(xw, 0, False); screen->visbuf = screen->editBuf_index[screen->whichBuf]; update_altscreen(); } } static void SwitchBufs(XtermWidget xw, int toBuf, Bool clearFirst) { TScreen *screen = TScreenOf(xw); int rows, top; screen->whichBuf = toBuf; if (screen->cursor_state) HideCursor(xw); rows = MaxRows(screen); #if OPT_STATUS_LINE if (IsStatusShown(screen) && (rows > 0)) { /* avoid clearing the status-line in this function */ --rows; } #endif SwitchBufPtrs(xw, toBuf); if ((top = INX2ROW(screen, 0)) < rows) { if (screen->scroll_amt) { FlushScroll(xw); } xtermClear2(xw, (int) OriginX(screen), (int) top * FontHeight(screen) + screen->border, (unsigned) Width(screen), (unsigned) ((rows - top) * FontHeight(screen))); if (clearFirst) { ClearBufRows(xw, top, rows); } } ScrnUpdate(xw, 0, 0, rows, MaxCols(screen), False); } Bool CheckBufPtrs(TScreen *screen) { return (screen->visbuf != NULL && screen->editBuf_index[0] != NULL && screen->editBuf_index[1] != NULL); } /* * Swap buffer line pointers between alternate and regular screens. */ void SwitchBufPtrs(XtermWidget xw, int toBuf) { TScreen *screen = TScreenOf(xw); if (CheckBufPtrs(screen)) { #if OPT_STATUS_LINE if (IsStatusShown(screen) && (screen->visbuf != screen->editBuf_index[toBuf])) { LineData *oldLD; LineData *newLD; int row = MaxRows(screen); oldLD = getLineData(screen, row); screen->visbuf = screen->editBuf_index[toBuf]; newLD = getLineData(screen, row); copyLineData(newLD, oldLD); } else #endif screen->visbuf = screen->editBuf_index[toBuf]; } } void VTRun(XtermWidget xw) { TScreen *screen = TScreenOf(xw); TRACE(("VTRun ...\n")); if (!screen->Vshow && !resource.notMapped) { set_vt_visibility(True); } update_vttekmode(); update_vtshow(); update_tekshow(); set_vthide_sensitivity(); ScrnAllocBuf(xw); screen->cursor_state = OFF; screen->cursor_set = ON; #if OPT_BLINK_CURS if (DoStartBlinking(screen)) StartBlinking(xw); #endif #if OPT_TEK4014 if (Tpushb > Tpushback) { fillPtyData(xw, VTbuffer, (char *) Tpushback, (size_t) (Tpushb - Tpushback)); Tpushb = Tpushback; } #endif screen->is_running = True; if (screen->embed_high && screen->embed_wide) { ScreenResize(xw, screen->embed_wide, screen->embed_high, &(xw->flags)); } #if OPT_MAXIMIZE else if (resource.fullscreen == esTrue || resource.fullscreen == esAlways) FullScreen(xw, True); #endif if (!setjmp(VTend)) VTparse(xw); StopBlinking(xw); HideCursor(xw); screen->cursor_set = OFF; TRACE(("... VTRun\n")); } /*ARGSUSED*/ static void VTExpose(Widget w GCC_UNUSED, XEvent *event, Region region GCC_UNUSED) { DEBUG_MSG("Expose\n"); if (event->type == Expose) HandleExposure(term, event); } static void VTGraphicsOrNoExpose(XEvent *event) { XtermWidget xw = term; TScreen *screen = TScreenOf(xw); if (screen->incopy <= 0) { screen->incopy = 1; if (screen->scrolls > 0) screen->scrolls--; } if (event->type == GraphicsExpose) if (HandleExposure(xw, event)) screen->cursor_state = OFF; if ((event->type == NoExpose) || ((XGraphicsExposeEvent *) event)->count == 0) { if (screen->incopy <= 0 && screen->scrolls > 0) screen->scrolls--; if (screen->scrolls) screen->incopy = -1; else screen->incopy = 0; } } /*ARGSUSED*/ static void VTNonMaskableEvent(Widget w GCC_UNUSED, XtPointer closure GCC_UNUSED, XEvent *event, Boolean *cont GCC_UNUSED) { switch (event->type) { case GraphicsExpose: /* FALLTHRU */ case NoExpose: VTGraphicsOrNoExpose(event); break; } } static void VTResize(Widget w) { if (XtIsRealized(w)) { XtermWidget xw = (XtermWidget) w; ScreenResize(xw, xw->core.width, xw->core.height, &xw->flags); } } #define okDimension(src,dst) ((src <= MAX_U_COORD) \ && ((dst = (Dimension) src) == src)) static void RequestResize(XtermWidget xw, int rows, int cols, Bool text) { TScreen *screen = TScreenOf(xw); Dimension replyWidth, replyHeight; Dimension askedWidth, askedHeight; XtGeometryResult status; XWindowAttributes attrs; #if OPT_RENDERFONT && USE_DOUBLE_BUFFER Boolean buggyXft = False; Cardinal ignore = 0; #endif TRACE(("RequestResize(rows=%d, cols=%d, text=%d)\n", rows, cols, text)); #if OPT_STATUS_LINE if (IsStatusShown(screen)) { if (rows == -1) { /* prevent shrinking on DECCOLM, XTRESTORE, DECSCPP, DECANM */ rows = MaxRows(screen); } if (rows > 0) { TRACE(("...reserve a row for status-line\n")); ++rows; } } #endif /* check first if the row/column values fit into a Dimension */ if (cols > 0) { if ((int) (askedWidth = (Dimension) cols) < cols) { TRACE(("... cols too large for Dimension\n")); return; } } else { askedWidth = 0; } if (rows > 0) { if ((int) (askedHeight = (Dimension) rows) < rows) { TRACE(("... rows too large for Dimension\n")); return; } } else { askedHeight = 0; } xw->work.doing_resize = True; #if OPT_RENDERFONT && USE_DOUBLE_BUFFER /* * Work around a bug seen when vttest switches from 132 columns back to 80 * columns, while double-buffering is active. If Xft is active during the * resize, the screen will be blank thereafter. This workaround causes * some extra flickering, but that is preferable to a blank screen. * * Since the bitmap- and TrueType-fonts do not always have identical sizes, * do this switching early, to use the updated font-sizes in the request * for resizing the window. */ #define ToggleXft() HandleRenderFont((Widget)xw, (XEvent *)0, (String *)0, &ignore) if (resource.buffered && UsingRenderFont(xw)) { ToggleXft(); buggyXft = True; } #endif /* * If the requested values will fit into a Dimension, and one or both are * zero, get the current corresponding screen dimension to use as a limit. */ if (askedHeight == 0 || askedWidth == 0 || xw->misc.limit_resize > 0) { xtermGetWinAttrs(XtDisplay(xw), RootWindowOfScreen(XtScreen(xw)), &attrs); } /* * Using the current font metrics, translate the requested character * rows/columns into pixels. */ if (text) { unsigned long value; if ((value = (unsigned long) rows) != 0) { if (rows < 0) value = (unsigned long) MaxRows(screen); value *= (unsigned long) FontHeight(screen); value += (unsigned long) (2 * screen->border); if (!okDimension(value, askedHeight)) goto give_up; } if ((value = (unsigned long) cols) != 0) { if (cols < 0) value = (unsigned long) MaxCols(screen); value *= (unsigned long) FontWidth(screen); value += (unsigned long) ((2 * screen->border) + ScrollbarWidth(screen)); if (!okDimension(value, askedWidth)) goto give_up; } } else { if (rows < 0) askedHeight = FullHeight(screen); if (cols < 0) askedWidth = FullWidth(screen); } if (rows == 0) { askedHeight = (Dimension) attrs.height; } if (cols == 0) { askedWidth = (Dimension) attrs.width; } if (xw->misc.limit_resize > 0) { Dimension high = (Dimension) (xw->misc.limit_resize * attrs.height); Dimension wide = (Dimension) (xw->misc.limit_resize * attrs.width); if ((int) high < attrs.height) high = (Dimension) attrs.height; if (askedHeight > high) askedHeight = high; if ((int) wide < attrs.width) wide = (Dimension) attrs.width; if (askedWidth > wide) askedWidth = wide; } #ifndef nothack getXtermSizeHints(xw); #endif TRACE(("...requesting resize %dx%d (%dx%d)\n", askedHeight, askedWidth, askedHeight / FontHeight(screen), askedWidth / FontWidth(screen))); status = REQ_RESIZE((Widget) xw, askedWidth, askedHeight, &replyWidth, &replyHeight); if (status == XtGeometryYes || status == XtGeometryDone) { ScreenResize(xw, replyWidth, replyHeight, &xw->flags); } #ifndef nothack /* * XtMakeResizeRequest() has the undesirable side-effect of clearing * the window manager's hints, even on a failed request. This would * presumably be fixed if the shell did its own work. */ if (xw->hints.flags && replyHeight && replyWidth) { xw->hints.height = replyHeight; xw->hints.width = replyWidth; TRACE(("%s@%d -- ", __FILE__, __LINE__)); TRACE_HINTS(&xw->hints); XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints); TRACE(("%s@%d -- ", __FILE__, __LINE__)); TRACE_WM_HINTS(xw); } #endif XSync(screen->display, False); /* synchronize */ if (xtermAppPending()) { xevents(xw); } give_up: #if OPT_RENDERFONT && USE_DOUBLE_BUFFER if (buggyXft) { ToggleXft(); if (xtermAppPending()) { xevents(xw); } } #endif xw->work.doing_resize = False; TRACE(("...RequestResize done\n")); return; } static String xterm_trans = "WM_PROTOCOLS: DeleteWindow()\n\ XTERM_CONTROL: ColorEvents()\n\ : KeyboardMapping()\n"; int VTInit(XtermWidget xw) { Widget vtparent = SHELL_OF(xw); TRACE(("VTInit " TRACE_L "\n")); XtRealizeWidget(vtparent); XtOverrideTranslations(vtparent, XtParseTranslationTable(xterm_trans)); (void) XSetWMProtocols(XtDisplay(vtparent), XtWindow(vtparent), &wm_delete_window, 1); if (IsEmpty(xw->keyboard.print_translations)) { TRACE_TRANS("shell", vtparent); TRACE_TRANS("vt100", (Widget) (xw)); xtermButtonInit(xw); } ScrnAllocBuf(xw); TRACE(("..." TRACE_R " VTInit\n")); return (1); } static void VTClassInit(void) { XtAddConverter(XtRString, XtRGravity, XmuCvtStringToGravity, (XtConvertArgList) NULL, (Cardinal) 0); } /* * Override the use of XtDefaultForeground/XtDefaultBackground to make some * colors, such as cursor color, use the actual foreground/background value * if there is no explicit resource value used. */ static Pixel fill_Tres(XtermWidget target, XtermWidget source, int offset) { char *name; ScrnColors temp; TScreen *src = TScreenOf(source); TScreen *dst = TScreenOf(target); dst->Tcolors[offset] = src->Tcolors[offset]; dst->Tcolors[offset].mode = False; if ((name = x_strtrim(dst->Tcolors[offset].resource)) != NULL) dst->Tcolors[offset].resource = name; if (name == NULL) { dst->Tcolors[offset].value = target->dft_foreground; } else if (isDefaultForeground(name)) { dst->Tcolors[offset].value = ((offset == TEXT_FG || offset == TEXT_BG) ? target->dft_foreground : dst->Tcolors[TEXT_FG].value); } else if (isDefaultBackground(name)) { dst->Tcolors[offset].value = ((offset == TEXT_FG || offset == TEXT_BG) ? target->dft_background : dst->Tcolors[TEXT_BG].value); } else { memset(&temp, 0, sizeof(temp)); if (AllocateTermColor(target, &temp, offset, name, True)) { if (COLOR_DEFINED(&(temp), offset)) free(temp.names[offset]); dst->Tcolors[offset].value = temp.colors[offset]; } else if (offset == TEXT_FG || offset == TEXT_BG) { free(name); dst->Tcolors[offset].resource = NULL; } } return dst->Tcolors[offset].value; } /* * If one or both of the foreground/background colors cannot be allocated, * e.g., due to gross misconfiguration, recover by setting both to the * display's default values. */ static void repairColors(XtermWidget target) { TScreen *screen = TScreenOf(target); if (screen->Tcolors[TEXT_FG].resource == NULL || screen->Tcolors[TEXT_BG].resource == NULL) { xtermWarning("unable to allocate fg/bg colors\n"); screen->Tcolors[TEXT_FG].resource = x_strdup(XtDefaultForeground); screen->Tcolors[TEXT_BG].resource = x_strdup(XtDefaultBackground); if (screen->Tcolors[TEXT_FG].resource == NULL || screen->Tcolors[TEXT_BG].resource == NULL) { Exit(ERROR_MISC); } screen->Tcolors[TEXT_FG].value = target->dft_foreground; screen->Tcolors[TEXT_BG].value = target->dft_background; } } #if OPT_WIDE_CHARS static void set_utf8_feature(TScreen *screen, int *feature) { if (*feature == uDefault) { switch (screen->utf8_mode) { case uFalse: /* FALLTHRU */ case uTrue: *feature = screen->utf8_mode; break; case uDefault: /* should not happen */ *feature = uTrue; break; case uAlways: /* use this to disable menu entry */ break; } } } static void VTInitialize_locale(XtermWidget xw) { TScreen *screen = TScreenOf(xw); Bool is_utf8 = xtermEnvUTF8(); TRACE(("VTInitialize_locale\n")); TRACE(("... request screen.utf8_mode = %d\n", screen->utf8_mode)); TRACE(("... request screen.utf8_fonts = %d\n", screen->utf8_fonts)); TRACE(("... request screen.utf8_title = %d\n", screen->utf8_title)); screen->utf8_always = (screen->utf8_mode == uAlways); if (screen->utf8_mode < 0) screen->utf8_mode = uFalse; if (screen->utf8_mode > 3) screen->utf8_mode = uDefault; screen->latin9_mode = 0; screen->unicode_font = 0; #if OPT_LUIT_PROG xw->misc.callfilter = 0; xw->misc.use_encoding = 0; TRACE(("... setup for luit:\n")); TRACE(("... request misc.locale_str = \"%s\"\n", xw->misc.locale_str)); if (screen->utf8_mode == uFalse) { TRACE(("... command-line +u8 overrides\n")); } else #if OPT_MINI_LUIT if (x_strcasecmp(xw->misc.locale_str, "CHECKFONT") == 0) { int fl = (int) strlen(DefaultFontN(xw)); if (fl > 11 && x_strcasecmp(DefaultFontN(xw) + fl - 11, "-ISO10646-1") == 0) { screen->unicode_font = 1; /* unicode font, use True */ #ifdef HAVE_LANGINFO_CODESET if (!strcmp(xtermEnvEncoding(), "ANSI_X3.4-1968") || !strcmp(xtermEnvEncoding(), "ISO-8859-1")) { if (screen->utf8_mode == uDefault) screen->utf8_mode = uFalse; } else if (!strcmp(xtermEnvEncoding(), "ISO-8859-15")) { if (screen->utf8_mode == uDefault) screen->utf8_mode = uFalse; screen->latin9_mode = 1; } else { xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1); screen->utf8_mode = uAlways; } #else xw->misc.callfilter = is_utf8 ? 0 : 1; screen->utf8_mode = uAlways; #endif } else { /* other encoding, use False */ if (screen->utf8_mode == uDefault) { screen->utf8_mode = is_utf8 ? uAlways : uFalse; } } } else #endif /* OPT_MINI_LUIT */ if (x_strcasecmp(xw->misc.locale_str, "TRUE") == 0 || x_strcasecmp(xw->misc.locale_str, "ON") == 0 || x_strcasecmp(xw->misc.locale_str, "YES") == 0 || x_strcasecmp(xw->misc.locale_str, "AUTO") == 0 || strcmp(xw->misc.locale_str, "1") == 0) { /* when true ... fully obeying LC_CTYPE locale */ xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1); screen->utf8_mode = uAlways; } else if (x_strcasecmp(xw->misc.locale_str, "FALSE") == 0 || x_strcasecmp(xw->misc.locale_str, "OFF") == 0 || x_strcasecmp(xw->misc.locale_str, "NO") == 0 || strcmp(xw->misc.locale_str, "0") == 0) { /* when false ... original value of utf8_mode is effective */ if (screen->utf8_mode == uDefault) { screen->utf8_mode = is_utf8 ? uAlways : uFalse; } } else if (x_strcasecmp(xw->misc.locale_str, "MEDIUM") == 0 || x_strcasecmp(xw->misc.locale_str, "SEMIAUTO") == 0) { /* when medium ... obeying locale only for UTF-8 and Asian */ if (is_utf8) { screen->utf8_mode = uAlways; } else if ( #ifdef MB_CUR_MAX MB_CUR_MAX > 1 || #else !strncmp(xtermEnvLocale(), "ja", (size_t) 2) || !strncmp(xtermEnvLocale(), "ko", (size_t) 2) || !strncmp(xtermEnvLocale(), "zh", (size_t) 2) || #endif !strncmp(xtermEnvLocale(), "th", (size_t) 2) || !strncmp(xtermEnvLocale(), "vi", (size_t) 2)) { xw->misc.callfilter = 1; screen->utf8_mode = uAlways; } else { screen->utf8_mode = uFalse; } } else if (x_strcasecmp(xw->misc.locale_str, "UTF-8") == 0 || x_strcasecmp(xw->misc.locale_str, "UTF8") == 0) { /* when UTF-8 ... UTF-8 mode */ screen->utf8_mode = uAlways; } else { /* other words are regarded as encoding name passed to luit */ xw->misc.callfilter = 1; screen->utf8_mode = uAlways; xw->misc.use_encoding = 1; } TRACE(("... updated misc.callfilter = %s\n", BtoS(xw->misc.callfilter))); TRACE(("... updated misc.use_encoding = %s\n", BtoS(xw->misc.use_encoding))); #else if (screen->utf8_mode == uDefault) { screen->utf8_mode = is_utf8 ? uAlways : uFalse; } #endif /* OPT_LUIT_PROG */ set_utf8_feature(screen, &screen->utf8_fonts); set_utf8_feature(screen, &screen->utf8_title); screen->utf8_inparse = (Boolean) (screen->utf8_mode != uFalse); TRACE(("... updated screen.utf8_mode = %d\n", screen->utf8_mode)); TRACE(("... updated screen.utf8_fonts = %d\n", screen->utf8_fonts)); TRACE(("... updated screen.utf8_title = %d\n", screen->utf8_title)); TRACE(("...VTInitialize_locale done\n")); } #endif void lookupSelectUnit(XtermWidget xw, Cardinal item, String value) { /* *INDENT-OFF* */ static const struct { const char * name; SelectUnit code; } table[] = { { "char", Select_CHAR }, { "word", Select_WORD }, { "line", Select_LINE }, { "group", Select_GROUP }, { "page", Select_PAGE }, { "all", Select_ALL }, #if OPT_SELECT_REGEX { "regex", Select_REGEX }, #endif }; /* *INDENT-ON* */ TScreen *screen = TScreenOf(xw); String next = x_skip_nonblanks(value); Cardinal n; screen->selectMap[item] = NSELECTUNITS; for (n = 0; n < XtNumber(table); ++n) { if (!x_strncasecmp(table[n].name, value, (unsigned) (next - value))) { screen->selectMap[item] = table[n].code; #if OPT_SELECT_REGEX if (table[n].code == Select_REGEX) { screen->selectExpr[item] = x_strtrim(next); TRACE(("Parsed regex \"%s\"\n", screen->selectExpr[item])); } #endif break; } } } static void ParseOnClicks(XtermWidget wnew, XtermWidget wreq, Cardinal item) { lookupSelectUnit(wnew, item, TScreenOf(wreq)->onClick[item]); } /* * Parse a comma-separated list, returning a string which the caller must * free, and updating the source pointer. */ static char * ParseList(const char **source) { const char *base = *source; const char *next; char *value = NULL; char *result; /* ignore empty values */ while (*base == ',') ++base; if (*base != '\0') { size_t size; next = base; while (*next != '\0' && *next != ',') ++next; size = (size_t) (1 + next - base); value = malloc(size); if (value != NULL) { memcpy(value, base, size); value[size - 1] = '\0'; } *source = next; } else { *source = base; } result = x_strtrim(value); free(value); return result; } static void set_flags_from_list(char *target, const char *source, const FlagList * list) { Cardinal n; while (!IsEmpty(source)) { char *next = ParseList(&source); Boolean found = False; char flag = 1; if (next == NULL) break; if (*next == '~') { flag = 0; next++; } if (isdigit(CharOf(*next))) { char *temp; int value = (int) strtol(next, &temp, 0); if (!FullS2L(next, temp)) { xtermWarning("Expected a number: %s\n", next); } else { for (n = 0; list[n].name != NULL; ++n) { if (list[n].code == value) { target[value] = flag; found = True; TRACE(("...found %s (%d)\n", list[n].name, value)); break; } } } } else { for (n = 0; list[n].name != NULL; ++n) { if (!x_wildstrcmp(next, list[n].name)) { int value = list[n].code; target[value] = flag; found = True; TRACE(("...found %s (%d)\n", list[n].name, value)); } } } if (!found) { xtermWarning("Unrecognized keyword: %s\n", next); } free(next); } } #define InitCursorShape(target, source) \ target->cursor_shape = source->cursor_underline ? CURSOR_UNDERLINE : \ source->cursor_bar ? CURSOR_BAR : CURSOR_BLOCK #if OPT_XRES_QUERY static XtResource * findVT100Resource(const char *name) { Cardinal n; XtResource *result = NULL; if (!IsEmpty(name)) { XrmQuark quarkName = XrmPermStringToQuark(name); for (n = 0; n < XtNumber(xterm_resources); ++n) { if ((int) xterm_resources[n].resource_offset >= 0 && !strcmp(xterm_resources[n].resource_name, name)) { result = &xterm_resources[n]; break; } else if (xterm_resources[n].resource_name == (String) (intptr_t) quarkName) { result = &xterm_resources[n]; break; } } } return result; } static int cmp_resources(const void *a, const void *b) { return strcmp((*(const String *) a), (*(const String *) b)); } static void reportResources(XtermWidget xw) { String *list = TypeMallocN(String, XtNumber(xterm_resources)); Cardinal n; int widest = 0; if (list == NULL) return; for (n = 0; n < XtNumber(xterm_resources); ++n) { int width; list[n] = (((int) xterm_resources[n].resource_offset < 0) ? XrmQuarkToString((XrmQuark) (intptr_t) xterm_resources[n].resource_name) : xterm_resources[n].resource_name); width = (int) strlen(list[n]); if (widest < width) widest = width; } qsort(list, (size_t) XtNumber(xterm_resources), sizeof(String), cmp_resources); for (n = 0; n < XtNumber(xterm_resources); ++n) { char *value = vt100ResourceToString(xw, list[n]); printf("%-*s : %s\n", widest, list[n], value ? value : "(skip)"); free(value); } free(list); } char * vt100ResourceToString(XtermWidget xw, const char *name) { XtResource *data; char *result = NULL; if ((data = findVT100Resource(name)) != NULL) { int fake_offset = (int) data->resource_offset; void *res_addr; int real_offset; String res_type; /* * X Toolkit "compiles" the resource-list into quarks and changes the * resource-offset at the same time to a negative value. */ if (fake_offset < 0) { real_offset = -(fake_offset + 1); res_type = XrmQuarkToString((XrmQuark) (intptr_t) data->resource_type); } else { real_offset = fake_offset; res_type = data->resource_type; } res_addr = (void *) ((char *) xw + real_offset); if (!strcmp(res_type, XtRString)) { char *value = *(char **) res_addr; if (value != NULL) { size_t need = strlen(value); if ((result = malloc(1 + need)) != NULL) strcpy(result, value); } } else if (!strcmp(res_type, XtRInt)) { if ((result = malloc(1 + (size_t) (3 * data->resource_size))) != NULL) sprintf(result, "%d", *(int *) res_addr); } else if (!strcmp(res_type, XtRFloat)) { if ((result = malloc(1 + (size_t) (3 * data->resource_size))) != NULL) sprintf(result, "%f", (double) (*(float *) res_addr)); } else if (!strcmp(res_type, XtRBoolean)) { if ((result = malloc((size_t) 6)) != NULL) strcpy(result, *(Boolean *) res_addr ? "true" : "false"); } } TRACE(("vt100ResourceToString(%s) %s\n", name, NonNull(result))); return result; } #endif /* OPT_XRES_QUERY */ /* * Decode a terminal-ID or graphics-terminal-ID, using the default terminal-ID * if the value is outside a (looser) range than limitedTerminalID. This uses * a wider range, to avoid being a nuisance when using X resources with * different configurations of xterm. */ static int decodeTerminalID(const char *value) { const char *s; char *t; long result; for (s = value; *s; s++) { if (!isalpha(CharOf(*s))) break; } result = strtol(s, &t, 10); if (t == s || *t != '\0' || result <= 0L || result > 1000L) { xtermWarning("unexpected value for terminalID: \"%s\"\n", value); result = atoi(DFT_DECID); } TRACE(("decodeTerminalID \"%s\" ->%d\n", value, (int) result)); return (int) result; } /* * Ensures that the value returned by decodeTerminalID is either in the range * of IDs matching a known terminal, or (failing that), set to the built-in * default. The DA response relies on having the ID being set to a known * value. */ static int limitedTerminalID(int terminal_id) { if (terminal_id < MIN_DECID) terminal_id = MIN_DECID; else if (terminal_id > MAX_DECID) terminal_id = MAX_DECID; else terminal_id = atoi(DFT_DECID); return terminal_id; } #define DATA_END { NULL, -1 } #define DATA(name) { #name, ec##name } static const FlagList tblColorOps[] = { DATA(SetColor) ,DATA(GetColor) ,DATA(GetAnsiColor) ,DATA_END }; #undef DATA #define DATA(name) { #name, ef##name } static const FlagList tblFontOps[] = { DATA(SetFont) ,DATA(GetFont) ,DATA_END }; #undef DATA #define DATA(name) { #name, em##name } static const FlagList tblMouseOps[] = { DATA(X10) ,DATA(Locator) ,DATA(VT200Click) ,DATA(VT200Hilite) ,DATA(AnyButton) ,DATA(AnyEvent) ,DATA(FocusEvent) ,DATA(Extended) ,DATA(SGR) ,DATA(URXVT) ,DATA(AlternateScroll) ,DATA_END }; #undef DATA #define DATA(name) { #name, ep##name } #define DATA2(alias,name) { #alias, ep##name } static const FlagList tblPasteOps[] = { DATA(NUL) ,DATA(SOH) ,DATA(STX) ,DATA(ETX) ,DATA(EOT) ,DATA(ENQ) ,DATA(ACK) ,DATA(BEL) ,DATA(BS) ,DATA(HT) ,DATA(LF) ,DATA(VT) ,DATA(FF) ,DATA(CR) ,DATA(SO) ,DATA(SI) ,DATA(DLE) ,DATA(DC1) ,DATA(DC2) ,DATA(DC3) ,DATA(DC4) ,DATA(NAK) ,DATA(SYN) ,DATA(ETB) ,DATA(CAN) ,DATA(EM) ,DATA(SUB) ,DATA(ESC) ,DATA(FS) ,DATA(GS) ,DATA(RS) ,DATA(US) /* aliases */ ,DATA2(NL, LF) ,DATA(C0) ,DATA(DEL) ,DATA(STTY) ,DATA_END }; #undef DATA #undef DATA2 #define DATA(name) { #name, et##name } static const FlagList tblTcapOps[] = { DATA(SetTcap) ,DATA(GetTcap) ,DATA_END }; #undef DATA #define DATA(name) { #name, ew##name } static const FlagList tblWindowOps[] = { DATA(RestoreWin) ,DATA(MinimizeWin) ,DATA(SetWinPosition) ,DATA(SetWinSizePixels) ,DATA(RaiseWin) ,DATA(LowerWin) ,DATA(RefreshWin) ,DATA(SetWinSizeChars) #if OPT_MAXIMIZE ,DATA(MaximizeWin) ,DATA(FullscreenWin) #endif ,DATA(GetWinState) ,DATA(GetWinPosition) ,DATA(GetWinSizePixels) ,DATA(GetWinSizeChars) #if OPT_MAXIMIZE ,DATA(GetScreenSizeChars) #endif ,DATA(GetIconTitle) ,DATA(GetWinTitle) ,DATA(PushTitle) ,DATA(PopTitle) /* this item uses all remaining numbers in the sequence */ ,DATA(SetWinLines) /* starting at this point, numbers do not apply */ ,DATA(SetXprop) ,DATA(GetSelection) ,DATA(SetSelection) ,DATA(GetChecksum) ,DATA(SetChecksum) ,DATA(StatusLine) ,DATA(ColumnMode) ,DATA_END }; #undef DATA #define DATA(name) { #name, OSC_##name } static const FlagList tblColorEvents[] = { DATA(TEXT_FG) ,DATA(TEXT_BG) ,DATA(TEXT_CURSOR) ,DATA(MOUSE_FG) ,DATA(MOUSE_BG) #if OPT_TEK4014 ,DATA(TEK_FG) ,DATA(TEK_BG) #endif #if OPT_HIGHLIGHT_COLOR ,DATA(HIGHLIGHT_BG) #endif #if OPT_TEK4014 ,DATA(TEK_CURSOR) #endif #if OPT_HIGHLIGHT_COLOR ,DATA(HIGHLIGHT_FG) #endif }; #undef DATA void unparse_disallowed_ops(XtermWidget xw, char *value) { TScreen *screen = TScreenOf(xw); #define DATA(mixed, plain, flags) { #mixed, offsetof(TScreen, plain), sizeof(screen->plain), flags } /* *INDENT-OFF* */ static const struct { const char * name; size_t offset; size_t length; const FlagList *codes; } table[] = { DATA(allowColorOps, disallow_color_ops, tblColorOps), DATA(allowFontOps, disallow_font_ops, tblFontOps), DATA(allowMouseOps, disallow_mouse_ops, tblMouseOps), DATA(allowPasteControls, disallow_paste_ops, tblPasteOps), DATA(allowTcapOps, disallow_tcap_ops, tblTcapOps), DATA(allowWinOps, disallow_win_ops, tblWindowOps), }; /* *INDENT-ON* */ #undef DATA Cardinal j, k, jk; char delim = ';'; for (j = 0; j < XtNumber(table); ++j) { if (!x_strcasecmp(value, table[j].name)) { const char *flags = (char *) screen + table[j].offset; for (k = 0; k < table[j].length; ++k) { if (flags[k]) { const FlagList *codes = table[j].codes; Boolean found = False; unparseputc(xw, delim); for (jk = 0; codes[jk].name; ++jk) { if (codes[jk].code == (int) k) { unparseputs(xw, codes[jk].name); found = True; break; } } if (!found) unparseputn(xw, k); delim = ','; } } break; } } } /* ARGSUSED */ static void VTInitialize(Widget wrequest, Widget new_arg, ArgList args GCC_UNUSED, Cardinal *num_args GCC_UNUSED) { #define Kolor(name) TScreenOf(wnew)->name.resource #define TxtFg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_FG]), Kolor(name)) #define TxtBg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_BG]), Kolor(name)) #define DftFg(name) isDefaultForeground(Kolor(name)) #define DftBg(name) isDefaultBackground(Kolor(name)) #if OPT_BLINK_CURS #define DATA(name) { #name, cb##name } static const FlagList tblBlinkOps[] = { DATA(Always) ,DATA(Never) ,DATA_END }; #undef DATA #endif #if OPT_RENDERFONT #define DATA(name) { #name, er##name } static const FlagList tblRenderFont[] = { DATA(Default) ,DATA(DefaultOff) ,DATA_END }; #undef DATA #endif #define DATA(name) { #name, ss##name } static const FlagList tblShift2S[] = { DATA(Always) ,DATA(Never) ,DATA_END }; #undef DATA #if OPT_WIDE_CHARS #define DATA(name) { #name, u##name } static const FlagList tblUtf8Mode[] = { DATA(Always) ,DATA(Default) ,DATA_END }; #undef DATA #endif #ifndef NO_ACTIVE_ICON #define DATA(name) { #name, ei##name } static const FlagList tblAIconOps[] = { DATA(Default) ,DATA_END }; #undef DATA #endif #define DATA(name) { #name, eb##name } static const FlagList tbl8BitMeta[] = { DATA(Never) ,DATA(Locale) ,DATA_END }; #undef DATA #define DATA(name) { #name, ed##name } static const FlagList tblCdXtraScroll[] = { DATA(Trim) ,DATA_END }; #undef DATA XtermWidget request = (XtermWidget) wrequest; XtermWidget wnew = (XtermWidget) new_arg; Widget my_parent = SHELL_OF(wnew); int i; #if OPT_ISO_COLORS Bool color_ok; #endif #if OPT_ISO_COLORS static XtResource fake_resources[] = { #if OPT_256_COLORS # include <256colres.h> #elif OPT_88_COLORS # include <88colres.h> #endif }; #endif TScreen *screen = TScreenOf(wnew); char *saveLocale = xtermSetLocale(LC_NUMERIC, "C"); #if OPT_BLINK_CURS int ebValue; #endif #if OPT_TRACE check_bitmasks(); check_tables(); #endif TRACE(("VTInitialize wnew %p, %d / %d resources " TRACE_L "\n", (void *) wnew, XtNumber(xterm_resources), MAXRESOURCES)); assert(XtNumber(xterm_resources) < MAXRESOURCES); /* Zero out the entire "screen" component of "wnew" widget, then do * field-by-field assignment of "screen" fields that are named in the * resource list. */ memset(screen, 0, sizeof(wnew->screen)); /* DESCO Sys#67660 * Zero out the entire "keyboard" component of "wnew" widget. */ memset(&wnew->keyboard, 0, sizeof(wnew->keyboard)); /* * The workspace has no resources - clear it. */ memset(&wnew->work, 0, sizeof(wnew->work)); /* dummy values so that we don't try to Realize the parent shell with height * or width of 0, which is illegal in X. The real size is computed in the * xtermWidget's Realize proc, but the shell's Realize proc is called first, * and must see a valid size. */ wnew->core.height = wnew->core.width = 1; /* * The definition of -rv now is that it changes the definition of * XtDefaultForeground and XtDefaultBackground. So, we no longer * need to do anything special. */ screen->display = wnew->core.screen->display; /* prep getVisualInfo() */ wnew->visInfo = NULL; wnew->numVisuals = 0; (void) getVisualInfo(wnew); #if OPT_STATUS_LINE StatusInit(&screen->status_data[0]); StatusInit(&screen->status_data[1]); #endif /* * We use the default foreground/background colors to compare/check if a * color-resource has been set. */ #define MyBlackPixel(dpy) BlackPixel(dpy,DefaultScreen(dpy)) #define MyWhitePixel(dpy) WhitePixel(dpy,DefaultScreen(dpy)) if (request->misc.re_verse) { wnew->dft_foreground = MyWhitePixel(screen->display); wnew->dft_background = MyBlackPixel(screen->display); } else { wnew->dft_foreground = MyBlackPixel(screen->display); wnew->dft_background = MyWhitePixel(screen->display); } init_Tres(TEXT_FG); init_Tres(TEXT_BG); repairColors(wnew); wnew->old_foreground = T_COLOR(screen, TEXT_FG); wnew->old_background = T_COLOR(screen, TEXT_BG); TRACE(("Color resource initialization:\n")); TRACE((" Default foreground 0x%06lx\n", wnew->dft_foreground)); TRACE((" Default background 0x%06lx\n", wnew->dft_background)); TRACE((" Screen foreground 0x%06lx\n", T_COLOR(screen, TEXT_FG))); TRACE((" Screen background 0x%06lx\n", T_COLOR(screen, TEXT_BG))); TRACE((" Actual foreground 0x%06lx\n", wnew->old_foreground)); TRACE((" Actual background 0x%06lx\n", wnew->old_background)); screen->mouse_button = 0; screen->mouse_row = -1; screen->mouse_col = -1; #if OPT_BOX_CHARS init_Bres(screen.force_box_chars); init_Bres(screen.force_packed); init_Bres(screen.assume_all_chars); #endif #if OPT_BOX_CHARS || OPT_WIDE_CHARS init_Bres(screen.force_all_chars); #endif init_Bres(screen.free_bold_box); init_Bres(screen.allowBoldFonts); init_Bres(screen.c132); init_Bres(screen.curses); init_Bres(screen.hp_ll_bc); #if OPT_XMC_GLITCH init_Ires(screen.xmc_glitch); init_Ires(screen.xmc_attributes); init_Bres(screen.xmc_inline); init_Bres(screen.move_sgr_ok); #endif #if OPT_BLINK_CURS init_Sres(screen.cursor_blink_s); ebValue = extendedBoolean(wnew->screen.cursor_blink_s, tblBlinkOps, cbLAST); wnew->screen.cursor_blink = (BlinkOps) ebValue; init_Bres(screen.cursor_blink_xor); init_Ires(screen.blink_on); init_Ires(screen.blink_off); screen->cursor_blink_i = screen->cursor_blink; #endif init_Bres(screen.cursor_underline); init_Bres(screen.cursor_bar); /* resources allow for underline or block, not (yet) bar */ InitCursorShape(screen, TScreenOf(request)); #if OPT_BLINK_CURS TRACE(("cursor_shape:%d blinks:%d\n", screen->cursor_shape, screen->cursor_blink)); #endif #if OPT_BLINK_TEXT init_Ires(screen.blink_as_bold); #endif init_Ires(screen.border); init_Bres(screen.jumpscroll); init_Bres(screen.fastscroll); init_Bres(screen.old_fkeys); wnew->screen.old_fkeys0 = wnew->screen.old_fkeys; wnew->keyboard.type = screen->old_fkeys ? keyboardIsLegacy : keyboardIsDefault; init_Mres(screen.delete_is_del); #ifdef ALLOWLOGGING init_Bres(misc.logInhibit); init_Bres(misc.log_on); init_Sres(screen.logfile); #endif init_Bres(screen.bellIsUrgent); init_Bres(screen.bellOnReset); init_Bres(screen.marginbell); init_Bres(screen.multiscroll); init_Ires(screen.nmarginbell); init_Ires(screen.savelines); init_Ires(screen.scrollBarBorder); init_Ires(screen.scrolllines); init_Bres(screen.alternateScroll); init_Bres(screen.scrollttyoutput); init_Bres(screen.scrollkey); init_Dres(screen.scale_height); if (screen->scale_height < MIN_SCALE_HEIGHT) screen->scale_height = MIN_SCALE_HEIGHT; if (screen->scale_height > MAX_SCALE_HEIGHT) screen->scale_height = MAX_SCALE_HEIGHT; init_Bres(misc.autoWrap); init_Bres(misc.login_shell); init_Bres(misc.reverseWrap); init_Bres(misc.scrollbar); init_Sres(misc.geo_metry); init_Sres(misc.T_geometry); init_Sres(screen.term_id); screen->terminal_id = decodeTerminalID(TScreenOf(request)->term_id); screen->display_da1 = screen->terminal_id; /* * (1) If a known terminal model, and not a graphical terminal, preserve * the terminal id. * (2) Otherwise, if ReGIS or sixel graphics are enabled, preserve the ID, * even if it is not a known terminal. * (3) Otherwise force the terminal ID to the min, max, or VT420 depending * on the input. */ switch (screen->terminal_id) { case 52: /* MIN_DECID */ case 100: case 101: case 102: case 131: case 132: case 220: case 320: case 420: /* DFT_DECID, unless overridden in configure */ case 510: case 520: case 525: /* MAX_DECID */ break; default: #if OPT_REGIS_GRAPHICS if (optRegisGraphics(screen)) break; #endif #if OPT_SIXEL_GRAPHICS if (optSixelGraphics(screen)) break; #endif screen->terminal_id = limitedTerminalID(screen->terminal_id); screen->display_da1 = screen->terminal_id; break; } TRACE(("term_id '%s' -> terminal_id %d\n", screen->term_id, screen->terminal_id)); set_vtXX_level(screen, (screen->terminal_id / 100)); init_Ires(screen.title_modes); screen->title_modes0 = screen->title_modes; init_Ires(screen.nextEventDelay); if (screen->nextEventDelay <= 0) screen->nextEventDelay = 1; init_Bres(screen.visualbell); init_Bres(screen.flash_line); init_Ires(screen.visualBellDelay); init_Bres(screen.poponbell); init_Bres(screen.eraseSavedLines0); screen->eraseSavedLines = screen->eraseSavedLines0; init_Ires(misc.limit_resize); #if OPT_NUM_LOCK init_Bres(misc.real_NumLock); init_Bres(misc.alwaysUseMods); #endif #if OPT_INPUT_METHOD init_Bres(misc.open_im); init_Ires(misc.retry_im); init_Sres(misc.f_x); init_Sres(misc.input_method); init_Sres(misc.preedit_type); #endif #if OPT_SHIFT_FONTS init_Bres(misc.shift_fonts); #endif #if OPT_SUNPC_KBD init_Ires(misc.ctrl_fkeys); #endif #if OPT_TEK4014 TEK4014_SHOWN(wnew) = False; /* not a resource... */ init_Bres(misc.tekInhibit); init_Bres(misc.tekSmall); init_Bres(misc.TekEmu); #endif #if OPT_TCAP_QUERY screen->tc_query_code = -1; #endif wnew->misc.re_verse0 = request->misc.re_verse; init_Bres(misc.re_verse); init_Ires(screen.multiClickTime); init_Ires(screen.bellSuppressTime); init_Sres(screen.charClass); init_Bres(screen.always_highlight); init_Bres(screen.brokenSelections); init_Bres(screen.cutNewline); init_Bres(screen.cutToBeginningOfLine); init_Bres(screen.highlight_selection); init_Bres(screen.show_wrap_marks); init_Bres(screen.i18nSelections); init_Bres(screen.keepClipboard); init_Bres(screen.keepSelection); init_Bres(screen.selectToClipboard); init_Bres(screen.trim_selection); screen->pointer_cursor = TScreenOf(request)->pointer_cursor; init_Ires(screen.pointer_mode); wnew->screen.pointer_mode0 = wnew->screen.pointer_mode; init_Sres(screen.answer_back); init_Bres(screen.prefer_latin1); wnew->SPS.printer_checked = False; init_Sres(SPS.printer_command); init_Bres(SPS.printer_autoclose); init_Bres(SPS.printer_extent); init_Bres(SPS.printer_formfeed); init_Bres(SPS.printer_newline); init_Ires(SPS.printer_controlmode); #if OPT_PRINT_COLORS init_Ires(SPS.print_attributes); #endif init_Bres(screen.print_rawchars); init_Sres(screen.keyboard_dialect); init_Sres(screen.cursor_font_name); init_Sres(screen.pointer_shape); init_Bres(screen.input_eight_bits); init_Bres(screen.output_eight_bits); init_Bres(screen.control_eight_bits); init_Bres(screen.backarrow_key); init_Bres(screen.alt_is_not_meta); init_Bres(screen.alt_sends_esc); init_Bres(screen.meta_sends_esc); init_Bres(screen.allowPasteControl0); init_Bres(screen.allowSendEvent0); init_Bres(screen.allowColorOp0); init_Bres(screen.allowFontOp0); init_Bres(screen.allowMouseOp0); init_Bres(screen.allowTcapOp0); init_Bres(screen.allowTitleOp0); init_Bres(screen.allowWindowOp0); init_Sres(screen.colorEvents); #if OPT_SCROLL_LOCK init_Bres(screen.allowScrollLock0); init_Bres(screen.autoScrollLock); #endif init_Sres(screen.disallowedColorOps); set_flags_from_list(screen->disallow_color_ops, screen->disallowedColorOps, tblColorOps); init_Sres(screen.disallowedFontOps); set_flags_from_list(screen->disallow_font_ops, screen->disallowedFontOps, tblFontOps); init_Sres(screen.disallowedMouseOps); set_flags_from_list(screen->disallow_mouse_ops, screen->disallowedMouseOps, tblMouseOps); init_Sres(screen.disallowedPasteOps); set_flags_from_list(screen->disallow_paste_ops, screen->disallowedPasteOps, tblPasteOps); init_Sres(screen.disallowedTcapOps); set_flags_from_list(screen->disallow_tcap_ops, screen->disallowedTcapOps, tblTcapOps); init_Sres(screen.disallowedWinOps); set_flags_from_list(screen->disallow_win_ops, screen->disallowedWinOps, tblWindowOps); init_Sres(screen.default_string); init_Sres(screen.eightbit_select_types); #if OPT_WIDE_CHARS init_Sres(screen.utf8_select_types); #endif /* make a copy so that editres cannot change the resource after startup */ screen->allowPasteControls = screen->allowPasteControl0; screen->allowSendEvents = screen->allowSendEvent0; screen->allowColorOps = screen->allowColorOp0; screen->allowFontOps = screen->allowFontOp0; screen->allowMouseOps = screen->allowMouseOp0; screen->allowTcapOps = screen->allowTcapOp0; screen->allowTitleOps = screen->allowTitleOp0; screen->allowWindowOps = screen->allowWindowOp0; if (!IsEmpty(screen->colorEvents)) { set_flags_from_list(screen->color_events, screen->colorEvents, tblColorEvents); } #if OPT_SCROLL_LOCK screen->allowScrollLock = screen->allowScrollLock0; #endif init_Bres(screen.quiet_grab); #ifndef NO_ACTIVE_ICON init_Sres(screen.icon_fontname); getIconicFont(screen)->fs = xtermLoadQueryFont(wnew, screen->icon_fontname); TRACE(("iconFont '%s' %sloaded successfully\n", screen->icon_fontname, getIconicFont(screen)->fs ? "" : "NOT ")); init_Sres(misc.active_icon_s); wnew->work.active_icon = (Boolean) extendedBoolean(wnew->misc.active_icon_s, tblAIconOps, eiLAST); init_Ires(misc.icon_border_width); wnew->misc.icon_border_pixel = request->misc.icon_border_pixel; #endif /* NO_ACTIVE_ICON */ init_Bres(misc.signalInhibit); init_Bres(misc.titeInhibit); init_Bres(misc.color_inner_border); init_Bres(misc.dynamicColors); init_Bres(misc.resizeByPixel); init_Sres(misc.cdXtraScroll_s); wnew->misc.cdXtraScroll = extendedBoolean(request->misc.cdXtraScroll_s, tblCdXtraScroll, edLast); init_Sres(misc.tiXtraScroll_s); wnew->misc.tiXtraScroll = extendedBoolean(request->misc.tiXtraScroll_s, tblCdXtraScroll, edLast); #if OPT_DEC_CHRSET for (i = 0; i < NUM_CHRSET; i++) { screen->double_fonts[i].warn = fwResource; } #endif for (i = fontMenu_font1; i <= fontMenu_lastBuiltin; i++) { init_Sres2(screen.MenuFontName, i); } for (i = 0; i < fMAX; i++) { screen->fnts[i].warn = fwResource; #if OPT_WIDE_ATTRS screen->ifnts[i].warn = fwResource; #endif } #ifndef NO_ACTIVE_ICON screen->fnt_icon.warn = fwResource; #endif init_Ires(misc.fontWarnings); initFontLists(wnew); #define DefaultFontNames screen->menu_font_names[fontMenu_default] /* * Process Xft font resources first, since faceName may contain X11 fonts * that should override the "font" resource. */ #if OPT_RENDERFONT init_Bres(screen.force_xft_height); for (i = 0; i <= fontMenu_lastBuiltin; ++i) { init_Dres2(misc.face_size, i); } init_Ires(screen.xft_max_glyph_memory); init_Ires(screen.xft_max_unref_fonts); init_Bres(screen.xft_track_mem_usage); #define ALLOC_FONTLIST(name,which,field) \ init_Sres(misc.default_xft.field);\ allocFontList(wnew,\ name,\ &(wnew->work.fonts),\ which,\ wnew->misc.default_xft.field,\ True) ALLOC_FONTLIST(XtNfaceName, fNorm, f_n); #if OPT_WIDE_CHARS ALLOC_FONTLIST(XtNfaceNameDoublesize, fWide, f_w); #endif #undef ALLOC_FONTLIST #endif /* * Process X11 (XLFD) font specifications. */ #define ALLOC_FONTLIST(name,which,field) \ init_Sres(misc.default_font.field);\ allocFontList(wnew,\ name,\ &(wnew->work.fonts),\ which,\ wnew->misc.default_font.field,\ False) ALLOC_FONTLIST(XtNfont, fNorm, f_n); ALLOC_FONTLIST(XtNboldFont, fBold, f_b); DefaultFontNames[fNorm] = x_strdup(DefaultFontN(wnew)); DefaultFontNames[fBold] = x_strdup(DefaultFontB(wnew)); #if OPT_WIDE_CHARS ALLOC_FONTLIST(XtNwideFont, fWide, f_w); ALLOC_FONTLIST(XtNwideBoldFont, fWBold, f_wb); DefaultFontNames[fWide] = x_strdup(DefaultFontW(wnew)); DefaultFontNames[fWBold] = x_strdup(DefaultFontWB(wnew)); #endif #undef ALLOC_FONTLIST screen->EscapeFontName() = NULL; screen->SelectFontName() = NULL; screen->menu_font_number = fontMenu_default; init_Sres(screen.initial_font); if (screen->initial_font != NULL) { int result = xtermGetFont(screen->initial_font); if (result >= 0) screen->menu_font_number = result; } #if OPT_BROKEN_OSC init_Bres(screen.brokenLinuxOSC); #endif #if OPT_BROKEN_ST init_Bres(screen.brokenStringTerm); #endif #if OPT_C1_PRINT init_Bres(screen.c1_printable); #endif #if OPT_CLIP_BOLD init_Bres(screen.use_border_clipping); init_Bres(screen.use_clipping); #endif #if OPT_DEC_CHRSET init_Bres(screen.font_doublesize); init_Ires(screen.cache_doublesize); if (screen->cache_doublesize > NUM_CHRSET) screen->cache_doublesize = NUM_CHRSET; if (screen->cache_doublesize == 0) screen->font_doublesize = False; TRACE(("Doublesize%s enabled, up to %d fonts\n", screen->font_doublesize ? "" : " not", screen->cache_doublesize)); #endif #if OPT_DEC_RECTOPS init_Ires(screen.checksum_ext0); screen->checksum_ext = screen->checksum_ext0; #endif #if OPT_ISO_COLORS init_Ires(screen.veryBoldColors); init_Bres(screen.boldColors); init_Bres(screen.colorAttrMode); init_Bres(screen.colorBDMode); init_Bres(screen.colorBLMode); init_Bres(screen.colorMode); init_Bres(screen.colorULMode); init_Bres(screen.italicULMode); init_Bres(screen.colorRVMode); #if OPT_WIDE_ATTRS init_Bres(screen.colorITMode); #endif #if OPT_DIRECT_COLOR init_Bres(screen.direct_color); #endif #if OPT_WIDE_ATTRS && OPT_SGR2_HASH init_Bres(screen.faint_relative); #endif #if OPT_VT525_COLORS screen->assigned_fg = 7; screen->assigned_bg = 0; #if MIN_ANSI_COLORS >= 16 /* * VT520-RM does not define the initial palette, but this is preferable * to black-on-black. */ for (i = 0; i < 16; i++) { screen->alt_colors[i].fg = screen->assigned_fg; screen->alt_colors[i].bg = screen->assigned_bg; } #endif #endif TRACE(("...will fake resources for color%d to color%d\n", MIN_ANSI_COLORS, NUM_ANSI_COLORS - 1)); for (i = 0, color_ok = False; i < MAXCOLORS; i++) { /* * Xt has a hardcoded limit on the maximum number of resources that can * be used in a widget. If we configured both luit (which implies * wide-characters) and 256-colors, it goes over that limit. Most * people would not need a resource-file with 256-colors; the default * values in our table are sufficient. Fake the resource setting by * copying the default value from the table. The #define's can be * overridden to make these true resources. */ if (i >= MIN_ANSI_COLORS && i < NUM_ANSI_COLORS) { screen->Acolors[i].resource = x_strtrim(fake_resources[i - MIN_ANSI_COLORS].default_addr); if (screen->Acolors[i].resource == NULL) screen->Acolors[i].resource = XtDefaultForeground; } else { screen->Acolors[i] = TScreenOf(request)->Acolors[i]; screen->Acolors[i].resource = x_strtrim(screen->Acolors[i].resource); } TRACE(("Acolors[%d] = %s\n", i, screen->Acolors[i].resource)); screen->Acolors[i].mode = False; if (DftFg(Acolors[i])) { screen->Acolors[i].value = T_COLOR(screen, TEXT_FG); screen->Acolors[i].mode = True; } else if (DftBg(Acolors[i])) { screen->Acolors[i].value = T_COLOR(screen, TEXT_BG); screen->Acolors[i].mode = True; } else { color_ok = True; } } /* * Check if we're trying to use color in a monochrome screen. Disable * color in that case, since that would make ANSI colors unusable. A 4-bit * or 8-bit display is usable, so we do not have to check for anything more * specific. */ if (color_ok) { if (getVisualDepth(wnew) <= 1) { TRACE(("disabling color since screen is monochrome\n")); color_ok = False; } } /* If none of the colors are anything other than the foreground or * background, we'll assume this isn't color, no matter what the colorMode * resource says. (There doesn't seem to be any good way to determine if * the resource lookup failed versus the user having misconfigured this). */ if (!color_ok) { screen->colorMode = False; TRACE(("All colors are foreground or background: disable colorMode\n")); } wnew->sgr_foreground = -1; wnew->sgr_background = -1; wnew->sgr_38_xcolors = False; clrDirectFG(wnew->flags); clrDirectFG(wnew->flags); #endif /* OPT_ISO_COLORS */ /* * Decode the resources that control the behavior on multiple mouse clicks. * A single click is always bound to normal character selection, but the * other flavors can be changed. */ for (i = 0; i < NSELECTUNITS; ++i) { int ck = (i + 1); screen->maxClicks = ck; if (i == Select_CHAR) screen->selectMap[i] = Select_CHAR; else if (TScreenOf(request)->onClick[i] != NULL) ParseOnClicks(wnew, request, (unsigned) i); else if (i <= Select_LINE) screen->selectMap[i] = (SelectUnit) i; else break; #if OPT_XRES_QUERY init_Sres(screen.onClick[i]); #endif TRACE(("on%dClicks %s=%d\n", ck, NonNull(TScreenOf(request)->onClick[i]), screen->selectMap[i])); if (screen->selectMap[i] == NSELECTUNITS) break; } TRACE(("maxClicks %d\n", screen->maxClicks)); init_Tres(MOUSE_FG); init_Tres(MOUSE_BG); init_Tres(TEXT_CURSOR); #if OPT_HIGHLIGHT_COLOR init_Tres(HIGHLIGHT_BG); init_Tres(HIGHLIGHT_FG); init_Bres(screen.hilite_reverse); init_Mres(screen.hilite_color); if (screen->hilite_color == Maybe) { screen->hilite_color = False; /* * If the highlight text/background are both set, and if they are * not equal to either the text/background or background/text, then * set the highlightColorMode automatically. */ if (!DftFg(Tcolors[HIGHLIGHT_BG]) && !DftBg(Tcolors[HIGHLIGHT_FG]) && !TxtFg(Tcolors[HIGHLIGHT_BG]) && !TxtBg(Tcolors[HIGHLIGHT_FG]) && !TxtBg(Tcolors[HIGHLIGHT_BG]) && !TxtFg(Tcolors[HIGHLIGHT_FG])) { TRACE(("...setting hilite_color automatically\n")); screen->hilite_color = True; } } #endif #if OPT_TEK4014 /* * The Tek4014 window has no separate resources for foreground, background * and cursor color. Since xterm always creates the vt100 widget first, we * can set the Tektronix colors here. That lets us use escape sequences to * set its dynamic colors and get consistent behavior whether or not the * window is displayed. */ screen->Tcolors[TEK_BG] = screen->Tcolors[TEXT_BG]; screen->Tcolors[TEK_FG] = screen->Tcolors[TEXT_FG]; screen->Tcolors[TEK_CURSOR] = screen->Tcolors[TEXT_CURSOR]; #endif #ifdef SCROLLBAR_RIGHT init_Bres(misc.useRight); #endif #if OPT_RENDERFONT init_Ires(misc.limit_fontsets); init_Ires(misc.limit_fontheight); if (wnew->misc.limit_fontheight > 50) { xtermWarning("limiting extra fontheight percent to 50 (was %d)\n", wnew->misc.limit_fontheight); wnew->misc.limit_fontheight = 50; } init_Ires(misc.limit_fontwidth); if (wnew->misc.limit_fontwidth > 50) { xtermWarning("limiting extra fontwidth percent to 50 (was %d)\n", wnew->misc.limit_fontwidth); wnew->misc.limit_fontwidth = 50; } wnew->work.max_fontsets = (unsigned) wnew->misc.limit_fontsets; if (wnew->work.max_fontsets > 255) { xtermWarning("limiting number of fontsets to 255 (was %u)\n", wnew->work.max_fontsets); wnew->work.max_fontsets = 255; } init_Sres(misc.render_font_s); wnew->work.render_font = (Boolean) extendedBoolean(wnew->misc.render_font_s, tblRenderFont, erLast); if (wnew->work.render_font == erDefault) { if (IsEmpty(CurrentXftFont(wnew))) { free((void *) CurrentXftFont(wnew)); CurrentXftFont(wnew) = x_strdup(DEFFACENAME_AUTO); TRACE(("will allow runtime switch to render_font using \"%s\"\n", CurrentXftFont(wnew))); } else { wnew->work.render_font = erTrue; TRACE(("initially using TrueType font\n")); } } else if (wnew->work.render_font == erDefaultOff) { wnew->work.render_font = erFalse; } /* minor tweak to make debug traces consistent: */ if (wnew->work.render_font) { if (IsEmpty(CurrentXftFont(wnew))) { wnew->work.render_font = False; TRACE(("reset render_font since there is no face_name\n")); } } #endif #if OPT_WIDE_CHARS /* setup data for next call */ init_Sres(screen.utf8_mode_s); request->screen.utf8_mode = extendedBoolean(request->screen.utf8_mode_s, tblUtf8Mode, uLast); init_Sres(screen.utf8_fonts_s); request->screen.utf8_fonts = extendedBoolean(request->screen.utf8_fonts_s, tblUtf8Mode, uLast); init_Sres(screen.utf8_title_s); request->screen.utf8_title = extendedBoolean(request->screen.utf8_title_s, tblUtf8Mode, uLast); /* * Make a copy in the input/request so that DefaultFontN() works for * the "CHECKFONT" option. */ copyFontList(&(request->work.fonts.x11.list_n), wnew->work.fonts.x11.list_n); VTInitialize_locale(request); init_Bres(screen.normalized_c); init_Bres(screen.utf8_latin1); init_Bres(screen.utf8_weblike); #if OPT_LUIT_PROG init_Bres(misc.callfilter); init_Bres(misc.use_encoding); init_Sres(misc.locale_str); init_Sres(misc.localefilter); #endif init_Ires(screen.utf8_inparse); init_Ires(screen.utf8_mode); init_Ires(screen.utf8_fonts); init_Ires(screen.utf8_title); init_Ires(screen.max_combining); init_Ires(screen.utf8_always); /* from utf8_mode, used in doparse */ if (screen->max_combining < 0) { screen->max_combining = 0; } if (screen->max_combining > 5) { screen->max_combining = 5; } init_Bres(screen.vt100_graphics); init_Bres(screen.wide_chars); init_Bres(misc.mk_width); init_Bres(misc.cjk_width); init_Ires(misc.mk_samplesize); init_Ires(misc.mk_samplepass); if (wnew->misc.mk_samplesize > 0xffff) wnew->misc.mk_samplesize = 0xffff; if (wnew->misc.mk_samplesize < 0) wnew->misc.mk_samplesize = 0; if (wnew->misc.mk_samplepass > wnew->misc.mk_samplesize) wnew->misc.mk_samplepass = wnew->misc.mk_samplesize; if (wnew->misc.mk_samplepass < 0) wnew->misc.mk_samplepass = 0; if (TScreenOf(request)->utf8_mode) { TRACE(("setting wide_chars on\n")); screen->wide_chars = True; } else { TRACE(("setting utf8_mode to 0\n")); screen->utf8_mode = uFalse; } mk_wcwidth_init(screen->utf8_mode); TRACE(("initialized UTF-8 mode to %d\n", screen->utf8_mode)); #if OPT_MINI_LUIT if (TScreenOf(request)->latin9_mode) { screen->latin9_mode = True; } if (TScreenOf(request)->unicode_font) { screen->unicode_font = True; } TRACE(("initialized Latin9 mode to %d\n", screen->latin9_mode)); TRACE(("initialized unicode_font to %d\n", screen->unicode_font)); #endif decode_wcwidth(wnew); xtermSaveVTFonts(wnew); #endif /* OPT_WIDE_CHARS */ init_Sres(screen.eight_bit_meta_s); wnew->screen.eight_bit_meta = extendedBoolean(request->screen.eight_bit_meta_s, tbl8BitMeta, ebLast); if (wnew->screen.eight_bit_meta == ebLocale) { #if OPT_WIDE_CHARS if (xtermEnvUTF8()) { wnew->screen.eight_bit_meta = ebFalse; TRACE(("...eightBitMeta is false due to locale\n")); } else #endif /* OPT_WIDE_CHARS */ { wnew->screen.eight_bit_meta = ebTrue; TRACE(("...eightBitMeta is true due to locale\n")); } } init_Bres(screen.always_bold_mode); init_Bres(screen.bold_mode); init_Bres(screen.underline); wnew->cur_foreground = 0; wnew->cur_background = 0; wnew->keyboard.flags = MODE_SRM; if (screen->backarrow_key) wnew->keyboard.flags |= MODE_DECBKM; TRACE(("initialized DECBKM %s\n", BtoS(wnew->keyboard.flags & MODE_DECBKM))); #if OPT_SIXEL_GRAPHICS /* Sixel scrolling is opposite of Sixel Display Mode */ init_Bres(screen.sixel_scrolling); if (screen->sixel_scrolling) UIntClr(wnew->keyboard.flags, MODE_DECSDM); else UIntSet(wnew->keyboard.flags, MODE_DECSDM); TRACE(("initialized DECSDM %s\n", BtoS(wnew->keyboard.flags & MODE_DECSDM))); #endif #if OPT_GRAPHICS init_Sres(screen.graph_termid); screen->graphics_termid = decodeTerminalID(TScreenOf(request)->graph_termid); switch (screen->graphics_termid) { case 125: case 240: case 241: case 330: case 340: case 382: break; default: screen->graphics_termid = 0; break; } TRACE(("graph_termid '%s' -> graphics_termid %d\n", screen->graph_termid, screen->graphics_termid)); init_Ires(screen.numcolorregisters); TRACE(("initialized NUM_COLOR_REGISTERS to resource default: %d\n", screen->numcolorregisters)); init_Bres(screen.privatecolorregisters); /* FIXME: should this be off unconditionally here? */ TRACE(("initialized PRIVATE_COLOR_REGISTERS to resource default: %s\n", BtoS(screen->privatecolorregisters))); screen->privatecolorregisters0 = screen->privatecolorregisters; init_Bres(screen.incremental_graphics); TRACE(("initialized INCREMENTAL_GRAPHICS to resource default: %s\n", BtoS(screen->incremental_graphics))); #endif #if OPT_GRAPHICS { int native_w, native_h; switch (GraphicsTermId(screen)) { case 125: native_w = 768; native_h = 460; break; case 240: /* FALLTHRU */ case 241: native_w = 800; native_h = 460; break; case 330: /* FALLTHRU */ case 340: native_w = 800; native_h = 480; break; default: native_w = 800; native_h = 480; break; case 382: native_w = 960; native_h = 720; break; } # if OPT_REGIS_GRAPHICS init_Sres(screen.graphics_regis_default_font); TRACE(("default ReGIS font: %s\n", screen->graphics_regis_default_font)); init_Sres(screen.graphics_regis_screensize); screen->graphics_regis_def_high = 1000; screen->graphics_regis_def_wide = 1000; if (!x_strcasecmp(screen->graphics_regis_screensize, "auto")) { TRACE(("setting default ReGIS screensize based on graphics_id %d\n", GraphicsTermId(screen))); screen->graphics_regis_def_high = (Dimension) native_h; screen->graphics_regis_def_wide = (Dimension) native_w; } else { int conf_high; int conf_wide; char ignore; if (sscanf(screen->graphics_regis_screensize, "%dx%d%c", &conf_wide, &conf_high, &ignore) == 2) { if (conf_high > 0 && conf_wide > 0) { screen->graphics_regis_def_high = (Dimension) conf_high; screen->graphics_regis_def_wide = (Dimension) conf_wide; } else { TRACE(("ignoring invalid regisScreenSize %s\n", screen->graphics_regis_screensize)); } } else { TRACE(("ignoring invalid regisScreenSize %s\n", screen->graphics_regis_screensize)); } } TRACE(("default ReGIS graphics screensize %dx%d\n", (int) screen->graphics_regis_def_wide, (int) screen->graphics_regis_def_high)); # endif init_Sres(screen.graphics_max_size); screen->graphics_max_high = 1000; screen->graphics_max_wide = 1000; if (!x_strcasecmp(screen->graphics_max_size, "auto")) { TRACE(("setting max graphics screensize based on graphics_id %d\n", GraphicsTermId(screen))); screen->graphics_max_high = (Dimension) native_h; screen->graphics_max_wide = (Dimension) native_w; } else { int conf_high; int conf_wide; char ignore; if (sscanf(screen->graphics_max_size, "%dx%d%c", &conf_wide, &conf_high, &ignore) == 2) { if (conf_high > 0 && conf_wide > 0) { screen->graphics_max_high = (Dimension) conf_high; screen->graphics_max_wide = (Dimension) conf_wide; } else { TRACE(("ignoring invalid maxGraphicSize %s\n", screen->graphics_max_size)); } } else { TRACE(("ignoring invalid maxGraphicSize %s\n", screen->graphics_max_size)); } } # if OPT_REGIS_GRAPHICS /* Make sure the max is large enough for the default ReGIS size. */ if (screen->graphics_regis_def_high > screen->graphics_max_high) { screen->graphics_max_high = screen->graphics_regis_def_high; } if (screen->graphics_regis_def_wide > screen->graphics_max_wide) { screen->graphics_max_wide = screen->graphics_regis_def_wide; } # endif TRACE(("max graphics screensize %dx%d\n", (int) screen->graphics_max_wide, (int) screen->graphics_max_high)); } #endif #if OPT_SIXEL_GRAPHICS init_Bres(screen.sixel_scrolls_right); screen->sixel_scrolls_right0 = screen->sixel_scrolls_right; #endif #if OPT_PRINT_GRAPHICS init_Bres(screen.graphics_print_to_host); init_Bres(screen.graphics_expanded_print_mode); init_Bres(screen.graphics_print_color_mode); init_Bres(screen.graphics_print_color_syntax); init_Bres(screen.graphics_print_background_mode); init_Bres(screen.graphics_rotated_print_mode); #endif #if OPT_STATUS_LINE init_Sres(screen.status_fmt); #endif /* look for focus related events on the shell, because we need * to care about the shell's border being part of our focus. */ TRACE(("adding event handlers for my_parent %p\n", (void *) my_parent)); XtAddEventHandler(my_parent, EnterWindowMask, False, HandleEnterWindow, (Opaque) NULL); XtAddEventHandler(my_parent, LeaveWindowMask, False, HandleLeaveWindow, (Opaque) NULL); XtAddEventHandler(my_parent, FocusChangeMask, False, HandleFocusChange, (Opaque) NULL); XtAddEventHandler((Widget) wnew, 0L, True, VTNonMaskableEvent, (Opaque) NULL); XtAddEventHandler((Widget) wnew, PropertyChangeMask, False, HandleBellPropertyChange, (Opaque) NULL); #if HANDLE_STRUCT_NOTIFY #if OPT_TOOLBAR wnew->VT100_TB_INFO(menu_bar) = request->VT100_TB_INFO(menu_bar); init_Ires(VT100_TB_INFO(menu_height)); #endif XtAddEventHandler(my_parent, MappingNotify | StructureNotifyMask, False, HandleStructNotify, (Opaque) 0); #endif /* HANDLE_STRUCT_NOTIFY */ screen->bellInProgress = False; set_character_class(screen->charClass); #if OPT_REPORT_CCLASS if (resource.reportCClass) report_char_class(wnew); #endif /* create it, but don't realize it */ ScrollBarOn(wnew, True); /* make sure that the resize gravity acceptable */ if (!GravityIsNorthWest(wnew) && !GravityIsSouthWest(wnew)) { char value[80]; String temp[2]; Cardinal nparams = 1; sprintf(value, "%d", wnew->misc.resizeGravity); temp[0] = value; temp[1] = NULL; XtAppWarningMsg(app_con, "rangeError", "resizeGravity", "XTermError", "unsupported resizeGravity resource value (%s)", temp, &nparams); wnew->misc.resizeGravity = SouthWestGravity; } #ifndef NO_ACTIVE_ICON screen->whichVwin = &screen->fullVwin; #endif /* NO_ACTIVE_ICON */ init_Ires(screen.unparse_max); if ((int) screen->unparse_max < 256) screen->unparse_max = 256; screen->unparse_bfr = (IChar *) (void *) XtCalloc(screen->unparse_max, (Cardinal) sizeof(IChar)); init_Ires(screen.strings_max); if (screen->savelines < 0) screen->savelines = 0; init_Bres(screen.awaitInput); wnew->flags = 0; if (!screen->jumpscroll) wnew->flags |= SMOOTHSCROLL; if (wnew->misc.reverseWrap) wnew->flags |= REVERSEWRAP; if (wnew->misc.autoWrap) wnew->flags |= WRAPAROUND; if (wnew->misc.re_verse != wnew->misc.re_verse0) wnew->flags |= REVERSE_VIDEO; if (screen->c132) wnew->flags |= IN132COLUMNS; wnew->initflags = wnew->flags; init_Sres(keyboard.shift_escape_s); wnew->keyboard.shift_escape = extendedBoolean(wnew->keyboard.shift_escape_s, tblShift2S, ssLAST); #if OPT_MOD_FKEYS init_Ires(keyboard.modify_1st.allow_keys); init_Ires(keyboard.modify_1st.cursor_keys); init_Ires(keyboard.modify_1st.function_keys); init_Ires(keyboard.modify_1st.keypad_keys); init_Ires(keyboard.modify_1st.other_keys); init_Ires(keyboard.modify_1st.special_keys); init_Ires(keyboard.modify_1st.string_keys); init_Ires(keyboard.format_1st.allow_keys); init_Ires(keyboard.format_1st.cursor_keys); init_Ires(keyboard.format_1st.function_keys); init_Ires(keyboard.format_1st.keypad_keys); init_Ires(keyboard.format_1st.other_keys); init_Ires(keyboard.format_1st.special_keys); init_Ires(keyboard.format_1st.string_keys); wnew->keyboard.modify_now = wnew->keyboard.modify_1st; wnew->keyboard.format_now = wnew->keyboard.format_1st; wnew->keyboard.ignore_now = wnew->keyboard.ignore_1st; #endif init_Ires(misc.appcursorDefault); if (wnew->misc.appcursorDefault) wnew->keyboard.flags |= MODE_DECCKM; init_Ires(misc.appkeypadDefault); if (wnew->misc.appkeypadDefault) wnew->keyboard.flags |= MODE_DECKPAM; initLineData(wnew); #if OPT_WIDE_CHARS freeFontList(&(request->work.fonts.x11.list_n)); #endif #if OPT_XRES_QUERY if (resource.reportXRes) reportResources(wnew); #endif xtermResetLocale(LC_NUMERIC, saveLocale); TRACE(("" TRACE_R " VTInitialize\n")); return; } void releaseCursorGCs(XtermWidget xw) { TScreen *screen = TScreenOf(xw); VTwin *win = WhichVWin(screen); int n; for_each_curs_gc(n) { freeCgs(xw, win, (CgsEnum) n); } } void releaseWindowGCs(XtermWidget xw, VTwin *win) { int n; for_each_text_gc(n) { switch (n) { case gcBorder: case gcFiller: break; default: freeCgs(xw, win, (CgsEnum) n); break; } } } #define TRACE_FREE_LEAK(name) \ if (name) { \ TRACE(("freed " #name ": %p\n", (const void *) name)); \ FreeAndNull(name); \ } #define TRACE_FREE_GC(name,part) \ if (part) { \ TRACE(("freed %s " #part ": %p\n", name, (const void *) part)); \ XFreeGC(dpy, part); \ part = NULL; \ } #if OPT_INPUT_METHOD static void cleanupInputMethod(XtermWidget xw) { TInput *input = lookupTInput(xw, (Widget) xw); if (input && input->xim) { XCloseIM(input->xim); input->xim = NULL; TRACE(("freed screen->xim\n")); } } #else #define cleanupInputMethod(xw) /* nothing */ #endif #ifdef NO_LEAKS #define FREE_VT_WIN(name) freeVTwin(dpy, #name, &(screen->name)) static void freeVTwin(Display *dpy, const char *whichWin, VTwin *win) { (void) whichWin; TRACE_FREE_GC(whichWin, win->filler_gc); TRACE_FREE_GC(whichWin, win->border_gc); TRACE_FREE_GC(whichWin, win->marker_gc[0]); TRACE_FREE_GC(whichWin, win->marker_gc[1]); } #endif static void VTDestroy(Widget w GCC_UNUSED) { #ifdef NO_LEAKS XtermWidget xw = (XtermWidget) w; TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; Cardinal n, k; StopBlinking(xw); if (screen->scrollWidget) { XtUninstallTranslations(screen->scrollWidget); XtDestroyWidget(screen->scrollWidget); } while (screen->saved_fifo > 0) { deleteScrollback(screen); } for (n = 0; n < MAX_SAVED_TITLES; ++n) xtermFreeTitle(&screen->saved_titles.data[n]); #if OPT_STATUS_LINE free(screen->status_fmt); #endif #ifndef NO_ACTIVE_ICON TRACE_FREE_LEAK(xw->misc.active_icon_s); #endif #if OPT_ISO_COLORS TRACE_FREE_LEAK(screen->cmap_data); for (n = 0; n < MAXCOLORS; n++) { TRACE_FREE_LEAK(screen->Acolors[n].resource); } for (n = 0; n < MAX_SAVED_SGR; n++) { TRACE_FREE_LEAK(xw->saved_colors.palettes[n]); } #endif for (n = 0; n < NCOLORS; n++) { switch (n) { #if OPT_TEK4014 case TEK_BG: /* FALLTHRU */ case TEK_FG: /* FALLTHRU */ case TEK_CURSOR: break; #endif default: TRACE_FREE_LEAK(screen->Tcolors[n].resource); break; } } FreeMarkGCs(xw); TRACE_FREE_LEAK(screen->unparse_bfr); TRACE_FREE_LEAK(screen->save_ptr); TRACE_FREE_LEAK(screen->saveBuf_data); TRACE_FREE_LEAK(screen->saveBuf_index); for (n = 0; n < 2; ++n) { TRACE_FREE_LEAK(screen->editBuf_data[n]); TRACE_FREE_LEAK(screen->editBuf_index[n]); } TRACE_FREE_LEAK(screen->keyboard_dialect); TRACE_FREE_LEAK(screen->cursor_font_name); TRACE_FREE_LEAK(screen->pointer_shape); TRACE_FREE_LEAK(screen->term_id); #if OPT_WIDE_CHARS TRACE_FREE_LEAK(screen->utf8_mode_s); TRACE_FREE_LEAK(screen->utf8_fonts_s); TRACE_FREE_LEAK(screen->utf8_title_s); #if OPT_LUIT_PROG TRACE_FREE_LEAK(xw->misc.locale_str); TRACE_FREE_LEAK(xw->misc.localefilter); #endif #endif TRACE_FREE_LEAK(xw->misc.T_geometry); TRACE_FREE_LEAK(xw->misc.geo_metry); #if OPT_INPUT_METHOD cleanupInputMethod(xw); TRACE_FREE_LEAK(xw->misc.f_x); TRACE_FREE_LEAK(xw->misc.input_method); TRACE_FREE_LEAK(xw->misc.preedit_type); #endif releaseCursorGCs(xw); releaseWindowGCs(xw, &(screen->fullVwin)); #ifndef NO_ACTIVE_ICON XFreeFont(screen->display, getIconicFont(screen)->fs); releaseWindowGCs(xw, &(screen->iconVwin)); #endif XtUninstallTranslations((Widget) xw); #if OPT_TOOLBAR XtUninstallTranslations((Widget) XtParent(xw)); #endif XtUninstallTranslations((Widget) SHELL_OF(xw)); if (screen->hidden_cursor) XFreeCursor(screen->display, screen->hidden_cursor); xtermCloseFonts(xw, screen->fnts); #if OPT_WIDE_ATTRS xtermCloseFonts(xw, screen->ifnts); #endif noleaks_cachedCgs(xw); free_termcap(xw); FREE_VT_WIN(fullVwin); #ifndef NO_ACTIVE_ICON FREE_VT_WIN(iconVwin); #endif /* NO_ACTIVE_ICON */ TRACE_FREE_LEAK(screen->selection_targets_8bit); #if OPT_SELECT_REGEX for (n = 0; n < NSELECTUNITS; ++n) { if (screen->selectMap[n] == Select_REGEX) { TRACE_FREE_LEAK(screen->selectExpr[n]); } } #endif #if OPT_RENDERFONT for (n = 0; n < NMENUFONTS; ++n) { int e; for (e = 0; e < fMAX; ++e) { xtermCloseXft(screen, getMyXftFont(xw, e, (int) n)); } } discardRenderDraw(screen); { ListXftFonts *p; while ((p = screen->list_xft_fonts) != NULL) { screen->list_xft_fonts = p->next; free(p); } } #endif /* free things allocated via init_Sres or Init_Sres2 */ #ifndef NO_ACTIVE_ICON TRACE_FREE_LEAK(screen->icon_fontname); #endif #ifdef ALLOWLOGGING TRACE_FREE_LEAK(screen->logfile); #endif TRACE_FREE_LEAK(screen->eight_bit_meta_s); TRACE_FREE_LEAK(screen->charClass); TRACE_FREE_LEAK(screen->answer_back); TRACE_FREE_LEAK(screen->printer_state.printer_command); TRACE_FREE_LEAK(screen->disallowedColorOps); TRACE_FREE_LEAK(screen->disallowedFontOps); TRACE_FREE_LEAK(screen->disallowedMouseOps); TRACE_FREE_LEAK(screen->disallowedPasteOps); TRACE_FREE_LEAK(screen->disallowedTcapOps); TRACE_FREE_LEAK(screen->disallowedWinOps); TRACE_FREE_LEAK(screen->default_string); TRACE_FREE_LEAK(screen->eightbit_select_types); #if OPT_WIDE_CHARS TRACE_FREE_LEAK(screen->utf8_select_types); #endif #if 0 for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; n++) { TRACE_FREE_LEAK(screen->MenuFontName(n)); } #endif TRACE_FREE_LEAK(screen->initial_font); #if OPT_LUIT_PROG TRACE_FREE_LEAK(xw->misc.locale_str); TRACE_FREE_LEAK(xw->misc.localefilter); #endif TRACE_FREE_LEAK(xw->misc.cdXtraScroll_s); TRACE_FREE_LEAK(xw->misc.tiXtraScroll_s); #if OPT_RENDERFONT TRACE_FREE_LEAK(xw->misc.default_xft.f_n); #if OPT_WIDE_CHARS TRACE_FREE_LEAK(xw->misc.default_xft.f_w); #endif TRACE_FREE_LEAK(xw->misc.render_font_s); #endif TRACE_FREE_LEAK(xw->misc.default_font.f_n); TRACE_FREE_LEAK(xw->misc.default_font.f_b); #if OPT_WIDE_CHARS TRACE_FREE_LEAK(xw->misc.default_font.f_w); TRACE_FREE_LEAK(xw->misc.default_font.f_wb); #endif TRACE_FREE_LEAK(xw->work.wm_name); freeFontLists(&(xw->work.fonts.x11)); #if OPT_RENDERFONT freeFontLists(&(xw->work.fonts.xft)); #endif xtermFontName(NULL); #if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS TRACE_FREE_LEAK(screen->cacheVTFonts.default_font.f_n); TRACE_FREE_LEAK(screen->cacheVTFonts.default_font.f_b); #if OPT_WIDE_CHARS TRACE_FREE_LEAK(screen->cacheVTFonts.default_font.f_w); TRACE_FREE_LEAK(screen->cacheVTFonts.default_font.f_wb); #endif freeFontLists(&(screen->cacheVTFonts.fonts.x11)); for (n = 0; n < NMENUFONTS; ++n) { for (k = 0; k < fMAX; ++k) { if (screen->menu_font_names[n][k] != screen->cacheVTFonts.menu_font_names[n][k]) { if (screen->menu_font_names[n][k] != _Font_Selected_) { TRACE_FREE_LEAK(screen->menu_font_names[n][k]); } TRACE_FREE_LEAK(screen->cacheVTFonts.menu_font_names[n][k]); } else { TRACE_FREE_LEAK(screen->menu_font_names[n][k]); } } } #endif #if OPT_BLINK_CURS TRACE_FREE_LEAK(screen->cursor_blink_s); #endif #if OPT_REGIS_GRAPHICS TRACE_FREE_LEAK(screen->graphics_regis_default_font); TRACE_FREE_LEAK(screen->graphics_regis_screensize); #endif #if OPT_GRAPHICS TRACE_FREE_LEAK(screen->graph_termid); TRACE_FREE_LEAK(screen->graphics_max_size); #endif for (n = 0; n < NSELECTUNITS; ++n) { #if OPT_SELECT_REGEX TRACE_FREE_LEAK(screen->selectExpr[n]); #endif #if OPT_XRES_QUERY TRACE_FREE_LEAK(screen->onClick[n]); #endif } XtFree((void *) (screen->selection_atoms)); for (n = 0; n < MAX_SELECTIONS; ++n) { free(screen->selected_cells[n].data_buffer); } if (defaultTranslations != xtermClassRec.core_class.tm_table) { TRACE_FREE_LEAK(defaultTranslations); } TRACE_FREE_LEAK(xtermClassRec.core_class.tm_table); TRACE_FREE_LEAK(xw->keyboard.shift_escape_s); TRACE_FREE_LEAK(xw->keyboard.extra_translations); TRACE_FREE_LEAK(xw->keyboard.shell_translations); TRACE_FREE_LEAK(xw->keyboard.xterm_translations); TRACE_FREE_LEAK(xw->keyboard.print_translations); UnmapSelections(xw); XtFree((void *) (xw->visInfo)); #if OPT_WIDE_CHARS FreeTypedBuffer(IChar); FreeTypedBuffer(XChar2b); FreeTypedBuffer(Char); #endif #if OPT_RENDERFONT #if OPT_RENDERWIDE FreeTypedBuffer(XftCharSpec); #else FreeTypedBuffer(XftChar8); #endif #endif TRACE_FREE_LEAK(myState.print_area); TRACE_FREE_LEAK(myState.string_area); memset(&myState, 0, sizeof(myState)); #endif /* defined(NO_LEAKS) */ } #ifndef NO_ACTIVE_ICON static void * getProperty(Display *dpy, Window w, Atom req_type, const char *prop_name) { Atom property; Atom actual_return_type; int actual_format_return = 0; unsigned long nitems_return = 0; unsigned long bytes_after_return = 0; unsigned char *prop_return = NULL; long long_length = 1024; size_t limit; char *result = NULL; TRACE(("getProperty %s(%s)\n", prop_name, req_type ? TraceAtomName(dpy, req_type) : "?")); property = CachedInternAtom(dpy, prop_name); if (!xtermGetWinProp(dpy, w, property, 0L, long_length, req_type, &actual_return_type, &actual_format_return, &nitems_return, &bytes_after_return, &prop_return)) { TRACE((".. Cannot get %s property.\n", prop_name)); } else if (prop_return != NULL) { if (nitems_return != 0 && actual_format_return != 0 && actual_return_type == req_type) { /* * Null-terminate the result to make string handling easier. * The format==8 corresponds to strings, and the number of items * is the number of characters. */ if (actual_format_return == 8) { limit = nitems_return; } else { /* manpage is misleading - X really uses 'long', not 32-bits */ limit = sizeof(long) * nitems_return; } if ((result = malloc(limit + 1)) != NULL) { memcpy(result, prop_return, limit); result[limit] = '\0'; } TRACE(("... result %s\n", result ? ("ok") : "null")); } XFree(prop_return); } else { TRACE((".. no property returned\n")); } return (void *) result; } /* * Active icons are supported by fvwm. This feature is not supported by * metacity (gnome) or kwin (kde). Both metacity and kwin support (in * incompatible ways, e.g., one uses the icon theme as a fallback for window * decorations but the other does not, etc, ...) an icon as part of the window * decoration (usually on the upper-left of the window). * * In either case, xterm's icon will only be shown in the window decorations if * xterm does not use the active icon feature. * * This function (tries to) determine the window manager's name, so that we can * provide a useful automatic default for active icons. It is based on reading * wmctrl, which covers most of EWMH and ICCM. */ static char * getWindowManagerName(XtermWidget xw) { TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; Window *sup_window = NULL; char *result = NULL; TRACE(("getWindowManagerName\n")); #define getWinProp(type, name) \ (Window *)getProperty(dpy, DefaultRootWindow(dpy), type, name) if ((sup_window = getWinProp(XA_WINDOW, "_NET_SUPPORTING_WM_CHECK")) == NULL) { sup_window = getWinProp(XA_CARDINAL, "_WIN_SUPPORTING_WM_CHECK"); } /* * If we found the supporting window, get the property containing the * window manager's name. EWMH defines _NET_WM_NAME, while ICCM defines * WM_CLASS. There is no standard for the names stored there; * conventionally it is mixed case. In practice, the former is more often * set; the latter is not given (or is a lowercased version of the former). */ if (sup_window != NULL) { #define getStringProp(type,name) \ (char *)getProperty(dpy, *sup_window, type, name) if ((result = getStringProp(XA_UTF8_STRING(dpy), "_NET_WM_NAME")) == NULL && (result = getStringProp(XA_STRING, "_NET_WM_NAME")) == NULL && (result = getStringProp(XA_STRING, "WM_CLASS")) == NULL) { TRACE(("... window manager does not tell its name\n")); } free(sup_window); } else { TRACE(("... Cannot get window manager info properties\n")); } if (result == NULL) result = x_strdup("unknown"); TRACE(("... window manager name is %s\n", result)); return result; } static Boolean discount_frame_extents(XtermWidget xw, int *high, int *wide) { TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; Atom atom_supported = CachedInternAtom(dpy, "_NET_FRAME_EXTENTS"); Atom actual_type; int actual_format; long long_offset = 0; long long_length = 128; /* number of items to ask for at a time */ unsigned long nitems; unsigned long bytes_after; unsigned char *args; Boolean rc; rc = xtermGetWinProp(dpy, VShellWindow(xw), atom_supported, long_offset, long_length, XA_CARDINAL, /* req_type */ &actual_type, /* actual_type_return */ &actual_format, /* actual_format_return */ &nitems, /* nitems_return */ &bytes_after, /* bytes_after_return */ &args /* prop_return */ ); if (rc && args && (nitems == 4) && (actual_format == 32)) { long *extents = (long *) (void *) args; TRACE(("_NET_FRAME_EXTENTS:\n")); TRACE((" left: %ld\n", extents[0])); TRACE((" right: %ld\n", extents[1])); TRACE((" top: %ld\n", extents[2])); TRACE((" bottom: %ld\n", extents[3])); if (!x_strncasecmp(xw->work.wm_name, "gnome shell", 11)) { *wide -= (int) (extents[0] + extents[1]); /* -= (left+right) */ *high -= (int) (extents[2] + extents[3]); /* -= (top+bottom) */ TRACE(("...applied extents %d,%d\n", *high, *wide)); } else if (!x_strncasecmp(xw->work.wm_name, "compiz", 6)) { /* Ubuntu 16.04 is really off-by-one */ *wide -= (int) (extents[0] + extents[1] - 1); *high -= (int) (extents[2] + extents[3] - 1); TRACE(("...applied extents %d,%d\n", *high, *wide)); } else if (!x_strncasecmp(xw->work.wm_name, "fvwm", 4)) { TRACE(("...skipping extents\n")); } else { TRACE(("...ignoring extents\n")); rc = False; } XFree(args); } else { rc = False; } return rc; } #endif /* !NO_ACTIVE_ICON */ void initBorderGC(XtermWidget xw, VTwin *win) { TScreen *screen = TScreenOf(xw); Pixel filler; TRACE(("initBorderGC(%s) core bg %#lx, bd %#lx text fg %#lx, bg %#lx %s\n", (win == &(screen->fullVwin)) ? "full" : "icon", xw->core.background_pixel, xw->core.border_pixel, T_COLOR(screen, TEXT_FG), T_COLOR(screen, TEXT_BG), xw->misc.re_verse ? "reverse" : "normal")); if (xw->misc.color_inner_border && (xw->core.background_pixel != xw->core.border_pixel)) { /* * By default, try to match the inner window's background. */ if ((xw->core.background_pixel == T_COLOR(screen, TEXT_BG)) && (xw->core.border_pixel == T_COLOR(screen, TEXT_FG))) { filler = T_COLOR(screen, TEXT_BG); } else { filler = xw->core.border_pixel; } TRACE((" border %#lx\n", filler)); setCgsFore(xw, win, gcBorder, filler); setCgsBack(xw, win, gcBorder, filler); win->border_gc = getCgsGC(xw, win, gcBorder); } #if USE_DOUBLE_BUFFER else if (resource.buffered) { filler = T_COLOR(screen, TEXT_BG); TRACE((" border %#lx (buffered)\n", filler)); setCgsFore(xw, win, gcBorder, filler); setCgsBack(xw, win, gcBorder, filler); win->border_gc = getCgsGC(xw, win, gcBorder); } #endif else { TRACE((" border unused\n")); win->border_gc = NULL; } /* * Initialize a GC for double-buffering, needed for XFillRectangle call * in xtermClear2(). When not double-buffering, the XClearArea call works, * without requiring a separate GC. */ #if USE_DOUBLE_BUFFER if (resource.buffered) { filler = (((xw->flags & BG_COLOR) && (xw->cur_background >= 0)) ? getXtermBG(xw, xw->flags, xw->cur_background) : T_COLOR(screen, TEXT_BG)); TRACE((" filler %#lx %s\n", filler, xw->misc.re_verse ? "reverse" : "normal")); setCgsFore(xw, win, gcFiller, filler); setCgsBack(xw, win, gcFiller, filler); win->filler_gc = getCgsGC(xw, win, gcFiller); } #endif } #if USE_DOUBLE_BUFFER static Boolean allocateDbe(XtermWidget xw, VTwin *target) { TScreen *screen = TScreenOf(xw); Boolean result = False; target->drawable = target->window; if (resource.buffered) { Window win = target->window; Drawable d; int major, minor; if (XdbeQueryExtension(XtDisplay(xw), &major, &minor)) { d = XdbeAllocateBackBufferName(XtDisplay(xw), win, (XdbeSwapAction) XdbeCopied); if (d == None) { fprintf(stderr, "Couldn't allocate a back buffer!\n"); exit(3); } target->drawable = d; screen->needSwap = 1; TRACE(("initialized double-buffering\n")); result = True; } else { resource.buffered = False; } } return result; } #endif /* USE_DOUBLE_BUFFER */ /*ARGSUSED*/ static void VTRealize(Widget w, XtValueMask * valuemask, XSetWindowAttributes * values) { XtermWidget xw = (XtermWidget) w; TScreen *screen = TScreenOf(xw); const VTFontNames *myfont; struct Xinerama_geometry pos; int pr; Atom pid_atom; int i; TRACE(("VTRealize " TRACE_L "\n")); TabReset(xw->tabs); if (screen->menu_font_number == fontMenu_default) { myfont = defaultVTFontNames(xw); } else { myfont = xtermFontName(screen->MenuFontName(screen->menu_font_number)); } memset(screen->fnts, 0, sizeof(screen->fnts)); if (!xtermLoadFont(xw, myfont, False, screen->menu_font_number)) { if (XmuCompareISOLatin1(myfont->f_n, DEFFONT) != 0) { char *use_font = x_strdup(DEFFONT); xtermWarning("unable to open font \"%s\", trying \"%s\"....\n", myfont->f_n, use_font); (void) xtermLoadFont(xw, xtermFontName(use_font), False, screen->menu_font_number); screen->MenuFontName(screen->menu_font_number) = use_font; } } /* really screwed if we couldn't open default font */ if (!GetNormalFont(screen, fNorm)->fs) { xtermWarning("unable to locate a suitable font\n"); Exit(ERROR_MISC); } #if OPT_WIDE_CHARS if (screen->utf8_mode) { TRACE(("check if this is a wide font, if not try again\n")); if (xtermLoadWideFonts(xw, False)) { SetVTFont(xw, screen->menu_font_number, True, NULL); /* we will not be able to switch to ISO-8859-1 */ if (!screen->mergedVTFonts) { screen->utf8_fonts = uAlways; update_font_utf8_fonts(); } } } #endif xtermSetupPointer(xw, screen->pointer_shape); /* set defaults */ pos.x = 1; pos.y = 1; pos.w = 80; pos.h = 24; TRACE(("parsing geo_metry %s\n", NonNull(xw->misc.geo_metry))); pr = XParseXineramaGeometry(screen->display, xw->misc.geo_metry, &pos); TRACE(("... position %d,%d size %dx%d\n", pos.y, pos.x, pos.h, pos.w)); set_max_col(screen, (int) (pos.w - 1)); /* units in character cells */ set_max_row(screen, (int) (pos.h - 1)); /* units in character cells */ xtermUpdateFontInfo(xw, False); pos.w = screen->fullVwin.fullwidth; pos.h = screen->fullVwin.fullheight; TRACE(("... BorderWidth: widget %d parent %d shell %d\n", BorderWidth(xw), BorderWidth(XtParent(xw)), BorderWidth(SHELL_OF(xw)))); if ((pr & XValue) && (XNegative & pr)) { pos.x = (Position) (pos.x + (pos.scr_w - (int) pos.w - (BorderWidth(XtParent(xw)) * 2))); } if ((pr & YValue) && (YNegative & pr)) { pos.y = (Position) (pos.y + (pos.scr_h - (int) pos.h - (BorderWidth(XtParent(xw)) * 2))); } pos.x = (Position) (pos.x + pos.scr_x); pos.y = (Position) (pos.y + pos.scr_y); /* set up size hints for window manager; min 1 char by 1 char */ getXtermSizeHints(xw); xtermSizeHints(xw, (xw->misc.scrollbar ? (screen->scrollWidget->core.width + BorderWidth(screen->scrollWidget)) : 0)); xw->hints.x = pos.x; xw->hints.y = pos.y; #if OPT_MAXIMIZE /* assure single-increment resize for fullscreen */ if (xw->work.ewmh[0].mode) { xw->hints.width_inc = 1; xw->hints.height_inc = 1; } #endif if ((XValue & pr) || (YValue & pr)) { xw->hints.flags |= USSize | USPosition; xw->hints.flags |= PWinGravity; switch (pr & (XNegative | YNegative)) { case 0: xw->hints.win_gravity = NorthWestGravity; break; case XNegative: xw->hints.win_gravity = NorthEastGravity; break; case YNegative: xw->hints.win_gravity = SouthWestGravity; break; default: xw->hints.win_gravity = SouthEastGravity; break; } } else { /* set a default size, but do *not* set position */ xw->hints.flags |= PSize; } xw->hints.height = xw->hints.base_height + xw->hints.height_inc * MaxRows(screen); xw->hints.width = xw->hints.base_width + xw->hints.width_inc * MaxCols(screen); if ((WidthValue & pr) || (HeightValue & pr)) xw->hints.flags |= USSize; else xw->hints.flags |= PSize; /* * Note that the size-hints are for the shell, while the resize-request * is for the vt100 widget. They are not the same size. */ (void) REQ_RESIZE((Widget) xw, (Dimension) pos.w, (Dimension) pos.h, &xw->core.width, &xw->core.height); /* XXX This is bogus. We are parsing geometries too late. This * is information that the shell widget ought to have before we get * realized, so that it can do the right thing. */ if (xw->hints.flags & USPosition) XMoveWindow(XtDisplay(xw), VShellWindow(xw), xw->hints.x, xw->hints.y); TRACE(("%s@%d -- ", __FILE__, __LINE__)); TRACE_HINTS(&xw->hints); XSetWMNormalHints(XtDisplay(xw), VShellWindow(xw), &xw->hints); TRACE(("%s@%d -- ", __FILE__, __LINE__)); TRACE_WM_HINTS(xw); if ((pid_atom = CachedInternAtom(XtDisplay(xw), "_NET_WM_PID")) != None) { /* XChangeProperty format 32 really is "long" */ unsigned long pid_l = (unsigned long) getpid(); TRACE(("Setting _NET_WM_PID property to %lu\n", pid_l)); XChangeProperty(XtDisplay(xw), VShellWindow(xw), pid_atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &pid_l, 1); } XFlush(XtDisplay(xw)); /* get it out to window manager */ /* use ForgetGravity instead of SouthWestGravity because translating the Expose events for ConfigureNotifys is too hard */ values->bit_gravity = (GravityIsNorthWest(xw) ? NorthWestGravity : ForgetGravity); screen->fullVwin.window = XtWindow(xw) = XCreateWindow(XtDisplay(xw), XtWindow(XtParent(xw)), xw->core.x, xw->core.y, xw->core.width, xw->core.height, BorderWidth(xw), (int) xw->core.depth, InputOutput, (void *) CopyFromParent, *valuemask | CWBitGravity, values); #if USE_DOUBLE_BUFFER if (allocateDbe(xw, &(screen->fullVwin))) { screen->needSwap = 1; TRACE(("initialized full double-buffering\n")); } else { resource.buffered = False; screen->fullVwin.drawable = screen->fullVwin.window; } #endif /* USE_DOUBLE_BUFFER */ screen->event_mask = values->event_mask; #ifndef NO_ACTIVE_ICON /* * Normally, the font-number for icon fonts does not correspond with any of * the menu-selectable fonts. If we cannot load the font given for the * iconFont resource, try with font1 aka "Unreadable". */ screen->icon_fontnum = -1; if (getIconicFont(screen)->fs == NULL) { getIconicFont(screen)->fs = xtermLoadQueryFont(xw, screen->MenuFontName(fontMenu_font1)); ReportIcons(("%susing font1 '%s' as iconFont\n", (getIconicFont(screen)->fs ? "" : "NOT "), screen->MenuFontName(fontMenu_font1))); } #if OPT_RENDERFONT /* * If we still have no result from iconFont resource (perhaps because fonts * are missing) but are using Xft, try to use that instead. We prefer * bitmap fonts in any case, since scaled fonts are usually less readable, * particularly at small sizes. */ if (UsingRenderFont(xw) && getIconicFont(screen)->fs == NULL) { screen->icon_fontnum = fontMenu_default; getIconicFont(screen)->fs = GetNormalFont(screen, fNorm)->fs; /* need for next-if */ ReportIcons(("using TrueType font as iconFont\n")); } #endif xw->work.wm_name = getWindowManagerName(xw); if ((xw->work.active_icon == eiDefault) && getIconicFont(screen)->fs) { ReportIcons(("window manager name is %s\n", xw->work.wm_name)); if (x_strncasecmp(xw->work.wm_name, "fvwm", 4) && x_strncasecmp(xw->work.wm_name, "window maker", 12)) { xw->work.active_icon = eiFalse; TRACE(("... disable active_icon\n")); } } TRACE((".. if active_icon (%d), get its font\n", xw->work.active_icon)); if (xw->work.active_icon && getIconicFont(screen)->fs) { int iconX = 0, iconY = 0; Widget shell = SHELL_OF(xw); VTwin *win = &(screen->iconVwin); int save_fontnum = screen->menu_font_number; ReportIcons(("initializing active-icon %d\n", screen->icon_fontnum)); screen->menu_font_number = screen->icon_fontnum; XtVaGetValues(shell, XtNiconX, &iconX, XtNiconY, &iconY, (XtPointer) 0); xtermComputeFontInfo(xw, &(screen->iconVwin), getIconicFont(screen)->fs, 0); screen->menu_font_number = save_fontnum; /* since only one client is permitted to select for Button * events, we have to let the window manager get 'em... */ values->event_mask &= ~(ButtonPressMask | ButtonReleaseMask); values->border_pixel = xw->misc.icon_border_pixel; screen->iconVwin.window = XCreateWindow(XtDisplay(xw), RootWindowOfScreen(XtScreen(shell)), iconX, iconY, screen->iconVwin.fullwidth, screen->iconVwin.fullheight, xw->misc.icon_border_width, (int) xw->core.depth, InputOutput, (void *) CopyFromParent, *valuemask | CWBitGravity | CWBorderPixel, values); #if USE_DOUBLE_BUFFER if (allocateDbe(xw, &(screen->iconVwin))) { TRACE(("initialized icon double-buffering\n")); } else { resource.buffered = False; screen->iconVwin.drawable = screen->iconVwin.window; screen->fullVwin.drawable = screen->fullVwin.window; } #endif /* USE_DOUBLE_BUFFER */ XtVaSetValues(shell, XtNiconWindow, screen->iconVwin.window, (XtPointer) 0); XtRegisterDrawable(XtDisplay(xw), screen->iconVwin.window, w); setCgsFont(xw, win, gcNorm, getIconicFont(screen)); setCgsFore(xw, win, gcNorm, T_COLOR(screen, TEXT_FG)); setCgsBack(xw, win, gcNorm, T_COLOR(screen, TEXT_BG)); copyCgs(xw, win, gcBold, gcNorm); setCgsFont(xw, win, gcNormReverse, getIconicFont(screen)); setCgsFore(xw, win, gcNormReverse, T_COLOR(screen, TEXT_BG)); setCgsBack(xw, win, gcNormReverse, T_COLOR(screen, TEXT_FG)); copyCgs(xw, win, gcBoldReverse, gcNormReverse); initBorderGC(xw, win); } else { ReportIcons(("disabled active-icon\n")); xw->work.active_icon = eiFalse; } #if OPT_TOOLBAR update_activeicon(); #endif #endif /* NO_ACTIVE_ICON */ #if OPT_INPUT_METHOD VTInitI18N(xw); #endif #if OPT_NUM_LOCK VTInitModifiers(xw); #if OPT_EXTRA_PASTE if (xw->keyboard.extra_translations) { XtOverrideTranslations((Widget) xw, XtParseTranslationTable(xw->keyboard.extra_translations)); } #endif #endif set_cursor_gcs(xw); initBorderGC(xw, &(screen->fullVwin)); /* Reset variables used by ANSI emulation. */ resetCharsets(screen); XDefineCursor(screen->display, VShellWindow(xw), screen->pointer_cursor); set_cur_col(screen, 0); set_cur_row(screen, 0); set_max_col(screen, Width(screen) / screen->fullVwin.f_width - 1); set_max_row(screen, Height(screen) / screen->fullVwin.f_height - 1); resetMarginMode(xw); memset(screen->sc, 0, sizeof(screen->sc)); /* Mark screen buffer as unallocated. We wait until the run loop so that the child process does not fork and exec with all the dynamic memory it will never use. If we were to do it here, the swap space for new process would be huge for huge savelines. */ #if OPT_TEK4014 if (!tekWidget) /* if not called after fork */ #endif { screen->visbuf = NULL; screen->saveBuf_index = NULL; } ResetWrap(screen); screen->scrolls = screen->incopy = 0; xtermSetCursorBox(screen); screen->savedlines = 0; for (i = 0; i < 2; ++i) { screen->whichBuf = !screen->whichBuf; CursorSave(xw); } #ifndef NO_ACTIVE_ICON if (!xw->work.active_icon) #endif xtermLoadIcon(xw, resource.icon_hint); /* * Do this last, since it may change the layout via a resize. */ if (xw->misc.scrollbar) { screen->fullVwin.sb_info.width = 0; ScrollBarOn(xw, False); } xtermSetWinSize(xw); TRACE(("" TRACE_R " VTRealize\n")); } #if OPT_INPUT_METHOD /* limit this feature to recent XFree86 since X11R6.x core dumps */ #if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && defined(X_HAVE_UTF8_STRING) #define USE_XIM_INSTANTIATE_CB static void xim_instantiate_cb(Display *display, XPointer client_data GCC_UNUSED, XPointer call_data GCC_UNUSED) { XtermWidget xw = term; TRACE(("xim_instantiate_cb client=%p, call=%p\n", client_data, call_data)); if (display == XtDisplay(xw)) { VTInitI18N(xw); } } static void xim_destroy_cb(XIM im GCC_UNUSED, XPointer client_data GCC_UNUSED, XPointer call_data GCC_UNUSED) { XtermWidget xw = term; TInput *input = lookupTInput(xw, (Widget) xw); TRACE(("xim_destroy_cb im=%lx, client=%p, call=%p\n", (long) im, client_data, call_data)); if (input) input->xic = NULL; XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL, xim_instantiate_cb, NULL); } #endif /* X11R6+ */ static Boolean xim_create_fs(XtermWidget xw) { XFontStruct **fonts; char **font_name_list; char **missing_charset_list; char *def_string; int missing_charset_count; unsigned i, j; if (xw->work.xim_fs == NULL) { xw->work.xim_fs = XCreateFontSet(XtDisplay(xw), xw->misc.f_x, &missing_charset_list, &missing_charset_count, &def_string); if (xw->work.xim_fs == NULL) { xtermWarning("Preparation of font set " "\"%s\" for XIM failed.\n", xw->misc.f_x); xw->work.xim_fs = XCreateFontSet(XtDisplay(xw), DEFXIMFONT, &missing_charset_list, &missing_charset_count, &def_string); } } if (xw->work.xim_fs == NULL) { xtermWarning("Preparation of default font set " "\"%s\" for XIM failed.\n", DEFXIMFONT); cleanupInputMethod(xw); xw->work.cannot_im = True; } else { (void) XExtentsOfFontSet(xw->work.xim_fs); j = (unsigned) XFontsOfFontSet(xw->work.xim_fs, &fonts, &font_name_list); for (i = 0, xw->work.xim_fs_ascent = 0; i < j; i++) { if (xw->work.xim_fs_ascent < (*fonts)->ascent) xw->work.xim_fs_ascent = (*fonts)->ascent; } } return (Boolean) !(xw->work.cannot_im); } static void xim_create_xic(XtermWidget xw, Widget theInput) { Display *myDisplay = XtDisplay(theInput); Window myWindow = XtWindow(theInput); unsigned i, j; char *p = NULL, *s, *t, *ns, *end, buf[32]; XIMStyles *xim_styles; XIMStyle input_style = 0; Bool found; static struct { const char *name; unsigned long code; } known_style[] = { { "OverTheSpot", (XIMPreeditPosition | XIMStatusNothing) }, { "OffTheSpot", (XIMPreeditArea | XIMStatusArea) }, { "Root", (XIMPreeditNothing | XIMStatusNothing) }, }; TInput *input = lookupTInput(xw, theInput); if (xw->work.cannot_im) { return; } if (input == NULL) { for (i = 0; i < NINPUTWIDGETS; ++i) { if (xw->work.inputs[i].w == NULL) { input = xw->work.inputs + i; input->w = theInput; break; } } } if (input == NULL) { xtermWarning("attempted to add too many input widgets\n"); return; } TRACE(("xim_real_init\n")); if (IsEmpty(xw->misc.input_method)) { if ((p = XSetLocaleModifiers("")) != NULL && *p) { input->xim = XOpenIM(myDisplay, NULL, NULL, NULL); } } else { s = xw->misc.input_method; i = 5 + (unsigned) strlen(s); t = (char *) MyStackAlloc(i, buf); if (t == NULL) { SysError(ERROR_VINIT); } else { for (ns = s; ns && *s;) { while (*s && isspace(CharOf(*s))) s++; if (!*s) break; if ((ns = end = strchr(s, ',')) == NULL) end = s + strlen(s); while ((end != s) && isspace(CharOf(end[-1]))) end--; if (end != s) { strcpy(t, "@im="); strncat(t, s, (size_t) (end - s)); if ((p = XSetLocaleModifiers(t)) != NULL && *p && (input->xim = XOpenIM(myDisplay, NULL, NULL, NULL)) != NULL) { break; } } s = ns + 1; } MyStackFree(t, buf); } } if (input->xim == NULL && (p = XSetLocaleModifiers("@im=none")) != NULL && *p) { input->xim = XOpenIM(myDisplay, NULL, NULL, NULL); } if (!input->xim) { xtermWarning("Failed to open input method\n"); return; } TRACE(("VTInitI18N opened input method:%s\n", NonNull(p))); if (XGetIMValues(input->xim, XNQueryInputStyle, &xim_styles, (void *) 0) || !xim_styles || !xim_styles->count_styles) { xtermWarning("input method doesn't support any style\n"); cleanupInputMethod(xw); xw->work.cannot_im = True; return; } found = False; for (s = xw->misc.preedit_type; s && !found;) { while (*s && isspace(CharOf(*s))) s++; if (!*s) break; if ((ns = end = strchr(s, ',')) != NULL) ns++; else end = s + strlen(s); while ((end != s) && isspace(CharOf(end[-1]))) end--; if (end != s) { /* just in case we have a spurious comma */ TRACE(("looking for style '%.*s'\n", (int) (end - s), s)); for (i = 0; i < XtNumber(known_style); i++) { if ((int) strlen(known_style[i].name) == (end - s) && !strncmp(s, known_style[i].name, (size_t) (end - s))) { input_style = known_style[i].code; for (j = 0; j < xim_styles->count_styles; j++) { if (input_style == xim_styles->supported_styles[j]) { found = True; break; } } if (found) break; } } } s = ns; } XFree(xim_styles); if (!found) { xtermWarning("input method doesn't support my preedit type (%s)\n", xw->misc.preedit_type); cleanupInputMethod(xw); xw->work.cannot_im = True; return; } /* * Check for styles we do not yet support. */ TRACE(("input_style %#lx\n", input_style)); if (input_style == (XIMPreeditArea | XIMStatusArea)) { xtermWarning("This program doesn't support the 'OffTheSpot' preedit type\n"); cleanupInputMethod(xw); xw->work.cannot_im = True; return; } /* * For XIMPreeditPosition (or OverTheSpot), XIM client has to * prepare a font. * The font has to be locale-dependent XFontSet, whereas * XTerm use Unicode font. This leads a problem that the * same font cannot be used for XIM preedit. */ if (input_style != (XIMPreeditNothing | XIMStatusNothing)) { XVaNestedList p_list; XPoint spot = {0, 0}; if (xim_create_fs(xw)) { p_list = XVaCreateNestedList(0, XNSpotLocation, &spot, XNFontSet, xw->work.xim_fs, (void *) 0); input->xic = XCreateIC(input->xim, XNInputStyle, input_style, XNClientWindow, myWindow, XNFocusWindow, myWindow, XNPreeditAttributes, p_list, (void *) 0); } } else { input->xic = XCreateIC(input->xim, XNInputStyle, input_style, XNClientWindow, myWindow, XNFocusWindow, myWindow, (void *) 0); } if (!input->xic) { xtermWarning("Failed to create input context\n"); cleanupInputMethod(xw); } #if defined(USE_XIM_INSTANTIATE_CB) else { XIMCallback destroy_cb; destroy_cb.callback = xim_destroy_cb; destroy_cb.client_data = NULL; if (XSetIMValues(input->xim, XNDestroyCallback, &destroy_cb, (void *) 0)) { xtermWarning("Could not set destroy callback to IM\n"); } } #endif return; } static void xim_real_init(XtermWidget xw) { xim_create_xic(xw, (Widget) xw); } static void VTInitI18N(XtermWidget xw) { if (xw->misc.open_im) { xim_real_init(xw); #if defined(USE_XIM_INSTANTIATE_CB) if (lookupTInput(xw, (Widget) xw) == NULL && !xw->work.cannot_im && xw->misc.retry_im-- > 0) { sleep(3); XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL, xim_instantiate_cb, NULL); } #endif } } TInput * lookupTInput(XtermWidget xw, Widget w) { TInput *result = NULL; unsigned n; for (n = 0; n < NINPUTWIDGETS; ++n) { if (xw->work.inputs[n].w == w) { result = xw->work.inputs + n; break; } } return result; } #endif /* OPT_INPUT_METHOD */ static void set_cursor_outline_gc(XtermWidget xw, Bool filled, Pixel fg, Pixel bg, Pixel cc) { TScreen *screen = TScreenOf(xw); VTwin *win = WhichVWin(screen); CgsEnum cgsId = gcVTcursOutline; if (cc == bg) cc = fg; if (filled) { setCgsFore(xw, win, cgsId, bg); setCgsBack(xw, win, cgsId, cc); } else { setCgsFore(xw, win, cgsId, cc); setCgsBack(xw, win, cgsId, bg); } } static Boolean VTSetValues(Widget cur, Widget request GCC_UNUSED, Widget wnew, ArgList args GCC_UNUSED, Cardinal *num_args GCC_UNUSED) { XtermWidget curvt = (XtermWidget) cur; XtermWidget newvt = (XtermWidget) wnew; Boolean refresh_needed = False; Boolean fonts_redone = False; if ((T_COLOR(TScreenOf(curvt), TEXT_BG) != T_COLOR(TScreenOf(newvt), TEXT_BG)) || (T_COLOR(TScreenOf(curvt), TEXT_FG) != T_COLOR(TScreenOf(newvt), TEXT_FG)) || (TScreenOf(curvt)->MenuFontName(TScreenOf(curvt)->menu_font_number) != TScreenOf(newvt)->MenuFontName(TScreenOf(newvt)->menu_font_number)) || strcmp(NonNull(DefaultFontN(curvt)), NonNull(DefaultFontN(newvt)))) { if (strcmp(NonNull(DefaultFontN(curvt)), NonNull(DefaultFontN(newvt)))) { TScreenOf(newvt)->MenuFontName(fontMenu_default) = DefaultFontN(newvt); } if (xtermLoadFont(newvt, xtermFontName(TScreenOf(newvt)->MenuFontName(TScreenOf(curvt)->menu_font_number)), True, TScreenOf(newvt)->menu_font_number)) { /* resizing does the redisplay, so don't ask for it here */ refresh_needed = True; fonts_redone = True; } else if (strcmp(NonNull(DefaultFontN(curvt)), NonNull(DefaultFontN(newvt)))) { TScreenOf(newvt)->MenuFontName(fontMenu_default) = DefaultFontN(curvt); } } if (!fonts_redone && (T_COLOR(TScreenOf(curvt), TEXT_CURSOR) != T_COLOR(TScreenOf(newvt), TEXT_CURSOR))) { if (set_cursor_gcs(newvt)) refresh_needed = True; } if (curvt->misc.re_verse != newvt->misc.re_verse) { newvt->flags ^= REVERSE_VIDEO; ReverseVideo(newvt); /* ReverseVideo toggles */ newvt->misc.re_verse = (Boolean) (!newvt->misc.re_verse); refresh_needed = True; } if ((T_COLOR(TScreenOf(curvt), MOUSE_FG) != T_COLOR(TScreenOf(newvt), MOUSE_FG)) || (T_COLOR(TScreenOf(curvt), MOUSE_BG) != T_COLOR(TScreenOf(newvt), MOUSE_BG))) { recolor_cursor(TScreenOf(newvt), TScreenOf(newvt)->pointer_cursor, T_COLOR(TScreenOf(newvt), MOUSE_FG), T_COLOR(TScreenOf(newvt), MOUSE_BG)); refresh_needed = True; } if (curvt->misc.scrollbar != newvt->misc.scrollbar) { ToggleScrollBar(newvt); } return refresh_needed; } /* * Given a font-slot and information about selection/reverse, find the * corresponding cached-GC slot. */ #if OPT_WIDE_ATTRS static int reverseCgs(XtermWidget xw, unsigned attr_flags, Bool hilite, int font) { TScreen *screen = TScreenOf(xw); CgsEnum result = gcMAX; (void) screen; if (ReverseOrHilite(screen, attr_flags, hilite)) { switch (font) { case fNorm: result = gcNormReverse; break; case fBold: result = gcBoldReverse; break; #if OPT_WIDE_ATTRS || OPT_RENDERWIDE case fItal: result = gcNormReverse; /* FIXME */ break; #endif #if OPT_WIDE_CHARS case fWide: result = gcWideReverse; break; case fWBold: result = gcWBoldReverse; break; case fWItal: result = gcWideReverse; /* FIXME */ break; #endif } } else { switch (font) { case fNorm: result = gcNorm; break; case fBold: result = gcBold; break; #if OPT_WIDE_ATTRS || OPT_RENDERWIDE case fItal: result = gcNorm; /* FIXME */ break; #endif #if OPT_WIDE_CHARS case fWide: result = gcWide; break; case fWBold: result = gcWBold; break; case fWItal: result = gcWide; /* FIXME */ break; #endif } } return (int) result; } #endif #define setGC(code) set_at = __LINE__, currentCgs = code #define OutsideSelection(screen,srow,scol) \ ((srow) > (screen)->endH.row || \ ((srow) == (screen)->endH.row && \ (scol) >= (screen)->endH.col) || \ (srow) < (screen)->startH.row || \ ((srow) == (screen)->startH.row && \ (scol) < (screen)->startH.col)) /* * Shows cursor at new cursor position in screen. */ void ShowCursor(XtermWidget xw) { TScreen *screen = TScreenOf(xw); XTermDraw params; IChar base; unsigned flags; CellColor fg_bg = initCColor; GC currentGC; GC outlineGC; CgsEnum currentCgs = gcMAX; VTwin *currentWin = WhichVWin(screen); int set_at; Bool in_selection; Bool reversed; Bool filled; Pixel fg_pix; Pixel bg_pix; Pixel tmp; #if OPT_HIGHLIGHT_COLOR Pixel selbg_pix = T_COLOR(screen, HIGHLIGHT_BG); Pixel selfg_pix = T_COLOR(screen, HIGHLIGHT_FG); Boolean use_selbg; Boolean use_selfg; #endif #if OPT_WIDE_CHARS int my_col = 0; #endif int cursor_col; CLineData *ld = NULL; if (screen->cursor_state == BLINKED_OFF) return; if (screen->eventMode != NORMAL) return; if (INX2ROW(screen, screen->cur_row) > screen->max_row) return; screen->cursorp.row = screen->cur_row; cursor_col = screen->cursorp.col = screen->cur_col; screen->cursor_moved = False; #ifndef NO_ACTIVE_ICON if (IsIcon(screen)) { screen->cursor_state = ON; return; } #endif /* NO_ACTIVE_ICON */ ld = getLineData(screen, screen->cur_row); base = ld->charData[cursor_col]; flags = ld->attribs[cursor_col]; if_OPT_WIDE_CHARS(screen, { if (base == HIDDEN_CHAR && cursor_col > 0) { /* if cursor points to non-initial part of wide character, * back it up */ --cursor_col; base = ld->charData[cursor_col]; } my_col = cursor_col; if (base == 0) base = ' '; if (isWide((int) base)) my_col += 1; }); if (base == 0) { base = ' '; } #if OPT_ISO_COLORS #ifdef EXP_BOGUS_FG /* * If the cursor happens to be on blanks, and we have not set both * foreground and background color, do not treat it as a colored cell. */ if (base == ' ') { if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) { TRACE(("ShowCursor - do not treat as a colored cell\n")); flags &= ~(FG_COLOR | BG_COLOR); } else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) { TRACE(("ShowCursor - should we treat as a colored cell?\n")); if (!(xw->flags & FG_COLOR)) { if (CheckBogusForeground(screen, "ShowCursor")) { flags &= ~(FG_COLOR | BG_COLOR); } } } } #else /* !EXP_BOGUS_FG */ /* * If the cursor happens to be on blanks, and the foreground color is set * but not the background, do not treat it as a colored cell. */ if ((flags & TERM_COLOR_FLAGS(xw)) == FG_COLOR && base == ' ') { flags &= ~TERM_COLOR_FLAGS(xw); } #endif #endif /* * Compare the current cell to the last set of colors used for the * cursor and update the GC's if needed. */ (void) fg_bg; if_OPT_ISO_COLORS(screen, { fg_bg = ld->color[cursor_col]; }); fg_pix = getXtermFG(xw, flags, (int) extract_fg(xw, fg_bg, flags)); bg_pix = getXtermBG(xw, flags, (int) extract_bg(xw, fg_bg, flags)); /* * If we happen to have the same foreground/background colors, choose * a workable foreground color from which we can obtain a visible cursor. */ if (fg_pix == bg_pix) { long bg_diff = (long) (bg_pix - T_COLOR(TScreenOf(xw), TEXT_BG)); long fg_diff = (long) (bg_pix - T_COLOR(TScreenOf(xw), TEXT_FG)); if (bg_diff < 0) bg_diff = -bg_diff; if (fg_diff < 0) fg_diff = -fg_diff; if (bg_diff < fg_diff) { fg_pix = T_COLOR(TScreenOf(xw), TEXT_FG); } else { fg_pix = T_COLOR(TScreenOf(xw), TEXT_BG); } } if (OutsideSelection(screen, screen->cur_row, screen->cur_col)) in_selection = False; else in_selection = True; reversed = ReverseOrHilite(screen, flags, in_selection); /* This is like updatedXtermGC(), except that we have to worry about * whether the window has focus, since in that case we want just an * outline for the cursor. */ filled = (screen->select || screen->always_highlight) && isCursorBlock(screen); #if OPT_HIGHLIGHT_COLOR use_selbg = isNotForeground(xw, fg_pix, bg_pix, selbg_pix); use_selfg = isNotBackground(xw, fg_pix, bg_pix, selfg_pix); #endif if (filled) { if (reversed) { /* text is reverse video */ if (getCgsGC(xw, currentWin, gcVTcursNormal)) { setGC(gcVTcursNormal); } else { if (flags & BOLDATTR(screen)) { setGC(gcBold); } else { setGC(gcNorm); } } EXCHANGE(fg_pix, bg_pix, tmp); #if OPT_HIGHLIGHT_COLOR if (screen->hilite_reverse) { if (use_selbg && !use_selfg) fg_pix = bg_pix; if (use_selfg && !use_selbg) bg_pix = fg_pix; if (use_selbg) bg_pix = selbg_pix; if (use_selfg) fg_pix = selfg_pix; } #endif } else { /* normal video */ if (getCgsGC(xw, currentWin, gcVTcursReverse)) { setGC(gcVTcursReverse); } else { if (flags & BOLDATTR(screen)) { setGC(gcBoldReverse); } else { setGC(gcNormReverse); } } } #define CUR_XX T_COLOR(screen, TEXT_CURSOR) #define CGS_FG getCgsFore(xw, currentWin, getCgsGC(xw, currentWin, currentCgs)) #define CGS_BG getCgsBack(xw, currentWin, getCgsGC(xw, currentWin, currentCgs)) #define FIX_311 (CUR_XX == (reversed ? xw->dft_background : xw->dft_foreground)) #define FIX_328 (CUR_XX == bg_pix) #define FIX_330 (FIX_328 && reversed && in_selection) if (FIX_330 || FIX_311) { setCgsBack(xw, currentWin, currentCgs, fg_pix); } setCgsFore(xw, currentWin, currentCgs, bg_pix); } else { /* not selected */ if (reversed) { /* text is reverse video */ EXCHANGE(fg_pix, bg_pix, tmp); setGC(gcNormReverse); } else { /* normal video */ setGC(gcNorm); } #if OPT_HIGHLIGHT_COLOR if (screen->hilite_reverse) { if (in_selection && !reversed) { /* EMPTY */ /* really INVERSE ... */ ; } else if (in_selection || reversed) { if (use_selbg) { if (use_selfg) { bg_pix = fg_pix; } else { fg_pix = bg_pix; bg_pix = selbg_pix; } } if (use_selfg) { fg_pix = selfg_pix; } } } else { if (in_selection) { if (use_selbg) { bg_pix = selbg_pix; } if (use_selfg) { fg_pix = selfg_pix; } } } #endif setCgsFore(xw, currentWin, currentCgs, fg_pix); setCgsBack(xw, currentWin, currentCgs, bg_pix); } if (screen->cursor_busy == 0 && (screen->cursor_state != ON || screen->cursor_GC != set_at)) { int x, y; screen->cursor_GC = set_at; TRACE(("ShowCursor calling drawXtermText cur(%d,%d) %s-%s, set_at %d\n", screen->cur_row, screen->cur_col, (filled ? "filled" : "outline"), (isCursorBlock(screen) ? "box" : isCursorUnderline(screen) ? "underline" : "bar"), set_at)); currentGC = getCgsGC(xw, currentWin, currentCgs); x = LineCursorX(screen, ld, cursor_col); y = CursorY(screen, screen->cur_row); if (!isCursorBlock(screen)) { /* * Overriding the combination of filled, reversed, in_selection is * too complicated since the underline or bar and the text-cell use * different rules. Just redraw the text-cell, and draw the * underline or bar on top of it. */ HideCursor(xw); /* * Our current-GC is likely to have been modified in HideCursor(). * Set up a new request. */ if (filled) { if (FIX_330 || FIX_311) { setCgsBack(xw, currentWin, currentCgs, fg_pix); } setCgsFore(xw, currentWin, currentCgs, bg_pix); } else { setCgsFore(xw, currentWin, currentCgs, fg_pix); setCgsBack(xw, currentWin, currentCgs, bg_pix); } } /* * Update the outline-gc, to keep the cursor color distinct from the * background color. */ set_cursor_outline_gc(xw, filled, fg_pix, bg_pix, T_COLOR(screen, TEXT_CURSOR)); outlineGC = getCgsGC(xw, currentWin, gcVTcursOutline); if (outlineGC == NULL) outlineGC = currentGC; if (isCursorUnderline(screen)) { /* * Finally, draw the underline. */ screen->box->x = (short) x; screen->box->y = (short) (y + FontHeight(screen) - screen->box[2].y); XFillRectangle(screen->display, VDrawable(screen), outlineGC, screen->box->x, screen->box->y, (unsigned) screen->box[1].x, (unsigned) screen->box[2].y); } else if (isCursorBar(screen)) { /* * Or draw the bar. */ screen->box->x = (short) x; screen->box->y = (short) y; XFillRectangle(screen->display, VDrawable(screen), outlineGC, screen->box->x, screen->box->y, (unsigned) screen->box[1].x, (unsigned) screen->box[2].y); } else { #if OPT_WIDE_ATTRS int italics_on = ((ld->attribs[cursor_col] & ATR_ITALIC) != 0); int italics_off = ((xw->flags & ATR_ITALIC) != 0); int fix_italics = (italics_on != italics_off); int which_font = ((xw->flags & BOLD) ? fBold : fNorm); MyGetFont getter = italics_on ? getItalicFont : getNormalFont; if_OPT_WIDE_CHARS(screen, { if (isWide((int) base)) { which_font = ((xw->flags & BOLD) ? fWBold : fWide); } }); if (fix_italics && UseItalicFont(screen)) { xtermLoadItalics(xw); setCgsFont(xw, currentWin, currentCgs, getter(screen, which_font)); getter = (((xw->flags & ATR_ITALIC) && UseItalicFont(screen)) ? getItalicFont : getNormalFont); } currentGC = getCgsGC(xw, currentWin, currentCgs); #endif /* OPT_WIDE_ATTRS */ /* *INDENT-EQLS* */ params.xw = xw; params.attr_flags = (flags & DRAWX_MASK); params.draw_flags = 0; params.this_chrset = LineCharSet(screen, ld); params.real_chrset = CSET_SWL; params.on_wide = 0; drawXtermText(¶ms, currentGC, x, y, &base, 1); #if OPT_WIDE_CHARS if_OPT_WIDE_CHARS(screen, { size_t off; /* *INDENT-EQLS* */ params.draw_flags = NOBACKGROUND; params.on_wide = isWide((int) base); for_each_combData(off, ld) { if (!(ld->combData[off][my_col])) break; drawXtermText(¶ms, currentGC, x, y, ld->combData[off] + my_col, 1); } }); #endif if (!filled) { screen->box->x = (short) x; screen->box->y = (short) y; XDrawLines(screen->display, VDrawable(screen), outlineGC, screen->box, NBOX, CoordModePrevious); } #if OPT_WIDE_ATTRS if (fix_italics && UseItalicFont(screen)) { setCgsFont(xw, currentWin, currentCgs, getter(screen, which_font)); } #endif } } screen->cursor_state = ON; return; } /* * hide cursor at previous cursor position in screen. */ void HideCursor(XtermWidget xw) { TScreen *screen = TScreenOf(xw); XTermDraw params; GC currentGC; int x, y; IChar base; unsigned flags; CellColor fg_bg = initCColor; Bool in_selection; #if OPT_WIDE_CHARS int my_col = 0; #endif int cursor_col; CLineData *ld = NULL; #if OPT_WIDE_ATTRS int which_Cgs = gcMAX; unsigned attr_flags; int which_font = fNorm; MyGetFont getter = getNormalFont; #endif if (screen->cursor_state == OFF) return; if (INX2ROW(screen, screen->cursorp.row) > screen->max_row) return; cursor_col = screen->cursorp.col; #ifndef NO_ACTIVE_ICON if (IsIcon(screen)) { screen->cursor_state = OFF; return; } #endif /* NO_ACTIVE_ICON */ ld = getLineData(screen, screen->cursorp.row); base = ld->charData[cursor_col]; flags = ld->attribs[cursor_col]; if_OPT_WIDE_CHARS(screen, { if (base == HIDDEN_CHAR && cursor_col > 0) { /* if cursor points to non-initial part of wide character, * back it up */ --cursor_col; base = ld->charData[cursor_col]; } my_col = cursor_col; if (base == 0) base = ' '; if (isWide((int) base)) my_col += 1; }); if (base == 0) { base = ' '; } #ifdef EXP_BOGUS_FG /* * If the cursor happens to be on blanks, and we have not set both * foreground and background color, do not treat it as a colored cell. */ #if OPT_ISO_COLORS if (base == ' ') { if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) { TRACE(("HideCursor - do not treat as a colored cell\n")); flags &= ~(FG_COLOR | BG_COLOR); } else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) { TRACE(("HideCursor - should we treat as a colored cell?\n")); if (!(xw->flags & FG_COLOR)) if (CheckBogusForeground(screen, "HideCursor")) flags &= ~(FG_COLOR | BG_COLOR); } } #endif #endif /* * Compare the current cell to the last set of colors used for the * cursor and update the GC's if needed. */ if_OPT_ISO_COLORS(screen, { fg_bg = ld->color[cursor_col]; }); if (OutsideSelection(screen, screen->cursorp.row, screen->cursorp.col)) in_selection = False; else in_selection = True; #if OPT_WIDE_ATTRS attr_flags = ld->attribs[cursor_col]; if ((attr_flags & ATR_ITALIC) ^ (xw->flags & ATR_ITALIC)) { which_font = ((attr_flags & BOLD) ? fBold : fNorm); if ((attr_flags & ATR_ITALIC) && UseItalicFont(screen)) getter = getItalicFont; if_OPT_WIDE_CHARS(screen, { if (isWide((int) base)) { which_font = ((attr_flags & BOLD) ? fWBold : fWide); } }); which_Cgs = reverseCgs(xw, attr_flags, in_selection, which_font); if (which_Cgs != gcMAX) { setCgsFont(xw, WhichVWin(screen), (CgsEnum) which_Cgs, getter(screen, which_font)); getter = (((xw->flags & ATR_ITALIC) && UseItalicFont(screen)) ? getItalicFont : getNormalFont); } } #endif currentGC = updatedXtermGC(xw, flags, fg_bg, in_selection); TRACE(("HideCursor calling drawXtermText cur(%d,%d)\n", screen->cursorp.row, screen->cursorp.col)); x = LineCursorX(screen, ld, cursor_col); y = CursorY(screen, screen->cursorp.row); /* *INDENT-EQLS* */ params.xw = xw; params.attr_flags = (flags & DRAWX_MASK); params.draw_flags = 0; params.this_chrset = LineCharSet(screen, ld); params.real_chrset = CSET_SWL; params.on_wide = 0; drawXtermText(¶ms, currentGC, x, y, &base, 1); #if OPT_WIDE_CHARS if_OPT_WIDE_CHARS(screen, { size_t off; /* *INDENT-EQLS* */ params.draw_flags = NOBACKGROUND; params.on_wide = isWide((int) base); for_each_combData(off, ld) { if (!(ld->combData[off][my_col])) break; drawXtermText(¶ms, currentGC, x, y, ld->combData[off] + my_col, 1); } }); #endif screen->cursor_state = OFF; #if OPT_WIDE_ATTRS if (which_Cgs != gcMAX) { setCgsFont(xw, WhichVWin(screen), (CgsEnum) which_Cgs, getter(screen, which_font)); } #endif resetXtermGC(xw, flags, in_selection); refresh_displayed_graphics(xw, screen->cursorp.col, screen->cursorp.row, 1, 1); return; } #if OPT_BLINK_CURS || OPT_BLINK_TEXT static void StartBlinking(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->blink_timer == 0) { unsigned long interval = (unsigned long) ((screen->cursor_state == ON) ? screen->blink_on : screen->blink_off); if (interval == 0) /* wow! */ interval = 1; /* let's humor him anyway */ screen->blink_timer = XtAppAddTimeOut(app_con, interval, HandleBlinking, xw); } } static void StopBlinking(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->blink_timer) { XtRemoveTimeOut(screen->blink_timer); screen->blink_timer = 0; reallyStopBlinking(xw); } else { screen->blink_timer = 0; } } #if OPT_BLINK_TEXT Bool LineHasBlinking(TScreen *screen, CLineData *ld) { Bool result = False; if (ld != NULL) { int col; for (col = 0; col < MaxCols(screen); ++col) { if (ld->attribs[col] & BLINK) { result = True; break; } } } return result; } #endif /* * Blink the cursor by alternately showing/hiding cursor. We leave the timer * running all the time (even though that's a little inefficient) to make the * logic simple. */ static void HandleBlinking(XtPointer closure, XtIntervalId * id GCC_UNUSED) { XtermWidget xw = (XtermWidget) closure; TScreen *screen = TScreenOf(xw); Bool resume = False; screen->blink_timer = 0; screen->blink_state = !screen->blink_state; #if OPT_BLINK_CURS if (DoStartBlinking(screen)) { if (screen->cursor_state == ON) { if (screen->select || screen->always_highlight) { HideCursor(xw); if (screen->cursor_state == OFF) screen->cursor_state = BLINKED_OFF; } } else if (screen->cursor_state == BLINKED_OFF) { screen->cursor_state = OFF; ShowCursor(xw); if (screen->cursor_state == OFF) screen->cursor_state = BLINKED_OFF; } resume = True; } #endif #if OPT_BLINK_TEXT /* * Inspect the lines on the current screen to see if any have the BLINK flag * associated with them. Prune off any that have had the corresponding * cells reset. If any are left, repaint those lines with ScrnRefresh(). */ if (!(screen->blink_as_bold)) { int row; int start_row = LastRowNumber(screen); int first_row = start_row; int last_row = -1; for (row = start_row; row >= 0; row--) { LineData *ld = getLineData(screen, ROW2INX(screen, row)); if (ld != NULL && LineTstBlinked(ld)) { if (LineHasBlinking(screen, ld)) { resume = True; if (row > last_row) last_row = row; if (row < first_row) first_row = row; } else { LineClrBlinked(ld); } } } /* * FIXME: this could be a little more efficient, e.g,. by limiting the * columns which are updated. */ if (first_row <= last_row) { ScrnRefresh(xw, first_row, 0, last_row + 1 - first_row, MaxCols(screen), True); } } #endif /* * If either the cursor or text is blinking, restart the timer. */ if (resume) StartBlinking(xw); } #endif /* OPT_BLINK_CURS || OPT_BLINK_TEXT */ void RestartBlinking(XtermWidget xw) { #if OPT_BLINK_CURS || OPT_BLINK_TEXT TScreen *screen = TScreenOf(xw); if (screen->blink_timer == 0) { Bool resume = False; #if OPT_BLINK_CURS if (DoStartBlinking(screen)) { resume = True; } #endif #if OPT_BLINK_TEXT if (!resume) { int row; for (row = screen->max_row; row >= 0; row--) { CLineData *ld = getLineData(screen, ROW2INX(screen, row)); if (ld != NULL && LineTstBlinked(ld)) { if (LineHasBlinking(screen, ld)) { resume = True; break; } } } } #endif if (resume) StartBlinking(xw); } #else (void) xw; #endif } /* * Implement soft or hard (full) reset of the VTxxx emulation. There are a * couple of differences from real DEC VTxxx terminals (to avoid breaking * applications which have come to rely on xterm doing this): * * + autowrap mode should be reset (instead it's reset to the resource * default). * + the popup menu offers a choice of resetting the savedLines, or not. * (but the control sequence does this anyway). */ static void ReallyReset(XtermWidget xw, Bool full, Bool saved) { TScreen *screen = TScreenOf(xw); IFlags saveflags = xw->flags; TRACE(("ReallyReset %s, %s\n", full ? "hard" : "soft", saved ? "clear savedLines" : "keep savedLines")); if (!XtIsRealized((Widget) xw) || (CURRENT_EMU() != (Widget) xw)) { Bell(xw, XkbBI_MinorError, 0); return; } if (saved) { screen->savedlines = 0; ScrollBarDrawThumb(xw, 0); } /* make cursor visible */ screen->cursor_set = ON; InitCursorShape(screen, screen); xtermSetCursorBox(screen); #if OPT_BLINK_CURS screen->cursor_blink_esc = 0; SetCursorBlink(xw, screen->cursor_blink_i); TRACE(("cursor_shape:%d blinks:%d\n", screen->cursor_shape, screen->cursor_blink)); #endif #if OPT_STATUS_LINE if (screen->vtXX_level >= 2) { if (full) handle_DECSSDT(xw, 0); /* DEC STD 070, page 14-10, RIS */ else handle_DECSASD(xw, 0); /* DEC STD 070, page 14-9, DECSTR */ } #endif /* reset scrolling region */ resetMarginMode(xw); bitclr(&xw->flags, ORIGIN); if_OPT_ISO_COLORS(screen, { static char empty[1]; reset_SGR_Colors(xw); if (ResetAnsiColorRequest(xw, empty, 0)) xtermRepaint(xw); }); /* Reset character-sets to initial state */ resetCharsets(screen); UIntClr(xw->keyboard.flags, (MODE_DECCKM | MODE_KAM | MODE_DECKPAM)); if (xw->misc.appcursorDefault) xw->keyboard.flags |= MODE_DECCKM; if (xw->misc.appkeypadDefault) xw->keyboard.flags |= MODE_DECKPAM; #if OPT_MOD_FKEYS /* Reset modifier-resources to initial state */ xw->keyboard.modify_now = xw->keyboard.modify_1st; xw->keyboard.format_now = xw->keyboard.format_1st; xw->keyboard.ignore_now = xw->keyboard.ignore_1st; #endif #if OPT_DEC_RECTOPS screen->checksum_ext = screen->checksum_ext0; #endif /* Reset DECSCA */ bitclr(&xw->flags, PROTECTED); screen->protected_mode = OFF_PROTECT; if (full) { /* RIS */ if (screen->bellOnReset) Bell(xw, XkbBI_TerminalBell, 0); reset_displayed_graphics(screen); /* reset the mouse mode */ screen->send_mouse_pos = MOUSE_OFF; screen->send_focus_pos = OFF; screen->extend_coords = 0; screen->waitingForTrackInfo = False; screen->eventMode = NORMAL; xtermShowPointer(xw, True); TabReset(xw->tabs); xw->keyboard.flags |= MODE_SRM; guard_keyboard_type = False; screen->old_fkeys = screen->old_fkeys0; decode_keyboard_type(xw, &resource); update_keyboard_type(); UIntClr(xw->keyboard.flags, MODE_DECBKM); #if OPT_INITIAL_ERASE if (xw->keyboard.reset_DECBKM == 1) xw->keyboard.flags |= MODE_DECBKM; else if (xw->keyboard.reset_DECBKM == 2) #endif if (screen->backarrow_key) xw->keyboard.flags |= MODE_DECBKM; TRACE(("full reset DECBKM %s\n", BtoS(xw->keyboard.flags & MODE_DECBKM))); #if OPT_SCROLL_LOCK xtermClearLEDs(screen); #endif screen->title_modes = screen->title_modes0; screen->pointer_mode = screen->pointer_mode0; #if OPT_SIXEL_GRAPHICS if (screen->sixel_scrolling) UIntClr(xw->keyboard.flags, MODE_DECSDM); else UIntSet(xw->keyboard.flags, MODE_DECSDM); TRACE(("full reset DECSDM to %s (resource default is %s)\n", BtoS(xw->keyboard.flags & MODE_DECSDM), BtoS(!screen->sixel_scrolling))); #endif #if OPT_GRAPHICS screen->privatecolorregisters = screen->privatecolorregisters0; TRACE(("full reset PRIVATE_COLOR_REGISTERS to %s\n", BtoS(screen->privatecolorregisters))); update_privatecolorregisters(); #endif #if OPT_SIXEL_GRAPHICS screen->sixel_scrolls_right = screen->sixel_scrolls_right0; TRACE(("full reset SIXEL_SCROLLS_RIGHT to %s\n", BtoS(screen->sixel_scrolls_right))); #endif update_appcursor(); update_appkeypad(); update_decbkm(); update_decsdm(); show_8bit_control(False); reset_decudk(xw); FromAlternate(xw, True); ClearScreen(xw); screen->cursor_state = OFF; if (xw->flags & REVERSE_VIDEO) ReverseVideo(xw); ResetItalics(xw); xw->flags = xw->initflags; update_reversevideo(); update_autowrap(); update_reversewrap(); update_autolinefeed(); screen->jumpscroll = (Boolean) (!(xw->flags & SMOOTHSCROLL)); update_jumpscroll(); #if OPT_DEC_RECTOPS screen->cur_decsace = 0; #endif #if OPT_PASTE64 || OPT_READLINE screen->paste_brackets = OFF; #endif #if OPT_READLINE screen->click1_moves = OFF; screen->paste_moves = OFF; screen->dclick3_deletes = OFF; screen->paste_quotes = OFF; screen->paste_literal_nl = OFF; #endif /* OPT_READLINE */ if (screen->c132 && AllowWindowOps(xw, ewColumnMode) && (saveflags & IN132COLUMNS)) { TRACE(("Making resize-request to restore 80-columns %dx%d\n", MaxRows(screen), MaxCols(screen))); RequestResize(xw, MaxRows(screen), 80, True); repairSizeHints(); XSync(screen->display, False); /* synchronize */ if (xtermAppPending()) xevents(xw); } CursorSet(screen, 0, 0, xw->flags); CursorSave(xw); } else { /* DECSTR */ bitcpy(&xw->flags, xw->initflags, WRAPAROUND | REVERSEWRAP | REVERSEWRAP2); bitclr(&xw->flags, INSERT | INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE); ResetItalics(xw); if_OPT_ISO_COLORS(screen, { reset_SGR_Colors(xw); }); update_appcursor(); update_autowrap(); update_reversewrap(); CursorSave(xw); screen->sc[screen->whichBuf].row = screen->sc[screen->whichBuf].col = 0; } } void VTReset(XtermWidget xw, Bool full, Bool saved) { ReallyReset(xw, full, saved); FreeAndNull(myState.string_area); FreeAndNull(myState.print_area); longjmp(vtjmpbuf, 1); /* force ground state in parser */ } typedef enum { ccLO, ccDASH, ccHI, ccCOLON, ccID, ccCOMMA } CCLASS; /* * set_character_class - takes a string of the form * * low[-high][:id][,low[-high][:id][...]] * * and sets the indicated ranges to the indicated values. */ static int set_character_class(char *s) { #define FMT "%s in range string \"%s\" (position %d)\n" TRACE(("set_character_class(%s) " TRACE_L "\n", NonNull(s))); if (IsEmpty(s)) { TRACE((TRACE_R " ERR set_character_class\n")); return -1; } else { CCLASS state = ccLO; int arg[3]; int i; int len = (int) strlen(s); arg[0] = arg[1] = arg[2] = -1; for (i = 0; i < len; ++i) { int ch = CharOf(s[i]); char *t = NULL; long value = 0; if (isspace(ch)) continue; switch (state) { case ccLO: case ccHI: case ccID: if (!isdigit(ch)) { xtermWarning(FMT, "missing number", s, i); TRACE((TRACE_R " ERR set_character_class\n")); return (-1); } value = strtol(s + i, &t, 0); i = (int) (t - s - 1); break; case ccDASH: case ccCOLON: case ccCOMMA: break; } switch (state) { case ccLO: arg[0] = arg[1] = (int) value; arg[2] = -1; state = ccDASH; break; case ccDASH: if (ch == '-') { state = ccHI; } else { goto parse_class; } break; case ccHI: arg[1] = (int) value; state = ccCOLON; break; parse_class: /* FALLTHRU */ case ccCOLON: if (ch == ':') { state = ccID; } else if (ch == ',') { goto apply_class; } else { xtermWarning(FMT, "unexpected character", s, i); TRACE((TRACE_R " ERR set_character_class\n")); return (-1); } break; case ccID: arg[2] = (int) value; state = ccCOMMA; break; apply_class: /* FALLTHRU */ case ccCOMMA: if (SetCharacterClassRange(arg[0], arg[1], arg[2]) != 0) { xtermWarning(FMT, "bad range", s, i); TRACE((TRACE_R " ERR set_character_class\n")); return -1; } state = ccLO; break; } } if (state >= ccDASH) { if (SetCharacterClassRange(arg[0], arg[1], arg[2]) != 0) { xtermWarning(FMT, "bad range", s, i); TRACE((TRACE_R " ERR set_character_class\n")); return -1; } } } TRACE((TRACE_R " OK set_character_class\n")); return (0); #undef FMT } void getKeymapResources(Widget w, const char *mapName, const char *mapClass, const char *type, void *result, size_t size) { XtResource key_resources[1]; key_resources[0].resource_name = XtNtranslations; key_resources[0].resource_class = XtCTranslations; key_resources[0].resource_type = (char *) type; key_resources[0].resource_size = (Cardinal) size; key_resources[0].resource_offset = 0; key_resources[0].default_type = key_resources[0].resource_type; key_resources[0].default_addr = NULL; XtGetSubresources(w, (XtPointer) result, mapName, mapClass, key_resources, (Cardinal) 1, NULL, (Cardinal) 0); } /* ARGSUSED */ static void HandleKeymapChange(Widget w, XEvent *event GCC_UNUSED, String *params, Cardinal *param_count) { static XtTranslations keymap, original; TRACE(("HandleKeymapChange(%#lx, %s)\n", (unsigned long) w, (*param_count ? params[0] : "missing"))); if (*param_count != 1) return; if (original == NULL) { TRACE(("...saving original keymap-translations\n")); original = w->core.tm.translations; } if (strcmp(params[0], "None") == 0) { TRACE(("...restoring original keymap-translations\n")); XtOverrideTranslations(w, original); } else { char mapName[1000]; char mapClass[1000]; char *pmapName; char *pmapClass; size_t len; len = strlen(params[0]) + 7; pmapName = (char *) MyStackAlloc(len, mapName); pmapClass = (char *) MyStackAlloc(len, mapClass); if (pmapName == NULL || pmapClass == NULL) { SysError(ERROR_KMMALLOC1); } else { (void) sprintf(pmapName, "%sKeymap", params[0]); (void) strcpy(pmapClass, pmapName); if (islower(CharOf(pmapClass[0]))) pmapClass[0] = x_toupper(pmapClass[0]); getKeymapResources(w, pmapName, pmapClass, XtRTranslationTable, &keymap, sizeof(keymap)); if (keymap != NULL) { TRACE(("...applying keymap \"%s\"\n", pmapName)); XtOverrideTranslations(w, keymap); } else { TRACE(("...found no match for keymap \"%s\"\n", pmapName)); } MyStackFree(pmapName, mapName); MyStackFree(pmapClass, mapClass); } } } /* ARGSUSED */ static void HandleBell(Widget w GCC_UNUSED, XEvent *event GCC_UNUSED, String *params, /* [0] = volume */ Cardinal *param_count) /* 0 or 1 */ { int percent = (*param_count) ? atoi(params[0]) : 0; Bell(term, XkbBI_TerminalBell, percent); } /* ARGSUSED */ static void HandleVisualBell(Widget w GCC_UNUSED, XEvent *event GCC_UNUSED, String *params GCC_UNUSED, Cardinal *param_count GCC_UNUSED) { VisualBell(); } /* ARGSUSED */ static void HandleIgnore(Widget w, XEvent *event, String *params GCC_UNUSED, Cardinal *param_count GCC_UNUSED) { XtermWidget xw; TRACE(("Handle ignore for %p %s\n", (void *) w, visibleEventType(event->type))); if ((xw = getXtermWidget(w)) != NULL) { /* do nothing, but check for funny escape sequences */ switch (event->type) { case ButtonPress: case ButtonRelease: case MotionNotify: (void) SendMousePosition(xw, event); break; } } } /* ARGSUSED */ static void DoSetSelectedFont(Widget w, XtPointer client_data GCC_UNUSED, Atom *selection GCC_UNUSED, Atom *type, XtPointer value, unsigned long *length, int *format) { XtermWidget xw = getXtermWidget(w); if (xw == NULL) { xtermWarning("unexpected widget in DoSetSelectedFont\n"); } else if (*type != XA_STRING || *format != 8) { Bell(xw, XkbBI_MinorError, 0); } else { Boolean failed = False; char *save = TScreenOf(xw)->SelectFontName(); char *val; char *test; unsigned len = (unsigned) *length; unsigned tst; /* * Some versions of X deliver null-terminated selections, some do not. */ for (tst = 0; tst < len; ++tst) { if (((char *) value)[tst] == '\0') { len = tst; break; } } if (len > 0 && (val = TypeMallocN(char, len + 1)) != NULL) { char *used; memcpy(val, value, (size_t) len); val[len] = '\0'; used = x_strtrim(val); TRACE(("DoSetSelectedFont(%s)\n", used)); /* Do some sanity checking to avoid sending a long selection back to the server in an OpenFont that is unlikely to succeed. XLFD allows up to 255 characters and no control characters; we are a little more liberal here. */ if (len < 1000 && used != NULL && !strchr(used, '\n') && (test = x_strdup(used)) != NULL) { TScreenOf(xw)->SelectFontName() = test; if (!xtermLoadFont(xw, xtermFontName(used), True, fontMenu_fontsel)) { failed = True; free(test); TScreenOf(xw)->SelectFontName() = save; } } else { failed = True; } if (failed) { Bell(xw, XkbBI_MinorError, 0); } free(used); free(val); } } } Bool FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe) { TScreen *screen = TScreenOf(xw); static AtomPtr *atoms; static unsigned int atomCount = 0; AtomPtr *pAtom; unsigned a; Atom target; if (!atom_name) atom_name = ((screen->mappedSelect && atomCount) ? screen->mappedSelect[0] : "PRIMARY"); TRACE(("FindFontSelection(%s)\n", atom_name)); for (pAtom = atoms, a = atomCount; a; a--, pAtom++) { if (strcmp(atom_name, XmuNameOfAtom(*pAtom)) == 0) { TRACE(("...found atom %d:%s\n", a + 1, atom_name)); break; } } if (!a) { atoms = TypeXtReallocN(AtomPtr, atoms, atomCount + 1); *(pAtom = &atoms[atomCount]) = XmuMakeAtom(atom_name); ++atomCount; TRACE(("...added atom %d:%s\n", atomCount, atom_name)); } target = XmuInternAtom(XtDisplay(xw), *pAtom); if (justprobe) { screen->SelectFontName() = XGetSelectionOwner(XtDisplay(xw), target) ? _Font_Selected_ : NULL; TRACE(("...selected fontname '%s'\n", NonNull(screen->SelectFontName()))); } else { XtGetSelectionValue((Widget) xw, target, XA_STRING, DoSetSelectedFont, NULL, XtLastTimestampProcessed(XtDisplay(xw))); } return (screen->SelectFontName() != NULL) ? True : False; } Bool set_cursor_gcs(XtermWidget xw) { TScreen *screen = TScreenOf(xw); VTwin *win = WhichVWin(screen); Pixel cc = T_COLOR(screen, TEXT_CURSOR); Pixel fg = T_COLOR(screen, TEXT_FG); Pixel bg = T_COLOR(screen, TEXT_BG); Bool changed = False; /* * Let's see, there are three things that have "color": * * background * text * cursorblock * * And, there are four situations when drawing a cursor, if we decide * that we like have a solid block of cursor color with the letter * that it is highlighting shown in the background color to make it * stand out: * * selected window, normal video - background on cursor * selected window, reverse video - foreground on cursor * unselected window, normal video - foreground on background * unselected window, reverse video - background on foreground * * Since the last two are really just normalGC and reverseGC, we only * need two new GC's. Under monochrome, we get the same effect as * above by setting cursor color to foreground. */ TRACE(("set_cursor_gcs cc=%#lx, fg=%#lx, bg=%#lx\n", cc, fg, bg)); if (win != NULL && (cc != bg)) { Pixel xx = ((fg == cc) ? bg : cc); /* set the fonts to the current one */ setCgsFont(xw, win, gcVTcursNormal, NULL); setCgsFont(xw, win, gcVTcursFilled, NULL); setCgsFont(xw, win, gcVTcursReverse, NULL); setCgsFont(xw, win, gcVTcursOutline, NULL); /* we have a colored cursor */ setCgsFore(xw, win, gcVTcursNormal, fg); setCgsBack(xw, win, gcVTcursNormal, xx); setCgsFore(xw, win, gcVTcursFilled, xx); setCgsBack(xw, win, gcVTcursFilled, fg); if (screen->always_highlight) { /* both GC's use the same color */ setCgsFore(xw, win, gcVTcursReverse, bg); setCgsBack(xw, win, gcVTcursReverse, cc); } else { setCgsFore(xw, win, gcVTcursReverse, bg); setCgsBack(xw, win, gcVTcursReverse, cc); } set_cursor_outline_gc(xw, screen->always_highlight, fg, bg, cc); changed = True; FreeMarkGCs(xw); } if (changed) { TRACE(("...set_cursor_gcs - done\n")); } return changed; } /* * Build up the default translations string, allowing the user to suppress * some of the features. */ void VTInitTranslations(void) { /* *INDENT-OFF* */ static struct { Boolean wanted; const char *name; const char *value; } table[] = { #define DATA(name,value) { False, name, value } DATA("select", "\ Shift Select:select-cursor-start() select-cursor-end(SELECT, CUT_BUFFER0) \n\ Shift Insert:insert-selection(SELECT, CUT_BUFFER0) \n\ " ), #if OPT_MAXIMIZE DATA("fullscreen", "\ Alt Return:fullscreen() \n\ " ), #endif #if OPT_SCROLL_LOCK DATA("scroll-lock", "\ Scroll_Lock:scroll-lock() \n\ " ), #endif #if OPT_SHIFT_FONTS DATA("shift-fonts", "\ Shift~Ctrl KP_Add:larger-vt-font() \n\ Shift Ctrl KP_Add:smaller-vt-font() \n\ Shift KP_Subtract:smaller-vt-font() \n\ " ), #endif DATA("paging", "\ Shift Prior:scroll-back(1,halfpage) \n\ Shift Next:scroll-forw(1,halfpage) \n\ " ), /* This must be the last set mentioning "KeyPress" */ DATA("keypress", "\ ~Meta :insert-seven-bit() \n\ Meta :insert-eight-bit() \n\ " ), DATA("popup-menu", "\ !Ctrl :popup-menu(mainMenu) \n\ !Lock Ctrl :popup-menu(mainMenu) \n\ !Lock Ctrl @Num_Lock :popup-menu(mainMenu) \n\ ! @Num_Lock Ctrl :popup-menu(mainMenu) \n\ !Ctrl :popup-menu(vtMenu) \n\ !Lock Ctrl :popup-menu(vtMenu) \n\ !Lock Ctrl @Num_Lock :popup-menu(vtMenu) \n\ ! @Num_Lock Ctrl :popup-menu(vtMenu) \n\ !Ctrl :popup-menu(fontMenu) \n\ !Lock Ctrl :popup-menu(fontMenu) \n\ !Lock Ctrl @Num_Lock :popup-menu(fontMenu) \n\ ! @Num_Lock Ctrl :popup-menu(fontMenu) \n\ " ), /* PROCURA added "Meta :clear-saved-lines()" */ DATA("reset", "\ Meta :clear-saved-lines() \n\ " ), DATA("select", "\ ~Meta :select-start() \n\ ~Meta :select-extend() \n\ ~Ctrl ~Meta :ignore() \n\ ~Ctrl ~Meta :insert-selection(SELECT, CUT_BUFFER0) \n\ ~Ctrl ~Meta :start-extend() \n\ ~Meta :select-extend() \n\ :select-end(SELECT, CUT_BUFFER0) \n\ " ), #if OPT_BLOCK_SELECT DATA("block-select", "\ Meta :select-start(block) \n\ " ), #endif DATA("wheel-mouse", "\ Ctrl :scroll-back(1,halfpage,m) \n\ Lock Ctrl :scroll-back(1,halfpage,m) \n\ Lock @Num_Lock Ctrl :scroll-back(1,halfpage,m) \n\ @Num_Lock Ctrl :scroll-back(1,halfpage,m) \n\ :scroll-back(5,line,m) \n\ Ctrl :scroll-forw(1,halfpage,m) \n\ Lock Ctrl :scroll-forw(1,halfpage,m) \n\ Lock @Num_Lock Ctrl :scroll-forw(1,halfpage,m) \n\ @Num_Lock Ctrl :scroll-forw(1,halfpage,m) \n\ :scroll-forw(5,line,m) \n\ " ), DATA("pointer", "\ :pointer-motion() \n\ :pointer-button() \n\ :pointer-button() \n\ " ), DATA("default", "\ :ignore() \n\ " ) }; #undef DATA /* *INDENT-ON* */ char *result = NULL; int pass; Cardinal item; TRACE(("VTInitTranslations\n")); for (item = 0; item < XtNumber(table); ++item) { table[item].wanted = True; } #if OPT_MAXIMIZE /* * As a special case, allow for disabling the alt-enter translation if * the resource settings prevent fullscreen from being used. We would * do the same for scroll-lock and shift-fonts if they were application * resources too, rather than in the widget. */ if (resource.fullscreen == esNever) { for (item = 0; item < XtNumber(table); ++item) { if (!strcmp(table[item].name, "fullscreen")) { table[item].wanted = False; TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value)); } } } #endif if (!IsEmpty(resource.omitTranslation)) { char *value; const char *source = resource.omitTranslation; while (*source != '\0' && (value = ParseList(&source)) != NULL) { size_t len = strlen(value); TRACE(("parsed:%s\n", value)); for (item = 0; item < XtNumber(table); ++item) { if (strlen(table[item].name) >= len && x_strncasecmp(table[item].name, value, (unsigned) len) == 0) { table[item].wanted = False; TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value)); /* continue: "select", for instance is two chunks */ } } free(value); } } for (pass = 0; pass < 2; ++pass) { size_t needed = 0; for (item = 0; item < XtNumber(table); ++item) { if (table[item].wanted) { if (pass) { strcat(result, table[item].value); } else { needed += strlen(table[item].value) + 1; } } } if (!pass) { result = XtMalloc((Cardinal) needed); *result = '\0'; } } TRACE(("result:\n%s\n", result)); defaultTranslations = result; free((void *) xtermClassRec.core_class.tm_table); xtermClassRec.core_class.tm_table = result; } #ifdef NO_LEAKS void noleaks_charproc(void) { free(v_buffer); } #endif xterm-399/config.guess0000755000000000000000000014306714651355010013570 0ustar rootroot#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2024-07-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still # use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c17 c99 c89 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #if defined(__ANDROID__) LIBC=android #else #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #elif defined(__LLVM_LIBC__) LIBC=llvm #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) GUESS="$UNAME_MACHINE-pc-managarm-mlibc" ;; *:[Mm]anagarm:*:*) GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __ARM_EABI__ #ifdef __ARM_PCS_VFP ABI=eabihf #else ABI=eabi #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; esac fi GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; kvx:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; kvx:cos:*:*) GUESS=$UNAME_MACHINE-unknown-cos ;; kvx:mbr:*:*) GUESS=$UNAME_MACHINE-unknown-mbr ;; loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __i386__ ABI=x86 #else #ifdef __ILP32__ ABI=x32 #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in x86) CPU=i686 ;; x32) LIBCABI=${LIBC}x32 ;; esac fi GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; ppc:Haiku:*:*) # Haiku running on Apple PowerPC GUESS=powerpc-apple-haiku ;; *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) GUESS=$UNAME_MACHINE-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; *:Ironclad:*:*) GUESS=$UNAME_MACHINE-unknown-ironclad ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif int main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: xterm-399/Tekproc.c0000644000000000000000000015632115012444015013014 0ustar rootroot/* $XTermId: Tekproc.c,v 1.255 2025/05/18 20:50:21 tom Exp $ */ /* * Copyright 2001-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * * Copyright 1988 X Consortium * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of the X Consortium shall not be * used in advertising or otherwise to promote the sale, use or other dealings * in this Software without prior written authorization from the X Consortium. * * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* Tekproc.c */ #define RES_OFFSET(field) XtOffsetOf(TekWidgetRec, field) #include #include #include #include #if OPT_TOOLBAR #if defined(HAVE_LIB_XAW) #include #elif defined(HAVE_LIB_XAW3D) #include #elif defined(HAVE_LIB_XAW3DXFT) #include #elif defined(HAVE_LIB_NEXTAW) #include #elif defined(HAVE_LIB_XAWPLUS) #include #endif #endif /* OPT_TOOLBAR */ #include #include #include #include #include #include #include #include #include #define DefaultGCID(tw) \ XGContextFromGC(DefaultGC(XtDisplay(tw), \ DefaultScreen(XtDisplay(tw)))) /* Tek defines */ #define MY_CLASS "Tek4014" #define MY_NAME "tek4014" #define SOLIDLINE 0 #define DOTTEDLINE 1 #define DOTDASHEDLINE 2 #define SHORTDASHEDLINE 3 #define LONGDASHEDLINE 4 #define EAST 001 #define WEST 002 #define NORTH 004 #define SOUTH 010 #define LINEMASK 07 #define MARGIN1 0 #define MARGIN2 1 #define MAX_PTS 150 #define MAX_VTX 300 #define PENDOWN 1 #define PENUP 0 #define TEKBOTTOMPAD 23 #define TEKDEFHEIGHT 565 #define TEKDEFWIDTH 750 #define TEKHEIGHT 3072 #define TEKHOME ( (TekChar[tekscr->page.fontsize].nlines - 1) \ * TekChar[tekscr->page.fontsize].vsize) #define TEKMINHEIGHT 452 #define TEKMINWIDTH 600 #define TEKTOPPAD 34 #define TEKWIDTH 4096 #define FULL_HEIGHT (TEKHEIGHT + TEKTOPPAD + TEKBOTTOMPAD) #define BottomY(y) (TEKHEIGHT + TEKTOPPAD - (y)) #define BorderOf(tw) (TScreenOf((tw)->vt)->border) #define ScaleOf(tw) TekScale(TekScreenOf(tw)) #define ScaledX(tw,x) (((x) * ScaleOf(tw)) + BorderOf(tw)) #define ScaledY(tw,y) ((BottomY(y) * ScaleOf(tw)) + BorderOf(tw)) #define TekMove(tw,x,y) do { tekscr->cur_X = x; tekscr->cur_Y = y; } while (0) #define input() Tinput(tw) #define unput(c) *Tpushback++ = (Char) c /* *INDENT-OFF* */ static const struct Tek_Char { int hsize; /* in Tek units */ int vsize; /* in Tek units */ int charsperline; int nlines; } TekChar[TEKNUMFONTS] = { {56, 88, 74, 35}, /* large */ {51, 82, 81, 38}, /* #2 */ {34, 53, 121, 58}, /* #3 */ {31, 48, 133, 64}, /* small */ }; /* *INDENT-ON* */ static Cursor GINcursor; static XSegment *line_pt; static int nplot; static TekLink Tek0; static jmp_buf Tekjump; static TekLink *TekRecord; static XSegment *Tline; static const int *curstate = Talptable; static const int *Tparsestate = Talptable; static char defaultTranslations[] = "\ ~Meta: insert-seven-bit() \n\ Meta: insert-eight-bit() \n\ !Ctrl : popup-menu(mainMenu) \n\ !Lock Ctrl : popup-menu(mainMenu) \n\ !Lock Ctrl @Num_Lock : popup-menu(mainMenu) \n\ !Ctrl @Num_Lock : popup-menu(mainMenu) \n\ !Ctrl : popup-menu(tekMenu) \n\ !Lock Ctrl : popup-menu(tekMenu) \n\ !Lock Ctrl @Num_Lock : popup-menu(tekMenu) \n\ !Ctrl @Num_Lock : popup-menu(tekMenu) \n\ Shift ~Meta: gin-press(L) \n\ ~Meta: gin-press(l) \n\ Shift ~Meta: gin-press(M) \n\ ~Meta: gin-press(m) \n\ Shift ~Meta: gin-press(R) \n\ ~Meta: gin-press(r)"; /* *INDENT-OFF* */ static XtActionsRec actionsList[] = { { "string", HandleStringEvent }, { "insert", HandleKeyPressed }, /* alias for insert-seven-bit */ { "insert-seven-bit", HandleKeyPressed }, { "insert-eight-bit", HandleEightBitKeyPressed }, { "gin-press", HandleGINInput }, { "secure", HandleSecure }, { "create-menu", HandleCreateMenu }, { "popup-menu", HandlePopupMenu }, /* menu actions */ { "allow-send-events", HandleAllowSends }, { "set-visual-bell", HandleSetVisualBell }, #ifdef ALLOWLOGGING { "set-logging", HandleLogging }, #endif { "redraw", HandleRedraw }, { "send-signal", HandleSendSignal }, { "quit", HandleQuit }, { "set-scrollbar", HandleScrollbar }, { "set-jumpscroll", HandleJumpscroll }, { "set-reverse-video", HandleReverseVideo }, { "set-autowrap", HandleAutoWrap }, { "set-reversewrap", HandleReverseWrap }, { "set-autolinefeed", HandleAutoLineFeed }, { "set-appcursor", HandleAppCursor }, { "set-appkeypad", HandleAppKeypad }, { "set-scroll-on-key", HandleScrollKey }, { "set-scroll-on-tty-output", HandleScrollTtyOutput }, { "set-allow132", HandleAllow132 }, { "set-cursesemul", HandleCursesEmul }, { "set-marginbell", HandleMarginBell }, { "set-altscreen", HandleAltScreen }, { "soft-reset", HandleSoftReset }, { "hard-reset", HandleHardReset }, { "set-terminal-type", HandleSetTerminalType }, { "set-visibility", HandleVisibility }, { "set-tek-text", HandleSetTekText }, { "tek-page", HandleTekPage }, { "tek-reset", HandleTekReset }, { "tek-copy", HandleTekCopy }, #if OPT_TOOLBAR { "set-toolbar", HandleToolbar }, #endif }; /* *INDENT-ON* */ static Dimension defOne = 1; #define GIN_TERM_NONE_STR "none" #define GIN_TERM_CR_STR "CRonly" #define GIN_TERM_EOT_STR "CR&EOT" #define GIN_TERM_NONE 0 #define GIN_TERM_CR 1 #define GIN_TERM_EOT 2 #define DFT_FONT_SMALL "6x10" static XtResource resources[] = { {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension), XtOffsetOf(CoreRec, core.width), XtRDimension, (caddr_t) & defOne}, {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension), XtOffsetOf(CoreRec, core.height), XtRDimension, (caddr_t) & defOne}, Fres("fontLarge", XtCFont, tek.Tfont[TEK_FONT_LARGE], "9x15"), Fres("font2", XtCFont, tek.Tfont[TEK_FONT_2], "6x13"), Fres("font3", XtCFont, tek.Tfont[TEK_FONT_3], "8x13"), Fres("fontSmall", XtCFont, tek.Tfont[TEK_FONT_SMALL], DFT_FONT_SMALL), Sres(XtNinitialFont, XtCInitialFont, tek.initial_font, "large"), Sres("ginTerminator", "GinTerminator", tek.gin_terminator_str, GIN_TERM_NONE_STR), #if OPT_TOOLBAR Wres(XtNmenuBar, XtCMenuBar, tek.tb_info.menu_bar, 0), Ires(XtNmenuHeight, XtCMenuHeight, tek.tb_info.menu_height, 25), #endif }; static IChar Tinput(TekWidget /* tw */ ); static int getpoint(TekWidget /* tw */ ); static void TCursorBack(TekWidget /* tw */ ); static void TCursorDown(TekWidget /* tw */ ); static void TCursorForward(TekWidget /* tw */ ); static void TCursorUp(TekWidget /* tw */ ); static void TekBackground(TekWidget /* tw */ , TScreen * /* screen */ ); static void TekResize(Widget /* w */ ); static void TekDraw(TekWidget /* tw */ , int /* x */ , int /* y */ ); static void TekEnq(TekWidget /* tw */ , unsigned /* status */ , int /* x */ , int /* y */ ); static void TekFlush(TekWidget /* tw */ ); static void TekInitialize(Widget /* request */ , Widget /* wnew */ , ArgList /* args */ , Cardinal * /* num_args */ ); static void TekPage(TekWidget /* tw */ ); static void TekRealize(Widget /* gw */ , XtValueMask * /* valuemaskp */ , XSetWindowAttributes * /* values */ ); static WidgetClassRec tekClassRec = { { /* core_class fields */ (WidgetClass) & widgetClassRec, /* superclass */ MY_CLASS, /* class_name */ sizeof(TekWidgetRec), /* widget_size */ NULL, /* class_initialize */ NULL, /* class_part_initialize */ False, /* class_inited */ TekInitialize, /* initialize */ NULL, /* initialize_hook */ TekRealize, /* realize */ actionsList, /* actions */ XtNumber(actionsList), /* num_actions */ resources, /* resources */ XtNumber(resources), /* num_resources */ NULLQUARK, /* xrm_class */ True, /* compress_motion */ True, /* compress_exposure */ True, /* compress_enterleave */ False, /* visible_interest */ NULL, /* destroy */ TekResize, /* resize */ TekExpose, /* expose */ NULL, /* set_values */ NULL, /* set_values_hook */ XtInheritSetValuesAlmost, /* set_values_almost */ NULL, /* get_values_hook */ NULL, /* accept_focus */ XtVersion, /* version */ NULL, /* callback_offsets */ defaultTranslations, /* tm_table */ XtInheritQueryGeometry, /* query_geometry */ XtInheritDisplayAccelerator, /* display_accelerator */ NULL /* extension */ } }; WidgetClass tekWidgetClass = (WidgetClass) & tekClassRec; static Bool Tfailed = False; /* * TekInit/TekRun are called after the VT100 widget has been initialized, but * may be before VT100 is realized, depending upon whether Tek4014 is the * first window to be shown. */ int TekInit(void) { Widget form_top, menu_top; Dimension menu_high; if (!Tfailed && tekWidget == NULL) { Cardinal nargs = 0; Arg myArgs[3]; Boolean iconic = 0; TRACE(("TekInit\n")); XtSetArg(myArgs[nargs], XtNiconic, &iconic); ++nargs; XtGetValues(toplevel, myArgs, nargs); nargs = 0; XtSetArg(myArgs[nargs], XtNiconic, iconic); ++nargs; XtSetArg(myArgs[nargs], XtNallowShellResize, True); ++nargs; XtSetArg(myArgs[nargs], XtNinput, True); ++nargs; /* this causes the Initialize method to be called */ tekshellwidget = XtCreatePopupShell("tektronix", topLevelShellWidgetClass, toplevel, myArgs, nargs); SetupMenus(tekshellwidget, &form_top, &menu_top, &menu_high); /* this causes the Realize method to be called */ tekWidget = (TekWidget) XtVaCreateManagedWidget(MY_NAME, tekWidgetClass, form_top, #if OPT_TOOLBAR XtNmenuBar, menu_top, XtNresizable, True, XtNfromVert, menu_top, XtNtop, XawChainTop, XtNleft, XawChainLeft, XtNright, XawChainRight, XtNbottom, XawChainBottom, XtNmenuHeight, menu_high, #endif (XtPointer) 0); TRACE(("created tek4014 widget %p, window %#lx\n", (void *) tekWidget, XtWindow(tekWidget))); #if OPT_TOOLBAR ShowToolbar(resource.toolBar); #endif } return (!Tfailed); } /* * If we haven't allocated the PtyData struct, do so. */ static int TekPtyData(void) { if (Tpushb == NULL && !Tfailed) { if ((Tpushb = TypeMallocN(Char, 10)) == NULL || (Tline = TypeMallocN(XSegment, MAX_VTX)) == NULL) { xtermWarning("Not enough core for Tek mode\n"); free(Tpushb); Tfailed = True; } } return (Tfailed ? 0 : 1); } static void Tekparse(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); TScreen *screen = TScreenOf(tw->vt); int x, y; IChar ch; int nextstate; for (;;) { IChar c = input(); /* * The parsing tables all have 256 entries. If we're supporting * wide characters, we handle them by treating them the same as * printing characters. */ #if OPT_WIDE_CHARS if (c > 255) { nextstate = (Tparsestate == Talptable) ? CASE_PRINT : CASE_IGNORE; } else #endif nextstate = Tparsestate[c]; TRACE(("Tekparse %04X -> %d\n", c, nextstate)); switch (nextstate) { case CASE_REPORT: TRACE(("case: report address\n")); if (tekscr->TekGIN) { TekGINoff(tw); TekEnqMouse(tw, 0); } else { c = 064; /* has hard copy unit */ if (tekscr->margin == MARGIN2) c |= 02; TekEnq(tw, c, tekscr->cur_X, tekscr->cur_Y); } TekRecord->ptr[-1] = ANSI_NAK; /* remove from recording */ Tparsestate = curstate; break; case CASE_VT_MODE: TRACE(("case: special return to vt102 mode\n")); Tparsestate = curstate; TekRecord->ptr[-1] = ANSI_NAK; /* remove from recording */ FlushLog(tw->vt); return; case CASE_SPT_STATE: TRACE(("case: Enter Special Point Plot mode\n")); if (tekscr->TekGIN) TekGINoff(tw); Tparsestate = curstate = Tspttable; break; case CASE_GIN: TRACE(("case: Do Tek GIN mode\n")); tekscr->TekGIN = &TekRecord->ptr[-1]; /* Set cross-hair cursor raster array */ if ((GINcursor = make_colored_cursor(XC_tcross, T_COLOR(screen, MOUSE_FG), T_COLOR(screen, MOUSE_BG))) != 0) { XDefineCursor(XtDisplay(tw), TWindow(tekscr), GINcursor); } Tparsestate = Tbyptable; /* Bypass mode */ break; case CASE_BEL: TRACE(("case: BEL\n")); if (tekscr->TekGIN) TekGINoff(tw); if (!tekRefreshList) Bell(tw->vt, XkbBI_TerminalBell, 0); Tparsestate = curstate; /* clear bypass condition */ break; case CASE_BS: TRACE(("case: BS\n")); if (tekscr->TekGIN) TekGINoff(tw); Tparsestate = curstate; /* clear bypass condition */ TCursorBack(tw); break; case CASE_PT_STATE: TRACE(("case: Enter Tek Point Plot mode\n")); if (tekscr->TekGIN) TekGINoff(tw); Tparsestate = curstate = Tpttable; break; case CASE_PLT_STATE: TRACE(("case: Enter Tek Plot mode\n")); if (tekscr->TekGIN) TekGINoff(tw); Tparsestate = curstate = Tplttable; if ((c = input()) == ANSI_BEL) tekscr->pen = PENDOWN; else { unput(c); tekscr->pen = PENUP; } break; case CASE_TAB: TRACE(("case: HT\n")); if (tekscr->TekGIN) TekGINoff(tw); Tparsestate = curstate; /* clear bypass condition */ TCursorForward(tw); break; case CASE_IPL_STATE: TRACE(("case: Enter Tek Incremental Plot mode\n")); if (tekscr->TekGIN) TekGINoff(tw); Tparsestate = curstate = Tipltable; break; case CASE_ALP_STATE: TRACE(("case: Enter Tek Alpha mode from any other mode\n")); if (tekscr->TekGIN) TekGINoff(tw); /* if in one of graphics states, move alpha cursor */ if (nplot > 0) /* flush line VTbuffer */ TekFlush(tw); Tparsestate = curstate = Talptable; break; case CASE_UP: TRACE(("case: cursor up\n")); if (tekscr->TekGIN) TekGINoff(tw); Tparsestate = curstate; /* clear bypass condition */ TCursorUp(tw); break; case CASE_COPY: TRACE(("case: make copy\n")); if (tekscr->TekGIN) TekGINoff(tw); TekCopy(tw); TekRecord->ptr[-1] = ANSI_NAK; /* remove from recording */ Tparsestate = curstate; /* clear bypass condition */ break; case CASE_PAGE: TRACE(("case: Page Function\n")); if (tekscr->TekGIN) TekGINoff(tw); TekPage(tw); /* clear bypass condition */ break; case CASE_BES_STATE: TRACE(("case: Byp: an escape char\n")); Tparsestate = Tbestable; break; case CASE_BYP_STATE: TRACE(("case: set bypass condition\n")); Tparsestate = Tbyptable; break; case CASE_IGNORE: TRACE(("case: Esc: totally ignore CR, ESC, LF, ~\n")); break; case CASE_ASCII: TRACE(("case: Select ASCII char set\n")); /* ignore for now */ Tparsestate = curstate; break; case CASE_APL: TRACE(("case: Select APL char set\n")); /* ignore for now */ Tparsestate = curstate; break; case CASE_CHAR_SIZE: TRACE(("case: character size selector\n")); TekSetFontSize(tw, False, (int) (c & 03)); Tparsestate = curstate; break; case CASE_BEAM_VEC: TRACE(("case: beam and vector selector\n")); /* only line types */ c = (IChar) (c & LINEMASK); if (c != tekscr->cur.linetype) { if (nplot > 0) TekFlush(tw); if (c <= TEKNUMLINES) tekscr->cur.linetype = c; } Tparsestate = curstate; break; case CASE_CURSTATE: Tparsestate = curstate; break; case CASE_PENUP: TRACE(("case: Ipl: penup\n")); tekscr->pen = PENUP; break; case CASE_PENDOWN: TRACE(("case: Ipl: pendown\n")); tekscr->pen = PENDOWN; break; case CASE_IPL_POINT: TRACE(("case: Ipl: point\n")); x = tekscr->cur_X; y = tekscr->cur_Y; if (c & NORTH) y++; else if (c & SOUTH) y--; if (c & EAST) x++; else if (c & WEST) x--; if (tekscr->pen == PENDOWN) { TekDraw(tw, x, y); } else { TekMove(tw, x, y); } break; case CASE_PLT_VEC: TRACE(("case: Plt: vector\n")); unput(c); if (getpoint(tw)) { if (tekscr->pen == PENDOWN) { TekDraw(tw, tekscr->cur.x, tekscr->cur.y); } else { TekMove(tw, tekscr->cur.x, tekscr->cur.y); } tekscr->pen = PENDOWN; } break; case CASE_PT_POINT: TRACE(("case: Pt: point\n")); unput(c); if (getpoint(tw)) { TekMove(tw, tekscr->cur.x, tekscr->cur.y); TekDraw(tw, tekscr->cur.x, tekscr->cur.y); } break; case CASE_SPT_POINT: TRACE(("case: Spt: point\n")); /* ignore intensity character in c */ if (getpoint(tw)) { TekMove(tw, tekscr->cur.x, tekscr->cur.y); TekDraw(tw, tekscr->cur.x, tekscr->cur.y); } break; case CASE_CR: TRACE(("case: CR\n")); if (tekscr->TekGIN) TekGINoff(tw); if (nplot > 0) /* flush line VTbuffer */ TekFlush(tw); tekscr->cur_X = tekscr->margin == MARGIN1 ? 0 : TEKWIDTH / 2; Tparsestate = curstate = Talptable; break; case CASE_ESC_STATE: TRACE(("case: ESC\n")); Tparsestate = Tesctable; break; case CASE_LF: TRACE(("case: LF\n")); if (tekscr->TekGIN) TekGINoff(tw); TCursorDown(tw); if (!tekRefreshList) do_xevents(tw->vt); break; case CASE_SP: TRACE(("case: SP\n")); TCursorForward(tw); break; case CASE_PRINT: TRACE(("case: printable character\n")); ch = c; x = (int) ScaledX(tw, tekscr->cur_X); y = (int) ScaledY(tw, tekscr->cur_Y); #if OPT_WIDE_CHARS if (screen->wide_chars && (ch > 255)) { XChar2b sbuf; sbuf.byte2 = LO_BYTE(ch); sbuf.byte1 = HI_BYTE(ch); XDrawImageString16(XtDisplay(tw), TWindow(tekscr), tekscr->TnormalGC, x, y, &sbuf, 1); } else #endif { char ch2 = (char) ch; XDrawString(XtDisplay(tw), TWindow(tekscr), tekscr->TnormalGC, x, y, &ch2, 1); } TCursorForward(tw); break; case CASE_OSC: /* FIXME: someone should disentangle the input queues * of this code so that it can be state-driven. */ TRACE(("case: do osc escape\n")); { /* * do_osc() can call TekExpose(), which calls TekRefresh(), * and sends us recurring here - don't do that... */ static int nested; Char buf2[512]; IChar c2; size_t len = 0; while ((c2 = input()) != ANSI_BEL) { if (!isprint(CharOf(c2 & 0x7f)) || len + 2 >= (int) sizeof(buf2)) break; buf2[len++] = (Char) c2; } buf2[len] = 0; if (!nested++) { if (c2 == ANSI_BEL) do_osc(tw->vt, buf2, len, ANSI_BEL); } --nested; } Tparsestate = curstate; break; } } } static int rcnt; static char *rptr; static PtySelect Tselect_mask; static IChar Tinput(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); TScreen *screen = TScreenOf(tw->vt); TekLink *tek; if (Tpushback > Tpushb) return (*--Tpushback); if (tekRefreshList) { if (rcnt-- > 0) return (IChar) (*rptr++); if ((tek = tekRefreshList->next) != NULL) { tekRefreshList = tek; rptr = tek->data; rcnt = tek->count - 1; TekSetFontSize(tw, False, tek->fontsize); return (IChar) (*rptr++); } tekRefreshList = (TekLink *) 0; longjmp(Tekjump, 1); } again: if (VTbuffer->next >= VTbuffer->last) { int update = VTbuffer->update; if (nplot > 0) /* flush line */ TekFlush(tw); XFD_COPYSET(&pty_mask, &Tselect_mask); for (;;) { #ifdef CRAY struct timeval crocktimeout; crocktimeout.tv_sec = 0; crocktimeout.tv_usec = 0; (void) Select(max_plus1, &Tselect_mask, NULL, NULL, &crocktimeout); #endif if (readPtyData(tw->vt, &Tselect_mask, VTbuffer)) { break; } if (Ttoggled && curstate == Talptable) { TCursorToggle(tw, TOGGLE); Ttoggled = False; } if (xtermAppPending() & XtIMXEvent) { XFD_COPYSET(&X_mask, &Tselect_mask); } else { XFlush(XtDisplay(tw)); XFD_COPYSET(&Select_mask, &Tselect_mask); if (Select(max_plus1, &Tselect_mask, NULL, NULL, NULL) < 0) { if (errno != EINTR) SysError(ERROR_TSELECT); continue; } } if (FD_ISSET(ConnectionNumber(XtDisplay(tw)), &Tselect_mask)) { xevents(tw->vt); if (VTbuffer->update != update) goto again; } } if (!Ttoggled && curstate == Talptable) { TCursorToggle(tw, TOGGLE); Ttoggled = True; } } tek = TekRecord; if (tek->count >= TEK_LINK_BLOCK_SIZE || tek->fontsize != tekscr->cur.fontsize) { if ((TekRecord = tek->next = CastMalloc(TekLink)) == NULL) { Panic("Tinput: malloc error (%d)\n", errno); } else { tek = tek->next; tek->next = (TekLink *) 0; tek->fontsize = (unsigned short) tekscr->cur.fontsize; tek->count = 0; tek->ptr = tek->data; } } tek->count++; (void) morePtyData(screen, VTbuffer); return (IChar) (*tek->ptr++ = (char) nextPtyData(screen, VTbuffer)); } static void TekClear(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); TRACE(("TekClear\n")); nplot = 0; line_pt = Tline; if (TWindow(tekscr)) XClearWindow(XtDisplay(tw), TWindow(tekscr)); } void TekSetWinSize(TekWidget tw) { if (TEK4014_ACTIVE(tw->vt)) { TekScreen *tekscr = TekScreenOf(tw); const struct Tek_Char *t = &TekChar[tekscr->cur.fontsize]; int rows = THeight(tekscr) / (int) (ScaleOf(tw) * t->vsize); int cols = TWidth(tekscr) / (int) (ScaleOf(tw) * t->hsize); update_winsize(TScreenOf(tw->vt), rows, cols, TFullHeight(tekscr), TFullWidth(tekscr)); } } static void compute_sizes(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); int border = 2 * BorderOf(tw); double d; #if OPT_TRACE const struct Tek_Char *t = &TekChar[tekscr->cur.fontsize]; const XFontStruct *fs = tw->tek.Tfont[tekscr->cur.fontsize]; #endif /* *INDENT-EQLS* */ TWidth(tekscr) = tw->core.width - border; THeight(tekscr) = tw->core.height - border; ScaleOf(tw) = (double) TWidth(tekscr) / TEKWIDTH; if ((d = (double) THeight(tekscr) / FULL_HEIGHT) < ScaleOf(tw)) ScaleOf(tw) = d; TFullWidth(tekscr) = tw->core.width; TFullHeight(tekscr) = tw->core.height; TRACE(("%s size %dx%d full %dx%d scale %.2f\n", MY_NAME, THeight(tekscr), TWidth(tekscr), TFullHeight(tekscr), TFullWidth(tekscr), ScaleOf(tw))); /* The tek4014 fonts always look odd since their spacing is overridden to * get the "same" size as a real Tektronix terminal. TrueType fonts for * these small sizes would be no better... */ TRACE(("unscaled font %dx%d\n", t->vsize, t->hsize)); TRACE(("scaled font %.1fx%.1f\n", d * t->vsize, d * t->hsize)); TRACE(("actual font %dx%d\n", fs->max_bounds.ascent + fs->max_bounds.descent, fs->max_bounds.width)); TekSetWinSize(tw); } static void TekResize(Widget w) { TekWidget tw = getTekWidget(w); if (tw != NULL) { TRACE(("TekResize " TRACE_L "\n")); TekClear(tw); compute_sizes(tw); TRACE((TRACE_R " TekResize\n")); } } /*ARGSUSED*/ void TekExpose(Widget w, XEvent *event GCC_UNUSED, Region region GCC_UNUSED) { TekWidget tw = getTekWidget(w); if (tw != NULL) { TekScreen *tekscr = TekScreenOf(tw); TRACE(("TekExpose " TRACE_L "\n")); #ifdef lint region = region; #endif if (!Ttoggled) TCursorToggle(tw, CLEAR); Ttoggled = True; Tpushback = Tpushb; tekscr->cur_X = 0; tekscr->cur_Y = TEKHOME; tekscr->cur = tekscr->page; TekSetFontSize(tw, False, tekscr->cur.fontsize); tekscr->margin = MARGIN1; if (tekscr->TekGIN) { tekscr->TekGIN = NULL; TekGINoff(tw); } tekRefreshList = &Tek0; rptr = tekRefreshList->data; rcnt = tekRefreshList->count; Tparsestate = curstate = Talptable; TRACE(("TekExpose resets data to replay %d bytes\n", rcnt)); first_map_occurred(); if (!tekscr->waitrefresh) TekRefresh(tw); TRACE((TRACE_R " TekExpose\n")); } } void TekRefresh(TekWidget tw) { if (tw != NULL) { TScreen *screen = TScreenOf(tw->vt); TekScreen *tekscr = TekScreenOf(tw); static Cursor wait_cursor = None; if (wait_cursor == None) wait_cursor = make_colored_cursor(XC_watch, T_COLOR(screen, MOUSE_FG), T_COLOR(screen, MOUSE_BG)); XDefineCursor(XtDisplay(tw), TWindow(tekscr), wait_cursor); XFlush(XtDisplay(tw)); if (!setjmp(Tekjump)) Tekparse(tw); XDefineCursor(XtDisplay(tw), TWindow(tekscr), (tekscr->TekGIN && GINcursor) ? GINcursor : tekscr->arrow); } } void TekRepaint(TekWidget tw) { TRACE(("TekRepaint\n")); TekClear(tw); TekExpose((Widget) tw, (XEvent *) NULL, (Region) NULL); } static void TekPage(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); TekLink *tek; TRACE(("TekPage\n")); TekClear(tw); tekscr->cur_X = 0; tekscr->cur_Y = TEKHOME; tekscr->margin = MARGIN1; tekscr->page = tekscr->cur; if (tekscr->TekGIN) TekGINoff(tw); tek = TekRecord = &Tek0; tek->fontsize = (unsigned short) tekscr->cur.fontsize; tek->count = 0; tek->ptr = tek->data; tek = tek->next; if (tek) do { TekLink *tek2 = tek->next; free(tek); tek = tek2; } while (tek); TekRecord->next = (TekLink *) 0; tekRefreshList = (TekLink *) 0; Ttoggled = True; Tparsestate = curstate = Talptable; /* Tek Alpha mode */ } #define EXTRABITS 017 #define FIVEBITS 037 #define HIBITS (FIVEBITS << SHIFTHI) #define LOBITS (FIVEBITS << SHIFTLO) #define SHIFTHI 7 #define SHIFTLO 2 #define TWOBITS 03 static int getpoint(TekWidget tw) { int x, y, e, lo_y = 0; TekScreen *tekscr = TekScreenOf(tw); x = tekscr->cur.x; y = tekscr->cur.y; for (;;) { int c; if ((c = (int) input()) < ' ') { /* control character */ unput(c); return (0); } if (c < '@') { /* Hi X or Hi Y */ if (lo_y) { /* seen a Lo Y, so this must be Hi X */ x &= ~HIBITS; x |= (c & FIVEBITS) << SHIFTHI; continue; } /* else Hi Y */ y &= ~HIBITS; y |= (c & FIVEBITS) << SHIFTHI; continue; } if (c < '`') { /* Lo X */ x &= ~LOBITS; x |= (c & FIVEBITS) << SHIFTLO; tekscr->cur.x = x; tekscr->cur.y = y; return (1); /* OK */ } /* else Lo Y */ if (lo_y) { /* seen a Lo Y, so other must be extra bits */ e = (y >> SHIFTLO) & EXTRABITS; x &= ~TWOBITS; x |= e & TWOBITS; y &= ~TWOBITS; y |= (e >> SHIFTLO) & TWOBITS; } y &= ~LOBITS; y |= (c & FIVEBITS) << SHIFTLO; lo_y++; } } static void TCursorBack(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); const struct Tek_Char *t; int x = (tekscr->cur_X -= (t = &TekChar[tekscr->cur.fontsize])->hsize); if (((tekscr->margin == MARGIN1) && (x < 0)) || ((tekscr->margin == MARGIN2) && (x < TEKWIDTH / 2))) { int l = ((tekscr->cur_Y + (t->vsize - 1)) / t->vsize + 1); if (l >= t->nlines) { tekscr->margin = !tekscr->margin; l = 0; } tekscr->cur_Y = l * t->vsize; tekscr->cur_X = (t->charsperline - 1) * t->hsize; } } static void TCursorForward(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); const struct Tek_Char *t = &TekChar[tekscr->cur.fontsize]; if ((tekscr->cur_X += t->hsize) > TEKWIDTH) { int l = (tekscr->cur_Y / t->vsize - 1); if (l < 0) { tekscr->margin = !tekscr->margin; l = t->nlines - 1; } tekscr->cur_Y = l * t->vsize; tekscr->cur_X = tekscr->margin == MARGIN1 ? 0 : TEKWIDTH / 2; } } static void TCursorUp(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); const struct Tek_Char *t; int l; t = &TekChar[tekscr->cur.fontsize]; if ((l = (tekscr->cur_Y + (t->vsize - 1)) / t->vsize + 1) >= t->nlines) { l = 0; if ((tekscr->margin = !tekscr->margin) != MARGIN1) { if (tekscr->cur_X < TEKWIDTH / 2) tekscr->cur_X += TEKWIDTH / 2; } else if (tekscr->cur_X >= TEKWIDTH / 2) tekscr->cur_X -= TEKWIDTH / 2; } tekscr->cur_Y = l * t->vsize; } static void TCursorDown(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); const struct Tek_Char *t; int l; t = &TekChar[tekscr->cur.fontsize]; if ((l = tekscr->cur_Y / t->vsize - 1) < 0) { l = t->nlines - 1; if ((tekscr->margin = !tekscr->margin) != MARGIN1) { if (tekscr->cur_X < TEKWIDTH / 2) tekscr->cur_X += TEKWIDTH / 2; } else if (tekscr->cur_X >= TEKWIDTH / 2) tekscr->cur_X -= TEKWIDTH / 2; } tekscr->cur_Y = l * t->vsize; } static void AddToDraw(TekWidget tw, int x1, int y1, int x2, int y2) { XSegment *lp; TRACE(("AddToDraw (%d,%d) (%d,%d)\n", x1, y1, x2, y2)); if (nplot >= MAX_PTS) { TekFlush(tw); } lp = line_pt++; lp->x1 = (short) ScaledX(tw, x1); lp->y1 = (short) ScaledY(tw, y1); lp->x2 = (short) ScaledX(tw, x2); lp->y2 = (short) ScaledY(tw, y2); nplot++; TRACE(("...AddToDraw %d points\n", nplot)); } static void TekDraw(TekWidget tw, int x, int y) { TekScreen *tekscr = TekScreenOf(tw); if (nplot == 0 || T_lastx != tekscr->cur_X || T_lasty != tekscr->cur_Y) { /* * We flush on each unconnected line segment if the line * type is not solid. This solves a bug in X when drawing * points while the line type is not solid. */ if (nplot > 0 && tekscr->cur.linetype != SOLIDLINE) TekFlush(tw); } AddToDraw(tw, tekscr->cur_X, tekscr->cur_Y, x, y); T_lastx = tekscr->cur_X = x; T_lasty = tekscr->cur_Y = y; } static void TekFlush(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); TRACE(("TekFlush\n")); XDrawSegments(XtDisplay(tw), TWindow(tekscr), ((tekscr->cur.linetype == SOLIDLINE) ? tekscr->TnormalGC : tekscr->linepat[tekscr->cur.linetype - 1]), Tline, nplot); nplot = 0; line_pt = Tline; } void TekGINoff(TekWidget tw) { TekScreen *tekscr = TekScreenOf(tw); TRACE(("TekGINoff\n")); XDefineCursor(XtDisplay(tw), TWindow(tekscr), tekscr->arrow); if (GINcursor) XFreeCursor(XtDisplay(tw), GINcursor); if (tekscr->TekGIN) { *tekscr->TekGIN = ANSI_CAN; /* modify recording */ tekscr->TekGIN = NULL; } } void TekEnqMouse(TekWidget tw, int c) /* character pressed */ { TekScreen *tekscr = TekScreenOf(tw); int mousex, mousey, rootx, rooty; unsigned int mask; /* XQueryPointer */ Window root, subw; TRACE(("TekEnqMouse\n")); XQueryPointer( XtDisplay(tw), TWindow(tekscr), &root, &subw, &rootx, &rooty, &mousex, &mousey, &mask); if ((mousex = (int) ((mousex - BorderOf(tw)) / ScaleOf(tw))) < 0) mousex = 0; else if (mousex >= TEKWIDTH) mousex = TEKWIDTH - 1; if ((mousey = (int) BottomY((mousey - BorderOf(tw)) / ScaleOf(tw))) < 0) mousey = 0; else if (mousey >= TEKHEIGHT) mousey = TEKHEIGHT - 1; TekEnq(tw, (unsigned) c, mousex, mousey); } static void TekEnq(TekWidget tw, unsigned status, int x, int y) { TScreen *screen = TScreenOf(tw->vt); TekScreen *tekscr = TekScreenOf(tw); Char cplot[7]; int len = 5; int adj = (status != 0) ? 0 : 1; TRACE(("TekEnq\n")); cplot[0] = (Char) status; /* Translate x and y to Tektronix code */ cplot[1] = (Char) (040 | ((x >> SHIFTHI) & FIVEBITS)); cplot[2] = (Char) (040 | ((x >> SHIFTLO) & FIVEBITS)); cplot[3] = (Char) (040 | ((y >> SHIFTHI) & FIVEBITS)); cplot[4] = (Char) (040 | ((y >> SHIFTLO) & FIVEBITS)); if (tekscr->gin_terminator != GIN_TERM_NONE) cplot[len++] = '\r'; if (tekscr->gin_terminator == GIN_TERM_EOT) cplot[len++] = '\004'; v_write(screen->respond, cplot + adj, (size_t) (len - adj)); } void TekRun(void) { XtermWidget xw = term; assert(xw != NULL); if (tekWidget == NULL) { TekInit(); } if (tekWidget != NULL) { TRACE(("TekRun ...\n")); if (!TEK4014_SHOWN(xw) && !resource.notMapped) { set_tek_visibility(True); } update_vttekmode(); update_vtshow(); update_tekshow(); set_tekhide_sensitivity(); Tpushback = Tpushb; Ttoggled = True; if (!setjmp(Tekend)) Tekparse(tekWidget); if (!Ttoggled) { TCursorToggle(tekWidget, TOGGLE); Ttoggled = True; } TEK4014_ACTIVE(xw) = False; xtermSetWinSize(xw); } else { TEK4014_ACTIVE(xw) = False; if (VWindow(TScreenOf(xw)) == 0) { Exit(ERROR_TINIT); } } } #define DOTTED_LENGTH 2 #define DOT_DASHED_LENGTH 4 #define SHORT_DASHED_LENGTH 2 #define LONG_DASHED_LENGTH 2 static const int dash_length[TEKNUMLINES] = { DOTTED_LENGTH, DOT_DASHED_LENGTH, SHORT_DASHED_LENGTH, LONG_DASHED_LENGTH, }; static _Xconst char dotted[DOTTED_LENGTH] = {3, 1}; static _Xconst char dot_dashed[DOT_DASHED_LENGTH] = {3, 4, 3, 1}; static _Xconst char short_dashed[SHORT_DASHED_LENGTH] = {4, 4}; static _Xconst char long_dashed[LONG_DASHED_LENGTH] = {4, 7}; static _Xconst char *dashes[TEKNUMLINES] = { dotted, dot_dashed, short_dashed, long_dashed, }; /* * The following functions are called to initialize and realize the tekWidget */ static void TekInitialize(Widget wrequest, Widget new_arg, ArgList args, Cardinal *num_args) { XtermWidget xw = term; TScreen *vtscr = TScreenOf(xw); TekWidget request = (TekWidget) wrequest; TekWidget wnew = (TekWidget) new_arg; Widget tekparent = SHELL_OF(wnew); TekScreen *tekscr = TekScreenOf((TekWidget) wnew); int i; int border; int pr; int winX, winY; unsigned min_width, min_height; unsigned width, height; char Tdefault[32]; (void) args; (void) num_args; TRACE(("TekInitialize " TRACE_L "\n")); memset(tekscr, 0, sizeof(*tekscr)); /* * Eliminate 'term' as global from other functions. */ wnew->vt = xw; border = 2 * BorderOf(wnew); TRACE(("... border*2: %d\n", border)); /* look for focus related events on the shell, because we need * to care about the shell's border being part of our focus. */ XtAddEventHandler(tekparent, EnterWindowMask, False, HandleEnterWindow, (Opaque) 0); XtAddEventHandler(tekparent, LeaveWindowMask, False, HandleLeaveWindow, (Opaque) 0); XtAddEventHandler(tekparent, FocusChangeMask, False, HandleFocusChange, (Opaque) 0); XtAddEventHandler(new_arg, PropertyChangeMask, False, HandleBellPropertyChange, (Opaque) 0); #ifndef NO_ACTIVE_ICON tekscr->whichTwin = &(tekscr->fullTwin); #endif /* NO_ACTIVE_ICON */ init_Sres(tek.initial_font); init_Sres(tek.gin_terminator_str); #if OPT_TOOLBAR init_Ires(tek.tb_info.menu_height); wnew->tek.tb_info.menu_bar = request->tek.tb_info.menu_bar; #endif BorderPixel(wnew) = BorderPixel(xw); tekscr->arrow = make_colored_cursor(XC_left_ptr, T_COLOR(vtscr, MOUSE_FG), T_COLOR(vtscr, MOUSE_BG)); for (i = 0; i < TEKNUMFONTS; i++) { if (!wnew->tek.Tfont[i]) { wnew->tek.Tfont[i] = XQueryFont(XtDisplay(wnew), DefaultGCID(wnew)); } if (wnew->tek.Tfont[i]) { TRACE(("Tfont[%d] %dx%d\n", i, wnew->tek.Tfont[i]->max_bounds.width, wnew->tek.Tfont[i]->ascent + wnew->tek.Tfont[i]->descent)); wnew->tek.tobaseline[i] = wnew->tek.Tfont[i]->ascent; } else { TRACE(("Tfont[%d] disabled\n", i)); SetItemSensitivity(tekMenuEntries[i].widget, False); } } if (xw->misc.T_geometry == NULL) { int def_width, def_height; if (xw->misc.tekSmall) { def_width = TEKMINWIDTH; def_height = TEKMINHEIGHT; } else { def_width = TEKDEFWIDTH; def_height = TEKDEFHEIGHT; } sprintf(Tdefault, "=%dx%d", def_width + border, def_height + border); xw->misc.T_geometry = Tdefault; } winX = 1; winY = 1; width = (unsigned) (TEKDEFWIDTH + border); height = (unsigned) (TEKDEFHEIGHT + border); min_width = (unsigned) (TEKMINWIDTH + border); min_height = (unsigned) (TEKMINHEIGHT + border); TRACE(("parsing T_geometry %s\n", NonNull(xw->misc.T_geometry))); if (strlen(xw->misc.T_geometry) <= MAX_U_STRING) { pr = XParseGeometry(xw->misc.T_geometry, &winX, &winY, &width, &height); } else { pr = 0; } /* window-manager hints will do this anyway... */ if (height < min_height) { TRACE(("... override height from %d to %d\n", height, min_height)); height = min_height; } if (width < min_width) { TRACE(("... override width from %d to %d\n", width, min_width)); width = min_width; } TRACE(("... position %d,%d size %dx%d\n", winY, winX, height, width)); if ((pr & XValue) && (pr & XNegative)) { winX += DisplayWidth(XtDisplay(wnew), DefaultScreen(XtDisplay(wnew))) - (int) width - (BorderWidth(SHELL_OF(xw)) * 2); } if ((pr & YValue) && (pr & YNegative)) { winY += DisplayHeight(XtDisplay(wnew), DefaultScreen(XtDisplay(wnew))) - (int) height - (BorderWidth(SHELL_OF(xw)) * 2); } /* set up size hints */ /* *INDENT-EQLS* */ wnew->hints.min_width = (int) min_width; wnew->hints.min_height = (int) min_height; wnew->hints.width_inc = 1; wnew->hints.height_inc = 1; wnew->hints.flags = PMinSize | PResizeInc; wnew->hints.x = winX; wnew->hints.y = winY; if ((XValue & pr) || (YValue & pr)) { wnew->hints.flags |= USSize | USPosition; wnew->hints.flags |= PWinGravity; switch (pr & (XNegative | YNegative)) { case 0: wnew->hints.win_gravity = NorthWestGravity; break; case XNegative: wnew->hints.win_gravity = NorthEastGravity; break; case YNegative: wnew->hints.win_gravity = SouthWestGravity; break; default: wnew->hints.win_gravity = SouthEastGravity; break; } } else { /* set a default size, but do *not* set position */ wnew->hints.flags |= PSize; } wnew->hints.width = (int) width; wnew->hints.height = (int) height; if ((WidthValue & pr) || (HeightValue & pr)) wnew->hints.flags |= USSize; else wnew->hints.flags |= PSize; tekscr->cur.fontsize = TEK_FONT_LARGE; if (wnew->tek.initial_font) { int result = TekGetFontSize(wnew->tek.initial_font); if (result >= 0) tekscr->cur.fontsize = result; } TRACE(("Tek cur.fontsize=%d\n", tekscr->cur.fontsize)); #define TestGIN(s) XmuCompareISOLatin1(wnew->tek.gin_terminator_str, s) if (TestGIN(GIN_TERM_NONE_STR) == 0) tekscr->gin_terminator = GIN_TERM_NONE; else if (TestGIN(GIN_TERM_CR_STR) == 0) tekscr->gin_terminator = GIN_TERM_CR; else if (TestGIN(GIN_TERM_EOT_STR) == 0) tekscr->gin_terminator = GIN_TERM_EOT; else xtermWarning("illegal GIN terminator setting \"%s\"\n", wnew->tek.gin_terminator_str); TRACE(("Tek gin_terminator=%d\n", tekscr->gin_terminator)); TRACE((TRACE_R " TekInitialize\n")); } static void TekRealize(Widget gw, XtValueMask * valuemaskp, XSetWindowAttributes * values) { TekWidget tw = (TekWidget) gw; TekScreen *tekscr = TekScreenOf(tw); TScreen *vtscr = TScreenOf(tw->vt); int i; TekLink *tek; XGCValues gcv; unsigned width, height; unsigned long TEKgcFontMask; TRACE(("TekRealize " TRACE_L "\n")); if (!TekPtyData()) return; /* use values from TekInitialize... */ height = (unsigned) tw->hints.height; width = (unsigned) tw->hints.width; (void) REQ_RESIZE((Widget) tw, (Dimension) width, (Dimension) height, &tw->core.width, &tw->core.height); /* XXX This is bogus. We are parsing geometries too late. This * is information that the shell widget ought to have before we get * realized, so that it can do the right thing. */ if (tw->hints.flags & USPosition) XMoveWindow(XtDisplay(tw), TShellWindow, tw->hints.x, tw->hints.y); XSetWMNormalHints(XtDisplay(tw), TShellWindow, &tw->hints); XFlush(XtDisplay(tw)); /* get it out to window manager */ values->win_gravity = NorthWestGravity; values->background_pixel = T_COLOR(vtscr, TEK_BG); XtWindow(tw) = TWindow(tekscr) = XCreateWindow(XtDisplay(tw), VShellWindow(tw), tw->core.x, tw->core.y, tw->core.width, tw->core.height, BorderWidth(tw), (int) tw->core.depth, InputOutput, (void *) CopyFromParent, ((*valuemaskp) | CWBackPixel | CWWinGravity), values); compute_sizes(tw); gcv.graphics_exposures = True; /* default */ gcv.font = tw->tek.Tfont[tekscr->cur.fontsize]->fid; gcv.foreground = T_COLOR(vtscr, TEK_FG); gcv.background = T_COLOR(vtscr, TEK_BG); /* if font wasn't successfully opened, then gcv.font will contain the Default GC's ID, meaning that we must use the server default font. */ TEKgcFontMask = (unsigned long) ((gcv.font == DefaultGCID(tw)) ? 0 : GCFont); tekscr->TnormalGC = XCreateGC(XtDisplay(tw), TWindow(tekscr), (TEKgcFontMask | GCGraphicsExposures | GCForeground | GCBackground), &gcv); gcv.function = GXinvert; gcv.plane_mask = (T_COLOR(vtscr, TEK_BG) ^ T_COLOR(vtscr, TEK_CURSOR)); gcv.join_style = JoinMiter; /* default */ gcv.line_width = 1; tekscr->TcursorGC = XCreateGC(XtDisplay(tw), TWindow(tekscr), (GCFunction | GCPlaneMask), &gcv); gcv.foreground = T_COLOR(vtscr, TEK_FG); gcv.line_style = LineOnOffDash; gcv.line_width = 0; for (i = 0; i < TEKNUMLINES; i++) { tekscr->linepat[i] = XCreateGC(XtDisplay(tw), TWindow(tekscr), (GCForeground | GCLineStyle), &gcv); XSetDashes(XtDisplay(tw), tekscr->linepat[i], 0, dashes[i], dash_length[i]); } TekBackground(tw, vtscr); tekscr->margin = MARGIN1; /* Margin 1 */ tekscr->TekGIN = NULL; /* GIN off */ XDefineCursor(XtDisplay(tw), TWindow(tekscr), tekscr->arrow); { /* there's gotta be a better way... */ static char empty_string[1]; static Arg args[] = { {XtNtitle, (XtArgVal) NULL}, {XtNiconName, (XtArgVal) NULL}, }; char *icon_name = NULL; char *title = NULL; char *tek_icon_name = NULL; char *tek_title = NULL; args[0].value = (XtArgVal) & icon_name; args[1].value = (XtArgVal) & title; XtGetValues(SHELL_OF(tw), args, 2); if (IsEmpty(title)) { title = empty_string; } if (IsEmpty(icon_name)) { icon_name = empty_string; } TRACE(("TekShell title='%s', iconName='%s'\n", title, icon_name)); tek_icon_name = XtMalloc((Cardinal) strlen(icon_name) + 7); strcpy(tek_icon_name, icon_name); strcat(tek_icon_name, "(Tek)"); tek_title = XtMalloc((Cardinal) strlen(title) + 7); strcpy(tek_title, title); strcat(tek_title, "(Tek)"); args[0].value = (XtArgVal) tek_icon_name; args[1].value = (XtArgVal) tek_title; TRACE(("Tek title='%s', iconName='%s'\n", tek_title, tek_icon_name)); XtSetValues(SHELL_OF(tw), args, 2); XtFree(tek_icon_name); XtFree(tek_title); } /* *INDENT-EQLS* */ tek = TekRecord = &Tek0; tek->next = (TekLink *) 0; tek->fontsize = (unsigned short) tekscr->cur.fontsize; tek->count = 0; tek->ptr = tek->data; Tpushback = Tpushb; tekscr->cur_X = 0; tekscr->cur_Y = TEKHOME; line_pt = Tline; Ttoggled = True; tekscr->page = tekscr->cur; TRACE((TRACE_R " TekRealize\n")); } int TekGetFontSize(const char *param) { int result; if (XmuCompareISOLatin1(param, "l") == 0 || XmuCompareISOLatin1(param, "large") == 0) result = TEK_FONT_LARGE; else if (XmuCompareISOLatin1(param, "2") == 0 || XmuCompareISOLatin1(param, "two") == 0) result = TEK_FONT_2; else if (XmuCompareISOLatin1(param, "3") == 0 || XmuCompareISOLatin1(param, "three") == 0) result = TEK_FONT_3; else if (XmuCompareISOLatin1(param, "s") == 0 || XmuCompareISOLatin1(param, "small") == 0) result = TEK_FONT_SMALL; else result = -1; return result; } void TekSetFontSize(TekWidget tw, Bool fromMenu, int newitem) { if (tw != NULL) { TekScreen *tekscr = TekScreenOf(tw); int oldsize = tekscr->cur.fontsize; int newsize = MI2FS(newitem); Font fid; TRACE(("TekSetFontSize(%d) size %d ->%d\n", newitem, oldsize, newsize)); if (newsize < 0 || newsize >= TEKNUMFONTS) { Bell(tw->vt, XkbBI_MinorError, 0); } else if (oldsize != newsize) { if (!Ttoggled) TCursorToggle(tw, TOGGLE); set_tekfont_menu_item(oldsize, False); tekscr->cur.fontsize = newsize; TekSetWinSize(tw); if (fromMenu) tekscr->page.fontsize = newsize; fid = tw->tek.Tfont[newsize]->fid; if (fid == DefaultGCID(tw)) { /* we didn't succeed in opening a real font for this size. Instead, use server default. */ XCopyGC(XtDisplay(tw), DefaultGC(XtDisplay(tw), DefaultScreen(XtDisplay(tw))), GCFont, tekscr->TnormalGC); } else { XSetFont(XtDisplay(tw), tekscr->TnormalGC, fid); } set_tekfont_menu_item(newsize, True); if (!Ttoggled) TCursorToggle(tw, TOGGLE); if (fromMenu) { /* we'll get an exposure event after changing fontsize, so we * have to clear the screen to avoid painting over the previous * text. */ TekClear(tw); } } } } void ChangeTekColors(TekWidget tw, TScreen *screen, ScrnColors * pNew) { if (tw && screen) { TekScreen *tekscr = TekScreenOf(tw); XGCValues gcv; int i; if (COLOR_DEFINED(pNew, TEK_FG)) { T_COLOR(screen, TEK_FG) = COLOR_VALUE(pNew, TEK_FG); TRACE(("... TEK_FG: %#lx\n", T_COLOR(screen, TEK_FG))); } if (COLOR_DEFINED(pNew, TEK_BG)) { T_COLOR(screen, TEK_BG) = COLOR_VALUE(pNew, TEK_BG); TRACE(("... TEK_BG: %#lx\n", T_COLOR(screen, TEK_BG))); } if (COLOR_DEFINED(pNew, TEK_CURSOR)) { T_COLOR(screen, TEK_CURSOR) = COLOR_VALUE(pNew, TEK_CURSOR); TRACE(("... TEK_CURSOR: %#lx\n", T_COLOR(screen, TEK_CURSOR))); } else { T_COLOR(screen, TEK_CURSOR) = T_COLOR(screen, TEK_FG); TRACE(("... TEK_CURSOR: %#lx\n", T_COLOR(screen, TEK_CURSOR))); } XSetForeground(XtDisplay(tw), tekscr->TnormalGC, T_COLOR(screen, TEK_FG)); XSetBackground(XtDisplay(tw), tekscr->TnormalGC, T_COLOR(screen, TEK_BG)); if (BorderPixel(tw) == T_COLOR(screen, TEK_BG)) { BorderPixel(tw) = T_COLOR(screen, TEK_FG); BorderPixel(XtParent(tw)) = T_COLOR(screen, TEK_FG); if (XtWindow(XtParent(tw))) XSetWindowBorder(XtDisplay(tw), XtWindow(XtParent(tw)), BorderPixel(tw)); } for (i = 0; i < TEKNUMLINES; i++) { XSetForeground(XtDisplay(tw), tekscr->linepat[i], T_COLOR(screen, TEK_FG)); } gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^ T_COLOR(screen, TEK_CURSOR)); XChangeGC(XtDisplay(tw), tekscr->TcursorGC, GCPlaneMask, &gcv); TekBackground(tw, screen); } return; } void TekReverseVideo(XtermWidget xw, TekWidget tw) { if (tw) { TScreen *screen = TScreenOf(xw); TekScreen *tekscr = TekScreenOf(tw); Pixel tmp; XGCValues gcv; int i; EXCHANGE(T_COLOR(screen, TEK_FG), T_COLOR(screen, TEK_BG), tmp); T_COLOR(screen, TEK_CURSOR) = T_COLOR(screen, TEK_FG); XSetForeground(XtDisplay(tw), tekscr->TnormalGC, T_COLOR(screen, TEK_FG)); XSetBackground(XtDisplay(tw), tekscr->TnormalGC, T_COLOR(screen, TEK_BG)); if (BorderPixel(tw) == T_COLOR(screen, TEK_BG)) { BorderPixel(tw) = T_COLOR(screen, TEK_FG); BorderPixel(XtParent(tw)) = T_COLOR(screen, TEK_FG); if (XtWindow(XtParent(tw))) XSetWindowBorder(XtDisplay(tw), XtWindow(XtParent(tw)), BorderPixel(tw)); } for (i = 0; i < TEKNUMLINES; i++) { XSetForeground(XtDisplay(tw), tekscr->linepat[i], T_COLOR(screen, TEK_FG)); } gcv.plane_mask = (T_COLOR(screen, TEK_BG) ^ T_COLOR(screen, TEK_CURSOR)); XChangeGC(XtDisplay(tw), tekscr->TcursorGC, GCPlaneMask, &gcv); TekBackground(tw, screen); } } static void TekBackground(TekWidget tw, TScreen *screen) { TekScreen *tekscr = TekScreenOf(tw); if (TWindow(tekscr)) XSetWindowBackground(XtDisplay(tw), TWindow(tekscr), T_COLOR(screen, TEK_BG)); } /* * Toggles cursor on or off at cursor position in screen. */ void TCursorToggle(TekWidget tw, int toggle) /* TOGGLE or CLEAR */ { TekScreen *tekscr; XtermWidget xw; int c, x, y; unsigned cellwidth, cellheight; if (tw == NULL) return; if ((tekscr = TekScreenOf(tw)) == NULL) return; if ((xw = tw->vt) == NULL) return; if (!TEK4014_SHOWN(xw)) return; TRACE(("TCursorToggle %s\n", (toggle == TOGGLE) ? "toggle" : "clear")); c = tekscr->cur.fontsize; cellwidth = (unsigned) tw->tek.Tfont[c]->max_bounds.width; cellheight = (unsigned) (tw->tek.Tfont[c]->ascent + tw->tek.Tfont[c]->descent); x = (int) ScaledX(tw, tekscr->cur_X); y = (int) ScaledY(tw, tekscr->cur_Y) - tw->tek.tobaseline[c]; if (toggle == TOGGLE) { TScreen *screen = TScreenOf(xw); if (screen->select || screen->always_highlight) XFillRectangle(XtDisplay(tw), TWindow(tekscr), tekscr->TcursorGC, x, y, cellwidth, cellheight); else { /* fix to use different GC! */ XDrawRectangle(XtDisplay(tw), TWindow(tekscr), tekscr->TcursorGC, x, y, cellwidth - 1, cellheight - 1); } } else { /* Clear the entire rectangle, even though we may only * have drawn an outline. This fits with our refresh * scheme of redrawing the entire window on any expose * event and is easier than trying to figure out exactly * which part of the cursor needs to be erased. */ XClearArea(XtDisplay(tw), TWindow(tekscr), x, y, cellwidth, cellheight, False); } } /* * The Tektronix manual describes the PAGE/RESET button. For PAGE: * Erases the display, resets to Alpha Mode and home position; * resets to Margin 1 and cancels Bypass condition. * For the RESET function: * Entered with SHIFT held down; creates a "home" function, * resetting the Terminal to initial status; does not erase. * * The reset done here is different, changing the modes (which changes * the line-type and font to default values) as well as erasing the screen * (like PAGE). */ void TekSimulatePageButton(TekWidget tw, Bool reset) { if (tw != NULL) { TekScreen *tekscr = TekScreenOf(tw); if (reset) { memset(&tekscr->cur, 0, sizeof tekscr->cur); } tekRefreshList = (TekLink *) 0; TekPage(tw); tekscr->cur_X = 0; tekscr->cur_Y = TEKHOME; } } /* write copy of screen to a file */ void TekCopy(TekWidget tw) { #ifdef ALLOWLOGGING if (tw != NULL) { TekScreen *tekscr = TekScreenOf(tw); TScreen *screen = TScreenOf(tw->vt); TekLink *Tp; char buf[TIMESTAMP_LEN + 10]; int tekcopyfd; timestamp_filename(buf, "COPY"); if (access(buf, F_OK) >= 0 && access(buf, W_OK) < 0) { Bell(tw->vt, XkbBI_MinorError, 0); return; } if (access(".", W_OK) < 0) { /* can't write in directory */ Bell(tw->vt, XkbBI_MinorError, 0); return; } tekcopyfd = open_userfile(screen->uid, screen->gid, buf, False); if (tekcopyfd >= 0) { char initbuf[5]; sprintf(initbuf, "%c%c%c%c", ANSI_ESC, (char) (tekscr->page.fontsize + '8'), ANSI_ESC, (char) (tekscr->page.linetype + '`')); IGNORE_RC(write(tekcopyfd, initbuf, (size_t) 4)); Tp = &Tek0; do { IGNORE_RC(write(tekcopyfd, Tp->data, (size_t) Tp->count)); Tp = Tp->next; } while (Tp); close(tekcopyfd); } } #else (void) tw; #endif /* ALLOWLOGGING */ } /*ARGSUSED*/ void HandleGINInput(Widget w, XEvent *event GCC_UNUSED, String *param_list, Cardinal *nparamsp) { TekWidget tw = getTekWidget(w); if (tw != NULL) { TekScreen *tekscr = TekScreenOf(tw); if (tekscr->TekGIN && *nparamsp == 1) { int c = param_list[0][0]; switch (c) { case 'l': case 'm': case 'r': case 'L': case 'M': case 'R': break; default: Bell(tw->vt, XkbBI_MinorError, 0); /* let them know they goofed */ c = 'l'; /* provide a default */ } TekEnqMouse(tw, c | 0x80); TekGINoff(tw); } else { Bell(tw->vt, XkbBI_MinorError, 0); } } } /* * Check if the current widget, or any parent, is the "tek4014" widget. */ TekWidget getTekWidget(Widget w) { TekWidget tw; if (w == NULL) { tw = (TekWidget) CURRENT_EMU(); if (!IsTekWidget(tw)) { tw = NULL; } } else if (IsTekWidget(w)) { tw = (TekWidget) w; } else { tw = getTekWidget(XtParent(w)); } TRACE2(("getTekWidget %p -> %p\n", w, tw)); return tw; } xterm-399/Imakefile0000644000000000000000000002377414764764437013111 0ustar rootrootXCOMM $XTermId: Imakefile,v 1.124 2025/03/14 08:30:23 tom Exp $ XCOMM XCOMM Attention xterm porters XCOMM XCOMM XCOMM Xterm assumes that bcopy can handle overlapping arguments. If your XCOMM bcopy (or memcpy) cannot, write a routine called bcopy and link it in XCOMM or add -Dbcopy=mybcopy to the DEFINES list below. XCOMM /* Uncomment SCROLLBAR_RIGHT if you want the scroll bar to be on the right */ SCROLLBAR_RIGHT = -DSCROLLBAR_RIGHT /* Define UTF8support to compile-in support for UTF-8 */ #define UTF8support /* * setgid mode works for systems that do not require setuid to open pty. * * This feature could also be applied to FreeBSD, but requires the installer * to define a "utmp" group as well as chgrp the utmp file to match. * * Note: InstallXtermSetUID is always defined; InstallXtermSetGID is defined * in newer imake configurations. */ #if !defined(InstallXtermSetGID) && !InstallXtermSetUID #if defined(OpenBSDArchitecture) || \ (defined(LinuxArchitecture) && \ (LinuxCLibMajorVersion == 6)) #define InstallXtermSetGID YES #endif #endif /* * Override the set uid/gid flags to use the utempter library. */ #if defined(UseUtempter) #undef InstallXtermSetUID /* imake sets this */ #undef InstallXtermSetGID /* we set this */ #define InstallXtermSetUID NO #define InstallXtermSetGID NO UTMPLIB = -lutempter #endif /* * Fixes to allow compile with X11R5, etc. */ #ifndef InstGidFlags #define InstGidFlags -m 2755 -g utmp #endif #ifndef InstUidFlags #define InstUidFlags -m 4711 #endif #ifndef XkbClientDefines #define XkbClientDefines /**/ #endif #ifndef InstallXtermSetUID #define InstallXtermSetUID NO #endif #ifndef InstallXtermSetGID #define InstallXtermSetGID NO #endif #ifndef XkbClientDepLibs #define XkbClientDepLibs /**/ #endif #ifndef XkbClientLibs #define XkbClientLibs /**/ #endif /* This must come before setting DEFINES */ #if InstallXtermSetGID CSGIDFLAGS = -DUSE_UTMP_SETGID INSTSETIDFLAGS = InstGidFlags #elif InstallXtermSetUID INSTSETIDFLAGS = InstUidFlags #else INSTSETIDFLAGS = NullParameter #endif /* * Compensate for broken imake configuration. */ #ifdef LinuxGnuSourceDefines # ifdef UseInstalled IMAKEDEFINES = -D_DEFAULT_SOURCE -U_XOPEN_SOURCE -D_XOPEN_SOURCE=600 # endif #endif #ifndef SpecialCObjectRule #define SpecialCObjectRule(module,ignore,defines) \ module.o: ; $(CC) -c defines $(CFLAGS) module.c #endif #ifndef ProgramTargetName #define ProgramTargetName(program) program #endif /* * add -DWTMP and -DLASTLOG if you want them; make sure that bcopy can * handle overlapping copies before using it. */ #if SetTtyGroup /* turn on in config/machine.cf */ TTYGROUPDEF = -DUSE_TTY_GROUP #endif #ifdef UsePUCCPtyd /* turn on in config/site.def */ PUCCPTYDDEF = -DPUCC_PTYD /* does not need to be setuid */ PTYLIB = -lpucc #endif #if defined(NetBSDArchitecture) || \ defined(OpenBSDArchitecture) || \ defined(FreeBSDArchitecture) || \ (defined(LinuxArchitecture) && \ (LinuxCLibMajorVersion == 6) && (LinuxCLibMinorVersion < 1)) PTYLIB = -lutil #endif #ifdef DarwinArchitecture /* dyld can deadlock if a signal comes in when it is looking up a symbol */ LOCAL_LDFLAGS = -Wl,-bind_at_load #endif OSMAJORVERSION = OSMajorVersion OSMINORVERSION = OSMinorVersion /* none of these can be expected to use termcap unless emulated by terminfo */ #if defined(NTOArchitecture) || \ defined(OpenBSDArchitecture) || \ defined(SGIArchitecture) || \ defined(SunArchitecture) || \ defined(NetBSDArchitecture) || \ defined(OpenBSDArchitecture) || \ defined(FreeBSDArchitecture) || \ defined(LinuxArchitecture) TERMCAPDEFINES=-DUSE_TERMINFO -DHAVE_TIGETSTR -DHAVE_TERM_H #endif #if !defined(OS2Architecture) && !defined(__GNU__) && !defined(Minix3Architecture) #if defined(UseUtempter) UTMPDEF = -DUSE_UTEMPTER #else UTMPDEF = -DUTMP #endif #endif #ifdef UTF8support UTF8_OPTION = -DOPT_WIDE_CHARS -DOPT_LUIT_PROG UTF8SRC = charclass.c precompose.c wcwidth.c xutf8.c UTF8OBJ = charclass.o precompose.o wcwidth.o xutf8.o #endif #if BuildXftLibrary #define XRenderSupport #endif #ifdef XRenderSupport XRFDEF = -DXRENDERFONT -DXFREE86_FT2 XRFLIBS = XftClientLibs XRFDEPLIBS = XftClientDepLibs XRFINCLUDES = $(XFTINCLUDES) #endif #if !HasPutenv PUTENVDEF = -DNOPUTENV #endif #ifdef RegisXTerm SIXELDEF = -DOPT_REGIS_GRAPHICS=1 #endif #ifdef SixelXTerm SIXELDEF = -DOPT_SIXEL_GRAPHICS=1 #endif #ifdef TraceXTerm TRACEDEF = -DOPT_TRACE=1 #endif MAIN_DEFINES = $(UTMPDEF) $(TTYGROUPDEF) $(PUCCPTYDDEF) $(CSGIDFLAGS) \ -DOSMAJORVERSION=$(OSMAJORVERSION) \ -DOSMINORVERSION=$(OSMINORVERSION) MISC_DEFINES = /* -DALLOWLOGGING -DALLOWLOGFILEEXEC */ XKB_DEFINES = XkbClientDefines PATH_DEFINES = -DPROJECTROOT=$(PROJECTROOT) DEFINES = $(XKB_DEFINES) $(TERMCAPDEFINES) $(FEATURE_DEFINES) $(SCROLLBAR_RIGHT) $(UTF8_OPTION) $(XRFDEF) $(PATH_DEFINES) $(PUTENVDEF) $(IMAKEDEFINES) $(SIXELDEF) $(TRACEDEF) INCLUDES = -I. $(XRFINCLUDES) MAINSRC = main.c MAINOBJ = main.o DUMPSSRC = html.c svg.c DUMPSOBJ = html.o svg.o #ifdef RegisXTerm SIXELSRC = graphics_regis.c SIXELOBJ = graphics_regis.o #endif #ifdef SixelXTerm SIXELSRC = graphics_sixel.c SIXELOBJ = graphics_sixel.o #endif #ifdef TraceXTerm TRACESRC = trace.c TRACEOBJ = trace.o #endif SRCS1 = button.c cachedGCs.c charproc.c charsets.c cursor.c \ data.c doublechr.c fontutils.c input.c keysym2ucs.c \ linedata.c menu.c misc.c print.c ptydata.c scrollback.c \ screen.c scrollbar.c tabs.c util.c version.c xstrings.c \ xtermcap.c TekPrsTbl.c Tekproc.c VTPrsTbl.c \ $(MAINSRC) $(EXTRASRC) $(UTF8SRC) $(SIXELSRC) $(TRACESRC) $(DUMPSSRC) OBJS1 = button.o cachedGCs.o charproc.o charsets.o cursor.o \ data.o doublechr.o fontutils.o input.o keysym2ucs.o \ linedata.o menu.o misc.o print.o ptydata.o scrollback.o \ screen.o scrollbar.o tabs.o util.o version.o xstrings.o \ xtermcap.o TekPrsTbl.o Tekproc.o VTPrsTbl.o \ $(MAINOBJ) $(EXTRAOBJ) $(UTF8OBJ) $(SIXELOBJ) $(TRACEOBJ) $(DUMPSOBJ) SRCS2 = resize.c version.c xstrings.c OBJS2 = resize.o version.o xstrings.o SRCS = $(SRCS1) $(SRCS2) OBJS = $(OBJS1) $(OBJS2) PROGRAMS = ProgramTargetName(resize) ProgramTargetName(xterm) DEPLIBS1 = XkbClientDepLibs XawClientDepLibs $(XRFDEPLIBS) DEPLIBS2 = #ifndef TermcapLibrary #if SystemV && !defined(MacIIArchitecture) #if defined(CrayArchitecture) || \ (defined(HPArchitecture) && (OSMajorVersion < 10)) || \ defined(RsArchitecture) || \ defined(SCOArchitecture) || \ defined(USLArchitecture) #define TermcapLibrary -lcurses /* special cases of System V */ #else #define TermcapLibrary -ltermlib /* usually in here */ #endif #else #define TermcapLibrary -ltermcap /* bsd puts it here */ #endif #endif TERMCAPLIB = TermcapLibrary AllTarget($(PROGRAMS)) VTPARSE_H = VTparse.h VTparse.hin TEKPARSE_H = Tekparse.h Tekparse.hin VTPARSE_C = VTparse.h VTparse.cin TEKPARSE_C = Tekparse.h Tekparse.cin .SUFFIXES : .def .cin .hin .def.cin : awk '/^CASE_/{printf "{ %d, \"%s\" },\n", n++, $$1; }' < $< >$@ .def.hin : awk '/^CASE_/{printf "#define %s %d\n", $$1, n++}' < $< >$@ SpecialCObjectRule(main,$(_NOOP_),$(MAIN_DEFINES)) SpecialCObjectRule(menu,$(_NOOP_),$(MISC_DEFINES)) SpecialCObjectRule(misc,$(VTPARSE_H),$(MISC_DEFINES)) SpecialCObjectRule(VTPrsTbl,$(VTPARSE_H),$(MISC_DEFINES)) SpecialCObjectRule(charproc,$(VTPARSE_H),$(MISC_DEFINES)) SpecialCObjectRule(data,$(_NOOP_),$(MISC_DEFINES)) SpecialCObjectRule(TekPrsTbl,$(TEKPARSE_H),$(MISC_DEFINES)) SpecialCObjectRule(TekProc,$(TEKPARSE_H),$(MISC_DEFINES)) SpecialCObjectRule(trace,$(VTPARSE_C) $(TEKPARSE_C),$(MISC_DEFINES)) #if InstallXtermSetUID SetUIDProgramTarget(xterm,$(OBJS1),$(DEPLIBS1),$(XRFLIBS) XkbClientLibs XawClientLibs,$(TERMCAPLIB) $(PTYLIB)) #else NormalProgramTarget(xterm,$(OBJS1),$(DEPLIBS1),$(XRFLIBS) XkbClientLibs XawClientLibs,$(TERMCAPLIB) $(UTMPLIB) $(PTYLIB)) #endif #if defined(OpenBSDArchitecture) || defined(MirBSDArchitecture) /* On OpenBSD xterm is now setgid utmp */ INSTUIDFLAGS= -m 2555 -g utmp #endif #if InstallXtermSetUID && defined(SunArchitecture) && HasSharedLibraries && (OSMajorVersion < 5) #if AlternateUsrLibDir #if ((OSMajorVersion == 4) && (OSMinorVersion >= 1)) LDOVERRIDE = -L$(DESTDIR)$(USRLIBDIR) #else #if HasGcc LDOVERRIDE = -static -L$(DESTDIR)$(USRLIBDIR) #else LDOVERRIDE = -Bstatic -L$(DESTDIR)$(USRLIBDIR) LDRESUME = -Bdynamic #endif #endif #endif install:: MakeDir($(DESTDIR)$(BINDIR)) RemoveFile(ProgramTargetName(xterm.inst)) LinkRule(ProgramTargetName(xterm.inst),$(CDEBUGFLAGS) $(CCOPTIONS) $(EXTRA_LDOPTIONS) $(LOCAL_LDFLAGS),$(OBJS1),$(LDOVERRIDE) $(XRFLIBS) XawClientLibs $(LDRESUME) $(LDLIBS) $(TERMCAPLIB) $(PTYLIB)) $(INSTALL) -c $(INSTPGMFLAGS) $(INSTSETIDFLAGS) ProgramTargetName(xterm.inst) $(DESTDIR)$(BINDIR)/ProgramTargetName(xterm) RemoveFile(ProgramTargetName(xterm.inst)) #else InstallProgramWithFlags(xterm,$(BINDIR),$(INSTSETIDFLAGS)) #endif InstallNamedProg(uxterm,uxterm,$(BINDIR)) /* * Link with the termcap library if USE_TERMCAP is defined in resize.c */ #if defined(NTOArchitecture) || \ defined(LinuxArchitecture) || \ defined(OpenBSDArchitecture) || \ defined(SGIArchitecture) || \ defined(SunArchitecture) NormalProgramTarget(resize,$(OBJS2),$(DEPLIBS2),NullParameter,NullParameter) #else NormalProgramTarget(resize,$(OBJS2),$(DEPLIBS2),NullParameter,$(TERMCAPLIB)) #endif InstallProgramWithFlags(resize,$(BINDIR),NullParameter) /* * termcap is a special name that does not install correctly with * InstallNamedNonExec() */ install:: MakeDir($(DESTDIR)$(LIBDIR)/etc) $(INSTALL) $(INSTALLFLAGS) $(INSTDATFLAGS) termcap \ $(DESTDIR)$(LIBDIR)/etc/xterm.termcap InstallNamedNonExec(terminfo,xterm.terminfo,$(LIBDIR)/etc) InstallAppDefaults(XTerm) InstallAppDefaults(UXTerm) InstallAppDefaultsLong(XTerm-col,XTerm-color) InstallManPage(xterm,$(MANDIR)) InstallManPage(resize,$(MANDIR)) cleandir:: $(RM) *parse.hin *parse.cin DependTarget() xterm-399/256colres.pl0000755000000000000000000000600610632366455013335 0ustar rootroot#! /usr/bin/perl # $XTermId: 256colres.pl,v 1.16 2007/06/08 23:58:37 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 1999-2002,2007 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Construct a header file defining default resources for the 256-color model # of xterm. This is modeled after the 256colors2.pl script. # use the resources for colors 0-15 - usually more-or-less a # reproduction of the standard ANSI colors, but possibly more # pleasing shades use strict; our ( $line1, $line2, $line3 ); our ( $red, $green, $blue, $gray ); our ( $level, $code, @steps ); print < #include #include #include #include #include static void alloc_pw(struct passwd *target, struct passwd *source) { *target = *source; /* we care only about these strings */ target->pw_dir = x_strdup(source->pw_dir); target->pw_name = x_strdup(source->pw_name); target->pw_shell = x_strdup(source->pw_shell); } static void free_pw(struct passwd *source) { free(source->pw_dir); free(source->pw_name); free(source->pw_shell); } void x_appendargv(char **target, char **source) { if (target && source) { target += x_countargv(target); while ((*target++ = *source++) != NULL) ; } } char * x_basename(char *name) { char *cp; cp = strrchr(name, '/'); return (cp ? cp + 1 : name); } unsigned x_countargv(char **argv) { unsigned result = 0; if (argv) { while (*argv++) { ++result; } } return result; } /* * Decode a hexadecimal string, returning the decoded string. * On return, 'next' points to the first character not part of the input. * The caller must free the result. */ char * x_decode_hex(const char *source, const char **next) { char *result = NULL; int pass; size_t j, k; for (pass = 0; pass < 2; ++pass) { for (j = k = 0; isxdigit(CharOf(source[j])); ++j) { if ((pass != 0) && (j & 1) != 0) { result[k++] = (char) ((CharOf(x_hex2int(source[j - 1])) << 4) | CharOf(x_hex2int(source[j]))); } } *next = (source + j); if ((j & 1) == 0) { if (pass) { result[k] = '\0'; } else { result = malloc(++j); if (result == NULL) break; /* not enough memory */ } } else { break; /* must have an even number of digits */ } } return result; } /* * Encode a string into hexadecimal, returning the encoded string. * The caller must free the result. */ char * x_encode_hex(const char *source) { size_t need = (strlen(source) * 2) + 1; char *result = malloc(need); if (result != NULL) { unsigned j, k; result[0] = '\0'; for (j = k = 0; source[j] != '\0'; ++j) { sprintf(result + k, "%02X", CharOf(source[j])); k += 2; } } return result; } char * x_getenv(const char *name) { char *result; result = x_strdup(x_nonempty(getenv(name))); TRACE2(("getenv(%s) %s\n", name, result)); return result; } static char * login_alias(char *login_name, uid_t uid, struct passwd *in_out) { /* * If the logon-name differs from the value we get by looking in the * password file, check if it does correspond to the same uid. If so, * allow that as an alias for the uid. */ if (!IsEmpty(login_name) && strcmp(login_name, in_out->pw_name)) { struct passwd pw2; if (x_getpwnam(login_name, &pw2)) { uid_t uid2 = pw2.pw_uid; struct passwd pw3; Boolean ok3; if ((ok3 = x_getpwuid(uid, &pw3)) && ((uid_t) pw3.pw_uid == uid2)) { /* use the other passwd-data including shell */ alloc_pw(in_out, &pw2); } else { FreeAndNull(login_name); } free_pw(&pw2); if (ok3) free_pw(&pw3); } } return login_name; } /* * Call this with in_out pointing to data filled in by x_getpwnam() or by * x_getpwnam(). It finds the user's logon name, if possible. As a side * effect, it updates in_out to fill in possibly more-relevant data, i.e., * in case there is more than one alias for the same uid. */ char * x_getlogin(uid_t uid, struct passwd *in_out) { char *login_name; login_name = login_alias(x_getenv("LOGNAME"), uid, in_out); if (IsEmpty(login_name)) { free(login_name); login_name = login_alias(x_getenv("USER"), uid, in_out); } #ifdef HAVE_GETLOGIN /* * Of course getlogin() will fail if we're started from a window-manager, * since there's no controlling terminal to fuss with. For that reason, we * tried first to get something useful from the user's $LOGNAME or $USER * environment variables. */ if (IsEmpty(login_name)) { TRACE2(("...try getlogin\n")); free(login_name); login_name = login_alias(x_strdup(getlogin()), uid, in_out); } #endif if (IsEmpty(login_name)) { free(login_name); login_name = x_strdup(in_out->pw_name); } TRACE2(("x_getloginid ->%s\n", NonNull(login_name))); return login_name; } /* * Simpler than getpwnam_r, retrieves the passwd result by name and stores the * result via the given pointer. On failure, wipes the data to prevent use. */ Boolean x_getpwnam(const char *name, struct passwd *result) { struct passwd *ptr = getpwnam(name); Boolean code; if (ptr != NULL && OkPasswd(ptr)) { code = True; alloc_pw(result, ptr); } else { code = False; memset(result, 0, sizeof(*result)); } return code; } /* * Simpler than getpwuid_r, retrieves the passwd result by uid and stores the * result via the given pointer. On failure, wipes the data to prevent use. */ Boolean x_getpwuid(uid_t uid, struct passwd *result) { struct passwd *ptr = getpwuid((uid_t) uid); Boolean code; if (ptr != NULL && OkPasswd(ptr)) { code = True; alloc_pw(result, ptr); } else { code = False; memset(result, 0, sizeof(*result)); } TRACE2(("x_getpwuid(%d) %d\n", (int) uid, (int) code)); return code; } /* * Decode a single hex "nibble", returning the nibble as 0-15, or -1 on error. */ int x_hex2int(int c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return -1; } /* * Check if the given string is nonnull/nonempty. If so, return a pointer * to the beginning of its content, otherwise return null. */ String x_nonempty(String s) { if (s != NULL) { if (*s == '\0') { s = NULL; } else { s = x_skip_blanks(s); if (*s == '\0') s = NULL; } } return s; } String x_skip_blanks(String s) { while (IsSpace(CharOf(*s))) ++s; return s; } String x_skip_nonblanks(String s) { while (*s != '\0' && !IsSpace(CharOf(*s))) ++s; return s; } static const char * skip_blanks(const char *s) { while (IsSpace(CharOf(*s))) ++s; return s; } /* * Split a command-string into an argv[]-style array. */ char ** x_splitargs(const char *command) { char **result = NULL; if (command != NULL) { const char *first = skip_blanks(command); char *blob = x_strdup(first); if (blob != NULL) { int pass; for (pass = 0; pass < 2; ++pass) { int state; size_t count; size_t n; for (n = count = 0, state = 0; first[n] != '\0'; ++n) { switch (state) { case 0: if (!IsSpace(CharOf(first[n]))) { state = 1; if (pass) result[count] = blob + n; ++count; } else { blob[n] = '\0'; } break; case 1: if (IsSpace(CharOf(first[n]))) { blob[n] = '\0'; state = 0; } break; } } if (!pass) { result = TypeCallocN(char *, count + 1); if (!result) { free(blob); break; } } } } } else { result = TypeCalloc(char *); } return result; } /* * Free storage allocated by x_splitargs(). */ void x_freeargs(char **argv) { if (argv != NULL) { free(*argv); free(argv); } } int x_strcasecmp(const char *s1, const char *s2) { size_t len1 = (s1 != NULL) ? strlen(s1) : 0; size_t len2 = (s2 != NULL) ? strlen(s2) : 0; return ((len1 != len2) ? 1 : x_strncasecmp(s1, s2, (unsigned) len1)); } int x_strncasecmp(const char *s1, const char *s2, unsigned n) { int result = 0; if (s1 != NULL && s2 != NULL) { while (n-- != 0) { char c1 = x_toupper(*s1); char c2 = x_toupper(*s2); if (c1 != c2) { result = 1; break; } else if (c1 == 0) { break; } s1++; s2++; } } else if (s1 == NULL && s2 != NULL) { result = 1; } else if (s1 != NULL && s2 == NULL) { result = 1; } return result; } /* * Allocates a copy of a string */ char * x_strdup(const char *s) { char *result = NULL; if (s != NULL) { char *t = malloc(strlen(s) + 5); if (t != NULL) { strcpy(t, s); } result = t; } return result; } /* * Returns a pointer to the first occurrence of s2 in s1, * or NULL if there are none. */ char * x_strindex(char *s1, const char *s2) { char *s3; size_t s2len = strlen(s2); while ((s3 = (strchr) (s1, *s2)) != NULL) { if (strncmp(s3, s2, s2len) == 0) return (s3); s1 = ++s3; } return (NULL); } /* * Trims leading/trailing spaces from a copy of the string. */ char * x_strtrim(const char *source) { char *result; if (IsEmpty(source)) { result = x_strdup(""); } else { char *t = x_strdup(source); if (t != NULL) { char *s = t; char *d = s; while (IsSpace(CharOf(*s))) ++s; while ((*d++ = *s++) != '\0') { ; } if (*t != '\0') { s = t + strlen(t); while (s != t && IsSpace(CharOf(s[-1]))) { *--s = '\0'; } } } result = t; } return result; } /* * Trims trailing whitespace from a copy of the string. */ char * x_strrtrim(const char *source) { char *result; if (IsEmpty(source)) { result = x_strdup(""); } else { char *t = x_strdup(source); if (t != NULL) { if (*t != '\0') { char *s = t + strlen(t); while (s != t && IsSpace(CharOf(s[-1]))) { *--s = '\0'; } } } result = t; } return result; } /* * Avoid using system locale for upper/lowercase conversion, since there are * a few locales where toupper(tolower(c)) != c. */ char x_toupper(int ch) { static char table[256]; char result = table[CharOf(ch)]; if (result == '\0') { unsigned n; static const char s[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; for (n = 0; n < sizeof(table); ++n) { table[n] = (char) n; } for (n = 0; s[n] != '\0'; ++n) { table[CharOf(s[n])] = s[n % 26]; } result = table[CharOf(ch)]; } return result; } /* * Match strings ignoring case and allowing glob-like '*' and '?' */ int x_wildstrcmp(const char *pattern, const char *actual) { int result = 0; while (*pattern && *actual) { char c1 = x_toupper(*pattern); char c2 = x_toupper(*actual); if (c1 == '*') { Boolean found = False; pattern++; while (*actual != '\0') { if (!x_wildstrcmp(pattern, actual++)) { found = True; break; } } if (!found) { result = 1; break; } } else if (c1 == '?') { ++pattern; ++actual; } else if ((result = (c1 != c2)) == 0) { ++pattern; ++actual; } else { break; } } return result; } xterm-399/version.h0000644000000000000000000000400215012470645013073 0ustar rootroot/* $XTermId: version.h,v 1.577 2025/05/18 23:47:49 tom Exp $ */ /* * Copyright 1998-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #ifndef included_version_h #define included_version_h /* * These definitions are used to build the string that's printed in response to * "xterm -version", or embedded in "xterm -help". It usually indicates the * version of X to which this version of xterm has been built. The resulting * number in parentheses is my patch number (Thomas E. Dickey). */ #define XTERM_PATCH 399 #define XTERM_DATE 2025-05-18 #ifndef __vendorversion__ #define __vendorversion__ "XTerm" #endif extern const char *xtermVersion(void); #endif /* included_version_h */ xterm-399/graphics_sixel.c0000644000000000000000000006550314723101664014422 0ustar rootroot/* $XTermId: graphics_sixel.c,v 1.63 2024/12/01 15:41:40 tom Exp $ */ /* * Copyright 2014-2023,2024 by Thomas E. Dickey * Copyright 2024 by Benjamin A. Wong * Copyright 2014-2022,2023 by Ross Combs * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #include #include #include #include #include #include #include #include #include #include /***====================================================================***/ typedef struct { RegisterNum current_register; RegisterNum background; /* current background color register or hole */ int aspect_vertical; int aspect_horizontal; int declared_width; /* size as reported by the application */ int declared_height; /* size as reported by the application */ int row; /* context used during parsing */ int col; /* context used during parsing */ } SixelContext; /* Saved state for the parse_sixel_char() state machine */ static XtermWidget s_xw; static TScreen *s_screen; static Graphic *s_graphic; static SixelContext s_context; static int s_prev_row; /* Dirty graphic cursor last location for screen updating */ static int s_prev_col; static int s_accumulator; /* Accumulation of decimal digits. (-1 for no digits, use default) */ static Boolean s_repeating; /* true if gathering digits for '!' (repeat) */ /* * States for gathering params for '#' (color) */ static enum { s_NOTCOLORING ,s_GETTINGREGISTER ,s_GETTINGCOLORSPACE ,s_GETTINGPC1 ,s_GETTINGPC2 ,s_GETTINGPC3 ,s_COLORINGDONE } s_color_state; static int s_color_params[s_COLORINGDONE + 1]; static RegisterNum s_Pregister; /* * States for gathering params from DECGRA ('"' set raster attributes) * Refer to EK-PPLV2-PM, page 5-24. */ static enum { s_NOTRASTER ,s_GETTINGPAN /* Pixel aspect ratio numerator */ ,s_GETTINGPAD /* Pixel aspect ratio denominator */ ,s_GETTINGV /* Pixel vertical extent */ ,s_GETTINGH /* Pixel horizontal extent */ ,s_RASTERDONE } s_raster_state; static int s_raster_params[s_RASTERDONE + 1]; /* SIXEL SCROLLING, which is on by default in VT3xx terminals, can be * turned off to better emulate VT2xx terminals by setting Sixel * Display Mode (DECSDM) * * SIXEL DISPLAY MODE SIXEL SCROLLING * VT125 Always on Unsupported * VT240 Always on Unsupported * VT241 Always on Unsupported * VT330 Available via DECSDM Default mode * VT382 Available via DECSDM Default mode * VT340 Available via DECSDM Default mode * VK100/GIGI No sixel support No sixel support * * dxterm (DECterm) emulated a VT100 series terminal, and supported sixels * according to 1995 posting to comp.os.vms: * https://groups.google.com/g/comp.os.vms/c/XAUMmLtC8Yk * though not DRCS according to * http://odl.sysworks.biz/disk$axpdocdec023/office/dwmot126/vmsdw126/relnotes/6470pro_004.html */ static void init_sixel_background(Graphic *graphic, SixelContext const *context) { RegisterNum *source; RegisterNum *target; size_t length; int r, c; TRACE(("initializing sixel background to size=%dx%d bgcolor=%hu\n", context->declared_width, context->declared_height, context->background)); if (context->background == COLOR_HOLE) return; source = graphic->pixels; for (c = 0; c < graphic->actual_width; c++) { source[c] = context->background; } target = source; length = (size_t) graphic->actual_width * sizeof(*target); for (r = 1; r < graphic->actual_height; r++) { target += graphic->max_width; memcpy(target, source, length); } graphic->color_registers_used[context->background] = True; } #define ValidColumn(graphic, context) \ ((context)->col >= 0 && \ (context)->col < (graphic)->max_width) static Boolean set_sixel(Graphic *graphic, SixelContext const *context, int sixel) { const int mh = graphic->max_height; const int mw = graphic->max_width; const RegisterNum color = context->current_register; int pix; int pix_row = context->row; int pix_col = context->col + (pix_row * mw); TRACE2(("drawing sixel at pos=%d,%d color=%hu (hole=%d, [%d,%d,%d])\n", context->col, context->row, color, color == COLOR_HOLE, ((color != COLOR_HOLE) ? (unsigned) graphic->color_registers[color].r : 0U), ((color != COLOR_HOLE) ? (unsigned) graphic->color_registers[color].g : 0U), ((color != COLOR_HOLE) ? (unsigned) graphic->color_registers[color].b : 0U))); for (pix = 0; pix < 6; pix++, pix_row++, pix_col += mw) { if (pix_row >= 0 && pix_row < mh) { if (sixel & (1 << pix)) { if (context->col >= graphic->actual_width) { graphic->actual_width = context->col + 1; } if (pix_row >= graphic->actual_height) { graphic->actual_height = pix_row + 1; } SetSpixel(graphic, pix_col, color); } } else { TRACE(("sixel pixel %d out of bounds\n", pix)); return False; } } return True; } static void update_sixel_aspect(SixelContext * context, Graphic *graphic) { int limit; int best; int gcd; /* We want to keep the ratio accurate but would like every pixel to have * the same size so keep these as whole numbers. */ /* FIXME: The VT340 repeats pixels instead of spreading them out. */ /* FIXME: A single sixel DCS string can have multiple aspect ratios on the VT340, but PPLv2 does not allow it. We currently neither implement it nor explicitly ignore DECGRA after sixels have started. We probably should allow for it as that is how genuine DEC hardware behaved. */ TRACE(("sixel updating pixel aspect (v:h): %d:%d\n", context->aspect_vertical, context->aspect_horizontal)); /* * Reduce to the lowest possible format, * to handle ratios such as 2:3 and 16:9 */ limit = Min(context->aspect_vertical, context->aspect_horizontal); TRACE(("sixel aspect limit: %d\n", limit)); best = 1; for (gcd = 2; gcd <= limit; ++gcd) { if ((context->aspect_vertical % gcd) == 0 && (context->aspect_horizontal % gcd) == 0) { best = gcd; } } TRACE(("sixel aspect gcd: %d\n", best)); context->aspect_vertical /= best; context->aspect_horizontal /= best; /* EK-PPLV2-PM-B01 says the range along either axis is no more than 10, * which is good advice for programs creating images for generic "Level 2 * Sixel" devices. * * FIXME: The converse is true when implementing a sixel rendering * engine. As a *minimum* requirement, xterm must allow either axis to * range from 1 to 10, but, just like the hardware it emulates, it may * exceed specifications. * * The VT340 appears to have no practical limit. Even ratios over 480:1 * -- where each pixel would exceed the screen height -- are allowed. */ if (context->aspect_vertical > (10 * context->aspect_horizontal)) context->aspect_vertical = (10 * context->aspect_horizontal); if (context->aspect_horizontal > (10 * context->aspect_vertical)) context->aspect_horizontal = (10 * context->aspect_vertical); /* in any case, limit "pixel" size if both are large */ #define by10(n) n = (n + 5) / 10 while (context->aspect_vertical >= 10 && context->aspect_horizontal >= 10) { by10(context->aspect_vertical); by10(context->aspect_horizontal); } graphic->pixw = context->aspect_horizontal; graphic->pixh = context->aspect_vertical; TRACE(("sixel aspect ratio: an=%d ad=%d -> pixw=%d pixh=%d\n", context->aspect_vertical, context->aspect_horizontal, graphic->pixw, graphic->pixh)); #if 1 /* FIXME: Aspect Ratio is buggy, so we'll just force it off */ graphic->pixw = 1; graphic->pixh = 1; #endif } static void finished_parsing(Graphic *graphic) { TScreen *screen = TScreenOf(s_xw); /* Update the screen scrolling and do a refresh. * The refresh may not cover the whole graphic. */ if (screen->scroll_amt) FlushScroll(s_xw); if (SixelScrolling(s_xw)) { int new_row, new_col; /* Note: XTerm follows the VT340 behavior in text cursor placement * for nearly all sixel images. It differs in the few places where * TWO newlines would have been necessary for subsequent text to not * overwrite an image. XTerm always requires only a single newline. * * Emulating the VT340's quirky and undocumented behavior is of * dubious value. The heuristic DEC used has nice properties, but * only applies if the font is exactly 20 pixels high. */ new_row = (graphic->charrow - 1 + (((graphic->actual_height * graphic->pixh) + FontHeight(screen) - 1) / FontHeight(screen))); if (screen->sixel_scrolls_right) { new_col = (graphic->charcol + (((graphic->actual_width * graphic->pixw) + FontWidth(screen) - 1) / FontWidth(screen))); } else { new_col = graphic->charcol; } TRACE(("setting text position after %dx%d\t%.1f start (%d %d): cursor (%d,%d)\n", graphic->actual_width * graphic->pixw, graphic->actual_height * graphic->pixh, ((double) graphic->charrow + ((double) (graphic->actual_height * graphic->pixh) / (double) FontHeight(screen))), graphic->charrow, graphic->charcol, new_row, new_col)); if (new_col > screen->rgt_marg) { new_col = screen->lft_marg; new_row++; TRACE(("column past left margin, overriding to row=%d col=%d\n", new_row, new_col)); } while (new_row > screen->bot_marg) { xtermScroll(s_xw, 1); new_row--; TRACE(("bottom row was past screen. new start row=%d, cursor row=%d\n", graphic->charrow, new_row)); } if (new_row < 0) { /* FIXME: this was triggering, now it isn't */ TRACE(("new row is going to be negative (%d); skipping position update!", new_row)); } else { set_cur_row(screen, new_row); set_cur_col(screen, new_col <= screen->rgt_marg ? new_col : screen->rgt_marg); } } graphic->dirty = True; refresh_modified_displayed_graphics(s_xw); dump_graphic(graphic); } /* * Handle Sixel protocol selector: Ps1 ; Ps2 ; Ps3 q * Refer to EK-PPLV2-PM, Table 5-1 "Macro Parameter Selections" */ void parse_sixel_init(XtermWidget xw, ANSI *params) { s_xw = xw; s_screen = TScreenOf(xw); s_repeating = False; s_accumulator = -1; /* No digits accumulated */ s_context.aspect_horizontal = 1; s_context.aspect_vertical = 2; switch (s_screen->terminal_id) { case 240: case 241: case 330: case 340: s_context.aspect_vertical = 2; s_context.aspect_horizontal = 1; break; case 382: s_context.aspect_vertical = 1; s_context.aspect_horizontal = 1; break; default: s_context.aspect_vertical = 2; s_context.aspect_horizontal = 1; break; } s_context.declared_width = 0; s_context.declared_height = 0; s_context.row = 0; s_context.col = 0; s_prev_row = 0; s_prev_col = 0; /* default isn't white on the VT240, but not sure what it is */ s_context.current_register = 3; /* FIXME: using green, but not sure what it should be */ /* allocate s_graphic if needs be */ if (SixelScrolling(s_xw)) { TRACE(("sixel scrolling enabled: inline positioning for graphic at %d,%d\n", s_screen->cur_row, s_screen->cur_col)); s_graphic = get_new_graphic(s_xw, s_screen->cur_row, s_screen->cur_col, 0U); } else { TRACE(("sixel scrolling disabled: inline positioning for graphic at %d,%d\n", 0, 0)); s_graphic = get_new_graphic(s_xw, 0, 0, 0U); } { static const int vertical[] = { /* 0 1 2 3 4 5 6 7 8 9 */ 200, 200, 450, 300, 250, 183, 150, 130, 112, 100 }; int Pmacro = UParmOf(params->a_param[0]); int Pbgmode = UParmOf(params->a_param[1]); int Phgrid = UParmOf(params->a_param[2]); TRACE(("sixel bitmap graphics sequence: params=%d (Pmacro=%d Pbgmode=%d Phgrid=%d) scroll_amt=%d\n", params->a_nparam, Pmacro, Pbgmode, Phgrid, s_screen->scroll_amt)); /* Ps1: "Macro" Aspect ratio and default grid size */ /* * Note: Macro is often left at 0 since its horizontal grid size can be * overridden by Ps3 and its aspect ratio can be overridden by DECGRA. */ if (Pmacro > 9 || Pmacro < 0) { Pmacro = 0; } s_context.aspect_vertical = vertical[Pmacro]; s_context.aspect_horizontal = 100; /* Ps2: Background 0 or 2 = opaque, 1 = transparent */ if (Pbgmode == 1) { s_context.background = COLOR_HOLE; } else { /* The default background register is always zero (including in * light background mode) on the VT340. */ s_context.background = 0; } /* Ps3: horizontal grid size in decipoints (1/720 inch) */ /* * Note: The CRT of the VT340 had a grid (distance between pixels) * of 10/720th of an inch (0.0195 cm). */ if (Phgrid <= 0) { Phgrid = 50; /* Default is 50 decipoints (144dpi) */ } } update_sixel_aspect(&s_context, s_graphic); } #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) #define TS_NANOSEC 1L #define TS_MICROSEC 1000L * TS_NANOSEC #define TS_MILLISEC 1000L * TS_MICROSEC #define TS_SEC 1000L * TS_MILLISEC /* Returns True if the system's monotonic clock has reached or exceeded _when_. * If _increment_ is not NULL, _when_ will be set to now + _increment_. */ static Boolean times_up(struct timespec *when, struct timespec *increment) { struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); if (when->tv_sec < now.tv_sec || (when->tv_sec == now.tv_sec && when->tv_nsec < now.tv_nsec)) { return False; } if (increment) { when->tv_sec += now.tv_sec + increment->tv_sec; when->tv_nsec += now.tv_nsec + increment->tv_nsec; while (when->tv_nsec >= TS_SEC) { when->tv_sec += 1; when->tv_nsec -= TS_SEC; } } return True; } #endif static void parse_sixel_incremental_display(void) { /* Watch sixels appear just like a VT340! */ int dirty_row = ((s_context.row * s_graphic->pixh) + (s_graphic->charrow * FontHeight(s_screen))); int dirty_col = ((s_context.col * s_graphic->pixw) + (s_graphic->charcol * FontWidth(s_screen))); #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) static struct timespec next_refresh = { 0, 0 }; static struct timespec refresh_delay = { 0, TS_MILLISEC }; /* Bundle up incremental refreshes that happen faster than visually * perceptible. */ if (!times_up(&next_refresh, &refresh_delay)) { return; } #endif if (dirty_row != s_prev_row) { s_prev_row = dirty_row; s_prev_col = 0; } /* FIXME: Image should be cropped to the text cells when xtermmargin>0 */ s_graphic->dirty = True; refresh_displayed_graphics(s_xw, s_prev_col / FontWidth(s_screen), s_prev_row / FontHeight(s_screen), 1 + 1 + (dirty_col - s_prev_col) / FontWidth(s_screen), 1); s_prev_row = dirty_row; s_prev_col = dirty_col; } void parse_sixel_char(char cp) { /* s_* variables are static state, defined above */ if (cp == '\0' || isspace(CharOf(cp))) { if (s_repeating && cp == '\0') { TRACE(("DATA_ERROR: sixel data string terminated in the middle of a repeat operator\n")); s_repeating = False; finished_parsing(s_graphic); } return; } if (isdigit(CharOf(cp))) { if (s_accumulator == -1) s_accumulator = 0; s_accumulator *= 10; s_accumulator += cp - '0'; return; } if (s_repeating) { /* '!' ... */ /* Not space or digit, so it must be the sixel to show */ if (cp >= 0x3F && cp <= 0x7E) { int sixel = cp - 0x3f; TRACE(("sixel repeat operator: sixel=%d (%c), count=%d\n", sixel, (char) cp, s_accumulator)); if (s_accumulator <= 0) { /* If the repeat count is zero or omitted, it is treated as 1 */ s_accumulator = 1; } if (!s_graphic->valid) { init_sixel_background(s_graphic, &s_context); s_graphic->valid = True; } if (sixel) { int i; for (i = 0; i < s_accumulator; i++) { if (ValidColumn(s_graphic, &s_context) && set_sixel(s_graphic, &s_context, sixel)) { s_context.col++; } else { break; } } } else { s_context.col += s_accumulator; } } else { TRACE(("DATA_ERROR: sixel data string ignoring repeat operator followed by control: %c (%d)\n", cp, cp)); s_repeating = False; } s_accumulator = -1; s_repeating = False; if (s_screen->incremental_graphics) parse_sixel_incremental_display(); return; } /* FIXME: Raster attributes (") can occur repeatedly and at any time. */ /* Parse the Raster Attributes ( " Pn1 ; Pn2 ; Pn3 ; Pn4 ) */ if (s_raster_state > s_NOTRASTER) { TRACE(("sixel DECGRA raster argument found %d, followed by '%c'\n", s_accumulator, cp)); /* cp is not a digit or space, so save the accumulator */ if (s_accumulator != -1) { s_raster_params[s_raster_state] = s_accumulator; } switch (s_raster_state) { #define GetAspect(state) \ case state: \ if (s_raster_params[state] <= 0) { \ s_raster_params[state] = 1; \ } else if (s_raster_params[state] > MaxSParm) { \ s_raster_params[state] = MaxSParm; \ } \ break GetAspect(s_GETTINGPAN); GetAspect(s_GETTINGPAD); #define GetExtent(state, field) \ case state: \ if (s_raster_params[state] <= 0) { \ s_raster_params[state] = 1; \ } \ if (s_raster_params[state] > s_graphic->max_ ## field) { \ TRACE(("DATA_ERROR: raster " #field " %d > max %d\n", \ s_raster_params[state], s_graphic->max_ ## field)); \ s_raster_state = s_NOTRASTER; \ finished_parsing(s_graphic); \ return; \ } \ s_context.declared_ ## field = s_raster_params[state]; \ break GetExtent(s_GETTINGV, height); GetExtent(s_GETTINGH, width); case s_NOTCOLORING: case s_RASTERDONE: /* ignore unreachable states */ break; default: TRACE(("DATA_ERROR: raster operator ('\"') with too many parameters (%d)\n, next char %c (%d)\n", s_raster_state, cp, cp)); s_raster_state = s_NOTRASTER; finished_parsing(s_graphic); return; } /* Save data from Raster Attributes */ /* *INDENT-EQLS* */ s_context.aspect_vertical = s_raster_params[s_GETTINGPAN]; s_context.aspect_horizontal = s_raster_params[s_GETTINGPAD]; update_sixel_aspect(&s_context, s_graphic); s_context.declared_width = s_raster_params[s_GETTINGV]; s_context.declared_height = s_raster_params[s_GETTINGH]; s_accumulator = -1; s_raster_state++; if (cp == ';') { return; } /* cp (next character to consume) is not digit, space, or semicolon, so finish up with raster */ s_raster_state = s_NOTRASTER; /* FIXME: Declared size should clear & scroll rectangle when no raster attributes */ if (s_context.declared_width > s_graphic->actual_width) { s_graphic->actual_width = s_context.declared_width; } if (s_context.declared_height > s_graphic->actual_height) { s_graphic->actual_height = s_context.declared_height; } /* FALLTHRU TO PROCESS cp */ } if (s_color_state > s_NOTCOLORING) { /* cp is not a digit or space, so process the accumulator */ if (s_accumulator != -1) { s_color_params[s_color_state] = s_accumulator; } switch (s_color_state) { case s_GETTINGREGISTER: if (s_accumulator == -1) { /* FIXME: What does VT340 do with default register? */ TRACE(("DATA_ERROR: sixel data string uses default color register, next char %c (%d)\n", cp, cp)); finished_parsing(s_graphic); return; } s_Pregister = (RegisterNum) s_color_params[s_GETTINGREGISTER]; /* The DEC terminals wrapped register indices. */ s_Pregister %= (RegisterNum) s_graphic->valid_registers; TRACE(("sixel switch to color register=%u\n", s_Pregister)); s_context.current_register = s_Pregister; break; case s_GETTINGCOLORSPACE: if (s_accumulator == -1) { /* FIXME: Default VT340 colorspace is HSL, right? */ TRACE(("DATA_ERROR: sixel data string uses default colorspace \n")); s_color_state = s_NOTCOLORING; finished_parsing(s_graphic); return; } break; case s_GETTINGPC1: if (s_accumulator == -1) { /* FIXME: Does VT340 sixel do the same as ReGIS and use the previous value for unspecified color components? */ TRACE(("DATA_ERROR: sixel data string uses default color component 1 \n")); s_color_state = s_NOTCOLORING; finished_parsing(s_graphic); return; } break; case s_GETTINGPC2: if (s_accumulator == -1) { /* FIXME: unspecified color components? */ TRACE(("DATA_ERROR: sixel data string uses default color component 2 \n")); s_color_state = s_NOTCOLORING; finished_parsing(s_graphic); return; } break; case s_GETTINGPC3: if (s_accumulator == -1) { /* FIXME: unspecified color components? */ TRACE(("DATA_ERROR: sixel data string uses default color component 3 \n")); s_color_state = s_NOTCOLORING; finished_parsing(s_graphic); return; } break; case s_COLORINGDONE: case s_NOTCOLORING: /* ignore unreachable states */ break; default: /* FIXME: Why abort if too many parameters? Doesn't DEC ignore unknown parameters? */ TRACE(("DATA_ERROR: sixel switch color operator ('#') with too many parameters\n, next char %c (%d)\n", cp, cp)); s_color_state = s_NOTCOLORING; finished_parsing(s_graphic); return; } s_accumulator = -1; s_color_state++; if (cp == ';') { return; } else { /* cp (next character to consume) is not digit, space, or semicolon, so finish up with color */ if (s_color_state != s_COLORINGDONE && s_color_state != s_GETTINGCOLORSPACE) { TRACE(("DATA_ERROR: sixel switch color operator with wrong number of parameters (%d)\n", s_color_state)); s_color_state = s_NOTCOLORING; finished_parsing(s_graphic); return; } if (s_color_state == s_COLORINGDONE) { /* We've got all components, so set the color register */ int Pspace = s_color_params[s_GETTINGCOLORSPACE]; int Pc1 = s_color_params[s_GETTINGPC1]; int Pc2 = s_color_params[s_GETTINGPC2]; int Pc3 = s_color_params[s_GETTINGPC3]; short r, g, b; s_color_state = s_NOTCOLORING; TRACE(("sixel set color register=%u space=%d color=[%d,%d,%d]\n", s_Pregister, Pspace, Pc1, Pc2, Pc3)); switch (Pspace) { case 1: /* HLS */ if (Pc1 > 360 || Pc2 > 100 || Pc3 > 100) { TRACE(("DATA_ERROR: sixel set color operator uses out-of-range HLS color coordinates %d,%d,%d\n", Pc1, Pc2, Pc3)); s_color_state = s_NOTCOLORING; finished_parsing(s_graphic); return; } hls2rgb(Pc1, Pc2, Pc3, &r, &g, &b); break; case 2: /* RGB */ if (Pc1 > 100 || Pc2 > 100 || Pc3 > 100) { TRACE(("DATA_ERROR: sixel set color operator uses out-of-range RGB color coordinates %d,%d,%d\n", Pc1, Pc2, Pc3)); s_color_state = s_NOTCOLORING; finished_parsing(s_graphic); return; } r = (short) Pc1; g = (short) Pc2; b = (short) Pc3; break; default: /* unknown */ TRACE(("DATA_ERROR: sixel set color operator uses unknown color space %d\n", Pspace)); s_color_state = s_NOTCOLORING; finished_parsing(s_graphic); return; } update_color_register(s_graphic, s_Pregister, r, g, b); } s_color_state = s_NOTCOLORING; /* FALLTHRU TO PROCESS cp */ } } if (cp >= 0x3f && cp <= 0x7e) { int sixel = cp - 0x3f; TRACE(("sixel=%x (%c)\n", sixel, (char) cp)); if (!s_graphic->valid) { init_sixel_background(s_graphic, &s_context); s_graphic->valid = True; } if (sixel) { if (!ValidColumn(s_graphic, &s_context) || !set_sixel(s_graphic, &s_context, sixel)) { return; } } s_context.col++; if (s_screen->incremental_graphics) parse_sixel_incremental_display(); } else if (cp == '$') { /* DECGCR */ /* ignore DECCRNLM in sixel mode */ TRACE(("sixel CR\n")); s_context.col = 0; } else if (cp == '-') { /* DECGNL */ int scroll_lines; TRACE(("sixel NL: ")); scroll_lines = 0; while (s_graphic->charrow - scroll_lines + (((s_context.row + Min(6, s_graphic->actual_height - s_context.row)) * s_graphic->pixh + FontHeight(s_screen) - 1) / FontHeight(s_screen)) > s_screen->bot_marg) { scroll_lines++; } s_context.col = 0; s_context.row += 6; TRACE2(("new row location is %u\n", s_context.row)); /* If we hit the bottom margin on the graphics page (well, we just use * the text margin for now), the behavior is to either scroll or to * discard the remainder of the graphic depending on this setting. */ if (scroll_lines > 0) { if (SixelScrolling(s_xw)) { xtermScroll(s_xw, scroll_lines); if (s_screen->incremental_graphics) { FlushScroll(s_xw); XSync(s_screen->display, False); s_graphic->dirty = True; refresh_modified_displayed_graphics(s_xw); } TRACE(("graphic scrolled the screen %d lines. s_screen->scroll_amt=%d s_screen->topline=%d, now starting row is %d\n", scroll_lines, s_screen->scroll_amt, s_screen->topline, s_graphic->charrow)); } } } else if (cp == '!') { /* DECGRI */ s_repeating = True; s_accumulator = -1; } else if (cp == '#') { /* DECGCI */ s_color_state = s_GETTINGREGISTER; s_accumulator = -1; } else if (cp == '"') { /* DECGRA */ s_raster_state = s_GETTINGPAN; s_accumulator = -1; s_raster_params[s_GETTINGPAN] = 1; /* Default if not specified */ s_raster_params[s_GETTINGPAD] = 1; /* Default if not specified */ s_raster_params[s_GETTINGH] = 0; /* Default if not specified */ s_raster_params[s_GETTINGV] = 0; /* Default if not specified */ } else { TRACE(("DATA_ERROR: skipping unknown sixel command %04x (%c)\n", (int) cp, cp)); } } /* Just like finished_parsing, but called from charproc.c */ void parse_sixel_finished(void) { finished_parsing(s_graphic); } xterm-399/scrollback.c0000644000000000000000000001017414723143224013525 0ustar rootroot/* $XTermId: scrollback.c,v 1.24 2024/12/01 20:27:00 tom Exp $ */ /* * Copyright 2009-2022,2024 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #include #define REAL_ROW(screen, row) ((row) + (screen)->saved_fifo) #define ROW2FIFO(screen, row) \ (unsigned) (REAL_ROW(screen, row) % (screen)->savelines) /* * Given a row-number, find the corresponding data for the line in the VT100 * widget's saved-line FIFO. The row-number (from getLineData) is negative. * So we just count backwards from the last saved line. */ LineData * getScrollback(TScreen *screen, int row) { LineData *result = NULL; if (screen->saved_fifo > 0 && REAL_ROW(screen, row) >= 0) { unsigned which = ROW2FIFO(screen, row); ScrnBuf where = scrnHeadAddr(screen, screen->saveBuf_index, which); result = (LineData *) where; } TRACE(("getScrollback %d -> %d -> %p\n", row, ROW2FIFO(screen, row), (void *) result)); return result; } /* * Allocate a new row in the scrollback FIFO, returning a pointer to it. */ LineData * addScrollback(TScreen *screen) { ScrnBuf where = NULL; unsigned ncols = (unsigned) MaxCols(screen); if (screen->saveBuf_index != NULL && screen->savelines != 0) { unsigned which; Char *block; TRACE(("addScrollback %lu\n", screen->saved_fifo)); /* first, see which index we'll use */ which = (unsigned) (screen->saved_fifo % screen->savelines); where = scrnHeadAddr(screen, screen->saveBuf_index, which); /* discard any obsolete index data */ if (screen->saved_fifo > screen->savelines) { LineData *prior = (LineData *) where; /* * setupLineData uses the attribs as the first address used from the * data block. */ if (prior->attribs != NULL) { TRACE(("...freeing prior FIFO data in slot %d: %p->%p\n", which, (void *) prior, (void *) prior->attribs)); FreeAndNull(prior->attribs); } if (screen->saved_fifo > 2 * screen->savelines) { screen->saved_fifo -= screen->savelines; } } /* allocate the new data */ block = allocScrnData(screen, 1, ncols, False); /* record the new data in the index */ setupLineData(screen, where, (Char *) block, 1, ncols, False); TRACE(("...storing new FIFO data in slot %d: %p->%p\n", which, (void *) where, block)); screen->saved_fifo++; } return (LineData *) where; } void deleteScrollback(TScreen *screen) { unsigned which = ROW2FIFO(screen, -1); ScrnBuf where = scrnHeadAddr(screen, screen->saveBuf_index, which); LineData *prior = (LineData *) where; /* * setupLineData uses the attribs as the first address used from the * data block. */ if (prior->attribs != NULL) { TRACE(("...freeing prior FIFO data in slot %d: %p->%p\n", which, (void *) prior, (void *) prior->attribs)); FreeAndNull(prior->attribs); } screen->saved_fifo--; } xterm-399/xterm.man0000644000000000000000000117632414773070576013127 0ustar rootroot'\" t .\" $XTermId: xterm.man,v 1.916 2025/04/01 23:06:38 tom Exp $ .\" .\" Copyright 1996-2024,2025 by Thomas E. Dickey .\" .\" All Rights Reserved .\" .\" Permission is hereby granted, free of charge, to any person obtaining a .\" copy of this software and associated documentation files (the .\" "Software"), to deal in the Software without restriction, including .\" without limitation the rights to use, copy, modify, merge, publish, .\" distribute, sublicense, and/or sell copies of the Software, and to .\" permit persons to whom the Software is furnished to do so, subject to .\" the following conditions: .\" .\" The above copyright notice and this permission notice shall be included .\" in all copies or substantial portions of the Software. .\" .\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS .\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF .\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. .\" IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY .\" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, .\" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE .\" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .\" .\" Except as contained in this notice, the name(s) of the above copyright .\" holders shall not be used in advertising or otherwise to promote the .\" sale, use or other dealings in this Software without prior written .\" authorization. .\" .\" .\" Copyright 1989 X Consortium .\" .\" Permission to use, copy, modify, distribute, and sell this software and its .\" documentation for any purpose is hereby granted without fee, provided that .\" the above copyright notice appear in all copies and that both that .\" copyright notice and this permission notice appear in supporting .\" documentation. .\" .\" The above copyright notice and this permission notice shall be included .\" in all copies or substantial portions of the Software. .\" .\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS .\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF .\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. .\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR .\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, .\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR .\" OTHER DEALINGS IN THE SOFTWARE. .\" .\" Except as contained in this notice, the name of the X Consortium shall .\" not be used in advertising or otherwise to promote the sale, use or .\" other dealings in this Software without prior written authorization .\" from the X Consortium. .\" .\" Updated by Thomas E. Dickey for XFree86, July 1996 - February 2006. .\" .TH XTERM 1 "__app_date__" "__app_version__" "X Window System" .ds N Xterm .ds n xterm .\" .\" Bulleted paragraph .de bP .ie n .IP \(bu 4 .el .IP \(bu 2 .. .ie n .ds CW R .el \{ .ie \n(.g .ds CW CR .el .ds CW CW .\} .\" Like EX/EE, but accounting for paragraph spacing. .de NS .ie n .sp .el .sp .5 .ie n .in +4 .el .in +2 .nf .ft \*(CW .. .de NE .fi .ft R .ie n .in -4 .el .in -2 .. .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g \{\ .ds `` \(lq .ds '' \(rq .ds ' \(aq .\} .el \{\ .ie t .ds `` `` .el .ds `` "" .ie t .ds '' '' .el .ds '' "" .ie t .ds ' \(aq .el .ds ' ' .\}", .SH NAME xterm \- terminal emulator for X .if n .hy 0 .if n .nh .if n .na .SH SYNOPSIS .B \*n [\-\fItoolkitoption\fP \&...\&] [\-\fIoption\fP \&...\&] [\fIshell\fP] .SH DESCRIPTION .hy 0 .nh The \fI\*n\fP program is a terminal emulator for the X Window System. It provides DEC VT102/VT220 and selected features from higher-level terminals such as VT320/VT420/VT520 (VT\fIxxx\fP). It also provides Tektronix 4014 emulation for programs that cannot use the window system directly. If the underlying operating system supports terminal resizing capabilities (for example, the SIGWINCH signal in systems derived from 4.3BSD), \fI\*n\fP will use the facilities to notify programs running in the window whenever it is resized. . .PP The VT\fIxxx\fP and Tektronix 4014 terminals each have their own window so that you can edit text in one and look at graphics in the other at the same time. To maintain the correct aspect ratio (height/width), Tektronix graphics will be restricted to the largest box with a 4014's aspect ratio that will fit in the window. This box is located in the upper left area of the window. . .PP Although both windows may be displayed at the same time, one of them is considered the \*(``active\*('' window for receiving keyboard input and terminal output. This is the window that contains the text cursor. The active window can be chosen through escape sequences, the \fBVT Options\fP menu in the VT\fIxxx\fP window, and the \fBTek Options\fP menu in the 4014 window. . .SH EMULATIONS \fI\*N\fP provides usable emulations of related DEC terminals: .bP VT52 emulation is complete. .bP VT102 emulation is fairly complete, but does not support autorepeat (because that would affect the keyboard used by other X clients). .IP Double-size characters are displayed properly if your font server supports scalable bitmap fonts. .bP VT220 emulation does not support soft fonts, it is otherwise complete. .bP VT420 emulation (the default) supports controls for manipulating rectangles of characters as well as left/right margins. .IP \fI\*N\fP does not support some other features which are not suitable for emulation, e.g., two-sessions. .PP Terminal database (\fIterminfo\fP (5) or \fItermcap\fP (5)) entries that work with \fI\*n\fP include .IP an optional platform-specific entry (\*(``__default_termname__\*(''), .br \*(``xterm\*('', .br \*(``vt102\*('', .br \*(``vt100\*('', .br \*(``ansi\*('' and .br \*(``dumb\*('' .PP \fI\*N\fP automatically searches the terminal database in this order for these entries and then sets the \*(``TERM\*('' variable (and the \*(``TERMCAP\*('' environment variable on a few older systems). The alternatives after \*(``xterm\*('' are very old, from the late 1980s. .PP VT100 and VT102 emulations are commonly equated, though they actually differ. The VT102 provided controls for inserting and deleting lines. .PP Similarly, \*(``ansi\*('' and \*(``vt100\*('' are often equated. These are not really the same. For instance, they use different controls for scrolling (but \fI\*n\fP supports both). These features differ in an \*(``ansi\*('' terminal description from \fI\*n\fP: .TP 8 .B acsc .br Pseudo-graphics (line-drawing) uses a different mapping. .TP 8 .B xenl .br \fI\*N\fP wraps text at the right margin using the VT100 \*(``newline glitch\*('' behavior. .PP Because of the wrapping behavior, you would occasionally have to repaint the screen when using a text editor with the \*(``ansi\*('' description. .PP You may also use descriptions corresponding to the various supported emulations such as \*(``vt220\*('' or \*(``vt420\*('', but should set the terminal emulation level with the \fBdecTerminalID\fP resource. .PP On most systems, \fI\*n\fP will use the terminfo database. Some older systems use termcap. (The \*(``TERMCAP\*('' environment variable is not set if \fI\*n\fP is linked against a terminfo library, since the requisite information is not provided by the termcap emulation of terminfo libraries). . .PP Many of the special \fI\*n\fP features may be modified under program control through a set of escape sequences different from the standard VT\fIxxx\fP escape sequences (see \fIXterm Control Sequences\fP). . .PP The Tektronix 4014 emulation is also fairly good. It supports 12-bit graphics addressing, scaled to the window size. Four different font sizes and five different lines types are supported. There is no write-through or defocused mode support. The Tektronix text and graphics commands are recorded internally by \fI\*n\fP and may be written to a file by sending the COPY escape sequence (or through the \fBTektronix\fP menu; see below). The name of the file will be .NS \*(``COPY\fIyyyy\fR\-\fIMM\fR\-\fIdd\fR.\fIhh\fR:\fImm\fR:\fIss\fR\*('' .NE .PP where .IR yyyy , .IR MM , .IR dd , .IR hh , .I mm and .I ss are the year, month, day, hour, minute and second when the COPY was performed (the file is created in the directory \fI\*n\fP is started in, or the home directory for a login \fI\*n\fP). . .PP Not all of the features described in this manual are necessarily available in this version of \fI\*n\fP. Some (e.g., the non-VT220 extensions) are available only if they were compiled in, though the most commonly-used are in the default configuration. . .SH "OTHER FEATURES" \fI\*N\fP automatically highlights the text cursor when the pointer enters the window (selected) and unhighlights it when the pointer leaves the window (unselected). If the window is the focus window, then the text cursor is highlighted no matter where the pointer is. . .PP In VT\fIxxx\fP mode, there are escape sequences to activate and deactivate an alternate screen buffer, which is the same size as the display area of the window. When activated, the current screen is saved and replaced with the alternate screen. Saving of lines scrolled off the top of the window is disabled until the normal screen is restored. The usual terminal description for \fI\*n\fP allows the visual editor .IR vi (1) to switch to the alternate screen for editing and to restore the screen on exit. A popup menu entry makes it simple to switch between the normal and alternate screens for cut and paste. . .PP In either VT\fIxxx\fP or Tektronix mode, there are escape sequences to change the name of the windows. Additionally, in VT\fIxxx\fP mode, \fI\*n\fP implements the window-manipulation control sequences from \fIdtterm\fP, such as resizing the window, setting its location on the screen. . .PP \fI\*N\fP allows character-based applications to receive mouse events (currently button-press and release events, and button-motion events) as keyboard control sequences. See \fIXterm Control Sequences\fP for details. . .\" *************************************************************************** .SH OPTIONS Because \fI\*n\fP uses the \fIX Toolkit\fP library, it accepts the standard \fIX Toolkit\fP command line options. \fI\*N\fP also accepts many application-specific options. .PP By convention, if an option begins with a \*(``\fB+\fP\*('' instead of a \*(``\fB\-\fP\*('', the option is restored to its default value. .\" *************************************************************************** .PP Most of the \fI\*n\fP options are actually parsed by the \fIX Toolkit\fP, which sets resource values, and overrides corresponding resource-settings in your X resource files. \fI\*N\fP provides the \fIX Toolkit\fP with a table of options. A few of these are marked, telling the \fIX Toolkit\fP to ignore them (\fB\-help\fP, \fB\-version\fP, \fB\-class\fP, \fB\-e\fP, and \fB\-into\fP). After the \fIX Toolkit\fP has parsed the command-line parameters, it removes those which it handles, leaving the specially-marked parameters for \fI\*n\fP to handle. .\" *************************************************************************** .PP These options do not set a resource value, and are handled specially: .TP 8 .B \-version This causes \fI\*n\fP to print a version number to the standard output, and then exit. .TP 8 .B \-help This causes \fI\*n\fP to print out a verbose message describing its options, one per line. The message is written to the standard output. After printing the message, \fI\*n\fP exits. \fI\*N\fP generates this message, sorting it and noting whether a \*(``\fB\-\fIoption\fR\*('' or a \*(``\fB+\fIoption\fR\*('' turns the feature on or off, since some features historically have been one or the other. \fI\*N\fP generates a concise help message (multiple options per line) when an unknown option is used, e.g., .NS \*n \-z .NE .IP If the logic for a particular option such as logging is not compiled into \fI\*n\fP, the help text for that option also is not displayed by the \fB\-help\fP option. .PP The \fB\-version\fP and \fB\-help\fP options are interpreted even if \fI\*n\fP cannot open the display, and are useful for testing and configuration scripts. Along with \fB\-class\fP, they are checked before other options. To do this, \fI\*n\fP has its own (much simpler) argument parser, along with a table of the \fIX Toolkit\fP's built-in list of options. .PP Relying upon the \fIX Toolkit\fP to parse the options and associated values has the advantages of simplicity and good integration with the X resource mechanism. There are a few drawbacks .bP \fI\*N\fP cannot tell easily whether a resource value was set by one of the external resource- or application-defaults files, whether it was set using \fBxrdb\fP(1), or if it was set through the \fB\-xrm\fP option or via some directly relevant command-line option. \fI\*N\fP sees only the end-result: a value supplied when creating its widgets. .bP \fI\*N\fP does not know the order in which particular options and items in resource files are evaluated. Rather, it sees all of the values for a given widget at the same time. In the design of these options, some are deemed more important, and can override other options. .IP The \fIX Toolkit\fP uses patterns (constants and wildcards) to match resources. Once a particular pattern has been used, it will not modify it. To override a given setting, a more-specific pattern must be used, e.g., replacing \*(``*\*('' with \*(``.\*(''. Some poorly-designed resource files are too specific to allow the command-line options to affect the relevant widget values. .bP In a few cases, the \fIX Toolkit\fP combines its standard options in ways which do not work well with \fI\*n\fP. This happens with the color (\fB\-fg\fP, \fB\-bg\fP) and reverse (\fB\-rv\fP) options. \fI\*N\fP makes a special case of these and adjusts its sense of \*(``reverse\*('' to lessen user surprise. .\" *************************************************************************** .PP One parameter (after all options) may be given. That overrides \fI\*n\fP's built-in choice of shell program: .bP If the parameter is not a relative path, i.e., beginning with \*(``./\*('' or \*(``../\*('', \fI\*n\fP looks for the file in the user's PATH. In either case, this check fails if \fI\*n\fP cannot construct an absolute path. .bP If that check fails (or if no such parameter is given), \fI\*n\fP next checks the \*(``SHELL\*('' variable. If that specifies an executable file, \fI\*n\fP will attempt to start that. However, \fI\*n\fP additionally checks if it is a valid shell, and will unset \*(``SHELL\*('' if it is not. .bP If \*(``SHELL\*('' is not set to an executable file, \fI\*n\fP tries to use the shell program specified in the user's password file entry. As before, \fI\*n\fP verifies if this is a valid shell. .bP Finally, if the password file entry does not specify a valid shell, \fI\*n\fP uses \fI/bin/sh\fP. .PP The \fB\-e\fP option cannot be used with this parameter since it uses all parameters following the option. .PP \fI\*N\fP validates shell programs by finding their pathname in the text file \fB/etc/shells\fP. It treats the environment variable \*(``SHELL\*('' specially because (like \*(``TERM\*(''), \fI\*n\fP both reads and updates the variable, and because the program started by \fI\*n\fP is not necessarily a shell. .\" *************************************************************************** .PP The other options are used to control the appearance and behavior. Not all options are necessarily configured into your copy of \fI\*n\fP: .TP 8 .B \-132 Normally, the VT102 DECCOLM escape sequence that switches between 80 and 132 column mode is ignored. This option causes the DECCOLM escape sequence to be recognized, and the \fI\*n\fP window will resize appropriately. .TP 8 .B \-ah This option indicates that \fI\*n\fP should always highlight the text cursor. By default, \fI\*n\fP will display a hollow text cursor whenever the focus is lost or the pointer leaves the window. .TP 8 .B +ah This option indicates that \fI\*n\fP should do text cursor highlighting based on focus. .TP 8 .B \-ai This option disables active icon support if that feature was compiled into \fI\*n\fP. This is equivalent to setting the \fIvt100\fP resource \fBactiveIcon\fP to \*(``false\*(''. .TP 8 .B +ai This option enables active icon support if that feature was compiled into \fI\*n\fP. This is equivalent to setting the \fIvt100\fP resource \fBactiveIcon\fP to \*(``true\*(''. .TP 8 .B \-aw This option indicates that auto-wraparound should be allowed, and is equivalent to setting the \fIvt100\fP resource \fBautoWrap\fP to \*(``true\*(''. .IP Auto-wraparound allows the cursor to automatically wrap to the beginning of the next line when it is at the rightmost position of a line and text is output. .TP 8 .B +aw This option indicates that auto-wraparound should not be allowed, and is equivalent to setting the \fIvt100\fP resource \fBautoWrap\fP to \*(``false\*(''. .TP 8 .BI \-b " number" This option specifies the size of the inner border (the distance between the outer edge of the characters and the window border) in pixels. That is the \fIvt100\fP \fBinternalBorder\fP resource. The default is \*(``2\*(''. .TP 8 .B "\-barc" This option, corresponding to the \fBcursorBar\fP resource, makes the cursor a bar instead of a box. .TP 8 .B "+barc" This option, corresponding to the \fBcursorBar\fP resource, makes the cursor a box instead of a bar. .TP 8 .BI \-baudrate " number" Set the line-speed, used to test the behavior of applications that use the line-speed when optimizing their output to the screen. The default is \*(``38400\*(''. .TP 8 .B \-bc turn on text cursor blinking. This overrides the \fBcursorBlink\fR resource. .TP 8 .B +bc turn off text cursor blinking. This overrides the \fBcursorBlink\fR resource. .TP 8 .BI \-bcf " milliseconds" set the amount of time text cursor is off when blinking via the \fBcursorOffTime\fP resource. .TP 8 .BI \-bcn " milliseconds" set the amount of time text cursor is on when blinking via the \fBcursorOnTime\fP resource. .TP 8 .B "\-bdc" Set the \fIvt100\fP resource \fBcolorBDMode\fR to \*(``false\*('', disabling the display of characters with bold attribute as color. .TP 8 .B "+bdc" Set the \fIvt100\fP resource \fBcolorBDMode\fR to \*(``true\*('', enabling the display of characters with bold attribute as color rather than bold. .TP 8 .B "\-cb" Set the \fIvt100\fP resource \fBcutToBeginningOfLine\fP to \*(``false\*(''. .TP 8 .B "+cb" Set the \fIvt100\fP resource \fBcutToBeginningOfLine\fP to \*(``true\*(''. .TP 8 .B "\-cc \fIcharacterclassrange\fP:\fIvalue\fP[, \&...\&]" This sets classes indicated by the given ranges for using in selecting by words (see \fBCHARACTER CLASSES\fP and the \fBcharClass\fP resource). .TP 8 .B "\-cjk_width" Set the \fBcjkWidth\fP resource to \*(``true\*(''. When turned on, characters with East Asian Ambiguous (A) category in UTR 11 have a column width of 2. Otherwise, they have a column width of 1. This may be useful for some legacy CJK text terminal-based programs assuming box drawings and others to have a column width of 2. It also should be turned on when you specify a TrueType CJK double-width (bi-width/monospace) font either with \fB\-fa\fP at the command line or \fBfaceName\fP resource. The default is \*(``false\*('' .TP 8 .B "+cjk_width" Reset the \fBcjkWidth\fP resource. .TP 8 .BI \-class " string" This option allows you to override \fI\*n\fP's resource class. Normally it is \*(``__default_class__\*('', but can be set to another class such as \*(``U__default_class__\*('' to override selected resources. .IP \fIX Toolkit\fP sets the \fBWM_CLASS\fP property using the instance name and this class value. .TP 8 .B "\-cm" This option disables recognition of ANSI color-change escape sequences. It sets the \fBcolorMode\fP resource to \*(``false\*(''. .TP 8 .B "+cm" This option enables recognition of ANSI color-change escape sequences. This is the same as the \fIvt100\fP resource \fBcolorMode\fP. .TP 8 .B "\-cn" This option indicates that newlines should not be cut in line-mode selections. It sets the \fBcutNewline\fP resource to \*(``false\*(''. .TP 8 .B +cn This option indicates that newlines should be cut in line-mode selections. It sets the \fBcutNewline\fP resource to \*(``true\*(''. .TP 8 .BI \-cr " color" This option specifies the color to use for text cursor. The default is to use the same foreground color that is used for text. It sets the \fBcursorColor\fP resource according to the parameter. .TP 8 .B \-cu This option indicates that \fI\*n\fP should work around a bug in the .BR more (1) program that causes it to incorrectly display lines that are exactly the width of the window and are followed by a line beginning with a tab (the leading tabs are not displayed). This option is so named because it was originally thought to be a bug in the .IR curses (3x) cursor motion package. .TP 8 .B +cu This option indicates that \fI\*n\fP should not work around the .BR more (1) bug mentioned above. .TP 8 .B "\-dc" This option disables the escape sequence to change dynamic colors: the vt100 foreground and background colors, its text cursor color, the pointer cursor foreground and background colors, the Tektronix emulator foreground and background colors, its text cursor color and highlight color. The option sets the \fBdynamicColors\fP option to \*(``false\*(''. .TP 8 .B "+dc" This option enables the escape sequence to change dynamic colors. The option sets the \fBdynamicColors\fP option to \*(``true\*(''. .TP 8 .BI \-e "\fI program \fP[ \fIarguments \fP\&.\|.\|.\& ]\fI" This option specifies the program (and its command line arguments) to be run in the \fI\*n\fP window. It also sets the window title and icon name to be the basename of the program being executed if neither \fI\-T\fP nor \fI\-n\fP are given on the command line. .IP \fBNOTE:\fP This must be the \fBlast option\fP on the command line. .TP 8 .BI \-en " encoding" This option determines the encoding on which \fI\*n\fP runs. It sets the \fBlocale\fR resource. Encodings other than UTF-8 are supported by using \fIluit\fR. The \fB\-lc\fR option should be used instead of \fB\-en\fR for systems with locale support. .TP 8 .BI \-fa " pattern" This option sets the pattern for fonts selected from the FreeType library if support for that library was compiled into \fI\*n\fP. This corresponds to the \fBfaceName\fP resource. When a CJK double-width font is specified, you also need to turn on the \fBcjkWidth\fP resource. .IP If you specify both \fB\-fa\fP and the \fIX Toolkit\fP option \fB\-fn\fP, the \fB\-fa\fP setting overrides the latter. .IP See also the \fBrenderFont\fP resource, which combines with this to determine whether FreeType fonts are initially active. .TP 8 .BI \-fb " font" This option specifies a font to be used when displaying bold text. It sets the \fBboldFont\fR resource. .IP This font must be the same height and width as the normal font, otherwise it is ignored. If only one of the normal or bold fonts is specified, it will be used as the normal font and the bold font will be produced by overstriking this font. .IP See also the discussion of \fBboldMode\fP and \fBalwaysBoldMode\fP resources. .TP 8 .B \-fbb This option indicates that \fI\*n\fP should compare normal and bold fonts bounding boxes to ensure they are compatible. It sets the \fBfreeBoldBox\fP resource to \*(``false\*(''. .TP 8 .B +fbb This option indicates that \fI\*n\fP should not compare normal and bold fonts bounding boxes to ensure they are compatible. It sets the \fBfreeBoldBox\fP resource to \*(``true\*(''. .TP 8 .B \-fbx This option indicates that \fI\*n\fP should not assume that the normal and bold fonts have VT100 line-drawing characters. If any are missing, \fI\*n\fP will draw the characters directly. It sets the \fBforceBoxChars\fP resource to \*(``false\*(''. .TP 8 .B +fbx This option indicates that \fI\*n\fP should assume that the normal and bold fonts have VT100 line-drawing characters. It sets the \fBforceBoxChars\fP resource to \*(``true\*(''. .TP 8 .BI \-fc " fontchoice" Specify the initial font chosen from the font menu. The option value corresponds to the \fBinitialFont\fP resource. .TP 8 .BI \-fd " pattern" This option sets the pattern for double-width fonts selected from the FreeType library if support for that library was compiled into \fI\*n\fP. This corresponds to the \fBfaceNameDoublesize\fP resource. .TP 8 .BI \-fi " font" This option sets the font for active icons if that feature was compiled into \fI\*n\fP. .IP See also the discussion of the \fBiconFont\fP resource. .TP 8 .BI \-fs " size" This option sets the pointsize for fonts selected from the FreeType library if support for that library was compiled into \fI\*n\fP. This corresponds to the \fBfaceSize\fP resource. .TP 8 .B \-fullscreen This option indicates that \fI\*n\fP should ask the window manager to let it use the full-screen for display, e.g., without window decorations. It sets the \fBfullscreen\fP resource to \*(``true\*(''. .TP 8 .B +fullscreen This option indicates that \fI\*n\fP should not ask the window manager to let it use the full-screen for display. It sets the \fBfullscreen\fP resource to \*(``false\*(''. .TP 8 .B \-fw \fIfont\fP This option specifies the font to be used for displaying wide text. By default, it will attempt to use a font twice as wide as the font that will be used to draw normal text. If no double-width font is found, it will improvise, by stretching the normal font. This corresponds to the \fBwideFont\fP resource. .TP 8 .B \-fwb \fIfont\fP This option specifies the font to be used for displaying bold wide text. By default, it will attempt to use a font twice as wide as the font that will be used to draw bold text. If no double-width font is found, it will improvise, by stretching the bold font. This corresponds to the \fBwideBoldFont\fP resource. .TP 8 .B \-fx \fIfont\fP This option specifies the font to be used for displaying the preedit string in the \*(``OverTheSpot\*('' input method. .IP See also the discussion of the \fBximFont\fP resource. .TP 8 .BI \-hc " color" (see \fB\-selbg\fP). .TP 8 .B \-hf This option indicates that HP function key escape codes should be generated for function keys. It sets the \fBhpFunctionKeys\fP resource to \*(``true\*(''. .TP 8 .B +hf This option indicates that HP function key escape codes should not be generated for function keys. It sets the \fBhpFunctionKeys\fP resource to \*(``false\*(''. .TP 8 .B \-hm Tells \fI\*n\fP to use \fBhighlightTextColor\fP and \fBhighlightColor\fP to override the reversed foreground/background colors in a selection. It sets the \fBhighlightColorMode\fP resource to \*(``true\*(''. .TP 8 .B +hm Tells \fI\*n\fP not to use \fBhighlightTextColor\fP and \fBhighlightColor\fP to override the reversed foreground/background colors in a selection. It sets the \fBhighlightColorMode\fP resource to \*(``false\*(''. .TP 8 .B \-hold Turn on the \fBhold\fP resource, i.e., \fI\*n\fP will not immediately destroy its window when the shell command completes. It will wait until you use the window manager to destroy/kill the window, or if you use the menu entries that send a signal, e.g., HUP or KILL. .TP 8 .B +hold Turn off the \fBhold\fP resource, i.e., \fI\*n\fP will immediately destroy its window when the shell command completes. .TP 8 .B \-ie Turn on the \fBptyInitialErase\fP resource, i.e., use the pseudo-terminal's sense of the \fBstty\fP(1) erase value. .TP 8 .B +ie Turn off the \fBptyInitialErase\fP resource, i.e., set the \fIstty\fP erase value using the \fBkb\fP string from the termcap entry as a reference, if available. .TP 8 .B \-im Turn on the \fBuseInsertMode\fP resource, which forces use of insert mode by adding appropriate entries to the TERMCAP environment variable. (This option is ignored on most systems, because TERMCAP is not used). .TP 8 .B +im Turn off the \fBuseInsertMode\fP resource. .TP 8 .BI \-into " windowId" Given an X window identifier (an integer, which can be hexadecimal, octal or decimal according to whether it begins with "0x", "0" or neither), \fI\*n\fP will reparent its top-level shell widget to that window. This is used to embed \fI\*n\fP within other applications. .IP For instance, there are scripts for Tcl/Tk and Gtk which can be used to demonstrate the feature. When using Gtk, there is a limitation of that toolkit which requires that \fI\*n\fP's \fBallowSendEvents\fP resource is enabled. .TP 8 .B "\-itc" Set the \fIvt100\fP resource \fBcolorITMode\fR to \*(``false\*('', disabling the display of characters with italic attribute as color. .TP 8 .B "+itc" Set the \fIvt100\fP resource \fBcolorITMode\fR to \*(``true\*('', enabling the display of characters with italic attribute as color rather than italic. .TP 8 .B \-j This option indicates that \fI\*n\fP should do jump scrolling. It corresponds to the \fBjumpScroll\fP resource. Normally, text is scrolled one line at a time; this option allows \fI\*n\fP to move multiple lines at a time so that it does not fall as far behind. Its use is strongly recommended since it makes \fI\*n\fP much faster when scanning through large amounts of text. The VT100 escape sequences for enabling and disabling smooth scroll as well as the \fBVT Options\fP menu can be used to turn this feature on or off. .TP 8 .B +j This option indicates that \fI\*n\fP should not do jump scrolling. .TP 8 .B \-jf When doing jump-scrolling or related indexing, e.g., carriage returns, \fI\*n\fP will defer flushing screen-updates, to improve speed. This corresponds to the \fBfastScroll\fP resource. .TP 8 .B +jf When doing jump-scrolling or related indexing, e.g., carriage returns, \fI\*n\fP will not defer flushing screen-updates, to improve speed. This corresponds to the \fBfastScroll\fP resource. .TP 8 .B \-k8 This option sets the \fBallowC1Printable\fP resource. When \fBallowC1Printable\fP is set, \fI\*n\fP overrides the mapping of C1 control characters (code 128\(en159) to treat them as printable. .TP 8 .B +k8 This option resets the \fBallowC1Printable\fP resource. .TP 8 .BI \-kt " keyboardtype" This option sets the \fBkeyboardType\fP resource. Possible values include: \*(``unknown\*('', \*(``default\*('', \*(``legacy\*('', \*(``hp\*('', \*(``sco\*('', \*(``sun\*('', \*(``tcap\*('' and \*(``vt220\*(''. .IP The value \*(``unknown\*('', causes the corresponding resource to be ignored. .IP The value \*(``default\*('', suppresses the associated resources .IP \fBhpFunctionKeys\fP, .br \fBscoFunctionKeys\fP, .br \fBsunFunctionKeys\fP, .br \fBtcapFunctionKeys\fP, .br \fBoldXtermFKeys\fP and .br \fBsunKeyboard\fP, .IP using the Sun/PC keyboard layout. .TP 8 .B \-l Turn logging on, unless disabled by the \fBlogInhibit\fP resource. .IP Some versions of \fI\*n\fP may have logging enabled. However, normally logging is not supported, due to security concerns in the early 1990s. That was a problem in X11R4 \fBxterm\fP (1989) which was addressed by a patch to X11R5 late in 1993. X11R6 included these fixes. The older version (when running with \fIroot\fP privilege) would create the log file using \fIroot\fP privilege. The reason why \fI\*n\fP ran with \fIroot\fP privileges was to open pseudo-terminals. Those privileges are now needed only on very old systems: Unix98 pseudo-terminals made the BSD scheme unnecessary. .IP Unless overridden by the \fB\-lf\fP option or the \fBlogFile\fP resource: .RS .bP If the filename is \*(``\-\*('', then logging is sent to the standard output. .bP Otherwise a filename is generated, and the log file is written to the directory from which \fI\*n\fP is invoked. .bP The generated filename is of the form .NS XtermLog.\fIXXXXXX\fR .NE .IP or .NS Xterm.log.\fIhostname.yyyy.mm.dd.hh.mm.ss.XXXXXX\fR .NE .IP depending on how \fI\*n\fP was built. .RE .TP 8 .B +l Turn logging off. .TP 8 .B \-lc Turn on support of various encodings according to the users' locale setting, i.e., LC_ALL, LC_CTYPE, or LANG environment variables. This is achieved by turning on UTF-8 mode and by invoking \fIluit\fR for conversion between locale encodings and UTF-8. (\fIluit\fR is not invoked in UTF-8 locales.) This corresponds to the \fBlocale\fR resource. .IP The actual list of encodings which are supported is determined by \fIluit\fR. Consult the \fIluit\fR manual page for further details. .IP See also the discussion of the \fB\-u8\fP option which supports UTF-8 locales. .TP 8 .B +lc Turn off support of automatic selection of locale encodings. Conventional 8bit mode or, in UTF-8 locales or with \fB\-u8\fP option, UTF-8 mode will be used. .TP 8 .BI \-lcc " path" File name for the encoding converter from/to locale encodings and UTF-8 which is used with \fB\-lc\fP option or \fBlocale\fR resource. This corresponds to the \fBlocaleFilter\fR resource. .TP 8 .B \-leftbar Force scrollbar to the left side of VT100 screen. This is the default, unless you have set the \fBrightScrollBar\fR resource. .TP 8 .BI \-lf " filename" Specify the log filename. This sets the \fBlogFile\fP resource. If set to \*(``\-\*('', \fI\*n\fP writes its log to the standard output. See the \fB\-l\fP option. .TP 8 .B \-ls This option indicates that the shell that is started in the \fI\*n\fP window will be a login shell (i.e., the first character of argv[0] will be a dash, indicating to the shell that it should read the user's \&.login or \&.profile). .IP The \fB\-ls\fP flag and the \fBloginShell\fP resource are ignored if \fB\-e\fP is also given, because \fI\*n\fP does not know how to make the shell start the given command after whatever it does when it is a login shell \- the user's shell of choice need not be a Bourne shell after all. Also, \fI\*n\ \-e\fP is supposed to provide a consistent functionality for other applications that need to start text-mode programs in a window, and if \fBloginShell\fP were not ignored, the result of ~/.profile might interfere with that. .IP If you do want the effect of \fB\-ls\fP and \fB\-e\fP simultaneously, you may get away with something like .NS 15 \*n \-e /bin/bash \-l \-c "my command here" .NE .IP Finally, \fB\-ls\fP is not completely ignored, because \fI\*n\ \-ls\ \-e\fP does write a \fI__wtmp_name__\fP entry (if configured to do so), whereas \fI\*n\ \-e\fP does not. .TP 8 .B +ls This option indicates that the shell that is started should not be a login shell (i.e., it will be a normal \*(``subshell\*(''). .TP 8 .B \-maximized This option indicates that \fI\*n\fP should ask the window manager to maximize its layout on startup. This corresponds to the \fBmaximized\fP resource. .IP Maximizing is not the reverse of iconifying; it is possible to do both with certain window managers. .TP 8 .B +maximized This option indicates that \fI\*n\fP should ask the window manager to not maximize its layout on startup. .TP 8 .B \-mb This option indicates that \fI\*n\fP should ring a margin bell when the user types near the right end of a line. .TP 8 .B +mb This option indicates that margin bell should not be rung. .TP 8 .BI \-mc " milliseconds" This option specifies the maximum time between multi-click selections. .TP 8 .B \-mesg Turn off the \fBmessages\fP resource, i.e., disallow write access to the terminal. .TP 8 .B +mesg Turn on the \fBmessages\fP resource, i.e., allow write access to the terminal. .TP 8 .B "\-mk_width" Set the \fBmkWidth\fP resource to \*(``true\*(''. This makes \fI\*n\fP use a built-in version of the wide-character width calculation. The default is \*(``false\*('' .TP 8 .B "+mk_width" Reset the \fBmkWidth\fP resource. .TP 8 .BI \-ms " color" This option specifies the color to be used for the pointer cursor. The default is to use the foreground color. This sets the \fBpointerColor\fP resource. .TP 8 .BI \-nb " number" This option specifies the number of characters from the right end of a line at which the margin bell, if enabled, will ring. The default is \*(``10\*(''. .TP 8 .B "\-nomap" This option disables the initial \fImapping\fP of the terminal window. Mapping an X window makes it visible if it is \fImanaged\fP. The default is \*(``false\*('' because \fI\*n\fP's window is normally displayed on startup. .IP After startup, an unmapped \fI\*n\fP window can be mapped by identifying its window-id, e.g., using \fBxwininfo\fP(1) or \fBxlsclients\fP(1), and then employing another program such as \fBxdotool\fP(1) to ask the window manager to make it visible. .IP If the \fI\*n\fP window is visible (i.e., mapped), \fI\*n\fP's menus and actions (i.e., \fBset\-visibility\fP) allow one to select whether the VT100 or Tek4014 windows should be displayed. .TP 8 .B "+nomap" This option enables the initial \fImapping\fP of the terminal window. This is the default behavior. .TP 8 .B "\-nul" This option disables the display of underlining. .TP 8 .B "+nul" This option enables the display of underlining. .TP 8 .B \-pc This option enables the PC-style use of bold colors (see \fBboldColors\fP resource). .TP 8 .B +pc This option disables the PC-style use of bold colors. .TP 8 .B \-pf \fIfont\fP This option specifies the font to be used for the pointer. The corresponding resource name is \fIpointerFont\fP. The resource value default is \fIcursor\fP. .TP 8 .B \-pob This option indicates that the window should be raised whenever a Control-G is received. .TP 8 .B +pob This option indicates that the window should not be raised whenever a Control-G is received. .TP 8 .B \-report\-charclass Print a report to the standard output showing information about the character-classes which can be altered using the \fBcharClass\fP resource. .TP 8 .B \-report\-colors Print a report to the standard output showing information about colors as \fI\*n\fP allocates them. This corresponds to the \fBreportColors\fP resource. .TP 8 .B \-report\-fonts Print a report to the standard output showing information about fonts which are loaded. This corresponds to the \fBreportFonts\fP resource. .TP 8 .B \-report\-icons Print a report to the standard output showing information about pixmap-icons which are loaded. This corresponds to the \fBreportIcons\fP resource. .TP 8 .B \-report\-xres Print a report to the standard output showing the values of boolean, numeric or string X resources for the VT100 widget when initialization is complete. This corresponds to the \fBreportXRes\fP resource. .TP 8 .B \-rightbar Force scrollbar to the right side of VT100 screen. .TP 8 .B "\-rvc" This option disables the display of characters with reverse attribute as color. .TP 8 .B "+rvc" This option enables the display of characters with reverse attribute as color. .TP 8 .B \-rw This option indicates that reverse-wraparound should be allowed. This allows the cursor to back up from the leftmost column of one line to the rightmost column of the previous line. This is very useful for editing long shell command lines and is encouraged. This option can be turned on and off from the \fBVT Options\fP menu. .TP 8 .B +rw This option indicates that reverse-wraparound should not be allowed. .TP 8 .B \-s This option indicates that \fI\*n\fP may scroll asynchronously, meaning that the screen does not have to be kept completely up to date while scrolling. This allows \fI\*n\fP to run faster when network latencies are very high and is typically useful when running across a very large internet or many gateways. .TP 8 .B +s This option indicates that \fI\*n\fP should scroll synchronously. .TP 8 .B \-samename Does not send title and icon name change requests when the request would have no effect: the name is not changed. This has the advantage of preventing flicker and the disadvantage of requiring an extra round trip to the server to find out the previous value. In practice this should never be a problem. .TP 8 .B +samename Always send title and icon name change requests. .TP 8 .B \-sb This option indicates that some number of lines that are scrolled off the top of the window should be saved and that a scrollbar should be displayed so that those lines can be viewed. This option may be turned on and off from the \fBVT Options\fP menu. .TP 8 .B +sb This option indicates that a scrollbar should not be displayed. .TP 8 .BI \-selbg " color" This option specifies the color to use for the background of selected text. If not specified, reverse video is used. See the discussion of the \fBhighlightColor\fP resource. .TP 8 .BI \-selfg " color" This option specifies the color to use for selected text. If not specified, reverse video is used. See the discussion of the \fBhighlightTextColor\fP resource. .TP 8 .B \-sf This option indicates that Sun function key escape codes should be generated for function keys. .TP 8 .B +sf This option indicates that the standard escape codes should be generated for function keys. .TP 8 .BI \-sh " number" scale line-height values by the given number. See the discussion of the \fBscaleHeight\fP resource. .TP 8 .B \-si This option indicates that output to a window should not automatically reposition the screen to the bottom of the scrolling region. This option can be turned on and off from the \fBVT Options\fP menu. .TP 8 .B +si This option indicates that output to a window should cause it to scroll to the bottom. .TP 8 .B \-sk This option indicates that pressing a key while using the scrollbar to review previous lines of text should cause the window to be repositioned automatically in the normal position at the bottom of the scroll region. .TP 8 .B +sk This option indicates that pressing a key while using the scrollbar should not cause the window to be repositioned. .TP 8 .BI \-sl " number" This option specifies the number of lines to save that have been scrolled off the top of the screen. This corresponds to the \fBsaveLines\fP resource. The default is \*(``1024\*(''. .TP 8 .B \-sm This option, corresponding to the \fBsessionMgt\fR resource, indicates that \fI\*n\fR should set up session manager callbacks. .TP 8 .B +sm This option indicates that \fI\*n\fR should not set up session manager callbacks. .TP 8 .B \-sp This option indicates that Sun/PC keyboard should be assumed, providing mapping for keypad \*(``+\*('' to \*(``,\*('', and CTRL-F1 to F13, CTRL-F2 to F14, etc. .TP 8 .B +sp This option indicates that the standard escape codes should be generated for keypad and function keys. .TP 8 .B \-t This option indicates that \fI\*n\fP should start in Tektronix mode, rather than in VT\fIxxx\fP mode. Switching between the two windows is done using the \*(``Options\*('' menus. .IP Terminal database (\fIterminfo\fP (5) or \fItermcap\fP (5)) entries that work with \fI\*n\fR are: .IP \*(``tek4014\*('', .br \*(``tek4015\*('', .br \*(``tek4012\*('', .br \*(``tek4013\*('', .br \*(``tek4010\*('', and .br \*(``dumb\*(''. .IP \fI\*N\fP automatically searches the terminal database in this order for these entries and then sets the \*(``TERM\*('' variable (and the \*(``TERMCAP\*('' environment variable, if relevant). .TP 8 .B +t This option indicates that \fI\*n\fP should start in VT\fIxxx\fP mode. .TP 8 .B \-tb This option, corresponding to the \fBtoolBar\fR resource, indicates that \fI\*n\fR should display a toolbar (or menubar) at the top of its window. The buttons in the toolbar correspond to the popup menus, e.g., control/left/mouse for \fBMain Options\fP. .TP 8 .B +tb This option indicates that \fI\*n\fR should not set up a toolbar. .TP 8 .BI \-ti " term_id" Specify the name used by \fI\*n\fP to select the correct response to terminal ID queries. It also specifies the emulation level, used to determine the type of response to a DA control sequence. Valid values include vt52, vt100, vt101, vt102, vt220, and vt240 (the \*(``vt\*('' is optional). The default is \*(``vt__default_termid__\*(''. The \fIterm_id\fP argument specifies the terminal ID to use. (This is the same as the \fBdecTerminalID\fP resource). .TP 8 .BI \-tm " string" This option specifies a series of terminal setting keywords followed by the characters that should be bound to those functions, similar to the \fBstty\fP(1) program. The keywords and their values are described in detail in the \fBttyModes\fP resource. .TP 8 .BI \-tn " name" This option specifies the name of the terminal type to be set in the TERM environment variable. It corresponds to the \fBtermName\fP resource. This terminal type must exist in the terminal database (termcap or terminfo, depending on how \fI\*n\fP is built) and should have \fIli#\fP and \fIco#\fP entries. If the terminal type is not found, \fI\*n\fP uses the built-in list \*(``xterm\*('', \*(``vt102\*('', etc. .TP 8 .B \-u8 This option sets the \fButf8\fP resource. When \fButf8\fP is set, \fI\*n\fP interprets incoming data as UTF-8. This sets the \fBwideChars\fP resource as a side-effect, but the UTF-8 mode set by this option prevents it from being turned off. If you must turn UTF-8 encoding on and off, use the \fB\-wc\fP option or the corresponding \fBwideChars\fP resource, rather than the \fB\-u8\fP option. .IP This option and the \fButf8\fR resource are overridden by the \fB\-lc\fP and \fB\-en\fP options and \fBlocale\fR resource. That is, if \fI\*n\fP has been compiled to support \fIluit\fR, and the \fBlocale\fP resource is not \*(``false\*('' this option is ignored. We recommend using the \fB\-lc\fR option or the \*(``\fBlocale:\ true\fR\*('' resource in UTF-8 locales when your operating system supports locale, or \fB\-en\ UTF\-8\fP option or the \*(``\fBlocale:\ UTF\-8\fR\*('' resource when your operating system does not support locale. .TP 8 .B +u8 This option resets the \fButf8\fP resource. .TP 8 .B "\-uc" This option, corresponding to the \fBcursorUnderLine\fP resource, makes the cursor underlined instead of a box. .TP 8 .B "+uc" This option m, corresponding to the \fBcursorUnderLine\fP resource, akes the cursor a box instead of underlined. .TP 8 .B "\-ulc" This option disables the display of characters with underline attribute as color rather than with underlining. .TP 8 .B "+ulc" This option enables the display of characters with underline attribute as color rather than with underlining. .TP 8 .B "\-ulit" This option, corresponding to the \fBitalicULMode\fP resource, disables the display of characters with underline attribute as italics rather than with underlining. .TP 8 .B "+ulit" This option, corresponding to the \fBitalicULMode\fP resource, enables the display of characters with underline attribute as italics rather than with underlining. .TP 8 .B \-ut This option indicates that \fI\*n\fP should not write a record into the system \fI__utmp_name__\fP log file. .TP 8 .B +ut This option indicates that \fI\*n\fP should write a record into the system \fI__utmp_name__\fP log file. .TP 8 .B \-vb This option indicates that a visual bell is preferred over an audible one. Instead of ringing the terminal bell whenever a Control-G is received, the window will be flashed. .TP 8 .B +vb This option indicates that a visual bell should not be used. .TP 8 .B \-wc This option sets the \fBwideChars\fP resource. .IP When \fBwideChars\fP is set, \fI\*n\fP maintains internal structures for 16-bit characters. If \fI\*n\fP is not started in UTF-8 mode (or if this resource is not set), initially it maintains those structures to support 8-bit characters. \fI\*N\fP can later be switched, using a menu entry or control sequence, causing it to reallocate those structures to support 16-bit characters. .IP The default is \*(``false\*(''. .TP 8 .B +wc This option resets the \fBwideChars\fP resource. .TP 8 .B \-wf This option indicates that \fI\*n\fP should wait for the window to be mapped the first time before starting the subprocess so that the initial terminal size settings and environment variables are correct. It is the application's responsibility to catch subsequent terminal size changes. .TP 8 .B +wf This option indicates that \fI\*n\fP should not wait before starting the subprocess. .TP 8 .B \-ziconbeep \fIpercent\fP Same as \fBzIconBeep\fP resource. If percent is non-zero, xterms that produce output while iconified will cause an XBell sound at the given volume and have \*(``***\*('' prepended to their icon titles. Most window managers will detect this change immediately, showing you which window has the output. (A similar feature was in x10 \fI\*n\fP.) .TP 8 .B \-C This option indicates that this window should receive console output. This is not supported on all systems. To obtain console output, you must be the owner of the console device, and you must have read and write permission for it. If you are running X under \fIxdm\fP on the console screen you may need to have the session startup and reset programs explicitly change the ownership of the console device in order to get this option to work. .TP 8 .B \-S\fIccn\fP This option allows \fI\*n\fP to be used as an input and output channel for an existing program and is sometimes used in specialized applications. The option value specifies the last few letters of the name of a pseudo-terminal to use in slave mode, plus the number of the inherited file descriptor. If the option contains a \*(``/\*('' character, that delimits the characters used for the pseudo-terminal name from the file descriptor. Otherwise, exactly two characters are used from the option for the pseudo-terminal name, the remainder is the file descriptor. Examples (the first two are equivalent since the descriptor follows the last \*(``/\*(''): .NS 15 \-S/dev/pts/123/45 \-S123/45 \-Sab34 .NE .IP Note that \fI\*n\fP does not close any file descriptor which it did not open for its own use. It is possible (though probably not portable) to have an application which passes an open file descriptor down to \fI\*n\fP past the initialization or the \fB\-S\fP option to a process running in the \fI\*n\fP. .SS "Old Options" The following command line arguments are provided for compatibility with older versions. They may not be supported in the next release as the \fIX Toolkit\fP provides standard options that accomplish the same task. .TP 8 .B "%\fIgeom\fP" This option specifies the preferred size and position of the Tektronix window. It is shorthand for specifying the \*(``\fBtekGeometry\fP\*('' resource. .TP 8 .B "#\fIgeom\fP" This option specifies the preferred position of the icon window. It is shorthand for specifying the \*(``\fBiconGeometry\fP\*('' resource. .TP 8 .BI \-T " string" This option specifies the title for \fI\*n\fP's windows. It is equivalent to \fB\-title\fP. .TP 8 .BI \-n " string" This option specifies the icon name for \fI\*n\fP's windows. It is shorthand for specifying the \*(``\fBiconName\fP\*('' resource. Note that this is not the same as the \fIX Toolkit\fP option \fB\-name\fP. The default icon name is the application name. .IP If no suitable icon is found, \fI\*n\fP provides a compiled-in pixmap. .IP \fIX Toolkit\fP sets the \fBWM_ICON_NAME\fP property using this value. .TP 8 .B \-r This option indicates that reverse video should be simulated by swapping the foreground and background colors. It is equivalent to \fB\-rv\fP. .TP 8 .BI \-w " number" This option specifies the width in pixels of the border surrounding the window. It is equivalent to \fB\-borderwidth\fP or \fB\-bw\fP. . .SS "X Toolkit Options" The following standard \fIX Toolkit\fP command line arguments are commonly used with \fI\*n\fP: .TP 8 .B \-bd \fIcolor\fP This option specifies the color to use for the border of the window. The corresponding resource name is \fBborderColor\fP. \fI\*N\fP uses the \fIX Toolkit\fP default, which is \*(``XtDefaultForeground\*(''. .IP \fI\*N\fP's VT100 window has two borders: the \fIinner\fP border \fBinternalBorder\fP and the \fIouter\fP border \fBborderWidth\fP, managed by the \fIX Toolkit\fP. .IP Normally \fI\*n\fP fills the inner border using the VT100 window's background color. If the \fBcolorInnerBorder\fP resource is enabled, then \fI\*n\fP may fill the inner border using the \fBborderColor\fP resource. .TP 8 .B \-bg \fIcolor\fP This option specifies the color to use for the background of the window. The corresponding resource name is \fIbackground\fP. The default is \*(``XtDefaultBackground\*(''. .TP 8 .B \-bw \fInumber\fP This option specifies the width in pixels of the border surrounding the window. .IP This appears to be a legacy of older X releases. It sets the \fBborderWidth\fP resource of the shell widget, and may provide advice to your window manager to set the thickness of the window frame. Most window managers do not use this information. See the \fB\-b\fP option, which controls the inner border of the \fI\*n\fP window. .TP 8 .B \-display \fIdisplay\fP This option specifies the X server to contact; see X(__miscmansuffix__). .TP 8 .B \-fg \fIcolor\fP This option specifies the color to use for displaying text. The corresponding resource name is \fIforeground\fP. The default is \*(``XtDefaultForeground\*(''. .TP 8 .B \-fn \fIfont\fP This option specifies the font to be used for displaying normal text. The corresponding resource name is \fIfont\fP. The resource value default is \fIfixed\fP. .IP \fI\*N\fP's \fB\-fn\fP option accepts a comma-separated list like \fB\-fa\fP, for the VT100 widget, using the first bitmap font (and discarding additional fonts). However, other widgets (such as the toolbar) will be confused by this and give a warning. .TP 8 .B \-font \fIfont\fP This is the same as \fB\-fn\fP. .TP 8 .B \-geometry \fIgeometry\fP This option specifies the preferred size and position of the VT\fIxxx\fP window; see X(__miscmansuffix__). .IP The normal geometry specification can be suffixed with \fB@\fP followed by a Xinerama screen specification; it can be either \fBg\fP for the global screen (default), \fBc\fP for the current screen or a screen number. .TP 8 .B \-iconic .br This option indicates that \fI\*n\fP should ask the window manager to start it as an icon rather than as the normal window. The corresponding resource name is \fIiconic\fP. .TP 8 .B \-name \fIname\fP This option specifies the application name under which resources are to be obtained, rather than the default executable file name. \fIName\fP should not contain \*(``.\*('' or \*(``*\*('' characters. .TP 8 .B \-rv This option indicates that reverse video should be simulated by swapping the foreground and background colors. The corresponding resource name is \fBreverseVideo\fP. .TP 8 .B +rv Disable the simulation of reverse video by swapping foreground and background colors. .TP 8 .B \-title \fIstring\fP This option specifies the window title string, which may be displayed by window managers if the user so chooses. It is shorthand for specifying the \*(``\fBtitle\fP\*('' resource. The default title is the command line specified after the \fB\-e\fP option, if any, otherwise the application name. .IP \fIX Toolkit\fP sets the \fBWM_NAME\fP property using this value. .TP 8 .B \-xrm \fIresourcestring\fP This option specifies a resource string to be used. This is especially useful for setting resources that do not have separate command line options. .PP \fIX Toolkit\fP accepts alternate names for a few of these options, e.g., .bP \*(``\fB\-background\fP\*('' for \*(``\fB\-bg\fP\*('' .bP \*(``\fB\-font\fP\*('' for \*(``\fB\-fn\fP\*('' .bP \*(``\fB\-foreground\fP\*('' for \*(``\fB\-fg\fP\*('' .PP Abbreviated options also are supported, e.g., \*(``\fB\-v\fP\*('' for \*(``\fB\-version\fP.\*('' . . .SH RESOURCES \fI\*N\fP understands all of the core \fIX Toolkit\fP resource names and classes. It also uses the \fIX Toolkit\fP resource types (such as booleans, colors, fonts, integers, and strings) along with their respective converters. Those resource types are not always sufficient: .bP \fI\*N\fP's resource values may be lists of names. \fIX Toolkit\fP resource types do not include lists. \fI\*N\fP uses a string for the resource, and parses it. .IP Comma-separated lists of names ignore case. .bP \fI\*N\fP may defer processing a resource until it is needed. For example, \fBfont2\fP through \fBfont7\fP are loaded as needed, to start faster. Again, the actual resource type is a string, parsed and used when needed. .PP Application specific resources (e.g., \*(``\fB__default_class__.\fINAME\fR\*('') follow: .SS "Application Resources" .TP 8 .B "backarrowKeyIsErase\fP (class\fB BackarrowKeyIsErase\fP)" Tie the VT\fIxxx\fP \fBbackarrowKey\fP and \fBptyInitialErase\fP resources together by setting the DECBKM state according to whether the \fIinitial erase\fP character is a backspace (8) or delete (127) character. A \*(``false\*('' value disables this feature. The default is \*(``__backarrow_is_erase__\*(''. .IP Here are tables showing how the initial settings for .RS .bP .B backarrowKeyIsErase\fP (BKIE), .bP .B backarrowKey\fP (BK), and .bP .B ptyInitialErase\fP (PIE), along with the .bP \fIstty\fP erase character (^H for backspace, ^?\& for delete) .RE .IP will affect DECBKM. First, \fI\*n\fP obtains the initial \fIerase\fP character: .RS .bP \fI\*n\fP's internal value is ^H .bP \fI\*n\fP asks the operating system for the value which \fBstty\fP(1) shows .bP the \fBttyModes\fP resource may override \fIerase\fP .bP if \fBptyInitialErase\fP is false, \fI\*n\fP will look in the terminal database .RE .IP Summarizing that as a table: .TS l l l l _ _ _ _ l c c c. \fBPIE\fR \fBstty\fR \fBtermcap\fR \fIerase\fP false ^H ^H ^H false ^H ^? ^? false ^? ^H ^H false ^? ^? ^? true ^H ^H ^H true ^H ^? ^H true ^? ^H ^? true ^? ^? ^? .TE .IP Using that \fIerase\fP character, \fI\*n\fP allows further choices: .RS .bP if \fBbackarrowKeyIsErase\fP is true, \fI\*n\fP uses the \fIerase\fP character for the initial state of \fBDECBKM\fP .bP if \fBbackarrowKeyIsErase\fP is false, \fI\*n\fP sets \fBDECBKM\fP to 2 (internal). This ties together \fBbackarrowKey\fP and the control sequence for \fBDECBKM\fP. .bP applications can send a control sequence to set/reset \fBDECBKM\fP control set .bP the \*(``Backarrow Key (BS/DEL)\*('' menu entry toggles \fBDECBKM\fP .RE .IP Summarizing the initialization details: .TS l l l l l _ _ _ _ _ c l l c c. \fIerase\fR \fBBKIE\fR \fBBK\fR \fBDECBKM\fP \fIresult\fP ^? false false 2 ^H ^? false true 2 ^? ^? true false 0 ^? ^? true true 1 ^? ^H false false 2 ^H ^H false true 2 ^? ^H true false 0 ^H ^H true true 1 ^H .TE .TP 8 .B "buffered\fP (class\fB Buffered\fP)" Normally \fI\*n\fP is built with double-buffer support. This resource can be used to turn it on or off. Setting the resource to \*(``true\*('' turns double-buffering on. The default value is \*(``__double_buffer__\*(''. .TP 8 .B "bufferedFPS\fP (class\fB BufferedFPS\fP)" When \fI\*n\fP is built with double-buffer support, this gives the maximum number of frames/second. The default is \*(``40\*('' and is limited to the range 1 through 100. .TP 8 .B "cursorTheme\fP (class\fB CursorTheme\fP)" The Xcursor(__miscmansuffix__) library provides a way to change the pointer shape and size. The X11 library uses this library to extend the font- and glyph-cursor calls used by applications such as \fI\*n\fP to substitute external files for the built-in \*(``core\*('' cursors provided by X. .IP \fI\*N\fP uses the \fBpointerShape\fP resource to select the X cursor shape. Most of the available sets of cursor themes provide an incomplete set of \*(``core\*('' cursors (while possibly adding other cursors). Because of this limitation, \fI\*n\fP disables the feature by default. .IP The cursor theme feature can be useful because X cursors are not scalable and on a high-resolution display, the cursors are hard to find. Some of the cursor themes include larger cursors to work around this limitation: .RS .bP The default core cursors are 8x8 pixels; .bP Some cursor themes include cursors up to the X server limit of 64x64 pixels. .RE .IP At startup, \fI\*n\fP sets the \fBXCURSOR_THEME\fP environment variable to enable or disable the cursor theme feature. The default value is \*(``none\*(''. Other values (including \*(``default\*('') are passed to the Xcursor library to select a cursor theme. .TP 8 .B "fullscreen\fP (class\fB Fullscreen\fP)" Specifies whether or not \fI\*n\fP should ask the window manager to use a fullscreen layout on startup. \fI\*N\fP accepts either a keyword (ignoring case) or the number shown in parentheses: .RS .TP 3 false (0) Fullscreen layout is not used initially, but may be later via menu-selection or control sequence. .TP 3 true (1) Fullscreen layout is used initially, but may be disabled later via menu-selection or control sequence. .TP 3 always (2) Fullscreen layout is used initially, and cannot be disabled later via menu-selection or control sequence. .TP 3 never (3) Fullscreen layout is not used, and cannot be enabled later via menu-selection or control sequence. .RE .IP The default is \*(``false\*(''. .TP 8 .B "hold\fP (class\fB Hold\fP)" If true, \fI\*n\fP will not immediately destroy its window when the shell command completes. It will wait until you use the window manager to destroy/kill the window, or if you use the menu entries that send a signal, e.g., HUP or KILL. You may scroll back, select text, etc., to perform most graphical operations. Resizing the display will lose data, however, since this involves interaction with the shell which is no longer running. .TP 8 .B "hpFunctionKeys\fP (class\fB HpFunctionKeys\fP)" Specifies whether or not HP function key escape codes should be generated for function keys. The default is \*(``false\*('', i.e., this feature is disabled. .IP The \fBkeyboardType\fP resource is the preferred mechanism for selecting this mode. .TP 8 .B "iconGeometry\fP (class\fB IconGeometry\fP)" Specifies the preferred size and position of the application when iconified. It is not necessarily obeyed by all window managers. .TP 8 .B "iconHint\fP (class\fB IconHint\fP)" Specifies an icon which will be added to the window manager hints. \fI\*N\fP provides no default value. .IP Set this resource to \*(``none\*('' to omit the hint entirely, using whatever the window manager may decide. .IP If the \fBiconHint\fP resource is given (or is set via the \fB\-n\fP option) \fI\*n\fP searches for a pixmap file with that name, in the current directory as well as in __pixmapsdir__. if the resource does not specify an absolute pathname. In each case, \fI\*n\fP adds \*(``_48x48\*('' and/or \*(``.xpm\*('' to the filename after trying without those suffixes. If it is able to load the file, \fI\*n\fP sets the window manager hint for the icon-pixmap. These pixmaps are distributed with \fI\*n\fP, and can optionally be compiled-in: .RS .bP mini.\*n_16x16, mini.\*n_32x32, mini.\*n_48x48 .bP filled\-\*n_16x16, filled\-\*n_32x32, filled\-\*n_48x48 .bP \*n_16x16, \*n_32x32, \*n_48x48 .bP \*n\-color_16x16, \*n\-color_32x32, \*n\-color_48x48 .RE .IP In either case, \fI\*n\fP allows for adding a \*(``_48x48\*('' to specify the largest of the pixmaps as a default. That is, \*(``mini.\*n\*('' is the same as \*(``mini.\*n_48x48\*(''. .IP If no explicit \fBiconHint\fP resource is given (or if none of the compiled-in names matches), \fI\*n\fP uses \*(``mini.\*n\*('' (which is always compiled-in). .IP The \fBiconHint\fP resource has no effect on \*(``desktop\*('' files, including \*(``panel\*('' and \*(``menu\*(''. Those are typically set via a \*(``.desktop\*('' file; \fI\*n\fP provides samples for itself (and the \fIu\*n\fP script). The more capable desktop systems allow changing the icon on a per-user basis. .TP 8 .B "iconName\fP (class\fB IconName\fP)" Specifies a label for \fI\*n\fP when iconified. \fI\*N\fP provides no default value; some window managers may assume the application name, e.g., \*(``\*n\*(''. .IP Setting the \fBiconName\fP resource sets the icon label unless overridden by \fBzIconBeep\fP or the control sequences which change the window and icon labels. .TP 8 .B "keyboardType\fP (class\fB KeyboardType\fP)" Enables one (or none) of the various keyboard-type resources: \fBhpFunctionKeys\fP, \fBscoFunctionKeys\fP, \fBsunFunctionKeys\fP, \fBtcapFunctionKeys\fP, \fBoldXtermFKeys\fP and \fBsunKeyboard\fP. .IP The resource's value should be one of the corresponding strings \*(``hp\*('', \*(``sco\*('', \*(``sun\*('', \*(``tcap\*('', \*(``legacy\*('' or \*(``vt220\*('', respectively. .IP The individual resources are provided for legacy support; this resource is simpler to use. \fI\*N\fP will use only one keyboard-type, but if multiple resources are set, it warns and uses the last one it checks. .IP The default is \*(``unknown\*('', i.e., none of the associated resources are set via this resource. .TP 8 .B "maxBufSize\fP (class\fB MaxBufSize\fP)" Specify the maximum size of the input buffer. The default is \*(``32768\*(''. You cannot set this to a value less than the \fBminBufSize\fR resource. It will be increased as needed to make that value evenly divide this one. .IP On some systems you may want to increase one or both of the \fBmaxBufSize\fP and \fBminBufSize\fP resource values to achieve better performance if the operating system prefers larger buffer sizes. .TP 8 .B "maximized\fP (class\fB Maximized\fP)" Specifies whether or not \fI\*n\fP should ask the window manager to maximize its layout on startup. The default is \*(``false\*(''. .TP 8 .B "menuHeight\fP (class\fB MenuHeight\fP)" Specifies the height of the toolbar, which may be increased by the \fIX Toolkit\fP Layout widget depending upon the fontsize used. The default is \*(``25\*(''. .TP 8 .B "menuLocale\fP (class\fB MenuLocale\fP)" Specify the locale used for character-set computations when loading the popup menus. Use this to improve initialization performance of the \fIAthena\fP popup menus, which may load unnecessary (and very large) fonts, e.g., in a locale having UTF-8 encoding. The default is \*(``C\*('' (POSIX). .IP To use the current locale (only useful if you have localized the resource settings for the menu entries), set the resource to an empty string. .TP 8 .B "messages\fP (class\fB Messages\fP)" Specifies whether write access to the terminal is allowed initially. See \fBmesg\fP(1). The default is \*(``true\*(''. .TP 8 .B "minBufSize\fP (class\fB MinBufSize\fP)" Specify the minimum size of the input buffer, i.e., the amount of data that \fI\*n\fR requests on each read. The default is \*(``4096\*(''. You cannot set this to a value less than 64. .TP 8 .B "omitTranslation\fP (class\fB OmitTranslation\fP)" Selectively omit one or more parts of \fI\*n\fP's default translations at startup. The resource value is a comma-separated list of keywords, which may be abbreviated: .RS .TP default ignore (mouse) button-down events which were not handled by other translations .TP fullscreen assigns a key-binding to the \fBfullscreen()\fP action. .TP keypress assigns keypresses by default to the \fBinsert\-seven\-bit()\fP and \fBinsert\-eight\-bit()\fP actions. .TP paging assigns key bindings to the \fBscroll\-back()\fP and \fBscroll\-forw()\fP actions. .TP pointer assigns pointer \fImotion\fP and \fIbutton\fP events to the \fBpointer\-motion()\fP and \fBpointer\-button()\fP actions respectively. .TP popup-menu assigns mouse-buttons with the \fIcontrol\fP modifier to the popup-menus. .TP reset assigns mouse-button 2 with the \fImeta\fP modifier to the \fBclear\-saved\-lines\fP action. .TP scroll\-lock assigns a key\-binding to the \fBscroll\-lock()\fP action. .TP block\-select an optional (compile-time) feature for supporting rectangular selections. By default, this is bound to \fIMeta button one\fP. .TP select assigns mouse- and keypress-combinations to actions which manipulate the selection. .IP \fI\*N\fP also uses these actions to capture mouse button and motion events which can be manipulated with the mouse protocol control sequences. If the \fIselect\fP translations are omitted, then the \fBpointer\-motion\fP and \fBpointer\-button\fP handle these mouse protocol control sequences instead. .TP shift\-fonts assigns key-bindings to \fBlarger\-vt\-font()\fP and \fBsmaller\-vt\-font()\fP actions. .TP wheel\-mouse assigns buttons 4 and 5 with different modifiers to the \fBscroll\-back()\fP and \fBscroll\-forw()\fP actions. .RE .TP 8 .B ptyHandshake\fP (class\fB PtyHandshake\fP) If \*(``true\*('', \fI\*n\fP will perform handshaking during initialization to ensure that the parent and child processes update the \fI__utmp_name__\fP and \fBstty\fP(1) state. .IP See also \fBwaitForMap\fP which waits for the pseudo-terminal's notion of the screen size, and \fBptySttySize\fP which resets the screen size after other terminal initialization is complete. The default is \*(``true\*(''. .TP 8 .B ptyInitialErase\fP (class\fB PtyInitialErase\fP) If \*(``true\*('', \fI\*n\fP will use the pseudo-terminal's sense of the \fIstty\fP erase value. If \*(``false\*('', \fI\*n\fP will set the \fIstty\fP erase value to match its own configuration, using the \fBkb\fP string from the termcap entry as a reference, if available. .IP In either case, the result is applied to the TERMCAP variable which \fI\*n\fP sets, if the system uses TERMCAP. .IP See also the \fBttyModes\fP resource, which may override this. The default is \*(``__initial_erase__\*(''. .TP 8 .B ptySttySize\fP (class\fB PtySttySize\fP) If \*(``true\*('', \fI\*n\fP will reset the screen size after terminal initialization is complete. This is needed for some systems whose pseudo-terminals cannot propagate terminal characteristics. Where it is not needed, it can interfere with other methods for setting the initial screen size, e.g., via window manager interaction. .IP See also \fBwaitForMap\fP which waits for a handshake-message giving the pseudo-terminal's notion of the screen size. The default is \*(``false\*('' on Linux and macOS systems, \*(``true\*('' otherwise. .TP 8 .B "reportColors\fP (class\fB ReportColors\fP)" If true, \fI\*n\fP will print to the standard output a summary of colors as it allocates them. The default is \*(``false\*(''. .TP 8 .B "reportFonts\fP (class\fB ReportFonts\fP)" If true, \fI\*n\fP will print to the standard output a summary of each font's metrics (size, number of glyphs, etc.), as it loads them. The default is \*(``false\*(''. .TP 8 .B "reportIcons\fP (class\fB ReportIcons\fP)" If true, \fI\*n\fP will print to the standard output a summary of each pixmap icon as it loads them. The default is \*(``false\*(''. .TP 8 .B "reportXRes\fP (class\fB ReportXRes\fP)" If true, \fI\*n\fP will print to the standard output a list of the boolean, numeric and string X resources for the VT100 widget after initialization. The default is \*(``false\*(''. .TP 8 .B "sameName\fP (class\fB SameName\fP)" If the value of this resource is \*(``true\*('', \fI\*n\fP does not send title and icon name change requests when the request would have no effect: the name is not changed. This has the advantage of preventing flicker and the disadvantage of requiring an extra round trip to the server to find out the previous value. In practice this should never be a problem. The default is \*(``true\*(''. .TP 8 .B "scaleHeight\fP (class\fB ScaleHeight\fP)" Scale line-height values by the resource value, which is limited to \*(``0.9\*('' to \*(``1.5\*(''. The default value is \*(``1.0\*('', .IP While this resource applies to either bitmap or TrueType fonts, its main purpose is to help work around incompatible changes in the Xft library's font metrics. \fI\*N\fP checks the font metrics to find what the library claims are the bounding boxes for each glyph (character). However, some of Xft's features (such as the autohinter) can cause the glyphs to be scaled larger than the bounding boxes, and be partly overwritten by the next row. .IP See \fBuseClipping\fP for a related resource. .TP 8 .B "scoFunctionKeys\fP (class\fB ScoFunctionKeys\fP)" Specifies whether or not SCO function key escape codes should be generated for function keys. The default is \*(``false\*('', i.e., this feature is disabled. .IP The \fBkeyboardType\fP resource is the preferred mechanism for selecting this mode. .TP 8 .B "sessionMgt\fP (class\fB SessionMgt\fP)" If the value of this resource is \*(``true\*('', \fI\*n\fP sets up session manager callbacks for \fBXtNdieCallback\fR and \fBXtNsaveCallback\fR. The default is \*(``true\*(''. .TP 8 .B "sunFunctionKeys\fP (class\fB SunFunctionKeys\fP)" Specifies whether or not Sun function key escape codes should be generated for function keys. The default is \*(``false\*('', i.e., this feature is disabled. .IP The \fBkeyboardType\fP resource is the preferred mechanism for selecting this mode. .TP 8 .B "sunKeyboard\fP (class\fB SunKeyboard\fP)" \fI\*N\fP translates certain key symbols based on its assumptions about your keyboard. This resource specifies whether or not Sun/PC keyboard layout (i.e., the PC keyboard's numeric keypad together with 12 function keys) should be assumed rather than DEC VT220. This causes the keypad \*(``+\*('' to be mapped to \*(``,\*(''. and CTRL F1-F10 to F11-F20, depending on the setting of the \fBctrlFKeys\fP resource, so \fI\*n\fP emulates a DEC VT220 more accurately. Otherwise (the default, with \fBsunKeyboard\fP set to \*(``false\*(''), \fI\*n\fP uses PC-style bindings for the function keys and keypad. .IP PC-style bindings use the Shift, Alt, Control and Meta keys as modifiers for function-keys and keypad (see \fIXterm Control Sequences\fP for details). The PC-style bindings are analogous to PCTerm, but not the same thing. Normally these bindings do not conflict with the use of the Meta key as described for the \fBeightBitInput\fP resource. If they do, note that the PC-style bindings are evaluated first. .IP See also the \fBkeyboardType\fP resource. .TP 8 .B "tcapFunctionKeys\fP (class\fB TcapFunctionKeys\fP)" Specifies whether or not function key escape codes read from the termcap/terminfo entry corresponding to the \fBTERM\fP environment variable should be generated for function keys instead of those configured using \fBsunKeyboard\fP and \fBkeyboardType\fP. The default is \*(``false\*('', i.e., this feature is disabled. .IP The \fBkeyboardType\fP resource is the preferred mechanism for selecting this mode. .TP 8 .B "termName\fP (class\fB TermName\fP)" Specifies the terminal type name to be set in the TERM environment variable. .TP 8 .B "title\fP (class\fB Title\fP)" Specifies a string that may be used by the window manager when displaying this application. .TP 8 .B "toolBar\fP (class\fB ToolBar\fP)" Specifies whether or not the toolbar should be displayed. The default is \*(``true\*(''. .TP 8 .B "ttyModes\fP (class\fB TtyModes\fP)" Specifies a string containing terminal setting keywords. Except where noted, they may be bound to \fIcharacters\fP. Other keywords set \fImodes\fP. Not all keywords are supported on a given system. Allowable keywords include: .TS l l l _ _ _ l l l. \fBKeyword\fR \fBPOSIX?\fR \fBNotes\fR brk no T{ \fICHAR\fP may send an \*(``interrupt\*('' signal, as well as ending the input-line. T} dsusp no T{ \fICHAR\fP will send a terminal \*(``stop\*('' signal after input is flushed. T} eof yes T{ \fICHAR\fP will terminate input (i.e., an end of file). T} eol yes \fICHAR\fP will end the line. eol2 no alternate \fICHAR\fP for ending the line. erase yes \fICHAR\fP will erase the last character typed. erase2 no T{ alternate \fICHAR\fP for erasing the last input-character. T} flush no T{ \fICHAR\fP will cause output to be discarded until another \fBflush\fP character is typed. T} intr yes \fICHAR\fP will send an \*(``interrupt\*('' signal. kill yes \fICHAR\fP will erase the current line. lnext no \fICHAR\fP will enter the next character quoted. quit yes \fPCHAR\fP will send a \*(``quit\*('' signal. rprnt no \fICHAR\fP will redraw the current line. start yes T{ \fICHAR\fP will \fIrestart\fP the output after stopping it. T} status no T{ \fICHAR\fP will cause a system-generated status line to be printed. T} stop yes \fICHAR\fP will stop the output. susp yes \fICHAR\fP will send a terminal \*(``stop\*('' signal swtch no \fICHAR\fP will switch to a different shell layer. tabs yes \fIMode\fP disables tab-expansion. -tabs yes \fIMode\fP enables tab-expansion. weras no \fICHAR\fP will erase the last word typed. .TE .IP Control characters may be specified as ^char (e.g., ^c or ^u) and \fB^?\fP may be used to indicate delete (127). Use \fB^\-\fP to denote \fIundef\fP. Use \fB\\034\fP to represent \fB^\\\fP, since a literal backslash in an X resource escapes the next character. .IP This is very useful for overriding the default terminal settings without having to run \fBstty\fP(1) every time an \fI\*n\fP is started. Note, however, that the \fIstty\fP program on a given host may use different keywords; \fI\*n\fR's table is built in. The \fIPOSIX\fP column in the table indicates which keywords are supported by a standard \fIstty\fP program. .IP If the \fBttyModes\fP resource specifies a value for \fBerase\fP, that overrides the \fBptyInitialErase\fP resource setting, i.e., \fI\*n\fP initializes the terminal to match that value. .TP 8 .B "useInsertMode\fP (class\fB UseInsertMode\fP)" Force use of insert mode by adding appropriate entries to the TERMCAP environment variable. This is useful if the system termcap is broken. (This resource is ignored on most systems, because TERMCAP is not used). The default is \*(``false\*(''. .TP 8 .B "utmpDisplayId\fP (class\fB UtmpDisplayId\fP)" Specifies whether or not \fI\*n\fP should try to record the display identifier (display number and screen number) as well as the hostname in the system \fI__utmp_name__\fP log file. The default is \*(``true\*(''. .TP 8 .B "utmpInhibit\fP (class\fB UtmpInhibit\fP)" Specifies whether or not \fI\*n\fP should try to record the user's terminal in the system \fI__utmp_name__\fP log file. If true, \fI\*n\fP will not try. The default is \*(``false\*(''. .TP 8 .B "validShells\fP (class\fB ValidShells\fP)" Augment (add to) the system's \fI/etc/shells\fP, when determining whether to set the \*(``SHELL\*('' environment variable when running a given program. .IP The resource value is a list of lines (separated by newlines). Each line holds one pathname. \fI\*N\fP ignores any line beginning with \*(``#\*('' after trimming leading/trailing whitespace from each line. .IP The default is an empty string. .TP 8 .B "waitForMap\fP (class\fB WaitForMap\fP)" Specifies whether or not \fI\*n\fP should wait for the initial window map before starting the subprocess. This is part of the \fBptyHandshake\fP logic. When \fI\*n\fP is directed to wait in this fashion, it passes the terminal size from the display end of the pseudo-terminal to the terminal I/O connection, e.g., using the size according to the window manager. Otherwise, it uses the size as given in resource values or command-line option \fB\-geometry\fP. The default is \*(``false\*(''. .TP 8 .B "zIconBeep\fP (class\fB ZIconBeep\fP)" Same as \-ziconbeep command line argument. If the value of this resource is non-zero, xterms that produce output while iconified will cause an XBell sound at the given volume and have \*(``***\ \*('' prepended to their icon titles. Most window managers will detect this change immediately, showing you which window has the output. (A similar feature was in x10 \fI\*n\fR.) The default is \*(``false\*(''. .TP 8 .B "zIconTitleFormat\fP (class\fB ZIconTitleFormat\fP)" Allow customization of the string used in the \fBzIconBeep\fP feature. The default value is \*(``***\ %s\*(''. .IP If the resource value contains a \*(``%s\*('', then \fI\*n\fP inserts the icon title at that point rather than prepending the string to the icon title. (Only the first \*(``%s\*('' is used). .\" .SS "VT100 Widget Resources" The following resources are specified as part of the \fIvt100\fP widget (class \fIVT100\fP). They are specified by patterns such as \*(``\fB__default_class__.vt100.\fINAME\fR\*(''. .PP If your \fI\*n\fP is configured to support the \*(``toolbar\*('', then those patterns need an extra level for the form-widget which holds the toolbar and vt100 widget. A wildcard between the top-level \*(``__default_class__\*('' and the \*(``vt100\*('' widget makes the resource settings work for either, e.g., \*(``\fB__default_class__*vt100.\fINAME\fR\*(''. .TP 8 .B "activeIcon\fP (class\fB ActiveIcon\fP)" Specifies whether or not active icon windows are to be used when the \fI\*n\fP window is iconified, if this feature is compiled into \fI\*n\fR. The active icon is a miniature representation of the content of the window and will update as the content changes. Not all window managers necessarily support application icon windows. Some window managers will allow you to enter keystrokes into the active icon window. The default is \*(``default\*(''. .IP \fI\*N\fP accepts either a keyword (ignoring case) or the number shown in parentheses: .RS .TP false (0) No active icon is shown. .TP true (1) The active icon is shown. If you are using \fItwm\fP, use this setting to enable active-icons. .TP default (2) \fI\*N\fP checks at startup, and shows an active icon only for window managers which it can identify and which are known to support the feature. These are \fIfvwm\fP (full support), and \fIwindow maker\fP (limited). A few other window managers (such as \fItwm\fP and \fIctwm\fP) support active icons, but do not support the extensions which allow \fI\*n\fP to identify the window manager. .RE .TP 8 .B "allowBoldFonts\fP (class\fB AllowBoldFonts\fP)" When set to \*(``false\*('', \fI\*n\fP will not use bold fonts. This overrides both the \fBalwaysBoldMode\fP and the \fBboldMode\fP resources. .TP 8 .B "allowC1Printable\fP (class\fB AllowC1Printable\fP)" If true, overrides the mapping of C1 controls (codes 128\(en159) to make them be treated as if they were printable characters. Although this corresponds to no particular standard, some users insist it is a VT100. The default is \*(``false\*(''. .TP .B "allowColorOps\fP (class\fB AllowColorOps\fP)" Specifies whether control sequences that set/query the dynamic colors should be allowed. ANSI colors are unaffected by this resource setting. The default is \*(``true\*(''. .TP .B "allowFontOps\fP (class\fB AllowFontOps\fP)" Specifies whether control sequences that set/query the font should be allowed. The default is \*(``true\*(''. .TP .B "allowMouseOps\fP (class\fB AllowMouseOps\fP)" Specifies whether control sequences that enable \fI\*n\fP to send escape sequences to the host on mouse-clicks and movement. The default is \*(``true\*(''. .TP 8 .B "allowPasteControls\fP (class\fB AllowPasteControls\fP)" If true, allow control characters such as BEL and CAN to be pasted. Formatting characters (tab, newline) are normally allowed, unless suppressed via the \fBdisallowedPasteControls\fP resource. Other C0 control characters are suppressed unless this resource is enabled. The exact set of control characters (C0 and C1) depends upon whether UTF-8 encoding is used, as well as the \fBallowC1Printable\fP and \fBdisallowedPasteControls\fP resources. The default is \*(``false\*(''. .TP 8 .B "allowScrollLock\fP (class\fB AllowScrollLock\fP)" Specifies whether control sequences that set/query the Scroll Lock key should be allowed, as well as whether the Scroll Lock key responds to user's keypress. The default is \*(``false\*(''. .IP When this feature is enabled, \fI\*n\fP will sense the state of the Scroll Lock key each time it acquires focus. Pressing the Scroll Lock key toggles \fI\*n\fP's internal state, as well as toggling the associated LED. While the Scroll Lock is active, \fI\*n\fP attempts to keep a viewport on the same set of lines. If the current viewport is scrolled past the limit set by the \fBsaveLines\fP resource, then Scroll Lock has no further effect. .IP The reason for setting the default to \*(``false\*('' is to avoid user surprise. This key is generally unused in keyboard configurations, and has not acquired a standard meaning even when it is used in that manner. Consequently, users have assigned it for ad hoc purposes. .IP See also the \fBautoScrollLock\fP resource. .TP 8 .B "allowSendEvents\fP (class\fB AllowSendEvents\fP)" Specifies whether or not synthetic key and button events (generated using the X protocol SendEvent request) should be interpreted or discarded. The default is \*(``false\*('' meaning they are discarded. Note that allowing such events would create a very large security hole, therefore enabling this resource forcefully disables the \fBallow\fIXXX\fBOps\fR resources. The default is \*(``false\*(''. .TP .B "allowTcapOps\fP (class\fB AllowTcapOps\fP)" Specifies whether control sequences that query the terminal's notion of its function-key strings, as termcap or terminfo capabilities should be allowed. The default is \*(``true\*(''. .IP A few programs, e.g., \fIvim\fP, use this feature to get an accurate description of the terminal's capabilities, independent of the termcap/terminfo setting: .RS .bP \fI\*N\fP can tell the querying program how many colors it supports. This is a constant, depending on how it is compiled, typically 16. It does not change if you alter resource settings, e.g., the \fBboldColors\fP resource. .bP \fI\*N\fP can tell the querying program what strings are sent by modified (shift-, control-, alt-) function- and keypad-keys. Reporting control- and alt-modifiers is a feature that relies on the \fIncurses\fP extended naming. .RE .TP .B "allowTitleOps\fP (class\fB AllowTitleOps\fP)" Specifies whether control sequences that modify the window title or icon name should be allowed. The default is \*(``true\*(''. .TP .B "allowWindowOps\fP (class\fB AllowWindowOps\fP)" Specifies whether extended window control sequences (as used in \fIdtterm\fP) should be allowed. These include several control sequences which manipulate the window size or position, as well as reporting these values and the title or icon name. Each of these can be abused in a script; curiously enough most terminal emulators that implement these restrict only a small part of the repertoire. For fine-tuning, see \fBdisallowedWindowOps\fP. The default is \*(``false\*(''. .TP 8 .B "altIsNotMeta\fP (class\fB AltIsNotMeta\fP)" If \*(``true\*('', treat the Alt-key as if it were the Meta-key. Your keyboard may happen to be configured so they are the same. But if they are not, this allows you to use the same prefix- and shifting operations with the Alt-key as with the Meta-key. See \fBaltSendsEscape\fP and \fBmetaSendsEscape\fP. The default is \*(``false\*(''. .TP 8 .B "altSendsEscape\fP (class\fB AltSendsEscape\fP)" This is an additional keyboard operation that may be processed after the logic for \fBmetaSendsEscape\fP. It is only available if the \fBaltIsNotMeta\fP resource is set. .RS .bP If \*(``true\*('', Alt characters (a character combined with the modifier associated with left/right Alt-keys) are converted into a two-character sequence with the character itself preceded by ESC. This applies as well to function key control sequences, unless \fI\*n\fP sees that \fBAlt\fP is used in your key translations. .bP If \*(``false\*('', Alt characters input from the keyboard cause a shift to 8-bit characters (just like \fBmetaSendsEscape\fP). By combining the Alt- and Meta-modifiers, you can create corresponding combinations of ESC-prefix and 8-bit characters. .RE .IP The default is \*(``__alt_sends_esc__\*(''. \fI\*N\fP provides a menu option for toggling this resource. .TP 8 .B "alternateScroll\fP (class\fB ScrollCond\fP)" If \*(``true\*('', the \fBscroll\-back\fP and \fBscroll\-forw\fP actions send cursor\-up and \-down keys when \fI\*n\fP is displaying the alternate screen. The default is \*(``false\*(''. .IP The \fBalternateScroll\fP state can also be set using a control sequence. .TP 8 .B "alwaysBoldMode\fP (class\fB AlwaysBoldMode\fP)" Specifies whether \fI\*n\fP should check if the normal and bold fonts are distinct before deciding whether to use overstriking to simulate bold fonts. If this resource is true, \fI\*n\fP does not make the check for distinct fonts when deciding how to handle the \fBboldMode\fP resource. The default is \*(``false\*(''. .ne 9 .TS l l l l _ _ _ _ l l l l. \fIboldMode\fR \fIalwaysBoldMode\fR \fIComparison\fR \fIAction\fP false false ignored use font false true ignored use font true false same overstrike true false different use font true true ignored overstrike .TE .RS .LP This resource is used only for bitmap fonts: .bP When using bitmap fonts, it is possible that the font server will approximate the bold font by rescaling it from a different font size than expected. The \fBalwaysBoldMode\fP resource allows the user to override the (sometimes poor) resulting bold font with overstriking (which is at least consistent). .bP The problem does not occur with TrueType fonts (though there can be other unnecessary issues such as different coverage of the normal and bold fonts). .RE .IP As an alternative, setting the \fBallowBoldFonts\fP resource to false overrides both the \fBalwaysBoldMode\fP and the \fBboldMode\fP resources. .TP 8 .B "alwaysHighlight\fP (class\fB AlwaysHighlight\fP)" Specifies whether or not \fI\*n\fP should always display a highlighted text cursor. By default (if this resource is false), a hollow text cursor is displayed whenever the pointer moves out of the window or the window loses the input focus. The default is \*(``false\*(''. .TP 8 .B "alwaysUseMods\fP (class\fB AlwaysUseMods\fP)" Override the \fBnumLock\fP resource, telling \fI\*n\fR to use the Alt and Meta modifiers to construct parameters for function key sequences even if those modifiers appear in the translations resource. Normally \fI\*n\fP checks if Alt or Meta is used in a translation that would conflict with function key modifiers, and will ignore these modifiers in that special case. The default is \*(``false\*(''. .TP 8 .B "answerbackString\fP (class\fB AnswerbackString\fP)" Specifies the string that \fI\*n\fR sends in response to an ENQ (control/E) character from the host. The default is a blank string, i.e., \*(``\*(''. A hardware VT100 implements this feature as a setup option. .TP 8 .B "appcursorDefault\fP (class\fB AppcursorDefault\fP)" If \*(``true\*('', the cursor keys are initially in application mode. This is the same as the VT102 private DECCKM mode, The default is \*(``false\*(''. .TP 8 .B "appkeypadDefault\fP (class\fB AppkeypadDefault\fP)" If \*(``true\*('', the keypad keys are initially in application mode. The default is \*(``false\*(''. .TP 8 .B "assumeAllChars\fP (class\fB AssumeAllChars\fP)" If \*(``true\*('', this enables a special case in bitmap fonts to allow the font server to choose how to display missing glyphs. The default is \*(``true\*(''. .IP The reason for this resource is to help with certain quasi-automatically generated fonts (such as the ISO-10646-1 encoding of Terminus) which have incorrect font-metrics. .TP 8 .B "autoScrollLock\fP (class\fB AutoScrollLock\fP)" If \*(``true\*('', \fI\*n\fR will maintain its viewport of displayed lines whenever displaying scrollback, as if \fBallowScrollLock\fP were enabled and the Scroll Lock key had been pressed. The default is \*(``false\*(''. This feature is only useful if the \fBscrollTtyOutput\fP resource is set to \*(``false\*(''. .TP 8 .B "autoWrap\fP (class\fB AutoWrap\fP)" Specifies whether or not auto-wraparound should be enabled. This is the same as the VT102 DECAWM. The default is \*(``true\*(''. .TP 8 .B "awaitInput\fP (class\fB AwaitInput\fP)" Specifies whether or not \fI\*n\fR uses a 50 millisecond timeout to await input (i.e., to support the \fIXaw3d\fP arrow scrollbar). The default is \*(``false\*(''. .TP 8 .B "backarrowKey\fP (class\fB BackarrowKey\fP)" Specifies whether the backarrow key transmits a backspace (8) or delete (127) character. This corresponds to the DECBKM control sequence. A \*(``true\*('' value specifies backspace. The default is \*(``__backarrow_is_bs__\*(''. Pressing the control key toggles this behavior. .TP 8 .B "background\fP (class\fB Background\fP)" Specifies the color to use for the background of the window. The default is \*(``XtDefaultBackground\*(''. .TP 8 .B "bellIsUrgent\fP (class\fB BellIsUrgent\fP)" Specifies whether to set the Urgency hint for the window manager when making a bell sound. The default is \*(``false\*(''. .TP 8 .B "bellOnReset\fP (class\fB BellOnReset\fP)" Specifies whether to sound a bell when doing a hard reset. The default is \*(``true\*(''. .TP 8 .B "bellSuppressTime\fP (class\fB BellSuppressTime\fP)" Number of milliseconds after a bell command is sent during which additional bells will be suppressed. Default is 200. If set non-zero, additional bells will also be suppressed until the server reports that processing of the first bell has been completed; this feature is most useful with the visible bell. .TP 8 .B "boldColors\fP (class\fB ColorMode\fP)" Specifies whether to combine bold attribute with colors like the IBM PC, i.e., map colors 0 through 7 to colors 8 through 15. These normally are the brighter versions of the first 8 colors, hence bold. The default is \*(``true\*(''. .TP 8 .B "boldFont\fP (class\fB BoldFont\fP)" Specifies the name of the bold font to use instead of overstriking. There is no default for this resource. .IP This font must be the same height and width as the normal font, otherwise it is ignored. If only one of the normal or bold fonts is specified, it will be used as the normal font and the bold font will be produced by overstriking this font. .IP See also the discussion of \fBboldMode\fP and \fBalwaysBoldMode\fP resources. .TP 8 .B "boldMode\fP (class\fB BoldMode\fP)" This specifies whether or not text with the bold attribute should be overstruck to simulate bold fonts if the resolved bold font is the same as the normal font. It may be desirable to disable bold fonts when color is being used for the bold attribute. .IP Note that \fI\*n\fP has one bold font which you may set explicitly. \fI\*N\fP attempts to derive a bold font for the other font selections (\fBfont1\fP through \fBfont7\fP). If it cannot find a bold font, it will use the normal font. In each case (whether the explicit resource or the derived font), if the normal and bold fonts are distinct, this resource has no effect. The default is \*(``true\*(''. .IP See the \fBalwaysBoldMode\fP resource which can modify the behavior of this resource. .IP Although \fI\*n\fP attempts to derive a bold font for other font selections, the font server may not cooperate. Since X11R6, bitmap fonts have been scaled. The font server claims to provide the bold font that \fI\*n\fP requests, but the result is not always readable. XFree86 introduced a feature which can be used to suppress the scaling. In the X server's configuration file (e.g., \*(``/etc/X11/XFree86\*('' or \*(``/etc/X11/xorg.conf\*(''), you can add \*(``:unscaled\*('' to the end of the directory specification for the \*(``misc\*('' fonts, which comprise the fixed-pitch fonts that are used by \fI\*n\fP. For example .NS FontPath "/usr/lib/X11/fonts/misc/" .NE .IP would become .NS FontPath "/usr/lib/X11/fonts/misc/:unscaled" .NE .IP Depending on your configuration, the font server may have its own configuration file. The same \*(``:unscaled\*('' can be added to its configuration file at the end of the directory specification for \*(``misc\*(''. .IP The bitmap scaling feature is also used by \fI\*n\fP to implement VT102 double-width and double-height characters. .TP 8 .B "brokenLinuxOSC\fP (class\fB BrokenLinuxOSC\fP)" If true, \fI\*n\fP applies a workaround to ignore malformed control sequences that a Linux script might send. Compare the palette control sequences documented in \fIconsole_codes\fR with ECMA-48. The default is \*(``true\*(''. .TP 8 .B "brokenSelections\fP (class\fB BrokenSelections\fP)" If true, \fI\*n\fP in 8-bit mode will interpret \fBSTRING\fP selections as carrying text in the current locale's encoding. Normally \fBSTRING\fP selections carry ISO-8859-1 encoded text. Setting this resource to \*(``true\*('' violates the ICCCM; it may, however, be useful for interacting with some broken X clients. The default is \*(``false\*(''. .TP 8 .B "brokenStringTerm\fP (class\fB BrokenStringTerm\fP)" provides a work-around for some ISDN routers which start an application control string without completing it. Set this to \*(``true\*('' if \fI\*n\fP appears to freeze when connecting. The default is \*(``false\*(''. .IP \fI\*N\fP's state parser recognizes several types of control strings which can contain text, e.g., .sp .RS \fBAPC\fP (Application Program Command), .br \fBDCS\fP (Device Control String), .br \fBOSC\fP (Operating System Command), .br \fBPM\fP (Privacy Message), and .br \fBSOS\fP (Start of String), .RE .IP Each should end with a string-terminator (a special character which cannot appear in these strings). Ordinary control characters found within the string are not ignored; they are processed without interfering with the process of accumulating the control string's content. \fI\*N\fP recognizes these controls in all modes, although some of the functions may be suppressed after parsing the control. .IP When enabled, this feature allows the user to exit from an unterminated control string when any of these ordinary control characters are found: .sp .RS control/D (used as an end of file in many shells), .br control/H (backspace), .br control/I (tab-feed), .br control/J (line feed aka newline), .br control/K (vertical tab), .br control/L (form feed), .br control/M (carriage return), .br control/N (shift-out), .br control/O (shift-in), .br control/Q (XOFF), .br control/X (cancel) .RE .TP 8 .B "c132\fP (class\fB C132\fP)" Specifies whether or not the VT102 DECCOLM escape sequence, used to switch between 80 and 132 columns, should be honored. The default is \*(``false\*(''. .TP 8 .B "cacheDoublesize\fP (class\fB CacheDoublesize\fP)" Tells whether to cache double-sized fonts by \fI\*n\fR. Set this to zero to disable double-sized fonts altogether. .TP 8 .B "cdXtraScroll\fP (class\fB CdXtraScroll\fP)" Specifies whether \fI\*n\fP should scroll to a new page when clearing the whole screen. Like \fBtiXtraScroll\fP, the intent of this option is to provide a picture of the full-screen application's display on the scrollback before wiping out the text. .IP \fI\*N\fP accepts either a keyword (ignoring case) or the number shown in parentheses: .RS .TP false (0) nothing is added to the scrollback. .TP true (1) the current screen is added to the scrollback. .TP trim (2) the current screen is added to the scrollback, but repeated blank lines are trimmed (reduced to a single blank line). .RE .IP The default for this resource is \*(``false\*(''. .TP 8 .B "charClass\fP (class\fB CharClass\fP)" Specifies comma-separated lists of character class bindings of the form .NS \fIlow\fP[\-\fIhigh]\fP[:\fIvalue\fP]. .NE .IP These are used in determining which sets of characters should be treated the same when doing cut and paste. See the \fBCHARACTER CLASSES\fP section. .TP 8 .B "checksumExtension\fP (class\fB ChecksumExtension\fP)" DEC VT420 and up support a control sequence \fBDECRQCRA\fP which reports the checksum of the characters in a rectangle. \fI\*N\fP supports this, with extensions that can be configured with bits of the \fBchecksumExtension\fP: .RS .TP 5 0 do not negate the result. .TP 5 1 do not report the VT100 video attributes. .TP 5 2 do not omit checksum for blanks. .TP 5 3 omit checksum for cells not explicitly initialized. .TP 5 4 do not mask cell value to 8 bits or ignore combining characters. .TP 5 5 do not mask cell value to 7 bits. .RE .IP With the default value (0), \fI\*n\fP matches the behavior of DEC's terminals. To use all extensions, set all bits, \*(``\-1\*('' for example. .TP 8 .B "cjkWidth\fP (class\fB CjkWidth\fP)" Specifies whether \fI\*n\fP should follow the traditional East Asian width convention. When turned on, characters with East Asian Ambiguous (A) category in UTR 11 have a column width of 2. You may have to set this option to \*(``true\*('' if you have some old East Asian terminal based programs that assume that line-drawing characters have a column width of 2. If this resource is false, the \fBmkWidth\fP resource controls the choice between the system's \fBwcwidth\fP(3) and \fI\*n\fP's built-in tables. The default is \*(``false\*(''. .TP 8 .B "color0\fP (class\fB Color0\fP)" .TP 8 .B "color1\fP (class\fB Color1\fP)" .TP 8 .B "color2\fP (class\fB Color2\fP)" .TP 8 .B "color3\fP (class\fB Color3\fP)" .TP 8 .B "color4\fP (class\fB Color4\fP)" .TP 8 .B "color5\fP (class\fB Color5\fP)" .TP 8 .B "color6\fP (class\fB Color6\fP)" .TP 8 .B "color7\fP (class\fB Color7\fP)" These specify the colors for the ISO-6429 extension. The defaults are, respectively, black, red3, green3, yellow3, a customizable dark blue, magenta3, cyan3, and gray90. The default shades of color are chosen to allow the colors 8\(en15 to be used as brighter versions. .TP 8 .B "color8\fP (class\fB Color8\fP)" .TP 8 .B "color9\fP (class\fB Color9\fP)" .TP 8 .B "color10\fP (class\fB Color10\fP)" .TP 8 .B "color11\fP (class\fB Color11\fP)" .TP 8 .B "color12\fP (class\fB Color12\fP)" .TP 8 .B "color13\fP (class\fB Color13\fP)" .TP 8 .B "color14\fP (class\fB Color14\fP)" .TP 8 .B "color15\fP (class\fB Color15\fP)" These specify the colors for the ISO-6429 extension if the bold attribute is also enabled. The default resource values are respectively, gray50, red, green, yellow, a customized light blue, magenta, cyan, and white. .TP 8 .B "color16\fP (class\fB Color16\fP)" .TP 8 through .TP 8 .B "color255\fP (class\fB Color255\fP)" These specify the colors for the 256-color extension. The default resource values are for .RS .bP colors 16 through 231 to make a 6x6x6 color cube, and .bP colors 232 through 255 to make a grayscale ramp. .RE .IP Resources past \fBcolor15\fP are available as a compile-time option. Due to a hardcoded limit in the X libraries on the total number of resources (to 400), the resources for 256-colors are omitted when wide-character support and \fIluit\fP are enabled. Besides inconsistent behavior if only part of the resources were allowed, determining the exact cutoff is difficult, and the X libraries tend to crash if the number of resources exceeds the limit. The color palette is still initialized to the same default values, and can be modified via control sequences. .IP On the other hand, the resource limit does permit including the entire range for 88-colors. .TP 8 .B "colorAttrMode\fP (class\fB ColorAttrMode\fP)" Specifies whether \fBcolorBD\fP, \fBcolorBL\fP, \fBcolorRV\fP, and \fBcolorUL\fP should override ANSI colors. If not, these are displayed only when no ANSI colors have been set for the corresponding position. The default is \*(``false\*(''. .TP 8 .B "colorBD\fP (class\fB ColorBD\fP)" This specifies the color to use to display bold characters if the \*(``colorBDMode\*('' resource is enabled. The default is \*(``XtDefaultForeground\*(''. .IP See also the \fBveryBoldColors\fP resource which allows combining bold and color. .TP 8 .B "colorBDMode\fP (class\fB ColorAttrMode\fP)" Specifies whether characters with the bold attribute should be displayed in color or as bold characters. Note that setting \fBcolorMode\fR off disables all colors, including bold. The default is \*(``false\*(''. .TP 8 .B "colorBL\fP (class\fB ColorBL\fP)" This specifies the color to use to display blink characters if the \*(``colorBLMode\*('' resource is enabled. The default is \*(``XtDefaultForeground\*(''. .IP See also the \fBveryBoldColors\fP resource which allows combining underline and color. .TP 8 .B "colorBLMode\fP (class\fB ColorAttrMode\fP)" Specifies whether characters with the blink attribute should be displayed in color. Note that setting \fBcolorMode\fR off disables all colors, including this. The default is \*(``false\*(''. .TP .B "colorEvents\fP (class\fB ColorEvents\fP)" Specifies OSC control codes that can be processed from client messages with the type \fBXTERM_CONTROL\fR. These events may be generated using the X protocol SendEvent request. The resource value is a comma separated list of codes allowed. The default is the empty string, disallowing all processing. .IP The names are listed below. \fI\*N\fP ignores capitalization, but they are shown in mixed-case for clarity. Either a name or a number can be used. .RS .TP 5 TEXT_FG (10) text foreground .TP 5 TEXT_BG (11) text background .TP 5 TEXT_CURSOR (12) text cursor .TP 5 MOUSE_FG (13) mouse foreground .TP 5 MOUSE_BG (14) mouse background .TP 5 TEK_FG (15) tektronix foreground .TP 5 TEK_BG (16) tektronix background .TP 5 HIGHLIGHT_BG (17) highlight background .TP 5 TEK_CURSOR (18) tektronix cursor .TP 5 HIGHLIGHT_FG (19) highlight foreground .RE .IP For example, if messages for the text color are enabled, e.g., by setting the resource to .NS text_fg, text_bg .NE .IP the text foreground color can be set to black by sending a message with this content: .NS 10;#000000 .NE .TP 8 .B "colorIT\fP (class\fB ColorIT\fP)" This specifies the color to use to display italic characters if the \*(``colorITMode\*('' resource is enabled. The default is \*(``XtDefaultForeground\*(''. .IP See also the \fBveryBoldColors\fP resource which allows combining attributes and color. .TP 8 .B "colorITMode\fP (class\fB ColorAttrMode\fP)" Specifies whether characters with the italic attribute should be displayed in color or as italic characters. The default is \*(``false\*(''. .IP Note that: .RS .bP Setting \fBcolorMode\fR off disables all colors, including italic. .bP The \fBitalicULMode\fP resource overrides \fBcolorITMode\fP. .RE .TP 8 .B "colorInnerBorder\fP (class\fB ColorInnerBorder\fP)" Normally, \fI\*n\fP fills the VT100 window's inner border using the background color. .IP If the \fBcolorInnerBorder\fP resource is enabled, at startup \fI\*n\fP will compare the \fBborderColor\fP and the window's background color. If those are different, \fI\*n\fP will use the \fBborderColor\fP resource to fill the inner border. Otherwise, it will use the window's background color. .IP The default is \*(``false\*(''. .TP 8 .B "colorMode\fP (class\fB ColorMode\fP)" Specifies whether or not recognition of ANSI (ISO-6429) color change escape sequences should be enabled. The default is \*(``true\*(''. .TP 8 .B "colorRV\fP (class\fB ColorRV\fP)" This specifies the color to use to display reverse characters if the \*(``colorRVMode\*('' resource is enabled. The default is \*(``XtDefaultForeground\*(''. .IP See also the \fBveryBoldColors\fP resource which allows combining reverse and color. .TP 8 .B "colorRVMode\fP (class\fB ColorAttrMode\fP)" Specifies whether characters with the reverse attribute should be displayed in color. Note that setting \fBcolorMode\fR off disables all colors, including this. The default is \*(``false\*(''. .TP 8 .B "colorUL\fP (class\fB ColorUL\fP)" This specifies the color to use to display underlined characters if the \*(``colorULMode\*('' resource is enabled. The default is \*(``XtDefaultForeground\*(''. .IP See also the \fBveryBoldColors\fP resource which allows combining underline and color. .TP 8 .B "colorULMode\fP (class\fB ColorAttrMode\fP)" Specifies whether characters with the underline attribute should be displayed in color or as underlined characters. Note that setting \fBcolorMode\fR off disables all colors, including underlining. The default is \*(``false\*(''. .TP 8 .B "combiningChars\fP (class\fB CombiningChars\fP)" Specifies the number of wide-characters which can be stored in a cell to overstrike (combine) with the base character of the cell. This can be set to values in the range 0 to 5. The default is \*(``2\*(''. .TP 8 .B "ctrlFKeys\fP (class\fB CtrlFKeys\fP)" In VT220 keyboard mode (see \fBsunKeyboard\fP resource), specifies the amount by which to shift F1-F12 given a control modifier (CTRL). This allows you to generate key symbols for F10-F20 on a Sun/PC keyboard. The default is \*(``10\*('', which means that CTRL F1 generates the key symbol for F11. .TP 8 .B "curses\fP (class\fB Curses\fP)" Specifies whether or not the last column bug in .IR more (1) should be worked around. See the \fB\-cu\fP option for details. The default is \*(``false\*(''. .TP 8 .B "cursorBar\fP (class\fB CursorBar\fP)" Specifies whether to make the cursor a left-bar or a box, unless the \fBcursorUnderLine\fP resource is set. The default is \*(``false\*(''. .TP 8 .B "cursorBlink\fP (class\fB CursorBlink\fP)" Specifies whether to make the cursor blink. \fI\*N\fP accepts either a keyword (ignoring case) or the number shown in parentheses: .RS .TP 3 false (0) The cursor will not blink, but may be combined with escape sequences according to the \fBcursorBlinkXOR\fP resource. .TP 3 true (1) The cursor will blink, but may be combined with escape sequences according to the \fBcursorBlinkXOR\fP resource. .TP 3 always (2) The cursor will always blink, ignoring escape sequences. The menu entry will be disabled. .TP 3 never (3) The cursor will never blink, ignoring escape sequences. The menu entry will be disabled. .RE .IP The default is \*(``false\*(''. .TP 8 .B "cursorBlinkXOR\fP (class\fB CursorBlinkXOR\fP)" \fI\*N\fP uses two inputs to determine whether the cursor blinks: .RS .bP The \fBcursorBlink\fP resource (which can be altered with a menu entry). .bP Control sequences (private mode 12 and DECSCUSR). .RE .IP The \fBcursorBlinkXOR\fP resource determines how those inputs are combined: .RS .TP 5 false .br \fI\*N\fP uses the logical-OR of the two variables. If either is set, \fI\*n\fP makes the cursor blink. .TP 5 true .br \fI\*N\fP uses the logical-XOR of the two variables. If only one is set, \fI\*n\fP makes the cursor blink. .RE .IP The default is \*(``true\*(''. .TP 8 .B "cursorColor\fP (class\fB CursorColor\fP)" Specifies the color to use for the text cursor. The default is \*(``XtDefaultForeground\*(''. By default, \fI\*n\fP attempts to keep this color from being the same as the background color, since it draws the cursor by filling the background of a text cell. The same restriction applies to control sequences which may change this color. .IP Setting this resource overrides most of \fI\*n\fP's adjustments to cursor color. It will still use reverse-video to disallow some cases, such as a black cursor on a black background. .TP 8 .B "cursorOffTime\fP (class\fB CursorOffTime\fP)" Specifies the duration of the \*(``off\*('' part of the cursor blink cycle-time in milliseconds. The same timer is used for text blinking. The default is \*(``300\*(''. .TP 8 .B "cursorOnTime\fP (class\fB CursorOnTime\fP)" Specifies the duration of the \*(``on\*('' part of the cursor blink cycle-time, in milliseconds. The same timer is used for text blinking. The default is \*(``600\*(''. .TP 8 .B "cursorUnderLine\fP (class\fB CursorUnderLine\fP)" Specifies whether to make the cursor underlined or a box. If unset (false), the \fBcursorBar\fP resource may set the cursor shape. The default is \*(``false\*(''. .TP 8 .B "cutNewline\fP (class\fB CutNewline\fP)" If \*(``false\*('', triple clicking to select a line does not include the \fInewline\fP at the end of the line. If \*(``true\*('', the Newline is selected. The default is \*(``true\*(''. .TP 8 .B "cutToBeginningOfLine\fP (class\fB CutToBeginningOfLine\fP)" If \*(``false\*('', triple clicking to select a line selects only from the current word forward. If \*(``true\*('', the entire line is selected. The default is \*(``true\*(''. .TP 8 .B "decGraphicsID\fP (class\fB DecGraphicsID\fP)" Allows a way to combine the graphics feature from certain DEC terminals (125, 240, 241, 330, 340 or 382) with other emulation levels which did not provide the graphics feature. As in \fBdecTerminalID\fP, leading non-digit characters are ignored, e.g., \*(``vt340\*('' and \*(``340\*('' are the same. .IP If the resource value is nonzero, \fI\*n\fP uses that emulation level when initializing the drawing region and decoding control sequences to draw graphics. .IP The default is \*(``0\*(''. .TP 8 .B "decTerminalID\fP (class\fB DecTerminalID\fP)" Specifies the emulation level (100=VT100, 220=VT220, etc.), used to determine the type of response to a DA control sequence. Leading non-digit characters are ignored, e.g., \*(``vt100\*('' and \*(``100\*('' are the same. The default is \*(``__default_termid__\*(''. .TP 8 .B "defaultString\fP (class\fB DefaultString\fP)" Specify the character (or string) which \fI\*n\fP will substitute when pasted text includes a character which cannot be represented in the current encoding. For instance, pasting UTF-8 text into a display of ISO-8859-1 characters will only be able to display codes 0\(en255, while UTF-8 text can include Unicode values above 255. The default is \*(``#\*('' (a single pound sign). .IP If the undisplayable text would be double-width, \fI\*n\fP will add a space after the \*(``#\*('' character, to give roughly the same layout on the screen as the original text. .TP 8 .B "deleteIsDEL\fP (class\fB DeleteIsDEL\fP)" Specifies what the \fIDelete\fP key on the editing keypad should send when pressed. The resource value is a string, evaluated as a boolean after startup. \fI\*N\fP uses it in conjunction with the \fBkeyboardType\fP resource: .RS .bP If the keyboard type is \*(``default\*('', or \*(``vt220\*('' and the resource is either \*(``true\*('' or \*(``maybe\*('' send the VT220-style \fIRemove\fP escape sequence. Otherwise, send DEL (127). .bP If the keyboard type is \*(``legacy\*('', and the resource is \*(``true\*('' send DEL. Otherwise, send the \fIRemove\fP sequence. .bP Otherwise, if the keyboard type is none of these special cases, send DEL (127). .RE .IP The default is \*(``__delete_is_del__\*(''. The resource is allowed to be a non-boolean \*(``maybe\*('' so that the popup menu \fBDelete is DEL\fP entry does not override the keyboard type. .TP 8 .B "directColor\fP (class\fB DirectColor\fP)" Specifies whether to handle direct-color control sequences using the X server's available colors, or to approximate those using a color map with 256 entries. A \*(``true\*('' value enables the former. The default is \*(``true\*(''. .TP 8 .B "disallowedColorOps\fP (class\fB DisallowedColorOps\fP)" Specify which features will be disabled if \fBallowColorOps\fP is false. This is a comma-separated list of names. The default value is .RS SetColor,GetColor,GetAnsiColor .RE .IP The names are listed below. \fI\*N\fP ignores capitalization, but they are shown in mixed-case for clarity. .RS .TP 5 SetColor Set a specific dynamic color. .TP 5 GetColor Report the current setting of a given dynamic color. .TP 5 GetAnsiColor Report the current setting of a given ANSI color (actually any of the colors set via ANSI-style controls). .RE .TP 8 .B "disallowedFontOps\fP (class\fB DisallowedFontOps\fP)" Specify which features will be disabled if \fBallowFontOps\fP is false. This is a comma-separated list of names. The default value is .NS SetFont,GetFont .NE .IP The names are listed below. \fI\*N\fP ignores capitalization, but they are shown in mixed-case for clarity. .RS .TP 5 SetFont Set the specified font. .TP 5 GetFont Report the specified font. .RE .TP 8 .B "disallowedMouseOps\fP (class\fB DisallowedMouseOps\fP)" Specify which features will be disabled if \fBallowMouseOps\fP is false. This is a comma-separated list of names. The default value is \*(``*\*('' which matches all names. The names are listed below. \fI\*N\fP ignores capitalization, but they are shown in mixed-case for clarity. .RS .TP 5 X10 The original X10 mouse protocol. .TP 5 Locator DEC locator mode .TP 5 VT200Click X11 mouse-clicks only. .TP 5 VT200Hilite X11 mouse-clicks and highlighting. .TP 5 AnyButton XFree86 \fI\*n\fP any-button mode sends button-clicks as well as motion events while the button is pressed. .TP 5 AnyEvent XFree86 \fI\*n\fP any-event mode sends button-clicks as well as motion events whether or not a button is pressed. .TP 5 FocusEvent Send FocusIn/FocusOut events. .TP 5 Extended The first extension beyond X11 mouse protocol, this encodes the coordinates in UTF-8. It is deprecated in favor of \fISGR\fP, but provided for compatibility. .TP 5 SGR This is the recommended extension for mouse-coordinates .TP 5 URXVT Like \fIExtended\fP, this is provided for compatibility. .TP 5 AlternateScroll This overrides the \fBalternateScroll\fP resource. .RE .TP 8 .B "disallowedPasteControls\fP (class\fB DisallowedPasteControls\fP)" Use this resource to disallow pasting specific C0 control characters when the \fBallowPasteControls\fP resource is false (i.e., the default). This resource defines the set of control characters which cannot be pasted, converting each into a space. Other C0 controls are pasted without change. .IP The resource value is a comma-separated list of names. \fI\*N\fP ignores capitalization. The default value is .NS BS,DEL,ENQ,EOT,ESC,NUL,STTY .NE .IP The names are listed below: .RS .TP 5 C0 all ASCII control characters. .TP 5 \fIIndividual C0 characters\fP NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, BS, HT, LF, VT, FF, CR, SO, SI, DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, CAN, EM, SUB, ESC, FS, GS, RS, US .TP 5 DEL ASCII delete .TP 5 NL ASCII line-feed, i.e., \*(``newline\*('' is the same as LF. .TP 5 STTY special characters which are set with \fBstty\fP(1). .RE .TP 8 .B "disallowedTcapOps\fP (class\fB DisallowedTcapOps\fP)" Specify which features will be disabled if \fBallowTcapOps\fP is false. This is a comma-separated list of names. The default value is .NS SetTcap,GetTcap .NE .IP The names are listed below. \fI\*N\fP ignores capitalization, but they are shown in mixed-case for clarity. .RS .TP 5 SetTcap (not implemented) .TP 5 GetTcap Report specified function- and other special keys. .RE .TP 8 .B "disallowedWindowOps\fP (class\fB DisallowedWindowOps\fP)" Specify which features will be disabled if \fBallowWindowOps\fP is false. This is a comma-separated list of names, or (for the controls adapted from \fIdtterm\fP the operation number). The default value is .NS 20,21,SetXprop,SetSelection (i.e., all except a few \*(``dangerous\*('' operations are allowed). .NE .IP The names are listed below. \fI\*N\fP ignores capitalization, but they are shown in mixed-case for clarity. Where a number can be used as an alternative, it is given in parentheses after the name. .RS .TP 5 ColumnMode Enable (or disable) switching between 80 and 132 columns. This is in addition to the \fBc132\fP resource. .TP 5 GetChecksum Report checksum of characters in a rectangular region. .TP 5 GetIconTitle (20) Report \fI\*n\fP window's icon label as a string. .TP 5 GetScreenSizeChars (19) Report the size of the screen in characters as numbers. .TP 5 GetSelection Report selection data as a base64 string. .TP 5 GetWinPosition (13) Report \fI\*n\fP window position as numbers. .TP 5 GetWinSizeChars (18) Report the size of the text area in characters as numbers. .TP 5 GetWinSizePixels (14) Report \fI\*n\fP window in pixels as numbers. .TP 5 GetWinState (11) Report \fI\*n\fP window state as a number. .TP 5 GetWinTitle (21) Report \fI\*n\fP window's title as a string. .TP 5 LowerWin (6) Lower the \fI\*n\fP window to the bottom of the stacking order. .TP 5 MaximizeWin (9) Maximize window (i.e., resize to screen size). .TP 5 FullscreenWin (10) Use full screen (i.e., resize to screen size, without window decorations). .TP 5 MinimizeWin (2) Iconify window. .TP 5 PopTitle (23) Pop title from internal stack. .TP 5 PushTitle (22) Push title to internal stack. .TP 5 RaiseWin (5) Raise the \fI\*n\fP window to the front of the stacking order. .TP 5 RefreshWin (7) Refresh the \fI\*n\fP window. .TP 5 RestoreWin (1) De-iconify window. .TP 5 SetChecksum Modify algorithm for reporting checksum of characters in a rectangular region. .TP 5 SetSelection Set selection data. .TP 5 SetWinLines Resize to a given number of lines, at least 24. .TP 5 SetWinPosition (3) Move window to given coordinates. .TP 5 SetWinSizeChars (8) Resize the text area to given size in characters. .TP 5 SetWinSizePixels (4) Resize the \fI\*n\fP window to given size in pixels. .TP 5 SetXprop Set X property on top-level window. .TP 5 StatusLine Resize window to provide a VT320-style status line. .RE .TP 8 .B "dynamicColors\fP (class\fB DynamicColors\fP)" Specifies whether or not escape sequences to change colors assigned to different attributes are recognized. .TP 8 .B "eightBitControl\fP (class\fB EightBitControl\fP)" Specifies whether or not control sequences sent by the terminal should be eight-bit characters or escape sequences. The default is \*(``false\*(''. .TP 8 .B "eightBitInput\fP (class\fB EightBitInput\fP)" If \*(``true\*('', Meta characters (a single-byte character combined with the \fIMeta\fP modifier key) input from the keyboard are presented as a single character, modified according to the \fBeightBitMeta\fP resource. If \*(``false\*('', Meta characters are converted into a two-character sequence with the character itself preceded by ESC. The default is \*(``true\*(''. .IP The \fBmetaSendsEscape\fP and \fBaltSendsEscape\fP resources may override this feature. Generally keyboards do not have a key labeled \*(``Meta\*('', but \*(``Alt\*('' keys are common, and they are conventionally used for \*(``Meta\*(''. If they were synonymous, it would have been reasonable to name this resource \*(``\fBaltSendsEscape\fP\*('', reversing its sense. For more background on this, see the \fBmeta\fP(3x) function in curses. .IP Note that the \fIAlt\fP key is not necessarily the same as the \fIMeta\fP modifier. The \fIxmodmap\fP utility lists your key modifiers. X defines modifiers for shift, (caps) lock and control, as well as 5 additional modifiers which are generally used to configure key modifiers. \fI\*N\fP inspects the same information to find the modifier associated with either \fIMeta\fP key (left or right), and uses that key as the \fIMeta\fP modifier. It also looks for the NumLock key, to recognize the modifier which is associated with that. .IP If your \fIxmodmap\fP configuration uses the same keycodes for Alt- and Meta-keys, \fI\*n\fP will only see the Alt-key definitions, since those are tested before Meta-keys. NumLock is tested first. It is important to keep these keys distinct; otherwise some of \fI\*n\fP's functionality is not available. .IP The \fBeightBitInput\fP resource is tested at startup time. If \*(``true\*('', the \fI\*n\fP tries to put the terminal into 8-bit mode. If \*(``false\*('', on startup, \fI\*n\fP tries to put the terminal into 7-bit mode. For some configurations this is unsuccessful; failure is ignored. After startup, \fI\*n\fP does not change the terminal between 8-bit and 7-bit mode. .IP As originally implemented in X11, the resource value did not change after startup. However (since patch #216 in 2006) \fI\*n\fP can modify \fBeightBitInput\fP after startup via a control sequence. The corresponding terminfo capabilities \fBsmm\fP (set meta mode) and \fBrmm\fP (reset meta mode) have been recognized by \fIbash\fP for some time. Interestingly enough, \fIbash\fP's notion of \*(``meta mode\*('' differs from the standard definition (in the \fIterminfo\fP manual), which describes the change to the eighth bit of a character. It happens that \fIbash\fP views \*(``meta mode\*('' as the ESC character that \fI\*n\fP puts before a character when a special meta key is pressed. \fIbash\fP's early documentation talks about the ESC character and ignores the eighth bit. .TP 8 .B "eightBitMeta\fP (class\fB EightBitMeta\fP)" This controls the way \fI\*n\fP modifies the eighth bit of a single-byte key when the \fBeightBitInput\fP resource is set. The default is \*(``locale\*(''. .IP The resource value is a string, evaluated as a boolean after startup. .RS .TP 5 false The key is sent unmodified. .TP 5 locale The key is modified only if the locale uses eight-bit encoding. .TP 5 true The key is sent modified. .TP 5 never The key is always sent unmodified. .RE .IP Except for the \fBnever\fP choice, \fI\*n\fP honors the terminfo capabilities \fBsmm\fP (set meta mode) and \fBrmm\fP (reset meta mode), allowing the feature to be turned on or off dynamically. .IP If \fBeightBitMeta\fP is enabled when the locale uses UTF-8, \fI\*n\fP encodes the value as UTF-8 (since patch #183 in 2003). .TP 8 .B "eightBitOutput\fP (class\fB EightBitOutput\fP)" Specifies whether or not eight-bit characters sent from the host should be accepted as is or stripped when printed. The default is \*(``true\*('', which means that they are accepted as is. .TP 8 .B "eightBitSelectTypes\fP (class\fB EightBitSelectTypes\fP)" Override \fI\*n\fP's default selection target list (see \fBSELECT/PASTE\fP) for selections in normal (ISO-8859-1) mode. The default is an empty string, i.e., \*(``\*('', which does not override anything. .TP 8 .B "eraseSavedLines\fP (class\fB EraseSavedLines\fP)" Specifies whether or not to allow \fI\*n\fP extended ED/DECSED control sequences to erase the saved-line buffer. The default is \*(``true\*(''. .TP 8 .B "faceName\fP (class\fB FaceName\fP)" Specify the pattern for scalable fonts selected from the FreeType library if support for that library was compiled into \fI\*n\fR. There is no default value. .IP One or more fonts can be specified, separated by commas. If prefixed with \*(``x:\*('' or \*(``x11:\*('' the specification applies to the XLFD \fBfont\fP resource. A \*(``xft:\*('' prefix is accepted but unnecessary since a missing prefix for \fBfaceName\fP means that it will be used for TrueType. For example, .NS XTerm*faceName: x:fixed,xft:Bitstream Vera Sans Mono .NE .IP Two TrueType fonts can be specified in this way. The first is the primary font; the second acts as a manual override to the \fIfontconfig\fP fontset. .IP If no \fBfaceName\fP resource is specified, or if there is no match for both TrueType normal and bold fonts, \fI\*n\fR uses the XLFD (bitmap) \fBfont\fP and related resources. .IP It is possible to select suitable bitmap fonts using a script such as this: .NS \&#!/bin/sh \&FONT=`xfontsel \-print` \&test \-n "$FONT" && xfd \-fn "$FONT" .NE .IP However (even though \fIxfd\fP accepts a \*(``\fB\-fa\fP\*('' option to denote FreeType fonts), \fIxfontsel\fP has not been similarly extended. As a workaround, you may try .NS fc\-list :scalable=true:spacing=mono: family .NE .IP to find a list of scalable fixed-pitch fonts which may be used for the \fBfaceName\fP resource value. .TP 8 .B "faceNameDoublesize\fP (class\fB FaceNameDoublesize\fP)" Specify a double-width scalable font for cases where an application requires this, e.g., in CJK applications. There is no default value. .IP Like the \fBfaceName\fP resource, this allows one or more comma-separated font specifications to be applied to the \fIwide\fP TrueType or XLFD fonts. .IP If the application uses double-wide characters and this resource is not given, \fI\*n\fP will use a scaled version of the font given by \fBfaceName\fP. .TP 8 .B "faceSize\fP (class\fB FaceSize\fP)" Specify the pointsize for fonts selected from the FreeType library if support for that library was compiled into \fI\*n\fR. The default is \*(``8.0\*('' On the \fBVT\ Fonts\fP menu, this corresponds to the \fIDefault\fP entry. .IP Although the default is \*(``8.0\*('', this may not be the same as the pointsize for the default bitmap font, i.e., that assigned with the \fB\-fn\fP option, or the \fBfont\fP resource. The default value of \fBfaceSize\fP is chosen to match the size of the \*(``fixed\*('' font, making switching between bitmap and TrueType fonts via the font menu give comparable sizes for the window. If your \fB\-fn\fP option uses a different pointsize, you might want to adjust the \fBfaceSize\fP resource to match. .IP You can specify the pointsize for TrueType fonts selected with the other size-related menu entries such as Medium, Huge, etc., by using one of the following resource values. If you do not specify a value, they default to \*(``0.0\*('', which causes \fI\*n\fP to use the ratio of font sizes from the corresponding bitmap font resources to obtain a TrueType pointsize. .IP If all of the \fBfaceSize\fP resources are set, then \fI\*n\fP will use this information to determine the next smaller/larger TrueType font for the \fBlarger\-vt\-font()\fP and \fBsmaller\-vt\-font()\fP actions. If any are not set, \fI\*n\fP will use only the areas of the bitmap fonts. .TP 8 .B "faceSize1\fP (class\fB FaceSize1\fP)" Specifies the pointsize of the first alternative font. .TP 8 .B "faceSize2\fP (class\fB FaceSize2\fP)" Specifies the pointsize of the second alternative font. .TP 8 .B "faceSize3\fP (class\fB FaceSize3\fP)" Specifies the pointsize of the third alternative font. .TP 8 .B "faceSize4\fP (class\fB FaceSize4\fP)" Specifies the pointsize of the fourth alternative font. .TP 8 .B "faceSize5\fP (class\fB FaceSize5\fP)" Specifies the pointsize of the fifth alternative font. .TP 8 .B "faceSize6\fP (class\fB FaceSize6\fP)" Specifies the pointsize of the sixth alternative font. .TP 8 .B "faceSize7\fP (class\fB FaceSize7\fP)" Specifies the pointsize of the seventh alternative font. .TP 8 .B "faintIsRelative\fP (class\fB FaintIsRelative\fP)" Faint colors are derived from the current text color, e.g., the ANSI colors, by scaling the red, green and blue components. Use this resource to specify whether that is done relative to the current background color, or as an absolute value. The default is \*(``false\*(''. .TP 8 .B "fastScroll\fP (class\fB FastScroll\fP)" Modifies the effect of jump scroll (\fBjumpScroll\fP) by suppressing screen refreshes for the special case when output to the screen has completely shifted the contents off-screen. Likewise, screen refreshes for related actions, e.g., carriage returns, are suppressed. .IP For instance, \fIcat\fP'ing a large file to the screen normally results in a large number of screen refreshes. By suppressing the corresponding refreshes, scrolling speed improves. .IP The default is \*(``true\*(''. .TP 8 .B "font\fP (class\fB Font\fP)" Specifies the name of the normal font. The default is \*(``fixed\*(''. .IP See the discussion of the \fBlocale\fP resource, which describes how this font may be overridden. .IP NOTE: some resource files use patterns such as .NS *font: fixed .NE .IP which are overly broad, affecting both .NS xterm.vt100.font .NE .IP and .NS xterm.vt100.utf8Fonts.font .NE .IP which is probably not what you intended. .TP 8 .B "font1\fP (class\fB Font1\fP)" Specifies the name of the first alternative font, corresponding to \*(``Unreadable\*('' in the standard menu. .TP 8 .B "font2\fP (class\fB Font2\fP)" Specifies the name of the second alternative font, corresponding to \*(``Tiny\*('' in the standard menu. .TP 8 .B "font3\fP (class\fB Font3\fP)" Specifies the name of the third alternative font, corresponding to \*(``Small\*('' in the standard menu. .TP 8 .B "font4\fP (class\fB Font4\fP)" Specifies the name of the fourth alternative font, corresponding to \*(``Medium\*('' in the standard menu. .TP 8 .B "font5\fP (class\fB Font5\fP)" Specifies the name of the fifth alternative font, corresponding to \*(``Large\*('' in the standard menu. .TP 8 .B "font6\fP (class\fB Font6\fP)" Specifies the name of the sixth alternative font, corresponding to \*(``Huge\*('' in the standard menu. .TP 8 .B "font7\fP (class\fB Font7\fP)" Specifies the name of the seventh alternative font, corresponding to \*(``Enormous\*('' in the standard menu. .TP 8 .B "fontDoublesize\fP (class\fB FontDoublesize\fP)" Specifies whether \fI\*n\fP should attempt to use font scaling to draw double-sized characters. Some older font servers cannot do this properly, will return misleading font metrics. The default is \*(``true\*(''. If disabled, \fI\*n\fP will simulate double-sized characters by drawing normal characters with spaces between them. .TP 8 .B "fontWarnings\fP (class\fB FontWarnings\fP)" Specify whether \fI\*n\fP should report an error if it fails to load a font: .RS .TP 5 0 Never report an error (though the X libraries may). .TP 5 1 Report an error if the font name was given as a resource setting. .TP 5 2 Always report an error on failure to load a font. .RE .IP The default is \*(``1\*(''. .TP 8 .B "forceBoxChars\fP (class\fB ForceBoxChars\fP)" Specifies whether \fI\*n\fP should assume the normal and bold fonts have VT100 line-drawing characters: .RS .bP The fixed-pitch ISO-8859-*-encoded fonts used by \fI\*n\fP normally have the VT100 line-drawing glyphs in cells 1\(en31. Other fixed-pitch fonts may be more attractive, but lack these glyphs. .bP When using an ISO-10646-1 font and the \fBwideChars\fP resource is true, \fI\*n\fP uses the Unicode glyphs which match the VT100 line-drawing glyphs. .RE .IP If \*(``false\*('', \fI\*n\fP checks for missing glyphs in the font and makes line-drawing characters directly as needed. If \*(``true\*('', \fI\*n\fP assumes the font does not contain the line-drawing characters, and draws them directly. The default is \*(``false\*(''. .IP The VT100 line-drawing character set (also known as the \fIDEC Special Character and Line Drawing Set\fP) is shown in this table. It includes a few \fIspecial\fP characters which are not used for drawing lines: .TS l l l _ _ _ l l l. \fICell\fR \fIUnicode\fR \fIDescription\fP 0 U+25AE black vertical rectangle 1 U+25C6 black diamond 2 U+2592 medium shade 3 U+2409 symbol for horizontal tabulation 4 U+240C symbol for form feed 5 U+240D symbol for carriage return 6 U+240A symbol for line feed 7 U+00B0 degree sign 8 U+00B1 plus-minus sign 9 U+2424 symbol for newline 10 U+240B symbol for vertical tabulation 11 U+2518 box drawings light up and left 12 U+2510 box drawings light down and left 13 U+250C box drawings light down and right 14 U+2514 box drawings light up and right 15 U+253C box drawings light vertical and horizontal 16 U+23BA box drawings scan 1 17 U+23BB box drawings scan 3 18 U+2500 box drawings light horizontal 19 U+23BC box drawings scan 7 20 U+23BD box drawings scan 9 21 U+251C box drawings light vertical and right 22 U+2524 box drawings light vertical and left 23 U+2534 box drawings light up and horizontal 24 U+252C box drawings light down and horizontal 25 U+2502 box drawings light vertical 26 U+2264 less-than or equal to 27 U+2265 greater-than or equal to 28 U+03C0 greek small letter pi 29 U+2260 not equal to 30 U+00A3 pound sign 31 U+00B7 middle dot _ .TE .TP 8 .B "forcePackedFont\fP (class\fB ForcePackedFont\fP)" Specifies whether \fI\*n\fP should use the maximum or minimum glyph width when displaying using a bitmap font. Use the maximum width to help with proportional fonts. The default is \*(``true\*('', denoting the minimum width. .TP 8 .B "forceXftHeight\fP (class\fB ForceXftHeight\fP)" Specifies whether \fI\*n\fP should use the given font metrics for TrueType fonts, or amend the ascent/descent to total no more than the given font-height. This optional feature is used to work around inconsistencies in FreeType's rounding computation. The default is \*(``false\*('', denoting the given metrics. .TP 8 .B "foreground\fP (class\fB Foreground\fP)" Specifies the color to use for displaying text in the window. Setting the class name instead of the instance name is an easy way to have everything that would normally appear in the text color change color. The default is \*(``XtDefaultForeground\*(''. .TP 8 .B "formatCursorKeys\fP (class\fB FormatCursorKeys\fP)" When \fBmodifyCursorKeys\fP is 4 or greater, use modified form as in \fBformatOtherKeys\fP, for cursor-keys instead of the conventional form. The default is \*(``0\*(''. .TP 8 .B "formatFunctionKeys\fP (class\fB FormatFunctionKeys\fP)" When \fBmodifyFunctionKeys\fP is 4 or greater, use modified form as in \fBformatOtherKeys\fP, for function-keys instead of the conventional form. The default is \*(``0\*(''. .TP 8 .B "formatKeypadKeys\fP (class\fB FormatKeypadKeys\fP)" When \fBmodifyKeypadKeys\fP is 4 or greater, use modified form as in \fBformatOtherKeys\fP, for numeric keypad-keys instead of the conventional form. The default is \*(``0\*(''. .TP 8 .B "formatModifierKeys\fP (class\fB FormatModifierKeys\fP)" When \fBmodifyModifierKeys\fP is 4 or greater, use modified form as in \fBformatOtherKeys\fP, for modifier-keys instead of the conventional form. The default is \*(``0\*(''. .TP 8 .B "formatOtherKeys\fP (class\fB FormatOtherKeys\fP)" Overrides the format of the escape sequence used to report modified keys with the \fBmodifyOtherKeys\fP resource. .RS .TP 3 0 send modified keys as parameters for function-key 27 (default). .TP 3 1 send modified keys as parameters for CSI\ u. .RE .TP 8 .B "formatSpecialKeys\fP (class\fB FormatSpecialKeys\fP)" When \fBmodifySpecialKeys\fP is 4 or greater, use modified form as in \fBformatOtherKeys\fP, for special keys instead of the conventional form. The default is \*(``0\*(''. .TP 8 .B "freeBoldBox\fP (class\fB FreeBoldBox\fP)" Specifies whether \fI\*n\fP should assume the bounding boxes for normal and bold fonts are compatible. If \*(``false\*('', \fI\*n\fP compares them and will reject choices of bold fonts that do not match the size of the normal font. The default is \*(``false\*('', which means that the comparison is performed. .TP 8 .B "geometry\fP (class\fB Geometry\fP)" Specifies the preferred size and position of the VT\fIxxx\fP window. There is no default for this resource. .TP 8 .B "highlightColor\fP (class\fB HighlightColor\fP)" Specifies the color to use for the background of selected (highlighted) text. If not specified (i.e., matching the default foreground), reverse video is used. The default is \*(``XtDefaultForeground\*(''. .TP 8 .B "highlightColorMode\fP (class\fB HighlightColorMode\fP)" Specifies whether \fI\*n\fP should use \fBhighlightTextColor\fP and \fBhighlightColor\fP to override the reversed foreground/background colors in a selection. The default is unspecified: at startup, \fI\*n\fP checks if those resources are set to something other than the default foreground and background colors. Setting this resource disables the check. .IP The following table shows the interaction of the highlighting resources, abbreviated as shown to fit in this page: .RS .TP 3 .I HCM highlightColorMode .TP 3 .I HR highlightReverse .TP 3 .I HBG highlightColor .TP 3 .I HFG highlightTextColor .RE .IP .ne 34 .TS l l l l l _ _ _ _ _ l l l l l. \fIHCM\fR \fIHR\fR \fIHBG\fR \fIHFG\fR \fIHighlight\fP false false default default bg/fg false false default set bg/fg false false set default fg/HBG false false set set fg/HBG = false true default default bg/fg false true default set bg/fg false true set default fg/HBG false true set set fg/HBG = true false default default bg/fg true false default set HFG/fg true false set default bg/HBG true false set set HFG/HBG = true true default default bg/fg true true default set HFG/fg true true set default fg/HBG true true set set HFG/HBG = default false default default bg/fg default false default set bg/fg default false set default fg/HBG default false set set HFG/HBG = default true default default bg/fg default true default set bg/fg default true set default fg/HBG default true set set HFG/HBG = .TE .TP 8 .B "highlightReverse\fP (class\fB HighlightReverse\fP)" Specifies whether \fI\*n\fP should reverse the selection foreground and background colors when selecting text with reverse-video attribute. This applies only to the \fBhighlightColor\fP and \fBhighlightTextColor\fP resources, e.g., to match the color scheme of \fIxwsh\fP. If \*(``true\*('', \fI\*n\fP reverses the colors, If \*(``false\*('', \fI\*n\fP does not reverse colors, The default is \*(``true\*(''. .TP 8 .B "highlightSelection\fP (class\fB HighlightSelection\fP)" Tells \fI\*n\fP whether to highlight all of the selected positions, or only the selected text: .RS .bP If \*(``false\*('', selecting with the mouse highlights all positions on the screen between the beginning of the selection and the current position. .bP If \*(``true\*('', \fI\*n\fP highlights only the positions that contain text that can be selected. .RE .IP The default is \*(``false\*(''. .IP Depending on the way your applications write to the screen, there may be trailing blanks on a line. \fI\*N\fP stores data as it is shown on the screen. Erasing the display changes the internal state of each cell so it is not considered a blank for the purpose of selection. Blanks written since the last erase are selectable. If you do not wish to have trailing blanks in a selection, use the \fBtrimSelection\fP resource. .TP 8 .B "highlightTextColor\fP (class\fB HighlightTextColor\fP)" Specifies the color to use for the foreground of selected (highlighted) text. If not specified (i.e., matching the default background), reverse video is used. The default is \*(``XtDefaultBackground\*(''. .TP 8 .B "hpLowerleftBugCompat\fP (class\fB HpLowerleftBugCompat\fP)" Specifies whether to work around a bug in HP's \fIxdb\fP, which ignores termcap and always sends ESC F to move to the lower left corner. \*(``true\*('' causes \fI\*n\fP to interpret ESC F as a request to move to the lower left corner of the screen. The default is \*(``false\*(''. .TP 8 .B "i18nSelections\fP (class\fB I18nSelections\fP)" If false, \fI\*n\fP will not request the targets \fBCOMPOUND_TEXT\fP or \fBTEXT\fP. The default is \*(``true\*(''. It may be set to false in order to work around ICCCM violations by other X clients. .TP 8 .B "iconBorderColor\fP (class\fB BorderColor\fP)" Specifies the border color for the active icon window if this feature is compiled into \fI\*n\fR. Not all window managers will make the icon border visible. .TP 8 .B "iconBorderWidth\fP (class\fB BorderWidth\fP)" Specifies the border width for the active icon window if this feature is compiled into \fI\*n\fR. The default is \*(``2\*(''. Not all window managers will make the border visible. .TP 8 .B "iconFont\fP (class\fB IconFont\fP)" Specifies the font for the miniature active icon window, if this feature is compiled into \fI\*n\fR. The default is \*(``nil2\*(''. .TP 8 .B "incrementalGraphics\fP (class\fB IncrementalGraphics\fP)" When displaying SIXEL graphics, refresh the screen after processing each cell. The default is \*(``false\*(''. .TP 8 .B "indicatorFormat\fP (class\fB IndicatorFormat\fP)" When displaying the status line using the \fIindicator\fP mode (i.e., selecting DECSSDT line type 1), format the status using this resource. .IP The default value of the resource displays the version of \fI\*n\fR, the cursor position and the time/date: .NS \*(``%{version%}\ \ %{position%}\ \ %{unixtime%}\*('' .NE .IP If a \*(``%\*('' marker does not match any of the three special tokens used in the default resource setting, \fI\*n\fP uses \fBstrftime\fP(3) to interpret it. .TP 8 .B "initialFont\fP (class\fB InitialFont\fP)" Specifies which of the VT100 fonts to use initially. Values are the same as for the \fBset\-vt\-font\fP action. The default is \*(``d\*('', i.e., \*(``default\*(''. .TP 8 .B "inputMethod\fP (class\fB InputMethod\fP)" Tells \fI\*n\fP which type of input method to use. There is no default method. .TP 8 .B "internalBorder\fP (class\fB BorderWidth\fP)" Specifies the number of pixels between the characters and the window border. The default is \*(``2\*(''. .TP 8 .B "italicULMode\fP (class\fB ColorAttrMode\fP)" Specifies whether characters with the underline attribute should be displayed in an italic font or as underlined characters. It is implemented only for TrueType fonts. .TP 8 .B "jumpScroll\fP (class\fB JumpScroll\fP)" Specifies whether or not jump scroll should be used. This corresponds to the VT102 DECSCLM private mode. The default is \*(``true\*(''. See \fBfastScroll\fP for a variation. .TP 8 .B "keepClipboard\fP (class\fB KeepClipboard\fP)" Specifies whether \fI\*n\fR will reuse the selection data which it copied to the clipboard rather than asking the clipboard for its current contents when told to provide the selection. The default is \*(``false\*(''. .IP If compiled into \fI\*n\fP, the menu entry \fBKeep Clipboard\fP allows you to change this at runtime. .TP 8 .B "keepSelection\fP (class\fB KeepSelection\fP)" Specifies whether \fI\*n\fR will keep the selection even after the selected area was touched by some output to the terminal. The default is \*(``true\*(''. .IP The menu entry \fBKeep Selection\fP allows you to change this at runtime. .TP 8 .B "keyboardDialect\fP (class\fB KeyboardDialect\fP)" Specifies the initial keyboard dialect, as well as the default value when the terminal is reset. The value given is the same as the final character in the control sequences which change character sets. The default is \*(``B\*('', which corresponds to US ASCII. .TP 8 .B "limitFontsets\fP (class\fB LimitFontsets\fP)" Limits the number of TrueType fallback fonts (i.e., fontset) which can be tested. The default is \*(``50\*(''. No more than \*(``255\*('' will be scanned. .IP This limits the number of fallback fonts which \fI\*n\fP uses to display characters. Because TrueType fonts typically are small, \fI\*n\fP may open several fonts for good coverage, and may open additional fonts to obtain information. You can see which font-files \fI\*n\fP opens by setting the environment variable \fBXFT_DEBUG\fP to 3. The Xft library and \fI\*n\fP write this debugging trace to the standard output. .IP Set this to \*(``0\*('' to disable fallbacks entirely. .TP 8 .B "limitFontHeight\fP (class\fB LimitFontHeight\fP)" When scaling a TrueType font to provide the parts for a double-high character, \fI\*n\fP compares the scaled font with the original to ensure that it is taller. .IP The default is \*(``10\*('' (percent). .TP 8 .B "limitFontWidth\fP (class\fB LimitFontWidth\fP)" When looking for fallback fonts, \fI\*n\fP checks to see that the character to be displayed is the same width as the primary font. If a character extends outside the font's bounding box, \fI\*n\fP will clip it, to fit. .IP This resource controls the amount by which the character can extend outside its bounding box before \fI\*n\fP looks further for a better font. .IP This resource is also used in scaling TrueType fonts for double-wide characters, like \fBlimitFontHeight\fP for double-wide characters. .IP The default is \*(``10\*('' (percent). .TP 8 .B "limitResize\fP (class\fB LimitResize\fP)" Limits resizing of the screen via control sequence to a given multiple of the display dimensions. The default is \*(``1\*(''. .TP 8 .B "limitResponse\fP (class\fB LimitResponse\fP)" Limits the buffer-size used when \fI\*n\fP replies to various control sequences. The default is \*(``1024\*(''. The minimum value is \*(``256\*(''. .TP 8 .B "locale\fP (class\fB Locale\fP)" Specifies how to use \fBluit\fR(1), an encoding converter between UTF-8 and locale encodings. The resource value (ignoring case) may be: .RS .TP 4 .I true \fI\*N\fR will use the encoding specified by the users' LC_CTYPE locale (i.e., LC_ALL, LC_CTYPE, or LANG variables) as far as possible. This is realized by always enabling UTF-8 mode and invoking \fIluit\fR in non-UTF-8 locales. .TP .I medium \fI\*N\fR will follow users' LC_CTYPE locale only for UTF-8, east Asian, and Thai locales, where the encodings were not supported by conventional 8bit mode with changing fonts. For other locales, \fI\*n\fR will use conventional 8bit mode. .TP .I checkfont If mini-luit is compiled-in, \fI\*n\fR will check if a Unicode font has been specified. If so, it checks if the character encoding for the current locale is POSIX, Latin-1 or Latin-9, uses the appropriate mapping to support those with the Unicode font. For other encodings, \fI\*n\fR assumes that UTF-8 encoding is required. .TP .I false \fI\*N\fR will use conventional 8bit mode or UTF-8 mode according to \fButf8\fR resource or \fB\-u8\fP option. .RE .IP Any other value, e.g., \*(``UTF\-8\*('' or \*(``ISO8859\-2\*('', is assumed to be an encoding name; \fIluit\fR will be invoked to support the encoding. The actual list of supported encodings depends on \fIluit\fR. The default is \*(``medium\*(''. .IP Regardless of your locale and encoding, you need an ISO-10646-1 font to display the result. Your configuration may not include this font, or locale-support by \fI\*n\fP may not be needed. .IP At startup, \fI\*n\fP uses a mechanism equivalent to the \fBload\-vt\-fonts(utf8Fonts,\ Utf8Fonts)\fP action to load font name subresources of the VT100 widget. That is, resource patterns such as \*(``\fB*vt100.utf8Fonts.font\fP\*('' will be loaded, and (if this resource is enabled), override the normal fonts. If no subresources are found, the normal fonts such as \*(``\fB*vt100.font\fP\*('', etc., are used. .IP For instance, you could have this in your resource file: .NS *VT100.font: 12x24 *VT100.utf8Fonts.font:9x15 .NE .IP When started with a UTF-8 locale, \fI\*n\fP would use 9x15, but allow you to switch to the 12x24 font using the menu entry \*(``\fBUTF\-8 Fonts\fP\*(''. .IP The resource files distributed with \fI\*n\fP use ISO-10646-1 fonts, but do not rely on them unless you are using the locale mechanism. .TP 8 .B "localeFilter\fP (class\fB LocaleFilter\fP)" Specifies the file name for the encoding converter from/to locale encodings and UTF-8 which is used with the \fB\-lc\fR option or \fBlocale\fR resource. The help message shown by \*(``\*n \-help\*('' lists the default value, which depends on your system configuration. .IP If the encoding converter requires command-line parameters, you can add those after the command, e.g., .NS *localeFilter: xterm\-filter \-p .NE .IP Alternatively, you may put those parameters within a shell script to execute the converter, and set this resource to point to the shell script. .IP When using a locale-filter, e.g., with the \fI\-e\fP option, or the shell, \fI\*n\fP first tries passing control via that filter. If it fails, \fI\*n\fP will retry without the locale-filter. \fI\*N\fP warns about the failure before retrying. .TP 8 .B "logFile\fP (class\fB Logfile\fP)" Specify the name for \fI\*n\fP's log file. If no name is specified, \fI\*n\fP will generate a name when logging is enabled, as described in the \fB\-l\fP option. .TP 8 .B "logInhibit\fP (class\fB LogInhibit\fP)" If \*(``true\*('', prevent the logging feature from being enabled, whether by the command-line option \fB\-l\fP, or the menu entry \fBLog to File\fP. The default is \*(``false\*(''. .TP 8 .B "logging\fP (class\fB Logging\fP)" If \*(``true\*('', (and if \fBlogInhibit\fP is not set) enable the logging feature. This resource is set/updated by the \fB\-l\fP option and the menu entry \fBLog to File\fP. The default is \*(``false\*(''. .TP 8 .B "loginShell\fP (class\fB LoginShell\fP)" Specifies whether or not the shell to be run in the window should be started as a login shell. The default is \*(``false\*(''. .TP 8 .B "marginBell\fP (class\fB MarginBell\fP)" Specifies whether or not the bell should be rung when the user types near the right margin. The default is \*(``false\*(''. .TP 8 .B "maxGraphicSize\fP (class\fB MaxGraphicSize\fP)" If \fI\*n\fR is configured to support ReGIS or SIXEL graphics, this resource controls the maximum size of a graph which can be displayed. .IP The default is \*(``1000x1000\*('' (given as \fIwidth\fP by \fIheight\fP). .IP If the resource is \*(``auto\*('' then \fI\*n\fR will use the \fBdecGraphicsID\fP resource (or \fBdecTerminalID\fP if that is not set): .TS l l _ _ r r. \fBResult\fR \fBdecGraphicsID\fR 768x400 125 800x460 240 800x460 241 800x480 330 800x480 340 860x750 382 800x480 \fIother\fP .TE .TP 8 .B "maxStringParse\fP (class\fB MaxStringParse\fP)" \fI\*N\fP's state parser recognizes several types of control strings which can contain text, e.g., .sp .RS \fBAPC\fP (Application Program Command), .br \fBDCS\fP (Device Control String), .br \fBOSC\fP (Operating System Command), .br \fBPM\fP (Privacy Message), and .br \fBSOS\fP (Start of String), .RE .IP \fI\*N\fP reads these strings, accumulating them into a buffer until they are properly terminated. At that point, \fI\*n\fP interprets the strings. If they happen to be \fBDCS\fP commands to draw ReGIS images, these strings may be large, in the hundreds of kilobytes. A few \fBOSC\fP commands may be as large as 10 kilobytes. .IP This resource sets a limit on the size of the buffer used for these strings. The default is \*(``__strings_max__\*('' based on the features which are configured for \fI\*n\fP. Control strings which require larger buffer size are ignored. .TP 8 .B "metaSendsEscape\fP (class\fB MetaSendsEscape\fP)" Tells \fI\*n\fP what to do with input-characters modified by \fIMeta\fP: .RS .bP If \*(``true\*('', Meta characters (a character combined with the \fIMeta\fP modifier key) are converted into a two-character sequence with the character itself preceded by ESC. This applies as well to function key control sequences, unless \fI\*n\fP sees that \fBMeta\fP is used in your key translations. .bP If \*(``false\*('', Meta characters input from the keyboard are handled according to the \fBeightBitInput\fP resource. .RE .IP The default is \*(``__meta_sends_esc__\*(''. .TP 8 .B "mkSamplePass\fP (class\fB MkSamplePass\fP)" If \fBmkSampleSize\fP is nonzero, and \fBmkWidth\fP (and \fBcjkWidth\fP) are false, on startup \fI\*n\fP compares its built-in tables to the system's wide character width data to decide if it will use the system's data. It tests the first \fBmkSampleSize\fP character values, and allows up to \fBmkSamplePass\fP mismatches before the test fails. The default (for the allowed number of mismatches) is 655 (one percent of the default value for \fBmkSampleSize\fP). .TP 8 .B "mkSampleSize\fP (class\fB MkSampleSize\fP)" With \fBmkSamplePass\fP, this specifies a startup test used for initializing wide character width calculations. The default (number of characters to check) is 65536. .TP 8 .B "mkWidth\fP (class\fB MkWidth\fP)" Specifies whether \fI\*n\fP should use a built-in version of the wide character width calculation. See also the \fBcjkWidth\fP resource which can override this. The default is \*(``false\*(''. .IP Here is a summary of the resources which control the choice of wide character width calculation: .ne 8 .TS l l l _ _ _ l l l. \fIcjkWidth\fR \fImkWidth\fR \fIAction\fP false false use system tables subject to \fBmkSamplePass\fP false true use built-in tables true false use built-in CJK tables true true use built-in CJK tables .TE .IP To disable \fBmkWidth\fP, and use the system's tables, set both \fBmkSampleSize\fP and \fBmkSamplePass\fP to \*(``0\*(''. Doing that may make \fI\*n\fP more consistent with applications running in \fI\*n\fP, but may omit some font glyphs whose width correctly differs from the system's character tables. .TP 8 .B "modifyCursorKeys\fP (class\fB ModifyCursorKeys\fP)" Tells how to handle the special case where Control-, Shift-, Alt- or Meta-modifiers are used to add a parameter to the escape sequence returned by a cursor-key. X11 cursor keys are the four keys with arrow symbols: .NS Left Right Up Down .NE .IP as well as some commonly found on an \*(``editing keypad\*('' .NS Home Prior Page_Up Next Page_Down End Begin .NE .IP The default is \*(``2\*('': .RS .TP 5 \-1 disables the feature. .TP 5 0 uses the old/obsolete behavior, i.e., the modifier is the first parameter. .TP 5 1 prefixes modified sequences with CSI. .TP 5 2 forces the modifier to be the second parameter if it would otherwise be the first. .TP 5 3 marks the sequence with a \*(``>\*('' to hint that it is private. .TP 5 4 changes the format to match \fBmodifyOtherKeys\fP\ 3, sending an escape sequence according to \fBformatCursorKeys\fP. .RE .TP 8 .B "modifyFunctionKeys\fP (class\fB ModifyFunctionKeys\fP)" Tells how to handle the special case where Control-, Shift-, Alt- or Meta-modifiers are used to add a parameter to the escape sequence returned by a (numbered) function-key. The default is \*(``2\*(''. The resource values are similar to \fBmodifyCursorKeys\fP: .RS .TP 5 \-1 permits the user to use shift- and control-modifiers to construct function-key strings using the normal encoding scheme. .TP 5 0 uses the old/obsolete behavior, i.e., the modifier is the first parameter. .TP 5 1 prefixes modified sequences with CSI. .TP 5 2 forces the modifier to be the second parameter if it would otherwise be the first. .TP 5 3 marks the sequence with a \*(``>\*('' to hint that it is private. .TP 5 4 changes the format to match \fBmodifyOtherKeys\fP\ 3, sending an escape sequence according to \fBformatFunctionKeys\fP. .RE .IP If \fBmodifyFunctionKeys\fP is zero, \fI\*n\fP uses Control- and Shift-modifiers to allow the user to construct numbered function-keys beyond the set provided by the keyboard: .RS .TP 5 Control adds the value given by the \fBctrlFKeys\fP resource. .TP 5 Shift adds twice the value given by the \fBctrlFKeys\fP resource. .TP 5 Control/Shift adds three times the value given by the \fBctrlFKeys\fP resource. .RE .TP 8 .B "modifyKeyboard\fP (class\fB ModifyKeyboard\fP)" Normally \fI\*n\fP makes a special case regarding modifiers (shift, control, etc.) to handle special keyboard layouts (\fBlegacy\fP and \fBvt220\fP). This is done to provide compatible keyboards for DEC VT220 and related terminals that implement user-defined keys (UDK). .IP The bits of the resource value selectively enable modification of the given category when these keyboards are selected. The default is \*(``0\*('': .RS .TP 5 0 The legacy/vt220 keyboards interpret only the Control-modifier when constructing numbered function-keys. Other special keys are not modified. .TP 5 1 allows modification of the numeric keypad .TP 5 2 allows modification of the editing keypad .TP 5 4 allows modification of function-keys, overrides use of Shift-modifier for UDK. .TP 5 8 allows modification of other special keys .RE .TP 8 .B "modifyKeypadKeys\fP (class\fB ModifyKeypadKeys\fP)" Like \fBmodifyCursorKeys\fP \*(``4\*('', tells \fI\*n\fP to construct an escape sequence for \fInumeric keypad\fP keys. The default is \*(``0\*(''. .TP 8 .B "modifyModifierKeys\fP (class\fB ModifyModifierKeys\fP)" Like \fBmodifyCursorKeys\fP \*(``4\*('', tells \fI\*n\fP to construct an escape sequence for \fImodifier\fP (e.g., \*(``shift\*('') keys. The default is \*(``0\*(''. .TP 8 .B "modifyOtherKeys\fP (class\fB ModifyOtherKeys\fP)" Like \fBmodifyCursorKeys\fP \*(``4\*('', tells \fI\*n\fP to construct an escape sequence for \fIordinary\fP (i.e., \*(``other\*('') keys (such as \*(``2\*('') when modified by Shift-, Control-, Alt- or Meta-modifiers. This feature does not apply to \fIspecial keys\fP, i.e., cursor-, keypad-, function- or control-keys which are labeled on your keyboard. Those have key symbols which XKB identifies uniquely. .IP The default is \*(``0\*('': .RS .TP 5 0 disables this feature. .TP 5 1 enables this feature for keys except for those with well-known behavior, e.g., Tab, Backarrow and some special control character cases which are built into the X11 library, e.g., Control-Space to make a NUL, or Control-3 to make an Escape character. .IP Except for those special cases built into the X11 library, the Shift- and Control- modifiers are treated normally. The Alt- and Meta- modifiers do not cause \fI\*n\fP to send escape sequences. Those modifier keys are interpreted according to other resources, e.g., the \fBmetaSendsEscape\fP resource. .TP 5 2 enables this feature for keys including the exceptions listed. \fI\*N\fP ignores the special cases built into the X11 library. Any shifted (modified) ordinary key sends an escape sequence. The Alt- and Meta- modifiers cause \fI\*n\fP to send escape sequences. .TP 5 3 extends the feature to send unmodified keys as escape sequences. .RE .IP The \fI\*N\fP FAQ has an extended discussion of this feature, with examples: .sp .RS https://invisible\-island.net/xterm/modified\-keys.html .RE .TP 8 .B "modifySpecialKeys\fP (class\fB ModifySpecialKeys\fP)" Like \fBmodifyCursorKeys\fP \*(``4\*('', tells \fI\*n\fP to construct an escape sequence for \fIspecial\fP keys (e.g., \*(``escape\*('' not in the other categories). The default is \*(``0\*(''. .TP 8 .B "multiClickTime\fP (class\fB MultiClickTime\fP)" Specifies the maximum time in milliseconds between multi-click select events. The default is \*(``250\*('' milliseconds. .TP 8 .B "multiScroll\fP (class\fB MultiScroll\fP)" Specifies whether or not scrolling should be done asynchronously. The default is \*(``false\*(''. .TP 8 .B "nMarginBell\fP (class\fB Column\fP)" Specifies the number of characters from the right margin at which the margin bell should be rung, when enabled by the \fBmarginBell\fP resource. The default is \*(``10\*(''. .TP 8 .B "\fIname\fBKeymap\fR (class\fB \fIName\fBKeymap\fR)" See the discussion of the \fBkeymap()\fP action. .TP 8 .B "nextEventDelay\fP (class\fB NextEventDelay\fP)" Specifies a delay time in milliseconds before checking for new X events. The default is \*(``1\*(''. .TP 8 .B "numColorRegisters\fP (class\fB NumColorRegisters\fP)" If \fI\*n\fR is configured to support ReGIS or SIXEL graphics, this specifies the number of color-registers which are available. .IP If this resource is not specified, \fI\*n\fR uses a value determined by the \fBdecTerminalID\fP resource: .TS l l _ _ r r. \fBResult\fR \fBdecTerminalID\fR 4 125 4 240 4 241 4 330 16 340 2 382 1024 \fIother\fP .TE .TP 8 .B "numLock\fP (class\fB NumLock\fP)" If \*(``true\*('', \fI\*n\fR checks if NumLock is used as a modifier (see \fBxmodmap\fP(__mansuffix__)). If so, this modifier is used to simplify the logic when implementing special NumLock for the \fBsunKeyboard\fP resource. Also (when \fBsunKeyboard\fP is false), similar logic is used to find the modifier associated with the left and right Alt keys. The default is \*(``true\*(''. .TP 8 .B "oldXtermFKeys\fP (class\fB OldXtermFKeys\fP)" If \*(``true\*('', \fI\*n\fR will use old-style (X11R5) escape sequences for function keys F1 to F4, for compatibility with X Consortium \fI\*n\fR. Otherwise, it uses the VT100 codes for PF1 to PF4. The default is \*(``false\*(''. .IP Setting this resource has the same effect as setting the \fBkeyboardType\fP to \fBlegacy\fP. The \fBkeyboardType\fP resource is the preferred mechanism for selecting this mode. .IP The old-style escape sequences resemble VT220 keys, but appear to have been invented for \fI\*n\fP in X11R4. .TP 8 .B "on2Clicks\fP (class\fB On2Clicks\fP)" .TP .B "on3Clicks\fP (class\fB On3Clicks\fP)" .TP .B "on4Clicks\fP (class\fB On4Clicks\fP)" .TP .B "on5Clicks\fP (class\fB On5Clicks\fP)" Specify selection behavior in response to multiple mouse clicks. A single mouse click is always interpreted as described in the \fBSelection Functions\fP section (see \fBPOINTER USAGE\fP). Multiple mouse clicks (using the button which activates the \fBselect\-start\fP action) are interpreted according to the resource values of \fBon2Clicks\fP, etc. The resource value can be one of these: .RS .TP 3 .B word Select a \*(``word\*('' as determined by the \fBcharClass\fP resource. See the \fBCHARACTER CLASSES\fP section. .IP If the pointer is on a \*(``word\*('' then \fI\*n\fP searches back to the beginning of the word, and then to the end. .IP If the pointer is not on a \*(``word\*('' then the result depends on whether it is on whitespace (including a newline), or past the end of the line. In the latter case \fI\*n\fP may select a \*(``word\*('' beginning after the newline, if there is no additional whitespace. .TP .B line Select a line (counting wrapping). .TP .B group Select a group of adjacent lines (counting wrapping). The selection stops on a blank line, and does not extend outside the current page. .TP .B page Select all visible lines, i.e., the page. .TP .B all .br Select all lines, i.e., including the saved lines. .TP .B regex Select the best match for the POSIX extended regular expression (ERE) which follows in the resource value: .RS .bP \fI\*N\fP matches the regular expression against a byte array for the entire (possibly wrapped) line. That byte array may be UTF-8 or ISO-8859-1, depending on the mode in which \fI\*n\fP is running. .bP \fI\*N\fP steps through each byte-offset in this array, keeping track of the best (longest) match. If more than one match ties for the longest length, the first is used. .IP \fI\*N\fP does this to make it convenient to click anywhere in the area of interest and cause the regular expression to match the entire word, etc. .bP The \*(``^\*('' and \*(``$\*('' anchors in a regular expression denote the ends of the entire line. .bP If the regular expression contains backslashes \*(``\\\*('' those should be escaped \*(``\\\\\*('' because the X libraries interpret backslashes in resource strings. .RE .TP .B none No selection action is associated with this resource. \fI\*N\fP interprets it as the end of the list. For example, you may use it to disable triple (and higher) clicking by setting \fBon3Clicks\fP to \*(``none\*(''. .RE .IP The default values for \fBon2Clicks\fP and \fBon3Clicks\fP are \*(``word\*('' and \*(``line\*('', respectively. There is no default value for \fBon4Clicks\fP or \fBon5Clicks\fP, making those inactive. On startup, \fI\*n\fP determines the maximum number of clicks by the \fBon\fIX\fBClicks\fR resource values which are set. .TP 8 .B "openIm\fP (class\fB OpenIm\fP)" Tells \fI\*n\fP whether to open the input method at startup. The default is \*(``true\*(''. .TP 8 .B "pointerColor\fP (class\fB PointerColor\fP)" Specifies the foreground color of the pointer. The default is \*(``XtDefaultForeground\*(''. .TP 8 .B "pointerColorBackground\fP (class\fB PointerColorBackground\fP)" Specifies the background color of the pointer. The default is \*(``XtDefaultBackground\*(''. .TP 8 .B "pointerFont\fP (class\fB PointerFont\fP)" Specifies the font to be used for the pointer. The shapes specified by \fBpointerShape\fP are glyphs in this font. The resource value default is \fIcursor\fP. .TP 8 .B "pointerMode\fP (class\fB PointerMode\fP)" Specifies when the pointer may be hidden as the user types. It will be redisplayed if the user moves the mouse, or clicks one of its buttons. .RS .TP 3 0 never .TP 3 1 the application running in \fI\*n\fP has not activated mouse mode. This is the default. .TP 3 2 always. .RE .TP 8 .B "pointerShape\fP (class\fB Cursor\fP)" Specifies the name of the shape of the pointer. The default is \*(``xterm\*(''. .IP Other shapes can be selected. Here is a list of the \*(``core\*('' (i.e., \fIstandard\fP) names extracted from : .RS 5 .IP X_cursor, arrow, based_arrow_down, based_arrow_up, boat, bogosity, bottom_left_corner, bottom_right_corner, bottom_side, bottom_tee, box_spiral, center_ptr, circle, clock, coffee_mug, cross, cross_reverse, crosshair, diamond_cross, dot, dotbox, double_arrow, draft_large, draft_small, draped_box, exchange, fleur, gobbler, gumby, hand1, hand2, heart, icon, iron_cross, left_ptr, left_side, left_tee, leftbutton, ll_angle, lr_angle, man, middlebutton, mouse, pencil, pirate, plus, question_arrow, right_ptr, right_side, right_tee, rightbutton, rtl_logo, sailboat, sb_down_arrow, sb_h_double_arrow, sb_left_arrow, sb_right_arrow, sb_up_arrow, sb_v_double_arrow, shuttle, sizing, spider, spraycan, star, target, tcross, top_left_arrow, top_left_corner, top_right_corner, top_side, top_tee, trek, ul_angle, umbrella, ur_angle, watch, xterm .RE .IP If you are using a \fIcursor theme\fP, expect it to provide about a third of those names, while adding others. .TP 8 .B "popOnBell\fP (class\fB PopOnBell\fP)" Specifies whether the window would be raised when Control-G is received. The default is \*(``false\*(''. .IP If the window is iconified, this has no effect. However, the \fBzIconBeep\fP resource provides you with the ability to see which iconified windows have sounded a bell. .TP 8 .B "precompose\fP (class\fB Precompose\fP)" Tells \fI\*n\fP whether to precompose UTF-8 data into Normalization Form C, which combines commonly-used accents onto base characters. If it does not do this, accents are left as separate characters. The default is \*(``true\*(''. .TP 8 .B "preeditType\fP (class\fB PreeditType\fP)" Tells \fI\*n\fP which types of preedit (preconversion) string to display. The default is \*(``OverTheSpot,Root\*(''. .TP 8 .B "preferLatin1\fP (class\fB PreferLatin1\fP)" Tells \fI\*n\fP whether to use DEC Supplemental Graphic, or ISO Latin-1 for the user-preferred supplemental set (UPSS) when initializing character sets. The former is the documented setting for hardware terminals, but the latter is expected by most users. The default is \*(``true\*('' (ISO Latin-1). .TP 8 .B "printAttributes\fP (class\fB PrintAttributes\fP)" Specifies whether to print graphic attributes along with the text. A real DEC VT\fIxxx\fP terminal will print the underline, highlighting codes but your printer may not handle these. .RS .bP \*(``0\*('' disables the attributes. .bP \*(``1\*('' prints the normal set of attributes (bold, underline, inverse and blink) as VT100-style control sequences. .bP \*(``2\*('' prints ANSI color attributes as well. .RE .IP The default is \*(``1\*(''. .TP 8 .B "printFileImmediate\fP (class \fBPrintFileImmediate\fP)" When the \fBprint\-immediate\fP action is invoked, \fI\*n\fP prints the screen contents directly to a file. Set this resource to the prefix of the filename (a timestamp will be appended to the actual name). .IP The default is an empty string, i.e., \*(``\*('', However, when the \fBprint\-immediate\fP action is invoked, if the string is empty, then \*(``__default_class__\*('' is used. .TP 8 .B "printFileOnXError\fP (class \fBPrintFileOnXError\fP)" If \fI\*n\fP exits with an X error, e.g., your connection is broken when the server crashes, it can be told to write the contents of the screen to a file. To enable the feature, set this resource to the prefix of the filename (a timestamp will be appended to the actual name). .IP The default is an empty string, i.e., \*(``\*('', which disables this feature. However, when the \fBprint\-on\-error\fP action is invoked, if the string is empty, then \*(``XTermError\*('' is used. .IP These error codes are handled: ERROR_XERROR, ERROR_XIOERROR and ERROR_ICEERROR. .TP 8 .B "printModeImmediate\fP (class \fBPrintModeImmediate\fP)" When the \fBprint\-immediate\fP action is invoked, \fI\*n\fP prints the screen contents directly to a file. You can use the \fBprintModeImmediate\fP resource to tell it to use escape sequences to reconstruct the video attributes and colors. This uses the same values as the \fBprintAttributes\fP resource. The default is \*(``0\*(''. .TP 8 .B "printModeOnXError\fP (class \fBPrintModeOnXError\fP)" \fI\*N\fP implements the \fBprintFileOnXError\fP feature using the printer feature, although the output is written directly to a file. You can use the \fBprintModeOnXError\fP resource to tell it to use escape sequences to reconstruct the video attributes and colors. This uses the same values as the \fBprintAttributes\fP resource. The default is \*(``0\*(''. .TP 8 .B "printOptsImmediate\fP (class \fBPrintOptsImmediate\fP)" Specify the range of text which is printed to a file when the \fBprint\-immediate\fP action is invoked. .RS .bP If zero (0), then this selects the current (visible screen) plus the saved lines, except if the alternate screen is being used. In that case, only the alternate screen is selected. .bP If nonzero, the bits of this resource value (checked in descending order) select the range: .RS .TP 3 8 selects the saved lines. .TP 3 4 selects the alternate screen. .TP 3 2 selects the normal screen. .TP 3 1 selects the current screen, which can be either the normal or alternate screen. .RE .RE .IP The default is \*(``9\*('', which selects the current visible screen plus saved lines, with no special case for the alternated screen. .TP 8 .B "printOptsOnXError\fP (class \fBPrintOptsOnXError\fP)" Specify the range of text which is printed to a file when the \fBprint\-on\-error\fP action is invoked. The resource value is interpreted the same as in \fBprintOptsImmediate\fP. .IP The default is \*(``9\*('', which selects the current visible screen plus saved lines, with no special case for the alternated screen. .TP 8 .B "printRawChars\fP (class \fBPrintRawChars\fP)" If \*(``true\*('', \fI\*n\fR allows Unicode non-characters to be printed. .TP 8 .B "printerAutoClose\fP (class\fB PrinterAutoClose\fP)" If \*(``true\*('', \fI\*n\fR will close the printer (a pipe) when the application switches the printer offline with a Media Copy command. The default is \*(``false\*(''. .TP 8 .B "printerCommand\fP (class\fB PrinterCommand\fP)" Specifies a shell command to which \fI\*n\fP will open a pipe when the first MC (Media Copy) command is initiated. The default is an empty string, i.e., \*(``\*(''. If the resource value is given as an empty string, the printer is disabled. .TP 8 .B "printerControlMode\fP (class\fB PrinterControlMode\fP)" Specifies the printer control mode. A \*(``1\*('' selects autoprint mode, which causes \fI\*n\fP to print a line from the screen when .RS .bP you move the cursor off that line with a line feed, form feed or vertical tab character, or .bP an autowrap occurs. .RE .IP Autoprint mode is overridden by printer controller mode (a \*(``2\*(''), which causes all of the output to be directed to the printer. The default is \*(``0\*(''. .TP 8 .B "printerExtent\fP (class\fB PrinterExtent\fP)" Controls whether a print page function will print the entire page (true), or only the portion within the scrolling margins (false). The default is \*(``false\*(''. .TP 8 .B "printerFormFeed\fP (class\fB PrinterFormFeed\fP)" Controls whether a form feed is sent to the printer at the end of a print page function. The default is \*(``false\*(''. .TP 8 .B "printerNewLine\fP (class\fB PrinterNewLine\fP)" Controls whether a newline is sent to the printer at the end of a print page function. The default is \*(``true\*(''. .TP 8 .B "privateColorRegisters\fP (class\fB PrivateColorRegisters\fP)" If \fI\*n\fR is configured to support ReGIS or SIXEL graphics, this controls whether \fI\*n\fR allocates separate color registers for each sixel device control string, e.g., for DECGCI. If not true, color registers are allocated only once, when the terminal is reset, and color changes in any graphic affect all graphics. The default is \*(``true\*(''. .TP 8 .B "quietGrab\fP (class\fB QuietGrab\fP)" Controls whether the cursor is repainted when \fINotifyGrab\fP and \fINotifyUngrab\fP event types are received during change of focus. The default is \*(``false\*(''. .TP 8 .B "regisDefaultFont\fP (class\fB RegisDefaultFont\fP)" If \fI\*n\fR is configured to support ReGIS graphics, this resource tells \fI\*n\fR which font to use if the ReGIS data does not specify one. No default value is specified; \fI\*n\fR accepts a TrueType font specification as in the \fBfaceName\fP resource. .IP If no value is specified, \fI\*n\fR draws a bitmap indicating a missing character. .TP 8 .B "regisScreenSize\fP (class\fB RegisScreenSize\fP)" If \fI\*n\fR is configured to support ReGIS graphics, this resource tells \fI\*n\fR the default size (in pixels) for these graphics, which also sets the default coordinate space to [0,0] (upper-left) and [\fIwidth\fP,\fIheight\fP] (lower-right). .IP The application using ReGIS may use the \*(``A\*('' option of the \*(``S\*('' command to adjust the coordinate space or change the addressable portion of the screen. .IP \fI\*N\fR accepts a special resource value \*(``auto\*('', which tells \fI\*n\fR to use the \fBdecGraphicsID\fP and \fBdecTerminalID\fP resources to set the default size based on the hardware terminal's limits. Those limits are the same as for the \fBmaxGraphicSize\fP resource. .IP The default is \*(``auto\*(''. .TP 8 .B "renderFont\fP (class\fB RenderFont\fP)" If \fI\*n\fR is built with the Xft library, this controls whether the \fBfaceName\fR resource is used. The default is \*(``default\*(''. .IP The resource values are strings, evaluated as booleans after startup. .RS .TP 5 false .br disable the feature and use the normal (bitmap) font. .TP 5 true .br startup using the TrueType font specified by the \fBfaceName\fP and \fBfaceSize\fP resource settings. If there is no value for \fBfaceName\fP, disable the feature and use the normal (bitmap) font. .IP After startup, you can still switch to/from the bitmap font using the \*(``TrueType Fonts\*('' menu entry. .TP 5 default .br Enable the \*(``TrueType Fonts\*('' menu entry to allow runtime switching to/from TrueType fonts. The initial font used depends upon whether the \fBfaceName\fP resource is set: .RS .bP If the \fBfaceName\fP resource is not set, start by using the normal (bitmap) font. \fI\*N\fP has a separate compiled-in value for \fBfaceName\fP for this special case. That is normally \*(``mono\*(''. .bP If the \fBfaceName\fP resource is set, then start by using the TrueType font rather than the bitmap font. .RE .TP 5 defaultOff .br Enable the \*(``TrueType Fonts\*('' menu entry to allow runtime switching to/from TrueType fonts, but allow it to be initially unselected if no \fBfaceName\fP resource was given. .RE .TP 8 .B "resizeByPixel\fP (class\fB ResizeByPixel\fP)" Set this \*(``true\*('' to disable hints to the window manager that request resizing by character rather than pixels. .IP Most window managers provide visual feedback showing the size of a window as you resize it, using these hints. When you maximize \fI\*n\fP, it disables those hints to allow the window manager to make better use of fractional rows or columns. Setting this resource disables the hints all the time. .IP The default is \*(``false\*(''. .TP 8 .B "resizeGravity\fP (class\fB ResizeGravity\fP)" Affects the behavior when the window is resized to be taller or shorter. \fBNorthWest\fP specifies that the top line of text on the screen stay fixed. If the window is made shorter, lines are dropped from the bottom; if the window is made taller, blank lines are added at the bottom. This is compatible with the behavior in X11R4. \fBSouthWest\fP (the default) specifies that the bottom line of text on the screen stay fixed. If the window is made taller, additional saved lines will be scrolled down onto the screen; if the window is made shorter, lines will be scrolled off the top of the screen, and the top saved lines will be dropped. .TP 8 .B "retryInputMethod\fP (class\fB RetryInputMethod\fP)" Tells \fI\*n\fP how many times to retry, in case the input-method server is not responding. This is a different issue than unsupported preedit type, etc. You may encounter retries if your X configuration (and its libraries) are missing pieces. Setting this resource to zero \*(``0\*('' will cancel the retrying. The default is \*(``3\*(''. .TP 8 .B "reverseVideo\fP (class\fB ReverseVideo\fP)" Specifies whether or not reverse video should be simulated. The default is \*(``false\*(''. .IP There are several aspects to reverse video in \fI\*n\fP: .RS .bP The command-line \fB\-rv\fP option tells the X libraries to reverse the foreground and background colors. \fI\*N\fP's command-line options set resource values. In particular, the \fIX Toolkit\fP sets the \fBreverseVideo\fP resource when the \fB\-rv\fP option is used. .bP If the user has also used command-line options \fB\-fg\fP or \fB\-bg\fP to set the foreground and background colors, \fI\*n\fP does not see these options directly. Instead, it examines the resource values to reconstruct the command-line options, and determine which of the colors is the user's intended foreground, etc. Their actual values are irrelevant to the reverse video function; some users prefer the X defaults (black text on a white background), others prefer white text on a black background. .bP After startup, the user can toggle the \*(``Enable Reverse Video\*('' menu entry. This exchanges the current foreground and background colors of the VT100 widget, and repaints the screen. Because of the X resource hierarchy, the \fBreverseVideo\fP resource applies to more than the VT100 widget. .RE .IP Programs running in an \fI\*n\fP can also use control sequences to enable the VT100 reverse video mode. These are independent of the \fBreverseVideo\fP resource and the menu entry. \fI\*N\fP exchanges the current foreground and background colors when drawing text affected by these control sequences. .IP Other control sequences can alter the foreground and background colors which are used: .RS .bP Programs can also use the ANSI color control sequences to set the foreground and background colors. .bP Extensions to the ANSI color controls (such as 16-, 88- or 256-colors) are treated similarly to the ANSI control. .bP Using other control sequences (the \*(``\fIdynamic colors\fR\*('' feature), a program can change the foreground and background colors. .RE .TP 8 .B "reverseWrap\fP (class\fB ReverseWrap\fP)" Specifies whether or not reverse-wraparound should be enabled. This corresponds to \fI\*n\fP's private mode 45. The default is \*(``false\*(''. .TP 8 .B "rightScrollBar\fP (class\fB RightScrollBar\fP)" Specifies whether or not the scrollbar should be displayed on the right rather than the left. The default is \*(``false\*(''. .TP 8 .B "saveLines\fP (class\fB SaveLines\fP)" Specifies the number of lines to save beyond the top of the screen when a scrollbar is turned on. The default is \*(``1024\*(''. .TP 8 .B "scrollBar\fP (class\fB ScrollBar\fP)" Specifies whether or not the scrollbar should be displayed. The default is \*(``false\*(''. .TP 8 .B "scrollBarBorder\fP (class\fB ScrollBarBorder\fP)" Specifies the width of the scrollbar border. Note that this is drawn to overlap the border of the \fI\*n\fP window. Modifying the scrollbar's border affects only the line between the VT100 widget and the scrollbar. The default value is 1. .TP 8 .B "scrollKey\fP (class\fB ScrollCond\fP)" Specifies whether or not pressing a key should automatically cause the scrollbar to go to the bottom of the scrolling region. This corresponds to \fI\*n\fP's private mode 1011. The default is \*(``false\*(''. .TP 8 .B "scrollLines\fP (class\fB ScrollLines\fP)" Specifies the number of lines that the \fBscroll\-back\fP and \fBscroll\-forw\fP actions should use as a default. The default value is 1. .TP 8 .B "scrollTtyOutput\fP (class\fB ScrollCond\fP)" Specifies whether or not output to the terminal should automatically cause the scrollbar to go to the bottom of the scrolling region. The default is \*(``true\*(''. .TP .B "selectToClipboard\fP (class\fB SelectToClipboard\fP)" Tells \fI\*n\fP whether to use the \fBPRIMARY\fP or \fBCLIPBOARD\fP for \fBSELECT\fP tokens in the selection mechanism. The \fBset\-select\fP action can change this at runtime, allowing the user to work with programs that handle only one of these mechanisms. The default is \*(``false\*('', which tells it to use \fBPRIMARY\fP. .TP 8 .B "shiftEscape\fP (class\fB ShiftEscape\fP)" \fI\*N\fP uses the \fBtranslations\fP resource to determine how to invoke actions for selecting and copying text using the pointer (e.g., a mouse). It also provides a mouse protocol which can be used by applications running in an xterm to detect mouse button clicks. .IP The mouse protocol causes \fI\*n\fP to send special escape sequences which allow an application to determine if \fImodifiers\fP (i.e., one or more of \fIshift\fP, \fIcontrol\fP, \fIalt\fP, and \fImeta\fP) were used. .IP \fI\*N\fP provides this mouse protocol by interpreting button- and motion-events in the functions which the \fBtranslations\fP resource calls for selecting and copying text: .RS .IP .nf \fBinsert-selection\fP \fBselect-end\fP \fBselect-extend\fP \fBselect-start\fP \fBstart-extend\fP .fi .RE .IP While the mouse protocol is active, \fI\*n\fP reserves most of the mouse button events for sending special escape sequences to the application. \fI\*N\fP normally allows you to use the \fIshift\fP-key to temporarily override this mouse protocol, permitting the selection and copying actions to be used. .IP The \fBshiftEscape\fP resource setting allows you to tell \fI\*n\fP whether to use the \fIshift\fP-key in this way (i.e., overriding the mouse protocol). \fI\*N\fP accepts either a keyword (ignoring case) or the number shown in parentheses: .RS .TP 3 false (0) Mouse protocol does not send special escapes when \fIshift\fP-key is used. .TP 3 true (1) Mouse protocol may send special escapes when \fIshift\fP-key is used. .IP At startup, \fI\*n\fP analyzes the \fBtranslations\fP to see which buttons are used in the (mouse) button-related bindings for selection and copying text. If the \fIshift\fP-key is not mentioned explicitly in a button's binding, \fI\*n\fP allows that button with \fIshift\fP-key for overriding the mouse protocol. .TP 3 always (2) Mouse protocol can always send special escapes when \fIshift\fP-key is used. .TP 3 never (3) Mouse protocol will never send special escapes when \fIshift\fP-key is used. .RE .IP \fI\*N\fP interprets a control sequence which can change this setting between \*(``true\*('' and \*(``false\*(''. The default is \*(``false\*(''. .TP 8 .B "shiftFonts\fP (class\fB ShiftFonts\fP)" Specifies whether to enable the actions \fBlarger\-vt\-font()\fP and \fBsmaller\-vt\-font()\fP, which are normally bound to the shifted KP_Add and KP_Subtract. The default is \*(``true\*(''. .TP 8 .B "showBlinkAsBold\fP (class\fB ShowBlinkAsBold\fP)" Tells \fI\*n\fP whether to display text with blink-attribute the same as bold. If \fI\*n\fP has not been configured to support blinking text, the default is \*(``true\*('', which corresponds to older versions of \fI\*n\fP, otherwise the default is \*(``false\*(''. .TP 8 .B "showMissingGlyphs\fP (class\fB ShowMissingGlyphs\fP)" Tells \fI\*n\fP whether to display a box outlining places where a character has been used that the font does not represent. The default is \*(``true\*(''. .TP 8 .B "showWrapMarks\fP (class\fB ShowWrapMarks\fP)" For debugging \fI\*n\fP and applications that may manipulate the wrapped-line flag by writing text at the right margin, show a mark on the right inner-border of the window. The mark shows which lines have the flag set. .TP 8 .B "signalInhibit\fP (class\fB SignalInhibit\fP)" Specifies whether or not the entries in the \fBMain Options\fP menu for sending signals to \fI\*n\fP should be disallowed. The default is \*(``false\*(''. .TP 8 .B "sixelScrolling\fP (class\fB SixelScrolling\fP)" If \fI\*n\fR is configured to support SIXEL graphics, this resource tells it whether to scroll up one line at a time when sixels would be written past the bottom line on the window. The default is \*(``true\*('' which enables scrolling. .IP Sixel scrolling is the opposite of DEC Sixel Display Mode (DECSDM): when one is on, the other is off. .TP 8 .B "sixelScrollsRight\fP (class\fB SixelScrollsRight\fP)" If \fI\*n\fR is configured to support SIXEL graphics, this resource tells it whether to scroll to the right as needed to keep the current position visible rather than truncate the plot on the on the right. The default is \*(``false\*('' which disables scrolling. .TP 8 .B "tekGeometry\fP (class\fB Geometry\fP)" Specifies the preferred size and position of the Tektronix window. There is no default for this resource. .TP 8 .B "tekInhibit\fP (class\fB TekInhibit\fP)" Specifies whether or not the escape sequence to enter Tektronix mode should be ignored. The default is \*(``false\*(''. .TP 8 .B "tekSmall\fP (class\fB TekSmall\fP)" Specifies whether or not the Tektronix mode window should start in its smallest size if no explicit geometry is given. This is useful when running \fI\*n\fP on displays with small screens. The default is \*(``false\*(''. .TP 8 .B "tekStartup\fP (class\fB TekStartup\fP)" Specifies whether or not \fI\*n\fP should start up in Tektronix mode. The default is \*(``false\*(''. .TP 8 .B "tiXtraScroll\fP (class\fB TiXtraScroll\fP)" Specifies whether \fI\*n\fP should scroll to a new page when processing the \fIti\fP or \fIte\fP termcap strings, i.e., the private modes 47, 1047 or 1049. This is only in effect if \fBtiteInhibit\fP is \*(``true\*('', because the intent of this option is to provide a picture of the full-screen application's display on the scrollback without wiping out the text that would be shown before the application was initialized. .IP \fI\*N\fP accepts either a keyword (ignoring case) or the number shown in parentheses: .RS .TP false (0) nothing is added to the scrollback. .TP true (1) the current screen is added to the scrollback. .TP trim (2) the current screen is added to the scrollback, but repeated blank lines are trimmed (reduced to a single blank line). .RE .IP The default for this resource is \*(``false\*(''. .TP 8 .B "titeInhibit\fP (class\fB TiteInhibit\fP)" Originally specified whether or not \fI\*n\fP should remove \fIti\fP and \fIte\fP termcap entries (used to switch between alternate screens on startup of many screen-oriented programs) from the TERMCAP string. .IP TERMCAP is used rarely now, but \fI\*n\fP supports the feature on modern systems: .RS .bP If set, \fI\*n\fP also ignores the escape sequence to switch to the alternate screen. .bP \fI\*N\fP supports terminfo in a different way, supporting composite control sequences (also known as private modes) 1047, 1048 and 1049 which have the same effect as the original 47 control sequence. .RE .IP The default for this resource is \*(``false\*(''. .TP 8 .B "titleModes\fP (class\fB TitleModes\fP)" Tells \fI\*n\fP whether to accept or return window- and icon-labels in ISO-8859-1 (the default) or UTF-8. Either can be encoded in hexadecimal: .RS .bP UTF-8 titles require special treatment, because they may contain bytes which can be mistaken for control characters. Hexadecimal-encoding is supported to eliminate that possibility. .bP As an alternative, you could use the \fBallowC1Printable\fP resource, which suppresses \fI\*n\fP's parsing of the relevant control characters (and as a result, treats those bytes as data). .RE .IP The default for this resource is \*(``0\*(''. .IP Each bit (bit \*(``0\*('' is 1, bit \*(``1\*('' is 2, etc.) corresponds to one of the parameters set by the title modes control sequence: .RS .TP 5 0 Set window/icon labels using hexadecimal .TP 5 1 Query window/icon labels using hexadecimal .TP 5 2 Set window/icon labels using UTF-8 (gives the same effect as the \fButf8Title\fP resource). .TP 5 3 Query window/icon labels using UTF-8 .RE .TP 8 .B "translations\fP (class\fB Translations\fP)" Specifies the key and button bindings for menus, selections, \*(``programmed strings\*('', etc. The \fBtranslations\fP resource, which provides much of \fI\*n\fP's configurability, is a feature of the \fIX Toolkit Intrinsics\fP library (Xt). See the \fBActions\fP section. .TP 8 .B "trimSelection\fP (class\fB TrimSelection\fP)" If you set \fBhighlightSelection\fP, you can see the text which is selected, including any trailing spaces. Clearing the screen (or a line) resets it to a state containing no spaces. Some lines may contain trailing spaces when an application writes them to the screen. However, you may not wish to paste lines with trailing spaces. If this resource is true, \fI\*n\fP will trim trailing spaces from text which is selected. It does not affect spaces which result in a wrapped line, nor will it trim the trailing newline from your selection. The default is \*(``false\*(''. .TP 8 .B "underLine\fP (class\fB UnderLine\fP)" This specifies whether or not text with the underline attribute should be underlined. It may be desirable to disable underlining when color is being used for the underline attribute. The default is \*(``true\*(''. .TP 8 .B "useBorderClipping\fP (class\fB UseBorderClipping\fP)" Tell \fI\*n\fP whether to apply clipping when \fBuseClipping\fP is false. Unlike \fBuseClipping\fP, this simply limits text to keep it within the window borders, e.g., as a refinement to the \fBscaleHeight\fP workaround. The default is \*(``false\*(''. .TP 8 .B "useClipping\fP (class\fB UseClipping\fP)" Tell \fI\*n\fP whether to use clipping to keep from producing dots outside the text drawing area. Originally used to work around for overstriking effects, this is also needed to work with some incorrectly-sized fonts. The default is \*(``true\*(''. .TP 8 .B "utf8\fP (class\fB Utf8\fP)" This specifies whether \fI\*n\fP will run in UTF-8 mode. If you set this resource, \fI\*n\fP also sets the \fBwideChars\fP resource as a side-effect. The resource can be set via the menu entry \*(``UTF\-8 Encoding\*(''. The default is \*(``default\*(''. .IP \fI\*N\fP accepts either a keyword (ignoring case) or the number shown in parentheses: .RS .TP 3 false (0) UTF-8 mode is initially off. The command-line option \fB+u8\fP sets the resource to this value. Escape sequences for turning UTF-8 mode on/off are allowed. .TP true (1) UTF-8 mode is initially on. Escape sequences for turning UTF-8 mode on/off are allowed. .TP always (2) The command-line option \fB\-u8\fP sets the resource to this value. Escape sequences for turning UTF-8 mode on/off are ignored. .TP default (3) This is the default value of the resource. It is changed during initialization depending on whether the \fBlocale\fP resource was set, to false (0) or always (2). See the \fBlocale\fR resource for additional discussion of non-UTF-8 locales. .RE .IP If you want to set the value of \fButf8\fP, it should be in this range. Other nonzero values are treated the same as \*(``1\*('', i.e., UTF-8 mode is initially on, and escape sequences for turning UTF-8 mode on/off are allowed. .TP 8 .B "utf8Fonts\fP (class\fB Utf8Fonts\fP)" See the discussion of the \fBlocale\fP resource. This specifies whether \fI\*n\fP will use UTF-8 fonts specified via resource patterns such as \*(``\fB*vt100.utf8Fonts.font\fP\*('' or normal (ISO-8859-1) fonts via patterns such as \*(``\fB*vt100.font\fP\*(''. The resource can be set via the menu entry \*(``\fBUTF\-8 Fonts\fP\*(''. The default is \*(``default\*(''. .IP \fI\*N\fP accepts either a keyword (ignoring case) or the number shown in parentheses: .RS .TP false (0) Use the ISO-8859-1 fonts. The menu entry is enabled, allowing the choice of fonts to be changed at runtime. .TP true (1) Use the UTF-8 fonts. The menu entry is enabled, allowing the choice of fonts to be changed at runtime. .TP always (2) Always use the UTF-8 fonts. This also disables the menu entry. .TP default (3) At startup, the resource is set to true or false, according to the effective value of the \fButf8\fP resource. .RE .TP 8 .B "utf8Latin1\fP (class\fB Utf8Latin1\fP)" If true, allow an ISO-8859-1 \fInormal\fP font to be combined with an ISO-10646-1 font if the latter is given via the \fB\-fw\fP option or its corresponding resource value. The default is \*(``false\*(''. .TP 8 .B "utf8SelectTypes\fP (class\fB Utf8SelectTypes\fP)" Override \fI\*n\fP's default selection target list (see \fBSELECT/PASTE\fP) for selections in wide-character (UTF-8) mode. The default is an empty string, i.e., \*(``\*('', which does not override anything. .TP 8 .B "utf8Title\fP (class\fB Utf8Title\fP)" Applications can set \fI\*n\fP's title by writing a control sequence. Normally this control sequence follows the VT220 convention, which encodes the string in ISO-8859-1 and allows for an 8-bit string terminator. If \fI\*n\fP is started in a UTF-8 locale, it translates the ISO-8859-1 string to UTF-8 to work with the X libraries which assume the string is UTF-8. .IP However, some users may wish to write a title string encoded in UTF-8. The window manager is responsible for drawing window titles. Some window managers (not all) support UTF-8 encoding of window titles. Set this resource to \*(``true\*('' to also set UTF-8 encoded title strings using the EWMH properties. .IP This feature is available as a menu entry, since it is related to the particular applications you are running within \fI\*n\fP. You can also use a control sequence (see the discussion of \*(``Title Modes\*('' in \fI\*N Control Sequences\fP), to set an equivalent flag (which can also be set using the \fBtitleModes\fP resource). .IP \fI\*N\fP accepts either a keyword (ignoring case) or the number shown in parentheses: .RS .TP false (0) Set only ISO-8859-1 title strings, e.g., using the ICCCM \fBWM_NAME\fP STRING property. The menu entry is enabled, allowing the choice of title-strings to be changed at runtime. .TP true (1) Set both the EWMH (UTF-8 strings) and the ICCCM \fBWM_NAME\fP, etc. The menu entry is enabled, allowing the choice to be changed at runtime. .TP always (2) Always set both the EWMH (UTF-8 strings) and the ICCCM \fBWM_NAME\fP, etc. This also disables the menu entry. .TP default (3) At startup, the resource is set to true or false, according to the effective value of the \fButf8\fP resource. .RE .IP The default is \*(``default\*(''. .TP 8 .B "utf8Weblike\fP (class\fB Utf8Weblike\fP)" Provide an alternate error-handling scheme for ill-formed UTF-8 as recommended in a W3C document. The Unicode standard does not require this for conformance. Some additional information can be found here: .sp .RS https://invisible\-island.net/xterm/bad\-utf8/ .RE .IP The default is \*(``false\*(''. .TP 8 .B "veryBoldColors\fP (class\fB VeryBoldColors\fP)" Specifies whether to combine video attributes with colors specified by \fBcolorBD\fR, \fBcolorBL\fR, \fBcolorIT\fR, \fBcolorRV\fR, and \fBcolorUL\fR. The resource value is the sum of values for each attribute: .RS 10 .nf 1 for reverse, 2 for underline, 4 for bold, 8 for blink, and 512 for italic .fi .RE .IP The default is \*(``0\*(''. .TP 8 .B "visualBell\fP (class\fB VisualBell\fP)" Specifies whether or not a visible bell (i.e., flashing) should be used instead of an audible bell when Control-G is received. The default is \*(``false\*('', which tells \fI\*n\fP to use an audible bell. .TP 8 .B "visualBellDelay\fP (class\fB VisualBellDelay\fP)" Number of milliseconds to delay when displaying a visual bell. Default is 100. If set to zero, no visual bell is displayed. This is useful for very slow displays, e.g., an LCD display on a laptop. .TP 8 .B "visualBellLine\fP (class\fB VisualBellLine\fP)" Specifies whether to flash only the current line when displaying a visual bell rather than flashing the entire screen: The default is \*(``false\*('', which tells \fI\*n\fP to flash the entire screen. .TP 8 .B "vt100Graphics\fP (class\fB VT100Graphics\fP)" This specifies whether \fI\*n\fP will interpret VT100 graphic character escape sequences while in UTF-8 mode. This feature also applies to code-pages (e.g., for VT320 and VT520) and National Replacement Character Sets (VT220 and up), but not US-ASCII (the initially selected character set), to avoid conflict with UTF-8. The default is \*(``true\*('', to provide support for various legacy applications. .TP 8 .B "wideBoldFont\fP (class\fB WideBoldFont\fP)" This option specifies the font to be used for displaying bold wide text. By default, it will attempt to use a font twice as wide as the font that will be used to draw bold text. If no double-width font is found, it will improvise, by stretching the bold font. .TP 8 .B "wideChars\fP (class\fB WideChars\fP)" Specifies if \fI\*n\fP should respond to control sequences that process 16-bit characters. The default is \*(``false\*(''. .TP 8 .B "wideFont\fP (class\fB WideFont\fP)" This option specifies the font to be used for displaying wide text. By default, it will attempt to use a font twice as wide as the font that will be used to draw normal text. If no double-width font is found, it will improvise, by stretching the normal font. .TP 8 .B "xftMaxGlyphMemory\fP (class\fB XftMaxGlyphMemory\fP)" Set the Xft library's limit on glyph memory (typically 4Mb). When it reaches this limit, it discards \*(``randomly chosen\*('' glyphs to make room for new ones. The default is \*(``0\*('' to use Xft's default value. .TP 8 .B "xftMaxUnrefFonts\fP (class\fB XftMaxUnrefFonts\fP)" Set the Xft library's limit on fonts which have been loaded (typically 16), e.g., matching patterns for fallback searches, but are not actually used. The default is \*(``0\*('' to use Xft's default value. .TP 8 .B "xftTrackMemUsage\fP (class\fB XftTrackMemUsage\fP)" Enables glyph memory tracking (introduced in Xft 2.3.5), which allows Xft to efficiently discard obsolete data when running short of memory. The default is \*(``false\*(''. .TP 8 .B "ximFont\fP (class\fB XimFont\fP)" This option specifies the font to be used for displaying the preedit string in the \*(``OverTheSpot\*('' input method. .IP In \*(``OverTheSpot\*('' preedit type, the preedit (preconversion) string is displayed at the position of the cursor. It is the XIM server's responsibility to display the preedit string. The XIM client must inform the XIM server of the cursor position. For best results, the preedit string must be displayed with a proper font. Therefore, \fI\*n\fP informs the XIM server of the proper font. The font is be supplied by a "fontset", whose default value is \*(``*\*(''. This matches every font, the X library automatically chooses fonts with proper charsets. The \fBximFont\fP resource is provided to override this default font setting. .\" .SS "Tek4014 Widget Resources" The following resources are specified as part of the \fItek4014\fP widget (class \fITek4014\fP). These are specified by patterns such as \*(``\fB__default_class__.tek4014.\fINAME\fR\*('': .TP 8 .B "font2\fP (class\fB Font\fP)" Specifies font number 2 to use in the Tektronix window. .TP 8 .B "font3\fP (class\fB Font\fP)" Specifies font number 3 to use in the Tektronix window. .TP 8 .B "fontLarge\fP (class\fB Font\fP)" Specifies the large font to use in the Tektronix window. .TP 8 .B "fontSmall\fP (class\fB Font\fP)" Specifies the small font to use in the Tektronix window. .TP 8 .B "ginTerminator\fP (class\fB GinTerminator\fP)" Specifies what character(s) should follow a GIN report or status report. The possibilities are \*(``none\*('', which sends no terminating characters, \*(``CRonly\*('', which sends CR, and \*(``CR&EOT\*('', which sends both CR and EOT. The default is \*(``none\*(''. .TP 8 .B "height\fP (class\fB Height\fP)" Specifies the height of the Tektronix window in pixels. .TP 8 .B "initialFont\fP (class\fB InitialFont\fP)" Specifies which of the four Tektronix fonts to use initially. Values are the same as for the \fBset\-tek\-text\fP action. The default is \*(``large\*(''. .TP 8 .B "width\fP (class\fB Width\fP)" Specifies the width of the Tektronix window in pixels. .\" .SS "Menu Resources" The resources that may be specified for the various menus are described in the documentation for the \fIAthena\fP \fBSimpleMenu\fP widget. The name and classes of the entries in each of the menus are listed below. Resources named \*(``\fBline\fIN\fR\*('' where \fIN\fR is a number are separators with class \fBSmeLine\fR. .PP As with all X resource-based widgets, the labels mentioned are customary defaults for the application. . .PP The \fBMain Options\fP menu (widget name \fImainMenu\fP) has the following entries: .TP 8 .B "toolbar\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-toolbar(\fItoggle\fB)\fR action. .TP 8 .B "securekbd\fP (class\fB SmeBSB\fP)" This entry invokes the \fBsecure()\fP action. .TP 8 .B "allowsends\fP (class\fB SmeBSB\fP)" This entry invokes the \fBallow\-send\-events(\fItoggle\fB)\fR action. .TP 8 .B "redraw\fP (class\fB SmeBSB\fP)" This entry invokes the \fBredraw()\fP action. .TP 8 .B "logging\fP (class\fB SmeBSB\fP)" This entry invokes the \fBlogging(\fItoggle\fB)\fR action. .TP 8 .B "print\-immediate\fP (class\fB SmeBSB\fP)" This entry invokes the \fBprint\-immediate()\fP action. .TP 8 .B "print\-on\-error\fP (class\fB SmeBSB\fP)" This entry invokes the \fBprint\-on\-error()\fP action. .TP 8 .B "print\fP (class\fB SmeBSB\fP)" This entry invokes the \fBprint()\fP action. .TP 8 .B "print\-redir\fP (class\fB SmeBSB\fP)" This entry invokes the \fBprint\-redir()\fP action. .TP 8 .B "dump\-html\fP (class\fB SmeBSB\fP)" This entry invokes the \fBdump\-html()\fP action. .TP 8 .B "dump\-svg\fP (class\fB SmeBSB\fP)" This entry invokes the \fBdump\-svg()\fP action. .TP 8 .B "8\-bit\-control\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-8\-bit\-control(\fItoggle\fB)\fR action. .TP 8 .B "backarrow\ key\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-backarrow(\fItoggle\fB)\fR action. .TP 8 .B "num\-lock\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-num\-lock(\fItoggle\fB)\fR action. .TP 8 .B "alt\-esc\fP (class\fB SmeBSB\fP)" This entry invokes the \fBalt\-sends\-escape(\fItoggle\fB)\fR action. .TP 8 .B "meta\-esc\fP (class\fB SmeBSB\fP)" This entry invokes the \fBmeta\-sends\-escape(\fItoggle\fB)\fR action. .TP 8 .B "delete\-is\-del\fP (class\fB SmeBSB\fP)" This entry invokes the \fBdelete\-is\-del(\fItoggle\fB)\fR action. .TP 8 .B "oldFunctionKeys\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-old\-function\-keys(\fItoggle\fB)\fR action. .TP 8 .B "hpFunctionKeys\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-hp\-function\-keys(\fItoggle\fB)\fR action. .TP 8 .B "scoFunctionKeys\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-sco\-function\-keys(\fItoggle\fB)\fR action. .TP 8 .B "sunFunctionKeys\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-sun\-function\-keys(\fItoggle\fB)\fR action. .TP 8 .B "sunKeyboard\fP (class\fB SmeBSB\fP)" This entry invokes the \fBsunKeyboard(\fItoggle\fB)\fR action. .TP 8 .B "suspend\fP (class\fB SmeBSB\fP)" This entry invokes the \fBsend\-signal(\fItstp\fB)\fR action on systems that support job control. .TP 8 .B "continue\fP (class\fB SmeBSB\fP)" This entry invokes the \fBsend\-signal(\fIcont\fB)\fR action on systems that support job control. .TP 8 .B "interrupt\fP (class\fB SmeBSB\fP)" This entry invokes the \fBsend\-signal(\fIint\fB)\fR action. .TP 8 .B "hangup\fP (class\fB SmeBSB\fP)" This entry invokes the \fBsend\-signal(\fIhup\fB)\fR action. .TP 8 .B "terminate\fP (class\fB SmeBSB\fP)" This entry invokes the \fBsend\-signal(\fIterm\fB)\fR action. .TP 8 .B "kill\fP (class\fB SmeBSB\fP)" This entry invokes the \fBsend\-signal(\fIkill\fB)\fR action. .TP 8 .B "quit\fP (class\fB SmeBSB\fP)" This entry invokes the \fBquit()\fP action. . .PP The \fBVT Options\fP menu (widget name \fIvtMenu\fP) has the following entries: .TP 8 .B "scrollbar\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-scrollbar(\fItoggle\fB)\fR action. .TP 8 .B "jumpscroll\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-jumpscroll(\fItoggle\fB)\fR action. .TP 8 .B "reversevideo\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-reverse\-video(\fItoggle\fB)\fR action. .TP 8 .B "autowrap\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-autowrap(\fItoggle\fB)\fR action. .TP 8 .B "reversewrap\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-reversewrap(\fItoggle\fB)\fR action. .TP 8 .B "autolinefeed\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-autolinefeed(\fItoggle\fB)\fR action. .TP 8 .B "appcursor\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-appcursor(\fItoggle\fB)\fR action. .TP 8 .B "appkeypad\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-appkeypad(\fItoggle\fB)\fR action. .TP 8 .B "scrollkey\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-scroll\-on\-key(\fItoggle\fB)\fR action. .TP 8 .B "scrollttyoutput\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-scroll\-on\-tty\-output(\fItoggle\fB)\fR action. .TP 8 .B "allow132\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-allow132(\fItoggle\fB)\fR action. .TP 8 .B "cursesemul\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-cursesemul(\fItoggle\fB)\fR action. .TP 8 .B "keepSelection\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-keep\-selection(\fItoggle\fB)\fR action. .TP 8 .B "selectToClipboard\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-keep\-clipboard(\fItoggle\fB)\fR action. .TP 8 .B "visualbell\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-visual\-bell(\fItoggle\fB)\fR action. .TP 8 .B "bellIsUrgent\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-bellIsUrgent(\fItoggle\fB)\fR action. .TP 8 .B "poponbell\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-pop\-on\-bell(\fItoggle\fB)\fR action. .TP 8 .B "cursorblink\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-cursorblink(\fItoggle\fB)\fR action. .TP 8 .B "titeInhibit\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-titeInhibit(\fItoggle\fB)\fR action. .TP 8 .B "activeicon\fP (class\fB SmeBSB\fP)" This entry toggles active icons on and off if this feature was compiled into \fI\*n\fP. It is enabled only if \fI\*n\fP was started with the command line option +ai or the \fBactiveIcon\fP resource is set to \*(``true\*(''. .TP 8 .B "softreset\fP (class\fB SmeBSB\fP)" This entry invokes the \fBsoft\-reset()\fP action. .TP 8 .B "hardreset\fP (class\fB SmeBSB\fP)" This entry invokes the \fBhard\-reset()\fP action. .TP 8 .B "clearsavedlines\fP (class\fB SmeBSB\fP)" This entry invokes the \fBclear\-saved\-lines()\fP action. .TP 8 .B "tekshow\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-visibility(\fItek,toggle\fB)\fR action. .TP 8 .B "tekmode\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-terminal\-type(\fItek\fB)\fR action. .TP 8 .B "vthide\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-visibility(\fIvt,off\fB)\fR action. .TP 8 .B "altscreen\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-altscreen(\fItoggle\fB)\fR action. .TP 8 .B "sixelScrolling\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-sixel\-scrolling(\fItoggle\fB)\fR action. .TP 8 .B "privateColorRegisters\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-private\-colors(\fItoggle\fB)\fR action. . .PP The \fBVT Fonts\fP menu (widget name \fIfontMenu\fP) has the following entries: .TP 8 .B "fontdefault\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-vt\-font(\fId\fB)\fR action, setting the font using the \fBfont\fP (default) resource, e.g., \*(``Default\*('' in the menu. .TP 8 .B "font1\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-vt\-font(\fI1\fB)\fR action, setting the font using the \fBfont1\fP resource, e.g., \*(``Unreadable\*('' in the menu. .TP 8 .B "font2\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-vt\-font(\fI2\fB)\fR action, setting the font using the \fBfont2\fP resource, e.g., \*(``Tiny\*('' in the menu. .TP 8 .B "font3\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-vt\-font(\fI3\fB)\fR action, setting the font using the \fBfont3\fP resource, e.g., \*(``Small\*('' in the menu. .TP 8 .B "font4\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-vt\-font(\fI4\fB)\fR action, letting the font using the \fBfont4\fP resource, e.g., \*(``Medium\*('' in the menu. .TP 8 .B "font5\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-vt\-font(\fI5\fB)\fR action, letting the font using the \fBfont5\fP resource, e.g., \*(``Large\*('' in the menu. .TP 8 .B "font6\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-vt\-font(\fI6\fB)\fR action, letting the font using the \fBfont6\fP resource, e.g., \*(``Huge\*('' in the menu. .TP 8 .B "font7\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-vt\-font(\fI7\fB)\fR action, letting the font using the \fBfont7\fP resource, e.g., \*(``Enormous\*('' in the menu. .TP 8 .B "fontescape\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-vt\-font(\fIe\fB)\fR action. .TP 8 .B "fontsel\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-vt\-font(\fIs\fB)\fR action. .TP 8 .B "allow\-bold\-fonts\fP (class\fB SmeBSB\fP)" This entry invokes the \fBallow\-bold\-fonts(\fItoggle\fB)\fR action. .TP 8 .B "font\-linedrawing\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-font\-linedrawing(\fIs\fB)\fR action. .TP 8 .B "font\-packed\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-font\-packed(\fIs\fB)\fR action. .TP 8 .B "font\-doublesize\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-font\-doublesize(\fIs\fB)\fR action. .TP 8 .B "render\-font\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-render\-font(\fIs\fB)\fR action. .TP 8 .B "utf8\-fonts\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-utf8\-fonts(\fIs\fB)\fR action. .TP 8 .B "utf8\-mode\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-utf8\-mode(\fIs\fB)\fR action. .TP 8 .B "utf8\-title\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-utf8\-title(\fIs\fB)\fR action. .TP 8 .B "allow\-color\-ops\fP (class\fB SmeBSB\fP)" This entry invokes the \fBallow\-color\-ops(\fItoggle\fB)\fR action. .TP 8 .B "allow\-font\-ops\fP (class\fB SmeBSB\fP)" This entry invokes the \fBallow\-font\-ops(\fItoggle\fB)\fR action. .TP 8 .B "allow\-tcap\-ops\fP (class\fB SmeBSB\fP)" This entry invokes the \fBallow\-tcap\-ops(\fItoggle\fB)\fR action. .TP 8 .B "allow\-title\-ops\fP (class\fB SmeBSB\fP)" This entry invokes the \fBallow\-title\-ops(\fItoggle\fB)\fR action. .TP 8 .B "allow\-window\-ops\fP (class\fB SmeBSB\fP)" This entry invokes the \fBallow\-window\-ops(\fItoggle\fB)\fR action. . .PP The \fBTek Options\fP menu (widget name \fItekMenu\fP) has the following entries: .TP 8 .B "tektextlarge\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-tek\-text(\fIlarge\fB)\fR action. .TP 8 .B "tektext2\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-tek\-text(\fI2\fB)\fR action. .TP 8 .B "tektext3\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-tek\-text(\fI3\fB)\fR action. .TP 8 .B "tektextsmall\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-tek\-text(\fIsmall\fB)\fR action. .TP 8 .B "tekpage\fP (class\fB SmeBSB\fP)" This entry invokes the \fBtek\-page()\fP action. .TP 8 .B "tekreset\fP (class\fB SmeBSB\fP)" This entry invokes the \fBtek\-reset()\fP action. .TP 8 .B "tekcopy\fP (class\fB SmeBSB\fP)" This entry invokes the \fBtek\-copy()\fP action. .TP 8 .B "vtshow\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-visibility(\fIvt,toggle\fB)\fR action. .TP 8 .B "vtmode\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-terminal\-type(\fIvt\fB)\fR action. .TP 8 .B "tekhide\fP (class\fB SmeBSB\fP)" This entry invokes the \fBset\-visibility(\fItek,toggle\fB)\fR action. .\" .SS "Scrollbar Resources" The following resources are useful when specified for the \fIAthena\fP Scrollbar widget: .TP 8 .B "background\fP (class\fB Background\fP)" Specifies the color to use for the background of the scrollbar. .TP 8 .B "foreground\fP (class\fB Foreground\fP)" Specifies the color to use for the foreground of the scrollbar. .TP 8 .B "thickness\fP (class\fB Thickness\fP)" Specifies the width in pixels of the scrollbar (default: 14). .IP This may be overridden by the \fBwidth\fP resource. .TP 8 .B "thumb\fP (class\fB Thumb\fP)" The default \*(``thumb\*('' pixmap used for the scrollbar is a simple checkerboard pattern alternating pixels for foreground and background color. .TP 8 .B "width\fP (class\fB Width\fP)" Specifies the width in pixels of the scrollbar (default: 0). .IP The widget checks the \fIwidth\fP resource first, using the \fIthickness\fP value if the \fIwidth\fP is zero. . . .SH "POINTER USAGE" . Once the VT\fIxxx\fP window is created, \fI\*n\fP allows you to select text and copy it within the same or other windows using the \fIpointer\fP or the keyboard. . .PP A \*(``pointer\*('' could be a mouse, touchpad or similar device. X applications generally do not care, since they see only \fIbutton events\fP which have .bP position and .bP button up/down state .PP \fI\*N\fP can see these events as long as it has \fIfocus\fP. .PP The keyboard also supplies events, but it is less flexible than the pointer for selecting/copying text. .PP \fIEvents\fP are applied to \fIactions\fP using the \fBtranslations\fP resource. See \fBActions\fP for a complete list, and \fBDefault Key Bindings\fP for the built-in set of \fBtranslations\fP resources. . .SS "Selection Functions" By default, the selection functions are invoked when the pointer buttons are used with no modifiers, and when they are used with the \*(``shift\*('' key. The \*(``shift\*('' key is special, because \fI\*n\fP uses that to ensure that selection functions are still available when it is programmed to send escape sequences in one of the mouse modes (see \fIXterm Control Sequences\fP, as well as the resource \fBdisallowedMouseOps\fP). .PP At startup, \fI\*n\fP inspects the \fBtranslations\fP resource to see which pointer buttons may be used in this way, and remembers these buttons when deciding whether to send escape sequences or perform selection when those buttons are used with the \*(``shift\*('' modifier. Other pointer buttons, e.g., typically those sent for wheel mouse events, are not affected. .PP The assignment of the functions described below to keys and buttons may be changed through the resource database; see \fBActions\fP below. . .TP 5 Pointer button one (usually left) is used to save text into the cut buffer: .NS ~Meta :\fBselect\-start\fP() .NE .IP Move the cursor to beginning of the text, and then hold the button down while moving the cursor to the end of the region and releasing the button. The selected text is highlighted and is saved in the global \fIcut buffer\fP and made the selection when the button is released: .NS :\fBselect\-end\fP(\fBSELECT\fP, \fBCUT_BUFFER0\fP) \en .NE .IP Normally (but see the discussion of \fBon2Clicks\fP, etc): .RS .bP Double-clicking selects by words. .bP Triple-clicking selects by lines. .bP Quadruple-clicking goes back to characters, etc. .RE .IP Multiple-click is determined by the time from button up to button down, so you can change the selection unit in the middle of a selection. Logical words and lines selected by double- or triple-clicking may wrap across more than one screen line if lines were wrapped by \fI\*n\fP itself rather than by the application running in the window. If the key/button bindings specify that an X selection is to be made, \fI\*n\fP will leave the selected text highlighted for as long as it is the selection owner. . .TP 5 Pointer button two (usually middle) \*(``types\*('' (\fIpastes\fP) the text from the given selection, if any, otherwise from the cut buffer, inserting it as keyboard input: .NS ~Ctrl ~Meta :\fB\fBinsert\-selection\fP\fP(\fBSELECT\fP, \fBCUT_BUFFER0\fP) .NE . .TP 5 Pointer button three (usually right) \fIextends\fP the current selection. .NS ~Ctrl ~Meta :\fB\fBstart\-extend\fP\fP() .NE .IP (Without loss of generality, you can swap \*(``right\*('' and \*(``left\*('' everywhere in the rest of this paragraph.) If pressed while closer to the right edge of the selection than the left, it extends/contracts the right edge of the selection. If you contract the selection past the left edge of the selection, \fI\*n\fP assumes you really meant the left edge, restores the original selection, then extends/contracts the left edge of the selection. Extension starts in the selection unit mode that the last selection or extension was performed in; you can multiple-click to cycle through them. . .PP By cutting and pasting pieces of text without trailing new lines, you can take text from several places in different windows and form a command to the shell, for example, or take output from a program and insert it into your favorite editor. Since cut buffers are globally shared among different applications, you may regard each as a \*(``file\*('' whose contents you know. The terminal emulator and other text programs should be treating it as if it were a text file, i.e., the text is delimited by new lines. . .SS "Scrolling" The scroll region displays the position and amount of text currently showing in the window (highlighted) relative to the amount of text actually saved. As more text is saved (up to the maximum), the size of the highlighted area decreases. . .PP Clicking button one with the pointer in the scroll region moves the adjacent line to the top of the display window. . .PP Clicking button three moves the top line of the display window down to the pointer position. . .PP Clicking button two moves the display to a position in the saved text that corresponds to the pointer's position in the scrollbar. . .SS "Tektronix Pointer" Unlike the VT\fIxxx\fP window, the Tektronix window does not allow the copying of text. It does allow Tektronix GIN mode, and in this mode the cursor will change from an arrow to a cross. Pressing any key will send that key and the current coordinate of the cross cursor. Pressing button one, two, or three will return the letters \*(``l\*('', \*(``m\*('', and \*(``r\*('', respectively. If the \*(``shift\*('' key is pressed when a pointer button is pressed, the corresponding upper case letter is sent. To distinguish a pointer button from a key, the high bit of the character is set (but this is bit is normally stripped unless the terminal mode is RAW; see .IR tty (4) for details). . . .SH "SELECT/PASTE" X clients provide select and paste support by responding to requests conveyed by the X server. The X server holds data in \*(``atoms\*('' which correspond to the different types of selection (\fBPRIMARY\fP, \fBSECONDARY\fP, \fBCLIPBOARD\fP) as well as the similar cut buffer mechanism (\fBCUT_BUFFER0\fP to \fBCUT_BUFFER7\fP). Those are documented in the ICCCM. .PP The ICCCM deals with the underlying mechanism for select/paste. It does not mention \fIhighlighting\fP. The \fIselection\fP is not the same as \fIhighlighting\fP. \fI\*N\fP (like many applications) uses highlighting to show you the currently selected text. An X application may \fIown\fP a selection, which allows it to be the source of data copied using a given selection atom \fI\*N\fP may continue owning a selection after it stops highlighting (see \fBkeepSelection\fP). .SS PRIMARY When configured to use the primary selection (the default), \fI\*n\fP can provide the selection data in ways which help to retain character encoding information as it is pasted. .PP The \fBPRIMARY\fP token is a standard X feature, documented in the ICCCM (\fIInter-Client Communication Conventions Manual\fR), which states .RS 3 .PP The selection named by the atom \fBPRIMARY\fP is used for all commands that take only a single argument and is the principal means of communication between clients that use the selection mechanism. .RE .PP A user \*(``selects\*('' text on \fI\*n\fP, which highlights the selected text. A subsequent \*(``paste\*('' to another client forwards a request to the client owning the selection. If \fI\*n\fP owns the primary selection, it makes the data available in the form of one or more \*(``selection targets\*(''. If it does not own the primary selection, e.g., if it has released it or another client has asserted ownership, it relies on cut-buffers to pass the data. But cut-buffers handle only ISO-8859-1 data (officially \- some clients ignore the rules). . .SS CLIPBOARD When configured to use the clipboard (using the \fBselectToClipboard\fP resource), the problem with persistence of ownership is bypassed. Otherwise, there is no difference regarding the data which can be passed via selection. .PP The \fBselectToClipboard\fP resource is a compromise, allowing \fBCLIPBOARD\fP to be treated almost like \fBPRIMARY\fP, unlike the ICCCM, which describes \fBCLIPBOARD\fP in different terms than \fBPRIMARY\fP or \fBSECONDARY\fP. Its lengthy explanation begins with the essential points: .RS 3 .PP The selection named by the atom CLIPBOARD is used to hold data that is being transferred between clients, that is, data that usually is being cut and then pasted or copied and then pasted. Whenever a client wants to transfer data to the clipboard: .bP It should assert ownership of the CLIPBOARD. .bP If it succeeds in acquiring ownership, it should be prepared to respond to a request for the contents of the CLIPBOARD in the usual way (retaining the data to be able to return it). The request may be generated by the clipboard client described below. .RE .SS SELECT However, many applications use \fBCLIPBOARD\fP in imitation of other windowing systems. The \fBselectToClipboard\fP resource (and corresponding menu entry \fBSelect to Clipboard\fP) introduce the \fBSELECT\fP token (known only to \fI\*n\fP) which chooses between the \fBPRIMARY\fP and \fBCLIPBOARD\fP tokens. .PP Without using this feature, one can use workarounds such as the \fIxclip\fP program to show the contents of the X clipboard within an \fI\*n\fP window. .SS SECONDARY This is used less often than \fBPRIMARY\fP or \fBCLIPBOARD\fP. According to the ICCCM, it is used .bP As the second argument to commands taking two arguments (for example, \*(``exchange primary and secondary selections\*('') .bP As a means of obtaining data when there is a primary selection and the user does not want to disturb it . .SS "Selection Targets" The different types of data which are passed depend on what the receiving client asks for. These are termed \fIselection targets\fP. .PP When asking for the selection data, \fI\*n\fP tries the following types in this order: .RS 5 .TP 5 UTF8_STRING This is an XFree86 extension, which denotes that the data is encoded in UTF-8. When \fI\*n\fP is built with wide-character support, it both accepts and provides this type. .TP 5 TEXT the text is in the encoding which corresponds to your current locale. .TP 5 .\" see xc/doc/specs/CTEXT/ctext.tbl.ms .\" (it says the data is stored as a type of ISO 2022) COMPOUND_TEXT this is a format for multiple character set data, such as multi-lingual text. It can store UTF-8 data as a special case. .TP 5 STRING This is Latin 1 (ISO-8859-1) data. .RE .PP The middle two (TEXT and COMPOUND_TEXT) are added if \fI\*n\fP is configured with the \fBi18nSelections\fP resource set to \*(``true\*(''. .PP UTF8_STRING is preferred (therefore first in the list) since \fI\*n\fP stores text as Unicode data when running in wide-character mode, and no translation is needed. On the other hand, TEXT and COMPOUND_TEXT may require translation. If the translation is incomplete, they will insert X's \*(``defaultString\*('' whose value cannot be set, and may simply be empty. \fI\*N\fP's \fBdefaultString\fP resource specifies the string to use for incomplete translations of the UTF8_STRING. .PP You can alter the types which \fI\*n\fP tries using the \fBeightBitSelectTypes\fP or \fButf8SelectTypes\fP resources. For instance, you might have some specific locale setting which does not use UTF-8 encoding. The resource value is a comma-separated list of the selection targets, which consist of the names shown. You can use the special name I18N to denote the optional inclusion of TEXT and COMPOUND_TEXT. The names are matched ignoring case, and can be abbreviated. The default list can be expressed in several ways, e.g., .sp .RS .nf UTF8_STRING,I18N,STRING utf8,i18n,string u,i,s .fi .RE . .SS "Mouse Protocol" Applications can send escape sequences to \fI\*n\fP to cause it to send escape sequences back to the computer when you press a pointer button, or even (depending on which escape sequence) send escape sequences back to the computer as you move the pointer. .PP These escape sequences and the responses, called the \fImouse protocol\fP, are documented in \fIXTerm Control Sequences\fP. They do not appear in the \fIactions\fP invoked by the \fBtranslations\fP resource because the resource does not change while you run \fI\*n\fP, whereas applications can change the mouse prototol (i.e., enable, disable, use different modes). .PP However, the mouse protocol is interpreted within the \fIactions\fP that are usually associated with the pointer buttons. \fI\*N\fP ignores the mouse protocol in the \fBinsert\-selection\fP action if the shift-key is pressed at the same time. It also modifies a few other actions if the shift-key is pressed, e.g., suppressing the response with the pointer position, though not eliminating changes to the selected text. . .SH MENUS . \fI\*N\fP has four menus, named .IR mainMenu , .IR vtMenu , .IR fontMenu , and .IR tekMenu . Each menu pops up under the correct combinations of key and button presses. Each menu is divided into sections, separated by a horizontal line. Some menu entries correspond to modes that can be altered. A check mark appears next to a mode that is currently active. Selecting one of these modes toggles its state. Other menu entries are commands; selecting one of these performs the indicated function. .PP All of the menu entries correspond to X actions. In the list below, the menu label is shown followed by the action's name in parenthesis. . .\" ************************************************************************ .SS "Main Options" The \fI\*n\fP \fImainMenu\fP pops up when the \*(``control\*('' key and pointer button one are pressed in a window. This menu contains items that apply to both the VT\fIxxx\fP and Tektronix windows. There are several sections: .TP Commands for managing X events: .RS .TP .B Toolbar\fP (resource \fBtoolbar\fP) Clicking on the \*(``Toolbar\*('' menu entry hides the toolbar if it is visible, and shows it if it is not. .TP .B Secure Keyboard\fP (resource \fBsecurekbd\fP) The \fBSecure Keyboard\fP mode is helpful when typing in passwords or other sensitive data in an unsecure environment (see \fBSECURITY\fP below, but read the limitations carefully). .TP .B Allow SendEvents\fP (resource \fBallowsends\fP) Specifies whether or not synthetic key and button events generated using the X protocol SendEvent request should be interpreted or discarded. This corresponds to the \fBallowSendEvents\fP resource. .TP .B Redraw Window\fP (resource \fBredraw\fP) Forces the X display to repaint; useful in some environments. .RE .TP Commands for capturing output: .RS .TP .B Log to File\fP (resource \fBlogging\fP) Captures text sent to the screen in a log file, as in the \fB\-l\fP logging option. .TP .B Print-All Immediately\fP (resource \fBprint\-immediate\fP) Invokes the \fBprint\-immediate\fP action, sending the text of the current window directly to a file, as specified by the \fBprintFileImmediate\fP, \fBprintModeImmediate\fP and \fBprintOptsImmediate\fP resources. .TP .B Print-All on Error\fP (resource \fBprint\-on\-error\fP) Invokes the \fBprint\-on\-error\fP action, which toggles a flag telling \fI\*n\fP that if it exits with an X error, to send the text of the current window directly to a file, as specified by the \fBprintFileOnXError\fP, \fBprintModeOnXError\fP and \fBprintOptsOnXError\fP resources. .TP .B Print Window\fP (resource \fBprint\fP) Sends the text of the current window to the program given in the \fBprinterCommand\fP resource. .TP .B Redirect to Printer\fP (resource \fBprint\-redir\fP) This sets the \fBprinterControlMode\fR to 0 or 2. You can use this to turn the printer on as if an application had sent the appropriate control sequence. It is also useful for switching the printer off if an application turns it on without resetting the print control mode. .TP .B XHTML Screen Dump\fP (resource \fBdump\-html\fP) Available only when compiled with screen dump support. Invokes the \fBdump\-html\fP action. This creates an XHTML file matching the contents of the current screen, including the border, internal border, colors and most attributes: bold, italic, underline, faint, strikeout, reverse; blink is rendered as white-on-red; double underline is rendered the same as underline since there is no portable equivalent in CSS 2.2. .IP The font is whatever your browser uses for preformatted (
)
elements.
The XHTML file references a cascading style sheet (CSS)
named \*(``\fBxterm.css\fP\*('' that you can create to select a font or
override properties.
.RS
.LP
The following CSS selectors are used with
the expected default behavior in the XHTML file:
.sp
\fI.ul\fP for underline,
.br
\fI.bd\fP for bold,
.br
\fI.it\fP for italic,
.br
\fI.st\fP for strikeout,
.br
\fI.lu\fP for strikeout combined with underline.
.LP
In addition you may use
.sp
\fI.ev\fP to affect even numbered lines and
.br
\fI.od\fP to affect odd numbered lines.
.RE
.IP
Attributes faint, reverse and blink are implemented as \fIstyle\fP attributes
setting color properties.
All colors are specified as RGB percentages
in order to support displays with 10 bits per RGB.
.IP
The name of the file will be
.NS
\fBxterm.\fIyyyy\fB\.\fIMM\fB\.\fIdd\fB.\fIhh\fB.\fImm\fB.\fIss\fR\.xhtml
.NE
.IP
where
.IR yyyy ,
.IR MM ,
.IR dd ,
.IR hh ,
.I mm
and
.I ss
are the year, month, day, hour, minute and second
when the screen dump was performed
(the file is created in the directory
\fI\*n\fP is started in, or the home directory for a login \fI\*n\fP).
.IP
The \fBdump\-html\fP action can also be triggered using the Media Copy
control sequence CSI 1 0 i, for example from a shell script with
.NS
printf \*'\\033[10i\*'
.NE
.sp
Only the UTF-8 encoding is supported.
.TP
.B SVG Screen Dump\fP (resource \fBdump\-svg\fP)
Available only when compiled with screen dump support.
Invokes the \fBdump\-svg\fP action.
This creates a Scalable Vector Graphics (SVG) file matching
the contents of the current screen, including the border,
internal border, colors and most attributes: bold, italic,
underline, double underline, faint, strikeout, reverse;
blink is rendered as white-on-red.
The font is whatever your renderer uses for the \fImonospace\fP font-family.
All colors are specified as RGB percentages
in order to support displays with 10 bits per RGB.
.IP
The name of the file will be
.NS
\fBxterm.\fIyyyy\fB\.\fIMM\fB\.\fIdd\fB.\fIhh\fB.\fImm\fB.\fIss\fR\.svg
.NE
.IP
where
.IR yyyy ,
.IR MM ,
.IR dd ,
.IR hh ,
.I mm
and
.I ss
are the year, month, day, hour, minute and second
when the screen dump was performed
(the file is created in the directory
\fI\*n\fP is started in, or the home directory for a login \fI\*n\fP).
.IP
The \fBdump\-svg\fP action can also be triggered using the Media Copy
control sequence CSI 1 1 i, for example from a shell script with
.NS
printf \*'\\033[11i\*'
.NE
.sp
Only the UTF-8 encoding is supported.
.RE
.TP
Modes for setting keyboard style:
.RS
.TP
.B 8-Bit Controls\fP (resource \fB8\-bit\-control\fP)
Enabled for VT220 emulation, this controls whether \fI\*n\fP will send
8-bit control sequences rather than using 7-bit (ASCII) controls,
e.g., sending a byte in the range 128\(en159 rather than the escape character
followed by a second byte.
\fI\*N\fP always interprets both 8-bit and 7-bit control sequences
(see \fI\*N Control Sequences\fP).
This corresponds to the \fBeightBitControl\fP resource.
.TP
.B Backarrow Key (BS/DEL)\fP (resource \fBbackarrow\ key\fP)
Modifies the behavior of the backarrow key, making it transmit
either a backspace (8)
or delete (127) character.
This corresponds to the \fBbackarrowKey\fP resource.
.TP
.B Alt/NumLock Modifiers\fP (resource \fBnum\-lock\fP)
Controls the treatment of Alt- and NumLock-key modifiers.
This corresponds to the \fBnumLock\fP resource.
.TP
.B Meta Sends Escape\fP (resource \fBmeta\-esc\fP)
Controls whether \fIMeta\fP keys are converted into a two-character
sequence with the character itself preceded by ESC.
This corresponds to the \fBmetaSendsEscape\fP resource.
.TP
.B Delete is DEL\fP (resource \fBdelete\-is\-del\fP)
Controls whether the Delete key on the editing keypad should send DEL (127)
or the VT220-style Remove escape sequence.
This corresponds to the \fBdeleteIsDEL\fP resource.
.TP
.B Old Function-Keys\fP (resource \fBoldFunctionKeys\fP)
.TP
.B HP Function-Keys\fP (resource \fBhpFunctionKeys\fP)
.TP
.B SCO Function-Keys\fP (resource \fBscoFunctionKeys\fP)
.TP
.B Sun Function-Keys\fP (resource \fBsunFunctionKeys\fP)
.TP
.B VT220 Keyboard\fP (resource \fBsunKeyboard\fP)
These act as a radio-button, selecting one style for the keyboard layout.
The layout corresponds to more than one resource setting:
\fBsunKeyboard\fP,
\fBsunFunctionKeys\fP,
\fBscoFunctionKeys\fP and
\fBhpFunctionKeys\fP.
.RE
.TP
Commands for process signalling:
.RS
.TP
.B Send STOP Signal\fP (resource \fBsuspend\fP)
.TP
.B Send CONT Signal\fP (resource \fBcontinue\fP)
.TP
.B Send INT Signal\fP (resource \fBinterrupt\fP)
.TP
.B Send HUP Signal\fP (resource \fBhangup\fP)
.TP
.B Send TERM Signal\fP (resource \fBterminate\fP)
.TP
.B Send KILL Signal\fP (resource \fBkill\fP)
These send the SIGTSTP, SIGCONT, SIGINT, SIGHUP, SIGTERM and SIGKILL
signals respectively, to
the process group of the process running under \fI\*n\fP (usually the shell).
The \fBSIGCONT\fP
function is especially useful if the user has accidentally typed CTRL-Z,
suspending the process.
.TP
.B Quit\fP (resource \fBquit\fP)
Stop processing X events except to support the \fB\-hold\fP option,
and then send a SIGHUP signal to
the process group of the process running under \fI\*n\fP (usually the shell).
.RE
.
.\" ************************************************************************
.SS "VT Options"
The \fI\*n\fP \fIvtMenu\fP
sets various modes in the VT\fIxxx\fP emulation, and is popped up when the
\*(``control\*('' key and pointer button two
are pressed in the VT\fIxxx\fP window.
.TP
VT\fIxxx\fP Modes:
.RS
.
.TP
.B Enable Scrollbar\fP (resource \fBscrollbar\fP)
Enable (or disable) the scrollbar.
This corresponds to the \fB\-sb\fP option and the \fBscrollBar\fP resource.
.
.TP
.B Enable Jump Scroll\fP (resource \fBjumpscroll\fP)
Enable (or disable) jump scrolling.
This corresponds to the \fB\-j\fP option and the \fBjumpScroll\fP resource.
.
.TP
.B Enable Reverse Video\fP (resource \fBreversevideo\fP)
Enable (or disable) reverse-video.
This corresponds to the \fB\-rv\fP option and the \fBreverseVideo\fP resource.
.
.TP
.B Enable Auto Wraparound\fP (resource \fBautowrap\fP)
Enable (or disable) auto-wraparound.
This corresponds to the \fB\-aw\fP option and the \fBautoWrap\fP resource.
.
.TP
.B Enable Reverse Wraparound\fP (resource \fBreversewrap\fP)
Enable (or disable) reverse wraparound.
This corresponds to the \fB\-rw\fP option and the \fBreverseWrap\fP resource.
.
.TP
.B Enable Auto Linefeed\fP (resource \fBautolinefeed\fP)
Enable (or disable) auto-linefeed.
This is the VT102 NEL function,
which causes the emulator to emit a line feed after each carriage return.
There is no corresponding command-line option or resource setting.
.
.TP
.B Enable Application Cursor Keys\fP (resource \fBappcursor\fP)
Enable (or disable) application cursor keys.
This corresponds to the \fBappcursorDefault\fP resource.
There is no corresponding command-line option.
.
.TP
.B Enable Application Keypad\fP (resource \fBappkeypad\fP)
Enable (or disable) application keypad keys.
This corresponds to the \fBappkeypadDefault\fP resource.
There is no corresponding command-line option.
.
.TP
.B Scroll to Bottom on Key Press\fP (resource \fBscrollkey\fP)
Enable (or disable) scrolling to the bottom of the scrolling region
on a keypress.
This corresponds to the \fB\-sk\fP option and the \fBscrollKey\fP resource.
.IP
As a special case, the XON / XOFF keys (control/S and control/Q) are ignored.
.
.TP
.B Scroll to Bottom on Tty Output\fP (resource \fBscrollttyoutput\fP)
Enable (or disable) scrolling to the bottom of the scrolling region on
output to the terminal.
This corresponds to the \fB\-si\fP option and
the \fBscrollTtyOutput\fP resource.
.
.TP
.B Allow 80/132 Column Switching\fP (resource \fBallow132\fP)
Enable (or disable) switching between 80 and 132 columns.
This corresponds to the \fB\-132\fP option and the \fBc132\fP resource.
.
.TP
.B Keep Selection\fP (resource \fBkeepSelection\fP)
Tell \fI\*n\fP whether to disown the selection when it stops highlighting it,
e.g., when an application modifies the display so that it no longer matches
the text which has been highlighted.
As long as \fI\*n\fP continues to own the selection for a given atom,
it can provide the corresponding text to other clients which request
the selection using that atom.
.IP
This corresponds to the \fBkeepSelection\fP resource.
There is no corresponding command-line option.
.IP
Telling \fI\*n\fP to not disown the selection
does not prevent other applications from taking ownership of the selection.
When that happens, \fI\*n\fP receives notification that this has happened,
and removes its highlighting.
.IP
See \fBSELECT/PASTE\fP for more information.
.
.TP
.B Select to Clipboard\fP (resource \fBselectToClipboard\fP)
Tell \fI\*n\fP whether to use the \fBPRIMARY\fP or \fBCLIPBOARD\fP
for \fBSELECT\fP tokens in the \fBtranslations\fP resource which
maps keyboard and mouse actions to select/paste actions.
.IP
This corresponds to the \fBselectToClipboard\fP resource.
There is no corresponding command-line option.
.IP
The \fBkeepSelection\fP resource setting applies
to \fBCLIPBOARD\fP selections just as it does for \fBPRIMARY\fP selections.
However some window managers treat the clipboard specially.
For instance, XQuartz's synchronization between the OSX \fIpasteboard\fP
and the X11 \fIclipboard\fP causes applications
to lose the selection ownership
for that atom when a selection is copied to the clipboard.
.IP
See \fBSELECT/PASTE\fP for more information.
.
.TP
.B Enable Visual Bell\fP (resource \fBvisualbell\fP)
Enable (or disable) visible bell (i.e., flashing) instead of an audible bell.
This corresponds to the \fB\-vb\fP option and the \fBvisualBell\fP resource.
.
.TP
.B Enable Bell Urgency\fP (resource \fBbellIsUrgent\fP)
Enable (or disable) Urgency window manager hint when Control-G is received.
This corresponds to the \fBbellIsUrgent\fP resource.
.
.TP
.B Enable Pop on Bell\fP (resource \fBpoponbell\fP)
Enable (or disable) raising of the window when Control-G is received.
This corresponds to the \fB\-pop\fP option and the \fBpopOnBell\fP resource.
.
.TP
.B Enable Blinking Cursor\fP (resource \fBcursorblink\fP)
Enable (or disable) the blinking-cursor feature.
This corresponds to the \fB\-bc\fP option and the \fBcursorBlink\fP resource.
There are also escape sequences
(see \fI\*N Control Sequences\fP):
.RS
.bP
If the \fBcursorBlinkXOR\fP resource is set,
the menu entry and the escape sequence states will be XOR'd:
if both are enabled, the cursor will not blink,
if only one is enabled, the cursor will blink.
.bP
If the \fBcursorBlinkXOR\fP is not set;
if either the menu entry or the escape sequence states are set,
the cursor will blink.
.RE
.IP
In either case, the checkbox for the menu shows the state of the
\fBcursorBlink\fP resource,
which may not correspond to what the cursor is actually doing.
.
.TP
.B Enable Alternate Screen Switching\fP (resource \fBtiteInhibit\fP)
Enable (or disable) switching between the normal and alternate screens.
This corresponds to the \fBtiteInhibit\fP resource.
There is no corresponding command-line option.
.
.TP
.B Enable Active Icon\fP (resource \fBactiveicon\fP)
Enable (or disable) the active-icon feature.
This corresponds to the \fB\-ai\fP option and the \fBactiveIcon\fP resource.
.
.TP
.B Sixel Scrolling\fP (resource \fBsixelScrolling\fP)
This corresponds to the \fBsixelScrolling\fP resource.
It can also be turned off and on using the private mode DECSDM
(Sixel Display Mode).
.RS
.bP
When enabled,
\fI\*n\fR draws sixel graphics at the current text cursor location,
scrolling the image vertically if it is larger than the screen,
and leaving the text cursor
at the same column in the next complete line after the image when
returning to text mode
.IP
This is the default,
which corresponds to the \fIreset\fP state of DECSDM.
.bP
When disabled,
\fI\*n\fR draws sixel graphics starting at the upper left of the screen,
cropping to fit the screen,
and does not alter the text cursor location.
.IP
This corresponds to the \fIset\fP state of DECSDM.
.RE
.IP
There is no corresponding command-line option.
.
.TP
.B Private Color Registers\fP (resource \fBprivateColorRegisters\fP)
If \fI\*n\fR is configured to support ReGIS graphics,
this controls whether a private color palette can be used.
.IP
When enabled,
each graphic image uses a separate set of color registers, so that it
essentially has a private palette (this is the default).
If it is not set,
all graphics images share a common set of registers which is how sixel and
ReGIS graphics worked on actual hardware.
The default is likely a more
useful mode on modern TrueColor hardware.
.IP
This corresponds to the \fBprivateColorRegisters\fP resource.
There is no corresponding command-line option.
.RE
.
.TP
VT\fIxxx\fP Commands:
.RS
.TP
.B Do Soft Reset\fP (resource \fBsoftreset\fP)
This corresponds to the VT220 DECSTR control sequence.
A soft reset leaves the contents of the window intact,
but resets modes which affect subsequent updates:
.RS
.PP
Soft reset differs from full reset in a minor detail:
.bP
Set the saved cursor position to the upper-left corner of the window.
.bP
Exit from the status-line without erasing it.
.PP
Both soft/full resets do the following:
.bP
Make the cursor visible, with shape reset according to the
\fBcursorUnderLine\fR and
\fBcursorBar\fR resources.
.bP
Enable or disable the cursor-blinking state
according to the \fBcursorBlink\fR resource,
and set the \fIEnable Blinking Cursor\fP menu checkmark to match.
.bP
Reset video attributes, e.g., bold, italic, underline, blink.
.bP
Reset the ANSI color mode to the \fI\*n\fP default foreground and background.
.bP
Reset the 256-color palette to its initial state.
.bP
Reset the selected character set, e.g., ASCII, alternate character set.
The UTF-8 modes are not changed.
.bP
Reset ECMA-48 KAM.
.bP
Reset DECCKM and DECKPAM per resources
.BR appcursorDefault " and"
.BR appkeypadDefault .
.bP
Reset key-format and key-modifier modes to the values set by resources,
i.e.,
.sp
.RS 8
.BR formatCursorKeys ,
.BR formatFunctionKeys ,
.BR formatKeypadKeys ,
.BR formatModifierKeys ,
.BR formatOtherKeys ", and"
.BR formatSpecialKeys .
.RE
.IP
as well as
.sp
.RS 8
.BR modifyCursorKeys ,
.BR modifyFunctionKeys ,
.BR modifyKeyboard ,
.BR modifyKeypadKeys ,
.BR modifyModifierKeys ,
.BR modifyOtherKeys ", and"
.BR modifySpecialKeys .
.RE
.bP
Reset origin mode (DECOM).
.bP
Reset all margins (i.e., top/bottom and left/right).
This can be convenient when some program has left the scroll regions
set incorrectly.
.bP
Set autowrap and reverse wrapping according to the resource values
.BR autoWrap " and"
.BR reverseWrap .
.bP
Reset checksum extension to the \fBchecksumExtension\fP resource.
.RE
.
.TP
.B Do Full Reset\fP (resource \fBhardreset\fP)
A full reset does this in addition to a soft reset:
.RS
.bP
Clear the window.
.bP
Reset tab stops to every eight columns.
.bP
Reset the screen to match the \fBreverseVideo\fP resource.
.bP
Resize the screen to 80 columns if 132-column mode was initially enabled
with the \fBc132\fP resource.
.bP
Reset scrolling (jump versus smooth) per the \fBjumpScroll\fP resource.
.bP
Enable linefeed mode (ECMA-48 LNM) and send/receive mode (ECMA-48 SRM).
.bP
Reset DEC user-defined keys (DECUDK).
.bP
Disable application mode for cursor- and keypad-keys (DECCKM, DECKPAM).
.bP
Reset menu entry \fI8-bit Controls\fR, per resource \fBeightBitControl\fP.
.bP
Reset interpretation of the backarrow key, per initial resource settings.
.bP
Set the keyboard type according to the resources
.BR keyboardType ,
.BR hpFunctionKeys ,
.BR scoFunctionKeys ,
.BR sunFunctionKeys ,
.BR tcapFunctionKeys ,
.BR oldXtermFKeys " and"
.BR sunKeyboard .
.bP
Turn mouse tracking off.
.bP
Reset title and pointer modes
per resources \fBtitleModes\fP and \fBpointerMode\fP.
.bP
Reset the readline and bracketed paste modes.
.bP
Discard all SIXEL and ReGIS graphics data from memory.
.bP
Reset \fBsixelScrolling\fP and \fBprivateColorRegisters\fP from
initial resource values.
.bP
Set DECSDM if the \fBsixelScrolling\fP resource is true.
Otherwise, reset DECSDM.
.PP
A full reset does this, unlike a soft reset:
.bP
Move the cursor to the upper-left corner of the window,
and then save that position.
.bP
Hide the status-line, setting its display-type to \*(``none\*(''.
.RE
.
.TP
.B Reset and Clear Saved Lines\fP (resource \fBclearsavedlines\fP)
Perform a full reset,
and also clear the saved lines.
.IP
This corresponds to the VT102 RIS control sequence,
with a few obvious differences.
For example, your session is not disconnected as a real VT102 would do.
.RE
.
.TP
Commands for setting the current screen:
.RS
.
.TP
.B Show Tek Window\fP (resource \fBtekshow\fP)
When enabled,
pops the Tektronix 4014 window up (makes it visible).
When disabled,
hides the Tektronix 4014 window.
.
.TP
.B Switch to Tek Mode\fP (resource \fBtekmode\fP)
When enabled,
pops the Tektronix 4014 window up if it is not already visible,
and switches the input stream to that window.
When disabled,
hides the Tektronix 4014 window and
switches input back to the VT\fIxxx\fP window.
.
.TP
.B Hide VT Window\fP (resource \fBvthide\fP)
When enabled,
hides the VT\fIxxx\fP window,
shows the Tektronix 4014 window if
it was not already visible
and switches the input stream to that window.
When disabled,
shows the VT\fIxxx\fP window,
and switches the input stream to that window.
.
.TP
.B Show Alternate Screen\fP (resource \fBaltscreen\fP)
When enabled,
shows the alternate screen.
When disabled,
shows the normal screen.
Note that the normal screen may have saved lines;
the alternate screen does not.
.RE
.
.SS "VT Fonts"
The \fI\*n\fP \fIfontMenu\fP pops up when
the \*(``control\*('' key and pointer button three are pressed in a window.
It sets the font used in the VT\fIxxx\fP window,
or modifies the way the font is specified or displayed.
There are several sections.
.PP
The first section allows you to select the font from a set of alternatives:
.RS
.TP
.B Default\fP (resource \fBfontdefault\fP)
Set the font to the default, i.e., that given by the \fB*VT100.font\fP resource.
.TP
.B Unreadable\fP (resource \fBfont1\fP)
Set the font to that given by the \fB*VT100.font1\fP resource.
.TP
.B Tiny\fP (resource \fBfont2\fP)
Set the font to that given by the \fB*VT100.font2\fP resource.
.TP
.B Small\fP (resource \fBfont3\fP)
Set the font to that given by the \fB*VT100.font3\fP resource.
.TP
.B Medium\fP (resource \fBfont4\fP)
Set the font to that given by the \fB*VT100.font4\fP resource.
.TP
.B Large\fP (resource \fBfont5\fP)
Set the font to that given by the \fB*VT100.font5\fP resource.
.TP
.B Huge\fP (resource \fBfont6\fP)
Set the font to that given by the \fB*VT100.font6\fP resource.
.TP
.B Enormous\fP (resource \fBfont7\fP)
Set the font to that given by the \fB*VT100.font7\fP resource.
.TP
.B Escape Sequence\fP (resource \fBfontescape\fP)
This allows you to set the font last specified by the Set
Font escape sequence (see \fI\*N Control Sequences\fP).
.TP
.B Selection\fP (resource \fBfontsel\fP)
This allows you to set the font specified
the current selection as a font name (if the \fBPRIMARY\fP selection is owned).
.RE
.PP
The second section allows you to modify the way it is displayed:
.RS
.TP
.B Bold Fonts\fP (resource \fBallow\-bold\-fonts\fP)
This is normally checked (enabled).
When unchecked, \fI\*n\fP will not use bold fonts.
The setting corresponds to the \fBallowBoldFonts\fP resource.
.TP
.B Line-Drawing Characters\fP (resource \fBfont\-linedrawing\fP)
When set, tells \fI\*n\fP to draw its own line-drawing characters.
Otherwise it relies on the font containing these.
Compare to the \fBforceBoxChars\fP resource.
.TP
.B Packed Font\fP (resource \fBfont\-packed\fP)
When set, tells \fI\*n\fP to use the minimum glyph-width from a font
when displaying characters.
Use the maximum width (unchecked) to help display proportional fonts.
Compare to the \fBforcePackedFont\fP resource.
.TP
.B Doublesized Characters\fP (resource \fBfont\-doublesize\fP)
When set, \fI\*n\fP may ask the font server to produce scaled versions
of the normal font, for VT102 double-size characters.
.RE
.PP
The third section allows you to modify the way it is specified:
.RS
.TP
.B TrueType Fonts\fP (resource \fBrender\-font\fP)
If the \fBrenderFont\fP and corresponding resources were set,
this is a further control whether \fI\*n\fP will actually use the
Xft library calls to obtain a font.
.TP
.B UTF-8 Encoding\fP (resource \fButf8\-mode\fP)
This controls whether \fI\*n\fP uses UTF-8 encoding of input/output.
It is useful for temporarily switching \fI\*n\fP to display
text from an application which does not follow the locale settings.
It corresponds to the \fButf8\fP resource.
.TP
.B UTF-8 Fonts\fP (resource \fButf8\-fonts\fP)
This controls whether \fI\*n\fP uses UTF-8 fonts for display.
It is useful for temporarily switching \fI\*n\fP to display
text from an application which does not follow the locale settings.
It combines the \fButf8\fP and \fButf8Fonts\fP resources,
subject to the \fBlocale\fP resource.
.TP
.B UTF-8 Titles\fP (resource \fButf8\-title\fP)
This controls whether \fI\*n\fP accepts UTF-8 encoding for
title control sequences.
It corresponds to the \fButf8Fonts\fP resource.
.IP
Initially the checkmark is set according to both the \fButf8\fP
and \fButf8Fonts\fP resource values.
If the latter is set to \*(``always\*('', the checkmark is disabled.
Likewise, if there are no fonts given in the \fButf8Fonts\fP
subresources, then the checkmark also is disabled.
.IP
The standard \fB__default_class__\fP app-defaults file defines
both sets of fonts,
while the \fBU__default_class__\fP app-defaults file defines only one set.
Assuming the standard app-defaults files,
this command will launch \fI\*n\fP able to switch between UTF-8
and ISO-8859-1 encoded fonts:
.NS
u\*n \-class __default_class__
.NE
.RE
.PP
The fourth section allows you to enable or disable special operations
which can be controlled by writing escape sequences to the terminal.
These are disabled if the SendEvents feature is enabled:
.RS
.TP
.B Allow Color Ops\fP (resource \fBallow\-color\-ops\fP)
This corresponds to the \fBallowColorOps\fP resource.
Enable or disable control sequences that set/query the colors.
.TP
.B Allow Font Ops\fP (resource \fBallow\-font\-ops\fP)
This corresponds to the \fBallowFontOps\fP resource.
Enable or disable control sequences that set/query the font.
.TP
.B Allow Mouse Ops\fP (resource \fBallow\-mouse\-ops\fP)
Enable or disable control sequences that cause the terminal to
send escape sequences on pointer-clicks and movement.
This corresponds to the \fBallowMouseOps\fP resource.
.TP
.B Allow Tcap Ops\fP (resource \fBallow\-tcap\-ops\fP)
Enable or disable control sequences that query the terminal's
notion of its function-key strings, as termcap or terminfo capabilities.
This corresponds to the \fBallowTcapOps\fP resource.
.TP
.B Allow Title Ops\fP (resource \fBallow\-title\-ops\fP)
Enable or disable control sequences that modify the window title or icon name.
This corresponds to the \fBallowTitleOps\fP resource.
.TP
.B Allow Window Ops\fP (resource \fBallow\-window\-ops\fP)
Enable or disable extended window control sequences (as used in dtterm).
This corresponds to the \fBallowWindowOps\fP resource.
.RE
.
.SS "Tek Options"
The \fI\*n\fP \fItekMenu\fP sets various modes in the Tektronix emulation,
and is popped up when the
\*(``control\*('' key and pointer button two
are pressed in the Tektronix window.
The current font size is checked in the modes section of the menu.
.RS
.TP
.B Large Characters\fP (resource \fBtektextlarge\fP)
.TP
.B \ Size Characters\fP (resource \fBtektext2\fP)
.TP
.B \ Size Characters\fP (resource \fBtektext3\fP)
.TP
.B Small Characters\fP (resource \fBtektextsmall\fP)
.RE
.PP
Commands:
.RS
.TP
.B PAGE\fP (resource \fBtekpage\fP)
Simulates the Tektronix \*(``PAGE\*('' button by
.RS
.bP
clearing the window,
.bP
cancelling the graphics input-mode, and
.bP
moving the cursor to the \fIhome\fP position.
.RE
.TP
.B RESET\fP (resource \fBtekreset\fP)
Unlike the similarly-named Tektronix \*(``RESET\*('' button,
this does everything that \fBPAGE\fP does
as well as resetting the line-type and font-size to their default values.
.TP
.B COPY\fP (resource \fBtekcopy\fP)
Simulates the Tektronix \*(``COPY\*('' button
(which makes a hard-copy of the screen)
by writing the information to a text file.
.RE
.PP
Windows:
.RS
.TP
.B Show VT Window\fP (resource \fBvtshow\fP)
.TP
.B Switch to VT Mode\fP (resource \fBvtmode\fP)
.TP
.B Hide Tek Window\fP (resource \fBtekhide\fP)
.RE
.
.
.SH SECURITY
.
X environments differ in their security consciousness.
.bP
Most servers,
run under \fIxdm\fP,
are capable of using a \*(``magic cookie\*('' authorization
scheme that can provide a reasonable level of security for many people.
If your server is only using a host-based mechanism to control access to
the server (see \fBxhost(__mansuffix__)\fP),
then if you enable access for a host and
other users are also permitted to run clients on that same host,
it is possible that someone can run an application which uses the
basic services of the X protocol to snoop on your activities,
potentially capturing a transcript of everything you type at the keyboard.
.bP
Any process which has access to your X display can manipulate it
in ways that you might not anticipate,
even redirecting your keyboard to itself
and sending events to your application's windows.
This is true even with the \*(``magic cookie\*('' authorization scheme.
While the \fBallowSendEvents\fP provides some protection against
rogue applications tampering with your programs,
guarding against a snooper is harder.
.
.bP
The X input extension for instance allows an application to bypass
all of the other (limited) authorization and security features,
including the GrabKeyboard protocol.
.
.bP
The possibility of an application spying on your keystrokes
is of particular concern when you want to type in a password
or other sensitive data.
The best solution to this problem is to use a better
authorization mechanism than is provided by X.
.PP
Subject to all of these caveats,
a simple mechanism exists for protecting keyboard input in \fI\*n\fP.
.
.PP
The \fI\*n\fP menu (see \fBMENUS\fP above) contains a \fBSecure Keyboard\fP
entry which, when enabled,
attempts to ensure that all keyboard input is directed
\fIonly\fP to \fI\*n\fP (using the GrabKeyboard protocol request).
When an application prompts you for a password
(or other sensitive data), you can enable \fBSecure Keyboard\fP using the
menu, type in the data, and then disable \fBSecure Keyboard\fP using
the menu again.
.bP
This ensures that you know which window is accepting your keystrokes.
.bP
It cannot ensure that there are no processes which have access to your
X display that might be observing the keystrokes as well.
.
.PP
Only one X client at a time can grab the keyboard,
so when you attempt to enable \fBSecure Keyboard\fP it may fail.
In this case, the bell will sound.
If the \fBSecure Keyboard\fP succeeds,
the foreground and background colors will be exchanged (as if you
selected the \fBEnable Reverse Video\fP entry in the \fBModes\fP menu);
they will be exchanged again when you exit secure mode.
If the colors
do \fInot\fP switch, then
you should be \fIvery\fP suspicious that you are being spoofed.
If the application you are running displays a prompt before asking for
the password, it is safest to enter secure mode \fIbefore\fP the
prompt gets displayed, and to make sure that the prompt gets displayed
correctly (in the new colors), to minimize the probability of
spoofing.
You can also bring up the menu again and make sure that a check
mark appears next to the entry.
.
.PP
\fBSecure Keyboard\fP mode will be disabled automatically if your \fI\*n\fP
window becomes iconified (or otherwise unmapped), or if you start up
a reparenting window manager (that places a title bar or other decoration
around the window) while in \fBSecure Keyboard\fP mode.
(This is a
feature of the X protocol not easily overcome.)  When this happens,
the foreground and background colors will be switched back and the bell
will sound in warning.
.
.
.SH "CHARACTER CLASSES"
Clicking the left pointer button twice in rapid succession
(double-clicking) causes all characters of the same class
(e.g., letters, white space, punctuation) to be selected as a \*(``word\*(''.
Since different people have different preferences for what should
be selected (for example, should filenames be selected as a whole or only
the separate subnames), the default mapping can be overridden through the use
of the \fBcharClass\fP (class \fICharClass\fP) resource.
.
.PP
This resource is a
series of comma-separated
\fIrange\fP:\fIvalue\fP pairs.
.bP
The
\fIrange\fP is either a single number or \fIlow\fP-\fIhigh\fP in the range of 0
to 65535, corresponding to the code for the character or characters to be
set.
.bP
The \fIvalue\fP is arbitrary.
For example, the default table uses the
character number of the first character occurring in the set.
When not in
UTF-8 mode, only the first 256 entries of this table will be used.
.
.PP
The default table starts as follows \-
.NS
static int charClass[256] = {
/* NUL  SOH  STX  ETX  EOT  ENQ  ACK  BEL */
    32,   1,   1,   1,   1,   1,   1,   1,
/*  BS   HT   NL   VT   NP   CR   SO   SI */
     1,  32,   1,   1,   1,   1,   1,   1,
/* DLE  DC1  DC2  DC3  DC4  NAK  SYN  ETB */
     1,   1,   1,   1,   1,   1,   1,   1,
/* CAN   EM  SUB  ESC   FS   GS   RS   US */
     1,   1,   1,   1,   1,   1,   1,   1,
/*  SP    !    "    #    $    %    &    \*' */
.\"   " <- for emacs autocolor to work well :-)
    32,  33,  34,  35,  36,  37,  38,  39,
/*   (    )    *    +    ,    \-    .    / */
    40,  41,  42,  43,  44,  45,  46,  47,
/*   0    1    2    3    4    5    6    7 */
    48,  48,  48,  48,  48,  48,  48,  48,
/*   8    9    :    ;    <    =    >    ? */
    48,  48,  58,  59,  60,  61,  62,  63,
/*   @    A    B    C    D    E    F    G */
    64,  48,  48,  48,  48,  48,  48,  48,
/*   H    I    J    K    L    M    N    O */
    48,  48,  48,  48,  48,  48,  48,  48,
/*   P    Q    R    S    T    U    V    W */
    48,  48,  48,  48,  48,  48,  48,  48,
/*   X    Y    Z    [    \\    ]    ^    _ */
    48,  48,  48,  91,  92,  93,  94,  48,
/*   `    a    b    c    d    e    f    g */
    96,  48,  48,  48,  48,  48,  48,  48,
/*   h    i    j    k    l    m    n    o */
    48,  48,  48,  48,  48,  48,  48,  48,
/*   p    q    r    s    t    u    v    w */
    48,  48,  48,  48,  48,  48,  48,  48,
/*   x    y    z    {    |    }    ~  DEL */
    48,  48,  48, 123, 124, 125, 126,   1,
/* x80  x81  x82  x83  IND  NEL  SSA  ESA */
     1,   1,   1,   1,   1,   1,   1,   1,
/* HTS  HTJ  VTS  PLD  PLU   RI  SS2  SS3 */
     1,   1,   1,   1,   1,   1,   1,   1,
/* DCS  PU1  PU2  STS  CCH   MW  SPA  EPA */
     1,   1,   1,   1,   1,   1,   1,   1,
/* x98  x99  x9A  CSI   ST  OSC   PM  APC */
     1,   1,   1,   1,   1,   1,   1,   1,
/*   \-    i   c/    L   ox   Y\-    |   So */
   160, 161, 162, 163, 164, 165, 166, 167,
/*  ..   c0   ip   <<    _        R0    \- */
   168, 169, 170, 171, 172, 173, 174, 175,
/*   o   +\-    2    3    \*'    u   q|    . */
   176, 177, 178, 179, 180, 181, 182, 183,
/*   ,    1    2   >>  1/4  1/2  3/4    ? */
   184, 185, 186, 187, 188, 189, 190, 191,
/*  A`   A\*'   A^   A~   A:   Ao   AE   C, */
    48,  48,  48,  48,  48,  48,  48,  48,
/*  E`   E\*'   E^   E:   I`   I\*'   I^   I: */
    48,  48,  48,  48,  48,  48,  48,  48,
/*  D\-   N~   O`   O\*'   O^   O~   O:    X */
    48,  48,  48,  48,  48,  48,  48, 215,
/*  O/   U`   U\*'   U^   U:   Y\*'    P    B */
    48,  48,  48,  48,  48,  48,  48,  48,
/*  a`   a\*'   a^   a~   a:   ao   ae   c, */
    48,  48,  48,  48,  48,  48,  48,  48,
/*  e`   e\*'   e^   e:   i`   i\*'   i^   i: */
    48,  48,  48,  48,  48,  48,  48,  48,
/*   d   n~   o`   o\*'   o^   o~   o:   \-: */
    48,  48,  48,  48,  48,  48,  48, 247,
/*  o/   u`   u\*'   u^   u:   y\*'    P   y: */
    48,  48,  48,  48,  48,  48,  48,  48};
.NE
.IP
For example, the string \*(``33:48,37:48,45\-47:48,38:48\*('' indicates that the
exclamation mark, percent sign, dash, period, slash, and ampersand characters
should be treated the same way as characters and numbers.
This is useful
for cutting and pasting electronic mailing addresses and filenames.
.
.
.SH KEY BINDINGS
.
It is possible to rebind keys (or sequences of keys) to arbitrary strings
for input, by changing the \fBtranslations\fP resources
for the vt100 or tek4014 widgets.
Changing the \fBtranslations\fP resource
for events other than key and button events is not expected,
and will cause unpredictable behavior.
.SS Actions
The following
actions are provided for use within the \fIvt100\fP or \fItek4014\fP
\fBtranslations\fP resources:
.TP 8
.B "allow\-bold\-fonts(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBallowBoldFonts\fP resource
and is also invoked by the \fBallow\-bold\-fonts\fP entry in \fIfontMenu\fP.
.TP 8
.B "allow\-color\-ops(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBallowColorOps\fP resource and is also
invoked by the \fBallow\-color\-ops\fP entry in \fIfontMenu\fP.
.TP 8
.B "allow\-font\-ops(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBallowFontOps\fP resource and is also
invoked by the \fBallow\-font\-ops\fP entry in \fIfontMenu\fP.
.TP 8
.B "allow\-mouse\-ops(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBallowMouseOps\fP resource
and is also invoked by the \fBallow\-mouse\-ops\fP entry in \fIfontMenu\fP.
.TP 8
.B "allow\-send\-events(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBallowSendEvents\fP resource
and is also invoked by the \fBallowsends\fP entry in \fImainMenu\fP.
.TP 8
.B "allow\-tcap\-ops(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBallowTcapOps\fP resource
and is also invoked by the \fBallow\-tcap\-ops\fP entry in \fIfontMenu\fP.
.TP 8
.B "allow\-title\-ops(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBallowTitleOps\fP resource
and is also invoked by the \fBallow\-title\-ops\fP entry in \fIfontMenu\fP.
.TP 8
.B "allow\-window\-ops(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBallowWindowOps\fP resource
and is also invoked by the \fBallow\-window\-ops\fP entry in \fIfontMenu\fP.
.TP 8
.B "alt\-sends\-escape()"
This action toggles the state of the \fBaltSendsEscape\fP resource.
.TP 8
.B "bell([\fIpercent\fP])"
This action rings the keyboard bell at the specified percentage
above or below the base volume.
.TP 8
.B "clear\-saved\-lines()"
This action does \fBhard\-reset()\fP and also clears the history
of lines saved off the top of the screen.
It is also invoked from the \fBclearsavedlines\fP entry in \fIvtMenu\fP.
The effect is identical to a hardware reset (RIS) control sequence.
.TP 8
.B "copy\-selection(\fIdestname\fP [, \&...\&])"
This action puts the currently selected text into all of the selections or
cutbuffers specified by \fIdestname\fP.
Unlike \fBselect\-end\fP, it does not send a mouse position or otherwise
modify the internal selection state.
.TP 8
.B "create\-menu(\fIm/v/f/t\fP)"
This action creates one of the menus used by \fI\*n\fP,
if it has not been previously created.
The parameter values are the menu names:
\fImainMenu\fP, \fIvtMenu\fP, \fIfontMenu\fP, \fItekMenu\fP, respectively.
.TP 8
.B "dabbrev\-expand()"
Expands the word before cursor by searching in the preceding text on the
screen and in the scrollback buffer for words starting with that
abbreviation.
Repeating \fBdabbrev\-expand()\fP several times in sequence searches for an
alternative expansion by looking farther back.
Lack of more matches is signaled by a bell.
Attempts to expand an empty word
(i.e., when cursor is preceded by a space) yield successively all previous
words.
Consecutive identical expansions are ignored.
The word here is defined as a sequence of non-whitespace characters.
This feature partially emulates the behavior
of \*(``dynamic abbreviation\*('' expansion in Emacs (bound there to M\-/).
Here is a resource setting for \fI\*n\fP which will do the same thing:
.NS
*VT100*translations:    #override \\n\\\&
        Meta  /:\fBdabbrev\-expand\fP()
.NE
.TP 8
.B "deiconify()"
Changes the window state back to normal, if it was iconified.
.TP 8
.B "delete\-is\-del()"
This action toggles the state of the \fBdeleteIsDEL\fP resource.
.TP 8
.B "dired\-button()"
Handles a button event (other than press and release)
by echoing the event's position
(i.e., character line and column) in the following format:
.NS
^X ESC G  
.NE
.TP 8
.B "dump\-html()"
Invokes the \fBXHTML Screen Dump\fP feature.
.TP 8
.B "dump\-svg()"
Invokes the \fBSVG Screen Dump\fP feature.
.TP 8
.B "exec\-formatted(\fIformat\fP, \fIsourcename\fP [, \&...\&])"
Execute an external command,
using the current selection for part of the command's parameters.
The first parameter, \fIformat\fP gives the basic command.
Succeeding parameters specify the selection source
as in \fBinsert\-selection\fP.
.IP
The \fIformat\fP parameter allows these substitutions:
.RS
.TP 5
%%
inserts a "%".
.TP 5
%P
the screen-position at the beginning of the highlighted region,
as a semicolon-separated pair of integers using the
values that the CUP control sequence would use.
.TP 5
%p
the screen-position after the beginning of the highlighted region,
using the same convention as \*(``%P\*(''.
.TP 5
%S
the length of the string that \*(``%s\*('' would insert.
.TP 5
%s
the content of the selection, unmodified.
.TP 5
%T
the length of the string that \*(``%t\*('' would insert.
.TP 5
%t
the selection, trimmed of leading/trailing whitespace.
Embedded spaces (and newlines) are copied as is.
.TP 5
%R
the length of the string that \*(``%r\*('' would insert.
.TP 5
%r
the selection, trimmed of trailing whitespace.
.TP 5
%V
the video attributes at the beginning of the highlighted region,
as a semicolon-separated list of integers using the
values that the SGR control sequence would use.
.TP 5
%v
the video attributes after the end of the highlighted region,
using the same convention as \*(``%V\*(''.
.RE
.IP
After constructing the command-string,
\fI\*n\fP forks a subprocess and executes the command,
which completes independently of \fI\*n\fP.
.IP
For example, this translation would invoke a new \fI\*n\fP process
to view a file whose name is selected while holding the shift key down.
The new process is started when the mouse button is released:
.NS
*VT100*translations: #override Shift \\\&
    :\fBexec\-formatted\fP("xterm \-e view \*'%t\*'", \fBSELECT\fP)
.NE
.TP 8
.B "exec\-selectable(\fIformat\fP, \fIonClicks\fP)"
Execute an external command,
using data copied from the screen for part of the command's parameters.
The first parameter, \fIformat\fP gives
the basic command as in \fBexec\-formatted\fP.
The second parameter specifies the method for copying
the data as in the \fBon2Clicks\fP resource.
.TP 8
.B "fullscreen(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBfullscreen\fP resource.
.TP 8
.B "hard\-reset()"
This action resets the scrolling region, tabs, window size, and cursor keys
and clears the screen.
It is also invoked from the \fBhardreset\fP
entry in \fIvtMenu\fP.
.TP 8
.B "iconify()"
Iconifies the window.
.TP 8
.B "ignore()"
This action ignores the event but checks for special pointer position
escape sequences.
.TP 8
.B "insert()"
This action inserts the character or string associated with
the key that was pressed.
.TP 8
.B "insert\-eight\-bit()"
This action inserts an eight-bit (Meta) version of the character or string
associated with the key that was pressed.
Only single-byte values are treated specially.
The exact action depends on the value of
the \fBaltSendsEscape\fP and
the \fBmetaSendsEscape\fP and
the \fBeightBitInput\fP resources.
The \fBmetaSendsEscape\fP resource is tested first.
See the \fBeightBitInput\fP resource for a full discussion.
.IP
The term \*(``eight-bit\*('' is misleading:
\fI\*n\fP checks if the key is in the range 128 to 255
(the eighth bit is set).
If the value is in that range,
depending on the resource values,
\fI\*n\fP may then do one of the following:
.RS
.bP
add 128 to the value, setting its eighth bit,
.bP
send an ESC byte before the key, or
.bP
send the key unaltered.
.RE
.TP 8
.B "insert\-formatted(\fIformat\fP, \fIsourcename\fP [, \&...\&])"
Insert the current selection or data related to it, formatted.
The first parameter, \fIformat\fP gives the template for the data
as in \fBexec\-formatted\fP.
Succeeding parameters specify the selection source
as in \fBinsert\-selection\fP.
.TP 8
.B "insert\-selectable(\fIformat\fP, \fIonClicks\fP)"
Insert data copied from the screen, formatted.
The first parameter, \fIformat\fP gives the template for the data
as in \fBexec\-formatted\fP.
The second parameter specifies the method for copying
the data as in the \fBon2Clicks\fP resource.
.TP 8
.B "insert\-selection(\fIsourcename\fP [, \&...\&])"
This action inserts the string found in the selection or cutbuffer indicated
by \fIsourcename\fP.
Sources are checked in the order given (case is
significant) until one is found.
Commonly-used selections include:
\fBPRIMARY\fP, \fBSECONDARY\fP, and \fBCLIPBOARD\fP.
Cut buffers are
typically named \fBCUT_BUFFER0\fP through \fBCUT_BUFFER7\fP.
.TP 8
.B "insert\-seven\-bit()"
This action is a synonym for \fBinsert()\fP.
The term \*(``seven-bit\*('' is misleading:
it only implies that \fI\*n\fP does not try to add 128 to the key's value
as in \fBinsert\-eight\-bit()\fP.
.TP 8
.B "interpret(\fIcontrol-sequence\fP)"
Interpret the given control sequence locally, i.e., without passing it to
the host.
This works by inserting the control sequence at the front
of the input buffer.
Use \*(``\\\*('' to escape octal digits in the string.
Xt does not allow you to put a null character
(i.e., \*(``\\000\*('') in the string.
.TP 8
.B "keymap(\fIname\fP)"
This action dynamically defines a new translation table whose resource
name is \fIname\fP with the suffix \*(``\fIKeymap\fP\*(''
(i.e., \fIname\fBKeymap\fR, where case is significant).
The name \fINone\fP restores the original translation table.
.TP 8
.B "larger\-vt\-font()"
Set the font to the next larger one, based on the font dimensions.
See also \fBset\-vt\-font()\fP.
.TP 8
.B "load\-vt\-fonts(\fIname\fP[,\fIclass\fP])"
Load fontnames from the given subresource name and class.
That is, load the \*(``*VT100.\fIname\fP.font\*('',
resource as \*(``*VT100.font\*('' etc.
If no name is given, the original set of fontnames is restored.
.IP
Unlike \fBset\-vt\-font()\fR, this does not affect the escape- and select-fonts,
since those are not based on resource values.
It does affect the fonts loosely organized under the \*(``Default\*('' menu
entry, including \fBfont\fP, \fBboldFont\fP, \fBwideFont\fP
and \fBwideBoldFont\fP.
.TP 8
.B "maximize()"
Resizes the window to fill the screen.
.TP 8
.B "meta\-sends\-escape()"
This action toggles the state of the \fBmetaSendsEscape\fP resource.
.TP 8
.B "pointer\-button()"
Use this action as a fall-back to handle button press- and release-events
for the mouse control sequence protocol
when the selection-related translations are suppressed with the
\fBomitTranslation\fP resource.
.TP 8
.B "pointer\-motion()"
Use this action as a fall-back to handle motion-events
for the mouse control sequence protocol
when the selection-related translations are suppressed with the
\fBomitTranslation\fP resource.
.TP 8
.B "popup\-menu(\fImenuname\fP)"
This action displays the specified popup menu.
Valid names (case is
significant) include:  \fImainMenu\fP, \fIvtMenu\fP, \fIfontMenu\fP,
and \fItekMenu\fP.
.TP 8
.B "print(\fIprinter\-flags\fP)"
This action prints the window.
It is also invoked by the \fBprint\fP entry in \fImainMenu\fP.
.IP
The action accepts optional parameters, which temporarily override
resource settings.
The parameter values are matched ignoring case:
.RS
.TP 5
noFormFeed
no form feed will be sent at the end of the last line printed
(i.e., \fBprinterFormFeed\fP is \*(``false\*('').
.TP 5
FormFeed
a form feed will be sent at the end of the last line printed
(i.e., \fBprinterFormFeed\fP is \*(``true\*('').
.TP 5
noNewLine
no newline will be sent at the end of the last line printed,
and wrapped lines will be combined into long lines
(i.e., \fBprinterNewLine\fP is \*(``false\*('').
.TP 5
NewLine
a newline will be sent at the end of the last line printed,
and each line will be limited (by adding a newline) to the screen width
(i.e., \fBprinterNewLine\fP is \*(``true\*('').
.TP 5
noAttrs
the page is printed without attributes
(i.e., \fBprintAttributes\fP is \*(``0\*('').
.TP 5
monoAttrs
the page is printed with monochrome (vt220) attributes
(i.e., \fBprintAttributes\fP is \*(``1\*('').
.TP 5
colorAttrs
the page is printed with ANSI color attributes
(i.e., \fBprintAttributes\fP is \*(``2\*('').
.RE
.TP 8
.B "print\-everything(\fIprinter\-flags\fP)"
This action sends the entire text history, in addition to the text
currently visible, to the program given in the \fBprinterCommand\fP resource.
It allows the same optional parameters as the \fBprint\fP action.
With a suitable printer command, the action can be used to load the text
history in an editor.
.TP 8
.B "print\-immediate()"
Sends the text of the current window directly to a file,
as specified by the
\fBprintFileImmediate\fP,
\fBprintModeImmediate\fP and
\fBprintOptsImmediate\fP
resources.
.TP 8
.B "print\-on\-error()"
Toggles a flag telling \fI\*n\fP that if it exits with an X error,
to send the text of the current window directly to a file,
as specified by the
\fBprintFileOnXError\fP,
\fBprintModeOnXError\fP and
\fBprintOptsOnXError\fP
resources.
.TP 8
.B "print\-redir()"
This action toggles the \fBprinterControlMode\fR between 0 and 2.
The corresponding popup menu entry is useful for switching the printer
off if you happen to change your mind after deciding to print random
binary files on the terminal.
.TP 8
.B "quit()"
.br
This action sends a SIGHUP to the subprogram and exits.
It is also invoked
by the \fBquit\fP entry in \fImainMenu\fP.
.TP 8
.B "readline\-button()"
Supports the optional readline feature by echoing repeated cursor forward
or backward control sequences on button release event,
to request that the host application update its notion of the cursor's
position to match the button event.
.TP 8
.B "redraw()"
This action redraws the window.
It is also invoked by the \fBredraw\fP entry in \fImainMenu\fP.
.TP 8
.B "restore()"
Restores the window to the size before it was last maximized.
.TP 8
.B "scroll\-back(\fIcount\fP [,\fIunits\fP [,\fImouse\fP] ])"
This action scrolls the text window backward so that text that had previously
scrolled off the top of the screen is now visible.
.IP
The \fIcount\fP argument
indicates the number of \fIunits\fP (which may be \fIpage\fP, \fIhalfpage\fP,
\fIpixel\fP, or \fIline\fP) by which to scroll.
If no \fIcount\fP parameter is given, \fI\*n\fP uses the number of lines
given by the \fBscrollLines\fP resource.
.IP
An adjustment can be specified for the \fIpage\fP or \fIhalfpage\fP units
by appending a \*(``+\*('' or \*(``\-\*(''
sign followed by a number,
e.g., \fIpage\-2\fP to specify 2 lines less than a page.
.IP
If the second parameter is omitted \*(``lines\*('' is used.
.IP
If the third parameter \fImouse\fP is given, the action is ignored when
mouse reporting is enabled.
.TP 8
.B "scroll\-forw(\fIcount\fP [,\fIunits\fP [,\fImouse\fP] ])"
This action is similar to \fBscroll\-back\fP except that it scrolls
in the other direction.
.TP 8
.B "scroll\-lock(\fIon/off/toggle\fP)"
This action sets, unsets or toggles internal state which tells
\fI\*n\fP whether Scroll Lock is active,
subject to the \fBallowScrollLock\fP resource.
.TP 8
.B "scroll\-to(\fIcount\fP)"
Scroll to the given line relative to the beginning of the saved-lines.
For instance, \*(``\fBscroll\-to(0)\fP\*('' would scroll to the beginning.
Two special nonnumeric parameters are recognized:
.RS
.TP 8
.B scroll\-to(begin)
Scroll to the beginning of the saved lines.
.TP 8
.B scroll\-to(end)
Scroll to the end of the saved lines, i.e., to the currently active page.
.RE
.TP 8
.B "secure()"
This action toggles the \fISecure Keyboard\fP mode
(see \fBSECURITY\fP), and is invoked from the \fBsecurekbd\fP
entry in \fImainMenu\fP.
.TP 8
.B "select\-cursor\-end(\fIdestname\fP [, \&...\&])"
This action is similar to \fBselect\-end\fP except that it should be used
with \fBselect\-cursor\-start\fP.
.TP 8
.B "select\-cursor\-extend()"
This action is similar to \fBselect\-extend\fP except that it should be used
with \fBselect\-cursor\-start\fP.
.TP 8
.B "select\-cursor\-start()"
This action is similar to \fBselect\-start\fP except that it begins the
selection at the current text cursor position.
.TP 8
.B "select\-end(\fIdestname\fP [, \&...\&])"
This action puts the currently selected text into all of the selections or
cutbuffers specified by \fIdestname\fP.
It also sends a mouse position and updates the internal selection state
to reflect the end of the selection process.
.TP 8
.B "select\-extend()"
This action tracks the pointer and extends the selection.
It should only be bound to Motion events.
.TP 8
.B "select\-set()"
This action stores text that corresponds to the current selection,
without affecting the selection mode.
.TP 8
.B "select\-start()"
This action begins text selection at the current pointer location.
See
the section on \fBPOINTER USAGE\fP for information on making selections.
.IP
If \fI\*n\fR is configured to support block-selection,
this action accepts a parameter \*(``block\*(''
which initiates a block-selection
rather than the default character-oriented selection.
.TP 8
.B "send\-signal(\fIsigname\fP)"
This action sends the signal named by \fIsigname\fP
to the \fI\*n\fP subprocess (the shell or program specified with
the \fI\-e\fP command line option).
It is also invoked by the
\fBsuspend\fP,
\fBcontinue\fP,
\fBinterrupt\fP,
\fBhangup\fP,
\fBterminate\fP,
and
\fBkill\fP
entries in \fImainMenu\fP.
Allowable signal names are (case is
not significant):
\fItstp\fP (if supported by the operating system), \fIsuspend\fP (same
as \fItstp\fP), \fIcont\fP
(if supported by the operating system), \fIint\fP, \fIhup\fP, \fIterm\fP,
\fIquit\fP,
\fIalrm\fP, \fIalarm\fP (same as \fIalrm\fP) and \fIkill\fP.
.TP 8
.B "set\-8\-bit\-control(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBeightBitControl\fP resource.
It is also invoked from the \fB8\-bit\-control\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-allow132(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBc132\fP resource.
It is also invoked from the \fBallow132\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-altscreen(\fIon/off/toggle\fP)"
This action sets, unsets or toggles between the alternate and current screens.
.TP 8
.B "set\-appcursor(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the handling Application Cursor Key mode
and is also invoked by the \fBappcursor\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-appkeypad(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the handling of Application Keypad mode
and is also invoked by the \fBappkeypad\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-autolinefeed(\fIon/off/toggle\fP)"
This action sets, unsets or toggles automatic insertion of line feeds.
It is also invoked by the \fBautolinefeed\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-autowrap(\fIon/off/toggle\fP)"
This action sets, unsets or toggles automatic wrapping of long lines.
It is also invoked by the \fBautowrap\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-backarrow(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBbackarrowKey\fP resource.
It is also invoked from the \fBbackarrow key\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-bellIsUrgent(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBbellIsUrgent\fP resource.
It is also invoked by the \fBbellIsUrgent\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-cursesemul(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBcurses\fP resource.
It is also invoked from the \fBcursesemul\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-cursorblink(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBcursorBlink\fP resource.
It is also invoked from the \fBcursorblink\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-font\-doublesize(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBfontDoublesize\fP resource.
It is also invoked by the \fBfont\-doublesize\fP entry in \fIfontMenu\fP.
.TP 8
.B "set\-font\-linedrawing(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fI\*n\fR's state regarding whether
the current font has line-drawing characters and whether it should draw them
directly.
It is also invoked by the \fBfont\-linedrawing\fP entry in \fIfontMenu\fP.
.\" .\" not implemented
.\" .TP 8
.\" .B "set\-font\-loading(\fIon/off/toggle\fP)"
.\" This action sets, unsets or toggles the TBD resource
.\" which controls the ability to load VT220 soft fonts.
.\" It is also invoked by the \fBfont\-loadable\fP entry in \fIfontMenu\fP.
.TP 8
.B "set\-font\-packed(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBforcePackedFont\fR resource
which controls use of the font's minimum or maximum glyph width.
It is also invoked by the \fBfont\-packed\fP entry in \fIfontMenu\fP.
.TP 8
.B "set\-hp\-function\-keys(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBhpFunctionKeys\fP resource.
It is also invoked by the \fBhpFunctionKeys\fP entry in \fImainMenu\fP.
.TP 8
.B "set\-jumpscroll(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBjumpscroll\fP resource.
It is also invoked by the \fBjumpscroll\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-keep\-clipboard(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBkeepClipboard\fP resource.
.TP 8
.B "set\-keep\-selection(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBkeepSelection\fP resource.
It is also invoked by the \fBkeepSelection\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-logging(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the state of the logging option.
.TP 8
.B "set\-marginbell(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBmarginBell\fP resource.
.TP 8
.B "set\-num\-lock(\fIon/off/toggle\fP)"
This action toggles the state of the \fBnumLock\fP resource.
.TP 8
.B "set\-old\-function\-keys(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the state of legacy function keys.
It is also invoked by the \fBoldFunctionKeys\fP entry in \fImainMenu\fP.
.TP 8
.B "set\-pop\-on\-bell(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBpopOnBell\fP resource.
It is also invoked by the \fBpoponbell\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-private\-colors(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBprivateColorRegisters\fP resource.
.TP 8
.B "set\-render\-font(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBrenderFont\fP resource.
It is also invoked by the \fBrender\-font\fP entry in \fIfontMenu\fP.
.TP 8
.B "set\-reverse\-video(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBreverseVideo\fP resource.
It is also invoked by the \fBreversevideo\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-reversewrap(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBreverseWrap\fP resource.
It is also invoked by the \fBreversewrap\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-sco\-function\-keys(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBscoFunctionKeys\fP resource.
It is also invoked by the \fBscoFunctionKeys\fP entry in \fImainMenu\fP.
.TP 8
.B "set\-scroll\-on\-key(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBscrollKey\fP resource.
It is also invoked from the \fBscrollkey\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-scroll\-on\-tty\-output(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBscrollTtyOutput\fP resource.
It is also invoked from the \fBscrollttyoutput\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-scrollbar(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBscrollbar\fP resource.
It is also invoked by the \fBscrollbar\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-select(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBselectToClipboard\fP resource.
It is also invoked by the \fBselectToClipboard\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-sixel\-scrolling(\fIon/off/toggle\fP)"
This action toggles between inline (sixel scrolling) and absolute positioning.
It can also be controlled via DEC private mode 80 (DECSDM) or from
the \fBsixelScrolling\fP entry in the \fIbtMenu\fP.
.TP 8
.B "set\-sun\-function\-keys(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBsunFunctionKeys\fP resource.
It is also invoked by the \fBsunFunctionKeys\fP entry in \fImainMenu\fP.
.TP 8
.B "set\-sun\-keyboard(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBsunKeyboard\fP resource.
It is also invoked by the \fBsunKeyboard\fP entry in \fImainMenu\fP.
.TP 8
.B "set\-tek\-text(\fIlarge/2/3/small\fP)"
This action sets the font used in the Tektronix window to the value of the
selected resource according to the argument.
The argument can be either a keyword or single-letter alias,
as shown in parentheses:
.RS
.TP 5
large (l)
Use resource \fBfontLarge\fP, same as menu entry \fBtektextlarge\fP.
.TP 5
two (2)
Use resource \fBfont2\fP, same as menu entry \fBtektext2\fP.
.TP 5
three (3)
Use resource \fBfont3\fP, same as menu entry \fBtektext3\fP.
.TP 5
small (s)
Use resource \fBfontSmall\fP, same as menu entry \fBtektextsmall\fP.
.RE
.TP 8
.B "set\-terminal\-type(\fItype\fP)"
This action directs output to either the \fIvt\fP or \fItek\fP windows,
according to the \fItype\fP string.
It is also invoked by the
\fBtekmode\fP entry in \fIvtMenu\fP and the \fBvtmode\fP entry in
\fItekMenu\fP.
.TP 8
.B "set\-titeInhibit(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBtiteInhibit\fP resource,
which controls switching between the alternate and current screens.
.TP 8
.B "set\-toolbar(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the toolbar feature.
It is also invoked by the \fBtoolbar\fP entry in \fImainMenu\fP.
.TP 8
.B "set\-utf8\-fonts(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fButf8Fonts\fP resource.
It is also invoked by the \fButf8\-fonts\fP entry in \fIfontMenu\fP.
.TP 8
.B "set\-utf8\-mode(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fButf8\fP resource.
It is also invoked by the \fButf8\-mode\fP entry in \fIfontMenu\fP.
.TP 8
.B "set\-utf8\-title(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fButf8Title\fP resource.
It is also invoked by the \fButf8\-title\fP entry in \fIfontMenu\fP.
.TP 8
.B "set\-visibility(\fIvt/tek\fP,\fIon/off/toggle\fP)"
This action sets, unsets or toggles whether or not
the \fIvt\fP or \fItek\fP windows are visible.
It is also invoked from the \fBtekshow\fP and \fBvthide\fP entries
in \fIvtMenu\fP and the \fBvtshow\fP and \fBtekhide\fP entries in
\fItekMenu\fP.
.TP 8
.B "set\-visual\-bell(\fIon/off/toggle\fP)"
This action sets, unsets or toggles the \fBvisualBell\fP resource.
It is also invoked by the \fBvisualbell\fP entry in \fIvtMenu\fP.
.TP 8
.B "set\-vt\-font(\fId/1/2/3/4/5/6/7/e/s\fP [,\fInormalfont\fP [, \fIboldfont\fP]])"
This action sets the font or fonts currently being used
in the VT\fIxxx\fP window.
The first argument is a single character that specifies the font to be used:
.RS 8
.HP
\fId\fP or \fID\fP indicate the default font (the font initially
used when
\fI\*n\fP was started),
.HP
\fI1\fP through \fI7\fP indicate the fonts
specified by the \fBfont1\fP through \fBfont7\fP resources,
.HP
\fIe\fP or \fIE\fP
indicate the normal and bold fonts that have been set through escape codes
(or specified as the second and third action arguments, respectively), and
.HP
\fIs\fP or \fIS\fP indicate the font selection (as made by programs such as
\fBxfontsel(__mansuffix__)\fP) indicated by the second action argument.
.RE
.IP
If \fI\*n\fR is configured to support wide characters, an
additional two optional parameters are recognized for the \fIe\fP argument:
wide font and wide bold font.
.TP 8
.B "smaller\-vt\-font()"
Set the font to the next smaller one, based on the font dimensions.
See also \fBset\-vt\-font()\fP.
.TP 8
.B "soft\-reset()"
This action resets the scrolling region.
It is also invoked from the \fBsoftreset\fP entry in \fIvtMenu\fP.
The effect is identical to a soft reset (DECSTR) control sequence.
.TP 8
.B "spawn\-new\-terminal(\fIparams\fP)"
Spawn a new \fI\*n\fP process.
This is available on systems which have a modern version of the
process filesystem, e.g., \*(``/proc\*('', which \fI\*n\fP can read.
.IP
Use the \*(``cwd\*('' process entry, e.g., /proc/12345/cwd to obtain the
working directory of the process which is running in the current \fI\*n\fP.
.IP
On systems which have the \*(``exe\*('' process entry, e.g., /proc/12345/exe,
use this to obtain the actual executable.
Otherwise, use the \fB$PATH\fP variable to find \fI\*n\fP.
.IP
If parameters are given in the action,
pass them to the new \fI\*n\fP process.
.TP 8
.B "start\-cursor\-extend()"
This action is similar to \fBselect\-extend\fP except that the
selection is extended to the current text cursor position.
.TP 8
.B "start\-extend()"
This action is similar to \fBselect\-start\fP except that the
selection is extended to the current pointer location.
.TP 8
.B "string(\fIstring\fP)"
This action inserts the specified text string as if it had been typed.
Quotation is necessary if the string contains whitespace or
non-alphanumeric characters.
If the string argument begins with the
characters \*(``0x\*('', it is interpreted
as a hex character constant.
.TP 8
.B "tek\-copy()"
This action copies the escape codes used to generate the current window
contents to a file in the current directory beginning with the name COPY.
It is also invoked from the \fBtekcopy\fP entry in \fItekMenu\fP.
.TP 8
.B "tek\-page()"
This action clears the Tektronix window.
It is also invoked by the \fBtekpage\fP entry in \fItekMenu\fP.
.TP 8
.B "tek\-reset()"
This action resets the Tektronix window.
It is also invoked by the \fBtekreset\fP entry in \fItekMenu\fP.
.TP 8
.B "vi\-button()"
Handles a button event (other than press and release)
by echoing a control sequence computed from the event's line number
in the screen relative to the current line:
.NS
ESC ^P
.NE
.IP
or
.NS
ESC ^N
.NE
.IP
according to whether the event is before, or after the current line,
respectively.
The ^N (or ^P) is repeated once for each line that the event differs
from the current line.
The control sequence is omitted altogether if the button event is on the
current line.
.TP 8
.B "visual\-bell()"
This action flashes the window quickly.
.
.PP
The Tektronix window also has the following action:
.TP 8
.B "gin\-press(\fIl/L/m/M/r/R\fP)"
This action sends the indicated graphics input code.
.
.SS "Default Key Bindings"
The default bindings in the VT\fIxxx\fP window use the \fBSELECT\fP token,
which is set by the \fBselectToClipboard\fP resource.
These are for the \fIvt100\fP widget:
.NS
          Shift  Prior:\fBscroll\-back\fP(1,halfpage) \\n\\\&
           Shift  Next:\fBscroll\-forw\fP(1,halfpage) \\n\\\&
         Shift  Select:\fBselect\-cursor\-start\fP() \\\&
                                 \fBselect\-cursor\-end\fP(\fBSELECT\fP, \fBCUT_BUFFER0\fP) \\n\\\&
         Shift  Insert:\fBinsert\-selection\fP(\fBSELECT\fP, \fBCUT_BUFFER0\fP) \\n\\\&
                 Alt Return:\fBfullscreen\fP() \\n\\\&
         Scroll_Lock:\fBscroll\-lock\fP() \\n\\\&
    Shift~Ctrl  KP_Add:\fBlarger\-vt\-font\fP() \\n\\\&
    Shift Ctrl  KP_Add:\fBsmaller\-vt\-font\fP() \\n\\\&
    Shift  KP_Subtract:\fBsmaller\-vt\-font\fP() \\n\\\&
                ~Meta :\fBinsert\-seven\-bit\fP() \\n\\\&
                 Meta :\fBinsert\-eight\-bit\fP() \\n\\\&
                !Ctrl :\fBpopup\-menu\fP(mainMenu) \\n\\\&
           !Lock Ctrl :\fBpopup\-menu\fP(mainMenu) \\n\\\&
 !Lock Ctrl @Num_Lock :\fBpopup\-menu\fP(mainMenu) \\n\\\&
     ! @Num_Lock Ctrl :\fBpopup\-menu\fP(mainMenu) \\n\\\&
                 Meta :\fBselect\-start\fP(block) \\n\\\&
                ~Meta :\fBselect\-start\fP() \\n\\\&
              ~Meta :\fBselect\-extend\fP() \\n\\\&
                !Ctrl :\fBpopup\-menu\fP(vtMenu) \\n\\\&
           !Lock Ctrl :\fBpopup\-menu\fP(vtMenu) \\n\\\&
 !Lock Ctrl @Num_Lock :\fBpopup\-menu\fP(vtMenu) \\n\\\&
     ! @Num_Lock Ctrl :\fBpopup\-menu\fP(vtMenu) \\n\\\&
          ~Ctrl ~Meta :\fBignore\fP() \\n\\\&
                 Meta :\fBclear\-saved\-lines\fP() \\n\\\&
            ~Ctrl ~Meta :\fBinsert\-selection\fP(\fBSELECT\fP, \fBCUT_BUFFER0\fP) \\n\\\&
                !Ctrl :\fBpopup\-menu\fP(fontMenu) \\n\\\&
           !Lock Ctrl :\fBpopup\-menu\fP(fontMenu) \\n\\\&
 !Lock Ctrl @Num_Lock :\fBpopup\-menu\fP(fontMenu) \\n\\\&
     ! @Num_Lock Ctrl :\fBpopup\-menu\fP(fontMenu) \\n\\\&
          ~Ctrl ~Meta :\fBstart\-extend\fP() \\n\\\&
              ~Meta :\fBselect\-extend\fP() \\n\\\&
                 Ctrl :\fBscroll\-back\fP(1,halfpage,m) \\n\\\&
            Lock Ctrl :\fBscroll\-back\fP(1,halfpage,m) \\n\\\&
  Lock @Num_Lock Ctrl :\fBscroll\-back\fP(1,halfpage,m) \\n\\\&
       @Num_Lock Ctrl :\fBscroll\-back\fP(1,halfpage,m) \\n\\\&
                      :\fBscroll\-back\fP(5,line,m)     \\n\\\&
                 Ctrl :\fBscroll\-forw\fP(1,halfpage,m) \\n\\\&
            Lock Ctrl :\fBscroll\-forw\fP(1,halfpage,m) \\n\\\&
  Lock @Num_Lock Ctrl :\fBscroll\-forw\fP(1,halfpage,m) \\n\\\&
       @Num_Lock Ctrl :\fBscroll\-forw\fP(1,halfpage,m) \\n\\\&
                      :\fBscroll\-forw\fP(5,line,m)     \\n\\\&
                         :\fBselect\-end\fP(\fBSELECT\fP, \fBCUT_BUFFER0\fP) \\n\\\&
                     :\fBpointer\-motion\fP() \\n\\\&
                       :\fBpointer\-button\fP() \\n\\\&
                         :\fBpointer\-button\fP() \\n\\\&
                       :\fBignore\fP()
.NE
.PP
The default bindings in the Tektronix window are analogous but less extensive.
These are for the \fItek4014\fP widget:
.NS
                 ~Meta: \fBinsert\-seven\-bit\fP() \\n\\\&
                  Meta: \fBinsert\-eight\-bit\fP() \\n\\\&
                !Ctrl : \fBpopup\-menu\fP(mainMenu) \\n\\\&
           !Lock Ctrl : \fBpopup\-menu\fP(mainMenu) \\n\\\&
 !Lock Ctrl @Num_Lock : \fBpopup\-menu\fP(mainMenu) \\n\\\&
      !Ctrl @Num_Lock : \fBpopup\-menu\fP(mainMenu) \\n\\\&
                !Ctrl : \fBpopup\-menu\fP(tekMenu) \\n\\\&
           !Lock Ctrl : \fBpopup\-menu\fP(tekMenu) \\n\\\&
 !Lock Ctrl @Num_Lock : \fBpopup\-menu\fP(tekMenu) \\n\\\&
      !Ctrl @Num_Lock : \fBpopup\-menu\fP(tekMenu) \\n\\\&
           Shift ~Meta: \fBgin\-press\fP(L) \\n\\\&
                 ~Meta: \fBgin\-press\fP(l) \\n\\\&
           Shift ~Meta: \fBgin\-press\fP(M) \\n\\\&
                 ~Meta: \fBgin\-press\fP(m) \\n\\\&
           Shift ~Meta: \fBgin\-press\fP(R) \\n\\\&
                 ~Meta: \fBgin\-press\fP(r)
.NE
.SS "Custom Key Bindings"
You can modify the \fBtranslations\fP resource by overriding parts
of it, or merging your resources with it.
.PP
Here is an example which uses shifted select/paste to copy to the clipboard,
and unshifted select/paste for the primary selection.
In each case, a (different) cut buffer is
also a target or source of the select/paste operation.
It is important to remember however,
that cut buffers store data in ISO-8859-1 encoding,
while selections can store data in a variety of formats and encodings.
While \fI\*n\fP owns the selection, it highlights it.
When it loses the selection, it removes the corresponding highlight.
But you can still paste from the corresponding cut buffer.
.NS
*VT100*translations:    #override \\n\\\&
   ~Shift~Ctrl: \fBinsert\-selection\fP(\fBPRIMARY\fP, \fBCUT_BUFFER0\fP) \\n\\\&
    Shift~Ctrl: \fBinsert\-selection\fP(\fBCLIPBOARD\fP, \fBCUT_BUFFER1\fP) \\n\\\&
   ~Shift      : \fBselect\-end\fP(\fBPRIMARY\fP, \fBCUT_BUFFER0\fP) \\n\\\&
    Shift      : \fBselect\-end\fP(\fBCLIPBOARD\fP, \fBCUT_BUFFER1\fP)
.NE
.PP
In the example, the class name \fBVT100\fP is used rather than the widget name.
These are different; a class name could apply to more than one widget.
A leading \*(``*\*('' is used because the widget hierarchy above the
\fIvt100\fP widget depends on
whether the toolbar support is compiled into \fI\*n\fP.
.PP
Most of the predefined translations are related to the mouse,
with a few that use some of the special keys on the keyboard.
Applications use special keys (function-keys, cursor-keys, keypad-keys)
with modifiers (shift, control, alt).
If \fI\*n\fP defines a translation for a given combination of
special key and modifier, that makes it unavailable for use
by applications within the terminal.
For instance, one might extend the use of \fIPage Up\fP and \fIPage Down\fP
keys seen here:
.NS
    Shift  Prior : \fBscroll\-back\fP(1,halfpage) \\n\\\&
    Shift  Next  : \fBscroll\-forw\fP(1,halfpage) \\n\\\&
.NE
.PP
to the \fIHome\fP and \fIEnd\fP keys:
.NS
    Shift  Home : \fBscroll\-to\fP(begin) \\n\\\&
    Shift  End  : \fBscroll\-to\fP(end)
.NE
.PP
but then shift\-\fIHome\fP and shift\-\fIEnd\fP would then
be unavailable to applications.
.PP
Not everyone finds the three-button mouse bindings easy to use.
In a wheel mouse, the middle button might be the wheel.
As an alternative, you could add a binding using shifted keys:
.NS
*VT100*translations:      #override \\n\\\&
    Shift Home:    \fBcopy\-selection\fP(\fBSELECT\fP) \\n\\\&
    Shift Insert:  \fBcopy\-selection\fP(\fBSELECT\fP) \\n\\\&
    Ctrl Shift C:  \fBcopy\-selection\fP(\fBSELECT\fP) \\n\\\&
    Ctrl Shift V:  \fBinsert\-selection\fP(\fBSELECT\fP)
.NE
.PP
You would still use the left- and right-mouse buttons (typically 1 and 3)
for beginning and extending selections.
.PP
Besides mouse problems, there are also keyboards with inconvenient layouts.
Some lack a numeric keypad, making it hard to use the shifted keypad plus
and minus bindings for switching between font sizes.
You can work around that by assigning the actions to more readily accessed
keys:
.NS
*VT100*translations:      #override \\n\\\&
    Ctrl  +:       \fBlarger\-vt\-font\fP() \\n\\\&
    Ctrl  \-:       \fBsmaller\-vt\-font\fP()
.NE
.PP
The keymap feature allows you to switch between sets of translations.
The sample below shows
how the \fBkeymap()\fP action may be used to add special
keys for entering commonly-typed words:
.NS
*VT100.Translations: #override F13: keymap(dbx)
*VT100.dbxKeymap.translations: \\\&
        F14:       \fBkeymap\fP(None) \\n\\\&
        F17:       \fBstring\fP("next") \\n\\\&
                        \fBstring\fP(0x0d) \\n\\\&
        F18:       \fBstring\fP("step") \\n\\\&
                        \fBstring\fP(0x0d) \\n\\\&
        F19:       \fBstring\fP("continue") \\n\\\&
                        \fBstring\fP(0x0d) \\n\\\&
        F20:       \fBstring\fP("print ") \\n\\\&
                        \fBinsert\-selection\fP(\fBPRIMARY\fP, \fBCUT_BUFFER0\fP)
.NE
.SS "Default Scrollbar Bindings"
Key bindings are normally associated with the \fIvt100\fP or \fItek4014\fP
widgets which act as terminal emulators.
\fI\*N\fP's scrollbar (and toolbar if it is configured) are separate widgets.
Because all of these use the \fIX Toolkit\fP,
they have corresponding \fBtranslations\fP resources.
Those resources are distinct,
and match different patterns, e.g., the differences in widget-name and
number of levels of widgets which they may contain.
.PP
The \fIscrollbar\fP widget is a child of the \fIvt100\fP widget.
It is positioned on top of the \fIvt100\fP widget.
Toggling the scrollbar on and off causes the \fIvt100\fP widget to resize.
.PP
The default bindings for the scrollbar widget use only mouse-button events:
.NS
   : StartScroll(Forward) \\n\\\&
   : StartScroll(Forward) \\n\\\&
   : StartScroll(Continuous) MoveThumb() NotifyThumb() \\n\\\&
   : StartScroll(Backward) \\n\\\&
   : StartScroll(Backward) \\n\\\&
   : MoveThumb() NotifyThumb() \\n\\\&
   :    NotifyScroll(Proportional) EndScroll()
.NE
.PP
Events which the \fIscrollbar\fP widget does not recognize at all are lost.
.PP
However, at startup, \fI\*n\fP augments these translations with the default
translations used for the \fIvt100\fP widget,
together with the resource \*(``actions\*('' which those translations use.
Because the \fIscrollbar\fP (or \fImenubar\fP) widgets do not recognize these
actions (but because it has a corresponding translation),
they are passed on to the \fIvt100\fP widget.
.PP
This augmenting of the scrollbar's translations has a few limitations:
.bP
\fI\*N\fP knows what the default translations are,
but there is no suitable library interface for determining what
customizations a user may have added to the \fIvt100\fP widget.
All that \fI\*n\fP can do is augment the \fIscrollbar\fP widget to
give it the same starting point for further customization by the user.
.bP
Events in the gap between the widgets may be lost.
.bP
Compose sequences begun in one widget cannot be completed in the other,
because the input methods for each widget do not share context information.
.PP
Most customizations of the scrollbar translations do not concern key bindings.
Rather, users are generally more interested in changing the bindings of the
mouse buttons.
For example, some people prefer using the left pointer button
for dragging the scrollbar thumb.
That can be set up by altering the translations resource, e.g.,
.NS
*VT100.scrollbar.translations:  #override \\n\\\&
   :     StartScroll(Forward) \\n\\\&
   :     StartScroll(Continuous) MoveThumb() NotifyThumb() \\n\\\&
   :     StartScroll(Backward) \\n\\\&
   :   MoveThumb() NotifyThumb() \\n\\\&
   :        NotifyScroll(Proportional) EndScroll()
.NE
.SH "CONTROL SEQUENCES AND KEYBOARD"
Applications can send sequences of characters to the terminal to change its
behavior.
Often they are referred to as
\*(``ANSI escape sequences\*('' or just plain
\*(``escape sequences\*('' but both terms are misleading:
.bP
ANSI x3.64 (obsolete) which was replaced by ISO 6429 (ECMA-48) gave rules
for the \fIformat\fP of these sequences of characters.
.bP
While the original VT100 was claimed to be ANSI-compatible (against x3.64),
there is no freely available version of the ANSI standard to show where
the VT100 differs.
Most of the documents which mention the ANSI standard have
additions not found in the original (such as those
based on \fBansi.sys\fP).
So this discussion focuses on the ISO standards.
.bP
The standard describes only sequences sent from the host to the terminal.
There is no standard for sequences sent by special keys from the terminal
to the host.
By convention (and referring to existing terminals), the format of those
sequences usually conforms to the host-to-terminal standard.
.bP
Some of \fI\*n\fP's sequences do not fit into the standard scheme.
Technically those are \*(``unspecified\*(''.
As an example,
DEC Screen Alignment Test (DECALN) is this three-character sequence:
.NS
\fIESC\fP # 8
.NE
.bP
Some sequences fit into the standard format,
but are not listed in the standard.
These include the sequences used for setting up scrolling margins
and doing forward/reverse scrolling.
.bP
Some of the sequences (in particular, the single-character functions
such as tab and backspace)
do not include the \fIescape\fP character.
.PP
With all of that in mind, the standard refers to these sequences of
characters as \*(``control sequences\*(''.
.PP
\fI\*N Control Sequences\fP lists the control sequences which
an application can send \fI\*n\fP to make it perform various operations.
Most of these operations are standardized, from either the DEC or Tektronix
terminals, or from more widely used standards such as ISO-6429.
.PP
A few examples of usage are given in this section.
.SS "Window and Icon Titles"
Some scripts use \fBecho\fP with options \fB\-e\fP and \fB\-n\fP to tell
the shell to interpret the string \*(``\\e\*('' as
the \fIescape\fP character and
to suppress a trailing newline on output.
Those are not portable, nor recommended.
Instead, use \fBprintf\fP(1) (POSIX).
.PP
For example, to set the \fIwindow title\fP to \*(``Hello world!\*('',
you could use one of these commands in a script:
.NS
printf \*'\\033]2;Hello world!\\033\\\\\*'
printf \*'\\033]2;Hello world!\\007\*'
printf \*'\\033]2;%s\\033\\\\\*' "Hello world!"
printf \*'\\033]2;%s\\007\*' "Hello world!"
.NE
.PP
The \fBprintf\fP(1) command interprets the octal value \*(``\\033\*('' for
\fIescape\fP, and (since it was not given in the format) omits a trailing
newline from the output.
.PP
Some programs (such as \fBscreen\fP(1)) set both window- and icon-titles
at the same time, using a slightly different control sequence:
.NS
printf \*'\\033]0;Hello world!\\033\\\\\*'
printf \*'\\033]0;Hello world!\\007\*'
printf \*'\\033]0;%s\\033\\\\\*' "Hello world!"
printf \*'\\033]0;%s\\007\*' "Hello world!"
.NE
.PP
The difference is the \fIparameter\fP \*(``0\*('' in each command.
Most window managers will honor either window title or icon title.
Some will make a distinction and allow you to set just the icon title.
You can tell \fI\*n\fP to ask for this with a different parameter
in the control sequence:
.NS
printf \*'\\033]1;Hello world!\\033\\\\\*'
printf \*'\\033]1;Hello world!\\007\*'
printf \*'\\033]1;%s\\033\\\\\*' "Hello world!"
printf \*'\\033]1;%s\\007\*' "Hello world!"
.NE
.
.SS "Special Keys"
\fI\*N\fP, like any VT100-compatible terminal emulator,
has two modes for the \fIspecial keys\fP (cursor-keys, numeric keypad,
and certain function-keys):
.bP
\fInormal mode\fP, which makes the special keys transmit
\*(``useful\*('' sequences such as the control sequence for cursor-up
when pressing the up-arrow, and
.bP
\fIapplication mode\fP,
which uses a different control sequence that cannot be mistaken for
the
\*(``useful\*('' sequences.
.PP
The main difference between the two modes is that normal mode sequences
start with \fICSI\fP (\fIescape\ [\fP) and application mode sequences
start with \fISS3\fP (\fIescape\ O\fP).
.PP
The terminal is initialized into one of these two modes (usually the
normal mode), based on the terminal description (termcap or terminfo).
The terminal description also has capabilities (strings) defined for
the keypad mode used in curses applications.
.PP
There is a problem in using the terminal description for applications
that are not intended to be full-screen curses applications:
the definitions of special keys are only correct for this keypad mode.
For example, some shells
(unlike \fBksh\fP(1), which appears to be hard-coded, not even using termcap)
allow their users to customize key-bindings,
assigning shell actions to special keys.
.bP
\fBbash\fP(1) allows \fIconstant\fP strings to be assigned
to functions.
This is only successful if the terminal is initialized to application
mode by default,
because \fBbash\fP lacks flexibility in this area.
It uses a (less expressive than \fBbash\fP's)
\fBreadline\fP scripting language for setting up key bindings,
which relies upon the user to statically enumerate the possible bindings for
given values of \fB$TERM\fP.
.bP
\fBzsh\fP(1) provides an analogous feature,
but it accepts runtime expressions,
as well as providing a \fB$terminfo\fP array for scripts.
In particular, one can use the terminal database,
transforming when defining a key-binding.
By transforming the output so that \fICSI\fP and \fISS3\fP are equated,
\fBzsh\fP can use the terminal database to obtain useful definitions
for its command-line use regardless of whether the terminal uses
normal or application mode initially.
Here is an example:
.NS
[[ "$terminfo[kcuu1]" == "^[O"* ]] && \\\&
bindkey \-M viins "${terminfo[kcuu1]/O/[}" \\\&
vi\-up\-line\-or\-history
.NE
.
.
.SS "Changing Colors"
A few shell programs provide the ability for users to add color and other
video attributes to the shell prompt strings.
Users can do this by setting \fB$PS1\fP (the primary prompt string).
Again, \fBbash\fP and \fBzsh\fP have provided features not found in \fBksh\fP.
There is a problem, however: the prompt's width on the screen will not
necessarily be the same as the number of characters.
Because there is no guidance in the POSIX standard, each shell addresses
the problem in a different way:
.bP
\fBbash\fP treats characters within
\*(``\\[\*('' and
\*(``\\]\*(''
as nonprinting (using no width on the screen).
.bP
\fBzsh\fP treats characters within
\*(``%{\*('' and
\*(``%}\*(''
as nonprinting.
.PP
In addition to the difference in syntax,
the shells provide different methods for obtaining useful escape sequences:
.bP
As noted in \fBSpecial Keys\fP, \fBzsh\fP initializes the $terminfo array
with the terminal capabilities.
.IP
It also provides a function \fBechoti\fP which works like \fBtput\fP(1)
to convert a terminal capability with its parameters into a string
that can be written to the terminal.
.bP
Shells lacking a comparable feature (such as \fBbash\fP) can always
use the program \fBtput\fP(1) to do this transformation.
.PP
Hard-coded escape sequences are supported by each shell,
but are not recommended because those rely upon particular configurations
and cannot be easily moved between different user environments.
.
.
.SH ENVIRONMENT
\fI\*N\fP sets several environment variables.
.SS "System Independent"
Some variables are used on every system:
.TP 5
.B DISPLAY
is the display name,
pointing to the X server (see \fIDISPLAY NAMES\fP in X(__miscmansuffix__)).
.TP 5
.B TERM
.br
is set according to the terminfo (or termcap) entry which it is using as
a reference.
.IP
On some systems, you may encounter situations where the shell which you
use and \fI\*n\fP are built using libraries with different terminal databases.
In that situation, \fI\*n\fP may choose a terminal description not known
to the shell.
.TP 5
.B WINDOWID
is set to the X window id number of the \fI\*n\fP window.
.TP 5
.B XTERM_FILTER
is set if a locale-filter is used.
The value is the pathname of the filter.
.TP 5
.B XTERM_LOCALE
shows the locale which was used by \fI\*n\fP on startup.
Some shell initialization scripts may set a different locale.
.TP 5
.B XTERM_SHELL
is set to the pathname of the program which is invoked.
Usually that is a shell program, e.g., \fI/bin/sh\fP.
Since it is not necessarily a shell program however,
it is distinct from \*(``SHELL\*(''.
.TP 5
.B XTERM_VERSION
is set to the string displayed by the \fB\-version\fP option.
That is normally an identifier for the X Window libraries used to
build \fI\*n\fP, followed by
\fI\*n\fP's patch number in parenthesis.
The patch number is also part of the response to a Secondary Device Attributes
(DA) control sequence (see \fIXterm Control Sequences\fP).
.
.SS "System Dependent"
.
Depending on your system configuration, \fI\*n\fP may also set the
following:
.TP 5
.B COLUMNS
the width of the \fI\*n\fP in characters (cf: \*(``stty columns\*('').
.IP
When this variable is set, \fIcurses\fP applications (and most
terminal programs) will assume that the terminal has this many columns.
.IP
\fI\*N\fP would do this for systems which have no ability
to tell the size of the terminal.
Those are very rare, none newer than the mid 1990s when SVR4 became prevalent.
.TP 5
.B HOME
.br
when \fI\*n\fP is configured (at build-time) to update __utmp_name__.
.TP 5
.B LINES
the height of the \fI\*n\fP in characters (cf: \*(``stty rows\*('').
.IP
When this variable is set, \fIcurses\fP applications (and most
terminal programs) will assume that the terminal has this many lines (rows).
.IP
\fI\*N\fP would do this for systems which have no ability
to tell the size of the terminal.
Those are very rare, none newer than the mid 1990s when SVR4 became prevalent.
.TP 5
.B LOGNAME
when \fI\*n\fP is configured (at build-time) to update __utmp_name__.
.IP
Your configuration may have set \fBLOGNAME\fP; \fI\*n\fP does not modify that.
If it is unset, \fI\*n\fP will use \fBUSER\fP if it is set.
Finally, if neither is set, \fI\*n\fP will use the \fBgetlogin\fP(3) function.
.TP 5
.B SHELL
when \fI\*n\fP is configured (at build-time) to update __utmp_name__.
It is also set if you provide a valid shell name as the optional parameter.
.IP
\fI\*N\fP sets this to an absolute pathname.
If you have set the variable to a relative pathname,
\fI\*n\fP may set it to a different shell pathname.
.IP
If you have set this to an pathname which does not correspond to a valid
shell, \fI\*n\fP may unset it, to avoid confusion.
.TP 5
.B TERMCAP
the contents of the termcap entry corresponding to \fB$TERM\fP,
with lines and columns values substituted
for the actual size window you have created.
.IP
This feature is, like \fBLINES\fP and \fBCOLUMNS\fP, used rarely.
It addresses the same limitation of a few older systems
by providing a way for \fItermcap\fP-based applications to get the initial
screen size.
.TP 5
.B TERMINFO
may be defined to a nonstandard location using the configure script.
.\"
.
.SH "WINDOW PROPERTIES"
.
In the output from \fBxprop\fP(1), there are several properties.
.SS "Properties set by X Toolkit"
.TP 5
.B WM_CLASS
This shows the \fIinstance name\fP and the X resource \fIclass\fP,
passed to \fIX Toolkit\fP during initialization of \fI\*n\fP,
e.g.,
.NS
WM_CLASS(STRING) = "xterm", "UXTerm"
.NE
.TP 5
.B WM_CLIENT_LEADER
This shows the window-id which \fI\*n\fP provides
with an environment variable (\fBWINDOWID\fP),
e.g.,
.NS
WM_CLIENT_LEADER(WINDOW): window id # 0x800023
.NE
.TP 5
.B WM_COMMAND
This shows the command-line arguments for \fI\*n\fP
which are passed to \fIX Toolkit\fP during initialization, e.g.,
.NS
WM_COMMAND(STRING) = { "xterm", "\-class", "UXTerm", "\-title", "uxterm", "\-u8" }
.NE
.TP 5
.B WM_ICON_NAME
This holds the icon title,
which different window managers handle in various ways.
It is set via the \fBiconName\fP resource.
Applications can change this using control sequences.
.TP 5
.B WM_LOCALE_NAME
This shows the result from the \fBsetlocale\fP(3) function
for the \fILC_CTYPE\fP category,
e.g.,
.NS
WM_LOCALE_NAME(STRING) = "en_US.UTF\-8"
.NE
.TP 5
.B WM_NAME
This holds the window title, normally at the top of \fI\*n\fP's window.
It is set via the \fBtitle\fP resource.
Applications can change this using control sequences.
.SS "Properties set by Xterm"
\fIX Toolkit\fP does not manage EWMH properties.
\*N does this directly.
.TP 5
.B _NET_WM_ICON_NAME
stores the icon name.
.TP 5
.B _NET_WM_NAME
stores the title string.
.TP 5
.B _NET_WM_PID
stores the process identifier for \fI\*n\fP's display.
.SS "Properties used by Xterm"
.TP 5
.B _NET_SUPPORTED
\*N checks this property on the \fIsupporting window\fP
to decide if the window manager supports
specific maximizing styles.
That may include other window manager hints;
\fI\*n\fP uses the X library calls to manage those.
.TP 5
.B _NET_SUPPORTING_WM_CHECK
\*N checks this to ensure that it will only update the EWMH
properties for a window manager which claims EWMH compliance.
.TP 5
.B _NET_WM_STATE
This tells \fI\*n\fP whether
its window has been maximized by the window manager,
and if so, what type of maximizing:
.RS
.TP 5
.B _NET_WM_STATE_FULLSCREEN
.TP 5
.B _NET_WM_STATE_MAXIMIZED_HORZ
.TP 5
.B _NET_WM_STATE_MAXIMIZED_VERT
.RE
.
.
.SH FILES
The actual pathnames given may differ on your system.
.TP 5
\fI/etc/shells\fP
contains a list of valid shell programs,
used by \fI\*n\fP to decide if the \*(``SHELL\*('' environment
variable should be set for the process started by \fI\*n\fP.
.IP
On systems which have the \fIgetusershell\fP function,
\fI\*n\fP will use that function rather than directly reading the file,
since the file may not be present if the system uses default settings.
.TP 5
\fI__utmp_path__\fP
the system log file, which records user logins.
.TP 5
\fI__wtmp_path__\fP
the system log file, which records user logins and logouts.
.TP 5
.I __apploaddir__/__default_class__
the \fI\*n\fP default application resources.
.TP 5
.I __apploaddir__/__default_class__\-color
the \fI\*n\fP color application resources.
If your display supports color, use this
.NS
*customization: \-color
.NE
.IP
in your \&.Xdefaults file to
automatically use this resource file rather than
.IR __apploaddir__/__default_class__ .
If you do not do this,
\fI\*n\fP uses its compiled-in default resource settings for colors.
.TP 5
.I __pixmapsdir__
the directory in which \fI\*n\fP's pixmap icon files are installed.
.
.
.SH "ERROR MESSAGES"
Most of the fatal error messages from \fI\*n\fP use the following format:
.NS
\*n: Error \fIXXX\fP, errno \fIYYY\fP: \fIZZZ\fR
.NE
.PP
The \fIXXX\fP codes (which are used by \fI\*n\fP as its exit-code)
are listed below, with a brief explanation.
.TP 5
1
ERROR_MISC
.br
miscellaneous errors, usually accompanied by a specific message,
.TP
11
ERROR_FIONBIO
.br
main: ioctl() failed on FIONBIO
.TP
12
ERROR_F_GETFL
.br
main: ioctl() failed on F_GETFL
.TP
13
ERROR_F_SETFL
.br
main: ioctl() failed on F_SETFL
.TP
14
ERROR_OPDEVTTY
.br
spawn: open() failed on /dev/tty
.TP
15
ERROR_TIOCGETP
.br
spawn: ioctl() failed on TIOCGETP
.TP
17
ERROR_PTSNAME
.br
spawn: ptsname() failed
.TP
18
ERROR_OPPTSNAME
.br
spawn: open() failed on ptsname
.TP
19
ERROR_PTEM
.br
spawn: ioctl() failed on I_PUSH/"ptem"
.TP
20
ERROR_CONSEM
.br
spawn: ioctl() failed on I_PUSH/"consem"
.TP
21
ERROR_LDTERM
.br
spawn: ioctl() failed on I_PUSH/"ldterm"
.TP
22
ERROR_TTCOMPAT
.br
spawn: ioctl() failed on I_PUSH/"ttcompat"
.TP
23
ERROR_TIOCSETP
.br
spawn: ioctl() failed on TIOCSETP
.TP
24
ERROR_TIOCSETC
.br
spawn: ioctl() failed on TIOCSETC
.TP
25
ERROR_TIOCSETD
.br
spawn: ioctl() failed on TIOCSETD
.TP
26
ERROR_TIOCSLTC
.br
spawn: ioctl() failed on TIOCSLTC
.TP
27
ERROR_TIOCLSET
.br
spawn: ioctl() failed on TIOCLSET
.TP
28
ERROR_INIGROUPS
.br
spawn: initgroups() failed
.TP
29
ERROR_FORK
.br
spawn: fork() failed
.TP
30
ERROR_EXEC
.br
spawn: exec() failed
.TP
32
ERROR_PTYS
.br
get_pty: not enough ptys
.TP
34
ERROR_PTY_EXEC
.br
waiting for initial map
.TP
35
ERROR_SETUID
.br
spawn: setuid() failed
.TP
36
ERROR_INIT
.br
spawn: can't initialize window
.TP
46
ERROR_TIOCKSET
.br
spawn: ioctl() failed on TIOCKSET
.TP
47
ERROR_TIOCKSETC
.br
spawn: ioctl() failed on TIOCKSETC
.TP
49
ERROR_LUMALLOC
.br
luit: command-line malloc failed
.TP
50
ERROR_SELECT
.br
in_put: select() failed
.TP
54
ERROR_VINIT
.br
VTInit: can't initialize window
.TP
57
ERROR_KMMALLOC1
.br
HandleKeymapChange: malloc failed
.TP
60
ERROR_TSELECT
.br
Tinput: select() failed
.TP
64
ERROR_TINIT
.br
TekInit: can't initialize window
.TP
71
ERROR_BMALLOC2
.br
SaltTextAway: malloc() failed
.TP
80
ERROR_LOGEXEC
.br
StartLog: exec() failed
.TP
83
ERROR_XERROR
.br
xerror: XError event
.TP
84
ERROR_XIOERROR
.br
xioerror: X I/O error
.TP
85
ERROR_ICEERROR
.br
ICE I/O error
.TP
90
ERROR_SCALLOC
.br
Alloc: calloc() failed on base
.TP
91
ERROR_SCALLOC2
.br
Alloc: calloc() failed on rows
.TP
102
ERROR_SAVE_PTR
.br
ScrnPointers: malloc/realloc() failed
.
.
.SH BUGS
.
Large pastes do not work on some systems.
This is not a bug in
\fI\*n\fP; it is a bug in the pseudo terminal driver of those
systems.
\fI\*N\fP feeds large pastes to the pty only as fast as the pty
will accept data, but some pty drivers do not return enough information
to know if the write has succeeded.
.
.PP
When connected to an input method, it is possible for \fI\*n\fP to hang
if the XIM server is suspended or killed.
.
.PP
Many of the options are not resettable after \fI\*n\fP starts.
.
.PP
This program still needs to be rewritten.
It should be split into very
modular sections, with the various emulators being completely separate
widgets that do not know about each other.
Ideally, you'd like to be able to
pick and choose emulator widgets and stick them into a single control widget.
.
.PP
There needs to be a dialog box to allow entry of the Tek COPY file name.
.
.SH AUTHORS
Far too many people.
.PP
These contributed to the X Consortium:
Loretta Guarino Reid (DEC-UEG-WSL),
Joel McCormack (DEC-UEG-WSL), Terry Weissman (DEC-UEG-WSL),
Edward Moy (Berkeley), Ralph R.\& Swick (MIT-Athena),
Mark Vandevoorde (MIT-Athena), Bob McNamara (DEC-MAD),
Jim Gettys (MIT-Athena), Bob Scheifler (MIT X Consortium), Doug Mink (SAO),
Steve Pitschke (Stellar), Ron Newman (MIT-Athena), Jim Fulton (MIT X
Consortium), Dave Serisky (HP), Jonathan Kamens (MIT-Athena).
.PP
Beginning with XFree86, there were far more identifiable contributors.
The \fITHANKS\fP file in \fI\*n\fP's source lists 243 in June 2022.
Keep in mind these:
Jason Bacon,
Jens Schweikhardt,
Ross Combs,
Stephen P.\& Wall,
David Wexelblat, and
Thomas Dickey (invisible\-island.net).
.
.
.SH "SEE ALSO"
.na
resize(__mansuffix__),
luit(__mansuffix__),
u\*n(__mansuffix__),
X(__miscmansuffix__),
Xcursor(__miscmansuffix__),
pty(4),
tty(4)
.ad
.PP
\fIXterm Control Sequences\fP
(this is the file ctlseqs.ms).
.RS 4n
.sp
https://invisible\-island.net/xterm/xterm.html
.br
https://invisible\-island.net/xterm/manpage/xterm.html
.br
https://invisible\-island.net/xterm/ctlseqs/ctlseqs.html
.br
https://invisible\-island.net/xterm/xterm.faq.html
.br
https://invisible\-island.net/xterm/xterm.log.html
.RE
.PP
\fIX Toolkit Intrinsics \(en C Language Interface\fR (Xt),
.br
Joel McCormack, Paul Asente, Ralph R. Swick (1994),
.br
Thomas E. Dickey (2019).
.PP
\fIInter-Client Communication Conventions Manual\fR (ICCCM),
.br
David Rosenthal and
Stuart W. Marks (version 2.0, 1994).
.PP
\fIExtended Window Manager Hints\fP (EWMH),
.br
X Desktop Group (version 1.3, 2005).
.PP
EWMH uses \fIUTF8_STRING\fP pervasively without defining it,
but does mention the ICCCM.
Version 2.0 of the ICCCM does not address UTF-8.
That is an extension added in XFree86.
.bP
Markus Kuhn summarized this in
\fIUTF-8 and Unicode FAQ for Unix/Linux\fP (2001),
in the section \*(``Is X11 ready for Unicode?\*(''
.IP
https://www.cl.cam.ac.uk/~mgk25/unicode.html
.bP
Juliusz Chroboczek proposed the UTF8_STRING selection atom in 1999/2000,
which became part of the ICCCM in XFree86.
.IP
https://www.irif.fr/~jch/software/UTF8_STRING/
.IP
An Xorg developer removed that part of the documentation in 2004
when incorporating other work from XFree86 into Xorg.
The feature is still supported in Xorg, though undocumented as of 2019.
xterm-399/util.c0000644000000000000000000044544515011755511012377 0ustar  rootroot/* $XTermId: util.c,v 1.958 2025/05/17 00:41:45 tom Exp $ */

/*
 * Copyright 1999-2024,2025 by Thomas E. Dickey
 *
 *                         All Rights Reserved
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name(s) of the above copyright
 * holders shall not be used in advertising or otherwise to promote the
 * sale, use or other dealings in this Software without prior written
 * authorization.
 *
 *
 * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 *
 *                         All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of Digital Equipment
 * Corporation not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.
 *
 *
 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

/* util.c */

#include 

#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 

#if OPT_WIDE_CHARS
#if defined(HAVE_WCHAR_H) && defined(HAVE_WCWIDTH)
#include 
#endif
#include 
#endif

#ifdef HAVE_X11_EXTENSIONS_XINERAMA_H
#include 
#endif /* HAVE_X11_EXTENSIONS_XINERAMA_H */

#include 

#define IncrementSavedLines(amount) \
	    if (screen->savedlines < screen->savelines) { \
		if ((screen->savedlines += amount) > screen->savelines) \
		    screen->savedlines = screen->savelines; \
		ScrollBarDrawThumb(xw, 1); \
	    }

static int handle_translated_exposure(XtermWidget xw,
				      int rect_x,
				      int rect_y,
				      int rect_width,
				      int rect_height);
static void ClearLeft(XtermWidget xw);
static void CopyWait(XtermWidget xw);
static void horizontal_copy_area(XtermWidget xw,
				 int firstchar,
				 int nchars,
				 int amount);
static void vertical_copy_area(XtermWidget xw,
			       int firstline,
			       int nlines,
			       int amount,
			       int left,
			       int right);

#if OPT_WIDE_CHARS
unsigned first_widechar;
int (*my_wcwidth) (wchar_t);
#endif

#if OPT_WIDE_CHARS
/*
 * We will modify the 'n' cells beginning at the current position.
 * Some of those cells may be part of multi-column characters, including
 * carryover from the left.  Find the limits of the multi-column characters
 * that we should fill with blanks, return true if filling is needed.
 */
int
DamagedCells(TScreen *screen, unsigned n, int *klp, int *krp, int row, int col)
{
    CLineData *ld = getLineData(screen, row);
    int result = False;

    assert(ld);
    if (col < (int) ld->lineSize) {
	int nn = (int) n;
	int kl = col;
	int kr = col + nn;

	if (kr >= (int) ld->lineSize) {
	    nn = (ld->lineSize - col - 1);
	    kr = col + nn;
	}

	if (nn > 0) {
	    assert(kl < (int) ld->lineSize);
	    if (ld->charData[kl] == HIDDEN_CHAR) {
		while (kl > 0) {
		    if (ld->charData[--kl] != HIDDEN_CHAR) {
			break;
		    }
		}
	    } else {
		kl = col + 1;
	    }

	    assert(kr < (int) ld->lineSize);
	    if (ld->charData[kr] == HIDDEN_CHAR) {
		while (kr < screen->max_col) {
		    assert((kr + 1) < (int) ld->lineSize);
		    if (ld->charData[++kr] != HIDDEN_CHAR) {
			--kr;
			break;
		    }
		}
	    } else {
		kr = col - 1;
	    }

	    if (klp)
		*klp = kl;
	    if (krp)
		*krp = kr;
	    result = (kr >= kl);
	}
    }

    return result;
}

int
DamagedCurCells(TScreen *screen, unsigned n, int *klp, int *krp)
{
    return DamagedCells(screen, n, klp, krp, screen->cur_row, screen->cur_col);
}
#endif /* OPT_WIDE_CHARS */

/*
 * These routines are used for the jump scroll feature
 */
void
FlushScroll(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    int i;
    int shift = INX2ROW(screen, 0);
    int bot = screen->max_row - shift;
    int refreshtop;
    int refreshheight;
    int scrolltop;
    int scrollheight;
    int left = ScrnLeftMargin(xw);
    int right = ScrnRightMargin(xw);
    Boolean full_lines = (Boolean) ((left == 0) && (right == screen->max_col));

    if (screen->cursor_state)
	HideCursor(xw);

    TRACE(("FlushScroll %s-lines scroll:%d refresh %d\n",
	   full_lines ? "full" : "partial",
	   screen->scroll_amt,
	   screen->refresh_amt));

    if (screen->scroll_amt > 0) {
	/*
	 * Lines will be scrolled "up".
	 */
	refreshheight = screen->refresh_amt;
	scrollheight = screen->bot_marg - screen->top_marg - refreshheight + 1;
	refreshtop = screen->bot_marg - refreshheight + 1 + shift;
	i = screen->max_row - screen->scroll_amt + 1;
	if (refreshtop > i) {
	    refreshtop = i;
	}

	/*
	 * If this is the normal (not alternate) screen, and the top margin is
	 * at the top of the screen, then we will shift full lines scrolled out
	 * of the scrolling region into the saved-lines.
	 */
	if (screen->scrollWidget
	    && !screen->whichBuf
	    && full_lines
	    && screen->top_marg == 0) {
	    scrolltop = 0;
	    scrollheight += shift;
	    if (scrollheight > i)
		scrollheight = i;
	    i = screen->bot_marg - bot;
	    if (i > 0) {
		refreshheight -= i;
		if (refreshheight < screen->scroll_amt) {
		    refreshheight = screen->scroll_amt;
		}
	    }
	    IncrementSavedLines(screen->scroll_amt);
	} else {
	    scrolltop = screen->top_marg + shift;
	    i = bot - (screen->bot_marg - screen->refresh_amt + screen->scroll_amt);
	    if (i > 0) {
		if (bot < screen->bot_marg) {
		    refreshheight = screen->scroll_amt + i;
		}
	    } else {
		scrollheight += i;
		refreshheight = screen->scroll_amt;
		i = screen->top_marg + screen->scroll_amt - 1 - bot;
		if (i > 0) {
		    refreshtop += i;
		    refreshheight -= i;
		}
	    }
	}
    } else {
	/*
	 * Lines will be scrolled "down".
	 */
	refreshheight = -screen->refresh_amt;
	scrollheight = screen->bot_marg - screen->top_marg - refreshheight + 1;
	refreshtop = screen->top_marg + shift;
	scrolltop = refreshtop + refreshheight;
	i = screen->bot_marg - bot;
	if (i > 0) {
	    scrollheight -= i;
	}
	i = screen->top_marg + refreshheight - 1 - bot;
	if (i > 0) {
	    refreshheight -= i;
	}
    }

    vertical_copy_area(xw,
		       scrolltop + screen->scroll_amt,
		       scrollheight,
		       screen->scroll_amt,
		       left,
		       right);
    ScrollSelection(screen, -(screen->scroll_amt), False);
    screen->scroll_amt = 0;
    screen->refresh_amt = 0;

    if (refreshheight > 0) {
	ClearCurBackground(xw,
			   refreshtop,
			   left,
			   (unsigned) refreshheight,
			   (unsigned) (right + 1 - left),
			   (unsigned) FontWidth(screen));
	ScrnRefresh(xw,
		    refreshtop,
		    0,
		    refreshheight,
		    MaxCols(screen),
		    False);
    }
    xtermTimedDbe(xw);
    return;
}

/*
 * Returns true if there are lines off-screen due to scrolling which should
 * include the current line.  If false, the line is visible and we should
 * paint it now rather than waiting for the line to become visible.
 */
static Bool
AddToRefresh(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    int amount = screen->refresh_amt;
    int row = screen->cur_row;
    Bool result;

    if (amount == 0) {
	result = False;
    } else if (amount > 0) {
	int bottom;

	if (row == (bottom = screen->bot_marg) - amount) {
	    screen->refresh_amt++;
	    result = True;
	} else {
	    result = (row >= bottom - amount + 1 && row <= bottom);
	}
    } else {
	int top;

	amount = -amount;
	if (row == (top = screen->top_marg) + amount) {
	    screen->refresh_amt--;
	    result = True;
	} else {
	    result = (row <= top + amount - 1 && row >= top);
	}
    }

    /*
     * If this line is visible, and there are scrolled-off lines, flush out
     * those which are now visible.
     */
    if (!result && screen->scroll_amt)
	FlushScroll(xw);

    return result;
}

/*
 * Returns true if the current row is in the visible area (it should be for
 * screen operations) and incidentally flush the scrolled-in lines which
 * have newly become visible.
 */
static Bool
AddToVisible(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    Bool result = False;

    if (INX2ROW(screen, screen->cur_row) <= LastRowNumber(screen)) {
	if (!AddToRefresh(xw)) {
	    result = True;
	}
    }
    return result;
}

/*
 * If we're scrolling, leave the selection intact if possible.
 * If it will bump into one of the extremes of the saved-lines, truncate that.
 * If the selection is not entirely contained within the margins and not
 * entirely outside the margins, clear it.
 */
static void
adjustHiliteOnFwdScroll(XtermWidget xw, int amount, Bool all_lines)
{
    TScreen *screen = TScreenOf(xw);
    int lo_row = (all_lines
		  ? (screen->bot_marg - screen->savelines)
		  : screen->top_marg);
    int hi_row = screen->bot_marg;
    int left = ScrnLeftMargin(xw);
    int right = ScrnRightMargin(xw);

    TRACE2(("adjustSelection FWD %s by %d (%s)\n",
	    screen->whichBuf ? "alternate" : "normal",
	    amount,
	    all_lines ? "all" : "visible"));
    TRACE2(("  before highlite %d.%d .. %d.%d\n",
	    screen->startH.row,
	    screen->startH.col,
	    screen->endH.row,
	    screen->endH.col));
    TRACE2(("  margins %d..%d\n", screen->top_marg, screen->bot_marg));
    TRACE2(("  limits  %d..%d\n", lo_row, hi_row));

    if ((left > 0 || right < screen->max_col) &&
	((screen->startH.row >= lo_row &&
	  screen->startH.row - amount <= hi_row) ||
	 (screen->endH.row >= lo_row &&
	  screen->endH.row - amount <= hi_row))) {
	/*
	 * This could be improved slightly by excluding the special case where
	 * the selection is on a single line outside left/right margins.
	 */
	TRACE2(("deselect because selection overlaps with scrolled partial-line\n"));
	ScrnDisownSelection(xw);
    } else if (screen->startH.row >= lo_row
	       && screen->startH.row - amount < lo_row) {
	/* truncate the selection because its start would move out of region */
	if (lo_row + amount <= screen->endH.row) {
	    TRACE2(("truncate selection by changing start %d.%d to %d.%d\n",
		    screen->startH.row,
		    screen->startH.col,
		    lo_row + amount,
		    0));
	    screen->startH.row = lo_row + amount;
	    screen->startH.col = 0;
	} else {
	    TRACE2(("deselect because %d.%d .. %d.%d shifted %d is outside margins %d..%d\n",
		    screen->startH.row,
		    screen->startH.col,
		    screen->endH.row,
		    screen->endH.col,
		    -amount,
		    lo_row,
		    hi_row));
	    ScrnDisownSelection(xw);
	}
    } else if (screen->startH.row <= hi_row && screen->endH.row > hi_row) {
	TRACE2(("deselect because selection straddles top-margin\n"));
	ScrnDisownSelection(xw);
    } else if (screen->startH.row < lo_row && screen->endH.row > lo_row) {
	TRACE2(("deselect because selection straddles bottom-margin\n"));
	ScrnDisownSelection(xw);
    }

    TRACE2(("  after highlite %d.%d .. %d.%d\n",
	    screen->startH.row,
	    screen->startH.col,
	    screen->endH.row,
	    screen->endH.col));
}

/*
 * This is the same as adjustHiliteOnFwdScroll(), but reversed.  In this case,
 * only the visible lines are affected.
 */
static void
adjustHiliteOnBakScroll(XtermWidget xw, int amount)
{
    TScreen *screen = TScreenOf(xw);
    int lo_row = screen->top_marg;
    int hi_row = screen->bot_marg;

    TRACE2(("adjustSelection BAK %s by %d (%s)\n",
	    screen->whichBuf ? "alternate" : "normal",
	    amount,
	    "visible"));
    TRACE2(("  before highlite %d.%d .. %d.%d\n",
	    screen->startH.row,
	    screen->startH.col,
	    screen->endH.row,
	    screen->endH.col));
    TRACE2(("  margins %d..%d\n", screen->top_marg, screen->bot_marg));

    if (screen->endH.row >= hi_row
	&& screen->endH.row + amount > hi_row) {
	/* truncate the selection because its start would move out of region */
	if (hi_row - amount >= screen->startH.row) {
	    TRACE2(("truncate selection by changing start %d.%d to %d.%d\n",
		    screen->startH.row,
		    screen->startH.col,
		    hi_row - amount,
		    0));
	    screen->endH.row = hi_row - amount;
	    screen->endH.col = 0;
	} else {
	    TRACE2(("deselect because %d.%d .. %d.%d shifted %d is outside margins %d..%d\n",
		    screen->startH.row,
		    screen->startH.col,
		    screen->endH.row,
		    screen->endH.col,
		    amount,
		    lo_row,
		    hi_row));
	    ScrnDisownSelection(xw);
	}
    } else if (screen->endH.row >= lo_row && screen->startH.row < lo_row) {
	ScrnDisownSelection(xw);
    } else if (screen->endH.row > hi_row && screen->startH.row > hi_row) {
	ScrnDisownSelection(xw);
    }

    TRACE2(("  after highlite %d.%d .. %d.%d\n",
	    screen->startH.row,
	    screen->startH.col,
	    screen->endH.row,
	    screen->endH.col));
}

/*
 * Move cells in LineData's on the current screen to simulate scrolling by the
 * given amount of lines.
 */
static void
scrollInMargins(XtermWidget xw, int amount, int top)
{
    TScreen *screen = TScreenOf(xw);
    LineData *src;
    LineData *dst;
    int row;
    int left = ScrnLeftMargin(xw);
    int right = ScrnRightMargin(xw);
    int length = right + 1 - left;

    if_OPT_WIDE_CHARS(screen, {
	if (amount != 0) {
	    for (row = top; row <= screen->bot_marg; ++row) {
		LineData *ld;
		if ((ld = getLineData(screen, row + amount)) != NULL) {
		    if (left > 0) {
			if (ld->charData[left] == HIDDEN_CHAR) {
			    Clear1Cell(ld, left - 1);
			    Clear1Cell(ld, left);
			}
		    }
		    if (right + 1 < (int) ld->lineSize) {
			if (ld->charData[right + 1] == HIDDEN_CHAR) {
			    Clear1Cell(ld, right);
			    Clear1Cell(ld, right + 1);
			}
		    }
		}
	    }
	}
    });

    if (amount > 0) {
	for (row = top; row <= screen->bot_marg - amount; ++row) {
	    if ((src = getLineData(screen, row + amount)) != NULL
		&& (dst = getLineData(screen, row)) != NULL) {
		CopyCells(screen, src, dst, left, length, False);
	    }
	}
	while (row <= screen->bot_marg) {
	    ClearCells(xw, 0, (unsigned) length, row, left);
	    ++row;
	}
    } else if (amount < 0) {
	for (row = screen->bot_marg; row >= top - amount; --row) {
	    if ((src = getLineData(screen, row + amount)) != NULL
		&& (dst = getLineData(screen, row)) != NULL) {
		CopyCells(screen, src, dst, left, length, True);
	    }
	}
	while (row >= top) {
	    ClearCells(xw, 0, (unsigned) length, row, left);
	    --row;
	}
    }
}

#if OPT_WIDE_CHARS
/*
 * If we're repainting a section of wide-characters that, e.g., ClearCells has
 * repaired when finding double-cell characters, then we should account for
 * that in the repaint.
 */
static void
ScrnUpdate2(XtermWidget xw,
	    int toprow,
	    int leftcol,
	    int nrows,
	    int ncols,
	    Bool force)
{
    if_OPT_WIDE_CHARS(TScreenOf(xw), {
	if (leftcol + ncols <= TScreenOf(xw)->max_col)
	    ncols++;
	if (leftcol > 0) {
	    leftcol--;
	    ncols++;
	}
    });
    ScrnUpdate(xw, toprow, leftcol, nrows, ncols, force);
}
#else
#define ScrnUpdate2(xw, toprow, leftcol, nrows, ncols, force) \
	ScrnUpdate(xw, toprow, leftcol, nrows, ncols, force)
#endif

/*
 * scrolls the screen by amount lines, erases bottom, doesn't alter
 * cursor position (i.e. cursor moves down amount relative to text).
 * All done within the scrolling region, of course.
 * requires: amount > 0
 */
void
xtermScroll(XtermWidget xw, int amount)
{
    TScreen *screen = TScreenOf(xw);
    int i;
    int refreshtop = 0;
    int refreshheight;
    Boolean save_wrap = screen->do_wrap;
    int left = ScrnLeftMargin(xw);
    int right = ScrnRightMargin(xw);
    Boolean scroll_all_lines = (Boolean) (screen->scrollWidget
					  && !screen->whichBuf
					  && screen->top_marg == 0);
    Boolean scroll_full_line = ((left == 0) && (right == screen->max_col));

    TRACE(("xtermScroll count=%d (top %d, saved %d)\n", amount,
	   screen->topline, screen->savelines));

    screen->cursor_busy += 1;
    screen->cursor_moved = True;

    if (screen->cursor_state)
	HideCursor(xw);

    i = screen->bot_marg - screen->top_marg + 1;
    if (amount > i)
	amount = i;

    if (!scroll_full_line) {
	refreshheight = 0;
    } else
#if OPT_SCROLL_LOCK
	if ((screen->allowScrollLock && screen->scroll_lock)
	    || (screen->autoScrollLock && screen->topline < 0)) {
	refreshheight = 0;
	screen->scroll_amt = 0;
	screen->refresh_amt = 0;
	if (--(screen->topline) < -screen->savelines) {
	    screen->topline = -screen->savelines;
	    screen->scroll_dirty = True;
	}
	if (++(screen->savedlines) > screen->savelines) {
	    screen->savedlines = screen->savelines;
	}
    } else
#endif
    {
	if (ScrnHaveSelection(screen))
	    adjustHiliteOnFwdScroll(xw, amount, scroll_all_lines);

	if (screen->jumpscroll) {
	    if (screen->scroll_amt > 0) {
		if (!screen->fastscroll) {
		    if (screen->refresh_amt + amount > i)
			FlushScroll(xw);
		}
		screen->scroll_amt += amount;
		screen->refresh_amt += amount;
	    } else {
		if (!screen->fastscroll) {
		    if (screen->scroll_amt < 0)
			FlushScroll(xw);
		}
		screen->scroll_amt = amount;
		screen->refresh_amt = amount;
	    }
	    refreshheight = 0;
	} else {
	    int scrolltop;
	    int scrollheight;
	    int shift;
	    int bot;

	    ScrollSelection(screen, -(amount), False);
	    if (amount == i) {
		ClearScreen(xw);
		goto done;
	    }

	    shift = INX2ROW(screen, 0);
	    bot = screen->max_row - shift;
	    scrollheight = i - amount;
	    refreshheight = amount;

	    if ((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
		(i = screen->max_row - refreshheight + 1))
		refreshtop = i;

	    if (scroll_all_lines) {
		scrolltop = 0;
		if ((scrollheight += shift) > i)
		    scrollheight = i;
		IncrementSavedLines(amount);
	    } else {
		scrolltop = screen->top_marg + shift;
		if ((i = screen->bot_marg - bot) > 0) {
		    scrollheight -= i;
		    if ((i = screen->top_marg + amount - 1 - bot) >= 0) {
			refreshtop += i;
			refreshheight -= i;
		    }
		}
	    }

	    if (screen->multiscroll && amount == 1 &&
		screen->topline == 0 && screen->top_marg == 0 &&
		screen->bot_marg == screen->max_row) {
		if (screen->incopy < 0 && screen->scrolls == 0)
		    CopyWait(xw);
		screen->scrolls++;
	    }

	    vertical_copy_area(xw,
			       scrolltop + amount,
			       scrollheight,
			       amount,
			       left,
			       right);

	    if (refreshheight > 0) {
		ClearCurBackground(xw,
				   refreshtop,
				   left,
				   (unsigned) refreshheight,
				   (unsigned) (right + 1 - left),
				   (unsigned) FontWidth(screen));
		if (refreshheight > shift)
		    refreshheight = shift;
	    }
	}
    }

    if (amount > 0) {
	if (left > 0 || right < screen->max_col) {
	    scrollInMargins(xw, amount, screen->top_marg);
	    ScrnUpdate2(xw,
			screen->top_marg,
			left,
			screen->bot_marg + 1 - screen->top_marg,
			right + 1 - left,
			True);
	} else if (scroll_all_lines) {
	    ScrnDeleteLine(xw,
			   screen->saveBuf_index,
			   screen->bot_marg + screen->savelines,
			   0,
			   (unsigned) amount);
	} else {
	    ScrnDeleteLine(xw,
			   screen->visbuf,
			   screen->bot_marg,
			   screen->top_marg,
			   (unsigned) amount);
	}
    }

    scroll_displayed_graphics(xw, amount);

    if (refreshheight > 0) {
	ScrnRefresh(xw,
		    refreshtop,
		    left,
		    refreshheight,
		    right + 1 - left,
		    False);
    }

  done:
    screen->do_wrap = save_wrap;
    screen->cursor_busy -= 1;
    TRACE(("...xtermScroll count=%d (top %d, saved %d)\n", amount,
	   screen->topline, screen->savelines));
    return;
}

/*
 * This is from ISO 6429, not found in any of DEC's terminals.
 */
void
xtermScrollLR(XtermWidget xw, int amount, Bool toLeft)
{
    if (amount > 0) {
	xtermColScroll(xw, amount, toLeft, ScrnLeftMargin(xw));
    }
}

/*
 * Implement DECBI/DECFI (back/forward column index)
 */
void
xtermColIndex(XtermWidget xw, Bool toLeft)
{
    TScreen *screen = TScreenOf(xw);

    if (toLeft) {
	if (ScrnIsColInMargins(screen, screen->cur_col)) {
	    if (screen->cur_col == ScrnLeftMargin(xw)) {
		xtermColScroll(xw, 1, False, screen->cur_col);
	    } else {
		CursorBack(xw, 1);
	    }
	} else {
	    CursorBack(xw, 1);
	}
    } else {
	if (ScrnIsColInMargins(screen, screen->cur_col)) {
	    if (screen->cur_col == ScrnRightMargin(xw)) {
		xtermColScroll(xw, 1, True, ScrnLeftMargin(xw));
	    } else {
		CursorForward(xw, 1);
	    }
	} else {
	    CursorForward(xw, 1);
	}
    }
}

/*
 * Implement DECDC/DECIC (delete/insert column)
 */
void
xtermColScroll(XtermWidget xw, int amount, Bool toLeft, int at_col)
{
    TScreen *screen = TScreenOf(xw);

    if (amount > 0) {
	int min_row;
	int max_row;

	if (ScrnHaveRowMargins(screen)) {
	    min_row = screen->top_marg;
	    max_row = screen->bot_marg;
	} else {
	    min_row = 0;
	    max_row = screen->max_row;
	}

	if (screen->cur_row >= min_row
	    && screen->cur_row <= max_row
	    && screen->cur_col >= screen->lft_marg
	    && screen->cur_col <= screen->rgt_marg) {
	    int save_row = screen->cur_row;
	    int save_col = screen->cur_col;
	    int row;

	    screen->cur_col = at_col;
	    if (toLeft) {
		for (row = min_row; row <= max_row; row++) {
		    screen->cur_row = row;
		    ScrnDeleteChar(xw, (unsigned) amount);
		}
	    } else {
		for (row = min_row; row <= max_row; row++) {
		    screen->cur_row = row;
		    ScrnInsertChar(xw, (unsigned) amount);
		}
	    }
	    screen->cur_row = save_row;
	    screen->cur_col = save_col;
	    xtermRepaint(xw);
	}
    }
}

/*
 * Reverse scrolls the screen by amount lines, erases top, doesn't alter
 * cursor position (i.e. cursor moves up amount relative to text).
 * All done within the scrolling region, of course.
 * Requires: amount > 0
 */
void
RevScroll(XtermWidget xw, int amount)
{
    TScreen *screen = TScreenOf(xw);
    int i = screen->bot_marg - screen->top_marg + 1;
    int left = ScrnLeftMargin(xw);
    int right = ScrnRightMargin(xw);
    Boolean scroll_full_line = ((left == 0) && (right == screen->max_col));

    TRACE(("RevScroll count=%d\n", amount));

    screen->cursor_busy += 1;
    screen->cursor_moved = True;

    if (screen->cursor_state)
	HideCursor(xw);

    if (amount > i)
	amount = i;

    if (ScrnHaveSelection(screen))
	adjustHiliteOnBakScroll(xw, amount);

    if (!scroll_full_line) {
	;
    } else if (screen->jumpscroll) {
	if (screen->scroll_amt < 0) {
	    if (-screen->refresh_amt + amount > i)
		FlushScroll(xw);
	    screen->scroll_amt -= amount;
	    screen->refresh_amt -= amount;
	} else {
	    if (screen->scroll_amt > 0)
		FlushScroll(xw);
	    screen->scroll_amt = -amount;
	    screen->refresh_amt = -amount;
	}
    } else {
	int shift = INX2ROW(screen, 0);
	int bot = screen->max_row - shift;
	int refreshheight = amount;
	int refreshtop = screen->top_marg + shift;
	int scrollheight = (screen->bot_marg
			    - screen->top_marg - refreshheight + 1);
	int scrolltop = refreshtop + refreshheight;

	if ((i = screen->bot_marg - bot) > 0)
	    scrollheight -= i;
	if ((i = screen->top_marg + refreshheight - 1 - bot) > 0)
	    refreshheight -= i;

	if (screen->multiscroll && amount == 1 &&
	    screen->topline == 0 && screen->top_marg == 0 &&
	    screen->bot_marg == screen->max_row) {
	    if (screen->incopy < 0 && screen->scrolls == 0)
		CopyWait(xw);
	    screen->scrolls++;
	}

	vertical_copy_area(xw,
			   scrolltop - amount,
			   scrollheight,
			   -amount,
			   left,
			   right);

	if (refreshheight > 0) {
	    ClearCurBackground(xw,
			       refreshtop,
			       left,
			       (unsigned) refreshheight,
			       (unsigned) (right + 1 - left),
			       (unsigned) FontWidth(screen));
	}
    }
    if (amount > 0) {
	if (left > 0 || right < screen->max_col) {
	    scrollInMargins(xw, -amount, screen->top_marg);
	    ScrnUpdate2(xw,
			screen->top_marg,
			left,
			screen->bot_marg + 1 - screen->top_marg,
			right + 1 - left,
			True);
	} else {
	    ScrnInsertLine(xw,
			   screen->visbuf,
			   screen->bot_marg,
			   screen->top_marg,
			   (unsigned) amount);
	}
    }
    screen->cursor_busy -= 1;
    return;
}

#if OPT_ZICONBEEP
void
initZIconBeep(void)
{
    if (resource.zIconBeep > 100 || resource.zIconBeep < -100) {
	resource.zIconBeep = 0;	/* was 100, but I prefer to defaulting off. */
	xtermWarning("a number between -100 and 100 is required for zIconBeep.  0 used by default\n");
    }
}

static char *
getIconName(void)
{
    static char *icon_name;
    static Arg args[] =
    {
	{XtNiconName, (XtArgVal) & icon_name}
    };

    icon_name = NULL;
    XtGetValues(toplevel, args, XtNumber(args));
    return icon_name;
}

static void
setZIconBeep(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    /* Flag icon name with "***"  on window output when iconified.
     */
    if (resource.zIconBeep && mapstate == IsUnmapped && !screen->zIconBeep_flagged) {
	char *icon_name = getIconName();
	if (icon_name != NULL) {
	    screen->zIconBeep_flagged = True;
	    ChangeIconName(xw, icon_name);
	}
	xtermBell(xw, XkbBI_Info, 0);
    }
    mapstate = -1;
}

/*
 * If warning should be given then give it
 */
Boolean
showZIconBeep(XtermWidget xw, const char *name)
{
    Boolean code = False;

    if (name == NULL)
	name = "";

    if (resource.zIconBeep && TScreenOf(xw)->zIconBeep_flagged) {
	char *format = resource.zIconFormat;
	char *newname = malloc(strlen(name) + strlen(format) + 2);
	if (!newname) {
	    xtermWarning("malloc failed in showZIconBeep\n");
	} else {
	    char *marker = strstr(format, "%s");
	    char *result = newname;
	    if (marker != NULL) {
		size_t skip = (size_t) (marker - format);
		if (skip) {
		    strncpy(result, format, skip);
		    result += skip;
		}
		strcpy(result, name);
		strcat(result, marker + 2);
	    } else {
		strcpy(result, format);
		strcat(result, name);
	    }
	    ChangeGroup(xw, XtNiconName, newname);
	    free(newname);
	}
	code = True;
    }
    return code;
}

/*
 * Restore the icon name, resetting the state for zIconBeep.
 */
void
resetZIconBeep(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    if (screen->zIconBeep_flagged) {
	char *icon_name = getIconName();
	screen->zIconBeep_flagged = False;
	if (icon_name != NULL) {
	    char *buf = malloc(strlen(icon_name) + 1);
	    if (buf == NULL) {
		screen->zIconBeep_flagged = True;
	    } else {
		char *format = resource.zIconFormat;
		char *marker = strstr(format, "%s");
		Boolean found = False;

		if (marker != NULL) {
		    if (marker == format
			|| !strncmp(icon_name, format, (size_t) (marker - format))) {
			found = True;
			strcpy(buf, icon_name + (marker - format));
			marker += 2;
			if (*marker != '\0') {
			    size_t len_m = strlen(marker);
			    size_t len_b = strlen(buf);
			    if (len_m < len_b
				&& !strcmp(buf + len_b - len_m, marker)) {
				buf[len_b - len_m] = '\0';
			    }
			}
		    }
		} else if (!strncmp(icon_name, format, strlen(format))) {
		    strcpy(buf, icon_name + strlen(format));
		    found = True;
		}
		if (found)
		    ChangeIconName(xw, buf);
		free(buf);
	    }
	}
    }
}
#else
#define setZIconBeep(xw)	/* nothing */
#endif /* OPT_ZICONBEEP */

/*
 * Write a string onto the screen at the current cursor position.
 * Update cursor position.
 */
void
WriteText(XtermWidget xw, Cardinal offset, Cardinal length)
{
    IChar *str = xw->work.write_text + offset;
    TScreen *screen = TScreenOf(xw);
    XTermDraw params;
    CLineData *ld = NULL;
    unsigned attr_flags = xw->flags;
    CellColor fg_bg = xtermColorPair(xw);
    unsigned cells = visual_width(str, length);
    GC currentGC;

    TRACE(("WriteText %d (%2d,%2d) %3d:%s\n",
	   screen->topline,
	   screen->cur_row,
	   screen->cur_col,
	   length, visibleIChars(str, length)));

    if (cells + (unsigned) screen->cur_col > (unsigned) MaxCols(screen)) {
	cells = (unsigned) (MaxCols(screen) - screen->cur_col);
    }

    if (screen->cur_row <= screen->max_row
	&& ScrnHaveSelection(screen)
	&& ScrnIsRowInSelection(screen, INX2ROW(screen, screen->cur_row))) {
	ScrnDisownSelection(xw);
    }
#if OPT_ISO_COLORS
    /* if colorBDMode is set, and enabled */
    if (screen->colorBDMode &&
	screen->boldColors &&
	!hasDirectFG(attr_flags) &&
    /* and bold foreground color on bold background color */
	GetCellColorFG(fg_bg) > COLOR_7 &&
	GetCellColorFG(fg_bg) < MIN_ANSI_COLORS &&
    /* and both colors are the same */
	GetCellColorFG(fg_bg) == GetCellColorBG(fg_bg))
	/* clear BOLD flag, else it will be colorBD on bold background color */
	UIntClr(attr_flags, BOLD);
#endif

    /* if we are in insert-mode, reserve space for the new cells */
    if (attr_flags & INSERT) {
	InsertChar(xw, cells);
    }

    if (AddToVisible(xw)
	&& ((ld = getLineData(screen, screen->cur_row))) != NULL) {
	unsigned test;

	if (screen->cursor_state)
	    HideCursor(xw);

	/*
	 * If we overwrite part of a multi-column character, fill the rest
	 * of it with blanks.
	 */
	if_OPT_WIDE_CHARS(screen, {
	    int kl;
	    int kr;
	    if (DamagedCurCells(screen, cells, &kl, &kr))
		ClearInLine(xw, screen->cur_row, kl, (unsigned) (kr - kl + 1));
	});

	TRACE(("WriteText calling drawXtermText (%d) (%d,%d)\n",
	       LineCharSet(screen, ld),
	       screen->cur_row,
	       screen->cur_col));

	test = attr_flags;
#if OPT_ISO_COLORS
	{
	    int fg;
	    if (screen->colorAttrMode) {
		fg = MapToColorMode(xw->cur_foreground, screen, attr_flags);
	    } else {
		fg = xw->cur_foreground;
	    }
	    checkVeryBoldColors(test, fg);
	}
#endif

	/* make sure that the correct GC is current */
	currentGC = updatedXtermGC(xw, attr_flags, fg_bg, False);

	/* *INDENT-EQLS* */
	params.xw          = xw;
	params.attr_flags  = (test & DRAWX_MASK);
	params.draw_flags  = 0;
	params.this_chrset = LineCharSet(screen, ld);
	params.real_chrset = CSET_SWL;
	params.on_wide     = 0;

	drawXtermText(¶ms,
		      currentGC,
		      LineCursorX(screen, ld, screen->cur_col),
		      CursorY(screen, screen->cur_row),
		      str, length);

	resetXtermGC(xw, attr_flags, False);
    }

    ScrnWriteText(xw, offset, length, attr_flags, fg_bg);
    CursorForward(xw, (int) cells);

    if (screen->cur_row <= screen->max_row) {
	setZIconBeep(xw);
    }
    return;
}

/*
 * If cursor not in scrolling region, returns.  Else,
 * inserts n blank lines at the cursor's position.  Lines above the
 * bottom margin are lost.
 */
void
InsertLine(XtermWidget xw, int n)
{
    TScreen *screen = TScreenOf(xw);
    int i;
    int left = ScrnLeftMargin(xw);
    int right = ScrnRightMargin(xw);
    Boolean scroll_full_line = ((left == 0) && (right == screen->max_col));

    if (!ScrnIsRowInMargins(screen, screen->cur_row)
	|| screen->cur_col < left
	|| screen->cur_col > right)
	return;

    TRACE(("InsertLine count=%d\n", n));

    set_cur_col(screen, ScrnLeftMargin(xw));
    if (screen->cursor_state)
	HideCursor(xw);

    if (ScrnHaveSelection(screen)
	&& ScrnAreRowsInSelection(screen,
				  INX2ROW(screen, screen->top_marg),
				  INX2ROW(screen, screen->cur_row - 1))
	&& ScrnAreRowsInSelection(screen,
				  INX2ROW(screen, screen->cur_row),
				  INX2ROW(screen, screen->bot_marg))) {
	ScrnDisownSelection(xw);
    }

    ResetWrap(screen);
    if (n > (i = screen->bot_marg - screen->cur_row + 1))
	n = i;
    if (screen->jumpscroll && scroll_full_line) {
	if (screen->scroll_amt <= 0 &&
	    screen->cur_row <= -screen->refresh_amt) {
	    if (-screen->refresh_amt + n > MaxRows(screen))
		FlushScroll(xw);
	    screen->scroll_amt -= n;
	    screen->refresh_amt -= n;
	} else {
	    if (screen->scroll_amt)
		FlushScroll(xw);
	}
    }
    if (!screen->scroll_amt && scroll_full_line) {
	int shift = INX2ROW(screen, 0);
	int bot = screen->max_row - shift;
	int refreshheight = n;
	int refreshtop = screen->cur_row + shift;
	int scrolltop = refreshtop + refreshheight;
	int scrollheight = (screen->bot_marg
			    - screen->cur_row - refreshheight + 1);

	if ((i = screen->bot_marg - bot) > 0)
	    scrollheight -= i;
	if ((i = screen->cur_row + refreshheight - 1 - bot) > 0)
	    refreshheight -= i;
	vertical_copy_area(xw, scrolltop - n, scrollheight, -n, left, right);
	if (refreshheight > 0) {
	    ClearCurBackground(xw,
			       refreshtop,
			       left,
			       (unsigned) refreshheight,
			       (unsigned) (right + 1 - left),
			       (unsigned) FontWidth(screen));
	}
    }
    if (n > 0) {
	if (scroll_full_line) {
	    ScrnInsertLine(xw,
			   screen->visbuf,
			   screen->bot_marg,
			   screen->cur_row,
			   (unsigned) n);
	} else {
	    scrollInMargins(xw, -n, screen->cur_row);
	    ScrnUpdate2(xw,
			screen->cur_row,
			left,
			screen->bot_marg + 1 - screen->cur_row,
			right + 1 - left,
			True);
	}
    }
}

/*
 * If cursor not in scrolling region, returns.  Else, deletes n lines
 * at the cursor's position, lines added at bottom margin are blank.
 */
void
DeleteLine(XtermWidget xw, int n, Bool canSave)
{
    TScreen *screen = TScreenOf(xw);
    int i;
    int left = ScrnLeftMargin(xw);
    int right = ScrnRightMargin(xw);
    Boolean scroll_all_lines = (Boolean) (screen->scrollWidget
					  && !screen->whichBuf
					  && screen->cur_row == 0);
    Boolean scroll_full_line = ((left == 0) && (right == screen->max_col));

    if (!ScrnIsRowInMargins(screen, screen->cur_row) ||
	!ScrnIsColInMargins(screen, screen->cur_col))
	return;

    TRACE(("DeleteLine count=%d\n", n));

    set_cur_col(screen, ScrnLeftMargin(xw));
    if (screen->cursor_state)
	HideCursor(xw);

    if (n > (i = screen->bot_marg - screen->cur_row + 1)) {
	n = i;
    }
    if (ScrnHaveSelection(screen)
	&& ScrnAreRowsInSelection(screen,
				  INX2ROW(screen, screen->cur_row),
				  INX2ROW(screen, screen->cur_row + n - 1))) {
	ScrnDisownSelection(xw);
    }

    ResetWrap(screen);
    if (screen->jumpscroll && scroll_full_line) {
	if (screen->scroll_amt >= 0 && screen->cur_row == screen->top_marg) {
	    if (screen->refresh_amt + n > MaxRows(screen))
		FlushScroll(xw);
	    if (canSave) {
		screen->scroll_amt += n;
		screen->refresh_amt += n;
	    }
	} else {
	    if (screen->scroll_amt)
		FlushScroll(xw);
	}
    }

    /* adjust screen->buf */
    if (n > 0) {
	if (left > 0 || right < screen->max_col) {
	    scrollInMargins(xw, n, screen->cur_row);
	} else if (canSave && scroll_all_lines) {
	    ScrnDeleteLine(xw,
			   screen->saveBuf_index,
			   screen->bot_marg + screen->savelines,
			   0,
			   (unsigned) n);
	} else {
	    ScrnDeleteLine(xw,
			   screen->visbuf,
			   screen->bot_marg,
			   screen->cur_row,
			   (unsigned) n);
	}
    }

    /* repaint the screen, as needed */
    if (!scroll_full_line) {
	ScrnUpdate2(xw,
		    screen->cur_row,
		    left,
		    screen->bot_marg + 1 - screen->cur_row,
		    right + 1 - left,
		    True);
    } else if (!screen->scroll_amt) {
	int shift = INX2ROW(screen, 0);
	int bot = screen->max_row - shift;
	int refreshtop;
	int refreshheight = n;
	int scrolltop;
	int scrollheight = i - n;

	if ((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
	    (i = screen->max_row - refreshheight + 1))
	    refreshtop = i;
	if (canSave && scroll_all_lines) {
	    scrolltop = 0;
	    if ((scrollheight += shift) > i)
		scrollheight = i;
	    IncrementSavedLines(n);
	} else {
	    scrolltop = screen->cur_row + shift;
	    if ((i = screen->bot_marg - bot) > 0) {
		scrollheight -= i;
		if ((i = screen->cur_row + n - 1 - bot) >= 0) {
		    refreshheight -= i;
		}
	    }
	}
	vertical_copy_area(xw, scrolltop + n, scrollheight, n, left, right);
	if (shift > 0 && refreshheight > 0) {
	    int rows = refreshheight;
	    if (rows > shift)
		rows = shift;
	    ScrnUpdate(xw, refreshtop, 0, rows, MaxCols(screen), True);
	    refreshtop += shift;
	    refreshheight -= shift;
	}
	if (refreshheight > 0) {
	    ClearCurBackground(xw,
			       refreshtop,
			       left,
			       (unsigned) refreshheight,
			       (unsigned) (right + 1 - left),
			       (unsigned) FontWidth(screen));
	}
    }
}

/*
 * Insert n blanks at the cursor's position, no wraparound
 */
void
InsertChar(XtermWidget xw, unsigned n)
{
    TScreen *screen = TScreenOf(xw);
    CLineData *ld;
    unsigned limit;
    int row = INX2ROW(screen, screen->cur_row);
    int left = ScrnLeftMargin(xw);
    int right = ScrnRightMargin(xw);

    if (screen->cursor_state)
	HideCursor(xw);

    TRACE(("InsertChar count=%d\n", n));

    if (ScrnHaveSelection(screen)
	&& ScrnIsRowInSelection(screen, row)) {
	ScrnDisownSelection(xw);
    }
    ResetWrap(screen);

    limit = (unsigned) (right + 1 - screen->cur_col);

    if (n > limit)
	n = limit;

    if (screen->cur_col < left || screen->cur_col > right) {
	n = 0;
    } else if (AddToVisible(xw)
	       && (ld = getLineData(screen, screen->cur_row)) != NULL) {
	int col = right + 1 - (int) n;

	/*
	 * If we shift part of a multi-column character, fill the rest
	 * of it with blanks.  Do similar repair for the text which will
	 * be shifted into the right-margin.
	 */
	if_OPT_WIDE_CHARS(screen, {
	    int kl;
	    int kr = screen->cur_col;
	    if (DamagedCurCells(screen, n, &kl, (int *) 0) && kr > kl) {
		ClearInLine(xw, screen->cur_row, kl, (unsigned) (kr - kl + 1));
	    }
	    kr = screen->max_col - (int) n + 1;
	    if (DamagedCells(screen, n, &kl, (int *) 0,
			     screen->cur_row,
			     kr) && kr > kl) {
		ClearInLine(xw, screen->cur_row, kl, (unsigned) (kr - kl + 1));
	    }
	});

#if OPT_DEC_CHRSET
	if (CSET_DOUBLE(GetLineDblCS(ld))) {
	    col = MaxCols(screen) / 2 - (int) n;
	}
#endif
	/*
	 * prevent InsertChar from shifting the end of a line over
	 * if it is being appended to
	 */
	if (non_blank_line(screen, screen->cur_row,
			   screen->cur_col, MaxCols(screen))) {
	    horizontal_copy_area(xw, screen->cur_col,
				 col - screen->cur_col,
				 (int) n);
	}

	ClearCurBackground(xw,
			   INX2ROW(screen, screen->cur_row),
			   screen->cur_col,
			   1U,
			   n,
			   (unsigned) LineFontWidth(screen, ld));
    }
    if (n != 0) {
	/* adjust screen->buf */
	ScrnInsertChar(xw, n);
    }
}

/*
 * Deletes n chars at the cursor's position, no wraparound.
 */
void
DeleteChar(XtermWidget xw, unsigned n)
{
    TScreen *screen = TScreenOf(xw);
    CLineData *ld;
    unsigned limit;
    int row = INX2ROW(screen, screen->cur_row);
    int right = ScrnRightMargin(xw);

    if (screen->cursor_state)
	HideCursor(xw);

    if (!ScrnIsColInMargins(screen, screen->cur_col))
	return;

    TRACE(("DeleteChar count=%d\n", n));

    if (ScrnHaveSelection(screen)
	&& ScrnIsRowInSelection(screen, row)) {
	ScrnDisownSelection(xw);
    }
    ResetWrap(screen);

    limit = (unsigned) (right + 1 - screen->cur_col);

    if (n > limit)
	n = limit;

    if (AddToVisible(xw)
	&& (ld = getLineData(screen, screen->cur_row)) != NULL) {
	int col = right + 1 - (int) n;

	/*
	 * If we delete part of a multi-column character, fill the rest
	 * of it with blanks.
	 */
	if_OPT_WIDE_CHARS(screen, {
	    int kl;
	    int kr;
	    if (DamagedCurCells(screen, n, &kl, &kr))
		ClearInLine(xw, screen->cur_row, kl, (unsigned) (kr - kl + 1));
	});

#if OPT_DEC_CHRSET
	if (CSET_DOUBLE(GetLineDblCS(ld))) {
	    col = MaxCols(screen) / 2 - (int) n;
	}
#endif
	horizontal_copy_area(xw,
			     (screen->cur_col + (int) n),
			     col - screen->cur_col,
			     -((int) n));

	ClearCurBackground(xw,
			   INX2ROW(screen, screen->cur_row),
			   col,
			   1U,
			   n,
			   (unsigned) LineFontWidth(screen, ld));
    }
    if (n != 0) {
	/* adjust screen->buf */
	ScrnDeleteChar(xw, n);
    }
}

/*
 * Clear from cursor position to beginning of display, inclusive.
 */
static void
ClearAbove(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    if (screen->protected_mode != OFF_PROTECT) {
	int row;
	unsigned len = (unsigned) MaxCols(screen);

	assert(screen->max_col >= 0);
	for (row = 0; row < screen->cur_row; row++)
	    ClearInLine(xw, row, 0, len);
	ClearInLine(xw, screen->cur_row, 0, (unsigned) screen->cur_col);
    } else {
	int top;

	if (screen->cursor_state)
	    HideCursor(xw);
	if ((top = INX2ROW(screen, 0)) <= screen->max_row) {
	    int height;

	    if (screen->scroll_amt)
		FlushScroll(xw);
	    if ((height = screen->cur_row + top) > screen->max_row)
		height = screen->max_row + 1;
	    if ((height -= top) > 0) {
		chararea_clear_displayed_graphics(screen,
						  0,
						  top,
						  MaxCols(screen),
						  height);

		ClearCurBackground(xw,
				   top,
				   0,
				   (unsigned) height,
				   (unsigned) MaxCols(screen),
				   (unsigned) FontWidth(screen));
	    }
	}
	ClearBufRows(xw, 0, screen->cur_row - 1);
    }

    ClearLeft(xw);
}

/*
 * Clear from cursor position to end of display, inclusive.
 */
static void
ClearBelow(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    ClearRight(xw, -1);

    if (screen->protected_mode != OFF_PROTECT) {
	int row;
	unsigned len = (unsigned) MaxCols(screen);

	assert(screen->max_col >= 0);
	for (row = screen->cur_row + 1; row <= screen->max_row; row++)
	    ClearInLine(xw, row, 0, len);
    } else {
	int top;

	if ((top = INX2ROW(screen, screen->cur_row)) <= screen->max_row) {
	    if (screen->scroll_amt)
		FlushScroll(xw);
	    if (++top <= screen->max_row) {
		chararea_clear_displayed_graphics(screen,
						  0,
						  top,
						  MaxCols(screen),
						  (screen->max_row - top + 1));
		ClearCurBackground(xw,
				   top,
				   0,
				   (unsigned) (screen->max_row - top + 1),
				   (unsigned) MaxCols(screen),
				   (unsigned) FontWidth(screen));
	    }
	}
	ClearBufRows(xw, screen->cur_row + 1, screen->max_row);
    }
}

/*
 * Clear the given row, for the given range of columns, returning 1 if no
 * protected characters were found, 0 otherwise.
 */
static int
ClearInLine2(XtermWidget xw, int flags, int row, int col, unsigned len)
{
    TScreen *screen = TScreenOf(xw);
    CLineData *ld;
    int rc = 1;

    TRACE(("ClearInLine(row=%d, col=%d, len=%d) vs %d..%d\n",
	   row, col, len,
	   screen->startH.row,
	   screen->startH.col));

    if (ScrnHaveSelection(screen)
	&& ScrnIsRowInSelection(screen, row)) {
	ScrnDisownSelection(xw);
    }

    if (col + (int) len >= MaxCols(screen)) {
	len = (unsigned) (MaxCols(screen) - col);
    }

    /* If we've marked protected text on the screen, we'll have to
     * check each time we do an erase.
     */
    if (screen->protected_mode != OFF_PROTECT) {
	unsigned n;
	IAttr *attrs = getLineData(screen, row)->attribs + col;
	int saved_mode = screen->protected_mode;
	Bool done;

	/* disable this branch during recursion */
	screen->protected_mode = OFF_PROTECT;

	do {
	    done = True;
	    for (n = 0; n < len; n++) {
		if (attrs[n] & PROTECTED) {
		    rc = 0;	/* found a protected segment */
		    if (n != 0) {
			ClearInLine(xw, row, col, n);
		    }
		    while ((n < len)
			   && (attrs[n] & PROTECTED)) {
			n++;
		    }
		    done = False;
		    break;
		}
	    }
	    /* setup for another segment, past the protected text */
	    if (!done) {
		attrs += n;
		col += (int) n;
		len -= n;
	    }
	} while (!done);

	screen->protected_mode = saved_mode;
	if ((int) len <= 0) {
	    return 0;
	}
    }
    /* fall through to the final non-protected segment */

    if (screen->cursor_state)
	HideCursor(xw);
    ResetWrap(screen);

    if (AddToVisible(xw)
	&& (ld = getLineData(screen, row)) != NULL) {

	ClearCurBackground(xw,
			   INX2ROW(screen, row),
			   col,
			   1U,
			   len,
			   (unsigned) LineFontWidth(screen, ld));
    }

    if (len != 0) {
	ClearCells(xw, flags, len, row, col);
    }

    return rc;
}

int
ClearInLine(XtermWidget xw, int row, int col, unsigned len)
{
    TScreen *screen = TScreenOf(xw);
    int flags = 0;

    /*
     * If we're clearing to the end of the line, we won't count this as
     * "drawn" characters.  We'll only do cut/paste on "drawn" characters,
     * so this has the effect of suppressing trailing blanks from a
     * selection.
     */
    if (col + (int) len < MaxCols(screen)) {
	flags |= CHARDRAWN;
    }
    return ClearInLine2(xw, flags, row, col, len);
}

/*
 * Clear the next n characters on the cursor's line, including the cursor's
 * position.
 */
void
ClearRight(XtermWidget xw, int n)
{
    TScreen *screen = TScreenOf(xw);
    LineData *ld;
    unsigned len = (unsigned) (MaxCols(screen) - screen->cur_col);

    assert(screen->max_col >= 0);
    assert(screen->max_col >= screen->cur_col);

    if (n < 0)			/* the remainder of the line */
	n = MaxCols(screen);
    if (n == 0)			/* default for 'ECH' */
	n = 1;

    if (len > (unsigned) n)
	len = (unsigned) n;

    ld = getLineData(screen, screen->cur_row);
    if (AddToVisible(xw)) {
	if_OPT_WIDE_CHARS(screen, {
	    int col = screen->cur_col;
	    int row = screen->cur_row;
	    int kl;
	    int kr;
	    if (DamagedCurCells(screen, len, &kl, &kr) && kr >= kl) {
		int xx = col;
		if (kl < xx) {
		    ClearInLine2(xw, 0, row, kl, (unsigned) (xx - kl));
		}
		xx = col + (int) len - 1;
		if (kr > xx) {
		    ClearInLine2(xw, 0, row, xx + 1, (unsigned) (kr - xx));
		}
	    }
	});
	(void) ClearInLine(xw, screen->cur_row, screen->cur_col, len);
    } else {
	ScrnClearCells(xw, screen->cur_row, screen->cur_col, len);
    }

    /* with the right part cleared, we can't be wrapping */
    LineClrWrapped(ld);
    ShowWrapMarks(xw, screen->cur_row, ld);
    ResetWrap(screen);
}

/*
 * Clear first part of cursor's line, inclusive.
 */
static void
ClearLeft(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    unsigned len = (unsigned) screen->cur_col + 1;

    assert(screen->cur_col >= 0);
    if (AddToVisible(xw)) {
	if_OPT_WIDE_CHARS(screen, {
	    int row = screen->cur_row;
	    int kl;
	    int kr;
	    if (DamagedCurCells(screen, 1, &kl, &kr) && kr >= kl) {
		ClearInLine2(xw, 0, row, kl, (unsigned) (kr - kl + 1));
	    }
	});
	(void) ClearInLine(xw, screen->cur_row, 0, len);
    } else {
	ScrnClearCells(xw, screen->cur_row, 0, len);
    }
}

/*
 * Erase the cursor's line.
 */
void
ClearLine(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    unsigned len = (unsigned) MaxCols(screen);

    assert(screen->max_col >= 0);
    (void) ClearInLine(xw, screen->cur_row, 0, len);
}

void
ClearScreen(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    int top;

    TRACE(("ClearScreen\n"));

    if (screen->cursor_state)
	HideCursor(xw);

    ScrnDisownSelection(xw);
    ResetWrap(screen);
    if ((top = INX2ROW(screen, 0)) <= screen->max_row) {
	if (screen->scroll_amt)
	    FlushScroll(xw);
	chararea_clear_displayed_graphics(screen,
					  0,
					  top,
					  MaxCols(screen),
					  (screen->max_row - top + 1));
	ClearCurBackground(xw,
			   top,
			   0,
			   (unsigned) (screen->max_row - top + 1),
			   (unsigned) MaxCols(screen),
			   (unsigned) FontWidth(screen));
    }
    ClearBufRows(xw, 0, screen->max_row);
}

/*
 * If we've written protected text DEC-style, and are issuing a non-DEC
 * erase, temporarily reset the protected_mode flag so that the erase will
 * ignore the protected flags.
 */
void
do_erase_char(XtermWidget xw, int param, int mode)
{
    TScreen *screen = TScreenOf(xw);
    int saved_mode = screen->protected_mode;

    if (saved_mode == DEC_PROTECT
	&& saved_mode != mode) {
	screen->protected_mode = OFF_PROTECT;
    }

    ClearRight(xw, param);
    screen->protected_mode = saved_mode;
}

void
do_erase_line(XtermWidget xw, int param, int mode)
{
    TScreen *screen = TScreenOf(xw);
    int saved_mode = screen->protected_mode;

    if (saved_mode == DEC_PROTECT
	&& saved_mode != mode) {
	screen->protected_mode = OFF_PROTECT;
    }

    switch (param) {
    case -1:			/* DEFAULT */
    case 0:
	ClearRight(xw, -1);
	break;
    case 1:
	ClearLeft(xw);
	break;
    case 2:
	ClearLine(xw);
	break;
    }
    screen->protected_mode = saved_mode;
}

/*
 * Just like 'do_erase_line()', except that this intercepts ED controls.  If we
 * clear the whole screen, we'll get the return-value from ClearInLine, and
 * find if there were any protected characters left.  If not, reset the
 * protected mode flag in the screen data (it's slower).
 */
void
do_erase_display(XtermWidget xw, int param, int mode)
{
    TScreen *screen = TScreenOf(xw);
    int saved_mode = screen->protected_mode;

    if (saved_mode == DEC_PROTECT
	&& saved_mode != mode)
	screen->protected_mode = OFF_PROTECT;

    switch (param) {
    case -1:			/* DEFAULT */
    case 0:
	if (screen->cur_row == 0
	    && screen->cur_col == 0) {
	    screen->protected_mode = saved_mode;
	    do_erase_display(xw, 2, mode);
	    saved_mode = screen->protected_mode;
	} else
	    ClearBelow(xw);
	break;

    case 1:
	if (screen->cur_row == screen->max_row
	    && screen->cur_col == screen->max_col) {
	    screen->protected_mode = saved_mode;
	    do_erase_display(xw, 2, mode);
	    saved_mode = screen->protected_mode;
	} else
	    ClearAbove(xw);
	break;

    case 2:
	/*
	 * We use 'ClearScreen()' throughout the remainder of the
	 * program for places where we don't care if the characters are
	 * protected or not.  So we modify the logic around this call
	 * on 'ClearScreen()' to handle protected characters.
	 */
	if (screen->protected_mode != OFF_PROTECT) {
	    int row;
	    int rc = 1;
	    unsigned len = (unsigned) MaxCols(screen);

	    assert(screen->max_col >= 0);
	    for (row = 0; row <= screen->max_row; row++)
		rc &= ClearInLine(xw, row, 0, len);
	    if (rc != 0)
		saved_mode = OFF_PROTECT;
	} else {
	    ClearScreen(xw);
	}
	break;

    case 3:
	/* xterm addition - erase saved lines. */
	if (screen->eraseSavedLines) {
	    screen->savedlines = 0;
	    ScrollBarDrawThumb(xw, 1);
	}
	break;
    }
    screen->protected_mode = saved_mode;
}

static Boolean
row_has_data(TScreen *screen, int row)
{
    Boolean result = False;
    CLineData *ld;

    if ((ld = getLineData(screen, row)) != NULL) {
	int col;

	for (col = 0; col < screen->max_col; ++col) {
	    if (ld->attribs[col] & CHARDRAWN && ld->charData[col] != ' ') {
		result = True;
		break;
	    }
	}
    }
    return result;
}

static Boolean
screen_has_data(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    Boolean result = False;
    int row;

    for (row = 0; row < screen->max_row; ++row) {
	if (row_has_data(screen, row)) {
	    result = True;
	    break;
	}
    }
    return result;
}

static void
do_extra_scroll(XtermWidget xw, Bool trimmed)
{
    TScreen *screen = TScreenOf(xw);

    if (screen_has_data(xw)) {
	TRACE(("do_extra_scroll buffer=%d, trimmed=%s\n", screen->whichBuf,
	       BtoS(trimmed)));
	if (trimmed) {
	    int row;
	    Boolean hadData = (Boolean) ((screen->saved_fifo > 0)
					 ? row_has_data(screen, -1)
					 : False);

	    for (row = 0; row < screen->max_row; ++row) {
		Boolean hasData = row_has_data(screen, row);
		if (hasData || hadData) {
		    LineData *dst = addScrollback(screen);
		    LineData *src = getLineData(screen, row);
		    copyLineData(dst, src);
		    IncrementSavedLines(1);
		}
		hadData = hasData;
	    }
	} else {
	    xtermScroll(xw, screen->max_row);
	    FlushScroll(xw);
	}
	xtermRepaint(xw);
    }
}

/*
 * Like tiXtraScroll, perform a scroll up of the page contents.
 *
 * In this case, it happens for the special case when erasing the whole
 * display, e.g., an erase-below starting from the upper-left corner of the
 * screen, or if the erasure applies to the whole screen.
 */
void
do_cd_xtra_scroll(XtermWidget xw, int param)
{
    TScreen *screen = TScreenOf(xw);

    TRACE(("do_cd_xtra_scroll param %d, @%d,%d vs %d,%d\n", param,
	   screen->cur_row,
	   screen->cur_col,
	   ScrnTopMargin(xw),
	   ScrnLeftMargin(xw)));
    if (xw->misc.cdXtraScroll
	&& (param == 2 ||
	    (param == 0
	     && screen->cur_col <= ScrnLeftMargin(xw)
	     && screen->cur_row <= ScrnTopMargin(xw)))) {
	do_extra_scroll(xw, (xw->misc.cdXtraScroll == edTrim));
    }
}

/*
 * Scroll the page up (saving it).  This is called when doing terminal
 * initialization (ti) or exiting from that (te).
 */
void
do_ti_xtra_scroll(XtermWidget xw)
{
    if (xw->misc.tiXtraScroll) {
	do_extra_scroll(xw, False);
    }
}

static void
CopyWait(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    XEvent reply;
    XEvent *rep = &reply;
#ifndef NO_ACTIVE_ICON
    int retries = 0;
#endif

#if USE_DOUBLE_BUFFER
    if (resource.buffered)
	return;
#endif

    for (;;) {
#ifndef NO_ACTIVE_ICON
	if (xw->work.active_icon != eiFalse) {
	    /*
	     * The XWindowEvent call blocks until an event is available.  That
	     * can hang when using active-icon and iconifying/deiconifying
	     * while the terminal is receiving lots of output.  Checking with
	     * this call on the other hand may lose exposure events which
	     * arrive too late.  As a compromise, try several times with a
	     * time-delay before assuming no more events are available.
	     */
	    if (XCheckWindowEvent(screen->display,
				  VWindow(screen),
				  ExposureMask,
				  &reply)) {
		retries = 0;
	    } else {
		if (++retries >= 1000)
		    return;
		usleep(100U);	/* wait 0.1msec */
		continue;
	    }
	} else
#endif
	    XWindowEvent(screen->display, VWindow(screen), ExposureMask, &reply);
	switch (reply.type) {
	case Expose:
	    HandleExposure(xw, &reply);
	    break;
	case NoExpose:
	case GraphicsExpose:
	    if (screen->incopy <= 0) {
		screen->incopy = 1;
		if (screen->scrolls > 0)
		    screen->scrolls--;
	    }
	    if (reply.type == GraphicsExpose)
		HandleExposure(xw, &reply);

	    if ((reply.type == NoExpose) ||
		((XExposeEvent *) rep)->count == 0) {
		if (screen->incopy <= 0 && screen->scrolls > 0)
		    screen->scrolls--;
		if (screen->scrolls == 0) {
		    screen->incopy = 0;
		    return;
		}
		screen->incopy = -1;
	    }
	    break;
	}
    }
}

/*
 * used by vertical_copy_area and and horizontal_copy_area
 */
static void
copy_area(XtermWidget xw,
	  int src_x,
	  int src_y,
	  unsigned width,
	  unsigned height,
	  int dest_x,
	  int dest_y)
{
    TScreen *screen = TScreenOf(xw);

    if (width != 0 && height != 0) {
	/* wait for previous CopyArea to complete unless
	   multiscroll is enabled and active */
	if (screen->incopy && screen->scrolls == 0)
	    CopyWait(xw);
	screen->incopy = -1;

	/* save for translating Expose events */
	screen->copy_src_x = src_x;
	screen->copy_src_y = src_y;
	screen->copy_width = width;
	screen->copy_height = height;
	screen->copy_dest_x = dest_x;
	screen->copy_dest_y = dest_y;

	XCopyArea(screen->display,
		  VDrawable(screen), VDrawable(screen),
		  NormalGC(xw, screen),
		  src_x, src_y, width, height, dest_x, dest_y);
    }
}

/*
 * use when inserting or deleting characters on the current line
 */
static void
horizontal_copy_area(XtermWidget xw,
		     int firstchar,	/* char pos on screen to start copying at */
		     int nchars,
		     int amount)	/* number of characters to move right */
{
    TScreen *screen = TScreenOf(xw);
    CLineData *ld;

    if ((ld = getLineData(screen, screen->cur_row)) != NULL) {
	int src_x = LineCursorX(screen, ld, firstchar);
	int src_y = CursorY(screen, screen->cur_row);

	copy_area(xw, src_x, src_y,
		  (unsigned) (nchars * LineFontWidth(screen, ld)),
		  (unsigned) FontHeight(screen),
		  src_x + amount * LineFontWidth(screen, ld), src_y);
    }
}

/*
 * use when inserting or deleting lines from the screen
 */
static void
vertical_copy_area(XtermWidget xw,
		   int firstline,	/* line on screen to start copying at */
		   int nlines,
		   int amount,	/* number of lines to move up (neg=down) */
		   int left,
		   int right)
{
    TScreen *screen = TScreenOf(xw);

    TRACE(("vertical_copy_area - firstline=%d nlines=%d left=%d right=%d amount=%d\n",
	   firstline, nlines, left, right, amount));

    if (nlines > 0) {
	int src_x = CursorX(screen, left);
	int src_y = firstline * FontHeight(screen) + screen->border;
	unsigned int w = (unsigned) ((right + 1 - left) * FontWidth(screen));
	unsigned int h = (unsigned) (nlines * FontHeight(screen));
	int dst_x = src_x;
	int dst_y = src_y - amount * FontHeight(screen);

	copy_area(xw, src_x, src_y, w, h, dst_x, dst_y);

	if (screen->show_wrap_marks) {
	    int row;
	    int first = firstline - amount;
	    int last = firstline + nlines + amount;

	    for (row = first; row < last; ++row) {
		CLineData *ld;
		int mapped = amount + row + screen->topline;

		if ((ld = getLineData(screen, mapped)) != NULL) {
		    ShowWrapMarks(xw, row, ld);
		}
	    }
	}
    }
}

/*
 * use when scrolling the entire screen
 */
void
scrolling_copy_area(XtermWidget xw,
		    int firstline,	/* line on screen to start copying at */
		    int nlines,
		    int amount)	/* number of lines to move up (neg=down) */
{

    if (nlines > 0) {
	vertical_copy_area(xw, firstline, nlines, amount, 0, TScreenOf(xw)->max_col);
    }
}

/*
 * Handler for Expose events on the VT widget.
 * Returns 1 iff the area where the cursor was got refreshed.
 */
int
HandleExposure(XtermWidget xw, XEvent *event)
{
    TScreen *screen = TScreenOf(xw);
    XExposeEvent *reply = (XExposeEvent *) event;

#ifndef NO_ACTIVE_ICON
    if (reply->window == screen->iconVwin.window) {
	WhichVWin(screen) = &screen->iconVwin;
	TRACE(("HandleExposure - icon\n"));
    } else {
	WhichVWin(screen) = &screen->fullVwin;
	TRACE(("HandleExposure - normal\n"));
    }
    TRACE((" event %d,%d %dx%d\n",
	   reply->y,
	   reply->x,
	   reply->height,
	   reply->width));
#endif /* NO_ACTIVE_ICON */

    /* if not doing CopyArea or if this is a GraphicsExpose, don't translate */
    if (!screen->incopy || event->type != Expose) {
	return handle_translated_exposure(xw, reply->x, reply->y,
					  reply->width,
					  reply->height);
    } else {
	/* compute intersection of area being copied with
	   area being exposed. */
	int both_x1 = Max(screen->copy_src_x, reply->x);
	int both_y1 = Max(screen->copy_src_y, reply->y);
	int both_x2 = Min(screen->copy_src_x + (int) screen->copy_width,
			  (reply->x + (int) reply->width));
	int both_y2 = Min(screen->copy_src_y + (int) screen->copy_height,
			  (reply->y + (int) reply->height));
	int value = 0;

	/* was anything copied affected? */
	if (both_x2 > both_x1 && both_y2 > both_y1) {
	    /* do the copied area */
	    value = handle_translated_exposure
		(xw, reply->x + screen->copy_dest_x - screen->copy_src_x,
		 reply->y + screen->copy_dest_y - screen->copy_src_y,
		 reply->width, reply->height);
	}
	/* was anything not copied affected? */
	if (reply->x < both_x1 || reply->y < both_y1
	    || reply->x + reply->width > both_x2
	    || reply->y + reply->height > both_y2)
	    value = handle_translated_exposure(xw, reply->x, reply->y,
					       reply->width, reply->height);

	return value;
    }
}

static void
set_background(XtermWidget xw, int color)
{
    TScreen *screen = TScreenOf(xw);
    Pixel c = getXtermBG(xw, xw->flags, color);

#if OPT_WIDE_ATTRS
    TRACE(("set_background(%d) %#lx %s\n", color, c,
	   ((xw->flags & ATR_DIRECT_BG)
	    ? "direct"
	    : "indexed")));
#else
    TRACE(("set_background(%d) %#lx\n", color, c));
#endif
    XSetWindowBackground(screen->display, VShellWindow(xw), c);
    XSetWindowBackground(screen->display, VWindow(screen), c);
    initBorderGC(xw, WhichVWin(screen));
}

void
xtermClear2(XtermWidget xw, int x, int y, unsigned width, unsigned height)
{
    TScreen *screen = TScreenOf(xw);
    VTwin *vwin = WhichVWin(screen);
    Drawable draw = VDrawable(screen);
    GC gc;

    if ((gc = vwin->border_gc) != NULL) {
	int vmark1 = screen->border;
	int vmark2 = vwin->height + vmark1;
	int hmark1 = OriginX(screen);
	int hmark2 = vwin->width + hmark1;
	if (y < vmark1) {
	    int yy = y + (int) height;
	    int h1 = (yy <= vmark1) ? (yy - y) : (vmark1 - y);
	    XFillRectangle(screen->display, draw, gc,
			   x, y, width, (unsigned) h1);
	    if (yy > vmark1) {
		xtermClear2(xw, x, vmark1, width, (unsigned) (yy - vmark1));
	    }
	} else if (y < vmark2) {
	    int yy = y + (int) height;
	    int h2 = (yy <= vmark2) ? (yy - y) : (vmark2 - y);
	    int xb = x;
	    int xx = x + (int) width;
	    int ww = (int) width;
	    if (x < hmark1) {
		int w1 = (xx <= hmark1) ? (xx - x) : (hmark1 - x);
		XFillRectangle(screen->display, draw, gc,
			       x, y, (unsigned) w1, (unsigned) h2);
		x += w1;
		ww -= w1;
	    }
	    if ((ww > 0) && (x < hmark2)) {
		int w2 = (xx <= hmark2) ? (xx - x) : (hmark2 - x);
#if USE_DOUBLE_BUFFER
		if (resource.buffered) {
		    XFillRectangle(screen->display, draw,
				   FillerGC(xw, screen),
				   x, y, (unsigned) w2, (unsigned) h2);
		} else
#endif
		    XClearArea(screen->display, VWindow(screen),
			       x, y, (unsigned) w2, (unsigned) h2, False);
		x += w2;
		ww -= w2;
	    }
	    if (ww > 0) {
		XFillRectangle(screen->display, draw, gc,
			       x, y, (unsigned) ww, (unsigned) h2);
	    }
	    if (yy > vmark2) {
		xtermClear2(xw, xb, vmark2, width, (unsigned) (yy - vmark2));
	    }
	} else {
	    XFillRectangle(screen->display, draw, gc, x, y, width, height);
	}
    } else {
#if USE_DOUBLE_BUFFER
	if (resource.buffered) {
	    gc = FillerGC(xw, screen);
	    XFillRectangle(screen->display, draw, gc,
			   x, y, width, height);
	} else
#endif
	    XClearArea(screen->display,
		       VWindow(screen),
		       x, y, width, height, False);
    }
}

/*
 * Called by the ExposeHandler to do the actual repaint after the coordinates
 * have been translated to allow for any CopyArea in progress.
 * The rectangle passed in is pixel coordinates.
 */
static int
handle_translated_exposure(XtermWidget xw,
			   int rect_x,
			   int rect_y,
			   int rect_width,
			   int rect_height)
{
    TScreen *screen = TScreenOf(xw);
    int toprow, leftcol, nrows, ncols;
    int x0, x1;
    int y0, y1;
    int result = 0;

    TRACE(("handle_translated_exposure at %d,%d size %dx%d\n",
	   rect_y, rect_x, rect_height, rect_width));

    x0 = (rect_x - OriginX(screen));
    x1 = (x0 + rect_width);

    y0 = (rect_y - OriginY(screen));
    y1 = (y0 + rect_height);

    if (x0 < 0 ||
	y0 < 0 ||
	x1 > Width(screen) ||
	y1 > PlusStatusLine(screen, Height(screen))) {
	set_background(xw, -1);
	xtermClear2(xw,
		    rect_x,
		    rect_y,
		    (unsigned) rect_width,
		    (unsigned) rect_height);
    }
    toprow = y0 / FontHeight(screen);
    if (toprow < 0)
	toprow = 0;

    leftcol = x0 / FontWidth(screen);
    if (leftcol < 0)
	leftcol = 0;

    nrows = (y1 - 1) / FontHeight(screen) - toprow + 1;
    ncols = (x1 - 1) / FontWidth(screen) - leftcol + 1;
    toprow -= screen->scrolls;
    if (toprow < 0) {
	nrows += toprow;
	toprow = 0;
    }
    if (toprow + nrows > PlusStatusLine(screen, MaxRows(screen)))
	nrows = PlusStatusLine(screen, MaxRows(screen)) - toprow;
    if (leftcol + ncols > MaxCols(screen))
	ncols = MaxCols(screen) - leftcol;

    if (nrows > 0 && ncols > 0) {
	ScrnRefresh(xw, toprow, leftcol, nrows, ncols, True);
	first_map_occurred();
	if (screen->cur_row >= toprow &&
	    screen->cur_row < toprow + nrows &&
	    screen->cur_col >= leftcol &&
	    screen->cur_col < leftcol + ncols) {
	    result = 1;
	}

    }
    TRACE(("...handle_translated_exposure %d\n", result));
    return (result);
}

/***====================================================================***/

void
GetColors(XtermWidget xw, ScrnColors * pColors)
{
    TScreen *screen = TScreenOf(xw);
    int n;

    pColors->which = 0;
    for (n = 0; n < NCOLORS; ++n) {
	SET_COLOR_VALUE(pColors, n, T_COLOR(screen, n));
    }
}

Boolean
AssignFgColor(XtermWidget xw, Pixel fg)
{
    Boolean repaint = False;
    TScreen *screen = TScreenOf(xw);
    VTwin *win = WhichVWin(screen);

    T_COLOR(screen, TEXT_FG) = fg;
    TRACE(("... TEXT_FG: %#lx\n", fg));
    if (screen->Vshow) {
	setCgsFore(xw, win, gcNorm, fg);
	setCgsBack(xw, win, gcNormReverse, fg);
	setCgsFore(xw, win, gcBold, fg);
	setCgsBack(xw, win, gcBoldReverse, fg);
	repaint = True;
    }
    FreeMarkGCs(xw);

    return repaint;
}

Boolean
AssignBgColor(XtermWidget xw, Pixel bg)
{
    Boolean repaint = False;
    TScreen *screen = TScreenOf(xw);
    VTwin *win = WhichVWin(screen);

    T_COLOR(screen, TEXT_BG) = bg;
    TRACE(("... TEXT_BG: %#lx\n", bg));
    if (screen->Vshow) {
	setCgsBack(xw, win, gcNorm, bg);
	setCgsFore(xw, win, gcNormReverse, bg);
	setCgsBack(xw, win, gcBold, bg);
	setCgsFore(xw, win, gcBoldReverse, bg);
	set_background(xw, -1);
	repaint = True;
    }

    return repaint;
}

void
ChangeColors(XtermWidget xw, ScrnColors * pNew)
{
    Boolean repaint = False;
    TScreen *screen = TScreenOf(xw);

    TRACE(("ChangeColors\n"));

    if (COLOR_DEFINED(pNew, TEXT_CURSOR)) {
	T_COLOR(screen, TEXT_CURSOR) = COLOR_VALUE(pNew, TEXT_CURSOR);
	TRACE(("... TEXT_CURSOR: %#lx\n", T_COLOR(screen, TEXT_CURSOR)));
	FreeMarkGCs(xw);
	/* no repaint needed */
    } else if ((T_COLOR(screen, TEXT_CURSOR) == T_COLOR(screen, TEXT_FG)) &&
	       (COLOR_DEFINED(pNew, TEXT_FG))) {
	if (T_COLOR(screen, TEXT_CURSOR) != COLOR_VALUE(pNew, TEXT_FG)) {
	    T_COLOR(screen, TEXT_CURSOR) = COLOR_VALUE(pNew, TEXT_FG);
	    TRACE(("... TEXT_CURSOR: %#lx\n", T_COLOR(screen, TEXT_CURSOR)));
	    if (screen->Vshow)
		repaint = True;
	}
	FreeMarkGCs(xw);
    }

    if (COLOR_DEFINED(pNew, TEXT_FG)
	&& AssignFgColor(xw, COLOR_VALUE(pNew, TEXT_FG))) {
	repaint = True;
    }

    if (COLOR_DEFINED(pNew, TEXT_BG)
	&& AssignBgColor(xw, COLOR_VALUE(pNew, TEXT_BG))) {
	repaint = True;
    }
#if OPT_HIGHLIGHT_COLOR
    if (COLOR_DEFINED(pNew, HIGHLIGHT_BG)) {
	if (T_COLOR(screen, HIGHLIGHT_BG) != COLOR_VALUE(pNew, HIGHLIGHT_BG)) {
	    T_COLOR(screen, HIGHLIGHT_BG) = COLOR_VALUE(pNew, HIGHLIGHT_BG);
	    TRACE(("... HIGHLIGHT_BG: %#lx\n", T_COLOR(screen, HIGHLIGHT_BG)));
	    if (screen->Vshow)
		repaint = True;
	}
    }
    if (COLOR_DEFINED(pNew, HIGHLIGHT_FG)) {
	if (T_COLOR(screen, HIGHLIGHT_FG) != COLOR_VALUE(pNew, HIGHLIGHT_FG)) {
	    T_COLOR(screen, HIGHLIGHT_FG) = COLOR_VALUE(pNew, HIGHLIGHT_FG);
	    TRACE(("... HIGHLIGHT_FG: %#lx\n", T_COLOR(screen, HIGHLIGHT_FG)));
	    if (screen->Vshow)
		repaint = True;
	}
    }
#endif

    if (COLOR_DEFINED(pNew, MOUSE_FG) || (COLOR_DEFINED(pNew, MOUSE_BG))) {
	if (COLOR_DEFINED(pNew, MOUSE_FG)) {
	    T_COLOR(screen, MOUSE_FG) = COLOR_VALUE(pNew, MOUSE_FG);
	    TRACE(("... MOUSE_FG: %#lx\n", T_COLOR(screen, MOUSE_FG)));
	}
	if (COLOR_DEFINED(pNew, MOUSE_BG)) {
	    T_COLOR(screen, MOUSE_BG) = COLOR_VALUE(pNew, MOUSE_BG);
	    TRACE(("... MOUSE_BG: %#lx\n", T_COLOR(screen, MOUSE_BG)));
	}

	if (screen->Vshow) {
	    recolor_cursor(screen,
			   screen->pointer_cursor,
			   T_COLOR(screen, MOUSE_FG),
			   T_COLOR(screen, MOUSE_BG));
	    XDefineCursor(screen->display, VWindow(screen),
			  screen->pointer_cursor);
	}
#if OPT_TEK4014
	if (TEK4014_SHOWN(xw)) {
	    TekScreen *tekscr = TekScreenOf(tekWidget);
	    Window tekwin = TWindow(tekscr);
	    if (tekwin) {
		recolor_cursor(screen,
			       tekscr->arrow,
			       T_COLOR(screen, MOUSE_FG),
			       T_COLOR(screen, MOUSE_BG));
		XDefineCursor(screen->display, tekwin, tekscr->arrow);
	    }
	}
#endif
	/* no repaint needed */
    }

    if (COLOR_DEFINED(pNew, TEXT_FG) ||
	COLOR_DEFINED(pNew, TEXT_BG) ||
	COLOR_DEFINED(pNew, TEXT_CURSOR)) {
	if (set_cursor_gcs(xw) && screen->Vshow) {
	    repaint = True;
	}
    }
#if OPT_TEK4014
    if (COLOR_DEFINED(pNew, TEK_FG) ||
	COLOR_DEFINED(pNew, TEK_BG)) {
	ChangeTekColors(tekWidget, screen, pNew);
	if (TEK4014_SHOWN(xw)) {
	    TekRepaint(tekWidget);
	}
    } else if (COLOR_DEFINED(pNew, TEK_CURSOR)) {
	ChangeTekColors(tekWidget, screen, pNew);
    }
#endif
    if (repaint)
	xtermRepaint(xw);
}

void
xtermClear(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    TRACE(("xtermClear\n"));
    xtermClear2(xw, 0, 0, FullWidth(screen), FullHeight(screen));
}

void
xtermRepaint(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    TRACE(("xtermRepaint\n"));
    xtermClear(xw);
    ScrnRefresh(xw, 0, 0, LastRowNumber(screen) + 1, MaxCols(screen), True);
}

/***====================================================================***/

Boolean
isDefaultForeground(const char *name)
{
    return (Boolean) !x_strcasecmp(name, XtDefaultForeground);
}

Boolean
isDefaultBackground(const char *name)
{
    return (Boolean) !x_strcasecmp(name, XtDefaultBackground);
}

/***====================================================================***/

typedef struct {
    Pixel fg;
    Pixel bg;
} ToSwap;

#if OPT_HIGHLIGHT_COLOR
#define hc_param ,Bool hilite_color
#define hc_value ,screen->hilite_color
#else
#define hc_param		/* nothing */
#define hc_value		/* nothing */
#endif

/*
 * Use this to swap the foreground/background color values in the resource
 * data, and to build up a list of the pairs which must be swapped in the
 * GC cache.
 */
static void
swapLocally(ToSwap * list, int *count, ColorRes * fg, ColorRes * bg hc_param)
{
    ColorRes tmp;
    Boolean found = False;

    Pixel fg_color = fg->value;
    Pixel bg_color = bg->value;

#if OPT_HIGHLIGHT_COLOR
    if ((fg_color != bg_color) || !hilite_color)
#endif
    {
	int n;

	EXCHANGE(*fg, *bg, tmp);
	for (n = 0; n < *count; ++n) {
	    if ((list[n].fg == fg_color && list[n].bg == bg_color)
		|| (list[n].fg == bg_color && list[n].bg == fg_color)) {
		found = True;
		break;
	    }
	}
	if (!found) {
	    list[*count].fg = fg_color;
	    list[*count].bg = bg_color;
	    *count = *count + 1;
	    TRACE(("swapLocally fg %#lx, bg %#lx ->%d\n",
		   fg_color, bg_color, *count));
	}
    }
}

static void
reallySwapColors(XtermWidget xw, ToSwap * list, int count)
{
    int j, k;

    TRACE(("reallySwapColors\n"));
    for (j = 0; j < count; ++j) {
	for_each_text_gc(k) {
	    redoCgs(xw, list[j].fg, list[j].bg, (CgsEnum) k);
	}
    }
    FreeMarkGCs(xw);
}

static void
swapVTwinGCs(XtermWidget xw, VTwin *win)
{
    swapCgs(xw, win, gcNorm, gcNormReverse);
    swapCgs(xw, win, gcBold, gcBoldReverse);
}

void
ReverseVideo(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    ToSwap listToSwap[5];
    int numToSwap = 0;

    TRACE(("ReverseVideo now %s\n", BtoS(xw->misc.re_verse)));

    /*
     * Swap SGR foreground and background colors.  By convention, these are
     * the colors assigned to "black" (SGR #0) and "white" (SGR #7).  Also,
     * SGR #8 and SGR #15 are the bold (or bright) versions of SGR #0 and
     * #7, respectively.
     *
     * We don't swap colors that happen to match the screen's foreground
     * and background because that tends to produce bizarre effects.
     */
#define swapAnyColor(name,a,b) swapLocally(listToSwap, &numToSwap, &(screen->name[a]), &(screen->name[b]) hc_value)
#define swapAColor(a,b) swapAnyColor(Acolors, a, b)
    if_OPT_ISO_COLORS(screen, {
	swapAColor(0, 7);
	swapAColor(8, 15);
    });

    if (T_COLOR(screen, TEXT_CURSOR) == T_COLOR(screen, TEXT_FG)) {
	T_COLOR(screen, TEXT_CURSOR) = T_COLOR(screen, TEXT_BG);
    }
#define swapTColor(a,b) swapAnyColor(Tcolors, a, b)
    swapTColor(TEXT_FG, TEXT_BG);
    swapTColor(MOUSE_FG, MOUSE_BG);

    reallySwapColors(xw, listToSwap, numToSwap);

    swapVTwinGCs(xw, &(screen->fullVwin));
#ifndef NO_ACTIVE_ICON
    swapVTwinGCs(xw, &(screen->iconVwin));
#endif /* NO_ACTIVE_ICON */

    xw->misc.re_verse = (Boolean) !xw->misc.re_verse;
    TRACE(("...swapping done, set ReverseVideo %s\n", BtoS(xw->misc.re_verse)));

    if (XtIsRealized((Widget) xw)) {
	xtermDisplayPointer(xw);
    }
#if OPT_TEK4014
    if (TEK4014_SHOWN(xw)) {
	TekScreen *tekscr = TekScreenOf(tekWidget);
	Window tekwin = TWindow(tekscr);
	recolor_cursor(screen,
		       tekscr->arrow,
		       T_COLOR(screen, MOUSE_FG),
		       T_COLOR(screen, MOUSE_BG));
	XDefineCursor(screen->display, tekwin, tekscr->arrow);
    }
#endif

    if (screen->scrollWidget)
	ScrollBarReverseVideo(screen->scrollWidget);

    if (XtIsRealized((Widget) xw)) {
	set_background(xw, -1);
    }
#if OPT_TEK4014
    TekReverseVideo(xw, tekWidget);
#endif
    if (XtIsRealized((Widget) xw)) {
	xtermRepaint(xw);
    }
#if OPT_TEK4014
    if (TEK4014_SHOWN(xw)) {
	TekRepaint(tekWidget);
    }
#endif
    ReverseOldColors(xw);
    set_cursor_gcs(xw);
    update_reversevideo();
    TRACE(("...ReverseVideo now %s\n", BtoS(xw->misc.re_verse)));
}

void
recolor_cursor(TScreen *screen,
	       Cursor cursor,	/* X cursor ID to set */
	       unsigned long fg,	/* pixel indexes to look up */
	       unsigned long bg)	/* pixel indexes to look up */
{
    Display *dpy = screen->display;
    XColor colordefs[2];	/* 0 is foreground, 1 is background */

    colordefs[0].pixel = fg;
    colordefs[1].pixel = bg;
    XQueryColors(dpy, DefaultColormap(dpy, DefaultScreen(dpy)),
		 colordefs, 2);
    XRecolorCursor(dpy, cursor, colordefs, colordefs + 1);
    cleanup_colored_cursor();
    return;
}

#if OPT_RENDERFONT
#define XFT_CACHE_LIMIT ((unsigned)(~0) >> 1)
#define XFT_CACHE_SIZE  16
typedef struct {
    XftColor color;
    unsigned use;
} XftColorCache;

static int
compare_xft_color_cache(const void *a, const void *b)
{
    return (int) (((const XftColorCache *) a)->use -
		  ((const XftColorCache *) b)->use);
}

static XftColor *
getXftColor(XtermWidget xw, Pixel pixel)
{
    static XftColorCache cache[XFT_CACHE_SIZE + 1];
    static unsigned latest_use;
    int i;
    int oldest;
    unsigned oldest_use;
    XColor color;
    Boolean found = False;

    (void) xw;
    oldest_use = XFT_CACHE_LIMIT;
    oldest = 0;
    if (latest_use == XFT_CACHE_LIMIT) {
	latest_use = 0;
	qsort(cache, (size_t) XFT_CACHE_SIZE, sizeof(XftColorCache), compare_xft_color_cache);
	for (i = 0; i < XFT_CACHE_SIZE; i++) {
	    if (cache[i].use) {
		cache[i].use = ++latest_use;
	    }
	}
    }
    for (i = 0; i < XFT_CACHE_SIZE; i++) {
	if (cache[i].use) {
	    if (cache[i].color.pixel == pixel) {
		found = True;
		break;
	    }
	}
	if (cache[i].use < oldest_use) {
	    oldest_use = cache[i].use;
	    oldest = i;
	}
    }
    if (!found) {
	i = oldest;
	color.pixel = pixel;
	(void) QueryOneColor(xw, &color);
	cache[i].color.color.red = color.red;
	cache[i].color.color.green = color.green;
	cache[i].color.color.blue = color.blue;
	cache[i].color.color.alpha = 0xffff;
	cache[i].color.pixel = pixel;
    }
    cache[i].use = ++latest_use;
    return &cache[i].color;
}

/*
 * The cell-width is related to, but not the same as the wide-character width.
 * We will only get useful values from wcwidth() for codes above 255.
 * Otherwise, interpret according to internal data.
 */
#if OPT_RENDERWIDE

#if OPT_C1_PRINT
#define XtermCellWidth(xw, ch) \
	(((ch) == 0 || (ch) == 127) \
	  ? 0 \
	  : (((ch) < 256) \
	      ? (((ch) >= 128 && (ch) < 160) \
		  ? (TScreenOf(xw)->c1_printable ? 1 : 0) \
		  : 1) \
	      : CharWidth(TScreenOf(xw), ch)))
#else
#define XtermCellWidth(xw, ch) \
	(((ch) == 0 || (ch) == 127) \
	  ? 0 \
	  : (((ch) < 256) \
	      ? 1 \
	      : CharWidth(TScreenOf(xw), ch)))
#endif

#endif /* OPT_RENDERWIDE */

#define XFT_DATA(which) getMyXftFont(params->xw, which, fontnum)

#if OPT_ISO_COLORS
#define UseBoldFont(screen) (!(screen)->colorBDMode || ((screen)->veryBoldColors & BOLD))
#else
#define UseBoldFont(screen) 1
#endif

#if OPT_RENDERWIDE
/*
 * Find Xft (truetype) double-width font for the given normal/bold attributes.
 */
static XTermXftFonts *
getWideXftFont(XTermDraw * params,
	       unsigned attr_flags)
{
    TScreen *screen = TScreenOf(params->xw);
    int fontnum = screen->menu_font_number;
    XTermXftFonts *result = NULL;

#if OPT_WIDE_ATTRS
    if ((attr_flags & ATR_ITALIC)
#if OPT_ISO_COLORS
	&& !screen->colorITMode
#endif
	) {
	if ((attr_flags & BOLDATTR(screen))
	    && UseBoldFont(screen)
	    && XFT_DATA(fWBtal)) {
	    result = XFT_DATA(fWBtal);
	} else if (XFT_DATA(fWItal)) {
	    result = XFT_DATA(fWItal);
	}
    }
    if (result != NULL) {
	;			/* skip the other tests */
    } else
#endif
#if OPT_ISO_COLORS
	if ((attr_flags & UNDERLINE)
	    && !screen->colorULMode
	    && screen->italicULMode
	    && XFT_DATA(fWItal)) {
	result = XFT_DATA(fWItal);
    } else
#endif
	if ((attr_flags & BOLDATTR(screen))
	    && UseBoldFont(screen)
	    && XFT_DATA(fWBold)) {
	result = XFT_DATA(fWBold);
    } else {
	result = XFT_DATA(fWide);
    }
    return result;
}
#endif /* OPT_RENDERWIDE */

/*
 * Find Xft (truetype) single-width font for the given normal/bold attributes.
 */
static XTermXftFonts *
getNormXftFont(XTermDraw * params,
	       unsigned attr_flags,
	       Bool *did_ul)
{
    TScreen *screen = TScreenOf(params->xw);
    int fontnum = screen->menu_font_number;
    XTermXftFonts *result = NULL;

    (void) did_ul;
#if OPT_DEC_CHRSET
    if (CSET_DOUBLE(params->real_chrset)) {
	result = xterm_DoubleFT(params, params->real_chrset, attr_flags);
    }
    if (result != NULL) {
	;			/* found a usable double-sized font */
    } else
#endif
#if OPT_WIDE_ATTRS
	if ((attr_flags & ATR_ITALIC)
#if OPT_ISO_COLORS
	    && !screen->colorITMode
#endif
	) {
	if ((attr_flags & BOLDATTR(screen))
	    && UseBoldFont(screen)
	    && XFT_DATA(fBtal)) {
	    result = XFT_DATA(fBtal);
	} else if (XFT_DATA(fItal)) {
	    result = XFT_DATA(fItal);
	}
    }
    if (result != NULL) {
	;			/* skip the other tests */
    } else
#endif
#if OPT_ISO_COLORS
	if ((attr_flags & UNDERLINE)
	    && !screen->colorULMode
	    && screen->italicULMode
	    && XFT_DATA(fItal)) {
	result = XFT_DATA(fItal);
	*did_ul = True;
    } else
#endif
	if ((attr_flags & BOLDATTR(screen))
	    && UseBoldFont(screen)
	    && XFT_DATA(fBold)) {
	result = XFT_DATA(fBold);
    } else {
	result = XFT_DATA(fNorm);
    }
    return result;
}

#if OPT_RENDERWIDE
#define pickXftData(width, nf, wf) (((width == 2) && ((wf) != NULL) && XftFp(wf) != NULL) ? (wf) : (nf))
#define pickXftFont(width, nf, wf) (((width == 2) && ((wf) != NULL)) ? (wf) : (nf))
#else
#define pickXftData(width, nf, wf) (nf)
#define pickXftFont(width, nf, wf) (nf)
#endif

/*
 * fontconfig/Xft combination prior to 2.2 has a problem with
 * CJK truetype 'double-width' (bi-width/monospace) fonts leading
 * to the 's p a c e d o u t' rendering. Consequently, we can't
 * rely on XftDrawString8/16 when one of those fonts is used.
 * Instead, we need to roll out our own using XftDrawCharSpec.
 * A patch in the same spirit (but in a rather different form)
 * was applied to gnome vte and gtk2 port of vim.
 * See http://bugzilla.mozilla.org/show_bug.cgi?id=196312
 */
static int
xtermXftDrawString(XTermDraw * params,
		   unsigned attr_flags,
		   XftColor *color,
		   XftFont *font,
		   int x,
		   int y,
		   const IChar *text,
		   Cardinal len,
		   Bool really)
{
    TScreen *screen = TScreenOf(params->xw);
    int ncells = 0;

    (void) attr_flags;
    if (len != 0) {
#if OPT_RENDERWIDE
	XftCharSpec *sbuf;
	XTermXftFonts *wdata = getWideXftFont(params, attr_flags);
	XftFont *wfont = XftFp(wdata);
	Cardinal src, dst;
	XftFont *lastFont = NULL;
	XftFont *currFont = NULL;
	Cardinal start = 0;
	int charWidth;
	int fwidth = FontWidth(screen);
#if OPT_DEC_CHRSET
	Boolean forceDbl = CSET_DOUBLE(params->real_chrset);
#else
	Boolean forceDbl = False;
#endif

	BumpTypedBuffer(XftCharSpec, 2 * len);
	sbuf = BfBuf(XftCharSpec);

	for (src = dst = 0; src < len; src++) {
	    FcChar32 wc = *text++;

	    charWidth = XtermCellWidth(params->xw, (wchar_t) wc);
	    if (charWidth < 0)
		continue;

	    sbuf[dst].ucs4 = wc;
	    sbuf[dst].x = (short) (x + fwidth * ncells);
	    sbuf[dst].y = (short) (y);

	    currFont = pickXftFont(charWidth, font, wfont);
	    ncells += charWidth;

	    if (lastFont != currFont) {
		if ((lastFont != NULL) && really) {
		    XftDrawCharSpec(screen->renderDraw,
				    color,
				    lastFont,
				    sbuf + start,
				    (int) (dst - start));
		}
		start = dst;
		lastFont = currFont;
	    }
	    ++dst;

	    if (forceDbl && charWidth < 2) {
		sbuf[dst].ucs4 = ' ';
		sbuf[dst].x = (short) (x + fwidth * ncells);
		sbuf[dst].y = (short) (y);
		++dst;
		ncells += charWidth;
	    }
	}
	if ((dst != start) && really) {
	    XftDrawCharSpec(screen->renderDraw,
			    color,
			    lastFont,
			    sbuf + start,
			    (int) (dst - start));
	}
#else /* !OPT_RENDERWIDE */
	if (really) {
	    XftChar8 *buffer;
	    int dst;

	    BumpTypedBuffer(XftChar8, len);
	    buffer = BfBuf(XftChar8);

	    for (dst = 0; dst < (int) len; ++dst)
		buffer[dst] = CharOf(text[dst]);

	    XftDrawString8(screen->renderDraw,
			   color,
			   font,
			   x, y, buffer, (int) len);
	}
	ncells = (int) len;
#endif
	xtermNeedSwap(params->xw, 1);
    }
    return ncells;
}
#define xtermXftWidth(params, attr_flags, color, font, x, y, chars, len) \
   xtermXftDrawString(params, attr_flags, color, font, x, y, chars, len, False)
#endif /* OPT_RENDERFONT */

#if OPT_WIDE_CHARS
/*
 * Map characters commonly "fixed" by groff back to their ASCII equivalents.
 * Also map other useful equivalents.
 */
unsigned
AsciiEquivs(unsigned ch)
{
    switch (ch) {
    case 0x2010:		/* groff "-" */
    case 0x2011:
    case 0x2012:
    case 0x2013:
    case 0x2014:
    case 0x2015:
    case 0x2212:		/* groff "\-" */
	ch = '-';
	break;
    case 0x2018:		/* groff "`" */
	ch = '`';
	break;
    case 0x2019:		/* groff ' */
	ch = '\'';
	break;
    case 0x201C:		/* groff lq */
    case 0x201D:		/* groff rq */
	ch = '"';
	break;
    case 0x2329:		/* groff ".URL" */
	ch = '<';
	break;
    case 0x232a:		/* groff ".URL" */
	ch = '>';
	break;
    default:
	if (ch >= 0xff01 && ch <= 0xff5e) {
	    /* "Fullwidth" codes (actually double-width) */
	    ch -= 0xff00;
	    ch += ANSI_SPA;
	    break;
	}
    }
    return ch;
}

/*
 * Actually this should be called "groff_workaround()" - for the places where
 * groff stomps on compatibility.  Still, if enough people get used to it,
 * this might someday become a quasi-standard.
 */
#if OPT_BOX_CHARS
static int
ucs_workaround(XTermDraw * params,
	       unsigned ch,
	       GC gc,
	       int x,
	       int y)
{
    TScreen *screen = TScreenOf(params->xw);
    int fixed = False;

    if (screen->wide_chars && screen->utf8_mode && ch > 256) {
	IChar eqv = (IChar) AsciiEquivs(ch);

	if (eqv != (IChar) ch) {
	    int width = CharWidth(screen, ch);

	    do {
		drawXtermText(params,
			      gc,
			      x,
			      y,
			      &eqv,
			      1);
		x += FontWidth(screen);
		eqv = BAD_ASCII;
	    } while (width-- > 1);

	    fixed = True;
	} else if (ch == HIDDEN_CHAR) {
	    fixed = True;
	}
    }
    return fixed;
}
#endif /* OPT_BOX_CHARS */
#endif /* OPT_WIDE_CHARS */

/*
 * Use this when the characters will not fill the cell area properly.  Fill the
 * area where we'll write the characters, otherwise we'll get gaps between
 * them, e.g., in the original background color.
 *
 * The cursor is a special case, because the XFillRectangle call only uses the
 * foreground, while we've set the cursor color in the background.  So we need
 * a special GC for that.
 */
static void
xtermFillCells(XTermDraw * params,
	       GC gc,
	       int x,
	       int y,
	       Cardinal len)
{
    TScreen *screen = TScreenOf(params->xw);
    VTwin *currentWin = WhichVWin(screen);

    if (!(params->draw_flags & NOBACKGROUND)) {
	CgsEnum srcId = getCgsId(params->xw, currentWin, gc);
	CgsEnum dstId = gcMAX;
	Pixel fg = getCgsFore(params->xw, currentWin, gc);
	Pixel bg = getCgsBack(params->xw, currentWin, gc);

	switch (srcId) {
	case gcVTcursNormal:
	case gcVTcursReverse:
	    dstId = gcVTcursOutline;
	    break;
	case gcVTcursFilled:
	case gcVTcursOutline:
	    break;
	case gcNorm:
	    dstId = gcNormReverse;
	    break;
	case gcNormReverse:
	    dstId = gcNorm;
	    break;
	case gcBold:
	    dstId = gcBoldReverse;
	    break;
	case gcBoldReverse:
	    dstId = gcBold;
	    break;
	case gcBorder:
	case gcFiller:
	    dstId = srcId;
	    break;
#if OPT_BOX_CHARS || OPT_WIDE_CHARS
	case gcLine:
	case gcDots:
	    break;
#endif
#if OPT_DEC_CHRSET
	case gcCNorm:
	case gcCBold:
	    break;
#endif
#if OPT_WIDE_CHARS
	case gcWide:
	    dstId = gcWideReverse;
	    break;
	case gcWBold:
	    dstId = gcBoldReverse;
	    break;
	case gcWideReverse:
	case gcWBoldReverse:
	    break;
#endif
#if OPT_TEK4014
	case gcTKcurs:
	    break;
#endif
	case gcMAX:
	    break;
	}

	if (dstId != gcMAX) {
	    setCgsFore(params->xw, currentWin, dstId, bg);
	    setCgsBack(params->xw, currentWin, dstId, fg);

	    XFillRectangle(screen->display, VDrawable(screen),
			   getCgsGC(params->xw, currentWin, dstId),
			   x, y,
			   len * (Cardinal) FontWidth(screen),
			   (unsigned) FontHeight(screen));
	}
    }
}

#if OPT_TRACE
static void
xtermSetClipRectangles(Display *dpy,
		       GC gc,
		       int x,
		       int y,
		       XRectangle * rp,
		       Cardinal nr,
		       int order)
{
#if 0
    TScreen *screen = TScreenOf(term);
    Drawable draw = VDrawable(screen);

    XSetClipMask(dpy, gc, None);
    XDrawRectangle(screen->display, draw, gc,
		   x + rp->x - 1,
		   y + rp->y - 1,
		   rp->width,
		   rp->height);
#endif

    XSetClipRectangles(dpy, gc,
		       x, y, rp, (int) nr, order);
    TRACE(("clipping @(%3d,%3d) (%3d,%3d)..(%3d,%3d)\n",
	   y, x,
	   rp->y, rp->x, rp->height, rp->width));
}

#else
#define xtermSetClipRectangles(dpy, gc, x, y, rp, nr, order) \
	    XSetClipRectangles(dpy, gc, x, y, rp, (int) nr, order)
#endif

#if OPT_CLIP_BOLD
/*
 * This special case is a couple of percent slower, but avoids a lot of pixel
 * trash in rxcurses' hanoi.cmd demo (e.g., 10x20 font).
 */
#define beginClipping(screen,gc,pwidth,plength) \
	if (pwidth > 2) { \
	    if (screen->use_clipping) { \
		XRectangle clip; \
		int clip_x = x; \
		int clip_y = y - FontHeight(screen) + FontDescent(screen); \
		clip.x = 0; \
		clip.y = 0; \
		clip.height = (unsigned short) FontHeight(screen); \
		clip.width = (unsigned short) ((pwidth) * (plength)); \
		xtermSetClipRectangles(screen->display, gc, \
				       clip_x, clip_y, \
				       &clip, 1, Unsorted); \
	    } else if (screen->use_border_clipping) { \
		XRectangle clip; \
		clip.x = 0; \
		clip.y = 0; \
		clip.height = (unsigned short) Height(screen); \
		clip.width = (unsigned short) Width(screen); \
		xtermSetClipRectangles(screen->display, gc, \
				       0, 0, \
				       &clip, 1, Unsorted); \
	    } \
	}
#define endClipping(screen,gc) \
	    XSetClipMask(screen->display, gc, None)
#else
#define beginClipping(screen,gc,pwidth,plength)		/* nothing */
#define endClipping(screen,gc)	/* nothing */
#endif /* OPT_CLIP_BOLD */

#if OPT_RENDERFONT
static int
drawClippedXftString(XTermDraw * params,
		     unsigned attr_flags,
		     XftFont *font,
		     XftColor *fg_color,
		     int x,
		     int y,
		     const IChar *text,
		     Cardinal len)
{
    int ncells = xtermXftWidth(params, attr_flags,
			       fg_color,
			       font, x, y,
			       text,
			       len);
    XtermWidget xw = params->xw;
    TScreen *screen = TScreenOf(xw);
    int fontHigh = FontHeight(screen);
    int fontWide = FontWidth(screen);

    if (fontWide > 2) {
	int plength = (ncells ? ncells : 1);
	Boolean halfHigh = False;
#if OPT_DEC_CHRSET
	Boolean halfWide = False;

	switch (params->real_chrset) {
	case CSET_SWL:
	    break;
	case CSET_DWL:
	    halfWide = True;
	    break;
	case CSET_DHL_TOP:
	    halfHigh = True;
	    halfWide = True;
	    break;
	case CSET_DHL_BOT:
	    halfHigh = True;
	    halfWide = True;
	    break;
	}
	if (CSET_DOUBLE(params->real_chrset)) {
	    fontHigh = font->height;
	    fontWide = font->max_advance_width;
	    /* check if this is really a double-height font */
#define DoubleScale(macro,field) \
	    (int) (macro(screen) * (1.0 + (Max(20, xw->misc.field) / 100.)))
	    if (halfHigh) {
		int wantHigh = DoubleScale(FontHeight, limit_fontheight);
		halfHigh = (fontHigh >= wantHigh);
		TRACE(("comparing fontHigh %d/%d vs %d:"
		       " double-height %s for %s\n",
		       fontHigh, FontHeight(screen),
		       wantHigh, BtoS(halfHigh),
		       visibleDblChrset(params->real_chrset)));
	    }
	    fontHigh = (halfHigh
			? (2 * FontHeight(screen))
			: FontHeight(screen));
	    /* check if this is really a double-width font */
	    if (halfWide) {
		int wantWide = DoubleScale(FontWidth, limit_fontwidth);
		halfWide = (fontWide >= wantWide);
		TRACE(("comparing fontWide %d/%d vs %d:"
		       " double-width %s for %s\n",
		       fontWide, FontWidth(screen),
		       wantWide, BtoS(halfWide),
		       visibleDblChrset(params->real_chrset)));
	    }
	    fontWide = (halfWide
			? (2 * FontWidth(screen))
			: FontWidth(screen));
	}
#endif
	if (screen->use_clipping || halfHigh) {
	    XRectangle clip;
	    double adds = ((double) screen->scale_height - 1.0f) * fontHigh;
	    int height = dimRound(adds + fontHigh);
	    int descnt = dimRound(adds / 2.0) + FontDescent(screen);
	    int clip_x = (x);
	    int clip_y = (y) - height + descnt;

	    clip.x = 0;
	    clip.y = 0;
	    clip.height = (Dimension) height;
	    clip.width = (Dimension) (fontWide * (Dimension) (plength));

#if OPT_DEC_CHRSET
	    if (halfHigh) {
		int adjust;

		clip.height = (unsigned short) FontHeight(screen);
		clip_y += descnt;
		if (params->real_chrset == CSET_DHL_BOT) {
		    y -= clip.height;
		}
		adjust = ((clip_y - OriginY(screen)) % FontHeight(screen));
		if (adjust) {
		    if (adjust > FontHeight(screen) / 2)
			adjust -= FontHeight(screen);
		    clip_y -= adjust;
		}
	    }
#endif
	    XftDrawSetClipRectangles(screen->renderDraw,
				     clip_x, clip_y,
				     &clip, 1);
	} else if (screen->use_border_clipping) {
	    XRectangle clip;

	    clip.x = (Position) OriginX(screen);
	    clip.y = (Position) OriginY(screen);
	    clip.height = (Dimension) Height(screen);
	    clip.width = (Dimension) Width(screen);

	    XftDrawSetClipRectangles(screen->renderDraw,
				     0, 0,
				     &clip, 1);
	}
    }

    xtermXftDrawString(params, attr_flags,
		       fg_color,
		       font, x, y + ScaleShift(screen),
		       text,
		       len,
		       True);
    XftDrawSetClip(screen->renderDraw, NULL);
    return ncells;
}
#endif

#ifndef NO_ACTIVE_ICON
#define WhichVFontData(screen,name) \
		(IsIcon(screen) ? getIconicFont(screen) \
				: GetNormalFont(screen, name))
#else
#define WhichVFontData(screen,name) \
				GetNormalFont(screen, name)
#endif

static void
drawUnderline(XtermWidget xw,
	      GC gc,
	      unsigned attr_flags,
	      unsigned underline_len,
	      int font_width,
	      int x,
	      int y,
	      Bool did_ul)
{
    TScreen *screen = TScreenOf(xw);

    if (screen->underline && !did_ul) {
	int repeat = 0;
	int descent = FontDescent(screen);
	int length = x + (int) underline_len * font_width - 1;

#if OPT_WIDE_ATTRS
	if ((attr_flags & ATR_STRIKEOUT)) {
	    int where = y - ((3 * FontAscent(screen)) / 8);
	    XDrawLine(screen->display, VDrawable(screen), gc,
		      x, where,
		      length,
		      where);
	}
	if ((attr_flags & ATR_DBL_UNDER)) {
	    repeat = 2;
	} else
#endif
	if ((attr_flags & UNDERLINE)) {
	    repeat = 1;
	}
	while (repeat-- > 0) {
	    if (descent-- > 1)
		y++;
	    XDrawLine(screen->display, VDrawable(screen), gc,
		      x, y,
		      length,
		      y);
	}
    }
}

#if OPT_WIDE_ATTRS
/*
 * As a special case, we are currently allowing italic fonts to be inexact
 * matches for the normal font's size.  That introduces a problem:  either the
 * ascent or descent may be shorter, leaving a gap that has to be filled in.
 * Or they may be larger, requiring clipping.  Check for both cases.
 */
static int
fixupItalics(XTermDraw * params,
	     GC gc,
	     XTermFonts * curFont,
	     int y, int x,
	     int font_width,
	     Cardinal len)
{
    TScreen *screen = TScreenOf(params->xw);
    VTwin *cgsWin = WhichVWin(screen);
    XFontStruct *realFp = curFont->fs;
    XFontStruct *thisFp = getCgsFont(params->xw, cgsWin, gc)->fs;
    int need_clipping = 0;
    int need_filling = 0;

    if (thisFp->ascent > realFp->ascent)
	need_clipping = 1;
    else if (thisFp->ascent < realFp->ascent)
	need_filling = 1;

    if (thisFp->descent > realFp->descent)
	need_clipping = 1;
    else if (thisFp->descent < realFp->descent)
	need_filling = 1;

    if (need_clipping) {
	beginClipping(screen, gc, font_width, (int) len);
    }
    if (need_filling) {
	xtermFillCells(params,
		       gc,
		       x,
		       y - realFp->ascent,
		       len);
    }
    return need_clipping;
}
#endif

#if OPT_DEC_CHRSET
static int
fakeDoubleChars(const XTermDraw * params,
		GC gc,
		int y,
		int x,
		const IChar *text,
		Cardinal len)
{
    unsigned need = 2 * len;
    IChar *temp = TypeMallocN(IChar, need);

    if (temp != NULL) {
	unsigned n = 0;
	XTermDraw recur = *params;

	recur.this_chrset = CSET_SWL;

	while (len--) {
	    temp[n++] = *text++;
	    temp[n++] = ' ';
	}
	x = drawXtermText(&recur,
			  gc,
			  x, y,
			  temp,
			  n);
	free(temp);
    }
    return x;
}
#endif /* OPT_DEC_CHRSET */

#define SetMissing(tag) \
	TRACE(("%s %s: missing %d %04X\n", __FILE__, tag, missing, ch)); \
	missing = 1

#define MaxImageString 255

#define UCS2SBUF(value)	buffer2[dst].byte2 = LO_BYTE(value);\
			buffer2[dst].byte1 = HI_BYTE(value)

#if OPT_WIDE_CHARS
static int
xtermDrawMissing(TScreen *screen, unsigned flags, GC gc,
		 int x, int y, int ncells, Bool fullWidth)
{
    /* *INDENT-EQLS* */
    int width   = FontWidth(screen) * ncells;
    int height  = FontHeight(screen);
    int descent = FontDescent(screen);
    int thick   = Max((height / 16), 1);
    int thick2  = 2 * thick;
    int yhigh   = height - thick2;
    int too_big = (flags & (DOUBLEWFONT | DOUBLEHFONT)) != 0;

    TRACE(("*missing [%4d,%4d] %dx%d (%d)/%d%s%s%s%s\n",
	   y, x,
	   height, width,
	   ncells,
	   descent,
	   flags ? " recur" : "",
	   flags & DOUBLEFIRST ? "*" : "",
	   flags & DOUBLEWFONT ? ":W" : "",
	   flags & DOUBLEHFONT ? ":H" : ""));
    if (width > thick2 && height > thick2) {
	if (too_big) {
	    if (flags & DOUBLEWFONT) {
		width *= 2;
	    }
	    if (flags & DOUBLEHFONT) {
		if (flags & DOUBLEFIRST) {
		    height *= 2;
		    height -= thick;
		} else {
		    height += thick;
		}
		descent *= 2;
	    }
	} else {
	    beginClipping(screen, gc, (Cardinal) width, (Cardinal) ncells);
	}
#if OPT_BOX_CHARS
	if (screen->force_all_chars)
#endif
	{
	    int xpos = x;
	    int ypos = (y - height + descent + thick);
	    unsigned high = (unsigned) yhigh;
	    unsigned wide = (unsigned) (width - thick2);

	    if (fullWidth)
		ncells /= 2;
	    setXtermLineAttributes(screen->display, gc, thick, LineOnOffDash);
	    XDrawImageString(screen->display, VDrawable(screen), gc,
			     x, y,
			     "    ",
			     Min(4, ncells));
	    XDrawRectangle(screen->display,
			   VDrawable(screen), gc,
			   xpos, ypos,
			   wide, high);
	    resetXtermLineAttributes(screen->display, gc);
	}
	if (!too_big) {
	    endClipping(screen, gc);
	}
    }
    return x + width;
}

static int
xtermPartString16(TScreen *screen, unsigned flags, GC gc, int x, int y, int length)
{
    if (length > 0) {
	IChar *mapped = BfBuf(IChar);
	XChar2b *buffer2 = BfBuf(XChar2b);
	Char *buffer1 = BfBuf(Char);
	int n;
	Bool eightBit = True;
	int ncells = 0;

	for (n = 0; n < length; ++n) {
	    IChar ch = mapped[n];
	    int bump = 1;
	    if (buffer2[n].byte1 != 0) {
		bump = CharWidth(screen, ch);
		bump = Max(1, bump);
		eightBit = False;
	    } else {
		buffer1[n] = buffer2[n].byte2;
	    }
	    ncells += bump;
	}

	if ((flags & NOBACKGROUND)) {
	    if (eightBit) {
		XDrawString(screen->display,
			    VDrawable(screen), gc,
			    x, y,
			    (char *) buffer1, length);
	    } else {
		XDrawString16(screen->display,
			      VDrawable(screen), gc,
			      x, y,
			      buffer2, length);
	    }
	} else {
	    int b_pos;
	    int b_max = MaxImageString;
	    for (b_pos = 0; b_pos < length; b_pos += b_max) {
		if (b_pos + b_max > length)
		    b_max = (length - b_pos);
		if (eightBit) {
		    XDrawImageString(screen->display,
				     VDrawable(screen), gc,
				     x + (b_pos * FontWidth(screen)),
				     y,
				     (char *) buffer1 + b_pos,
				     b_max);
		} else {
		    XDrawImageString16(screen->display,
				       VDrawable(screen), gc,
				       x + (b_pos * FontWidth(screen)),
				       y,
				       buffer2 + b_pos,
				       b_max);
		}
	    }
	}
	x += ncells * FontWidth(screen);
    }
    return x;
}

static int
xtermFullString16(XTermDraw * params, unsigned flags, GC gc,
		  int x, int y, int length, Bool fullwidth)
{
    XtermWidget xw = params->xw;
    TScreen *screen = TScreenOf(xw);
    int src, dst;
    IChar *mapped = BfBuf(IChar);
    XChar2b *buffer2 = BfBuf(XChar2b);
    VTwin *currentWin = WhichVWin(screen);
    XTermFonts *xf = getCgsFont(xw, currentWin, gc);
    XTermFonts *fn = getNormalFont(screen, fNorm);
    XTermFonts *fp = xf ? xf : fn;

    for (src = dst = 0; src < (int) length; src++) {
	IChar ch = mapped[src];
	int ch_width = CharWidth(screen, ch);
	/*
	 * X11 bitmap-fonts are limited to 16-bits.
	 */
	assert(ch != HIDDEN_CHAR);
	if (
#if OPT_WIDER_ICHAR
	       (ch > NARROW_ICHAR) ||
#endif
	       xtermMissingChar(ch,
				(((xf >= fn) && (xf - fn) < fMAX)
				 ? XTermFontsRef(screen->fnts,
						 (VTFontEnum) (xf - fn))
				 : fp))) {
	    unsigned part = ucs2dec(screen, ch);
	    if (xtermIsDecGraphic(part) && ch > 255)
		ch = (IChar) part;
	    x = xtermPartString16(screen, flags, gc, x, y, dst);
	    if (xtermIsInternalCs(ch)) {
		xtermDrawBoxChar(params, ch, gc,
				 x, y - FontAscent(screen), 1, False);
		x += FontWidth(screen);
	    } else {
		x = xtermDrawMissing(screen, flags, gc, x, y, ch_width, fullwidth);
	    }
	    dst = 0;
	} else {
	    UCS2SBUF(ch);
	    ++dst;
	}
    }

    x = xtermPartString16(screen, flags, gc, x, y, dst);
    return x;
}
#endif /* OPT_WIDE_CHARS */

static void
xtermPartString(TScreen *screen, unsigned flags, GC gc, int x, int y, int length)
{
    Char *buffer1 = BfBuf(Char);

    if ((flags & NOBACKGROUND)) {
	XDrawString(screen->display, VDrawable(screen), gc,
		    x, y, (char *) buffer1, length);
    } else {
	int b_pos;
	int b_max = MaxImageString;
	for (b_pos = 0; b_pos < length; b_pos += b_max) {
	    if (b_pos + b_max > length)
		b_max = (length - b_pos);
	    XDrawImageString(screen->display,
			     VDrawable(screen), gc,
			     x + (b_pos * FontWidth(screen)),
			     y,
			     (char *) (buffer1 + b_pos),
			     b_max);
	}
    }
}

static void
xtermDrawString(TScreen *screen, unsigned flags, GC gc, int x, int y, int length)
{
    IChar *mapped = BfBuf(IChar);
    Char *buffer1 = BfBuf(Char);

    int dst;

    for (dst = 0; dst < length; ++dst)
	buffer1[dst] = (Char) LO_BYTE(mapped[dst]);

    xtermPartString(screen, flags, gc, x, y, length);
}

/*
 * Draws text with the specified combination of bold/underline.  The return
 * value is the updated x position.
 */
int
drawXtermText(const XTermDraw * params,
	      GC gc,
	      int start_x,
	      int start_y,
	      const IChar *text,
	      Cardinal len)
{
    XTermDraw recur = *params;
    TScreen *screen = TScreenOf(recur.xw);
    int x = start_x;
    int y = start_y;
    int y_shift = ScaleShift(screen);
    Cardinal real_length = len;
    Cardinal underline_len = 0;
    /* Intended width of the font to draw (as opposed to the actual width of
       the X font, and the width of the default font) */
    int font_width = (((recur.draw_flags & DOUBLEWFONT) ? 2 : 1)
		      * screen->fnt_wide);
    Bool did_ul = False;
    XTermFonts *curFont;

#if OPT_WIDE_ATTRS
    int need_clipping = 0;
#endif

#if OPT_WIDE_CHARS
    Bool need_wide;
#endif

#if OPT_WIDE_CHARS
    if (text == NULL)
	return 0;
#endif
    TRACE(("DRAWTEXT%c[%4d,%4d] (%d)%3d:%s\n",
	   screen->cursor_state == OFF ? ' ' : '*',
	   y, x, recur.this_chrset, len,
	   visibleIChars(text, len)));

#if OPT_DEC_CHRSET
    if (CSET_DOUBLE(recur.this_chrset)) {
	/* We could try drawing double-size characters in the icon, but
	 * given that the icon font is usually nil or nil2, there
	 * doesn't seem to be much point.
	 */
	int inx = 0;
	GC gc2;

#if OPT_RENDERFONT
	if (UsingRenderFont(recur.xw)) {
	    if (!IsIcon(screen) && screen->font_doublesize) {
		int next;
		TRACE(("drawing %s\n", visibleDblChrset((unsigned) recur.this_chrset)));
		recur.real_chrset = recur.this_chrset;
		recur.this_chrset = CSET_SWL;
		next = drawXtermText(&recur,
				     gc,
				     x, y,
				     text,
				     len);
		x += (next - x) * 2;
	    } else {
		x = fakeDoubleChars(&recur,
				    gc, y, x,
				    text, len);
	    }
	} else
#endif
	    if ((!IsIcon(screen) && screen->font_doublesize)
		&& (gc2 = xterm_DoubleGC(&recur, gc, &inx)) != NULL) {
	    /* draw actual double-sized characters */
	    XFontStruct *fs = getDoubleFont(screen, inx)->fs;
	    XRectangle rect, *rp = ▭
	    Cardinal nr = 1;
	    Cardinal nlen;
	    int ncells = (int) len;

	    font_width *= 2;
	    recur.draw_flags |= DOUBLEWFONT;

	    for (nlen = 0; nlen < len; ++nlen) {
		int ch_width = CharWidth(screen, text[nlen]);
		if (ch_width > 1)
		    ncells += (ch_width - 1);
	    }

	    rect.x = 0;
	    rect.y = 0;
	    rect.width = (unsigned short) (ncells * font_width);
	    rect.height = (unsigned short) (FontHeight(screen));

	    TRACE(("drawing %s\n", visibleDblChrset((unsigned) recur.this_chrset)));
	    switch (recur.this_chrset) {
	    case CSET_DHL_TOP:
		rect.y = (short) -(fs->ascent / 2);
		y -= rect.y;
		recur.draw_flags |= (DOUBLEHFONT | DOUBLEFIRST);
		break;
	    case CSET_DHL_BOT:
		rect.y = (short) (rect.height - (fs->ascent / 2));
		y -= rect.y;
		recur.draw_flags |= DOUBLEHFONT;
		recur.draw_flags &= (unsigned) ~DOUBLEFIRST;
		break;
	    case CSET_DWL:
		break;
	    default:
		nr = 0;
		break;
	    }

	    if (nr) {
		xtermSetClipRectangles(screen->display, gc2,
				       x, y, rp, nr, YXBanded);
		xtermFillCells(&recur, gc, x, y + rect.y,
			       (Cardinal) ncells * 2);
	    } else {
		XSetClipMask(screen->display, gc2, None);
	    }

	    /* Call ourselves recursively with the new gc */

	    /*
	     * If we're trying to use proportional font, or if the
	     * font server didn't give us what we asked for wrt
	     * width, position each character independently.
	     */
	    if (screen->fnt_prop
		|| (fs->min_bounds.width != fs->max_bounds.width)
		|| (fs->min_bounds.width != 2 * FontWidth(screen))) {
		/* It is hard to fall-through to the main
		   branch: in a lot of places the check
		   for the cached font info is for
		   normal/bold fonts only. */
		XTermDraw param2 = recur;
		param2.this_chrset = CSET_SWL;
		while (len--) {
		    int next = drawXtermText(¶m2,
					     gc2,
					     x, y,
					     text++,
					     1);
		    x += (next - x) * 2;
		}
	    } else {
		int next;
		XTermDraw param2 = recur;
		param2.this_chrset = CSET_SWL;
		next = drawXtermText(¶m2,
				     gc2,
				     x, y,
				     text,
				     len);
		x += (next - x) * 2;
	    }

	} else {		/* simulate double-sized characters */
	    x = fakeDoubleChars(&recur,
				gc, y, x,
				text, len);
	}
	TRACE(("DrewText [%4d,%4d] @%d\n", y, x, __LINE__));
	return x;
    }
#endif
#if OPT_RENDERFONT
    if (UsingRenderFont(recur.xw)) {
	VTwin *currentWin = WhichVWin(screen);
	Display *dpy = screen->display;
	XTermXftFonts *ndata;
	XGCValues values;
#if OPT_WIDE_CHARS && OPT_BOX_CHARS
	XTermXftFonts *ndata0;
#endif
#if OPT_RENDERWIDE && OPT_BOX_CHARS
	XTermXftFonts *wdata;
	XTermXftFonts *wdata0;
#endif
	int ncells = 0;

#if OPT_DEC_CHRSET
	/*
	 * If this is a VT100-style double-width font, ensure that everything
	 * is printed using two-columns per character.
	 */
	Boolean forceDbl = CSET_DOUBLE(recur.real_chrset);
#else
	Boolean forceDbl = False;
#endif

	(void) forceDbl;
	/*
	 * Defer creating the drawable until we need it.
	 */
	if (!screen->renderDraw) {
	    int scr;
	    Drawable draw = VDrawable(screen);
	    Visual *visual;

	    scr = DefaultScreen(dpy);
	    visual = DefaultVisual(dpy, scr);
	    screen->renderDraw = XftDrawCreate(dpy, draw, visual,
					       DefaultColormap(dpy, scr));
	}

	/*
	 * ndata0/wdata0 provide fallback to non-bolded Xft font if a glyph is
	 * not found in the bold version.
	 */
#define IS_BOLD  (recur.attr_flags & BOLDATTR(screen))
#define NOT_BOLD (recur.attr_flags & ~BOLDATTR(screen))
	ndata = getNormXftFont(&recur, recur.attr_flags, &did_ul);
#if OPT_WIDE_CHARS && OPT_BOX_CHARS
	ndata0 = IS_BOLD ? getNormXftFont(&recur, NOT_BOLD, &did_ul) : ndata;
#endif
#if OPT_RENDERWIDE && OPT_BOX_CHARS
	wdata = getWideXftFont(&recur, recur.attr_flags);
	wdata0 = IS_BOLD ? getWideXftFont(&recur, NOT_BOLD) : wdata;
#endif

#define GET_XFT_FG() getXftColor(recur.xw, values.foreground)
#define GET_XFT_BG() getXftColor(recur.xw, values.background)

	values.foreground = getCgsFore(recur.xw, currentWin, gc);
	values.background = getCgsBack(recur.xw, currentWin, gc);

	if (!(recur.draw_flags & NOBACKGROUND)) {
	    XftColor *bg_color = GET_XFT_BG();
	    int nc = xtermXftWidth(&recur, recur.attr_flags,
				   bg_color,
				   XftFp(ndata), x, y,
				   text,
				   len);
	    XftDrawRect(screen->renderDraw,
			bg_color,
			x, y,
			(unsigned) (nc * FontWidth(screen)),
			(unsigned) FontHeight(screen));
	}

	y += XftFp(ndata)->ascent;
#if OPT_BOX_CHARS
	{
	    /* adding code to substitute simulated line-drawing characters */
	    int last, first = 0;
	    int curX = x;

	    for (last = 0; last < (int) len; last++) {
		Boolean replace = False;
		Boolean missing = False;
		unsigned ch = (unsigned) text[last];
		int ch_width = CharWidth(screen, ch);
		int filler = 0;
#if OPT_WIDE_CHARS
		int needed = forceDbl ? 2 : ch_width;
		XTermXftFonts *currData = pickXftData(needed, ndata, wdata);
		XftFont *tempFont = NULL;
#define CURR_TEMP (tempFont ? tempFont : XftFp(currData))

		if (xtermIsInternalCs(ch) || ch == 0) {
		    /*
		     * Xft generally does not have the line-drawing characters
		     * in cells 0-31.  Assume this (we cannot inspect the
		     * picture easily...), and attempt to fill in from real
		     * line-drawing character in the font at the Unicode
		     * position.  Failing that, use our own box-characters.
		     */
		    if (screen->force_box_chars
			|| screen->broken_box_chars
			|| xtermXftMissing(recur.xw,
					   currData, 0,
					   XftFp(currData),
					   dec2ucs(screen, ch))) {
			SetMissing("case 1");
		    } else {
			ch = dec2ucs(screen, ch);
			replace = True;
		    }
		} else if (ch >= 256) {
		    /*
		     * If we're reading UTF-8 from the client, we may have a
		     * line-drawing character.  Translate it back to our
		     * box-code if Xft tells us that the glyph is missing.
		     */
		    if_OPT_WIDE_CHARS(screen, {
			unsigned part = ucs2dec(screen, ch);
			if (xtermIsInternalCs(part)) {
			    if (screen->force_box_chars
				|| xtermXftMissing(recur.xw,
						   currData, 0,
						   XftFp(currData), ch)) {
				SetMissing("case 2");
				ch = part;
			    }
			}
			if (!missing && xtermXftMissing(recur.xw,
							currData, 0,
							XftFp(currData), ch)) {
			    int found = findXftGlyph(recur.xw, currData, ch);
			    XftFont *test;
			    if (found >= 0) {
				test = XftFpN(currData, found);
			    } else {
				test = pickXftFont(needed,
						   XftFp(ndata0),
						   XftFp(wdata0));
			    }
			    if (!xtermXftMissing(recur.xw,
						 currData, found,
						 test, ch)) {
				tempFont = test;
				replace = True;
				filler = 0;
			    } else if ((part = AsciiEquivs(ch)) != ch) {
				filler = needed - 1;
				ch = part;
				replace = True;
			    } else if (ch != HIDDEN_CHAR) {
				SetMissing("case 3");
			    }
			}
		    });
		}
#else
		XTermXftFonts *currData = ndata;
#define CURR_TEMP XftFp(currData)
		if (xtermIsInternalCs(ch)) {
		    /*
		     * Xft generally does not have the line-drawing characters
		     * in cells 1-31.  Check for this, and attempt to fill in
		     * from real line-drawing character in the font at the
		     * Unicode position.  Failing that, use our own
		     * box-characters.
		     */
		    if (xtermXftMissing(recur.xw,
					currData, 0,
					XftFp(currData), ch)) {
			SetMissing("case 4");
		    }
		}
#endif

		/*
		 * If we now have one of our box-codes, draw it directly.
		 */
		if (missing || replace) {
		    /* line drawing character time */
		    if (last > first) {
			int nc = drawClippedXftString(&recur,
						      recur.attr_flags,
						      XftFp(currData),
						      GET_XFT_FG(),
						      curX,
						      y,
						      text + first,
						      (Cardinal) (last - first));
			curX += nc * FontWidth(screen);
			underline_len += (Cardinal) nc;
		    }
		    if (missing) {
			Dimension old_wide = screen->fnt_wide;
			Dimension old_high = screen->fnt_high;
			screen->fnt_wide = (Dimension) FontWidth(screen);
			screen->fnt_high = (Dimension) FontHeight(screen);

			xtermDrawBoxChar(&recur, ch,
					 gc,
					 curX,
					 y - FontAscent(screen),
					 1,
					 True);
			curX += FontWidth(screen);
			underline_len += 1;
			screen->fnt_wide = old_wide;
			screen->fnt_high = old_high;
		    } else {
			IChar ch2 = (IChar) ch;
			int nc = drawClippedXftString(&recur,
						      recur.attr_flags,
						      CURR_TEMP,
						      GET_XFT_FG(),
						      curX,
						      y,
						      &ch2,
						      1);
			curX += nc * FontWidth(screen);
			underline_len += (Cardinal) nc;
			if (filler) {
			    ch2 = ' ';
			    nc = drawClippedXftString(&recur,
						      recur.attr_flags,
						      CURR_TEMP,
						      GET_XFT_FG(),
						      curX,
						      y,
						      &ch2,
						      1);
			    curX += nc * FontWidth(screen);
			    underline_len += (Cardinal) nc;
			}
		    }
		    first = last + 1;
		}
		if (ch_width > 0)
		    ncells += ch_width;
	    }
	    if (last > first) {
		int nc = drawClippedXftString(&recur,
					      recur.attr_flags,
					      XftFp(ndata),
					      GET_XFT_FG(),
					      curX,
					      y,
					      text + first,
					      (Cardinal) (last - first));
		underline_len += (Cardinal) nc;
	    }
	}
#else
	{
	    int nc = drawClippedXftString(&recur,
					  recur.attr_flags,
					  XftFp(ndata),
					  GET_XFT_FG(),
					  x,
					  y,
					  text,
					  len);
	    underline_len += (Cardinal) nc;
	    ncells = nc;
	}
#endif /* OPT_BOX_CHARS */

	drawUnderline(recur.xw,
		      gc,
		      recur.attr_flags,
		      underline_len,
		      FontWidth(screen),
		      x,
		      y + y_shift,
		      did_ul);

	x += (int) ncells *FontWidth(screen);

	TRACE(("DrewText [%4d,%4d] @%d\n", y, x, __LINE__));
	return x;
    }
#endif /* OPT_RENDERFONT */
    curFont = ((recur.attr_flags & BOLDATTR(screen))
	       ? WhichVFontData(screen, fBold)
	       : WhichVFontData(screen, fNorm));
    /*
     * If we're asked to display a proportional font, do this with a fixed
     * pitch.  Yes, it's ugly.  But we cannot distinguish the use of xterm
     * as a dumb terminal vs its use as in fullscreen programs such as vi.
     * Hint: do not try to use a proportional font in the icon.
     */
    if (!IsIcon(screen) && !(recur.draw_flags & CHARBYCHAR) && screen->fnt_prop) {
	int adj, width;

	while (len--) {
	    int cells = WideCells(*text);
#if OPT_BOX_CHARS
#if OPT_WIDE_CHARS
	    if (*text == HIDDEN_CHAR) {
		++text;
		continue;
	    } else
#endif
	    if (IsXtermMissingChar(screen, *text, curFont)) {
		adj = 0;
	    } else
#endif
	    {
		if_WIDE_OR_NARROW(screen, {
		    XChar2b temp[1];
		    temp[0].byte2 = LO_BYTE(*text);
		    temp[0].byte1 = HI_BYTE(*text);
		    width = XTextWidth16(curFont->fs, temp, 1);
		}
		, {
		    char temp[1];
		    temp[0] = (char) LO_BYTE(*text);
		    width = XTextWidth(curFont->fs, temp, 1);
		});
		adj = (FontWidth(screen) - width) / 2;
		if (adj < 0)
		    adj = 0;
	    }
	    xtermFillCells(&recur, gc, x, y, (Cardinal) cells);
	    recur.draw_flags |= (NOBACKGROUND | CHARBYCHAR);
	    x = drawXtermText(&recur,
			      gc, x + adj, y,
			      text++, 1) - adj;
	}

	TRACE(("DrewText [%4d,%4d] @%d\n", y, x, __LINE__));
	return x;
    }
#if OPT_BOX_CHARS
    /*
     * Draw some substitutions, if needed.  The font may not include the
     * line-drawing set, or it may be incomplete (in which case we'll draw an
     * empty space via xtermDrawBoxChar), or we may be told to force our
     * line-drawing.
     *
     * The empty space is a special case which can be overridden with the
     * showMissingGlyphs resource to produce an outline.  Not all fonts in
     * "modern" (sic) X provide an empty space; some use a thick outline or
     * something like the replacement character.  If you would rather not see
     * that, you can set assumeAllChars.
     */
    if (!IsIcon(screen)
	&& !(recur.draw_flags & NOTRANSLATION)
	&& (!screen->fnt_boxes
	    || (FontIsIncomplete(curFont) && !screen->assume_all_chars)
	    || recur.xw->work.force_wideFont
	    || screen->force_box_chars)) {
	/*
	 * Fill in missing box-characters.  Find regions without missing
	 * characters, and draw them calling ourselves recursively.  Draw
	 * missing characters via xtermDrawBoxChar().
	 */
	int last, first = 0;
	Bool drewBoxes = False;

	for (last = 0; last < (int) len; last++) {
	    unsigned ch = (unsigned) text[last];
	    Bool isMissing;
	    int ch_width;
#if OPT_WIDE_CHARS
	    unsigned part;

	    if (ch == HIDDEN_CHAR) {
		if (last > first) {
		    XTermDraw param2 = recur;
		    param2.draw_flags |= NOTRANSLATION;
		    x = drawXtermText(¶m2,
				      gc,
				      x, y,
				      text + first,
				      (unsigned) (last - first));
		}
		first = last + 1;
		drewBoxes = True;
		continue;
	    }
	    ch_width = CharWidth(screen, ch);
	    isMissing =
		IsXtermMissingChar(screen, ch,
				   ((recur.on_wide || ch_width > 1)
				    && okFont(NormalWFont(screen)))
				   ? WhichVFontData(screen, fWide)
				   : curFont);
#else
	    isMissing = IsXtermMissingChar(screen, ch, curFont);
	    ch_width = 1;
#endif
	    /*
	     * If the character is not missing, but we're in wide-character
	     * mode and the character happens to be a wide-character that
	     * corresponds to the line-drawing set, allow the forceBoxChars
	     * resource (or menu entry) to force it to display using our
	     * tables.
	     */
	    if_OPT_WIDE_CHARS(screen, {
		if (!isMissing
		    && TScreenOf(recur.xw)->force_box_chars) {
		    if (ch > 255
			&& (part = ucs2dec(screen, ch)) < 32) {
			ch = part;
			isMissing = True;
		    } else if (ch < 32) {
			isMissing = True;
		    }
		}
	    });

	    if (isMissing) {
		if (last > first) {
		    XTermDraw param2 = recur;
		    param2.draw_flags |= NOTRANSLATION;
		    x = drawXtermText(&recur,
				      gc,
				      x, y,
				      text + first,
				      (unsigned) (last - first));
		}
#if OPT_WIDE_CHARS
		if (ch_width <= 0 && ch < 32)
		    ch_width = 1;	/* special case for line-drawing */
		else if (ch_width < 0)
		    ch_width = 1;	/* special case for combining char */
		if (ch > 255 && (part = ucs2dec(screen, ch)) < 32) {
		    xtermDrawBoxChar(&recur, part, gc, x, y, 1, False);
		} else if (!ucs_workaround(&recur, ch, gc, x, y)) {
		    xtermDrawBoxChar(&recur, ch, gc, x, y, ch_width, False);
		}
#else
		xtermDrawBoxChar(&recur, ch, gc, x, y, ch_width, False);
#endif
		x += (ch_width * FontWidth(screen));
		first = last + 1;
		drewBoxes = True;
	    } else if (ch_width == 2
		       && recur.xw->work.force_wideFont
		       && !(recur.draw_flags & NOTRANSLATION)) {
		XTermDraw param2 = recur;
		param2.draw_flags |= NOTRANSLATION;
		/*
		 * Not a "box" character, but a special case treated similarly.
		 */
		(void) drawXtermText(¶m2,
				     gc,
				     x, y,
				     text + first,
				     (unsigned) (1 + last - first));
		x += (ch_width * FontWidth(screen));
		first = last + 1;
		drewBoxes = True;
	    }
	}
	if (last <= first) {
	    TRACE(("DrewText [%4d,%4d] @%d\n", y, x, __LINE__));
	    return x;
	}
	text += first;
	len = (Cardinal) (last - first);
	recur.draw_flags |= NOTRANSLATION;
	if (drewBoxes) {
	    x = drawXtermText(&recur,
			      gc,
			      x,
			      y,
			      text,
			      len);
	    TRACE(("DrewText [%4d,%4d] @%d\n", y, x, __LINE__));
	    return x;
	}
    }
#endif /* OPT_BOX_CHARS */
    /*
     * Behave as if the font has (maybe Unicode-replacements for) drawing
     * characters in the range 1-31 (either we were not asked to ignore them,
     * or the caller made sure that there is none).
     */
#if OPT_WIDE_ATTRS
#define AttrFlags() recur.attr_flags
#define DrawFlags() recur.draw_flags
#else
#define AttrFlags() (recur.attr_flags & DRAWX_MASK)
#define DrawFlags() (recur.draw_flags & (unsigned)~DRAWX_MASK)
#endif
    TRACE(("drawtext%c[%4d,%4d] {%#x,%#x} (%d) %d:%s\n",
	   screen->cursor_state == OFF ? ' ' : '*',
	   y, x,
	   AttrFlags(),
	   DrawFlags(),
	   recur.this_chrset, len,
	   visibleIChars(text, len)));
    if (screen->scale_height != 1.0f) {
	xtermFillCells(&recur, gc, x, y, (Cardinal) len);
    }
    y += FontAscent(screen);

#if OPT_WIDE_CHARS

    need_wide = False;
    if (screen->wide_chars || screen->unicode_font) {
	int src;
	for (src = 0; src < (int) len; src++) {
	    IChar ch = text[src];
	    if (ch > 0xff) {
		need_wide = True;
		break;
	    }
	}
    }

    if (need_wide) {
	IChar *mapped;
	Bool needWide = False;
	int src, dst;
	Bool useBoldFont;
	int ascent_adjust = 0;

	BumpTypedBuffer(XChar2b, len);
	BumpTypedBuffer(Char, len);
	BumpTypedBuffer(IChar, len);
	mapped = BfBuf(IChar);

	/* transform characters first, to decide how to draw them */
	for (src = 0; src < (int) len; src++) {
	    IChar ch = text[src];
	    if (ch != HIDDEN_CHAR) {
#if OPT_BOX_CHARS
		if ((screen->fnt_boxes == 1) && (ch >= 256)) {
		    unsigned part = ucs2dec(screen, ch);
		    if (part < 32)
			ch = (IChar) part;
		}
#endif
#if OPT_MINI_LUIT
#define Map2Sbuf(from,to) (ch == from) { ch = to; }
		if (screen->latin9_mode && !screen->utf8_mode && ch < 256) {

		    /* see http://www.cs.tut.fi/~jkorpela/latin9.html */
		    /* *INDENT-OFF* */
		    if Map2Sbuf(0xa4, 0x20ac)
		    else if Map2Sbuf(0xa6, 0x0160)
		    else if Map2Sbuf(0xa8, 0x0161)
		    else if Map2Sbuf(0xb4, 0x017d)
		    else if Map2Sbuf(0xb8, 0x017e)
		    else if Map2Sbuf(0xbc, 0x0152)
		    else if Map2Sbuf(0xbd, 0x0153)
		    else if Map2Sbuf(0xbe, 0x0178)
		    /* *INDENT-ON* */

		}
		if (screen->unicode_font
		    && (ch == ANSI_DEL ||
			ch < ANSI_SPA)) {
		    ch = (IChar) dec2ucs(screen,
					 (unsigned) ((ch == ANSI_DEL) ? 0 : ch));
		}
#endif /* OPT_MINI_LUIT */
	    }
	    mapped[src] = ch;
	}

	for (src = dst = 0; src < (int) len; src++) {
	    IChar ch = mapped[src];

	    if (ch != HIDDEN_CHAR) {
		int ch_width = CharWidth(screen, ch);
		if (!needWide
		    && !IsIcon(screen)
		    && ((recur.on_wide || ch_width > 1)
			&& okFont(NormalWFont(screen)))) {
		    needWide = True;
		}
		mapped[dst++] = ch;
	    }
	}

	/*
	 * Check for special case where the bold font lacks glyphs found in the
	 * normal font, and drop down to normal fonts with overstriking to help
	 * show the actual characters.
	 */
	useBoldFont = ((recur.attr_flags & BOLDATTR(screen)) != 0);
	if (useBoldFont) {
	    XTermFonts *norm = NULL;
	    XTermFonts *bold = NULL;
	    Bool noBold, noNorm;

	    (void) norm;
	    if (needWide && okFont(BoldWFont(screen))) {
		norm = WhichVFontData(screen, fWide);
		bold = WhichVFontData(screen, fWBold);
	    } else if (okFont(BoldFont(screen))) {
		norm = WhichVFontData(screen, fNorm);
		bold = WhichVFontData(screen, fBold);
	    } else {
		useBoldFont = False;
	    }

	    if (useBoldFont && FontIsIncomplete(bold)) {
		for (src = 0; src < dst; src++) {
		    IChar ch = mapped[src];

		    (void) ch;
		    noBold = IsXtermMissingChar(screen, ch, bold);
		    if (noBold) {
			noNorm = IsXtermMissingChar(screen, ch, norm);
			if (!noNorm) {
			    useBoldFont = False;
			    break;
			}
		    }
		}
	    }
	}

	/* This is probably wrong. But it works. */
	underline_len = (Cardinal) dst;

	/* Set the drawing font */
	if (!(recur.draw_flags & (DOUBLEHFONT | DOUBLEWFONT))) {
	    VTwin *currentWin = WhichVWin(screen);
	    VTFontEnum fntId;
	    CgsEnum cgsId;
	    Pixel fg = getCgsFore(recur.xw, currentWin, gc);
	    Pixel bg = getCgsBack(recur.xw, currentWin, gc);

	    if (needWide
		&& useBoldFont
		&& okFont(BoldWFont(screen))) {
		fntId = fWBold;
		cgsId = gcWBold;
	    } else if (needWide) {
		fntId = fWide;
		cgsId = gcWide;
	    } else if (useBoldFont) {
		fntId = fBold;
		cgsId = gcBold;
	    } else {
		fntId = fNorm;
		cgsId = gcNorm;
	    }

	    setCgsFore(recur.xw, currentWin, cgsId, fg);
	    setCgsBack(recur.xw, currentWin, cgsId, bg);
	    gc = getCgsGC(recur.xw, currentWin, cgsId);

#if OPT_WIDE_ATTRS
#if OPT_DEC_CHRSET
	    if (!(CSET_DOUBLE(recur.this_chrset) || (recur.draw_flags & DOUBLEWFONT)))
#endif
	    {
		need_clipping = fixupItalics(&recur,
					     gc,
					     getCgsFont(recur.xw,
							currentWin, gc),
					     y, x, font_width, len);
	    }
#endif
	    if (fntId != fNorm) {
		XFontStruct *thisFp = WhichVFont(screen, fntId);
		ascent_adjust = (thisFp->ascent
				 - NormalFont(screen)->ascent);
		if (thisFp->max_bounds.width ==
		    NormalFont(screen)->max_bounds.width * 2) {
		    underline_len = real_length = (Cardinal) (dst * 2);
		} else if (cgsId == gcWide || cgsId == gcWBold) {
		    int ascent2 = Max(NormalFont(screen)->ascent,
				      thisFp->ascent);
		    underline_len = real_length = (Cardinal) (dst * 2);
		    xtermFillCells(&recur,
				   gc,
				   x,
				   y - ascent2,
				   real_length);
		}
	    }
	}

	xtermFullString16(&recur, recur.draw_flags, gc,
			  x, y + y_shift + ascent_adjust,
			  dst, needWide);
#if OPT_WIDE_ATTRS
	if (need_clipping) {
	    endClipping(screen, gc);
	}
#endif

	if ((recur.attr_flags & BOLDATTR(screen)) && (screen->enbolden || !useBoldFont)) {
	    if (!(recur.draw_flags & (DOUBLEWFONT | DOUBLEHFONT))) {
		beginClipping(screen, gc, (Cardinal) font_width, len);
	    }
	    xtermFullString16(&recur, recur.draw_flags | NOBACKGROUND,
			      gc, x + 1, y + y_shift + ascent_adjust,
			      dst, needWide);
	    if (!(recur.draw_flags & (DOUBLEWFONT | DOUBLEHFONT))) {
		endClipping(screen, gc);
	    }
	}

    } else
#endif /* OPT_WIDE_CHARS */
    {
	IChar *mapped;
	Cardinal dst;

	BumpTypedBuffer(IChar, len);
	BumpTypedBuffer(Char, len);

	mapped = BfBuf(IChar);
	for (dst = 0; dst < len; ++dst)
	    mapped[dst] = text[dst];

#if OPT_WIDE_ATTRS
#if OPT_DEC_CHRSET
	if (!(CSET_DOUBLE(recur.this_chrset) || (recur.draw_flags & DOUBLEWFONT)))
#endif
	{
	    need_clipping = fixupItalics(&recur, gc, curFont,
					 y, x, font_width, len);
	}
#endif

	xtermDrawString(screen, recur.draw_flags, gc,
			x, y + y_shift, (int) len);

#if OPT_WIDE_ATTRS
	if (need_clipping) {
	    endClipping(screen, gc);
	}
#endif
	underline_len = len;
	if ((recur.attr_flags & BOLDATTR(screen)) && screen->enbolden) {
	    if (!(recur.draw_flags & (DOUBLEWFONT | DOUBLEHFONT))) {
		beginClipping(screen, gc, font_width, (int) len);
	    }
	    xtermDrawString(screen, (recur.draw_flags | NOBACKGROUND),
			    gc, x + 1, y + y_shift, (int) len);
	    if (!(recur.draw_flags & (DOUBLEWFONT | DOUBLEHFONT))) {
		endClipping(screen, gc);
	    }
	}
    }

    drawUnderline(recur.xw,
		  gc,
		  recur.attr_flags,
		  underline_len,
		  font_width,
		  x,
		  y + y_shift,
		  did_ul);

    x += ((int) real_length) * FontWidth(screen);
    TRACE(("DrewText [%4d,%4d] @%d\n", y, x, __LINE__));
    return x;
}

#if OPT_WIDE_CHARS
/*
 * Allocate buffer - workaround for wide-character interfaces.
 */
void
allocXtermChars(ScrnPtr *buffer, Cardinal length)
{
    if (*buffer == NULL) {
	*buffer = (ScrnPtr) XtMalloc(length);
    } else {
	*buffer = (ScrnPtr) XtRealloc((char *) *buffer, length);
    }
}
#endif

/* set up size hints for window manager; min 1 char by 1 char */
void
xtermSizeHints(XtermWidget xw, int scrollbarWidth)
{
    TScreen *screen = TScreenOf(xw);

    TRACE(("xtermSizeHints\n"));
    TRACE(("   border    %d\n", xw->core.border_width));
    TRACE(("   scrollbar %d\n", scrollbarWidth));

    xw->hints.base_width = 2 * screen->border + scrollbarWidth;
    xw->hints.base_height = 2 * screen->border;

#if OPT_TOOLBAR
    TRACE(("   toolbar   %d\n", ToolbarHeight(xw)));

    xw->hints.base_height += ToolbarHeight(xw);
    xw->hints.base_height += BorderWidth(xw) * 2;
    xw->hints.base_width += BorderWidth(xw) * 2;
#endif

    if (xw->misc.resizeByPixel) {
	xw->hints.width_inc = 1;
	xw->hints.height_inc = 1;
    } else {
	xw->hints.width_inc = FontWidth(screen);
	xw->hints.height_inc = FontHeight(screen);
    }
    xw->hints.min_width = xw->hints.base_width + xw->hints.width_inc;
    xw->hints.min_height = xw->hints.base_height + xw->hints.height_inc;

    xw->hints.width = MaxCols(screen) * FontWidth(screen) + xw->hints.min_width;
    xw->hints.height = MaxRows(screen) * FontHeight(screen) + xw->hints.min_height;

    xw->hints.flags |= (PSize | PBaseSize | PMinSize | PResizeInc);

    TRACE_HINTS(&(xw->hints));
}

void
getXtermSizeHints(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    long supp;

    if (!XGetWMNormalHints(screen->display, VShellWindow(xw),
			   &xw->hints, &supp))
	memset(&xw->hints, 0, sizeof(xw->hints));
    TRACE_HINTS(&(xw->hints));
}

CgsEnum
whichXtermCgs(XtermWidget xw, unsigned attr_flags, Bool hilite)
{
    TScreen *screen = TScreenOf(xw);
    CgsEnum cgsId = gcMAX;

    if (ReverseOrHilite(screen, attr_flags, hilite)) {
	if (attr_flags & BOLDATTR(screen)) {
	    cgsId = gcBoldReverse;
	} else {
	    cgsId = gcNormReverse;
	}
    } else {
	if (attr_flags & BOLDATTR(screen)) {
	    cgsId = gcBold;
	} else {
	    cgsId = gcNorm;
	}
    }
    return cgsId;
}

/*
 * Returns a GC, selected according to the font (reverse/bold/normal) that is
 * required for the current position (implied).  The GC is updated with the
 * current screen foreground and background colors.
 */
GC
updatedXtermGC(XtermWidget xw, unsigned attr_flags, CellColor fg_bg,
	       Bool hilite)
{
    TScreen *screen = TScreenOf(xw);
    VTwin *win = WhichVWin(screen);
    CgsEnum cgsId = whichXtermCgs(xw, attr_flags, hilite);
    Pixel my_fg = extract_fg(xw, fg_bg, attr_flags);
    Pixel my_bg = extract_bg(xw, fg_bg, attr_flags);
    Pixel fg_pix = getXtermFG(xw, attr_flags, (int) my_fg);
    Pixel bg_pix = getXtermBG(xw, attr_flags, (int) my_bg);
    Pixel xx_pix;
#if OPT_HIGHLIGHT_COLOR
    Boolean reverse2 = ((attr_flags & INVERSE) && hilite);
    Pixel selbg_pix = T_COLOR(screen, HIGHLIGHT_BG);
    Pixel selfg_pix = T_COLOR(screen, HIGHLIGHT_FG);
    Boolean always = screen->hilite_color;
    Boolean use_selbg = (Boolean) (always &&
				   isNotForeground(xw, fg_pix, bg_pix, selbg_pix));
    Boolean use_selfg = (Boolean) (always &&
				   isNotBackground(xw, fg_pix, bg_pix, selfg_pix));
#endif

    (void) fg_bg;
    (void) my_bg;
    (void) my_fg;

    /*
     * Discard video attributes overridden by colorXXXMode's.
     */
    checkVeryBoldColors(attr_flags, my_fg);

    if (ReverseOrHilite(screen, attr_flags, hilite)) {
#if OPT_HIGHLIGHT_COLOR
	if (!screen->hilite_color) {
	    if (selbg_pix != T_COLOR(screen, TEXT_FG)
		&& selbg_pix != fg_pix
		&& selbg_pix != bg_pix
		&& selbg_pix != xw->dft_foreground) {
		bg_pix = fg_pix;
		fg_pix = selbg_pix;
	    }
	}
#endif
	EXCHANGE(fg_pix, bg_pix, xx_pix);
#if OPT_HIGHLIGHT_COLOR
	if (screen->hilite_color) {
	    if (screen->hilite_reverse) {
		if (use_selbg) {
		    if (use_selfg) {
			bg_pix = fg_pix;
		    } else {
			fg_pix = bg_pix;
			bg_pix = selbg_pix;
		    }
		}
		if (use_selfg)
		    fg_pix = selfg_pix;
	    }
	}
#endif
    } else if ((attr_flags & INVERSE) && hilite) {
#if OPT_HIGHLIGHT_COLOR
	if (!screen->hilite_color) {
	    if (selbg_pix != T_COLOR(screen, TEXT_FG)
		&& selbg_pix != fg_pix
		&& selbg_pix != bg_pix
		&& selbg_pix != xw->dft_foreground) {
		bg_pix = fg_pix;
		fg_pix = selbg_pix;
	    }
	}
#endif
	/* double-reverse... EXCHANGE(fg_pix, bg_pix, xx_pix); */
#if OPT_HIGHLIGHT_COLOR
	if (screen->hilite_color) {
	    if (screen->hilite_reverse) {
		if (use_selbg) {
		    if (use_selfg ^ reverse2) {
			bg_pix = fg_pix;
		    } else {
			fg_pix = bg_pix;
		    }
		    if (reverse2) {
			fg_pix = selbg_pix;
		    } else {
			bg_pix = selbg_pix;
		    }
		}
		if (use_selfg) {
		    if (reverse2) {
			bg_pix = selfg_pix;
		    } else {
			fg_pix = selfg_pix;
		    }
		}
	    }
	}
#endif
    }
#if OPT_HIGHLIGHT_COLOR
    if (!screen->hilite_color || !screen->hilite_reverse) {
	if (hilite && !screen->hilite_reverse) {
	    if (use_selbg) {
		if (reverse2)
		    fg_pix = selbg_pix;
		else
		    bg_pix = selbg_pix;
	    }
	    if (use_selfg) {
		if (reverse2)
		    bg_pix = selfg_pix;
		else
		    fg_pix = selfg_pix;
	    }
	}
    }
#endif

#if OPT_BLINK_TEXT
    if ((screen->blink_state == ON) &&
	(!screen->blink_as_bold) &&
	(attr_flags & BLINK)) {
	fg_pix = bg_pix;
    }
#endif

    if (attr_flags & INVISIBLE) {
	fg_pix = bg_pix;
    }
    setCgsFore(xw, win, cgsId, fg_pix);
    setCgsBack(xw, win, cgsId, bg_pix);
    return getCgsGC(xw, win, cgsId);
}

/*
 * Resets the foreground/background of the GC returned by 'updatedXtermGC()'
 * to the values that would be set in SGR_Foreground and SGR_Background. This
 * duplicates some logic, but only modifies 1/4 as many GC's.
 */
void
resetXtermGC(XtermWidget xw, unsigned attr_flags, Bool hilite)
{
    TScreen *screen = TScreenOf(xw);
    VTwin *win = WhichVWin(screen);
    CgsEnum cgsId = whichXtermCgs(xw, attr_flags, hilite);
    Pixel fg_pix = getXtermFG(xw, attr_flags, xw->cur_foreground);
    Pixel bg_pix = getXtermBG(xw, attr_flags, xw->cur_background);

    checkVeryBoldColors(attr_flags, xw->cur_foreground);

    if (ReverseOrHilite(screen, attr_flags, hilite)) {
	setCgsFore(xw, win, cgsId, bg_pix);
	setCgsBack(xw, win, cgsId, fg_pix);
    } else {
	setCgsFore(xw, win, cgsId, fg_pix);
	setCgsBack(xw, win, cgsId, bg_pix);
    }
}

#if OPT_ISO_COLORS
/*
 * Extract the foreground-color index from a color pair.
 * If we've got BOLD or UNDERLINE color-mode active, those will be used.
 */
Pixel
extract_fg(XtermWidget xw, CellColor color, unsigned attr_flags)
{
    unsigned fg = ExtractForeground(color);

    if (TScreenOf(xw)->colorAttrMode
	|| (fg == ExtractBackground(color))) {
	fg = MapToColorMode(fg, TScreenOf(xw), attr_flags);
    }
    return fg;
}

/*
 * Extract the background-color index from a color pair.
 * If we've got INVERSE color-mode active, that will be used.
 */
Pixel
extract_bg(XtermWidget xw, CellColor color, unsigned attr_flags)
{
    unsigned bg = ExtractBackground(color);

    if (TScreenOf(xw)->colorAttrMode
	|| (bg == ExtractForeground(color))) {
	if (TScreenOf(xw)->colorRVMode && (attr_flags & INVERSE))
	    bg = COLOR_RV;
    }
    return bg;
}

/*
 * Combine the current foreground and background into a single 8-bit number.
 * Note that we're storing the SGR foreground, since cur_foreground may be set
 * to COLOR_UL, COLOR_BD or COLOR_BL, which would make the code larger than 8
 * bits.
 *
 * This assumes that fg/bg are equal when we override with one of the special
 * attribute colors.
 */
CellColor
makeColorPair(XtermWidget xw)
{
    CellColor result;

#if OPT_DIRECT_COLOR
    result.fg = xw->cur_foreground;
    result.bg = xw->cur_background;
#else
    int fg = xw->cur_foreground;
    int bg = xw->cur_background;
    unsigned my_bg = okIndexedColor(bg) ? (unsigned) bg : 0;
    unsigned my_fg = okIndexedColor(fg) ? (unsigned) fg : my_bg;

    result = (CellColor) (my_fg | (my_bg << COLOR_BITS));
#endif

    return result;
}

/*
 * Using the "current" SGR background, clear a rectangle.
 */
void
ClearCurBackground(XtermWidget xw,
		   int top,
		   int left,
		   unsigned height,
		   unsigned width,
		   unsigned fw)
{
    TScreen *screen = TScreenOf(xw);
    int actual_rows = PlusStatusLine(screen, screen->max_row + 1);
    Boolean visible = (((int) width > 0)
		       && ((left + (int) width) <= screen->max_col + 1)
		       && (((int) height + top) <= actual_rows));

    TRACE(("ClearCurBackground %d,%d %dx%d%s with %d %s\n",
	   top, left, height, width,
	   IsStatusShown(screen) ? "*" : "",
	   xw->cur_background,
	   visible ? "(ok)" : "(err)"));

    if (VWindow(screen) && visible) {
	set_background(xw, xw->cur_background);

	xtermClear2(xw,
		    CursorX2(screen, left, fw),
		    CursorY2(screen, top),
		    (width * fw),
		    (height * (unsigned) FontHeight(screen)));

	set_background(xw, -1);
    }
}
#endif /* OPT_ISO_COLORS */

Pixel
getXtermBackground(XtermWidget xw, unsigned attr_flags, int color)
{
    Pixel result = T_COLOR(TScreenOf(xw), TEXT_BG);

#if OPT_ISO_COLORS
    if (color >= 0) {
	if_OPT_DIRECT_COLOR2_else(TScreenOf(xw), (attr_flags & ATR_DIRECT_BG), {
	    result = (Pixel) color;
	}) if ((attr_flags & BG_COLOR) && (color < MAXCOLORS)) {
	    result = GET_COLOR_RES(xw, TScreenOf(xw)->Acolors[color]);
	}
    }
#else
    (void) attr_flags;
    (void) color;
#endif
    return result;
}

#if OPT_ISO_COLORS && OPT_WIDE_ATTRS
#if OPT_SGR2_HASH
typedef struct _DimColorHT {
    Pixel org;
    Pixel dim;
} DimColorHT;

static unsigned
jhash1(const unsigned char *key, size_t len)
{
    unsigned hash;
    size_t i;

    for (hash = 0, i = 0; i < len; ++i) {
	hash += key[i];
	hash += (hash << 10);
	hash ^= (hash >> 6);
    }
    hash += (hash << 3);
    hash ^= (hash >> 11);
    hash += (hash << 15);
    return hash;
}

static unsigned
computeFaint(XtermWidget xw, unsigned value, unsigned compare)
{
    TScreen *screen = TScreenOf(xw);
    if (screen->faint_relative) {
	value = (unsigned) ((value + compare) / 2);
    } else {
	value = (unsigned) ((2 * value) / 3);
    }
    return value;
}
#endif /* OPT_SGR2_HASH */
#endif /* OPT_ISO_COLORS && OPT_WIDE_ATTRS */

Pixel
getXtermForeground(XtermWidget xw, unsigned attr_flags, int color)
{
    Pixel result = T_COLOR(TScreenOf(xw), TEXT_FG);

#if OPT_ISO_COLORS
    if_OPT_DIRECT_COLOR2_else(TScreenOf(xw), (attr_flags & ATR_DIRECT_FG), {
	result = (Pixel) color;
    })
	if ((attr_flags & FG_COLOR) &&
	    (color >= 0 && color < MAXCOLORS)) {
	result = GET_COLOR_RES(xw, TScreenOf(xw)->Acolors[color]);
    }
#else
    (void) attr_flags;
    (void) color;
#endif

#if OPT_ISO_COLORS && OPT_WIDE_ATTRS
    if ((attr_flags & ATR_FAINT)) {
#if OPT_SGR2_HASH
#define DIM_IT(n) work.n = (unsigned short) computeFaint(xw, work.n, bkg.n)
#define SizeOfHT ((unsigned) sizeof(unsigned long) * CHAR_BIT)
	static DimColorHT ht[SizeOfHT];
	Pixel bg = T_COLOR(TScreenOf(xw), TEXT_BG);
	XColor work;
	Pixel p;

	if ((color >= 0)
	    || (result != (Pixel) color)) {
	    static unsigned long have = 0;
	    static Boolean have_bg = False;
	    static XColor bkg;

	    /* cache bkg color in r/g/b */
	    if (!have_bg || bg != bkg.pixel) {
		bkg.pixel = bg;
		have_bg = QueryOneColor(xw, &bkg);
		have = 0;	/* invalidate color cache */
	    }
	    if (have_bg) {
		unsigned hv;
		hv = jhash1((unsigned char *) &result, sizeof(result));
		hv %= SizeOfHT;

		if ((have & (1UL << hv))
		    && ht[hv].org == result) {
		    result = ht[hv].dim;	/* return cached color */
		} else {
		    work.pixel = result;
		    if (QueryOneColor(xw, &work)) {
			DIM_IT(red);
			DIM_IT(green);
			DIM_IT(blue);
			p = result;
			if (allocateBestRGB(xw, &work)) {
			    result = work.pixel;
			}

			/* cache the result */
			have |= (1UL << hv);
			ht[hv].org = p;
			ht[hv].dim = result;
		    }
		}
	    }
	}
#else /* !OPT_SGR2_HASH */
#define DIM_IT(n) work.n = (unsigned short) ((2 * (unsigned)work.n) / 3)
	static Pixel last_in;
	static Pixel last_out;
	if ((result != last_in)
	    && ((color >= 0)
		|| (result != (Pixel) color))) {
	    XColor work;
	    last_in = result;
	    work.pixel = result;
	    if (QueryOneColor(xw, &work)) {
		DIM_IT(red);
		DIM_IT(green);
		DIM_IT(blue);
		if (allocateBestRGB(xw, &work)) {
		    result = work.pixel;
		}
	    }
	    last_out = result;
	} else {
	    result = last_out;
	}
#endif /* OPT_SGR2_HASH */
    }
#endif
    return result;
}

/*
 * Returns a single base character for the given cell.
 */
unsigned
getXtermCell(TScreen *screen, int row, int col)
{
    CLineData *ld = getLineData(screen, row);

    return ((ld && (col >= 0) && (col < (int) ld->lineSize))
	    ? ld->charData[col]
	    : (unsigned) ' ');
}

/*
 * Sets a single base character for the given cell.
 */
void
putXtermCell(TScreen *screen, int row, int col, int ch)
{
    LineData *ld = getLineData(screen, row);

    if (ld && (col < (int) ld->lineSize)) {
	ld->charData[col] = (CharData) ch;
	if_OPT_WIDE_CHARS(screen, {
	    size_t off;
	    for_each_combData(off, ld) {
		ld->combData[off][col] = 0;
	    }
	});
    }
}

#if OPT_WIDE_CHARS
/*
 * Add a combining character for the given cell
 */
void
addXtermCombining(TScreen *screen, int row, int col, unsigned ch)
{
    if (ch != 0) {
	LineData *ld = getLineData(screen, row);
	size_t off;

	TRACE(("addXtermCombining %d,%d U+%04X (%d)\n",
	       row, col, ch, CharWidth(screen, ch)));

	for_each_combData(off, ld) {
	    if (!ld->combData[off][col]) {
		ld->combData[off][col] = (CharData) ch;
		break;
	    }
	}
    }
}

unsigned
getXtermCombining(TScreen *screen, int row, int col, int off)
{
    CLineData *ld = getLineData(screen, row);
    return (ld->combSize ? ld->combData[off][col] : 0U);
}
#endif

void
update_keyboard_type(void)
{
    update_delete_del();
    update_tcap_fkeys();
    update_old_fkeys();
    update_hp_fkeys();
    update_sco_fkeys();
    update_sun_fkeys();
    update_sun_kbd();
}

void
set_keyboard_type(XtermWidget xw, xtermKeyboardType type, Bool set)
{
    xtermKeyboardType save = xw->keyboard.type;

    TRACE(("set_keyboard_type(%s, %s) currently %s\n",
	   visibleKeyboardType(type),
	   BtoS(set),
	   visibleKeyboardType(xw->keyboard.type)));
    if (set) {
	xw->keyboard.type = type;
    } else {
	xw->keyboard.type = keyboardIsDefault;
    }

    if (save != xw->keyboard.type) {
	update_keyboard_type();
    }
}

void
toggle_keyboard_type(XtermWidget xw, xtermKeyboardType type)
{
    xtermKeyboardType save = xw->keyboard.type;

    TRACE(("toggle_keyboard_type(%s) currently %s\n",
	   visibleKeyboardType(type),
	   visibleKeyboardType(xw->keyboard.type)));
    if (xw->keyboard.type == type) {
	xw->keyboard.type = keyboardIsDefault;
    } else {
	xw->keyboard.type = type;
    }

    if (save != xw->keyboard.type) {
	update_keyboard_type();
    }
}

const char *
visibleKeyboardType(xtermKeyboardType type)
{
    const char *result = "?";
    switch (type) {
	CASETYPE(keyboardIsLegacy);	/* bogus vt220 codes for F1-F4, etc. */
	CASETYPE(keyboardIsDefault);
	CASETYPE(keyboardIsHP);
	CASETYPE(keyboardIsSCO);
	CASETYPE(keyboardIsSun);
	CASETYPE(keyboardIsTermcap);
	CASETYPE(keyboardIsVT220);
    }
    return result;
}

static void
init_keyboard_type(XtermWidget xw, xtermKeyboardType type, Bool set)
{
    TRACE(("init_keyboard_type(%s, %s) currently %s\n",
	   visibleKeyboardType(type),
	   BtoS(set),
	   visibleKeyboardType(xw->keyboard.type)));
    if (set) {
	/*
	 * Check for conflicts, e.g., if someone asked for both Sun and HP
	 * function keys.
	 */
	if (guard_keyboard_type) {
	    xtermWarning("Conflicting keyboard type option (%s/%s)\n",
			 visibleKeyboardType(xw->keyboard.type),
			 visibleKeyboardType(type));
	}
	xw->keyboard.type = type;
	guard_keyboard_type = True;
	update_keyboard_type();
    }
}

/*
 * If the keyboardType resource is set, use that, overriding the individual
 * boolean resources for different keyboard types.
 */
void
decode_keyboard_type(XtermWidget xw, XTERM_RESOURCE * rp)
{
#define DATA(n, t, f) { n, t, XtOffsetOf(XTERM_RESOURCE, f) }
#define FLAG(n) *(Boolean *)(((char *)rp) + table[n].offset)
    static struct {
	const char *name;
	xtermKeyboardType type;
	unsigned offset;
    } table[] = {
	DATA(NAME_OLD_KT, keyboardIsLegacy, oldKeyboard),
#if OPT_HP_FUNC_KEYS
	    DATA(NAME_HP_KT, keyboardIsHP, hpFunctionKeys),
#endif
#if OPT_SCO_FUNC_KEYS
	    DATA(NAME_SCO_KT, keyboardIsSCO, scoFunctionKeys),
#endif
#if OPT_SUN_FUNC_KEYS
	    DATA(NAME_SUN_KT, keyboardIsSun, sunFunctionKeys),
#endif
#if OPT_SUNPC_KBD
	    DATA(NAME_VT220_KT, keyboardIsVT220, sunKeyboard),
#endif
#if OPT_TCAP_FKEYS
	    DATA(NAME_TCAP_KT, keyboardIsTermcap, termcapKeys),
#endif
    };
    Cardinal n;
    TScreen *screen = TScreenOf(xw);

    TRACE(("decode_keyboard_type(%s)\n", rp->keyboardType));
    if (!x_strcasecmp(rp->keyboardType, "unknown")) {
	/*
	 * Let the individual resources comprise the keyboard-type.
	 */
	for (n = 0; n < XtNumber(table); ++n)
	    init_keyboard_type(xw, table[n].type, FLAG(n));
    } else if (!x_strcasecmp(rp->keyboardType, "default")) {
	/*
	 * Set the keyboard-type to the Sun/PC type, allowing modified
	 * function keys, etc.
	 */
	for (n = 0; n < XtNumber(table); ++n)
	    init_keyboard_type(xw, table[n].type, False);
    } else {
	Bool found = False;

	/*
	 * Special case: oldXtermFKeys should have been like the others.
	 */
	if (!x_strcasecmp(rp->keyboardType, NAME_OLD_KT)) {
	    TRACE(("special case, setting oldXtermFKeys\n"));
	    screen->old_fkeys = True;
	    screen->old_fkeys0 = True;
	}

	/*
	 * Choose an individual keyboard type.
	 */
	for (n = 0; n < XtNumber(table); ++n) {
	    if (!x_strcasecmp(rp->keyboardType, table[n].name + 1)) {
		FLAG(n) = True;
		found = True;
	    } else {
		FLAG(n) = False;
	    }
	    init_keyboard_type(xw, table[n].type, FLAG(n));
	}
	if (!found) {
	    xtermWarning("KeyboardType resource \"%s\" not found\n",
			 rp->keyboardType);
	}
    }
#undef DATA
#undef FLAG
}

#if OPT_WIDE_CHARS
#if defined(HAVE_WCHAR_H) && defined(HAVE_WCWIDTH)
/*
 * If xterm is running in a UTF-8 locale, it is still possible to encounter
 * old runtime configurations which yield incomplete or inaccurate data.
 */
static Bool
systemWcwidthOk(int samplesize, int samplepass)
{
    wchar_t n;
    int oops = 0;

    for (n = 21; n <= 25; ++n) {
	wchar_t code = (wchar_t) dec2ucs(NULL, (unsigned) n);
	int system_code = wcwidth(code);
	int intern_code = mk_wcwidth(code);

	/*
	 * Solaris 10 wcwidth() returns "2" for all of the line-drawing (page
	 * 0x2500) and most of the geometric shapes (a few are excluded, just
	 * to make it more difficult to use).  Do a sanity check to avoid using
	 * it.
	 */
	if ((system_code < 0 && intern_code >= 1)
	    || (system_code >= 0 && intern_code != system_code)) {
	    TRACE(("systemWcwidthOk: broken system line-drawing wcwidth\n"));
	    oops += (samplepass + 1);
	    break;
	}
    }

    for (n = 0; n < (wchar_t) samplesize; ++n) {
	int system_code = wcwidth(n);
	int intern_code = mk_wcwidth(n);

	/*
	 * When this check was originally implemented, there were few if any
	 * libraries with full Unicode coverage.  Time passes, and it is
	 * possible to make a full comparison of the BMP.  There are some
	 * differences: mk_wcwidth() marks some codes as combining and some
	 * as single-width, differing from GNU libc.
	 */
	if ((system_code < 0 && intern_code >= 1)
	    || (system_code >= 0 && intern_code != system_code)) {
	    TRACE((".. width(U+%04X) = %d, expected %d\n",
		   (unsigned) n, system_code, intern_code));
	    if (++oops > samplepass)
		break;
	}
    }
    TRACE(("systemWcwidthOk: %d/%d mismatches, allowed %d\n",
	   oops, (int) n, samplepass));
    return (oops <= samplepass);
}
#endif /* HAVE_WCWIDTH */

void
decode_wcwidth(XtermWidget xw)
{
    int mode = ((xw->misc.cjk_width ? 2 : 0)
		+ (xw->misc.mk_width ? 1 : 0)
		+ 1);

    switch (mode) {
    default:
#if defined(HAVE_WCHAR_H) && defined(HAVE_WCWIDTH)
	if (xtermEnvUTF8() &&
	    systemWcwidthOk(xw->misc.mk_samplesize, xw->misc.mk_samplepass)) {
	    my_wcwidth = wcwidth;
	    TRACE(("using system wcwidth() function\n"));
	    break;
	}
#endif
	/* FALLTHRU */
    case 2:
	my_wcwidth = &mk_wcwidth;
	TRACE(("using MK wcwidth() function\n"));
	break;
    case 3:
	/* FALLTHRU */
    case 4:
	my_wcwidth = &mk_wcwidth_cjk;
	TRACE(("using MK-CJK wcwidth() function\n"));
	break;
    }

    for (first_widechar = 128; first_widechar < 4500; ++first_widechar) {
	if (my_wcwidth((wchar_t) first_widechar) > 1) {
	    TRACE(("first_widechar %#x\n", first_widechar));
	    break;
	}
    }
}
#endif

/*
 * Extend a (normally) boolean resource value by checking for additional values
 * which will be mapped into true/false.
 */
int
extendedBoolean(const char *value, const FlagList * table, Cardinal limit)
{
    int result = -1;
    long check;
    char *next;
    Cardinal n;

    if ((x_strcasecmp(value, "true") == 0)
	|| (x_strcasecmp(value, "yes") == 0)
	|| (x_strcasecmp(value, "on") == 0)) {
	result = True;
    } else if ((x_strcasecmp(value, "false") == 0)
	       || (x_strcasecmp(value, "no") == 0)
	       || (x_strcasecmp(value, "off") == 0)) {
	result = False;
    } else if ((check = strtol(value, &next, 0)) >= 0 && FullS2L(value, next)) {
	if (check >= (long) limit)	/* i.e., past False=0, True=1 */
	    check = True;
	result = (int) check;
    } else {
	for (n = 0; n < limit - 2; ++n) {
	    if (table[n].name == NULL) {
		break;
	    } else if (x_strcasecmp(value, table[n].name) == 0) {
		result = table[n].code;
		break;
	    }
	}
    }

    if (result < 0) {
	xtermWarning("Unrecognized keyword: %s\n", value);
	result = False;
    }

    TRACE(("extendedBoolean(%s) = %d\n", value, result));
    return result;
}

/*
 * Something like round() from math library, but round() is less widely-used
 * than xterm.  Also, there are no negative numbers to complicate this.
 */
int
dimRound(double value)
{
    int result = (int) value;
    if (result < value)
	++result;
    return result;
}

/*
 * Find the geometry of the specified Xinerama screen
 */
static void
find_xinerama_screen(Display *display, int screen, struct Xinerama_geometry *ret)
{
#ifdef HAVE_X11_EXTENSIONS_XINERAMA_H
    XineramaScreenInfo *screens;
    int nb_screens;

    if (screen == -1)		/* already inited */
	return;
    screens = XineramaQueryScreens(display, &nb_screens);
    if (screen >= nb_screens) {
	xtermWarning("Xinerama screen %d does not exist\n", screen);
	return;
    }
    if (screen == -2) {
	int ptr_x, ptr_y;
	int dummy_int, i;
	unsigned dummy_uint;
	Window dummy_win;
	if (nb_screens == 0)
	    return;
	XQueryPointer(display, DefaultRootWindow(display),
		      &dummy_win, &dummy_win,
		      &ptr_x, &ptr_y,
		      &dummy_int, &dummy_int, &dummy_uint);
	for (i = 0; i < nb_screens; i++) {
	    if ((ptr_x - screens[i].x_org) < screens[i].width &&
		(ptr_y - screens[i].y_org) < screens[i].height) {
		screen = i;
		break;
	    }
	}
	if (screen < 0) {
	    xtermWarning("Mouse not in any Xinerama screen, using 0\n");
	    screen = 0;
	}
    }
    ret->scr_x = screens[screen].x_org;
    ret->scr_y = screens[screen].y_org;
    ret->scr_w = screens[screen].width;
    ret->scr_h = screens[screen].height;
#else /* HAVE_X11_EXTENSIONS_XINERAMA_H */
    (void) display;
    (void) ret;
    if (screen > 0)
	xtermWarning("Xinerama support not enabled\n");
#endif /* HAVE_X11_EXTENSIONS_XINERAMA_H */
}

/*
 * Parse the screen code after the @ in a geometry string.
 */
static void
parse_xinerama_screen(Display *display, const char *str, struct Xinerama_geometry *ret)
{
    int screen = -1;
    char *end;

    if (*str == 'g') {
	screen = -1;
	str++;
    } else if (*str == 'c') {
	screen = -2;
	str++;
    } else {
	long s = strtol(str, &end, 0);
	if (FullS2L(str, end) && ((int) s >= 0)) {
	    screen = (int) s;
	    str = end;
	}
    }
    if (*str) {
	xtermWarning("invalid Xinerama specification '%s'\n", str);
	return;
    }
    if (screen == -1)		/* already done */
	return;
    find_xinerama_screen(display, screen, ret);
}

/*
 * Parse a geometry string with extra Xinerama specification:
 * x++@.
 */
int
XParseXineramaGeometry(Display *display, char *parsestring, struct Xinerama_geometry *ret)
{
    char *at, buf[128];

    ret->scr_x = 0;
    ret->scr_y = 0;
    ret->scr_w = DisplayWidth(display, DefaultScreen(display));
    ret->scr_h = DisplayHeight(display, DefaultScreen(display));
    at = strchr(parsestring, '@');
    if (at != NULL && (size_t) (at - parsestring) < sizeof(buf) - 1) {
	memcpy(buf, parsestring, (size_t) (at - parsestring));
	buf[at - parsestring] = 0;
	parsestring = buf;
	parse_xinerama_screen(display, at + 1, ret);
    }
    return ((strlen(parsestring) <= MAX_U_STRING)
	    ? XParseGeometry(parsestring, &ret->x, &ret->y, &ret->w, &ret->h)
	    : 0);
}

#if USE_DOUBLE_BUFFER
Window
VDrawable(TScreen *screen)
{
    screen->needSwap = 1;
    return WhichVWin(screen)->drawable;
}
#endif

#if OPT_RENDERFONT
#ifndef discardRenderDraw
void
discardRenderDraw(TScreen *screen)
{
    if (screen->renderDraw) {
	XftDrawDestroy(screen->renderDraw);
	screen->renderDraw = NULL;
    }
}
#endif
#endif /* OPT_RENDERFONT */

char *
xtermSetLocale(int category, String after)
{
    char *before = x_strdup(setlocale(category, NULL));

    (void) setlocale(category, after);
    TRACE(("before setlocale :%s\n", NonNull(before)));
    TRACE(("updated locale   :%s\n", NonNull(setlocale(category, NULL))));
    return before;
}

void
xtermResetLocale(int category, char *before)
{
    (void) setlocale(category, before);
    free(before);
    TRACE(("restored locale  :%s\n", NonNull(setlocale(category, NULL))));
}
xterm-399/main.h0000644000000000000000000001550214750007662012344 0ustar  rootroot/* $XTermId: main.h,v 1.86 2025/02/03 00:37:06 tom Exp $ */

/*
 * Copyright 2000-2023,2025 by Thomas E. Dickey
 *
 *                         All Rights Reserved
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name(s) of the above copyright
 * holders shall not be used in advertising or otherwise to promote the
 * sale, use or other dealings in this Software without prior written
 * authorization.
 *
 * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 *
 *                         All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of Digital Equipment
 * Corporation not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.
 *
 *
 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */
#ifndef included_main_h
#define included_main_h

#include 

#ifndef DEFCLASS
#define DEFCLASS		"XTerm"
#endif

#ifndef DEFFONT
#define DEFFONT			"fixed"
#endif

#ifndef DEFWIDEFONT
#define DEFWIDEFONT		NULL	/* grab one which is 2x as wide */
#endif

#ifndef DEFWIDEBOLDFONT
#define DEFWIDEBOLDFONT		NULL
#endif

#ifndef DEFXIMFONT
#define DEFXIMFONT		"fixed"
#endif

#ifndef DEFBOLDFONT
#define DEFBOLDFONT		NULL	/* no bold font uses overstriking */
#endif

#ifndef DEFBORDER
#define DEFBORDER		2
#endif

#ifndef DEFFACENAME
#define DEFFACENAME		NULL
#endif

#ifndef DEFFACENAME_AUTO
#define DEFFACENAME_AUTO	"mono"
#endif

#ifndef DEFFACESIZE
#define DEFFACESIZE		"8.0"
#endif

#ifndef DEF_ALLOW_COLOR
#define DEF_ALLOW_COLOR		True
#endif

#ifndef DEF_ALLOW_FONT
#define DEF_ALLOW_FONT		True
#endif

#ifndef DEF_ALLOW_MOUSE
#define DEF_ALLOW_MOUSE		True
#endif

#ifndef DEF_ALLOW_TCAP
#define DEF_ALLOW_TCAP		True
#endif

#ifndef DEF_ALLOW_TITLE
#define DEF_ALLOW_TITLE		True
#endif

#ifndef DEF_ALLOW_WINDOW
#define DEF_ALLOW_WINDOW	False
#endif

#ifndef DEF_COLOR_EVENTS
#define DEF_COLOR_EVENTS	""
#endif

#ifndef DEF_DISALLOWED_COLOR
#define DEF_DISALLOWED_COLOR	"SetColor,GetColor,GetAnsiColor"
#endif

#ifndef DEF_DISALLOWED_FONT
#define DEF_DISALLOWED_FONT	"SetFont,GetFont"
#endif

#ifndef DEF_DISALLOWED_MOUSE
#define DEF_DISALLOWED_MOUSE	"*"
#endif

#ifndef DEF_DISALLOWED_PASTE_CONTROLS
#define DEF_DISALLOWED_PASTE_CONTROLS	"BS,DEL,ENQ,EOT,ESC,NUL,STTY"
#endif

#ifndef DEF_DISALLOWED_TCAP
#define DEF_DISALLOWED_TCAP	"SetTcap,GetTcap"
#endif

#ifndef DEF_DISALLOWED_WINDOW
#define DEF_DISALLOWED_WINDOW	"20,21,SetXprop,SetSelection"
#endif

#if OPT_BLINK_TEXT
#define DEFBLINKASBOLD		False
#else
#define DEFBLINKASBOLD		True
#endif

#if OPT_DOUBLE_BUFFER
#define DEF_DOUBLE_BUFFER	True
#else
#define DEF_DOUBLE_BUFFER	False
#endif

#ifndef DEFDELETE_DEL
#define DEFDELETE_DEL		Maybe
#endif

#ifndef DEF_BACKARO_ERASE
#define DEF_BACKARO_ERASE	False
#endif

#ifndef DEF_BACKARO_BS
#define DEF_BACKARO_BS		True
#endif

#ifndef DEF_CD_XTRA_SCROLL
#define DEF_CD_XTRA_SCROLL	"False"
#endif

#ifndef DEF_ALT_SENDS_ESC
#define DEF_ALT_SENDS_ESC	False
#endif

#ifndef DEF_META_SENDS_ESC
#define DEF_META_SENDS_ESC	False
#endif

#ifndef DEF_8BIT_META
#define DEF_8BIT_META		"true"	/* eightBitMeta */
#endif

#ifndef DEF_COLOR4
#define DEF_COLOR4		"blue2"		/* see XTerm-col.ad */
#endif

#ifndef DEF_COLOR12
#define DEF_COLOR12		"rgb:5c/5c/ff"	/* see XTerm-col.ad */
#endif

#ifndef DEF_INITIAL_ERASE
#define DEF_INITIAL_ERASE	False
#endif

#ifndef DEF_MENU_LOCALE
#define DEF_MENU_LOCALE		"C"
#endif

#ifndef DEF_POINTER_MODE
#define DEF_POINTER_MODE	pNoMouse
#endif

#ifndef DEF_PTY_STTY_SIZE
#if defined(linux) || defined(__APPLE__)
#define DEF_PTY_STTY_SIZE	False
#else
#define DEF_PTY_STTY_SIZE	True
#endif
#endif

#ifndef DEF_BUFFER_RATE
#define DEF_BUFFER_RATE		40	/* frames/second, limited to 100 */
#endif

#ifndef DEF_LIMIT_RESPONSE
#define DEF_LIMIT_RESPONSE	1024
#endif

#ifndef DEF_SAVE_LINES
#define DEF_SAVE_LINES		1024
#endif

#ifndef DEF_SCROLL_LINES
#define DEF_SCROLL_LINES	1
#endif

#ifndef DEF_SL_CLOCK
#define DEF_SL_CLOCK		1000
#endif

#ifndef DEF_SL_COORDS
#define DEF_SL_COORDS		80
#endif

#ifndef DEF_SL_FORMAT
#define DEF_SL_FORMAT           "%{version%}  %{position%}  %{unixtime%}"
#endif

#ifndef DEF_STRINGS_MAX
#if OPT_REGIS_GRAPHICS || OPT_SIXEL_GRAPHICS
#define DEF_STRINGS_MAX		600000
#else
#define DEF_STRINGS_MAX		20000
#endif
#endif

#ifndef DEF_TITLE_MODES
#define DEF_TITLE_MODES		0
#endif

#ifndef DEF_TI_XTRA_SCROLL
#define DEF_TI_XTRA_SCROLL	"False"
#endif

#ifndef DEF_TRACK_USAGE
#define DEF_TRACK_USAGE		False
#endif

#ifndef DEF_XFT_CACHE
#define DEF_XFT_CACHE		50
#endif

#ifndef PROJECTROOT
#define PROJECTROOT		"/usr"
#endif

/*
 * The configure script quotes PROJECTROOT's value.
 * imake does not quote PROJECTROOT's value.
 */
#ifdef HAVE_CONFIG_H
#define DEFLOCALEFILTER2(x)	x
#else
#define DEFLOCALEFILTER2(x)	#x
#endif

/*
 * If the configure script finds luit, we have the path directly.
 */
#ifdef LUIT_PATH
#define DEFLOCALEFILTER		LUIT_PATH
#else
#define DEFLOCALEFILTER1(x)	DEFLOCALEFILTER2(x)
#define DEFLOCALEFILTER		DEFLOCALEFILTER1(PROJECTROOT) "/bin/luit"
#endif

#define MIN_SCALE_HEIGHT	0.9f
#define MAX_SCALE_HEIGHT	1.5f

/*
 * See lib/Xt/Resources.c
 */
#define MAXRESOURCES            400

#endif /* included_main_h */
xterm-399/run-tic.in0000755000000000000000000001011114316402714013145 0ustar  rootroot#!/bin/sh
# $XTermId: run-tic.in,v 1.1 2022/10/02 21:42:36 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2006-2021,2022 by Thomas E. Dickey
# 
#                         All Rights Reserved
# 
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# 
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# 
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
#
# Run tic, either using ncurses' extension feature or filtering out harmless
# messages for the extensions which are otherwise ignored by other versions of
# tic.

USE_NCURSES=20190609

failed() {
	echo "? $*" >&2
	exit 1
}

need_ncurses() {
	failed "This terminal description relies on ncurses 6.1 $USE_NCURSES"
}

use_ncurses6() {
	VER=`infocmp6 -V 2>/dev/null`
	test -n "$VER" && INFOCMP_PROG=infocmp6
	VER=`tic6 -V 2>/dev/null`
	test -n "$VER" && TIC_PROG=tic6
	test -z "$VER" && need_ncurses
}

MYTEMP=`mktemp -d 2>/dev/null`
if test -z "$MYTEMP"
then
	MYTEMP=${TMPDIR:-/tmp}/run-tic$$
fi
mkdir -p "$MYTEMP" || failed "cannot mkdir $MYTEMP"
trap "rm -rf $MYTEMP; exit 1" 1 2 3 15
trap "rm -rf $MYTEMP" 0

STDERR=$MYTEMP/run-tic$$.log
VER=`tic -V 2>/dev/null`
OPT=

TIC_PROG=tic
INFOCMP_PROG=infocmp
unset TERM
unset TERMINFO_DIRS

PASS1="$*"
PASS2="$*"

case "x$VER" in
*ncurses*)
	OPT="-x"
	# Prefer ncurses 6.1 over 6.0 over any 5, if we can get it, to support
	# large numbers (used in xterm-direct) and large entries (an issue with
	# xterm-nrc).
	case "$VER" in
	*\ [7-9].*|*\ 6.[1-9].20[12][0-9]*)
		check=`echo "$VER" | sed -e 's/^.*\.//' -e 's/[^0-9].*$//'`
		[ "$check" -ge "20210626" ] && \
		[ "$check" -lt "20210828" ] && use_ncurses6
		[ "$check" -lt "$USE_NCURSES" ] && use_ncurses6
		;;
	*)
		# On systems with only ncurses 5, check for development version
		# of ncurses.
		use_ncurses6
		;;
	esac
	echo "** using tic from $VER"
	# If this is 6.1.20180127 or later and using ABI 6, then it supports
	# entries larger than 4096 bytes (up to 32768).
	case "$VER" in
	*\ [7-9].*|*\ 6.[1-9].20[12][0-9]*)
		expect="	cols#100000,"
		cat >"$MYTEMP"/fake.ti </dev/null
		check=`TERMINFO="$MYTEMP" TERM=fake $INFOCMP_PROG -1 fake 2>/dev/null |grep "$expect"`
		test "x$check" = "x$expect" || BIG=no
		;;
	*)
		BIG=no
		;;
	esac
	if test "$BIG" = no
	then
		# Trim out the SGR 1006 feature, to keep "xterm-nrc" smaller
		# than 4096 bytes.
		echo "...this version does not support large terminal descriptions"
		PASS2=$MYTEMP/input
		sed -e 's/use=xterm+sm+1006,//' -e '/^[	 ][	 ]*$/d' "$PASS1" >"$PASS2"
		set "$PASS2"
	fi
	;;
esac

echo "** $TIC_PROG $OPT $PASS1"
$TIC_PROG $OPT "$PASS2" 2>"$STDERR"
RET=$?

sed -e "s%$PASS2%$PASS1%" "$STDERR" | \
@FGREP@ -v 'Unknown Capability' | \
@FGREP@ -v 'Capability is not recognized:' | \
@FGREP@ -v 'tic: Warning near line ' >&2
rm -f "$STDERR"

exit $RET
xterm-399/charsets.dat0000644000000000000000000016152314775322767013577 0ustar  rootroot# $XTermId: charsets.dat,v 1.36 2025/04/08 22:40:55 tom Exp $

# Copyright 2023-2024,2025 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.

# According to
#  Digital ANSI-Compliant Printing Protocol
#  Level 2 Programming Reference Manual
#  EK-PPLV2-PM. B01
#
# the supplementary character sets Greek, Hebrew, Latin-5 and Latin/Cyrillic
# are standardized by ISO:
#  ISO Greek is 8859-7
#  ISO Hebrew is 8859-8
#  ISO Latin-5 is 8859-9
#  ISO Latin/Cyrillic is 8859-5
#
# These are derived from the data at
#  ftp://www.unicode.org/Public/MAPPINGS/ISO8859/
#
# Note: the "figure A-xx" comments refer to EK-PPLV2-PM.

# A "codepage" is treated different from the NRC mode:  it is always enabled.
# Reuse the UNI() macros by temporarily setting its state.

# xterm's original implementation of NRCS in 1998 was before Unicode became
# prevalent.  Most of the necessary mappings could be done using definitions
# from X11/keysymdef.h, using ISO-8859-1 as the default.

map_ASCII
	A0	UNDEF	1B
	FF	UNDEF	10000

map_DEC_Spec_Graphic_VT52
	5F	UNDEF	10000
	60	U+0020	14	# nbsp, treat as blank
	61	U+0020	78	# reserved, treat as blank
	62	U+25AE	0A	# black vertical rectangle
	63	U+215F	0D	# "1/"
	64	U+0020	0E	# "3/", not in Unicode, ignore
	65	U+0020	0B	# "5/", not in Unicode, ignore
	66	U+0020	B0	# "7/", not in Unicode, ignore
	67	U+00B0	B1	# degree sign
	68	U+00B1	15	# plus-minus sign
	69	U+2192	0C	# right-arrow
	6A	U+2026	16	# ellipsis
	6B	U+00F7	17	# divide by
	6C	U+2193	18	# down arrow
	6D	U+23BA	19	# bar at scan 0
	6E	U+23BA	1A	# bar at scan 1
	6F	U+23BB	1B	# bar at scan 2
	70	U+23BB	1C	# bar at scan 3
	71	U+23BC	1D	# bar at scan 4
	72	U+23BC	1E	# bar at scan 5
	73	U+23BD	1F	# bar at scan 6
	74	U+23BD	80	# bar at scan 7
	75	U+2080	81	# subscript 0
	76	U+2081	82	# subscript 1
	77	U+2082	83	# subscript 2
	78	U+2083	84	# subscript 3
	79	U+2084	85	# subscript 4
	7A	U+2085	86	# subscript 5
	7B	U+2086	C6	# subscript 6
	7C	U+2087	87	# subscript 7
	7D	U+2088	A3	# subscript 8
	7E	U+2089	B7	# subscript 9

map_DEC_Spec_Graphic
	5F	UNDEF	10000
	60	U+25c6	14	# black diamond
	61	U+2592	78	# medium shade
	62	U+2409	0A	# symbol for horizontal tabulation
	63	U+240C	0D	# symbol for form feed
	64	U+240D	0E	# symbol for carriage return
	65	U+240A	0B	# symbol for line feed
	66	U+00B0	B0	# degree sign
	67	U+00B1	B1	# plus-minus sign
	68	U+2424	15	# symbol for newline
	69	U+240B	0C	# symbol for vertical tabulation
	6A	U+2518	16	# box drawings light up and left
	6B	U+2510	17	# box drawings light down and left
	6C	U+250C	18	# box drawings light down and right
	6D	U+2514	19	# box drawings light up and right
	6E	U+253C	1A	# box drawings light vertical and horizontal
	6F	U+23BA	1B	# box drawings scan 1
	70	U+23BB	1C	# box drawings scan 3
	71	U+2500	1D	# box drawings light horizontal
	72	U+23BC	1E	# box drawings scan 7
	73	U+23BD	1F	# box drawings scan 9
	74	U+251C	80	# box drawings light vertical and right
	75	U+2524	81	# box drawings light vertical and left
	76	U+2534	82	# box drawings light up and horizontal
	77	U+252C	83	# box drawings light down and horizontal
	78	U+2502	84	# box drawings light vertical
	79	U+2264	85	# less-than or equal to
	7A	U+2265	86	# greater-than or equal to
	7B	U+03C0	C6	# greek small letter pi
	7C	U+2260	87	# not equal to
	7D	U+00A3	A3	# pound sign
	7E	U+00B7	B7	# middle dot

map_ISO_Latin_1

map_NRCS_Dutch
	23	XK_sterling	# U+00A3 POUND SIGN
	40	XK_threequarters # U+00BE VULGAR FRACTION THREE QUARTERS
	5B	U+0133	 	# LATIN SMALL LIGATURE IJ
	5C	XK_onehalf	# U+00BD VULGAR FRACTION ONE HALF
	5D	XK_bar		# U+007C VERTICAL LINE
	7B	XK_diaeresis	# U+00A8 DIAERESIS
	7C	U+0192	 	# LATIN SMALL LETTER F WITH HOOK (florin)
	7D	XK_onequarter	# U+00BC VULGAR FRACTION ONE QUARTER
	7E	XK_acute	# U+00B4 ACUTE ACCENT

map_NRCS_Finnish
	5B	XK_Adiaeresis	# U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS
	5C	XK_Odiaeresis	# U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS
	5D	XK_Aring	# U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE
	5E	XK_Udiaeresis	# U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS
	60	XK_eacute	# U+00E9 LATIN SMALL LETTER E WITH ACUTE
	7B	XK_adiaeresis	# U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
	7C	XK_odiaeresis	# U+00F6 LATIN SMALL LETTER O WITH DIAERESIS
	7D	XK_aring	# U+00E5 LATIN SMALL LETTER A WITH RING ABOVE
	7E	XK_udiaeresis	# U+00FC LATIN SMALL LETTER U WITH DIAERESIS

map_NRCS_French
	23	XK_sterling	# U+00A3 POUND SIGN
	40	XK_agrave	# U+00E0 LATIN SMALL LETTER A WITH GRAVE
	5B	XK_degree	# U+00B0 DEGREE SIGN
	5C	XK_ccedilla	# U+00E7 LATIN SMALL LETTER C WITH CEDILLA
	5D	XK_section	# U+00A7 SECTION SIGN
	7B	XK_eacute	# U+00E9 LATIN SMALL LETTER E WITH ACUTE
	7C	XK_ugrave	# U+00F9 LATIN SMALL LETTER U WITH GRAVE
	7D	XK_egrave	# U+00E8 LATIN SMALL LETTER E WITH GRAVE
	7E	XK_diaeresis	# U+00A8 DIAERESIS

map_NRCS_French_Canadian
	40	XK_agrave	# U+00E0 LATIN SMALL LETTER A WITH GRAVE
	5B	XK_acircumflex	# U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX
	5C	XK_ccedilla	# U+00E7 LATIN SMALL LETTER C WITH CEDILLA
	5D	XK_ecircumflex	# U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX
	5E	XK_icircumflex	# U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX
	60	XK_ocircumflex	# U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX
	7B	XK_eacute	# U+00E9 LATIN SMALL LETTER E WITH ACUTE
	7C	XK_ugrave	# U+00F9 LATIN SMALL LETTER U WITH GRAVE
	7D	XK_egrave	# U+00E8 LATIN SMALL LETTER E WITH GRAVE
	7E	XK_ucircumflex  # U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX

map_NRCS_German
	40	XK_section	# U+00A7 SECTION SIGN
	5B	XK_Adiaeresis	# U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS
	5C	XK_Odiaeresis	# U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS
	5D	XK_Udiaeresis	# U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS
	7B	XK_adiaeresis	# U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
	7C	XK_odiaeresis	# U+00F6 LATIN SMALL LETTER O WITH DIAERESIS
	7D	XK_udiaeresis	# U+00FC LATIN SMALL LETTER U WITH DIAERESIS
	7E	XK_ssharp	# U+00DF LATIN SMALL LETTER SHARP S

map_NRCS_Italian
	23	XK_sterling	# U+00A3 POUND SIGN
	40	XK_section	# U+00A7 SECTION SIGN
	5B	XK_degree	# U+00B0 DEGREE SIGN
	5C	XK_ccedilla	# U+00E7 LATIN SMALL LETTER C WITH CEDILLA
	5D	XK_eacute	# U+00E9 LATIN SMALL LETTER E WITH ACUTE
	60	XK_ugrave	# U+00F9 LATIN SMALL LETTER U WITH GRAVE
	7B	XK_agrave	# U+00E0 LATIN SMALL LETTER A WITH GRAVE
	7C	XK_ograve	# U+00F2 LATIN SMALL LETTER O WITH GRAVE
	7D	XK_egrave	# U+00E8 LATIN SMALL LETTER E WITH GRAVE
	7E	XK_igrave	# U+00EC LATIN SMALL LETTER I WITH GRAVE

map_NRCS_Norwegian_Danish
	40	XK_Adiaeresis	# U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS
	5B	XK_AE	 	# U+00C6 LATIN CAPITAL LETTER AE
	5C	XK_Ooblique	# U+00D8 LATIN CAPITAL LETTER O WITH STROKE
	5D	XK_Aring	# U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE
	5E	XK_Udiaeresis	# U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS
	60	XK_adiaeresis	# U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
	7B	XK_ae		# U+00E6 LATIN SMALL LETTER AE
	7C	XK_oslash	# U+00F8 LATIN SMALL LETTER O WITH STROKE
	7D	XK_aring	# U+00E5 LATIN SMALL LETTER A WITH RING ABOVE
	7E	XK_udiaeresis	# U+00FC LATIN SMALL LETTER U WITH DIAERESIS

map_NRCS_Portuguese
	5B	XK_Atilde	# U+00C3 LATIN CAPITAL LETTER A WITH TILDE
	5C	XK_Ccedilla	# U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA
	5D	XK_Otilde	# U+00D5 LATIN CAPITAL LETTER O WITH TILDE
	7B	XK_atilde	# U+00E3 LATIN SMALL LETTER A WITH TILDE
	7C	XK_ccedilla	# U+00E7 LATIN SMALL LETTER C WITH CEDILLA
	7D	XK_otilde	# U+00F5 LATIN SMALL LETTER O WITH TILDE

map_NRCS_Spanish
	23	XK_sterling	# U+00A3 POUND SIGN
	40	XK_section	# U+00A7 SECTION SIGN
	5B	XK_exclamdown	# U+00A1 INVERTED EXCLAMATION MARK
	5C	XK_Ntilde	# U+00D1 LATIN CAPITAL LETTER N WITH TILDE
	5D	XK_questiondown	# U+00BF INVERTED QUESTION MARK
	7B	XK_degree	# U+00B0 DEGREE SIGN
	7C	XK_ntilde	# U+00F1 LATIN SMALL LETTER N WITH TILDE
	7D	XK_ccedilla	# U+00E7 LATIN SMALL LETTER C WITH CEDILLA

map_NRCS_Swedish
	40	XK_Eacute
	5B	XK_Adiaeresis	# U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS
	5C	XK_Odiaeresis	# U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS
	5D	XK_Aring	# U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE
	5E	XK_Udiaeresis	# U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS
	60	XK_eacute	# U+00E9 LATIN SMALL LETTER E WITH ACUTE
	7B	XK_adiaeresis	# U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
	7C	XK_odiaeresis	# U+00F6 LATIN SMALL LETTER O WITH DIAERESIS
	7D	XK_aring	# U+00E5 LATIN SMALL LETTER A WITH RING ABOVE
	7E	XK_udiaeresis	# U+00FC LATIN SMALL LETTER U WITH DIAERESIS

map_NRCS_Swiss
	23	XK_ugrave	# U+00F9 LATIN SMALL LETTER U WITH GRAVE
	40	XK_agrave	# U+00E0 LATIN SMALL LETTER A WITH GRAVE
	5B	XK_eacute	# U+00E9 LATIN SMALL LETTER E WITH ACUTE
	5C	XK_ccedilla	# U+00E7 LATIN SMALL LETTER C WITH CEDILLA
	5D	XK_ecircumflex	# U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX
	5E	XK_icircumflex	# U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX
	5F	XK_egrave	# U+00E8 LATIN SMALL LETTER E WITH GRAVE
	60	XK_ocircumflex	# U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX
	7B	XK_adiaeresis	# U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
	7C	XK_odiaeresis	# U+00F6 LATIN SMALL LETTER O WITH DIAERESIS
	7D	XK_udiaeresis	# U+00FC LATIN SMALL LETTER U WITH DIAERESIS
	7E	XK_ucircumflex  # U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX

# Unlike NRCS, which splices a few characters onto ISO-8859-1, the
# supplementary character sets are complete, normally mapped to GR.  Most of
# these mappings rely upon glyphs not found in ISO-8859-1.  We can display most
# of those using Unicode, thereby supporting specialized applications that use
# SCS with luit, subject to the limitation that select/paste will give
# meaningless results in terms of the application which uses these mappings.
#
# Since the codepages introduced with VT320, etc, use 8-bit encodings, there is
# no plausible argument to be made that these mappings "use" UTF-8, even though
# there is a hidden step in the terminal emulator which relies upon UTF-8.

map_DEC_Supp_Graphic(code,dft)
	24	UNDEF	1B
	26	UNDEF	1B
	28	U+00A4	A4	# CURRENCY SIGN
	2C	UNDEF	1B
	2D	UNDEF	1B
	2E	UNDEF	1B
	2F	UNDEF	1B
	34	UNDEF	1B
	38	UNDEF	1B
	3E	UNDEF	1B
	50	UNDEF	1B
	57	U+0152	97	# LATIN CAPITAL LIGATURE OE
	5D	U+0178	98	# LATIN CAPITAL LETTER Y WITH DIAERESIS
	5E	UNDEF	1B
	5F	U+005F	DF
	70	UNDEF	1B
	77	U+0153	99	# LATIN SMALL LIGATURE OE
	7D	U+00FF	FF	# LATIN SMALL LETTER Y WITH DIAERESIS
	7E	UNDEF	1B

# derived from http://www.vt100.net/charsets/technical.html
map_DEC_Technical
	21	U+23B7	D5	# RADICAL SYMBOL BOTTOM Centred left to right, so that it joins up with 02/02
	22	U+250C	D6	# BOX DRAWINGS LIGHT DOWN AND RIGHT
	23	U+2500	1D	# BOX DRAWINGS LIGHT HORIZONTAL
	24	U+2320	D7	# TOP HALF INTEGRAL with the proviso that the stem is vertical, to join with 02/06
	25	U+2321	D8	# BOTTOM HALF INTEGRAL with the proviso above.
	26	U+2502	84	# BOX DRAWINGS LIGHT VERTICAL
	27	U+23A1	D9	# LEFT SQUARE BRACKET UPPER CORNER Joins vertically to 02/06, 02/08. Doesn't join to its right.
	28	U+23A3	DA	# LEFT SQUARE BRACKET LOWER CORNER Joins vertically to 02/06, 02/07. Doesn't join to its right.
	29	U+23A4	DB	# RIGHT SQUARE BRACKET UPPER CORNER Joins vertically to 026, 02a. Doesn't join to its left.
	2A	U+23A6	DC	# RIGHT SQUARE BRACKET LOWER CORNER Joins vertically to 026, 029. Doesn't join to its left.
	2B	U+23A7	DD	# LEFT CURLY BRACKET UPPER HOOK Joins vertically to 026, 02c, 02/15. Doesn't join to its right.
	2C	U+23A9	DE	# LEFT CURLY BRACKET LOWER HOOK Joins vertically to 026, 02b, 02/15. Doesn't join to its right.
	2D	U+23AB	DF	# RIGHT CURLY BRACKET UPPER HOOK Joins vertically to 026, 02e, 03/00. Doesn't join to its left.
	2E	U+23AD	E0	# RIGHT CURLY BRACKET LOWER HOOK Joins vertically to 026, 02d, 03/00. Doesn't join to its left.
	2F	U+23A8	E1	# LEFT CURLY BRACKET MIDDLE PIECE Joins vertically to 026, 02b, 02c.
	30	U+23AC	E2	# RIGHT CURLY BRACKET MIDDLE PIECE Joins vertically to 02/06, 02d, 02e.
	31	PUA(0)	E3	# Top Left Sigma. Joins to right with 02/03, 03/05. Joins diagonally below right with 03/03, 03/07.
	32	PUA(1)	E4	# Bottom Left Sigma. Joins to right with 02/03, 03/06. Joins diagonally above right with 03/04, 03/07.
	33	PUA(2)	E5	# Top Diagonal Sigma. Line for joining 03/01 to 03/04 or 03/07.
	34	PUA(3)	E6	# Bottom Diagonal Sigma. Line for joining 03/02 to 03/03 or 03/07.
	35	PUA(4)	E7	# Top Right Sigma. Joins to left with 02/03, 03/01.
	36	PUA(5)	E8	# Bottom Right Sigma. Joins to left with 02/03, 03/02.
	37	PUA(6)	E9	# Middle Sigma. Joins diagonally with 03/01, 03/02, 03/03, 03/04.
	38	UNDEF	1B	# undefined
	39	UNDEF	1B	# undefined
	3A	UNDEF	1B	# undefined
	3B	UNDEF	1B	# undefined
	3C	U+2264	85	# LESS-THAN OR EQUAL TO
	3D	U+2260	87	# NOT EQUAL TO
	3E	U+2265	86	# GREATER-THAN OR EQUAL TO
	3F	U+222B	EA	# INTEGRAL
	40	U+2234	EB	# THEREFORE
	41	U+221D	EC	# PROPORTIONAL TO
	42	U+221E	ED	# INFINITY
	43	U+00F7	F7	# DIVISION SIGN
	44	U+0394	EE	# GREEK CAPITAL DELTA
	45	U+2207	EF	# NABLA
	46	U+03A6	AC	# GREEK CAPITAL LETTER PHI
	47	U+0393	78	# GREEK CAPITAL LETTER GAMMA
	48	U+223C	F0	# TILDE OPERATOR
	49	U+2243	F1	# ASYMPTOTICALLY EQUAL TO
	4A	U+0398	7D	# GREEK CAPITAL LETTER THETA
	4B	U+00D7	D7	# MULTIPLICATION SIGN
	4C	U+039B	A2	# GREEK CAPITAL LETTER LAMDA
	4D	U+21D4	F2	# LEFT RIGHT DOUBLE ARROW
	4E	U+21D2	F3	# RIGHTWARDS DOUBLE ARROW
	4F	U+2261	F4	# IDENTICAL TO
	50	U+03A0	A7	# GREEK CAPITAL LETTER PI
	51	U+03A8	AE	# GREEK CAPITAL LETTER PSI
	52	UNDEF	1B	# undefined
	53	U+03A3	A9	# GREEK CAPITAL LETTER SIGMA
	54	UNDEF	1B	# undefined
	55	UNDEF	1B	# undefined
	56	U+221A	F5	# SQUARE ROOT
	57	U+03A9	AF	# GREEK CAPITAL LETTER OMEGA
	58	U+039E	A5	# GREEK CAPITAL LETTER XI
	59	U+03A5	AB	# GREEK CAPITAL LETTER UPSILON
	5A	U+2282	F6	# SUBSET OF
	5B	U+2283	F7	# SUPERSET OF
	5C	U+2229	F8	# INTERSECTION
	5D	U+222A	F9	# UNION
	5E	U+2227	FA	# LOGICAL AND
	5F	U+2228	FB	# LOGICAL OR
	60	U+00AC	AC	# NOT SIGN
	61	U+03B1	B7	# GREEK SMALL LETTER ALPHA
	62	U+03B2	B8	# GREEK SMALL LETTER BETA
	63	U+03C7	CD	# GREEK SMALL LETTER CHI
	64	U+03B4	BA	# GREEK SMALL LETTER DELTA
	65	U+03B5	BB	# GREEK SMALL LETTER EPSILON
	66	U+03C6	CC	# GREEK SMALL LETTER PHI
	67	U+03B3	B9	# GREEK SMALL LETTER GAMMA
	68	U+03B7	BD	# GREEK SMALL LETTER ETA
	69	U+03B9	BF	# GREEK SMALL LETTER IOTA
	6A	U+03B8	BE	# GREEK SMALL LETTER THETA
	6B	U+03BA	C0	# GREEK SMALL LETTER KAPPA
	6C	U+03BB	C1	# GREEK SMALL LETTER LAMDA
	6D	UNDEF	1B	# undefined
	6E	U+03BD	C3	# GREEK SMALL LETTER NU
	6F	U+2202	FC	# PARTIAL DIFFERENTIAL
	70	U+03C0	C6	# GREEK SMALL LETTER PI
	71	U+03C8	CE	# GREEK SMALL LETTER PSI
	72	U+03C1	C7	# GREEK SMALL LETTER RHO
	73	U+03C3	C9	# GREEK SMALL LETTER SIGMA
	74	U+03C4	CA	# GREEK SMALL LETTER TAU
	75	UNDEF	1B	# undefined
	76	U+0192	FD	# LATIN SMALL LETTER F WITH HOOK Probably chosen for its meaning of "function"
	77	U+03C9	CF	# GREEK SMALL LETTER OMEGA
	78	U+03BE	C4	# GREEK SMALL LETTER XI
	79	U+03C5	CB	# GREEK SMALL LETTER UPSILON
	7A	U+03B6	BC	# GREEK SMALL LETTER ZETA
	7B	U+2190	FE	# LEFTWARDS ARROW
	7C	U+2191	FF	# UPWARDS ARROW
	7D	U+2192	100	# RIGHTWARDS ARROW
	7E	U+2193	02	# DOWNWARDS ARROW

map_JIS_Roman
	5C	U+00A5		# YEN SIGN
	7E	U+203E		# OVERLINE

# Documented as if only GR, but encoded here to allow assignment to GL and GR.
map_JIS_Katakana
	21	U+FF61		# HALFWIDTH IDEOGRAPHIC FULL STOP
	22	U+FF62		# HALFWIDTH LEFT CORNER BRACKET
	23	U+FF63		# HALFWIDTH RIGHT CORNER BRACKET
	24	U+FF64		# HALFWIDTH IDEOGRAPHIC COMMA
	25	U+FF65		# HALFWIDTH KATAKANA MIDDLE DOT
	26	U+FF66		# HALFWIDTH KATAKANA LETTER WO
	27	U+FF67		# HALFWIDTH KATAKANA LETTER SMALL A
	28	U+FF68		# HALFWIDTH KATAKANA LETTER SMALL I
	29	U+FF69		# HALFWIDTH KATAKANA LETTER SMALL U
	2A	U+FF6A		# HALFWIDTH KATAKANA LETTER SMALL E
	2B	U+FF6B		# HALFWIDTH KATAKANA LETTER SMALL O
	2C	U+FF6C		# HALFWIDTH KATAKANA LETTER SMALL YA
	2D	U+FF6D		# HALFWIDTH KATAKANA LETTER SMALL YU
	2E	U+FF6E		# HALFWIDTH KATAKANA LETTER SMALL YO
	2F	U+FF6F		# HALFWIDTH KATAKANA LETTER SMALL TU
	30	U+FF70		# HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
	31	U+FF71		# HALFWIDTH KATAKANA LETTER A
	32	U+FF72		# HALFWIDTH KATAKANA LETTER I
	33	U+FF73		# HALFWIDTH KATAKANA LETTER U
	34	U+FF74		# HALFWIDTH KATAKANA LETTER E
	35	U+FF75		# HALFWIDTH KATAKANA LETTER O
	36	U+FF76		# HALFWIDTH KATAKANA LETTER KA
	37	U+FF77		# HALFWIDTH KATAKANA LETTER KI
	38	U+FF78		# HALFWIDTH KATAKANA LETTER KU
	39	U+FF79		# HALFWIDTH KATAKANA LETTER KE
	3A	U+FF7A		# HALFWIDTH KATAKANA LETTER KO
	3B	U+FF7B		# HALFWIDTH KATAKANA LETTER SA
	3C	U+FF7C		# HALFWIDTH KATAKANA LETTER SI
	3D	U+FF7D		# HALFWIDTH KATAKANA LETTER SU
	3E	U+FF7E		# HALFWIDTH KATAKANA LETTER SE
	3F	U+FF7F		# HALFWIDTH KATAKANA LETTER SO
	40	U+FF80		# HALFWIDTH KATAKANA LETTER TA
	41	U+FF81		# HALFWIDTH KATAKANA LETTER TI
	42	U+FF82		# HALFWIDTH KATAKANA LETTER TU
	43	U+FF83		# HALFWIDTH KATAKANA LETTER TE
	44	U+FF84		# HALFWIDTH KATAKANA LETTER TO
	45	U+FF85		# HALFWIDTH KATAKANA LETTER NA
	46	U+FF86		# HALFWIDTH KATAKANA LETTER NI
	47	U+FF87		# HALFWIDTH KATAKANA LETTER NU
	48	U+FF88		# HALFWIDTH KATAKANA LETTER NE
	49	U+FF89		# HALFWIDTH KATAKANA LETTER NO
	4A	U+FF8A		# HALFWIDTH KATAKANA LETTER HA
	4B	U+FF8B		# HALFWIDTH KATAKANA LETTER HI
	4C	U+FF8C		# HALFWIDTH KATAKANA LETTER HU
	4D	U+FF8D		# HALFWIDTH KATAKANA LETTER HE
	4E	U+FF8E		# HALFWIDTH KATAKANA LETTER HO
	4F	U+FF8F		# HALFWIDTH KATAKANA LETTER MA
	50	U+FF90		# HALFWIDTH KATAKANA LETTER MI
	51	U+FF91		# HALFWIDTH KATAKANA LETTER MU
	52	U+FF92		# HALFWIDTH KATAKANA LETTER ME
	53	U+FF93		# HALFWIDTH KATAKANA LETTER MO
	54	U+FF94		# HALFWIDTH KATAKANA LETTER YA
	55	U+FF95		# HALFWIDTH KATAKANA LETTER YU
	56	U+FF96		# HALFWIDTH KATAKANA LETTER YO
	57	U+FF97		# HALFWIDTH KATAKANA LETTER RA
	58	U+FF98		# HALFWIDTH KATAKANA LETTER RI
	59	U+FF99		# HALFWIDTH KATAKANA LETTER RU
	5A	U+FF9A		# HALFWIDTH KATAKANA LETTER RE
	5B	U+FF9B		# HALFWIDTH KATAKANA LETTER RO
	5C	U+FF9C		# HALFWIDTH KATAKANA LETTER WA
	5D	U+FF9D		# HALFWIDTH KATAKANA LETTER N
	5E	U+FF9E		# HALFWIDTH KATAKANA VOICED SOUND MARK
	5F	U+FF9F		# HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
	60	UNDEF
	61	UNDEF
	62	UNDEF
	63	UNDEF
	64	UNDEF
	65	UNDEF
	66	UNDEF
	67	UNDEF
	68	UNDEF
	69	UNDEF
	6A	UNDEF
	6B	UNDEF
	6C	UNDEF
	6D	UNDEF
	6E	UNDEF
	6F	UNDEF
	70	UNDEF
	71	UNDEF
	72	UNDEF
	73	UNDEF
	74	UNDEF
	75	UNDEF
	76	UNDEF
	77	UNDEF
	78	UNDEF
	79	UNDEF
	7A	UNDEF
	7B	UNDEF
	7C	UNDEF
	7D	UNDEF

# ISO Latin/Cyrillic is 8859-5
map_ISO_Latin_Cyrillic
	20	U+00A0		# NO-BREAK SPACE
	21	U+0401	03	# CYRILLIC CAPITAL LETTER IO
	22	U+0402	04	# CYRILLIC CAPITAL LETTER DJE
	23	U+0403	05	# CYRILLIC CAPITAL LETTER GJE
	24	U+0404	06	# CYRILLIC CAPITAL LETTER UKRAINIAN IE
	25	U+0405	07	# CYRILLIC CAPITAL LETTER DZE
	26	U+0406	08	# CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
	27	U+0407	09	# CYRILLIC CAPITAL LETTER YI
	28	U+0408	0A	# CYRILLIC CAPITAL LETTER JE
	29	U+0409	0B	# CYRILLIC CAPITAL LETTER LJE
	2A	U+040A	0C	# CYRILLIC CAPITAL LETTER NJE
	2B	U+040B	0D	# CYRILLIC CAPITAL LETTER TSHE
	2C	U+040C	0E	# CYRILLIC CAPITAL LETTER KJE
	2D	U+00AD		# SOFT HYPHEN
	2E	U+040E	0F	# CYRILLIC CAPITAL LETTER SHORT U
	2F	U+040F	10	# CYRILLIC CAPITAL LETTER DZHE
	30	U+0410	11	# CYRILLIC CAPITAL LETTER A
	31	U+0411	12	# CYRILLIC CAPITAL LETTER BE
	32	U+0412	13	# CYRILLIC CAPITAL LETTER VE
	33	U+0413	14	# CYRILLIC CAPITAL LETTER GHE
	34	U+0414	15	# CYRILLIC CAPITAL LETTER DE
	35	U+0415	16	# CYRILLIC CAPITAL LETTER IE
	36	U+0416	17	# CYRILLIC CAPITAL LETTER ZHE
	37	U+0417	18	# CYRILLIC CAPITAL LETTER ZE
	38	U+0418	19	# CYRILLIC CAPITAL LETTER I
	39	U+0419	1A	# CYRILLIC CAPITAL LETTER SHORT I
	3A	U+041A	1B	# CYRILLIC CAPITAL LETTER KA
	3B	U+041B	1C	# CYRILLIC CAPITAL LETTER EL
	3C	U+041C	1D	# CYRILLIC CAPITAL LETTER EM
	3D	U+041D	1E	# CYRILLIC CAPITAL LETTER EN
	3E	U+041E	1F	# CYRILLIC CAPITAL LETTER O
	3F	U+041F	20	# CYRILLIC CAPITAL LETTER PE
	40	U+0420	21	# CYRILLIC CAPITAL LETTER ER
	41	U+0421	22	# CYRILLIC CAPITAL LETTER ES
	42	U+0422	23	# CYRILLIC CAPITAL LETTER TE
	43	U+0423	24	# CYRILLIC CAPITAL LETTER U
	44	U+0424	25	# CYRILLIC CAPITAL LETTER EF
	45	U+0425	26	# CYRILLIC CAPITAL LETTER HA
	46	U+0426	27	# CYRILLIC CAPITAL LETTER TSE
	47	U+0427	28	# CYRILLIC CAPITAL LETTER CHE
	48	U+0428	29	# CYRILLIC CAPITAL LETTER SHA
	49	U+0429	2A	# CYRILLIC CAPITAL LETTER SHCHA
	4A	U+042A	2B	# CYRILLIC CAPITAL LETTER HARD SIGN
	4B	U+042B	2C	# CYRILLIC CAPITAL LETTER YERU
	4C	U+042C	2D	# CYRILLIC CAPITAL LETTER SOFT SIGN
	4D	U+042D	2E	# CYRILLIC CAPITAL LETTER E
	4E	U+042E	2F	# CYRILLIC CAPITAL LETTER YU
	4F	U+042F	30	# CYRILLIC CAPITAL LETTER YA
	50	U+0430	31	# CYRILLIC SMALL LETTER A
	51	U+0431	32	# CYRILLIC SMALL LETTER BE
	52	U+0432	33	# CYRILLIC SMALL LETTER VE
	53	U+0433	34	# CYRILLIC SMALL LETTER GHE
	54	U+0434	35	# CYRILLIC SMALL LETTER DE
	55	U+0435	36	# CYRILLIC SMALL LETTER IE
	56	U+0436	37	# CYRILLIC SMALL LETTER ZHE
	57	U+0437	38	# CYRILLIC SMALL LETTER ZE
	58	U+0438	39	# CYRILLIC SMALL LETTER I
	59	U+0439	3A	# CYRILLIC SMALL LETTER SHORT I
	5A	U+043A	3B	# CYRILLIC SMALL LETTER KA
	5B	U+043B	3C	# CYRILLIC SMALL LETTER EL
	5C	U+043C	3D	# CYRILLIC SMALL LETTER EM
	5D	U+043D	3E	# CYRILLIC SMALL LETTER EN
	5E	U+043E	3F	# CYRILLIC SMALL LETTER O
	5F	U+043F	40	# CYRILLIC SMALL LETTER PE
	60	U+0440	41	# CYRILLIC SMALL LETTER ER
	61	U+0441	42	# CYRILLIC SMALL LETTER ES
	62	U+0442	43	# CYRILLIC SMALL LETTER TE
	63	U+0443	44	# CYRILLIC SMALL LETTER U
	64	U+0444	45	# CYRILLIC SMALL LETTER EF
	65	U+0445	46	# CYRILLIC SMALL LETTER HA
	66	U+0446	47	# CYRILLIC SMALL LETTER TSE
	67	U+0447	48	# CYRILLIC SMALL LETTER CHE
	68	U+0448	49	# CYRILLIC SMALL LETTER SHA
	69	U+0449	4A	# CYRILLIC SMALL LETTER SHCHA
	6A	U+044A	4B	# CYRILLIC SMALL LETTER HARD SIGN
	6B	U+044B	4C	# CYRILLIC SMALL LETTER YERU
	6C	U+044C	4D	# CYRILLIC SMALL LETTER SOFT SIGN
	6D	U+044D	4E	# CYRILLIC SMALL LETTER E
	6E	U+044E	4F	# CYRILLIC SMALL LETTER YU
	6F	U+044F	50	# CYRILLIC SMALL LETTER YA
	70	U+2116	51	# NUMERO SIGN
	71	U+0451	52	# CYRILLIC SMALL LETTER IO
	72	U+0452	53	# CYRILLIC SMALL LETTER DJE
	73	U+0453	54	# CYRILLIC SMALL LETTER GJE
	74	U+0454	55	# CYRILLIC SMALL LETTER UKRAINIAN IE
	75	U+0455	56	# CYRILLIC SMALL LETTER DZE
	76	U+0456	57	# CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
	77	U+0457	58	# CYRILLIC SMALL LETTER YI
	78	U+0458	59	# CYRILLIC SMALL LETTER JE
	79	U+0459	5A	# CYRILLIC SMALL LETTER LJE
	7A	U+045A	5B	# CYRILLIC SMALL LETTER NJE
	7B	U+045B	5C	# CYRILLIC SMALL LETTER TSHE
	7C	U+045C	5D	# CYRILLIC SMALL LETTER KJE
	7D	U+00A7	A7	# SECTION SIGN
	7E	U+045E	5E	# CYRILLIC SMALL LETTER SHORT U
	7F	U+045F	5F	# CYRILLIC SMALL LETTER DZHE

# ISO Greek is 8859-7
map_ISO_Greek_Supp
	20	U+00A0		# NO-BREAK SPACE
	21	U+2018	60	# LEFT SINGLE QUOTATION MARK
	22	U+2019	27	# RIGHT SINGLE QUOTATION MARK
	23	U+00A3		# POUND SIGN
	24	UNDEF	1B	# undefined
	25	UNDEF	1B	# undefined
	26	U+00A6		# BROKEN BAR
	27	U+00A7		# SECTION SIGN
	28	U+00A8		# DIAERESIS
	29	U+00A9		# COPYRIGHT SIGN
	2A	UNDEF	1B	# undefined
	2B	U+00AB		# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
	2C	U+00AC		# NOT SIGN
	2D	U+00AD		# SOFT HYPHEN
	2E	UNDEF	1B	# undefined
	2F	U+2015	2D	# HORIZONTAL BAR
	30	U+00B0		# DEGREE SIGN
	31	U+00B1		# PLUS-MINUS SIGN
	32	U+00B2		# SUPERSCRIPT TWO
	33	U+00B3		# SUPERSCRIPT THREE
	34	U+0384	96	# GREEK TONOS
	35	U+0385	95	# GREEK DIALYTIKA TONOS
	36	U+0386	6E	# GREEK CAPITAL LETTER ALPHA WITH TONOS
	37	U+00B7		# MIDDLE DOT
	38	U+0388	6F	# GREEK CAPITAL LETTER EPSILON WITH TONOS
	39	U+0389	70	# GREEK CAPITAL LETTER ETA WITH TONOS
	3A	U+038A	71	# GREEK CAPITAL LETTER IOTA WITH TONOS
	3B	U+00BB		# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
	3C	U+038C	72	# GREEK CAPITAL LETTER OMICRON WITH TONOS
	3D	U+00BD		# VULGAR FRACTION ONE HALF
	3E	U+038E	73	# GREEK CAPITAL LETTER UPSILON WITH TONOS
	3F	U+038F	74	# GREEK CAPITAL LETTER OMEGA WITH TONOS
	40	U+0390	75	# GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
	41	U+0391	76	# GREEK CAPITAL LETTER ALPHA
	42	U+0392	77	# GREEK CAPITAL LETTER BETA
	43	U+0393	78	# GREEK CAPITAL LETTER GAMMA
	44	U+0394	79	# GREEK CAPITAL LETTER DELTA
	45	U+0395	7A	# GREEK CAPITAL LETTER EPSILON
	46	U+0396	7B	# GREEK CAPITAL LETTER ZETA
	47	U+0397	7C	# GREEK CAPITAL LETTER ETA
	48	U+0398	7D	# GREEK CAPITAL LETTER THETA
	49	U+0399	7E	# GREEK CAPITAL LETTER IOTA
	4A	U+039A	7F	# GREEK CAPITAL LETTER KAPPA
	4B	U+039B	A2	# GREEK CAPITAL LETTER LAMDA
	4C	U+039C	A3	# GREEK CAPITAL LETTER MU
	4D	U+039D	A4	# GREEK CAPITAL LETTER NU
	4E	U+039E	A5	# GREEK CAPITAL LETTER XI
	4F	U+039F	A6	# GREEK CAPITAL LETTER OMICRON
	50	U+03A0	A7	# GREEK CAPITAL LETTER PI
	51	U+03A1	A8	# GREEK CAPITAL LETTER RHO
	52	UNDEF	1B	# undefined
	53	U+03A3	A9	# GREEK CAPITAL LETTER SIGMA
	54	U+03A4	AA	# GREEK CAPITAL LETTER TAU
	55	U+03A5	AB	# GREEK CAPITAL LETTER UPSILON
	56	U+03A6	AC	# GREEK CAPITAL LETTER PHI
	57	U+03A7	AD	# GREEK CAPITAL LETTER CHI
	58	U+03A8	AE	# GREEK CAPITAL LETTER PSI
	59	U+03A9	AF	# GREEK CAPITAL LETTER OMEGA
	5A	U+03AA	B0	# GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
	5B	U+03AB	B1	# GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
	5C	U+03AC	B2	# GREEK SMALL LETTER ALPHA WITH TONOS
	5D	U+03AD	B3	# GREEK SMALL LETTER EPSILON WITH TONOS
	5E	U+03AE	B4	# GREEK SMALL LETTER ETA WITH TONOS
	5F	U+03AF	B5	# GREEK SMALL LETTER IOTA WITH TONOS
	60	U+03B0	B6	# GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
	61	U+03B1	B7	# GREEK SMALL LETTER ALPHA
	62	U+03B2	B8	# GREEK SMALL LETTER BETA
	63	U+03B3	B9	# GREEK SMALL LETTER GAMMA
	64	U+03B4	BA	# GREEK SMALL LETTER DELTA
	65	U+03B5	BB	# GREEK SMALL LETTER EPSILON
	66	U+03B6	BC	# GREEK SMALL LETTER ZETA
	67	U+03B7	BD	# GREEK SMALL LETTER ETA
	68	U+03B8	BE	# GREEK SMALL LETTER THETA
	69	U+03B9	BF	# GREEK SMALL LETTER IOTA
	6A	U+03BA	C0	# GREEK SMALL LETTER KAPPA
	6B	U+03BB	C1	# GREEK SMALL LETTER LAMDA
	6C	U+03BC	C2	# GREEK SMALL LETTER MU
	6D	U+03BD	C3	# GREEK SMALL LETTER NU
	6E	U+03BE	C4	# GREEK SMALL LETTER XI
	6F	U+03BF	C5	# GREEK SMALL LETTER OMICRON
	70	U+03C0	C6	# GREEK SMALL LETTER PI
	71	U+03C1	C7	# GREEK SMALL LETTER RHO
	72	U+03C2	C8	# GREEK SMALL LETTER FINAL SIGMA
	73	U+03C3	C9	# GREEK SMALL LETTER SIGMA
	74	U+03C4	CA	# GREEK SMALL LETTER TAU
	75	U+03C5	CB	# GREEK SMALL LETTER UPSILON
	76	U+03C6	CC	# GREEK SMALL LETTER PHI
	77	U+03C7	CD	# GREEK SMALL LETTER CHI
	78	U+03C8	CE	# GREEK SMALL LETTER PSI
	79	U+03C9	CF	# GREEK SMALL LETTER OMEGA
	7A	U+03CA	D0	# GREEK SMALL LETTER IOTA WITH DIALYTIKA
	7B	U+03CB	D1	# GREEK SMALL LETTER UPSILON WITH DIALYTIKA
	7C	U+03CC	D2	# GREEK SMALL LETTER OMICRON WITH TONOS
	7D	U+03CD	D3	# GREEK SMALL LETTER UPSILON WITH TONOS
	7E	U+03CE	D4	# GREEK SMALL LETTER OMEGA WITH TONOS
	7F	UNDEF	1B	# undefined

# figure A-23 "ISO Latin-Hebrew Supplemental Character Set"
map_ISO_Hebrew
	20	U+00A0		# NO-BREAK SPACE
	21	UNDEF	1B	# undefined
	22	U+00A2		# CENT SIGN
	23	U+00A3		# POUND SIGN
	24	U+00A4		# CURRENCY SIGN
	25	U+00A5		# YEN SIGN
	26	U+00A6		# BROKEN BAR
	27	U+00A7		# SECTION SIGN
	28	U+00A8		# DIAERESIS
	29	U+00A9		# COPYRIGHT SIGN
	2A	U+00D7	D7	# MULTIPLICATION SIGN
	2B	U+00AB		# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
	2C	U+00AC		# NOT SIGN
	2D	U+00AD		# SOFT HYPHEN
	2E	U+00AE		# REGISTERED SIGN
	2F	U+00AF		# MACRON
	30	U+00B0		# DEGREE SIGN
	31	U+00B1		# PLUS-MINUS SIGN
	32	U+00B2		# SUPERSCRIPT TWO
	33	U+00B3		# SUPERSCRIPT THREE
	34	U+00B4		# ACUTE ACCENT
	35	U+00B5		# MICRO SIGN
	36	U+00B6		# PILCROW SIGN
	37	U+00B7		# MIDDLE DOT
	38	U+00B8		# CEDILLA
	39	U+00B9		# SUPERSCRIPT ONE
	3A	U+00F7	F7	# DIVISION SIGN
	3B	U+00BB		# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
	3C	U+00BC		# VULGAR FRACTION ONE QUARTER
	3D	U+00BD		# VULGAR FRACTION ONE HALF
	3E	U+00BE		# VULGAR FRACTION THREE QUARTERS
	3F	UNDEF	1B	# undefined
	40	UNDEF	1B	# undefined
	41	UNDEF	1B	# undefined
	42	UNDEF	1B	# undefined
	43	UNDEF	1B	# undefined
	44	UNDEF	1B	# undefined
	45	UNDEF	1B	# undefined
	46	UNDEF	1B	# undefined
	47	UNDEF	1B	# undefined
	48	UNDEF	1B	# undefined
	49	UNDEF	1B	# undefined
	4A	UNDEF	1B	# undefined
	4B	UNDEF	1B	# undefined
	4C	UNDEF	1B	# undefined
	4D	UNDEF	1B	# undefined
	4E	UNDEF	1B	# undefined
	4F	UNDEF	1B	# undefined
	50	UNDEF	1B	# undefined
	51	UNDEF	1B	# undefined
	52	UNDEF	1B	# undefined
	53	UNDEF	1B	# undefined
	54	UNDEF	1B	# undefined
	55	UNDEF	1B	# undefined
	56	UNDEF	1B	# undefined
	57	UNDEF	1B	# undefined
	58	UNDEF	1B	# undefined
	59	UNDEF	1B	# undefined
	5A	UNDEF	1B	# undefined
	5B	UNDEF	1B	# undefined
	5C	UNDEF	1B	# undefined
	5D	UNDEF	1B	# undefined
	5E	UNDEF	1B	# undefined
	5F	U+2017	52	# DOUBLE LOW LINE
	60	U+05D0	53	# HEBREW LETTER ALEF
	61	U+05D1	54	# HEBREW LETTER BET
	62	U+05D2	55	# HEBREW LETTER GIMEL
	63	U+05D3	56	# HEBREW LETTER DALET
	64	U+05D4	57	# HEBREW LETTER HE
	65	U+05D5	58	# HEBREW LETTER VAV
	66	U+05D6	59	# HEBREW LETTER ZAYIN
	67	U+05D7	5A	# HEBREW LETTER HET
	68	U+05D8	5B	# HEBREW LETTER TET
	69	U+05D9	5C	# HEBREW LETTER YOD
	6A	U+05DA	5D	# HEBREW LETTER FINAL KAF
	6B	U+05DB	5E	# HEBREW LETTER KAF
	6C	U+05DC	5F	# HEBREW LETTER LAMED
	6D	U+05DD	60	# HEBREW LETTER FINAL MEM
	6E	U+05DE	61	# HEBREW LETTER MEM
	6F	U+05DF	62	# HEBREW LETTER FINAL NUN
	70	U+05E0	63	# HEBREW LETTER NUN
	71	U+05E1	64	# HEBREW LETTER SAMEKH
	72	U+05E2	65	# HEBREW LETTER AYIN
	73	U+05E3	66	# HEBREW LETTER FINAL PE
	74	U+05E4	67	# HEBREW LETTER PE
	75	U+05E5	68	# HEBREW LETTER FINAL TSADI
	76	U+05E6	69	# HEBREW LETTER TSADI
	77	U+05E7	6A	# HEBREW LETTER QOF
	78	U+05E8	6B	# HEBREW LETTER RESH
	79	U+05E9	6C	# HEBREW LETTER SHIN
	7A	U+05EA	6D	# HEBREW LETTER TAV
	7B	UNDEF	1B	# undefined
	7C	UNDEF	1B	# undefined
	7D	UNDEF	1B	# undefined
	7E	UNDEF	1B	# undefined
	7F	UNDEF	1B	# undefined

# ISO Latin-2 is 8859-2
map_ISO_Latin_2
	20	U+00A0		# NO-BREAK SPACE
	21	U+0104	9A	# LATIN CAPITAL LETTER A WITH OGONEK
	22	U+02D8	90	# BREVE
	23	U+0141	9B	# LATIN CAPITAL LETTER L WITH STROKE
	24	U+00A4		# CURRENCY SIGN
	25	U+013D	9C	# LATIN CAPITAL LETTER L WITH CARON
	26	U+015A	9D	# LATIN CAPITAL LETTER S WITH ACUTE
	27	U+00A7		# SECTION SIGN
	28	U+00A8		# DIAERESIS
	29	U+0160	9E	# LATIN CAPITAL LETTER S WITH CARON
	2A	U+015E	9F	# LATIN CAPITAL LETTER S WITH CEDILLA
	2B	U+0164	21	# LATIN CAPITAL LETTER T WITH CARON
	2C	U+0179	22	# LATIN CAPITAL LETTER Z WITH ACUTE
	2D	U+00AD		# SOFT HYPHEN
	2E	U+017D	23	# LATIN CAPITAL LETTER Z WITH CARON
	2F	U+017B	24	# LATIN CAPITAL LETTER Z WITH DOT ABOVE
	30	U+00B0		# DEGREE SIGN
	31	U+0105	25	# LATIN SMALL LETTER A WITH OGONEK
	32	U+02DB	91	# OGONEK
	33	U+0142	26	# LATIN SMALL LETTER L WITH STROKE
	34	U+00B4		# ACUTE ACCENT
	35	U+013E	27	# LATIN SMALL LETTER L WITH CARON
	36	U+015B	28	# LATIN SMALL LETTER S WITH ACUTE
	37	U+02C7	92	# CARON
	38	U+00B8		# CEDILLA
	39	U+0161	29	# LATIN SMALL LETTER S WITH CARON
	3A	U+015F	2A	# LATIN SMALL LETTER S WITH CEDILLA
	3B	U+0165	2B	# LATIN SMALL LETTER T WITH CARON
	3C	U+017A	2C	# LATIN SMALL LETTER Z WITH ACUTE
	3D	U+02DD	93	# DOUBLE ACUTE ACCENT
	3E	U+017E	2D	# LATIN SMALL LETTER Z WITH CARON
	3F	U+017C	2E	# LATIN SMALL LETTER Z WITH DOT ABOVE
	40	U+0154	2F	# LATIN CAPITAL LETTER R WITH ACUTE
	41	U+00C1		# LATIN CAPITAL LETTER A WITH ACUTE
	42	U+00C2		# LATIN CAPITAL LETTER A WITH CIRCUMFLEX
	43	U+0102	30	# LATIN CAPITAL LETTER A WITH BREVE
	44	U+00C4		# LATIN CAPITAL LETTER A WITH DIAERESIS
	45	U+0139	31	# LATIN CAPITAL LETTER L WITH ACUTE
	46	U+0106	32	# LATIN CAPITAL LETTER C WITH ACUTE
	47	U+00C7		# LATIN CAPITAL LETTER C WITH CEDILLA
	48	U+010C	33	# LATIN CAPITAL LETTER C WITH CARON
	49	U+00C9		# LATIN CAPITAL LETTER E WITH ACUTE
	4A	U+0118	34	# LATIN CAPITAL LETTER E WITH OGONEK
	4B	U+00CB		# LATIN CAPITAL LETTER E WITH DIAERESIS
	4C	U+011A	35	# LATIN CAPITAL LETTER E WITH CARON
	4D	U+00CD		# LATIN CAPITAL LETTER I WITH ACUTE
	4E	U+00CE		# LATIN CAPITAL LETTER I WITH CIRCUMFLEX
	4F	U+010E	36	# LATIN CAPITAL LETTER D WITH CARON
	50	U+0110		# LATIN CAPITAL LETTER D WITH STROKE
	51	U+0143	37	# LATIN CAPITAL LETTER N WITH ACUTE
	52	U+0147	38	# LATIN CAPITAL LETTER N WITH CARON
	53	U+00D3		# LATIN CAPITAL LETTER O WITH ACUTE
	54	U+00D4		# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
	55	U+0150	39	# LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
	56	U+00D6		# LATIN CAPITAL LETTER O WITH DIAERESIS
	57	U+00D7		# MULTIPLICATION SIGN
	58	U+0158	3A	# LATIN CAPITAL LETTER R WITH CARON
	59	U+016E	3B	# LATIN CAPITAL LETTER U WITH RING ABOVE
	5A	U+00DA		# LATIN CAPITAL LETTER U WITH ACUTE
	5B	U+0170	3C	# LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
	5C	U+00DC		# LATIN CAPITAL LETTER U WITH DIAERESIS
	5D	U+00DD		# LATIN CAPITAL LETTER Y WITH ACUTE
	5E	U+0162	3D	# LATIN CAPITAL LETTER T WITH CEDILLA
	5F	U+00DF		# LATIN SMALL LETTER SHARP S
	60	U+0155	3E	# LATIN SMALL LETTER R WITH ACUTE
	61	U+00E1		# LATIN SMALL LETTER A WITH ACUTE
	62	U+00E2		# LATIN SMALL LETTER A WITH CIRCUMFLEX
	63	U+0103	3F	# LATIN SMALL LETTER A WITH BREVE
	64	U+00E4		# LATIN SMALL LETTER A WITH DIAERESIS
	65	U+013A	40	# LATIN SMALL LETTER L WITH ACUTE
	66	U+0107	41	# LATIN SMALL LETTER C WITH ACUTE
	67	U+00E7		# LATIN SMALL LETTER C WITH CEDILLA
	68	U+010D	42	# LATIN SMALL LETTER C WITH CARON
	69	U+00E9		# LATIN SMALL LETTER E WITH ACUTE
	6A	U+0119	43	# LATIN SMALL LETTER E WITH OGONEK
	6B	U+00EB		# LATIN SMALL LETTER E WITH DIAERESIS
	6C	U+011B	44	# LATIN SMALL LETTER E WITH CARON
	6D	U+00ED		# LATIN SMALL LETTER I WITH ACUTE
	6E	U+00EE		# LATIN SMALL LETTER I WITH CIRCUMFLEX
	6F	U+010F	45	# LATIN SMALL LETTER D WITH CARON
	70	U+0111	46	# LATIN SMALL LETTER D WITH STROKE
	71	U+0144	47	# LATIN SMALL LETTER N WITH ACUTE
	72	U+0148	48	# LATIN SMALL LETTER N WITH CARON
	73	U+00F3		# LATIN SMALL LETTER O WITH ACUTE
	74	U+00F4		# LATIN SMALL LETTER O WITH CIRCUMFLEX
	75	U+0151	49	# LATIN SMALL LETTER O WITH DOUBLE ACUTE
	76	U+00F6		# LATIN SMALL LETTER O WITH DIAERESIS
	77	U+00F7		# DIVISION SIGN
	78	U+0159	4A	# LATIN SMALL LETTER R WITH CARON
	79	U+016F	4B	# LATIN SMALL LETTER U WITH RING ABOVE
	7A	U+00FA		# LATIN SMALL LETTER U WITH ACUTE
	7B	U+0171	4C	# LATIN SMALL LETTER U WITH DOUBLE ACUTE
	7C	U+00FC		# LATIN SMALL LETTER U WITH DIAERESIS
	7D	U+00FD		# LATIN SMALL LETTER Y WITH ACUTE
	7E	U+0163	4D	# LATIN SMALL LETTER T WITH CEDILLA
	7F	U+02D9	94	# DOT ABOVE

# ISO Latin-5 is 8859-9
map_ISO_Latin_5
	20	U+00A0		# NO-BREAK SPACE
	21	U+00A1		# INVERTED EXCLAMATION MARK
	22	U+00A2		# CENT SIGN
	23	U+00A3		# POUND SIGN
	24	U+00A4		# CURRENCY SIGN
	25	U+00A5		# YEN SIGN
	26	U+00A6		# BROKEN BAR
	27	U+00A7		# SECTION SIGN
	28	U+00A8		# DIAERESIS
	29	U+00A9		# COPYRIGHT SIGN
	2A	U+00AA		# FEMININE ORDINAL INDICATOR
	2B	U+00AB		# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
	2C	U+00AC		# NOT SIGN
	2D	U+00AD		# SOFT HYPHEN
	2E	U+00AE		# REGISTERED SIGN
	2F	U+00AF		# MACRON
	30	U+00B0		# DEGREE SIGN
	31	U+00B1		# PLUS-MINUS SIGN
	32	U+00B2		# SUPERSCRIPT TWO
	33	U+00B3		# SUPERSCRIPT THREE
	34	U+00B4		# ACUTE ACCENT
	35	U+00B5		# MICRO SIGN
	36	U+00B6		# PILCROW SIGN
	37	U+00B7		# MIDDLE DOT
	38	U+00B8		# CEDILLA
	39	U+00B9		# SUPERSCRIPT ONE
	3A	U+00BA		# MASCULINE ORDINAL INDICATOR
	3B	U+00BB		# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
	3C	U+00BC		# VULGAR FRACTION ONE QUARTER
	3D	U+00BD		# VULGAR FRACTION ONE HALF
	3E	U+00BE		# VULGAR FRACTION THREE QUARTERS
	3F	U+00BF		# INVERTED QUESTION MARK
	40	U+00C0		# LATIN CAPITAL LETTER A WITH GRAVE
	41	U+00C1		# LATIN CAPITAL LETTER A WITH ACUTE
	42	U+00C2		# LATIN CAPITAL LETTER A WITH CIRCUMFLEX
	43	U+00C3		# LATIN CAPITAL LETTER A WITH TILDE
	44	U+00C4		# LATIN CAPITAL LETTER A WITH DIAERESIS
	45	U+00C5		# LATIN CAPITAL LETTER A WITH RING ABOVE
	46	U+00C6		# LATIN CAPITAL LETTER AE
	47	U+00C7		# LATIN CAPITAL LETTER C WITH CEDILLA
	48	U+00C8		# LATIN CAPITAL LETTER E WITH GRAVE
	49	U+00C9		# LATIN CAPITAL LETTER E WITH ACUTE
	4A	U+00CA		# LATIN CAPITAL LETTER E WITH CIRCUMFLEX
	4B	U+00CB		# LATIN CAPITAL LETTER E WITH DIAERESIS
	4C	U+00CC		# LATIN CAPITAL LETTER I WITH GRAVE
	4D	U+00CD		# LATIN CAPITAL LETTER I WITH ACUTE
	4E	U+00CE		# LATIN CAPITAL LETTER I WITH CIRCUMFLEX
	4F	U+00CF		# LATIN CAPITAL LETTER I WITH DIAERESIS
	50	U+011E	4E	# LATIN CAPITAL LETTER G WITH BREVE
	51	U+00D1		# LATIN CAPITAL LETTER N WITH TILDE
	52	U+00D2		# LATIN CAPITAL LETTER O WITH GRAVE
	53	U+00D3		# LATIN CAPITAL LETTER O WITH ACUTE
	54	U+00D4		# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
	55	U+00D5		# LATIN CAPITAL LETTER O WITH TILDE
	56	U+00D6		# LATIN CAPITAL LETTER O WITH DIAERESIS
	57	U+00D7		# MULTIPLICATION SIGN
	58	U+00D8		# LATIN CAPITAL LETTER O WITH STROKE
	59	U+00D9		# LATIN CAPITAL LETTER U WITH GRAVE
	5A	U+00DA		# LATIN CAPITAL LETTER U WITH ACUTE
	5B	U+00DB		# LATIN CAPITAL LETTER U WITH CIRCUMFLEX
	5C	U+00DC		# LATIN CAPITAL LETTER U WITH DIAERESIS
	5D	U+0130	4F	# LATIN CAPITAL LETTER I WITH DOT ABOVE
	5E	U+015E	9F	# LATIN CAPITAL LETTER S WITH CEDILLA
	5F	U+00DF		# LATIN SMALL LETTER SHARP S
	60	U+00E0		# LATIN SMALL LETTER A WITH GRAVE
	61	U+00E1		# LATIN SMALL LETTER A WITH ACUTE
	62	U+00E2		# LATIN SMALL LETTER A WITH CIRCUMFLEX
	63	U+00E3		# LATIN SMALL LETTER A WITH TILDE
	64	U+00E4		# LATIN SMALL LETTER A WITH DIAERESIS
	65	U+00E5		# LATIN SMALL LETTER A WITH RING ABOVE
	66	U+00E6		# LATIN SMALL LETTER AE
	67	U+00E7		# LATIN SMALL LETTER C WITH CEDILLA
	68	U+00E8		# LATIN SMALL LETTER E WITH GRAVE
	69	U+00E9		# LATIN SMALL LETTER E WITH ACUTE
	6A	U+00EA		# LATIN SMALL LETTER E WITH CIRCUMFLEX
	6B	U+00EB		# LATIN SMALL LETTER E WITH DIAERESIS
	6C	U+00EC		# LATIN SMALL LETTER I WITH GRAVE
	6D	U+00ED		# LATIN SMALL LETTER I WITH ACUTE
	6E	U+00EE		# LATIN SMALL LETTER I WITH CIRCUMFLEX
	6F	U+00EF		# LATIN SMALL LETTER I WITH DIAERESIS
	70	U+011F	50	# LATIN SMALL LETTER G WITH BREVE
	71	U+00F1		# LATIN SMALL LETTER N WITH TILDE
	72	U+00F2		# LATIN SMALL LETTER O WITH GRAVE
	73	U+00F3		# LATIN SMALL LETTER O WITH ACUTE
	74	U+00F4		# LATIN SMALL LETTER O WITH CIRCUMFLEX
	75	U+00F5		# LATIN SMALL LETTER O WITH TILDE
	76	U+00F6		# LATIN SMALL LETTER O WITH DIAERESIS
	77	U+00F7		# DIVISION SIGN
	78	U+00F8		# LATIN SMALL LETTER O WITH STROKE
	79	U+00F9		# LATIN SMALL LETTER U WITH GRAVE
	7A	U+00FA		# LATIN SMALL LETTER U WITH ACUTE
	7B	U+00FB		# LATIN SMALL LETTER U WITH CIRCUMFLEX
	7C	U+00FC		# LATIN SMALL LETTER U WITH DIAERESIS
	7D	U+0131	51	# LATIN SMALL LETTER DOTLESS I
	7E	U+015F	2A	# LATIN SMALL LETTER S WITH CEDILLA
	7F	U+00FF		# LATIN SMALL LETTER Y WITH DIAERESIS

# DEC Cyrillic from screenshot
map_DEC_Cyrillic
	21	UNDEF	1B	# undefined
	22	UNDEF	1B	# undefined
	23	UNDEF	1B	# undefined
	24	UNDEF	1B	# undefined
	25	UNDEF	1B	# undefined
	26	UNDEF	1B	# undefined
	27	UNDEF	1B	# undefined
	28	UNDEF	1B	# undefined
	29	UNDEF	1B	# undefined
	2A	UNDEF	1B	# undefined
	2B	UNDEF	1B	# undefined
	2C	UNDEF	1B	# undefined
	2D	UNDEF	1B	# undefined
	2E	UNDEF	1B	# undefined
	2F	UNDEF	1B	# undefined
	30	UNDEF	1B	# undefined
	31	UNDEF	1B	# undefined
	32	UNDEF	1B	# undefined
	33	UNDEF	1B	# undefined
	34	UNDEF	1B	# undefined
	35	UNDEF	1B	# undefined
	36	UNDEF	1B	# undefined
	37	UNDEF	1B	# undefined
	38	UNDEF	1B	# undefined
	39	UNDEF	1B	# undefined
	3A	UNDEF	1B	# undefined
	3B	UNDEF	1B	# undefined
	3C	UNDEF	1B	# undefined
	3D	UNDEF	1B	# undefined
	3E	UNDEF	1B	# undefined
	3F	UNDEF	1B	# undefined
	40	U+044E	4F	# CYRILLIC SMALL LETTER YU
	41	U+0430	31	# CYRILLIC SMALL LETTER A
	42	U+0431	32	# CYRILLIC SMALL LETTER BE
	43	U+0446	47	# CYRILLIC SMALL LETTER TSE
	44	U+0434	35	# CYRILLIC SMALL LETTER DE
	45	U+0435	36	# CYRILLIC SMALL LETTER IE
	46	U+0444	45	# CYRILLIC SMALL LETTER EF
	47	U+0433	34	# CYRILLIC SMALL LETTER GHE
	48	U+0445	46	# CYRILLIC SMALL LETTER HA
	49	U+0438	39	# CYRILLIC SMALL LETTER I
	4A	U+0439	3A	# CYRILLIC SMALL LETTER SHORT I
	4B	U+043A	3B	# CYRILLIC SMALL LETTER KA
	4C	U+043B	3C	# CYRILLIC SMALL LETTER EL
	4D	U+043C	3D	# CYRILLIC SMALL LETTER EM
	4E	U+043D	3E	# CYRILLIC SMALL LETTER EN
	4F	U+043E	3F	# CYRILLIC SMALL LETTER O
	50	U+043F	40	# CYRILLIC SMALL LETTER PE
	51	U+044F	50	# CYRILLIC SMALL LETTER YA
	52	U+0440	41	# CYRILLIC SMALL LETTER ER
	53	U+0441	42	# CYRILLIC SMALL LETTER ES
	54	U+0442	43	# CYRILLIC SMALL LETTER TE
	55	U+0443	44	# CYRILLIC SMALL LETTER U
	56	U+0436	37	# CYRILLIC SMALL LETTER ZHE
	57	U+0432	33	# CYRILLIC SMALL LETTER VE
	58	U+044C	4D	# CYRILLIC SMALL LETTER SOFT SIGN
	59	U+044B	4C	# CYRILLIC SMALL LETTER YERU
	5A	U+0437	38	# CYRILLIC SMALL LETTER ZE
	5B	U+0448	49	# CYRILLIC SMALL LETTER SHA
	5C	U+044D	4E	# CYRILLIC SMALL LETTER E
	5D	U+0449	4A	# CYRILLIC SMALL LETTER SHCHA
	5E	U+0447	48	# CYRILLIC SMALL LETTER CHE
	5F	U+044A	4B	# CYRILLIC SMALL LETTER HARD SIGN
	60	U+042E	2F	# CYRILLIC CAPITAL LETTER YU
	61	U+0410	11	# CYRILLIC CAPITAL LETTER A
	62	U+0411	12	# CYRILLIC CAPITAL LETTER BE
	63	U+0426	27	# CYRILLIC CAPITAL LETTER TSE
	64	U+0414	15	# CYRILLIC CAPITAL LETTER DE
	65	U+0415	16	# CYRILLIC CAPITAL LETTER IE
	66	U+0424	25	# CYRILLIC CAPITAL LETTER EF
	67	U+0413	14	# CYRILLIC CAPITAL LETTER GHE
	68	U+0425	26	# CYRILLIC CAPITAL LETTER HA
	69	U+0418	19	# CYRILLIC CAPITAL LETTER I
	6A	U+0419	1A	# CYRILLIC CAPITAL LETTER SHORT I
	6B	U+041A	1B	# CYRILLIC CAPITAL LETTER KA
	6C	U+041B	1C	# CYRILLIC CAPITAL LETTER EL
	6D	U+041C	1D	# CYRILLIC CAPITAL LETTER EM
	6E	U+041D	1E	# CYRILLIC CAPITAL LETTER EN
	6F	U+041E	1F	# CYRILLIC CAPITAL LETTER O
	70	U+041F	20	# CYRILLIC CAPITAL LETTER PE
	71	U+042F	30	# CYRILLIC CAPITAL LETTER YA
	72	U+0420	21	# CYRILLIC CAPITAL LETTER ER
	73	U+0421	22	# CYRILLIC CAPITAL LETTER ES
	74	U+0422	23	# CYRILLIC CAPITAL LETTER TE
	75	U+0423	24	# CYRILLIC CAPITAL LETTER U
	76	U+0416	17	# CYRILLIC CAPITAL LETTER ZHE
	77	U+0412	13	# CYRILLIC CAPITAL LETTER VE
	78	U+042C	2D	# CYRILLIC CAPITAL LETTER SOFT SIGN
	79	U+042B	2C	# CYRILLIC CAPITAL LETTER YERU
	7A	U+0417	18	# CYRILLIC CAPITAL LETTER ZE
	7B	U+0428	29	# CYRILLIC CAPITAL LETTER SHA
	7C	U+042D	2E	# CYRILLIC CAPITAL LETTER E
	7D	U+0429	2A	# CYRILLIC CAPITAL LETTER SHCHA
	7E	U+0427	28	# CYRILLIC CAPITAL LETTER CHE

# figure A-24 "DEC Greek Supplemental Character Set"
map_DEC_Greek_Supp
	21	U+00A1		# LEFT SINGLE QUOTATION MARK
	22	U+00A2		# RIGHT SINGLE QUOTATION MARK
	23	U+00A3		# POUND SIGN
	24	UNDEF	1B	# EURO SIGN
	25	U+00A5		# YEN SIGN
	26	UNDEF	1B	# BROKEN BAR
	27	U+00A7		# SECTION SIGN
	28	U+00A4	A4	# CURRENCY SIGN
	29	U+00A9		# COPYRIGHT SIGN
	2A	U+00AA		# FEMININE ORDINAL INDICATOR
	2B	U+00AB		# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
	2C	UNDEF	1B	# reserved
	2D	UNDEF	1B	# reserved
	2E	UNDEF	1B	# reserved
	2F	UNDEF	1B	# reserved
	30	U+00B0		# DEGREE SIGN
	31	U+00B1		# PLUS-MINUS SIGN
	32	U+00B2		# SUPERSCRIPT TWO
	33	U+00B3		# SUPERSCRIPT THREE
	34	UNDEF	1B	# reserved
	35	U+00B5		# MICRO SIGN
	36	U+00B6		# PILCROW SIGN
	37	U+00B7		# MIDDLE DOT
	38	UNDEF	1B	# reserved
	39	U+00B9		# SUPERSCRIPT ONE
	3A	U+00BA		# MASCULINE ORDINAL INDICATOR
	3B	U+00BB		# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
	3C	U+00BC		# VULGAR FRACTION ONE QUARTER
	3D	U+00BD		# VULGAR FRACTION ONE HALF
	3E	UNDEF	1B	# reserved
	3F	U+00BF		# INVERTED QUESTION MARK
	40	U+03CA	D0	# GREEK SMALL LETTER IOTA WITH DIALYTIKA
	41	U+0391	76	# GREEK CAPITAL LETTER ALPHA
	42	U+0392	77	# GREEK CAPITAL LETTER BETA
	43	U+0393	78	# GREEK CAPITAL LETTER GAMMA
	44	U+0394	79	# GREEK CAPITAL LETTER DELTA
	45	U+0395	7A	# GREEK CAPITAL LETTER EPSILON
	46	U+0396	7B	# GREEK CAPITAL LETTER ZETA
	47	U+0397	7C	# GREEK CAPITAL LETTER ETA
	48	U+0398	7D	# GREEK CAPITAL LETTER THETA
	49	U+0399	7E	# GREEK CAPITAL LETTER IOTA
	4A	U+039A	7F	# GREEK CAPITAL LETTER KAPPA
	4B	U+039B	A2	# GREEK CAPITAL LETTER LAMDA
	4C	U+039C	A3	# GREEK CAPITAL LETTER MU
	4D	U+039D	A4	# GREEK CAPITAL LETTER NU
	4E	U+039E	A5	# GREEK CAPITAL LETTER XI
	4F	U+039F	A6	# GREEK CAPITAL LETTER OMICRON
	50	UNDEF	1B	# reserved
	51	U+03A0	A7	# GREEK CAPITAL LETTER PI
	52	U+03A1	A8	# GREEK CAPITAL LETTER RHO
	53	U+03A3	A9	# GREEK CAPITAL LETTER SIGMA
	54	U+03A4	AA	# GREEK CAPITAL LETTER TAU
	55	U+03A5	AB	# GREEK CAPITAL LETTER UPSILON
	56	U+03A6	AC	# GREEK CAPITAL LETTER PHI
	57	U+03A7	AD	# GREEK CAPITAL LETTER CHI
	58	U+03A8	AE	# GREEK CAPITAL LETTER PSI
	59	U+03A9	AF	# GREEK CAPITAL LETTER OMEGA
	5A	U+03AC	B2	# GREEK SMALL LETTER ALPHA WITH TONOS
	5B	U+03AD	B3	# GREEK SMALL LETTER EPSILON WITH TONOS
	5C	U+03AE	B4	# GREEK SMALL LETTER ETA WITH TONOS
	5D	U+03AF	B5	# GREEK SMALL LETTER IOTA WITH TONOS
	5E	UNDEF	1B	# reserved
	5F	U+03CC	D2	# GREEK SMALL LETTER OMICRON WITH TONOS
	60	U+03CB	D1	# GREEK SMALL LETTER UPSILON WITH DIALYTIKA
	61	U+03B1	B7	# GREEK SMALL LETTER ALPHA
	62	U+03B2	B8	# GREEK SMALL LETTER BETA
	63	U+03B3	B9	# GREEK SMALL LETTER GAMMA
	64	U+03B4	BA	# GREEK SMALL LETTER DELTA
	65	U+03B5	BB	# GREEK SMALL LETTER EPSILON
	66	U+03B6	BC	# GREEK SMALL LETTER ZETA
	67	U+03B7	BD	# GREEK SMALL LETTER ETA
	68	U+03B8	BE	# GREEK SMALL LETTER THETA
	69	U+03B9	BF	# GREEK SMALL LETTER IOTA
	6A	U+03BA	C0	# GREEK SMALL LETTER KAPPA
	6B	U+03BB	C1	# GREEK SMALL LETTER LAMDA
	6C	U+03BC	C2	# GREEK SMALL LETTER MU
	6D	U+03BD	C3	# GREEK SMALL LETTER NU
	6E	U+03BE	C4	# GREEK SMALL LETTER XI
	6F	U+03BF	C5	# GREEK SMALL LETTER OMICRON
	70	UNDEF	1B	# reserved
	71	U+03C0	C6	# GREEK SMALL LETTER PI
	72	U+03C1	C7	# GREEK SMALL LETTER RHO
	73	U+03C3	C9	# GREEK SMALL LETTER SIGMA
	74	U+03C4	CA	# GREEK SMALL LETTER TAU
	75	U+03C5	CB	# GREEK SMALL LETTER UPSILON
	76	U+03C6	CC	# GREEK SMALL LETTER PHI
	77	U+03C7	CD	# GREEK SMALL LETTER CHI
	78	U+03C8	CE	# GREEK SMALL LETTER PSI
	79	U+03C9	CF	# GREEK SMALL LETTER OMEGA
	7A	U+03C2	C8	# GREEK SMALL LETTER FINAL SIGMA
	7B	U+03CD	D3	# GREEK SMALL LETTER UPSILON WITH TONOS
	7C	U+03CE	D4	# GREEK SMALL LETTER OMEGA WITH TONOS
	7D	U+0384	96	# GREEK TONOS
	7E	UNDEF	1B	# reserved

# figure A-22 "DEC Hebrew Supplemental Character Set"
map_DEC_Hebrew_Supp
	21	U+00A1		# INVERTED EXCLAMATION MARK
	22	U+00A2		# CENT SIGN
	23	U+00A3		# POUND SIGN
	24	UNDEF	1B	# CURRENCY SIGN
	25	U+00A5		# YEN SIGN
	26	UNDEF	1B	# BROKEN BAR
	27	U+00A7		# SECTION SIGN
	28	U+00A8	A4	# DIAERESIS
	29	U+00A9		# COPYRIGHT SIGN
	2A	U+00D7		# MULTIPLICATION SIGN
	2B	U+00AB		# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
	2C	UNDEF	1B	# NOT SIGN
	2D	UNDEF	1B	# SOFT HYPHEN
	2E	UNDEF	1B	# REGISTERED SIGN
	2F	UNDEF	1B	# MACRON
	30	U+00B0		# DEGREE SIGN
	31	U+00B1		# PLUS-MINUS SIGN
	32	U+00B2		# SUPERSCRIPT TWO
	33	U+00B3		# SUPERSCRIPT THREE
	34	UNDEF	1B	# ACUTE ACCENT
	35	U+00B5		# MICRO SIGN
	36	U+00B6		# PILCROW SIGN
	37	U+00B7		# MIDDLE DOT
	38	UNDEF	1B	# CEDILLA
	39	U+00B9		# SUPERSCRIPT ONE
	3A	U+00F7		# DIVISION SIGN
	3B	U+00BB		# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
	3C	U+00BC		# VULGAR FRACTION ONE QUARTER
	3D	U+00BD		# VULGAR FRACTION ONE HALF
	3E	UNDEF	1B	# VULGAR FRACTION THREE QUARTERS
	3F	U+00BF		# INVERTED QUESTION MARK
	40	UNDEF	1B	# reserved
	41	UNDEF	1B	# reserved
	42	UNDEF	1B	# reserved
	43	UNDEF	1B	# reserved
	44	UNDEF	1B	# reserved
	45	UNDEF	1B	# reserved
	46	UNDEF	1B	# reserved
	47	UNDEF	1B	# reserved
	48	UNDEF	1B	# reserved
	49	UNDEF	1B	# reserved
	4A	UNDEF	1B	# reserved
	4B	UNDEF	1B	# reserved
	4C	UNDEF	1B	# reserved
	4D	UNDEF	1B	# reserved
	4E	UNDEF	1B	# reserved
	4F	UNDEF	1B	# reserved
	50	UNDEF	1B	# reserved
	51	UNDEF	1B	# reserved
	52	UNDEF	1B	# reserved
	53	UNDEF	1B	# reserved
	54	UNDEF	1B	# reserved
	55	UNDEF	1B	# reserved
	56	UNDEF	1B	# reserved
	57	UNDEF	1B	# reserved
	58	UNDEF	1B	# reserved
	59	UNDEF	1B	# reserved
	5A	UNDEF	1B	# reserved
	5B	UNDEF	1B	# reserved
	5C	UNDEF	1B	# reserved
	5D	UNDEF	1B	# reserved
	5E	UNDEF	1B	# reserved
	5F	UNDEF	1B	# reserved
	60	U+05D0	53	# HEBREW LETTER ALEF
	61	U+05D1	54	# HEBREW LETTER BET
	62	U+05D2	55	# HEBREW LETTER GIMEL
	63	U+05D3	56	# HEBREW LETTER DALET
	64	U+05D4	57	# HEBREW LETTER HE
	65	U+05D5	58	# HEBREW LETTER VAV
	66	U+05D6	59	# HEBREW LETTER ZAYIN
	67	U+05D7	5A	# HEBREW LETTER HET
	68	U+05D8	5B	# HEBREW LETTER TET
	69	U+05D9	5C	# HEBREW LETTER YOD
	6A	U+05DA	5D	# HEBREW LETTER FINAL KAF
	6B	U+05DB	5E	# HEBREW LETTER KAF
	6C	U+05DC	5F	# HEBREW LETTER LAMED
	6D	U+05DD	60	# HEBREW LETTER FINAL MEM
	6E	U+05DE	61	# HEBREW LETTER MEM
	6F	U+05DF	62	# HEBREW LETTER FINAL NUN
	70	U+05E0	63	# HEBREW LETTER NUN
	71	U+05E1	64	# HEBREW LETTER SAMEKH
	72	U+05E2	65	# HEBREW LETTER AYIN
	73	U+05E3	66	# HEBREW LETTER FINAL PE
	74	U+05E4	67	# HEBREW LETTER PE
	75	U+05E5	68	# HEBREW LETTER FINAL TSADI
	76	U+05E6	69	# HEBREW LETTER TSADI
	77	U+05E7	6A	# HEBREW LETTER QOF
	78	U+05E8	6B	# HEBREW LETTER RESH
	79	U+05E9	6C	# HEBREW LETTER SHIN
	7A	U+05EA	6D	# HEBREW LETTER TAV
	7B	UNDEF	1B	# reserved
	7C	UNDEF	1B	# reserved
	7D	UNDEF	1B	# reserved
	7E	UNDEF	1B	# reserved

# figure A-27 "DEC 8-Bit Turkish Supplemental Character Set"
map_DEC_Turkish_Supp
	21	U+00A1		# INVERTED EXCLAMATION MARK
	22	U+00A2		# CENT SIGN
	23	U+00A3		# POUND SIGN
	24	UNDEF	1B	# reserved
	25	U+00A5		# YEN SIGN
	26	UNDEF	1B	# reserved
	27	U+00A7		# SECTION SIGN
	28	U+00A8	A4	# DIAERESIS
	29	U+00A9		# COPYRIGHT SIGN
	2A	U+00AA		# FEMININE ORDINAL INDICATOR
	2B	U+00AB		# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
	2C	UNDEF	1B	# reserved
	2D	UNDEF	1B	# reserved
	2E	U+0130	4F	# LATIN CAPITAL LETTER I WITH DOT ABOVE
	2F	UNDEF	1B	# reserved
	30	U+00B0		# DEGREE SIGN
	31	U+00B1		# PLUS-MINUS SIGN
	32	U+00B2		# SUPERSCRIPT TWO
	33	U+00B3		# SUPERSCRIPT THREE
	34	UNDEF	1B	# reserved
	35	U+00B5		# MICRO SIGN
	36	U+00B6		# PILCROW SIGN
	37	U+00B7		# MIDDLE DOT
	38	UNDEF	1B	# reserved
	39	U+00B9		# SUPERSCRIPT ONE
	3A	U+00BA		# MASCULINE ORDINAL INDICATOR
	3B	U+00BB		# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
	3C	U+00BC		# VULGAR FRACTION ONE QUARTER
	3D	U+00BD		# VULGAR FRACTION ONE HALF
	3E	U+0131	51	# LATIN SMALL LETTER DOTLESS I
	3F	U+00BF		# INVERTED QUESTION MARK
	40	U+00C0		# LATIN CAPITAL LETTER A WITH GRAVE
	41	U+00C1		# LATIN CAPITAL LETTER A WITH ACUTE
	42	U+00C2		# LATIN CAPITAL LETTER A WITH CIRCUMFLEX
	43	U+00C3		# LATIN CAPITAL LETTER A WITH TILDE
	44	U+00C4		# LATIN CAPITAL LETTER A WITH DIAERESIS
	45	U+00C5		# LATIN CAPITAL LETTER A WITH RING ABOVE
	46	U+00C6		# LATIN CAPITAL LETTER AE
	47	U+00C7		# LATIN CAPITAL LETTER C WITH CEDILLA
	48	U+00C8		# LATIN CAPITAL LETTER E WITH GRAVE
	49	U+00C9		# LATIN CAPITAL LETTER E WITH ACUTE
	4A	U+00CA		# LATIN CAPITAL LETTER E WITH CIRCUMFLEX
	4B	U+00CB		# LATIN CAPITAL LETTER E WITH DIAERESIS
	4C	U+00CC		# LATIN CAPITAL LETTER I WITH GRAVE
	4D	U+00CD		# LATIN CAPITAL LETTER I WITH ACUTE
	4E	U+00CE		# LATIN CAPITAL LETTER I WITH CIRCUMFLEX
	4F	U+00CF		# LATIN CAPITAL LETTER I WITH DIAERESIS
	50	U+011E	4E	# LATIN CAPITAL LETTER G WITH BREVE
	51	U+00D1		# LATIN CAPITAL LETTER N WITH TILDE
	52	U+00D2		# LATIN CAPITAL LETTER O WITH GRAVE
	53	U+00D3		# LATIN CAPITAL LETTER O WITH ACUTE
	54	U+00D4		# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
	55	U+00D5		# LATIN CAPITAL LETTER O WITH TILDE
	56	U+00D6		# LATIN CAPITAL LETTER O WITH DIAERESIS
	57	U+0152	97	# LATIN CAPITAL LIGATURE OE
	58	U+00D8		# LATIN CAPITAL LETTER O WITH STROKE
	59	U+00D9		# LATIN CAPITAL LETTER U WITH GRAVE
	5A	U+00DA		# LATIN CAPITAL LETTER U WITH ACUTE
	5B	U+00DB		# LATIN CAPITAL LETTER U WITH CIRCUMFLEX
	5C	U+00DC		# LATIN CAPITAL LETTER U WITH DIAERESIS
	5D	U+0178	98	# LATIN CAPITAL LETTER Y WITH DIAERESIS
	5E	U+015E	9F	# LATIN CAPITAL LETTER S WITH CEDILLA
	5F	U+00DF		# LATIN SMALL LETTER SHARP S
	60	U+00E0		# LATIN SMALL LETTER A WITH GRAVE
	61	U+00E1		# LATIN SMALL LETTER A WITH ACUTE
	62	U+00E2		# LATIN SMALL LETTER A WITH CIRCUMFLEX
	63	U+00E3		# LATIN SMALL LETTER A WITH TILDE
	64	U+00E4		# LATIN SMALL LETTER A WITH DIAERESIS
	65	U+00E5		# LATIN SMALL LETTER A WITH RING ABOVE
	66	U+00E6		# LATIN SMALL LETTER AE
	67	U+00E7		# LATIN SMALL LETTER C WITH CEDILLA
	68	U+00E8		# LATIN SMALL LETTER E WITH GRAVE
	69	U+00E9		# LATIN SMALL LETTER E WITH ACUTE
	6A	U+00EA		# LATIN SMALL LETTER E WITH CIRCUMFLEX
	6B	U+00EB		# LATIN SMALL LETTER E WITH DIAERESIS
	6C	U+00EC		# LATIN SMALL LETTER I WITH GRAVE
	6D	U+00ED		# LATIN SMALL LETTER I WITH ACUTE
	6E	U+00EE		# LATIN SMALL LETTER I WITH CIRCUMFLEX
	6F	U+00EF		# LATIN SMALL LETTER I WITH DIAERESIS
	70	U+011F	50	# LATIN SMALL LETTER G WITH BREVE
	71	U+00F1		# LATIN SMALL LETTER N WITH TILDE
	72	U+00F2		# LATIN SMALL LETTER O WITH GRAVE
	73	U+00F3		# LATIN SMALL LETTER O WITH ACUTE
	74	U+00F4		# LATIN SMALL LETTER O WITH CIRCUMFLEX
	75	U+00F5		# LATIN SMALL LETTER O WITH TILDE
	76	U+00F6		# LATIN SMALL LETTER O WITH DIAERESIS
	77	U+0153	99	# LATIN SMALL LIGATURE OE
	78	U+00F8		# LATIN SMALL LETTER O WITH STROKE
	79	U+00F9		# LATIN SMALL LETTER U WITH GRAVE
	7A	U+00FA		# LATIN SMALL LETTER U WITH ACUTE
	7B	U+00FB		# LATIN SMALL LETTER U WITH CIRCUMFLEX
	7C	U+00FC		# LATIN SMALL LETTER U WITH DIAERESIS
	7D	U+00FF	FF	# LATIN SMALL LETTER Y WITH DIAERESIS
	7E	U+015F	2A	# LATIN SMALL LETTER S WITH CEDILLA

# mentioned, but not documented in VT510 manual, etc., this uses
# the ELOT927 table from Kermit 95:
map_NRCS_Greek
	61	U+0391		# CAPITAL GREEK LETTER ALPHA
	62	U+0392		# CAPITAL GREEK LETTER BETA
	63	U+0393		# CAPITAL GREEK LETTER GAMMA
	64	U+0394		# CAPITAL GREEK LETTER DELTA
	65	U+0395		# CAPITAL GREEK LETTER EPSILON
	66	U+0396		# CAPITAL GREEK LETTER ZETA
	67	U+0397		# CAPITAL GREEK LETTER ETA
	68	U+0398		# CAPITAL GREEK LETTER THETA
	69	U+0399		# CAPITAL GREEK LETTER IOTA
	6a	U+039A		# CAPITAL GREEK LETTER KAPPA
	6b	U+039B		# CAPITAL GREEK LETTER LAMDA
	6c	U+039C		# CAPITAL GREEK LETTER MU
	6d	U+039D		# CAPITAL GREEK LETTER NU
	6e	U+03A7		# CAPITAL GREEK LETTER KSI (CHI)
	6f	U+039F		# CAPITAL GREEK LETTER OMICRON
	70	U+03A0		# CAPITAL GREEK LETTER PI
	71	U+03A1		# CAPITAL GREEK LETTER RHO
	72	U+03A3		# CAPITAL GREEK LETTER SIGMA
	73	U+03A4		# CAPITAL GREEK LETTER TAU
	74	U+03A5		# CAPITAL GREEK LETTER UPSILON
	75	U+03A6		# CAPITAL GREEK LETTER FI (PHI)
	76	U+039E		# CAPITAL GREEK LETTER XI
	77	U+03A8		# CAPITAL GREEK LETTER PSI
	78	U+03A9		# CAPITAL GREEK LETTER OMEGA
	79	UNDEF	1B 	# unused
	7a	UNDEF	1B 	# unused

# figure A-21 "DEC 7-Bit Hebrew Character Set"
map_NRCS_Hebrew
	60	U+05D0		# HEBREW LETTER ALEF
	61	U+05D1		# HEBREW LETTER BET
	62	U+05D2		# HEBREW LETTER GIMEL
	63	U+05D3		# HEBREW LETTER DALET
	64	U+05D4		# HEBREW LETTER HE
	65	U+05D5		# HEBREW LETTER VAV
	66	U+05D6		# HEBREW LETTER ZAYIN
	67	U+05D7		# HEBREW LETTER HET
	68	U+05D8		# HEBREW LETTER TET
	69	U+05D9		# HEBREW LETTER YOD
	6a	U+05DA		# HEBREW LETTER FINAL KAF
	6b	U+05DB		# HEBREW LETTER KAF
	6c	U+05DC		# HEBREW LETTER LAMED
	6d	U+05DD		# HEBREW LETTER FINAL MEM
	6e	U+05DE		# HEBREW LETTER MEM
	6f	U+05DF		# HEBREW LETTER FINAL NUN
	70	U+05E0		# HEBREW LETTER NUN
	71	U+05E1		# HEBREW LETTER SAMEKH
	72	U+05E2		# HEBREW LETTER AYIN
	73	U+05E3		# HEBREW LETTER FINAL PE
	74	U+05E4		# HEBREW LETTER PE
	75	U+05E5		# HEBREW LETTER FINAL TSADI
	76	U+05E6		# HEBREW LETTER TSADI
	77	U+05E7		# HEBREW LETTER QOF
	78	U+05E8		# HEBREW LETTER RESH
	79	U+05E9		# HEBREW LETTER SHIN
	7a	U+05EA		# HEBREW LETTER TAV

# VT520/VT525 manual p 4-35 explains "SCS" as Serbo-Croatian.  The remaining
# "S" may be Slovene.  With that clue, choose ISO-IR-141, which provides a
# chart with names of suitable replacement characters.
map_NRCS_Serbo_Croatian
	40	U+017D		# LATIN CAPITAL LETTER Z WITH CARON
	5B	U+0160		# LATIN CAPITAL LETTER S WITH CARON
	5C	U+0110		# LATIN CAPITAL LETTER D WITH STROKE
	5D	U+0106		# LATIN CAPITAL LETTER C WITH ACUTE
	5E	U+010C		# LATIN CAPITAL LETTER C WITH CARON
	60	U+017E		# LATIN SMALL LETTER Z WITH CARON
	7B	U+0161		# LATIN SMALL LETTER S WITH CARON
	7C	U+0111		# LATIN SMALL LETTER D WITH STROKE
	7D	U+0107		# LATIN SMALL LETTER C WITH ACUTE
	7E	U+010D		# LATIN SMALL LETTER C WITH CARON

# VT520/VT525 manual p 7-2 explains "Russian" as KOI-7, though the dialect
# is unknown.  Choose the one Kermit used.
map_NRCS_Russian
	60	U+042E		# CYRILLIC CAPITAL LETTER YU
	61	U+0410		# CYRILLIC CAPITAL LETTER A
	62	U+0411		# CYRILLIC CAPITAL LETTER BE
	63	U+0426		# CYRILLIC CAPITAL LETTER TSE
	64	U+0414		# CYRILLIC CAPITAL LETTER DE
	65	U+0415		# CYRILLIC CAPITAL LETTER IE
	66	U+0424		# CYRILLIC CAPITAL LETTER EF
	67	U+0413		# CYRILLIC CAPITAL LETTER GHE
	68	U+0425		# CYRILLIC CAPITAL LETTER HA
	69	U+0418		# CYRILLIC CAPITAL LETTER I
	6A	U+0419		# CYRILLIC CAPITAL LETTER SHORT I
	6B	U+041A		# CYRILLIC CAPITAL LETTER KA
	6C	U+041B		# CYRILLIC CAPITAL LETTER EL
	6D	U+041C		# CYRILLIC CAPITAL LETTER EM
	6E	U+041D		# CYRILLIC CAPITAL LETTER EN
	6F	U+041E		# CYRILLIC CAPITAL LETTER O
	70	U+041F		# CYRILLIC CAPITAL LETTER PE
	71	U+042F		# CYRILLIC CAPITAL LETTER YA
	72	U+0420		# CYRILLIC CAPITAL LETTER ER
	73	U+0421		# CYRILLIC CAPITAL LETTER ES
	74	U+0422		# CYRILLIC CAPITAL LETTER TE
	75	U+0423		# CYRILLIC CAPITAL LETTER U
	76	U+0416		# CYRILLIC CAPITAL LETTER ZHE
	77	U+0412		# CYRILLIC CAPITAL LETTER VE
	78	U+042C		# CYRILLIC CAPITAL LETTER SOFT SIGN
	79	U+042B		# CYRILLIC CAPITAL LETTER YERU
	7A	U+0417		# CYRILLIC CAPITAL LETTER ZE
	7B	U+0428		# CYRILLIC CAPITAL LETTER SHA
	7C	U+042D		# CYRILLIC CAPITAL LETTER E
	7D	U+0429		# CYRILLIC CAPITAL LETTER SHCHA
	7E	U+0427		# CYRILLIC CAPITAL LETTER CHE

# figure A-26 "DEC 7-Bit Turkish Character Set"
map_NRCS_Turkish
	26	U+011F		# LATIN SMALL LETTER G WITH BREVE
	40	U+0130		# LATIN CAPITAL LETTER I WITH DOT ABOVE
	5b	U+015E		# LATIN CAPITAL LETTER S WITH CEDILLA
	5c	U+00D6		# LATIN CAPITAL LETTER O WITH DIAERESIS
	5d	U+00C7		# LATIN CAPITAL LETTER C WITH CEDILLA
	5e	U+00dC		# LATIN CAPITAL LETTER U WITH DIAERESIS
	60	U+011E		# LATIN CAPITAL LETTER G WITH BREVE
	7b	U+015F		# LATIN SMALL LETTER S WITH CEDILLA
	7c	U+00F6		# LATIN SMALL LETTER O WITH DIAERESIS
	7d	U+00E7		# LATIN SMALL LETTER C WITH CEDILLA
	7e	U+00FC		# LATIN SMALL LETTER U WITH DIAERESIS
xterm-399/koi8rxterm.man0000644000000000000000000000652414550061675014066 0ustar  rootroot.\" $XTermId: koi8rxterm.man,v 1.9 2024/01/11 21:55:09 tom Exp $
.\"
.\" Copyright 2007-2018,2024 Thomas E. Dickey
.\" Copyright 2004 Branden Robinson
.\"
.\" Permission is hereby granted, free of charge, to any person obtaining a
.\" copy of this software and associated documentation files (the "Software"),
.\" to deal in the Software without restriction, including without limitation
.\" the rights to use, copy, modify, merge, publish, distribute, sublicense,
.\" and/or sell copies of the Software, and to permit persons to whom the
.\" Software is furnished to do so, subject to the following conditions:
.\"
.\" The above copyright notice and this permission notice shall be included in
.\" all copies or substantial portions of the Software.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
.\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
.\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
.\" SOFTWARE IN THE PUBLIC INTEREST, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR
.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
.\" DEALINGS IN THE SOFTWARE.
.\"
.ds N Koi8rxterm
.ds n koi8rxterm
.\"
.TH KOI8RXTERM 1 "__app_date__" "__app_version__" "X Window System"
.\"
.ie \n(.g \{\
.ds `` \(lq
.ds '' \(rq
.ds '  \(aq
.\}
.el \{\
.ie t .ds `` ``
.el   .ds `` ""
.ie t .ds '' ''
.el   .ds '' ""
.ie t .ds '  \(aq
.el   .ds '  '
.\}
.SH NAME
koi8rxterm \-
X terminal emulator for KOI8-R environments
.SH SYNOPSIS
.B \*n
[
.I xterm-options
]
.SH DESCRIPTION
.B \*n
is a wrapper around the
.B xterm(1)
program that invokes the latter program
with the \*(``KOI8R__default_class__\*('' X resource class set.
All arguments to
.B \*n
are passed to
.B xterm
without processing; the
.B \-class
and
.B \-k8
options should not be specified because they are used by the wrapper.
See the
.B xterm
manual page for more information on
.IR xterm-options .
.PP
The environment's locale settings (see \*(``ENVIRONMENT\*('' below) are
used to discern the locale's character set.
If no current locale can be determined, the locale \*(``ru_RU.KOI8-R\*(''
(the Russian language as used in the territory of Russia, with the KOI8-R
character set) is assumed.
The
.B locale(1)
utility is used to determine whether the system supports the selected
locale.
If it does not,
.B \*n
will exit with an error and report the output of
.BR locale .
.PP
.B Note: \*n
may produce unexpected results if the current locale is set to one in which
the KOI8-R character encoding is not supported, or if fonts using that
encoding are not available.
In the Debian system, the \*(``xfonts\-cyrillic\*('' package provides the
fonts that
.B \*n
uses by default.
To change the fonts
.B \*n
uses, edit the
.I __apploaddir__/KOI8R__default_class__
file.
.PP
A similar wrapper,
.B uxterm(1),
is available for Unicode UTF-8 environments.
.SH ENVIRONMENT
.TP
.B LC_ALL\fR, \fBLC_CTYPE\fR, \fBLANG
The values of these variables are checked, in order, to determine the
character set used by the current locale.
.SH AUTHORS
.B \*n
was written by Branden Robinson and is very heavily based on
.BR uxterm ,
by Thomas Dickey.
The assistance of Jurij Smakov was invaluable in sanity-checking its
operation.
.SH "SEE ALSO"
.B locale(1),
.B locale(7),
.B uxterm(1),
.B xterm(1)
xterm-399/xcharmouse.h0000644000000000000000000000633413712115076013575 0ustar  rootroot/* $XTermId: xcharmouse.h,v 1.19 2020/08/03 23:14:06 tom Exp $ */

/************************************************************

Copyright 1997-2012,2020 by Thomas E. Dickey
Copyright 1998 by Jason Bacon 

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the above listed
copyright holder(s) not be used in advertising or publicity pertaining
to distribution of the software without specific, written prior
permission.

THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

********************************************************/

#ifndef included_xcharmouse_h
#define included_xcharmouse_h
/* *INDENT-OFF* */

/*
 * Macros for dpmodes (Thomas Dickey and others):
 * J. Bacon, acadix@execpc.com, June 1998
 * Steve Wall, September 1999
 * Ilya Zakharevich, August 2002
 * Ryan Johnson, August 2010
 * Egmont Koblinger, December 2011
 */

/* DECSET arguments for turning on mouse reporting modes */
#define SET_X10_MOUSE               9
#define SET_VT200_MOUSE             1000
#define SET_VT200_HIGHLIGHT_MOUSE   1001
#define SET_BTN_EVENT_MOUSE         1002
#define SET_ANY_EVENT_MOUSE         1003

#if OPT_FOCUS_EVENT
#define SET_FOCUS_EVENT_MOUSE       1004 /* can be combined with above */
#endif

#define SET_ALTERNATE_SCROLL        1007 /* wheel mouse may send cursor-keys */

/* Extend mouse tracking for terminals wider(taller) than 223 cols(rows) */
#define SET_EXT_MODE_MOUSE          1005 /* compatible with above */
#define SET_SGR_EXT_MODE_MOUSE      1006
#define SET_URXVT_EXT_MODE_MOUSE    1015

#define SET_PIXEL_POSITION_MOUSE    1016 /* like 1006, but pixels not chars */

#define SET_BUTTON1_MOVE_POINT      2001 /* click1 emit Esc seq to move point*/
#define SET_BUTTON2_MOVE_POINT      2002 /* press2 emit Esc seq to move point*/
#define SET_DBUTTON3_DELETE         2003 /* Double click-3 deletes */
#define SET_PASTE_IN_BRACKET        2004 /* Surround paste by escapes */
#define SET_PASTE_QUOTE             2005 /* Quote each char during paste */
#define SET_PASTE_LITERAL_NL        2006 /* Paste "\n" as C-j */

#if OPT_DEC_LOCATOR

/* Bit fields for screen->locator_events */
#define	LOC_BTNS_DN		0x1
#define	LOC_BTNS_UP		0x2

/* Special values for screen->loc_filter_* */
#define	LOC_FILTER_POS		-1

#endif /* OPT_DEC_LOCATOR */

/* Values for screen->send_mouse_pos */
typedef enum {
    MOUSE_OFF
    ,X10_MOUSE
    ,VT200_MOUSE
    ,VT200_HIGHLIGHT_MOUSE
    ,BTN_EVENT_MOUSE
    ,ANY_EVENT_MOUSE
    ,DEC_LOCATOR
} XtermMouseModes;

/* *INDENT-ON* */

#endif /* included_xcharmouse_h */
xterm-399/uxterm.man0000644000000000000000000000621714550063525013271 0ustar  rootroot.\" $XTermId: uxterm.man,v 1.9 2024/01/11 22:10:29 tom Exp $
.\"
.\" Copyright 2007-2018,2024 Thomas E. Dickey
.\" Copyright 2001, 2004 Branden Robinson
.\"
.\" Permission is hereby granted, free of charge, to any person obtaining a
.\" copy of this software and associated documentation files (the "Software"),
.\" to deal in the Software without restriction, including without limitation
.\" the rights to use, copy, modify, merge, publish, distribute, sublicense,
.\" and/or sell copies of the Software, and to permit persons to whom the
.\" Software is furnished to do so, subject to the following conditions:
.\"
.\" The above copyright notice and this permission notice shall be included in
.\" all copies or substantial portions of the Software.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
.\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
.\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
.\" SOFTWARE IN THE PUBLIC INTEREST, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR
.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
.\" DEALINGS IN THE SOFTWARE.
.\"
.ds N Uxterm
.ds n uxterm
.TH UXTERM 1 "__app_date__" "__app_version__" "X Window System"
.
.ie \n(.g \{\
.ds `` \(lq
.ds '' \(rq
.ds '  \(aq
.\}
.el \{\
.ie t .ds `` ``
.el   .ds `` ""
.ie t .ds '' ''
.el   .ds '' ""
.ie t .ds '  \(aq
.el   .ds '  '
.\}
.
.SH NAME
uxterm \-
X terminal emulator for Unicode (UTF-8) environments
.SH SYNOPSIS
.B \*n
[
.I xterm-options
]
.SH DESCRIPTION
.B \*n
is a wrapper around the
.B xterm(1)
program that invokes the latter program
with the \*(``U__default_class__\*('' X resource class set.
All arguments to
.B \*n
are passed to
.B xterm
without processing; the
.B \-class
and
.B \-u8
options should not be specified because they are used by the wrapper.
See the
.B xterm
manual page for more information on
.IR xterm-options .
.PP
The environment's locale settings (see \*(``ENVIRONMENT\*('' below) are
used to discern the locale's character set.
If no current locale can be determined, the locale \*(``en_US\*('' (the
English language as used in the territory of the United States) is assumed.
The
.B locale(1)
utility is used to determine whether the system supports the selected
locale.
If it does not,
.B \*n
will exit with an error and report the output of
.BR locale .
.PP
.B Note: \*n
may produce unexpected results if the current locale is set to one in which
the UTF-8 character encoding is not supported, or if fonts using the ISO
10646-1 character set are not available.
In the Debian system, the \*(``xfonts\-base\*('' package provides the fonts
that
.B \*n
uses by default.
To change the fonts
.B \*n
uses, edit the
.I __apploaddir__/U__default_class__
file.
.PP
A similar wrapper,
.B koi8rxterm(1),
is available for KOI8-R environments.
.SH ENVIRONMENT
.TP
.B LC_ALL\fR, \fBLC_CTYPE\fR, \fBLANG
The values of these variables are checked, in order, to determine the
character set used by the current locale.
.SH AUTHORS
Thomas Dickey
.SH "SEE ALSO"
.B locale(1),
.B locale(7),
.B koi8rxterm(1),
.B xterm(1)
xterm-399/graphics_regis.h0000644000000000000000000000364114452070470014406 0ustar  rootroot/* $XTermId: graphics_regis.h,v 1.3 2023/07/07 20:10:32 tom Exp $ */

/*
 * Copyright 2014-2016,2023 by Ross Combs
 * Copyright 2014-2016,2023 by Thomas E. Dickey
 *
 *                         All Rights Reserved
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name(s) of the above copyright
 * holders shall not be used in advertising or otherwise to promote the
 * sale, use or other dealings in this Software without prior written
 * authorization.
 */

#ifndef included_graphics_regis_h
#define included_graphics_regis_h
/* *INDENT-OFF* */

#include 

#if OPT_REGIS_GRAPHICS
extern void reset_regis(void);
extern void parse_regis(XtermWidget /* xw */, ANSI */* params */, char const */* string */);
#else
#define reset_regis() /* nothing */
#define parse_regis(xw, params, string) /* nothing */
#endif

/* *INDENT-ON* */

#endif /* included_graphics_regis_h */
xterm-399/menu.c0000644000000000000000000026725614723137774012406 0ustar  rootroot/* $XTermId: menu.c,v 1.378 2024/12/01 19:58:52 tom Exp $ */

/*
 * Copyright 1999-2023,2024 by Thomas E. Dickey
 *
 *                         All Rights Reserved
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name(s) of the above copyright
 * holders shall not be used in advertising or otherwise to promote the
 * sale, use or other dealings in this Software without prior written
 * authorization.
 *
 *
 * Copyright 1989  X Consortium
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name of the X Consortium shall not be
 * used in advertising or otherwise to promote the sale, use or other dealings
 * in this Software without prior written authorization from the X Consortium.
 */

#include 
#include 
#include 
#include 
#include 
#include 

#include 

#define app_con Xaw_app_con	/* quiet a warning from SimpleMenu.h */

#if defined(HAVE_LIB_XAW)

#include 
#include 
#include 
#include 

#if OPT_TOOLBAR
#include 
#include 
#endif

#elif defined(HAVE_LIB_XAW3D)

#include 
#include 
#include 
#include 

#if OPT_TOOLBAR
#include 
#include 
#endif

#elif defined(HAVE_LIB_XAW3DXFT)

#include 
#include 
#include 
#include 

#if OPT_TOOLBAR
#include 
#include 
#endif

#elif defined(HAVE_LIB_NEXTAW)

#include 
#include 
#include 
#include 

#if OPT_TOOLBAR
#include 
#include 
#endif

#elif defined(HAVE_LIB_XAWPLUS)

#include 
#include 
#include 
#include 

#if OPT_TOOLBAR
#include 
#include 
#endif

#endif

#undef app_con

#include 
#include 

#if OPT_TRACE
#define UpdateCheckbox(func, mn, mi, val) UpdateMenuItem(func, mn, mi, val)
#else
#define UpdateCheckbox(func, mn, mi, val) UpdateMenuItem(mn, mi, val)
#endif

#define ToggleFlag(flag) flag = (Boolean) !flag
/* *INDENT-OFF* */
static void do_8bit_control    PROTO_XT_CALLBACK_ARGS;
static void do_allow132        PROTO_XT_CALLBACK_ARGS;
static void do_allowBoldFonts  PROTO_XT_CALLBACK_ARGS;
static void do_allowsends      PROTO_XT_CALLBACK_ARGS;
static void do_altscreen       PROTO_XT_CALLBACK_ARGS;
static void do_appcursor       PROTO_XT_CALLBACK_ARGS;
static void do_appkeypad       PROTO_XT_CALLBACK_ARGS;
static void do_autolinefeed    PROTO_XT_CALLBACK_ARGS;
static void do_autowrap        PROTO_XT_CALLBACK_ARGS;
static void do_backarrow       PROTO_XT_CALLBACK_ARGS;
static void do_bellIsUrgent    PROTO_XT_CALLBACK_ARGS;
static void do_continue        PROTO_XT_CALLBACK_ARGS;
static void do_delete_del      PROTO_XT_CALLBACK_ARGS;
#if OPT_SCREEN_DUMPS
static void do_dump_html       PROTO_XT_CALLBACK_ARGS;
static void do_dump_svg        PROTO_XT_CALLBACK_ARGS;
#endif
static void do_interrupt       PROTO_XT_CALLBACK_ARGS;
static void do_jumpscroll      PROTO_XT_CALLBACK_ARGS;
static void do_keepClipboard   PROTO_XT_CALLBACK_ARGS;
static void do_keepSelection   PROTO_XT_CALLBACK_ARGS;
static void do_kill            PROTO_XT_CALLBACK_ARGS;
static void do_old_fkeys       PROTO_XT_CALLBACK_ARGS;
static void do_poponbell       PROTO_XT_CALLBACK_ARGS;
static void do_print           PROTO_XT_CALLBACK_ARGS;
static void do_print_redir     PROTO_XT_CALLBACK_ARGS;
static void do_redraw          PROTO_XT_CALLBACK_ARGS;
static void do_reversevideo    PROTO_XT_CALLBACK_ARGS;
static void do_reversewrap     PROTO_XT_CALLBACK_ARGS;
static void do_scrollbar       PROTO_XT_CALLBACK_ARGS;
static void do_scrollkey       PROTO_XT_CALLBACK_ARGS;
static void do_scrollttyoutput PROTO_XT_CALLBACK_ARGS;
static void do_securekbd       PROTO_XT_CALLBACK_ARGS;
static void do_selectClipboard PROTO_XT_CALLBACK_ARGS;
static void do_suspend         PROTO_XT_CALLBACK_ARGS;
static void do_terminate       PROTO_XT_CALLBACK_ARGS;
static void do_titeInhibit     PROTO_XT_CALLBACK_ARGS;
static void do_visualbell      PROTO_XT_CALLBACK_ARGS;
static void do_vtfont          PROTO_XT_CALLBACK_ARGS;

static GCC_NORETURN void do_clearsavedlines PROTO_XT_CALLBACK_ARGS;
static GCC_NORETURN void do_hardreset       PROTO_XT_CALLBACK_ARGS;
static GCC_NORETURN void do_quit            PROTO_XT_CALLBACK_ARGS;
static GCC_NORETURN void do_softreset       PROTO_XT_CALLBACK_ARGS;

#ifdef ALLOWLOGGING
static void do_logging         PROTO_XT_CALLBACK_ARGS;
#endif

#ifndef NO_ACTIVE_ICON
static void do_activeicon      PROTO_XT_CALLBACK_ARGS;
#endif /* NO_ACTIVE_ICON */

#if OPT_ALLOW_XXX_OPS
static void enable_allow_xxx_ops (Bool);
static void do_allowColorOps   PROTO_XT_CALLBACK_ARGS;
static void do_allowFontOps    PROTO_XT_CALLBACK_ARGS;
static void do_allowMouseOps   PROTO_XT_CALLBACK_ARGS;
static void do_allowTcapOps    PROTO_XT_CALLBACK_ARGS;
static void do_allowTitleOps   PROTO_XT_CALLBACK_ARGS;
static void do_allowWindowOps  PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_BLINK_CURS
static void do_cursorblink     PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_BOX_CHARS
static void do_font_boxchars   PROTO_XT_CALLBACK_ARGS;
static void do_font_packed     PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_DEC_CHRSET
static void do_font_doublesize PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_DEC_SOFTFONT
static void do_font_loadable   PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_HP_FUNC_KEYS
static void do_hp_fkeys        PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_MAXIMIZE
static void do_fullscreen      PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_NUM_LOCK
static void do_alt_esc         PROTO_XT_CALLBACK_ARGS;
static void do_num_lock        PROTO_XT_CALLBACK_ARGS;
static void do_meta_esc        PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_PRINT_ON_EXIT
static void do_write_now       PROTO_XT_CALLBACK_ARGS;
static void do_write_error     PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_RENDERFONT
static void do_font_renderfont PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_SCO_FUNC_KEYS
static void do_sco_fkeys       PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_SIXEL_GRAPHICS
static void do_sixelscrolling  PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_GRAPHICS
static void do_privatecolorregisters PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_SUN_FUNC_KEYS
static void do_sun_fkeys       PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_SUNPC_KBD
static void do_sun_kbd         PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_TCAP_FKEYS
static void do_tcap_fkeys      PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_TEK4014
static void do_tekcopy         PROTO_XT_CALLBACK_ARGS;
static void do_tekhide         PROTO_XT_CALLBACK_ARGS;
static void do_tekmode         PROTO_XT_CALLBACK_ARGS;
static void do_tekonoff        PROTO_XT_CALLBACK_ARGS;
static void do_tekpage         PROTO_XT_CALLBACK_ARGS;
static void do_tekreset        PROTO_XT_CALLBACK_ARGS;
static void do_tekshow         PROTO_XT_CALLBACK_ARGS;
static void do_tektext2        PROTO_XT_CALLBACK_ARGS;
static void do_tektext3        PROTO_XT_CALLBACK_ARGS;
static void do_tektextlarge    PROTO_XT_CALLBACK_ARGS;
static void do_tektextsmall    PROTO_XT_CALLBACK_ARGS;
static void do_vthide          PROTO_XT_CALLBACK_ARGS;
static void do_vtmode          PROTO_XT_CALLBACK_ARGS;
static void do_vtonoff         PROTO_XT_CALLBACK_ARGS;
static void do_vtshow          PROTO_XT_CALLBACK_ARGS;
static void handle_tekshow     (Widget gw, Bool allowswitch);
static void handle_vtshow      (Widget gw, Bool allowswitch);
#endif

#if OPT_TOOLBAR
static void do_toolbar         PROTO_XT_CALLBACK_ARGS;
#endif

#if OPT_WIDE_CHARS
static void do_font_utf8_mode  PROTO_XT_CALLBACK_ARGS;
static void do_font_utf8_fonts PROTO_XT_CALLBACK_ARGS;
static void do_font_utf8_title PROTO_XT_CALLBACK_ARGS;
#endif

/*
 * The order of entries MUST match the values given in menu.h
 */
MenuEntry mainMenuEntries[] = {
#if OPT_TOOLBAR
    { "toolbar",	do_toolbar,	NULL },
#endif
#if OPT_MAXIMIZE
    { "fullscreen",	do_fullscreen,	NULL },
#endif
    { "securekbd",	do_securekbd,	NULL },
    { "allowsends",	do_allowsends,	NULL },
    { "redraw",		do_redraw,	NULL },
    { "line1",		NULL,		NULL },
#ifdef ALLOWLOGGING
    { "logging",	do_logging,	NULL },
#endif
#if OPT_PRINT_ON_EXIT
    { "print-immediate", do_write_now,	NULL },
    { "print-on-error",	do_write_error,	NULL },
#endif
    { "print",		do_print,	NULL },
    { "print-redir",	do_print_redir,	NULL },
#if OPT_SCREEN_DUMPS
    { "dump-html",	do_dump_html,	NULL },
    { "dump-svg",	do_dump_svg,	NULL },
#endif
    { "line2",		NULL,		NULL },
    { "8-bit control",	do_8bit_control,NULL },
    { "backarrow key",	do_backarrow,	NULL },
#if OPT_NUM_LOCK
    { "num-lock",	do_num_lock,	NULL },
    { "alt-esc",	do_alt_esc,	NULL },
    { "meta-esc",	do_meta_esc,	NULL },
#endif
    { "delete-is-del",	do_delete_del,	NULL },
    { "oldFunctionKeys",do_old_fkeys,	NULL },
#if OPT_TCAP_FKEYS
    { "tcapFunctionKeys",do_tcap_fkeys,	NULL },
#endif
#if OPT_HP_FUNC_KEYS
    { "hpFunctionKeys",	do_hp_fkeys,	NULL },
#endif
#if OPT_SCO_FUNC_KEYS
    { "scoFunctionKeys",do_sco_fkeys,	NULL },
#endif
#if OPT_SUN_FUNC_KEYS
    { "sunFunctionKeys",do_sun_fkeys,	NULL },
#endif
#if OPT_SUNPC_KBD
    { "sunKeyboard",	do_sun_kbd,	NULL },
#endif
    { "line3",		NULL,		NULL },
    { "suspend",	do_suspend,	NULL },
    { "continue",	do_continue,	NULL },
    { "interrupt",	do_interrupt,	NULL },
    { "hangup",		do_hangup,	NULL },
    { "terminate",	do_terminate,	NULL },
    { "kill",		do_kill,	NULL },
    { "line4",		NULL,		NULL },
    { "quit",		do_quit,	NULL }};

MenuEntry vtMenuEntries[] = {
    { "scrollbar",	do_scrollbar,	NULL },
    { "jumpscroll",	do_jumpscroll,	NULL },
    { "reversevideo",	do_reversevideo, NULL },
    { "autowrap",	do_autowrap,	NULL },
    { "reversewrap",	do_reversewrap, NULL },
    { "autolinefeed",	do_autolinefeed, NULL },
    { "appcursor",	do_appcursor,	NULL },
    { "appkeypad",	do_appkeypad,	NULL },
    { "scrollkey",	do_scrollkey,	NULL },
    { "scrollttyoutput",do_scrollttyoutput, NULL },
    { "allow132",	do_allow132,	NULL },
    { "keepSelection",	do_keepSelection, NULL },
#if OPT_MENU_KEEPCLIPBOARD
    { "keepClipboard",	do_keepClipboard, NULL },
#endif
    { "selectToClipboard",do_selectClipboard, NULL },
    { "visualbell",	do_visualbell,	NULL },
    { "bellIsUrgent",	do_bellIsUrgent, NULL },
    { "poponbell",	do_poponbell,	NULL },
#if OPT_BLINK_CURS
    { "cursorblink",	do_cursorblink,	NULL },
#endif
    { "titeInhibit",	do_titeInhibit,	NULL },
#ifndef NO_ACTIVE_ICON
    { "activeicon",	do_activeicon,	NULL },
#endif /* NO_ACTIVE_ICON */
    { "line1",		NULL,		NULL },
    { "softreset",	do_softreset,	NULL },
    { "hardreset",	do_hardreset,	NULL },
    { "clearsavedlines",do_clearsavedlines, NULL },
    { "line2",		NULL,		NULL },
#if OPT_TEK4014
    { "tekshow",	do_tekshow,	NULL },
    { "tekmode",	do_tekmode,	NULL },
    { "vthide",		do_vthide,	NULL },
#endif
    { "altscreen",	do_altscreen,	NULL },
#if OPT_SIXEL_GRAPHICS
    { "sixelScrolling",	do_sixelscrolling,	NULL },
#endif
#if OPT_GRAPHICS
    { "privateColorRegisters", do_privatecolorregisters, NULL },
#endif
    };

MenuEntry fontMenuEntries[] = {
    { "fontdefault",	do_vtfont,	NULL },
    { "font1",		do_vtfont,	NULL },
    { "font2",		do_vtfont,	NULL },
    { "font3",		do_vtfont,	NULL },
    { "font4",		do_vtfont,	NULL },
    { "font5",		do_vtfont,	NULL },
    { "font6",		do_vtfont,	NULL },
    { "font7",		do_vtfont,	NULL },
    /* this is after the last builtin font; the other entries are special */
    { "fontescape",	do_vtfont,	NULL },
    { "fontsel",	do_vtfont,	NULL },
    /* down to here should match NMENUFONTS in ptyx.h */

#if OPT_DEC_CHRSET || OPT_BOX_CHARS || OPT_DEC_SOFTFONT
    { "line1",		NULL,		NULL },
    { "allow-bold-fonts", do_allowBoldFonts, NULL },
#if OPT_BOX_CHARS
    { "font-linedrawing",do_font_boxchars,NULL },
    { "font-packed",	do_font_packed,NULL },
#endif
#if OPT_DEC_CHRSET
    { "font-doublesize",do_font_doublesize,NULL },
#endif
#if OPT_DEC_SOFTFONT
    { "font-loadable",	do_font_loadable,NULL },
#endif
#endif /* toggles for DEC font extensions */

#if OPT_RENDERFONT || OPT_WIDE_CHARS
    { "line2",		NULL,		NULL },
#if OPT_RENDERFONT
    { "render-font",	do_font_renderfont,NULL },
#endif
#if OPT_WIDE_CHARS
    { "utf8-mode",	do_font_utf8_mode,NULL },
    { "utf8-fonts",	do_font_utf8_fonts,NULL },
    { "utf8-title",	do_font_utf8_title,NULL },
#endif
#endif /* toggles for other font extensions */

#if OPT_ALLOW_XXX_OPS
    { "line3",		NULL,		NULL },
    { "allow-color-ops",do_allowColorOps,NULL },
    { "allow-font-ops",	do_allowFontOps,NULL },
    { "allow-mouse-ops",do_allowMouseOps,NULL },
    { "allow-tcap-ops",	do_allowTcapOps,NULL },
    { "allow-title-ops",do_allowTitleOps,NULL },
    { "allow-window-ops",do_allowWindowOps,NULL },
#endif

    };

#if OPT_TEK4014
MenuEntry tekMenuEntries[] = {
    { "tektextlarge",	do_tektextlarge, NULL },
    { "tektext2",	do_tektext2,	NULL },
    { "tektext3",	do_tektext3,	NULL },
    { "tektextsmall",	do_tektextsmall, NULL },
    { "line1",		NULL,		NULL },
    { "tekpage",	do_tekpage,	NULL },
    { "tekreset",	do_tekreset,	NULL },
    { "tekcopy",	do_tekcopy,	NULL },
    { "line2",		NULL,		NULL },
    { "vtshow",		do_vtshow,	NULL },
    { "vtmode",		do_vtmode,	NULL },
    { "tekhide",	do_tekhide,	NULL }};
#endif

typedef struct {
    char *internal_name;
    MenuEntry *entry_list;
    Cardinal entry_len;
} MenuHeader;

    /* This table is ordered to correspond with MenuIndex */
#define DATA(name) { (char *)#name, name ## Entries, XtNumber(name ## Entries ) }
static const MenuHeader menu_names[] = {
    DATA( mainMenu),
    DATA( vtMenu),
    DATA( fontMenu),
#if OPT_TEK4014
    DATA( tekMenu),
#endif
    { NULL, NULL, 0 },
};
#undef DATA
/* *INDENT-ON* */

/*
 * FIXME:  These are global data rather than in the xterm widget because they
 * are initialized before the widget is created.
 */
typedef struct {
    Widget b;			/* the toolbar's buttons */
    Widget w;			/* the popup shell activated by the button */
    Cardinal entries;
} MenuList;

static MenuList vt_shell[NUM_POPUP_MENUS];

#if OPT_TEK4014 && OPT_TOOLBAR
static MenuList tek_shell[NUM_POPUP_MENUS];
#endif

/*
 * Returns a pointer to the MenuList entry that matches the popup menu.
 */
static MenuList *
select_menu(Widget w, MenuIndex num)
{
#if OPT_TEK4014 && OPT_TOOLBAR
    while (w != NULL) {
	if (w == tekshellwidget) {
	    return &tek_shell[num];
	}
	w = XtParent(w);
    }
#else
    (void) w;
#endif
    return &vt_shell[num];
}

/*
 * Returns a pointer to the given popup menu shell
 */
static Widget
obtain_menu(Widget w, MenuIndex num)
{
    return select_menu(w, num)->w;
}

/*
 * Returns the number of entries in the given popup menu shell
 */
static Cardinal
sizeof_menu(Widget w, MenuIndex num)
{
    return select_menu(w, num)->entries;
}

/*
 * Return an array of flags telling if a given menu item is never going to
 * be used, so we can reduce the size of menus.
 */
static Boolean *
unusedEntries(XtermWidget xw, MenuIndex num)
{
    static Boolean result[XtNumber(mainMenuEntries)
			  + XtNumber(vtMenuEntries)
			  + XtNumber(fontMenuEntries)
#if OPT_TEK4014
			  + XtNumber(tekMenuEntries)
#endif
    ];
    TScreen *screen = TScreenOf(xw);

    memset(result, 0, sizeof(result));
    switch (num) {
    case mainMenu:
#if OPT_MAXIMIZE
	if (resource.fullscreen > 1) {
	    result[mainMenu_fullscreen] = True;
	}
#endif
#if OPT_NUM_LOCK
	if (!screen->alt_is_not_meta) {
	    result[mainMenu_alt_esc] = True;
	}
#endif
	if (!xtermHasPrinter(xw)) {
	    result[mainMenu_print] = True;
	    result[mainMenu_print_redir] = True;
	}
	if (screen->terminal_id < 200) {
	    result[mainMenu_8bit_ctrl] = True;
	}
#if !defined(SIGTSTP)
	result[mainMenu_suspend] = True;
#endif
#if !defined(SIGCONT)
	result[mainMenu_continue] = True;
#endif
#ifdef ALLOWLOGGING
	if (screen->inhibit & I_LOG) {
	    result[mainMenu_logging] = True;
	}
#endif
	if (screen->inhibit & I_SIGNAL) {
	    int n;
	    for (n = (int) mainMenu_suspend; n <= (int) mainMenu_quit; ++n) {
		result[n] = True;
	    }
	}
	break;
    case vtMenu:
#if !defined(NO_ACTIVE_ICON) && !OPT_TOOLBAR
	if (!getIconicFont(screen)->fs || !screen->iconVwin.window) {
	    result[vtMenu_activeicon] = True;
	}
#endif /* NO_ACTIVE_ICON */
#if OPT_TEK4014
	if (screen->inhibit & I_TEK) {
	    int n;
	    for (n = (int) vtMenu_tekshow; n <= (int) vtMenu_vthide; ++n) {
		result[n] = True;
	    }
	}
#endif
	break;
    case fontMenu:
	break;
#if OPT_TEK4014
    case tekMenu:
	break;
#endif
    case noMenu:
	break;
    }
    return result;
}

/*
 * When using the toolbar configuration, some systems (seen with Solaris 11)
 * give a warning that (Xt) cannot find a usable font-set.  This does not stop
 * the toolbars from working - ignore for now.
 */
#if OPT_TOOLBAR
static void
ignoreWarning(
		 String p_name,
		 String p_type,
		 String p_class,
		 String p_default,
		 String *p_params,
		 Cardinal *p_num_params)
{
    (void) p_name;
    (void) p_type;
    (void) p_class;
    (void) p_default;
    (void) p_params;
    (void) p_num_params;
}
#endif

/*
 * create_menu - create a popup shell and stuff the menu into it.
 */
static Widget
create_menu(Widget w, XtermWidget xw, MenuIndex num)
{
    static XtCallbackRec cb[2] =
    {
	{NULL, NULL},
	{NULL, NULL}};
    static Arg arg =
    {XtNcallback, (XtArgVal) cb};

    TScreen *screen = TScreenOf(xw);
    const MenuHeader *data = &menu_names[num];
    MenuList *list = select_menu(w, num);
    struct _MenuEntry *entries = data->entry_list;
    Cardinal nentries = data->entry_len;
#if !OPT_TOOLBAR
    char *saveLocale;
#endif

    if (screen->menu_item_bitmap == None) {
	/*
	 * we really want to do these dynamically
	 */
#define check_width 9
#define check_height 8
	static unsigned char check_bits[] =
	{
	    0x00, 0x01, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00,
	    0x31, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x04, 0x00
	};

	screen->menu_item_bitmap =
	    XCreateBitmapFromData(XtDisplay(xw),
				  RootWindowOfScreen(XtScreen(xw)),
				  (char *) check_bits, check_width, check_height);
    }
#if !OPT_TOOLBAR
    saveLocale = xtermSetLocale(LC_CTYPE, resource.menuLocale);
    list->w = XtCreatePopupShell(data->internal_name,
				 simpleMenuWidgetClass,
				 toplevel,
				 NULL, 0);
    TRACE(("created popupShell(%s) widget %p, window %#lx\n",
	   data->internal_name, (void *) list->w, XtWindow(list->w)));
#endif
    if (list->w != NULL) {
	Boolean *unused = unusedEntries(xw, num);
	Cardinal n;
#if OPT_TOOLBAR
	Boolean useLocale = !strcmp(resource.menuLocale, "");
	XtErrorMsgHandler warningHandler = NULL;
	if (!useLocale)
	    warningHandler = XtAppSetWarningMsgHandler(app_con, ignoreWarning);
#endif

	list->entries = 0;

	for (n = 0; n < nentries; ++n) {
	    if (!unused[n]) {
		cb[0].callback = (XtCallbackProc) entries[n].function;
		cb[0].closure = (XtPointer) entries[n].name;
		entries[n].widget = XtCreateManagedWidget(entries[n].name,
							  (entries[n].function
							   ? smeBSBObjectClass
							   : smeLineObjectClass),
							  list->w,
							  &arg, (Cardinal) 1);
		TRACE(("created menuEntry[%d] widget %p, window %#lx\n",
		       n, (void *) entries[n].widget, XtWindow(entries[n].widget)));
		list->entries++;
	    }
	}
#if OPT_TOOLBAR
	if (!useLocale)
	    XtAppSetWarningMsgHandler(app_con, warningHandler);
#endif
    }
#if !OPT_TOOLBAR
    xtermResetLocale(LC_CTYPE, saveLocale);
#endif

    /* do not realize at this point */
    return list->w;
}

static MenuIndex
indexOfMenu(String menuName)
{
    MenuIndex me;
    switch (*menuName) {
    case 'm':
	me = mainMenu;
	break;
    case 'v':
	me = vtMenu;
	break;
    case 'f':
	me = fontMenu;
	break;
#if OPT_TEK4014
    case 't':
	me = tekMenu;
	break;
#endif
    default:
	me = noMenu;
    }
    return (me);
}

/* ARGSUSED */
static Bool
domenu(Widget w,
       XEvent *event GCC_UNUSED,
       String *params,		/* mainMenu, vtMenu, or tekMenu */
       const Cardinal *param_count)	/* 0 or 1 */
{
    XtermWidget xw = term;
    TScreen *screen = TScreenOf(xw);
    MenuIndex me;
    Bool created = False;
    Widget mw;

    if (*param_count != 1) {
	Bell(xw, XkbBI_MinorError, 0);
	return False;
    }

    if ((me = indexOfMenu(params[0])) == noMenu) {
	Bell(xw, XkbBI_MinorError, 0);
	return False;
    }

    if ((mw = obtain_menu(w, me)) == NULL
	|| sizeof_menu(w, me) == 0) {
	mw = create_menu(w, xw, me);
	created = (mw != NULL);
    }
    if (mw == NULL)
	return False;

    TRACE(("domenu(%s) %s\n", params[0], created ? "create" : "update"));
    switch (me) {
    case mainMenu:
	if (created) {
	    update_toolbar();
	    update_fullscreen();
	    update_securekbd();
	    update_allowsends();
	    update_logging();
	    update_print_redir();
	    update_8bit_control();
	    update_decbkm();
	    update_num_lock();
	    update_alt_esc();
	    update_meta_esc();
	    update_delete_del();
	    update_keyboard_type();
#if OPT_PRINT_ON_EXIT
	    screen->write_error = !IsEmpty(resource.printFileOnXError);
	    SetItemSensitivity(mainMenuEntries[mainMenu_write_now].widget, True);
	    SetItemSensitivity(mainMenuEntries[mainMenu_write_error].widget, screen->write_error);
#endif
	}
	break;

    case vtMenu:
	if (created) {
	    update_scrollbar();
	    update_jumpscroll();
	    update_reversevideo();
	    update_autowrap();
	    update_reversewrap();
	    update_autolinefeed();
	    update_appcursor();
	    update_appkeypad();
	    update_scrollkey();
	    update_scrollttyoutput();
	    update_allow132();
	    update_cursesemul();
	    update_keepSelection();
	    update_selectToClipboard();
	    update_visualbell();
	    update_poponbell();
	    update_bellIsUrgent();
	    update_cursorblink();
	    update_altscreen();
	    update_decsdm();	/* Sixel Display Mode */
	    update_titeInhibit();
#ifndef NO_ACTIVE_ICON
	    update_activeicon();
#endif /* NO_ACTIVE_ICON */
	    update_privatecolorregisters();
	}
	break;

    case fontMenu:
	if (created) {
	    int n;

	    set_menu_font(True);
	    for (n = fontMenu_font1; n <= fontMenu_font7; ++n) {
		if (IsEmpty(screen->menu_font_names[n][fNorm]))
		    SetItemSensitivity(fontMenuEntries[n].widget, False);
	    }
	    update_font_escape();
	    update_menu_allowBoldFonts();
#if OPT_BOX_CHARS
	    update_font_boxchars();
	    update_font_packed();
	    SetItemSensitivity(
				  fontMenuEntries[fontMenu_font_packedfont].widget,
				  True);
#endif
#if OPT_DEC_SOFTFONT		/* FIXME: not implemented */
	    update_font_loadable();
	    SetItemSensitivity(
				  fontMenuEntries[fontMenu_font_loadable].widget,
				  False);
#endif
#if OPT_DEC_CHRSET
	    update_font_doublesize();
	    if (TScreenOf(xw)->cache_doublesize == 0)
		SetItemSensitivity(
				      fontMenuEntries[fontMenu_font_doublesize].widget,
				      False);
#endif
#if OPT_RENDERFONT
	    update_font_renderfont();
#endif
#if OPT_WIDE_CHARS
	    update_font_utf8_mode();
	    update_font_utf8_fonts();
	    update_font_utf8_title();
#endif
#if OPT_ALLOW_XXX_OPS
	    update_menu_allowColorOps();
	    update_menu_allowFontOps();
	    update_menu_allowMouseOps();
	    update_menu_allowTcapOps();
	    update_menu_allowTitleOps();
	    update_menu_allowWindowOps();
	    enable_allow_xxx_ops(!(screen->allowSendEvents));
#endif
	}
#if OPT_TOOLBAR
	/* menus for toolbar are initialized once only */
	SetItemSensitivity(fontMenuEntries[fontMenu_fontsel].widget, True);
#else
	FindFontSelection(xw, NULL, True);
	SetItemSensitivity(fontMenuEntries[fontMenu_fontsel].widget,
			   (screen->SelectFontName()
			    ? True
			    : False));
#endif
	break;

#if OPT_TEK4014
    case tekMenu:
	if (created && tekWidget) {
	    set_tekfont_menu_item(TekScreenOf(tekWidget)->cur.fontsize, True);
	    update_vtshow();
	}
	break;
#endif
    case noMenu:
    default:
	break;
    }

    return True;
}

/*
 * public interfaces
 */

void
HandleCreateMenu(Widget w,
		 XEvent *event,
		 String *params,	/* mainMenu, vtMenu, or tekMenu */
		 Cardinal *param_count)		/* 0 or 1 */
{
    TRACE(("HandleCreateMenu\n"));
    (void) domenu(w, event, params, param_count);
}

void
HandlePopupMenu(Widget w,
		XEvent *event,
		String *params,	/* mainMenu, vtMenu, or tekMenu */
		Cardinal *param_count)	/* 0 or 1 */
{
    TRACE(("HandlePopupMenu\n"));
    if (domenu(w, event, params, param_count)) {
	XtermWidget xw = term;
	TScreen *screen = TScreenOf(xw);

#if OPT_TOOLBAR
	w = select_menu(w, mainMenu)->w;
#endif
	/*
	 * The action procedure in SimpleMenu.c, PositionMenu does not expect a
	 * key translation event when we are popping up a menu.  In particular,
	 * if the pointer is outside the menu, then the action procedure will
	 * fail in its attempt to determine the location of the pointer within
	 * the menu.  Anticipate that by warping the pointer into the menu when
	 * a key event is detected.
	 */
	switch (event->type) {
	case KeyPress:
	case KeyRelease:
	    XWarpPointer(screen->display, None, XtWindow(w), 0, 0, 0, 0, 0, 0);
	    break;
	default:
	    XtCallActionProc(w, "XawPositionSimpleMenu", event, params, 1);
	    break;
	}
	XtCallActionProc(w, "MenuPopup", event, params, 1);
    }
}

/*
 * private interfaces - keep out!
 */

/* ARGSUSED */
static void
handle_send_signal(Widget gw GCC_UNUSED, int sig)
{
    TScreen *screen = TScreenOf(term);

    if (hold_screen > 1)
	hold_screen = 0;
    if (screen->pid > 1)
	kill_process_group(screen->pid, sig);
}

#if OPT_VT52_MODE
static void
DisableIfVT52(MenuEntry * menu, int which)
{
    Widget mi = menu[which].widget;
    SetItemSensitivity(mi, TScreenOf(term)->vtXX_level != 0);
}

#else
#define DisableIfVT52(which,val)	/* nothing */
#endif

static void
UpdateMenuItem(
#if OPT_TRACE
		  const char *func,
#endif
		  MenuEntry * menu,
		  int which,
		  Bool val)
{
    static Arg menuArgs =
    {XtNleftBitmap, (XtArgVal) 0};
    Widget mi = menu[which].widget;

    if (mi) {
	menuArgs.value = (XtArgVal) ((val)
				     ? TScreenOf(term)->menu_item_bitmap
				     : None);
	XtSetValues(mi, &menuArgs, (Cardinal) 1);
    }
    TRACE(("%s(%d): %s\n", func, which, MtoS(val)));
}

void
SetItemSensitivity(Widget mi, Bool val)
{
    static Arg menuArgs =
    {XtNsensitive, (XtArgVal) 0};

    if (mi) {
	menuArgs.value = (XtArgVal) (val);
	XtSetValues(mi, &menuArgs, (Cardinal) 1);
    }
}

/*
 * action routines
 */

static void
do_securekbd(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    XtermWidget xw = term;
    TScreen *screen = TScreenOf(xw);
    Time now = CurrentTime;	/* XXX - wrong */

    if (screen->grabbedKbd) {
	XUngrabKeyboard(screen->display, now);
	ReverseVideo(xw);
	screen->grabbedKbd = False;
    } else {
	if (XGrabKeyboard(screen->display, XtWindow(CURRENT_EMU()),
			  True, GrabModeAsync, GrabModeAsync, now)
	    != GrabSuccess) {
	    Bell(xw, XkbBI_MinorError, 100);
	} else {
	    ReverseVideo(xw);
	    screen->grabbedKbd = True;
	}
    }
    update_securekbd();
}

/* ARGSUSED */
void
HandleSecure(Widget w GCC_UNUSED,
	     XEvent *event GCC_UNUSED,	/* unused */
	     String *params GCC_UNUSED,		/* [0] = volume */
	     Cardinal *param_count GCC_UNUSED)	/* 0 or 1 */
{
    do_securekbd(vt_shell[mainMenu].w, (XtPointer) 0, (XtPointer) 0);
}

static void
do_allowsends(Widget gw GCC_UNUSED,
	      XtPointer closure GCC_UNUSED,
	      XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->allowSendEvents);
    update_allowsends();
#if OPT_ALLOW_XXX_OPS
    enable_allow_xxx_ops(!(screen->allowSendEvents));
#endif
}

static void
do_visualbell(Widget gw GCC_UNUSED,
	      XtPointer closure GCC_UNUSED,
	      XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->visualbell);
    update_visualbell();
}

static void
do_bellIsUrgent(Widget gw GCC_UNUSED,
		XtPointer closure GCC_UNUSED,
		XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->bellIsUrgent);
    update_bellIsUrgent();
}

static void
do_poponbell(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->poponbell);
    update_poponbell();
}

#ifdef ALLOWLOGGING
static void
do_logging(Widget gw GCC_UNUSED,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
    XtermWidget xw = term;
    TScreen *screen = TScreenOf(xw);

    if (screen->logging) {
	CloseLog(xw);
    } else {
	StartLog(xw);
    }
    /* update_logging done by CloseLog and StartLog */
}
#endif

#if OPT_PRINT_ON_EXIT
static void
do_write_now(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    XtermWidget xw = term;

    xtermPrintImmediately(xw,
			  (IsEmpty(resource.printFileNow)
			   ? (String) "XTerm"
			   : resource.printFileNow),
			  resource.printOptsNow,
			  resource.printModeNow);
}

void
HandlePrintImmediate(Widget w GCC_UNUSED,
		     XEvent *event GCC_UNUSED,
		     String *params GCC_UNUSED,
		     Cardinal *param_count GCC_UNUSED)
{
    do_write_now((Widget) 0, (XtPointer) 0, (XtPointer) 0);
}

static void
do_write_error(Widget gw GCC_UNUSED,
	       XtPointer closure GCC_UNUSED,
	       XtPointer data GCC_UNUSED)
{
    XtermWidget xw = term;

    if (IsEmpty(resource.printFileOnXError)) {
	resource.printFileOnXError = "XTermError";
    }
    TScreenOf(xw)->write_error = (Boolean) (!TScreenOf(xw)->write_error);
    update_write_error();
}

void
HandlePrintOnError(Widget w GCC_UNUSED,
		   XEvent *event GCC_UNUSED,
		   String *params GCC_UNUSED,
		   Cardinal *param_count GCC_UNUSED)
{
    do_write_error((Widget) 0, (XtPointer) 0, (XtPointer) 0);
}
#endif

static void
do_print(Widget gw GCC_UNUSED,
	 XtPointer closure GCC_UNUSED,
	 XtPointer data GCC_UNUSED)
{
    xtermPrintScreen(term, True, getPrinterFlags(term, NULL, NULL));
}

static void
do_print_redir(Widget gw GCC_UNUSED,
	       XtPointer closure GCC_UNUSED,
	       XtPointer data GCC_UNUSED)
{
    setPrinterControlMode(term,
			  (PrinterOf(TScreenOf(term)).printer_controlmode
			   ? 0
			   : 2));
}

#if OPT_SCREEN_DUMPS
static void
do_dump_html(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    xtermDumpHtml(term);
}

static void
do_dump_svg(Widget gw GCC_UNUSED,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
    xtermDumpSvg(term);
}
#endif

static void
do_redraw(Widget gw GCC_UNUSED,
	  XtPointer closure GCC_UNUSED,
	  XtPointer data GCC_UNUSED)
{
    Redraw();
}

void
show_8bit_control(Bool value)
{
    if (TScreenOf(term)->control_eight_bits != value) {
	TScreenOf(term)->control_eight_bits = (Boolean) value;
	update_8bit_control();
    }
}

static void
do_8bit_control(Widget gw GCC_UNUSED,
		XtPointer closure GCC_UNUSED,
		XtPointer data GCC_UNUSED)
{
    show_8bit_control(!TScreenOf(term)->control_eight_bits);
}

static void
do_backarrow(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    term->keyboard.flags ^= MODE_DECBKM;
    update_decbkm();
}

#if OPT_NUM_LOCK
static void
do_num_lock(Widget gw GCC_UNUSED,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
    ToggleFlag(term->misc.real_NumLock);
    update_num_lock();
}

static void
do_alt_esc(Widget gw GCC_UNUSED,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
    ToggleFlag(TScreenOf(term)->alt_sends_esc);
    update_alt_esc();
}

static void
do_meta_esc(Widget gw GCC_UNUSED,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
    ToggleFlag(TScreenOf(term)->meta_sends_esc);
    update_meta_esc();
}
#endif

static void
do_delete_del(Widget gw GCC_UNUSED,
	      XtPointer closure GCC_UNUSED,
	      XtPointer data GCC_UNUSED)
{
    if (xtermDeleteIsDEL(term))
	TScreenOf(term)->delete_is_del = False;
    else
	TScreenOf(term)->delete_is_del = True;
    update_delete_del();
}

static void
do_old_fkeys(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    toggle_keyboard_type(term, keyboardIsLegacy);
}

#if OPT_HP_FUNC_KEYS
static void
do_hp_fkeys(Widget gw GCC_UNUSED,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
    toggle_keyboard_type(term, keyboardIsHP);
}
#endif

#if OPT_SCO_FUNC_KEYS
static void
do_sco_fkeys(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    toggle_keyboard_type(term, keyboardIsSCO);
}
#endif

#if OPT_SUN_FUNC_KEYS
static void
do_sun_fkeys(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    toggle_keyboard_type(term, keyboardIsSun);
}
#endif

#if OPT_SUNPC_KBD
/*
 * This really means "Sun/PC keyboard emulating VT220".
 */
static void
do_sun_kbd(Widget gw GCC_UNUSED,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
    toggle_keyboard_type(term, keyboardIsVT220);
}
#endif

#if OPT_TCAP_FKEYS
static void
do_tcap_fkeys(Widget gw GCC_UNUSED,
	      XtPointer closure GCC_UNUSED,
	      XtPointer data GCC_UNUSED)
{
    toggle_keyboard_type(term, keyboardIsTermcap);
}
#endif

/*
 * The following cases use the pid instead of the process group so that we
 * don't get hosed by programs that change their process group
 */

/* ARGSUSED */
static void
do_suspend(Widget gw,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
#if defined(SIGTSTP)
    handle_send_signal(gw, SIGTSTP);
#endif
}

/* ARGSUSED */
static void
do_continue(Widget gw,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
#if defined(SIGCONT)
    handle_send_signal(gw, SIGCONT);
#endif
}

/* ARGSUSED */
static void
do_interrupt(Widget gw,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    handle_send_signal(gw, SIGINT);
}

/* ARGSUSED */
void
do_hangup(Widget gw,
	  XtPointer closure GCC_UNUSED,
	  XtPointer data GCC_UNUSED)
{
    handle_send_signal(gw, SIGHUP);
}

/* ARGSUSED */
static void
do_terminate(Widget gw,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    handle_send_signal(gw, SIGTERM);
}

/* ARGSUSED */
static void
do_kill(Widget gw,
	XtPointer closure GCC_UNUSED,
	XtPointer data GCC_UNUSED)
{
    handle_send_signal(gw, SIGKILL);
}

static void
do_quit(Widget gw GCC_UNUSED,
	XtPointer closure GCC_UNUSED,
	XtPointer data GCC_UNUSED)
{
    Cleanup(ERROR_MISC);
}

/*
 * vt menu callbacks
 */

static void
do_scrollbar(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    ToggleScrollBar(term);
}

static void
do_jumpscroll(Widget gw GCC_UNUSED,
	      XtPointer closure GCC_UNUSED,
	      XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    term->flags ^= SMOOTHSCROLL;
    if (term->flags & SMOOTHSCROLL) {
	screen->jumpscroll = False;
	if (screen->scroll_amt)
	    FlushScroll(term);
    } else {
	screen->jumpscroll = True;
    }
    update_jumpscroll();
}

static void
do_reversevideo(Widget gw GCC_UNUSED,
		XtPointer closure GCC_UNUSED,
		XtPointer data GCC_UNUSED)
{
    ReverseVideo(term);
}

static void
do_autowrap(Widget gw GCC_UNUSED,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
    term->flags ^= WRAPAROUND;
    update_autowrap();
}

static void
do_reversewrap(Widget gw GCC_UNUSED,
	       XtPointer closure GCC_UNUSED,
	       XtPointer data GCC_UNUSED)
{
    term->flags ^= REVERSEWRAP;
    update_reversewrap();
}

static void
do_autolinefeed(Widget gw GCC_UNUSED,
		XtPointer closure GCC_UNUSED,
		XtPointer data GCC_UNUSED)
{
    term->flags ^= LINEFEED;
    update_autolinefeed();
}

static void
do_appcursor(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    term->keyboard.flags ^= MODE_DECCKM;
    update_appcursor();
}

static void
do_appkeypad(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    term->keyboard.flags ^= MODE_DECKPAM;
    update_appkeypad();
}

static void
do_scrollkey(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->scrollkey);
    update_scrollkey();
}

static void
do_scrollttyoutput(Widget gw GCC_UNUSED,
		   XtPointer closure GCC_UNUSED,
		   XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->scrollttyoutput);
    update_scrollttyoutput();
}

#if OPT_MENU_KEEPCLIPBOARD
void
update_keepClipboard(void)
{
    UpdateCheckbox("update_keepClipboard",
		   vtMenuEntries,
		   vtMenu_keepClipboard,
		   TScreenOf(term)->keepClipboard);
}
#endif

static void
do_keepClipboard(Widget gw GCC_UNUSED,
		 XtPointer closure GCC_UNUSED,
		 XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->keepClipboard);
    update_keepClipboard();
}

static void
do_keepSelection(Widget gw GCC_UNUSED,
		 XtPointer closure GCC_UNUSED,
		 XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->keepSelection);
    update_keepSelection();
}

static void
do_selectClipboard(Widget gw GCC_UNUSED,
		   XtPointer closure GCC_UNUSED,
		   XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->selectToClipboard);
    update_selectToClipboard();
}

static void
do_allow132(Widget gw GCC_UNUSED,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->c132);
    update_allow132();
}

static void
do_cursesemul(Widget gw GCC_UNUSED,
	      XtPointer closure GCC_UNUSED,
	      XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->curses);
    update_cursesemul();
}

static void
do_marginbell(Widget gw GCC_UNUSED,
	      XtPointer closure GCC_UNUSED,
	      XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    if ((ToggleFlag(screen->marginbell)) == 0)
	screen->bellArmed = -1;
    update_marginbell();
}

#if OPT_TEK4014
static void
handle_tekshow(Widget gw GCC_UNUSED, Bool allowswitch)
{
    XtermWidget xw = term;
    TScreen *screen = TScreenOf(xw);

    TRACE(("Show tek-window\n"));
    if (!TEK4014_SHOWN(xw)) {	/* not showing, turn on */
	set_tek_visibility(True);
    } else if (screen->Vshow || allowswitch) {	/* is showing, turn off */
	set_tek_visibility(False);
	end_tek_mode();		/* WARNING: this does a longjmp */
    } else
	Bell(xw, XkbBI_MinorError, 0);
}

/* ARGSUSED */
static void
do_tekshow(Widget gw,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
    handle_tekshow(gw, True);
}

/* ARGSUSED */
static void
do_tekonoff(Widget gw,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
    handle_tekshow(gw, False);
}
#endif /* OPT_TEK4014 */

#if OPT_BLINK_CURS
/* ARGSUSED */
static void
do_cursorblink(Widget gw GCC_UNUSED,
	       XtPointer closure GCC_UNUSED,
	       XtPointer data GCC_UNUSED)
{
    ToggleCursorBlink(term);
}
#endif

/* ARGSUSED */
static void
do_altscreen(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    ToggleAlternate(term);
}

/* ARGSUSED */
static void
do_titeInhibit(Widget gw GCC_UNUSED,
	       XtPointer closure GCC_UNUSED,
	       XtPointer data GCC_UNUSED)
{
    ToggleFlag(term->misc.titeInhibit);
    update_titeInhibit();
}

#ifndef NO_ACTIVE_ICON
/* ARGSUSED */
static void
do_activeicon(Widget gw GCC_UNUSED,
	      XtPointer closure GCC_UNUSED,
	      XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    if (screen->iconVwin.window) {
	Widget shell = XtParent(term);
	ToggleFlag(term->work.active_icon);
	XtVaSetValues(shell, XtNiconWindow,
		      term->work.active_icon ? screen->iconVwin.window : None,
		      (XtPointer) 0);
	update_activeicon();
    }
}
#endif /* NO_ACTIVE_ICON */

static void
do_softreset(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    VTReset(term, False, False);
}

static void
do_hardreset(Widget gw GCC_UNUSED,
	     XtPointer closure GCC_UNUSED,
	     XtPointer data GCC_UNUSED)
{
    VTReset(term, True, False);
}

static void
do_clearsavedlines(Widget gw GCC_UNUSED,
		   XtPointer closure GCC_UNUSED,
		   XtPointer data GCC_UNUSED)
{
    VTReset(term, True, True);
}

#if OPT_TEK4014
static void
do_tekmode(Widget gw GCC_UNUSED,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
    switch_modes(TEK4014_ACTIVE(term));		/* switch to tek mode */
}

/* ARGSUSED */
static void
do_vthide(Widget gw GCC_UNUSED,
	  XtPointer closure GCC_UNUSED,
	  XtPointer data GCC_UNUSED)
{
    hide_vt_window();
}
#endif /* OPT_TEK4014 */

/*
 * vtfont menu
 */

static void
do_vtfont(Widget gw GCC_UNUSED,
	  XtPointer closure,
	  XtPointer data GCC_UNUSED)
{
    XtermWidget xw = term;
    char *entryname = (char *) closure;
    int i;

    TRACE(("do_vtfont(%s)\n", entryname));
    for (i = 0; i < NMENUFONTS; i++) {
	if (strcmp(entryname, fontMenuEntries[i].name) == 0) {
	    SetVTFont(xw, i, True, NULL);
	    return;
	}
    }
    Bell(xw, XkbBI_MinorError, 0);
}

#if OPT_DEC_CHRSET
static void
do_font_doublesize(Widget gw GCC_UNUSED,
		   XtPointer closure GCC_UNUSED,
		   XtPointer data GCC_UNUSED)
{
    XtermWidget xw = term;

    if (TScreenOf(xw)->cache_doublesize != 0)
	ToggleFlag(TScreenOf(xw)->font_doublesize);
    update_font_doublesize();
    Redraw();
}
#endif

#if OPT_BOX_CHARS
static void
do_font_boxchars(Widget gw GCC_UNUSED,
		 XtPointer closure GCC_UNUSED,
		 XtPointer data GCC_UNUSED)
{
    ToggleFlag(TScreenOf(term)->force_box_chars);
    update_font_boxchars();
    Redraw();
}

static void
do_font_packed(Widget gw GCC_UNUSED,
	       XtPointer closure GCC_UNUSED,
	       XtPointer data GCC_UNUSED)
{
    ToggleFlag(TScreenOf(term)->force_packed);
    update_font_packed();
    SetVTFont(term, TScreenOf(term)->menu_font_number, True, NULL);
}
#endif

#if OPT_DEC_SOFTFONT
static void
do_font_loadable(Widget gw GCC_UNUSED,
		 XtPointer closure GCC_UNUSED,
		 XtPointer data GCC_UNUSED)
{
    ToggleFlag(term->misc.font_loadable);
    update_font_loadable();
}
#endif

#if OPT_RENDERFONT
static void
do_font_renderfont(Widget gw GCC_UNUSED,
		   XtPointer closure GCC_UNUSED,
		   XtPointer data GCC_UNUSED)
{
    XtermWidget xw = (XtermWidget) term;
    TScreen *screen = TScreenOf(xw);
    int fontnum = screen->menu_font_number;
    String name = TScreenOf(xw)->MenuFontName(fontnum);

    DefaultRenderFont(xw);
    ToggleFlag(xw->work.render_font);
    update_font_renderfont();
    xtermLoadFont(xw, xtermFontName(name), True, fontnum);
    ScrnRefresh(term, 0, 0,
		MaxRows(screen),
		MaxCols(screen), True);
}
#endif

#if OPT_WIDE_CHARS
static void
setup_wide_fonts(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    if (screen->wide_chars) {
	if (xtermLoadWideFonts(xw, True)) {
	    SetVTFont(xw, screen->menu_font_number, True, NULL);
	}
    } else {
	ChangeToWide(xw);
    }
}

static void
setup_narrow_fonts(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    if (xtermLoadDefaultFonts(xw)) {
	SetVTFont(xw, screen->menu_font_number, True, NULL);
    }
}

static void
do_font_utf8_mode(Widget gw GCC_UNUSED,
		  XtPointer closure GCC_UNUSED,
		  XtPointer data GCC_UNUSED)
{
    XtermWidget xw = term;
    TScreen *screen = TScreenOf(xw);

    /*
     * If xterm was started with -wc option, it might not have the wide fonts.
     * If xterm was not started with -wc, it might not have wide cells.
     */
    if (!screen->utf8_mode) {
	setup_wide_fonts(xw);
    }
    switchPtyData(screen, !screen->utf8_mode);
    /*
     * We don't repaint the screen when switching UTF-8 on/off.  When switching
     * on - the Latin-1 codes should paint as-is.  When switching off, that's
     * hard to do properly.
     */
}

static void
do_font_utf8_fonts(Widget gw GCC_UNUSED,
		   XtPointer closure GCC_UNUSED,
		   XtPointer data GCC_UNUSED)
{
    XtermWidget xw = term;
    TScreen *screen = TScreenOf(xw);

    ToggleFlag(screen->utf8_fonts);
    update_font_utf8_fonts();

    if (screen->utf8_fonts) {
	setup_wide_fonts(xw);
    } else {
	setup_narrow_fonts(xw);
    }
}

static void
do_font_utf8_title(Widget gw GCC_UNUSED,
		   XtPointer closure GCC_UNUSED,
		   XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->utf8_title);
    update_font_utf8_title();
}
#endif

/*
 * tek menu
 */

#if OPT_TEK4014
static void
do_tektextlarge(Widget gw,
		XtPointer closure GCC_UNUSED,
		XtPointer data GCC_UNUSED)
{
    TekSetFontSize(getTekWidget(gw), True, tekMenu_tektextlarge);
}

static void
do_tektext2(Widget gw,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
    TekSetFontSize(getTekWidget(gw), True, tekMenu_tektext2);
}

static void
do_tektext3(Widget gw,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
    TekSetFontSize(getTekWidget(gw), True, tekMenu_tektext3);
}

static void
do_tektextsmall(Widget gw,
		XtPointer closure GCC_UNUSED,
		XtPointer data GCC_UNUSED)
{
    TekSetFontSize(getTekWidget(gw), True, tekMenu_tektextsmall);
}

static void
do_tekpage(Widget gw,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
    TekSimulatePageButton(getTekWidget(gw), False);
}

static void
do_tekreset(Widget gw,
	    XtPointer closure GCC_UNUSED,
	    XtPointer data GCC_UNUSED)
{
    TekSimulatePageButton(getTekWidget(gw), True);
}

static void
do_tekcopy(Widget gw,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
    TekCopy(getTekWidget(gw));
}

static void
handle_vtshow(Widget gw GCC_UNUSED, Bool allowswitch)
{
    XtermWidget xw = term;
    TScreen *screen = TScreenOf(xw);

    TRACE(("Show vt-window\n"));
    if (!screen->Vshow) {	/* not showing, turn on */
	set_vt_visibility(True);
    } else if (TEK4014_SHOWN(xw) || allowswitch) {	/* is showing, turn off */
	set_vt_visibility(False);
	if (!TEK4014_ACTIVE(xw) && tekRefreshList)
	    TekRefresh(tekWidget);
	end_vt_mode();		/* WARNING: this does a longjmp... */
    } else
	Bell(xw, XkbBI_MinorError, 0);
}

static void
do_vtshow(Widget gw,
	  XtPointer closure GCC_UNUSED,
	  XtPointer data GCC_UNUSED)
{
    handle_vtshow(gw, True);
}

static void
do_vtonoff(Widget gw,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
    handle_vtshow(gw, False);
}

static void
do_vtmode(Widget gw GCC_UNUSED,
	  XtPointer closure GCC_UNUSED,
	  XtPointer data GCC_UNUSED)
{
    switch_modes(TEK4014_ACTIVE(term));		/* switch to vt, or from */
}

/* ARGSUSED */
static void
do_tekhide(Widget gw GCC_UNUSED,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
    hide_tek_window();
}
#endif /* OPT_TEK4014 */

/*
 * public handler routines
 */
int
decodeToggle(XtermWidget xw, String *params, Cardinal nparams)
{
    int dir = toggleErr;

    switch (nparams) {
    case 0:
	dir = toggleAll;
	break;
    case 1:
	if (XmuCompareISOLatin1(params[0], "on") == 0)
	    dir = toggleOn;
	else if (XmuCompareISOLatin1(params[0], "off") == 0)
	    dir = toggleOff;
	else if (XmuCompareISOLatin1(params[0], "toggle") == 0)
	    dir = toggleAll;
	break;
    }

    if (dir == toggleErr) {
	Bell(xw, XkbBI_MinorError, 0);
    }

    return dir;
}

static void
handle_toggle(void (*proc) PROTO_XT_CALLBACK_ARGS,
	      int var,
	      String *params,
	      Cardinal nparams,
	      Widget w,
	      XtPointer closure,
	      XtPointer data)
{
    XtermWidget xw = term;

    switch (decodeToggle(xw, params, nparams)) {

    case toggleAll:
	(*proc) (w, closure, data);
	break;

    case toggleOff:
	if (var)
	    (*proc) (w, closure, data);
	else
	    Bell(xw, XkbBI_MinorError, 0);
	break;

    case toggleOn:
	if (!var)
	    (*proc) (w, closure, data);
	else
	    Bell(xw, XkbBI_MinorError, 0);
	break;
    }
    return;
}

#define handle_vt_toggle(proc, var, params, nparams, w) \
	handle_toggle(proc, (int) (var), params, nparams, w, (XtPointer)0, (XtPointer)0)

#define HANDLE_VT_TOGGLE(name) \
	handle_vt_toggle(do_##name, TScreenOf(term)->name, params, *param_count, w)

#define handle_tek_toggle(proc, var, params, nparams, w) \
	handle_toggle(proc, (int) (var), params, nparams, w, (XtPointer)0, (XtPointer)0)

void
HandleAllowSends(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    handle_vt_toggle(do_allowsends, TScreenOf(term)->allowSendEvents,
		     params, *param_count, w);
}

void
HandleSetVisualBell(Widget w,
		    XEvent *event GCC_UNUSED,
		    String *params,
		    Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(visualbell);
}

void
HandleSetPopOnBell(Widget w,
		   XEvent *event GCC_UNUSED,
		   String *params,
		   Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(poponbell);
}

#ifdef ALLOWLOGGING
void
HandleLogging(Widget w,
	      XEvent *event GCC_UNUSED,
	      String *params,
	      Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(logging);
}
#endif

#if OPT_PRINT_ON_EXIT
void
HandleWriteNow(Widget w,
	       XEvent *event GCC_UNUSED,
	       String *params GCC_UNUSED,
	       Cardinal *param_count GCC_UNUSED)
{
    do_write_now(w, NULL, NULL);
}

void
HandleWriteError(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(write_error);
}
#endif

/* ARGSUSED */
void
HandlePrintScreen(Widget w GCC_UNUSED,
		  XEvent *event GCC_UNUSED,
		  String *params,
		  Cardinal *param_count)
{
    xtermPrintScreen(term, True, getPrinterFlags(term, params, param_count));
}

/* ARGSUSED */
void
HandlePrintEverything(Widget w GCC_UNUSED,
		      XEvent *event GCC_UNUSED,
		      String *params,
		      Cardinal *param_count)
{
    xtermPrintEverything(term, getPrinterFlags(term, params, param_count));
}

/* ARGSUSED */
void
HandlePrintControlMode(Widget w,
		       XEvent *event GCC_UNUSED,
		       String *params GCC_UNUSED,
		       Cardinal *param_count GCC_UNUSED)
{
    do_print_redir(w, (XtPointer) 0, (XtPointer) 0);
}

/* ARGSUSED */
void
HandleRedraw(Widget w,
	     XEvent *event GCC_UNUSED,
	     String *params GCC_UNUSED,
	     Cardinal *param_count GCC_UNUSED)
{
    do_redraw(w, (XtPointer) 0, (XtPointer) 0);
}

/* ARGSUSED */
void
HandleSendSignal(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    /* *INDENT-OFF* */
    static const struct sigtab {
	const char *name;
	int sig;
    } signals[] = {
#ifdef SIGTSTP
	{ "suspend",	SIGTSTP },
	{ "tstp",	SIGTSTP },
#endif
#ifdef SIGCONT
	{ "cont",	SIGCONT },
#endif
	{ "int",	SIGINT },
	{ "hup",	SIGHUP },
	{ "quit",	SIGQUIT },
	{ "alrm",	SIGALRM },
	{ "alarm",	SIGALRM },
	{ "term",	SIGTERM },
	{ "kill",	SIGKILL },
	{ NULL, 0 },
    };
    /* *INDENT-ON* */

    if (*param_count == 1) {
	const struct sigtab *st;

	for (st = signals; st->name; st++) {
	    if (XmuCompareISOLatin1(st->name, params[0]) == 0) {
		handle_send_signal(w, st->sig);
		return;
	    }
	}
	/* one could allow numeric values, but that would be a security hole */
    }

    Bell(term, XkbBI_MinorError, 0);
}

/* ARGSUSED */
void
HandleQuit(Widget w,
	   XEvent *event GCC_UNUSED,
	   String *params GCC_UNUSED,
	   Cardinal *param_count GCC_UNUSED)
{
    do_quit(w, (XtPointer) 0, (XtPointer) 0);
}

void
Handle8BitControl(Widget w,
		  XEvent *event GCC_UNUSED,
		  String *params,
		  Cardinal *param_count)
{
    handle_vt_toggle(do_8bit_control, TScreenOf(term)->control_eight_bits,
		     params, *param_count, w);
}

void
HandleBackarrow(Widget w,
		XEvent *event GCC_UNUSED,
		String *params,
		Cardinal *param_count)
{
    handle_vt_toggle(do_backarrow, term->keyboard.flags & MODE_DECBKM,
		     params, *param_count, w);
}

#if OPT_MAXIMIZE
#if OPT_TEK4014
#define WhichEWMH (TEK4014_ACTIVE(xw) != 0)
#else
#define WhichEWMH 0
#endif
static void
do_fullscreen(Widget gw GCC_UNUSED,
	      XtPointer closure GCC_UNUSED,
	      XtPointer data GCC_UNUSED)
{
    XtermWidget xw = term;

    if (resource.fullscreen != esNever)
	FullScreen(xw, !xw->work.ewmh[WhichEWMH].mode);
}

/* ARGSUSED */
void
HandleFullscreen(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    XtermWidget xw = term;

    if (resource.fullscreen != esNever) {
	handle_vt_toggle(do_fullscreen, xw->work.ewmh[WhichEWMH].mode,
			 params, *param_count, w);
    }
}

void
update_fullscreen(void)
{
    XtermWidget xw = term;

    if (resource.fullscreen <= 1) {
	UpdateCheckbox("update_fullscreen",
		       mainMenuEntries,
		       mainMenu_fullscreen,
		       xw->work.ewmh[WhichEWMH].mode);
    } else {
	SetItemSensitivity(mainMenuEntries[mainMenu_fullscreen].widget,
			   False);
    }
}

#endif /* OPT_MAXIMIZE */

#if OPT_SIXEL_GRAPHICS
static void
do_sixelscrolling(Widget gw GCC_UNUSED,
		  XtPointer closure GCC_UNUSED,
		  XtPointer data GCC_UNUSED)
{
    term->keyboard.flags ^= MODE_DECSDM;
    update_decsdm();
}

void
update_decsdm(void)
{
    UpdateCheckbox("update_decsdm",
		   vtMenuEntries,
		   vtMenu_sixelscrolling,
		   (term->keyboard.flags & MODE_DECSDM) == 0);
}

void
HandleSixelScrolling(Widget w,
		     XEvent *event GCC_UNUSED,
		     String *params,
		     Cardinal *param_count)
{
    handle_vt_toggle(do_sixelscrolling, term->keyboard.flags & MODE_DECSDM,
		     params, *param_count, w);
}
#endif

#if OPT_GRAPHICS
static void
do_privatecolorregisters(Widget gw GCC_UNUSED,
			 XtPointer closure GCC_UNUSED,
			 XtPointer data GCC_UNUSED)
{
    TScreen *screen = TScreenOf(term);

    ToggleFlag(screen->privatecolorregisters);
    update_privatecolorregisters();
}

void
update_privatecolorregisters(void)
{
    UpdateCheckbox("update_privatecolorregisters",
		   vtMenuEntries,
		   vtMenu_privatecolorregisters,
		   TScreenOf(term)->privatecolorregisters);
}

void
HandleSetPrivateColorRegisters(Widget w,
			       XEvent *event GCC_UNUSED,
			       String *params,
			       Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(privatecolorregisters);
}
#endif

#if OPT_SUN_FUNC_KEYS
void
HandleSunFunctionKeys(Widget w,
		      XEvent *event GCC_UNUSED,
		      String *params,
		      Cardinal *param_count)
{
    handle_vt_toggle(do_sun_fkeys, term->keyboard.type == keyboardIsSun,
		     params, *param_count, w);
}
#endif

#if OPT_NUM_LOCK
void
HandleNumLock(Widget w,
	      XEvent *event GCC_UNUSED,
	      String *params,
	      Cardinal *param_count)
{
    handle_vt_toggle(do_num_lock, term->misc.real_NumLock,
		     params, *param_count, w);
}

void
HandleAltEsc(Widget w,
	     XEvent *event GCC_UNUSED,
	     String *params,
	     Cardinal *param_count)
{
    handle_vt_toggle(do_alt_esc, !TScreenOf(term)->alt_sends_esc,
		     params, *param_count, w);
}

void
HandleMetaEsc(Widget w,
	      XEvent *event GCC_UNUSED,
	      String *params,
	      Cardinal *param_count)
{
    handle_vt_toggle(do_meta_esc, TScreenOf(term)->meta_sends_esc,
		     params, *param_count, w);
}
#endif

void
HandleDeleteIsDEL(Widget w,
		  XEvent *event GCC_UNUSED,
		  String *params,
		  Cardinal *param_count)
{
    handle_vt_toggle(do_delete_del, TScreenOf(term)->delete_is_del,
		     params, *param_count, w);
}

void
HandleOldFunctionKeys(Widget w,
		      XEvent *event GCC_UNUSED,
		      String *params,
		      Cardinal *param_count)
{
    handle_vt_toggle(do_old_fkeys, term->keyboard.type == keyboardIsLegacy,
		     params, *param_count, w);
}

#if OPT_SUNPC_KBD
void
HandleSunKeyboard(Widget w,
		  XEvent *event GCC_UNUSED,
		  String *params,
		  Cardinal *param_count)
{
    handle_vt_toggle(do_sun_kbd, term->keyboard.type == keyboardIsVT220,
		     params, *param_count, w);
}
#endif

#if OPT_HP_FUNC_KEYS
void
HandleHpFunctionKeys(Widget w,
		     XEvent *event GCC_UNUSED,
		     String *params,
		     Cardinal *param_count)
{
    handle_vt_toggle(do_hp_fkeys, term->keyboard.type == keyboardIsHP,
		     params, *param_count, w);
}
#endif

#if OPT_SCO_FUNC_KEYS
void
HandleScoFunctionKeys(Widget w,
		      XEvent *event GCC_UNUSED,
		      String *params,
		      Cardinal *param_count)
{
    handle_vt_toggle(do_sco_fkeys, term->keyboard.type == keyboardIsSCO,
		     params, *param_count, w);
}
#endif

void
HandleScrollbar(Widget w,
		XEvent *event GCC_UNUSED,
		String *params,
		Cardinal *param_count)
{
    XtermWidget xw = term;

    if (IsIcon(TScreenOf(xw))) {
	Bell(xw, XkbBI_MinorError, 0);
    } else {
	handle_vt_toggle(do_scrollbar, TScreenOf(xw)->fullVwin.sb_info.width,
			 params, *param_count, w);
    }
}

void
HandleJumpscroll(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(jumpscroll);
}

void
HandleKeepClipboard(Widget w,
		    XEvent *event GCC_UNUSED,
		    String *params,
		    Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(keepClipboard);
}

void
HandleKeepSelection(Widget w,
		    XEvent *event GCC_UNUSED,
		    String *params,
		    Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(keepSelection);
}

void
HandleSetSelect(Widget w,
		XEvent *event GCC_UNUSED,
		String *params,
		Cardinal *param_count)
{
    handle_vt_toggle(do_selectClipboard, TScreenOf(term)->selectToClipboard,
		     params, *param_count, w);
}

void
HandleReverseVideo(Widget w,
		   XEvent *event GCC_UNUSED,
		   String *params,
		   Cardinal *param_count)
{
    handle_vt_toggle(do_reversevideo, (term->misc.re_verse0),
		     params, *param_count, w);
}

void
HandleAutoWrap(Widget w,
	       XEvent *event GCC_UNUSED,
	       String *params,
	       Cardinal *param_count)
{
    handle_vt_toggle(do_autowrap, (term->flags & WRAPAROUND),
		     params, *param_count, w);
}

void
HandleReverseWrap(Widget w,
		  XEvent *event GCC_UNUSED,
		  String *params,
		  Cardinal *param_count)
{
    handle_vt_toggle(do_reversewrap, (term->flags & REVERSEWRAP),
		     params, *param_count, w);
}

void
HandleAutoLineFeed(Widget w,
		   XEvent *event GCC_UNUSED,
		   String *params,
		   Cardinal *param_count)
{
    handle_vt_toggle(do_autolinefeed, (term->flags & LINEFEED),
		     params, *param_count, w);
}

void
HandleAppCursor(Widget w,
		XEvent *event GCC_UNUSED,
		String *params,
		Cardinal *param_count)
{
    handle_vt_toggle(do_appcursor, (term->keyboard.flags & MODE_DECCKM),
		     params, *param_count, w);
}

void
HandleAppKeypad(Widget w,
		XEvent *event GCC_UNUSED,
		String *params,
		Cardinal *param_count)
{
    handle_vt_toggle(do_appkeypad, (term->keyboard.flags & MODE_DECKPAM),
		     params, *param_count, w);
}

void
HandleScrollKey(Widget w,
		XEvent *event GCC_UNUSED,
		String *params,
		Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(scrollkey);
}

void
HandleScrollTtyOutput(Widget w,
		      XEvent *event GCC_UNUSED,
		      String *params,
		      Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(scrollttyoutput);
}

void
HandleAllow132(Widget w,
	       XEvent *event GCC_UNUSED,
	       String *params,
	       Cardinal *param_count)
{
    handle_vt_toggle(do_allow132, TScreenOf(term)->c132,
		     params, *param_count, w);
}

void
HandleCursesEmul(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    handle_vt_toggle(do_cursesemul, TScreenOf(term)->curses,
		     params, *param_count, w);
}

void
HandleBellIsUrgent(Widget w,
		   XEvent *event GCC_UNUSED,
		   String *params,
		   Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(bellIsUrgent);
}

void
HandleMarginBell(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(marginbell);
}

#if OPT_BLINK_CURS
void
HandleCursorBlink(Widget w,
		  XEvent *event GCC_UNUSED,
		  String *params,
		  Cardinal *param_count)
{
    handle_vt_toggle(do_cursorblink, TScreenOf(term)->cursor_blink,
		     params, *param_count, w);
}
#endif

void
HandleAltScreen(Widget w,
		XEvent *event GCC_UNUSED,
		String *params,
		Cardinal *param_count)
{
    /* eventually want to see if sensitive or not */
    handle_vt_toggle(do_altscreen, TScreenOf(term)->whichBuf,
		     params, *param_count, w);
}

void
HandleTiteInhibit(Widget w,
		  XEvent *event GCC_UNUSED,
		  String *params,
		  Cardinal *param_count)
{
    /* eventually want to see if sensitive or not */
    handle_vt_toggle(do_titeInhibit, !(term->misc.titeInhibit),
		     params, *param_count, w);
}

/* ARGSUSED */
void
HandleSoftReset(Widget w,
		XEvent *event GCC_UNUSED,
		String *params GCC_UNUSED,
		Cardinal *param_count GCC_UNUSED)
{
    do_softreset(w, (XtPointer) 0, (XtPointer) 0);
}

/* ARGSUSED */
void
HandleHardReset(Widget w,
		XEvent *event GCC_UNUSED,
		String *params GCC_UNUSED,
		Cardinal *param_count GCC_UNUSED)
{
    do_hardreset(w, (XtPointer) 0, (XtPointer) 0);
}

/* ARGSUSED */
void
HandleClearSavedLines(Widget w,
		      XEvent *event GCC_UNUSED,
		      String *params GCC_UNUSED,
		      Cardinal *param_count GCC_UNUSED)
{
    do_clearsavedlines(w, (XtPointer) 0, (XtPointer) 0);
}

void
HandleAllowBoldFonts(Widget w,
		     XEvent *event GCC_UNUSED,
		     String *params,
		     Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(allowBoldFonts);
}

#if OPT_LOAD_VTFONTS
void
update_font_escape(void)
{
    TScreen *screen = TScreenOf(term);

    SetItemSensitivity(fontMenuEntries[fontMenu_fontescape].widget,
		       ((screen->allowFontOps &&
			 screen->EscapeFontName())
			? True : False));
}
#endif

#if OPT_DEC_CHRSET
void
HandleFontDoublesize(Widget w,
		     XEvent *event GCC_UNUSED,
		     String *params,
		     Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(font_doublesize);
}
#endif

#if OPT_BOX_CHARS
void
HandleFontBoxChars(Widget w,
		   XEvent *event GCC_UNUSED,
		   String *params,
		   Cardinal *param_count)
{
    handle_vt_toggle(do_font_boxchars, TScreenOf(term)->force_box_chars,
		     params, *param_count, w);
}

void
HandleFontPacked(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    handle_vt_toggle(do_font_packed, TScreenOf(term)->force_packed,
		     params, *param_count, w);
}
#endif

#if OPT_DEC_SOFTFONT
void
HandleFontLoading(Widget w,
		  XEvent *event GCC_UNUSED,
		  String *params,
		  Cardinal *param_count)
{
    handle_vt_toggle(do_font_loadable, term->misc.font_loadable,
		     params, *param_count, w);
}
#endif

#if OPT_RENDERFONT
static void
update_fontmenu(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    int n;

    for (n = 0; n <= fontMenu_lastBuiltin; ++n) {
	Boolean active = (Boolean) (xw->work.render_font ||
				    (screen->menu_font_sizes[n] >= 0));
	SetItemSensitivity(fontMenuEntries[n].widget, active);
    }
}

void
HandleRenderFont(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    XtermWidget xw = (XtermWidget) term;

    DefaultRenderFont(xw);

    handle_vt_toggle(do_font_renderfont, xw->work.render_font,
		     params, *param_count, w);

    update_fontmenu(xw);
}
#endif

#if OPT_WIDE_CHARS
void
HandleUTF8Mode(Widget w,
	       XEvent *event GCC_UNUSED,
	       String *params,
	       Cardinal *param_count)
{
    handle_vt_toggle(do_font_utf8_mode, TScreenOf(term)->utf8_mode,
		     params, *param_count, w);
}

void
HandleUTF8Fonts(Widget w,
		XEvent *event GCC_UNUSED,
		String *params,
		Cardinal *param_count)
{
    handle_vt_toggle(do_font_utf8_fonts, TScreenOf(term)->utf8_fonts,
		     params, *param_count, w);
}

void
HandleUTF8Title(Widget w,
		XEvent *event GCC_UNUSED,
		String *params,
		Cardinal *param_count)
{
    handle_vt_toggle(do_font_utf8_title, TScreenOf(term)->utf8_title,
		     params, *param_count, w);
}
#endif

#if OPT_SCREEN_DUMPS
void
HandleDumpHtml(Widget w GCC_UNUSED,
	       XEvent *event GCC_UNUSED,
	       String *params GCC_UNUSED,
	       Cardinal *param_count GCC_UNUSED)
{
    xtermDumpHtml(term);
}

void
HandleDumpSvg(Widget w GCC_UNUSED,
	      XEvent *event GCC_UNUSED,
	      String *params GCC_UNUSED,
	      Cardinal *param_count GCC_UNUSED)
{
    xtermDumpSvg(term);
}
#endif

#if OPT_TEK4014
void
HandleSetTerminalType(Widget w,
		      XEvent *event GCC_UNUSED,
		      String *params,
		      Cardinal *param_count)
{
    XtermWidget xw = term;

    if (*param_count == 1) {
	switch (params[0][0]) {
	case 'v':
	case 'V':
	    if (TEK4014_ACTIVE(xw))
		do_vtmode(w, (XtPointer) 0, (XtPointer) 0);
	    break;
	case 't':
	case 'T':
	    if (!TEK4014_ACTIVE(xw))
		do_tekmode(w, (XtPointer) 0, (XtPointer) 0);
	    break;
	default:
	    Bell(xw, XkbBI_MinorError, 0);
	}
    } else {
	Bell(xw, XkbBI_MinorError, 0);
    }
}

void
HandleVisibility(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    XtermWidget xw = term;

    if (*param_count == 2) {
	switch (params[0][0]) {
	case 'v':
	case 'V':
	    handle_tek_toggle(do_vtonoff, (int) TScreenOf(xw)->Vshow,
			      params + 1, (*param_count) - 1, w);
	    break;
	case 't':
	case 'T':
	    handle_tek_toggle(do_tekonoff, (int) TEK4014_SHOWN(xw),
			      params + 1, (*param_count) - 1, w);
	    break;
	default:
	    Bell(xw, XkbBI_MinorError, 0);
	}
    } else {
	Bell(xw, XkbBI_MinorError, 0);
    }
}

/* ARGSUSED */
void
HandleSetTekText(Widget w,
		 XEvent *event GCC_UNUSED,
		 String *params,
		 Cardinal *param_count)
{
    XtermWidget xw = term;
    void (*proc) PROTO_XT_CALLBACK_ARGS = NULL;

    switch (*param_count) {
    case 0:
	proc = do_tektextlarge;
	break;
    case 1:
	switch (TekGetFontSize(params[0])) {
	case TEK_FONT_LARGE:
	    proc = do_tektextlarge;
	    break;
	case TEK_FONT_2:
	    proc = do_tektext2;
	    break;
	case TEK_FONT_3:
	    proc = do_tektext3;
	    break;
	case TEK_FONT_SMALL:
	    proc = do_tektextsmall;
	    break;
	}
	break;
    }
    if (proc)
	(*proc) (w, (XtPointer) 0, (XtPointer) 0);
    else
	Bell(xw, XkbBI_MinorError, 0);
}

/* ARGSUSED */
void
HandleTekPage(Widget w,
	      XEvent *event GCC_UNUSED,
	      String *params GCC_UNUSED,
	      Cardinal *param_count GCC_UNUSED)
{
    do_tekpage(w, (XtPointer) 0, (XtPointer) 0);
}

/* ARGSUSED */
void
HandleTekReset(Widget w,
	       XEvent *event GCC_UNUSED,
	       String *params GCC_UNUSED,
	       Cardinal *param_count GCC_UNUSED)
{
    do_tekreset(w, (XtPointer) 0, (XtPointer) 0);
}

/* ARGSUSED */
void
HandleTekCopy(Widget w,
	      XEvent *event GCC_UNUSED,
	      String *params GCC_UNUSED,
	      Cardinal *param_count GCC_UNUSED)
{
    do_tekcopy(w, (XtPointer) 0, (XtPointer) 0);
}
#endif /* OPT_TEK4014 */

#if OPT_TOOLBAR
/*
 * The normal style of xterm popup menu delays initialization until the menu is
 * first requested.  When using a toolbar, we can use the same initialization,
 * though on the first popup there will be a little geometry layout jitter,
 * since the menu is already managed when this callback is invoked.
 */
static void
InitPopup(Widget gw,
	  XtPointer closure,
	  XtPointer data GCC_UNUSED)
{
    String params[2];
    Cardinal count = 1;

    params[0] = (char *) closure;
    params[1] = NULL;
    TRACE(("InitPopup(%s)\n", params[0]));

    domenu(gw, (XEvent *) 0, params, &count);

    XtRemoveCallback(gw, XtNpopupCallback, InitPopup, closure);
}

static Dimension
SetupShell(Widget *menus, MenuList * shell, int n, int m)
{
    char temp[80];
    char *external_name = NULL;
    Dimension button_height;
    Dimension button_border;
    char *saveLocale = xtermSetLocale(LC_CTYPE, resource.menuLocale);

    shell[n].w = XtVaCreatePopupShell(menu_names[n].internal_name,
				      simpleMenuWidgetClass,
				      *menus,
				      XtNgeometry, NULL,
				      (XtPointer) 0);
    TRACE(("created popupShel widget %p, window %#lx\n",
	   (void *) shell[n].w, XtWindow(shell[n].w)));

    XtAddCallback(shell[n].w, XtNpopupCallback, InitPopup, menu_names[n].internal_name);
    XtVaGetValues(shell[n].w,
		  XtNlabel, &external_name,
		  (XtPointer) 0);

    TRACE(("...SetupShell(%s) -> %s -> %#lx\n",
	   menu_names[n].internal_name,
	   external_name,
	   (long) shell[n].w));

    sprintf(temp, "%sButton", menu_names[n].internal_name);
    shell[n].b = XtVaCreateManagedWidget(temp,
					 menuButtonWidgetClass,
					 *menus,
					 XtNfromHoriz, ((m >= 0)
							? shell[m].b
							: NULL),
					 XtNmenuName, menu_names[n].internal_name,
					 XtNlabel, external_name,
					 (XtPointer) 0);
    TRACE(("created menuButton[%d] widget %p, window %#lx\n",
	   n, (void *) shell[n].b, XtWindow(shell[n].b)));
    XtVaGetValues(shell[n].b,
		  XtNheight, &button_height,
		  XtNborderWidth, &button_border,
		  (XtPointer) 0);

    xtermResetLocale(LC_CTYPE, saveLocale);
    return (Dimension) (button_height + (button_border * 2));
}
#endif /* OPT_TOOLBAR */

void
SetupMenus(Widget shell, Widget *forms, Widget *menus, Dimension *menu_high)
{
#if OPT_TOOLBAR
    Dimension button_height = 0;
    Dimension toolbar_hSpace;
    Arg args[10];
#endif

    TRACE(("SetupMenus(%s)\n", shell == toplevel ? "vt100" : "tek4014"));

    *menu_high = 0;

    if (shell == toplevel) {
	XawSimpleMenuAddGlobalActions(app_con);
	XtRegisterGrabAction(HandlePopupMenu, True,
			     (unsigned) (ButtonPressMask | ButtonReleaseMask),
			     GrabModeAsync, GrabModeAsync);
    }
#if OPT_TOOLBAR
    *forms = XtVaCreateManagedWidget("form",
				     formWidgetClass, shell,
				     (XtPointer) 0);
    TRACE(("created form widget %p, window %#lx\n",
	   (void *) *forms, XtWindow(*forms)));
    xtermAddInput(*forms);

    /*
     * Set a nominal value for the preferred pane size, which lets the
     * buttons determine the actual height of the menu bar.  We don't show
     * the grip, because it's too easy to make the toolbar look bad that
     * way.
     */
    XtSetArg(args[0], XtNorientation, XtorientHorizontal);
    XtSetArg(args[1], XtNtop, XawChainTop);
    XtSetArg(args[2], XtNbottom, XawChainTop);
    XtSetArg(args[3], XtNleft, XawChainLeft);
    XtSetArg(args[4], XtNright, XawChainLeft);

    if (resource.toolBar) {
	*menus = XtCreateManagedWidget("menubar", boxWidgetClass, *forms,
				       args, 5);
    } else {
	*menus = XtCreateWidget("menubar", boxWidgetClass, *forms, args, 5);
    }
    TRACE(("created menubar widget %p, window %#lx\n",
	   (void *) *menus, XtWindow(*menus)));

    /*
     * The toolbar widget's height is not necessarily known yet.  If the
     * toolbar is not created as a managed widget, we can still make a good
     * guess about its height by collecting the widget's other resource values.
     */
    XtVaGetValues(*menus,
		  XtNhSpace, &toolbar_hSpace,
		  (XtPointer) 0);

    if (shell == toplevel) {	/* vt100 */
	int j;
	for (j = mainMenu; j <= fontMenu; j++) {
	    button_height = SetupShell(menus, vt_shell, j, j - 1);
	}
    }
#if OPT_TEK4014
    else {			/* tek4014 */
	(void) SetupShell(menus, tek_shell, mainMenu, -1);
	button_height = SetupShell(menus, tek_shell, tekMenu, mainMenu);
    }
#endif

    /*
     * Tell the main program how high the toolbar is, to help with the initial
     * layout.
     */
    *menu_high = (Dimension) (button_height + 2 * (toolbar_hSpace));
    TRACE(("...menuHeight:%d = (%d + 2 * %d)\n",
	   *menu_high, button_height, toolbar_hSpace));

#else /* !OPT_TOOLBAR */
    *forms = shell;
    *menus = shell;
#endif

    TRACE(("...shell=%#lx\n", (long) shell));
    TRACE(("...forms=%#lx\n", (long) *forms));
    TRACE(("...menus=%#lx\n", (long) *menus));
}

void
repairSizeHints(void)
{
    XtermWidget xw = term;
    TScreen *screen = TScreenOf(xw);

    if (XtIsRealized((Widget) xw)) {
	getXtermSizeHints(xw);
	xtermSizeHints(xw, ScrollbarWidth(screen));

	XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints);
    }
}

#if OPT_TOOLBAR
#define INIT_POPUP(s, n) InitPopup(s[n].w, menu_names[n].internal_name, NULL)

static Bool
InitWidgetMenu(Widget shell)
{
    Bool result = False;

    TRACE(("InitWidgetMenu(%p)\n", (void *) shell));
    if (term != NULL) {
	if (shell == toplevel) {	/* vt100 */
	    if (!term->init_menu) {
		INIT_POPUP(vt_shell, mainMenu);
		INIT_POPUP(vt_shell, vtMenu);
		INIT_POPUP(vt_shell, fontMenu);
		term->init_menu = True;
		TRACE(("...InitWidgetMenu(vt)\n"));
	    }
	    result = term->init_menu;
	}
#if OPT_TEK4014
	else if (tekWidget) {	/* tek4014 */
	    if (!tekWidget->init_menu) {
		INIT_POPUP(tek_shell, mainMenu);
		INIT_POPUP(tek_shell, tekMenu);
		tekWidget->init_menu = True;
		TRACE(("...InitWidgetMenu(tek)\n"));
	    }
	    result = tekWidget->init_menu;
	}
#endif
    }
    TRACE(("...InitWidgetMenu ->%d\n", result));
    return result;
}

static TbInfo *
toolbar_info(Widget w)
{
    TRACE(("...getting toolbar_info\n"));
#if OPT_TEK4014
    if (w != (Widget) term)
	return &(tekWidget->tek.tb_info);
#else
    (void) w;
#endif
    return &(WhichVWin(TScreenOf(term))->tb_info);
}

static void
hide_toolbar(Widget w)
{
    if (w != NULL) {
	TbInfo *info = toolbar_info(w);

	TRACE(("hiding toolbar\n"));
	XtVaSetValues(w,
		      XtNfromVert, (Widget) 0,
		      (XtPointer) 0);

	if (info->menu_bar != NULL) {
	    repairSizeHints();
	    XtUnmanageChild(info->menu_bar);
	    if (XtIsRealized(info->menu_bar)) {
		XtUnmapWidget(info->menu_bar);
	    }
	}
	TRACE(("...hiding toolbar (done)\n"));
    }
}

static void
show_toolbar(Widget w)
{
    if (w != NULL) {
	TbInfo *info = toolbar_info(w);

	TRACE(("showing toolbar\n"));
	if (info->menu_bar != NULL) {
	    XtVaSetValues(w,
			  XtNfromVert, info->menu_bar,
			  (XtPointer) 0);
	    if (XtIsRealized(info->menu_bar))
		repairSizeHints();
	    XtManageChild(info->menu_bar);
	    if (XtIsRealized(info->menu_bar)) {
		XtMapWidget(info->menu_bar);
	    }
	}
	/*
	 * This is needed to make the terminal widget move down below the
	 * toolbar.
	 */
	XawFormDoLayout(XtParent(w), True);
	TRACE(("...showing toolbar (done)\n"));
    }
}

/*
 * Make the toolbar visible or invisible in the current window(s).
 */
void
ShowToolbar(Bool enable)
{
    XtermWidget xw = term;

    TRACE(("ShowToolbar(%d)\n", enable));

    if (IsIcon(TScreenOf(xw))) {
	Bell(xw, XkbBI_MinorError, 0);
    } else {
	if (enable) {
	    if (InitWidgetMenu(toplevel))
		show_toolbar((Widget) xw);
#if OPT_TEK4014
	    if (InitWidgetMenu(tekshellwidget))
		show_toolbar((Widget) tekWidget);
#endif
	} else {
	    hide_toolbar((Widget) xw);
#if OPT_TEK4014
	    hide_toolbar((Widget) tekWidget);
#endif
	}
	resource.toolBar = (Boolean) enable;
	update_toolbar();
    }
#if OPT_TOOLBAR
    /*
     * Layout for the toolbar confuses the Shell widget.  Remind it that we
     * would like to be iconified if the corresponding resource was set.
     */
    {
	static Bool first = True;
	if (first && XtIsRealized(toplevel)) {
	    Boolean iconic = 0;

	    XtVaGetValues(toplevel,
			  XtNiconic, &iconic,
			  (XtPointer) 0);

	    if (iconic) {
		TRACE(("...please iconify window %#lx\n", XtWindow(toplevel)));
		xtermIconify(xw);
	    }
	    first = False;
	}
    }
#endif
}

void
HandleToolbar(Widget w,
	      XEvent *event GCC_UNUSED,
	      String *params,
	      Cardinal *param_count)
{
    XtermWidget xw = term;

    if (IsIcon(TScreenOf(xw))) {
	Bell(xw, XkbBI_MinorError, 0);
    } else {
	handle_vt_toggle(do_toolbar, resource.toolBar,
			 params, *param_count, w);
    }
}

/* ARGSUSED */
static void
do_toolbar(Widget gw GCC_UNUSED,
	   XtPointer closure GCC_UNUSED,
	   XtPointer data GCC_UNUSED)
{
    XtermWidget xw = term;

    /*
     * Toggle toolbars for both vt100 and tek windows, since they share the
     * menu which contains the checkbox indicating whether the toolbar is
     * active.
     */
    if (IsIcon(TScreenOf(xw))) {
	Bell(xw, XkbBI_MinorError, 0);
    } else {
	ShowToolbar(ToggleFlag(resource.toolBar));
    }
}

void
update_toolbar(void)
{
    UpdateCheckbox("update_toolbar",
		   mainMenuEntries,
		   mainMenu_toolbar,
		   resource.toolBar);
}
#endif /* OPT_TOOLBAR */

void
update_securekbd(void)
{
    UpdateCheckbox("update_securekbd",
		   mainMenuEntries,
		   mainMenu_securekbd,
		   TScreenOf(term)->grabbedKbd);
}

void
update_allowsends(void)
{
    UpdateCheckbox("update_allowsends",
		   mainMenuEntries,
		   mainMenu_allowsends,
		   TScreenOf(term)->allowSendEvents);
}

#ifdef ALLOWLOGGING
void
update_logging(void)
{
    UpdateCheckbox("update_logging",
		   mainMenuEntries,
		   mainMenu_logging,
		   TScreenOf(term)->logging);
}
#endif

#if OPT_PRINT_ON_EXIT
void
update_write_error(void)
{
    UpdateCheckbox("update_write_error",
		   mainMenuEntries,
		   mainMenu_write_error,
		   TScreenOf(term)->write_error);
}
#endif

void
update_print_redir(void)
{
    UpdateCheckbox("update_print_redir",
		   mainMenuEntries,
		   mainMenu_print_redir,
		   PrinterOf(TScreenOf(term)).printer_controlmode);
}

void
update_8bit_control(void)
{
    UpdateCheckbox("update_8bit_control",
		   mainMenuEntries,
		   mainMenu_8bit_ctrl,
		   TScreenOf(term)->control_eight_bits);
}

void
update_decbkm(void)
{
    UpdateCheckbox("update_decbkm",
		   mainMenuEntries,
		   mainMenu_backarrow,
		   (term->keyboard.flags & MODE_DECBKM) != 0);
}

#if OPT_NUM_LOCK
void
update_num_lock(void)
{
    UpdateCheckbox("update_num_lock",
		   mainMenuEntries,
		   mainMenu_num_lock,
		   term->misc.real_NumLock);
}

void
update_alt_esc(void)
{
    UpdateCheckbox("update_alt_esc",
		   mainMenuEntries,
		   mainMenu_alt_esc,
		   TScreenOf(term)->alt_sends_esc);
}

void
update_meta_esc(void)
{
    UpdateCheckbox("update_meta_esc",
		   mainMenuEntries,
		   mainMenu_meta_esc,
		   TScreenOf(term)->meta_sends_esc);
}
#endif

#if OPT_SUN_FUNC_KEYS
void
update_sun_fkeys(void)
{
    UpdateCheckbox("update_sun_fkeys",
		   mainMenuEntries,
		   mainMenu_sun_fkeys,
		   term->keyboard.type == keyboardIsSun);
}
#endif

#if OPT_TCAP_FKEYS
void
update_tcap_fkeys(void)
{
    UpdateCheckbox("update_tcap_fkeys",
		   mainMenuEntries,
		   mainMenu_tcap_fkeys,
		   term->keyboard.type == keyboardIsTermcap);
}
#endif

void
update_old_fkeys(void)
{
    UpdateCheckbox("update_old_fkeys",
		   mainMenuEntries,
		   mainMenu_old_fkeys,
		   term->keyboard.type == keyboardIsLegacy);
}

void
update_delete_del(void)
{
    UpdateCheckbox("update_delete_del",
		   mainMenuEntries,
		   mainMenu_delete_del,
		   xtermDeleteIsDEL(term));
}

#if OPT_SUNPC_KBD
void
update_sun_kbd(void)
{
    UpdateCheckbox("update_sun_kbd",
		   mainMenuEntries,
		   mainMenu_sun_kbd,
		   term->keyboard.type == keyboardIsVT220);
}
#endif

#if OPT_HP_FUNC_KEYS
void
update_hp_fkeys(void)
{
    UpdateCheckbox("update_hp_fkeys",
		   mainMenuEntries,
		   mainMenu_hp_fkeys,
		   term->keyboard.type == keyboardIsHP);
}
#endif

#if OPT_SCO_FUNC_KEYS
void
update_sco_fkeys(void)
{
    UpdateCheckbox("update_sco_fkeys",
		   mainMenuEntries,
		   mainMenu_sco_fkeys,
		   term->keyboard.type == keyboardIsSCO);
}
#endif

void
update_scrollbar(void)
{
    UpdateCheckbox("update_scrollbar",
		   vtMenuEntries,
		   vtMenu_scrollbar,
		   ScrollbarWidth(TScreenOf(term)));
}

void
update_jumpscroll(void)
{
    UpdateCheckbox("update_jumpscroll",
		   vtMenuEntries,
		   vtMenu_jumpscroll,
		   TScreenOf(term)->jumpscroll);
}

void
update_reversevideo(void)
{
    UpdateCheckbox("update_reversevideo",
		   vtMenuEntries,
		   vtMenu_reversevideo,
		   (term->misc.re_verse));
}

void
update_autowrap(void)
{
    DisableIfVT52(vtMenuEntries,
		  vtMenu_autowrap);
    UpdateCheckbox("update_autowrap",
		   vtMenuEntries,
		   vtMenu_autowrap,
		   (term->flags & WRAPAROUND) != 0);
}

void
update_reversewrap(void)
{
    DisableIfVT52(vtMenuEntries,
		  vtMenu_reversewrap);
    UpdateCheckbox("update_reversewrap",
		   vtMenuEntries,
		   vtMenu_reversewrap,
		   (term->flags & REVERSEWRAP) != 0);
}

void
update_autolinefeed(void)
{
    DisableIfVT52(vtMenuEntries,
		  vtMenu_autolinefeed);
    UpdateCheckbox("update_autolinefeed",
		   vtMenuEntries,
		   vtMenu_autolinefeed,
		   (term->flags & LINEFEED) != 0);
}

void
update_appcursor(void)
{
    DisableIfVT52(vtMenuEntries,
		  vtMenu_appcursor);
    UpdateCheckbox("update_appcursor",
		   vtMenuEntries,
		   vtMenu_appcursor,
		   (term->keyboard.flags & MODE_DECCKM) != 0);
}

void
update_appkeypad(void)
{
    UpdateCheckbox("update_appkeypad",
		   vtMenuEntries,
		   vtMenu_appkeypad,
		   (term->keyboard.flags & MODE_DECKPAM) != 0);
}

void
update_scrollkey(void)
{
    UpdateCheckbox("update_scrollkey",
		   vtMenuEntries,
		   vtMenu_scrollkey,
		   TScreenOf(term)->scrollkey);
}

void
update_scrollttyoutput(void)
{
    UpdateCheckbox("update_scrollttyoutput",
		   vtMenuEntries,
		   vtMenu_scrollttyoutput,
		   TScreenOf(term)->scrollttyoutput);
}

void
update_keepSelection(void)
{
    UpdateCheckbox("update_keepSelection",
		   vtMenuEntries,
		   vtMenu_keepSelection,
		   TScreenOf(term)->keepSelection);
}

void
update_selectToClipboard(void)
{
    UpdateCheckbox("update_selectToClipboard",
		   vtMenuEntries,
		   vtMenu_selectToClipboard,
		   TScreenOf(term)->selectToClipboard);
}

void
update_allow132(void)
{
    DisableIfVT52(vtMenuEntries,
		  vtMenu_allow132);
    UpdateCheckbox("update_allow132",
		   vtMenuEntries,
		   vtMenu_allow132,
		   TScreenOf(term)->c132);
}

void
update_cursesemul(void)
{
#if 0				/* 2006-2-12: no longer menu entry */
    UpdateMenuItem("update_cursesemul", vtMenuEntries, vtMenu_cursesemul,
		   TScreenOf(term)->curses);
#endif
}

void
update_visualbell(void)
{
    UpdateCheckbox("update_visualbell",
		   vtMenuEntries,
		   vtMenu_visualbell,
		   TScreenOf(term)->visualbell);
}

void
update_bellIsUrgent(void)
{
    UpdateCheckbox("update_bellIsUrgent",
		   vtMenuEntries,
		   vtMenu_bellIsUrgent,
		   TScreenOf(term)->bellIsUrgent);
}

void
update_poponbell(void)
{
    UpdateCheckbox("update_poponbell",
		   vtMenuEntries,
		   vtMenu_poponbell,
		   TScreenOf(term)->poponbell);
}

#ifndef update_marginbell	/* 2007-3-7: no longer menu entry */
void
update_marginbell(void)
{
    UpdateCheckbox("update_marginbell",
		   vtMenuEntries,
		   vtMenu_marginbell,
		   TScreenOf(term)->marginbell);
}
#endif

#if OPT_BLINK_CURS
void
update_cursorblink(void)
{
    BlinkOps check = TScreenOf(term)->cursor_blink;

    if (check == cbAlways ||
	check == cbNever) {
	SetItemSensitivity(vtMenuEntries[vtMenu_cursorblink].widget, False);
    }
    UpdateCheckbox("update_cursorblink",
		   vtMenuEntries,
		   vtMenu_cursorblink,
		   (check == cbTrue ||
		    check == cbAlways));
}
#endif

void
update_altscreen(void)
{
    UpdateCheckbox("update_altscreen",
		   vtMenuEntries,
		   vtMenu_altscreen,
		   TScreenOf(term)->whichBuf);
}

void
update_titeInhibit(void)
{
    UpdateCheckbox("update_titeInhibit",
		   vtMenuEntries,
		   vtMenu_titeInhibit,
		   !(term->misc.titeInhibit));
}

#ifndef NO_ACTIVE_ICON
void
update_activeicon(void)
{
    SetItemSensitivity(vtMenuEntries[vtMenu_activeicon].widget, False);
    UpdateCheckbox("update_activeicon",
		   vtMenuEntries,
		   vtMenu_activeicon,
		   term->work.active_icon);
}
#endif /* NO_ACTIVE_ICON */

static void
do_allowBoldFonts(Widget w,
		  XtPointer closure GCC_UNUSED,
		  XtPointer data GCC_UNUSED)
{
    XtermWidget xw = getXtermWidget(w);
    if (xw != NULL) {
	ToggleFlag(TScreenOf(xw)->allowBoldFonts);
	update_menu_allowBoldFonts();
	Redraw();
    }
}

#if OPT_DEC_CHRSET
void
update_font_doublesize(void)
{
    UpdateCheckbox("update_font_doublesize",
		   fontMenuEntries,
		   fontMenu_font_doublesize,
		   TScreenOf(term)->font_doublesize);
}
#endif

#if OPT_BOX_CHARS
void
update_font_boxchars(void)
{
    SetItemSensitivity(fontMenuEntries[fontMenu_font_boxchars].widget,
		       !TScreenOf(term)->broken_box_chars);
    UpdateCheckbox("update_font_boxchars",
		   fontMenuEntries,
		   fontMenu_font_boxchars,
		   TScreenOf(term)->force_box_chars ||
		   TScreenOf(term)->broken_box_chars);
}

void
update_font_packed(void)
{
    UpdateCheckbox("update_font_packed",
		   fontMenuEntries,
		   fontMenu_font_packedfont,
		   TScreenOf(term)->force_packed);
}
#endif

#if OPT_DEC_SOFTFONT
void
update_font_loadable(void)
{
    UpdateCheckbox("update_font_loadable",
		   fontMenuEntries,
		   fontMenu_font_loadable,
		   term->misc.font_loadable);
}
#endif

#if OPT_RENDERFONT
void
update_font_renderfont(void)
{
    UpdateCheckbox("update_font_renderfont",
		   fontMenuEntries,
		   fontMenu_render_font,
		   (term->work.render_font == True));
    SetItemSensitivity(fontMenuEntries[fontMenu_render_font].widget,
		       !IsEmpty(CurrentXftFont(term)));

#if OPT_BOX_CHARS
    if (term->work.render_font) {
	TScreenOf(term)->broken_box_chars = term->work.broken_box_chars;
    } else {
	TScreenOf(term)->broken_box_chars = False;
    }
#endif
    update_font_boxchars();

    update_fontmenu(term);
}
#endif

#if OPT_WIDE_CHARS
void
update_font_utf8_mode(void)
{
    Bool active = (TScreenOf(term)->utf8_mode != uAlways);
    Bool enable = (TScreenOf(term)->utf8_mode != uFalse);

    TRACE(("update_font_utf8_mode active %d, enable %d\n", active, enable));
    SetItemSensitivity(fontMenuEntries[fontMenu_utf8_mode].widget, active);
    UpdateCheckbox("update_font_utf8_mode",
		   fontMenuEntries,
		   fontMenu_utf8_mode,
		   enable);
}

void
update_font_utf8_fonts(void)
{
    Bool active = (TScreenOf(term)->utf8_fonts != uAlways);
    Bool enable = (TScreenOf(term)->utf8_fonts != uFalse);

    TRACE(("update_font_utf8_fonts active %d, enable %d\n", active, enable));
    SetItemSensitivity(fontMenuEntries[fontMenu_utf8_fonts].widget, active);
    UpdateCheckbox("update_font_utf8_fonts",
		   fontMenuEntries,
		   fontMenu_utf8_fonts,
		   enable);
}

void
update_font_utf8_title(void)
{
    Bool active = (TScreenOf(term)->utf8_mode != uAlways);
    Bool enable = (TScreenOf(term)->utf8_mode != uFalse);

    TRACE(("update_font_utf8_title active %d, enable %d\n", active, enable));
    SetItemSensitivity(fontMenuEntries[fontMenu_utf8_title].widget, active);
    UpdateCheckbox("update_font_utf8_title",
		   fontMenuEntries,
		   fontMenu_utf8_title,
		   enable);
}
#endif

#if OPT_DEC_CHRSET || OPT_BOX_CHARS || OPT_DEC_SOFTFONT
void
update_menu_allowBoldFonts(void)
{
    UpdateCheckbox("update_menu_allowBoldFonts",
		   fontMenuEntries,
		   fontMenu_allowBoldFonts,
		   TScreenOf(term)->allowBoldFonts);
}
#endif

#if OPT_ALLOW_XXX_OPS
static void
enable_allow_xxx_ops(Bool enable)
{
    SetItemSensitivity(fontMenuEntries[fontMenu_allowFontOps].widget, enable);
    SetItemSensitivity(fontMenuEntries[fontMenu_allowMouseOps].widget, enable);
    SetItemSensitivity(fontMenuEntries[fontMenu_allowTcapOps].widget, enable);
    SetItemSensitivity(fontMenuEntries[fontMenu_allowTitleOps].widget, enable);
    SetItemSensitivity(fontMenuEntries[fontMenu_allowWindowOps].widget, enable);
}

static void
do_allowColorOps(Widget w,
		 XtPointer closure GCC_UNUSED,
		 XtPointer data GCC_UNUSED)
{
    XtermWidget xw = getXtermWidget(w);
    if (xw != NULL) {
	ToggleFlag(TScreenOf(xw)->allowColorOps);
	update_menu_allowColorOps();
    }
}

static void
do_allowFontOps(Widget w,
		XtPointer closure GCC_UNUSED,
		XtPointer data GCC_UNUSED)
{
    XtermWidget xw = getXtermWidget(w);
    if (xw != NULL) {
	ToggleFlag(TScreenOf(xw)->allowFontOps);
	update_menu_allowFontOps();
    }
}

static void
do_allowMouseOps(Widget w,
		 XtPointer closure GCC_UNUSED,
		 XtPointer data GCC_UNUSED)
{
    XtermWidget xw = getXtermWidget(w);
    if (xw != NULL) {
	ToggleFlag(TScreenOf(xw)->allowMouseOps);
	update_menu_allowMouseOps();
    }
}

static void
do_allowTcapOps(Widget w,
		XtPointer closure GCC_UNUSED,
		XtPointer data GCC_UNUSED)
{
    XtermWidget xw = getXtermWidget(w);
    if (xw != NULL) {
	ToggleFlag(TScreenOf(xw)->allowTcapOps);
	update_menu_allowTcapOps();
    }
}

static void
do_allowTitleOps(Widget w,
		 XtPointer closure GCC_UNUSED,
		 XtPointer data GCC_UNUSED)
{
    XtermWidget xw = getXtermWidget(w);
    if (xw != NULL) {
	ToggleFlag(TScreenOf(xw)->allowTitleOps);
	update_menu_allowTitleOps();
    }
}

static void
do_allowWindowOps(Widget w,
		  XtPointer closure GCC_UNUSED,
		  XtPointer data GCC_UNUSED)
{
    XtermWidget xw = getXtermWidget(w);
    if (xw != NULL) {
	ToggleFlag(TScreenOf(xw)->allowWindowOps);
	update_menu_allowWindowOps();
    }
}

void
HandleAllowColorOps(Widget w,
		    XEvent *event GCC_UNUSED,
		    String *params,
		    Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(allowColorOps);
}

void
HandleAllowFontOps(Widget w,
		   XEvent *event GCC_UNUSED,
		   String *params,
		   Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(allowFontOps);
}

void
HandleAllowMouseOps(Widget w,
		    XEvent *event GCC_UNUSED,
		    String *params,
		    Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(allowMouseOps);
}

void
HandleAllowTcapOps(Widget w,
		   XEvent *event GCC_UNUSED,
		   String *params,
		   Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(allowTcapOps);
}

void
HandleAllowTitleOps(Widget w,
		    XEvent *event GCC_UNUSED,
		    String *params,
		    Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(allowTitleOps);
}

void
HandleAllowWindowOps(Widget w,
		     XEvent *event GCC_UNUSED,
		     String *params,
		     Cardinal *param_count)
{
    HANDLE_VT_TOGGLE(allowWindowOps);
}

void
update_menu_allowColorOps(void)
{
    UpdateCheckbox("update_menu_allowColorOps",
		   fontMenuEntries,
		   fontMenu_allowColorOps,
		   TScreenOf(term)->allowColorOps);
}

void
update_menu_allowFontOps(void)
{
    UpdateCheckbox("update_menu_allowFontOps",
		   fontMenuEntries,
		   fontMenu_allowFontOps,
		   TScreenOf(term)->allowFontOps);
}

void
update_menu_allowMouseOps(void)
{
    UpdateCheckbox("update_menu_allowMouseOps",
		   fontMenuEntries,
		   fontMenu_allowMouseOps,
		   TScreenOf(term)->allowMouseOps);
}

void
update_menu_allowTcapOps(void)
{
    UpdateCheckbox("update_menu_allowTcapOps",
		   fontMenuEntries,
		   fontMenu_allowTcapOps,
		   TScreenOf(term)->allowTcapOps);
}

void
update_menu_allowTitleOps(void)
{
    UpdateCheckbox("update_menu_allowTitleOps",
		   fontMenuEntries,
		   fontMenu_allowTitleOps,
		   TScreenOf(term)->allowTitleOps);
}

void
update_menu_allowWindowOps(void)
{
    UpdateCheckbox("update_menu_allowWindowOps",
		   fontMenuEntries,
		   fontMenu_allowWindowOps,
		   TScreenOf(term)->allowWindowOps);
}
#endif

#if OPT_TEK4014
void
update_tekshow(void)
{
    if (!(TScreenOf(term)->inhibit & I_TEK)) {
	UpdateCheckbox("update_tekshow",
		       vtMenuEntries,
		       vtMenu_tekshow,
		       TEK4014_SHOWN(term));
    }
}

void
update_vttekmode(void)
{
    XtermWidget xw = term;

    if (!(TScreenOf(xw)->inhibit & I_TEK)) {
	UpdateCheckbox("update_vtmode",
		       vtMenuEntries,
		       vtMenu_tekmode,
		       TEK4014_ACTIVE(xw));
	UpdateCheckbox("update_tekmode",
		       tekMenuEntries,
		       tekMenu_vtmode,
		       !TEK4014_ACTIVE(xw));
	update_fullscreen();
    }
}

void
update_vtshow(void)
{
    if (!(TScreenOf(term)->inhibit & I_TEK)) {
	UpdateCheckbox("update_vtshow",
		       tekMenuEntries,
		       tekMenu_vtshow,
		       TScreenOf(term)->Vshow);
    }
}

void
set_vthide_sensitivity(void)
{
    if (!(TScreenOf(term)->inhibit & I_TEK)) {
	SetItemSensitivity(
			      vtMenuEntries[vtMenu_vthide].widget,
			      TEK4014_SHOWN(term));
    }
}

void
set_tekhide_sensitivity(void)
{
    if (!(TScreenOf(term)->inhibit & I_TEK)) {
	SetItemSensitivity(
			      tekMenuEntries[tekMenu_tekhide].widget,
			      TScreenOf(term)->Vshow);
    }
}

void
set_tekfont_menu_item(int n, int val)
{
    if (!(TScreenOf(term)->inhibit & I_TEK)) {
	UpdateCheckbox("set_tekfont_menu_item", tekMenuEntries, FS2MI(n),
		       (val));
    }
}
#endif /* OPT_TEK4014 */

void
set_menu_font(int val)
{
    UpdateCheckbox("set_menu_font",
		   fontMenuEntries,
		   TScreenOf(term)->menu_font_number,
		   (val));
}
xterm-399/screen.c0000644000000000000000000025430114776054330012676 0ustar  rootroot/* $XTermId: screen.c,v 1.660 2025/04/10 23:48:40 tom Exp $ */

/*
 * Copyright 1999-2024,2025 by Thomas E. Dickey
 *
 *                         All Rights Reserved
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name(s) of the above copyright
 * holders shall not be used in advertising or otherwise to promote the
 * sale, use or other dealings in this Software without prior written
 * authorization.
 *
 *
 * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 *
 *                         All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of Digital Equipment
 * Corporation not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.
 *
 *
 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

/* screen.c */

#include 
#include 
#include 
#include 
#include 

#include 

#if OPT_WIDE_ATTRS || OPT_WIDE_CHARS
#include 
#endif

#include 

#include 
#include 

#include 

#define inSaveBuf(screen, buf, inx) \
	((buf) == (screen)->saveBuf_index && \
	 ((inx) < (screen)->savelines || (screen)->savelines == 0))

#define getMinRow(screen) ((xw->flags & ORIGIN) ? (screen)->top_marg : 0)
#define getMaxRow(screen) ((xw->flags & ORIGIN) ? (screen)->bot_marg : (screen)->max_row)
#define getMinCol(screen) ((xw->flags & ORIGIN) ? (screen)->lft_marg : 0)
#define getMaxCol(screen) ((xw->flags & ORIGIN) ? (screen)->rgt_marg : (screen)->max_col)

#define MoveLineData(base, dst, src, len) \
	memmove(scrnHeadAddr(screen, base, (unsigned) (dst)), \
		scrnHeadAddr(screen, base, (unsigned) (src)), \
		(size_t) scrnHeadSize(screen, (unsigned) (len)))

#define SaveLineData(base, src, len) \
	(void) ScrnPointers(screen, len); \
	memcpy (screen->save_ptr, \
		scrnHeadAddr(screen, base, src), \
		(size_t) scrnHeadSize(screen, (unsigned) (len)))

#define RestoreLineData(base, dst, len) \
	memcpy (scrnHeadAddr(screen, base, dst), \
		screen->save_ptr, \
		(size_t) scrnHeadSize(screen, (unsigned) (len)))

#define VisBuf(screen) screen->editBuf_index[screen->whichBuf]

/*
 * ScrnPtr's can point to different types of data.
 */
#define SizeofScrnPtr(name) \
	(unsigned) sizeof(*((LineData *)0)->name)

/*
 * The pointers in LineData point into a block of text allocated as a single
 * chunk for the given number of rows.  Ensure that these pointers are aligned
 * at least to int-boundaries.
 */
#define AlignMask()      (sizeof(int) - 1)
#define IsAligned(value) (((unsigned long) (value) & AlignMask()) == 0)

#define AlignValue(value) \
		if (!IsAligned(value)) \
		    value = (value | (unsigned) AlignMask()) + 1

#define SetupScrnPtr(dst,src,type) \
		dst = (type *) (void *) src; \
		assert(IsAligned(dst)); \
		src += skipNcol##type

#define ScrnBufAddr(ptrs, offset)  (ScrnBuf)    ((void *) ((char *) (ptrs) + (offset)))
#define LineDataAddr(ptrs, offset) (LineData *) ((void *) ((char *) (ptrs) + (offset)))

#if OPT_TRACE > 1
static void
traceScrnBuf(const char *tag, TScreen *screen, ScrnBuf sb, unsigned len)
{
    unsigned j;

    TRACE(("traceScrnBuf %s\n", tag));
    for (j = 0; j < len; ++j) {
	LineData *src = (LineData *) scrnHeadAddr(screen, sb, j);
	TRACE(("%p %s%3d:%s\n",
	       src, ((int) j >= screen->savelines) ? "*" : " ",
	       j, visibleIChars(src->charData, src->lineSize)));
    }
    TRACE(("...traceScrnBuf %s\n", tag));
}

#define TRACE_SCRNBUF(tag, screen, sb, len) traceScrnBuf(tag, screen, sb, len)
#else
#define TRACE_SCRNBUF(tag, screen, sb, len)	/*nothing */
#endif

#if OPT_WIDE_CHARS
#define scrnHeadSize(screen, count) \
	(unsigned) ((count) * \
		    (SizeOfLineData + \
		     ((screen)->wide_chars \
		      ? (unsigned) (screen)->lineExtra \
		      : 0)))
#else
#define scrnHeadSize(screen, count) \
	(unsigned) ((count) * \
		    SizeOfLineData)
#endif

ScrnBuf
scrnHeadAddr(TScreen *screen, ScrnBuf base, unsigned offset)
{
    unsigned size = scrnHeadSize(screen, offset);
    ScrnBuf result = ScrnBufAddr(base, size);

    (void) screen;
    assert((int) offset >= 0);

    return result;
}

/*
 * Given a block of data, build index to it in the 'base' parameter.
 */
void
setupLineData(TScreen *screen,
	      ScrnBuf base,
	      Char *data,
	      unsigned nrow,
	      unsigned ncol,
	      Bool bottom)
{
    unsigned i;
    unsigned offset = 0;
    unsigned jump = scrnHeadSize(screen, 1);
    LineData *ptr;
#if OPT_WIDE_CHARS
    unsigned j;
#endif
    /* these names are based on types */
    unsigned skipNcolIAttr;
    unsigned skipNcolCharData;
#if OPT_DEC_RECTOPS
    unsigned skipNcolChar;
#endif
#if OPT_ISO_COLORS
    unsigned skipNcolCellColor;
#endif

    (void) screen;
    AlignValue(ncol);

    (void) bottom;
#if OPT_STATUS_LINE
    if (bottom) {
	AddStatusLineRows(nrow);
    }
#endif

    /* *INDENT-EQLS* */
    skipNcolIAttr     = (ncol * SizeofScrnPtr(attribs));
    skipNcolCharData  = (ncol * SizeofScrnPtr(charData));
#if OPT_DEC_RECTOPS
    skipNcolChar      = (ncol * SizeofScrnPtr(charSeen));	/* = charSets */
#endif
#if OPT_ISO_COLORS
    skipNcolCellColor = (ncol * SizeofScrnPtr(color));
#endif

    for (i = 0; i < nrow; i++, offset += jump) {
	ptr = LineDataAddr(base, offset);

	ptr->lineSize = (Dimension) ncol;
	ptr->bufHead = 0;
#if OPT_DEC_CHRSET
	SetLineDblCS(ptr, 0);
#endif
	SetupScrnPtr(ptr->attribs, data, IAttr);
#if OPT_ISO_COLORS
	SetupScrnPtr(ptr->color, data, CellColor);
#endif
	SetupScrnPtr(ptr->charData, data, CharData);
#if OPT_DEC_RECTOPS
	SetupScrnPtr(ptr->charSeen, data, Char);
	SetupScrnPtr(ptr->charSets, data, Char);
#endif
#if OPT_WIDE_CHARS
	if (screen->wide_chars) {
	    unsigned extra = (unsigned) screen->max_combining;

	    ptr->combSize = (Char) extra;
	    for (j = 0; j < extra; ++j) {
		SetupScrnPtr(ptr->combData[j], data, CharData);
	    }
	}
#endif
    }
}

#define ExtractScrnData(name) \
		memcpy(dstPtrs->name, \
		       ((LineData *) srcPtrs)->name,\
		       dstCols * sizeof(dstPtrs->name[0]))

/*
 * As part of reallocating the screen buffer when resizing, extract from
 * the old copy of the screen buffer the data which will be used in the
 * new copy of the screen buffer.
 */
static void
extractScrnData(TScreen *screen,
		ScrnBuf dstPtrs,
		ScrnBuf srcPtrs,
		unsigned nrows,
		unsigned move_down)
{
    unsigned j;

    TRACE(("extractScrnData(nrows %d)\n", nrows));

    TRACE_SCRNBUF("extract from", screen, srcPtrs, nrows);
    for (j = 0; j < nrows; j++) {
	LineData *dst = (LineData *) scrnHeadAddr(screen,
						  dstPtrs, j + move_down);
	LineData *src = (LineData *) scrnHeadAddr(screen,
						  srcPtrs, j);
	copyLineData(dst, src);
    }
}

static ScrnPtr *
allocScrnHead(TScreen *screen, unsigned nrow)
{
    ScrnPtr *result;
    unsigned size = scrnHeadSize(screen, 1);

    (void) screen;
    AddStatusLineRows(nrow);
    result = (ScrnPtr *) calloc((size_t) nrow, (size_t) size);
    if (result == NULL)
	SysError(ERROR_SCALLOC);

    TRACE(("allocScrnHead %d -> %d -> %p..%p\n", nrow, nrow * size,
	   (void *) result,
	   (char *) result + (nrow * size) - 1));
    return result;
}

/*
 * Return the size of a line's data.
 */
static unsigned
sizeofScrnRow(TScreen *screen, unsigned ncol)
{
    unsigned result;
    unsigned sizeAttribs;
#if OPT_ISO_COLORS
    unsigned sizeColors;
#endif

    (void) screen;

    result = (ncol * (unsigned) sizeof(CharData));	/* ->charData */
    AlignValue(result);

#if OPT_DEC_RECTOPS
    result += (ncol * (unsigned) sizeof(Char));		/* ->charSeen */
    AlignValue(result);
    result += (ncol * (unsigned) sizeof(Char));		/* ->charSets */
    AlignValue(result);
#endif

#if OPT_WIDE_CHARS
    if (screen->wide_chars) {
	result *= (unsigned) (1 + screen->max_combining);
    }
#endif

    sizeAttribs = (ncol * SizeofScrnPtr(attribs));
    AlignValue(sizeAttribs);
    result += sizeAttribs;

#if OPT_ISO_COLORS
    sizeColors = (ncol * SizeofScrnPtr(color));
    AlignValue(sizeColors);
    result += sizeColors;
#endif

    return result;
}

Char *
allocScrnData(TScreen *screen, unsigned nrow, unsigned ncol, Bool bottom)
{
    Char *result = NULL;
    size_t length;

    AlignValue(ncol);
    if (bottom) {
	AddStatusLineRows(nrow);
    }
    length = (nrow * sizeofScrnRow(screen, ncol));
    if (length == 0
	|| (result = (Char *) calloc(length, sizeof(Char))) == NULL)
	  SysError(ERROR_SCALLOC2);

    TRACE(("allocScrnData %ux%u -> %lu -> %p..%p\n",
	   nrow, ncol, (unsigned long) length, result, result + length - 1));
    return result;
}

/*
 * Allocates memory for a 2-dimensional array of chars and returns a pointer
 * thereto.  Each line is formed from a set of char arrays, with an index
 * (i.e., the ScrnBuf type).  The first pointer in the index is reserved for
 * per-line flags, and does not point to data.
 *
 * After the per-line flags, we have a series of pointers to char arrays:  The
 * first one is the actual character array, the second one is the attributes,
 * the third is the foreground and background colors, and the fourth denotes
 * the character set.
 *
 * We store it all as pointers, because of alignment considerations.
 */
ScrnBuf
allocScrnBuf(XtermWidget xw, unsigned nrow, unsigned ncol, Char **addr)
{
    TScreen *screen = TScreenOf(xw);
    ScrnBuf base = NULL;

    if (nrow != 0) {
	base = allocScrnHead(screen, nrow);
	*addr = allocScrnData(screen, nrow, ncol, True);

	setupLineData(screen, base, *addr, nrow, ncol, True);
    }

    TRACE(("allocScrnBuf %dx%d ->%p\n", nrow, ncol, (void *) base));
    return (base);
}

/*
 * Copy line-data from the visible (edit) buffer to the save-lines buffer.
 */
static void
saveEditBufLines(TScreen *screen, unsigned n)
{
    unsigned j;

    TRACE(("...copying %d lines from editBuf to saveBuf\n", n));

    for (j = 0; j < n; ++j) {

	LineData *dst = addScrollback(screen);

	LineData *src = getLineData(screen, (int) j);
	copyLineData(dst, src);
    }
}

/*
 * Copy line-data from the save-lines buffer to the visible (edit) buffer.
 */
static void
unsaveEditBufLines(TScreen *screen, ScrnBuf sb, unsigned n)
{
    unsigned j;

    TRACE(("...copying %d lines from saveBuf to editBuf\n", n));
    for (j = 0; j < n; ++j) {
	int extra = (int) (n - j);
	LineData *dst = (LineData *) scrnHeadAddr(screen, sb, j);

	CLineData *src;

	if (extra > screen->saved_fifo || extra > screen->savelines) {
	    TRACE(("...FIXME: must clear text!\n"));
	    continue;
	}
	src = getScrollback(screen, -extra);

	copyLineData(dst, src);
    }
}

/*
 *  This is called when the screen is resized.
 *  Returns the number of lines the text was moved down (neg for up).
 *  (Return value only necessary with SouthWestGravity.)
 */
static int
Reallocate(XtermWidget xw,
	   ScrnBuf *sbuf,
	   Char **sbufaddr,
	   unsigned nrow,
	   unsigned ncol,
	   unsigned oldrow)
{
    TScreen *screen = TScreenOf(xw);
    ScrnBuf oldBufHead;
    ScrnBuf newBufHead;
    Char *newBufData;
    unsigned minrows;
    Char *oldBufData;
    int move_down = 0, move_up = 0;

    if (sbuf == NULL || *sbuf == NULL) {
	return 0;
    }

    oldBufData = *sbufaddr;

    TRACE(("Reallocate %dx%d -> %dx%d\n", oldrow, MaxCols(screen), nrow, ncol));

    /*
     * realloc sbuf, the pointers to all the lines.
     * If the screen shrinks, remove lines off the top of the buffer
     * if resizeGravity resource says to do so.
     */
    TRACE(("Check move_up, nrow %d vs oldrow %d (resizeGravity %s)\n",
	   nrow, oldrow,
	   BtoS(GravityIsSouthWest(xw))));
    if (GravityIsSouthWest(xw)) {
	if (nrow < oldrow) {
	    /* Remove lines off the top of the buffer if necessary. */
	    move_up = (int) (oldrow - nrow)
		- (TScreenOf(xw)->max_row - TScreenOf(xw)->cur_row);
	    if (move_up < 0)
		move_up = 0;
	    /* Overlapping move here! */
	    TRACE(("move_up %d\n", move_up));
	    if (move_up) {
		ScrnBuf dst = *sbuf;
		unsigned len = (unsigned) ((int) oldrow - move_up);

		TRACE_SCRNBUF("before move_up", screen, dst, oldrow);
		SaveLineData(dst, 0, (size_t) move_up);
		MoveLineData(dst, 0, (size_t) move_up, len);
		RestoreLineData(dst, len, (size_t) move_up);
		TRACE_SCRNBUF("after move_up", screen, dst, oldrow);
	    }
	}
    }
    oldBufHead = *sbuf;
    *sbuf = allocScrnHead(screen, (unsigned) nrow);
    newBufHead = *sbuf;

    /*
     * Create the new buffer space and copy old buffer contents there, line by
     * line.
     */
    newBufData = allocScrnData(screen, nrow, ncol, True);
    *sbufaddr = newBufData;

    minrows = (oldrow < nrow) ? oldrow : nrow;
    if (GravityIsSouthWest(xw)) {
	if (nrow > oldrow) {
	    /* move data down to bottom of expanded screen */
	    move_down = Min((int) (nrow - oldrow), TScreenOf(xw)->savedlines);
	}
    }

    setupLineData(screen, newBufHead, *sbufaddr, nrow, ncol, True);
    extractScrnData(screen, newBufHead, oldBufHead, minrows, 0);

    /* Now free the old data */
    free(oldBufData);
    free(oldBufHead);

    TRACE(("...Reallocate %dx%d ->%p\n", nrow, ncol, (void *) newBufHead));
    return move_down ? move_down : -move_up;	/* convert to rows */
}

#if OPT_WIDE_CHARS
/*
 * This function reallocates memory if changing the number of Buf offsets.
 * The code is based on Reallocate().
 */
static void
ReallocateBufOffsets(XtermWidget xw,
		     ScrnBuf *sbuf,
		     Char **sbufaddr,
		     unsigned nrow,
		     unsigned ncol)
{
    TScreen *screen = TScreenOf(xw);
    unsigned i;
    ScrnBuf newBufHead;
    Char *oldBufData;
    ScrnBuf oldBufHead;

    unsigned old_jump = scrnHeadSize(screen, 1);
    unsigned new_jump;
    unsigned dstCols = ncol;
    LineData *dstPtrs;
    LineData *srcPtrs;

    assert(nrow != 0);
    assert(ncol != 0);

    oldBufData = *sbufaddr;
    oldBufHead = *sbuf;

    /*
     * Allocate a new LineData array, retain the old one until we've copied
     * the data that it points to, as well as non-pointer data, e.g., bufHead.
     *
     * Turn on wide-chars temporarily when constructing pointers, since that is
     * used to decide whether to address the combData[] array, which affects
     * the length of the LineData structure.
     */
    screen->wide_chars = True;

    new_jump = scrnHeadSize(screen, 1);
    newBufHead = allocScrnHead(screen, nrow);
    *sbufaddr = allocScrnData(screen, nrow, ncol, True);
    setupLineData(screen, newBufHead, *sbufaddr, nrow, ncol, True);

    screen->wide_chars = False;

    srcPtrs = (LineData *) oldBufHead;
    dstPtrs = (LineData *) newBufHead;
    for (i = 0; i < nrow; i++) {
	dstPtrs->bufHead = srcPtrs->bufHead;
	ExtractScrnData(attribs);
#if OPT_ISO_COLORS
	ExtractScrnData(color);
#endif
	ExtractScrnData(charData);

	srcPtrs = LineDataAddr(srcPtrs, old_jump);
	dstPtrs = LineDataAddr(dstPtrs, new_jump);
    }

    /* Now free the old data */
    free(oldBufData);
    free(oldBufHead);

    *sbuf = newBufHead;

    TRACE(("ReallocateBufOffsets %dx%d ->%p\n", nrow, ncol, *sbufaddr));
}

/*
 * Allocate a new FIFO index.
 */
static void
ReallocateFifoIndex(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    if (screen->savelines > 0 && screen->saveBuf_index != NULL) {
	ScrnBuf newBufHead;
	LineData *dstPtrs;
	LineData *srcPtrs;
	unsigned i;
	unsigned old_jump = scrnHeadSize(screen, 1);
	unsigned new_jump;

	screen->wide_chars = True;
	newBufHead = allocScrnHead(screen, (unsigned) screen->savelines);
	new_jump = scrnHeadSize(screen, 1);

	srcPtrs = (LineData *) screen->saveBuf_index;
	dstPtrs = (LineData *) newBufHead;

	for (i = 0; i < (unsigned) screen->savelines; ++i) {
	    memcpy(dstPtrs, srcPtrs, SizeOfLineData);
	    srcPtrs = LineDataAddr(srcPtrs, old_jump);
	    dstPtrs = LineDataAddr(dstPtrs, new_jump);
	}

	screen->wide_chars = False;
	free(screen->saveBuf_index);
	screen->saveBuf_index = newBufHead;
    }
}

/*
 * This function dynamically adds support for wide-characters.
 */
void
ChangeToWide(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    if (screen->wide_chars)
	return;

    TRACE(("ChangeToWide\n"));
    if (xtermLoadWideFonts(xw, True)) {
	int whichBuf = screen->whichBuf;

	/*
	 * If we're displaying the alternate screen, switch the pointers back
	 * temporarily so ReallocateBufOffsets() will operate on the proper
	 * data in the alternate buffer.
	 */
	if (screen->whichBuf)
	    SwitchBufPtrs(xw, 0);

	ReallocateFifoIndex(xw);

	if (screen->editBuf_index[0]) {
	    ReallocateBufOffsets(xw,
				 &screen->editBuf_index[0],
				 &screen->editBuf_data[0],
				 (unsigned) MaxRows(screen),
				 (unsigned) MaxCols(screen));
	}

	if (screen->editBuf_index[1]) {
	    ReallocateBufOffsets(xw,
				 &screen->editBuf_index[1],
				 &screen->editBuf_data[1],
				 (unsigned) MaxRows(screen),
				 (unsigned) MaxCols(screen));
	}

	screen->wide_chars = True;
	screen->visbuf = VisBuf(screen);

	/*
	 * Switch the pointers back before we start painting on the screen.
	 */
	if (whichBuf)
	    SwitchBufPtrs(xw, whichBuf);

	update_font_utf8_mode();
	SetVTFont(xw, screen->menu_font_number, True, NULL);
    }
    TRACE(("...ChangeToWide\n"));
}
#endif

/*
 * Copy cells, no side-effects.
 */
void
CopyCells(TScreen *screen, LineData *src, LineData *dst, int col, int len, Bool down)
{
    (void) screen;
    (void) down;

    if (len > 0) {
	int n;
	int last = col + len;
#if OPT_WIDE_CHARS
	int fix_l = -1;
	int fix_r = -1;
#endif

	/*
	 * If the copy overwrites a double-width character which has one half
	 * outside the margin, then we will replace both cells with blanks.
	 */
	if_OPT_WIDE_CHARS(screen, {
	    if (col > 0) {
		if (dst->charData[col] == HIDDEN_CHAR) {
		    if (down) {
			Clear2Cell(dst, src, col - 1);
			Clear2Cell(dst, src, col);
		    } else {
			if (src->charData[col] != HIDDEN_CHAR) {
			    Clear2Cell(dst, src, col - 1);
			    Clear2Cell(dst, src, col);
			} else {
			    fix_l = col - 1;
			}
		    }
		} else if (src->charData[col] == HIDDEN_CHAR) {
		    Clear2Cell(dst, src, col - 1);
		    Clear2Cell(dst, src, col);
		    ++col;
		}
	    }
	    if (last < (int) src->lineSize) {
		if (dst->charData[last] == HIDDEN_CHAR) {
		    if (down) {
			Clear2Cell(dst, src, last - 1);
			Clear2Cell(dst, src, last);
		    } else {
			if (src->charData[last] != HIDDEN_CHAR) {
			    Clear2Cell(dst, src, last);
			} else {
			    fix_r = last - 1;
			}
		    }
		} else if (src->charData[last] == HIDDEN_CHAR) {
		    last--;
		    Clear2Cell(dst, src, last);
		}
	    }
	});

	for (n = col; n < last; ++n) {
	    dst->charData[n] = src->charData[n];
	    dst->attribs[n] = src->attribs[n];
	}

	if_OPT_ISO_COLORS(screen, {
	    for (n = col; n < last; ++n) {
		dst->color[n] = src->color[n];
	    }
	});

	if_OPT_WIDE_CHARS(screen, {
	    size_t off;
	    for (n = col; n < last; ++n) {
		for_each_combData(off, src) {
		    dst->combData[off][n] = src->combData[off][n];
		}
	    }
	});

	if_OPT_WIDE_CHARS(screen, {
	    if (fix_l >= 0) {
		Clear2Cell(dst, src, fix_l);
		Clear2Cell(dst, src, fix_l + 1);
	    }
	    if (fix_r >= 0) {
		Clear2Cell(dst, src, fix_r);
		Clear2Cell(dst, src, fix_r + 1);
	    }
	});
    }
}

static void
FillIAttr(IAttr * target, unsigned source, size_t count)
{
    while (count-- != 0) {
	*target++ = (IAttr) source;
    }
}

/*
 * Clear cells, no side-effects.
 */
void
ClearCells(XtermWidget xw, int flags, unsigned len, int row, int col)
{
    if (len != 0) {
	TScreen *screen = TScreenOf(xw);
	LineData *ld;
	unsigned n;

	ld = getLineData(screen, row);

	if (((unsigned) col + len) > ld->lineSize)
	    len = (unsigned) (ld->lineSize - col);

	if_OPT_WIDE_CHARS(screen, {
	    if (((unsigned) col + len) < ld->lineSize &&
		ld->charData[col + (int) len] == HIDDEN_CHAR) {
		len++;
	    }
	    if (col > 0 &&
		ld->charData[col] == HIDDEN_CHAR) {
		len++;
		col--;
	    }
	});

	flags = (int) ((unsigned) flags | TERM_COLOR_FLAGS(xw));

	for (n = 0; n < len; ++n) {
	    if_OPT_DEC_RECTOPS(ld->charSeen[(unsigned) col + n] = ' ');
	    ld->charData[(unsigned) col + n] = (CharData) ' ';
	}

	FillIAttr(ld->attribs + col, (unsigned) flags, (size_t) len);

	if_OPT_ISO_COLORS(screen, {
	    CellColor p = xtermColorPair(xw);
	    for (n = 0; n < len; ++n) {
		ld->color[(unsigned) col + n] = p;
	    }
	});
	if_OPT_WIDE_CHARS(screen, {
	    size_t off;
	    for_each_combData(off, ld) {
		memset(ld->combData[off] + col, 0, (size_t) len * sizeof(CharData));
	    }
	});
    }
}

/*
 * Clear data in the screen-structure (no I/O).
 * Check for wide-character damage as well, clearing the damaged cells.
 */
void
ScrnClearCells(XtermWidget xw, int row, int col, unsigned len)
{
#if OPT_WIDE_CHARS
    TScreen *screen = TScreenOf(xw);
#endif
    int flags = 0;

    if_OPT_WIDE_CHARS(screen, {
	int kl;
	int kr;

	if (DamagedCells(screen, len, &kl, &kr, row, col)
	    && kr >= kl) {
	    ClearCells(xw, flags, (unsigned) (kr - kl + 1), row, kl);
	}
    });
    ClearCells(xw, flags, len, row, col);
}

/*
 * Disown the selection and repaint the area that is highlighted so it is no
 * longer highlighted.
 */
void
ScrnDisownSelection(XtermWidget xw)
{
    if (ScrnHaveSelection(TScreenOf(xw))) {
	TRACE(("ScrnDisownSelection\n"));
	if (TScreenOf(xw)->keepSelection) {
	    UnhiliteSelection(xw);
	} else {
	    DisownSelection(xw);
	}
    }
}

/*
 * Writes str into buf at screen's current row and column.  Characters are set
 * to match flags.
 */
void
ScrnWriteText(XtermWidget xw,
	      Cardinal offset,
	      Cardinal length,
	      unsigned flags,
	      CellColor cur_fg_bg)
{
    IChar *str = xw->work.write_text + offset;
    TScreen *screen = TScreenOf(xw);
    LineData *ld;
    IAttr *attrs;
    int avail = MaxCols(screen) - screen->cur_col;
    IChar *chars;
#if OPT_DEC_RECTOPS
    Char *seens;
#endif
#if OPT_WIDE_CHARS
    IChar starcol1;
#endif
    unsigned n;
    unsigned real_width = visual_width(str, length);

    (void) cur_fg_bg;		/* quiet compiler warnings when unused */

    if (real_width + (unsigned) screen->cur_col > (unsigned) MaxCols(screen)) {
	real_width = (unsigned) (MaxCols(screen) - screen->cur_col);
    }

    if (avail <= 0)
	return;
    if (length > (unsigned) avail)
	length = (unsigned) avail;
    if (length == 0 || real_width == 0)
	return;

    ld = getLineData(screen, screen->cur_row);

    if_OPT_DEC_RECTOPS(seens = ld->charSeen + screen->cur_col);
    chars = ld->charData + screen->cur_col;
    attrs = ld->attribs + screen->cur_col;

#if OPT_WIDE_CHARS
    starcol1 = *chars;
#endif

    /*
     * Copy the string onto the line,
     * writing blanks if we're writing invisible text.
     */
    for (n = 0; n < length; ++n) {
#if OPT_DEC_RECTOPS
	if (xw->work.write_sums != NULL) {
	    ld->charSeen[screen->cur_col + (int) n] = xw->work.buffer_sums[n];
	    ld->charSets[screen->cur_col + (int) n] = xw->work.buffer_sets[n];
	} else {
	    seens[n] = (str[n] < 32
#if OPT_WIDE_CHARS
			|| str[n] > 255
#endif
		)
		? ANSI_ESC
		: (Char) str[n];
	}
#endif /* OPT_DEC_RECTOPS */
	chars[n] = str[n];
    }

#if OPT_BLINK_TEXT
    if ((flags & BLINK) && !(screen->blink_as_bold)) {
	LineSetBlinked(ld);
    }
#endif

    if_OPT_WIDE_CHARS(screen, {

	if (real_width != length) {
	    IChar *char1 = chars;
	    if (screen->cur_col
		&& starcol1 == HIDDEN_CHAR
		&& isWide((int) char1[-1])) {
		char1[-1] = (CharData) ' ';
	    }
	    /* if we are overwriting the right hand half of a
	       wide character, make the other half vanish */
	    while (length) {
		int ch = (int) str[0];

		*char1++ = *str++;
		length--;

		if (isWide(ch)) {
		    *char1++ = (CharData) HIDDEN_CHAR;
		}
	    }

	    if (*char1 == HIDDEN_CHAR
		&& char1[-1] == HIDDEN_CHAR) {
		*char1 = (CharData) ' ';
	    }
	    /* if we are overwriting the left hand half of a
	       wide character, make the other half vanish */
	} else {
	    if (screen->cur_col
		&& starcol1 == HIDDEN_CHAR
		&& isWide((int) chars[-1])) {
		chars[-1] = (CharData) ' ';
	    }
	    /* if we are overwriting the right hand half of a
	       wide character, make the other half vanish */
	    if (chars[length] == HIDDEN_CHAR
		&& isWide((int) chars[length - 1])) {
		chars[length] = (CharData) ' ';
	    }
	}
    });

    flags &= ATTRIBUTES;
    flags |= CHARDRAWN;
    FillIAttr(attrs, flags, (size_t) real_width);

    if_OPT_WIDE_CHARS(screen, {
	size_t off;
	for_each_combData(off, ld) {
	    memset(ld->combData[off] + screen->cur_col,
		   0,
		   real_width * sizeof(CharData));
	}
    });
    if_OPT_ISO_COLORS(screen, {
	unsigned j;
	for (j = 0; j < real_width; ++j)
	    ld->color[screen->cur_col + (int) j] = cur_fg_bg;
    });

#if OPT_WIDE_CHARS
    screen->last_written_col = screen->cur_col + (int) real_width - 1;
    screen->last_written_row = screen->cur_row;
#endif

    chararea_clear_displayed_graphics(screen,
				      screen->cur_col,
				      screen->cur_row,
				      (int) real_width, 1);

    if_OPT_XMC_GLITCH(screen, {
	Resolve_XMC(xw);
    });

    return;
}

/*
 * Saves pointers to the n lines beginning at sb + where, and clears the lines
 */
static void
ScrnClearLines(XtermWidget xw, ScrnBuf sb, int where, unsigned n, unsigned size)
{
    TScreen *screen = TScreenOf(xw);
    ScrnPtr *base;
    unsigned jump = scrnHeadSize(screen, 1);
    unsigned i;
    LineData *work;
    unsigned flags = TERM_COLOR_FLAGS(xw);
#if OPT_ISO_COLORS
    unsigned j;
#endif

    TRACE(("ScrnClearLines(%s:where %d, n %d, size %d)\n",
	   (sb == screen->saveBuf_index) ? "save" : "edit",
	   where, n, size));

    assert((int) n > 0);
    assert(size != 0);

    /* save n lines at where */
    SaveLineData(sb, (unsigned) where, (size_t) n);

    /* clear contents of old rows */
    base = screen->save_ptr;
    for (i = 0; i < n; ++i) {
	work = (LineData *) base;
	work->bufHead = 0;
#if OPT_DEC_CHRSET
	SetLineDblCS(work, 0);
#endif

	memset(work->charData, 0, size * sizeof(CharData));
	if (TERM_COLOR_FLAGS(xw)) {
	    FillIAttr(work->attribs, flags, (size_t) size);
#if OPT_ISO_COLORS
	    {
		CellColor p = xtermColorPair(xw);
		for (j = 0; j < size; ++j) {
		    work->color[j] = p;
		}
	    }
#endif
	} else {
	    FillIAttr(work->attribs, 0, (size_t) size);
#if OPT_ISO_COLORS
	    memset(work->color, 0, size * sizeof(work->color[0]));
#endif
	}
	if_OPT_DEC_RECTOPS({
	    memset(work->charSeen, 0, size * sizeof(Char));
	    memset(work->charSets, 0, size * sizeof(work->charSets[0]));
	});
#if OPT_WIDE_CHARS
	if (screen->wide_chars) {
	    size_t off;

	    for (off = 0; off < work->combSize; ++off) {
		memset(work->combData[off], 0, size * sizeof(CharData));
	    }
	}
#endif
	base = ScrnBufAddr(base, jump);
    }

    /* FIXME: this looks wrong -- rcombs */
    chararea_clear_displayed_graphics(screen,
				      where + screen->savelines,
				      0,
				      screen->max_col + 1,
				      (int) n);
}

/*
 * We're always ensured of having a visible buffer, but may not have saved
 * lines.  Check the pointer that's sure to work.
 */

#define OkAllocBuf(screen) (screen->editBuf_index[0] != NULL)

void
ScrnAllocBuf(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);

    if (!OkAllocBuf(screen)) {
	int nrows = MaxRows(screen);

	TRACE(("ScrnAllocBuf %dx%d (%d)\n",
	       nrows, MaxCols(screen), screen->savelines));

	if (screen->savelines != 0) {
	    /* for FIFO, we only need space for the index - addScrollback inits */
	    screen->saveBuf_index = allocScrnHead(screen,
						  (unsigned) (screen->savelines));
	} else {
	    screen->saveBuf_index = NULL;
	}
	screen->editBuf_index[0] = allocScrnBuf(xw,
						(unsigned) nrows,
						(unsigned) MaxCols(screen),
						&screen->editBuf_data[0]);
	screen->visbuf = VisBuf(screen);
    }
    return;
}

size_t
ScrnPointers(TScreen *screen, size_t len)
{
    size_t result = scrnHeadSize(screen, (unsigned) len);

    if (result > screen->save_len) {
	if (screen->save_len)
	    screen->save_ptr = (ScrnPtr *) realloc(screen->save_ptr, result);
	else
	    screen->save_ptr = (ScrnPtr *) malloc(result);
	screen->save_len = len;
	if (screen->save_ptr == NULL)
	    SysError(ERROR_SAVE_PTR);
    }
    TRACE2(("ScrnPointers %ld ->%p\n", (long) len, screen->save_ptr));
    return result;
}

/*
 * Inserts n blank lines at sb + where, treating last as a bottom margin.
 */
void
ScrnInsertLine(XtermWidget xw, ScrnBuf sb, int last, int where, unsigned n)
{
    TScreen *screen = TScreenOf(xw);
    unsigned size = (unsigned) MaxCols(screen);

    TRACE(("ScrnInsertLine(last %d, where %d, n %d, size %d)\n",
	   last, where, n, size));

    assert(where >= 0);
    assert(last >= where);

    assert((int) n > 0);
    assert(size != 0);

    /* save n lines at bottom */
    ScrnClearLines(xw, sb, (last -= (int) n - 1), n, size);
    if (last < 0) {
	TRACE(("...remainder of screen is blank\n"));
	return;
    }

    /*
     * WARNING, overlapping copy operation.  Move down lines (pointers).
     *
     *   +----|---------|--------+
     *
     * is copied in the array to:
     *
     *   +--------|---------|----+
     */
    assert(last >= where);
    /*
     * This will never shift from the saveBuf to editBuf, so there is no need
     * to handle that case.
     */
    MoveLineData(sb,
		 (unsigned) (where + (int) n),
		 (unsigned) where,
		 (unsigned) (last - where));

    /* reuse storage for new lines at where */
    RestoreLineData(sb, (unsigned) where, n);
}

/*
 * Deletes n lines at sb + where, treating last as a bottom margin.
 */
void
ScrnDeleteLine(XtermWidget xw, ScrnBuf sb, int last, int where, unsigned n)
{
    TScreen *screen = TScreenOf(xw);
    unsigned size = (unsigned) MaxCols(screen);

    TRACE(("ScrnDeleteLine(%s:last %d, where %d, n %d, size %d)\n",
	   (sb == screen->saveBuf_index) ? "save" : "edit",
	   last, where, n, size));

    assert(where >= 0);
    assert(last >= where + (int) n - 1);

    assert((int) n > 0);
    assert(size != 0);

    /* move up lines */
    last -= ((int) n - 1);

    if (inSaveBuf(screen, sb, where)) {

	/* we shouldn't be editing the saveBuf, only scroll into it */
	assert(last >= screen->savelines);

	if (sb != NULL) {
	    /* copy lines from editBuf to saveBuf (allocating as we go...) */
	    saveEditBufLines(screen, n);
	}

	/* adjust variables to fall-thru into changes only to editBuf */
	TRACE(("...adjusting variables, to work on editBuf alone\n"));
	last -= screen->savelines;
	where = 0;
	sb = screen->visbuf;
    }

    /*
     * Scroll the visible buffer (editBuf).
     */
    ScrnClearLines(xw, sb, where, n, size);

    MoveLineData(sb,
		 (unsigned) where,
		 (unsigned) (where + (int) n),
		 (size_t) (last - where));

    /* reuse storage for new bottom lines */
    RestoreLineData(sb, (unsigned) last, n);
}

/*
 * Inserts n blanks in screen at current row, col.  Size is the size of each
 * row.
 */
void
ScrnInsertChar(XtermWidget xw, unsigned n)
{
#define MemMove(data) \
    	for (j = last; j >= (col + (int) n); --j) \
	    data[j] = data[j - (int) n]

    TScreen *screen = TScreenOf(xw);
    int first = ScrnLeftMargin(xw);
    int last = ScrnRightMargin(xw);
    int row = screen->cur_row;
    int col = screen->cur_col;
    LineData *ld;

    if (col < first || col > last) {
	TRACE(("ScrnInsertChar - col %d outside [%d..%d]\n", col, first, last));
	return;
    } else if (last < (col + (int) n)) {
	n = (unsigned) (last + 1 - col);
    }

    assert(screen->cur_col >= 0);
    assert(screen->cur_row >= 0);
    assert((int) n >= 0);
    assert((last + 1) >= (int) n);

    if_OPT_WIDE_CHARS(screen, {
	int xx = screen->cur_row;
	int kl;
	int kr = screen->cur_col;
	if (DamagedCells(screen, n, &kl, (int *) 0, xx, kr) && kr > kl) {
	    ClearCells(xw, 0, (unsigned) (kr - kl + 1), row, kl);
	}
	kr = last - (int) n + 1;
	if (DamagedCells(screen, n, &kl, (int *) 0, xx, kr) && kr > kl) {
	    ClearCells(xw, 0, (unsigned) (kr - kl + 1), row, kl);
	}
    });

    if ((ld = getLineData(screen, row)) != NULL) {
	int j;

	MemMove(ld->charData);
	MemMove(ld->attribs);

	if_OPT_ISO_COLORS(screen, {
	    MemMove(ld->color);
	});
	if_OPT_WIDE_CHARS(screen, {
	    size_t off;
	    for_each_combData(off, ld) {
		MemMove(ld->combData[off]);
	    }
	});
    }
    ClearCells(xw, CHARDRAWN, n, row, col);

#undef MemMove
}

/*
 * Deletes n characters at current row, col.
 */
void
ScrnDeleteChar(XtermWidget xw, unsigned n)
{
#define MemMove(data) \
    	for (j = col; j < last - (int) n; ++j) \
	    data[j] = data[j + (int) n]

    TScreen *screen = TScreenOf(xw);
    int first = ScrnLeftMargin(xw);
    int last = ScrnRightMargin(xw) + 1;
    int row = screen->cur_row;
    int col = screen->cur_col;
    LineData *ld;

    if (col < first || col > last) {
	TRACE(("ScrnDeleteChar - col %d outside [%d..%d]\n", col, first, last));
	return;
    } else if (last <= (col + (int) n)) {
	n = (unsigned) (last - col);
    }

    assert(screen->cur_col >= 0);
    assert(screen->cur_row >= 0);
    assert((int) n >= 0);
    assert(last >= (int) n);

    if_OPT_WIDE_CHARS(screen, {
	int kl;
	int kr;
	if (DamagedCells(screen, n, &kl, &kr,
			 screen->cur_row,
			 screen->cur_col))
	    ClearCells(xw, 0, (unsigned) (kr - kl + 1), row, kl);
    });

    if ((ld = getLineData(screen, row)) != NULL) {
	int j;

	MemMove(ld->charData);
	MemMove(ld->attribs);

	if_OPT_ISO_COLORS(screen, {
	    MemMove(ld->color);
	});
	if_OPT_WIDE_CHARS(screen, {
	    size_t off;
	    for_each_combData(off, ld) {
		MemMove(ld->combData[off]);
	    }
	});
	LineClrWrapped(ld);
	ShowWrapMarks(xw, row, ld);
    }
    ClearCells(xw, 0, n, row, (last - (int) n));

#undef MemMove
}

#define WhichMarkGC(set) (set ? 1 : 0)
#define WhichMarkColor(set) T_COLOR(screen, (set ? TEXT_CURSOR : TEXT_BG))

void
FreeMarkGCs(XtermWidget xw)
{
    TScreen *const screen = TScreenOf(xw);
    Display *const display = screen->display;
    VTwin *vwin = WhichVWin(screen);
    int which;

    for (which = 0; which < 2; ++which) {
	if (vwin->marker_gc[which] != NULL) {
	    XFreeGC(display, vwin->marker_gc[which]);
	    vwin->marker_gc[which] = NULL;
	}
    }
}

static GC
MakeMarkGC(XtermWidget xw, Bool set)
{
    TScreen *const screen = TScreenOf(xw);
    VTwin *vwin = WhichVWin(screen);
    int which = WhichMarkGC(set);

    if (vwin->marker_gc[which] == NULL) {
	Display *const display = screen->display;
	Window const drawable = VDrawable(screen);
	XGCValues xgcv;
	XtGCMask mask = GCForeground;

	memset(&xgcv, 0, sizeof(xgcv));
	xgcv.foreground = WhichMarkColor(set);
	vwin->marker_gc[which] = XCreateGC(display,
					   drawable,
					   mask,
					   &xgcv);
    }
    return vwin->marker_gc[which];
}

/*
 * This is useful for debugging both xterm and applications that may manipulate
 * its line-wrapping state.
 */
void
ShowWrapMarks(XtermWidget xw, int row, CLineData *ld)
{
    TScreen *screen = TScreenOf(xw);
    if (screen->show_wrap_marks && row >= 0 && row <= screen->max_row) {
	Bool set = (Bool) LineTstWrapped(ld);
	int y = row * FontHeight(screen) + screen->border;
	int x = LineCursorX(screen, ld, screen->max_col + 1);

	TRACE2(("ShowWrapMarks %d:%s\n", row, BtoS(set)));

	XFillRectangle(screen->display,
		       VDrawable(screen),
		       MakeMarkGC(xw, set),
		       x, y,
		       (unsigned) screen->border,
		       (unsigned) FontHeight(screen));
    }
}

#if OPT_BLOCK_SELECT
/*
 * Return the start and end cols of a block selection
 */
static void
blockSelectBounds(TScreen *screen,
		  int *start,
		  int *end)
{
    assert(screen->blockSelecting);
    if (screen->startH.col < screen->endH.col) {
	*start = screen->startH.col;
	*end = screen->endH.col;
    } else {
	*start = screen->endH.col;
	*end = screen->startH.col;
    }
}

/*
 * Return 1 if any part of [col, maxcol] intersects with the selection.
 */
static int
intersectsSelection(TScreen *screen,
		    int row,
		    int col,
		    int maxcol)
{
    if (screen->blockSelecting) {
	int start, end;
	blockSelectBounds(screen, &start, &end);
	return start != end
	    && (row >= screen->startH.row && row <= screen->endH.row)
	    && ((start >= col && start <= maxcol)
		|| (end > col && end < maxcol)) ? 1 : 0;
    }
    return !(row < screen->startH.row || row > screen->endH.row
	     || (row == screen->startH.row && maxcol < screen->startH.col)
	     || (row == screen->endH.row && col >= screen->endH.col)) ? 1 : 0;
}

/*
 * If there are any parts of [col, maxcol] not in the selection,
 * invoke ScrnRefresh on them, then adjust [col, maxcol] to be fully
 * inside the selection. The intent is to optimize the loop at the
 * end of ScrnRefresh, so that we are painting either all highlighted
 * or all unhighlighted cells.
 */
static void
recurseForNotSelectedAndAdjust(XtermWidget xw,
			       int row,
			       int *col,
			       int *maxcol,
			       int force)
{
    TScreen *screen = TScreenOf(xw);
    if (screen->blockSelecting) {
	int start, end;
	blockSelectBounds(screen, &start, &end);
	if (*col < start) {
	    ScrnRefresh(xw, row, *col, 1, start - *col, force);
	    *col = start;
	}
	if (*maxcol >= end) {
	    ScrnRefresh(xw, row, end, 1, *maxcol - end + 1, force);
	    *maxcol = end - 1;
	}
    } else {
	if (row == screen->startH.row && *col < screen->startH.col) {
	    ScrnRefresh(xw, row, *col, 1, screen->startH.col - *col,
			force);
	    *col = screen->startH.col;
	}
	if (row == screen->endH.row && *maxcol >= screen->endH.col) {
	    ScrnRefresh(xw, row, screen->endH.col, 1,
			*maxcol - screen->endH.col + 1, force);
	    *maxcol = screen->endH.col - 1;
	}
    }
}
#else
#define intersectsSelection(screen, row, col, maxcol) \
	((row >= screen->startH.row && row <= screen->endH.row) \
	 && (row != screen->startH.row || maxcol >= screen->startH.col) \
	 && (row != screen->endH.row || col < screen->endH.col))
#endif /* OPT_BLOCK_SELECT */

/*
 * Repaints the area enclosed by the parameters.
 * Requires: (toprow, leftcol), (toprow + nrows, leftcol + ncols) are
 *	     coordinates of characters in screen;
 *	     nrows and ncols positive.
 *	     all dimensions are based on single-characters.
 */
void
ScrnRefresh(XtermWidget xw,
	    int toprow,
	    int leftcol,
	    int nrows,
	    int ncols,
	    Bool force)		/* ... leading/trailing spaces */
{
    TScreen *screen = TScreenOf(xw);
    XTermDraw params;
    CLineData *ld;
    int y = toprow * FontHeight(screen) + screen->border;
    int row;
    int maxrow = toprow + nrows - 1;
    int scrollamt = screen->scroll_amt;
    unsigned gc_changes = 0;
#ifdef __CYGWIN__
    static char first_time = 1;
#endif
    static int recurse = 0;
#if OPT_WIDE_ATTRS
    unsigned old_attrs = xw->flags;
#endif

    TRACE(("ScrnRefresh top %d (%d,%d) - (%d,%d)%s " TRACE_L "\n",
	   screen->topline, toprow, leftcol,
	   nrows, ncols,
	   force ? " force" : ""));

#if OPT_STATUS_LINE
    if (!recurse && (maxrow == screen->max_row) && IsStatusShown(screen)) {
	TRACE(("...allow a row for status-line\n"));
	nrows += StatusLineRows;
	maxrow += StatusLineRows;
    }
#endif
    (void) recurse;
    ++recurse;

    if (screen->cursorp.col >= leftcol
	&& screen->cursorp.col <= (leftcol + ncols - 1)
	&& screen->cursorp.row >= ROW2INX(screen, toprow)
	&& screen->cursorp.row <= ROW2INX(screen, maxrow))
	screen->cursor_state = OFF;

    for (row = toprow; row <= maxrow; y += FontHeight(screen), row++) {
#if OPT_ISO_COLORS
	CellColor *fb = NULL;
#define ColorOf(col) (fb ? fb[col] : initCColor)
#endif
#if OPT_WIDE_CHARS
	int wideness = 0;
#endif
#define BLANK_CEL(cell) (chars[cell] == ' ')
	IChar *chars;
	const IAttr *attrs;
	int col = leftcol;
	int maxcol = leftcol + ncols - 1;
	int hi_col = maxcol;
	int lastind;
	unsigned flags;
	unsigned test;
	CellColor fg_bg = initCColor;
	Pixel fg = 0, bg = 0;
	int x;
	GC gc;
	Bool hilite;

	(void) fg;
	(void) bg;
#if !OPT_ISO_COLORS
	fg_bg = 0;
#endif

	if (row < screen->top_marg || row > screen->bot_marg)
	    lastind = row;
	else
	    lastind = row - scrollamt;

	if (lastind < 0 || lastind > LastRowNumber(screen))
	    continue;

	TRACE2(("ScrnRefresh row=%d lastind=%d ->%d\n",
		row, lastind, ROW2INX(screen, lastind)));

	if ((ld = getLineData(screen, ROW2INX(screen, lastind))) == NULL
	    || ld->charData == NULL
	    || ld->attribs == NULL) {
	    break;
	}

	ShowWrapMarks(xw, lastind, ld);

	if (maxcol >= (int) ld->lineSize) {
	    maxcol = ld->lineSize - 1;
	    hi_col = maxcol;
	}

	chars = ld->charData;
	attrs = ld->attribs;

	if_OPT_WIDE_CHARS(screen, {
	    /* This fixes an infinite recursion bug, that leads
	       to display anomalies. It seems to be related to
	       problems with the selection. */
	    if (recurse < 3) {
		/* adjust to redraw all of a widechar if we just wanted
		   to draw the right hand half */
		if (leftcol > 0 &&
		    chars[leftcol] == HIDDEN_CHAR &&
		    isWide((int) chars[leftcol - 1])) {
		    leftcol--;
		    ncols++;
		    col = leftcol;
		}
	    } else {
		xtermWarning("Unexpected recursion drawing hidden characters.\n");
	    }
	});

	if (!intersectsSelection(screen, row, col, maxcol)) {
#if OPT_DEC_CHRSET
	    /*
	     * Temporarily change dimensions to double-sized characters so
	     * we can reuse the recursion on this function.
	     */
	    if (CSET_DOUBLE(GetLineDblCS(ld))) {
		col /= 2;
		maxcol /= 2;
	    }
#endif
	    /*
	     * If row does not intersect selection; don't hilite blanks
	     * unless block selecting.
	     */
	    if (!force
#if OPT_BLOCK_SELECT
		&& !screen->blockSelecting
#endif
		) {
		while (col <= maxcol && (attrs[col] & ~BOLD) == 0 &&
		       BLANK_CEL(col))
		    col++;

		while (col <= maxcol && (attrs[maxcol] & ~BOLD) == 0 &&
		       BLANK_CEL(maxcol))
		    maxcol--;
	    }
#if OPT_DEC_CHRSET
	    if (CSET_DOUBLE(GetLineDblCS(ld))) {
		col *= 2;
		maxcol *= 2;
	    }
#endif
	    hilite = False;
	} else {
#if OPT_BLOCK_SELECT
	    /* row intersects selection; recurse for the unselected pieces
	     * of col to maxcol, then adjust col and maxcol so that they are
	     * strictly inside the selection.
	     */
	    recurseForNotSelectedAndAdjust(xw, row, &col, &maxcol, force);
#else
	    /* row intersects selection; split into pieces of single type */
	    if (row == screen->startH.row && col < screen->startH.col) {
		ScrnRefresh(xw, row, col, 1, screen->startH.col - col,
			    force);
		col = screen->startH.col;
	    }
	    if (row == screen->endH.row && maxcol >= screen->endH.col) {
		ScrnRefresh(xw, row, screen->endH.col, 1,
			    maxcol - screen->endH.col + 1, force);
		maxcol = screen->endH.col - 1;
	    }
#endif

	    /*
	     * If we're highlighting because the user is doing cut/paste,
	     * trim the trailing blanks from the highlighted region so we're
	     * showing the actual extent of the text that'll be cut.  If
	     * we're selecting a blank line, we'll highlight one column
	     * anyway.
	     *
	     * We don't do this if the mouse-hilite mode is set because that
	     * would be too confusing.  The same applies to block select mode.
	     *
	     * The default if the highlightSelection resource isn't set will
	     * highlight the whole width of the terminal, which is easy to
	     * see, but harder to use (because trailing blanks aren't as
	     * apparent).
	     */
	    if (screen->highlight_selection
#if OPT_BLOCK_SELECT
		&& !screen->blockSelecting
#endif
		&& screen->send_mouse_pos != VT200_HIGHLIGHT_MOUSE) {
		hi_col = screen->max_col;
		while (hi_col > 0 && !(attrs[hi_col] & CHARDRAWN))
		    hi_col--;
	    }

	    /* remaining piece should be hilited */
	    hilite = True;
	}

	if (col > maxcol)
	    continue;

	/*
	 * Go back to double-sized character dimensions if the line has
	 * double-width characters.  Note that 'hi_col' is already in the
	 * right units.
	 */
	if_OPT_DEC_CHRSET({
	    if (CSET_DOUBLE(GetLineDblCS(ld))) {
		col /= 2;
		maxcol /= 2;
	    }
	});

	flags = attrs[col];

	if_OPT_WIDE_CHARS(screen, {
	    wideness = isWide((int) chars[col]);
	});

	if_OPT_ISO_COLORS(screen, {
	    fb = ld->color;
	    fg_bg = ColorOf(col);
	    fg = extract_fg(xw, fg_bg, flags);
	    bg = extract_bg(xw, fg_bg, flags);
	});
#if OPT_WIDE_ATTRS
	old_attrs = xtermUpdateItalics(xw, flags, old_attrs);
#endif
	gc = updatedXtermGC(xw, flags, fg_bg, hilite);
	gc_changes |= (flags & (FG_COLOR | BG_COLOR));

	x = LineCursorX(screen, ld, col);
	lastind = col;

	for (; col <= maxcol; col++) {
	    if (
#if OPT_WIDE_CHARS
		   (chars[col] != HIDDEN_CHAR) &&
#endif
		   ((attrs[col] != flags)
		    || (hilite && (col > hi_col))
#if OPT_ISO_COLORS
		    || ((flags & FG_COLOR)
			&& (extract_fg(xw, ColorOf(col), attrs[col]) != fg))
		    || ((flags & BG_COLOR)
			&& (extract_bg(xw, ColorOf(col), attrs[col]) != bg))
#endif
#if OPT_WIDE_CHARS
		    || (isWide((int) chars[col]) != wideness)
#endif
		   )
		) {
		assert(col >= lastind);
		TRACE(("ScrnRefresh looping drawXtermText %d..%d:%s\n",
		       lastind, col,
		       visibleIChars((&chars[lastind]),
				     (unsigned) (col - lastind))));

		test = flags;
		checkVeryBoldColors(test, fg);

		/* *INDENT-EQLS* */
		params.xw          = xw;
		params.attr_flags  = (test & DRAWX_MASK);
		params.draw_flags  = 0;
		params.this_chrset = GetLineDblCS(ld);
		params.real_chrset = CSET_SWL;
		params.on_wide     = 0;

		x = drawXtermText(¶ms,
				  gc, x, y,
				  &chars[lastind],
				  (unsigned) (col - lastind));

		if_OPT_WIDE_CHARS(screen, {
		    int i;
		    size_t off;

		    params.draw_flags = NOBACKGROUND;

		    for_each_combData(off, ld) {
			IChar *com_off = ld->combData[off];

			for (i = lastind; i < col; i++) {
			    int my_x = LineCursorX(screen, ld, i);
			    IChar base = chars[i];

			    if ((params.on_wide = isWide((int) base)) != 0)
				my_x = LineCursorX(screen, ld, i - 1);

			    if (com_off[i] != 0)
				drawXtermText(¶ms,
					      gc, my_x, y,
					      com_off + i,
					      1);
			}
		    }
		});

		resetXtermGC(xw, flags, hilite);

		lastind = col;

		if (hilite && (col > hi_col))
		    hilite = False;

		flags = attrs[col];
		if_OPT_ISO_COLORS(screen, {
		    fg_bg = ColorOf(col);
		    fg = extract_fg(xw, fg_bg, flags);
		    bg = extract_bg(xw, fg_bg, flags);
		});
		if_OPT_WIDE_CHARS(screen, {
		    wideness = isWide((int) chars[col]);
		});

#if OPT_WIDE_ATTRS
		old_attrs = xtermUpdateItalics(xw, flags, old_attrs);
#endif
		gc = updatedXtermGC(xw, flags, fg_bg, hilite);
		gc_changes |= (flags & (FG_COLOR | BG_COLOR));
	    }

	    if (chars[col] == 0) {
		chars[col] = ' ';
	    }
	}

	assert(col >= lastind);
	TRACE(("ScrnRefresh calling drawXtermText %d..%d:%s\n",
	       lastind, col,
	       visibleIChars(&chars[lastind], (unsigned) (col - lastind))));

	test = flags;
	checkVeryBoldColors(test, fg);

	/* *INDENT-EQLS* */
	params.xw          = xw;
	params.attr_flags  = (test & DRAWX_MASK);
	params.draw_flags  = 0;
	params.this_chrset = GetLineDblCS(ld);
	params.real_chrset = CSET_SWL;
	params.on_wide     = 0;

	drawXtermText(¶ms,
		      gc, x, y,
		      &chars[lastind],
		      (unsigned) (col - lastind));

	if_OPT_WIDE_CHARS(screen, {
	    int i;
	    size_t off;

	    params.draw_flags = NOBACKGROUND;

	    for_each_combData(off, ld) {
		IChar *com_off = ld->combData[off];

		for (i = lastind; i < col; i++) {
		    int my_x = LineCursorX(screen, ld, i);
		    int base = (int) chars[i];

		    if ((params.on_wide = isWide(base)) != 0)
			my_x = LineCursorX(screen, ld, i - 1);

		    if (com_off[i] != 0)
			drawXtermText(¶ms,
				      gc, my_x, y,
				      com_off + i,
				      1);
		}
	    }
	});

	resetXtermGC(xw, flags, hilite);
    }

    refresh_displayed_graphics(xw, leftcol, toprow, ncols, nrows);

    /*
     * If we're in color mode, reset the various GC's to the current
     * screen foreground and background so that other functions (e.g.,
     * ClearRight) will get the correct colors.
     */
#if OPT_WIDE_ATTRS
    (void) xtermUpdateItalics(xw, xw->flags, old_attrs);
#endif
    if_OPT_ISO_COLORS(screen, {
	if (gc_changes & FG_COLOR)
	    SGR_Foreground(xw, xw->cur_foreground);
	if (gc_changes & BG_COLOR)
	    SGR_Background(xw, xw->cur_background);
    });
    (void) gc_changes;

#if defined(__CYGWIN__) && defined(TIOCSWINSZ)
    if (first_time == 1) {
	first_time = 0;
	update_winsize(screen, nrows, ncols, xw->core.height, xw->core.width);
    }
#endif
    recurse--;

    TRACE((TRACE_R " ScrnRefresh\n"));
    return;
}

/*
 * Call this wrapper to ScrnRefresh() when the data has changed.  If the
 * refresh region overlaps the selection, we will release the primary selection.
 */
void
ScrnUpdate(XtermWidget xw,
	   int toprow,
	   int leftcol,
	   int nrows,
	   int ncols,
	   Bool force)		/* ... leading/trailing spaces */
{
    TScreen *screen = TScreenOf(xw);

    if (ScrnHaveSelection(screen)
	&& (toprow <= screen->endH.row)
	&& (toprow + nrows - 1 >= screen->startH.row)) {
	ScrnDisownSelection(xw);
    }
    ScrnRefresh(xw, toprow, leftcol, nrows, ncols, force);
}

/*
 * Sets the rows first though last of the buffer of screen to spaces.
 * Requires first <= last; first, last are rows of screen->buf.
 */
void
ClearBufRows(XtermWidget xw,
	     int first,
	     int last)
{
    TScreen *screen = TScreenOf(xw);
    unsigned len = (unsigned) MaxCols(screen);
    int row;

    TRACE(("ClearBufRows %d..%d\n", first, last));
    for (row = first; row <= last; row++) {
	LineData *ld = getLineData(screen, row);
	if (ld != NULL) {
	    if_OPT_DEC_CHRSET({
		/* clearing the whole row resets the doublesize characters */
		SetLineDblCS(ld, CSET_SWL);
	    });
	    LineClrWrapped(ld);
	    ShowWrapMarks(xw, row, ld);
	    ClearCells(xw, 0, len, row, 0);
	}
    }
}

#if OPT_STATUS_LINE
static LineData *
freeLineData(TScreen *screen, LineData *source)
{
    (void) screen;
    if (source != NULL) {
	free(source->attribs);
	free(source->charData);
#if OPT_ISO_COLORS
	free(source->color);
#endif
#if OPT_WIDE_CHARS
	if_OPT_WIDE_CHARS(screen, {
	    size_t off;
	    for_each_combData(off, source) {
		free(source->combData[off]);
	    }
	});
#endif
	free(source);
	source = NULL;
    }
    return source;
}

#define ALLOC_IT(field) \
    if (result != NULL) { \
	if ((result->field = calloc((size_t) ncol, sizeof(*result->field))) == NULL) { \
	    result = freeLineData(screen, result); \
	} \
    }

/*
 * Allocate a temporary LineData structure, which is not part of the index.
 */
static LineData *
allocLineData(TScreen *screen, LineData *source)
{
    LineData *result = NULL;
    Dimension ncol = (Dimension) (source->lineSize + 1);
    size_t size = sizeof(*result);
#if OPT_WIDE_CHARS
    size += source->combSize * sizeof(result->combData[0]);
#endif
    if ((result = calloc((size_t) 1, size)) != NULL) {
	result->lineSize = ncol;
	ALLOC_IT(attribs);
#if OPT_ISO_COLORS
	ALLOC_IT(color);
#endif
#if OPT_DEC_RECTOPS
	ALLOC_IT(charSeen);
	ALLOC_IT(charData);
#endif
#if OPT_WIDE_CHARS
	ALLOC_IT(charSets);
	if_OPT_WIDE_CHARS(screen, {
	    size_t off;
	    for_each_combData(off, source) {
		ALLOC_IT(combData[off]);
	    }
	});
#endif
    }
    return result;
}

#undef ALLOC_IT
#endif /* OPT_STATUS_LINE */

/*
  Resizes screen:
  1. If new window would have fractional characters, sets window size so as to
  discard fractional characters and returns -1.
  Minimum screen size is 1 X 1.
  Note that this causes another ExposeWindow event.
  2. Enlarges screen->buf if necessary.  New space is appended to the bottom
  and to the right
  3. Reduces  screen->buf if necessary.  Old space is removed from the bottom
  and from the right
  4. Cursor is positioned as closely to its former position as possible
  5. Sets screen->max_row and screen->max_col to reflect new size
  6. Maintains the inner border (and clears the border on the screen).
  7. Clears origin mode and sets scrolling region to be entire screen.
  */
void
ScreenResize(XtermWidget xw,
	     int width,
	     int height,
	     unsigned *flags)
{
    TScreen *screen = TScreenOf(xw);
    int rows, cols;
    const int border = 2 * screen->border;
    int move_down_by = 0;
    Boolean forced = False;

#if OPT_STATUS_LINE
    LineData *savedStatus = NULL;
#endif

    TRACE(("ScreenResize %dx%d border 2*%d font %dx%d\n",
	   height, width, screen->border,
	   FontHeight(screen), FontWidth(screen)));

    assert(width > 0);
    assert(height > 0);

    TRACE(("...computing rows/cols: %.2f %.2f\n",
	   (double) (height - border) / FontHeight(screen),
	   (double) (width - border - ScrollbarWidth(screen)) / FontWidth(screen)));

    rows = (height - border) / FontHeight(screen);
    cols = (width - border - ScrollbarWidth(screen)) / FontWidth(screen);
    if (rows < 1)
	rows = 1;
    if (cols < 1)
	cols = 1;

#if OPT_STATUS_LINE
    /*
     * The dimensions passed to this function include the status-line.
     * Discount that here (to obtain the actual rows/columns), and save
     * the contents of the status-line, to repaint it after resizing.
     */
    TRACE(("...StatusShown %d/%d\n", IsStatusShown(screen), screen->status_shown));
    if (IsStatusShown(screen)) {
	int oldRow = MaxRows(screen);
	int newRow = rows - StatusLineRows;
	LineData *oldLD;
	TRACE(("...status line is currently on row %d(%d-%d) vs %d\n",
	       oldRow,
	       MaxRows(screen),
	       (screen->status_shown ? 0 : StatusLineRows),
	       rows));
	oldLD = getLineData(screen, oldRow);
	TRACE(("...copying:%s\n",
	       visibleIChars(oldLD->charData,
			     oldLD->lineSize)));
	TRACE(("...will move status-line from row %d to %d\n",
	       oldRow,
	       newRow));
	savedStatus = allocLineData(screen, oldLD);
	copyLineData(savedStatus, oldLD);
	TRACE(("...copied::%s\n",
	       visibleIChars(savedStatus->charData,
			     savedStatus->lineSize)));
	TRACE(("...discount a row for status-line\n"));
	rows = newRow;
	height -= FontHeight(screen) * StatusLineRows;
    }
#endif

    if (screen->is_running) {
	/* clear the right and bottom internal border because of NorthWest
	   gravity might have left junk on the right and bottom edges */
	if (width >= (int) FullWidth(screen)) {
	    xtermClear2(xw,
			FullWidth(screen), 0,	/* right edge */
			0, (unsigned) height);	/* from top to bottom */
	}
	if (height >= (int) FullHeight(screen)) {
	    xtermClear2(xw,
			0, FullHeight(screen),	/* bottom */
			(unsigned) width, 0);	/* all across the bottom */
	}
    }

    /* update buffers if the screen has changed size */
    if (forced) {
	;
    } else if (MaxRows(screen) != rows || MaxCols(screen) != cols) {
	int delta_rows = rows - MaxRows(screen);
#if OPT_TRACE
	int delta_cols = cols - MaxCols(screen);
#endif

	TRACE(("...ScreenResize chars %dx%d delta %dx%d\n",
	       rows, cols, delta_rows, delta_cols));

	if (screen->is_running) {
	    if (screen->cursor_state)
		HideCursor(xw);

	    /*
	     * The non-visible buffer is simple, since we will not copy data
	     * to/from the saved-lines.  Do that first.
	     */
	    if (screen->editBuf_index[!screen->whichBuf]) {
		(void) Reallocate(xw,
				  &screen->editBuf_index[!screen->whichBuf],
				  &screen->editBuf_data[!screen->whichBuf],
				  (unsigned) rows,
				  (unsigned) cols,
				  (unsigned) MaxRows(screen));
	    }

	    /*
	     * The save-lines buffer may change width, but will not change its
	     * height.  Deal with the cases where we copy data to/from the
	     * saved-lines buffer.
	     */
	    if (GravityIsSouthWest(xw)
		&& delta_rows
		&& screen->saveBuf_index != NULL) {

		if (delta_rows < 0) {
		    unsigned move_up = (unsigned) (-delta_rows);
		    int amount = ((MaxRows(screen) - (int) move_up - 1)
				  - screen->cur_row);

		    if (amount < 0) {
			/* move line-data from visible-buffer to save-buffer */
			saveEditBufLines(screen, (unsigned) -amount);
			move_down_by = amount;
		    } else {
			move_down_by = 0;
		    }

		    /* decrease size of visible-buffer */
		    (void) Reallocate(xw,
				      &screen->editBuf_index[screen->whichBuf],
				      &screen->editBuf_data[screen->whichBuf],
				      (unsigned) rows,
				      (unsigned) cols,
				      (unsigned) MaxRows(screen));
		    TRACE_SCRNBUF("reallocEDIT",
				  screen,
				  screen->editBuf_index[screen->whichBuf],
				  rows);
		} else {
		    unsigned move_down = (unsigned) delta_rows;
		    long unsave_fifo;
		    ScrnBuf dst;
		    int amount;

		    if ((int) move_down > screen->savedlines) {
			move_down = (unsigned) screen->savedlines;
		    }
		    move_down_by = (int) move_down;
		    amount = rows - (int) move_down;

		    /* increase size of visible-buffer */
		    (void) Reallocate(xw,
				      &screen->editBuf_index[screen->whichBuf],
				      &screen->editBuf_data[screen->whichBuf],
				      (unsigned) rows,
				      (unsigned) cols,
				      (unsigned) MaxRows(screen));

		    dst = screen->editBuf_index[screen->whichBuf];
		    TRACE_SCRNBUF("reallocEDIT", screen, dst, rows);

		    TRACE(("...%smoving pointers in editBuf (compare %d %d)\n",
			   (amount > 0
			    ? ""
			    : "SKIP "),
			   rows,
			   move_down));
		    if (amount > 0) {
			/* shift lines in visible-buffer to make room */
			SaveLineData(dst, (unsigned) amount, (size_t) move_down);

			MoveLineData(dst,
				     move_down,
				     0,
				     (unsigned) amount);

			TRACE(("...reuse %d lines storage in editBuf\n", move_down));
			RestoreLineData(dst,
					0,
					move_down);

			TRACE_SCRNBUF("shifted", screen, dst, rows);
		    }

		    /* copy line-data from save-buffer to visible-buffer */
		    unsaveEditBufLines(screen, dst, move_down);
		    TRACE_SCRNBUF("copied", screen, dst, rows);

		    unsave_fifo = (long) move_down;
		    if (screen->saved_fifo < (int) unsave_fifo)
			unsave_fifo = screen->saved_fifo;

		    /* free up storage in fifo from the copied lines */
		    while (unsave_fifo-- > 0) {
			deleteScrollback(screen);
		    }

		    /* recover storage in save-buffer */
		}
	    } else {
		(void) Reallocate(xw,
				  &screen->editBuf_index[screen->whichBuf],
				  &screen->editBuf_data[screen->whichBuf],
				  (unsigned) rows,
				  (unsigned) cols,
				  (unsigned) MaxRows(screen));
	    }

	    screen->visbuf = VisBuf(screen);
	}

	AdjustSavedCursor(xw, move_down_by);
	set_max_row(screen, screen->max_row + delta_rows);
	set_max_col(screen, cols - 1);

	if (screen->is_running) {
	    if (GravityIsSouthWest(xw)) {
		screen->savedlines -= move_down_by;
		if (screen->savedlines < 0)
		    screen->savedlines = 0;
		if (screen->savedlines > screen->savelines)
		    screen->savedlines = screen->savelines;
		if (screen->topline < -screen->savedlines)
		    screen->topline = -screen->savedlines;
		set_cur_row(screen, screen->cur_row + move_down_by);
		screen->cursorp.row += move_down_by;
		ScrollSelection(screen, move_down_by, True);
	    }
	}

	/* adjust scrolling region */
	resetMargins(xw);
	UIntClr(*flags, ORIGIN);

	if (screen->cur_row > screen->max_row)
	    set_cur_row(screen, screen->max_row);
	if (screen->cur_col > screen->max_col)
	    set_cur_col(screen, screen->max_col);

	screen->fullVwin.height = height - border;
	screen->fullVwin.width = width - border - screen->fullVwin.sb_info.width;

	scroll_displayed_graphics(xw, -move_down_by);
    } else if (FullHeight(screen) == height && FullWidth(screen) == width) {
#if OPT_STATUS_LINE
	if (savedStatus != NULL) {
	    TRACE(("...status line is currently saved!\n"));
	    freeLineData(screen, savedStatus);
	}
#endif
	return;			/* nothing has changed at all */
    }

    screen->fullVwin.fullheight = (Dimension) height;
    screen->fullVwin.fullwidth = (Dimension) width;

    ResizeScrollBar(xw);
    ResizeSelection(screen, rows, cols);

#ifndef NO_ACTIVE_ICON
    if (screen->iconVwin.window) {
	XWindowChanges changes;
	screen->iconVwin.width =
	    MaxCols(screen) * screen->iconVwin.f_width;

	screen->iconVwin.height =
	    MaxRows(screen) * screen->iconVwin.f_height;

	changes.width = screen->iconVwin.fullwidth =
	    (Dimension) ((unsigned) screen->iconVwin.width
			 + 2 * xw->misc.icon_border_width);

	changes.height = screen->iconVwin.fullheight =
	    (Dimension) ((unsigned) screen->iconVwin.height
			 + 2 * xw->misc.icon_border_width);

	changes.border_width = (int) xw->misc.icon_border_width;

	TRACE(("resizing icon window %dx%d\n", changes.height, changes.width));
	XConfigureWindow(XtDisplay(xw), screen->iconVwin.window,
			 CWWidth | CWHeight | CWBorderWidth, &changes);
    }
#endif /* NO_ACTIVE_ICON */

#if OPT_STATUS_LINE
    if (savedStatus != NULL) {
	int newRow = LastRowNumber(screen);
	LineData *newLD = getLineData(screen, newRow);
	TRACE(("...status line is currently on row %d\n",
	       LastRowNumber(screen)));
	copyLineData(newLD, savedStatus);
	TRACE(("...copied::%s\n",
	       visibleIChars(newLD->charData,
			     newLD->lineSize)));
	freeLineData(screen, savedStatus);
    }
#endif

#ifdef TTYSIZE_STRUCT
    if (update_winsize(screen, rows, cols, height, width) == 0) {
#if defined(SIGWINCH) && defined(TIOCGPGRP)
	if (screen->pid > 1) {
	    int pgrp;

	    TRACE(("getting process-group\n"));
	    if (ioctl(screen->respond, TIOCGPGRP, &pgrp) != -1) {
		TRACE(("sending SIGWINCH to process group %d\n", pgrp));
		kill_process_group(pgrp, SIGWINCH);
	    }
	}
#endif /* SIGWINCH */
    }
#else
    TRACE(("ScreenResize cannot do anything to pty\n"));
#endif /* TTYSIZE_STRUCT */
    return;
}

/*
 * Return true if any character cell starting at [row,col], for len-cells is
 * nonnull.
 */
Bool
non_blank_line(TScreen *screen,
	       int row,
	       int col,
	       int len)
{
    Bool found = False;
    LineData *ld = getLineData(screen, row);

    if (ld != NULL) {
	int i;

	for (i = col; i < len; i++) {
	    if (ld->charData[i]) {
		found = True;
		break;
	    }
	}
    }
    return found;
}

/*
 * Limit/map rectangle parameters.
 */
#define minRectRow(screen) (getMinRow(screen) + 1)
#define minRectCol(screen) (getMinCol(screen) + 1)
#define maxRectRow(screen) (getMaxRow(screen) + 1)
#define maxRectCol(screen) (getMaxCol(screen) + 1)

static int
limitedParseRow(XtermWidget xw, int row)
{
    TScreen *screen = TScreenOf(xw);
    int min_row = minRectRow(screen);
    int max_row = maxRectRow(screen);

    if (xw->flags & ORIGIN)
	row += screen->top_marg;

    if (row < min_row)
	row = min_row;
    else if (row > max_row)
	row = max_row;

    return row;
}

static int
limitedParseCol(XtermWidget xw, int col)
{
    TScreen *screen = TScreenOf(xw);
    int min_col = minRectCol(screen);
    int max_col = maxRectCol(screen);

    if (xw->flags & ORIGIN)
	col += screen->lft_marg;

    if (col < min_col)
	col = min_col;
    else if (col > max_col)
	col = max_col;

    return col;
}

#define LimitedParse(num, func, dft) \
	func(xw, (nparams > num && params[num] > 0) ? params[num] : dft)

/*
 * Copy the rectangle boundaries into a struct, providing default values as
 * needed.
 */
void
xtermParseRect(XtermWidget xw, int nparams, int *params, XTermRect *target)
{
    TScreen *screen = TScreenOf(xw);

    memset(target, 0, sizeof(*target));
    target->top = LimitedParse(0, limitedParseRow, minRectRow(screen));
    target->left = LimitedParse(1, limitedParseCol, minRectCol(screen));
    target->bottom = LimitedParse(2, limitedParseRow, maxRectRow(screen));
    target->right = LimitedParse(3, limitedParseCol, maxRectCol(screen));
    TRACE(("parsed %d params for rectangle %d,%d %d,%d default %d,%d %d,%d\n",
	   nparams,
	   target->top,
	   target->left,
	   target->bottom,
	   target->right,
	   minRectRow(screen),
	   minRectCol(screen),
	   maxRectRow(screen),
	   maxRectCol(screen)));
}

static Bool
validRect(XtermWidget xw, XTermRect *target)
{
    TScreen *screen = TScreenOf(xw);
    Bool result = (target != NULL
		   && target->top >= minRectRow(screen)
		   && target->left >= minRectCol(screen)
		   && target->top <= target->bottom
		   && target->left <= target->right
		   && target->top <= maxRectRow(screen)
		   && target->right <= maxRectCol(screen));

    TRACE(("comparing against screensize %dx%d, is%s valid\n",
	   maxRectRow(screen),
	   maxRectCol(screen),
	   result ? "" : " NOT"));
    return result;
}

/*
 * Fills a rectangle with the given 8-bit character and video-attributes.
 * Colors and double-size attribute are unmodified.
 */
void
ScrnFillRectangle(XtermWidget xw,
		  XTermRect *target,
		  int value,
		  DECNRCM_codes charset,
		  unsigned flags,
		  Bool keepColors)
{
    IChar actual = (IChar) value;
    TScreen *screen = TScreenOf(xw);

    TRACE(("filling rectangle with '%s' %s flags %#x\n",
	   visibleIChars(&actual, 1),
	   visibleScsCode(charset),
	   flags));
    if (validRect(xw, target)) {
	LineData *ld;
	int top = (target->top - 1);
	int left = (target->left - 1);
	int right = (target->right - 1);
	int bottom = (target->bottom - 1);
	int numcols = (right - left) + 1;
	int numrows = (bottom - top) + 1;
	unsigned attrs = flags;
	int row, col;
	int b_left = 0;
	int b_right = 0;

	(void) numcols;

	if (charset != nrc_ASCII) {
	    xw->work.write_text = &actual;
	    if (xtermCharSetOut(xw, 1, charset) == 0)
		actual = ' ';
	}

	attrs &= ATTRIBUTES;
	attrs |= CHARDRAWN;
	for (row = bottom; row >= top; row--) {
	    ld = getLineData(screen, row);

	    TRACE(("filling %d [%d..%d]\n", row, left, left + numcols));

	    if_OPT_WIDE_CHARS(screen, {
		if (left > 0) {
		    if (ld->charData[left] == HIDDEN_CHAR) {
			b_left = 1;
			Clear1Cell(ld, left - 1);
			Clear1Cell(ld, left);
		    }
		}
		if (right + 1 < (int) ld->lineSize) {
		    if (ld->charData[right + 1] == HIDDEN_CHAR) {
			b_right = 1;
			Clear1Cell(ld, right);
			Clear1Cell(ld, right + 1);
		    }
		}
	    });

	    /*
	     * Fill attributes, preserving colors.
	     */
	    for (col = left; col <= right; ++col) {
		unsigned temp = ld->attribs[col];

		if (!keepColors) {
		    UIntClr(temp, (FG_COLOR | BG_COLOR));
		}
		temp = attrs | (temp & (FG_COLOR | BG_COLOR)) | CHARDRAWN;
		ld->attribs[col] = (IAttr) temp;
		if_OPT_ISO_COLORS(screen, {
		    if (attrs & (FG_COLOR | BG_COLOR)) {
			ld->color[col] = xtermColorPair(xw);
		    }
		});
	    }

	    for (col = left; col <= right; ++col) {
		ld->charData[col] = actual;
#if OPT_DEC_RECTOPS
		ld->charSeen[col] = (Char) value;
		ld->charSets[col] = charset;
#endif
	    }

	    if_OPT_WIDE_CHARS(screen, {
		size_t off;
		for_each_combData(off, ld) {
		    memset(ld->combData[off] + left,
			   0,
			   (size_t) numcols * sizeof(CharData));
		}
	    })
	}
	chararea_clear_displayed_graphics(screen,
					  left,
					  top,
					  numcols, numrows);
	ScrnUpdate(xw,
		   top,
		   left - b_left,
		   numrows,
		   numcols + b_left + b_right,
		   False);
    }
}

#if OPT_DEC_RECTOPS
/*
 * Copies the source rectangle to the target location, including video
 * attributes.
 *
 * This implementation ignores page numbers.
 *
 * The reference manual does not indicate if it handles overlapping copy
 * properly - so we make a local copy of the source rectangle first, then apply
 * the target from that.
 */
void
ScrnCopyRectangle(XtermWidget xw, XTermRect *source, int nparam, int *params)
{
    TScreen *screen = TScreenOf(xw);

    TRACE(("copying rectangle\n"));

    if (nparam > 4)
	nparam = 4;

    if (validRect(xw, source)) {
	XTermRect target;
	xtermParseRect(xw,
		       ((nparam > 2) ? 2 : nparam),
		       params,
		       &target);
	if (validRect(xw, &target)) {
	    Cardinal high = (Cardinal) (source->bottom - source->top) + 1;
	    Cardinal wide = (Cardinal) (source->right - source->left) + 1;
	    Cardinal size = (high * wide);
	    int row, col;
	    Cardinal j, k;
	    LineData *ld;
	    int b_left = 0;
	    int b_right = 0;

	    CellData *cells = newCellData(xw, size);

	    if (cells != NULL) {

		TRACE(("OK - make copy %dx%d\n", high, wide));
		target.bottom = target.top + (int) (high - 1);
		target.right = target.left + (int) (wide - 1);

		for (row = source->top - 1; row < source->bottom; ++row) {
		    ld = getLineData(screen, row);
		    if (ld == NULL)
			continue;
		    j = (Cardinal) (row - (source->top - 1));
		    TRACE2(("ROW %d\n", row + 1));
		    for (col = source->left - 1; col < source->right; ++col) {
			k = (Cardinal) (col - (source->left - 1));
			saveCellData(screen, cells,
				     (j * wide) + k,
				     ld, source, col);
		    }
		}
		for (row = target.top - 1; row < target.bottom; ++row) {
		    ld = getLineData(screen, row);
		    if (ld == NULL)
			continue;
		    j = (Cardinal) (row - (target.top - 1));
		    TRACE2(("ROW %d\n", row + 1));
		    for (col = target.left - 1; col < target.right; ++col) {
			k = (Cardinal) (col - (target.left - 1));
			if (row >= getMinRow(screen)
			    && row <= getMaxRow(screen)
			    && col >= getMinCol(screen)
			    && col <= getMaxCol(screen)
			    && (j < high)
			    && (k < wide)) {
			    if_OPT_WIDE_CHARS(screen, {
				if (ld->charData[col] == HIDDEN_CHAR
				    && (col + 1) == target.left) {
				    b_left = 1;
				    Clear1Cell(ld, col - 1);
				}
				if ((col + 1) == target.right
				    && ld->charData[col] == HIDDEN_CHAR) {
				    b_right = 1;
				}
			    });
			    restoreCellData(screen, cells,
					    (j * wide) + k,
					    ld, &target, col);
			}
			ld->attribs[col] |= CHARDRAWN;
		    }
#if OPT_BLINK_TEXT
		    if (LineHasBlinking(screen, ld)) {
			LineSetBlinked(ld);
		    } else {
			LineClrBlinked(ld);
		    }
#endif
		}
		free(cells);

		ScrnUpdate(xw,
			   (target.top - 1),
			   (target.left - (1 + b_left)),
			   (target.bottom - target.top) + 1,
			   ((target.right - target.left) + (1 + b_left + b_right)),
			   False);
	    }
	}
    }
}

/*
 * Modifies the video-attributes only - so selection (not a video attribute) is
 * unaffected.  Colors and double-size flags are unaffected as well.
 *
 * Reference: VSRM - Character Cell Display EL-00070-05
 *
 * Section:
 * -------
 * CHANGE ATTRIBUTES RECTANGULAR AREA -- DECCARA
 * Page 5-173
 *
 * Quote:
 * The character positions affected depend on the current setting of DECSACE
 * (STREAM or RECTANGLE).  See DECSACE for details.
 *
 * Notes:
 * xterm allows 8 (hidden) to be reversed, as an extension.
 *
 * Section:
 * -------
 * REVERSE ATTRIBUTES RECTANGULAR AREA -- DECRARA
 * Page 5-175
 *
 * Quote:
 * The video attribute(s) to be reversed are in the affected area are indicated
 * by one or more subsequent parameters.  These parameters are similar to the
 * parameters of the Set Graphic Rendition control function (SGR):
 *
 * Parameter  Parameter Meaning
 *    0       Reverse all attributes
 *    1       Reverse bold attribute
 *    4       Reverse underscore attribute
 *    5       Reverse blinking attribute
 *    7       Reverse negative (reverse) image attribute
 *
 * All other parameter values shall be ignored unless they are part of a well
 * defined extension to the architecture.  Note if the Color Text Extension is
 * present, the color text SGR values are ignored since the "reverse" of a
 * color is not defined by the extension.
 *
 * Notes:
 * xterm allows 8 (hidden) to be reversed, as an extension.
 *
 * Section:
 * -------
 * SELECT ATTRIBUTE CHANGE EXTENT -- DECSACE
 * Page 5-177
 *
 * Quote:
 * When Ps = 0 or 1, DECCARA and DECRARA affects the stream of character
 * positions beginning with the first character position specified in the
 * command, and ending with the second character position specified.
 *
 * Notes:
 * The description of DECSACE goes on to state that "unoccupied" cells are
 * not affected in STREAM mode, while in RECTANGLE mode they are converted
 * to blanks.
 *
 * While STREAM uses the upper-left and lower-right cell coordinates for a
 * RECTANGLE (which may take into account ORIGIN mode), the characters wrap,
 * in STREAM mode, and DEC 070 does not appear to state that ORIGIN mode
 * affects the wrap-margins.
 */
void
ScrnMarkRectangle(XtermWidget xw,
		  XTermRect *target,
		  Bool reverse,
		  int nparam,
		  int *params)
{
    TScreen *screen = TScreenOf(xw);
    Bool exact = (screen->cur_decsace == 2);

    TRACE(("%s %s\n",
	   reverse ? "reversing" : "marking",
	   (exact
	    ? "rectangle"
	    : "region")));

    if (validRect(xw, target)) {
	LineData *ld;
	int top = target->top - 1;
	int bottom = target->bottom - 1;
	int row, col;
	int n;

	for (row = top; row <= bottom; ++row) {
	    int left = ((exact || (row == top))
			? (target->left - 1)
			: 0);
	    int right = ((exact || (row == bottom))
			 ? (target->right - 1)
			 : screen->max_col);

	    ld = getLineData(screen, row);

	    TRACE(("marking %d [%d..%d]\n", row, left, right));
	    for (col = left; col <= right; ++col) {
		unsigned flags = ld->attribs[col];

		if (!(flags & CHARDRAWN)) {
		    if (exact) {
			flags |= CHARDRAWN;
			Clear1Cell(ld, col);
		    } else {
			continue;
		    }
		}

		for (n = 0; n < nparam; ++n) {
#if OPT_TRACE
		    if (row == top && col == left)
			TRACE(("attr param[%d] %d\n", n + 1, params[n]));
#endif
		    if (reverse) {
			switch (params[n]) {
			case 0:
			    flags ^= SGR_MASK;
			    break;
			case 1:
			    flags ^= BOLD;
			    break;
			case 4:
			    flags ^= UNDERLINE;
			    break;
			case 5:
			    flags ^= BLINK;
			    break;
			case 7:
			    flags ^= INVERSE;
			    break;
			case 8:
			    flags ^= INVISIBLE;
			    break;
			}
		    } else {
			switch (params[n]) {
			case 0:
			    UIntClr(flags, SGR_MASK);
			    break;
			case 1:
			    flags |= BOLD;
			    break;
			case 4:
			    flags |= UNDERLINE;
			    break;
			case 5:
			    flags |= BLINK;
			    break;
			case 7:
			    flags |= INVERSE;
			    break;
			case 8:
			    flags |= INVISIBLE;
			    break;
			case 22:
			    UIntClr(flags, BOLD);
			    break;
			case 24:
			    UIntClr(flags, UNDERLINE);
			    break;
			case 25:
			    UIntClr(flags, BLINK);
			    break;
			case 27:
			    UIntClr(flags, INVERSE);
			    break;
			case 28:
			    UIntClr(flags, INVISIBLE);
			    break;
			}
		    }
		}
#if OPT_TRACE
		if (row == top && col == left)
		    TRACE(("first mask-change is %#x\n",
			   ld->attribs[col] ^ flags));
#endif
		ld->attribs[col] = (IAttr) flags;
	    }
	}
	ScrnRefresh(xw,
		    (target->top - 1),
		    (exact ? (target->left - 1) : getMinCol(screen)),
		    (target->bottom - target->top) + 1,
		    (exact
		     ? ((target->right - target->left) + 1)
		     : (getMaxCol(screen) - getMinCol(screen) + 1)),
		    True);
    }
}

/*
 * Resets characters to space, except where prohibited by DECSCA.  Video
 * attributes (including color) are untouched.
 */
void
ScrnWipeRectangle(XtermWidget xw,
		  XTermRect *target)
{
    TScreen *screen = TScreenOf(xw);

    TRACE(("wiping rectangle\n"));

#define IsProtected(ld, col) \
		((screen->protected_mode == DEC_PROTECT) \
		 && (ld->attribs[col] & PROTECTED))

    if (validRect(xw, target)) {
	int top = target->top - 1;
	int left = target->left - 1;
	int right = target->right - 1;
	int bottom = target->bottom - 1;
	int numcols = (right - left) + 1;
	int numrows = (bottom - top) + 1;
	int row, col;
	int b_left = 0;
	int b_right = 0;

	for (row = top; row <= bottom; ++row) {
	    LineData *ld;

	    TRACE(("wiping %d [%d..%d]\n", row, left, right));

	    ld = getLineData(screen, row);

	    if_OPT_WIDE_CHARS(screen, {
		if (left > 0 && !IsProtected(ld, left)) {
		    if (ld->charData[left] == HIDDEN_CHAR) {
			b_left = 1;
			Clear1Cell(ld, left - 1);
			Clear1Cell(ld, left);
		    }
		}
		if (right + 1 < (int) ld->lineSize && !IsProtected(ld, right)) {
		    if (ld->charData[right + 1] == HIDDEN_CHAR) {
			b_right = 1;
			Clear1Cell(ld, right);
			Clear1Cell(ld, right + 1);
		    }
		}
	    });

	    for (col = left; col <= right; ++col) {
		if (!IsProtected(ld, col)) {
		    ld->attribs[col] |= CHARDRAWN;
		    Clear1Cell(ld, col);
		}
	    }
	}
	chararea_clear_displayed_graphics(screen,
					  left,
					  top,
					  numcols, numrows);
	ScrnUpdate(xw,
		   top,
		   left - b_left,
		   numrows,
		   numcols + b_left + b_right,
		   False);
    }
}

/*
 * Compute a checksum, ignoring the page number (since we have only one page).
 */
void
xtermCheckRect(XtermWidget xw,
	       int nparam,
	       int *params,
	       int *result)
{
    TScreen *screen = TScreenOf(xw);
    XTermRect target;
    LineData *ld;
    int total = 0;
    int trimmed = 0;
    int mode = screen->checksum_ext;

    TRACE(("xtermCheckRect: %s%s%s%s%s%s\n",
	   (mode == csDEC) ? "DEC" : "checksumExtension",
	   (mode & csPOSITIVE) ? " !negative" : "",
	   (mode & csATTRIBS) ? " !attribs" : "",
	   (mode & csNOTRIM) ? " !trimmed" : "",
	   (mode & csDRAWN) ? " !drawn" : "",
	   (mode & csBYTE) ? " !byte" : ""));

    if (nparam > 2) {
	nparam -= 2;
	params += 2;
    }
    xtermParseRect(xw, nparam, params, &target);
    if (validRect(xw, &target)) {
	int top = target.top - 1;
	int bottom = target.bottom - 1;
	int row, col;
	Boolean first = True;
	int embedded = 0;

	for (row = top; row <= bottom; ++row) {
	    int left = (target.left - 1);
	    int right = (target.right - 1);
	    int ch;

	    ld = getLineData(screen, row);
	    if (ld == NULL)
		continue;
	    for (col = left; col <= right && col < (int) ld->lineSize; ++col) {
		if (!(ld->attribs[col] & CHARDRAWN)) {
		    if (!(mode & (csNOTRIM | csDRAWN)))
			continue;
		    ch = ' ';
		} else if (!(mode & csBYTE)) {
		    ch = xtermCharSetDec(xw,
					 ld->charSeen[col],
					 ld->charSets[col]);
		} else {
		    ch = (int) ld->charData[col];
		    if_OPT_WIDE_CHARS(screen, {
			if (ld->charSets[col] == nrc_DEC_Spec_Graphic) {
			    ch = (int) dec2ucs(screen, (unsigned) ch);
			}
			if (is_UCS_SPECIAL(ch))
			    continue;
		    });
		}
		if (!(mode & csATTRIBS)) {
#if OPT_ISO_COLORS && OPT_VT525_COLORS
		    if (screen->terminal_id == 525) {
			IAttr flags = ld->attribs[col];
			CellColor fg_bg = ld->color[col];
			int fg = (int) extract_fg(xw, fg_bg, flags);
			int bg = (int) extract_bg(xw, fg_bg, flags);
			Boolean dft_bg = (bg < 0);
			Boolean dft_fg = (fg < 0);

			if (dft_bg)
			    bg = screen->assigned_bg;
			if (bg >= 0 && bg < 16)
			    ch += bg;

			if (dft_fg)
			    fg = screen->assigned_fg;
			if (fg >= 0 && fg < 16)
			    ch += (fg << 4);

			/* special case to match VT525 behavior */
			if (dft_bg && !dft_fg && (ld->attribs[col] & BOLD))
			    ch -= 0x80;
		    }
#endif
		    if (ld->attribs[col] & PROTECTED)
			ch += 0x4;
#if OPT_WIDE_ATTRS
		    if (ld->attribs[col] & INVISIBLE)
			ch += 0x8;
#endif
		    if (ld->attribs[col] & UNDERLINE)
			ch += 0x10;
		    if (ld->attribs[col] & INVERSE)
			ch += 0x20;
		    if (ld->attribs[col] & BLINK)
			ch += 0x40;
		    if (ld->attribs[col] & BOLD)
			ch += 0x80;
		}
		if (first || (ch != ' ') || (ld->attribs[col] & DRAWX_MASK)) {
		    trimmed += ch + embedded;
		    embedded = 0;
		} else if ((mode & csNOTRIM)) {
		    embedded += ch;
		}
		total += ch;
		if_OPT_WIDE_CHARS(screen, {
		    /* FIXME - not counted if trimming blanks */
		    if (!(mode & csBYTE)) {
			size_t off;
			for_each_combData(off, ld) {
			    total += (int) ld->combData[off][col];
			}
		    }
		});
		first = ((mode & csNOTRIM) != 0) ? True : False;
	    }
	    if (!(mode & csNOTRIM)) {
		embedded = 0;
		first = False;
	    }
	}
    }
    if (!(mode & csNOTRIM))
	total = trimmed;
    if (!(mode & csPOSITIVE))
	total = -total;
    *result = total;
}
#endif /* OPT_DEC_RECTOPS */

static void
set_ewmh_hint(XtermWidget xw, int operation, _Xconst char *prop)
{
    TScreen *screen = TScreenOf(xw);
    Display *dpy = screen->display;
    Window window;
    XEvent e;
    Atom atom_fullscreen = CachedInternAtom(dpy, prop);
    Atom atom_state = CachedInternAtom(dpy, "_NET_WM_STATE");

#if OPT_TRACE
    const char *what = "?";
    switch (operation) {
    case _NET_WM_STATE_ADD:
	what = "adding";
	break;
    case _NET_WM_STATE_REMOVE:
	what = "removing";
	break;
    }
    TRACE(("set_ewmh_hint %s %s\n", what, prop));
#endif

#if OPT_TEK4014
    if (TEK4014_ACTIVE(xw)) {
	window = TShellWindow;
    } else
#endif
	window = VShellWindow(xw);

    memset(&e, 0, sizeof(e));
    e.xclient.type = ClientMessage;
    e.xclient.message_type = atom_state;
    e.xclient.display = dpy;
    e.xclient.window = window;
    e.xclient.format = 32;
    e.xclient.data.l[0] = operation;
    e.xclient.data.l[1] = (long) atom_fullscreen;

    XSendEvent(dpy, DefaultRootWindow(dpy), False,
	       SubstructureRedirectMask, &e);
}

void
ResetHiddenHint(XtermWidget xw)
{
    set_ewmh_hint(xw, _NET_WM_STATE_REMOVE, "_NET_WM_STATE_HIDDEN");
}

#if OPT_MAXIMIZE

static _Xconst char *
ewmhProperty(int mode)
{
    _Xconst char *result;
    switch (mode) {
    default:
	result = NULL;
	break;
    case 1:
	result = "_NET_WM_STATE_FULLSCREEN";
	break;
    case 2:
	result = "_NET_WM_STATE_MAXIMIZED_VERT";
	break;
    case 3:
	result = "_NET_WM_STATE_MAXIMIZED_HORZ";
	break;
    }
    return result;
}

static void
set_resize_increments(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    int min_width = (2 * screen->border) + screen->fullVwin.sb_info.width;
    int min_height = (2 * screen->border);
    XSizeHints sizehints;

    TRACE(("set_resize_increments\n"));
    memset(&sizehints, 0, sizeof(XSizeHints));
    sizehints.width_inc = FontWidth(screen);
    sizehints.height_inc = FontHeight(screen);
    sizehints.flags = PResizeInc;
    TRACE_HINTS(&sizehints);
    XSetWMNormalHints(screen->display, VShellWindow(xw), &sizehints);

    TRACE(("setting values for widget %p:\n", (void *) SHELL_OF(xw)));
    TRACE(("   base width  %d\n", min_width));
    TRACE(("   base height %d\n", min_width));
    TRACE(("   min width   %d\n", min_width + FontWidth(screen)));
    TRACE(("   min height  %d\n", min_width + FontHeight(screen)));
    TRACE(("   width inc   %d\n", FontWidth(screen)));
    TRACE(("   height inc  %d\n", FontHeight(screen)));

    XtVaSetValues(SHELL_OF(xw),
		  XtNbaseWidth, min_width,
		  XtNbaseHeight, min_height,
		  XtNminWidth, min_width + FontWidth(screen),
		  XtNminHeight, min_height + FontHeight(screen),
		  XtNwidthInc, FontWidth(screen),
		  XtNheightInc, FontHeight(screen),
		  (XtPointer) 0);

    XFlush(XtDisplay(xw));
}

static void
unset_resize_increments(XtermWidget xw)
{
    TScreen *screen = TScreenOf(xw);
    XSizeHints sizehints;

    TRACE(("unset_resize_increments\n"));
    memset(&sizehints, 0, sizeof(XSizeHints));
    sizehints.width_inc = 1;
    sizehints.height_inc = 1;
    sizehints.flags = PResizeInc;
    TRACE_HINTS(&sizehints);
    XSetWMNormalHints(screen->display, VShellWindow(xw), &sizehints);

    XtVaSetValues(SHELL_OF(xw),
		  XtNwidthInc, 1,
		  XtNheightInc, 1,
		  (XtPointer) 0);

    XFlush(XtDisplay(xw));
}

/*
 * Check if the given property is supported on the root window.
 *
 * The XGetWindowProperty function returns a list of Atom's which corresponds
 * to the output of xprop.  The actual list (ignore the manpage, which refers
 * to an array of 32-bit values) is constructed by _XRead32, which uses long
 * as a datatype.
 *
 * Alternatively, we could check _NET_WM_ALLOWED_ACTIONS on the application's
 * window.
 */
static Boolean
probe_netwm(Display *dpy, _Xconst char *propname)
{
    Atom atom_fullscreen = CachedInternAtom(dpy, propname);
    Atom atom_supported = CachedInternAtom(dpy, "_NET_SUPPORTED");
    Atom actual_type;
    int actual_format;
    long long_offset = 0;
    long long_length = 128;	/* number of items to ask for at a time */
    unsigned int i;
    unsigned long nitems, bytes_after;
    unsigned char *args;
    long *ldata;
    Boolean has_capability = False;
    Boolean rc;

    while (!has_capability) {
	rc = xtermGetWinProp(dpy,
			     DefaultRootWindow(dpy),
			     atom_supported,
			     long_offset,
			     long_length,
			     AnyPropertyType,	/* req_type */
			     &actual_type,	/* actual_type_return */
			     &actual_format,	/* actual_format_return */
			     &nitems,	/* nitems_return */
			     &bytes_after,	/* bytes_after_return */
			     &args	/* prop_return */
	    );
	if (!rc
	    || actual_type != XA_ATOM) {
	    break;
	}
	ldata = (long *) (void *) args;
	for (i = 0; i < nitems; i++) {
#if OPT_TRACE > 1
	    char *name;
	    if ((name = XGetAtomName(dpy, ldata[i])) != 0) {
		TRACE(("atom[%d] = %s\n", i, name));
		XFree(name);
	    } else {
		TRACE(("atom[%d] = ?\n", i));
	    }
#endif
	    if ((Atom) ldata[i] == atom_fullscreen) {
		has_capability = True;
		break;
	    }
	}
	XFree(ldata);

	if (!has_capability) {
	    if (bytes_after != 0) {
		long remaining = (long) (bytes_after / sizeof(long));
		if (long_length > remaining)
		    long_length = remaining;
		long_offset += (long) nitems;
	    } else {
		break;
	    }
	}
    }

    TRACE(("probe_netwm(%s) ->%d\n", propname, has_capability));
    return has_capability;
}

/*
 * Alter fullscreen mode for the xterm widget, if the window manager supports
 * that feature.
 */
void
FullScreen(XtermWidget xw, int new_ewmh_mode)
{
    TScreen *screen = TScreenOf(xw);
    Display *dpy = screen->display;
    int old_ewmh_mode;
    _Xconst char *oldprop;
    _Xconst char *newprop;

    int which = 0;
#if OPT_TEK4014
    if (TEK4014_ACTIVE(xw))
	which = 1;
#endif

    old_ewmh_mode = xw->work.ewmh[which].mode;
    oldprop = ewmhProperty(old_ewmh_mode);
    newprop = ewmhProperty(new_ewmh_mode);

    TRACE(("FullScreen %d:%s -> %d:%s\n",
	   old_ewmh_mode, NonNull(oldprop),
	   new_ewmh_mode, NonNull(newprop)));

    if (new_ewmh_mode == old_ewmh_mode) {
	TRACE(("...unchanged\n"));
	return;
    } else if (new_ewmh_mode < 0 || new_ewmh_mode > MAX_EWMH_MODE) {
	TRACE(("BUG: FullScreen %d\n", new_ewmh_mode));
	return;
    } else if (new_ewmh_mode == 0) {
	xw->work.ewmh[which].checked[new_ewmh_mode] = True;
	xw->work.ewmh[which].allowed[new_ewmh_mode] = True;
    } else if (resource.fullscreen == esNever) {
	xw->work.ewmh[which].checked[new_ewmh_mode] = True;
	xw->work.ewmh[which].allowed[new_ewmh_mode] = False;
    } else if (!xw->work.ewmh[which].checked[new_ewmh_mode]) {
	xw->work.ewmh[which].checked[new_ewmh_mode] = True;
	xw->work.ewmh[which].allowed[new_ewmh_mode] = probe_netwm(dpy, newprop);
    }

    if (xw->work.ewmh[which].allowed[new_ewmh_mode]) {
	TRACE(("...new EWMH mode is allowed\n"));
	if (new_ewmh_mode && !xw->work.ewmh[which].mode) {
	    unset_resize_increments(xw);
	    set_ewmh_hint(xw, _NET_WM_STATE_ADD, newprop);
	} else if (xw->work.ewmh[which].mode && !new_ewmh_mode) {
	    if (!xw->misc.resizeByPixel) {
		set_resize_increments(xw);
	    }
	    set_ewmh_hint(xw, _NET_WM_STATE_REMOVE, oldprop);
	} else {
	    set_ewmh_hint(xw, _NET_WM_STATE_REMOVE, oldprop);
	    set_ewmh_hint(xw, _NET_WM_STATE_ADD, newprop);
	}
	xw->work.ewmh[which].mode = new_ewmh_mode;
	update_fullscreen();
    } else {
	Bell(xw, XkbBI_MinorError, 100);
    }
}
#endif /* OPT_MAXIMIZE */
xterm-399/cachedGCs.c0000644000000000000000000004621414773617351013232 0ustar  rootroot/* $XTermId: cachedGCs.c,v 1.86 2025/04/03 23:51:05 tom Exp $ */

/*
 * Copyright 2007-2024,2025 by Thomas E. Dickey
 *
 *                         All Rights Reserved
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name(s) of the above copyright
 * holders shall not be used in advertising or otherwise to promote the
 * sale, use or other dealings in this Software without prior written
 * authorization.
 */

#include 
#include 
#include 

#include 

/*
 * hide (or eliminate) calls to
 *	XCreateGC()
 *	XFreeGC()
 *	XGetGCValues()
 *	XSetBackground()
 *	XSetFont()
 *	XSetForeground()
 *	XtGetGC()
 *	XtReleaseGC()
 * by associating an integer with each GC, maintaining a cache which
 * reflects frequency of use rather than most recent usage.
 *
 * FIXME: XTermFonts should hold gc, font, fs.
 */
typedef struct {
    GC gc;
    unsigned used;
    unsigned cset;
    XTermFonts *font;
    Pixel tile;
    Pixel fg;
    Pixel bg;
} CgsCacheData;

#define DEPTH 8
#define ITEM()      (int) (me->data - me->list)
#define LIST(item)  me->list[item]
#define LINK(item)  me->data = (me->list + (item))
#define THIS(field) me->data->field
#define NEXT(field) me->next.field

#define HaveFont(font) (Boolean) ((font) != NULL && (font)->fs != NULL)

#define GC_CSet GCFunction

typedef struct {
    CgsCacheData list[DEPTH];
    CgsCacheData *data;		/* points to current list[] entry */
    XtGCMask mask;		/* changes since the last getCgsGC() */
    CgsCacheData next;		/* updated values, apply in getCgsGC() */
} CgsCache;

#if OPT_TRACE
#define CASE(name) case gc##name: result = #name; break
static const char *
traceCgsEnum(CgsEnum value)
{
    const char *result = "?";
    switch (value) {
	CASE(Norm);
	CASE(Bold);
	CASE(NormReverse);
	CASE(BoldReverse);
	CASE(Border);
	CASE(Filler);
#if OPT_BOX_CHARS || OPT_WIDE_CHARS
	CASE(Line);
	CASE(Dots);
#endif
#if OPT_DEC_CHRSET
	CASE(CNorm);
	CASE(CBold);
#endif
#if OPT_WIDE_CHARS
	CASE(Wide);
	CASE(WBold);
	CASE(WideReverse);
	CASE(WBoldReverse);
#endif
	CASE(VTcursNormal);
	CASE(VTcursFilled);
	CASE(VTcursReverse);
	CASE(VTcursOutline);
#if OPT_TEK4014
	CASE(TKcurs);
#endif
	CASE(MAX);
    }
    return result;
}

#undef CASE

static const char *
traceVTwin(XtermWidget xw, const VTwin *value)
{
    const char *result = "?";
    if (value == NULL)
	result = "null";
    else if (value == &(TScreenOf(xw)->fullVwin))
	result = "fullVwin";
#ifndef NO_ACTIVE_ICON
    else if (value == &(TScreenOf(xw)->iconVwin))
	result = "iconVwin";
#endif
    return result;
}

#if OPT_TRACE > 1
static String
traceCSet(unsigned cset)
{
    static char result[80];
    switch (cset) {
    case CSET_SWL:
	strcpy(result, "SWL");
	break;
    case CSET_DHL_TOP:
	strcpy(result, "DHL_TOP");
	break;
    case CSET_DHL_BOT:
	strcpy(result, "DHL_BOT");
	break;
    case CSET_DWL:
	strcpy(result, "DWL");
	break;
    default:
	sprintf(result, "%#x", cset);
	break;
    }
    return result;
}

static String
traceFont(XTermFonts * font)
{
    static char result[80];

    return strcpy(result, font != NULL ? visibleFont(font->fs) : "null");
}

static String
tracePixel(XtermWidget xw, Pixel value)
{
#define CASE(name) { name, #name }
    static struct {
	TermColors code;
	String name;
    } t_colors[] = {
	CASE(TEXT_FG),
	    CASE(TEXT_BG),
	    CASE(TEXT_CURSOR),
	    CASE(MOUSE_FG),
	    CASE(MOUSE_BG),
#if OPT_TEK4014
	    CASE(TEK_FG),
	    CASE(TEK_BG),
#endif
#if OPT_HIGHLIGHT_COLOR
	    CASE(HIGHLIGHT_BG),
	    CASE(HIGHLIGHT_FG),
#endif
#if OPT_TEK4014
	    CASE(TEK_CURSOR),
#endif
    };
    TScreen *screen = TScreenOf(xw);
    String result = 0;
    int n;

    for (n = 0; n < NCOLORS; ++n) {
	if (value == T_COLOR(screen, t_colors[n].code)) {
	    result = t_colors[n].name;
	    break;
	}
    }

    if (result == 0) {
	for (n = 0; n < MAXCOLORS; ++n) {
	    if (screen->Acolors[n].mode > 0
		&& value == screen->Acolors[n].value) {
		result = screen->Acolors[n].resource;
		break;
	    }
	}
    }

    if (result == 0) {
	char temp[80];
	sprintf(temp, "%#lx", value);
	result = x_strdup(temp);
    }

    return result;
}

#undef CASE

#endif /* OPT_TRACE > 1 */
#endif /* OPT_TRACE */

static CgsCache *
allocCache(void **cache_pointer)
{
    if (*cache_pointer == NULL) {
	*cache_pointer = TypeCallocN(CgsCache, gcMAX);
	TRACE(("allocCache %p\n", *cache_pointer));
    }
    return *((CgsCache **) cache_pointer);
}

#define ALLOC_CACHE(p) ((*(p) == NULL) ? allocCache(p) : *(p))

static int
dataIndex(CgsCache * me)
{
    return ITEM();
}

static void
relinkData(CgsCache * me, int item)
{
    LINK(item);
}

/*
 * Returns the appropriate cache pointer.
 */
static CgsCache *
myCache(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId)
{
    CgsCache *result = NULL;

    if ((int) cgsId >= 0 && cgsId < gcMAX) {
#ifdef NO_ACTIVE_ICON
	(void) xw;
	(void) cgsWin;
#else
	if (cgsWin == &(TScreenOf(xw)->iconVwin))
	    result = ALLOC_CACHE(&(TScreenOf(xw)->icon_cgs_cache));
	else
#endif
	    result = ALLOC_CACHE(&(TScreenOf(xw)->main_cgs_cache));

	result += cgsId;
	if (result->data == NULL) {
	    result->data = result->list;
	}
    }

    return result;
}

static Display *
myDisplay(XtermWidget xw)
{
    return TScreenOf(xw)->display;
}

static Drawable
myDrawable(XtermWidget xw, VTwin *cgsWin)
{
    Drawable drawable = 0;

    if (cgsWin != NULL && cgsWin->window != 0)
	drawable = cgsWin->window;
    if (drawable == 0)
	drawable = RootWindowOfScreen(XtScreen(xw));
    return drawable;
}

static GC
newCache(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId, CgsCache * me)
{
    XGCValues xgcv;
    XtGCMask mask;

    THIS(font) = NEXT(font);
    THIS(cset) = NEXT(cset);
    THIS(fg) = NEXT(fg);
    THIS(bg) = NEXT(bg);

    memset(&xgcv, 0, sizeof(xgcv));
    xgcv.font = NEXT(font)->fs->fid;
    mask = (GCForeground | GCBackground | GCFont);

    switch (cgsId) {
    case gcFiller:
    case gcBorder:
	mask &= (XtGCMask) ~ GCFont;
	/* FALLTHRU */
    case gcNorm:
    case gcBold:
    case gcNormReverse:
    case gcBoldReverse:
#if OPT_WIDE_CHARS
    case gcWide:
    case gcWBold:
    case gcWideReverse:
    case gcWBoldReverse:
#endif
	mask |= (GCGraphicsExposures | GCFunction);
	xgcv.graphics_exposures = True;		/* default */
	xgcv.function = GXcopy;
	break;
#if OPT_BOX_CHARS || OPT_WIDE_CHARS
    case gcLine:
	mask |= (GCGraphicsExposures | GCFunction);
	xgcv.graphics_exposures = True;		/* default */
	xgcv.function = GXcopy;
	break;
    case gcDots:
	xgcv.fill_style = FillTiled;
	xgcv.tile =
	    XmuCreateStippledPixmap(XtScreen((Widget) xw),
				    THIS(fg),
				    THIS(bg),
				    xw->core.depth);
	THIS(tile) = xgcv.tile;
	mask = (GCForeground | GCBackground);
	mask |= (GCGraphicsExposures | GCFunction | GCTile | GCFillStyle);
	xgcv.graphics_exposures = True;		/* default */
	xgcv.function = GXcopy;
	break;
#endif
#if OPT_DEC_CHRSET
    case gcCNorm:
    case gcCBold:
	break;
#endif
    case gcVTcursNormal:	/* FALLTHRU */
    case gcVTcursFilled:	/* FALLTHRU */
    case gcVTcursReverse:	/* FALLTHRU */
    case gcVTcursOutline:	/* FALLTHRU */
	break;
#if OPT_TEK4014
    case gcTKcurs:		/* FALLTHRU */
	/* FIXME */
#endif
    case gcMAX:		/* should not happen */
	return NULL;
    }
    xgcv.foreground = NEXT(fg);
    xgcv.background = NEXT(bg);

    THIS(gc) = XCreateGC(myDisplay(xw), myDrawable(xw, cgsWin), mask, &xgcv);
    TRACE(("getCgsGC(%s) created gc %p(%d)\n",
	   traceCgsEnum(cgsId), (void *) THIS(gc), ITEM()));

    THIS(used) = 0;
    return THIS(gc);
}

#define SameFont(a, b) \
	(Boolean) (HaveFont(a) \
		   && HaveFont(b) \
		   && (((a)->fs == (b)->fs) \
		       || !memcmp((a)->fs, (b)->fs, sizeof(*((a)->fs)))))

#define SameColor(a,b) ((a) == (b))
#define SameCSet(a,b)  ((a) == (b))

static GC
chgCache(XtermWidget xw, CgsEnum cgsId GCC_UNUSED, CgsCache * me, Bool both)
{
    XGCValues xgcv;
    XtGCMask mask = (GCForeground | GCBackground | GCFont);

    memset(&xgcv, 0, sizeof(xgcv));

    TRACE2(("chgCache(%s) old data fg=%s, bg=%s, font=%s cset %s\n",
	    traceCgsEnum(cgsId),
	    tracePixel(xw, THIS(fg)),
	    tracePixel(xw, THIS(bg)),
	    traceFont(THIS(font)),
	    traceCSet(THIS(cset))));
#if OPT_TRACE > 1
    if (!SameFont(THIS(font), NEXT(font)))
	TRACE2(("...chgCache new font=%s\n", traceFont(NEXT(font))));
    if (!SameCSet(THIS(cset), NEXT(cset)))
	TRACE2(("...chgCache new cset=%s\n", traceCSet(NEXT(cset))));
    if (!SameColor(THIS(fg), NEXT(fg)))
	TRACE2(("...chgCache new fg=%s\n", tracePixel(xw, NEXT(fg))));
    if (!SameColor(THIS(bg), NEXT(bg)))
	TRACE2(("...chgCache new bg=%s\n", tracePixel(xw, NEXT(bg))));
#endif

    if (both) {
	THIS(font) = NEXT(font);
	THIS(cset) = NEXT(cset);
    }
    THIS(fg) = NEXT(fg);
    THIS(bg) = NEXT(bg);

    xgcv.font = THIS(font)->fs->fid;
    xgcv.foreground = THIS(fg);
    xgcv.background = THIS(bg);

    XChangeGC(myDisplay(xw), THIS(gc), mask, &xgcv);
    TRACE2(("...chgCache(%s) updated gc %p(%d)\n",
	    traceCgsEnum(cgsId), THIS(gc), ITEM()));

    THIS(used) = 0;
    return THIS(gc);
}

/*
 * Use the "setCgsXXXX()" calls to initialize parameters for a new GC.
 */
void
setCgsFore(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId, Pixel fg)
{
    CgsCache *me;

    if ((me = myCache(xw, cgsWin, cgsId)) != NULL) {
	NEXT(fg) = fg;
	me->mask |= GCForeground;
	TRACE2(("setCgsFore(%s) %s\n",
		traceCgsEnum(cgsId),
		tracePixel(xw, NEXT(fg))));
    }
}

void
setCgsBack(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId, Pixel bg)
{
    CgsCache *me;

    if ((me = myCache(xw, cgsWin, cgsId)) != NULL) {
	NEXT(bg) = bg;
	me->mask |= GCBackground;
	TRACE2(("setCgsBack(%s) %s\n",
		traceCgsEnum(cgsId),
		tracePixel(xw, NEXT(bg))));
    }
}

#if OPT_DEC_CHRSET
void
setCgsCSet(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId, unsigned cset)
{
    CgsCache *me;

    if ((me = myCache(xw, cgsWin, cgsId)) != NULL) {
	NEXT(cset) = cset;
	me->mask |= GC_CSet;
    }
}
#else
#define setCgsCSet(xw, cgsWin, dstCgsId, cset)	/* nothing */
#endif

void
setCgsFont2(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId, XTermFonts * font, unsigned which)
{
    CgsCache *me;

    if ((me = myCache(xw, cgsWin, cgsId)) != NULL) {
	TScreen *screen = TScreenOf(xw);
	if (!HaveFont(font)) {
	    if (cgsId != gcNorm)
		(void) getCgsGC(xw, cgsWin, gcNorm);
#ifndef NO_ACTIVE_ICON
	    if (cgsWin == &(TScreenOf(xw)->iconVwin))
		font = getIconicFont(screen);
	    else
#endif
		font = GetNormalFont(screen, which);
	}
	if (HaveFont(font) && okFont(font->fs)) {
	    TRACE2(("setCgsFont next: %s for %s slot %p, gc %p\n",
		    traceFont(font), traceCgsEnum(cgsId),
		    me, THIS(gc)));
	    TRACE2(("...next font was %s\n", traceFont(NEXT(font))));
	    NEXT(font) = font;
	    me->mask |= GCFont;
	} else {
	    /* EMPTY */
	    TRACE2(("...NOT updated font for %s\n",
		    traceCgsEnum(cgsId)));
	}
    }
}

void
setCgsFont(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId, XTermFonts * font)
{
    setCgsFont2(xw, cgsWin, cgsId, font, fNorm);
}

/*
 * Discard all of the font information, e.g., we are resizing the font.
 * Keep the GC's so we can simply change them rather than creating new ones.
 */
void
clrCgsFonts(XtermWidget xw, VTwin *cgsWin, XTermFonts * font)
{
    if (HaveFont(font)) {
	int j;
	for_each_gc(j) {
	    CgsCache *me;
	    if ((me = myCache(xw, cgsWin, (CgsEnum) j)) != NULL) {
		int k;
		for (k = 0; k < DEPTH; ++k) {
		    if (SameFont(LIST(k).font, font)) {
			TRACE2(("clrCgsFonts %s gc %p(%d) %s\n",
				traceCgsEnum((CgsEnum) j),
				LIST(k).gc,
				k,
				traceFont(font)));
			LIST(k).font = NULL;
			LIST(k).cset = 0;
		    }
		}
		if (SameFont(NEXT(font), font)) {
		    TRACE2(("clrCgsFonts %s next %s\n",
			    traceCgsEnum((CgsEnum) j),
			    traceFont(font)));
		    NEXT(font) = NULL;
		    NEXT(cset) = 0;
		    me->mask &= (unsigned) ~(GCFont | GC_CSet);
		}
	    }
	}
    }
}

/*
 * Return a GC associated with the given id, allocating if needed.
 */
GC
getCgsGC(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId)
{
    CgsCache *me;
    GC result = NULL;

    if ((me = myCache(xw, cgsWin, cgsId)) != NULL) {
	TRACE2(("getCgsGC(%s, %s)\n",
		traceVTwin(xw, cgsWin), traceCgsEnum(cgsId)));
	if (me->mask != 0) {
	    int j;
	    unsigned used = 0;

	    /* fill in the unchanged fields */
	    if (!(me->mask & GC_CSet))
		NEXT(cset) = 0;	/* OPT_DEC_CHRSET */
	    if (!(me->mask & GCFont))
		NEXT(font) = THIS(font);
	    if (!(me->mask & GCForeground))
		NEXT(fg) = THIS(fg);
	    if (!(me->mask & GCBackground))
		NEXT(bg) = THIS(bg);

	    if (NEXT(font) == NULL) {
		setCgsFont(xw, cgsWin, cgsId, NULL);
	    }

	    TRACE2(("...Cgs new data fg=%s, bg=%s, font=%s cset %s\n",
		    tracePixel(xw, NEXT(fg)),
		    tracePixel(xw, NEXT(bg)),
		    traceFont(NEXT(font)),
		    traceCSet(NEXT(cset))));

	    /* try to find the given data in an already-created GC */
	    for (j = 0; j < DEPTH; ++j) {
		if (LIST(j).gc != NULL
		    && SameFont(LIST(j).font, NEXT(font))
		    && SameCSet(LIST(j).cset, NEXT(cset))
		    && SameColor(LIST(j).fg, NEXT(fg))
		    && SameColor(LIST(j).bg, NEXT(bg))) {
		    LINK(j);
		    result = THIS(gc);
		    TRACE2(("getCgsGC existing %p(%d)\n", result, ITEM()));
		    break;
		}
	    }

	    if (result == NULL) {
		/* try to find an empty slot, to create a new GC */
		used = 0;
		for (j = 0; j < DEPTH; ++j) {
		    if (LIST(j).gc == NULL) {
			LINK(j);
			result = newCache(xw, cgsWin, cgsId, me);
			break;
		    }
		    if (used < LIST(j).used)
			used = LIST(j).used;
		}
	    }

	    if (result == NULL) {
		int k;
		/* if none were empty, pick the least-used slot, to modify */
		for (j = 0, k = -1; j < DEPTH; ++j) {
		    if (used >= LIST(j).used) {
			used = LIST(j).used;
			k = j;
		    }
		}
		if (k >= 0) {
		    LINK(k);
		    TRACE2(("...getCgsGC least-used(%d) was %d\n", k, THIS(used)));
		    result = chgCache(xw, cgsId, me, True);
		}
	    }
	    me->next = *(me->data);
	} else {
	    result = THIS(gc);
	}
	me->mask = 0;
	THIS(used) += 1;
	TRACE2(("...getCgsGC(%s, %s) gc %p(%d), used %d\n",
		traceVTwin(xw, cgsWin),
		traceCgsEnum(cgsId), result, ITEM(), THIS(used)));
    }
    return result;
}

/*
 * Return the font for the given GC.
 */
CgsEnum
getCgsId(XtermWidget xw, VTwin *cgsWin, GC gc)
{
    int n;
    CgsEnum result = gcNorm;

    for_each_gc(n) {
	CgsCache *me;

	if ((me = myCache(xw, cgsWin, (CgsEnum) n)) != NULL) {
	    if (THIS(gc) == gc) {
		result = (CgsEnum) n;
		break;
	    }
	}
    }
    return result;
}

/*
 * Return the font for the given GC.
 */
XTermFonts *
getCgsFont(XtermWidget xw, VTwin *cgsWin, GC gc)
{
    int n;
    XTermFonts *result = NULL;

    for_each_gc(n) {
	CgsCache *me;

	if ((me = myCache(xw, cgsWin, (CgsEnum) n)) != NULL) {
	    if (THIS(gc) == gc) {
		result = THIS(font);
		break;
	    }
	}
    }
    return result;
}

/*
 * Return the foreground color for the given GC.
 */
Pixel
getCgsFore(XtermWidget xw, VTwin *cgsWin, GC gc)
{
    int n;
    Pixel result = 0;

    for_each_gc(n) {
	CgsCache *me;

	if ((me = myCache(xw, cgsWin, (CgsEnum) n)) != NULL) {
	    if (THIS(gc) == gc) {
		result = THIS(fg);
		break;
	    }
	}
    }
    return result;
}

/*
 * Return the background color for the given GC.
 */
Pixel
getCgsBack(XtermWidget xw, VTwin *cgsWin, GC gc)
{
    int n;
    Pixel result = 0;

    for_each_gc(n) {
	CgsCache *me;

	if ((me = myCache(xw, cgsWin, (CgsEnum) n)) != NULL) {
	    if (THIS(gc) == gc) {
		result = THIS(bg);
		break;
	    }
	}
    }
    return result;
}

/*
 * Copy the parameters (except GC of course) from one cache record to another.
 */
void
copyCgs(XtermWidget xw, VTwin *cgsWin, CgsEnum dstCgsId, CgsEnum srcCgsId)
{
    if (dstCgsId != srcCgsId) {
	CgsCache *me;

	if ((me = myCache(xw, cgsWin, srcCgsId)) != NULL) {
	    TRACE(("copyCgs from %s to %s\n",
		   traceCgsEnum(srcCgsId),
		   traceCgsEnum(dstCgsId)));
	    TRACE2(("copyCgs from %s (me %p, fg %s, bg %s, cset %s) to %s "
		    TRACE_L "\n",
		    traceCgsEnum(srcCgsId),
		    me,
		    tracePixel(xw, THIS(fg)),
		    tracePixel(xw, THIS(bg)),
		    traceCSet(THIS(cset)),
		    traceCgsEnum(dstCgsId)));
	    setCgsCSet(xw, cgsWin, dstCgsId, THIS(cset));
	    setCgsFore(xw, cgsWin, dstCgsId, THIS(fg));
	    setCgsBack(xw, cgsWin, dstCgsId, THIS(bg));
	    setCgsFont(xw, cgsWin, dstCgsId, THIS(font));
	    TRACE2(("...copyCgs " TRACE_R "\n"));
	}
    }
}

/*
 * Interchange colors in the cache, e.g., for reverse-video.
 */
void
redoCgs(XtermWidget xw, Pixel fg, Pixel bg, CgsEnum cgsId)
{
    VTwin *cgsWin = WhichVWin(TScreenOf(xw));
    CgsCache *me = myCache(xw, cgsWin, cgsId);

    if (me != NULL) {
	CgsCacheData *save_data = me->data;
	int n;

	for (n = 0; n < DEPTH; ++n) {
	    if (LIST(n).gc != NULL && HaveFont(LIST(n).font)) {
		LINK(n);

		if (LIST(n).fg == fg
		    && LIST(n).bg == bg) {
		    setCgsFore(xw, cgsWin, cgsId, bg);
		    setCgsBack(xw, cgsWin, cgsId, fg);
		} else if (LIST(n).fg == bg
			   && LIST(n).bg == fg) {
		    setCgsFore(xw, cgsWin, cgsId, fg);
		    setCgsBack(xw, cgsWin, cgsId, bg);
		} else {
		    continue;
		}

		(void) chgCache(xw, cgsId, me, False);
	    }
	}
	me->data = save_data;
    }
}

/*
 * Swap the cache records, e.g., when doing reverse-video.
 */
void
swapCgs(XtermWidget xw, VTwin *cgsWin, CgsEnum dstCgsId, CgsEnum srcCgsId)
{
    if (dstCgsId != srcCgsId) {
	CgsCache *src;

	if ((src = myCache(xw, cgsWin, srcCgsId)) != NULL) {
	    CgsCache *dst;

	    if ((dst = myCache(xw, cgsWin, dstCgsId)) != NULL) {
		CgsCache tmp;
		int srcIndex = dataIndex(src);
		int dstIndex = dataIndex(dst);

		EXCHANGE(*src, *dst, tmp);

		relinkData(src, dstIndex);
		relinkData(dst, srcIndex);
	    }
	}
    }
}

/*
 * Free any GC associated with the given id.
 */
GC
freeCgs(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId)
{
    CgsCache *me;

    if ((me = myCache(xw, cgsWin, cgsId)) != NULL) {
	int j;

	for (j = 0; j < DEPTH; ++j) {
	    if (LIST(j).gc != NULL) {
		TRACE(("freeCgs(%s, %s) gc %p(%d)\n",
		       traceVTwin(xw, cgsWin),
		       traceCgsEnum(cgsId), (void *) LIST(j).gc, j));
		clrCgsFonts(xw, cgsWin, LIST(j).font);
#if OPT_BOX_CHARS
		if (cgsId == gcDots) {
		    XmuReleaseStippledPixmap(XtScreen((Widget) xw), LIST(j).tile);
		}
#endif
		XFreeGC(TScreenOf(xw)->display, LIST(j).gc);
		memset(&LIST(j), 0, sizeof(LIST(j)));
	    }
	    LINK(0);
	}
    }
    return NULL;
}

#ifdef NO_LEAKS
void
noleaks_cachedCgs(XtermWidget xw)
{
#ifndef NO_ACTIVE_ICON
    free(TScreenOf(xw)->icon_cgs_cache);
#endif
    free(TScreenOf(xw)->main_cgs_cache);
}
#endif
xterm-399/package/0000755000000000000000000000000014777541255012651 5ustar  rootrootxterm-399/package/freebsd/0000755000000000000000000000000014777541255014263 5ustar  rootrootxterm-399/package/freebsd/Makefile0000644000000000000000000000714514777541255015732 0ustar  rootroot# $XTermId: Makefile,v 1.121 2025/04/15 20:33:49 tom Exp $

# This is adapted from the FreeBSD port, installing as "xterm-dev" with
# separate resource- and manpage files.
# copy "xterm-${PORTVERSION}.tgz to the port's distfiles directory
# and "make makesum".

PORTNAME=	xterm
DISTVERSION=	399
CATEGORIES=	x11
MASTER_SITES=	https://invisible-island.net/archives/xterm/:src1 \
		https://invisible-mirror.net/archives/xterm/:src1
PKGNAMESUFFIX=	-dev
DISTFILES=	${DISTNAME}${EXTRACT_SUFX}:src1

MAINTAINER=	ehaupt@FreeBSD.org
COMMENT=	Terminal emulator for the X Window System
WWW=		https://invisible-island.net/xterm/

LICENSE=	MIT
LICENSE_FILE=	${WRKSRC}/COPYING

LIB_DEPENDS+=	libfontconfig.so:x11-fonts/fontconfig

USES=			cpe localbase ncurses tar:tgz xorg
CPE_VENDOR=		invisible-island
USE_XORG=		ice x11 xext xft xmu xpm xt
GNU_CONFIGURE=		yes
CONFIGURE_ARGS+=	--enable-narrowproto \
			--with-utempter

CPPFLAGS+=	-DPIXMAP_ROOTDIR=${LOCALBASE}/share/pixmaps

CONFLICTS=	x11iraf

OPTIONS_DEFINE=		256COLOR DABBREV DECTERM GNOME LOGGING LUIT PCRE2 REGIS \
			SCRNDUMP SIXEL TOOLBAR WCHAR XINERAMA
OPTIONS_DEFAULT=	256COLOR LUIT SIXEL WCHAR XAW
OPTIONS_SINGLE=		ATHENA
OPTIONS_SINGLE_ATHENA=	NEXTAW XAW XAW3D XAW3DXFT

256COLOR_DESC=	Enable 256-color support
DABBREV_DESC=	Enable support for dabbrev-expand
DECTERM_DESC=	Enable DECterm Locator support
LOGGING_DESC=	Enable logging terminal I/O to a file
LUIT_DESC=	Use LUIT for locale convertion from/to UTF-8
NEXTAW_DESC=	Link with neXT Athena library
PCRE2_DESC=	${PCRE_DESC} version 2
REGIS_DESC=	Enable ReGIS graphics support
SCRNDUMP_DESC=	Enable XHTML and SVG screen dumps
SIXEL_DESC=	Enable Sixel graphics support
TOOLBAR_DESC=	Enable pulldown menus with a toolbar
WCHAR_DESC=	Enable wide-character support
XAW3DXFT_DESC=	Link with Xaw 3d xft (extended fonts) library
XAW3D_DESC=	Link with Xaw 3d library
XAW_DESC=	Link with Xaw library

256COLOR_CONFIGURE_ENABLE=	256-color
DABBREV_CONFIGURE_ENABLE=	dabbrev
DECTERM_CONFIGURE_ENABLE=	dec-locator
GNOME_USES=			desktop-file-utils
LOGGING_CONFIGURE_ENABLE=	logging
LUIT_IMPLIES=			WCHAR
LUIT_BUILD_DEPENDS=		luit:x11/luit
LUIT_RUN_DEPENDS=		luit:x11/luit
LUIT_CONFIGURE_ENABLE=		luit
NEXTAW_LIB_DEPENDS=		libneXtaw.so:x11-toolkits/neXtaw
NEXTAW_CONFIGURE_WITH=		neXtaw
PCRE2_LIB_DEPENDS=		libpcre2-8.so:devel/pcre2
PCRE2_CONFIGURE_WITH=		pcre2
REGIS_CONFIGURE_ENABLE=		regis-graphics
SCRNDUMP_CONFIGURE_ENABLE=	screen-dumps
SIXEL_CONFIGURE_ENABLE=		sixel-graphics
TOOLBAR_CONFIGURE_ENABLE=	toolbar
WCHAR_LIB_DEPENDS=		libfreetype.so:print/freetype2
WCHAR_CONFIGURE_ENABLE=		wide-chars
WCHAR_VARS=			PKGMESSAGE="${PKGDIR}/pkg-message.wchar"
XAW3DXFT_LIB_DEPENDS=		libXaw3dxft.so:x11-toolkits/libxaw3dxft
XAW3DXFT_CONFIGURE_WITH=	Xaw3dxft
XAW3D_LIB_DEPENDS=		libXaw3d.so:x11-toolkits/Xaw3d
XAW3D_CONFIGURE_WITH=		Xaw3d
XAW_USE=			XORG=xaw
XINERAMA_USE=			XORG=xinerama,xorgproto
XINERAMA_CONFIGURE_OFF=		--without-xinerama

PKG_CLASS=	XTermDev

.include 

CONFIGURE_ARGS+=	--program-suffix=${PKGNAMESUFFIX} --with-app-class=${PKG_CLASS} --without-xterm-symlink

.if ! ${PORT_OPTIONS:MXAW3D} && ! ${PORT_OPTIONS:MXAW3DXFT} && ! ${PORT_OPTIONS:MNEXTAW}
USE_XORG+=	xaw
.endif

#ICONVERSION=	1
#
#post-extract:
#	@${CP} ${WRKDIR}/bsd-xterm-icons-${ICONVERSION}/*.png \
#		${WRKDIR}/bsd-xterm-icons-${ICONVERSION}/*.xpm \
#			${WRKSRC}/icons/

post-install:
.for f in koi8rxterm${PKGNAMESUFFIX} resize${PKGNAMESUFFIX} uxterm${PKGNAMESUFFIX} xterm${PKGNAMESUFFIX}
	@${CHMOD} ${BINMODE} ${STAGEDIR}${PREFIX}/bin/${f}
.endfor
	${INSTALL_DATA} ${WRKSRC}/xterm.desktop \
		${STAGEDIR}${PREFIX}/share/applications/xterm${PKGNAMESUFFIX}.desktop

.include 
xterm-399/package/freebsd/pkg-descr0000644000000000000000000000066614306206546016062 0ustar  rootrootThe xterm program is the standard terminal emulator for the X
Window System. It provides DEC VT102/VT220 and Tektronix 4014
compatible terminals for programs that can't use the window
system directly. If the underlying operating system supports
terminal resizing capabilities (for example, the SIGWINCH
signal in systems derived from 4.3bsd), xterm will use the
facilities to notify programs running in the window whenever it
is resized.
xterm-399/package/freebsd/distinfo0000644000000000000000000000042714723273004016011 0ustar  rootrootTIMESTAMP = 1733129732
SHA256 (xterm-396.tgz) = a1f6be14857a31c87722605ff7b4e7c8bb82ff4dce859abac85c085548e87153
SIZE (xterm-396.tgz) = 1585022
SHA256 (bsd-xterm-icons-1.tgz) = fcf51dce0e23e9911a16ed7f2ce835bb6ff2ada65f023c29fdd8abda2795bf7c
SIZE (bsd-xterm-icons-1.tgz) = 22718
xterm-399/package/freebsd/pkg-message.wchar0000644000000000000000000000077213524776720017516 0ustar  rootroot[
{ type: install
  message: <

All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the above listed
copyright holder(s) not be used in advertising or publicity pertaining
to distribution of the software without specific, written prior
permission.

THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.


-------------------------------------------------------------------------------
Files: xutf8.*
License: MIT-X11

Copyright (C) 2001 by Juliusz Chroboczek

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

-------------------------------------------------------------------------------
Files: ctlseqs.ms install-sh
License: MIT-X11

Copyright 1984-1994 X Consortium

-------------------------------------------------------------------------------
Copyright 1987,1988 by Digital Equipment Corporation, Maynard, Massachusetts.

All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Digital Equipment
Corporation not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

-------------------------------------------------------------------------------
Copyright 1988,1989  X Consortium

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the X Consortium.

-------------------------------------------------------------------------------
Files: koi8rxterm.man uxterm.man
License: MIT-X11

Copyright 2001, 2004 Branden Robinson

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
SOFTWARE IN THE PUBLIC INTEREST, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

-------------------------------------------------------------------------------
Files: charclass.*

Markus Kuhn -- 2000-07-03

Permission to use, copy, modify, and distribute this software
for any purpose and without fee is hereby granted. The author
disclaims all warranties with regard to this software.

-------------------------------------------------------------------------------
Files: wcwidth.c

Copyright 2002-2016,2017 by Thomas E. Dickey
Markus Kuhn -- 2007-05-25

Permission to use, copy, modify, and distribute this software
for any purpose and without fee is hereby granted. The author
disclaims all warranties with regard to this software.

-------------------------------------------------------------------------------
Files: config.guess config.sub
License: GPL-3

	Copyright 1992-2017 Free Software Foundation, Inc.

On Debian systems, see "/usr/share/common-licenses/GPL-3" for details.

-------------------------------------------------------------------------------
Files: configure
License: GPL-2

	Copyright 1992-2001 Free Software Foundation, Inc.

On Debian systems, see "/usr/share/common-licenses/GPL-2" for details.

-------------------------------------------------------------------------------
xterm-399/package/debian/xterm-dev.lintian-overrides0000644000000000000000000000052714412336611021352 0ustar  rootroot# Ignore this, but keep in mind:
#	https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=741573
#	https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=707851
xterm-dev: command-in-menu-file-and-desktop-file xterm-dev usr/share/menu/xterm-dev:7
xterm-dev: command-in-menu-file-and-desktop-file uxterm-dev usr/share/menu/xterm-dev:14

# vile: confmode
xterm-399/package/debian/xterm-dev.docs0000644000000000000000000000011213112654503016631 0ustar  rootrootREADME.i18n
THANKS
ctlseqs.ms
ctlseqs.txt
termcap
terminfo
xterm.log.html
xterm-399/package/debian/compat0000644000000000000000000000000314401761237015256 0ustar  rootroot12
xterm-399/package/debian/postinst0000644000000000000000000000053212424252524015662 0ustar  rootroot#! /bin/sh
echo "** postinst script for xterm: $*"

set -e

PRI=60
ALT=x-terminal-emulator
PKG=xterm-dev

BINDIR=/usr/bin
MANDIR=/usr/share/man/man1

if [ $1 != "upgrade" ]
then
	update-alternatives \
		--install \
			$BINDIR/$ALT $ALT \
			$BINDIR/$PKG $PRI \
		--slave $MANDIR/$ALT.1.gz $ALT.1.gz \
			$MANDIR/$PKG.1.gz
fi

#DEBHELPER#

exit 0
xterm-399/package/debian/prerm0000644000000000000000000000026712424250520015123 0ustar  rootroot#! /bin/sh
echo "** prerm script for xterm: $*"

set -e

if [ "x$1" != "xupgrade" ]; then
	update-alternatives --remove x-terminal-emulator /usr/bin/xterm-dev
fi

#DEBHELPER#

exit 0
xterm-399/package/debian/rules0000755000000000000000000001127114723204544015141 0ustar  rootroot#!/usr/bin/make -f
# Made with the aid of dh_make, by Craig Small
# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess.
# Some lines taken from debmake, by Cristoph Lameter.

# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1

SHELL = /bin/bash
DPKG_EXPORT_BUILDFLAGS = 1
export DEB_BUILD_MAINT_OPTIONS := hardening=+all qa=+bug reproducible=+all

include /usr/share/dpkg/buildflags.mk

# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)

DESKTOP_VENDOR  = dickey

PKG_SUFFIX	= -dev
PKG_CLASS	= XTermDev

PACKAGE		:= $(shell dpkg-parsechangelog| \
			sed -n 's/^Source: \(.*\)$$/\1/p')

PKG_APPDEFAULTS	:= /etc/X11/app-defaults
PKG_DESKTOP	:= /usr/share/applications

DSTDIR		:= $(CURDIR)/debian/$(PACKAGE)
MY_DESKTOP	:= $(DSTDIR)/usr/share/applications

ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
DEBOP=--enable-debug
else
DEBOP=
endif

ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
        CFLAGS += -O0
else
        CFLAGS += -O2
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
        INSTALL_PROGRAM += -s
endif

configure_flags = \
	--host=$(DEB_HOST_GNU_TYPE) \
	--build=$(DEB_BUILD_GNU_TYPE) \
	--program-suffix=$(PKG_SUFFIX) \
	--prefix=/usr \
	--libexecdir=\$${prefix}/lib \
	--mandir=\$${prefix}/share/man \
	--sysconfdir=/etc/$(PACKAGE) \
	--localstatedir=/var \
	--libdir=/etc/$(PACKAGE) \
	--with-app-class=$(PKG_CLASS) \
	--without-xterm-symlink \
	--disable-imake \
	--enable-dabbrev \
	--enable-dec-locator \
	--enable-exec-xterm \
	--enable-hp-fkeys \
	--enable-load-vt-fonts \
	--enable-logfile-exec \
	--enable-logging \
	--enable-mini-luit \
	--enable-regis-graphics \
	--enable-sco-fkeys \
	--enable-status-line \
	--enable-toolbar \
	--enable-xmc-glitch \
	--with-app-defaults=$(PKG_APPDEFAULTS) \
	--with-icondir=\$${prefix}/share/icons \
	--with-pixmapdir=\$${prefix}/share/pixmaps \
	--with-own-terminfo=\$${prefix}/share/terminfo \
	--with-icon-theme \
	--with-terminal-type=xterm-new \
	--with-utempter \
	--with-icon-name=mini.xterm \
	--with-xpm ${DEBOP}

configure: configure-stamp
configure-stamp:
	dh_testdir

	# Update config.guess, config.sub
	dh_update_autotools_config

	# Configure xterm-dev
	dh_auto_configure -- $(configure_flags)

	touch configure-stamp

build: build-stamp
build-stamp: configure-stamp
	dh_testdir

	$(MAKE)

	touch build-stamp

clean:
	dh_testdir
	dh_testroot

	[ ! -f Makefile ] || $(MAKE) distclean

	dh_clean

install: install-stamp
install-stamp: build-stamp
	dh_testdir
	dh_testroot
	dh_prep
	dh_installdirs

	$(MAKE) install \
		DESTDIR=$(CURDIR)/debian/$(PACKAGE)

	touch install-stamp

install: install-indep install-arch
install-indep:

install-arch:
	dh_testdir
	dh_testroot
	dh_prep -a
	dh_installdirs -a

	$(MAKE) install-bin \
		DESTDIR=$(DSTDIR)

# Build architecture-independent files here.
binary-indep: build install
	dh_testdir
	dh_testroot

	# This overwrites the Debian package's copy of app-defaults and icons.
	# But the resources are not the same; they are patched.
	sed -i -f package/debian/color.sed XTerm-col.ad
	sed -i -f package/debian/xterm-xres.sed XTerm.ad

	$(MAKE) install-app \
		install-icon \
		install-man \
		DESTDIR=$(DSTDIR)

	# Follow-up with a check against the installed resource files.
	( cd $(DSTDIR)$(PKG_APPDEFAULTS) \
	  && $(SHELL) -c 'for p in *; do \
	  	test -f $(PKG_APPDEFAULTS)/$$p && \
	  	diff -u $(PKG_APPDEFAULTS)/$$p $$p; \
		done' ; \
	  exit 0 )

	# The Debian package stopped installing xterm's desktop files; a
	# subsequent revision added that back with limitations.  xterm's
	# configure script checks for categories which are used by other
	# terminal emulators.  The Debian package overrides that to a single
	# category.
	# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=486317
	$(MAKE) install-desktop \
		DESKTOP_FLAGS="--dir $(MY_DESKTOP)"

	( cd $(DSTDIR)$(PKG_DESKTOP) \
	  && $(SHELL) -c 'for p in *;do \
	  	test -f $(PKG_DESKTOP)/$$p && \
		diff -u $(PKG_DESKTOP)/$$p $$p; \
	  	test -n "$(PKG_SUFFIX)" && mv $$p `basename $$p .desktop`$(PKG_SUFFIX).desktop; \
		done' ; \
	  exit 0 )

	dh_icons

# Build architecture-dependent files here.
binary-arch: build install
	dh_testdir
	dh_testroot
	dh_installdebconf
	dh_lintian
	dh_installdocs
	dh_installmenu
	dh_installmime
	dh_installexamples tektests vttests
	dh_installchangelogs
	dh_install
	dh_link
	dh_strip
	dh_compress -Xexamples
	dh_fixperms
	dh_installdeb
	dh_shlibdeps
	dh_gencontrol
	dh_md5sums
	dh_builddeb

binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install install-stamp
xterm-399/package/debian/xterm-dev.menu0000644000000000000000000000076213112654236016663 0ustar  rootroot?package(xterm-dev):\
 needs="x11"\
 section="Applications/Terminal Emulators"\
 longtitle="XTerm: terminal emulator for X (development)"\
 title="XTermDev"\
 icon="/usr/share/pixmaps/xterm-dev-color_32x32.xpm"\
 command="xterm-dev"
?package(xterm-dev):\
 needs="x11"\
 section="Applications/Terminal Emulators"\
 longtitle="XTerm: terminal emulator for X with Unicode support (development)"\
 title="XTermDev (Unicode)"\
 icon="/usr/share/pixmaps/xterm-dev-color_32x32.xpm"\
 command="uxterm-dev"
xterm-399/package/debian/control0000644000000000000000000000213414723201633015456 0ustar  rootrootSource: xterm-dev
Section: x11
Priority: optional
Maintainer: Thomas E. Dickey 
Homepage: https://invisible-island.net/xterm/
Build-Depends: debhelper (>= 7), xorg-docs-core, libxft-dev, libxpm-dev, libxaw7-dev, libutempter-dev
Standards-Version: 3.8.2

Package: xterm-dev
Architecture: any
Depends: xbitmaps, libc6 (>= 2.7), libfontconfig1, libice6 (>= 1:1.0.0), libutempter0 (>= 1.1.5), libx11-6, libxaw7, libxft2 (>> 2.1.1), libxmu6, libxt6
Provides: x-terminal-emulator
Recommends: xfonts-75dpi, xfonts-base, x11-utils | luit | bluit
Description: X terminal emulator (development version)
 xterm is the standard terminal emulator for the X Window System.
 It provides DEC VT102 and Tektronix 4014 compatible terminals for
 programs that cannot use the window system directly.  This version
 implements ISO/ANSI colors, Unicode, and most of the control sequences
 used by DEC VT220 terminals.
 .
 This package contains a development version of xterm.  It is
 configured to use "xterm-dev" and "XTermDev" for the program
 and its resource class, to avoid conflict with other packages.
xterm-399/package/debian/xterm-xres.sed0000644000000000000000000000026312015672076016674 0ustar  rootroot/\*tek4014\*fontSmall:[ 	]*6x10/a\
\
! Debian package customizations follow.\
*backarrowKeyIsErase: true\
*ptyInitialErase: true
/!*allowWindowOps: false/a\
*allowWindowOps: true
xterm-399/package/debian/source/0000755000000000000000000000000011410226414015345 5ustar  rootrootxterm-399/package/debian/source/format0000644000000000000000000000001511410226414016554 0ustar  rootroot3.0 (native)
xterm-399/package/debian/watch0000644000000000000000000000014613142442262015104 0ustar  rootrootversion=3

opts=passive ftp://ftp.invisible-island.net/xterm/current/xterm\.tar.gz \
 debian  uupdate
xterm-399/package/debian/changelog0000644000000000000000000005012214777541255015745 0ustar  rootrootxterm-dev (399) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 15 Apr 2025 16:33:49 -0400

xterm-dev (398) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 07 Jan 2025 16:30:14 -0500

xterm-dev (397) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 04 Dec 2024 16:54:33 -0500

xterm-dev (396) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 20 Nov 2024 16:39:31 -0500

xterm-dev (395) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 11 Sep 2024 03:48:16 -0400

xterm-dev (394) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Fri, 09 Aug 2024 14:18:03 -0400

xterm-dev (393) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sat, 25 May 2024 09:03:00 -0400

xterm-dev (392) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 15 May 2024 16:52:03 -0400

xterm-dev (391) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 16 Apr 2024 03:51:06 -0400

xterm-dev (390) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 11 Jan 2024 16:18:30 -0500

xterm-dev (389) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 12 Nov 2023 16:48:50 -0500

xterm-dev (388) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Fri, 20 Oct 2023 16:43:09 -0400

xterm-dev (387) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 10 Oct 2023 20:02:59 -0400

xterm-dev (386) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 02 Oct 2023 17:19:01 -0400

xterm-dev (385) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 13 Jul 2023 14:57:11 -0400

xterm-dev (384) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 29 Jun 2023 18:22:58 -0400

xterm-dev (383) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 31 May 2023 13:04:55 -0400

xterm-dev (382) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 29 May 2023 07:15:40 -0400

xterm-dev (381) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 28 May 2023 04:34:22 -0400

xterm-dev (380) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 26 Feb 2023 20:00:24 -0500

xterm-dev (379) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 24 Jan 2023 20:14:44 -0500

xterm-dev (378) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sat, 26 Nov 2022 07:25:02 -0500

xterm-dev (377) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 20 Nov 2022 19:18:58 -0500

xterm-dev (376) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 30 Oct 2022 06:48:25 -0400

xterm-dev (375) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 20 Oct 2022 20:45:30 -0400

xterm-dev (374) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 27 Sep 2022 04:18:41 -0400

xterm-dev (373) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Fri, 11 Mar 2022 14:51:56 -0500

xterm-dev (372) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Fri, 04 Mar 2022 16:37:03 -0500

xterm-dev (371) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 25 Nov 2021 17:42:23 -0500

xterm-dev (370) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 22 Sep 2021 18:23:43 -0400

xterm-dev (369) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 10 Jun 2021 04:13:52 -0400

xterm-dev (368) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 27 Apr 2021 20:02:52 -0400

xterm-dev (367) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 22 Feb 2021 16:18:59 -0500

xterm-dev (366) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 08 Feb 2021 15:30:49 -0500

xterm-dev (365) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 03 Feb 2021 15:56:34 -0500

xterm-dev (364) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 27 Dec 2020 07:20:40 -0500

xterm-dev (363) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 15 Nov 2020 11:38:35 -0500

xterm-dev (362) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 18 Oct 2020 06:27:36 -0400

xterm-dev (361) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sat, 26 Sep 2020 08:39:10 -0400

xterm-dev (360) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 18 Aug 2020 16:53:17 -0400

xterm-dev (359) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sat, 25 Jul 2020 13:48:12 -0400

xterm-dev (358) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 05 Jul 2020 20:35:21 -0400

xterm-dev (357) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 18 May 2020 16:21:11 -0400

xterm-dev (356) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sat, 02 May 2020 06:19:22 -0400

xterm-dev (355) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 27 Apr 2020 14:58:28 -0400

xterm-dev (354) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Fri, 28 Feb 2020 19:23:02 -0500

xterm-dev (353) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sat, 18 Jan 2020 10:53:11 -0500

xterm-dev (352) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 18 Nov 2019 04:22:56 -0500

xterm-dev (351) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 04 Nov 2019 16:16:46 -0500

xterm-dev (350) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 23 Sep 2019 16:16:38 -0400

xterm-dev (349) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 23 Jul 2019 16:06:11 -0400

xterm-dev (348) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 30 Jun 2019 20:15:46 -0400

xterm-dev (347) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 28 May 2019 20:19:05 -0400

xterm-dev (346) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 19 May 2019 04:44:47 -0400

xterm-dev (345) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 26 Feb 2019 17:33:30 -0500

xterm-dev (344) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 14 Jan 2019 13:12:18 -0500

xterm-dev (343) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 07 Jan 2019 18:09:07 -0500

xterm-dev (342) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 01 Jan 2019 12:29:29 -0500

xterm-dev (341) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 18 Dec 2018 05:25:26 -0500

xterm-dev (340) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 13 Dec 2018 19:11:25 -0500

xterm-dev (339) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 10 Dec 2018 19:01:55 -0500

xterm-dev (338) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 23 Sep 2018 12:47:17 -0400

xterm-dev (337) unstable; urgency=low

  * errata from #336

 -- Thomas E. Dickey   Thu, 20 Sep 2018 17:28:53 -0400

xterm-dev (336) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 16 Aug 2018 04:47:52 -0400

xterm-dev (335) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 13 Aug 2018 16:24:45 -0400

xterm-dev (334) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Fri, 04 May 2018 17:08:25 -0400

xterm-dev (333) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 15 Apr 2018 20:46:52 -0400

xterm-dev (332) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 01 Jan 2018 11:13:30 -0500

xterm-dev (331) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 08 Aug 2017 19:08:43 -0400

xterm-dev (330) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 12 Jun 2017 17:34:51 -0400

xterm-dev (329) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 04 Jun 2017 09:40:17 -0400

xterm-dev (328) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 24 Oct 2016 18:07:15 -0400

xterm-dev (327) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 02 Oct 2016 19:18:09 -0400

xterm-dev (326) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 07 Sep 2016 21:12:23 -0400

xterm-dev (325) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 12 May 2016 19:25:56 -0400

xterm-dev (324) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 10 Mar 2016 19:19:50 -0500

xterm-dev (323) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 27 Jan 2016 04:48:15 -0500

xterm-dev (322) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sat, 02 Jan 2016 08:42:56 -0500

xterm-dev (321) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sun, 27 Sep 2015 19:17:50 -0400

xterm-dev (320) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 26 Aug 2015 17:52:20 -0400

xterm-dev (319) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 22 Apr 2015 20:44:42 -0400

xterm-dev (318) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 06 Apr 2015 06:31:31 -0400

xterm-dev (317) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Fri, 20 Mar 2015 19:54:44 -0400

xterm-dev (316) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 05 Mar 2015 15:52:55 -0500

xterm-dev (315) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Fri, 02 Jan 2015 07:49:44 -0500

xterm-dev (314) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 01 Dec 2014 04:54:46 -0500

xterm-dev (313) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 06 Oct 2014 05:26:37 -0400

xterm-dev (312) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Fri, 26 Sep 2014 18:42:15 -0400

xterm-dev (311) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 28 Jul 2014 17:36:30 -0400

xterm-dev (310) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 14 Jul 2014 19:36:58 -0400

xterm-dev (309) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sat, 28 Jun 2014 10:34:28 -0400

xterm-dev (308) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Thu, 19 Jun 2014 15:58:13 -0400

xterm-dev (307) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 04 Jun 2014 18:58:36 -0400

xterm-dev (306) unstable; urgency=low

  * fix incomplete implementation of new SGRs

 -- Thomas E. Dickey   Tue, 03 Jun 2014 16:25:02 -0400

xterm-dev (305) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Mon, 05 May 2014 14:51:42 -0400

xterm-dev (304) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Wed, 09 Apr 2014 20:27:40 -0400

xterm-dev (303) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Tue, 04 Mar 2014 17:46:25 -0500

xterm-dev (302) unstable; urgency=low

  * maintenance updates

 -- Thomas E. Dickey   Sat, 15 Feb 2014 16:19:35 -0500

xterm-dev (301) unstable; urgency=high

  * miscellaneous fixes

 -- Thomas E. Dickey   Mon, 09 Dec 2013 07:59:24 -0500

xterm-dev (300) unstable; urgency=high

  * fix a regression from #298 changes

 -- Thomas E. Dickey   Tue, 03 Dec 2013 18:59:58 -0500

xterm-dev (299) unstable; urgency=low

  * fix remaining regression from #297 changes

 -- Thomas E. Dickey   Sun, 01 Dec 2013 11:48:42 -0500

xterm-dev (298) unstable; urgency=low

  * miscellaneous fixes

 -- Thomas E. Dickey   Wed, 11 Sep 2013 17:16:37 -0400

xterm-dev (297) unstable; urgency=low

  * miscellaneous fixes for old issues

 -- Thomas E. Dickey   Sun, 04 Aug 2013 08:58:31 -0400

xterm-dev (296) unstable; urgency=low

  * Build-fix for #295 changes

 -- Thomas E. Dickey   Tue, 09 Jul 2013 21:20:04 -0400

xterm-dev (295) unstable; urgency=low

  * Workaround for problem with ld --as-needed option

 -- Thomas E. Dickey   Sat, 06 Jul 2013 21:20:33 -0400

xterm-dev (294) unstable; urgency=low

  * Add experimental support for sixel graphics

 -- Thomas E. Dickey   Sun, 23 Jun 2013 10:36:52 -0400

xterm-dev (293) unstable; urgency=low

  * Miscellaneous fixes.

 -- Thomas E. Dickey   Wed, 08 May 2013 18:29:21 -0400

xterm-dev (292) unstable; urgency=low

  * Miscellaneous fixes.

 -- Thomas E. Dickey   Tue, 26 Mar 2013 19:11:17 -0400

xterm-dev (291) unstable; urgency=low

  * Fix a different #282 change (Redhat #874327).

 -- Thomas E. Dickey   Tue, 26 Feb 2013 19:09:32 -0500

xterm-dev (290) unstable; urgency=low

  * Fix incomplete revert of #282 change.

 -- Thomas E. Dickey   Tue, 12 Feb 2013 19:48:21 -0500

xterm-dev (289) unstable; urgency=low

  * Miscellaneous fixes.
  * Fix regression with XTERM_SHELL feature.

 -- Thomas E. Dickey   Sun, 03 Feb 2013 13:59:20 -0500

xterm-dev (288) unstable; urgency=low

  * Miscellaneous fixes.

 -- Thomas E. Dickey   Mon, 26 Nov 2012 20:53:23 -0500

xterm-dev (287) unstable; urgency=low

  * Miscellaneous fixes.
  * Redhat #874327, #875305.

 -- Thomas E. Dickey   Mon, 19 Nov 2012 04:53:39 -0500

xterm-dev (286) unstable; urgency=low

  * Redhat #869959

 -- Thomas E. Dickey   Thu, 25 Oct 2012 06:56:35 -0400

xterm-dev (285) unstable; urgency=low

  * Miscellaneous fixes.

 -- Thomas E. Dickey   Mon, 15 Oct 2012 06:57:38 -0400

xterm-dev (284) unstable; urgency=low

  * fix documentation errata
  * fix regression in --enable-regex

 -- Thomas E. Dickey   Wed, 10 Oct 2012 18:17:35 -0400

xterm-dev (283) unstable; urgency=low

  * Miscellaneous fixes.

 -- Thomas E. Dickey   Mon, 01 Oct 2012 20:45:50 -0400

xterm-dev (282) unstable; urgency=low

  * Miscellaneous fixes.

 -- Thomas E. Dickey   Mon, 20 Aug 2012 17:55:32 -0400

xterm-dev (281) unstable; urgency=low

  * fix regression in keyboard configuration.

 -- Thomas E. Dickey   Tue, 26 Jun 2012 04:36:36 -0400

xterm-dev (280) unstable; urgency=low

  * Add Debian menu-file.
  * modify to support icon-theme
  * Miscellaneous fixes.

 -- Thomas E. Dickey   Fri, 25 May 2012 05:36:50 -0400

xterm-dev (279) unstable; urgency=low

  * Miscellaneous fixes.

 -- Thomas E. Dickey   Wed, 14 Mar 2012 20:33:27 -0400

xterm-dev (278) unstable; urgency=low

  * Fix regression in eightBitInput logic.
  * Fix regression in Darwin 9.x

 -- Thomas E. Dickey   Thu, 12 Jan 2012 08:10:50 -0500

xterm-dev (277) unstable; urgency=low

  * Minor keyboard fix.

 -- Thomas E. Dickey   Tue, 11 Oct 2011 20:12:14 -0400

xterm-dev (276) unstable; urgency=low

  * Regressions in #272, #274.

 -- Thomas E. Dickey   Wed, 28 Sep 2011 17:34:20 -0400

xterm-dev (275) unstable; urgency=low

  * Regressions in #272, #274.

 -- Thomas E. Dickey   Sun, 11 Sep 2011 09:46:57 -0400

xterm-dev (274) unstable; urgency=low

  * Various build-fixes.

 -- Thomas E. Dickey   Sun, 28 Aug 2011 20:07:29 -0400

xterm-dev (273) unstable; urgency=low

  * Build-fixes/regressions from #272.

 -- Thomas E. Dickey   Thu, 25 Aug 2011 05:42:58 -0400

xterm-dev (272) unstable; urgency=low

  * Build-fix for termcap systems.

 -- Thomas E. Dickey   Fri, 15 Jul 2011 20:41:30 -0400

xterm-dev (271) unstable; urgency=low

  * Ubuntu #756273 (accommodate function keys as popup-menu triggers)

 -- Thomas E. Dickey   Fri, 29 Apr 2011 20:30:29 -0400

xterm-dev (270) unstable; urgency=low

  * more fixes for fullscreen toggle.

 -- Thomas E. Dickey   Sun, 20 Mar 2011 14:53:54 -0400

xterm-dev (269) unstable; urgency=low

  * amend translations for fullscreen toggle.

 -- Thomas E. Dickey   Sun, 13 Feb 2011 19:20:48 -0500

xterm-dev (268) unstable; urgency=low

  * build-fixes, etc.

 -- Thomas E. Dickey   Wed, 24 Nov 2010 06:17:16 -0500

xterm-dev (267) unstable; urgency=low

  * build-fixes, etc.

 -- Thomas E. Dickey   Wed, 10 Nov 2010 18:46:41 -0500

xterm-dev (266) unstable; urgency=low

  * add build-script for testing, adapted from Debian xterm package.

 -- Thomas E. Dickey   Fri, 22 Oct 2010 17:15:59 -0400
xterm-399/package/xterm.spec0000644000000000000000000002111114777541255014660 0ustar  rootroot# $XTermId: xterm.spec,v 1.180 2025/04/15 20:33:49 tom Exp $
Summary: X terminal emulator (development version)
%global my_middle xterm
%global my_suffix -dev
%global fullname %{my_middle}%{my_suffix}
%global my_class XTermDev
Name: %{fullname}
Version: 399
Release: 1
License: X11
Group: User Interface/X
Source: https://invisible-island.net/archives/xterm/xterm-%{version}.tgz
URL: https://invisible-island.net/xterm/
Provides: x-terminal-emulator >= %{version}

# Using "find-xterm-fonts" gives these package names:
#
# fedora:
#     xorg-x11-fonts-misc
# mageia:
#     x11-font-adobe-75dpi
#     x11-font-misc-misc
# opensuse:
#     efont-unicode-bitmap-fonts
#     xorg-x11-fonts-core
#     xorg-x11-fonts-legacy

# Library dependencies (chiefly Xft and Xpm) are similar across my test
# machines for mageia/fedora/opensuse, but package names vary:
#
# fedora:
#     libXft            libXft-devel
#     libXpm            libXpm-devel
#     libutempter       libutempter-devel
#     ncurses-libs      ncurses-devel
# mageia
#     lib64xft2         lib64xft-devel
#     lib64xpm4         lib64xpm-devel
#     lib64utempter0    lib64utempter-devel
#     lib64ncurses6     lib64ncurses-devel
# opensuse
#     libXft2           libXft-devel
#     libXpm4           libXpm-devel
#     libutempter0      utempter-devel
#     libncurses6       ncurses-devel

# This part (the build-requires) would be useful if the various distributions
# had provided stable package-naming, or virtual packages to cover transitions. 
# However, they have not done this in the past.
%define use_x_manpage %(test "x$_use_x_manpage" = xyes && echo 1 || echo 0)
%if "%{use_x_manpage}"

%global is_mandriva %(test -f /etc/mandriva-release && echo %{use_x_manpage} || echo 0)
%global is_redhat   %(test -f /etc/redhat-release && echo %{use_x_manpage} || echo 0)
%global is_suse     %(test -f /etc/SuSE-release && echo %{use_x_manpage} || echo 0)

%if %{is_mandriva}
BuildRequires: x11-docs
%else
%if %{is_redhat}
# missing in Fedora 37:
## BuildRequires: xorg-x11-docs
BuildRequires: ncurses-devel
%else
%if %{is_suse}
BuildRequires: xorg-docs
%endif
%endif
%endif

%endif

%description
xterm is the standard terminal emulator for the X Window System.
It provides DEC VT102 and Tektronix 4014 compatible terminals for
programs that cannot use the window system directly.  This version
implements ISO/ANSI colors, Unicode, and most of the control sequences
used by DEC VT220 terminals.

This package provides four commands:
 a) %{fullname}, which is the actual terminal emulator
 b) u%{fullname}, which is a wrapper around %{fullname}
    which sets %{fullname} to use UTF-8 encoding when
    the user's locale supports this,
 c) koi8r%{fullname}, a wrapper similar to u%{fullname}
    for locales that use the KOI8-R character set, and
 d) resize%{my_suffix}.

A complete list of control sequences supported by the X terminal emulator
is provided in /usr/share/doc/%{fullname}.

The %{fullname} program uses bitmap images provided by the xbitmaps package.

Those interested in using koi8r%{fullname} will likely want to install the
xfonts-cyrillic package as well.

This package is configured to use "%{fullname}" and "%{my_class}"
for the program and its resource class, to avoid conflict with other packages.

%prep

%global target_appdata %{fullname}.appdata.xml

%define desktop_utils   %(if which desktop-file-install 2>&1 >/dev/null ; then echo 1 || echo 0 ; fi)
%define icon_theme  %(test -d /usr/share/icons/hicolor && echo 1 || echo 0)
%define apps_x11r6  %(test -d /usr/X11R6/lib/X11/app-defaults && echo 1 || echo 0)
%define apps_shared %(test -d /usr/share/X11/app-defaults && echo 1 || echo 0)
%define apps_syscnf %(test -d /etc/X11/app-defaults && echo 1 || echo 0)

%if %{apps_x11r6}
%define _xresdir    %{_prefix}/X11R6/lib/X11/app-defaults
%else
%if %{apps_shared}
%define _xresdir    %{_datadir}/X11/app-defaults
%else
%define _xresdir    %{_sysconfdir}/X11/app-defaults
%endif
%endif

%define _iconsdir   %{_datadir}/icons
%define _pixmapsdir %{_datadir}/pixmaps
%define my_docdir   %{_datadir}/doc/%{fullname}

# no need for debugging symbols...
%define debug_package %{nil}

%setup -q -n xterm-%{version}

%build
CPPFLAGS="-DMISC_EXP -DEXP_HTTP_HEADERS" \
%configure \
        --target %{_target_platform} \
        --prefix=%{_prefix} \
        --bindir=%{_bindir} \
        --datadir=%{_datadir} \
        --mandir=%{_mandir} \
%if "%{my_suffix}" != ""
        --program-suffix=%{my_suffix} \
        --without-xterm-symlink \
%endif
%if "%{icon_theme}"
        --with-icon-symlink=%{fullname} \
        --with-icon-theme \
        --with-icondir=%{_iconsdir} \
%endif
        --with-app-class=%{my_class} \
        --disable-imake \
        --enable-dabbrev \
        --enable-dec-locator \
        --enable-exec-xterm \
        --enable-hp-fkeys \
        --enable-load-vt-fonts \
        --enable-logfile-exec \
        --enable-logging \
        --enable-mini-luit \
        --enable-regis-graphics \
        --enable-sco-fkeys \
        --enable-toolbar \
        --enable-xmc-glitch \
        --with-app-defaults=%{_xresdir} \
        --with-pixmapdir=%{_pixmapsdir} \
        --with-own-terminfo=%{_datadir}/terminfo \
        --with-terminal-type=xterm-new \
        --with-utempter \
        --with-icon-name=mini.xterm \
        --with-xpm
make

chmod u+w XTerm.ad
cat >>XTerm.ad <xterm\.desktop%{fullname}.desktopXTerm%{my_class} xterm.1.tbl && mv xterm.1.tbl xterm.1

.include "options.mk"

.include "../../mk/curses.buildlink3.mk"
.include "../../mk/termcap.buildlink3.mk"
.include "../../sysutils/desktop-file-utils/desktopdb.mk"
.include "../../mk/xaw.buildlink3.mk"
.include "../../mk/bsd.pkg.mk"
xterm-399/package/pkgsrc/DESCR0000644000000000000000000000053207407401151014703 0ustar  rootrootThe xterm program is a terminal emulator for the X Window System.  It provides
DEC VT102 and Tektronix 4014 compatible terminals for programs that can't use
the window system directly.

This version implements ISO/ANSI colors using the "new" color model
(i.e., background color erase). It also implements most of the control
sequences for VT220.
xterm-399/package/pkgsrc/distinfo0000644000000000000000000000052314736603071015672 0ustar  rootroot$NetBSD: distinfo,v 1.115 2024/10/27 05:42:46 pin Exp $

BLAKE2s (xterm-397.tgz) = 184268b9344b10846f2ce8291286ad0e88dd3ea221962bff6248508922367587
SHA512 (xterm-397.tgz) = eea89645bc772072e2313423441d104c9dfba584eb2f76adbb1e68e7a3bc27ba69cf9fbbfae6b35dcad51c089bcf31cdbaf4f391e753137d5f6ba8ef913f34e3
Size (xterm-397.tgz) = 1588379 bytes
xterm-399/package/pkgsrc/PLIST0000644000000000000000000000153014437402263014743 0ustar  rootroot@comment $NetBSD: PLIST,v 1.10 2023/06/05 15:52:19 wiz Exp $
bin/koi8rxterm
bin/resize
bin/uxterm
bin/xterm
lib/X11/app-defaults/KOI8RXTerm
lib/X11/app-defaults/KOI8RXTerm-color
lib/X11/app-defaults/UXTerm
lib/X11/app-defaults/UXTerm-color
lib/X11/app-defaults/XTerm
lib/X11/app-defaults/XTerm-color
man/man1/koi8rxterm.1
man/man1/resize.1
man/man1/uxterm.1
man/man1/xterm.1
share/applications/uxterm.desktop
share/applications/xterm.desktop
share/pixmaps/filled-xterm_16x16.xpm
share/pixmaps/filled-xterm_32x32.xpm
share/pixmaps/filled-xterm_48x48.xpm
share/pixmaps/mini.xterm_16x16.xpm
share/pixmaps/mini.xterm_32x32.xpm
share/pixmaps/mini.xterm_48x48.xpm
share/pixmaps/xterm-color_16x16.xpm
share/pixmaps/xterm-color_32x32.xpm
share/pixmaps/xterm-color_48x48.xpm
share/pixmaps/xterm_16x16.xpm
share/pixmaps/xterm_32x32.xpm
share/pixmaps/xterm_48x48.xpm
xterm-399/package/pkgsrc/options.mk0000644000000000000000000000265413557515155016170 0ustar  rootroot# $NetBSD: options.mk,v 1.15 2019/11/03 09:14:21 rillig Exp $

PKG_OPTIONS_VAR=		PKG_OPTIONS.xterm
PKG_SUPPORTED_OPTIONS=		debug pcre freetype luit xpm xterm-toolbar
PKG_SUGGESTED_OPTIONS=		freetype luit xpm

.include "../../mk/bsd.options.mk"

.if !empty(PKG_OPTIONS:Mdebug)
CONFIGURE_ARGS+=	--enable-trace
CONFIGURE_ARGS+=	--enable-warnings
.elif defined(PKG_DEVELOPER) && !empty(PKG_DEVELOPER:M[Yy][Ee][Ss])
CONFIGURE_ARGS+=	--enable-warnings
.endif

.if !empty(PKG_OPTIONS:Mfreetype)
CONFIGURE_ARGS+=	--enable-freetype
.  include "../../x11/libXft/buildlink3.mk"
.else
CONFIGURE_ARGS+= --disable-freetype
.endif
###
### XXX The configure test checks for pcreposix_regcomp in libpcreposix.
###	However, there is no such function [insofar as I can tell].
###	Moreover, libc's regex(3) functions are weak-aliased to those
###     within libc's namespace, so we should have no problems.
###
.if !empty(PKG_OPTIONS:Mpcre)
CONFIGURE_ARGS+=	--with-pcre
CONFIGURE_ENV+=		ac_cv_lib_pcreposix_pcreposix_regcomp=yes
.  include "../../devel/pcre/buildlink3.mk"
.endif

.if !empty(PKG_OPTIONS:Mluit)
DEPENDS+=		luit-[0-9]*:../../x11/luit
CONFIGURE_ARGS+=	--enable-luit --enable-mini-luit
.else
CONFIGURE_ARGS+=	--disable-luit --disable-mini-luit
.endif

.if !empty(PKG_OPTIONS:Mxpm)
### nothing
.else
CONFIGURE_ARGS+=	--without-xpm
.endif

.if !empty(PKG_OPTIONS:Mxterm-toolbar)
CONFIGURE_ARGS+=	--enable-toolbar
.else
CONFIGURE_ARGS+=	--disable-toolbar
.endif
xterm-399/gen-pc-fkeys.pl0000755000000000000000000002457410724113333014076 0ustar  rootroot#! /usr/bin/perl -w
# $XTermId: gen-pc-fkeys.pl,v 1.22 2007/11/30 23:03:55 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2004-2005,2007 by Thomas E. Dickey
# 
#                         All Rights Reserved
# 
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# 
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# 
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
#
# Construct a list of function-key definitions corresponding to xterm's
# Sun/PC keyboard.  This uses ncurses' infocmp to obtain the strings (including
# extensions) to modify (and verify).
use strict;

my($max_modifier, $terminfo);
my(@old_fkeys, $opt_fkeys, $min_fkeys, $max_fkeys);
my(%old_ckeys, $opt_ckeys, $min_ckeys, $max_ckeys);
my(%old_ekeys, $opt_ekeys, $min_ekeys, $max_ekeys);

my(@ckey_names);
@ckey_names = (
	'kcud1', 'kcub1', 'kcuf1', 'kcuu1',	# 1 = no modifiers
	'kDN',   'kLFT',  'kRIT',  'kUP',	# 2 = shift
	# make_ckey_names() repeats this row, appending the modifier code
	);
my %ckey_names;
my(@ckey_known);
@ckey_known = (
	'kind',  'kLFT',  'kRIT',  'kri',	# 2 = shift (standard)
	);

my(@ekey_names);
@ekey_names = (
	'khome', 'kend',  'knp',   'kpp',   'kdch1', 'kich1', # 1 = no modifiers
	'kHOM',  'kEND',  'kNXT',  'kPRV',  'kDC',   'kIC',   # 2 = shift
	# make_ekey_names() repeats this row, appending the modifier code
);
my %ekey_names;

$min_fkeys=12;		# the number of "real" function keys on your keyboard
$max_fkeys=64;		# the number of function-keys terminfo can support
$max_modifier=8;	# modifier 1 + (1=shift, 2=alt, 4=control 8=meta)

$min_ckeys=4;		# the number of "real" cursor keys on your keyboard
$max_ckeys=($min_ckeys * ($max_modifier - 1));

$min_ekeys=6;		# the number of "real" editing keys on your keyboard
$max_ekeys=($min_ekeys * ($max_modifier - 1));

$opt_ckeys=2;		# xterm's modifyCursorKeys resource
$opt_ekeys=2;		# xterm's modifyCursorKeys resource
$opt_fkeys=2;		# xterm's modifyFunctionKeys resource
$terminfo="xterm-new";	# the terminfo entry to use

# apply the given modifier to the terminfo string, return the result
sub modify_fkey($$$) {
	my $code = $_[0];
	my $text = $_[1];
	my $opts = $_[2];
	if (not defined($text)) {
		$text = "";
	} elsif ($code != 1) {
		$text =~ s/\\EO/\\E\[/ if ($opts >= 1);

		my $piece = substr $text, 0, length ($text) - 1;
		my $final = substr $text, length ($text) - 1;
		my $check = substr $piece, length ($piece) - 1;
		if ($check =~ /[0-9]/) {
			$code = ";" . $code;
		} elsif ( $check =~ /\[/ and $opts >= 2) {
			$code = "1;" . $code;
		}
		if ( $opts >= 3 ) {
			$code = ">" . $code;
		}
		$text = $piece . $code . $final;
		$text =~ s/([\d;]+)>/>$1/;
	}
	return $text;
}

# compute the next modifier value -
# Cycling through the modifiers is not just like counting.  Users prefer
# pressing one modifier (even if using Emacs).  So first we cycle through
# the individual modifiers, then for completeness two, three, etc.
sub next_modifier {
	my $code = $_[0];
	my $mask = $code - 1;
	if ($mask == 0) {
		$mask = 1;	# shift
	} elsif ($mask == 1) {
		$mask = 4;	# control
	} elsif ($mask == 2) {
		$mask = 3;	# shift+alt
	} elsif ($mask == 4) {
		$mask = 5;	# shift+control
	} elsif ($mask == 5) {
		$mask = 2;	# alt
	}
	# printf ("# next_modifier(%d) = %d\n", $code, $mask + 1);
	return $mask + 1;
}

sub make_ckey_names() {
	my ($j, $k);
	my $min = $min_ckeys * 2;
	my $max = $max_ckeys - 1;

	# printf "# make_ckey_names\n";
	for $j ($min..$max) {
		$k = 1 + substr($j / $min_ckeys, 0, 1);
		$ckey_names[$j] = $ckey_names[$min_ckeys + ($j % $min_ckeys)] . $k;
		# printf "# make %d:%s\n", $j, $ckey_names[$j];
	}
	for $j (0..$#ckey_names) {
		# printf "# %d:%s\n", $j, $ckey_names[$j];
		$ckey_names{$ckey_names[$j]} = $j;
	}
}

sub make_ekey_names() {
	my ($j, $k);
	my $min = $min_ekeys * 2;
	my $max = $max_ekeys - 1;

	# printf "# make_ekey_names\n";
	for $j ($min..$max) {
		$k = 1 + substr($j / $min_ekeys, 0, 1);
		$ekey_names[$j] = $ekey_names[$min_ekeys + ($j % $min_ekeys)] . $k;
		# printf "# make %d:%s\n", $j, $ekey_names[$j];
	}
	for $j (0..$#ekey_names) {
		# printf "# %d:%s\n", $j, $ekey_names[$j];
		$ekey_names{$ekey_names[$j]} = $j;
	}
}

# Read the terminfo entry's list of function keys $old_fkeys[].
# We could handle $old_fkeys[0], but choose to start numbering from 1.
sub readterm($) {
	my $term = $_[0];
	my($key, $n, $str);
	my(@list) = `infocmp -x -1 $term`;

	for $n (0..$#list) {
		chop $list[$n];
		$list[$n] =~ s/^[[:space:]]//;

		$key = $list[$n];
		$key =~ s/=.*//;

		$str = $list[$n];
		$str =~ s/^[^=]+=//;
		$str =~ s/,$//;

		if ( $list[$n] =~ /^kf[[:digit:]]+=/ ) {
			$key =~ s/^kf//;
			# printf "# $n:%s(%d)(%s)\n", $list[$n], $key, $str;
			$old_fkeys[$key] = $str;
		} elsif ( $key =~ /^kc[[:alpha:]]+1/
			or $key =~ /^k(LFT|RIT|UP|DN)\d?/) {
			# printf "# $n:%s(%d)(%s)\n", $list[$n], $key, $str;
			$old_ckeys{$key} = $str;
		} elsif ( defined $ekey_names{$key} ) {
			# printf "# $n:%s(%s)(%s)\n", $list[$n], $key, $str;
			$old_ekeys{$key} = $str;
		}
	}
	# printf ("last index:%d\n", $#old_fkeys);
}

# read the whole terminfo to ensure we get the non-modified stuff, then read
# the part that contains modifiers.
sub read_part($) {
	my $part = $_[0];

	%old_ckeys = ();
	@old_fkeys = ();
	readterm($terminfo);
	readterm($part);
}

sub nameof_ckeys($) {
	my $opts = $_[0];
	my $optname = "xterm+pcc" . ($opts >= 0 ? $opts : "n");
	return $optname;
}

sub generate_ckeys($) {
	my $opts = $_[0];
	my($modifier, $cur_ckey, $index);

	printf "%s|fragment with modifyCursorKeys:%s,\n",
		nameof_ckeys($opts), $opts;

	# show the standard cursor definitions
	$modifier = 1;
	for ($index = 0; $index < $min_ckeys; ++$index) {
		$cur_ckey = $index + ($modifier * $min_ckeys);
		my $name = $ckey_known[$index];
		my $input = $old_ckeys{$ckey_names[$index]};
		my $result = modify_fkey($modifier + 1, $input, $opts);
		printf "\t%s=%s,\n", $name, $result;
		if (defined $old_ckeys{$name}) {
			if ($old_ckeys{$name} ne $result) {
				printf "# found %s=%s\n", $name, $old_ckeys{$name};
			}
		}
	}

	# show the extended cursor definitions
	for ($index = 0; $index < $min_ckeys; ++$index) {
		for ($modifier = 1; $modifier < $max_modifier; ++$modifier) {
			$cur_ckey = $index + ($modifier * $min_ckeys);
			if (defined $ckey_names[$cur_ckey] and
				$ckey_names[$cur_ckey] ne "kLFT" and
				$ckey_names[$cur_ckey] ne "kRIT" ) {
				my $name = $ckey_names[$cur_ckey];
				my $input = $old_ckeys{$ckey_names[$index]};
				my $result = modify_fkey($modifier + 1, $input, $opts);
				printf "\t%s=%s,\n", $name, $result;
				if (defined $old_ckeys{$name}) {
					if ($old_ckeys{$name} ne $result) {
						printf "# found %s=%s\n", $name, $old_ckeys{$name};
					}
				}
			}
		}
	}
}

sub nameof_ekeys($) {
	my $opts = $_[0];
	my $optname = "xterm+pce" . ($opts >= 0 ? $opts : "n");
	return $optname;
}

sub generate_ekeys($) {
	my $opts = $_[0];
	my($modifier, $cur_ekey, $index);

	printf "%s|fragment with modifyCursorKeys:%s,\n",
		nameof_ekeys($opts), $opts;

	for ($index = 0; $index < $min_ekeys; ++$index) {
		for ($modifier = 1; $modifier < $max_modifier; ++$modifier) {
			$cur_ekey = $index + ($modifier * $min_ekeys);
			if (defined $ekey_names[$cur_ekey] ) {
				my $name = $ekey_names[$cur_ekey];
				my $input = $old_ekeys{$ekey_names[$index]};
				my $result = modify_fkey($modifier + 1, $input, $opts);
				printf "\t%s=%s,\n", $name, $result;
				if (defined $old_ekeys{$name}) {
					if ($old_ekeys{$name} ne $result) {
						printf "# found %s=%s\n", $name, $old_ekeys{$name};
					}
				}
			}
		}
	}
}

sub nameof_fkeys($) {
	my $opts = $_[0];
	my $optname = "xterm+pcf" . ($opts >= 0 ? $opts : "n");
	return $optname;
}

sub generate_fkeys($) {
	my $opts = $_[0];
	my($modifier, $cur_fkey);

	printf "%s|fragment with modifyFunctionKeys:%s and ctrlFKeys:10,\n",
		nameof_fkeys($opts), $opts;

	for ($cur_fkey = 1, $modifier = 1; $cur_fkey < $max_fkeys; ++$cur_fkey) {
		my $index = (($cur_fkey - 1) % $min_fkeys);
		if ($index == 0 && $cur_fkey != 1) {
			$modifier = next_modifier($modifier);
		}
		if (defined $old_fkeys[$index + 1]) {
			my $input = $old_fkeys[$index + 1];
			my $result = modify_fkey($modifier, $input, $opts);
			printf "\tkf%d=%s,\n", $cur_fkey, $result;
			if (defined $old_fkeys[$cur_fkey]) {
				if ($old_fkeys[$cur_fkey] ne $result) {
					printf "# found kf%d=%s\n", $cur_fkey, $old_fkeys[$cur_fkey];
				}
			}
		}
	}
}

sub show_default() {
	readterm($terminfo);

	printf "xterm+pcfkeys|fragment for PC-style keys,\n";
	printf "\tuse=%s,\n", nameof_ckeys($opt_ckeys);
	printf "\tuse=%s,\n", nameof_ekeys($opt_ekeys);
	printf "\tuse=%s,\n", nameof_fkeys($opt_fkeys);

	generate_ckeys($opt_ckeys);
	generate_ekeys($opt_ekeys);
	generate_fkeys($opt_fkeys);
}

sub show_nondefault()
{
	my $opts;

	for ($opts = 0; $opts <= 3; ++$opts) {
		if ($opts != $opt_ckeys) {
			read_part(nameof_ckeys($opts));
			generate_ckeys($opts);
		}
	}

	for ($opts = 0; $opts <= 3; ++$opts) {
		if ($opts != $opt_ekeys) {
			read_part(nameof_ekeys($opts));
			generate_ekeys($opts);
		}
	}

	for ($opts = 0; $opts <= 3; ++$opts) {
		if ($opts != $opt_fkeys) {
			read_part(nameof_fkeys($opts));
			generate_fkeys($opts);
		}
	}
}

make_ckey_names();
make_ekey_names();

printf "# gen-pc-fkeys.pl\n";
printf "# %s:timode\n", "vile";
show_default();
show_nondefault();
xterm-399/vttests/0000755000000000000000000000000014762173130012755 5ustar  rootrootxterm-399/vttests/256colors2.pl0000755000000000000000000001512014321052277015133 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: 256colors2.pl,v 1.26 2022/10/10 17:22:07 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 1999-2020,2022 by Thomas E. Dickey
# Copyright 2002 by Steve Wall
# Copyright 1999 by Todd Larason
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
#
# If -s is not given, use the resources for colors 0-15 - usually more-or-less
# a reproduction of the standard ANSI colors, but possibly more pleasing
# shades.

use strict;
use warnings;

use Getopt::Std;
use Encode 'encode_utf8';

our ( $opt_8, $opt_c, $opt_C, $opt_d, $opt_h, $opt_q, $opt_r, $opt_s, $opt_u );

$Getopt::Std::STANDARD_HELP_VERSION = 1;
&getopts('8cCdhqrsu') || die("Usage: $0 [options]");
die(
    "Usage: $0 [options]\n
Options:
  -8  use 8-bit controls
  -c  use colons for separating parameter values in SGR 38/48
  -C  like -c, but allow semicolon plus colon
  -d  use rgb values rather than palette index
  -h  display this message
  -q  quieter output by merging all palette initialization
  -r  display the reverse of the usual palette
  -s  modify system colors, i.e., 0..15
  -u  use UTF-8 when emitting 8-bit controls
"
) if ($opt_h);

our $cube = 6;
our (@steps);
our ( $red,  $green, $blue );
our ( $gray, $level, $color );
our ( $csi,  $osc,   $sep, $sep2, $st );

our @rgb;

sub map_cube($) {
    my $value = $_[0];
    $value = ( 5 - $value ) if defined($opt_r);
    return $value;
}

sub map_gray($) {
    my $value = $_[0];
    $value = ( 23 - $value ) if defined($opt_r);
    return $value;
}

sub define_color($$$$) {
    my $index = $_[0];
    my $r     = $_[1];
    my $g     = $_[2];
    my $b     = $_[3];

    printf( "%s4", $osc ) unless ($opt_q);
    printf( ";%d;rgb:%2.2x/%2.2x/%2.2x", $index, $r, $g, $b );
    printf( "%s", $st ) unless ($opt_q);

    $rgb[$index] = sprintf "%d%s%d%s%d", $r, $sep, $g, $sep, $b;
}

sub select_color($) {
    my $index = $_[0];
    if ( $opt_d and defined( $rgb[$index] ) ) {
        printf "%s48%s2%s%sm  ", $csi, $sep, $sep2, $rgb[$index];
    }
    else {
        printf "%s48%s5%s%sm  ", $csi, $sep, $sep2, $index;
    }
}

sub system_color($$$$) {
    my $color = shift;
    my $red   = shift;
    my $green = shift;
    my $blue  = shift;
    &define_color( 15 - $color, $red, $green, $blue ) if ($opt_r);
    &define_color( $color, $red, $green, $blue ) unless ($opt_r);
}

if ($opt_8) {
    $csi = "\x9b";
    $osc = "\x9d";
    $st  = "\x9c";
}
else {
    $csi = "\x1b[";
    $osc = "\x1b]";
    $st  = "\x1b\\";
}

if ($opt_c) {
    $sep = ":";
}
else {
    $sep = ";";
}
$sep2 = $sep;

if ($opt_C) {
    $sep  = ";";
    $sep2 = ":";
}

if ( $opt_8 and $opt_u ) {
    if ( open( FP, "locale 2>/dev/null |" ) ) {
        my (@locale) = ;
        chomp @locale;
        close(FP);
        for my $n ( 0 .. $#locale ) {
            if ( $locale[$n] =~ /^LC_CTYPE=/ ) {
                binmode( STDOUT, ":utf8" ) if ( $locale[$n] =~ /utf.?8/i );
                last;
            }
        }
    }
}

printf( "%s4", $osc ) if ($opt_q);

if ($opt_s) {
    &system_color( 0,  0,   0,   0 );
    &system_color( 1,  205, 0,   0 );
    &system_color( 2,  0,   205, 0 );
    &system_color( 3,  205, 205, 0 );
    &system_color( 4,  0,   0,   238 );
    &system_color( 5,  205, 0,   205 );
    &system_color( 6,  0,   205, 205 );
    &system_color( 7,  229, 229, 229 );
    &system_color( 8,  127, 127, 127 );
    &system_color( 9,  255, 0,   0 );
    &system_color( 10, 0,   255, 0 );
    &system_color( 11, 255, 255, 0 );
    &system_color( 12, 92,  92,  255 );
    &system_color( 13, 255, 0,   255 );
    &system_color( 14, 0,   255, 255 );
    &system_color( 15, 255, 255, 255 );
}

# colors 16-231 are a 6x6x6 color cube
@steps = ( 0, 95, 135, 175, 215, 255 );
for ( $red = 0 ; $red < $cube ; $red++ ) {
    for ( $green = 0 ; $green < $cube ; $green++ ) {
        for ( $blue = 0 ; $blue < $cube ; $blue++ ) {
            &define_color(
                16 + ( map_cube($red) * $cube * $cube ) +
                  ( map_cube($green) * $cube ) +
                  map_cube($blue),
                int( $steps[$red] ),
                int( $steps[$green] ),
                int( $steps[$blue] )
            );
        }
    }
}

# colors 232-255 are a grayscale ramp, intentionally leaving out
# black and white
for ( $gray = 0 ; $gray < 24 ; $gray++ ) {
    $level = ( map_gray($gray) * 10 ) + 8;
    &define_color( 232 + $gray, $level, $level, $level );
}
printf( "%s", $st ) if ($opt_q);

# display the colors

# first the system ones:
print "System colors:\n";
for ( $color = 0 ; $color < 8 ; $color++ ) {
    &select_color($color);
}
printf "%s0m\n", $csi;
for ( $color = 8 ; $color < 16 ; $color++ ) {
    &select_color($color);
}
printf "%s0m\n\n", $csi;

# now the color cube
print "Color cube, ${cube}x${cube}x${cube}:\n";
for ( $green = 0 ; $green < $cube ; $green++ ) {
    for ( $red = 0 ; $red < $cube ; $red++ ) {
        for ( $blue = 0 ; $blue < $cube ; $blue++ ) {
            $color = 16 + ( $red * $cube * $cube ) + ( $green * $cube ) + $blue;
            &select_color($color);
        }
        printf "%s0m ", $csi;
    }
    print "\n";
}

# now the grayscale ramp
print "Grayscale ramp:\n";
for ( $color = 232 ; $color < 256 ; $color++ ) {
    &select_color($color);
}
printf "%s0m\n", $csi;
xterm-399/vttests/acs.pl0000755000000000000000000000503713267123345014072 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: acs.pl,v 1.3 2018/04/22 15:14:45 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2018 by Thomas E. Dickey
# 
#                         All Rights Reserved
# 
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# 
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# 
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Assuming at least 24x80, print an array of the printable characters and their
# mapping to alternate character-set.  This also requires cursor-addressing.

use strict;
use warnings;
use diagnostics;

sub failed() {
    my $args = shift;
    printf STDERR "? %s\n", $args;
    exit 1;
}

sub need() {
    my $cap   = shift;
    my $check = `tput $cap 0 0`;
    chomp $check;
    &failed("missing capability: $cap") if ( $check eq "" );
}

&need("cup");
&need("clear");
&need("smacs");
&need("rmacs");

system("tput clear");
system("tput enacs");
my $smacs = `tput smacs`;
my $rmacs = `tput rmacs`;

for my $row ( 0 .. 15 ) {
    for my $col ( 0 .. 5 ) {
        my $ch = 32 + $row + $col * 16;
        last if ( $ch >= 127 );
        system( sprintf( "tput cup %d %d", $row, 4 + $col * 12 ) );
        my $xx = chr($ch);
        printf '%2x:%s{%s%s%s}', $ch, $xx, $smacs, $xx . $xx . $xx . $xx,
          $rmacs;
    }
}

printf "\n";

1;
xterm-399/vttests/tab0.sh0000755000000000000000000000552414231622612014143 0ustar  rootroot#!/bin/sh
# $XTermId: tab0.sh,v 1.6 2022/04/25 22:49:46 tom Exp $
# -----------------------------------------------------------------------------
# Copyright 2019,2022 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Demonstrate hard-tabs.

: "${TABS:=tabs}"
: "${TPUT:=tput}"

show() {
	printf "Tabs %s:" "$1"
	read -r ignore
	p=0
	while [ "$p" -lt "$wide" ]
	do
		printf "%s+----%d" "----" "`expr 1 + \( "$p" / 10 \)`"
		p=`expr $p + 10`
	done
	printf '\n'
	p=1
	printf " "
	while [ "$p" -lt "$wide" ]
	do
		printf "%*s" "$1" "*"
		p=`expr "$p" + "$1"`
	done
	printf '\n'
	p=0
	while [ "$p" -lt "$wide" ]
	do
		printf '\t+'
		p=`expr "$p" + "$1"`
	done
	printf '\n'
	printf "...done"
	read -r ignore
}

# enable hard tabs, disable autowrap.
initialize() {
	"$TPUT" "$1"
	clear
	stty tabs
	printf '\033[?7l'
}

setup() {
	initialize reset
}

# Turn hard tabs off, reenable autowrap.
restore() {
	stty -tabs
	printf '\033[?7h'
}

wide=`$TPUT cols`

# If the terminal honors VT100 RIS, try that as a "hard reset" to get the
# power-on behavior.
for name in rs1 rs2
do
	value=`$TPUT $name | sed -e 's//ESC:/g'`
	case "$value" in
	*ESC:c*)
		;;
	*)
		value=
		;;
	esac
	if [ -n "$value" ]
	then
		initialize $name
		printf 'Testing after tput %s\r\n' "$name"
		show	8
		break
	fi
done

# The following tests use the normal "reset" behavior.
setup
$TABS	-8
show	8
$TABS	-4
show	4

# Some terminal emulators are known to be buggy, and "reset" does not get them
# to reset the tab-stops.
setup
show	8
restore
xterm-399/vttests/sgrPushPop2.pl0000755000000000000000000001517213765426642015532 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: sgrPushPop2.pl,v 1.4 2020/12/13 15:05:06 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2019,2020 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------

use strict;
use warnings;

use Getopt::Std;

$| = 1;

our ( $opt_b, $opt_n, $opt_r );

$Getopt::Std::STANDARD_HELP_VERSION = 1;
&getopts('bn:r:') || die(
    "Usage: $0 [options]\n
Options:\n
  -b      color backgrounds instead of foregrounds
  -n NUM  limit test to NUM rows (default: 9)
  -r NUM  rotate example-columns (e.g, -r1 puts direct-color in middle)
"
);
$opt_n = 9 unless ( defined $opt_n );
$opt_r = 0 unless ( defined $opt_r );

our @xterm_ansi = (
    0x000000,    #black
    0xcd0000,    #red3
    0x00cd00,    #green3
    0xcdcd00,    #yellow3
    0x0000ee,    #blue2
    0xcd00cd,    #magenta3
    0x00cdcd,    #cyan3
    0xe5e5e5     #gray90
);

# The lengths in @example_title differ to ensure that the trailing "END!"
# should be the same color as the middle column, regardless of "-r" rotation.
our $example_title = "COLOR-";
our @example_title = ( "Indexed", "ANSI8", "Direct" );

# demonstrate selective SGR pop by a two-level test where the top-level has
# ANSI colors, while the lower-level iterates over a color test-pattern,
# alternating between direct-color and indexed-colors.

sub choose_fgbg($$) {
    my $fg     = shift;
    my $bg     = shift;
    my $result = $opt_b ? $bg : $fg;
    return $result;
}

sub choose_column($) {
    my $code = shift;
    return ( $code + $opt_r ) % 3;
}

sub pushSGR($) {
    my $params = shift;
    printf "\x1b[%s#{", $params;
}

sub popSGR() {
    printf "\x1b[#}";
}

sub mark_l() {
    printf " {";
}

sub mark_r() {
    printf "} ";
}

sub standard_example() {
    &mark_l;
    my $text = $example_title . $example_title[1];
    for my $n ( 0 .. length($text) - 1 ) {
        printf "\x1b[%dm", ( $n % 7 ) + 1 + &choose_fgbg( 30, 40 );
        printf "%s", substr( $text, $n, 1 );
    }
    &mark_r;
}

# The first 16 colors of xterm-256's palette match the ANSI+aixterm range.
# Do not imitate the bold-colors.
sub indexed_example() {
    &mark_l;
    my $text = $example_title . $example_title[0];
    for my $n ( 0 .. length($text) - 1 ) {
        my $c = ( $n % 7 ) + 1;
        printf "\x1b[%d;5:%dm", &choose_fgbg( 38, 48 ), $c;
        printf "%s", substr( $text, $n, 1 );
    }
    &mark_r;
}

# Imitate the "ANSI" colors from xterm's palette.
# (Again bold colors are not imitated here).
sub direct_example() {
    &mark_l;
    my $text = $example_title . $example_title[2];
    for my $n ( 0 .. length($text) - 1 ) {
        my $c = ( $n % 7 ) + 1;
        my $r = ( $xterm_ansi[$c] / ( 256 * 256 ) ) % 256;
        my $g = ( $xterm_ansi[$c] / (256) ) % 256;
        my $b = ( $xterm_ansi[$c] ) % 256;
        printf "\x1b[%d;2:1:%d:%d:%dm", &choose_fgbg( 38, 48 ), $r, $g, $b;
        printf "%s", substr( $text, $n, 1 );
    }
    &mark_r;
}

sub run_example($) {
    my $column = shift;
    &indexed_example  if ( &choose_column($column) == 0 );
    &standard_example if ( &choose_column($column) == 1 );
    &direct_example   if ( &choose_column($column) == 2 );
}

sub video_name($) {
    my $code   = shift;
    my $result = "?";
    $result = "normal"            if ( $code == 0 );
    $result = "bold"              if ( $code == 1 );
    $result = "faint"             if ( $code == 2 );
    $result = "italicized"        if ( $code == 3 );
    $result = "underlined"        if ( $code == 4 );
    $result = "blink"             if ( $code == 5 );
    $result = "inverse"           if ( $code == 7 );
    $result = "crossed-out"       if ( $code == 9 );
    $result = "double-underlined" if ( $code == 21 );
    return $result;
}

sub reset_video() {
    printf "\x1b[m";
}

sub set_video($) {
    my $row   = shift;
    my $param = "";
    my $cycle = 9;
    $param = 0  if ( ( $row % $cycle ) == 0 );
    $param = 1  if ( ( $row % $cycle ) == 1 );
    $param = 2  if ( ( $row % $cycle ) == 2 );
    $param = 3  if ( ( $row % $cycle ) == 3 );
    $param = 4  if ( ( $row % $cycle ) == 4 );
    $param = 5  if ( ( $row % $cycle ) == 5 );
    $param = 7  if ( ( $row % $cycle ) == 6 );
    $param = 9  if ( ( $row % $cycle ) == 7 );
    $param = 21 if ( ( $row % $cycle ) == 8 );
    printf "%-20s",    &video_name($param);
    printf "\x1b[%dm", $param;
}

printf "\x1b[H\x1b[J";

&pushSGR("");
printf "\x1b[40;37mSetting ambient colors to white-on-black\n";

# The three columns (indexed, ANSI, direct) will look similar.
&pushSGR("");

printf "Testing white-on-black with columns %s,%s,%s\n",
  $example_title[ &choose_column(0) ],
  $example_title[ &choose_column(1) ],
  $example_title[ &choose_column(2) ];

for my $row ( 0 .. $opt_n ) {

    &pushSGR("30;31");    # save/restore only foreground/background color
    &set_video($row);     # this attribute is set for the whole row
    &run_example(0);
    &popSGR;

    &run_example(1);

    &pushSGR("30;31");    # save/restore only foreground/background color
    &run_example(2);
    &popSGR;
    printf "END!";        # this is in the last color used in the middle column
    &reset_video();
    printf "\n";
}

&popSGR;
printf "The ambient colors should still be white-on-black.\n";
&popSGR;
printf "Now we should be back to whatever it was before we got here.\n";

1;
xterm-399/vttests/pointer-shapes.sh0000755000000000000000000000542514143253433016261 0ustar  rootroot#!/bin/sh
# $XTermId: pointer-shapes.sh,v 1.2 2021/11/11 17:47:07 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2021 by Thomas E. Dickey
# 
#                         All Rights Reserved
# 
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# 
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# 
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# exercise xterm's pointer-shape control

map() {
	printf '\033]22;%s\033\\' "$1"
	printf "** %s\n" "$1"
	sleep 2
}

map X_cursor
map arrow
map based_arrow_down
map based_arrow_up
map boat
map bogosity
map bottom_left_corner
map bottom_right_corner
map bottom_side
map bottom_tee
map box_spiral
map center_ptr
map circle
map clock
map coffee_mug
map cross
map cross_reverse
map crosshair
map diamond_cross
map dot
map dotbox
map double_arrow
map draft_large
map draft_small
map draped_box
map exchange
map fleur
map gobbler
map gumby
map hand1
map hand2
map heart
map icon
map iron_cross
map left_ptr
map left_side
map left_tee
map leftbutton
map ll_angle
map lr_angle
map man
map middlebutton
map mouse
map pencil
map pirate
map plus
map question_arrow
map right_ptr
map right_side
map right_tee
map rightbutton
map rtl_logo
map sailboat
map sb_down_arrow
map sb_h_double_arrow
map sb_left_arrow
map sb_right_arrow
map sb_up_arrow
map sb_v_double_arrow
map shuttle
map sizing
map spider
map spraycan
map star
map target
map tcross
map top_left_arrow
map top_left_corner
map top_right_corner
map top_side
map top_tee
map trek
map ul_angle
map umbrella
map ur_angle
map watch
map xterm
xterm-399/vttests/title.sh0000755000000000000000000000543714231454632014446 0ustar  rootroot#!/bin/sh
# $XTermId: title.sh,v 1.26 2022/04/25 08:19:38 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 1999-2021,2022 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Obtain the current title of the window, set up a simple clock which runs
# until this script is interrupted, then restore the title.

ESC=""
CSI="${ESC}["
CMD='/bin/echo'
OPT='-n'
SUF=''
: "${TMPDIR=/tmp}"
TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$"
eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null
{ test ! -f "$TMP" || test -s "$TMP"; } &&
for verb in "printf" "print" ; do
    rm -f "$TMP"
    eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null
    if test -f "$TMP" ; then
	if test ! -s "$TMP" ; then
	    CMD="$verb"
	    OPT=
	    SUF='\c'
	    break
	fi
    fi
done
rm -f "$TMP"

exec  /dev/tty
read -r original

stty $old

# We actually get this terminated by an backslash, but the backslash
# is lost.  We may lose doublequote characters when restoring the title,
# depending on the shell.
original=`echo "$original" |sed -e 's/^...//' -e 's/.$//'`
original=${ESC}]2\;"${original}"${SUF}

trap '$CMD $OPT "$original" >/dev/tty; exit 1' 1 2 3 15
trap '$CMD $OPT "$original" >/dev/tty' 0

while true
do
	sleep 1
	$CMD $OPT "${ESC}]2;`date`" >/dev/tty
done
xterm-399/vttests/paste64.pl0000755000000000000000000001136013374656763014624 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: paste64.pl,v 1.14 2018/11/20 01:05:55 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2006-2014,2018 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Test the paste64 option of xterm.

use strict;
use warnings;

use Term::ReadKey;
use IO::Handle;
use MIME::Base64;

our $target = "";

sub to_hex($) {
    my $value  = $_[0];
    my $result = "";
    my $n;

    for ( $n = 0 ; $n < length($value) ; ++$n ) {
        $result .= sprintf( "%02X", ord substr( $value, $n, 1 ) );
    }
    return $result;
}

sub show_string($) {
    my $value = $_[0];
    my $n;

    my $result = "";
    for ( $n = 0 ; $n < length($value) ; $n += 1 ) {
        my $c = ord substr( $value, $n, 1 );
        if ( $c == ord '\\' ) {
            $result .= "\\\\";
        }
        elsif ( $c == 0x1b ) {
            $result .= "\\E";
        }
        elsif ( $c == 0x7f ) {
            $result .= "^?";
        }
        elsif ( $c == 32 ) {
            $result .= "\\s";
        }
        elsif ( $c < 32 ) {
            $result .= sprintf( "^%c", $c + 64 );
        }
        elsif ( $c > 128 ) {
            $result .= sprintf( "\\%03o", $c );
        }
        else {
            $result .= chr($c);
        }
    }

    printf "%s\r\n", $result;
}

sub get_reply($) {
    my $command = $_[0];
    my $reply   = "";

    printf "send: ";
    show_string($command);

    print STDOUT $command;
    autoflush STDOUT 1;
    while (1) {
        my $test = ReadKey 1;
        last if not defined $test;

        #printf "%d:%s\r\n", length($reply), to_hex($test);
        $reply .= $test;
    }
    return $reply;
}

sub get_paste() {
    my $reply = get_reply( "\x1b]52;" . $target . ";?\x1b\\" );

    printf "read: ";
    show_string($reply);

    my $data = $reply;
    $data =~ s/^\x1b]52;[[:alnum:]]*;//;
    $data =~ s/\x1b\\$//;
    printf "chop: ";
    show_string($data);

    $data = decode_base64($data);
    printf "data: ";
    show_string($data);
}

sub put_paste() {
    ReadMode 1;

    printf "data: ";
    my $data = ReadLine 0;
    chomp $data;
    ReadMode 5;

    $data = encode_base64($data);
    chomp $data;
    printf "data: ";
    show_string($data);

    my $send = "\x1b]52;" . $target . ";" . $data . "\x1b\\";

    printf "send: ";
    show_string($send);
    print STDOUT $send;
    autoflush STDOUT 1;
}

sub set_target() {
    ReadMode 1;

    printf "target: ";
    $target = ReadLine 0;
    $target =~ s/[^cps01234567]//g;
    ReadMode 5;
    printf "result: %s\r\n", $target;
}

ReadMode 5, 'STDIN';    # allow single-character inputs
while (1) {
    my $cmd;

    printf "\r\nCommand (? for help):";
    $cmd = ReadKey 0;
    if ( $cmd eq "?" ) {
        printf "\r\np=put selection,"
          . " g=get selection,"
          . " q=quit,"
          . " r=reset target,"
          . " s=set target\r\n";
    }
    elsif ( $cmd eq "p" ) {
        printf " ...put selection\r\n";
        put_paste();
    }
    elsif ( $cmd eq "g" ) {
        printf " ...get selection\r\n";
        get_paste();
    }
    elsif ( $cmd eq "q" ) {
        printf " ...quit\r\n";
        last;
    }
    elsif ( $cmd eq "r" ) {
        printf " ...reset\r\n";
        $target = "";
    }
    elsif ( $cmd eq "s" ) {
        printf " ...set target\r\n";
        set_target();
    }
}
ReadMode 0, 'STDIN';    # Reset tty mode before exiting
xterm-399/vttests/closest-rgb.pl0000755000000000000000000001531213765427026015553 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: closest-rgb.pl,v 1.12 2020/12/13 15:07:02 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2017-2018,2020 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# For a given RGB value, show its distance from xterm's 88/256-color
# models or alternatively against rgb.txt

use strict;
use warnings;

use Getopt::Std;

our $namedRGB = "/etc/X11/rgb.txt";
our @namedRGB;
our @xtermRGB;

our ( $opt_f, $opt_i, $opt_n );

sub main::HELP_MESSAGE() {
    printf STDERR <;
    close $fp;
    my @result;
    my $o = 0;
    for my $i ( 0 .. $#data ) {
        next if ( $data[$i] =~ /^\s*[[:punct:]]/ );

        $result[ $o++ ] = &lookup( $data[$i] );
    }
    return @result;
}

sub distance($$) {
    my %a      = %{ $_[0] };
    my %b      = %{ $_[1] };
    my $R      = $a{R} - $b{R};
    my $G      = $a{G} - $b{G};
    my $B      = $a{B} - $b{B};
    my $result = sqrt( $R * $R + $G * $G + $B * $B );
}

sub show_distances($$) {
    my @ref = @{ $_[0] };
    my @cmp = @{ $_[1] };
    for my $c ( 0 .. $#cmp ) {
        my %cmp  = %{ $cmp[$c] };
        my $best = -1;
        my %best;
        for my $r ( 0 .. $#ref ) {
            my %ref = %{ $ref[$r] };
            my $test = &distance( \%ref, \%cmp );
            if ( $best < 0 ) {
                $best = $test;
                %best = %ref;
            }
            elsif ( $best > $test ) {
                $best = $test;
                %best = %ref;
            }
        }
        printf "%3d %-25s %5.1f   %s\n", $c, $cmp{NAME}, $best, $best{NAME};
    }
}

@namedRGB = &load_namedRGB($opt_f);
printf "%d names from $opt_f\n", $#namedRGB + 1;

if ( $opt_n <= 16 ) {
    @xtermRGB = &xterm16;
}
elsif ( $opt_n <= 88 ) {
    @xtermRGB = &xterm88;
}
else {
    @xtermRGB = &xterm256;
}
printf "%d names from xterm palette\n", $#xtermRGB + 1;

&show_distances( \@xtermRGB, \@namedRGB ) if ($opt_i);
&show_distances( \@namedRGB, \@xtermRGB ) unless ($opt_i);

1;
xterm-399/vttests/il.sh0000755000000000000000000000404314231455476013730 0ustar  rootroot#!/bin/bash
# $XTermId: il.sh,v 1.3 2022/04/25 08:26:38 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2019,2022 by Thomas E. Dickey
# 
#                         All Rights Reserved
# 
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# 
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# 
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
start_test() {
	printf '\033[H\033[2J'
	printf 'First line\nSecond line\nThird line\nLast line!\n'
}

actual_test() {
	printf '\033[2;8H'
	printf '\033[1L'
	printf '*'
}

set_margins() {
	printf '\033[?69h'
	printf '\033[4;40s'
}

reset_margins() {
	printf '\033[?69l'
}

finish_test() {
	printf '\033[10;1H'
	read -r -p "$*"
}

start_test
actual_test
finish_test NEXT

start_test
set_margins
actual_test
reset_margins
finish_test DONE
xterm-399/vttests/halves.pl0000755000000000000000000001356614335302014014601 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: halves.pl,v 1.11 2022/11/17 00:45:00 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2007,2022 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Draw a grid of characters (optionally double-width) and modify it using
# overstrike, insert- and delete-characters to see if the double-width
# characters are completely cleared when "partly" modified.
use strict;
use warnings;

use Getopt::Std;

our ( $opt_c, $opt_n, $opt_r, $opt_w );
our ( $lineno, $test_string, $term_width );

# returns the number of columns in the screen
sub screen_width() {
    open( FP, "resize -u |" ) or exit $!;
    my (@input) = ;
    chomp @input;
    close(FP);
    my $result = 80;
    for my $n ( 0 .. $#input ) {
        if ( $input[$n] =~ /^COLUMNS=/ ) {
            $result = $input[$n];
            $result =~ s/^[^=]*=//;
            $result =~ s/;.*//;
            last;
        }
    }
    return $result;
}

sub set_color($) {
    my $code = $_[0];
    if ( defined($opt_c) ) {
        if ( $code == 3 ) {
            printf "\x1b[1;33;42m";    # yellow-on-green
        }
        elsif ( $code == 2 ) {
            printf "\x1b[0;31;45m";    # red-on-magenta
        }
        elsif ( $code == 1 ) {
            printf "\x1b[0;36;44m";    # cyan-on-blue
        }
        else {
            printf "\x1b[0;39;49m";
        }
    }
}

# returns a string of two-column characters given an ASCII alpha/numeric string
sub double_cells($) {
    my $value = $_[0];
    $value =~ s/ /  /g;
    pack(
        "U*",
        map {
            ( $_ <= 32 || $_ > 127 )        # if non-ASCII character...
              ? 32                          # ...just show a blank
              : ( 0xff00 + ( $_ - 32 ) )    # map to "Fullwidth Form"
        } unpack( "C*", $value )
    );                                      # unpack unsigned-char characters
}

sub move_to($) {
    printf "\x1b[%dG", $_[0] + 1;
}

sub delete_char() {
    set_color(2);
    printf "\x1b[%dP", 1;
    set_color(1);
}

sub insert_once($) {
    set_color(2);
    printf "\x1b[%d@", length( $_[0] );
    write_chars( $_[0] );
}

sub insert_mode($) {
    set_color(2);
    printf "\x1b[%dP", length( $_[0] );
    printf "\x1b[4h";
    write_chars( $_[0] );
    printf "\x1b[4l";
}

sub write_chars($) {
    set_color(3);
    printf "%s", $_[0];
    set_color(1);
}

# vary the starting point of each line, to make a more interesting pattern
sub starts_of($) {
    my $value = $_[0];
    if ( defined($opt_w) ) {

        # 0,1,1,2,2,3,3,...
        $value = ( ( $value + 1 ) / 2 ) % length($test_string);
    }
    else {
        $value %= length($test_string);
    }
    return $value;
}

# write the text for the given line-number
sub testit($) {
    my $number = $_[0];
    my $length = $term_width;
    if ( defined($opt_n) ) {
        printf "%5d ", $number % 99999;
        $length -= 6;
    }

    # if we're printing double-column characters, we have half as much
    # space effectively - but don't forget the remainder, so we can push
    # the characters by single-columns.
    if ( defined($opt_c) ) {
        set_color(1);
        printf "\x1b[K";
    }
    my $starts = starts_of($number);
    if ( defined($opt_w) ) {
        printf " ", if ( ( $number % 2 ) != 0 );
        $length = ( $length - ( ($number) % 2 ) ) / 2;
    }
    my $string = substr( $test_string, $starts );
    while ( length($string) < $length ) {
        $string = $string . $test_string;
    }
    $string = substr( $string, 0, $length );
    if ( defined($opt_w) ) {
        $string = double_cells($string);
    }
    printf "%s", $string;

    # now - within the line - modify it
    move_to( ( 4 * $term_width ) / 5 );
    insert_mode("XX");
    move_to( ( 3 * $term_width ) / 5 );
    delete_char();
    move_to( ( 2 * $term_width ) / 5 );
    insert_once('~');
    move_to( ( 1 * $term_width ) / 5 );
    write_chars('~');
    move_to(0);
    set_color(0);
    printf "\n";
}

sub main::HELP_MESSAGE() {
    printf STDERR </dev/null` || TMP="$TMPDIR/xterm$$"
eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null
( test ! -f "$TMP" || test -s "$TMP" ) &&
for verb in printf print ; do
    rm -f "$TMP"
    eval '$verb "\c" >"$TMP" || echo fail >"$TMP"' 2>/dev/null
    if test -f "$TMP" ; then
	if test ! -s "$TMP" ; then
	    CMD="$verb"
	    OPT=
	    SUF='\c'
	    break
	fi
    fi
done
rm -f "$TMP"

exec 0q${SUF}" > /dev/tty
read -r version

stty $old
echo "$version" |cat -v
xterm-399/vttests/vt52chars.pl0000755000000000000000000000716013510723451015137 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: vt52chars.pl,v 1.1 2019/07/08 20:27:21 tom Exp $
# -----------------------------------------------------------------------------
# Copyright 2019 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# show the vt52 graphic characters, annotatated in a table.

sub clear() {
    printf "\033H";    # home
    printf "\033J";    # erase
}

sub move($$) {
    my $y = shift;
    my $x = shift;
    printf "\033Y%c%c", $y + 32, $x + 32;
}

sub start_vt52() {
    printf "\033[?2l";
}

sub stop_vt52() {
    printf "\033<";
}

sub show_char() {
    my $value  = shift;
    my $string = shift;
    my $chr    = $value - 0140;
    return if ( $chr < 0 );    # not supported by xterm
    $value &= 0xff;
    my $y = 2 + int( $chr % 16 );
    my $x = 6 + int( $chr / 16 ) * 40;
    &move( $y, $x );
    printf "%03o \033F%s\033G %s", $value, chr($value), $string;
}

sub show_table() {
    &clear;
    &move( 0, 28 );
    printf "VT52 graphic characters";
    &show_char( 0140, "reserved" );
    &show_char( 0141, "solid rectangle" );
    &show_char( 0142, "1/" );
    &show_char( 0143, "3/" );
    &show_char( 0144, "5/" );
    &show_char( 0145, "7/" );
    &show_char( 0146, "degrees" );
    &show_char( 0147, "plus or minus" );
    &show_char( 0150, "right arrow" );
    &show_char( 0151, "ellipsis" );
    &show_char( 0152, "divide by" );
    &show_char( 0153, "down arrow" );
    &show_char( 0154, "bar at scan 0" );
    &show_char( 0155, "bar at scan 1" );
    &show_char( 0156, "bar at scan 2" );
    &show_char( 0157, "bar at scan 3" );
    &show_char( 0160, "bar at scan 4" );
    &show_char( 0161, "bar at scan 5" );
    &show_char( 0162, "bar at scan 6" );
    &show_char( 0163, "bar at scan 7" );
    &show_char( 0164, "subscript 0" );
    &show_char( 0165, "subscript 1" );
    &show_char( 0166, "subscript 2" );
    &show_char( 0167, "subscript 3" );
    &show_char( 0170, "subscript 4" );
    &show_char( 0171, "subscript 5" );
    &show_char( 0172, "subscript 6" );
    &show_char( 0173, "subscript 7" );
    &show_char( 0174, "subscript 8" );
    &show_char( 0175, "subscript 9" );
    &show_char( 0176, "paragraph" );
    &move( 19, 6 );
    printf "BAR[\033F\154\155\156\157\160\161\162\163\033G]";
    &move( 23, 0 );
}

&start_vt52;
&show_table;
&stop_vt52;

1;
xterm-399/vttests/under-latin.pl0000755000000000000000000000674213614670764015562 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: under-latin.pl,v 1.6 2020/01/31 00:16:52 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2020 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Print a text-test pattern using Latin-1 characters that have these features:
#	a) accents
#	b) descenders
#	c) underlining

use strict;
use warnings;

use Getopt::Std;
use Term::ReadKey;

$| = 1;

our ( $opt_b, $opt_i, $opt_u );

our $ROWS = 24;
our $COLS = 4;

our @sample;

sub underlined($$) {
    my $text = shift;
    my $code = shift;
    $text = sprintf "\033[4m%s\033[24m", $text if ($code);
    return $text;
}

sub print_row($) {
    my $y     = shift;
    my $cells = $y * 5;
    for my $x ( 0 .. $COLS ) {
        printf "%s",
          &underlined( $sample[ $cells % 2 ], ( $cells % 4 ) > 1 ? 1 : 0 );
        ++$cells;
    }
}

sub main::HELP_MESSAGE() {
    printf STDERR <= $ROWS );
}

if ( -t 1 ) {
    printf "\033[m";
    ReadMode 'cbreak';
    my $key = ReadKey(30);
    ReadMode 'normal';
}
printf "\n";

1;
xterm-399/vttests/query-color.pl0000755000000000000000000002021113765455304015602 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: query-color.pl,v 1.26 2020/12/13 18:17:40 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2012-2019,2020 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Test the color-query features of xterm using OSC 4 or OSC 5.

use strict;
use warnings;

use Getopt::Std;
use IO::Handle;

our ( $opt_4, $opt_a, $opt_n, $opt_q, $opt_r, $opt_s, $opt_t );

$Getopt::Std::STANDARD_HELP_VERSION = 1;
&getopts('4an:qrst') || die(
    "Usage: $0 [options] [color1[-color2]]\n
Options:\n
  -4      use OSC 4 for special colors rather than OSC 5
  -a      query all \"ANSI\" colors
  -n NUM  assume terminal supports NUM \"ANSI\" colors rather than 256
  -q      quicker results by merging queries
  -r      show reported color in #rrggbb format
  -s      use ^G rather than ST
  -t      show actual color
"
);

our $ST              = $opt_s ? "\007" : "\x1b\\";
our $num_ansi_colors = $opt_n ? $opt_n : 256;

our $last_op = -1;
our $this_op = -1;

our @query_params;

sub get_reply($) {
    open TTY, "+;
    close TTY;
    system "stty $old";
    if ( defined $reply ) {
        die("^C received\n") if ( "$reply" eq "\003" );
    }
    return $reply;
}

sub visible($) {
    my $reply = $_[0];
    my $n;
    my $result = "";
    for ( $n = 0 ; $n < length($reply) ; ) {
        my $c = substr( $reply, $n, 1 );
        if ( $c =~ /[[:print:]]/ ) {
            $result .= $c;
        }
        else {
            my $k = ord substr( $reply, $n, 1 );
            if ( ord $k == 0x1b ) {
                $result .= "\\E";
            }
            elsif ( $k == 0x7f ) {
                $result .= "^?";
            }
            elsif ( $k == 32 ) {
                $result .= "\\s";
            }
            elsif ( $k < 32 ) {
                $result .= sprintf( "^%c", $k + 64 );
            }
            elsif ( $k > 128 ) {
                $result .= sprintf( "\\%03o", $k );
            }
            else {
                $result .= chr($k);
            }
        }
        $n += 1;
    }

    return $result;
}

sub special2code($) {
    my $param = shift;
    $param = 0 if ( $param =~ /^bold$/i );
    $param = 1 if ( $param =~ /^underline$/i );
    $param = 2 if ( $param =~ /^blink$/i );
    $param = 3 if ( $param =~ /^reverse$/i );
    $param = 4 if ( $param =~ /^italic$/i );
    return $param;
}

sub code2special($) {
    my $param = shift;
    my $result;
    $result = "bold"      if ( $param == 0 );
    $result = "underline" if ( $param == 1 );
    $result = "blink"     if ( $param == 2 );
    $result = "reverse"   if ( $param == 3 );
    $result = "italic"    if ( $param == 4 );
    return $result;
}

sub begin_query() {
    @query_params = ();
}

sub add_param($) {
    $query_params[ $#query_params + 1 ] = $_[0];
}

sub show_reply($) {
    my $reply = shift;
    my $shown = sprintf "data={%s}", &visible($reply);
    my $limit = 30;
    if ( $reply =~ /^\d+;rgb:.*/ ) {
        my $color = $reply;
        $color =~ s/^\d+;rgb://;
        if ( $color =~ /^[[:xdigit:]]{4}(\/[[:xdigit:]]{4}){2}/ ) {
            $color =~ s/..$//;
            $color =~ s/..\///g;
            if ($opt_r) {
                $shown = sprintf "#%s", $color;
                $limit = 7;
            }
        }
        printf "%s", $shown;
        if ( $opt_4 or ( $this_op == 5 ) ) {
            my $num = $reply;
            my $max = $opt_4 ? $num_ansi_colors : 0;
            $num =~ s/;.*//;
            if ( $num >= $max ) {
                my $name = &code2special( $num - $max );
                printf "  %s", $name if ($name);
            }
        }
        if ($opt_t) {
            my $num = $reply;
            $num =~ s/;.*//;
            printf "%*s", $limit - length($shown), " ";
            if ( $num < 8 ) {
                printf "\x1b[%dm", 40 + $num;
            }
            elsif ( $num < 16 ) {
                printf "\x1b[%dm", 100 + $num - 8;
            }
            elsif ( $num < $num_ansi_colors ) {
                printf "\x1b[48;5;%dm", $num;
            }
            else {
            }
            printf "   ";
            printf "\x1b[K";
            printf "\x1b[m";
        }
    }
    else {
        printf "%s", $shown;
    }
}

sub finish_query() {
    my $query;
    my $reply;
    my $n;
    my $st    = $opt_s ? qr/\007/ : qr/\x1b\\/;
    my $osc   = qr/\x1b]$this_op/;
    my $match = qr/^(${osc}.*${st})+$/;

    my $params = sprintf "%s;?;", ( join( ";?;", @query_params ) );
    $query = "\x1b]$this_op;" . $params . $ST;
    $reply = &get_reply($query);

    if ($opt_q) {
        printf "query %s\n", &visible($query);
    }
    else {
        printf "query %s%*s ", &visible($query),
          15 - length( &visible($query) ),
          " ";
    }

    if ( defined $reply ) {
        printf "reply len=%2d ", length($reply);
        if ( $reply =~ /${match}/ ) {
            my @chunks = split /${st}${osc}/, $reply;
            printf "\n" if ( $#chunks > 0 );
            for my $c ( 0 .. $#chunks ) {
                $chunks[$c] =~ s/^${osc}// if ( $c == 0 );
                $chunks[$c] =~ s/${st}$//  if ( $c == $#chunks );
                $chunks[$c] =~ s/^;//;
                printf "%3d: ", $c if ( $#chunks > 0 );
                &show_reply( $chunks[$c] );
                printf "\n" if ( $c < $#chunks );
            }
        }
        else {
            printf "? ";
            &show_reply($reply);
        }
    }
    printf "\n";
}

sub query_color($) {
    my $param = shift;
    my $op    = 4;

    if ( $param !~ /^\d+$/ ) {
        $param = &special2code($param);
        if ( $param !~ /^\d+$/ ) {
            printf STDERR "? not a color name or code: $param\n";
            return;
        }
        if ($opt_4) {
            $param += $num_ansi_colors;
        }
        else {
            $op = 5;
        }
    }
    $this_op = $op;    # FIXME handle mixed OSC 4/5

    &begin_query unless $opt_q;
    &add_param($param);
    &finish_query unless $opt_q;
}

sub query_colors($$) {
    my $lo = shift;
    my $hi = shift;
    if ( $lo =~ /^\d+$/ ) {
        my $n;
        for ( $n = $lo ; $n <= $hi ; ++$n ) {
            &query_color($n);
        }
    }
    else {
        &query_color($lo);
        &query_color($hi) unless ( $hi eq $lo );
    }
}

&begin_query if ($opt_q);

if ( $#ARGV >= 0 ) {
    while ( $#ARGV >= 0 ) {
        if ( $ARGV[0] =~ /-/ ) {
            my @args = split /-/, $ARGV[0];
            &query_colors( $args[0], $args[1] );
        }
        else {
            &query_colors( $ARGV[0], $ARGV[0] );
        }
        shift @ARGV;
    }
}
else {
    &query_colors( 0, $opt_a ? $num_ansi_colors : 7 );
}

&finish_query if ($opt_q);

1;
xterm-399/vttests/wrap.pl0000755000000000000000000001177710645542040014277 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: wrap.pl,v 1.12 2007/07/13 00:15:28 tom Exp $
# -----------------------------------------------------------------------------
# Copyright 2007 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Generates a series of wrapping lines, according to the terminal width.
# The wrapping text optionally includes double-width or other characters
# encoded in UTF-8.
use strict;

use Getopt::Std;

our ($opt_i, $opt_n, $opt_r, $opt_w);
our ($lineno, $test_string, $term_width);

# Return a string of two-column characters given an ASCII alpha/numeric string
sub double_cells($) {
	my $value = $_[0];
	$value =~ s/ /  /g;
	pack("U*",
	map { ($_ <= 32 || $_ > 127)      # if non-ASCII character...
	       ? 32                       # ...just show a blank
	       : (0xff00 + ($_ - 32))     # map to "Fullwidth Form"
	} unpack("C*", $value));          # unpack unsigned-char characters
}

# Insert a character using escape sequences to push the existing text to the
# right, write the actual character and then move left one column so succeeding
# calls will do the same.  This will not cause the pushed-text to wrap, but
# will exercise the right-margin logic in other ways.
#
# Since this script does not modify the autowrap mode, you can reset that
# outside the script and compare the default (unwrapped) versus the "-i"
# option.
sub insert_char($$) {
	my $value = $_[0];
	my $final = $_[1];
	my $cells = defined($opt_w) ? 2 : 1;
	printf "\x1b[%d@", $cells;
	printf "%s", defined($opt_w) ? double_cells($value) : $value;
	if ( ! $final ) {
		printf "\x1b[%dD", $cells;
	}
}

# vary the starting point of each line, to make a more interesting pattern
sub starts_of($) {
	my $value = $_[0];
	if (defined($opt_w)) {
		# 0,1,1,2,2,3,3,...
		$value = (($value + 1) / 2) % length($test_string);
	} else {
		$value %= length($test_string);
	}
	return $value;
}

# Vary the length of each line from $term_width - 5 to $term_width + 5, then
# double it, and then repeat.  That's 22/cycle.
sub length_of($) {
	my $value = $_[0];
	my $cycle = $value % 22;
	if ( $cycle < 11 ) {
		$value = $term_width;
	} else {
		$value = $term_width * 2;
		$cycle /= 2;
	}
	return $value + $cycle - 5;
}

# Write the text for the given line-number.
sub testit($) {
	my $number = $_[0];
	my $length = length_of($number);
	if ( defined($opt_n) ) {
		printf "%5d ", $number % 99999;
		$length -= 6;
	}
	# If we're printing double-column characters, we have half as much
	# space effectively - but don't forget the remainder, so we can push
	# the characters by single-columns.
	my $starts = starts_of($number);
	if ( defined($opt_w) ) {
		printf " ", if ( ($number % 2 ) != 0);
		$length = ($length + (($number + 1) % 2)) / 2;
	}
	my $string = substr($test_string, $starts);
	while ( length($string) < $length ) {
		$string = $string . $test_string;
	}
	$string = substr($string, 0, $length);
	if ( defined($opt_i) ) {
		my ($n, $c);
		for ($n = length($string) - 1; $n >= 0; $n--) {
			insert_char(substr($string, $n, 1), $n == 0);
		}
		printf "\n";
	} else {
		if ( defined($opt_w) ) {
			$string = double_cells($string);
		}
		printf "%s\n", $string;
	}
}

sub main::HELP_MESSAGE() {
	printf STDERR < $vt_level );
    }
    printf STDERR "? no match for $mixed with VT-level $vt_level\n"
      unless %result;
    return \%result;
}

sub failed($) {
    my $msg = shift;
    printf STDERR "? %s\n", $msg;
    exit 1;
}

sub valid_code($) {
    my $code   = shift;
    my $result = 0;
    $result = 1 if ( $code =~ /^[0-3]$/ );
    return $result;
}

sub valid_name($) {
    my $mixed  = shift;
    my $lower  = lc $mixed;
    my $result = 0;
    $result = 1 if ( defined( $caseless{$lower} ) );
    return $result;
}

sub setup_charsets($$$$) {
    my $gl_code = shift;
    my $gl_name = shift;
    my $gr_code = shift;
    my $gr_name = shift;
    my %gl_data = %{ &find_charset($gl_name) };
    my %gr_data = %{ &find_charset($gr_name) };

    return 0 unless %gl_data;
    return 0 unless %gr_data;

    &NRC(1) if ( $gl_data{NRC} or $gr_data{NRC} );

    if ( $gl_code == 0 ) {
        &G0( \%gl_data );
        &LS0;
    }
    elsif ( $gl_code == 1 ) {
        &G1( \%gl_data );
        &LS1;
    }
    elsif ( $gl_code == 2 ) {
        &G2( \%gl_data );
        &LS2;
    }
    elsif ( $gl_code == 3 ) {
        &G3( \%gl_data );
        &LS3;
    }

    if ( $gr_code == 0 ) {
        &G0( \%gr_data );
    }
    elsif ( $gr_code == 1 ) {
        &G1( \%gr_data );
        &LS1R;
    }
    elsif ( $gr_code == 2 ) {
        &G2( \%gr_data );
        &LS2R;
    }
    elsif ( $gr_code == 3 ) {
        &G3( \%gr_data );
        &LS3R;
    }
    return 1;
}

sub cleanup() {
    &setup_charsets( 0, "ASCII", 1, "ASCII" );
    &NRC(0);
}

sub doit($$$$) {
    my $gl_code = shift;
    my $gl_name = shift;
    my $gr_code = shift;
    my $gr_name = shift;

    &failed("Illegal left-code $gl_code")     unless &valid_code($gl_code);
    &failed("Illegal right-code $gr_code")    unless &valid_code($gr_code);
    &failed("Unknown left-charset $gl_name")  unless &valid_name($gl_name);
    &failed("Unknown right charset $gr_name") unless &valid_name($gr_name);

    printf "GL (G%d %s):\n", $gl_code, $gl_name;
    if ( &setup_charsets( $gl_code, $gl_name, $gr_code, $gr_name ) ) {

        for my $c ( 32 .. 127 ) {
            printf "%c", $c;
            printf "\n" if ( ( ( $c - 31 ) % 16 ) == 0 );
        }
        printf "\n";

        &cleanup;
    }

    printf "GR (G%d %s):\n", $gr_code, $gr_name;
    if ( &setup_charsets( $gl_code, $gl_name, $gr_code, $gr_name ) ) {

        for my $c ( 32 .. 127 ) {
            printf "%c", $c + 128;
            printf "\n" if ( ( ( $c - 31 ) % 16 ) == 0 );
        }
        printf "\n";

        &cleanup;
    }
}

sub main::HELP_MESSAGE() {
    printf STDERR < $vt_level );
        $known[ ++$known ] = $key;
        $width = length($key) if ( length($key) > $width );
    }
    $width += 3;
    my $cols = int( 78 / $width );
    my $high = int( ( $known + $cols ) / $cols );
    for my $y ( 0 .. $high - 1 ) {
        printf STDERR " ";
        for my $x ( 0 .. $cols - 1 ) {
            my $z = $x * $high + $y;
            next if ( $z > $known );
            printf STDERR "%-*s", $width, $known[$z];
        }
        printf STDERR "\n";
    }
    exit 1;
}

&init_charset( "ASCII",              0, 'B',  1, 9, 0 );
&init_charset( "British",            0, 'A',  1, 9, 0 );
&init_charset( "DEC_Spec_Graphic",   0, '0',  1, 9, 0 );
&init_charset( "DEC_Alt_Chars",      0, '1',  1, 1, 0 );
&init_charset( "DEC_Alt_Graphics",   0, '2',  1, 1, 0 );
&init_charset( "DEC_Supp",           0, '<',  2, 9, 0 );
&init_charset( "Dutch",              0, '4',  2, 9, 1 );
&init_charset( "Finnish",            0, '5',  2, 9, 1 );
&init_charset( "Finnish2",           0, 'C',  2, 9, 1 );
&init_charset( "French",             0, 'R',  2, 9, 1 );
&init_charset( "French2",            0, 'f',  2, 9, 1 );
&init_charset( "French_Canadian",    0, 'Q',  2, 9, 1 );
&init_charset( "German",             0, 'K',  2, 9, 1 );
&init_charset( "Italian",            0, 'Y',  2, 9, 1 );
&init_charset( "Norwegian_Danish2",  0, 'E',  2, 9, 1 );
&init_charset( "Norwegian_Danish3",  0, '6',  2, 9, 1 );
&init_charset( "Spanish",            0, 'Z',  2, 9, 1 );
&init_charset( "Swedish",            0, '7',  2, 9, 1 );
&init_charset( "Swedish2",           0, 'H',  2, 9, 1 );
&init_charset( "Swiss",              0, '=',  2, 9, 1 );
&init_charset( "British_Latin_1",    0, 'A',  3, 9, 1 );
&init_charset( "DEC_Supp_Graphic",   0, '%5', 3, 9, 0 );
&init_charset( "DEC_Technical",      0, '>',  3, 9, 0 );
&init_charset( "French_Canadian2",   0, '9',  3, 9, 1 );
&init_charset( "Norwegian_Danish",   0, '`',  3, 9, 1 );
&init_charset( "Portuguese",         0, '%6', 3, 9, 1 );
&init_charset( "ISO_Greek_Supp",     1, 'F',  5, 9, 0 );
&init_charset( "ISO_Hebrew_Supp",    1, 'H',  5, 9, 0 );
&init_charset( "ISO_Latin_5_Supp",   1, 'M',  5, 9, 0 );
&init_charset( "ISO_Latin_Cyrillic", 1, 'L',  5, 9, 0 );
&init_charset( "Greek",              0, '">', 5, 9, 1 );
&init_charset( "DEC_Greek",          0, '"?', 5, 9, 1 );
&init_charset( "Cyrillic",           0, '&4', 5, 9, 0 );
&init_charset( "DEC_Hebrew",         0, '"4', 5, 9, 0 );
&init_charset( "Hebrew",             0, '%=', 5, 9, 1 );
&init_charset( "Russian",            0, '&5', 5, 9, 1 );
&init_charset( "SCS_NRCS",           0, '%3', 5, 9, 0 );
&init_charset( "Turkish",            0, '%2', 5, 9, 1 );
&init_charset( "DEC_Turkish",        0, '%0', 5, 9, 0 );

$vt_level = 1;    # don't expect much
if ( -t 0 and -t 1 ) {
    my $da2 = `
	old=\$(stty -g);
	stty raw -echo min 0  time 5;
	printf '\033[>c' >/dev/tty;
	read response;
	stty \$old;
	echo "\$response"`;
    if ( $da2 =~ /^\033\[>\d+;\d+;\d+c$/ ) {
        my $Pp = $da2;
        $Pp =~ s/^.*>//;
        $Pp =~ s/;.*$//;
        if ( $Pp == 0 ) {
            $vt_level = 1;
        }
        elsif ( $Pp == 1 or $Pp == 2 ) {
            $vt_level = 2;
        }
        elsif ( $Pp == 18 or $Pp == 19 or $Pp == 24 ) {
            $vt_level = 3;
        }
        elsif ( $Pp == 41 ) {
            $vt_level = 4;
        }
        elsif ( $Pp == 61 or $Pp == 64 or $Pp == 65 ) {
            $vt_level = 5;
        }
    }
}

$Getopt::Std::STANDARD_HELP_VERSION = 1;
&getopts('L:l:R:r:v:') || main::HELP_MESSAGE;
$vt_level = $opt_v if ( defined $opt_v );
&failed("VT-level must be 1-5") if ( $vt_level < 1 or $vt_level > 5 );

if ( $#ARGV >= 0 ) {
    while ( $#ARGV >= 0 ) {
        my $name = shift @ARGV;
        &doit(
            defined($opt_L) ? $opt_L : 2,        #
            defined($opt_l) ? $opt_l : $name,    #
            defined($opt_R) ? $opt_R : 3,        #
            defined($opt_r) ? $opt_r : $name
        );
        last
          if (
            defined($opt_L)                      #
            and defined($opt_l)                  #
            and defined($opt_R)                  #
            and defined($opt_r)
          );
    }
}
else {
    &doit(
        defined($opt_L) ? $opt_L : 2,            #
        defined($opt_l) ? $opt_l : "ASCII",      #
        defined($opt_R) ? $opt_R : 3,            #
        defined($opt_r) ? $opt_r : "ASCII"
    );
}

1;
xterm-399/vttests/decsed.pl0000755000000000000000000001154212472231320014537 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: decsed.pl,v 1.6 2015/02/22 01:37:20 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2015 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Exercise DECSED (erase display) with or without DECSCA (protect against
# DECSED).
use strict;

use Getopt::Std;

our ( $opt_c,  $opt_n,       $opt_p,     $opt_w );
our ( $lineno, $test_string, $term_wide, $term_high );

sub move($$) {
    my $y = shift;
    my $x = shift;
    printf "\x1b[%d;%dH", $y, $x;
}

sub protect($) {
    my $code = shift;
    printf "\x1b[%d\"q", $code;
}

sub set_color($) {
    my $code = shift;
    if ( $code == 1 ) {
        printf "\x1b[0;36;44m";    # cyan-on-blue
    }
    else {
        printf "\x1b[0;39;49m";
    }
}

# returns a string of two-column characters given an ASCII alpha/numeric string
sub double_cells($) {
    my $value = $_[0];
    $value =~ s/ /  /g;
    pack(
        "U*",
        map {
            ( $_ <= 32 || $_ > 127 )    # if non-ASCII character...
              ? 32                      # ...just show a blank
              : ( 0xff00 + ( $_ - 32 ) )    # map to "Fullwidth Form"
          } unpack( "C*", $value )
    );                                      # unpack unsigned-char characters
}

# write the text for the given line-number
sub fill_line($$) {
    my $number = shift;
    my $offset = shift;
    my $length = $opt_w ? ( $term_wide / 2 ) : $term_wide;
    my $actual;
    my $margin = 0;
    $actual = $length;
    my $string = $test_string;
    while ( ( $opt_w ? ( 2 * length($string) ) : length($string) ) <
        ( $offset + $length ) )
    {
        $string = $string . $test_string;
    }
    $string = substr( $string, $offset, $length );
    $string = double_cells($string) if ($opt_w);
    printf "%s", $string;

    printf "\n";
    return ++$offset;
}

sub main::HELP_MESSAGE() {
    printf STDERR <= 0 ) ? $ARGV[0] : 2;
my $parm_ycoord = ( $#ARGV >= 1 ) ? $ARGV[1] : $term_high / 2;
my $parm_xcoord = ( $#ARGV >= 2 ) ? $ARGV[2] : $term_wide / 2;

binmode( STDOUT, ":utf8" );
&protect(1)   if ($opt_p);
&set_color(1) if ($opt_c);
if ( $opt_n or $opt_w ) {
    my $offset = 0;
    for ( $lineno = 0 ; $lineno < $term_high - 1 ; ++$lineno ) {
        $offset = &fill_line( $lineno, $offset );
    }
}
else {
    printf "\x1b#8";    # DECALN
}
&move( $parm_ycoord, $parm_xcoord );
printf '*';
&move( $parm_ycoord, $parm_xcoord );
printf "\x1b[?%dJ", $parm_DECSED;
if ( $parm_DECSED == 0 ) {
    &move( $parm_ycoord + 1, $parm_xcoord );
}
elsif ( $parm_DECSED == 1 ) {
    &move( $parm_ycoord - 1, $parm_xcoord );
}
&set_color(0) if ($opt_c);
&protect(0)   if ($opt_p);

exit;
xterm-399/vttests/dynamic2.sh0000755000000000000000000000644414231454632015032 0ustar  rootroot#!/bin/sh
# $XTermId: dynamic2.sh,v 1.11 2022/04/25 08:19:38 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2006-2021,2022 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Demonstrate the use of dynamic colors by setting each dynamic color
# successively to different values.

ESC=""
OSC="${ESC}]"
CMD='/bin/echo'
OPT='-n'
SUF=''
: "${TMPDIR=/tmp}"
TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$"
eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null
{ test ! -f "$TMP" || test -s "$TMP"; } &&
for verb in "printf" "print" ; do
    rm -f "$TMP"
    eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null
    if test -f "$TMP" ; then
	if test ! -s "$TMP" ; then
	    CMD="$verb"
	    OPT=
	    SUF='\c'
	    break
	fi
    fi
done
rm -f "$TMP"

LIST="00 30 80 d0 ff"
FULL="10 11 12 13 14 15 16 17 18"

echo "reading current color settings"

exec  /dev/tty
    read -r reply
    eval original"$N"='${reply}${SUF}'
    original=${original}${reply}${SUF}
done
stty $old

trap '$CMD $OPT "$original" >/dev/tty; exit 1' 1 2 3 15
trap '$CMD $OPT "$original" >/dev/tty' 0

while true
do
    for N in $FULL
    do
	case $N in
	10) echo "coloring text foreground";;
	11) echo "coloring text background";;
	12) echo "coloring text cursor";;
	13) echo "coloring mouse foreground";;
	14) echo "coloring mouse background";;
	15) echo "coloring tektronix foreground";;
	16) echo "coloring tektronix background";;
	17) echo "coloring highlight background";;
	18) echo "coloring tektronix cursor";;
	esac
	for R in $LIST
	do
	    for G in $LIST
	    do
		for B in $LIST
		do
		    $CMD $OPT "${OSC}$N;rgb:$R/$G/$B${SUF}" >/dev/tty
		    sleep 1
		done
	    done
	done
	eval restore=\$original"$N"
	$CMD $OPT "$restore" >/dev/tty
	sleep 1
    done
done
xterm-399/vttests/doublechars.sh0000755000000000000000000000673114231626765015626 0ustar  rootroot#!/bin/sh
# $XTermId: doublechars.sh,v 1.26 2022/04/25 23:25:41 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 1999-2021,2022 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Illustrate the use of double-size characters by drawing successive lines in
# the commonly used video attributes.
#
# Use the -w option to force the output to wrap.  It will look ugly, because
# the double-high lines will be split.

ESC=""
CSI="${ESC}["
CMD='/bin/echo'
OPT='-n'
SUF=''
: "${TMPDIR=/tmp}"
TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$"
eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null
{ test ! -f "$TMP" || test -s "$TMP"; } &&
for verb in "printf" "print" ; do
    rm -f "$TMP"
    eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null
    if test -f "$TMP" ; then
	if test ! -s "$TMP" ; then
	    CMD="$verb"
	    OPT=
	    SUF='\c'
	    break
	fi
    fi
done
rm -f "$TMP"

ITAL=no
SAVE=yes
WRAP=no
if test $# != 0 ; then
    while test $# != 0
    do
    	case $1 in
	-i)	ITAL=yes ;;
	-n)	SAVE=no ;;
	-w)	WRAP=yes ;;
	*)
		echo "usage: $0 [-i] [-n] [-w]"
		exit 1
	esac
	shift
    done
fi

if test $SAVE = yes ; then
    exec  /dev/tty
    IFS=';' read -r junk high wide

    stty $old

    wide=`echo "$wide"|sed -e 's/t.*//'`
    original=${CSI}8\;${high}\;${wide}t${SUF}

    trap '$CMD $OPT "$original" >/dev/tty; exit 1' 1 2 3 15
    trap '$CMD $OPT "$original" >/dev/tty' 0

fi

if test $WRAP = yes ; then
	# turn on wrapping and force the screen to 80 columns
	$CMD $OPT "${CSI}?7h" >/dev/tty
	$CMD $OPT "${CSI}?40l" >/dev/tty
else
	# force the screen to 132 columns
	$CMD $OPT "${CSI}?40h" >/dev/tty
	$CMD $OPT "${CSI}?3h" >/dev/tty
fi

for SGR in 0 1 4 5 7
do
	$CMD $OPT "${CSI}0;${SGR}m" >/dev/tty
	test "$ITAL" = yes && $CMD $OPT "${CSI}3m" >/dev/tty
	for DBL in 5 3 4 6 5
	do
		$CMD $OPT "${ESC}#${DBL}" >/dev/tty
		echo "The quick brown fox jumps over the lazy dog" >/dev/tty
	done
	echo
done
$CMD $OPT "${CSI}0m" >/dev/tty
xterm-399/vttests/cursor.pl0000755000000000000000000001062610724652075014643 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: cursor.pl,v 1.8 2007/12/03 00:56:29 tom Exp $
# -----------------------------------------------------------------------------
# Copyright 2007 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Read a file (or pipe from a program) and move the cursor around the screen
# in response to h,j,k,l commands so we can see the colors that affect the
# cursor.  Exit on 'q'.  Do forward/backward paging to \E[J markers
# in the data with n,p.  Ignore other characters.
#
# Use this rather than, say, a curses program since it is much easier to
# construct a particular screen using 'script' or echo commands than to
# guarantee the same screen with curses' optimization.

use strict;

use Getopt::Std;
use IO::Handle;

our ( $opt_x );
our ( $row_max, $col_max );
our $old_stty;
our $text_blob;
our $text_1st;
our $text_2nd;
our $text_chop = qw/^\x1b\[H\x1b\[J/;
our $text_mark = "\x1b[H\x1b[J";

sub get_screensize() {
	my @reply = `resize -u`;
	chomp @reply;
	for my $n (0..$#reply) {
		if ( $reply[$n] =~ /=/ ) {
			my $value = $reply[$n];
			$value =~ s/^.*=//;
			if ( $reply[$n] =~ /^COLUMNS.*/ ) {
				$col_max = $value;
			} else {
				$row_max = $value;
			}
		}
	}
}

sub end_cursor($) {
	close TTY;
	system "stty $old_stty";
	print $_[0];
	exit;
}

sub begin_cursor() {
	open TTY, "+;
		# printf "get_char\r\n";
	} while (not defined $reply);
	return $reply;
}

sub move_to($$) {
	my $y = $_[0];
	my $x = $_[1];
	if ( $y < 0 ) {
		$y = 0;
	} elsif ( $x < 0 ) {
		$x = 0;
	} elsif ( $y >= $row_max ) {
		$y -= 1;
	} elsif ( $x >= $col_max ) {
		$x -= 1;
	} else {
		printf "\x1b[%d;%dH", $y + 1, $x + 1;
	}
	return ( $y, $x );
}

sub vxt_cursor() {
	my $ch;
	my $x = 0;
	my $y = 0;
	my @pages = split $text_chop, $text_blob;
	my $page = 1;

my_page:
	move_to ($y, $x);
	printf "%s", $text_mark . $pages[$page];
	move_to ($y, $x);
my_loop:
	for (;;) {
		$ch = get_char();
		if ( $ch eq "q") {
			last my_loop;
		} elsif ( $ch eq "h" ) {
			($y, $x) = move_to($y, $x - 1);
		} elsif ( $ch eq "j" ) {
			($y, $x) = move_to($y + 1, $x);
		} elsif ( $ch eq "k" ) {
			($y, $x) = move_to($y - 1, $x);
		} elsif ( $ch eq "l" ) {
			($y, $x) = move_to($y, $x + 1);
		} elsif ( $ch eq "n" ) {
			if ( $page < $#pages ) {
				$page += 1;
				goto my_page;
			} else {
				beep();
			}
		} elsif ( $ch eq "p" ) {
			if ( $page > 1 ) {
				$page -= 1;
				goto my_page;
			} else {
				beep();
			}
		} else {
			beep();
			# printf "got:%s\r\n", $ch;
		}
	}
}

sub load_text($) {
	my $source = $_[0];
	my $text;
	if ( defined($opt_x) ) {
		$text = `$source`;
	} else {
		$text = `cat $source`;
	}
	$text =~ s/\n/\r\n/g;
	if ( $text !~ $text_chop ) {
		$text = $text_mark . $text;
	}
	$text_blob = $text_blob . $text;
}

&getopts('x') || die();

while ( $#ARGV >= 0 ) {
	load_text ( shift @ARGV );
}

get_screensize();
begin_cursor();
vxt_cursor();
end_cursor("Done\n");
xterm-399/vttests/dynamic.sh0000755000000000000000000000522314231454632014742 0ustar  rootroot#!/bin/sh
# $XTermId: dynamic.sh,v 1.25 2022/04/25 08:19:38 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 1999-2021,2022 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Demonstrate the use of dynamic colors by setting the background successively
# to different values.

ESC=""
OSC="${ESC}]"
CMD='/bin/echo'
OPT='-n'
SUF=''
: "${TMPDIR=/tmp}"
TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$"
eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null
{ test ! -f "$TMP" || test -s "$TMP"; } &&
for verb in "printf" "print" ; do
    rm -f "$TMP"
    eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null
    if test -f "$TMP" ; then
	if test ! -s "$TMP" ; then
	    CMD="$verb"
	    OPT=
	    SUF='\c'
	    break
	fi
    fi
done
rm -f "$TMP"

LIST="00 30 80 d0 ff"

exec  /dev/tty
read -r original
stty $old
original=${original}${SUF}

trap '$CMD $OPT "$original" >/dev/tty; exit 1' 1 2 3 15
trap '$CMD $OPT "$original" >/dev/tty' 0

while true
do
    for R in $LIST
    do
	for G in $LIST
	do
	    for B in $LIST
	    do
		$CMD $OPT "${OSC}11;rgb:$R/$G/$B${SUF}" >/dev/tty
		sleep 1
	    done
	done
    done
done
xterm-399/vttests/xorblink.pl0000755000000000000000000001753113220013072015136 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: xorblink.pl,v 1.16 2017/12/24 21:03:54 tom Exp $
# -----------------------------------------------------------------------------
# Copyright 2017 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# walk through the different states of cursor-blinking, with annotation
#
# Manual:
#        +bc     turn off text cursor blinking.  This overrides the cursorBlink
#                resource.
#
#        -bc     turn on text cursor blinking.  This overrides the cursorBlink
#                resource.
#
#        cursorBlink (class CursorBlink)
#                Specifies whether to make the cursor blink.  The default is
#                "false".
#
#                Xterm-dev uses two variables to determine whether the cursor
#                blinks.  One is set by this resource.  The other is set by
#                control sequences (private mode 12 and DECSCUSR).  Xterm-dev
#                tests the XOR of the two variables.
#
#               Enable Blinking Cursor (resource cursorblink)
#                      Enable (or disable) the blinking-cursor feature.  This
#                      corresponds to the -bc option and the cursorBlink
#                      resource.  There is also an escape sequence (see Xterm-
#                      dev Control Sequences).  The menu entry and the escape
#                      sequence states are XOR'd: if both are enabled, the
#                      cursor will not blink, if only one is enabled, the cursor
#                      will blink.
#
#        set-cursorblink(on/off/toggle)
#                This action sets, unsets or toggles the cursorBlink resource.
#                It is also invoked from the cursorblink entry in vtMenu.
#
# Control sequences:
#
# CSI ? Pm h
#           DEC Private Mode Set (DECSET).
#             Ps = 1 2  -> Start Blinking Cursor (att610).
#
# CSI ? Pm l
#           DEC Private Mode Reset (DECRST).
#             Ps = 1 2  -> Stop Blinking Cursor (att610).
#
# CSI Ps SP q
#           Set cursor style (DECSCUSR, VT520).
#             Ps = 0  -> blinking block.
#             Ps = 1  -> blinking block (default).
#             Ps = 2  -> steady block.
#             Ps = 3  -> blinking underline.
#             Ps = 4  -> steady underline.
#             Ps = 5  -> blinking bar (xterm).
#             Ps = 6  -> steady bar (xterm).
#
use strict;

use Term::ReadKey;

use IO::Handle;
STDERR->autoflush(1);
STDOUT->autoflush(1);

our %DECSET = (
    "\e[?12h", "Start Blinking Cursor (AT&T 610)",
    "\e[?12l", "Stop Blinking Cursor (AT&T 610)"
);

our %DECSCUSR = (
    "\e[0 q",
    "blinking block",
    "\e[1 q",
    "blinking block (default)",
    "\e[2 q",
    "steady block",
    "\e[3 q",
    "blinking underline",
    "\e[4 q",
    "steady underline",
    "\e[5 q",
    "blinking bar (xterm)",
    "\e[6 q",
    "steady bar (xterm)"
);

sub show($$) {
    my $seq = shift;
    my $txt = shift;
    printf "%s -> %s\n", &visible($seq), $txt;
}

sub get_reply($$) {
    my $seq = shift;
    my $end = shift;
    printf STDERR "%s", $seq;
    my $key;
    my $result = "";
    $key = ReadKey(0);
    $result .= $key;
    if ( $key eq "\e" ) {

        while (1) {
            $key = ReadKey(100);
            $result .= $key;
            next if ( length($result) < length($end) );
            last if ( substr( $result, -length($end) ) eq $end );
        }
    }
    return $result;
}

sub mode_value($) {
    my $value = shift;
    if ( $value eq 1 ) {
        $value = "set";
    }
    elsif ( $value eq 2 ) {
        $value = "reset";
    }
    elsif ( $value eq 3 ) {
        $value = "*set";
    }
    elsif ( $value eq 4 ) {
        $value = "*reset";
    }
    else {
        $value = &visible( "?" . $value );
    }
    return $value;
}

sub DECRQM($) {
    my $mode     = shift;
    my $sequence = sprintf( "\e[?%d\$p", $mode );
    my $reply    = &get_reply( $sequence, "y" );
    if ( $reply =~ /^\e\[\?$mode;\d+\$y$/ ) {
        $reply =~ s/^\e\[\?$mode;(\d+)\$y$/$1/;
    }
    return &mode_value($reply);
}

sub DECRQSS($) {
    my $request  = shift;
    my $ending   = "\e\\";
    my $sequence = sprintf( "\eP\$q%s$ending", $request );
    my $reply    = &get_reply( $sequence, $ending );

    # xterm responds with
    # DCS 1 $ r Pt ST for valid requests,
    # DCS 0 $ r Pt ST for invalid requests.
    #if ( $reply =~ /^\eP1\$r.*$ending$/ ) {
    if ( $reply =~ /^\eP1\$r\d+ q\e\\$/ ) {
        $reply =~ s/^\eP1\$r(\d+) q\e\\$/$1/;
    }
    return &visible($reply);
}

sub get_key() {
    my $key;
    do {
        $key = ReadKey(0);
        if ( $key eq "\e" ) {
            while ( ReadKey(10) !~ /[@-~]/ ) {
                #
            }
        }
    } while ( $key eq "\e" );
    return $key;
}

sub visible($) {
    my $txt = shift;
    $txt =~ s/\e/\\e/g;
    $txt =~ s/\a/\\a/g;
    return $txt;
}

sub test($$) {
    my $set = shift;
    my $msg = shift;

    ReadMode 'raw';

    printf STDERR "%s\t[", &visible($set);

    # save the cursor position
    printf STDERR "\e7";

    # send the escape sequence
    printf STDERR "%s", $set;

    # print the description
    printf STDERR "X] ";

    printf STDERR " [C=%s,",  &DECRQSS(" q");
    printf STDERR "B=%s,",    &DECRQM(12);
    printf STDERR "M=%s,%s]", &DECRQM(13), &DECRQM(14);
    printf STDERR " %s",      $msg;
    printf STDERR "\e[0J";

    # restore the cursor position
    printf STDERR "\e8";

    # wait for any key
    my $key = &get_key;
    ReadMode 'restore';

    # print newline
    printf STDERR "\n";

    # A backspace response makes the current line reprint (to test menus)
    return ( $key ne "\b" and $key ne "\177" ) ? 1 : 0;
}

if ( -t STDOUT ) {
    printf "Legend:\n";
    printf "  C = cursor shape (1,2 block, 3,4 underline, 5,6 left-bar)\n";
    printf "  B = escape-sequence blink\n";
    printf "  M = menu blink and XOR mode\n";
    printf "\n";
    printf "An asterisk means the mode is always set or reset.\n";
    printf "Press any key to proceed; press backspace to reprint line.\n";
    printf "\n";
    my @DECSET   = sort keys %DECSET;
    my @DECSCUSR = sort keys %DECSCUSR;

    for ( my $h = 0 ; $h <= $#DECSET ; ++$h ) {
        $h-- unless &test( $DECSET[$h], $DECSET{ $DECSET[$h] } );
    }
    for my $l ( 0 .. $#DECSCUSR ) {
        $l-- unless &test( $DECSCUSR[$l], $DECSCUSR{ $DECSCUSR[$l] } );
    }
}
else {
    printf "DECSET (AT&T 610 blinking cursor):\n";
    for my $key ( sort keys %DECSET ) {
        &show( $key, $DECSET{$key} );
    }

    printf "DECSCUSR:\n";
    for my $key ( sort keys %DECSCUSR ) {
        &show( $key, $DECSCUSR{$key} );
    }
}
1;
xterm-399/vttests/bounce.sh0000755000000000000000000000370513606721344014576 0ustar  rootroot#!/bin/sh
# $XTermId: bounce.sh,v 1.3 2020/01/12 22:51:16 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2020 by Thomas E. Dickey
# 
#                         All Rights Reserved
# 
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# 
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# 
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# iconify/deiconify, recording the window properties
LOG=1
logit() {
	sleep 2
	[ -n "$WINDOWID" ] && xprop -id $WINDOWID >bounce${LOG}.log
	LOG=`expr $LOG + 1`
}

[ -n "$WINDOWID" ] && rm -f bounce*.log

printf 'Hello ...\n'
logit

printf '\033[2t'
logit

printf '\033[1t'
logit

printf 'World!\n'
logit

[ -n "$WINDOWID" ] && ls -l bounce*.log
xterm-399/vttests/blink.pl0000755000000000000000000001010010645543466014415 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: blink.pl,v 1.2 2007/07/13 00:28:38 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2007 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Write a test pattern which includes some blinking text in scattered
# locations, to test scrollback of blinking text.
use strict;

use Getopt::Std;

our ($opt_n, $opt_r, $opt_w);
our ($lineno, $test_string, $term_width);

# returns a string of two-column characters given an ASCII alpha/numeric string
sub double_cells($) {
	my $value = $_[0];
	$value =~ s/ /  /g;
	pack("U*",
	map { ($_ <= 32 || $_ > 127)      # if non-ASCII character...
	       ? 32                       # ...just show a blank
	       : (0xff00 + ($_ - 32))     # map to "Fullwidth Form"
	} unpack("C*", $value));          # unpack unsigned-char characters
}

# vary the starting point of each line, to make a more interesting pattern
sub starts_of($) {
	my $value = $_[0];
	if (defined($opt_w)) {
		# 0,1,1,2,2,3,3,...
		$value = (($value + 1) / 2) % length($test_string);
	} else {
		$value %= length($test_string);
	}
	return $value;
}

# vary the length of each line from $term_width - 5 to $term_width + 5, then
# double it, and then repeat.  That's 22/cycle.
sub length_of($) {
	my $value = $_[0];
	my $cycle = $value % 22;
	if ( $cycle < 11 ) {
		$value = $term_width;
	} else {
		$value = $term_width * 2;
		$cycle /= 2;
	}
	return $value + $cycle - 5;
}

# write the text for the given line-number
sub testit($) {
	my $number = $_[0];
	my $length = length_of($number);
	if ( defined($opt_n) ) {
		printf "%5d ", $number % 99999;
		$length -= 6;
	}
	# if we're printing double-column characters, we have half as much
	# space effectively - but don't forget the remainder, so we can push
	# the characters by single-columns.
	my $starts = starts_of($number);
	if ( defined($opt_w) ) {
		printf " ", if ( ($number % 2 ) != 0);
		$length = ($length + (($number + 1) % 2)) / 2;
	}
	my $string = substr($test_string, $starts);
	while ( length($string) < $length ) {
		$string = $string . $test_string;
	}
	$string = substr($string, 0, $length);
	if ( defined($opt_w) ) {
		$string = double_cells($string);
	}
	printf "%s\n", $string;
}

sub main::HELP_MESSAGE() {
	printf STDERR <;
    close TTY;
    system "stty $old";
    if ( defined $reply ) {
        die("^C received\n") if ( "$reply" eq "\003" );
    }
    return $reply;
}

sub query_color($) {
    my $code   = $_[0];
    my $param1 = $code + 10;
    my $reply;

    $reply = get_reply("\x1b]$param1;?\007");

    return unless defined $reply;
    if ( $reply =~ /\x1b]$param1;.*\007/ ) {
        my $value = $reply;

        $value =~ s/^\x1b]$param1;//;
        $value =~ s/\007//;

        printf "%24s = %s\n", $color_names[$code], $value;
    }
}

sub query_colors() {
    my $n;

    for ( $n = 0 ; $n <= 9 ; ++$n ) {
        &query_color($n);
    }
}

sub reset_colors() {
    my $n;

    for ( $n = 0 ; $n <= 9 ; ++$n ) {
        my $code = 110 + $n;
        &no_reply("\x1b]$code\007");
    }
}

if ( defined($opt_c) ) {
    &no_reply("\x1b]12;$opt_c\007");
}
if ( defined($opt_r) ) {
    &reset_colors();
}

&query_colors();
xterm-399/vttests/fonts.sh0000755000000000000000000000514214231454632014447 0ustar  rootroot#!/bin/sh
# $XTermId: fonts.sh,v 1.20 2022/04/25 08:19:38 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 1999-2021,2022 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Demonstrate control sequence which sets relative fonts.

ESC=""
CSI="${ESC}["
CMD='/bin/echo'
OPT='-n'
SUF=''
: "${TMPDIR=/tmp}"
TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$"
eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null
{ test ! -f "$TMP" || test -s "$TMP"; } &&
for verb in "printf" "print" ; do
    rm -f "$TMP"
    eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null
    if test -f "$TMP" ; then
	if test ! -s "$TMP" ; then
	    CMD="$verb"
	    OPT=
	    SUF='\c'
	    break
	fi
    fi
done
rm -f "$TMP"

exec  /dev/tty
read -r original

stty $old
original="${original}${SUF}"

trap '$CMD $OPT "$original" >/dev/tty; exit 1' 1 2 3 15
trap '$CMD $OPT "$original" >/dev/tty' 0

F=1
D=1
T=6
while true
do
    $CMD $OPT "${ESC}]50;#$F${SUF}" >/dev/tty
    sleep 1
    if test .$D = .1 ; then
	test $F = $T && D=-1
    else
	test $F = 1 && D=1
    fi
    F=`expr $F + $D`
done
xterm-399/vttests/resize.pl0000755000000000000000000000764513041175436014632 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: resize.pl,v 1.6 2017/01/22 18:34:06 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2004-2014,2017 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# resize.sh rewritten into Perl for comparison.
# See also Term::ReadKey.

use strict;
use warnings;

use IO::Handle;

sub write_tty {
    open TTY, "+;
    close TTY;
    system "stty $old";
    return $reply;
}

sub csi_field {
    my $first  = $_[0];
    my $second = $_[1];
    $first =~ s/^[^0-9]+//;
    while ( --$second > 0 ) {
        $first =~ s/^[\d]+//;
        $first =~ s/^[^\d]+//;
    }
    $first =~ s/[^\d]+.*$//;
    return $first;
}

our $original = get_reply("\x1b[18t");
our $high;
our $wide;

if ( defined($original) and ( $original =~ /\x1b\[8;\d+;\d+t/ ) ) {
    $high = csi_field( $original, 2 );
    $wide = csi_field( $original, 3 );
    printf "parsed terminal size $high,$wide\n";
}
else {
    die "Cannot get current terminal size via escape sequence\n";
}

#
our $maximize = get_reply("\x1b[19t");
our $maxhigh;
our $maxwide;

if ( defined($maximize) and ( $maximize =~ /^\x1b\[9;\d+;\d+t/ ) ) {
    $maxhigh = csi_field( $maximize, 2 );
    $maxwide = csi_field( $maximize, 3 );
    $maxhigh != 0 or $maxhigh = $high * 2;
    $maxwide != 0 or $maxwide = $wide * 2;
    printf "parsed terminal maxsize $maxhigh,$maxwide\n";
}
else {
    die "Cannot get maximum terminal size via escape sequence\n";
}

our $zapped;
our ( $w, $h, $a );

sub catch_zap {
    $zapped++;
}
$SIG{INT}  = \&catch_zap;
$SIG{QUIT} = \&catch_zap;
$SIG{KILL} = \&catch_zap;
$SIG{HUP}  = \&catch_zap;
$SIG{TERM} = \&catch_zap;

$w      = $wide;
$h      = $high;
$a      = 1;
$zapped = 0;
while ( $zapped == 0 ) {

    #	sleep 1
    printf "resizing to $h by $w\n";
    write_tty( "\x1b[8;$h;$w" . "t" );
    if ( $a == 1 ) {
        if ( $w == $maxwide ) {
            $h += $a;
            if ( $h = $maxhigh ) {
                $a = -1;
            }
        }
        else {
            $w += $a;
        }
    }
    else {
        if ( $w == $wide ) {
            $h += $a;
            if ( $h = $high ) {
                $a = 1;
            }
        }
        else {
            $w += $a;
        }
    }
}
write_tty($original);
xterm-399/vttests/modify-keys.pl0000755000000000000000000014012314762173130015556 0ustar  rootroot#!/usr/bin/env perl
# $XTermId: modify-keys.pl,v 1.94 2025/03/06 01:11:52 tom Exp $
# -----------------------------------------------------------------------------
# this file is part of xterm
#
# Copyright 2019-2022,2025 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# Print a table to illustrate the modifyOtherKeys resource choices.
#
# Some of the key combinations are unavailable unless certain translations
# resource settings are suppressed.  This command helped to verify those:
#	xterm -xrm '*omitTranslation:fullscreen,scroll-lock,shift-fonts'
#
# Additionally, a test-script was written to exercise xterm when the
# "Allow SendEvents" feature is enabled, in combination with keys sent by
# commands like this:
#	xdotool key --window XXX shift 2>/dev/null
#
# A curses application running in the target xterm showed the received data
# in the terminfo-style format used in this script.

# TODO factor in the backspace/delete meta/alt/escape resource-settings
# TODO show keycodes via "xmodmap -pk" as alternative to xkbcomp
# TODO show different sort-order (code, sym, xkb)
# TODO use U+xxxx codepoints in keysymdef.h for rendering plain text
# TODO optionally show 2**N, e.g., 4 (shift+control), 8 (shift+alt+control) or 16 (+meta) modifiers
# TODO optionally show -c (cursor) -e (edit) -f (function-keys) with modifiers

use strict;
use warnings;

use Getopt::Std;

$| = 1;

our (
    $opt_d, $opt_h, $opt_k, $opt_K, $opt_l,
    $opt_m, $opt_M, $opt_o, $opt_u, $opt_v
);

our $REPORT;
our @headers;
our @nolinks = ();
our ( $xkb_layout, $xkb_model );
our $keyfile = "/usr/include/X11/keysymdef.h";

our @keyNames;    # xkb's notion of key-names (undocumented)
our %keySyms;     # all keysyms, hashed by name
our %keyCodes;    # all keysyms, hashed by keycode
our %uniCodes;    # keysym Unicode values, hashed by keycode
our %uniNames;    # keysym Unicode descriptions, hashed by keycode
our @keyTypes;    # XkbKeyTypeRec
our @symCache;    # keysyms defined in keysymdef.h which might be used
our @symMap;      # index into symCache from keyNames
our %keysUsed;    # report derived from @symMap, etc.
our %linkUsed;    # check for uniqueness of html anchor-names

our $modify_mods;
our $MAXMODS = 8;    # maximum for modifier-param
our %Shifted;        # map keycode to shifted-keycode seen by xterm

# imitate /usr/include/X11/X.h
our $ShiftMask   = 1;
our $LockMask    = 2;
our $ControlMask = 4;
our $AltMask     = 8;     # assume mod1=alt
our $MetaMask    = 16;    # assume mod2=meta

our %editKeys = qw(
  XK_Delete             1
  XK_Prior              1
  XK_Next               1
  XK_Insert             1
  XK_Find               1
  XK_Select             1
  XK_KP_Delete          1
  XK_KP_Insert          1
  XK_ISO_Left_Tab       1
);

sub failed($) {
    printf STDERR "%s\n", $_[0];
    exit 1;
}

# prefer hex with 4 digit for hash keys
sub toCode($) {
    my $value = shift;
    $value = sprintf( "0x%04x", $value ) if ( $value =~ /^\d+$/ );
    return $value;
}

sub codeOf($) {
    my $value  = shift;
    my $result = 0;
    &failed("missing keysym") unless ( defined $value );
    if ( $value =~ /^\d+$/ ) {
        $result = $value;
    }
    elsif ( $value =~ /^0x[[:xdigit:]]+$/i ) {
        $result = hex $value;
    }
    elsif ( $value =~ /^XK_/ ) {
        $result = hex $keySyms{$value};
    }
    else {
        &failed("not a keysym: $value");
    }
    return $result;
}

# macros from 

sub IsKeypadKey($) {
    my $code   = &codeOf( $_[0] );
    my $result = ( ( $code >= &codeOf("XK_KP_Space") )
          and ( $code <= &codeOf("XK_KP_Equal") ) ) ? 1 : 0;
    return $result;
}

sub IsPrivateKeypadKey($) {
    my $code = &codeOf( $_[0] );
    my $result =
      ( ( $code >= 0x11000000 ) and ( $code <= 0x1100FFFF ) ) ? 1 : 0;
    return $result;
}

sub IsCursorKey($) {
    my $code = &codeOf( $_[0] );
    my $result =
      ( ( $code >= &codeOf("XK_Home") ) and ( $code < &codeOf("XK_Select") ) )
      ? 1
      : 0;
    return $result;
}

sub IsPFKey($) {
    my $code = &codeOf( $_[0] );
    my $result =
      ( ( $code >= &codeOf("XK_KP_F1") ) and ( $code <= &codeOf("XK_KP_F4") ) )
      ? 1
      : 0;
    return $result;
}

sub IsFunctionKey($) {
    my $code = &codeOf( $_[0] );
    my $result =
      ( ( $code >= &codeOf("XK_F1") ) and ( $code <= &codeOf("XK_F35") ) )
      ? 1
      : 0;
    return $result;
}

sub IsMiscFunctionKey($) {
    my $code = &codeOf( $_[0] );
    my $result =
      ( ( $code >= &codeOf("XK_Select") ) and ( $code <= &codeOf("XK_Break") ) )
      ? 1
      : 0;
    return $result;
}

sub IsModifierKey($) {
    my $code   = &codeOf( $_[0] );
    my $result = (
        (
                  ( $code >= &codeOf("XK_Shift_L") )
              and ( $code <= &codeOf("XK_Hyper_R") )
        )
          or (  ( $code >= &codeOf("XK_ISO_Lock") )
            and ( $code <= &codeOf("XK_ISO_Level5_Lock") ) )
          or ( $code == &codeOf("XK_Mode_switch") )
          or ( $code == &codeOf("XK_Num_Lock") )
    ) ? 1 : 0;
    return $result;
}

# debugging/reporting

# Xutil.h's macros do not cover the whole range of special keys, which are not
# actually printable.
sub IsSpecialKey($) {
    my $code = &codeOf( $_[0] );
    my $result =
      ( ( $code >= 0xff00 ) and ( $code <= 0xffff ) )
      ? 1
      : 0;
    return $result;
}

sub IsOrdinaryKey($) {
    my $code   = shift;
    my $result = 1;
    $result = 0
      if ( &IsFunctionKey($code)
        or &IsEditFunctionKey($code)
        or &IsKeypadKey($code)
        or &IsCursorKey($code)
        or &IsPFKey($code)
        or &IsMiscFunctionKey($code)
        or &IsPrivateKeypadKey($code) );
    return $result;
}

sub VisibleChar($) {
    my $ch     = shift;
    my $ord    = ord $ch;
    my $result = $ch;
    if ( $ord < 32 ) {
        if ( $ord == 8 ) {
            $result = '\b';
        }
        elsif ( $ord == 9 ) {
            $result = '\t';
        }
        elsif ( $ord == 10 ) {
            $result = '\n';
        }
        elsif ( $ord == 12 ) {
            $result = '\f';
        }
        elsif ( $ord == 13 ) {
            $result = '\r';
        }
        elsif ( $ord == 27 ) {
            $result = '\E';
        }
        else {
            $result = sprintf( "^%c", $ord + 64 );
        }
    }
    elsif ( $ord == 32 ) {
        $result = '\s';
    }
    elsif ( $ord == 94 ) {
        $result = '\^';
    }
    elsif ( $ord == 92 ) {
        $result = '\\\\';
    }
    elsif ( $ord == 127 ) {
        $result = '^?';
    }
    return $result;
}

sub IsShift($$) {
    my $code   = shift;
    my $state  = shift;    # 0/1=normal, 2=shift
    my $result = 0;
    if ( ( ( $state - 1 ) & 1 ) != 0 ) {
        if ( $Shifted{$code} ) {
            return 1 if ( $Shifted{$code} ne $code );
        }
    }
    return 0;
}

sub TypeOf($) {
    my $code   = &toCode( $_[0] );
    my $result = "other";
    $result = "special"  if ( &IsSpecialKey($code) );
    $result = "keypad"   if ( &IsKeypadKey($code) );
    $result = "*keypad"  if ( &IsPrivateKeypadKey($code) );
    $result = "cursor"   if ( &IsCursorKey($code) );
    $result = "pf-key"   if ( &IsPFKey($code) );
    $result = "func-key" if ( &IsFunctionKey($code) );
    $result = "misc-key" if ( &IsMiscFunctionKey($code) );
    $result = "edit-key" if ( &IsEditFunctionKey($code) );
    $result = "modifier" if ( &IsModifierKey($code) );
    return $result;
}

sub KeyToS($$$) {
    my $code   = &codeOf( $_[0] );
    my $mode   = $_[1];
    my $state  = $_[2];
    my $result = "";

    $code = &codeOf( $Shifted{ $_[0] } )
      if ( ( $modify_mods & ( $state - 1 ) & 1 ) == 0
        and &IsShift( $_[0], $state ) );
    my $type = &TypeOf( &toCode($code) );
    if (    $mode == 1
        and $type eq "other"
        and ( $modify_mods & ( $state - 1 ) ) != 0 )
    {
        # TODO - can this be improved using xkb groups?
        $state = 1 + ( ( $state - 1 ) & ~$modify_mods ) if ( $state <= 5 );
    }

    if ( $type ne "other" ) {
        $result = ( $type eq "special" ) ? "-ignore-" : "?";
    }
    elsif ($opt_u) {
        $result = sprintf( "\\E[%d;%du", $code, $state );
    }
    else {
        $result = sprintf( "\\E[27;%d;%d~", $state, $code );
    }
    return $result;
}

sub ParamToQ($) {
    my $param  = shift;
    my $result = shift;
    $param--;
    $result .= ( $param & 1 ) ? 's' : '-';
    $result .= ( $param & 2 ) ? 'a' : '-';
    $result .= ( $param & 4 ) ? 'c' : '-';
    $result .= ( $param & 8 ) ? 'm' : '-';
    return $result;
}

sub ParamToS($) {
    my $param  = shift;
    my $result = "";
    if ( $param-- > 1 ) {
        $result .= "+Shift" if ( $param & 1 );
        $result .= "+Alt"   if ( $param & 2 );
        $result .= "+Ctrl"  if ( $param & 4 );
        $result .= "+Meta"  if ( $param & 8 );
        $result =~ s/^\+//;
    }
    return $result;
}

sub StateToS($) {
    my $state  = shift;
    my $result = "";
    $result .= "+Shift" if ( $state & $ShiftMask );
    $result .= "+Lock"  if ( $state & $LockMask );
    $result .= "+Ctrl"  if ( $state & $ControlMask );
    $result .= "+Alt"   if ( $state & $AltMask );
    $result .= "+Meta"  if ( $state & $MetaMask );
    $result =~ s/^\+//;
    return $result;
}

# macros/functions in xterm's input.c

sub Masked($$) {
    my $value  = shift;
    my $mask   = shift;
    my $result = ( ($value) & ( ~($mask) ) );
    return $result;
}

sub IsPredefinedKey($) {
    my $code   = &codeOf( $_[0] );
    my $result = 0;
    if ( $keySyms{"XK_ISO_Lock"} ) {
        $result =
          ( $code >= &codeOf("XK_ISO_Lock") and $code <= &codeOf("XK_Delete") )
          ? 1
          : 0;
    }
    else {
        $result =
          ( $code >= &codeOf("XK_BackSpace") and $code <= &codeOf("XK_Delete") )
          ? 1
          : 0;
    }
    return $result;
}

sub IsTabKey($) {
    my $code   = &codeOf( $_[0] );
    my $result = 0;
    if ( $keySyms{"XK_ISO_Left_Tab"} ) {
        $result =
          ( $code == &codeOf("XK_Tab") || $code == &codeOf("XK_ISO_Left_Tab") );
    }
    else {
        $result = ( $code == &codeOf("XK_Tab") ) ? 1 : 0;
    }
    return $result;
}

sub IsEditFunctionKey($) {
    my $code   = shift;
    my $result = 0;
    if ( $keyCodes{$code} ) {
        my $name = $keyCodes{$code};
        $result = 1 if ( $editKeys{$name} );
    }
    return $result;
}

sub IS_CTRL($) {
    my $code   = &codeOf( $_[0] );
    my $result = ( $code < 32 || ( $code >= 0x7f && $code <= 0x9f ) );
    return $result;
}

sub IsControlInput($) {
    my $code   = &codeOf( $_[0] );
    my $result = 0;
    $result = 1 if ( $code >= 0x40 && $code <= 0x7f );
    return $result;
}

sub IsControlOutput($) {
    my $code   = shift;
    my $result = 0;
    $result = 1 if &IS_CTRL($code);
    return $result;
}

sub IsControlAlias($$) {
    my $code   = shift;
    my $state  = shift;
    my $result = 0;

    $code = &toCode($code);
    $code = &toCode( &AliasedKey($code) );
    if ( hex $code < 256 ) {
        $result = &IS_CTRL($code);

        # In xterm, this function does not directly test evt_state, but relies
        # upon kd.strbuf converted by Xutf8LookupString or XmbLookupString
        # (ultimately in _XTranslateKeysym).
        #
        # See https://www.mail-archive.com/xorg@lists.x.org/msg04434.html
        #
        # xterm does its own special cases for XK_BackSpace
        if ( $state & $ControlMask ) {
            my $ch = chr &codeOf($code);
            $result = 1 if ( &IsTabKey($code) );
            $result = 1 if ( &IsControlInput($code) );
            $result = 1 if ( $ch =~ /^[\/ 2-8]$/ );
        }
    }
    return $result;
}

sub computeMaskedModifier($$) {
    my $state  = shift;
    my $mask   = shift;
    my $result = &xtermStateToParam( &Masked( $state, $mask ) );
    return $result;
}

sub xtermStateToParam($) {
    my $state       = shift;
    my $modify_parm = 1;

    $modify_parm += 1 if ( $state & $ShiftMask );
    $modify_parm += 2 if ( $state & $AltMask );
    $modify_parm += 4 if ( $state & $ControlMask );
    $modify_parm += 8 if ( $state & $MetaMask );
    $modify_parm = 0 if ( $modify_parm == 1 );
    return $modify_parm;
}

sub ParamToState($) {
    my $modify_parm = shift;
    my $state       = 0;
    $modify_parm-- if ( $modify_parm > 0 );
    $state |= $ShiftMask   if ( $modify_parm & 1 );
    $state |= $AltMask     if ( $modify_parm & 2 );
    $state |= $ControlMask if ( $modify_parm & 4 );
    $state |= $MetaMask    if ( $modify_parm & 8 );
    return $state;
}

sub allowedCharModifiers($$) {
    my $other_key = shift;
    my $state     = shift;
    my $code      = shift;
    my $result = $state & ( $ShiftMask | $AltMask | $ControlMask | $MetaMask );

    # If modifyOtherKeys is off or medium (0 or 1), moderate its effects by
    # excluding the common cases for modifiers.
    if ( $other_key <= 1 ) {
        my $sym = $keyCodes{$code};
        if (    &IsControlInput($code)
            and &Masked( $result, $ControlMask ) == 0 )
        {
            # These keys are already associated with the control-key
            if ( $other_key == 0 ) {
                $result &= ~$ControlMask;
            }
        }
        elsif ( $sym eq "XK_Tab" || $sym eq "XK_Return" ) {
            #
        }
        elsif ( &IsControlAlias( $code, $state ) ) {

            # Things like "^_" work here...
            if ( &Masked( $result, ( $ControlMask | $ShiftMask ) ) == 0 ) {
                if ( $sym =~ /^XK_[34578]$/ or $sym eq "XK_slash" ) {
                    $result = 0 if ( $state == $ControlMask );
                }
                else {
                    $result = 0;
                }
            }
        }
        elsif ( !&IsControlOutput($code) && !&IsPredefinedKey($code) ) {

            # Printable keys are already associated with the shift-key
            if ( !( $result & $ControlMask ) ) {
                $result &= ~$ShiftMask;
            }
        }

        # TODO:
        #       result = filterAltMeta(result,
        #                              xw->work.meta_mods,
        #                              TScreenOf(xw)->meta_sends_esc, kd);
        #       if (TScreenOf(xw)->alt_is_not_meta) {
        #           result = filterAltMeta(result,
        #                                  xw->work.alt_mods,
        #                                  TScreenOf(xw)->alt_sends_esc, kd);
        #       }
    }
    elsif ( $other_key >= 2 ) {

        # For an ordinary key, if the state has only one modified bit set
        # and if that is in the modify-modifiers mask, then disable the
        # use of modifiers for sending the key as an escape sequence.
        if ( &IsOrdinaryKey($code) and ( $modify_mods & $state ) != 0 ) {
            my $check = $state;
            while ( $check != 0 ) {
                if ( ( $check & 1 ) != 0 ) {
                    $result = 0 if ( $check == 1 );
                    last;
                }
                $check >>= 1;
            }
        }
    }
    return $result;
}

# Some details are omitted (e.g., the backspace/delete toggle), but this gives
# the general sense of the corresponding function in xterm's input.c
sub ModifyOtherKeys($$$$) {
    my $code        = shift;    # the keycode to test
    my $other_key   = shift;    # "modifyOtherKeys" resource
    my $modify_parm = shift;    # 0=unmodified, 2=shift, etc
    my $state       = shift;    # mask of modifiers, e.g., ControlMask
    my $result      = 0;

    $modify_parm = 0 if ( $modify_parm == 1 );

    if ( &IsModifierKey($code) ) {

        # xterm filters out bare modifiers (ignore)
    }
    elsif ( &IsOrdinaryKey($code) == 0 ) {

        # Exclude the keys already covered by a modifier.
    }
    elsif ( $state > 0 ) {
        my $sym = "";
        $sym = $keyCodes{$code} if ( $keyCodes{$code} );

        # TODO:
        #if (IsBackarrowToggle(keyboard, kd->keysym, state)) {
        #    kd->keysym = XK_Delete;
        #    UIntClr(state, ControlMask);
        #}
        if ( !&IsPredefinedKey($code) ) {
            $state = &allowedCharModifiers( $other_key, $state, $code );
        }
        if ( $state != 0 ) {
            if ( $other_key == 1 ) {
                if (   $sym eq "XK_BackSpace"
                    or $sym eq "XK_Delete" )
                {
                }
                elsif ( $sym eq "XK_ISO_Left_Tab" ) {
                    $result = 1
                      if ( &computeMaskedModifier( $state, $ShiftMask ) );
                }
                elsif ($sym eq "XK_Return"
                    or $sym eq "XK_Tab" )
                {
                    $result = ( $modify_parm != 0 );
                }
                else {
                    if ( &IsControlInput($code) ) {
                        if ( $state == $ControlMask or $state == $ShiftMask ) {
                            $result = 0;
                        }
                        else {
                            $result = ( $modify_parm != 0 );
                        }
                    }
                    elsif ( &IsControlAlias( $code, $state ) ) {
                        if ( $state == $ShiftMask ) {
                            $result = 0;
                        }
                        elsif ( &computeMaskedModifier( $state, $ControlMask ) )
                        {
                            $result = 1;
                        }
                    }
                    else {
                        $result = 1;
                    }
                }
                if ($result) {    # second case in xterm's Input()
                    $result = 0
                      if ( &allowedCharModifiers( $other_key, $state, $code ) ==
                        0 );
                }
            }
            elsif ( $other_key == 2 ) {
                if ( $sym eq "XK_BackSpace" ) {

                    # strip ControlMask as per IsBackarrowToggle()
                    $result = 1
                      if ( &computeMaskedModifier( $state, $ControlMask ) );
                }
                elsif ( $sym eq "XK_Delete" ) {

                    $result = ( &xtermStateToParam($state) != 0 );
                }
                elsif ( $sym eq "XK_ISO_Left_Tab" ) {
                    $result = 1
                      if ( &computeMaskedModifier( $state, $ShiftMask ) );
                }
                elsif ($sym eq "XK_Escape"
                    or $sym eq "XK_Return"
                    or $sym eq "XK_Tab" )
                {

                    $result = ( $modify_parm != 0 );
                }
                else {
                    if ( &IsControlInput($code) ) {
                        $result = 1;
                    }
                    elsif ( $state == $ShiftMask and $sym eq "XK_space" ) {
                        $result = 1;
                    }
                    elsif ( &computeMaskedModifier( $state, $ShiftMask ) ) {
                        $result = 1;
                    }
                }
            }
        }
    }
    return $result;
}

# See IsControlAlias. This handles some of the special cases where the keycode
# seen or used by xterm is not the same as the actual keycode.
sub AliasedKey($) {
    my $code   = &toCode( $_[0] );
    my $result = &codeOf($code);
    my $sym    = $keyCodes{$code};
    if ($sym) {
        $result = 8  if ( $sym eq "XK_BackSpace" );
        $result = 9  if ( $sym eq "XK_Tab" );
        $result = 13 if ( $sym eq "XK_Return" );
        $result = 27 if ( $sym eq "XK_Escape" );
    }
    return $result;
}

# Returns a short display for shift/control/alt modifiers applied to the
# keycode to show which are affected by "modifyOtherKeys" at the given level in
# $other_key
sub CheckOtherKey($$) {
    my $code      = shift;
    my $other_key = shift;
    my $modified  = 0;
    my $result    = "";
    for my $modify_parm ( 1 .. $MAXMODS ) {
        my $state = &ParamToState($modify_parm);
        if ( &ModifyOtherKeys( $code, $other_key, $modify_parm, $state ) ) {
            $modified++;
            $result .= "*";
        }
        else {
            $result .= "-";
        }
    }
    return $modified ? $result : "-(skip)-";
}

# Use the return-string from CheckOtherKeys as a template for deciding which
# keys to render as escape-sequences.
sub ShowOtherKeys($$$) {
    my $code = &AliasedKey( $_[0] );
    my $mode = $_[1];                  # modifyOtherKeys: 0, 1 or 2
    my $show = $_[2];
    my $type = &TypeOf( $_[0] );
    my @result;

    # index for $show[] can be tested with a bit-mask:
    # 1 = shift
    # 2 = alt
    # 4 = ctrl
    # 8 = meta
    for my $c ( 0 .. length($show) - 1 ) {
        my $rc = substr( $show, $c, 1 );
        if ( $rc eq "*" ) {
            $result[$c] = &KeyToS( &toCode($code), $mode, $c + 1 );
        }
        elsif ( $type eq "other" or ( $type eq "special" and $code < 256 ) ) {
            my $map   = $code;
            my $tmp   = &toCode($code);
            my $chr   = chr hex $tmp;
            my $shift = ( $c & 1 );
            my $cntrl = ( $c & 4 );

            # TODO - can this be simplified using xkb groups?
            if ( $chr =~ /^[`345678]$/ and ( $c & 4 ) != 0 ) {
                if ($shift) {
                    $map = 30      if ( $chr eq "`" );
                    $map = ord "#" if ( $chr eq "3" );
                    $map = ord '$' if ( $chr eq "4" );
                    $map = ord "%" if ( $chr eq "5" );
                    $map = 30      if ( $chr eq "6" );
                    $map = ord "&" if ( $chr eq "7" );
                    $map = ord "*" if ( $chr eq "8" );
                }
                else {
                    $map = 0   if ( $chr eq "`" );
                    $map = 27  if ( $chr eq "3" );
                    $map = 28  if ( $chr eq "4" );
                    $map = 29  if ( $chr eq "5" );
                    $map = 30  if ( $chr eq "6" );
                    $map = 31  if ( $chr eq "7" );
                    $map = 127 if ( $chr eq "8" );
                }
            }
            else {
                $map = &codeOf( $Shifted{$tmp} )
                  if ( defined( $Shifted{$tmp} ) and $shift );
                if ($cntrl) {
                    if ( $chr =~ /^[190:<=>.,+*()'&%\$#"!]$/ ) {

                        # ignore
                    }
                    elsif ( $chr =~ /^[2]$/ ) {
                        $map = 0;
                    }
                    elsif ( $chr =~ /^[:;]$/ ) {
                        $map = 27 if ( $mode > 0 );
                    }
                    elsif ( $chr eq '-' ) {
                        $map = 31 if ($shift);
                    }
                    elsif ( $chr eq '/' ) {
                        $map = $shift ? 127 : 31 if ( $mode == 0 );
                        $map = 31 if ( not $shift and $mode == 1 );
                    }
                    elsif ( $chr eq '?' ) {
                        $map = 127;
                    }
                    else {
                        $map = ( $code & 0x1f ) if ( $code < 128 );
                    }
                }
            }
            $result[$c] = &VisibleChar( chr $map );
        }
        elsif ( $type eq "special" ) {
            $result[$c] = "-ignore-";
        }
        else {
            $result[$c] = sprintf( "%d:%s", $c + 1, $type );
        }
    }
    return @result;
}

sub readfile($) {
    my $data = shift;
    my @data;
    if ( open my $fp, $data ) {
        @data = <$fp>;
        close $fp;
        chomp @data;
    }
    return @data;
}

sub readpipe($) {
    my $cmd = shift;
    return &readfile("$cmd 2>/dev/null |");
}

sub trim($) {
    my $text = shift;
    $text =~ s/^\s+//;
    $text =~ s/\s+$//;
    $text =~ s/\s+/ /g;
    return $text;
}

sub html_ref($) {
    my $header = shift;
    my $anchor = lc &trim($header);
    $anchor =~ s/\s/_/g;
    return $anchor;
}

sub rightarrow() {
    return $opt_h ? "→" : "->";
}

sub safe_html($) {
    my $text = shift;
    if ($opt_h) {
        $text =~ s/\&/\&/g;
        $text =~ s/\= 128 );
                $s .= $ch                      if ( $ord < 128 );
            }
            $text = $s;
        }
    }
    return $text;
}

sub begin_report() {
    if ($opt_o) {
        open( $REPORT, '>', $opt_o ) or &failed("cannot open $opt_o");
        select $REPORT;
    }
    if ($opt_h) {
        printf <



  

  XTERM - Modified "Other" Keys ($xkb_layout-$xkb_model)
  
  
  



EOF
          ;
    }
}

sub end_report() {
    if ($opt_h) {
        my $output = "output.html";
        $output = $opt_o if ($opt_o);
        printf <
  
    EOF ; for my $h ( 0 .. $#headers ) { printf "
  • %s
  • \n", &html_ref( $headers[$h] ), $headers[$h]; } printf < EOF ; } if ($opt_o) { select STDOUT; close $REPORT; } } sub begin_section($) { my $header = shift; $headers[ $#headers + 1 ] = $header; if ($opt_h) { printf "

    %s

    \n", &html_ref($header), $header; } else { printf "\n"; printf "%s:\n", $header; } printf STDERR "** %s\n", $header if ($opt_o); } sub begin_table() { my $title = shift; &begin_section($title); if ($opt_h) { printf "\n"; } } sub end_table() { if ($opt_h) { printf "
    \n"; } } sub tt_cell($) { my $text = shift; return sprintf "%s", $text; } sub td_any($) { my $text = shift; return sprintf "%s", &tt_cell($text); } sub td_left($) { my $text = shift; return sprintf "%s", &tt_cell($text); } sub td_right($) { my $text = shift; return sprintf "%s", &tt_cell($text); } sub padded($$) { my $size = shift; my $text = shift; $text = sprintf( "%*s", $size, $text ) if ( $size > 0 ); $text = sprintf( "%-*s", $size, $text ) if ( $size < 0 ); $text =~ s/ / /g if ($opt_h); return $text; } sub print_head() { my $argc = $#_; if ($opt_h) { printf ""; for ( my $n = 0 ; $n <= $argc ; $n += 2 ) { my $size = $_[$n]; my $text = &padded( $size, $_[ $n + 1 ] ); printf "%s", $text; } printf "\n"; } else { for ( my $n = 0 ; $n <= $argc ; $n += 2 ) { my $size = $_[$n]; my $text = &padded( $size, $_[ $n + 1 ] ); printf "%s", $text; printf " " if ( $n < $argc ); } printf "\n"; } } sub link_data($$) { my $thisis = shift; my $thatis = shift; my $column = shift; my $symbol = shift; my %result; $result{THISIS} = $thisis; # current table name $result{THATIS} = $thatis; # name of target table for link $result{COLUMN} = $column; # column counting from 0 $result{SYMBOL} = $symbol; return \%result; } sub unique_link($$) { my $thisis = shift; my $symbol = shift; my $unique = 0; for my $n ( 0 .. length($symbol) - 1 ) { $unique += ord substr( $symbol, $n, 1 ); } return sprintf( "%s:%s.%x", $thisis, $symbol, $unique ); } # print a row in the table, using pairs of lengths and strings: # + Right-align lengths greater than zero and pad; # + Left-align lengths less than zero, pad. # + For the special case of zero, just left align without padding. sub print_data() { my $argc = $#_; if ($opt_h) { my @links = @{ $_[0] }; printf ""; my $col = 0; for ( my $n = 1 ; $n <= $argc ; $n += 2 ) { my $size = $_[$n]; my $text = &padded( $size, $_[ $n + 1 ] ); if ( $#links >= 0 ) { for my $l ( 0 .. $#links ) { my %obj = %{ $links[$l] }; # link_data if ( $obj{COLUMN} == $col ) { my $props = ""; my $value = &unique_link( $obj{THISIS}, $obj{SYMBOL} ); # The symbol-map from xkbcomp has duplicates because # different modifier combinations can produce the same # keysym. Since it appears that the slots that the # user would expect are filled in first, just ignoring # the duplicate works well enough. if ( not $linkUsed{$value} ) { $props .= " name=\"$value\""; $linkUsed{$value} = 1; } $value = &unique_link( $obj{THATIS}, $obj{SYMBOL} ); $props .= " href=\"#$value\""; my $tail = $text; $text =~ s/(\ )+$//; $tail = substr( $tail, length($text) ); $text = sprintf( "%s%s", $props, $text, $tail ); last; } } } printf "%s", ( $size > 0 ) ? &td_right($text) : ( $size == 0 ) ? &td_any($text) : &td_left($text); ++$col; } printf "\n"; } else { for ( my $n = 1 ; $n <= $argc ; $n += 2 ) { my $size = $_[$n]; my $text = &padded( $size, $_[ $n + 1 ] ); printf "%s", $text; printf " " if ( $n < $argc ); } printf "\n"; } } sub begin_preformatted($) { my $title = shift; &begin_section($title); printf "
    \n" if ($opt_h);
    }
    
    sub end_preformatted() {
        printf "
    \n" if ($opt_h); } sub do_localectl($) { my $report = shift; my $cmd = "localectl status"; my @data = &readpipe($cmd); &begin_table("Output of $cmd") if ($report); for my $n ( 0 .. $#data ) { # let command-line parameters override localectl output, for reports $data[$n] =~ s/^(\s+X11 Layout:\s+).*$/$1$opt_l/ if ($opt_l); $data[$n] =~ s/^(\s+X11 Model:\s+).*$/$1$opt_m/ if ($opt_m); my @fields = split /:\s*/, $data[$n]; next unless ( $#fields == 1 ); if ($report) { if ($opt_h) { printf "%s%s\n", &td_right( $fields[0] ), &td_left( $fields[1] ); } else { printf "%s\n", $data[$n]; } } $xkb_layout = $fields[1] if ( $fields[0] =~ /x11 layout/i ); $xkb_model = $fields[1] if ( $fields[0] =~ /x11 model/i ); } if ($report) { &end_table; } } sub do_keysymdef() { my @data = &readfile($keyfile); my $lenSyms = 0; for my $n ( 0 .. $#data ) { my $value = &trim( $data[$n] ); next unless ( $value =~ /^#define\s+XK_/ ); my $name = $value; $name =~ s/^#define\s+//; $value = $name; $name =~ s/\s.*//; $value =~ s/^[^\s]+\s+//; my $note = $value; $value =~ s/\s.*//; $note =~ s/^[^\s]+\s*//; if ( $note !~ /\b(alias|deprecated)\b/ ) { if ( $note =~ /\/*.*\bU\+[[:xdigit:]]{4,8}.*\*\// ) { next if ( $note =~ /\(U\+/ ); my $code = $note; $code =~ s/^.*\bU\+([[:xdigit:]]+).*/$1/; $note =~ s/^\/\*[([:space:]]*//; $note =~ s/[)[:space:]]*\*\/$//; $uniNames{$value} = $note; $uniCodes{$value} = hex $code; } } $lenSyms = length($name) if ( length($name) > $lenSyms ); $value = lc $value; $keySyms{$name} = $value; $keyCodes{$value} = $name unless ( $keyCodes{$value} ); printf "keySyms{$name} = '$value', keyCodes{$value} = $name\n" if ($opt_d); } my $tmpfile = $keyfile; $tmpfile =~ s/^.*\///; &begin_table("Symbols from $tmpfile"); my @keys = keys %keySyms; &print_data( \@nolinks, 5, sprintf( "%d", $#keys ), 0, sprintf( "keysyms are defined (longest %d)", $lenSyms ) ); @keys = keys %keyCodes; &print_data( \@nolinks, 5, sprintf( "%d", $#keys ), 0, "keycodes are defined" ); @keys = keys %uniCodes; &print_data( \@nolinks, 5, sprintf( "%d", $#keys ), 0, "keycodes are equated to Unicode" ); &end_table; } # For what it's worth, there is a C library (xkbfile) which could be used, # but there is no documentation and would not actually solve the problem at # hand. # # setxkbmap -model pc105 -layout us -print | xkbcomp - -C -o - sub do_xkbcomp() { my @data = &readpipe( "setxkbmap " . "-model $xkb_model " . "-layout $xkb_layout -print " . "| xkbcomp - -C -o -" ); my $state = -1; my $type = {}; printf "
    DUMP do_xkbcomp\n" if ($opt_v);
        for my $n ( 0 .. $#data ) {
            if ( $data[$n] =~ /static.*\bkeyNames\[.*{/ ) {    # }
                $state = 0;
                next;
            }
            if ( $data[$n] =~ /static.*\bsymCache\[.*{/ ) {    # }
                $state = 1;
                next;
            }
            if ( $data[$n] =~ /static.*\bsymMap\[.*{/ ) {      # }
                $state = 2;
                next;
            }
            if ( $data[$n] =~ /static.*\bdflt_types\[.*{/ ) {    # }
                $state = 3;
                next;
            }
            if ( $state >= 0 ) {
                if ( $data[$n] =~ /^\s*};/ ) {                   # {
                    printf "# %s\n", $data[$n] if ($opt_d);
                    $state = -1;
                    next;
                }
                printf "* %s\n", $data[$n] if ($opt_d);
            }
    
            # parse data in "keyNames[NUM_KEYS]"
            if ( $state == 0 ) {
                my $text = $data[$n];
                my $name;
                while ( $text =~ /^.*".*".*$/ ) {
                    $text =~ s/^[^"]*//;
                    $name = $text;
                    $name =~ s/"\s+}.*//;    #{
                    $name =~ s/"//g;
                    $keyNames[ $#keyNames + 1 ] = $name;
                    printf "keyNames[%d] = '%s'\n", $#keyNames,
                      $keyNames[$#keyNames]
                      if ($opt_v);
                    $text =~ s/^"[^"]*"//;
                }
            }
    
            # parse data in "symCache[NUM_SYMBOLS]"
            elsif ( $state == 1 ) {
                my $text = $data[$n];
                my $name;
                while ( $text =~ /[[:alnum:]_]/ ) {
                    $text =~ s/^[^[[:alnum:]_]*//;
                    $name = $text;
                    $name =~ s/[^[[:alnum:]_].*//;
                    $symCache[ $#symCache + 1 ] = $name;
                    printf "symCache[%d] = %s\n", $#symCache, $symCache[$#symCache]
                      if ($opt_v);
                    $text =~ s/^[[:alnum:]_]+//;
                }
            }
    
            # parse data in "symMap[NUM_KEYS]"
            elsif ( $state == 2 ) {
                my $text = $data[$n];
                my $code;
                while ( $text =~ /[{].*[}]/ ) {
                    my %obj;
                    $text =~ s/^[^{]*[{]\s*//;    # }}
                    $code = $text;
                    $code =~ s/[^[[:alnum:]].*//;
                    $text =~ s/[[:alnum:]]+\s*,\s*//;
                    $obj{TYPE} = $code;           # KeyType
                    my %tmp = %{ $keyTypes[$code] };
                    $tmp{USED} += 1;
                    $keyTypes[$code] = \%tmp;
                    $code = $text;
                    $code =~ s/[^[[:alnum:]].*//;
                    $text =~ s/[[:alnum:]]+\s*,\s*//;
                    $obj{USED} = hex $code;       # 0/1 for used/unused
                    $code = $text;
                    $code =~ s/[^[[:alnum:]].*//;
                    $obj{CODE} = $code;           # index in symCache[]
                    $text =~ s/[[:alnum:]]+\s*//;
                    $symMap[ $#symMap + 1 ] = \%obj;
                    printf "symMap[%d] = {%d,%d,%d}\n", $#symMap, $obj{TYPE},
                      $obj{USED}, $obj{CODE}
                      if ($opt_v);
                }
            }
    
            # parse data in "dflt_types[]"
            elsif ( $state == 3 ) {
                my $text = &trim( $data[$n] );    #{
                if ( $text =~ /^\s*[}](,)?$/ ) {
                    $type->{USED}               = 0;
                    $keyTypes[ $#keyTypes + 1 ] = $type;
                    $type                       = {};
                }
                elsif ( $text =~ /^\d+,$/ ) {
                    $text =~ s/,//;
                    $type->{SIZE} = $text;
                }
                elsif ( $text =~ /^None,\s+lnames_[[:alnum:]_]+$/ ) {
                    $text =~ s/^None,\s+lnames_//;
                    $type->{NAME} = $text;
                }
                elsif ( $text =~ /^\s*[{].*[}],\s*$/ ) {
                    $text =~ s/^\s*[{]\s*([^,]+),.*/$1/;
                    $type->{MODS} = $text;
                }
            }
        }
        printf "
    \n" if ($opt_v); &begin_table("Summary from xkbcomp"); &print_data( \@nolinks, 5, sprintf( "%d", $#keyNames + 1 ), 0, "keyNames" ); &print_data( \@nolinks, 5, sprintf( "%d", $#keyTypes + 1 ), 0, "keyTypes" ); &print_data( \@nolinks, 5, sprintf( "%d", $#symCache + 1 ), 0, "symCache" ); &print_data( \@nolinks, 5, sprintf( "%d", $#symMap + 1 ), 0, "symMap" ); &end_table; } # Report keysymdef.h without the deprecated stuff, and sorted by keycode. sub report_keysymdef() { &begin_table("Key symbols"); &print_head( 0, "Code", 0, "Category", 0, "Symbol" ); # sort by numeric keycode rather than string my @keyCodes = keys %keyCodes; my @sortCodes; for my $c ( 0 .. $#keyCodes ) { $sortCodes[$c] = sprintf "%08X", hex $keyCodes[$c]; } @sortCodes = sort @sortCodes; for my $c ( 0 .. $#sortCodes ) { my $code = sprintf( "0x%04x", hex $sortCodes[$c] ); my $sym = $keyCodes{$code}; &print_data( \@nolinks, 9, $code, -8, &TypeOf($code), 0, $sym ); } &end_table; } sub report_key_types() { &begin_table("Key types"); &print_head( 5, "Type", 5, "Used", 5, "Levels", 0, "Name" ); for my $t ( 0 .. $#keyTypes ) { my %type = %{ $keyTypes[$t] }; next if ( $type{USED} == 0 and not $opt_v ); &print_data( \@nolinks, 5, sprintf( "%d", $t ), 5, sprintf( "%d", $type{USED} ), 5, sprintf( "%d", $type{SIZE} ), 0, $type{NAME} ); } &end_table; } sub TitleN($) { my $result = sprintf( "Mode %d", shift ); $result .= ":$modify_mods" if ( $modify_mods != 0 ); return $result; } sub report_modified_keys() { my @codes = sort keys %keysUsed; my $width = 14; &begin_table("Other modifiable keycodes"); &print_head( 0, "Code", 0, "Symbol", 0, "Actual", -$width, "Mode 0", -$width, &TitleN(1), -$width, &TitleN(2) ); $width = 0 if ($opt_h); for my $c ( 0 .. $#codes ) { next unless ( $codes[$c] ne "" ); my @links; my $sym = $keysUsed{ $codes[$c] }; $links[0] = &link_data( "summary", "detailed", 1, $sym ); &print_data( \@links, 6, $codes[$c], # -20, $keysUsed{ $codes[$c] }, # -6, sprintf( "%d", hex $codes[$c] ), # -$width, &CheckOtherKey( $codes[$c], 0 ), # -$width, &CheckOtherKey( $codes[$c], 1 ), # -$width, &CheckOtherKey( $codes[$c], 2 ) ); } &end_table; &begin_preformatted("Modify-param to/from state"); for my $param ( 0 .. $MAXMODS ) { my $state = &ParamToState($param); my $check = &xtermStateToParam($state); printf " PARAM %d %s %d %s %d (%s)\n", $param, &rightarrow, # $state, &rightarrow, # $check, &ParamToS($param); } &end_preformatted; &begin_preformatted("State to/from modify-param"); for my $state ( 0 .. 15 ) { my $param = &xtermStateToParam($state); my $check = &ParamToState($param); printf " STATE %d %s %d %s %d (%s)\n", # $state, &rightarrow, # $param, &rightarrow, # $check, &StateToS($state); } &end_preformatted; } # Make a report showing user- and program-modes. sub report_otherkey_escapes() { my @codes = sort keys %keysUsed; my $width = 14; &begin_table("Other modified-key escapes"); &print_head( 0, "Code", 0, "Symbol", 0, "Actual", -$width, "Mode 0", -$width, &TitleN(1), -$width, &TitleN(2) ); $width = 0 if ($opt_h); for my $c ( 0 .. $#codes ) { next unless ( $codes[$c] ne "" ); my $level0 = &CheckOtherKey( $codes[$c], 0 ); my $level1 = &CheckOtherKey( $codes[$c], 1 ); my $level2 = &CheckOtherKey( $codes[$c], 2 ); my @level0 = &ShowOtherKeys( $codes[$c], 0, $level0 ); my @level1 = &ShowOtherKeys( $codes[$c], 1, $level1 ); my @level2 = &ShowOtherKeys( $codes[$c], 2, $level2 ); my @links; my $sym = $keysUsed{ $codes[$c] }; $links[0] = &link_data( "detailed", "symmap", 1, $sym ); &print_data( \@links, # -6, $codes[$c], # -20, $keysUsed{ $codes[$c] }, # -6, sprintf( "%d", hex $codes[$c] ), # -$width, $level0, # -$width, $level1, # -$width, $level2 ); for my $r ( 0 .. $#level0 ) { &print_data( \@nolinks, # -6, &ParamToQ( $r + 1 ), # -20, "", # -6, "", # -$width, &safe_html( $level0[$r] ), # -$width, &safe_html( $level1[$r] ), # -$width, &safe_html( $level2[$r] ) ); } } &end_table; } sub report_keys_used() { &begin_table("Key map"); &print_head( 5, "Type", # 0, "Level", # 0, "Name", # 6, "Code", # 0, "Symbol" ); for my $m ( 0 .. $#symMap ) { my %obj = %{ $symMap[$m] }; next unless ( $obj{USED} ); my $sym = $symCache[ $obj{CODE} ]; next if ( $sym eq "NoSymbol" ); my $code = ""; $code = $keySyms{$sym} if ( $keySyms{$sym} ); next if ( $code eq "" ); $keysUsed{$code} = $sym; my %type = %{ $keyTypes[ $obj{TYPE} ] }; my @links; $links[0] = &link_data( "symmap", "summary", 4, $sym ); &print_data( \@links, 5, sprintf( "%d", $obj{TYPE} ), # 5, sprintf( "1/%d", $type{SIZE} ), # -4, $keyNames[$m], # 6, $code, # 0, $sym ); my $base = $code; $Shifted{$code} = $code unless ( $Shifted{$code} ); for my $t ( 1 .. $type{SIZE} - 1 ) { $sym = $symCache[ $obj{CODE} + $t ]; if ( $keySyms{$sym} ) { $code = $keySyms{$sym}; $keysUsed{$code} = $sym; $links[0] = &link_data( "symmap", "summary", 4, $sym ); } else { $code = ""; @links = (); } &print_data( \@links, 5, "", # 5, sprintf( "%d/%d", $t + 1, $type{SIZE} ), # -4, "", # 6, $code, # 0, $sym ); @links = (); # The shift-modifier could be used in custom groups, but the only # built-in ones that appear relevant are TWO_LEVEL and ALPHABETIC, # which have two levels. This records the shifted code for a given # base. if ( $type{SIZE} == 2 and $type{MODS} and index( $type{MODS}, "ShiftMask" ) >= 0 ) { if ( $t == 1 ) { $Shifted{$base} = $code; } elsif ( not $Shifted{$code} ) { $Shifted{$code} = $code; } } } } &end_table; } sub KeyClasses($) { my $hex = shift; my $alias = &IsControlAlias( $hex, $ControlMask ) ? "alias" : ""; my $cntrl = &IS_CTRL($hex) ? "cntrl" : ""; my $ctl_i = &IsControlInput($hex) ? "ctl_i" : ""; my $ctl_o = &IsControlOutput($hex) ? "ctl_o" : ""; my $this = sprintf( "%-5s %-5s %-5s %-5s %-8s", $alias, $cntrl, $ctl_i, $ctl_o, &TypeOf($hex) ); } sub report_key_classes() { &begin_table("Keycode-classes"); my $base = -1; my $last = ""; my $next = 65535; my $form = " [%8s .. %-8s] %s\n"; &print_head( 0, "First", 0, "Last", 0, "Classes" ) if ($opt_h); for my $code ( 0 .. $next ) { my $hex = &toCode($code); my $this = &KeyClasses($hex); if ( $base < 0 ) { $base = 0; $last = $this; } elsif ( $this ne $last ) { printf $form, &toCode($base), &toCode( $code - 1 ), $last unless ($opt_h); &print_data( \@nolinks, 0, &toCode($base), 0, &toCode( $code - 1 ), 0, $last ) if ($opt_h); $base = $code; $last = $this; } } printf $form, &toCode($base), &toCode($next), $last unless ($opt_h); &print_data( \@nolinks, 0, &toCode($base), 0, &toCode($next), 0, $last ) if ($opt_h); &end_table; } sub main::HELP_MESSAGE() { printf STDERR <; close TTY; system "stty $old"; if ( defined $reply ) { die("^C received\n") if ( "$reply" eq "\003" ); } return $reply; } sub visible($) { my $reply = $_[0]; my $n; my $result = ""; for ( $n = 0 ; $n < length($reply) ; ) { my $c = substr( $reply, $n, 1 ); if ( $c =~ /[[:print:]]/ ) { $result .= $c; } else { my $k = ord substr( $reply, $n, 1 ); if ( ord $k == 0x1b ) { $result .= "\\E"; } elsif ( $k == 0x7f ) { $result .= "^?"; } elsif ( $k == 32 ) { $result .= "\\s"; } elsif ( $k < 32 ) { $result .= sprintf( "^%c", $k + 64 ); } elsif ( $k > 128 ) { $result .= sprintf( "\\%03o", $k ); } else { $result .= chr($k); } } $n += 1; } return $result; } sub query_one($) { my $name = shift; return unless $suffixes{$name}; my $suffix = $suffixes{$name}; my $prefix = $opt_8 ? "\x90" : "\x1bP"; my $st = $opt_8 ? "\x9c" : qr/\x1b\\/; my $DCS = qr/${prefix}/; my $match = qr/${DCS}.*${st}/; my $reply = get_reply( $prefix . '$q' . $suffix . $ST ); printf "%-10s query{%s}%*s", $name, # &visible($suffix), # 4 - length($suffix), " "; if ( defined $reply ) { printf "%2d ", length($reply); if ( $reply =~ /${match}/ ) { $reply =~ s/^${DCS}//; $reply =~ s/^;//; $reply =~ s/${st}$//; } else { printf "? "; } printf "{%s}", visible($reply); } printf "\n"; } sub ansi_color($) { my $color = shift; return $color; } sub direct_color($) { my $color = shift; my $result = "8:2:"; $result .= ( $color & 4 ) ? ":255" : ":0"; $result .= ( $color & 2 ) ? ":255" : ":0"; $result .= ( $color & 1 ) ? ":255" : ":0"; return $result; } sub default_colors() { return "39;49"; } printf "\x1b G" if ($opt_8); if ( $#ARGV >= 0 ) { while ( $#ARGV >= 0 ) { &query_one( shift @ARGV ); } } elsif ($opt_a) { for my $fg ( 0 .. 7 ) { printf "%s3%sm", $CSI, &ansi_color($fg); for my $bg ( 0 .. 7 ) { printf "%s4%sm", $CSI, &ansi_color($bg); &query_one("SGR"); } } printf "%s%sm", $CSI, &default_colors; } elsif ($opt_c) { for my $c ( 0 .. 6 ) { printf "%s%d q", $CSI, $c; &query_one("DECSCUSR"); } printf "%s q", $CSI; } elsif ($opt_d) { for my $fg ( 0 .. 7 ) { printf "%s3%sm", $CSI, &direct_color($fg); for my $bg ( 0 .. 7 ) { printf "%s4%sm", $CSI, &direct_color($bg); &query_one("SGR"); } } printf "%s39;49m", $CSI; } else { for my $key ( sort keys %suffixes ) { &query_one($key); } } printf "\x1b F" if ($opt_8); xterm-399/vttests/nrcs.pl0000755000000000000000000001334312213151777014270 0ustar rootroot#!/usr/bin/perl -w # $XTermId: nrcs.pl,v 1.10 2013/09/08 19:46:07 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2013 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # This is a more direct way of exercising character sets than vttest. use strict; use File::Temp qw/ tempdir /; our $prepare_GL = "\x1bo"; # Invoke the G3 Character Set as GL (LS3). our $prepare_GR = "\x1b|"; # Invoke the G3 Character Set as GR (LS3R). our $restore_GL = "\017"; # Invoke the G1 Character Set as GR (LS1R). our $restore_GR = "\x1b~"; # Invoke the G1 Character Set as GR (LS1R). our $enable_NRC = "\x1b[?42h"; our $dummy; our %level; our %suffix; our %short_name; our %long_name; sub select_G3() { printf "\x1b+%s", shift; } sub show_charset($) { my $alias = shift; my $suffix = $suffix{$alias}; return if not $suffix; printf $enable_NRC; &select_G3($suffix); printf $prepare_GL; printf $prepare_GR; printf "GL:\n"; for my $n ( 32 .. 126 ) { print chr($n); printf "\n" if ( ( ( $n + 1 ) % 32 ) == 0 ); } printf "\nGR:\n"; for my $n ( 160 .. 255 ) { print chr($n); printf "\n" if ( ( ( $n + 1 ) % 32 ) == 0 ); } do { $dummy = `sh -c 'read dummy; echo "\$dummy"'`; chomp $dummy; } until $dummy =~ /^\s*$/; printf $restore_GL; printf $restore_GR; } sub list_charset($$$$) { my $level = shift; my $suffix = shift; my $short_name = shift; my $long_name = shift; my $alias = lc $short_name; $level{$alias} = $level; $suffix{$alias} = $suffix; $short_name{$alias} = $short_name; $long_name{$alias} = $long_name; } sub initialize() { &list_charset( 1, '0', "graphic", "DEC Line Drawing Set" ); &list_charset( 2, '<', "supp", "DEC Supplementary" ); &list_charset( 3, '%5', "supp_graphic", "DEC Supplementary Graphics" ); &list_charset( 3, '>', "technical", "DEC Technical" ); &list_charset( 3, 'A', "latin_1", "United Kingdom (UK)" ); &list_charset( 1, 'B', "ascii", "United States (USASCII)" ); &list_charset( 2, '4', "dutch", "Dutch" ); &list_charset( 2, '5', "finnish", "Finnish" ); &list_charset( 2, 'C', "finnish2", "Finnish" ); &list_charset( 2, 'R', "french", "French" ); &list_charset( 2, 'f', "french2", "French" ); &list_charset( 2, 'Q', "canadian", "French Canadian " ); &list_charset( 2, '9', "canadian2", "French Canadian " ); &list_charset( 2, 'K', "german", "German" ); &list_charset( 2, 'Y', "italian", "Italian" ); &list_charset( 3, '`', "danish", "Norwegian/Danish " ); &list_charset( 2, 'E', "danish2", "Norwegian/Danish" ); &list_charset( 2, '6', "danish3", "Norwegian/Danish" ); &list_charset( 3, '%6', "portuguese", "Portuguese " ); &list_charset( 2, 'Z', "spanish", "Spanish" ); &list_charset( 2, '7', "swedish", "Swedish" ); &list_charset( 2, 'H', "swedish2", "Swedish" ); &list_charset( 2, '=', "swiss", "Swiss" ); } sub show_dialog() { my $dir = tempdir( CLEANUP => 1 ); my $in_file = "$dir/input"; my $out_file = "$dir/output"; my $exe_file = "$dir/script"; my $rc_file = "$dir/status"; my $output = ""; my $status; do { open( FP, ">$in_file" ) || die("cannot create $in_file"); print FP "#!/bin/sh\n"; print FP "dialog"; printf FP "\\\n\t--default-item \"%s\"", $output if ( $output ne "" ); print FP "\\\n\t--menu \"Select a character set\" 0 0 0 "; foreach my $key ( sort keys %short_name ) { printf FP "\\\n\t%s \"VT%d00: %s\"", $short_name{$key}, $level{$key}, $long_name{$key}; } printf FP "\\\n 2>$out_file\n"; printf FP "echo \$? >$rc_file\n"; close FP; chmod 0700, $in_file; system("$in_file"); $output = `cat $out_file`; $status = `cat $rc_file`; chomp $output; chomp $status; &show_charset($output) if ( $status == 0 ); } while ( $status ne "" and $status == 0 ); } &initialize; if ( $#ARGV >= 0 ) { while ( $#ARGV >= 0 ) { &show_charset( shift @ARGV ); } } else { &show_dialog; } xterm-399/vttests/ctlpix.sh0000755000000000000000000000337214231452711014620 0ustar rootroot#!/bin/sh # $XTermId: ctlpix.sh,v 1.6 2022/04/25 08:03:21 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2019,2022 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- PATH="$(dirname "$(readlink -f "$0")"):$PATH" export PATH clear lo=9216 hi=9232 for n in `seq $lo $hi` do utf8.pl "$n" done altchars.sh xterm-399/vttests/titlestack.pl0000755000000000000000000004550214722212132015462 0ustar rootroot#!/usr/bin/env perl # $XTermId: titlestack.pl,v 1.35 2024/11/29 01:09:46 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2019,2024 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Test the title-stack and title-mode options of xterm. # TODO: add test for arbitrary x property # TODO: allow -g and -v options to toggle interactively use strict; use warnings; use Getopt::Std; use Encode qw(decode encode); use Term::ReadKey; use I18N::Langinfo qw(langinfo CODESET); our $target = ""; our $encoding = lc( langinfo( CODESET() ) ); our $wm_name; our ( $opt_b, $opt_c, $opt_g, $opt_l, $opt_s, $opt_v, $opt_8 ); our @titlestack; # stack of title-strings, using current encoding our @item_stack; # selector used when doing a push our @mode_stack; # titleModes in effect when titlestack was loaded our $SP; # stack-pointer our $SQ = 10; # stack-limit our $TM; # current titleModes, in various combinations our @cmd_buffer; # command-input our $cmd_index; # current index in $cmd_buffer[] our $log_fp; # logging-output our $utf8_sample = 0; our $CSI = "\x1b["; our $DCS = "\x1bP"; our $OSC = "\x1b]"; our $ST = "\x1b\\"; sub SendHEX() { return ( $TM & 1 ) ? 1 : 0; } sub ReadHEX() { return ( $TM & 2 ) ? 1 : 0; } sub SendUTF8() { return ( $TM & 4 ) ? 1 : 0; } sub ReadUTF8() { return ( $TM & 8 ) ? 1 : 0; } sub to_hex($) { my $value = shift; my $result = ""; my $n; for ( $n = 0 ; $n < length($value) ; ++$n ) { $result .= sprintf( "%02X", ord substr( $value, $n, 1 ) ); } return $result; } sub from_hex($) { my $value = shift; my $result = ""; if ( $value =~ /^[[:xdigit:]]+$/ and ( length($value) % 2 ) == 0 ) { my $octets = ""; for ( my $n = 0 ; $n < length($value) ; $n += 2 ) { my $pair = substr( $value, $n, 2 ); my $data = hex $pair; $octets .= chr($data); } $result = decode( &ReadUTF8 ? "utf-8" : "iso-8859-1", $octets ); } else { $result = $value; } return $result; } sub show_string($) { my $value = shift; my $n; my $octets = encode( ( ( $encoding eq "utf-8" ) ? "utf-8" : "iso-8859-1" ), $value ); my $result = ""; for ( $n = 0 ; $n < length($octets) ; $n += 1 ) { my $c = ord substr( $octets, $n, 1 ); if ( $c == ord '\\' ) { $result .= "\\\\"; } elsif ( $c == 0x1b ) { $result .= "\\E"; } elsif ( $c == 0x7f ) { $result .= "^?"; } elsif ( $c == 32 ) { $result .= "\\s"; } elsif ( $c < 32 ) { $result .= sprintf( "^%c", $c + 64 ); } elsif ( $c > 128 ) { $result .= sprintf( "\\%03o", $c ); } else { $result .= chr($c); } } printf "%s\r\n", $result; } sub send_command($) { my $command = shift; if ($opt_v) { printf "send: "; &show_string($command); } print STDERR encode( &SendUTF8 ? "utf-8" : "iso-8859-1", $command ); } sub get_reply($) { my $command = shift; my $reply = ""; &send_command($command); my $start = time; while (1) { my $test = ReadKey 1; last if not defined $test; last if ( time > ( $start + 1 ) ); $reply .= $test; } if ($opt_v) { printf "read: "; &show_string($reply); } return $reply; } sub get_level() { my $reply = &get_reply( sprintf( "%s#S", $CSI ) ); if ( index( $reply, $CSI ) == 0 ) { $reply = substr( $reply, length($CSI) ); if ( $reply =~ /^\d+;\d+#S$/ ) { $reply =~ s/#S//; my @params = split /;/, $reply; $SP = $params[0]; $SQ = $params[1]; } } } sub get_titlemodes() { my $reply = &get_reply( sprintf( "%s\$q>t%s", $DCS, $ST ) ); my $prefix = "${DCS}1\$r"; my $p = index( $reply, $prefix ); my $q = index( $reply, $ST ); my $r = length($reply) - length($ST); if ( $p == 0 and $q == $r ) { $reply = substr( $reply, 0, $q ); $reply = substr( $reply, length($prefix) ); if ( $reply =~ /^>(\d;)*\dt$/ ) { $reply =~ s/^.(.+).$/$1/; my @modes = split /;/, $reply; $TM = 0; for my $n ( 0 .. $#modes ) { $TM += ( 1 << $n ) if ( $modes[$n] != 0 ); } } } } sub get_title($) { my $icon = shift; my $reply = &get_reply( sprintf( "%s%dt", $CSI, $icon ? 20 : 21 ) ); my $prefix = $icon ? "L" : "l"; if ( $opt_8 and ( $reply =~ /^$CSI/ ) ) { $reply =~ s/^${CSI}//; $reply =~ s/${ST}$//; } else { $reply =~ s/^\x1b//; $reply =~ s/^[\[\]]//; if ( index( $reply, $ST ) >= 0 ) { $reply =~ s/\x1b\\$//; } else { $reply =~ s/\007$//; } } if ( $reply =~ /^$prefix/ ) { $reply =~ s/^$prefix//; if (&ReadHEX) { $reply = &from_hex($reply); } } else { $reply = "?" . $reply; } return $reply; } sub raw() { ReadMode 'ultra-raw', 'STDIN'; # allow single-character inputs } sub cooked() { ReadMode 'normal'; } sub get_cmd() { my $result; select( undef, undef, undef, $opt_s ); if ( $cmd_index <= $#cmd_buffer ) { $result = $cmd_buffer[ $cmd_index++ ]; } else { $result = "q"; } return $result; } sub get_char() { my $result; if ($opt_c) { $result = &get_cmd(); if ( index( $result, "char:" ) == 0 ) { $result = substr( $result, 5 ); } else { $result = "q"; } } else { $result = ReadKey 0; } printf $log_fp "char:%s\n", $result if ($opt_l); return $result; } sub get_line() { my $result; if ($opt_c) { $result = &get_cmd(); if ( index( $result, "line:" ) == 0 ) { $result = substr( $result, 5 ); } else { $result = ""; } } else { &cooked; $result = ReadLine 0; chomp $result; &raw; } printf $log_fp "line:%s\n", $result if ($opt_l); return $result; } sub read_cmd($) { my $command = shift; my @result; if ( open( my $fp, "$command |" ) ) { binmode( $fp, ":utf8" ) if ( $encoding eq "utf-8" ); @result = <$fp>; close($fp); chomp @result; } return @result; } sub which_modes($) { my $modes = shift; my $result = ""; if ( $modes & 3 ) { $result .= "put" if ( ( $modes & 3 ) == 1 ); $result .= "get" if ( ( $modes & 3 ) == 2 ); $result .= "p/q" if ( ( $modes & 3 ) == 3 ); $result .= " hex"; } if ( $modes & 12 ) { $modes /= 4; $result .= "," unless ( $result eq "" ); $result .= "put" if ( ( $modes & 3 ) == 1 ); $result .= "get" if ( ( $modes & 3 ) == 2 ); $result .= "p/q" if ( ( $modes & 3 ) == 3 ); $result .= " utf"; } $result = "default" if ( $result eq "" ); return $result; } sub which_tmode($$) { my $set = shift; my $mode = shift; my $result = ""; $result = "set window/icon labels using hexadecimal" if ( $mode == 0 ); $result = "query window/icon labels using hexadecimal" if ( $mode == 1 ); $result = "set window/icon labels using UTF-8" if ( $mode == 2 ); $result = "query window/icon labels using UTF-8" if ( $mode == 3 ); $result = "do not " . $result if ( $set == 0 and $result ne "" ); return $result; } sub get_tmode($) { my $set = shift; my $help = 0; my $result = "?"; while ( $result !~ /^[0123]$/ ) { $result = &get_char; if ( $result eq "q" ) { $result = -1; last; } elsif ( $result eq "?" and not $help ) { for my $n ( 0 .. 3 ) { printf "\r\n\t%s = %s", $n, &which_tmode( $set, $n ); } printf "\r\n\t:"; $help = 1; } } if ( $result >= 0 ) { printf "[%s]\r\n\t:", &which_tmode( $set, $result ); } return $result; } sub which_item($) { my $code = shift; my $result = ""; $result = "both" if ( $code == 0 ); $result = "icon" if ( $code == 1 ); $result = "name" if ( $code == 2 ); return $result; } sub which_selector($) { my $code = shift; my $result = ""; $result = "both titles" if ( $code == 0 ); $result = "icon title" if ( $code == 1 ); $result = "window title" if ( $code == 2 ); return $result; } sub get_selector() { my $result = "?"; my $help = 0; printf "\t:"; while ( $result !~ /^[012]$/ ) { $result = &get_char; if ( $result eq "q" ) { $result = -1; last; } elsif ( $result eq "l" ) { $result = 2; } elsif ( $result eq "L" ) { $result = 1; } elsif ( $result eq "?" and not $help ) { for my $n ( 0 .. 2 ) { printf "\r\n\t%d = %s", $n, &which_selector($n); } printf "\r\n\t:"; $help = 1; } } if ( $result >= 0 ) { printf "[%s]\r\n\t:", &which_selector($result); } return $result; } sub display_info() { # use xprop to get properties my $command = "xprop"; if ( $ENV{WINDOWID} ) { my $windowid = $ENV{WINDOWID}; $command .= " -id " . $windowid if ( $windowid ne "" ); } else { printf "...xprop\r\n"; } my @props = &read_cmd($command); for my $n ( 0 .. $#props ) { printf "\t%s\r\n", $props[$n] if ( index( $props[$n], "WM_NAME(" ) >= 0 or index( $props[$n], "WM_ICON_NAME(" ) >= 0 ); } # use escape sequences to get corresponding information printf "... Icon title:%s\r\n", &get_title(1); printf "... Window title:%s\r\n", &get_title(0); # show title-stack (and modes used for each level) printf "... Modes[%s]\r\n", &which_modes($TM); printf "... Stack(%d):\r\n", $SP; for my $n ( 0 .. $SP ) { printf "\t%d [%s:%s]%s\r\n", $n, &which_item( $item_stack[$n] ), &which_modes( $mode_stack[$n] ), $titlestack[$n]; } } sub set_titlemode($) { my $set = shift; my $opts = ""; my $opt; printf "\t:"; while ( ( $opt = &get_tmode($set) ) >= 0 ) { $TM |= ( 1 << $opt ) if ($set); $TM &= ~( 1 << $opt ) unless ($set); $opts .= ";" unless ( $opts eq "" ); $opts .= $opt; } if ( $opts ne "" ) { &send_command( sprintf( "%s>%s%s", $CSI, $opts, $set ? "t" : "T" ) ); } if ($opt_l) { my $save = $TM; &get_titlemodes; if ( $TM != $save ) { printf $log_fp "note: expected title-modes $save, got $TM\n"; } } } sub utf8_sample($) { my $item = shift; my $last = 4; my $text; if ( ( $item % $last ) == 0 ) { my $chars = "THE QUICK BROWN FOX\nJUMPED OVER THE LAZY DOG"; $text = ""; for my $n ( 0 .. length($chars) ) { my $chr = substr( $chars, $n, 1 ); if ( $chr eq " " ) { $chr = " "; } elsif ( ord($chr) < 32 ) { # leave control characters as-is } else { $chr = chr( 0xff00 + ord($chr) - 32 ); } $text .= $chr; } } elsif ( ( $item % $last ) == 1 ) { $text = chr(0x442) . chr(0x435) . chr(0x441) . chr(0x442); } elsif ( ( $item % $last ) == 2 ) { for my $chr ( 0x391 .. 0x3a9 ) { $text .= chr($chr); } } elsif ( ( $item % $last ) == 3 ) { for my $chr ( 0x3b1 .. 0x3c9 ) { $text .= chr($chr); } } return $text; } sub set_titletext() { my $opt = &get_selector; if ( $opt >= 0 ) { my $text; if ($opt_g) { if (&SendUTF8) { $text = &utf8_sample( $utf8_sample++ ); } else { # ugly code, but mapping the a/e/i/o/u uppercase accented # characters that repeat. my $a_chars = chr(192) . chr(193) . chr(194) . chr(196); my $e_chars = ""; my $i_chars = " "; my $o_chars = chr(210) . chr(211) . chr(212) . chr(214); my $u_chars = ""; my $gap = " " . chr(215) . " "; for my $chr ( 0 .. 3 ) { $e_chars .= chr( $chr + 200 ); $i_chars .= chr( $chr + 204 ) . " "; $u_chars .= chr( $chr + 217 ); } $text = $a_chars . $gap . $e_chars . $gap . $i_chars . $gap . $o_chars . $gap . $u_chars; } &cooked; printf "%s\r\n", $text; &raw; } else { $text = &get_line; } $titlestack[$SP] = $text; $item_stack[$SP] = $opt; $mode_stack[$SP] = $TM; if (&SendHEX) { my $octets = encode( ( &SendUTF8 ? "utf-8" : "iso-8859-1" ), $text ); $text = &to_hex($octets); } &send_command( sprintf( "%s%s;%s%s", $OSC, $opt, $text, $ST ) ); } } sub save_title() { my $opt = &get_selector; if ( $opt >= 0 ) { &send_command( sprintf( "%s22;%st", $CSI, $opt ) ); ++$SP; $titlestack[$SP] = $titlestack[ $SP - 1 ]; $item_stack[$SP] = $opt; $mode_stack[$SP] = $mode_stack[ $SP - 1 ]; } } sub restore_title($) { my $set = shift; my $opt = &get_selector unless ($set); if ( $opt >= 0 and $SP > 0 ) { $opt = $item_stack[$SP] if ($set); &send_command( sprintf( "%s23;%st", $CSI, $opt ) ); $SP--; } } sub get_xprop($$) { my $id = shift; my $name = shift; my @data = &read_cmd("xprop -id $id"); my $prop = ""; for my $n ( 0 .. $#data ) { if ( $data[$n] =~ /$name\([^)]+\) =/ ) { $prop = $data[$n]; $prop =~ s/^[^=]*=\s*//; $prop =~ s/"//g; last; } } return $prop; } sub get_WM_NAME() { $wm_name = "missing WM_NAME"; my $supwin = `xprop -root '_NET_SUPPORTING_WM_CHECK'`; if ( $supwin ne "" ) { $supwin =~ s/^.*(0x[[:xdigit:]]+).*/$1/; $wm_name = &get_xprop( $supwin, "_NET_WM_NAME" ); $wm_name = "unknown" if ( $wm_name eq "" ); printf "** using \"$wm_name\" window manager\n"; } } sub main::HELP_MESSAGE() { printf STDERR <; close $cmd_fp; chomp @cmd_buffer; $cmd_index = 0; } if ($opt_l) { open( $log_fp, ">", $opt_l ) || &main::HELP_MESSAGE; } $opt_s = "1" unless ( defined($opt_s) and ( $opt_s =~ /^(\d*\.)?\d+$/ ) ); $ST = "\007" if ($opt_b); $SP = 0; $titlestack[$SP] = "unknown"; $item_stack[$SP] = 0; $mode_stack[$SP] = $TM = 0; binmode( STDOUT, ":utf8" ) if ( $encoding eq "utf-8" ); if ($opt_8) { if ( $encoding eq "utf-8" ) { undef $opt_8; printf "...ignoring -8 option since locale uses %s\n", $encoding; } else { printf STDERR "\x1b G"; $CSI = "\x9b"; $DCS = "\x90"; $OSC = "\x9d"; $ST = "\x9c"; } } &get_WM_NAME; &raw; &get_titlemodes; &get_level; &raw; while (1) { my $cmd; printf "\r\n[$SP:$SQ] Command (? for help):"; $cmd = &get_char; if ( not $cmd ) { sleep 1; } elsif ( $cmd eq "?" ) { printf "\r\n? help," . " d=display," . " m/M=set/reset mode," . " p=set title," . " q=quit," . " r=restore," . " s=save\r\n"; } elsif ( $cmd eq "#" ) { printf " ...comment\r\n\t#"; &get_line; } elsif ( $cmd eq "!" ) { printf " ...shell\r\n"; &cooked; system( $ENV{SHELL} ); &raw; } elsif ( $cmd eq "d" ) { printf " ...display\r\n"; &display_info; } elsif ( $cmd eq "p" ) { printf " ...set text\r\n"; &set_titletext; } elsif ( $cmd eq "q" ) { printf " ...quit\r\n"; last; } elsif ( $cmd eq "s" ) { printf " ...save title\r\n"; &save_title; } elsif ( $cmd eq "r" ) { printf " ...restore title\r\n"; &restore_title(0); } elsif ( $cmd eq "m" ) { printf " ...set title mode\r\n"; &set_titlemode(1); } elsif ( $cmd eq "M" ) { printf " ...reset title mode\r\n"; &set_titlemode(0); } } # when unstacking here, just use the selector used for the push while ( $SP > 0 ) { &restore_title(1); } &send_command( sprintf( "%s>T", $CSI ) ); # reset title-modes to default &cooked; printf "\x1b F" if ($opt_8); xterm-399/vttests/query-dynamic.pl0000755000000000000000000001421713470215053016105 0ustar rootroot#!/usr/bin/env perl # $XTermId: query-dynamic.pl,v 1.6 2019/05/19 08:56:11 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2019 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Test the color-query features of xterm for dynamic-colors use strict; use warnings; use Getopt::Std; use IO::Handle; our ( $opt_q, $opt_s, $opt_8 ); our @query_params; our @color_names = ( "VT100 text foreground color", "VT100 text background color", "text cursor color", "mouse foreground color", "mouse background color", "Tektronix foreground color", "Tektronix background color", "highlight background color", "Tektronix cursor color", "highlight foreground color" ); $Getopt::Std::STANDARD_HELP_VERSION = 1; &getopts('qs8') || die( "Usage: $0 [options]\n Options:\n -q quicker results by merging queries -s use ^G rather than ST -8 use 8-bit controls " ); our $OSC = "\x1b\]"; $OSC = "\x9d" if ($opt_8); our $ST = $opt_8 ? "\x9c" : ( $opt_s ? "\007" : "\x1b\\" ); sub get_reply($) { open TTY, "+; close TTY; system "stty $old"; if ( defined $reply ) { die("^C received\n") if ( "$reply" eq "\003" ); } return $reply; } sub visible($) { my $reply = $_[0]; my $n; my $result = ""; for ( $n = 0 ; $n < length($reply) ; ) { my $c = substr( $reply, $n, 1 ); if ( $c =~ /[[:print:]]/ ) { $result .= $c; } else { my $k = ord substr( $reply, $n, 1 ); if ( ord $k == 0x1b ) { $result .= "\\E"; } elsif ( $k == 0x7f ) { $result .= "^?"; } elsif ( $k == 32 ) { $result .= "\\s"; } elsif ( $k < 32 ) { $result .= sprintf( "^%c", $k + 64 ); } elsif ( $k > 128 ) { $result .= sprintf( "\\%03o", $k ); } else { $result .= chr($k); } } $n += 1; } return $result; } sub begin_query() { @query_params = (); } sub add_param($) { $query_params[ $#query_params + 1 ] = $_[0]; } sub show_reply($) { my $reply = shift; printf "data={%s}", &visible($reply); } sub finish_query($) { return unless (@query_params); my $reply; my $n; my $st = $opt_8 ? qr/\x9c/ : ( $opt_s ? qr/\007/ : qr/\x1b\\/ ); my $osc = $opt_8 ? qr/\x9d/ : qr/\x1b]/; my $match = qr/${osc}.*${st}/; my $params = join( ";", @query_params ); $params =~ s/\d+/?/g; $params = sprintf( "%d;%s", $query_params[0], $params ); $reply = &get_reply( $OSC . $params . $ST ); printf "query{%s}", &visible($params); if ( defined $reply ) { printf " len=%2d ", length($reply); if ( $reply =~ /${match}/ ) { my @chunks = split /${st}${osc}/, $reply; printf "\n" if ( $#chunks > 0 ); for my $c ( 0 .. $#chunks ) { $chunks[$c] =~ s/^${osc}// if ( $c == 0 ); $chunks[$c] =~ s/${st}$// if ( $c == $#chunks ); my $param = $chunks[$c]; $param =~ s/^(\d+);.*/$1/; $param = -1 unless ( $param =~ /^\d+$/ ); $chunks[$c] =~ s/^\d+;//; printf "\t%d: ", $param if ( $#chunks > 0 ); &show_reply( $chunks[$c] ); printf " %s", $color_names[ $param - 10 ] if ( ( $param >= 10 ) and ( ( $param - 10 ) <= $#color_names ) ); printf "\n" if ( $c < $#chunks ); } } else { printf "? "; &show_reply($reply); } } printf "\n"; } sub query_color($) { my $param = shift; &begin_query unless $opt_q; if ( $#query_params >= 0 and ( $param != $query_params[$#query_params] + 1 ) ) { &finish_query; &begin_query; } &add_param($param); &finish_query unless $opt_q; } sub query_colors($$) { my $lo = shift; my $hi = shift; my $n; for ( $n = $lo ; $n <= $hi ; ++$n ) { &query_color($n); } } printf "\x1b G" if ($opt_8); &begin_query if ($opt_q); if ( $#ARGV >= 0 ) { while ( $#ARGV >= 0 ) { if ( $ARGV[0] =~ /-/ ) { my @args = split /-/, $ARGV[0]; &query_colors( $args[0], $args[1] ); } else { &query_colors( $ARGV[0], $ARGV[0] ); } shift @ARGV; } } else { &query_colors( 10, 19 ); } &finish_query if ($opt_q); printf "\x1b F" if ($opt_8); 1; xterm-399/vttests/altchars.sh0000755000000000000000000000502313746406602015121 0ustar rootroot#!/bin/sh # $XTermId: altchars.sh,v 1.4 2020/10/29 00:32:02 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2020 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- echo tput enacs tput smacs #define ACS_ULCORNER NCURSES_ACS('l') /* upper left corner */ #define ACS_LLCORNER NCURSES_ACS('m') /* lower left corner */ #define ACS_URCORNER NCURSES_ACS('k') /* upper right corner */ #define ACS_LRCORNER NCURSES_ACS('j') /* lower right corner */ #define ACS_LTEE NCURSES_ACS('t') /* tee pointing right */ #define ACS_RTEE NCURSES_ACS('u') /* tee pointing left */ #define ACS_BTEE NCURSES_ACS('v') /* tee pointing up */ #define ACS_TTEE NCURSES_ACS('w') /* tee pointing down */ #define ACS_HLINE NCURSES_ACS('q') /* horizontal line */ #define ACS_VLINE NCURSES_ACS('x') /* vertical line */ #define ACS_PLUS NCURSES_ACS('n') /* large plus or crossover */ cat <<'EOF' XlqqqqwqqqqwqqqqwqqqqkX XxaaaaxaaaaxaaaaxaaaaxX XtqqqqnqqqqnqqqqnqqqquX XxaaaaxaaaaxaaaaxaaaaxX XmqqqqvqqqqvqqqqvqqqqjX X _`abcdefghijklmn X X opqrstuvwxyz{|}~ X X ................ X EOF tput rmacs cat <<'EOF' +----+----+----+----+ EOF xterm-399/vttests/other-sgr.sh0000755000000000000000000001015614231357364015235 0ustar rootroot#!/bin/sh # $XTermId: other-sgr.sh,v 1.9 2022/04/24 23:36:20 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2018-2021,2022 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Show non-VTxx SGRs combined with the conventional VT100/VT220 SGRs ESC="" CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' : "${TMPDIR=/tmp}" TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null { test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null if test -f "$TMP" ; then if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' break fi fi done rm -f "$TMP" trap '$CMD $OPT "${CSI}0m"; exit 1' 1 2 3 15 trap '$CMD $OPT "${CSI}0m"' 0 echo "${CSI}0m" while true do # blink(5) and conceal(8) are omitted because they are distracting, but the # case-statement handles those if the for-statement includes them. for GRP in 0 1 4 7 do case $GRP in 0) attr="normal ";; 1) attr="bold ";; 4) attr="under ";; 5) attr="blink ";; 7) attr="reverse ";; 8) attr="conceal ";; esac for NUL in "0" "21" do for ROW in $NUL "2" "3" "9" "2;3" "2;9" "3;9" "2;3;9" do case $ROW in "0") rlabel="normal ";; "21") rlabel="double ";; "2") rlabel="dim ";; "3") rlabel="italic ";; "2;3") rlabel="di/it ";; "9") rlabel="crossout";; "2;9") rlabel="di/cr ";; "3;9") rlabel="it/cr ";; "2;3;9") rlabel="di/it/cr";; *) rlabel="UNKNOWN ";; esac # video attributes from the first two columns intentionally # "bleed through" to the other columns to help show some of # the possible combinations of attributes. $CMD $OPT "$GRP:${CSI}${GRP}m$attr${SUF}" $CMD $OPT "${CSI}${ROW}m$rlabel${SUF}" for COL in $NUL "3" "9" "2;3" "2;9" "3;9" "2;3;9" do END="" case $COL in "0") clabel="normal ";; "21") clabel="double "; END="${CSI}24m";; "2") clabel="dim "; END="${CSI}22m";; "3") clabel="italic "; END="${CSI}23m";; "2;3") clabel="di/it "; END="${CSI}22;23m";; "9") clabel="crossout"; END="${CSI}29m";; "2;9") clabel="di/cr "; END="${CSI}22;29m";; "3;9") clabel="it/cr "; END="${CSI}23;29m";; "2;3;9") clabel="di/it/cr"; END="${CSI}23;29m";; *) clabel="UNKNOWN ";; esac # The remaining columns (try to) reset their respective # attribute, to make the result somewhat readable. $CMD $OPT "${CSI}${COL}m$clabel${END}${SUF}" done echo "${CSI}0m:$GRP" done done [ -t 1 ] && sleep 3 done [ -t 1 ] || break done xterm-399/vttests/tcapquery.pl0000755000000000000000000002434113461704175015342 0ustar rootroot#!/usr/bin/env perl # $XTermId: tcapquery.pl,v 1.29 2019/04/29 23:27:57 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2004-2018,2019 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Test the tcap-query option of xterm. use strict; use warnings; use Getopt::Std; use IO::Handle; our ( $opt_a, $opt_b, $opt_c, $opt_e, $opt_f, $opt_i, $opt_k, $opt_m, $opt_q, $opt_t, $opt_x, $opt_X ); our @query_params; our @query_result; $Getopt::Std::STANDARD_HELP_VERSION = 1; &getopts('abcefikmqt:x:X') || die( "Usage: $0 [options]\n Options:\n -a (same as -c -e -f -k -m) -b use both terminfo and termcap (default is termcap) -c cursor-keys -e editing keypad-keys -f function-keys -i use terminfo rather than termcap names -k numeric keypad-keys -m miscellaneous (none of -c, -e, -f, -k) -q quicker results by merging queries -t NAME use given NAME for \$TERM, set that in xterm's tcap keyboard -x KEY extended cursor/editing key (terminfo only) -X test all extended cursor- and/or editing-keys (terminfo) " ); if ( not( defined($opt_c) or defined($opt_e) or defined($opt_f) or defined($opt_k) or defined($opt_m) or defined($opt_x) ) ) { $opt_a = 1; } sub no_reply($) { open TTY, "+; close TTY; system "stty $old"; if ( defined $reply ) { die("^C received\n") if ( "$reply" eq "\003" ); } return $reply; } sub hexified($) { my $value = $_[0]; my $result = ""; my $n; for ( $n = 0 ; $n < length($value) ; ++$n ) { $result .= sprintf( "%02X", ord substr( $value, $n, 1 ) ); } return $result; } sub modify_tcap($) { my $name = $_[0]; my $param = &hexified($name); &no_reply( "\x1bP+p" . $param . "\x1b\\" ); } sub begin_query() { @query_params = (); } sub add_param($) { $query_params[ $#query_params + 1 ] = &hexified( $_[0] ); } sub finish_query() { my $reply = &get_reply( "\x1bP+q" . join( ';', @query_params ) . "\x1b\\" ); return unless defined $reply; if ( $reply =~ /\x1bP1\+r[[:xdigit:]]+=[[:xdigit:]]*.*/ ) { my $n; $reply =~ s/^\x1bP1\+r//; $reply =~ s/\x1b\\//; my $result = ""; my $count = 0; my $state = 0; my $error = "?"; for ( $n = 0 ; $n < length($reply) ; ) { my $c = substr( $reply, $n, 1 ); if ( $c eq ';' ) { $n += 1; printf "%d%s\t%s\n", $count, $error, $result if ( $result ne "" ); $result = ""; $state = 0; $error = "?"; $count++; } elsif ( $c eq '=' ) { $error = "" if ( $count <= $#query_params and &hexified($result) eq $query_params[$count] ); $n += 1; $result .= $c; $state = 1; } elsif ( $c =~ /[[:punct:]]/ ) { $n += 1; $result .= $c; } else { my $k = hex substr( $reply, $n, 2 ); if ( $k == 0x1b ) { $result .= "\\E"; } elsif ( $k == 0x7f ) { $result .= "^?"; } elsif ( $k == 32 ) { $result .= "\\s"; } elsif ( $k < 32 ) { $result .= sprintf( "^%c", $k + 64 ); } elsif ( $k > 128 ) { $result .= sprintf( "\\%03o", $k ); } else { $result .= chr($k); } $n += 2; } } printf "%d%s\t%s\n", $count, $error, $result if ( $result ne "" ); } } sub query_tcap($$) { my $tcap = shift; my $tinfo = shift; &begin_query unless ($opt_q); &add_param($tcap) if ( $opt_b or not $opt_i ); &add_param($tinfo) if ( $opt_b or $opt_i ); &finish_query unless ($opt_q); } # extended-keys are a feature of ncurses 5.0 and later sub query_extended($) { my $name = $_[0]; my $n; $name = "k" . $name if ( $name !~ /^k/ ); for ( $n = 2 ; $n <= 7 ; ++$n ) { my $test = $name; $test = $test . $n if ( $n > 2 ); &query_tcap( $name, $test ); } } &begin_query if ($opt_q); &query_tcap( "TN", "name" ); if ( defined($opt_t) ) { printf "Setting TERM=%s\n", $opt_t; &modify_tcap($opt_t); } # See xtermcapKeycode() if ( defined($opt_a) || defined($opt_c) ) { &query_tcap( "ku", "kcuu1" ); &query_tcap( "kd", "kcud1" ); &query_tcap( "kr", "kcuf1" ); &query_tcap( "kl", "kcub1" ); &query_tcap( "kF", "kind" ); &query_tcap( "kR", "kri" ); &query_tcap( "%i", "kRIT" ); &query_tcap( "#4", "kLFT" ); } if ( defined($opt_a) || defined($opt_e) ) { &query_tcap( "kD", "kdch1" ); &query_tcap( "kI", "kich1" ); &query_tcap( "kh", "khome" ); &query_tcap( "\@7", "kend" ); &query_tcap( "#2", "kHOM" ); &query_tcap( "*7", "kEND" ); &query_tcap( "*6", "kslt" ); &query_tcap( "#6", "kSLT" ); &query_tcap( "\@0", "kfnd" ); &query_tcap( "*0", "kFND" ); &query_tcap( "kN", "knp" ); &query_tcap( "kP", "kpp" ); &query_tcap( "%c", "kNXT" ); &query_tcap( "%e", "kPRV" ); } if ( defined($opt_a) || defined($opt_f) ) { &query_tcap( "k1", "kf1" ); &query_tcap( "k2", "kf2" ); &query_tcap( "k3", "kf3" ); &query_tcap( "k4", "kf4" ); &query_tcap( "k5", "kf5" ); &query_tcap( "k6", "kf6" ); &query_tcap( "k7", "kf7" ); &query_tcap( "k8", "kf8" ); &query_tcap( "k9", "kf9" ); &query_tcap( "k;", "kf10" ); &query_tcap( "F1", "kf11" ); &query_tcap( "F2", "kf12" ); &query_tcap( "F3", "kf13" ); &query_tcap( "F4", "kf14" ); &query_tcap( "F5", "kf15" ); &query_tcap( "F6", "kf16" ); &query_tcap( "F7", "kf17" ); &query_tcap( "F8", "kf18" ); &query_tcap( "F9", "kf19" ); &query_tcap( "FA", "kf20" ); &query_tcap( "FB", "kf21" ); &query_tcap( "FC", "kf22" ); &query_tcap( "FD", "kf23" ); &query_tcap( "FE", "kf24" ); &query_tcap( "FF", "kf25" ); &query_tcap( "FG", "kf26" ); &query_tcap( "FH", "kf27" ); &query_tcap( "FI", "kf28" ); &query_tcap( "FJ", "kf29" ); &query_tcap( "FK", "kf30" ); &query_tcap( "FL", "kf31" ); &query_tcap( "FM", "kf32" ); &query_tcap( "FN", "kf33" ); &query_tcap( "FO", "kf34" ); &query_tcap( "FP", "kf35" ); &query_tcap( "FQ", "kf36" ); &query_tcap( "FR", "kf37" ); &query_tcap( "FS", "kf38" ); &query_tcap( "FT", "kf39" ); &query_tcap( "FU", "kf40" ); &query_tcap( "FV", "kf41" ); &query_tcap( "FW", "kf42" ); &query_tcap( "FX", "kf43" ); &query_tcap( "FY", "kf44" ); &query_tcap( "FZ", "kf45" ); &query_tcap( "Fa", "kf46" ); &query_tcap( "Fb", "kf47" ); &query_tcap( "Fc", "kf48" ); &query_tcap( "Fd", "kf49" ); &query_tcap( "Fe", "kf50" ); &query_tcap( "Ff", "kf51" ); &query_tcap( "Fg", "kf52" ); &query_tcap( "Fh", "kf53" ); &query_tcap( "Fi", "kf54" ); &query_tcap( "Fj", "kf55" ); &query_tcap( "Fk", "kf56" ); &query_tcap( "Fl", "kf57" ); &query_tcap( "Fm", "kf58" ); &query_tcap( "Fn", "kf59" ); &query_tcap( "Fo", "kf60" ); &query_tcap( "Fp", "kf61" ); &query_tcap( "Fq", "kf62" ); &query_tcap( "Fr", "kf63" ); } if ( defined($opt_a) || defined($opt_k) ) { &query_tcap( "K1", "ka1" ); &query_tcap( "K3", "ka3" ); &query_tcap( "K4", "kc1" ); &query_tcap( "K5", "kc3" ); } if ( defined($opt_a) || defined($opt_m) ) { &query_tcap( "kB", "kcbt" ); &query_tcap( "kC", "kclr" ); &query_tcap( "&8", "kund" ); &query_tcap( "kb", "kbs" ); &query_tcap( "%1", "khlp" ); &query_tcap( "#1", "kHLP" ); &query_tcap( "Co", "colors" ); &query_tcap( "Co", "RGB" ) if ($opt_i); } if ( defined($opt_x) ) { &query_extended($opt_x); } if ( defined($opt_X) ) { if ( defined($opt_c) ) { &query_extended("DN"); &query_extended("UP"); &query_extended("LFT"); &query_extended("RIT"); } if ( defined($opt_e) ) { &query_extended("DC"); &query_extended("END"); &query_extended("HOM"); &query_extended("IC"); &query_extended("NXT"); &query_extended("PRV"); } } &finish_query if ($opt_q); 1; xterm-399/vttests/acolors.sh0000755000000000000000000000557614231454632014773 0ustar rootroot#!/bin/sh # $XTermId: acolors.sh,v 1.16 2022/04/25 08:19:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2002-2021,2022 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Demonstrate the use of the control sequence for changing ANSI colors. ESC="" CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' : "${TMPDIR=/tmp}" TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null { test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null if test -f "$TMP" ; then if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' break fi fi done rm -f "$TMP" LIST="00 30 80 d0 ff" exec /dev/tty read -r original stty $old original=${original}${SUF} trap '$CMD $OPT "$original" >/dev/tty; exit 1' 1 2 3 15 trap '$CMD $OPT "$original" >/dev/tty' 0 echo "${CSI}0;1;34mThis message is BLUE" echo "${CSI}0;1;31mThis message is RED ${CSI}0;31m(sometimes)" echo "${CSI}0;1;32mThis message is GREEN${CSI}0m" while true do for R in $LIST do for G in $LIST do for B in $LIST do # color "9" is bold-red test "$R" != 00 && test "$G" = 00 && test "$B" = 00 && $CMD $OPT "" >/dev/tty $CMD $OPT "${ESC}]4;9;rgb:$R/$G/$B${SUF}" >/dev/tty sleep 1 done done done done xterm-399/vttests/query-fonts.pl0000755000000000000000000001066413470215173015617 0ustar rootroot#!/usr/bin/env perl # $XTermId: query-fonts.pl,v 1.8 2019/05/19 08:57:31 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2010-2018,2019 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Test the font-query features of xterm. # TODO: # test relative vs absolute font numbering # test all font-slots # test selection # test bold / wide / widebold # test actual fontname vs nominal # extend "CSI > Ps; Ps T" to query fontname in hex use strict; use warnings; use Getopt::Std; use IO::Handle; our ( $opt_a, $opt_r, $opt_s ); $Getopt::Std::STANDARD_HELP_VERSION = 1; &getopts('ars') || die( "Usage: $0 [options]\n Options:\n -a test using absolute numbers -r test using relative numbers -s use ^G rather than ST " ); our $ST = $opt_s ? "\007" : "\x1b\\"; sub get_reply($) { open TTY, "+; close TTY; system "stty $old"; if ( defined $reply ) { die("^C received\n") if ( "$reply" eq "\003" ); } return $reply; } sub query_font($) { my $param = $_[0]; my $reply; my $n; my $st = $opt_s ? qr/\007/ : qr/\x1b\\/; my $osc = qr/\x1b]50/; my $match = qr/${osc}.*${st}/; $reply = get_reply( "\x1b]50;?" . $param . $ST ); printf "query{%s}%*s", $param, 3 - length($param), " "; if ( defined $reply ) { printf "%2d ", length($reply); if ( $reply =~ /${match}/ ) { $reply =~ s/^${osc}//; $reply =~ s/^;//; $reply =~ s/${st}$//; } else { printf "? "; } my $result = ""; for ( $n = 0 ; $n < length($reply) ; ) { my $c = substr( $reply, $n, 1 ); if ( $c =~ /[[:print:]]/ ) { $result .= $c; } else { my $k = ord substr( $reply, $n, 1 ); if ( ord $k == 0x1b ) { $result .= "\\E"; } elsif ( $k == 0x7f ) { $result .= "^?"; } elsif ( $k == 32 ) { $result .= "\\s"; } elsif ( $k < 32 ) { $result .= sprintf( "^%c", $k + 64 ); } elsif ( $k > 128 ) { $result .= sprintf( "\\%03o", $k ); } else { $result .= chr($k); } } $n += 1; } printf "{%s}", $result; } printf "\n"; } if ($opt_r) { my $n; query_font("-"); foreach $n ( 0 .. 5 ) { query_font( sprintf "-%d", $n ); } query_font("+"); foreach $n ( 0 .. 5 ) { query_font( sprintf "+%d", $n ); } } if ($opt_a) { my $n; foreach $n ( 0 .. 5 ) { query_font( sprintf "%d", $n ); } } if ( not $opt_a and not $opt_r ) { query_font(""); } xterm-399/vttests/palettes.pl0000755000000000000000000007024214473176006015147 0ustar rootroot#!/usr/bin/env perl # $XTermId: palettes.pl,v 1.27 2023/08/28 19:56:54 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2020,2023 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Demonstrate how to set palette colors using xterm's control sequences. # TODO: add "-n" option, to show tput in dry-run mode # TODO: make some way to optimize-out the Tcolors resets, to focus on tput vs hardcoded use strict; use warnings; use Getopt::Std; use Term::ReadKey; use FileHandle; select(STDERR); $| = 1; select(STDOUT); $| = 1; our ( $opt_a, $opt_b, $opt_d, $opt_g, $opt_i, $opt_p, $opt_s, $opt_T, $opt_v, $opt_x, $opt_8 ); our ( $CSI, $OSC, $ST ); our %colors; our @Acolors; our %Tcolors; our $dump; our %Tcolor_names = qw( 0 foreground 1 background 2 cursorColor 3 pointerForegroundColor 4 pointerBackgroundColor 5 tektronixForegroundColor 6 tektronixBackgroundColor 7 highlightColor 8 tektronixCursorColor 9 highlightForegroundColor ); our $DARK; sub isatty() { my $result = 0; $result = 1 if ( -t 0 and -t 1 and -t 2 ); return $result; } # Adapted from # https://github.com/altercation/solarized (xresources/solarized) sub init_solarized() { $colors{S_yellow} = 0xb58900; $colors{S_orange} = 0xcb4b16; $colors{S_red} = 0xdc322f; $colors{S_magenta} = 0xd33682; $colors{S_violet} = 0x6c71c4; $colors{S_blue} = 0x268bd2; $colors{S_cyan} = 0x2aa198; $colors{S_green} = 0x859900; if ($DARK) { $colors{S_base03} = 0x002b36; $colors{S_base02} = 0x073642; $colors{S_base01} = 0x586e75; $colors{S_base00} = 0x657b83; $colors{S_base0} = 0x839496; $colors{S_base1} = 0x93a1a1; $colors{S_base2} = 0xeee8d5; $colors{S_base3} = 0xfdf6e3; } else { $colors{S_base03} = 0xfdf6e3; $colors{S_base02} = 0xeee8d5; $colors{S_base01} = 0x93a1a1; $colors{S_base00} = 0x839496; $colors{S_base0} = 0x657b83; $colors{S_base1} = 0x586e75; $colors{S_base2} = 0x073642; $colors{S_base3} = 0x002b36; } $Acolors[0] = $colors{S_base02}; $Acolors[1] = $colors{S_red}; $Acolors[2] = $colors{S_green}; $Acolors[3] = $colors{S_yellow}; $Acolors[4] = $colors{S_blue}; $Acolors[5] = $colors{S_magenta}; $Acolors[6] = $colors{S_cyan}; $Acolors[7] = $colors{S_base2}; $Acolors[9] = $colors{S_orange}; $Acolors[8] = $colors{S_base03}; $Acolors[10] = $colors{S_base01}; $Acolors[11] = $colors{S_base00}; $Acolors[12] = $colors{S_base0}; $Acolors[13] = $colors{S_violet}; $Acolors[14] = $colors{S_base1}; $Acolors[15] = $colors{S_base3}; $Tcolors{background} = $colors{S_base03}; $Tcolors{foreground} = $colors{S_base0}; $Tcolors{cursorColor} = $colors{S_base1}; $Tcolors{pointerColorBackground} = $colors{S_base01}; $Tcolors{pointerColorForeground} = $colors{S_base1}; } # Most of the "themes" are from this source: # http://web.archive.org/web/20100329130515/http://phraktured.net:80/terminal-colors # in turn, that cites Aaron Griffin (2007) and uses colortheme.sh, referring to # https://github.com/Rydgel/archlinux/blob/master/scripts/colortheme.sh # https://web.archive.org/web/20060630201817/http://frexx.de/xterm-256-notes/ sub init_1() { $Tcolors{background} = 0x000000; $Tcolors{foreground} = 0xa8a8a8; $Acolors[0] = 0x000000; $Acolors[1] = 0xa80000; $Acolors[2] = 0x00a800; $Acolors[3] = 0xa85400; $Acolors[4] = 0x0000a8; $Acolors[5] = 0xa800a8; $Acolors[6] = 0x00a8a8; $Acolors[7] = 0xa8a8a8; $Acolors[8] = 0x545054; $Acolors[9] = 0xf85450; $Acolors[10] = 0x50fc50; $Acolors[11] = 0xf8fc50; $Acolors[12] = 0x5054f8; $Acolors[13] = 0xf854f8; $Acolors[14] = 0x50fcf8; $Acolors[15] = 0xf8fcf8; } sub init_2() { $Tcolors{background} = 0x000000; $Tcolors{foreground} = 0x7f7f7f; $Acolors[0] = 0x000000; $Acolors[1] = 0x9e1828; $Acolors[2] = 0xaece92; $Acolors[3] = 0x968a38; $Acolors[4] = 0x414171; $Acolors[5] = 0x963c59; $Acolors[6] = 0x418179; $Acolors[7] = 0xbebebe; $Acolors[8] = 0x666666; $Acolors[9] = 0xcf6171; $Acolors[10] = 0xc5f779; $Acolors[11] = 0xfff796; $Acolors[12] = 0x4186be; $Acolors[13] = 0xcf9ebe; $Acolors[14] = 0x71bebe; $Acolors[15] = 0xffffff; } sub init_3() { $Tcolors{background} = 0x000000; $Tcolors{foreground} = 0xcfcfcf; $Acolors[0] = 0x000000; $Acolors[1] = 0xe01010; $Acolors[2] = 0x20ad20; $Acolors[3] = 0xd4c24f; $Acolors[4] = 0x231bb8; $Acolors[5] = 0x9c3885; $Acolors[6] = 0x1dbdb8; $Acolors[7] = 0xfefefe; $Acolors[8] = 0x6a6a6a; $Acolors[9] = 0xe83a3d; $Acolors[10] = 0x35e956; $Acolors[11] = 0xffff2f; $Acolors[12] = 0x3a53f0; $Acolors[13] = 0xe628ba; $Acolors[14] = 0x1cf5f5; $Acolors[15] = 0xffffff; } sub init_4() { $Tcolors{background} = 0x000000; $Tcolors{foreground} = 0xffffff; $Acolors[0] = 0x000000; $Acolors[1] = 0xd36265; $Acolors[2] = 0xaece91; $Acolors[3] = 0xe7e18c; $Acolors[4] = 0x7a7ab0; $Acolors[5] = 0x963c59; $Acolors[6] = 0x418179; $Acolors[7] = 0xbebebe; $Acolors[8] = 0x666666; $Acolors[9] = 0xef8171; $Acolors[10] = 0xe5f779; $Acolors[11] = 0xfff796; $Acolors[12] = 0x4186be; $Acolors[13] = 0xef9ebe; $Acolors[14] = 0x71bebe; $Acolors[15] = 0xffffff; } sub init_5() { $Tcolors{background} = 0xadaaad; $Tcolors{foreground} = 0x000000; $Acolors[0] = 0x000000; $Acolors[1] = 0x640f19; $Acolors[2] = 0x63796b; $Acolors[3] = 0xad7142; $Acolors[4] = 0x4f4f89; $Acolors[5] = 0xb25c7c; $Acolors[6] = 0x52756b; $Acolors[7] = 0xadaaad; $Acolors[8] = 0x525552; $Acolors[9] = 0xa56163; $Acolors[10] = 0xcec263; $Acolors[11] = 0x73ae70; $Acolors[12] = 0x36709f; $Acolors[13] = 0xaa829c; $Acolors[14] = 0x518989; $Acolors[15] = 0xffffef; } sub init_6() { $Tcolors{background} = 0xbebebe; $Tcolors{foreground} = 0x212121; $Acolors[0] = 0x000000; $Acolors[1] = 0xbf7276; $Acolors[2] = 0x86af80; $Acolors[3] = 0x968a38; $Acolors[4] = 0x3673b5; $Acolors[5] = 0x9a70b2; $Acolors[6] = 0x7abecc; $Acolors[7] = 0xdbdbdb; $Acolors[8] = 0x6692af; $Acolors[9] = 0xe5505f; $Acolors[10] = 0x87bc87; $Acolors[11] = 0xe0d95c; $Acolors[12] = 0x1b85d6; $Acolors[13] = 0xad73ba; $Acolors[14] = 0x338eaa; $Acolors[15] = 0xf4f4f4; } sub init_7() { $Tcolors{background} = 0x676767; $Tcolors{foreground} = 0xffffff; $Acolors[0] = 0x000000; $Acolors[1] = 0xbf4646; $Acolors[2] = 0x67b25f; $Acolors[3] = 0xcfc44e; $Acolors[4] = 0x516083; $Acolors[5] = 0xca6eff; $Acolors[6] = 0x92b2f8; $Acolors[7] = 0xd5d5d5; $Acolors[8] = 0x000000; $Acolors[9] = 0xf48a8a; $Acolors[10] = 0xa5d79f; $Acolors[11] = 0xe1da84; $Acolors[12] = 0xa2bbff; $Acolors[13] = 0xe2b0ff; $Acolors[14] = 0xbacdf8; $Acolors[15] = 0xd5d5d5; } sub init_8() { $Tcolors{background} = 0x101010; $Tcolors{foreground} = 0xd3d3d3; $Acolors[0] = 0x101010; $Acolors[1] = 0xcd5c5c; $Acolors[2] = 0x2e8b57; $Acolors[3] = 0xf0e68c; $Acolors[4] = 0xb0c4de; $Acolors[5] = 0xba55d3; $Acolors[6] = 0x4682b4; $Acolors[7] = 0xd3d3d3; $Acolors[8] = 0x4d4d4d; $Acolors[9] = 0xff6a6a; $Acolors[10] = 0x8fbc8f; $Acolors[11] = 0xfffacd; $Acolors[12] = 0x1e90ff; $Acolors[13] = 0xdb7093; $Acolors[14] = 0x5f9ea0; $Acolors[15] = 0xffffff; } sub init_9() { $Tcolors{background} = 0x1a1a1a; $Tcolors{foreground} = 0xd6d6d6; $Acolors[0] = 0x000000; $Acolors[1] = 0x9e1828; $Acolors[2] = 0x008800; $Acolors[3] = 0x968a38; $Acolors[4] = 0x414171; $Acolors[5] = 0x963c59; $Acolors[6] = 0x418179; $Acolors[7] = 0xbebebe; $Acolors[8] = 0x666666; $Acolors[9] = 0xcf6171; $Acolors[10] = 0x7cbc8c; $Acolors[11] = 0xfff796; $Acolors[12] = 0x4186be; $Acolors[13] = 0xcf9ebe; $Acolors[14] = 0x71bebe; $Acolors[15] = 0xffffff; } sub init_10() { $Tcolors{background} = 0x1a1a1a; $Tcolors{foreground} = 0xd6d6d6; $Acolors[0] = 0x000000; $Acolors[1] = 0x98565e; $Acolors[2] = 0x66825d; $Acolors[3] = 0x969176; $Acolors[4] = 0x4d6585; $Acolors[5] = 0x967395; $Acolors[6] = 0x5f7f7b; $Acolors[7] = 0xb3b3b3; $Acolors[8] = 0x737373; $Acolors[9] = 0xcfa3a9; $Acolors[10] = 0xcaf7bb; $Acolors[11] = 0xfff8bc; $Acolors[12] = 0x83a3be; $Acolors[13] = 0xbba9cf; $Acolors[14] = 0x96cccc; $Acolors[15] = 0xffffff; } sub init_11() { $Tcolors{background} = 0x333333; $Tcolors{foreground} = 0xffffff; $Acolors[0] = 0x333333; $Acolors[1] = 0xffa0a0; $Acolors[2] = 0x98fb98; $Acolors[3] = 0xf0e68c; $Acolors[4] = 0x87ceeb; $Acolors[5] = 0xffa0a0; $Acolors[6] = 0x87ceeb; $Acolors[7] = 0xffffff; $Acolors[8] = 0x333333; $Acolors[9] = 0xffa0a0; $Acolors[10] = 0x9acd32; $Acolors[11] = 0xf0e68c; $Acolors[12] = 0x87ceeb; $Acolors[13] = 0xffa0a0; $Acolors[14] = 0x87ceeb; $Acolors[15] = 0xffffff; } sub init_12() { $Tcolors{foreground} = 0xffffff; $Tcolors{background} = 0x000000; $Acolors[0] = 0x000000; $Acolors[1] = 0xbf7276; $Acolors[2] = 0x86af80; $Acolors[3] = 0x968a38; $Acolors[4] = 0x3673b5; $Acolors[5] = 0x9a70b2; $Acolors[6] = 0x7abecc; $Acolors[7] = 0xdbdbdb; $Acolors[8] = 0x6692af; $Acolors[9] = 0xe5505f; $Acolors[10] = 0x87bc87; $Acolors[11] = 0xe0d95c; $Acolors[12] = 0x1b85d6; $Acolors[13] = 0xad73ba; $Acolors[14] = 0x338eaa; $Acolors[15] = 0xf4f4f4; } sub init_13() { $Tcolors{background} = 0x000000; $Tcolors{foreground} = 0xaaaaaa; $Acolors[0] = 0x000000; $Acolors[1] = 0x9e1828; $Acolors[2] = 0xaece92; $Acolors[3] = 0x968a38; $Acolors[4] = 0x414171; $Acolors[5] = 0x963c59; $Acolors[6] = 0x7f9f7f; $Acolors[7] = 0xbebebe; $Acolors[8] = 0x666666; $Acolors[9] = 0xcf6171; $Acolors[10] = 0xafc5af; $Acolors[11] = 0xf0dfaf; $Acolors[12] = 0x8e9fbc; $Acolors[13] = 0xdca3a3; $Acolors[14] = 0x95c1c5; $Acolors[15] = 0xffffff; } sub init_14() { $Tcolors{background} = 0x959595; $Tcolors{foreground} = 0x000000; $Acolors[0] = 0x7f7f7f; $Acolors[1] = 0xcd0000; $Acolors[2] = 0x008b00; $Acolors[3] = 0xeeee00; $Acolors[4] = 0x0000cd; $Acolors[5] = 0xcd00cd; $Acolors[6] = 0x00eeee; $Acolors[7] = 0xfaebd7; $Acolors[8] = 0xe5e5e5; $Acolors[9] = 0x800000; $Acolors[10] = 0x005020; $Acolors[11] = 0x995500; $Acolors[12] = 0x004080; $Acolors[13] = 0x443300; $Acolors[14] = 0x306080; $Acolors[15] = 0xffffff; } sub init_15() { $Tcolors{background} = 0x1d2b3a; $Tcolors{foreground} = 0xbebebe; $Acolors[0] = 0x000000; $Acolors[1] = 0xd36265; $Acolors[2] = 0xaece91; $Acolors[3] = 0xe7e18c; $Acolors[4] = 0x7a7ab0; $Acolors[5] = 0x963c59; $Acolors[6] = 0x418179; $Acolors[7] = 0xbebebe; $Acolors[8] = 0x666666; $Acolors[9] = 0xef8171; $Acolors[10] = 0xe5f779; $Acolors[11] = 0xfff799; $Acolors[12] = 0x4186be; $Acolors[13] = 0xef9ebe; $Acolors[14] = 0x71bebe; $Acolors[15] = 0xffffff; } sub init_16() { $Tcolors{background} = 0x000000; $Tcolors{foreground} = 0xbebebe; $Acolors[0] = 0x000000; $Acolors[1] = 0x9e1828; $Acolors[2] = 0xaece92; $Acolors[3] = 0x968a38; $Acolors[4] = 0x414171; $Acolors[5] = 0x963c59; $Acolors[6] = 0x418179; $Acolors[7] = 0xbebebe; $Acolors[8] = 0x666666; $Acolors[9] = 0xcf6171; $Acolors[10] = 0xc5f779; $Acolors[11] = 0xfff796; $Acolors[12] = 0x4186be; $Acolors[13] = 0xcf9ebe; $Acolors[14] = 0x71bebe; $Acolors[15] = 0xffffff; } sub init_17() { $Tcolors{background} = 0x000000; $Tcolors{foreground} = 0xe5e5e5; $Acolors[0] = 0x000000; $Acolors[1] = 0xff0000; $Acolors[2] = 0x00ff00; $Acolors[3] = 0xffff00; $Acolors[4] = 0x0000ff; $Acolors[5] = 0xff00ff; $Acolors[6] = 0x00ffff; $Acolors[7] = 0xffffff; $Acolors[8] = 0xffd39b; $Acolors[9] = 0xff8247; $Acolors[10] = 0xff82ab; $Acolors[11] = 0x87cefa; $Acolors[12] = 0xffffff; $Acolors[13] = 0xffffff; $Acolors[14] = 0xffffff; $Acolors[15] = 0xffffff; } sub init_18() { $Acolors[0] = 0x000000; $Acolors[1] = 0x9e1828; $Acolors[2] = 0x5cb247; $Acolors[3] = 0x968a38; $Acolors[4] = 0x4161a0; $Acolors[5] = 0x9b768e; $Acolors[6] = 0x419189; $Acolors[7] = 0xbebebe; $Acolors[8] = 0x666666; $Acolors[9] = 0xcf6171; $Acolors[10] = 0xc5f779; $Acolors[11] = 0xfff796; $Acolors[12] = 0x4186be; $Acolors[13] = 0xcf9ebe; $Acolors[14] = 0x71bebe; $Acolors[15] = 0xdddddd; } sub init_19() { $Acolors[0] = 0x000000; $Acolors[1] = 0xb07050; $Acolors[2] = 0x12914e; $Acolors[3] = 0xa0a070; $Acolors[4] = 0x3e4581; $Acolors[5] = 0xa070a0; $Acolors[6] = 0x70a0a0; $Acolors[7] = 0xa0a0a0; $Acolors[8] = 0x606060; $Acolors[9] = 0xb07050; $Acolors[10] = 0x12914e; $Acolors[11] = 0xc0c090; $Acolors[12] = 0x3e4581; $Acolors[13] = 0xc090c0; $Acolors[14] = 0x90c0c0; $Acolors[15] = 0xffffff; } sub init_20() { $Tcolors{foreground} = 0xaaaaaa; $Tcolors{background} = 0x000000; $Acolors[0] = 0x303430; $Acolors[1] = 0xbf7979; $Acolors[2] = 0x97b26b; $Acolors[3] = 0xcdcdc1; $Acolors[4] = 0x86a2be; $Acolors[5] = 0xd9b798; $Acolors[6] = 0xa1b5cd; $Acolors[7] = 0xffffff; $Acolors[8] = 0xcdb5cd; $Acolors[9] = 0xf4a45f; $Acolors[10] = 0xc5f779; $Acolors[11] = 0xffffef; $Acolors[12] = 0x98afd9; $Acolors[13] = 0xd7d998; $Acolors[14] = 0xa1b5cd; $Acolors[15] = 0xdedede; } sub init_21() { $Tcolors{background} = 0x1a1a1a; $Tcolors{foreground} = 0xaaaaaa; $Acolors[0] = 0x000000; $Acolors[1] = 0x9e1828; $Acolors[2] = 0x008800; $Acolors[3] = 0xd2bb4b; $Acolors[4] = 0x414171; $Acolors[5] = 0x963c59; $Acolors[6] = 0x418179; $Acolors[7] = 0xbebebe; $Acolors[8] = 0x666666; $Acolors[9] = 0xbc5766; $Acolors[10] = 0x61a171; $Acolors[11] = 0xe7db52; $Acolors[12] = 0x5085af; $Acolors[13] = 0xa97a99; $Acolors[14] = 0x6ba4a4; $Acolors[15] = 0xffffff; } sub init_22() { $Tcolors{background} = 0x000000; $Tcolors{foreground} = 0xbebebe; $Acolors[0] = 0x000000; $Acolors[1] = 0xd36265; $Acolors[2] = 0xaece91; $Acolors[3] = 0xe7e18c; $Acolors[4] = 0x7a7ab0; $Acolors[5] = 0x963c59; $Acolors[6] = 0x7f9f7f; $Acolors[7] = 0xbebebe; $Acolors[8] = 0x666666; $Acolors[9] = 0xef8171; $Acolors[10] = 0xe5f779; $Acolors[11] = 0xf0dfaf; $Acolors[12] = 0x8e9fbc; $Acolors[13] = 0xef9ebe; $Acolors[14] = 0x71bebe; $Acolors[15] = 0xffffff; } sub init_23() { $Tcolors{background} = 0x0e0e0e; $Tcolors{foreground} = 0x4ad5e1; $Acolors[0] = 0x000000; $Acolors[1] = 0xdc74d1; $Acolors[2] = 0x0eb8c7; $Acolors[3] = 0xdfe37e; $Acolors[4] = 0x0; #?? $Acolors[5] = 0x9e88f0; $Acolors[6] = 0x73f7ff; $Acolors[7] = 0xe1dddd; $Acolors[8] = 0x8b8f93; $Acolors[9] = 0xdc74d1; $Acolors[10] = 0x0eb8c7; $Acolors[11] = 0xdfe37e; $Acolors[13] = 0x9e88f0; $Acolors[14] = 0x73f7ff; $Acolors[15] = 0xe1dddd; } sub init_24() { $Acolors[0] = 0x000000; $Acolors[1] = 0xcd5c5c; $Acolors[2] = 0x8eae71; $Acolors[3] = 0xd2b48c; $Acolors[4] = 0x5f7b8a; $Acolors[5] = 0xcdcdb4; $Acolors[6] = 0x686868; $Acolors[7] = 0xffffff; $Acolors[8] = 0x000000; $Acolors[9] = 0xee6363; $Acolors[10] = 0x95c749; $Acolors[11] = 0xcdcdc1; $Acolors[12] = 0x6b7b8a; $Acolors[13] = 0xcdcdb4; $Acolors[14] = 0x778798; $Acolors[15] = 0xcacaca; } sub init_25() { $Acolors[0] = 0x000000; $Acolors[1] = 0x800000; $Acolors[2] = 0x008000; $Acolors[3] = 0xd0d090; $Acolors[4] = 0x000080; $Acolors[5] = 0x800080; $Acolors[6] = 0xa6caf0; $Acolors[7] = 0xd0d0d0; $Acolors[8] = 0xb0b0b0; $Acolors[9] = 0xf08060; $Acolors[10] = 0x60f080; $Acolors[11] = 0xe0c060; $Acolors[12] = 0x80c0e0; $Acolors[13] = 0xf0c0f0; $Acolors[14] = 0xc0d8f8; $Acolors[15] = 0xe0e0e0; } # (Griffin) colors ripped from rezza: http://metawire.org/~rezza/index.php sub init_rezza() { $Tcolors{foreground} = 0xdddddd; $Tcolors{background} = 0x222222; $Acolors[0] = 0x191919; $Acolors[1] = 0x803232; $Acolors[2] = 0x5b762f; $Acolors[3] = 0xaa9943; $Acolors[4] = 0x324c80; $Acolors[5] = 0x706c9a; $Acolors[6] = 0x92b19e; $Acolors[7] = 0xffffff; $Acolors[8] = 0x252525; $Acolors[9] = 0x982b2b; $Acolors[10] = 0x89b83f; $Acolors[11] = 0xefef60; $Acolors[12] = 0x2b4f98; $Acolors[13] = 0x826ab1; $Acolors[14] = 0xa1cdcd; $Acolors[15] = 0xdddddd; } sub init_theme($) { my $theme = shift; @Acolors = (); %Tcolors = (); &init_solarized if ( index( "solarized", $theme ) eq 0 ); &init_rezza if ( index( "rezza", $theme ) eq 0 ); &init_1 if ( $theme eq 1 ); &init_2 if ( $theme eq 2 ); &init_3 if ( $theme eq 3 ); &init_4 if ( $theme eq 4 ); &init_5 if ( $theme eq 5 ); &init_6 if ( $theme eq 6 ); &init_7 if ( $theme eq 7 ); &init_8 if ( $theme eq 8 ); &init_9 if ( $theme eq 9 ); &init_10 if ( $theme eq 10 ); &init_11 if ( $theme eq 11 ); &init_12 if ( $theme eq 12 ); &init_13 if ( $theme eq 13 ); &init_14 if ( $theme eq 14 ); &init_15 if ( $theme eq 15 ); &init_16 if ( $theme eq 16 ); &init_17 if ( $theme eq 17 ); &init_18 if ( $theme eq 18 ); &init_19 if ( $theme eq 19 ); &init_20 if ( $theme eq 20 ); &init_21 if ( $theme eq 21 ); &init_22 if ( $theme eq 22 ); &init_23 if ( $theme eq 23 ); &init_24 if ( $theme eq 24 ); &init_25 if ( $theme eq 25 ); } sub all_themes() { my @result; push @result, "solarized"; push @result, "rezza"; for my $n ( 1 .. 25 ) { push @result, $n; } return \@result; } sub raw() { ReadMode 'ultra-raw', 'STDIN'; # allow single-character inputs } sub cooked() { ReadMode 'normal'; } sub get_reply($$) { my $command = shift; my $finish = shift; my $reply = ""; &raw; printf STDERR "%s", $command; my $start = time; while ( index( $reply, $finish ) < 0 ) { my $test = ReadKey 0.1; last if ( time > ( $start + 3 ) ); next if not defined $test; $reply .= $test; } &cooked; return $reply; } sub query_color($$) { my $ansi = shift; my $code = shift; my @result; my $parms; if ($ansi) { $parms = sprintf( "4;%d", $code ); } else { $parms = sprintf( "%d", 10 + $code ); } my $query = sprintf( "%s%s;?%s", $OSC, $parms, $ST ); my $reply = &get_reply( $query, $ST ); if ( $reply =~ /^${OSC}${parms};rgb:/ ) { $reply =~ s/^${OSC}${parms};rgb://; $reply =~ s/[^[:print:]].*$//; if ( $reply =~ /^[[:xdigit:]]+(\/[[:xdigit:]]+)+$/ ) { $reply =~ s/([[:xdigit:]]+)/0x$1/g; @result = split /\//, $reply; # RGB should have 3 values for my $n ( 0 .. $#result ) { $result[$n] = hex $result[$n]; } # add the limit based on the number of bits needed to print. push @result, 2**( 4 * ( length($reply) - 2 ) / 3 ); } } # this would occur in case of error push @result, $reply unless ( $#result >= 3 ); return @result; } sub get_color_string($$) { my $ansi = shift; my $color = shift; my $result; my @check = &query_color( $ansi, $color ); if ( $#check == 3 ) { while ( $check[3] > 0x10000 ) { $check[0] /= ( 16 * 16 ); $check[1] /= ( 16 * 16 ); $check[2] /= ( 16 * 16 ); $check[3] /= ( 16 * 16 * 16 ); } $result = sprintf "( %3d %3d %3d )", $check[0], $check[1], $check[2]; } else { $result = sprintf( "{%s}", $check[0] ); } return $result; } sub guess_dark() { my $result = 0; # assume black-on-white if (&isatty) { my @check = &query_color( 0, 1 ); if ( $#check == 3 ) { my $value = ( ( $check[0] ) + ( $check[1] ) + ( $check[2] ) ) / 3; printf "%#x / %#x\n", $value, $check[3]; $result = 1 if ( $value < ( $check[3] / 2 ) ); printf "%s\n", $result ? "dark" : "light" if ($opt_v); } } return $result; } sub for_tput($) { my $value = shift; $value *= 1000; $value /= 255; $value *= 256 / 255; return sprintf( "%.0f", $value ); } sub reset_Acolor($) { my $number = shift; printf STDERR "%s104;%d%s", $OSC, $number, $ST; printf "\t%2d ->reset Acolor\n", $number if ($opt_v); } sub set_Acolor($) { my $number = shift; my $result = 0; if ( defined $Acolors[$number] ) { my $value = $Acolors[$number]; my $r = ( ( $value / ( 256 * 256 ) ) % 256 ); my $g = ( ( $value / (256) ) % 256 ); my $b = ( ( $value / (1) ) % 256 ); if ($opt_x) { system( sprintf( "$opt_x $opt_T initc %d %d %d %d", $number, &for_tput($r), &for_tput($g), &for_tput($b) ) ); } else { printf STDERR "%s4;%d;rgb:%02X/%02X/%02X%s", $OSC, $number, $r, $g, $b, $ST; } printf "\t%2d ->%06X ( %3d %3d %3d )\n", $number, $value, $r, $g, $b if ($opt_v); $result = 1; } return $result; } sub reset_Tcolor($) { my $number = shift; my $actual = $Tcolor_names{$number}; printf STDERR "%s%d%s", $OSC, 110 + $number, $ST; printf "\t%2d ->reset Tcolor{%s}\n", $number, $actual if ($opt_v); } sub set_Tcolor($) { my $number = shift; my $actual = $Tcolor_names{$number}; my $result = 0; if (%Tcolors) { if ( defined $Tcolors{$actual} ) { my $value = $Tcolors{$actual}; my $r = ( ( $value / ( 256 * 256 ) ) % 256 ); my $g = ( ( $value / (256) ) % 256 ); my $b = ( ( $value / (1) ) % 256 ); printf STDERR "%s%d;rgb:%02X/%02X/%02X%s", $OSC, 10 + $number, $r, $g, $b, $ST; printf "\t%2d ->set Tcolor{%s}\n", $number, $actual if ($opt_v); $result = 1; } } return $result; } sub set_colors() { for my $n ( 0 .. 2 ) { &reset_Tcolor($n) unless &set_Tcolor($n); } for my $n ( 0 .. 15 ) { &reset_Acolor($n) unless &set_Acolor($n); } printf STDERR "\007" if (&isatty); STDERR->flush; } sub reset_colors() { for my $n ( 0 .. 2 ) { &reset_Tcolor($n); } printf STDERR "%s104%s", $OSC, $ST; printf "\tall ->reset Acolor\n" if ($opt_v); } sub dump_colors($) { my $theme = shift; if ( open( DUMP, ">>", $opt_d ) ) { my $state = &get_reply( sprintf( "%s#R", $CSI ), "Q" ); $state = substr( $state, length($CSI) ) if ( index( $state, $CSI ) == 0 ); printf DUMP "State \"%s\"\n", $state; printf DUMP "Palette after \"%s\"\n", $theme; if (&isatty) { printf DUMP "Tcolors:\n"; for my $n ( 0 .. 2 ) { printf DUMP "\t%s = %s\n", $Tcolor_names{$n}, &get_color_string( 0, $n ); } printf DUMP "Acolors:\n"; for my $n ( 0 .. 15 ) { printf DUMP "\t%2d -> %s\n", $n, &get_color_string( 1, $n ); } } close DUMP; } } sub show_colors($) { my $theme = shift; if ( substr( $theme, 0, 1 ) eq "+" ) { # push (or set slot, if number follows) if ( $theme =~ /^\+[0-9]$/ ) { my $slot = substr( $theme, 1 ); printf STDERR "%s#%dP", $CSI, $slot + 1; printf "\tpush %s\n", $slot if ($opt_v); } else { printf STDERR "%s#P", $CSI; printf "\tpush\n" if ($opt_v); } } elsif ( substr( $theme, 0, 1 ) eq "-" ) { # pop (or restore from slot, if number follows) if ( $theme =~ /^-[0-9]$/ ) { my $slot = substr( $theme, 1 ); printf STDERR "%s#%dQ", $CSI, $slot + 1; printf "\tpop %s\n", $slot if ($opt_v); } else { printf STDERR "%s#Q", $CSI; printf "\tpop\n" if ($opt_v); } } elsif ( $theme eq "?" ) { # query TODO printf STDERR "%s#R", $CSI; printf "\tquery\n" if ($opt_v); } else { &init_theme($theme); &set_colors if ( $#Acolors >= 0 ); &reset_colors unless ( $#Acolors >= 0 ); } &dump_colors($theme) if ($opt_d); } sub show_themes($) { my @themes = @{ $_[0] }; for my $n ( 0 .. $#themes ) { &show_colors( $themes[$n] ); printf STDERR "\033[11i" if ( &isatty and $opt_p ); if ( ( $n != $#themes ) and &isatty ) { sleep $opt_s; } } } sub main::HELP_MESSAGE() { printf STDERR <= 0 ) ); if ($opt_8) { $CSI = "\x9b"; $OSC = "\x9d"; $ST = "\x9c"; } else { $CSI = "\x1b["; $OSC = "\x1b]"; $ST = "\x1b\\"; } $ST = "\007" if ($opt_b); $opt_s = 1 unless ($opt_s); $opt_T = "-T $opt_T" if ($opt_T); $opt_T = "-T xterm-256color" unless ($opt_T); $DARK = 0; $DARK = 1 if ($opt_i); $DARK = &guess_dark if ($opt_g); if ($opt_a) { &show_themes(&all_themes); } elsif ( $#ARGV >= 0 ) { &show_themes( \@ARGV ); } else { &show_colors("solarized"); } 1; xterm-399/vttests/report-sgr.pl0000755000000000000000000004036513515157545015440 0ustar rootroot#!/usr/bin/env perl # $XTermId: report-sgr.pl,v 1.35 2019/07/21 21:55:49 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2018,2019 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Test the report-sgr option of xterm. # TODO: add "-8" option, for 8-bit controls use strict; use warnings; use Getopt::Long qw(:config auto_help no_ignore_case); use Pod::Usage; use Term::ReadKey; our ( $opt_colors, $opt_direct, $opt_help, $opt_man ); our $csi = "\033["; our $osc = "\033]"; our $st = "\033\\"; our @sgr_names = qw( Normal Bold Faint Italicized Underlined Blink Fast-Blink Inverse Invisible Crossed-Out ); our ( $row_max, $col_max ); our ( $mark, $top_row ); our $cur_sgr = 0; # indexed colors, e.g., "ANSI" our %indexed_f = qw ( default 1 c 7 ); our %indexed_b = qw ( default 1 c 0 ); # direct colors our %direct_f = qw ( default 0 r 255 g 0 b 0 ); our %direct_b = qw ( default 0 r 0 g 0 b 255 ); our $which_value = "video-attributes"; our $which_color = "red"; our ( $row_1st, $col_1st, $row_now, $col_now ); sub beep() { printf "\a"; } sub cup($$) { my $r = shift; my $c = shift; printf "%s%d;%dH", $csi, $r, $c; } sub el($) { printf "%s%sK", $csi, $_[0]; } sub ed($) { printf "%s%sJ", $csi, $_[0]; } sub sgr($) { printf "%s%sm", $csi, $_[0]; } sub same_rgb($$) { my %c1 = %{ $_[0] }; my %c2 = %{ $_[1] }; my $result = 1; $result = 0 if ( $c1{r} ne $c2{r} ); $result = 0 if ( $c1{g} ne $c2{g} ); $result = 0 if ( $c1{b} ne $c2{b} ); return $result; } sub color_name($) { my $code = shift; my $result; if ($opt_direct) { $result = $code; } else { if ( $code < 0 ) { $result = "default"; } else { $result = $code; } } return $result; } sub color_code($$) { my $isfg = shift; my $result = ""; my $base = $isfg ? 30 : 40; if ($opt_direct) { $result = sprintf "%d:2", $base + 8; if ($isfg) { $result .= sprintf ":%d:%d:%d", # $direct_f{r}, # $direct_f{g}, # $direct_f{b}; } else { $result .= sprintf ":%d:%d:%d", # $direct_b{r}, # $direct_b{g}, # $direct_b{b}; } } else { my %data = $isfg ? %indexed_f : %indexed_b; if ( &is_default( \%data ) ) { $result = $base + 9; } else { if ( $opt_colors <= 16 ) { $base += 60 if ( $data{c} >= 8 ); $result = $base + $data{c}; } else { $result = sprintf "%d:5:%d", $base + 8, $data{c}; } } } return $result; } sub show_string($) { my $value = $_[0]; my $n; $value = "" unless $value; my $result = ""; for ( $n = 0 ; $n < length($value) ; $n += 1 ) { my $c = ord substr( $value, $n, 1 ); if ( $c == ord '\\' ) { $result .= "\\\\"; } elsif ( $c == 0x1b ) { $result .= "\\E"; } elsif ( $c == 0x7f ) { $result .= "^?"; } elsif ( $c == 32 ) { $result .= "\\s"; } elsif ( $c < 32 ) { $result .= sprintf( "^%c", $c + 64 ); } elsif ( $c > 128 ) { $result .= sprintf( "\\%03o", $c ); } else { $result .= chr($c); } } return $result; } sub get_reply($) { my $command = $_[0]; my $reply = ""; print STDOUT $command; autoflush STDOUT 1; while (1) { my $test = ReadKey 0.02; last if not defined $test; $reply .= $test; } return $reply; } sub show_status() { &cup( 1, 1 ); &el(2); my $show = ""; my $parm = ""; if ($mark) { my $r1 = ( $row_now > $row_1st ) ? $row_1st : $row_now; my $r2 = ( $row_now < $row_1st ) ? $row_1st : $row_now; my $c1 = ( $col_now > $col_1st ) ? $col_1st : $col_now; my $c2 = ( $col_now < $col_1st ) ? $col_1st : $col_now; $show = sprintf "[%d,%d] [%d,%d] ", $r1, $c1, $r2, $c2; $parm = sprintf "%d;%d;%d;%d", $r1, $c1, $r2, $c2; } else { $show = sprintf "[%d,%d] ", $row_now, $col_now; $parm = sprintf "%d;%d;%d;%d", # $row_now, $col_now, # $row_now, $col_now; } my $send = sprintf "%s%s#|", $csi, $parm; printf "%s %s ", $show, &show_string($send); &cup( $row_now, $col_now ); my $reply = &get_reply($send); &cup( 2, 1 ); &el(2); printf "read %s", &show_string($reply); &cup( $row_now, $col_now ); } sub toggle_default() { if ($opt_direct) { if ( $which_value =~ /^f/ ) { $direct_f{default} = !$direct_f{default}; } elsif ( $which_value =~ /^b/ ) { $direct_b{default} = !$direct_b{default}; } else { &beep; } } else { if ( $which_value =~ /^f/ ) { $indexed_f{default} = !$indexed_f{default}; } elsif ( $which_value =~ /^b/ ) { $indexed_b{default} = !$indexed_b{default}; } else { &beep; } } &show_example; } sub is_default($) { my $result = 0; my %data = %{ $_[0] }; $result = ( $data{default} != 0 ); return $result; } sub change_color($$) { my $inc = $_[0]; my %data = %{ $_[1] }; my $name = $_[2]; $data{$name} = ( $data{$name} + $opt_colors + $inc ) % $opt_colors; return %data; } sub set_which_value($) { $which_value = shift; &show_example; } sub set_which_color($) { $which_color = shift; &show_example; } sub change_value($) { my $inc = shift; if ( $which_value =~ /^v/ ) { $cur_sgr = ( $cur_sgr + 10 + $inc ) % 10; } elsif ( $which_value =~ /^f/ ) { if ($opt_direct) { %direct_f = &change_color( $inc, \%direct_f, "r" ) if ( $which_color =~ /^r/ ); %direct_f = &change_color( $inc, \%direct_f, "g" ) if ( $which_color =~ /^g/ ); %direct_f = &change_color( $inc, \%direct_f, "b" ) if ( $which_color =~ /^b/ ); } else { %indexed_f = &change_color( $inc, \%indexed_f, "c" ); } } elsif ( $which_value =~ /^b/ ) { if ($opt_direct) { %direct_b = &change_color( $inc, \%direct_b, "r" ) if ( $which_color =~ /^r/ ); %direct_b = &change_color( $inc, \%direct_b, "g" ) if ( $which_color =~ /^g/ ); %direct_b = &change_color( $inc, \%direct_b, "b" ) if ( $which_color =~ /^b/ ); } else { %indexed_b = &change_color( $inc, \%indexed_b, "c" ); } } &show_example; } sub show_example() { &cup( $top_row, 1 ); my $init = "0"; if ($opt_direct) { $init .= sprintf ";%s", &color_code(1); $init .= sprintf ";%s", &color_code(0); } else { $init .= sprintf ";%s", &color_code(1) unless ( &is_default( \%indexed_f ) ); $init .= sprintf ";%s", &color_code(0) unless ( &is_default( \%indexed_b ) ); } &ed(0); for my $n ( 0 .. 9 ) { my $mode = $n; $mode = $init if ( $n == 0 ); &cup( $n + $top_row, 1 ); if ($opt_direct) { &sgr($init); &sgr( &same_rgb( \%direct_f, \%direct_b ) ? "0" : $init ); } else { &sgr( $indexed_f{c} eq $indexed_b{c} ? "0" : $init ); } printf "%s SGR %d: %-12s", # ( $cur_sgr == $n ) ? "-->" : " ", # $n, $sgr_names[$n]; $mode .= ";$cur_sgr" unless ( $cur_sgr eq "0" ); &sgr($mode); printf "%.55s", # "abcdefghijklmnopqrstuvwxyz" . # "ABCDEFGHIJKLMNOPQRSTUVWXYZ" . # "0123456789"; } &sgr(0); my $end = $top_row + 11; &cup( $end++, 1 ); printf 'Change %s with "<" or ">".', ( $opt_direct and ( $which_value !~ /^v/ ) ) ? ( sprintf "%s(%s)", $which_value, $which_color ) : $which_value; &cup( $end++, 1 ); printf "Current SGR %d (%s)", $cur_sgr, $sgr_names[$cur_sgr]; if ($opt_direct) { &cup( $end++, 1 ); printf "Colors: direct"; &cup( $end++, 1 ); if ( &is_default( \%direct_f ) ) { printf " fg( default )"; } else { printf " fg( r=%s, g=%s, b=%s )", # &color_name( $direct_f{r} ), # &color_name( $direct_f{g} ), # &color_name( $direct_f{b} ); } &cup( $end++, 1 ); if ( &is_default( \%direct_b ) ) { printf " bg( default )"; } else { printf " bg( r=%s, g=%s, b=%s )", # &color_name( $direct_b{r} ), # &color_name( $direct_b{g} ), # &color_name( $direct_b{b} ); } } else { &cup( $end++, 1 ); printf "Colors: indexed"; if ( &is_default( \%indexed_f ) ) { printf ", fg=default"; } else { printf ", fg=%s", &color_name( $indexed_f{c} ); } if ( &is_default( \%indexed_b ) ) { printf ", bg=default"; } else { printf ", bg=%s", &color_name( $indexed_b{c} ); } } &cup( $end++, 1 ); printf ' ("q" to quit, "?" for help)'; } sub init_screensize() { $row_max = 24; $col_max = 80; &cup( 9999, 9999 ); my $result = &get_reply( $csi . "6n" ); if ( $result =~ /^$csi[[:digit:];]+R$/ ) { $result =~ s/^$csi[;]*//; $result =~ s/[;]*R$//; my @params = split /;/, $result; if ( $#params == 1 ) { $row_max = $params[0]; $col_max = $params[1]; } } &cup( 1, 1 ); } sub startup_screen() { ReadMode 'ultra-raw', 'STDIN'; } sub restore_screen() { &sgr(0); printf "%s102%s", $osc, $st if ($opt_direct); &cup( $row_max, 1 ); ReadMode 'restore', 'STDIN'; } GetOptions( 'colors=i', # 'help|?', # 'direct', # 'man' ) || pod2usage(2); pod2usage(1) if $opt_help; pod2usage( -verbose => 2 ) if $opt_man; $opt_colors = ( $opt_direct ? 256 : 8 ) unless ($opt_colors); $opt_colors = 8 if ( $opt_colors < 8 ); &startup_screen; &init_screensize; $mark = 0; $top_row = 4; $row_now = $row_1st = $top_row; $col_now = $col_1st = 1; &ed(2); &show_example; while (1) { my $cmd; &show_status; &cup( $row_now, $col_now ); $cmd = ReadKey 0; if ( $cmd eq "?" ) { &restore_screen; system( $0 . " -man" ); &startup_screen; &show_example; $cmd = ReadKey 0; } elsif ( $cmd eq " " ) { $mark = ( $mark != 0 ) ? 0 : 1; $row_1st = $row_now; $col_1st = $col_now; } elsif ( $cmd eq chr(12) ) { &show_example; } elsif ( $cmd eq "h" ) { $col_now-- if ( $col_now > 1 ); } elsif ( $cmd eq "j" ) { $row_now++ if ( $row_now < $row_max ); } elsif ( $cmd eq "k" ) { $row_now-- if ( $row_now > 1 ); } elsif ( $cmd eq "l" ) { $col_now++ if ( $col_now < $col_max ); } elsif ( $cmd eq "q" ) { &restore_screen; printf "\r\n...quit\r\n"; last; } elsif ( $cmd eq "=" ) { &cup( $row_now = $row_1st + $cur_sgr, $col_now = 24 ); } elsif ( $cmd eq "v" ) { &set_which_value("video-attributes (SGR)"); } elsif ( $cmd eq "f" ) { &set_which_value("foreground"); } elsif ( $cmd eq "b" ) { &set_which_value("background"); } elsif ( $cmd eq "d" ) { &toggle_default; } elsif ( $cmd eq "<" ) { &change_value(-1); } elsif ( $cmd eq ">" ) { &change_value(1); } elsif ( $opt_direct and ( $cmd eq "R" ) ) { &set_which_color("red"); } elsif ( $opt_direct and ( $cmd eq "G" ) ) { &set_which_color("green"); } elsif ( $opt_direct and ( $cmd eq "B" ) ) { &set_which_color("blue"); } else { &beep; } } 1; __END__ =head1 NAME report-sgr.pl - demonstrate xterm's report-SGR control sequence =head1 SYNOPSIS report-sgr.pl [options] Options: -help brief help message -8 use 8-bit controls -colors=NUM specify number of indexed colors -direct use direct-colors, rather than indexed =head1 OPTIONS =over 8 =item B<-help> Print a brief help message and exit. =item B<-man> Print the extended help message and exit. =item B<-colors> Specify the number of indexed colors. =item B<-direct> Use direct-colors (e.g., an RGB value), rather than indexed (e.g., ANSI colors). =back =head1 DESCRIPTION B displays a normal line, as well as one for each SGR code 1-9, with a test-string showing the effect of the SGR. Two SGR codes can be combined, as well as foreground and background colors. =head1 Commands =over 8 =item B Quit the program with B. It will ignore B<^C> and other control characters. =item B, B, B, B As you move the cursor around the screen (with vi-style h,j,k,l characters), the script sends an XTREPORTSGR control to the terminal, asking what the video attributes are for the currently selected cell. The script displays the result on the second line of the screen. =item B XTREPORTSGR returns an SGR control sequence which could be used to set the terminal's current video attributes to match the attributes found in all cells of the rectangle specified by this script. Use the spacebar to toggle the mark which denotes one corner of the rectangle. The current cursor position is the other corner. =item B<=> Move the cursor to the first cell of the test-data for the currently selected SGR code (the one with B<-->>). =item B Select the video-attribute mode. =item B Select the foreground-color mode. =item B Select the background-color mode. =item B When direct-colors are chosen, select the red-component of the currently selected foreground or background mode. =item B When direct-colors are chosen, select the green-component of the currently selected foreground or background mode. =item B When direct-colors are chosen, select the blue-component of the currently selected foreground or background mode. =item B Toggle between the selected colors and the terminal's default colors. =item B<<> Decrease the index of video-attribute to combine, or the color value depending on the selected mode. =item B<>> Increase the index of video-attribute to combine, or the color value depending on the selected mode. =item B<^L> Repaint the screen. =back =cut xterm-399/vttests/insdelln.pl0000755000000000000000000001621214321050342015115 0ustar rootroot#!/usr/bin/env perl # $XTermId: insdelln.pl,v 1.10 2022/10/10 17:05:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2009,2022 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Tests insert/delete-line feature in xterm. This applies only to the # visible screen (saved-lines are unaffected). # # TODO: # add option to wrap the test-pattern # use scrolling-margins to help fill-in a chunk use strict; use warnings; use Getopt::Std; # do this so output from successive calls to this script won't get in the # wrong order: use IO::Handle; STDERR->autoflush(1); STDOUT->autoflush(1); our ( $opt_c, $opt_n, $opt_r, $opt_w ); our ( $lineno, $test_string, $term_height, $term_width ); our @resize; sub read_resize($) { my $field = shift; my $result = shift; if ( $#resize < 0 ) { open( FP, "resize -u |" ) or exit $!; @resize = ; chomp @resize; close(FP); } for my $n ( 0 .. $#resize ) { if ( $resize[$n] =~ /^$field=/ ) { $result = $resize[$n]; $result =~ s/^[^=]*=//; $result =~ s/;.*//; last; } } return $result; } # returns the number of rows in the screen sub screen_height() { return &read_resize( "LINES", 24 ); } # returns the number of columns in the screen sub screen_width() { return &read_resize( "COLUMNS", 80 ); } sub set_color($) { my $code = $_[0]; if ( defined($opt_c) ) { if ( $code == 3 ) { printf "\x1b[1;33;42m"; # yellow-on-green } elsif ( $code == 2 ) { printf "\x1b[0;31;45m"; # red-on-magenta } elsif ( $code == 1 ) { printf "\x1b[0;36;44m"; # cyan-on-blue } else { printf "\x1b[0;39;49m"; } } } # returns a string of two-column characters given an ASCII alpha/numeric string sub double_cells($) { my $value = $_[0]; $value =~ s/ / /g; pack( "U*", map { ( $_ <= 32 || $_ > 127 ) # if non-ASCII character... ? 32 # ...just show a blank : ( 0xff00 + ( $_ - 32 ) ) # map to "Fullwidth Form" } unpack( "C*", $value ) ); # unpack unsigned-char characters } sub clear_screen() { upper_left(); printf "\x1b[J"; } sub clr_to_eol() { printf "\x1b[K"; } sub lower_left() { printf "\x1b[%dH", $term_height; } sub upper_left() { printf "\x1b[H"; } sub move_to($) { printf "\x1b[%dG", $_[0] + 1; } sub insert_lines($) { #lower_left; if ( $_[0] ) { printf "\x1b[%dL", $_[0]; } else { printf "\x1b[L"; } } sub delete_lines($) { if ( $_[0] ) { printf "\x1b[%dM", $_[0]; } else { printf "\x1b[M"; } } sub delete_char() { set_color(2); printf "\x1b[%dP", 1; set_color(1); } sub insert_once($) { my $text = shift; set_color(2); printf "\x1b[%d@", length($text); write_chars($text); } sub insert_mode($) { set_color(2); printf "\x1b[%dP", length( $_[0] ); printf "\x1b[4h"; write_chars( $_[0] ); printf "\x1b[4l"; } sub write_chars($) { set_color(3); printf "%s", $_[0]; set_color(1); } # vary the starting point of each line, to make a more interesting pattern sub starts_of($) { my $value = $_[0]; if ( defined($opt_w) ) { # 0,1,1,2,2,3,3,... $value = ( ( $value + 1 ) / 2 ) % length($test_string); } else { $value %= length($test_string); } return $value; } # write the text for the given line-number sub testit($) { my $number = $_[0]; my $length = $term_width; # use delete-lines to "pull" the screen up, like scrolling. select( undef, undef, undef, 0.1 ); if ( ( ( $number / $term_height ) % 2 ) != 0 ) { upper_left; insert_lines(1); } else { upper_left; delete_lines(1); lower_left; } if ( defined($opt_n) ) { printf "%5d ", $number % 99999; $length -= 6; } # if we're printing double-column characters, we have half as much # space effectively - but don't forget the remainder, so we can push # the characters by single-columns. if ( defined($opt_c) ) { set_color(1); clr_to_eol(); } my $starts = starts_of($number); if ( defined($opt_w) ) { printf " ", if ( ( $number % 2 ) != 0 ); $length = ( $length - ( ($number) % 2 ) ) / 2; } my $string = substr( $test_string, $starts ); while ( length($string) < $length ) { $string = $string . $test_string; } $string = substr( $string, 0, $length ); if ( defined($opt_w) ) { $string = double_cells($string); } printf "%s", $string; # now - within the line - modify it move_to( ( 4 * $term_width ) / 5 ); insert_mode("XX"); move_to( ( 3 * $term_width ) / 5 ); delete_char(); move_to( ( 2 * $term_width ) / 5 ); insert_once('~'); move_to( ( 1 * $term_width ) / 5 ); write_chars('~'); move_to(0); set_color(0); } sub main::HELP_MESSAGE() { printf STDERR < 3 ) ? $code : ( $code + 1 ); } return $result; } # Combine the modifier state as bits: # shift key -> 1 # meta key -> 2 (Mod1 came from X11R1, but was adapted from X10) # control key -> 4 our $maxstates = 7; sub KeyState($) { my $mask = shift; my $result = ""; $result .= " + shift" if ( ( $mask & 1 ) != 0 ); $result .= " + meta" if ( ( $mask & 2 ) != 0 ); $result .= " + control" if ( ( $mask & 4 ) != 0 ); return $result; } sub Motion($) { my $code = shift; my $result = ""; $result = " + motion" if ( $code != 0 ); return $result; } sub report() { my $button; my $states; my $motion; my %encoded; my %reports; for $states ( 0 .. $maxstates ) { for $motion ( 0 .. 1 ) { for $button ( -1 .. $maxbutton ) { next if ( $button == 3 ); my $result = ( 32 + ( $states << 2 ) ); $result += 32 if ( $motion != 0 ); if ( $button < 0 ) { $result += 3; } else { $result += $button & 3; if ( $button & 4 ) { $result += 64; } if ( $button & 8 ) { $result += 128; } } my $code = sprintf "%3d", $result; my $report = sprintf "%s%s%s", &ButtonName($button), &KeyState($states), &Motion($motion); if ( defined $encoded{$code} ) { printf "OOPS %s ->%s versus %s\n", $code, $report, $encoded{$code}; } elsif ( $result > 255 and not defined $opt_x ) { printf "OOPS %s ->%s\n", $code, $report; } $encoded{$code} = $report; $reports{$report} = $result; } } } if ($opt_i) { foreach my $report ( sort keys %reports ) { printf "%s = %s\n", $report, $reports{$report}; } } else { foreach my $code ( sort keys %encoded ) { printf "%s = %s\n", $code, $encoded{$code}; } } } sub main::HELP_MESSAGE() { printf STDERR <autoflush(1); STDOUT->autoflush(1); our ( $opt_8, $opt_c, $opt_l, $opt_o, $opt_r, $opt_s, $opt_w, $opt_x ); our ( $margins, $test_state, $test_string, $test_width ); our ( $term_height, $term_width ); our $CSI = "\033["; our @resize; sub read_resize($) { my $field = shift; my $result = shift; if ( $#resize < 0 ) { open( FP, "resize -u |" ) or exit $!; @resize = ; chomp @resize; close(FP); } for my $n ( 0 .. $#resize ) { if ( $resize[$n] =~ /^$field=/ ) { $result = $resize[$n]; $result =~ s/^[^=]*=//; $result =~ s/;.*//; last; } } return $result; } # returns the number of rows in the screen sub screen_height() { return &read_resize( "LINES", 24 ); } # returns the number of columns in the screen sub screen_width() { return &read_resize( "COLUMNS", 80 ); } sub set_color($) { my $code = shift; if ( defined($opt_c) ) { if ( $code == 3 ) { printf "%s1;33;42m", $CSI; # yellow-on-green } elsif ( $code == 2 ) { printf "%s0;31;45m", $CSI; # red-on-magenta } elsif ( $code == 1 ) { printf "%s0;36;44m", $CSI; # cyan-on-blue } else { printf "%s0;39;49m", $CSI; } } } # returns a string of two-column characters given an ASCII alpha/numeric string sub double_cells($) { my $value = $_[0]; $value =~ s/ / /g; pack( "U*", map { ( $_ <= 32 || $_ > 127 ) # if non-ASCII character... ? 32 # ...just show a blank : ( 0xff00 + ( $_ - 32 ) ) # map to "Fullwidth Form" } unpack( "C*", $value ) ); # unpack unsigned-char characters } sub clear_screen() { &upper_left; printf "%sJ", $CSI; } sub clr_to_eol() { printf "%sK", $CSI; } sub lower_left() { printf "%s%dH", $CSI, $term_height; } sub upper_left() { printf "%sH", $CSI; } sub move_to($) { my $value = shift; $value += ( $opt_l - 1 ) if ( $margins and not $opt_o ); printf "%s%dG", $CSI, $value + 1; } sub bak_scroll($) { my $value = shift; if ($value) { printf "%s%dS", $CSI, $value; } else { printf "%sS", $CSI; } } sub delete_char() { &set_color(2); printf "%s%dP", $CSI, 1; &set_color(1); } sub insert_once($) { my $value = shift; &set_color(2); printf "%s%d@", $CSI, length($value); &write_chars($value); } sub insert_mode($) { my $value = shift; &set_color(2); printf "%s%dP", $CSI, length($value); printf "%s4h", $CSI; &write_chars($value); printf "%s4l", $CSI; } sub write_chars($) { &set_color(3); printf "%s", $_[0]; &set_color(1); } # vary the starting point of each line, to make a more interesting pattern sub starts_of($) { my $value = shift; if ( defined($opt_w) ) { # 0,1,1,2,2,3,3,... $value = ( ( $value + 1 ) / 2 ) % length($test_string); } else { $value %= length($test_string); } return $value; } # write the text for the given line-number sub show_line($) { my $number = shift; my $length = $test_width; # use delete-lines to "pull" the screen up, like scrolling. select( undef, undef, undef, 0.05 ) if ($opt_s); &lower_left; &bak_scroll(1); # if we're printing double-column characters, we have half as much # space effectively - but don't forget the remainder, so we can push # the characters by single-columns. if ( defined($opt_c) ) { &set_color(1); printf "%s%dX", $CSI, $length if ($margins); &clr_to_eol unless ($margins); } my $starts = &starts_of($number); if ( defined($opt_w) ) { printf " ", if ( ( $number % 2 ) != 0 ); $length = ( $length - ( ($number) % 2 ) ) / 2; } my $string = substr( $test_string, $starts ); while ( length($string) < $length ) { $string = $string . $test_string; } $string = substr( $string, 0, $length ); if ( defined($opt_w) ) { $string = &double_cells($string); } printf "%s", $string; # now - within the line - modify it if ($opt_x) { &move_to( ( 4 * $test_width ) / 5 ); &insert_mode("XX"); &move_to( ( 3 * $test_width ) / 5 ); &delete_char; &move_to( ( 2 * $test_width ) / 5 ); &insert_once('~'); &move_to( ( 1 * $test_width ) / 5 ); &write_chars('~'); &move_to(0); } &set_color(0); } sub show_pattern() { &set_color(0); &clear_screen; for ( my $lineno = 0 ; $lineno < $term_height ; ++$lineno ) { &show_line($lineno); } } sub scroll_left($) { my $value = shift; printf "%s%d @", $CSI, $value; } sub scroll_right($) { my $value = shift; printf "%s%d A", $CSI, $value; } sub show_help() { &finish_test; &clear_screen; printf < $margins{L} ); } else { $value = $value % $term_wide; } return $value; } sub next_y($) { my $value = shift; if ($mode_origin) { $value = $margins{B} if ( $value < $margins{T} ); $value = $margins{T} if ( $value > $margins{B} ); } else { $value = $value % $term_high; } return $value; } sub move() { my $y = $pos_y; if ($mode_origin) { my $min_y = ( $margins{T} >= 0 ) ? $margins{T} : 0; my $two_y = $min_y + 1; # scrolling region is at least 2 lines my $max_y = ( $margins{B} >= $two_y ) ? $margins{B} : $two_y; $y = $max_y if ( $y > $max_y ); $y -= $min_y; # convert to relative ordinate } $y = 0 if ( $y < 0 ); printf STDERR "%s%d;%dH", $CSI, 1 + $y, 1 + $pos_x; } sub home() { printf STDERR "%sH", $CSI; $pos_x = 0; $pos_y = 0; &move; } sub erase_display($) { my $mode = shift; printf STDERR "%s%sJ", $CSI, $mode; } sub erase_line($) { my $mode = shift; printf STDERR "%s%sK", $CSI, $mode; } sub toggle($) { my $value = shift; return ( $value == 0 ) ? 1 : 0; } ################################################################################ sub set_margin_mode($) { my $mode = shift; printf STDERR "%s?69%s", $CSI, ( $mode == 0 ) ? "l" : "h"; $mode_margin = $mode; } ################################################################################ sub set_origin_mode($) { my $mode = shift; printf STDERR "%s?6%s", $CSI, ( $mode == 0 ) ? "l" : "h"; $mode_origin = $mode; } ################################################################################ sub set_screen_mode($) { my $mode = shift; printf STDERR "%s?1049%s", $CSI, ( $mode == 0 ) ? "l" : "h"; $mode_screen = $mode; } ################################################################################ sub do_tb_margins($$) { my $param_T = ""; my $param_B = ""; $param_T = sprintf( "%d", 1 + $margins{T} ) if ( $margins{T} >= 0 ); $param_B = sprintf( "%d", 1 + $margins{B} ) if ( $margins{B} > $margins{T} ); printf STDERR "%s%s;%sr", $CSI, $param_T, $param_B; &move; } sub undo_tb_margins() { &do_tb_margins( -1, -1 ); } sub redo_tb_margins() { &do_tb_margins( $margins{T}, $margins{B} ); } sub set_tb_margins($$) { my $reset = ( not defined $margins{T} or not defined $margins{B} ) ? 1 : 0; my $old_T = 1; my $old_B = $term_high; $old_T = $margins{T} if ( defined $margins{T} ); $old_B = $margins{B} if ( defined $margins{B} ); $margins{T} = shift; $margins{B} = shift; if ( $reset == 0 ) { $reset = 1 if ( $old_T != $margins{T} ); $reset = 1 if ( $old_B != $margins{B} ); } &redo_tb_margins if ( $reset == 1 ); } ################################################################################ sub do_lr_margins($$) { my $param_L = ""; my $param_R = ""; $param_L = sprintf( "%d", 1 + $margins{L} ) if ( $margins{L} >= 0 ); $param_R = sprintf( "%d", 1 + $margins{R} ) if ( $margins{R} > $margins{T} ); printf STDERR "%s%s;%ss", $CSI, $param_L, $param_R; &move; } sub undo_lr_margins() { &do_lr_margins( -1, -1 ); } sub redo_lr_margins() { &do_lr_margins( $margins{L}, $margins{R} ); } sub set_lr_margins($$) { my $reset = ( not defined $margins{L} or not defined $margins{R} ) ? 1 : 0; my $old_L = 1; my $old_R = $term_high; $old_L = $margins{L} if ( defined $margins{L} ); $old_R = $margins{R} if ( defined $margins{R} ); $margins{L} = shift; $margins{R} = shift; if ( $reset == 0 ) { $reset = 1 if ( $old_L != $margins{L} ); $reset = 1 if ( $old_R != $margins{R} ); } &redo_lr_margins if ( $reset == 1 ); } ################################################################################ sub has_tb_margins() { my $result = 0; $result = 1 if ( $margins{T} != 1 ); $result = 1 if ( $margins{B} != $term_high ); return $result; } sub repaint($) { my $erase = shift; my $save_x = $pos_x; my $save_y = $pos_y; $dirty = 0; if ($erase) { &home; &erase_display(2); } if ( $text_filler ne "" ) { if ( $mode_origin and &has_tb_margins ) { my @rows = split /$crlf/, $text_filler; for my $row ( 0 .. $#rows ) { next unless ( $row >= $margins{T} ); next unless ( $row <= $margins{B} ); printf STDERR "%s$crlf", $rows[$row]; } } else { printf STDERR "%s$crlf", $text_filler; } } else { my $cells = 0; my $limit = $term_high * $term_wide; while ( $cells < $limit ) { my $sample = ( $encoding eq "utf-8" ) ? &utf8_sample : $text_sample; printf STDERR "%s", $sample; $cells += length($sample); } } $pos_x = $save_x; $pos_y = $save_y; &move; } sub initialize() { if ( $encoding eq "utf-8" ) { binmode( STDOUT, ":utf8" ); binmode( STDERR, ":utf8" ); } if ($opt_8) { if ( $encoding eq "utf-8" ) { undef $opt_8; printf "...ignoring -8 option since locale uses %s\n", $encoding; } else { printf STDERR "\x1b G"; $CSI = "\x9b"; } } &raw; my @term_size = GetTerminalSize( \*STDERR ); $term_wide = 80; $term_wide = $term_size[0] if ( $#term_size >= 0 ); $term_wide = 80 if ( $term_wide <= 0 ); $term_high = 24; $term_high = $term_size[1] if ( $#term_size >= 1 ); $term_high = 24 if ( $term_high <= 0 ); &set_margin_mode(0); &set_origin_mode(0); &set_screen_mode(0); &set_tb_margins( -1, -1 ); &set_lr_margins( 1, $term_wide ); &home; &erase_display("2"); } sub cleanup() { &cooked; printf STDERR "\x1b F" if ($opt_8); &set_margin_mode(0); &set_origin_mode(0); &set_screen_mode(0); &undo_tb_margins; $pos_x = 1; $pos_y = $term_high - 2; &move; &erase_display(""); } sub beep() { printf STDERR "\a"; } sub main::HELP_MESSAGE() { printf STDERR <; chomp @lines; close FP; $text_filler = join( $crlf, @lines ); } } printf "encoding $encoding\n"; &initialize(); while (1) { my $cmd; printf "\r\nCommand (? for help):" if ( $dirty != 0 ); $cmd = ReadKey 0; if ( not $cmd ) { sleep 1; } elsif ( $cmd eq "?" ) { $dirty = 1; &home; &erase_display(2); printf $crlf . "General:" . $crlf . " ? (help)," . " q (quit)" . $crlf . "Clear:" . $crlf . " C (entire screen)," . " c (screen-below)," . " E (entire line)," . " e (line-right)" . $crlf . "Fill:" . $crlf . " @ (margin-box)," . " # (prompt-char)" . $crlf . "Move cursor:\r\n" . " h,j,k,l (vi-like)," . " H (to home)." . $crlf . "Set margin using current position:" . $crlf . " T (top)," . " B (bottom)," . " L (left)," . " R (right)" . $crlf . "Reset modes" . $crlf . " M (margins)" . $crlf . "Toggle modes" . $crlf . " A (alternate-screen)," . " O (origin-mode)" . " | (left/right-mode)" . $crlf . "Print sample:" . " form-feed (repaint)"; } elsif ( $cmd eq "\033" ) { # try to ignore special-keys my $count = 0; while (1) { $cmd = ReadKey 0; $count++; next if ( $count == 1 and $cmd eq "O" ); next unless ( $cmd =~ /^[A-~]$/ ); $cmd = ReadKey 0; last; } } elsif ( $cmd eq "q" ) { last; } elsif ( index( "CcEe@#hjklHMTBLRAO|\f", $cmd ) >= 0 ) { my $was_dirty = $dirty; &repaint(1) if ( $dirty != 0 ); if ( $cmd eq "C" ) { &home; &erase_display("2"); } elsif ( $cmd eq "c" ) { &erase_display(""); } elsif ( $cmd eq "E" ) { &erase_line("2"); } elsif ( $cmd eq "e" ) { &erase_line(""); } elsif ( $cmd eq "@" ) { # FIXME } elsif ( $cmd eq "#" ) { $text_sample = ReadKey 0; if ( $text_filler ne "" ) { my $save_filler = $text_filler; $text_filler =~ s/[^\d\s]/$text_sample/g; &repaint(0); $text_filler = $save_filler; } else { &repaint(0); } } elsif ( $cmd eq "h" ) { $pos_x = &next_x( $pos_x - 1 ); &move; } elsif ( $cmd eq "j" ) { $pos_y = &next_y( $pos_y + 1 ); &move; } elsif ( $cmd eq "k" ) { $pos_y = &next_y( $pos_y - 1 ); &move; } elsif ( $cmd eq "l" ) { $pos_x = &next_x( $pos_x + 1 ); &move; } elsif ( $cmd eq "H" ) { &home; } elsif ( $cmd eq "M" ) { &set_tb_margins( -1, -1 ); &set_lr_margins( -1, -1 ); &repaint(0); } elsif ( $cmd eq "T" ) { &set_tb_margins( $pos_y, $margins{B} ); } elsif ( $cmd eq "B" ) { &set_tb_margins( $margins{T}, $pos_y ); } elsif ( $cmd eq "L" ) { &set_lr_margins( $pos_x, $margins{R} ); } elsif ( $cmd eq "R" ) { &set_lr_margins( $margins{L}, $pos_x ); } elsif ( $cmd eq "A" ) { &set_screen_mode( &toggle($mode_screen) ); &repaint(1); } elsif ( $cmd eq "O" ) { &set_origin_mode( &toggle($mode_origin) ); } elsif ( $cmd eq "|" ) { &set_margin_mode( &toggle($mode_margin) ); } elsif ( $cmd eq "\f" ) { &repaint(1) unless ($was_dirty); } else { &beep; $dirty = 2; } } else { &beep; } } &cleanup; printf " ...quit\r\n"; 1; xterm-399/vttests/resize.sh0000755000000000000000000000625614231454632014626 0ustar rootroot#!/bin/sh # $XTermId: resize.sh,v 1.25 2022/04/25 08:19:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 1999-2021,2022 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Obtain the current screen size, then resize the terminal to the nominal # screen width/height, and restore the size. ESC="" CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' : "${TMPDIR=/tmp}" TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null { test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null if test -f "$TMP" ; then if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' break fi fi done rm -f "$TMP" exec /dev/tty IFS=';' read -r junk high wide $CMD $OPT "${CSI}19t${SUF}" > /dev/tty IFS=';' read -r junk maxhigh maxwide stty $old wide=`echo "$wide"|sed -e 's/t.*//'` maxwide=`echo "$maxwide"|sed -e 's/t.*//'` original=${CSI}8\;${high}\;${wide}t${SUF} test "$maxwide" = 0 && maxwide=`expr "$wide" \* 2` test "$maxhigh" = 0 && maxhigh=`expr "$high" \* 2` trap '$CMD $OPT "$original" >/dev/tty; exit 1' 1 2 3 15 trap '$CMD $OPT "$original" >/dev/tty' 0 w=$wide h=$high a=1 while true do # sleep 1 echo "resizing to $h by $w" $CMD $OPT "${CSI}8;${h};${w}t" >/dev/tty if test $a = 1 ; then if test "$w" = "$maxwide" ; then h=`expr "$h" + "$a"` if test "$h" = "$maxhigh" ; then a=-1 fi else w=`expr "$w" + "$a"` fi else if test "$w" = "$wide" ; then h=`expr "$h" + "$a"` if test "$h" = "$high" ; then a=1 fi else w=`expr "$w" + "$a"` fi fi done xterm-399/vttests/scroll.pl0000755000000000000000000001622314321050076014611 0ustar rootroot#!/usr/bin/env perl # $XTermId: scroll.pl,v 1.4 2022/10/10 17:02:54 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2009,2022 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Tests insert/delete-line feature in xterm. This applies only to the # visible screen (saved-lines are unaffected). # # TODO: # add option to wrap the test-pattern # use scrolling-margins to help fill-in a chunk use strict; use warnings; use Getopt::Std; # do this so output from successive calls to this script won't get in the # wrong order: use IO::Handle; STDERR->autoflush(1); STDOUT->autoflush(1); our ( $opt_c, $opt_n, $opt_r, $opt_w ); our ( $lineno, $test_string, $term_height, $term_width, $max_scroll ); our @resize; sub read_resize($) { my $field = shift; my $result = shift; if ( $#resize < 0 ) { open( FP, "resize -u |" ) or exit $!; @resize = ; chomp @resize; close(FP); } for my $n ( 0 .. $#resize ) { if ( $resize[$n] =~ /^$field=/ ) { $result = $resize[$n]; $result =~ s/^[^=]*=//; $result =~ s/;.*//; last; } } return $result; } # returns the number of rows in the screen sub screen_height() { return &read_resize( "LINES", 24 ); } # returns the number of columns in the screen sub screen_width() { return &read_resize( "COLUMNS", 80 ); } sub set_color($) { my $code = $_[0]; if ( defined($opt_c) ) { if ( $code == 3 ) { printf "\x1b[1;33;42m"; # yellow-on-green } elsif ( $code == 2 ) { printf "\x1b[0;31;45m"; # red-on-magenta } elsif ( $code == 1 ) { printf "\x1b[0;36;44m"; # cyan-on-blue } else { printf "\x1b[0;39;49m"; } } } # returns a string of two-column characters given an ASCII alpha/numeric string sub double_cells($) { my $value = $_[0]; $value =~ s/ / /g; pack( "U*", map { ( $_ <= 32 || $_ > 127 ) # if non-ASCII character... ? 32 # ...just show a blank : ( 0xff00 + ( $_ - 32 ) ) # map to "Fullwidth Form" } unpack( "C*", $value ) ); # unpack unsigned-char characters } sub clear_screen() { upper_left(); printf "\x1b[J"; } sub clr_to_eol() { printf "\x1b[K"; } sub lower_left() { printf "\x1b[%dH", $term_height; } sub upper_left() { printf "\x1b[H"; } sub move_to($) { printf "\x1b[%dG", $_[0] + 1; } sub bak_scroll($) { #lower_left; if ( $_[0] ) { printf "\x1b[%dS", $_[0]; } else { printf "\x1b[S"; } } sub fwd_scroll($) { if ( $_[0] ) { printf "\x1b[%dT", $_[0]; } else { printf "\x1b[T"; } } sub delete_char() { set_color(2); printf "\x1b[%dP", 1; set_color(1); } sub insert_once($) { my $data = shift; set_color(2); printf "\x1b[%d@%s", length($data), $data; write_chars($data); } sub insert_mode($) { set_color(2); printf "\x1b[%dP", length( $_[0] ); printf "\x1b[4h"; write_chars( $_[0] ); printf "\x1b[4l"; } sub write_chars($) { set_color(3); printf "%s", $_[0]; set_color(1); } # vary the starting point of each line, to make a more interesting pattern sub starts_of($) { my $value = $_[0]; if ( defined($opt_w) ) { # 0,1,1,2,2,3,3,... $value = ( ( $value + 1 ) / 2 ) % length($test_string); } else { $value %= length($test_string); } return $value; } # write the text for the given line-number sub testit($) { my $number = $_[0]; my $length = $term_width; # use delete-lines to "pull" the screen up, like scrolling. select( undef, undef, undef, 0.1 ); if ( ( ( $number / $max_scroll ) % 2 ) != 0 ) { lower_left; fwd_scroll(1); } else { lower_left; bak_scroll(1); } if ( defined($opt_n) ) { printf "%5d ", $number % 99999; $length -= 6; } # if we're printing double-column characters, we have half as much # space effectively - but don't forget the remainder, so we can push # the characters by single-columns. if ( defined($opt_c) ) { set_color(1); clr_to_eol(); } my $starts = starts_of($number); if ( defined($opt_w) ) { printf " ", if ( ( $number % 2 ) != 0 ); $length = ( $length - ( ($number) % 2 ) ) / 2; } my $string = substr( $test_string, $starts ); while ( length($string) < $length ) { $string = $string . $test_string; } $string = substr( $string, 0, $length ); if ( defined($opt_w) ) { $string = double_cells($string); } printf "%s", $string; # now - within the line - modify it move_to( ( 4 * $term_width ) / 5 ); insert_mode("XX"); move_to( ( 3 * $term_width ) / 5 ); delete_char(); move_to( ( 2 * $term_width ) / 5 ); insert_once('~'); move_to( ( 1 * $term_width ) / 5 ); write_chars('~'); move_to(0); set_color(0); } sub main::HELP_MESSAGE() { printf STDERR < 127) # if non-ASCII character... ? 32 # ...just show a blank : (0xff00 + ($_ - 32)) # map to "Fullwidth Form" } unpack("C*", $value)); # unpack unsigned-char characters } sub erase_left() { set_color(2); printf "\x1b[1K"; set_color(1); } sub erase_right() { set_color(2); printf "\x1b[0K"; set_color(1); } sub erase_middle($) { set_color(3); printf "\x1b[%dX", $_[0]; set_color(1); } sub move_to($) { printf "\x1b[%dG", $_[0] + 1; } # write the text for the given line-number sub testit($) { my $number = $_[0]; my $length = $term_width; my $actual; my $margin = 0; if ( defined($opt_n) ) { $margin = 6; move_to($margin); $length -= $margin; } $actual = $length; if (defined($opt_c)) { set_color(1); erase_right(); } if ( defined($opt_w) ) { $length /= 2; } my $string = $test_string; while ( length($string) < $length ) { $string = $string . $test_string; } $string = substr($string, 0, $length); if ( defined($opt_w) ) { $string = double_cells($string); } printf "%s", $string; move_to($margin + ($number % ($actual / 3))); erase_left(); move_to($margin + ((2 * $actual) / 3) + ($number % ($actual / 3))); erase_right(); move_to($margin + ((1 * $actual) / 3) + ($number % ($actual / 3))); erase_middle($actual / 10); set_color(0); if ( defined($opt_n) ) { move_to(0); printf "%5d ", $number % 99999; } printf "\n"; } sub main::HELP_MESSAGE() { printf STDERR </dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null { test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null if test -f "$TMP" ; then if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' break fi fi done rm -f "$TMP" trap '$CMD $OPT "${CSI}0m"; exit 1' 1 2 3 15 trap '$CMD $OPT "${CSI}0m"' 0 echo "${CSI}0m" while true do for AT in 0 1 4 7 do case $AT in 0) attr="normal ";; 1) attr="bold ";; 4) attr="under ";; 7) attr="reverse ";; esac for FG in 0 1 2 3 4 5 6 7 do case $FG in 0) fcolor="black ";; 1) fcolor="red ";; 2) fcolor="green ";; 3) fcolor="yellow ";; 4) fcolor="blue ";; 5) fcolor="magenta ";; 6) fcolor="cyan ";; 7) fcolor="white ";; esac $CMD $OPT "${CSI}0;${AT}m$attr${SUF}" $CMD $OPT "${CSI}3${FG}m$fcolor${SUF}" for BG in 1 2 3 4 5 6 7 do case $BG in 0) bcolor="black ";; 1) bcolor="red ";; 2) bcolor="green ";; 3) bcolor="yellow ";; 4) bcolor="blue ";; 5) bcolor="magenta ";; 6) bcolor="cyan ";; 7) bcolor="white ";; esac $CMD $OPT "${CSI}4${BG}m$bcolor${SUF}" done echo "${CSI}0m" done sleep 1 done done xterm-399/vttests/utf8.pl0000755000000000000000000000715514262074113014207 0ustar rootroot#!/usr/bin/env perl # $XTermId: utf8.pl,v 1.12 2022/07/08 18:32:43 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2012-2018,2022 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # display the given Unicode characters, given their hex or decimal values. use warnings FATAL => "overflow"; no warnings "portable"; use strict; use Encode 'encode_utf8'; use Text::CharWidth qw(mbswidth); $| = 1; sub num_bytes($) { my $char = shift; my $value = length( Encode::encode_utf8($char) ); my $result = ( $value <= 0 ? "no bytes" : ( $value > 1 ? sprintf( "%d bytes", $value ) : "1 bytes" ) ); return $result; } sub num_cells($) { my $char = shift; my $value = mbswidth($char); my $result = ( $value <= 0 ? "no cells" : ( $value > 1 ? sprintf( "%d cells", $value ) : "1 cell" ) ); return $result; } sub pad_column($) { my $char = shift; my $value = mbswidth($char); $value = 0 if ( $value < 0); my $result = sprintf( "%.*s", 3 - $value, " "); return $result; } sub vxt_utf8($) { my $arg = $_[0]; my $hex = $arg; my $dec = $arg; if ( $arg =~ /^u\+[[:xdigit:]]+$/i ) { $hex =~ s/^../0x/; $dec = hex($hex); } elsif ( $arg =~ /^0x[[:xdigit:]]+$/i ) { $dec = hex($hex); } elsif ( $arg =~ /^[[:xdigit:]]+$/i ) { $dec = hex($hex); } else { printf STDERR "? not a codepoint: $dec\n"; return; } my $chr = chr($dec); my $type = ( $chr =~ /\p{isPrint}/ ? ( $chr =~ /\p{isAlpha}/ ? "alpha" : ( $chr =~ /\p{isPunct}/ ? "punct" : ( $chr =~ /\p{isDigit}/ ? "digit" : "printing" ) ) ) : ( $chr =~ /\p{isCntrl}/ ? "cntrl" : "nonprinting" ) ); printf "%d ->%#x ->{%s}%s(%s %s %s)\n", $dec, $dec, $chr, &pad_column($chr), &num_bytes($chr), &num_cells($chr), $type; } binmode( STDOUT, ":utf8" ); while ( $#ARGV >= 0 ) { vxt_utf8( shift @ARGV ); } 1; xterm-399/vttests/query-xres.pl0000755000000000000000000001427013546477442015461 0ustar rootroot#!/usr/bin/env perl # $XTermId: query-xres.pl,v 1.6 2019/10/06 23:56:18 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2019 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Report features enabled/disabled via resource-settings # TODO: handle 8-bit controls use strict; use warnings; use Getopt::Std; use IO::Handle; our ( $opt_a, $opt_d, $opt_e, $opt_m, $opt_q ); our @query_params; our @query_result; $Getopt::Std::STANDARD_HELP_VERSION = 1; &getopts('acdemq') || die( "Usage: $0 [options]\n Options:\n -a (same as -d -e -m) -d query disabled/disallowed features -e query enabled/allowed features -m query modified keys -q quicker results by merging queries " ); if ( $#ARGV < 0 and not( defined($opt_d) or defined($opt_e) or defined($opt_m) ) ) { $opt_a = 1; } sub get_reply($) { open TTY, "+; close TTY; system "stty $old"; if ( defined $reply ) { die("^C received\n") if ( "$reply" eq "\003" ); } return $reply; } sub hexified($) { my $value = $_[0]; my $result = ""; my $n; for ( $n = 0 ; $n < length($value) ; ++$n ) { $result .= sprintf( "%02X", ord substr( $value, $n, 1 ) ); } return $result; } sub begin_query() { @query_params = (); } sub add_param($) { $query_params[ $#query_params + 1 ] = &hexified( $_[0] ); } sub finish_query() { my $reply = &get_reply( "\x1bP+Q" . join( ';', @query_params ) . "\x1b\\" ); return unless defined $reply; while ( $reply =~ /\x1bP1\+R[[:xdigit:]]+[=;][[:xdigit:]]*.*\x1b\\/ ) { my $n; my $parse; $reply =~ s/^\x1bP1\+R//; $parse = $reply; $reply =~ s/\x1b\\.*$//; $parse = substr( $parse, length($reply) ); $parse =~ s/^\x1b\\//; my $result = ""; my $count = 0; my $state = 0; my $error = "?"; for ( $n = 0 ; $n < length($reply) ; ) { my $c = substr( $reply, $n, 1 ); if ( $c eq ';' ) { $n += 1; printf "%d%s\t%s\n", $count, $error, $result if ( $result ne "" ); $result = ""; $state = 0; $error = "?"; $count++; } elsif ( $c eq '=' ) { $error = "" if ( $count <= $#query_params and &hexified($result) eq $query_params[$count] ); $n += 1; $result .= $c; $state = 1; } elsif ( $c =~ /[[:punct:]]/ ) { $n += 1; $result .= $c; } else { my $k = hex substr( $reply, $n, 2 ); if ( $k == 0x1b ) { $result .= "\\E"; } elsif ( $k == 0x7f ) { $result .= "^?"; } elsif ( $k == 32 ) { $result .= "\\s"; } elsif ( $k < 32 ) { $result .= sprintf( "^%c", $k + 64 ); } elsif ( $k > 128 ) { $result .= sprintf( "\\%03o", $k ); } else { $result .= chr($k); } $n += 2; } } printf "%d%s\t%s\n", $count, $error, $result if ( $result ne "" ); $reply = $parse; } } sub do_query($) { my $name = shift; &begin_query unless ($opt_q); &add_param($name); &finish_query unless ($opt_q); } &begin_query if ($opt_q); while ( $#ARGV >= 0 ) { &do_query( shift @ARGV ); } if ( defined($opt_a) || defined($opt_d) ) { &do_query("disallowedColorOps"); &do_query("disallowedFontOps"); &do_query("disallowedMouseOps"); &do_query("disallowedPasteControls"); &do_query("disallowedTcapOps"); &do_query("disallowedWindowOps"); } if ( defined($opt_a) ) { &do_query("allowSendEvents"); &do_query("allowPasteControls"); &do_query("allowC1Printable"); &do_query("saveLines"); } if ( defined($opt_a) || defined($opt_e) ) { &do_query("allowColorOps"); &do_query("allowFontOps"); &do_query("allowMouseOps"); &do_query("allowPasteControls"); &do_query("allowTcapOps"); &do_query("allowTitleOps"); &do_query("allowWindowOps"); } if ( defined($opt_a) || defined($opt_m) ) { &do_query("formatOtherKeys"); &do_query("modifyCursorKeys"); &do_query("modifyFunctionKeys"); &do_query("modifyKeyboard"); &do_query("modifyOtherKeys"); } &finish_query if ($opt_q); 1; xterm-399/vttests/unascii.sh0000755000000000000000000000365514231452227014756 0ustar rootroot#!/bin/bash # $XTermId: unascii.sh,v 1.4 2022/04/25 07:58:15 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2013,2022 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # display the characters recognized by xterm in AsciiEquivs PATH="$(dirname "$(readlink -f "$0")"):$PATH" export PATH utf8.pl 0x2010 utf8.pl 0x2011 utf8.pl 0x2012 utf8.pl 0x2013 utf8.pl 0x2014 utf8.pl 0x2015 utf8.pl 0x2212 utf8.pl 0x2018 utf8.pl 0x2019 utf8.pl 0x201C utf8.pl 0x201D utf8.pl 0x2329 utf8.pl 0x232a xterm-399/vttests/16colors.sh0000755000000000000000000000660514231357364014777 0ustar rootroot#!/bin/sh # $XTermId: 16colors.sh,v 1.22 2022/04/24 23:36:20 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 1999-2021,2022 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Show a simple 16-color test pattern. It is a little more confusing than # 8colors.sh, since everything is abbreviated to fit on an 80-column line. # The high (8-15) combinations for foreground or background are marked with # a '+' sign. ESC="" CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' : "${TMPDIR=/tmp}" TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null { test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null if test -f "$TMP" ; then if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' break fi fi done rm -f "$TMP" trap '$CMD "${CSI}0m"; exit 1' 1 2 3 15 trap '$CMD "${CSI}0m"' 0 echo "${CSI}0m" while true do for AT in 0 1 4 7 do case $AT in 0) attr=" ";; 1) attr="BO ";; 4) attr="UN ";; 7) attr="RV ";; esac for FG in 0 1 2 3 4 5 6 7 do case $FG in 0) fcolor="BLK ";; 1) fcolor="RED ";; 2) fcolor="GRN ";; 3) fcolor="YEL ";; 4) fcolor="BLU ";; 5) fcolor="MAG ";; 6) fcolor="CYN ";; 7) fcolor="WHT ";; esac for HI in 3 9 do if test $HI = 3 ; then color=" $fcolor" else color="+$fcolor" fi $CMD $OPT "${CSI}0;${AT}m$attr$SUF" $CMD $OPT "${CSI}${HI}${FG}m$color$SUF" for BG in 1 2 3 4 5 6 7 do case $BG in 0) bcolor="BLK ";; 1) bcolor="RED ";; 2) bcolor="GRN ";; 3) bcolor="YEL ";; 4) bcolor="BLU ";; 5) bcolor="MAG ";; 6) bcolor="CYN ";; 7) bcolor="WHT ";; esac $CMD $OPT "${CSI}4${BG}m$bcolor$SUF" $CMD $OPT "${CSI}10${BG}m+$bcolor$SUF" done echo "${CSI}0m" done done sleep 1 done done xterm-399/vttests/88colors2.pl0000755000000000000000000001521514321131516015055 0ustar rootroot#!/usr/bin/env perl # $XTermId: 88colors2.pl,v 1.22 2022/10/11 00:05:34 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 1999-2021,2022 by Thomas E. Dickey # Copyright 1999 by Steve Wall # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # # Adapted from 256colors2.pl # If -s is not given, use the resources for colors 0-15 - usually more-or-less # a reproduction of the standard ANSI colors, but possibly more pleasing # shades. use strict; use warnings; use Getopt::Std; use Encode 'encode_utf8'; our ( $opt_8, $opt_c, $opt_C, $opt_d, $opt_h, $opt_q, $opt_r, $opt_s, $opt_u ); $Getopt::Std::STANDARD_HELP_VERSION = 1; &getopts('8cCdhqrsu') || die("Usage: $0 [options]"); die( "Usage: $0 [options]\n Options: -8 use 8-bit controls -c use colons for separating parameter values in SGR 38/48 -C like -c, but allow semicolon plus colon -d use rgb values rather than palette index -h display this message -q quieter output by merging all palette initialization -r display the reverse of the usual palette -s modify system colors, i.e., 0..15 -u use UTF-8 when emitting 8-bit controls " ) if ($opt_h); our $cube = 4; our (@steps); our ( $red, $green, $blue ); our ( $gray, $level, $color ); our ( $csi, $osc, $sep, $sep2, $st ); our @rgb; sub map_cube($) { my $value = $_[0]; $value = ( 3 - $value ) if defined($opt_r); return $value; } sub map_gray($) { my $value = $_[0]; $value = ( 7 - $value ) if defined($opt_r); return $value; } sub define_color($$$$) { my $index = $_[0]; my $r = $_[1]; my $g = $_[2]; my $b = $_[3]; printf( "%s4", $osc ) unless ($opt_q); printf( ";%d;rgb:%2.2x/%2.2x/%2.2x", $index, $r, $g, $b ); printf( "%s", $st ) unless ($opt_q); $rgb[$index] = sprintf "%d%s%d%s%d", $r, $sep, $g, $sep, $b; } sub select_color($) { my $index = $_[0]; if ( $opt_d and defined( $rgb[$index] ) ) { printf "%s48%s2%s%sm ", $csi, $sep, $sep2, $rgb[$index]; } else { printf "%s48%s5%s%sm ", $csi, $sep, $sep2, $index; } } sub system_color($$$$) { my $color = shift; my $red = shift; my $green = shift; my $blue = shift; &define_color( 15 - $color, $red, $green, $blue ) if ($opt_r); &define_color( $color, $red, $green, $blue ) unless ($opt_r); } if ($opt_8) { $csi = "\x9b"; $osc = "\x9d"; $st = "\x9c"; } else { $csi = "\x1b["; $osc = "\x1b]"; $st = "\x1b\\"; } if ($opt_c) { $sep = ":"; } else { $sep = ";"; } $sep2 = $sep; if ($opt_C) { $sep = ";"; $sep2 = ":"; } if ( $opt_8 and $opt_u ) { if ( open( FP, "locale 2>/dev/null |" ) ) { my (@locale) = ; chomp @locale; close(FP); for my $n ( 0 .. $#locale ) { if ( $locale[$n] =~ /^LC_CTYPE=/ ) { binmode( STDOUT, ":utf8" ) if ( $locale[$n] =~ /utf.?8/i ); last; } } } } printf( "%s4", $osc ) if ($opt_q); if ($opt_s) { &system_color( 0, 0, 0, 0 ); &system_color( 1, 205, 0, 0 ); &system_color( 2, 0, 205, 0 ); &system_color( 3, 205, 205, 0 ); &system_color( 4, 0, 0, 238 ); &system_color( 5, 205, 0, 205 ); &system_color( 6, 0, 205, 205 ); &system_color( 7, 229, 229, 229 ); &system_color( 8, 127, 127, 127 ); &system_color( 9, 255, 0, 0 ); &system_color( 10, 0, 255, 0 ); &system_color( 11, 255, 255, 0 ); &system_color( 12, 92, 92, 255 ); &system_color( 13, 255, 0, 255 ); &system_color( 14, 0, 255, 255 ); &system_color( 15, 255, 255, 255 ); } # colors 16-79 are a 4x4x4 color cube @steps = ( 0, 139, 205, 255 ); for ( $red = 0 ; $red < $cube ; $red++ ) { for ( $green = 0 ; $green < $cube ; $green++ ) { for ( $blue = 0 ; $blue < $cube ; $blue++ ) { &define_color( 16 + ( map_cube($red) * $cube * $cube ) + ( map_cube($green) * $cube ) + map_cube($blue), int( $steps[$red] ), int( $steps[$green] ), int( $steps[$blue] ) ); } } } # colors 80-87 are a grayscale ramp, intentionally leaving out # black and white for ( $gray = 0 ; $gray < 8 ; $gray++ ) { $level = ( map_gray($gray) * 23.18181818 ) + 46.36363636; if ( $gray > 0 ) { $level += 23.18181818; } &define_color( 80 + $gray, int($level), int($level), int($level) ); } printf( "%s", $st ) if ($opt_q); # display the colors # first the system ones: print "System colors:\n"; for ( $color = 0 ; $color < 8 ; $color++ ) { &select_color($color); } printf "%s0m\n", $csi; for ( $color = 8 ; $color < 16 ; $color++ ) { &select_color($color); } printf "%s0m\n\n", $csi; # now the color cube print "Color cube, ${cube}x${cube}x${cube}:\n"; for ( $green = 0 ; $green < $cube ; $green++ ) { for ( $red = 0 ; $red < $cube ; $red++ ) { for ( $blue = 0 ; $blue < $cube ; $blue++ ) { $color = 16 + ( $red * $cube * $cube ) + ( $green * $cube ) + $blue; &select_color($color); } printf "%s0m ", $csi; } print "\n"; } # now the grayscale ramp print "Grayscale ramp:\n"; for ( $color = 80 ; $color < 88 ; $color++ ) { &select_color($color); } printf "%s0m\n", $csi; xterm-399/vttests/sgrPushPop.pl0000755000000000000000000000665613330671432015442 0ustar rootroot#!/usr/bin/env perl # $XTermId: sgrPushPop.pl,v 1.10 2018/08/02 21:09:46 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm, contributed by Dan Thompson # # Copyright 2018 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- use strict; use warnings; # This script demonstrates the utility of the [non-standard] SGR push/pop # control sequences. The ability to save (on a stack) the current SGR # attributes (fg/bg color, bold, etc.) and then later restore them allows # [SGR-containing] text from independent sources to be easily composed # together, without requiring any sort of global coordination. our ( $pushSgr, $popSgr, $lib1Fmt, $lib2Fmt, $redOnBlack, $blackOnYellow, $blueOnGreen, $bg, $fg ); $pushSgr = "\x1b[#{"; $popSgr = "\x1b[#}"; # lib1Fmt represents a "top-level" program, and controls the current "ambient" # fg/bg colors. $lib1Fmt = "\x1b[48;5;%sm\x1b[38;5;%sm%03.3d/%03.3d "; # lib2Fmt represents some intermediate library. Note that it contains no SGR # control sequences at all. $lib2Fmt = "Test stack: %s, %s, %s"; # The following represent individual bits of colorized data that come from # other, "leaf-level" libraries. $redOnBlack = $pushSgr . "\x1b[1;31m\x1b[40m" . "redOnBlack" . $popSgr; $blackOnYellow = $pushSgr . "\x1b[30m\x1b[4;43m" . "blackOnYellow" . $popSgr; $blueOnGreen = $pushSgr . "\x1b[34m\x1b[42m" . "blueOnGreen" . $popSgr; printf $pushSgr; printf "\x1b[40;37mSetting ambient colors to white-on-black\n"; printf $pushSgr; for ( $bg = 0 ; $bg < 16 ; $bg++ ) { for ( $fg = 0 ; $fg < 16 ; $fg++ ) { printf $pushSgr; printf $lib1Fmt, $fg, $bg, $fg, $bg; printf $lib2Fmt, $redOnBlack, $blackOnYellow, $blueOnGreen; print " something else"; printf $popSgr; # keep the newline from bleeding color print "\n"; } print "\n"; } printf $popSgr; printf "The ambient colors should still be white-on-black.\n"; printf $popSgr; printf "Now we should be back to whatever it was before we got here.\n"; 1; xterm-399/vttests/bold-italics.pl0000755000000000000000000000504113541747471015674 0ustar rootroot#!/usr/bin/env perl # $XTermId: bold-italics.pl,v 1.1 2019/09/22 19:44:57 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2019 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Test bold-italics for single- and double-width characters. use strict; use warnings; use I18N::Langinfo qw(langinfo CODESET); our $encoding = lc( langinfo( CODESET() ) ); our $single_text = "ABCDEFGH"; our $double_text = ""; sub showcase($$) { my $testcase = shift; my $sgr_code = shift; printf "\033[%sm", $sgr_code; printf "%-8s%s\n", $testcase, $single_text; printf "%-8s%s\n", " ", $double_text if ( $encoding eq "utf-8" ); printf "\033[%sm", "0"; } sub doit() { my $bold = "1"; my $italics = "3"; &showcase( "Normal", "0" ); &showcase( "Bold", $bold ); &showcase( "Italics", $italics ); &showcase( "Both:BI", "$bold;$italics" ); } if ( $encoding eq "utf-8" ) { binmode( STDOUT, ":utf8" ); for my $n ( 0 .. length($single_text) - 1 ) { my $chr = substr( $single_text, $n, 1 ); $double_text .= chr( 0xff00 + ord($chr) - 32 ); } } &doit; 1; xterm-399/vttests/88colors.pl0000755000000000000000000000366313041175436015006 0ustar rootroot#!/usr/bin/env perl # $XTermId: 88colors.pl,v 1.5 2017/01/22 18:34:06 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 1999-2014,2017 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Made from 256colors.pl use strict; use warnings; our ( $bg, $fg ); for ( $bg = 0 ; $bg < 88 ; $bg++ ) { print "\x1b[9;1H\x1b[48;5;${bg}m\x1b[2J"; for ( $fg = 0 ; $fg < 88 ; $fg++ ) { print "\x1b[38;5;${fg}m"; printf "%03.3d/%03.3d ", $fg, $bg; } sleep 1; print "\n"; } xterm-399/vttests/256colors.pl0000755000000000000000000000406713041175436015062 0ustar rootroot#!/usr/bin/env perl # $XTermId: 256colors.pl,v 1.6 2017/01/22 18:34:06 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 1999-2014,2017 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- use strict; use warnings; # This uses 33 print-lines on an 80-column display. Printing the numbers in # hexadecimal would make it compact enough for 24x80, but less readable. our ( $bg, $fg ); for ( $bg = 0 ; $bg < 256 ; $bg++ ) { # print "\x1b[9;1H\x1b[2J"; for ( $fg = 0 ; $fg < 256 ; $fg++ ) { print "\x1b[48;5;${bg}m\x1b[38;5;${fg}m"; printf "%03.3d/%03.3d ", $fg, $bg; } print "\n"; sleep 1; } xterm-399/vttests/setpos.pl0000755000000000000000000002162413472617401014640 0ustar rootroot#!/usr/bin/env perl # $XTermId: setpos.pl,v 1.18 2019/05/26 23:19:29 tom Exp $ # ----------------------------------------------------------------------------- # Copyright 2019 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Exercise CSI 3/13 t which set/get the window position. use strict; use Getopt::Std; use IO::Handle; $| = 1; our ( $opt_a, $opt_n, $opt_p, $opt_v, $opt_x, $opt_8 ); our $default_y = 100; our $default_x = 150; sub main::HELP_MESSAGE() { printf STDERR <; close TTY; system "stty $old"; if ( defined $reply ) { die("^C received\n") if ( "$reply" eq "\003" ); } return $reply; } sub read_cmd($) { my $cmd = shift; my @result; if ( open my $fh, "$cmd |" ) { @result = <$fh>; close $fh; chomp @result; } return @result; } sub get_xprop($$) { my $id = shift; my $name = shift; my @data = &read_cmd("xprop -id $id"); my $prop = ""; for my $n ( 0 .. $#data ) { if ( $data[$n] =~ /$name\([^)]+\) =/ ) { $prop = $data[$n]; $prop =~ s/^[^=]*=\s*//; $prop =~ s/"//g; last; } } return $prop; } sub visible($) { my $reply = $_[0]; my $n; my $result = ""; for ( $n = 0 ; $n < length($reply) ; ) { my $c = substr( $reply, $n, 1 ); if ( $c =~ /[[:print:]]/ ) { $result .= $c; } else { my $k = ord substr( $reply, $n, 1 ); if ( ord $k == 0x1b ) { $result .= "\\E"; } elsif ( $k == 0x7f ) { $result .= "^?"; } elsif ( $k == 32 ) { $result .= "\\s"; } elsif ( $k < 32 ) { $result .= sprintf( "^%c", $k + 64 ); } elsif ( $k > 128 ) { $result .= sprintf( "\\%03o", $k ); } else { $result .= chr($k); } } $n += 1; } return $result; } sub limited($) { my $value = shift; if ( $value >= 65536 ) { $value %= 65536; } if ( $value >= 32768 ) { $value -= 65536; } return $value; } sub check_position($$$) { my $name = shift; my $expect = shift; my $actual = shift; printf " ?%s:%d", $name, $expect if ( $expect != $actual ); } sub report_position() { my $reply = &get_reply( sprintf "%s13t", $CSI ); my $status = 0; my @result; if ( index( $reply, $CSI ) == 0 ) { $reply = substr( $reply, length($CSI) ); $status = 1; } if ( $reply =~ /^3;\d+;\d+t$/ ) { my $y = $reply; $y =~ s/^3;(\d+);.*/$1/; my $x = $reply; $x =~ s/^3;\d+;(\d+).*/$1/; $result[0] = &limited($y); $result[1] = &limited($x); printf "OK ->%s ->%d,%d", &visible($reply), $result[0], $result[1]; } else { printf "ERR ->%s", &visible($reply); } if ( $opt_x and $ENV{WINDOWID} ) { my @actual = `xwininfo -id $ENV{WINDOWID} | grep " upper-left [XY]:"`; for my $n ( 0 .. $#actual ) { $actual[$n] =~ s/^.*:\s+//; } if ( $#actual == 3 ) { printf " abs(%d,%d) rel(%d,%d)", $actual[0], $actual[1], $actual[2], $actual[3] if ($opt_v); my $expect_y; my $expect_x; if ( $wm_name =~ /^gnome/i ) { $expect_x = $actual[0] - ( $extents[0] + $extents[1] ); $expect_y = $actual[1] - ( $extents[2] + $extents[3] ); } elsif ( $#extents == 3 and ( $wm_name !~ /^fvwm/i ) and ( $wm_name !~ /^enlightenment/i ) ) { $expect_x = $actual[0] - ( $extents[0] ); $expect_y = $actual[1] - ( $extents[2] ); } else { $expect_x = $actual[0] - $actual[2]; $expect_y = $actual[1] - $actual[3]; } if ( $#result > 0 ) { &check_position( "X", $expect_x, $result[0] ); &check_position( "Y", $expect_y, $result[1] ); } } } printf "\n"; return @result; } sub update_position() { my @pos = @{ $_[0] }; printf "** update %d,%d\n", $pos[0], $pos[1]; $pos[0] += 65536 if ( $pos[0] < 0 ); $pos[1] += 65536 if ( $pos[1] < 0 ); &no_reply( sprintf "%s3;%d;%dt", $CSI, $pos[0], $pos[1] ); } sub update_and_report($) { my @pos = @{ $_[0] }; &update_position( \@pos ); sleep 1 if ($opt_a); return &report_position; } sub get_screensize() { my $reply = &get_reply( sprintf "%s15t", $CSI ); my @result; if ( index( $reply, $CSI ) == 0 ) { $reply = substr( $reply, length($CSI) ); if ( $reply =~ /^5;\d+;\d+t$/ ) { my $y = $reply; $y =~ s/^5;(\d+);.*/$1/; my $x = $reply; $x =~ s/^5;\d+;(\d+).*/$1/; $result[0] = $x; $result[1] = $y; } } return @result; } sub doit() { my @old = &report_position; if ($opt_a) { my @size = &get_screensize; if (@size) { printf "Screen %dx%d\n", $size[0], $size[1]; my $ulx = -$default_x; my $uly = -$default_y; my $lrx = $size[0] - $default_x; my $lry = $size[1] - $default_y; &update_and_report( [ $ulx, $uly ] ); &update_and_report( [ $ulx, $lry ] ); &update_and_report( [ $lrx, $lry ] ); &update_and_report( [ $lrx, $uly ] ); &update_position( \@old ); } } else { my @pos = ( $default_y, $default_x ); for my $n ( 1 .. $repeat ) { @pos = &update_and_report( \@pos ); } } } printf "\x1b G" if ($opt_8); if ( $opt_x and $ENV{WINDOWID} ) { my $extents = &get_xprop( $ENV{WINDOWID}, "_NET_FRAME_EXTENTS" ); if ( $extents ne "" ) { @extents = split /,\s*/, $extents; printf "** has EWMH extents: $extents\n"; my $supwin = `xprop -root '_NET_SUPPORTING_WM_CHECK'`; if ( $supwin ne "" ) { $supwin =~ s/^.*(0x[[:xdigit:]]+).*/$1/; $wm_name = &get_xprop( $supwin, "_NET_WM_NAME" ); $wm_name = "unknown" unless ( $wm_name ne "" ); printf "** using \"$wm_name\"\n"; } } } &doit; printf "\x1b F" if ($opt_8); 1; xterm-399/vttests/iso2022.pl0000755000000000000000000000577014011625120014412 0ustar rootroot#!/usr/bin/env perl # $XTermId: iso2022.pl,v 1.5 2021/02/13 01:24:32 tom Exp $ # ----------------------------------------------------------------------------- # Copyright 2021 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # show ISO-2022 characters, by default GL and GR, optionally G1/G2/G3 use strict; use warnings; use Getopt::Std; $| = 1; our ( $opt_k, $opt_n, $opt_q, $opt_s ); sub doit() { my $GL = ""; printf "-- vile: fk=8bit\n"; my $lo = 0; if ($opt_q) { $GL = "`1234567890-=\n" . "qwertyuiop[]\\\n" . "asdfghjkl;'\n" . "zxcvbnm,./\n" . "~!@#$%^&*()_+\n" . "QWERTYUIOP{}|\n" . "ASDFGHJKL:\"\n" . "ZXCVBNM<>?"; } else { $lo = $opt_k ? 0 : 32; for my $n ( $lo .. 127 ) { $GL .= chr($n); $GL .= "\n" if ( ( ( $n - 31 ) % 16 ) == 0 ); } } my $GR = ""; for my $n ( 0 .. ( length($GL) - 1 ) ) { my $c = substr( $GL, $n, 1 ); if ( ord($c) == 10 and ( not $opt_k or $n != 10 ) ) { $GR .= $c; } else { $GR .= chr( ord($c) + 128 ); } } if ($opt_s) { $GL =~ s/([^\n])/ $1/g; $GR =~ s/([^\n])/ $1/g; } printf "GL:\n%s\n", $GL; printf "GR:\n%s\n", $GR; } sub main::HELP_MESSAGE() { printf STDERR < #include #include #include #include #include /* * This module performs translation as needed to support the DEC VT220 national * replacement character sets as well as supplementary character sets (aka * code-pages) introduced in VT320, etc. * * We assume that xterm's font is based on the ISO 8859-1 (Latin 1) character * set, which is almost the same as the DEC multinational character set. Glyph * positions 0-31 have to be the DEC graphic characters, though. * * References: * "VT220 Programmer Pocket Guide" EK-VT220-HR-002 (2nd ed., 1984), which * contains character charts for the national character sets. * "VT330/VT340 Programmer Reference Manual Volume 1: Text Programming" * EK-VT3XX-TP-001 (1st ed, 1987), which contains a table (2-1) * listing the glyphs which are mapped from the multinational * character set to the national character set. * * The latter reference, though easier to read, has a few errors and omissions. */ #define HandleUPSS(charset) \ if (charset == nrc_DEC_UPSS) { \ charset = screen->gsets_upss; \ if (screen->vtXX_level >= 5) { \ /* EMPTY */ ; \ } else if (screen->vtXX_level >= 3) { \ if (charset != nrc_DEC_Supp) \ charset = nrc_ISO_Latin_1_Supp; \ } else if (screen->vtXX_level < 2) { \ charset = nrc_ASCII; \ } \ } static Boolean isSevenBit(DECNRCM_codes cs) { Boolean result = False; switch (cs) { case nrc_ISO_Greek_Supp: case nrc_ISO_Hebrew_Supp: case nrc_ISO_Latin_1_Supp: case nrc_ISO_Latin_2_Supp: case nrc_ISO_Latin_5_Supp: case nrc_ISO_Latin_Cyrillic: case nrc_DEC_UPSS: break; /* VT100 character sets */ case nrc_ASCII: case nrc_British: case nrc_DEC_Alt_Chars: case nrc_DEC_Spec_Graphic: /* VT220 character sets */ case nrc_DEC_Alt_Graphics: case nrc_DEC_Supp: /* VT320 character sets */ case nrc_DEC_Supp_Graphic: case nrc_DEC_Technical: /* NRCS character sets (VT320 to VT520) */ case nrc_British_Latin_1: case nrc_Dutch: case nrc_Finnish2: case nrc_Finnish: case nrc_French2: case nrc_French: case nrc_French_Canadian2: case nrc_French_Canadian: case nrc_German: case nrc_Greek: case nrc_Hebrew: case nrc_Italian: case nrc_JIS_Katakana: case nrc_JIS_Roman: case nrc_Norwegian_Danish2: case nrc_Norwegian_Danish3: case nrc_Norwegian_Danish: case nrc_Portugese: case nrc_Russian: case nrc_SCS_NRCS: case nrc_Spanish: case nrc_Swedish2: case nrc_Swedish: case nrc_Swiss: case nrc_Turkish: /* other DEC character sets */ case nrc_DEC_Cyrillic: case nrc_DEC_Greek_Supp: case nrc_DEC_Hebrew_Supp: case nrc_DEC_Turkish_Supp: result = True; break; case nrc_Unknown: break; } return result; } /* * Translate an input keysym to the corresponding NRC keysym. */ unsigned xtermCharSetIn(XtermWidget xw, unsigned code, DECNRCM_codes charset) { TScreen *screen = TScreenOf(xw); #define MAP(to, from) case from: code = to; break; #if OPT_WIDE_CHARS #define UNI(to, from) case from: if (screen->utf8_nrc_mode) code = to; break; #else #define UNI(to, from) case from: break; #endif #define XXX(to, from) /* no defined mapping to 0..255 */ TRACE(("CHARSET-IN GL=%s(G%d) GR=%s(G%d) SS%d\n\t%s\n", visibleScsCode(screen->gsets[screen->curgl]), screen->curgl, visibleScsCode(screen->gsets[screen->curgr]), screen->curgr, screen->curss, visibleUChar(code))); HandleUPSS(charset); switch (charset) { case nrc_British: /* United Kingdom set (or Latin 1) */ if (code == XK_sterling) code = 0x23; code &= 0x7f; break; case nrc_DEC_Alt_Chars: case nrc_DEC_Alt_Graphics: case nrc_ASCII: break; case nrc_DEC_Spec_Graphic: break; case nrc_DEC_Supp: map_DEC_Supp_Graphic(code, code &= 0x7f); break; case nrc_DEC_Supp_Graphic: map_DEC_Supp_Graphic(code, code |= 0x80); break; case nrc_DEC_Technical: map_DEC_Technical(code); break; case nrc_Dutch: map_NRCS_Dutch(code); break; case nrc_Finnish: case nrc_Finnish2: map_NRCS_Finnish(code); break; case nrc_French: case nrc_French2: map_NRCS_French(code); break; case nrc_French_Canadian: map_NRCS_French_Canadian(code); break; case nrc_German: map_NRCS_German(code); break; case nrc_Greek: map_NRCS_Greek(code); /* FIXME - ELOT? */ break; case nrc_DEC_Greek_Supp: map_DEC_Greek_Supp(code); break; case nrc_ISO_Greek_Supp: map_ISO_Greek_Supp(code); break; case nrc_DEC_Hebrew_Supp: map_DEC_Hebrew_Supp(code); break; case nrc_Hebrew: map_NRCS_Hebrew(code); break; case nrc_ISO_Hebrew_Supp: map_ISO_Hebrew(code); break; case nrc_Italian: map_NRCS_Italian(code); break; case nrc_ISO_Latin_2_Supp: map_ISO_Latin_2(code); break; case nrc_ISO_Latin_5_Supp: map_ISO_Latin_5(code); break; case nrc_ISO_Latin_Cyrillic: map_ISO_Latin_Cyrillic(code); break; case nrc_JIS_Katakana: map_JIS_Katakana(code); break; case nrc_JIS_Roman: map_JIS_Roman(code); break; case nrc_Norwegian_Danish: case nrc_Norwegian_Danish2: case nrc_Norwegian_Danish3: map_NRCS_Norwegian_Danish(code); break; case nrc_Portugese: map_NRCS_Portuguese(code); break; case nrc_Russian: map_NRCS_Russian(code); break; case nrc_SCS_NRCS: /* vt5xx - Serbo/Croatian */ map_NRCS_Serbo_Croatian(code); break; case nrc_Spanish: map_NRCS_Spanish(code); break; case nrc_Swedish2: case nrc_Swedish: map_NRCS_Swedish(code); break; case nrc_Swiss: map_NRCS_Swiss(code); break; case nrc_Turkish: map_NRCS_Turkish(code); break; case nrc_DEC_Turkish_Supp: map_DEC_Turkish_Supp(code); break; case nrc_DEC_Cyrillic: map_DEC_Cyrillic(code); break; case nrc_ISO_Latin_1_Supp: case nrc_British_Latin_1: case nrc_French_Canadian2: case nrc_Unknown: case nrc_DEC_UPSS: default: /* any character sets we don't recognize */ break; } code &= 0x7f; /* NRC in any case is 7-bit */ TRACE(("->\t%s\n", visibleUChar(code))); return code; #undef MAP #undef UNI #undef XXX } /* * Translate a string to the display form. This assumes the font has the * DEC graphic characters in cells 0-31, and otherwise is ISO-8859-1. */ Cardinal xtermCharSetOut(XtermWidget xw, Cardinal length, DECNRCM_codes leftset) { IChar *buf = xw->work.write_text; IChar *ptr = buf + length; IChar *s; TScreen *screen = TScreenOf(xw); Cardinal count = 0; DECNRCM_codes rightset = screen->gsets[(int) (screen->curgr)]; #if OPT_DEC_RECTOPS int sums = 0; #endif #define MAP(from, to) case from: chr = to; break; #if OPT_WIDE_CHARS #define UNI(from, to) case from: if (screen->utf8_nrc_mode) chr = to; break; #define XXX(from, to) UNI(from, to) #else #define UNI(old, new) case new: chr = old; break; #define XXX(from, to) /* nothing */ #endif TRACE(("CHARSET-OUT GL=%s(G%d) GR=%s(G%d) SS%d\n\t%s\n", visibleScsCode(leftset), screen->curgl, visibleScsCode(rightset), screen->curgr, screen->curss, visibleIChars(buf, (size_t) length))); assert(length != 0); #if OPT_DEC_RECTOPS if (length != 0 && length > xw->work.sizeof_sums) { xw->work.sizeof_sums += length + 80; xw->work.buffer_sums = realloc(xw->work.buffer_sums, xw->work.sizeof_sums); xw->work.buffer_sets = realloc(xw->work.buffer_sets, xw->work.sizeof_sums); } xw->work.write_sums = xw->work.buffer_sums; #endif for (s = buf; s < ptr; ++s) { int eight = CharOf(*s); int seven = eight & 0x7f; DECNRCM_codes cs = (eight >= 128) ? rightset : leftset; int chr = eight; HandleUPSS(cs); #if OPT_DEC_RECTOPS if (xw->work.buffer_sums != NULL && xw->work.buffer_sets != NULL) { xw->work.buffer_sums[sums] = (Char) ((eight < 32 || eight > 255) ? ANSI_ESC : eight); xw->work.buffer_sets[sums] = cs; ++sums; } #endif count++; #if OPT_WIDE_CHARS /* * This is only partly right - prevent inadvertent remapping of * the replacement character and other non-8bit codes into bogus * 8bit codes. */ if (screen->utf8_mode || screen->utf8_nrc_mode) { if (*s > 255) continue; } #endif if (*s < 32) continue; switch (cs) { case nrc_DEC_UPSS: break; case nrc_ISO_Latin_1_Supp: case nrc_British_Latin_1: case nrc_British: /* United Kingdom set (or Latin 1) */ if ((xw->flags & NATIONAL) || (screen->vtXX_level <= 1)) { if ((xw->flags & NATIONAL)) { chr = seven; } if (chr == 0x23) { chr = XTERM_POUND; #if OPT_WIDE_CHARS if (screen->utf8_nrc_mode) { chr = 0xa3; } #endif } } break; case nrc_DEC_Alt_Chars: case nrc_DEC_Alt_Graphics: case nrc_ASCII: break; case nrc_DEC_Spec_Graphic: if (seven > 0x5f && seven <= 0x7e) { #if OPT_WIDE_CHARS if (screen->utf8_mode || screen->utf8_nrc_mode) chr = (int) dec2ucs(screen, (unsigned) (seven - 0x5f)); else #endif chr = seven - 0x5f; } else if (chr == 0x5f) { chr = 0; } else { chr = seven; } break; case nrc_DEC_Supp: case nrc_DEC_Supp_Graphic: map_DEC_Supp_Graphic(chr = seven, chr = eight); break; case nrc_DEC_Technical: map_DEC_Technical(chr = seven); break; case nrc_Dutch: map_NRCS_Dutch(chr = seven); break; case nrc_Finnish: case nrc_Finnish2: map_NRCS_Finnish(chr = seven); break; case nrc_French: case nrc_French2: map_NRCS_French(chr = seven); break; case nrc_French_Canadian: case nrc_French_Canadian2: map_NRCS_French_Canadian(chr = seven); break; case nrc_German: map_NRCS_German(chr = seven); break; case nrc_Greek: map_NRCS_Greek(chr = seven); /* FIXME - ELOT? */ break; case nrc_DEC_Greek_Supp: map_DEC_Greek_Supp(chr = seven); break; case nrc_ISO_Greek_Supp: map_ISO_Greek_Supp(chr = seven); break; case nrc_DEC_Hebrew_Supp: map_DEC_Hebrew_Supp(chr = seven); break; case nrc_Hebrew: map_NRCS_Hebrew(chr = seven); break; case nrc_ISO_Hebrew_Supp: map_ISO_Hebrew(chr = seven); break; case nrc_Italian: map_NRCS_Italian(chr = seven); break; case nrc_ISO_Latin_2_Supp: map_ISO_Latin_2(chr = seven); break; case nrc_ISO_Latin_5_Supp: map_ISO_Latin_5(chr = seven); break; case nrc_ISO_Latin_Cyrillic: map_ISO_Latin_Cyrillic(chr = seven); break; case nrc_JIS_Katakana: map_JIS_Katakana(chr = seven); break; case nrc_JIS_Roman: map_JIS_Roman(chr = seven); break; case nrc_Norwegian_Danish: case nrc_Norwegian_Danish2: case nrc_Norwegian_Danish3: map_NRCS_Norwegian_Danish(chr = seven); break; case nrc_Portugese: map_NRCS_Portuguese(chr = seven); break; case nrc_Russian: map_NRCS_Russian(chr = seven); break; case nrc_SCS_NRCS: /* vt5xx - Serbo/Croatian */ map_NRCS_Serbo_Croatian(chr = seven); break; case nrc_Spanish: map_NRCS_Spanish(chr = seven); break; case nrc_Swedish2: case nrc_Swedish: map_NRCS_Swedish(chr = seven); break; case nrc_Swiss: map_NRCS_Swiss(chr = seven); break; case nrc_Turkish: map_NRCS_Turkish(chr = seven); break; case nrc_DEC_Turkish_Supp: map_DEC_Turkish_Supp(chr = seven); break; case nrc_DEC_Cyrillic: map_DEC_Cyrillic(chr = seven); break; case nrc_Unknown: default: /* any character sets we don't recognize */ break; } /* * The state machine already treated DEL as a nonprinting and * nonspacing character. If we have DEL now, remove it. */ if (chr == ANSI_DEL && isSevenBit(cs)) { IChar *s1; --ptr; for (s1 = s; s1 < ptr; ++s1) { s1[0] = s1[1]; } --count; #if OPT_DEC_RECTOPS --sums; #endif } else { if (eight >= 128 && chr < 128 && chr > 32) chr |= 128; *s = (IChar) chr; } } TRACE(("%d\t%s\n", count, visibleIChars(buf, (size_t) length))); return count; #undef MAP #undef UNI #undef XXX } #if OPT_DEC_RECTOPS /* * Given a mapped character, e.g., a Unicode value returned by xtermCharSetIn, * match it against the current GL/GR selection and return the corresponding * DEC internal character-set code for DECRQCRA. * * A hardware terminal presumably stores the original and mapped characters, * as well as the character set which was selected at that time Doing that * in xterm adds a couple of bytes to every cell. */ int xtermCharSetDec(XtermWidget xw, IChar chr, DECNRCM_codes cs) { #define MAP(from, to) case from: result = to; break; #define DFTMAP() result = (actual | 0x80) #define DFT_94(chr) result = ((actual) & 0x7f) #define DFT_96(chr) result = ((actual) | 0x80) #if OPT_WIDE_CHARS #define UNI(from, to) case from: if (screen->utf8_nrc_mode) result = to; break; #define XXX(from, to) UNI(from, to) #else #define UNI(old, new) case new: result = old; break; #define XXX(from, to) /* nothing */ #endif int result; if (chr < 0x20 #if OPT_WIDE_CHARS || chr > 0xff #endif ) { result = ANSI_ESC; } else { Boolean isSeven = isSevenBit(cs); TScreen *screen = TScreenOf(xw); result = -1; HandleUPSS(cs); if (chr == 0xa0 && isSeven) { result = ANSI_ESC; } else if (chr == ANSI_SPA && isSeven) { result = ANSI_SPA; } else if ((chr == ANSI_DEL || chr == 0xff) && isSeven) { result = 0; } else { int actual = (int) chr; chr &= 0x7f; switch (cs) { case nrc_DEC_Alt_Chars: case nrc_DEC_Alt_Graphics: case nrc_ASCII: result = (int) chr; break; case nrc_British: if (chr == 0x23) chr = XK_sterling; result = (int) chr; break; case nrc_DEC_Cyrillic: unmap_DEC_Cyrillic(chr, DFT_94(chr)); break; case nrc_DEC_Spec_Graphic: unmap_DEC_Spec_Graphic(chr, DFT_94(chr)); break; case nrc_DEC_Supp: /* FALLTHRU */ case nrc_DEC_Supp_Graphic: unmap_DEC_Supp_Graphic(chr, DFTMAP()); break; case nrc_DEC_Technical: unmap_DEC_Technical(chr, DFTMAP()); break; case nrc_Dutch: unmap_NRCS_Dutch(chr, DFT_94(chr)); break; case nrc_Finnish: case nrc_Finnish2: unmap_NRCS_Finnish(chr, DFT_94(chr)); break; case nrc_French: case nrc_French2: unmap_NRCS_French(chr, DFT_94(chr)); break; case nrc_French_Canadian: case nrc_French_Canadian2: unmap_NRCS_French_Canadian(chr, DFT_94(chr)); break; case nrc_German: unmap_NRCS_German(chr, DFT_94(chr)); break; case nrc_Greek: unmap_NRCS_Greek(chr, DFT_94(chr)); break; case nrc_DEC_Greek_Supp: unmap_DEC_Greek_Supp(chr, DFTMAP()); break; case nrc_ISO_Greek_Supp: unmap_ISO_Greek_Supp(chr, DFTMAP()); break; case nrc_DEC_Hebrew_Supp: unmap_DEC_Hebrew_Supp(chr, DFTMAP()); break; case nrc_Hebrew: unmap_NRCS_Hebrew(chr, DFT_94(chr)); break; case nrc_ISO_Hebrew_Supp: unmap_ISO_Hebrew(chr, DFTMAP()); break; case nrc_Italian: unmap_NRCS_Italian(chr, DFT_94(chr)); break; case nrc_JIS_Katakana: unmap_JIS_Katakana(chr, DFT_94(chr)); break; case nrc_JIS_Roman: unmap_JIS_Roman(chr, DFT_94(chr)); break; case nrc_ISO_Latin_1_Supp: unmap_ISO_Latin_1(chr, DFTMAP()); break; case nrc_ISO_Latin_2_Supp: unmap_ISO_Latin_2(chr, DFTMAP()); break; case nrc_ISO_Latin_5_Supp: unmap_ISO_Latin_5(chr, DFTMAP()); break; case nrc_ISO_Latin_Cyrillic: unmap_ISO_Latin_Cyrillic(chr, DFTMAP()); break; case nrc_Norwegian_Danish: case nrc_Norwegian_Danish2: case nrc_Norwegian_Danish3: unmap_NRCS_Norwegian_Danish(chr, DFT_94(chr)); break; case nrc_Portugese: unmap_NRCS_Portuguese(chr, DFT_94(chr)); break; case nrc_Russian: unmap_NRCS_Russian(chr, DFT_94(chr)); break; case nrc_SCS_NRCS: unmap_NRCS_Serbo_Croatian(chr, DFT_94(chr)); break; case nrc_Spanish: unmap_NRCS_Spanish(chr, DFT_94(chr)); break; case nrc_Swedish: case nrc_Swedish2: unmap_NRCS_Swedish(chr, DFT_94(chr)); break; case nrc_Swiss: unmap_NRCS_Swiss(chr, DFT_94(chr)); break; case nrc_DEC_Turkish_Supp: unmap_DEC_Turkish_Supp(chr, DFTMAP()); break; case nrc_Turkish: unmap_NRCS_Turkish(chr, DFT_94(chr)); break; case nrc_British_Latin_1: case nrc_Unknown: case nrc_DEC_UPSS: default: /* anything we cannot unmap */ break; } if (result < 0) { if (isSeven) { DFT_94(chr); } else { DFT_96(chr); } } } } return result; #undef MAP #undef UNI #undef XXX } #endif /* OPT_DEC_RECTOPS */ xterm-399/trace.c0000644000000000000000000010321014773617007012510 0ustar rootroot/* $XTermId: trace.c,v 1.247 2025/04/03 23:47:19 tom Exp $ */ /* * Copyright 1997-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ /* * debugging support via TRACE macro. */ #include /* for definition of GCC_UNUSED */ #include #include #include #if OPT_TRACE #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_X11_TRANSLATEI_H #include #include #else #ifdef __cplusplus extern "C" { #endif extern String _XtPrintXlations(Widget w, XtTranslations xlations, Widget accelWidget, _XtBoolean includeRHS); #ifdef __cplusplus } #endif #endif const char *trace_who = "parent"; static FILE *trace_fp; static FILE * TraceOpen(void) { static const char *trace_out; if (trace_fp != NULL && trace_who != trace_out) { fclose(trace_fp); trace_fp = NULL; } trace_out = trace_who; if (!trace_fp) { static char dot[] = "."; mode_t oldmask = umask(077); char *home; char *name; /* * Put the trace-file in user's home-directory if the current * directory is not writable. */ home = ((access(dot, R_OK | W_OK) == 0) ? dot : getenv("HOME")); if (home != NULL && (name = malloc(strlen(home) + strlen(trace_who) + 50)) != NULL) { #if OPT_TRACE_UNIQUE /* usually I do not want unique names */ int unique; for (unique = 0;; ++unique) { if (unique) sprintf(name, "%s/Trace-%s.out-%d", home, trace_who, unique); else sprintf(name, "%s/Trace-%s.out", home, trace_who); if ((trace_fp = fopen(name, "r")) == 0) { break; } fclose(trace_fp); } #else sprintf(name, "%s/Trace-%s.out", home, trace_who); #endif trace_fp = fopen(name, "w"); if (trace_fp != NULL) { fprintf(trace_fp, "%s\n", xtermVersion()); TraceIds(NULL, 0); } if (!trace_fp) { xtermWarning("Cannot open \"%s\"\n", name); exit(EXIT_FAILURE); } (void) umask(oldmask); free(name); } } return trace_fp; } void Trace(const char *fmt, ...) { va_list ap; FILE *fp = TraceOpen(); va_start(ap, fmt); vfprintf(fp, fmt, ap); (void) fflush(fp); va_end(ap); } void TraceVA(const char *fmt, va_list ap) { FILE *fp = TraceOpen(); vfprintf(fp, fmt, ap); (void) fflush(fp); } void TraceClose(void) { if (trace_fp != NULL) { (void) fclose(trace_fp); (void) fflush(stdout); (void) fflush(stderr); (void) visibleChars(NULL, 0); (void) visibleIChars(NULL, 0); trace_fp = NULL; } } void TraceXError(Display *d, XErrorEvent *ev) { FILE *fp = TraceOpen(); (void) XmuPrintDefaultErrorMessage(d, ev, fp); (void) fflush(fp); } void TraceIds(const char *fname, int lnum) { Trace("process %d ", (int) getpid()); #ifdef HAVE_UNISTD_H Trace("real (%u/%u) effective (%u/%u)", (unsigned) getuid(), (unsigned) getgid(), (unsigned) geteuid(), (unsigned) getegid()); #endif if (fname != NULL) { Trace(" (%s@%d)\n", fname, lnum); } else { time_t now = time((time_t *) 0); Trace("-- %s", ctime(&now)); } } void TraceTime(const char *fname, int lnum) { time_t now; if (fname != NULL) { Trace("datetime (%s@%d) ", fname, lnum); } now = time((time_t *) 0); Trace("-- %s", ctime(&now)); } static void formatAscii(char *dst, unsigned value) { switch (value) { case '\\': sprintf(dst, "\\\\"); break; case '\b': sprintf(dst, "\\b"); break; case '\n': sprintf(dst, "\\n"); break; case '\r': sprintf(dst, "\\r"); break; case '\t': sprintf(dst, "\\t"); break; default: if (value < 32 || (value >= 127 && value < 160)) sprintf(dst, "\\%03o", value & 0xff); else sprintf(dst, "%c", CharOf(value)); break; } } #if OPT_DEC_CHRSET const char * visibleDblChrset(unsigned chrset) { const char *result = "?"; switch (chrset) { case CSET_SWL: result = "CSET_SWL"; break; case CSET_DHL_TOP: result = "CSET_DHL_TOP"; break; case CSET_DHL_BOT: result = "CSET_DHL_BOT"; break; case CSET_DWL: result = "CSET_DWL"; break; } return result; } #endif const char * visibleScsCode(DECNRCM_codes chrset) { #define MAP(to,from) case from: result = to ":" #from; break const char *result = ""; switch ((DECNRCM_codes) chrset) { MAP("B", nrc_ASCII); MAP("A", nrc_British); MAP("A", nrc_British_Latin_1); MAP("&4", nrc_DEC_Cyrillic); MAP("0", nrc_DEC_Spec_Graphic); MAP("1", nrc_DEC_Alt_Chars); MAP("2", nrc_DEC_Alt_Graphics); MAP("<", nrc_DEC_Supp); MAP("<", nrc_DEC_UPSS); MAP("%5", nrc_DEC_Supp_Graphic); MAP(">", nrc_DEC_Technical); MAP("4", nrc_Dutch); MAP("5", nrc_Finnish); MAP("C", nrc_Finnish2); MAP("R", nrc_French); MAP("f", nrc_French2); MAP("Q", nrc_French_Canadian); MAP("9", nrc_French_Canadian2); MAP("K", nrc_German); MAP("\"?", nrc_DEC_Greek_Supp); MAP("\">", nrc_Greek); MAP("F", nrc_ISO_Greek_Supp); MAP("\"4", nrc_DEC_Hebrew_Supp); MAP("%=", nrc_Hebrew); MAP("H", nrc_ISO_Hebrew_Supp); MAP("Y", nrc_Italian); MAP("A", nrc_ISO_Latin_1_Supp); MAP("B", nrc_ISO_Latin_2_Supp); MAP("I", nrc_JIS_Katakana); MAP("J", nrc_JIS_Roman); MAP("M", nrc_ISO_Latin_5_Supp); MAP("L", nrc_ISO_Latin_Cyrillic); MAP("`", nrc_Norwegian_Danish); MAP("E", nrc_Norwegian_Danish2); MAP("6", nrc_Norwegian_Danish3); MAP("%6", nrc_Portugese); MAP("&5", nrc_Russian); MAP("%3", nrc_SCS_NRCS); MAP("Z", nrc_Spanish); MAP("7", nrc_Swedish); MAP("H", nrc_Swedish2); MAP("=", nrc_Swiss); MAP("%2", nrc_Turkish); MAP("%0", nrc_DEC_Turkish_Supp); MAP("", nrc_Unknown); } #undef MAP return result; } const char * visibleChars(const Char *buf, size_t len) { static char *result; static size_t used; if (buf != NULL) { size_t limit = ((len + 1) * 8) + 1; if (limit > used) { used = limit; result = realloc(result, used); } if (result != NULL) { char *dst = result; *dst = '\0'; while (len--) { unsigned value = *buf++; formatAscii(dst, value); dst += strlen(dst); } } } else { FreeAndNull(result); used = 0; } return NonNull(result); } const char * visibleEventMode(EventMode value) { const char *result; switch (value) { case NORMAL: result = "NORMAL"; break; case LEFTEXTENSION: result = "LEFTEXTENSION"; break; case RIGHTEXTENSION: result = "RIGHTEXTENSION"; break; default: result = "?"; break; } return result; } const char * visibleFont(XFontStruct *fs) { static char result[80]; if (fs != NULL) { sprintf(result, "%p(%dx%d %d %#lx)", (void *) fs, fs->max_bounds.width, fs->max_bounds.ascent + fs->max_bounds.descent, fs->max_bounds.descent, (unsigned long) (fs->fid)); } else { strcpy(result, "null"); } return result; } const char * visibleIChars(const IChar *buf, size_t len) { static char *result; static size_t used; if (buf != NULL) { size_t limit = ((len + 1) * 12) + 1; if (limit > used) { used = limit; result = realloc(result, used); } if (result != NULL) { char *dst = result; *dst = '\0'; while (len--) { unsigned value = *buf++; #if OPT_WIDE_CHARS if (value > 255) sprintf(dst, "\\U+%04X", value); else #endif formatAscii(dst, value); dst += strlen(dst); } } } else { FreeAndNull(result); used = 0; } return NonNull(result); } const char * visibleUChar(unsigned chr) { IChar buf[1]; buf[0] = (IChar) chr; return visibleIChars(buf, 1); } const char * visibleEventType(int type) { const char *result = "?"; switch (type) { CASETYPE(KeyPress); CASETYPE(KeyRelease); CASETYPE(ButtonPress); CASETYPE(ButtonRelease); CASETYPE(MotionNotify); CASETYPE(EnterNotify); CASETYPE(LeaveNotify); CASETYPE(FocusIn); CASETYPE(FocusOut); CASETYPE(KeymapNotify); CASETYPE(Expose); CASETYPE(GraphicsExpose); CASETYPE(NoExpose); CASETYPE(VisibilityNotify); CASETYPE(CreateNotify); CASETYPE(DestroyNotify); CASETYPE(UnmapNotify); CASETYPE(MapNotify); CASETYPE(MapRequest); CASETYPE(ReparentNotify); CASETYPE(ConfigureNotify); CASETYPE(ConfigureRequest); CASETYPE(GravityNotify); CASETYPE(ResizeRequest); CASETYPE(CirculateNotify); CASETYPE(CirculateRequest); CASETYPE(PropertyNotify); CASETYPE(SelectionClear); CASETYPE(SelectionRequest); CASETYPE(SelectionNotify); CASETYPE(ColormapNotify); CASETYPE(ClientMessage); CASETYPE(MappingNotify); } return result; } const char * visibleMappingMode(int code) { const char *result = "?"; switch (code) { CASETYPE(MappingModifier); CASETYPE(MappingKeyboard); CASETYPE(MappingPointer); } return result; } const char * visibleNotifyMode(int code) { const char *result = "?"; switch (code) { CASETYPE(NotifyNormal); CASETYPE(NotifyGrab); CASETYPE(NotifyUngrab); CASETYPE(NotifyWhileGrabbed); } return result; } const char * visibleNotifyDetail(int code) { const char *result = "?"; switch (code) { CASETYPE(NotifyAncestor); CASETYPE(NotifyVirtual); CASETYPE(NotifyInferior); CASETYPE(NotifyNonlinear); CASETYPE(NotifyNonlinearVirtual); CASETYPE(NotifyPointer); CASETYPE(NotifyPointerRoot); CASETYPE(NotifyDetailNone); } return result; } const char * visibleSelectionTarget(Display *d, Atom a) { const char *result = "?"; if (a == XA_STRING) { result = "XA_STRING"; } else if (a == XA_TEXT(d)) { result = "XA_TEXT()"; } else if (a == XA_COMPOUND_TEXT(d)) { result = "XA_COMPOUND_TEXT()"; } else if (a == XA_UTF8_STRING(d)) { result = "XA_UTF8_STRING()"; } else if (a == XA_TARGETS(d)) { result = "XA_TARGETS()"; } return result; } #if OPT_TEK4014 const char * visibleTekparse(int code) { static const struct { int code; const char *name; } table[] = { #include "Tekparse.cin" }; const char *result = "?"; Cardinal n; for (n = 0; n < XtNumber(table); ++n) { if (table[n].code == code) { result = table[n].name; break; } } return result; } #endif const char * visibleVTparse(int code) { static const struct { int code; const char *name; } table[] = { #include "VTparse.cin" }; const char *result = "?"; Cardinal n; for (n = 0; n < XtNumber(table); ++n) { if (table[n].code == code) { result = table[n].name; break; } } return result; } const char * visibleXError(int code) { static char temp[80]; const char *result = "?"; switch (code) { CASETYPE(Success); CASETYPE(BadRequest); CASETYPE(BadValue); CASETYPE(BadWindow); CASETYPE(BadPixmap); CASETYPE(BadAtom); CASETYPE(BadCursor); CASETYPE(BadFont); CASETYPE(BadMatch); CASETYPE(BadDrawable); CASETYPE(BadAccess); CASETYPE(BadAlloc); CASETYPE(BadColor); CASETYPE(BadGC); CASETYPE(BadIDChoice); CASETYPE(BadName); CASETYPE(BadLength); CASETYPE(BadImplementation); default: sprintf(temp, "%d", code); result = temp; break; } return result; } #if OPT_TRACE_FLAGS #define isScrnFlag(flag) ((flag) == LINEWRAPPED) static char * ScrnText(LineData *ld) { return visibleIChars(ld->charData, ld->lineSize); } #define SHOW_BAD_LINE(name, ld) \ Trace("OOPS " #name " bad row\n") #define SHOW_SCRN_FLAG(name,code) \ Trace(#name " %s:%s\n", \ code ? "*" : "", \ ScrnText(ld)) void LineClrFlag(LineData *ld, int flag) { if (ld == 0) { SHOW_BAD_LINE(LineClrFlag, ld); assert(0); } else if (isScrnFlag(flag)) { SHOW_SCRN_FLAG(LineClrFlag, 0); } LineFlags(ld) &= ~flag; } void LineSetFlag(LineData *ld, int flag) { if (ld == 0) { SHOW_BAD_LINE(LineSetFlag, ld); assert(0); } else if (isScrnFlag(flag)) { SHOW_SCRN_FLAG(LineSetFlag, 1); } LineFlags(ld) |= flag; } int LineTstFlag(LineData ld, int flag) { int code = 0; if (ld == 0) { SHOW_BAD_LINE(LineTstFlag, ld); } else { code = LineFlags(ld); if (isScrnFlag(flag)) { SHOW_SCRN_FLAG(LineTstFlag, code); } } return code; } #endif /* OPT_TRACE_FLAGS */ const char * TraceAtomName(Display *dpy, Atom atom) { static char *result; free(result); if (atom != 0) { result = XGetAtomName(dpy, atom); } else { result = x_strdup("NONE"); } return result; } /* * Trace the normal or alternate screen, showing color values up to 16, e.g., * for debugging with vttest. */ void TraceScreen(XtermWidget xw, int whichBuf) { TScreen *screen = TScreenOf(xw); if (screen->editBuf_index[whichBuf]) { int row; TRACE(("TraceScreen %d:\n", whichBuf)); for (row = 0; row <= LastRowNumber(screen); ++row) { LineData *ld = getLineData(screen, row); TRACE((" %3d:", row)); if (ld != NULL) { int col; for (col = 0; col < ld->lineSize; ++col) { int ch = (int) ld->charData[col]; if (ch < ' ') ch = ' '; if (ch >= 127) ch = '#'; TRACE(("%c", ch)); } TRACE((":\n")); #if 0 TRACE((" xx:")); for (col = 0; col < ld->lineSize; ++col) { unsigned attrs = ld->attribs[col]; char ch; if (attrs & PROTECTED) { ch = '*'; } else if (attrs & BLINK) { ch = 'B'; } else if (attrs & CHARDRAWN) { ch = '+'; } else { ch = ' '; } TRACE(("%c", ch)); } TRACE((":\n")); #endif #if 0 TRACE((" fg:")); for (col = 0; col < ld->lineSize; ++col) { unsigned fg = extract_fg(xw, ld->color[col], ld->attribs[col]); if (fg > 15) fg = 15; TRACE(("%1x", fg)); } TRACE((":\n")); TRACE((" bg:")); for (col = 0; col < ld->lineSize; ++col) { unsigned bg = extract_bg(xw, ld->color[col], ld->attribs[col]); if (bg > 15) bg = 15; TRACE(("%1x", bg)); } TRACE((":\n")); #endif } else { TRACE(("null lineData\n")); } } } else { TRACE(("TraceScreen %d is nil\n", whichBuf)); } } static char * formatEventMask(char *target, unsigned source, Boolean buttons) { #define DATA(name) { name ## Mask, #name } static struct { unsigned mask; const char *name; } table[] = { DATA(Shift), DATA(Lock), DATA(Control), DATA(Mod1), DATA(Mod2), DATA(Mod3), DATA(Mod4), DATA(Mod5), DATA(Button1), DATA(Button2), DATA(Button3), DATA(Button4), DATA(Button5), }; #undef DATA Cardinal n; char marker = L_CURL; char *base = target; for (n = 0; n < XtNumber(table); ++n) { if (!buttons && (table[n].mask >= Button1Mask)) continue; if ((table[n].mask & source)) { UIntClr(source, table[n].mask); sprintf(target, "%c%s", marker, table[n].name); target += strlen(target); marker = '|'; } } if (source != 0) { sprintf(target, "%c?%#x", marker, source); target += strlen(target); marker = '|'; } if (marker == L_CURL) *target++ = L_CURL; *target++ = R_CURL; *target = '\0'; return base; } void TraceEvent(const char *tag, XEvent *ev, String *params, const Cardinal *num_params) { char mask_buffer[160]; TRACE(("Event #%lu %s: %#lx %s", ev->xany.serial, tag, ev->xany.window, visibleEventType(ev->type))); switch (ev->type) { case KeyPress: /* FALLTHRU */ case KeyRelease: TRACE((" keycode 0x%04X %s", ev->xkey.keycode, formatEventMask(mask_buffer, ev->xkey.state, False))); break; case ButtonPress: /* FALLTHRU */ case ButtonRelease: TRACE((" button %u state %#x %s", ev->xbutton.button, ev->xbutton.state, formatEventMask(mask_buffer, ev->xbutton.state, True))); break; case MotionNotify: TRACE((" (%d,%d) state %#x %s", ev->xmotion.y_root, ev->xmotion.x_root, ev->xmotion.state, formatEventMask(mask_buffer, ev->xmotion.state, True))); break; case EnterNotify: case LeaveNotify: TRACE((" at %d,%d root %d,%d %s %s", ev->xcrossing.y, ev->xcrossing.x, ev->xcrossing.y_root, ev->xcrossing.x_root, visibleNotifyMode(ev->xcrossing.mode), visibleNotifyDetail(ev->xcrossing.detail))); break; case FocusIn: case FocusOut: TRACE((" %s %s", visibleNotifyMode(ev->xfocus.mode), visibleNotifyDetail(ev->xfocus.detail))); break; case MapNotify: TRACE((" event %#lx %s", ev->xmap.event, ev->xmap.override_redirect ? "override" : "")); break; case UnmapNotify: TRACE((" event %#lx %s", ev->xunmap.event, ev->xunmap.from_configure ? "configure" : "")); break; case ReparentNotify: TRACE((" at %d,%d event %#lx parent %#lx %s", ev->xreparent.y, ev->xreparent.x, ev->xreparent.event, ev->xreparent.parent, ev->xreparent.override_redirect ? "override" : "")); break; case ConfigureNotify: TRACE((" at %d,%d size %dx%d bd %d above %#lx", ev->xconfigure.y, ev->xconfigure.x, ev->xconfigure.height, ev->xconfigure.width, ev->xconfigure.border_width, ev->xconfigure.above)); break; case CreateNotify: TRACE((" at %d,%d size %dx%d bd %d", ev->xcreatewindow.y, ev->xcreatewindow.x, ev->xcreatewindow.height, ev->xcreatewindow.width, ev->xcreatewindow.border_width)); break; case ResizeRequest: TRACE((" size %dx%d", ev->xresizerequest.height, ev->xresizerequest.width)); break; case PropertyNotify: TRACE((" %s %s", TraceAtomName(XtDisplay(toplevel), ev->xproperty.atom), ((ev->xproperty.state == PropertyNewValue) ? "NewValue" : ((ev->xproperty.state == PropertyDelete) ? "Delete" : "?")))); break; case Expose: TRACE((" at %d,%d size %dx%d count %d", ev->xexpose.y, ev->xexpose.x, ev->xexpose.height, ev->xexpose.width, ev->xexpose.count)); break; case MappingNotify: TRACE((" %s first_keycode %d count %d", visibleMappingMode(ev->xmapping.request), ev->xmapping.first_keycode, ev->xmapping.count)); break; case VisibilityNotify: TRACE((" state %d", ev->xvisibility.state)); break; case KeymapNotify: { Cardinal j; for (j = 0; j < XtNumber(ev->xkeymap.key_vector); ++j) { if (ev->xkeymap.key_vector[j] != 0) { Cardinal k; for (k = 0; k < CHAR_BIT; ++k) { if (ev->xkeymap.key_vector[j] & (1 << k)) { TRACE((" key%u", (j * CHAR_BIT) + k)); } } } } } break; case NoExpose: TRACE((" send_event:%d display %p major:%d minor:%d", ev->xnoexpose.send_event, (void *) ev->xnoexpose.display, ev->xnoexpose.major_code, ev->xnoexpose.minor_code)); break; case GraphicsExpose: TRACE((" send_event:%d display %p major:%d minor:%d", ev->xgraphicsexpose.send_event, (void *) ev->xgraphicsexpose.display, ev->xgraphicsexpose.major_code, ev->xgraphicsexpose.minor_code)); break; case SelectionClear: TRACE((" selection:%s", TraceAtomName(ev->xselectionclear.display, ev->xselectionclear.selection))); break; case SelectionRequest: TRACE((" owner:%#lx requestor:%#lx", ev->xselectionrequest.owner, ev->xselectionrequest.requestor)); TRACE((" selection:%s", TraceAtomName(ev->xselectionrequest.display, ev->xselectionrequest.selection))); TRACE((" target:%s", TraceAtomName(ev->xselectionrequest.display, ev->xselectionrequest.target))); TRACE((" property:%s", TraceAtomName(ev->xselectionrequest.display, ev->xselectionrequest.property))); break; case ClientMessage: TRACE((" message_type:%s format:%d", TraceAtomName(ev->xselectionrequest.display, ev->xclient.message_type), ev->xclient.format)); break; default: TRACE((":FIXME")); break; } TRACE(("\n")); if (params != NULL && *num_params != 0) { Cardinal n; for (n = 0; n < *num_params; ++n) { TRACE((" param[%d] = %s\n", n, params[n])); } } } #if OPT_RENDERFONT && OPT_WIDE_CHARS void TraceFallback(XtermWidget xw, const char *tag, unsigned wc, int n, XftFont *font) { TScreen *screen = TScreenOf(xw); XGlyphInfo gi; int expect = my_wcwidth((wchar_t) wc); int hijack = mk_wcwidth_cjk((wchar_t) wc); int actual; XftTextExtents32(screen->display, font, &wc, 1, &gi); actual = ((gi.xOff + FontWidth(screen) - 1) / FontWidth(screen)); TRACE(("FALLBACK #%d %s U+%04X %d,%d pos," " %d,%d off," " %dx%d size," " %d/%d next," " %d vs %d/%d cells%s\n", n + 1, tag, wc, gi.y, gi.x, gi.yOff, gi.xOff, gi.height, gi.width, font->max_advance_width, FontWidth(screen), actual, expect, hijack, ((actual != expect) ? ((actual == hijack) ? " OOPS" : " oops") : ""))); } #endif /* OPT_RENDERFONT */ void TraceFocus(Widget w, XEvent *ev) { TRACE(("trace_focus event type %d:%s\n", ev->type, visibleEventType(ev->type))); switch (ev->type) { case FocusIn: case FocusOut: { XFocusChangeEvent *event = (XFocusChangeEvent *) ev; TRACE(("\tdetail: %s\n", visibleNotifyDetail(event->detail))); TRACE(("\tmode: %s\n", visibleNotifyMode(event->mode))); TRACE(("\twindow: %#lx\n", event->window)); } break; case EnterNotify: case LeaveNotify: { XCrossingEvent *event = (XCrossingEvent *) ev; TRACE(("\tdetail: %s\n", visibleNotifyDetail(event->detail))); TRACE(("\tmode: %s\n", visibleNotifyMode(event->mode))); TRACE(("\twindow: %#lx\n", event->window)); TRACE(("\tfocus: %d\n", event->focus)); TRACE(("\troot: %#lx\n", event->root)); TRACE(("\tsubwindow: %#lx\n", event->subwindow)); } break; } while (w != NULL) { TRACE(("w %p -> %#lx\n", (void *) w, XtWindow(w))); w = XtParent(w); } } void TraceSizeHints(XSizeHints * hints) { TRACE(("size hints:\n")); if (hints->flags & (USPosition | PPosition)) { TRACE((" position %d,%d%s%s\n", hints->y, hints->x, (hints->flags & USPosition) ? " user" : "", (hints->flags & PPosition) ? " prog" : "")); } if (hints->flags & (USSize | PSize)) { TRACE((" size %d,%d%s%s\n", hints->height, hints->width, (hints->flags & USSize) ? " user" : "", (hints->flags & PSize) ? " prog" : "")); } if (hints->flags & PMinSize) { TRACE((" min %d,%d\n", hints->min_height, hints->min_width)); } if (hints->flags & PMaxSize) { TRACE((" max %d,%d\n", hints->max_height, hints->max_width)); } if (hints->flags & PResizeInc) { TRACE((" inc %d,%d\n", hints->height_inc, hints->width_inc)); } else { TRACE((" inc NONE!\n")); } if (hints->flags & PAspect) { TRACE((" min aspect %d/%d\n", hints->min_aspect.y, hints->min_aspect.y)); TRACE((" max aspect %d/%d\n", hints->max_aspect.y, hints->max_aspect.y)); } if (hints->flags & PBaseSize) { TRACE((" base %d,%d\n", hints->base_height, hints->base_width)); } if (hints->flags & PWinGravity) { TRACE((" gravity %d\n", hints->win_gravity)); } } static void TraceEventMask(const char *tag, long mask) { #define DATA(name) { name##Mask, #name } /* *INDENT-OFF* */ static struct { long mask; const char *name; } table[] = { DATA(KeyPress), DATA(KeyRelease), DATA(ButtonPress), DATA(ButtonRelease), DATA(EnterWindow), DATA(LeaveWindow), DATA(PointerMotion), DATA(PointerMotionHint), DATA(Button1Motion), DATA(Button2Motion), DATA(Button3Motion), DATA(Button4Motion), DATA(Button5Motion), DATA(ButtonMotion), DATA(KeymapState), DATA(Exposure), DATA(VisibilityChange), DATA(StructureNotify), DATA(ResizeRedirect), DATA(SubstructureNotify), DATA(SubstructureRedirect), DATA(FocusChange), DATA(PropertyChange), DATA(ColormapChange), DATA(OwnerGrabButton), }; #undef DATA Cardinal n; /* *INDENT-ON* */ for (n = 0; n < XtNumber(table); ++n) { if (table[n].mask & mask) { TRACE(("%s %s\n", tag, table[n].name)); } } } void TraceWindowAttributes(XWindowAttributes * attrs) { TRACE(("window attributes:\n")); TRACE((" position %d,%d\n", attrs->y, attrs->x)); TRACE((" size %dx%d\n", attrs->height, attrs->width)); TRACE((" border %d\n", attrs->border_width)); TRACE((" depth %d\n", attrs->depth)); TRACE((" bit_gravity %d\n", attrs->bit_gravity)); TRACE((" win_gravity %d\n", attrs->win_gravity)); TRACE((" root %#lx\n", (long) attrs->root)); TRACE((" class %s\n", ((attrs->class == InputOutput) ? "InputOutput" : ((attrs->class == InputOnly) ? "InputOnly" : "unknown")))); TRACE((" map_state %s\n", ((attrs->map_state == IsUnmapped) ? "IsUnmapped" : ((attrs->map_state == IsUnviewable) ? "IsUnviewable" : ((attrs->map_state == IsViewable) ? "IsViewable" : "unknown"))))); TRACE((" all_events\n")); TraceEventMask(" ", attrs->all_event_masks); TRACE((" your_events\n")); TraceEventMask(" ", attrs->your_event_mask); TRACE((" no_propagate\n")); TraceEventMask(" ", attrs->do_not_propagate_mask); } void TraceWMSizeHints(XtermWidget xw) { XSizeHints sizehints = xw->hints; getXtermSizeHints(xw); TraceSizeHints(&xw->hints); xw->hints = sizehints; } const char * ModifierName(unsigned modifier) { const char *s = ""; if (modifier & ShiftMask) s = " Shift"; else if (modifier & LockMask) s = " Lock"; else if (modifier & ControlMask) s = " Control"; else if (modifier & Mod1Mask) s = " Mod1"; else if (modifier & Mod2Mask) s = " Mod2"; else if (modifier & Mod3Mask) s = " Mod3"; else if (modifier & Mod4Mask) s = " Mod4"; else if (modifier & Mod5Mask) s = " Mod5"; return s; } void TraceTranslations(const char *name, Widget w) { String result; XErrorHandler save = XSetErrorHandler(ignore_x11_error); XtTranslations xlations; Widget xcelerat; TRACE(("TraceTranslations for %s (widget %#lx) " TRACE_L "\n", name, (long) w)); if (w) { XtVaGetValues(w, XtNtranslations, &xlations, XtNaccelerators, &xcelerat, (XtPointer) 0); TRACE(("... xlations %#08lx\n", (long) xlations)); TRACE(("... xcelerat %#08lx\n", (long) xcelerat)); result = _XtPrintXlations(w, xlations, xcelerat, True); TRACE(("%s\n", NonNull(result))); if (result) XFree((char *) result); } else { TRACE(("none (widget is null)\n")); } TRACE((TRACE_R "\n")); XSetErrorHandler(save); } XtGeometryResult TraceResizeRequest(const char *fn, int ln, Widget w, unsigned reqwide, unsigned reqhigh, Dimension *gotwide, Dimension *gothigh) { XtGeometryResult rc; TRACE(("%s@%d ResizeRequest %ux%u\n", fn, ln, reqhigh, reqwide)); rc = XtMakeResizeRequest((Widget) w, (Dimension) reqwide, (Dimension) reqhigh, gotwide, gothigh); TRACE(("... ResizeRequest -> ")); if (gothigh && gotwide) TRACE(("%dx%d ", *gothigh, *gotwide)); TRACE(("(%d)\n", rc)); return rc; } #define XRES_S(name) Trace(#name " = %s\n", NonNull(resp->name)) #define XRES_B(name) Trace(#name " = %s\n", MtoS(resp->name)) #define XRES_I(name) Trace(#name " = %d\n", resp->name) void TraceXtermResources(void) { XTERM_RESOURCE *resp = &resource; Trace("XTERM_RESOURCE settings:\n"); XRES_S(icon_geometry); XRES_S(title); XRES_S(icon_hint); XRES_S(icon_name); XRES_S(term_name); XRES_S(tty_modes); XRES_I(minBufSize); XRES_I(maxBufSize); XRES_B(hold_screen); XRES_B(utmpInhibit); XRES_B(utmpDisplayId); XRES_B(messages); XRES_S(menuLocale); XRES_S(omitTranslation); XRES_S(keyboardType); #ifdef HAVE_LIB_XCURSOR XRES_S(cursorTheme); #endif #if OPT_PRINT_ON_EXIT XRES_I(printModeNow); XRES_I(printModeOnXError); XRES_I(printOptsNow); XRES_I(printOptsOnXError); XRES_S(printFileNow); XRES_S(printFileOnXError); #endif #if OPT_SUNPC_KBD XRES_B(sunKeyboard); #endif #if OPT_HP_FUNC_KEYS XRES_B(hpFunctionKeys); #endif #if OPT_SCO_FUNC_KEYS XRES_B(scoFunctionKeys); #endif #if OPT_SUN_FUNC_KEYS XRES_B(sunFunctionKeys); #endif #if OPT_INITIAL_ERASE XRES_B(ptyInitialErase); XRES_B(backarrow_is_erase); #endif XRES_B(useInsertMode); #if OPT_ZICONBEEP XRES_I(zIconBeep); XRES_S(zIconFormat); #endif #if OPT_PTY_HANDSHAKE XRES_B(wait_for_map); XRES_B(ptyHandshake); XRES_B(ptySttySize); #endif #if OPT_REPORT_CCLASS XRES_B(reportCClass); #endif #if OPT_REPORT_COLORS XRES_B(reportColors); #endif #if OPT_REPORT_FONTS XRES_B(reportFonts); #endif #if OPT_REPORT_ICONS XRES_B(reportIcons); #endif #if OPT_SAME_NAME XRES_B(sameName); #endif #if OPT_SESSION_MGT XRES_B(sessionMgt); #endif #if OPT_TOOLBAR XRES_B(toolBar); #endif #if OPT_MAXIMIZE XRES_B(maximized); XRES_S(fullscreen_s); #endif #if USE_DOUBLE_BUFFER XRES_B(buffered); XRES_I(buffered_fps); #endif } void TraceArgv(const char *tag, char **argv) { TRACE(("%s:\n", tag)); if (argv != NULL) { int n = 0; while (*argv != NULL) { TRACE((" %d:%s\n", n++, *argv++)); } } } static char * parse_option(char *dst, String src, int first) { char *s; if (!strncmp(src, "-/+", (size_t) 3)) { dst[0] = (char) first; strcpy(dst + 1, src + 3); } else { strcpy(dst, src); } for (s = dst; *s != '\0'; s++) { if (*s == '#' || *s == '%' || *s == 'S') { s[1] = '\0'; } else if (*s == ' ') { *s = '\0'; break; } } return dst; } static Bool same_option(OptionHelp * opt, XrmOptionDescRec * res) { char temp[BUFSIZ]; return !strcmp(parse_option(temp, opt->opt, res->option[0]), res->option); } static Bool standard_option(String opt) { static const char *table[] = { "+rv", "+synchronous", "-background", "-bd", "-bg", "-bordercolor", "-borderwidth", "-bw", "-display", "-fg", "-fn", "-font", "-foreground", "-geometry", "-iconic", "-name", "-reverse", "-rv", "-selectionTimeout", "-synchronous", "-title", "-xnllanguage", "-xrm", "-xtsessionID", }; Cardinal n; char temp[BUFSIZ]; opt = parse_option(temp, opt, '-'); for (n = 0; n < XtNumber(table); n++) { if (!strcmp(opt, table[n])) return True; } return False; } /* * Analyse the options/help messages for inconsistencies. */ void TraceOptions(OptionHelp * options, XrmOptionDescRec * resources, Cardinal res_count) { OptionHelp *opt_array = sortedOpts(options, resources, res_count); size_t j, k; XrmOptionDescRec *res_array = sortedOptDescs(resources, res_count); Bool first, found; TRACE(("Checking options-tables for inconsistencies:\n")); #if 0 TRACE(("Options listed in help-message:\n")); for (j = 0; options[j].opt != 0; j++) TRACE(("%5d %-28s %s\n", j, opt_array[j].opt, opt_array[j].desc)); TRACE(("Options listed in resource-table:\n")); for (j = 0; j < res_count; j++) TRACE(("%5d %-28s %s\n", j, res_array[j].option, res_array[j].specifier)); #endif /* list all options[] not found in resources[] */ for (j = 0, first = True; options[j].opt != NULL; j++) { found = False; for (k = 0; k < res_count; k++) { if (same_option(&opt_array[j], &res_array[k])) { found = True; break; } } if (!found) { if (first) { TRACE(("Options listed in help, not found in resource list:\n")); first = False; } TRACE((" %-28s%s\n", opt_array[j].opt, standard_option(opt_array[j].opt) ? " (standard)" : "")); } } /* list all resources[] not found in options[] */ for (j = 0, first = True; j < res_count; j++) { found = False; for (k = 0; options[k].opt != NULL; k++) { if (same_option(&opt_array[k], &res_array[j])) { found = True; break; } } if (!found) { if (first) { TRACE(("Resource list items not found in options-help:\n")); first = False; } TRACE((" %s\n", res_array[j].option)); } } TRACE(("Resource list items that will be ignored by XtOpenApplication:\n")); for (j = 0; j < res_count; j++) { switch (res_array[j].argKind) { case XrmoptionSkipArg: TRACE((" %-28s {param}\n", res_array[j].option)); break; case XrmoptionSkipNArgs: TRACE((" %-28s {%ld params}\n", res_array[j].option, (long) res_array[j].value)); break; case XrmoptionSkipLine: TRACE((" %-28s {remainder of line}\n", res_array[j].option)); break; case XrmoptionIsArg: case XrmoptionNoArg: case XrmoptionResArg: case XrmoptionSepArg: case XrmoptionStickyArg: default: break; } } } #else extern void empty_trace(void); void empty_trace(void) { } #endif xterm-399/misc.c0000644000000000000000000061532314773341646012365 0ustar rootroot/* $XTermId: misc.c,v 1.1112 2025/04/02 23:09:26 tom Exp $ */ /* * Copyright 1999-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * * * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if HAVE_X11_SUNKEYSYM_H #include #endif #ifdef HAVE_LIBXPM #include #endif #ifdef HAVE_LANGINFO_CODESET #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_MKSTEMP #define MakeTemp(f) mkstemp(f) #else #define MakeTemp(f) mktemp(f) #endif #if USE_DOUBLE_BUFFER #include #endif #if OPT_WIDE_CHARS #include #endif #if OPT_TEK4014 #define OUR_EVENT(event,Type) \ (event.type == Type && \ (event.xcrossing.window == XtWindow(XtParent(xw)) || \ (tekWidget && \ event.xcrossing.window == XtWindow(XtParent(tekWidget))))) #else #define OUR_EVENT(event,Type) \ (event.type == Type && \ (event.xcrossing.window == XtWindow(XtParent(xw)))) #endif #define VB_DELAY screen->visualBellDelay #define EVENT_DELAY TScreenOf(term)->nextEventDelay static Boolean xtermAllocColor(XtermWidget, XColor *, const char *); static Cursor make_hidden_cursor(XtermWidget); #if OPT_EXEC_XTERM /* Like readlink(2), but returns a malloc()ed buffer, or NULL on error; adapted from libc docs */ static char * Readlink(const char *filename) { char *buf = NULL; size_t size = 100; for (;;) { int n; char *tmp = TypeRealloc(char, size, buf); if (tmp == NULL) { free(buf); return NULL; } buf = tmp; memset(buf, 0, size); n = (int) readlink(filename, buf, size); if (n < 0) { free(buf); return NULL; } if ((unsigned) n < size) { return buf; } size *= 2; } } #endif /* OPT_EXEC_XTERM */ static void Sleep(int msec) { static struct timeval select_timeout; select_timeout.tv_sec = 0; select_timeout.tv_usec = msec * 1000; select(0, NULL, NULL, NULL, &select_timeout); } static void selectwindow(XtermWidget xw, int flag) { TScreen *screen = TScreenOf(xw); TRACE(("selectwindow(%d) flag=%d\n", screen->select, flag)); #if OPT_TEK4014 if (TEK4014_ACTIVE(xw)) { if (!Ttoggled) TCursorToggle(tekWidget, TOGGLE); screen->select |= flag; if (!Ttoggled) TCursorToggle(tekWidget, TOGGLE); } else #endif { #if OPT_INPUT_METHOD TInput *input = lookupTInput(xw, (Widget) xw); if (input && input->xic) XSetICFocus(input->xic); #endif if (screen->cursor_state && CursorMoved(screen)) HideCursor(xw); screen->select |= flag; if (screen->cursor_state) ShowCursor(xw); } GetScrollLock(screen); } static void unselectwindow(XtermWidget xw, int flag) { TScreen *screen = TScreenOf(xw); TRACE(("unselectwindow(%d) flag=%d\n", screen->select, flag)); if (screen->hide_pointer && screen->pointer_mode < pFocused) { screen->hide_pointer = False; xtermDisplayPointer(xw); } screen->select &= ~flag; if (!screen->always_highlight) { #if OPT_TEK4014 if (TEK4014_ACTIVE(xw)) { if (!Ttoggled) TCursorToggle(tekWidget, TOGGLE); if (!Ttoggled) TCursorToggle(tekWidget, TOGGLE); } else #endif { #if OPT_INPUT_METHOD TInput *input = lookupTInput(xw, (Widget) xw); if (input && input->xic) XUnsetICFocus(input->xic); #endif if (screen->cursor_state && CursorMoved(screen)) HideCursor(xw); if (screen->cursor_state) ShowCursor(xw); } } } static void DoSpecialEnterNotify(XtermWidget xw, XEnterWindowEvent *ev) { TScreen *screen = TScreenOf(xw); TRACE(("DoSpecialEnterNotify(%d)\n", screen->select)); TRACE_FOCUS(xw, ev); if (((ev->detail) != NotifyInferior) && ev->focus && !(screen->select & FOCUS)) selectwindow(xw, INWINDOW); } static void DoSpecialLeaveNotify(XtermWidget xw, XEnterWindowEvent *ev) { TScreen *screen = TScreenOf(xw); TRACE(("DoSpecialLeaveNotify(%d)\n", screen->select)); TRACE_FOCUS(xw, ev); if (((ev->detail) != NotifyInferior) && ev->focus && !(screen->select & FOCUS)) unselectwindow(xw, INWINDOW); } #ifndef XUrgencyHint #define XUrgencyHint (1L << 8) /* X11R5 does not define */ #endif static void setXUrgency(XtermWidget xw, Bool enable) { TScreen *screen = TScreenOf(xw); if (screen->bellIsUrgent) { XWMHints *h = XGetWMHints(screen->display, VShellWindow(xw)); if (h != NULL) { if (enable && !(screen->select & FOCUS)) { h->flags |= XUrgencyHint; } else { h->flags &= ~XUrgencyHint; } XSetWMHints(screen->display, VShellWindow(xw), h); } } } void do_xevents(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (xtermAppPending() || GetBytesAvailable(screen->display) > 0) { xevents(xw); } } void xtermDisplayPointer(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->Vshow) { if (screen->hide_pointer) { TRACE(("Display text pointer (hidden)\n")); XDefineCursor(screen->display, VWindow(screen), screen->hidden_cursor); } else { TRACE(("Display text pointer (visible)\n")); recolor_cursor(screen, screen->pointer_cursor, T_COLOR(screen, MOUSE_FG), T_COLOR(screen, MOUSE_BG)); XDefineCursor(screen->display, VWindow(screen), screen->pointer_cursor); } } } void xtermShowPointer(XtermWidget xw, Bool enable) { static int tried = -1; TScreen *screen = TScreenOf(xw); #if OPT_TEK4014 if (TEK4014_SHOWN(xw)) enable = True; #endif /* * Whether we actually hide the pointer depends on the pointer-mode and * the mouse-mode: */ if (!enable) { switch (screen->pointer_mode) { case pNever: enable = True; break; case pNoMouse: if (screen->send_mouse_pos != MOUSE_OFF) enable = True; break; case pAlways: case pFocused: break; } } if (enable) { if (screen->hide_pointer) { screen->hide_pointer = False; xtermDisplayPointer(xw); switch (screen->send_mouse_pos) { case ANY_EVENT_MOUSE: break; default: MotionOff(screen, xw); break; } } } else if (!(screen->hide_pointer) && (tried <= 0)) { if (screen->hidden_cursor == 0) { screen->hidden_cursor = make_hidden_cursor(xw); } if (screen->hidden_cursor == 0) { tried = 1; } else { tried = 0; screen->hide_pointer = True; xtermDisplayPointer(xw); MotionOn(screen, xw); } } } /* true if p contains q */ #define ExposeContains(p,q) \ ((p)->y <= (q)->y \ && (p)->x <= (q)->x \ && ((p)->y + (p)->height) >= ((q)->y + (q)->height) \ && ((p)->x + (p)->width) >= ((q)->x + (q)->width)) static XtInputMask mergeExposeEvents(XEvent *target) { XEvent next_event; XExposeEvent *p; XtAppNextEvent(app_con, target); p = (XExposeEvent *) target; while (XtAppPending(app_con) && XtAppPeekEvent(app_con, &next_event) && next_event.type == Expose) { Boolean merge_this = False; XExposeEvent *q = (XExposeEvent *) (&next_event); XtAppNextEvent(app_con, &next_event); TRACE_EVENT("pending", &next_event, (String *) 0, NULL); /* * If either window is contained within the other, merge the events. * The traces show that there are also cases where a full repaint of * a window is broken into 3 or more rectangles, which do not arrive * in the same instant. We could merge those if xterm were modified * to skim several events ahead. */ if (p->window == q->window) { if (ExposeContains(p, q)) { TRACE(("pending Expose...merged forward\n")); merge_this = True; next_event = *target; } else if (ExposeContains(q, p)) { TRACE(("pending Expose...merged backward\n")); merge_this = True; } } if (!merge_this) { XtDispatchEvent(target); } *target = next_event; } XtDispatchEvent(target); return XtAppPending(app_con); } /* * On entry, we have peeked at the event queue and see a configure-notify * event. Remove that from the queue so we can look further. * * Then, as long as there is a configure-notify event in the queue, remove * that. If the adjacent events are for different windows, process the older * event and update the event used for comparing windows. If they are for the * same window, only the newer event is of interest. * * Finally, process the (remaining) configure-notify event. */ static XtInputMask mergeConfigureEvents(XEvent *target) { XEvent next_event; XConfigureEvent *p; XtAppNextEvent(app_con, target); p = (XConfigureEvent *) target; if (XtAppPending(app_con) && XtAppPeekEvent(app_con, &next_event) && next_event.type == ConfigureNotify) { Boolean merge_this = False; XConfigureEvent *q = (XConfigureEvent *) (&next_event); XtAppNextEvent(app_con, &next_event); TRACE_EVENT("pending", &next_event, (String *) 0, NULL); if (p->window == q->window) { TRACE(("pending Configure...merged\n")); merge_this = True; } if (!merge_this) { TRACE(("pending Configure...skipped\n")); XtDispatchEvent(target); } *target = next_event; } XtDispatchEvent(target); return XtAppPending(app_con); } #define SAME(a,b,name) ((a)->xbutton.name == (b)->xbutton.name) #define SameButtonEvent(a,b) ( \ SAME(a,b,type) && \ SAME(a,b,serial) && \ SAME(a,b,send_event) && \ SAME(a,b,display) && \ SAME(a,b,window) && \ SAME(a,b,root) && \ SAME(a,b,subwindow) && \ SAME(a,b,time) && \ SAME(a,b,x) && \ SAME(a,b,y) && \ SAME(a,b,x_root) && \ SAME(a,b,y_root) && \ SAME(a,b,state) && \ SAME(a,b,button) && \ SAME(a,b,same_screen)) /* * Work around a bug in the X mouse code, which delivers duplicate events. */ static XtInputMask mergeButtonEvents(XEvent *target) { XEvent next_event; XButtonEvent *p; XtAppNextEvent(app_con, target); p = (XButtonEvent *) target; if (XtAppPending(app_con) && XtAppPeekEvent(app_con, &next_event) && SameButtonEvent(target, &next_event)) { Boolean merge_this = False; XButtonEvent *q = (XButtonEvent *) (&next_event); XtAppNextEvent(app_con, &next_event); TRACE_EVENT("pending", &next_event, (String *) 0, NULL); if (p->window == q->window) { TRACE(("pending ButtonEvent...merged\n")); merge_this = True; } if (!merge_this) { TRACE(("pending ButtonEvent...skipped\n")); XtDispatchEvent(target); } *target = next_event; } XtDispatchEvent(target); return XtAppPending(app_con); } /* * Filter redundant Expose- and ConfigureNotify-events. This is limited to * adjacent events because there could be other event-loop processing. Absent * that limitation, it might be possible to scan ahead to find when the screen * would be completely updated, skipping unnecessary re-repainting before that * point. * * Note: all cases should allow doing XtAppNextEvent if result is true. */ XtInputMask xtermAppPending(void) { XtInputMask result = XtAppPending(app_con); XEvent this_event; Boolean found = False; while (result && XtAppPeekEvent(app_con, &this_event)) { found = True; TRACE_EVENT("pending", &this_event, (String *) 0, NULL); if (this_event.type == Expose) { result = mergeExposeEvents(&this_event); } else if (this_event.type == ConfigureNotify) { result = mergeConfigureEvents(&this_event); } else if (this_event.type == ButtonPress || this_event.type == ButtonRelease) { result = mergeButtonEvents(&this_event); } else { break; } } /* * With NetBSD, closing a shell results in closing the X input event * stream, which interferes with the "-hold" option. Wait a short time in * this case, to avoid max'ing the CPU. */ if (hold_screen && caught_intr && !found) { Sleep(EVENT_DELAY); } return result; } void xevents(XtermWidget xw) { TScreen *screen = TScreenOf(xw); XEvent event; XtInputMask input_mask; if (need_cleanup) NormalExit(); if (screen->scroll_amt) FlushScroll(xw); /* * process timeouts, relying on the fact that XtAppProcessEvent * will process the timeout and return without blockng on the * XEvent queue. Other sources i.e., the pty are handled elsewhere * with select(). */ while ((input_mask = xtermAppPending()) != 0) { if (input_mask & XtIMTimer) XtAppProcessEvent(app_con, (XtInputMask) XtIMTimer); #if OPT_SESSION_MGT /* * Session management events are alternative input events. Deal with * them in the same way. */ else if (input_mask & XtIMAlternateInput) XtAppProcessEvent(app_con, (XtInputMask) XtIMAlternateInput); #endif else break; } /* * If there are no XEvents, don't wait around... */ if ((input_mask & XtIMXEvent) != XtIMXEvent) return; do { /* * This check makes xterm hang when in mouse hilite tracking mode. * We simply ignore all events except for those not passed down to * this function, e.g., those handled in in_put(). */ if (screen->waitingForTrackInfo) { Sleep(EVENT_DELAY); return; } XtAppNextEvent(app_con, &event); /* * Hack to get around problems with the toolkit throwing away * eventing during the exclusive grab of the menu popup. By * looking at the event ourselves we make sure that we can * do the right thing. */ if (OUR_EVENT(event, EnterNotify)) { DoSpecialEnterNotify(xw, &event.xcrossing); } else if (OUR_EVENT(event, LeaveNotify)) { DoSpecialLeaveNotify(xw, &event.xcrossing); } else if (event.xany.type == MotionNotify && event.xcrossing.window == XtWindow(xw)) { switch (screen->send_mouse_pos) { case ANY_EVENT_MOUSE: #if OPT_DEC_LOCATOR case DEC_LOCATOR: #endif /* OPT_DEC_LOCATOR */ SendMousePosition(xw, &event); xtermShowPointer(xw, True); continue; case BTN_EVENT_MOUSE: SendMousePosition(xw, &event); xtermShowPointer(xw, True); } } /* * If the event is interesting (and not a keyboard event), turn the * mouse pointer back on. */ if (screen->hide_pointer) { if (screen->pointer_mode >= pFocused) { switch (event.xany.type) { case MotionNotify: xtermShowPointer(xw, True); break; } } else { switch (event.xany.type) { case KeyPress: case KeyRelease: case ButtonPress: case ButtonRelease: /* also these... */ case Expose: case GraphicsExpose: case NoExpose: case PropertyNotify: case ClientMessage: break; default: xtermShowPointer(xw, True); break; } } } if (!event.xany.send_event || screen->allowSendEvents || ((event.xany.type != KeyPress) && (event.xany.type != KeyRelease) && (event.xany.type != ButtonPress) && (event.xany.type != ButtonRelease))) { if (event.xany.type == MappingNotify) { XRefreshKeyboardMapping(&(event.xmapping)); VTInitModifiers(xw); } XtDispatchEvent(&event); } } while (xtermAppPending() & XtIMXEvent); } static Cursor make_hidden_cursor(XtermWidget xw) { TScreen *screen = TScreenOf(xw); Cursor c; Display *dpy = screen->display; XFontStruct *fn; static XColor dummy; /* * Prefer nil2 (which is normally available) to "fixed" (which is supposed * to be "always" available), since it's a smaller glyph in case the * server insists on drawing _something_. */ TRACE(("Ask for nil2 font\n")); if ((fn = xtermLoadQueryFont(xw, "nil2")) == NULL) { TRACE(("...Ask for fixed font\n")); fn = xtermLoadQueryFont(xw, DEFFONT); } if (fn != NULL) { /* a space character seems to work as a cursor (dots are not needed) */ c = XCreateGlyphCursor(dpy, fn->fid, fn->fid, 'X', ' ', &dummy, &dummy); XFreeFont(dpy, fn); } else { c = None; } TRACE(("XCreateGlyphCursor ->%#lx\n", c)); return c; } /* * Xlib uses Xcursor to customize cursor coloring, which interferes with * xterm's pointerColor resource. Work around this by providing our own * default theme. Testing seems to show that we only have to provide this * until the window is initialized. */ #ifdef HAVE_LIB_XCURSOR void init_colored_cursor(Display *dpy) { static const char theme[] = "index.theme"; static const char pattern[] = "xtermXXXXXXXX"; char *env = getenv("XCURSOR_THEME"); xterm_cursor_theme = NULL; /* * The environment variable overrides a (possible) resource Xcursor.theme */ if (IsEmpty(env)) { env = XGetDefault(dpy, "Xcursor", "theme"); TRACE(("XGetDefault Xcursor theme \"%s\"\n", NonNull(env))); } else { TRACE(("getenv(XCURSOR_THEME) \"%s\"\n", NonNull(env))); } /* * If neither found, provide our own default theme. */ if (IsEmpty(env)) { const char *tmp_dir; char *filename; size_t needed; TRACE(("init_colored_cursor will make an empty Xcursor theme\n")); if ((tmp_dir = getenv("TMPDIR")) == NULL) { tmp_dir = P_tmpdir; } needed = strlen(tmp_dir) + 4 + strlen(theme) + strlen(pattern); if ((filename = malloc(needed)) != NULL) { sprintf(filename, "%s/%s", tmp_dir, pattern); #ifdef HAVE_MKDTEMP xterm_cursor_theme = mkdtemp(filename); #else if (MakeTemp(filename) != 0 && mkdir(filename, 0700) == 0) { xterm_cursor_theme = filename; } #endif if (xterm_cursor_theme != filename) free(filename); /* * Actually, Xcursor does what _we_ want just by steering its * search path away from home. We are setting up the complete * theme just in case the library ever acquires a maintainer. */ if (xterm_cursor_theme != NULL) { char *leaf = xterm_cursor_theme + strlen(xterm_cursor_theme); FILE *fp; strcat(leaf, "/"); strcat(leaf, theme); if ((fp = fopen(xterm_cursor_theme, "w")) != NULL) { fprintf(fp, "[Icon Theme]\n"); fclose(fp); *leaf = '\0'; xtermSetenv("XCURSOR_PATH", xterm_cursor_theme); *leaf = '/'; TRACE(("...initialized xterm_cursor_theme \"%s\"\n", xterm_cursor_theme)); atexit(cleanup_colored_cursor); } else { FreeAndNull(xterm_cursor_theme); } } } } } #endif /* HAVE_LIB_XCURSOR */ /* * Once done, discard the file and directory holding it. */ void cleanup_colored_cursor(void) { #ifdef HAVE_LIB_XCURSOR if (xterm_cursor_theme != NULL) { char *my_path = getenv("XCURSOR_PATH"); struct stat sb; if (!IsEmpty(my_path) && stat(my_path, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFDIR) { unlink(xterm_cursor_theme); rmdir(my_path); } FreeAndNull(xterm_cursor_theme); } #endif /* HAVE_LIB_XCURSOR */ } Cursor make_colored_cursor(unsigned c_index, /* index into font */ unsigned long fg, /* pixel value */ unsigned long bg) /* pixel value */ { TScreen *screen = TScreenOf(term); Cursor c = None; Display *dpy = screen->display; TRACE(("alternate cursor font is \"%s\"\n", screen->cursor_font_name)); if (!IsEmpty(screen->cursor_font_name)) { static XTermFonts myFont; /* adapted from XCreateFontCursor(), which hardcodes the font name */ TRACE(("loading cursor from alternate cursor font\n")); myFont.fs = xtermLoadQueryFont(term, screen->cursor_font_name); if (myFont.fs != NULL) { if (!xtermMissingChar(c_index, &myFont) && !xtermMissingChar(c_index + 1, &myFont)) { #define DATA(c) { 0UL, c, c, c, 0, 0 } static XColor foreground = DATA(0); static XColor background = DATA(65535); #undef DATA /* * Cursor fonts follow each shape glyph with a mask glyph; so * that character position 0 contains a shape, 1 the mask for * 0, 2 a shape, 3 a mask for 2, etc. * contains defined names for each shape. */ c = XCreateGlyphCursor(dpy, myFont.fs->fid, /* source_font */ myFont.fs->fid, /* mask_font */ c_index + 0, /* source_char */ c_index + 1, /* mask_char */ &foreground, &background); } XFreeFont(dpy, myFont.fs); } if (c == None) { xtermWarning("cannot load cursor %u from alternate cursor font \"%s\"\n", c_index, screen->cursor_font_name); } } if (c == None) c = XCreateFontCursor(dpy, c_index); if (c != None) { recolor_cursor(screen, c, fg, bg); } return c; } /* adapted from */ static int LookupCursorShape(const char *name) { #define DATA(name) { XC_##name, #name } static struct { int code; const char name[25]; } table[] = { DATA(X_cursor), DATA(arrow), DATA(based_arrow_down), DATA(based_arrow_up), DATA(boat), DATA(bogosity), DATA(bottom_left_corner), DATA(bottom_right_corner), DATA(bottom_side), DATA(bottom_tee), DATA(box_spiral), DATA(center_ptr), DATA(circle), DATA(clock), DATA(coffee_mug), DATA(cross), DATA(cross_reverse), DATA(crosshair), DATA(diamond_cross), DATA(dot), DATA(dotbox), DATA(double_arrow), DATA(draft_large), DATA(draft_small), DATA(draped_box), DATA(exchange), DATA(fleur), DATA(gobbler), DATA(gumby), DATA(hand1), DATA(hand2), DATA(heart), DATA(icon), DATA(iron_cross), DATA(left_ptr), DATA(left_side), DATA(left_tee), DATA(leftbutton), DATA(ll_angle), DATA(lr_angle), DATA(man), DATA(middlebutton), DATA(mouse), DATA(pencil), DATA(pirate), DATA(plus), DATA(question_arrow), DATA(right_ptr), DATA(right_side), DATA(right_tee), DATA(rightbutton), DATA(rtl_logo), DATA(sailboat), DATA(sb_down_arrow), DATA(sb_h_double_arrow), DATA(sb_left_arrow), DATA(sb_right_arrow), DATA(sb_up_arrow), DATA(sb_v_double_arrow), DATA(shuttle), DATA(sizing), DATA(spider), DATA(spraycan), DATA(star), DATA(target), DATA(tcross), DATA(top_left_arrow), DATA(top_left_corner), DATA(top_right_corner), DATA(top_side), DATA(top_tee), DATA(trek), DATA(ul_angle), DATA(umbrella), DATA(ur_angle), DATA(watch), DATA(xterm), }; #undef DATA Cardinal j; int result = -1; if (!IsEmpty(name)) { for (j = 0; j < XtNumber(table); ++j) { if (!strcmp(name, table[j].name)) { result = table[j].code; break; } } } return result; } void xtermSetupPointer(XtermWidget xw, const char *theShape) { TScreen *screen = TScreenOf(xw); unsigned shape = XC_xterm; int other = LookupCursorShape(theShape); unsigned which; if (other >= 0 && other < XC_num_glyphs) shape = (unsigned) other; TRACE(("looked up shape index %d from shape name \"%s\"\n", other, NonNull(theShape))); which = (unsigned) (shape / 2); if (xw->work.pointer_cursors[which] == None) { TRACE(("creating text pointer cursor from shape %d\n", shape)); xw->work.pointer_cursors[which] = make_colored_cursor(shape, T_COLOR(screen, MOUSE_FG), T_COLOR(screen, MOUSE_BG)); } else { TRACE(("updating text pointer cursor for shape %d\n", shape)); recolor_cursor(screen, screen->pointer_cursor, T_COLOR(screen, MOUSE_FG), T_COLOR(screen, MOUSE_BG)); } if (screen->pointer_cursor != xw->work.pointer_cursors[which]) { screen->pointer_cursor = xw->work.pointer_cursors[which]; TRACE(("defining text pointer cursor with shape %d\n", shape)); XDefineCursor(screen->display, VShellWindow(xw), screen->pointer_cursor); if (XtIsRealized((Widget) xw)) { /* briefly override pointerMode after changing the pointer */ if (screen->pointer_mode != pNever) screen->hide_pointer = True; xtermShowPointer(xw, True); } } } /* ARGSUSED */ void HandleKeyPressed(Widget w GCC_UNUSED, XEvent *event, String *params GCC_UNUSED, Cardinal *nparams GCC_UNUSED) { TRACE(("Handle insert-seven-bit for %p\n", (void *) w)); Input(term, &event->xkey, False); } /* ARGSUSED */ void HandleEightBitKeyPressed(Widget w GCC_UNUSED, XEvent *event, String *params GCC_UNUSED, Cardinal *nparams GCC_UNUSED) { TRACE(("Handle insert-eight-bit for %p\n", (void *) w)); Input(term, &event->xkey, True); } /* ARGSUSED */ void HandleStringEvent(Widget w GCC_UNUSED, XEvent *event GCC_UNUSED, String *params, Cardinal *nparams) { if (*nparams != 1) return; if ((*params)[0] == '0' && (*params)[1] == 'x' && (*params)[2] != '\0') { const char *abcdef = "ABCDEF"; const char *xxxxxx; Char c; UString p; unsigned value = 0; for (p = (UString) (*params + 2); (c = CharOf(x_toupper(*p))) != '\0'; p++) { value *= 16; if (c >= '0' && c <= '9') value += (unsigned) (c - '0'); else if ((xxxxxx = (strchr) (abcdef, c)) != NULL) value += (unsigned) (xxxxxx - abcdef) + 10; else break; } if (c == '\0') { Char hexval[2]; hexval[0] = (Char) value; hexval[1] = 0; StringInput(term, hexval, (size_t) 1); } } else { StringInput(term, (const Char *) *params, strlen(*params)); } } #if OPT_EXEC_XTERM #ifndef PROCFS_ROOT #define PROCFS_ROOT "/proc" #endif /* * Determine the current working directory of the child so that we can * spawn a new terminal in the same directory. * * If we cannot get the CWD of the child, just use our own. */ char * ProcGetCWD(pid_t pid) { char *child_cwd = NULL; if (pid) { char child_cwd_link[sizeof(PROCFS_ROOT) + 80]; sprintf(child_cwd_link, PROCFS_ROOT "/%lu/cwd", (unsigned long) pid); child_cwd = Readlink(child_cwd_link); } return child_cwd; } /* ARGSUSED */ void HandleSpawnTerminal(Widget w GCC_UNUSED, XEvent *event GCC_UNUSED, String *params, Cardinal *nparams) { TScreen *screen = TScreenOf(term); char *child_cwd = NULL; char *child_exe; pid_t pid; /* * Try to find the actual program which is running in the child process. * This works for Linux. If we cannot find the program, fall back to the * xterm program (which is usually adequate). Give up if we are given only * a relative path to xterm, since that would not always match $PATH. */ child_exe = Readlink(PROCFS_ROOT "/self/exe"); if (!child_exe) { if (strncmp(ProgramName, "./", (size_t) 2) && strncmp(ProgramName, "../", (size_t) 3)) { child_exe = xtermFindShell(ProgramName, True); } else { xtermWarning("Cannot exec-xterm given \"%s\"\n", ProgramName); } if (child_exe == NULL) return; } child_cwd = ProcGetCWD(screen->pid); /* The reaper will take care of cleaning up the child */ pid = fork(); if (pid == -1) { xtermWarning("Could not fork: %s\n", SysErrorMsg(errno)); } else if (!pid) { /* We are the child */ if (child_cwd) { IGNORE_RC(chdir(child_cwd)); /* We don't care if this fails */ } if (setuid(screen->uid) == -1 || setgid(screen->gid) == -1) { xtermWarning("Cannot reset uid/gid\n"); } else { unsigned myargc = *nparams + 1; char **myargv = TypeMallocN(char *, myargc + 1); if (myargv != NULL) { unsigned n = 0; myargv[n++] = child_exe; while (n < myargc) { myargv[n++] = (char *) *params++; } myargv[n] = NULL; execv(child_exe, myargv); } /* If we get here, we've failed */ xtermWarning("exec of '%s': %s\n", child_exe, SysErrorMsg(errno)); } _exit(0); } /* We are the parent; clean up */ free(child_cwd); free(child_exe); } #endif /* OPT_EXEC_XTERM */ /* * Rather than sending characters to the host, put them directly into our * input queue. That lets a user have access to any of the control sequences * for a key binding. This is the equivalent of local function key support. * * NOTE: This code does not support the hexadecimal kludge used in * HandleStringEvent because it prevents us from sending an arbitrary string * (but it appears in a lot of examples - so we are stuck with it). The * standard string converter does recognize "\" for newline ("\n") and for * octal constants (e.g., "\007" for BEL). So we assume the user can make do * without a specialized converter. (Don't try to use \000, though). */ /* ARGSUSED */ void HandleInterpret(Widget w GCC_UNUSED, XEvent *event GCC_UNUSED, String *params, Cardinal *param_count) { if (*param_count == 1) { const char *value = params[0]; size_t need = strlen(value); size_t used = (size_t) (VTbuffer->next - VTbuffer->buffer); size_t have = (size_t) (VTbuffer->last - VTbuffer->buffer); if ((have - used) + need < (size_t) BUF_SIZE) { fillPtyData(term, VTbuffer, value, strlen(value)); TRACE(("Interpret %s\n", value)); VTbuffer->update++; } } } /*ARGSUSED*/ void HandleEnterWindow(Widget w GCC_UNUSED, XtPointer eventdata GCC_UNUSED, XEvent *event GCC_UNUSED, Boolean *cont GCC_UNUSED) { /* NOP since we handled it above */ TRACE(("HandleEnterWindow ignored\n")); TRACE_FOCUS(w, event); } /*ARGSUSED*/ void HandleLeaveWindow(Widget w GCC_UNUSED, XtPointer eventdata GCC_UNUSED, XEvent *event GCC_UNUSED, Boolean *cont GCC_UNUSED) { /* NOP since we handled it above */ TRACE(("HandleLeaveWindow ignored\n")); TRACE_FOCUS(w, event); } /*ARGSUSED*/ void HandleFocusChange(Widget w GCC_UNUSED, XtPointer eventdata GCC_UNUSED, XEvent *ev, Boolean *cont GCC_UNUSED) { XFocusChangeEvent *event = (XFocusChangeEvent *) ev; XtermWidget xw = term; TScreen *screen = TScreenOf(xw); TRACE(("HandleFocusChange type=%s, mode=%s, detail=%s\n", visibleEventType(event->type), visibleNotifyMode(event->mode), visibleNotifyDetail(event->detail))); TRACE_FOCUS(xw, event); if (screen->quiet_grab && (event->mode == NotifyGrab || event->mode == NotifyUngrab)) { /* EMPTY */ ; } else if (event->type == FocusIn) { if (event->detail != NotifyPointer) { setXUrgency(xw, False); } /* * NotifyNonlinear only happens (on FocusIn) if the pointer was not in * one of our windows. Use this to reset a case where one xterm is * partly obscuring another, and X gets (us) confused about whether the * pointer was in the window. In particular, this can happen if the * user is resizing the obscuring window, causing some events to not be * delivered to the obscured window. */ if (event->detail == NotifyNonlinear && (screen->select & INWINDOW) != 0) { unselectwindow(xw, INWINDOW); } selectwindow(xw, ((event->detail == NotifyPointer) ? INWINDOW : FOCUS)); SendFocusButton(xw, event); } else { #if OPT_FOCUS_EVENT if (event->type == FocusOut) { SendFocusButton(xw, event); } #endif /* * XGrabKeyboard() will generate NotifyGrab event that we want to * ignore. */ if (event->mode != NotifyGrab) { unselectwindow(xw, ((event->detail == NotifyPointer) ? INWINDOW : FOCUS)); } if (screen->grabbedKbd && (event->mode == NotifyUngrab)) { Bell(xw, XkbBI_Info, 100); ReverseVideo(xw); screen->grabbedKbd = False; update_securekbd(); } } } static long lastBellTime; /* in milliseconds */ #if defined(HAVE_XKB_BELL_EXT) static Atom AtomBell(XtermWidget xw, int which) { #define DATA(name) { XkbBI_##name, XkbBN_##name } static struct { int value; const char *name; } table[] = { DATA(Info), DATA(MarginBell), DATA(MinorError), DATA(TerminalBell) }; #undef DATA Cardinal n; Atom result = None; for (n = 0; n < XtNumber(table); ++n) { if (table[n].value == which) { result = CachedInternAtom(XtDisplay(xw), table[n].name); break; } } return result; } #endif void xtermBell(XtermWidget xw, int which, int percent) { TScreen *screen = TScreenOf(xw); #if defined(HAVE_XKB_BELL_EXT) Atom tony = AtomBell(xw, which); #endif switch (which) { case XkbBI_Info: case XkbBI_MinorError: case XkbBI_MajorError: case XkbBI_TerminalBell: switch (screen->warningVolume) { case bvOff: percent = -100; break; case bvLow: break; case bvHigh: percent = 100; break; } break; case XkbBI_MarginBell: switch (screen->marginVolume) { case bvOff: percent = -100; break; case bvLow: break; case bvHigh: percent = 100; break; } break; default: break; } #if defined(HAVE_XKB_BELL_EXT) if (tony != None) { XkbBell(screen->display, VShellWindow(xw), percent, tony); } else #endif XBell(screen->display, percent); } void Bell(XtermWidget xw, int which, int percent) { TScreen *screen = TScreenOf(xw); struct timeval curtime; TRACE(("BELL %d %d%%\n", which, percent)); if (!XtIsRealized((Widget) xw)) { return; } setXUrgency(xw, True); /* has enough time gone by that we are allowed to ring the bell again? */ if (screen->bellSuppressTime) { long now_msecs; if (screen->bellInProgress) { do_xevents(xw); if (screen->bellInProgress) { /* even after new events? */ return; } } X_GETTIMEOFDAY(&curtime); now_msecs = 1000 * curtime.tv_sec + curtime.tv_usec / 1000; if (lastBellTime != 0 && now_msecs - lastBellTime >= 0 && now_msecs - lastBellTime < screen->bellSuppressTime) { return; } lastBellTime = now_msecs; } if (screen->visualbell) { VisualBell(); } else { xtermBell(xw, which, percent); } if (screen->poponbell) XRaiseWindow(screen->display, VShellWindow(xw)); if (screen->bellSuppressTime) { /* now we change a property and wait for the notify event to come back. If the server is suspending operations while the bell is being emitted (problematic for audio bell), this lets us know when the previous bell has finished */ Widget w = CURRENT_EMU(); XChangeProperty(XtDisplay(w), XtWindow(w), XA_NOTICE, XA_NOTICE, 8, PropModeAppend, NULL, 0); screen->bellInProgress = True; } } static void flashWindow(TScreen *screen, Window window, GC visualGC, unsigned width, unsigned height) { int y = 0; int x = 0; if (screen->flash_line) { y = CursorY(screen, screen->cur_row); height = (unsigned) FontHeight(screen); } XFillRectangle(screen->display, window, visualGC, x, y, width, height); XFlush(screen->display); Sleep(VB_DELAY); XFillRectangle(screen->display, window, visualGC, x, y, width, height); } void VisualBell(void) { XtermWidget xw = term; TScreen *screen = TScreenOf(xw); if (VB_DELAY > 0) { Pixel xorPixel = (T_COLOR(screen, TEXT_FG) ^ T_COLOR(screen, TEXT_BG)); XGCValues gcval; GC visualGC; gcval.function = GXxor; gcval.foreground = xorPixel; visualGC = XtGetGC((Widget) xw, GCFunction + GCForeground, &gcval); #if OPT_TEK4014 if (TEK4014_ACTIVE(xw)) { TekScreen *tekscr = TekScreenOf(tekWidget); flashWindow(screen, TWindow(tekscr), visualGC, TFullWidth(tekscr), TFullHeight(tekscr)); } else #endif { flashWindow(screen, VWindow(screen), visualGC, FullWidth(screen), FullHeight(screen)); } XtReleaseGC((Widget) xw, visualGC); } } /* ARGSUSED */ void HandleBellPropertyChange(Widget w GCC_UNUSED, XtPointer data GCC_UNUSED, XEvent *ev, Boolean *more GCC_UNUSED) { TScreen *screen = TScreenOf(term); if (ev->xproperty.atom == XA_NOTICE) { screen->bellInProgress = False; } } void xtermWarning(const char *fmt, ...) { int save_err = errno; va_list ap; fflush(stdout); #if OPT_TRACE va_start(ap, fmt); Trace("xtermWarning: "); TraceVA(fmt, ap); va_end(ap); #endif fprintf(stderr, "%s: ", ProgramName); va_start(ap, fmt); vfprintf(stderr, fmt, ap); (void) fflush(stderr); va_end(ap); errno = save_err; } void xtermPerror(const char *fmt, ...) { int save_err = errno; const char *msg = strerror(errno); va_list ap; fflush(stdout); #if OPT_TRACE va_start(ap, fmt); Trace("xtermPerror: "); TraceVA(fmt, ap); va_end(ap); #endif fprintf(stderr, "%s: ", ProgramName); va_start(ap, fmt); vfprintf(stderr, fmt, ap); fprintf(stderr, ": %s\n", msg); (void) fflush(stderr); va_end(ap); errno = save_err; } Window WMFrameWindow(XtermWidget xw) { Window win_root, win_current, *children; Window win_parent = 0; unsigned int nchildren; win_current = XtWindow(xw); /* find the parent which is child of root */ do { if (win_parent) win_current = win_parent; XQueryTree(TScreenOf(xw)->display, win_current, &win_root, &win_parent, &children, &nchildren); XFree(children); } while (win_root != win_parent); return win_current; } #if OPT_DABBREV /* * The following code implements `dynamic abbreviation' expansion a la * Emacs. It looks in the preceding visible screen and its scrollback * to find expansions of a typed word. It compares consecutive * expansions and ignores one of them if they are identical. * (Tomasz J. Cholewo, t.cholewo@ieee.org) */ #define IS_WORD_CONSTITUENT(x) ((x) != ' ' && (x) != '\0') static int dabbrev_prev_char(TScreen *screen, CELL *cell, LineData **ld) { int result = -1; int firstLine = -(screen->savedlines); *ld = getLineData(screen, cell->row); while (cell->row >= firstLine) { if (--(cell->col) >= 0) { result = (int) (*ld)->charData[cell->col]; break; } if (--(cell->row) < firstLine) break; /* ...there is no previous line */ *ld = getLineData(screen, cell->row); cell->col = MaxCols(screen); if (!LineTstWrapped(*ld)) { result = ' '; /* treat lines as separate */ break; } } return result; } static char * dabbrev_prev_word(XtermWidget xw, CELL *cell, LineData **ld) { TScreen *screen = TScreenOf(xw); char *abword; int c; char *ab_end = (xw->work.dabbrev_data + MAX_DABBREV - 1); char *result = NULL; abword = ab_end; *abword = '\0'; /* end of string marker */ while ((c = dabbrev_prev_char(screen, cell, ld)) >= 0 && IS_WORD_CONSTITUENT(c)) { if (abword > xw->work.dabbrev_data) /* store only the last chars */ *(--abword) = (char) c; } if (c >= 0) { result = abword; } else if (abword != ab_end) { result = abword; } if (result != NULL) { while ((c = dabbrev_prev_char(screen, cell, ld)) >= 0 && !IS_WORD_CONSTITUENT(c)) { ; /* skip preceding spaces */ } (cell->col)++; /* can be | > screen->max_col| */ } return result; } static int dabbrev_expand(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int pty = screen->respond; /* file descriptor of pty */ static CELL cell; static char *dabbrev_hint = NULL, *lastexpansion = NULL; static unsigned int expansions; char *expansion; size_t hint_len; int result = 0; LineData *ld; if (!screen->dabbrev_working) { /* initialize */ expansions = 0; cell.col = screen->cur_col; cell.row = screen->cur_row; free(dabbrev_hint); if ((dabbrev_hint = dabbrev_prev_word(xw, &cell, &ld)) != NULL) { free(lastexpansion); if ((lastexpansion = strdup(dabbrev_hint)) != NULL) { /* make own copy */ if ((dabbrev_hint = strdup(dabbrev_hint)) != NULL) { screen->dabbrev_working = True; /* we are in the middle of dabbrev process */ } } else { return result; } } else { return result; } if (!screen->dabbrev_working) { free(lastexpansion); lastexpansion = NULL; return result; } } if (dabbrev_hint == NULL) return result; hint_len = strlen(dabbrev_hint); for (;;) { if ((expansion = dabbrev_prev_word(xw, &cell, &ld)) == NULL) { if (expansions >= 2) { expansions = 0; cell.col = screen->cur_col; cell.row = screen->cur_row; continue; } break; } if (!strncmp(dabbrev_hint, expansion, hint_len) && /* empty hint matches everything */ strlen(expansion) > hint_len && /* trivial expansion disallowed */ strcmp(expansion, lastexpansion)) /* different from previous */ break; } if (expansion != NULL) { Char *copybuffer; size_t del_cnt = strlen(lastexpansion) - hint_len; size_t buf_cnt = del_cnt + strlen(expansion) - hint_len; if ((copybuffer = TypeMallocN(Char, buf_cnt)) != NULL) { /* delete previous expansion */ memset(copybuffer, screen->dabbrev_erase_char, del_cnt); memmove(copybuffer + del_cnt, expansion + hint_len, strlen(expansion) - hint_len); v_write(pty, copybuffer, buf_cnt); /* v_write() just reset our flag */ screen->dabbrev_working = True; free(copybuffer); free(lastexpansion); if ((lastexpansion = strdup(expansion)) != NULL) { result = 1; expansions++; } } } return result; } /*ARGSUSED*/ void HandleDabbrevExpand(Widget w, XEvent *event GCC_UNUSED, String *params GCC_UNUSED, Cardinal *nparams GCC_UNUSED) { XtermWidget xw; TRACE(("Handle dabbrev-expand for %p\n", (void *) w)); if ((xw = getXtermWidget(w)) != NULL) { if (!dabbrev_expand(xw)) Bell(xw, XkbBI_TerminalBell, 0); } } #endif /* OPT_DABBREV */ void xtermDeiconify(XtermWidget xw) { TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; Window target = VShellWindow(xw); XEvent e; Atom atom_state = CachedInternAtom(dpy, "_NET_ACTIVE_WINDOW"); if (xtermIsIconified(xw)) { TRACE(("...de-iconify window %#lx\n", target)); ResetHiddenHint(xw); XMapWindow(dpy, target); memset(&e, 0, sizeof(e)); e.xclient.type = ClientMessage; e.xclient.message_type = atom_state; e.xclient.display = dpy; e.xclient.window = target; e.xclient.format = 32; e.xclient.data.l[0] = 1; e.xclient.data.l[1] = CurrentTime; XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureRedirectMask | SubstructureNotifyMask, &e); xevents(xw); } } void xtermIconify(XtermWidget xw) { TScreen *screen = TScreenOf(xw); Window target = VShellWindow(xw); if (!xtermIsIconified(xw)) { TRACE(("...iconify window %#lx\n", target)); XIconifyWindow(screen->display, target, DefaultScreen(screen->display)); xevents(xw); } } Boolean xtermIsIconified(XtermWidget xw) { XWindowAttributes win_attrs; TScreen *screen = TScreenOf(xw); Window target = VShellWindow(xw); Display *dpy = screen->display; Boolean result = False; if (xtermGetWinAttrs(dpy, target, &win_attrs)) { Atom actual_return_type; int actual_format_return = 0; unsigned long nitems_return = 0; unsigned long bytes_after_return = 0; unsigned char *prop_return = NULL; long long_length = 1024; Atom requested_type = XA_ATOM; Atom is_hidden = CachedInternAtom(dpy, "_NET_WM_STATE_HIDDEN"); Atom wm_state = CachedInternAtom(dpy, "_NET_WM_STATE"); /* this works with non-EWMH */ result = (win_attrs.map_state != IsViewable) ? True : False; /* this is a convention used by some EWMH applications */ if (xtermGetWinProp(dpy, target, wm_state, 0L, long_length, requested_type, &actual_return_type, &actual_format_return, &nitems_return, &bytes_after_return, &prop_return)) { if (prop_return != NULL && actual_return_type == requested_type && actual_format_return == 32) { unsigned long n; for (n = 0; n < nitems_return; ++n) { unsigned long check = (((unsigned long *) (void *) prop_return)[n]); if (check == is_hidden) { result = True; break; } } XFree(prop_return); } } } TRACE(("...window %#lx is%s iconified\n", target, result ? "" : " not")); return result; } #if OPT_MAXIMIZE /*ARGSUSED*/ void HandleDeIconify(Widget w, XEvent *event GCC_UNUSED, String *params GCC_UNUSED, Cardinal *nparams GCC_UNUSED) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { xtermDeiconify(xw); } } /*ARGSUSED*/ void HandleIconify(Widget w, XEvent *event GCC_UNUSED, String *params GCC_UNUSED, Cardinal *nparams GCC_UNUSED) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { xtermIconify(xw); } } int QueryMaximize(XtermWidget xw, unsigned *width, unsigned *height) { TScreen *screen = TScreenOf(xw); XSizeHints hints; long supp = 0; Window root_win; int root_x = -1; /* saved co-ordinates */ int root_y = -1; unsigned root_border; unsigned root_depth; int code; if (XGetGeometry(screen->display, RootWindowOfScreen(XtScreen(xw)), &root_win, &root_x, &root_y, width, height, &root_border, &root_depth)) { TRACE(("QueryMaximize: XGetGeometry position %d,%d size %d,%d border %d\n", root_x, root_y, *width, *height, root_border)); *width -= (root_border * 2); *height -= (root_border * 2); hints.flags = PMaxSize; if (XGetWMNormalHints(screen->display, VShellWindow(xw), &hints, &supp) && (hints.flags & PMaxSize) != 0) { TRACE(("QueryMaximize: WM hints max_w %#x max_h %#x\n", hints.max_width, hints.max_height)); if ((unsigned) hints.max_width < *width) *width = (unsigned) hints.max_width; if ((unsigned) hints.max_height < *height) *height = (unsigned) hints.max_height; } code = 1; } else { *width = 0; *height = 0; code = 0; } return code; } void RequestMaximize(XtermWidget xw, int maximize) { TScreen *screen = TScreenOf(xw); XWindowAttributes wm_attrs, vshell_attrs; unsigned root_width = 0, root_height = 0; Boolean success = False; TRACE(("RequestMaximize %d:%s\n", maximize, (maximize ? "maximize" : "restore"))); /* * Before any maximize, ensure that we can capture the current screensize * as well as the estimated root-window size. */ if (maximize && QueryMaximize(xw, &root_width, &root_height) && xtermGetWinAttrs(screen->display, WMFrameWindow(xw), &wm_attrs) && xtermGetWinAttrs(screen->display, VShellWindow(xw), &vshell_attrs)) { if (screen->restore_data != True || screen->restore_width != root_width || screen->restore_height != root_height) { screen->restore_data = True; screen->restore_x = wm_attrs.x; screen->restore_y = wm_attrs.y; screen->restore_width = (unsigned) vshell_attrs.width; screen->restore_height = (unsigned) vshell_attrs.height; TRACE(("RequestMaximize: save window position %d,%d size %d,%d\n", screen->restore_x, screen->restore_y, screen->restore_width, screen->restore_height)); } /* subtract wm decoration dimensions */ root_width -= (unsigned) (wm_attrs.width - vshell_attrs.width); root_height -= (unsigned) (wm_attrs.height - vshell_attrs.height); success = True; } else if (screen->restore_data) { success = True; maximize = 0; } if (success) { switch (maximize) { case 3: FullScreen(xw, 3); /* depends on EWMH */ break; case 2: FullScreen(xw, 2); /* depends on EWMH */ break; case 1: FullScreen(xw, 0); /* overrides any EWMH hint */ TRACE(("XMoveResizeWindow(Maximize): position %d,%d size %d,%d\n", 0, 0, root_width, root_height)); XMoveResizeWindow(screen->display, VShellWindow(xw), 0, /* x */ 0, /* y */ root_width, root_height); break; default: FullScreen(xw, 0); /* reset any EWMH hint */ if (screen->restore_data) { screen->restore_data = False; TRACE(("XMoveResizeWindow(Restore): position %d,%d size %d,%d\n", screen->restore_x, screen->restore_y, screen->restore_width, screen->restore_height)); XMoveResizeWindow(screen->display, VShellWindow(xw), screen->restore_x, screen->restore_y, screen->restore_width, screen->restore_height); } break; } } } /*ARGSUSED*/ void HandleMaximize(Widget w, XEvent *event GCC_UNUSED, String *params GCC_UNUSED, Cardinal *nparams GCC_UNUSED) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { RequestMaximize(xw, 1); } } /*ARGSUSED*/ void HandleRestoreSize(Widget w, XEvent *event GCC_UNUSED, String *params GCC_UNUSED, Cardinal *nparams GCC_UNUSED) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { RequestMaximize(xw, 0); } } #endif /* OPT_MAXIMIZE */ void Redraw(void) { XtermWidget xw = term; TScreen *screen = TScreenOf(xw); XExposeEvent event; TRACE(("Redraw\n")); event.type = Expose; event.display = screen->display; event.x = 0; event.y = 0; event.count = 0; if (VWindow(screen)) { event.window = VWindow(screen); event.width = xw->core.width; event.height = xw->core.height; (*xw->core.widget_class->core_class.expose) ((Widget) xw, (XEvent *) &event, NULL); if (ScrollbarWidth(screen)) { (screen->scrollWidget->core.widget_class->core_class.expose) (screen->scrollWidget, (XEvent *) &event, NULL); } } #if OPT_TEK4014 if (TEK4014_SHOWN(xw)) { TekScreen *tekscr = TekScreenOf(tekWidget); event.window = TWindow(tekscr); event.width = tekWidget->core.width; event.height = tekWidget->core.height; TekExpose((Widget) tekWidget, (XEvent *) &event, NULL); } #endif } #define TIMESTAMP_FMT "%s%d-%02d-%02d.%02d:%02d:%02d" void timestamp_filename(char *dst, const char *src) { time_t tstamp; struct tm *tstruct; tstamp = time((time_t *) 0); tstruct = localtime(&tstamp); sprintf(dst, TIMESTAMP_FMT, src, (int) tstruct->tm_year + 1900, tstruct->tm_mon + 1, tstruct->tm_mday, tstruct->tm_hour, tstruct->tm_min, tstruct->tm_sec); } #if OPT_SCREEN_DUMPS FILE * create_printfile(XtermWidget xw, const char *suffix) { TScreen *screen = TScreenOf(xw); char fname[1024]; int fd; FILE *fp; #if defined(HAVE_STRFTIME) { char format[1024]; time_t now; struct tm *ltm; now = time((time_t *) 0); ltm = localtime(&now); sprintf(format, "xterm%s%s", FMT_TIMESTAMP, suffix); if (strftime(fname, sizeof fname, format, ltm) == 0) { sprintf(fname, "xterm%s", suffix); } } #else sprintf(fname, "xterm%s", suffix); #endif fd = open_userfile(screen->uid, screen->gid, fname, False); fp = (fd >= 0) ? fdopen(fd, "wb") : NULL; return fp; } #endif /* OPT_SCREEN_DUMPS */ #if OPT_SCREEN_DUMPS || defined(ALLOWLOGGING) int open_userfile(uid_t uid, gid_t gid, char *path, Bool append) { int fd; struct stat sb; if ((access(path, F_OK) != 0 && (errno != ENOENT)) || (creat_as(uid, gid, append, path, 0644) <= 0) || ((fd = open(path, O_WRONLY | O_APPEND)) < 0)) { int the_error = errno; xtermWarning("cannot open %s: %d:%s\n", path, the_error, SysErrorMsg(the_error)); return -1; } /* * Doublecheck that the user really owns the file that we've opened before * we do any damage, and that it is not world-writable. */ if (fstat(fd, &sb) < 0 || sb.st_uid != uid || (sb.st_mode & 022) != 0) { xtermWarning("you do not own %s\n", path); close(fd); return -1; } return fd; } /* * Create a file only if we could with the permissions of the real user id. * We could emulate this with careful use of access() and following * symbolic links, but that is messy and has race conditions. * Forking is messy, too, but we can't count on setreuid() or saved set-uids * being available. * * Note: When called for user logging, we have ensured that the real and * effective user ids are the same, so this remains as a convenience function * for the debug logs. * * Returns * 1 if we can proceed to open the file in relative safety, * -1 on error, e.g., cannot fork * 0 otherwise. */ int creat_as(uid_t uid, gid_t gid, Bool append, char *pathname, unsigned mode) { int fd; pid_t pid; int retval = 0; int childstat = 0; #ifndef HAVE_WAITPID int waited; void (*chldfunc) (int); chldfunc = signal(SIGCHLD, SIG_DFL); #endif /* HAVE_WAITPID */ TRACE(("creat_as(uid=%d/%d, gid=%d/%d, append=%d, pathname=%s, mode=%#o)\n", (int) uid, (int) geteuid(), (int) gid, (int) getegid(), append, pathname, mode)); if (uid == geteuid() && gid == getegid()) { fd = open(pathname, O_WRONLY | O_CREAT | (append ? O_APPEND : O_EXCL), mode); if (fd >= 0) close(fd); return (fd >= 0); } pid = fork(); switch (pid) { case 0: /* child */ if (setgid(gid) == -1 || setuid(uid) == -1) { /* we cannot report an error here via stderr, just quit */ retval = 1; } else { fd = open(pathname, O_WRONLY | O_CREAT | (append ? O_APPEND : O_EXCL), mode); if (fd >= 0) { close(fd); retval = 0; } else { retval = 1; } } _exit(retval); /* NOTREACHED */ case -1: /* error */ return retval; default: /* parent */ #ifdef HAVE_WAITPID while (waitpid(pid, &childstat, 0) < 0) { #ifdef EINTR if (errno == EINTR) continue; #endif /* EINTR */ #ifdef ERESTARTSYS if (errno == ERESTARTSYS) continue; #endif /* ERESTARTSYS */ break; } #else /* HAVE_WAITPID */ waited = wait(&childstat); signal(SIGCHLD, chldfunc); /* Since we had the signal handler uninstalled for a while, we might have missed the termination of our screen child. If we can check for this possibility without hanging, do so. */ do if (waited == TScreenOf(term)->pid) NormalExit(); while ((waited = nonblocking_wait()) > 0) ; #endif /* HAVE_WAITPID */ #ifndef WIFEXITED #define WIFEXITED(status) ((status & 0xff) != 0) #endif if (WIFEXITED(childstat)) retval = 1; return retval; } } #endif /* OPT_SCREEN_DUMPS || defined(ALLOWLOGGING) */ int xtermResetIds(TScreen *screen) { int result = 0; if (setgid(screen->gid) == -1) { xtermWarning("unable to reset group-id\n"); result = -1; } if (setuid(screen->uid) == -1) { xtermWarning("unable to reset user-id\n"); result = -1; } return result; } #ifdef ALLOWLOGGING /* * Logging is a security hole, since it allows a setuid program to write * arbitrary data to an arbitrary file. So it is disabled by default. */ #ifdef ALLOWLOGFILEEXEC static void handle_SIGPIPE(int sig GCC_UNUSED) { XtermWidget xw = term; TScreen *screen = TScreenOf(xw); DEBUG_MSG("handle:logpipe\n"); #ifdef SYSV (void) signal(SIGPIPE, SIG_IGN); #endif /* SYSV */ if (screen->logging) CloseLog(xw); } /* * Open a command to pipe log data to it. * Warning, enabling this "feature" allows arbitrary programs * to be run. If ALLOWLOGFILECHANGES is enabled, this can be * done through escape sequences.... You have been warned. */ static void StartLogExec(TScreen *screen) { int pid; int p[2]; static char *shell; struct passwd pw; if ((shell = x_getenv("SHELL")) == NULL) { if (x_getpwuid(screen->uid, &pw)) { char *name = x_getlogin(screen->uid, &pw); if (*(pw.pw_shell)) { shell = pw.pw_shell; } free(name); } } if (shell == NULL) { static char dummy[] = "/bin/sh"; shell = dummy; } if (access(shell, X_OK) != 0) { xtermPerror("Can't execute `%s'\n", shell); return; } if (pipe(p) < 0) { xtermPerror("Can't make a pipe connection\n"); return; } else if ((pid = fork()) < 0) { xtermPerror("Can't fork...\n"); return; } if (pid == 0) { /* child */ /* * Close our output (we won't be talking back to the * parent), and redirect our child's output to the * original stderr. */ close(p[1]); dup2(p[0], 0); close(p[0]); dup2(fileno(stderr), 1); dup2(fileno(stderr), 2); close(fileno(stderr)); close(ConnectionNumber(screen->display)); close(screen->respond); signal(SIGHUP, SIG_DFL); signal(SIGCHLD, SIG_DFL); /* (this is redundant) */ if (xtermResetIds(screen) < 0) exit(ERROR_SETUID); execl(shell, shell, "-c", &screen->logfile[1], (void *) 0); xtermWarning("Can't exec `%s -c %s'\n", shell, &screen->logfile[1]); exit(ERROR_LOGEXEC); } close(p[0]); screen->logfd = p[1]; signal(SIGPIPE, handle_SIGPIPE); } #endif /* ALLOWLOGFILEEXEC */ /* * Generate a path for a logfile if no default path is given. */ static char * GenerateLogPath(void) { static char *log_default = NULL; /* once opened we just reuse the same log name */ if (log_default) return (log_default); #if defined(HAVE_GETHOSTNAME) && defined(HAVE_STRFTIME) { #define LEN_HOSTNAME 255 /* Internet standard limit (RFC 1035): ``To simplify implementations, * the total length of a domain name (i.e., label octets and label * length octets) is restricted to 255 octets or less.'' */ #define LEN_GETPID 9 /* * This is arbitrary... */ const char form[] = "Xterm.log.%s%s.%lu"; char where[LEN_HOSTNAME + 1]; char when[LEN_TIMESTAMP]; time_t now = time((time_t *) 0); struct tm *ltm = (struct tm *) localtime(&now); if ((gethostname(where, sizeof(where)) == 0) && (strftime(when, sizeof(when), FMT_TIMESTAMP, ltm) > 0) && ((log_default = (char *) malloc((sizeof(form) + strlen(where) + strlen(when) + LEN_GETPID))) != NULL)) { (void) sprintf(log_default, form, where, when, ((unsigned long) getpid()) % ((unsigned long) 1e10)); } } #else { static const char log_def_name[] = "XtermLog.XXXXXX"; if ((log_default = x_strdup(log_def_name)) != NULL) { MakeTemp(log_default); } } #endif return (log_default); } void StartLog(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->logging || (screen->inhibit & I_LOG)) return; /* if we weren't supplied with a logfile path, generate one */ if (IsEmpty(screen->logfile)) screen->logfile = GenerateLogPath(); /* give up if we were unable to allocate the filename */ if (!screen->logfile) return; if (*screen->logfile == '|') { /* exec command */ #ifdef ALLOWLOGFILEEXEC StartLogExec(screen); #else Bell(xw, XkbBI_Info, 0); Bell(xw, XkbBI_Info, 0); return; #endif } else if (strcmp(screen->logfile, "-") == 0) { screen->logfd = STDOUT_FILENO; } else { if ((screen->logfd = open_userfile(screen->uid, screen->gid, screen->logfile, True)) < 0) return; } screen->logstart = VTbuffer->next; screen->logging = True; update_logging(); } void CloseLog(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (!screen->logging || (screen->inhibit & I_LOG)) return; FlushLog(xw); close(screen->logfd); screen->logging = False; update_logging(); } void FlushLog(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->logging && !(screen->inhibit & I_LOG)) { Char *cp; size_t i; cp = VTbuffer->next; if (screen->logstart != NULL && (i = (size_t) (cp - screen->logstart)) > 0) { IGNORE_RC(write(screen->logfd, screen->logstart, i)); } screen->logstart = VTbuffer->next; } } #endif /* ALLOWLOGGING */ /***====================================================================***/ static unsigned maskToShift(unsigned long mask) { unsigned result = 0; if (mask != 0) { while ((mask & 1) == 0) { mask >>= 1; ++result; } } return result; } static unsigned maskToWidth(unsigned long mask) { unsigned result = 0; while (mask != 0) { if ((mask & 1) != 0) ++result; mask >>= 1; } return result; } XVisualInfo * getVisualInfo(XtermWidget xw) { #define MYFMT "getVisualInfo \ depth %d, \ type %d (%s), \ size %d \ rgb masks (%04lx/%04lx/%04lx)\n" #define MYARG \ vi->depth,\ vi->class,\ ((vi->class & 1) ? "dynamic" : "static"),\ vi->colormap_size,\ vi->red_mask,\ vi->green_mask,\ vi->blue_mask TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; XVisualInfo myTemplate; if (xw->visInfo == NULL && xw->numVisuals == 0) { myTemplate.visualid = XVisualIDFromVisual(DefaultVisual(dpy, XDefaultScreen(dpy))); xw->visInfo = XGetVisualInfo(dpy, (long) VisualIDMask, &myTemplate, &xw->numVisuals); if ((xw->visInfo != NULL) && (xw->numVisuals > 0)) { XVisualInfo *vi = xw->visInfo; xw->rgb_widths[0] = maskToWidth(vi->red_mask); xw->rgb_widths[1] = maskToWidth(vi->green_mask); xw->rgb_widths[2] = maskToWidth(vi->blue_mask); xw->rgb_shifts[0] = maskToShift(vi->red_mask); xw->rgb_shifts[1] = maskToShift(vi->green_mask); xw->rgb_shifts[2] = maskToShift(vi->blue_mask); xw->has_rgb = ((vi->red_mask != 0) && (vi->green_mask != 0) && (vi->blue_mask != 0) && ((vi->red_mask & vi->green_mask) == 0) && ((vi->green_mask & vi->blue_mask) == 0) && ((vi->blue_mask & vi->red_mask) == 0) && xw->rgb_widths[0] <= (unsigned) vi->bits_per_rgb && xw->rgb_widths[1] <= (unsigned) vi->bits_per_rgb && xw->rgb_widths[2] <= (unsigned) vi->bits_per_rgb && (vi->class == TrueColor || vi->class == DirectColor)); if (resource.reportColors) { printf(MYFMT, MYARG); } TRACE((MYFMT, MYARG)); TRACE(("...shifts %u/%u/%u\n", xw->rgb_shifts[0], xw->rgb_shifts[1], xw->rgb_shifts[2])); TRACE(("...widths %u/%u/%u\n", xw->rgb_widths[0], xw->rgb_widths[1], xw->rgb_widths[2])); } } return (xw->visInfo != NULL) && (xw->numVisuals > 0) ? xw->visInfo : NULL; #undef MYFMT #undef MYARG } #if OPT_ISO_COLORS static Bool ReportAnsiColorRequest(XtermWidget xw, int opcode, int colornum, int final) { Bool result = False; if (AllowColorOps(xw, ecGetAnsiColor)) { XColor color; char buffer[80]; TRACE(("ReportAnsiColorRequest %d\n", colornum)); color.pixel = GET_COLOR_RES(xw, TScreenOf(xw)->Acolors[colornum]); (void) QueryOneColor(xw, &color); sprintf(buffer, "%d;%d;rgb:%04x/%04x/%04x", opcode, (opcode == 5) ? (colornum - NUM_ANSI_COLORS) : colornum, color.red, color.green, color.blue); unparseputc1(xw, ANSI_OSC); unparseputs(xw, buffer); unparseputc1(xw, final); result = True; } return result; } static void getColormapInfo(XtermWidget xw, unsigned *typep, unsigned *sizep) { if (getVisualInfo(xw)) { *typep = (unsigned) xw->visInfo->class; *sizep = (unsigned) xw->visInfo->colormap_size; } else { *typep = 0; *sizep = 0; } } #define MAX_COLORTABLE 4096 /* * Make only one call to XQueryColors(), since it can be slow. */ static Boolean loadColorTable(XtermWidget xw, unsigned length) { Colormap cmap = xw->core.colormap; TScreen *screen = TScreenOf(xw); Boolean result = (screen->cmap_data != NULL); if (!result && length != 0 && length < MAX_COLORTABLE) { screen->cmap_data = TypeMallocN(XColor, (size_t) length); if (screen->cmap_data != NULL) { unsigned i; unsigned shift; if (getVisualInfo(xw)) shift = xw->rgb_shifts[2]; else shift = 0; screen->cmap_size = length; for (i = 0; i < screen->cmap_size; i++) { screen->cmap_data[i].pixel = (unsigned long) i << shift; } result = (Boolean) (XQueryColors(screen->display, cmap, screen->cmap_data, (int) screen->cmap_size) != 0); } } return result; } /***====================================================================***/ /* * Call this function with def->{red,green,blue} initialized, to obtain a pixel * value. */ Boolean AllocOneColor(XtermWidget xw, XColor *def) { TScreen *screen = TScreenOf(xw); Boolean result = True; #define MaskIt(name,nn) \ ((unsigned long) ((def->name >> (16 - xw->rgb_widths[nn])) \ << xw->rgb_shifts[nn]) \ & xw->visInfo->name ##_mask) #define VisualIsRGB(xw) (getVisualInfo(xw) != NULL && xw->has_rgb && xw->visInfo->bits_per_rgb <= 8) if (VisualIsRGB(xw)) { def->pixel = MaskIt(red, 0) | MaskIt(green, 1) | MaskIt(blue, 2); } else { Display *dpy = screen->display; if (!XAllocColor(dpy, xw->core.colormap, def)) { /* * Decide between foreground and background by a grayscale * approximation. */ int bright = def->red * 3 + def->green * 10 + def->blue; int levels = 14 * 0x8000; def->pixel = ((bright >= levels) ? xw->dft_background : xw->dft_foreground); TRACE(("XAllocColor failed, for %04x/%04x/%04x: choose %08lx (%d vs %d)\n", def->red, def->green, def->blue, def->pixel, bright, levels)); result = False; } } return result; } /***====================================================================***/ /* * Call this function with def->pixel set to the color that we want to convert * to separate red/green/blue. */ Boolean QueryOneColor(XtermWidget xw, XColor *def) { Boolean result = True; #define UnMaskIt(name,nn) \ ((unsigned short)((def->pixel & xw->visInfo->name ##_mask) >> xw->rgb_shifts[nn])) #define UnMaskIt2(name,nn) \ (unsigned short)((((UnMaskIt(name,nn) << 8) \ |UnMaskIt(name,nn))) << (8 - xw->rgb_widths[nn])) if (VisualIsRGB(xw)) { /* *INDENT-EQLS* */ def->red = UnMaskIt2(red, 0); def->green = UnMaskIt2(green, 1); def->blue = UnMaskIt2(blue, 2); } else { Display *dpy = TScreenOf(xw)->display; if (!XQueryColor(dpy, xw->core.colormap, def)) { TRACE(("XQueryColor failed, given %08lx\n", def->pixel)); result = False; } } return result; } /***====================================================================***/ /* * Find closest color for "def" in "cmap". * Set "def" to the resulting color. * * Based on Monish Shah's "find_closest_color()" for Vim 6.0, * modified with ideas from David Tong's "noflash" library. * The code from Vim in turn was derived from FindClosestColor() in Tcl/Tk. * * Return False if not able to find or allocate a color. */ static Boolean allocateClosestRGB(XtermWidget xw, XColor *def) { TScreen *screen = TScreenOf(xw); Boolean result = False; unsigned cmap_type; unsigned cmap_size; getColormapInfo(xw, &cmap_type, &cmap_size); if ((cmap_type & 1) != 0) { if (loadColorTable(xw, cmap_size)) { char *tried = TypeCallocN(char, (size_t) cmap_size); if (tried != NULL) { unsigned attempts; /* * Try (possibly each entry in the color map) to find the best * approximation to the requested color. */ for (attempts = 0; attempts < cmap_size; attempts++) { Boolean first = True; double bestRGB = 0.0; unsigned bestInx = 0; unsigned i; for (i = 0; i < cmap_size; i++) { if (!tried[bestInx]) { double diff, thisRGB = 0.0; /* * Look for the best match based on luminance. * Measure this by the least-squares difference of * the weighted R/G/B components from the color map * versus the requested color. Use the Y (luma) * component of the YIQ color space model for * weights that correspond to the luminance. */ #define AddColorWeight(weight, color) \ diff = weight * (int) ((def->color) - screen->cmap_data[i].color); \ thisRGB += diff * diff AddColorWeight(0.30, red); AddColorWeight(0.61, green); AddColorWeight(0.11, blue); if (first || (thisRGB < bestRGB)) { first = False; bestInx = i; bestRGB = thisRGB; } } } if (AllocOneColor(xw, &screen->cmap_data[bestInx])) { *def = screen->cmap_data[bestInx]; TRACE(("...closest %x/%x/%x\n", def->red, def->green, def->blue)); result = True; break; } /* * It failed - either the color map entry was readonly, or * another client has allocated the entry. Mark the entry * so we will ignore it */ tried[bestInx] = True; } free(tried); } } } return result; } #ifndef ULONG_MAX #define ULONG_MAX (unsigned long)(~(0L)) #endif /* * Allocate a color for the "ANSI" colors. That actually includes colors up * to 256. * * Returns * -1 on error * 0 on no change * 1 if a new color was allocated. */ static int AllocateAnsiColor(XtermWidget xw, ColorRes * res, const char *spec) { int result; XColor def; if (xtermAllocColor(xw, &def, spec)) { if (res->mode == True && EQL_COLOR_RES(res, def.pixel)) { result = 0; } else { result = 1; SET_COLOR_RES(res, def.pixel); res->red = def.red; res->green = def.green; res->blue = def.blue; TRACE(("AllocateAnsiColor[%d] %s (rgb:%04x/%04x/%04x, pixel 0x%06lx)\n", (int) (res - TScreenOf(xw)->Acolors), spec, def.red, def.green, def.blue, def.pixel)); if (!res->mode) result = 0; res->mode = True; } } else { TRACE(("AllocateAnsiColor %s (failed)\n", spec)); result = -1; } return (result); } Pixel xtermGetColorRes(XtermWidget xw, ColorRes * res) { Pixel result = 0; if (res->mode) { result = res->value; } else { TRACE(("xtermGetColorRes for Acolors[%d]\n", (int) (res - TScreenOf(xw)->Acolors))); if (res >= TScreenOf(xw)->Acolors) { assert(res - TScreenOf(xw)->Acolors < MAXCOLORS); if (AllocateAnsiColor(xw, res, res->resource) < 0) { res->value = TScreenOf(xw)->Tcolors[TEXT_FG].value; res->mode = -True; xtermWarning("Cannot allocate color \"%s\"\n", NonNull(res->resource)); } result = res->value; } else { result = 0; } } return result; } static int ChangeOneAnsiColor(XtermWidget xw, int color, const char *name) { int code; if (color < 0 || color >= MAXCOLORS) { code = -1; } else { ColorRes *res = &(TScreenOf(xw)->Acolors[color]); TRACE(("ChangeAnsiColor for Acolors[%d]\n", color)); code = AllocateAnsiColor(xw, res, name); } return code; } /* * Set or query entries in the Acolors[] array by parsing pairs of color/name * values from the given buffer. * * The color can be any legal index into Acolors[], which consists of the * 16/88/256 "ANSI" colors, followed by special color values for the various * colorXX resources. The indices for the special color values are not * simple to work with, so an alternative is to use the calls which pass in * 'first' set to the beginning of those indices. * * If the name is "?", report to the host the current value for the color. */ static Bool ChangeAnsiColorRequest(XtermWidget xw, int opcode, char *buf, int first, int final) { int repaint = False; int code; int last = (MAXCOLORS - first); int queried = 0; TRACE(("ChangeAnsiColorRequest string='%s'\n", buf)); while (buf && *buf) { int color; char *name = strchr(buf, ';'); if (name == NULL) break; *name = '\0'; name++; color = atoi(buf); if (color < 0 || color >= last) break; /* quit on any error */ buf = strchr(name, ';'); if (buf) { *buf = '\0'; buf++; } if (!strcmp(name, "?")) { if (ReportAnsiColorRequest(xw, opcode, color + first, final)) ++queried; } else { code = ChangeOneAnsiColor(xw, color + first, name); if (code < 0) { /* stop on any error */ break; } else if (code > 0) { repaint = True; } /* FIXME: free old color somehow? We aren't for the other color * change style (dynamic colors). */ } } if (queried) unparse_end(xw); return (repaint); } static Bool ResetOneAnsiColor(XtermWidget xw, int color, int start) { Bool repaint = False; int last = MAXCOLORS - start; if (color >= 0 && color < last) { ColorRes *res = &(TScreenOf(xw)->Acolors[color + start]); if (res->mode) { /* a color has been allocated for this slot - test further... */ if (ChangeOneAnsiColor(xw, color + start, res->resource) > 0) { repaint = True; } } } return repaint; } int ResetAnsiColorRequest(XtermWidget xw, char *buf, int start) { int repaint = 0; int color; TRACE(("ResetAnsiColorRequest(%s)\n", buf)); if (*buf != '\0') { /* reset specific colors */ while (!IsEmpty(buf)) { char *next; color = (int) (strtol) (buf, &next, 10); if (!PartS2L(buf, next) || (color < 0)) break; /* no number at all */ if (next != NULL) { if (strchr(";", *next) == NULL) break; /* unexpected delimiter */ ++next; } if (ResetOneAnsiColor(xw, color, start)) { ++repaint; } buf = next; } } else { TRACE(("...resetting all %d colors\n", MAXCOLORS)); for (color = 0; color < MAXCOLORS; ++color) { if (ResetOneAnsiColor(xw, color, start)) { ++repaint; } } } TRACE(("...ResetAnsiColorRequest ->%d\n", repaint)); return repaint; } #else #define allocateClosestRGB(xw, def) 0 #endif /* OPT_ISO_COLORS */ Boolean allocateBestRGB(XtermWidget xw, XColor *def) { (void) xw; (void) def; return AllocOneColor(xw, def) || allocateClosestRGB(xw, def); } static Boolean xtermAllocColor(XtermWidget xw, XColor *def, const char *spec) { Boolean result = False; TScreen *screen = TScreenOf(xw); Colormap cmap = xw->core.colormap; size_t have = strlen(spec); if (have == 0 || have > MAX_U_STRING) { if (resource.reportColors) { printf("color (ignored, length %lu)\n", (unsigned long) have); } } else if (XParseColor(screen->display, cmap, spec, def)) { XColor save_def = *def; if (resource.reportColors) { printf("color %04x/%04x/%04x = \"%s\"\n", def->red, def->green, def->blue, spec); } if (allocateBestRGB(xw, def)) { if (resource.reportColors) { if (def->red != save_def.red || def->green != save_def.green || def->blue != save_def.blue) { printf("color %04x/%04x/%04x ~ \"%s\"\n", def->red, def->green, def->blue, spec); } } TRACE(("xtermAllocColor -> %x/%x/%x\n", def->red, def->green, def->blue)); result = True; } } return result; } /* * This provides an approximation (the closest color from xterm's palette) * rather than the "exact" color (whatever the display could provide, actually) * because of the context in which it is used. */ #define ColorDiff(given,cache) ((long) ((cache) >> 8) - (long) (given)) int xtermClosestColor(XtermWidget xw, int find_red, int find_green, int find_blue) { int result = -1; #if OPT_ISO_COLORS int n; int best_index = -1; unsigned long best_value = 0; unsigned long this_value; long diff_red, diff_green, diff_blue; TRACE(("xtermClosestColor(%x/%x/%x)\n", find_red, find_green, find_blue)); for (n = NUM_ANSI_COLORS - 1; n >= 0; --n) { ColorRes *res = &(TScreenOf(xw)->Acolors[n]); /* ensure that we have a value for each of the colors */ if (!res->mode) { (void) AllocateAnsiColor(xw, res, res->resource); } /* find the closest match */ if (res->mode == True) { TRACE2(("...lookup %lx -> %x/%x/%x\n", res->value, res->red, res->green, res->blue)); diff_red = ColorDiff(find_red, res->red); diff_green = ColorDiff(find_green, res->green); diff_blue = ColorDiff(find_blue, res->blue); this_value = (unsigned long) ((diff_red * diff_red) + (diff_green * diff_green) + (diff_blue * diff_blue)); if (best_index < 0 || this_value < best_value) { best_index = n; best_value = this_value; } } } TRACE(("...best match at %d with diff %lx\n", best_index, best_value)); result = best_index; #else (void) xw; (void) find_red; (void) find_green; (void) find_blue; #endif return result; } #if OPT_DIRECT_COLOR int getDirectColor(XtermWidget xw, int red, int green, int blue) { Pixel result = 0; #define getRGB(name,shift) \ do { \ Pixel value = (Pixel) name & 0xff; \ if (xw->rgb_widths[shift] < 8) { \ value >>= (int) (8 - xw->rgb_widths[shift]); \ } \ value <<= xw->rgb_shifts[shift]; \ value &= xw->visInfo->name ##_mask; \ result |= value; \ } while (0) getRGB(red, 0); getRGB(green, 1); getRGB(blue, 2); #undef getRGB return (int) result; } static void formatDirectColor(char *target, XtermWidget xw, unsigned value) { Pixel result[3]; #define getRGB(name, shift) \ do { \ result[shift] = value & xw->visInfo->name ## _mask; \ result[shift] >>= xw->rgb_shifts[shift]; \ if (xw->rgb_widths[shift] < 8) \ result[shift] <<= (int) (8 - xw->rgb_widths[shift]); \ } while(0) getRGB(red, 0); getRGB(green, 1); getRGB(blue, 2); #undef getRGB sprintf(target, "%lu:%lu:%lu", result[0], result[1], result[2]); } #endif /* OPT_DIRECT_COLOR */ #define fg2SGR(n) \ (n) >= 8 ? 9 : 3, \ (n) >= 8 ? (n) - 8 : (n) #define bg2SGR(n) \ (n) >= 8 ? 10 : 4, \ (n) >= 8 ? (n) - 8 : (n) #define EndOf(s) (s) + strlen(s) char * xtermFormatSGR(XtermWidget xw, char *target, unsigned attr, int fg, int bg) { TScreen *screen = TScreenOf(xw); char *msg = target; strcpy(target, "0"); if (attr & BOLD) strcat(msg, ";1"); if (attr & UNDERLINE) strcat(msg, ";4"); if (attr & BLINK) strcat(msg, ";5"); if (attr & INVERSE) strcat(msg, ";7"); if (attr & INVISIBLE) strcat(msg, ";8"); #if OPT_WIDE_ATTRS if (attr & ATR_FAINT) strcat(msg, ";2"); if (attr & ATR_ITALIC) strcat(msg, ";3"); if (attr & ATR_STRIKEOUT) strcat(msg, ";9"); if (attr & ATR_DBL_UNDER) strcat(msg, ";21"); #endif #if OPT_256_COLORS || OPT_88_COLORS if_OPT_ISO_COLORS(screen, { if (attr & FG_COLOR) { if_OPT_DIRECT_COLOR2_else(screen, hasDirectFG(attr), { strcat(msg, ";38:2::"); formatDirectColor(EndOf(msg), xw, (unsigned) fg); }) if (fg >= 16) { sprintf(EndOf(msg), ";38:5:%d", fg); } else { sprintf(EndOf(msg), ";%d%d", fg2SGR(fg)); } } if (attr & BG_COLOR) { if_OPT_DIRECT_COLOR2_else(screen, hasDirectBG(attr), { strcat(msg, ";48:2::"); formatDirectColor(EndOf(msg), xw, (unsigned) bg); }) if (bg >= 16) { sprintf(EndOf(msg), ";48:5:%d", bg); } else { sprintf(EndOf(msg), ";%d%d", bg2SGR(bg)); } } }); #elif OPT_ISO_COLORS if_OPT_ISO_COLORS(screen, { if (attr & FG_COLOR) { sprintf(EndOf(msg), ";%d%d", fg2SGR(fg)); } if (attr & BG_COLOR) { sprintf(EndOf(msg), ";%d%d", bg2SGR(bg)); } }); #else (void) screen; (void) fg; (void) bg; #endif return target; } #if OPT_PASTE64 static void ManipulateSelectionData(XtermWidget xw, TScreen *screen, char *buf, int final) { #define PDATA(a,b) { a, #b } static struct { char given; String result; } table[] = { PDATA('s', SELECT), PDATA('p', PRIMARY), PDATA('q', SECONDARY), PDATA('c', CLIPBOARD), PDATA('0', CUT_BUFFER0), PDATA('1', CUT_BUFFER1), PDATA('2', CUT_BUFFER2), PDATA('3', CUT_BUFFER3), PDATA('4', CUT_BUFFER4), PDATA('5', CUT_BUFFER5), PDATA('6', CUT_BUFFER6), PDATA('7', CUT_BUFFER7), }; char target_used[XtNumber(table)]; const char *base = buf; Cardinal j; Cardinal num_targets = 0; TRACE(("Manipulate selection data\n")); memset(target_used, 0, sizeof(target_used)); while (*buf != ';' && *buf != '\0') { ++buf; } if (*buf == ';') { char select_code[XtNumber(table) + 1]; String select_args[XtNumber(table) + 1]; *buf++ = '\0'; if (*base == '\0') base = "s0"; while (*base != '\0') { for (j = 0; j < XtNumber(table); ++j) { if (*base == table[j].given) { if (!target_used[j]) { target_used[j] = 1; select_code[num_targets] = *base; select_args[num_targets++] = table[j].result; TRACE(("atom[%d] %s\n", num_targets, table[j].result)); } break; } } ++base; } select_code[num_targets] = '\0'; if (!strcmp(buf, "?")) { if (AllowWindowOps(xw, ewGetSelection)) { TRACE(("Getting selection\n")); unparseputc1(xw, ANSI_OSC); unparseputs(xw, "52"); unparseputc(xw, ';'); unparseputs(xw, select_code); unparseputc(xw, ';'); /* Tell xtermGetSelection data is base64 encoded */ screen->base64_paste = num_targets; screen->base64_final = final; screen->selection_time = XtLastTimestampProcessed(TScreenOf(xw)->display); /* terminator will be written in this call */ xtermGetSelection((Widget) xw, screen->selection_time, select_args, num_targets, NULL); } } else { if (AllowWindowOps(xw, ewSetSelection)) { char *old = buf; TRACE(("Setting selection(%s) with %s\n", select_code, buf)); screen->selection_time = XtLastTimestampProcessed(TScreenOf(xw)->display); for (j = 0; j < num_targets; ++j) { buf = old; ClearSelectionBuffer(screen, select_args[j]); while (*buf != '\0') { AppendToSelectionBuffer(screen, CharOf(*buf++), select_args[j]); } } CompleteSelection(xw, select_args, num_targets); } } } } #endif /* OPT_PASTE64 */ /***====================================================================***/ static Bool xtermIsPrintable(XtermWidget xw, Char **bufp, Char *last) { TScreen *screen = TScreenOf(xw); Bool result = False; Char *cp = *bufp; Char *next = cp; (void) screen; (void) last; #if OPT_WIDE_CHARS if (xtermEnvUTF8() && IsSetUtf8Title(xw)) { PtyData data; if (decodeUtf8(screen, fakePtyData(&data, cp, last))) { if (!is_UCS_SPECIAL(data.utf_data) && (data.utf_data >= 128 || ansi_table[data.utf_data] == CASE_PRINT)) { next += (data.utf_size - 1); result = True; } else { result = False; } } else { result = False; } } else #endif #if OPT_C1_PRINT if (screen->c1_printable && (*cp >= 128 && *cp < 160)) { result = True; } else #endif if (ansi_table[*cp] == CASE_PRINT) { result = True; } *bufp = next; return result; } /***====================================================================***/ /* * Map codes to OSC controls that can reset colors. */ #define OSC_RESET 100 #define OSC_Reset(code) (code) + OSC_RESET /* * Other (non-color) OSC controls */ typedef enum { OSC_IconBoth = 0 ,OSC_IconOnly = 1 ,OSC_TitleOnly = 2 ,OSC_X_Property = 3 ,OSC_SetAnsiColor = 4 ,OSC_GetAnsiColors = 5 ,OSC_ColorMode = 6 ,OSC_SetupPointer = 22 ,OSC_Unused_30 = 30 /* Konsole (unused) */ ,OSC_Unused_31 = 31 /* Konsole (unused) */ ,OSC_NewLogFile = 46 ,OSC_FontOps = 50 ,OSC_Unused_51 /* Emacs (unused) */ ,OSC_SelectionData = 52 ,OSC_AllowedOps = 60 ,OSC_DisallowedOps = 61 } OscMiscOps; static Bool GetOldColors(XtermWidget xw) { if (xw->work.oldColors == NULL) { int i; xw->work.oldColors = TypeXtMalloc(ScrnColors); if (xw->work.oldColors == NULL) { xtermWarning("allocation failure in GetOldColors\n"); return (False); } xw->work.oldColors->which = 0; for (i = 0; i < NCOLORS; i++) { xw->work.oldColors->colors[i] = 0; xw->work.oldColors->names[i] = NULL; } GetColors(xw, xw->work.oldColors); } return (True); } static int oppositeColor(XtermWidget xw, int n) { Boolean reversed = (xw->misc.re_verse); switch (n) { case TEXT_FG: n = reversed ? TEXT_FG : TEXT_BG; break; case TEXT_BG: n = reversed ? TEXT_BG : TEXT_FG; break; case MOUSE_FG: n = MOUSE_BG; break; case MOUSE_BG: n = MOUSE_FG; break; #if OPT_TEK4014 case TEK_FG: n = reversed ? TEK_FG : TEK_BG; break; case TEK_BG: n = reversed ? TEK_BG : TEK_FG; break; #endif #if OPT_HIGHLIGHT_COLOR case HIGHLIGHT_FG: n = HIGHLIGHT_BG; break; case HIGHLIGHT_BG: n = HIGHLIGHT_FG; break; #endif default: break; } return n; } static Bool ReportColorRequest(XtermWidget xw, int ndx, int final) { Bool result = False; if (AllowColorOps(xw, ecGetColor)) { XColor color; char buffer[80]; /* * ChangeColorsRequest() has "always" chosen the opposite color when * reverse-video is set. Report this as the original color index, but * reporting the opposite color which would be used. */ int i = (xw->misc.re_verse) ? oppositeColor(xw, ndx) : ndx; GetOldColors(xw); color.pixel = xw->work.oldColors->colors[ndx]; (void) QueryOneColor(xw, &color); sprintf(buffer, "%d;rgb:%04x/%04x/%04x", i + 10, color.red, color.green, color.blue); TRACE(("ReportColorRequest #%d: 0x%06lx as %s\n", ndx, xw->work.oldColors->colors[ndx], buffer)); unparseputc1(xw, ANSI_OSC); unparseputs(xw, buffer); unparseputc1(xw, final); result = True; } return result; } static Bool UpdateOldColors(XtermWidget xw, ScrnColors * pNew) { int i; /* if we were going to free old colors, this would be the place to * do it. I've decided not to (for now), because it seems likely * that we'd have a small set of colors we use over and over, and that * we could save some overhead this way. The only case in which this * (clearly) fails is if someone is trying a boatload of colors, in * which case they can restart xterm */ for (i = 0; i < NCOLORS; i++) { if (COLOR_DEFINED(pNew, i)) { if (xw->work.oldColors->names[i] != NULL) { XtFree(xw->work.oldColors->names[i]); xw->work.oldColors->names[i] = NULL; } if (pNew->names[i]) { xw->work.oldColors->names[i] = pNew->names[i]; } xw->work.oldColors->colors[i] = pNew->colors[i]; } } return (True); } /* * OSC codes are constant, but the indices for the color arrays depend on how * xterm is compiled. */ static int OscToColorIndex(OscTextColors mode) { int result = 0; #define CASE(name) case OSC_##name: result = name; break switch (mode) { CASE(TEXT_FG); CASE(TEXT_BG); CASE(TEXT_CURSOR); CASE(MOUSE_FG); CASE(MOUSE_BG); #if OPT_TEK4014 CASE(TEK_FG); CASE(TEK_BG); #endif #if OPT_HIGHLIGHT_COLOR CASE(HIGHLIGHT_BG); CASE(HIGHLIGHT_FG); #endif #if OPT_TEK4014 CASE(TEK_CURSOR); #endif case OSC_NCOLORS: break; } #undef CASE return result; } static Bool ChangeColorsRequest(XtermWidget xw, int start, char *names, int final) { Bool result = False; ScrnColors newColors; TRACE(("ChangeColorsRequest start=%d, names='%s'\n", start, names)); if (GetOldColors(xw)) { int i; int queried = 0; newColors.which = 0; for (i = 0; i < NCOLORS; i++) { newColors.names[i] = NULL; } for (i = start; i < OSC_NCOLORS; i++) { int ndx = OscToColorIndex((OscTextColors) i); if (xw->misc.re_verse) ndx = oppositeColor(xw, ndx); if (IsEmpty(names)) { newColors.names[ndx] = NULL; } else { char *thisName = ((names[0] == ';') ? NULL : names); names = strchr(names, ';'); if (names != NULL) { *names++ = '\0'; } if (thisName != NULL) { if (!strcmp(thisName, "?")) { if (ReportColorRequest(xw, ndx, final)) ++queried; } else if (!xw->work.oldColors->names[ndx] || strcmp(thisName, xw->work.oldColors->names[ndx])) { AllocateTermColor(xw, &newColors, ndx, thisName, False); } } } } if (newColors.which != 0) { ChangeColors(xw, &newColors); UpdateOldColors(xw, &newColors); } else if (queried) { unparse_end(xw); } result = True; } return result; } static Bool ResetColorsRequest(XtermWidget xw, int code) { Bool result = False; (void) xw; (void) code; TRACE(("ResetColorsRequest code=%d\n", code)); if (GetOldColors(xw)) { ScrnColors newColors; const char *thisName; int ndx = OscToColorIndex((OscTextColors) (code - OSC_RESET)); if (xw->misc.re_verse) ndx = oppositeColor(xw, ndx); thisName = xw->screen.Tcolors[ndx].resource; newColors.which = 0; newColors.names[ndx] = NULL; if (thisName != NULL && xw->work.oldColors->names[ndx] != NULL && strcmp(thisName, xw->work.oldColors->names[ndx])) { AllocateTermColor(xw, &newColors, ndx, thisName, False); if (newColors.which != 0) { ChangeColors(xw, &newColors); UpdateOldColors(xw, &newColors); } } result = True; } return result; } #if OPT_SHIFT_FONTS /* * Initially, 'source' points to '#' or '?'. * * Look for an optional sign and optional number. If those are found, lookup * the corresponding menu font entry. */ static int ParseShiftedFont(XtermWidget xw, String source, String *target) { TScreen *screen = TScreenOf(xw); int num = screen->menu_font_number; int rel = 0; if (*++source == '+') { rel = 1; source++; } else if (*source == '-') { rel = -1; source++; } if (isdigit(CharOf(*source))) { int val = atoi(source); if (rel > 0) rel = val; else if (rel < 0) rel = -val; else num = val; } if (rel != 0) { num = lookupRelativeFontSize(xw, screen->menu_font_number, rel); } TRACE(("ParseShiftedFont(%s) ->%d (%s)\n", *target, num, source)); *target = source; return num; } static void QueryFontRequest(XtermWidget xw, String buf, int final) { if (AllowFontOps(xw, efGetFont)) { TScreen *screen = TScreenOf(xw); Bool success = True; int num; String base = buf + 1; const char *name = NULL; num = ParseShiftedFont(xw, buf, &buf); if (num < 0 || num > fontMenu_lastBuiltin) { Bell(xw, XkbBI_MinorError, 0); success = False; } else { #if OPT_RENDERFONT if (UsingRenderFont(xw)) { name = getFaceName(xw, False); } else #endif if ((name = screen->MenuFontName(num)) == NULL) { success = False; } } unparseputc1(xw, ANSI_OSC); unparseputs(xw, "50"); if (success) { unparseputc(xw, ';'); if (buf >= base) { /* identify the font-entry, unless it is the current one */ if (*buf != '\0') { char temp[10]; unparseputc(xw, '#'); sprintf(temp, "%d", num); unparseputs(xw, temp); if (*name != '\0') unparseputc(xw, ' '); } } unparseputs(xw, name); } unparseputc1(xw, final); unparse_end(xw); } } static void ChangeFontRequest(XtermWidget xw, String buf) { if (AllowFontOps(xw, efSetFont)) { TScreen *screen = TScreenOf(xw); Bool success = True; int num; VTFontNames fonts; char *name; /* * If the font specification is a "#", followed by an optional sign and * optional number, lookup the corresponding menu font entry. * * Further, if the "#", etc., is followed by a font name, use that * to load the font entry. */ if (*buf == '#') { num = ParseShiftedFont(xw, buf, &buf); if (num < 0 || num > fontMenu_lastBuiltin) { Bell(xw, XkbBI_MinorError, 0); success = False; } else { /* * Skip past the optional number, and any whitespace to look * for a font specification within the control. */ while (isdigit(CharOf(*buf))) { ++buf; } while (isspace(CharOf(*buf))) { ++buf; } #if OPT_RENDERFONT if (UsingRenderFont(xw)) { /* EMPTY */ /* there is only one font entry to load */ ; } else #endif { /* * Normally there is no font specified in the control. * But if there is, simply overwrite the font entry. */ if (*buf == '\0') { if ((buf = screen->MenuFontName(num)) == NULL) { success = False; } } } } } else { num = screen->menu_font_number; } name = x_strtrim(buf); if (screen->EscapeFontName()) { FREE_STRING(screen->EscapeFontName()); screen->EscapeFontName() = NULL; } if (success && !IsEmpty(name)) { #if OPT_RENDERFONT if (UsingRenderFont(xw)) { setFaceName(xw, name); xtermUpdateFontInfo(xw, True); } else #endif { memset(&fonts, 0, sizeof(fonts)); fonts.f_n = name; if (SetVTFont(xw, num, True, &fonts) && num == screen->menu_font_number && num != fontMenu_fontescape) { screen->EscapeFontName() = x_strdup(name); } } } else { Bell(xw, XkbBI_MinorError, 0); } update_font_escape(); free(name); } } #endif /* OPT_SHIFT_FONTS */ /***====================================================================***/ static void report_allowed_ops(XtermWidget xw, int final) { TScreen *screen = TScreenOf(xw); char delimiter = ';'; unparseputc1(xw, ANSI_OSC); unparseputn(xw, OSC_AllowedOps); #define CASE(name) \ if (screen->name) { \ unparseputc(xw, delimiter); \ unparseputs(xw, #name); \ delimiter = ','; \ } CASE(allowColorOps); CASE(allowFontOps); CASE(allowMouseOps); CASE(allowPasteControls); CASE(allowTcapOps); CASE(allowTitleOps); CASE(allowWindowOps); (void) delimiter; #undef CASE unparseputc1(xw, final); } static void report_disallowed_ops(XtermWidget xw, char *value, int final) { unparseputc1(xw, ANSI_OSC); unparseputn(xw, OSC_DisallowedOps); unparse_disallowed_ops(xw, value); unparseputc1(xw, final); } /***====================================================================***/ void do_osc(XtermWidget xw, Char *oscbuf, size_t len, int final) { TScreen *screen = TScreenOf(xw); int mode; Char *cp; int state = 0; char *buf = NULL; char temp[20]; #if OPT_ISO_COLORS int ansi_colors = 0; #endif Bool need_data = True; Bool optional_data = False; TRACE(("do_osc %s\n", oscbuf)); (void) screen; /* * Lines should be of the form number ; string , however * older xterms can accept as a final character. We will respond * with the same final character as the application sends to make this * work better with shell scripts, which may have trouble reading an * , which is the 7-bit equivalent to . */ mode = 0; for (cp = oscbuf; *cp != '\0'; cp++) { switch (state) { case 0: if (isdigit(*cp)) { mode = 10 * mode + (*cp - '0'); if (mode > 65535) { TRACE(("do_osc found unknown mode %d\n", mode)); return; } break; } else { switch (*cp) { case 'I': xtermLoadIcon(xw, (char *) ++cp); return; case 'l': ChangeTitle(xw, (char *) ++cp); return; case 'L': ChangeIconName(xw, (char *) ++cp); return; } } /* FALLTHRU */ case 1: if (*cp != ';') { TRACE(("do_osc did not find semicolon offset %lu\n", (unsigned long) (cp - oscbuf))); return; } state = 2; break; case 2: buf = (char *) cp; state = 3; /* FALLTHRU */ default: if (!xtermIsPrintable(xw, &cp, oscbuf + len)) { switch (mode) { case 0: case 1: case 2: break; default: TRACE(("do_osc found nonprinting char %02X offset %lu\n", CharOf(*cp), (unsigned long) (cp - oscbuf))); return; } } } } /* * Check if the palette changed and there are no more immediate changes * that could be deferred to the next repaint. */ if (xw->work.palette_changed) { switch (mode) { case OSC_AllowedOps: case OSC_DisallowedOps: case OSC_FontOps: case OSC_NewLogFile: case OSC_SelectionData: case OSC_Unused_30: case OSC_Unused_31: case OSC_Unused_51: case OSC_X_Property: TRACE(("forced repaint after palette changed\n")); xw->work.palette_changed = False; xtermRepaint(xw); break; default: xtermNeedSwap(xw, 1); break; } } /* * Most OSC controls other than resets require data. Handle the others as * a special case. */ switch (mode) { case OSC_FontOps: #if OPT_ISO_COLORS case OSC_Reset(OSC_SetAnsiColor): case OSC_Reset(OSC_GetAnsiColors): need_data = False; optional_data = True; break; case OSC_Reset(OSC_TEXT_FG): case OSC_Reset(OSC_TEXT_BG): case OSC_Reset(OSC_TEXT_CURSOR): case OSC_Reset(OSC_MOUSE_FG): case OSC_Reset(OSC_MOUSE_BG): #if OPT_HIGHLIGHT_COLOR case OSC_Reset(OSC_HIGHLIGHT_BG): case OSC_Reset(OSC_HIGHLIGHT_FG): #endif #if OPT_TEK4014 case OSC_Reset(OSC_TEK_FG): case OSC_Reset(OSC_TEK_BG): case OSC_Reset(OSC_TEK_CURSOR): #endif case OSC_AllowedOps: need_data = False; break; #endif default: break; } /* * Check if we have data when we want, and not when we do not want it. * Either way, that is a malformed control sequence, and will be ignored. */ if (IsEmpty(buf)) { if (need_data) { switch (mode) { case 0: case 1: case 2: buf = strcpy(temp, "xterm"); break; default: TRACE(("do_osc found no data\n")); return; } } else { temp[0] = '\0'; buf = temp; } } else if (!need_data && !optional_data) { TRACE(("do_osc found unwanted data\n")); return; } switch (mode) { case OSC_IconBoth: /* new icon name and title */ ChangeIconName(xw, buf); ChangeTitle(xw, buf); break; case OSC_IconOnly: /* new icon name only */ ChangeIconName(xw, buf); break; case OSC_TitleOnly: /* new title only */ ChangeTitle(xw, buf); break; case OSC_X_Property: /* change X property */ if (AllowWindowOps(xw, ewSetXprop)) ChangeXprop(buf); break; #if OPT_ISO_COLORS case OSC_GetAnsiColors: ansi_colors = NUM_ANSI_COLORS; /* FALLTHRU */ case OSC_SetAnsiColor: if (ChangeAnsiColorRequest(xw, mode, buf, ansi_colors, final)) xw->work.palette_changed = True; break; case OSC_ColorMode: /* FALLTHRU */ case OSC_Reset(OSC_ColorMode): TRACE(("parse colorXXMode:%s\n", buf)); while (*buf != '\0') { long which = 0; long value = 0; char *next; if (*buf == ';') { ++buf; } else { which = strtol(buf, &next, 10); if (!PartS2L(buf, next) || (which < 0)) break; buf = next; if (*buf == ';') ++buf; } if (*buf == ';') { ++buf; } else { value = strtol(buf, &next, 10); if (!PartS2L(buf, next) || (value < 0)) break; buf = next; if (*buf == ';') ++buf; } TRACE(("updating colorXXMode which=%ld, value=%ld\n", which, value)); switch (which) { case 0: screen->colorBDMode = (value != 0); break; case 1: screen->colorULMode = (value != 0); break; case 2: screen->colorBLMode = (value != 0); break; case 3: screen->colorRVMode = (value != 0); break; #if OPT_WIDE_ATTRS case 4: screen->colorITMode = (value != 0); break; #endif default: TRACE(("...unknown colorXXMode\n")); break; } } break; case OSC_Reset(OSC_GetAnsiColors): ansi_colors = NUM_ANSI_COLORS; /* FALLTHRU */ case OSC_Reset(OSC_SetAnsiColor): if (ResetAnsiColorRequest(xw, buf, ansi_colors)) xw->work.palette_changed = True; break; #endif case OSC_TEXT_FG: case OSC_TEXT_BG: case OSC_TEXT_CURSOR: case OSC_MOUSE_FG: case OSC_MOUSE_BG: #if OPT_HIGHLIGHT_COLOR case OSC_HIGHLIGHT_BG: case OSC_HIGHLIGHT_FG: #endif #if OPT_TEK4014 case OSC_TEK_FG: case OSC_TEK_BG: case OSC_TEK_CURSOR: #endif if (xw->misc.dynamicColors) { ChangeColorsRequest(xw, mode, buf, final); } break; case OSC_Reset(OSC_TEXT_FG): case OSC_Reset(OSC_TEXT_BG): case OSC_Reset(OSC_TEXT_CURSOR): case OSC_Reset(OSC_MOUSE_FG): case OSC_Reset(OSC_MOUSE_BG): #if OPT_HIGHLIGHT_COLOR case OSC_Reset(OSC_HIGHLIGHT_BG): case OSC_Reset(OSC_HIGHLIGHT_FG): #endif #if OPT_TEK4014 case OSC_Reset(OSC_TEK_FG): case OSC_Reset(OSC_TEK_BG): case OSC_Reset(OSC_TEK_CURSOR): #endif if (xw->misc.dynamicColors) { ResetColorsRequest(xw, mode); } break; case OSC_SetupPointer: xtermSetupPointer(xw, buf); break; #ifdef ALLOWLOGGING case OSC_NewLogFile: #ifdef ALLOWLOGFILECHANGES /* * Warning, enabling this feature allows people to overwrite * arbitrary files accessible to the person running xterm. */ if (strcmp(buf, "?")) { char *bp; if ((bp = x_strdup(buf)) != NULL) { free(screen->logfile); screen->logfile = bp; break; } } #endif Bell(xw, XkbBI_Info, 0); Bell(xw, XkbBI_Info, 0); break; #endif /* ALLOWLOGGING */ case OSC_FontOps: #if OPT_SHIFT_FONTS if (*buf == '?') { QueryFontRequest(xw, buf, final); } else if (xw->misc.shift_fonts) { ChangeFontRequest(xw, buf); } #endif /* OPT_SHIFT_FONTS */ break; #if OPT_PASTE64 case OSC_SelectionData: ManipulateSelectionData(xw, screen, buf, final); break; #endif case OSC_AllowedOps: /* XTQALLOWED */ report_allowed_ops(xw, final); break; case OSC_DisallowedOps: /* XTQDISALLOWED */ report_disallowed_ops(xw, buf, final); break; case OSC_Unused_30: case OSC_Unused_31: case OSC_Unused_51: default: TRACE(("do_osc - unrecognized code\n")); break; } unparse_end(xw); } /* * Parse one nibble of a hex byte from the OSC string. We have removed the * string-terminator (replacing it with a null), so the only other delimiter * that is expected is semicolon. Ignore other characters (Ray Neuman says * "real" terminals accept commas in the string definitions). */ static int udk_value(const char **cp) { int result = -1; for (;;) { int c; if ((c = **cp) != '\0') *cp = *cp + 1; if (c == ';' || c == '\0') break; if ((result = x_hex2int(c)) >= 0) break; } return result; } void reset_decudk(XtermWidget xw) { int n; for (n = 0; n < MAX_UDK; n++) { FreeAndNull(xw->work.user_keys[n].str); xw->work.user_keys[n].len = 0; } } /* * Parse the data for DECUDK (user-defined keys). */ static void parse_decudk(XtermWidget xw, const char *cp) { while (*cp) { const char *base = cp; char *str = malloc(strlen(cp) + 3); unsigned key = 0; int len = 0; if (str == NULL) break; while (isdigit(CharOf(*cp))) key = (key * 10) + (unsigned) (*cp++ - '0'); if (*cp == '/') { int lo, hi; cp++; while ((hi = udk_value(&cp)) >= 0 && (lo = udk_value(&cp)) >= 0) { str[len++] = (char) ((hi << 4) | lo); } } if (len > 0 && key < MAX_UDK) { str[len] = '\0'; free(xw->work.user_keys[key].str); xw->work.user_keys[key].str = str; xw->work.user_keys[key].len = len; TRACE(("parse_decudk %d:%.*s\n", key, len, str)); } else { free(str); } if (*cp == ';') cp++; if (cp == base) /* badly-formed sequence - bail out */ break; } } /* * Parse numeric parameters. Normally we use a state machine to simplify * interspersing with control characters, but have the string already. */ void parse_ansi_params(ANSI *params, const char **string) { const char *cp = *string; ParmType nparam = 0; int last_empty = 1; memset(params, 0, sizeof(*params)); while (*cp != '\0') { Char ch = CharOf(*cp++); if (isdigit(ch)) { last_empty = 0; if (nparam < NPARAM) { params->a_param[nparam] = (ParmType) ((params->a_param[nparam] * 10) + (ch - '0')); } } else if (ch == ';') { last_empty = 1; nparam++; } else if (ch < 32) { /* EMPTY */ ; } else { /* should be 0x30 to 0x7e */ params->a_final = ch; break; } } *string = cp; if (!last_empty) nparam++; if (nparam > NPARAM) params->a_nparam = NPARAM; else params->a_nparam = nparam; } #if OPT_TRACE #define SOFT_WIDE 10 #define SOFT_HIGH 20 static void parse_decdld(ANSI *params, const char *string) { char DscsName[8]; int len; int Pfn = params->a_param[0]; int Pcn = params->a_param[1]; int Pe = params->a_param[2]; int Pcmw = params->a_param[3]; int Pw = params->a_param[4]; int Pt = params->a_param[5]; int Pcmh = params->a_param[6]; int Pcss = params->a_param[7]; int start_char = Pcn + 0x20; int char_wide = ((Pcmw == 0) ? (Pcss ? 6 : 10) : (Pcmw > 4 ? Pcmw : (Pcmw + 3))); int char_high = ((Pcmh == 0) ? ((Pcmw >= 2 && Pcmw <= 4) ? 10 : 20) : Pcmh); Char ch; Char bits[SOFT_HIGH][SOFT_WIDE]; Bool first = True; Bool prior = False; int row = 0, col = 0; TRACE(("Parsing DECDLD\n")); TRACE((" font number %d\n", Pfn)); TRACE((" starting char %d\n", Pcn)); TRACE((" erase control %d\n", Pe)); TRACE((" char-width %d\n", Pcmw)); TRACE((" font-width %d\n", Pw)); TRACE((" text/full %d\n", Pt)); TRACE((" char-height %d\n", Pcmh)); TRACE((" charset-size %d\n", Pcss)); if (Pfn > 1 || Pcn > 95 || Pe > 2 || Pcmw > 10 || Pcmw == 1 || Pt > 2 || Pcmh > 20 || Pcss > 1 || char_wide > SOFT_WIDE || char_high > SOFT_HIGH) { TRACE(("DECDLD illegal parameter\n")); return; } len = 0; while (*string != '\0') { ch = CharOf(*string++); if (ch >= ANSI_SPA && ch <= 0x2f) { if (len < 2) DscsName[len++] = (char) ch; } else if (ch >= 0x30 && ch <= 0x7e) { DscsName[len++] = (char) ch; break; } } DscsName[len] = 0; TRACE((" Dscs name '%s'\n", DscsName)); TRACE((" character matrix %dx%d\n", char_high, char_wide)); while (*string != '\0') { if (first) { TRACE(("Char %d:\n", start_char)); if (prior) { for (row = 0; row < char_high; ++row) { TRACE(("%.*s\n", char_wide, bits[row])); } } prior = False; first = False; for (row = 0; row < char_high; ++row) { for (col = 0; col < char_wide; ++col) { bits[row][col] = '.'; } } row = col = 0; } ch = CharOf(*string++); if (ch >= 0x3f && ch <= 0x7e) { int n; ch = CharOf(ch - 0x3f); for (n = 0; n < 6; ++n) { bits[row + n][col] = CharOf((ch & xBIT(n)) ? '*' : '.'); } col += 1; prior = True; } else if (ch == '/') { row += 6; col = 0; } else if (ch == ';') { first = True; ++start_char; } } } #else #define parse_decdld(p,q) /* nothing */ #endif static const char * skip_params(const char *cp) { while (*cp == ';' || (*cp >= '0' && *cp <= '9')) ++cp; return cp; } #if OPT_MOD_FKEYS || OPT_DEC_RECTOPS || (OPT_VT525_COLORS && OPT_ISO_COLORS) static int parse_int_param(const char **cp) { Boolean found = False; int result = 0; const char *s = *cp; while (*s != '\0') { if (*s == ';') { ++s; break; } else if (*s >= '0' && *s <= '9') { result = (result * 10) + (*s++ - '0'); found = True; } else { s += strlen(s); } } TRACE(("parse-int \"%s\" ->%d, %#x->\"%s\"\n", *cp, result, result, s)); *cp = s; return found ? result : -1; } #endif #if OPT_DEC_RECTOPS static int parse_chr_param(const char **cp) { int result = 0; const char *s = *cp; if (*s != '\0') { if ((result = CharOf(*s++)) != 0) { if (*s == ';') { ++s; } else if (*s != '\0') { result = 0; } } } TRACE(("parse-chr %s ->%#x, %#x->%s\n", *cp, result, result, s)); *cp = s; return result; } #if OPT_TRACE #define done_DECCIR() do { TRACE(("...quit DECCIR @%d\n", __LINE__)); return; } while(0) #else #define done_DECCIR() return #endif static void restore_DECCIR(XtermWidget xw, const char *cp) { TScreen *screen = TScreenOf(xw); int value; /* row */ if ((value = parse_int_param(&cp)) <= 0 || value > MaxRows(screen)) done_DECCIR(); screen->cur_row = (value - 1); /* column */ if ((value = parse_int_param(&cp)) <= 0 || value > MaxCols(screen)) done_DECCIR(); screen->cur_col = (value - 1); /* page */ if (parse_int_param(&cp) != 1) done_DECCIR(); /* rendition */ if (((value = parse_chr_param(&cp)) & 0xf0) != 0x40) { if (value & 0x10) { /* * VT420 is documented for bit 5 always reset; VT520/VT525 are not * documented, but do use the bit for setting invisible mode. */ if (screen->vtXX_level <= 4) done_DECCIR(); } else if (!(value & 0x40)) { done_DECCIR(); } } UIntClr(xw->flags, (INVERSE | BLINK | UNDERLINE | BOLD)); xw->flags |= (value & 16) ? INVISIBLE : 0; xw->flags |= (value & 8) ? INVERSE : 0; xw->flags |= (value & 4) ? BLINK : 0; xw->flags |= (value & 2) ? UNDERLINE : 0; xw->flags |= (value & 1) ? BOLD : 0; /* attributes */ if (((value = parse_chr_param(&cp)) & 0xfe) != 0x40) done_DECCIR(); screen->protected_mode &= ~DEC_PROTECT; screen->protected_mode |= (value & 1) ? DEC_PROTECT : 0; /* flags */ if (((value = parse_chr_param(&cp)) & 0xf0) != 0x40) done_DECCIR(); screen->do_wrap = (value & 8) ? True : False; screen->curss = (Char) ((value & 4) ? 3 : ((value & 2) ? 2 : 0)); UIntClr(xw->flags, ORIGIN); xw->flags |= (value & 1) ? ORIGIN : 0; if ((value = (parse_chr_param(&cp) - '0')) < 0 || value >= NUM_GSETS) done_DECCIR(); screen->curgl = (Char) value; if ((value = (parse_chr_param(&cp) - '0')) < 0 || value >= NUM_GSETS) done_DECCIR(); screen->curgr = (Char) value; /* character-set size */ if (parse_chr_param(&cp) == 0xffff) /* FIXME: limit SCS? */ done_DECCIR(); /* SCS designators */ for (value = 0; value < NUM_GSETS; ++value) { if (*cp == '\0') { done_DECCIR(); } else if (strchr("%&\"", *cp) != NULL) { int prefix = *cp++; xtermDecodeSCS(xw, value, 0, prefix, *cp); } else { xtermDecodeSCS(xw, value, 0, '\0', *cp); } cp++; } TRACE(("...done DECCIR\n")); } static void restore_DECTABSR(XtermWidget xw, const char *cp) { int stop = 0; Bool fail = False; TabZonk(xw->tabs); while (*cp != '\0' && !fail) { if ((*cp) >= '0' && (*cp) <= '9') { stop = (stop * 10) + ((*cp) - '0'); } else if (*cp == '/') { --stop; if (OkTAB(stop)) { TabSet(xw->tabs, stop); } stop = 0; } else { fail = True; } ++cp; } --stop; if (OkTAB(stop)) TabSet(xw->tabs, stop); TRACE(("...done DECTABSR\n")); } #endif /* OPT_DEC_RECTOPS */ /* * VT510 and VT520 reference manual have the same explanation for Pn (params), * but it does not agree with the possible values for Dscs because it refers * to "ISO Latin-7" (ISO 8859-13 aka "Baltic Rim"), and omits ISO Greek * (ISO 8859-7): * * ------------------------------------------------------------------------ * Pn Meaning * ------------------------------------------------------------------------ * 0 DEC, ISO Latin-1, ISO Latin-2 * 1 ISO Latin-5, ISO Latin-7, ISO Cyrillic, ISO Hebrew * ------------------------------------------------------------------------ * * versus * * ------------------------------------------------------------------------ * Dscs Character Set * ------------------------------------------------------------------------ * %5 DEC Supplemental * "? DEC Greek * "4 DEC Hebrew * %0 DEC Turkish * &4 DEC Cyrillic * < User-preferred Supplemental * A ISO Latin-1 Supplemental * B ISO Latin-2 Supplemental * F ISO Greek Supplemental * H ISO Hebrew Supplemental * M ISO Latin-5 Supplemental * L ISO Latin-Cyrillic * ------------------------------------------------------------------------ * * DEC 070, page 5-123 explains that Pn ("Ps" in the text) selects 94 or 96 * character sets (0 or 1, respectively), and on the next page states that * the valid combinations are 0 (DEC Supplemental) and 1 (ISO Latin-1 * supplemental). The document comments in regard to LS0 that (applications) * should not assume that they can use 96-character sets for G0, but that it * is possible to do this using UPSS. * * The VT510/VT520 reference manuals under SCS Select Character Set show * a list of 94- and 96-character sets with "DEC" and "NRCS" as 94-characters, * and the "ISO" as 96-characters. A few 94-character sets are added, based * on testing VT520/VT525 that shows that DEC Special Graphics also is allowed. */ static Bool decode_upss(XtermWidget xw, const char *cp, char psarg, DECNRCM_codes * upss) { /* *INDENT-OFF* */ static const struct { DECNRCM_codes code; int params; /* 0 for 94-characters, 1 for 96-characters */ int prefix; int suffix; int min_level; int max_level; } upss_table[] = { { DFT_UPSS, 0, '%', '5', 3, 9 }, { nrc_ASCII, 0, 0, 'A', 1, 9 }, /* undocumented */ { nrc_DEC_Spec_Graphic, 0, 0, '0', 1, 9 }, /* undocumented */ { nrc_DEC_Technical, 0, 0, '>', 3, 9 }, /* undocumented */ { nrc_DEC_Greek_Supp, 0, '"', '?', 5, 9 }, { nrc_DEC_Hebrew_Supp, 0, '"', '4', 5, 9 }, { nrc_DEC_Turkish_Supp, 0, '%', '0', 5, 9 }, { nrc_DEC_Cyrillic, 0, '&', '4', 5, 9 }, { ALT_UPSS, 1, 0, 'A', 3, 9 }, { nrc_ISO_Latin_2_Supp, 1, 0, 'B', 5, 9 }, { nrc_ISO_Greek_Supp, 1, 0, 'F', 5, 9 }, { nrc_ISO_Hebrew_Supp, 1, 0, 'H', 5, 9 }, { nrc_ISO_Latin_5_Supp, 1, 0, 'M', 5, 9 }, { nrc_ISO_Latin_Cyrillic, 1, 0, 'L', 5, 9 }, }; /* *INDENT-ON* */ TScreen *screen = TScreenOf(xw); Bool result = False; *upss = nrc_ASCII; if (screen->vtXX_level >= 3) { Cardinal n; for (n = 0; n < XtNumber(upss_table); ++n) { if (((int) psarg - '0') != upss_table[n].params) continue; if (cp[1] == '\0') { if (upss_table[n].suffix != cp[0]) continue; } else if (cp[2] == '\0') { if (upss_table[n].prefix != cp[0]) continue; if (upss_table[n].suffix != cp[1]) continue; } else { continue; } result = True; *upss = upss_table[n].code; if (*upss == DFT_UPSS) { TRACE(("DECAUPSS (default)\n")); } else if (*upss == ALT_UPSS) { TRACE(("DECAUPSS (alternate)\n")); } break; } TRACE(("DECAUPSS %ssuccessful %s\n", result ? "" : "not ", visibleScsCode(*upss))); } return result; } void do_dcs(XtermWidget xw, Char *dcsbuf, size_t dcslen) { TScreen *screen = TScreenOf(xw); char reply[BUFSIZ]; const char *cp = (const char *) dcsbuf; Bool okay; ANSI params; char psarg = '0'; #if OPT_VT525_COLORS && OPT_ISO_COLORS const char *cp2; #endif #if (OPT_VT525_COLORS && OPT_ISO_COLORS) || OPT_MOD_FKEYS int ival; #endif TRACE(("do_dcs(%s:%lu)\n", (char *) dcsbuf, (unsigned long) dcslen)); if (dcslen != strlen(cp)) /* shouldn't have nulls in the string */ return; switch (*cp) { /* intermediate character, or parameter */ case '$': /* DECRQSS */ okay = True; cp++; if (*cp == 'q') { *reply = '\0'; cp++; if (!strcmp(cp, "\"q")) { /* DECSCA */ TRACE(("DECRQSS -> DECSCA\n")); sprintf(reply, "%d%s", (screen->protected_mode == DEC_PROTECT) && (xw->flags & PROTECTED) ? 1 : 0, cp); } else if (!strcmp(cp, "\"p")) { /* DECSCL */ if (screen->vtXX_level < 2) { /* actually none of DECRQSS is valid for vt100's */ break; } TRACE(("DECRQSS -> DECSCL\n")); sprintf(reply, "%d%s%s", (screen->vtXX_level ? screen->vtXX_level : 1) + 60, (screen->control_eight_bits ? ";0" : ";1"), cp); } else if (!strcmp(cp, "r")) { /* DECSTBM */ TRACE(("DECRQSS -> DECSTBM\n")); sprintf(reply, "%d;%dr", screen->top_marg + 1, screen->bot_marg + 1); } else if (!strcmp(cp, "s")) { /* DECSLRM */ if (screen->vtXX_level >= 4) { /* VT420 */ TRACE(("DECRQSS -> DECSLRM\n")); sprintf(reply, "%d;%ds", screen->lft_marg + 1, screen->rgt_marg + 1); } else { okay = False; } } else if (!strcmp(cp, "m")) { /* SGR */ TRACE(("DECRQSS -> SGR\n")); xtermFormatSGR(xw, reply, xw->flags, xw->cur_foreground, xw->cur_background); strcat(reply, "m"); } else if (!strcmp(cp, " q")) { /* DECSCUSR */ int code = STEADY_BLOCK; if (isCursorUnderline(screen)) code = STEADY_UNDERLINE; else if (isCursorBar(screen)) code = STEADY_BAR; #if OPT_BLINK_CURS if (screen->cursor_blink_esc != 0) code -= 1; #endif TRACE(("reply DECSCUSR\n")); sprintf(reply, "%d%s", code, cp); } else if (!strcmp(cp, "t")) { /* DECSLPP */ sprintf(reply, "%d%s", ((screen->max_row > 24) ? screen->max_row : 24), cp); TRACE(("reply DECSLPP\n")); } else if (!strcmp(cp, "$|")) { /* DECSCPP */ TRACE(("reply DECSCPP\n")); sprintf(reply, "%d%s", ((xw->flags & IN132COLUMNS) ? 132 : 80), cp); } else #if OPT_STATUS_LINE if (!strcmp(cp, "$}")) { /* DECSASD */ TRACE(("reply DECSASD\n")); sprintf(reply, "%d%s", screen->status_active, cp); } else if (!strcmp(cp, "$~")) { /* DECSSDT */ TRACE(("reply DECSASD\n")); sprintf(reply, "%d%s", screen->status_type, cp); } else #endif #if OPT_DEC_RECTOPS if (!strcmp(cp, "*x")) { /* DECSACE */ TRACE(("reply DECSACE\n")); sprintf(reply, "%d%s", screen->cur_decsace, cp); } else #endif if (!strcmp(cp, "*|")) { /* DECSNLS */ TRACE(("reply DECSNLS\n")); sprintf(reply, "%d%s", screen->max_row + 1, cp); } else #if OPT_VT525_COLORS && OPT_ISO_COLORS if (screen->terminal_id == 525 && !strcmp((cp2 = skip_params(cp)), ",}")) { /* DECATC */ ival = parse_int_param(&cp); TRACE(("reply DECATC:%s\n", cp)); if (ival >= 0 && ival < 16 && *cp2 == ',') { sprintf(reply, "%d;%d;%d%s", ival, screen->alt_colors[ival].fg, screen->alt_colors[ival].bg, cp2); } else { okay = False; } } else if (screen->terminal_id == 525 && !strcmp((cp2 = skip_params(cp)), "){")) { /* DECSTGLT */ TRACE(("reply DECSTGLT:%s\n", cp)); sprintf(reply, "%d%s", 3, /* ANSI SGR color */ cp); } else if (screen->terminal_id == 525 && !strcmp((cp2 = skip_params(cp)), ",|")) { /* DECAC */ ival = parse_int_param(&cp); TRACE(("reply DECAC\n")); switch (ival) { case 1: /* normal text */ sprintf(reply, "%d,%d%s", screen->assigned_fg, screen->assigned_bg, cp2); break; case 2: /* window frame (not implemented) */ /* FALLTHRU */ default: okay = False; break; } } else #endif #if OPT_MOD_FKEYS if (*cp == '>' && !strcmp(skip_params(1 + cp), "f")) { /* XTQFMTKEYS */ ++cp; okay = True; ival = parse_int_param(&cp); #define GET_FMT_FKEYS(field) xw->keyboard.format_now.field #define FMT_FMT_FKEYS(field) sprintf(reply, ">%d;%dm", ival, GET_FMT_FKEYS(field)) switch (ival) { case modifyKeyboard: FMT_FMT_FKEYS(allow_keys); break; case modifyCursorKeys: FMT_FMT_FKEYS(cursor_keys); break; case modifyFunctionKeys: FMT_FMT_FKEYS(function_keys); break; case modifyKeypadKeys: FMT_FMT_FKEYS(keypad_keys); break; case modifyModifierKeys: FMT_FMT_FKEYS(modify_keys); break; case modifyOtherKeys: FMT_FMT_FKEYS(other_keys); break; case modifySpecialKeys: FMT_FMT_FKEYS(special_keys); break; default: okay = False; break; } } else if (*cp == '>' && !strcmp(skip_params(1 + cp), "m")) { /* XTQMODKEYS */ ++cp; okay = True; ival = parse_int_param(&cp); #define GET_IGN_FKEYS(field) xw->keyboard.ignore_now.field #define GET_MOD_FKEYS(field) xw->keyboard.modify_now.field #define FMT_MOD_FKEYS(field) { \ if (GET_IGN_FKEYS(field)) \ sprintf(reply, ">%d;%d:%dm", ival, \ GET_MOD_FKEYS(field), \ GET_IGN_FKEYS(field)); \ else \ sprintf(reply, ">%d;%dm", ival, \ GET_MOD_FKEYS(field)); \ } while (0); switch (ival) { case modifyKeyboard: FMT_MOD_FKEYS(allow_keys); break; case modifyCursorKeys: FMT_MOD_FKEYS(cursor_keys); break; case modifyFunctionKeys: FMT_MOD_FKEYS(function_keys); break; case modifyKeypadKeys: FMT_MOD_FKEYS(keypad_keys); break; case modifyModifierKeys: FMT_MOD_FKEYS(modify_keys); break; case modifyOtherKeys: FMT_MOD_FKEYS(other_keys); break; case modifySpecialKeys: FMT_MOD_FKEYS(special_keys); break; default: okay = False; break; } } else #endif /* * This query returns the settings assuming the default value * of DEF_TITLE_MODES, which is zero. Someone could in * principle alter that (so that some states could only be * reached by removing rather than consistently by setting), * but the default value could be discovered by resetting the * title modes, querying the resulting reset state. */ if (*cp == '>' && !strcmp(skip_params(1 + cp), "t")) { /* XTSMTITLE */ char buffer[80]; int n; ++cp; okay = True; ival = parse_int_param(&cp); *buffer = '\0'; if (ival == -1) { /* DEFAULT */ for (n = 0; n <= MAX_TITLEMODE; ++n) { int check = xBIT(n); char *s = buffer + strlen(buffer); if (s != buffer) *s++ = ';'; sprintf(s, "%d", ((check & screen->title_modes) != 0 ? 1 : 0)); } } else if (ival >= 0 && ival <= MAX_TITLEMODE) { sprintf(buffer, "%d", ((xBIT(ival) & screen->title_modes) != 0 ? 1 : 0)); } else { okay = False; } if (okay) sprintf(reply, ">%st", buffer); } else { okay = False; } unparseputc1(xw, ANSI_DCS); unparseputc(xw, okay ? '1' : '0'); unparseputc(xw, '$'); unparseputc(xw, 'r'); cp = reply; unparseputs(xw, cp); unparseputc1(xw, ANSI_ST); } else { unparseputc(xw, ANSI_CAN); } break; case '+': cp++; switch (*cp) { #if OPT_TCAP_QUERY case 'p': /* XTSETTCAP */ if (AllowTcapOps(xw, etSetTcap)) { set_termcap(xw, cp + 1); } break; case 'q': /* XTGETTCAP */ if (AllowTcapOps(xw, etGetTcap)) { Bool fkey; unsigned state; int code; const char *tmp; const char *parsed = ++cp; code = xtermcapKeycode(xw, &parsed, &state, &fkey); unparseputc1(xw, ANSI_DCS); unparseputc(xw, code >= 0 ? '1' : '0'); unparseputc(xw, '+'); unparseputc(xw, 'r'); while (*cp != 0 && (code >= -1)) { if (cp == parsed) break; /* no data found, error */ for (tmp = cp; tmp != parsed; ++tmp) unparseputc(xw, *tmp); if (code >= 0) { unparseputc(xw, '='); screen->tc_query_code = code; screen->tc_query_fkey = fkey; #if OPT_ISO_COLORS /* XK_COLORS is a fake code for the "Co" entry (maximum * number of colors) */ if (code == XK_COLORS) { unparseputn(xw, (unsigned) NUM_ANSI_COLORS); } else #if OPT_DIRECT_COLOR if (code == XK_RGB) { if (TScreenOf(xw)->direct_color && xw->has_rgb) { if (xw->rgb_widths[0] == xw->rgb_widths[1] && xw->rgb_widths[1] == xw->rgb_widths[2]) { unparseputn(xw, xw->rgb_widths[0]); } else { char temp[1024]; sprintf(temp, "%u/%u/%u", xw->rgb_widths[0], xw->rgb_widths[1], xw->rgb_widths[2]); unparseputs(xw, temp); } } else { unparseputs(xw, "-1"); } } else #endif #endif if (code == XK_TCAPNAME) { unparseputs(xw, resource.term_name); } else { XKeyEvent event; memset(&event, 0, sizeof(event)); event.type = KeyPress; event.state = state; Input(xw, &event, False); } screen->tc_query_code = -1; } else { break; /* no match found, error */ } cp = parsed; if (*parsed == ';') { unparseputc(xw, *parsed++); cp = parsed; code = xtermcapKeycode(xw, &parsed, &state, &fkey); } } unparseputc1(xw, ANSI_ST); } break; #endif #if OPT_XRES_QUERY case 'Q': /* XTGETXRES */ ++cp; if (AllowXResOps(xw)) { Boolean first = True; okay = True; while (*cp != '\0' && okay) { const char *parsed = NULL; const char *tmp; char *name = x_decode_hex(cp, &parsed); char *value; char *result; if (cp == parsed || name == NULL) { free(name); break; /* no data found, error */ } if ((cp - parsed) > 1024) { free(name); break; /* ignore improbable resource */ } TRACE(("query-feature '%s'\n", name)); if ((value = vt100ResourceToString(xw, name)) != NULL) { okay = True; /* valid */ } else { okay = False; /* invalid */ } if (first) { unparseputc1(xw, ANSI_DCS); unparseputc(xw, okay ? '1' : '0'); unparseputc(xw, '+'); unparseputc(xw, 'R'); first = False; } for (tmp = cp; tmp != parsed; ++tmp) unparseputc(xw, *tmp); if (value != NULL) { unparseputc1(xw, '='); result = x_encode_hex(value); unparseputs(xw, result); } else { result = NULL; } free(name); free(value); free(result); cp = parsed; if (*parsed == ';') { unparseputc(xw, *parsed++); cp = parsed; } } if (!first) unparseputc1(xw, ANSI_ST); } break; #endif } break; case '0': /* FALLTHRU */ case '1': if (screen->vtXX_level >= 3 && *skip_params(cp) == '!') { DECNRCM_codes upss; psarg = *cp++; if (*cp++ == '!' && *cp++ == 'u') { #if OPT_WIDE_CHARS if (screen->wide_chars && screen->utf8_mode) { ; /* EMPTY */ } else #endif if (decode_upss(xw, cp, psarg, &upss)) { screen->gsets_upss = upss; } } break; } #if OPT_DEC_RECTOPS /* FALLTHRU */ case '2': if (*skip_params(cp) == '$') { psarg = *cp++; if ((*cp++ == '$') && (*cp++ == 't') && (screen->vtXX_level >= 3)) { switch (psarg) { case '1': TRACE(("DECRSPS (DECCIR)\n")); restore_DECCIR(xw, cp); break; case '2': TRACE(("DECRSPS (DECTABSR)\n")); restore_DECTABSR(xw, cp); break; } } break; } #endif /* FALLTHRU */ default: if (optRegisGraphics(screen) || screen->vtXX_level >= 2) { /* VT220 */ parse_ansi_params(¶ms, &cp); switch (params.a_final) { case 'p': /* ReGIS */ #if OPT_REGIS_GRAPHICS if (optRegisGraphics(screen)) { parse_regis(xw, ¶ms, cp); } #else TRACE(("ignoring ReGIS graphic (compilation flag not enabled)\n")); #endif break; case 'q': /* sixel is done in charproc.c */ break; case '|': /* DECUDK */ if (screen->vtXX_level >= 2) { /* VT220 */ if (params.a_param[0] == 0) reset_decudk(xw); parse_decudk(xw, cp); } break; case L_CURL: /* DECDLD */ if (screen->vtXX_level >= 2) { /* VT220 */ parse_decdld(¶ms, cp); } break; } } break; } unparse_end(xw); } #if OPT_DEC_RECTOPS enum { mdUnknown = 0, mdMaybeSet = 1, mdMaybeReset = 2, mdAlwaysSet = 3, mdAlwaysReset = 4 }; #define MdBool(bool) ((bool) ? mdMaybeSet : mdMaybeReset) #define MdFlag(mode,flag) MdBool((mode) & (flag)) /* * Reply is the same format as the query, with pair of mode/value: * 0 - not recognized * 1 - set * 2 - reset * 3 - permanently set * 4 - permanently reset * Only one mode can be reported at a time. */ void do_ansi_rqm(XtermWidget xw, int nparams, int *params) { ANSI reply; int count = 0; TRACE(("do_ansi_rqm %d:%d\n", nparams, params[0])); memset(&reply, 0, sizeof(reply)); if (nparams >= 1) { int result = mdUnknown; /* DECRQM can only ask about one mode at a time */ switch (params[0]) { case 1: /* GATM */ result = mdAlwaysReset; break; case 2: result = MdFlag(xw->keyboard.flags, MODE_KAM); break; case 3: /* CRM */ result = mdMaybeReset; break; case 4: result = MdFlag(xw->flags, INSERT); break; case 5: /* SRTM */ case 7: /* VEM */ case 10: /* HEM */ case 11: /* PUM */ result = mdAlwaysReset; break; case 12: result = MdFlag(xw->keyboard.flags, MODE_SRM); break; case 13: /* FEAM */ case 14: /* FETM */ case 15: /* MATM */ case 16: /* TTM */ case 17: /* SATM */ case 18: /* TSM */ case 19: /* EBM */ result = mdAlwaysReset; break; case 20: result = MdFlag(xw->flags, LINEFEED); break; } reply.a_param[count++] = (ParmType) params[0]; reply.a_param[count++] = (ParmType) result; } reply.a_type = ANSI_CSI; reply.a_nparam = (ParmType) count; reply.a_inters = '$'; reply.a_final = 'y'; unparseseq(xw, &reply); } void do_dec_rqm(XtermWidget xw, int nparams, int *params) { ANSI reply; int count = 0; TRACE(("do_dec_rqm %d:%d\n", nparams, params[0])); memset(&reply, 0, sizeof(reply)); if (nparams >= 1) { TScreen *screen = TScreenOf(xw); int result = mdUnknown; /* DECRQM can only ask about one mode at a time */ switch ((DECSET_codes) params[0]) { case srm_DECCKM: result = MdFlag(xw->keyboard.flags, MODE_DECCKM); break; case srm_DECANM: /* ANSI/VT52 mode */ #if OPT_VT52_MODE result = MdBool(screen->vtXX_level >= 1); #else result = mdMaybeSet; #endif break; case srm_DECCOLM: result = MdFlag(xw->flags, IN132COLUMNS); break; case srm_DECSCLM: /* (slow scroll) */ result = MdFlag(xw->flags, SMOOTHSCROLL); break; case srm_DECSCNM: result = MdFlag(xw->flags, REVERSE_VIDEO); break; case srm_DECOM: result = MdFlag(xw->flags, ORIGIN); break; case srm_DECAWM: result = MdFlag(xw->flags, WRAPAROUND); break; case srm_DECARM: result = mdAlwaysReset; break; case srm_X10_MOUSE: /* X10 mouse */ result = MdBool(screen->send_mouse_pos == X10_MOUSE); break; #if OPT_TOOLBAR case srm_RXVT_TOOLBAR: result = MdBool(resource.toolBar); break; #endif #if OPT_BLINK_CURS case srm_ATT610_BLINK: /* AT&T 610: Start/stop blinking cursor */ result = MdBool(screen->cursor_blink_esc); break; case srm_CURSOR_BLINK_OPS: switch (screen->cursor_blink) { case cbTrue: result = mdMaybeSet; break; case cbFalse: result = mdMaybeReset; break; case cbAlways: result = mdAlwaysSet; break; case cbLAST: /* FALLTHRU */ case cbNever: result = mdAlwaysReset; break; } break; case srm_XOR_CURSOR_BLINKS: result = (screen->cursor_blink_xor ? mdAlwaysSet : mdAlwaysReset); break; #endif case srm_DECPFF: /* print form feed */ result = MdBool(PrinterOf(screen).printer_formfeed); break; case srm_DECPEX: /* print extent */ result = MdBool(PrinterOf(screen).printer_extent); break; case srm_DECTCEM: /* Show/hide cursor (VT200) */ result = MdBool(screen->cursor_set); break; case srm_RXVT_SCROLLBAR: result = MdBool(screen->fullVwin.sb_info.width != OFF); break; #if OPT_SHIFT_FONTS case srm_RXVT_FONTSIZE: result = MdBool(xw->misc.shift_fonts); break; #endif #if OPT_TEK4014 case srm_DECTEK: result = MdBool(TEK4014_ACTIVE(xw)); break; #endif case srm_132COLS: result = MdBool(screen->c132); break; case srm_CURSES_HACK: result = MdBool(screen->curses); break; case srm_DECNRCM: /* national charset (VT220) */ if (screen->vtXX_level >= 2) { result = MdFlag(xw->flags, NATIONAL); } else { result = 0; } break; case srm_MARGIN_BELL: /* margin bell */ result = MdBool(screen->marginbell); break; #if OPT_PRINT_GRAPHICS case srm_DECGEPM: /* Graphics Expanded Print Mode */ result = MdBool(screen->graphics_expanded_print_mode); break; #endif case srm_REVERSEWRAP: /* reverse wraparound */ if_PRINT_GRAPHICS2(result = MdBool(screen->graphics_print_color_syntax)) result = MdFlag(xw->flags, REVERSEWRAP); break; case srm_REVERSEWRAP2: /* extended reverse wraparound */ result = MdFlag(xw->flags, REVERSEWRAP2); break; #if defined(ALLOWLOGGING) case srm_ALLOWLOGGING: /* logging */ if_PRINT_GRAPHICS2(result = MdBool(screen->graphics_print_background_mode)) #if defined(ALLOWLOGFILEONOFF) result = MdBool(screen->logging); #else result = ((MdBool(screen->logging) == mdMaybeSet) ? mdAlwaysSet : mdAlwaysReset); #endif break; #elif OPT_PRINT_GRAPHICS case srm_DECGPBM: /* Graphics Print Background Mode */ result = MdBool(screen->graphics_print_background_mode); break; #endif case srm_OPT_ALTBUF_CURSOR: /* alternate buffer & cursor */ /* FALLTHRU */ case srm_OPT_ALTBUF: result = MdBool(screen->whichBuf); break; case srm_ALTBUF: if_PRINT_GRAPHICS2(result = MdBool(screen->graphics_print_background_mode)) result = MdBool(screen->whichBuf); break; case srm_DECNKM: result = MdFlag(xw->keyboard.flags, MODE_DECKPAM); break; case srm_DECBKM: result = MdFlag(xw->keyboard.flags, MODE_DECBKM); break; case srm_DECLRMM: if (screen->vtXX_level >= 4) { /* VT420 */ result = MdFlag(xw->flags, LEFT_RIGHT); } else { result = 0; } break; #if OPT_SIXEL_GRAPHICS case srm_DECSDM: result = MdFlag(xw->keyboard.flags, MODE_DECSDM); break; #endif case srm_DECNCSM: /* no clearing screen on column change */ if (screen->vtXX_level >= 5) { /* VT510 */ result = MdFlag(xw->flags, NOCLEAR_COLM); } else { result = 0; } break; case srm_VT200_MOUSE: /* xterm bogus sequence */ result = MdBool(screen->send_mouse_pos == VT200_MOUSE); break; case srm_VT200_HIGHLIGHT_MOUSE: /* xterm sequence w/hilite tracking */ result = MdBool(screen->send_mouse_pos == VT200_HIGHLIGHT_MOUSE); break; case srm_BTN_EVENT_MOUSE: result = MdBool(screen->send_mouse_pos == BTN_EVENT_MOUSE); break; case srm_ANY_EVENT_MOUSE: result = MdBool(screen->send_mouse_pos == ANY_EVENT_MOUSE); break; #if OPT_FOCUS_EVENT case srm_FOCUS_EVENT_MOUSE: result = MdBool(screen->send_focus_pos); break; #endif case srm_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_SGR_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_URXVT_EXT_MODE_MOUSE: /* FALLTHRU */ case srm_PIXEL_POSITION_MOUSE: result = MdBool(screen->extend_coords == params[0]); break; case srm_ALTERNATE_SCROLL: result = MdBool(screen->alternateScroll); break; case srm_RXVT_SCROLL_TTY_OUTPUT: result = MdBool(screen->scrollttyoutput); break; case srm_RXVT_SCROLL_TTY_KEYPRESS: result = MdBool(screen->scrollkey); break; case srm_EIGHT_BIT_META: result = MdBool(screen->eight_bit_meta); break; #if OPT_NUM_LOCK case srm_REAL_NUMLOCK: result = MdBool(xw->misc.real_NumLock); break; case srm_META_SENDS_ESC: result = MdBool(screen->meta_sends_esc); break; #endif case srm_DELETE_IS_DEL: result = MdBool(xtermDeleteIsDEL(xw)); break; #if OPT_NUM_LOCK case srm_ALT_SENDS_ESC: result = MdBool(screen->alt_sends_esc); break; #endif case srm_KEEP_SELECTION: result = MdBool(screen->keepSelection); break; case srm_SELECT_TO_CLIPBOARD: result = MdBool(screen->selectToClipboard); break; case srm_BELL_IS_URGENT: result = MdBool(screen->bellIsUrgent); break; case srm_POP_ON_BELL: result = MdBool(screen->poponbell); break; case srm_KEEP_CLIPBOARD: result = MdBool(screen->keepClipboard); break; case srm_ALLOW_ALTBUF: result = MdBool(xw->misc.titeInhibit); break; case srm_SAVE_CURSOR: result = MdBool(screen->sc[screen->whichBuf].saved); break; case srm_FAST_SCROLL: result = MdBool(screen->fastscroll); break; #if OPT_TCAP_FKEYS case srm_TCAP_FKEYS: result = MdBool(xw->keyboard.type == keyboardIsTermcap); break; #endif #if OPT_SUN_FUNC_KEYS case srm_SUN_FKEYS: result = MdBool(xw->keyboard.type == keyboardIsSun); break; #endif #if OPT_HP_FUNC_KEYS case srm_HP_FKEYS: result = MdBool(xw->keyboard.type == keyboardIsHP); break; #endif #if OPT_SCO_FUNC_KEYS case srm_SCO_FKEYS: result = MdBool(xw->keyboard.type == keyboardIsSCO); break; #endif case srm_LEGACY_FKEYS: result = MdBool(xw->keyboard.type == keyboardIsLegacy); break; #if OPT_SUNPC_KBD case srm_VT220_FKEYS: result = MdBool(xw->keyboard.type == keyboardIsVT220); break; #endif #if OPT_PASTE64 || OPT_READLINE case srm_PASTE_IN_BRACKET: result = MdBool(SCREEN_FLAG(screen, paste_brackets)); break; #endif #if OPT_READLINE case srm_BUTTON1_MOVE_POINT: result = MdBool(SCREEN_FLAG(screen, click1_moves)); break; case srm_BUTTON2_MOVE_POINT: result = MdBool(SCREEN_FLAG(screen, paste_moves)); break; case srm_DBUTTON3_DELETE: result = MdBool(SCREEN_FLAG(screen, dclick3_deletes)); break; case srm_PASTE_QUOTE: result = MdBool(SCREEN_FLAG(screen, paste_quotes)); break; case srm_PASTE_LITERAL_NL: result = MdBool(SCREEN_FLAG(screen, paste_literal_nl)); break; #endif /* OPT_READLINE */ #if OPT_GRAPHICS case srm_PRIVATE_COLOR_REGISTERS: result = MdBool(screen->privatecolorregisters); break; #endif #if OPT_SIXEL_GRAPHICS case srm_SIXEL_SCROLLS_RIGHT: result = MdBool(screen->sixel_scrolls_right); break; #endif /* the remainder are recognized but unimplemented */ /* VT3xx */ case srm_DEC131TM: /* vt330:VT131 transmit */ case srm_DECEKEM: /* vt330:edit key execution */ case srm_DECHCCM: /* vt320:Horizontal Cursor-Coupling Mode */ case srm_DECKBUM: /* vt330:Keyboard Usage mode */ case srm_DECKKDM: /* vt382:Kanji/Katakana */ case srm_DECLTM: /* vt330:line transmit */ case srm_DECPCCM: /* vt330:Page Cursor-Coupling Mode */ case srm_DECVCCM: /* vt330:Vertical Cursor-Coupling Mode */ case srm_DECXRLM: /* vt330:Transmit Rate Limiting */ #if !OPT_BLINK_CURS case srm_DECKANAM: /* vt382:Katakana shift */ case srm_DECSCFDM: /* vt330:space compression field delimiter */ case srm_DECTEM: /* vt330:transmission execution */ #endif #if !OPT_TOOLBAR case srm_DECEDM: /* vt330:edit */ #endif if (screen->vtXX_level >= 3) result = mdAlwaysReset; break; /* VT4xx */ case srm_DECKPM: /* vt420:Key Position Mode */ if (screen->vtXX_level >= 4) result = mdAlwaysReset; break; /* VT5xx */ case srm_DECAAM: /* vt510:auto answerback */ case srm_DECARSM: /* vt510:auto resize */ case srm_DECATCBM: /* vt520:alternate text color blink */ case srm_DECATCUM: /* vt520:alternate text color underline */ case srm_DECBBSM: /* vt520:bold and blink style */ case srm_DECCANSM: /* vt510:conceal answerback */ case srm_DECCAPSLK: /* vt510:Caps Lock Mode */ case srm_DECCRTSM: /* vt510:CRT save */ case srm_DECECM: /* vt520:erase color */ case srm_DECESKM: /* vt510:enable secondary keyboard language */ case srm_DECFWM: /* vt520:framed windows */ case srm_DECHDPXM: /* vt510:half duplex */ case srm_DECHEM: /* vt510:Hebrew encoding */ case srm_DECHWUM: /* vt520:host wake-up mode (CRT and energy saver) */ case srm_DECIPEM: /* vt510:IBM ProPrinter Emulation Mode */ case srm_DECKLHIM: /* vt510:ignore */ case srm_DECMCM: /* vt510:modem control */ case srm_DECNAKB: /* vt510:Greek/N-A Keyboard Mapping */ case srm_DECNULM: /* vt510:Ignoring Null Mode */ case srm_DECNUMLK: /* vt510:Num Lock Mode */ case srm_DECOSCNM: /* vt510:Overscan Mode */ case srm_DECRLCM: /* vt510:Right-to-Left Copy */ case srm_DECRLM: /* vt510:left-to-right */ case srm_DECRPL: /* vt520:Review Previous Lines */ #if !OPT_SHIFT_FONTS case srm_DECHEBM: /* vt520:Hebrew keyboard mapping */ #endif if (screen->vtXX_level >= 5) result = mdAlwaysReset; break; default: TRACE(("DATA_ERROR: requested report for unknown private mode %d\n", params[0])); } reply.a_param[count++] = (ParmType) params[0]; reply.a_param[count++] = (ParmType) result; TRACE(("DECRPM(%d) = %d\n", params[0], result)); } reply.a_type = ANSI_CSI; reply.a_pintro = '?'; reply.a_nparam = (ParmType) count; reply.a_inters = '$'; reply.a_final = 'y'; unparseseq(xw, &reply); } #endif /* OPT_DEC_RECTOPS */ char * udk_lookup(XtermWidget xw, int keycode, int *len) { char *result = NULL; if (keycode >= 0 && keycode < MAX_UDK) { *len = xw->work.user_keys[keycode].len; result = xw->work.user_keys[keycode].str; TRACE(("udk_lookup(%d) = %.*s\n", keycode, *len, result)); } else { TRACE(("udk_lookup(%d) = \n", keycode)); } return result; } #if OPT_REPORT_ICONS void report_icons(const char *fmt, ...) { if (resource.reportIcons) { va_list ap; va_start(ap, fmt); vfprintf(stdout, fmt, ap); va_end(ap); #if OPT_TRACE va_start(ap, fmt); TraceVA(fmt, ap); va_end(ap); #endif } } #endif #ifdef HAVE_LIBXPM #ifndef PIXMAP_ROOTDIR #define PIXMAP_ROOTDIR "/usr/share/pixmaps/" #endif typedef struct { const char *name; const char *const *data; } XPM_DATA; static char * x_find_icon(char **work, int *state, const char *filename, const char *suffix) { const char *prefix = PIXMAP_ROOTDIR; const char *larger = "_48x48"; char *result = NULL; if (*state >= 0) { if ((*state & 1) == 0) suffix = ""; if ((*state & 2) == 0) larger = ""; if ((*state & 4) == 0) { prefix = ""; } else if (!strncmp(filename, "/", (size_t) 1) || !strncmp(filename, "./", (size_t) 2) || !strncmp(filename, "../", (size_t) 3)) { *state = -1; } else if (*state >= 8) { *state = -1; } } if (*state >= 0) { size_t length; FreeAndNull(*work); length = 3 + strlen(prefix) + strlen(filename) + strlen(larger) + strlen(suffix); if ((result = malloc(length)) != NULL) { sprintf(result, "%s%s%s%s", prefix, filename, larger, suffix); *work = result; } *state += 1; } TRACE(("x_find_icon %d:%s ->%s\n", *state, filename, NonNull(result))); return result; } #if OPT_BUILTIN_XPMS static const XPM_DATA * built_in_xpm(const XPM_DATA * table, Cardinal length, const char *find) { const XPM_DATA *result = NULL; if (!IsEmpty(find)) { Cardinal n; for (n = 0; n < length; ++n) { if (!x_strcasecmp(find, table[n].name)) { result = table + n; ReportIcons(("use builtin-icon %s\n", table[n].name)); break; } } /* * As a fallback, check if the icon name matches without the lengths, * which are all _HHxWW format. */ if (result == NULL) { const char *base = table[0].name; const char *last = strchr(base, '_'); if (last != NULL && !x_strncasecmp(find, base, (unsigned) (last - base))) { result = table + length - 1; ReportIcons(("use builtin-icon %s\n", table[0].name)); } } } return result; } #define BuiltInXPM(name) built_in_xpm(name, XtNumber(name), icon_hint) #endif /* OPT_BUILTIN_XPMS */ typedef enum { eHintDefault = 0 /* use the largest builtin-icon */ ,eHintNone ,eHintSearch } ICON_HINT; #endif /* HAVE_LIBXPM */ int getVisualDepth(XtermWidget xw) { int result = 0; if (getVisualInfo(xw)) { result = xw->visInfo->depth; } return result; } /* * WM_ICON_SIZE should be honored if possible. */ void xtermLoadIcon(XtermWidget xw, const char *icon_hint) { #ifdef HAVE_LIBXPM Display *dpy = XtDisplay(xw); Pixmap myIcon = 0; Pixmap myMask = 0; char *workname = NULL; ICON_HINT hint = eHintDefault; #include ReportIcons(("load icon (hint: %s)\n", NonNull(icon_hint))); if (!IsEmpty(icon_hint)) { if (!x_strcasecmp(icon_hint, "none")) { hint = eHintNone; } else { hint = eHintSearch; } } if (hint == eHintSearch) { int state = 0; while (x_find_icon(&workname, &state, icon_hint, ".xpm") != NULL) { Pixmap resIcon = 0; Pixmap shapemask = 0; XpmAttributes attributes; struct stat sb; attributes.depth = (unsigned) getVisualDepth(xw); attributes.valuemask = XpmDepth; if (IsEmpty(workname) || lstat(workname, &sb) != 0 || !S_ISREG(sb.st_mode)) { TRACE(("...failure (no such file)\n")); } else { int rc = XpmReadFileToPixmap(dpy, DefaultRootWindow(dpy), workname, &resIcon, &shapemask, &attributes); if (rc == XpmSuccess) { myIcon = resIcon; myMask = shapemask; TRACE(("...success\n")); ReportIcons(("found/loaded icon-file %s\n", workname)); break; } else { TRACE(("...failure (%s)\n", XpmGetErrorString(rc))); } } } } /* * If no external file was found, look for the name in the built-in table. * If that fails, just use the biggest mini-icon. */ if (myIcon == 0 && hint != eHintNone) { char **data; #if OPT_BUILTIN_XPMS const XPM_DATA *myData = NULL; myData = BuiltInXPM(mini_xterm_xpms); if (myData == NULL) myData = BuiltInXPM(filled_xterm_xpms); if (myData == NULL) myData = BuiltInXPM(xterm_color_xpms); if (myData == NULL) myData = BuiltInXPM(xterm_xpms); if (myData == NULL) myData = &mini_xterm_xpms[XtNumber(mini_xterm_xpms) - 1]; data = (char **) myData->data; #else data = (char **) &mini_xterm_48x48_xpm; #endif if (XpmCreatePixmapFromData(dpy, DefaultRootWindow(dpy), data, &myIcon, &myMask, NULL) == 0) { ReportIcons(("loaded built-in pixmap icon\n")); } else { myIcon = 0; myMask = 0; } } if (myIcon != 0) { XWMHints *hints = XGetWMHints(dpy, VShellWindow(xw)); if (!hints) hints = XAllocWMHints(); if (hints) { hints->flags |= IconPixmapHint; hints->icon_pixmap = myIcon; if (myMask) { hints->flags |= IconMaskHint; hints->icon_mask = myMask; } XSetWMHints(dpy, VShellWindow(xw), hints); XFree(hints); ReportIcons(("updated window-manager hints\n")); } } free(workname); #else (void) xw; (void) icon_hint; #endif } void ChangeGroup(XtermWidget xw, const char *attribute, char *value) { Arg args[1]; Boolean changed = True; Widget w = CURRENT_EMU(); Widget top = SHELL_OF(w); char *my_attr = NULL; char *old_value = value; #if OPT_WIDE_CHARS Boolean titleIsUTF8; #endif if (!AllowTitleOps(xw)) return; /* * Ignore empty or too-long requests. */ if (value == NULL || strlen(value) > 1000) return; if (IsTitleMode(xw, tmSetBase16)) { const char *temp; char *test; /* this allocates a new string, if no error is detected */ value = x_decode_hex(value, &temp); if (value == NULL || *temp != '\0') { free(value); return; } for (test = value; *test != '\0'; ++test) { if (CharOf(*test) < 32) { *test = '\0'; break; } } } #if OPT_WIDE_CHARS /* * By design, xterm uses the XtNtitle resource of the X Toolkit for setting * the WM_NAME property, rather than doing this directly. That relies on * the application to tell it if the format should be something other than * STRING, i.e., by setting the XtNtitleEncoding resource. * * The ICCCM says that WM_NAME is TEXT (i.e., uninterpreted). In X11R6, * the ICCCM listed STRING and COMPOUND_TEXT as possibilities; XFree86 * added UTF8_STRING (the documentation for that was discarded by an Xorg * developer, although the source-code provides this feature). * * Since X11R5, if the X11 library fails to store a text property as * STRING, it falls back to COMPOUND_TEXT. For best interoperability, we * prefer to use STRING if the data fits, or COMPOUND_TEXT. In either * case, limit the resulting characters to the printable ISO-8859-1 set. */ titleIsUTF8 = isValidUTF8((Char *) value); if (IsSetUtf8Title(xw) && titleIsUTF8) { char *testc = malloc(strlen(value) + 1); Char *nextc = (Char *) value; Boolean ok8bit = True; if (testc != NULL) { /* * Check if the data fits in STRING. Along the way, replace * control characters. */ Char *lastc = (Char *) testc; while (*nextc != '\0') { unsigned ch; nextc = convertFromUTF8(nextc, &ch); if (ch > 255) { ok8bit = False; } else if (!IsLatin1(ch)) { ch = OnlyLatin1(ch); } *lastc++ = (Char) ch; } *lastc = '\0'; if (ok8bit) { TRACE(("ChangeGroup: UTF-8 converted to ISO-8859-1\n")); if (value != old_value) free(value); value = testc; titleIsUTF8 = False; } else { TRACE(("ChangeGroup: UTF-8 NOT converted to ISO-8859-1:\n" "\t%s\n", value)); free(testc); nextc = (Char *) value; while (*nextc != '\0') { unsigned ch; Char *skip = convertFromUTF8(nextc, &ch); if (iswcntrl((wint_t) ch)) { memset(nextc, BAD_ASCII, (size_t) (skip - nextc)); } nextc = skip; } } } } else #endif { Char *c1 = (Char *) value; TRACE(("ChangeGroup: assume ISO-8859-1\n")); for (c1 = (Char *) value; *c1 != '\0'; ++c1) { *c1 = (Char) OnlyLatin1(*c1); } } my_attr = x_strdup(attribute); ReportIcons(("ChangeGroup(attribute=%s, value=%s)\n", my_attr, value)); #if OPT_WIDE_CHARS /* * If we're running in UTF-8 mode, and have not been told that the * title string is in UTF-8, it is likely that non-ASCII text in the * string will be rejected because it is not printable in the current * locale. So we convert it to UTF-8, allowing the X library to * convert it back. */ TRACE(("ChangeGroup: value is %sUTF-8\n", titleIsUTF8 ? "" : "NOT ")); if (xtermEnvUTF8() && !titleIsUTF8) { size_t limit = strlen(value); Char *c1 = (Char *) value; int n; for (n = 0; c1[n] != '\0'; ++n) { if (c1[n] > 127) { Char *converted; if ((converted = TypeMallocN(Char, 1 + (6 * limit))) != NULL) { Char *temp = converted; while (*c1 != 0) { temp = convertToUTF8(temp, *c1++); } *temp = 0; if (value != old_value) free(value); value = (char *) converted; ReportIcons(("...converted{%s}\n", value)); } break; } } } #endif #if OPT_SAME_NAME /* If the attribute isn't going to change, then don't bother... */ if (resource.sameName) { char *buf = NULL; XtSetArg(args[0], my_attr, &buf); XtGetValues(top, args, 1); TRACE(("...comparing resource{%s} to new value{%s}\n", NonNull(buf), NonNull(value))); if (buf != NULL && strcmp(value, buf) == 0) changed = False; } #endif /* OPT_SAME_NAME */ if (changed) { ReportIcons(("...updating %s\n", my_attr)); ReportIcons(("...value is %s\n", value)); XtSetArg(args[0], my_attr, value); XtSetValues(top, args, 1); } #if OPT_WIDE_CHARS if (xtermEnvUTF8()) { Display *dpy = XtDisplay(xw); const char *propname = (!strcmp(my_attr, XtNtitle) ? "_NET_WM_NAME" : "_NET_WM_ICON_NAME"); Atom my_atom = CachedInternAtom(dpy, propname); if (my_atom != None) { changed = True; if (IsSetUtf8Title(xw)) { #if OPT_SAME_NAME if (resource.sameName) { Atom actual_type; Atom requested_type = XA_UTF8_STRING(dpy); int actual_format = 0; long long_length = 1024; unsigned long nitems = 0; unsigned long bytes_after = 0; unsigned char *prop = NULL; if (xtermGetWinProp(dpy, VShellWindow(xw), my_atom, 0L, long_length, requested_type, &actual_type, &actual_format, &nitems, &bytes_after, &prop)) { if (actual_type == requested_type && actual_format == 8 && prop != NULL && nitems == strlen(value) && memcmp(value, prop, nitems) == 0) { changed = False; } XFree(prop); } } #endif /* OPT_SAME_NAME */ if (changed) { ReportIcons(("...updating %s\n", propname)); ReportIcons(("...value is %s\n", value)); XChangeProperty(dpy, VShellWindow(xw), my_atom, XA_UTF8_STRING(dpy), 8, PropModeReplace, (Char *) value, (int) strlen(value)); } } else { ReportIcons(("...deleting %s\n", propname)); XDeleteProperty(dpy, VShellWindow(xw), my_atom); } } } #endif if (value != old_value) { free(value); } free(my_attr); return; } void ChangeIconName(XtermWidget xw, char *name) { if (!showZIconBeep(xw, name)) ChangeGroup(xw, XtNiconName, name); } void ChangeTitle(XtermWidget xw, char *name) { ChangeGroup(xw, XtNtitle, name); } #define Strlen(s) strlen((const char *)(s)) void ChangeXprop(char *buf) { Display *dpy = XtDisplay(toplevel); Window w = XtWindow(toplevel); XTextProperty text_prop; Atom aprop; Char *pchEndPropName = (Char *) strchr(buf, '='); if (pchEndPropName) *pchEndPropName = '\0'; aprop = CachedInternAtom(dpy, buf); if (pchEndPropName == NULL) { /* no "=value" given, so delete the property */ XDeleteProperty(dpy, w, aprop); } else { text_prop.value = pchEndPropName + 1; text_prop.encoding = XA_STRING; text_prop.format = 8; text_prop.nitems = Strlen(text_prop.value); XSetTextProperty(dpy, w, &text_prop, aprop); } } /***====================================================================***/ /* * This is part of ReverseVideo(). It reverses the data stored for the old * "dynamic" colors that might have been retrieved using OSC 10-18. */ void ReverseOldColors(XtermWidget xw) { ScrnColors *pOld = xw->work.oldColors; Pixel tmpPix; char *tmpName; if (pOld) { /* change text cursor, if necessary */ if (pOld->colors[TEXT_CURSOR] == pOld->colors[TEXT_FG]) { pOld->colors[TEXT_CURSOR] = pOld->colors[TEXT_BG]; if (pOld->names[TEXT_CURSOR]) { XtFree(xw->work.oldColors->names[TEXT_CURSOR]); pOld->names[TEXT_CURSOR] = NULL; } if (pOld->names[TEXT_BG]) { if ((tmpName = x_strdup(pOld->names[TEXT_BG])) != NULL) { pOld->names[TEXT_CURSOR] = tmpName; } } } EXCHANGE(pOld->colors[TEXT_FG], pOld->colors[TEXT_BG], tmpPix); EXCHANGE(pOld->names[TEXT_FG], pOld->names[TEXT_BG], tmpName); EXCHANGE(pOld->colors[MOUSE_FG], pOld->colors[MOUSE_BG], tmpPix); EXCHANGE(pOld->names[MOUSE_FG], pOld->names[MOUSE_BG], tmpName); #if OPT_TEK4014 EXCHANGE(pOld->colors[TEK_FG], pOld->colors[TEK_BG], tmpPix); EXCHANGE(pOld->names[TEK_FG], pOld->names[TEK_BG], tmpName); #endif FreeMarkGCs(xw); } return; } Bool AllocateTermColor(XtermWidget xw, ScrnColors * pNew, int ndx, const char *name, Bool always) { Bool result = False; if (always || AllowColorOps(xw, ecSetColor)) { XColor def; char *newName; result = True; if (!x_strcasecmp(name, XtDefaultForeground)) { def.pixel = xw->old_foreground; } else if (!x_strcasecmp(name, XtDefaultBackground)) { def.pixel = xw->old_background; } else if (!xtermAllocColor(xw, &def, name)) { result = False; } if (result && (newName = x_strdup(name)) != NULL) { if (COLOR_DEFINED(pNew, ndx)) { free(pNew->names[ndx]); } SET_COLOR_VALUE(pNew, ndx, def.pixel); SET_COLOR_NAME(pNew, ndx, newName); TRACE(("AllocateTermColor #%d: %s (pixel 0x%06lx)\n", ndx, newName, def.pixel)); } else { TRACE(("AllocateTermColor #%d: %s (failed)\n", ndx, name)); result = False; } } return result; } /***====================================================================***/ /* ARGSUSED */ void Panic(const char *s GCC_UNUSED, int a GCC_UNUSED) { if_DEBUG({ xtermWarning(s, a); }); } const char * SysErrorMsg(int code) { static const char unknown[] = "unknown error"; const char *s = strerror(code); return s ? s : unknown; } const char * SysReasonMsg(int code) { /* *INDENT-OFF* */ static const struct { int code; const char *name; } table[] = { { ERROR_FIONBIO, "main: ioctl() failed on FIONBIO" }, { ERROR_F_GETFL, "main: ioctl() failed on F_GETFL" }, { ERROR_F_SETFL, "main: ioctl() failed on F_SETFL", }, { ERROR_OPDEVTTY, "spawn: open() failed on /dev/tty", }, { ERROR_TIOCGETP, "spawn: ioctl() failed on TIOCGETP", }, { ERROR_PTSNAME, "spawn: ptsname() failed", }, { ERROR_OPPTSNAME, "spawn: open() failed on ptsname", }, { ERROR_PTEM, "spawn: ioctl() failed on I_PUSH/\"ptem\"" }, { ERROR_CONSEM, "spawn: ioctl() failed on I_PUSH/\"consem\"" }, { ERROR_LDTERM, "spawn: ioctl() failed on I_PUSH/\"ldterm\"" }, { ERROR_TTCOMPAT, "spawn: ioctl() failed on I_PUSH/\"ttcompat\"" }, { ERROR_TIOCSETP, "spawn: ioctl() failed on TIOCSETP" }, { ERROR_TIOCSETC, "spawn: ioctl() failed on TIOCSETC" }, { ERROR_TIOCSETD, "spawn: ioctl() failed on TIOCSETD" }, { ERROR_TIOCSLTC, "spawn: ioctl() failed on TIOCSLTC" }, { ERROR_TIOCLSET, "spawn: ioctl() failed on TIOCLSET" }, { ERROR_INIGROUPS, "spawn: initgroups() failed" }, { ERROR_FORK, "spawn: fork() failed" }, { ERROR_EXEC, "spawn: exec() failed" }, { ERROR_PTYS, "get_pty: not enough ptys" }, { ERROR_PTY_EXEC, "waiting for initial map" }, { ERROR_SETUID, "spawn: setuid() failed" }, { ERROR_INIT, "spawn: can't initialize window" }, { ERROR_TIOCKSET, "spawn: ioctl() failed on TIOCKSET" }, { ERROR_TIOCKSETC, "spawn: ioctl() failed on TIOCKSETC" }, { ERROR_LUMALLOC, "luit: command-line malloc failed" }, { ERROR_SELECT, "in_put: select() failed" }, { ERROR_VINIT, "VTInit: can't initialize window" }, { ERROR_KMMALLOC1, "HandleKeymapChange: malloc failed" }, { ERROR_TSELECT, "Tinput: select() failed" }, { ERROR_TINIT, "TekInit: can't initialize window" }, { ERROR_BMALLOC2, "SaltTextAway: malloc() failed" }, { ERROR_LOGEXEC, "StartLog: exec() failed" }, { ERROR_XERROR, "xerror: XError event" }, { ERROR_XIOERROR, "xioerror: X I/O error" }, { ERROR_SCALLOC, "Alloc: calloc() failed on base" }, { ERROR_SCALLOC2, "Alloc: calloc() failed on rows" }, { ERROR_SAVE_PTR, "ScrnPointers: malloc/realloc() failed" }, }; /* *INDENT-ON* */ Cardinal n; const char *result = "?"; for (n = 0; n < XtNumber(table); ++n) { if (code == table[n].code) { result = table[n].name; break; } } return result; } void SysError(int code) { int oerrno = errno; fprintf(stderr, "%s: Error %d, errno %d: ", ProgramName, code, oerrno); fprintf(stderr, "%s\n", SysErrorMsg(oerrno)); fprintf(stderr, "Reason: %s\n", SysReasonMsg(code)); Cleanup(code); } void NormalExit(void) { static Bool cleaning; /* * Process "-hold" and session cleanup only for a normal exit. */ if (cleaning) { hold_screen = 0; return; } cleaning = True; need_cleanup = False; if (hold_screen) { hold_screen = 2; while (hold_screen) { xtermFlushDbe(term); xevents(term); Sleep(EVENT_DELAY); } } #if OPT_SESSION_MGT if (resource.sessionMgt) { XtVaSetValues(toplevel, XtNjoinSession, False, (void *) 0); } #endif Cleanup(0); } #if USE_DOUBLE_BUFFER void xtermFlushDbe(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (resource.buffered && screen->needSwap) { XdbeSwapInfo swap; swap.swap_window = VWindow(screen); swap.swap_action = XdbeCopied; XdbeSwapBuffers(XtDisplay(xw), &swap, 1); XFlush(XtDisplay(xw)); screen->needSwap = 0; ScrollBarDrawThumb(xw, 2); X_GETTIMEOFDAY(&screen->buffered_at); } } void xtermTimedDbe(XtermWidget xw) { if (resource.buffered) { TScreen *screen = TScreenOf(xw); struct timeval now; long elapsed; long limit = DbeMsecs(xw); X_GETTIMEOFDAY(&now); if (screen->buffered_at.tv_sec) { elapsed = (1000L * (now.tv_sec - screen->buffered_at.tv_sec) + (now.tv_usec - screen->buffered_at.tv_usec) / 1000L); } else { elapsed = limit; } if (elapsed >= limit) { xtermNeedSwap(xw, 1); xtermFlushDbe(xw); } } } #endif /* * cleanup by sending SIGHUP to client processes */ void Cleanup(int code) { TScreen *screen = TScreenOf(term); TRACE(("Cleanup %d\n", code)); if (screen->pid > 1) { (void) kill_process_group(screen->pid, SIGHUP); } Exit(code); } #ifndef S_IXOTH #define S_IXOTH 1 #endif Boolean validProgram(const char *pathname) { Boolean result = False; struct stat sb; if (!IsEmpty(pathname) && *pathname == '/' && strstr(pathname, "/..") == NULL && stat(pathname, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFREG && access(pathname, F_OK | X_OK) == 0) { result = True; } return result; } #ifndef PATH_MAX #define PATH_MAX 512 /* ... is not defined consistently in Xos.h */ #endif char * xtermFindShell(char *leaf, Bool warning) { char *s0; char *s; char *d; char *tmp; char *result = leaf; Bool allocated = False; TRACE(("xtermFindShell(%s)\n", leaf)); if (!strncmp("./", result, (size_t) 2) || !strncmp("../", result, (size_t) 3)) { size_t need = PATH_MAX; size_t used = strlen(result) + 2; char *buffer = malloc(used + need); if (buffer != NULL) { if (getcwd(buffer, need) != NULL) { sprintf(buffer + strlen(buffer), "/%s", result); result = buffer; allocated = True; } else { free(buffer); } } } else if (*result != '\0' && strchr("+/-", *result) == NULL) { /* find it in $PATH */ if ((s = s0 = x_getenv("PATH")) != NULL) { if ((tmp = TypeMallocN(char, strlen(leaf) + strlen(s) + 2)) != NULL) { Bool found = False; while (*s != '\0') { strcpy(tmp, s); for (d = tmp;; ++d) { if (*d == ':' || *d == '\0') { int skip = (*d != '\0'); *d = '/'; strcpy(d + 1, leaf); if (skip) ++d; s += (d - tmp); if (validProgram(tmp)) { result = x_strdup(tmp); found = True; allocated = True; } break; } } if (found) break; } free(tmp); } free(s0); } } TRACE(("...xtermFindShell(%s)\n", result)); if (!validProgram(result)) { if (warning) xtermWarning("No absolute path found for shell: %s\n", result); if (allocated) free(result); result = NULL; } /* be consistent, so that caller can always free the result */ if (result != NULL && !allocated) result = x_strdup(result); return result; } #define ENV_HUNK(n) (unsigned) ((((n) + 1) | 31) + 1) /* * If we do not have unsetenv(), make consistent updates for environ[]. * This could happen on some older machines due to the uneven standardization * process for the two functions. * * That is, putenv() makes a copy of environ, and some implementations do not * update the environ pointer, so the fallback when unsetenv() is missing would * not work as intended. Likewise, the reverse could be true, i.e., unsetenv * could copy environ. */ #if defined(HAVE_PUTENV) && !defined(HAVE_UNSETENV) #undef HAVE_PUTENV #elif !defined(HAVE_PUTENV) && defined(HAVE_UNSETENV) #undef HAVE_UNSETENV #endif /* * copy the environment before Setenv'ing. */ void xtermCopyEnv(char **oldenv) { #ifdef HAVE_PUTENV (void) oldenv; #else unsigned size; char **newenv; for (size = 0; oldenv[size] != NULL; size++) { ; } newenv = TypeCallocN(char *, ENV_HUNK(size)); memmove(newenv, oldenv, size * sizeof(char *)); environ = newenv; #endif } #if !defined(HAVE_PUTENV) || !defined(HAVE_UNSETENV) static int findEnv(const char *var, int *lengthp) { char *test; int envindex = 0; size_t len = strlen(var); int found = -1; TRACE(("findEnv(%s=..)\n", var)); while ((test = environ[envindex]) != NULL) { if (strncmp(test, var, len) == 0 && test[len] == '=') { found = envindex; break; } envindex++; } *lengthp = envindex; return found; } #endif /* * sets the value of var to be arg in the Unix 4.2 BSD environment env. * Var should end with '=' (bindings are of the form "var=value"). * This procedure assumes the memory for the first level of environ * was allocated using calloc, with enough extra room at the end so not * to have to do a realloc(). */ void xtermSetenv(const char *var, const char *value) { if (value != NULL) { #ifdef HAVE_PUTENV char *both = malloc(2 + strlen(var) + strlen(value)); TRACE(("xtermSetenv(%s=%s)\n", var, value)); if (both) { sprintf(both, "%s=%s", var, value); putenv(both); } #else size_t len = strlen(var); int envindex; int found = findEnv(var, &envindex); TRACE(("xtermSetenv(%s=%s)\n", var, value)); if (found < 0) { unsigned need = ENV_HUNK(envindex + 1); unsigned have = ENV_HUNK(envindex); if (need > have) { char **newenv; newenv = TypeMallocN(char *, need); if (newenv == 0) { xtermWarning("Cannot increase environment\n"); return; } memmove(newenv, environ, have * sizeof(*newenv)); free(environ); environ = newenv; } found = envindex; environ[found + 1] = NULL; } environ[found] = malloc(2 + len + strlen(value)); if (environ[found] == 0) { xtermWarning("Cannot allocate environment %s\n", var); return; } sprintf(environ[found], "%s=%s", var, value); #endif } } void xtermUnsetenv(const char *var) { TRACE(("xtermUnsetenv(%s)\n", var)); #ifdef HAVE_UNSETENV unsetenv(var); #else { int ignore; int item = findEnv(var, &ignore); if (item >= 0) { while ((environ[item] = environ[item + 1]) != 0) { ++item; } } } #endif } /*ARGSUSED*/ int xerror(Display *d, XErrorEvent *ev) { xtermWarning("warning, error event received:\n"); TRACE_X_ERR(d, ev); (void) XmuPrintDefaultErrorMessage(d, ev, stderr); Exit(ERROR_XERROR); return 0; /* appease the compiler */ } void ice_error(IceConn iceConn) { (void) iceConn; xtermWarning("ICE IO error handler doing an exit(), pid = %ld, errno = %d\n", (long) getpid(), errno); Exit(ERROR_ICEERROR); } /*ARGSUSED*/ int xioerror(Display *dpy) { int the_error = errno; xtermWarning("fatal IO error %d (%s) or KillClient on X server \"%s\"\r\n", the_error, SysErrorMsg(the_error), DisplayString(dpy)); Exit(ERROR_XIOERROR); return 0; /* appease the compiler */ } void xt_error(String message) { xtermWarning("Xt error: %s\n", message); /* * Check for the obvious - Xt does a poor job of reporting this. */ if (x_getenv("DISPLAY") == NULL) { xtermWarning("DISPLAY is not set\n"); } exit(ERROR_MISC); } int XStrCmp(char *s1, char *s2) { if (s1 && s2) return (strcmp(s1, s2)); if (s1 && *s1) return (1); if (s2 && *s2) return (-1); return (0); } #if OPT_TEK4014 static void withdraw_window(Display *dpy, Window w, int scr) { TRACE(("withdraw_window %#lx\n", (long) w)); (void) XmuUpdateMapHints(dpy, w, NULL); XWithdrawWindow(dpy, w, scr); return; } #endif void set_vt_visibility(Bool on) { XtermWidget xw = term; TScreen *screen = TScreenOf(xw); TRACE(("set_vt_visibility(%d)\n", on)); if (on) { if (!screen->Vshow && xw) { resource.notMapped = False; VTInit(xw); XtMapWidget(XtParent(xw)); #if OPT_TOOLBAR /* we need both of these during initialization */ XtMapWidget(SHELL_OF(xw)); ShowToolbar(resource.toolBar); #endif screen->Vshow = True; } } #if OPT_TEK4014 else { if (screen->Vshow && xw) { withdraw_window(XtDisplay(xw), VShellWindow(xw), XScreenNumberOfScreen(XtScreen(xw))); screen->Vshow = False; } } set_vthide_sensitivity(); set_tekhide_sensitivity(); update_vttekmode(); update_tekshow(); update_vtshow(); #endif return; } #if OPT_TEK4014 void set_tek_visibility(Bool on) { XtermWidget xw = term; TRACE(("set_tek_visibility(%d)\n", on)); if (on) { if (!TEK4014_SHOWN(xw)) { if (tekWidget == NULL) { TekInit(); /* will exit on failure */ } if (tekWidget != NULL) { Widget tekParent = SHELL_OF(tekWidget); resource.notMapped = False; XtRealizeWidget(tekParent); XtMapWidget(XtParent(tekWidget)); #if OPT_TOOLBAR /* we need both of these during initialization */ XtMapWidget(tekParent); XtMapWidget(tekWidget); #endif XtOverrideTranslations(tekParent, XtParseTranslationTable ("WM_PROTOCOLS: DeleteWindow()")); (void) XSetWMProtocols(XtDisplay(tekParent), XtWindow(tekParent), &wm_delete_window, 1); TEK4014_SHOWN(xw) = True; } } } else { if (TEK4014_SHOWN(xw) && tekWidget) { withdraw_window(XtDisplay(tekWidget), TShellWindow, XScreenNumberOfScreen(XtScreen(tekWidget))); TEK4014_SHOWN(xw) = False; } } set_tekhide_sensitivity(); set_vthide_sensitivity(); update_vtshow(); update_tekshow(); update_vttekmode(); return; } void end_tek_mode(void) { XtermWidget xw = term; if (TEK4014_ACTIVE(xw)) { FlushLog(xw); TEK4014_ACTIVE(xw) = False; xtermSetWinSize(xw); longjmp(Tekend, 1); } return; } void end_vt_mode(void) { XtermWidget xw = term; if (!TEK4014_ACTIVE(xw)) { FlushLog(xw); set_tek_visibility(True); TEK4014_ACTIVE(xw) = True; TekSetWinSize(tekWidget); longjmp(VTend, 1); } return; } void switch_modes(Bool tovt) /* if true, then become vt mode */ { if (tovt) { if (tekRefreshList) TekRefresh(tekWidget); end_tek_mode(); /* WARNING: this does a longjmp... */ } else { end_vt_mode(); /* WARNING: this does a longjmp... */ } } void hide_vt_window(void) { set_vt_visibility(False); if (!TEK4014_ACTIVE(term)) switch_modes(False); /* switch to tek mode */ } void hide_tek_window(void) { set_tek_visibility(False); tekRefreshList = (TekLink *) 0; if (TEK4014_ACTIVE(term)) switch_modes(True); /* does longjmp to vt mode */ } #endif /* OPT_TEK4014 */ static const char * skip_punct(const char *s) { while (*s == '-' || *s == '/' || *s == '+' || *s == '#' || *s == '%') { ++s; } return s; } static int cmp_options(const void *a, const void *b) { const char *s1 = skip_punct(((const OptionHelp *) a)->opt); const char *s2 = skip_punct(((const OptionHelp *) b)->opt); return strcmp(s1, s2); } static int cmp_resources(const void *a, const void *b) { return strcmp(((const XrmOptionDescRec *) a)->option, ((const XrmOptionDescRec *) b)->option); } XrmOptionDescRec * sortedOptDescs(const XrmOptionDescRec * descs, Cardinal res_count) { static XrmOptionDescRec *res_array = NULL; #ifdef NO_LEAKS if (descs == NULL) { FreeAndNull(res_array); } else #endif if (res_array == NULL) { Cardinal j; /* make a sorted index to 'resources' */ res_array = TypeCallocN(XrmOptionDescRec, res_count); if (res_array != NULL) { for (j = 0; j < res_count; j++) res_array[j] = descs[j]; qsort(res_array, (size_t) res_count, sizeof(*res_array), cmp_resources); } } return res_array; } /* * The first time this is called, construct sorted index to the main program's * list of options, taking into account the on/off options which will be * compressed into one token. It's a lot simpler to do it this way than * maintain the list in sorted form with lots of ifdef's. */ OptionHelp * sortedOpts(OptionHelp * options, XrmOptionDescRec * descs, Cardinal numDescs) { static OptionHelp *opt_array = NULL; #ifdef NO_LEAKS if (descs == NULL && opt_array != NULL) { sortedOptDescs(descs, numDescs); FreeAndNull(opt_array); return NULL; } else if (options == NULL || descs == NULL) { return NULL; } #endif if (opt_array == NULL) { size_t opt_count, j; #if OPT_TRACE Cardinal k; XrmOptionDescRec *res_array = sortedOptDescs(descs, numDescs); int code; const char *mesg; #else (void) descs; (void) numDescs; #endif /* count 'options' and make a sorted index to it */ for (opt_count = 0; options[opt_count].opt != NULL; ++opt_count) { ; } opt_array = TypeCallocN(OptionHelp, opt_count + 1); for (j = 0; j < opt_count; j++) opt_array[j] = options[j]; qsort(opt_array, opt_count, sizeof(OptionHelp), cmp_options); /* supply the "turn on/off" strings if needed */ #if OPT_TRACE for (j = 0; j < opt_count; j++) { if (!strncmp(opt_array[j].opt, "-/+", (size_t) 3)) { char temp[80]; const char *name = opt_array[j].opt + 3; for (k = 0; k < numDescs; ++k) { const char *value = res_array[k].value; if (res_array[k].option[0] == '-') { code = -1; } else if (res_array[k].option[0] == '+') { code = 1; } else { code = 0; } sprintf(temp, "%.*s", (int) sizeof(temp) - 2, opt_array[j].desc); if (x_strindex(temp, "inhibit") != NULL) code = -code; if (code != 0 && res_array[k].value != NULL && !strcmp(name, res_array[k].option + 1)) { if (((code < 0) && !strcmp(value, "on")) || ((code > 0) && !strcmp(value, "off")) || ((code > 0) && !strcmp(value, "0"))) { mesg = "turn on/off"; } else { mesg = "turn off/on"; } TRACE(("%s: %s %s: %s (%s)\n", mesg, res_array[k].option, res_array[k].value, opt_array[j].opt, opt_array[j].desc)); break; } } } } #endif } return opt_array; } /* * Report the character-type locale that xterm was started in. */ String xtermEnvLocale(void) { static String result; if (result == NULL) { if ((result = x_nonempty(setlocale(LC_CTYPE, NULL))) == NULL) { result = x_strdup("C"); } else { result = x_strdup(result); } TRACE(("xtermEnvLocale ->%s\n", result)); } return result; } char * xtermEnvEncoding(void) { static char *result; if (result == NULL) { #ifdef HAVE_LANGINFO_CODESET result = nl_langinfo(CODESET); #else const char *locale = xtermEnvLocale(); if (!strcmp(locale, "C") || !strcmp(locale, "POSIX")) { result = x_strdup("ASCII"); } else { result = x_strdup("ISO-8859-1"); } #endif TRACE(("xtermEnvEncoding ->%s\n", result)); } return result; } #if OPT_WIDE_CHARS /* * Tell whether xterm was started in a locale that uses UTF-8 encoding for * characters. That environment is inherited by subprocesses and used in * various library calls. */ Bool xtermEnvUTF8(void) { static Bool init = False; static Bool result = False; if (!init) { init = True; #ifdef HAVE_LANGINFO_CODESET result = (strcmp(xtermEnvEncoding(), "UTF-8") == 0); #else { char *locale = x_strdup(xtermEnvLocale()); int n; for (n = 0; locale[n] != 0; ++n) { locale[n] = x_toupper(locale[n]); } if (strstr(locale, "UTF-8") != 0) result = True; else if (strstr(locale, "UTF8") != 0) result = True; free(locale); } #endif TRACE(("xtermEnvUTF8 ->%s\n", BtoS(result))); } return result; } #endif /* OPT_WIDE_CHARS */ /* * Check if the current widget, or any parent, is the VT100 "xterm" widget. */ XtermWidget getXtermWidget(Widget w) { XtermWidget xw; if (w == NULL) { xw = (XtermWidget) CURRENT_EMU(); if (!IsXtermWidget(xw)) { xw = NULL; } } else if (IsXtermWidget(w)) { xw = (XtermWidget) w; } else { xw = getXtermWidget(XtParent(w)); } TRACE2(("getXtermWidget %p -> %p\n", w, xw)); return xw; } #if OPT_SESSION_MGT #if OPT_TRACE static void trace_1_SM(const char *tag, String name) { Arg args[1]; char *buf = NULL; XtSetArg(args[0], name, &buf); XtGetValues(toplevel, args, 1); if (strstr(name, "Path") || strstr(name, "Directory")) { TRACE(("%s %s: %s\n", tag, name, NonNull(buf))); } else if (strstr(name, "Command")) { if (buf != NULL) { char **vec = (char **) (void *) buf; int n; TRACE(("%s %s:\n", tag, name)); for (n = 0; vec[n] != NULL; ++n) { TRACE((" arg[%d] = %s\n", n, vec[n])); } } else { TRACE(("%s %s: %p\n", tag, name, buf)); } } else { TRACE(("%s %s: %p\n", tag, name, buf)); } } static void trace_SM_props(void) { /* *INDENT-OFF* */ static struct { String app, cls; } table[] = { { XtNcurrentDirectory, XtCCurrentDirectory }, { XtNdieCallback, XtNdiscardCommand }, { XtCDiscardCommand, XtNenvironment }, { XtCEnvironment, XtNinteractCallback }, { XtNjoinSession, XtCJoinSession }, { XtNprogramPath, XtCProgramPath }, { XtNresignCommand, XtCResignCommand }, { XtNrestartCommand, XtCRestartCommand }, { XtNrestartStyle, XtCRestartStyle }, { XtNsaveCallback, XtNsaveCompleteCallback }, { XtNsessionID, XtCSessionID }, { XtNshutdownCommand, XtCShutdownCommand }, }; /* *INDENT-ON* */ Cardinal n; TRACE(("Session properties:\n")); for (n = 0; n < XtNumber(table); ++n) { trace_1_SM("app", table[n].app); trace_1_SM("cls", table[n].cls); } } #define TRACE_SM_PROPS() trace_SM_props() #else #define TRACE_SM_PROPS() /* nothing */ #endif static void die_callback(Widget w GCC_UNUSED, XtPointer client_data GCC_UNUSED, XtPointer call_data GCC_UNUSED) { TRACE(("die_callback client=%p, call=%p\n", (void *) client_data, (void *) call_data)); TRACE_SM_PROPS(); NormalExit(); } static void save_callback(Widget w GCC_UNUSED, XtPointer client_data GCC_UNUSED, XtPointer call_data) { XtCheckpointToken token = (XtCheckpointToken) call_data; TRACE(("save_callback:\n")); TRACE(("... save_type <-%d\n", token->save_type)); TRACE(("... interact_style <-%d\n", token->interact_style)); TRACE(("... shutdown <-%s\n", BtoS(token->shutdown))); TRACE(("... fast <-%s\n", BtoS(token->fast))); TRACE(("... cancel_shutdown <-%s\n", BtoS(token->cancel_shutdown))); TRACE(("... phase <-%d\n", token->phase)); TRACE(("... interact_dialog_type ->%d\n", token->interact_dialog_type)); TRACE(("... request_cancel ->%s\n", BtoS(token->request_cancel))); TRACE(("... request_next_phase ->%s\n", BtoS(token->request_next_phase))); TRACE(("... save_success ->%s\n", BtoS(token->save_success))); xtermUpdateRestartCommand(term); /* we have nothing more to save */ token->save_success = True; } static void icewatch(IceConn iceConn, IcePointer clientData GCC_UNUSED, Bool opening, IcePointer * watchData GCC_UNUSED) { if (opening) { ice_fd = IceConnectionNumber(iceConn); TRACE(("got IceConnectionNumber %d\n", ice_fd)); } else { ice_fd = -1; TRACE(("reset IceConnectionNumber\n")); } } void xtermOpenSession(void) { if (resource.sessionMgt) { TRACE(("Enabling session-management callbacks\n")); XtAddCallback(toplevel, XtNdieCallback, die_callback, NULL); XtAddCallback(toplevel, XtNsaveCallback, save_callback, NULL); TRACE_SM_PROPS(); } } void xtermCloseSession(void) { IceRemoveConnectionWatch(icewatch, NULL); } typedef enum { B_ARG = 0, I_ARG, D_ARG, S_ARG } ParamType; #define Barg(name, field) { name, B_ARG, XtOffsetOf(XtermWidgetRec, field) } #define Iarg(name, field) { name, I_ARG, XtOffsetOf(XtermWidgetRec, field) } #define Darg(name, field) { name, D_ARG, XtOffsetOf(XtermWidgetRec, field) } #define Sarg(name, field) { name, S_ARG, XtOffsetOf(XtermWidgetRec, field) } typedef struct { const char name[30]; ParamType type; Cardinal offset; } FontParams; /* *INDENT-OFF* */ static const FontParams fontParams[] = { Iarg(XtNinitialFont, screen.menu_font_number), /* "-fc" */ Barg(XtNallowBoldFonts, screen.allowBoldFonts), /* menu */ #if OPT_BOX_CHARS Barg(XtNforceBoxChars, screen.force_box_chars), /* "-fbx" */ Barg(XtNforcePackedFont, screen.force_packed), /* menu */ #endif #if OPT_DEC_CHRSET Barg(XtNfontDoublesize, screen.font_doublesize), /* menu */ #endif #if OPT_WIDE_CHARS Barg(XtNutf8Fonts, screen.utf8_fonts), /* menu */ #endif #if OPT_RENDERFONT Darg(XtNfaceSize, misc.face_size[0]), /* "-fs" */ Sarg(XtNfaceName, misc.default_xft.f_n), /* "-fa" */ Sarg(XtNrenderFont, misc.render_font_s), /* (resource) */ #endif }; /* *INDENT-ON* */ #define RESTART_PARAMS (int)(XtNumber(fontParams) * 2) #define TypedPtr(type) *(type *)(void *)((char *) xw + parameter->offset) /* * If no widget is given, no value is used. */ static char * formatFontParam(char *result, XtermWidget xw, const FontParams * parameter) { sprintf(result, "%s*%s:", ProgramName, parameter->name); if (xw != NULL) { char *next = result + strlen(result); switch (parameter->type) { case B_ARG: sprintf(next, "%s", *(Boolean *) ((char *) xw + parameter->offset) ? "true" : "false"); break; case I_ARG: sprintf(next, "%d", TypedPtr(int)); break; case D_ARG: sprintf(next, "%.1f", TypedPtr(float)); break; case S_ARG: strcpy(next, TypedPtr(char *)); #if OPT_RENDERFONT if (!strcmp(parameter->name, XtNfaceName)) { if (IsEmpty(next) && xw->work.render_font) { strcpy(next, DEFFACENAME_AUTO); } } else if (!strcmp(parameter->name, XtNrenderFont)) { if (xw->work.render_font == erDefault && IsEmpty(xw->misc.default_xft.f_n)) { strcpy(next, "DefaultOff"); } } #endif break; } } return result; } #if OPT_TRACE static void dumpFontParams(XtermWidget xw) { char buffer[1024]; Cardinal n; TRACE(("FontParams:\n")); for (n = 0; n < XtNumber(fontParams); ++n) { TRACE(("%3d:%s\n", n, formatFontParam(buffer, xw, fontParams + n))); } } #else #define dumpFontParams(xw) /* nothing */ #endif static Boolean findFontParams(int argc, char **argv) { Boolean result = False; if (argc > RESTART_PARAMS && (argc - restart_params) > RESTART_PARAMS) { int n; for (n = 0; n < RESTART_PARAMS; ++n) { int my_index = argc - restart_params - n - 1; int my_param = (RESTART_PARAMS - n - 1) / 2; char *actual = argv[my_index]; char expect[1024]; Boolean value = (Boolean) ((n % 2) == 0); result = False; TRACE(("...index: %d\n", my_index)); TRACE(("...param: %d\n", my_param)); TRACE(("...actual %s\n", actual)); if (IsEmpty(actual)) break; if (value) { formatFontParam(expect, NULL, fontParams + my_param); } else { strcpy(expect, "-xrm"); } TRACE(("...expect %s\n", expect)); if (value) { if (strlen(expect) >= strlen(actual)) break; if (strncmp(expect, actual, strlen(expect))) break; } else { if (strcmp(actual, expect)) break; } TRACE(("fixme/ok:%d\n", n)); result = True; } TRACE(("findFontParams: %s (tested %d of %d parameters)\n", BtoS(result), n + 1, RESTART_PARAMS)); } return result; } static int insertFontParams(XtermWidget xw, int *targetp, Bool first) { int changed = 0; int n; int target = *targetp; char buffer[1024]; const char *option = "-xrm"; for (n = 0; n < (int) XtNumber(fontParams); ++n) { formatFontParam(buffer, xw, fontParams + n); TRACE(("formatted %3d ->%3d:%s\n", n, target, buffer)); if (restart_command[target] == NULL) restart_command[target] = x_strdup(option); ++target; if (first) { restart_command[target] = x_strdup(buffer); ++changed; } else if (restart_command[target] == NULL || strcmp(restart_command[target], buffer)) { free(restart_command[target]); restart_command[target] = x_strdup(buffer); ++changed; } ++target; } *targetp = target; return changed; } void xtermUpdateRestartCommand(XtermWidget xw) { if (resource.sessionMgt) { Arg args[1]; char **argv = NULL; XtSetArg(args[0], XtNrestartCommand, &argv); XtGetValues(toplevel, args, 1); if (argv != NULL) { static int my_params = 0; int changes = 0; Boolean first = False; int argc; int want; int source, target; TRACE(("xtermUpdateRestartCommand\n")); dumpFontParams(xw); for (argc = 0; argv[argc] != NULL; ++argc) { TRACE((" arg[%d] = %s\n", argc, argv[argc])); ; } want = argc - (restart_params + RESTART_PARAMS); TRACE((" argc: %d\n", argc)); TRACE((" restart_params: %d\n", restart_params)); TRACE((" want to insert: %d\n", want)); /* * If we already have the font-choice option, do not add it again. */ if (findFontParams(argc, argv)) { my_params = (want); } else { first = True; my_params = (argc - restart_params); } TRACE((" my_params: %d\n", my_params)); if (my_params > argc) { TRACE((" re-allocate restartCommand\n")); FreeAndNull(restart_command); } if (restart_command == NULL) { int need = argc + RESTART_PARAMS + 1; restart_command = TypeCallocN(char *, need); TRACE(("..inserting font-parameters\n")); for (source = target = 0; source < argc; ++source) { if (source == my_params) { changes += insertFontParams(xw, &target, first); if (!first) { source += (RESTART_PARAMS - 1); continue; } } if (argv[source] == NULL) break; restart_command[target++] = x_strdup(argv[source]); } restart_command[target] = NULL; } else { TRACE(("..replacing font-parameters\n")); target = my_params; changes += insertFontParams(xw, &target, first); } if (changes) { TRACE(("..%d parameters changed\n", changes)); XtSetArg(args[0], XtNrestartCommand, restart_command); XtSetValues(toplevel, args, 1); } else { TRACE(("..NO parameters changed\n")); } } TRACE_SM_PROPS(); } } #endif /* OPT_SESSION_MGT */ Widget xtermOpenApplication(XtAppContext * app_context_return, String my_class, XrmOptionDescRec * options, Cardinal num_options, int *argc_in_out, char **argv_in_out, String *fallback_resources, WidgetClass widget_class, ArgList args, Cardinal num_args) { Widget result; XtSetErrorHandler(xt_error); #if OPT_SESSION_MGT result = XtOpenApplication(app_context_return, my_class, options, num_options, argc_in_out, argv_in_out, fallback_resources, widget_class, args, num_args); IceAddConnectionWatch(icewatch, NULL); #else (void) widget_class; (void) args; (void) num_args; result = XtAppInitialize(app_context_return, my_class, options, num_options, argc_in_out, argv_in_out, fallback_resources, NULL, 0); #endif /* OPT_SESSION_MGT */ XtSetErrorHandler(NULL); return result; } /* * Some calls to XGetAtom() will fail, and we don't want to stop. So we use * our own error-handler. */ /* ARGSUSED */ int ignore_x11_error(Display *dpy GCC_UNUSED, XErrorEvent *event GCC_UNUSED) { return 1; } static int x11_errors; static int catch_x11_error(Display *display, XErrorEvent *error_event) { (void) display; (void) error_event; ++x11_errors; return 0; } Boolean xtermGetWinAttrs(Display *dpy, Window win, XWindowAttributes * attrs) { Boolean result = False; Status code; memset(attrs, 0, sizeof(*attrs)); if (win != None) { XErrorHandler save = XSetErrorHandler(catch_x11_error); x11_errors = 0; code = XGetWindowAttributes(dpy, win, attrs); XSetErrorHandler(save); result = (Boolean) ((code != 0) && !x11_errors); if (result) { TRACE_WIN_ATTRS(attrs); } else { xtermWarning("invalid window-id %ld\n", (long) win); } } return result; } Boolean xtermGetWinProp(Display *display, Window win, Atom property, long long_offset, long long_length, Atom req_type, Atom *actual_type_return, int *actual_format_return, unsigned long *nitems_return, unsigned long *bytes_after_return, unsigned char **prop_return) { Boolean result = False; if (win != None) { XErrorHandler save = XSetErrorHandler(catch_x11_error); x11_errors = 0; if (XGetWindowProperty(display, win, property, long_offset, long_length, False, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return) == Success && x11_errors == 0) { result = True; } XSetErrorHandler(save); } return result; } void xtermEmbedWindow(Window winToEmbedInto) { Display *dpy = XtDisplay(toplevel); XWindowAttributes attrs; TRACE(("checking winToEmbedInto %#lx\n", winToEmbedInto)); if (xtermGetWinAttrs(dpy, winToEmbedInto, &attrs)) { XtermWidget xw = term; TScreen *screen = TScreenOf(xw); XtRealizeWidget(toplevel); TRACE(("...reparenting toplevel %#lx into %#lx\n", XtWindow(toplevel), winToEmbedInto)); XReparentWindow(dpy, XtWindow(toplevel), winToEmbedInto, 0, 0); screen->embed_high = (Dimension) attrs.height; screen->embed_wide = (Dimension) attrs.width; } } void free_string(String value) { free((void *) value); } /* Set tty's idea of window size, using the given file descriptor 'fd'. */ int update_winsize(TScreen *screen, int rows, int cols, int height, int width) { int code = -1; #ifdef TTYSIZE_STRUCT static int last_rows = -1; static int last_cols = -1; static int last_high = -1; static int last_wide = -1; TRACE(("update_winsize %dx%d (%dx%d) -> %dx%d (%dx%d)\n", last_rows, last_cols, last_high, last_wide, rows, cols, height, width)); if (rows != last_rows || cols != last_cols || last_high != height || last_wide != width) { TTYSIZE_STRUCT ts; last_rows = rows; last_cols = cols; last_high = height; last_wide = width; setup_winsize(ts, rows, cols, height, width); TRACE_RC(code, SET_TTYSIZE(screen->respond, ts)); trace_winsize(ts, "from SET_TTYSIZE"); } #endif (void) rows; (void) cols; (void) height; (void) width; return code; } /* * Update stty settings to match the values returned by dtterm window * manipulation 18 and 19. */ void xtermSetWinSize(XtermWidget xw) { #if OPT_TEK4014 if (!TEK4014_ACTIVE(xw)) #endif if (XtIsRealized((Widget) xw)) { TScreen *screen = TScreenOf(xw); TRACE(("xtermSetWinSize\n")); update_winsize(screen, MaxRows(screen), MaxCols(screen), Height(screen), Width(screen)); } } static void xtermInitTitle(TScreen *screen, int which) { TRACE(("xtermInitTitle #%d\n", which)); screen->saved_titles.data[which].iconName = NULL; screen->saved_titles.data[which].windowName = NULL; } /* * Store/update an item on the title stack. */ void xtermPushTitle(TScreen *screen, int which, SaveTitle * item) { if (which-- <= 0) { which = screen->saved_titles.used++; screen->saved_titles.used %= MAX_SAVED_TITLES; } which %= MAX_SAVED_TITLES; xtermFreeTitle(&screen->saved_titles.data[which]); screen->saved_titles.data[which] = *item; TRACE(("xtermPushTitle #%d: icon='%s', window='%s'\n", which, NonNull(item->iconName), NonNull(item->windowName))); } /* * Pop/retrieve an item from the title stack. */ Boolean xtermPopTitle(TScreen *screen, int which, SaveTitle * item) { Boolean result = True; Boolean popped = False; if (which-- > 0) { which %= MAX_SAVED_TITLES; } else if (screen->saved_titles.used > 0) { which = ((--(screen->saved_titles.used) + MAX_SAVED_TITLES) % MAX_SAVED_TITLES); popped = True; } else { result = False; } if (result) { *item = screen->saved_titles.data[which]; TRACE(("xtermPopTitle #%d: icon='%s', window='%s'\n", which, NonNull(item->iconName), NonNull(item->windowName))); /* if the data is incomplete, try to get it from the next levels */ #define TryHigher(name) \ if (item->name == NULL) { \ int n; \ for (n = 1; n < MAX_SAVED_TITLES; ++n) { \ int nw = ((which - n) + MAX_SAVED_TITLES) % MAX_SAVED_TITLES; \ if ((item->name = screen->saved_titles.data[nw].name) != NULL) { \ item->name = x_strdup(item->name); \ break; \ } \ } \ } TryHigher(iconName); TryHigher(windowName); if (popped) { xtermInitTitle(screen, which); } } return result; } /* * Discard data used for pushing or popping title. */ void xtermFreeTitle(SaveTitle * item) { TRACE(("xtermFreeTitle icon='%s', window='%s'\n", NonNull(item->iconName), NonNull(item->windowName))); FreeAndNull(item->iconName); FreeAndNull(item->windowName); } #if OPT_XTERM_SGR void xtermReportTitleStack(XtermWidget xw) { TScreen *screen = TScreenOf(xw); char reply[100]; sprintf(reply, "%d;%d", screen->saved_titles.used, MAX_SAVED_TITLES); unparseputc1(xw, ANSI_CSI); unparseputs(xw, reply); unparseputc(xw, '#'); unparseputc(xw, 'S'); unparse_end(xw); } #if OPT_TRACE static char * traceIFlags(IFlags flags) { static char result[1000]; result[0] = '\0'; #define DATA(name) if (flags & name) { strcat(result, " " #name); } DATA(INVERSE); DATA(UNDERLINE); DATA(BOLD); DATA(BLINK); DATA(INVISIBLE); DATA(BG_COLOR); DATA(FG_COLOR); #if OPT_WIDE_ATTRS DATA(ATR_FAINT); DATA(ATR_ITALIC); DATA(ATR_STRIKEOUT); DATA(ATR_DBL_UNDER); DATA(ATR_DIRECT_FG); DATA(ATR_DIRECT_BG); #endif #undef DATA return result; } static char * traceIStack(unsigned flags) { static char result[1000]; result[0] = '\0'; #define DATA(name) if (flags & xBIT(ps##name - 1)) { strcat(result, " " #name); } DATA(INVERSE); DATA(UNDERLINE); DATA(BOLD); DATA(BLINK); DATA(INVISIBLE); #if OPT_ISO_COLORS DATA(BG_COLOR); DATA(FG_COLOR); #endif #if OPT_WIDE_ATTRS DATA(ATR_FAINT); DATA(ATR_ITALIC); DATA(ATR_STRIKEOUT); DATA(ATR_DBL_UNDER); /* direct-colors are a special case of ISO-colors (see above) */ #endif #undef DATA return result; } #endif void xtermPushSGR(XtermWidget xw, int value) { SavedSGR *s = &(xw->saved_sgr); TRACE(("xtermPushSGR %d mask %#x %s\n", s->used + 1, (unsigned) value, traceIStack((unsigned) value))); if (s->used < MAX_SAVED_SGR) { s->stack[s->used].mask = (IFlags) value; #define PUSH_FLAG(name) \ s->stack[s->used].name = xw->name;\ TRACE(("...may pop %s 0x%04X %s\n", #name, xw->name, traceIFlags(xw->name))) #define PUSH_DATA(name) \ s->stack[s->used].name = xw->name;\ TRACE(("...may pop %s %d\n", #name, xw->name)) PUSH_FLAG(flags); #if OPT_ISO_COLORS PUSH_DATA(sgr_foreground); PUSH_DATA(sgr_background); PUSH_DATA(sgr_38_xcolors); #endif } s->used++; } #define IAttrClr(dst,bits) dst = dst & (IAttr) ~(bits) void xtermReportSGR(XtermWidget xw, XTermRect *value) { TScreen *screen = TScreenOf(xw); char reply[BUFSIZ]; size_t cell_size = CellDataSize(screen); CellData *working = calloc(1, cell_size); int row, col; Boolean first = True; if (working == NULL) return; for (row = value->top - 1; row < value->bottom; ++row) { LineData *ld = getLineData(screen, row); if (ld == NULL) continue; for (col = value->left - 1; col < value->right; ++col) { if (first) { first = False; saveCellData(screen, working, 0, ld, NULL, col); } working->attribs &= ld->attribs[col]; #if OPT_ISO_COLORS if (working->attribs & FG_COLOR && GetCellColorFG(working->color) != GetCellColorFG(ld->color[col])) { IAttrClr(working->attribs, FG_COLOR); } if (working->attribs & BG_COLOR && GetCellColorBG(working->color) != GetCellColorBG(ld->color[col])) { IAttrClr(working->attribs, BG_COLOR); } #endif } } xtermFormatSGR(xw, reply, working->attribs, GetCellColorFG(working->color), GetCellColorBG(working->color)); unparseputc1(xw, ANSI_CSI); unparseputs(xw, reply); unparseputc(xw, 'm'); unparse_end(xw); free(working); } void xtermPopSGR(XtermWidget xw) { SavedSGR *s = &(xw->saved_sgr); TRACE(("xtermPopSGR %d\n", s->used)); if (s->used > 0) { if (s->used-- <= MAX_SAVED_SGR) { IFlags mask = s->stack[s->used].mask; Boolean changed = False; TRACE(("...mask %#x %s\n", mask, traceIStack(mask))); TRACE(("...old: %s\n", traceIFlags(xw->flags))); TRACE(("...new: %s\n", traceIFlags(s->stack[s->used].flags))); #define POP_FLAG(name) \ if (xBIT(ps##name - 1) & mask) { \ if ((xw->flags & name) ^ (s->stack[s->used].flags & name)) { \ changed = True; \ UIntClr(xw->flags, name); \ UIntSet(xw->flags, (s->stack[s->used].flags & name)); \ TRACE(("...pop " #name " = %s\n", BtoS(xw->flags & name))); \ } \ } #define POP_FLAG2(name,part) \ if (xBIT(ps##name - 1) & mask) { \ if ((xw->flags & part) ^ (s->stack[s->used].flags & part)) { \ changed = True; \ UIntClr(xw->flags, part); \ UIntSet(xw->flags, (s->stack[s->used].flags & part)); \ TRACE(("...pop " #part " = %s\n", BtoS(xw->flags & part))); \ } \ } #define POP_DATA(name,value) \ if (xBIT(ps##name - 1) & mask) { \ Bool always = False; \ if ((xw->flags & name) ^ (s->stack[s->used].flags & name)) { \ always = changed = True; \ UIntClr(xw->flags, name); \ UIntSet(xw->flags, (s->stack[s->used].flags & name)); \ TRACE(("...pop " #name " = %s\n", BtoS(xw->flags & name))); \ } \ if (always || (xw->value != s->stack[s->used].value)) { \ TRACE(("...pop " #name " %d => %d\n", xw->value, s->stack[s->used].value)); \ xw->value = s->stack[s->used].value; \ changed = True; \ } \ } POP_FLAG(BOLD); POP_FLAG(UNDERLINE); POP_FLAG(BLINK); POP_FLAG(INVERSE); POP_FLAG(INVISIBLE); #if OPT_WIDE_ATTRS if (xBIT(psATR_ITALIC - 1) & mask) { xtermUpdateItalics(xw, s->stack[s->used].flags, xw->flags); } POP_FLAG(ATR_ITALIC); POP_FLAG(ATR_FAINT); POP_FLAG(ATR_STRIKEOUT); POP_FLAG(ATR_DBL_UNDER); #endif #if OPT_ISO_COLORS POP_DATA(FG_COLOR, sgr_foreground); POP_DATA(BG_COLOR, sgr_background); POP_DATA(BG_COLOR, sgr_38_xcolors); #if OPT_DIRECT_COLOR POP_FLAG2(FG_COLOR, ATR_DIRECT_FG); POP_FLAG2(BG_COLOR, ATR_DIRECT_BG); #endif if (changed) { setExtendedColors(xw); } #else (void) changed; #endif } #if OPT_ISO_COLORS TRACE(("xtermP -> flags%s, fg=%d bg=%d%s\n", traceIFlags(xw->flags), xw->sgr_foreground, xw->sgr_background, xw->sgr_38_xcolors ? " (SGR 38)" : "")); #else TRACE(("xtermP -> flags%s\n", traceIFlags(xw->flags))); #endif } } #if OPT_ISO_COLORS static ColorSlot * allocColorSlot(XtermWidget xw, int slot) { SavedColors *s = &(xw->saved_colors); ColorSlot *result = NULL; if (slot >= 0 && slot < MAX_SAVED_SGR) { if (s->palettes[slot] == NULL) { s->palettes[slot] = (ColorSlot *) calloc((size_t) 1, sizeof(ColorSlot) + (sizeof(ColorRes) * MAXCOLORS)); } result = s->palettes[slot]; } return result; } static void popOldColors(XtermWidget xw, ScrnColors * source) { Boolean changed = False; ScrnColors *target = xw->work.oldColors; if (source->which != target->which) { changed = True; } else { int n; for (n = 0; n < NCOLORS; ++n) { if (COLOR_DEFINED(source, n)) { if (COLOR_DEFINED(target, n)) { if (source->colors[n] != target->colors[n]) { changed = True; break; } } else { changed = True; break; } } else if (COLOR_DEFINED(target, n)) { changed = True; break; } } } if (changed) { ChangeColors(xw, source); UpdateOldColors(xw, source); } } #endif /* OPT_ISO_COLORS */ #define DiffColorSlot(d,s,n) (memcmp((d), (s), (n) * sizeof(ColorRes)) ? True : False) #define CopyColorSlot(d,s,n) memcpy((d), (s), (n) * sizeof(ColorRes)) /* * By default, a "push" increments the stack after copying to the current * slot. But a specific target allows one to copy into a specific slot. */ void xtermPushColors(XtermWidget xw, int value) { #if OPT_ISO_COLORS SavedColors *s = &(xw->saved_colors); int pushed = s->used; int actual = (value <= 0) ? pushed : (value - 1); TRACE(("xtermPushColors %d:%d\n", actual, pushed)); if (actual < MAX_SAVED_SGR && actual >= 0) { TScreen *screen = TScreenOf(xw); ColorSlot *palette; if ((palette = allocColorSlot(xw, actual)) != NULL) { GetColors(xw, &(palette->base)); CopyColorSlot(&(palette->ansi[0]), screen->Acolors, MAXCOLORS); if (value < 0) { s->used++; if (s->last < s->used) s->last = s->used; } else { s->used = value; } } } #else (void) xw; (void) value; #endif } void xtermPopColors(XtermWidget xw, int value) { #if OPT_ISO_COLORS SavedColors *s = &(xw->saved_colors); int popped = (s->used - 1); int actual = (value <= 0) ? popped : (value - 1); TRACE(("xtermPopColors %d:%d\n", actual, popped)); if (actual < MAX_SAVED_SGR && actual >= 0) { TScreen *screen = TScreenOf(xw); ColorSlot *palette; if ((palette = s->palettes[actual]) != NULL) { Boolean changed = DiffColorSlot(screen->Acolors, palette->ansi, MAXCOLORS); GetOldColors(xw); popOldColors(xw, &(palette->base)); CopyColorSlot(screen->Acolors, &(palette->ansi[0]), MAXCOLORS); s->used = actual; if (changed) xtermRepaint(xw); } } #else (void) xw; (void) value; #endif } void xtermReportColors(XtermWidget xw) { ANSI reply; SavedColors *s = &(xw->saved_colors); memset(&reply, 0, sizeof(reply)); reply.a_type = ANSI_CSI; reply.a_pintro = '?'; reply.a_param[reply.a_nparam++] = (ParmType) s->used; reply.a_param[reply.a_nparam++] = (ParmType) s->last; reply.a_inters = '#'; reply.a_final = 'Q'; unparseseq(xw, &reply); } #endif /* OPT_XTERM_SGR */ xterm-399/testxmc.c0000644000000000000000000001552514723143224013102 0ustar rootroot/* $XTermId: testxmc.c,v 1.55 2024/12/01 20:27:00 tom Exp $ */ /* * Copyright 1997-2020,2024 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ /* * This module provides test support for curses applications that must work * with terminals that have the xmc (magic cookie) glitch. The xmc_glitch * resource denotes the number of spaces that are emitted when switching to or * from standout (reverse) mode. Some terminals implement this by storing the * attribute controls in the character cell that is skipped. So if the cell is * overwritten by text, then the attribute change in the cell is cancelled, * causing attributes to the left of the change to propagate. * * We implement the glitch by writing a character that won't be mistaken for * other normal characters (and mapping normal writes to that character to a * different one). * * Since xmc isn't normally part of xterm, we document it here rather than in * the man-page. This module is driven by resources rather than by the * termcap/terminfo description to make it a little more flexible for testing * purposes. * * Resources: * * xmcGlitch (class XmcGlitch) * When true, enables this extension. The default is `0', which disables * the module. (termcap sg, terminfo xmc). * * xmcAttributes (class XmcAttributes) * The attributes for which we'll generate a glitch, as a bitmask. * * INVERSE 1 * UNDERLINE 2 * BOLD 4 * BLINK 8 * * The default is `1' (INVERSE). Some terminals emit glitches for * underline. Just for completeness, we recognize all of the video * attributes. * * xmcInline (class XmcInline) * When true, limits the extent of an SGR change to the current line. * The default is `false'. (No termcap or terminfo equivalent, though * there are comments in some entries relating to this issue). * * xmcMoveSGR (class XmcMoveSGR) * When false, a cursor movement will leave a glitch when SGR's are * active. The default is `true'. (termcap ms, terminfo msgr). * * TODO: * When xmc is active, the terminfo max_attributes (ma) capability is * assumed to be 1. * * The xmcAttributes resource should also apply to alternate character * sets and to color. */ #include #include #define MARK_ON(a) (Bool) ((my_attrs & a) != 0 && (xw->flags & (whichone = CharOf(a))) == 0) #define MARK_OFF(a) (Bool) ((my_attrs & a) != 0 && (xw->flags & (whichone = CharOf(a))) != 0) void Mark_XMC(XtermWidget xw, int param) { static IChar *glitch; TScreen *screen = TScreenOf(xw); Bool found = False; unsigned my_attrs = CharOf(screen->xmc_attributes & XMC_FLAGS); unsigned whichone = 0; if (glitch == NULL) { unsigned len = screen->xmc_glitch; glitch = TypeMallocN(IChar, len); if (glitch == NULL) { xtermWarning("Not enough core for xmc glitch mode\n"); return; } else { while (len--) glitch[len] = XMC_GLITCH; } } switch (param) { case -1: /* DEFAULT */ case 0: /* FALLTHRU */ found = MARK_OFF((xw->flags & XMC_FLAGS)); break; case 1: found = MARK_ON(BOLD); break; case 4: found = MARK_ON(UNDERLINE); break; case 5: found = MARK_ON(BLINK); break; case 7: found = MARK_ON(INVERSE); break; case 22: found = MARK_OFF(BOLD); break; case 24: found = MARK_OFF(UNDERLINE); break; case 25: found = MARK_OFF(BLINK); break; case 27: found = MARK_OFF(INVERSE); break; } /* * Write a glitch with the attributes temporarily set to the new(er) * ones. */ if (found) { unsigned save = xw->flags; xw->flags ^= whichone; TRACE(("XMC Writing glitch (%d/%d) after SGR %d\n", my_attrs, whichone, param)); dotext(xw, (DECNRCM_codes) '?', glitch, screen->xmc_glitch); xw->flags = save; } } /* * Force a glitch on cursor movement when we're in standout mode and not at the * end of a line. */ void Jump_XMC(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (!screen->move_sgr_ok && screen->cur_col <= LineMaxCol(screen, getLineData(screen, screen->cur_row))) { Mark_XMC(xw, -1); } } /* * After writing text to the screen, resolve mismatch between the current * location and any attributes that would have been set by preceding locations. */ void Resolve_XMC(XtermWidget xw) { TScreen *screen = TScreenOf(xw); LineData *ld; Bool changed = False; IAttr start; IAttr my_attrs = CharOf(screen->xmc_attributes & XMC_FLAGS); int row = screen->cur_row; int col = screen->cur_col; /* Find the preceding cell. */ ld = getLineData(screen, row); if (ld->charData[col] != XMC_GLITCH) { if (col != 0) { col--; } else if (!screen->xmc_inline && row != 0) { ld = getLineData(screen, --row); col = LineMaxCol(screen, ld); } } start = (ld->attribs[col] & my_attrs); /* Now propagate the starting state until we reach a cell which holds * a glitch. */ for (;;) { if (col < LineMaxCol(screen, ld)) { col++; } else if (!screen->xmc_inline && row < screen->max_row) { col = 0; ld = getLineData(screen, ++row); } else break; if (ld->charData[col] == XMC_GLITCH) break; if ((ld->attribs[col] & my_attrs) != start) { ld->attribs[col] = (IAttr) (start | (ld->attribs[col] & ~my_attrs)); changed = True; } } TRACE(("XMC %s (%s:%d/%d) from %d,%d to %d,%d\n", changed ? "Ripple" : "Nochange", BtoS(xw->flags & my_attrs), my_attrs, start, screen->cur_row, screen->cur_col, row, col)); if (changed) { ScrnUpdate(xw, screen->cur_row, 0, row + 1 - screen->cur_row, MaxCols(screen), True); } } xterm-399/menu.h0000644000000000000000000004137414723171565012376 0ustar rootroot/* $XTermId: menu.h,v 1.147 2024/12/01 23:38:29 tom Exp $ */ /* * Copyright 1999-2021,2024 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * * * Copyright 1989 X Consortium * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of the X Consortium shall * not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization * from the X Consortium. */ #ifndef included_menu_h #define included_menu_h /* *INDENT-OFF* */ #include #ifndef OPT_MENU_KEEPCLIPBOARD #define OPT_MENU_KEEPCLIPBOARD 0 /* useful for debugging */ #endif typedef struct _MenuEntry { const char *name; void (*function) PROTO_XT_CALLBACK_ARGS; Widget widget; } MenuEntry; extern MenuEntry mainMenuEntries[], vtMenuEntries[]; extern MenuEntry fontMenuEntries[]; #if OPT_TEK4014 extern MenuEntry tekMenuEntries[]; #endif extern void Handle8BitControl PROTO_XT_ACTIONS_ARGS; extern void HandleAllow132 PROTO_XT_ACTIONS_ARGS; extern void HandleAllowBoldFonts PROTO_XT_ACTIONS_ARGS; extern void HandleAllowColorOps PROTO_XT_ACTIONS_ARGS; extern void HandleAllowFontOps PROTO_XT_ACTIONS_ARGS; extern void HandleAllowMouseOps PROTO_XT_ACTIONS_ARGS; extern void HandleAllowSends PROTO_XT_ACTIONS_ARGS; extern void HandleAllowTcapOps PROTO_XT_ACTIONS_ARGS; extern void HandleAllowTitleOps PROTO_XT_ACTIONS_ARGS; extern void HandleAllowWindowOps PROTO_XT_ACTIONS_ARGS; extern void HandleAltEsc PROTO_XT_ACTIONS_ARGS; extern void HandleAltScreen PROTO_XT_ACTIONS_ARGS; extern void HandleAppCursor PROTO_XT_ACTIONS_ARGS; extern void HandleAppKeypad PROTO_XT_ACTIONS_ARGS; extern void HandleAutoLineFeed PROTO_XT_ACTIONS_ARGS; extern void HandleAutoWrap PROTO_XT_ACTIONS_ARGS; extern void HandleBackarrow PROTO_XT_ACTIONS_ARGS; extern void HandleBellIsUrgent PROTO_XT_ACTIONS_ARGS; extern void HandleCreateMenu PROTO_XT_ACTIONS_ARGS; extern void HandleCursesEmul PROTO_XT_ACTIONS_ARGS; extern void HandleCursorBlink PROTO_XT_ACTIONS_ARGS; extern void HandleDeleteIsDEL PROTO_XT_ACTIONS_ARGS; extern void HandleDumpHtml PROTO_XT_ACTIONS_ARGS; extern void HandleDumpSvg PROTO_XT_ACTIONS_ARGS; extern void HandleFontBoxChars PROTO_XT_ACTIONS_ARGS; extern void HandleFontDoublesize PROTO_XT_ACTIONS_ARGS; extern void HandleFontLoading PROTO_XT_ACTIONS_ARGS; extern void HandleFontPacked PROTO_XT_ACTIONS_ARGS; extern void HandleFullscreen PROTO_XT_ACTIONS_ARGS; extern void HandleHpFunctionKeys PROTO_XT_ACTIONS_ARGS; extern void HandleJumpscroll PROTO_XT_ACTIONS_ARGS; extern void HandleKeepClipboard PROTO_XT_ACTIONS_ARGS; extern void HandleKeepSelection PROTO_XT_ACTIONS_ARGS; extern void HandleLogging PROTO_XT_ACTIONS_ARGS; extern void HandleMarginBell PROTO_XT_ACTIONS_ARGS; extern void HandleMetaEsc PROTO_XT_ACTIONS_ARGS; extern void HandleNumLock PROTO_XT_ACTIONS_ARGS; extern void HandleOldFunctionKeys PROTO_XT_ACTIONS_ARGS; extern void HandlePopupMenu PROTO_XT_ACTIONS_ARGS; extern void HandlePrintControlMode PROTO_XT_ACTIONS_ARGS; extern void HandlePrintEverything PROTO_XT_ACTIONS_ARGS; extern void HandlePrintImmediate PROTO_XT_ACTIONS_ARGS; extern void HandlePrintOnError PROTO_XT_ACTIONS_ARGS; extern void HandlePrintScreen PROTO_XT_ACTIONS_ARGS; extern void HandleRedraw PROTO_XT_ACTIONS_ARGS; extern void HandleRenderFont PROTO_XT_ACTIONS_ARGS; extern void HandleReverseVideo PROTO_XT_ACTIONS_ARGS; extern void HandleReverseWrap PROTO_XT_ACTIONS_ARGS; extern void HandleScoFunctionKeys PROTO_XT_ACTIONS_ARGS; extern void HandleScrollKey PROTO_XT_ACTIONS_ARGS; extern void HandleScrollTtyOutput PROTO_XT_ACTIONS_ARGS; extern void HandleScrollbar PROTO_XT_ACTIONS_ARGS; extern void HandleSecure PROTO_XT_ACTIONS_ARGS; extern void HandleSendSignal PROTO_XT_ACTIONS_ARGS; extern void HandleSetPopOnBell PROTO_XT_ACTIONS_ARGS; extern void HandleSetPrivateColorRegisters PROTO_XT_ACTIONS_ARGS; extern void HandleSetSelect PROTO_XT_ACTIONS_ARGS; extern void HandleSetTekText PROTO_XT_ACTIONS_ARGS; extern void HandleSetTerminalType PROTO_XT_ACTIONS_ARGS; extern void HandleSetVisualBell PROTO_XT_ACTIONS_ARGS; extern void HandleSixelScrolling PROTO_XT_ACTIONS_ARGS; extern void HandleSunFunctionKeys PROTO_XT_ACTIONS_ARGS; extern void HandleSunKeyboard PROTO_XT_ACTIONS_ARGS; extern void HandleTekCopy PROTO_XT_ACTIONS_ARGS; extern void HandleTekPage PROTO_XT_ACTIONS_ARGS; extern void HandleTekReset PROTO_XT_ACTIONS_ARGS; extern void HandleTiteInhibit PROTO_XT_ACTIONS_ARGS; extern void HandleToolbar PROTO_XT_ACTIONS_ARGS; extern void HandleUTF8Fonts PROTO_XT_ACTIONS_ARGS; extern void HandleUTF8Mode PROTO_XT_ACTIONS_ARGS; extern void HandleUTF8Title PROTO_XT_ACTIONS_ARGS; extern void HandleVisibility PROTO_XT_ACTIONS_ARGS; extern void HandleWriteError PROTO_XT_ACTIONS_ARGS; extern void HandleWriteNow PROTO_XT_ACTIONS_ARGS; extern GCC_NORETURN void HandleClearSavedLines PROTO_XT_ACTIONS_ARGS; extern GCC_NORETURN void HandleHardReset PROTO_XT_ACTIONS_ARGS; extern GCC_NORETURN void HandleQuit PROTO_XT_ACTIONS_ARGS; extern GCC_NORETURN void HandleSoftReset PROTO_XT_ACTIONS_ARGS; extern void SetupMenus (Widget /*shell*/, Widget */*forms*/, Widget */*menus*/, Dimension * /*menu_high*/); #if OPT_TOOLBAR extern void ShowToolbar(Bool); #endif /* * The following definitions MUST match the order of entries given in * the mainMenuEntries, vtMenuEntries, and tekMenuEntries arrays in menu.c. */ /* * items in primary menu */ typedef enum { #if OPT_TOOLBAR mainMenu_toolbar, #endif #if OPT_MAXIMIZE mainMenu_fullscreen, #endif mainMenu_securekbd, mainMenu_allowsends, mainMenu_redraw, mainMenu_line1, #ifdef ALLOWLOGGING mainMenu_logging, #endif #if OPT_PRINT_ON_EXIT mainMenu_write_now, mainMenu_write_error, #endif mainMenu_print, mainMenu_print_redir, #if OPT_SCREEN_DUMPS mainMenu_dump_html, mainMenu_dump_svg, #endif mainMenu_line2, mainMenu_8bit_ctrl, mainMenu_backarrow, #if OPT_NUM_LOCK mainMenu_num_lock, mainMenu_alt_esc, mainMenu_meta_esc, #endif mainMenu_delete_del, mainMenu_old_fkeys, #if OPT_TCAP_FKEYS mainMenu_tcap_fkeys, #endif #if OPT_HP_FUNC_KEYS mainMenu_hp_fkeys, #endif #if OPT_SCO_FUNC_KEYS mainMenu_sco_fkeys, #endif #if OPT_SUN_FUNC_KEYS mainMenu_sun_fkeys, #endif #if OPT_SUNPC_KBD mainMenu_sun_kbd, #endif mainMenu_line3, mainMenu_suspend, mainMenu_continue, mainMenu_interrupt, mainMenu_hangup, mainMenu_terminate, mainMenu_kill, mainMenu_line4, mainMenu_quit, mainMenu_LAST } mainMenuIndices; /* * items in vt100 mode menu */ typedef enum { vtMenu_scrollbar, vtMenu_jumpscroll, vtMenu_reversevideo, vtMenu_autowrap, vtMenu_reversewrap, vtMenu_autolinefeed, vtMenu_appcursor, vtMenu_appkeypad, vtMenu_scrollkey, vtMenu_scrollttyoutput, vtMenu_allow132, vtMenu_keepSelection, #if OPT_MENU_KEEPCLIPBOARD vtMenu_keepClipboard, #endif vtMenu_selectToClipboard, vtMenu_visualbell, vtMenu_bellIsUrgent, vtMenu_poponbell, #if OPT_BLINK_CURS vtMenu_cursorblink, #endif vtMenu_titeInhibit, #ifndef NO_ACTIVE_ICON vtMenu_activeicon, #endif /* NO_ACTIVE_ICON */ vtMenu_line1, vtMenu_softreset, vtMenu_hardreset, vtMenu_clearsavedlines, vtMenu_line2, #if OPT_TEK4014 vtMenu_tekshow, vtMenu_tekmode, vtMenu_vthide, #endif vtMenu_altscreen, #if OPT_SIXEL_GRAPHICS vtMenu_sixelscrolling, #endif #if OPT_GRAPHICS vtMenu_privatecolorregisters, #endif vtMenu_LAST } vtMenuIndices; /* * items in vt100 font menu */ typedef enum { fontMenu_default, fontMenu_font1, fontMenu_font2, fontMenu_font3, fontMenu_font4, fontMenu_font5, fontMenu_font6, fontMenu_font7, #define fontMenu_lastBuiltin fontMenu_font7 fontMenu_fontescape, fontMenu_fontsel, /* number of non-line items down to here should match NMENUFONTS in ptyx.h */ #if OPT_DEC_CHRSET || OPT_BOX_CHARS || OPT_DEC_SOFTFONT fontMenu_line1, fontMenu_allowBoldFonts, #if OPT_BOX_CHARS fontMenu_font_boxchars, fontMenu_font_packedfont, #endif #if OPT_DEC_CHRSET fontMenu_font_doublesize, #endif #if OPT_DEC_SOFTFONT fontMenu_font_loadable, #endif #endif #if OPT_RENDERFONT || OPT_WIDE_CHARS fontMenu_line2, #if OPT_RENDERFONT fontMenu_render_font, #endif #if OPT_WIDE_CHARS fontMenu_utf8_mode, fontMenu_utf8_fonts, fontMenu_utf8_title, #endif #endif #if OPT_ALLOW_XXX_OPS fontMenu_line3, fontMenu_allowColorOps, fontMenu_allowFontOps, fontMenu_allowMouseOps, fontMenu_allowTcapOps, fontMenu_allowTitleOps, fontMenu_allowWindowOps, #endif fontMenu_LAST } fontMenuIndices; /* * items in tek4014 mode menu */ #if OPT_TEK4014 typedef enum { tekMenu_tektextlarge, tekMenu_tektext2, tekMenu_tektext3, tekMenu_tektextsmall, tekMenu_line1, tekMenu_tekpage, tekMenu_tekreset, tekMenu_tekcopy, tekMenu_line2, tekMenu_vtshow, tekMenu_vtmode, tekMenu_tekhide, tekMenu_LAST } tekMenuIndices; #endif /* * functions for updating menus */ extern void SetItemSensitivity(Widget mi, Bool val); typedef enum { toggleErr = -2, toggleAll = -1, toggleOff = 0, toggleOn = 1 } ToggleEnum; extern int decodeToggle(XtermWidget /* xw */, String * /* params */, Cardinal /* nparams */); /* * there should be one of each of the following for each checkable item */ #if OPT_TOOLBAR extern void update_toolbar(void); #else #define update_toolbar() /* nothing */ #endif #if OPT_MAXIMIZE extern void update_fullscreen(void); #else #define update_fullscreen() /* nothing */ #endif extern void update_securekbd(void); extern void update_allowsends(void); #ifdef ALLOWLOGGING extern void update_logging(void); #else #define update_logging() /*nothing*/ #endif #if OPT_PRINT_ON_EXIT extern void update_write_error(void); #else #define update_write_error() /*nothing*/ #endif extern void update_print_redir(void); extern void update_8bit_control(void); extern void update_decbkm(void); #if OPT_NUM_LOCK extern void update_num_lock(void); extern void update_alt_esc(void); extern void update_meta_esc(void); #else #define update_num_lock() /*nothing*/ #define update_alt_esc() /*nothing*/ #define update_meta_esc() /*nothing*/ #endif extern void update_old_fkeys(void); extern void update_delete_del(void); #if OPT_SUNPC_KBD extern void update_sun_kbd(void); #endif #if OPT_HP_FUNC_KEYS extern void update_hp_fkeys(void); #else #define update_hp_fkeys() /*nothing*/ #endif #if OPT_SCO_FUNC_KEYS extern void update_sco_fkeys(void); #else #define update_sco_fkeys() /*nothing*/ #endif #if OPT_SUN_FUNC_KEYS extern void update_sun_fkeys(void); #else #define update_sun_fkeys() /*nothing*/ #endif #if OPT_TCAP_FKEYS extern void update_tcap_fkeys(void); #else #define update_tcap_fkeys() /*nothing*/ #endif extern void update_scrollbar(void); extern void update_jumpscroll(void); extern void update_reversevideo(void); extern void update_autowrap(void); extern void update_reversewrap(void); extern void update_autolinefeed(void); extern void update_appcursor(void); extern void update_appkeypad(void); extern void update_scrollkey(void); extern void update_keepSelection(void); extern void update_selectToClipboard(void); extern void update_scrollttyoutput(void); extern void update_allow132(void); extern void update_cursesemul(void); extern void update_visualbell(void); extern void update_bellIsUrgent(void); extern void update_poponbell(void); #if OPT_MENU_KEEPCLIPBOARD extern void update_keepClipboard(void); #else #define update_keepClipboard() /* nothing */ #endif #define update_marginbell() /* nothing */ #if OPT_LOAD_VTFONTS extern void update_font_escape(void); #else #define update_font_escape() /* nothing */ #endif #if OPT_ALLOW_XXX_OPS extern void update_menu_allowColorOps(void); extern void update_menu_allowFontOps(void); extern void update_menu_allowMouseOps(void); extern void update_menu_allowTcapOps(void); extern void update_menu_allowTitleOps(void); extern void update_menu_allowWindowOps(void); #endif #if OPT_BLINK_CURS extern void update_cursorblink(void); #else #define update_cursorblink() /* nothing */ #endif extern void update_altscreen(void); extern void update_titeInhibit(void); #ifndef NO_ACTIVE_ICON extern void update_activeicon(void); #endif /* NO_ACTIVE_ICON */ #if OPT_DEC_CHRSET extern void update_font_doublesize(void); #else #define update_font_doublesize() /* nothing */ #endif #if OPT_BOX_CHARS extern void update_font_boxchars(void); extern void update_font_packed(void); #else #define update_font_boxchars() /* nothing */ #define update_font_packed() /* nothing */ #endif #if OPT_SIXEL_GRAPHICS extern void update_decsdm(void); #else #define update_decsdm() /* nothing */ #endif #if OPT_GRAPHICS extern void update_privatecolorregisters(void); #else #define update_privatecolorregisters() /* nothing */ #endif #if OPT_DEC_SOFTFONT extern void update_font_loadable(void); #else #define update_font_loadable() /* nothing */ #endif #if OPT_RENDERFONT extern void update_font_renderfont(void); #else #define update_font_renderfont() /* nothing */ #endif #if OPT_WIDE_CHARS extern void update_font_utf8_mode(void); extern void update_font_utf8_fonts(void); extern void update_font_utf8_title(void); #else #define update_font_utf8_mode() /* nothing */ #define update_font_utf8_fonts() /* nothing */ #define update_font_utf8_title() /* nothing */ #endif #if OPT_TEK4014 extern void update_tekshow(void); extern void update_vttekmode(void); extern void update_vtshow(void); extern void set_vthide_sensitivity(void); extern void set_tekhide_sensitivity(void); #else #define update_tekshow() /*nothing*/ #define update_vttekmode() /*nothing*/ #define update_vtshow() /*nothing*/ #define set_vthide_sensitivity() /*nothing*/ #define set_tekhide_sensitivity() /*nothing*/ #endif #if OPT_DEC_CHRSET || OPT_BOX_CHARS || OPT_DEC_SOFTFONT extern void update_menu_allowBoldFonts(void); #else #define update_menu_allowBoldFonts() /*nothing*/ #endif /* * macros for mapping font size to tekMenu placement */ #define FS2MI(n) (n) /* font_size_to_menu_item */ #define MI2FS(n) (n) /* menu_item_to_font_size */ #if OPT_TEK4014 extern void set_tekfont_menu_item(int n,int val); #else #define set_tekfont_menu_item(n,val) /*nothing*/ #endif extern void set_menu_font(int val); /* *INDENT-ON* */ #endif /* included_menu_h */ xterm-399/resize.c0000644000000000000000000004045314763042165012720 0ustar rootroot/* $XTermId: resize.c,v 1.154 2025/03/08 13:21:57 tom Exp $ */ /* * Copyright 2003-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * * * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* resize.c */ #include #include #include #include #include #include #include #ifndef USE_TERMINFO /* avoid conflict with configure script */ #if defined(__QNX__) || defined(__SCO__) || defined(linux) || defined(__OpenBSD__) || defined(__UNIXWARE__) #define USE_TERMINFO #endif #endif #if defined(__QNX__) #include #endif /* * Some OS's may want to use both, like SCO for example. We catch here anyone * who hasn't decided what they want. */ #if !defined(USE_TERMCAP) && !defined(USE_TERMINFO) #define USE_TERMINFO #endif #include #include #ifdef USE_IGNORE_RC int ignore_unused; #endif #define ESCAPE(string) "\033" string #define EMULATIONS 2 #define SUN 1 #define VT100 0 #define TIMEOUT 3 #define SHELL_UNKNOWN 0 #define SHELL_C 1 #define SHELL_BOURNE 2 /* *INDENT-OFF* */ static struct { const char *name; int type; } shell_list[] = { { "csh", SHELL_C }, /* vanilla cshell */ { "jcsh", SHELL_C }, { "tcsh", SHELL_C }, { "sh", SHELL_BOURNE }, /* vanilla Bourne shell */ { "ash", SHELL_BOURNE }, { "bash", SHELL_BOURNE }, /* GNU Bourne again shell */ { "dash", SHELL_BOURNE }, { "jsh", SHELL_BOURNE }, { "ksh", SHELL_BOURNE }, /* Korn shell (from AT&T toolchest) */ { "ksh-i", SHELL_BOURNE }, /* another name for Korn shell */ { "ksh93", SHELL_BOURNE }, /* Korn shell */ { "mksh", SHELL_BOURNE }, { "pdksh", SHELL_BOURNE }, { "zsh", SHELL_BOURNE }, { NULL, SHELL_BOURNE } /* default (same as xterm's) */ }; /* *INDENT-ON* */ static const char *const emuname[EMULATIONS] = { "VT100", "Sun", }; static char *myname; static int shell_type = SHELL_UNKNOWN; static const char *const getattr[EMULATIONS] = { ESCAPE("[c"), NULL, }; static const char *const getsize[EMULATIONS] = { ESCAPE("7") ESCAPE("[r") ESCAPE("[9999;9999H") ESCAPE("[6n"), ESCAPE("[18t"), }; #if defined(USE_STRUCT_WINSIZE) static const char *const getwsize[EMULATIONS] = { /* size in pixels */ NULL, ESCAPE("[14t"), }; #endif /* USE_STRUCT_WINSIZE */ static const char *const restore[EMULATIONS] = { ESCAPE("8"), NULL, }; static const char *const setsize[EMULATIONS] = { NULL, ESCAPE("[8;%s;%st"), }; #ifdef USE_ANY_SYSV_TERMIO static struct termio tioorig; #elif defined(USE_TERMIOS) static struct termios tioorig; #else static struct sgttyb sgorig; #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ static const char *const reply_attr[EMULATIONS] = { ESCAPE("[?%d;%dc"), NULL, }; static const char *const reply_size[EMULATIONS] = { ESCAPE("[%d;%dR"), ESCAPE("[8;%d;%dt"), }; static const char sunname[] = "sunsize"; static int tty; static FILE *ttyfp; #if defined(USE_STRUCT_WINSIZE) static const char *wsize[EMULATIONS] = { NULL, ESCAPE("[4;%hd;%hdt"), }; #endif /* USE_STRUCT_WINSIZE */ static GCC_NORETURN void failed(const char *); static GCC_NORETURN void onintr(int); static GCC_NORETURN void resize_timeout(int); static GCC_NORETURN void Usage(void); static void failed(const char *s) { int save = errno; IGNORE_RC(write(2, myname, strlen(myname))); IGNORE_RC(write(2, ": ", (size_t) 2)); errno = save; perror(s); exit(EXIT_FAILURE); } /* ARGSUSED */ static void onintr(int sig GCC_UNUSED) { #ifdef USE_ANY_SYSV_TERMIO (void) ioctl(tty, TCSETAW, &tioorig); #elif defined(USE_TERMIOS) (void) tcsetattr(tty, TCSADRAIN, &tioorig); #else /* not USE_TERMIOS */ (void) ioctl(tty, TIOCSETP, &sgorig); #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ exit(EXIT_FAILURE); } const char *timeout_message = "?"; static void resize_timeout(int sig) { fprintf(stderr, "\n%s: %s\r\n", myname, timeout_message); onintr(sig); } static void Usage(void) { fprintf(stderr, strcmp(myname, sunname) == 0 ? "Usage: %s [rows cols]\n" : "Usage: %s [-v] [-u] [-c] [-s [rows cols]]\n", myname); exit(EXIT_FAILURE); } #ifdef USE_TERMCAP static void print_termcap(const char *termcap) { int ch; putchar('\''); while ((ch = *termcap++) != '\0') { switch (ch & 0xff) { case 127: /* undo bug in GNU termcap */ printf("^?"); break; case '\'': /* must escape anyway (unlikely) */ /* FALLTHRU */ case '!': /* must escape for SunOS csh */ putchar('\\'); /* FALLTHRU */ default: putchar(ch); break; } } putchar('\''); } #endif /* USE_TERMCAP */ static int checkdigits(char *str) { while (*str) { if (!isdigit(CharOf(*str))) return (0); str++; } return (1); } static void unexpected_char(int c) { fprintf(stderr, "%s: unknown character %#x, exiting.\r\n", myname, (unsigned) c); onintr(0); } static void readstring(FILE *fp, char *buf, const char *str) { int last, c; #if HAVE_SETITIMER struct itimerval it; #endif int limit = (BUFSIZ - 3); signal(SIGALRM, resize_timeout); #if HAVE_SETITIMER memset((char *) &it, 0, sizeof(struct itimerval)); it.it_value.tv_sec = TIMEOUT; setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL); #else alarm(TIMEOUT); #endif if ((c = getc(fp)) == 0233) { /* meta-escape, CSI */ c = ESCAPE("")[0]; *buf++ = (char) c; *buf++ = '['; } else { *buf++ = (char) c; } if (c != *str) { unexpected_char(c); } last = str[strlen(str) - 1]; while ((c = getc(fp)) != EOF) { if (--limit <= 0) { fprintf(stderr, "%s: unexpected response\n", myname); onintr(0); } if (c < 32 || c > 126) { unexpected_char(c); } *buf++ = (char) c; if (c == last) break; } #if HAVE_SETITIMER memset((char *) &it, 0, sizeof(struct itimerval)); setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL); #else alarm(0); #endif *buf = 0; } /* resets termcap string to reflect current screen size */ int main(int argc, char **argv ENVP_ARG) { #ifdef USE_TERMCAP char *env; #endif char *ptr; int emu = VT100; char *shell; int i; int rc; int rows, cols; #ifdef USE_ANY_SYSV_TERMIO struct termio tio; #elif defined(USE_TERMIOS) struct termios tio; #else struct sgttyb sg; #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ #ifdef USE_TERMCAP int ok_tcap = 1; char termcap[TERMCAP_SIZE]; char newtc[TERMCAP_SIZE]; #endif /* USE_TERMCAP */ char buf[BUFSIZ]; #ifdef TTYSIZE_STRUCT TTYSIZE_STRUCT ts; #endif char *name_of_tty; #ifdef CANT_OPEN_DEV_TTY extern char *ttyname(); #endif const char *setname = ""; myname = x_basename(argv[0]); if (strcmp(myname, sunname) == 0) emu = SUN; for (argv++, argc--; argc > 0 && **argv == '-'; argv++, argc--) { switch ((*argv)[1]) { case 's': /* Sun emulation */ if (emu == SUN) Usage(); /* Never returns */ emu = SUN; break; case 'u': /* Bourne (Unix) shell */ shell_type = SHELL_BOURNE; break; case 'c': /* C shell */ shell_type = SHELL_C; break; case 'v': printf("%s\n", xtermVersion()); exit(EXIT_SUCCESS); default: Usage(); /* Never returns */ } } if (SHELL_UNKNOWN == shell_type) { /* Find out what kind of shell this user is running. * This is the same algorithm that xterm uses. */ if ((ptr = x_getenv("SHELL")) == NULL) { uid_t uid = getuid(); struct passwd pw; if (x_getpwuid(uid, &pw)) { (void) x_getlogin(uid, &pw); } if (!OkPasswd(&pw) || *(ptr = pw.pw_shell) == 0) { /* this is the same default that xterm uses */ ptr = x_strdup("/bin/sh"); } } shell = x_basename(ptr); /* now that we know, what kind is it? */ for (i = 0; shell_list[i].name; i++) { if (!strcmp(shell_list[i].name, shell)) { break; } } shell_type = shell_list[i].type; } if (argc == 2) { if (!setsize[emu]) { fprintf(stderr, "%s: Can't set window size under %s emulation\n", myname, emuname[emu]); exit(EXIT_FAILURE); } if (!checkdigits(argv[0]) || !checkdigits(argv[1])) { Usage(); /* Never returns */ } } else if (argc != 0) { Usage(); /* Never returns */ } #ifdef CANT_OPEN_DEV_TTY if ((name_of_tty = ttyname(fileno(stderr))) == NULL) #endif name_of_tty = x_strdup("/dev/tty"); if ((ttyfp = fopen(name_of_tty, "r+")) == NULL) { fprintf(stderr, "%s: can't open terminal %s\n", myname, name_of_tty); exit(EXIT_FAILURE); } tty = fileno(ttyfp); #ifdef USE_TERMCAP if ((env = x_getenv("TERM")) == NULL) { env = x_strdup(DFT_TERMTYPE); if (SHELL_BOURNE == shell_type) { setname = "TERM=" DFT_TERMTYPE ";\nexport TERM;\n"; } else { setname = "setenv TERM " DFT_TERMTYPE ";\n"; } } termcap[0] = 0; /* ...just in case we've accidentally gotten terminfo */ if (tgetent(termcap, env) <= 0 || termcap[0] == 0) { ok_tcap = 0; } #endif /* USE_TERMCAP */ #ifdef USE_TERMINFO if (x_getenv("TERM") == NULL) { if (SHELL_BOURNE == shell_type) { setname = "TERM=" DFT_TERMTYPE ";\nexport TERM;\n"; } else { setname = "setenv TERM " DFT_TERMTYPE ";\n"; } } #endif /* USE_TERMINFO */ #ifdef USE_ANY_SYSV_TERMIO rc = ioctl(tty, TCGETA, &tioorig); tio = tioorig; UIntClr(tio.c_iflag, (ICRNL | IUCLC)); UIntClr(tio.c_lflag, (ICANON | ECHO)); tio.c_cflag |= CS8; tio.c_cc[VMIN] = 6; tio.c_cc[VTIME] = 1; #elif defined(USE_TERMIOS) rc = tcgetattr(tty, &tioorig); tio = tioorig; UIntClr(tio.c_iflag, ICRNL); UIntClr(tio.c_lflag, (ICANON | ECHO)); tio.c_cflag |= CS8; tio.c_cc[VMIN] = 6; tio.c_cc[VTIME] = 1; #else /* not USE_TERMIOS */ rc = ioctl(tty, TIOCGETP, &sgorig); sg = sgorig; sg.sg_flags |= RAW; UIntClr(sg.sg_flags, ECHO); #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ if (rc != 0) failed("get tty settings"); signal(SIGINT, onintr); signal(SIGQUIT, onintr); signal(SIGTERM, onintr); #ifdef USE_ANY_SYSV_TERMIO rc = ioctl(tty, TCSETAW, &tio); #elif defined(USE_TERMIOS) rc = tcsetattr(tty, TCSADRAIN, &tio); #else /* not USE_TERMIOS */ rc = ioctl(tty, TIOCSETP, &sg); #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ if (rc != 0) failed("set tty settings"); if (argc == 2) { /* look for optional parameters of "-s" */ char *tmpbuf = TypeMallocN(char, strlen(setsize[emu]) + strlen(argv[0]) + strlen(argv[1]) + 1); if (tmpbuf == NULL) { fprintf(stderr, "%s: Cannot query size\n", myname); onintr(0); } else { sprintf(tmpbuf, setsize[emu], argv[0], argv[1]); IGNORE_RC(write(tty, tmpbuf, strlen(tmpbuf))); free(tmpbuf); } } if (getattr[emu]) { timeout_message = "Terminal is not VT100-compatible"; IGNORE_RC(write(tty, getattr[emu], strlen(getattr[emu]))); readstring(ttyfp, buf, reply_attr[emu]); } timeout_message = "Time out occurred"; IGNORE_RC(write(tty, getsize[emu], strlen(getsize[emu]))); readstring(ttyfp, buf, reply_size[emu]); if (sscanf(buf, reply_size[emu], &rows, &cols) != 2) { fprintf(stderr, "%s: Can't get rows and columns\r\n", myname); onintr(0); } if (restore[emu]) IGNORE_RC(write(tty, restore[emu], strlen(restore[emu]))); #if defined(USE_STRUCT_WINSIZE) /* finally, set the tty's window size */ if (getwsize[emu]) { /* get the window size in pixels */ IGNORE_RC(write(tty, getwsize[emu], strlen(getwsize[emu]))); readstring(ttyfp, buf, wsize[emu]); if (sscanf(buf, wsize[emu], &ts.ws_xpixel, &ts.ws_ypixel) != 2) { fprintf(stderr, "%s: Can't get window size\r\n", myname); onintr(0); } setup_winsize(ts, rows, cols, 0, 0); SET_TTYSIZE(tty, ts); } else if (ioctl(tty, TIOCGWINSZ, &ts) != -1) { /* we don't have any way of directly finding out the current height & width of the window in pixels. We try our best by computing the font height and width from the "old" window-size values, and multiplying by these ratios... */ #define scaled(old,new,len) (old)?((unsigned)(new)*(len)/(old)):(len) setup_winsize(ts, rows, cols, scaled(TTYSIZE_ROWS(ts), rows, ts.ws_ypixel), scaled(TTYSIZE_COLS(ts), cols, ts.ws_xpixel)); SET_TTYSIZE(tty, ts); } #endif /* USE_STRUCT_WINSIZE */ #ifdef USE_ANY_SYSV_TERMIO rc = ioctl(tty, TCSETAW, &tioorig); #elif defined(USE_TERMIOS) rc = tcsetattr(tty, TCSADRAIN, &tioorig); #else /* not USE_TERMIOS */ rc = ioctl(tty, TIOCSETP, &sgorig); #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ if (rc != 0) failed("set tty settings"); signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGTERM, SIG_DFL); #ifdef USE_TERMCAP if (ok_tcap) { /* update termcap string */ /* first do columns */ if ((ptr = x_strindex(termcap, "co#")) == NULL) { fprintf(stderr, "%s: No `co#'\n", myname); exit(EXIT_FAILURE); } i = (int) (ptr - termcap) + 3; strncpy(newtc, termcap, (size_t) i); sprintf(newtc + i, "%d", cols); if ((ptr = strchr(ptr, ':')) != NULL) strcat(newtc, ptr); /* now do lines */ if ((ptr = x_strindex(newtc, "li#")) == NULL) { fprintf(stderr, "%s: No `li#'\n", myname); exit(EXIT_FAILURE); } i = (int) (ptr - newtc) + 3; strncpy(termcap, newtc, (size_t) i); sprintf(termcap + i, "%d", rows); if ((ptr = strchr(ptr, ':')) != NULL) strcat(termcap, ptr); } #endif /* USE_TERMCAP */ if (SHELL_BOURNE == shell_type) { #ifdef USE_TERMCAP if (ok_tcap) { printf("%sTERMCAP=", setname); print_termcap(termcap); printf(";\nexport TERMCAP;\n"); } #endif /* USE_TERMCAP */ #ifdef USE_TERMINFO printf("%sCOLUMNS=%d;\nLINES=%d;\nexport COLUMNS LINES;\n", setname, cols, rows); #endif /* USE_TERMINFO */ } else { /* not Bourne shell */ #ifdef USE_TERMCAP if (ok_tcap) { printf("set noglob;\n%ssetenv TERMCAP ", setname); print_termcap(termcap); printf(";\nunset noglob;\n"); } #endif /* USE_TERMCAP */ #ifdef USE_TERMINFO printf("set noglob;\n%ssetenv COLUMNS '%d';\nsetenv LINES '%d';\nunset noglob;\n", setname, cols, rows); #endif /* USE_TERMINFO */ } exit(EXIT_SUCCESS); } xterm-399/xutf8.h0000644000000000000000000000327011454344504012472 0ustar rootroot/* * $XTermId: xutf8.h,v 1.4 2010/10/10 14:10:12 Jeremy.Huddleston Exp $ */ /* Copyright (c) 2001 by Juliusz Chroboczek Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #ifndef X_HAVE_UTF8_STRING #undef XA_UTF8_STRING Atom _xa_utf8_string(Display*); #define XA_UTF8_STRING(dpy) _xa_utf8_string(dpy) #undef XUTF8StringStyle #define XUTF8StringStyle 4 int Xutf8TextPropertyToTextList( Display *, const XTextProperty *, char ***, int * ); int Xutf8TextListToTextProperty( Display *, char **, int, XICCEncodingStyle, XTextProperty * ); int Xutf8LookupString( XIC, XKeyPressedEvent *, char *, int, KeySym *, Status * ); #else void xutf8_dummy(void); #endif xterm-399/VTparse.def0000644000000000000000000001131314765653676013331 0ustar rootroot# $XTermId: VTparse.def,v 1.76 2025/03/16 22:59:10 tom Exp $ # # vile:confmode rs=lf # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 1996-2024,2025 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # # List of symbols that need to be defined for VTparse.h. If you need to # change any of the CASE_ macros, make the change here and rerun the command # shown in VTparse.h. # CASE_GROUND_STATE CASE_IGNORE CASE_BELL CASE_BS CASE_CR CASE_ESC CASE_VMOT CASE_TAB CASE_SI CASE_SO CASE_SCR_STATE CASE_SCS0_STATE CASE_SCS1_STATE CASE_SCS2_STATE CASE_SCS3_STATE CASE_ESC_IGNORE CASE_ESC_DIGIT CASE_ESC_SEMI CASE_DEC_STATE CASE_ICH CASE_CUU CASE_CUD CASE_CUF CASE_CUB CASE_CUP CASE_ED CASE_EL CASE_IL CASE_DL CASE_DCH CASE_DA1 CASE_TRACK_MOUSE # XTHIMOUSE CASE_TBC CASE_SET CASE_RST CASE_SGR CASE_CPR CASE_DECSTBM CASE_DECREQTPARM CASE_DECSET CASE_DECRST CASE_DECALN CASE_GSETS CASE_DECSC CASE_DECRC CASE_DECKPAM CASE_DECKPNM CASE_IND CASE_NEL CASE_HTS CASE_RI CASE_SS2 CASE_SS3 CASE_CSI_STATE CASE_OSC CASE_RIS CASE_LS2 CASE_LS3 CASE_LS3R CASE_LS2R CASE_LS1R CASE_PRINT CASE_XTERM_SAVE # XTSAVE CASE_XTERM_RESTORE # XTRESTORE CASE_DECID CASE_HP_MEM_LOCK # HPMEMLOCK CASE_HP_MEM_UNLOCK # HPMEMUNLOCK CASE_HP_BUGGY_LL # HPBUGGYLL CASE_HPA CASE_VPA CASE_XTERM_WINOPS # XTWINOPS CASE_ECH CASE_CHT CASE_CPL CASE_CNL CASE_CBT CASE_SU CASE_SD CASE_S7C1T CASE_S8C1T CASE_ESC_SP_STATE CASE_ENQ CASE_DECSCL CASE_DECSCA CASE_DECSED CASE_DECSEL CASE_DCS CASE_PM CASE_SOS CASE_ST CASE_APC CASE_EPA CASE_SPA CASE_CSI_QUOTE_STATE CASE_DSR CASE_ANSI_LEVEL_1 CASE_ANSI_LEVEL_2 CASE_ANSI_LEVEL_3 CASE_MC CASE_DEC2_STATE CASE_DA2 CASE_DEC3_STATE CASE_DECRPTUI CASE_VT52_CUP CASE_REP CASE_CSI_EX_STATE CASE_DECSTR CASE_DECDHL CASE_DECSWL CASE_DECDWL CASE_DEC_MC CASE_ESC_PERCENT CASE_UTF8 CASE_CSI_TICK_STATE CASE_DECELR CASE_DECRQLP CASE_DECEFR CASE_DECSLE CASE_CSI_IGNORE CASE_VT52_IGNORE CASE_VT52_FINISH CASE_CSI_DOLLAR_STATE CASE_DECCRA CASE_DECERA CASE_DECFRA CASE_DECSERA CASE_DECSACE CASE_DECCARA CASE_DECRARA CASE_CSI_STAR_STATE CASE_SET_MOD_FKEYS # XTMODKEYS CASE_SET_MOD_FKEYS0 CASE_HIDE_POINTER # XTSMPOINTER CASE_SCS1A_STATE CASE_SCS2A_STATE CASE_SCS3A_STATE CASE_CSI_SPACE_STATE CASE_DECSCUSR CASE_XTERM_SM_TITLE # XTSMTITLE CASE_XTERM_RM_TITLE # XTRMTITLE CASE_DECSMBV CASE_DECSWBV CASE_DECLL CASE_DECRQM CASE_RQM CASE_CSI_DEC_DOLLAR_STATE CASE_SL CASE_SR CASE_DECDC CASE_DECIC CASE_DECBI CASE_DECFI CASE_DECRQCRA CASE_HPR CASE_VPR CASE_ANSI_SC CASE_ANSI_RC CASE_ESC_COLON CASE_SCS_PERCENT CASE_GSETS_PERCENT CASE_GRAPHICS_ATTRIBUTES # XTSMGRAPHICS CASE_DECRQPSR CASE_DECSCPP CASE_DECSNLS CASE_CSI_HASH_STATE CASE_XTERM_PUSH_SGR # XTPUSHSGR CASE_XTERM_REPORT_SGR # XTREPORTSGR CASE_XTERM_POP_SGR # XTPOPSGR CASE_XTERM_CHECKSUM # XTCHECKSUM CASE_GSETS3 CASE_GSETS5 CASE_SCS_DQUOTE CASE_GSETS_DQUOTE CASE_SCS_AMPRSND CASE_GSETS_AMPRSND CASE_REPORT_VERSION # XTVERSION CASE_XTERM_PUSH_COLORS # XTPUSHCOLORS CASE_XTERM_REPORT_COLORS # XTREPORTCOLORS CASE_XTERM_POP_COLORS # XTPOPCOLORS CASE_XTERM_SHIFT_ESCAPE # XTSHIFTESCAPE CASE_DECSSDT CASE_DECSASD CASE_XTERM_REPORT_MOD_FKEYS # XTQMODKEYS CASE_DECRQDE CASE_DECRQUPSS CASE_CSI_AMP_STATE CASE_CSI_COMMA_STATE CASE_DECAC CASE_DECATC CASE_DECTID CASE_DECST8C CASE_XTERM_TITLE_STACK # XTTITLEPOS CASE_SUB CASE_CAN CASE_SET_FMT_KEYS # XTFMTKEYS CASE_XTERM_REPORT_FMT_KEYS # XTQFMTKEYS xterm-399/html.c0000644000000000000000000002137214723143224012354 0ustar rootroot/* $XTermId: html.c,v 1.24 2024/12/01 20:27:00 tom Exp $ */ /* * Copyright 2018-2021,2024 Thomas E. Dickey * Copyright 2015,2018 Jens Schweikhardt * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the sale, * use or other dealings in this Software without prior written * authorization. */ #include #include #define MakeDim(color) \ color = (unsigned short) ((2 * (unsigned) color) / 3) #define RGBPCT(c) \ ((double)c.red / 655.35), \ ((double)c.green / 655.35), \ ((double)c.blue / 655.35) static void dumpHtmlHeader(XtermWidget xw, FILE *fp); static void dumpHtmlScreen(XtermWidget xw, FILE *fp); static void dumpHtmlLine(XtermWidget xw, int row, FILE *fp); static void dumpHtmlFooter(XtermWidget, FILE *fp); static void writeStyle(XtermWidget, FILE *fp); void xtermDumpHtml(XtermWidget xw) { char *saveLocale; FILE *fp; TRACE(("xtermDumpHtml...\n")); saveLocale = xtermSetLocale(LC_NUMERIC, "C"); fp = create_printfile(xw, ".xhtml"); if (fp != NULL) { dumpHtmlHeader(xw, fp); dumpHtmlScreen(xw, fp); dumpHtmlFooter(xw, fp); fclose(fp); } xtermResetLocale(LC_NUMERIC, saveLocale); TRACE(("...xtermDumpHtml done\n")); } static void dumpHtmlHeader(XtermWidget xw, FILE *fp) { fputs("\n", fp); fputs("\n", fp); fputs("\n", fp); fputs(" \n", fp); fprintf(fp, " \n", xtermVersion()); fputs(" \n", fp); fputs(" \n", fp); fputs(" Xterm\n", fp); writeStyle(xw, fp); fputs(" \n", fp); fputs(" \n", fp); fputs("
    \n", fp); fputs("
    ", fp);
        xevents(xw);
    }
    
    static void
    writeStyle(XtermWidget xw, FILE *fp)
    {
        TScreen *s = TScreenOf(xw);
    
        fputs("  \n", fp);
        xevents(xw);
    }
    
    static void
    dumpHtmlScreen(XtermWidget xw, FILE *fp)
    {
        TScreen *s = TScreenOf(xw);
        int row;
    
        for (row = s->top_marg; row <= s->bot_marg; ++row) {
    	dumpHtmlLine(xw, row, fp);
        }
    }
    
    /*
     * Note: initial and final space around values of class and style
     *       attribute are deliberate. They make it easier for XPath
     *       to test whether a particular name is among the attributes.
     *       It allows expressions such as
     *           [contains(@class, ' ul ')]
     *       instead of the unwieldy
     *           [contains(concat(' ', @class, ' '), ' ul ')]
     *       The ev and od (for even and odd rows) values
     *       avoid empty values when going back to old fg/bg.
     */
    static void
    dumpHtmlLine(XtermWidget xw, int row, FILE *fp)
    {
        TScreen *s = TScreenOf(xw);
        char attrs[2][sizeof
    		  ""];
        int attr_index = 0;
        char *attr = &attrs[attr_index][0];
        int inx = ROW2INX(s, row);
        LineData *ld = getLineData(s, inx);
        int col;
    
        if (ld == NULL)
    	return;
    
        for (col = 0; col < MaxCols(s); col++) {
    	XColor fgcolor, bgcolor;
    	IChar chr = ld->charData[col];
    	int slen = 0;
    
    	fgcolor.pixel = xw->old_foreground;
    	bgcolor.pixel = xw->old_background;
    #if OPT_ISO_COLORS
    	if (ld->attribs[col] & FG_COLOR) {
    	    Pixel fg = extract_fg(xw, ld->color[col], ld->attribs[col]);
    #if OPT_DIRECT_COLOR
    	    if (ld->attribs[col] & ATR_DIRECT_FG)
    		fgcolor.pixel = fg;
    	    else
    #endif
    		fgcolor.pixel = s->Acolors[fg].value;
    	}
    	if (ld->attribs[col] & BG_COLOR) {
    	    Pixel bg = extract_bg(xw, ld->color[col], ld->attribs[col]);
    #if OPT_DIRECT_COLOR
    	    if (ld->attribs[col] & ATR_DIRECT_BG)
    		bgcolor.pixel = bg;
    	    else
    #endif
    		bgcolor.pixel = s->Acolors[bg].value;
    	}
    #endif
    
    	(void) QueryOneColor(xw, &fgcolor);
    	(void) QueryOneColor(xw, &bgcolor);
    	xevents(xw);
    
    	if (ld->attribs[col] & BLINK) {
    	    /* White on red. */
    	    fgcolor.red = fgcolor.green = fgcolor.blue = MAX_U_COLOR;
    	    bgcolor.red = MAX_U_COLOR;
    	    bgcolor.green = bgcolor.blue = 0u;
    	}
    #if OPT_WIDE_ATTRS
    	if (ld->attribs[col] & ATR_FAINT) {
    	    MakeDim(fgcolor.red);
    	    MakeDim(fgcolor.green);
    	    MakeDim(fgcolor.blue);
    	}
    #endif
    	if (ld->attribs[col] & INVERSE) {
    	    XColor tmp = fgcolor;
    	    fgcolor = bgcolor;
    	    bgcolor = tmp;
    	}
    
    	slen = sprintf(attr + slen, "", RGBPCT(bgcolor));
    	if (col == 0) {
    	    fputs(attr, fp);
    	    attr = &attrs[attr_index ^= 1][0];
    	} else {
    	    if (strcmp(&attrs[0][0], &attrs[1][0])) {
    		fputs("", fp);
    		fputs(attr, fp);
    		attr = &attrs[attr_index ^= 1][0];
    	    }
    	}
    
    #if OPT_WIDE_CHARS
    	if (chr > 127) {
    	    /* Ignore hidden characters. */
    	    if (chr != HIDDEN_CHAR) {
    		Char temp[10];
    		*convertToUTF8(temp, chr) = 0;
    		fputs((char *) temp, fp);
    	    }
    	} else
    #endif
    	    switch (chr) {
    	    case 0:
    		fputc(' ', fp);
    		break;
    	    case '&':
    		fputs("&", fp);
    		break;
    	    case '<':
    		fputs("<", fp);
    		break;
    	    case '>':
    		fputs(">", fp);
    		break;
    	    case ' ':
    		fputs("\302\240", fp);
    		break;
    	    default:
    		fputc((int) chr, fp);
    	    }
    	xevents(xw);
        }
        fprintf(fp, "\n");
        xevents(xw);
    }
    
    static void
    dumpHtmlFooter(XtermWidget xw, FILE *fp)
    {
        fputs("
    \n", fp); fputs("
    \n", fp); fputs(" \n", fp); fputs("\n", fp); xevents(xw); } char * PixelToCSSColor(XtermWidget xw, Pixel p) { static char rgb[sizeof "rgb(100.00%, 100.00%, 100.00%)"]; XColor c; (void) xw; c.pixel = p; (void) QueryOneColor(xw, &c); sprintf(rgb, "rgb(%.2f%%, %.2f%%, %.2f%%)", RGBPCT(c)); return rgb; } xterm-399/xterm.h0000644000000000000000000022750114775150751012570 0ustar rootroot/* $XTermId: xterm.h,v 1.964 2025/04/08 07:36:09 tom Exp $ */ /* * Copyright 1999-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ /* * Common/useful definitions for XTERM application. * * This is also where we put the fallback definitions if we do not build using * the configure script. */ #ifndef included_xterm_h #define included_xterm_h /* *INDENT-OFF* */ #ifdef HAVE_CONFIG_H #include #endif #undef bcopy #include #ifndef HAVE_CONFIG_H #define HAVE_LIB_XAW 1 #ifdef CSRG_BASED /* Get definition of BSD */ #include #endif #ifndef DFT_TERMTYPE #define DFT_TERMTYPE "xterm" #endif #ifndef X_NOT_POSIX #define HAVE_WAITPID 1 #define HAVE_SYS_WAIT_H 1 #define HAVE_UNISTD_H 1 #endif #define HAVE_STDLIB_H 1 #if defined(sun) /* errno is declared in */ #else #define DECL_ERRNO 1 #endif #undef DECL_PTSNAME /* ptsname() is normally in stdlib.h */ #ifndef NOPUTENV #define HAVE_PUTENV 1 #endif #if defined(CSRG_BASED) || defined(__GNU__) || defined(__minix) #define USE_POSIX_TERMIOS 1 #endif #ifdef __FreeBSD__ #if __FreeBSD_version >= 900000 #define USE_SYSV_UTMP 1 #define UTMPX_FOR_UTMP 1 #define HAVE_UTMP_UT_HOST 1 #define HAVE_UTMP_UT_XTIME 1 #define ut_name ut_user #define ut_xtime ut_tv.tv_sec #endif #endif #ifdef __NetBSD__ #if __NetBSD_Version__ >= 106030000 /* 1.6C */ #define BSD_UTMPX 1 #define ut_xtime ut_tv.tv_sec #endif #endif #if defined(hpux) && !defined(__hpux) #define __hpux 1 /* HPUX 11.0 does not define this */ #endif #if !defined(__SCO__) && (defined(SCO) || defined(sco) || defined(SCO325)) #define __SCO__ 1 #endif #ifdef USE_POSIX_TERMIOS #define HAVE_TERMIOS_H 1 #define HAVE_TCGETATTR 1 #endif #if defined(__SCO__) || defined(__UNIXWARE__) || defined(__minix) #define USE_TERMCAP 1 #endif #if defined(UTMP) #define HAVE_UTMP 1 #endif #if (defined(SVR4) || defined(__SCO__) || defined(BSD_UTMPX)) && !defined(__CYGWIN__) #define UTMPX_FOR_UTMP 1 #endif #if !defined(ISC) && !defined(__QNX__) #define HAVE_UTMP_UT_HOST 1 #endif #if defined(UTMPX_FOR_UTMP) && !(defined(__hpux) || defined(__FreeBSD__)) #define HAVE_UTMP_UT_SESSION 1 #endif #if !(defined(__linux__) && (!defined(__GLIBC__) || (__GLIBC__ < 2))) && !defined(SVR4) && !defined(__FreeBSD__) #define ut_xstatus ut_exit.e_exit #endif #if defined(SVR4) || defined(__SCO__) || defined(BSD_UTMPX) || (defined(__linux__) && defined(__GLIBC__) && (__GLIBC__ >= 2) && !(defined(__powerpc__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0))) #define HAVE_UTMP_UT_XTIME 1 #endif #if defined(__linux__) || defined(__CYGWIN__) #define USE_LASTLOG #define HAVE_LASTLOG_H #define USE_STRUCT_LASTLOG #elif defined(BSD) && (BSD >= 199103) #ifdef BSD_UTMPX #define USE_LASTLOGX #elif defined(USE_SYSV_UTMP) #else #define USE_LASTLOG #define USE_STRUCT_LASTLOG #endif #endif #if defined(__OpenBSD__) #define DEFDELETE_DEL True #define DEF_BACKARO_ERASE True #define DEF_INITIAL_ERASE True #endif #if defined(__SCO__) || defined(__UNIXWARE__) #define DEFDELETE_DEL True #define OPT_SCO_FUNC_KEYS 1 #endif #if defined(__SCO__) || defined(SVR4) || defined(_POSIX_VERSION) || defined(__QNX__) || defined(__hpux) || (defined(BSD) && (BSD >= 199103)) || defined(__CYGWIN__) #define USE_POSIX_WAIT #endif #if defined(AIXV3) || defined(CRAY) || defined(__SCO__) || defined(SVR4) || (defined(SYSV) && defined(i386)) || defined(__hpux) || defined(__osf__) || defined(__linux__) || defined(macII) || defined(BSD_UTMPX) #define USE_SYSV_UTMP #endif #if defined(__GNU__) || defined(__osf__) #define USE_TTY_GROUP #endif #if defined(__CYGWIN__) #define HAVE_NCURSES_TERM_H 1 #endif #ifdef __osf__ #define TTY_GROUP_NAME "terminal" #endif #if defined(ut_xstatus) #define HAVE_UTMP_UT_XSTATUS 1 #endif #if defined(XKB) #define HAVE_XKB_BELL_EXT 1 #endif #if (defined(SVR4) && !defined(__CYGWIN__)) || defined(__linux__) || (defined(BSD) && (BSD >= 199103)) #define HAVE_POSIX_SAVED_IDS #endif #if defined(__linux__) || defined(__GLIBC__) || (defined(SYSV) && (defined(CRAY) || defined(macII) || defined(__hpux) || defined(__osf__) || defined(__sgi))) || !(defined(SYSV) || defined(__QNX__) || defined(__INTERIX)) #define HAVE_INITGROUPS #endif #if defined(__linux__) #define HAVE_PTY_H #endif #if !defined(USG) && !defined(__minix) #define HAVE_SETITIMER 1 #else #define HAVE_SETITIMER 0 #endif #if defined(_POSIX_VERSION) || defined(SVR4) || defined(__convex__) || defined(__SCO__) || defined(__QNX__) #define HAVE_SETSID 1 #endif #endif /* HAVE_CONFIG_H */ #ifndef HAVE_X11_DECKEYSYM_H #define HAVE_X11_DECKEYSYM_H 1 #endif #ifndef HAVE_X11_SUNKEYSYM_H #define HAVE_X11_SUNKEYSYM_H 1 #endif #ifndef HAVE_X11_XF86KEYSYM_H #define HAVE_X11_XF86KEYSYM_H 0 #endif #if defined(HAVE_X11_EXTENSIONS_XDBE_H) && defined(HAVE_XDBESWAPBUFFERS) #define USE_DOUBLE_BUFFER 1 #else #define USE_DOUBLE_BUFFER 0 #endif /***====================================================================***/ /* if compiling with gcc -ansi -pedantic, we must fix POSIX definitions */ #if defined(SVR4) && defined(sun) #ifndef __EXTENSIONS__ #define __EXTENSIONS__ 1 #endif #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 1 #endif #endif /***====================================================================***/ #ifdef HAVE_STDLIB_H #include #else extern char *calloc(); extern char *getenv(); extern char *malloc(); extern char *realloc(); extern void exit(); extern void free(); #endif #ifdef HAVE_UNISTD_H #include #undef HAVE_UNISTD_H #endif #ifdef HAVE_SYS_WAIT_H #include #endif #include #if defined(DECL_ERRNO) && !defined(errno) extern int errno; #endif #include #ifdef HAVE_STDNORETURN_H #include #undef GCC_NORETURN #define GCC_NORETURN STDC_NORETURN #endif /* * FIXME: Toggling logging from xterm hangs under Linux 2.0.29 with libc5 if * we use 'waitpid()', while 'wait()' seems to work properly. */ #ifdef __linux__ #undef HAVE_WAITPID #endif #ifndef OPT_WIDE_CHARS #define OPT_WIDE_CHARS 0 #endif #if OPT_WIDE_CHARS #define HIDDEN_CHAR 0xffff #endif /***====================================================================***/ #define PROTO_XT_ACTIONS_ARGS \ (Widget w, XEvent *event, String *params, Cardinal *num_params) #define PROTO_XT_CALLBACK_ARGS \ (Widget gw, XtPointer closure, XtPointer data) #define PROTO_XT_CVT_SELECT_ARGS \ (Widget w, Atom *selection, Atom *target, Atom *type, XtPointer *value, unsigned long *length, int *format) #define PROTO_XT_EV_HANDLER_ARGS \ (Widget w, XtPointer closure, XEvent *event, Boolean *cont) #define PROTO_XT_SEL_CB_ARGS \ (Widget w, XtPointer client_data, Atom *selection, Atom *type, XtPointer value, unsigned long *length, int *format) #include /***====================================================================***/ #ifndef GCC_PRINTFLIKE #ifdef _X_ATTRIBUTE_PRINTF #define GCC_PRINTFLIKE(f,n) _X_ATTRIBUTE_PRINTF(f,n) #else #define GCC_PRINTFLIKE(f,n) /* nothing */ #endif #endif #ifndef GCC_UNUSED #ifdef _X_UNUSED #define GCC_UNUSED _X_UNUSED #else #define GCC_UNUSED /* nothing */ #endif #endif #ifndef GCC_NORETURN #ifdef _X_NORETURN #define GCC_NORETURN _X_NORETURN #else #define GCC_NORETURN /* nothing */ #endif #endif /***====================================================================***/ #if defined(__GNUC__) && defined(_FORTIFY_SOURCE) #define USE_IGNORE_RC #define IGNORE_RC(func) ignore_unused = (int) func #else #define IGNORE_RC(func) (void) func #endif /* gcc workarounds */ #if (XtSpecificationRelease >= 6) && !defined(NO_XPOLL_H) && !defined(sun) #include #define USE_XPOLL_H 1 #else #define Select(n,r,w,e,t) select(n,(fd_set*)r,(fd_set*)w,(fd_set*)e,(struct timeval *)t) #define XFD_COPYSET(src,dst) memcpy((dst)->fds_bits, (src)->fds_bits, sizeof(fd_set)) #endif #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif /* these may be needed for sig_atomic_t */ #include #include #ifdef USE_SYS_SELECT_H #if defined(USE_XPOLL_H) && defined(AIXV3) && defined(NFDBITS) #undef NFDBITS /* conflict between X11/Xpoll.h and sys/select.h */ #endif #include #endif /* USE_SYS_SELECT_H */ #include #if !(defined(__linux__) && defined(__USE_GNU)) && !defined(__hpux) && !defined(_ALL_SOURCE) && !defined(__osf__) extern char **environ; #endif #ifndef _Xconst #define _Xconst const /* Solaris 7 workaround */ #endif /* _Xconst */ #define XK_Fn(n) (XK_F1 + (n) - 1) #define Maybe 2 #define ALLOC_STRING(name) \ if (name != NULL) \ name = x_strdup(name) #define FREE_STRING(name) \ free_string(name) /* strftime format and length of the result */ #define FMT_TIMESTAMP ".%Y.%m.%d.%H.%M.%S" #define LEN_TIMESTAMP sizeof(".YYYY.MM.DD.hh.mm.ss") /***====================================================================***/ #if OPT_TRACE #undef NDEBUG /* turn on assert's */ #else #ifndef NDEBUG #define NDEBUG /* not debugging, don't do assert's */ #endif #endif #include #if OPT_TRACE && !defined(DEBUG) #define DEBUG 1 #endif #ifdef DEBUG #define if_DEBUG(code) if(debug) code #else #define if_DEBUG(code) /*nothing*/ #endif #define DEBUG_MSG(text) if_DEBUG({ IGNORE_RC(write(2, text, sizeof(text) - 1)); }) /***====================================================================***/ #define XtNactiveIcon "activeIcon" #define XtNallowBoldFonts "allowBoldFonts" #define XtNallowC1Printable "allowC1Printable" #define XtNallowColorOps "allowColorOps" #define XtNallowFontOps "allowFontOps" #define XtNallowMouseOps "allowMouseOps" #define XtNallowPasteControls "allowPasteControls" #define XtNallowScrollLock "allowScrollLock" #define XtNallowSendEvents "allowSendEvents" #define XtNallowTcapOps "allowTcapOps" #define XtNallowTitleOps "allowTitleOps" #define XtNallowWindowOps "allowWindowOps" #define XtNaltIsNotMeta "altIsNotMeta" #define XtNaltSendsEscape "altSendsEscape" #define XtNalternateScroll "alternateScroll" #define XtNalwaysBoldMode "alwaysBoldMode" #define XtNalwaysHighlight "alwaysHighlight" #define XtNalwaysUseMods "alwaysUseMods" #define XtNanswerbackString "answerbackString" #define XtNappcursorDefault "appcursorDefault" #define XtNappkeypadDefault "appkeypadDefault" #define XtNassumeAllChars "assumeAllChars" #define XtNautoScrollLock "autoScrollLock" #define XtNautoWrap "autoWrap" #define XtNawaitInput "awaitInput" #define XtNbackarrowKey "backarrowKey" #define XtNbackarrowKeyIsErase "backarrowKeyIsErase" #define XtNbellIsUrgent "bellIsUrgent" #define XtNbellOnReset "bellOnReset" #define XtNbellSuppressTime "bellSuppressTime" #define XtNboldColors "boldColors" #define XtNboldFont "boldFont" #define XtNboldMode "boldMode" #define XtNbrokenLinuxOSC "brokenLinuxOSC" #define XtNbrokenSelections "brokenSelections" #define XtNbrokenStringTerm "brokenStringTerm" #define XtNbuffered "buffered" #define XtNbufferedFPS "bufferedFPS" #define XtNc132 "c132" #define XtNcacheDoublesize "cacheDoublesize" #define XtNcdXtraScroll "cdXtraScroll" #define XtNcharClass "charClass" #define XtNchecksumExtension "checksumExtension" #define XtNcjkWidth "cjkWidth" #define XtNcolorAttrMode "colorAttrMode" #define XtNcolorBDMode "colorBDMode" #define XtNcolorBLMode "colorBLMode" #define XtNcolorEvents "colorEvents" #define XtNcolorITMode "colorITMode" #define XtNcolorInnerBorder "colorInnerBorder" #define XtNcolorMode "colorMode" #define XtNcolorRVMode "colorRVMode" #define XtNcolorULMode "colorULMode" #define XtNcombiningChars "combiningChars" #define XtNctrlFKeys "ctrlFKeys" #define XtNcurses "curses" #define XtNcursorBar "cursorBar" #define XtNcursorBlink "cursorBlink" #define XtNcursorBlinkXOR "cursorBlinkXOR" #define XtNcursorColor "cursorColor" #define XtNcursorOffTime "cursorOffTime" #define XtNcursorOnTime "cursorOnTime" #define XtNcursorTheme "cursorTheme" #define XtNcursorUnderLine "cursorUnderLine" #define XtNcutNewline "cutNewline" #define XtNcutToBeginningOfLine "cutToBeginningOfLine" #define XtNdecGraphicsID "decGraphicsID" #define XtNdecTerminalID "decTerminalID" #define XtNdefaultString "defaultString" #define XtNdeleteIsDEL "deleteIsDEL" #define XtNdirectColor "directColor" #define XtNdisallowedColorOps "disallowedColorOps" #define XtNdisallowedFontOps "disallowedFontOps" #define XtNdisallowedMouseOps "disallowedMouseOps" #define XtNdisallowedPasteControls "disallowedPasteControls" #define XtNdisallowedTcapOps "disallowedTcapOps" #define XtNdisallowedWindowOps "disallowedWindowOps" #define XtNdynamicColors "dynamicColors" #define XtNeightBitControl "eightBitControl" #define XtNeightBitInput "eightBitInput" #define XtNeightBitMeta "eightBitMeta" #define XtNeightBitOutput "eightBitOutput" #define XtNeightBitSelectTypes "eightBitSelectTypes" #define XtNeraseSavedLines "eraseSavedLines" #define XtNfaceName "faceName" #define XtNfaceNameDoublesize "faceNameDoublesize" #define XtNfaceSize "faceSize" #define XtNfaintIsRelative "faintIsRelative" #define XtNfastScroll "fastScroll" #define XtNfont1 "font1" #define XtNfont2 "font2" #define XtNfont3 "font3" #define XtNfont4 "font4" #define XtNfont5 "font5" #define XtNfont6 "font6" #define XtNfont7 "font7" #define XtNfontDoublesize "fontDoublesize" #define XtNfontWarnings "fontWarnings" #define XtNforceBoxChars "forceBoxChars" #define XtNforcePackedFont "forcePackedFont" #define XtNforceXftHeight "forceXftHeight" #define XtNformatCursorKeys "formatCursorKeys" #define XtNformatFunctionKeys "formatFunctionKeys" #define XtNformatKeypadKeys "formatKeypadKeys" #define XtNformatModifierKeys "formatModifierKeys" #define XtNformatOtherKeys "formatOtherKeys" #define XtNformatSpecialKeys "formatSpecialKeys" #define XtNformatStringKeys "formatStringKeys" #define XtNfreeBoldBox "freeBoldBox" #define XtNfullscreen "fullscreen" #define XtNhighlightColor "highlightColor" #define XtNhighlightColorMode "highlightColorMode" #define XtNhighlightReverse "highlightReverse" #define XtNhighlightSelection "highlightSelection" #define XtNhighlightTextColor "highlightTextColor" #define XtNhold "hold" #define XtNhpFunctionKeys "hpFunctionKeys" #define XtNhpLowerleftBugCompat "hpLowerleftBugCompat" #define XtNi18nSelections "i18nSelections" #define XtNiconBorderColor "iconBorderColor" #define XtNiconBorderWidth "iconBorderWidth" #define XtNiconFont "iconFont" #define XtNiconGeometry "iconGeometry" #define XtNiconHint "iconHint" #define XtNincrementalGraphics "incrementalGraphics" #define XtNindicatorFormat "indicatorFormat" #define XtNinitialFont "initialFont" #define XtNinternalBorder "internalBorder" #define XtNitalicULMode "italicULMode" #define XtNjumpScroll "jumpScroll" #define XtNkeepClipboard "keepClipboard" #define XtNkeepSelection "keepSelection" #define XtNkeyboardDialect "keyboardDialect" #define XtNkeyboardType "keyboardType" #define XtNlimitFontHeight "limitFontHeight" #define XtNlimitFontWidth "limitFontWidth" #define XtNlimitFontsets "limitFontsets" #define XtNlimitResize "limitResize" #define XtNlimitResponse "limitResponse" #define XtNlocale "locale" #define XtNlocaleFilter "localeFilter" #define XtNlogFile "logFile" #define XtNlogInhibit "logInhibit" #define XtNlogging "logging" #define XtNloginShell "loginShell" #define XtNmarginBell "marginBell" #define XtNmaxBufSize "maxBufSize" #define XtNmaxGraphicSize "maxGraphicSize" #define XtNmaxStringParse "maxStringParse" #define XtNmaximized "maximized" #define XtNmenuBar "menuBar" /* internal */ #define XtNmenuHeight "menuHeight" #define XtNmenuLocale "menuLocale" #define XtNmessages "messages" #define XtNmetaSendsEscape "metaSendsEscape" #define XtNminBufSize "minBufSize" #define XtNmkSamplePass "mkSamplePass" #define XtNmkSampleSize "mkSampleSize" #define XtNmkWidth "mkWidth" #define XtNmodifyCursorKeys "modifyCursorKeys" #define XtNmodifyFunctionKeys "modifyFunctionKeys" #define XtNmodifyKeyboard "modifyKeyboard" #define XtNmodifyKeypadKeys "modifyKeypadKeys" #define XtNmodifyModifierKeys "modifyModifierKeys" #define XtNmodifyOtherKeys "modifyOtherKeys" #define XtNmodifySpecialKeys "modifySpecialKeys" #define XtNmodifyStringKeys "modifyStringKeys" #define XtNmultiClickTime "multiClickTime" #define XtNmultiScroll "multiScroll" #define XtNnMarginBell "nMarginBell" #define XtNnextEventDelay "nextEventDelay" #define XtNnotMapped "notMapped" #define XtNnumColorRegisters "numColorRegisters" #define XtNnumLock "numLock" #define XtNoldXtermFKeys "oldXtermFKeys" #define XtNomitTranslation "omitTranslation" #define XtNpointerColor "pointerColor" #define XtNpointerColorBackground "pointerColorBackground" #define XtNpointerFont "pointerFont" #define XtNpointerMode "pointerMode" #define XtNpointerShape "pointerShape" #define XtNpopOnBell "popOnBell" #define XtNprecompose "precompose" #define XtNpreferLatin1 "preferLatin1" #define XtNprintAttributes "printAttributes" #define XtNprintFileImmediate "printFileImmediate" #define XtNprintFileOnXError "printFileOnXError" #define XtNprintModeImmediate "printModeImmediate" #define XtNprintModeOnXError "printModeOnXError" #define XtNprintOptsImmediate "printOptsImmediate" #define XtNprintOptsOnXError "printOptsOnXError" #define XtNprintRawChars "printRawChars" #define XtNprinterAutoClose "printerAutoClose" #define XtNprinterCommand "printerCommand" #define XtNprinterControlMode "printerControlMode" #define XtNprinterExtent "printerExtent" #define XtNprinterFormFeed "printerFormFeed" #define XtNprinterNewLine "printerNewLine" #define XtNprivateColorRegisters "privateColorRegisters" #define XtNptyHandshake "ptyHandshake" #define XtNptyInitialErase "ptyInitialErase" #define XtNptySttySize "ptySttySize" #define XtNquietGrab "quietGrab" #define XtNregisDefaultFont "regisDefaultFont" #define XtNregisScreenSize "regisScreenSize" #define XtNrenderFont "renderFont" #define XtNreportCClass "reportCClass" #define XtNreportColors "reportColors" #define XtNreportFonts "reportFonts" #define XtNreportIcons "reportIcons" #define XtNreportXRes "reportXRes" #define XtNresizeByPixel "resizeByPixel" #define XtNresizeGravity "resizeGravity" #define XtNretryInputMethod "retryInputMethod" #define XtNreverseWrap "reverseWrap" #define XtNrightScrollBar "rightScrollBar" #define XtNsameName "sameName" #define XtNsaveLines "saveLines" #define XtNscaleHeight "scaleHeight" #define XtNscoFunctionKeys "scoFunctionKeys" #define XtNscrollBar "scrollBar" #define XtNscrollBarBorder "scrollBarBorder" #define XtNscrollKey "scrollKey" #define XtNscrollLines "scrollLines" #define XtNscrollTtyOutput "scrollTtyOutput" #define XtNselectToClipboard "selectToClipboard" #define XtNsessionMgt "sessionMgt" #define XtNshiftEscape "shiftEscape" #define XtNshiftFonts "shiftFonts" #define XtNshowBlinkAsBold "showBlinkAsBold" #define XtNshowMissingGlyphs "showMissingGlyphs" #define XtNshowWrapMarks "showWrapMarks" #define XtNsignalInhibit "signalInhibit" #define XtNsixelScrolling "sixelScrolling" #define XtNsixelScrollsRight "sixelScrollsRight" #define XtNsunFunctionKeys "sunFunctionKeys" #define XtNsunKeyboard "sunKeyboard" #define XtNtcapFunctionKeys "tcapFunctionKeys" #define XtNtekGeometry "tekGeometry" #define XtNtekInhibit "tekInhibit" #define XtNtekSmall "tekSmall" #define XtNtekStartup "tekStartup" #define XtNtermName "termName" #define XtNtiXtraScroll "tiXtraScroll" #define XtNtiteInhibit "titeInhibit" #define XtNtitleModes "titleModes" #define XtNtoolBar "toolBar" #define XtNtrimSelection "trimSelection" #define XtNttyModes "ttyModes" #define XtNunderLine "underLine" #define XtNuseBorderClipping "useBorderClipping" #define XtNuseClipping "useClipping" #define XtNuseInsertMode "useInsertMode" #define XtNutf8 "utf8" #define XtNutf8Fonts "utf8Fonts" #define XtNutf8Latin1 "utf8Latin1" #define XtNutf8SelectTypes "utf8SelectTypes" #define XtNutf8Title "utf8Title" #define XtNutf8Weblike "utf8Weblike" #define XtNutmpDisplayId "utmpDisplayId" #define XtNutmpInhibit "utmpInhibit" #define XtNvalidShells "validShells" #define XtNveryBoldColors "veryBoldColors" #define XtNvisualBell "visualBell" #define XtNvisualBellDelay "visualBellDelay" #define XtNvisualBellLine "visualBellLine" #define XtNvt100Graphics "vt100Graphics" #define XtNwaitForMap "waitForMap" #define XtNwideBoldFont "wideBoldFont" #define XtNwideChars "wideChars" #define XtNwideFont "wideFont" #define XtNxftMaxGlyphMemory "xftMaxGlyphMemory" #define XtNxftMaxUnrefFonts "xftMaxUnrefFonts" #define XtNxftTrackMemUsage "xftTrackMemUsage" #define XtNximFont "ximFont" #define XtNxmcAttributes "xmcAttributes" /* ncurses-testing */ #define XtNxmcGlitch "xmcGlitch" /* ncurses-testing */ #define XtNxmcInline "xmcInline" /* ncurses-testing */ #define XtNxmcMoveSGR "xmcMoveSGR" /* ncurses-testing */ #define XtNzIconBeep "zIconBeep" #define XtNzIconTitleFormat "zIconTitleFormat" #define XtCActiveIcon "ActiveIcon" #define XtCAllowBoldFonts "AllowBoldFonts" #define XtCAllowC1Printable "AllowC1Printable" #define XtCAllowColorOps "AllowColorOps" #define XtCAllowFontOps "AllowFontOps" #define XtCAllowMouseOps "AllowMouseOps" #define XtCAllowPasteControls "AllowPasteControls" #define XtCAllowScrollLock "AllowScrollLock" #define XtCAllowSendEvents "AllowSendEvents" #define XtCAllowTcapOps "AllowTcapOps" #define XtCAllowTitleOps "AllowTitleOps" #define XtCAllowWindowOps "AllowWindowOps" #define XtCAltIsNotMeta "AltIsNotMeta" #define XtCAltSendsEscape "AltSendsEscape" #define XtCAlwaysBoldMode "AlwaysBoldMode" #define XtCAlwaysHighlight "AlwaysHighlight" #define XtCAlwaysUseMods "AlwaysUseMods" #define XtCAnswerbackString "AnswerbackString" #define XtCAppcursorDefault "AppcursorDefault" #define XtCAppkeypadDefault "AppkeypadDefault" #define XtCAssumeAllChars "AssumeAllChars" #define XtCAutoScrollLock "AutoScrollLock" #define XtCAutoWrap "AutoWrap" #define XtCAwaitInput "AwaitInput" #define XtCBackarrowKey "BackarrowKey" #define XtCBackarrowKeyIsErase "BackarrowKeyIsErase" #define XtCBellIsUrgent "BellIsUrgent" #define XtCBellOnReset "BellOnReset" #define XtCBellSuppressTime "BellSuppressTime" #define XtCBoldFont "BoldFont" #define XtCBoldMode "BoldMode" #define XtCBrokenLinuxOSC "BrokenLinuxOSC" #define XtCBrokenSelections "BrokenSelections" #define XtCBrokenStringTerm "BrokenStringTerm" #define XtCBuffered "Buffered" #define XtCBufferedFPS "BufferedFPS" #define XtCC132 "C132" #define XtCCacheDoublesize "CacheDoublesize" #define XtCCdXtraScroll "CdXtraScroll" #define XtCCharClass "CharClass" #define XtCChecksumExtension "ChecksumExtension" #define XtCCjkWidth "CjkWidth" #define XtCColorAttrMode "ColorAttrMode" #define XtCColorEvents "ColorEvents" #define XtCColorInnerBorder "ColorInnerBorder" #define XtCColorMode "ColorMode" #define XtCColumn "Column" #define XtCCombiningChars "CombiningChars" #define XtCCtrlFKeys "CtrlFKeys" #define XtCCurses "Curses" #define XtCCursorBar "CursorBar" #define XtCCursorBlink "CursorBlink" #define XtCCursorBlinkXOR "CursorBlinkXOR" #define XtCCursorOffTime "CursorOffTime" #define XtCCursorOnTime "CursorOnTime" #define XtCCursorTheme "CursorTheme" #define XtCCursorUnderLine "CursorUnderLine" #define XtCCutNewline "CutNewline" #define XtCCutToBeginningOfLine "CutToBeginningOfLine" #define XtCDecGraphicsID "DecGraphicsID" #define XtCDecTerminalID "DecTerminalID" #define XtCDefaultString "DefaultString" #define XtCDeleteIsDEL "DeleteIsDEL" #define XtCDirectColor "DirectColor" #define XtCDisallowedColorOps "DisallowedColorOps" #define XtCDisallowedFontOps "DisallowedFontOps" #define XtCDisallowedMouseOps "DisallowedMouseOps" #define XtCDisallowedPasteControls "DisallowedPasteControls" #define XtCDisallowedTcapOps "DisallowedTcapOps" #define XtCDisallowedWindowOps "DisallowedWindowOps" #define XtCDynamicColors "DynamicColors" #define XtCEightBitControl "EightBitControl" #define XtCEightBitInput "EightBitInput" #define XtCEightBitMeta "EightBitMeta" #define XtCEightBitOutput "EightBitOutput" #define XtCEightBitSelectTypes "EightBitSelectTypes" #define XtCEraseSavedLines "EraseSavedLines" #define XtCFaceName "FaceName" #define XtCFaceNameDoublesize "FaceNameDoublesize" #define XtCFaceSize "FaceSize" #define XtCFaintIsRelative "FaintIsRelative" #define XtCFastScroll "FastScroll" #define XtCFont1 "Font1" #define XtCFont2 "Font2" #define XtCFont3 "Font3" #define XtCFont4 "Font4" #define XtCFont5 "Font5" #define XtCFont6 "Font6" #define XtCFont7 "Font7" #define XtCFontDoublesize "FontDoublesize" #define XtCFontWarnings "FontWarnings" #define XtCForceBoxChars "ForceBoxChars" #define XtCForcePackedFont "ForcePackedFont" #define XtCForceXftHeight "ForceXftHeight" #define XtCFormatCursorKeys "FormatCursorKeys" #define XtCFormatFunctionKeys "FormatFunctionKeys" #define XtCFormatKeypadKeys "FormatKeypadKeys" #define XtCFormatModifierKeys "FormatModifierKeys" #define XtCFormatOtherKeys "FormatOtherKeys" #define XtCFormatSpecialKeys "FormatSpecialKeys" #define XtCFormatStringKeys "FormatStringKeys" #define XtCFreeBoldBox "FreeBoldBox" #define XtCFullscreen "Fullscreen" #define XtCHighlightColorMode "HighlightColorMode" #define XtCHighlightReverse "HighlightReverse" #define XtCHighlightSelection "HighlightSelection" #define XtCHold "Hold" #define XtCHpFunctionKeys "HpFunctionKeys" #define XtCHpLowerleftBugCompat "HpLowerleftBugCompat" #define XtCI18nSelections "I18nSelections" #define XtCIconFont "IconFont" #define XtCIconGeometry "IconGeometry" #define XtCIconHint "IconHint" #define XtCIncrementalGraphics "IncrementalGraphics" #define XtCIndicatorFormat "IndicatorFormat" #define XtCInitialFont "InitialFont" #define XtCInternalBorder "InternalBorder" #define XtCJumpScroll "JumpScroll" #define XtCKeepClipboard "KeepClipboard" #define XtCKeepSelection "KeepSelection" #define XtCKeyboardDialect "KeyboardDialect" #define XtCKeyboardType "KeyboardType" #define XtCLimitFontHeight "LimitFontHeight" #define XtCLimitFontWidth "LimitFontWidth" #define XtCLimitFontsets "LimitFontsets" #define XtCLimitResize "LimitResize" #define XtCLimitResponse "LimitResponse" #define XtCLocale "Locale" #define XtCLocaleFilter "LocaleFilter" #define XtCLogInhibit "LogInhibit" #define XtCLogfile "Logfile" #define XtCLogging "Logging" #define XtCLoginShell "LoginShell" #define XtCMarginBell "MarginBell" #define XtCMaxBufSize "MaxBufSize" #define XtCMaxGraphicSize "MaxGraphicSize" #define XtCMaxStringParse "MaxStringParse" #define XtCMaximized "Maximized" #define XtCMenuBar "MenuBar" /* internal */ #define XtCMenuHeight "MenuHeight" #define XtCMenuLocale "MenuLocale" #define XtCMessages "Messages" #define XtCMetaSendsEscape "MetaSendsEscape" #define XtCMinBufSize "MinBufSize" #define XtCMkSamplePass "MkSamplePass" #define XtCMkSampleSize "MkSampleSize" #define XtCMkWidth "MkWidth" #define XtCModifyCursorKeys "ModifyCursorKeys" #define XtCModifyFunctionKeys "ModifyFunctionKeys" #define XtCModifyKeyboard "ModifyKeyboard" #define XtCModifyKeypadKeys "ModifyKeypadKeys" #define XtCModifyModifierKeys "ModifyModifierKeys" #define XtCModifyOtherKeys "ModifyOtherKeys" #define XtCModifySpecialKeys "ModifySpecialKeys" #define XtCModifyStringKeys "ModifyStringKeys" #define XtCMultiClickTime "MultiClickTime" #define XtCMultiScroll "MultiScroll" #define XtCNextEventDelay "NextEventDelay" #define XtCNotMapped "NotMapped" #define XtCNumColorRegisters "NumColorRegisters" #define XtCNumLock "NumLock" #define XtCOldXtermFKeys "OldXtermFKeys" #define XtCOmitTranslation "OmitTranslation" #define XtCPointerFont "PointerFont" #define XtCPointerMode "PointerMode" #define XtCPopOnBell "PopOnBell" #define XtCPrecompose "Precompose" #define XtCPreferLatin1 "PreferLatin1" #define XtCPrintAttributes "PrintAttributes" #define XtCPrintFileImmediate "PrintFileImmediate" #define XtCPrintFileOnXError "PrintFileOnXError" #define XtCPrintModeImmediate "PrintModeImmediate" #define XtCPrintModeOnXError "PrintModeOnXError" #define XtCPrintOptsImmediate "PrintOptsImmediate" #define XtCPrintOptsOnXError "PrintOptsOnXError" #define XtCPrintRawChars "PrintRawChars" #define XtCPrinterAutoClose "PrinterAutoClose" #define XtCPrinterCommand "PrinterCommand" #define XtCPrinterControlMode "PrinterControlMode" #define XtCPrinterExtent "PrinterExtent" #define XtCPrinterFormFeed "PrinterFormFeed" #define XtCPrinterNewLine "PrinterNewLine" #define XtCPrivateColorRegisters "PrivateColorRegisters" #define XtCPtyHandshake "PtyHandshake" #define XtCPtyInitialErase "PtyInitialErase" #define XtCPtySttySize "PtySttySize" #define XtCQuietGrab "QuietGrab" #define XtCRegisDefaultFont "RegisDefaultFont" #define XtCRegisScreenSize "RegisScreenSize" #define XtCRenderFont "RenderFont" #define XtCReportCClass "ReportCClass" #define XtCReportColors "ReportColors" #define XtCReportFonts "ReportFonts" #define XtCReportIcons "ReportIcons" #define XtCReportXRes "ReportXRes" #define XtCResizeByPixel "ResizeByPixel" #define XtCResizeGravity "ResizeGravity" #define XtCRetryInputMethod "RetryInputMethod" #define XtCReverseWrap "ReverseWrap" #define XtCRightScrollBar "RightScrollBar" #define XtCSameName "SameName" #define XtCSaveLines "SaveLines" #define XtCScaleHeight "ScaleHeight" #define XtCScoFunctionKeys "ScoFunctionKeys" #define XtCScrollBar "ScrollBar" #define XtCScrollBarBorder "ScrollBarBorder" #define XtCScrollCond "ScrollCond" #define XtCScrollLines "ScrollLines" #define XtCSelectToClipboard "SelectToClipboard" #define XtCSessionMgt "SessionMgt" #define XtCShiftEscape "ShiftEscape" #define XtCShiftFonts "ShiftFonts" #define XtCShowBlinkAsBold "ShowBlinkAsBold" #define XtCShowMissingGlyphs "ShowMissingGlyphs" #define XtCShowWrapMarks "ShowWrapMarks" #define XtCSignalInhibit "SignalInhibit" #define XtCSixelScrolling "SixelScrolling" #define XtCSixelScrollsRight "SixelScrollsRight" #define XtCSunFunctionKeys "SunFunctionKeys" #define XtCSunKeyboard "SunKeyboard" #define XtCTcapFunctionKeys "TcapFunctionKeys" #define XtCTekInhibit "TekInhibit" #define XtCTekSmall "TekSmall" #define XtCTekStartup "TekStartup" #define XtCTermName "TermName" #define XtCTiXtraScroll "TiXtraScroll" #define XtCTiteInhibit "TiteInhibit" #define XtCTitleModes "TitleModes" #define XtCToolBar "ToolBar" #define XtCTrimSelection "TrimSelection" #define XtCTtyModes "TtyModes" #define XtCUnderLine "UnderLine" #define XtCUseBorderClipping "UseBorderClipping" #define XtCUseClipping "UseClipping" #define XtCUseInsertMode "UseInsertMode" #define XtCUtf8 "Utf8" #define XtCUtf8Fonts "Utf8Fonts" #define XtCUtf8Latin1 "Utf8Latin1" #define XtCUtf8SelectTypes "Utf8SelectTypes" #define XtCUtf8Title "Utf8Title" #define XtCUtf8Weblike "Utf8Weblike" #define XtCUtmpDisplayId "UtmpDisplayId" #define XtCUtmpInhibit "UtmpInhibit" #define XtCVT100Graphics "VT100Graphics" #define XtCValidShells "ValidShells" #define XtCVeryBoldColors "VeryBoldColors" #define XtCVisualBell "VisualBell" #define XtCVisualBellDelay "VisualBellDelay" #define XtCVisualBellLine "VisualBellLine" #define XtCWaitForMap "WaitForMap" #define XtCWideBoldFont "WideBoldFont" #define XtCWideChars "WideChars" #define XtCWideFont "WideFont" #define XtCXftMaxGlyphMemory "XftMaxGlyphMemory" #define XtCXftMaxUnrefFonts "XftMaxUnrefFonts" #define XtCXftTrackMemUsage "XftTrackMemUsage" #define XtCXimFont "XimFont" #define XtCXmcAttributes "XmcAttributes" /* ncurses-testing */ #define XtCXmcGlitch "XmcGlitch" /* ncurses-testing */ #define XtCXmcInline "XmcInline" /* ncurses-testing */ #define XtCXmcMoveSGR "XmcMoveSGR" /* ncurses-testing */ #define XtCZIconBeep "ZIconBeep" #define XtCZIconTitleFormat "ZIconTitleFormat" #if defined(NO_ACTIVE_ICON) && !defined(XtNgeometry) #define XtNgeometry "geometry" #define XtCGeometry "Geometry" #endif #if OPT_COLOR_CLASS #define XtCCursorColor "CursorColor" #define XtCPointerColor "PointerColor" #define XtCHighlightColor "HighlightColor" #define XtCHighlightTextColor "HighlightTextColor" #else #define XtCCursorColor XtCForeground #define XtCPointerColor XtCForeground #define XtCHighlightColor XtCForeground #define XtCHighlightTextColor XtCBackground #endif /***====================================================================***/ #ifdef __cplusplus extern "C" { #endif struct XTERM_RESOURCE; /* Tekproc.c */ #if OPT_TEK4014 extern TekWidget getTekWidget(Widget /* w */); extern int TekGetFontSize (const char * /* param */); extern int TekInit (void); extern void ChangeTekColors (TekWidget /* tw */, TScreen * /* screen */, ScrnColors * /* pNew */); extern void HandleGINInput PROTO_XT_ACTIONS_ARGS; extern void TCursorToggle (TekWidget /* tw */, int /* toggle */); extern void TekCopy (TekWidget /* tw */); extern void TekEnqMouse (TekWidget /* tw */, int /* c */); extern void TekExpose (Widget /* w */, XEvent * /* event */, Region /* region */); extern void TekGINoff (TekWidget /* tw */); extern void TekRefresh (TekWidget /* tw */); extern void TekRepaint (TekWidget /* xw */); extern void TekReverseVideo (XtermWidget /* xw */, TekWidget /* tw */); extern void TekRun (void); extern void TekSetFontSize (TekWidget /* tw */, Bool /* fromMenu */, int /* newitem */); extern void TekSetWinSize (TekWidget /* tw */); extern void TekSimulatePageButton (TekWidget /* tw */, Bool /* reset */); #endif /* button.c */ #define MotionOff( s, t ) if (!(screen->hide_pointer)) { \ (s)->event_mask |= ButtonMotionMask; \ (s)->event_mask &= ~PointerMotionMask; \ XSelectInput(XtDisplay((t)), XtWindow((t)), (long) (s)->event_mask); } #define MotionOn( s, t ) { \ (s)->event_mask &= ~ButtonMotionMask; \ (s)->event_mask |= PointerMotionMask; \ XSelectInput(XtDisplay((t)), XtWindow((t)), (long) (s)->event_mask); } extern Bool SendMousePosition (XtermWidget /* w */, XEvent* /* event */); extern XtermMouseModes okSendMousePos(XtermWidget /* xw */); extern void DiredButton PROTO_XT_ACTIONS_ARGS; extern void DisownSelection (XtermWidget /* xw */); extern void UnhiliteSelection (XtermWidget /* xw */); extern void HandleCopySelection PROTO_XT_ACTIONS_ARGS; extern void HandleInsertSelection PROTO_XT_ACTIONS_ARGS; extern void HandleKeyboardSelectEnd PROTO_XT_ACTIONS_ARGS; extern void HandleKeyboardSelectExtend PROTO_XT_ACTIONS_ARGS; extern void HandleKeyboardSelectStart PROTO_XT_ACTIONS_ARGS; extern void HandleKeyboardStartExtend PROTO_XT_ACTIONS_ARGS; extern void HandlePointerMotion PROTO_XT_ACTIONS_ARGS; extern void HandlePointerButton PROTO_XT_ACTIONS_ARGS; extern void HandleSelectEnd PROTO_XT_ACTIONS_ARGS; extern void HandleSelectExtend PROTO_XT_ACTIONS_ARGS; extern void HandleSelectSet PROTO_XT_ACTIONS_ARGS; extern void HandleSelectStart PROTO_XT_ACTIONS_ARGS; extern void HandleStartExtend PROTO_XT_ACTIONS_ARGS; extern void ResizeSelection (TScreen * /* screen */, int /* rows */, int /* cols */); extern void ScrollSelection (TScreen * /* screen */, int /* amount */, Bool /* always */); extern void TrackMouse (XtermWidget /* xw */, int /* func */, const CELL * /* start */, int /* firstrow */, int /* lastrow */); extern void ViButton PROTO_XT_ACTIONS_ARGS; extern void UnmapSelections (XtermWidget /* xw */); extern int xtermUtf8ToTextList (XtermWidget /* xw */, XTextProperty * /* text_prop */, char *** /* text_list */, int * /* text_list_count */); extern void xtermButtonInit (XtermWidget /* xw */); #if OPT_DEC_LOCATOR extern void GetLocatorPosition (XtermWidget /* w */); extern void InitLocatorFilter (XtermWidget /* w */); #endif /* OPT_DEC_LOCATOR */ #if OPT_FOCUS_EVENT extern void SendFocusButton(XtermWidget /* xw */, XFocusChangeEvent * /* event */); #else #define SendFocusBotton(xw, event) /* nothing */ #endif #if OPT_PASTE64 extern void AppendToSelectionBuffer (TScreen * /* screen */, unsigned /* c */, String /* selection */); extern void ClearSelectionBuffer (TScreen * /* screen */, String /* selection */); extern void CompleteSelection (XtermWidget /* xw */, String * /* args */, Cardinal /* len */); extern void xtermGetSelection (Widget /* w */, Time /* ev_time */, String * /* params */, Cardinal /* num_params */, Atom * /* targets */); #endif #if OPT_READLINE extern void ReadLineButton PROTO_XT_ACTIONS_ARGS; #endif #if OPT_REPORT_CCLASS extern void report_char_class(XtermWidget); #endif #define IsAscii1(n) (((n) >= 32 && (n) <= 126)) #if OPT_WIDE_CHARS #define WideCells(n) (((IChar)(n) >= first_widechar) ? my_wcwidth((wchar_t) (n)) : 1) #define isWideFrg(n) (((n) == HIDDEN_CHAR) || (WideCells((n)) == 2)) #define isWide(n) (((IChar)(n) >= first_widechar) && isWideFrg(n)) #define CharWidth(screen, n) (((n) < 256) \ ? (IsLatin1(n) ? 1 : 0) \ : my_wcwidth((wchar_t) (n))) #define IsLatin1(n) (IsAscii1(n) || ((n) >= 160 && (n) <= 255)) #else #define WideCells(n) 1 #define CharWidth(screen, n) (IsLatin1(n) ? 1 : 0) #define IsLatin1(n) (IsAscii1(n) || ((n) >= 160)) #endif /* cachedCgs.c */ extern CgsEnum getCgsId(XtermWidget /*xw*/, VTwin * /*cgsWin*/, GC /*gc*/); extern GC freeCgs(XtermWidget /*xw*/, VTwin * /*cgsWin*/, CgsEnum /*cgsId*/); extern GC getCgsGC(XtermWidget /*xw*/, VTwin * /*cgsWin*/, CgsEnum /*cgsId*/); extern Pixel getCgsBack(XtermWidget /*xw*/, VTwin * /*cgsWin*/, GC /*gc*/); extern Pixel getCgsFore(XtermWidget /*xw*/, VTwin * /*cgsWin*/, GC /*gc*/); extern XTermFonts * getCgsFont(XtermWidget /*xw*/, VTwin * /*cgsWin*/, GC /*gc*/); extern void clrCgsFonts(XtermWidget /*xw*/, VTwin * /*cgsWin*/, XTermFonts * /*font*/); extern void copyCgs(XtermWidget /*xw*/, VTwin * /*cgsWin*/, CgsEnum /*dstCgsId*/, CgsEnum /*srcCgsId*/); extern void redoCgs(XtermWidget /*xw*/, Pixel /*fg*/, Pixel /*bg*/, CgsEnum /*cgsId*/); extern void setCgsBack(XtermWidget /*xw*/, VTwin * /*cgsWin*/, CgsEnum /*cgsId*/, Pixel /*bg*/); extern void setCgsCSet(XtermWidget /*xw*/, VTwin * /*cgsWin*/, CgsEnum /*cgsId*/, unsigned /*cset*/); extern void setCgsFont(XtermWidget /*xw*/, VTwin * /*cgsWin*/, CgsEnum /*cgsId*/, XTermFonts * /*font*/); extern void setCgsFont2(XtermWidget /*xw*/, VTwin * /*cgsWin*/, CgsEnum /*cgsId*/, XTermFonts * /*font*/, unsigned /*which*/); extern void setCgsFore(XtermWidget /*xw*/, VTwin * /*cgsWin*/, CgsEnum /*cgsId*/, Pixel /*fg*/); extern void setCgsLine(XtermWidget /*xw*/, VTwin * /*cgsWin*/, CgsEnum /*cgsId*/, Pixel /*fg*/); extern void swapCgs(XtermWidget /*xw*/, VTwin * /*cgsWin*/, CgsEnum /*dstCgsId*/, CgsEnum /*srcCgsId*/); #ifdef NO_LEAKS extern void noleaks_cachedCgs (XtermWidget /* xw */); #endif /* charproc.c */ extern Bool CheckBufPtrs (TScreen * /* screen */); extern Bool set_cursor_gcs (XtermWidget /* xw */); extern char * vt100ResourceToString (XtermWidget /* xw */, const char * /* name */); extern int VTInit (XtermWidget /* xw */); extern Bool FindFontSelection (XtermWidget /* xw */, const char * /* atom_name */, Bool /* justprobe */); extern void HideCursor (XtermWidget /* xw */); extern void RestartBlinking(XtermWidget /* xw */); extern void ShowCursor (XtermWidget /* xw */); extern void SwitchBufPtrs (XtermWidget /* xw */, int /* toBuf */); extern void ToggleAlternate (XtermWidget /* xw */); extern void VTInitTranslations (void); extern GCC_NORETURN void VTReset (XtermWidget /* xw */, int /* full */, int /* saved */); extern void VTRun (XtermWidget /* xw */); extern void dotext (XtermWidget /* xw */, DECNRCM_codes /* charset */, IChar * /* buf */, Cardinal /* len */); extern void getKeymapResources(Widget /* w */, const char * /*mapName */, const char * /* mapClass */, const char * /* type */, void * /* result */, size_t /* size */); extern void initBorderGC (XtermWidget /* xw */, VTwin * /* win */); extern void lookupSelectUnit(XtermWidget /* xw */, Cardinal /* item */, String /* value */); extern void releaseCursorGCs(XtermWidget /*xw*/); extern void releaseWindowGCs(XtermWidget /*xw*/, VTwin * /*win*/); extern void resetCharsets (TScreen * /* screen */); extern void resetMargins (XtermWidget /* xw */); extern void restoreCharsets (TScreen * /* screen */, const DECNRCM_codes * /* source */); extern void saveCharsets (TScreen * /* screen */, DECNRCM_codes * /* target */); extern void set_max_col(TScreen * /* screen */, int /* cols */); extern void set_max_row(TScreen * /* screen */, int /* rows */); extern void unparse_disallowed_ops (XtermWidget /* xw */, char * /* value */); extern void unparse_end (XtermWidget /* xw */); extern void unparseputc (XtermWidget /* xw */, int /* c */); extern void unparseputc1 (XtermWidget /* xw */, int /* c */); extern void unparseputn (XtermWidget /* xw */, unsigned /* n */); extern void unparseputs (XtermWidget /* xw */, const char * /* s */); extern void unparseseq (XtermWidget /* xw */, ANSI * /* ap */); extern void v_write (int /* f */, const Char * /* d */, size_t /* len */); extern void xtermAddInput (Widget /* w */); extern void xtermDecodeSCS (XtermWidget /* xw */, int /* which */, int /* sgroup */, int /* prefix */, int /* suffix */); #if OPT_BLINK_CURS extern void ToggleCursorBlink(XtermWidget /* xw */); #endif #if OPT_BLINK_TEXT extern Bool LineHasBlinking(TScreen * /* screen */, CLineData * /* ld */); #endif #if OPT_INPUT_METHOD extern TInput *lookupTInput (XtermWidget /* xw */, Widget /* w */); #endif #if OPT_ISO_COLORS extern void SGR_Background (XtermWidget /* xw */, int /* color */); extern void SGR_Foreground (XtermWidget /* xw */, int /* color */); extern void setExtendedColors (XtermWidget /* xw */); #endif #ifdef NO_LEAKS extern void noleaks_charproc (void); #endif /* charsets.c */ extern unsigned xtermCharSetIn (XtermWidget /* xw */, unsigned /* code */, DECNRCM_codes /* charset */); extern Cardinal xtermCharSetOut (XtermWidget /* xw */, Cardinal /* length */, DECNRCM_codes /* charset */); extern int xtermCharSetDec (XtermWidget /* xw */, IChar /* ch */, DECNRCM_codes /* cs */); /* cursor.c */ extern int CursorCol (XtermWidget /* xw */); extern int CursorRow (XtermWidget /* xw */); extern void AdjustSavedCursor (XtermWidget /* xw */, int /* adjust */); extern void CarriageReturn (XtermWidget /* xw */); extern void CursorBack (XtermWidget /* xw */, int /* n */); extern void CursorDown (TScreen * /* screen */, int /* n */); extern void CursorForward (XtermWidget /* xw */, int /* n */); extern void CursorNextLine (XtermWidget /* xw */, int /* count */); extern void CursorPrevLine (XtermWidget /* xw */, int /* count */); extern void CursorRestore2 (XtermWidget /* xw */, SavedCursor * /* sc */); extern void CursorRestore (XtermWidget /* xw */); extern void CursorSave2 (XtermWidget /* xw */, SavedCursor * /* sc */); extern void CursorSave (XtermWidget /* xw */); extern void CursorSet (TScreen * /* screen */, int /* row */, int /* col */, unsigned /* flags */); extern void CursorUp (TScreen * /* screen */, int /* n */); extern void RevIndex (XtermWidget /* xw */, int /* amount */); extern void xtermIndex (XtermWidget /* xw */, int /* amount */); #if OPT_TRACE extern int set_cur_col(TScreen * /* screen */, int /* value */); extern int set_cur_row(TScreen * /* screen */, int /* value */); #else #define set_cur_col(screen, value) screen->cur_col = value #define set_cur_row(screen, value) \ do { \ int row_value = value; \ if_STATUS_LINE(screen, { \ row_value = LastRowNumber(screen); \ }); \ screen->cur_row = row_value; \ } while (0) #endif /* cursorfont.c */ extern Cursor CreateAlternateCursorFontCursor(Display * /* dpy */, char const * /* cursorfont */, unsigned int /* which */); extern int CursorFontIndexFromShapeName(char const * /* shapename */); /* doublechr.c */ extern void xterm_DECDHL (XtermWidget /* xw */, Bool /* top */); extern void xterm_DECSWL (XtermWidget /* xw */); extern void xterm_DECDWL (XtermWidget /* xw */); extern void xterm_ResetDouble(XtermWidget /* xw */); #if OPT_DEC_CHRSET extern GC xterm_DoubleGC(XTermDraw * /* params */, GC /* old_gc */, int * /* inxp */); #if OPT_RENDERFONT extern XTermXftFonts * xterm_DoubleFT(XTermDraw * /* params */, unsigned /* chrset */, unsigned /* attr_flags */); extern void freeall_DoubleFT(XtermWidget /* xw */); #endif #endif /* input.c */ extern unsigned xtermParamToState (XtermWidget /* xw */, unsigned /* param */); extern unsigned xtermStateToParam (XtermWidget /* xw */, unsigned /* state */); extern Bool xtermDeleteIsDEL (XtermWidget /* xw */); extern void Input (XtermWidget /* xw */, XKeyEvent */* event */, Bool /* eightbit */); extern void StringInput (XtermWidget /* xw */, const Char * /* string */, size_t /* nbytes */); #if OPT_NUM_LOCK extern void VTInitModifiers(XtermWidget /* xw */); #else #define VTInitModifiers(xw) /* nothing */ #endif /* linedata.c */ extern LineData *getLineData(TScreen * /* screen */, int /* row */); extern void copyLineData(LineData * /* dst */, CLineData * /* src */); extern void initLineData(XtermWidget /* xw */); extern CellData *newCellData(XtermWidget /* xw */, Cardinal /* count */); extern void saveCellData(TScreen * /* screen */, CellData * /* data */, Cardinal /* cell */, CLineData * /* ld */, XTermRect * /* limits */, int /* column */); extern void restoreCellData(TScreen * /* screen */, const CellData * /* data */, Cardinal /* cell */, LineData * /* ld */, XTermRect * /* limits */, int /* column */); /* main.c */ #define ENVP_ARG /**/ extern int main (int /* argc */, char ** /* argv */ ENVP_ARG); extern int xtermDisabledChar(void); extern int GetBytesAvailable (Display * /* dpy */); extern int kill_process_group (int /* pid */, int /* sig */); extern int nonblocking_wait (void); extern Atom CachedInternAtom(Display * /* display */, const char * /* name */); extern int get_tty_erase(int /* fd */, int /* default_erase */, const char * /* tag */); extern int get_tty_lnext(int /* fd */, int /* default_lnext */, const char * /* tag */); #if OPT_PTY_HANDSHAKE extern void first_map_occurred (void); #else #define first_map_occurred() /* nothing */ #endif extern GCC_NORETURN void Exit (int /* n */); #ifndef SIG_ATOMIC_T #define SIG_ATOMIC_T int #endif #if OPT_WIDE_CHARS extern unsigned first_widechar; extern int (*my_wcwidth)(wchar_t); #endif /* menu.c */ extern void do_hangup PROTO_XT_CALLBACK_ARGS; extern void repairSizeHints (void); extern void show_8bit_control (Bool /* value */); /* misc.c */ #define TIMESTAMP_LEN 20 /* length of TIMESTAMP_FMT */ extern Bool AllocateTermColor(XtermWidget, ScrnColors *, int, const char *, Bool); extern Boolean allocateBestRGB(XtermWidget /* xw */, XColor * /* def */); extern Boolean validProgram(const char * /* pathname */); extern Boolean xtermGetWinAttrs(Display * /* dpy */, Window /* win */, XWindowAttributes * /* attrs */); extern Boolean xtermGetWinProp(Display * /* dpy */, Window /* win */, Atom /* property */, long /* long_offset */, long /* long_length */, Atom /* req_type */, Atom * /* actual_type_return */, int * /* actual_format_return */, unsigned long * /* nitems_return */, unsigned long * /* bytes_after_return */, unsigned char ** /* prop_return */); extern Boolean xtermIsIconified (XtermWidget /* xw */); extern Cursor make_colored_cursor (unsigned /* cursorindex */, unsigned long /* fg */, unsigned long /* bg */); extern FILE * create_printfile(XtermWidget /* xw */, const char * /* suffix */); extern OptionHelp * sortedOpts(OptionHelp *, XrmOptionDescRec *, Cardinal); extern String xtermEnvLocale (void); extern Widget xtermOpenApplication (XtAppContext * /* app_context_return */, String /* application_class */, XrmOptionDescRec */* options */, Cardinal /* num_options */, int * /* argc_in_out */, char **/* argv_in_out */, String * /* fallback_resources */, WidgetClass /* widget_class */, ArgList /* args */, Cardinal /* num_args */); extern Window WMFrameWindow (XtermWidget /* xw */); extern XtInputMask xtermAppPending (void); extern XrmOptionDescRec * sortedOptDescs (const XrmOptionDescRec *, Cardinal); extern XtermWidget getXtermWidget (Widget /* w */); extern XVisualInfo *getVisualInfo (XtermWidget /* xw */); extern char *udk_lookup (XtermWidget /* xw */, int /* keycode */, int * /* len */); extern char *xtermEnvEncoding (void); extern char *xtermFindShell (char * /* leaf */, Bool /* warning */); extern char *xtermFormatSGR (XtermWidget /* xw */, char * /* target */, unsigned /* attrs */, int /* fg */, int /* bg */); extern const char *SysErrorMsg (int /* n */); extern const char *SysReasonMsg (int /* n */); extern int ResetAnsiColorRequest (XtermWidget, char *, int); extern int XStrCmp (char * /* s1 */, char * /* s2 */); extern int creat_as (uid_t /* uid */, gid_t /* gid */, Bool /* append */, char * /* pathname */, unsigned /* mode */); extern int getVisualDepth (XtermWidget /* xw */); extern int ignore_x11_error(Display * /* dpy */, XErrorEvent * /* event */); extern int open_userfile (uid_t /* uid */, gid_t /* gid */, char * /* path */, Bool /* append */); extern int update_winsize (TScreen * /* screen */, int /* rows */, int /* cols */, int /* height */, int /* width */); extern int xerror (Display * /* d */, XErrorEvent * /* ev */); extern int xioerror (Display * /* dpy */); extern int xtermClosestColor (XtermWidget /* xw */, int /* red */, int /* green */, int /* blue */); extern int xtermResetIds (TScreen * /* screen */); extern void Bell (XtermWidget /* xw */, int /* which */, int /* percent */); extern void ChangeGroup(XtermWidget /* xw */, const char * /* attribute */, char * /* value */); extern void ChangeIconName (XtermWidget /* xw */, char * /* name */); extern void ChangeTitle (XtermWidget /* xw */, char * /* name */); extern void ChangeXprop (char * /* name */); extern GCC_NORETURN void Cleanup (int /* code */); extern void HandleBellPropertyChange PROTO_XT_EV_HANDLER_ARGS; extern void HandleEightBitKeyPressed PROTO_XT_ACTIONS_ARGS; extern void HandleEnterWindow PROTO_XT_EV_HANDLER_ARGS; extern void HandleFocusChange PROTO_XT_EV_HANDLER_ARGS; extern void HandleInterpret PROTO_XT_ACTIONS_ARGS; extern void HandleKeyPressed PROTO_XT_ACTIONS_ARGS; extern void HandleLeaveWindow PROTO_XT_EV_HANDLER_ARGS; extern void HandleSpawnTerminal PROTO_XT_ACTIONS_ARGS; extern void HandleStringEvent PROTO_XT_ACTIONS_ARGS; extern void NormalExit (void); extern void Panic (const char * /* s */, int /* a */); extern void Redraw (void); extern void ReverseOldColors (XtermWidget /* xw */); extern GCC_NORETURN void SysError (int /* i */); extern void VisualBell (void); extern void cleanup_colored_cursor (void); extern void do_ansi_rqm (XtermWidget /* xw */, int /* nparam */, int * /* params */); extern void do_dcs (XtermWidget /* xw */, Char * /* buf */, size_t /* len */); extern void do_dec_rqm (XtermWidget /* xw */, int /* nparam */, int * /* params */); extern void do_osc (XtermWidget /* xw */, Char * /* buf */, size_t /* len */, int /* final */); extern void do_xevents (XtermWidget /* xw */); extern void end_tek_mode (void); extern void end_vt_mode (void); extern void free_string(String value); extern void hide_tek_window (void); extern void hide_vt_window (void); extern GCC_NORETURN void ice_error (IceConn /* iceConn */); extern void init_colored_cursor (Display * /* dpy */); extern void parse_ansi_params(ANSI * /* params */, const char ** /* string */); extern void reset_decudk (XtermWidget /* xw */); extern void set_tek_visibility (Bool /* on */); extern void set_vt_visibility (Bool /* on */); extern void switch_modes (Bool /* tovt */); extern void timestamp_filename(char * /* dst */, const char * /* src */); extern void xevents (XtermWidget /* xw */); extern GCC_NORETURN void xt_error (String /* message */); extern void xtermBell(XtermWidget /* xw */, int /* which */, int /* percent */); extern void xtermCopyEnv (char ** /* oldenv */); extern void xtermDisplayPointer (XtermWidget /* xw */); extern void xtermDeiconify (XtermWidget /* xw */); extern void xtermEmbedWindow (Window /* winToEmbedInfo */); extern void xtermIconify (XtermWidget /* xw */); extern void xtermLoadIcon (XtermWidget /* xw */, const char * /* icon_hint */); extern void xtermPerror (const char * /*fmt*/,...) GCC_PRINTFLIKE(1,2); extern void xtermSetenv (const char * /* var */, const char * /* value */); extern void xtermSetupPointer (XtermWidget /* xw */, const char * /* theShape */); extern void xtermSetWinSize (XtermWidget /* xw */); extern void xtermShowPointer (XtermWidget /* xw */, Bool /* enable */); extern void xtermUnsetenv (const char * /* var */); extern void xtermWarning (const char * /*fmt*/,...) GCC_PRINTFLIKE(1,2); extern Boolean xtermPopTitle(TScreen * /* screen */, int /* which */, SaveTitle * /* item */); extern void xtermPushTitle(TScreen * /* screen */, int /* which */, SaveTitle * /* item */); extern void xtermFreeTitle(SaveTitle *item); extern void xtermReportTitleStack(XtermWidget /* xw */); #if OPT_DABBREV extern void HandleDabbrevExpand PROTO_XT_ACTIONS_ARGS; #endif #if OPT_DIRECT_COLOR extern int getDirectColor(XtermWidget /* xw */, int /* red */, int /* green */, int /* blue */); #endif /* OPT_DIRECT_COLOR */ #if USE_DOUBLE_BUFFER extern void xtermFlushDbe(XtermWidget /* xw */); extern void xtermTimedDbe(XtermWidget /* xw */); #define xtermNeedSwap(xw,why) TScreenOf(xw)->needSwap |= (why) #else #define xtermFlushDbe(xw) /* nothing */ #define xtermTimedDbe(xw) /* nothing */ #define xtermNeedSwap(xw,why) /* nothing */ #endif /* USE_DOUBLE_BUFFER */ #if OPT_EXEC_XTERM extern char *ProcGetCWD(pid_t /* pid */); #else #define ProcGetCWD(pid) NULL #endif #if OPT_ISO_COLORS extern Boolean AllocOneColor(XtermWidget /* xw */, XColor * /* def */); extern Boolean QueryOneColor(XtermWidget /* xw */, XColor * /* def */); #else #define AllocOneColor(xw, def) ((def)->pixel = 0) #define QueryOneColor(xw, def) ((def)->red = (def)->green = (def)->blue = 0) #endif #if OPT_MAXIMIZE extern int QueryMaximize (XtermWidget /* xw */, unsigned * /* width */, unsigned * /* height */); extern void HandleDeIconify PROTO_XT_ACTIONS_ARGS; extern void HandleIconify PROTO_XT_ACTIONS_ARGS; extern void HandleMaximize PROTO_XT_ACTIONS_ARGS; extern void HandleRestoreSize PROTO_XT_ACTIONS_ARGS; extern void RequestMaximize (XtermWidget /* xw */, int /* maximize */); #endif #if OPT_REPORT_ICONS extern void report_icons(const char *fmt,...) GCC_PRINTFLIKE(1,2); #define ReportIcons(params) report_icons params #else #define ReportIcons(params) TRACE(params) #endif #if OPT_SCROLL_LOCK extern void GetScrollLock (TScreen * /* screen */); extern void HandleScrollLock PROTO_XT_ACTIONS_ARGS; extern void ShowScrollLock (TScreen * /* screen */, Bool /* enable */); extern void SetScrollLock (TScreen * /* screen */, Bool /* enable */); extern void xtermShowLED (TScreen * /* screen */, Cardinal /* led_number */, Bool /* enable */); extern void xtermClearLEDs (TScreen * /* screen */); #else #define ShowScrollLock(screen, enable) /* nothing */ #define SetScrollLock(screen, enable) /* nothing */ #define GetScrollLock(screen) /* nothing */ #endif #if OPT_SELECTION_OPS extern void HandleExecFormatted PROTO_XT_ACTIONS_ARGS; extern void HandleExecSelectable PROTO_XT_ACTIONS_ARGS; extern void HandleInsertFormatted PROTO_XT_ACTIONS_ARGS; extern void HandleInsertSelectable PROTO_XT_ACTIONS_ARGS; #endif #if OPT_SESSION_MGT extern void xtermCloseSession (void); extern void xtermOpenSession (void); extern void xtermUpdateRestartCommand(XtermWidget /* xw */); #else #define xtermCloseSession() /* nothing */ #define xtermOpenSession() /* nothing */ #define xtermUpdateRestartCommand(xw) /* nothing */ #endif #if OPT_WIDE_CHARS extern Bool xtermEnvUTF8(void); #else #define xtermEnvUTF8() False #endif #if OPT_XTERM_SGR extern void xtermPushSGR (XtermWidget /* xw */, int /* value */); extern void xtermPopSGR (XtermWidget /* xw */); extern void xtermReportSGR (XtermWidget /* xw */, XTermRect * /* value */); extern void xtermPushColors (XtermWidget /* xw */, int /* value */); extern void xtermPopColors (XtermWidget /* xw */, int /* value */); extern void xtermReportColors (XtermWidget /* xw */); #endif #ifdef ALLOWLOGGING extern void StartLog (XtermWidget /* xw */); extern void CloseLog (XtermWidget /* xw */); extern void FlushLog (XtermWidget /* xw */); #else #define FlushLog(xw) /*nothing*/ #endif /* print.c */ extern Bool xtermHasPrinter (XtermWidget /* xw */); extern PrinterFlags *getPrinterFlags (XtermWidget /* xw */, String * /* params */, Cardinal * /* param_count */); extern int xtermPrinterControl (XtermWidget /* xw */, int /* chr */); extern void setPrinterControlMode (XtermWidget /* xw */, int /* mode */); extern void xtermAutoPrint (XtermWidget /* xw */, unsigned /* chr */); extern void xtermMediaControl (XtermWidget /* xw */, int /* param */, int /* private_seq */); extern void xtermPrintScreen (XtermWidget /* xw */, Bool /* use_DECPEX */, PrinterFlags * /* p */); extern void xtermPrintEverything (XtermWidget /* xw */, PrinterFlags * /* p */); extern void xtermPrintImmediately (XtermWidget /* xw */, String /* filename */, int /* opts */, int /* attributes */); extern void xtermPrintOnXError (XtermWidget /* xw */, int /* n */); #if OPT_SCREEN_DUMPS /* html.c */ extern void xtermDumpHtml (XtermWidget /* xw */); extern char *PixelToCSSColor(XtermWidget /* xw */, Pixel /* p */); /* svg.c */ extern void xtermDumpSvg (XtermWidget /* xw */); #endif /* ptydata.c */ #define PtySelect fd_set extern Bool decodeUtf8 (TScreen * /* screen */, PtyData * /* data */); extern int readPtyData (XtermWidget /* xw */, PtySelect * /* select_mask */, PtyData * /* data */); extern void fillPtyData (XtermWidget /* xw */, PtyData * /* data */, const char * /* value */, size_t /* length */); extern void initPtyData (PtyData ** /* data */); extern void trimPtyData (XtermWidget /* xw */, PtyData * /* data */); #ifdef NO_LEAKS extern void noleaks_ptydata ( void ); #endif #if OPT_WIDE_CHARS extern Boolean isValidUTF8 (Char * /* lp */); extern Char *convertToUTF8 (Char * /* lp */, unsigned /* c */); extern Char *convertFromUTF8 (Char * /* lp */, unsigned * /* cp */); extern IChar nextPtyData (TScreen * /* screen */, PtyData * /* data */); extern PtyData * fakePtyData (PtyData * /* result */, Char * /* next */, Char * /* last */); extern void switchPtyData (TScreen * /* screen */, int /* f */); extern void writePtyData (int /* f */, IChar * /* d */, size_t /* len */); #define morePtyData(screen, data) \ (((data)->last > (data)->next) \ ? (((screen)->utf8_inparse && !(data)->utf_size) \ ? decodeUtf8(screen, data) \ : True) \ : False) #define skipPtyData(data, result) \ do { \ result = (data)->utf_data; \ (data)->next += (data)->utf_size; \ (data)->utf_size = 0; \ } while (0) #else #define morePtyData(screen, data) ((data)->last > (data)->next) #define nextPtyData(screen, data) (IChar) (*((data)->next++) & \ (screen->output_eight_bits \ ? 0xff \ : 0x7f)) #define writePtyData(f,d,len) v_write(f,d,len) #endif /* screen.c */ /* * See http://standards.freedesktop.org/wm-spec/wm-spec-latest.html */ #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ #define _NET_WM_STATE_ADD 1 /* add/set property */ #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ extern Bool non_blank_line (TScreen */* screen */, int /* row */, int /* col */, int /* len */); extern Char * allocScrnData (TScreen * /* screen */, unsigned /* nrow */, unsigned /* ncol */, Bool /* bottom */); extern ScrnBuf allocScrnBuf (XtermWidget /* xw */, unsigned /* nrow */, unsigned /* ncol */, ScrnPtr * /* addr */); extern ScrnBuf scrnHeadAddr (TScreen * /* screen */, ScrnBuf /* base */, unsigned /* offset */); extern size_t ScrnPointers (TScreen * /* screen */, size_t /* len */); extern void ClearBufRows (XtermWidget /* xw */, int /* first */, int /* last */); extern void ClearCells (XtermWidget /* xw */, int /* flags */, unsigned /* len */, int /* row */, int /* col */); extern void CopyCells (TScreen * /* screen */, LineData * /* src */, LineData * /* dst */, int /* col */, int /* len */, Bool /* down */); extern void FullScreen (XtermWidget /* xw */, int /* mode */); extern void FreeMarkGCs (XtermWidget /* xw */); extern void ResetHiddenHint (XtermWidget /* xw */); extern void ScreenResize (XtermWidget /* xw */, int /* width */, int /* height */, unsigned * /* flags */); extern void ScrnAllocBuf (XtermWidget /* xw */); extern void ScrnClearCells (XtermWidget /* xw */, int /* row */, int /* col */, unsigned /* len */); extern void ScrnDeleteChar (XtermWidget /* xw */, unsigned /* n */); extern void ScrnDeleteCol (XtermWidget /* xw */, unsigned /* n */); extern void ScrnDeleteLine (XtermWidget /* xw */, ScrnBuf /* sb */, int /* n */, int /* last */, unsigned /* where */); extern void ScrnDisownSelection (XtermWidget /* xw */); extern void ScrnFillRectangle (XtermWidget /* xw */, XTermRect *, int /* value */, DECNRCM_codes /* charset */, unsigned /* flags */, Bool /* keepColors */); extern void ScrnInsertChar (XtermWidget /* xw */, unsigned /* n */); extern void ScrnInsertCol (XtermWidget /* xw */, unsigned /* n */); extern void ScrnInsertLine (XtermWidget /* xw */, ScrnBuf /* sb */, int /* last */, int /* where */, unsigned /* n */); extern void ScrnRefresh (XtermWidget /* xw */, int /* toprow */, int /* leftcol */, int /* nrows */, int /* ncols */, Bool /* force */); extern void ScrnUpdate (XtermWidget /* xw */, int /* toprow */, int /* leftcol */, int /* nrows */, int /* ncols */, Bool /* force */); extern void ScrnWriteText (XtermWidget /* xw */, Cardinal /* offset */, Cardinal /* length */, unsigned /* flags */, CellColor /* cur_fg_bg */); extern void ShowWrapMarks (XtermWidget /* xw */, int /* row */, CLineData * /* ld */); extern void setupLineData (TScreen * /* screen */, ScrnBuf /* base */, Char * /* data */, unsigned /* nrow */, unsigned /* ncol */, Bool /* bottom */); extern void xtermParseRect (XtermWidget /* xw */, int, int *, XTermRect *); #if OPT_TRACE && OPT_TRACE_FLAGS extern int LineTstFlag(LineData /* ld */, int /* flag */); extern void LineClrFlag(LineData /* ld */, int /* flag */); extern void LineSetFlag(LineData /* ld */, int /* flag */); #else #define LineFlags(ld) GetLineFlags(ld) #define LineClrFlag(ld, flag) SetLineFlags(ld, (GetLineFlags(ld) & ~ (flag))) #define LineSetFlag(ld, flag) SetLineFlags(ld, (GetLineFlags(ld) | (flag))) #define LineTstFlag(ld, flag) ((GetLineFlags(ld) & flag) != 0) #endif /* OPT_TRACE && OPT_TRACE_FLAGS */ #define LineClrBlinked(ld) LineClrFlag(ld, LINEBLINKED) #define LineSetBlinked(ld) LineSetFlag(ld, LINEBLINKED) #define LineTstBlinked(ld) LineTstFlag(ld, LINEBLINKED) #define LineClrWrapped(ld) LineClrFlag(ld, LINEWRAPPED) #define LineSetWrapped(ld) LineSetFlag(ld, LINEWRAPPED) #define LineTstWrapped(ld) LineTstFlag(ld, LINEWRAPPED) #define ScrnHaveSelection(screen) \ ((screen)->startH.row != (screen)->endH.row \ || (screen)->startH.col != (screen)->endH.col) #define ScrnAreRowsInSelection(screen, first, last) \ ((last) >= (screen)->startH.row && (first) <= (screen)->endH.row) #define ScrnIsRowInSelection(screen, line) \ ((line) >= (screen)->startH.row && (line) <= (screen)->endH.row) #define ScrnHaveRowMargins(screen) \ ((screen)->top_marg != 0 \ || ((screen)->bot_marg != screen->max_row)) #define ScrnIsRowInMargins(screen, line) \ ((line) >= (screen)->top_marg && (line) <= (screen)->bot_marg) #define ScrnHaveColMargins(screen) \ ((screen)->rgt_marg > (screen)->max_col) #define ScrnIsColInMargins(screen, col) \ ((col) >= (screen)->lft_marg && (col) <= (screen)->rgt_marg) /* * If the vertical scrolling margins are active, they will be something other * than the first/last row of the visible screen, as well as being distinct. */ #define IsTopBottomMode(xw) (ScrnTopMargin(xw) < ScrnBottomMargin(xw)) #define ScrnTopMargin(xw) TScreenOf(xw)->top_marg #define ScrnBottomMargin(xw) TScreenOf(xw)->bot_marg /* * Left/right horizontal scrolling margins are only active when DECLRMM is. */ #define IsLeftRightMode(xw) ((xw)->flags & LEFT_RIGHT) #define ScrnLeftMargin(xw) (IsLeftRightMode(xw) \ ? TScreenOf(xw)->lft_marg \ : 0) #define ScrnRightMargin(xw) (IsLeftRightMode(xw) \ ? TScreenOf(xw)->rgt_marg \ : MaxCols(TScreenOf(xw)) - 1) #if OPT_DEC_RECTOPS extern void ScrnCopyRectangle (XtermWidget /* xw */, XTermRect *, int, int *); extern void ScrnMarkRectangle (XtermWidget /* xw */, XTermRect *, Bool, int, int *); extern void ScrnWipeRectangle (XtermWidget /* xw */, XTermRect *); extern void xtermCheckRect(XtermWidget /* xw */, int /* nparam */, int */* params */, int * /* result */); #endif #if OPT_WIDE_CHARS extern void ChangeToWide(XtermWidget /* xw */); #endif /* scrollback.c */ extern LineData *getScrollback (TScreen * /* screen */, int /* row */); extern LineData *addScrollback (TScreen * /* screen */); extern void deleteScrollback (TScreen * /* screen */); /* scrollbar.c */ extern void DoResizeScreen (XtermWidget /* xw */); extern void HandleScrollBack PROTO_XT_ACTIONS_ARGS; extern void HandleScrollForward PROTO_XT_ACTIONS_ARGS; extern void HandleScrollTo PROTO_XT_ACTIONS_ARGS; extern void ResizeScrollBar (XtermWidget /* xw */); extern void ScrollBarDrawThumb (XtermWidget /* xw */, int /* mode */); extern void ScrollBarOff (XtermWidget /* xw */); extern void ScrollBarOn (XtermWidget /* xw */, Bool /* init */); extern void ScrollBarReverseVideo (Widget /* scrollWidget */); extern void ToggleScrollBar (XtermWidget /* xw */); extern void WindowScroll (XtermWidget /* xw */, int /* top */, Bool /* always */); #ifdef SCROLLBAR_RIGHT extern void updateRightScrollbar(XtermWidget /* xw */); #else #define updateRightScrollbar(xw) /* nothing */ #endif /* tabs.c */ extern Bool TabToNextStop (XtermWidget /* xw */); extern Bool TabToPrevStop (XtermWidget /* xw */); extern void TabClear (Tabs /* tabs */, int /* col */); extern void TabReset (Tabs /* tabs */); extern void TabSet (Tabs /* tabs */, int /* col */); extern void TabZonk (Tabs /* tabs */); extern Bool TabIsSet (Tabs /* tabs */, int /* col */); /* util.c */ extern Boolean AssignFgColor (XtermWidget /* xw */, Pixel /* bg */); extern Boolean AssignBgColor (XtermWidget /* xw */, Pixel /* bg */); extern Boolean isDefaultBackground (const char * /* name */); extern Boolean isDefaultForeground (const char * /* name */); extern CgsEnum whichXtermCgs (XtermWidget /* xw */, unsigned /* attr_flags */, Bool /* hilite */); extern GC updatedXtermGC (XtermWidget /* xw */, unsigned /* flags */, CellColor /* fg_bg */, Bool /* hilite */); extern Pixel getXtermBackground (XtermWidget /* xw */, unsigned /* flags */, int /* color */); extern Pixel getXtermForeground (XtermWidget /* xw */, unsigned /* flags */, int /* color */); extern char * xtermSetLocale (int /* category */, String /* after */); extern int ClearInLine (XtermWidget /* xw */, int /* row */, int /* col */, unsigned /* len */); extern int HandleExposure (XtermWidget /* xw */, XEvent * /* event */); extern int dimRound (double /* value */); extern int drawXtermText (const XTermDraw * /* param */, GC /* gc */, int /* x */, int /* y */, const IChar * /* text */, Cardinal /* len */); extern int extendedBoolean (const char * /* value */, const FlagList * /* table */, Cardinal /* limit */); extern void ChangeColors (XtermWidget /* xw */, ScrnColors * /* pNew */); extern void ClearLine (XtermWidget /* xw */); extern void ClearRight (XtermWidget /* xw */, int /* n */); extern void ClearScreen (XtermWidget /* xw */); extern void DeleteChar (XtermWidget /* xw */, unsigned /* n */); extern void DeleteLine (XtermWidget /* xw */, int /* n */, Bool /* canSave */); extern void FlushScroll (XtermWidget /* xw */); extern void GetColors (XtermWidget /* xw */, ScrnColors * /* pColors */); extern void InsertChar (XtermWidget /* xw */, unsigned /* n */); extern void InsertLine (XtermWidget /* xw */, int /* n */); extern void RevScroll (XtermWidget /* xw */, int /* amount */); extern void ReverseVideo (XtermWidget /* xw */); extern void WriteText (XtermWidget /* xw */, Cardinal /* offset */, Cardinal /* len */); extern void decode_keyboard_type (XtermWidget /* xw */, struct XTERM_RESOURCE * /* rp */); extern void decode_wcwidth (XtermWidget /* xw */); extern void do_cd_xtra_scroll (XtermWidget /* xw */, int /* param */); extern void do_erase_display (XtermWidget /* xw */, int /* param */, int /* mode */); extern void do_erase_char (XtermWidget /* xw */, int /* param */, int /* mode */); extern void do_erase_line (XtermWidget /* xw */, int /* param */, int /* mode */); extern void do_ti_xtra_scroll (XtermWidget /* xw */); extern void getXtermSizeHints (XtermWidget /* xw */); extern void recolor_cursor (TScreen * /* screen */, Cursor /* cursor */, unsigned long /* fg */, unsigned long /* bg */); extern void resetXtermGC (XtermWidget /* xw */, unsigned /* flags */, Bool /* hilite */); extern void scrolling_copy_area (XtermWidget /* xw */, int /* firstline */, int /* nlines */, int /* amount */); extern void set_keyboard_type (XtermWidget /* xw */, xtermKeyboardType /* type */, Bool /* set */); extern void toggle_keyboard_type (XtermWidget /* xw */, xtermKeyboardType /* type */); extern void update_keyboard_type (void); extern void xtermClear (XtermWidget /* xw */); extern void xtermClear2 (XtermWidget /* xw */, int /* x */, int /* y */, unsigned /* width */, unsigned /* height */); extern void xtermColIndex (XtermWidget /* xw */, Bool /* toLeft */); extern void xtermColScroll (XtermWidget /* xw */, int /* amount */, Bool /* toLeft */, int /* at_col */); extern void xtermRepaint (XtermWidget /* xw */); extern void xtermResetLocale (int /* category */, char * /* before */); extern void xtermScroll (XtermWidget /* xw */, int /* amount */); extern void xtermScrollLR (XtermWidget /* xw */, int /* amount */, Bool /* toLeft */); extern void xtermSizeHints (XtermWidget /* xw */, int /* scrollbarWidth */); struct Xinerama_geometry { int x; int y; unsigned w; unsigned h; int scr_x; int scr_y; int scr_w; int scr_h; }; extern int XParseXineramaGeometry(Display * /* display */, char * /* parsestring */, struct Xinerama_geometry * /* ret */); #if OPT_ISO_COLORS extern Pixel extract_fg (XtermWidget /* xw */, CellColor /* color */, unsigned /* flags */); extern Pixel extract_bg (XtermWidget /* xw */, CellColor /* color */, unsigned /* flags */); extern CellColor makeColorPair (XtermWidget /* xw */); extern void ClearCurBackground (XtermWidget /* xw */, int /* top */, int /* left */, unsigned /* height */, unsigned /* width */, unsigned /* fw */); #define xtermColorPair(xw) makeColorPair(xw) #define GET_COLOR_RES(xw, res) xtermGetColorRes(xw, &(res)) #define SET_COLOR_RES(res,color) (res)->value = color #define EQL_COLOR_RES(res,color) (res)->value == color #define T_COLOR(v,n) (v)->Tcolors[n].value extern Pixel xtermGetColorRes(XtermWidget /* xw */, ColorRes * /* res */); #define ExtractForeground(color) (unsigned) GetCellColorFG(color) #define ExtractBackground(color) (unsigned) GetCellColorBG(color) #if OPT_RENDERFONT extern void discardRenderDraw(TScreen * /* screen */); #else #define discardRenderDraw(screen) /* nothing */ #endif #if OPT_WIDE_ATTRS #define MapToWideColorMode(fg, screen, flags) \ (((screen)->colorITMode && ((flags) & ATR_ITALIC)) \ ? COLOR_IT \ : fg) #else #define MapToWideColorMode(fg, screen, flags) fg #endif #define MapToColorMode(fg, screen, flags) \ (((screen)->colorBLMode && ((flags) & BLINK)) \ ? COLOR_BL \ : (((screen)->colorBDMode && ((flags) & BOLD)) \ ? COLOR_BD \ : (((screen)->colorULMode && ((flags) & UNDERLINE)) \ ? COLOR_UL \ : MapToWideColorMode(fg, screen, flags)))) #define checkVeryBoldAttr(flags, fg, code, attr) \ if ((flags & FG_COLOR) != 0 \ && (screen->veryBoldColors & attr) == 0 \ && (flags & attr) != 0 \ && (fg == code)) \ UIntClr(flags, attr) #if OPT_WIDE_ATTRS #define checkVeryBoldWideAttr(flags, fg, it, atr) \ checkVeryBoldAttr(flags, fg, it, atr) #else #define checkVeryBoldWideAttr(flags, fg, it, atr) (void) flags #endif #define checkVeryBoldColors(flags, fg) \ checkVeryBoldAttr(flags, fg, COLOR_RV, INVERSE); \ checkVeryBoldAttr(flags, fg, COLOR_UL, UNDERLINE); \ checkVeryBoldAttr(flags, fg, COLOR_BD, BOLD); \ checkVeryBoldAttr(flags, fg, COLOR_BL, BLINK); \ checkVeryBoldWideAttr(flags, fg, COLOR_IT, ATR_ITALIC) #else /* !OPT_ISO_COLORS */ #define MapToColorMode(fg, screen, flags) fg #define ClearCurBackground(xw, top, left, height, width, fw) \ XClearArea (TScreenOf(xw)->display, \ VDrawable(TScreenOf(xw)), \ CursorX2(TScreenOf(xw), left, fw), \ CursorY2(TScreenOf(xw), top), \ ((width) * (unsigned) fw), \ ((height) * (unsigned) FontHeight(TScreenOf(xw))), \ False) #define extract_fg(xw, color, flags) (unsigned) (xw)->cur_foreground #define extract_bg(xw, color, flags) (unsigned) (xw)->cur_background /* FIXME: Reverse-Video? */ #define T_COLOR(v,n) (v)->Tcolors[n].value #define xtermColorPair(xw) 0 #define checkVeryBoldColors(flags, fg) /* nothing */ #define discardRenderDraw(screen) /* nothing */ #endif /* OPT_ISO_COLORS */ #define getXtermFG(xw, flags, color) getXtermForeground(xw, flags, color) #define getXtermBG(xw, flags, color) getXtermBackground(xw, flags, color) #if OPT_ZICONBEEP extern void initZIconBeep(void); extern void resetZIconBeep(XtermWidget /* xw */); extern Boolean showZIconBeep(XtermWidget /* xw */, const char * /* name */); #else #define initZIconBeep() /* nothing */ #define resetZIconBeep(xw) /* nothing */ #define showZIconBeep(xw, name) False #endif #define XTERM_CELL(row,col) getXtermCell(screen, ROW2INX(screen, row), col) extern unsigned getXtermCell (TScreen * /* screen */, int /* row */, int /* col */); extern unsigned getXtermCombining(TScreen * /* screen */, int /* row */, int /* col */, int /* off */); extern void putXtermCell (TScreen * /* screen */, int /* row */, int /* col */, int /* ch */); #define IsCellCombined(screen, row, col) (getXtermCombining(screen, row, col, 0) != 0) #if OPT_HIGHLIGHT_COLOR #define isNotForeground(xw, fg, bg, sel) \ (Boolean) ((sel) != T_COLOR(TScreenOf(xw), TEXT_FG) \ && (sel) != (fg) \ && (sel) != (bg) \ && (sel) != (xw)->dft_foreground) #define isNotBackground(xw, fg, bg, sel) \ (Boolean) ((sel) != T_COLOR(TScreenOf(xw), TEXT_BG) \ && (sel) != (fg) \ && (sel) != (bg) \ && (sel) != (xw)->dft_background) #endif #define setXtermLineAttributes(dpy, gc, width, style) \ XSetLineAttributes(dpy, gc, (unsigned) width, style, CapProjecting, JoinMiter); #define resetXtermLineAttributes(dpy, gc) \ setXtermLineAttributes(dpy, gc, 0, LineSolid); #if OPT_WIDE_CHARS extern int DamagedCells(TScreen * /* screen */, unsigned /* n */, int * /* klp */, int * /* krp */, int /* row */, int /* col */); extern int DamagedCurCells(TScreen * /* screen */, unsigned /* n */, int * /* klp */, int * /* krp */); extern unsigned AsciiEquivs(unsigned /* ch */); extern void addXtermCombining (TScreen * /* screen */, int /* row */, int /* col */, unsigned /* ch */); extern void allocXtermChars(ScrnPtr * /* buffer */, Cardinal /* length */); #endif #if OPT_XMC_GLITCH extern void Mark_XMC (XtermWidget /* xw */, int /* param */); extern void Jump_XMC (XtermWidget /* xw */); extern void Resolve_XMC (XtermWidget /* xw */); #endif #if OPT_WIDE_CHARS unsigned visual_width(const IChar * /* str */, Cardinal /* len */); #else #define visual_width(a, b) (b) #endif #define BtoS(b) ((b) ? "on" : "off") #define MtoS(b) (((b) == Maybe) ? "maybe" : BtoS(b)) #define NonNull(s) ((s) ? (s) : "") #define UIntSet(dst,bits) dst = dst | (unsigned) (bits) #define UIntClr(dst,bits) dst = dst & (unsigned) ~(bits) #define SIntClr(dst,bits) dst = (int) ((unsigned) dst & (unsigned) ~(bits)) #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* included_xterm_h */ xterm-399/input.c0000644000000000000000000017245114773102416012557 0ustar rootroot/* $XTermId: input.c,v 1.387 2025/04/02 00:30:06 tom Exp $ */ /* * Copyright 1999-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * * * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* input.c */ #include #include #if HAVE_X11_DECKEYSYM_H #include #endif #if HAVE_X11_SUNKEYSYM_H #include #endif #if HAVE_X11_XF86KEYSYM_H #include #endif #if !defined(HAVE_CONFIG_H) && defined(_X_DEPRECATED) #define HAVE_XKBKEYCODETOKEYSYM 1 #endif #ifdef HAVE_XKBKEYCODETOKEYSYM #include #endif #include #include #include #include #include #include #include #include #include #if OPT_NUM_LOCK #define AltOrMeta(xw) ((xw)->work.meta_mods | (xw)->work.alt_mods) #else #define AltOrMeta(xw) 0 #endif /* * Xutil.h has no macro to check for the complete set of function- and * modifier-keys that might be returned. Fake it. * * The XK_ISO_xxx symbols (starting at 0xfe01) were introduced for the * X Keyboard Extension (XKB) in X11R6. There also were 3270 terminal * symbols (starting at 0xfd01), but those are less used. We do not count * those here, but make provision for them in keysym2ucs, just in case. */ #ifdef XK_ISO_Lock #define IsPredefinedKey(n) (((n) >= XK_ISO_Lock && (n) <= XK_Delete) || ((n) >= 0x10000000)) #else #define IsPredefinedKey(n) ((n) >= XK_BackSpace && (n) <= XK_Delete) #endif #ifdef XK_ISO_Left_Tab #define IsTabKey(n) ((n) == XK_Tab || (n) == XK_ISO_Left_Tab) #else #define IsTabKey(n) ((n) == XK_Tab) #endif #ifndef IsPrivateKeypadKey #define IsPrivateKeypadKey(k) (0) #endif #define IsOrdinaryKey(xwidget, key_data) \ (!((key_data)->is_fkey \ || IsEditFunctionKey(xwidget, (key_data)->keysym) \ || IsKeypadKey((key_data)->keysym) \ || IsCursorKey((key_data)->keysym) \ || IsPFKey((key_data)->keysym) \ || IsMiscFunctionKey((key_data)->keysym) \ || IsPrivateKeypadKey((key_data)->keysym))) #define IsBackarrowToggle(keyboard, keysym, state) \ ((((keyboard->flags & MODE_DECBKM) == 0) \ ^ ((state & ControlMask) != 0)) \ && (keysym == XK_BackSpace)) #define MAP(from, to) case from: result = to; break #define Masked(value,mask) ((unsigned) (value) & (unsigned) (~(mask))) #define KEYSYM_FMT "0x%04lX" /* simplify matching */ #define TEK4014_GIN(tw) (tw != NULL && TekScreenOf(tw)->TekGIN) typedef struct { KeySym keysym; Bool is_fkey; int nbytes; #define STRBUFSIZE 500 char strbuf[STRBUFSIZE]; } KEY_DATA; static const char kypd_num[] = " XXXXXXXX\tXXX\rXXXxxxxXXXXXXXXXXXXXXXXXXXXX*+,-./0123456789XXX="; /* 0123456789 abc def0123456789abcdef0123456789abcdef0123456789abcd */ static const char kypd_apl[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ??????abcdefghijklmnopqrstuvwxyzXXX"; /* 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd */ static const char curfinal[] = "HDACB FE"; static int decfuncvalue(KEY_DATA *); static void sunfuncvalue(ANSI *, KEY_DATA *); static void hpfuncvalue(ANSI *, KEY_DATA *); static void scofuncvalue(ANSI *, KEY_DATA *); static void AdjustAfterInput(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->scrollkey && screen->topline != 0) WindowScroll(xw, 0, False); if (screen->marginbell) { int col = screen->max_col - screen->nmarginbell; if (screen->bellArmed >= 0) { if (screen->bellArmed == screen->cur_row) { if (screen->cur_col >= col) { Bell(xw, XkbBI_MarginBell, 0); screen->bellArmed = -1; } } else { screen->bellArmed = screen->cur_col < col ? screen->cur_row : -1; } } else if (screen->cur_col < col) screen->bellArmed = screen->cur_row; } } /* * Return true if the key is on the editing keypad. This overlaps with * IsCursorKey() and IsKeypadKey() and must be tested before those macros to * distinguish it from them. * * VT220 emulation uses the VT100 numeric keypad as well as a 6-key * editing keypad. Here's a picture of the VT220 editing keypad: * +--------+--------+--------+ * | Find | Insert | Remove | * +--------+--------+--------+ * | Select | Prev | Next | * +--------+--------+--------+ * * and the similar Sun and PC keypads: * +--------+--------+--------+ * | Insert | Home | PageUp | * +--------+--------+--------+ * | Delete | End | PageDn | * +--------+--------+--------+ */ static Bool IsEditKeypad(XtermWidget xw, KeySym keysym) { Bool result; switch (keysym) { case XK_Delete: result = !xtermDeleteIsDEL(xw); break; case XK_Prior: case XK_Next: case XK_Insert: case XK_Find: case XK_Select: #ifdef DXK_Remove case DXK_Remove: #endif result = True; break; default: result = False; break; } return result; } /* * Editing-keypad, plus other editing keys which are not included in the * other macros. */ static Bool IsEditFunctionKey(XtermWidget xw, KeySym keysym) { Bool result; switch (keysym) { #ifdef XK_KP_Delete case XK_KP_Delete: /* editing key on numeric keypad */ case XK_KP_Insert: /* editing key on numeric keypad */ #endif #ifdef XK_ISO_Left_Tab case XK_ISO_Left_Tab: #endif result = True; break; default: result = IsEditKeypad(xw, keysym); break; } return result; } #if OPT_MOD_FKEYS #define IS_CTRL(n) ((n) < ANSI_SPA || ((n) >= 0x7f && (n) <= 0x9f)) /* * Return true if the keysym corresponds to one of the control characters, * or one of the common ASCII characters that is combined with control to * make a control character. */ static Bool IsControlInput(KEY_DATA * kd) { return ((kd->keysym) >= 0x40 && (kd->keysym) <= 0x7f); } static Bool IsControlOutput(KEY_DATA * kd) { return IS_CTRL(kd->keysym); } /* * X "normally" has some built-in translations, which the user may want to * suppress when processing the modifyOtherKeys resource. In particular, the * control modifier applied to some of the keyboard digits gives results for * control characters. * * control 2 0 NUL * control SPC 0 NUL * control @ 0 NUL * control ` 0 NUL * control 3 0x1b ESC * control 4 0x1c FS * control \ 0x1c FS * control 5 0x1d GS * control 6 0x1e RS * control ^ 0x1e RS * control ~ 0x1e RS * control 7 0x1f US * control / 0x1f US * control _ 0x1f US * control 8 0x7f DEL * * It is possible that some other keyboards do not work for these combinations, * but they do work with modifyOtherKeys=2 for the US keyboard: * * control ` 0 NUL * control [ 0x1b ESC * control \ 0x1c FS * control ] 0x1d GS * control ? 0x7f DEL */ static Bool IsControlAlias(KEY_DATA * kd) { Bool result = False; if (kd->nbytes == 1) { result = IS_CTRL(CharOf(kd->strbuf[0])); } return result; } #if OPT_TRACE static const char * visibleModkeyModes(ModkeyModes value) { const char *result = NULL; switch (value) { CASETYPE(modifyCursorKeys); CASETYPE(modifyKeyboard); CASETYPE(modifyFunctionKeys); CASETYPE(modifyKeypadKeys); CASETYPE(modifyOtherKeys); CASETYPE(modifyStringKeys); CASETYPE(modifyModifierKeys); CASETYPE(modifySpecialKeys); } return result; } #else #define visibleModkeyModes(value) "" #endif static ModkeyModes TypeOfKeysym(XtermWidget xw, KEY_DATA * key_data) { ModkeyModes result; if (IsCursorKey(key_data->keysym)) { TRACE2(("type: IsCursorKey\n")); result = modifyCursorKeys; } else if (IsEditKeypad(xw, key_data->keysym)) { TRACE2(("type: IsEditKeypad\n")); result = modifyCursorKeys; } else if (IsFunctionKey(key_data->keysym)) { TRACE2(("type: IsFunctionKey\n")); /* F1-F12 */ result = modifyFunctionKeys; } else if (IsKeypadKey(key_data->keysym)) { TRACE2(("type: IsKeypadKey\n")); result = modifyKeypadKeys; } else if (IsModifierKey(key_data->keysym)) { TRACE2(("type: IsModifierKey\n")); result = modifyModifierKeys; } else if (IsMiscFunctionKey(key_data->keysym)) { TRACE2(("type: IsMiscFunctionKey\n")); result = modifyFunctionKeys; } else if (IsPFKey(key_data->keysym)) { TRACE2(("type: IsPFKey\n")); result = modifyFunctionKeys; } else if (IsPrivateKeypadKey(key_data->keysym)) { TRACE2(("type: IsPrivateKeypadKey\n")); result = modifySpecialKeys; } else if (IsPredefinedKey(key_data->keysym)) { TRACE2(("type: IsPredefinedKey\n")); result = modifySpecialKeys; } else { TRACE2(("type: IsOrdinaryKey: %d\n", IsOrdinaryKey(xw, key_data))); result = modifyOtherKeys; } return result; } /* * If we are in the non-VT220/VT52 keyboard state, allow modifiers to add a * parameter to the function-key control sequences. * * Note that we generally cannot capture the Shift-modifier for the numeric * keypad since this is commonly used to act as a type of NumLock, e.g., * making the keypad send "7" (actually XK_KP_7) where the unshifted code * would be Home (XK_KP_Home). The other modifiers work, subject to the * usual window-manager assignments. */ #if OPT_SUNPC_KBD #define LegacyAllows(code) (!is_legacy || (code & xw->keyboard.modify_now.allow_keys) != 0) #else #define LegacyAllows(code) True #endif static Bool allowModifierParm(XtermWidget xw, KEY_DATA * kd) { TKeyboard *keyboard = &(xw->keyboard); int is_legacy = (keyboard->type == keyboardIsLegacy); Bool result = False; #if OPT_SUNPC_KBD if (keyboard->type == keyboardIsVT220) is_legacy = True; #endif #if OPT_VT52_MODE if (TScreenOf(xw)->vtXX_level != 0) #endif { if (IsCursorKey(kd->keysym) || IsEditFunctionKey(xw, kd->keysym)) { result = LegacyAllows(2); } else if (IsKeypadKey(kd->keysym)) { result = LegacyAllows(1); } else if (IsFunctionKey(kd->keysym)) { result = LegacyAllows(4); } else if (IsMiscFunctionKey(kd->keysym)) { result = LegacyAllows(8); } } if (xw->keyboard.modify_now.other_keys != mokNone) { result = True; } return result; } #endif /* OPT_MOD_FKEYS */ #if OPT_MOD_FKEYS || OPT_TCAP_FKEYS /* * Modifier codes: * None 1 * Shift 2 = 1(None)+1(Shift) * Alt 3 = 1(None)+2(Alt) * Alt+Shift 4 = 1(None)+1(Shift)+2(Alt) * Ctrl 5 = 1(None)+4(Ctrl) * Ctrl+Shift 6 = 1(None)+1(Shift)+4(Ctrl) * Ctrl+Alt 7 = 1(None)+2(Alt)+4(Ctrl) * Ctrl+Alt+Shift 8 = 1(None)+1(Shift)+2(Alt)+4(Ctrl) * Meta 9 = 1(None)+8(Meta) * Meta+Shift 10 = 1(None)+8(Meta)+1(Shift) * Meta+Alt 11 = 1(None)+8(Meta)+2(Alt) * Meta+Alt+Shift 12 = 1(None)+8(Meta)+1(Shift)+2(Alt) * Meta+Ctrl 13 = 1(None)+8(Meta)+4(Ctrl) * Meta+Ctrl+Shift 14 = 1(None)+8(Meta)+1(Shift)+4(Ctrl) * Meta+Ctrl+Alt 15 = 1(None)+8(Meta)+2(Alt)+4(Ctrl) * Meta+Ctrl+Alt+Shift 16 = 1(None)+8(Meta)+1(Shift)+2(Alt)+4(Ctrl) */ unsigned xtermParamToState(XtermWidget xw, unsigned param) { unsigned result = 0; #if OPT_NUM_LOCK if (param > MOD_NONE) { if ((param - MOD_NONE) & MOD_SHIFT) UIntSet(result, ShiftMask); if ((param - MOD_NONE) & MOD_CTRL) UIntSet(result, ControlMask); if ((param - MOD_NONE) & MOD_ALT) UIntSet(result, xw->work.alt_mods); if ((param - MOD_NONE) & MOD_META) UIntSet(result, xw->work.meta_mods); } #else (void) xw; (void) param; #endif TRACE(("xtermParamToState(%d) %s%s%s%s -> %#x\n", param, MODIFIER_NAME(param, MOD_SHIFT), MODIFIER_NAME(param, MOD_ALT), MODIFIER_NAME(param, MOD_CTRL), MODIFIER_NAME(param, MOD_META), result)); return result; } unsigned xtermStateToParam(XtermWidget xw, unsigned state) { unsigned modify_parm = MOD_NONE; TRACE(("xtermStateToParam %#x\n", state)); #if OPT_NUM_LOCK if (state & ShiftMask) { modify_parm += MOD_SHIFT; UIntClr(state, ShiftMask); } if (state & ControlMask) { modify_parm += MOD_CTRL; UIntClr(state, ControlMask); } if ((state & xw->work.alt_mods) != 0) { modify_parm += MOD_ALT; UIntClr(state, xw->work.alt_mods); } if ((state & xw->work.meta_mods) != 0) { modify_parm += MOD_META; /* UIntClr(state, xw->work.meta_mods); */ } if (modify_parm == MOD_NONE) modify_parm = !xw->work.min_mod; #else (void) xw; (void) state; #endif TRACE(("...xtermStateToParam %d%s%s%s%s\n", modify_parm, MODIFIER_NAME(modify_parm, MOD_SHIFT), MODIFIER_NAME(modify_parm, MOD_ALT), MODIFIER_NAME(modify_parm, MOD_CTRL), MODIFIER_NAME(modify_parm, MOD_META))); return modify_parm; } #endif /* OPT_TCAP_FKEYS */ #define computeMaskedModifier(xw, state, mask) \ xtermStateToParam(xw, Masked(state, mask)) #if OPT_MOD_FKEYS #if OPT_NUM_LOCK static unsigned filterAltMeta(unsigned result, unsigned mask, Bool enable, KEY_DATA * kd) { if ((result & mask) != 0) { /* * metaSendsEscape makes the meta key independent of * modifyOtherKeys. */ if (enable) { result &= ~mask; } /* * A bare meta-modifier is independent of modifyOtherKeys. If it * is combined with other modifiers, make it depend. */ if ((result & ~(mask)) == 0) { result &= ~mask; } /* * Check for special cases of control+meta which are used by some * applications, e.g., emacs. */ if ((IsControlInput(kd) || IsControlOutput(kd)) && (result & ControlMask) != 0) { result &= ~(mask | ControlMask); } if (kd->keysym == XK_Return || kd->keysym == XK_Tab) { result &= ~(mask | ControlMask); } } return result; } #endif /* OPT_NUM_LOCK */ /* * Single characters (not function-keys) are allowed fewer modifiers when * interpreting modifyOtherKeys due to pre-existing associations with some * modifiers. */ static int allowedCharModifiers(XtermWidget xw, int state, KEY_DATA * kd) { /* * Start by limiting the result to the modifiers we might want to use. */ int result = (state >= 0 ? (int) ((unsigned) state & (ControlMask | ShiftMask | AltOrMeta(xw))) : -1); /* * If modifyOtherKeys is off or medium (0 or 1), moderate its effects by * excluding the common cases for modifiers. */ if (xw->keyboard.modify_now.other_keys <= mokUser) { if (IsControlInput(kd) && Masked(result, ControlMask) == 0) { /* These keys are already associated with the control-key */ if (xw->keyboard.modify_now.other_keys == mokNone) { SIntClr(result, ControlMask); } } else if (kd->keysym == XK_Tab || kd->keysym == XK_Return) { /* EMPTY */ ; } else if (IsControlAlias(kd)) { /* Things like "^_" work here... */ if (Masked(result, (ControlMask | ShiftMask)) == 0) { result = 0; } } else if (!IsControlOutput(kd) && !IsPredefinedKey(kd->keysym)) { /* Printable keys are already associated with the shift-key */ if (!((unsigned) result & ControlMask)) { SIntClr(result, ShiftMask); } } #if OPT_NUM_LOCK result = (int) filterAltMeta((unsigned) result, xw->work.meta_mods, TScreenOf(xw)->meta_sends_esc, kd); if (TScreenOf(xw)->alt_is_not_meta) { result = (int) filterAltMeta((unsigned) result, xw->work.alt_mods, TScreenOf(xw)->alt_sends_esc, kd); } #endif } /* * For an ordinary key, if the state has only one modified bit set and if * that is in the modify-modifiers mask, then disable the use of modifiers * for sending the key as an escape sequence. */ if (result != 0 && xw->keyboard.modify_now.other_keys > mokNone && (state & xw->keyboard.ignore_now.other_keys) != 0 && IsOrdinaryKey(xw, kd)) { unsigned check = (unsigned) state; while (check != 0) { if ((check & 1) != 0) { if (check == 1) result = 0; break; } check >>= 1; } } TRACE(("...allowedCharModifiers(state=%u" FMT_MODIFIER_NAMES ", ch=" KEYSYM_FMT ") ->" "%u" FMT_MODIFIER_NAMES "\n", state, ARG_MODIFIER_NAMES(state), kd->keysym, result, ARG_MODIFIER_NAMES(result))); return result; } /* * Decide if we should generate a special escape sequence for "other" keys * than cursor-, function-keys, etc., as per the modifyOtherKeys resource. */ static Bool ModifyOtherKeys(XtermWidget xw, int state, KEY_DATA * kd, unsigned modify_parm) { TKeyboard *keyboard = &(xw->keyboard); Bool result = False; /* * Exclude the keys already covered by a modifier. */ if (!IsOrdinaryKey(xw, kd)) { result = False; } else if (modify_parm >= (unsigned) xw->work.min_mod) { if (IsBackarrowToggle(keyboard, kd->keysym, state)) { kd->keysym = XK_Delete; SIntClr(state, ControlMask); } if (!IsPredefinedKey(kd->keysym)) { state = allowedCharModifiers(xw, state, kd); } if (state >= xw->work.min_mod) { switch (keyboard->modify_now.other_keys) { default: break; case mokUser: switch (kd->keysym) { case XK_BackSpace: case XK_Delete: result = False; break; #ifdef XK_ISO_Left_Tab case XK_ISO_Left_Tab: if (computeMaskedModifier(xw, state, ShiftMask)) result = True; break; #endif case XK_Return: case XK_Tab: result = (modify_parm != 0); break; default: if (IsControlInput(kd)) { if (state == ControlMask || state == ShiftMask) { result = False; } else { result = (modify_parm != 0); } } else if (IsControlAlias(kd)) { if (state == ShiftMask) result = False; else if (computeMaskedModifier(xw, state, ControlMask)) { result = True; } } else { result = True; } break; } break; case 2: switch (kd->keysym) { case XK_BackSpace: /* strip ControlMask as per IsBackarrowToggle() */ if (computeMaskedModifier(xw, state, ControlMask)) result = True; break; case XK_Delete: result = (xtermStateToParam(xw, (unsigned) state) != 0); break; #ifdef XK_ISO_Left_Tab case XK_ISO_Left_Tab: if (computeMaskedModifier(xw, state, ShiftMask)) result = True; break; #endif case XK_Escape: case XK_Return: case XK_Tab: result = (modify_parm != 0); break; default: if (IsControlInput(kd)) { result = True; } else if (state == ShiftMask && kd->keysym == ' ') { result = True; } else if (computeMaskedModifier(xw, state, ShiftMask)) { result = True; } break; } break; case 3: result = True; break; } } } TRACE(("...ModifyOtherKeys(%d,%d) %s\n", keyboard->modify_now.other_keys, modify_parm, BtoS(result))); return result; } #define APPEND_PARM(number) \ reply->a_param[reply->a_nparam] = (ParmType) number; \ reply->a_nparam++ /* * Function-key code 27 happens to not be used in the vt220-style encoding. * xterm uses this to represent modified non-function-keys such as control/+ in * the Sun/PC keyboard layout. See the modifyOtherKeys resource in the manpage * for more information. */ static Bool modifyOtherKey(ANSI *reply, int input_char, unsigned modify_parm, int format_keys) { Bool result = False; if (input_char >= 0) { reply->a_type = ANSI_CSI; if (!modify_parm) modify_parm = 1; if (format_keys) { APPEND_PARM(input_char); APPEND_PARM(modify_parm); reply->a_final = 'u'; } else { APPEND_PARM(27); APPEND_PARM(modify_parm); APPEND_PARM(input_char); reply->a_final = '~'; } result = True; } return result; } static void modifyCursorKey(ANSI *reply, int modify, unsigned *modify_parm) { if (*modify_parm != 0) { if (modify == mfkNone) { *modify_parm = 0; } if (modify >= mfkControl) { reply->a_type = ANSI_CSI; /* SS3 should not have params */ } if (modify >= mfkParam && reply->a_nparam == 0) { APPEND_PARM(1); /* force modifier to 2nd param */ } if (modify >= mfkPrivate) { reply->a_pintro = '>'; /* mark this as "private" */ } } } #else #define modifyCursorKey(reply, modify, parm) /* nothing */ #endif /* OPT_MOD_FKEYS */ #if OPT_SUNPC_KBD /* * If we have told xterm that our keyboard is really a Sun/PC keyboard, this is * enough to make a reasonable approximation to DEC vt220 numeric and editing * keypads. */ static KeySym TranslateFromSUNPC(KeySym keysym) { /* *INDENT-OFF* */ static struct { KeySym before, after; } table[] = { #ifdef DXK_Remove { XK_Delete, DXK_Remove }, #endif { XK_Home, XK_Find }, { XK_End, XK_Select }, #ifdef XK_KP_Home { XK_Delete, XK_KP_Decimal }, { XK_KP_Delete, XK_KP_Decimal }, { XK_KP_Insert, XK_KP_0 }, { XK_KP_End, XK_KP_1 }, { XK_KP_Down, XK_KP_2 }, { XK_KP_Next, XK_KP_3 }, { XK_KP_Left, XK_KP_4 }, { XK_KP_Begin, XK_KP_5 }, { XK_KP_Right, XK_KP_6 }, { XK_KP_Home, XK_KP_7 }, { XK_KP_Up, XK_KP_8 }, { XK_KP_Prior, XK_KP_9 }, #endif }; /* *INDENT-ON* */ unsigned n; for (n = 0; n < sizeof(table) / sizeof(table[0]); n++) { if (table[n].before == keysym) { TRACE(("...Input keypad before was " KEYSYM_FMT "\n", keysym)); keysym = table[n].after; TRACE(("...Input keypad changed to " KEYSYM_FMT "\n", keysym)); break; } } return keysym; } #endif /* OPT_SUNPC_KBD */ #define VT52_KEYPAD \ if_OPT_VT52_MODE(screen,{ \ reply.a_type = ANSI_ESC; \ reply.a_pintro = '?'; \ }) #define VT52_CURSOR_KEYS \ if_OPT_VT52_MODE(screen,{ \ reply.a_type = ANSI_ESC; \ }) #undef APPEND_PARM #define APPEND_PARM(number) \ reply.a_param[reply.a_nparam] = (ParmType) number, \ reply.a_nparam++ #if OPT_MOD_FKEYS #define MODIFIER_PARM \ if (modify_parm != 0) APPEND_PARM(modify_parm) #else #define MODIFIER_PARM /*nothing */ #endif /* * Determine if we use the \E[3~ sequence for Delete, or the legacy ^?. We * maintain the delete_is_del value as 3 states: unspecified(2), true and * false. If unspecified, it is handled differently according to whether the * legacy keyboard support is enabled, or if xterm emulates a VT220. * * Once the user (or application) has specified delete_is_del via resource * setting, popup menu or escape sequence, it overrides the keyboard type * rather than the reverse. */ Bool xtermDeleteIsDEL(XtermWidget xw) { Bool result = True; if (xw->keyboard.type == keyboardIsDefault || xw->keyboard.type == keyboardIsVT220) result = (TScreenOf(xw)->delete_is_del == True); if (xw->keyboard.type == keyboardIsLegacy) result = (TScreenOf(xw)->delete_is_del != False); TRACE(("xtermDeleteIsDEL(%d/%d) = %d\n", xw->keyboard.type, TScreenOf(xw)->delete_is_del, result)); return result; } static Boolean lookupKeyData(KEY_DATA * kd, XtermWidget xw, XKeyEvent *event) { TScreen *screen = TScreenOf(xw); Boolean result = True; #if OPT_INPUT_METHOD #if OPT_MOD_FKEYS TKeyboard *keyboard = &(xw->keyboard); #endif #endif (void) screen; TRACE(("lookupKeyData %s keycode 0x%04X\n", visibleEventType(event->type), event->keycode)); kd->keysym = 0; kd->is_fkey = False; #if OPT_TCAP_QUERY if (screen->tc_query_code >= 0) { kd->keysym = (KeySym) screen->tc_query_code; kd->is_fkey = screen->tc_query_fkey; if (kd->keysym != XK_BackSpace) { kd->nbytes = 0; kd->strbuf[0] = 0; } else if (kd->keysym > 0) { kd->nbytes = 1; kd->strbuf[0] = 8; } else { result = False; } } else #endif { #if OPT_INPUT_METHOD TInput *input = lookupTInput(xw, (Widget) xw); if (input && input->xic) { Status status_return; #if OPT_WIDE_CHARS if (screen->utf8_mode) { kd->nbytes = Xutf8LookupString(input->xic, event, kd->strbuf, (int) sizeof(kd->strbuf), &(kd->keysym), &status_return); } else #endif { kd->nbytes = XmbLookupString(input->xic, event, kd->strbuf, (int) sizeof(kd->strbuf), &(kd->keysym), &status_return); } #if OPT_MOD_FKEYS /* * Fill-in some code useful with IsControlAlias(): */ if (status_return == XLookupBoth && kd->nbytes <= 1 && !IsPredefinedKey(kd->keysym) && (keyboard->modify_now.other_keys > mokUser) && !IsControlInput(kd)) { kd->nbytes = 1; kd->strbuf[0] = (char) kd->keysym; } else if (kd->keysym <= 0) { result = False; } #endif /* OPT_MOD_FKEYS */ } else #endif /* OPT_INPUT_METHOD */ { static XComposeStatus compose_status = {NULL, 0}; kd->nbytes = XLookupString(event, kd->strbuf, (int) sizeof(kd->strbuf), &(kd->keysym), &compose_status); if (kd->keysym <= 0) result = False; } kd->is_fkey = IsFunctionKey(kd->keysym); } return result; } void Input(XtermWidget xw, XKeyEvent *event, Bool eightbit) { Char *string; TKeyboard *keyboard = &(xw->keyboard); TScreen *screen = TScreenOf(xw); int j; int key = False; ANSI reply; int dec_code; unsigned modify_parm = 0; int keypad_mode = ((keyboard->flags & MODE_DECKPAM) != 0); unsigned evt_state = event->state; KEY_DATA kd; #if OPT_MOD_FKEYS ModkeyModes keysymType; int mod_state; KEY_DATA kd_unmodified; Boolean use_unmodified = False; #endif /* Ignore characters typed at the keyboard */ if (keyboard->flags & MODE_KAM) return; lookupKeyData(&kd, xw, event); #if OPT_MOD_FKEYS SET_MIN_MOD(xw, keyboard->modify_now.other_keys); kd_unmodified = kd; keysymType = TypeOfKeysym(xw, &kd); if (keyboard->modify_now.other_keys >= mokUser) { XKeyEvent event2 = *event; event2.state &= (unsigned) ~(keyboard->ignore_now.other_keys); if (lookupKeyData(&kd_unmodified, xw, &event2)) { TRACE(("may use unmodified 0x%04lX vs 0x%04lX\n", kd_unmodified.keysym, kd.keysym)); use_unmodified = True; } } #endif memset(&reply, 0, sizeof(reply)); TRACE(("Input(%d,%d) keysym " KEYSYM_FMT ", %d:'%s'%s" FMT_MODIFIER_NAMES "%s%s%s%s%s%s: %s\n", screen->cur_row, screen->cur_col, kd.keysym, kd.nbytes, visibleChars((Char *) kd.strbuf, ((kd.nbytes > 0) ? (unsigned) kd.nbytes : 0)), ARG_MODIFIER_NAMES(evt_state), eightbit ? " 8bit" : " 7bit", IsKeypadKey(kd.keysym) ? " KeypadKey" : "", IsCursorKey(kd.keysym) ? " CursorKey" : "", IsPFKey(kd.keysym) ? " PFKey" : "", kd.is_fkey ? " FKey" : "", IsMiscFunctionKey(kd.keysym) ? " MiscFKey" : "", IsEditFunctionKey(xw, kd.keysym) ? " EditFkey" : "", visibleModkeyModes(keysymType))); /* * The extended mode for cursor/function/keypad keys bypasses other checks. */ #if OPT_MOD_FKEYS #define CHECK(res,mod) \ ((keysymType == res \ && keyboard->modify_now.mod >= mfkExtended)) if (CHECK(modifyCursorKeys, cursor_keys) || CHECK(modifyFunctionKeys, function_keys) || CHECK(modifyKeypadKeys, keypad_keys) || CHECK(modifyModifierKeys, modify_keys) || CHECK(modifySpecialKeys, special_keys)) { int input_char = (int) keysym2ucs(kd_unmodified.keysym); int format = (keysymType == modifyCursorKeys ? keyboard->format_now.cursor_keys : (keysymType == modifyFunctionKeys ? keyboard->format_now.function_keys : (keysymType == modifyKeypadKeys ? keyboard->format_now.keypad_keys : (keysymType == modifyModifierKeys ? keyboard->format_now.modify_keys : keyboard->format_now.special_keys)))); modify_parm = xtermStateToParam(xw, evt_state); if (modifyOtherKey(&reply, input_char, modify_parm, format)) { unparseseq(xw, &reply); unparse_end(xw); } return; } #undef CHECK #endif #if OPT_SUNPC_KBD /* * DEC keyboards don't have keypad(+), but do have keypad(,) instead. * Other (Sun, PC) keyboards commonly have keypad(+), but no keypad(,) * - it's a pain for users to work around. */ if (keyboard->type == keyboardIsVT220 && (evt_state & ShiftMask) == 0) { if (kd.keysym == XK_KP_Add) { kd.keysym = XK_KP_Separator; UIntClr(evt_state, ShiftMask); TRACE(("...Input keypad(+), change keysym to " KEYSYM_FMT "\n", kd.keysym)); } if ((evt_state & ControlMask) != 0 && kd.keysym == XK_KP_Separator) { kd.keysym = XK_KP_Subtract; UIntClr(evt_state, ControlMask); TRACE(("...Input control/keypad(,), change keysym to " KEYSYM_FMT "\n", kd.keysym)); } } #endif /* * The keyboard tables may give us different keypad codes according to * whether NumLock is pressed. Use this check to simplify the process * of determining whether we generate an escape sequence for a keypad * key, or force it to the value kypd_num[]. There is no fixed * modifier for this feature, so we assume that it is the one assigned * to the NumLock key. * * This check used to try to return the contents of strbuf, but that * does not work properly when a control modifier is given (trash is * returned in the buffer in some cases -- perhaps an X bug). */ #if OPT_NUM_LOCK if (kd.nbytes == 1 && IsKeypadKey(kd.keysym) && xw->misc.real_NumLock && (xw->work.num_lock & evt_state) != 0) { keypad_mode = 0; TRACE(("...Input num_lock, force keypad_mode off\n")); } #endif #if OPT_MOD_FKEYS if (evt_state != 0 && allowModifierParm(xw, &kd)) { modify_parm = xtermStateToParam(xw, evt_state); } /* * Shift-tab is often mapped to XK_ISO_Left_Tab which is classified as * IsEditFunctionKey(), and the conversion does not produce any bytes. * Check for this special case so we have data when handling the * modifyOtherKeys resource. */ if (keyboard->modify_now.other_keys > mokUser) { if (IsTabKey(kd.keysym) && kd.nbytes == 0) { kd.nbytes = 1; kd.strbuf[0] = '\t'; } } #ifdef XK_ISO_Left_Tab else if (IsTabKey(kd.keysym) && kd.nbytes <= 1) { if (allowModifierParm(xw, &kd)) { if (modify_parm == (MOD_NONE + MOD_SHIFT)) { kd.keysym = XK_ISO_Left_Tab; } } else if (evt_state & ShiftMask) { kd.keysym = XK_ISO_Left_Tab; } } #endif #endif /* OPT_MOD_FKEYS */ /* VT300 & up: backarrow toggle */ if ((kd.nbytes == 1) && IsBackarrowToggle(keyboard, kd.keysym, evt_state)) { kd.strbuf[0] = ANSI_DEL; TRACE(("...Input backarrow changed to %d\n", kd.strbuf[0])); } #if OPT_SUNPC_KBD /* make an DEC editing-keypad from a Sun or PC editing-keypad */ if (keyboard->type == keyboardIsVT220 && (kd.keysym != XK_Delete || !xtermDeleteIsDEL(xw))) kd.keysym = TranslateFromSUNPC(kd.keysym); else #endif { #ifdef XK_KP_Home if (kd.keysym >= XK_KP_Home && kd.keysym <= XK_KP_Begin) { TRACE(("...Input keypad before was " KEYSYM_FMT "\n", kd.keysym)); kd.keysym += (KeySym) (XK_Home - XK_KP_Home); TRACE(("...Input keypad changed to " KEYSYM_FMT "\n", kd.keysym)); } #endif } /* * Map the Sun afterthought-keys in as F36 and F37. */ #ifdef SunXK_F36 if (!kd.is_fkey) { if (kd.keysym == SunXK_F36) { kd.keysym = XK_Fn(36); kd.is_fkey = True; } if (kd.keysym == SunXK_F37) { kd.keysym = XK_Fn(37); kd.is_fkey = True; } } #endif #if OPT_TRACE #define TRACE_FK(prefix) \ if ((kd.keysym >= XK_Fn(1) && kd.keysym <= XK_Fn(24))) \ TRACE((prefix " XK_F%ld\n", kd.keysym - XK_Fn(1) + 1)); \ else \ TRACE((prefix " keysym %04X\n", (unsigned) kd.keysym)) #else #define TRACE_FK(prefix) /* nothing */ #endif /* * Use the control- and shift-modifiers to obtain more function keys than * the keyboard provides. We can do this if there is no conflicting use of * those modifiers: * * a) for VT220 keyboard, we use only the control-modifier. The keyboard * uses shift-modifier for UDK's. * * b) for non-VT220 keyboards, we only have to check if the * modifyFunctionKeys resource is inactive. * * Thereafter, we note when we have a function-key and keep that * distinction when testing for "function-key" values. */ if ((evt_state & (ControlMask | ShiftMask)) != 0 && kd.is_fkey) { /* VT220 keyboard uses shift for UDK */ if (keyboard->type == keyboardIsVT220 || keyboard->type == keyboardIsLegacy) { TRACE_FK("...map"); if (evt_state & ControlMask) { kd.keysym += (KeySym) xw->misc.ctrl_fkeys; UIntClr(evt_state, ControlMask); } TRACE_FK(" to"); } #if OPT_MOD_FKEYS else if (keyboard->modify_now.function_keys == mfkNone) { TRACE_FK("...map"); if (evt_state & ShiftMask) { kd.keysym += (KeySym) (xw->misc.ctrl_fkeys * 1); UIntClr(evt_state, ShiftMask); } if (evt_state & ControlMask) { kd.keysym += (KeySym) (xw->misc.ctrl_fkeys * 2); UIntClr(evt_state, ControlMask); } TRACE_FK(" to"); } /* * Reevaluate the modifier parameter, stripping off the modifiers * that we just used. */ if (modify_parm) { modify_parm = xtermStateToParam(xw, evt_state); } #endif /* OPT_MOD_FKEYS */ } /* * Test for one of the keyboard variants. */ switch (keyboard->type) { case keyboardIsHP: hpfuncvalue(&reply, &kd); break; case keyboardIsSCO: scofuncvalue(&reply, &kd); break; case keyboardIsSun: sunfuncvalue(&reply, &kd); break; case keyboardIsTermcap: #if OPT_TCAP_FKEYS if (xtermcapString(xw, (int) kd.keysym, evt_state)) return; #endif break; case keyboardIsDefault: case keyboardIsLegacy: case keyboardIsVT220: break; } #if OPT_MOD_FKEYS if (reply.a_final) { /* * The key symbol matches one of the variants. Most of those are * function-keys, though some cursor- and editing-keys are mixed in. */ modifyCursorKey(&reply, ((kd.is_fkey || IsMiscFunctionKey(kd.keysym) || IsEditFunctionKey(xw, kd.keysym)) ? keyboard->modify_now.function_keys : keyboard->modify_now.cursor_keys), &modify_parm); MODIFIER_PARM; unparseseq(xw, &reply); } else #endif /* OPT_MOD_FKEYS */ if (((kd.is_fkey || IsMiscFunctionKey(kd.keysym) || IsEditFunctionKey(xw, kd.keysym)) #if OPT_MOD_FKEYS && !ModifyOtherKeys(xw, (int) evt_state, &kd, modify_parm) #endif ) || (kd.keysym == XK_Delete && ((modify_parm != 0) || !xtermDeleteIsDEL(xw)))) { dec_code = decfuncvalue(&kd); if ((evt_state & ShiftMask) #if OPT_SUNPC_KBD && keyboard->type == keyboardIsVT220 #endif && ((string = (Char *) udk_lookup(xw, dec_code, &kd.nbytes)) != NULL)) { /* UIntClr(evt_state, ShiftMask); */ while (kd.nbytes-- > 0) unparseputc(xw, CharOf(*string++)); } /* * Interpret F1-F4 as PF1-PF4 for VT52, VT100 */ else if (keyboard->type != keyboardIsLegacy && (dec_code >= 11 && dec_code <= 14)) { reply.a_type = ANSI_SS3; VT52_CURSOR_KEYS; reply.a_final = (Char) (dec_code - 11 + 'P'); modifyCursorKey(&reply, keyboard->modify_now.function_keys, &modify_parm); MODIFIER_PARM; unparseseq(xw, &reply); } else { reply.a_type = ANSI_CSI; reply.a_final = 0; #ifdef XK_ISO_Left_Tab if (kd.keysym == XK_ISO_Left_Tab) { reply.a_nparam = 0; reply.a_final = 'Z'; #if OPT_MOD_FKEYS if (keyboard->modify_now.other_keys > mokUser && computeMaskedModifier(xw, evt_state, ShiftMask)) modifyOtherKey(&reply, '\t', modify_parm, keyboard->format_now.other_keys); #endif } else #endif /* XK_ISO_Left_Tab */ { reply.a_nparam = 1; #if OPT_MOD_FKEYS if (kd.is_fkey) { modifyCursorKey(&reply, keyboard->modify_now.function_keys, &modify_parm); } MODIFIER_PARM; #endif reply.a_param[0] = (ParmType) dec_code; reply.a_final = '~'; } if (reply.a_nparam == 0 || reply.a_param[0] >= 0) unparseseq(xw, &reply); } key = True; } else if (IsPFKey(kd.keysym)) { reply.a_type = ANSI_SS3; reply.a_final = (Char) ((kd.keysym - XK_KP_F1) + 'P'); VT52_CURSOR_KEYS; MODIFIER_PARM; unparseseq(xw, &reply); key = True; } else if (IsKeypadKey(kd.keysym)) { if (keypad_mode) { reply.a_type = ANSI_SS3; reply.a_final = (Char) (kypd_apl[kd.keysym - XK_KP_Space]); VT52_KEYPAD; MODIFIER_PARM; unparseseq(xw, &reply); } else { unparseputc(xw, kypd_num[kd.keysym - XK_KP_Space]); } key = True; } else if (IsCursorKey(kd.keysym)) { if (keyboard->flags & MODE_DECCKM) { reply.a_type = ANSI_SS3; } else { reply.a_type = ANSI_CSI; } modifyCursorKey(&reply, keyboard->modify_now.cursor_keys, &modify_parm); reply.a_final = (Char) (curfinal[kd.keysym - XK_Home]); VT52_CURSOR_KEYS; MODIFIER_PARM; unparseseq(xw, &reply); key = True; } else if (kd.nbytes > 0) { #if OPT_TEK4014 if (TEK4014_GIN(tekWidget)) { TekEnqMouse(tekWidget, kd.strbuf[0]); TekGINoff(tekWidget); kd.nbytes--; for (j = 0; j < kd.nbytes; ++j) { kd.strbuf[j] = kd.strbuf[j + 1]; } } #endif #if OPT_MOD_FKEYS mod_state = (int) evt_state; if ((keyboard->modify_now.other_keys > mokNone) && ModifyOtherKeys(xw, mod_state, &kd, modify_parm) && (mod_state = allowedCharModifiers(xw, mod_state, &kd)) >= xw->work.min_mod) { int input_char; if (use_unmodified) kd.keysym = kd_unmodified.keysym; evt_state = (unsigned) mod_state; modify_parm = xtermStateToParam(xw, evt_state); /* * We want to show a keycode that corresponds to the 8-bit value * of the key. If the keysym is less than 256, that is good * enough. Special keys such as Tab may result in a value that * is usable as well. For the latter (special cases), try to use * the result from the X library lookup. */ input_char = ((kd.keysym < 256) ? (int) kd.keysym : ((kd.nbytes == 1) ? CharOf(kd.strbuf[0]) : -1)); /* * If we failed to find an 8-bit (Latin1 or ASCII) value, use the * UCS value corresponding to the keysym. */ if (input_char == -1) { long codepoint = keysym2ucs(kd.keysym); if (codepoint > 0x7E) { TRACE(("...using keysym2ucs(%#lx) = U+%04lX\n", kd.keysym, codepoint)); input_char = (int) codepoint; } } TRACE(("...modifyOtherKeys %d;%d\n", modify_parm, input_char)); if (modifyOtherKey(&reply, input_char, modify_parm, keyboard->format_now.other_keys)) { unparseseq(xw, &reply); } else { Bell(xw, XkbBI_MinorError, 0); } } else #endif /* OPT_MOD_FKEYS */ { int prefix = 0; #if OPT_NUM_LOCK /* * Send ESC if we have a META modifier and metaSendsEcape is true. * Like eightBitInput, except that it is not associated with * terminal settings. */ if (kd.nbytes != 0) { if (screen->meta_sends_esc && (evt_state & xw->work.meta_mods) != 0) { TRACE(("...input-char is modified by META\n")); UIntClr(evt_state, xw->work.meta_mods); eightbit = False; prefix = ANSI_ESC; } else if (eightbit) { /* it might be overridden, but this helps for debugging */ TRACE(("...input-char is shifted by META\n")); } if (screen->alt_is_not_meta && (evt_state & xw->work.alt_mods) != 0) { UIntClr(evt_state, xw->work.alt_mods); if (screen->alt_sends_esc) { TRACE(("...input-char is modified by ALT\n")); eightbit = False; prefix = ANSI_ESC; } else if (!eightbit) { TRACE(("...input-char is shifted by ALT\n")); eightbit = True; } } } #endif /* * If metaSendsEscape is false, fall through to this chunk, which * implements the eightBitInput resource. * * It is normally executed when the user presses Meta plus a * printable key, e.g., Meta+space. The presence of the Meta * modifier is not guaranteed since what really happens is the * "insert-eight-bit" or "insert-seven-bit" action, which we * distinguish by the eightbit parameter to this function. So the * eightBitInput resource really means that we use this shifting * logic in the "insert-eight-bit" action. */ if (eightbit && (kd.nbytes == 1) && screen->input_eight_bits) { IChar ch = CharOf(kd.strbuf[0]); if ((ch < 128) && (screen->eight_bit_meta == ebTrue)) { kd.strbuf[0] |= (char) 0x80; TRACE(("...input shift from %d to %d (%#x to %#x)\n", ch, CharOf(kd.strbuf[0]), ch, CharOf(kd.strbuf[0]))); #if OPT_WIDE_CHARS if (screen->utf8_mode) { /* * We could interpret the incoming code as "in the * current locale", but it's simpler to treat it as * a Unicode value to translate to UTF-8. */ ch = CharOf(kd.strbuf[0]); kd.nbytes = 2; kd.strbuf[0] = (char) (0xc0 | ((ch >> 6) & 0x3)); kd.strbuf[1] = (char) (0x80 | (ch & 0x3f)); TRACE(("...encoded %#x in UTF-8 as %#x,%#x\n", ch, CharOf(kd.strbuf[0]), CharOf(kd.strbuf[1]))); } #endif } eightbit = False; } #if OPT_WIDE_CHARS if (kd.nbytes == 1) /* cannot do NRC on UTF-8, for instance */ #endif { /* VT220 & up: National Replacement Characters */ if ((xw->flags & NATIONAL) != 0) { unsigned cmp = xtermCharSetIn(xw, CharOf(kd.strbuf[0]), (DECNRCM_codes) screen->keyboard_dialect[0]); TRACE(("...input NRC %d, %s %d\n", CharOf(kd.strbuf[0]), (CharOf(kd.strbuf[0]) == cmp) ? "unchanged" : "changed to", CharOf(cmp))); kd.strbuf[0] = (char) cmp; } else if (eightbit) { prefix = ANSI_ESC; } else if (kd.strbuf[0] == '?' && (evt_state & ControlMask) != 0) { kd.strbuf[0] = ANSI_DEL; } } if (prefix != 0) unparseputc(xw, prefix); /* escape */ for (j = 0; j < kd.nbytes; ++j) unparseputc(xw, CharOf(kd.strbuf[j])); } key = ((kd.keysym != ANSI_XOFF) && (kd.keysym != ANSI_XON)); } unparse_end(xw); if (key && !TEK4014_ACTIVE(xw)) AdjustAfterInput(xw); xtermShowPointer(xw, False); return; } void StringInput(XtermWidget xw, const Char *string, size_t nbytes) { TRACE(("InputString (%s,%lu)\n", visibleChars(string, (unsigned) nbytes), (unsigned long) nbytes)); #if OPT_TEK4014 if (nbytes && TEK4014_GIN(tekWidget)) { TekEnqMouse(tekWidget, *string++); TekGINoff(tekWidget); nbytes--; } #endif while (nbytes-- != 0) unparseputc(xw, *string++); if (!TEK4014_ACTIVE(xw)) AdjustAfterInput(xw); unparse_end(xw); } /* These definitions are DEC-style (e.g., vt320) */ static int decfuncvalue(KEY_DATA * kd) { int result; if (kd->is_fkey) { switch (kd->keysym) { MAP(XK_Fn(1), 11); MAP(XK_Fn(2), 12); MAP(XK_Fn(3), 13); MAP(XK_Fn(4), 14); MAP(XK_Fn(5), 15); MAP(XK_Fn(6), 17); MAP(XK_Fn(7), 18); MAP(XK_Fn(8), 19); MAP(XK_Fn(9), 20); MAP(XK_Fn(10), 21); MAP(XK_Fn(11), 23); MAP(XK_Fn(12), 24); MAP(XK_Fn(13), 25); MAP(XK_Fn(14), 26); MAP(XK_Fn(15), 28); MAP(XK_Fn(16), 29); MAP(XK_Fn(17), 31); MAP(XK_Fn(18), 32); MAP(XK_Fn(19), 33); MAP(XK_Fn(20), 34); default: /* after F20 the codes are made up and do not correspond to any * real terminal. So they are simply numbered sequentially. */ result = 42 + (int) (kd->keysym - XK_Fn(21)); break; } } else { switch (kd->keysym) { MAP(XK_Find, 1); MAP(XK_Insert, 2); MAP(XK_Delete, 3); #ifdef XK_KP_Insert MAP(XK_KP_Insert, 2); MAP(XK_KP_Delete, 3); #endif #ifdef DXK_Remove MAP(DXK_Remove, 3); #endif MAP(XK_Select, 4); MAP(XK_Prior, 5); MAP(XK_Next, 6); MAP(XK_Help, 28); MAP(XK_Menu, 29); default: result = -1; break; } } return result; } static void hpfuncvalue(ANSI *reply, KEY_DATA * kd) { #if OPT_HP_FUNC_KEYS int result; if (kd->is_fkey) { switch (kd->keysym) { MAP(XK_Fn(1), 'p'); MAP(XK_Fn(2), 'q'); MAP(XK_Fn(3), 'r'); MAP(XK_Fn(4), 's'); MAP(XK_Fn(5), 't'); MAP(XK_Fn(6), 'u'); MAP(XK_Fn(7), 'v'); MAP(XK_Fn(8), 'w'); default: result = -1; break; } } else { switch (kd->keysym) { MAP(XK_Up, 'A'); MAP(XK_Down, 'B'); MAP(XK_Right, 'C'); MAP(XK_Left, 'D'); MAP(XK_End, 'F'); MAP(XK_Clear, 'J'); MAP(XK_Delete, 'P'); MAP(XK_Insert, 'Q'); MAP(XK_Next, 'S'); MAP(XK_Prior, 'T'); MAP(XK_Home, 'h'); #ifdef XK_KP_Insert MAP(XK_KP_Delete, 'P'); MAP(XK_KP_Insert, 'Q'); #endif #ifdef DXK_Remove MAP(DXK_Remove, 'P'); #endif MAP(XK_Select, 'F'); MAP(XK_Find, 'h'); default: result = -1; break; } } if (result > 0) { reply->a_type = ANSI_ESC; reply->a_final = (Char) result; } #else (void) reply; (void) kd; #endif /* OPT_HP_FUNC_KEYS */ } static void scofuncvalue(ANSI *reply, KEY_DATA * kd) { #if OPT_SCO_FUNC_KEYS int result; if (kd->is_fkey) { switch (kd->keysym) { MAP(XK_Fn(1), 'M'); MAP(XK_Fn(2), 'N'); MAP(XK_Fn(3), 'O'); MAP(XK_Fn(4), 'P'); MAP(XK_Fn(5), 'Q'); MAP(XK_Fn(6), 'R'); MAP(XK_Fn(7), 'S'); MAP(XK_Fn(8), 'T'); MAP(XK_Fn(9), 'U'); MAP(XK_Fn(10), 'V'); MAP(XK_Fn(11), 'W'); MAP(XK_Fn(12), 'X'); MAP(XK_Fn(13), 'Y'); MAP(XK_Fn(14), 'Z'); MAP(XK_Fn(15), 'a'); MAP(XK_Fn(16), 'b'); MAP(XK_Fn(17), 'c'); MAP(XK_Fn(18), 'd'); MAP(XK_Fn(19), 'e'); MAP(XK_Fn(20), 'f'); MAP(XK_Fn(21), 'g'); MAP(XK_Fn(22), 'h'); MAP(XK_Fn(23), 'i'); MAP(XK_Fn(24), 'j'); MAP(XK_Fn(25), 'k'); MAP(XK_Fn(26), 'l'); MAP(XK_Fn(27), 'm'); MAP(XK_Fn(28), 'n'); MAP(XK_Fn(29), 'o'); MAP(XK_Fn(30), 'p'); MAP(XK_Fn(31), 'q'); MAP(XK_Fn(32), 'r'); MAP(XK_Fn(33), 's'); MAP(XK_Fn(34), 't'); MAP(XK_Fn(35), 'u'); MAP(XK_Fn(36), 'v'); MAP(XK_Fn(37), 'w'); MAP(XK_Fn(38), 'x'); MAP(XK_Fn(39), 'y'); MAP(XK_Fn(40), 'z'); MAP(XK_Fn(41), '@'); MAP(XK_Fn(42), '['); MAP(XK_Fn(43), '\\'); MAP(XK_Fn(44), ']'); MAP(XK_Fn(45), '^'); MAP(XK_Fn(46), '_'); MAP(XK_Fn(47), '`'); MAP(XK_Fn(48), L_CURL); default: result = -1; break; } } else { switch (kd->keysym) { MAP(XK_Up, 'A'); MAP(XK_Down, 'B'); MAP(XK_Right, 'C'); MAP(XK_Left, 'D'); MAP(XK_Begin, 'E'); MAP(XK_End, 'F'); MAP(XK_Insert, 'L'); MAP(XK_Next, 'G'); MAP(XK_Prior, 'I'); MAP(XK_Home, 'H'); #ifdef XK_KP_Insert MAP(XK_KP_Insert, 'L'); #endif default: result = -1; break; } } if (result > 0) { reply->a_type = ANSI_CSI; reply->a_final = (Char) result; } #else (void) reply; (void) kd; #endif /* OPT_SCO_FUNC_KEYS */ } static void sunfuncvalue(ANSI *reply, KEY_DATA * kd) { #if OPT_SUN_FUNC_KEYS ParmType result; if (kd->is_fkey) { switch (kd->keysym) { /* kf1-kf20 are numbered sequentially */ MAP(XK_Fn(1), 224); MAP(XK_Fn(2), 225); MAP(XK_Fn(3), 226); MAP(XK_Fn(4), 227); MAP(XK_Fn(5), 228); MAP(XK_Fn(6), 229); MAP(XK_Fn(7), 230); MAP(XK_Fn(8), 231); MAP(XK_Fn(9), 232); MAP(XK_Fn(10), 233); MAP(XK_Fn(11), 192); MAP(XK_Fn(12), 193); MAP(XK_Fn(13), 194); MAP(XK_Fn(14), 195); /* kund */ MAP(XK_Fn(15), 196); MAP(XK_Fn(16), 197); /* kcpy */ MAP(XK_Fn(17), 198); MAP(XK_Fn(18), 199); MAP(XK_Fn(19), 200); /* kfnd */ MAP(XK_Fn(20), 201); /* kf31-kf36 are numbered sequentially */ MAP(XK_Fn(21), 208); /* kf31 */ MAP(XK_Fn(22), 209); MAP(XK_Fn(23), 210); MAP(XK_Fn(24), 211); MAP(XK_Fn(25), 212); MAP(XK_Fn(26), 213); /* kf36 */ /* kf37-kf47 are interspersed with keypad keys */ MAP(XK_Fn(27), 214); /* khome */ MAP(XK_Fn(28), 215); /* kf38 */ MAP(XK_Fn(29), 216); /* kpp */ MAP(XK_Fn(30), 217); /* kf40 */ MAP(XK_Fn(31), 218); /* kb2 */ MAP(XK_Fn(32), 219); /* kf42 */ MAP(XK_Fn(33), 220); /* kend */ MAP(XK_Fn(34), 221); /* kf44 */ MAP(XK_Fn(35), 222); /* knp */ MAP(XK_Fn(36), 234); /* kf46 */ MAP(XK_Fn(37), 235); /* kf47 */ default: result = -1; break; } } else { switch (kd->keysym) { MAP(XK_Help, 196); /* khlp */ MAP(XK_Menu, 197); MAP(XK_Find, 1); MAP(XK_Insert, 2); /* kich1 */ MAP(XK_Delete, 3); #ifdef XK_KP_Insert MAP(XK_KP_Insert, 2); MAP(XK_KP_Delete, 3); #endif #ifdef DXK_Remove MAP(DXK_Remove, 3); #endif MAP(XK_Select, 4); MAP(XK_Prior, 216); MAP(XK_Next, 222); MAP(XK_Home, 214); MAP(XK_End, 220); MAP(XK_Begin, 218); /* kf41=kb2 */ default: result = -1; break; } } if (result > 0) { reply->a_type = ANSI_CSI; reply->a_nparam = 1; reply->a_param[0] = result; reply->a_final = 'z'; } else if (IsCursorKey(kd->keysym)) { reply->a_type = ANSI_SS3; reply->a_final = (Char) curfinal[kd->keysym - XK_Home]; } #else (void) reply; (void) kd; #endif /* OPT_SUN_FUNC_KEYS */ } #if OPT_NUM_LOCK #define isName(c) ((c) == '_' || (c) == '-' || isalnum(CharOf(c))) static const char * skipName(const char *s) { while (*s != '\0' && isName(CharOf(*s))) ++s; return s; } /* * Found a ":" in a translation, check what is past it to see if it contains * any of the insert-text action names. */ static Boolean keyCanInsert(const char *parse) { Boolean result = False; Boolean escape = False; Boolean quoted = False; static const char *const table[] = { "insert", "insert-seven-bit", "insert-eight-bit", "string", }; Cardinal n; while (*parse != '\0' && *parse != '\n') { int ch = CharOf(*parse++); if (escape) { escape = False; } else if (ch == '\\') { escape = True; } else if (ch == '"') { quoted = (Boolean) !quoted; } else if (!quoted && isName(ch)) { const char *next = skipName(--parse); size_t need = (size_t) (next - parse); for (n = 0; n < XtNumber(table); ++n) { if (need == strlen(table[n]) && !strncmp(parse, table[n], need)) { result = True; break; } } parse = next; } } return result; } /* * Strip the entire action, to avoid matching it. */ static char * stripAction(const char *base, char *last) { while (last != base) { if (*--last == '\n') { break; } } return last; } static char * stripBlanks(const char *base, char *last) { while (last != base) { int ch = CharOf(last[-1]); if (ch != ' ' && ch != '\t') break; --last; } return last; } /* * Strip unneeded whitespace from a translations resource, mono-casing and * returning a malloc'd copy of the result. */ static char * stripTranslations(const char *s, Bool onlyInsert) { char *dst = NULL; if (s != NULL) { dst = TypeMallocN(char, strlen(s) + 1); if (dst != NULL) { int state = 0; int prv = 0; char *d = dst; TRACE(("stripping:\n%s\n", s)); while (*s != '\0') { int ch = *s++; if (ch == '\n') { if (d != dst) *d++ = (char) ch; state = 0; } else if (strchr(":!#", ch) != NULL) { d = stripBlanks(dst, d); if (onlyInsert && (ch == ':') && !keyCanInsert(s)) { d = stripAction(dst, d); } state = -1; } else if (state >= 0) { if (isspace(CharOf(ch))) { if (state == 0 || strchr("<>~ \t", prv)) continue; } else if (strchr("<>~", ch)) { d = stripBlanks(dst, d); } *d++ = x_toupper(ch); ++state; } prv = ch; } *d = '\0'; TRACE(("...result:\n%s\n", dst)); } } return dst; } /* * Make a simple check to see if a given translations keyword appears in * xterm's translations resource. It does not attempt to parse the strings, * just makes a case-independent check and ensures that the ends of the match * are on token-boundaries. * * That this can only retrieve translations that are given as resource values; * the default translations in charproc.c for example are not retrievable by * any interface to X. * * Also: We can retrieve only the most-specified translation resource. For * example, if the resource file specifies both "*translations" and * "XTerm*translations", we see only the latter. */ static Bool TranslationsUseKeyword(Widget w, char **cache, const char *keyword, Bool onlyInsert) { Bool result = False; char *copy; char *test; if ((test = stripTranslations(keyword, onlyInsert)) != NULL) { if (*cache == NULL) { String data = NULL; getKeymapResources(w, "vt100", "VT100", XtRString, &data, sizeof(data)); if (data != NULL && (copy = stripTranslations(data, onlyInsert)) != NULL) { *cache = copy; } } if (*cache != NULL) { char *p = *cache; int state = 0; int now = ' '; while (*p != 0) { int prv = now; now = *p++; if (now == ':' || now == '!') { state = -1; } else if (now == '\n') { state = 0; } else if (state >= 0) { if (now == test[state]) { if ((state != 0 || !isName(prv)) && ((test[++state] == 0) && !isName(*p))) { result = True; break; } } else { state = 0; } } } } free(test); } TRACE(("TranslationsUseKeyword(%p, %s) = %d\n", (void *) w, keyword, result)); return result; } static Bool xtermHasTranslation(XtermWidget xw, const char *keyword, Bool onlyInsert) { return (TranslationsUseKeyword(SHELL_OF(xw), &(xw->keyboard.shell_translations), keyword, onlyInsert) || TranslationsUseKeyword((Widget) xw, &(xw->keyboard.xterm_translations), keyword, onlyInsert)); } #if OPT_EXTRA_PASTE && (defined(XF86XK_Paste) || defined(SunXK_Paste)) static void addTranslation(XtermWidget xw, const char *fromString, const char *toString) { size_t have = (xw->keyboard.extra_translations ? strlen(xw->keyboard.extra_translations) : 0); size_t need = (((have != 0) ? (have + 4) : 0) + strlen(fromString) + strlen(toString) + 6); if (!xtermHasTranslation(xw, fromString, False)) { xw->keyboard.extra_translations = TypeRealloc(char, need, xw->keyboard.extra_translations); if ((xw->keyboard.extra_translations) != NULL) { TRACE(("adding %s: %s\n", fromString, toString)); if (have) strcat(xw->keyboard.extra_translations, " \\n\\"); sprintf(xw->keyboard.extra_translations, "%s: %s", fromString, toString); TRACE(("...{%s}\n", xw->keyboard.extra_translations)); } } } #endif #define SaveMask(name) xw->work.name |= (unsigned) mask;\ TRACE(("SaveMask(%#x -> %s) %#x (%#x is%s modifier)\n", \ (unsigned) keysym, #name, \ xw->work.name, (unsigned) mask, \ ModifierName((unsigned) mask))); /* * Determine which modifier mask (if any) applies to the Num_Lock keysym. * * Also, determine which modifiers are associated with the ALT keys, so we can * send that information as a parameter for special keys in Sun/PC keyboard * mode. However, if the ALT modifier is used in translations, we do not want * to confuse things by sending the parameter. */ void VTInitModifiers(XtermWidget xw) { Display *dpy = XtDisplay(xw); XModifierKeymap *keymap = XGetModifierMapping(dpy); KeySym keysym; int min_keycode, max_keycode, keysyms_per_keycode = 0; if (keymap != NULL) { KeySym *theMap; int keycode_count; TRACE(("VTInitModifiers\n")); XDisplayKeycodes(dpy, &min_keycode, &max_keycode); keycode_count = (max_keycode - min_keycode + 1); theMap = XGetKeyboardMapping(dpy, (KeyCode) min_keycode, keycode_count, &keysyms_per_keycode); if (theMap != NULL) { int i, j, k, l; unsigned long mask; #if OPT_EXTRA_PASTE /* * Assume that if we can find the paste keysym in the X keyboard * mapping that the server allows the corresponding translations * resource. */ int limit = (max_keycode - min_keycode) * keysyms_per_keycode; for (i = 0; i < limit; ++i) { #ifdef XF86XK_Paste if (theMap[i] == XF86XK_Paste) { TRACE(("keyboard has XF86XK_Paste\n")); addTranslation(xw, ": XF86Paste", "insert-selection(SELECT, CUT_BUFFER0)"); } #endif #ifdef SunXK_Paste if (theMap[i] == SunXK_Paste) { TRACE(("keyboard has SunXK_Paste\n")); addTranslation(xw, ": SunPaste", "insert-selection(SELECT, CUT_BUFFER0)"); } #endif } #endif /* OPT_EXTRA_PASTE */ for (i = k = 0, mask = 1; i < 8; i++, mask <<= 1) { for (j = 0; j < keymap->max_keypermod; j++) { KeyCode code = keymap->modifiermap[k++]; if (code == 0) continue; for (l = 0; l < keysyms_per_keycode; ++l) { #ifdef HAVE_XKBKEYCODETOKEYSYM keysym = XkbKeycodeToKeysym(dpy, code, 0, l); #else keysym = XKeycodeToKeysym(dpy, code, l); #endif if (keysym == NoSymbol) { /* EMPTY */ ; } else if (keysym == XK_Num_Lock) { SaveMask(num_lock); } else if (keysym == XK_Alt_L || keysym == XK_Alt_R) { SaveMask(alt_mods); } else if (keysym == XK_Meta_L || keysym == XK_Meta_R) { SaveMask(meta_mods); } } } } XFree(theMap); } /* Don't disable any mods if "alwaysUseMods" is true. */ if (!xw->misc.alwaysUseMods) { /* * Force TranslationsUseKeyword() to reload. */ FreeAndNull(xw->keyboard.shell_translations); FreeAndNull(xw->keyboard.xterm_translations); /* * If the Alt modifier is used in translations, we would rather not * use it to modify function-keys when NumLock is active. */ if ((xw->work.alt_mods != 0) && xtermHasTranslation(xw, "alt", True)) { TRACE(("ALT is used as a modifier in translations (ignore mask)\n")); xw->work.alt_mods = 0; } /* * If the Meta modifier is used in translations, we would rather not * use it to modify function-keys. */ if ((xw->work.meta_mods != 0) && xtermHasTranslation(xw, "meta", True)) { TRACE(("META is used as a modifier in translations\n")); xw->work.meta_mods = 0; } } XFreeModifiermap(keymap); } #if OPT_TRACE /* * Dump a summary of the coverage of the various IsXXX macros. */ { /* *INDENT-OFF* */ static const struct { const char *name; KeySym lo; KeySym hi; } other_files[] = { { "DECkeysym.h (DEC)", 0x1000FEB0, 0x1000FF00 }, { "HPkeysym.h (hp)", 0x1000FF48, 0x1000FF77 }, { "HPkeysym.h (osf)", 0x1004FF02, 0x1004FFFF }, { "Sunkeysym.h (Sun)", 0x1005FF00, 0x1005FF7D }, { "XF86keysym.h (all)", 0x10080001, 0x1008FFFF }, { "XF86keysym.h (used)", 0x1008FE01, 0x1008FFB8 }, { "XF86keysym.h (evdev)", 0x10081000, 0x10081FFF }, { "ap_keysym.h (ap)", 0x1000FF00, 0x1000FFA9 }, }; /* *INDENT-ON* */ size_t nn; KeySym lo = 0xfe00; KeySym hi = 0xffff; unsigned covered = 0; for (keysym = lo; keysym <= hi; ++keysym) { if (IsCursorKey(keysym) || IsEditFunctionKey(xw, keysym) || IsFunctionKey(keysym) || IsKeypadKey(keysym) || IsModifierKey(keysym) || IsMiscFunctionKey(keysym) || IsPFKey(keysym)) { unsigned long result = (unsigned long) keysym - 0x1d00; /* this is the same as keysym2ucs(keysym) */ ++covered; TRACE(("%#lx -> U+%04lx %-8s%-8s%-8s%-8s%-8s%-8s%-8s\n", keysym, result, IsCursorKey(keysym) ? "cursor" : "", IsEditFunctionKey(xw, keysym) ? "editing" : "", IsFunctionKey(keysym) ? "fkey" : "", IsKeypadKey(keysym) ? "keypad" : "", IsModifierKey(keysym) ? "modify" : "", IsMiscFunctionKey(keysym) ? "fkey" : "", IsPFKey(keysym) ? "fkey" : "")); } } TRACE(("%u keysyms are used in %lu slots (%#lx to %#lx)\n", covered, hi + 1 - lo, lo, hi)); TRACE(("Other files, keysym limits\n")); for (nn = 0; nn < XtNumber(other_files); ++nn) { TRACE(("%s:\n", other_files[nn].name)); TRACE(("\tlo %#lx -> %#lx\n", other_files[nn].lo, keysym2ucs(other_files[nn].lo))); TRACE(("\thi %#lx -> %#lx\n", other_files[nn].hi, keysym2ucs(other_files[nn].hi))); } } #endif } #endif /* OPT_NUM_LOCK */ xterm-399/xtermcap.c0000644000000000000000000003732615000532711013231 0ustar rootroot/* $XTermId: xtermcap.c,v 1.66 2025/04/18 20:27:53 tom Exp $ */ /* * Copyright 2007-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #include #include #include #include #include #if USE_TERMINFO && defined(NCURSES_VERSION) && defined(HAVE_USE_EXTENDED_NAMES) #define USE_EXTENDED_NAMES 1 #else #define USE_EXTENDED_NAMES 0 #endif #if USE_TERMINFO #define TcapInit(buffer, name) (setupterm(name, fileno(stdout), &ignored) == OK) #define TcapFree() (del_curterm(cur_term)) #else #define TcapInit(buffer, name) (tgetent(buffer, name) == 1) #define TcapFree() /*nothing */ #endif #define NO_STRING (char *)(-1) #if OPT_TCAP_QUERY || OPT_TCAP_FKEYS #define SHIFT (MOD_NONE + MOD_SHIFT) typedef struct { const char tc[3]; const char ti[8]; int code; unsigned param; /* see xtermStateToParam() */ } TCAPINFO; /* *INDENT-OFF* */ #define DATA(tc,ti,x,y) { tc, ti, x, y } static const TCAPINFO table[] = { /* tcap terminfo code state */ DATA( "%1", "khlp", XK_Help, 0 ), DATA( "#1", "kHLP", XK_Help, SHIFT ), DATA( "@0", "kfnd", XK_Find, 0 ), DATA( "*0", "kFND", XK_Find, SHIFT ), DATA( "*6", "kslt", XK_Select, 0 ), DATA( "#6", "kSLT", XK_Select, SHIFT ), DATA( "kh", "khome", XK_Home, 0 ), DATA( "#2", "kHOM", XK_Home, SHIFT ), DATA( "@7", "kend", XK_End, 0 ), DATA( "*7", "kEND", XK_End, SHIFT ), DATA( "kl", "kcub1", XK_Left, 0 ), DATA( "kr", "kcuf1", XK_Right, 0 ), DATA( "ku", "kcuu1", XK_Up, 0 ), DATA( "kd", "kcud1", XK_Down, 0 ), DATA( "#4", "kLFT", XK_Left, SHIFT ), DATA( "%i", "kRIT", XK_Right, SHIFT ), DATA( "kF", "kind", XK_Down, SHIFT ), DATA( "kR", "kri", XK_Up, SHIFT ), DATA( "k1", "kf1", XK_Fn(1), 0 ), DATA( "k2", "kf2", XK_Fn(2), 0 ), DATA( "k3", "kf3", XK_Fn(3), 0 ), DATA( "k4", "kf4", XK_Fn(4), 0 ), DATA( "k5", "kf5", XK_Fn(5), 0 ), DATA( "k6", "kf6", XK_Fn(6), 0 ), DATA( "k7", "kf7", XK_Fn(7), 0 ), DATA( "k8", "kf8", XK_Fn(8), 0 ), DATA( "k9", "kf9", XK_Fn(9), 0 ), DATA( "k;", "kf10", XK_Fn(10), 0 ), DATA( "F1", "kf11", XK_Fn(11), 0 ), DATA( "F2", "kf12", XK_Fn(12), 0 ), DATA( "F3", "kf13", XK_Fn(13), 0 ), DATA( "F4", "kf14", XK_Fn(14), 0 ), DATA( "F5", "kf15", XK_Fn(15), 0 ), DATA( "F6", "kf16", XK_Fn(16), 0 ), DATA( "F7", "kf17", XK_Fn(17), 0 ), DATA( "F8", "kf18", XK_Fn(18), 0 ), DATA( "F9", "kf19", XK_Fn(19), 0 ), DATA( "FA", "kf20", XK_Fn(20), 0 ), DATA( "FB", "kf21", XK_Fn(21), 0 ), DATA( "FC", "kf22", XK_Fn(22), 0 ), DATA( "FD", "kf23", XK_Fn(23), 0 ), DATA( "FE", "kf24", XK_Fn(24), 0 ), DATA( "FF", "kf25", XK_Fn(25), 0 ), DATA( "FG", "kf26", XK_Fn(26), 0 ), DATA( "FH", "kf27", XK_Fn(27), 0 ), DATA( "FI", "kf28", XK_Fn(28), 0 ), DATA( "FJ", "kf29", XK_Fn(29), 0 ), DATA( "FK", "kf30", XK_Fn(30), 0 ), DATA( "FL", "kf31", XK_Fn(31), 0 ), DATA( "FM", "kf32", XK_Fn(32), 0 ), DATA( "FN", "kf33", XK_Fn(33), 0 ), DATA( "FO", "kf34", XK_Fn(34), 0 ), DATA( "FP", "kf35", XK_Fn(35), 0 ), DATA( "FQ", "kf36", -36, 0 ), DATA( "FR", "kf37", -37, 0 ), DATA( "FS", "kf38", -38, 0 ), DATA( "FT", "kf39", -39, 0 ), DATA( "FU", "kf40", -40, 0 ), DATA( "FV", "kf41", -41, 0 ), DATA( "FW", "kf42", -42, 0 ), DATA( "FX", "kf43", -43, 0 ), DATA( "FY", "kf44", -44, 0 ), DATA( "FZ", "kf45", -45, 0 ), DATA( "Fa", "kf46", -46, 0 ), DATA( "Fb", "kf47", -47, 0 ), DATA( "Fc", "kf48", -48, 0 ), DATA( "Fd", "kf49", -49, 0 ), DATA( "Fe", "kf50", -50, 0 ), DATA( "Ff", "kf51", -51, 0 ), DATA( "Fg", "kf52", -52, 0 ), DATA( "Fh", "kf53", -53, 0 ), DATA( "Fi", "kf54", -54, 0 ), DATA( "Fj", "kf55", -55, 0 ), DATA( "Fk", "kf56", -56, 0 ), DATA( "Fl", "kf57", -57, 0 ), DATA( "Fm", "kf58", -58, 0 ), DATA( "Fn", "kf59", -59, 0 ), DATA( "Fo", "kf60", -60, 0 ), DATA( "Fp", "kf61", -61, 0 ), DATA( "Fq", "kf62", -62, 0 ), DATA( "Fr", "kf63", -63, 0 ), DATA( "K1", "ka1", XK_KP_Home, 0 ), DATA( "K4", "kc1", XK_KP_End, 0 ), DATA( "K3", "ka3", XK_KP_Prior, 0 ), DATA( "K5", "kc3", XK_KP_Next, 0 ), #ifdef XK_ISO_Left_Tab DATA( "kB", "kcbt", XK_ISO_Left_Tab, 0 ), #endif DATA( "kC", "kclr", XK_Clear, 0 ), DATA( "kD", "kdch1", XK_Delete, 0 ), DATA( "kI", "kich1", XK_Insert, 0 ), DATA( "kN", "knp", XK_Next, 0 ), DATA( "kP", "kpp", XK_Prior, 0 ), DATA( "%c", "kNXT", XK_Next, SHIFT ), DATA( "%e", "kPRV", XK_Prior, SHIFT ), DATA( "&8", "kund", XK_Undo, 0 ), DATA( "kb", "kbs", XK_BackSpace, 0 ), # if OPT_TCAP_QUERY && OPT_ISO_COLORS /* XK_COLORS is a fake code. */ DATA( "Co", "colors", XK_COLORS, 0 ), # if OPT_DIRECT_COLOR /* note - termcap cannot support RGB */ DATA( "Co", "RGB", XK_RGB, 0 ), # endif # endif DATA( "TN", "name", XK_TCAPNAME, 0 ), #if USE_EXTENDED_NAMES #define DEXT(name, parm, code) DATA("", name, code, parm) #define D1ST(name, parm, code) DEXT("k" #name, parm, code) #define DMOD(name, parm, code) DEXT("k" #name #parm, parm, code) #define DGRP(name, code) \ D1ST(name, 2, code), \ DMOD(name, 3, code), \ DMOD(name, 4, code), \ DMOD(name, 5, code), \ DMOD(name, 6, code), \ DMOD(name, 7, code), \ DMOD(name, 8, code) /* the terminfo codes here are ncurses extensions */ /* ignore the termcap names, which are empty */ DATA( "", "kUP", XK_Up, SHIFT ), DATA( "", "kDN", XK_Up, SHIFT ), DGRP(DN, XK_Down), DGRP(LFT, XK_Left), DGRP(RIT, XK_Right), DGRP(UP, XK_Up), DGRP(DC, XK_Delete), DGRP(END, XK_End), DGRP(HOM, XK_Home), DGRP(IC, XK_Insert), DGRP(NXT, XK_Next), DGRP(PRV, XK_Prior), #endif }; #undef DATA /* *INDENT-ON* */ #if OPT_TCAP_FKEYS static Boolean loadTermcapStrings(TScreen *screen) { Boolean result = True; if (screen->tcap_fkeys == NULL) { Cardinal want = XtNumber(table); Cardinal have; #if !USE_TERMINFO char *area = screen->tcap_area; #endif TRACE(("loadTermcapStrings\n")); if ((screen->tcap_fkeys = TypeCallocN(char *, want)) != NULL) { for (have = 0; have < want; ++have) { char name[80]; char *fkey; #if USE_TERMINFO fkey = tigetstr(strcpy(name, table[have].ti)); #else fkey = tgetstr(strcpy(name, table[have].tc), &area); #endif if (fkey != NULL && fkey != NO_STRING) { screen->tcap_fkeys[have] = x_strdup(fkey); } else { screen->tcap_fkeys[have] = NO_STRING; } } } else { result = False; } } return result; } #endif #if OPT_TCAP_QUERY static Boolean keyIsDistinct(XtermWidget xw, int which) { Boolean result = True; switch (xw->keyboard.type) { case keyboardIsTermcap: #if OPT_TCAP_FKEYS if (table[which].param == SHIFT) { TScreen *screen = TScreenOf(xw); Cardinal k; if (loadTermcapStrings(screen) && screen->tcap_fkeys[which] != NO_STRING) { for (k = 0; k < XtNumber(table); k++) { if (table[k].code == table[which].code && table[k].param == 0) { char *fkey; if ((fkey = screen->tcap_fkeys[k]) != NO_STRING && !strcmp(fkey, screen->tcap_fkeys[which])) { TRACE(("shifted/unshifted keys do not differ\n")); result = False; } break; } } } else { /* there is no data for the shifted key */ result = False; } } #endif break; /* * The vt220-keyboard will not return distinct key sequences for * shifted cursor-keys. Just pretend they do not exist, since some * programs may be confused if we return the same data for * shifted/unshifted keys. */ case keyboardIsVT220: if (table[which].param == SHIFT) { TRACE(("shifted/unshifted keys do not differ\n")); result = False; } break; case keyboardIsLegacy: case keyboardIsDefault: case keyboardIsHP: case keyboardIsSCO: case keyboardIsSun: break; } return result; } static int lookupTcapByName(const char *name) { int result = -2; Cardinal j; if (!IsEmpty(name)) { for (j = 0; j < XtNumber(table); j++) { if (!strcmp(table[j].ti, name) || !strcmp(table[j].tc, name)) { result = (int) j; break; } } } if (result >= 0) { TRACE(("lookupTcapByName(%s) tc=%s, ti=%s code %#x, param %#x\n", name, table[result].tc, table[result].ti, table[result].code, table[result].param)); } else { TRACE(("lookupTcapByName(%s) FAIL\n", name)); } return result; } /* * Parse the termcap/terminfo name from the string, returning a positive number * (the keysym) if found, otherwise -1. Update the string pointer. * Returns the (shift, control) state in *state. * * This does not attempt to construct control/shift modifiers to construct * function-key values. Instead, it sets the *fkey flag to pass to Input() * and bypass the lookup of keysym altogether. */ int xtermcapKeycode(XtermWidget xw, const char **params, unsigned *state, Bool *fkey) { const TCAPINFO *data; int code = -1; char *name; const char *p; TRACE(("xtermcapKeycode(%s)\n", *params)); /* Convert hex encoded name to ascii */ name = x_decode_hex(*params, &p); *params = p; *state = 0; *fkey = False; if (!IsEmpty(name) && (*p == 0 || *p == ';')) { int which; if ((which = lookupTcapByName(name)) >= 0) { if (keyIsDistinct(xw, which)) { data = table + which; code = data->code; *state = xtermParamToState(xw, data->param); if (IsFunctionKey(code)) { *fkey = True; } else if (code < 0) { *fkey = True; code = XK_Fn((-code)); } #if OPT_SUN_FUNC_KEYS if (*fkey && xw->keyboard.type == keyboardIsSun) { int num = code - XK_Fn(0); /* match function-key case in sunfuncvalue() */ if (num > 20) { if (num <= 30 || num > 47) { code = -1; } else { code -= 10; switch (num) { case 37: /* khome */ case 39: /* kpp */ case 41: /* kb2 */ case 43: /* kend */ case 45: /* knp */ code = -1; break; } } } } #endif } else { TRACE(("... name ok, data not ok\n")); code = -1; } } else { TRACE(("... name not ok\n")); code = -2; } } else { TRACE(("... name not ok\n")); code = -2; } TRACE(("... xtermcapKeycode(%s, %u, %d) -> %#06x\n", name, *state, *fkey, code)); free(name); return code; } #endif /* OPT_TCAP_QUERY */ #if OPT_TCAP_FKEYS static int nextTcapByCode(int code, unsigned param, int last) { int result = -1; int n; TRACE(("lookupTcapByCode %#x:%#x\n", code, param)); for (n = last + 1; n < (int) XtNumber(table); n++) { if (table[n].code == code && table[n].param == param) { TRACE(("->lookupTcapByCode %d:%s\n", n, table[n].ti)); result = n; break; } } return result; } static int firstTcapByCode(int code, unsigned param) { return nextTcapByCode(code, param, -1); } int xtermcapString(XtermWidget xw, int keycode, unsigned mask) { int result = 0; unsigned param = xtermStateToParam(xw, mask); int which; if ((which = firstTcapByCode(keycode, param)) >= 0) { TScreen *screen = TScreenOf(xw); if (loadTermcapStrings(screen)) { do { char *fkey; if ((fkey = screen->tcap_fkeys[which]) != NO_STRING) { StringInput(xw, (Char *) fkey, strlen(fkey)); result = 1; break; } } while ((which = nextTcapByCode(keycode, param, which)) >= 0); } } TRACE(("xtermcapString(keycode=%#x, mask=%#x) ->%d\n", keycode, mask, result)); return result; } #endif /* OPT_TCAP_FKEYS */ #endif /* OPT_TCAP_QUERY || OPT_TCAP_FKEYS */ /* * If we're linked to terminfo, tgetent() will return an empty buffer. We * cannot use that to adjust the $TERMCAP variable. */ Bool get_termcap(XtermWidget xw, char *name) { #if USE_TERMINFO int ignored = 0; #endif char *buffer = get_tcap_buffer(xw); *buffer = 0; /* initialize, in case we're using terminfo's tgetent */ #if USE_EXTENDED_NAMES use_extended_names(TRUE); #endif if (!IsEmpty(name)) { if (TcapInit(buffer, name)) { TRACE(("get_termcap(%s) succeeded (%s)\n", name, (*buffer ? "ok:termcap, we can update $TERMCAP" : "assuming this is terminfo"))); return True; } else { *buffer = 0; /* just in case */ } } return False; } /* * Retrieve the termcap-buffer. */ char * get_tcap_buffer(XtermWidget xw) { TScreen *screen = TScreenOf(xw); char *buffer; #if OPT_TEK4014 if (TEK4014_ACTIVE(xw)) { buffer = TekScreenOf(tekWidget)->tcapbuf; } else #endif { buffer = screen->tcapbuf; } return buffer; } /* * Retrieve the erase-key, for initialization in main program. */ #if OPT_INITIAL_ERASE char * get_tcap_erase(XtermWidget xw) { #if !USE_TERMINFO char *area = TScreenOf(xw)->tcap_area; #endif char *fkey; (void) xw; #if USE_TERMINFO fkey = tigetstr("kbs"); #else fkey = tgetstr("kb", &area); #endif if (fkey == NO_STRING) fkey = NULL; if (fkey != NULL) fkey = x_strdup(fkey); return fkey; } #endif /* OPT_INITIAL_ERASE */ /* * A legal termcap (or terminfo) name consists solely of graphic characters, * excluding the punctuation used to delimit fields of the source description. */ static Bool isLegalTcapName(const char *name) { Bool result = False; if (*name != '\0') { int length = 0; result = True; while (*name != '\0') { if (++length < 32 && isgraph(CharOf(*name))) { if (strchr("\\|,:'\"", *name) != NULL) { result = False; break; } } else { result = False; break; } ++name; } } return result; } void set_termcap(XtermWidget xw, const char *name) { Boolean success = False; #if USE_TERMINFO int ignored = 0; #else TScreen *screen = TScreenOf(xw); char buffer[sizeof(screen->tcapbuf)]; #endif TRACE(("set_termcap(%s)\n", NonNull(name))); if (IsEmpty(name)) { Bell(xw, XkbBI_MinorError, 0); } else { const char *temp; char *value; if ((value = x_decode_hex(name, &temp)) != NULL) { if (*temp == '\0' && isLegalTcapName(value)) { if (TcapInit(buffer, value)) { TRACE(("...set_termcap(%s)\n", NonNull(value))); #if !USE_TERMINFO memcpy(screen->tcapbuf, buffer, sizeof(buffer)); #endif free_termcap(xw); success = True; } } free(value); } } if (!success) Bell(xw, XkbBI_MinorError, 0); } void free_termcap(XtermWidget xw) { #if OPT_TCAP_FKEYS TScreen *screen = TScreenOf(xw); if (screen->tcap_fkeys != NULL) { Cardinal want = XtNumber(table); Cardinal have; for (have = 0; have < want; ++have) { char *fkey = screen->tcap_fkeys[have]; if (fkey != NO_STRING) { free(fkey); } } FreeAndNull(screen->tcap_fkeys); } #else (void) xw; #endif TcapFree(); } xterm-399/charclass.h0000644000000000000000000000422314723173075013363 0ustar rootroot/* $XTermId: charclass.h,v 1.10 2024/12/01 23:50:21 tom Exp $ */ /* $XFree86: xc/programs/xterm/charclass.h,v 1.3 2006/02/13 01:14:58 dickey Exp $ */ /* * Copyright 2006-2023,2024 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #ifndef CHARCLASS_H #define CHARCLASS_H typedef enum { IDENT = -1, OTHER = 0, CNTRL = 1, ALNUM = 48, BLANK = 32, U_CJK = 0x4e00, U_SUP = 0x2070, U_SUB = 0x2080, U_HIR = 0x3040, U_KAT = 0x30a0, U_HAN = 0xac00 } Classes; extern void init_classtab(void); /* initialise the table. needs calling before either of the others. */ extern int SetCharacterClassRange(int low, int high, int value); extern int CharacterClass(int c); #if OPT_REPORT_CCLASS extern void report_wide_char_class(void); #endif #ifdef NO_LEAKS extern void noleaks_CharacterClass(void); #endif #endif xterm-399/VTPrsTbl.c0000644000000000000000000065612014765666611013115 0ustar rootroot/* $XTermId: VTPrsTbl.c,v 1.126 2025/03/17 00:32:09 tom Exp $ */ /* * Copyright 1999-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * * * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #include /* *INDENT-OFF* */ #if !OPT_BLINK_CURS #undef CASE_CSI_SPACE_STATE #define CASE_CSI_SPACE_STATE CASE_CSI_IGNORE #endif #if !OPT_DEC_LOCATOR #undef CASE_DECEFR #define CASE_DECEFR CASE_CSI_IGNORE #undef CASE_DECELR #define CASE_DECELR CASE_CSI_IGNORE #undef CASE_DECSLE #define CASE_DECSLE CASE_CSI_IGNORE #undef CASE_DECRQLP #define CASE_DECRQLP CASE_CSI_IGNORE #endif #if !OPT_WIDE_CHARS #undef CASE_ESC_PERCENT #define CASE_ESC_PERCENT CASE_ESC_IGNORE #endif #if !OPT_MOD_FKEYS #undef CASE_SET_FMT_KEYS #define CASE_SET_FMT_KEYS CASE_GROUND_STATE #undef CASE_SET_MOD_FKEYS #define CASE_SET_MOD_FKEYS CASE_GROUND_STATE #undef CASE_SET_MOD_FKEYS0 #define CASE_SET_MOD_FKEYS0 CASE_GROUND_STATE #undef CASE_XTERM_REPORT_FMT_FKEYS #define CASE_XTERM_REPORT_FMT_FKEYS CASE_GROUND_STATE #undef CASE_XTERM_REPORT_MOD_FKEYS #define CASE_XTERM_REPORT_MOD_FKEYS CASE_GROUND_STATE #endif #if !OPT_XTERM_SGR #undef CASE_CSI_HASH_STATE #define CASE_CSI_HASH_STATE CASE_CSI_IGNORE #endif /* * Stupid Apollo C preprocessor can't handle long lines. So... To keep * it happy, we put each onto a separate line.... Sigh... */ const PARSE_T ansi_table[] = { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* $ % & ' */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* ( ) * + */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* , - . / */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* 0 1 2 3 */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* 4 5 6 7 */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* 8 9 : ; */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* < = > ? */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* @ A B C */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* D E F G */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* H I J K */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* L M N O */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* P Q R S */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* T U V W */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* X Y Z [ */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* \ ] ^ _ */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* ` a b c */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* d e f g */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* h i j k */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* l m n o */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* p q r s */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* t u v w */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* x y z { */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* | } ~ DEL */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* currency yen brokenbar section */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* diaeresis copyright ordfeminine guillemotleft */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* notsign hyphen registered macron */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* degree plusminus twosuperior threesuperior */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* acute mu paragraph periodcentered */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* cedilla onesuperior masculine guillemotright */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* onequarter onehalf threequarters questiondown */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Agrave Aacute Acircumflex Atilde */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Adiaeresis Aring AE Ccedilla */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Eth Ntilde Ograve Oacute */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Udiaeresis Yacute Thorn ssharp */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* agrave aacute acircumflex atilde */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* adiaeresis aring ae ccedilla */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* egrave eacute ecircumflex ediaeresis */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* igrave iacute icircumflex idiaeresis */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* eth ntilde ograve oacute */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* ocircumflex otilde odiaeresis division */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* oslash ugrave uacute ucircumflex */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* udiaeresis yacute thorn ydiaeresis */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, }; const PARSE_T csi_table[] = /* CSI */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_SPACE_STATE, CASE_CSI_EX_STATE, CASE_CSI_QUOTE_STATE, CASE_CSI_HASH_STATE, /* $ % & ' */ CASE_CSI_DOLLAR_STATE, CASE_CSI_IGNORE, CASE_CSI_AMP_STATE, CASE_CSI_TICK_STATE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* vt525 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* vt420 and vt520 */ /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 4 5 6 7 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 8 9 : ; */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_COLON, CASE_ESC_SEMI, /* < = > ? */ CASE_CSI_IGNORE, CASE_DEC3_STATE, CASE_DEC2_STATE, CASE_DEC_STATE, /* @ A B C */ CASE_ICH, CASE_CUU, CASE_CUD, CASE_CUF, /* D E F G */ CASE_CUB, CASE_CNL, CASE_CPL, CASE_HPA, /* H I J K */ CASE_CUP, CASE_CHT, CASE_ED, CASE_EL, /* L M N O */ CASE_IL, CASE_DL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_DCH, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SU, /* T U V W */ CASE_TRACK_MOUSE, CASE_GROUND_STATE, /* vt420:NP */ CASE_GROUND_STATE, /* vt420:PP */ CASE_GROUND_STATE, /* X Y Z [ */ CASE_ECH, CASE_GROUND_STATE, CASE_CBT, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SD, CASE_GROUND_STATE, /* ` a b c */ CASE_HPA, CASE_HPR, CASE_REP, CASE_DA1, /* d e f g */ CASE_VPA, CASE_VPR, CASE_CUP, CASE_TBC, /* h i j k */ CASE_SET, CASE_MC, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_RST, CASE_SGR, CASE_CPR, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_DECLL, CASE_DECSTBM, CASE_ANSI_SC, /* t u v w */ CASE_XTERM_WINOPS, CASE_ANSI_RC, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_DECREQTPARM, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_SPACE_STATE, CASE_CSI_EX_STATE, CASE_CSI_QUOTE_STATE, CASE_CSI_HASH_STATE, /* currency yen brokenbar section */ CASE_CSI_DOLLAR_STATE, CASE_CSI_IGNORE, CASE_CSI_AMP_STATE, CASE_CSI_TICK_STATE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* acute mu paragraph periodcentered */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* cedilla onesuperior masculine guillemotright */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_COLON, CASE_ESC_SEMI, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_DEC3_STATE, CASE_DEC2_STATE, CASE_DEC_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_ICH, CASE_CUU, CASE_CUD, CASE_CUF, /* Adiaeresis Aring AE Ccedilla */ CASE_CUB, CASE_CNL, CASE_CPL, CASE_HPA, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_CUP, CASE_CHT, CASE_ED, CASE_EL, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IL, CASE_DL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_DCH, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SU, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_TRACK_MOUSE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_ECH, CASE_GROUND_STATE, CASE_CBT, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SD, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_HPA, CASE_HPR, CASE_REP, CASE_DA1, /* adiaeresis aring ae ccedilla */ CASE_VPA, CASE_VPR, CASE_CUP, CASE_TBC, /* egrave eacute ecircumflex ediaeresis */ CASE_SET, CASE_MC, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_RST, CASE_SGR, CASE_CPR, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_DECLL, CASE_DECSTBM, CASE_ANSI_SC, /* ocircumflex otilde odiaeresis division */ CASE_XTERM_WINOPS, CASE_ANSI_RC, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_DECREQTPARM, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T csi2_table[] = /* CSI */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_SPACE_STATE, CASE_CSI_EX_STATE, CASE_CSI_QUOTE_STATE, CASE_CSI_HASH_STATE, /* $ % & ' */ CASE_CSI_DOLLAR_STATE, CASE_CSI_IGNORE, CASE_CSI_AMP_STATE, CASE_CSI_TICK_STATE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_STAR_STATE, CASE_CSI_IGNORE, /* vt420 and vt520 */ /* , - . / */ CASE_CSI_COMMA_STATE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 4 5 6 7 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 8 9 : ; */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_COLON, CASE_ESC_SEMI, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_ICH, CASE_CUU, CASE_CUD, CASE_CUF, /* D E F G */ CASE_CUB, CASE_CNL, CASE_CPL, CASE_HPA, /* H I J K */ CASE_CUP, CASE_CHT, CASE_ED, CASE_EL, /* L M N O */ CASE_IL, CASE_DL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_DCH, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SU, /* T U V W */ CASE_TRACK_MOUSE, CASE_GROUND_STATE, /* vt420:NP */ CASE_GROUND_STATE, /* vt420:PP */ CASE_GROUND_STATE, /* X Y Z [ */ CASE_ECH, CASE_GROUND_STATE, CASE_CBT, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SD, CASE_GROUND_STATE, /* ` a b c */ CASE_HPA, CASE_HPR, CASE_REP, CASE_DA1, /* d e f g */ CASE_VPA, CASE_VPR, CASE_CUP, CASE_TBC, /* h i j k */ CASE_SET, CASE_MC, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_RST, CASE_SGR, CASE_CPR, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_DECLL, CASE_DECSTBM, CASE_ANSI_SC, /* t u v w */ CASE_XTERM_WINOPS, CASE_ANSI_RC, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_DECREQTPARM, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* vt510:DECFNK */ CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_SPACE_STATE, CASE_CSI_EX_STATE, CASE_CSI_QUOTE_STATE, CASE_CSI_HASH_STATE, /* currency yen brokenbar section */ CASE_CSI_DOLLAR_STATE, CASE_CSI_IGNORE, CASE_CSI_AMP_STATE, CASE_CSI_TICK_STATE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_STAR_STATE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_COMMA_STATE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* acute mu paragraph periodcentered */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* cedilla onesuperior masculine guillemotright */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_COLON, CASE_ESC_SEMI, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_ICH, CASE_CUU, CASE_CUD, CASE_CUF, /* Adiaeresis Aring AE Ccedilla */ CASE_CUB, CASE_CNL, CASE_CPL, CASE_HPA, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_CUP, CASE_CHT, CASE_ED, CASE_EL, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IL, CASE_DL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_DCH, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SU, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_TRACK_MOUSE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_ECH, CASE_GROUND_STATE, CASE_CBT, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SD, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_HPA, CASE_HPR, CASE_REP, CASE_DA1, /* adiaeresis aring ae ccedilla */ CASE_VPA, CASE_VPR, CASE_CUP, CASE_TBC, /* egrave eacute ecircumflex ediaeresis */ CASE_SET, CASE_MC, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_RST, CASE_SGR, CASE_CPR, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_DECLL, CASE_DECSTBM, CASE_ANSI_SC, /* ocircumflex otilde odiaeresis division */ CASE_XTERM_WINOPS, CASE_ANSI_RC, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_DECREQTPARM, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T csi_ex_table[] = /* CSI ! */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 4 5 6 7 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 8 9 : ; */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_DECSTR, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* acute mu paragraph periodcentered */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_DECSTR, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T csi_quo_table[] = /* CSI ... " */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 4 5 6 7 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 8 9 : ; */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_DECSCL, CASE_DECSCA, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, /* vt510:DECSRFR */ CASE_GROUND_STATE, /* vt510:DECSTRL */ CASE_DECRQDE, CASE_GROUND_STATE, /* vt420:DECRPDE */ /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* acute mu paragraph periodcentered */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_DECSCL, CASE_DECSCA, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECRQDE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; #if OPT_BLINK_CURS const PARSE_T csi_sp_table[] = /* CSI ... SP */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 4 5 6 7 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 8 9 : ; */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_SL, CASE_SR, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, /* vt510:PPA */ CASE_GROUND_STATE, /* vt420:PPR */ CASE_GROUND_STATE, /* vt510:PPB */ CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, /* vt510:DECSSCLS */ CASE_DECSCUSR, CASE_GROUND_STATE, /* vt510:DECSKCV */ CASE_GROUND_STATE, /* t u v w */ CASE_DECSWBV, CASE_DECSMBV, CASE_GROUND_STATE, /* vt510:DECSLCK */ CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, /* vt510:DECKBD */ CASE_GROUND_STATE, /* vt510:DECTME */ CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* acute mu paragraph periodcentered */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_SL, CASE_SR, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_DECSCUSR, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_DECSWBV, CASE_DECSMBV, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; #endif const PARSE_T csi_tick_table[] = /* CSI ... ' */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 4 5 6 7 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 8 9 : ; */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECEFR, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECELR, CASE_DECSLE, /* | } ~ DEL */ CASE_DECRQLP, CASE_DECIC, CASE_DECDC, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* acute mu paragraph periodcentered */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECEFR, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECELR, CASE_DECSLE, /* udiaeresis yacute thorn ydiaeresis */ CASE_DECRQLP, CASE_DECIC, CASE_DECDC, CASE_IGNORE, }; #if OPT_XTERM_SGR const PARSE_T csi_hash_table[] = /* CSI ... # */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 4 5 6 7 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 8 9 : ; */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_XTERM_PUSH_COLORS, CASE_XTERM_POP_COLORS, CASE_XTERM_REPORT_COLORS, CASE_XTERM_TITLE_STACK, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_XTERM_PUSH_SGR, CASE_XTERM_POP_SGR, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_XTERM_CHECKSUM, CASE_GROUND_STATE, CASE_XTERM_PUSH_SGR, /* | } ~ DEL */ CASE_XTERM_REPORT_SGR, CASE_XTERM_POP_SGR, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* acute mu paragraph periodcentered */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* cedilla onesuperior masculine guillemotright */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_XTERM_PUSH_COLORS, CASE_XTERM_POP_COLORS, CASE_XTERM_REPORT_COLORS, CASE_XTERM_TITLE_STACK, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_XTERM_PUSH_SGR, CASE_XTERM_POP_SGR, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_XTERM_CHECKSUM, CASE_GROUND_STATE, CASE_XTERM_PUSH_SGR, /* udiaeresis yacute thorn ydiaeresis */ CASE_XTERM_REPORT_SGR, CASE_XTERM_POP_SGR, CASE_GROUND_STATE, CASE_GROUND_STATE, }; #endif const PARSE_T csi_amp_table[] = /* CSI ... & */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 4 5 6 7 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 8 9 : ; */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_DECRQUPSS, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, /* vt420:Enable Session */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* acute mu paragraph periodcentered */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_DECRQUPSS, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, }; #if OPT_DEC_RECTOPS const PARSE_T csi_dollar_table[] = /* CSI ... $ */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 4 5 6 7 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 8 9 : ; */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_RQM, CASE_GROUND_STATE, CASE_DECCARA, CASE_GROUND_STATE, /* t u v w */ CASE_DECRARA, CASE_GROUND_STATE, /* vt420:DECRQTSR */ CASE_DECCRA, CASE_DECRQPSR, /* x y z { */ CASE_DECFRA, CASE_GROUND_STATE, /* vt420:DECRPM */ CASE_DECERA, CASE_DECSERA, /* | } ~ DEL */ CASE_DECSCPP, CASE_DECSASD, CASE_DECSSDT, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* acute mu paragraph periodcentered */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_RQM, CASE_GROUND_STATE, CASE_DECCARA, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_DECRARA, CASE_GROUND_STATE, CASE_DECCRA, CASE_DECRQPSR, /* oslash ugrave uacute ucircumflex */ CASE_DECFRA, CASE_GROUND_STATE, CASE_DECERA, CASE_DECSERA, /* udiaeresis yacute thorn ydiaeresis */ CASE_DECSCPP, CASE_DECSASD, CASE_DECSSDT, CASE_GROUND_STATE, }; const PARSE_T csi_star_table[] = /* CSI ... * */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 4 5 6 7 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 8 9 : ; */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, /* vt510:DECSPPCS */ CASE_GROUND_STATE, /* vt420:DECSRC */ CASE_GROUND_STATE, /* vt510:DECSCS */ CASE_GROUND_STATE, /* vt510:DECSFC */ /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, /* vt510:DECSCP */ CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_DECSACE, CASE_DECRQCRA, CASE_GROUND_STATE, /* vt420:DECINVM */ CASE_GROUND_STATE, /* | } ~ DEL */ CASE_DECSNLS, CASE_GROUND_STATE, /* vt420:DECLFKC */ CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* acute mu paragraph periodcentered */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_DECSACE, CASE_DECRQCRA, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_DECSNLS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, }; #endif /* OPT_DEC_RECTOPS */ #if OPT_VT525_COLORS const PARSE_T csi_comma_table[] = /* CSI ... , */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 4 5 6 7 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 8 9 : ; */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, /* vt520:DECLTOD */ CASE_DECTID, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, /* vt520:DECRQKT */ CASE_GROUND_STATE, /* vt520:DECRPKT */ CASE_GROUND_STATE, /* vt520:DECRQKD */ /* x y z { */ CASE_GROUND_STATE, /* vt520:DECSPMA */ CASE_GROUND_STATE, /* vt520:DECUS */ CASE_GROUND_STATE, /* vt520:DECDLDA */ CASE_GROUND_STATE, /* vt520:DECSZS */ /* | } ~ DEL */ CASE_DECAC, CASE_DECATC, CASE_GROUND_STATE, /* vt520:DECPS */ CASE_GROUND_STATE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* acute mu paragraph periodcentered */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_DECTID, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_DECAC, CASE_DECATC, CASE_GROUND_STATE, CASE_GROUND_STATE, }; #endif /* OPT_VT525_COLORS */ const PARSE_T dec_table[] = /* CSI ? */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_DEC_DOLLAR_STATE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 4 5 6 7 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 8 9 : ; */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_COLON, CASE_ESC_SEMI, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECSED, CASE_DECSEL, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GRAPHICS_ATTRIBUTES, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECST8C, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_DECSET, CASE_DEC_MC, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_DECRST, CASE_XTERM_REPORT_MOD_FKEYS, CASE_DSR, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_XTERM_RESTORE, CASE_XTERM_SAVE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_DEC_DOLLAR_STATE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* acute mu paragraph periodcentered */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* cedilla onesuperior masculine guillemotright */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_COLON, CASE_ESC_SEMI, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECSED, CASE_DECSEL, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GRAPHICS_ATTRIBUTES, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECST8C, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_DECSET, CASE_DEC_MC, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_DECRST, CASE_XTERM_REPORT_MOD_FKEYS, CASE_DSR, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_XTERM_RESTORE, CASE_XTERM_SAVE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; #if OPT_DEC_RECTOPS const PARSE_T csi_dec_dollar_table[] = /* CSI ?... $ */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 4 5 6 7 */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 8 9 : ; */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_DECRQM, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* acute mu paragraph periodcentered */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_DECRQM, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, }; #endif /* OPT_DEC_RECTOPS */ const PARSE_T dec2_table[] = /* CSI > */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 4 5 6 7 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 8 9 : ; */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_COLON, CASE_ESC_SEMI, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_XTERM_RM_TITLE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DA2, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SET_FMT_KEYS, CASE_XTERM_REPORT_FMT_KEYS, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_SET_MOD_FKEYS, CASE_SET_MOD_FKEYS0, CASE_GROUND_STATE, /* p q r s */ CASE_HIDE_POINTER, CASE_REPORT_VERSION, CASE_GROUND_STATE, CASE_XTERM_SHIFT_ESCAPE, /* t u v w */ CASE_XTERM_SM_TITLE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* acute mu paragraph periodcentered */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* cedilla onesuperior masculine guillemotright */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_COLON, CASE_ESC_SEMI, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_XTERM_RM_TITLE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DA2, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SET_FMT_KEYS, CASE_XTERM_REPORT_FMT_KEYS, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_SET_MOD_FKEYS, CASE_SET_MOD_FKEYS0, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_HIDE_POINTER, CASE_REPORT_VERSION, CASE_GROUND_STATE, CASE_XTERM_SHIFT_ESCAPE, /* ocircumflex otilde odiaeresis division */ CASE_XTERM_SM_TITLE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T dec3_table[] = /* CSI = */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* $ % & ' */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* ( ) * + */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* , - . / */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* 0 1 2 3 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 4 5 6 7 */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* 8 9 : ; */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_COLON, CASE_ESC_SEMI, /* < = > ? */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECRPTUI, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* currency yen brokenbar section */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* notsign hyphen registered macron */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* acute mu paragraph periodcentered */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_DIGIT, /* cedilla onesuperior masculine guillemotright */ CASE_ESC_DIGIT, CASE_ESC_DIGIT, CASE_ESC_COLON, CASE_ESC_SEMI, /* onequarter onehalf threequarters questiondown */ CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, CASE_CSI_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECRPTUI, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T cigtable[] = /* CASE_CSI_IGNORE */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* $ % & ' */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ( ) * + */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* , - . / */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0 1 2 3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 4 5 6 7 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 8 9 : ; */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* < = > ? */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T eigtable[] = /* CASE_ESC_IGNORE */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* $ % & ' */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ( ) * + */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* , - . / */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0 1 2 3 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 4 5 6 7 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 8 9 : ; */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* acute mu paragraph periodcentered */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* cedilla onesuperior masculine guillemotright */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* onequarter onehalf threequarters questiondown */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T esc_table[] = /* ESC */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_ESC_SP_STATE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_SCR_STATE, /* $ % & ' */ CASE_ESC_IGNORE, CASE_ESC_PERCENT, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* ( ) * + */ CASE_SCS0_STATE, CASE_SCS1_STATE, CASE_SCS2_STATE, CASE_SCS3_STATE, /* , - . / */ CASE_ESC_IGNORE, CASE_SCS1A_STATE, CASE_SCS2A_STATE, CASE_SCS3A_STATE, /* 0 1 2 3 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 4 5 6 7 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECBI, CASE_DECSC, /* 8 9 : ; */ CASE_DECRC, CASE_DECFI, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GROUND_STATE, CASE_DECKPAM, CASE_DECKPNM, CASE_GROUND_STATE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_IND, CASE_NEL, CASE_HP_BUGGY_LL, CASE_GROUND_STATE, /* H I J K */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* P Q R S */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* X Y Z [ */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* \ ] ^ _ */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_RIS, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_HP_MEM_LOCK, CASE_HP_MEM_UNLOCK, CASE_LS2, CASE_LS3, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_LS3R, CASE_LS2R, CASE_LS1R, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_ESC_SP_STATE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_SCR_STATE, /* currency yen brokenbar section */ CASE_ESC_IGNORE, CASE_ESC_PERCENT, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_SCS0_STATE, CASE_SCS1_STATE, CASE_SCS2_STATE, CASE_SCS3_STATE, /* notsign hyphen registered macron */ CASE_ESC_IGNORE, CASE_SCS1A_STATE, CASE_SCS2A_STATE, CASE_SCS3A_STATE, /* degree plusminus twosuperior threesuperior */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* acute mu paragraph periodcentered */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECBI, CASE_DECSC, /* cedilla onesuperior masculine guillemotright */ CASE_DECRC, CASE_DECFI, CASE_GROUND_STATE, CASE_GROUND_STATE, /* onequarter onehalf threequarters questiondown */ CASE_GROUND_STATE, CASE_DECKPAM, CASE_DECKPNM, CASE_GROUND_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_IND, CASE_NEL, CASE_HP_BUGGY_LL, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* Eth Ntilde Ograve Oacute */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_RIS, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_HP_MEM_LOCK, CASE_HP_MEM_UNLOCK, CASE_LS2, CASE_LS3, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_LS3R, CASE_LS2R, CASE_LS1R, CASE_IGNORE, }; const PARSE_T esc_sp_table[] = /* ESC SP */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* $ % & ' */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* ( ) * + */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* , - . / */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* 0 1 2 3 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 4 5 6 7 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 8 9 : ; */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_S7C1T, CASE_S8C1T, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_ANSI_LEVEL_1, CASE_ANSI_LEVEL_2, CASE_ANSI_LEVEL_3, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* currency yen brokenbar section */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* notsign hyphen registered macron */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* acute mu paragraph periodcentered */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* cedilla onesuperior masculine guillemotright */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* onequarter onehalf threequarters questiondown */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_S7C1T, CASE_S8C1T, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_ANSI_LEVEL_1, CASE_ANSI_LEVEL_2, CASE_ANSI_LEVEL_3, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T scrtable[] = /* ESC # */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* $ % & ' */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* ( ) * + */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* , - . / */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* 0 1 2 3 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECDHL, /* 4 5 6 7 */ CASE_DECDHL, CASE_DECSWL, CASE_DECDWL, CASE_GROUND_STATE, /* 8 9 : ; */ CASE_DECALN, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* currency yen brokenbar section */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* notsign hyphen registered macron */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_DECDHL, /* acute mu paragraph periodcentered */ CASE_DECDHL, CASE_DECSWL, CASE_DECDWL, CASE_GROUND_STATE, /* cedilla onesuperior masculine guillemotright */ CASE_DECALN, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* onequarter onehalf threequarters questiondown */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T scstable[] = /* ESC ( etc. */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_SCS_DQUOTE, CASE_ESC_IGNORE, /* $ % & ' */ CASE_ESC_IGNORE, CASE_SCS_PERCENT, CASE_SCS_AMPRSND, CASE_ESC_IGNORE, /* ( ) * + */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* , - . / */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* 0 1 2 3 */ CASE_GSETS, CASE_GSETS, CASE_GSETS, CASE_GROUND_STATE, /* 4 5 6 7 */ CASE_GSETS, CASE_GSETS, CASE_GSETS, CASE_GSETS, /* 8 9 : ; */ CASE_GROUND_STATE, CASE_GSETS3, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GSETS, CASE_GSETS, CASE_GSETS3, CASE_GROUND_STATE, /* @ A B C */ CASE_GROUND_STATE, CASE_GSETS, CASE_GSETS, CASE_GSETS, /* D E F G */ CASE_GROUND_STATE, CASE_GSETS, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GSETS, CASE_GSETS, CASE_GSETS, CASE_GSETS, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GSETS, CASE_GSETS, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GSETS, CASE_GSETS, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GSETS3, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GSETS, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_SCS_DQUOTE, CASE_ESC_IGNORE, /* currency yen brokenbar section */ CASE_ESC_IGNORE, CASE_SCS_PERCENT, CASE_SCS_AMPRSND, CASE_ESC_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* notsign hyphen registered macron */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_GSETS, CASE_GSETS, CASE_GSETS, CASE_GROUND_STATE, /* acute mu paragraph periodcentered */ CASE_GSETS, CASE_GSETS, CASE_GSETS, CASE_GSETS, /* cedilla onesuperior masculine guillemotright */ CASE_GROUND_STATE, CASE_GSETS3, CASE_GROUND_STATE, CASE_GROUND_STATE, /* onequarter onehalf threequarters questiondown */ CASE_GSETS, CASE_GSETS, CASE_GSETS3, CASE_GROUND_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GSETS, CASE_GSETS, CASE_GSETS, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GSETS, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GSETS, CASE_GSETS, CASE_GSETS, CASE_GSETS, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GSETS, CASE_GSETS, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GSETS, CASE_GSETS, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GSETS3, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GSETS, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T scs96table[] = /* ESC - etc. */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* $ % & ' */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* ( ) * + */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* , - . / */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* 0 1 2 3 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 4 5 6 7 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 8 9 : ; */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* @ A B C */ CASE_GROUND_STATE, CASE_GSETS3, CASE_GSETS5, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GSETS5, CASE_GROUND_STATE, /* H I J K */ CASE_GSETS5, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GSETS5, CASE_GSETS5, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* currency yen brokenbar section */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* notsign hyphen registered macron */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* acute mu paragraph periodcentered */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* cedilla onesuperior masculine guillemotright */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* onequarter onehalf threequarters questiondown */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GSETS3, CASE_GSETS5, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GSETS5, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GSETS5, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GSETS5, CASE_GSETS5, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; /* * This table is treated specially. The CASE_IGNORE entries correspond to the * characters that can be accumulated for the string function (e.g., OSC). */ const PARSE_T sos_table[] = /* OSC, DCS, etc. */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* FF CR SO SI */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* $ % & ' */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ( ) * + */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* , - . / */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0 1 2 3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 4 5 6 7 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 8 9 : ; */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* < = > ? */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* @ A B C */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* D E F G */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* H I J K */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* L M N O */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* P Q R S */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* T U V W */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* X Y Z [ */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* \ ] ^ _ */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ` a b c */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* d e f g */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* h i j k */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* l m n o */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* p q r s */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* t u v w */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* x y z { */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* | } ~ DEL */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Adiaeresis Aring AE Ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Eth Ntilde Ograve Oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Udiaeresis Yacute Thorn ssharp */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* agrave aacute acircumflex atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* adiaeresis aring ae ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* egrave eacute ecircumflex ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* igrave iacute icircumflex idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* eth ntilde ograve oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ocircumflex otilde odiaeresis division */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* oslash ugrave uacute ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* udiaeresis yacute thorn ydiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, }; #if OPT_WIDE_CHARS const PARSE_T esc_pct_table[] = /* ESC % */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* $ % & ' */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* ( ) * + */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* , - . / */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* 0 1 2 3 */ CASE_GSETS5, CASE_GROUND_STATE, CASE_GSETS5, CASE_GROUND_STATE, /* 4 5 6 7 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 8 9 : ; */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* @ A B C */ CASE_UTF8, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_UTF8, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* currency yen brokenbar section */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* notsign hyphen registered macron */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_GSETS5, CASE_GROUND_STATE, CASE_GSETS5, CASE_GROUND_STATE, /* acute mu paragraph periodcentered */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* cedilla onesuperior masculine guillemotright */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* onequarter onehalf threequarters questiondown */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_UTF8, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_UTF8, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T scs_2qt_table[] = /* SCS " */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* $ % & ' */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* ( ) * + */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* , - . / */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* 0 1 2 3 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 4 5 6 7 */ CASE_GSETS_DQUOTE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 8 9 : ; */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GSETS_DQUOTE, CASE_GSETS_DQUOTE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* currency yen brokenbar section */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* notsign hyphen registered macron */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* acute mu paragraph periodcentered */ CASE_GSETS_DQUOTE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* cedilla onesuperior masculine guillemotright */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* onequarter onehalf threequarters questiondown */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GSETS_DQUOTE, CASE_GSETS_DQUOTE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T scs_amp_table[] = /* SCS & */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* $ % & ' */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* ( ) * + */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* , - . / */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* 0 1 2 3 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 4 5 6 7 */ CASE_GSETS_AMPRSND, CASE_GSETS_AMPRSND, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 8 9 : ; */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* currency yen brokenbar section */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* notsign hyphen registered macron */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* acute mu paragraph periodcentered */ CASE_GSETS_AMPRSND, CASE_GSETS_AMPRSND, CASE_GROUND_STATE, CASE_GROUND_STATE, /* cedilla onesuperior masculine guillemotright */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* onequarter onehalf threequarters questiondown */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; const PARSE_T scs_pct_table[] = /* SCS % */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_SO, CASE_SI, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* $ % & ' */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* ( ) * + */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* , - . / */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* 0 1 2 3 */ CASE_GSETS_PERCENT, CASE_GROUND_STATE, CASE_GSETS_PERCENT, CASE_GSETS_PERCENT, /* 4 5 6 7 */ CASE_GROUND_STATE, CASE_GSETS_PERCENT, CASE_GSETS_PERCENT, CASE_GROUND_STATE, /* 8 9 : ; */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GROUND_STATE, CASE_GSETS_PERCENT, CASE_GROUND_STATE, CASE_GROUND_STATE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x84 0x85 0x86 0x87 */ CASE_IND, CASE_NEL, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x88 0x89 0x8a 0x8b */ CASE_HTS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_GROUND_STATE, CASE_RI, CASE_SS2, CASE_SS3, /* 0x90 0x91 0x92 0x93 */ CASE_DCS, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 0x94 0x95 0x96 0x97 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_SPA, CASE_EPA, /* 0x98 0x99 0x9a 0x9b */ CASE_SOS, CASE_GROUND_STATE, CASE_DECID, CASE_CSI_STATE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_ST, CASE_OSC, CASE_PM, CASE_APC, /* nobreakspace exclamdown cent sterling */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* currency yen brokenbar section */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* notsign hyphen registered macron */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_GSETS_PERCENT, CASE_GROUND_STATE, CASE_GSETS_PERCENT, CASE_GSETS_PERCENT, /* acute mu paragraph periodcentered */ CASE_GROUND_STATE, CASE_GSETS_PERCENT, CASE_GSETS_PERCENT, CASE_GROUND_STATE, /* cedilla onesuperior masculine guillemotright */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* onequarter onehalf threequarters questiondown */ CASE_GROUND_STATE, CASE_GSETS_PERCENT, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Eth Ntilde Ograve Oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* agrave aacute acircumflex atilde */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* adiaeresis aring ae ccedilla */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* eth ntilde ograve oacute */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ocircumflex otilde odiaeresis division */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* oslash ugrave uacute ucircumflex */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, }; #endif /* OPT_WIDE_CHARS */ #if OPT_VT52_MODE const PARSE_T vt52_table[] = { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_IGNORE, CASE_IGNORE, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* $ % & ' */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* ( ) * + */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* , - . / */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* 0 1 2 3 */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* 4 5 6 7 */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* 8 9 : ; */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* < = > ? */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* @ A B C */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* D E F G */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* H I J K */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* L M N O */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* P Q R S */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* T U V W */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* X Y Z [ */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* \ ] ^ _ */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* ` a b c */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* d e f g */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* h i j k */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* l m n o */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* p q r s */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* t u v w */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* x y z { */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* | } ~ DEL */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x98 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Adiaeresis Aring AE Ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Eth Ntilde Ograve Oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Udiaeresis Yacute Thorn ssharp */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* agrave aacute acircumflex atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* adiaeresis aring ae ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* egrave eacute ecircumflex ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* igrave iacute icircumflex idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* eth ntilde ograve oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ocircumflex otilde odiaeresis division */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* oslash ugrave uacute ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* udiaeresis yacute thorn ydiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, }; const PARSE_T vt52_esc_table[] = { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_IGNORE, CASE_IGNORE, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_VT52_IGNORE, CASE_VT52_IGNORE, CASE_VT52_IGNORE, CASE_VT52_IGNORE, /* $ % & ' */ CASE_VT52_IGNORE, CASE_VT52_IGNORE, CASE_VT52_IGNORE, CASE_VT52_IGNORE, /* ( ) * + */ CASE_VT52_IGNORE, CASE_VT52_IGNORE, CASE_VT52_IGNORE, CASE_VT52_IGNORE, /* , - . / */ CASE_VT52_IGNORE, CASE_VT52_IGNORE, CASE_VT52_IGNORE, CASE_VT52_IGNORE, /* 0 1 2 3 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 4 5 6 7 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 8 9 : ; */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_VT52_FINISH, CASE_DECKPAM, CASE_DECKPNM, CASE_GROUND_STATE, /* @ A B C */ CASE_GROUND_STATE, CASE_CUU, CASE_CUD, CASE_CUF, /* D E F G */ CASE_CUB, CASE_GROUND_STATE, CASE_SO, CASE_SI, /* H I J K */ CASE_CUP, CASE_RI, CASE_ED, CASE_EL, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_VT52_CUP, CASE_DECID, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x98 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Adiaeresis Aring AE Ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Eth Ntilde Ograve Oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Udiaeresis Yacute Thorn ssharp */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* agrave aacute acircumflex atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* adiaeresis aring ae ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* egrave eacute ecircumflex ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* igrave iacute icircumflex idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* eth ntilde ograve oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ocircumflex otilde odiaeresis division */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* oslash ugrave uacute ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* udiaeresis yacute thorn ydiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, }; const PARSE_T vt52_ignore_table[] = { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_ENQ, CASE_IGNORE, CASE_BELL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_VMOT, CASE_VMOT, /* FF CR SO SI */ CASE_VMOT, CASE_CR, CASE_IGNORE, CASE_IGNORE, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_CAN, CASE_IGNORE, CASE_SUB, CASE_ESC, /* FS GS RS US */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* $ % & ' */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ( ) * + */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* , - . / */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0 1 2 3 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 4 5 6 7 */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* 8 9 : ; */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* < = > ? */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* @ A B C */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* H I J K */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* L M N O */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* P Q R S */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* T U V W */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* X Y Z [ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* \ ] ^ _ */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* ` a b c */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* d e f g */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* h i j k */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* l m n o */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* p q r s */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* t u v w */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* x y z { */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, /* | } ~ DEL */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x98 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Adiaeresis Aring AE Ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Eth Ntilde Ograve Oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Udiaeresis Yacute Thorn ssharp */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* agrave aacute acircumflex atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* adiaeresis aring ae ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* egrave eacute ecircumflex ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* igrave iacute icircumflex idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* eth ntilde ograve oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ocircumflex otilde odiaeresis division */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* oslash ugrave uacute ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* udiaeresis yacute thorn ydiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, }; #endif /* OPT_VT52_MODE */ /* *INDENT-ON* */ xterm-399/VTparse.h0000644000000000000000000000574214665361170013013 0ustar rootroot/* $XTermId: VTparse.h,v 1.73 2024/09/02 16:06:16 tom Exp $ */ /* * Copyright 1996-2023,2024 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #ifndef included_VTparse_h #define included_VTparse_h 1 #include /* * PARSE_T has to be large enough to handle the number of cases enumerated here. */ typedef unsigned char PARSE_T; extern const PARSE_T ansi_table[]; extern const PARSE_T cigtable[]; extern const PARSE_T csi2_table[]; extern const PARSE_T csi_amp_table[]; extern const PARSE_T csi_dec_dollar_table[]; extern const PARSE_T csi_ex_table[]; extern const PARSE_T csi_quo_table[]; extern const PARSE_T csi_sp_table[]; extern const PARSE_T csi_table[]; extern const PARSE_T csi_tick_table[]; extern const PARSE_T dec2_table[]; extern const PARSE_T dec3_table[]; extern const PARSE_T dec_table[]; extern const PARSE_T eigtable[]; extern const PARSE_T esc_sp_table[]; extern const PARSE_T esc_table[]; extern const PARSE_T scrtable[]; extern const PARSE_T scs96table[]; extern const PARSE_T scstable[]; extern const PARSE_T sos_table[]; #if OPT_DEC_RECTOPS extern const PARSE_T csi_dollar_table[]; extern const PARSE_T csi_star_table[]; #endif /* OPT_DEC_LOCATOR */ #if OPT_VT52_MODE extern const PARSE_T vt52_table[]; extern const PARSE_T vt52_esc_table[]; extern const PARSE_T vt52_ignore_table[]; #endif #if OPT_VT525_COLORS extern const PARSE_T csi_comma_table[]; #endif #if OPT_WIDE_CHARS extern const PARSE_T esc_pct_table[]; extern const PARSE_T scs_amp_table[]; extern const PARSE_T scs_pct_table[]; extern const PARSE_T scs_2qt_table[]; #endif #if OPT_XTERM_SGR extern const PARSE_T csi_hash_table[]; #endif #include #endif /* included_VTparse_h */ xterm-399/charclass.c0000644000000000000000000003254114411673303013353 0ustar rootroot/* $XTermId: charclass.c,v 1.50 2023/04/01 00:11:47 tom Exp $ */ /* * Copyright 2002-2022,2023 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * *---------------------------------------------------------------------------- * Compact and efficient reimplementation of the * xterm character class mechanism for large character sets * * Markus Kuhn -- mkuhn@acm.org -- 2000-07-03 * * xterm allows users to select entire words with a double-click on the left * mouse button. Opinions might differ on what type of characters are part of * separate words, therefore xterm allows users to configure a class code for * each 8-bit character. Words are maximum length sequences of neighboring * characters with identical class code. Extending this mechanism to Unicode * naively would create an at least 2^16 entries (128 kB) long class code * table. * * Instead, we transform the character class table into a list of intervals, * that will be accessed via a linear search. Changes made to the table by the * user will be appended. A special class code IDENT (default) marks * characters who have their code number as the class code. * * We could alternatively use a sorted table of non-overlapping intervals that * can be accessed via binary search, but merging in new intervals is * significantly more hassle and not worth the effort here. */ #include #include #if OPT_WIDE_CHARS #ifdef TEST_DRIVER #include #include #include #if OPT_TRACE #define Trace if (opt_v) printf #endif #undef OPT_REPORT_CCLASS #define OPT_REPORT_CCLASS 1 #endif /* TEST_DRIVER */ static struct classentry { int cclass; int first; int last; } *classtab; #ifdef TEST_DRIVER static int opt_all; static int opt_check; static int opt_quiet; static int opt_v; #endif void init_classtab(void) { const int size = 50; TRACE(("init_classtab " TRACE_L "\n")); classtab = TypeMallocN(struct classentry, (unsigned) size); if (!classtab) abort(); classtab[0].cclass = size; classtab[0].first = 1; classtab[0].last = 0; /* old xterm default classes */ SetCharacterClassRange(0, 0, BLANK); SetCharacterClassRange(1, 31, CNTRL); SetCharacterClassRange('\t', '\t', BLANK); SetCharacterClassRange('0', '9', ALNUM); SetCharacterClassRange('A', 'Z', ALNUM); SetCharacterClassRange('_', '_', ALNUM); SetCharacterClassRange('a', 'z', ALNUM); SetCharacterClassRange(127, 159, CNTRL); SetCharacterClassRange(160, 191, IDENT); SetCharacterClassRange(192, 255, ALNUM); SetCharacterClassRange(215, 215, IDENT); SetCharacterClassRange(247, 247, IDENT); /* added Unicode classes */ SetCharacterClassRange(0x0100, 0xffdf, ALNUM); /* mostly characters */ SetCharacterClassRange(0x037e, 0x037e, IDENT); /* Greek question mark */ SetCharacterClassRange(0x0387, 0x0387, IDENT); /* Greek ano teleia */ SetCharacterClassRange(0x055a, 0x055f, IDENT); /* Armenian punctuation */ SetCharacterClassRange(0x0589, 0x0589, IDENT); /* Armenian full stop */ SetCharacterClassRange(0x0700, 0x070d, IDENT); /* Syriac punctuation */ SetCharacterClassRange(0x104a, 0x104f, IDENT); /* Myanmar punctuation */ SetCharacterClassRange(0x10fb, 0x10fb, IDENT); /* Georgian punctuation */ SetCharacterClassRange(0x1361, 0x1368, IDENT); /* Ethiopic punctuation */ SetCharacterClassRange(0x166d, 0x166e, IDENT); /* Canadian Syl. punctuation */ SetCharacterClassRange(0x17d4, 0x17dc, IDENT); /* Khmer punctuation */ SetCharacterClassRange(0x1800, 0x180a, IDENT); /* Mongolian punctuation */ SetCharacterClassRange(0x2000, 0x200a, BLANK); /* spaces */ SetCharacterClassRange(0x200b, 0x200f, CNTRL); /* formatting */ SetCharacterClassRange(0x2010, 0x27ff, IDENT); /* punctuation and symbols */ SetCharacterClassRange(0x202a, 0x202e, CNTRL); /* formatting */ SetCharacterClassRange(0x2060, 0x206f, CNTRL); /* formatting */ SetCharacterClassRange(0x2070, 0x207f, U_SUP); /* superscript */ SetCharacterClassRange(0x2080, 0x208f, U_SUB); /* subscript */ SetCharacterClassRange(0x3000, 0x3000, BLANK); /* ideographic space */ SetCharacterClassRange(0x3001, 0x3020, IDENT); /* ideographic punctuation */ SetCharacterClassRange(0x3040, 0x309f, U_HIR); /* Hiragana */ SetCharacterClassRange(0x30a0, 0x30ff, U_KAT); /* Katakana */ SetCharacterClassRange(0x3300, 0x9fff, U_CJK); /* CJK Ideographs */ SetCharacterClassRange(0xac00, 0xd7a3, U_HAN); /* Hangul Syllables */ SetCharacterClassRange(0xf900, 0xfaff, U_CJK); /* CJK Ideographs */ SetCharacterClassRange(0xfe30, 0xfe6b, IDENT); /* punctuation forms */ SetCharacterClassRange(0xfeff, 0xfeff, CNTRL); /* formatting */ SetCharacterClassRange(0xff00, 0xff0f, IDENT); /* half/fullwidth ASCII */ SetCharacterClassRange(0xff1a, 0xff20, IDENT); /* half/fullwidth ASCII */ SetCharacterClassRange(0xff3b, 0xff40, IDENT); /* half/fullwidth ASCII */ SetCharacterClassRange(0xff5b, 0xff64, IDENT); /* half/fullwidth ASCII */ SetCharacterClassRange(0xfff9, 0xfffb, CNTRL); /* formatting */ TRACE((TRACE_R " init_classtab\n")); return; } int CharacterClass(int c) { int i, cclass = IDENT; for (i = classtab[0].first; i <= classtab[0].last; i++) if (classtab[i].first <= c && classtab[i].last >= c) cclass = classtab[i].cclass; if (cclass < 0) cclass = c; return cclass; } #if OPT_REPORT_CCLASS #define charFormat(code) ((code) > 255 ? "0x%04X" : "%d") static const char * class_name(Classes code) { static char buffer[80]; const char *result = "?"; switch (code) { case ALNUM: result = "ALNUM"; break; case BLANK: result = "BLANK"; break; case CNTRL: result = "CNTRL"; break; case OTHER: result = "OTHER"; break; case IDENT: result = "IDENT"; break; case U_SUP: result = "superscript"; break; case U_SUB: result = "subscript"; break; case U_CJK: result = "CJK Ideographs"; break; case U_HIR: result = "Hiragana"; break; case U_KAT: result = "Katakana"; break; case U_HAN: result = "Hangul Syllables"; break; default: sprintf(buffer, charFormat(code), code); result = buffer; break; } return result; } /* * Special convention for classtab[0]: * - classtab[0].cclass is the allocated number of entries in classtab * - classtab[0].first = 1 (first used entry in classtab) * - classtab[0].last is the last used entry in classtab */ int SetCharacterClassRange(int low, int high, int value) { TRACE(("...SetCharacterClassRange (U+%04X .. U+%04X) = %s\n", low, high, class_name(value))); if (high < low) return -1; /* nothing to do */ /* make sure we have at least one free entry left at table end */ if (classtab[0].last > classtab[0].cclass - 2) { classtab[0].cclass += 5 + classtab[0].cclass / 4; classtab = TypeRealloc(struct classentry, (unsigned) classtab[0].cclass, classtab); if (!classtab) abort(); } /* simply append new interval to end of interval array */ classtab[0].last++; classtab[classtab[0].last].first = low; classtab[classtab[0].last].last = high; classtab[classtab[0].last].cclass = value; return 0; } void report_wide_char_class(void) { static const Classes known_classes[] = {IDENT, ALNUM, CNTRL, BLANK, U_SUP, U_SUB, U_HIR, U_KAT, U_CJK, U_HAN}; int i; printf("\n"); printf("Unicode charClass data uses the last match\n"); printf("from these overlapping intervals of character codes:\n"); for (i = classtab[0].first; i <= classtab[0].last; i++) { printf("\tU+%04X .. U+%04X %s\n", (unsigned) classtab[i].first, (unsigned) classtab[i].last, class_name((Classes) classtab[i].cclass)); } printf("\n"); printf("These class-names are used internally (the first character code in a class):\n"); for (i = 0; i < (int) XtNumber(known_classes); ++i) { printf("\t"); printf(charFormat(known_classes[i]), known_classes[i]); printf(" = %s\n", class_name(known_classes[i])); } } #endif /* OPT_REPORT_CCLASS */ #ifdef NO_LEAKS void noleaks_CharacterClass(void) { FreeAndNull(classtab); } #endif #endif /* OPT_WIDE_CHARS */ #ifdef TEST_DRIVER #if OPT_WIDE_CHARS static void usage(void) { static const char *msg[] = { "Usage: test_charclass [options] [c1[-c1b] [c2-[c2b] [...]]]", "", "Options:", " -a show all data", " -s show only summary", " -v verbose" }; size_t n; for (n = 0; n < sizeof(msg) / sizeof(msg[0]); ++n) { fprintf(stderr, "%s\n", msg[n]); } exit(EXIT_FAILURE); } static int expected_class(int wch) { int result = wch; wint_t ch = (wint_t) wch; if (wch < 0 || ch == '\0' || ch == '\t') { result = BLANK; } else if (iswcntrl(ch)) { result = CNTRL; } else if (iswspace(ch)) { result = BLANK; } else if (ch < 127) { if (isalnum(ch) || ch == '_') { result = ALNUM; } } else if (ch == 170 || ch == 181 || ch == 186) { ; } else if (iswalnum(ch)) { result = ALNUM; } return result; } static int show_cclass_range(int lo, int hi) { int cclass = CharacterClass(lo); int ident = (cclass == lo); int more = 0; if (ident) { int ch; for (ch = lo + 1; ch <= hi; ch++) { if (CharacterClass(ch) != ch) { ident = 0; break; } } if (ident && (hi < 255)) { ch = hi + 1; if (CharacterClass(ch) == ch) { if (ch >= 255 || CharacterClass(ch + 1) != ch) { more = 1; } } } } if (!more) { if (lo == hi) { printf("\t%d", lo); } else { printf("\t%d-%d", lo, hi); } if (!ident) printf(":%d", cclass); if (hi < 255) printf(", \\"); printf("\n"); } return !more; } static void report_resource(int first, int last) { int class_p; int ch; int dh; class_p = CharacterClass(dh = first); for (ch = first; ch < last; ++ch) { int class_c = CharacterClass(ch); if (class_c != class_p) { if (show_cclass_range(dh, ch - 1)) { dh = ch; class_p = class_c; } } } if (dh < last - 1) { show_cclass_range(dh, last - 1); } } static int decode_one(const char *source, char **target) { int result = -1; long check; int radix = 0; if ((source[0] == 'u' || source[0] == 'U') && source[1] == '+') { source += 2; radix = 16; } check = strtol(source, target, radix); if (*target != NULL && *target != source) result = (int) check; return result; } static int decode_range(const char *source, int *lo, int *hi) { int result = 0; char *after1; char *after2; if ((*lo = decode_one(source, &after1)) >= 0) { after1 += strspn(after1, ":-.\t "); if ((*hi = decode_one(after1, &after2)) < 0) { *hi = *lo; } result = 1; } return result; } static void do_range(const char *source) { int lo, hi; if (decode_range(source, &lo, &hi)) { if (opt_all) { while (lo <= hi) { int other_rc = CharacterClass(lo); if (!opt_quiet) printf("U+%04X\t%s\n", lo, class_name(other_rc)); ++lo; } } else if (opt_check) { while (lo <= hi) { int expect = expected_class(lo); int actual = CharacterClass(lo); if (actual != expect) printf("U+%04X\t%s ->%s\n", lo, class_name(expect), class_name(actual)); ++lo; } } else { printf("\"charClass\" resource for [%d..%d]:\n", lo, hi); report_resource(lo, hi + 1); } } } #endif /* OPT_WIDE_CHARS */ /* * TODO: add option to show do_range in hex */ int main(int argc, char **argv ENVP_ARG) { #if OPT_WIDE_CHARS int ch; #endif (void) argc; (void) argv; #if OPT_WIDE_CHARS setlocale(LC_ALL, ""); while ((ch = getopt(argc, argv, "acsv")) != -1) { switch (ch) { case 'a': opt_all = 1; break; case 'c': opt_check = 1; break; case 's': opt_quiet = 1; break; case 'v': opt_v = 1; break; default: usage(); } } init_classtab(); if (optind >= argc) { do_range("0-255"); } else { while (optind < argc) { do_range(argv[optind++]); } } report_wide_char_class(); #else printf("wide-character support is not configured\n"); #endif /* OPT_WIDE_CHARS */ return 0; } #endif /* TEST_DRIVER */ xterm-399/xterm.log.html0000644000000000000000000235076615012470763014072 0ustar rootroot XTERM - Change Log

    Copyright © 1997-2024,2025 by Thomas E. Dickey


    Contents

    Here is the latest version of this file.

    It began as a list of the changes that I made for xterm, using the notes that I added when submitting a patch. You should note that other changes were made as well, by other people, to fix bugs and correct ifdef's for portability. Until mid-2006, most of these were summarized in the XFree86 CHANGELOG).

    Patch #399 - 2025/05/18

    • add configure check for inline, for c89 support.
    • further improve integration between UTF-8 and allowC1Printable (report by Matthieu Herrb).
    • modify one of the missing-character checks to prefer Xft's check over the check for missing line-drawing characters (Debian #1084794).
    • align terminfo building blocks in terminfo to correspond to recent refactoring/trimming in ncurses.
    • revise a limit-check in selection to fix a regression in patch #398 (Debian #1105738).
    • modify configure check for Xft to work around recent change to fontconfig's pkg-config file (Gentoo #953864).

    Patch #398 - 2025/04/11

    • modify DECFRA and DECRQCRA to handle NRCS and ISO character set mappings.
    • ensure that the cursor GC is updated when switching between normal and italic fonts (report/testcase by Peter Fabinski).
    • reduce overflow in scaling of ReGIS coordinates (report/testcase by Robert L Masterson).
    • improve permissions-check for valid shell program.
    • extend modifyOtherKeys and formatOtherKeys to the various categories of special keys, i.e., cursor-keys, function-keys, keypad-keys, modifier-keys and (other) special-keys.
      • review/extend convmap.pl to handle all of the X11 keysym definitions in keysym2ucs.
      • keysyms which do not correspond to Unicode character codes are mapped to Unicode private use areas in the BMP and plane 15.
      • add/extend control sequences for the new format- and modify-resources.
    • fix copy/paste error in configure script for default value of --enable-block-select (report by Vincent Lefèvre).
    • revise keysym2ucs.c, to provide mapping to/from the Unicode private use area for non-character keysyms. Also remove redundant items from keysym.map.
    • improve modifyOtherKeys, by providing the UCS value for keys which have no single-byte representation (Debian #1093056).
    • add two extensions to modifyOtherKeys:
      • setting modifyOtherKeys to 3 makes all keyboard input send escape sequences, using parameter 1 where no modifiers are given.
      • a subparameter can be added to the XTMODKEYS control sequence, telling xterm to factor-out the corresponding modifier mask from available parameters in the modifyOtherKeys feature.
    • add items ColumnMode and StatusLine to disallowWindowOps, for DECCOLM, DECANM and DECSASD, DECSSDT respectively (report by Sami Farin).
    • fix several minor issues reported by Coverity.
    • add ColorEvents resource to provide a way for applications to send a client message which can modify the default foreground and background colors (adapted from patch by Claes Nästén).
    • add special case for displaying an error for CAN (cancel) when emulating VT100 (prompted by discussion with Thomas Wolff).
    • correct the size of a CellData buffer in xtermReportSGR seen in ASAN2 (report by Sami Farin).

    Patch #397 - 2025/01/05

    • add resource printRawChars to allow bypassing check in patch #389 which omits Unicode non-characters from printing (request by Adam Saponara).
    • add visible-effect for SUB, per DEC 070 page 5-132.
    • correct a limit-check in private mode 1045.
    • add optional feature for block-selection, bound to meta-button-one (patch by Adam Saponara).
    • if started as a VT52, identify the terminal as a real VT52 rather than VT52 emulated by VT100.
    • amend change to VT52 cursor-addressing per DEC 070 (mintty #1299).
    • correct ctlseqs.ms suffix for XTTITLEPOS

    Patch #396 - 2024/12/02

    • fix stricter warnings provided by upcoming gcc 15, as well as NetBSD lint.
    • modify title-stack test script, adding logging and command-replay options. Improved the script with new controls:
      • add XTTITLEPOS query to get position in title-stack.
      • add DECRQSS for XTSMTITLE.
    • correct cursor-addressing limit for VT52 mode (report by Serguei Fichel).
    • amend change in patch #395 for 7-bit parsing to allow UTF-8 titles (report by Dmytro Bagril).
    • portability fixes for configure script, from ncurses
    • update config.guess, config.sub

    Patch #395 - 2024/10/24

    • add DECRQSS response for DECSTGLT, i.e., ANSI SGR color.
    • add Russian and SCS NRCS character set mappings.
    • remove obsolete code for OS390 and VMS.
    • minor fixes to work with vttest 20240929's 7-bit parsing test.
    • improve DECRPM responses for unsupported modes; those which are valid for a given DEC terminal are reported as permanently reset rather than unknown.
    • add JIS-Roman and JIS-Katakana character sets, for VT382.
    • fix typo in ctlseqs.ms note about function key vs DSR (report by Michael Thomas Greer).
    • formatting fixes for ctlseqs.ms (report by Mark Manning).
    • update tables in wcwidth.c based on Unicode 16.0.0

    Patch #394 - 2024/09/02

    • add -nomap option (request by Tavis Ormandy).
    • improve checks for rectangle operations, per DEC 070.
    • improve check for missing characters in bitmap fonts, for a case where the font is marked complete but its range does not include non-Latin1 codes (prompted by discussion with Craig Leres).
    • correct upper-limit in check for missing characters, from patch #393 changes (report/patch by Matthew Martin).
    • fix for -report-fonts option when the font's first character position is nonzero (prompted by discussion with Craig Leres).
    • add null-pointer check for a Heisenbug (Debian #1078255).

    Patch #393 - 2024/07/11

    • add a check for ANSI SC/RC, to ignore CSI parameters.
    • improve check for missing characters for bitmap-fonts by using the normal font for reference in the case where the current font, e.g., the wide-font was derived from the normal font and lacks per-character metrics (report by Rajeev V. Pillai).
    • fix regression in error-recovery for SGR parameters from patch #357 (report by James Holderness).
    • remove some duplicates in xtermcfg.h (report by Matthew Green).
    • change default for --enable-imake configure option.
    • fixes for wcwidth:
      • return 0 for format effectors, like a zero-width printing character rather than -1 like a control character (report by Rajeev V. Pillai).
      • correct doublewidth to account for reserved codepoints which are listed in the EastAsianWidth file.
      • add a special case for surrogate pairs, which might be checked in testing the wcwidth function.
    • amend sixel bounds-check added in patch #371 to not wrap out-of-bounds data.
    • eliminate maxStringParse limit for SIXEL.
    • improve logic which ignores APC, PM and SOS controls to also not accumulate their data temporarily in a buffer.
    • exclude TERM_INGRESS from cleanup of environment variables (patch by Iain Riley).
    • fix some documentation typos (report by Thomas Wolff).

    Patch #392 - 2024/05/22

    • improve input decoding for non-Latin1 character sets by preserving the sense of GL/GR.
    • add resource preferLatin1 to simplify UPSS configuration (Gentoo #932154).
    • build-fix for --disable-boxchars; patch #390 reuses that feature's code to draw the part of the DEC Technical character set which has no Unicode equivalent.
    • modify #include of pty.h to work with musl (report by Khem Raj).
    • improve definitions used in clock_gettime logic in graphics_sixel.c, as well as updating comments (patch by Ben Wong).
    • amend allowC1Printable changes from patch #391, restoring a special case which caused C1 characters to be ignored (report/testcase by Dmytro Bagrii).

    Patch #391 - 2024/05/12

    • improve integration between UTF-8 and allowC1Printable.
    • alter SIXEL HLS computation to make blue 0 degrees (patch by Ben Wong).
    • disable SIXEL aspect-ratio, pending a rewrite (patch by Ben Wong).
    • add resource incrementalGraphics (prompted by patch by Ben Wong).
    • reorganize graphics_sixel.c as a step toward eliminating graphics buffer-size (integrated patch by Ben Wong).
    • use __linux__ consistently rather than the older linux.
    • build-fix for musl (report by Jonáš Vidra, adapted patch by Khem Raj):
      • modify ifdef for USE_OPENPTY, changing test for __GLIBC__ to __linux__
      • change ifdef's for _POSIX_SOURCE to _POSIX_VERSION
      • modify ifdef for setsid to use a configure-script check for that function's existence and move the old check to imake fallbacks.
    • minor consistency fixes for manpage.
    • fix regression in patch #390: non-UTF8 text pasted as a XA_UTF8_STRING was not decoded (report by Petri Kaukasoina).

    Patch #390 - 2024/02/19

    • improve typography of control-sequences page (patches by Branden Robinson).
    • amend UPSS change from patch #389, fixing a regression in VT100/VT220 character sets.
    • modify ANSI conformance per ECMA-43 and DEC 070:
      • set ANSI conformance level to 3 for DEC levels 2 and up.
      • disable locking shifts in level 1, e.g., VT100.
      • disable single-shifts from G2/G3 in level 1.
      • use UPSS for G2/G3 in levels 2 and up.
    • modify invisible-character attribute to permit DECRQCRA to report a consistent checksum (report/testcase by Thomas Wolff).
    • align terminfo building blocks in terminfo to correspond to recent refactoring/trimming in ncurses.
    • set flag in regexec call for onNClicks to handle “^” anchor (patch by Matthew Martin).
    • add line-drawing data for the characters in DEC Technical which have no Unicode equivalents.
    • remove a special case in encode_scs which made xterm report Latin-1 when encoding is set to UTF-8, where ASCII is the selected character set. This fixes a regression in vttest for the DECRSPS cursor test.
    • correct values for Ps of DECAUPSS in ctlseqs.ms (report by James Holderness).
    • simplify/correct expression for checking Unicode non-characters (report by Thomas Wolff).
    • correct loop for trimming environment variables (report/patch by Casper Dik).
    • fixes for manpage formatting (Debian #1041809).
    • update config.guess, config.sub

    Patch #389 - 2024/01/01

    • interchange variables in subparameter parsing, fixing a bug where subparameters after the first parameter could be misidentified (patch by Adam Saponara).
    • correct popping of icon/window titles in a case where only one was pushed from patch #385 changes.
    • add XTQMODKEYS response in DECRQSS, as alternative for vim.
    • correct DECCIR encoded information on character set size, handle a VT525 quirk, and add DECST8C (Windows Terminal #14984).
    • improve DECRQCRA (prompted by discussion with James Holderness, Windows Terminal #14974).
    • add part of VT525 color controls:
      • DECAC, to update default foreground/background, respond to DECRQSS
      • DECATC, to respond with DECRQSS
    • prevent Unicode non-characters from being printed (prompted by patch by Grady Martin).
    • modify send_SGR() to avoid modifying colors 16 to 255 in printed output (patch by Grady Martin).
    • minor cleanup of miscellaneous error-codes with ERROR_MISC.
    • remove legacy CSI 53 for locator status, corrected in patch #294.
    • modify DECRQUPSS and DECAUPSS feature to support VT5xx character sets (report by Thomas Wolff).
    • improve configure script:
      • reduce configure-check compiler warnings (prompted by Florian Weimer, Redhat #2251945)
      • improve usage messages in configure script to make it clearer when an option value is optional.
    • improve EWMH handling (report/analysis by Edward Rosten)
      • reset _NET_WM_STATE_HIDDEN flag from _NET_WM_STATE before mapping the window to deiconify.
      • cache X properties to reduce latency (adapted from patch by Edward Rosten).

    Patch #388 - 2023/10/22

    • improve disallowPasteControls by adding a category for the special characters known to stty (prompted by discussion with David Leadbeater).
    • amend support of DECAUPSS, undoing change to initialization of G2/G3 so that pasting of GR characters works properly (report/analysis by Petri Kaukasoina).
    • update config.guess, config.sub

    Patch #387 - 2023/10/15

    • add DECRQUPSS and DECAUPSS.
    • add DECRQDE (report by Jake Hamby).
    • correct indexing expression in title-stack, from patch #385 changes (report by Brian Lindholm).

    Patch #386 - 2023/10/09

    • improve references in ctlseqs.ms (prompted by discussion with Kirill Chibisov).
    • make the maximum amount of memory used for buffering DCS and OSC strings configurable with maxStringParse resource (report by Daniel Franke).
    • improve performance of ReGIS when initializing the largest fontsize (report by Ben Wong).
    • fix regression in SIXEL colors, in patch #385 (report/patch by Jonny Langley).
    • fix typo in --with-wtmp (report/patch by Sven Joachim)

    Patch #385 - 2023/10/01

    • fixes for ReGIS (report by Ben Wong).
      • correct conversion from HLS to RGB
      • improve font-caching performance.
    • update tables in wcwidth.c based on Unicode 15.1.0
    • improve fastScroll resource:
      • suppress screen-refreshes for carriage-returns
      • add -jf option to simplify use of this resource.
      • add a control sequence for enabling/disabling the resource.
      • enable this feature by default
    • extend title-stack feature to allow an additional parameter to directly access the stack, like the XTPUSHCOLORS and XTPOPCOLORS feature.
    • correct size and position of box shown for double-cell character which happens to be missing from the bitmap font (report by Peter Fabinski).
    • improved configure script:
      • add pattern for uClibc-ng to CF_XOPEN_SOURCE (report/patch by Waldemar Brodkorb).
      • add configure options --with-utmp-path and --with-wtmp-path to override configure script's check for utmp/wtmp pathnames which are shown in the manual (Debian #1042767).
      • CF_XOPEN_SOURCE provides for defining _DEFAULT_SOURCE for MinGW32 and MinGW64.
      • sed expression used to report gcc version now works with MinGW
    • ensure that line-attributes are reset after drawing missing character (report by Christian Weisgerber).
    • update config.guess, config.sub

    Patch #384 - 2023/07/10

    • exclude ASCII space from showMissingGlyphs, since a few bitmap fonts lack this (report by "SanRemo", Emanuel Haupt).
    • correct a step in rendering double-width characters with bitmap-fonts (report by Peter Fabinski, Debian #1039986).
    • fixes for ReGIS-related problems (report by Ben Wong):
      • mimic an undocumented hardware VT340 feature which handles color initialization with incomplete parameters.
      • handle whitespace between operator/operands for color values.
      • reset ReGIS-context when resetting graphics in RIS.

    Patch #383 - 2023/06/27

    • expand description of full- and soft-reset in the manual.
    • fixes for full- and soft-reset:
      • clear alternate screen on full reset.
      • disable menu-entry for active icon; it merely shows whether the feature is enabled.
      • use appcursorDefault and appkeypadDefault resources for reset of DECCKM and DECKPAM.
      • save initial resource values for sixelScrolling and privateColorRegisters, using those in full reset.
      • update checkbox for Enable Blinking Cursor (report by Rajeev V. Pillai).
    • add reply for DECSACE with DECRQSS.
    • modify status-line feature to exit without erasing for DECSTR.
    • add private mode 1045 which imitates the original xterm cursor-back reverse wrapping mode 45 (see patch #380).
    • improve checks for non-Unicode values, e.g., in DECRQCRA.
    • re-checkout from RCS archive to fix stale identifiers (report by Sven Joachim).

    Patch #382 - 2023/05/30

    • amend change to CursorBack in patch #380, allowing the result to be on the hidden right-half of double-cell characters (report by Rajeev V. Pillai).
    • amend xtermDrawString, fixing regression with --disable-wide-chars configuration from patch #380.
    • corrected pathname for run-tic.sh, for full install in an out-of-tree build (report by Rajeev V. Pillai).

    Patch #381 - 2023/05/28

    • fix a regression in wide bitmap fonts versus check for missing glyphs (report by Rajeev V. Pillai).

    Patch #380 - 2023/05/09

    • simplify the change for sixelScrolling from patch #374 (report by Per Bothner).
    • add xterm+focus and report+da2, update report+version building blocks in terminfo, from post-ncurses 6.4
    • drop the -title option from uxterm and koi8rxterm, because that interferes with deriving the default title from the -e option (Debian #1031837). Compensate for this by using the -class option to derive a default title.
    • improve description of readline 2003 mode in ctlseqs.ms (report by Thomas Wolff).
    • other improvements to status-line feature (report by Thomas Wolff):
      • clear status line on DECCOLM
      • ignore DECSASD if no previous DECSSDT
      • allow DECSSDT 1 immediately after DECSSDT 2, i.e., without switching back to host mode.
    • adjust RequestResize to avoid shrinking screen when using DECCOLM while the status-line is active (report/patch by Thomas Wolff).
    • disallow wrapping before the beginning of the screen, to the end of the screen, for cursor-back sequences (Redhat #2182357).
    • modify makefile to install the 16x16 xpm files (report by Harald Dunkel).
    • update test-package to reflect resolution of Debian #906901.
    • change default of showMissingGlyphs to True.
    • improve handling of double-sized characters when those happen to be missing from the bitmap font and/or are fullwidth.
    • pointer/overflow fixes (reported by David Leadbeater):
      • improve limit-checks for control-sequence numeric parameters in SIXEL graphics.
      • add null-pointer checks in WriteNow macro to handle a case where SS2 or SS3 might be in effect while processing a combining character.
      • disallow ReGIS reporting for character-set names containing characters other than alphanumerics or underscore.
      • implement TrueType fallback font for double-sized characters, including Unicode fullwidth. Also add limitFontHeight to provide for configuring the distinction between slightly-oversized glyphs and double-sized glyphs.
    • configure script improvements:
      • check for nfsd_t
    • fix a typo in the underline cursor thickness derivation (patch by Jan Engelhardt).

    Patch #379 - 2023/02/15

    • improve text-cursor (patch by Jan Engelhardt):
      • allow selecting CURSOR_BAR mode from command-line/Xresources.
      • draw cursor using filled rectangle instead of rectangle outline to permit thicker underlines/bars.
      • scale up cursor relative to font size.
    • improve readline modes (Fedora #2166860):
      • document readline modes
      • change the feature to configure by default
      • replace hard-coded SS3 for cursor movement with current mode
      • replace hard-coded erase/lnext characters with current values
    • improve status-line (report by Thomas Wolff):
      • RIS turns off status-line
      • Right-margin (DECLRMM and DECSLRM) limits the length of text written/updated in the status-line.
      • Most controls which affect the whole screen are ignored while updating the status-line.
    • modify configure check for tgetent to allow for some special cases of ncurses configuration (report by Satadru Pramani).
    • reduce timeout, improve warning message if resize is run on a terminal which is not VT100-compatible.
    • reduce compiler warnings in configure script.

    Patch #378 - 2023/01/09

    • improve descriptions of XTQMODKEYS and XTQALLOWED features in ctlseqs.ms (reports by Bram Moolenaar, Thomas Wolff).
    • add bracketed+paste and report+version building blocks to terminfo, from ncurses 6.4
    • improve check for unsupported formatting characters, e.g., zero-width space, to properly ignore them (report by Thomas Wolff).
    • improve/document error-checking for some of the controls which return responses: DECRQSS, XTGETXRES, XTSETTCAP, XTGETTCAP (prompted by discussion with David Leadbeater).
    • improve limit-checks for fallback font cache (report by Dimitrije Erdeljan).
    • improve check for too-wide glyph in fallback font by allowing xterm to continue searching for a suitable font rather than just failing on the first. Also add limitFontWidth to allow changing the amount by which a glyph must extend outside the font's bounding box to disallow it.

    Patch #377 - 2022/11/25

    • add control sequences for reporting the current state of the modified keys options (XTQMODKEYS) and allowed/disallowed operations (XTQALLOWED), (prompted by discussion with Bram Moolenaar).
    • amend modifyOtherKeys case 2 to distinguish the escape character with modifiers, e.g., shift-escape, from a plain escape character (suggested by Bram Moolenaar).
    • improve parsing and error-recovery in the case where a list of X11 bitmap fonts is given in the -fn and related options.
    • change default for xftTrackMemUsage to false, because libXft does not handle certain fonts.

    Patch #376 - 2022/11/16

    • modify configure script to always check for gcc attributes,
    • update install-sh.
    • fix parsing of result -u in vttests/halves.pl.
    • add a note in ctlseqs.ms about compatibility of TBC.
    • fix a copy/paste error in manual (patch by Grady Martin).
    • add null-pointer checks in x_strcasecmp and x_strncasecmp, to help with error-recovery for a missing font (Debian #1022942).

    Patch #375 - 2022/10/23

    • improve error-recovery when setting a bitmap font for the VT100 window, e.g., in case OSC 50 failed, restoring the most recent valid font so that a subsequent OSC 50 reports this correctly (report by David Leadbeater).
    • exclude MC_XDG_OPEN from environment variables trimmed on startup (report by Gabor Hauzer).
    • check for null pointer in isSelect() (report by Column Paget).

    Patch #374 - 2022/10/10

    • eliminate use of grep aliases from vttests scripts.
    • amend discussion of DECSDM versus Sixel Scrolling in ctlseqs.ms (reports by Hayaki Saito, Ben Wong).
    • change default for sixelScrolling resource to better match VT330/VT340 DECSDM setting (patch by Ben Wong).
    • fix some gcc and coverity warnings.
    • improve memory usage for OSC 52 (report by David Leadbeater).
    • fix regression in xterm-373 change adding resources xftTrackMemUsage to xftMaxGlyphMemory, which did not first cache the server's resource-settings (report/testcase by Gabor Hauzer, as well as Debian #1021243).
    • fix regression in xterm-373 change for status-line vs alternate screen (report by Rajeev V. Pillai).
    • configure script improvements:
      • modify CF_XOPEN_SOURCE to handle more special cases of Linux (reports by Adam Sampson, Sven Joachim).
      • modify checks for egrep/fgrep aliases to work around warning messages from GNU grep 3.8

    Patch #373 - 2022/09/25

    • improve rendering of TrueType fonts:
      • add resource xftTrackMemUsage to enable/disable a new feature of Xft which improves performance.
      • add resources xftMaxGlyphMemory and xftMaxUnrefFonts to customize memory-usage of Xft and fontconfig.
      • provide for display of colored fonts in libXft 2.3.5
      • allow for an extra TrueType font to be specified using the -fa option, as an override to the fontconfig scheme of fallback fonts (request by Nickolas Raymond Kaczynski).
      • improve caching of TrueType missing-glyph tests.
      • allow no more than 255 fonts to be scanned for a fontset.
      • eliminate a table-lookup in findXftGlyph
    • improvements status-line feature:
      • save/restore wraparound flag when updating the status-line (report by Rajeev V. Pillai).
      • avoid clearing the status-line when switching between normal and alternate screens (report by Valtteri Vuorikoski).
      • remove adjustment from update_winsize leftover from initial work (report by Valtteri Vuorikoski).
    • modify wcwidth tables to separate Unicode Cf category as formatting control-characters, to better match the guideline for unsupported characters (report by Tim Chase).
    • add configure option --disable-exec-selection.
    • use mkstemp where mkdtemp is unavailable, when initializing colored cursor.
    • adapt fixes from OpenBSD xenocara:
      • improve ifdef's for a few optional features.
      • correct #ifdef to #if in a few uses of OPT_PRINT_ON_EXIT.
    • set StartupWMClass in “.desktop” files, e.g., to help cinnamon-session notice that xterm sets WM_CLASS and use its icon (patch by Richard de Boer).
    • disable pixel computation when rgb width is greater than 8, to work with depth 30 (patch by Denis Kaganovich).
    • improve color-computation for SGR 2 faint/dim (patch by Boian Bonev). Add resource faintIsRelative to specify if the modified computation should be used (prompted by discussion with Matthieu Herrb).
    • correct comparison-length for environment variable cleanup (patch by Brendan O' Dea).
    • correct dsl capability for dec+sl block in terminfo (report by Rajeev V. Pillai).
    • improve output formatting by vttests/utf8.pl
    • repair test/demo scripts still using "vxt-" prefix, some cleanup with shellcheck.
    • enable page-number for DECXCPR response in VT330.
    • amend change for combining characters in patch #371 to limit it to the currently-defined codes (report by Thomas Wolff).
    • add directory-template parameter to mktemp in shell-scripts to improve portability to older systems (patch by Ryan Schmidt).
    • mention webpage XTerm – bracketed-paste in ctlseqs.ms
    • update manual-page descriptions for allowPasteControls and disallowedPasteControls (patch #363).
    • further extended list of environment variables to purge on startup (suggested by Thomas Wolff).
    • update config.guess, config.sub

    Patch #372 - 2022/03/09

    • amend allocation/freeing of scrollback lines, eliminating an adjustment for status-line added in patch #371 (report/testcase by Rajeev V. Pillai).

    Patch #371 - 2022/02/24

    • drop double-buffer default from test-packages, since that interferes with status-line.
    • add faceSize7 to table in charproc.c, overlooked in patch #360 (patch by Vladimir A. Pavlov).
    • use XDrawString rather than XDrawString16 for text when the latter is not needed.
    • improve performance for initializing/reusing graphic objects in the SIXEL feature.
    • improve error-checking for resize.
    • fix errata in manual page (Debian #988221).
    • extended list of environment variables to purge on startup, i.e., in case a user starts xterm from another terminal emulator.
    • add comment in cursor.c to explain why autowrap (DECAWM) does not apply to data saved/restored with save/restore cursor-operations (report by Thomas Wolff).
    • add special case in generating the combining-character table in wcwidth.c, for Hangul Jamo Extended-B (report by Luis Javier Merino).
    • simplify/improve portability of trap commands in shell-scripts.
    • update configure options
      --disable-rectangles,
      --disable-tcap-fkeys and
      --disable-tcap-query
      to account for changed default settings.
    • rather than ignore empty parameter for setting title, use that to reset it to “xterm” for scripting.
    • check for out-of-bounds condition while drawing sixels, and quit that operation (report by Nick Black).
    • add fallback definition for PROJECTROOT so that a suitable default location for luit will be compiled-in on build-servers.
    • implement DEC status-line controls DECSASD/DECSSDT:
      • decode controls, set state
      • implement DECRQSS responses
      • implement indicator-style status-line
      • add configure option --enable-status-line
      • add resource indicatorFormat
      • implement host-writable status-line, able to handle video-attributes and simple left/right cursor movement. This disallows all of the DEC/xterm private modes such as switching to/from the alternate screen.
      • move the status-line if the window is resized.
      • Note: the associated screen-resizing does not work for the special case of TrueType fonts with double-buffering (see note in patch #349).
    • modify configure-script fixup for -Werror options to exclude fixup for -Werror=format, e.g., -Werror=format-security.
    • amend change from patch #370; DEC 070's pseudo-code for DECCOLM incorrectly suggests that it enables DECLRMM as a side-effect.
    • fix some memory leaks seen using esctest and asan2 (patch by Luis Javier Merino).

    Patch #370 - 2021/11/13

    • add -a, -c and -d options to query-status.pl to improve test for DECRQSS.
    • expanded discussion of maximum graphics geometry in ctlseqs.ms (suggested by Bon Wong).
    • corrected parameter symbol for DECCARA and DECRARA in ctlseqs.ms to indicate that multiple parameters may be used (report by Thomas Wolff).
    • add several test/demo scripts.
    • improve DECCOLM, DECLRMM and DECALN referring to pseudo-code in DEC 070.
    • amend a change in patch #348 which caused left/right margin mode to be reset when resizing the terminal window (report by Valentine Barshak).
    • fix a misnamed macro-parameter (patch by Rajeev V. Pillai).
    • fix spacing of wideFont when its width is not exactly twice as wide as the normal font (report by Rajeev V. Pillai).
    • suppress loading of italic font in a few places when colorITmode is enabled (report/analysis by Rajeev V. Pillai).
    • modify XTSMGRAPHICS to return failure status if the terminal is not configured to support the corresponding ReGIS or SIXEL feature (report by Nick Black, notcurses #2252, notcurses #2257).
    • modify DECERA and DECFRA to erase corresponding area in SIXEL graphics (patch by Nick Black, notcurses #1740, vt340test #16). Also modify DECSERA.
    • equate visuals for TrueColor and DirectColor (patch by Denis Kaganovich).
    • correct computation for pixel value of rgb when using depth 16 (report by Denis Kaganovich).
    • correct wrapping of VT100-style double-sized characters when configured for Unicode wide-characters (report by Luis Javier Merino).
    • updated default value for sixelScrolling resource to match expected behavior versus DECSDM change in patch #369 (report by Grant Taylor).

    Patch #369 - 2021/09/21

    • modify run-tic.sh to work around bug in development version of ncurses which was packaged in FreeBSD ports.
    • remove ifdef's for OPT_COLOR_RES and OPT_COLOR_RES2.
    • improve performance over slow connections (report by Harald Dunkel).
    • update cursor if restoring mode for DECTCEM.
    • modify CharWidth macro to ensure that the shortcut for Latin-1 is only applied when UTF-8 is not enabled, to fix a bug in handling soft-hyphen from patch #334 changes (patch by Martijn van Duren).
    • improve terminfo:
      • fill-in function-keys in terminfo which are not Sun/HP keyboards using xterm+nopcfkeys building-block.
      • add kbeg to xterm+keypad to accommodate termcap applications
      • add smglp and smgrp to vt420+lrmm, to provide useful data for the "tabs" +m option
    • support shift-tab in Sun, HP and SCO keyboards.
    • document some legacy features in ctlseqs.ms (prompted by discussion with Jimmy Aguilar Mena "Ergus").
    • add “trim” option to cdXtraScroll and tiXtraScroll.
    • remove support for non-fifo save-lines configuration.
    • extend cdXtraScroll to check if the cursor is at the upper-left of the scrolling region when the erasure is for the remainder of the screen versus the whole screen (prompted by discussion with Jörg Breitbart).
    • add workaround for broken pcre2 package in Debian 10.
    • change screen-refresh call used for DECCARA and DECRARA to ensure that trailing blanks which are part of the rectangle are repainted (report/analysis by Dennis Filder).
    • when resetting the terminal, ensure that the cursor shape also is reset, e.g., if DECSCUSR has been used to modify the cursor shape for an xterm which was started with the underlined cursor option (report/analysis by Luis Javier Merino).
    • prevent DECSCUSR from blinking the cursor if the cursorBlink resource is “never” (report by Vladimir D Seleznev).
    • invert the sense of DECSDM, to correspond with VT382 manuals (lsix #41).
    • update tables in wcwidth.c based on Unicode 14.0.0

    Patch #368 - 2021/06/07

    • add DefaultOff option to RenderFont resource, as part of the session-management feature.
    • add auto-scroll-lock feature (patch by Stelios Bounanos).
    • update the window-size information returned via TIOCGWINSZ when rows/columns are unchanged but the font-size changes (report by Nick Black).
    • improve session-management feature by saving/restoring the font settings.
    • update config.guess, config.sub

    Patch #367 - 2021/03/26

    • add OSC 22 to allow programs to select different pointer cursor at runtime.
    • change configuration for no-return functions to use _Noreturn when it is available, because clang --analyze does not properly handle the gcc noreturn attribute.
    • add cursorTheme resource to provide a way to enable or disable the cursor theme feature.
    • modified CopyWait event retries to use shorter sleeps, to improve responsiveness (tmux #2556).
    • improve quoting/escaping in demo-scripts per shellcheck.
    • add resizeByPixel resource, to permit disabling window manager resizing-hints (patch by Tim Oehl).
    • corrected printOptsImmediate handling of alternate-screen (report by Abhijit Dasgupta).
    • update sample terminfo to more closely match ncurses.
    • add/improve limit-checks for Xlib calls (report by Roman Fiedler).
    • fix a typo in the help-message (report by Tomas Korbar).

    Patch #366 - 2021/02/10

    • correct a compiler-warning fix in patch #352 which allowed sign-extension of coordinate values (report by "CismonX").
    • correct upper-limit for selection buffer, accounting for combining characters (report/testcase by Tavis Ormandy).
    • with alwaysHighlight true, xterm does not properly track focus. The screen->select FOCUS flag remains always on, which prevents bellIsUrgent from working, as the urgent WM_HINT flag is only set in setXUrgency() when the window is not focused. Fix this by updating screen->select in unselectwindow() regardless of the value of always_highlight (patch by Jiri Bohac).
    • improve fix for interaction between SRM and ENQ (report by Grant Taylor).
    • build-fix for --with-Xaw3dxft, needed when --with-toolbar is omitted (report by Jimmy Olgeni, Emanuel Haupt).

    Patch #365 - 2021/02/03

    • amend fix for “word” selection in patch #364 to limit that to the insert-selectable action, which reads data from the screen. This restores the interactive behavior where double-clicking on a “word” would make subsequent selection extensions by words as well as suppressing some boundary-checks (report by David Wolfskill, FreeBSD #253225).

    Patch #364 - 2021/02/02

    • add -fc option.
    • correct/improve limit-checks for SRM versus ENQ from patch #344 (report by Tom Szilagyi).
    • enable XftFont resource in Xaw3dxft configuration (patch by Tavis Ormandy).
    • improve quoting/escaping in build-scripts per shellcheck.
    • add libpcre2-posix to the packages tested for --with-pcre2 option, needed with Fedora (report by Tomas Korbar).
    • correct a typo in manual page, and note that KeepClipboard may not be compiled-in (report/patch by Sean C Farley).
    • corrected boundary-checks for “word” selection used in onNClicks resources (report by Tavis Ormandy).
    • update to autoconf-2.52-20210101, to improve shellcheck warnings.
    • improve configure check for desktop categories.

    Patch #363 - 2020/12/26

    • disable groff hyphenation in generated html when using man2html.
    • change SCS “&4” Cyrillic to non-NRCS, per VT520 manual.
    • amend fix for SCS in patch #198 to remove DEL rather than converting it to a space (report by Thomas Wolff).
    • modify state transitions for selecting character sets to eliminate an ambiguity between the “A” used in VT220 versus VT320.
    • improve error recovery when selecting characters by resetting to US ASCII when no suitable encoding is found, e.g., attempting to use an NRCS sequence when NRCS is not enabled.
    • turn off hyphenation in “.txt” conversion, prompted by groff changes.
    • add VT5xx ISO Latin-2 (prompted by discussion with Thomas Wolff).
    • amend change from patch #361 to event-handling in CopyWait to handle active-icon as a special case (Debian #975687).
    • add call to loadColorTable to get the visual information needed to decode BE RGBA32 color format (patch by Leandro Lupori).
    • modify the resource-parsing for disallowedPasteControls and similar lists of names/numbers to recognize “~;” (tilde) for cancelling a given name/number.
    • add ENQ, EOT and NUL to default for disallowedPasteControls.
    • change default for disallowedPasteControls to omit the tab character (suggested by Harald Dunkel).
    • fix swapped height/width in regisScreenSize and maxGraphicSize resources using "auto" value, from patch #314 (report by Anton Lavrentiev)
    • revise patch #362 change for shift-modifier versus mouse protocol and select/paste by adding resource shiftEscape, which can be enabled via a control sequence (prompted by discussion with Matthijs van Duin).
    • simplify/improve ifdef in trace code for using a separate set of files for each run of xterm.
    • add options -r and -t to vttests/query-color.pl to show the 6-digit RGB code and actual colors.
    • add nel to xterm-basic terminfo.
    • alter vttests/modify-keys.pl to omit HTML reference links to the modified-keys table where no keycode was available.

    Patch #362 - 2020/11/11

    • cleanup of calls to free, removing checks for null (Walter Harms).
    • improved mouse-button reporting (prompted by discussion with Stephane Chazelas)
      • narrow the scope of the change for shift-key in patch #361 to make it apply only when the modifyOtherKeys resource is set to 2 (i.e., “program mode”). Also, when checking the shift-key, ignore modifiers other than shift, control and “meta”
      • use the alt/meta modifier information obtained in VTInitModifiers to replace a hard-coded mod1 used to detect “Meta” for mouse-button responses.
    • reduce SIGWINCH's sent to the client by filtering out duplicates.
    • improve display when scaleHeight is greater than 1:
      • the text-cursor is vertically-centered on the current line, rather than only extending below the current line (report by Manu Chaturvedi).
      • the built-in line-drawing characters extend to the scaled cell-height.
    • fill-in special case for motion-events to match the changes for shift-key in pointer-button events from patch #361.

    Patch #361 - 2020/10/14

    • treat the return value of strerror as readonly (patch by Philipp Klaus Krause).
    • modify event-handling in CopyWait to work around hanging while writing large amounts of text to an active icon and at the same time iconifying/deiconifying (report by Dave Kemper).
    • initialize double-buffer for active-icon window.
    • improve manual page description of scrollbar resources (report by Brian Lindholm).
    • correct ifdef for menu entry for active-icon, when initializing it with toolbar configuration.
    • add preprocessor option to makefile to set internal definition of pixmaps directory to match the install-configuration (FreeBSD #250036).
    • cleanup of calls to free, removing checks for null (Walter Harms).
    • add fallback actions pointer-button and pointer-motion which handle events for the mouse control-sequences protocol if the select-related translations are omitted with *omitTranslation:select (prompted by discussion with "Ergus")
    • amend rule for using shift-key to override mouse-protocol for select/paste to limit that feature to mouse-buttons which are actually bound to select/paste actions (prompted by discussion with "Ergus").
    • corrected mapping in special case for repainting wrap-marks when viewing the scrollback area.
    • use separate GCs for showWrapMarks feature, to work around cursor coloring change in patch #345 (report by Paulo Silva de Alíbano).

    Patch #360 - 2020/09/20

    • mention decGraphicsID in ctlseqs.ms (suggested by Thomas Wolff).
    • modify pixel-coordinate mouse response to use as origin the VT100-window rather than the underlying widget, which includes the scrollbar (report by Thomas Wolff).
    • add configure option --disable-print-graphics (Ross Combs).
    • add test_ptydata to “make check” rule.
    • minor fixes for ctlseqs.ms (report by Jean-Marc Bourguet).
    • minor fixes for manpage style (report/patch by "a1346054").
    • correct cleanup from switch between italics/normal font in the show/hide cursor functions (report/testcase by Peter Fabinski).
    • integrated patch by Ross Combs:
      • internal renaming of GraphicsID symbols, for readability.
      • adjust logic for VT125, treating it as a ReGIS terminal.
    • update configure macros, for compiler-warning fixes.
    • integrated patch by Ross Combs:
      • add control sequence modes for graphics printing.
      • improve conversion to bitmaps for TrueType fonts in ReGIS
      • add font7 resource, for an “enormous” bitmap font.
      • do not reset graphics in a soft-reset.
      • add pointerFont resource, and -pf command-line option.
    • improve typography of manual page (patch by Branden Robinson).
    • amend patch #359 change to df-install.in to ignore a command-line assignment to DESTDIR if followed by an explicit --dir (report by Sven Joachim).

    Patch #359 - 2020/08/17

    • add special case in WriteText to allow colors 8-15 to override colorBDMode (patch by Ingo Brückl).
    • add utf8Weblike resource, to provide an alternate scheme for handling ill-formed UTF-8 sequences (adapted from patch by Dan Gohman).
    • improve computation for the number of lines needed to scroll-up a SIXEL graphic (report/patch by Ben Wong).
    • correct manpage description for default value of disallowWindowOps from changes in xterm #331 (patch by Ben Wong).
    • correct a loop starting-point in refresh_graphics from optimization in patch #358 changes (report by Ben Wong).
    • add a new mouse mode 1016, which uses the same format as mode 1006, but sends the mouse's position in pixels (suggested by Igor van den Hoven).
    • fix an issue from patch #338 changes where only the first selection buffer specified in the request would be updated using OSC 52 (patch by Michael Gulick).
    • modify makefile/scripts to allow DESTDIR to prefix the target directory for desktop-file-install (report by Fred Heitkamp).
    • enable SIXEL feature by default.
    • update config.guess, config.sub

    Patch #358 - 2020/07/12

    • correct logic for decodeTerminalID changes in patch #357 (report by "Chartreuse").
    • modify makefile to use plink.sh when linking test-programs, to fix build when using pcre (report by H Merijn Brand)
    • build-fix for test_ptydata program (patch by H Merijn Brand)

    Patch #357 - 2020/07/05

    • several minor optimizations for the ReGIS and SIXEL features, improving performance by 10%.
    • add resource decGraphicsID to allow displaying graphics when the emulation level would ordinarily disallow this (prompted by discussion with Thomas Wolff).
    • add control sequences for fast switching of color palettes: XTPUSHCOLORS, XTPOPCOLORS, XTREPORTCOLORS
    • amend change for soft-hyphen from patch #328 to avoid stripping replacement-characters which would be shown with malformed or overlong UTF-8 input.
    • corrected an error-handling case in decodeUtf8, matching a similar fix in patch #268 (report/patch by Dan Gohman).
    • add a test-driver for ptydata.c
    • minor cleanup of macros (adapted from patch by Walter Harms).
    • fix some errata in ctlseqs.ms (report by Thomas Wolff).
    • allow immediate repaint-on-palette-changed if double-buffering is enabled.
    • deprecate codes 10/11 in sgr push controls, changing those to 30/31, to avoid confusion with sgr 10-19.
    • modify SGR parameter handling to stop if an unrecognized parameter is encountered, to guard against malformed or nonstandard sequences (report by Bram Moolenaar).
    • modify DECERA color for consistency with other erasures/clearing (report by Thomas Wolff).
    • ECH should not be masked by DECSCA (report by Thomas Wolff).
    • extend DECFRA and REP to accept any “graphic” character rather than just Latin1, etc. (report by Thomas Wolff).
    • add -C option to 256colors2.pl and 88colors2.pl, to demonstrate mixed semicolon/colon separators which are implied by ECMA-48.
    • update sample terminfo to reflect the documentation improvements.
    • update description of 88/256/direct color in ctlseqs.ms to point out that using semicolons is a deprecated legacy feature, and standard terminal applications should use colons (prompted by discussion with Bram Moolenaar).
    • modify configure-check for tgetent to conditionally include termcap.h, enabling configuration using clang's pedantic-errors option (report by Dennis Clarke). See Other Compatibility in ncurses' curs_termcap(3X).
    • remove some unnecessary pointer checks (patch by Walter Harms).
    • accept terminal-id and add DA response for VT131, VT132.

    Patch #356 - 2020/05/02

    • revise fix for Debian #954730, which interfered with wheel mouse events (report by Gabriele Balducci).

    Patch #355 - 2020/05/01

    • revise fix for Debian #954730, which interfered with wheel mouse events (report by Henri Menke).
    • fix typos in documentation (reports by Stephen Hurd, Stefan Assmann).
    • add mapping for decTerminalID for “100” overlooked in patch #354.
    • update tables in wcwidth.c based on Unicode 13.0.0
    • build-fix for “make check” when building out-of-tree (report by Sven Joachim).

    Patch #354 - 2020/04/26

    • work around performance problems of XDrawImageString and XDrawImageString16 functions (Debian #954845).
    • add a control sequence which reports xterm's version (patch by Nicholas Marriott, mintty #881).
    • temporarily set numeric locale category to "C" when parsing resources, so that scaleHeight and faceSize settings do not depend on locale (Debian #820803).
    • improve DA/DA2 response by ensuring that the decTerminalID maps to one of the known identifiers, as well as providing DA2 response for VT241 and VT382.
    • terminfo improvements:
      • add (my) comments from ncurses which explain the keypad layouts.
      • add vt52+keypad from ncurses
      • use improved xm example for xterm+x11mouse, xterm+sm+1006 from ncurses 6.2 terminfo.src
    • two fixes for left/right wheel mouse event reporting (Debian #954730):
      • filter identical button-events
      • correct order of button-range versus protocol type (see patch #345)
    • change “make check” makefile-rule to use test-drivers for charclass and wcwidth data.
    • quiet “did not find a usable xxx TrueType font” warnings by making fontWarnings apply to these messages (report by Jim Rees).
    • improve reinitialization of parameter list (report/testcase by James Holderness).
    • temporarily set numeric locale category to "C" when formatting SVG or XHTML screendumps, to make the radix separator used in RGB values consistent (adapted from patch by George Kouryachy).
    • add resource forceXftHeight to control whether workaround from Debian #880407 is used.
    • apply updated ascent/descent in workaround from Debian #880407 to fix a 1-pixel gap in built-in vertical lines (report/testcase by Stefan Assmann).
    • improve round-off of scaling for built-in line-drawing (prompted by discussion with Stefan Assmann).
    • adjust fonts in svg-icon files to accommodate reduced functionality of new pango (report/analysis by YOKOTA Hiroshi).
    • improve configure check for X Toolkit library.
    • correct Y-coordinate transformation in ClearCurBackground, overlooked in changes for patch #334 (report/analysis by Chuck Silvers).
    • remove --vendor option from test-packages' install of desktop files; the feature is badly broken in gnome-shell.
    • modify uxterm to make it possible to select nonstandard locale C.UTF-8, e.g, if the user's locale is set to “C” (Debian #940626).
    • re-save/tweak “.svg” icon-files to work around breakage in toolset since the files were created in patch #283.

    Patch #353 - 2020/02/01

    • amend change in patch #352 for button-events to fix a case where some followup events were not processed soon enough (report/patch by Jimmy Aguilar Mena).
    • handle MappingNotify X event, to improve recovery when switching keyboard configurations using xkbcomp (prompted by discussion with Frank Mosch, Debian #661295). There is more work needed here, possibly in the X libraries.
    • improve discussion of mouse-mode in ctlseqs.ms (suggested by Igor van den Hoven).
    • further improve checks for Xft max-advance-width to take into account fonts which use two cells for ambiguous width characters. Also improve the time used for these checks (reports by Yuri Pankov, Frank Mosch).
    • fix a few spelling errors reported by codespell (report by Jens Schleusener).
    • modify run-tic.sh to prefer development version of ncurses since changes to terminfo file in patch #345 rely upon bug-fixes in ncurses (prompted by discussion with Will Senn).

    Patch #352 - 2020/01/16

    • adjust fontsize data to handle a minor inconsistency from recent Xft versions (Debian #880407, adapted from patch by Vincent Lefèvre).
    • add a table to the manual page description of forceBoxChars to alert the reader to the special characters aside from “line-drawing” which are drawn directly when this resource is set (Debian #931305).
    • improve checkXft logic which attempts to detect fonts whose max-advance-width is inconsistent with the actual glyph widths. For some fonts, it is necessary to check additional characters (report/analysis by Jan Engelhardt).
    • improve configure-checks for X headers and libraries on recent MacOS, which has moved those files under /usr/X11.
    • improve portability of iconify/deiconify feature by taking into account some window managers which manipulate the EWMH _NET_WM_STATE property, adding/removing _NET_WM_STATE_HIDDEN rather than actually minimizing the window (prompted by discussion with Jörg Breitbart).
    • improve workaround from patch #287 for the -iconic option when configured with toolbar by postponing the extra request for minimizing the window to the end of menu-initialization.
    • modify xevents special-case for mouse-events to include button-events so that the meta key by itself can generate button-events (report/analysis by Mattias Engdegård).
    • amend SGR-stack change from patch #348 to not associate bold attribute with background color (report by Nicholas Marriott).
    • fix copy/paste error in manual page (patch by Larry Hynes).
    • add definitions in xterm_io.h so that GNU/Hurd will use posix_openpty (patch by Samuel Thibault).
    • build-fix in debug-tracing, for esctest.
    • updated autoconf macros
    • update config.guess

    Patch #351 - 2019/11/17

    • correct logic in property_to_string for deciding when to fallback from UTF-8 decoding to ISO-8859-1 decoding, broken in xterm #350 (FreeBSD #241961).
    • add -report-icons to help-message.
    • improved autoconf macros:
      • CF_ADD_LIBS: the change to filter out duplicates caused this to append rather than prepend. revise to fix that.
      • CF_GCC_VERSION and CF_GCC_WARNINGS: move checks to distinguish icc/clang from gcc from the macro which handles the --enable-warnings option, to make this work without-warnings for the inline-checks.
    • update config.guess, config.sub
    • correct status in XTGETXRES replies when the resource was not found.
    • fix some gcc, cppcheck, clang and coverity warnings.
    • guard call to RequestResize from the struct-notify event handler to prevent recursion in the Xft+buffered workaround in some cases when doing manual resizing rather than resizing via escape sequences (reports by Stefan Assmann, Mike Thornburg).
    • amend the workaround for Xft+buffered blanking by moving the switch to bitmap-fonts to account for differences in font metrics between bitmap- and TrueType-fonts (report by Stefan Assmann).
    • improve the note on the xterm-rep terminfo entry (prompted by discussion with Sven Joachim).

    Patch #350 - 2019/11/02

    • modify html/svg dump to not ignore zero'd/blank cells.
    • align terminfo file with ncurses, e.g., add xterm+osc104 block.
    • improve discussion of modifyOtherKeys in manual page and in ctlseqs.ms.
    • add vttests/modify-keys.pl script to illustrate the modifyOtherKeys resource (prompted by discussion with Bram Moolenaar).
    • various improvements to ctlseqs.ms, as part of autogenerating links for the website.
    • update manual page default for saveLines resource default value (Branden Robinson, Debian #913815).
    • add command-line option -report-xres to show the values of the VT100 widget X resources when initialization is complete.
    • add a control sequence which, like tcap-query, allows an application to inspect most X resource settings of the VT100 widget.
    • adjust some optional features to enable them in the imake configuration as they would be by default via the configure script.
    • add null-pointer checks to improve error recovery when bitmap fonts are missing or corrupt (report by Jonne Ransijn).
    • correct the condition for deleting the EWMH window-title property, i.e., if UTF-8 titles are disabled, rather than if an update to the EWHM property found no change (report by Sven Joachim).
    • build-fix for the case when configure --enable-trace is used without --enable-warnings (report by Sven Joachim).
    • fix a few minor bugs found with Coverity.
    • add a check in property_to_string to avoid translating UTF8_STRING or COMPOUND_TEXT into Latin-1 when UTF-8 encoding is active, e.g., when pushing onto the title-stack while switching to the alternate screen.
    • build-fix for the --disable-doublechars configure option (report by Brian Lindholm).

    Patch #349 - 2019/09/22

    • add graphic context to support bold+italics (patch by Quinn Strahl).
    • document window properties in the manual page.
    • improve title-string feature:
      • if any of allowC1Printable, utf8Title or titleModes hint that an application might send a title-string encoded in UTF-8, check if that is the case, and if it is recodable into ISO-8859-1, use that for the ICCCM-style title.
      • check if the title given by a control sequence happens to be already encoded in UTF-8, to avoid double-encoding (FreeBSD #240393).
      • Make sameName resource work for the EWMH titles.
      • Modify menu-state of utf8Title to be consistent with the utf8 source, i.e., setting the EWMH properties automatically when UTF-8 is active.
    • reorganize text-drawing to make it possible to investigate using Xft to implement VT100-style double-sized characters. While doing this, made a workaround for apparent Xft bug which loses its drawable state when switching from 132 to 80 columns.
    • improve font-warning messages by showing which are derived rather than directly from resource settings (suggested by Tomas Korbar). Also filter repeated font-warning messages, to accommodate broken X configurations.
    • fix an inconsistency between failure to load derived wide font versus failure to load derived wide-bold font (Redhat #1679790). That relies upon the “:unscaled” property which is broken in some distributions (however, recent Debian and the BSDs such as MacOS work).
    • updated autoconf-252 to check X11R7 include/lib directories found on some older configurations.
    • set a graphic-context for border when double-buffering is active; to prevent the border color from changing when switching to reverse-video.
    • build-fix for --disable-ziconbeep, which conflicted with the new double-buffer configuration (report by Brian Lindholm).
    • fix loop-limit for lookup of fullscreen resource broken in xterm #347 (report by Scott Bertilson).

    Patch #348 - 2019/07/22

    • update window-manager hints when exiting Tek4014 mode (Debian #932569, patch by Jonathan Irwin).
    • fix a misformatted printf in report-sgr.pl.
    • add configure check for termios types, to improve compiler-warnings.
    • ensure that when resetting margins, to also reset DECLRMM. This affects DECCOLM, DECALN (although DEC STD 070 mentions only top/bottom margins), and DECSTR.
    • corrected order of reset/move when setting DECCOLM, and make it more consistent by always resetting margins, rather than only when the mode is changed (report by James Holderness).
    • compile-in double-buffer support by default, changing the configure option to set the default resource value for buffered to true or false.
    • take in account the reverse-video state when computing the filler-color used when clearing the screen in double-buffering configuration.
    • correct logic for filtering scrollbar-updates when buffered resource is compiled-in but not enabled (report by Paul Lampert).
    • improve state saved/restored for cursor-save and SGR stack features.
    • improve description of 1006 and 1005 mouse modes, to avoid implying that they use character-parameters (report by Bryan Christ).
    • explain in ctlseqs.ms that some of the numeric keypad keys were xterm extensions rather than VT100/VT220 terminal features (prompted by discussion with Thomas Wolff).
    • explain in ctlseqs.ms how the DEC windowing extension is supported by xterm.
    • add 28 rectangular editing to the primary response (suggested by Thomas Wolff).
    • fix a typo, improve wording in ctlseqs.ms (Thomas Wolff).
    • fix internal column-parameter when SL or SR is used with left/right margins (patch by Thomas Wolff).
    • fix off-by-one in VT52 graphics character mapping (patch by Thomas Wolff).
    • use _X_UNUSED, etc., when available as a fallback for GCC_UNUSED, etc., to reduce compiler warnings when building with imake.
    • update config.sub

    Patch #347 - 2019/06/30

    • fix a few minor bugs found with Coverity.
    • improve double-buffering for scrollbars combined with scrolled text; add bufferedFPS resource to control the maximum rate of screen updates (report by Mike Thornburg).
    • improve fixes for DECCRA handling of double-width characters (patch by Martin Hostettler).
    • improve discussion of ECMA-48's typographical error for SD in ctlseqs.ms (prompted by report by Martin Hostettler).
    • correct off-by-one in parameter limit-check for DECCRA (report by Martin Hostettler).
    • modify saveCellData to handle case where double-width character is partially copied; that should be blanked (report/testcase by Thomas Wolff).
    • add resource buffered to allow enabling/disabling double-buffered mode.
    • two fixes for the double-buffer configuration, prompted by MacPorts' switch to double-buffering (patch by Mike Thornburg, MacPorts #58313):
      • ensure that the needSwap flag is set after drawing TrueType text
      • corrected the drawable-parameter used for the bar-cursor
    • modify ScrnRefresh to ignore a case where the left/right halves of a double-width character have been set to different video attributes. The attribute to use is in the left-half (report/testcase by Thomas Wolff).
    • correct a limit-check for DECCRA in case the target lies off-screen (report/testcase by Thomas Wolff).
    • documentation errata (report by Thomas Wolff).
    • reset flags including wraparound and reverse-wrap when switching to VT52 mode, while noting that DEC's standard documentation leaves that behavior undefined (report by Thomas Wolff).
    • ensure that italic font is turned off on hard/soft resets (report by Martin Hostettler).
    • improve responsiveness to X events while processing HTML or SVG dumps (report by Martin Hostettler).
    • replace logic in wcwidth.c for detecting double-width characters with binary-search table generated using updated uniset (report by Robert Ross).
    • add test-driver for wcwidth.c to simplify comparison with system's wcwidth.
    • ensure that window-manager name comparisons work when active-icon is enabled, since CSI13t uses the window-manager name (report by Glenn Golden, Arch #62818).
    • trim a stray “experimental” in one of the comments about the tcap-query feature, which has been a supported feature since 2008 (see patch #238).

    Patch #346 - 2019/05/27

    • update description of the “default” setting for the renderFont resource to match the behavior in patch #261 (Debian #862042).
    • account for internalBorder in useBorderClipping (report by Robert Ross).
    • update table of unknown-width characters in wcwidth.c based on Unicode 12.1.0 (prompted by discussion with Robert Ross).
    • improve description of DECSCL versus S7C1T and S8C1T in ctlseqs.ms.
    • improve consistency between CSI3t and CSI13t, accounting for differences between some window managers' handling of EMWH extents (report by Bram Moolenaar).
    • fix a sign-extension when reporting offscreen window position (report by Bram Moolenaar).

    Patch #345 - 2019/05/14

    • updated FreeBSD test-package from recent /usr/ports scripts.
    • workaround in run-tic.sh for HPUX, whose mktemp prints the name of a temporary directory without creating it.
    • add left/right margin capabilities to terminfo, since the default terminal emulation is VT420 (suggested by Thomas Wolff).
    • modify treatment of reverseVideo for dynamic colors to make text foreground/background consistent with the cursor color (prompted by discussion with Ben Wong, lsix #20).
    • modify button-handling to make SGR button-release distinct from button-press for button-codes starting with 8 (patch by Mikulas Patocka).
    • add aliases for the sgr push/pop controls to work around language limitations of C# (request by Dan Thompson).
    • correct a typo in setDirectFG, which could cause setting of indexed-color after a direct-color to be ignored.
    • add resource useBorderClipping as an alternative to useClipping (request by Robert Ross).
    • improve logic for displaying xterm's built-in line-drawing characters vs missing glyphs, e.g., for U+2409 to U+240D (patch by Robert Ross).
    • add vttests/sgrPushPop2.pl to illustrate how selective pushes work, as well as to demonstrate push/pop of the various color types supported by xterm.
    • fix a special case in XTPOPSGR where direct-colors were not checked as a dependency of indexed-colors, contrary to documentation.
    • reduce buffer-flushes for OSC 4 and OSC 5 color-queries, as well as in the queries for dynamic colors.
      Note: this change makes the reply for OSC 5 use the “5” in the response; formerly it was mapped to ”4” after adding the maximum number of colors.
    • modify vttests/query-color.pl to demonstrate multiple queries in one request.
    • update tables of combining and unknown-width characters in wcwidth.c based on Unicode 12.0.0.
    • modify response for OSC 5 to be consistent with documentation.
    • add vttests/query-dynamic.pl
    • modify vttests/query-color.pl to accept bold, underline, etc., keywords to decide whether to use OSC 5 rather than OSC 4.
    • modify cursor coloring to avoid a case where the cursor matched the foreground color while the text was displayed in reverse-video (report by Nuno Silva).
    • fix an inconsistency in X10 mouse responses from patch #342 changes; the legacy protocol supports only buttons 1-3.
    • reduce the number of buffer-flushes for tcap-query batches.
    • modify tcapquery.pl to demonstrate batch queries with -q option.
    • increase response-buffer size, and make it configurable as limitResponse (prompted by discussion with Stephen P Wall).
    • modified configure script:
      • check/workaround for non-POSIX manipulation of predefined symbols
      • check for updated X Toolkit, which uses const.
    • update config.guess, config.sub
    • provide for secondary-selection, overlooked in patch #338 (report by Emile LeBlanc).
    • documentation errata (patch by Larry Hynes).
    • improve pointer-checks in Tekproc.c
    • revise solution for Debian #919475, to allow for struct-notify events occurring as a side-effect of toggling to/from full-screen mode.
    • window's border-size was incorrectly added to position when maximizing window (report by Gary Langshaw).

    Patch #344 - 2019/02/12

    • add ASCII escape to default for disallowedPasteControls (prompted by discussion with Martin Hostettler).
    • fix typo in ctlseqs.ms (Robert Ross).
    • implement DEC Cyrillic NRCS (based on screenshots of vttest provided by Markus Schmidt).
    • correct control returning sixel geometry maximum versus actual size (patch by Ben Wong).
    • improve manual page for resize to clarify that resize does not execute the shell commands which it generates for setting environment variables.
    • improve memory-management for parser, to handle response strings that might occur with ENQ or when SRM mode is active (patch by Martin Hostettler).
    • change Comment text in uxterm's desktop file to work around a limitation of GNOME's GIO application (issue #940). The documentation reads:

      Searches desktop files for ones that match search_string.

      The return value is an array of strvs. Each strv contains a list of applications that matched search_string with an equal score. The outer list is sorted by score so that the first strv contains the best-matching applications, and so on. The algorithm for determining matches is undefined and may change at any time.

    • a check of zIconBeep resource was removed in double-buffer fix in patch #334. That is used to decide whether to handle struct-notify events. When xterm does handle the events, it may negotiate a new window-size with the window manager. In that case, the limitResize resource setting limited the new window-size to the screen-size. Amended that by eliminating the limit for this special case when double-buffer is configured, and restoring the check for zIconBeep when double-buffer is not configured (Debian #919475).
    • disallow recursion which could happen if a user configures the answerbackString resource with the ENQ code and experiments with that code when SRM is enabled (report by by Martin Hostettler).
    • add remaining credits in COPYING file.
    • modify run-tic.sh to check if it is using an older version of ncurses which does not support large terminal descriptions, and if so, remove a non-essential feature to keep within the 4096-byte legacy limit.

    Patch #343 - 2019/01/13

    • modify run-tic.sh to prefer ncurses6 over ncurses5, when available.
    • add COPYING file, and dummy "check" makefile rule for testing Arch packages.
    • add/update package scripts for FreeBSD and NetBSD, for testing.
    • update tables of combining and ambiguous-width characters in wcwidth.c based on Unicode 11.0.0.
    • modify xterm-new sample terminfo entry to correspond to ncurses 6.1, using the SGR 1006 mouse protocol.
    • improve manual page discussion of selection ownership versus highlighting (prompted by discussion with Martin Hostettler).
    • restore/repair keepClipboard feature which was broken by changes in patch #338 (report by Martin Hostettler).
    • improve documentation for deleteIsDEL resource.
    • modify DECRQM response for private mode 1037 to account for cases where the resource deleteIsDEL is initially neither true nor false, but dependent upon the keyboard type (report/analysis by Martin Hostettler).
    • clear pointers for pattern/fontset after destroying their data when switching facename with an escape sequence (report by Robert Ross).
    • modify logic for TrueType fallback fonts to match the sort-order used by fc-match (report by Robert Ross).
    • add resource setting limitFontsets which can be used to limit or disable the new TrueType fontset feature (request by Robert Ross).

    Patch #342 - 2019/01/03

    • limit mouse-button events to 11 buttons in the original protocol, and 15 in the extended mouse-protocol (patch by Martin Hostettler).
    • correct calculation for buttons past 11 in mouse-codes sample script (patch by Martin Hostettler).
    • disable a supplementary check added in patch #341 which interferes with using fontconfig to select different-sized bitmap fonts (Arch #61237).

    Patch #341 - 2018/12/24

    • add options to mouse-codes script to demonstrate that the encoding used for mouse events limits button numbers to 11.
    • allow mouse button numbers up to 11 using an offset of 128 for button numbers 8-11 rather than the offset of 64 used for wheel-mouse, etc., buttons 4-7 in patch #338 (adapted from patch by Martin Hostettler).
    • correct off-by-one right-margin checks for double-width character adjustments in DECERA/DECFRA (patch by Martin Hostettler).
    • allocated size of selection buffer was not reset when freeing the buffer in patch #338 (report/analysis by Stefan Assmann).
    • modify the initial pattern passed to fontconfig to disallow color bitmap fonts.
    • improve error recovery for a case where fontconfig ignores the requested pattern due to override in the user's font configuration (report/testcase by Stefan Assmann).

    Patch #340 - 2018/12/16

    • suppress a spurious warning about fontsets when initializing menus for the toolbar configuration.
    • fix some strict compiler warnings.
    • improve checks for TrueType font, to help with the case of color bitmap fonts, which fontconfig misrepresents (Arch Linux #58706).

    Patch #339 - 2018/12/12

    • modify CF_GNU_SOURCE macro to treat newlib as similar to glibc, fixing a problem with the configure checks for pseudoterminals in Cygwin overlooked in patch #334 updates for configure-macros.

    Patch #338 - 2018/12/09

    • ignore $TERMINFO in the configure script if it is set to a non-directory value.
    • updated configure macros:
      • CF_WITH_PCRE2, modified to work with Debian's (mis-numbered) pcre3 package.
      • CF_CC_ENV_FLAGS , report preprocessor options in CFLAGS
      • CF_LD_RPATH_OPT , suppress check if --disable-rpath option was given.
      • CF_XOPEN_SOURCE, add case for midnightbsd
    • update config.guess, config.sub
    • add a check to ensure that the filename parameter passed to XpmReadFileToPixmap is actually a file, since that function does not check (report by Ben Nott).
    • amend solution for Debian #758633 to ensure that replies for bracketed paste are not sent while processing a selection for exec-formatted (Debian #913237).
    • improve adjustments/clearing for double-width characters in DECERA, DECFRA, DECSERA.
    • improve adjustments/clearing for double-width characters when doing vertical scrolling within left/right margins (patch by Martin Hostettler).
    • modify wcwidth to encode a few spacing combining marks as regular combining characters.
    • change compiled-in default for saveLines to match the resource-file changed in patch #192 (Debian #913815).
    • change default faceSize to 8.0, to simplify switching back/forth between bitmap fonts and TrueType. This was originally (mis)set to 14.0 in patch #148.
    • add fallback support in Xft configuration for missing glyphs (prompted by discussion with Mike Burns).
    • fix a problem with using direct-colors for the background color when clearing/scrolling (report by Nicholas Marriott).
    • add a "sources" rule for the makefile's generated source.
    • add a short explanation in ctlseqs.ms discussing the differences in error-recovery for malformed sequences versus unimplemented features, and amend one case for consistency (prompted by discussion with Martin Hostettler).
    • adjusted ifdef's so that the paste64 configure option does not automatically enable the readline-mouse configure option.
    • revert the change which prevented concurrent ownership of different selection targets, and instead modify selection storage so that different concurrent requests for different selection targets will be stored/retrieved independently (Debian #901249).
    • remove a check which prevented returning button-codes past the documented 4/5 for wheel mouse, and add a script mouse-codes which makes a report showing the various mouse codes for different button/modifier combinations (discussion with Přemysl Janouch).
    • improve display and checksum for DEC Special Graphics by mapping 0x5f to 0.
    • add a null-pointer check for table-ending in the extended-boolean resource-handling (report by Felix von Leitner).
    • remove stray ]'s from INSTALL-file (Larry Hynes).

    Patch #337 - 2018/09/21

    • regenerated configure script (report by Sven Joachim).
    • revise/improve fix for scrolling in margins (report/analysis by Martin Hostettler):
    • amend change to default-translations "select" subset to ensure that specific key-press actions are listed before generic key-press actions (reports by H Merijn Brand, Sven Joachim).

    Patch #336 - 2018/09/19

    • ensure that only one of PRIMARY and CLIPBOARD is owned by xterm at a given time (Debian #901249).
    • documentation fixes (report by Lars Krueger):
      • document SL and SR.
      • document DECRPTUI, change number of digits to match VT420.
    • revise omitTranslation resource, e.g., splitting “default” into several more useful categories.
    • modify mask-logic to permit control- and meta- modifiers to be used in mouse protocol.
    • several fixes for parsing/state (report/testcases by Martin Hostettler):
      • remove an old/unimplemented entry for xterm-title from state table.
      • save/restore wrap-flag when scrolling, to fix an inconsistency between jump-scrolling and normal-scrolling.
      • improve a special case of wrapping where the cursor starts beyond the right-margin, and wraps at the terminal's last-column before the settable-margins can take effect.
      • if origin mode is set, adjust a restored cursor column relative to the left margin.
      • when scrolling a line within left/right margins, correct order of the fixups needed when a double-width character crosses the margin boundary.
    • review/fix a few cases where the parsing state was not reset after completing a control sequence (prompted by report by Martin Hostettler).
    • disallow XTCHECKSUM if the corresponding window-ops "SetChecksum" is unset.
    • add print-vt-chars.pl script to illustrate the NRCS and codepages supported by xterm.
    • add other-sgr.sh script to demonstrate the non-VT100 video attributes implemented in patch #305, and added a summary of their introduction in ECMA-48 to the control sequences document.
    • add tabs and -tabs keywords to ttyModes resource to simplify workaround for terminal drivers which are not aware of UTF-8 (FreeBSD #229682).
    • add VT5xx NRCS 7-bit Turkish and DEC Turkish.
    • add VT5xx NRCS 7-bit Hebrew and DEC Hebrew.
    • add VT5xx NRCS 7-bit Greek and DEC Greek.
    • correct a few post-VT220 codepages to make them display without setting the NRCS state.
    • extend vt100Graphics resource to include other character-sets such as the VT500 codepages in UTF-8 mode.
    • add some VT5xx codepages to help with the discussion of 96-character sets: ISO Greek Supplemental, ISO Hebrew Supplemental, ISO Latin–5 Supplemental, and ISO Latin–Cyrillic.
    • improve description of the VT300-controls for designating character sets, and fix a typo which indicated that some were used for 94-character sets (prompted by discussion with Lars Krueger).
    • add private control XTCHECKSUM for modifying checksumExtension.
    • factor out xterm's DECRQCRA checksum extensions as a resource setting checksumExtension.
    • revise calculation of checksum for DECRQCRA to match DEC's terminals (using screenshots of vttest provided by Markus Schmidt).
    • restore a fix for memory-checksum setup of DECCKSR from patch #315 incorrectly reverted in patch #334 as part of fix for DECRQCRA.

    Patch #335 - 2018/08/14

    • add colorInnerBorder resource to make a change from patch #334 configurable (reports by H Merijn Brand, Gabriele Balducci).

    Patch #334 - 2018/08/12

    • modify Imakefile to reflect the fact that NetBSD no longer has a working termcap emulation.
    • add resource-setting validShells which can be used to augment the system's /etc/shell (prompted by discussion with Paul Lampert).
    • stifle some useless warnings from lintian in test-packages.
    • add the ncurses extension “RGB” to the responses for the termcap-query feature.
    • improved getopts-handling in sample scripts.
    • fix some warnings from gcc8 and clang --analyze.
    • update note about incorrect documentation for DECRQSS to include VT525 (report by Markus Schmidt).
    • correct check for default-values in rectangular parsing; a zero counts as a missing or default parameter (report/testcase by Markus Schmidt).
    • correct some ranges in the ambiguous[] table in wcwidth (adapted from patch by KUGA Tsutomu).
    • fix a special case with faint video attribute incorrectly combined with default color.
    • add private control XTREPORTSGR for reporting video-attributes and color on a rectangle, and script report-sgr.pl to demonstrate it.
    • modify some of the markup in ctlseqs.ms to work around groff's reassignment of ASCII punctuation characters as documented in groff_char(7).
    • treat ECMA-48 SGR 6 the same as SGR 5.
    • add private controls XTPUSHSGR and XTPOPSGR for saving/restoring the current video-attributes on a stack (adapted from patch by Dan Thompson).
    • modify DECRPM response for logging enable to indicate its state even when enabling/disabling it is not allowed.
    • implement DECSNLS
    • implement DECRSPS
    • improve fill-color for double-buffer configuration, which was sharing a graphic context with the cursor.
    • fix a couple of cases where double-sized VT100 characters were not clipped, seen in Joe Smith's VT100 torture test.
    • color the inner border using the same borderColor as the outer border, rather than filling with the VT100's default background.
    • change encoding of “THANKS” to UTF-8.
    • modify handling of DECELR to recognize MotionNotify events again, amending a check for allowMouseOps which limited that to button-events in patch #328 (Olaf Rogalsky).
    • fix some screen-painting problems with left/right margins when using insert-line or delete-line (report/testcase by Martin Hostettler). also fix similar case with index/reverse-index.
    • several minor performance improvements using macros, e.g., inline checks for character width.
    • add DECSCPP and DECSLPP to DECRQSS.
    • implement DECSCPP.
    • implement DECCIR and DECTABSR presentation reports.
    • modify checksum computation for DECRQCRA to treat uninitialized cells as blanks rather than nulls.
    • drop custom-entity from HTML-dump, use UTF-8 for &nbsp; (Debian #902381).
    • modify display of non-BMP characters when using bitmap fonts to show a null/empty box rather than the replacement character which was used in cleanup changes for patch #233 (report by Christian Weisgerber).
    • when setting up clipping rectangle for Xft, allow for the case where xterm is only displaying a combining character, where the base was already written (report by Joshua Crowgey).
    • allow reset Xft's state if switching font-sizes when double-buffering is used.
    • fix repainting, e.g., on resize, when double-buffering is used with Xft (patch by Daniel Colascione).
    • correct some interchanged pairs of symbols in unicode/keysym.map (Brad Town).
    • improve configure macros CF_GCC_WARNINGS, CF_GNU_SOURCE, CF_POSIX_C_SOURCE, CF_TRY_XOPEN_SOURCE, CF_XOPEN_SOURCE, CF_X_ATHENA_CPPFLAGS.
    • modify logFile resource to interpret “-” as the standard output (adapted patch by Colum Paget).
    • improve documentation of Tek4014 menu options; fix a case where the Tek4014 window was not displayed before switching modes.
    • re-correct parameter for pid used for DECCKSR, DECRQCSR (see xterm #315).
    • hard/soft reset now resets the cursor-blinking state that may have been set via escape sequences; the cursor-blinking menu-entry feature is unmodified (report by Matthieu Herrb).
    • update config.guess, config.sub

    Patch #333 - 2018/05/03

    • ensure that i18n is enabled if input-method is enabled.
    • modify logic for pre-edit to update spot-location while the cursor is invisible (Kakoune #1940).
    • change default icon to newer one, "mini.xterm".
    • install a complete set of icons, to simplify post-install customization.
    • add resource disallowedPasteControls to extend filtering of control characters from pastes.
    • add print-on-error action-hook, and document action-hooks for dump-html, dump-svg.
    • provide action-hook for print-immediate, which was available only as a menu-item (report by Rastislav Barlik).
    • continue to improve notes in ctlseqs.ms which mention where various controls originated.
    • add case to accept ECMA-48's bogus SD, but document the issue in ctlseqs.ms.
    • add control sequence for loading XPM-icon file, using the analogous control sequence from shelltool/dtterm.
    • add -report-icons option, to report on XPM-icon and title-bar updates.
    • correct a discrepancy between locator-reports for VT220 vs VT330.
    • add window-ops control sequences to complement existing ones for reporting window-position and text-area size with reports for text-area position and window-size.
    • display vt52 graphics mode characters.
    • correct case-statement for window-ops 10, overlooked since some window managers equate vertical-maximize and horizontal-maximize window hints with full-screen maximize.

    Patch #332 - 2018/04/15

    • add a GetChecksum item to disallowedWindowOps
    • improve notes in ctlseqs.ms which mention where various controls originated.
    • add control sequences for querying the X display size and the character size, both in pixels to help eliminate some of the constants in esctest.
    • fixes prompted by review of George Nachman's esctest script:
      • add a null-pointer check and a limit-check in xtermCheckRect.
      • correct limit-check for right-margin when processing autowrapping if xterm is not built for wide-characters.
      • repair logic in RIS to reset 132-column mode when an escape sequence is used to enable 80/132-column switching.
      • correct array-limit for EWMH working state.
      • further improve limit-checks versus assert's (see patch #315).
      • correct order of check-margins and move-to-left margin for DL and IL.
      • modify reverse-wrap to pay attention to top/bottom margins as it has done for left/right margins since patch #279.
      • modify behavior of DECFI and DECBI to not index the screen at the left/right edge of the display unless those happen to be the left/right margins.
      • add case for VT320 DSR response for keyboard status.
    • improve check for valid shell path using getusershell and endusershell if available, in case /etc/shells does not exist (suggested by Rainer Orth).
    • modified configure checks for groff and man2html, to use the latter by default, but allowing mandoc as a partial replacement for former.
    • revisited the inconsistent copyright notices mentioned in patch #165, and eliminate the issue as mentioned in this copyright discussion.
    • fix typo in this change-log (report by Sven Joachim)
    • update config.guess, config.sub

    Patch #331 - 2017/12/30

    • add workaround for improper grayscale adjustments made in FreeType library, exposed by changes to rounding in 2.8.1, which shows up as a gap in line-drawing characters (Debian #880407).
    • improve a special case where a non-Unicode font's line-drawing characters were not used, when specifying it via the utf8Fonts resource, e.g.,
              -fs 15 \
              -xrm '*VT100.font:12x24' \
              -xrm '*VT100.boldFont:12x24' \
              -xrm '*VT100.utf8Fonts.font: 12x24' \
              -xrm '*VT100.utf8Fonts.boldFont: 12x24' \
      
    • replace constant 10msec delay for next X event with new resource nextEventDelay, and reduce that to 1msec to accommodate faster machines than used when -hold was implemented in 1999 (Debian #877628).
    • add scroll-to action, which simplifies binding a key to scroll to the beginning or end of the saved-lines (Debian #880120).
    • add building blocks for alternate screen and/or title-stack features in the terminfo file.
    • improve calculations for cell-data size.
    • change configure script to enable XHTML/SVG screen dumps by default.
    • change configure script to enable 256-colors by default.
    • update config.guess, config.sub
    • change configure script option for --with-man2html to use improved script by default.
    • add case for private mode 1044 in DECRQM, to report the keepClipboard resource setting and corresponding menu entry.
    • fix an inconsistency between private mode 12 (the AT&T 610 cursor blink) and DECSCUSR: the former relied on having the cursorBlink resource set initially to enable the escape sequence, while the latter does not.
    • add private modes 13 and 14, as well as resource cursorBlinkXOR to allow better control over the cursor-blinking state (discussion with Bram Moolenaar).
    • modify the html and svg screen dumps to support direct color
    • modify media copy (screen-printing) to support the same SGR codes as DECRQSS, including 88/256 indexed color as well as direct color.
    • improve options-parsing for query-status.pl script.
    • modify parsing of SGR direct-color control making color space identitier optional. The corresponding DECRQSS reply always returns an empty (default) field for the identifier.
    • add wide-attributes to DECRQSS reply for SGR.
    • add private mode 1046 to help with scripting applications.
    • correct expression used for readline-flags in DECRQM; to test the current flag rather than information stacked within the same variable.
    • correct typo in ctlseqs.ms reference to ISO-8613-6 (patch by Mike Frysinger).
    • fix lintian warning for test-package.
    • fix typo in DECRQSS for SGR 48, which printed the foreground value for colors past 15. Also use colon delimiter for codes 38/48 in response (report by Paul LeoNerd Evans).
    • improve workaround for Debian #542434 by using the font's maximum width when no ISO-8859-1 glyphs are provided (Debian #879936).
    • work around a special case of Xft's mismanagement of its cached data by adding a check before the -report-fonts option to ensure that it does not use an XftPattern which may have been freed during a call to XftFontOpenPattern.
    • improve manual page description of regex option for onXClicks resources (report by Lukas Mai).
    • add directColor resource.
    • additional manpage macro cleanup (Branden Robinson, Debian #880551).
    • add optional support for direct-colors (adapted from patch by anonymous “Nibby Nebbulous”).
    • improve legacy/NRC character set mapping (patch by Thomas Wolff), e.g.,
      • enable alternate NRC set designators for French and French Canadian, ‘9’ and ‘f’ respectively, as documented in ctlseqs. (‘9’ is documented for VT510, ‘f’ is a Kermit feature).
      • correct the Unicode value in the DEC Technical table to show capital delta.
      • referring to

        http://vt100.net/docs/vt220-rm/table2-3b.html
        http://vt100.net/docs/vt320-uu/appendixe.html

        add entries for the DEC Supplemental Graphics table to display 0x28/0xa8 as ¤ and 0x5d/0xdd as Ÿ.

      • referring to

        http://www.vt100.net/charsets/technical.html

        alter the Unicode values used for 0x2b through 0x2c to use curly braces to work with the “middle” parts displayed with 0x2f and 0x30.

      • modify the VT220 “Supplemental” table, giving a hint that it was probably meant to be “Supplemental Graphics” and is the same as VT320's table.
    • quiet a few font-warnings when a derived fontname cannot be opened, overlooked in refactoring of font resources in patch #328 (initially reported on Cygwin mailing list, with followup).
    • correct error response for DECRQSS broken in cleanup of Coverity reports in patch #288 (reports by Bram Moolenaar and IWAMOTO Kouichi).
    • improve DECRPM responses by returning mode not recognized for modes which may not be settable due to the selected decTerminalID resource (report by IWAMOTO Kouichi).
    • correct logic for print-immediate action, and enable corresponding menu entry (patch by Lauri Tirkkonen).
    • add configure option --with-pcre2 (patch by David Michael).
    • fix a misspelled subsection title in ctlseqs.ms and add a note regarding blink which was rendered as bold in X11R6. Blinking text was implemented in Patch #60.
    • fix typos in xterm.man (patches by Sven Joachim, Larry Hynes).
    • fix typography in xterm.man (patch by Bjarni Ingi Gislason, Debian #869248).
    • fix typo in INSTALL (Larry Hynes).
    • add xterm-direct terminal description based on changes introduced in patch #277, and relying upon ncurses RGB extension.
    • modify xterm-new terminal description to use ECMA-48 REP, reflecting its use in xterm since patch #32 (1996).
    • clarify comment in ctlseqs.ms regarding blink: it has been part of xterm since patch #60 (1998).
    • update ftp URLs in documentation.

    Patch #330 - 2017/06/20

    • updates for ReGIS (Ross Combs):
      • remove redundant text command error check which broke T(B) and T(E).
      • retain the loading alphabet number across multiple “L” commands.
      • add S(T) delay handler.
      • fix some color handling error messages.
      • add stubbed-out macrograph handling.
      • use fragment_remaining() and fragment_consumed() instead of manually checking position / length in various places.
      • rename some local variables in string / extent / option parsing
      • wrap some long lines.
      • move macrograph command handling out of the top-level.
    • add a summary of the italic fonts loaded to -report-fonts option.
    • modify the font-lookup for italics to allow for “-i-” if no match is found with slant “-o-” (prompted by patch by Ben Wong).
    • change default values for mkSamplePass and mkSampleSize to reflect generally-improved locale support in various operating systems (FreeBSD #219800).
    • modify wcwidth.c to return -1 for non-Unicode values, and adjust a couple of blocks to better match assumptions about ambiguous-width characters in other implementations. Also modify wcwidth.c to support configurable soft-hyphen, so there is no drawback to using this version rather than a system wcwidth.
    • amend change made in patch #328 for cursor-visibility to handle case where an application is updating the reverse-video state (FreeBSD #219800).
    • update tables of combining and ambiguous-width characters in wcwidth.c based on Unicode 10.0.0.
    • build-fix for --enable-sixel-graphics without --enable-regis-graphics (reports by Sven Joachim, FreeBSD #219945).

    Patch #329 - 2017/06/12

    • add control sequences for reading the Sixel and ReGIS graphics sizes (suggested by Ben Wong).
    • add a workaround for wcwidth returning -1 for characters which should have been printable (FreeBSD #219800).
    • fix a bug in font initialization from patch #328 (FreeBSD #219800).
    • fix a special case in HideCursor which assigned a bold font to the slot used for normal font in changes for italics in patch #307 (Debian #858304).
    • updates for ReGIS (Ross Combs):
      • Strings specified with no command are used as "comments". Print these in the log when tracing.
      • Catch attempts to use "alternate display" mode (AKA "blink") from the GIGI, but do not implement it.
      • The T(M) command should only multiply the height by 10, not 20.
      • Make the S(E) command reset more state than just the screen contents.
      • Remove two rotation variables which were only being printed.
      • Numerous minor fixes and comment updates in the R command.
      • Unknown R command option names trigger an empty response.
      • Fix the output position after printing rotated text (it was missing the the sign before).
      • Fix the position change with pixelvectors and rotated text (the rotation transform was not being applied).
      • Update the TODO list and remove a verification FIXME (slanted text positioning is correct as is).
      • Emulate the approximately 1.4x enlargement for text which isn't rotated at right angles.
      • Only update the color planes specified in the plane mask (the W command's F option).
    • fix a bug introduced by the changes to font information in patch #328. When processing the "checkfont" option of the locale resource, the program referred to the request data, to an array which was only allocated in the new/result widget (report by H Merijn Brand).
    • fix a missing assignment initialization to make the utf8 resource control whether escape sequences to enable/disable UTF-8 mode are allowed.

    Patch #328 - 2017/06/01

    • revise parser for charClass resource, making these improvements:
      • accept octal and hexadecimal values
      • allow embedded whitespace
      • allow the class after colon to be optional, e.g., to clear class settings for a range of characters.
    • add command-line option -report-charclass.
    • fix most lintian warnings about test-package
    • add eraseSavedLines resource.
    • document DECSED 3 in ctlseqs.ms (report by Ben Longmans).
    • improve integration between configure-events and updates for reported screensize, in particular when switching between vt100 and tek4014 modes.
    • modify selection-highlighting of reverse-video text to keep that distinct, e.g., by reversing the selection foreground and background colors as one would expect. This fixes a "useless" case in the description of highlightColorMode.
    • improve fix for Debian #759734, addressing a case where non-colored cursor would be invisible against reverse-video (see patch #311).
    • updates for ReGIS (Ross Combs):
      • the "H" option of the "T" command should multiply by 10, not 20.
      • display unknown glyphs as a solid block.
      • given a succession of text-direction options, use the last.
      • fix the direction of ReGIS slanted text so that negative values produce oblique output .
      • fix the ReGIS text direction option to only rotate characters when no following size option is used.
    • update terminfo to better match corresponding entries in ncurses, e.g., u8 pattern to match the VT220, VT420, etc., primary responses, as well as adding smxx and rmxx.
    • fixes from Jörg Sommer:
      • corrected a trace-message regarding maximum graphics-size; it used the similar ReGIS maximum size which might not be configured.
      • in do_select_regex, clear selection if there is no match. If the regex does not match anything around the cursor, the selection returned must be empty, otherwise the whole line is treated as a match. This way the command defined by exec-selectable will not be executed if there is no match.
      • modify limit in do_select_regex to include the character at the cursor in the match, making it easier to type something and then hit the key to trigger exec-selectable.
      • If exec-selectable or insert-selection is triggered by a mouse button click, the position of the mouse pointer should be used. This makes it easier to address any position on the window and it makes it possible to use the mouse, e.g., for applications such as mutt where you cannot move the cursor.
    • modify DECRC to save/restore xterm's last-column flag used to control wrapping behavior rather than manipulating DECAWM (report/analysis by Mattias Engdegård).
    • add configure option --enable-terminfo-env to use the value set by --with-own-terminfo for the $TERMINFO environment variable. That variable was set automatically for HPUX, but would be useful in other systems, e.g., for Solaris (request by Jeff Wieland).
    • fix a race condition when setting up a signal handler to timeout if opening /dev/tty hangs (patch by Tobias Stoeckmann).
    • review/cleanup resources which were not in the manual page (report by Maxwell Anselm):
      • add manual page description as needed.
      • drop resource name for menuBar, as unnecessary.
      • modify fallback numeric value for regisScreenSize resource to match that for maxGraphicSize.
    • updated configure macros CF_ADD_CFLAGS, CF_CC_ENV_FLAGS, CF_GNU_SOURCE, CF_MATH_LIB, and CF_XOPEN_SOURCE from other program-changes.
    • update config.guess, config.sub
    • change “maximum screensize” assumed by resize to 9999x9999, to accommodate people using the Unreadable font.
    • drop Utility from default value of --with-desktop-category (Debian #780176).
    • widen the configure script pattern used for finding related ".desktop" files, including “Terminal”
    • several minor improvements to font utility functions:
      • provide for later modification to implement font-sets by parsing the font resources as comma-separated lists.
      • parse -fn and -fa similarly, using “x:” and “xft:” prefixes for font name/family strings to distinguish between XLFD and Xft font specifications.
      • use loops to iterate over font classes
      • use getters/setters for font data to allow for on-demand lookups.
      • make the debugging trace for missing glyph less verbose since that interferes with the -report-fonts option.
      • refactor xtermLoadFont to make it clearer how some fonts are derived from others, e.g., bold, wide.
      • make the triggering and suppressing of font-warnings more consistent by storing the last state in the widget.
      • reduce font-warnings by checking for repeated warnings.
    • add vttests/query-status.pl
    • add vttests/closest-rgb
    • add special case for displaying soft-hyphen if it happens to fall at the right margin, and omitting similar case such as the BIDI markers, where a zero-width character is neither a control character nor a combining character (Debian #844325).
    • modify logic for OSC 52, manipulate selection data, to update the selection-time to include the latest X events. This fixes some cases where the selection was invalid, e.g., after an event due to focus-follows-mouse (report/testcase by Stephane Chauveau).
    • revise macro CastMallocN as new macro TextAlloc to make explicit use of sizeof(char) (prompted by patch by Cade Foster).
    • add “Mouse Ops” menu entry and related resources to allow runtime disabling/enabling of the mouse protocol escape sequences (discussion with Bob Proulx).
    • improve discussion of mouse actions versus protocol in the manual (discussion with Bob Proulx).
    • improve discussion of environment variables in the manual, pointing out where some features (such as termcap and the System5 COLUMNS and LINES variables) are used rarely, mainly to support legacy applications.
    • add examples of translations resource for select/paste, and for font-size changes to the manual.
    • minor reordering of some entries in ctlseqs.ms for consistency (report by Arran Ubels).
    • add -s option to 256colors2.pl and 88colors2.pl, to demonstrate modifying the “system” colors 0–15.
    • omit XFT_SPACING property from call to XftPatternBuild, to work around a bug in fontconfig for handling Google Go fonts, whose names sort in an order not expected by fontconfig, causing the request for a monospaced font to return italics, e.g.,
      $ fc-match 'Go Mono:spacing=monospace'
      Go-Mono-Italic.ttf: "Go Mono" "Italic"
      (report by Giacomo Boffi on Stackoverflow).
      
      
    • modify minstall.in to improve a workaround added to the manual page in patch #182 to avoid having the C preprocessor used in the imake configuration strip out the comments in the character classes section (reports by Ted Unangst, Anthony J Bentley).

    Patch #327 - 2016/10/07

    • add a check in the function which handles end-of-line wrapping to ensure that C1 controls are allocated one column when allowC1Printable is set (Debian #738794).
    • use consistent error-checking after strtol calls, fixes a case where a query with OSC 6 did not ensure there was a valid color number (report by Alex Smith).
    • add -baudrate option, for testing ncurses.
    • always generate the CASE_xxx symbols in VTparse.h and Tekparse.h, as part of a change to improve debug-logging. This makes the build always depend upon awk.
    • modify allowC1Printable to disallow codes 160-254 as being equivalent to codes 32-126 when parsing escape sequences (Debian #839220).
    • amend fix from patch #326 for TrueType fonts to exclude the hidden character used for double-width cells (report by Grady Martin).
    • fix a typo in ctlseqs.ms

    Patch #326 - 2016/09/25

    • updated appdata file (report by Richard Hughes).
    • improve discussion of the different terminal emulations provided by xterm in the manual page.
    • add examples of setting the icon title with/without the window title in the manual (Debian #833984).
    • correct a limit-check when using a numeric value for extended Booleans e.g., *fullscreen:3 rather than a name such as *fullscreen:never.
    • add action allow-bold-fonts
    • improved formatting fixes for manual page, using script to find mismatches in spelling of resources, actions and menu entries.
    • improve documentation of logging resources.
    • fix a special case of flickering cursor by adding GraphicsExpose to the list of event types that should not trigger making the mouse cursor visible (patch by Joe Peterson).
    • correct initialization of line-drawing in VT52-mode, overlooked in changes for patch #297 (report/patch by Ben Wiley Sittler).
    • minor clarification of form-feed versus line-feed in ctlseqs.ms (suggested by David Kemper).
    • amend fix for Debian #738794 to restore a check for missing characters which are not combining characters. Also fill in a corresponding special case for TrueType fonts (Debian #827905).

    Patch #325 - 2016/06/05

    • improve manual page discussion of function keys (discussion with Ross Combs).
    • further improve fix for Debian #545220 in patch #248, to avoid conflict with combining characters (Debian #738794).
    • improve -hold option to avoid 100% CPU usage with NetBSD after closing the shell, which makes subsequent checks for X input events fail (prompted by patch by Pierre Pronchery).
    • review #ifdef statements, listed those which do not have a configure option in xtermcfg.hin.
    • fixed one case where the menu sensistivity for Print-All Immediately and Print-All on Error was not properly ifdef'd.
    • modify terminfo entries for 16-, 88- and 256-color to reset palette with rs1 capability.
    • accept legacy value of -kt as synonym for the oldXtermFKeys resource, and extend the full-reset logic to use the keyboard type set via -kt.
    • modify ioctl calls for I_PUSH to first check if the module has been added, using I_FIND. This is needed for newer Solaris libraries with c11 support (adapted from patch by Alan Coopersmith).
    • add check in getXtermCombining to ensure that combining characters were allocated (report by Tor Andersson).
    • add configure option --without-xinerama to allow suppressing the extension (Gentoo #580936).
    • update keysym2ucs.c based on Unicode 9.0
    • fixed most cppcheck --enable=all warnings, including for style (prompted by report by David Binderman). There was one bug-fix:
      • RGB least-squares computation in allocateClosestRGB used only one ordinate
    • add cppcheck to lint-like programs in configure script and makefile.
    • fix some const correctness issues and point out an array lifetime issue (Ross Combs).
    • updates for SIXEL and ReGIS (Ross Combs):
      • Sixel drawing should still happen after an error if some commands have been processed
      • Tiny steps toward reporting ReGIS input

    Patch #324 - 2016/03/10

    • updated configure macro CF_LD_RPATH_OPT from ncurses changes.
    • provide alternate fix for Juha Nurmela's report by turning on POSIX signals if _POSIX_C_SOURCE is at least one. This is done to improve the behavior if a direct child process receives a STOP signal.
    • revert change to CF_POSIX_C_SOURCE from patch #323 (reports by Ashish Shukla, Christian Weisgerber).

    Patch #323 - 2016/03/07

    • updated appdata and desktop files to add keywords (report by Richard Hughes).
    • modify configure macro CF_POSIX_C_SOURCE to accommodate some systems, e.g., FreeBSD, which have separated their implementation specific preprocessor symbols from the POSIX ones, requiring both to be defined (report by Juha Nurmela).
    • change the directory to the current working dir of the child process in exec-formatted and exec-selectable actions (patch by Alexander Pohoyda).
    • correct typo in xterm.man (patch by Larry Hynes).
    • correct typo in ctlseqs.ms (report by Shriramana Sharma).
    • add feature to support XHTML and SVG screen dumps (patch by Jens Schweikhardt).
    • correct response to DECRQSS when terminal id is less than 400 (patch by Iwamoto Kouichi).

    Patch #322 - 2016/01/02

    • fix regression due to incorrect fix for compiler warning when allocating storage for /etc/shells (reports by Ashish Shukla, Debian #809646).

    Patch #321 - 2015/12/31

    • add resource keepClipboard, escape sequence and action keep-clipboard.
    • add optional feature to capture text copied to clipboard at the time of copying rather than at the time the clipboard contents are requested for pasting (patch by Milan Mehner).
    • improve a special case where the -e option was used to pass a single-quoted command via luit, by wrapping it in a “sh -c” (report by Keith Hedger).
    • minor fix for type-cleanliness when allocating storage for /etc/shells (Tobias Stoeckmann).
    • fix a typo in manual page (Dan Church).
    • fix minor file-descriptor leak; after calling openpty, the slave's file descriptor is not needed (report by Juha Nurmela).
    • editorial change to ctlseqs.ms (report by David Gomboc).
    • minor updates for autoconf macros.
    • update config.guess, config.sub

    Patch #320 - 2015/08/28

    • correct documentation for %t format (report by Martin Tournoij).
    • add %R for consistency to exec-formatted() and insert-formatted() actions.
    • add %r format to exec-formatted() and insert-formatted() actions (patch by Martin Tournoij).
    • Amend fix for Debian #794201 (report forwarded from Christian Jachmann by Emanuel Haupt, Debian #797008).

    Patch #319 - 2015/08/19

    • add a section to ctlseqs.ms discussing control sequences and ECMA-48, to explain why C1 controls do not occur in the decoded characters from UTF-8 byte streams (prompted by discussion with Poul-Henning Kamp).
    • modify check for cursor-theme from patch #301 to also check if the resource Xcursor.theme is set to a nonempty value before fallback to xterm's own dummy theme (request by Robert Kloefkorn).
    • explain in ctlseqs.ms that some keys which normally send SS3-prefixes are changed to CSI-prefixes if key-modifiers are passed as parameters (report by George Nachman).
    • correct double-free of font information when multiple problems are found, particularly for the wide fonts loaded via the -wc option (report/testcase by Nelson Beebe).
    • make configure option --enable-builtin-xpms actually work (report by William Bulley).
    • correct combination of -ls and -e options for utempter configuration (Debian #794201).
    • NetBSD build-fix for OPT_RENDERFONT versus OPT_SHIFT_FONTS (patch by Matthew Green, forwarded by Thomas Klausner).
    • fix a few minor bugs found with Coverity.
    • update pixelvector handling (Ross Combs):
      • split pixel-based and coord-based functions with common parts factored out to a "raw" function
      • add a "step" variant which loads a single PV digit
    • make the graphic dirty upon resize or clear, fixing some missing refreshes (patch by Ross Combs)
    • fixes scrolling to use user coordinates and move in the correct direction (patch by Ross Combs)
    • several fixes/improvements for ReGIS whitespace and page-handling (patch by Ross Combs).

    Patch #318 - 2015/04/12

    • rename new(er) configure option --enable-initial-erase to --enable-pty-erase, since that conflicted with an existing option (report by Jens Schweikhardt).
    • fix cut/paste error in --with-builtin-xpms configure option (reports by Jens Schweikhardt, Ross Combs).
    • fix minor formatting issue in xterm manual (report by Jens Schweikhardt).
    • eliminate unnecessary "#(vi" markers in autoconf macros by using "(" to begin case-statement cases (suggested by Jens Schweikhardt).
    • minor fixes to improve const usage (Ross Combs).

    Patch #317 - 2015/03/27

    • adapt example for exec-formatted from Lukáš Zapletal's webpage to manual (Debian #780008).
    • add a short usage section to the xterm manual, including notes on setting the window title (Debian #742477).
    • revise a change made to ICH in patch #314 to address limit-checks (reports/testcases by Zoltán Kéri and Joe Peterson, also reported by Christian Weisgerber).

    Patch #316 - 2015/03/07

    • revert change to make DCH honor top/bottom scrolling margins. For the record, both the VT420 and VT520 reference manuals incorrectly state that "DCH has no effect outside the scrolling margins."
    • fix regression in DCH introduced in adjustment for limit-check in patch #315 (report/testcase by Zoltán Kéri, also reported by Christian Weisgerber).
    • correct default value for configure option --enable-initial-erase; it should be "False", but in patch #315 it was "Maybe", which differed from default set in patch #192.

    Patch #315 - 2015/03/02

    • change default for --enable-narrowproto for Cygwin to "no" to better match contemporary configurations (report by Jens Schweikhardt, prompted by discussion).
    • provide OSC 106 as an alternative to OSC 6, avoiding conflict with one of Terminal.app's undocumented escape sequences (report by Egmont Koblinger).
    • fix an off-by-one in comparison when autowrap and left/right margins are combined (report by George Nachman).
    • modify DECBI and DECFI to work outside the left/right margins, since the vague VT520 reference manual could support that interpretation (suggested by George Nachman).
    • correct response for DECSCUSR in DECRQSS (report/analysis by George Nachman).
    • add DECSLRM to list for DECRQSS in ctlseqs.ms (report by George Nachman).
    • improve limit-checks versus assert's in the debugging version (reports by George Nachman).
    • correct a problem with multiple writes to the right-margin when autowrap is turned off (report by George Nachman, also reported in Gnome #744819 by Ulf Magnusson).
    • modify DCH to honor top/bottom and left/right margins (report by George Nachman).
    • correct off-by-one in comparison so that DL honors left/right margins (report by George Nachman).
    • correct logic of DECSCL, which always set 8-bit controls as a side-effect (report by George Nachman).
    • correct loop limit for DECSED 1, when DECSCA is enabled (report by George Nachman).
    • fix a entry in csi_table for “$”, needed for CSI [ $ z (report by George Nachman).
    • remove restriction from patch #279 changes on DECIC and DECDC to left-right mode (report by George Nachman).
    • correct PID value returned in response to DECRQCRA (report/analysis by George Nachman).
    • fix an ifdef'ing problem, where --disable-dec-locator would turn off logic needed for DECIC and DECDC (report by George Nachman).
    • correct order of parameters in report for CSI 1 9 t, which gives the screensize in characters (report by George Nachman).
    • add null pointer checks for a case in DECCRA where part of the target rectangle lies outside the screen limits (report by George Nachman).
    • remove extra "6" for selective erase from DA1 response (report by George Nachman).
    • support Xinerama screen specification in geometry parsing (patch by Nicolas George).
    • add configure option --enable-initial-erase to set ptyInitialErase consistently with manpage, as well as adding a table in manpage to clarify the relationship between the resources related to the backarrow key (Debian #775952).
    • add configure --enable-builtin-xpms to simplify compiling-in the icons introduced in patch #284 (prompted by discussion with William Bulley).
    • fix/improve autoconf macros:
      • CF_WITH_APP_DEFAULTS, add paths for OSX
      • CF_WITH_MAN2HTML, configure option "--with-man2html" provides "man2html" as alternative to groff's man/html conversion
    • fix some minor issues in manpage (Jens Schweikhardt).

    Patch #314 - 2014/12/28

    • fix a minor bug in the termcap-specific version of resize when the lines or columns values are at the very end of an incomplete termcap string (prompted by coverity report).
    • improve paste64 feature (report by Olaf Rogalsky)
      • fix “p;” command in paste64.pl example.
      • modify _OwnSelection to allow the paste64 control to cause primary/clipboard selections to be disowned and cleared.
      • omit an extra "=" used in padding, to make the base64 response a multiple of four characters.
      • modify _ConvertSelectionHelper to not stop converting on embedded nulls in the primary or clipboard selection. That makes the behavior consistent with cut-buffers. Nulls are not passed on to the application because they are used for separators in the X library calls that convert XTextProperty values.
    • add configure option --with-man2html to allow an alternative to groff's man/html conversion.
    • review and modify resource-settings which can be set via control sequences, etc:
      • add OSC 6, to enable/disable colors set via OSC 5, without changing the color assignments (prompted by patch by Ingo Brückl).
      • add command-line option -itc for italics.
      • add colorIT and colorITMode for italics, like colorBD, etc.
      • guard allowPasteControls against modification by editres.
    • change passedPty from fixed-length to allocated to ensure that it is long enough to hold the -S option value (report by Ben Longbons).
    • improve ReGIS graphics initialization (Ross Combs):
      • add a new string resource to set the default ReGIS font.
      • fix a caching problem where the font name wasn't taken into consideration when looking up cached metrics.
      • enables use of fractional values in coordinates (which in turn allows setting the coordinates to something like [0,1][1,0])
      • doubles the minimum ReGIS graphic to 200x200
      • set the default ReGIS image size to "auto"
      • fix some swapped width/height parameters in TRACE messages
      • add support for scaling and mirrored coordinate systems to the screen address command
      • sets a minimum ReGIS graphics size of 100x100 -- smaller address ranges will be scaled up
      • reset the image if either the width or height is zero (which should happen together or not at all, but switching the logic gets rid of some parentheses)
      • adds support for alternate screen coordinates (just offsets, not inverted coordinates or scaling)
      • keeps the graphics state across ReGIS calls unless P1 or P3 entry codes are used
      • changes loops to continue after parsing whitespace to allow trailing whitespace
      • fixes some incorrect character casts

    Patch #313 - 2014/11/28

    • add regisScreenSize resource setting to allow custom screensizes for ReGIS graphics (prompted by discussion with Scott Froebe).
    • fix some minor issues in manpage (Jens Schweikhardt).
    • improve ReGIS font-handling (Ross Combs):
      • remove "random junk" generation for unknown characters
      • add xterm extension to load user glyphs for alphabet 0
      • add xterm extension to specify loading an alphabet from a font by name
      • fix bug with use of empty alphabet slots which caused slot 0 to be clobbered
      • update/clarify ReGIS-related comments
      • add DECprint extension for printing/clearing the screen (only clearing is performed)
    • improve ReGIS colorspec conversion (Ross Combs):
      • avoid some floating point math for colorspace conversion
      • move two copies of colorspec parsing to a single function
      • change colorspec parsing to handle components being out of order or with spaces and commas between them
      • add support for an extension where RGB components can be given instead of HLS
    • improve use of const, e.g., for the LineData pointers (patch by Ross Combs).
    • clip of graphics that overlap the scrollback buffer and alt screen (patch by Ross Combs).
    • amend change to focus-change events in patch #287 to limit it to suppressing the reset of the urgency-hint, because some useful FocusOut events were lost (report by Joe Peterson).
    • modify dpkg build-script to configure xterm-dev as an x-terminal-emulator alternative.
    • extend the --with-xterm-symlink feature to make symbolic links for the other programs and scripts.
    • minor fix to vttests/resize.pl to avoid undefined variable when receiving broken/missing response, e.g., from mrxvt.
    • change the way that ReGIS graphics are refreshed (patch by Ross Combs):
      • it pre-composes any overlapping graphics to avoid unnecessary and flickering draws
      • it adds a three-dimensional lookup table for RGB -> pixel values and uses this across all graphics
      • it draws in line segments when there is a run of the same color
      • in cases where there are no transparent parts, it uses an XImage to draw
      • it hooks into the double-buffering support if it is enabled (though this doesn't seem to get rid of all flicker).
      This has the effect of reducing flicker and speeding up redraws.

    Patch #312 - 2014/09/28

    • undo change to do_select_regex() in patch #311 (reports by H Merijn Brand, Sven-Haegar Koch, Debian #762978).

    Patch #311 - 2014/09/18

    • mention xclip in manpage as an alternative workaround for copying clipboard data, noting that selectToClipboard (see patch #209) is the recommended approach (Debian #639094).
    • correct comparison in do_select_regex() of working position against starting column.
    • correct initialization for regular-expression feature of exec-selectable and insert-selectable actions (Debian #758633).
    • modify logic for exec-formatted and insert-formatted actions to ensure that the formatting occurs just after the selection is received (Debian #758633).
    • account for state of reverse-video in special case of cursor coloring (Debian #759734).
    • fix a sign-extension problem in ReGIS support, as well as correcting a case where ignored-characters were not really ignored (patch by Ross Combs).
    • Enable the "Escape Sequence" menu entry when an OSC 50 is received. Also disable it if the escape sequence specifies no font (Debian #760208).
    • improve fix for the fontsel menu entry from patch #304: because the recovery used the "current font", it would fail if one first selected a valid font, then an invalid font (Debian #760207).
    • correct an off-by-one in limit-check for ScrnLimitChar function (report by Egmont Koblinger).

    Patch #310 - 2014/07/25

    • update package/freebsd files based on xterm #309 port.
    • adapt changes from Minux3.2 which ported xterm #197, to allow building on that platform both using imake as well as using the configure script.
    • update precompose.c based on Unicode 7.0
    • build-fix for --with-Xaw3dxft option (report by Emanuel Haupt).

    Patch #309 - 2014/07/13

    • modify configure script to work around debris left by XQuartz upgrades.
    • modify test-package scripts to enable ReGIS graphics.
    • improvements/additions to ReGIS graphics, e.g., drawing text (Ross Combs).
    • add --with-Xaw3dxft, to link with Xaw 3d xft library (Stephen P Wall).
    • amend reset for cursor-shape to take into account cursorUnderline resource (report by Christian Weisgerber).
    • update config.guess, config.sub

    Patch #308 - 2014/06/19

    • corrected font used for clipping double-width bitmap fonts from patch #307 changes to work around mis-scaled fonts (Debian #752947).
    • improve wording of a warning message.

    Patch #307 - 2014/06/17

    • fill background for top/bottom parts of double-width/double-height characters, to cover occasional gaps due to bitmap font-scaling (report by Egmont Koblinger).
    • amend resets for keyboard-type, pointer-mode and title-modes from xterm #305 changes to account for resource settings (Debian #751351).
    • modify printAttributes feature to include new SGR codes.
    • modify cursor show/hide logic to work with italic fonts.
    • do clipping and filling for a case with bitmap-fonts and italics when the font server returns only a "close" match (report/testcase by Egmont Koblinger).
    • adjust loop comparison for underlining to display underlines on 5x8 font as in patch #304 (Debian #750733).
    • amend fix for Freedesktop #15979 (Debian #750733).
    • amend xterm.appdata.xml, making it validate with current schema.

    Patch #306 - 2014/06/03

    • fixes for display-errors in new SGR codes (report by Egmont Koblinger).

    Patch #305 - 2014/06/02

    • add xterm.appdata.xml (request by Richard Hughes). By the way, none of the released validators yet handle <licence> tags (or <metadata_license>, etc).
    • fix memory leaks in bitmap font-name caching.
    • other changes to hard-reset behavior:
      • reset keyboard-type on hard-reset.
      • reset pointer-mode (pointerMode) on hard-reset
      • reset title-modes (titleModes) on hard-reset
      • reset cursor-shape on hard or soft-reset
      • reset LEDs on hard-reset.
      • reset DECSACE on hard-reset.
    • reset bracketed-paste mode on hard-reset (suggested by Egmont Koblinger).
    • modify UTF-8 decoder to account for allowC1Printable resource.
    • revise getXftColor to ensure that its sequence number will not overflow in long-running sessions.
    • minor fix to selection to prevent hidden character from being returned in selection data (report by Egmont Koblinger).
    • add -sh to help-message.
    • amend check for incomplete fonts to always decide that a character is missing if the font lacks per-character metrics (prompted by Freedesktop #15979).
    • minor reorganization to implement “filler” SGR features. There are no established applications which rely upon these; some people find them amusing.
      • separate bits used to manage drawing state from attribute-bits.
      • implement SGR codes 2, 3, 9, 21 and their corresponding resets.
      • add configure option --disable-wide-attrs to disable the feature.
    • additional changes for ReGIS support (Ross Combs):
      • fix some arc drawing bugs and add support for pattern shading.

    Patch #304 - 2014/05/03

    • add debugging check for parsing table entries, fixed a few inconsistencies.
    • handle utmp/utmpx strings consistently with new function that null-pads unused locations.
    • build-fix for imake configuration with FreeBSD 9 and later, to account for replacing utmp with utmpx.
    • improve handling of the fontsel (font-selection) menu item:
      • initialize the menu entry differently if the toolbar configuration is used, i.e., enabling it without attempting to use the current selection as a font name. Because of the way in which the toolbar is setup, this attempt usually failed, and would result in a warning.
      • if the menu action fails, e.g., no font can be loaded for the given selected name, then recover by resuming with the current font. Before, the recovery went to the default font. That was done to work around missing bitmap font in patch #276.
    • document OSC 119 in the control sequences listing (report by Egmont Koblinger).
    • modify special handling of XF86Paste or SunPaste keysyms (see patch #227) to use the standard shift/lock modifiers in case those are, for example, used in level 3 in an XKB file (patch by Matthieu Herrb).
    • configure macro updates:
      • drop the -no-gcc option from CF_INTEL_COMPILER
      • modify CF_XOPEN_SOURCE to suppress the check for defining _XOPEN_SOURCE on Solaris
    • reduce bss storage used for ReGIS/Sixel modules, as well as cleanup storage usage in other modules.
    • initial changes for ReGIS support (Ross Combs):
      • document control-sequences
      • separate ifdef's for sixel and color-register features
      • add configuration for VT382

    Patch #303 - 2014/03/06

    • improve check for /etc/shells to allow its entries to be symbolic links.
    • fix a regression in patch #302 fixes relating to interaction of SHELL and XTERM_SHELL variables (Debian #740919).
    • improve manpage discussion of use of /etc/shells for validating the SHELL environment variable.
    • further improve the approximation for color map by ignoring bits which would not be applied by the rgb masks for the current visual (report by Joe Peterson).
    • add -report-colors to usage-message (report by Joe Peterson).

    Patch #302 - 2014/03/02

    • amend approximation for color map introduced in patch #277 to make that apply only to TrueColor (adapted from patch by Joe Peterson).
    • add -report-colors option, to show colors as they are allocated.
    • fix some gcc -Wcast-qual warnings.
    • correct app-defaults location for CentOS-4 in xterm.spec
    • improve check in minstall.sh for X manpage's section number; add sample dependencies for the relevant documentation package to packaging test-scripts (prompted by Novell #779474).
    • modify sample build-scripts for dpkg and rpm to ensure that vttests scripts are uncompressed and executable.
    • modify Perl scripts in vttests to use env to find Perl rather than relying on /usr/bin/perl This makes the sample scripts usable with NetBSD and other systems using pkgsrc.
    • amend check from patch #301 for valid shell to permit existing SHELL value to specify the shell; clarify the behavior in the manpage (report by Emmanuel Thomé).
    • amend change to wide-character processing from patch #257 to allow switching to/from UTF-8 encoding if the utf8 resource was not set to “always” (report by Honza Maly).
    • fix incorrect free from patch #301 changes, if explicit program without -e option is a valid shell (patch by Romain Francoise).

    Patch #301 - 2014/01/19

    • OSC 104 and 105 did not accept parameter to reset a specific color (patch by Egmont Koblinger).
    • add configure check for initgroups, and use that function to complement its use of setgid (prompted by patch by Miroslav Lichvar).
    • improve manpage description of scrollbar translations versus the vt100 translations (Debian #723573).
    • add a few paragraphs to manpage explaining the implications of xterm's reliance on X Toolkit for command-line parsing.
    • modify cursor-theme logic to check if the environment variable XCURSOR_THEME is set to a nonempty value before constructing a dummy them (prompted by similar check added in OpenBSD CVS).
    • add check for a case where TrueType bold font is missing a glyph where the non-bold font has it. Temporarily switch to the non-bold font to draw the glyph (report by David Demelier).
    • minor documentation fixes for ctlseqs.ms
    • only set SHELL environment variable to programs found in /etc/shells (prompted by patch/report by Al Poole).
    • build-fix, when --disable-wide-chars --disable-boxchar is used (prompted by patch by Andrey Panov).

    Patch #300 - 2013/12/03

    • amend workaround for Xcursor library from patch #298; the suggested solution for Debian #466704 fell afoul of a bug in Xcursor which treated an empty value for Inherits= as a valid theme—and resulted in a stack overflow due to unbounded recursion. Certain environments such as XFCE4 exposed the bug. A related report in Debian #531679 was closed without following the recommendation to limit stack recursion in this library (reported by Sergey V Dyatko, Debian #731269).

    Patch #299 - 2013/12/01

    • fix regression in line-drawing from patch #297 changes for NRCS exposed by change to assumeAllChars resource in patch #298 (report by Markus Waldeck).

    Patch #298 - 2013/11/27

    • quiet a warning about ambiguity when -h command-line option is parsed, since -help is used rather than the options mentioned in the message. This warning was caused by fixes in patch #272.
    • remove an extra check for keypad-mode which interfered with the patch #280 modifyKeyboard feature for the numeric keypad (report by David Conners).
    • change default for assumeAllChars resource (Debian #725682). There are unresolved issues with Terminus fonts, e.g., Debian #722017.
    • add -report-fonts command-line option and reportFonts resource to optionally report the fonts which are loaded, and their metrics such as the number of missing glyphs.
    • work around Xcursor library to make pointerColor resource work as documented (Debian #466704, analysis by Vincent Lefèvre).
    • amend change from patch #297 for ASCII-equivalents to ensure that missing characters which happen to be double-width are padded to the expected number of columns. Also, correct the choice between normal/wide Xft fonts used when checking for missing characters (reported by WU Yue, Debian #728949, Gentoo #491334).
    • modify sixel-graphics drawing to account for scrollbar width (report by Mario Edelmann).
    • fix remaining issue with DECNRCM; the British character set was confused with ISO Latin-1 (report by Hayaki Saito).
    • build-fix for --disable-boxchars configure option.
    • updated configure macros, from ongoing work on lynx and ncurses.
    • update config.guess, config.sub

    Patch #297 - 2013/09/10

    • modify check for missing cells in bitmap font to work around terminus 10646 encoding, which is mostly missing, add assumeAllChars resource to provide the older behavior.
    • modify macros used to check for missing cells in bitmap fonts to pick up a long-overlooked improvement made to xfd in XFree86.
    • improve workaround for groff versus ASCII-equivalents; patch #185 had overlooked Xft configuration (reported by anonymous user on Arch Linux forum).
    • review/extend DECNRCM support (prompted by report by Hayaki Saito asking about the two "A" codes).
      • make pasting of DECNRCM data work by translating the pasted data into the selected encoding.
      • limit mode changes to VT220 and up.
      • ignore SCS for National Replacement Characters if DECNRCM is not set.
      • add tables and logic to decode SCS controls ending with "%" and one additional character. This expects the parsing of SCS to VT320.
      • also added parsing for SCS of DEC Supplemental and DEC Technical, which are for VT2xx and VT3xx respectively.
      • implement VT220 Multinational character set "GR" aka "DEC Supplemental Graphic".
      • DEC Technical character set based on vt100.net description.
      • implement Portuguese NRC.
      • provide for temporarily switching to/from NRC mode from UTF-8 mode when DECNRCM is set or reset.
    • minor fix to assert's found while testing examples from ttdoda's slrm-test1.txt.
    • modify DECLRMM to not update the cursor position (report by Iwamoto Kouichi forwarded by Hayaki Saito).
    • modify cursor-position report to take origin-mode into account (report by Hayaki Saito, see also iTerm2 pull request 129).
    • correct off-by-one comparison in when handling carriage-return at left margin (patch by Iwamoto Kouichi, forwarded by Hayaki Saito).
    • improve handling of faceName resource when a "size=" property is embedded in it, by using that size to replace the default faceSize resource. This lets xterm honor the other faceSize resources (report by Jens Schweikhardt).
    • improve OSC 52 selection-data by setting its timestamp to correspond to the most-recent event received by xterm, to ensure that calls to XtOwnSelect succeed even if the selection is manipulated solely through the keyboard (prompted by patch by Richard Tollerton).
    • change configure-script defaults for "luit" and "wide-chars" options to match the values used in the imake configuration, to lessen user surprise if they are accustomed to building xterm using imake(report by Andries E Brouwer).
    • improve the imake-related configuration's check if xterm is started in a locale that uses UTF-8 encoding. Before, this checked the locale settings only for "UTF-8", now it checks ignoring case for "UTF-8" and "UTF-8" (report by Andries E Brouwer).

    Patch #296 - 2013/07/10

    • improve experimental sixel feature (Ross Combs).
    • modify delimiter in configure macro used to add a library after a given library to avoid confusion with -Wl pass-through options to linker (NetBSD #48031).
    • fix quoting in expression used to trim extra libraries from patch #295 changes (report by Thomas Klausner).

    Patch #295 - 2013/07/06

    • adjust order of libraries to work around incomplete symbol resolution when using --as-needed option (ArchLinux #36047).
    • minor fix for plink.sh, for IRIX64.

    Patch #294 - 2013/07/05

    • add note in ctlseqs.ms for CPR response pointing out a potential point of confusion with the string sent by a modified F1 key (suggested by Bram Moolenaar).
    • improve plink.sh by checking if the linker supports the --as-needed option (suggested by David Philippi).
    • improve clearing for private mode 1049 when switching to the alternate screen (Debian #711758).
    • amend fix from patch #292 by removing now-unneeded chunk which introduced problem in selection (Debian #714527).
    • add definition to optionally override compiled-in class for xterm from makefile, needed for test-packages.
    • add configure option --enable-sixel-graphics
    • add experimental support for sixel graphics (Ross Combs).

    Patch #293 - 2013/05/27

    • modify sample xterm.spec to use newer icon
    • add configure option --with-icon-symlink to work around systems which map icon requests for to a single "xterm" icon, but neglect to install the icon needed for window decorations (report by H Merijn Brand).
    • improve parameterizing of sample xterm.spec
    • amend fix for printer from patch #280, removing a reset of the signal handler for SIGCHLD (report by Joe Julian).
    • set environment variable XTERM_FILTER if a locale-filter is used.
    • enable DEBUG logic when --enable-trace configure option is given.
    • improve description of initialFont, set-vt-font and set-tex-text in manpage (Debian #707899).
    • fix regression from patch #292; selecting a word that ended at the right margin without wrapping would not select the last cell (report by Christian Weisgerber).

    Patch #292 - 2013/04/25

    • add limit-check when double-click selects a word; if the saved-lines were scrolled back and the word selected wrapped at the screen's lower right corner, an assertion was triggered (patch by Taketo Kabe).
    • correct limit-check in unsaveEditBufLines, fixing a case where enlarging the terminal size could show a blank line where there actually is available text (patch by Bertram Felgenhauer).
    • add PasteControls feature to allowWindowOps which by default disallows pasting control characters other than formatting such as carriage return (discussion with Hayaki Saito).
    • fix typo in ctlseqs.ms for DECRQM response (patch by Emanuele Giaquinta).
    • update default shown in configure --help message for --with-terminal-id option (patch by Andres Perera).
    • rename script/preprocessor variables used for substituting the backarrowKey default value for consistency (patch by Andres Perera).
    • set umask to 077 before creating debugging-trace files.
    • add configure option --disable-openpty to control whether openpty() may be used in preference to posix_openpt().
    • improve workaround from patch #279 for BSD systems which do not complete initialization until both sides of the pseudoterminal are opened, by preferring openpty() function over posix_openpt() when available (report by Christian Weisgerber).

    Patch #291 - 2013/02/26

    • add validity check for xterm widget parameter to AlternateScroll function, needed to handle wheel mouse events in the scrollbar area since patch #282 changes which introduced alternateScroll feature (Redhat #874327).

    Patch #290 - 2013/02/12

    • revert of patch #282 change was incomplete (report by Jim Reisert).
    • fix typo in manpage (report by Vincent Lefèvre).

    Patch #289 - 2013/02/08

    • revert the patch #282 change which restored "lost" text after shrinking/growing the screen size. If the screen was updated between the two resizing operations, unexpected text might be shown at the end (report/testcase by Joe Peterson).
    • reverse the arrow-keys sent for alternateScroll to match the usage in browsers (suggested by Dieter Roelants).
    • modify mouse reports to consistently indicate motion events whether or not a button is pressed. Old behavior (since patch #127 modified encoding for wheel mouse) showed only that the button was released if no button had been pressed (report by Andy Koppe).
    • correct and improve behavior for SGR 1006 mouse protocol on button release in any-event mode. Initial implementation in patch #277 left internal state showing the last button pressed when reporting motion events. It now keeps track of all buttons which have been pressed and released, showing the lowest remaining button by number in the response (reports by Hayaki Saito, Andy Koppe).
    • fix inconsistency between TermColors and OscTextColors enums which interchanged values for tektronix cursor color and highlight foreground in control sequences in patch #225 (report/patch by Peder Stray).
    • fix inconsistent use of noreturn-attribute in Exit function which interfered with clang --analyze.
    • remove incorrect free used in computation of XTERM_SHELL variable, from Coverity fixes in patch #288 (FreeBSD #175782).
    • add --with-valgrind option to configure script for consistency with my other programs.
    • update table of ambiguous width characters in wcwidth.c based on Unicode 6.2.0
    • update table of combining characters in wcwidth.c based on Unicode 6.2.0
    • update precompose.c based on Unicode 6.2.0

    Patch #288 - 2013/01/09

    • fix a special case in ShowCursor where the foreground and background colors of the current position are the same. In that case, choose the further of the window's foreground and background colors for the cursor color.
    • modify alternateScroll feature added in patch #282 to use either CSI or SS3 according to the cursor keys application mode setting, to simplify using it in vi, etc. (suggested by Dietar Roelants).
    • revise manpage for resize to clarify the changes which resize may make to the terminal settings as well as to the terminal itself.
    • remove code such as struct ttysize, used for SunOS 3 and 4.
    • modify configure script and makefile to check for groff and suppress groff-specific rules if groff is not found.
    • modify ctlseqs.ms and makefile to work around bugs in grohtml which cause ".png" files to be truncated when producing html documentation.
    • modify suffix rules for "make docs" to make the names of the generated ".png" files predictable, helping to work around longstanding problems with this feature of groff—none of its releases work for all of xterm's tables..
    • correct typo in ctlseqs.ms for DECIC and DECDC; the character preceding the final "~" is an ASCII single-quote "'" rather than a space (report by Paul LeoNerd Evans).
    • update CF_GCC_VERSION macro, handling both Debian and Darwin.
    • improve configure script checks for the --with-desktop-category option. After patch #280 changes, if no value was given for this option, and no existing desktop files found for comparison, the incorrect "auto" value was passed into the generated desktop file (report by Julien Cristau).
    • modify sample build-scripts to disable check for imake due to code-rot in Xorg.
    • add -v command-line option to resize, reporting the same version string as xterm and the two shell-wrappers.
    • make name-transformation apply to other occurrences of resize, other manpages.
    • special-case the name-transformation in xterm's manpage in the NAME section so that the result works with makewhatis (report by Julien Cristau).
    • modify install-rules for manpages to put each program's respective transformed name into the header rather than xterm's.
    • remove deprecated files: proto.h, os2main.c
    • minor fixes based on Coverity scan, including:
      • correct caching of Atom value for the font menu's "Selection" entry.
      • ensure that utmp/utmpx calls do not depend upon trailing nulls in the ut_id and ut_line values.

    Patch #287 - 2012/11/25

    • fix a case where in_put() loop could continue when it has found an X event rather than the pty, causing the pty-read to be delayed (patch by Balazs Kezes).
    • add option to pointerMode resource and corresponding control sequences to allow text-cursor to remain hidden if the pointer leaves/enters the window via accelerator keys. Ordinary motion within the window restores the pointer (prompted by patch by Balazs Kezes).
    • remove special case of modifiers for the Mode_switch and XK_ISO_Level3_Shift from patch #223. Verified that the conflict which this was intended to resolve does not happen for normal compose- or modeswitch-handling (prompted by patch by Balazs Kezes, Debian #638694).
    • modify the handling of focus-change events to ignore those whose detail is NotifyPointer, since those are sent in addition to focus-change events directed to the old/new windows having focus. In particular, this prevents the urgency-hint from being reset inadvertently (prompted by patch by Balazs Kezes).
    • modify description of iconName in manpage to make it clearer that this resource does not specify the filename of an icon (discussion with Ian Collier).
    • modify iconHint resource to allow suppressing the built-in icon by setting this to "none" (discussion with Ian Collier).
    • make -iconic option work with the toolbar configuration.
    • correct initialization of window manager hints used to set the icon-pixmap. That detail from patch #282 overwrote state used to control the -iconic command-line option (report by Ian Collier).
    • fix paste64 feature for the case where the selection comes from the current terminal. The selection callback can happen after the reply is partly built, making it necessary to flush the reply-buffer to keep things in the proper order (report by Ailin Nemui).
    • reject command-line options which are longer than the options in xterm's table, to avoid mismatches (Redhat #875305).
    • correct attribution for patch #282 changes.

    Patch #286 - 2012/10/29

    • fix minstall.in to work with "make docs" rule, so that patch number appears in the corresponding generated documentation.
    • modify minstall.in to keep the name shown in the heading consistent with any renaming, e.g., for test-builds.
    • check for misconfigured printerCommand resource on the first use, warn and disable it if it does not specify an executable command (Debian #691642).
    • improve check for window-manager name needed to establish usable default for activeIcon resource. This works around a scenario where gdm does incomplete cleanup, leaving window properties that refer to windows which no longer exist (Redhat #869959).

    Patch #285 - 2012/10/23

    • add/adapt FreeBSD ports files for test-building.
    • modify minstall.sh to use the patch-number and date in the manpage footer.
    • add check for failure to allocate the fg/bg colors at startup, e.g., misconfiguration. Work around by setting both to the default colors (suggested by Scott Bertilson).
    • amend change for patch #280 which added modifyKeyboard, to make modifyOtherKeys work (report by Ailin Nemui).
    • add query-colors.pl example for OSC 4.
    • correct mis-applied fix for minstall.sh (report by Miroslav Lichvar).

    Patch #284 - 2012/10/14

    • amend configurability changes for icons from patch #283, moving the new functionality to the iconHint resource to avoid conflict with existing uses of the iconName resource in the Shell widget (report by Emanuel Haupt).
    • fix documentation errata reported by Miroslav Lichvar:
      • correct manpage default for allowTcapOps (see patch #243
      • modify documentation for configure --enable-backarrow-key to match the script (see patch #280).
      • fix typo in minstall.sh in patch #283, which made the leading-cap "Xterm" become "xterm" (patch by Miroslav).
    • fix two typos in configure.in from patch #283 changes; one broke the --regex configure option (report by H Merijn Brand).

    Patch #283 - 2012/10/09

    • modify makefile and script to generate appropriate renaming s/xterm/xterm-dev/ for test-package's manpage.
    • improve makefile rules for installing/uninstalling pixmap files, to include the newer mini- and filled- variants.
    • clarify change in manpage regarding patch #282 change to always set a window-decoration icon, even if iconName is not set.
    • add a fourth flavor of window-decoration icons, "filled-xterm" for a monochrome xterm with filled interior.
    • use shape-mask to improve contrast of the window-decoration icons.
    • minor changes to icon colors to improve contrast on bright-mud backgrounds.
    • drop configure checks for memmove versus bcopy, and strerror function; all currently tested platforms support these.
    • cleanup configure macros, as done in byacc 20121003.
    • improve configurability of the built-in icon selectable via the iconName resource.
    • update config.guess, config.sub

    Patch #282 - 2012/09/28

    • improve configure check for XkbKeycodeToKeysym, fixing a regression on some older systems in the patch #280 changes.
    • add clarification in manpage for alwaysBoldMode and veryBoldColors resources (prompted by Derek Martin question about using the former with TrueType fonts).
    • add alternateScroll resource and corresponding control sequences which modify the scroll-forw and scroll-back actions: when the alternate screen is displayed, wheel mouse up/down will send cursor keys (Debian #683942).
    • improve rendering for the case when a Unicode character is absent in the bold font but present in the normal font by temporarily falling back to the normal font (Debian #359006, Debian #408666).
    • provide configure option --enable-double-buffer and ifdef's to allow comparisons with/without double-buffering. The default uses normal buffering.
    • add feature to optionally scroll current page before clearing, controlled by resource setting cdXtraScroll (prompted by patch by Balazs Kezes):
    • integrated patches from Arch Linux forum posting (patches by Balazs Kezes):
      • modify reallocation limit of line-data when resizing screen so that "lost" text will be restored if the screen is first shrunk and then grown.
      • modify output to use double-buffering to reduce flicker.
    • modify scroll-lock action to handle on/off/toggle keywords like other actions. Previously the optional parameter was interpreted as an integer.
    • extend DECSCUSR to provide a way to set the cursor to a vertical bar (patch by Paul Bolle).
    • add -8, -c, -d and -u options to 88colors2.pl and 256colors2.pl scripts. No current terminal emulator recognizes C1 controls while handling UTF-8 encoding—see notes in patch #119 and patch #109 regarding utf8controls—but the -u and -8 options are useful for demonstrating this point.
    • improve speed when changing color palettes using OSC controls by deferring repaint while followup controls might be additional color palette changes.
    • modify SGR 38 and SGR 48 to accept RGB index, matching the closest entry in xterm's palette.
    • extend SGR 38 and SGR 48 to accept colon as parameter separator (request by Paul LeoNerd Evans).
    • modify fullscreen action to allow it to toggle the full-screen mode rather than only set or unset it (prompted by Eeri Kask's suggestion to support _NET_WM_TOGGLE). This implementation does not yet use _NET_WM_TOGGLE.
    • add support for _NET_WM_STATE_MAXIMIZED_VERT and _NET_WM_STATE_MAXIMIZED_HORZ EWMH properties (suggested by Eeri Kask).
    • make fullscreen mode work with the tek4014 window. This change makes only the currently active window to be changed to fullscreen rather than changing both windows.
    • modify TekClear function to discard pending output before clearing the tek4014 display (patch by Kevin Ryde).
    • fix deleteIsDEL feature, broken in patch #280 changes (report by Mike Thornburg, forwarded by Jeremy Huddleston).
    • fix a special case of wrapping double-width characters (report/test-case by Ken Winstein).
    • add E3 extended capability to xterm-basic to match ncurses 20120728 patch.
    • fix incorrect transformation of row-parameter for ClearCurBackground in patch #279 which caused incorrect painting in some scrolling scenarios (report by Chuck Silvers).
    • fix typo in manpage description of +maximized option (Paul Maier).
    • change default for configure option --with-xpm, turning it on unless requested otherwise.
    • add configure option --with-icon-name which can be used to override the default icon used in icon-themes.
    • extend activeIcon resource to provide default value which tells xterm to determine the window manager's name and automatically enable the feature for fvwm and window maker. The explicit true/false values can be used to override this behavior.
    • add "mini" xterm icon, which scales better than the standard xterm icon, e.g., for the gnome/kde "panel" feature.
    • extend iconName resource to search for icon named according to resource value and use that if found. If not found, use compiled-in pixmap. Both set the WM_ICON_NAME property which is used by various window managers, usually for window decoration.
    • updated autoconf patch, adding support for --datarootdir, which changes the default location of manpages.
    • further improved autoconf macros for configuring icons, from vile 9.8h

    Patch #281 - 2012/06/26

    • remove "$(srcdir)/" from install-icon rule to fix builds when --srcdir configuration option is used.
    • fix for configure script's search for icon file when it is not found in the current directory, e.g., when building out of tree (patch by Thierry Reding).
    • undo the XK_Home / XK_End change from patch #280 which broke the non-VT220 keyboard for those keys (report by H Merijn Brand).

    Patch #280 - 2012/06/24

    • add configure check to work around warning from desktop-file-install for "Encoding", noting that it emits deprecation warnings without providing its version information.
    • add configure option --with-icon-theme to tell xterm whether to install into an icon theme, defaulting to "hicolor" (Redhat #755206, Redhat #799614 and Redhat #804279).
    • change --with-icondir to look for "icons" directory rather than "pixmaps" by default. Add new option --with-pixmapdir to allow these two uses to be installed concurrently.
    • modify configure options --with-app-defaults and --with-icondir to accept "auto" as value to look for existing directory from well-known locations.
    • add missing codes for secondary DA response which tell the type of terminal as in the primary DA response.
    • update primary DA response for VT420 to include user windows and horizontal scrolling.
    • add modifyKeyboard resource to support keypad-modifier changes per request by Thomas Wolff.
    • add XK_Home / XK_End to editing-keypad checks
    • add back-tab key kB to termcap entries to match the terminfo.
    • update terminfo to match corresponding entries in ncurses, e.g., add XT and adjust sgr string for xterm-bold entry.
    • add configure options to predefine the most commonly customized resources for terminal-settings, use those to substitute into the manpage the corresponding compiled-in values: altSendsEscape, backarrowKey, backarrowKeyIsErase, deleteIsDEL, metaSendsEscape (Redhat #819588).
    • change default emulation level to VT420 (discussion with Ailin Nemui).
    • improve logic for DECSCL; patch 279 partly enforced limitation of this to higher-level emulations. This patch finishes that change.
    • improve check for base of combining characters, preventing combination when cursor movement has intervened. Mosh's webpage gives two different examples of this, with other causes ascribed to the behavior.
    • modify IL/DL to set cursor to first column on row for better VT102/VT220 compatibility (prompted by code review of mosh).
    • separate state-table entries for DECSC/DECRC from the ANSI.SYS save/restore cursor, since the latter conflicts with DECSLRM when DECLRMM is enabled since patch #279 (report/analysis by Ailin Nemui).
    • fixes to avoid using SIGCHLD handler of main program in printer's subprocess (report by Joe Julian).
    • correct restore-parameter for mouse-modes from patch #279 changes.
    • add null-pointer checks to input-method caching added in patch #277 to fix a problem in the exposure code, when deselecting a window (report by Kriston Rehberg).
    • unset DESKTOP_STARTUP_ID environment variable to lessen confusion on the part of GTK applications which use the variable without checking it (report by John Little).

    Patch #279 - 2012/05/10

    • fill in missing cases in the save/restore modes feature (report by Thomas Wolff).
    • add check to ensure that combining characters are precomposed in the order given (report/analysis by Andries E Brouwer).
    • improve workability check for posix_openpt(), to take into account BSD systems which do not complete initialization until both sides of the pseudoterminal are opened (report by Christian Weisgerber).
    • amend fix for Debian #650291 in patch #277 changes to account for different data returned by vnc4server (Debian #670638).
    • add check in DECCRA operation to make copies of blinking text also blink by updating a line-level flag.
    • modify rectangle operations to work with DECOM.
    • modify DECSERA to use the current protected state rather than preserving it.
    • add precompose resource to allow storing character data in Normalized Form D as described in http://unicode.org/reports/tr15/ (report/discussion with Andries E Brouwer).
    • modify CBT, other ISO-6429 controls which are used by VT520 to work with DECOM.
    • add HPR and VPR controls, ISO 6429 cursor movement used in VT520.
    • remove "linux" restriction for IUTF8 ifdef in main.c (prompted by Matthew Dempsky posting on mailing.openbsd.tech).
    • implement the remaining VT420-level device status reports.
    • change DECXCPR to return page 1, rather than 0.
    • improve VT-level checks on reporting functions, such as DECXCPR.
    • change limit on decTerminalID to 525.
    • fixes to improve vttest vt52 screen when running as a VT420:
      • add checks for some VT2xx and up controls for consistency: DECSCL, S1C8T, S1C7T.
      • modify DECRQSS return for DECSCL to only return that when running as VT2xx and up.
      • when exiting from VT52-mode, resume in VT100 level rather than the level before starting VT52-mode.
    • implement DECLRMM, DECSLRMM and DECNCSM (prompted by discussions with Ailin Nemui and Paul LeoNerd Evans). This modifies several controls to obey top/bottom and left/right margins.
    • correct macro definition used for testing modes used in ANSI/DEC request-mode controls introduced in patch #262.
    • modify x_getlogin to check $LOGNAME and $USER before fallback to getlogin, so that user's choice for these variables can be carried forward to the xterm process (Debian #611487).
    • document DECSCUSR response for DECRQSS in ctlseqs.ms
    • add zIconTitleFormat resource to allow customizing the "*** " prefixed to the icon title when the zIconBeep feature is activated (request by Thomas Adam).
    • modify DECSCUSR to update the same internal variable as RM/SM 12, and document in manpage the two variables used for controlling blinking cursor (report by Paul LeoNerd Evans).
    • correct response data for DECSCUSR in reply for DECRQSS response, which had inverted the blink-value (reports by Ailin Nemui, Paul LeoNerd Evans).
    • add a null-pointer check in OkPasswd macro to fix a problem in resize with Fedora 17 and a serial console (report/patch by Daniel Drake).
    • add workaround for Mac OS X, which loses the window size of a pseudo-terminal when the tty device is opened (report/analysis by Egmont Koblinger).
    • updated configure check for workable posix_openpt versus grantpt, from luit fixes.
    • modify DECIC/DECDC/DECBI/DECFI implemented in patch #277 to enable them only in VT4xx mode and up (report by Ailin Nemui).
    • update config.guess, config.sub

    Patch #278 - 2012/01/18

    • correct initialization for eightBitMeta resource (FreeBSD #164101).
    • make special check for Darwin 9 (and lower) to not use posix_openpt (report by Christian Ebert).
    • minor fixes (adding ".ne" directives) to reduce the cases where groff's utility for generating images for tables dumps core. Most versions of groff (I've found 1.19.2 to be the most stable) dump core when attempting to report that there are too few lines on a page for a table to be shown.

    Patch #277 - 2012/01/07

    • remove special case for ISC pseudo-terminals which attempts to open the pty in two different ways.
    • move call to grantpt before asking utempter to add a record, to work with kFreeBSD which does not update the terminal's ownership until this point (Debian #652907).
    • document limitation of XIM interface in manpage (Debian #230787).
    • cleanup error reporting with new xtermWarning function.
    • add configure option --disable-selection-ops to make the new actions optional.
    • add four new actions for making the selection or data directly copied from the screen (prompted by discussion in Debian #637001, as well as report by Arjen van Tol):
      • exec-formatted
      • exec-selectable
      • insert-formatted
      • insert-selectable
    • add visualBellLine resource to allow visualBell to flash only the current line (prompted by patch by Gertjan Halkes).
    • add eightBitMeta resource to control the features which modify or interpret the eighth bit of a key when the meta modifier key is pressed (prompted by Debian #326200).
    • improve discussion of eightBitInput in the manpage (prompted by Debian #326200).
    • correct logic for alt-sends-escape action, overlooked when implementing altSendsEscape resource, which still used eightBitInput resource value.
    • add a workaround for XAllocColor(), which does not actually allocate "a read-only colormap entry corresponding to the closest RGB value supported by the hardware", but rather a rough approximation (Debian #650291).
    • undo parameter checks for RequestResize() added in patch #251 and amended in patch #270, because zeros also are special cases (report by John S Urban).
    • modify some test-scripts to use /bin/echo rather than the shell's possibly-builtin echo, to work around broken configuration on Mac OS X, i.e., neither honoring the option nor flagging an error.
    • add SGR 1006, as a better technical solution than SGR 1015:
      • the responses will not be confused with line-deletion and scrolling controls.
      • the button encoding is a little simpler, since it does not add an unnecessary 32 because the integer parameter does not have to be represented as a printable character.
      • the control responses for pressing and releasing a mouse button differ, allowing an application to tell which button was released.

      Besides these improvements, in discussion, it was noted that urxvt's implementation of 1005 is incorrect, relying upon a locale that provides UTF-8 encoding. In contrast, vttest demonstrates a correct decoding, independent of locale.

    • add support for urxvt SGR 1015 to address shortcoming of SGR 1005 with luit (patch by Egmont Koblinger).
    • add ISO and DEC controls useful for left/right scrolling.
    • add some changes for OpenBSD and MirBSD (adapted from patch by Thorsten Glaser):
      • disable search for non-Unix96 ptys.
      • fix a gcc warning in timestamp_filename
      • modify Imakefile to install xterm setgid to utmp.
    • add/use/prefer posix_openpt() for opening pseudo-terminal.
    • modify special errno handling case in ptydata.c from patch #158 to allow for the possibility that any platform may have special cases where "/dev/tty" is absent. For example, this can happen in a FreeBSD jail (patch by David Wolfskill).
    • add keyboard logic to map shift-tab into XK_ISO_Left_Tab, which is usually, not always, done by the X keyboard configuration.
    • portability fixes for some configure macros: CF_XOPEN_SOURCE

    Patch #276 - 2011/10/10

    • modify clipping limits for TrueType fonts to account for the scaleHeight resource setting, to work around another problem due to recent FreeType changes. In this case, the DejaVu Sans Mono set to pixelsize=13.5 is truncated because the font descent is reduced by FreeType to match an incorrect height metric (report by Adam Lee).
    • improve recovery when bitmap fonts are not installed, e.g., so that switching font-sizes works for TrueType fonts.
    • modify lookup for XTERM_SHELL feature to allow relative pathnames.
    • modify abbreviation disambiguation check for command-line parameters to account for -geometry, whose parameter may begin with "+" or "-" (report by Scott Bertilson).

    Patch #275 - 2011/09/11

    • add ash, zsh to known shells for resize.
    • modify resize to reuse the logic from xterm which determines the actual logon-user's shell if $SHELL is not set.
    • revert the unsetenv("SHELL") added in patch #272.
    • an unsetenv("SHELL") added in patch #272 to help ensure that luit would get the user's shell consistently did not work as expected for cases where multiple names are in the password-file for a given uid. That was because changes in patch #157 to handle this situation did not take into account that repeated calls to getpwnam and getpwuid return a pointer to the same static buffer. Fixed the older logic to work as intended, by ensuring that the passwd-data from each call is stored separately (report by Paul Keusemann).
    • adjust ifdef's for putenv and unsetenv in case only one of those is provided on a given platform.
    • correct comparison used in ExposeContains macro from patch #274 changes, to handle window-dragging (patch by Todd Eigenschink).

    Patch #274 - 2011/09/05

    • portability fixes for cygwin: do not define SVR4, and work around nonstandard header location.
    • ifdef'd use of unsetenv from patch #273 changes to work with Solaris 9 (report by Waldemar Rachwal).
    • modify logic for XtAppPending to merge adjacent Expose and ConfigureNotify events which are redundant (report by Edward McGuire).
    • fix an unneeded warning message when -r option is given.
    • remove a few redundant entries from table used for helping abbreviation-checking of command-line options, makes -geom work again after patch #272 changes as an abbreviation of -geometry.
    • add scaleHeight resource and command-line option -sh as workaround for some font-configurations broken by changes in FreeType 2.4.6 (report by Miroslav Hodak).
    • portability fixes for some configure macros: CF_FUNC_TGETENT, CF_XOPEN_SOURCE, CF_X_ATHENA_LIBS.
    • add configure option --with-freetype-config to improve selection over the plethora of configuration options which freetype has so far provided.
    • build-fix for configure --enable-load-vt-fonts when --enable-widec is not specified.
    • build-fixes for suppressing various features, needed after changes in patches 270, 271 and 272 (report by Brian Lindholm)

    Patch #273 - 2011/08/25

    • build-fix for out-of-tree "make docs" rule.
    • correct a typo in x_strdup, from patch #198 changes.
    • correct initialization for -e option, broken in patch #272 changes (report by Gabriele Balducci).
    • build-fix for out-of-tree builds to address minstall script changes in patch #272 (patch by Thierry Reding).

    Patch #272 - 2011/08/24

    • document limitation of Gtk in connection with xterm's -into option, in the manpage (Ubuntu #806969).
    • improve -into by checking for and using the size of the window within which xterm is embedded, overriding other clues.
    • modify logic for localeFilter resource to allow that to include command-line options of luit.
    • improve -into by checking for invalid window-id, and allowing hexadecimal/decimal/octal values.
    • improve keepSelection, adding the case where the highlighting is cleared, overlooked in patch #230 (patch by Marco Peereboom).
    • improve command-line parsing to make abbreviate options work consistently across xterm-specific versus standard X toolkit options, and report cases where an abbreviated option happens to be ambiguous. In particular, -d now works as an abbreviation for -display.
    • fix regression in command-line parsing introduced in patch #271 changes for Debian #629358, (Debian #637910).
    • split-out new termcap/terminfo building block xterm+kbs for configurability.
    • modify terminfo file to reflect changes in ncurses for xterm-16color and xterm-256color.
    • modify minstall.sh, etc., to reflect the default default class, $TERM and decTerminalID values.
    • reword resize manpage to reflect the fact that $TERMCAP is not set on all systems (patch by Alan Coopersmith).
    • work around combined Xaw6/Xaw7 package in DragonFlyBSD which omits the usual symbolic link to the preferred library name.
    • further improve build-fix for termcap systems by checking for some which are only partial implementations, e.g., termcap 2.08 in CentOS 5.2

    Patch #271 - 2011/07/14

    • omit permissions adjustments to pty on exit except for pre-Unix98 ptys, since modern implementations handle this (report by Sean C Farley).
    • modify logic for switching fonts between UTF-8 and non-UTF-8 encoding to not merge the derivable bold-, wide- and widebold values from the VT100 fonts. Also suppress warning when not using UTF-8 fonts if wide- and widebold-fonts cannot be derived or otherwise loaded (report by Werner Scheinast).
    • modify menu-creation to suppress entries which will never be used in the current configuration, rather than simply disabling them.
    • add resource printModeImmediate and menu item to allow print of screen plus saved lines to a file.
    • add menu item to allow runtime enable/disable of the printFileOnXError feature.
    • append a timestamp to filename used in printFileOnXError feature, and restrict its permissions (request by Vincent Lefèvre).
    • add a check when cancelling cursor-blinking, in case the cursor is blinked off. Fix so that the cursor is repainted without waiting for other events, e.g., keypress (report by Ailin Nemui).
    • add configure --with-app-class option, to simplify building "xterm-dev" packages with filenames that do not conflict with conventional "xterm" packages.
    • corrected logic flow for DECSCL, which prevented the updated operating level from being reported via DECRQSS (report by Ailin Nemui).
    • corrected default for brokenStringTerm resource to match manpage.
    • add vttests/dynamic.pl
    • add runtime check for locale not supported by X libraries, and fallback to XA_STRING in this case (request by Bryan Henderson).
    • fix a special case in configure script after no FreeType libraries are found. The script was proceeding to check for a usable configuration.
    • add xterm+tmux building block to terminfo (adapted from changes proposed by Ailin Nemui and Nicholas Marriott).
    • improve discussion of faceName resource in manpage (adapted from suggestions by Jens Schweikhardt).
    • correct mapping of shifted up/down cursor-keys in termcap function-keys mode, i.e., resource tcapFunctionKeys (patch by Gertjan Halkes).
    • update AIX case in CF_XOPEN_SOURCE configure macro to add release 7.x.
    • modify ifdef's in xterm_io.h for __hpux to force that to use the hacked SYSV support in that file. This fixes a problem with a non-blocking socket call (patch by Paul Lampert).
    • improve filtering of desktop category scanning, to exclude XFCE.
    • modify configure script to work with systems that have both ncurses (or other terminfo) as well as a real termcap library, e.g., Slackware (report by Andrew Watts).
    • modify configure script to work around special case where user's environment adds compiler flags to the CC variable (prompted by report by Paul Lampert).
    • amend change for Debian #110226 so that "-h" or "-v" options cause an exit, rather than simply printing to stdout while the window is displayed (Debian #629358).
    • add response for DECRQSS which gives the setting for DECSCUSR.
    • modify AllocateTermColor() to handle XtDefaultForeground and XtDefaultBackground, which are not recognized by XParseColor. For example, this fixes the use of OSC 112 when no explicit cursor color was set (report by Ailin Nemui).
    • handle special-case of KeyPress translated to popup-menu action (Ubuntu #756273).

    Patch #270 - 2011/04/26

    • build-fix, e.g., for using imake on platforms which use the termcap library.
    • modify utf8 resource to accept a name.
    • mention default for fontWarnings in manpage (report by Werner Scheinast).
    • split "UTF-8" menu entry into "UTF-8 Encoding" and "UTF-8 Fonts" (prompted by discussion with Werner Scheinast).
    • gray-out font-menu entries when a font fails to load, e.g., a bitmap font is not installed.
    • improve behavior when there is no app-defaults file:
      • set the toolBar resource to false
      • gray-out the font menu entries where no resource is found.
    • add configure option --with-desktop-category to allow customization of the ".desktop" files.
    • build-fix for the install-desktop makefile-rule, when the source/build directories differ (patch by Loïc Minier).
    • add menu entry and corresponding resource which can be used to suppress all bold-fonts (discussion with Jan Engelhardt).
    • make internal line-size value consistent with allocated sizes of character and related arrays to ensure that bulk copying of line data, e.g., in scrolling, accounts for the padding used for pointer alignment (adapted from patch by Rajesh Mandalemula, also reported by Ali Bahar).
    • widen ifdef for screen-resizing logic from patch #176 changes to send SIGWINCH to process group to include any system supporting ioctl(*,TIOCGPGRP,*) (prompted by linux-specific patch in OpenSUSE rpm package).
    • add printModeOnXError and printFileOnXError resources, which allow the user to specify that xterm will write the contents of its screen to a file if it is exiting due to an X error (Debian #280457).
    • restore logic that made reverse-video apply to the scrollbar's foreground/background, broken in patch #158 (report by Bryan Ischo).
    • amend some of the window operations parameter-checks added in patch #251 for the push/pop title feature, to allow the parameters used for window resizing to be -1's, which makes the corresponding values ignored rather than using the window's maximum width/height (report by Noah Friedman).
    • correct order of initialization for translations vs fullscreen resources to enable a special case which omits the Alt-Enter translation when fullscreen is disabled (Debian #612978).
    • update config.guess, config.sub

    Patch #269 - 2011/02/19

    • build-fixes for imake (report by Heiko Berges).
    • modify autoconf macro CF_PKG_CONFIG to work with cross-compile environments (patch by Thierry Reding).
    • modify MapToColorMode() to favor bold over underline, matching the precedence used before patch #252 (report/analysis by Nicolas George).
    • add omitTranslation resource, which can be used to suppress the default translations for these features:
      • fullscreen
      • scroll-lock
      • shift-fonts
      • wheel-mouse
    • make the fullscreen feature configurable (Debian #612978)
      • add it to the configurable list disallowedWindowOps.
      • add command-line option -fullscreen to allow the feature to be enabled at startup.
      • add resource fullscreen to control whether the feature is active or may be enabled.
    • modify probe_netwm_fullscreen_capability for 64-bit machines. Contrary to XGetWindowProperty manpage, that function returns 32-bit data packed as long's.
    • eliminate copy of name resource, which was otherwise used only to give the terminal-description name for the tcap-query feature. Use the actual $TERM value instead, as derived from termName resource, etc.
    • eliminate an old inconsistency with error messages, some used the -name option, while others used argv[0]. The latter is now used consistently.
    • improve configure check for rpath-hack, to improve builds on systems where gcc will not search /usr/local/lib, etc.
    • build-fix for Xaw3d configuration (report by H Merijn Brand).
    • update config.guess, config.sub

    Patch #268 - 2011/02/10

    • fix an inconsistency of the "Enable Reverse Video" checkbox in the VT Options menu. This also removes a special case added in patch #217 which limited the effect of the reverseVideo resource (Debian #603808).
    • amend decoding of misformed UTF-8 sequences to avoid absorbing valid characters as documented in Unicode 6.0 section 3.9 (report by Keith Winstein).
    • do not set urgency hint when window already has focus (patch by Dimitrios Christidis).
    • amend extended mouse-coordinate mode from patch #262 changes to include the Cb button-code, which also may be greater than 127 (report by Ailin Nemui).
    • ensure that underline-cursor is visible when an application happens to set the background color (report by Christian Weisgerber).
    • add feature for full-screen toggling using either Alt-Enter or a menu selection (integrated patch by Dave Simmons).
    • add missing logic to handle reallocation of FIFO index for the "UTF-8" menu entry (report by David Holland, NetBSD #44344).
    • add makefile rules docs-ctlseqs, docs-xterm, etc.
    • correct typo in description of DECRPM in control sequences document (report by Ailin Nemui).

    Patch #267 - 2010/11/20

    • minor formatting changes to ctlseqs.ms to simplify a script which extracts the feature information. See the results in Comparing versions, by counting controls in the xterm FAQ.
    • add docs-clean makefile rule.
    • add copy-selection action (request by Timo Juhani Lindfors, Debian #588785).
    • trim leading/trailing blanks from string used for "Selection" font-menu data.
    • trim leading/trailing blanks from color resource values.
    • configure script improvements:
      • add workaround for removal of X11 dependency from Xt's package file (report by Robert Hooker).
      • add workaround for removal of fontconfig dependency from Xft's package file (report by Jeremy Huddleston).
      • add workaround for removal of Xmu dependency from Xaw's package file (report by Jeremy Huddleston).
      • improve workaround in CF_X_TOOLKIT macro, checking for other possible packages where Xt's dependencies may be given.
      • prefer ${name:=value} to ${name-value}, since recent bash changes break legacy support for that feature.

    Patch #266 - 2010/10/24

    • add rpm and dpkg scripts, for testing.
    • more fixes for Debian #600707 (report by Cyril Brulebois).

    Patch #265 - 2010/10/22

    • fix a regression in fontname logic from patch #263 changes (Debian #600707, reported by Vincent Lefèvre).
    • revert modification of any-event/any-button protocol from patch #263 changes. It interferes with selection using a shifted mouse button (reports by Neil Bird, Bram Moolenaar).

    Patch #264 - 2010/10/14

    • replace a null-pointer check with check for empty string in xtermOpenFont, to eliminate a warning message from patch #263 changes.
    • build-fix for patch #263 when toolbar is not configured (patch by Chris Clayton) (reports by Robby Workman, David Wood).

    Patch #263 - 2010/10/13

    • corrected initialization of "misc" resource values, to ensure that xterm has allocated a copy of strings which may not have been malloc'd by the X library (Debian #600129).
    • modify handling of any-event/any-button mouse protocol; it now is active with any combination of key-modifiers.
    • add debugging feature showWrapMarks, which marks lines which xterm knows are wrapped, showing where a double-click will select past the end of a line.
    • build-fix to address change in include-guards for Xlib.h in ongoing Xorg edits (patch by Jeremy Huddleston).
    • improve pointerMode by continuing to watch for motion events after mouse tracking is disabled if the pointer is hidden (Debian #594856).
    • further extend initialization for active-icon font to check if the font was not loaded successfully, to retry with font1, or as even (if TrueType fonts are used) to use a TrueType font. The retries are to help with cases as in patch #241 where the bitmap fonts are not available.
    • fix special case of active-icon used when TrueType font is specified for the xterm window, from patch #261 change. In that case, the default font's size was used for layout of the active icon's window (Debian #591265).

    Patch #262 - 2010/8/30

    • fix a case where changing the cursor color via escape sequences did not immediately update the screen (report by Andreas Wagner).
    • implement ANSI and DEC request-mode control sequences. The latter includes the xterm-specific private modes such as the mouse mode. The feature is ifdef'd with the rectangle operations since its decoding overlaps that feature.
    • correct typo in ctlseqs.ms for response of OSC 21 (patch by Kevin Schoedel).
    • improve discussion of mouse tracking in ctlseqs.ms
    • increase an array limit used in reporting mouse events (report by Ryan Johnson).
    • add extended mouse-coordinates mode, allowing up to 2015x2015 windows, using UTF-8 encoding (patch by Ryan Johnson).
    • modify manpage hyphens to conform with Debian.

    Patch #261 - 2010/6/28

    • fix regression in renderFont logic, from patch #260 changes (report by Joseph Quinsey).

    Patch #260 - 2010/6/20

    • modify plink.sh to work around problem linking to recent PCRE libraries.
    • extend renderFont resource to allow deferred switch to TrueType fonts without affecting existing resource settings (Debian #585620).
    • modify configure macro CF_X_TOOLKIT to work around omission of ICE library from ".pc" file (report by Miroslav Lichvar).
    • change configure script default for --enable-broken-st i.e., the brokenStringTerm feature) to normally enable it. If the corresponding resource is enabled, this feature eliminates an apparent freeze of xterm when sending mis-encoded data to the screen (Debian #584801).
    • document in manpage some actions which were overlooked:
      • readline-button
      • scroll-lock
      • set-8-bit-control
    • undo a change to limit-check in ScrnRefresh in patch #257, which broke fastScroll feature (Debian #584841).
    • modify handling of brokenLinuxOSC and brokenStringTerm to also sound the bell.
    • add control/D and control/Q to controls which will cause early exit from control string per brokenStringTerm resource.
    • improve documentation of brokenStringTerm resource in manpage.

    Patch #259 - 2010/6/5

    • modify configure check for luit to include new aliases for the program (xterm-filter and bluit).
    • add workaround in xtermClearLEDs() to account for Xkb's override, making vttest's LED demo reset the scroll lock.
    • filter out client-message events when deciding whether to hide cursor, e.g., when using SCIM (patch/report by anonymous user).
    • improve description of -bd option in manpage (report by Guy Daniel Clotilde).
    • modify configure checks for PCRE and other libraries to use pkg-config, if available.
    • amend change from patch #252, to take veryColorColors resource into account when checking colorBDMode resource for TrueType fonts (report by anonymous user).
    • add vttests/query-fonts.pl script for demonstrating the OSC 50 font query.
    • improve manpage discussion of Scroll Lock feature.
    • improve configure macros CF_GCC_VERSION and CF_GCC_WARNINGS.
    • fix warnings for "clang --analyze".
    • change default for allowScrollLock resource to false, noting that the supposedly unused key has been useful for various rebindings (Debian #580946).

    Patch #258 - 2010/5/1

    • add pointer-checks in ScrnRefresh to fix a case in rapid scrolling where an empty record is fetched from the scrollback FIFO.

    Patch #257 - 2010/4/22

    • correct ctlseqs.ms description of OSC 17 and OSC 19 (patch by Emanuele Giaquinta).
    • corrected logic for menuLocale resource; the setlocale function returns the original locale only when querying.
    • improve filtering of translations resource, narrowing the scope of the alwaysUseMods to address only the translations that would cause a key to be sent to the host (report by Andrew Gaylard).
    • change default value of menuLocale resource to "C", to work around longstanding Xorg bug.
    • modify handling of scrollKey feature to ignore XON/XOFF keys.
    • implement scroll-lock feature.
    • revise memory allocation in UTF8toLatin1() to fix an out-of-bounds index (Mandriva #54531).
    • compute value for first wide-character rather than assuming it is 256, fixes problem with -cjk_width introduced in patches 242 and 249 (report by Thomas Wolff).
    • improve configure script:
      • corrected check for _XOPEN_SOURCE for OpenSolaris.
      • when possible, add rpath option for libraries in unusual places
      • add configure option --disable-rpath-hack to control whether the rpath option can be added.
    • modify AllocateTermColor() to separate initialization from control sequences, fixing problem from patch #254 changes where enabling allowSendEvents resource prevents setting cursor color on command-line (Debian #572928).
    • amend logic from patch #185 to not reallocate cell-array if processing ESC % G to switch from UTF-8 if already in ISO-8859-1 character set (report by Michael Koehne).
    • fix to avoid calling XmuInternStrings() with zero count (report by Johan Bockgård).
    • fix build when --disable-ansi-color configure option is used.
    • fix build when neither OPT_TCAP_QUERY or OPT_TCAP_FKEYS is defined (patch by Matthieu Herrb)

    Patch #256 - 2010/3/6

    • add TerminalEmulator to desktop category files.
    • modify sinstall.sh to ignore the "." appended to permissions by selinux.
    • change app-defaults organization, installing UXTerm-color and KOI8XTerm-color for consistent behavior regarding customization: color (prompted by discussion in Ubuntu #421261).
    • fix typo in minstall.sh from patch #255 changes, and add case for /var/run needed for full path of utmp (report by Julien Cristau).
    • minor fix to xterm manpage, remove a comment stating that margin bell can be changed via the VT Options menu. That was replaced in patch #225
    • add a "docs" rule to makefile.
    • fix initialization of Atom used for XkbBell feature from patch 243 changes. Unlike the other calls to XInternAtom(), in this case the flag telling X to create the Atom was unset (patch by Chris Adams).

    Patch #255 - 2010/1/21

    • rename install.sh to install-sh in case suffix-rules might interfere.
    • extend range for convertToUTF8 function to full 31-bits, to use with printing, etc.
    • improve manpage by checking for actual locations of utmp/wtmp files (Debian #562640).
    • modify configure macro CF_XOPEN_SOURCE to remove -D's before adding the same name rather than relying on -U's, to reduce redefinition warnings for some platforms that have conflicting definitions in headers.
    • correct logic used to switch to alternate screen using FIFO-lines configuration (Debian #565772).
    • update config.guess, config.sub

    Patch #254 - 2010/1/6

    • add a configure-check to eliminate install-ti rule from Makefile when the system has no tic (terminfo compiler) program. This lets one use the install-full rule more consistently.
    • amend change to WriteText() function in patch #252 to take into account the colorAttrMode resource (report by Krzysztof Kotlenga).
    • document titleModes resource in manpage, added in patch #252.
    • modify tcap-query table entries for shifted up/down cursor keys to match ncurses convention.
    • improve lookup of termcap-query data, allowing for duplicate keycodes versus missing entries.
    • add control sequence which can be used to modify the terminal data used for the termcap-keyboard.
    • improve portability of tcap-query feature, using terminfo functions in preference to termcap on systems having terminfo.
    • improve font-setting/querying control (OSC 50):
      • when TrueType font is selected, the TrueType faceName will be set, rather than the bitmap font.
      • when TrueType font is selected, querying returns the name of the TrueType font.
      • querying a font recognizes the relative-font convention that setting a font could use.
    • add menu-entry for allowColorOps.
    • add new resources for fine-tuning menu entries: allowColorOps, disallowedColorOps, disallowedFontOps and disallowedTcapOps.
    • correct logic for disabling the "TrueType Fonts" menu item; it was not ensuring that the faceName resource value was non-empty.
    • implement VT520-style controls DECSMBV and DECSWBV for setting the margin- and warning-bell volume.
    • fix a minor error from patch #243 which made the zIconBeep feature use a minor-error tone rather than an informational tone.
    • add a null-pointer check for the case where renderFont resource is true, but faceName resource is unset, used in logic to strip "xft:" prefix from patch #251 changes (patch by Michael Riepe).
    • add special case to configure CF_XOPEN_SOURCE macro to use extensions on Darwin (patch by Dennis Preiser).
    • improve configure checks for regular expressions header and library
    • update config.guess, config.sub

    Patch #253 - 2009/12/10

    • add a null-pointer check in getPrinterFlags() per changes in patch #252.
    • add a null-pointer check, needed in UTF-8 mode for Xft fonts after changes in patch #252 (patch by Alan Coopersmith).
    • correct size when clearing struct for tek4014 (patch by Jochen Voss).
    • parenthesize expression in MoreRows macro, fixing a limit check added in patch #251 (Debian #560039).

    Patch #252 - 2009/12/7

    • modify title-querying logic to support retrieval of titles encoded using UTF-8.
    • add new "title-modes" control sequence for controlling whether window/icon titles can be set or queried using UTF-8, optionally encoded in a hexadecimal string.
    • use mkdir -p rather than mkdirs.sh (prompted by discussion of mawk by Aleksey Cheusov).
    • add appropriate copyright/license notices to the bulk of files lacking same, and modify to use identical terms in others which used different wording. The main exceptions are the files contributed by Markus Kuhn, who appears to prefer public domain distribution, noting that I have modified/improved several of these without changing the terms of distribution (request by Jari Aalto).
    • add control sequences for resetting the "dynamic" colors to their default values.
    • add control sequences for resetting the "special" colors to their default values.
    • add control sequences for setting the "special" colors such as colorBD (bold).
    • add overlooked case for setting highlight foreground color with the dynamic-colors control.
    • add OSC 104, for resetting ANSI/16/88/256 colors to default.
    • reset ANSI/16/88/256 colors to default in soft/hard reset functions.
    • strip "xft:" prefix from faceName and faceNameDoublesize resource values,
    • add DECSCUSR (discussion with Andy Koppe).
    • add check/warning on failure to load font, to see if the name looks like an Xft pattern rather than XLFD. This can happen if someone happens to modify their X resource settings for programs that read data from xterm's namespace.
    • modify handling of print and print-everything actions to allow the various printer flags to be overridden by supplying parameters.
    • add resource printerNewLine (request by Ovidiu Gheorghioiu).
    • minor cleanup, finish using TScreenOf() and TekScreenOf() macros introduced in patch #224.
    • improve checks in ShowCursor/HideCursor to get the background color, particularly when highlightReverse resource is used (reports by Jan Engelhardt, Christian Weisgerber).
    • correct checkVeryBoldAttr to omit comparison of foreground color to special color values used for color<XX> resources (report by Jan Engelhardt).
    • make colorBDMode and colorULMode resources work with TrueType configuration (report by Jan Engelhardt).

    Patch #251 - 2009/11/11

    • add window-ops controls to push/pop icon and/or window labels on a stack.
    • minor fixes to align termcap file with terminfo.
    • add resource disallowedWindowOps, to allow fine-tuning of features to suppress with the allowWindowOps resource (prompted by discussion with Bram Moolenaar).
    • add makefile rules for resize-manpage to pdf, etc.
    • further improve limit-checks in select/paste (Mandriva #54531).

    Patch #250 - 2009/10/13

    • add check and error-message for fonts that have no printable values in the ISO-8859-1 range (Debian #542434).
    • some compiler-warning cleanup, in particular workaround for defective implementation of gcc's attribute warn_unused_result (report by Bram Moolenaar).
    • improve estimate of single-column width for packed TrueType fonts by ignoring extents for codes 127 and 159.
    • improve line-drawing for TrueType fonts which happen to have defined glyphs which are not line-drawing in 0..31 by assuming they're not, and just checking the existence of the Unicode codepoints. This makes it more likely that the user can override a misconfigured font using the "Line-Drawing Characters" menu entry.
    • limit minimum cell-width for packed font to maximum-advance reported by Xft. Some fonts are wider than that, even in the Latin-1 range (Debian #550497).
    • add list of direct-contributors in "THANKS" file.
    • stylistic changes to this file to help scripted extraction of list of contributors.
    • correct off-by-one in okPosition fix from patch #249 limit-checks which prevented double-click selection on the bottom line of the screen (reports by Rajeev V. Pillai, Debian #550368).
    • add -q option to vttests/256colors2.pl and vttests/88colors2.pl to demonstrate bulk initialization of color palette.
    • improve the workaround from patch #188 by enabling resources for the 88-color model.
    • document in xterm manpage the limited availability of resources color16 to color255 as noted in patch #188 (Ubuntu #438850).

    Patch #249 - 2009/10/1

    • change default for allowWindowOps resource to false.
    • add limit-checks for result of visual_width() function, needed from patch #242 and exposed by #244 changes (Debian #548321).
    • improve limit-checks in select/paste.
    • fix a remaining bug from patch #230 changes for displaying multi-column characters in a proportional font (report by Chris Jones).
    • add new resource forcePackedFont and menu entry "Packed Font" to control whether to use the font's minimum (default) or maximum width when those differ. The workaround which xterm uses to accommodate proportional fonts is not necessary with certain fonts such as unifont which happen to store a mixture of multicolumn glyphs (report by Chris Jones).
    • fix an (old) bug which did not restart the timer for blinking text if the only blinking text was temporarily scrolled out of view, e.g., using the scrollbar.
    • fix an (old) flaw in the delete-line operation where the text which is scrolled into view while the display is scrolled up was not repainted.
    • improve delete-line and insert-line operations, retaining selection when the selection does not intersect the deleted/inserted lines.
    • fix an (old) off-by-one error when an application cleared above the cursor position while the display was scrolled up, that would leave an extra line of text uncleared.
    • fix a similar problem where the double-size attribute would not be reset when clearing the screen while the display was scrolled up.
    • fix an indexing error which would occur if an application cleared a line while the display was scrolled up and was also in UTF-8 mode (Redhat #524503). The error was from patch #228 but more visible after changes from patch #244.

    Patch #248 - 2009/9/11

    • fix an overlooked adjustment for selecting double-width characters in the narrow-character configuration.
    • eliminate uses of XTERM_CELL and XTERM_CELLC where an appropriate LineData pointer is available.
    • correct expression in okScrnRow macro, making selections give the length of lines below the visible screen (report by Stuart Henderson).
    • correct logic used to improve performance of missing-glyph check, which did not handle line-drawing characters (Debian #545220).

    Patch #247 - 2009/8/30

    • add ifdef's and check for openpty() on DragonFly (patch by Alex Hornung).
    • correct calculation for size of line's data block, which was sometimes off-by-one when configured using --enable-16bit-chars (report by H Merijn Brand).
    • fix indexing error in print-everything feature from patch #246 (patch by Ovidiu Gheorghioiu).

    Patch #246 - 2009/8/16

    • remove obsolete logic for saving/restoring wrapping flags, which did not work on 64-bit platform. Wrapping flags (stored in the line-index) are now copied with line-data (Debian #541160).
    • modify comments in app-defaults files to avoid problem with C preprocessor used by xrdb (Debian #541603).
    • restore special case in makeColorPair, needed for colorBDMode resource (Debian #541089).
    • correct SetLineFlags() macro, broken in patch #244 when recoding to avoid gcc-specific bitfields (Debian #541236).
    • modify initialization of screen buffers to ensure that pointers align to int-boundaries. This fixes a problem introduced in patch #244 where the color- and character-arrays (stored after the video-attributes in each row) might be misaligned (report by Rajeev V Pillai).
    • add limit-check in ScrnRefresh for handling saved-lines from the circular buffer which are repainted on a screen whose width has increased. To improve performance, circular buffer entries are not resized (report by Rajeev V Pillai).
    • correct type for CellColor (a late change in patch #244 to avoid gcc-specifc enums made that unsigned rather than unsigned short, for the 256-color option).
    • fix typo in configure option --enable-16bit-chars (report by Rajeev V. Pillai).

    Patch #245 - 2009/8/12

    • correct a special case in saving FIFO-lines from patch #244. If the screen was shrunk, xterm used the wrong amount for copying to FIFO-lines, and then used this amount to adjust the current row on the screen. That was both a visible defect (Debian #541109) as well as a potential addressing error (Debian #541132, Debian #541160, and Debian #541236).
    • add clarification in xterm manual about the various allowXXXOps resources, which are disabled when the allowSendEvents resource is active (patch by Julien Cristau, Debian #531597).

    Patch #244 - 2009/8/9

    • refactored storage of saved-lines, providing a configure option to manage them as a FIFO (actually a circular buffer), improving performance. Added configure option --enable-fifo-lines to enable/disable the new feature (it is enabled by default).
    • added fastScroll resource, to amuse people who measure terminal emulator performance by cat'ing large files to the screen.
    • modify check in readPtyData from return values to provide exit on zero-bytes read from pty for FreeBSD, or eliminate high-CPU in "xterm-hold" processing (discussion with Ulrich Spoerlein, FreeBSD ports/136686). The check was originally modified to combine negative/zero values in XFree86-3.1.2E, 1996/05/06.
    • add configure option --enable-16bit-chars to provide wide-characters with 16-bits (rather than the default 32-bits).
    • add retryInputMethod resource to allow configuring out the retries xterm uses to connect to non-responsive XIM server, to work around defective X configurations as noted in NetBSD mailing list.
    • make regular-expression selection work for VT100 double-sized characters.
    • improve layout when drawing missing characters in a proportional font, e.g., as boxes, to take into account whether they are double-width (report by Guilbert Stabilo on comp.unix.shell).
    • add capability for keypad-center (kb2/KA2) to termcap entry for xterm-new, as well as xterm-8bit, xterm-sun and xterm-vt220 (FreeBSD conf/136336).
    • change default for keepSelection resource to true (prompted by discussion with David Muir Sharnoff).
    • remove a limit-check in ptydata.c, allowing Unicode values past 64k to be displayed using TrueType fonts (Debian #458432).
    • remove a vt52-specific ifdef to allow mapping F1-F4 to PF1-PF4 when vt52 support is not compiled (report by Olaf 'Rhialto' Seibert).
    • save/restore line-wrapping flags when converting from ISO-8859-1 encoding to UTF-8 encoding, as well as when resizing screen.
    • remove extra adjustment of position in fix for Debian #418324.
    • modify default check for mkWidth resource to check for line-drawing characters, which are categorized as double-width in Solaris 10 (report by Sebastian Kayser).
    • add "print-everything" action (patch by Ovidiu Gheorghioiu).
    • start refactoring scrollback data using new getLineData() function.
    • demote recent change to Debian #252873 fix to experimental, ifdef'd out as EXP_BOGUS_FG (Debian #522141).
    • work around groff mapping of ASCII quotes using macros (requested by Reuben Thomas based on Colin Watson advice, fixes Debian #378700).
    • correct symbol used for default of allowWindowOps which was DEF_ALLOW_FONT rather than DEF_ALLOW_WINDOW (report by Matthieu Herrb).
    • amend fix for tek4014 from patch #243 to make it only apply to the Tek Options menu.

    Patch #243 - 2009/3/28

    • revert change to default for allowTcapOps (request by Bram Moolenaar).
    • reallocate result returned by xtermEnvLocale() to avoid reference to freed memory after handling menuLocale resource.
    • fix an old (X11R5) bug in tek4014 for switching fontsizes.
    • add resource defaultString to make configurable the use of "#" when pastes of UTF-8 text fail due to limitations in the current locale settings.
    • make the set of selection target Atom's configurable by two new resources eightBitSelectTypes and utf8SelectTypes, e.g., to use the TEXT Atom in preference to UTF8_STRING (discussion with Stanislav Sedov regarding koi8rxterm and the FreeBSD port).
    • modify handling of TARGETS Atom by making it return exactly the set of targets as those which xterm is currently providing.
    • set MANPAGER and PAGER explicitly to /bin/cat in minstall.sh to work around /etc/man.conf's with those variables already set (report by Марьясин Семён).
    • improve error-checking of tcap-query parser.
    • add check for keyboard tcap), which ensures that terminal descriptions containing the same string for shifted/unshifted keys will be seen by tcap-query as only the unshifted key. (This would only happen with an incorrect terminal description).
    • fix conversion for input event-state to modifier-parameter which made tcap-query feature not work with tcapFunctionKeys (keyboard type tcap).
    • add "DEF_ALLOW_XXX" definitions to main.h to allow overriding the default compiled-in values for "allowxxx" resources.
    • remove check on bell-percentage added in patch #242, which disallowed zero/negative values (Redhat Bugzilla #487829).

    Patch #242 - 2009/2/15

    • fix configure check for XkbBell and provide appropriate parameter for it.
    • fix a caching problem with double-size fonts versus reverse video that could cause core dump.
    • repair double-size fonts from workaround used in patch #240.
    • add new section to the VT Fonts menu which allows enabling or disabling the font, termcap (tcap-query), title and window operations.
    • add fontWarnings resource, to control whether to show warnings on failure to load a font.
    • improve warnings for unloadable fonts introduced in patch #240 by limiting those to the cases where a font would be specified directly by a resource setting rather than a derived fontname.
    • further amend fix for Debian #252873 from patch #197 to treat a blank cell which does not have both foreground and background colored as a non-colored cell. This improves a special case where the cursor is on a blank cell which had foreground color scrolled in (report by Miroslav Lichvar).

      Also add the same logic when hiding cursor, so the outline matches the in-focus cursor.

    • modify internals to reduce places PAIRED_CHARS() is used, making WriteText() and ScrnWriteText() accept IChar array, as well as providing a wrapper for drawXtermText().
    • change default XIM font from "*" to "fixed" to improve startup time in zh_CN.UTF-8 locale (Mike Fabian, SuSE Bugzilla #464930).
    • typo in #240 log (Slava Semushin)

    Patch #241 - 2009/1/26

    • improve checks for missing bitmap fonts, fallback to "fixed" as needed to work around broken font-packages (report by Jacek Luczak).
    • fix breakage from patch #240 changes for xtermAddInput() (patches by Jeff Chua, Julien Cristau).

    Patch #240 - 2009/1/25

    • use plink.sh for linking xterm (suggested by Larry Doolittle).
    • add resource descriptions for input method to xterm manpage.
    • update configure script; consistently append to $CFLAGS rather than prepend.
    • add install-scripts rule to makefile, to allow koi8rxterm and uxterm scripts to be altered independently of install-bin
    • add -maximized command-line option and corresponding resource (prompted by alt.os.linux newsgroup comment).
    • modify translations of scrollbar widget using xtermAddInput() (see patch #181) to accept the actions that the vt100 widget accepts, such as shift-insert to perform a paste operation (request by Martin Zwickel).
    • change default for allowTcapsOps resource to false, since it causes unexpected behavior for vim users with AltGr.
    • update config.guess, config.sub

    Patch #239 - 2009/1/8

    • correct a cast in input.c, which broke translation of numeric keypad codes to pageup, pagedown, etc., on 64-bit platform (Debian #511138, report by Larry Doolittle).

    Patch #238 - 2008/12/30

    • update configure macro CF_XOPEN_SOURCE for AIX 6.x and Mint platforms.
    • reset the screen wrapping-flag at the end of ClearRight to fix an occasional case where the last character of a scrolled and wrapped line would be cleared (patch by Joe Peterson).
    • modify to use POSIX coding for comparing resource settings such as locale, to work with locales such as Turkish (report by M Vefa Bicakci).
    • turn on configure paste64 feature by default (request by Jean-Philippe Bernardy). It is runtime enabled/disabled with allowWindowOps.
    • turn on configure tcap-query feature by default, add resource allowTcapOps to make this runtime enabled/disabled.
    • make OSC 3 (change X property, from patch #110) subject to allowWindowOps resource.
    • make VT220 DSR responses inactive in VT100-mode.
    • make DECUDK feature inactive in VT100-mode.
    • respond to incorrectly formatted DECRQSS with a cancel.
    • add allowFontOps resource to allow the fontsize-switching and font query/set control sequences to be enabled/disabled (prompted by Debian #510030).
    • some code cleanup based on gcc 4.x -Wconversion warnings in button.c and charproc.c
    • modify tcap-query feature to not return data for shifted cursor-keys when the keyboard type is set to vt220, since returning the same string for shifted/unshifted keys may confuse some applications (Gentoo #212546).

    Patch #237 - 2008/09/14

    • improve usability of TrueType fonts by making the font-size switching for shifted keypad plus/minus use the faceSize resources to determine the order of fonts (when TrueType fonts are used) rather than the bitmap fonts, since their sizes may not be in the same order (report by H Merijn Brand)
    • remove an optimization of ConfigureNotify events from patch #236 which seems to interfere with passing SIGWINCH to applications (Gentoo #233836).
    • modify handling of altSendsEscape to reset the eightBitInput mode, like metaSendsEscape (patch by Ted Phelps).
    • add feature to show the text-cursor as an underline rather than a box, plus command-line options -uc and +uc and resource cursorUnderLine to control the feature (patch by Paul Lampert).
    • update config.guess, config.sub

    Patch #236 - 2008/07/27

    • correct memory reallocation when handling a paste of UTF-8 text from patch #225 changes (report/patch by Max Mikhanosha).
    • correct allocation of temporary buffer in xtermFindShell in case the user's $PATH contains no ":" (report/analysis by Victor Stinner, Freedesktop.Org Bugzilla #16790).
    • modify CF_XOPEN_SOURCE to add case for DragonFly BSD, to fix new compile problem exposed by fix for fd_mask (patch by Hasso Tepper).
    • add configure-check for ncurses use_extended_names, (report by Martin Mokrejs).
    • correct computation for toolbar height; layout manager already takes into account borderWidth resource.
    • implement VT320-style SCS (select character set) for ISO Latin-1 supplemental.
    • fixes for vt100-style character sets in UTF-8 mode (Ubuntu #230919).
    • fix to make luit work with xterm's -ls option (report/patch by Marius Tolzmann).
    • update config.guess, config.sub

    Patch #235 - 2008/04/20

    • add control sequences for some of the recent resource/menu settings:
      • altSendsEscape (private mode 1039)
      • keepSelection (private mode 1040)
      • selectToClipboard (private mode 1041)
      • bellIsUrgent (private mode 1042)
      • popOnBell (private mode 1043)
    • add resource formatOtherKeys to provide an alternate escape sequence format for the modifyOtherKeys resource (request by Paul LeoNerd Evans).
    • adjust saved-cursor position if the window is resized while displaying the alternate screen (Novell #196880, Debian #383384).
    • improve pointer-checks to fix a bug exposed by resizing during initialization under StumpWM window manager (Fedora Bugzilla #437928).
    • modify unselectwindow() to ensure that the mouse pointer is not hidden after xterm loses focus (report by Jeremy Huddleston).
    • add special check for fd_mask on Mac OS X (report by Jeremy Huddleston).
    • add dylib to autoconf's suffix list used for checking the result from xmkmf, to work with Mac OS X (report by Jeremy Huddleston).
    • correct initialization of bold- and wide-, wide-bold fonts which may be set via the utf8Fonts subresource (Debian #347790).

    Patch #234 - 2008/03/02

    • modify sinstall.sh to use POSIX locale to bypass GNU ls changes to date-format.
    • improved/refined changes for closing bitmap font (patch by Andrea Odetti).
    • improve resize computation for situations where the negotiation fails, by invoking the xterm widget's core-class resize method (Debian #365602, patch by Jim Paris).
    • restore initialization of terminal's VMIN and VTIME settings, from patch #232 changes (patch by Matthieu Herrb).

    Patch #233 - 2008/02/24

    • add configure check for ttydefaults.h, include if needed, e.g., for systems where defining _POSIX_C_SOURCE, etc., prevents it from being included via termios.h (prompted by comments by Robert Delius Royar and Jeremy Huddleston).
    • bug-fixes for bugs.opensolaris.org (patches from Alan Coopersmith)
      4029911
      fix a typo in manpage
      4045962
      xterm doesn't properly set ut_syslen
      4192572
      left-left-right misinterpreted as triple click
    • minor optimization to tab-initialization (patch by Németh Márton).
    • fix a case where an incorrect font was freed during initialization from patch #232 changes (patch by Andrea Odetti).
    • improve comparison used in SameFont function for GC-caching (Julien Cristau).
    • correct macro name used for default CKILL definition to work with Mac OS X (report by Jeremy Huddleston).

    Patch #232 - 2008/01/30

    • corrected logic in a font-cache used for reverse-video (Debian #404079).
    • add control sequence to alter pointerMode at runtime.
    • add limit-checks for rectangle operation parameters (report by Martin Pirker).
    • modify minstall.sh to suppress $MANPAGER and $PAGER environment variables, which may interfere with redirecting output of man to a shell variable (report/patch by Zdenek Sekera).
    • do not try to hide mouse pointer in the tek4014 window, fixes broken "-t" option at startup from patch #230 changes (report by Robert K. Nelson).
    • correct datatype used when drawing tek4014 data using xterm compiled for wide-characters, on big-endian machines (reports by Jeremy Huddleston, Harald Hanche-Olsen, Martin Costabel, Merle Reinhart).
    • modify to cache the font-names along with the bitmap font data, to improve comparison of fonts.
    • modify to allow building with configure options --disable-ansi-color and --disable-leaks (Debian #459817, report/patch by Németh Márton).
    • modify to allow building with configure options --enable-wide-chars and --disable-c1-print (Debian #459816, report/patch by Németh Márton).
    • add pointerMode resource to control whether and when the pointer cursor is hidden as the user types.
    • simplify initialization of ttyMode- and related characters using a table.
    • modify initialization-logic for stty values that correspond to ltchars structure and the BSD TIOCSLTC ioctl (susp, dsusp, rprnt flush, werase, lnext). These were reset to constants for both termios and legacy interfaces immediately after asking the system for the existing values since X11R6.1, rather than using them to provide inherited values. While the legacy interface has some constraints, e.g., on HPUX, the POSIX or termios interface should not. Your shell may reset these anyway (prompted by patch by Ed Schouten).
    • improve logic for hiding/displaying pointer-cursor (report by Mark Brukhartz).
    • add limit-checks to tabs.c, increase maximum column for setting tab-stops from 320 to 1024 (report by Németh Márton).
    • correct length, i.e., number of types of selection targets, computed by ConvertSelection() when not handling wide characters for the XA_TARGETS() case. This leaves an extra Atom on the end of the list which is not handled by Java applications. The problem was introduced in patch #151 (report by David Wood).

    Patch #231 - 2008/01/05

    • undo change to getXtermCell() from patch #230 using PACK_PAIR macro (Debian #459014, analysis by Caetano Jimenez Carezzato).
    • minor documentation fixes (patch by Slava Semushin)
    • add makefile actions to install KOI8RXTerm app-defaults file (patch by Julien Cristau).

    Patch #230 - 2007/12/31

    • add quietGrab resource, which when true, suppresses cursor repainting when NotifyGrab and NotifyUngrab event types are received during change of focus (request by Nicolas George).
    • do not treat Unicode BIDI control characters as combining characters (Debian #457634).
    • add koi8rxterm, from Debian.
    • add manpage for uxterm, from Debian (Ubuntu #128136, Debian #438645)
    • remove ".xpm" suffixes from Icon filenames in desktop files since it confuses some lookups following the Icon Theme Specification (report by Slava Semushin)
    • correct width-calculation used for adjusting proportional fonts, to work with wide-characters (Debian #441354).
    • fixes/improvements for double-size characters:
      • correct old clipping calculation which used total height of glyphs where ascent was needed.
      • if bold font is unavailable, fall back to normal font
      • adjust to "work" with Xft (which does not support double-width single-height characters).
      • restore reset of doublesize for a line when it is cleared, broken in patch #228.
    • modify logic for forceBoxChars resource when using TrueType fonts to be consistent with bitmap fonts
    • modify logic for forceBoxChars resource to make the "Line-Drawing Characters" menu entry use xterm's line-drawing characters even asked to draw wide line-drawing characters which are available in the font.
    • modify rectangle-support functions to preserve colors when filling/erasing to match WRQ Reflection behavior (request by Enzo Toscano).
    • add getopt-parsing to tcapquery.pl, including feature to test the extended cursor/editing keys.
    • make missing double-width glyphs display as double-width (Debian #456236).
    • change tcap-fkeys and rectangles configure options to enable them by default.
    • hide the mouse pointer while user is typing (request by Rodolfo Borges).
    • extend configure options --enable-tcap-query and --enable-tcap-fkeys to send cursor- and editing-keypad keys modified according to the keyboard (or termcap) selection for shift, alt, control, meta.
    • modify kdch1 in termcap, e.g., xterm-r6 to match the terminfo file.
    • add -hm option to turn highlightColorMode on or off.
    • add highlightColorMode resource to separate the new (since patch #225) highlighting with both text- and background-colors (prompted by report/example by Thomas Wolff).
    • add Keep Selection menu entry to turn the keepSelection resource on/off at runtime.
    • add keepSelection resource, which when enabled, tells xterm to retain the X selection even after it stops highlighting it (patch by Sergey Vlasov).
    • extend the CSI > n sequence to allow disabling all types of modified-keys that the CSI > m sequence affects.
    • move include for <xtermcap.h> in resize.c to avoid redefinition of termios structure on OpenSolaris (report by Rahul Gopinathan Nair).
    • extend terminfo building blocks for modified editing keys to include all six keys.
    • synchronize terminfo with ncurses (report by Stephane Chazelas)
      • equate xterm-xfree86 and xterm-xf86-v44.
      • add ncurses extensions OTbs, AX, for termcap conversions.
      • make old/legacy entries such as xterm-24, xterm-65 and aliases xterms, vs100 inherit from xterm-old.
      • make xterm-r5 and xterm-r6 the same, ignoring historical errors in X Consortium's version.
    • fix an ifdef in logic for selecting regular expressions while in a narrow-character locale (Debian #449227).

    Patch #229 - 2007/8/12

    • override locale in minstall.sh; change in patch #226 does not work in UTF-8 locale (report by Zdenek Sekera).
    • undo an incorrect fix for a memory leak in patch #209 (Debian #435858).

    Patch #228 - 2007/7/22

    • modify configure script to permit combining --with-utempter and --enable-setuid, e.g., for using xterm with the utempter library on FreeBSD (report by Andriy Gapon).
    • modify "Quit" menu entry to override the -hold command-line option.
    • add a check in the startup error-reporting to avoid writing to pipe when it has not been opened. In that case, report errors directly to the standard error.
    • add OPT_READLINE definition to xtermcfg.hin, overlooked in patch #205 (report by Kalle Olavi Niemitalo).
    • modify 88colors2.pl and 256colors2.pl, adding -r option to reverse the palettes for the extended colors.
    • check for partial overwrite or deletion of multi-column characters in several cases, e.g., insert-character, delete-character, etc., and fill the remainder of the cells used by the multi-column characters affected with blanks.
    • correct character-class codes in wide-character mode for characters 215, 247 (see also patch #165).
    • fix missing assignment for UTF-8 parsing in widget initialization (Debian #403360).
    • correct index expression used to set line-wrapping flag, making selection from scrollback work consistently (Debian #430121, report by Vincent Lefèvre).
    • amend changes to handshake in patch #226 to accommodate Solaris, which relies on the extra setting of the terminal size after I/O initialization. Do this by adding new resource ptySttySize, which is false for Linux and MacOS X, i.e., true for for Solaris and other SVR4 platforms, as well as FreeBSD (reports by David Wood, Renato Botelho).
    • check for X events after cursor-left, and carriage return, consistent with indexing operations (comments by Vegard Nossum and Ingo Molnar on a mailing-list).
    • initialize the .keyboard structure, needed for some platforms (such as Solaris) after patch #227 fixes for keysyms (patch by David Wood).
    • update config.guess, config.sub

    Patch #227 - 2007/6/27

    • exclude the Intel compiler from the extra gcc warning options added in patch #226.
    • modify change for Debian #422521 from patch #226 to work with configurations where the X server does not recognize the XF86Paste or SunPaste keysyms (report by Paolo Pumilia).
    • fix incorrect free in fix for "Selection" menu entry in patch #226.

    Patch #226 - 2007/6/17

    • add configure check to use -Wno-unknown-pragmas for Solaris, and a few other new gcc warning options to address regressions in its warning options.
    • add sample desktop and icon files, along with configure options for manipulating them.
    • fix an infinite loop when showing a 2-column character in a 1-column screen (Debian #426863).
    • add XF86Paste and SunPaste to the default translations (Debian #422521, patch by Bernhard R Link).
    • update wcwidth.c (partly based on/prompted by mailing list comment).
    • update/improve keysym2ucs.c based on Unicode 5.0.1d3 and Xorg 7.1 keysymdef.h file.
    • improve gen-pc-fkeys.pl, making it show all of the building-block terminfo entries used by xterm.
    • correct strings used for modifiers applied to F1-F4 in xterm+pcf1 terminfo entry.
    • improve session management by adding the ICE connection number to the select call rather than waking up once per second (patch by Miroslav Lichvar).
    • add environment variable $XTERM_LOCALE to help with shell initialization, e.g., to set a specific locale for xterm on systems where a global locale is set in the shell startup scripts.
    • add resource settings mkSampleSize and mkSamplePass to modify the mkWidth added in patch #201. In patch #202, xterm would also check if the system's wcwidth matched its built-in tables "well enough" to be used when mkWidth was false, and if not would use the built-in tables anyway. These resources allow the user to customize the decision (prompted by comments by Emanuele Giaquinta)
    • modify logic which resets/updates the screensize on the child process side of the pseudo-terminal to do this only if a successful handshake was received, e.g., as determined by the waitForMap resource (prompted by reports by Emanuele Giaquinta and Bernhard R Link, but see also patch #177 and patch #159.
    • improve permissions logic when closing pseudo-terminal (Debian #12261, patch by Nathanael Nerode, analysis by Richard Braakman).
    • add resource highlightReverse which controls whether xterm will allow selection highlighting to hide reverse-video or use the older behavior which inverts the foreground and background colors when selected text with reverse-video attribute (report by Adam M Costello, comments by Victor Vaile).
    • restore a special case for cursor-color in ReverseVideo() lost in rewrite for patch #224 (report by Adam Sulmicki).
    • correct initialization for menu entry for bellIsUrgent (patch by Emanuele Giaquinta).
    • correct length of underlining for double-width Xft fonts (report by Shidai Liu "Leo").
    • correct clipping for double-width Xft fonts (report by Shidai Liu "Leo").
    • modify initialization for italicULMode to avoid XftPatternBuild reusing bold attributes (report by Shidai Liu "Leo").
    • add a check in case someone tries to call the popup-menu() action on a menu which is not initialized (Debian #426364).
    • improve CF_IMAKE_CFLAGS to work with Solaris sed (report by Peter Bray).
    • improve guess for X's manpage section in minstall.sh, (prompted by comment by Miroslav Lichvar).
    • modify minstall.sh to handle manpage patch with more than one dot (patch by Miroslav Lichvar).
    • fix configure message for --disable-setgid option (patch by Miroslav Lichvar).
    • add allowTitleOps resource to allow users to prevent the title- and icon-names from changing (request by John Bashinski).
    • fix "spawn-new-terminal" action, for the case where no parameter is passed to the action (patch by Daniel Colascione).
    • fix error-checking on internal font switching for "Selection" menu entry (Debian #421523).
    • amend select/paste change from patch #225 by limiting it to non-UTF-8/non-KOI8-R encoding (Debian #420974).
    • add workaround for groff ".URL" codes which are not present in some commonly-used bitmap fonts (Debian #418324).

    Patch #225 - 2007/3/24

    • add useClipping resource to allow clipping to be disabled.
    • use XftDrawSetClipRectangles to work around Xft pixel-trash (report by Reuben Thomas).
    • add configure option --enable-tcap-fkeys, and resource tcapFunctionKeys, which can be used to tell xterm to use function-key definitions from the termcap (or terminfo) which it uses to set $TERM on startup.
    • add resources altIsNotMeta and altSendsEscape to allow one to use Alt-keys like the meta-key even if they are bound to different keycodes (prompted by discussion with Daniel Jacobowitz).
    • revert a change from patch #216 that unnecessarily made the meta modifier override the eightBitInput resource if the alt- and meta-modifiers happened to overlap (report/patch by Daniel Jacobowitz).
    • correct associated font for active icon for colored text (broken in patch #224).
    • correct ifdef's for Darwin (patch by Emanuele Giaquinta).
    • add highlightTextColor resource, and options -selfg, -selbg like xwsh (adapted from patch by Victor Vaile).
    • revise find_closest_color() function to address concern about borrowing from Tcl/Tk (request by Dan McNichol).
    • add "spawn-new-terminal" action, which can be assigned to key translation, allowing one to spawn a new copy of xterm using the current process's working directory (adapted from patch by Daniel Colascione).
    • improve select/paste between UTF-8 and Latin1 xterms by adapting the translations from patch #185. Extend that to include Unicode fullwidth forms FF00-FF5E. Also modify select/paste of DEC line-drawing characters in Latin1 mode to use ASCII characters.
    • add "Enable Bell Urgency" to VT Options menu, removed "Enable Margin Bell".
    • add bellIsUrgent resource to control whether the Urgency hint is set/reset.
    • modify to set Urgency window manager hint on bell, reset it on Focus-In event (patch by Emanuele Giaquinta).
    • add --disable-setgid configure option (request by Miroslav Lichvar).
    • fix a possible infinite loop in last change to dabbrev-expand() (patch by Emanuele Giaquinta).
    • modify initialization to set the pty erase value if the erase is set in the ttyModes resource. This overrides the ptyInitialErase setting (request by Lluís Batlle i Rossell).
    • add initialFont resource to xterm widget, like tek-widget (Debian #299669).
    • amend change to boldMode from patch #223 for Debian #347790. As noted in Debian #412599, that made xterm no longer match the documented behavior. Add new resource alwaysBoldMode to allow overriding the comparison between normal/bold fonts when deciding whether to use overstriking to simulate bold fonts.
    • restore background color in ClearCurBackground(), omitted in changes for patch #223 (report by Miroslav Lichvar).
    • correct logic for repainting double-width TrueType characters (prompted by test-case for Novell #246573).
    • add a check to avoid trying to repeat a multibyte character (report by Sami Farin).
    • modify parameter to XftNameParse() to select wide face-name as needed, to make -fd option work (patch by Mike Fabian, Novell #246573).
    • correct logic for mouse highlight tracking's abort sequence, broken in a restructuring modification from patch #224 (report by Thomas Wolff).
    • revert the simplification of blinking cursor, since that broke the xor'ing introduced in patch #193 (report by Thomas Wolff).

    Patch #224 - 2007/2/11

    • simplify code for set/reset mode for blinking cursor (patch by Emanuele Giaquinta).
    • modify dabbrev-expand() to restart after the last match (patch by Emanuele Giaquinta).
    • add control sequences for enabling/disabling focus in/out event reporting (request by Bram Moolenaar).
    • improve startup performance of menus by adding resource setting menuLocale which can be set to override X's lengthy initialization of fontsets - which are seldom used for the Xaw popup menus (adapted from patch by Dave Coffin).
    • modify do_precomposition() function and make-precompose.sh to handle 21-bit codes vs the 16-bit codes those were written for, and fix a few mis-sorted codes (patch by Thomas Wolff).
    • handle special case in -cjk_width which unexpectedly caused a character's width to change when a combining character (patch by Thomas Wolff)
    • fix build for GNU/KFreeBSD (Debian #40111).
    • consolidate GC creation/updating into a single module to reduce GC manipulation (prompted by Debian #389476, though a complete fix would involve optimizing the scrolling behavior).
    • fix ifdef of xtermCellWidth(), which broke for a case without TrueType and without wide-character support (report by Martin Pirker).
    • undo a comparison in handle_translated_exposure which did not work due to X server optimization. That caused the inner border to be repainted with unexpected colors when handling a repaint, e.g., after switching to/from another workspace (Debian #401726, Redhat Bugzilla #223027).
    • allow -cr option to override cursor color when -ah option is used (Debian #406502).
    • add a note in xterm's manpage explaining that the -bw (or -w) option is only used by the window manager, if at all (Debian #405043).
    • make Selection of VT Fonts work with selectToClipboard resource.
    • correct length calculation for Selection entry of VT Fonts menu, broken since it ignored the actual selection length since X11R4.
    • fixes for fontsize changes with -fa option (Redhat Bugzilla #222340).

    Patch #223 - 2006/11/30

    • add --enable-rectangles configure option (request by Martin Pirker).
    • correct default value for --with-symlink configure option.
    • fixes configure script macros that use $X_EXTRA_LIBS.
    • modify configure script to provide support for pre-package config versions of Xft aka "FreeType".
    • add the Xaw scrollbar translations resource to the xterm manpage, add an example showing how to change the mouse button assignments (Debian #382225).
    • amend a change from patch #216, which omitted modifiers for control, meta, etc., if they were mixed with any other modifiers. The intent of the change was to avoid confusion with XK_Mode_switch and XK_ISO_Level3_Shift; the check is now done explicitly (report by Daniel Jacobowitz).
    • interpret a negative value for modifyCursorKeys or modifyFunctionKeys resources to disable the respective features (prompted by Novell #220728).
    • amend cell-width computation for FreeType from patch #217, which did not work for VT100 line-drawing characters (Debian #399638, Gentoo #147111).
    • amend a change from patch #216, which made alt-modifier on a cursor-key send a modifier parameter (Novell #220728).
    • correct an off-by-one that made DECCRA not work (report/patch by Martin Pirker).
    • revert an optimization in SGR_Foreground() and SGR_Background from patch #209 (Debian #347722, analysis by Pierre Lombard).
    • fix for boldMode (Debian #347790, patch by Tim Pope).
    • amend fix for -iconic in patch #208, which broke the positioning part of -geom with toolbar configuration.
    • fix to prevent indexing error in regular expressions (patch by Dennis Schneider).
    • fixes to make the internalBorder area not change color due to reverseVideo and/or related exposure events. The latter was a very old bug exposed in patch #196 (report by Neil Hoggarth, also Debian #397624).

    Patch #222 - 2006/10/17

    • minor optimization for recoloring cursor via dynamic colors.
    • fix a bug caused by restructuring of tek4014 widget (report by Paul Schenkeveld)

    Patch #221 - 2006/10/1

    • fix for regular expressions: the code which converted the column offset within a line did not check properly for the end of a line, and if allowed to match the whole line, would select the beginning of the following line. If the following line were empty, in turn it would select from the next, etc. (report by Sean Reifschneider).
    • minor optimization of color allocation to avoid repainting the screen if the corresponding color had not been allocated.
    • fixes for vttests/256colors.pl (report by Egmont Koblinger).
    • add terminfo building block entries for modifiers of the 6-key editing keypad.
    • fix for initialization of tek4014 which broke on QNX 6.1

    Patch #220 - 2006/9/10

    • make "xterm -t -iconic" work as expected, i.e., start in tek4014 mode, but iconified.

    Patch #219 - 2006/9/4

    • some internal restructuring to separate data for vt100 and tek4014 widgets.
    • fix a few cases where form-events would be seen by the vt100 widget when built with the toolbar configuration.

    Patch #218 - 2006/8/27

    • change behavior when encountering an illegal character in a title string. Rather than reject the string, translate illegal characters into "?" and use the string (requested by Thomas Wolff).
    • improve checks for nonprinting characters in title strings (report by Samuel Thibault).
    • correct typo in menu labels, changing print-redirect to print-redir, making it follow the manpage and match the usage for the actions table (report by Samuel Thibault).
    • correct a typo that prevents building with some older systems such as Solaris 2.6 (report by Julian Bridle).

    Patch #217 - 2006/8/20

    • minor improvements to FreeType font layout and drawing.
    • add a check in the ptyInitialErase logic to ensure that the termcap was read (Redhat Bugzilla #201246).
    • limit changes for reverse-video from patch #216 to cases where the reverse-video command-line option is used (report by Zdenek Sekera).
    • correct bitmap-derived pointsizes for TrueType fonts; they should be proportional to the square root of the area of the bitmap fonts.
    • add resources to specify pointsize of TrueType fonts (request by Reuben Thomas).
    • improve install of terminfo by filtering out harmless messages related to extended capabilities. At the same time, use ncurses tic to compile the extended capabilities if possible (report by Zdenek Sekera).
    • update "xterm+pcfkeys" terminfo entry to correspond to patch #216.

    Patch #216 - 2006/8/3

    • improve handling of ConfigureNotify events by checking if there are further events in the queue which obsolete the current one (adapted from rxvt 2.7.5). Only the normal normal (non-toolbar) configuration is addressed in this patch.
    • several changes to terminfo:
      • incorporate some minor changes from ncurses to help keep these synchronized:
        2005-02-26
        modify sgr/sgr0 in xterm-new to improve tgetent's derived "me".
        2006-02-18
        remove ncv flag from xterm-16color
        2006-06-24
        improve xterm-256color by combining the 16-color setaf/setab strings with SGR 48, and cancelling the setf/setb strings.
      • use extended function-key definitions for xterm-sun, xterm-sco entries.
      • add terminfo building-blocks corresponding to the modifyFunctionKeys and modifyCursorKeys resources.
    • ifdef'd Sun function-key feature to make it optional, like HP and SCO.
    • extend table for termcap-query feature through F63, and updated tcapquery.pl to match.
    • modify logic for function-key input processing to allow function key numbers which are constructed by control- and shift-modifiers to extend beyond X's hardcoded limit of 35.
    • add control sequence to set or reset the eightBitInput resource.
    • change default resource modifyFunctionKeys to 2 to avoid sending SS3 with parameters (report by Kalle Olavi Niemitalo).
    • add control sequences for setting and resetting the values of the modifyCursorKeys, modifyFunctionKeys and modifyOtherKeys resources.
    • add modifyFunctionKeys resource like modifyCursorKeys. Setting this to zero allows one to use the control- and shift-modifiers to construct function key strings, for terminals using many function keys, e.g., for xterm-sun or xterm-sco.
    • modify screen responses and function-key logic to reduce the number of writes made, to make it less likely that an application would read only part of a function-key in a read operation (suggested by John E Urbanczyk).
    • add combiningChars resource, which allows the user to specify the maximum number of combining characters that xterm will store for each cell in wide-character mode (prompted by request by Markus Kuhn to increase the limit from 2).
    • improve logic in metaSendsEscape in case the Alt- and Meta-keys are mapped to different modifiers. That allows one to use the Alt-key for shifting in the eightBitInput and use a Meta-key modifier to prefix the result with an <ESC>.
    • improve modifyCursorKeys logic to prevent it from modifying codes where eightBitInput or metaSendsEscape are set (request by Dan Nicolaescu).
    • improve modifyCursorKeys logic to prevent it from changing the user input when other modifiers such as AltGr are used (report by Thomas Wolff).
    • extend modifyCursorKeys to include the numeric keypad when in application mode.
    • improve -reverse (-rv) option (patch by Jason Vas Dias, Redhat #189161).
    • workaround for color resources on Fedora-5 which made the toolbar colors inconsistent.
    • corrected calls used for --disable-setuid option, add debugging traces to help diagnose this area.
    • modify configure script to ensure that USE_UTMP_SETGID is defined only if the check for POSIX saved-ids succeeds, or corresponds to one of the BSD systems known to have a workable setegid function.
    • extend configure check for POSIX saved-ids to include BSD systems
    • modify CF_SYSV configure macro to work with gcc on HPUX 10.20, whose broken <term.h> relies on including <termios.h>.
    • change order of setuid/setgid ifdef checks in Imakefile to make it simpler to produce a setgid install, allowing the latter to override the former (prompted by an XFree86 commit).
    • adapt a fix for setgid support from subsequent XFree86 changes (patch by Emanuele Giaquinta).
    • further improve setgid support (patches by Emanuele Giaquinta).

    Patch #215 - 2006/6/19 - XFree86 4.6.99.2

    • improve setgid support by exploiting the saved-ids feature on which it relies (patch by Emanuele Giaquinta).
    • make the modifyOtherKeys resource disabled by default since the intermediate setting altered some common bindings (report by Emanuele Giaquinta).

    Patch #214 - 2006/6/18 - XFree86 4.6.99.2

    • modify makefile rule for ctlseqs.txt to strip backspace/overstrikes, and add a copy of ctlseqs.txt to the source tarballs (requests by Bram Moolenaar, Emanuele Giaquinta).
    • add modifyOtherKeys resource, analogous to the modifyCursorKeys resource. This applies to keys that normally would transmit nothing when a given modifier is applied (request by Dan Nicolaescu).
    • add default to the acceptable values for the keyboardType resource, allowing the -kt command-line option to override app-defaults resource settings of sunKeyboard, etc.
    • correct ifdef's for XkbBell() which used the header file but not the corresponding function in patch #175 (report by Zach Beane).
    • add xterm manpage to the --with-symlink logic.
    • regenerated configure script to omit some debugging artifacts of the SIGWINCH test.
    • fix install-man rule in Makefile.in to avoid including the $(DESTDIR) value in substitutions made on the manpages (patch by Emanuele Giaquinta).
    • improved fix for cursor deallocation (Redhat #186935, patch by Jason Vas Dias).
    • improve checks for setuid/setgid operation to accommodate limited resource management in some kernels (Gentoo #193238).
    • update config.guess, config.sub

    Patch #213 - 2006/4/30 - XFree86 4.5.99.905

    • minor optimization to cell layout; will use that to simplify some logic and allow for more than two combining characters in another patch.
    • add utf8Latin1 resource to make optional the feature from patch #209 which allowed ISO-8859-1 fonts to be used in cases where a wide font was given. This would only work for the special case where the user normally used Latin-1 and wanted some wide characters (report by Rostislav Krasny).
    • add utf8Title resource to manpage (Novell #52655).
    • fix typo in table entry for utf8Title resource which made it treated as an integer rather than boolean (patch by Mike Fabian, Novell #52655).

    Patch #212 - 2006/4/9 - XFree86 4.5.99.904

    • improve description of forceBoxChars in manpage (discussion with Joe Wells).
    • set checkmark for "Select To Clipboard" menu entry on startup, from resource setting.
    • update manpage to note that *customization:color is not needed, though it is useful (Redhat #188034).
    • add underscore to sample pattern for URL in XTerm.ad (Redhat #188037).
    • modify install rule for manpage to use the configured app-defaults directory (Redhat #188031).
    • add checks in releaseCursorGCs() to ensure GC's are distinct, needed since memory leak changes for patch #208 (Redhat #186935, patch by Jason Vas Dias).
    • modify Imakefile definitions to allow imake to set InstallXtermSetGID. Add symbol InstGidFlags.
    • add configure script check to ensure that SIGWINCH if defined even when headers undefine this as a side-effect of _POSIX_C_SOURCE, etc.
    • resync with XFree86 CVS
      • ifdef-out chmod of terminal device for OS/2 (XFree86 #1663, Frank Giessler).
      • move new Imakefile chunk which defines $(CSGIDFLAGS) before DEFINES, e.g., for IRIX64 (Marc La France).

    Patch #211 - 2006/3/19 - XFree86 4.5.99.902

    • modify prefix/suffix transformation in makefile to make uxterm install properly on Cygwin.
    • restore the sizeof-comparison for struct lastlog added in patch #208, rendered (mostly) obsolete in patch #210, since an imake configuration can still turn that code on (prompted by comment by David Dawes).
    • remove feature for FreeBSDArchitecture from Imakefile which would install xterm using the utmp group since a standard FreeBSD system has no such group, though it would support this configuration. FreeBSD packager uses the configure script, which can make the appropriate check (prompted by comment by David Dawes).
    • fixes for gcc redefinition warnings when built using imake (reports by David Dawes, Marc La France).

    Patch #210 - 2006/3/12 - XFree86 4.5.99.902

    • add configure check for workaround in patch #208 for Solaris' inconsistent support for struct lastlog to quiet compiler warnings (prompted by David Dawes commit message for XFree86).
    • fixes for BASE64 selection manipulation, e.g., ensure that the string terminator is written after cut-buffer data (report by Joe Allen).
    • add vttests/paste64.pl script to test experimental option for setting/getting selection data.
    • add some error-checking in fontutils.c (prompted by David Dawes commit message for XFree86).
    • change xterm manpage to show the actual color resource names XtDefaultForeground and XtDefaultBackground rather than black and white (prompted by discussion with Emanuele Giaquinta).
    • add utf8Title resource and menu entry, allowing the user to control whether title strings are interpreted as ISO-8859-1 or UTF-8 encoding (Novell #52655, Novell #113206).
    • change order of ifdef's for utempter versus platforms in Imakefile to ensure a proper value for InstallXtermSetGID (prompted by Marc La France commit message for XFree86).
    • update the cursor GCs when menu entry for reverse video is toggled. (Redhat #183993).
    • a memory-leak fix for set_cursor_gcs() in patch #208 broke the -cm option (Redhat #182382).

    Patch #209 - 2006/2/12 - XFree86 4.5.99.22

    • remove setf and setb from xterm-256color terminfo entry to avoid issues with applications that ignore the ANSI strings (report by Emanuele Giaquinta).
    • remove obsolete references to "Xorg" to avoid confusion with "X.org" (prompted by David Dawes commit message for XFree86).
    • improve initial layout performance for the toolbar configuration by precalculating the height of the toolbar.
    • remove menu entry for "Enable Curses Emulation" (to make room for "Select To Clipboard").
    • add resource selectToClipboard, action set-select and a menu entry to allow users to switch between PRIMARY and CLIPBOARD for select/paste.
    • allow cursor to have the same color as foreground (text), since it is rendered as reverse (Debian #350664).
    • amend change for loading utf8Fonts resource from patch #204 to allow an ISO-8859-1 "normal" font to be combined with an ISO-10646 font if the latter is given via the -fw option or its corresponding resource value (prompted by comment in Novell #49305).
    • add TIOCSCTTY ioctl() ifdef'd for __GNU__ to set the controlling terminal (Debian #348457).
    • add configure option --disable-leaks.
    • add a check in Bell to ensure that the VT100 widget is realized, since it may be called by xtermLoadFont given an incorrect font resource (Redhat #180450).
    • improve initialization of wide-bold font by not using the derived value when it happens to have few glyphs (report by Mboso Sampson).
    • improve dynamic colors by not repainting the screen if only the cursor color changes (request by Bram Moolenaar).
    • fix menu initialization for tek4014 window broken in patch #206.
    • typo in manpage (Debian #351425).
    • correct loop logic in dotext to prevent an infinite loop if a wide character was just at the right margin when wrapping was disabled (report by Serge van den Boom).
    • initialize the saved-cursor data so a restore-cursor operation without a preceding save-cursor operation will not modify the foreground color.
    • add a new selection feature: regular expressions, and new resources which specify what happens on multiple mouse clicks: on2Clicks, on3Clicks, on4Clicks and on5Clicks.
    • revert the XTerm.ad change from patch #208 (Debian #348384).
    • fixes for the print-window to make it handle combining characters in UTF-8 mode.
    • add check to ensure that double-clicking to extend selection will not extend it into the scrollback area. This still allows users to scroll back and select text (Debian #347415).
    • add configure option --with-tty-group to help work around deficiencies in packager's build environment (Debian #349142).
    • fix typo in configure script option --disable-narrowproto (report by David Martínez Moreno).
    • amend CF_X_FREETYPE changes for pkg-config check to ensure that Xft is known to that tool (report and patch by Emanuele Giaquinta).
    • add an ifdef to allow ./configure --disable-active-icon to work, broken by new code for testing memory leaks in patch #208 (report by Brian Lindholm).

    Patch #208 - 2006/1/3 - XFree86 4.5.99.19

    • add charClass resource to XTerm.ad and UXTerm.ad which simplifies selecting URLs (prompted by Kirill Ponomarew).
    • modify install rule for uxterm to account for the --program-prefix, etc., options by invoking the transformed name of xterm rather than simply "xterm".
    • modify configure --with-app-defaults option to allow --without-app-defaults.
    • add configure --with-symlink option to make it simpler to install successive versions of xterm renamed using the --program-prefix, etc., options with a symbolic link pointing to the most recent.
    • make -iconic option work with toolbar configuration (Gentoo #113604).
    • suppress lastlog feature for 64-bit Solaris configuration since that platform provides only a 32-bit interface (report by Peter Bray).
    • fix memory reallocation for the "UTF-8" menu entry when xterm is started using the +u8 option (reported by Jan Willem Stumpel).
    • add a configure check for the actual path of luit, to work around broken imake configurations.
    • add a configure check for pkg-config (Redhat Bugzilla #173541).
    • modify install-rule for uxterm to omit executable suffix, e.g., for Cygwin.
    • modify sinstall.sh to work around quirks in Cygwin configuration.

    Patch #207 - 2005/11/13 - XFree86 4.5.99.16

    • enable lastlogx support for NetBSD (was added, but not enabled in patch #186).
    • work around broken lastlog.h in glibc 2.3.5, which includes utmp.h.
    • revert part of recent XFree86 Imakefile change, restoring the -I. needed for xmkmf builds of xterm (XFree86 Bugzilla #1633, reports by Alexander Pohoyda, Matthieu Herrb).
    • change compiled-in default for printerCommand resource to an empty string. People who want to use the printer should be able to read the manual (Debian #311490).
    • modify Imakefile to work around old problems in imake configuration to allow test-builds using xmkmf on Linux. (This was not noticed since several releases had broken definitions relating to Xft which were harder to work around).
    • link resize for SCO platforms (Kean Johnston).

    Patch #206 - 2005/11/3 - XFree86 4.5.99.15

    • add configure --with-app-defaults option to allow app-defaults directory for install-rules to be customized.
    • remove default translations for dabbrev-expand() due to conflicts with existing keyboard arrangements.
    • remove redundant check for _NET_WM_PID (report by Emanuele Giaquinta).
    • set icon border width explicitly to work around fvwm problem with active icon resizing (report by Steve Morris, analysis by Dominik Vogt).
    • modify resource files to make the font-resources a little more specific, e.g., changing "*VT100*" to "*VT100.", to make the distinction between VT100.font and VT100.utf8Fonts.font sharper, in case a packager modifies one of those.
    • expanded comments in UXTerm.ad regarding the font resources (Debian #319179).
    • add --enable-narrowproto configure option to accommodate X.org "modular" build (report by Stephan Hermann, Gentoo #17220).
    • fix typo in xterm.man description of +wf (patch by Tobias Stoeckmann).
    • add scrollBarBorder resource (request by Floyd L Davidson).
    • modify xterm-new terminfo entry to use capabilities for shifted scroll forward/reverse as shifted cursor up/down.
    • correct updating of checkmark for toolbar entry in popup menu (report by Emanuele Giaquinta).
    • fix ifdef's to allow compiling with toolbar and without tek4014 (patch by Emanuele Giaquinta).
    • use openpty() for Darwin port (patch by Emanuele Giaquinta).
    • fix Gentoo #90697 a different way, postponing the logic in SetupToolbar until the toolbar is actually needed, i.e., the +tb option is handled as expected.
    • revert fix made in patch #203 for Gentoo #90697. That introduced a problem with the control mouse click-popups, while most of the performance problems can be resolved by restricting the menu fonts (report by Emanuele Giaquinta).
    • fix a file-descriptor leak when calling openpty() (OpenBSD system/4561).
    • make a special case of resizing work like vt100: a hard reset also resets the 132/80 mode. The code to support this was present since X11R5, but not used because the corresponding initial state of the -132 option was not saved.
    • restore window manager hints after XtMakeResizeRequest() calls. One instance from patch #205 resulted in the window manager displaying pixels rather than than characters after selecting a different font size (FreeBSD ports/87424).
    • remove special case for Darwin in CF_XOPEN_SOURCE (Emanuele Giaquinta).
    • modify parsing of control sequence CSI T to allow scroll-down to be sent while mouse tracking is enabled (request by D Hugh Redelmeier).
    • correct termcap "me" (mode-end) string so it does not modify the alternate character set (report by Andrey Chernov).
    • correct size-comparison in HandleInterpret() broken in changes from patch #201 to allocate input buffer (Debian #334317).
    • amend adjustments for scrollbar layout from patch #204 to make this apply only to the toolbar configuration. In the non-toolbar configuration, the resulting scrollbar was shifted by its borderwidth (report by Matthieu Herrb).
    • add select-cursor-extend() action.
    • fix some broken href's in xterm.log.html, and typo in the INSTALL file (report/patch by David Martínez Moreno).
    • modify Imakefile to use setgid mode for installing with Linux, OpenBSD and FreeBSD.
    • add configure --with-setuid and --with-reference options to allow packagers more flexibility in customizing install permissions.
    • generalize and make optional (configure --with-utmp-setgid) the change made for XFree86 Bugzilla #878 in patch #205 (FreeBSD bug report #ports/86663).

    Patch #205 - 2005/9/18 - XFree86 4.5.99.12

    • correct a typo in CF_FUNC_TGETENT introduced in patch #198 fix for Gentoo #69926.
    • implement logic in termcap query to process multiple parameters as documented in ctlseqs.ms
    • fix buffer size used for termcap query, which was not long enough for the terminfo "colors" name (patch by Bradd W. Szonye).
    • add configure option --enable-readline-mouse, which turns on the experimental OPT_READLINE code (patch by Ilya Zakharevich).
    • for FreeBSD, drop setuid privileges after startup (XFree86 Bugzilla #878, report/patch by Alexander Pohoyda)
    • add menu entry (alt-esc) and corresponding action (alt-sends-esc) to toggle the eightBitInput resource setting.
    • generate configure script with autoconf 2.52 (patched) to use the feature therein which forces the script's locale to POSIX (Gentoo Bugzilla #105369).
    • modify computation of rows/columns on resize to avoid extending beyond the given limits, e.g., if resizing in response to a "maximize" in Gnome or KDE which do not use the window manager hints for this case (Debian #289123, Novell #61153).
    • modifications to work with z/OS 1.4 (Paul Giordano).
    • improve error-reporting when chown/chmod of the pseudo-terminal fails, e.g., if a copy of xterm which was designed to work with old-style pseudo-terminals is not installed setuid or setgid (report by Jeremy C. Reed).
    • patches from Emanuele Giaquinta:
      • ctlseqs.ms says that primary and secondary DA accept a nonzero parameter, which is incorrect. Also modify code to agree with this.
      • correct a comment in 88colres.pl
      • ctlseqs.ms says that the DEC Set/Reset control sequences for the backarrow key make it send DEL/BS, respectively, while it's the opposite.
      • update the menu entries for the metaSendsEscape, deleteIsDEL and numLock resources when changing them with the corresponding DEC Set/Reset control sequences.
    • fixes for configure script:
      • add special case for QNX, defining _QNX_SOURCE.
      • check for preprocessors which do not perform -U and -D options in the given order.
      • improve macro to determine gcc version
      • improve check for Intel compiler and related warning options
    • update config.guess, config.sub
    • improve fix from patch #198 for Cleanup() by ensuring it is not called from the SIGCHLD handler (patch by Todd Miller (OpenBSD CVS)).
    • eliminate a retry for a better-matching bold font, to work around recent font server changes.
    • fixes for Novell #113277:
      • specify weight for wide font which may be derived from normal fontname.
      • cache the derived wide- and widebolt-fontnames.
    • workaround for Gentoo Bugzilla #100728.
    • add menubar's border width to layout computation. Normally this is zero, but patterns such as XTerm*borderWidth:1 would give poor layout for the toolbar configuration.

    Patch #204 - 2005/8/4 - XFree86 4.5.99.9

    • work around quirk in shell which allowed user to "run" uxterm script when there was no UTF-8 locale installed by entering "sh -x uxterm". Also popup an xmessage to show the problem for users who run this via a GUI (Debian #318513).
    • disallow changes to fonts, toolbar and scrollbar when the vt100 window is iconified, to simplify management of the active icon.
    • fixes to make -geom option work properly with the toolbar configuration (Gentoo #90717, Gentoo #91967).
    • minor improvements to scrollbar layout: ensure that the scrollbar border is zero if the vt100 border is zero.
    • improve initialization due to utf8 resource by loading the utf8Fonts resource in the case where locale resource is false. Also in this case, do not disable switching UTF-8 mode on/off.
    • minor optimization of TrueType font-loading, loads italic font only when needed.
    • correct variable used to store temporary result from lookup of bold font, when initializing the wide-bold-font data and no immediate match is found by asking for a bold variant of the wide-font. The result was to use overstriking rather than the actual bold font (Debian #318162, patch by Eugene Konev).
    • add checks to ensure vt100 widget is realized when it might be updated via actions handled from a tek4014-only configuration.

    Patch #203 - 2005/7/6 - XFree86 4.5.99.7

    • modify initialization of allowSendEvents and allowWindowOps to prevent modification with the editres protocol.
    • fix compiler warning for NetBSD by including util.h in main.c (XFree86 Bugzilla #1596).
    • fix to build on Darwin 8.x, which no longer provides setpgrp() (patch by Min Sik Kim).
    • adapted fixes for Legend (SCO) from diffs attached to Freedesktop.Org Bugzilla #3180.
    • fix typo in xterm manpage description of -ls option (Freedesktop.Org Bugzilla #3543).
    • add support for interpreting the underline attribute as an italic font in Xft mode (patch by Chuck Blake).
    • improve initialization of toolbar so that individual pulldown menus are initialized on demand, as they are in the scenario where they are invoked as popup menus (Gentoo Bugzilla #90697).
    • fix logic in find_utmp, which did not reset result in getutid(), causing an infinite loop in some conditions (report by Emil Mikulic).
    • set the _NET_WM_PID property (Gentoo Bugzilla #91008).
    • modify ifdef's in ptyx.h and xterm_io.h to build with DragonFly (patch by Jeroen Ruigrok).
    • change default values for minBufSize and maxBufSize to 4096 and 32768 respectively so that the initial read request will match the value from before changes to use sched_yield().
    • make paste of UTF-8 faster for Western character sets by checking range of incoming data (patch by Joe Allen).
    • add experimental option to allow applications to get or set the selection data as a BASE64 string (adapted from patch by Joe Allen).
    • fix an off-by-one error parsing -S/nn option (Debian #311438, report/fix by Peter Chubb).
    • fix an initialization bug from patch #201 that broke logging (report by Rodney Thayer).
    • amend change to command-line processing in patch #201 to avoid conflict with -e option (report by Servatius Brandt).
    • suppress configure check for _XOPEN_SOURCE on darwin.
    • update config.guess, config.sub

    Patch #202 - 2005/5/2 - XFree86 4.5.99.3

    • add extended shift- and control-modifier cursor keys to "xterm+pcfkeys" terminfo entry to correspond to ncurses 20050430 patch.
    • fix a rare case where text would be written with the wrong colors because output of scrolled text would reset the colors and the new text would be written with the same colors (report/testcase by Thomas Glanzmann).
    • rename $CMD variable in plink.sh because it is a reserved symbol in bash 3.00.16 (report by Ted Taylor).
    • add environment variables $XTERM_SHELL and $XTERM_VERSION (request by Zdenek Sekera).
    • corrected workaround for background color of menubar, which gave a too-broad expression, coloring the background of the VT100 widget unless overridden by another resource setting.
    • correct an error in the logic which decides when sched_yield() is run; it would occasionally hang when contending with other pseudo-terminal applications such as screen (report by Kirill Ponomarew).
    • modify initialization to decide whether to default to built-in wcwidth() versus system's version based on the starting locale and whether the system's version is poor quality (suggested by Bram Moolenaar).
    • update table for mk_width() from UnicodeData 4.1.0 using Markus Kuhn's uniset script.

    Patch #201 - 2005/4/21 - XFree86 4.5.99.2

    • improve resource files to show how the menubar and popup menus can be colored (prompted by report by Joe Wells).
    • modify parsing of OSC (and SOS, etc), strings so their contents are not interpreted as UTF-8. This allows non-ASCII title strings to be set, provided that the window manager complies (report by Thomas Wolff).
    • improved some of the built-in line-drawing glyphs.
    • correct color of "box" character drawn for line-drawing glyph 1 (report by Nicolas George).
    • improve behavior when switching to UTF-8 mode after startup so xterm will check if the current fonts are already wide (ISO10646-1). If they are not, xterm will use the utf8Fonts subresource to load appropriate fonts (request by Bram Moolenaar).
    • modify logic for setting title-string so it applies to the current widget rather than the vt100 widget.
    • modify initialization for wide-bold fontname, to search for one if none is given (report by Michael Schroeder).
    • add resource mkWidth and command-line option -mk_width to control whether xterm uses the built-in version of wcwidth().
    • add resource settings for minimum/maximum input buffer size, and call to sched_yield to improve performance with newer Linux kernels (adapted from patch by Nicolas George).
    • correct computation of width for wide characters with the invisible attribute (report by Thomas Wolff).
    • modify interaction between +u8 and locale resource to allow the command-line option to override the resource (requested by Thomas Wolff).
    • add a limit check for scrolling margins in a one-line screen, overlooked in fixes for patch #198 (Debian #297430).
    • correct treatment of iconBorderWidth for resizing an active-icon, and its description in manpage (Debian #296592).
    • modify configure script --disable-imake to use the script's definitions anyway if it cannot detect imake (prompted by FreeBSD bug 77408).
    • ignore error in the I/O initialization that tries to set the tty to 7-bit input for the case where eightBitInput resource is false (Debian #298551).
    • modify command-processing to accept an optional parameter that tells xterm which shell program to use (request by Zdenek Sekera).
    • add simpler resource keyboardType which, when set, overrides the individual keyboard-type resources and eliminates the possibility of conflict between them.
    • add initialization for scoFunctionKeys resource (report by Rick K).
    • correct logic of ReallocateBufOffsets() which did not copy the content of the old screen buffer to the proper location, making a repaint clear after switching to wide-character mode (report by Bram Moolenaar):
    • implement the remaining pieces to make xterm allocate cells for wide-characters when the "UTF-8" menu entry is selected. Also, load the UTF-8 font when that menu entry is selected, or the escape sequence for UTF-8 mode is received (report by Bram Moolenaar):
    • add command-line options (-tb, +tb) and resource toolBar to allow menu/toolbar to disabled or enabled at startup (prompted by reports by Joe Wells).
    • correct typo in configure script's --enable-dec-locator option (report by Bram Moolenaar).

    Patch #200 - 2005/2/6 - XFree86 4.4.99.23

    • increase color pairs value for xterm-256color and xterm-88color to match ncurses, which has an experimental option to support this.
    • modify ifdef's to make AIX use termios rather than termio; the struct sizes for the two were not the same.
    • improve CF_WITH_IMAKE_CFLAGS configure macro script for OSMAJORVERSION and OSMINORVERSION values, e.g., for Tru64 and AIX.
    • modify ifdef to define USE_POSIX_TERMIOS for Darwin (patch by Min Sik Kim).
    • modify find_utmp() to initialize the whole utmpx struct (except ut_id), since that is needed for OSF1 4.0D to prevent an infinite loop on exit.
    • add configure check before adding -D_POSIX_SOURCE since some platforms predefine it, e.g., cygwin.
    • add simplified sed expressions in CF_IMAKE_CFLAGS configure script macro to ensure value for PROJECTROOT is quoted on Solaris, i.e., when nested \( and \) are not interpreted correctly.
    • correct DEC rectangle operations to reset state after completing the operations.
    • modify CASE_ST handling in charproc.c to ensure that the parse state is reset even if xterm is not currently processing an OSC or other string (patch by Johnny Billquist forwarded by Matthias Scheler, NetBSD xsrc/29003).
    • fix OS/2 build for innotek_libc (patch by David Yeo).
    • fix a regression from patch #197 fix for Debian #277832 which disowned the selection if it was scrolled, e.g., by the user pressing return at the bottom of the screen (Debian #291787).
    • move the warning/exit for missing $DISPLAY into the error handler in case -display is given, and the connect fails for some other reason.

    Patch #199 - 2005/1/17 - XFree86 4.4.99.22

    • instead of setting $DISPLAY, check for the unset variable and warn/exit on this condition (comments by H Merijn Brand and Bernhard R Link).
    • fix a typo in Imakefile from patch #198 (reports/patches by Stefan Dirsch, Mike Castle).

    Patch #198 - 2005/1/13 - XFree86 4.4.99.21

    • set $DISPLAY to ":0" if it is not set.
    • add utmpDisplayId resource to allow users to control whether the display identifier (display number and screen number) are retained in the connection information recorded in utmp (discussion with Edoardo Tirtarahardja).
    • add bellOnReset resource to allow users to disable bell which sounds on hard reset since patch #183 changes to DECSCL (discussion with Danek Duvall).
    • improve $WINDOWID for configuration with toolbar by making it refer to the top-level shell rather than the parent of the current window. For that case, the parent is a form widget, which does not have a name, which made the $WINDOWID not very useful as a parameter for xwininfo (suggested by Dave Bodenstab).
    • fix a typo in WhichVFont() macro from patch #197 changes which broke the --disable-active-icon configuration (report by Ralf S. Engelschall).
    • improve some limit checks (Gentoo Bugzilla #75604).
    • add --disable-setuid option to configure script (Gentoo Bugzilla #76543).
    • add --disable-full-tgetent option to configure script, allowing one to ignore a termcap library in favor of ncurses/curses (Gentoo Bugzilla #69926).
    • modify configure script to choose useful warning options for Intel version 8.0 compiler.
    • update config.guess, config.sub
    • make active-icon work properly when TrueType fonts are used (Debian #286068).
    • correct change from patch #157 which uses getlogin() to check for an alias; the storage used for the related getpwuid() call was overwritten by the data used for comparison (patch by Per Hedeland).
    • correct case of SCS for character set 0 (line-drawing) to allow it to be selected into GR.
    • fix a file-descriptor leak (Redhat Bugzilla #139597).
    • modify creat_as() to only fork if xterm is actually running as setuid and/or setgid. This works around a Cygwin bug which hangs when logging is enabled and makes xterm a little faster for systems using interfaces such as utempter (report by Al Goodman).
    • modify Cleanup() to avoid operations such as X calls that might use unsafe functions when it is called by a signal handler (report by Michiel Boland).
    • fix bugs in patch #191 and in SRM changes from patch #197 that broke DECSET 38: switch to Tek4014 emulation (report by Dave Bodenstab).
    • fix for manpage escapes (Marc La France).
    • improve on IRIX-specific change for Imakefile in XFree86 CVS versus resize linking against termcap library to reflect definitions for USE_TERMCAP in resize.c

    Patch #197 - 2004/11/30 - XFree86 4.4.99.19

    • modify configure script to remove empty "-DPROJECTROOT=" definition which resulted unusable values for luit's default path.
    • update precompose.c based on Unicode 4.0.1
    • several minor fixes based on Intel compiler warnings.
    • change default translations so a BtnDown which is not recognized is simply ignored rather than emitting a bell. That makes it less obtrusive when the user tries to use a mouse which provides more capabilities than the X mouse driver supports, e.g., one with a horizontal scroll wheel (Debian #265133).
    • note in xterm's manpage that translations is not specific to xterm (Debian #278897).
    • modify uxterm script to use locale program to verify if the derived locale is installed (Debian #246398).
    • correct font handling for active icon when in UTF-8 mode (report by Paolo Liberatore).
    • make active-icon and toolbar configurations work together.
    • modify the criteria for disowning primary selection. Previously, this happened anytime the cursor was moved before the end of the selection. That would ensure that any insert/delete of char or line, as well as scrolling, would disown the selection. The new criteria change this to checking if the operations would modify the data which is highlighted (Debian #277832).
    • reimplement DECALN with functions for vt420 rectangles, fixes selection for this case.
    • implement vt420 rectangle operations.
    • add parsing, for debug/test of vt220 soft-fonts.
    • add menu entry, actions and escape sequence to allow enabling/disabling toolbars at runtime.
    • improve rendering for Xft, allow it to draw non-linedrawing characters such as "pi", which were drawn from internal tables with patch #180 (Freedesktop.org Bugzilla #1260).
    • add configure option --enable-mini-luit, ifdef'd the mini-luit feature with OPT_MINI_LUIT.
    • add mini-luit feature, which supports Latin9 directly rather than via luit, provided that Unicode fonts are used (Freedesktop.org Bugzilla #1571, request by Stefan Dirsch, patch by Michael Schroeder).
    • for Linux, if IUTF8 is defined, e.g., on recent 2.6.x kernels, set the corresponding flag for the slave pty, to enable UTF-8 interpretation of backspace in cooked mode (Freedesktop.org Bugzilla #1578, request by Stefan Dirsch).
    • modify faceSize resource to use a floating-point internal value (adapted from patch by Sam Stephenson).
    • correct handling selection of tabs over cleared space in UTF-8 mode. In this special case, xterm represents the whitespace with a null rather than a space character (Debian #276447).
    • amend fix for infinite loop from patch #192 to check if there is wrapped text to output in a following iteration (Debian #273202).
    • fixes ifdef'd with __INTERIX to allow building with Interix (Windows Services for UNIX) 3.5 using the xlibs libraries from freedesktop.org (patch by Min Sik Kim).
    • amend solution for Debian #252873, Debian #260471 from patch #194 by making the cursor not explicitly colored if only the foreground color is set, and the cursor is on a blank space (Debian #275473).
    • correct logic for send/receive mode (SRM) with regard to control characters.
    • fix masking of invisible text in wide-character mode, which did not work for line-drawing characters.
    • incorporate CF_XOPEN_SOURCE into configure script, replacing CF_GNU_SOURCE.

    Patch #196 - 2004/8/15 - XFree86 4.4.99.12

    • add a special case to configure script to ignore NetBSD's grantpt() which was recently added (but not part of a release), until someone is able to ensure that xterm can use it (report by Min Sik Kim).
    • clear the buffer returned by getutid(). This fixes an infinite loop on some platforms introduced in patch #193 by Debian #256468 fix (report by David Ellement).

    Patch #195 - 2004/8/8 - XFree86 4.4.99.11

    • correct length used for blinking text, make the last column blink (patch by Alexander V Lukyanov).
    • start changes to make doublesize characters work with TrueType fonts (see patch #44).
    • trim leading/trailing blanks from color resources as done for other strings in patch #167.
    • fixes for showBlinkAsBold resource (report by Christoph Berg).

    Patch #194 - 2004/7/27 - XFree86 4.4.99.11

    • change clearing operations so foreground color attribute is not set. Usually this is benign, but in some cases when the cursor color is not set explicitly, the cursor would show this color (Debian #252873, Debian #260471).
    • add extra state (cursor-moved) to guard against deciding that the cursor did not require repainting after an indexing operation that leaves the cursor in the same location on the screen.
    • fix a case where a full-screen indexing operation would not restore the cursor-busy state.
    • fix a repainting bug introduced in patch #180: when using a font lacking line-drawing characters, a repaint of the screen could skip horizontally an extra amount after filling in the missing character (reports by Nicolas George, Hans de Goede, Redhat Bugzilla #128341).
    • rename terminfo fragment "xterm-pc-fkeys" to "xterm+pcfkeys" for consistency with ncurses.

    Patch #193 - 2004/7/19 - XFree86 4.4.99.10

    • fix for wide-character selection from OpenBSD CVS (report/patch by Matthieu Herrb).
    • modify initialization and cleanup of utmp data to also compare the ut_line member (Debian #256468).
    • modify check on focus-change to ignore FocusOut events generated by XGrabKeyboard. This fixes a case where the text cursor would act as if focus were lost when selecting the "Secure Keyboard" menu option.
    • add gen-pc-fkeys.pl script, use that to generate terminfo fragment corresponding to the pc-style function keys.
    • fix a case where the checkmark by the "VT220 Keyboard" menu entry was not set on startup.
    • separated two methods for making the cursor blink (menu and escape sequence) by using the menu as the primary method and XOR'ing the state of the escape sequence against that.
    • modify logic for enabling blinking cursor via escape sequence as well as the related save/restore operations so this is only available if the cursorBlink resource was set on startup.

    Patch #192 - 2004/7/12 - XFree86 4.4.99.9

    • change resource settings for color4 and color12, add some discussion in XTerm-col.ad (Debian #241717).
    • add a note in xterm manpage discussing the difference between alt- and meta-keys, and the way the latter is used in the eightBitInput resource.
    • add a note in xterm manpage regarding possible conflict between resource settings for xterm.vt100.font and xterm.vt100.utf8Fonts.font (Debian #254650).
    • add compile-time customization of backarrowKeyIsErase and ptyInitialErase default resource values (adapted from OpenBSD CVS).
    • change parameter of FIONREAD ioctl() call from long to int (discussion on tech-x11@netbsd.org regarding LP64 by John Heasley and Matthias Scheler).
    • modify configure script options for Athena widgets to work as expected for "--without-Xaw3d", etc., (Gentoo Bugzilla #53455).
    • add case to uxterm to accommodate locales ending with "@euro", e.g., fr_FR.UTF-8@euro (Debian #255197, report/analysis by Matthieu Lagouge).
    • add special case for VT100 graphic's "box" character (discussion with Ben Armstrong).
    • add missing initialization for bitmap-font sizes needed to make fonts menu work with TrueType fonts (report by Ben Armstrong).
    • save the fontnames for bold fonts that are derived from normal fonts, or from the boldFont resource, so the same value is restored when switching with the VT Fonts menu (Debian #256086).
    • fix manpage preprocessing (Marc La France).
    • fix typo in manpage's description of character classes (Debian #257073).
    • modify terminfo to accommodate luit, which relies on G1 being used via an ISO-2022 escape sequence (Debian #254316, analysis by Juliusz Chroboczek).
    • modify Makefile.in rule for ctlseqs.txt to work around groff SGR misfeature.
    • modify XTerm.ad to set saveLines default to 1024 (Redhat Bugzilla #127132).
    • add a limit-check in dotext() to prevent infinite loop in a corner case of UTF-8 configuration.
    • update config.guess, config.sub

    Patch #191 - 2004/6/6 - XFree86 4.4.99.7

    • correct options parsing for -into option so it can be combined with -e (Redhat Bugzilla #124518, report/patch by James Armstrong).
    • fix ifdef's for OPT_COLOR_RES2 so that the fake resource table introduced in patch #188 is not compiled if it is empty. This happened to work with gcc (report by Joel Konkle-Parker).
    • reorganize ptydata.c to use one input buffer shared between the VTxxx and tek4014 emulators. In the new scheme, UTF-8 decoding is performed on characters as they are needed by the state machine rather than on buffers as they are read.
    • work around change in quoting of PROJECTROOT symbol when using configure script, from changes made in patch #187 for CF_IMAKE_CFLAGS (Gentoo Bugzilla #50982).

    Patch #190 - 2004/5/25 - XFree86 4.4.99.6

    • correct state for values in the range 128-159 after translating from UTF-8: this should be ignored unless the user overrides it with the allowC1Printable resource (reported by Simon Strandgaard).
    • add configure-script check for nl_langinfo(CODESET), use this to replace check of environment variables for UTF-8.
    • change Makefile.in rules for 256colres.h and 88colres.h so they are only made if they do not exist. The maintainer-clean rule will remove these files; they require perl to be made.
    • remove check in configure script --enable-toolbar that suppressed this option when building with Xaw7.
    • apply fixes to Tektronix widget used for VT100 widget to make toolbar work with Xaw7 (XFree86 4.x).

    Patch #189 - 2004/5/16 - XFree86 4.4.99.6

    • do not call xim_real_init() if openIm resource is false (Debian #249025).
    • minor improvements to built-in line-drawing.
    • fix a few portability issues with dynamic abbreviation support, i.e., did not compile on Tru64.
    • modify constraints in form used to layout toolbar, to work with newer Xaw in XFree86 4.x.

    Patch #188 - 2004/5/12 - XFree86 4.4.99.6

    • correct table entry for DEL in the ground state, which marked it as a printable character from patch #171 (report by D Hugh Redelmeier).
    • improve fix in patch #186 for failure in xim_real_init() by adding a sleep.
    • fix a typo in os2main.c (XFree86 Bugzilla #1358, report/patch by Frank Giessler).
    • make escape sequence reporting dynamic colors consistent with the logic that sets it; choosing the opposite color when reverse video is set (XFree86 Bugzilla #1361, reported by Bradd W Szonye).
    • modify initialization of 256- and 88-colors so that colors beyond 16 are normally not X resources. This works around a hard-coded limit in Xt which breaks xterm when 256-colors and luit are both configured (report by Noah Friedman).
    • remove ncv from xterm-256color terminfo entry since it is no longer needed (report by Eli Zaretskii).
    • add "erase2" and "eol2" keywords to ttyModes resource, for recent/current FreeBSD.
    • improve ifdef's for utempter library to omit direct calls to setutent() or getutent() (adapted from patch by Christian Biere).
    • add dynamic abbreviation support like Emacs (patch by Tomasz Cholewo). This is ifdef'd with OPT_DABBREV, and enabled via the configure script --enable-dabbrev option.
    • fix problem responding to session management events, e.g., which would make logging out very slow (patch by Eddy De Greef, Debian #233883).
    • work around a newer bug in toolbar with XFree86 by forcing menus to be fully initialized at startup. In older versions of XFree86 and X11R6, it was possible to delay initialization of the menu contents until it was popped up. (The longstanding bug with XFree86 4.x layout for toolbar still exists, though).
    • modify xtermAddInput to work around core dump on IRIX64 when initializing scrollbar translations if toolbar is compiled-in.
    • fix some minor conflicts in the 2-character entry names in the termcap file.

    Patch #187 - 2004/4/27 - XFree86 4.4.99.4

    • change xterm version string to use __vendorversion__ where that is available, and "XTerm" otherwise.
    • improve description of utf8 resource in manpage (Debian #179407).
    • modify configure macros CF_IMAKE_CFLAGS and CF_ADD_CFLAGS to handle -D options that define string values, e.g., for XVENDORNAME.
    • modify configure macro CF_IMAKE_CFLAGS to allow (if $PATH is set accordingly) to use the xmkmf script within an X build tree.
    • add missing #undef OPT_SESSION_MGT to xtermcfg.hin to make the configure script's --disable-session-mgt option work.
    • update config.guess, config.sub

    Patch #186 - 2004/4/18 - XFree86 4.4.99.4

    • change reset on DECSCL to a soft-reset (appears some DEC manuals have errors).
    • add a section to ctlseqs.ms elaborating on normal/alternate screens.
    • modify initialization of Acolors[] so that any XtDefaultForeground or XtDefaultBackground values are translated as in the Tcolors[], to use the window's foreground/background colors. This affects the colorBD and similar resources which normally have no explicit color assigned.
    • modify initialization of Tektronix window so that control sequences setting its color before the window is popped up will apply to its initial colors.
    • add control sequence to set Tektronix window's text-cursor.
    • modify initialization of terminal colors, e.g., mouse pointer and text cursor, to treat XtDefaultForeground and XtDefaultBackground values as the actual foreground and background colors of the terminal rather than white and black (Debian #241717).
    • remove an incorrect comparison against PTYCHARLEN in parsing the -S option (report by Michael B Taylor).
    • minor restructuring of terminfo/termcap files, having noted some packager's customizations which caused the structure to be confused.
    • eliminate an isolated use of MIN/MAX in charproc.c
    • replace XtExtdefaultfont and XtExtdefaultbackground by their more familiar equivalents XtDefaultFont and XtDefaultBackground.
    • replace ifdef's using SCO, sco and SCO325 with __SCO__ (XFree86 Bugzilla #1301, Kean Johnston). But ensure that it still builds on platforms where this symbol is not defined.
    • add scoFunctionKeys resource, to match manpage.
    • update manpage discussion of menus and related resources.
    • enable utmpx support for NetBSD 1.6C and newer (patch by Matthias Scheler).
    • add a note in the manpage discussing xterm's treatment of open file-descriptors (request by Dan Shearer).
    • modify Help() to make "xterm -h" write to standard output rather than standard error (patch by Bram Moolenaar).
    • check for type of failure in xim_real_init() to avoid looping when the problem is an unsupported input method rather than a failure to connect to the XIM server. Problem was introduced in patch #175 (XFree86 Bugzilla #1306).
    • modify Imakefile to remove dependency of "install" target on the xterm executable to make installs from tree without attempting to rebuild anything (commit by David Dawes, report/patch from Lee Olsen).
    • remove call to ShowCursor from SetCursorBlink() since that is redundant, and can cause display glitches if the cursor is already blinking (XFree86 Bugzilla #1158, patch/report by Andreas Schwab).

    Patch #185 - 2004/3/3 - XFree86 4.4

    • fix tcap-query logic for the backspace key (XFree86 Bugzilla #1233, report/patch by Anton Kovalenko).
    • add test-scripts resize.pl and tcapquery.pl
    • add translation to ASCII of commonly-used characters that groff translates to Unicode, when the font in use does not provide the corresponding glyphs (Debian #219551).
    • modify RequestMaximize(), which performs maximize/restore via control sequences, to account for window-frame (patch by Jess Thrysoee).
    • improve pattern used in uxterm to check for UTF-8 locale, e.g., for HPUX (patch by H Merijn Brand).
    • add -fd option and resource faceNameDoublesize to specify double-wide fonts with Xft (adapted from patch by Zarick Lau).
    • change a couple of resource classes from "Boolean" to specific values: freeBoldBox, forceBoxChars.
    • add resource showMissingGlyphs to outline places on the screen where a font lacks the corresponding glyph.
    • add resource showBlinkAsBold to control whether blinking text should be shown as bold or actual blinking text.
    • improve logic in ShowCursor() to avoid repainting the cursor when it is already visible, e.g., in response to the DECTCEM escape sequence. This also addresses XFree86 Bugzilla #1158.
    • implement blinking text, using the timer for blinking cursor.
    • modify FreeType support to allow resizing the font, in the same ways the window can be resized if fixed fonts are used. The relative font sizes are derived from the fixed font sizes.
    • add menu items and corresponding actions for switching on/off the UTF-8 mode and Xft (TrueType) support.
    • add logic to handle switching UTF-8 mode on/off. It worked if the escape sequences were flushed, but if data was mixed in with the same write, some were not handled properly (report by Nicolas George).
    • modify to allow turning UTF-8 mode on/off via escape sequence even if -wc option was not given at startup (patch by Peter Berg Larsen).
    • amend fix for XFree86 Bugzilla #981, adjusting for savedlines value (report by Tim Adye).
    • fix a typo in computing relative font size (Jess Thrysoee).

    Patch #184 - 2003/12/31 - XFree86 4.3.99.903

    • improve configure-script checks for FreeType and related libraries, using xft-config or freetype-config scripts when available.
    • fix configure-script check for SYSV definition by ensuring whether sys_errlist[] is declared, and by modifying the test program to include X11/Intrinsic.h to check that wchar_t is declared consistently (report by H Merijn Brand).

    Patch #183 - 2003/12/26 - XFree86 4.3.99.903

    • correct logic for configurations that may attempt to open both old/new-style pseudoterminals. In this case, the old-style are preferred. Logic was broken in patch #145 (XFree86 Bugzilla #997, report/patch by Kean Johnston).
    • modify handling of eightBitInput resource in UTF-8 mode to translate the value into UTF-8. Otherwise an illegal UTF-8 code is sent to the application (report by Bram Moolenaar).
    • modify uxterm script to interpret help and version options so xterm does not always create a window when the user requests this information (Debian #223926).
    • add a limit check to ScrnTstWrapped() (XFree86 Bugzilla #981).
    • modify DECSCL to perform a hard reset (RIS) as per DEC manuals. Extended DECSCL to accept parameters for vt4XX and vt5xx terminals.
    • correct logic for ANSI conformance level escape sequences, which were confused with DEC conformance level escape sequences.
    • correct state for vt52 shift-in/shift-out, which was not reset properly after patch #171.
    • correct handling of graphics characters for vt52 mode, which did not display line-drawing characters after G1 fix from patch #182.
    • fixes for configure script to work with current Cygwin headers and libraries.
    • modify Imakefile to put the current directory at the beginning of the include searchpath (patch by David Dawes).

    Patch #182 - 2003/12/2 - XFree86 4.3.99.901

    • correct logic for metaSendsEscape resource to allow for the meta-right key to be tested. Improve check for meta/alt modifiers by dropping the assumption that a keysym is associated with only one modifier, and by ignoring NoSymbol entries in the xmodmap data (XFree86 Bugzilla #924, patch by David Dawes).
    • correct wrapping logic for line-drawing characters written in non-UTF-8 mode of xterm build for wide-characters (XFree86 Bugzilla #918, report/patch by Jürgen Keil).
    • improve manpage description of resources, in particular the utf8Fonts class (XFree86 Bugzilla #905).
    • add definitions to compile with glibc-based GNU/Hurd, GNU/KFreeBSD and GNU/KNetBSD (XFree86 Bugzilla #893).
    • compiler-warning fixes (patch by Christian Biere).
    • add README.i18n (Tomohiro Kubota).
    • correct initialization of G1 character set mapping, which used line-drawing set as a result of confusion between "DEC Supplemental Graphic" and "DEC Special Graphic" character sets (see patch #34 regarding DECSTR).
    • correct ifdef in main.c for variable utret (patch by Bernhard Rosenkraenzer).
    • document in xterm's manpage how to use XFree86 ":unscaled" keyword to suppress scaling of bold fonts.
    • when deriving bold fontname from normal fontname, use the normal font's average width to avoid for example selecting 7x13bold from an 8x13 normal font (Debian #107769).

    Patch #181 - 2003/10/26 - XFree86 4.3.99.15

    • implement boldMode for wide-character logic in drawXtermText() (report by Michael Schroeder).
    • modify UXTerm.ad resource file to include "XTerm-color" rather than "XTerm", in case the latter file contains no color resource definitions, e.g., after patch #180.
    • add action load-vt-fonts() and configure option --enable-load-vt-fonts which allows users to define additional sets of VT-fonts which can be loaded at runtime.
    • add logic to wide-character support which attempts to load fonts specified by utf8Fonts subresources at startup. The subresources have the same names as the fonts which they replace, e.g., font, font1, etc., so that the ISO-10646-1 fonts can be specified in the XTerm app-defaults file (adapted from patch by Tomohiro Kubota).
    • improve Set Font escape string handling by making the relative settings apply to the size of the font, as in shift keypad plus/minus rather than the menu index.
    • simplify parameter passing for the set-vt-font action and related code.
    • cleanup some include-ordering, moving some recently-added hardcoded stuff into xterm.h where it will not interfere with the configure script.
    • modify xtermAddInput() (see note on augmentation in patch #158) to use the complete set of default keyboard translations so that one can use shifted pageup, wheel mouse, etc., while the mouse pointer is over the scrollbar. (Debian #178812).
    • make save/restore mode controls apply to show/blink cursor states.
    • add escape sequence to start/stop blinking cursor, which allows implementing cvvis terminfo capability (request by Nate Bargmann).
    • add indp and rin to terminfo entry.
    • fix an out-of-bounds array reference in ScrnRefresh() for wide characters (report by Dan Harnett, patch by Todd Miller). This bug dates from patch #141.

    Patch #180 - 2003/10/12 - XFree86 4.3.99.15

    • several fixes for rendering using Xft via option -fa:
      • translate Unicode values, i.e,. from UTF-8 output to xterm, for line-drawing to xterm's internal code, etc., since TrueType fonts generally do not have either set of line-drawing glyphs. xterm can draw these directly (report by Abigail Brady).
      • pass 16-bit values rather than 8-bit values to xtermXftDrawString() to allow for wide-characters.
      • remove spurious check for colorBDMode resource in logic that does bold fonts.
      • implement underlining.
    • patches by Ilya Zakharevich:
      • improve drawXtermText() by making the recursive calls communicate through arguments, and not through saving/restoring global variables.
      • make double-width characters work with -u8 option.
      • modify lookup of double-sized fonts by checking for a match ignoring x/y resolution if the first check fails.
    • make height of TrueType fonts match ascent+descent (patch by Keith Packard).
    • correct configure-script check for imake $CFLAGS, which did not check properly if imake was not available.
    • correct install rule in Makefile.in for uxterm, which was attempting to strip the script (newsgroup posting by Fernan Aguero).
    • correct AF/AB strings in termcap for xterm-256color and xterm-88color entries (report by Josh Howard).
    • update wcwidth.c to incorporate changes from Markus Kuhn's 2003-05-20 (Unicode 4.0) version of that file.
    • modify scroll-back and scroll-forw actions to accept an adjustment value, e.g.,
                    scroll-back(1, page-2)
      
      to scroll back by 2 lines less than a page (patch by Greg Klanderman).
    • use color resource setting from Debian package for xterm VT100 widget, since the choice of blues provides better contrast.
    • remove color resources from XTerm.ad, leaving them only in XTerm-col.ad (prompted by Debian package for xterm).
    • correct configure script option --enable-pty-handshake (report by Paul Gilmartin).
    • add visualBellDelay resource to modify the length of time used for visual bell, for very slow displays or very fast computers (reports by Ingo van Lil and Doug Toppin).
    • correct logic for initializing dynamic highlight color (patch by Jess Thrysoee).
    • add a check for non-zero size in call to XCopyArea() to accommodate a Solaris bug.
    • correct typo in example for character classes in xterm manpage (Debian #198910).
    • link xterm with bind_on_load option on Darwin to work around a deadlock in the dynamic loader when a signal is received while the dynamic loader is looking up symbols (patches by Rob Braun, Torrey Lyons).
    • modify configure script to avoid using "head -1".
    • update config.guess, config.sub
    • modify ifdef's to work around inclusion of types FcChar32 and XftCharSpec with FreeType 2.0 (see patch #175).
    • modify the predictable version of the generated logfile name (see patch #171) to append the process-id rather than a random value.
    • resync with XFree86 CVS
      • Enable SCO function keys in xterm
      • Make Delete key send DEL by default on SCO in xterm

    Patch #179 - 2003/5/21 - XFree86 4.3.99.5

    • modify ifdef's for WTMPX_FILE to allow building on cygwin again.
    • change the default of pty-handshaking configure option (and related default for imake) to assume this feature is needed.
    • add ifdef's so configure option for XawPlus library works (patch by Pavel Roskin).
    • add $(MAIN_DEFINES) to the variables checked by the configure script that may contain information set by imake. This allows xterm to build/run properly using the configure script on IRIX64.
    • add configure check for ".exe" suffix on cygwin.

    Patch #178 - 2003/5/18 - XFree86 4.3.99.5

    • modify default for configure --enable-pty-handshake option to enable it for Solaris (report by Nelson Beebe).
    • modify in_put() function to call PreeditPosition() only when the cursor's position has changed. This addresses report by Stefan Baums of high CPU usage while xterm with chinput are running in the background (patch by Yong Li).
    • improved explanation of -ls conflict with -e option in xterm manpage (adapted from comments by Henning Makholm).
    • correct comment in terminfo file regarding modifier used for kDC (Debian #189764, report by Henning Makholm).
    • correct/extend some of the keypad description in ctlseqs.ms (report by Henning Makholm).
    • correct keypad-mapping table in input.c so XK_KP_Equal works (report by Henning Makholm).
    • modified to work with CJK double-width (bi-width/monospace) fonts. They're similar to Roman Czbora and David Starner's gnuunifonts in that Latin letters and numbers have all the same width which is exactly the half of the width of East Asian characters. (patch by Jungshik Shin <jshin@mailaps.org>).
    • add configure option --enable-broken-osc and resource brokenLinuxOSC to accommodate scripts which do not distinguish between running in the Linux console and running in X. Linux console recognizes malformed control strings which start with an OSC, but are fixed-length, with no terminator.
    • add configure option --enable-broken-st and resource brokenStringTerm to allow user to revert one part of the parsing table corrections from patch #171. (reports by Matthias Scheler and Kirill Ponomarew indicate that someone's network firmware sends an <escape>X).
    • modify configure --disable-imake to provide values for OSMAJORVERSION, OSMINORVERSION, FUNCPROTO and NARROWPROTO (report by Heiko Schlichting).
    • correct vttests/16colors.sh, which omitted the $SUF variable in output strings (patch by Paul Gilmartin).
    • modify shell scripts in vttests directory to attempt to use named signals in the trap statement, making this portable to OS/390 (report by Paul Gilmartin). Tested on SunOS 4.1.4, which implements only numbers.

    Patch #177 - 2003/3/23 - XFree86 4.3.0

    • fix definition of USE_HANDSHAKE, must be numeric (reported by Jens Schleusener).

    Patch #176 - 2003/3/22 - XFree86 4.3.0

    • add configure option --enable-pty-handshake to allow one to compile-in support for the pty handshaking logic, and resource ptyHandshake to enable or disable it (suggested by Ian Collier).
    • restore USE_HANDSHAKE ifdef removed in patch #159 to address Debian #39964.
    • move ifdef's for ttysize/winsize into xterm_io.h
    • simplify loop on tgetent, check if the successive entries in the lookup table are the same. That makes xterm do one less lookup if there is no "xterm" entry in the termcap file (report by Derek Martin).
    • correct manpage discussion of $TERM and $TERMCAP variables, which omitted the Tektronix emulation and a note of the final "dumb" fallback.
    • broaden ifdef for XRegisterIMInstantiateCallback() from patch #175 (XIM fix) to exclude non-XFree86 (report by Nelson Beebe indicates this breaks for Solaris, IRIX and OSF/1).
    • correct resource-size for iconFont (this was added by X11R6.3).
    • improve configure check for XKB bell extension, to work around inconsistent implementation of this feature (reports by Nelson Beebe, Kriston Rehberg and David Ellement).
    • modify configure-check for tty group to be less strict in batch mode (report by Nelson Beebe).
    • modify to allow building with g++, to use its compiler warnings (suggested by Nelson Beebe).
    • modify dec2ucs[] table to reflect newer codes available for scanlines 1, 3, 7, 9 (report by Michael Schroeder).
    • add configure option for XawPlus library.

    Patch #175 - 2003/3/9 - XFree86 4.3.0

    • fix a SIGSEGV which could occur if xterm is connecting to XIM server, and the XIM server is destroyed (patch by Nam SungHyun).
    • modify to use built-in line-drawing characters for Xft fonts (patch by Andrew Tipton).
    • make menu reflect the state of the tekInhibit resource.
    • make signalInhibit resource work, i.e., disable the menu entries that would send signals to, or exit xterm. This was probably broken in X11R5 when logging was disabled (report by Sven Mascheck).
    • changed classes of colorBDMode and similar resources that override colors when a video attribute is set to ColorAttrMode, to make them distinct from ColorMode. This avoids an unexpected rendering of reverse video, for example (report by Paul Fox).
    • changed class of veryBoldColors to VeryBoldColors, since ColorMode is associated with boolean resources.
    • add option -k8 and resource allowC1Printable to allow users of non-VTxxx character sets such as KOI-8 to treat the C1 control area (character codes 128-159) as printable rather than control characters.
    • add a null-pointer check for return-value of ptsname() in HPUX-specific code (report by David Ellement).
    • revise the ifdef's used for XKB bell support. The code was using a nonstandard call XkbStdBell(). Changed to use XkbBell() (based on patch by <derek@signalmarketing.com>).
    • add a null-pointer check in xtermLoadFont() in case there is no wide-bold font (Nam SungHyun).
    • change Makefile.in to use autoconf's bindir, libdir and mandir variables (report by Nam SungHyun).
    • add le to termcap xterm-basic entry. Though missing from older termcaps for xterm, some applications check for it (report by Matthias Buelow).
    • modify uxterm script to strip modifiers such as "@euro" from the locale setting before adding ".UTF-8" (Debian #179929).
    • modify the remaining places where tek4014 emulation uses XDefineCursor(), to make it work as originally implemented, e.g., when switching back to alpha mode. Added test-screen in vttest to test this feature properly.

    Patch #174 - 2003/2/25 - XFree86 4.2.99.903

    • work-around for XFree86 bug which made XDefineCursor() on a shell-window no longer work. The tek4014 emulation used this. Use the next lower window (report by Karl Rudolf Bauchspiess).
    • add a resource setting allowWindowOps to control whether the extended window operations should be allowed, e.g., resize, iconify, report window attributes. This is to accommodate people who are not capable of using a pager to view log-files.

    Patch #173 - 2003/2/6 - XFree86 4.2.99.902

    • reset mouse mode to normal on a full reset. This does not apply to mouse hilite tracking mode, of course (see ctlseqs.ms).
    • add a time-delay at the point where mouse hilite tracking mode choses to not handle X events, to avoid runaway CPU usage (report by D Hugh Redelmeier).
    • check for illegal character in DECUDK string, quit if detected.

    Patch #172 - 2002/12/27 - XFree86 4.2.99.3

    • fixes to make repainting of 256-color example work properly (reports by Abigail Brady and Scott A Crosby).
      • set flag in AllocateAnsiColor() to ensure the color is allocated once only.
      • fix check in ScrnRefresh, which was comparing background colors only if the ANSI foreground colors also were set.
    • merge Error() calls and some exit() calls into SysError(), and change that to add the brief explanation for each error code which is provided in the manpage. Change a few SysError(), calls to avoid using code 1, to avoid confusion with exit status from places that do not use SysError().
    • simplify logic used to open a debug logfile as the standard error.
    • modify the -e option so that if it fails, xterm will check if only one argument follows, e.g., it was quoted, and then retry using sh -c.
    • modify parsing of DECUDK string parameter to allow a comma between pairs of hexadecimal digits (Ray Neuman <raymond@one.com.au> reports that "real" terminals accept this; perhaps they simply ignore unexpected characters).
    • fix a few problems with the $TERMCAP string generated by resize:
      • for Bourne shell, add an export command. This was missing as far back as X11R5.
      • escape exclamation marks, used in xterm's reset string.
      • translate literal \177\ to "^?".
    • improve configure check for tgetent() to work when $TERMCAP has been set to a specific entry.
    • modify minstall.sh to use "%" rather than "@", to avoid problems with AFS (report by Zdenek Sekera).
    • list fatal error codes from error.h in the manpage, remove unused codes in error.h.
    • use more explicit wording for manpage list of color resources, since at least one user confused the generic names such as "black" with the names in rgb.txt (the latter are now used).
    • minor fix to description of 1003 mouse mode in ctlseqs.ms (Larry Riedel).

    Patch #171 - 2002/12/12 - XFree86 4.2.99.3

    • modify parser tables to improve detection of malformed control sequences, making xterm behave more like a real DEC terminal (patch by Paul Williams).
    • update comment in input.c to document Meta as a modifier for escape sequences (patch by D Roland Walker).
    • add ifdef'd code for logging option which adds the hostname and a timestamp to the generated logfile name. The ifdef's are setup with the configure script (patch by Nelson Beebe).
    • remove xevents() call from the end of BlinkCursor(), to fix an occasional problem which caused xterm to pause until a key was pressed. The reason for this was that there was no check to ensure that there really were events for xevents() to process. (patch by Semen A Ustimenko <semenu@FreeBSD.org>).
    • remove unused mode-params from open() calls that do not create a file.
    • modify configure script to put new items first on $CPPFLAGS and $CFLAGS to avoid conflict with environment's -I and -D options.
    • update config.guess, config.sub
    • resync with XFree86 CVS
      • fix va_args glitches for xterm/libfontconfig: 0 == (void*)0 isn't true for all platforms (Egbert Eich).
      • initialise ProgramName in xterm's main before referencing it (XFree86 #5473, Peter Valchev).
      • some cleanup of Imakefile ifdef's (Marc La France).

    Patch #170 - 2002/10/13 - XFree86 4.2.1

    • correct an off-by-one allocating data for sorted help message.
    • modify configure script to check for Xpm library, on which XFree86 Xaw library depends.
    • update config.guess, config.sub

    Patch #169 - 2002/10/5 - XFree86 4.2.1

    • modify wording of some options in help message to make them use -/+ consistently with respect to "on/off" or "off/on".
    • sort options list which is displayed in help- and syntax-messages at runtime to simplify maintenance.
    • remove support for Amoeba and Minix (Juliusz Chroboczek noted it was removed from XFree86 server; there have been no users since 1996).
    • add configure script option --disable-session-mgt to control whether the session management code should be compiled-in (request by H Merijn Brand).
    • ifdef'd the session-management changes with OPT_SESSION_MGT, to accommodate X11R5 which predates the related definitions.
    • fix decode_keyvalue(), which did not properly parse multiple settings as needed for the ttyModes resource, since it did not skip over the parsed data.
    • fix an option-parsing conflict between -class and -cjk_width (Nam SungHyun)
    • add a missing null in XtVaSetValues() call used in Cleanup() (Nam SungHyun)

    Patch #168 - 2002/9/29 - XFree86 4.2.1

    • improve data reported for control sequence that requests window position by taking into account the window decorations, e.g., border and title (patch by Jess Thrysoee <jess@thrysoee.dk>).
    • add -cjk_width and corresponding resource cjkWidth (patch by Jungshik Shin <jshin@mailaps.org>).
    • add -into option, for embedding xterm in a Tcl/Tk application (patch by George Peter Staplin <georgeps@xmission.com>).
    • add simple session management (XSM) client capabilities to xterm. So a session manager such as, e.g., xsm, should be able to respawn or kill xterms without the help of an SM proxy (like smproxy), which is a hack and almost always buggy (patch by David Madore).
    • fix conflict between ifdef's for OPT_DEC_LOCATOR and OPT_READLINE in button.c (reported by Ilya Zakharevich).
    • fix for inconsistent use of struct utmp versus struct utmpx introduced in patch #167 (patches by Paul Gilmartin, Marc La France).
    • modify logic for metaSendsEscape to allow it to work in a setup where the Meta-key is not recognized as a modifier by the key-translations logic (discussion of eightBitInput with H.J.Lu). Note however that Vincent Lefèvre reported this in January).
    • use null pointer values consistently, rather than literal "0", for ending variable-length argument lists, e.g., for execlp() (based on patch by Matthieu Herrb).
    • correct logic of ChangeAnsiColorRequest(), which would do a screen repaint after replying to a request for information.
    • improve scripts in vttests to work with systems whose shells support echo -n and have, as does Debian, an unrelated print utility.
    • add vttests/acolors.sh to demonstrate OSC 4, which queries or sets ANSI colors.
    • fixes for ctlseqs.ms (Pavel Roskin, Ilya Zakharevich).
    • typos in xterm manpage (Jens Schweikhardt)
    • remove a redundant GCC_UNUSED from InitPopup() (Nam SungHyun)

    Patch #167 - 2002/8/24 - XFree86 4.2.0

    • correct ifdef's for USE_TERMCAP to match cygwin configuration.
    • fix several places in ctlseqs.ms which had no boxes around the literal text (report by Ilya Zakharevich).
    • extend mouse support for readline, ifdef'd with OPT_READLINE (integrated patch from Ilya Zakharevich).
    • modify terminfo description to match default for modifyCursorKeys resource.
    • add modifyCursorKeys resource to control how the shift- and similar modifiers are used to make a cursor escape sequence. The default makes a modified escape sequence always start with CSI and puts the modifier as the second parameter, to avoid confusing applications that would interpret the first parameter as a repeat count. The original behavior can be obtained by setting the resource to 0 (newsgroup discussion with Stephen J Turnbull, Jeffrey Altman).
    • correct missing initializations for appdefaultCursor and appdefaultKeypad resources.
    • add configure option --enable-luit and ifdef'd the luit-related code with OPT_LUIT_PROG.
    • modify xterm to invoke luit (integrated patch by Tomohiro Kubota)
    • update wcwidth.c to match Markus Kuhn's 2002-05-18 version.
    • correct limit-checking in ComputeSelect() to handle selections that extend off the visible area; rather than modify the parameters to TrackText(), use ScrollSelection() to update the highlighting limits. (reported by Yegappan Lakshmanan and Nelson Beebe, patch by Alexander V Lukyanov).
    • correct manpage description of tiXtraScroll resource (reported by Tony Finch).
    • changes from OpenBSD:
      • Make xterm setgid utmp to be able to update utmp even with root privileges revoked.
      • If not updating utmp, revoke group privileges totally too.
    • changes from NetBSD:
      • Check that the return value from ttyslot() is greater than 0 before writing the utmp file. Fixes w's "w: Stale utmp entry: <user> <tty> <pty>" errors.
      • Use openpty() to deal with new pty naming scheme.
    • add print-redir action and menu entry to allow user to switch terminal in/out of printer controller mode. It appears from the manual that a real vt220 would not switch back to normal mode, so another mechanism is used (addresses Debian #37517).
    • check if printerCommand resource string is empty, use this to allow user to disable printer function.
    • trim trailing blanks from resource strings.
    • check return value from ptsname(), which may return null for example if someone has changed the permissions of /dev/pts to zero (Debian #121899).
    • modify OS/2 version to use __UNIXOS2__ definition rather than __EMX__, related cleanup (patch by Holger Veit).
    • used modified indent 2.0 (patch 20020428) to reformat most of the C source files, to simplify maintenance.
    • fix a couple of places where there were leading tabs on symbol-definition lines in Imakefile (Marc La France from report by Tony Finch)
    • add imake variable (TraceXTerm) to allow building debug version (Egbert Eich).

    Patch #166 - 2002/3/25 - XFree86 4.2.0

    • correct a bug in selection: double clicking on a word which was partly scrolled off the screen may select that text (report by Vincent Lefèvre <vincent@vinc17.org>).
    • implement veryBoldColors resource to control whether the corresponding video attribute such as bold is displayed when using colorBDMode, etc. (request by Josh Howard <jrh@vicor-nb.com>).
    • define escape sequences for function keys F21-F35 (patch by Stephen P Wall).
    • change the colors for the 256-color model, making them less skewed toward black (patch by Stephen P Wall).
    • add vt100Graphics resource (see patch #115, based on discussion with Glenn Maynard).
    • ifdef'd Xaw/Xaw3d/neXtaw includes separately to avoid potential incompatibilities between these flavors of Athena widgets.
    • add configure check for XFree86 4.x Xaw library, whose geometry management is broken, to avoid trying to use it for toolbar configuration.
    • updates to configure script from vile and lynx to allow configure.in to be compiled with autoconf 2.5x
    • add a check for null pointer return by ptsname() (newsgroup posting from Mike Silva <mikesilva@lucent.com>).
    • fill in a few details needed to allow UTF-8 mode to switch on/off after startup. This requires that wideChars resource be set. (based on comments in 4 Aug 2001 by Alexey Marinichev <lyosha@lyosha.2y.net>).
    • remove duplicate install rules that make directories, e.g., so installing manpage will not create app-defaults directory.
    • add comment in in do_osc(), reserving cases 30 and 31 for for Konsole (request by Stephan Binner <Stephan.Binner@gmx.de>).
    • fixes for ctlseqs.ms and xterm.man (patch by Werner Lemberg <wl@gnu.org>).
    • add check for monochrome display, disabling colorMode in that case (fixes Debian #134130).
    • resync with XFree86 CVS
      • Fix some xterm build warnings on *BSD (patch by David Dawes).
      • Only use SA_RESTART in xterm when it's available (patch by Frank Liu).
      • Fix incorrect code in signal handlers in most of the clients, xterm and xdm not done yet (patch by Matthieu Herrb).

    Patch #165 - 2002/1/5 - XFree86 4.1.0

    • modify uxterm script to strip encoding part from environment variable before adding ".UTF-8" (based on Debian #125947, but using a more portable solution).
    • add an assignment statement in VTInitialize() to make awaitInput resource work.
    • use new macros init_Bres(), etc., in VTInitialize() to add trace of the initialization of resources.
    • modify checks for $LC_ALL, related environment variables to ensure the resulting strings are nonempty (report by Markus Kuhn).
    • add an ifdef in charproc.c for num_ptrs variable in case all configure options are disabled.
    • modify definition of getXtermBackground() to avoid negative array index warning on Tru64 (report by Jeremie Petit).
    • improve fix from patch #165 (still Debian #117184, report by Matt Zimmerman <mdz@debian.org>)
    • correct install rule for uxterm in Makefile.in, to handle the case where building in a different directory than xterm's source (patch by Paul Gilmartin).
    • documented ANSI.SYS-style cursor save/restore escape sequences in ctlseqs.ms, which are in xterm since X11R5.
    • correct two entries in the default charClass table, which did not follow the manpage comment about the character number corresponding to the class (patch by Marc Bevand <bevand_m@epita.fr>).
    • fix a couple of typos in comments in the app-defaults files (David Krause <xfree86@davidkrause.com>).
    • resync with XFree86 CVS
      • update language of copyrights in some files to reflect the fact that they were reassigned from X Consortium to The Open Group in 1998. Note that this xterm source is derived from the 1996 version from X Consortium, does not incorporate changes made by X Consortium or The Open Group after that date, hence we do not add The Open Group's 1998 copyright date to related files.
      • save/restore errno in signal catcher (patch by Matthieu Herrb).
      • modify UXTerm.ad's font5 resource so that xterm can display double width characters using a font distributed with XFree86 (Tomohiro Kubota).

    Patch #164 - 2001/11/13 - XFree86 4.1.0

    • correct a case where ptyInitialErase and backarrowKeyIsErase resources combine to set DECBKM mode, but a reset command would not reset xterm to that state, making the erase character revert to ^H (Debian #117184)

    Patch #163 - 2001/11/04 - XFree86 4.1.0

    • correct ifdef's for __QNX__ and USE_SYSV_PGRP in main.c call to tcsetpgrp, which broke bash behavior around patch #140 (report/patch by Frank Liu <fliu@mail.vipstage.com>).
    • modify trace.c to fix missing definition of GCC_UNUSED for compilers other than gcc when configured for trace code (report/patch by Paul Gilmartin).
    • change format in TraceOptions() to use long rather than int, since the latter could lose precision on 64-bit machines (report/patch by Nelson Beebe).
    • modify xterm manual page and minstall.sh to allow imake rules to define location of app-defaults directory (Debian #87611).
    • review/update list of conflicting preprocessor symbols to remove from $CPPFLAGS at the end of the configure script. In particular, this allows one to configure xterm without the utempter library on Redhat 7.1 (report/patch by Adam Sulmicki).

    Patch #162 - 2001/10/23 - XFree86 4.1.0

    • correct logic that processes -class option, so that a following -e option is handled (Debian #116297).
    • improve options-decoding to allow -version and -help options to be combined (Debian #110226).
    • add a 10 millisecond delay in event loop when processing -hold option, to avoid using too much CPU time (Debian #116213).
    • prefix final program execution in uxterm with "exec" to avoid a useless shell hanging around (Christian Weisgerber).

    Patch #161 - 2001/10/10 - XFree86 4.1.0

    • modify logic that resets keypad application mode to avoid doing this if there is no modifier associated with the Num_Lock keysym (report by John E Davis <davis@space.mit.edu> and Alan W Irwin <irwin@beluga.phys.uvic.ca>).
    • add built-in translation for Control/KP_Separator to KP_Subtract, to accommodate users who wish to use xmodmap to reassign the top row of the numeric keypad.
    • correct Imakefile install-rule for uxname script (reported by Nam SungHyun <namsh@lge.com>).
    • resync with XFree86 CVS – correct typo in <ncurses/term.h> ifdef.

    Patch #160 - 2001/10/7 - XFree86 4.1.0

    • modify logic in main.c (see patch #145) to avoid generating the same identifier, for example, for /dev/tty1 and /dev/pts/1, which is used to denote an entry in the utmp file (Debian bug report #84676), A similar fix was also sent by Jerome Borsboom <borsboom@westbrabant.net> in May, but I overlooked it when reviewing bug reports.
    • add configure check for <ncurses/term.h> to get rid of hardcoded __CYGWIN__ ifdef in resize.c

      NOTE: The CYGWIN port should not be linking resize with ncurses. It appears that the only reason it is, is because both the ncurses and termcap ports on that platform are badly misconfigured (essential pieces have been removed, etc). Checking for <ncurses/term.h> does not hurt anything, since there are some correct installations that are set up that way.

    • add a sample uxterm script, which uses the UXTerm application defaults for UTF-8 environments.
    • undo change to xterm application defaults, since this introduced an unnecessary incompatibility. The intended functionality was already addressed by the UXTerm app-defaults file.
    • resync with XFree86 CVS
      • Modified xterm app default to use LFD fontnames instead of old type (Michael Schroeder).
      • Fix xterm when XIM is disabled - caused a segfault (Tomohiro Kubota).

    Patch #159 - 2001/9/19 - XFree86 4.1.0

    • remove an ifdef for USE_HANDSHAKE added in patch #158 from the second TIOCSSIZE ioctl call in the initialization code. Paul Gilmartin reports that for Solaris 2.6 (sparc), stty does not show that xterm sets rows and columns unless the second ioctl is executed.
    • correct treatment of empty parameter list for some OSC strings (report by Sami Farin <sfarin@ratol.fi>).

    Patch #158 - 2001/9/8 - XFree86 4.1.0

    • augment key translations for scrollbar widget to ensure that keystrokes intended for the text area are not lost if the mouse pointer happens to fall on the scrollbar. This can happen, for instance, if the user's app-defaults or .Xdefaults file contains a translations resource, though it may also happen through unrelated resource settings: probably a bug in libXt (reported by Paul Fox <pgf@foxharp.boston.ma.us> and Dmitry Yu. Bolkhovityanov <D.Yu.Bolkhovityanov@inp.nsk.su>).
    • widen ifdef's in xterm.h to define __EXTENSIONS__ on Solaris, for compilers other than gcc. This was added along _POSIX_C_SOURCE with in patch #151, but is not sufficient since Sun's compiler does not define __STDC__ by default (report by Matthias Scheler <tron@zhadum.de>).
    • modify xterm to obtain the closest matching color if an exact color is not available, e.g., on 8-bit displays (patch by Stephen P Wall)
    • implement "OverTheSpot" preedit type of XIM input (patch by Tomohiro Kubota):
      • This preedit type is a reasonable compromise between simpleness of implementation and usefulness. "Root" preedit type is easy to implement but not useful; "OnTheSpot" preedit type is the best in the point of view of user interface but very complex. And more, "OverTheSpot" is the preedit type which the most XIM servers support. Thus, to achieve reasonable usability, support of "OverTheSpot" preedit type is needed.
      • In "OverTheSpot" preedit type, the preedit (preconversion) string is displayed at the position of the cursor. On the other hand, it is XIM server's responsibility to display the preedit string. Thus, it is needed for XIM client (here XTerm) to inform the XIM server of the cursor position. And more, to achieve good visual proportion, preedit string must be written using proper font. Thus, it is XIM client's responsibility to inform the XIM server of the proper font. The font must be supplied by "fontset". Fontset is a set of fonts with charsets which are specified by the current locale. Since XTerm uses ISO10646 fonts regardless of the current locale, the fonts for XIM must be prepared separately. It is difficult to prepare fonts which are similar to XTerm font. Thus, my patch uses a simple way - the default font is "*" which matches every fonts and X library will automatically choose fonts with proper charsets. I added "-fx" command option and "ximFont" resource to override this default font setting.
      • changed the definition of "OverTheSpot" preedit type from XIMPreeditPosition|XIMStatusArea to XIMPreeditPosition|XIMStatusNothing. This matches the behavior of other programs such as Rxvt, Kterm, Gedit.
      • A tiny XIM bugfix is also included. By calling XSetLocaleModifiers() with parameter of "", it can consider XMODIFIERS environmental variable which is a standard way for users to specify XIM server to be used.
    • adjust configure script to accommodate repackaging of keysym2ucs.c as include-file for xutf8.c (patch by Tomohiro Kubota).
    • add the UXTerm app-defaults file to makefile install rules (request by Juliusz Chroboczek).
    • correct logic in get_termcap(), which returned false if the tgetent() call indicated that xterm was linked with terminfo. Although the $TERMCAP variable cannot be adjusted in this case, xterm still needs information from this call to extract data to initialize the erase-mode when the ptyInitialErase resource is false.
    • modify ScrollbarReverseVideo() function to cache the original border color, so it can restore that when an application flashes the screen (Bugzilla #38872).
    • resync with XFree86 CVS
      • remove ifdef's for X_NOT_STDC_ENV (patch by David Dawes).
      • add Cygwin to special errno handling case in ptydata.c (Alan Hourihane)
      • set screen size earlier in initialization, to address a race with window manager resizing its clients (Keith Packard).

    Patch #157 - 2001/6/18 - XFree86 4.1.0

    • clean up button.c and input.c (patch by Juliusz Chroboczek). The basic idea is to use a single set of APIs in the XTerm core, and put a set of workarounds in a separate file. As you will notice, this drastically simplifies parts of the code; in particular, the only remaining ifdefs related to the differences between Xutf8 and legacy systems are related to the selection provider logic. This defines two new files, xutf8.h and xutf8.c, provide some half-hearted but fully portable emulation for the three Xutf8* functions that XTerm uses. Putting these in a separate file will allow people to experiment with more complex versions without making the core of XTerm more difficult to maintain. The functionality of the emulation is as follows.
      • Xutf8TextListToTextProperty fully handles XStringstyle and XUTF8StringStyle. It will only generate STRING for XStdICCTextStyle, and will only generate Latin-1 in XCompoundTextStyle (but label it as COMPOUND_TEXT, as the spec requires). (I have hesitated to make this function fail for XStdICCTextStyle and XCompoundTextStyle; this might be a smart thing to do, in the hope that the selection requestor will try UTF8_STRING afterwards; opinions?)
      • Xutf8TextPropertyToTextList fully handles STRING and UTF8_STRING. It systematically fails for COMPOUND_TEXT.
      • Xutf8LookupString will properly handle single-keystroke input for the keysyms covered by Markus' keysym2ucs function. It will not handle either compose key input or external input methods.
    • add an ifdef for SunXK_F36, used in xtermcapKeycode() (patch by Mark Waggoner <waggoner@ichips.intel.com>).
    • modify check for login name to try getlogin() and $LOGNAME, $USER environment variables to detect if the user has logged in under an alias, i.e., an account with the same user id but a different name (Debian bug report #70084).
    • add resource tiXtraScroll, which can be used to preserve the screen contents in the scrollback rather than erasing it when starting a fullscreen application such as vi (patch by Ken Martin <fletcher@catsreach.org>).
    • two patches by Denis Zaitsev <zzz@cd-club.ru>:
      • added forceBoxChars resource to control the "line-drawing characters" option.
      • added freeBoldBox resource, which, when set true, suppresses check in same_font_size(), so xterm does not attempt to ensure that the bold font is the same size as the normal font.
    • change the color class for ANSI colors and similar ones such as bold-color, etc., to follow the convention that the classname is the instance name with a leading capital (e.g., color0 and Color0 rather than color0 and Foreground). There was little use for Foreground as a class other than to create occasional confusion and bug reports, most recently by Nelson Beebe who reports that it disables colors in xterm but not on Linux, which is probably due to a difference in resource evaluation order. A configure script option (--disable-color-class) is provided for anyone who did use the older behavior.
    • fix a signal-handling bug. When running xterm with ksh or similar shell such as bash 2.05, xterm will hang and not respond to keystrokes after the user types suspend. Additionally the popup menus do not respond, so it is not possible to send SIGCONT to the shell. What is happening is that the shell is sending itself SIGSTOP, and it is being stopped. Per specification it also means that the operating system is sending SIGCHLD to parent to the bash (XTERM). Now the issue is that xterm assumes it cannot happen and it expects to receive SIGCHLD only upon termination of its children. This causes a deadlock with xterm waiting for the child to die, and the child waiting for SIGCONT. (report/patch by Adam Sulmicki), analysis/testing by Sven Mascheck <sven.mascheck@student.uni-ulm.de>).
    • correct some inconsistent checks for XtReleaseGC() calls in xtermLoadFont() (patch by Nam SungHyun <namsh@lge.com>).
    • updated wcwidth.c and keysym2ucs.c to versions dated 2001/1/12 and 2001/4/18, respectively from http://www.cl.cam.ac.uk/~mgk25/ucs/
    • correction to change from patch #90, which was intended to reset the saved cursor position for normal/alternate screens on a soft reset, but actually wiped out all of the saved cursor information. Just reset the saved position for the current screen (report by Michael Schroeder).
    • modify ShowCursor() and HideCursor() so that if the cursor points to the second part of a wide character, make the show/hide operate on the first position of the wide character (patch by Sven Verdoolaege).
    • scrolling in the alternate screen just before switching back to the main screen can cause extra blank lines to be inserted into the scrollback buffer (patch by Paul Vojta <vojta@math.berkeley.edu>).
    • resync with XFree86 4.1.0:
      • Use TermcapLibrary as -lncurses instead of -ltermcap, fixes problem building xterm/resize on Cygwin/XFree86 (Harold Hunt).
      • Install xterm.termcap and xterm.terminfo when installing xterm (Torrey T. Lyons).
      • Fix some build issues on Cygwin/XFree86 (Suhaib Siddiqi).
      • Define CBAUD, when it's missing in xterm, on LynxOS (Stuart Lissaman).

    Patch #156 - 2001/4/28 - XFree86 4.0.3

    • change order of selection-target types to make 8-bit xterm prefer UTF8_STRING to COMPOUND_TEXT (patch by Juliusz Chroboczek).
    • document -fa, -fs command-line options and faceName, faceSize resources which are used by the freetype library support.
    • if configure script finds freetype libraries, but imake definitions do not have the XRENDERFONT definition, define it anyway.
    • modify configure script check for freetype libraries to include <Xlib.h>, since an older version of the related headers relies on this (patch by Adam Sulmicki).

    Patch #155 - 2001/4/20 - XFree86 4.0.3

    • correct return type of in_put() from patch #153 changes, which left it not wide enough for UTF-8 (patch by Bruno Haible).

    Patch #154 - 2001/4/11 - XFree86 4.0.3

    • undo check for return value from pututline (used for debugging) since that function does not return a value on Slackware 3.6.
    • correct length in ScreenWrite, when rendering invisible text (patch by Sven Verdoolaege <skimo@kotnet.org>).
    • fixes/improvements for the i18nSelection resource from patch #153, by Bruno Haible:
      • add missing initialization for i18nSelection resource.
      • split-out the non-ICCM aspect of the i18nSelection resource as a new resource, brokenSelections.
    • add configure check for <time.h> and <sys/time.h>, to allow for Unixware 7, which requires both. If the configure script is not used, only <time.h> will be included as before (report by Thanh Ma).
    • fix redefinition of dup2, getutent, getutid, getutline and sleep functions on Unixware 7 (report by Thanh Ma <Thanh.Ma@casi-rusco.com>)
    • add a fall-back definition for __hpux, which is apparently not defined in some compilers on HPUX 11.0 (reported by Clint Olsen).
    • change VAL_INITIAL_ERASE, which is used as a fallback for the "kb" termcap string to 8, since that matches the xterm terminal description (request by Alexander V Lukyanov).
    • correct an off-by-one in ClearInLine, which caused the erase-characters (ECH) control to display incorrectly (patch by Alexander V Lukyanov).
    • correct escape sequences shown in terminfo for shifted editing keys. The modifier code was for the control key rather than the shift key.

    Patch #153 - 2001/3/29 - XFree86 4.0.3

    • increase PTYCHARLEN to 8 for os390, add some debugging traces for UTMP functions (patch by Paul Gilmartin).
    • correct an misplaced brace in SelectionReceived() (patch by Bruno Haible).
    • correct an assignment dropped in SelectionReceived() which made it not compile for wide-characters combined with debug traces.
    • correct typo, clarify description of 88- and 256-color controls (report by Bram Moolenaar).
    • correct a typo in ctlseqs.ms which caused DEC Locator control sequences using single quote "'" display grave "`" instead (reported by Paul Williams, apparently in patch #114).

    Patch #152 - 2001/3/13 - XFree86 4.0.2

    • correct index in inner loop in VTInitI18N() from patch #151 changes, which resulted in infinite loop under some conditions (report/analysis by Paul Gilmartin).
    • remove spurious "%|" from terminfo sgr capabilities (report/analysis by Adam M Costello, Debian #89222).
    • add shell script to adjust list of dynamic libraries linked by resize when building with the standalone configure script. Otherwise it uses the same list as for xterm, which is excessive.
    • fix a few compiler warnings reported by the 20010305 gcc snapshot.

    Patch #151 - 2001/3/10 - XFree86 4.0.2

    • alter the behaviour of selections in XTerm (patch by Juliusz Chroboczek). It is believed to follow the ICCCM + UTF8_STRING to the letter, both in UTF-8 and in eight-bit mode. From his description:
      • When compiled against XFree86 4.0.2, the patched XTerm will make the selection available as COMPOUND_TEXT, STRING or UTF8_STRING in both modes. It will request selections in the following order:

        UTF-8 mode: UTF8_STRING, TEXT, COMPOUND_TEXT, STRING.
        eight-bit mode: TEXT, COMPOUND_TEXT, UTF8_STRING, STRING.

      • When compiled against an earlier version of XFree86 (or compiled with OPT_UTF8_API=0), it will still obey the ICCCM, but will neither request nor provide UTF8_STRING in eight-bit mode, and neither TEXT nor COMPOUND_TEXT in UTF-8 mode.
      • For compatibility with previous versions of XTerm, a resource i18nSelections is provided, please see the manpage for details. However, due to an unexpected combination of ICCCM extensions by various bits and pieces of the libraries, interacting with previous versions of XTerm will work in many locales even without this flag. (Please do not set this resource to true by default, as this would violate the ICCCM.)
    • improved error checking/reporting in VTInitI18N(), ensuring that lack of input method styles is treated distinctly from a mismatch.
    • remove an incorrect ifdef from patch #141 which suppressed overstriking to simulate bold font when xterm was compiled to support wide characters (report/analysis by Adam M Costello <amc@cs.berkeley.edu>, Debian #76404, Debian #77575).
    • modify RequestResize() function to save/restore window manager hints. Its call to XtMakeResizeRequest() had the undesirable side-effect of clearing window manager hints, e.g., when switching to 132-columns via DECCOLM escape sequence. Window manager hints make it simple to resize xterm in terms of character cells rather than pixels (reports by Christian Weisgerber, Debian #79939).

      This applies to the normal configuration. When built with toolbar support, the hints are applied to a different widget level (more work will be needed to make hints work with the toolbar).

    • fix a redefinition warning for resize.c on OpenBSD (patch by Christian Weisgerber).
    • change resource corresponding to -T option to match Xt library's -title, i.e., .title rather than *title so the command-line options are interchangeable as documented (Debian bug report #68843).
    • add script used from autoconf'd makefile for installing manpages, since recent XFree86 changing the way section numbers are represented makes the install dependent on extra scripts.
    • add configure check for freetype libraries and configure option --disable-freetype to override this feature.
    • modify some configure script macros to avoid using changequote(), which has been rendered useless in the latest autoconf alpha 2.49c
    • update config.guess, config.sub to 2001-2-13
    • remove redundant/contradictory __CYGWIN__ definitions from resize.c
    • correct manpage typo introduced by X11R6.5 resync.

    Changes from XFree86 4.0.2:

    • add definition of _POSIX_C_SOURCE for Solaris to make this compile with gcc -ansi -pedantic (report by <mark@zang.com>.

    Patch #150 - 2000/12/29 - XFree86 4.0.2

    • move the binding for shifted keypad plus/minus, which invokes the larger-vt-font() and smaller-vt-font() actions, respectively, into the translations resource (suggested by Marius Gedminas <mgedmin@puni.osf.lt>).
    • modify configure script to support the --program-prefix, --program-suffix and --program-transform-name options (request by Alison Winters <alison@mirrabooka.com>).
    • fixes for wide/combining characters (Robert Brady):
      • fix a scrolling / combining characters display anomaly
      • fix a problem with double-width characters where if the primary font had no box-drawing characters, the right hand half of double-width characters was erased (reported by Yao Zhang <yzhang@sharemedia.com>).
      • fix special case of null byte for key handling in UTF-8 locales.
    • modify logic that compares sizes of normal and bold fonts to be more forgiving of the font server's choice of bold font which must match the normal font's size. Now same_font_size() compares the height of the fonts rather than individually ascent and descent, and allows the bold font to be one pixel smaller than the normal font (addresses a report by Alan Citterman <alan@mticket.com>, who says that something in patches #146 to #148 made xterm more likely to overstrike bold fonts, and indirectly Debian bug report #76404, which reports the opposite).
    • make configure script use $CFLAGS and $CPPFLAGS consistently, including removing a chunk from configure.in which attempted to save/restore $CPPFLAGS while processing value set by the --x-includes option, but lost values set in an intervening AC_CHECK_HEADERS. This change modifies macros CF_ADD_CFLAGS, CF_ANSI_CC_CHECK and CF_X_TOOLKIT, as well as removing variables IMAKE_CFLAGS and X_CFLAGS from the generated makefile (the AC_CHECK_HEADERS problem was reported by Albert Chin-A-Young <china@thewrittenword.com<).
    • correct a comparison in SELECTWORD case of ComputeSelect(), which resulted in a word-selection wrapping past the first column without checking the first column's character class (reported by Christian Lacunza <celacunza@netscape.net>
    • correct a logic in UTF-8 mode for selecting double-width characters; a combining character was omitted (patch by Markus Kuhn).
    • add feature to pop (raise) window when a bell is received (patch by Gael Roualland <gael.roualland@dial.oleane.com>).
    • add __NetBSD__ and __OpenBSD__ to special-case in xterm_io.h for USE_POSIX_TERMIOS definition (patch by Christian Weisgerber).
    • move special-case HPUX include for <sys/bsdtty.h> to xterm_io.h to define TIOCSLTC, making HAS_LTCHARS defined for HPUX 10.20 (report by Bruno Betro).

    Patch #149 - 2000/12/6 - XFree86 4.0.1h

    • restructured includes for termios.h, termio.h and related definitions for main.c, os2main.c, screen.c and resize.c so they will share equivalent definitions in a new header xterm_io.h. This is intended to solve some problems mainly for HPUX which appear to arise from inconsistent definitions for SIGWINCH- and HAS_LTCHARS-related symbols (reports by Bruno Betro, Jeremie Petit and Clint Olsen).
    • improve usability of double-width fonts by allowing normal fonts to be given as double-width (from a patch by Fabrice Bellard <bellard@email.enst.fr>).
    • correct a few compiler warnings in TRACE() macros for signed/unsigned variable differences (reported by Clint Olsen).
    • make configure script use $CFLAGS and $CPPFLAGS more consistently, i.e., by using CF_ADD_CFLAGS in CF_ANSI_CC macro.
    • expanded description of environment variables in manual-page.
    • modify OPT_TCAP_QUERY feature to always return the termcap or terminfo capability string in the response, and to read/write the names in hexadecimal form to allow for the special case of termcap's k; name (patch by Bram Moolenaar).
    • add OPT_SAME_NAME and OPT_TCAP_QUERY to xtermcfg.hin, so the corresponding configure options work (patch by Bram Moolenaar).
    • resync with XFree86 4.0.1g:
      • Rewrite Xft library for Render extension/core text and font management Change xterm to use new interface (Keith Packard).

    Patch #148 - 2000/10/31 - XFree86 4.0.1d

    • document logfile options in man-page.
    • correct spelling of -samename option in help message.
    • add configure script option --enable-tcap-query (request by Bram Moolenaar).
    • add a "Co" or "colors" entry to the OPT_TCAP_QUERY feature (patch by Bram Moolenaar).
    • patch by Kiyokazu Suto <suto@ks-and-ks.ne.jp>:
      • add support for bold font for double width characters. The font name may be specified with the command line option -fwb or with resource wideBoldFont (class WideBoldFont).
      • correct underlining of double width character string, which was drawn only half width.
      • correct binary search of precomposed character table, which may return wrong result when int is just 32 bits.
    • some changes to align terminfo with ncurses 5.2:
      • remove xtermm description, retaining xterm-mono since the former conflicts with ncurses.
      • modify initialization and reset strings to avoid putting the save/restore cursor operations bracketing changes to video attributes, since the changes could be lost when the cursor is restored. This affects xterm-r6 and xterm-8bit (the xterm-xfree86 entry uses the soft-reset feature which resets scrolling margins and origin mode without requiring us to save/restore the cursor position).
      • make a few entries explicitly inherit from xterm-xfree86 rather than xterm: xterm-rep, xterm-xmc, xterm-nrc
    • ensure that sign-extension does not affect ctype macros by using CharOf() macro to coerce the parameter to an unsigned char.
    • resync with XFree86 4.0.1d:
      • Add primitive support in xterm for Xft based fonts (Keith Packard). The changes are ifdef'd with -DXRENDERFONT.

    Patch #147 - 2000/10/26 - XFree86 4.0.1c

    • correct implementation of ptyInitialErase: the value assigned to initial_erase was for the control terminal, which is correct as far as it goes. But there was no following test for the pseudo-terminal's erase value, which would overwrite the default obtained from the control terminal (reported by Christian Weisgerber <naddy@mips.inka.de>).
    • modify check for printable-characters in OSC string to use xterm's ansi_table rather than isprint() macro, to isolate this check from locale settings. This fixes a problem using 8-bit characters to set the title (reported by Ricardas Cepas <rch@richard.eu.org>).
    • modify sample scripts to check for printf before print, since the latter is not as well standardized (e.g., on Linux).
    • updated config.sub, config.guess to reflect changes on subversions.gnu.org

    Patch #146 - 2000/9/12 - XFree86 4.0.1c

    • correct two instances overlooked from patch #141 which assumed UTF-8 mode without checking, causing a core dump in non-UTF-8 mode (one instance was reported by Tommi Virtanen <tv@debian.org>).
    • correct a problem selecting from the scrollback buffer in UTF-8 mode by changing remaining getXtermCell() calls to XTERM_CELL() as in the non-UTF-8 cases (report by Markus Kuhn, patch by Robert Brady).

    Patch #145 - 2000/9/11 - XFree86 4.0.1c

    • changes for UTF-8 configuration (Robert Brady):
      • doublewide characters don't lose their accents when the cursor moves onto or from them (a visual bug)
      • fix logic in addXtermCombining, which mean that if the low byte of a cell's first combining char was 0, a following combining char would go into combining slot 1, not 2.
      • modify logic for cut-buffers so UTF-8 data is first converted to Latin1.
      • collapse surrogates, 0xfffe, 0xffff to UCS_REPL.
      • modify to allow xterm to to show combining characters attached to doublewidth characters.
      • correct bug in linewrap with -u8 option (reported by Andreas Koenig <andreas.koenig@anima.de>).
    • several changes to PTY logic (based on request by Tim Ryan <timryan@nortelnetworks.com>).
      • modify treatment of -S option to to make it work with Unix98 PTY's.
      • restore sense of IsPts flag in get_pty(), which was lost in Unix98 changes.
      • use new functions my_pty_id() and my_pty_name() to simplify/fix strings used for utmp, wtmp identifiers.
      • simplify get_pty() function, making it have a single return point so its inputs/outputs can be identified.
    • update config.guess and config.sub and scripts to my 20000819 patch, adding cases for OS/2 EMX.
    • add special case for os390 compiler options to configure script (patch by Paul Gilmartin)
    • fix some unused-variable compiler warnings (reported by Zdenek Sekera).
    • split-out some string functions into xstrings.c, to use them more consistently among main.c, os2main.c and resize.c
    • align termcap/terminfo files, adding entries to make them match. The termcap entries are necessarily less complete than the terminfo, to fit within 1023 character per entry.
    • add terminfo entry for xterm-sco (SCO function keys).
    • modify same_font_name() to properly handle wildcard introduced in bold_font_name(), making comparison for different fonts succeed when only the normal font is specified. This is needed to decide if 1-pixel offset should be used. (reported in a newsgroup by Bart Oldeman <enbeo@enbeo.resnet.bris.ac.uk>)
    • correct preprocessor line for OPT_WIDE_CHARS in drawXtermText() from patch #141 which resulted in overstriking for bold fonts not working.
    • correct Imakefile from 4.0.1c resync so UTF-8 modules are in UTF8SRC, UTF8OBJ lists, allowing build without UTF-8 support.

    Patch #144 - 2000/8/23 - XFree86 4.0.1b

    • remove a spurious assignment in ScreenWrite() from Robert Brady's patch which set a null at the "end" of the buffer to be written. That made the autowrap feature write a blank in the first column for the non-UTF-8 configuration, rather than the actual character (reported by Alan Citterman <alan@mticket.com>).

    Patch #143 - 2000/8/19 - XFree86 4.0.1b

    • add a check to ensure that -class command-line option is not confused with -c (reported by Paul Townsend <aab@aab.cc.purdue.edu>).

    Patch #142 - 2000/8/18 - XFree86 4.0.1b

    • correction to precompose scripts, so 0061 + 0300 will now be really be displayed as 00C0 (patch by Robert Brady <robert@susu.org.uk>).
    • correct macro ClassSelects() in button.c, used to hide ifdef's for OPT_WIDE_CHARS in patch #141 (reported by Andreas Paul <paula@informatik.tu-muenchen.de>).
    • change wcwidth.h to include stddef.h rather than wchar.h, which is not present on OpenBSD and FreeBSD (reported by Christian Weisgerber and Bram Moolenaar).
    • newer config.sub and config.guess, from lynx 2.8.4dev.7

    Patch #141 - 2000/8/14 - XFree86 4.0.1b

    • changes for doublewidth and combining characters, from http://www.ecs.soton.ac.uk/~rwb197/xterm/ (integrated patch by Robert Brady). In this context, doublewidth refers to 16-bit character sets which may have glyphs occupying two cells.
    • add command-line option -class, which allows one to override xterm's resource class. Also add resource file UXTerm.ad, which simplifies using xterm for both 8-bit character sets and UTF-8.
    • fixes/improvements to OPT_TCAP_QUERY logic (patches by Bram Moolenaar, Stephen P Wall).

    Patch #140 - 2000/7/23 - XFree86 4.0.1

    • modify Makefile.in to circumvent GNU make's built-in suffix rule for ".sh" which confuses install.sh with the "make install" target (report/patch by Paul Gilmartin).
    • implement an experimental control sequence which an application may use to query the terminal to determine what sequence of characters it would send for a given function key. This is ifdef'd with OPT_TCAP_QUERY (request by Bram Moolenaar).
    • add /usr/local to search path in CF_X_ATHENA configure macro to build with Xaw3d on OpenBSD (patch by Christian Weisgerber).
    • add missing #undef HAVE_TERMIO_C_ISPEED to xtermcfg.hin, omitted in patch #133 fix for IRIX 6.5 baudrate (report by Alain Filbois <Alain.Filbois@loria.fr>).
    • correct a few errors in xterm.man: font in filename example for Tektronix emulation, and description of -nul/+nul command-line options (report by Eric Fischer <enf@pobox.com>).
    • update config.guess and config.sub, from tin and lynx.

    Patch #139 - 2000/6/17 - XFree86 4.0d

    • back out change to -name command-line option, restoring its original behavior (as noted by David Madore, the correct interpretation of this option is the application instance rather than the application class).

    Patch #138 - 2000/6/15 - XFree86 4.0c

    • workaround for fixed fonts which are generated from Unicode fonts: they omit glyphs for some xterm's less-used line-drawing characters, which caused xterm to set a flag telling it to use only its internal line-drawing characters. Do not set the flag (it can be set from the popup menu), and xterm will generate only the line-drawing glyphs which actually are missing.
      Otherwise, when used for large fonts, xterm may generate a 2-pixel wide line, which can leave dots on the screen.
    • restore first line of 256colres.pl, omitted in 4.0c diffs.

    Patch #137 - 2000/6/10 - XFree86 4.0b

    • make command-line -name option work as documented. Apparently this was lost in X11R5 when coding to use XtAppInitialize.
    • limit numeric parameters of control sequences to 65535 to simplify checks for numeric overflow.
    • change index into UDK list to unsigned to guard against numeric overflow making the index negative (Taneli Huuskonen <huuskone@cc.helsinki.fi>).
    • change sun function-keys resource name to sunFunctionKeys to work around redefinition of the token sun by xrdb on Solaris. Similarly, renamed resource sun keyboard to sunKeyboard (Stephen P Wall).
    • change similar resource names for HP and SCO to avoid potential conflict with xrdb symbols on other systems, as well as for consistency.
    • reorganized the install targets in the autoconf'd Makefile, adding install-app, install-bin, install-dirs and install-man. The app-defaults class can be overridden by setting the make variable 'CLASS', simplifying customization of xterm as a Unicode terminal, e.g., CLASS=UXTerm.
    • add limit checks to ClearInLine(), ScrnInsertChar(), ScrnDeleteChar() to correct potential out-of-bounds indexing (prompted by Debian bug report #64713, which reported a problem with ICH escape sequences).
    • updates to config.sub and config.guess Kevin Buettner <kev@primenet.com> for elf64_ia64 Bernd Kuemmerlen <bkuemmer@mevis.de> and MacOS X.
    • for os390, add check for errno set to ENODEV on failure to open /dev/tty when there is no controlling terminal (patch by Paul Gilmartin).
    • fixes for building on Digital Unix 4.0 and AIX 4.2 (patch from H Merijn Brand <h.m.brand@hccnet.nl>).
    • modify DECRQSS reply for DECSCL to additionally report if the terminal is set for 8-bit controls.

    Patch #136 - 2000/6/3 - XFree86 4.0b

    • add a resource (limitResize) limiting resizing via the CSI 4 t and CSI 8 t sequences.
    • ignore out-of-bounds resize requests, i.e., where sign-extension or truncation of the parameters would occur.

    Patch #135 - 2000/5/29 - XFree86 4.0b

    • remove code introduced in #134 which made some backgrounds bold.
    • minor correction to format of updated $TERMCAP when adding kb capability for ptyInitialErase logic.
    • improved test for SVR4 definition.

    Patch #134 - 2000/5/28 - XFree86 4.0b

    • update URL's and mailing addresses, moved to http://dickey.his.com and dickey@herndon4.his.com
    • correct missing quotes in CF_TTY_GROUP configure script macro in case the script is run in batch mode.
    • modify ownership-check of log file to ignore the group ownership. Otherwise xterm cannot create logfiles in directories with set-gid permissions.
    • simplify the logic that reads termcap data.
    • add fallback definition for B9600 in case line speed definition for 38400 is missing (report by Jack J Woehr <jwoehr@ibm.net>, for OpenBSD 2.6).
    • fix: Set highlightColor, and select a region containing the text cursor. If the window loses focus, the cursor becomes hollow, with the region inside the cursor being background/foreground, unlike the rest of the selection, which is foreground/highlight (patch by Ross Paterson <ross@soi.city.ac.uk>).
    • add configure script tests to define SVR4, SYSV and USE_POSIX_WAIT, which enables xterm to compile on Solaris 7 and SCO Openserver without imake, though there are still a few features for the latter which require sco to be predefined.
    • patches from Stephen P Wall:
      • add support for two Sun-specific function keys. These keys are labeled F11 and F12 on Sun Type 5 keyboards, but return SunXK_F36 and SunXK_F37. Support will only be compiled in if the header file <X11/Sunkeysym.h> exists and contains the appropriate symbol definitions. The keycodes for the DEC keycodes were arbitrary unused codes, but the ones for the Sun keycodes are what cmdtool and shelltool actually send.
      • add colorRV and colorRVMode resources to allow specifying a color to use for reverse video, similar to the existing UL, BD, and BL modes.
      • add alwaysUseMods resource, to override check if alt or meta modifiers are used in translations resource. Revamped the code to calculate the modifier value, and included Meta if alwaysUseMods is TRUE, using values 9-16.
    • fixes for os390 (Paul Gilmartin):
      • regularize the definition of CONTROL() and remove an acknowledged "trial and error" table.
      • translate "^?" into A2E(0177) which is the EBCDIC "DEL" rather than plain 0177 which is the EBCDIC quotation mark.
      • modify xtermMissingChar() so that EBCDIC codes 128-159 are not rendered as blanks by X server running on Solaris, which sees those as control characters.
      • make debugging traces (configure --enable-trace) work properly with EBCDIC.

    Patch #133 - 2000/5/2 - XFree86 4.0a

    • add substitutions in autoconf'd Makefile for CPPFLAGS, LDFLAGS and AWK (reported by Neil Bird).
    • correct uninitialized childstat variable from patch #131 in creat_as() function, which caused logging to not work on Solaris, whose waitpid() function does not initialize its parameter. Add check for EINTR on return from waitpid() as well (reported by Neil Bird <neil.bird@rdel.co.uk>).
    • remove a redundant check for working setuid() function introduced in patch #132. Greg Smith reports that this does not work as intended on os390.
    • change line speed from 9600bd to 38400bd, to accommodate people who mistakenly use $TERM set to vt100, to reduce the effect of padding associated with this terminal type.
    • add configure script check for IRIX 6.5's redefinition of baud rates associated with struct termio, to correct a situation where the baud rate was initialized to zero (reported by Andrew Isaacson <adi@lcse.umn.edu>).
    • remove unused configure script check for VDISABLE.

    Patch #132 - 2000/4/11 - XFree86 4.0a

    • undo an incorrect change from patch #113 caused the right scrollbar to be positioned incorrectly when re-enabling it (analysis by D Roland Walker).
    • add ctrlFKeys resource, replacing constant for adjusting control-F1 to control-F12 to VT220-style F10-F20. The resource changes the constant 12 to a default value of 10 (request by Jim Knoble <jmknoble@pobox.com>).
    • correct ifdef'ing for conflict between definitions in AIX's <sys/select.h> and <X11/Xpoll.h> (reported by Clint Olsen).
    • add checks for return-values of getutid(), initgroups() and setuid() in main.c, as well as modifying ifdef's for __osf__ to include tty-group and WTMP logic (adapted from patch by Paul Szabo <psz@maths.usyd.edu.au>)
    • modify resize.c to build and work on os390 (uses EBCDIC) (adapted from patch by Phil Sidler <Phil.Sidler@airborne.com>)
    • use Ires(), Bres() and Sres() macros to simplify resource list in charproc.c
    • resync with XFree86 4.0a:
      • correct a typo in os2main.c (Holger Veit, from 4.0a).

    Patch #131 - 2000/3/3 - XFree86 3.9.18b

    • improve logfile security (integrated patch by Branden Robinson)
      • make the creat_as() function more strict by using O_EXCL rather than O_APPEND.
      • fixes to make DEBUG ifdef's compile/run, including making the debug logfile more unique by appending a timestamp to its name.
      • include <term.h> in resize.c, to fix a missing-prototype warning.
    • modified creat_as() a little more, retaining the ability to append to a logfile If the user specifies the name. Also, check if the opened file (which patch #130 ensures is owned by the effective user) is not writable by other users.
    • use creat_as() logic to make tek4014 screen-copy more secure (noted by Branden Robinson).
    • ifdef'd some of Branden's changes to build/work on older machines.
    • correct missing initialization of the .mode flag in ColorRes struct, from patch #129. This worked on Linux because malloc() zeroes memory on that platform (reported by Christian Weisgerber).
    • modify logic for deleteIsDEL resource so it has internally 3 states: unspecified, true and false. If unspecified, the keyboard type determines whether the Delete key transmits <ESC>[3~ or \177, and the popup menu entry reflects the internal state. Otherwise, the popup menu entry overrides the keyboard type (suggested by Dr Werner Fink, to make it simpler to set resources that imitate the legacy X11R6 xterm).

    Patch #130 - 2000/3/1 - XFree86 3.9.18a

    • modify scroll-forw() and scroll-back() actions, adding a third parameter which will direct xterm to ignore the action when mouse reporting is enabled. This is needed for the wheel mouse to be used to report to the application rather than scroll the window.
    • add menu entry and action to allow disabling xterm's assumption that the current font contains line-drawing characters if the font cells 1-31 are nonempty. Some fonts may have other characters (reported by Bruno Betro <bruno@iami.mi.cnr.it>).
    • add a check in creat_as() to ensure that the user really owns the logfile that has been opened.
    • add logic to implement SCO function-keys. (This is really incomplete, since I intend to revisit this and make xterm able to emulate scoansi better than just the function-keys).
    • add configure script option --enable-sco-fkeys, minor related fixes (patch by Dr Werner Fink).
    • fix typos in ctlseqs.ms (reported by Bram Moolenaar)
    • fix typo in sinstall.sh default for $TST_PROG (reported by Paul Gilmartin <pg@sweng.stortek.com>)

    Patch #129 - 2000/2/26 - XFree86 3.9.18a

    • improve initialization of ANSI colors by delaying allocation until each color is first used.
    • remove ifdef that prevented colorBD/colorUL/colorBL resources from working when 256-color configuration was built (reported by Todd Larason).
    • fix some minor inconsistencies in terminfo (Debian #58530).

    Patch #128 - 2000/2/17 - XFree86 3.9.18

    • correct logic for oldXtermFKeys resource, fixes a core dump when attempting to set it from the command-line (reported by Dr Werner Fink).
    • correct ifdef for meta-sends-escap so configure --disable-num-lock builds.

    Patch #127 - 2000/2/12 - XFree86 3.9.17e

    • add resource, popup menu entry and control sequence to allow changing the Delete key to send either DEL or the VT220-style Remove escape sequence.
    • remove logic for metaSendsEscape that would allow xterm to send <ESC>[3~ before a function key that would begin with <ESC>[3~ (request by Christian Weisgerber).
    • add missing action and documentation for meta-sends-escape.
    • correct a few typos in ctlseqs.ms (incorrect code for Cyan color)

    Patch #126 - 2000/2/8 - XFree86 3.9.17c

    • ensure that xterm will automatically activate the UTF-8 mode whenever the name of the locale environment variable suggests that a UTF-8 locale is in use (patch by Markus Kuhn). This will help that by simply setting LC_CTYPE an entire system can be switched over to UTF-8, without users having to remember the UTF-8 command line options ("-u8", etc.) of the various applications. Command line options and X resource entries can still be used to override this default choice.
    • add old function-keys control sequences and popup menu entry, for compatibility with legacy X11R6 xterm.
    • revert translation of editing keypad "Delete" key to legacy \177.
    • simplify the color-resource data expressions with macro COLOR_RES, for later use in restructuring color initialization.
    • change encoding of wheel mouse (buttons 4 and 5) to avoid conflict with legacy mouse modifiers (suggested by Bram Moolenaar).

    Patch #125 - 2000/1/31 - XFree86 3.9.17c

    • make this work on OpenVMS (integrated patch by David Mathog).
    • rename some functions, e.g., Index to xtermIndex so that ports such as VMS which link externals ignoring case will not have library conflicts (reported by David Mathog).
    • correct logic of do_reversevideo(), which did not update the corresponding popup menu check mark (reported by David Mathog, this was a detail overlooked in patch #94).
    • change TRACE macro so semicolon is not within definition, making indent and similar programs work better.
    • add depend rule to Makefile.in
    • modify logic of boldColors resource to suppress it if an extended color control has been used, e.g., for 88-color or 256-color mode (patch by Todd Larason).
    • revise logic that handles menus and input translation for keyboard type so only one can be selected at a time.
    • restore kdch1=\177 for the Sun function-key type, and make the the Delete key send DEL (\177) if the oldXtermFKeys resource is set.
    • rephrase logic and ifdef's for POSIX VDISABLE to avoid preprocessor expression that will not compile on NetBSD/x86 1.4.1 (reported by Takaaki Nomura <amadeus@yk.rim.or.jp>).

    Patch #124 - 2000/1/27 - XFree86 3.9.17b

    • change coding of editing keypad's "Delete" key to <escape>[3~, in the default (Sun/PC) keyboard mode. This makes the terminfo kdch1 capability independent of the coding of the backarrow key, which sends either backspace (8) or DEL (127). The reason for doing this (compatibility with the screen program) outweighs the choice of DEL (127) which was used in X11R5/X11R6 xterms. The screen program translates whatever matches kdch1 into <escape>[3~, even if it happens to be the stty erase character.
    • add encoding for control/?, to work around xmodmap or key translations which may confuse backspace and delete. A control/? will send DEL (127), and a control/H will of course send backspace (8).
    • add encoding for kcbt to <escape>[Z (fixes Debian #54840).
    • minor correction to logic that encodes Sun and DEC function keys to avoid sending an escape sequence if the key symbol is not found in xterm's lookup table.
    • simplify ifdef's in main.c for POSIX VDISABLE so the "^-" pattern is more likely to be implemented when imake configures xterm (fixes Debian #55105).
    • change manpage to make it clearer what codes are sent by the backarrow key.

    Patch #123 - 2000/1/22 - XFree86 3.9.17a

    • add a note reserving OSC 51 for use in Emacs shell (request by Rob Mayoff <mayoff@dqd.com>).
    • correct a missing backslash in xterm-vt220 termcap.
    • cleanup remaining quoted includes, preferring bracketed form.
    • minor configure-script macro updates from tin and vile.
    • add configure-script option for using utempter library, adapted from Redhat 6.1 patch for XFree86 3.3.5
    • resync with XFree86 3.9.17a:
      • correction to QNX support (Frank Guangxin Liu)
      • some cosmetic changes that did not correct any reported problems.

    Patch #122 - 1999/12/28 - XFree86 3.9.16f

    • move the suggested wheel-mouse button translations into charproc.c to simplify customization. Correct some minor logic errors in the support for buttons 4 and 5, used for wheel mice (reported by Bram Moolenaar).
    • implement metaSendsEscape resource, with corresponding control sequence and menu entry. Like eightBitInput, this causes xterm to send ESC prefixing the given key, but applies to all keys and is independent of the 8-bit/7-bit terminal setting. (requests by Alexander V Lukyanov and Marc Feeley).
    • correct potential indexing with negative subscript in udk_lookup(), (reported by Ian Collier <Ian.Collier@comlab.ox.ac.uk>).
    • modify configure script that sets TERMINFO_DIR to use ${prefix} rather than /usr if the --prefix option was specified (request by Zdenek Sekera <zs@sgi.com>).
    • modify checks for repeat-character control sequence to test the character class against xterm's state table, rather than the isprint() macro (patch by Alexander V Lukyanov).
    • change several functions to macros to improve speed
    • two corrections to simulation of bold font via overstriking:
      • use clipping to avoid leaving trash at end of the text, and
      • add brackets so wide-character logic does not fall-through into the overstriking logic (reported by Marc Feeley <feeley@IRO.UMontreal.CA>)
    • add several entries to termcap file to make it have the same set of aliases as the terminfo file.
    • scale the color values used for xterm-256color terminfo entry to 0..1000, as expected by ncurses.
    • change xterm-r6 terminfo definitions for F1-F4 to match program.
    • Add QNX/Neutrino support (Frank Guangxin Liu <frank@ctcqnx4.ctc.cummins.com>)

    Patch #121 - 1999/11/14 - XFree86 3.9.16c

    • change label on "Sun/PC Keyboard" popup menu entry to "VT220 Keyboard", since the checked state corresponds to VT220 rather than Sun/PC.
    • add configure test CF_UTMP_UT_XSTATUS to handle the variants of utmp exit status (reports by Dave Ellement, Jeremie Petit, Tomas Vanhala).
    • amend treatment of ALT key (see patch #94) so that if ALT is used as a modifier in key translations, then no parameter will be sent in escape sequences for Sun/PC function keys (request by Dr Werner Fink).
    • modify default for OPT_I18N_SUPPORT to assume that XtSetLanguageProc() is available in X11R5.

      Caveat: XtSetLanguageProc() was added fairly late in the X11R5 patches, and some vendors shipped buggy versions of this function (request by Tomas Vanhala).

    • correct configure macro CF_SYSV_UTMP to test-link with functions consistent with the header, e.g., getutent() for utmp.h and getutxent() for utmpx.h (reported by Greg Smith).
    • modify terminfo entry for xterm-xfree86 to reflect modifiers for shift and control (from a patch by Alexander V Lukyanov).
    • modify terminfo entry for xterm-sun to match the function-key definitions in ncurses. The pageup/pagedown and related function keys correspond to the Sun keyboard, which does not necessarily correspond with X's notion of those keys.
    • modify treatment of XK_Delete keysym so it transmits parameterized VT220-style <ESC>[3~ if modifiers (shift, control alt) are given (request by Alexander V Lukyanov).
    • corrected misspelled resource name in command-line option for HP function keys.

    Patch #120 - 1999/10/28 - XFree86 3.9.16c

    • refine the change to SGR_Background() in patch #119, by not flushing the pending scrolling operation if the background color is not actually changing. This combination occurs when using color-ls to display a long listing, since each line ends with an SGR0 which affects only the foreground color. The unnecessary flushing made it noticeably slower (reported by D Roland Walker <walker@pobox.com>).
    • remove obsolete documentation about modifiers which can be returned in mouse tracking mode, and modify logic to ignore modifiers other than the existing ones, e.g., NumLock (prompted by discussions with Christian Weisgerber and Brad Pepers <brad@linuxcanada.com>).
    • use free bit from obsolete shift-modifier coding of mouse tracking button events to encode buttons 4 and 5, e.g., for a wheel mouse (requests by Brad Pepers and Bram Moolenaar).
    • correct a place where the ptyInitialErase logic did not set the backarrowKey state, and modify it further to use tgetstr() rather than parse the termcap data returned from tgetent() so the ptyInitialErase logic will work when xterm is linked with a terminfo library (based on a patch by Dr Werner Fink <werner@suse.de>).
    • fix definition of HAVE_UTMP_UT_HOST for ISC configuration (patch by Michael Rohleder).
    • improve configure script's utmp tests (based on reports by Greg Smith for os390, and David Ellement for HPUX).
    • modify sinstall.sh to use uid=0 rather than 'root' to determine if the installer is privileged. This is needed on some systems since more than one account may be privileged (report by Greg Smith).
    • add an application resource, messages (and a corresponding -/+mesg option) which controls the initial permission on the terminal: if messages is set to true (the default), behavior is as without the patch; if it is set to false (as per -mesg), the terminal is opened in mode 0600, thus producing the effect of the mesg n command. This is useful for users who want to redirect all their messages to one particular xterm: it is more pleasant to do this with xterm resources than with explicit calls to the mesg program (patch, description by David Madore <david.madore@ens.fr>).

    Patch #119 - 1999/10/16 - XFree86 3.9.16c

    • add responses (DA and DSR) for DEC locator mode
    • add coding for ANSI color to DA response
    • implement UTF-8 translation for Media Copy (print) operations.
    • implement vt320 control sequences for Print Composed Main Display and for Print All Pages. The latter directs xterm to print the current screen as well as the scrollback buffer.
    • correct error in _GNU_SOURCE configure test, which left it always defined.
    • add more information, i.e., with strerror for some system calls in the main program which may fail due to insufficient permissions (prompted by a problem report for -C by Jeremie Petit <Jeremie.Petit@digital.com>).
    • add workaround for conflict between <X11/Xpoll.h> and <sys/select.h> on AIX 4.3 (Richard Griswold <griswold@acm.org>).
    • add configure script test to resolve conflict between between <X11/Xpoll.h> and <sys/select.h>
    • modify translation of UTF-8 sequences to reject "overly long" variations (patch by Markus Kuhn).
    • remove utf8controls resource, since Markus' change removes the corresponding logic.
    • correct a case where colors were not rendered properly. This happened when an application inserted several lines, then changed colors. If this was done all in one write, then there would be no intervening refresh, and the new color was applied to the pending scrolling operation which was awaiting the next refresh (reported by Stephane Chazelas <Stephane_Chazelas@Raytheon.com>).

    Patch #118 - 1999/10/5 - XFree86 3.9.16b

    • refine configure test for utmp versus utmpx, to build on HP-UX 10.x (reported by David Ellement).
    • move the configure check for const after the check for ANSI C compiler options, since those may be required to make it work properly on HP-UX.
    • add configure test for defining _GNU_SOURCE
    • correction to -hold option, ensure that if data is already in the output buffer that it will be displayed before closing the PTY.
    • move the configure checks for setuid install of xterm into a script to avoid installing it setuid'd to a non-root user (reported by Adam Sulmicki <adam@cfar.umd.edu>).
    • correct configure script's check for termcap.h to avoid using ncurses' version of it on systems that have a working tgetent() function. This is needed to make resize work properly.
    • fix some typography in ctlseqs.ms description of DEC locator events (reported by Stephen P Wall).

    Patch #117 - 1999/9/29 - XFree86 3.9.16b

    • change order of tests in configure script for utmp and utmpx to test utmpx first, to compile on Solaris (reported by Leena Heino <liinu@uta.fi> and Patrik Hagglund <patha@ida.liu.se>).
    • add a configure test for utmp.ut_xtime, needed for SCO Openserver, and for lastlog, needed for Redhat 6.0, to refine the utmp/utmpx auto-configure.
    • remove a spurious comma in an #undef (reported by David Green <greendjf@cvhp152.marconicomms.com> and David Ellement <ellement@sdd.hp.com> both on HP-UX, whose compiler does care about syntax).
    • change ifdef's using __CYGWIN32__ to __CYGWIN__ (reported by Suhaib M. Siddiqi <Ssiddiqi@InspirePharm.Com>, who is told that the next Cygnus release will drop that symbol in their next release).
    • minor cleanup of ifdef's for makeColorPair (patch by Stephen P Wall).
    • work around problem observed in XFree86 3.3.5 (patch by Alexander V Lukyanov, Redhat #5419). From the problem report:

      xterm consumes cpu when selecting text with mouse (holding down left mouse button) and when a program working under the xterm outputs something to stdout.

      Easy way to reproduce:
      while :; do echo aaa; sleep 1; done
      (while this runs, select text and hold down left mouse button) watch cpu load.
      release left mouse button - spinning stops.

    Patch #116 - 1999/9/25 - XFree86 3.9.16a

    • modify warning if change-ownership of PTY fails; some configurations may not happen to have old-style pty's (reported by Bob Maynard).
    • improve check in configure script for group ownership of installed xterm; some platforms use the -g option of ls to toggle group off rather than on (reported by Greg Smith).
    • minor improvement to toolbar geometry, to make it not resizable. This still is not satisfactory (but is usable) since the toolbar overlaps the xterm widget if the window is resized to make it smaller. It appears that some work is needed for the xterm widget's geometry management to make it function properly.
    • implement configure script tests for utmp, tty group.
    • implement -hold option, allowing users to retain the window after a shell has exited (this is recently an FAQ, but prompted by a comment by Joachim Plaettner-Hochwarth <plaettner@aem.umn.edu> in comp.unix.programmer, that the IRIX winterm provides this option).
    • add support for DEC Locator control sequences for xterm (integrated patch by Stephen P Wall):
                      DECEFR, "Enable Filter Rectangle"
                      DECELR, "Enable Locator Reports"
                      DECSLE, "Select Locator Events"
                      DECRQLP, "Request Locator Position"
      

      This allows the xterm mouse to be used with applications that use the DEC Locator sequences, such as VAX Tpu, or SMG$ based applications.

    • improve print action (patch by Matthias Baake). From his notes,
      • Bug 1
        Underlined text is preceded by ESC [0;2m . This should be ESC [0;4m , ESC [2m doesn't seem to have any effect. (print.c/send_SGR)
      • Bug 2
        The check for the last non-empty column (while (last > 0) ... in print.c/printLine) omits the rightmost column of the screen, the loop must start with last = screen->max_col+1 instead of last = screen->max_col.
      • Bug 3
        Any attributes of the first character (and of all immediately following characters with the same attributes) are ignored. The variable attr (print.c/printLine) should be initialized with 0, not with *a & SGR_MASK.

    Patch #115 - 1999/9/18 - XFree86 3.9.16a

    • integrated changes by Stephen P Wall to implement an 88-color model for systems where 256-colors cannot be allocated.
    • when 256-color configuration is compiled, colored bold and underlining is not available; ifdef'd to avoid possible odd effects in this case (reported by Stephen P Wall).
    • add resource cacheDoublesize, to limit the caching of font information for double-sized characters. This addresses a problem reported by Aryeh Koenigsberg for X terminals with limited font memory.
    • modify treatment of line-drawing characters in UTF-8 mode so that the Unicode values are used rather than the C0 codes for storing the translated characters (request by Markus Kuhn).

    Patch #114 - 1999/9/15 - XFree86 3.9.16

    • add configure script checks for Athena headers and libraries under /usr/contrib to work on HPUX (reported by several people: David Nixon <djn@csc.liv.ac.uk> Aryeh Koenigsberg <aryeh.koenigsberg@telrad.co.il> Johannes Mähner <johanm@camline.com> Andrew Gaylard <andrew.gaylard@bsw.co.za>).
    • add check to configure script if xterm is installed setgid rather than setuid, since wtmp and utmp may be installed with group-writable permissions other than root (based on Debian bug report #7112 by Bo Branten <bosse@ing.umu.se>).
    • rewrote logic that removes data from termcap entry, e.g., for titeInhibit, to make it less likely to remove the wrong data.
    • correct logic which checks for missing characters used for line drawing. The 0 character was tested unnecessarily, leading to some inefficiency when rendering.
    • change termcap capability which is used as input or output of ptyInitialErase logic from kD to kb. Christian Weisgerber <naddy@mips.rhein-neckar.de> pointed out in effect that kD (in terminfo kdch1) should correspond to the control sequence for dch1, which deletes from the current position toward the right.
    • check for failure to change ownership of the PTY device and warn when xterm is running setuid'd to root. This was reported to happen on the FreeBSD/NetBSD/OpenBSD systems as a result of the chflags() call.
    • add xterm-noapp terminfo entry to illustate a nominally bash-compatible terminal description.

    Patch #113 - 1999/8/15 - XFree86 3.9.15b

    Several fixes. The main one is a first draft of pulldown menus. It's not complete (I have some minor/annoying geometry problems to correct), but is usable. Once it's complete I plan to add a menu to support additional selections that won't fit on the current popup menus. Also, this fits into my longterm plan to allow configuring with Motif libraries.

    • correct error in input conversion for NRC mode (reported by Stefan Traby <stefan@sime.com>).
    • fix initialization of num_lock data in Misc struct (since those fields of the reference widget aren't initialized), and add logic to deal with XVision whose NumLock key does not transmit but does alter keypad state.
    • correct a missing return-value in get_pty(), for SCO
    • add E2A fix for backspace (patch by Greg Smith), i.e.,
      #define VAL_INITIAL_ERASE A2E(127)
    • correct foreground color within cursor outline when the window is unfocused (reported by Stephane Chazelas).
    • corrected position of scrollbar set in ResizeScrollBar(), which left it positioned incorrectly if the right scrollbar were enabled from the popup menu but was not initially enabled.

      I have noticed some additional problems with right-scrollbar on X11R5 which I will correct later.

    • integrate changes by Jean-Claude Michot for QNX from XFree86 3.3.4c
    • add resources menuBar/MenuBar, menuHeight/MenuHeight for later use in toolbar geometry.
    • add configure option --enable-toolbar
    • add missing definition to make ziconbeep logic not compile-in when configure script disables it.
    • add configure-check for input-method support in X libraries

    Patch #112 - 1999/7/17 - XFree86 3.9Pw

    • add null-pointer check to FlushLog(), fixes a core dump when both -l and -lf options are used when xterm is configured with wide-character support.
    • remove "ISO" case for SD, which was due to a typographical error in ECMA-48 (reported by Paul Williams <paul@celigne.co.uk> for vttest).
    • add "FILES" section to manpage.
    • generate header file to initialize default resources for colors 16-255.
    • fixes for os390 (Greg Smith):
      • add README.os390
      • use the pty_search() function to find an available pty/tty pair.
      • move E2A() call out of getXtermCell() to SaveText() function so it will be available in all configurations.
    • patches by Todd Larason:
      • enable SGR 48 5 in ISO color mode, not just 256 color mode
      • change configure's --disable-256-color option to --enable-256-color, to match its effect
      • fix OSC 4 xx ? (report ansi color) to report a string which can actually be used to set the color back
      • fix OSC 4 xx yy (change ansi color) to not allow setting colors > 15 in 16 color mode
      • simplify the COLOR_ settings a bit in ptyx.h, along with setting NUM_ANSI_COLORS needed for #1 and #4 above
      • correct string-terminator code passed for reference to OSC responses; when in 7-bit mode, only the final byte of ST was seen.
      • Allow multiple color #;name pairs in OSC 4, and document changes to match.

    Patch #111 - 1999/7/10 - XFree86 3.9Pw

    • add control sequences for specifying the RGB value of the ANSI colors, and for configuring with 256 colors (patch by Todd Larason <jtl@molehill.org>). I made the default configuration to 16-colors, because xterm uses the default color map (which has only 256 colors).
    • correct an error in DCS $ q m reporting for colors 8-15 (Todd Larason).
    • add test/demo script for double size characters. Used this to test/correct display of double size characters that should wrap, underlined double size characters.
    • increased cache size for double size fonts to 8, to allow for both normal and bold fonts (discussion with Aryeh Koenigsberg <aryeh.koenigsberg@telrad.co.il>).
    • add fixes for port to OS390 aka MVS (integrated patch from Greg Smith <rys@epaibm.rtpnc.epa.gov>). OS390 uses EBCDIC rather than ASCII.
    • correct an off-by-one in binary search limits in keysym2ucs.c (Markus Kuhn).
    • implement logging for UTF-8 mode. The output is written in UTF-8 form.

    Patch #110 - 1999/6/29 - XFree86 3.9Pu

    • If colorMode is enabled by default, compile-in default resources to match the colors listed in XTerm-col.ad (this should fix a longstanding FAQ).
    • added new OSC 3 ; PROPNAME=VALUE ST escape sequence to set an arbitrary X property on the top level xterm X11 window. Omit "=VALUE" to delete the X property (patch by Greg Badros <gjb@cs.washington.edu>).
    • change internal flag used for utf8controls resource so we allow 31-bit range of characters (suggested by Thomas Wolff).
    • add check for 16-bit characters in OSC strings, change them to '?' (reported by Thomas Wolff).
    • modify logic of same_font_name() to avoid trying to interpret both parameters as wildcard patterns. That does not (cannot) work, and in some instances the font server will return unresolved wildcards for the normal or bold fontnames, making them match inadvertently, triggering the fallback overstrike logic (reported by Tim Adye).

    Patch #109 - 1999/6/23 - XFree86 3.9Pt

    • correct range-check from patch #108, which resulted in not being able to select from the scrollback buffer (reported by Tim Adye <T.J.Adye@rl.ac.uk>)
    • correct "no available ptys" problem with Cygwin B20.1 (patch by Tim Adye).
    • modified install-ti rule in Makefile.in to allow override of the terminfo directory when doing a "make install", i.e., by assigning to TERMINFO_DIR (request by Zdenek Sekera <zs@sgi.com>).
    • added install-full rule to Makefile.in
    • resync mkdirs.sh and install.sh scripts against current autoconf
    • implement $(DESTDIR) in Makefile.in, making it simple to install xterm and associated files into a directory just for packaging a binary release (suggested by CaT <cat@zip.com.au>).
    • change IChar type to unsigned, rather than unsigned short, making room for a flag to keep with 16-bit characters to prevent them from being interpreted as C0 or C1 controls (reported by Thomas Wolff).
    • correct a typo from patch #107, incorrect array name, in the filterUTF8 function (patch by Bruno Haible <haible@ilog.fr>)
    • add utf8controls resource to specify whether xterm should interpret 16-bit characters unpacked from UTF-8 form as control characters if they happen to fall into that range. This behavior is left unspecified by the Unicode standard (request by Thomas Wolff).
    • modify handling of OSC to recover if application sends 16-bit characters with codes above 255. We cannot display them as is, but translate out-of-range characters to a '?' (reported by Thomas Wolff).

    Patch #108 - 1999/6/19 - XFree86 3.9Ps

    • add a range-check to LastTextCol(), to guard against indexing before the beginning of the scrollback buffer. This appears to happen with certain fonts under X11R5 (reported by Stephane Chazelas <Stephane_Chazelas@Raytheon.com>).
    • implement resource boldMode, to allow disabling the simulation of bold fonts when the bold and normal fonts are not different (requested by Will Day <willday@rom.oit.gatech.edu>).
    • change the atom "UTF-8" to "UTF8_STRING", and fixes a few bugs in the UTF-8 selection (patch by Juliusz Chroboczek).
    • correct logic of binary-search in keysym2ucs.c (patch by Markus Kuhn).
    • add special interpretation of keysym codes above 0x1000000 as the corresponding UCS value plus 0x1000000 (patch by Markus Kuhn).

    Patch #107 - 1999/6/12 - XFree86 3.9Pq

    • Two changes from Stephen P Wall. From his description:

      The first change is simple - I added ESC[3J to erase the stored lines above the screen. That's what the changes to util.c and ctlseqs.ms are.

      The second change is to get the blinking cursor working. I took out the cursorBlinkTime resource, and put in cursorBlink (Boolean), cursorOnTime (time cursor is on in msecs) and cursorOffTime, and added a cursorblink item to the vtMenu to enable/disable it.

    • improve selection (integrated patch by Juliusz Chroboczek). From his description:

      With this patch, selection conversion works properly:

              ISO 8859-1 xterm -> ISO 8859-1 xterm (transferred as STRING);
              ISO 8859-1 xterm -> UTF-8 xterm (transferred as STRING);
              UTF-8 xterm -> ISO 8859-1 xterm (transferred as STRING);
              UTF-8 xterm -> UTF-8 xterm (transferred as UTF-8).
      

      It will not work properly if one xterm is in, say, ISO 8859-2. Actually, for this case xterm breaks the ICCCM routinely (sending ISO 8859-2 data as STRING), so I wouldn't worry too much about it. I have not changed the behaviour in eight-bit mode in any way.

    Patch #106 - 1999/6/9 - XFree86 3.9Pq

    • remove duplicate fix for OpenBSD in resize.c
    • correct logic in ScreenWrite, which did not reset the high bytes of 16-bit characters when overwriting them with a 8-bit character string (reported by Thomas Wolff).
    • provide limited support for input of UTF-8 16-bit data by a lookup table (integrated patch by Markus Kuhn).
    • correct check in non_blank_line to ensure we're in wide-character mode before looking at the high bytes, for InsertChar.

    Patch #105 - 1999/6/5 - XFree86 3.9Pp

    • implement new resource trimSelection, which allows xterm to trim trailing blanks from selected lines. This does not affect the highlighting. (reported by several people using mutt, including Hans Morten Kind <edphk@uib.no>, Jeremy <jeremy@exit109.com> and (Michael Fuller <msf@mds.rmit.edu.au>).
    • include term.h in resize for OpenBSD (patch by Matthieu Herrb).
    • correct logic for UTF-8 in functions that hide and show the cursor; it was displaying a space whenever the low byte of the character at the cursor position was zero (reported by Thomas Wolff <Thomas.Wolff@icn.siemens.de>).

    Patch #104 - 1999/5/30 - XFree86 3.9Pn

    This is a resync patch against XFree86 3.9Pn, reflecting changes which were submitted by Branden Robinson, who worked with Wichert Akkerman <wichert@cs.leidenuniv.nl> to set up ifdef's to handle GNU libc 2.1, and use getpt() which lets xterm avoid having to know the actual PTY name.

    I have also added a few fixes for signed/unsigned mismatches, and corrected a problem in the configure script (the UTF-8 code was always configured since the Imakefile defines this).

    Patch #103 - 1999/5/14 - XFree86 3.9Pm

    • correct selection logic: I omitted an offset that accounts for the distance into the scrollback buffer when rewriting this for patch #101. Also fixed a similar problem for selecting double size characters from the scrollback buffer (first was reported by D Roland Walker <walker@pobox.com>).
    • improved support for Unix98 PTY's, using patch in Debian bug report #35650, by J.H.M. Dassen <jdassen@wi.leidenuniv.nl>. From the patch description:
      • No longer links xterm against libutil on a glibc2.1 system. libutil is a compatibility library and should only be used when necessary. Rather than having get_pty() use openpty() from this compatibility library, use the real UNIX98 pty support in get_pty() (open()ing the master pty, through getpt() if available (glibc extension)). Use openpty() only under glibc2.0.
      • GNU libc2 is not Linux-specific; already it runs on the Hurd. It provides the UNIX98 pty functions (plus the getpt() extension), regardless of the underlying OS. Changed two constructs to look for GNU libc2 only, not GNU libc2 on Linux.
    • improve font configuration, by checking if the user's resource settings for normal and bold fonts give the same font sizes (fixes problem reported by Peter Waltenberg <peterw@dascom.com>).

    Patch #102 - 1999/5/12 - XFree86 3.9Pm

    • revert change to openpty call in patch #101; this causes xterm to fail on DEC-Alpha OSF/1 4.0B (reported by H Merijn Brand).
    • modify print.c to move include of stdio.h after the autoconf'd xtermcfg.h since HP's ANSI C compiler otherwise sees inconsistent prototype for getopt, probably due to problem with const (reported by H Merijn Brand).

    Patch #101 - 1999/5/10 - XFree86 3.9Pm

    • moved includes and definitions for 'select' from data.h to xterm.h to fix problem introduced by prototype for getPtyData, part of UTF-8 changes (reported by Jens Schleusener <Jens.Schleusener@dlr.de>)
    • added "Meta <Btn2Down>:clear-saved-lines()" default translation (patch by H Merijn Brand)
    • fixes to configure script and ifdef's in main.c to build on a HP9000/D390 (hppa-2.0w) running HP-UX 11.00 (64 bit) with egcs 1.1.2 and HP's ANSI C compiler (patch by H Merijn Brand <PROCURA_BV@CompuServe.com>)
    • add more parentheses in ifdef's (patch by Bob Maynard).
    • eliminate conflicting definitions for USE_TERMINFO in resize.c (reported by Jeremy Buhler).
    • change openpty call to pass NULL rather than ttydev parameter, since that was used only to estimate the length of the corresponding data, and may not really be long enough (reported by Andreas Jaeger)
    • update description in xterm manpage for character class table, which said it handles only 7-bit codes.
    • correct a typo in ScrnDeleteChar() which made it not clear the high byte of wide-character data.
    • add logic to convert selection to UTF-8 form when appropriate. This makes select/paste "work", but further work is needed to make UTF-8 recognized as a locale in Xlib.
    • correct right-limit check when selecting double-width characters.
    • change default answerback response to an empty string.

    Patch #100 - 1999/5/3 - XFree86 3.9Pl

    • Correct a typo in the default resource value for backarrowKeyIsErase: it was always true (reported by Bram Moolenaar).
    • improve configure script's test if the installed xterm is setuid, in case that is a symbolic link.
    • correct "install-ti" rule in Makefile.in, by not setting a blank $TERMINFO value. That is interpreted as "." by ncurses' tic.

    Patch #99 - 1999/5/2 - XFree86 3.9Pk

    • correct logic that computes num_ptrs count of the number of indices into the screen buffer. This is the maximum of the colors and character-set indices; was incorrect in patch #97.
    • correct argument type for sigsetjmp, incidental change in patch #96's Unix88 PTY patch (reported by Bram Moolenaar).
    • correct description of secondary DA in ctlseqs.ms (reported by Bram Moolenaar).
    • decouple the backarrowKey and ptyInitialErase resources by adding a new resource backarrowKeyIsErase, to accommodate people using applications which have hardcoded tests for characters 8 and 127 rather than relying on the stty settings.
    • modify the UTF-8 decoder so that all possible illegal UTF-8 sequences are properly represented by U+FFFD. This should be very helpful for developers of code that output UTF-8 strings for debugging. See the file utf-8-test.txt in http://www.cl.cam.ac.uk/~mgk25/download/ucs-fonts.tar.gz for a demonstration text that contains numerous illegal UTF-8 values. (patch by Markus Kuhn).
    • correct a place in ScrnRefresh where I was filling the high byte of a wide character with a space rather than a null (reported by Markus Kuhn).

    Patch #98 - 1999/4/26 - XFree86 3.9Pk

    • correct data manipulation in unparseputc(), broken for little-endian machines by patch #97's UTF-8 changes. This meant that keyboard input on SunOS did not work, though Linux i386 was fine.
    • modify initialization for backarrowKey and logic for initial-erase to prevent the initial-erase from overriding an explicitly set backarrowKey resource (reported by Vikas Agnihotri).
    • add a missing null-pointer check in ScrnRefresh, for the wide-characters configuration.

    Patch #97 - 1999/4/25 - XFree86 3.9Pk

    • add configure script test for -lutil, needed for openpty call when configuring xterm for Glibc-2.1 and Unix98 PTY's (first reported by Martin Lorentz" <m.lorentz@w12.link-goe.de>).
    • completely parenthesize ifdef expressions for Glibc (suggested by Bob Maynard).
    • add initial-erase options (-ie, +ie) to help message (reported by Vikas Agnihotri).
    • remove duplicate definition of USE_USG_PTYS (reported by Jeremy Buhler).
    • change termcap kD and terminfo kdch1 to a DEL (\177). I overlooked this when separating the styles of keyboard with the sunKeyboard resources in patch #94, so that it normally matches the value of the stty erase character:
      • Reported by Jae Gangemi <jgangemi@ccf.rutgers.edu>, this caused emacs to not process the DEL properly, combining it with succeeding characters.
      • This does not appear to be related to a problem which I have found with screen, which translates the stty erase into the termcap kD or terminfo kdch1 value (depending on how it is linked) if the $TERMCAP variable is set when screen is invoked.
    • add command-line options for enabling UTF-8 mode: -u8 and +u8. The more obvious -utf8 and +utf8 would conflict with xterm's -ut and +ut (utmp) options. The UTF-8 changes were requested by Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk>. This patch does not complete UTF-8 implementation, but makes it usable, i.e., display and refresh work, and I am able to display the test cases which Markus provides. More work is needed to complete this feature:
      • the control sequences for switching in/out of UTF-8 mode are partly implemented (don't use them). Similarly, the switching between vt100 and tek4014 emulations when UTF-8 mode is enabled will not work properly.

        You must use the -u8 command line option to use this feature, as well as compile with the OPT_WIDE_CHARS definition.

      • cut/paste only copies 8-bit characters.
      • logging is disabled in the wide-character configuration
      • printing only writes 8-bit characters.
      • input only does 8-bit characters. This is the area that I know least about.

    Patch #96 - 1999/4/19 - XFree86 3.9Pj

    • modify Makefile.in to work with configure script's --srcdir option. (patch by Jeremy Buhler <jbuhler@cs.washington.edu>)
    • add checks for 'echo -n' equivalent for 8colors.sh and 16colors.sh scripts (reported by Vikas Agnihotri).
    • improve logic that looks for bold fonts to allow for wildcards in the specification for normal fonts, and to ensure that if a bold font is specified as normal, that xterm will simulate a bold version of that using a one-pixel offset overstrike (reported by Henrik Harmsen <harmsen@erv.ericsson.se>).
    • correct horizontal spacing of double width line-drawing characters that xterm simulates.
    • improve support for Unix98 PTY's, using patch in Debian bug report #35650, by Topi Miettinen <Topi.Miettinen@medialab.sonera.fi>. Andreas Jaeger says this also corrects a permissions problem reported by cat@zip.net.au
    • modify initial-erase logic to ensure that ttyModes resource overrides it.

    Patch #95 - 1999/4/5 - XFree86 3.9Ph

    • modify primary DA response to allow a '1' parameter.
    • add printer and national replacement character sets to VT220 primary DA response.
    • document primary and secondary DA responses in ctlseqs.ms
    • use the patch number (e.g., 95) in the secondary DA response, providing user applications a means of determining the version of xterm for feature comparison (request by Bram Moolenaar).
    • make xterm respond to secondary DA when the decTerminalID is set for VT100.
    • limit user-defined keys (DECUDK) to VT220-style keyboard when sunKeyBoard resource is true.
    • modify ifdef's for Linux-2.2.x with Glibc-2.1 to work with Glibc-2.1 and no Unix98 PTY support (patch from Andreas Jaeger <aj@arthur.rhein-neckar.de>)
    • add optional feature (resource and command-line options) to make xterm use the PTY's sense of erase character on startup, rather than requiring it to be \177, or set the PTY's erase character to match xterm's configuration. Note that while $TERMCAP is modified to reflect the actual configuration, the terminfo kdch1 string is not (request by Dirk H Hohndel <hohndel@suse.de>)
    • improve scripts in vttests to work with newer shells that do not use 'echo -n'.
    • add fonts.sh example script
    • correct inequality in handling of "#1" font specification.
    • correct call to XGetWMNormalHints() used for computing maximum screen size; the size hints may not have been set.
    • begin implementation of support for wide-characters (configure option --enable-wide-chars defines OPT_WIDE_CHARS, invoke xterm with -wc option to activate this feature). This patch optionally widens internal data structures, invokes the 16-bit text output rather than the 8-bit version and adds some tables.

    Patch #94 - 1999/3/27 - XFree86 3.9Pf

    • further fixes for terminfo: ka1, ka3, etc., differ between the default xterm-xfree86 and xterm-vt220 entries.
    • change default (with sunKeyboard resource false) behavior of the editing keypad "Delete" to send a 127, like xterm-r6. The VT220-style <ESC>[3~ is sent when sunKeyboard is true (reported by Tomas Vanhala).
    • add parameters to function keys to indicate if shift, control or alt are set. The codes are based on a description of a DEC VT510 with a PC keyboard, from Jeffrey Altman <jaltman@watsun.cc.columbia.edu>.
    • add control sequence 1035, set-num-lock action and num-lock menu entry to control the use of the NumLock and Alt keys for the Sun/PC and VT220 keyboard extensions.
    • implement DECSET/DECRST numeric keypad (DECNKM) mode.
    • modify terminfo and termcap to use recommended "X Window" or "X11" names rather than "X Windows" (reported by Tomas Vanhala).
    • suppress translation of shifted keypad "+" when sunKeyboard is true.
    • workaround unexpected behavior (perhaps bug) in XmbLookupString, which returns trash in the string buffer for numlock and control-key combined with keypad-keys.
    • modify ScrollBarReverseVideo() to keep scrollbar border visible when reverse video is toggled.
    • correct missing case for parameter 17 (set highlight color) in dynamic colors control sequences.
    • extend dynamic colors control sequences to allow users to determine the colors and font which are currently active.
    • minor tweak to OSC responses, to use BEL if the application used that to end the request, rather than ST. This works better with shell scripts, which may not handle an <ESC>backslash very well.
    • separate menu settings for reverse video from that done under program control.
    • corrected ifdef's for menus, which did not allow tek4014 to be suppressed properly (reported by Clint Olsen).
    • changes for Linux-2.2.x with GLibc-2.1 and /dev/ptmx support (integrated patch from Pavel Roskin):
      • main.c and resize.c were using different rules to determine whether ATT should be defined (actually USE_USG_PTYS is more apt).
      • copy definitions from main.c to resize.c to prevent sys/stream.h and sys/ptem.h from inclusion when SYSV is not defined
      • define CNUL if not already defined like other variables.
      • /dev/tty does exist in Linux, but it doesn't mean, it should be used. Therefore EACCES is now an acceptable result.
      • ifdef'd several calls such as ioctl (ptyfd, I_PUSH, "ptem") to build on Linux (I_PUSH is not defined when sys/stropts.h is not included).
    • initialize second "ltc" variable in main.c (reported by David Dawes).
    • provide definition for USE_USG_PTYS in screen.c
    • add resource-files to install rule in standalone Makefile.in
    • add sample scripts to illustrate titlebar controls, resizing and colors.

    Patch #93 - 1999/3/14 - XFree86 3.9Pd

    Here are several fixes and minor enhancements. The chief ones are the fixes for NumLock mode and reverse video, since we had become used to working around the problems.

    • remove kfnd/kll/kslt strings from terminfo, because curses applications do not necessarily return khome/kend pairs (reported by Vikas Agnihotri).
    • implement NumLock resource which overrides the keyboard tables for the special case of keypad keys. This is a problem introduced in xterm by X11R6 changes, i.e., an ambiguity which in effect discarded vt100 keypad support.
    • modify Sun/PC keyboard mode to extend this (emulation of DEC vt100 keypad) to the remainder of the numeric keypad. Now, the default operating mode of xterm uses the keyboard tables as-is (except if the NumLock mode overrides), but provides good vt100 keypad compatibility if the Sun/PC keyboard menu item is checked.
    • separate command-line settings for reverse video from that done under program control. This is a problem which was introduced by X11R6. Though correct, most users are confused by allowing the reset command to undo the effect of the command-line -rv option.
    • add description of function keys, keypad and cursor keys to ctlseqs.ms
    • add terminfo entries for xterm-vt52, xterm-sun and xterm-hp
    • correct typo (missing case value) for DECSET 35, enable/disable shifted keypad action and a few compiler warnings (reported by Zdenek Sekera <zs@sgi.com>).
    • correct reporting of color values 8-15 in DECRQSS (reported by Vikas Agnihotri).
    • modify parsing of ttyModes resource to recognize "^-" as "undef" (requested by Tomas Vanhala).
    • integrate/extend changes to add iconify/maximize actions (from Edward S. Arthur <eda@ultranet.com>).
    • add control sequences for maximizing/restoring window, and for reporting maximum screen size.
    • add 'interpret' action, to support local function-key interpretation. Used properly, this makes most of the specialized actions of xterm redundant.
    • add control sequence private modes 1051, 1052 and 1052, for setting the Sun and HP function key modes, and for setting the Sun/PC keyboard mode.
    • add configure option --disable-maximize
    • add configure option --disable-num-lcok
    • extend descriptions of configure script options in INSTALL.

    Patch #92 - 1999/2/5 - XFree86 3.9Nz

    • increase buffer size for tgetent (i.e., termcap) to 1500. This fixes a problem where screen is built using ncurses or GNU termcap and xterm is built using the standard termcap interface. The former does not limit the termcap size, while the latter is assumed to be no longer than 1023 characters. The screen program's termcap entry is about 1200 characters long.
    • change update_menu_item() to a function, to simplify debugging. This also reduces the executable by 4Kb.
    • add control sequences for DECSET 30, 1010, 1011 like rxvt (enable or disable some features that were only settable via resources or command line arguments).
    • add control sequence for DECSET 35, which enables/disables the shifted keypad functions.
    • add support for switching font sizes, by stepping through the font menu using shifted keypad plus and minus.
    • correct missing initialization of tekInhibit and tekSmall resources.
    • correct ifdef's in charproc.c for XtNgeometry and XtCGeometry (reported by Bram Moolenaar).

    Patch #91 - 1999/1/21 - XFree86 3.9Nw

    • Implement logic to translate input characters which are mapped when in vt220 National Replacement Character mode (requested by Tomas Vanhala).
    • Resync configure scripts with my patches to autoconf 2.13
    • Change order of -lXmu and -lXext to accommodate cygwin32 (reported by Vikas Agnihotri).
    • Add "-ti" option to set terminal emulation level from command line rather than via resource.
    • Simplify some of the preprocessor logic using #elif.

    Patch #90 - 1998/12/13 - XFree86 3.9Nq

    This implements several small fixes and enhancements. The chief one implements fallback support for line drawing characters with fonts that do not include those characters. But I implemented that last.

    • If any of the glyphs in positions 0-31 (used by xterm to implement the VT100 alternate character set) are zero-sized (i.e., missing), xterm will reserve a normal space for the glyph when drawing. I implemented a simple stroke-drawing function to draw the line-drawing characters and a couple of the other (simpler) characters such as diamond. (This was suggested by Vikas Agnihotri).
    • Modify the computation of doublesize characters to work around font servers which shift the scaled characters up/down or do not give the correct width.
    • Add popup menu item and corresponding resource settings to disable the font-scaling logic for doublesize characters to work around (older) font servers which simply do not draw the fonts scaled to the size that they said they would. I see this problem on a SunOS system running X11R5; the X11R6 servers seem well behaved.
    • Implement new escape sequence, private mode 1049, which combines the switch to/from alternate screen mode with screen clearing and cursor save/restore. Unlike the existing escape sequence, this clears the alternate screen when switching to it rather than when switching to the normal screen, thus retaining the alternate screen contents for select/paste operations.

      When I implemented the popup menu entry to toggle between the normal and alternate screens, I considered only pasting from the normal screen to the alternate; this improvement allows either direction.

    • Changed the termcap and terminfo for xterm-xfree86 and xterm-8bit to use the new 1049 private mode.
    • Modify the logic which switches between normal and alternate screens so that the save/restore cursor operations apply only to the current screen. That means that applications which use the terminfo smcur/rmcur or termcap ti/te capabilities will restore the cursor to the original position on the normal screen rather than to the most recent place where a save-cursor operation was performed.

      I note that a real VT100 terminal would not behave in this way, but it is a moot point since the VT100 does not implement alternate screen, and therefore the save/restore cursor sequence would not be used in this context. I reviewed the logic which switches between normal and alternate screens based on some recent newsgroup postings as well as a proposed patch in the Debian group which attempts to do this (the patch has a bug, however, so I did not use it).

    • Add popup menu entry for toggling the titeInhibit resource.
    • Add new resource answerbackString, which overrides the default "xterm" returned by xterm when responding to an ENQ (control/E) character (request by Rajesh Vaidheeswarran <rv@fore.com>).
    • Add new resource keyboardDialect for setting the NRC display character set (request by Tomas Vanhala, who notes that I should add logic to translate the keyboard as well).
    • Add new command-line option and corresponding resources for making xterm generate escape sequences compatible with HP terminals. Like the existing Sun escape sequences, this is available as a popup menu item. It is enabled by the configure script with the option --enable-hp-fkeys (requested by Toni Mueller <sales@oeko.net>).
    • Add configure script option --disable-boxchars to disable the fallback support for line drawing characters.
    • Fix ifdef's for configure script --disable-ansi-color, and reviewed all configure options to ensure that all can be enabled/disabled appropriately.
    • Update config.guess and config.sub, from Lynx.

    Patch #89 - 1998/11/20 - XFree86 3.9Nm

    This patch completes the implementation of double-sized character support for the VT100 emulation, and fixes a few minor bugs:

    • corrected the cursor position in HideCursor, which did not multiply the column by two when in doublesize mode. This bug, which did not appear in normal use, dates back to my original changes to partly implement double-sized characters. I noticed it when cat'ing a typescript from vttest's double-sized character test.
    • ensure that the current line is repainted when switching between single and double width characters.
    • reduce the number of bits used for double-sized character coding from 3 to 2, to make more room for soft-font codes.
    • copy newer ifdef's from the XFree86 3.3.3 release's main.c, which address details of glibc and powerpc.
    • moved definition of DECL_ERRNO in xterm.h to match XFree86 3.3.3
    • modify resize to remove the ifdef on SVr4 that suppressed printing the script for $LINES and $COLUMNS. Solaris' resize utility does this; suppressing the behavior is unnecessary.

    I tested the double-sized characters using vttest and the xfsft patch. These fonts worked reasonably well:

            -bitstream-courier-medium-r-normal--0-0-0-0-m-0-iso8859-1
            9x15
    

    The iso8859 font does not include box characters, of course, but looks good.

    Patch #88 - 1998/10/31 - XFree86 3.9Nk and 3.3.2h

    This refines my patch #85 by checking for a case where the font server returns a bold font that does not quite correspond to the normal font. When I asked for a bold version of the 6x12 font, the font server returned a near equivalent where the ascent and descent values did not match, causing xterm to leave lines across the display. This patch makes xterm reject that type of mismatch, falling back to the old font behavior.

    Patch #87 - 1998/10/21 - XFree86 3.9Nj and 3.3.2f

    This corrects a problem reported by Stefan Dalibor. My table entries for the printerExtent and printerFormFeed resources used the wrong types for sizeof, causing the printer to not work properly on some platforms because the printAttributes resource was overwritten (e.g., Digital Unix with DEC Alpha).

    I reviewed all of the resource table entries and fixed a potential problem with resizeGravity, which was typed as int rather than XtGravity.

    Patch #86 - 1998/10/14 - XFree86 3.9Nj and 3.3.2e

    A small fix: when switching to/from the continuous mouse reporting mode, the event mask was incorrect if xterm was built under X11R5 because the original data was saved under an ifdef for active-icon.

    Patch #85 - 1998/10/12 - XFree86 3.9Nj and 3.3.2e

    Some cleanup (I noticed the pixel droppings a few months ago after getting a new 17" monitor):

    • split-out the functions that load/reload fonts for xterm as new file fontutils.c to extend them to support automatic loading of bold font corresponding to the normal font. Adapted logic from EMU 1.3 for this purpose. This fixes most occurrences of pixel droppings from bold characters.
    • modified by renaming variables and adding casts to permit compile with g++.
    • modify headers so they can all be compiled without order dependencies, and use bracketed rather than quoting includes to allow compile from separate directory.
    • renamed xtermm terminfo entry to xterm-mono, to avoid conflict with Solaris entry now in ncurses.

    Patch #84 - 1998/10/9 - XFree86 3.9Ni and 3.3.2e

    Several small fixes and enhancements, including a patch from Bjorn Helgaas:

    • correct initialization of TERMCAP environment variable, which was frequently set to garbage on non-Linux systems because "termcap" and "newtc" contained random data from the stack.
    • remove the LINEWRAPPED attribute from lines as they are cleared. Previously, the attribute was set but never cleared.
    • make word and line selections work even when lines are wrapped by xterm. Previously, selections were limited to one screen line.

    as well as

    • modify logic for line-wrapping to reset the associated flag if the application deletes a character. This fixes a problem reported by Bjorn Helgaas where word/line selection would still wrap even after deleting characters from the first line.
    • add kll/kH capabilities to xterm-xfree86 entries in termcap and terminfo (request by Michael Schroeder).
    • shorten descriptions in termcap to make resolved entries all shorter than 1023 character limit.
    • use DECSTR control sequence to shorten initialization and reset strings in xterm-xfree86 termcap and terminfo.
    • use rmul/smul and rmir/smir in xterm-r5 terminfo to match termcap.
    • correct typos in initialization and reset strings in xterm-r5 termcap and terminfo.
    • disable special translations of key symbols (the backarrow key, the editing keypad and the keypad "+") when a modifier other than shift, control or numlock is used. This makes xterm handle the meta key as expected by people using emacs (reported by Pete Harlan <harlan@pointofchoice.com> in linux.debian.user newsgroup).

    Resync #83 - 1998/10/7 - XFree86 3.3.2e

    Merge changes through patch #83 with the 3.3.2e version.

    This follows a change from XFree86 CVS which adds checks for non-null return from malloc (patch by Matthieu Herrb).

    Patch #83 - 1998/8/25 - XFree86 3.9Nb

    Several small fixes and enhancements:

    • add configure test to infer if xterm should be installed setuid based on previously installed xterm (reported by Stephen Marley and Stefan Dalibor).
    • implement quasi-continuous mouse reporting (integrated patch by Jason Bacon).
    • correct control sequences transmitted by function keys F1 to F4 when sunFunctionKeys resource is true (it was still using the VT100 control sequences).
    • modify handling of backarrow key so that the control modifier toggles the backspace/delete interpretation set by the backarrowKey resource.
    • limit the row and column values used to report mouse position.

    From resync with XFree86 3.9Nb:

    • add support for the VSTATUS control character (patch by Robert Earl <rearl@teleport.com>).

    Patch #82 - 1998/7/15 - XFree86 3.9Aj

    Bug fix for patch #81:

    • remove an #undef for NBBY, which caused compile problem on FreeBSD (reported by David Dawes).

    Patch #81 - 1998/7/14 - XFree86 3.9Aj

    More bug fixes:

    • fix conflicting ifdef's for TIOCSLTC when building with Linux on AXP aka DEC Alpha (reported by Robin Cutshaw).
    • correction to patch #79, move assignment for *utptr->ut_user = 0; back into non-SVR4 ifdef in main.c, since this clobbers username on Solaris 2.5.1 (analysis by Will Day <willday@rom.oit.gatech.edu>).
    • corrected khome/kend in xterm-8bit terminfo description.
    • improve cursor color by making it always the reverse of fg/bg unless the cursorColor resource is set, i.e., to something other than the default foreground (reported by Vikas Agnihotri and Bram Moolenaar).
    • minor fixes for compiler warnings, including a syntax error in the AMOEBA ifdef's.

    From resync with XFree86 3.9Aj:

    • correction to patch #73, supply missing #else for fallback definitions of size_t, time_t (Robin Cutshaw <robin@intercore.com>).

    Patch #80 - 1998/6/29 - XFree86 3.9Ai

    This fixes a couple of items leftover or introduced by patch 79:

    • take out the logic that suppresses editing-keypad in vt100 mode (those keys are too valuable to give up for a fine point of emulation).
    • corrected a couple of places in terminfo where I missed using the vt220-style editing-keypad codes for Find/Select (mapped to Home/End).
    • checked termcap file against terminfo, fix several places where it was inconsistent.

    Patch #79 - 1998/6/28 - XFree86 3.9Ai

    This patch fixes several small bugs:

    • use X_EXTRA_LIBS in standalone Makefile.in (patch by Tomas Vanhala).
    • add new resource 'oldXtermFKeys' which provides backward compatibility for F1-F4 control sequences with TOG's xterm.
    • determine the server's default foreground/background Pixel values, needed if the -flipPixels X server option is used (reported by David Dawes).
    • correct logic for F1-F4 function keys so that they generate VT100 compatible escape sequences in VT220 mode, since that is what the numeric keypad is supposed to do (reported by Ron Johnson, Jr. <ronjohn@communique.net>).
    • modify logic for editing keypad to work more like VT220: don't pass those codes in VT100-mode unless oldXtermFKeys mode is set.
    • correct an interaction with the editing-keypad logic that prevented backarrow key from sending a 127 for the delete key (the 'remove' escape sequence was being sent instead).
    • use return-value from getuid() rather than the parameter, to work on systems which do not update the latter (patch by Kevin Buhr <buhr@mozart.stat.wisc.edu>)
    • correct scrollbar border color when toggling to/from secure keyboard mode (patch by Jeff Uphoff <juphoff@tarsier.cv.nrao.edu>)
    • modifications to terminfo file:
      • rename description to xterm-xfree86, adding an entry 'xterm' which is derived from xterm-xfree86 to simplify customization.
      • change string for kdch1 from \177 to \E[3~, to address complaints from Debian developers. (This applies to the key labeled "Delete", and does not affect the backarrow key).
      • add user-strings u6, u7, u8, u9 to entries to make them work with Daniel Weaver's "tack" program.
      • modify xterm-24, xterm-bold, xterm-boldso entries to disentangle them from explicit dependency upon xterm-xfree86.
      • add generic 'xterm-color' entry.
      • minor corrections to xterm-xfree86, xterm-8bit, xterm-r5 and xterm-r6 entries.

    Patch #78 - 1998/6/3 - XFree86 3.9Ah and 3.3.2

    Again, most of the bulk of this patch is for ANSI conversion. I used the IRIX compiler's -wlint option to find the remaining functions that use K&R syntax (since gcc does not do this properly). Also, I changed the logic in the print code slightly to close unwanted files before opening a pipe to the printer. This may help in some configurations where the line printer hangs until xterm closes the pipe.

    Patch #77 - 1998/5/26 - XFree86 3.9Ah and 3.3.2

    Most of the bulk of this patch is to convert the extended C (K&R functions with prototypes) to ANSI. I verified that on Linux by comparing object files, to ensure that I did not, for example, interchange parameters in the function declarations.

    The rest of the patch fixes several minor bugs, and adds a few features:

    • back-out my use of ncurses "captoinfo -f" option (if/then/else/endif) formatting, since ncurses did not correctly filter embedded newlines in terminfo capability strings until _after_ ncurses 4.1, thus corrupting setf/setb/sgr strings (reported by Darren Hiebert and others).
    • document SGR 8, 28 (invisible/visible), add corresponding capabilities to terminfo description.

      I would also add the 'prot protected capability, but the control sequences for that would not be recognized or properly ignored by the older xterm programs.

    • modify ChangeGroup to not suppress a null-resource, but treat it as an empty string (recommended by Stefan Dalibor).
    • add printerAutoClose resource to control whether printer is closed when going offline. More than one person reports problems (on Solaris 2.6 and Digital Unix 4.0) getting the printer to proceed unless xterm exits; I think that it is a problem flushing the pipe. Closing it ought to flush it.
    • adapt TOG fix-3 to in HandleKeymapChange and VTInitI18N (but adapt XtStackAlloc/XtStackFree for clarity, as well as fixing memory leak).
    • change calls on FillCurBackground to ClearCurBackground, in effect using XClearArea rather than XFillRectangle when clearing as a side-effect of scrolling and insertion (patch by Alexander V Lukyanov)
    • correct some places where insert/delete did not _move_ the color attributes, using memmove (patch by Alexander V Lukyanov <lav@long.yar.ru>)
    • add ifdef's for __CYGWIN32__, for port to cygnus version B19.1 (patch by Andrew Sumner <andrew_sumner@hotmail.com>).
    • remove #define for hpux that turned on USE_SYSV_ENVVARS, since this causes some applications (such as 'less') to get incorrect $LINES and $COLUMNS values (reported by Clint Olsen).
    • modify behavior for HP-UX, to set the "reserved" process group controls to _POSIX_VDISABLE so the TIOCSLTC ioctl does not produce an error (patch by Ben Yoshino <ben@wiliki.eng.hawaii.edu>).
    • correct length of underlining, reducing it by one pixel to avoid leaving a dot when the application does not clear the whole screen I noticed this only recently myself (and other people as well); it depends on the font chosen. A 6x10 font shows it, but the other fonts from XTerm.ad do not. I also see a similar problem with the emulation of bold fonts. (patch by Sergei Laskavy <Laskavy@cs.msu.su>).
    • add include for Xos.h to xterm.h, to ensure proper definitions (reported by Holger Veit).
    • update config.guess to recognize Unixware 2.1 and 7 (patch by Mike Hopkirk <hops@sco.com>).

    Patch #76 - 1998/5/8 - XFree86 3.9Ah and 3.3.2

    A fix for the print-window function, and some minor cleanup:

    • modify logic that closes pipe in the print-window function to not use pclose, which does not work on all systems, since I did not open the pipe with popen (reported by Stefan Dalibor).
    • correct name of $(EXTRA_LOAD_FLAGS) imake variable (reported by Stefan Dalibor).
    • guard logic in ChangeGroup() function against null pointer (reported by Stefan Dalibor).
    • ensure that menu entry for toggling sunKeyboard resource is initialized (reported by Branden Robinson <branden@purdue.edu>).
    • gcc unused-variable warnings (reported by Bernd Ernesti <bernd@arresum.inka.de>)
    • rename global variable 'buffer' to 'VTbuffer'

    Patch #75 - 1998/5/7 - XFree86 3.9Ah and 3.3.2

    This incorporates fixes from several people, as well as some improvements that I made based on feedback from users:

    • add option to standalone configure script, "--with-own-terminfo-dir", which causes xterm to pass a predefined value of $TERMINFO to the application. Also use this value in install rule "make install-ti", for the standalone configure script. (patch & feedback from Tor Lillqvist <tml@hemuli.tte.vtt.fi>)
    • change ifdef's for "hpux" to "__hpux" (patch by Tor Lillqvist). The imake configuration uses the former, but the latter is predefined by HP's compilers.
    • define USE_SYSV_ENVVARS for HP-UX, curses does not use $TERMCAP (patch by Tor Lillqvist).
    • on HP-UX, use the /dev/ptym/clone device to allocate PTY's. Works both on HP-UX 9 and 10. (patch by Tor Lillqvist).
    • modify configure script to obtain the $(EXTRA_LOADFLAGS) value from imake, needed for compiling under DEC OSF/1 (reported by Stefan Dalibor)
    • modify print-window action so that the printer is closed after printing a window, unless the printer was already opened (i.e., by an application running in the window). This makes the printing complete without having to exit xterm, since not all systems treat fflush through a pipe very well (reported by Stefan Dalibor)
    • modify printing code so that the ^M's are not printed if the printAttribute resource is set to zero (request by Stefan Dalibor).
    • correct typo in xterm.man, for the default value of printAttribute (reported by Stefan Dalibor).
    • correct printing code so that the alternate character set is printed, like other attributes, with escape sequences.
    • correct termcap description, removing spurious 'm' character from the 'op' capability (reported by Greg Woods <woods@weird.com>).
    • correct trace code so that the initial timestamp is set.
    • correct/modify utmp data for the Linux glibc 2 configuration, so that the ut_line member is set before using it to update wtmp (patch by Bill Nottingham <wen1@cec.wustl.edu>).

    Patch #74 - 1998/4/27 - XFree86 3.9Ag and 3.3.2

    This corrects a couple of recent bugs and adds a new resource:

    • modify definition of TRACE_CHILD so that it does not conflict with ifdef's for USE_USG_PTYS in main.c (reported by Vikas Agnihotri <VikasA@att.com> and Stefan Dalibor).
    • correct ownership of file (actually pipe) written by the print controls. When undoing the setuid changes in patch #69, I overlooked this. Now xterm forks a process which resets setuid and routes the printer data as the real user.
    • add a new resource, "printAttributes", which controls whether color attributes (or any attributes) are sent to the printer.

    Patch #73 - 1998/4/25 - XFree86 3.9Ag and 3.3.2

    This patch does the following:

    • implements a print-window facility for xterm. Though useful in itself, I added it as part of some debugging which I am doing. (Occasionally during an exposure event xterm fails to restore the proper colors for highlighted text, and printing the screen will show the internal states nicely).

      The print facility now also displays the color information. (I will probably make this a resource).

    • modified the xterm-16color terminfo description to use the setaf and setab strings, which is a little more efficient (requested by Stephen Marley).
    • reduced some clutter of the ifdef/includes (e.g., stdlib.h, unistd.h, errno) making the configure script test for these.

      I removed the symbols Size_t and Time_t, since they no longer serve a useful purpose.

    • added some debugging traces to show the initial screen size, and the success/failure of the ioctl calls pass handle window resizing events to the application (for Clint Olsen).

      I also modified the trace code to produce two files since some of the information is produced by the child process. So now they are Trace-parent.out and Trace-child.out

    • updated configure test for ANSI compiler options to handle a special case for HP-UX 10.x (reported by Clint Olsen).

    Patch #72 - 1998/4/17 - XFree86 3.9Ag and 3.3.2

    This is a patch from Chris Siebenmann <cks@hawkwind.utcs.toronto.edu>, which I have cleaned up a little, and integrated into the configure script.

    From his description:

    This set of patches is the latest incarnation of patches originally written by Ian! D Allen, then of the University of Waterloo and now of who knows where; I have been carrying them forward from xterm to xterm ever since about X11R4. What they do is add an option so that when an iconified xterm receives output it prepends '*** ' to its icon title and (optionally) beeps the bell; deiconifying the xterm removes the '*** '. Over the years I've found this to be incredibly convenient for monitoring all sorts of low-activity things.

    Patch #71 - 1998/4/12 - XFree86 3.9Ag and 3.3.2

    This patch is a slightly modified version of one by Richard Braakman, which prevents buffer overflow in the input-method and preedit-type parsing in xterm. I changed a couple of details to make the code more maintainable, and looked for similar things - copying into a fixed-size buffer (found none, though I did spot an unused variable).

    Patch #70 - 1998/3/29 - XFree86 3.9Af and 3.3.2

    This patch corrects some minor bugs in xterm, and fills in some more details in the VT220 emulation:

    • modify Imakefile to use SpecialCObjectRule for menu and data modules, making xterm build properly if logging is enabled (patch by Scott Sewall <scott@iprg.nokia.com>).
    • restore "ich" capability to terminfo entries, since Michael Schroeder points out that "ich1" is the one which is the problem in Solaris vi.
    • correct color of cursor, which would disappear on inverse-video since the initialization did not compare the cursor color against both foreground and background (reported by Olivier Calle).
    • correct abbreviation-test for -version and -help options, making command-line option -vb work (reported by Stefan Dalibor).
    • correct a dependency between ifdef's for OPT_I18N_SUPPORT and OPT_INPUT_METHOD (reported by Stefan Dalibor).
    • split-out character-set translations as new module charsets.c, to implement VT220 national replacement character sets (a mode where some of the characters are displayed as specific European glyphs). This relies on xterm using an ISO 8859-1 font (approach suggested by Kenneth R. Robinette <zkrr01@mailbox.neosoft.com>).
    • correct a missing increment, which made SS2 and SS3 controls repeat the shifted character.
    • add xterm-nrc to terminfo to illustrate the VT220 national replacement character sets.
    • reformat terminfo using new ncurses tic option "-f", which makes if/then/else/endif expressions easier to read.

    Patch #69 - 1998/3/16 - XFree86 3.9Ad and 3.3.2

    This corrects the problem in xterm with utmp, reported by Olivier Calle <olivier@tc.fluke.com> as well as some other people after the XFree86 3.3.2 release.

    The error was introduced by my patch #53 in XFree86 3.9r (October 1997).

    The correction removes the reset of setuid/setgid before the main event loop, and solves the problem which I had worked around in a different manner: for some reason, the particular waitpid() call in creat_as() hangs, does not return when the child process exits. I changed the ifdef's to force the Linux configuration to use wait() instead. This call appears to work properly on other platforms such as SunOS and Solaris.

    I also added tests in the standalone configure script to check for the existence of waitpid().

    Patch #68 - 1998/3/4 - XFree86 3.9Ad and 3.3.1z

    This corrects another problem with the logic for highlightColor resource. As reported by David Dawes:

    I've just noticed a problem with with the "inverse" control sequence (ESC[7m) with the 3.3.2 xterm. What it does is sets the background black, and the text the usual foreground colour rather than simply swapping the foreground/background.

    This appears to be because when I added logic to check that the highlightColor was distinct from foreground and background colors, I did not add a further check to see that it was not black (I would make an explicit check for the resource not being set, but see nothing definite in the headers that would let me reference an explicitly-undefined Pixel value, though there are some implications in xpm.h). But this should work.

    Patch #67 - 1998/2/23 - XFree86 3.9Ad and 3.3.1e

    This patch does the following:

    • improve test for highlightColor so that xterm does not attempt to use that unless it is different from the foreground and background colors (reported by Stefan Dalibor <Stefan.Dalibor@informatik.uni-erlangen.de>.

      I could not reproduce this until I noticed that the -rev option exposed it nicely.

    • remove ich and ich1 from xterm and xterm-8bit terminfo descriptions. SVr4 terminfo documents that you must not combine these with smir/rmir, but ncurses allows it, opening a hole. Solaris 2.6 vi does not work properly if it is using a terminfo description when these are combined, since it was written to accommodate old terminals that required it (reported by Stephen Marley).
    • restore 1-pixel overlap of scrollbar border with left edge of window (reported by Jim Burmeister <jimb@metrolink.com>).
    • add a configure option, --enable-logfile-exec, which allows the user to specify a pipe for logfile. This defines ALLOWLOGFILEEXEC.
    • makes the ALLOWLOGFILEEXEC code compile & run, if configured.
    • minor documentation nits.

    Patch #66 - 1998/2/16 - XFree86 3.9Ad and 3.3.1d

    This fixes the problem reported with failure to build the resize program (BSDI, OSF/1) due to not having <termcap.h>, by changing the ifdef to one that would be set only if the file exists (not currently specified, except by the standalone configure script). We do not really need to include <termcap.h> to build, but only for a clean compile, since it may declare the tgetent() prototype. I also updated the man-page for resize, since I had recently noticed that it can be used to resize xterm using the "Sun" control sequences option.

    Patch #65 - 1998/2/14 - XFree86 3.9Ad and 3.3.1c

    This is a small patch to xterm's 8-bit terminal description. I noticed while testing ncurses that I had specified the wrong (VT100-style) codes for the F1-F4. Xterm only uses VT220-style function keys in 8-bit mode.

    Patch #64 - 1998/2/8 - XFree86 3.9Ad

    This fixes the following problems with xterm:

    • save/restore the ANSI foreground and background colors with the other visible attributes in the save-cursor and restore-cursor operations. This works around a problem with vim, which apparently assumed that switching between the normal and alternate screens resets the colors (reported by Jim Battle <jb@chromatic.com>).

      It would be nice to implement save/restore cursor as a stack (and solve this type of problem completely), but that would lead to incompatibility with applications which assume they are running with a VT100 or VT220.

    • corrects behavior of a restore-cursor operation which does not follow a save-cursor (it is supposed to set the character sets to a known initial state).
    • extends the sunKeyboard resource (and menu toggle) to modify the home, end and delete keys on a Sun or PC editing keypad, making them generate codes compatible with DEC VT220's Find, Select and Remove keys.
    • corrects a length in checking command-line options, which caused the "-help" message to not work when X was not running.
    • add some detail to the man-page (requested by Jason Bacon <acadix@execpc.com>)
    • modify the standalone configure script to ignore the broken nsl and socket libraries on IRIX 6.2 (the ones on 5.2 also are broken, so this change just widens the check for the system version number).

    Patch #63 - 1998/2/5 - XFree86 3.9Ad

    This is another patch from Bjorn Helgaas <helgaas@rsn.hp.com>, which I've reviewed (and learned some). Following are his notes:

    I poked around some more and finally got xterm-62 to build and run cleanly on HP-UX 10.20. Here are the patches. They look sort of ugly, so here's a little explanation:

    • aclocal.m4: Removed side effects from the AC_CACHE_VAL commands in CF_FUNC_TGETENT. Previously, LIBS was set inside AC_CACHE_VAL, which worked fine the first time configure was run, but failed if there were cached values.
    • aclocal.m4: Added temporary setting of LIBS before AC_TRY_LINK in CF_FUNC_TGETENT. Previously, the last value set by the AC_TRY_RUN loop was used, so only -lcurses was checked.
    • configure.in: Added temporary setting of CPPFLAGS before AC_CHECK_HEADERS for X11 files. Previously <X11/DECkeysym.h> and <X11/Xpoll.h> were found only if they were in the compiler's default include directories, even if `--x-includes=DIR' had been used or AC_PATH_XTRA had found them elsewhere.

    The problem on HP-UX was that we were linking with -lcurses rather than -ltermcap due to the second bullet above, and apparently something in HP-UX curses is broken. This seems very strange, because the only thing used is tgetent, which should affect any tty/pty configuration, but I lost interest in tracking down the exact problem.

    Patch #62 - 1998/1/23 - XFree86 3.9Ac

    This is a patch mostly by Bjorn Helgaas <helgaas@dhc.net> (I added the os2main.c change, and a little of the documentation). From Bjorn's description:

    • If you use the "-hc <color>" option or set the "highlightColor" resource, text is highlighted by changing only the background color, rather than using reverse video. I find this easier to read, especially when selecting multi-colored text, and it is similar to the way Netscape shows selections.
    • Most of the code changes are under "#if OPT_HIGHLIGHT_COLOR". The principal exception is in screen.c, where I added a couple calls to resetXtermGC(). This seems like it could be a bug even without the color highlighting changes (though I don't pretend to understand all the logic).

    Patch #61 - 1998/1/17 - XFree86 3.9Ac

    This patch modifies the reset behavior of xterm slightly:

    • change the terminfo entry so that rs1 (one of the strings used by the 'reset' program) does a hard reset rather than switching character sets. This is more in accord with other terminal descriptions.
    • modifies the treatment of hard reset by the xterm program to reset the saved lines.
    • corrects hard reset by also resetting user-defined keys, i.e., DECUDK.

    Patch #60 - 1998/1/10 - XFree86 3.9Ab

    This fixes some minor bugs and adds new functionality:

    • add support for blinking text.
      • This does not actually cause the text to flash, but text with the blink attribute can be displayed in color, using new resources colorBL and colorBLMode.
      • If colors are not used, the blinking text will be displayed as before (just like bold). The main purpose of this is to make applications work properly when they assume the emulator supports blinking text.
      • I did this by moving the per-cell LINEWRAPPED flag to a per-line flag, to make room for the new BLINK flag. There were no per-line flags, so this changes a lot of logic.
    • corrected missing save-cursor logic in the handling of SGR 1048 (the new control sequence I added in patch #54, 1997/10/17). Reported by Darren Hiebert.
    • flush the output of the transparent printing after each line Reported by Tomas Vanhala <vanhala@ling.helsinki.fi>.
    • correct the modes that are affected by save/restore cursor by adding WRAPAROUND and PROTECTED.
    • corrected placement of one of the XSync calls that I added in patch #51, 1997/9/15, which had the side-effect of writing on the window border when the xterm was resizing from 132 to 80 columns.
    • work around an incompatibility of the XKB definition used in xterm versus that symbol from IRIX 6.2's imake definitions (by adjusting the standalone configure script).

    Patch #59 - 1998/1/5 - XFree86 3.9Ab

    My last patch has an off-by-one error in the comparison for argc. Douglas Kosovic <douglask@dstc.edu.au> showed me where (he got a core dump). Also, I think this explains Clint Olsen's problem, but the symptoms were more subtle (EINVAL for a system call if the -display option is omitted).

    Patch #58 - 1998/1/3 - XFree86 3.9Ab

    This patch does the following:

    • implement logic to permit xterm to work with proportional fonts.
      • Thomas Wolff <Thomas.Wolff@sietec.de> requested this (but it isn't exactly what he's asking for - that's a more involved task).
      • I chose to do this by rendering the characters on a fixed pitch, because it would not be useful for existing applications to display varying numbers of characters on each line.
      • Except that this forces the display to be wider, it works reasonably well. A couple of special cases (reverse + colorBD, for example) do not display with proper colors, since the inter-character gaps are painted with the background.
    • added a version number to the program (several people have requested this).
    • make the -version and -help options interpreted before the program attempts to open the display.
    • minor reorganization of the man-page (ordered the options, resources and translations alphabetically - and eliminated some duplication).
    • corrected a misspelled filename in Makefile.in, and added a lint rule.
    • updated the configure script to correct behavior when it cannot find imake, as well as to fix the IRIX+gcc build (conflict with /usr/include).
    • regenerated the configure script with a newer patch to autoconf that fixes a problem with environment space vs the configure --help message.

    Patch #57 - 1997/12/26 - XFree86 3.9Aa

    This patch is mostly concerned with the standalone configure script; a few minor corrections are added:

    • add configure option --disable-tek4014, to allow xterm to be built without the tek4014 emulation.
    • add configure option --with-terminal-type, to allow xterm to be compiled with default $TERM value other than "xterm" (e.g., "xterm-16color") -- requested by Stephen Marley <stephen@memex.com>.
    • fix a typo in the configure --help message -- reported by Darren Hiebert <darren@hmi.com>.
    • review diffs between main.c and os2main.c, to make them more alike. (applies some minor bug-fixes to OS/2's version).
    • add missing quotes in memmove/bcopy configure test

    Patch #56 - 1997/11/28 - XFree86 3.9x

    This patch is based on analysis by Arfst Ludwig <arfst@luxor.IN-Berlin.DE>, who reported:

    Setting the following resources xterm (all current versions) receives a segmentation fault on <Btn2Up> after scrolling:

              *XTerm*VT100*translations:    #override \
                  ~Shift~Ctrl<Btn2Up>: insert-selection(PRIMARY, CUT_BUFFER0)\n\
                  Shift~Ctrl<Btn2Up>:  insert-selection(CLIPBOARD, CUT_BUFFER1)\n\
                  ~Shift<BtnUp>:       select-end(PRIMARY, CUT_BUFFER0)\n\
                  Shift<BtnUp>:        select-end(CLIPBOARD, CUT_BUFFER1)
    

    (The above resources intention is to be able to paste the latest selection even if the xterm was cleared.)

    And here is how it works (and a fix!): The widget given to the action handler as first argument is not guaranteed to be a XtermWidget (it can be the ScrollbarWidget). Instead of accessing the widget's member directly XtDisplay gives the required pointer in a safe way.

    I noticed that this was not the only instance (by reading the code, and testing with his example), and extended the solution to check the widget-class to ensure that it is indeed xterm's widget class before attempting to use it in the context of translations.

    Patch #55 - 1997/11/25 - XFree86 3.9x

    This fixes the segmentation violation noted by Rogier Wolff about a month ago. He'd set xterm to 400 (rows) by 150 columns, which broke because there were limited buffers (200 rows) used for juggling data when adding or deleting lines and for switching between alternate and normal screens. I replaced this by an allocated buffer.

    The bug is simple to test if you set titeInhibit false.

    Patch #54 - 1997/10/17 - XFree86 3.9s

    This patch does the following:

    • correct a minor placement problem with the right scrollbar.
    • implement a new set of control sequences for switching between the normal and alternate VT100 screens. These work around the older sequences limitation that required modification of the runtime $TERMCAP to cooperate with the titeInhibit resource (that can't work with terminfo). I do this by moving all of the functionality of the rmcur terminfo capability into the control sequences.
    • implement the alternate-screen menu entry

    Patch #53 - 1997/10/12 - XFree86 3.9r

    This patch adds a fix and implements a new feature (as well as some minor typos):

    • JCHANDRA@Inf.COM (JCHANDRA) noted that there was still a problem with the wait call with the logging option. It hung when the logfile was opened as a command-line option. I fixed this by moving the StartLogging() call down past the place where I'd reset the setuid mode. So the logfile is opened as the real user, without having to fork.
    • improve Rohleder's changes by renaming the command-line options and reducing the number of ifdef's.
    • implement right-scrollbars for xterm (patch by Michael Rohleder <michael.rohleder@stadt-frankfurt.de>).

    Patch #52 - 1997/9/29 - XFree86 3.9q

    This patch addresses bugs and requests reported by

    • Bob Maynard <rmaynard@montana.com>,
    • Clint Olsen <olsenc@ichips.intel.com>,
    • JCHANDRA@Inf.COM (JCHANDRA),
    • Michael Schroeder <Michael.Schroeder@informatik.uni-erlangen.de>,
    • Pablo Ariel Kohan <pablo@memco.co.il>

    Some of the changes are interrelated (it was an unusually busy week).

    • change the default resource value for colorMode to true, matching the Xterm.ad file.
    • correct behavior of 'ech' control, making the default and 0 parameters erase one character rather than to the end of line (reported by Michael Schroeder).
    • add resource boldColors, command-line options +pc and -pc and configure-script option to specify behavior of xterm's mapping bold colors 0 through 7 to colors 8 through 15. (request by Pablo Ariel Kohan).
    • add resource colorAttrMode to specify whether colorULMode and colorBDMode can override the ANSI colors (report by Clint Olsen).
    • correct a conflict between colorULMode/colorBDMode versus ANSI colors, where exposure events would occasionally pick up the former (e.g., colorBD) rather than ANSI colors. Testing the colorAttrMode made this apparent, though it has been in the code since 3.2A (patch #35 in Jan 1997).
    • correct two problems with the optional logging support. On Linux at least, the waitpid call in creat_as hangs when the logging is toggled from the popup menu. Also, the mktemp template has the wrong number of X's (since X11R5!). Fixed the waitpid problem by exploiting the fact that the setuid behavior is reset before the popup menus are available. (reported by Jayachandran C.).
    • add configure script options for building with the Xaw3d and neXtaw libraries.
    • correct CF_IMAKE_CFLAGS standalone configure script macro, so that it will pick up $(ALLDEFINES) rather than $(STD_DEFINES). This is needed to make scrollbars work on Linux, since that uses narrow prototypes. (reported by Bob Maynard).
    • various minor updates to configure-script macros.

    Patch #51 - 1997/9/15 - XFree86 3.9p

    Most of this patch is related to the standalone configure script, though there are fixes/enhancements as well:

    • add a new resource sunKeyboard, with associated command-line option and menu-toggle that allows using a normal Sun or PC keyboard to generated the complete DEC-style function keys and keypad.
    • correct a reversed foreground/background test in the control sequence that replies with the current SGR settings.
    • correct, by invoking XSync, a display problem that caused the program to not properly update newly exposed areas when a font change or 80/132 resize request was not completely accepted.
    • restructured autoconf macros (I made a library of all of the macros across the complicated configure scripts I'm working on).
    • use the autoconf config.guess and config.sub scripts to better identify the host-os.
    • improve the configure script that uses 'imake' as a fallback for definitions.
    • correct several instances of unsigned/signed mixed expressions.

    I've tested the configure script on Linux, SunOS 4.1.3, Solaris 2.5.1, IRIX 5.2 and 6.2, AIX 3.2.5 and CLIX 3.1 (all but the last run properly as well).

    Patch #50 - 1997/8/22 - XFree86 3.9m

    This is a collection of small fixes, and a couple of minor enhancements:

    • plug a security hole in the implementation of Media Copy (print) by invoking setuid just before the main loop.
    • add an ifdef'd include for <sys/termio.h> for HP-UX, which allows the program to process SIGWINCH events (this is a bug in X11R6.3)
    • add state-table entries for VT52 emulation to enter/exit keypad application mode.
    • disable the popup-menu entry for 8-bit controls when the terminal-id is less than 200 (e.g., VT52 or VT100).
    • ensure that the popup-menu entry for 8-bit controls is updated when the application enables/disables this mode, including the response to a full-reset.
    • implement VT300 DECBKM feature: set interpretation of the backarrow key to either backspace or delete. The initial setting is via resource; it can also be modified in the main popup menu.
    • implement VTxxx KAM (ISO AM), which allows a keyboard to be locked (i.e., the terminal discards input).
    • implement VTxxx SRM, which is used to control local echoing of input on the terminal.
    • add terminfo and termcap entries for xterm-8bit, a variation of the xterm description that uses 8-bit control characters.
    • add fallback definitions for Imakefile to allow it to work on some X11R5 systems that have no SpecialCObjectRule or ProgramTargetName macros.
    • add .c.o and .c.i rules to standalone Makefile.in
    • correct order of -lXmu and -lXext in standalone configure script.
    • add configure script options to allow selective disabling of active-icon, input-method and i18n code (mainly for users with X11R5 or an incomplete X11R6 configuration).
    • change menu-indices from #define's to enum values, thereby making it work better with the ifdef's for logging and active-icon (the X11R6.3 active-icon code is incorrectly ifdef'd; this corrects an error introduced by incorporating that code).
    • correct minor compile errors in the configuration where active-icon is not used.
    • add configure option to suppress echoing of long compiler commands
    • correct spelling of decTerminalID in configure script help message
    • use gcc __attribute__((unused)) to quiet warnings about unused parameters when compiling with -W (to make it simpler to find the real problems).

    Patch #49 - 1997/8/10 - XFree86 3.9k

    This patch implements the VT100/VT220 Media Copy (i.e., print-screen) control sequences.

    Patch #48 - 1997/7/26 - XFree86 3.9j

    This patch does the following (all but the first affect only the standalone configure script):

    • minor correction to positioning of underlines for small (e.g., 5x8) font size.

      The existing behavior allowed underlines to be drawn outside the character-cell, so they weren't cleared properly under some circumstances.

    • adds more special-case tokens to the standalone configure script's imake-option filter (e.g., "&&", since a "make -n main.o" on my IRIX system uses that shell construct).
    • adds a '--enable-logging' option for the standalone configure script.
    • adds check and ifdef's for the standalone configure script to allow for building on platforms with X11R6, which lacks Xpoll.h (introduced in X11R6.1).

    Patch #47 - 1997/7/13 - XFree86 3.9i

    This patch does the following

    • corrects an indexing error in the doublesize character logic (button.c) that caused core dump (this was reported by J. Wunsch).
    • corrects the logic of ShowCursor when it is painting in a doublesize cell (charproc.c).
    • corrects, according to vttest, the behavior when switching to doublesize characters and back again (doublechr.c).
    • adds cbt (back_tab) to the terminfo description (this was something that I'd overlooked as applicable to curses optimization last summer).
    • corrects, for the standalone xmc test, the logic for disabling xmc.

    Patch #46 - 1997/7/4 - XFree86 3.9h

    This is a patch to provide test-support for some work I'm doing on ncurses. It does not modify the normal configuration of xterm; the code is compiled if the standalone configure option "--enable-xmc-glitch" is specified.

    Patch #45 - 1997/7/2 - XFree86 3.9h

    This fixes the problem reported with xterm's cursor color versus the background (the second chunk in this patch) and also removes some duplicate initialization of the cursor GC's. If the cursor color at startup is the same as the background, then xterm will use the reverse GC, ignoring the setting of the colorMode resource.

    Patch #44 - 1997/6/22 - XFree86 3.9g

    This implements the first part of the VT100 doublesize characters for xterm, as well as fixing a handful of bugs:

    • the doublesize character support uses the normal font (using scaled fonts will be another patch) with blanks to simulate doublesize characters. This patch does most of the global changes that'll be required. I've hidden most of the details in macros and ifdef's so it's easy to configure out (part of the patch is a configure option for that purpose).
    • corrected limits in DeleteChar() function -- it's always ignored the size of the left border and scrollbar. I noticed this when working on the doublesize characters since the glitch was doubled in size (i.e., it wrapped some garbage around the right margin).
    • corrected 'memmove()' logic, for standalone builds (it referenced a malloc wrapper from my development library).
    • add a check for HideCursor() to prevent repeated screen updates (which can cause a spurious cursor glitch to appear, e.g., during scrolling). I noticed this with the 3.2A version (but only a few weeks ago, when I started working on this patch).

    Patch #43 - 1997/6/10 - XFree86 3.9d

    Here's a fix for two problems:

    • modify handling of tgetent results in xterm and resize programs to make them tolerant of missing termcap file, or unknown terminal name. In this scheme, an explicit "-tn" option will succeed, overriding the fallback list.
    • a nit in the configure script (log extra information to help diagnose which case of the test-compile of tgetent was used).

    Patch #42 - 1997/6/8 - XFree86 3.2Xl

    Bram Moolenaar reported that the cursor color changed unexpectedly while scrolling. The cause was that it used the same GC's as the logic that draws the ANSI colors. The bug only appears if the cursorColor resource isn't set, and has been present since the initial implementation early last year. (The same bug also appears in rxvt ;-). Here's a fix.

    Patch #41 - 1997/5/28 - XFree86 3.2Xl

    Some nits found by Darren Hiebert (missing part of install-rule, incorrect assignment for --enable-color-mode option).

    Patch #40 - 1997/5/26 - XFree86 3.2Xl

    Patch for the configure script's logic for obtaining imake predefined symbols.

    Patch #39 - 1997/5/24 - XFree86 3.2Xl

    This patch does the following:

    • integrate the 16-color change for 'xterm'
    • minor fixes/clarification of tgetent in terminfo vs termcap to 'resize'

    (both changes also modify the configure script)

    Patch #38 - 1997/5/22 - XFree86 3.2Xh

    This implements a simple configuration script with autoconf (to which I'll add more options later). It does the following:

    • configures xterm to build with X11R5 (at least on SunOS 4.1, Solaris 2.4, possibly IRIX - sorry network was down today, but I did test an earlier version yesterday).
    • enables/disables the configuration ifdef's for ANSI color and VT52 emulation.

    It does not make tests for the things that imake does (that's another project), instead it uses a hybrid of the autoconf tests for libraries and adds imake's compiler options (which are necessary in some cases to get main.c to compile).

    Patch #37 - 1997/5/7 - XFree86 3.9a

    This corrects a minor, but annoying error in the vt220 emulation: the DECUDK is only supposed to be interpreted for _shifted_ function keys.

    Patch #36 - 1997/1/16 - XFree86 3.2r

    This corrects something that I overlooked in patch #27 (21-aug-1996), which is that when trimming the region to be repainted for the highlightSelection resource of xterm, I still have to paint the background past the highlighted region. This only happens when I first do a selection in a window that's partly off-screen, then move the window on-screen.

    Patch #35 - 1997/1/7 - XFree86 3.2o

    This patch does the following:

    • combines the coding for foreground and background colors into a single byte, reducing the memory required to store saved-lines in color. (I'll take back that byte in a following patch to use to ensure the character-set, so there's no long-term decrease in memory use).
    • modifies the PF1-PF4 coding in termcap/terminfo. Because xterm is still by default emulating vt100, the function key codes are vt100-compatible (I overlooked this in patch #31). I also reformatted the whole terminfo file into a single-column, for consistency.
    • adds an interim xterm-vt220 description to accommodate the old and new styles of function-keys (though probably it'd be better to drop the old-style altogether).

    Patch #34 - 1997/1/5 - XFree86 3.2o

    This patch does the following:

    • implement DECSTR (soft terminal reset). The biggest diff is due to adding another state table (note that there's only one useful state here, but it's only 256 bytes rather than 1k as it would have been before I reduced the size of state entries).
    • some minor tidying up (e.g., signed/unsigned use bitcpy, MODE_DECCKM, resetColor, resetCharsets). More is done in patch #35.

    I got the description of DECSTR from a vt420 user's manual. I'll do some testing with vttest to ensure that there's nothing else to do than what was documented.

    Patch #33 - 1996/11/24 - XFree86 3.2

    This adds to the reset-fix by Matthieu Herrb <Mathieu.Herrb@mipnet.fr> a small change to make xterm able to output 8-bit characters in VT100 mode. Applications that run on real VT100's don't do that anyway, and this feature should be removed sometime after finishing off the VT220 emulation (VT220's can do 8-bit characters). That would be a good time to change the default terminal-id to 220.

    Patch #32 - 1996/11/21 - XFree86 3.2

    This implements the REP (repeat) control for xterm. That isn't part of the DEC VTxxx series, but is defined in ISO 6429. (Note that the base xterm terminal description is not changed -- I added a variant, "xterm-rep").

    Patch #31 - 1996/11/16 - XFree86 3.2

    This implements vt52 emulation in xterm (ifdef'd so it can be removed). I've been using it for testing for the past month or so.

    Patch #30 - 1996/11/16 - XFree86 3.2

    From bug-report by <auroux@clipper.ens.fr> (Denis Auroux), missing reset to ground state. I checked through the rest of that table and found another, in the unimplemented MC (screen print).

    Patch #29 - 1996/9/15 - XFree86 3.1.2Gb

    This patch does the following:

    • corrects the restoration of color for bold/underline color mode
    • adds a resource 'decTerminalID' to control the reporting level of xterm (e.g., VT100, VT220).
    • uses the new resource to implement/correct the DA1, DA2 and DECRPTUI reports.
    • change valid-response code in DECRQSS from 0 to 1 (the manual says 0, but the VT420 terminal I've been testing on says 1).

    All of these changes are based on vttest 2.6

    (Most of the volume in the patch is to add 2 more state tables for parsing the 2nd/3rd device-attribute controls).

    Patch #28 - 1996/8/31 - XFree86 3.1.2F

    This patch corrects the following reported by Roland Rosenfeld <roland@spinnaker.rhein.de>:

    • handle SGR 22, 24 and 25 in combination with colorUL and colorBD resources. Also noted & fixed reset of colored underline/bold with SGR 0.
    • a typo in the termcap (missing '['), from 3.1.2Dj (my error)

    Roland also complained that he couldn't use box characters with

            -adobe-courier-bold-r-normal--12-120-75-75-m-70-iso8859-1
    

    but that's a known xterm limitation (the box characters must be part of the font, in the first 32 locations).

    Patch #27 - 1996/8/21 - XFree86 3.1.2Ek

    This patch fixes one of my long-term gripes: xterm's selection doesn't clearly show what's being selected (as per David's request, it's controlled by a resource, which defaults to the older behavior).

    Patch #26 - 1996/8/20 - XFree86 3.1.2Ei

    Here's a patch to fix a problem with xterm's cut/paste and another to modify the appearance of the highlighting while selecting. (The changes are independent, so you can see if the change to screen.c is desirable).

    Patch #25 - 1996/8/18 - XFree86 3.1.2Ei

    Here's a correction for two minor bugs that I picked up in testing, plus some lint (from Solaris 2.5) where NULL was used incorrectly:

    • make the second alternate font the same as the first (that's what vt420 and dtterm do)
    • corrected DECSCL report when DECSCL hasn't been set (i.e., don't return a '60').

    Patch #24 - 1996/8/11 - XFree86 3.1.2Ee

    This patch does several things. In effect, xterm can (I think) do a reasonably good job of emulating vt220 and vt320 terminals (as well as it was doing vt100, at any rate ;-).

    It does NOT do:

    • soft fonts
    • rigel or sixel graphics

    Anyway, I:

    • added ECH, CPL, CNL, SU, SD, CBT, CHT controls
    • added popup-menu for switching between DEC and Sun function keys. (corrected alignment err wrt logging entry at that point).
    • make xterm recognize both 8-bit and 7-bit controls (including popup menu for switching modes).
    • add user-definable function keys (aka DECUDK)
    • support concealed text
    • support protected text (both ISO compatible and DEC compatible - that's not the same thing, btw), with SPA, EPA, DECSCA, DECSED, DECSEL controls.
    • implement DECSCL.

    I'll be continuing to test this patch for a while, but don't expect to add any new functionality (it passes all of the current tests I've built in vttest, but I need to make more tests)..

    Patch #23 - 1996/7/31 - XFree86 3.1.2Ec

    This removes the blinking cursor I added last week (for performance reasons). Time-permitting, I'll revisit this after 3.2 is released (there will be more work after XFree86 3.2, I assume).

    Patch #22 - 1996/7/26 - XFree86 3.1.2Ec

    I looked more closely at my "double-negative" and realized that I had been confused by the default color scheme (black on white) in combination with reverse video. However, I did see that the original_fg and original_bg data weren't really used - so I removed that logic.

    Also:

    • during initialization, check if ANSI colors are set with non fg/bg values, disable color mode if not. This makes xterm tolerant of applications that allocate the whole color map.
    • implemented blinking cursor (default is off)

    Patch #21 - 1996/7/24 - XFree86 3.1.2Ec

    This patch does the following:

    • fixes some minor typography in the control-sequences documentation (it didn't occur to me til I'd sent the last patch that I could use ghostview for previewing the troff output ;-)
    • adjusts the shell's background color in ReverseVideo so that flicker in resizing is reduced
    • adds an ifdef OPT_ISO_COLORS to allow configuring xterm without the ISO color support (saves a lot of memory)
    • used that ifdef to isolate/modify logic so that if the user doesn't have the colorMode enabled, then ISO color support is disabled (saving memory).

      (If anyone needs numbers, I had savedLines set to 2000, and found a reduction from ~700k to ~400k of allocated memory, according to Purify).

    Patch #20 - 1996/7/24 - XFree86 3.1.2Ec

    This documents the changes in control sequences for window operations that I added in my previous patch. I'm testing another patch that allows the user to use less memory if colors aren't needed.

    Patch #19 - 1996/7/21 - XFree86 3.1.2Ec

    This patch does the following:

    • fixes the core dump that I reported on IRIX 5.2 (in main.c)

      (it's worth noting that this bug exists in X11R6.1, so I'd like to assume that someone's already submitted a fix to X Consortium...)

    • change the interpretation of zero rows or columns in a resize-window request to use the root window's size (looking more carefully at dtterm, that seems to be what it does).
    • change some memmove calls to memcpy for slightly better performance. also, a couple of memset calls to bzero, since Quantify says bzero runs 20% faster, I assume because there's one less argument.
    • interpret character sets 1 and 2 (so that vttest gives a reasonable result) Both rxvt and dtterm do something equivalent.
    • fix a minor memory leak in the logic that retrieves the window or icon names (Purify found this for me while I ran vttest).

    Patch #18 - 1996/7/18 - XFree86 3.1.2Ec

    This implements the following:

    • escape sequences that act like the CDE dtterm's window operations (though I have implemented the default width and height -- I've seen a rather buggy dtterm running that seems to treat width=0 or height=0 literally -- maybe that's a feature, not a bug?)
    • minor tweak to the screen-repainting when resizing (I still cannot entirely get rid of flicker).
    • still more fixes to terminfo & termcap (I corrected my error for the hpa code and added some other stuff by comparing to ncurses' description and rxvt's).
    • a tweak to the changes by Michael Rohleder for the color translation
    • re-order attribute codes to allow later implementation of protected fields (dtterm supposedly does this; it's probably more useful than blinking or invisible text -- that uses up all of the available bits without changing the attribute scheme radically).

    Patch #17 - 1996/7/2 - XFree86 3.1.2Eb

    This patch implements for xterm several minor features from ISO 6429 which are useful for terminfo applications. The HPA and VPA control sequences allow cursor movement along a row or column, cutting down a little on the characters transmitted. The other codes allow resetting specific graphic rendition attributes without modifying the other attributes. (now if someone just had time to implement blinking cursors...)

    Patch #16 - 1996/6/25 - XFree86 3.1.2Ea

    Adam Tla/lka <atlka@pg.gda.pl> told me a couple of weeks ago that I'd missed some of the background coloring in xterm. I investigated, and found that while I'd picked up on the clear-to-bottom and clear-to-end-of-line operations, I'd overlooked the insert/delete lines. Just so I wouldn't overlook any more of these, I updated a copy of vttest to test ISO colors and bce (background color erase). This patch introduces a new function, ClearCurBackground, whose calls replace the direct XClearArea calls that I'd overlooked. (There's also a few compiler warnings fixed, etc ;-)

    Patch #15 - 1996/5/29 - XFree86 3.1.2E

    This fixes the problem reported by David Dawes, by making the 50msec select timeout for the Xaw3d arrow scrollbar a resource. (I made it a boolean for a variety of reasons -- to make it a number, you'd need an additional resource, to avoid breaking the logic).

    Patch #14 - 1996/5/12 - XFree86 3.1.2Dj

    This patch brings the termcap and terminfo descriptions for xterm up to date. I made the following changes:

    • reformatted the terminfo description in a single-column (this is ok for terminfo, and will simplify future patches -- can't do that for termcap, since it would impact buffer requirements on some systems).
    • omitted obsolete features in termcap to save a little space (bs, pt)
    • added color capabilities to termcap (ut, Co, NC, op, AB, AF)
    • corrected some capabilities (vi, ve)
    • added 'st' (set tab)
    • reduced function keys in termcap for 'xterm' to 12 because color capabilities makes that description larger than 1023 characters.
    • created new termcap name 'xtermm' (monochrome) to match the terminfo list, and make that description have 20 function keys.
    • added corresponding color capabilities to terminfo (bce, colors, pairs, op, ncv, setab, setaf)
    • corrected corresponding capabilities in terminfo (civis, cnorm, rmcup, smcup)
    • added capabilities (el1, hts)
    • in both, corrected home/end keys to match the code correction made by Thomas Mueller in 3.1.2Bk

      => (I'm still considering modifying the code & description to match the rxvt program).

    Patch #13 - 1996/4/23 - XFree86 3.1.2Df

    This corrects my earlier changes for colors - the inner border of the xterm was getting painted with the wrong color, since I'd moved the call to set the background into the logic that tracks SGR information.

    Patch #12 - 1996/3/16 - XFree86 3.1.2Dc

    This corrects a memory leak in xterm that happens whenever one switches fonts.

    Patch #11 - 1996/3/5 - XFree86 3.1.2Db

    This patch corrects the behavior of the ANSI colors in xterm when reverse video is used, as well as some other lesser sins:

    • button.c
      • (compiler warnings: shadowing of 'time', redundant cast)
    • charproc.c
      • renamed screen.colors[] array to screen.Acolors[] to more easily distinguish the non-ANSI colors from the ANSI colors.
      • moved logic of SGR_Save() into VTInitialize, getting rid of local private variables original_fg and original_bg.
      • moved some logic into getXtermForeground and getXtermBackground from SGR_Foreground, SGR_Background, etc.
      • corrected misleading 'row' to 'col' in case for CUF, CUB sequences.
    • ctlseqs.ms
    • xterm.man
      • (correct a misconception which I'd added that the color0 through color6 resource values apply to non-ANSI colors)
    • ptyx.h
      • added original_fg, original_bg to TScreen structure.
    • scrollbar.c
      • (compiler warnings: redundant cast)
    • util.c
      • new functions getXtermForeground and getXtermBackground replace the macros GET_FG and GET_BG, with the added functionality of checking for the reverse-video status of xterm.
      • in ReverseVideo, swap the SGR foreground and background colors also.

    Patch #10 - 1996/2/14 - XFree86 3.1.2Cd

    I observed an occasional glitch in the xterm's color behavior; a clear to end of line would get a color that had been used in a program that supposedly reset colors. I traced this down to the way xterm was modifying colors of GC's on the fly; it didn't restore the original color of the GC, even though it would later be used in functions (such as ClearRight) that assumed (my error) that the GC would have the current foreground or background color.

    I fixed this by resetting the GC's colors with a new function 'resetXtermGC()', and direct calls on SGR_Foreground/SGR_Background, as appropriate and using a new function 'updatedXtermGC()' to encapsulate the logic that modifies the GC's color. (I also removed some commented-out code that was trying to do this -- the problem was a little more obscure).

    Patch #9 - 1996/2/10 - XFree86 3.1.2Cb

    This patch fixes the remaining problems that I had making xterm run with x11r5, as well as a couple of other bugs. It follows my patch from yesterday, that added ifdef's for some of the input-method resources.

    • corrected ifdef's that suppress the input-method code (doesn't exist in my x11r5, and xterm works adequately without it).
    • corrected fallback definition for 'Select()' macro (oops: I'd copied the wrong text...)
    • moved the declarations for the fd_set variables to data.[ch]
    • corrected an ifdef in resize.c (sunos 4.x doesn't have termcap.h)
    • corrected (in main.c) some unused/orphaned variables.

    Patch #8 - 1996/2/9 - XFree86 3.1.2Cb

    This is mostly a documentation patch for xterm. It describes the color control sequences in more detail, and documents some other features of xterm that aren't described elsewhere.

    I've also added a couple of ifdef's to fix (part of) the problem that I'm working on (making the program work properly on x11r5, where I'm doing memory testing -- I have a "good" version from mid-January, but my resync version doesn't work properly on x11r5). I'm not done with that yet.

    Patch #7 - 1996/1/28 - XFree86 3.1.2n

    I did a (clean) build of 3.1.2n on Linux 1.2.13 (ELF). I've got an S3 card.

    This fixes the following in the 3.1.2n xterm:

    • initialize cur_foreground, cur_background in charproc.c (Purify told me they weren't initialized).
    • add interpretation of codes 39, 49, to reset background and foreground to default value (I'm told that ISO 6429 does this; but I don't have a written reference -- yet -- can anyone help here?). Anyway, rxvt does it, and it'll solve my remaining color management problems.
    • shadowing of 'time' in menu.c
    • 'Cardinal' vs 'int' in scrollbar.c
    • several changes to permit compile with X11R5 (the system that I've got Purify on won't be upgraded to X11R6 for a long time).

    I built this version (with a minor nit that I'll patch soon) on SunOS 4.1.3 so that I can test it some more with Purify.

    btw: the changes made in Xpoll.h won't work on some older systems, because fd_set isn't a defined type (I've got one machine at least that this applies to).

    Patch #6 - 1996/1/8

    This patch does all of the SGR foreground/background fixes (i.e., clearing the screen after an SGR color is set causes that color to be used in the foreground and/or background). If the FG_COLOR and/or BG_COLOR flags aren't set, then the xterm foreground and background default to the window's values. This usage is consistent with various types of hardware (especially the IBM PC), and is also used in rxvt.

    • charproc.c:
      • add/use new macros GET_FG, GET_BG - n/c.
      • add/use new functions SGR_Foreground() and SGR_Background() to set corresponding colors in GC's, and to retain sense of "original" colors.

        => This makes redundant some of the corresponding logic in HideCursor to set the foreground and background, but I left it in since it may be fixing an unrelated requirement.

      • set GC's in LoadNewFont() according to whether the SGR fg/bg colors are active.

        => This fixes some glitches in the accompanying resize, that leaves parts of the window in the original background color.

    • screen.c:
      • modified ClearBufRows() to use the SGR fg/bg colors if they're set.
      • added function ScrnClearLines(), used this to replace portions of ScrnInsertLine() and ScrnDeleteLine(). The new function uses the SGR fg/bg colors if they're set.

        => Otherwise, selection after an index or reverse index will paint the wrong colors.

      • modified ScrnDeleteChar() and ScrnInsertChar() to use SGR fg/bg colors.
    • util.c:
      • modified ClearRight() so that if either of the SGR fg/bg colors is set, we don't bzero the attributes and color arrays, but instead fill them with the appropriate codes.
      • modified ClearLeft to use SGR fg/bg colors.

    Patch #5 - 1996/1/7

    This patch modifies the object code, by replacing indexing expressions with temporary variables with the full indexing expression. At first glance, this seems inefficient (it did to me ;-), until remembering comments made in the compilers newsgroups that trying to "help" the compiler doesn't really work that well. A good optimizing compiler can do a better job than the programmer can. (There's a moral in the use of 'register' variables also, but I won't fix those...).

    Anyway, the revised code generates a smaller object...

    • charproc.c:
      • recode index expressions in ShowCursor() and HideCursor() using SCRN_BUF_xxxxS macros - changes object.
      • replace constant '4' by MAX_PTRS - n/c.
    • ptyx.h:
      • defined the SCRN_BUF_xxxxS macros in terms of BUF_xxxxS macros, to pick up references to ScrnBuf data directly, and added MAX_PTRS symbol to pick up those '4' constants strewn about the code - n/c.
    • screen.c:
      • recode index expressions in ScreenWrite() using SCRN_BUF_xxxxS macros - changes object.
      • replace constant '4' by MAX_PTRS - n/c.
      • use macros BUF_CHARS, BUF_ATTRS - n/c.
      • cast calloc to 'Char *' to fix compiler warning on IRIX - n/c
    • scrollbar.c:
      • replace constant '4' by MAX_PTRS - n/c.
      • cast calloc to 'Char *' to fix compiler warning on IRIX - n/c

    Patch #4 - 1996/1/7

    When setting up for this phase, I saw that you'd corrected the bug that I found in ClearLeft. I decided to make this series of patches anyway, since readability never hurt (and there's the potential for finding another bug while reviewing this set).

    • button.c:
      • use SCRN_BUF_xxxxS macros - n/c
    • charproc.c:
      • use SCRN_BUF_xxxxS macros - n/c
    • ptyx.h:
      • added four macros: SCRN_BUF_CHARS, SCRN_BUF_ATTRS, SCRN_BUF_FORES, SCRN_BUF_BACKS to represent the four arrays that are derived from screen->buf.
    • screen.c:
      • use SCRN_BUF_xxxxS macros - n/c
    • util.c:
      • use SCRN_BUF_xxxxS macros - n/c

    Patch #3 - 1996/1/7

    This is my third (and final cleanup) patch for xterm. It gets rid of the unused stuff, and converts several functions to static (thereby reducing their scope).

    At this point, the only compile warnings I've got (on Linux) are those about the select arguments (int vs fd_set type), and a missing declaration for waitpid. Those both are hard to get right without autoconfigure.

    The next patches will address the functional changes...

    • Tekproc.c:
      • changed several functions to 'static' that aren't used outside this module -- changes object
    • charproc.c:
      • changed several functions to 'static' that aren't used outside this module -- changes object
      • deleted unused function unparsefputs -- changes object.
    • main.c:
      • changed several functions to 'static' that aren't used outside this module -- changes object
      • ifdef'd out unused function 'consolepr()' -- changes object
      • removed unused variable 'dummy_tio' -- changes object
      • moved variable 'discipline' to quiet unused-warning -- changes object
    • main.h:
      • deleted unused definition of DEFBORDERWIDTH - n/c
    • misc.c:
      • changed several functions to 'static' that aren't used outside this module -- changes object
      • provide dummy return statements for xerror and xioerror to quiet compiler warnings -- changes object
    • ptyx.h:
      • change sbuf_address and abuf_address to 'Char *' - n/c
    • resize.c:
      • changed several functions to 'static' that aren't used outside this module -- changes object
    • screen.c:
      • remove unnecessary 'Char **' casts - n/c
    • util.c:
      • changed several functions to 'static' that aren't used outside this module -- changes object

    Patch #2 - 1996/1/7

    This is my second patch to xterm. It corrects most of the gcc warnings (except for some that are due to X header files ;-). I compared objects to keep track of the changes that don't affect the object code (n/c) versus those that do.

    At this point, I'm compiling (fairly) clean with gcc options

            -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wnested-externs
    

    (I also compiled with -Wshadow, but while that found some things that I wanted to find, there's far too many warnings from the X headers to be usable in this context).

    The changes:

    • Tekproc.c:
      • parenthesized expression to avoid gcc warning -- n/c.
      • corrected nested-extern declaration for Bool waiting_for_initial_map; ourTopLevelShellArgs, and number_ourTopLevelShellArgs - n/c
    • charproc.c:
      • corrected potentially-unintialized variables 'scstype', 'xim', and 'input_style' -- changes object.
      • adjusted logic of VTparse so that gcc won't warn about setjmp clobbering parsestate -- changes object.
      • corrected initialization of 'scstype', which could have been clobbered by setjmp/longjmp - changes object.
      • corrected nested-extern declaration of 'term', 'ProgramName' - n/c
    • cursor.c:
      • corrected nested-extern declaration of 'term' -- n/c
      • renamed 'term' parameters to avoid gcc -Wshadow warning - n/c
    • input.c:
      • change interface of StringInput to assume size_t (i.e., unsigned) nbytes -- changes object.
      • change interface of funcvalue, and sunfuncvalue to use 'KeySym' type instead of 'int' - changes object.
    • main.c:
      • moved definitions of SIGNAL_T, SIGNAL_RETURN to proto.h - n/c
      • corrected missing params of 'do_hangup()' -- changes object (note: the missing params were not used).
      • corrected missing param of 'Error()' -- changes object
      • corrected nested-extern 'environ' - n/c
      • adjusted assignments to 'tty_got_hung' and 'no_dev_tty' so that gcc can see they won't be clobbered by the longjmp - changes object.
      • use Size_t type - n/c.
    • menu.c:
      • removed redundant prototype for 'do_hangup()' -- n/c.
      • renamed 'time' parameters to avoid gcc -Wshadow warning - n/c
    • menu.h:
      • renamed 'time' parameters to avoid gcc -Wshadow warning - n/c
    • misc.c:
      • corrected definition of 'HandleFocusChange()' -- changes object
      • cast parameters in call to 'TekExpose()' -- n/c
      • corrected nested-extern declarations of 'term', 'toplevel', ProgramName, and 'environ' -- n/c.
      • use Size_t type - n/c.
    • proto.h:
      • moved definition of SIGNAL_T (and SIGNAL_RETURN) here from main.c, resize.c to allow use of this symbol in prototypes (mostly in xterm.h).
      • added definition 'Size_t' to use as corrected type for strncpy, malloc sizes - n/c.
    • resize.c:
      • moved SIGNAL_T definition to proto.h -- n/c.
      • use Size_t type - n/c.
    • screen.c:
      • use Size_t type - n/c.
    • tabs.c:
      • corrected nested-extern declaration of 'term' -- n/c
    • util.c:
      • corrected/supplied parameters to 'TekExpose()' -- changes object (note: 'TekExpose()' doesn't use its parameters).
      • corrected nested-extern declaration of 'waiting_for_initial_map' -- n/c.
      • renamed 'term' parameters to avoid gcc -Wshadow warning - n/c
    • xterm.h:
      • prototype 'do_hangup()', 'HandleFocusChange()', 'TekExpose()', 'Error()', 'Exit()' - forces changes in various places.
      • adjusted prototypes that pass 'Boolean' arguments to use 'int' (this is the "correct" ANSI approach to extended compiles; it's worth mentioning that gcc doesn't meet the ANSI spec here). I used gcc -Wconversion to find these, but there's a lot of unrelated warnings that are due to setting NARROWPROTO in the config - n/c.
      • renamed 'term' parameters to avoid gcc -Wshadow warning - n/c

    Patch #1 - 1996/1/6

    This is my first cleanup patch for xterm. It addresses all of the gcc warnings for -Wall, -Wmissing-prototypes and -Wstrict-prototypes that I can change without modifying the object code. (I'm compiling this with gcc 2.7.0 for an aout target, which makes it simple to compare objects. When I do ELF-only, I've got a tool that compares that sort of thing as well).

    Briefly, this patch adds (and uses) two header files in the xterm directory:

            proto.h
            xterm.h
    

    I expect this to be the biggest patch by far. However (barring a misplaced prototype), it shouldn't break anything, since the intent of the patch is to provide missing declarations.

    xterm-399/button.c0000644000000000000000000047157015011473154012733 0ustar rootroot/* $XTermId: button.c,v 1.672 2025/05/15 23:19:08 tom Exp $ */ /* * Copyright 1999-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* button.c Handles button events in the terminal emulator. does cut/paste operations, change modes via menu, passes button events through to some applications. J. Gettys. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if OPT_SELECT_REGEX #if defined(HAVE_PCRE2POSIX_H) #include /* pcre2 used to provide its "POSIX" entrypoints using the same names as the * standard ones in the C runtime, but that never worked because the linker * would use the C runtime. Debian patched the library to fix this symbol * conflict, but overlooked the header file, and Debian's patch was made * obsolete when pcre2 was changed early in 2019 to provide different names. * * Here is a workaround to make the older version of Debian's package work. */ #if !defined(PCRE2regcomp) && defined(HAVE_PCRE2REGCOMP) #undef regcomp #undef regexec #undef regfree #ifdef __cplusplus extern "C" { #endif PCRE2POSIX_EXP_DECL int PCRE2regcomp(regex_t *, const char *, int); PCRE2POSIX_EXP_DECL int PCRE2regexec(const regex_t *, const char *, size_t, regmatch_t *, int); PCRE2POSIX_EXP_DECL void PCRE2regfree(regex_t *); #ifdef __cplusplus } /* extern "C" */ #endif #define regcomp(r,s,n) PCRE2regcomp(r,s,n) #define regexec(r,s,n,m,x) PCRE2regexec(r,s,n,m,x) #define regfree(r) PCRE2regfree(r) #endif /* end workaround... */ #elif defined(HAVE_PCREPOSIX_H) #include #else /* POSIX regex.h */ #include #include #endif #endif /* OPT_SELECT_REGEX */ #ifdef HAVE_X11_TRANSLATEI_H #include #include #else extern String _XtPrintXlations(Widget w, XtTranslations xlations, Widget accelWidget, _XtBoolean includeRHS); #endif #define PRIMARY_NAME "PRIMARY" #define CLIPBOARD_NAME "CLIPBOARD" #define SECONDARY_NAME "SECONDARY" #define AtomToSelection(d,n) \ (((n) == XA_CLIPBOARD(d)) \ ? CLIPBOARD_CODE \ : (((n) == XA_SECONDARY) \ ? SECONDARY_CODE \ : PRIMARY_CODE)) #define isSelectionCode(n) ((n) >= PRIMARY_CODE) #define CutBufferToCode(n) ((n) + MAX_SELECTION_CODES) #define okSelectionCode(n) (isSelectionCode(n) ? (n) : PRIMARY_CODE) #if OPT_WIDE_CHARS #include #include #else #define CharacterClass(value) \ charClass[(value) & (int)((sizeof(charClass)/sizeof(charClass[0]))-1)] #endif /* * We'll generally map rows to indices when doing selection. * Simplify that with a macro. * * Note that ROW2INX() is safe to use with auto increment/decrement for * the row expression since that is evaluated once. */ #define GET_LINEDATA(screen, row) \ getLineData(screen, ROW2INX(screen, row)) #define MaxMouseBtn 5 #define IsBtnEvent(event) ((event)->type == ButtonPress || (event)->type == ButtonRelease) #define IsKeyEvent(event) ((event)->type == KeyPress || (event)->type == KeyRelease) #define Coordinate(s,c) ((c)->row * MaxCols(s) + (c)->col) static const CELL zeroCELL = {0, 0}; #if OPT_DEC_LOCATOR static Bool SendLocatorPosition(XtermWidget xw, XButtonEvent *event); static void CheckLocatorPosition(XtermWidget xw, XButtonEvent *event); #endif /* OPT_DEC_LOCATOR */ /* Multi-click handling */ #if OPT_READLINE static Time lastButtonDownTime = 0; static int ExtendingSelection = 0; static Time lastButton3UpTime = 0; static Time lastButton3DoubleDownTime = 0; static CELL lastButton3; /* At the release time */ #endif /* OPT_READLINE */ static Char *SaveText(TScreen *screen, int row, int scol, int ecol, Char *lp, int *eol); static int Length(TScreen *screen, int row, int scol, int ecol); static void ComputeSelect(XtermWidget xw, const CELL *startc, const CELL *endc, Bool extend, Bool normal); static void EditorButton(XtermWidget xw, XButtonEvent *event); static void EndExtend(XtermWidget w, XEvent *event, String *params, Cardinal num_params, Bool use_cursor_loc); static void ExtendExtend(XtermWidget xw, const CELL *cell); static void PointToCELL(TScreen *screen, int y, int x, CELL *cell); static void ReHiliteText(XtermWidget xw, const CELL *first, const CELL *last); static void SaltTextAway(XtermWidget xw, int which, const CELL *cellc, const CELL *cell); static void SelectSet(XtermWidget xw, XEvent *event, String *params, Cardinal num_params); static void SelectionReceived PROTO_XT_SEL_CB_ARGS; static void StartSelect(XtermWidget xw, const CELL *cell); static void TrackDown(XtermWidget xw, XButtonEvent *event); static void TrackText(XtermWidget xw, const CELL *first, const CELL *last); static void UnHiliteText(XtermWidget xw); static void _OwnSelection(XtermWidget xw, String *selections, Cardinal count); static void do_select_end(XtermWidget xw, XEvent *event, String *params, Cardinal *num_params, Bool use_cursor_loc); #define MOUSE_LIMIT (255 - 32) /* Send SET_EXT_SIZE_MOUSE to enable offsets up to EXT_MOUSE_LIMIT */ #define EXT_MOUSE_LIMIT (2047 - 32) #define EXT_MOUSE_START (127 - 32) static int MouseLimit(TScreen *screen) { int mouse_limit; switch (screen->extend_coords) { default: mouse_limit = MOUSE_LIMIT; break; case SET_EXT_MODE_MOUSE: mouse_limit = EXT_MOUSE_LIMIT; break; case SET_SGR_EXT_MODE_MOUSE: case SET_URXVT_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: mouse_limit = -1; break; } return mouse_limit; } static unsigned EmitMousePosition(TScreen *screen, Char line[], unsigned count, int value) { int mouse_limit = MouseLimit(screen); /* * Add pointer position to key sequence * * In extended mode we encode large positions as two-byte UTF-8. * * NOTE: historically, it was possible to emit 256, which became * zero by truncation to 8 bits. While this was arguably a bug, * it's also somewhat useful as a past-end marker. We preserve * this behavior for both normal and extended mouse modes. */ switch (screen->extend_coords) { default: if (value == mouse_limit) { line[count++] = CharOf(0); } else { line[count++] = CharOf(' ' + value + 1); } break; case SET_EXT_MODE_MOUSE: if (value == mouse_limit) { line[count++] = CharOf(0); } else if (value < EXT_MOUSE_START) { line[count++] = CharOf(' ' + value + 1); } else { value += ' ' + 1; line[count++] = CharOf(0xC0 + (value >> 6)); line[count++] = CharOf(0x80 + (value & 0x3F)); } break; case SET_SGR_EXT_MODE_MOUSE: case SET_URXVT_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: count += (unsigned) sprintf((char *) line + count, "%d", value + 1); break; } return count; } static unsigned EmitMousePositionSeparator(TScreen *screen, Char line[], unsigned count) { switch (screen->extend_coords) { case SET_SGR_EXT_MODE_MOUSE: case SET_URXVT_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: line[count++] = ';'; break; } return count; } enum { scanMods, scanKey, scanColon, scanFunc, scanArgs }; #if OPT_TRACE > 1 static const char * visibleScan(int mode) { const char *result = "?"; #define DATA(name) case name: result = #name; break switch (mode) { DATA(scanMods); DATA(scanKey); DATA(scanColon); DATA(scanFunc); DATA(scanArgs); } #undef DATA return result; } #endif #define L_BRACK '<' #define R_BRACK '>' #define L_PAREN '(' #define R_PAREN ')' static char * scanTrans(char *source, int *this_is, int *next_is, unsigned *first, unsigned *last) { char *target = source; *first = *last = 0; if (IsEmpty(target)) { target = NULL; } else { do { char ch; while (IsSpace(*target)) target++; *first = (unsigned) (target - source); switch (*this_is = *next_is) { case scanMods: while ((ch = *target)) { if (IsSpace(ch)) { break; } else if (ch == L_BRACK) { *next_is = scanKey; break; } else if (ch == ':') { *next_is = scanColon; break; } else if (ch == '~' && target != source) { break; } target++; } break; case scanKey: while ((ch = *target)) { if (IsSpace(ch)) { break; } else if (ch == ':') { *next_is = scanColon; break; } target++; if (ch == R_BRACK) break; } break; case scanColon: *next_is = scanFunc; target++; break; case scanFunc: while ((ch = *target)) { if (IsSpace(ch)) { break; } else if (ch == L_PAREN) { *next_is = scanArgs; break; } target++; } break; case scanArgs: while ((ch = *target)) { if (ch == R_PAREN) { target++; *next_is = scanFunc; break; } target++; } break; } *last = (unsigned) (target - source); if (*target == '\n') { *next_is = scanMods; target++; } } while (*first == *last); } return target; } void xtermButtonInit(XtermWidget xw) { Widget w = (Widget) xw; XErrorHandler save = XSetErrorHandler(ignore_x11_error); XtTranslations xlations; Widget xcelerat; String result; XtVaGetValues(w, XtNtranslations, &xlations, XtNaccelerators, &xcelerat, (XtPointer) 0); result = _XtPrintXlations(w, xlations, xcelerat, True); if (result) { static const char *table[] = { "insert-selection", "select-end", "select-extend", "select-start", "start-extend", }; char *data = x_strdup(result); char *next; int state = scanMods; int state2 = scanMods; unsigned first; unsigned last; int have_button = -1; Bool want_button = False; Bool have_shift = False; unsigned allowed = 0; unsigned disallow = 0; TRACE(("xtermButtonInit length %ld\n", (long) strlen(result))); xw->keyboard.print_translations = data; while ((next = scanTrans(data, &state, &state2, &first, &last)) != NULL) { unsigned len = (last - first); TRACE2(("parse %s:%d..%d '%.*s'\n", visibleScan(state), first, last, len, data + first)); if (state == scanMods) { if (len > 1 && data[first] == '~') { len--; first++; } if (len == 7 && !x_strncasecmp(data + first, "button", len - 1)) { have_button = data[first + 6] - '0'; } else if (len == 5 && !x_strncasecmp(data + first, "shift", len)) { have_shift = True; } } else if (state == scanKey) { if (!x_strncasecmp(data + first, "", len) || !x_strncasecmp(data + first, "", len)) { want_button = True; } else if (want_button) { have_button = data[first] - '0'; want_button = False; } } else if (state == scanFunc && have_button > 0) { Cardinal n; unsigned bmask = 1U << (have_button - 1); for (n = 0; n < XtNumber(table); ++n) { if (!x_strncasecmp(table[n], data + first, len)) { TRACE(("...button %d: %s%s\n", have_button, table[n], have_shift ? " (disallow)" : "")); if (have_shift) disallow |= bmask; else allowed |= bmask; break; } } } if (state2 == scanMods && state >= scanColon) { have_button = -1; want_button = False; have_shift = False; } state = state2; data = next; } XFree((char *) result); xw->keyboard.shift_buttons = allowed & ~disallow; #if OPT_TRACE if (xw->keyboard.shift_buttons) { int button = 0; unsigned mask = xw->keyboard.shift_buttons; TRACE(("...Buttons used for selection that can be overridden:")); while (mask != 0) { ++button; if ((mask & 1) != 0) TRACE((" %d", button)); mask >>= 1; } TRACE(("\n")); } else { TRACE(("...No buttons used with selection can be overridden\n")); } #endif } XSetErrorHandler(save); } /* * Shift and control are regular X11 modifiers, but meta is not: * + X10 (which had no xmodmap utility) had a meta mask, but X11 did not. * + X11R1 introduced xmodmap, along with the current set of modifier masks. * The meta key has been assumed to be mod1 since X11R1. * The initial xterm logic in X11 was different, but gave the same result. * + X11R2 modified xterm was to eliminate the X10 table which provided part of * the meta logic. * + X11R3 modified Xt, making Meta_L and Meta_R assignable via xmodmap, and * equating Alt with Meta. Neither Alt/Meta are modifiers, but Alt is more * likely to be on the keyboard. This release also added keymap tables for * the server; Meta was used frequently in HP keymaps, which were the most * extensive set of keymaps. * + X11R4 mentions Meta in the ICCCM, stating that if Meta_L or Meta_R are * found in the keysyms for a given modifier, that the client should use * that modifier. * * This function follows the ICCCM, picking the modifier which contains the * Meta_L/Meta_R keysyms (if available), falling back to the Alt_L/Alt_R * (as per X11R3), and ultimately to mod1 (per X11R1). */ static unsigned MetaMask(XtermWidget xw) { #if OPT_NUM_LOCK unsigned meta = xw->work.meta_mods; if (meta == 0) meta = xw->work.alt_mods; if (meta == 0) meta = Mod1Mask; #else unsigned meta = Mod1Mask; (void) xw; #endif return meta; } /* * Returns a mask of the modifiers we may use for modifying the mouse protocol * response strings. */ static unsigned OurModifiers(XtermWidget xw) { return (ShiftMask | ControlMask | MetaMask(xw)); } /* * The actual check for the shift-mask, to see if it should tell xterm to * override mouse-protocol in favor of select/paste actions depends upon * whether the shiftEscape resource is set to true/always vs false/never. */ static Boolean ShiftOverride(XtermWidget xw, unsigned state, int button) { unsigned check = (state & OurModifiers(xw)); Boolean result = False; if (check & ShiftMask) { if (xw->keyboard.shift_escape == ssFalse || xw->keyboard.shift_escape == ssNever) { result = True; } else if (xw->keyboard.shift_escape == ssTrue) { /* * Check if the button is one that we found does not directly use * the shift-modifier in its bindings to select/copy actions. */ if (button > 0 && button <= MaxMouseBtn) { if (xw->keyboard.shift_buttons & (1U << (button - 1))) { result = True; } } else { result = True; /* unlikely, and we don't care */ } } } TRACE2(("ShiftOverride ( %#x -> %#x ) %d\n", state, check, result)); return result; } /* * Normally xterm treats the shift-modifier specially when the mouse protocol * is active. The translations resource binds otherwise unmodified button * for these mouse-related events: * * ~Meta :select-start() \n\ * ~Meta :select-extend() \n\ * ~Ctrl ~Meta :insert-selection(SELECT, CUT_BUFFER0) \n\ * ~Ctrl ~Meta :start-extend() \n\ * ~Meta :select-extend() \n\ * :select-end(SELECT, CUT_BUFFER0) \n\ * * There is no API in the X libraries which would tell us if a given mouse * button is bound to one of these actions. These functions make the choice * configurable. */ static Bool InterpretButton(XtermWidget xw, XButtonEvent *event) { Bool result = False; if (ShiftOverride(xw, event->state, (int) event->button)) { TRACE(("...shift-button #%d overrides mouse-protocol\n", event->button)); result = True; } return result; } #define Button1Index 8 /* X.h should have done this */ static int MotionButton(unsigned state) { unsigned bmask = state >> Button1Index; int result = 1; if (bmask != 0) { while (!(bmask & 1)) { ++result; bmask >>= 1; } } return result; } static Bool InterpretEvent(XtermWidget xw, XEvent *event) { Bool result = False; /* if not a button, is motion */ if (IsBtnEvent(event)) { result = InterpretButton(xw, (XButtonEvent *) event); } else if (event->type == MotionNotify) { unsigned state = event->xmotion.state; int button = MotionButton(state); if (ShiftOverride(xw, state, button)) { TRACE(("...shift-motion #%d (%d,%d) overrides mouse-protocol\n", button, event->xmotion.y, event->xmotion.x)); result = True; } } return result; } #define OverrideEvent(event) InterpretEvent(xw, event) #define OverrideButton(event) InterpretButton(xw, event) /* * Returns true if we handled the event here, and nothing more is needed. */ Bool SendMousePosition(XtermWidget xw, XEvent *event) { XButtonEvent *my_event = (XButtonEvent *) event; Bool result = False; switch (okSendMousePos(xw)) { case MOUSE_OFF: /* If send_mouse_pos mode isn't on, we shouldn't be here */ break; case BTN_EVENT_MOUSE: case ANY_EVENT_MOUSE: if (!OverrideEvent(event)) { /* xterm extension for motion reporting. June 1998 */ /* EditorButton() will distinguish between the modes */ switch (event->type) { case MotionNotify: my_event->button = 0; /* FALLTHRU */ case ButtonPress: /* FALLTHRU */ case ButtonRelease: EditorButton(xw, my_event); result = True; break; } } break; case X10_MOUSE: /* X10 compatibility sequences */ if (IsBtnEvent(event)) { if (!OverrideButton(my_event)) { if (my_event->type == ButtonPress) EditorButton(xw, my_event); result = True; } } break; case VT200_HIGHLIGHT_MOUSE: /* DEC vt200 hilite tracking */ if (IsBtnEvent(event)) { if (!OverrideButton(my_event)) { if (my_event->type == ButtonPress && my_event->button == Button1) { TrackDown(xw, my_event); } else { EditorButton(xw, my_event); } result = True; } } break; case VT200_MOUSE: /* DEC vt200 compatible */ if (IsBtnEvent(event)) { if (!OverrideButton(my_event)) { EditorButton(xw, my_event); result = True; } } break; case DEC_LOCATOR: #if OPT_DEC_LOCATOR if (IsBtnEvent(event) || event->type == MotionNotify) { result = SendLocatorPosition(xw, my_event); } #endif /* OPT_DEC_LOCATOR */ break; } return result; } #if OPT_DEC_LOCATOR #define LocatorCoords( row, col, x, y, oor ) \ if( screen->locator_pixels ) { \ (oor)=False; (row) = (y)+1; (col) = (x)+1; \ /* Limit to screen dimensions */ \ if ((row) < 1) (row) = 1,(oor)=True; \ else if ((row) > screen->border*2+Height(screen)) \ (row) = screen->border*2+Height(screen),(oor)=True; \ if ((col) < 1) (col) = 1,(oor)=True; \ else if ((col) > OriginX(screen)*2+Width(screen)) \ (col) = OriginX(screen)*2+Width(screen),(oor)=True; \ } else { \ (oor)=False; \ /* Compute character position of mouse pointer */ \ (row) = ((y) - screen->border) / FontHeight(screen); \ (col) = ((x) - OriginX(screen)) / FontWidth(screen); \ /* Limit to screen dimensions */ \ if ((row) < 0) (row) = 0,(oor)=True; \ else if ((row) > screen->max_row) \ (row) = screen->max_row,(oor)=True; \ if ((col) < 0) (col) = 0,(oor)=True; \ else if ((col) > screen->max_col) \ (col) = screen->max_col,(oor)=True; \ (row)++; (col)++; \ } static Bool SendLocatorPosition(XtermWidget xw, XButtonEvent *event) { ANSI reply; TScreen *screen = TScreenOf(xw); int row, col; Bool oor; int button; unsigned state; /* Make sure the event is an appropriate type */ if (IsBtnEvent(event)) { if (OverrideButton(event)) return (False); } else { if (!screen->loc_filter) return (False); } if ((event->type == ButtonPress && !(screen->locator_events & LOC_BTNS_DN)) || (event->type == ButtonRelease && !(screen->locator_events & LOC_BTNS_UP))) return (True); if (event->type == MotionNotify) { CheckLocatorPosition(xw, event); return (True); } /* get button # */ button = (int) event->button - 1; LocatorCoords(row, col, event->x, event->y, oor); /* * DECterm mouse: * * ESCAPE '[' event ; mask ; row ; column '&' 'w' */ memset(&reply, 0, sizeof(reply)); reply.a_type = ANSI_CSI; if (oor) { reply.a_nparam = 1; reply.a_param[0] = 0; /* Event - 0 = locator unavailable */ reply.a_inters = '&'; reply.a_final = 'w'; unparseseq(xw, &reply); if (screen->locator_reset) { MotionOff(screen, xw); screen->send_mouse_pos = MOUSE_OFF; } return (True); } /* * event: * 1 no buttons * 2 left button down * 3 left button up * 4 middle button down * 5 middle button up * 6 right button down * 7 right button up * 8 M4 down * 9 M4 up */ reply.a_nparam = 4; switch (event->type) { case ButtonPress: reply.a_param[0] = (ParmType) (2 + (button << 1)); break; case ButtonRelease: reply.a_param[0] = (ParmType) (3 + (button << 1)); break; default: return (True); } /* * mask: * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 * M4 down left down middle down right down * * Notice that Button1 (left) and Button3 (right) are swapped in the mask. * Also, mask should be the state after the button press/release, * X provides the state not including the button press/release. */ state = (event->state & (Button1Mask | Button2Mask | Button3Mask | Button4Mask)) >> 8; /* update mask to "after" state */ state ^= ((unsigned) (1 << button)); /* swap Button1 & Button3 */ state = ((state & (unsigned) ~(4 | 1)) | ((state & 1) ? 4 : 0) | ((state & 4) ? 1 : 0)); reply.a_param[1] = (ParmType) state; reply.a_param[2] = (ParmType) row; reply.a_param[3] = (ParmType) col; reply.a_inters = '&'; reply.a_final = 'w'; unparseseq(xw, &reply); if (screen->locator_reset) { MotionOff(screen, xw); screen->send_mouse_pos = MOUSE_OFF; } /* * DECterm turns the Locator off if a button is pressed while a filter * rectangle is active. This might be a bug, but I don't know, so I'll * emulate it anyway. */ if (screen->loc_filter) { screen->send_mouse_pos = MOUSE_OFF; screen->loc_filter = False; screen->locator_events = 0; MotionOff(screen, xw); } return (True); } /* * mask: * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 * M4 down left down middle down right down * * Button1 (left) and Button3 (right) are swapped in the mask relative to X. */ #define ButtonState(state, mask) \ { int stemp = (int) (((mask) & (Button1Mask | Button2Mask | Button3Mask | Button4Mask)) >> 8); \ /* swap Button1 & Button3 */ \ (state) = (stemp & ~(4|1)) | ((stemp & 1) ? 4 : 0) | ((stemp & 4) ? 1 : 0); \ } void GetLocatorPosition(XtermWidget xw) { ANSI reply; TScreen *screen = TScreenOf(xw); Window root, child; int rx, ry, x, y; unsigned int mask = 0; int row = 0, col = 0; Bool oor = False; Bool ret = False; int state; /* * DECterm turns the Locator off if the position is requested while a * filter rectangle is active. This might be a bug, but I don't know, so * I'll emulate it anyways. */ if (screen->loc_filter) { screen->send_mouse_pos = MOUSE_OFF; screen->loc_filter = False; screen->locator_events = 0; MotionOff(screen, xw); } memset(&reply, 0, sizeof(reply)); reply.a_type = ANSI_CSI; if (okSendMousePos(xw) == DEC_LOCATOR) { ret = XQueryPointer(screen->display, VWindow(screen), &root, &child, &rx, &ry, &x, &y, &mask); if (ret) { LocatorCoords(row, col, x, y, oor); } } if (ret == False || oor) { reply.a_nparam = 1; reply.a_param[0] = 0; /* Event - 0 = locator unavailable */ reply.a_inters = '&'; reply.a_final = 'w'; unparseseq(xw, &reply); if (screen->locator_reset) { MotionOff(screen, xw); screen->send_mouse_pos = MOUSE_OFF; } return; } ButtonState(state, mask); reply.a_nparam = 4; reply.a_param[0] = 1; /* Event - 1 = response to locator request */ reply.a_param[1] = (ParmType) state; reply.a_param[2] = (ParmType) row; reply.a_param[3] = (ParmType) col; reply.a_inters = '&'; reply.a_final = 'w'; unparseseq(xw, &reply); if (screen->locator_reset) { MotionOff(screen, xw); screen->send_mouse_pos = MOUSE_OFF; } } void InitLocatorFilter(XtermWidget xw) { ANSI reply; TScreen *screen = TScreenOf(xw); Window root, child; int rx, ry, x, y; unsigned int mask; int row = 0, col = 0; Bool oor = 0; Bool ret; ret = XQueryPointer(screen->display, VWindow(screen), &root, &child, &rx, &ry, &x, &y, &mask); if (ret) { LocatorCoords(row, col, x, y, oor); } if (ret == False || oor) { /* Locator is unavailable */ if (screen->loc_filter_top != LOC_FILTER_POS || screen->loc_filter_left != LOC_FILTER_POS || screen->loc_filter_bottom != LOC_FILTER_POS || screen->loc_filter_right != LOC_FILTER_POS) { /* * If any explicit coordinates were received, * report immediately with no coordinates. */ memset(&reply, 0, sizeof(reply)); reply.a_type = ANSI_CSI; reply.a_nparam = 1; reply.a_param[0] = 0; /* Event - 0 = locator unavailable */ reply.a_inters = '&'; reply.a_final = 'w'; unparseseq(xw, &reply); if (screen->locator_reset) { MotionOff(screen, xw); screen->send_mouse_pos = MOUSE_OFF; } } else { /* * No explicit coordinates were received, and the pointer is * unavailable. Report when the pointer re-enters the window. */ screen->loc_filter = True; MotionOn(screen, xw); } return; } /* * Adjust rectangle coordinates: * 1. Replace "LOC_FILTER_POS" with current coordinates * 2. Limit coordinates to screen size * 3. make sure top and left are less than bottom and right, resp. */ if (screen->locator_pixels) { rx = OriginX(screen) * 2 + Width(screen); ry = screen->border * 2 + Height(screen); } else { rx = screen->max_col; ry = screen->max_row; } #define Adjust( coord, def, max ) \ if( (coord) == LOC_FILTER_POS ) (coord) = (def); \ else if ((coord) < 1) (coord) = 1; \ else if ((coord) > (max)) (coord) = (max) Adjust(screen->loc_filter_top, row, ry); Adjust(screen->loc_filter_left, col, rx); Adjust(screen->loc_filter_bottom, row, ry); Adjust(screen->loc_filter_right, col, rx); if (screen->loc_filter_top > screen->loc_filter_bottom) { ry = screen->loc_filter_top; screen->loc_filter_top = screen->loc_filter_bottom; screen->loc_filter_bottom = ry; } if (screen->loc_filter_left > screen->loc_filter_right) { rx = screen->loc_filter_left; screen->loc_filter_left = screen->loc_filter_right; screen->loc_filter_right = rx; } if ((col < screen->loc_filter_left) || (col > screen->loc_filter_right) || (row < screen->loc_filter_top) || (row > screen->loc_filter_bottom)) { int state; /* Pointer is already outside the rectangle - report immediately */ ButtonState(state, mask); memset(&reply, 0, sizeof(reply)); reply.a_type = ANSI_CSI; reply.a_nparam = 4; reply.a_param[0] = 10; /* Event - 10 = locator outside filter */ reply.a_param[1] = (ParmType) state; reply.a_param[2] = (ParmType) row; reply.a_param[3] = (ParmType) col; reply.a_inters = '&'; reply.a_final = 'w'; unparseseq(xw, &reply); if (screen->locator_reset) { MotionOff(screen, xw); screen->send_mouse_pos = MOUSE_OFF; } return; } /* * Rectangle is set up. Allow pointer tracking * to detect if the mouse leaves the rectangle. */ screen->loc_filter = True; MotionOn(screen, xw); } static void CheckLocatorPosition(XtermWidget xw, XButtonEvent *event) { ANSI reply; TScreen *screen = TScreenOf(xw); int row, col; Bool oor; LocatorCoords(row, col, event->x, event->y, oor); /* * Send report if the pointer left the filter rectangle, if * the pointer left the window, or if the filter rectangle * had no coordinates and the pointer re-entered the window. */ if (oor || (screen->loc_filter_top == LOC_FILTER_POS) || (col < screen->loc_filter_left) || (col > screen->loc_filter_right) || (row < screen->loc_filter_top) || (row > screen->loc_filter_bottom)) { /* Filter triggered - disable it */ screen->loc_filter = False; MotionOff(screen, xw); memset(&reply, 0, sizeof(reply)); reply.a_type = ANSI_CSI; if (oor) { reply.a_nparam = 1; reply.a_param[0] = 0; /* Event - 0 = locator unavailable */ } else { int state; ButtonState(state, event->state); reply.a_nparam = 4; reply.a_param[0] = 10; /* Event - 10 = locator outside filter */ reply.a_param[1] = (ParmType) state; reply.a_param[2] = (ParmType) row; reply.a_param[3] = (ParmType) col; } reply.a_inters = '&'; reply.a_final = 'w'; unparseseq(xw, &reply); if (screen->locator_reset) { MotionOff(screen, xw); screen->send_mouse_pos = MOUSE_OFF; } } } #endif /* OPT_DEC_LOCATOR */ #if OPT_READLINE static int isClick1_clean(XtermWidget xw, XButtonEvent *event) { TScreen *screen = TScreenOf(xw); int delta; /* Disable on Shift-Click-1, including the application-mouse modes */ if (OverrideButton(event) || (okSendMousePos(xw) != MOUSE_OFF) || ExtendingSelection) /* Was moved */ return 0; if (event->type != ButtonRelease) return 0; if (lastButtonDownTime == (Time) 0) { /* first time or once in a blue moon */ delta = screen->multiClickTime + 1; } else if (event->time > lastButtonDownTime) { /* most of the time */ delta = (int) (event->time - lastButtonDownTime); } else { /* time has rolled over since lastButtonUpTime */ delta = (int) ((((Time) ~ 0) - lastButtonDownTime) + event->time); } return delta <= screen->multiClickTime; } static int isDoubleClick3(XtermWidget xw, TScreen *screen, XButtonEvent *event) { int delta; if (event->type != ButtonRelease || OverrideButton(event) || event->button != Button3) { lastButton3UpTime = 0; /* Disable the cached info */ return 0; } /* Process Btn3Release. */ if (lastButton3DoubleDownTime == (Time) 0) { /* No previous click or once in a blue moon */ delta = screen->multiClickTime + 1; } else if (event->time > lastButton3DoubleDownTime) { /* most of the time */ delta = (int) (event->time - lastButton3DoubleDownTime); } else { /* time has rolled over since lastButton3DoubleDownTime */ delta = (int) ((((Time) ~ 0) - lastButton3DoubleDownTime) + event->time); } if (delta <= screen->multiClickTime) { /* Double click */ CELL cell; /* Cannot check ExtendingSelection, since mouse-3 always sets it */ PointToCELL(screen, event->y, event->x, &cell); if (isSameCELL(&cell, &lastButton3)) { lastButton3DoubleDownTime = 0; /* Disable the third click */ return 1; } } /* Not a double click, memorize for future check. */ lastButton3UpTime = event->time; PointToCELL(screen, event->y, event->x, &lastButton3); return 0; } static int CheckSecondPress3(XtermWidget xw, TScreen *screen, XEvent *event) { int delta; if (event->type != ButtonPress || OverrideEvent(event) || event->xbutton.button != Button3) { lastButton3DoubleDownTime = 0; /* Disable the cached info */ return 0; } /* Process Btn3Press. */ if (lastButton3UpTime == (Time) 0) { /* No previous click or once in a blue moon */ delta = screen->multiClickTime + 1; } else if (event->xbutton.time > lastButton3UpTime) { /* most of the time */ delta = (int) (event->xbutton.time - lastButton3UpTime); } else { /* time has rolled over since lastButton3UpTime */ delta = (int) ((((Time) ~ 0) - lastButton3UpTime) + event->xbutton.time); } if (delta <= screen->multiClickTime) { CELL cell; PointToCELL(screen, event->xbutton.y, event->xbutton.x, &cell); if (isSameCELL(&cell, &lastButton3)) { /* A candidate for a double-click */ lastButton3DoubleDownTime = event->xbutton.time; PointToCELL(screen, event->xbutton.y, event->xbutton.x, &lastButton3); return 1; } lastButton3UpTime = 0; /* Disable the info about the previous click */ } /* Either too long, or moved, disable. */ lastButton3DoubleDownTime = 0; return 0; } static int rowOnCurrentLine(TScreen *screen, int line, int *deltap) /* must be XButtonEvent */ { int result = 1; *deltap = 0; if (line != screen->cur_row) { int l1, l2; if (line < screen->cur_row) { l1 = line; l2 = screen->cur_row; } else { l2 = line; l1 = screen->cur_row; } l1--; while (++l1 < l2) { LineData *ld = GET_LINEDATA(screen, l1); if (!LineTstWrapped(ld)) { result = 0; break; } } if (result) { /* Everything is on one "wrapped line" now */ *deltap = line - screen->cur_row; } } return result; } static int eventRow(TScreen *screen, XEvent *event) /* must be XButtonEvent */ { return (event->xbutton.y - screen->border) / FontHeight(screen); } static int eventColBetween(TScreen *screen, XEvent *event) /* must be XButtonEvent */ { /* Correct by half a width - we are acting on a boundary, not on a cell. */ return ((event->xbutton.x - OriginX(screen) + (FontWidth(screen) - 1) / 2) / FontWidth(screen)); } static int ReadLineMovePoint(XtermWidget xw, int col, int ldelta) { TScreen *screen = TScreenOf(xw); Char line[6]; unsigned count = 0; col += ldelta * MaxCols(screen) - screen->cur_col; if (col == 0) return 0; if (screen->control_eight_bits) { line[count++] = ANSI_CSI; } else { line[count++] = ANSI_ESC; line[count++] = (xw->keyboard.flags & MODE_DECCKM) ? 'O' : '['; } line[count] = CharOf(col > 0 ? 'C' : 'D'); if (col < 0) col = -col; while (col--) v_write(screen->respond, line, (size_t) 3); return 1; } static int ReadLineDelete(TScreen *screen, CELL *cell1, CELL *cell2) { int del; Char erases[2]; erases[0] = (Char) get_tty_erase(screen->respond, XTERM_ERASE, "pty"); erases[1] = 0; del = (cell2->col - cell1->col) + ((cell2->row - cell1->row) * MaxCols(screen)); if (del <= 0) /* Just in case... */ return 0; while (del--) v_write(screen->respond, erases, (size_t) 1); return 1; } static void readlineExtend(XtermWidget xw, XEvent *event) { TScreen *screen = TScreenOf(xw); int ldelta1, ldelta2; if (IsBtnEvent(event)) { XButtonEvent *my_event = (XButtonEvent *) event; if (isClick1_clean(xw, my_event) && SCREEN_FLAG(screen, click1_moves) && rowOnCurrentLine(screen, eventRow(screen, event), &ldelta1)) { ReadLineMovePoint(xw, eventColBetween(screen, event), ldelta1); } if (isDoubleClick3(xw, screen, my_event) && SCREEN_FLAG(screen, dclick3_deletes) && rowOnCurrentLine(screen, screen->startSel.row, &ldelta1) && rowOnCurrentLine(screen, screen->endSel.row, &ldelta2)) { ReadLineMovePoint(xw, screen->endSel.col, ldelta2); ReadLineDelete(screen, &screen->startSel, &(screen->endSel)); } } } #endif /* OPT_READLINE */ /* ^XM-G */ void DiredButton(Widget w, XEvent *event, /* must be XButtonEvent */ String *params GCC_UNUSED, /* selections */ Cardinal *num_params GCC_UNUSED) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TScreen *screen = TScreenOf(xw); if (IsBtnEvent(event) && (event->xbutton.y >= screen->border) && (event->xbutton.x >= OriginX(screen))) { Char Line[6]; unsigned line, col; line = (unsigned) ((event->xbutton.y - screen->border) / FontHeight(screen)); col = (unsigned) ((event->xbutton.x - OriginX(screen)) / FontWidth(screen)); Line[0] = CONTROL('X'); Line[1] = ANSI_ESC; Line[2] = 'G'; Line[3] = CharOf(' ' + col); Line[4] = CharOf(' ' + line); v_write(screen->respond, Line, (size_t) 5); } } } #if OPT_READLINE void ReadLineButton(Widget w, XEvent *event, /* must be XButtonEvent */ String *params, /* selections */ Cardinal *num_params) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TScreen *screen = TScreenOf(xw); Char Line[6]; int line, col, ldelta = 0; if (!IsBtnEvent(event) || (okSendMousePos(xw) != MOUSE_OFF) || ExtendingSelection) goto finish; if (event->type == ButtonRelease) { int delta; if (lastButtonDownTime == (Time) 0) { /* first time and once in a blue moon */ delta = screen->multiClickTime + 1; } else if (event->xbutton.time > lastButtonDownTime) { /* most of the time */ delta = (int) (event->xbutton.time - lastButtonDownTime); } else { /* time has rolled over since lastButtonUpTime */ delta = (int) ((((Time) ~ 0) - lastButtonDownTime) + event->xbutton.time); } if (delta > screen->multiClickTime) goto finish; /* All this work for this... */ } line = (event->xbutton.y - screen->border) / FontHeight(screen); if (!rowOnCurrentLine(screen, line, &ldelta)) goto finish; /* Correct by half a width - we are acting on a boundary, not on a cell. */ col = (event->xbutton.x - OriginX(screen) + (FontWidth(screen) - 1) / 2) / FontWidth(screen) - screen->cur_col + ldelta * MaxCols(screen); if (col == 0) goto finish; Line[0] = ANSI_ESC; Line[1] = (xw->keyboard.flags & MODE_DECCKM) ? 'O' : '['; Line[2] = CharOf(col > 0 ? 'C' : 'D'); if (col < 0) col = -col; while (col--) v_write(screen->respond, Line, (size_t) 3); finish: if (event->type == ButtonRelease) do_select_end(xw, event, params, num_params, False); } } #endif /* OPT_READLINE */ /* repeats n or p */ void ViButton(Widget w, XEvent *event, /* must be XButtonEvent */ String *params GCC_UNUSED, /* selections */ Cardinal *num_params GCC_UNUSED) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TScreen *screen = TScreenOf(xw); int pty = screen->respond; if (IsBtnEvent(event)) { int line; line = screen->cur_row - ((event->xbutton.y - screen->border) / FontHeight(screen)); if (line != 0) { Char Line[6]; Line[0] = ANSI_ESC; /* force an exit from insert-mode */ v_write(pty, Line, (size_t) 1); if (line < 0) { line = -line; Line[0] = CONTROL('n'); } else { Line[0] = CONTROL('p'); } while (--line >= 0) v_write(pty, Line, (size_t) 1); } } } } /* * This function handles button-motion events */ /*ARGSUSED*/ void HandleSelectExtend(Widget w, XEvent *event, /* must be XMotionEvent */ String *params GCC_UNUSED, Cardinal *num_params GCC_UNUSED) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TScreen *screen = TScreenOf(xw); CELL cell; TRACE_EVENT("HandleSelectExtend", event, params, num_params); screen->selection_time = event->xmotion.time; switch (screen->eventMode) { /* If not in one of the DEC mouse-reporting modes */ case LEFTEXTENSION: case RIGHTEXTENSION: PointToCELL(screen, event->xmotion.y, event->xmotion.x, &cell); ExtendExtend(xw, &cell); break; /* If in motion reporting mode, send mouse position to character process as a key sequence \E[M... */ case NORMAL: /* will get here if send_mouse_pos != MOUSE_OFF */ if (okSendMousePos(xw) == BTN_EVENT_MOUSE || okSendMousePos(xw) == ANY_EVENT_MOUSE) { (void) SendMousePosition(xw, event); } break; } } } void HandleKeyboardSelectExtend(Widget w, XEvent *event GCC_UNUSED, /* must be XButtonEvent */ String *params GCC_UNUSED, Cardinal *num_params GCC_UNUSED) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TScreen *screen = TScreenOf(xw); TRACE_EVENT("HandleKeyboardSelectExtend", event, params, num_params); ExtendExtend(xw, &screen->cursorp); } } static void do_select_end(XtermWidget xw, XEvent *event, /* must be XButtonEvent */ String *params, /* selections */ Cardinal *num_params, Bool use_cursor_loc) { TScreen *screen = TScreenOf(xw); screen->selection_time = event->xbutton.time; TRACE(("do_select_end %s @%ld\n", visibleEventMode(screen->eventMode), screen->selection_time)); switch (screen->eventMode) { case NORMAL: (void) SendMousePosition(xw, event); break; case LEFTEXTENSION: case RIGHTEXTENSION: EndExtend(xw, event, params, *num_params, use_cursor_loc); #if OPT_READLINE readlineExtend(xw, event); #endif /* OPT_READLINE */ break; } } void HandleSelectEnd(Widget w, XEvent *event, /* must be XButtonEvent */ String *params, /* selections */ Cardinal *num_params) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TRACE(("HandleSelectEnd\n")); do_select_end(xw, event, params, num_params, False); } } void HandleKeyboardSelectEnd(Widget w, XEvent *event, /* must be XButtonEvent */ String *params, /* selections */ Cardinal *num_params) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TRACE(("HandleKeyboardSelectEnd\n")); do_select_end(xw, event, params, num_params, True); } } void HandlePointerMotion(Widget w, XEvent *event, String *params, /* selections */ Cardinal *num_params) { XtermWidget xw; (void) params; (void) num_params; if ((xw = getXtermWidget(w)) != NULL) { TRACE(("HandlePointerMotion\n")); if (event->type == MotionNotify) (void) SendMousePosition(xw, event); } } void HandlePointerButton(Widget w, XEvent *event, String *params, /* selections */ Cardinal *num_params) { XtermWidget xw; (void) params; (void) num_params; if ((xw = getXtermWidget(w)) != NULL) { TRACE(("HandlePointerButton\n")); if (IsBtnEvent(event)) (void) SendMousePosition(xw, event); } } /* * Copy the selection data to the given target(s). */ void HandleCopySelection(Widget w, XEvent *event, String *params, /* list of targets */ Cardinal *num_params) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TRACE_EVENT("HandleCopySelection", event, params, num_params); SelectSet(xw, event, params, *num_params); } } struct _SelectionList { String *params; Cardinal count; Atom *targets; Time time; }; static unsigned DECtoASCII(unsigned ch) { if (xtermIsDecGraphic(ch)) { ch = CharOf("###########+++++##-##++++|######"[ch]); /* 01234567890123456789012345678901 */ } else { ch = '?'; /* DEC Technical has no mapping */ } return ch; } #if OPT_WIDE_CHARS static Cardinal addXtermChar(Char **buffer, Cardinal *used, Cardinal offset, unsigned value) { if (offset + 1 >= *used) { *used = 1 + (2 * (offset + 1)); allocXtermChars(buffer, *used); } (*buffer)[offset++] = (Char) value; return offset; } #define AddChar(buffer, used, offset, value) \ offset = addXtermChar(buffer, used, offset, (unsigned) value) /* * Convert a UTF-8 string to Latin-1, replacing non Latin-1 characters by `#', * or ASCII/Latin-1 equivalents for special cases. */ static Char * UTF8toLatin1(TScreen *screen, Char *s, unsigned long len, unsigned long *result) { static Char *buffer; static Cardinal used; Cardinal offset = 0; if (len != 0) { PtyData data; Boolean save_vt100 = screen->vt100_graphics; fakePtyData(&data, s, s + len); screen->vt100_graphics = False; /* temporary override */ while (decodeUtf8(screen, &data)) { Bool fails = False; Bool extra = False; IChar value; skipPtyData(&data, value); if (is_UCS_SPECIAL(value)) { fails = True; } else if (value < 256) { AddChar(&buffer, &used, offset, CharOf(value)); } else { unsigned eqv = ucs2dec(screen, value); if (xtermIsInternalCs(eqv)) { AddChar(&buffer, &used, offset, DECtoASCII(eqv)); } else { eqv = AsciiEquivs(value); if (eqv == value) { fails = True; } else { AddChar(&buffer, &used, offset, eqv); } if (isWide((wchar_t) value)) extra = True; } } /* * If we're not able to plug in a single-byte result, insert the * defaultString (which normally is a single "#", but could be * whatever the user wants). */ if (fails) { const Char *p; for (p = (const Char *) screen->default_string; *p != '\0'; ++p) { AddChar(&buffer, &used, offset, *p); } } if (extra) AddChar(&buffer, &used, offset, ' '); } AddChar(&buffer, &used, offset, '\0'); screen->vt100_graphics = save_vt100; *result = (unsigned long) (offset - 1); } else { *result = 0; } return buffer; } int xtermUtf8ToTextList(XtermWidget xw, XTextProperty * text_prop, char ***text_list, int *text_list_count) { TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; int rc = -1; if (text_prop->format == 8 && (rc = Xutf8TextPropertyToTextList(dpy, text_prop, text_list, text_list_count)) >= 0) { if (*text_list != NULL && *text_list_count != 0) { int i; Char *data; char **new_text_list, *tmp; unsigned long size, new_size; TRACE(("xtermUtf8ToTextList size %d\n", *text_list_count)); /* * XLib StringList actually uses only two pointers, one for the * list itself, and one for the data. Pointer to the data is the * first element of the list, the rest (if any) list elements point * to the same memory block as the first element */ new_size = 0; for (i = 0; i < *text_list_count; ++i) { data = (Char *) (*text_list)[i]; size = strlen((*text_list)[i]) + 1; (void) UTF8toLatin1(screen, data, size, &size); new_size += size + 1; } new_text_list = TypeXtMallocN(char *, *text_list_count); new_text_list[0] = tmp = XtMalloc((Cardinal) new_size); for (i = 0; i < (*text_list_count); ++i) { data = (Char *) (*text_list)[i]; size = strlen((*text_list)[i]) + 1; if ((data = UTF8toLatin1(screen, data, size, &size)) != NULL) { memcpy(tmp, data, size + 1); new_text_list[i] = tmp; tmp += size + 1; } } XFreeStringList((*text_list)); *text_list = new_text_list; } else { rc = -1; } } return rc; } #endif /* OPT_WIDE_CHARS */ static char * parseItem(char *value, char *nextc) { char *nextp = value; while (*nextp != '\0' && *nextp != ',') { *nextp = x_toupper(*nextp); ++nextp; } *nextc = *nextp; *nextp = '\0'; return nextp; } /* * All of the wanted strings are unique in the first character, so we can * use simple abbreviations. */ static Bool sameItem(const char *actual, const char *wanted) { Bool result = False; size_t have = strlen(actual); size_t need = strlen(wanted); if (have != 0 && have <= need) { if (!strncmp(actual, wanted, have)) { TRACE(("...matched \"%s\"\n", wanted)); result = True; } } return result; } /* * Handle the eightBitSelectTypes or utf8SelectTypes resource values. */ static Bool overrideTargets(Widget w, String value, Atom **resultp) { Bool override = False; XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TScreen *screen = TScreenOf(xw); if (!IsEmpty(value)) { char *copied = x_strdup(value); if (copied != NULL) { Atom *result = NULL; Cardinal count = 1; int n; TRACE(("decoding SelectTypes \"%s\"\n", value)); for (n = 0; copied[n] != '\0'; ++n) { if (copied[n] == ',') ++count; } result = TypeXtMallocN(Atom, (2 * count) + 1); if (result == NULL) { TRACE(("Couldn't allocate selection types\n")); } else { char nextc = '?'; char *listp = (char *) copied; count = 0; do { char *nextp = parseItem(listp, &nextc); char *item = x_strtrim(listp); size_t len = (item ? strlen(item) : 0); if (len == 0) { /* EMPTY */ ; } #if OPT_WIDE_CHARS else if (sameItem(item, "UTF8")) { result[count++] = XA_UTF8_STRING(XtDisplay(w)); } #endif else if (sameItem(item, "I18N")) { if (screen->i18nSelections) { result[count++] = XA_TEXT(XtDisplay(w)); result[count++] = XA_COMPOUND_TEXT(XtDisplay(w)); } } else if (sameItem(item, "TEXT")) { result[count++] = XA_TEXT(XtDisplay(w)); } else if (sameItem(item, "COMPOUND_TEXT")) { result[count++] = XA_COMPOUND_TEXT(XtDisplay(w)); } else if (sameItem(item, "STRING")) { result[count++] = XA_STRING; } *nextp++ = nextc; listp = nextp; free(item); } while (nextc != '\0'); if (count) { result[count] = None; override = True; *resultp = result; } else { XtFree((char *) result); } } free(copied); } else { TRACE(("Couldn't allocate copy of selection types\n")); } } } return override; } #if OPT_WIDE_CHARS static Atom * allocUtf8Targets(Widget w, TScreen *screen) { Atom **resultp = &(screen->selection_targets_utf8); if (*resultp == NULL) { Atom *result; if (!overrideTargets(w, screen->utf8_select_types, &result)) { result = TypeXtMallocN(Atom, 5); if (result == NULL) { TRACE(("Couldn't allocate utf-8 selection targets\n")); } else { int n = 0; if (XSupportsLocale()) { result[n++] = XA_UTF8_STRING(XtDisplay(w)); #ifdef X_HAVE_UTF8_STRING if (screen->i18nSelections) { result[n++] = XA_TEXT(XtDisplay(w)); result[n++] = XA_COMPOUND_TEXT(XtDisplay(w)); } #endif } result[n++] = XA_STRING; result[n] = None; } } *resultp = result; } return *resultp; } #endif static Atom * alloc8bitTargets(Widget w, TScreen *screen) { Atom **resultp = &(screen->selection_targets_8bit); if (*resultp == NULL) { Atom *result = NULL; if (!overrideTargets(w, screen->eightbit_select_types, &result)) { result = TypeXtMallocN(Atom, 5); if (result == NULL) { TRACE(("Couldn't allocate 8bit selection targets\n")); } else { int n = 0; if (XSupportsLocale()) { #ifdef X_HAVE_UTF8_STRING result[n++] = XA_UTF8_STRING(XtDisplay(w)); #endif if (screen->i18nSelections) { result[n++] = XA_TEXT(XtDisplay(w)); result[n++] = XA_COMPOUND_TEXT(XtDisplay(w)); } } result[n++] = XA_STRING; result[n] = None; } } *resultp = result; } return *resultp; } static Atom * _SelectionTargets(Widget w) { Atom *result; XtermWidget xw; if ((xw = getXtermWidget(w)) == NULL) { result = NULL; } else { TScreen *screen = TScreenOf(xw); #if OPT_WIDE_CHARS if (screen->wide_chars) { result = allocUtf8Targets(w, screen); } else #endif { /* not screen->wide_chars */ result = alloc8bitTargets(w, screen); } } return result; } #define isSELECT(value) (!strcmp(NonNull(value), "SELECT")) static int DefaultSelection(TScreen *screen) { return (screen->selectToClipboard ? 1 : 0); } static int TargetToSelection(TScreen *screen, String name) { int result = -1; int cutb; if (isSELECT(name)) { result = DefaultSelection(screen); } else if (!strcmp(name, PRIMARY_NAME)) { result = PRIMARY_CODE; } else if (!strcmp(name, CLIPBOARD_NAME)) { result = CLIPBOARD_CODE; } else if (!strcmp(name, SECONDARY_NAME)) { result = SECONDARY_CODE; } else if (sscanf(name, "CUT_BUFFER%d", &cutb) == 1) { if (cutb >= 0 && cutb < MAX_CUT_BUFFER) { result = CutBufferToCode(cutb); } else { xtermWarning("unexpected cut-buffer code: %d\n", cutb); } } else { xtermWarning("unexpected selection target: %s\n", name); } TRACE2(("TargetToSelection(%s) ->%d\n", name, result)); return result; } void UnmapSelections(XtermWidget xw) { TScreen *screen = TScreenOf(xw); FreeAndNull(screen->mappedSelect); } /* * xterm generally uses the primary selection. Some applications prefer * (or are limited to) the clipboard. Since the translations resource is * complicated, users seldom change the way it affects selection. But it * is simple to remap the choice between primary and clipboard before the * call to XmuInternStrings(). */ static String * MapSelections(XtermWidget xw, String *params, Cardinal num_params) { String *result = params; if (params != NULL && num_params > 0) { Cardinal j; Boolean map = False; for (j = 0; j < num_params; ++j) { TRACE(("param[%d]:%s\n", j, params[j])); if (isSELECT(params[j])) { map = True; break; } } if (map) { TScreen *screen = TScreenOf(xw); const char *mapTo = (screen->selectToClipboard ? CLIPBOARD_NAME : PRIMARY_NAME); UnmapSelections(xw); if ((result = TypeMallocN(String, num_params + 1)) != NULL) { result[num_params] = NULL; for (j = 0; j < num_params; ++j) { result[j] = (String) (isSELECT(params[j]) ? mapTo : params[j]); if (result[j] == NULL) { UnmapSelections(xw); FreeAndNull(result); break; } } screen->mappedSelect = result; } } } return result; } /* * Lookup the cut-buffer number, which will be in the range 0-7. * If it is not a cut-buffer, it is a type of selection, e.g., primary. */ static int CutBuffer(Atom code) { int cutbuffer; switch ((unsigned) code) { case XA_CUT_BUFFER0: cutbuffer = 0; break; case XA_CUT_BUFFER1: cutbuffer = 1; break; case XA_CUT_BUFFER2: cutbuffer = 2; break; case XA_CUT_BUFFER3: cutbuffer = 3; break; case XA_CUT_BUFFER4: cutbuffer = 4; break; case XA_CUT_BUFFER5: cutbuffer = 5; break; case XA_CUT_BUFFER6: cutbuffer = 6; break; case XA_CUT_BUFFER7: cutbuffer = 7; break; default: cutbuffer = -1; break; } TRACE2(("CutBuffer(%d) = %d\n", (int) code, cutbuffer)); return cutbuffer; } #if OPT_PASTE64 static void FinishPaste64(XtermWidget xw) { TScreen *screen = TScreenOf(xw); TRACE(("FinishPaste64(%d)\n", screen->base64_paste)); if (screen->base64_paste) { screen->base64_paste = 0; unparseputc1(xw, screen->base64_final); unparse_end(xw); } } #endif #if !OPT_PASTE64 static #endif void xtermGetSelection(Widget w, Time ev_time, String *params, /* selections in precedence order */ Cardinal num_params, Atom *targets) { Atom selection; int cutbuffer; Atom target; XtermWidget xw; if (num_params == 0) return; if ((xw = getXtermWidget(w)) == NULL) return; TRACE(("xtermGetSelection num_params %d @%ld\n", num_params, ev_time)); params = MapSelections(xw, params, num_params); XmuInternStrings(XtDisplay(w), params, (Cardinal) 1, &selection); cutbuffer = CutBuffer(selection); TRACE(("Cutbuffer: %d, target: %s\n", cutbuffer, (targets ? visibleSelectionTarget(XtDisplay(w), targets[0]) : "None"))); if (cutbuffer >= 0) { int inbytes; unsigned long nbytes; int fmt8 = 8; Atom type = XA_STRING; char *line; /* 'line' is freed in SelectionReceived */ line = XFetchBuffer(XtDisplay(w), &inbytes, cutbuffer); nbytes = (unsigned long) inbytes; if (nbytes > 0) { SelectionReceived(w, NULL, &selection, &type, (XtPointer) line, &nbytes, &fmt8); } else if (num_params > 1) { xtermGetSelection(w, ev_time, params + 1, num_params - 1, NULL); } #if OPT_PASTE64 else { FinishPaste64(xw); } #endif } else { if (targets == NULL || targets[0] == None) { targets = _SelectionTargets(w); } if (targets != NULL) { struct _SelectionList *list; target = targets[0]; if (targets[1] == None) { /* last target in list */ params++; num_params--; targets = _SelectionTargets(w); } else { targets = &(targets[1]); } if (num_params) { /* 'list' is freed in SelectionReceived */ list = TypeXtMalloc(struct _SelectionList); if (list != NULL) { list->params = params; list->count = num_params; list->targets = targets; list->time = ev_time; } } else { list = NULL; } XtGetSelectionValue(w, selection, target, SelectionReceived, (XtPointer) list, ev_time); } } } #if OPT_TRACE && OPT_WIDE_CHARS static void GettingSelection(Display *dpy, Atom type, Char *line, unsigned long len) { Char *cp; const char *name = TraceAtomName(dpy, type); TRACE(("Getting %s (type=%ld, length=%ld)\n", name, (long int) type, len)); for (cp = line; cp < line + len; cp++) { TRACE(("[%d:%lu]", (int) (cp + 1 - line), len)); if (isprint(*cp)) { TRACE(("%c\n", *cp)); } else { TRACE(("\\x%02x\n", *cp)); } } } #else #define GettingSelection(dpy,type,line,len) /* nothing */ #endif #define tty_vwrite(pty,lag,l) v_write(pty,lag,(size_t) l) #if OPT_PASTE64 /* Return base64 code character given 6-bit number */ static const char base64_code[] = "\ ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz\ 0123456789+/"; static void base64_flush(TScreen *screen) { Char x; TRACE(("base64_flush count %d, pad %d (%d)\n", screen->base64_count, screen->base64_pad, screen->base64_pad & 3)); switch (screen->base64_count) { case 0: break; case 2: x = CharOf(base64_code[screen->base64_accu << 4]); tty_vwrite(screen->respond, &x, 1); break; case 4: x = CharOf(base64_code[screen->base64_accu << 2]); tty_vwrite(screen->respond, &x, 1); break; } if (screen->base64_pad & 3) { tty_vwrite(screen->respond, (const Char *) "===", (unsigned) (3 - (screen->base64_pad & 3))); } screen->base64_count = 0; screen->base64_accu = 0; screen->base64_pad = 0; } #endif /* OPT_PASTE64 */ /* * Translate ISO-8859-1 or UTF-8 data to NRCS. */ static void ToNational(XtermWidget xw, Char *buffer, size_t *length) { TScreen *screen = TScreenOf(xw); DECNRCM_codes gsetL = screen->gsets[screen->curgl]; DECNRCM_codes gsetR = screen->gsets[screen->curgr]; #if OPT_WIDE_CHARS if ((screen->utf8_nrc_mode | screen->utf8_mode) != uFalse) { Char *p; PtyData *data = TypeXtMallocX(PtyData, *length); memset(data, 0, sizeof(*data)); data->next = data->buffer; data->last = data->buffer + *length; memcpy(data->buffer, buffer, *length); p = buffer; while (data->next < data->last) { unsigned chr, out, gl, gr; if (!decodeUtf8(screen, data)) { data->utf_size = 1; data->utf_data = data->next[0]; } data->next += data->utf_size; chr = data->utf_data; out = chr; if ((gl = xtermCharSetIn(xw, chr, gsetL)) != chr) { out = gl; } else if ((gr = xtermCharSetIn(xw, chr, gsetR)) != chr) { out = gr; } *p++ = (Char) ((out < 256) ? out : ' '); } *length = (size_t) (p - buffer); free(data); } else #endif { Char *p; for (p = buffer; (size_t) (p - buffer) < *length; ++p) { unsigned gl, gr; unsigned chr = *p; unsigned out = chr; if ((gl = xtermCharSetIn(xw, chr, gsetL)) != chr) { out = gl; } else if ((gr = xtermCharSetIn(xw, chr, gsetR)) != chr) { out = gr; } *p = (Char) out; } } } static void _qWriteSelectionData(XtermWidget xw, Char *lag, size_t length) { TScreen *screen = TScreenOf(xw); /* * If we are pasting into a window which is using NRCS, we want to map * the text from the normal encoding (ISO-8859-1 or UTF-8) into the coding * that an application would use to write characters with NRCS. * * TODO: handle conversion from UTF-8, and adjust length. This can be done * in the same buffer because the target is always 8-bit. */ if ((xw->flags & NATIONAL) && (length != 0)) { ToNational(xw, lag, &length); } #if OPT_PASTE64 if (screen->base64_paste) { /* Send data as base64 */ Char *p = lag; Char buf[64]; unsigned x = 0; TRACE(("convert to base64 %lu:%s\n", (unsigned long) length, visibleChars(p, length))); /* * Handle the case where the selection is from _this_ xterm, which * puts part of the reply in the buffer before the selection callback * happens. */ if (screen->base64_paste && screen->unparse_len) { unparse_end(xw); } while (length--) { switch (screen->base64_count) { case 0: buf[x++] = CharOf(base64_code[*p >> 2]); screen->base64_accu = (unsigned) (*p & 0x3); screen->base64_count = 2; ++p; break; case 2: buf[x++] = CharOf(base64_code[(screen->base64_accu << 4) + (*p >> 4)]); screen->base64_accu = (unsigned) (*p & 0xF); screen->base64_count = 4; ++p; break; case 4: buf[x++] = CharOf(base64_code[(screen->base64_accu << 2) + (*p >> 6)]); buf[x++] = CharOf(base64_code[*p & 0x3F]); screen->base64_accu = 0; screen->base64_count = 0; ++p; break; } if (x >= 63) { /* Write 63 or 64 characters */ screen->base64_pad += x; TRACE(("writing base64 interim %s\n", visibleChars(buf, x))); tty_vwrite(screen->respond, buf, x); x = 0; } } if (x != 0) { screen->base64_pad += x; TRACE(("writing base64 finish %s\n", visibleChars(buf, x))); tty_vwrite(screen->respond, buf, x); } } else #endif /* OPT_PASTE64 */ #if OPT_READLINE if (SCREEN_FLAG(screen, paste_quotes)) { Char quote[2]; quote[0] = (Char) get_tty_lnext(screen->respond, XTERM_LNEXT, "pty"); quote[1] = 0; TRACE(("writing quoted selection data %s\n", visibleChars(lag, length))); while (length--) { tty_vwrite(screen->respond, quote, 1); tty_vwrite(screen->respond, lag++, 1); } } else #endif { TRACE(("writing selection data %s\n", visibleChars(lag, length))); tty_vwrite(screen->respond, lag, length); } } static void _WriteSelectionData(XtermWidget xw, Char *line, size_t length) { #if OPT_PASTE64 || OPT_READLINE TScreen *screen = TScreenOf(xw); #endif #if OPT_PASTE64 if (screen->base64_paste) { _qWriteSelectionData(xw, line, length); base64_flush(screen); } else #endif { if (!SCREEN_FLAG(screen, paste_literal_nl)) { size_t n; for (n = 0; n < length; ++n) { if (line[n] == '\n') { line[n] = '\r'; } } } _qWriteSelectionData(xw, line, length); } } #if OPT_PASTE64 || OPT_READLINE static void _WriteKey(TScreen *screen, const Char *in) { Char line[16]; unsigned count = 0; size_t length = strlen((const char *) in); if (screen->control_eight_bits) { line[count++] = ANSI_CSI; } else { line[count++] = ANSI_ESC; line[count++] = '['; } while (length--) line[count++] = *in++; line[count++] = '~'; tty_vwrite(screen->respond, line, count); } #endif /* OPT_READLINE */ /* * Unless enabled by the user, strip control characters other than formatting. */ static size_t removeControls(XtermWidget xw, char *value) { TScreen *screen = TScreenOf(xw); size_t dst = 0; if (screen->allowPasteControls) { dst = strlen(value); } else { size_t src = 0; Boolean *disallowed = screen->disallow_paste_ops; TERMIO_STRUCT data; char current_chars[epLAST]; if (disallowed[epSTTY] && ttyGetAttr(screen->respond, &data) == 0) { int n; int disabled = xtermDisabledChar(); TRACE(("disallow(STTY):")); memcpy(current_chars, disallowed, sizeof(current_chars)); for (n = 0; n < NCCS; ++n) { PasteControls nc = (data.c_cc[n] < 32 ? data.c_cc[n] : (data.c_cc[n] == 127 ? epDEL : epLAST)); if (nc == epNUL || nc == epLAST) continue; if (CharOf(data.c_cc[n]) == CharOf(disabled)) continue; if ((n == VMIN || n == VTIME) && !(data.c_lflag & ICANON)) continue; switch (n) { /* POSIX */ case VEOF: case VEOL: case VERASE: case VINTR: case VKILL: case VQUIT: case VSTART: case VSTOP: case VSUSP: /* system-dependent */ #ifdef VDISCARD case VDISCARD: #endif #ifdef VDSUSP case VDSUSP: #endif #ifdef VEOL2 case VEOL2: #endif #ifdef VLNEXT case VLNEXT: #endif #ifdef VREPRINT case VREPRINT: #endif #ifdef VSTATUS case VSTATUS: #endif #ifdef VSWTC case VSWTC: /* System V SWTCH */ #endif #ifdef VWERASE case VWERASE: #endif break; default: continue; } if (nc != epLAST) { TRACE((" \\%03o", data.c_cc[n])); current_chars[nc] = 1; } } TRACE(("\n")); disallowed = current_chars; } while ((value[dst] = value[src]) != '\0') { int ch = CharOf(value[src++]); #define ReplacePaste(n) \ if (disallowed[n]) \ value[dst] = ' ' if (ch < 32) { ReplacePaste(epC0); ReplacePaste(ch); ++dst; } else if (ch == ANSI_DEL) { ReplacePaste(epDEL); ++dst; } #if OPT_WIDE_CHARS else if (screen->utf8_inparse || screen->utf8_nrc_mode) ++dst; #endif #if OPT_C1_PRINT || OPT_WIDE_CHARS else if (screen->c1_printable) ++dst; #endif else if (ch >= 128 && ch < 160) continue; else ++dst; } } return dst; } #if OPT_SELECTION_OPS static void beginInternalSelect(XtermWidget xw) { TScreen *screen = TScreenOf(xw); InternalSelect *mydata = &(screen->internal_select); (void) mydata; /* override flags so that SelectionReceived only updates a buffer */ #if OPT_PASTE64 mydata->base64_paste = screen->base64_paste; screen->base64_paste = 0; #endif #if OPT_PASTE64 || OPT_READLINE mydata->paste_brackets = screen->paste_brackets; SCREEN_FLAG_unset(screen, paste_brackets); #endif } static void finishInternalSelect(XtermWidget xw) { TScreen *screen = TScreenOf(xw); InternalSelect *mydata = &(screen->internal_select); (void) mydata; #if OPT_PASTE64 screen->base64_paste = mydata->base64_paste; #endif #if OPT_PASTE64 || OPT_READLINE screen->paste_brackets = mydata->paste_brackets; #endif } #else #define finishInternalSelect(xw) /* nothing */ #endif /* OPT_SELECTION_OPS */ /* SelectionReceived: stuff received selection text into pty */ /* ARGSUSED */ static void SelectionReceived(Widget w, XtPointer client_data, Atom *selection GCC_UNUSED, Atom *type, XtPointer value, unsigned long *length, int *format) { char **text_list = NULL; int text_list_count = 0; XTextProperty text_prop; TScreen *screen; Display *dpy; #if OPT_TRACE && OPT_WIDE_CHARS Char *line = (Char *) value; #endif XtermWidget xw; if ((xw = getXtermWidget(w)) == NULL) return; screen = TScreenOf(xw); dpy = XtDisplay(w); if (*type == 0 /*XT_CONVERT_FAIL */ || *length == 0 || value == NULL) { TRACE(("...no data to convert\n")); goto fail; } text_prop.value = (unsigned char *) value; text_prop.encoding = *type; text_prop.format = *format; text_prop.nitems = *length; TRACE(("SelectionReceived %s %s format %d, nitems %ld\n", TraceAtomName(screen->display, *selection), visibleSelectionTarget(dpy, text_prop.encoding), text_prop.format, text_prop.nitems)); #if OPT_WIDE_CHARS if (XSupportsLocale() && screen->wide_chars) { if (*type == XA_UTF8_STRING(dpy) || *type == XA_STRING || *type == XA_COMPOUND_TEXT(dpy)) { GettingSelection(dpy, *type, line, *length); if (Xutf8TextPropertyToTextList(dpy, &text_prop, &text_list, &text_list_count) < 0) { TRACE(("default Xutf8 Conversion failed\n")); text_list = NULL; } } } else #endif /* OPT_WIDE_CHARS */ { /* Convert the selection to locale's multibyte encoding. */ if (*type == XA_UTF8_STRING(dpy) || *type == XA_STRING || *type == XA_COMPOUND_TEXT(dpy)) { Status rc; GettingSelection(dpy, *type, line, *length); #if OPT_WIDE_CHARS if (*type == XA_UTF8_STRING(dpy) && !(screen->wide_chars || screen->c1_printable)) { rc = xtermUtf8ToTextList(xw, &text_prop, &text_list, &text_list_count); } else #endif if (*type == XA_STRING && (!XSupportsLocale() || screen->brokenSelections)) { rc = XTextPropertyToStringList(&text_prop, &text_list, &text_list_count); } else { rc = XmbTextPropertyToTextList(dpy, &text_prop, &text_list, &text_list_count); } if (rc < 0) { TRACE(("Conversion failed\n")); text_list = NULL; } } } if (text_list != NULL && text_list_count != 0) { int i; #if OPT_PASTE64 if (screen->base64_paste) { /* EMPTY */ ; } else #endif #if OPT_PASTE64 || OPT_READLINE if (SCREEN_FLAG(screen, paste_brackets) && !screen->selectToBuffer) { _WriteKey(screen, (const Char *) "200"); } #endif for (i = 0; i < text_list_count; i++) { size_t len = removeControls(xw, text_list[i]); if (screen->selectToBuffer) { InternalSelect *mydata = &(screen->internal_select); if (!mydata->done) { size_t have = (mydata->buffer ? strlen(mydata->buffer) : 0); size_t need = have + len + 1; char *buffer = realloc(mydata->buffer, need); if (buffer != NULL) { strcpy(buffer + have, text_list[i]); mydata->buffer = buffer; } TRACE(("FormatSelect %d.%d .. %d.%d %s\n", screen->startSel.row, screen->startSel.col, screen->endSel.row, screen->endSel.col, mydata->buffer)); mydata->format_select(w, mydata->format, mydata->buffer, &(screen->startSel), &(screen->endSel)); mydata->done = True; } } else { _WriteSelectionData(xw, (Char *) text_list[i], len); } } #if OPT_PASTE64 if (screen->base64_paste) { FinishPaste64(xw); } else #endif #if OPT_PASTE64 || OPT_READLINE if (SCREEN_FLAG(screen, paste_brackets) && !screen->selectToBuffer) { _WriteKey(screen, (const Char *) "201"); } #endif if (screen->selectToBuffer) { InternalSelect *mydata = &(screen->internal_select); finishInternalSelect(xw); if (mydata->done) { free(mydata->format); free(mydata->buffer); memset(mydata, 0, sizeof(*mydata)); } screen->selectToBuffer = False; } XFreeStringList(text_list); } else { TRACE(("...empty text-list\n")); goto fail; } XtFree((char *) client_data); XtFree((char *) value); return; fail: if (client_data != NULL) { struct _SelectionList *list = (struct _SelectionList *) client_data; TRACE(("SelectionReceived ->xtermGetSelection\n")); xtermGetSelection(w, list->time, list->params, list->count, list->targets); XtFree((char *) client_data); #if OPT_PASTE64 } else { FinishPaste64(xw); #endif } return; } void HandleInsertSelection(Widget w, XEvent *event, /* assumed to be XButtonEvent* */ String *params, /* selections in precedence order */ Cardinal *num_params) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TRACE_EVENT("HandleInsertSelection", event, params, num_params); if (!SendMousePosition(xw, event)) { #if OPT_READLINE int ldelta; TScreen *screen = TScreenOf(xw); if (IsBtnEvent(event) && !OverrideEvent(event) && (okSendMousePos(xw) == MOUSE_OFF) && SCREEN_FLAG(screen, paste_moves) && rowOnCurrentLine(screen, eventRow(screen, event), &ldelta)) ReadLineMovePoint(xw, eventColBetween(screen, event), ldelta); #endif /* OPT_READLINE */ xtermGetSelection(w, event->xbutton.time, params, *num_params, NULL); } } } static SelectUnit EvalSelectUnit(XtermWidget xw, Time buttonDownTime, SelectUnit defaultUnit, unsigned int button) { TScreen *screen = TScreenOf(xw); SelectUnit result; int delta; if (button != screen->lastButton) { delta = screen->multiClickTime + 1; } else if (screen->lastButtonUpTime == (Time) 0) { /* first time and once in a blue moon */ delta = screen->multiClickTime + 1; } else if (buttonDownTime > screen->lastButtonUpTime) { /* most of the time */ delta = (int) (buttonDownTime - screen->lastButtonUpTime); } else { /* time has rolled over since lastButtonUpTime */ delta = (int) ((((Time) ~ 0) - screen->lastButtonUpTime) + buttonDownTime); } #if OPT_BLOCK_SELECT if (screen->blockSelecting || screen->blockSelecting != screen->lastSelectWasBlock) { /* No word, line, paragraph selecting when block selecting or when our last click was a block select */ screen->numberOfClicks = 1; result = defaultUnit; } else #endif if (delta > screen->multiClickTime) { screen->numberOfClicks = 1; result = defaultUnit; } else { result = screen->selectMap[screen->numberOfClicks % screen->maxClicks]; screen->numberOfClicks += 1; } TRACE(("EvalSelectUnit(%d) = %d\n", screen->numberOfClicks, result)); return result; } static void do_select_start(XtermWidget xw, XEvent *event, /* must be XButtonEvent* */ CELL *cell) { TScreen *screen = TScreenOf(xw); if (SendMousePosition(xw, event)) return; screen->selectUnit = EvalSelectUnit(xw, event->xbutton.time, Select_CHAR, event->xbutton.button); screen->replyToEmacs = False; #if OPT_READLINE lastButtonDownTime = event->xbutton.time; #endif StartSelect(xw, cell); } /* ARGSUSED */ void HandleSelectStart(Widget w, XEvent *event, /* must be XButtonEvent* */ String *params GCC_UNUSED, Cardinal *num_params GCC_UNUSED) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TScreen *screen = TScreenOf(xw); CELL cell; TRACE_EVENT("HandleSelectStart", event, params, num_params); screen->firstValidRow = 0; screen->lastValidRow = screen->max_row; PointToCELL(screen, event->xbutton.y, event->xbutton.x, &cell); #if OPT_READLINE ExtendingSelection = 0; #endif #if OPT_BLOCK_SELECT screen->blockSelecting = (*num_params >= 1 && !strcmp(params[0], "block")) ? 1 : 0; #endif do_select_start(xw, event, &cell); } } /* ARGSUSED */ void HandleKeyboardSelectStart(Widget w, XEvent *event, /* must be XButtonEvent* */ String *params GCC_UNUSED, Cardinal *num_params GCC_UNUSED) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TScreen *screen = TScreenOf(xw); TRACE_EVENT("HandleKeyboardSelectStart", event, params, num_params); do_select_start(xw, event, &screen->cursorp); } } static void TrackDown(XtermWidget xw, XButtonEvent *event) { TScreen *screen = TScreenOf(xw); CELL cell; screen->selectUnit = EvalSelectUnit(xw, event->time, Select_CHAR, event->button); if (screen->numberOfClicks > 1) { PointToCELL(screen, event->y, event->x, &cell); screen->replyToEmacs = True; StartSelect(xw, &cell); } else { screen->waitingForTrackInfo = True; EditorButton(xw, event); } } #define boundsCheck(x) if (x < 0) \ x = 0; \ else if (x >= screen->max_row) \ x = screen->max_row void TrackMouse(XtermWidget xw, int func, const CELL *start, int firstrow, int lastrow) { TScreen *screen = TScreenOf(xw); if (screen->waitingForTrackInfo) { /* if Timed, ignore */ screen->waitingForTrackInfo = False; if (func != 0) { CELL first = *start; boundsCheck(first.row); boundsCheck(firstrow); boundsCheck(lastrow); screen->firstValidRow = firstrow; screen->lastValidRow = lastrow; screen->replyToEmacs = True; StartSelect(xw, &first); } } } static void StartSelect(XtermWidget xw, const CELL *cell) { TScreen *screen = TScreenOf(xw); TRACE(("StartSelect row=%d, col=%d\n", cell->row, cell->col)); if (screen->cursor_state) HideCursor(xw); if (screen->numberOfClicks == 1) { /* set start of selection */ screen->rawPos = *cell; } /* else use old values in rawPos */ screen->saveStartR = screen->startExt = screen->rawPos; screen->saveEndR = screen->endExt = screen->rawPos; if (Coordinate(screen, cell) < Coordinate(screen, &(screen->rawPos))) { screen->eventMode = LEFTEXTENSION; screen->startExt = *cell; } else { screen->eventMode = RIGHTEXTENSION; screen->endExt = *cell; } ComputeSelect(xw, &(screen->startExt), &(screen->endExt), False, True); } static void EndExtend(XtermWidget xw, XEvent *event, /* must be XButtonEvent */ String *params, /* selections */ Cardinal num_params, Bool use_cursor_loc) { CELL cell; TScreen *screen = TScreenOf(xw); TRACE_EVENT("EndExtend", event, params, &num_params); if (use_cursor_loc) { cell = screen->cursorp; } else { PointToCELL(screen, event->xbutton.y, event->xbutton.x, &cell); } ExtendExtend(xw, &cell); screen->lastButtonUpTime = event->xbutton.time; screen->lastButton = event->xbutton.button; #if OPT_BLOCK_SELECT screen->lastSelectWasBlock = screen->blockSelecting; #endif if (!isSameCELL(&(screen->startSel), &(screen->endSel))) { if (screen->replyToEmacs) { Char line[64]; unsigned count = 0; if (screen->control_eight_bits) { line[count++] = ANSI_CSI; } else { line[count++] = ANSI_ESC; line[count++] = '['; } if (isSameCELL(&(screen->rawPos), &(screen->startSel)) && isSameCELL(&cell, &(screen->endSel))) { /* Use short-form emacs select */ switch (screen->extend_coords) { case 0: case SET_EXT_MODE_MOUSE: line[count++] = 't'; break; case SET_SGR_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: line[count++] = '<'; break; } count = EmitMousePosition(screen, line, count, screen->endSel.col); count = EmitMousePositionSeparator(screen, line, count); count = EmitMousePosition(screen, line, count, screen->endSel.row); switch (screen->extend_coords) { case SET_SGR_EXT_MODE_MOUSE: case SET_URXVT_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: line[count++] = 't'; break; } } else { /* long-form, specify everything */ switch (screen->extend_coords) { case 0: case SET_EXT_MODE_MOUSE: line[count++] = 'T'; break; case SET_SGR_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: line[count++] = '<'; break; } count = EmitMousePosition(screen, line, count, screen->startSel.col); count = EmitMousePositionSeparator(screen, line, count); count = EmitMousePosition(screen, line, count, screen->startSel.row); count = EmitMousePositionSeparator(screen, line, count); count = EmitMousePosition(screen, line, count, screen->endSel.col); count = EmitMousePositionSeparator(screen, line, count); count = EmitMousePosition(screen, line, count, screen->endSel.row); count = EmitMousePositionSeparator(screen, line, count); count = EmitMousePosition(screen, line, count, cell.col); count = EmitMousePositionSeparator(screen, line, count); count = EmitMousePosition(screen, line, count, cell.row); switch (screen->extend_coords) { case SET_SGR_EXT_MODE_MOUSE: case SET_URXVT_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: line[count++] = 'T'; break; } } v_write(screen->respond, line, (size_t) count); UnHiliteText(xw); } } SelectSet(xw, event, params, num_params); screen->eventMode = NORMAL; } void HandleSelectSet(Widget w, XEvent *event, String *params, Cardinal *num_params) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TRACE_EVENT("HandleSelectSet", event, params, num_params); SelectSet(xw, event, params, *num_params); } } /* ARGSUSED */ static void SelectSet(XtermWidget xw, XEvent *event GCC_UNUSED, String *params, Cardinal num_params) { TScreen *screen = TScreenOf(xw); TRACE(("SelectSet\n")); /* Only do select stuff if non-null select */ if (!isSameCELL(&(screen->startSel), &(screen->endSel))) { Cardinal n; for (n = 0; n < num_params; ++n) { SaltTextAway(xw, TargetToSelection(screen, params[n]), &(screen->startSel), &(screen->endSel)); } _OwnSelection(xw, params, num_params); } else { ScrnDisownSelection(xw); } } #define Abs(x) ((x) < 0 ? -(x) : (x)) /* ARGSUSED */ static void do_start_extend(XtermWidget xw, XEvent *event, /* must be XButtonEvent* */ String *params GCC_UNUSED, Cardinal *num_params GCC_UNUSED, Bool use_cursor_loc) { TScreen *screen = TScreenOf(xw); int coord; CELL cell; if (SendMousePosition(xw, event)) return; screen->firstValidRow = 0; screen->lastValidRow = screen->max_row; #if OPT_READLINE if (OverrideEvent(event) || event->xbutton.button != Button3 || !(SCREEN_FLAG(screen, dclick3_deletes))) #endif screen->selectUnit = EvalSelectUnit(xw, event->xbutton.time, screen->selectUnit, event->xbutton.button); screen->replyToEmacs = False; #if OPT_READLINE CheckSecondPress3(xw, screen, event); #endif if (screen->numberOfClicks == 1 || (SCREEN_FLAG(screen, dclick3_deletes) && !OverrideEvent(event))) { /* Save existing selection so we can reestablish it if the guy extends past the other end of the selection */ screen->saveStartR = screen->startExt = screen->startRaw; screen->saveEndR = screen->endExt = screen->endRaw; } else { /* He just needed the selection mode changed, use old values. */ screen->startExt = screen->startRaw = screen->saveStartR; screen->endExt = screen->endRaw = screen->saveEndR; } if (use_cursor_loc) { cell = screen->cursorp; } else { PointToCELL(screen, event->xbutton.y, event->xbutton.x, &cell); } coord = Coordinate(screen, &cell); if (Abs(coord - Coordinate(screen, &(screen->startSel))) < Abs(coord - Coordinate(screen, &(screen->endSel))) || coord < Coordinate(screen, &(screen->startSel))) { /* point is close to left side of selection */ screen->eventMode = LEFTEXTENSION; screen->startExt = cell; } else { /* point is close to left side of selection */ screen->eventMode = RIGHTEXTENSION; screen->endExt = cell; } ComputeSelect(xw, &(screen->startExt), &(screen->endExt), True, True); #if OPT_READLINE if (!isSameCELL(&(screen->startSel), &(screen->endSel))) ExtendingSelection = 1; #endif } static void ExtendExtend(XtermWidget xw, const CELL *cell) { TScreen *screen = TScreenOf(xw); int coord = Coordinate(screen, cell); TRACE(("ExtendExtend row=%d, col=%d\n", cell->row, cell->col)); if (screen->eventMode == LEFTEXTENSION && ((coord + (screen->selectUnit != Select_CHAR)) > Coordinate(screen, &(screen->endSel)))) { /* Whoops, he's changed his mind. Do RIGHTEXTENSION */ screen->eventMode = RIGHTEXTENSION; screen->startExt = screen->saveStartR; } else if (screen->eventMode == RIGHTEXTENSION && coord < Coordinate(screen, &(screen->startSel))) { /* Whoops, he's changed his mind. Do LEFTEXTENSION */ screen->eventMode = LEFTEXTENSION; screen->endExt = screen->saveEndR; } if (screen->eventMode == LEFTEXTENSION) { screen->startExt = *cell; } else { screen->endExt = *cell; } ComputeSelect(xw, &(screen->startExt), &(screen->endExt), False, True); #if OPT_READLINE if (!isSameCELL(&(screen->startSel), &(screen->endSel))) ExtendingSelection = 1; #endif } void HandleStartExtend(Widget w, XEvent *event, /* must be XButtonEvent* */ String *params, /* unused */ Cardinal *num_params) /* unused */ { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TRACE_EVENT("HandleStartExtend", event, params, num_params); do_start_extend(xw, event, params, num_params, False); } } void HandleKeyboardStartExtend(Widget w, XEvent *event, /* must be XButtonEvent* */ String *params, /* unused */ Cardinal *num_params) /* unused */ { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TRACE_EVENT("HandleKeyboardStartExtend", event, params, num_params); do_start_extend(xw, event, params, num_params, True); } } void ScrollSelection(TScreen *screen, int amount, Bool always) { int minrow = INX2ROW(screen, -screen->savedlines); int maxrow = INX2ROW(screen, screen->max_row); int maxcol = screen->max_col; #define scroll_update_one(cell) \ (cell)->row += amount; \ if ((cell)->row < minrow) { \ (cell)->row = minrow; \ (cell)->col = 0; \ } \ if ((cell)->row > maxrow) { \ (cell)->row = maxrow; \ (cell)->col = maxcol; \ } scroll_update_one(&(screen->startRaw)); scroll_update_one(&(screen->endRaw)); scroll_update_one(&(screen->startSel)); scroll_update_one(&(screen->endSel)); scroll_update_one(&(screen->rawPos)); /* * If we are told to scroll the selection but it lies outside the scrolling * margins, then that could cause the selection to move (bad). It is not * simple to fix, because this function is called both for the scrollbar * actions as well as application scrolling. The 'always' flag is set in * the former case. The rest of the logic handles the latter. */ if (ScrnHaveSelection(screen)) { int adjust; adjust = ROW2INX(screen, screen->startH.row); if (always || !ScrnHaveRowMargins(screen) || ScrnIsRowInMargins(screen, adjust)) { scroll_update_one(&screen->startH); } adjust = ROW2INX(screen, screen->endH.row); if (always || !ScrnHaveRowMargins(screen) || ScrnIsRowInMargins(screen, adjust)) { scroll_update_one(&screen->endH); } } screen->startHCoord = Coordinate(screen, &screen->startH); screen->endHCoord = Coordinate(screen, &screen->endH); } /*ARGSUSED*/ void ResizeSelection(TScreen *screen, int rows, int cols) { rows--; /* decr to get 0-max */ cols--; if (screen->startRaw.row > rows) screen->startRaw.row = rows; if (screen->startSel.row > rows) screen->startSel.row = rows; if (screen->endRaw.row > rows) screen->endRaw.row = rows; if (screen->endSel.row > rows) screen->endSel.row = rows; if (screen->rawPos.row > rows) screen->rawPos.row = rows; if (screen->startRaw.col > cols) screen->startRaw.col = cols; if (screen->startSel.col > cols) screen->startSel.col = cols; if (screen->endRaw.col > cols) screen->endRaw.col = cols; if (screen->endSel.col > cols) screen->endSel.col = cols; if (screen->rawPos.col > cols) screen->rawPos.col = cols; } #if OPT_WIDE_CHARS #define isWideCell(row, col) isWideFrg((int)XTERM_CELL(row, col)) #endif static void PointToCELL(TScreen *screen, int y, int x, CELL *cell) /* Convert pixel coordinates to character coordinates. Rows are clipped between firstValidRow and lastValidRow. Columns are clipped between to be 0 or greater, but are not clipped to some maximum value. */ { cell->row = (y - screen->border) / FontHeight(screen); if (cell->row < screen->firstValidRow) cell->row = screen->firstValidRow; else if (cell->row > screen->lastValidRow) cell->row = screen->lastValidRow; cell->col = (x - OriginX(screen)) / FontWidth(screen); if (cell->col < 0) cell->col = 0; else if (cell->col > MaxCols(screen)) { cell->col = MaxCols(screen); } #if OPT_WIDE_CHARS /* * If we got a click on the right half of a doublewidth character, * pretend it happened on the left half. */ if (cell->col > 0 && isWideCell(cell->row, cell->col - 1) && (XTERM_CELL(cell->row, cell->col) == HIDDEN_CHAR)) { cell->col -= 1; } #endif } /* * Find the last column at which text was drawn on the given row. */ static int LastTextCol(TScreen *screen, CLineData *ld, int row) { int i = -1; if (ld != NULL) { if (okScrnRow(screen, row)) { const IAttr *ch; for (i = screen->max_col, ch = ld->attribs + i; i >= 0 && !(*ch & CHARDRAWN); ch--, i--) { ; } #if OPT_DEC_CHRSET if (CSET_DOUBLE(GetLineDblCS(ld))) { i *= 2; } #endif } } return (i); } #if !OPT_WIDE_CHARS /* ** double click table for cut and paste in 8 bits ** ** This table is divided in four parts : ** ** - control characters [0,0x1f] U [0x80,0x9f] ** - separators [0x20,0x3f] U [0xa0,0xb9] ** - binding characters [0x40,0x7f] U [0xc0,0xff] ** - exceptions */ /* *INDENT-OFF* */ static int charClass[256] = { /* NUL SOH STX ETX EOT ENQ ACK BEL */ 32, 1, 1, 1, 1, 1, 1, 1, /* BS HT NL VT FF CR SO SI */ 1, 32, 1, 1, 1, 1, 1, 1, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ 1, 1, 1, 1, 1, 1, 1, 1, /* CAN EM SUB ESC FS GS RS US */ 1, 1, 1, 1, 1, 1, 1, 1, /* SP ! " # $ % & ' */ 32, 33, 34, 35, 36, 37, 38, 39, /* ( ) * + , - . / */ 40, 41, 42, 43, 44, 45, 46, 47, /* 0 1 2 3 4 5 6 7 */ 48, 48, 48, 48, 48, 48, 48, 48, /* 8 9 : ; < = > ? */ 48, 48, 58, 59, 60, 61, 62, 63, /* @ A B C D E F G */ 64, 48, 48, 48, 48, 48, 48, 48, /* H I J K L M N O */ 48, 48, 48, 48, 48, 48, 48, 48, /* P Q R S T U V W */ 48, 48, 48, 48, 48, 48, 48, 48, /* X Y Z [ \ ] ^ _ */ 48, 48, 48, 91, 92, 93, 94, 48, /* ` a b c d e f g */ 96, 48, 48, 48, 48, 48, 48, 48, /* h i j k l m n o */ 48, 48, 48, 48, 48, 48, 48, 48, /* p q r s t u v w */ 48, 48, 48, 48, 48, 48, 48, 48, /* x y z { | } ~ DEL */ 48, 48, 48, 123, 124, 125, 126, 1, /* x80 x81 x82 x83 IND NEL SSA ESA */ 1, 1, 1, 1, 1, 1, 1, 1, /* HTS HTJ VTS PLD PLU RI SS2 SS3 */ 1, 1, 1, 1, 1, 1, 1, 1, /* DCS PU1 PU2 STS CCH MW SPA EPA */ 1, 1, 1, 1, 1, 1, 1, 1, /* x98 x99 x9A CSI ST OSC PM APC */ 1, 1, 1, 1, 1, 1, 1, 1, /* - i c/ L ox Y- | So */ 160, 161, 162, 163, 164, 165, 166, 167, /* .. c0 ip << _ R0 - */ 168, 169, 170, 171, 172, 173, 174, 175, /* o +- 2 3 ' u q| . */ 176, 177, 178, 179, 180, 181, 182, 183, /* , 1 2 >> 1/4 1/2 3/4 ? */ 184, 185, 186, 187, 188, 189, 190, 191, /* A` A' A^ A~ A: Ao AE C, */ 48, 48, 48, 48, 48, 48, 48, 48, /* E` E' E^ E: I` I' I^ I: */ 48, 48, 48, 48, 48, 48, 48, 48, /* D- N~ O` O' O^ O~ O: X */ 48, 48, 48, 48, 48, 48, 48, 215, /* O/ U` U' U^ U: Y' P B */ 48, 48, 48, 48, 48, 48, 48, 48, /* a` a' a^ a~ a: ao ae c, */ 48, 48, 48, 48, 48, 48, 48, 48, /* e` e' e^ e: i` i' i^ i: */ 48, 48, 48, 48, 48, 48, 48, 48, /* d n~ o` o' o^ o~ o: -: */ 48, 48, 48, 48, 48, 48, 48, 247, /* o/ u` u' u^ u: y' P y: */ 48, 48, 48, 48, 48, 48, 48, 48}; /* *INDENT-ON* */ int SetCharacterClassRange(int low, /* in range of [0..255] */ int high, int value) /* arbitrary */ { if (low < 0 || high > 255 || high < low) return (-1); for (; low <= high; low++) charClass[low] = value; return (0); } #endif static int class_of(LineData *ld, const CELL *cell) { CELL temp = *cell; int result = 0; #if OPT_DEC_CHRSET if (CSET_DOUBLE(GetLineDblCS(ld))) { temp.col /= 2; } #endif if (temp.col < (int) ld->lineSize) result = CharacterClass((int) (ld->charData[temp.col])); return result; } #if OPT_WIDE_CHARS #define CClassSelects(name, cclass) \ (CClassOf(name) == cclass \ || XTERM_CELL(screen->name.row, screen->name.col) == HIDDEN_CHAR) #else #define CClassSelects(name, cclass) \ (class_of(ld.name, &((screen->name))) == cclass) #endif #define CClassOf(name) class_of(ld.name, &((screen->name))) #if OPT_REPORT_CCLASS static int show_cclass_range(int lo, int hi) { int cclass = CharacterClass(lo); int ident = (cclass == lo); int more = 0; if (ident) { int ch; for (ch = lo + 1; ch <= hi; ch++) { if (CharacterClass(ch) != ch) { ident = 0; break; } } if (ident && (hi < 255)) { ch = hi + 1; if (CharacterClass(ch) == ch) { if (ch >= 255 || CharacterClass(ch + 1) != ch) { more = 1; } } } } if (!more) { if (lo == hi) { printf("\t%d", lo); } else { printf("\t%d-%d", lo, hi); } if (!ident) printf(":%d", cclass); if (hi < 255) printf(", \\"); printf("\n"); } return !more; } void report_char_class(XtermWidget xw) { /* simple table, to match documentation */ static const char charnames[] = "NUL\0" "SOH\0" "STX\0" "ETX\0" "EOT\0" "ENQ\0" "ACK\0" "BEL\0" " BS\0" " HT\0" " NL\0" " VT\0" " NP\0" " CR\0" " SO\0" " SI\0" "DLE\0" "DC1\0" "DC2\0" "DC3\0" "DC4\0" "NAK\0" "SYN\0" "ETB\0" "CAN\0" " EM\0" "SUB\0" "ESC\0" " FS\0" " GS\0" " RS\0" " US\0" " SP\0" " !\0" " \"\0" " #\0" " $\0" " %\0" " &\0" " '\0" " (\0" " )\0" " *\0" " +\0" " ,\0" " -\0" " .\0" " /\0" " 0\0" " 1\0" " 2\0" " 3\0" " 4\0" " 5\0" " 6\0" " 7\0" " 8\0" " 9\0" " :\0" " ;\0" " <\0" " =\0" " >\0" " ?\0" " @\0" " A\0" " B\0" " C\0" " D\0" " E\0" " F\0" " G\0" " H\0" " I\0" " J\0" " K\0" " L\0" " M\0" " N\0" " O\0" " P\0" " Q\0" " R\0" " S\0" " T\0" " U\0" " V\0" " W\0" " X\0" " Y\0" " Z\0" " [\0" " \\\0" " ]\0" " ^\0" " _\0" " `\0" " a\0" " b\0" " c\0" " d\0" " e\0" " f\0" " g\0" " h\0" " i\0" " j\0" " k\0" " l\0" " m\0" " n\0" " o\0" " p\0" " q\0" " r\0" " s\0" " t\0" " u\0" " v\0" " w\0" " x\0" " y\0" " z\0" " {\0" " |\0" " }\0" " ~\0" "DEL\0" "x80\0" "x81\0" "x82\0" "x83\0" "IND\0" "NEL\0" "SSA\0" "ESA\0" "HTS\0" "HTJ\0" "VTS\0" "PLD\0" "PLU\0" " RI\0" "SS2\0" "SS3\0" "DCS\0" "PU1\0" "PU2\0" "STS\0" "CCH\0" " MW\0" "SPA\0" "EPA\0" "x98\0" "x99\0" "x9A\0" "CSI\0" " ST\0" "OSC\0" " PM\0" "APC\0" " -\0" " i\0" " c/\0" " L\0" " ox\0" " Y-\0" " |\0" " So\0" " ..\0" " c0\0" " ip\0" " <<\0" " _\0" " \0" " R0\0" " -\0" " o\0" " +-\0" " 2\0" " 3\0" " '\0" " u\0" " q|\0" " .\0" " ,\0" " 1\0" " 2\0" " >>\0" "1/4\0" "1/2\0" "3/4\0" " ?\0" " A`\0" " A'\0" " A^\0" " A~\0" " A:\0" " Ao\0" " AE\0" " C,\0" " E`\0" " E'\0" " E^\0" " E:\0" " I`\0" " I'\0" " I^\0" " I:\0" " D-\0" " N~\0" " O`\0" " O'\0" " O^\0" " O~\0" " O:\0" " X\0" " O/\0" " U`\0" " U'\0" " U^\0" " U:\0" " Y'\0" " P\0" " B\0" " a`\0" " a'\0" " a^\0" " a~\0" " a:\0" " ao\0" " ae\0" " c,\0" " e`\0" " e'\0" " e^\0" " e:\0" " i`\0" " i'\0" " i^\0" " i:\0" " d\0" " n~\0" " o`\0" " o'\0" " o^\0" " o~\0" " o:\0" " -:\0" " o/\0" " u`\0" " u'\0" " u^\0" " u:\0" " y'\0" " P\0" " y:\0"; int ch, dh; int class_p; (void) xw; printf("static int charClass[256] = {\n"); for (ch = 0; ch < 256; ++ch) { const char *s = charnames + (ch * 4); if ((ch & 7) == 0) printf("/*"); printf(" %s ", s); if (((ch + 1) & 7) == 0) { printf("*/\n "); for (dh = ch - 7; dh <= ch; ++dh) { printf(" %3d%s", CharacterClass(dh), dh == 255 ? "};" : ","); } printf("\n"); } } /* print the table as if it were the charClass resource */ printf("\n"); printf("The table is equivalent to this \"charClass\" resource:\n"); class_p = CharacterClass(dh = 0); for (ch = 0; ch < 256; ++ch) { int class_c = CharacterClass(ch); if (class_c != class_p) { if (show_cclass_range(dh, ch - 1)) { dh = ch; class_p = class_c; } } } if (dh < 255) { show_cclass_range(dh, 255); } if_OPT_WIDE_CHARS(TScreenOf(xw), { /* if this is a wide-character configuration, print all intervals */ report_wide_char_class(); }); } #endif /* * If the given column is past the end of text on the given row, bump to the * beginning of the next line. */ static Boolean okPosition(TScreen *screen, LineData **ld, CELL *cell) { Boolean result = True; assert(ld != NULL); assert(*ld != NULL); if (*ld == NULL) { result = False; TRACE(("okPosition LineData is null!\n")); } else if (cell->row > screen->max_row) { result = False; TRACE(("okPosition cell row %d > screen max %d\n", cell->row, screen->max_row)); } else if (cell->col > (LastTextCol(screen, *ld, cell->row) + 1)) { TRACE(("okPosition cell col %d > screen max %d\n", cell->col, (LastTextCol(screen, *ld, cell->row) + 1))); if (cell->row < screen->max_row) { TRACE(("okPosition cell row %d < screen max %d\n", cell->row, screen->max_row)); cell->col = 0; *ld = GET_LINEDATA(screen, ++cell->row); result = False; } } return result; } static void trimLastLine(TScreen *screen, LineData **ld, CELL *last) { if (screen->cutNewline && last->row < screen->max_row) { last->col = 0; *ld = GET_LINEDATA(screen, ++last->row); } else { last->col = LastTextCol(screen, *ld, last->row) + 1; } } #if OPT_SELECT_REGEX /* * Returns the first row of a wrapped line. */ static int firstRowOfLine(TScreen *screen, int row, Bool visible) { LineData *ld = NULL; int limit = visible ? 0 : -screen->savedlines; while (row > limit && (ld = GET_LINEDATA(screen, row - 1)) != NULL && LineTstWrapped(ld)) { --row; } return row; } /* * Returns the last row of a wrapped line. */ static int lastRowOfLine(TScreen *screen, int row) { LineData *ld; while (row < screen->max_row && (ld = GET_LINEDATA(screen, row)) != NULL && LineTstWrapped(ld)) { ++row; } return row; } /* * Returns the number of cells on the range of rows. */ static unsigned lengthOfLines(TScreen *screen, int firstRow, int lastRow) { unsigned length = 0; int n; for (n = firstRow; n <= lastRow; ++n) { LineData *ld = GET_LINEDATA(screen, n); int value = LastTextCol(screen, ld, n); if (value >= 0) length += (unsigned) (value + 1); } return length; } /* * Make a copy of the wrapped-line which corresponds to the given row as a * string of bytes. Construct an index for the columns from the beginning of * the line. */ static char * make_indexed_text(TScreen *screen, int row, unsigned length, int *indexed) { Char *result = NULL; size_t need = (length + 1); /* * Get a quick upper bound to the number of bytes needed, if the whole * string were UTF-8. */ if_OPT_WIDE_CHARS(screen, { need *= ((screen->lineExtra + 1) * 6); }); if ((result = TypeCallocN(Char, need + 1)) != NULL) { LineData *ld = GET_LINEDATA(screen, row); unsigned used = 0; Char *last = result; do { int col = 0; int limit = LastTextCol(screen, ld, row); while (col <= limit) { Char *next = last; unsigned data = ld->charData[col]; assert(col < (int) ld->lineSize); /* some internal points may not be drawn */ if (data == 0) data = ' '; if_WIDE_OR_NARROW(screen, { next = convertToUTF8(last, data); } , { *next++ = CharOf(data); }); if_OPT_WIDE_CHARS(screen, { size_t off; for_each_combData(off, ld) { data = ld->combData[off][col]; if (data == 0) break; next = convertToUTF8(next, data); } }); indexed[used] = (int) (last - result); *next = 0; /* TRACE(("index[%d.%d] %d:%s\n", row, used, indexed[used], last)); */ last = next; ++used; ++col; indexed[used] = (int) (next - result); } } while (used < length && LineTstWrapped(ld) && (ld = GET_LINEDATA(screen, ++row)) != NULL && row < screen->max_row); } /* TRACE(("result:%s\n", result)); */ return (char *) result; } /* * Find the column given an offset into the character string by using the * index constructed in make_indexed_text(). */ static int indexToCol(const int *indexed, int len, int off) { int col = 0; while (indexed[col] < len) { if (indexed[col] >= off) break; ++col; } return col; } /* * Given a row number, and a column offset from that (which may be wrapped), * set the cell to the actual row/column values. */ static void columnToCell(TScreen *screen, int row, int col, CELL *cell) { while (row < screen->max_row) { CLineData *ld = GET_LINEDATA(screen, row); int last = LastTextCol(screen, ld, row); /* TRACE(("last(%d) = %d, have %d\n", row, last, col)); */ if (col <= last) { break; } /* * Stop if the current row does not wrap (does not continue the current * line). */ if (!LineTstWrapped(ld)) { col = last + 1; break; } col -= (last + 1); ++row; } if (col < 0) col = 0; cell->row = row; cell->col = col; } /* * Given a cell, find the corresponding column offset. */ static int cellToColumn(TScreen *screen, CELL *cell) { CLineData *ld = NULL; int col = cell->col; int row = firstRowOfLine(screen, cell->row, False); while (row < cell->row) { int adj; if ((ld = GET_LINEDATA(screen, row)) == NULL) break; if ((adj = LastTextCol(screen, ld, row++)) < 0) col += adj; } #if OPT_DEC_CHRSET if (ld == NULL) ld = GET_LINEDATA(screen, row); if (CSET_DOUBLE(GetLineDblCS(ld))) col /= 2; #endif return col; } static void do_select_regex(TScreen *screen, CELL *startc, CELL *endc) { LineData *ld = GET_LINEDATA(screen, startc->row); int inx = ((screen->numberOfClicks - 1) % screen->maxClicks); char *expr = screen->selectExpr[inx]; regex_t preg; regmatch_t match; TRACE(("Select_REGEX[%d]:%s\n", inx, NonNull(expr))); if (okPosition(screen, &ld, startc) && expr != NULL) { if (regcomp(&preg, expr, REG_EXTENDED) == 0) { int firstRow = firstRowOfLine(screen, startc->row, True); int lastRow = lastRowOfLine(screen, firstRow); unsigned size = lengthOfLines(screen, firstRow, lastRow); int actual = cellToColumn(screen, startc); int *indexed; TRACE(("regcomp ok rows %d..%d bytes %d\n", firstRow, lastRow, size)); if ((indexed = TypeCallocN(int, size + 1)) != NULL) { char *search; if ((search = make_indexed_text(screen, firstRow, size, indexed)) != NULL) { int len = (int) strlen(search); int col; int offset; int best_col = -1; int best_len = -1; startc->row = 0; startc->col = 0; endc->row = 0; endc->col = 0; for (col = 0; (offset = indexed[col]) < len; ++col) { if (regexec(&preg, search + offset, (size_t) 1, &match, col ? REG_NOTBOL : 0) == 0) { int start_inx = (int) (match.rm_so + offset); int finis_inx = (int) (match.rm_eo + offset); int start_col = indexToCol(indexed, len, start_inx); int finis_col = indexToCol(indexed, len, finis_inx); if (start_col <= actual && actual <= finis_col) { int test = finis_col - start_col; if (best_len < test) { best_len = test; best_col = start_col; TRACE(("match column %d len %d\n", best_col, best_len)); } } } } if (best_col >= 0) { int best_nxt = best_col + best_len; columnToCell(screen, firstRow, best_col, startc); columnToCell(screen, firstRow, best_nxt, endc); TRACE(("search::%s\n", search)); TRACE(("indexed:%d..%d -> %d..%d\n", best_col, best_nxt, indexed[best_col], indexed[best_nxt])); TRACE(("matched:%d:%s\n", indexed[best_nxt] - indexed[best_col], visibleChars((Char *) (search + indexed[best_col]), (unsigned) (indexed[best_nxt] - indexed[best_col])))); } free(search); } free(indexed); #if OPT_DEC_CHRSET if ((ld = GET_LINEDATA(screen, startc->row)) != NULL) { if (CSET_DOUBLE(GetLineDblCS(ld))) startc->col *= 2; } if ((ld = GET_LINEDATA(screen, endc->row)) != NULL) { if (CSET_DOUBLE(GetLineDblCS(ld))) endc->col *= 2; } #endif } regfree(&preg); } } } #endif /* OPT_SELECT_REGEX */ #define InitRow(name) \ ld.name = GET_LINEDATA(screen, screen->name.row) #define NextRow(name) \ ld.name = GET_LINEDATA(screen, ++screen->name.row) #define PrevRow(name) \ ld.name = GET_LINEDATA(screen, --screen->name.row) #define MoreRows(name) \ (screen->name.row < screen->max_row) #define isPrevWrapped(name) \ (screen->name.row > 0 \ && (ltmp = GET_LINEDATA(screen, screen->name.row - 1)) != NULL \ && LineTstWrapped(ltmp)) /* * sets startSel endSel * ensuring that they have legal values */ static void ComputeSelect(XtermWidget xw, const CELL *startc, const CELL *endc, Bool extend, Bool normal) { TScreen *screen = TScreenOf(xw); int cclass; CELL first = *startc; CELL last = *endc; Boolean ignored = False; struct { LineData *startSel; LineData *endSel; } ld; LineData *ltmp; TRACE(("ComputeSelect(startRow=%d, startCol=%d, endRow=%d, endCol=%d, %sextend)\n", first.row, first.col, last.row, last.col, extend ? "" : "no")); #if OPT_WIDE_CHARS if (first.col > 1 && isWideCell(first.row, first.col - 1) && XTERM_CELL(first.row, first.col - 0) == HIDDEN_CHAR) { TRACE(("Adjusting start. Changing downwards from %i.\n", first.col)); first.col -= 1; if (last.col == (first.col + 1)) last.col--; } if (last.col > 1 && isWideCell(last.row, last.col - 1) && XTERM_CELL(last.row, last.col) == HIDDEN_CHAR) { last.col += 1; } #endif if (Coordinate(screen, &first) <= Coordinate(screen, &last)) { screen->startSel = screen->startRaw = first; screen->endSel = screen->endRaw = last; } else { /* Swap them */ screen->startSel = screen->startRaw = last; screen->endSel = screen->endRaw = first; } InitRow(startSel); InitRow(endSel); switch (screen->selectUnit) { case Select_CHAR: #if OPT_BLOCK_SELECT /* Allow block selecting past EOL */ if (screen->blockSelecting) break; #endif (void) okPosition(screen, &(ld.startSel), &(screen->startSel)); (void) okPosition(screen, &(ld.endSel), &(screen->endSel)); break; case Select_WORD: TRACE(("Select_WORD\n")); if (okPosition(screen, &(ld.startSel), &(screen->startSel))) { CELL mark; cclass = CClassOf(startSel); TRACE(("...starting with class %d\n", cclass)); do { mark = screen->startSel; --screen->startSel.col; if (screen->startSel.col < 0 && isPrevWrapped(startSel)) { PrevRow(startSel); screen->startSel.col = LastTextCol(screen, ld.startSel, screen->startSel.row); } } while (screen->startSel.col >= 0 && CClassSelects(startSel, cclass)); if (normal) ++screen->startSel.col; else screen->startSel = mark; } #if OPT_WIDE_CHARS #define SkipHiddenCell(mark) \ if (mark.col && XTERM_CELL(mark.row, mark.col) == HIDDEN_CHAR) \ mark.col++ #else #define SkipHiddenCell(mark) /* nothing */ #endif SkipHiddenCell(screen->startSel); if (!normal) { screen->endSel = screen->startSel; ld.endSel = ld.startSel; } if (okPosition(screen, &(ld.endSel), &(screen->endSel))) { int length = LastTextCol(screen, ld.endSel, screen->endSel.row); cclass = CClassOf(endSel); TRACE(("...ending with class %d\n", cclass)); do { ++screen->endSel.col; if (screen->endSel.col > length && LineTstWrapped(ld.endSel)) { if (!MoreRows(endSel)) break; screen->endSel.col = 0; NextRow(endSel); length = LastTextCol(screen, ld.endSel, screen->endSel.row); } } while (screen->endSel.col <= length && CClassSelects(endSel, cclass)); if (normal && screen->endSel.col > length + 1 && MoreRows(endSel)) { screen->endSel.col = 0; NextRow(endSel); } } SkipHiddenCell(screen->endSel); screen->saveStartW = screen->startSel; break; case Select_LINE: TRACE(("Select_LINE\n")); while (LineTstWrapped(ld.endSel) && MoreRows(endSel)) { NextRow(endSel); } if (screen->cutToBeginningOfLine || screen->startSel.row < screen->saveStartW.row) { screen->startSel.col = 0; while (isPrevWrapped(startSel)) { PrevRow(startSel); } } else if (!extend) { if ((first.row < screen->saveStartW.row) || (isSameRow(&first, &(screen->saveStartW)) && first.col < screen->saveStartW.col)) { screen->startSel.col = 0; while (isPrevWrapped(startSel)) { PrevRow(startSel); } } else { screen->startSel = screen->saveStartW; } } trimLastLine(screen, &(ld.endSel), &(screen->endSel)); break; case Select_GROUP: /* paragraph */ TRACE(("Select_GROUP\n")); if (okPosition(screen, &(ld.startSel), &(screen->startSel))) { /* scan backward for beginning of group */ while (screen->startSel.row > 0 && (LastTextCol(screen, ld.startSel, screen->startSel.row - 1) > 0 || isPrevWrapped(startSel))) { PrevRow(startSel); } screen->startSel.col = 0; /* scan forward for end of group */ while (MoreRows(endSel) && (LastTextCol(screen, ld.endSel, screen->endSel.row + 1) > 0 || LineTstWrapped(ld.endSel))) { NextRow(endSel); } trimLastLine(screen, &(ld.endSel), &(screen->endSel)); } break; case Select_PAGE: /* everything one can see */ TRACE(("Select_PAGE\n")); screen->startSel.row = 0; screen->startSel.col = 0; screen->endSel.row = MaxRows(screen); screen->endSel.col = 0; break; case Select_ALL: /* counts scrollback if in normal screen */ TRACE(("Select_ALL\n")); screen->startSel.row = -screen->savedlines; screen->startSel.col = 0; screen->endSel.row = MaxRows(screen); screen->endSel.col = 0; break; #if OPT_SELECT_REGEX case Select_REGEX: do_select_regex(screen, &(screen->startSel), &(screen->endSel)); break; #endif case NSELECTUNITS: /* always ignore */ ignored = True; break; } if (!ignored) { /* check boundaries */ ScrollSelection(screen, 0, False); TrackText(xw, &(screen->startSel), &(screen->endSel)); } return; } /* Guaranteed (first.row, first.col) <= (last.row, last.col) */ static void TrackText(XtermWidget xw, const CELL *firstp, const CELL *lastp) { TScreen *screen = TScreenOf(xw); int from, to; CELL old_start, old_end; CELL first = *firstp; CELL last = *lastp; TRACE(("TrackText(first=%d,%d, last=%d,%d)\n", first.row, first.col, last.row, last.col)); old_start = screen->startH; old_end = screen->endH; TRACE(("...previous(first=%d,%d, last=%d,%d)\n", old_start.row, old_start.col, old_end.row, old_end.col)); if (isSameCELL(&first, &old_start) && isSameCELL(&last, &old_end)) { return; } screen->startH = first; screen->endH = last; from = Coordinate(screen, &screen->startH); to = Coordinate(screen, &screen->endH); if (to <= screen->startHCoord || from > screen->endHCoord #if OPT_BLOCK_SELECT || screen->blockSelecting || screen->blockSelecting != screen->lastSelectWasBlock #endif ) { #if OPT_BLOCK_SELECT /* Either no overlap whatsoever between old and new hilite, or we're in block select mode (or just came from it), in which case there is no optimization possible. */ if (screen->lastSelectWasBlock) { /* If we just came from block select mode, we need to unhighlight more aggressively. */ old_start.col = 0; old_end.col = MaxCols(screen); } #endif ReHiliteText(xw, &old_start, &old_end); ReHiliteText(xw, &first, &last); } else { if (from < screen->startHCoord) { /* Extend left end */ ReHiliteText(xw, &first, &old_start); } else if (from > screen->startHCoord) { /* Shorten left end */ ReHiliteText(xw, &old_start, &first); } if (to > screen->endHCoord) { /* Extend right end */ ReHiliteText(xw, &old_end, &last); } else if (to < screen->endHCoord) { /* Shorten right end */ ReHiliteText(xw, &last, &old_end); } } screen->startHCoord = from; screen->endHCoord = to; } static void UnHiliteText(XtermWidget xw) { TrackText(xw, &zeroCELL, &zeroCELL); } /* Guaranteed that (first->row, first->col) <= (last->row, last->col) */ static void ReHiliteText(XtermWidget xw, const CELL *firstp, const CELL *lastp) { TScreen *screen = TScreenOf(xw); CELL first = *firstp; CELL last = *lastp; TRACE(("ReHiliteText from %d.%d to %d.%d\n", first.row, first.col, last.row, last.col)); if (first.row < 0) first.row = first.col = 0; else if (first.row > screen->max_row) return; /* nothing to do, since last.row >= first.row */ if (last.row < 0) return; /* nothing to do, since first.row <= last.row */ else if (last.row > screen->max_row) { last.row = screen->max_row; last.col = MaxCols(screen); } if (isSameCELL(&first, &last)) return; #if OPT_BLOCK_SELECT if (screen->blockSelecting) { /* In block select mode, there is no special case for the first or last rows. Also, unlike normal selections, there can be unselected text on both sides of the selection per row, so we refresh all columns. */ int row; for (row = first.row; row <= last.row; row++) { ScrnRefresh(xw, row, 0, 1, MaxCols(screen), True); } } else #endif if (!isSameRow(&first, &last)) { /* do multiple rows */ int i; if ((i = screen->max_col - first.col + 1) > 0) { /* first row */ ScrnRefresh(xw, first.row, first.col, 1, i, True); } if ((i = last.row - first.row - 1) > 0) { /* middle rows */ ScrnRefresh(xw, first.row + 1, 0, i, MaxCols(screen), True); } if (last.col > 0 && last.row <= screen->max_row) { /* last row */ ScrnRefresh(xw, last.row, 0, 1, last.col, True); } } else { /* do single row */ ScrnRefresh(xw, first.row, first.col, 1, last.col - first.col, True); } } /* * Guaranteed that (cellc->row, cellc->col) <= (cell->row, cell->col), * and that both points are valid * (may have cell->row = screen->max_row+1, cell->col = 0). */ static void SaltTextAway(XtermWidget xw, int which, const CELL *cellc, const CELL *cell) { TScreen *screen = TScreenOf(xw); SelectedCells *scp; int i; int eol; int need = 0; size_t have = 0; Char *line; Char *lp; CELL first = *cellc; CELL last = *cell; if (which < 0 || which >= MAX_SELECTIONS) { TRACE(("SaltTextAway - which selection?\n")); return; } scp = &(screen->selected_cells[which]); TRACE(("SaltTextAway which=%d, first=%d,%d, last=%d,%d\n", which, first.row, first.col, last.row, last.col)); if (isSameRow(&first, &last) && first.col > last.col) { int tmp; EXCHANGE(first.col, last.col, tmp); } --last.col; /* first we need to know how long the string is before we can save it */ if (isSameRow(&last, &first)) { need = Length(screen, first.row, first.col, last.col); } else { /* two cases, cut is on same line, cut spans multiple lines */ need += Length(screen, first.row, first.col, screen->max_col) + 1; for (i = first.row + 1; i < last.row; i++) need += Length(screen, i, 0, screen->max_col) + 1; if (last.col >= 0) need += Length(screen, last.row, 0, last.col); } /* UTF-8 may require more space */ if_OPT_WIDE_CHARS(screen, { if (need > 0) { if (screen->max_combining > 0) need += screen->max_combining; need *= 6; } }); /* now get some memory to save it in */ if (need < 0) return; if (scp->data_limit <= (unsigned) need) { if ((line = (Char *) malloc((size_t) need + 1)) == NULL) SysError(ERROR_BMALLOC2); free(scp->data_buffer); scp->data_buffer = line; scp->data_limit = (size_t) (need + 1); } else { line = scp->data_buffer; } if (line == NULL) return; line[need] = '\0'; /* make sure it is null terminated */ lp = line; /* lp points to where to save the text */ if (isSameRow(&last, &first)) { lp = SaveText(screen, last.row, first.col, last.col, lp, &eol); } #if OPT_BLOCK_SELECT else if (screen->blockSelecting) { /* In block select mode, find the left most column of the block. This can be from either the start or the end of the selection. */ int blockFirst, blockLast; if (first.col < last.col) { blockFirst = first.col; blockLast = last.col; } else { blockFirst = last.col; blockLast = first.col; } for (i = first.row; i <= last.row; i++) { lp = SaveText(screen, i, blockFirst, blockLast, lp, &eol); if (i < last.row || eol) *lp++ = '\n'; } } #endif else { lp = SaveText(screen, first.row, first.col, screen->max_col, lp, &eol); if (eol) *lp++ = '\n'; /* put in newline at end of line */ for (i = first.row + 1; i < last.row; i++) { lp = SaveText(screen, i, 0, screen->max_col, lp, &eol); if (eol) *lp++ = '\n'; } if (last.col >= 0) lp = SaveText(screen, last.row, 0, last.col, lp, &eol); } *lp = '\0'; /* make sure we have end marked */ have = (size_t) (lp - line); /* * Scanning the buffer twice is unnecessary. Discard unwanted memory if * the estimate is too-far off. */ if ((have * 2) < (size_t) need) { Char *next; scp->data_limit = have + 1; next = realloc(line, scp->data_limit); if (next == NULL) { free(line); scp->data_length = 0; scp->data_limit = 0; } scp->data_buffer = next; } scp->data_length = have; TRACE(("Salted TEXT:%u:%s\n", (unsigned) have, visibleChars(scp->data_buffer, (unsigned) have))); } #if OPT_PASTE64 void ClearSelectionBuffer(TScreen *screen, String selection) { int which = TargetToSelection(screen, selection); SelectedCells *scp = &(screen->selected_cells[okSelectionCode(which)]); FreeAndNull(scp->data_buffer); scp->data_limit = 0; scp->data_length = 0; screen->base64_count = 0; } static void AppendStrToSelectionBuffer(SelectedCells * scp, Char *text, size_t len) { if (len != 0) { size_t j = (scp->data_length + len); size_t k = j + (j >> 2) + 80; if (j + 1 >= scp->data_limit) { Char *line; if (!scp->data_length) { line = (Char *) malloc(k); } else { line = (Char *) realloc(scp->data_buffer, k); } if (line == NULL) SysError(ERROR_BMALLOC2); scp->data_buffer = line; scp->data_limit = k; } if (scp->data_buffer != NULL) { memcpy(scp->data_buffer + scp->data_length, text, len); scp->data_length += len; scp->data_buffer[scp->data_length] = 0; } } } void AppendToSelectionBuffer(TScreen *screen, unsigned c, String selection) { int which = TargetToSelection(screen, selection); SelectedCells *scp = &(screen->selected_cells[okSelectionCode(which)]); unsigned six; Char ch; /* Decode base64 character */ if (c >= 'A' && c <= 'Z') six = c - 'A'; else if (c >= 'a' && c <= 'z') six = c - 'a' + 26; else if (c >= '0' && c <= '9') six = c - '0' + 52; else if (c == '+') six = 62; else if (c == '/') six = 63; else return; /* Accumulate bytes */ switch (screen->base64_count) { case 0: screen->base64_accu = six; screen->base64_count = 6; break; case 2: ch = CharOf((screen->base64_accu << 6) + six); screen->base64_count = 0; AppendStrToSelectionBuffer(scp, &ch, (size_t) 1); break; case 4: ch = CharOf((screen->base64_accu << 4) + (six >> 2)); screen->base64_accu = (six & 0x3); screen->base64_count = 2; AppendStrToSelectionBuffer(scp, &ch, (size_t) 1); break; case 6: ch = CharOf((screen->base64_accu << 2) + (six >> 4)); screen->base64_accu = (six & 0xF); screen->base64_count = 4; AppendStrToSelectionBuffer(scp, &ch, (size_t) 1); break; } } void CompleteSelection(XtermWidget xw, String *args, Cardinal len) { TScreen *screen = TScreenOf(xw); screen->base64_count = 0; screen->base64_accu = 0; _OwnSelection(xw, args, len); } #endif /* OPT_PASTE64 */ static Bool _ConvertSelectionHelper(Widget w, SelectedCells * scp, Atom *type, XtPointer *value, unsigned long *length, int *format, int (*conversion_function) (Display *, char **, int, XICCEncodingStyle, XTextProperty *), XICCEncodingStyle conversion_style) { *value = NULL; *length = 0; *type = 0; *format = 0; if (getXtermWidget(w) != NULL) { Display *dpy = XtDisplay(w); XTextProperty textprop; int out_n = 0; char *result = NULL; char *the_data = (char *) scp->data_buffer; char *the_next; unsigned long remaining = scp->data_length; TRACE(("converting %ld:'%s'\n", (long) scp->data_length, visibleChars(scp->data_buffer, (unsigned) scp->data_length))); /* * For most selections, we can convert in one pass. It is possible * that some applications contain embedded nulls, e.g., using xterm's * paste64 feature. For those cases, we will build up the result in * parts. */ if (memchr(the_data, 0, scp->data_length) != NULL) { TRACE(("selection contains embedded nulls\n")); result = calloc(scp->data_length + 1, sizeof(char)); } next_try: memset(&textprop, 0, sizeof(textprop)); if (conversion_function(dpy, &the_data, 1, conversion_style, &textprop) >= Success) { if ((result != NULL) && (textprop.value != NULL) && (textprop.format == 8)) { char *text_values = (char *) textprop.value; unsigned long in_n; if (out_n == 0) { *value = result; *type = textprop.encoding; *format = textprop.format; } for (in_n = 0; in_n < textprop.nitems; ++in_n) { result[out_n++] = text_values[in_n]; } *length += textprop.nitems; if ((the_next = memchr(the_data, 0, remaining)) != NULL) { unsigned long this_was = (unsigned long) (the_next - the_data); this_was++; the_data += this_was; remaining -= this_was; result[out_n++] = 0; *length += 1; if (remaining) goto next_try; } return True; } else { free(result); *value = (XtPointer) textprop.value; *length = textprop.nitems; *type = textprop.encoding; *format = textprop.format; return True; } } free(result); } return False; } static Boolean SaveConvertedLength(XtPointer *target, unsigned long source) { Boolean result = False; *target = XtMalloc(4); if (*target != NULL) { result = True; if (sizeof(unsigned long) == 4) { *(unsigned long *) *target = source; } else if (sizeof(unsigned) == 4) { *(unsigned *) *target = (unsigned) source; } else if (sizeof(unsigned short) == 4) { *(unsigned short *) *target = (unsigned short) source; } else { /* FIXME - does this depend on byte-order? */ unsigned long temp = source; memcpy((char *) *target, ((char *) &temp) + sizeof(temp) - 4, (size_t) 4); } } return result; } #define keepClipboard(d,atom) ((screen->keepClipboard) && \ (atom == XA_CLIPBOARD(d))) static Boolean ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type, XtPointer *value, unsigned long *length, int *format) { Display *dpy = XtDisplay(w); TScreen *screen; SelectedCells *scp; Bool result = False; Char *data; unsigned long data_length; XtermWidget xw; if ((xw = getXtermWidget(w)) == NULL) return False; screen = TScreenOf(xw); TRACE(("ConvertSelection %s -> %s\n", TraceAtomName(screen->display, *selection), visibleSelectionTarget(dpy, *target))); if (keepClipboard(dpy, *selection)) { TRACE(("asked for clipboard\n")); scp = &(screen->clipboard_data); } else { TRACE(("asked for selection\n")); scp = &(screen->selected_cells[AtomToSelection(dpy, *selection)]); } data = scp->data_buffer; data_length = scp->data_length; if (data == NULL) { TRACE(("...no selection-data\n")); return False; } if (*target == XA_TARGETS(dpy)) { Atom *targetP; XPointer std_return = NULL; unsigned long std_length; if (XmuConvertStandardSelection(w, screen->selection_time, selection, target, type, &std_return, &std_length, format)) { Atom *my_targets = _SelectionTargets(w); Atom *allocP; Atom *std_targets; TRACE(("XmuConvertStandardSelection - success\n")); std_targets = (Atom *) (void *) (std_return); *length = std_length + 6; targetP = TypeXtMallocN(Atom, *length); allocP = targetP; *value = (XtPointer) targetP; if (my_targets != NULL) { while (*my_targets != None) { *targetP++ = *my_targets++; } } *targetP++ = XA_LENGTH(dpy); *targetP++ = XA_LIST_LENGTH(dpy); *length = std_length + (unsigned long) (targetP - allocP); memcpy(targetP, std_targets, sizeof(Atom) * std_length); XtFree((char *) std_targets); *type = XA_ATOM; *format = 32; result = True; } else { TRACE(("XmuConvertStandardSelection - failed\n")); } } #if OPT_WIDE_CHARS else if (screen->wide_chars && *target == XA_STRING) { result = _ConvertSelectionHelper(w, scp, type, value, length, format, Xutf8TextListToTextProperty, XStringStyle); TRACE(("...Xutf8TextListToTextProperty:%d\n", result)); } else if (screen->wide_chars && *target == XA_UTF8_STRING(dpy)) { result = _ConvertSelectionHelper(w, scp, type, value, length, format, Xutf8TextListToTextProperty, XUTF8StringStyle); TRACE(("...Xutf8TextListToTextProperty:%d\n", result)); } else if (screen->wide_chars && *target == XA_TEXT(dpy)) { result = _ConvertSelectionHelper(w, scp, type, value, length, format, Xutf8TextListToTextProperty, XStdICCTextStyle); TRACE(("...Xutf8TextListToTextProperty:%d\n", result)); } else if (screen->wide_chars && *target == XA_COMPOUND_TEXT(dpy)) { result = _ConvertSelectionHelper(w, scp, type, value, length, format, Xutf8TextListToTextProperty, XCompoundTextStyle); TRACE(("...Xutf8TextListToTextProperty:%d\n", result)); } #endif else if (*target == XA_STRING) { /* not wide_chars */ /* We can only reach this point if the selection requestor requested STRING before any of TEXT, COMPOUND_TEXT or UTF8_STRING. We therefore assume that the requestor is not properly internationalised, and dump raw eight-bit data with no conversion into the selection. Yes, this breaks the ICCCM in non-Latin-1 locales. */ *type = XA_STRING; *value = (XtPointer) data; *length = data_length; *format = 8; result = True; TRACE(("...raw 8-bit data:%d\n", result)); } else if (*target == XA_TEXT(dpy)) { /* not wide_chars */ result = _ConvertSelectionHelper(w, scp, type, value, length, format, XmbTextListToTextProperty, XStdICCTextStyle); TRACE(("...XmbTextListToTextProperty(StdICC):%d\n", result)); } else if (*target == XA_COMPOUND_TEXT(dpy)) { /* not wide_chars */ result = _ConvertSelectionHelper(w, scp, type, value, length, format, XmbTextListToTextProperty, XCompoundTextStyle); TRACE(("...XmbTextListToTextProperty(Compound):%d\n", result)); } #ifdef X_HAVE_UTF8_STRING else if (*target == XA_UTF8_STRING(dpy)) { /* not wide_chars */ result = _ConvertSelectionHelper(w, scp, type, value, length, format, XmbTextListToTextProperty, XUTF8StringStyle); TRACE(("...XmbTextListToTextProperty(UTF8):%d\n", result)); } #endif else if (*target == XA_LIST_LENGTH(dpy)) { result = SaveConvertedLength(value, (unsigned long) 1); *type = XA_INTEGER; *length = 1; *format = 32; TRACE(("...list of values:%d\n", result)); } else if (*target == XA_LENGTH(dpy)) { /* This value is wrong if we have UTF-8 text */ result = SaveConvertedLength(value, scp->data_length); *type = XA_INTEGER; *length = 1; *format = 32; TRACE(("...list of values:%d\n", result)); } else if (XmuConvertStandardSelection(w, screen->selection_time, selection, target, type, (XPointer *) value, length, format)) { result = True; TRACE(("...XmuConvertStandardSelection:%d\n", result)); } /* else */ return (Boolean) result; } static void LoseSelection(Widget w, Atom *selection) { TScreen *screen; Atom *atomP; Cardinal i; XtermWidget xw; if ((xw = getXtermWidget(w)) == NULL) return; screen = TScreenOf(xw); TRACE(("LoseSelection %s\n", TraceAtomName(screen->display, *selection))); for (i = 0, atomP = screen->selection_atoms; i < screen->selection_count; i++, atomP++) { if (*selection == *atomP) *atomP = (Atom) 0; if (CutBuffer(*atomP) >= 0) { *atomP = (Atom) 0; } } for (i = screen->selection_count; i; i--) { if (screen->selection_atoms[i - 1] != 0) break; } screen->selection_count = i; for (i = 0, atomP = screen->selection_atoms; i < screen->selection_count; i++, atomP++) { if (*atomP == (Atom) 0) { *atomP = screen->selection_atoms[--screen->selection_count]; } } if (screen->selection_count == 0) UnHiliteText(xw); } /* ARGSUSED */ static void SelectionDone(Widget w GCC_UNUSED, Atom *selection GCC_UNUSED, Atom *target GCC_UNUSED) { /* empty proc so Intrinsics know we want to keep storage */ TRACE(("SelectionDone\n")); } static void _OwnSelection(XtermWidget xw, String *selections, Cardinal count) { TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; Atom *atoms = screen->selection_atoms; Cardinal i; Bool have_selection = False; SelectedCells *scp; if (count == 0) return; TRACE(("_OwnSelection count %d\n", count)); selections = MapSelections(xw, selections, count); if (count > screen->sel_atoms_size) { XtFree((char *) atoms); atoms = TypeXtMallocN(Atom, count); screen->selection_atoms = atoms; screen->sel_atoms_size = count; } XmuInternStrings(dpy, selections, count, atoms); for (i = 0; i < count; i++) { int cutbuffer = CutBuffer(atoms[i]); if (cutbuffer >= 0) { unsigned long limit = (unsigned long) (4 * XMaxRequestSize(dpy) - 32); scp = &(screen->selected_cells[CutBufferToCode(cutbuffer)]); if (scp->data_length > limit) { TRACE(("selection too big (%lu bytes), not storing in CUT_BUFFER%d\n", (unsigned long) scp->data_length, cutbuffer)); xtermWarning("selection too big (%lu bytes), not storing in CUT_BUFFER%d\n", (unsigned long) scp->data_length, cutbuffer); } else { /* This used to just use the UTF-8 data, which was totally * broken as not even the corresponding paste code in xterm * understood this! So now it converts to Latin1 first. * Robert Brady, 2000-09-05 */ unsigned long length = scp->data_length; Char *data = scp->data_buffer; if_OPT_WIDE_CHARS((screen), { data = UTF8toLatin1(screen, data, length, &length); }); TRACE(("XStoreBuffer(%d)\n", cutbuffer)); XStoreBuffer(dpy, (char *) data, (int) length, cutbuffer); } } else { int which = AtomToSelection(dpy, atoms[i]); if (keepClipboard(dpy, atoms[i])) { Char *buf; SelectedCells *tcp = &(screen->clipboard_data); TRACE(("saving selection to clipboard buffer\n")); scp = &(screen->selected_cells[CLIPBOARD_CODE]); if ((buf = (Char *) malloc((size_t) scp->data_length)) == NULL) { SysError(ERROR_BMALLOC2); } else { free(tcp->data_buffer); memcpy(buf, scp->data_buffer, scp->data_length); tcp->data_buffer = buf; tcp->data_limit = scp->data_length; tcp->data_length = scp->data_length; } } scp = &(screen->selected_cells[which]); if (scp->data_length == 0) { TRACE(("XtDisownSelection(%s, @%ld)\n", TraceAtomName(screen->display, atoms[i]), (long) screen->selection_time)); XtDisownSelection((Widget) xw, atoms[i], screen->selection_time); } else if (!screen->replyToEmacs && atoms[i] != 0) { TRACE(("XtOwnSelection(%s, @%ld)\n", TraceAtomName(screen->display, atoms[i]), (long) screen->selection_time)); have_selection |= XtOwnSelection((Widget) xw, atoms[i], screen->selection_time, ConvertSelection, LoseSelection, SelectionDone); } } TRACE(("... _OwnSelection used length %lu value %s\n", (unsigned long) scp->data_length, visibleChars(scp->data_buffer, (unsigned) scp->data_length))); } if (!screen->replyToEmacs) screen->selection_count = count; if (!have_selection) UnHiliteText(xw); } static void ResetSelectionState(TScreen *screen) { screen->selection_count = 0; screen->startH = zeroCELL; screen->endH = zeroCELL; } void DisownSelection(XtermWidget xw) { TScreen *screen = TScreenOf(xw); Atom *atoms = screen->selection_atoms; Cardinal count = screen->selection_count; Cardinal i; TRACE(("DisownSelection count %d, start %d.%d, end %d.%d\n", count, screen->startH.row, screen->startH.col, screen->endH.row, screen->endH.col)); for (i = 0; i < count; i++) { int cutbuffer = CutBuffer(atoms[i]); if (cutbuffer < 0) { XtDisownSelection((Widget) xw, atoms[i], screen->selection_time); } } /* * If none of the callbacks via XtDisownSelection() reset highlighting * do it now. */ if (ScrnHaveSelection(screen)) { /* save data which will be reset */ CELL first = screen->startH; CELL last = screen->endH; ResetSelectionState(screen); ReHiliteText(xw, &first, &last); } else { ResetSelectionState(screen); } } void UnhiliteSelection(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (ScrnHaveSelection(screen)) { CELL first = screen->startH; CELL last = screen->endH; screen->startH = zeroCELL; screen->endH = zeroCELL; ReHiliteText(xw, &first, &last); } } /* returns number of chars in line from scol to ecol out */ /* ARGSUSED */ static int Length(TScreen *screen, int row, int scol, int ecol) { CLineData *ld = GET_LINEDATA(screen, row); const int lastcol = LastTextCol(screen, ld, row); if (ecol > lastcol) ecol = lastcol; return Max(0, (ecol - scol + 1)); } /* copies text into line, preallocated */ static Char * SaveText(TScreen *screen, int row, int scol, int ecol, Char *lp, /* pointer to where to put the text */ int *eol) { LineData *ld; int i = 0; Char *result = lp; #if OPT_WIDE_CHARS unsigned previous = 0; #endif ld = GET_LINEDATA(screen, row); i = Length(screen, row, scol, ecol); ecol = scol + i; #if OPT_DEC_CHRSET if (CSET_DOUBLE(GetLineDblCS(ld))) { scol = (scol + 0) / 2; ecol = (ecol + 1) / 2; } #endif *eol = !LineTstWrapped(ld); for (i = scol; i < ecol; i++) { unsigned c; if (i >= (int) ld->lineSize) { /* The terminal was probably resized */ *lp++ = CharOf(' '); continue; } c = ld->charData[i]; if (ld->attribs[i] & INVISIBLE) continue; #if OPT_WIDE_CHARS /* We want to strip out every occurrence of HIDDEN_CHAR AFTER a * wide character. */ if (c == HIDDEN_CHAR) { if (isWide((int) previous)) { previous = c; /* Combining characters attached to double-width characters are in memory attached to the HIDDEN_CHAR */ if_OPT_WIDE_CHARS(screen, { if ((screen->utf8_nrc_mode | screen->utf8_mode) != uFalse) { size_t off; for_each_combData(off, ld) { unsigned ch = ld->combData[off][i]; if (ch == 0) break; lp = convertToUTF8(lp, ch); } } }); continue; } else { c = ' '; /* should not happen, but just in case... */ } } previous = c; if ((screen->utf8_nrc_mode | screen->utf8_mode) != uFalse) { lp = convertToUTF8(lp, (c != 0) ? c : ' '); if_OPT_WIDE_CHARS(screen, { size_t off; for_each_combData(off, ld) { unsigned ch = ld->combData[off][i]; if (ch == 0) break; lp = convertToUTF8(lp, ch); } }); } else #endif { if (c == 0) { c = ' '; } else if (c < ' ') { c = DECtoASCII(c); } else if (c == 0x7f) { c = 0x5f; } *lp++ = CharOf(c); } if (c != ' ') result = lp; } /* * If requested, trim trailing blanks from selected lines. Do not do this * if the line is wrapped. */ if (!*eol || !screen->trim_selection) result = lp; return (result); } /* * This adds together the bits: * shift key -> 1 * meta key -> 2 * control key -> 4 */ static unsigned KeyState(XtermWidget xw, unsigned x) { return ((((x) & (ShiftMask | ControlMask))) + (((x) & MetaMask(xw)) ? 2 : 0)); } /* 32 + following 8-bit word: 1:0 Button no: 0, 1, 2. 3=release. 2 shift 3 meta 4 ctrl 5 set for motion notify 6 set for wheel (and button 6 and 7) 7 set for buttons 8 to 11 */ /* Position: 32 - 255. */ static int BtnCode(XtermWidget xw, XButtonEvent *event, int button) { int result = (int) (32 + (KeyState(xw, event->state) << 2)); if (event->type == MotionNotify) result += 32; if (button < 0) { result += 3; } else { result += button & 3; if (button & 4) result += 64; if (button & 8) result += 128; } TRACE(("BtnCode button %d, %s state " FMT_MODIFIER_NAMES " ->%#x\n", button, visibleEventType(event->type), ARG_MODIFIER_NAMES(event->state), result)); return result; } static unsigned EmitButtonCode(XtermWidget xw, Char *line, unsigned count, XButtonEvent *event, int button) { TScreen *screen = TScreenOf(xw); int value; if (okSendMousePos(xw) == X10_MOUSE) { value = CharOf(' ' + button); } else { value = BtnCode(xw, event, button); } switch (screen->extend_coords) { default: line[count++] = CharOf(value); break; case SET_SGR_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: value -= 32; /* encoding starts at zero */ /* FALLTHRU */ case SET_URXVT_EXT_MODE_MOUSE: count += (unsigned) sprintf((char *) line + count, "%d", value); break; case SET_EXT_MODE_MOUSE: if (value < 128) { line[count++] = CharOf(value); } else { line[count++] = CharOf(0xC0 + (value >> 6)); line[count++] = CharOf(0x80 + (value & 0x3F)); } break; } return count; } static int FirstBitN(int bits) { int result = -1; if (bits > 0) { result = 0; while (!(bits & 1)) { bits /= 2; ++result; } } return result; } #define ButtonBit(button) ((button >= 0) ? (1 << (button)) : 0) #define EMIT_BUTTON(button) EmitButtonCode(xw, line, count, event, button) static void EditorButton(XtermWidget xw, XButtonEvent *event) { TScreen *screen = TScreenOf(xw); int pty = screen->respond; int mouse_limit = MouseLimit(screen); Char line[32]; Char final = 'M'; int row, col; int button; unsigned count = 0; Boolean changed = True; /* If button event, get button # adjusted for DEC compatibility */ button = (int) (event->button - 1); if (button >= 3) button++; /* Ignore buttons that cannot be encoded */ if (screen->send_mouse_pos == X10_MOUSE) { if (button > 3) return; } else if (screen->extend_coords == SET_SGR_EXT_MODE_MOUSE || screen->extend_coords == SET_URXVT_EXT_MODE_MOUSE || screen->extend_coords == SET_PIXEL_POSITION_MOUSE) { if (button > 15) { return; } } else { if (button > 11) { return; } } if (screen->extend_coords == SET_PIXEL_POSITION_MOUSE) { row = event->y - OriginY(screen); col = event->x - OriginX(screen); } else { /* Compute character position of mouse pointer */ row = (event->y - screen->border) / FontHeight(screen); col = (event->x - OriginX(screen)) / FontWidth(screen); /* Limit to screen dimensions */ if (row < 0) row = 0; else if (row > screen->max_row) row = screen->max_row; if (col < 0) col = 0; else if (col > screen->max_col) col = screen->max_col; if (mouse_limit > 0) { /* Limit to representable mouse dimensions */ if (row > mouse_limit) row = mouse_limit; if (col > mouse_limit) col = mouse_limit; } } /* Build key sequence starting with \E[M */ if (screen->control_eight_bits) { line[count++] = ANSI_CSI; } else { line[count++] = ANSI_ESC; line[count++] = '['; } switch (screen->extend_coords) { case 0: case SET_EXT_MODE_MOUSE: #if OPT_SCO_FUNC_KEYS if (xw->keyboard.type == keyboardIsSCO) { /* * SCO function key F1 is \E[M, which would conflict with xterm's * normal kmous. */ line[count++] = '>'; } #endif line[count++] = final; break; case SET_SGR_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: line[count++] = '<'; break; } /* Add event code to key sequence */ if (okSendMousePos(xw) == X10_MOUSE) { count = EMIT_BUTTON(button); } else { /* Button-Motion events */ switch (event->type) { case ButtonPress: screen->mouse_button |= ButtonBit(button); count = EMIT_BUTTON(button); break; case ButtonRelease: /* * The (vertical) wheel mouse interface generates release-events * for buttons 4 and 5. * * The X10/X11 xterm protocol maps the release for buttons 1..3 to * a -1, which will be later mapped into a "0" (some button was * released), At this point, buttons 1..3 are encoded 0..2 (the * code 3 is unused). * * The SGR (extended) xterm mouse protocol keeps the button number * and uses a "m" to indicate button release. * * The behavior for mice with more buttons is unclear, and may be * revised -TD */ screen->mouse_button &= ~ButtonBit(button); if (button < 3 || button > 5) { switch (screen->extend_coords) { case SET_SGR_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: final = 'm'; break; default: button = -1; break; } } count = EMIT_BUTTON(button); break; case MotionNotify: /* BTN_EVENT_MOUSE and ANY_EVENT_MOUSE modes send motion * events only if character cell has changed. */ if ((row == screen->mouse_row) && (col == screen->mouse_col)) { changed = False; } else { count = EMIT_BUTTON(FirstBitN(screen->mouse_button)); } break; default: changed = False; break; } } if (changed) { screen->mouse_row = row; screen->mouse_col = col; TRACE(("mouse at %d,%d button+mask = %#x\n", row, col, line[count - 1])); /* Add pointer position to key sequence */ count = EmitMousePositionSeparator(screen, line, count); count = EmitMousePosition(screen, line, count, col); count = EmitMousePositionSeparator(screen, line, count); count = EmitMousePosition(screen, line, count, row); switch (screen->extend_coords) { case SET_SGR_EXT_MODE_MOUSE: case SET_URXVT_EXT_MODE_MOUSE: case SET_PIXEL_POSITION_MOUSE: line[count++] = final; break; } /* Transmit key sequence to process running under xterm */ TRACE(("EditorButton -> %s\n", visibleChars(line, count))); v_write(pty, line, (size_t) count); } return; } /* * Check the current send_mouse_pos against allowed mouse-operations, returning * none if it is disallowed. */ XtermMouseModes okSendMousePos(XtermWidget xw) { TScreen *screen = TScreenOf(xw); XtermMouseModes result = (XtermMouseModes) screen->send_mouse_pos; switch ((int) result) { case MOUSE_OFF: break; case X10_MOUSE: if (!AllowMouseOps(xw, emX10)) result = MOUSE_OFF; break; case VT200_MOUSE: if (!AllowMouseOps(xw, emVT200Click)) result = MOUSE_OFF; break; case VT200_HIGHLIGHT_MOUSE: if (!AllowMouseOps(xw, emVT200Hilite)) result = MOUSE_OFF; break; case BTN_EVENT_MOUSE: if (!AllowMouseOps(xw, emAnyButton)) result = MOUSE_OFF; break; case ANY_EVENT_MOUSE: if (!AllowMouseOps(xw, emAnyEvent)) result = MOUSE_OFF; break; case DEC_LOCATOR: if (!AllowMouseOps(xw, emLocator)) result = MOUSE_OFF; break; } return result; } #if OPT_FOCUS_EVENT /* * Check the current send_focus_pos against allowed mouse-operations, returning * none if it is disallowed. */ static int okSendFocusPos(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int result = screen->send_focus_pos; if (!AllowMouseOps(xw, emFocusEvent)) { result = False; } return result; } void SendFocusButton(XtermWidget xw, XFocusChangeEvent *event) { if (okSendFocusPos(xw)) { ANSI reply; memset(&reply, 0, sizeof(reply)); reply.a_type = ANSI_CSI; #if OPT_SCO_FUNC_KEYS if (xw->keyboard.type == keyboardIsSCO) { reply.a_pintro = '>'; } #endif reply.a_final = CharOf((event->type == FocusIn) ? 'I' : 'O'); unparseseq(xw, &reply); } return; } #endif /* OPT_FOCUS_EVENT */ #if OPT_SELECTION_OPS /* * Get the event-time, needed to process selections. */ static Time getEventTime(XEvent *event) { Time result; if (IsBtnEvent(event)) { result = ((XButtonEvent *) event)->time; } else if (IsKeyEvent(event)) { result = ((XKeyEvent *) event)->time; } else { result = 0; } return result; } /* obtain the selection string, passing the endpoints to caller's parameters */ static void doSelectionFormat(XtermWidget xw, Widget w, XEvent *event, String *params, const Cardinal *num_params, FormatSelect format_select) { TScreen *screen = TScreenOf(xw); InternalSelect *mydata = &(screen->internal_select); memset(mydata, 0, sizeof(*mydata)); mydata->format = x_strdup(params[0]); mydata->format_select = format_select; screen->selectToBuffer = True; beginInternalSelect(xw); xtermGetSelection(w, getEventTime(event), params + 1, *num_params - 1, NULL); if (screen->selectToBuffer) finishInternalSelect(xw); } /* obtain data from the screen, passing the endpoints to caller's parameters */ static char * getDataFromScreen(XtermWidget xw, XEvent *event, String method, CELL *start, CELL *finish) { TScreen *screen = TScreenOf(xw); CELL save_old_start = screen->startH; CELL save_old_end = screen->endH; CELL save_startSel = screen->startSel; CELL save_startRaw = screen->startRaw; CELL save_finishSel = screen->endSel; CELL save_finishRaw = screen->endRaw; int save_firstValidRow = screen->firstValidRow; int save_lastValidRow = screen->lastValidRow; const Cardinal noClick = 0; int save_numberOfClicks = screen->numberOfClicks; SelectUnit saveUnits = screen->selectUnit; SelectUnit saveMap = screen->selectMap[noClick]; #if OPT_SELECT_REGEX char *saveExpr = screen->selectExpr[noClick]; #endif SelectedCells *scp = &(screen->selected_cells[PRIMARY_CODE]); SelectedCells save_selection = *scp; char *result = NULL; TRACE(("getDataFromScreen %s\n", method)); memset(scp, 0, sizeof(*scp)); screen->numberOfClicks = 1; lookupSelectUnit(xw, noClick, method); screen->selectUnit = screen->selectMap[noClick]; memset(start, 0, sizeof(*start)); if (IsBtnEvent(event)) { XButtonEvent *btn_event = (XButtonEvent *) event; CELL cell; screen->firstValidRow = 0; screen->lastValidRow = screen->max_row; PointToCELL(screen, btn_event->y, btn_event->x, &cell); start->row = cell.row; start->col = cell.col; finish->row = cell.row; finish->col = screen->max_col; } else { start->row = screen->cur_row; start->col = screen->cur_col; finish->row = screen->cur_row; finish->col = screen->max_col; } ComputeSelect(xw, start, finish, False, False); SaltTextAway(xw, TargetToSelection(screen, PRIMARY_NAME), &(screen->startSel), &(screen->endSel)); if (scp->data_limit && scp->data_buffer) { TRACE(("...getDataFromScreen selection-data %.*s\n", (int) scp->data_limit, scp->data_buffer)); result = malloc(scp->data_limit + 1); if (result) { memcpy(result, scp->data_buffer, scp->data_limit); result[scp->data_limit] = 0; } free(scp->data_buffer); scp->data_limit = 0; } TRACE(("...getDataFromScreen restoring previous selection\n")); screen->startSel = save_startSel; screen->startRaw = save_startRaw; screen->endSel = save_finishSel; screen->endRaw = save_finishRaw; screen->firstValidRow = save_firstValidRow; screen->lastValidRow = save_lastValidRow; screen->numberOfClicks = save_numberOfClicks; screen->selectUnit = saveUnits; screen->selectMap[noClick] = saveMap; #if OPT_SELECT_REGEX screen->selectExpr[noClick] = saveExpr; #endif screen->selected_cells[0] = save_selection; TrackText(xw, &save_old_start, &save_old_end); TRACE(("...getDataFromScreen done\n")); return result; } #if OPT_EXEC_SELECTION /* * Split-up the format before substituting data, to avoid quoting issues. * The resource mechanism has a limited ability to handle escapes. We take * the result as if it were an sh-type string and parse it into a regular * argv array. */ static char ** tokenizeFormat(String format) { char **result = NULL; format = x_skip_blanks(format); if (*format != '\0') { char *blob = x_strdup(format); int pass; for (pass = 0; pass < 2; ++pass) { int used = 0; int first = 1; int escaped = 0; int squoted = 0; int dquoted = 0; int n; int argc = 0; for (n = 0; format[n] != '\0'; ++n) { if (escaped) { blob[used++] = format[n]; escaped = 0; } else if (format[n] == '"') { if (!squoted) { if (!dquoted) blob[used++] = format[n]; dquoted = !dquoted; } } else if (format[n] == '\'') { if (!dquoted) { if (!squoted) blob[used++] = format[n]; squoted = !squoted; } } else if (format[n] == '\\') { blob[used++] = format[n]; escaped = 1; } else { if (first) { first = 0; if (pass) { result[argc] = &blob[n]; } ++argc; } if (isspace((Char) format[n])) { first = !isspace((Char) format[n + 1]); if (squoted || dquoted) { blob[used++] = format[n]; } else if (first) { blob[used++] = '\0'; } } else { blob[used++] = format[n]; } } } blob[used] = '\0'; assert(strlen(blob) <= strlen(format)); if (!pass) { result = TypeCallocN(char *, argc + 1); if (result == NULL) { free(blob); break; } } } } #if OPT_TRACE if (result) { int n; TRACE(("tokenizeFormat %s\n", format)); for (n = 0; result[n]; ++n) { TRACE(("argv[%d] = %s\n", n, result[n])); } } #endif return result; } #endif /* OPT_EXEC_SELECTION */ static void formatVideoAttrs(XtermWidget xw, char *buffer, CELL *cell) { TScreen *screen = TScreenOf(xw); LineData *ld = GET_LINEDATA(screen, cell->row); *buffer = '\0'; if (ld != NULL && cell->col < (int) ld->lineSize) { IAttr attribs = ld->attribs[cell->col]; const char *delim = ""; if (attribs & INVERSE) { buffer += sprintf(buffer, "7"); delim = ";"; } if (attribs & UNDERLINE) { buffer += sprintf(buffer, "%s4", delim); delim = ";"; } if (attribs & BOLD) { buffer += sprintf(buffer, "%s1", delim); delim = ";"; } if (attribs & BLINK) { buffer += sprintf(buffer, "%s5", delim); delim = ";"; } #if OPT_ISO_COLORS if (attribs & FG_COLOR) { Pixel fg = extract_fg(xw, ld->color[cell->col], attribs); if (fg < 8) { fg += 30; } else if (fg < 16) { fg += 90; } else { buffer += sprintf(buffer, "%s38;5", delim); delim = ";"; } buffer += sprintf(buffer, "%s%lu", delim, fg); delim = ";"; } if (attribs & BG_COLOR) { Pixel bg = extract_bg(xw, ld->color[cell->col], attribs); if (bg < 8) { bg += 40; } else if (bg < 16) { bg += 100; } else { buffer += sprintf(buffer, "%s48;5", delim); delim = ";"; } (void) sprintf(buffer, "%s%lu", delim, bg); } #endif } } static char * formatStrlen(char *target, char *source, int freeit) { if (source != NULL) { sprintf(target, "%u", (unsigned) strlen(source)); if (freeit) { free(source); } } else { strcpy(target, "0"); } return target; } /* substitute data into format, reallocating the result */ static char * expandFormat(XtermWidget xw, const char *format, char *data, CELL *start, CELL *finish) { char *result = NULL; if (!IsEmpty(format)) { static char empty[1]; int pass; int n; char numbers[80]; if (data == NULL) data = empty; for (pass = 0; pass < 2; ++pass) { size_t need = 0; for (n = 0; format[n] != '\0'; ++n) { if (format[n] == '%') { char *value = NULL; switch (format[++n]) { case '%': if (pass) { result[need] = format[n]; } ++need; break; case 'P': sprintf(numbers, "%d;%d", TScreenOf(xw)->topline + start->row + 1, start->col + 1); value = numbers; break; case 'p': sprintf(numbers, "%d;%d", TScreenOf(xw)->topline + finish->row + 1, finish->col + 1); value = numbers; break; case 'R': value = formatStrlen(numbers, x_strrtrim(data), 1); break; case 'r': value = x_strrtrim(data); break; case 'S': value = formatStrlen(numbers, data, 0); break; case 's': value = data; break; case 'T': value = formatStrlen(numbers, x_strtrim(data), 1); break; case 't': value = x_strtrim(data); break; case 'V': formatVideoAttrs(xw, numbers, start); value = numbers; break; case 'v': formatVideoAttrs(xw, numbers, finish); value = numbers; break; default: if (pass) { result[need] = format[n]; } --n; ++need; break; } if (value != NULL) { if (pass) { strcpy(result + need, value); } need += strlen(value); if (value != numbers && value != data) { free(value); } } } else { if (pass) { result[need] = format[n]; } ++need; } } if (pass) { result[need] = '\0'; } else { ++need; result = malloc(need); if (result == NULL) { break; } } } } TRACE(("expandFormat(%s) = %s\n", NonNull(format), NonNull(result))); return result; } #if OPT_EXEC_SELECTION /* execute the command after forking. The main process frees its data */ static void executeCommand(pid_t pid, char **argv) { (void) pid; if (argv != NULL && argv[0] != NULL) { char *child_cwd = ProcGetCWD(pid); if (fork() == 0) { if (child_cwd) { IGNORE_RC(chdir(child_cwd)); /* We don't care if this fails */ } execvp(argv[0], argv); exit(EXIT_FAILURE); } free(child_cwd); } } static void freeArgv(char *blob, char **argv) { if (blob) { free(blob); if (argv) { int n; for (n = 0; argv[n]; ++n) free(argv[n]); free(argv); } } } static void reallyExecFormatted(Widget w, char *format, char *data, CELL *start, CELL *finish) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { char **argv; if ((argv = tokenizeFormat(format)) != NULL) { char *blob = argv[0]; int argc; for (argc = 0; argv[argc] != NULL; ++argc) { argv[argc] = expandFormat(xw, argv[argc], data, start, finish); } executeCommand(TScreenOf(xw)->pid, argv); freeArgv(blob, argv); } } } void HandleExecFormatted(Widget w, XEvent *event, String *params, /* selections */ Cardinal *num_params) { XtermWidget xw; TRACE_EVENT("HandleExecFormatted", event, params, num_params); if ((xw = getXtermWidget(w)) != NULL && (*num_params > 1)) { doSelectionFormat(xw, w, event, params, num_params, reallyExecFormatted); } } void HandleExecSelectable(Widget w, XEvent *event, String *params, /* selections */ Cardinal *num_params) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TRACE_EVENT("HandleExecSelectable", event, params, num_params); if (*num_params == 2) { CELL start, finish; char *data; char **argv; data = getDataFromScreen(xw, event, params[1], &start, &finish); if (data != NULL) { if ((argv = tokenizeFormat(params[0])) != NULL) { char *blob = argv[0]; int argc; for (argc = 0; argv[argc] != NULL; ++argc) { argv[argc] = expandFormat(xw, argv[argc], data, &start, &finish); } executeCommand(TScreenOf(xw)->pid, argv); freeArgv(blob, argv); } free(data); } } } } #endif /* OPT_EXEC_SELECTION */ static void reallyInsertFormatted(Widget w, char *format, char *data, CELL *start, CELL *finish) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { char *exps; if ((exps = expandFormat(xw, format, data, start, finish)) != NULL) { unparseputs(xw, exps); unparse_end(xw); free(exps); } } } void HandleInsertFormatted(Widget w, XEvent *event, String *params, /* selections */ Cardinal *num_params) { XtermWidget xw; TRACE_EVENT("HandleInsertFormatted", event, params, num_params); if ((xw = getXtermWidget(w)) != NULL && (*num_params > 1)) { doSelectionFormat(xw, w, event, params, num_params, reallyInsertFormatted); } } void HandleInsertSelectable(Widget w, XEvent *event, String *params, /* selections */ Cardinal *num_params) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { TRACE_EVENT("HandleInsertSelectable", event, params, num_params); if (*num_params == 2) { CELL start, finish; char *data; char *temp = x_strdup(params[0]); data = getDataFromScreen(xw, event, params[1], &start, &finish); if (data != NULL) { char *exps = expandFormat(xw, temp, data, &start, &finish); if (exps != NULL) { unparseputs(xw, exps); unparse_end(xw); free(exps); } free(data); } free(temp); } } } #endif /* OPT_SELECTION_OPS */ xterm-399/xtermcap.h0000644000000000000000000000626312161612615013241 0ustar rootroot/* $XTermId: xtermcap.h,v 1.20 2013/06/23 15:34:37 tom Exp $ */ /* * Copyright 2007-2011,2013 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ /* * Common/useful definitions for XTERM termcap interface. */ #ifndef included_xtermcap_h #define included_xtermcap_h /* *INDENT-OFF* */ #include #include #ifndef HAVE_TIGETSTR #undef USE_TERMINFO #endif #ifndef USE_TERMINFO #define USE_TERMINFO 0 #endif #if !USE_TERMINFO #undef HAVE_TIGETSTR #ifndef USE_TERMCAP #define USE_TERMCAP 1 #endif #endif #undef ERR /* workaround for glibc 2.1.3 */ #ifdef HAVE_NCURSES_CURSES_H #include #else #include #endif #ifndef NCURSES_VERSION #ifdef HAVE_TERMCAP_H #include #endif #endif #ifdef HAVE_NCURSES_TERM_H #include #elif defined(HAVE_TERM_H) #include /* tgetent() */ #endif /* * Get rid of conflicting symbols from term.h */ #undef bell /***====================================================================***/ #ifdef __cplusplus extern "C" { #endif #define MOD_NONE 1 #define MOD_SHIFT 1 #define MOD_ALT 2 #define MOD_CTRL 4 #define MOD_META 8 #define MODIFIER_NAME(parm, name) \ (((parm > MOD_NONE) && ((parm - MOD_NONE) & name)) ? " "#name : "") /* xtermcap.c */ extern Bool get_termcap(XtermWidget /* xw */, char * /* name */); extern void set_termcap(XtermWidget /* xw */, const char * /* name */); extern void free_termcap(XtermWidget /* xw */); extern char *get_tcap_buffer(XtermWidget /* xw */); extern char *get_tcap_erase(XtermWidget /* xw */); #if OPT_TCAP_FKEYS extern int xtermcapString(XtermWidget /* xw */, int /* keycode */, unsigned /* mask */); #endif #if OPT_TCAP_QUERY extern int xtermcapKeycode(XtermWidget /* xw */, const char ** /* params */, unsigned * /* state */, Bool * /* fkey */); #endif #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* included_xtermcap_h */ xterm-399/README0000644000000000000000000000165710625366077012142 0ustar rootroot-- $XTermId: README,v 1.3 2007/05/24 19:49:19 tom Exp $ -- Below is the original README for xterm from 1991, for your amusement. -- For a better overview, see http://invisible-island.net/xterm/ ------------------------------------------------------------------------------- Abandon All Hope, Ye Who Enter Here This is undoubtedly the most ugly program in the distribution. It was one of the first "serious" programs ported, and still has a lot of historical baggage. Ideally, there would be a general tty widget and then vt102 and tek4014 subwidgets so that they could be used in other programs. We are trying to clean things up as we go, but there is still a lot of work to do. If you are porting this to a machine that has problems with overlapping bcopy's, watch out! There are two documents on xterm: the man page, xterm.man, which describes how to use it, and ctlseqs.ms, which describes the control sequences it understands. xterm-399/TekPrsTbl.c0000644000000000000000000015232314665361257013300 0ustar rootroot/* $XTermId: TekPrsTbl.c,v 1.10 2024/09/02 16:07:11 tom Exp $ */ /* * Copyright 1998-2006,2024 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. * * * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* $XFree86: xc/programs/xterm/TekPrsTbl.c,v 3.5 2006/02/13 01:14:57 dickey Exp $ */ #include /* *INDENT-OFF* */ const int Talptable[] = /* US (^_) normal alpha mode */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_BEL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_LF, CASE_UP, /* NP CR SO SI */ CASE_IGNORE, CASE_CR, CASE_IGNORE, CASE_IGNORE, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_ESC_STATE, /* FS GS RS US */ CASE_PT_STATE, CASE_PLT_STATE, CASE_IPL_STATE, CASE_ALP_STATE, /* SP ! " # */ CASE_SP, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* $ % & ' */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* ( ) * + */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* , - . / */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* 0 1 2 3 */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* 4 5 6 7 */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* 8 9 : ; */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* < = > ? */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* @ A B C */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* D E F G */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* H I J K */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* L M N O */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* P Q R S */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* T U V W */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* X Y Z [ */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* \ ] ^ _ */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* ` a b c */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* d e f g */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* h i j k */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* l m n o */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* p q r s */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* t u v w */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* x y z { */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* | } ~ DEL */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x99 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* currency yen brokenbar section */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* diaeresis copyright ordfeminine guillemotleft */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* notsign hyphen registered macron */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* degree plusminus twosuperior threesuperior */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* acute mu paragraph periodcentered */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* cedilla onesuperior masculine guillemotright */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* onequarter onehalf threequarters questiondown */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Agrave Aacute Acircumflex Atilde */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Adiaeresis Aring AE Ccedilla */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Eth Ntilde Ograve Oacute */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* Udiaeresis Yacute Thorn ssharp */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* agrave aacute acircumflex atilde */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* adiaeresis aring ae ccedilla */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* egrave eacute ecircumflex ediaeresis */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* igrave iacute icircumflex idiaeresis */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* eth ntilde ograve oacute */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* ocircumflex otilde odiaeresis division */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* oslash ugrave uacute ucircumflex */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, /* udiaeresis yacute thorn ydiaeresis */ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, }; const int Tbestable[] = /* ESC while in bypass state */ { /* NUL SOH STX ETX */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_VT_MODE, /* EOT ENQ ACK BEL */ CASE_BYP_STATE, CASE_REPORT, CASE_BYP_STATE, CASE_BEL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_IGNORE, CASE_UP, /* NP CR SO SI */ CASE_PAGE, CASE_IGNORE, CASE_BYP_STATE, CASE_BYP_STATE, /* DLE DC1 DC2 DC3 */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* DC4 NAK SYN ETB */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_COPY, /* CAN EM SUB ESC */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_GIN, CASE_IGNORE, /* FS GS RS US */ CASE_SPT_STATE, CASE_PLT_STATE, CASE_IPL_STATE, CASE_ALP_STATE, /* SP ! " # */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* $ % & ' */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* ( ) * + */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* , - . / */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* 0 1 2 3 */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* 4 5 6 7 */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* 8 9 : ; */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* < = > ? */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* @ A B C */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* D E F G */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* H I J K */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* L M N O */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* P Q R S */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* T U V W */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* X Y Z [ */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* \ ] ^ _ */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* ` a b c */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* d e f g */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* h i j k */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* l m n o */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* p q r s */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* t u v w */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* x y z { */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* | } ~ DEL */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_IGNORE, CASE_BYP_STATE, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x99 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* currency yen brokenbar section */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* notsign hyphen registered macron */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* degree plusminus twosuperior threesuperior */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* acute mu paragraph periodcentered */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* cedilla onesuperior masculine guillemotright */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* onequarter onehalf threequarters questiondown */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* Agrave Aacute Acircumflex Atilde */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* Adiaeresis Aring AE Ccedilla */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* Eth Ntilde Ograve Oacute */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* Udiaeresis Yacute Thorn ssharp */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* agrave aacute acircumflex atilde */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* adiaeresis aring ae ccedilla */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* egrave eacute ecircumflex ediaeresis */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* igrave iacute icircumflex idiaeresis */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* eth ntilde ograve oacute */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* ocircumflex otilde odiaeresis division */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* oslash ugrave uacute ucircumflex */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, /* udiaeresis yacute thorn ydiaeresis */ CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, CASE_BYP_STATE, }; const int Tbyptable[] = /* ESC CAN (^X) bypass state */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_BEL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_LF, CASE_UP, /* NP CR SO SI */ CASE_IGNORE, CASE_CR, CASE_IGNORE, CASE_IGNORE, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_BES_STATE, /* FS GS RS US */ CASE_PT_STATE, CASE_PLT_STATE, CASE_IPL_STATE, CASE_ALP_STATE, /* SP ! " # */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* $ % & ' */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ( ) * + */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* , - . / */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0 1 2 3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 4 5 6 7 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 8 9 : ; */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* < = > ? */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* @ A B C */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* D E F G */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* H I J K */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* L M N O */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* P Q R S */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* T U V W */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* X Y Z [ */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* \ ] ^ _ */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ` a b c */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* d e f g */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* h i j k */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* l m n o */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* p q r s */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* t u v w */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* x y z { */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* | } ~ DEL */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x99 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Adiaeresis Aring AE Ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Eth Ntilde Ograve Oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Udiaeresis Yacute Thorn ssharp */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* agrave aacute acircumflex atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* adiaeresis aring ae ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* egrave eacute ecircumflex ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* igrave iacute icircumflex idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* eth ntilde ograve oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ocircumflex otilde odiaeresis division */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* oslash ugrave uacute ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* udiaeresis yacute thorn ydiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, }; const int Tesctable[] = /* ESC */ { /* NUL SOH STX ETX */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_VT_MODE, /* EOT ENQ ACK BEL */ CASE_CURSTATE, CASE_REPORT, CASE_CURSTATE, CASE_BEL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_IGNORE, CASE_UP, /* NP CR SO SI */ CASE_PAGE, CASE_IGNORE, CASE_APL, CASE_ASCII, /* DLE DC1 DC2 DC3 */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* DC4 NAK SYN ETB */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_COPY, /* CAN EM SUB ESC */ CASE_BYP_STATE, CASE_CURSTATE, CASE_GIN, CASE_IGNORE, /* FS GS RS US */ CASE_SPT_STATE, CASE_PLT_STATE, CASE_IPL_STATE, CASE_ALP_STATE, /* SP ! " # */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* $ % & ' */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* ( ) * + */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* , - . / */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* 0 1 2 3 */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* 4 5 6 7 */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* 8 9 : ; */ CASE_CHAR_SIZE, CASE_CHAR_SIZE, CASE_CHAR_SIZE, CASE_CHAR_SIZE, /* < = > ? */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* @ A B C */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* D E F G */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* H I J K */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* L M N O */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* P Q R S */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* T U V W */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* X Y Z [ */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* \ ] ^ _ */ CASE_CURSTATE, CASE_OSC, CASE_CURSTATE, CASE_CURSTATE, /* ` a b c */ CASE_BEAM_VEC, CASE_BEAM_VEC, CASE_BEAM_VEC, CASE_BEAM_VEC, /* d e f g */ CASE_BEAM_VEC, CASE_CURSTATE, CASE_CURSTATE, CASE_BEAM_VEC, /* h i j k */ CASE_BEAM_VEC, CASE_BEAM_VEC, CASE_BEAM_VEC, CASE_BEAM_VEC, /* l m n o */ CASE_BEAM_VEC, CASE_CURSTATE, CASE_CURSTATE, CASE_BEAM_VEC, /* p q r s */ CASE_BEAM_VEC, CASE_BEAM_VEC, CASE_BEAM_VEC, CASE_BEAM_VEC, /* t u v w */ CASE_BEAM_VEC, CASE_CURSTATE, CASE_CURSTATE, CASE_BEAM_VEC, /* x y z { */ CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, CASE_CURSTATE, /* | } ~ DEL */ CASE_CURSTATE, CASE_CURSTATE, CASE_IGNORE, CASE_CURSTATE, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x99 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Adiaeresis Aring AE Ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Eth Ntilde Ograve Oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Udiaeresis Yacute Thorn ssharp */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* agrave aacute acircumflex atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* adiaeresis aring ae ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* egrave eacute ecircumflex ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* igrave iacute icircumflex idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* eth ntilde ograve oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ocircumflex otilde odiaeresis division */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* oslash ugrave uacute ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* udiaeresis yacute thorn ydiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, }; const int Tipltable[] = /* RS (^^) incremental plot */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_BEL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_LF, CASE_UP, /* NP CR SO SI */ CASE_IGNORE, CASE_CR, CASE_IGNORE, CASE_IGNORE, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_ESC_STATE, /* FS GS RS US */ CASE_PT_STATE, CASE_PLT_STATE, CASE_IPL_STATE, CASE_ALP_STATE, /* SP ! " # */ CASE_PENUP, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* $ % & ' */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ( ) * + */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* , - . / */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0 1 2 3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 4 5 6 7 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 8 9 : ; */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* < = > ? */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* @ A B C */ CASE_IGNORE, CASE_IPL_POINT, CASE_IPL_POINT, CASE_IGNORE, /* D E F G */ CASE_IPL_POINT, CASE_IPL_POINT, CASE_IPL_POINT, CASE_IGNORE, /* H I J K */ CASE_IPL_POINT, CASE_IPL_POINT, CASE_IPL_POINT, CASE_IGNORE, /* L M N O */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* P Q R S */ CASE_PENDOWN, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* T U V W */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* X Y Z [ */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* \ ] ^ _ */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ` a b c */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* d e f g */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* h i j k */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* l m n o */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* p q r s */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* t u v w */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* x y z { */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* | } ~ DEL */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x99 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Adiaeresis Aring AE Ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Eth Ntilde Ograve Oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Udiaeresis Yacute Thorn ssharp */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* agrave aacute acircumflex atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* adiaeresis aring ae ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* egrave eacute ecircumflex ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* igrave iacute icircumflex idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* eth ntilde ograve oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ocircumflex otilde odiaeresis division */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* oslash ugrave uacute ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* udiaeresis yacute thorn ydiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, }; const int Tplttable[] = /* GS (^]) graph (plot) mode */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_BEL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_LF, CASE_UP, /* NP CR SO SI */ CASE_IGNORE, CASE_CR, CASE_IGNORE, CASE_IGNORE, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_ESC_STATE, /* FS GS RS US */ CASE_PT_STATE, CASE_PLT_STATE, CASE_IPL_STATE, CASE_ALP_STATE, /* SP ! " # */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* $ % & ' */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* ( ) * + */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* , - . / */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* 0 1 2 3 */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* 4 5 6 7 */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* 8 9 : ; */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* < = > ? */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* @ A B C */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* D E F G */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* H I J K */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* L M N O */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* P Q R S */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* T U V W */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* X Y Z [ */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* \ ] ^ _ */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* ` a b c */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* d e f g */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* h i j k */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* l m n o */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* p q r s */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* t u v w */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* x y z { */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* | } ~ DEL */ CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, CASE_PLT_VEC, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x99 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Adiaeresis Aring AE Ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Eth Ntilde Ograve Oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Udiaeresis Yacute Thorn ssharp */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* agrave aacute acircumflex atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* adiaeresis aring ae ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* egrave eacute ecircumflex ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* igrave iacute icircumflex idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* eth ntilde ograve oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ocircumflex otilde odiaeresis division */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* oslash ugrave uacute ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* udiaeresis yacute thorn ydiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, }; const int Tpttable[] = /* FS (^\) point plot mode */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_BEL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_LF, CASE_UP, /* NP CR SO SI */ CASE_IGNORE, CASE_CR, CASE_IGNORE, CASE_IGNORE, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_ESC_STATE, /* FS GS RS US */ CASE_PT_STATE, CASE_PLT_STATE, CASE_IPL_STATE, CASE_ALP_STATE, /* SP ! " # */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* $ % & ' */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* ( ) * + */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* , - . / */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* 0 1 2 3 */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* 4 5 6 7 */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* 8 9 : ; */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* < = > ? */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* @ A B C */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* D E F G */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* H I J K */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* L M N O */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* P Q R S */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* T U V W */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* X Y Z [ */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* \ ] ^ _ */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* ` a b c */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* d e f g */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* h i j k */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* l m n o */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* p q r s */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* t u v w */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* x y z { */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* | } ~ DEL */ CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, CASE_PT_POINT, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x99 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Adiaeresis Aring AE Ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Eth Ntilde Ograve Oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Udiaeresis Yacute Thorn ssharp */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* agrave aacute acircumflex atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* adiaeresis aring ae ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* egrave eacute ecircumflex ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* igrave iacute icircumflex idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* eth ntilde ograve oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ocircumflex otilde odiaeresis division */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* oslash ugrave uacute ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* udiaeresis yacute thorn ydiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, }; const int Tspttable[] = /* ESC FS (^\) special point plot */ { /* NUL SOH STX ETX */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* EOT ENQ ACK BEL */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_BEL, /* BS HT NL VT */ CASE_BS, CASE_TAB, CASE_LF, CASE_UP, /* NP CR SO SI */ CASE_IGNORE, CASE_CR, CASE_IGNORE, CASE_IGNORE, /* DLE DC1 DC2 DC3 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* DC4 NAK SYN ETB */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* CAN EM SUB ESC */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_ESC_STATE, /* FS GS RS US */ CASE_PT_STATE, CASE_PLT_STATE, CASE_IPL_STATE, CASE_ALP_STATE, /* SP ! " # */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* $ % & ' */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* ( ) * + */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* , - . / */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* 0 1 2 3 */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* 4 5 6 7 */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* 8 9 : ; */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* < = > ? */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* @ A B C */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* D E F G */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* H I J K */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* L M N O */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* P Q R S */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* T U V W */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* X Y Z [ */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* \ ] ^ _ */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* ` a b c */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* d e f g */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* h i j k */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* l m n o */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* p q r s */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* t u v w */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* x y z { */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* | } ~ DEL */ CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, CASE_SPT_POINT, /* 0x80 0x81 0x82 0x83 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x84 0x85 0x86 0x87 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x88 0x89 0x8a 0x8b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x8c 0x8d 0x8e 0x8f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x90 0x91 0x92 0x93 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x94 0x95 0x96 0x97 */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x99 0x99 0x9a 0x9b */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* 0x9c 0x9d 0x9e 0x9f */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* nobreakspace exclamdown cent sterling */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* currency yen brokenbar section */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* diaeresis copyright ordfeminine guillemotleft */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* notsign hyphen registered macron */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* degree plusminus twosuperior threesuperior */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* acute mu paragraph periodcentered */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* cedilla onesuperior masculine guillemotright */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* onequarter onehalf threequarters questiondown */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Agrave Aacute Acircumflex Atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Adiaeresis Aring AE Ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Egrave Eacute Ecircumflex Ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Igrave Iacute Icircumflex Idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Eth Ntilde Ograve Oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ocircumflex Otilde Odiaeresis multiply */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Ooblique Ugrave Uacute Ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* Udiaeresis Yacute Thorn ssharp */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* agrave aacute acircumflex atilde */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* adiaeresis aring ae ccedilla */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* egrave eacute ecircumflex ediaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* igrave iacute icircumflex idiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* eth ntilde ograve oacute */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* ocircumflex otilde odiaeresis division */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* oslash ugrave uacute ucircumflex */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* udiaeresis yacute thorn ydiaeresis */ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, }; /* *INDENT-ON* */ xterm-399/icons/0000755000000000000000000000000014763041146012356 5ustar rootrootxterm-399/icons/mini.xterm.svg0000644000000000000000000001154113642720773015200 0ustar rootroot image/svg+xml XTerm mini-icon August 21, 2012 Thomas E. Dickey https://invisible-island.net/xterm/xterm.icon.html https://invisible-island.net/xterm/images/mini.xterm_256.png X T xterm-399/icons/filled-xterm.xpms0000644000000000000000000004177414763041146015700 0ustar rootroot/* $XTermId: filled-xterm.xpms,v 1.2 2025/03/08 13:13:10 tom Exp $ */ /* generated by ./make-xpms */ /* vile:xpmmode */ /* XPM */ static const char * const filled_xterm_16x16_xpm[] = { "16 16 110 2", " c None", ". c #BAA9A9", "+ c #C59C9C", "@ c #C49999", "# c #C6AAAA", "$ c #4D4242", "% c #F0E4E4", "& c #CEBABA", "* c #D5BEBE", "= c #C6B5B5", "- c #CEBEBE", "; c #796D6D", "> c #DEC5C5", ", c #B19B9B", "' c #C6B8B8", ") c #B19696", "! c #EBE5E5", "~ c #FFFFFF", "{ c #D6D6D6", "] c #D0BDBD", "^ c #FFF4F4", "/ c #FEFDFD", "( c #706969", "_ c #CCC3C3", ": c #FFF0F0", "< c #978989", "[ c #A9A5A5", "} c #A7A3A3", "| c #E3E1E1", "1 c #DACBCB", "2 c #DEDEDE", "3 c #FFF8F8", "4 c #FFF6F6", "5 c #FFFCFC", "6 c #FFFEFE", "7 c #D2D2D2", "8 c #9C9C9C", "9 c #9B8787", "0 c #B3A0A0", "a c #FFD5D5", "b c #D4C2C2", "c c #FFE7E7", "d c #7A6F6F", "e c #786F6F", "f c #C2C2C2", "g c #B4B4B4", "h c #FFE3E3", "i c #E1CECE", "j c #FED8D8", "k c #908888", "l c #878080", "m c #898383", "n c #F3ECEC", "o c #D8C2C2", "p c #FFFAFA", "q c #FFF2F2", "r c #FFF9F9", "s c #EFEFEF", "t c #FEFEFE", "u c #C8C3C3", "v c #D2BFBF", "w c #8A8383", "x c #FCE5E5", "y c #D9B6B6", "z c #DDBCBC", "A c #BCA0A0", "B c #F0D2D2", "C c #AB9C9C", "D c #000000", "E c #B0A2A2", "F c #AE9F9F", "G c #C6ABAB", "H c #B48E8E", "I c #C8ABAB", "J c #C39A9A", "K c #D0B2B2", "L c #C3A0A0", "M c #CFB2B2", "N c #C59999", "O c #CCC1C1", "P c #3C3535", "Q c #A39C9C", "R c #FAEDED", "S c #FEFCFC", "T c #F9F2F2", "U c #FEF7F7", "V c #FAEBEB", "W c #FEFAFA", "X c #F9F1F1", "Y c #FEF4F4", "Z c #FAEFEF", "` c #EBE0E0", " . c #DFB9B9", ".. c #E8E3E3", "+. c #BBB0B0", "@. c #BBA9A9", "#. c #CEC8C8", "$. c #BCADAD", "%. c #CDC8C8", "&. c #C78D8D", "*. c #E3B2B2", "=. c #E3BCBC", "-. c #BBAAAA", ";. c #746C6C", ">. c #858585", ",. c #8A7F7F", "'. c #977878", "). c #A38686", "!. c #A78686", "~. c #201717", " . + @ @ @ @ @ @ @ @ # $ ", " % & * * * * * * * * = - ; ", " > , ' ) ! ~ ~ ~ ~ ~ { ] ^ ", " > / ( _ ~ ~ ~ ~ ~ ~ { ] : ", " > ~ < [ ~ ~ ~ ~ ~ ~ { ] : ", " > } | 1 2 ~ ~ ~ ~ ~ { ] : ", " > ~ ~ 3 ~ 4 4 5 6 4 7 ] : ", " > 7 8 9 0 a b c d e f ] : ", " > ~ g h i j k c l m f ] n ", " o ~ ~ p ~ q 6 r s t u v w ", " x y z z z z z z A z B C ", " D ", " E F G H I J K L M N O P ", " Q R S T U V W X Y Z U ` Q ", " ...+._ @.#.$.%.&.*.=.-.;. ", " >.>.>.,.'.).).).).).!.~. "}; /* XPM */ static const char * const filled_xterm_32x32_xpm[] = { "32 32 225 2", " c None", ". c #000000", "+ c #D9C2C2", "@ c #EEE5E5", "# c #EBE0E0", "$ c #EBE1E1", "% c #EDE1E1", "& c #918484", "* c #FFEEEE", "= c #F2DCDC", "- c #403838", "; c #5A5A5A", "> c #5B4545", ", c #FEF2F2", "' c #E9E9E9", ") c #856868", "! c #271D1D", "~ c #FBCFCF", "{ c #746060", "] c #FFFBFB", "^ c #FFFFFF", "/ c #FAF0F0", "( c #5E4949", "_ c #E3DCDC", ": c #BAA8A8", "< c #292020", "[ c #F1C0C0", "} c #D9C6C6", "| c #FFECEC", "1 c #FFE8E8", "2 c #FFFAFA", "3 c #FFF0F0", "4 c #FFEFEF", "5 c #705D5D", "6 c #DED5D5", "7 c #F9E6E6", "8 c #D3C3C3", "9 c #392F2F", "0 c #FCF6F6", "a c #BAA7A7", "b c #524646", "c c #D9D1D1", "d c #F2EAEA", "e c #796666", "f c #FEF7F7", "g c #BBAAAA", "h c #918383", "i c #1D1515", "j c #EBDADA", "k c #B5B5B5", "l c #FFF4F4", "m c #DDD0D0", "n c #110A0A", "o c #FEFBFB", "p c #D3C7C7", "q c #FFF3F3", "r c #968484", "s c #F2E9E9", "t c #908484", "u c #FFFDFD", "v c #A89191", "w c #776262", "x c #CCB4B4", "y c #9E7979", "z c #705F5F", "A c #FFCCCC", "B c #FFEAEA", "C c #FFE6E6", "D c #FFF1F1", "E c #FFFEFE", "F c #FFE1E1", "G c #FFF2F2", "H c #FFF7F7", "I c #C7B8B8", "J c #AE9494", "K c #5A4848", "L c #C0AFAF", "M c #D1BDBD", "N c #4F3D3D", "O c #513636", "P c #BCB0B0", "Q c #665757", "R c #1A0C0C", "S c #E4DCDC", "T c #FCF3F3", "U c #1F0C0C", "V c #C3C3C3", "W c #726363", "X c #443A3A", "Y c #FFF8F8", "Z c #583D3D", "` c #FCF4F4", " . c #615757", ".. c #6C5656", "+. c #A09393", "@. c #9B8E8E", "#. c #856464", "$. c #4A3F3F", "%. c #BBBBBB", "&. c #C0BCBC", "*. c #452F2F", "=. c #736C6C", "-. c #775656", ";. c #878787", ">. c #A38888", ",. c #624D4D", "'. c #C9B4B4", "). c #F8F0F0", "!. c #FFEDED", "~. c #604242", "{. c #B5A8A8", "]. c #FAE9E9", "^. c #FBF3F3", "/. c #BAB2B2", "(. c #F8DEDE", "_. c #7F6F6F", ":. c #B5A2A2", "<. c #806F6F", "[. c #AA8E8E", "}. c #FEFDFD", "|. c #BD9F9F", "1. c #C3B4B4", "2. c #E0DCDC", "3. c #F9EEEE", "4. c #080303", "5. c #F3C1C1", "6. c #B7A2A2", "7. c #4C3A3A", "8. c #DFD6D6", "9. c #7E6D6D", "0. c #FFE9E9", "a. c #B39A9A", "b. c #BBA5A5", "c. c #DEC9C9", "d. c #715D5D", "e. c #F3DDDD", "f. c #8B7979", "g. c #060303", "h. c #FFEBEB", "i. c #EFE9E9", "j. c #EAEAEA", "k. c #FAEFEF", "l. c #D1C3C3", "m. c #0B0707", "n. c #312222", "o. c #584141", "p. c #685252", "q. c #5D5858", "r. c #5F5F5F", "s. c #5B5B5B", "t. c #5C5858", "u. c #473232", "v. c #181111", "w. c #ECD8D8", "x. c #F9EFEF", "y. c #DBC6C6", "z. c #DEC5C5", "A. c #F7EDED", "B. c #DCC4C4", "C. c #F8EDED", "D. c #DEC3C3", "E. c #E0C9C9", "F. c #DEC1C1", "G. c #DBC7C7", "H. c #F7E8E8", "I. c #E1CACA", "J. c #DBC2C2", "K. c #F8EFEF", "L. c #796868", "M. c #422B2B", "N. c #B5A3A3", "O. c #F8ECEC", "P. c #F8EEEE", "Q. c #FDF7F7", "R. c #FEF9F9", "S. c #F7EAEA", "T. c #FDF6F6", "U. c #F7EBEB", "V. c #FDF5F5", "W. c #F7EEEE", "X. c #F8EBEB", "Y. c #786565", "Z. c #2C2121", "`. c #F6E9E9", " + c #F6E8E8", ".+ c #F9EDED", "++ c #FEFCFC", "@+ c #F7ECEC", "#+ c #F7E9E9", "$+ c #837070", "%+ c #806C6C", "&+ c #D4C3C3", "*+ c #DCC8C8", "=+ c #DDC2C2", "-+ c #DBBFBF", ";+ c #E1C8C8", ">+ c #DEC8C8", ",+ c #DEC7C7", "'+ c #DFC8C8", ")+ c #DEBBBB", "!+ c #FAEEEE", "~+ c #221B1B", "{+ c #3E3131", "]+ c #F8E8E8", "^+ c #8D8181", "/+ c #F6E7E7", "(+ c #696969", "_+ c #6D6D6D", ":+ c #6F6C6C", "<+ c #835D5D", "[+ c #875D5D", "}+ c #9D7474", "|+ c #A27A7A", "1+ c #958989", "2+ c #919191", "3+ c #9D9797", "4+ c #917E7E", "5+ c #E3C8C8", "6+ c #241B1B", "7+ c #695959", "8+ c #CEBCBC", "9+ c #D1D1D1", "0+ c #CFCBCB", "a+ c #322424", "b+ c #201818", " ", " . + @ # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % @ & . ", " . * = - ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; > , ' ) ! ", " . ~ { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ / ( _ : / < ", " . [ } | 1 1 2 3 1 4 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 : ^ 7 . ", " . [ } 8 9 0 a b * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 : ^ 4 . ", " . [ } ^ c d e f ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 g ^ 4 . ", " . [ } ^ ^ h i j ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 k ^ l . ", " . [ } ^ ^ m n | ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 k ^ ^ . ", " . [ } ^ o { p q ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 k ^ ^ . ", " . [ } ^ r s ^ t u ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 k ^ ^ . ", " . [ } v w x ^ y z A ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 : ^ ^ . ", " . [ } ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 : ^ ^ . ", " . [ } B C C C D C C C E F G G ^ l C ^ ^ H ] 5 6 : ^ ^ . ", " . [ } I J K L M N L L E O P Q l B R S T U V 5 6 : ^ ^ . ", " . [ } ^ * W ^ * X ^ Y ^ Z ` .q B ..+.@.#.V 5 6 : ^ ^ . ", " . [ } ^ * W ^ * $.%.&.^ *.=.-.u B ;.>.,.'.V 5 6 : ^ ).. ", " . [ } ^ * W ^ * ,.!.!.E ~.^ {.].B ;.^./.(.V 5 6 : ^ _. ", " . [ } ^ q :.^ l <.<.<.E [.^ }.|.3 1.^ ^ B 2.5 6 : 3.4. ", " . 5.6.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ] 7.8.: 9. ", " . 0.a.b.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.d.e.' f.g. ", " . h.2 i.j.j.j.j.j.j.j.j.j.j.j.j.j.j.j.j.j.k.^ l.m. ", " . . . . . . . . . . . . . . . . . . . . . . . ", " ", " n.o.p.p.p.p.q.; r.s.; ; ; t.p.p.p.p.p.p.p.p.u.. ", " v.w.x.y.z.A.3.} B.C.3.D.E.C.C.F.G.C.H.I.J.C.K.L.M. ", " N.O.P.Q.R.S.S.f T.U.S.V.f W.A.Q.Q.P.P.Q.f O.X._.Y. ", " Z.Y `. +V.f .+A.T.Q.O..+++V.K.@+f f #+A.R.V.`.$+x.%+ ", " &+B.X.).*+=+C.#+-+;+C.O.>+,+U.#+'+)+@+#+F.*+!+9.k.~+ ", " {+]+^+/+(+_+_+_+_+_+_+_+_+:+<+[+}+|+1+2+3+S.^+4+5+6+ ", " 7+8+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+0+a+b+ ", " "}; /* XPM */ static const char * const filled_xterm_48x48_xpm[] = { "48 48 246 2", " c None", ". c #000000", "+ c #F6D5D5", "@ c #FFEAEA", "# c #FFD6D6", "$ c #FFD2D2", "% c #FFD3D3", "& c #F8D6D6", "* c #FFEFEF", "= c #FFFFFF", "- c #F6DBDB", "; c #0F0707", "> c #090505", ", c #F6DCDC", "' c #FFEEEE", ") c #C99999", "! c #030101", "~ c #F7DEDE", "{ c #150B0B", "] c #E3C5C5", "^ c #FFEDED", "/ c #E4CBCB", "( c #140B0B", "_ c #F7DDDD", ": c #E0C9C9", "< c #080303", "[ c #FFD9D9", "} c #0D0707", "| c #E5CACA", "1 c #E5CBCB", "2 c #0B0606", "3 c #FFDCDC", "4 c #E2CECE", "5 c #090303", "6 c #E1CBCB", "7 c #9F8A8A", "8 c #3B2929", "9 c #312020", "0 c #FFD5D5", "a c #ECC8C8", "b c #402525", "c c #351F1F", "d c #663E3E", "e c #E6DBDB", "f c #FFFAFA", "g c #FFFEFE", "h c #8C7272", "i c #B4A1A1", "j c #A69494", "k c #D8C0C0", "l c #675353", "m c #FFFDFD", "n c #584545", "o c #E1BFBF", "p c #3C2929", "q c #FCF3F3", "r c #F6EAEA", "s c #160F0F", "t c #E9D3D3", "u c #6E5C5C", "v c #D6BABA", "w c #CBBBBB", "x c #0D0808", "y c #F8E8E8", "z c #FFE2E2", "A c #F4EDED", "B c #FFF2F2", "C c #4B3A3A", "D c #FFFBFB", "E c #AD9292", "F c #FFE1E1", "G c #A28E8E", "H c #CCBDBD", "I c #8B7777", "J c #231515", "K c #ECCECE", "L c #FFDADA", "M c #251414", "N c #9A8686", "O c #FFF1F1", "P c #FFECEC", "Q c #FFE4E4", "R c #FFDFDF", "S c #FFDBDB", "T c #FFF0F0", "U c #FFDDDD", "V c #FFEBEB", "W c #FFF4F4", "X c #FFE5E5", "Y c #FFDEDE", "Z c #B29E9E", "` c #A08F8F", " . c #8A7373", ".. c #1C1111", "+. c #D7CACA", "@. c #645555", "#. c #5E4B4B", "$. c #FFF7F7", "%. c #BD9F9F", "&. c #392B2B", "*. c #A19090", "=. c #867474", "-. c #9C8D8D", ";. c #A99494", ">. c #0E0606", ",. c #FFE9E9", "'. c #D5C6C6", "). c #564545", "!. c #FFE7E7", "~. c #5B3D3D", "{. c #352121", "]. c #5B4242", "^. c #FFD7D7", "/. c #E7D2D2", "(. c #1F1313", "_. c #786363", ":. c #AC9191", "<. c #FFE8E8", "[. c #DBC7C7", "}. c #897474", "|. c #574E4E", "1. c #999999", "2. c #FFF6F6", "3. c #170F0F", "4. c #3B2B2B", "5. c #190E0E", "6. c #C7B6B6", "7. c #5F4D4D", "8. c #F6E1E1", "9. c #FCE9E9", "0. c #F1EAEA", "a. c #FEFAFA", "b. c #3D2828", "c. c #382626", "d. c #947D7D", "e. c #FFFCFC", "f. c #B09B9B", "g. c #C2B2B2", "h. c #EEDADA", "i. c #FDEFEF", "j. c #0B0505", "k. c #DACACA", "l. c #7D6565", "m. c #C6A7A7", "n. c #FDF9F9", "o. c #6C4D4D", "p. c #AB9797", "q. c #927B7B", "r. c #FCEDED", "s. c #0A0404", "t. c #120B0B", "u. c #E8D1D1", "v. c #E2CACA", "w. c #0F0808", "x. c #907979", "y. c #F9DFDF", "z. c #1D1111", "A. c #E8D0D0", "B. c #E1C8C8", "C. c #1A0C0C", "D. c #F8E0E0", "E. c #F7D4D4", "F. c #090404", "G. c #FAE1E1", "H. c #100A0A", "I. c #100808", "J. c #7C4F4F", "K. c #F6D3D3", "L. c #FFD8D8", "M. c #F8D5D5", "N. c #AF9393", "O. c #FDE5E5", "P. c #FDE9E9", "Q. c #FDE2E2", "R. c #FDF8F8", "S. c #FDE6E6", "T. c #FEECEC", "U. c #FEE5E5", "V. c #FFE6E6", "W. c #F8D1D1", "X. c #0D0404", "Y. c #291D1D", "Z. c #583030", "`. c #FFF8F8", " + c #683737", ".+ c #5B3333", "++ c #582D2D", "@+ c #593030", "#+ c #5D3232", "$+ c #5A2D2D", "%+ c #663737", "&+ c #5B3030", "*+ c #897272", "=+ c #996F6F", "-+ c #DBC1C1", ";+ c #110808", ">+ c #FDDDDD", ",+ c #473636", "'+ c #563232", ")+ c #FFF5F5", "!+ c #5C3636", "~+ c #FFF9F9", "{+ c #582E2E", "]+ c #6F4040", "^+ c #5B3434", "/+ c #6D3E3E", "(+ c #5A3333", "_+ c #EFD7D7", ":+ c #FCEFEF", "<+ c #140A0A", "[+ c #6A5252", "}+ c #583333", "|+ c #5C2A2A", "1+ c #653737", "2+ c #6B3C3C", "3+ c #643434", "4+ c #6A3C3C", "5+ c #613535", "6+ c #9C8787", "7+ c #907A7A", "8+ c #DDC3C3", "9+ c #F8E5E5", "0+ c #FDF3F3", "a+ c #190D0D", "b+ c #FAEAEA", "c+ c #DCC4C4", "d+ c #876E6E", "e+ c #461F1F", "f+ c #472020", "g+ c #261414", "h+ c #070000", "i+ c #220000", "j+ c #230101", "k+ c #3A1818", "l+ c #3F1D1D", "m+ c #3E1E1E", "n+ c #553333", "o+ c #724646", "p+ c #431F1F", "q+ c #AB8F8F", "r+ c #887171", "s+ c #DAC0C0", "t+ c #FBD1D1", "u+ c #1A1010", "v+ c #B27C7C", "w+ c #020101", " ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . + @ @ # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % @ @ & . . ", " . * = - ; . . . . . . . . . . . . . . . . . . . . . . . . . . > , = ' . ) ! ", " . * ~ { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ / ( _ ' . ^ : < ", " . [ } | = = = = = = = = = = = = = = = = = = = = = = = = = = = = 1 2 3 . ^ = 4 5 ", " . [ . * = = = = = = = = = = = = = = = = = = = = = = = = = = = = * . [ . ^ = = 6 . ", " . [ . * 7 8 9 0 = a b c d = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = e f = g h i = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = j = k l g = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = m n o p q = = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = = r s . t = = = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = = = u . v = = = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = = w x y = = = = = = = = = = = = = = = = = = = = * . [ . z = = * . ", " . [ . * = = A B B C D = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = E z = = F G = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * H I J K = = L M } N O = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * P Q Q R = = S Q Q Q T = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = = = = = = = = = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = = = = = = = = = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * [ U U U U U V z U U U U W X Y X ^ = = V U O = = O F ' * . [ . ' = = * . ", " . [ . * Z ` ...` Q +.@.#.` ` Q $.%.&.*.=. ^ = -. = = ;.>.,.* . [ . ' = = * . ", " . [ . * = = '. = = = Q = = = = %. = = ).!.= -.~. f f {.].,.* . [ . ' = = * . ", " . [ . * = = '. = = = U U ^.= %. ^ /.(.' = -._.:.<.[.}.@.,.* . [ . ' = = * . ", " . [ . * = = '. = = = @.|.1.1.2.= %.3.4.5. = = -. 6. 7.8.@.,.* . [ . ' = = 9.. ", " . [ . * = = '. = = = Q = = = = %. = 0. ' = -. a.b.c.f @.,.* . [ . ' = = d.. ", " . [ . * = = '. = = = 0 ^ ^ ^ e.%. = = f. m -. = g.h.= @.,.* . [ . ' = i.j. ", " . [ . * = = k. = = = l.9 9 9 ' m. = = n.o.z p. = = = = l.X * . [ . ' = q.. ", " . [ . * = = = = = = = = = = = = = = = = = = = = = = = = = = = = * . [ . ' r.s. ", " . 3 t.u.= = = = = = = = = = = = = = = = = = = = = = = = = = = = v.w.S . ' x.. ", " . * y.z.A.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ B.C.D.' . E.F. ", " . * = G.H.. . . . . . . . . . . . . . . . . . . . . . . . . . I.D.= ' . J.. ", " . K.P P # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ L.P P M.. . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " ", " ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . N.O.P.O.P.Q.R.S.P.O.P.O.P.O.T.U.T.U.T.,.^ ,.^ ,.^ V.^ ,.= D W ,.^ W.X.. ", " Y.W Z.`. +e..+e.++D @+$.Z.`. +e.#+e.$+D @+$.Z.`.%+e.#+e.$+e.&+$.Z.D *+=+. ", " . -+D f e.m D `.= D e.D D f D m D `.= D e.D D f D m D `.= D e.D D f r.;+>+. ", " ,+`.'+)+!+~+{+= ]+f .+`.Z.)+^+~+{+= /+f .+`.Z.)+^+~+{+= /+f (+`.Z.f q.q.T . ", " . _+m f = D m ~+e.`.m f m f = D m ~+e.`.m f e.f = D m ~+e.`.m f m f :+<+i.T . ", " . [+~+}+)+|+~+1+g 2+g 3+`.}+)+|+~+1+g 4+= 3+`.}+)+|+~+1+g 4+= 3+~+5+e.6+7+= 8+. ", " ! 9+= ~+= T ' @ ' ,.' <.' <.' ' ' @ e.f = ~+= ~+= = = D = f = ~+= = 0+a+b+c+! ", " . d+m e+f+e.g+. . . . . . . . . . . . h+i+i+j+k+l+l+c m+l+l+n+o+e.e+p+q+r+s+! ", " . t+* @ @ P S [ L S S S S S S S S S S z ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ P z u+v+w+ ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " "}; static const XPM_DATA filled_xterm_xpms[] = { { "filled-xterm_16x16", filled_xterm_16x16_xpm }, { "filled-xterm_32x32", filled_xterm_32x32_xpm }, { "filled-xterm_48x48", filled_xterm_48x48_xpm } }; xterm-399/icons/filled-xterm.png0000644000000000000000000000444512034405232015454 0ustar rootroot‰PNG  IHDR00Wù‡sRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEÜ :ÅFÿ¯¥IDAThÞíY{PT×ÿÝ}åµò¢‘"‚Â*&Vâ+Æ™R8šdÒPŸSg¢ÓIF|TAÅiŒ‰¢u2M:m§­ÚÔˆFcí(fQ@(/eÙ]Ø{ï¹÷ë°[D…¥DÓ~3wv÷|¿9÷ûïqÎùøžÊ,ô”<³ú3”{Â8uÞ¹Óìhm%062KÇq@h(|k«UÜ£™ à+O§!²Ù$"¢ÎªªûþZ툭¸—ZMÕÕMDDdµº~ôè'JŽ»ÿ8opý6›%2>ž3ž?_?h¸{·4qÖ¬˜ºâbIÊéõ ‹¥ÌT]Ý3}z¼S’–{â ¢Š ÁW«¥†7®ÐKCaáU†¨ºš ²Xî™Æ¯¼”Êûå…‹€³Çö‘&@6›½Ç±7""SaáÅžp(Ú½›Èn¯i*OâÉð ß&N,Ýš™ ˆ¢o¯’«¼uëó^´SF:‰="€Q£ Ý£¢^{æªÐÓ&žy ²ò#¨TŒûù¥¢««¢XüÐxhèFØí-åÓE ´Z?èts ×ÇõÜðn¢½ý,‚‚Òáçho¯E[Û)øú.Ç=7¤G‰¿?Nù¹¹´oË  ¤üÜ\¢úúüò7hÝòå´&5•òssÝãÔÕõ àÄ z9.ŽN<(ï޺ի׿AK9ÑÇ99䬤êê_ºró³¼¼³~ QsóçÃVFï\»Fôé§qUŒŠŠuT_ o!)8q‚¨¤d…ë÷ŠyóÔØxÂE =%¥Œ?z4ž'Aà§Ž_‘>gΠ ¨†$Íæ‹àùv€ è“ °Û°Zk›lׯPhµîkiDt´é¯Nç[K­Ö¿Wß»¾léÒo«L¦èáÉ~dýŽÇð<椦ÞÌÈøK7:5õÏQáá¸[W×õû¬¬# ÜåÒ-ž;÷œ%™LéY»wþM^žã[·ø>I¬ü†ŒÀ±¬¬õðñ‰Åر›z†Ò\º¦«WŠÉ“?k¿?rKFFãV¯.B`à‹i¡ädß™ «DY.÷ ó¨$˜—W àC[Fív«µÍýH’üP± öùɲe9.¼YîŽ_Æ©ÕÜ®}ûVž;s& jµr ×ÈmmuÛöîM°ÿ¿ò€Z¥8î¡8ýUvö±3_~éþmܳ' óçŸóÒéFÃáw/X³Æòeë¿ôR¡¿·w²K—Ò}4O€°€€1_h4}ÿ‘ììêQ,Ðôlu%¬Ö:f±˜½U* €ÑžíÄJ¥Bïãƒf³ù_#½»ÖUUýu:@¡pßò²³«:Ëï»úývæ„¶6{TR’\xéRMhDDôHo®ª*zùÕWãï––BëçÄéõè*--Ô'&Nèb,Γðy¨7*˜L–oïëèt䬭½ß»7ºãõ×ÏÈ\wº¤¤É+,¬;ÞZZ$0F#? ‡  %ðÍÍ-º¸¸WgÇÓÕ¦þø¿|×ò¤˜  €mÞ¡à=\¶>‰Àßþtø°fá’% Rq`ŒƒJEày!!¬V‚R©p3F.§Õú€ç9hµ ð¼ ­VÁIA¥B/ RÁ¥cÝó2ð<‡Ž‚JÅñõõµÁCäÆôýØúˆ¼6)"â.9Ž´ÄD#9ÒÛÓ¦Ý&Æ(Ý`("Æ(->ÞH¢H+ÔÕÅúâ2’’nc´ê ¸7‡cŒÒ‹Ü8Q”~½yóù£6\öäãÞW]¾|™DQ&A bL&I"E™œÎî–(v‹"¹q¢8ŽzáäpÌb¹¨ÓY¤ššºÁX;?9¹ˆœNqERÒ7ÔÑA«““‹ˆç¥´„#цY³JIXºÁPDN§”–˜h¤ŽJŸ2å!\æ+¯” HžâVõÆ Ú¾½àÐöí©­<%à ÁV^~“$‰H\«#‘$ñ<#ƈœNÑ­÷ÇØ æc6[C··E²Ù̃!ðþ;K–\&ž§4ƒÁHÒêØØ"âyyý´i·I–éç3f“,Óº)Sn“ÓùDÜ;3f”Ñàpû^ˆ8-€±=zŽã”¡¡¡P«Õ*èT(àEŽˆ€eĨQÖœsçôóÇkåÛ7š7¬[×V[V¦˜4{vBÆ»<àÀ!Þ¾] ŠŒœQì¹)(›MYæÀqZpœÖ³mK øø þàGtv²± A¾ûîoíÚ5_Àx—ø?E·ÞÏôÿ‰³Ð¿Ž êè†ðNIEND®B`‚xterm-399/icons/mini.xterm_16x16.png0000644000000000000000000000133412034362166016021 0ustar rootroot‰PNG  IHDRóÿasRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEÜ ž@Å\IDAT8Ë“KH”qÅÿQqtЬ)+K©1mTÌ,í YHÐ ¥ˆ‚ÈAÑ"hÓº0µ‘.’ ˆˆ *" ¡"¤è¡fo±Ñïcü,gæ´p,ݽ~÷.×°˜sÄã& ! ›NóžtM¥™L6ñ¿‚éÄ X Ø©x.ª G+¼\¬‰ø%‚íŠážVb+‘S‚Dä2ÐaàÊÖýךZ?çÝïôûh_”±9§úù7å3j?SzÒz³63µ•¼‡¦V æ’Ú§z%n?Åc)q~Wh}Á æ>øJ’%¢ä/xÜ»:û¶cÒì~<–˜f¢F¾ß€£ß·1Í–+'PoMO¨Ó^Â*f8&»¿¯­·}¶|T€âðêðÚb×ÐÁ߀R§åƒ ‘Ìy*¦YehFÖ‡ ^[¯‹2ŒÛx™s-CÍc: ˜ÑJq×nzfåv ¯­CGj ÆgVØÙ®‘Æ”v0ÿ|‡ó´Ð2ZæÛÏf˜$¼˜ 7Ì$/Ž ¬k»S-"wŸ IA,s8EÀ º€è¹Á4r©ù/Ig+q¨ ¸<‘„€› -!ÿŸŸ öÐÍ-óŽÛ aèöÊ¡jRfÁTy8¦b,¥p8ª|ð*ùƒwH¶E²-wfß“U%w?~Ù—"-ÅQÅ‚$#8LUx€aàÐËuÓA)€b9K>•ô‘‰|zF>Ò²ÿ„h/ ¼ŠlXÌûÃŒ¦Ÿú‚¦½_IEND®B`‚xterm-399/icons/xterm_16x16.xpm0000644000000000000000000000062712034404343015104 0ustar rootroot/* XPM */ static char * xterm_16x16_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " . ", " .... . ", " .. . ", " .. . ", " .. . . ", " . ", " .... .. . ", " . . . .. . ", " . . ", " . . ", " . ", " . ", " ", " ", " . "}; xterm-399/icons/xterm-color_32x32.xpm0000644000000000000000000000410412034777553016226 0ustar rootroot/* XPM */ static char * xterm_color_32x32_xpm[] = { "32 32 60 1", ". c None", " c #FFFFFF", "+ c #000000", "@ c #EFEFEF", "# c #FEFEFE", "$ c #FBFBFB", "% c #F3F3F3", "& c #ADADAD", "* c #909090", "= c #737373", "- c #D2D2D2", "; c #646464", "> c #9A9A9A", ", c #8D8D8D", "' c #D3D3D3", ") c #0E0E0E", "! c #F6F6F6", "~ c #5E5E5E", "{ c #B1B1B1", "] c #777777", "^ c #949494", "/ c #757575", "( c #C4C4C4", "_ c #E7E7E7", ": c #F1F1F1", "< c #F8F8F8", "[ c #EEEEEE", "} c #F0F0F0", "| c #FAFAFA", "1 c #7B7B7B", "2 c #3D3D3D", "3 c #868686", "4 c #4F4F4F", "5 c #ABABAB", "6 c #545454", "7 c #5B5B5B", "8 c #AFAFAF", "9 c #292929", "0 c #181818", "a c #C7C7C7", "b c #CFCFCF", "c c #7F7F7F", "d c #A3A3A3", "e c #4D4D4D", "f c #6A6A6A", "g c #A1A1A1", "h c #8E8E8E", "i c #696969", "j c #474747", "k c #5A5A5A", "l c #959595", "m c #767676", "n c #8B8B8B", "o c #BCBCBC", "p c #BFBFBF", "q c #D7D7D7", "r c #404040", "s c #636363", "t c #989898", "u c #8A8A8A", "................................", ".....+++++++++++++++++++++++....", "....+..+++++++++++++++++++..++..", "....+.+...................+.+.+.", "....++.@#.$%................+..+", "....++.&*.=-................+..+", "....++..;>,.................+..+", "....++..')!.................+..+", "....++.#~{].................+..+", "....++.^{./(................+..+", "....++......................+..+", "....++......................+..+", "....++.____:___<_[..<}..[|..+..+", "....++.1;21341156]7.89$:0a..+..+", "....++..bc.8^__8d.e.8fghia..+..+", "....++..bc.84115jkl.887mna..+..+", "....++..bc.8d..8dof.88pqna..+..+", "....++..bc.8rss5d.tu88..na..+...", "....++......................+.+.", "....++......................+.+.", "....+.+...................+.++..", "....+..+++++++++++++++++++..+...", ".....+++++++++++++++++++++++....", "................................", ".....++++++++++++++++++++++++...", "....+.......................+...", "...+.......................+....", "...+..++..++.++..++..+..++.+....", "....++..++..+..++..++.++........", "..+.......................+.+...", ".+.......................+......", ".++++++++++++++++++++++++++....."}; xterm-399/icons/xterm_32x32.xpm0000644000000000000000000000232712034404307015077 0ustar rootroot/* XPM */ static char * xterm_32x32_xpm[] = { "32 32 2 1", " c None", ". c #000000", " ", " . .. ", " . ................... ... ", " . . ... . ", " . ... . ", " . .. ... ... . ", " . . . ... . ", " . .. ... . ", " . .. ... . ", " . .. ... . ", " . . . ... . ", " . ... .. ... . ", " . ... . ", " . ... . ", " . ........ ... .. ..... . ", " . . . . . ........ . ", " . . ... .. . . .... . ", " . . . . . . . .... . ", " . . ... . .. . .... . ", " . . .... ", " . . . ... ", " . .. ", " ....................... ", " ", " ........................ ", " . .. ", " .. ", " . . . ", " . . ", " . . ................. .. . ", " . .. ", " "}; xterm-399/icons/mini.xterm_16x16.xpm0000644000000000000000000000315312034362210016030 0ustar rootroot/* XPM */ static char * mini_xterm_16x16_xpm[] = { "16 16 84 1", " c None", ". c #FF3200", "+ c #FF3C00", "@ c #FF3F00", "# c #FF3B00", "$ c #FF3800", "% c #FF2000", "& c #FF1100", "* c #FF3D00", "= c #FF3900", "- c #FF2200", "; c #FF0A00", "> c #FF5D00", ", c #FF1300", "' c #FF0500", ") c #D0412F", "! c #DD6722", "~ c #DA3E25", "{ c #D84727", "] c #D03C2F", "^ c #0023F3", "/ c #000BF2", "( c #0E21E6", "_ c #4433B4", ": c #352EC3", "< c #0010F2", "[ c #0004F1", "} c #2C33CB", "| c #3E2ABA", "1 c #011EF3", "2 c #0012F3", "3 c #022DF5", "4 c #F2140D", "5 c #FF5E00", "6 c #052AF0", "7 c #0013F3", "8 c #DD4822", "9 c #002CF5", "0 c #004FF7", "a c #003AF6", "b c #1529E1", "c c #D83827", "d c #0037F7", "e c #004CF8", "f c #FF5900", "g c #182EDE", "h c #FF2100", "i c #152CE1", "j c #DD3B22", "k c #FF2300", "l c #FF2A00", "m c #0C28E9", "n c #E1571E", "o c #FF2E00", "p c #012AF4", "q c #E1661E", "r c #FF3600", "s c #FF3500", "t c #0028F4", "u c #0011F2", "v c #D64E29", "w c #FF5C00", "x c #FF2B00", "y c #FF1D00", "z c #FF2F00", "A c #000EF2", "B c #0003F1", "C c #8C4072", "D c #FF4C00", "E c #FF2D00", "F c #0360F6", "G c #0031F6", "H c #0016F3", "I c #0827EE", "J c #3D47BE", "K c #E5631A", "L c #FF4300", "M c #FF3E00", "N c #FF2400", "O c #FF0700", "P c #FF3400", "Q c #FF5700", "R c #FF5600", "S c #FF3700", " .+@#$% &$$*=- ", " ;>#, '+ ", " )!~ {] ", " ^/(_:<[}|1/2 ", " 2345=678 97 ", " 0a =>b7c de ", " fg7 ", " hg7 ", " $i7j ", " klm7no ", " # p7qr ", " sk tuvwx ", " yz ABCfDE ", " = FGHHIJKr ", " $LM$N O$PQRS- ", " "}; xterm-399/icons/xterm.xpms0000644000000000000000000001066314763041146014434 0ustar rootroot/* $XTermId: xterm.xpms,v 1.4 2025/03/08 13:13:10 tom Exp $ */ /* generated by ./make-xpms */ /* vile:xpmmode */ /* XPM */ static const char * const xterm_16x16_xpm[] = { "16 16 2 1", " c None", ". c #000000", " ", " . ", " .... . ", " .. . ", " .. . ", " .. . . ", " . ", " .... .. . ", " . . . .. . ", " . . ", " . . ", " . ", " . ", " ", " ", " . "}; /* XPM */ static const char * const xterm_32x32_xpm[] = { "32 32 2 1", " c None", ". c #000000", " ", " . .. ", " . ................... ... ", " . . ... . ", " . ... . ", " . .. ... ... . ", " . . . ... . ", " . .. ... . ", " . .. ... . ", " . .. ... . ", " . . . ... . ", " . ... .. ... . ", " . ... . ", " . ... . ", " . ........ ... .. ..... . ", " . . . . . ........ . ", " . . ... .. . . .... . ", " . . . . . . . .... . ", " . . ... . .. . .... . ", " . . .... ", " . . . ... ", " . .. ", " ....................... ", " ", " ........................ ", " . .. ", " .. ", " . . . ", " . . ", " . . ................. .. . ", " . .. ", " "}; /* XPM */ static const char * const xterm_48x48_xpm[] = { "48 48 2 1", " c None", ". c #000000", " ", " .................................. ", " . .. ", " . ............................ . . ", " . . . . . ", " . . . . . ", " . . . . . ", " . . ... ... . . . ", " . . . . . . . ", " . . . . . . . ", " . . . . . . . ", " . . .. . . . ", " . . .. . . . ", " . . . . . . . ", " . . . . . . . ", " . . . . . . . ", " . . ... ... . . . ", " . . . . . ", " . . . . . ", " . . . . . ", " . . . . . ", " . . ..... ..... .... . . . . . ", " . . . . . . .. .. . . . ", " . . . . . . .. .. . . . ", " . . . ..... .... . . . . . . . ", " . . . . . . . ... . . . .. ", " . . . . . . . . . . . . ", " . . . ..... . . . . . . .. ", " . . . . . ", " . . . . .. ", " . . . . . ", " . ............................ ... ", " . .. ", " .................................. ", " ", " ", " .................................... ", " . .. ", " . . . . . . . . . . . . . . . . . ... ", " . . . ", " . . . . . . . . . . . . . . . . . .. . ", " . . . ", " .. . . . . . . . . . . . . . . . . .. . ", " . . . ", " .. .. .......................... .... . ", " . . . ", " ..................................... ", " "}; static const XPM_DATA xterm_xpms[] = { { "xterm_16x16", xterm_16x16_xpm }, { "xterm_32x32", xterm_32x32_xpm }, { "xterm_48x48", xterm_48x48_xpm } }; xterm-399/icons/filled-xterm_32x32.xpm0000644000000000000000000001332212034404160016326 0ustar rootroot/* XPM */ static char * filled_xterm_32x32_xpm[] = { "32 32 225 2", " c None", ". c #000000", "+ c #D9C2C2", "@ c #EEE5E5", "# c #EBE0E0", "$ c #EBE1E1", "% c #EDE1E1", "& c #918484", "* c #FFEEEE", "= c #F2DCDC", "- c #403838", "; c #5A5A5A", "> c #5B4545", ", c #FEF2F2", "' c #E9E9E9", ") c #856868", "! c #271D1D", "~ c #FBCFCF", "{ c #746060", "] c #FFFBFB", "^ c #FFFFFF", "/ c #FAF0F0", "( c #5E4949", "_ c #E3DCDC", ": c #BAA8A8", "< c #292020", "[ c #F1C0C0", "} c #D9C6C6", "| c #FFECEC", "1 c #FFE8E8", "2 c #FFFAFA", "3 c #FFF0F0", "4 c #FFEFEF", "5 c #705D5D", "6 c #DED5D5", "7 c #F9E6E6", "8 c #D3C3C3", "9 c #392F2F", "0 c #FCF6F6", "a c #BAA7A7", "b c #524646", "c c #D9D1D1", "d c #F2EAEA", "e c #796666", "f c #FEF7F7", "g c #BBAAAA", "h c #918383", "i c #1D1515", "j c #EBDADA", "k c #B5B5B5", "l c #FFF4F4", "m c #DDD0D0", "n c #110A0A", "o c #FEFBFB", "p c #D3C7C7", "q c #FFF3F3", "r c #968484", "s c #F2E9E9", "t c #908484", "u c #FFFDFD", "v c #A89191", "w c #776262", "x c #CCB4B4", "y c #9E7979", "z c #705F5F", "A c #FFCCCC", "B c #FFEAEA", "C c #FFE6E6", "D c #FFF1F1", "E c #FFFEFE", "F c #FFE1E1", "G c #FFF2F2", "H c #FFF7F7", "I c #C7B8B8", "J c #AE9494", "K c #5A4848", "L c #C0AFAF", "M c #D1BDBD", "N c #4F3D3D", "O c #513636", "P c #BCB0B0", "Q c #665757", "R c #1A0C0C", "S c #E4DCDC", "T c #FCF3F3", "U c #1F0C0C", "V c #C3C3C3", "W c #726363", "X c #443A3A", "Y c #FFF8F8", "Z c #583D3D", "` c #FCF4F4", " . c #615757", ".. c #6C5656", "+. c #A09393", "@. c #9B8E8E", "#. c #856464", "$. c #4A3F3F", "%. c #BBBBBB", "&. c #C0BCBC", "*. c #452F2F", "=. c #736C6C", "-. c #775656", ";. c #878787", ">. c #A38888", ",. c #624D4D", "'. c #C9B4B4", "). c #F8F0F0", "!. c #FFEDED", "~. c #604242", "{. c #B5A8A8", "]. c #FAE9E9", "^. c #FBF3F3", "/. c #BAB2B2", "(. c #F8DEDE", "_. c #7F6F6F", ":. c #B5A2A2", "<. c #806F6F", "[. c #AA8E8E", "}. c #FEFDFD", "|. c #BD9F9F", "1. c #C3B4B4", "2. c #E0DCDC", "3. c #F9EEEE", "4. c #080303", "5. c #F3C1C1", "6. c #B7A2A2", "7. c #4C3A3A", "8. c #DFD6D6", "9. c #7E6D6D", "0. c #FFE9E9", "a. c #B39A9A", "b. c #BBA5A5", "c. c #DEC9C9", "d. c #715D5D", "e. c #F3DDDD", "f. c #8B7979", "g. c #060303", "h. c #FFEBEB", "i. c #EFE9E9", "j. c #EAEAEA", "k. c #FAEFEF", "l. c #D1C3C3", "m. c #0B0707", "n. c #312222", "o. c #584141", "p. c #685252", "q. c #5D5858", "r. c #5F5F5F", "s. c #5B5B5B", "t. c #5C5858", "u. c #473232", "v. c #181111", "w. c #ECD8D8", "x. c #F9EFEF", "y. c #DBC6C6", "z. c #DEC5C5", "A. c #F7EDED", "B. c #DCC4C4", "C. c #F8EDED", "D. c #DEC3C3", "E. c #E0C9C9", "F. c #DEC1C1", "G. c #DBC7C7", "H. c #F7E8E8", "I. c #E1CACA", "J. c #DBC2C2", "K. c #F8EFEF", "L. c #796868", "M. c #422B2B", "N. c #B5A3A3", "O. c #F8ECEC", "P. c #F8EEEE", "Q. c #FDF7F7", "R. c #FEF9F9", "S. c #F7EAEA", "T. c #FDF6F6", "U. c #F7EBEB", "V. c #FDF5F5", "W. c #F7EEEE", "X. c #F8EBEB", "Y. c #786565", "Z. c #2C2121", "`. c #F6E9E9", " + c #F6E8E8", ".+ c #F9EDED", "++ c #FEFCFC", "@+ c #F7ECEC", "#+ c #F7E9E9", "$+ c #837070", "%+ c #806C6C", "&+ c #D4C3C3", "*+ c #DCC8C8", "=+ c #DDC2C2", "-+ c #DBBFBF", ";+ c #E1C8C8", ">+ c #DEC8C8", ",+ c #DEC7C7", "'+ c #DFC8C8", ")+ c #DEBBBB", "!+ c #FAEEEE", "~+ c #221B1B", "{+ c #3E3131", "]+ c #F8E8E8", "^+ c #8D8181", "/+ c #F6E7E7", "(+ c #696969", "_+ c #6D6D6D", ":+ c #6F6C6C", "<+ c #835D5D", "[+ c #875D5D", "}+ c #9D7474", "|+ c #A27A7A", "1+ c #958989", "2+ c #919191", "3+ c #9D9797", "4+ c #917E7E", "5+ c #E3C8C8", "6+ c #241B1B", "7+ c #695959", "8+ c #CEBCBC", "9+ c #D1D1D1", "0+ c #CFCBCB", "a+ c #322424", "b+ c #201818", " ", " . + @ # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % @ & . ", " . * = - ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; > , ' ) ! ", " . ~ { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ / ( _ : / < ", " . [ } | 1 1 2 3 1 4 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 : ^ 7 . ", " . [ } 8 9 0 a b * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 : ^ 4 . ", " . [ } ^ c d e f ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 g ^ 4 . ", " . [ } ^ ^ h i j ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 k ^ l . ", " . [ } ^ ^ m n | ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 k ^ ^ . ", " . [ } ^ o { p q ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 k ^ ^ . ", " . [ } ^ r s ^ t u ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 k ^ ^ . ", " . [ } v w x ^ y z A ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 : ^ ^ . ", " . [ } ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 5 6 : ^ ^ . ", " . [ } B C C C D C C C E F G G ^ l C ^ ^ H ] 5 6 : ^ ^ . ", " . [ } I J K L M N L L E O P Q l B R S T U V 5 6 : ^ ^ . ", " . [ } ^ * W ^ * X ^ Y ^ Z ` .q B ..+.@.#.V 5 6 : ^ ^ . ", " . [ } ^ * W ^ * $.%.&.^ *.=.-.u B ;.>.,.'.V 5 6 : ^ ).. ", " . [ } ^ * W ^ * ,.!.!.E ~.^ {.].B ;.^./.(.V 5 6 : ^ _. ", " . [ } ^ q :.^ l <.<.<.E [.^ }.|.3 1.^ ^ B 2.5 6 : 3.4. ", " . 5.6.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ] 7.8.: 9. ", " . 0.a.b.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.d.e.' f.g. ", " . h.2 i.j.j.j.j.j.j.j.j.j.j.j.j.j.j.j.j.j.k.^ l.m. ", " . . . . . . . . . . . . . . . . . . . . . . . ", " ", " n.o.p.p.p.p.q.; r.s.; ; ; t.p.p.p.p.p.p.p.p.u.. ", " v.w.x.y.z.A.3.} B.C.3.D.E.C.C.F.G.C.H.I.J.C.K.L.M. ", " N.O.P.Q.R.S.S.f T.U.S.V.f W.A.Q.Q.P.P.Q.f O.X._.Y. ", " Z.Y `. +V.f .+A.T.Q.O..+++V.K.@+f f #+A.R.V.`.$+x.%+ ", " &+B.X.).*+=+C.#+-+;+C.O.>+,+U.#+'+)+@+#+F.*+!+9.k.~+ ", " {+]+^+/+(+_+_+_+_+_+_+_+_+:+<+[+}+|+1+2+3+S.^+4+5+6+ ", " 7+8+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+0+a+b+ ", " "}; xterm-399/icons/xterm-color.svg0000644000000000000000000014216413642730351015360 0ustar rootroot xterm-color image/svg+xml xterm-color Thomas E. Dickey MIT-X11 XTerm icon, in SVG format. June 14, 2012 https://invisible-island.net/xterm/xterm.icon.html https://invisible-island.net/xterm/images/icons-xterm-color_226.png X TERM xterm-399/icons/xterm-color.png0000644000000000000000000000350412034362541015333 0ustar rootroot‰PNG  IHDR00Wù‡sRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEÜ  ¬‘?ÄIDAThÞí™}lS×À/¶ŸILb’1.͵Ba[‘è&4JÉAHº-ƒI먺þ±NdhšP‘–5` %£-ÓÔÁ(´­ÛTMÐVÐMŒÑ’0ÈÇ@I‹É§“@êØ$¡‰÷|ö‡?H N NØv¤§ë{|î»çóžsσÿRxò<9£Êxq¹\gívûÒмÐb¤<#ÐÚÚz)===/„_ü=Ú—H\.×YUUc¦qUU¥³³ó£Ðö^@jkkß2 Ý£YCGÚÛÛÿ‘ãpäÌöù>õCN,Ô? ê½fs޳¹ùªÍfËQÅ*"­ííí-‡#Ççó•Dc ‘>“É$©ðq¬ý~œQUUDÄâ¥%ì f³¹{¢¸ àÄ: ;n†.€ˆHKKËéqјõ{)PÿtÁ'káñ?¶AC8×ÂoÒcáiiiŽhƒx„æÿ3H×fD¦­‹yÈ÷çÅÎaܤ,ЭÁ®÷!u1ü.+ˆûé#pkŽvϼD6f \^‹žG “ÏžBãb_Øa(8 Þ}^¬†¾ÀôjzÒ´û¡¡)x`;â§ßU&-@ñ\˜c×'ð|>d™ ŒÀðÄ Xy:¼¿&&|ªS"À;__×µAhõÁÏþ ¹ðËûŸâïI€GM°ß+3¡ñÖm|µú\°k}0©Í‰‹½ £!ZdÅÇ®@V"¼w3ˆÏI‚7.gZ!Å^ß ÏÓT y§,Ì4ˆÊ…^Yö g?~þØÅ?!_®Âšwû0ôCÅ®ëÌ·Y·9‰@ÜÝ5Õ\ï ºÛ¦Í,/}ò,žúze÷ê\þýoñüåS{Œ::iô8ñxÜ|ýçÛhô8iô8éðõ`ø¡ÊÍÅ Ý´‚¯;˜š3f¶nO¡«cû#&Þ=÷(©vYßú.½³£àµc‘=6y‡~ë²¾½uê-pèê ¸z‚¯‘ÆFïxöTEä¿çHå¡…—˯ߵ®ç3OôðØWX¶<>b…³—€òðmâ„t扇ÞûáBAÓ7tJßN fœ&¨ØÆhR˜;ßÈ •%_ŠçåÝ]Ãî²ñ³¼ì% †8âô>Äh¹?10XÝq‚Ãçmz¿ly<ßJ#m‘Ê›‡Ü¸Z‡F¬«;ü ˶¿€‚pþÕݬØñ« ÷ê¿§Zh4H©QØ_~ƒýå78xÄÁ_:ÿ9[ó¯±:§‘u›“"1†z YHœ çñ£ÀÄ¥í¾}ûÚ€Ê)µÀ„Zó •/^§ü€ç¾ÓÔœ-uùH½îènDº®7•••­žþBô2ˆû‚s.± ê7 ñÍus#¸s+<ôzu.× FpgO÷SXbe¾ÍH¿«¤EA¦¯¼~ðvöôÐßÑ:æþ{÷îmÔ4í ÐõÀeb¿ßï4nÀm UU%>ØŠ)ÄCªª#<$¤ý?Ü©ý ;sÙGŽÙçk襱`~ÔÝ2›—:››?µÙlKE±ú|¾K 麮/Æ}FôFÛÚÚÎLwotÇŽöO¶;ýO»Ý¾d: µpwZQDdA´Ú ¾ü¦ÆŠ\ ðLÁf á~ñ:–'?.[¶lY (ÊlEQîÌØZ+ã¼@EAQ”Àtw¾G~^2øýþkV«5spp0e‚}FÀºÌÌL§ˆôçççW‰ˆžŸŸ^Dô7V‹ˆ„æ’——w>ôÿdèaúU«V}<]AAA•ˆHyyùÉÊÊÊSÃïÀ¨khhø[è„F=4jwÌõ{¤sÔ4íšÅbqkšÖ>¶¯^½ú‚ˆè………Õ""6l¨ i©JD¤¤¤ä_ÃçaºðŸ¯87Þø¥²²²³f³¹(77·Å`0kkkÎÌÌlnnnÎe]Òd¹LLLÄh¼ûþ´páBW]]%77×e0Œ¥¥¥M;wîìkkk›=óa X€~ŸÏ÷ªªÀ:»¡äääù‡>ZRR²A×õ§Æc>ÒT˜A…ÛðgåÿD-ôóvYáwü IEND®B`‚xterm-399/icons/mini.xterm_256x256.png0000644000000000000000000002650312034362025016174 0ustar rootroot‰PNG  IHDR\r¨fsRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEÜ %Ê^R IDATxÚíy˜SÕÝÇ?'“Y˜a_QAqÁ¶Z¬Õº´jµUa­ZµµZÛj­¶¶.µUkmÕªuôUßöíb[ë®,"n¨ˆ¢AÙ—Ù2IÎûǹ3“drî;$¹7Éïó~çm`qž¯«µ˜ ß õ]`˜ó Šý€í2rµ }Îgçßà nIYË\ %À¿_ LÁg%!Tì õQ>¼Pš¿ø  ˜ð5 ÆJ?*JútcÙ·µt«¤ø6W| }¥?ÀgœŸ]å#à½Ò®–â<xh¸1†œ¡úí& î™~£W_)еn°~:8*àÚ[Œ×ÉÇGó| ”«B…† ÀîìÞ—Y?LõùO«]K\¼^ÈÖ¦ÌVxp@#úð{kƒ^kà `µÄF`_ŸÈœ·GP ,öÊZ 8èáãKßqÖþv¾¯LØsYäyzrð¸µÀ«À–€çOSp;LíÜ«åÜ ŸÜdíü‡úìüveç)àfÙ(çZÇØð"ÁÑôv& v޾)ý4/£ÿ ÀùÖc€]||a¯#¿ À eæ~"d×ç¹>’ Ãevv-q£†=¤Ëæ´óÁ̳ÓÇS˜;óŠçŒò—R=Å>¶‚?X ,Ö|‘“jë§uÀlíïJ°w~Ü ²¶êÃðgçº XêZâ§" ßÁXdm¼ˆ±Ú ŠZ`¢k‰I¸íT ~¸cÍŸñÀßÖ„±2µópq)VdÑ€2öXgZWh[1{ÁA2ÒyÙù‰öo‹&¤ký8à—ÖC€}|~é\ Ùúi ˜¦‚µ<pDàYàk¥¿B›è̲SÌÒn‹Á­óWaÛׯ¿¯ÆÏ6ó KµN‹Ñ–íJà-W5Òa¨ÚÙ°3¸Vºs·¸ØÏu‘UçãÛ6ãuä÷pc)WhÑ €2“µéØœJ›0± ‚dg¼²$}WÃg¥?ûý§—X Œò\~¥Óvä—°–ØLWn%J€ð¨ÌÖßBóe¯b{®}äˆõ+ìGk}ñg’‡Ë:{k‰V7ÍÛóÐùñH4!ÝÛcRo©œ´lþ¤ÊDkö¥Sæ<ÀOkÞŠëªþÝ÷Z¼ªßðµyèqÿbººI é*šùãt+¥È&jÆ©ªI–†E¾"_(qúÑÂ)a¹˜h¨ªFgXü]ÙÍZšŒPÜT×÷Lmçç³d ¾öƒfIû5=ƒû›¥ñ¥A} Y•:÷Þ‡iêYtpnš =Ó*F(2Ûs’sd Çt43Úߘ€å²9.”+°,­M×s¿®hâdR­·ŸŽIƒJgÓÚu¢œ,`®¢Ã_¾QÃü¸4¡ôX7í» íâæ^60Gï‹fJûû—Z!V&;ÿµ êôT°Sļz9ÿWJG+0÷Ô+å>ëœûŒ–‘´h˜—¶p÷뽂¼¤à«?™¡‚Å>ýƒ" }§ôvo½"¦Ãw%3Í6 ë’æõIÇÍþH˜“Tì QØ­ÂÔàôéÂaS“†Í¶jØš4ÿÞ¤aMV'`m2Xwï\ñL+Lm? PTp.ðÝ .'ØcÀÇtOšY…‰ßKp]y]öQ¦¡ïV#+`— ˆä·V·jø{ ü'H.9+c£pj5ìž§˜'I`}>N µéSêbáê:Õ^OëÙÌp.R¸°;hækíÌÙ˜é§`Ÿ(Œ‹Â^Ðßÿ<½R·20¶žÉ&zlo¢¦ÁØ:ôjÚFE2Á溾h›êúéG4'U$Ý£¡·‚Ójà¨*c'ñfÀÃb˜^GTYÇv`5ŠMκw P¢§ó¾O¿†Mýþ›êú¹/VÛfTDÛÖа: ïÅaqÞŽ‡ <ƒQíu }9x¸üf³ôBà öéîw¶…kš§0#ÚÄJØ7 ;»wx¥5#›—³Gã2F5Èî°{Ó mYÍÀÖõ Š­£o|sÇ/Ä01퓞¥'|çñ£?ø¸=Ñ|Íq¤BOw6Á‚§ßì“ÓÖ3›QüÍ_QÌcºr®¯Mä¾¹@UK´šu½±ºïPÖö̇;bécxoôh–ÖaeµG„Ïffðf^m5³…0R£à7=ÍOG¨WG”—ÌÒ‘há1x$$–£œNpÚ;ýnMÿå­/sàÖE¸mn]DŸ¸Ï8åk€»–ø­‚‹LoÑŠÙLîÆD¼7‚ùƒífz\hÆTÀêR[Ó"âÇLµ¦+¿®÷þ"lÎÓ5˜¸¿ÎiùÖho^î} úLd~ŸI,è3‘u•ƒì`Eæ¶ÂüV³Ÿ&άÏWuT…f/f¨÷ÊGÔ¿Gñö©ÜeÛ͆Oª<¥Ò<”]²wúA­ë˜ºá)ŽÜôŽÜøF4­ÈÍß^ˆ‰Lcí'¥à?)âùEàï´Ûjf…æüpheÇZ6Ê8NW]v¡ÕpÆ4;Ÿ†»Ç’º±<1àhžx4Ï÷ù,Í5ÙkpIžj53ƒ0ؘ¬€ŸÕ¥^ãMÌPß/xL÷q6ÿÌ:ðí8ü¢1˜14bÖÓ“+¡GçêÑ´‚S>ý_¾¶öQܶ¥ó0’$€¿á’z%°¿ÂYG¸8»ý÷/Úf–Q…¢—‚[{¥î"]K½ºÊGç?ø‹}vWÕtbÐø¯ZžÝõpþtà‰üñà“ɺ§°1 O·šý¦mÏ ~Zg6 ë¨a8§ªXé Àƒú·wLr›`a×±Ã"pB5LªìT cë9cÍC|mí£LÚ:??>“ À?q;⛣L$$Ãl=ÍKíïo/ð^ÀQøNZðÃéWÏu±óÁdsÈ>ï‹¿-êçåo[¢Õüsÿc˜3y,Í•3ƒ8ðB ³|³q:3íºN£^=Rú0K¿ ìk¶Œ4\²­pÓ²#ð•j³ÆÏ¸û‰[pÁª;øÚšG©ÖœÊ¼‰WºÉSüÁ™EUÑÌVÚŒ>ƒÙÜCùJ5œT:àjc:¿þɘԙð%LRµ®ò¤HaçéSÿ]~½ë-­Dq™ KãÀó1økÌÌ ½ìLÝ Ô<Å udi Àz ^lÿ×øC:[/eìáUié9¢‰8§Íÿ.yâèûìà”P;³€õ®ó„qN¶$˜¥—#X‡[ ¸Œ:¯‡Ù3i[ÿ׫A]¼Åï¿¶Ï,ðÖ{›³|juÝa9LAŒ«u„ÝøŠ‹€#ÓÚ³,øsKa—gÕ˜6ÙV=Œá õ~¡þ|á N#)–x6ÏÓÖ ŒåÕ/{šŸ¿þÅY¼óý™uW=¬xÍŒÀAfRxe´ÜÓžlT¥ì ÔøZÓ÷K»ØùÇá•ò}oŸ‚ù‚kçoÀÄô7ëê«U’êoÔ«£H0ÁÙƒ0½= |¡ nìi~*‡Sº›°"îì딤<¨_mÿF<¿ë¯±Q¸¶'̨1vç†ä×<Ú°äò±`÷ÄúXp¯:³aVüĹâìâó^ÖcÎüí<Ü™÷»ªWÿe3‡¡¹­ýÿz)3ÈÅ)A瀸_`–Þ­¸ 5òiœÛü+ëÒ 44ó‰r(ÓÕŽvÑ;'¬Ÿ.ÂØEÿ†2ÁŒþ‡—[ Œ ÓßVŒµŸ}ÐXœ­vlXé:©f¨o3i[n´ÍHO¬Þñç“:<‚vŒ¾ŠRÔÀãÚß/lí¾õ\U ÃÓ.ùÏôàóœ®vØ€×i@gµ¯ó2‰ãuöœvŸ©lá;`6¶í±Z̦¦^ÆØûÛwf*“ˆ½°Ô«0ö ›Ú÷N¬6B°#‡Ë°2™Ú0gòŒŽ§Dø©ÕÑ]Ë¿¡s¾Ÿƒï·ÔðÕ\¦YVÆä›®SÑÅ÷²€~¡Õ€;°™ô´ùUûø¶åO?;¿Qn³¶ü‹Às$˜œv•“+Í)ÁެÒgCùˆã‹OžÑÑ´éË'Iõ×/;GàŠŒÝVÍ/¨WqªÊ¹±‚ÿÅØ¬g'h‡¡ˆÓ‘B–7@Ãé˜WvöÆ8ût•¼Žü».5 ÅLõ.Q&‘Þn|¾[ ÕÝ\¼Ôš~–Éßf`þšÑ*¾Dj@§gbþ§ÏÜΟn}u3T¾ü·1Qx:“ÄX VªŸ3 UñX%¤xɤ¿Ïëm;ò³O›1G~á"yºZO„#«6ì5›ÕµÝF /·¦ÖÇyH(.HJÇ€}žýŒ˜ ì­R‡ç«©WWæûy:¡·Î²®ø·¼ÃÐÞìØ43‡ìºá£]€¾Y?¬>ã³¥½ ¸G¼LÁ[¡šMS[i⋤Æn]Ñ}x&c30™7áüÀýz$š/¶¿_Ð >†ÿ^ .«M_ók~ÌtõÓB=O'ço­–¬Ã¸‡€±&»ßA¤f~ðf=^Q‘þéú\‚ä<ÕH‚ã1!J »WB¿¾ï'ÒÚkÎÊÇf`~À¤;ŠXÔÌc>©ÌúipÚ¥ýŽêšé帗Ì%X‡¡ ÂÍpl¿³ÓvÒbwû8K{ãµ'ÐL 'ÿ꘭Eá‚ZÿÏ+}3p˜³¬¹˜`gµ¿ÿ¨S^t;Qà’™é¥¦†o4Ⱥ; 5`Ž©„ÎÔàß„y!n¶sÞ¿&ô÷~ªŠÑÄI¤ÚNˆÂ9=üÙ ¼˜±¨sï&œ{0Á wŒþ>ÖþÓjÌæIOSÃÌ|ìöûW€k­>$x‡¡02[ìŸì|„±Ç´s§JZ‡óT#5|‰ÔƒãÉ•ðu•Ò á•´þs ÷é]¾èØükÖæH£+L­JÍ”°˜N*tœt ×ãå0Ô$}¾1x&ôH£˜çZâàÒ¢«‡SÕâL–utá*·<ŠÉÜ ¬Èíf`nàA=èÈq6¯S¤“ìì5£ëˆs,§ª-axŽÊ¬Në±ù†Áa(,ô¡-Ûc×yÉ©C¬µ{†*V‰=K­Cq ©ÖŠÓkL›ï KƆ¦£1žÍcº"œ`"þ*_ÓÿÁ¸°GêI 8‰³ÔÊ0=G'¸ä¬>&x‡¡ ‰`Žüü4Ï·ñ:M¹By „éjðuR}¾Ý#s£ÛNúfàpš8&|p¿®A3£cmœ€åK÷*e*¢WÚÎÈÔ«Cú(ï uw7“ †‚æü%ôؼæZâ?À-%Q7õêià‚ö÷uÊIJèŠÀ‹­é‘ªS£k…F"|ÿÍðz\ò§UîiÃÅo¨W÷†õ:ÇOgf‡¡ ðÓ?Žñò³ùmêU)Õf½ºÅuÉL –>ÿhæèáa€t'š“ªM¨®SªMà„Ì¿thejF€Ôðý°?Ce&ûX „Áa(€Jñàc^Ù¾¡‚Íœ{ªù!:%fáÄJ82˦à€^i–Ç·÷2bÑA”dÊQûË¢ÇtZ¨qƾŽf0¢Â¼Ž¯6*öVÜ„_›ÌT¾M$øzHvü»ÒÞÕðeà´¬ÞÄDñP&P‹¿ÌD«<÷KîVðç’¬«SU‚‡õÄy¶`©§×Àª„Ég±oÆE¬£Â#f·þ î×C¨àhÇ¢ù©F uʨÝÄNìÍÙÌTË‹ìQ^|Öéêé$¥Àq„ßZ/ø1smÂëÄd)ðÝ’®¯ÓÕZféÓ0Ñ‹+ˆbœÞÜyø7š'iæ9ÎSá€6fª5˜ððŒŽ²‚ÉD88†¶lÀ¹êOE8ëݤMT˜eü¶9 ŒÊ\Ü|øb˜#¿†’¯‡zõ³õÑ\g)±xxÍ“ÌPçã2ò—üÌæ|Þy]Æ=œÇ:g¢S1#_¥†ïñÒ÷I ·ÅTy ° þüàK™%˜;?qBµ—Óø9søš£Yœ‹âß$ù7õ¼ž‘Ȇâ€N7«Vwwñ˜®¢‘éàÃbY÷»p9&4Tv·——€ãñï VjlÂË…úà—eU'JiÖõ$8€FžO›ÖÏ(Ì%D¹qÓéÿ]ÏЄo˜îLn;×g›ÃÐaeÜù˜#¿„«<ÌP¹MW<û†5‹ äBâå0´¢Œ+èU`³k‰s•-“ P$\Gj\¸LæSžCã•®ãæ#Pì³€8f) Cm4{Þó2&Öƒ XŠ[¤Ú1.EåÂ\×YO˜¦Ü} "EÈm˜óÛ켂[¢‹Òa)ÆâÏÎÕÊ-Æ‚ P¤³1Úd÷JÝah ©)4³ñ"pƒ´€Rw‡¡u„-¨uîHâuä·Ù™ú'¤¥ˆ”²<A×gA@èÆ, ã0”}Åß–a(ÜÜ¢ÉMÚjA E`^C…úz³ty$EòÂ5¸eÈ ¿ÃÐg9#ˆݘ´õÖnÞL18 ]­a¼ƒÙy+uÀ!®%&âfê,ˆ”1ßޱ~:¯Ýöp0 éZâ*îyŒ€PðÑðKk!À>EtC1çÙ©ÄÄè!O^@:¿ÙÒ{›]ÆÓ¾˜Ѫý;cä鋦#ìgýt’³¶.6vör-ñm GÊã(çÑÿ(à;Ö»{®§ÃÍÌÉEvÆa¨Ÿ´€rìü¬“û^xí¨‡Ÿ(ÆJо|Ü.­A ¹›éŒr:Ne Üå@×Ài¾&ÍA œFÿs¬ö•Ð ïç;4 “–!P/àWÖƒðr±->Úf4v#¦þÀ}â0$Pê¿ è#û¾~%ÆÚ¯»Aoà@×GJ+(e~êÚ &=KøîÇ`ŽíüB›R‚@ÉþGà–8c$å‘\k2nÞŒµ˜°âQi1"¥ÔùûZë½cðSÔ:3;WI«(%îvÉúIÛY•o‹ymxÏv®Ð^2!ˆÉè&pеÀ8`°/l¦òxsn&ÎQŒÃP´ €bîü£p =sæï‡¹@²*§ /‡¡Ñ¸yH "!ïüQL`Ï^Ö1î0ŸOb)&?`©0·È‡çk8ZZ“@1rnëØCps”éÌÜ’‡/pˤ0Bý¥9‰Óè?ø‘µÀ®ø ™^Ää,5*0ÆO×yÂÒªDŠ¥ó÷ÆXûe~Y êóK_6”p¥õÇk/ä Ó¤u‰·áæÅ?a½×ï”A­ÃËê·Úv”*ˆ„dô?˜n-°7^±óÓ‰/™/.y¼†úˆÃ@X;ÿÜ‚[ôÇ+{Ngæ eT‰½ðŠüyÜ"( "uþ `–3JuÆ{£«3+ʰ2GcâÙù¹6s)A 4\|ÖúéA¸uufð²ýãÆªÚí%]›‡â¶ORƒqª’f'†Ñÿ`à'ÖÃñçàª1G~­Ö K‡ŽYZÒ•Ú¯“’ À¥õ‰Ýù{bbúWZǪÉ>¿ô `k‰‹ªëšJ¾rwÅDEv™uiÿµ+ˆä”_{Z?‚-ÝGvÖ‹]KüIÁ=eS»îC‡¡žÒ E‚ýOζØ a.[©¿ýÈo5pNYUr%^Y‘vÇ-¾¢ §Î? ø½µ@_¼âßuffóϾ30C•¶=`v†àµçކã¤UŠªó+LtŸþÖ‰ég°gg9ð¡k‰[¯üA¿×¥H] Ä\ Lµ~zþ’]5ó]K¼ \QÖ5^—ëôLÔ%A ¯£ÿxà:k¡ø3QÑS_{ˆ¯fà -e_ùýqµs¢}IÈKç¯Åùe7@©vF)?¼qö±ó}oIí;ì ìäZâV]ÜéTEBÌM®ãûdŒKWÙ¼îZâŸHâÌt¼s&öÆ8 IûÈéèðMkÑøsTcŽüì±ýÖg©òðôGOŒí¥Ïß•ŠÈUç‚É䫬cÎA>¿ôLˆ/ûÎÀÙÊkqPÎìá)¸×êÒ˰(@çWÀ}Ö•gsäç'ÍJà=×w*x\j߃Cq³²¬æˆÃÀŽr!pŒõÓñÀßÖ„ññ·ó.𽢩D€»/‡¡ý€k¤ ‹twôÜh-0ØÇç—¾„9ØËN ˜¦ ±h*©!`دગj77mÁÒù«1G~Ù'™U˜Ýh?Á©–Ÿ¸–¸R[àï&`iŒ-ó¢µ[ ! 78SÈìLÂ_ÒªÍÀ«®%žn.ÊšZ¬ ðï{; n•&-ÐÕ|i.Ÿ ·IDATÑÿ(ÜâÎíŽ?S“ð‚ëTyÆÑ'Y¬ÆK¸0É?;y.ÇfjøŠ´n¯¶<xÀ:žôÂø¨ûáU§‹Û9O™³âe;°0àkWþ »µ¿4¬"eÈ}Øw{[¡uægŠlçÿ»CWÜ[¡e+cçùؽ0áæÂ-Pö£ÿ¹À ÖûãÏá´Å™Ûù¸¨[«R¢à:]Xc‡à$"½mn§ù§/^CÇkø†´v€Ìοn‘eáß®l.æÜ?;q̑߶n^p‡éQ³.xeµÏük2¢q5;÷$c1¶›vnqÒ¶‹àX‹ÍÁ¶¯_‰±öósä÷žçtøåeäNG^áBo¦NkE–õÐ*g9 s*`·쉉%X! ü·^ñvr+ÆÖßÎ<Üb ø4xršÑXU›½ÌBº;·É ux9 M~  £ÿÀ÷­Fâo²˜ÄùÙ×åÛœ©ÿŽÙÏ©”ÙJ¡-ñZ:§¹ÊbŒßJð9 wÇ$k³sµàE L;?Ll¿ ë(2Éç—¾ŽWØÎ •Wô¿®Q“­C„qk‰º¤9þ”à³OÂ-FC&ÃP@yr'6§Ò¶#??¾dk1~ì<ª`ö_õcºŠÔÄY…–±äØÐsÀ_¬e_ÃË"¿Tã•:dÜ/ÇDŠrô?8ÕµYø1‰áÓ%p~N.¾ÓÞo*ð.à–ô›<óœ®Ç» éÔKCÃ0[ì\ì,Eʤó~c-0sæï‡ù¸¥ñNõ*WcaeÆ!׿/6§ Î߯W‡I’ýB6áú,ÿ„›;PF¬¯@éwþ(ÆË/{sˆâ~º3bâúÛ¹QÁ³9»‰DÆÖÖ†ÏÖëÌåÒpÿî¶þÎ;ë0Ôö\íG¹»º "%ÃU¸míLê »7Û1}ì,Â-sp÷žÜ^iï?)°¬IfŽõcŸßÃf‡!oc®é¾*Pº£ÿdàG®cÀžþ¾\u#æÈ/–ÓI¦$ߢÓLs B‹ÎœuŒ5¶õÖ†öÃ+‚ÓÚæ "PÔ¿·3õÏ~äW‹Wx©Î,Æ+÷%Ê„øÊ-*ÅhiE@»k+Òà€ŽKcð ëï…ßahp¯ög÷)P܆›ÿRÖº°Þp-ñWå¶&î.ëÁ¤îi/ HÞK³tÁ}:õ8õ§¸Å Úa¨0ÁµÄ1Ày"¥3úŸL·Ø“¾VgêoŸy¯!_g >—öþÝx0•º$Cx*:®ËYòL·vófvÌ "Œõ|æ7i B€vþÀÖý=GƒÎ¼ŒWï3•×â û7tRû¿7iXÔ ë“©­é¤ôU oã–Ðt%Á: µÍúì†^u+Á €âíüSßìç»mi¼ýÔÄ à׿Qð¯¼ÜÐýº/&C‘aakp¶öx9žúþÖ3JÝŠ‰u˜…˜Á ¨Å8zÙ™H ge.‡Àå1eNå g=ØUñJãý–ó7óCç“ê²ü|k°µû|,U€jHpaÆ, ÌÄ–©/ëÉü³^ñ¯Òþó>‰„`ô?·ó÷ár˜ÖµïEÜìîÛÒxçg{k¶Jªûê[qø(l%’„7Òf—2GϸE= ƒÃÐDg6JLì€"ÅÓù{bŽü²Gï«ÁËA¤3ïà•©ïroæç†´Âd îXÊ< Ge?Þ’:‚÷"ÉÎõ¦ŠÀ,àÿ¬ßñ:aw‹ /P$ü·Ü)øs݈Wò‹“O3ÒÙ\ŽæÄö÷ó[aI<5ý~^L[ŠÏl®ÏRò<«„&ÞahgȰ¯ÌäÛŽÿè"Æ1%;{a¼ÃºJsäg·¶]ÙõÏÏJv¶¾ŒTwÕIx¨9\•þp3¬M¦ï½<¨¯Ê˜¬Çíh4 Cp3W‡¡~"áíüÀ{¬úàø+;‹pKã &÷êœßÌcºêûÐÜ@›UZ£†›;¹ãNƒ†_7šŸÝågÌÒñî—ÒƒþŽ[Xîwœ= ðv†Û‘r‘¡J¬ó+àI`jÖÀ—ð§ß«€§]KÜ­rm1vîO瓚’|cÒtþ•!N4,—ÖÂÀHæ éV4¿c†ÚàìÏ¼Ž ØÕ™žÀñøË½kÞÀËÊó4ˆ„K¾‡[&߃0]¥ x·=ý÷€ Ê- @W¸ZGÅÞ(>ƒæGÀÒ›ÿüV˜Ó [uøD/gÔÀäÊl‹©§€Ç¯ý¿+·þð/?¿?¢“ÙlöÀÿ&mŽÿt¤Ë¾`ÙWÁÇ"áèüã1N¹Ùíº†_ðù¥OáöxcÀd×L¾÷ëÌ®}_*鋦/šþΨ>Åp4c0‡‘ÙWž+“ðh3¼/¾‡2. §UÃ.Ùûxu¼%¶ïÊÅUcV/eئºy5ƒ¶­£ÿöômÜLß}7ÓwàfúÆ7Ó#ÑTøëß ü ·à®O_TÁZ1ˆ8糯XÇ÷jL®?§¸ïbÌ}-ü}ü±·wÉßbDœŽMû«OÊ¿»h2¼‡§cðZ¼ˆ›—ÓÂöÂÔ*#Ý4ª­Ö-ô1èôjÝÌôÕ³Ù§áíÜ_ÿR¼b=\¤à·"Á À¸ÅÚ;ãçßU¶8Êo?’z®ú¾–{bѪÙ9¹ðI>HϾÅñôÍ´R¡NÁ¾Qس¼vŽ@UnšàCoÁékÎÏu»Ï›œeà»ÅøH¢%Ðù¾i-0ÚgçOÏã™Æ;­šb-ÇìÖg¾´1%Þ’„mÚÄñ[›45J°¿w¢A›½Œù­ÃOÿ Ž@_½W‚Ú”Ÿ©¯ Zìdà¯Ø,@{`¬§¨`c•Ÿh“ýíëL¦7þ-¸½CXŸï˜¶¦ ÀýÍðz«ÙŒ•CoÎÍdCÒ_<Ã*eÁ梀û´±Ü ÛÑÿ(Œ}|vvÇ+²K:m9ëÜÓxŸ¡ÜJ´Q 앎Y´…‘û6Ñ¡˜¤³§È wð€urß ³Iã‡7p³õcåõ´x¡ýñÊùUí…:$¨"€?_¶ÞÅј´O]åSLØNû©Ý”›‚?¦{Òšâ©'䜻î=ïÀ#ßúÏÿ`3 I{:’Z?¥g|{Á%Oàûy3°¿òÚað¬çs»¬Æ»î t&†ñò³ûð­rÜFé†?û€Ë¬>‰íÛœ¶d_$>L «ÃP¤ÀàWÖÞÉ;³Àµó'1i¼¥ó‡ƒãæ™?—`3 õÂØÚ9·}+×Î_…9ò˾¯_‰ÿ#¿ÿ:/;7+·8öB¡§¨1`6Küf¼Â´çŸ==g!×kÿ–)áZ8‰5—øúÜc÷†—yf:Û1^~îÁtÈu&_;ï(sÅ filled-xterm image/svg+xml filled-xterm Thomas E. Dickey MIT-X11 XTerm icon, in SVG format. June 14, 2012 https://invisible-island.net/xterm/xterm.icon.html https://invisible-island.net/xterm/images/icons-xterm_281.png X TERM xterm-399/icons/terminal_48x48.xpm0000644000000000000000000000503511766200770015601 0ustar rootroot/* XPM */ static char * terminal_48x48_xpm[] = { "48 48 2 1", " c #000000", ". c #FFFFFF", "................................................", "...... ........", "..... .................................. ......", "..... ... ... . .....", "..... .. ............................ .. .. ....", "..... . .............................. . ... ...", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . .... ..", "..... . .............................. . ... ...", "..... . .............................. . ... ...", "..... . .............................. . .. ....", "..... . .............................. . .. ....", "..... . .............................. . . .....", "..... .. ............................ .. . .....", "..... ... ... ......", "..... .................................. ......", "...... ........", "................................................", "................................................", "...... ......", "..... .................................. ......", "..... . . . . . . . . . . . . . . . . .. ......", ".... .................................. . ......", ".... . . . . . . . . . . . . . . . . .. . ......", "... .................................. .. ......", "... . . . . . . . . . . . . . . . . .. .. ......", ".. .................................. .. .......", ".. . . . . . ........", ". .................................. . .........", ". ..........", "................................................"}; xterm-399/icons/mini.xterm_32x32.xpm0000644000000000000000000001066012034362314016032 0ustar rootroot/* XPM */ static char * mini_xterm_32x32_xpm[] = { "32 32 143 2", " c None", ". c #FF0000", "+ c #FF1900", "@ c #FF1F00", "# c #FF0B00", "$ c #FF1D00", "% c #FF4A00", "& c #FF5100", "* c #FF5B00", "= c #FF5E00", "- c #FF5300", "; c #FF3600", "> c #FF0C00", ", c #FF5A00", "' c #FF5C00", ") c #FF0A00", "! c #FF0D00", "~ c #FF2E00", "{ c #FF5800", "] c #FF2700", "^ c #FF0500", "/ c #0073FB", "( c #0041F7", "_ c #0074FB", ": c #0059F9", "< c #0000F1", "[ c #0505EC", "} c #3A44BE", "| c #615A9A", "1 c #784285", "2 c #3466C8", "3 c #004DF8", "4 c #0053F8", "5 c #006CF9", "6 c #3C44BD", "7 c #2729CF", "8 c #002CF5", "9 c #2D2EC9", "0 c #8D6E71", "a c #E96416", "b c #FF4400", "c c #FF1800", "d c #0019F3", "e c #FF1400", "f c #D66729", "g c #73498A", "h c #091FEB", "i c #002CF4", "j c #006FFC", "k c #0002F1", "l c #0059F8", "m c #AD3252", "n c #FF1700", "o c #FF2B00", "p c #B84A47", "q c #0026F4", "r c #FF0700", "s c #FF1600", "t c #003FF6", "u c #0003F1", "v c #006FFA", "w c #0058F9", "x c #0055FA", "y c #FF3D00", "z c #C3363C", "A c #FF0400", "B c #FF3F00", "C c #FF1000", "D c #003DF6", "E c #005AF8", "F c #002AF4", "G c #FF0100", "H c #FF5600", "I c #C3643C", "J c #A73958", "K c #FF3100", "L c #0020F3", "M c #002DF5", "N c #0089FD", "O c #0022F4", "P c #0085FD", "Q c #C36E3C", "R c #BC3943", "S c #FF1300", "T c #007AFC", "U c #FF2200", "V c #C3693C", "W c #FF4600", "X c #C3563C", "Y c #FF1100", "Z c #BD6C42", "` c #C12F3E", " . c #B13B4E", ".. c #C32F3C", "+. c #C0283F", "@. c #C34D3C", "#. c #FF2400", "$. c #BC3E43", "%. c #C36D3C", "&. c #FF3400", "*. c #FF0800", "=. c #C36B3C", "-. c #FF4E00", ";. c #C3523C", ">. c #FF3E00", ",. c #FF1C00", "'. c #FF0200", "). c #BF3240", "!. c #FF1A00", "~. c #B4624B", "{. c #FF5900", "]. c #FF1200", "^. c #B82E47", "/. c #FF4800", "(. c #FF3A00", "_. c #001EF4", ":. c #001DF4", "<. c #7D4882", "[. c #FF4F00", "}. c #0076FB", "|. c #000CF2", "1. c #0276F9", "2. c #FF3800", "3. c #FF5D00", "4. c #004CF7", "5. c #004CF8", "6. c #FB0104", "7. c #FF5500", "8. c #B53E4A", "9. c #0055F8", "0. c #0038F6", "a. c #0028F4", "b. c #0039F6", "c. c #0254F6", "d. c #C66E39", "e. c #FF3500", "f. c #248ADB", "g. c #785587", "h. c #DE3121", "i. c #FF1E00", "j. c #FF2800", "k. c #FF5700", "l. c #FF1B00", " ", " ", " . + @ @ @ @ @ @ @ @ @ # $ . @ @ @ @ @ @ @ @ . ", " . % & & * = = = - & & ; @ > & & & , ' & & & ) ", " . . . . ! = = = ~ . . . . . . . { ] ^ . . . ", " / ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( _ ", " : < < < [ } | 1 2 3 < < < < 4 5 6 7 < < < < : ", " 8 < < 9 0 a = b c d < < d e f g h < < i ", " j k < l m n = = = o p q < < q r { ] s t < u v ", " w < x . y = = ' z q < < q A % B C D < E ", " 8 F G H = = I q < < q J K & ! L M ", " N O P r = = Q q < < q R ' S T O N ", " . U = Q q < < q V ] s ", " . W Q q < < q X Y ", " G Z q < < q ` ", " .q < < q .. ", " +.q < < q @.#. ", " $.q < < q %.+ &. ", " *.=.q < < q Q - Y ", " A -.;.q < < q Q = >.,. ", " '.; -.).q < < q Q = = U ~ ", " !., Y q < < q ~.= = {.]. ", " *., U q < < q ^., = = /.s ", " A -.(.]. _.< < :.<.C = = = ~ ] ", " '.; [.! }.|.< < |.1.. 2.= = 3.s ", " !., Y 4.< < < < 5. 6.7.= = & ]. ", " *., U 8.9.0.a.< < < < < < a.b.c.d.= = (.@ ", " A -.e.# f. g.h.= = = i.j. ", " . @ @ ,.y , Y ,.@ @ G '.@ ,.].* = = k.l.@ @ . ", " . & & & & & & & & & ) ,.& & & & & & & & & & ) ", " . . . . . . . . . . . . . . . . . . . . . . . ", " "}; xterm-399/icons/xterm-color_48x48.xpm0000644000000000000000000000522612034777373016252 0ustar rootroot/* XPM */ static char * xterm_color_48x48_xpm[] = { "48 48 10 1", ". c None", " c #555500", "+ c #000000", "@ c #FFFFFF", "# c #FF0000", "$ c #070700", "% c #0B0B00", "& c #FF8400", "* c #49FF00", "= c #60B7FF", "................................................", "......++++++++++++++++++++++++++++++++++........", ".....+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++......", ".....+@@@++++++++++++++++++++++++++++@@@+@+.....", ".....+@@++++++++++++++++++++++++++++++@@+@@+....", ".....+@++++++++++++++++++++++++++++++++@+@@@+...", ".....+@++###++++###++++++++++++++++++++@+@@@@+..", ".....+@+++##++++##+++++++++++++++++++++@+@@@@+..", ".....+@++++##++##++++++++++++++++++++++@+@@@@+..", ".....+@++++##++##++++++++++++++++++++++@+@@@@+..", ".....+@+++++####+++++++++++++++++++++++@+@@@@+..", ".....+@+++++####+++++++++++++++++++++++@+@@@@+..", ".....+@++++++##++++++++++++++++++++++++@+@@@@+..", ".....+@+++++####+++++++++++++++++++++++@+@@@@+..", ".....+@+++++####+++++++++++++++++++++++@+@@@@+..", ".....+@++++##++##++++++++++++++++++++++@+@@@@+..", ".....+@++++##++##++++++++++++++++++++++@+@@@@+..", ".....+@+++##++++##+++++++++++++++++++++@+@@@@+..", ".....+@++###++++###++++++++++++++++++++@+@@@@+..", ".....+@++++++++++++++++++++++++++++++++@+@@@@+..", ".....+@$+++++++++++++++++++++++++++++++@+@@@@+..", ".....+@%@@@@@@@+&&&&&++****+++==+++==++@+@@@@+..", ".....+@++++@++++&++++++*+++*++==+++==++@+@@@@+..", ".....+@++++@++++&++++++*+++*++=+=+=+=++@+@@@@+..", ".....+@++++@++++&&&&+++****+++=+=+=+=++@+@@@@+..", ".....+@++++@++++&++++++*+*++++=++=++=++@+@@@+...", ".....+@++++@++++&++++++*++*+++=++=++=++@+@@@+...", ".....+@++++@++++&&&&&++*+++*++=+++++=++@+@@+....", ".....+@++++++++++++++++++++++++++++++++@+@@+....", ".....+@++++++++++++++++++++++++++++++++@+@+.....", ".....+@@++++++++++++++++++++++++++++++@@+@+.....", ".....+@@@++++++++++++++++++++++++++++@@@++......", ".....+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++......", "......++++++++++++++++++++++++++++++++++........", "................................................", "................................................", "......++++++++++++++++++++++++++++++++++++......", ".....+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++......", ".....+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@@++......", "....+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@+......", "....+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@@+@+......", "...+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@@+......", "...+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@@+@@+......", "..+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@@+.......", "..+@++@++++++++++++++++++++++++++@++@+@+........", ".+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@+.........", ".+++++++++++++++++++++++++++++++++++++..........", "................................................"}; xterm-399/icons/filled-xterm_48x48.xpm0000644000000000000000000002114212034404120016337 0ustar rootroot/* XPM */ static char * filled_xterm_48x48_xpm[] = { "48 48 246 2", " c None", ". c #000000", "+ c #F6D5D5", "@ c #FFEAEA", "# c #FFD6D6", "$ c #FFD2D2", "% c #FFD3D3", "& c #F8D6D6", "* c #FFEFEF", "= c #FFFFFF", "- c #F6DBDB", "; c #0F0707", "> c #090505", ", c #F6DCDC", "' c #FFEEEE", ") c #C99999", "! c #030101", "~ c #F7DEDE", "{ c #150B0B", "] c #E3C5C5", "^ c #FFEDED", "/ c #E4CBCB", "( c #140B0B", "_ c #F7DDDD", ": c #E0C9C9", "< c #080303", "[ c #FFD9D9", "} c #0D0707", "| c #E5CACA", "1 c #E5CBCB", "2 c #0B0606", "3 c #FFDCDC", "4 c #E2CECE", "5 c #090303", "6 c #E1CBCB", "7 c #9F8A8A", "8 c #3B2929", "9 c #312020", "0 c #FFD5D5", "a c #ECC8C8", "b c #402525", "c c #351F1F", "d c #663E3E", "e c #E6DBDB", "f c #FFFAFA", "g c #FFFEFE", "h c #8C7272", "i c #B4A1A1", "j c #A69494", "k c #D8C0C0", "l c #675353", "m c #FFFDFD", "n c #584545", "o c #E1BFBF", "p c #3C2929", "q c #FCF3F3", "r c #F6EAEA", "s c #160F0F", "t c #E9D3D3", "u c #6E5C5C", "v c #D6BABA", "w c #CBBBBB", "x c #0D0808", "y c #F8E8E8", "z c #FFE2E2", "A c #F4EDED", "B c #FFF2F2", "C c #4B3A3A", "D c #FFFBFB", "E c #AD9292", "F c #FFE1E1", "G c #A28E8E", "H c #CCBDBD", "I c #8B7777", "J c #231515", "K c #ECCECE", "L c #FFDADA", "M c #251414", "N c #9A8686", "O c #FFF1F1", "P c #FFECEC", "Q c #FFE4E4", "R c #FFDFDF", "S c #FFDBDB", "T c #FFF0F0", "U c #FFDDDD", "V c #FFEBEB", "W c #FFF4F4", "X c #FFE5E5", "Y c #FFDEDE", "Z c #B29E9E", "` c #A08F8F", " . c #8A7373", ".. c #1C1111", "+. c #D7CACA", "@. c #645555", "#. c #5E4B4B", "$. c #FFF7F7", "%. c #BD9F9F", "&. c #392B2B", "*. c #A19090", "=. c #867474", "-. c #9C8D8D", ";. c #A99494", ">. c #0E0606", ",. c #FFE9E9", "'. c #D5C6C6", "). c #564545", "!. c #FFE7E7", "~. c #5B3D3D", "{. c #352121", "]. c #5B4242", "^. c #FFD7D7", "/. c #E7D2D2", "(. c #1F1313", "_. c #786363", ":. c #AC9191", "<. c #FFE8E8", "[. c #DBC7C7", "}. c #897474", "|. c #574E4E", "1. c #999999", "2. c #FFF6F6", "3. c #170F0F", "4. c #3B2B2B", "5. c #190E0E", "6. c #C7B6B6", "7. c #5F4D4D", "8. c #F6E1E1", "9. c #FCE9E9", "0. c #F1EAEA", "a. c #FEFAFA", "b. c #3D2828", "c. c #382626", "d. c #947D7D", "e. c #FFFCFC", "f. c #B09B9B", "g. c #C2B2B2", "h. c #EEDADA", "i. c #FDEFEF", "j. c #0B0505", "k. c #DACACA", "l. c #7D6565", "m. c #C6A7A7", "n. c #FDF9F9", "o. c #6C4D4D", "p. c #AB9797", "q. c #927B7B", "r. c #FCEDED", "s. c #0A0404", "t. c #120B0B", "u. c #E8D1D1", "v. c #E2CACA", "w. c #0F0808", "x. c #907979", "y. c #F9DFDF", "z. c #1D1111", "A. c #E8D0D0", "B. c #E1C8C8", "C. c #1A0C0C", "D. c #F8E0E0", "E. c #F7D4D4", "F. c #090404", "G. c #FAE1E1", "H. c #100A0A", "I. c #100808", "J. c #7C4F4F", "K. c #F6D3D3", "L. c #FFD8D8", "M. c #F8D5D5", "N. c #AF9393", "O. c #FDE5E5", "P. c #FDE9E9", "Q. c #FDE2E2", "R. c #FDF8F8", "S. c #FDE6E6", "T. c #FEECEC", "U. c #FEE5E5", "V. c #FFE6E6", "W. c #F8D1D1", "X. c #0D0404", "Y. c #291D1D", "Z. c #583030", "`. c #FFF8F8", " + c #683737", ".+ c #5B3333", "++ c #582D2D", "@+ c #593030", "#+ c #5D3232", "$+ c #5A2D2D", "%+ c #663737", "&+ c #5B3030", "*+ c #897272", "=+ c #996F6F", "-+ c #DBC1C1", ";+ c #110808", ">+ c #FDDDDD", ",+ c #473636", "'+ c #563232", ")+ c #FFF5F5", "!+ c #5C3636", "~+ c #FFF9F9", "{+ c #582E2E", "]+ c #6F4040", "^+ c #5B3434", "/+ c #6D3E3E", "(+ c #5A3333", "_+ c #EFD7D7", ":+ c #FCEFEF", "<+ c #140A0A", "[+ c #6A5252", "}+ c #583333", "|+ c #5C2A2A", "1+ c #653737", "2+ c #6B3C3C", "3+ c #643434", "4+ c #6A3C3C", "5+ c #613535", "6+ c #9C8787", "7+ c #907A7A", "8+ c #DDC3C3", "9+ c #F8E5E5", "0+ c #FDF3F3", "a+ c #190D0D", "b+ c #FAEAEA", "c+ c #DCC4C4", "d+ c #876E6E", "e+ c #461F1F", "f+ c #472020", "g+ c #261414", "h+ c #070000", "i+ c #220000", "j+ c #230101", "k+ c #3A1818", "l+ c #3F1D1D", "m+ c #3E1E1E", "n+ c #553333", "o+ c #724646", "p+ c #431F1F", "q+ c #AB8F8F", "r+ c #887171", "s+ c #DAC0C0", "t+ c #FBD1D1", "u+ c #1A1010", "v+ c #B27C7C", "w+ c #020101", " ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . + @ @ # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % @ @ & . . ", " . * = - ; . . . . . . . . . . . . . . . . . . . . . . . . . . > , = ' . ) ! ", " . * ~ { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ / ( _ ' . ^ : < ", " . [ } | = = = = = = = = = = = = = = = = = = = = = = = = = = = = 1 2 3 . ^ = 4 5 ", " . [ . * = = = = = = = = = = = = = = = = = = = = = = = = = = = = * . [ . ^ = = 6 . ", " . [ . * 7 8 9 0 = a b c d = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = e f = g h i = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = j = k l g = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = m n o p q = = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = = r s . t = = = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = = = u . v = = = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = = w x y = = = = = = = = = = = = = = = = = = = = * . [ . z = = * . ", " . [ . * = = A B B C D = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = E z = = F G = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * H I J K = = L M } N O = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * P Q Q R = = S Q Q Q T = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = = = = = = = = = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * = = = = = = = = = = = = = = = = = = = = = = = = = = = = * . [ . ' = = * . ", " . [ . * [ U U U U U V z U U U U W X Y X ^ = = V U O = = O F ' * . [ . ' = = * . ", " . [ . * Z ` ...` Q +.@.#.` ` Q $.%.&.*.=. ^ = -. = = ;.>.,.* . [ . ' = = * . ", " . [ . * = = '. = = = Q = = = = %. = = ).!.= -.~. f f {.].,.* . [ . ' = = * . ", " . [ . * = = '. = = = U U ^.= %. ^ /.(.' = -._.:.<.[.}.@.,.* . [ . ' = = * . ", " . [ . * = = '. = = = @.|.1.1.2.= %.3.4.5. = = -. 6. 7.8.@.,.* . [ . ' = = 9.. ", " . [ . * = = '. = = = Q = = = = %. = 0. ' = -. a.b.c.f @.,.* . [ . ' = = d.. ", " . [ . * = = '. = = = 0 ^ ^ ^ e.%. = = f. m -. = g.h.= @.,.* . [ . ' = i.j. ", " . [ . * = = k. = = = l.9 9 9 ' m. = = n.o.z p. = = = = l.X * . [ . ' = q.. ", " . [ . * = = = = = = = = = = = = = = = = = = = = = = = = = = = = * . [ . ' r.s. ", " . 3 t.u.= = = = = = = = = = = = = = = = = = = = = = = = = = = = v.w.S . ' x.. ", " . * y.z.A.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ B.C.D.' . E.F. ", " . * = G.H.. . . . . . . . . . . . . . . . . . . . . . . . . . I.D.= ' . J.. ", " . K.P P # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ L.P P M.. . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " ", " ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . N.O.P.O.P.Q.R.S.P.O.P.O.P.O.T.U.T.U.T.,.^ ,.^ ,.^ V.^ ,.= D W ,.^ W.X.. ", " Y.W Z.`. +e..+e.++D @+$.Z.`. +e.#+e.$+D @+$.Z.`.%+e.#+e.$+e.&+$.Z.D *+=+. ", " . -+D f e.m D `.= D e.D D f D m D `.= D e.D D f D m D `.= D e.D D f r.;+>+. ", " ,+`.'+)+!+~+{+= ]+f .+`.Z.)+^+~+{+= /+f .+`.Z.)+^+~+{+= /+f (+`.Z.f q.q.T . ", " . _+m f = D m ~+e.`.m f m f = D m ~+e.`.m f e.f = D m ~+e.`.m f m f :+<+i.T . ", " . [+~+}+)+|+~+1+g 2+g 3+`.}+)+|+~+1+g 4+= 3+`.}+)+|+~+1+g 4+= 3+~+5+e.6+7+= 8+. ", " ! 9+= ~+= T ' @ ' ,.' <.' <.' ' ' @ e.f = ~+= ~+= = = D = f = ~+= = 0+a+b+c+! ", " . d+m e+f+e.g+. . . . . . . . . . . . h+i+i+j+k+l+l+c m+l+l+n+o+e.e+p+q+r+s+! ", " . t+* @ @ P S [ L S S S S S S S S S S z ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ P z u+v+w+ ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " "}; xterm-399/icons/terminal_48x48.svg0000644000000000000000000005473313630421115015573 0ustar rootroot terminal image/svg+xml terminal Thomas E. Dickey MIT-X11 Translated from the X11 bitmaps/terminal file through stages to svg. June 14, 2012 https://invisible-island.net/xterm/xterm.icon.html https://invisible-island.net/xterm/images/icons-terminal.png xterm-399/icons/mini.xterm_48x48.png0000644000000000000000000000422212034054407016026 0ustar rootroot‰PNG  IHDR00Wù‡sRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEÜ ÄDߌIDAThÞí™{pUGÇ?{Î}åm¹IHÒ6¤¥Ò@)Q^R‚ÒŽS¡m¨ÁRZµV*õÅ`[êØŽ2µ:>*j)‚ÓÊ#€e¨4mxE IHy$¹Ü$7¹÷Ü{ÎúGÜœûIgüÍìgÏo»ßÝßþö÷€ÿqÀ˜A’yB@G¤ŸÆ @¶& ÆJh¾9HmR´ T~¸<[¯¯‡€¤ìÏëqò}ÚOÙÀnê£hü=¾@²…°N k@[բߤà û× @Zt{-„α¡€w"ô—›PÃYË;Ù€bÞäz"¼¡RÅ´>š—L:°qbXÞs¤0„ܸFÎq–ÑÀTË5YˆH:ói¦‹Z‹²±¡²^Æ’ì#'w‚ìż, :n3jIoȉÌ,רéÇvWˆÛ¥BBOä1¡É»{Ǧ{çîïïÚ+ÿùúÌ’ÓµÓ)\ÐñŸä zPÕVÍúö¯4›C7Í–…*‡ú`•QÍ ßdòæ¾TNÏ'`±2Ùê·ÍÚÊ|óh5"Ÿ[ … n —ôƒ@÷Èt?ƒI4èÖãF¨0Ñц@ªß;Äp ­^S:´EØ(Ÿ„3¡\ÖÈá, ñÝË<Ã6­ ¯ $ÏRúõã,-…ÃEShwdÒJ6­[³C[2~Á|ç^2,Äf*0Ϲ‹Qöt¹Ã±ßûV–hq¹Ù|×—ypÚ®Ža¶û˜`“–:±]˧ËXß‘m’*ËõZðÊ«Íæ•ÌöûÆW¼]×”åöËG²2¬ÍDJ>cÑÎ3¾SöWRê“üZ.”Ù<,R–›ãŠø·„z é<šÃ3Z-c|}ǯÔßçE©Ä>v Z»öNf)ðlR#êÌwÖ—Ýéö|XÏaúêH6PŒ¬8ºñIìÖºœhxYËhÓdž£‰Ó•<üÒ¶…W%Ìp¬¤ÒÕÖKÁßÖ†Oyl¹˜ê`&Ãøš«– õN~f?(ÀOˆ¹œ,YŠj·S"îóU?z.Ód†Øƒ ¬áOè+öàV>Ǣċ$š:µ;8¯\Àe.õF>~ ÃXà:ÎÛx–oû{É2¢õr;èv”bà @²§#Ÿ)¦±‹4Ë,™_¶W“j›ÌÓ —p‰îËüah$ëåÈÚXÄv.O&4Rh+c®°òz^ †¿ê»Ê(÷«ÈtŽqŠV y´ˆü/Š“$Ër¾šàA æÑÆ‘t)̲7òB’§ñ‰Ë¬¨Nˆ/ÒDˆº~Øt7ÐF;ÿ ø–€“1Ǽàø©Ê–&ú™fo¤ÝH=ÑïdJ<ë‘ð„T Ê9׬ѺïUHÊ,¬PY§\÷Ý )]ÔIØÒW]Z:úÖïÀã¢=N±¯{,>«7élR#~\ÀÂ~¨¾øÄJt*iÆoéð…Qâ¹N70_\ñî” pƒÇ8‚Þ' £º¡#w øÛ`ºJÊ`Ý:ý&ÕÑUI³9üƒíë)ƒ&Éà)Úñp62KISíç%Œ½%ð⢃óQ˜†!QØ$Áu˹|….FpGERÅE>°ò– ³È¦™ß0H¨Sp"X$aÚ­sÕ¤bç`hJ0*ïP Âzî sø)mŒbR÷Eè:‘p1æ ±($“Âê› @ºÏEže‚™j9Â1g{àc1ªÀTœH*$̾)$8ðQE‚@+j(ÚW’q0ð£QM"°\À!Ó¤ ¬ ©& ù~Þ³ð–F9¨¨lÖyëÁ sY—ÑL2GVQ‡ÁI`ÅU¦€1Ÿ…G×!Y7î‘79ŠaéL*cï|$d.c¹Àî1_Û÷8Áeò€ A4‹B.[dôÚ$» îó!XË>}3.àS8,—p× `£¿’ƒÂ(à2m¼K>ð´ ÌÿÔäÎ[8o@—¼ƒoÒI3ïÒ—i¸ø+l–Ýå•A:7› ‘IÝÕ“4o XÛ#£—ÆjýûlÑr-c lÕrÅjý‡o›ð8ÇÁÒs€ '½ÔòºÒëWæÍæa.°™fVa?5œ!uÈOšÛL¯ Ù¸„@Å#쌠ÉȈ¾J ³œ§GŠÓî_SnóíYbnèO,køá5ž @:’é±ê¶¨‹O#=,xŽ3å-jÚtÎè%Ô÷ЄR;”ÆÜ´L.™uRG!\Rð¦§†Ç 0Áq6HƒâhæùJ8Í4f½)•MØ(â~ DˆØ€*`éŽ:÷HÀƲ/zíÓ }±V¾ó¥ÏŒQ ýª™Ìñ4•d{ϯN×…«0,ÚÔmhg’çÂò•zñÛ-g}Ð̦í>ˆ¸¶É±jcæ<‘#æ/@Ÿ ØqçEoJ¢»N‰¦FèƒNŒ8mžŠÆTäÅÉŸT†õ…Õ‹m=ìwwý¶ÿÁLbܼ:Z-vº?V/î}‰Rû—Žšm`”Æÿé¡ÿš"9¤D!êIEND®B`‚xterm-399/icons/xterm-color_16x16.xpm0000644000000000000000000000306012034777545016233 0ustar rootroot/* XPM */ static char * xterm_color_16x16_xpm[] = { "16 16 80 1", ". c None", " c #555500", "+ c #545400", "@ c #3A3A00", "# c #222200", "$ c #2A2A00", "% c #2B2B00", "& c #151500", "* c #5E5E00", "= c #5A5A00", "- c #909098", "; c #3E3E3E", "> c #000000", ", c #F2F2F2", "' c #2E2E36", ") c #343400", "! c #4C0000", "~ c #140000", "{ c #7C0000", "] c #7F7F7F", "^ c #858588", "/ c #EA0000", "( c #0B0000", "_ c #460000", ": c #8E0000", "< c #A80000", "[ c #474747", "} c #868686", "| c #404548", "1 c #8F3400", "2 c #451200", "3 c #299000", "4 c #1F6C00", "5 c #192E48", "6 c #1B3448", "7 c #888888", "8 c #CF4C00", "9 c #3B0700", "0 c #39C700", "a c #42E800", "b c #2D5181", "c c #55A3E3", "d c #305C81", "e c #989898", "f c #D84F00", "g c #3A0600", "h c #258100", "i c #376599", "j c #396D99", "k c #7E7E7E", "l c #010100", "m c #000101", "n c #9A9A9A", "o c #101000", "p c #5B5B00", "q c #3D3D00", "r c #272700", "s c #2F2F00", "t c #303000", "u c #1A1A00", "v c #464636", "w c #7A7A7F", "x c #8B8B90", "y c #1B1B00", "z c #0F0F00", "A c #FFFFFF", "B c #5B5B5B", "C c #C9C9C9", "D c #BFBFBF", "E c #B5B5B5", "F c #5C5C5C", "G c #79797F", "H c #7F7F88", "I c #484835", "J c #3C3C00", "K c #1E1E00", "L c #909090", "M c #333336", "N c #464600", "O c #575700", ".+@#$$$$$$$$%&*+", ".=-;>>>>>>>>>,')", ".=>!~{>>>>>>>>]^", ".=>>/(>>>>>>>>]]", ".=>_:<>>>>>>>>]]", ".=>>>>>>>>>>>>]]", ".=>[}|12345>6>]]", ".=>>7>890abcd>]]", ".=>>e>fgh0i>j>k^", ".=>>>l>>>>>m>>no", ".=-;>>>>>>>>>,>p", ".+qrsssssssstu*.", ".pvwwwwwwwwwwxy.", "+zABABCDDDEAFG*.", "*HBABAEDDDCBAIJ.", "KL]]]]]]]]]]MNO."}; xterm-399/icons/mini.xterm_48x48.xpm0000644000000000000000000002012012034362362016043 0ustar rootroot/* XPM */ static char * mini_xterm_48x48_xpm[] = { "48 48 213 2", " c None", ". c #FF0000", "+ c #FF5300", "@ c #FF5E00", "# c #FF4800", "$ c #FF4200", "% c #FF4000", "& c #FF4B00", "* c #FF5200", "= c #FF5400", "- c #FF3500", "; c #FF5100", "> c #FF5C00", ", c #FF3000", "' c #FF4500", ") c #FF2000", "! c #FF0300", "~ c #FF1600", "{ c #FF5D00", "] c #FF3800", "^ c #FF0200", "/ c #FF0900", "( c #FF2B00", "_ c #FF3300", ": c #FF1A00", "< c #FF1300", "[ c #FF1200", "} c #FF5700", "| c #4577BA", "1 c #874E78", "2 c #887577", "3 c #887E77", "4 c #887977", "5 c #875078", "6 c #566CA9", "7 c #5E70A1", "8 c #884E77", "9 c #887677", "0 c #7C5B83", "a c #795686", "b c #008DFE", "c c #0012F3", "d c #000BF2", "e c #008FFE", "f c #006CFA", "g c #0000F1", "h c #0001F1", "i c #0020F4", "j c #0040F6", "k c #0959F0", "l c #1158E8", "m c #1159E8", "n c #0058F9", "o c #001DF4", "p c #0023F4", "q c #005BFA", "r c #0060FA", "s c #0E58EB", "t c #0651F3", "u c #0033F5", "v c #000EF2", "w c #006EFA", "x c #0092FF", "y c #001FF4", "z c #000FF2", "A c #0C51EC", "B c #326AC9", "C c #7A6583", "D c #CA6234", "E c #FC5F03", "F c #FF5800", "G c #FF0800", "H c #F4060B", "I c #007CFB", "J c #0013F3", "K c #007EFB", "L c #FF1800", "M c #F3590C", "N c #AB6152", "O c #4F4EAD", "P c #175CE4", "Q c #0036F5", "R c #0022F4", "S c #0095FD", "T c #0084FD", "U c #0004F1", "V c #0051F8", "W c #345AC7", "X c #E61519", "Y c #FF5900", "Z c #FF4600", "` c #FF0100", " . c #446EB9", ".. c #0034F6", "+. c #0032F5", "@. c #FF2200", "#. c #006FFA", "$. c #002DF5", "%. c #0086FD", "&. c #0046F7", "*. c #0015F3", "=. c #0076FC", "-. c #FF0400", ";. c #FF2300", ">. c #FF2900", ",. c #9E3E61", "'. c #0039F6", "). c #FF2A00", "!. c #FF4300", "~. c #0071FB", "{. c #005EF9", "]. c #004DF7", "^. c #008CFE", "/. c #0008F2", "(. c #001DF3", "_. c #007DFB", ":. c #FF4100", "<. c #FF5B00", "[. c #A3425C", "}. c #994C66", "|. c #FF1100", "1. c #0072FB", "2. c #000AF2", "3. c #006EFC", "4. c #0017F3", "5. c #007FFB", "6. c #FF0600", "7. c #FF5600", "8. c #A56A5A", "9. c #A53B5A", "0. c #FF4F00", "a. c #0076FB", "b. c #0076FA", "c. c #0093FF", "d. c #007DFC", "e. c #FF1C00", "f. c #A5765A", "g. c #A55D5A", "h. c #006FFB", "i. c #002CF5", "j. c #008AFD", "k. c #006BF9", "l. c #FF3A00", "m. c #FF5000", "n. c #007BFB", "o. c #008BFD", "p. c #A5755A", "q. c #9A5565", "r. c #A43A5B", "s. c #FF4D00", "t. c #80507F", "u. c #FF0F00", "v. c #7A5485", "w. c #A5555A", "x. c #FF0A00", "y. c #A53D5A", "z. c #A4515B", "A. c #A5685A", "B. c #A5735A", "C. c #FF0700", "D. c #FF2E00", "E. c #FF1500", "F. c #A3705C", "G. c #FF0500", "H. c #9A4965", "I. c #FF0E00", "J. c #FF3B00", "K. c #FF2D00", "L. c #A13C5E", "M. c #FF4C00", "N. c #62649D", "O. c #FF0B00", "P. c #FF4700", "Q. c #FF1D00", "R. c #A56D5A", "S. c #FF2C00", "T. c #A4465B", "U. c #FF1400", "V. c #A03E61", "W. c #FF3100", "X. c #FF1B00", "Y. c #FF1000", "Z. c #0029F5", "`. c #0027F4", " + c #4571BA", ".+ c #FF3900", "++ c #FF3200", "@+ c #008EFD", "#+ c #0019F3", "$+ c #0090FD", "%+ c #FF0D00", "&+ c #FF1E00", "*+ c #FF4E00", "=+ c #0088FC", "-+ c #0087FC", ";+ c #FF1900", ">+ c #0036F6", ",+ c #FF2100", "'+ c #0073FB", ")+ c #0062FA", "!+ c #001AF3", "~+ c #2463D8", "{+ c #3E58BE", "]+ c #2A7FD3", "^+ c #807B7F", "/+ c #008EFB", "(+ c #006AFA", "_+ c #004CF8", ":+ c #717B8D", "<+ c #EE0B11", "[+ c #F73E08", "}+ c #FF1F00", "|+ c #FF5500", " ", " ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . . # @ @ @ @ @ @ @ @ @ @ @ @ $ . ", " . % & & & * @ @ @ @ @ = & & & & & . . - & & & & & ; @ > & & & & , . ", " . . . . . . * @ @ @ @ ; . . . . . . . . . . . . . ' @ ) . . . . . . ", " ! ~ { @ @ @ @ ] ^ / ( @ $ . ", " ^ _ @ @ @ @ @ : ! < [ > } ^ . ", " | 1 2 3 3 3 3 4 5 6 7 8 9 3 0 a ", " b c d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d c e ", " f g g g g g g h i j k l m n o g g g g g g p q r s t u v g g g g g g g w ", " x y g g g g z A B C D E F G H I c g g g g J K L / M N O P Q h g g g g R S ", " T g g g U V W X Y @ @ @ @ Z ` ...g g g g +. ` ' @ @.. #.$.g g g g %. ", " &.g g *.=. -.;.@ @ @ @ @ >.,.'.g g g g '. / ).@ !.. ~.{.U g g ]. ", " ^./.g (._. ` :.@ @ @ @ <.[.'.g g g g '.}.|.<.} ^ . 1.2.g d e ", " 3.g 4.5. 6.7.@ @ @ @ 8.'.g g g g '.9.0.@ [ . a./.g b. ", " c.R /.d. -.e.@ @ @ @ f.'.g g g g '.g.@ - . h.h i. ", " j.k.%. ^ l.@ @ @ f.'.g g g g '.f.m.` n.f o. ", " ! * @ @ f.'.g g g g '.p.G . ", " ! ~ { @ f.'.g g g g '.q.. ", " ^ _ @ f.'.g g g g '.r. ", " ^ s.f.'.g g g g '.t. ", " ^ u.p.'.g g g g '.v. ", " ^ w.'.g g g g '.r. ", " x.y.'.g g g g '.z.^ ", " ` A.'.g g g g '.B.x.. ", " C.D.f.'.g g g g '.f.# ` ", " < E.{ F.'.g g g g '.f.@ ( ^ ", " : G.; @ H.'.g g g g '.f.@ <.I.^ ", " -.J.@ K.L.'.g g g g '.f.@ @ s.` ", " I.) @ M.. N.'.g g g g '.f.@ @ @ _ ^ ", " L O.F <.6.. '.g g g g '.f.@ @ @ { E.! ", " ^ P.@ Q.. '.g g g g '.R.@ @ @ @ * ! ", " G S.@ % . '.g g g g '.T.{ @ @ @ @ l.^ ", " < U.> 7.^ ..g g g g u V.W.@ @ @ @ @ e.! ", " X.-.m.@ Y.. Z.g g g g `. +` M.@ @ @ @ 7.6. ", " -..+@ ++. @+#+g g g g #+$+^ %+<.@ @ @ @ :.` ", " I.&+@ *+. =+h g g g g h -+ ! >.@ @ @ @ @ ;.^ ", " ;+x.} > C.. >+g g g g g g >+ ` Z @ @ @ @ Y / . ", " ` ' @ ,+. %.1.'+)+!+g g g g g g g g #+)+~+{+]+^+@ @ @ P.` ", " / ).@ !.. /+(+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+(+:+@ @ @ @ ).^ ", " I.[ > F . . <+[+@ @ @ @ <.I.` ", " . . . . . . 0.@ }+. . . . . . . . . . . . . |+@ @ @ @ s.. . . . . . ", " O.@ @ @ @ @ @ @ @ @ @ @ @ @ ^ ! $ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ $ . ", " . & & & & & & & & & & & & & . . , & & & & & & & & & & & & & & & , . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " ", " "}; xterm-399/icons/xterm.svg0000644000000000000000000005223513642727626014256 0ustar rootroot xterm image/svg+xml xterm Thomas E. Dickey MIT-X11 XTerm icon, in SVG format. June 14, 2012 https://invisible-island.net/xterm/xterm.icon.html https://invisible-island.net/xterm/images/icons-xterm_281.png X TERM xterm-399/icons/make-xpms0000755000000000000000000000141114763041077014206 0ustar rootroot#!/bin/sh # $XTermId: make-xpms,v 1.7 2025/03/08 13:12:31 tom Exp $ # some files are generated from other icons... for name in mini.xterm filled-xterm xterm xterm-color do target=${name}.xpms NAME=`echo "$target" | sed -e 's/[\.-]/_/g'` LIST= echo "** creating $target" rm -f $target echo "/* @XTermId@ */" | sed -e 's/@/$/g' >$target echo "/* generated by $0 $* */" >>$target echo "/* vile:xpmmode */" >>$target for source in "${name}"_*[0-9]x[1-9]*.xpm do echo ".. from $source" BASE=`basename "$source" .xpm` PART=`echo "$source" | sed -e 's/[\.-]/_/g'` test -n "$LIST" && LIST="$LIST," LIST="$LIST { \"$BASE\", $PART }" sed -e 's/char \*/const char * const/' "$source" >>$target done echo "static const XPM_DATA $NAME[] = {$LIST };" >>$target done xterm-399/icons/xterm.png0000644000000000000000000000151311766601046014224 0ustar rootroot‰PNG  IHDR00Wù‡sRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEÜ $&R?ÌÖËIDAThÞíÙÏkUðOL"Ö‚46jŠ.¢›TZˆAUÅ.J *‚v© —­ wíª›.ŠèRòdeÁ…P¤"þ ¥MU\ÔÛ*Ò`^6˜.Þ˜^æ½7ïGf&!.oÞ¹÷Ìœï¹çÜsæ ;”f±Ž¤âñ/^èÀz¯‚[`Èž€$îF¬l‚ü—»0gJ´z¬lÒ‚_@U®”îzì …A$9ÂeS+²à 72>:—Yw0òß22l,<_0Ÿ³ö4¾ÃÞ:€§pG3¼7ñ++Ñ…zÏbGðR¨§K޾¤Gë︅ç*âûxôpã;X 7­k-Ô ý–q(ä‡ÕÛÂ…å_Ìð^¼Gë` ?â휵ïã2¬3€l²z&ZÛØ‰¬NqØ÷)T+Ú°]ä½9µãgçþè†OðFôŒ3ƒŒ¹V”tq¤sã¾æ®`(üÅRŽjÄéÃöDü«8®ßÂ¥2ް¤ kÅsßb:š›Â7a–2/Gt˜ÀÆ w`(ñÜ8®áÉhî7ü‰ñs(Í‹Ðø°ÌHãàì‹æÒ¾Ïó92y:Lâ/ì/Ë…²ô>ê¼€‹8ßo¯ª”ȵ~§hTØjäT½ŸàŸnÐwÝÒÅÝÀ¤ßÏóÅÙ¨dÞêïzÒï§T·îôF·­›²­^t7v©*z¨]GÓør¥ÆP&ûöK£Ø, à3|OŒÖúŸ %ÈX¨f7‹½‚Ÿ0ŒÅÀ«ê7=>ÿÇHåGpÇkà÷ÙäUÀ»ø¼b«/æn…<¢Ùq>\3ëp 5´þ1ÍO¯Ãí”ãñšYÿUÜÖü°Ò–p.\/‡‘^ou¹°=7µþ|P~¦H¢YÑìù¯×`Vñ.à$¾ê`\ó dʆ»x _ïø"éþ9·¯¬nuIEND®B`‚xterm-399/icons/xterm_48x48.xpm0000644000000000000000000000502712034404252015114 0ustar rootroot/* XPM */ static char * xterm_48x48_xpm[] = { "48 48 2 1", " c None", ". c #000000", " ", " .................................. ", " . .. ", " . ............................ . . ", " . . . . . ", " . . . . . ", " . . . . . ", " . . ... ... . . . ", " . . . . . . . ", " . . . . . . . ", " . . . . . . . ", " . . .. . . . ", " . . .. . . . ", " . . . . . . . ", " . . . . . . . ", " . . . . . . . ", " . . ... ... . . . ", " . . . . . ", " . . . . . ", " . . . . . ", " . . . . . ", " . . ..... ..... .... . . . . . ", " . . . . . . .. .. . . . ", " . . . . . . .. .. . . . ", " . . . ..... .... . . . . . . . ", " . . . . . . . ... . . . .. ", " . . . . . . . . . . . . ", " . . . ..... . . . . . . .. ", " . . . . . ", " . . . . .. ", " . . . . . ", " . ............................ ... ", " . .. ", " .................................. ", " ", " ", " .................................... ", " . .. ", " . . . . . . . . . . . . . . . . . ... ", " . . . ", " . . . . . . . . . . . . . . . . . .. . ", " . . . ", " .. . . . . . . . . . . . . . . . . .. . ", " . . . ", " .. .. .......................... .... . ", " . . . ", " ..................................... ", " "}; xterm-399/icons/mini.xterm_32x32.png0000644000000000000000000000263212034362107016012 0ustar rootroot‰PNG  IHDR szzôsRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEÜ ذr¸IDATXÃÍ—mP”UÇÏò€1®Ä[à+øŽ" –®âDƒ£8:øŠÕ0:5•S¾”Zœip²>TŽSÔ—F¿84cb8jc6šLBNˆ…†(`oÂ*°±¸»Ïé»Ë.Ë*L0ufvæ¹÷þϹÿ½çœ{ÏÿXX xz ´ž”~±ÃÐר÷$ÐB áax¬ê=ÀÈ ¥¤!˜€&=ÆÆŸ 8÷Ö9§î²Aï$x(tšó» hÅá×x×Ha{lT§ —˜ýŸ.¿pŽÀLc d³ÚM£¨ ˆ üž•^NQLRÈ®¢q‡jlüîĽbÀKöØ ©°o“ˆ{ZWÄ'ë=§t> fm.ÅÝÃÀ@©é•̈¬%ê®Y.&d”·$9ۗ奷^š¸€ Ú8Sui¶¹ÉëæÔ /L´:ëÑ ólË™Ûm‹€E’æ]é:´ó­îÖW"Ery‘h¬±‡›¶Ó%.1]Âç²Öˆ$‚šª×fÉž•Ù “ÌÍnÜ\«ƒ¶eþ ì²Gu‚·ôžÿ&e]¾DqBr÷or~ÕŠ*¦[L· ÇÄ$0UôÔI"3pH$ó©d“þ ,B€EØõð+Ï-U/­ŽùhÀFÃdêw¬«(ÚM+FþàŒ³BïuûeD×½@tœ$ƒZ€V®+mìc—rŠM†}, ¬Ä˜µä¡ äÉsܰ'2;à6‡Ù¦Ô(àr)e ½ÜtkÌó=¼ü‚;Hˆž'¨ÀB'éîÅ7”bÖò™¬¶qÝ‘ÈAÛb_m3¤‘ ßóºrÚ#Mšösšf Ç}O ’'1§2‡I\¦=Ù X¼{•#¼`¸H·4¨nñÍ‚u;y¡Ysyˆûú¬ô‘I)fLä >úä¾8.¡@¾ÒFñ16#à„ΦŽFœÂz2ÉäBÉN“ Â’M&‘ñü6R»ê^­>`+˜ðP jóy]n©½t°lÌ8IT#|a½VãkH b5acJÀIâhø}K²ÏÂDTªýø~4 lµGê:|&Ý$ÊBÙóž>©/nÈÒf1PÇnI'uÔ „ ã™DÑâ $¡RÇyy•ÀÑ=•/I!±×ë,~q“ Œ”qrÔl%š4ˆ£„Þ‚´—ÞŒ±XÃË݃E@#kÄÄÆMÀåw–“Ht¼tÑË>i¨+·‡c§¹¿ˆÒ€Û“Õψ xù½è¤L1ó!íŽñôz{à§Ø%ÅœãJ¿ DL壯]uX~Wá:÷i'³ÿÙ–…´k¸æ½ÛJ':nS䞟t,iì1/¿_¦•Lé#«g)Uö¬2¶ Z•l6-¹tÄ~E—HUîÔ\Ôr@2™é·1ñã÷oYÇÊpœ‹[õyVTÑ›4h*šBµŸª|fŒWE} Jc3lÏvþÜ_ÖM´°8%ͧ(˜èñ4‡ ãk2‰¢håN{¤ñXBjC7iü]Ð1ÔÞ¬÷ƒ£,ak®žÉ.¹[O+H‰á8'özvG®ÎHÜÝŒ˜Äß9/W“ò(â÷Ô¶£òñèp8•º}@©ÇßtvG®a)Ä{Yì–ÚÅŒÝÕÑ )±”“Â3îñ`lšowä"ð+§(NSùˆµ:)æÝjäÿ ÿ„ê” ´ïIEND®B`‚xterm-399/icons/mini.xterm.xpms0000644000000000000000000003470114763041110015355 0ustar rootroot/* $XTermId: mini.xterm.xpms,v 1.5 2025/03/08 13:12:40 tom Exp $ */ /* generated by ./make-xpms */ /* vile:xpmmode */ /* XPM */ static const char * const mini_xterm_16x16_xpm[] = { "16 16 84 1", " c None", ". c #FF3200", "+ c #FF3C00", "@ c #FF3F00", "# c #FF3B00", "$ c #FF3800", "% c #FF2000", "& c #FF1100", "* c #FF3D00", "= c #FF3900", "- c #FF2200", "; c #FF0A00", "> c #FF5D00", ", c #FF1300", "' c #FF0500", ") c #D0412F", "! c #DD6722", "~ c #DA3E25", "{ c #D84727", "] c #D03C2F", "^ c #0023F3", "/ c #000BF2", "( c #0E21E6", "_ c #4433B4", ": c #352EC3", "< c #0010F2", "[ c #0004F1", "} c #2C33CB", "| c #3E2ABA", "1 c #011EF3", "2 c #0012F3", "3 c #022DF5", "4 c #F2140D", "5 c #FF5E00", "6 c #052AF0", "7 c #0013F3", "8 c #DD4822", "9 c #002CF5", "0 c #004FF7", "a c #003AF6", "b c #1529E1", "c c #D83827", "d c #0037F7", "e c #004CF8", "f c #FF5900", "g c #182EDE", "h c #FF2100", "i c #152CE1", "j c #DD3B22", "k c #FF2300", "l c #FF2A00", "m c #0C28E9", "n c #E1571E", "o c #FF2E00", "p c #012AF4", "q c #E1661E", "r c #FF3600", "s c #FF3500", "t c #0028F4", "u c #0011F2", "v c #D64E29", "w c #FF5C00", "x c #FF2B00", "y c #FF1D00", "z c #FF2F00", "A c #000EF2", "B c #0003F1", "C c #8C4072", "D c #FF4C00", "E c #FF2D00", "F c #0360F6", "G c #0031F6", "H c #0016F3", "I c #0827EE", "J c #3D47BE", "K c #E5631A", "L c #FF4300", "M c #FF3E00", "N c #FF2400", "O c #FF0700", "P c #FF3400", "Q c #FF5700", "R c #FF5600", "S c #FF3700", " .+@#$% &$$*=- ", " ;>#, '+ ", " )!~ {] ", " ^/(_:<[}|1/2 ", " 2345=678 97 ", " 0a =>b7c de ", " fg7 ", " hg7 ", " $i7j ", " klm7no ", " # p7qr ", " sk tuvwx ", " yz ABCfDE ", " = FGHHIJKr ", " $LM$N O$PQRS- ", " "}; /* XPM */ static const char * const mini_xterm_32x32_xpm[] = { "32 32 143 2", " c None", ". c #FF0000", "+ c #FF1900", "@ c #FF1F00", "# c #FF0B00", "$ c #FF1D00", "% c #FF4A00", "& c #FF5100", "* c #FF5B00", "= c #FF5E00", "- c #FF5300", "; c #FF3600", "> c #FF0C00", ", c #FF5A00", "' c #FF5C00", ") c #FF0A00", "! c #FF0D00", "~ c #FF2E00", "{ c #FF5800", "] c #FF2700", "^ c #FF0500", "/ c #0073FB", "( c #0041F7", "_ c #0074FB", ": c #0059F9", "< c #0000F1", "[ c #0505EC", "} c #3A44BE", "| c #615A9A", "1 c #784285", "2 c #3466C8", "3 c #004DF8", "4 c #0053F8", "5 c #006CF9", "6 c #3C44BD", "7 c #2729CF", "8 c #002CF5", "9 c #2D2EC9", "0 c #8D6E71", "a c #E96416", "b c #FF4400", "c c #FF1800", "d c #0019F3", "e c #FF1400", "f c #D66729", "g c #73498A", "h c #091FEB", "i c #002CF4", "j c #006FFC", "k c #0002F1", "l c #0059F8", "m c #AD3252", "n c #FF1700", "o c #FF2B00", "p c #B84A47", "q c #0026F4", "r c #FF0700", "s c #FF1600", "t c #003FF6", "u c #0003F1", "v c #006FFA", "w c #0058F9", "x c #0055FA", "y c #FF3D00", "z c #C3363C", "A c #FF0400", "B c #FF3F00", "C c #FF1000", "D c #003DF6", "E c #005AF8", "F c #002AF4", "G c #FF0100", "H c #FF5600", "I c #C3643C", "J c #A73958", "K c #FF3100", "L c #0020F3", "M c #002DF5", "N c #0089FD", "O c #0022F4", "P c #0085FD", "Q c #C36E3C", "R c #BC3943", "S c #FF1300", "T c #007AFC", "U c #FF2200", "V c #C3693C", "W c #FF4600", "X c #C3563C", "Y c #FF1100", "Z c #BD6C42", "` c #C12F3E", " . c #B13B4E", ".. c #C32F3C", "+. c #C0283F", "@. c #C34D3C", "#. c #FF2400", "$. c #BC3E43", "%. c #C36D3C", "&. c #FF3400", "*. c #FF0800", "=. c #C36B3C", "-. c #FF4E00", ";. c #C3523C", ">. c #FF3E00", ",. c #FF1C00", "'. c #FF0200", "). c #BF3240", "!. c #FF1A00", "~. c #B4624B", "{. c #FF5900", "]. c #FF1200", "^. c #B82E47", "/. c #FF4800", "(. c #FF3A00", "_. c #001EF4", ":. c #001DF4", "<. c #7D4882", "[. c #FF4F00", "}. c #0076FB", "|. c #000CF2", "1. c #0276F9", "2. c #FF3800", "3. c #FF5D00", "4. c #004CF7", "5. c #004CF8", "6. c #FB0104", "7. c #FF5500", "8. c #B53E4A", "9. c #0055F8", "0. c #0038F6", "a. c #0028F4", "b. c #0039F6", "c. c #0254F6", "d. c #C66E39", "e. c #FF3500", "f. c #248ADB", "g. c #785587", "h. c #DE3121", "i. c #FF1E00", "j. c #FF2800", "k. c #FF5700", "l. c #FF1B00", " ", " ", " . + @ @ @ @ @ @ @ @ @ # $ . @ @ @ @ @ @ @ @ . ", " . % & & * = = = - & & ; @ > & & & , ' & & & ) ", " . . . . ! = = = ~ . . . . . . . { ] ^ . . . ", " / ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( _ ", " : < < < [ } | 1 2 3 < < < < 4 5 6 7 < < < < : ", " 8 < < 9 0 a = b c d < < d e f g h < < i ", " j k < l m n = = = o p q < < q r { ] s t < u v ", " w < x . y = = ' z q < < q A % B C D < E ", " 8 F G H = = I q < < q J K & ! L M ", " N O P r = = Q q < < q R ' S T O N ", " . U = Q q < < q V ] s ", " . W Q q < < q X Y ", " G Z q < < q ` ", " .q < < q .. ", " +.q < < q @.#. ", " $.q < < q %.+ &. ", " *.=.q < < q Q - Y ", " A -.;.q < < q Q = >.,. ", " '.; -.).q < < q Q = = U ~ ", " !., Y q < < q ~.= = {.]. ", " *., U q < < q ^., = = /.s ", " A -.(.]. _.< < :.<.C = = = ~ ] ", " '.; [.! }.|.< < |.1.. 2.= = 3.s ", " !., Y 4.< < < < 5. 6.7.= = & ]. ", " *., U 8.9.0.a.< < < < < < a.b.c.d.= = (.@ ", " A -.e.# f. g.h.= = = i.j. ", " . @ @ ,.y , Y ,.@ @ G '.@ ,.].* = = k.l.@ @ . ", " . & & & & & & & & & ) ,.& & & & & & & & & & ) ", " . . . . . . . . . . . . . . . . . . . . . . . ", " "}; /* XPM */ static const char * const mini_xterm_48x48_xpm[] = { "48 48 213 2", " c None", ". c #FF0000", "+ c #FF5300", "@ c #FF5E00", "# c #FF4800", "$ c #FF4200", "% c #FF4000", "& c #FF4B00", "* c #FF5200", "= c #FF5400", "- c #FF3500", "; c #FF5100", "> c #FF5C00", ", c #FF3000", "' c #FF4500", ") c #FF2000", "! c #FF0300", "~ c #FF1600", "{ c #FF5D00", "] c #FF3800", "^ c #FF0200", "/ c #FF0900", "( c #FF2B00", "_ c #FF3300", ": c #FF1A00", "< c #FF1300", "[ c #FF1200", "} c #FF5700", "| c #4577BA", "1 c #874E78", "2 c #887577", "3 c #887E77", "4 c #887977", "5 c #875078", "6 c #566CA9", "7 c #5E70A1", "8 c #884E77", "9 c #887677", "0 c #7C5B83", "a c #795686", "b c #008DFE", "c c #0012F3", "d c #000BF2", "e c #008FFE", "f c #006CFA", "g c #0000F1", "h c #0001F1", "i c #0020F4", "j c #0040F6", "k c #0959F0", "l c #1158E8", "m c #1159E8", "n c #0058F9", "o c #001DF4", "p c #0023F4", "q c #005BFA", "r c #0060FA", "s c #0E58EB", "t c #0651F3", "u c #0033F5", "v c #000EF2", "w c #006EFA", "x c #0092FF", "y c #001FF4", "z c #000FF2", "A c #0C51EC", "B c #326AC9", "C c #7A6583", "D c #CA6234", "E c #FC5F03", "F c #FF5800", "G c #FF0800", "H c #F4060B", "I c #007CFB", "J c #0013F3", "K c #007EFB", "L c #FF1800", "M c #F3590C", "N c #AB6152", "O c #4F4EAD", "P c #175CE4", "Q c #0036F5", "R c #0022F4", "S c #0095FD", "T c #0084FD", "U c #0004F1", "V c #0051F8", "W c #345AC7", "X c #E61519", "Y c #FF5900", "Z c #FF4600", "` c #FF0100", " . c #446EB9", ".. c #0034F6", "+. c #0032F5", "@. c #FF2200", "#. c #006FFA", "$. c #002DF5", "%. c #0086FD", "&. c #0046F7", "*. c #0015F3", "=. c #0076FC", "-. c #FF0400", ";. c #FF2300", ">. c #FF2900", ",. c #9E3E61", "'. c #0039F6", "). c #FF2A00", "!. c #FF4300", "~. c #0071FB", "{. c #005EF9", "]. c #004DF7", "^. c #008CFE", "/. c #0008F2", "(. c #001DF3", "_. c #007DFB", ":. c #FF4100", "<. c #FF5B00", "[. c #A3425C", "}. c #994C66", "|. c #FF1100", "1. c #0072FB", "2. c #000AF2", "3. c #006EFC", "4. c #0017F3", "5. c #007FFB", "6. c #FF0600", "7. c #FF5600", "8. c #A56A5A", "9. c #A53B5A", "0. c #FF4F00", "a. c #0076FB", "b. c #0076FA", "c. c #0093FF", "d. c #007DFC", "e. c #FF1C00", "f. c #A5765A", "g. c #A55D5A", "h. c #006FFB", "i. c #002CF5", "j. c #008AFD", "k. c #006BF9", "l. c #FF3A00", "m. c #FF5000", "n. c #007BFB", "o. c #008BFD", "p. c #A5755A", "q. c #9A5565", "r. c #A43A5B", "s. c #FF4D00", "t. c #80507F", "u. c #FF0F00", "v. c #7A5485", "w. c #A5555A", "x. c #FF0A00", "y. c #A53D5A", "z. c #A4515B", "A. c #A5685A", "B. c #A5735A", "C. c #FF0700", "D. c #FF2E00", "E. c #FF1500", "F. c #A3705C", "G. c #FF0500", "H. c #9A4965", "I. c #FF0E00", "J. c #FF3B00", "K. c #FF2D00", "L. c #A13C5E", "M. c #FF4C00", "N. c #62649D", "O. c #FF0B00", "P. c #FF4700", "Q. c #FF1D00", "R. c #A56D5A", "S. c #FF2C00", "T. c #A4465B", "U. c #FF1400", "V. c #A03E61", "W. c #FF3100", "X. c #FF1B00", "Y. c #FF1000", "Z. c #0029F5", "`. c #0027F4", " + c #4571BA", ".+ c #FF3900", "++ c #FF3200", "@+ c #008EFD", "#+ c #0019F3", "$+ c #0090FD", "%+ c #FF0D00", "&+ c #FF1E00", "*+ c #FF4E00", "=+ c #0088FC", "-+ c #0087FC", ";+ c #FF1900", ">+ c #0036F6", ",+ c #FF2100", "'+ c #0073FB", ")+ c #0062FA", "!+ c #001AF3", "~+ c #2463D8", "{+ c #3E58BE", "]+ c #2A7FD3", "^+ c #807B7F", "/+ c #008EFB", "(+ c #006AFA", "_+ c #004CF8", ":+ c #717B8D", "<+ c #EE0B11", "[+ c #F73E08", "}+ c #FF1F00", "|+ c #FF5500", " ", " ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . . # @ @ @ @ @ @ @ @ @ @ @ @ $ . ", " . % & & & * @ @ @ @ @ = & & & & & . . - & & & & & ; @ > & & & & , . ", " . . . . . . * @ @ @ @ ; . . . . . . . . . . . . . ' @ ) . . . . . . ", " ! ~ { @ @ @ @ ] ^ / ( @ $ . ", " ^ _ @ @ @ @ @ : ! < [ > } ^ . ", " | 1 2 3 3 3 3 4 5 6 7 8 9 3 0 a ", " b c d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d c e ", " f g g g g g g h i j k l m n o g g g g g g p q r s t u v g g g g g g g w ", " x y g g g g z A B C D E F G H I c g g g g J K L / M N O P Q h g g g g R S ", " T g g g U V W X Y @ @ @ @ Z ` ...g g g g +. ` ' @ @.. #.$.g g g g %. ", " &.g g *.=. -.;.@ @ @ @ @ >.,.'.g g g g '. / ).@ !.. ~.{.U g g ]. ", " ^./.g (._. ` :.@ @ @ @ <.[.'.g g g g '.}.|.<.} ^ . 1.2.g d e ", " 3.g 4.5. 6.7.@ @ @ @ 8.'.g g g g '.9.0.@ [ . a./.g b. ", " c.R /.d. -.e.@ @ @ @ f.'.g g g g '.g.@ - . h.h i. ", " j.k.%. ^ l.@ @ @ f.'.g g g g '.f.m.` n.f o. ", " ! * @ @ f.'.g g g g '.p.G . ", " ! ~ { @ f.'.g g g g '.q.. ", " ^ _ @ f.'.g g g g '.r. ", " ^ s.f.'.g g g g '.t. ", " ^ u.p.'.g g g g '.v. ", " ^ w.'.g g g g '.r. ", " x.y.'.g g g g '.z.^ ", " ` A.'.g g g g '.B.x.. ", " C.D.f.'.g g g g '.f.# ` ", " < E.{ F.'.g g g g '.f.@ ( ^ ", " : G.; @ H.'.g g g g '.f.@ <.I.^ ", " -.J.@ K.L.'.g g g g '.f.@ @ s.` ", " I.) @ M.. N.'.g g g g '.f.@ @ @ _ ^ ", " L O.F <.6.. '.g g g g '.f.@ @ @ { E.! ", " ^ P.@ Q.. '.g g g g '.R.@ @ @ @ * ! ", " G S.@ % . '.g g g g '.T.{ @ @ @ @ l.^ ", " < U.> 7.^ ..g g g g u V.W.@ @ @ @ @ e.! ", " X.-.m.@ Y.. Z.g g g g `. +` M.@ @ @ @ 7.6. ", " -..+@ ++. @+#+g g g g #+$+^ %+<.@ @ @ @ :.` ", " I.&+@ *+. =+h g g g g h -+ ! >.@ @ @ @ @ ;.^ ", " ;+x.} > C.. >+g g g g g g >+ ` Z @ @ @ @ Y / . ", " ` ' @ ,+. %.1.'+)+!+g g g g g g g g #+)+~+{+]+^+@ @ @ P.` ", " / ).@ !.. /+(+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+(+:+@ @ @ @ ).^ ", " I.[ > F . . <+[+@ @ @ @ <.I.` ", " . . . . . . 0.@ }+. . . . . . . . . . . . . |+@ @ @ @ s.. . . . . . ", " O.@ @ @ @ @ @ @ @ @ @ @ @ @ ^ ! $ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ $ . ", " . & & & & & & & & & & & & & . . , & & & & & & & & & & & & & & & , . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " ", " "}; static const XPM_DATA mini_xterm_xpms[] = { { "mini.xterm_16x16", mini_xterm_16x16_xpm }, { "mini.xterm_32x32", mini_xterm_32x32_xpm }, { "mini.xterm_48x48", mini_xterm_48x48_xpm } }; xterm-399/icons/xterm-color.xpms0000644000000000000000000001515014763041146015544 0ustar rootroot/* $XTermId: xterm-color.xpms,v 1.4 2025/03/08 13:13:10 tom Exp $ */ /* generated by ./make-xpms */ /* vile:xpmmode */ /* XPM */ static const char * const xterm_color_16x16_xpm[] = { "16 16 80 1", ". c None", " c #555500", "+ c #545400", "@ c #3A3A00", "# c #222200", "$ c #2A2A00", "% c #2B2B00", "& c #151500", "* c #5E5E00", "= c #5A5A00", "- c #909098", "; c #3E3E3E", "> c #000000", ", c #F2F2F2", "' c #2E2E36", ") c #343400", "! c #4C0000", "~ c #140000", "{ c #7C0000", "] c #7F7F7F", "^ c #858588", "/ c #EA0000", "( c #0B0000", "_ c #460000", ": c #8E0000", "< c #A80000", "[ c #474747", "} c #868686", "| c #404548", "1 c #8F3400", "2 c #451200", "3 c #299000", "4 c #1F6C00", "5 c #192E48", "6 c #1B3448", "7 c #888888", "8 c #CF4C00", "9 c #3B0700", "0 c #39C700", "a c #42E800", "b c #2D5181", "c c #55A3E3", "d c #305C81", "e c #989898", "f c #D84F00", "g c #3A0600", "h c #258100", "i c #376599", "j c #396D99", "k c #7E7E7E", "l c #010100", "m c #000101", "n c #9A9A9A", "o c #101000", "p c #5B5B00", "q c #3D3D00", "r c #272700", "s c #2F2F00", "t c #303000", "u c #1A1A00", "v c #464636", "w c #7A7A7F", "x c #8B8B90", "y c #1B1B00", "z c #0F0F00", "A c #FFFFFF", "B c #5B5B5B", "C c #C9C9C9", "D c #BFBFBF", "E c #B5B5B5", "F c #5C5C5C", "G c #79797F", "H c #7F7F88", "I c #484835", "J c #3C3C00", "K c #1E1E00", "L c #909090", "M c #333336", "N c #464600", "O c #575700", ".+@#$$$$$$$$%&*+", ".=-;>>>>>>>>>,')", ".=>!~{>>>>>>>>]^", ".=>>/(>>>>>>>>]]", ".=>_:<>>>>>>>>]]", ".=>>>>>>>>>>>>]]", ".=>[}|12345>6>]]", ".=>>7>890abcd>]]", ".=>>e>fgh0i>j>k^", ".=>>>l>>>>>m>>no", ".=-;>>>>>>>>>,>p", ".+qrsssssssstu*.", ".pvwwwwwwwwwwxy.", "+zABABCDDDEAFG*.", "*HBABAEDDDCBAIJ.", "KL]]]]]]]]]]MNO."}; /* XPM */ static const char * const xterm_color_32x32_xpm[] = { "32 32 60 1", ". c None", " c #FFFFFF", "+ c #000000", "@ c #EFEFEF", "# c #FEFEFE", "$ c #FBFBFB", "% c #F3F3F3", "& c #ADADAD", "* c #909090", "= c #737373", "- c #D2D2D2", "; c #646464", "> c #9A9A9A", ", c #8D8D8D", "' c #D3D3D3", ") c #0E0E0E", "! c #F6F6F6", "~ c #5E5E5E", "{ c #B1B1B1", "] c #777777", "^ c #949494", "/ c #757575", "( c #C4C4C4", "_ c #E7E7E7", ": c #F1F1F1", "< c #F8F8F8", "[ c #EEEEEE", "} c #F0F0F0", "| c #FAFAFA", "1 c #7B7B7B", "2 c #3D3D3D", "3 c #868686", "4 c #4F4F4F", "5 c #ABABAB", "6 c #545454", "7 c #5B5B5B", "8 c #AFAFAF", "9 c #292929", "0 c #181818", "a c #C7C7C7", "b c #CFCFCF", "c c #7F7F7F", "d c #A3A3A3", "e c #4D4D4D", "f c #6A6A6A", "g c #A1A1A1", "h c #8E8E8E", "i c #696969", "j c #474747", "k c #5A5A5A", "l c #959595", "m c #767676", "n c #8B8B8B", "o c #BCBCBC", "p c #BFBFBF", "q c #D7D7D7", "r c #404040", "s c #636363", "t c #989898", "u c #8A8A8A", "................................", ".....+++++++++++++++++++++++....", "....+..+++++++++++++++++++..++..", "....+.+...................+.+.+.", "....++.@#.$%................+..+", "....++.&*.=-................+..+", "....++..;>,.................+..+", "....++..')!.................+..+", "....++.#~{].................+..+", "....++.^{./(................+..+", "....++......................+..+", "....++......................+..+", "....++.____:___<_[..<}..[|..+..+", "....++.1;21341156]7.89$:0a..+..+", "....++..bc.8^__8d.e.8fghia..+..+", "....++..bc.84115jkl.887mna..+..+", "....++..bc.8d..8dof.88pqna..+..+", "....++..bc.8rss5d.tu88..na..+...", "....++......................+.+.", "....++......................+.+.", "....+.+...................+.++..", "....+..+++++++++++++++++++..+...", ".....+++++++++++++++++++++++....", "................................", ".....++++++++++++++++++++++++...", "....+.......................+...", "...+.......................+....", "...+..++..++.++..++..+..++.+....", "....++..++..+..++..++.++........", "..+.......................+.+...", ".+.......................+......", ".++++++++++++++++++++++++++....."}; /* XPM */ static const char * const xterm_color_48x48_xpm[] = { "48 48 10 1", ". c None", " c #555500", "+ c #000000", "@ c #FFFFFF", "# c #FF0000", "$ c #070700", "% c #0B0B00", "& c #FF8400", "* c #49FF00", "= c #60B7FF", "................................................", "......++++++++++++++++++++++++++++++++++........", ".....+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++......", ".....+@@@++++++++++++++++++++++++++++@@@+@+.....", ".....+@@++++++++++++++++++++++++++++++@@+@@+....", ".....+@++++++++++++++++++++++++++++++++@+@@@+...", ".....+@++###++++###++++++++++++++++++++@+@@@@+..", ".....+@+++##++++##+++++++++++++++++++++@+@@@@+..", ".....+@++++##++##++++++++++++++++++++++@+@@@@+..", ".....+@++++##++##++++++++++++++++++++++@+@@@@+..", ".....+@+++++####+++++++++++++++++++++++@+@@@@+..", ".....+@+++++####+++++++++++++++++++++++@+@@@@+..", ".....+@++++++##++++++++++++++++++++++++@+@@@@+..", ".....+@+++++####+++++++++++++++++++++++@+@@@@+..", ".....+@+++++####+++++++++++++++++++++++@+@@@@+..", ".....+@++++##++##++++++++++++++++++++++@+@@@@+..", ".....+@++++##++##++++++++++++++++++++++@+@@@@+..", ".....+@+++##++++##+++++++++++++++++++++@+@@@@+..", ".....+@++###++++###++++++++++++++++++++@+@@@@+..", ".....+@++++++++++++++++++++++++++++++++@+@@@@+..", ".....+@$+++++++++++++++++++++++++++++++@+@@@@+..", ".....+@%@@@@@@@+&&&&&++****+++==+++==++@+@@@@+..", ".....+@++++@++++&++++++*+++*++==+++==++@+@@@@+..", ".....+@++++@++++&++++++*+++*++=+=+=+=++@+@@@@+..", ".....+@++++@++++&&&&+++****+++=+=+=+=++@+@@@@+..", ".....+@++++@++++&++++++*+*++++=++=++=++@+@@@+...", ".....+@++++@++++&++++++*++*+++=++=++=++@+@@@+...", ".....+@++++@++++&&&&&++*+++*++=+++++=++@+@@+....", ".....+@++++++++++++++++++++++++++++++++@+@@+....", ".....+@++++++++++++++++++++++++++++++++@+@+.....", ".....+@@++++++++++++++++++++++++++++++@@+@+.....", ".....+@@@++++++++++++++++++++++++++++@@@++......", ".....+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++......", "......++++++++++++++++++++++++++++++++++........", "................................................", "................................................", "......++++++++++++++++++++++++++++++++++++......", ".....+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++......", ".....+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@@++......", "....+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@+......", "....+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@@+@+......", "...+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@@+......", "...+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@+@@+@@+......", "..+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@@+.......", "..+@++@++++++++++++++++++++++++++@++@+@+........", ".+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@+.........", ".+++++++++++++++++++++++++++++++++++++..........", "................................................"}; static const XPM_DATA xterm_color_xpms[] = { { "xterm-color_16x16", xterm_color_16x16_xpm }, { "xterm-color_32x32", xterm_color_32x32_xpm }, { "xterm-color_48x48", xterm_color_48x48_xpm } }; xterm-399/icons/filled-xterm_16x16.xpm0000644000000000000000000000454212034404216016340 0ustar rootroot/* XPM */ static char * filled_xterm_16x16_xpm[] = { "16 16 110 2", " c None", ". c #BAA9A9", "+ c #C59C9C", "@ c #C49999", "# c #C6AAAA", "$ c #4D4242", "% c #F0E4E4", "& c #CEBABA", "* c #D5BEBE", "= c #C6B5B5", "- c #CEBEBE", "; c #796D6D", "> c #DEC5C5", ", c #B19B9B", "' c #C6B8B8", ") c #B19696", "! c #EBE5E5", "~ c #FFFFFF", "{ c #D6D6D6", "] c #D0BDBD", "^ c #FFF4F4", "/ c #FEFDFD", "( c #706969", "_ c #CCC3C3", ": c #FFF0F0", "< c #978989", "[ c #A9A5A5", "} c #A7A3A3", "| c #E3E1E1", "1 c #DACBCB", "2 c #DEDEDE", "3 c #FFF8F8", "4 c #FFF6F6", "5 c #FFFCFC", "6 c #FFFEFE", "7 c #D2D2D2", "8 c #9C9C9C", "9 c #9B8787", "0 c #B3A0A0", "a c #FFD5D5", "b c #D4C2C2", "c c #FFE7E7", "d c #7A6F6F", "e c #786F6F", "f c #C2C2C2", "g c #B4B4B4", "h c #FFE3E3", "i c #E1CECE", "j c #FED8D8", "k c #908888", "l c #878080", "m c #898383", "n c #F3ECEC", "o c #D8C2C2", "p c #FFFAFA", "q c #FFF2F2", "r c #FFF9F9", "s c #EFEFEF", "t c #FEFEFE", "u c #C8C3C3", "v c #D2BFBF", "w c #8A8383", "x c #FCE5E5", "y c #D9B6B6", "z c #DDBCBC", "A c #BCA0A0", "B c #F0D2D2", "C c #AB9C9C", "D c #000000", "E c #B0A2A2", "F c #AE9F9F", "G c #C6ABAB", "H c #B48E8E", "I c #C8ABAB", "J c #C39A9A", "K c #D0B2B2", "L c #C3A0A0", "M c #CFB2B2", "N c #C59999", "O c #CCC1C1", "P c #3C3535", "Q c #A39C9C", "R c #FAEDED", "S c #FEFCFC", "T c #F9F2F2", "U c #FEF7F7", "V c #FAEBEB", "W c #FEFAFA", "X c #F9F1F1", "Y c #FEF4F4", "Z c #FAEFEF", "` c #EBE0E0", " . c #DFB9B9", ".. c #E8E3E3", "+. c #BBB0B0", "@. c #BBA9A9", "#. c #CEC8C8", "$. c #BCADAD", "%. c #CDC8C8", "&. c #C78D8D", "*. c #E3B2B2", "=. c #E3BCBC", "-. c #BBAAAA", ";. c #746C6C", ">. c #858585", ",. c #8A7F7F", "'. c #977878", "). c #A38686", "!. c #A78686", "~. c #201717", " . + @ @ @ @ @ @ @ @ # $ ", " % & * * * * * * * * = - ; ", " > , ' ) ! ~ ~ ~ ~ ~ { ] ^ ", " > / ( _ ~ ~ ~ ~ ~ ~ { ] : ", " > ~ < [ ~ ~ ~ ~ ~ ~ { ] : ", " > } | 1 2 ~ ~ ~ ~ ~ { ] : ", " > ~ ~ 3 ~ 4 4 5 6 4 7 ] : ", " > 7 8 9 0 a b c d e f ] : ", " > ~ g h i j k c l m f ] n ", " o ~ ~ p ~ q 6 r s t u v w ", " x y z z z z z z A z B C ", " D ", " E F G H I J K L M N O P ", " Q R S T U V W X Y Z U ` Q ", " ...+._ @.#.$.%.&.*.=.-.;. ", " >.>.>.,.'.).).).).).!.~. "}; xterm-399/graphics.h0000644000000000000000000001524714773460577013243 0ustar rootroot/* $XTermId: graphics.h,v 1.33 2025/04/03 10:22:55 tom Exp $ */ /* * Copyright 2013-2023,2025 by Thomas E. Dickey * Copyright 2013-2022,2023 by Ross Combs * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #ifndef included_graphics_h #define included_graphics_h /* *INDENT-OFF* */ #include #if OPT_GRAPHICS #define CHANNEL_MAX 100 typedef struct { short r, g, b; } ColorRegister; typedef unsigned short RegisterNum; #define MAX_COLOR_REGISTERS 0x400 /* 1024U */ #define COLOR_HOLE 0x404 /* bytable above MAX_COLOR_REGISTERS */ #define MAX_GRAPHICS 16U #define ClrSpixel(graphic, cell) \ do { \ (graphic)->pixels[cell] = COLOR_HOLE; \ } while (0) #define SetSpixel(graphic, cell, value) \ do { \ (graphic)->pixels[cell] = value; \ } while (0) typedef struct { RegisterNum *pixels; ColorRegister *private_color_registers; ColorRegister *color_registers; Boolean color_registers_used[MAX_COLOR_REGISTERS]; XtermWidget xw; int max_width; /* largest image which can be stored */ int max_height; /* largest image which can be stored */ unsigned valid_registers; /* for wrap-around behavior */ int actual_width; /* size of image before scaling */ int actual_height; /* size of image before scaling */ int private_colors; /* if not using the shared color registers */ int charrow; /* upper left starting point in characters */ int charcol; /* upper left starting point in characters */ int pixw; /* width of graphic pixels in screen pixels */ int pixh; /* height of graphic pixels in screen pixels */ int bufferid; /* which screen buffer the graphic is associated with */ unsigned type; /* type of graphic 0==sixel, 1...NUM_REGIS_PAGES==ReGIS page */ unsigned id; /* sequential id used for preserving layering */ Boolean valid; /* if the graphic has been initialized */ Boolean dirty; /* if the graphic needs to be redrawn */ Boolean hidden; /* if the graphic should not be displayed */ } Graphic; extern Graphic *get_new_graphic(XtermWidget /* xw */, int /* charrow */, int /* charcol */, unsigned /* type */); extern Graphic *get_new_or_matching_graphic(XtermWidget /* xw */, int /* charrow */, int /* charcol */, int /* actual_width */, int /* actual_height */, unsigned /* type */); extern RegisterNum read_pixel(Graphic */* graphic */, int /* x */, int /* y */); extern void draw_solid_pixel(Graphic */* graphic */, int /* x */, int /* y */, unsigned /* color */); extern void draw_solid_rectangle(Graphic */* graphic */, int /* x1 */, int /* y1 */, int /* x2 */, int /* y2 */, unsigned /* color */); extern void copy_overlapping_area(Graphic */* graphic */, int /* src_x */, int /* src_y */, int /* dst_x */, int /* dst_y */, unsigned /* w */, unsigned /* h */, unsigned /* default_color */); extern void hls2rgb(int /* h */, int /* l */, int /* s */, short */* r */, short */* g */, short */* b */); extern void rgb2hls(int /* r */, int /* g */, int /* b */, short */* h */, short */* l */, short */* s */); extern void dump_graphic(Graphic const */* graphic */); extern unsigned get_color_register_count(TScreen const */* screen */); extern void fetch_color_register(Graphic */* graphic */, unsigned /* color */, ColorRegister* /* reg */); extern void update_color_register(Graphic */* graphic */, unsigned /* color */, int /* r */, int /* g */, int /* b */); extern RegisterNum find_color_register(ColorRegister const */* color_registers */, int /* r */, int /* g */, int /* b */); extern void chararea_clear_displayed_graphics(TScreen const */* screen */, int /* leftcol */, int /* toprow */, int /* ncols */, int /* nrows */); extern void refresh_displayed_graphics(XtermWidget /* xw */, int /* leftcol */, int /* toprow */, int /* ncols */, int /* nrows */); extern void refresh_modified_displayed_graphics(XtermWidget /* xw */); extern void reset_displayed_graphics(TScreen const */* screen */); extern void scroll_displayed_graphics(XtermWidget /* xw */, int /* rows */); #ifdef NO_LEAKS extern void noleaks_graphics(Display */* dpy */); #endif #else #define get_new_graphic(xw, charrow, charcol, type) /* nothing */ #define get_new_or_matching_graphic(xw, charrow, charcol, actual_width, actual_height, type) /* nothing */ #define read_pixel(graphic, x, y) /* nothing */ #define draw_solid_pixel(graphic, x, y, color) /* nothing */ #define draw_solid_rectangle(graphic, x1, y1, x2, y2, color) /* nothing */ #define copy_overlapping_area(graphic, src_x, src_y, dst_x, dst_y, w, h, default_color) /* nothing */ #define hls2rgb(h, l, s, r, g, b) /* nothing */ #define rgb2hls(r, g, b, h, l, s) /* nothing */ #define dump_graphic(graphic) /* nothing */ #define get_color_register_count(screen) /* nothing */ #define update_color_register(graphic, color, r, g, b) /* nothing */ #define find_color_register(color_registers, r, g, b) /* nothing */ #define chararea_clear_displayed_graphics(screen, leftcol, toprow, ncols, nrows) /* nothing */ #define refresh_displayed_graphics(xw, leftcol, toprow, ncols, nrows) /* nothing */ #define refresh_modified_displayed_graphics(xw) /* nothing */ #define reset_displayed_graphics(screen) /* nothing */ #define scroll_displayed_graphics(xw, rows) /* nothing */ #endif /* *INDENT-ON* */ #endif /* included_graphics_h */ xterm-399/plink.sh0000755000000000000000000000533414213433621012715 0ustar rootroot#!/bin/sh # $XTermId: plink.sh,v 1.17 2022/03/13 18:27:29 Ryan.Schmidt Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2001-2021,2022 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # # Reduce the number of dynamic libraries used to link an executable. LINKIT= ASNEED=no NO_LTO= # gcc's link-time optimization is very slow - reduce usage of that. case "$*" in *-flto=*|-flto\ ) NO_LTO=-fno-lto ;; esac : "${TMPDIR=/tmp}" while [ $# != 0 ] do if [ $ASNEED = no ] && [ -n "$LINKIT" ] then ASNEED=yes OPT=-Wl,-as-needed warned=`mktemp "$TMPDIR/xterm.XXXXXXXX"` trap "rm -f $warned; exit 1" 1 2 3 15 trap "rm -f $warned" 0 if ( eval $LINKIT $OPT $NO_LTO "$@" >"$warned" 2>&1 ) then WARNED=`cat "$warned"` rm -f "$warned" case ".$WARNED" in *Warning*|*nsupported*|*nrecognized*|*nknown*) ;; *) LINKIT="$LINKIT $OPT $*" break ;; esac else rm -f "$warned" fi fi OPT="$1" shift case $OPT in -k*) OPT=`echo "$OPT" | sed -e 's/^-k/-l/'` echo "always use $OPT (cannot test if needed)" LINKIT="$LINKIT $OPT" ;; -l*) echo "testing if $OPT is needed" if ( eval $LINKIT $NO_LTO "$@" >/dev/null 2>&1 ) then : echo ...no else echo ...yes LINKIT="$LINKIT $OPT" fi ;; *) LINKIT="$LINKIT $OPT" ;; esac done eval $LINKIT xterm-399/fontutils.c0000644000000000000000000050102514774607546013457 0ustar rootroot/* $XTermId: fontutils.c,v 1.790 2025/04/06 23:33:58 tom Exp $ */ /* * Copyright 1998-2024,2025 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ /* * A portion of this module (for FontNameProperties) was adapted from EMU 1.3; * it constructs font names with specific properties changed, e.g., for bold * and double-size characters. */ #define RES_OFFSET(field) XtOffsetOf(SubResourceRec, field) #include #include #include #include #include #include #include #include #include #include #include #define USE_FC_COLOR 0 #if OPT_RENDERFONT #if XftVersion > 20304 #undef USE_FC_COLOR #define USE_FC_COLOR 1 #endif #endif #define FcOK(func) (func == FcResultMatch) #define NoFontWarning(data) (data)->warn = fwAlways #define SetFontWidth(screen,dst,src) (dst)->f_width = (src) #define SetFontHeight(screen,dst,src) (dst)->f_height = dimRound((double)((screen)->scale_height * (float) (src))) /* from X11/Xlibint.h - not all vendors install this file */ #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \ (((cs)->rbearing|(cs)->lbearing| \ (cs)->ascent|(cs)->descent) == 0)) #define CI_GET_CHAR_INFO_1D(fs,col,cs) \ { \ cs = NULL; \ if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ if (fs->per_char == NULL) { \ cs = &fs->min_bounds; \ } else { \ cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \ } \ if (CI_NONEXISTCHAR(cs)) cs = NULL; \ } \ } #define CI_GET_CHAR_INFO_2D(fs,row,col,cs) \ { \ cs = NULL; \ if (row >= fs->min_byte1 && row <= fs->max_byte1 && \ col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ if (fs->per_char == NULL) { \ cs = &fs->min_bounds; \ } else { \ cs = &fs->per_char[((row - fs->min_byte1) * \ (fs->max_char_or_byte2 - \ fs->min_char_or_byte2 + 1)) + \ (col - fs->min_char_or_byte2)]; \ } \ if (CI_NONEXISTCHAR(cs)) cs = NULL; \ } \ } #define FREE_FNAME(field) \ if (fonts == NULL || new_fnames.field != fonts->field) { \ FREE_STRING(new_fnames.field); \ new_fnames.field = NULL; \ } /* * A structure to hold the relevant properties from a font * we need to make a well formed font name for it. */ typedef struct { /* registry, foundry, family */ const char *beginning; /* weight */ const char *weight; /* slant */ const char *slant; /* wideness */ const char *wideness; /* add style */ const char *add_style; int pixel_size; const char *point_size; int res_x; int res_y; const char *spacing; int average_width; /* charset registry, charset encoding */ char *end; } FontNameProperties; #if OPT_WIDE_CHARS && (OPT_RENDERFONT || (OPT_TRACE > 1)) #define MY_UCS(code,high,wide,name) { code, high, wide, #name } static const struct { unsigned code, high, wide; const char *name; } unicode_boxes[] = { MY_UCS(0x2500, 0, 1, box drawings light horizontal), MY_UCS(0x2502, 1, 0, box drawings light vertical), MY_UCS(0x250c, 2, 2, box drawings light down and right), MY_UCS(0x2510, 2, 2, box drawings light down and left), MY_UCS(0x2514, 2, 2, box drawings light up and right), MY_UCS(0x2518, 2, 2, box drawings light up and left), MY_UCS(0x251c, 1, 2, box drawings light vertical and right), MY_UCS(0x2524, 1, 2, box drawings light vertical and left), MY_UCS(0x252c, 2, 1, box drawings light down and horizontal), MY_UCS(0x2534, 2, 1, box drawings light up and horizontal), MY_UCS(0x253c, 1, 1, box drawings light vertical and horizontal), { 0, 0, 0, NULL } }; #undef MY_UCS #endif /* OPT_WIDE_CHARS */ #if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS static Boolean merge_sublist(char ***, char **); #endif static void save2FontList(XtermWidget, const char *, XtermFontNames *, VTFontEnum, const char *, Bool, Bool); #if OPT_RENDERFONT static void fillInFaceSize(XtermWidget, int); #endif #if OPT_REPORT_FONTS && OPT_TRACE static void report_fonts(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stdout, fmt, ap); va_end(ap); #if OPT_TRACE va_start(ap, fmt); TraceVA(fmt, ap); va_end(ap); #endif } #define ReportFonts report_fonts #else #define ReportFonts printf #endif #if OPT_TRACE static void set_font_height(TScreen *screen, VTwin *win, int height) { SetFontHeight(screen, win, height); TRACE(("SetFontHeight %d\n", win->f_height)); #undef SetFontHeight #define SetFontHeight(screen, win, height) set_font_height(screen, win, height) } static void set_font_width(TScreen *screen, VTwin *win, int width) { (void) screen; SetFontWidth(screen, win, width); TRACE(("SetFontWidth %d\n", win->f_width)); #undef SetFontWidth #define SetFontWidth(screen, win, width) set_font_width(screen, win, width) } #endif #if OPT_REPORT_FONTS || OPT_WIDE_CHARS static unsigned countGlyphs(XFontStruct *fp) { unsigned count = 0; if (fp != NULL) { if (fp->min_byte1 == 0 && fp->max_byte1 == 0) { count = fp->max_char_or_byte2 - fp->min_char_or_byte2 + 1; } else if (fp->min_char_or_byte2 < 256 && fp->max_char_or_byte2 < 256) { unsigned first = (fp->min_byte1 << 8) + fp->min_char_or_byte2; unsigned last = (fp->max_byte1 << 8) + fp->max_char_or_byte2; count = last + 1 - first; } } return count; } #endif #if OPT_WIDE_CHARS /* * Verify that the wide-bold font is at least a bold font with roughly as many * glyphs as the wide font. The counts should be the same, but settle for * filtering out the worst of the font mismatches. */ static Bool compatibleWideCounts(XFontStruct *wfs, XFontStruct *wbfs) { unsigned count_w = countGlyphs(wfs); unsigned count_wb = countGlyphs(wbfs); if (count_w <= 256 || count_wb <= 256 || ((count_w / 4) * 3) > count_wb) { TRACE(("...font server lied (count wide %u vs wide-bold %u)\n", count_w, count_wb)); return False; } return True; } #endif /* OPT_WIDE_CHARS */ #if OPT_BOX_CHARS static void setupPackedFonts(XtermWidget xw) { TScreen *screen = TScreenOf(xw); Bool value = False; #if OPT_RENDERFONT if (xw->work.render_font == True) { int e; for (e = 0; e < fMAX; ++e) { XTermXftFonts *data = getMyXftFont(xw, e, screen->menu_font_number); if (data != NULL) { if (data->font_info.mixed) { screen->allow_packing = True; break; } } } } #endif /* OPT_RENDERFONT */ value = screen->allow_packing; SetItemSensitivity(fontMenuEntries[fontMenu_font_packedfont].widget, value); } #endif typedef struct _nameList { struct _nameList *next; char *name; } NameList; static NameList *derived_fonts; static Boolean is_derived_font_name(const char *name) { Boolean result = False; NameList *list; if (!IsEmpty(name)) { for (list = derived_fonts; list != NULL; list = list->next) { if (!x_strcasecmp(name, list->name)) { result = True; break; } } } return result; } void xtermDerivedFont(const char *name) { if (!IsEmpty(name) && !is_derived_font_name(name)) { NameList *list = TypeCalloc(NameList); list->name = x_strdup(name); list->next = derived_fonts; derived_fonts = list; } } /* * Returns the fields from start to stop in a dash- separated string. This * function will modify the source, putting '\0's in the appropriate place and * moving the beginning forward to after the '\0' * * This will NOT work for the last field (but we won't need it). */ static char * n_fields(char **source, int start, int stop) { int i; char *str, *str1; /* * find the start-1th dash */ for (i = start - 1, str = *source; i; i--, str++) { if ((str = strchr(str, '-')) == NULL) return NULL; } /* * find the stopth dash */ for (i = stop - start + 1, str1 = str; i; i--, str1++) { if ((str1 = strchr(str1, '-')) == NULL) return NULL; } /* * put a \0 at the end of the fields */ *(str1 - 1) = '\0'; /* * move source forward */ *source = str1; return str; } static Boolean check_fontname(const char *name) { Boolean result = True; if (IsEmpty(name)) { TRACE(("fontname missing\n")); result = False; } return result; } /* * Gets the font properties from a given font structure. We use the FONT name * to find them out, since that seems easier. * * Returns a pointer to a static FontNameProperties structure * or NULL on error. */ static FontNameProperties * get_font_name_props(Display *dpy, XFontStruct *fs, char **result) { static FontNameProperties props; static char *last_name; Atom fontatom; char *name; char *str; if (fs == NULL) return NULL; /* * first get the full font name */ name = NULL; fontatom = CachedInternAtom(dpy, "FONT"); if (fontatom != 0) { XFontProp *fp; int i; for (i = 0, fp = fs->properties; i < fs->n_properties; i++, fp++) { if (fp->name == fontatom) { name = XGetAtomName(dpy, fp->card32); break; } } } if (name == NULL) return NULL; /* * XGetAtomName allocates memory - don't leak */ XFree(last_name); last_name = name; if (result != NULL) { if (!check_fontname(name)) return NULL; free(*result); *result = x_strdup(name); } /* * Now split it up into parts and put them in * their places. Since we are using parts of * the original string, we must not free the Atom Name */ /* registry, foundry, family */ if ((props.beginning = n_fields(&name, 1, 3)) == NULL) return NULL; /* weight is the next */ if ((props.weight = n_fields(&name, 1, 1)) == NULL) return NULL; /* slant */ if ((props.slant = n_fields(&name, 1, 1)) == NULL) return NULL; /* width */ if ((props.wideness = n_fields(&name, 1, 1)) == NULL) return NULL; /* add style */ if ((props.add_style = n_fields(&name, 1, 1)) == NULL) return NULL; /* pixel size */ if ((str = n_fields(&name, 1, 1)) == NULL) return NULL; if ((props.pixel_size = atoi(str)) == 0) return NULL; /* point size */ if ((props.point_size = n_fields(&name, 1, 1)) == NULL) return NULL; /* res_x */ if ((str = n_fields(&name, 1, 1)) == NULL) return NULL; if ((props.res_x = atoi(str)) == 0) return NULL; /* res_y */ if ((str = n_fields(&name, 1, 1)) == NULL) return NULL; if ((props.res_y = atoi(str)) == 0) return NULL; /* spacing */ if ((props.spacing = n_fields(&name, 1, 1)) == NULL) return NULL; /* average width */ if ((str = n_fields(&name, 1, 1)) == NULL) return NULL; if ((props.average_width = atoi(str)) == 0) return NULL; /* the rest: charset registry and charset encoding */ props.end = name; return &props; } #define ALLOCHUNK(n) ((n | 127) + 1) static void alloca_fontname(char **result, size_t next) { size_t last = (*result != NULL) ? strlen(*result) : 0; size_t have = (*result != NULL) ? ALLOCHUNK(last) : 0; size_t want = last + next + 2; if (want >= have) { char *save = *result; want = ALLOCHUNK(want); if (last != 0) { *result = TypeRealloc(char, want, *result); if (*result == NULL) free(save); } else { if ((*result = TypeMallocN(char, want)) != NULL) { free(save); **result = '\0'; } } } } static void append_fontname_str(char **result, const char *value) { if (value == NULL) value = "*"; alloca_fontname(result, strlen(value)); if (*result != NULL) { if (**result != '\0') strcat(*result, "-"); strcat(*result, value); } } static void append_fontname_num(char **result, int value) { if (value < 0) { append_fontname_str(result, "*"); } else { char temp[100]; sprintf(temp, "%d", value); append_fontname_str(result, temp); } } /* * Take the given font props and try to make a well formed font name specifying * the same base font and size and everything, but with different weight/width * according to the parameters. The return value is allocated, should be freed * by the caller. */ static char * derive_font_name(FontNameProperties *props, const char *use_weight, int use_average_width, const char *use_encoding) { char *result = NULL; append_fontname_str(&result, props->beginning); append_fontname_str(&result, use_weight); append_fontname_str(&result, props->slant); append_fontname_str(&result, NULL); append_fontname_str(&result, NULL); append_fontname_num(&result, props->pixel_size); append_fontname_str(&result, props->point_size); append_fontname_num(&result, props->res_x); append_fontname_num(&result, props->res_y); append_fontname_str(&result, props->spacing); append_fontname_num(&result, use_average_width); append_fontname_str(&result, use_encoding); xtermDerivedFont(result); return result; } static char * bold_font_name(FontNameProperties *props, int use_average_width) { return derive_font_name(props, "bold", use_average_width, props->end); } #if OPT_WIDE_ATTRS static char * italic_font_name(FontNameProperties *props, const char *slant) { FontNameProperties myprops = *props; myprops.slant = slant; return derive_font_name(&myprops, props->weight, myprops.average_width, props->end); } static Boolean open_italic_font(XtermWidget xw, int n, FontNameProperties *fp, XTermFonts * data) { static const char *const slant[] = { "o", "i" }; Cardinal pass; Boolean result = False; NoFontWarning(data); for (pass = 0; pass < XtNumber(slant); ++pass) { char *name; if ((name = italic_font_name(fp, slant[pass])) != NULL) { TRACE(("open_italic_font %s %s\n", whichFontEnum((VTFontEnum) n), name)); if (xtermOpenFont(xw, name, data, NULL, False)) { result = (data->fs != NULL); #if OPT_REPORT_FONTS if (resource.reportFonts) { ReportFonts("opened italic version of %s:\n\t%s\n", whichFontEnum((VTFontEnum) n), name); } #endif } free(name); if (result) break; } } #if OPT_TRACE if (result) { XFontStruct *fs = data->fs; if (fs != NULL) { TRACE(("...actual size %dx%d (ascent %d, descent %d)\n", fs->ascent + fs->descent, fs->max_bounds.width, fs->ascent, fs->descent)); } } #endif return result; } #endif #if OPT_WIDE_CHARS #define derive_wide_font(props, weight) \ derive_font_name(props, weight, props->average_width * 2, "ISO10646-1") static char * wide_font_name(FontNameProperties *props) { return derive_wide_font(props, "medium"); } static char * widebold_font_name(FontNameProperties *props) { return derive_wide_font(props, "bold"); } #endif /* OPT_WIDE_CHARS */ #if OPT_DEC_CHRSET /* * Take the given font props and try to make a well formed font name specifying * the same base font but changed depending on the given attributes and chrset. * * For double width fonts, we just double the X-resolution, for double height * fonts we double the pixel-size and Y-resolution */ char * xtermSpecialFont(XTermDraw * params) { TScreen *screen = TScreenOf(params->xw); #if OPT_TRACE static char old_spacing[80]; static FontNameProperties old_props; #endif FontNameProperties *props; char *result = NULL; const char *weight; int pixel_size; int res_x; int res_y; props = get_font_name_props(screen->display, GetNormalFont(screen, fNorm)->fs, NULL); if (props == NULL) return result; pixel_size = props->pixel_size; res_x = props->res_x; res_y = props->res_y; if (params->attr_flags & BOLD) weight = "bold"; else weight = props->weight; if (CSET_DOUBLE(params->this_chrset)) res_x *= 2; if (params->this_chrset == CSET_DHL_TOP || params->this_chrset == CSET_DHL_BOT) { res_y *= 2; pixel_size *= 2; } #if OPT_TRACE if (old_props.res_x != res_x || old_props.res_x != res_y || old_props.pixel_size != pixel_size || strcmp(old_props.spacing, props->spacing)) { TRACE(("xtermSpecialFont(atts = %#x, draw = %#x, chrset = %#x)\n", params->attr_flags, params->draw_flags, params->this_chrset)); TRACE(("res_x = %d\n", res_x)); TRACE(("res_y = %d\n", res_y)); TRACE(("point_size = %s\n", props->point_size)); TRACE(("pixel_size = %d\n", pixel_size)); TRACE(("spacing = %s\n", props->spacing)); old_props.res_x = res_x; old_props.res_y = res_y; old_props.pixel_size = pixel_size; old_props.spacing = old_spacing; sprintf(old_spacing, "%.*s", (int) sizeof(old_spacing) - 2, props->spacing); } #endif append_fontname_str(&result, props->beginning); append_fontname_str(&result, weight); append_fontname_str(&result, props->slant); append_fontname_str(&result, props->wideness); append_fontname_str(&result, props->add_style); append_fontname_num(&result, pixel_size); append_fontname_str(&result, props->point_size); append_fontname_num(&result, (params->draw_flags & NORESOLUTION) ? -1 : res_x); append_fontname_num(&result, (params->draw_flags & NORESOLUTION) ? -1 : res_y); append_fontname_str(&result, props->spacing); append_fontname_str(&result, NULL); append_fontname_str(&result, props->end); xtermDerivedFont(result); return result; } #endif /* OPT_DEC_CHRSET */ /* * Case-independent comparison for font-names, including wildcards. * XLFD allows '?' as a wildcard, but we do not handle that (no one seems * to use it). */ static Bool same_font_name(const char *pattern, const char *match) { Bool result = False; if (pattern && match) { while (*pattern && *match) { if (*pattern == *match) { pattern++; match++; } else if (*pattern == '*' || *match == '*') { if (same_font_name(pattern + 1, match)) { return True; } else if (same_font_name(pattern, match + 1)) { return True; } else { return False; } } else { int p = x_toupper(*pattern++); int m = x_toupper(*match++); if (p != m) return False; } } result = (*pattern == *match); /* both should be NUL */ } return result; } /* * Double-check the fontname that we asked for versus what the font server * actually gave us. The larger fixed fonts do not always have a matching bold * font, and the font server may try to scale another font or otherwise * substitute a mismatched font. * * If we cannot get what we requested, we will fallback to the original * behavior, which simulates bold by overstriking each character at one pixel * offset. */ static int got_bold_font(Display *dpy, XFontStruct *fs, String requested) { char *actual = NULL; int got; if (get_font_name_props(dpy, fs, &actual) == NULL) got = 0; else got = same_font_name(requested, actual); free(actual); return got; } /* * Check normal/bold (or wide/wide-bold) font pairs to see if we will be able * to check for missing glyphs in a comparable manner. */ static int comparable_metrics(XFontStruct *normal, XFontStruct *bold) { #define DATA "comparable_metrics: " int result = 0; if (normal == NULL || bold == NULL) { ; } else if (normal->all_chars_exist) { if (bold->all_chars_exist) { result = 1; } else { TRACE((DATA "all chars exist in normal font, but not in bold\n")); } } else if (normal->per_char != NULL) { if (bold->per_char != NULL) { result = 1; } else { TRACE((DATA "normal font has per-char metrics, but not bold\n")); } } else { TRACE((DATA "normal font is not very good!\n")); result = 1; /* give in (we're not going in reverse) */ } return result; #undef DATA } /* * If the font server tries to adjust another font, it may not adjust it * properly. Check that the bounding boxes are compatible. Otherwise we'll * leave trash on the display when we mix normal and bold fonts. */ static int same_font_size(XtermWidget xw, XFontStruct *nfs, XFontStruct *bfs) { TScreen *screen = TScreenOf(xw); int result = 0; if (nfs != NULL && bfs != NULL) { TRACE(("same_font_size height %d/%d, min %d/%d max %d/%d\n", nfs->ascent + nfs->descent, bfs->ascent + bfs->descent, nfs->min_bounds.width, bfs->min_bounds.width, nfs->max_bounds.width, bfs->max_bounds.width)); result = screen->free_bold_box || ((nfs->ascent + nfs->descent) == (bfs->ascent + bfs->descent) && (nfs->min_bounds.width == bfs->min_bounds.width || nfs->min_bounds.width == bfs->min_bounds.width + 1) && (nfs->max_bounds.width == bfs->max_bounds.width || nfs->max_bounds.width == bfs->max_bounds.width + 1)); } return result; } /* * Check if the font looks like it has fixed width */ static int is_fixed_font(XFontStruct *fs) { if (fs) return (fs->min_bounds.width == fs->max_bounds.width); return 1; } static int differing_widths(XFontStruct *a, XFontStruct *b) { int result = 0; if (a != NULL && b != NULL && a->max_bounds.width != b->max_bounds.width) result = 1; return result; } /* * Check if the font looks like a double width font (i.e. contains * characters of width X and 2X */ #if OPT_WIDE_CHARS static int is_double_width_font(XFontStruct *fs) { return (fs != NULL && ((2 * fs->min_bounds.width) == fs->max_bounds.width)); } #else #define is_double_width_font(fs) 0 #endif #if OPT_WIDE_CHARS && OPT_RENDERFONT && defined(HAVE_TYPE_FCCHAR32) #define HALF_WIDTH_TEST_STRING "1234567890" /* '1234567890' in Chinese characters in UTF-8 */ #define FULL_WIDTH_TEST_STRING "\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89" \ "\xe5\x9b\x9b\xe4\xba\x94" \ "\xef\xa7\x91\xe4\xb8\x83\xe5\x85\xab" \ "\xe4\xb9\x9d\xef\xa6\xb2" /* '1234567890' in Korean script in UTF-8 */ #define FULL_WIDTH_TEST_STRING2 "\xec\x9d\xbc\xec\x9d\xb4\xec\x82\xbc" \ "\xec\x82\xac\xec\x98\xa4" \ "\xec\x9c\xa1\xec\xb9\xa0\xed\x8c\x94" \ "\xea\xb5\xac\xec\x98\x81" #define HALF_WIDTH_CHAR1 0x0031 /* '1' */ #define HALF_WIDTH_CHAR2 0x0057 /* 'W' */ #define FULL_WIDTH_CHAR1 0x4E00 /* CJK Ideograph 'number one' */ #define FULL_WIDTH_CHAR2 0xAC00 /* Korean script syllable 'Ka' */ static Bool is_double_width_font_xft(Display *dpy, XftFont *font) { XGlyphInfo gi1, gi2; FcChar32 c1 = HALF_WIDTH_CHAR1, c2 = HALF_WIDTH_CHAR2; String fwstr = FULL_WIDTH_TEST_STRING; String hwstr = HALF_WIDTH_TEST_STRING; /* Some Korean fonts don't have Chinese characters at all. */ if (!XftCharExists(dpy, font, FULL_WIDTH_CHAR1)) { if (!XftCharExists(dpy, font, FULL_WIDTH_CHAR2)) return False; /* Not a CJK font */ else /* a Korean font without CJK Ideographs */ fwstr = FULL_WIDTH_TEST_STRING2; } XftTextExtents32(dpy, font, &c1, 1, &gi1); XftTextExtents32(dpy, font, &c2, 1, &gi2); if (gi1.xOff != gi2.xOff) /* Not a fixed-width font */ return False; XftTextExtentsUtf8(dpy, font, (_Xconst FcChar8 *) hwstr, (int) strlen(hwstr), &gi1); XftTextExtentsUtf8(dpy, font, (_Xconst FcChar8 *) fwstr, (int) strlen(fwstr), &gi2); /* * fontconfig and Xft prior to 2.2(?) set the width of half-width * characters identical to that of full-width character in CJK double-width * (bi-width / monospace) font even though the former is half as wide as * the latter. This was fixed sometime before the release of fontconfig * 2.2 in early 2003. See * http://bugzilla.mozilla.org/show_bug.cgi?id=196312 * In the meantime, we have to check both possibilities. */ return ((2 * gi1.xOff == gi2.xOff) || (gi1.xOff == gi2.xOff)); } #else #define is_double_width_font_xft(dpy, xftfont) 0 #endif #define EmptyFont(fs) (fs != NULL \ && ((fs)->ascent + (fs)->descent == 0 \ || (fs)->max_bounds.width == 0)) #define FontSize(fs) (((fs)->ascent + (fs)->descent) \ * (fs)->max_bounds.width) const VTFontNames * xtermFontName(const char *normal) { static VTFontNames data; FREE_STRING(data.f_n); memset(&data, 0, sizeof(data)); if (normal) data.f_n = x_strdup(normal); return &data; } const VTFontNames * defaultVTFontNames(XtermWidget xw) { static VTFontNames data; memset(&data, 0, sizeof(data)); data.f_n = DefaultFontN(xw); data.f_b = DefaultFontB(xw); #if OPT_WIDE_CHARS data.f_w = DefaultFontW(xw); data.f_wb = DefaultFontWB(xw); #endif return &data; } static void cache_menu_font_name(TScreen *screen, int fontnum, int which, const char *name) { if (name != NULL) { String last = screen->menu_font_names[fontnum][which]; if (last != NULL) { if (strcmp(last, name)) { FREE_STRING(last); TRACE(("caching menu fontname %d.%d %s\n", fontnum, which, name)); screen->menu_font_names[fontnum][which] = x_strdup(name); } } else { TRACE(("caching menu fontname %d.%d %s\n", fontnum, which, name)); screen->menu_font_names[fontnum][which] = x_strdup(name); } } } static void cannotFont(XtermWidget xw, const char *who, const char *tag, const char *name) { static NameList *reported; NameList *list; switch (xw->misc.fontWarnings) { case fwNever: return; case fwResource: if (is_derived_font_name(name)) return; break; case fwAlways: break; } for (list = reported; list != NULL; list = list->next) { if (!x_strcasecmp(name, list->name)) { return; } } if ((list = TypeMalloc(NameList)) != NULL) { list->name = x_strdup(name); list->next = reported; reported = list; } xtermWarning("cannot %s%s%s %sfont \"%s\"\n", who, *tag ? " " : "", tag, is_derived_font_name(name) ? "derived " : "", name); } #if OPT_RENDERFONT static void noUsableXft(XtermWidget xw, const char *name) { switch (xw->misc.fontWarnings) { case fwNever: return; case fwResource: /* these combinations of wide/bold/italic are all "derived" */ return; case fwAlways: break; } xtermWarning("did not find a usable %s TrueType font\n", name); } #endif XFontStruct * xtermLoadQueryFont(XtermWidget xw, const char *name) { XFontStruct *result = NULL; size_t have = strlen(name); if (have == 0 || have > MAX_U_STRING) { ; /* just ignore it */ } else { TScreen *screen = TScreenOf(xw); result = XLoadQueryFont(screen->display, name); } TRACE(("xtermLoadQueryFont ->%s\n", visibleFont(result))); return result; } /* * Open the given font and verify that it is non-empty. Return false on * failure. */ Bool xtermOpenFont(XtermWidget xw, const char *name, XTermFonts * result, XTermFonts * current, Bool force) { Bool code = False; TRACE(("xtermOpenFont %d:%d '%s'\n", result->warn, xw->misc.fontWarnings, NonNull(name))); if (!IsEmpty(name)) { Bool existing = (current != NULL && current->fs != NULL && current->fn != NULL); if ((result->fs = xtermLoadQueryFont(xw, name)) != NULL) { code = True; if (EmptyFont(result->fs)) { xtermCloseFont(xw, result); code = False; } else { result->fn = x_strdup(name); } } else if (XmuCompareISOLatin1(name, DEFFONT) != 0) { if (result->warn <= xw->misc.fontWarnings #if OPT_RENDERFONT && !UsingRenderFont(xw) #endif ) { cannotFont(xw, "load", "", name); } else { TRACE(("xtermOpenFont: cannot load font '%s'\n", name)); } if (existing) { TRACE(("...continue using font '%s'\n", current->fn)); result->fn = x_strdup(current->fn); result->fs = current->fs; } else if (force) { NoFontWarning(result); code = xtermOpenFont(xw, DEFFONT, result, NULL, True); } } } NoFontWarning(result); return code; } /* * Close the font and free the font info. */ void xtermCloseFont(XtermWidget xw, XTermFonts * fnt) { if (fnt != NULL && fnt->fs != NULL) { TScreen *screen = TScreenOf(xw); clrCgsFonts(xw, WhichVWin(screen), fnt); XFreeFont(screen->display, fnt->fs); xtermFreeFontInfo(fnt); } } /* * Close and free the font (as well as any aliases). */ static void xtermCloseFont2(XtermWidget xw, XTermFonts * fnts, int which) { XFontStruct *thisFont = fnts[which].fs; if (thisFont != NULL) { int k; xtermCloseFont(xw, &fnts[which]); for (k = 0; k < fMAX; ++k) { if (k != which) { if (thisFont == fnts[k].fs) { xtermFreeFontInfo(&fnts[k]); } } } } } /* * Close the listed fonts, noting that some may use copies of the pointer. */ void xtermCloseFonts(XtermWidget xw, XTermFonts * fnts) { int j; for (j = 0; j < fMAX; ++j) { xtermCloseFont2(xw, fnts, j); } } /* * Make a copy of the source, assuming the XFontStruct's to be unique, but * ensuring that the names are reallocated to simplify freeing. */ void xtermCopyFontInfo(XTermFonts * target, XTermFonts * source) { xtermFreeFontInfo(target); target->chrset = source->chrset; target->flags = source->flags; target->fn = x_strdup(source->fn); target->fs = source->fs; target->warn = source->warn; } void xtermFreeFontInfo(XTermFonts * target) { target->chrset = 0; target->flags = 0; FreeAndNull(target->fn); target->fs = NULL; } #if OPT_REPORT_FONTS static void reportXCharStruct(const char *tag, XCharStruct * cs) { ReportFonts("\t\t%s:\n", tag); ReportFonts("\t\t\tlbearing: %d\n", cs->lbearing); ReportFonts("\t\t\trbearing: %d\n", cs->rbearing); ReportFonts("\t\t\twidth: %d\n", cs->width); ReportFonts("\t\t\tascent: %d\n", cs->ascent); ReportFonts("\t\t\tdescent: %d\n", cs->descent); } static void fillXCharStruct(XCharStruct * cs, short value) { cs->lbearing = value; cs->rbearing = value; cs->width = value; cs->ascent = value; cs->descent = value; } /* if the per-character data differs from the summary, that is a problem */ static void compareXCharStruct(const char *tag, XCharStruct * actual, XCharStruct * expect) { #define CompareXCharStruct(field) \ if (actual->field != expect->field) \ ReportFonts("\t\t%s %s differs: %d\n", tag, #field, actual->field) CompareXCharStruct(lbearing); CompareXCharStruct(rbearing); CompareXCharStruct(width); CompareXCharStruct(ascent); CompareXCharStruct(descent); } static void reportXPerChar(XFontStruct *fs) { XCharStruct *cs = fs->per_char; if (cs != NULL) { XCharStruct min_bounds; XCharStruct max_bounds; int valid = 0; int total = 0; unsigned first_char = 0; unsigned last_char = 0; unsigned ch; if (fs->max_byte1 == 0) { first_char = fs->min_char_or_byte2; last_char = fs->max_char_or_byte2; } else { first_char = (fs->min_byte1 * 256) + fs->min_char_or_byte2; last_char = (fs->max_byte1 * 256) + fs->max_char_or_byte2; } fillXCharStruct(&max_bounds, -32768); fillXCharStruct(&min_bounds, 32767); TRACE2(("\t\tCells: %d..%d\n", first_char, last_char)); for (ch = first_char; ch < last_char; ++ch) { XCharStruct *item = cs + ch - first_char; ++total; if (!CI_NONEXISTCHAR(item)) { ++valid; #define MIN_BOUNDS(field) min_bounds.field = Min(min_bounds.field, item->field) MIN_BOUNDS(lbearing); MIN_BOUNDS(rbearing); MIN_BOUNDS(width); MIN_BOUNDS(ascent); MIN_BOUNDS(descent); #define MAX_BOUNDS(field) max_bounds.field = Max(max_bounds.field, item->field) MAX_BOUNDS(lbearing); MAX_BOUNDS(rbearing); MAX_BOUNDS(width); MAX_BOUNDS(ascent); MAX_BOUNDS(descent); TRACE2(("\t\t\t%d: cell [%d .. %d] wide %d high %d / %d\n", ch, item->lbearing, item->rbearing, item->width, item->ascent, item->descent)); } else { TRACE(("\t\t\t%d: cell missing\n", ch)); } } ReportFonts("\t\tPer-character: %d/%d\n", valid, total); compareXCharStruct("Max", &max_bounds, &(fs->max_bounds)); compareXCharStruct("Min", &min_bounds, &(fs->min_bounds)); } else { ReportFonts("\t\tPer-character: none\n"); } } static void reportOneVTFont(const char *tag, XTermFonts * fnt) { if (!IsEmpty(fnt->fn) && fnt->fs != NULL) { XFontStruct *fs = fnt->fs; unsigned first_char = 0; unsigned last_char = 0; if (fs->max_byte1 == 0) { first_char = fs->min_char_or_byte2; last_char = fs->max_char_or_byte2; } else { first_char = (fs->min_byte1 * 256) + fs->min_char_or_byte2; last_char = (fs->max_byte1 * 256) + fs->max_char_or_byte2; } ReportFonts("\t%s: %s\n", tag, NonNull(fnt->fn)); ReportFonts("\t\tall chars: %s\n", (fs->all_chars_exist ? "yes" : "no")); ReportFonts("\t\tdefault char: %u\n", fs->default_char); ReportFonts("\t\tdirection: %u\n", fs->direction); ReportFonts("\t\tascent: %d\n", fs->ascent); ReportFonts("\t\tdescent: %d\n", fs->descent); ReportFonts("\t\tfirst char: %u\n", first_char); ReportFonts("\t\tlast char: %u\n", last_char); ReportFonts("\t\tmaximum-chars: %u\n", countGlyphs(fs)); if (FontLacksMetrics(fnt)) { ReportFonts("\t\tmissing-chars: ?\n"); ReportFonts("\t\tpresent-chars: ?\n"); } else { unsigned missing = 0; unsigned ch; for (ch = first_char; ch <= last_char; ++ch) { if (xtermMissingChar(ch, fnt)) { ++missing; } } ReportFonts("\t\tmissing-chars: %u\n", missing); ReportFonts("\t\tpresent-chars: %u\n", countGlyphs(fs) - missing); } ReportFonts("\t\tmin_byte1: %u\n", fs->min_byte1); ReportFonts("\t\tmax_byte1: %u\n", fs->max_byte1); ReportFonts("\t\tproperties: %d\n", fs->n_properties); reportXCharStruct("min_bounds", &(fs->min_bounds)); reportXCharStruct("max_bounds", &(fs->max_bounds)); reportXPerChar(fs); /* TODO: report fs->properties */ } } static void reportVTFontInfo(XtermWidget xw, int fontnum) { if (resource.reportFonts) { TScreen *screen = TScreenOf(xw); if (fontnum) { ReportFonts("Loaded VTFonts(font%d)\n", fontnum); } else { ReportFonts("Loaded VTFonts(default)\n"); } #define ReportOneVTFont(name) reportOneVTFont(#name, screen->fnts + name) ReportOneVTFont(fNorm); ReportOneVTFont(fBold); #if OPT_WIDE_CHARS ReportOneVTFont(fWide); ReportOneVTFont(fWBold); #endif } } #endif void xtermUpdateFontGCs(XtermWidget xw, MyGetFont myfunc) { TScreen *screen = TScreenOf(xw); VTwin *win = WhichVWin(screen); Pixel new_normal = getXtermFG(xw, xw->flags, xw->cur_foreground); Pixel new_revers = getXtermBG(xw, xw->flags, xw->cur_background); setCgsFore(xw, win, gcNorm, new_normal); setCgsBack(xw, win, gcNorm, new_revers); setCgsFont(xw, win, gcNorm, myfunc(screen, fNorm)); setCgsFont(xw, win, gcVTcursNormal, NULL); setCgsFont(xw, win, gcVTcursReverse, NULL); copyCgs(xw, win, gcBold, gcNorm); setCgsFont2(xw, win, gcBold, myfunc(screen, fBold), fBold); setCgsFore(xw, win, gcNormReverse, new_revers); setCgsBack(xw, win, gcNormReverse, new_normal); setCgsFont(xw, win, gcNormReverse, myfunc(screen, fNorm)); copyCgs(xw, win, gcBoldReverse, gcNormReverse); setCgsFont2(xw, win, gcBoldReverse, myfunc(screen, fBold), fBold); if_OPT_WIDE_CHARS(screen, { XTermFonts *wide_xx = myfunc(screen, fWide); XTermFonts *bold_xx = myfunc(screen, fWBold); if (wide_xx->fs != NULL && bold_xx->fs != NULL) { setCgsFore(xw, win, gcWide, new_normal); setCgsBack(xw, win, gcWide, new_revers); setCgsFont(xw, win, gcWide, wide_xx); copyCgs(xw, win, gcWBold, gcWide); setCgsFont(xw, win, gcWBold, bold_xx); setCgsFore(xw, win, gcWideReverse, new_revers); setCgsBack(xw, win, gcWideReverse, new_normal); setCgsFont(xw, win, gcWideReverse, wide_xx); copyCgs(xw, win, gcWBoldReverse, gcWideReverse); setCgsFont(xw, win, gcWBoldReverse, bold_xx); } }); } #if OPT_WIDE_ATTRS unsigned xtermUpdateItalics(XtermWidget xw, unsigned new_attrs, unsigned old_attrs) { TScreen *screen = TScreenOf(xw); (void) screen; if (UseItalicFont(screen)) { if ((new_attrs & ATR_ITALIC) && !(old_attrs & ATR_ITALIC)) { xtermLoadItalics(xw); xtermUpdateFontGCs(xw, getItalicFont); } else if (!(new_attrs & ATR_ITALIC) && (old_attrs & ATR_ITALIC)) { xtermUpdateFontGCs(xw, getNormalFont); } } return new_attrs; } #endif #if OPT_TRACE && OPT_BOX_CHARS static void show_font_misses(const char *name, XTermFonts * fp) { if (fp->fs != NULL) { if (FontLacksMetrics(fp)) { TRACE(("%s font lacks metrics\n", name)); } else if (FontIsIncomplete(fp)) { TRACE(("%s font is incomplete\n", name)); } else { TRACE(("%s font is complete\n", name)); } } else { TRACE(("%s font is missing\n", name)); } } #endif static Bool loadNormFP(XtermWidget xw, char **nameOutP, XTermFonts * infoOut, XTermFonts * current, int fontnum) { Bool status = True; TRACE(("loadNormFP (%s)\n", NonNull(*nameOutP))); if (!xtermOpenFont(xw, *nameOutP, infoOut, current, (fontnum == fontMenu_default))) { /* * If we are opening the default font, and it happens to be missing, * force that to the compiled-in default font, e.g., "fixed". If we * cannot open the font, disable it from the menu. */ if (fontnum != fontMenu_fontsel) { SetItemSensitivity(fontMenuEntries[fontnum].widget, False); } status = False; } return status; } static Bool loadBoldFP(XtermWidget xw, char **nameOutP, XTermFonts * infoOut, const char *nameRef, XTermFonts * infoRef, int fontnum) { TScreen *screen = TScreenOf(xw); Bool status = True; TRACE(("loadBoldFP (%s)\n", NonNull(*nameOutP))); if (!check_fontname(*nameOutP)) { FontNameProperties *fp; char *normal = x_strdup(nameRef); fp = get_font_name_props(screen->display, infoRef->fs, &normal); if (fp != NULL) { NoFontWarning(infoOut); *nameOutP = bold_font_name(fp, fp->average_width); if (!xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)) { free(*nameOutP); *nameOutP = bold_font_name(fp, -1); xtermOpenFont(xw, *nameOutP, infoOut, NULL, False); } TRACE(("...derived bold '%s'\n", NonNull(*nameOutP))); } if (fp == NULL || infoOut->fs == NULL) { xtermCopyFontInfo(infoOut, infoRef); TRACE(("...cannot load a matching bold font\n")); } else if (comparable_metrics(infoRef->fs, infoOut->fs) && same_font_size(xw, infoRef->fs, infoOut->fs) && got_bold_font(screen->display, infoOut->fs, *nameOutP)) { TRACE(("...got a matching bold font\n")); cache_menu_font_name(screen, fontnum, fBold, *nameOutP); } else { xtermCloseFont2(xw, infoOut - fBold, fBold); *infoOut = *infoRef; TRACE(("...did not get a matching bold font\n")); } free(normal); } else if (!xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)) { xtermCopyFontInfo(infoOut, infoRef); TRACE(("...cannot load bold font '%s'\n", NonNull(*nameOutP))); } else { cache_menu_font_name(screen, fontnum, fBold, *nameOutP); } /* * Most of the time this call to load the font will succeed, even if * there is no wide font : the X server doubles the width of the * normal font, or similar. * * But if it did fail for some reason, then nevermind. */ if (EmptyFont(infoOut->fs)) status = False; /* can't use a 0-sized font */ if (!same_font_size(xw, infoRef->fs, infoOut->fs) && (is_fixed_font(infoRef->fs) && is_fixed_font(infoOut->fs))) { TRACE(("...ignoring mismatched normal/bold fonts\n")); xtermCloseFont2(xw, infoOut - fBold, fBold); xtermCopyFontInfo(infoOut, infoRef); } return status; } #if OPT_WIDE_CHARS static Bool loadWideFP(XtermWidget xw, char **nameOutP, XTermFonts * infoOut, const char *nameRef, XTermFonts * infoRef, int fontnum) { TScreen *screen = TScreenOf(xw); Bool status = True; TRACE(("loadWideFP (%s)\n", NonNull(*nameOutP))); if (!check_fontname(*nameOutP) && (screen->utf8_fonts && !is_double_width_font(infoRef->fs))) { char *normal = x_strdup(nameRef); FontNameProperties *fp = get_font_name_props(screen->display, infoRef->fs, &normal); if (fp != NULL) { *nameOutP = wide_font_name(fp); NoFontWarning(infoOut); } free(normal); } if (check_fontname(*nameOutP)) { if (xtermOpenFont(xw, *nameOutP, infoOut, NULL, False) && is_derived_font_name(*nameOutP) && EmptyFont(infoOut->fs)) { xtermCloseFont2(xw, infoOut - fWide, fWide); } if (infoOut->fs == NULL) { xtermCopyFontInfo(infoOut, infoRef); } else { TRACE(("...%s wide %s\n", is_derived_font_name(*nameOutP) ? "derived" : "given", NonNull(*nameOutP))); cache_menu_font_name(screen, fontnum, fWide, *nameOutP); } } else { xtermCopyFontInfo(infoOut, infoRef); } #define MinWidthOf(fs) fs->min_bounds.width #define MaxWidthOf(fs) fs->max_bounds.width xw->work.force_wideFont = False; if (MaxWidthOf(infoOut->fs) != (2 * MaxWidthOf(infoRef->fs))) { TRACE(("...reference width %d\n", MaxWidthOf(infoRef->fs))); TRACE(("...?? double-width %d\n", 2 * MaxWidthOf(infoRef->fs))); TRACE(("...actual width %d\n", MaxWidthOf(infoOut->fs))); xw->work.force_wideFont = True; } return status; } static Bool loadWBoldFP(XtermWidget xw, char **nameOutP, XTermFonts * infoOut, const char *wideNameRef, XTermFonts * wideInfoRef, const char *boldNameRef, XTermFonts * boldInfoRef, int fontnum) { TScreen *screen = TScreenOf(xw); Bool status = True; char *bold = NULL; TRACE(("loadWBoldFP (%s)\n", NonNull(*nameOutP))); if (!check_fontname(*nameOutP)) { FontNameProperties *fp; fp = get_font_name_props(screen->display, boldInfoRef->fs, &bold); if (fp != NULL) { *nameOutP = widebold_font_name(fp); NoFontWarning(infoOut); } } if (check_fontname(*nameOutP)) { if (xtermOpenFont(xw, *nameOutP, infoOut, NULL, False) && is_derived_font_name(*nameOutP) && !compatibleWideCounts(wideInfoRef->fs, infoOut->fs)) { xtermCloseFont2(xw, infoOut - fWBold, fWBold); } if (infoOut->fs == NULL) { if (is_derived_font_name(*nameOutP)) free(*nameOutP); if (IsEmpty(wideNameRef)) { *nameOutP = x_strdup(boldNameRef); xtermCopyFontInfo(infoOut, boldInfoRef); TRACE(("...cannot load wide-bold, use bold %s\n", NonNull(boldNameRef))); } else { *nameOutP = x_strdup(wideNameRef); xtermCopyFontInfo(infoOut, wideInfoRef); TRACE(("...cannot load wide-bold, use wide %s\n", NonNull(wideNameRef))); } } else { TRACE(("...%s wide/bold %s\n", is_derived_font_name(*nameOutP) ? "derived" : "given", NonNull(*nameOutP))); cache_menu_font_name(screen, fontnum, fWBold, *nameOutP); } } else if (is_double_width_font(boldInfoRef->fs)) { xtermCopyFontInfo(infoOut, boldInfoRef); TRACE(("...bold font is double-width, use it %s\n", NonNull(boldNameRef))); } else { xtermCopyFontInfo(infoOut, wideInfoRef); TRACE(("...cannot load wide bold font, use wide %s\n", NonNull(wideNameRef))); } free(bold); if (EmptyFont(infoOut->fs)) { status = False; /* can't use a 0-sized font */ } else { if ((!comparable_metrics(wideInfoRef->fs, infoOut->fs) || (!same_font_size(xw, wideInfoRef->fs, infoOut->fs) && is_fixed_font(wideInfoRef->fs) && is_fixed_font(infoOut->fs)))) { TRACE(("...ignoring mismatched normal/bold wide fonts\n")); xtermCloseFont2(xw, infoOut - fWBold, fWBold); xtermCopyFontInfo(infoOut, wideInfoRef); } } return status; } #endif /* * Load a given bitmap font, along with the bold/wide variants. * Returns nonzero on success. */ int xtermLoadFont(XtermWidget xw, const VTFontNames * fonts, Bool doresize, int fontnum) { TScreen *screen = TScreenOf(xw); VTwin *win = WhichVWin(screen); VTFontNames new_fnames; XTermFonts new_fonts[fMAX]; XTermFonts old_fonts[fMAX]; char *tmpname = NULL; Boolean proportional = False; Boolean recovered; int code = 0; memset(&new_fnames, 0, sizeof(new_fnames)); memset(new_fonts, 0, sizeof(new_fonts)); memcpy(&old_fonts, screen->fnts, sizeof(old_fonts)); if (fonts != NULL) new_fnames = *fonts; if (!check_fontname(new_fnames.f_n)) return code; if (fontnum == fontMenu_fontescape && new_fnames.f_n != screen->MenuFontName(fontnum)) { if ((tmpname = x_strdup(new_fnames.f_n)) == NULL) return code; } TRACE(("Begin Cgs - xtermLoadFont(%s)\n", new_fnames.f_n)); releaseWindowGCs(xw, win); #define DbgResource(name, field, index) \ TRACE(("xtermLoadFont #%d "name" %s%s\n", \ fontnum, \ (new_fonts[index].warn == fwResource) ? "*" : " ", \ NonNull(new_fnames.field))) DbgResource("normal", f_n, fNorm); DbgResource("bold ", f_b, fBold); #if OPT_WIDE_CHARS DbgResource("wide ", f_w, fWide); DbgResource("w/bold", f_wb, fWBold); #endif if (!loadNormFP(xw, &new_fnames.f_n, &new_fonts[fNorm], &old_fonts[fNorm], fontnum)) goto bad; if (!loadBoldFP(xw, &new_fnames.f_b, &new_fonts[fBold], new_fnames.f_n, &new_fonts[fNorm], fontnum)) goto bad; /* * If there is no widefont specified, fake it by doubling AVERAGE_WIDTH * of normal fonts XLFD, and asking for it. This plucks out 18x18ja * and 12x13ja as the corresponding fonts for 9x18 and 6x13. */ if_OPT_WIDE_CHARS(screen, { if (!loadWideFP(xw, &new_fnames.f_w, &new_fonts[fWide], new_fnames.f_n, &new_fonts[fNorm], fontnum)) goto bad; if (!loadWBoldFP(xw, &new_fnames.f_wb, &new_fonts[fWBold], new_fnames.f_w, &new_fonts[fWide], new_fnames.f_b, &new_fonts[fBold], fontnum)) goto bad; }); /* * Normal/bold fonts should be the same width. Also, the min/max * values should be the same. */ if (new_fonts[fNorm].fs != NULL && new_fonts[fBold].fs != NULL && (!is_fixed_font(new_fonts[fNorm].fs) || !is_fixed_font(new_fonts[fBold].fs) || differing_widths(new_fonts[fNorm].fs, new_fonts[fBold].fs))) { TRACE(("Proportional font! normal %d/%d, bold %d/%d\n", new_fonts[fNorm].fs->min_bounds.width, new_fonts[fNorm].fs->max_bounds.width, new_fonts[fBold].fs->min_bounds.width, new_fonts[fBold].fs->max_bounds.width)); proportional = True; } if_OPT_WIDE_CHARS(screen, { if (new_fonts[fWide].fs != NULL && new_fonts[fWBold].fs != NULL && (!is_fixed_font(new_fonts[fWide].fs) || !is_fixed_font(new_fonts[fWBold].fs) || differing_widths(new_fonts[fWide].fs, new_fonts[fWBold].fs))) { TRACE(("Proportional font! wide %d/%d, wide bold %d/%d\n", new_fonts[fWide].fs->min_bounds.width, new_fonts[fWide].fs->max_bounds.width, new_fonts[fWBold].fs->min_bounds.width, new_fonts[fWBold].fs->max_bounds.width)); proportional = True; } }); /* TODO : enforce that the width of the wide font is 2* the width of the narrow font */ /* * If we're switching fonts, free the old ones. Otherwise we'll leak * the memory that is associated with the old fonts. The * XLoadQueryFont call allocates a new XFontStruct. */ xtermCloseFonts(xw, screen->fnts); #if OPT_WIDE_ATTRS xtermCloseFonts(xw, screen->ifnts); screen->ifnts_ok = False; #endif xtermCopyFontInfo(GetNormalFont(screen, fNorm), &new_fonts[fNorm]); xtermCopyFontInfo(GetNormalFont(screen, fBold), &new_fonts[fBold]); #if OPT_WIDE_CHARS xtermCopyFontInfo(GetNormalFont(screen, fWide), &new_fonts[fWide]); if (new_fonts[fWBold].fs == NULL) xtermCopyFontInfo(GetNormalFont(screen, fWide), &new_fonts[fWide]); xtermCopyFontInfo(GetNormalFont(screen, fWBold), &new_fonts[fWBold]); #endif xtermUpdateFontGCs(xw, getNormalFont); #if OPT_BOX_CHARS screen->allow_packing = proportional; setupPackedFonts(xw); #endif screen->fnt_prop = (Boolean) (proportional && !(screen->force_packed)); screen->fnt_boxes = 1; #if OPT_BOX_CHARS /* * xterm uses character positions 1-31 of a font for the line-drawing * characters. Check that they are all present. The null character * (0) is special, and is not used. */ #if OPT_RENDERFONT if (UsingRenderFont(xw)) { /* * FIXME: we shouldn't even be here if we're using Xft. */ screen->fnt_boxes = 0; TRACE(("assume Xft missing line-drawing chars\n")); } else #endif { unsigned ch; #if OPT_TRACE #define TRACE_MISS(index) show_font_misses(#index, &new_fonts[index]) TRACE_MISS(fNorm); TRACE_MISS(fBold); #if OPT_WIDE_CHARS TRACE_MISS(fWide); TRACE_MISS(fWBold); #endif #endif #if OPT_WIDE_CHARS if (screen->utf8_mode || screen->unicode_font) { UIntSet(screen->fnt_boxes, 2); for (ch = 1; ch < 32; ch++) { unsigned n = dec2ucs(screen, ch); if (!is_UCS_SPECIAL(n) && (n != ch) && (screen->fnt_boxes & 2)) { if (xtermMissingChar(n, &new_fonts[fNorm]) || xtermMissingChar(n, &new_fonts[fBold])) { UIntClr(screen->fnt_boxes, 2); TRACE(("missing graphics character #%d, U+%04X\n", ch, n)); break; } } } } #endif for (ch = 1; ch < 32; ch++) { if (xtermMissingChar(ch, &new_fonts[fNorm])) { TRACE(("missing normal char #%d\n", ch)); UIntClr(screen->fnt_boxes, 1); break; } if (xtermMissingChar(ch, &new_fonts[fBold])) { TRACE(("missing bold char #%d\n", ch)); UIntClr(screen->fnt_boxes, 1); break; } } TRACE(("Will %suse internal line-drawing characters (mode %d)\n", screen->fnt_boxes ? "not " : "", screen->fnt_boxes)); } #endif if (screen->always_bold_mode) { screen->enbolden = screen->bold_mode; } else { screen->enbolden = screen->bold_mode && ((new_fonts[fNorm].fs == new_fonts[fBold].fs) || same_font_name(new_fnames.f_n, new_fnames.f_b)); } TRACE(("Will %suse 1-pixel offset/overstrike to simulate bold\n", screen->enbolden ? "" : "not ")); set_menu_font(False); screen->menu_font_number = fontnum; set_menu_font(True); if (tmpname) { /* if setting escape or sel */ if (screen->MenuFontName(fontnum)) FREE_STRING(screen->MenuFontName(fontnum)); screen->MenuFontName(fontnum) = tmpname; if (fontnum == fontMenu_fontescape) { update_font_escape(); } #if OPT_SHIFT_FONTS screen->menu_font_sizes[fontnum] = FontSize(new_fonts[fNorm].fs); #endif } set_cursor_gcs(xw); xtermUpdateFontInfo(xw, doresize); TRACE(("Success Cgs - xtermLoadFont\n")); #if OPT_REPORT_FONTS reportVTFontInfo(xw, fontnum); #endif FREE_FNAME(f_n); FREE_FNAME(f_b); #if OPT_WIDE_CHARS FREE_FNAME(f_w); FREE_FNAME(f_wb); #endif if (new_fonts[fNorm].fn == new_fonts[fBold].fn) { free(new_fonts[fNorm].fn); } else { free(new_fonts[fNorm].fn); free(new_fonts[fBold].fn); } #if OPT_WIDE_CHARS free(new_fonts[fWide].fn); free(new_fonts[fWBold].fn); #endif xtermSetWinSize(xw); return 1; bad: recovered = False; free(tmpname); #if OPT_RENDERFONT if ((fontnum == fontMenu_fontsel) && (fontnum != screen->menu_font_number)) { int old_fontnum = screen->menu_font_number; #if OPT_TOOLBAR SetItemSensitivity(fontMenuEntries[fontnum].widget, True); #endif Bell(xw, XkbBI_MinorError, 0); new_fnames.f_n = screen->MenuFontName(old_fontnum); if (xtermLoadFont(xw, &new_fnames, doresize, old_fontnum)) recovered = True; } else if (x_strcasecmp(new_fnames.f_n, DEFFONT) && x_strcasecmp(new_fnames.f_n, old_fonts[fNorm].fn)) { new_fnames.f_n = x_strdup(old_fonts[fNorm].fn); TRACE(("...recovering from failed font-load\n")); if (xtermLoadFont(xw, &new_fnames, doresize, fontnum)) { recovered = True; if (fontnum != fontMenu_fontsel) { SetItemSensitivity(fontMenuEntries[fontnum].widget, UsingRenderFont(xw)); } TRACE(("...recovered size %dx%d\n", FontHeight(screen), FontWidth(screen))); } } #endif if (!recovered) { releaseWindowGCs(xw, win); xtermCloseFonts(xw, new_fonts); TRACE(("Fail Cgs - xtermLoadFont\n")); code = 0; } return code; } #if OPT_WIDE_ATTRS /* * (Attempt to) load matching italics for the current normal/bold/etc fonts. * If the attempt fails for a given style, use the non-italic font. */ void xtermLoadItalics(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (UseItalicFont(screen) && !screen->ifnts_ok) { int n; FontNameProperties *fp; XTermFonts *data; screen->ifnts_ok = True; for (n = 0; n < fMAX; ++n) { switch (n) { case fNorm: /* FALLTHRU */ case fBold: /* FALLTHRU */ #if OPT_WIDE_CHARS case fWide: /* FALLTHRU */ case fWBold: #endif /* FALLTHRU */ data = getItalicFont(screen, n); /* * FIXME - need to handle font-leaks */ data->fs = NULL; if (getNormalFont(screen, n)->fs != NULL && (fp = get_font_name_props(screen->display, getNormalFont(screen, n)->fs, NULL)) != NULL) { if (!open_italic_font(xw, n, fp, data)) { if (n > 0) { xtermCopyFontInfo(data, getItalicFont(screen, n - 1)); } else { xtermOpenFont(xw, getNormalFont(screen, n)->fn, data, NULL, False); } } } break; } } } } #endif #if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS /* * Collect font-names that we can modify with the load-vt-fonts() action. */ #define MERGE_SUBFONT(dst,src,name) \ if (IsEmpty(dst.name)) { \ TRACE(("MERGE_SUBFONT " #dst "." #name " merge \"%s\"\n", NonNull(src.name))); \ dst.name = x_strdup(src.name); \ } else { \ TRACE(("MERGE_SUBFONT " #dst "." #name " found \"%s\"\n", NonNull(dst.name))); \ } #define MERGE_SUBLIST(dst,src,name) \ if (dst.fonts.x11.name == NULL) \ dst.fonts.x11.name = TypeCalloc(char *); \ if (merge_sublist(&(dst.fonts.x11.name), src.fonts.x11.name)) { \ TRACE(("MERGE_SUBLIST " #dst "." #name " merge \"%s\"\n", NonNull(src.fonts.x11.name[0]))); \ } else { \ TRACE(("MERGE_SUBLIST " #dst "." #name " found \"%s\"\n", NonNull(dst.fonts.x11.name[0]))); \ } #define INFER_SUBFONT(dst,src,name) \ if (IsEmpty(dst.name)) { \ TRACE(("INFER_SUBFONT " #dst "." #name " will infer\n")); \ dst.name = x_strdup(""); \ } else { \ TRACE(("INFER_SUBFONT " #dst "." #name " found \"%s\"\n", NonNull(dst.name))); \ } #define FREE_MENU_FONTS(dst) \ TRACE(("FREE_MENU_FONTS " #dst "\n")); \ for (n = fontMenu_default; n <= fontMenu_lastBuiltin; ++n) { \ for (m = 0; m < fMAX; ++m) { \ FREE_STRING(dst.menu_font_names[n][m]); \ dst.menu_font_names[n][m] = NULL; \ } \ } #define COPY_MENU_FONTS(dst,src) \ TRACE(("COPY_MENU_FONTS " #src " to " #dst "\n")); \ for (n = fontMenu_default; n <= fontMenu_lastBuiltin; ++n) { \ for (m = 0; m < fMAX; ++m) { \ FREE_STRING(dst.menu_font_names[n][m]); \ dst.menu_font_names[n][m] = x_strdup(src.menu_font_names[n][m]); \ } \ TRACE((".. " #dst ".menu_fonts_names[%d] = %s\n", n, NonNull(dst.menu_font_names[n][fNorm]))); \ } #define COPY_DEFAULT_FONTS(target, source) \ TRACE(("COPY_DEFAULT_FONTS " #source " to " #target "\n")); \ xtermCopyVTFontNames(&target.default_font, &source.default_font) #define COPY_X11_FONTLISTS(target, source) \ TRACE(("COPY_X11_FONTLISTS " #source " to " #target "\n")); \ xtermCopyFontLists(xw, &target.fonts.x11, &source.fonts.x11) static void xtermCopyVTFontNames(VTFontNames * target, VTFontNames * source) { #define COPY_IT(name,field) \ TRACE((".. "#name" = %s\n", NonNull(source->field))); \ free(target->field); \ target->field = x_strdup(source->field) TRACE(("xtermCopyVTFontNames\n")); COPY_IT(font, f_n); COPY_IT(boldFont, f_b); #if OPT_WIDE_CHARS COPY_IT(wideFont, f_w); COPY_IT(wideBoldFont, f_wb); #endif #undef COPY_IT } static void xtermCopyFontLists(XtermWidget xw, VTFontList * target, VTFontList * source) { #define COPY_IT(name,field) \ copyFontList(&(target->field), source->field); \ TRACE_ARGV(".. " #name, source->field) (void) xw; TRACE(("xtermCopyFontLists %s ->%s\n", whichFontList(xw, source), whichFontList(xw, target))); COPY_IT(font, list_n); COPY_IT(fontBold, list_b); #if OPT_WIDE_ATTRS || OPT_RENDERWIDE COPY_IT(fontItal, list_i); COPY_IT(fontBtal, list_bi); #endif #if OPT_WIDE_CHARS COPY_IT(wideFont, list_w); COPY_IT(wideBoldFont, list_wb); COPY_IT(wideItalFont, list_wi); COPY_IT(wideBtalFont, list_wbi); #endif #undef COPY_IT } void xtermSaveVTFonts(XtermWidget xw) { TScreen *screen = TScreenOf(xw); Cardinal n, m; if (!screen->savedVTFonts) { screen->savedVTFonts = True; TRACE(("xtermSaveVTFonts saving original\n")); COPY_DEFAULT_FONTS(screen->cacheVTFonts, xw->misc); COPY_X11_FONTLISTS(screen->cacheVTFonts, xw->work); COPY_MENU_FONTS(screen->cacheVTFonts, xw->screen); } } #define SAME_STRING(x,y) ((x) == (y) || ((x) && (y) && !strcmp(x, y))) #define SAME_MEMBER(n) SAME_STRING(a->n, b->n) static Boolean sameSubResources(SubResourceRec * a, SubResourceRec * b) { Boolean result = True; if (!SAME_MEMBER(default_font.f_n) || !SAME_MEMBER(default_font.f_b) #if OPT_WIDE_CHARS || !SAME_MEMBER(default_font.f_w) || !SAME_MEMBER(default_font.f_wb) #endif ) { TRACE(("sameSubResources: default_font differs\n")); result = False; } else { int n; for (n = 0; n < NMENUFONTS; ++n) { if (!SAME_MEMBER(menu_font_names[n][fNorm])) { TRACE(("sameSubResources: menu_font_names[%d] differs\n", n)); result = False; break; } } } return result; } /* * Load the "VT" font names from the given subresource name/class. These * correspond to the VT100 resources. */ static Bool xtermLoadVTFonts(XtermWidget xw, String myName, String myClass) { SubResourceRec subresourceRec; SubResourceRec referenceRec; /* * These are duplicates of the VT100 font resources, but with a special * application/classname passed in to distinguish them. */ static XtResource font_resources[] = { Sres(XtNfont, XtCFont, default_font.f_n, DEFFONT), Sres(XtNboldFont, XtCBoldFont, default_font.f_b, DEFBOLDFONT), #if OPT_WIDE_CHARS Sres(XtNwideFont, XtCWideFont, default_font.f_w, DEFWIDEFONT), Sres(XtNwideBoldFont, XtCWideBoldFont, default_font.f_wb, DEFWIDEBOLDFONT), #endif Sres(XtNfont1, XtCFont1, MenuFontName(fontMenu_font1), NULL), Sres(XtNfont2, XtCFont2, MenuFontName(fontMenu_font2), NULL), Sres(XtNfont3, XtCFont3, MenuFontName(fontMenu_font3), NULL), Sres(XtNfont4, XtCFont4, MenuFontName(fontMenu_font4), NULL), Sres(XtNfont5, XtCFont5, MenuFontName(fontMenu_font5), NULL), Sres(XtNfont6, XtCFont6, MenuFontName(fontMenu_font6), NULL), Sres(XtNfont7, XtCFont7, MenuFontName(fontMenu_font7), NULL), }; Cardinal n, m; Bool status = True; TScreen *screen = TScreenOf(xw); TRACE(("called xtermLoadVTFonts(name=%s, class=%s)\n", NonNull(myName), NonNull(myClass))); xtermSaveVTFonts(xw); if (IsEmpty(myName)) { TRACE(("xtermLoadVTFonts restoring original\n")); COPY_DEFAULT_FONTS(xw->misc, screen->cacheVTFonts); COPY_X11_FONTLISTS(xw->work, screen->cacheVTFonts); FREE_MENU_FONTS(xw->screen); COPY_MENU_FONTS(xw->screen, screen->cacheVTFonts); } else { TRACE(("xtermLoadVTFonts(%s, %s)\n", myName, myClass)); memset(&referenceRec, 0, sizeof(referenceRec)); memset(&subresourceRec, 0, sizeof(subresourceRec)); XtGetSubresources((Widget) xw, (XtPointer) &subresourceRec, myName, myClass, font_resources, (Cardinal) XtNumber(font_resources), NULL, (Cardinal) 0); /* * XtGetSubresources returns no status, so we compare the returned * data against a zero'd struct to see if any data is returned. */ if (memcmp(&referenceRec, &subresourceRec, sizeof(referenceRec)) && !sameSubResources(&(screen->cacheVTFonts), &subresourceRec)) { screen->mergedVTFonts = True; /* * To make it simple, reallocate the strings returned by * XtGetSubresources. We can free our own strings, but not theirs. */ ALLOC_STRING(subresourceRec.default_font.f_n); ALLOC_STRING(subresourceRec.default_font.f_b); #if OPT_WIDE_CHARS ALLOC_STRING(subresourceRec.default_font.f_w); ALLOC_STRING(subresourceRec.default_font.f_wb); #endif for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; ++n) { ALLOC_STRING(subresourceRec.MenuFontName(n)); } /* * Now, save the string to a font-list for consistency */ #define ALLOC_SUBLIST(which,field) \ if (subresourceRec.default_font.field != NULL) { \ char *blob = x_strdup(subresourceRec.default_font.field); \ char *base; \ for (base = blob; ; base = NULL) { \ char *item = strtok(base, ","); \ if (item == NULL) \ break; \ save2FontList(xw, "cached", \ &(subresourceRec.fonts), \ which, \ item, False, False); \ } \ free(blob); \ } ALLOC_SUBLIST(fNorm, f_n); ALLOC_SUBLIST(fBold, f_b); #if OPT_WIDE_CHARS ALLOC_SUBLIST(fWide, f_w); ALLOC_SUBLIST(fWBold, f_wb); #endif /* * If a particular resource value was not found, use the original. */ MERGE_SUBFONT(subresourceRec, xw->misc, default_font.f_n); INFER_SUBFONT(subresourceRec, xw->misc, default_font.f_b); MERGE_SUBLIST(subresourceRec, xw->work, list_n); MERGE_SUBLIST(subresourceRec, xw->work, list_b); #if OPT_WIDE_CHARS INFER_SUBFONT(subresourceRec, xw->misc, default_font.f_w); INFER_SUBFONT(subresourceRec, xw->misc, default_font.f_wb); MERGE_SUBLIST(subresourceRec, xw->work, list_w); MERGE_SUBLIST(subresourceRec, xw->work, list_wb); #endif for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; ++n) { MERGE_SUBFONT(subresourceRec, xw->screen, MenuFontName(n)); } /* * Finally, copy the subresource data to the widget. */ COPY_DEFAULT_FONTS(xw->misc, subresourceRec); COPY_X11_FONTLISTS(xw->work, subresourceRec); FREE_MENU_FONTS(xw->screen); COPY_MENU_FONTS(xw->screen, subresourceRec); FREE_STRING(screen->MenuFontName(fontMenu_default)); FREE_STRING(screen->menu_font_names[0][fBold]); screen->MenuFontName(fontMenu_default) = x_strdup(DefaultFontN(xw)); screen->menu_font_names[0][fBold] = x_strdup(DefaultFontB(xw)); #if OPT_WIDE_CHARS FREE_STRING(screen->menu_font_names[0][fWide]); FREE_STRING(screen->menu_font_names[0][fWBold]); screen->menu_font_names[0][fWide] = x_strdup(DefaultFontW(xw)); screen->menu_font_names[0][fWBold] = x_strdup(DefaultFontWB(xw)); #endif /* * And remove our copies of strings. */ FREE_STRING(subresourceRec.default_font.f_n); FREE_STRING(subresourceRec.default_font.f_b); #if OPT_WIDE_CHARS FREE_STRING(subresourceRec.default_font.f_w); FREE_STRING(subresourceRec.default_font.f_wb); #endif for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; ++n) { FREE_STRING(subresourceRec.MenuFontName(n)); } } else { TRACE(("...no resources found\n")); status = False; } } TRACE((".. xtermLoadVTFonts: %d\n", status)); return status; } #if OPT_WIDE_CHARS static Bool isWideFont(XFontStruct *fp, const char *tag, Bool nullOk) { Bool result = False; (void) tag; if (okFont(fp)) { unsigned count = countGlyphs(fp); TRACE(("isWideFont(%s) found %d cells\n", tag, count)); result = (count > 256) ? True : False; } else { result = nullOk; } return result; } /* * If the current fonts are not wide, load the UTF8 fonts. * * Called during initialization (for wide-character mode), the fonts have not * been setup, so we pass nullOk=True to isWideFont(). * * Called after initialization, e.g., in response to the UTF-8 menu entry * (starting from narrow character mode), it checks if the fonts are not wide. */ Bool xtermLoadWideFonts(XtermWidget xw, Bool nullOk) { TScreen *screen = TScreenOf(xw); Bool result; if (EmptyFont(GetNormalFont(screen, fWide)->fs)) { result = (isWideFont(GetNormalFont(screen, fNorm)->fs, "normal", nullOk) && isWideFont(GetNormalFont(screen, fBold)->fs, "bold", nullOk)); } else { result = (isWideFont(GetNormalFont(screen, fWide)->fs, "wide", nullOk) && isWideFont(GetNormalFont(screen, fWBold)->fs, "wide-bold", nullOk)); if (result && !screen->utf8_latin1) { result = (isWideFont(GetNormalFont(screen, fNorm)->fs, "normal", nullOk) && isWideFont(GetNormalFont(screen, fBold)->fs, "bold", nullOk)); } } if (!result) { TRACE(("current fonts are not all wide%s\n", nullOk ? " nullOk" : "")); result = xtermLoadVTFonts(xw, XtNutf8Fonts, XtCUtf8Fonts); } TRACE(("xtermLoadWideFonts:%d\n", result)); return result; } #endif /* OPT_WIDE_CHARS */ /* * Restore the default fonts, i.e., if we had switched to wide-fonts. */ Bool xtermLoadDefaultFonts(XtermWidget xw) { Bool result; result = xtermLoadVTFonts(xw, NULL, NULL); TRACE(("xtermLoadDefaultFonts:%d\n", result)); return result; } #endif /* OPT_LOAD_VTFONTS || OPT_WIDE_CHARS */ #if OPT_LOAD_VTFONTS void HandleLoadVTFonts(Widget w, XEvent *event GCC_UNUSED, String *params, Cardinal *param_count) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { static char empty[] = ""; /* appease strict compilers */ TScreen *screen = TScreenOf(xw); char name_buf[80]; String name = (String) ((*param_count > 0) ? params[0] : empty); char *myName = MyStackAlloc(strlen(name) + 1, name_buf); TRACE(("HandleLoadVTFonts(%d)\n", *param_count)); if (myName != NULL) { char class_buf[80]; String convert = (String) ((*param_count > 1) ? params[1] : myName); char *myClass = MyStackAlloc(strlen(convert) + 1, class_buf); strcpy(myName, name); if (myClass != NULL) { strcpy(myClass, convert); if (*param_count == 1) myClass[0] = x_toupper(myClass[0]); if (xtermLoadVTFonts(xw, myName, myClass)) { int n; /* * When switching fonts, try to preserve the font-menu * selection, since it is less surprising to do that (if * the font-switching can be undone) than to switch to * "Default". */ int font_number = screen->menu_font_number; if (font_number > fontMenu_lastBuiltin) font_number = fontMenu_lastBuiltin; for (n = 0; n < NMENUFONTS; ++n) { screen->menu_font_sizes[n] = 0; } if (font_number == fontMenu_default) { SetVTFont(xw, font_number, True, defaultVTFontNames(xw)); } else { SetVTFont(xw, font_number, True, NULL); } } MyStackFree(myClass, class_buf); } MyStackFree(myName, name_buf); } } } #endif /* OPT_LOAD_VTFONTS */ /* * Set the limits for the box that outlines the cursor. */ void xtermSetCursorBox(TScreen *screen) { static XPoint VTbox[NBOX]; XPoint *vp; int fw = FontWidth(screen) - 1; int fh = FontHeight(screen) - 1; int ww = isCursorBar(screen) ? fw / 8 : fw; int hh = isCursorUnderline(screen) ? fh / 8 : fh; if (ww < 2) ww = 2; if (hh < 2) hh = 2; vp = &VTbox[1]; (vp++)->x = (short) ww; (vp++)->y = (short) hh; (vp++)->x = (short) -ww; vp->y = (short) -hh; screen->box = VTbox; } #if OPT_RENDERFONT #define CACHE_XFT(data) if (XftFp(data) != NULL) {\ int err = checkXftWidth(xw, data);\ TRACE(("Xft metrics %s[%d] = %d (%d,%d)%s advance %d, actual %d%s%s\n",\ #data,\ fontnum,\ XftFp(data)->height,\ XftFp(data)->ascent,\ XftFp(data)->descent,\ ((XftFp(data)->ascent + XftFp(data)->descent) > XftFp(data)->height ? "*" : ""),\ XftFp(data)->max_advance_width,\ data->font_info.min_width,\ data->font_info.mixed ? " mixed" : "",\ err ? " ERROR" : ""));\ if (err) {\ xtermCloseXft(screen, data);\ memset((data), 0, sizeof(*data));\ failed += err;\ }\ } #if OPT_REPORT_FONTS static FcChar32 xtermXftFirstChar(XftFont *xft) { FcChar32 map[FC_CHARSET_MAP_SIZE]; FcChar32 next; FcChar32 first; int i; first = FcCharSetFirstPage(xft->charset, map, &next); for (i = 0; i < FC_CHARSET_MAP_SIZE; i++) { if (map[i]) { FcChar32 bits = map[i]; first += (FcChar32) i *32; while (!(bits & 0x1)) { bits >>= 1; first++; } break; } } return first; } static FcChar32 xtermXftLastChar(XftFont *xft) { FcChar32 temp, last, next; FcChar32 map[FC_CHARSET_MAP_SIZE]; int i; last = FcCharSetFirstPage(xft->charset, map, &next); while ((temp = FcCharSetNextPage(xft->charset, map, &next)) != FC_CHARSET_DONE) last = temp; last &= (FcChar32) ~ 0xff; for (i = FC_CHARSET_MAP_SIZE - 1; i >= 0; i--) { if (map[i]) { FcChar32 bits = map[i]; last += (FcChar32) i *32 + 31; while (!(bits & 0x80000000)) { last--; bits <<= 1; } break; } } return (FcChar32) last; } #endif /* OPT_REPORT_FONTS */ #if OPT_TRACE #if !OPT_WIDE_CHARS static Char * convertToUTF8(Char *buffer, int c) { buffer[0] = (Char) c; buffer[1] = 0; return buffer; } #endif static void dumpXft(XtermWidget xw, XTermXftFonts *data) { XftFont *xft = XftFp(data); TScreen *screen = TScreenOf(xw); VTwin *win = WhichVWin(screen); FcChar32 c; FcChar32 first = xtermXftFirstChar(xft); FcChar32 last = xtermXftLastChar(xft); FcChar32 dump; unsigned count = 0; unsigned too_high = 0; unsigned too_wide = 0; Boolean skip = False; TRACE(("dumpXft " TRACE_L "\n")); TRACE(("\tdata range U+%04X..U+%04X\n", first, last)); TRACE(("\tcode\tcells\tdimensions\n")); #if OPT_TRACE < 2 dump = 255; #else dump = last; #endif for (c = first; c <= last; ++c) { if (FcCharSetHasChar(xft->charset, c)) { int width = CharWidth(screen, c); XGlyphInfo extents; Boolean big_x; Boolean big_y; XftTextExtents32(XtDisplay(xw), xft, &c, 1, &extents); big_x = (extents.width > win->f_width); big_y = (extents.height > win->f_height); if (c <= dump) { Char buffer[80]; *convertToUTF8(buffer, c) = '\0'; TRACE(("%s%s\tU+%04X\t%d\t%.1f x %.1f\t%s\n", (big_y ? "y" : ""), (big_x ? "x" : ""), c, width, ((double) extents.height) / win->f_height, ((double) extents.width) / win->f_width, buffer)); } else if (!skip) { skip = True; TRACE(("\t...skipping\n")); } if (big_y) ++too_high; if (big_x) ++too_wide; ++count; } } TRACE((TRACE_R " %u total, %u too-high, %u too-wide\n", count, too_high, too_wide)); } #define DUMP_XFT(xw, data) dumpXft(xw, data) #else #define DUMP_XFT(xw, data) /* nothing */ #endif /* * Check if this is a FC_COLOR font, which fontconfig misrepresents to "fix" a * problem with web browsers. As of 2018/12 (4 years later), Xft does not work * with that. Even with this workaround, fontconfig has at least one bug which * causes it to crash (Debian #917034). */ #ifdef FC_COLOR #define GetFcBool(pattern, what) \ FcOK(FcPatternGetBool(pattern, what, 0, &fcbogus)) static Boolean isBogusXft(XftFont *font) { Boolean result = False; if (font != NULL) { FcBool fcbogus; if (GetFcBool(font->pattern, FC_COLOR) && fcbogus) { TRACE(("...matched color-bitmap font\n")); #if !USE_FC_COLOR result = True; #endif } else if (GetFcBool(font->pattern, FC_OUTLINE) && !fcbogus) { TRACE(("...matched non-outline font\n")); /* This is legal for regular bitmap fonts - fontconfig attempts to * find a match - but problematic for misencoded color-bitmap fonts. */ } } return result; } #endif #if OPT_BOX_CHARS static void setBrokenBoxChars(XtermWidget xw, Bool state) { TRACE(("setBrokenBoxChars %s\n", BtoS(state))); term->work.broken_box_chars = (Boolean) state; TScreenOf(xw)->broken_box_chars = (Boolean) state; update_font_boxchars(); } #else #define setBrokenBoxChars(xw, state) /* nothing */ #endif static Boolean checkedXftWidth(Display *dpy, XTermXftFonts *source, unsigned limit, Dimension *width, FcChar32 c) { Boolean result = False; if (FcCharSetHasChar(XftFp(source)->charset, c)) { XGlyphInfo extents; result = True; XftTextExtents32(dpy, XftFp(source), &c, 1, &extents); if (*width < extents.width && extents.width <= limit) { *width = extents.width; } } return result; } /* * Check if the given character has a glyph known to Xft. This is likely to be * slower than checking our cache. * * see xc/lib/Xft/xftglyphs.c */ static Bool slowXftMissing(XtermWidget xw, XftFont *font, unsigned wc) { TScreen *screen = TScreenOf(xw); Bool result = False; if (font != NULL) { if (XftCharIndex(screen->display, font, wc) == 0) result = True; } return result; } static int checkXftWidth(XtermWidget xw, XTermXftFonts *data) { FcChar32 c; FcChar32 last = xtermXftLastChar(XftFp(data)); Dimension limit = (Dimension) XftFp(data)->max_advance_width; Dimension width = 0; Dimension width2 = 0; int failed = 0; #if OPT_WIDE_CHARS Cardinal n; #endif data->font_info.min_width = 0; data->font_info.max_width = limit; #if OPT_WIDE_CHARS /* * Check if the line-drawing characters are all provided in the font. * If so, take that into account for the cell-widths. */ for (n = 0; n < XtNumber(unicode_boxes) - 1; ++n) { if (!checkedXftWidth(XtDisplay(xw), data, limit, &width2, unicode_boxes[n].code)) { width2 = 0; TRACE(("font omits U+%04X line-drawing symbol\n", unicode_boxes[n].code)); break; } } #else (void) width2; #endif if (width2 > 0) { Dimension check = (Dimension) (limit + 1) / 2; TRACE(("font provides VT100-style line-drawing\n")); /* * The "VT100 line-drawing" characters happen to be all "ambiguous * width" in Unicode's scheme. That means that they could be twice as * wide as the Latin-1 characters. */ #define FC_ERR(n) (1.2 * (n)) if (width2 > FC_ERR(check)) { TRACE(("line-drawing characters appear to be double-width (ignore)\n")); setBrokenBoxChars(xw, True); } else if (width2 > width) { width = width2; } } else { TRACE(("font does NOT provide VT100-style line-drawing\n")); setBrokenBoxChars(xw, True); } /* * For each printable code, ask what its width is. Given the maximum width * for those, we have a reasonable estimate of the single-column width. * * Ignore control characters - their extent information is misleading. */ for (c = 32; c < 256; ++c) { if (CharWidth(TScreenOf(xw), c) <= 0) continue; if (FcCharSetHasChar(XftFp(data)->charset, c)) { (void) checkedXftWidth(XtDisplay(xw), data, data->font_info.max_width, &width, c); } } /* * Sometimes someone uses a symbol font which has no useful ASCII or * Latin-1 characters. Allow that, in case they did it intentionally. */ if (width == 0) { failed = 1; if (last >= 256) { width = data->font_info.max_width; } } data->font_info.min_width = width; data->font_info.mixed = (data->font_info.max_width >= (data->font_info.min_width + 1)); return failed; } #if OPT_TRACE static const char * nameOfXftFont(XftFont *fp) { static char *result; char buffer[1024]; FreeAndNull(result); if (XftNameUnparse(fp->pattern, buffer, (int) sizeof(buffer))) { char *target; char *source = buffer; if ((target = strtok(source, ":")) != NULL) { result = x_strdup(target); } } return NonNull(result); } #endif #if OPT_REPORT_FONTS static void reportXftFonts(XtermWidget xw, XTermXftFonts *fontData, int fontNum, XftFont *fp, const char *name, const char *tag, XftPattern *match) { if (resource.reportFonts) { char buffer[1024]; FcChar32 first_char = xtermXftFirstChar(fp); FcChar32 last_char = xtermXftLastChar(fp); FcChar32 ch; unsigned missing = 0; ReportFonts("Loaded XftFonts(%s[%s])\n", name, tag); for (ch = first_char; ch <= last_char; ++ch) { if (xtermXftMissing(xw, fontData, fontNum, fp, ch)) { ++missing; } } ReportFonts("\t\tfirst char: %u\n", first_char); ReportFonts("\t\tlast char: %u\n", last_char); ReportFonts("\t\tmissing-chars: %u\n", missing); ReportFonts("\t\tpresent-chars: %u\n", ((last_char - first_char) + 1 - missing)); if (XftNameUnparse(match, buffer, (int) sizeof(buffer))) { char *target; char *source = buffer; while ((target = strtok(source, ":")) != NULL) { ReportFonts("\t%s\n", target); source = NULL; } } fflush(stdout); } } static void reportXftFallbackFont(XtermWidget xw, XTermXftFonts *fontData, int fontNum, XftFont *font, XftPattern *match) { if (resource.reportFonts) { char tag[80]; sprintf(tag, "%s#%d", whichXftFonts(xw, fontData), fontNum + 1); reportXftFonts(xw, fontData, fontNum, font, "fallback", tag, match); } } #else #define reportXftFonts(xw, fontData, fontNum, result, name, tag, match) /* empty */ #define reportXftFallbackFont(xw, fontData, fontNum, font, match) /* empty */ #endif /* OPT_REPORT_FONTS */ /* * Xft discards the pattern-match during open-pattern if the result happens to * match a currently-open file, but provides no clue to the caller when it does * this. That is, closing a font-file may leave the data in Xft's cache, while * opening a file may free the data used for the match. * * Because of this problem, we cannot reliably refer to the pattern-match data * if it may have been seen before. */ Boolean maybeXftCache(XtermWidget xw, XftFont *font) { Boolean result = False; if (font != NULL) { TScreen *screen = TScreenOf(xw); ListXftFonts *p; for (p = screen->list_xft_fonts; p != NULL; p = p->next) { if (p->font == font) { result = True; break; } } if (!result) { p = TypeXtMalloc(ListXftFonts); if (p != NULL) { p->font = font; p->next = screen->list_xft_fonts; screen->list_xft_fonts = p; } } } return result; } /* * Drop an entry from the cache, and close the font. */ void closeCachedXft(TScreen *screen, XftFont *font) { if (font != NULL) { ListXftFonts *p, *q; for (p = screen->list_xft_fonts, q = NULL; p != NULL; q = p, p = p->next) { if (p->font == font) { XftFontClose(screen->display, font); if (q != NULL) { q->next = p->next; } else { screen->list_xft_fonts = p->next; } free(p); break; } } } } static void xtermOpenXft(XtermWidget xw, XTermXftFonts *fontData, int fontNum, const char *name, XftPattern *pat, const char *tag) { TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; XftResult status; XftFont *result = NULL; TRACE(("xtermOpenXft(name=%s, tag=%s)\n", name, tag)); if (pat != NULL && (fontNum <= MaxXftCache)) { XftPattern *match; FcConfigSubstitute(NULL, pat, FcMatchPattern); XftDefaultSubstitute(dpy, DefaultScreen(dpy), pat); match = FcFontMatch(NULL, pat, &status); if (match != NULL) { Boolean maybeReopened = False; result = XftFontOpenPattern(dpy, match); #ifdef FC_COLOR if (result != NULL) { if (isBogusXft(result)) { XftFontClose(dpy, result); result = NULL; maybeReopened = True; } } #endif if (result != NULL) { TRACE(("...matched %s font\n", tag)); if (fontData->fs_size < fontNum) fontData->fs_size = fontNum; XftFpN(fontData, fontNum) = result; XftIsN(fontData, fontNum) = xcOpened; if (!maybeXftCache(xw, result)) { reportXftFonts(xw, fontData, fontNum, result, name, tag, match); } } else { TRACE(("...could not open %s font\n", tag)); if (!maybeReopened) XftPatternDestroy(match); if (xw->misc.fontWarnings >= fwAlways) { cannotFont(xw, "open", tag, name); } } } else { TRACE(("...did not match %s font\n", tag)); if (xw->misc.fontWarnings >= fwResource) { cannotFont(xw, "match", tag, name); } } } if (result == NULL && (fontNum <= MaxXftCache)) { XftFpN(fontData, fontNum) = NULL; XftIsN(fontData, fontNum) = xcEmpty; } } #if OPT_SHIFT_FONTS /* * Don't make a dependency on the math library for a single function. * (Newton Raphson). */ static double dimSquareRoot(double value) { double result = 0.0; if (value > 0.0) { int n; double older = value; for (n = 0; n < 10; ++n) { double delta = (older * older - value) / (2.0 * older); double newer = older - delta; older = newer; result = newer; if (delta > -0.001 && delta < 0.001) break; } } return result; } #endif #ifdef DEBUG_XFT static void trace_xft_glyph(XtermWidget xw, XTermXftFonts *data, FT_Face face, int code, const char *name) { if (xtermXftMissing(xw, data, 0, XftFp(data), code)) { TRACE(("Xft glyph U+%04X missing :%s\n", code, name)); } else if (FT_Load_Char(face, code, FT_LOAD_RENDER) == 0) { FT_GlyphSlot g = face->glyph; TRACE(("Xft glyph U+%04X size(%3d,%3d) at(%3d,%3d) :%s\n", code, g->bitmap.rows, g->bitmap.width, g->bitmap_top, g->bitmap_left, name)); } } #if OPT_WIDE_CHARS static void trace_xft_line_drawing(XtermWidget xw, XTermXftFonts *data, FT_Face face) { int n; for (n = 0; unicode_boxes[n].code != 0; ++n) { trace_xft_glyph(xw, data, face, unicode_boxes[n].code, unicode_boxes[n].name); } } #else #define trace_xft_line_drawing(xw, data, face) /* nothing */ #endif #endif /* DEBUG_XFT */ /* * Check if the line-drawing characters do not fill the bounding box. If so, * they're not useful. */ #if OPT_BOX_CHARS static void linedrawing_gaps(XtermWidget xw, XTermXftFonts *data) { Boolean broken; #if OPT_WIDE_CHARS TScreen *screen = TScreenOf(xw); int n; FT_Face face; face = XftLockFace(XftFp(data)); broken = False; for (n = 0; unicode_boxes[n].code; ++n) { unsigned code = unicode_boxes[n].code; if (xtermXftMissing(xw, data, 0, XftFp(data), code)) { TRACE(("Xft glyph U+%04X is missing\n", code)); broken = True; break; } if (FT_Load_Char(face, code, FT_LOAD_RENDER) == 0) { FT_GlyphSlot g = face->glyph; TRACE(("Xft glyph U+%04X size(%3d,%3d) at(%3d,%3d) :%s\n", code, g->bitmap.rows, g->bitmap.width, g->bitmap_top, g->bitmap_left, unicode_boxes[n].name)); /* * While it is possible for badly-designed fonts to have line * drawing characters which do not meet, FreeType aggravates the * situation with its rounding. Check for an obvious case where * the weights at the ends of a vertical line do not add up. That * shows up as two under-weight rows at the beginning/end of the * bitmap. */ if (code == 0x2502) { unsigned r, c; unsigned mids = 0, ends = 0; unsigned char *buffer = g->bitmap.buffer; switch (g->bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: /* FALLTHRU */ case FT_PIXEL_MODE_GRAY: for (r = 0; r < (unsigned) g->bitmap.rows; ++r) { unsigned k = r * (unsigned) g->bitmap.pitch; unsigned sum = 0; for (c = 0; c < (unsigned) g->bitmap.width; ++c) { unsigned xx = 0; switch (g->bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: xx = (unsigned) ((buffer[k + (c / 8)] >> (c % 8)) & 1); break; case FT_PIXEL_MODE_GRAY: xx = buffer[k + c]; break; } sum += xx; TRACE2((" %2x", xx)); } TRACE2((" = %u\n", sum)); if (r > 0 && (r + 1) < (unsigned) g->bitmap.rows) { mids = sum; } else { ends += sum; } } TRACE(("...compare middle %u vs ends %u\n", mids, ends)); if ((mids > ends) && (g->bitmap.rows < 16)) broken = True; break; default: TRACE(("FIXME pixel_mode %d not handled\n", g->bitmap.pixel_mode)); break; } if (broken) break; } /* * The factor of two accounts for line-drawing that goes through * the middle of a cell, possibly leaving half of the cell unused. * A horizontal line has to extend the full width of the cell. */ switch (unicode_boxes[n].high) { case 1: if ((unsigned) g->bitmap.rows < (unsigned) FontHeight(screen)) { TRACE(("...bitmap is shorter than full-cell (%u vs %u)\n", (unsigned) g->bitmap.rows, (unsigned) FontHeight(screen))); broken = True; } break; case 2: if ((unsigned) (g->bitmap.rows * 2) < (unsigned) FontHeight(screen)) { TRACE(("...bitmap is too short for half-cell (%u vs %u)\n", (unsigned) (g->bitmap.rows * 2), (unsigned) FontHeight(screen))); broken = True; } break; } switch (unicode_boxes[n].wide) { case 1: if ((unsigned) g->bitmap.width < (unsigned) FontWidth(screen)) { TRACE(("...bitmap is narrower than full-cell (%u vs %u)\n", (unsigned) g->bitmap.width, (unsigned) FontWidth(screen))); broken = True; } break; case 2: if ((unsigned) (g->bitmap.width * 2) < (unsigned) FontWidth(screen)) { TRACE(("...bitmap is too narrow for half-cell (%u vs %u)\n", (unsigned) (g->bitmap.width * 2), (unsigned) FontWidth(screen))); broken = True; } break; } if (broken) break; } } XftUnlockFace(XftFp(data)); #else (void) data; broken = True; #endif if (broken) { TRACE(("Xft line-drawing would not work\n")); setBrokenBoxChars(xw, True); } } #endif /* OPT_BOX_CHARS */ /* * Given the Xft font metrics, determine the actual font size. This is used * for each font to ensure that normal, bold and italic fonts follow the same * rule. */ static void setRenderFontsize(XtermWidget xw, VTwin *win, XTermXftFonts *data, const char *tag) { XftFont *font = XftFp(data); if (font != NULL) { TScreen *screen = TScreenOf(xw); int width, height, ascent, descent; #ifdef DEBUG_XFT int n; FT_Face face; FT_Size size; FT_Size_Metrics metrics; Boolean scalable; Boolean is_fixed; Boolean debug_xft = False; face = XftLockFace(font); size = face->size; metrics = size->metrics; is_fixed = FT_IS_FIXED_WIDTH(face); scalable = FT_IS_SCALABLE(face); trace_xft_line_drawing(xw, data, face); for (n = 32; n < 127; ++n) { char name[80]; sprintf(name, "letter \"%c\"", n); trace_xft_glyph(xw, data, face, n, name); } XftUnlockFace(font); /* freetype's inconsistent for this sign */ metrics.descender = -metrics.descender; #define TR_XFT "Xft metrics: " #define D_64(name) ((double)(metrics.name)/64.0) #define M_64(a,b) ((font->a * 64) != metrics.b) #define BOTH(a,b) D_64(b), M_64(a,b) ? "*" : "" debug_xft = (M_64(ascent, ascender) || M_64(descent, descender) || M_64(height, height) || M_64(max_advance_width, max_advance)); TRACE(("Xft font is %sscalable, %sfixed-width\n", is_fixed ? "" : "not ", scalable ? "" : "not ")); if (debug_xft) { TRACE(("Xft font size %d+%d vs %d by %d\n", font->ascent, font->descent, font->height, font->max_advance_width)); TRACE((TR_XFT "ascender %6.2f%s\n", BOTH(ascent, ascender))); TRACE((TR_XFT "descender %6.2f%s\n", BOTH(descent, descender))); TRACE((TR_XFT "height %6.2f%s\n", BOTH(height, height))); TRACE((TR_XFT "max_advance %6.2f%s\n", BOTH(max_advance_width, max_advance))); } else { TRACE((TR_XFT "matches font\n")); } #endif width = font->max_advance_width; height = font->height; ascent = font->ascent; descent = font->descent; if (screen->force_xft_height && height < ascent + descent) { TRACE(("...height is less than ascent + descent (%u vs %u)\n", height, ascent + descent)); if ((ascent + descent) > (height + 1)) { /* this happens less than 10% of the time */ --ascent; --descent; TRACE(("...decrement both ascent and descent before retry\n")); } else if (ascent > descent) { /* this is the usual case */ --ascent; TRACE(("...decrement ascent before retry\n")); } else { /* this could happen, though rare... */ --descent; TRACE(("...decrement descent before retry\n")); } height = ascent + descent; font->ascent = ascent; font->descent = descent; TRACE(("...updated height %d vs %d (ascent %d, descent %d)\n", height, ascent + descent, ascent, descent)); } if (is_double_width_font_xft(screen->display, font)) { TRACE(("...reduce width from %d to %d\n", width, width >> 1)); width >>= 1; } if (tag == NULL) { SetFontWidth(screen, win, width); SetFontHeight(screen, win, height); win->f_ascent = ascent; win->f_descent = descent; TRACE(("setRenderFontsize result %dx%d (%d+%d)\n", width, height, ascent, descent)); } else if (win->f_width < width || win->f_height < height || win->f_ascent < ascent || win->f_descent < descent) { TRACE(("setRenderFontsize %s changed %dx%d (%d+%d) to %dx%d (%d+%d)\n", tag, win->f_width, win->f_height, win->f_ascent, win->f_descent, width, height, ascent, descent)); SetFontWidth(screen, win, width); SetFontHeight(screen, win, height); win->f_ascent = ascent; win->f_descent = descent; } else { TRACE(("setRenderFontsize %s unchanged\n", tag)); } #if OPT_BOX_CHARS if (!screen->broken_box_chars && (tag == NULL)) { linedrawing_gaps(xw, data); } #endif } } #endif static void checkFontInfo(int value, const char *tag, int failed) { if (value == 0 || failed) { if (value == 0) { xtermWarning("Selected font has no non-zero %s for ISO-8859-1 encoding\n", tag); exit(ERROR_MISC); } else { xtermWarning("Selected font has no valid %s for ISO-8859-1 encoding\n", tag); } } } #if OPT_RENDERFONT void xtermCloseXft(TScreen *screen, XTermXftFonts *pub) { if (XftFp(pub) != NULL) { int n; if (pub->pattern) { XftPatternDestroy(pub->pattern); pub->pattern = NULL; } if (pub->fontset) { XftFontSetDestroy(pub->fontset); pub->fontset = NULL; } for (n = 0; n <= pub->fs_size; ++n) { if (XftFpN(pub, n) != NULL) { closeCachedXft(screen, XftFpN(pub, n)); XftFpN(pub, n) = NULL; XftIsN(pub, n) = xcEmpty; } } FreeAndNull(pub->font_map.per_font); memset(pub, 0, sizeof(*pub)); } } /* * Get the faceName/faceNameDoublesize resource setting. */ String getFaceName(XtermWidget xw, Bool wideName) { #if OPT_RENDERWIDE String result = (wideName ? FirstItemOf(xw->work.fonts.xft.list_w) : CurrentXftFont(xw)); #else String result = CurrentXftFont(xw); (void) wideName; #endif return x_nonempty(result); } /* * If we change the faceName, we'll have to re-acquire all of the fonts that * are derived from it. */ void setFaceName(XtermWidget xw, const char *value) { TScreen *screen = TScreenOf(xw); Boolean changed = (Boolean) ((CurrentXftFont(xw) == NULL) || strcmp(CurrentXftFont(xw), value)); if (changed) { int n; CurrentXftFont(xw) = x_strdup(value); for (n = 0; n < NMENUFONTS; ++n) { int e; xw->misc.face_size[n] = -1.0; for (e = 0; e < fMAX; ++e) { xtermCloseXft(screen, getMyXftFont(xw, e, n)); } } } } #endif /* * Compute useful values for the font/window sizes */ void xtermComputeFontInfo(XtermWidget xw, VTwin *win, XFontStruct *font, int sbwidth) { TScreen *screen = TScreenOf(xw); int i, j, width, height; #if OPT_RENDERFONT int fontnum = screen->menu_font_number; #endif int failed = 0; #if OPT_RENDERFONT /* * xterm contains a lot of references to fonts, assuming they are fixed * size. This chunk of code overrides the actual font-selection (see * drawXtermText()), if the user has selected render-font. All of the * font-loading for fixed-fonts still goes on whether or not this chunk * overrides it. */ if (UsingRenderFont(xw) && fontnum >= 0) { String face_name = getFaceName(xw, False); XTermXftFonts *norm = &(screen->renderFontNorm[fontnum]); XTermXftFonts *bold = &(screen->renderFontBold[fontnum]); XTermXftFonts *ital = &(screen->renderFontItal[fontnum]); XTermXftFonts *btal = &(screen->renderFontBtal[fontnum]); #if OPT_RENDERWIDE XTermXftFonts *wnorm = &(screen->renderWideNorm[fontnum]); XTermXftFonts *wbold = &(screen->renderWideBold[fontnum]); XTermXftFonts *wital = &(screen->renderWideItal[fontnum]); XTermXftFonts *wbtal = &(screen->renderWideBtal[fontnum]); #endif if (XftFp(norm) == NULL && !IsEmpty(face_name)) { Work *work = &(xw->work); XftPattern *pat; double face_size; TRACE(("xtermComputeFontInfo font %d: norm(face %s, size %.1f)\n", fontnum, face_name, xw->misc.face_size[fontnum])); TRACE(("Using Xft %d\n", XftGetVersion())); TRACE(("Using FontConfig %d\n", FC_VERSION)); if (work->xft_defaults == NULL) { FcInit(); work->xft_defaults = FcPatternCreate(); XftDefaultSubstitute(screen->display, XScreenNumberOfScreen(XtScreen(xw)), work->xft_defaults); if (screen->xft_max_glyph_memory > 0) { FcPatternAddInteger(work->xft_defaults, XFT_MAX_GLYPH_MEMORY, screen->xft_max_glyph_memory); } if (screen->xft_max_unref_fonts > 0) { FcPatternAddInteger(work->xft_defaults, XFT_MAX_UNREF_FONTS, screen->xft_max_unref_fonts); } #ifdef XFT_TRACK_MEM_USAGE FcPatternAddBool(work->xft_defaults, XFT_TRACK_MEM_USAGE, screen->xft_track_mem_usage); #endif XftDefaultSet(screen->display, work->xft_defaults); } fillInFaceSize(xw, fontnum); face_size = (double) xw->misc.face_size[fontnum]; /* * By observation (there is no documentation), XftPatternBuild is * cumulative. Build the bold- and italic-patterns on top of the * normal pattern. */ #ifdef FC_COLOR #if USE_FC_COLOR #define NormXftPattern \ XFT_FAMILY, XftTypeString, "mono", \ FC_OUTLINE, XftTypeBool, FcTrue, \ XFT_SIZE, XftTypeDouble, face_size #else #define NormXftPattern \ XFT_FAMILY, XftTypeString, "mono", \ FC_COLOR, XftTypeBool, FcFalse, \ FC_OUTLINE, XftTypeBool, FcTrue, \ XFT_SIZE, XftTypeDouble, face_size #endif #else #define NormXftPattern \ XFT_FAMILY, XftTypeString, "mono", \ XFT_SIZE, XftTypeDouble, face_size #endif #define BoldXftPattern(norm) \ XFT_WEIGHT, XftTypeInteger, XFT_WEIGHT_BOLD, \ XFT_CHAR_WIDTH, XftTypeInteger, XftFp(norm)->max_advance_width #define ItalXftPattern(norm) \ XFT_SLANT, XftTypeInteger, XFT_SLANT_ITALIC, \ XFT_CHAR_WIDTH, XftTypeInteger, XftFp(norm)->max_advance_width #define BtalXftPattern(norm) \ XFT_WEIGHT, XftTypeInteger, XFT_WEIGHT_BOLD, \ XFT_SLANT, XftTypeInteger, XFT_SLANT_ITALIC, \ XFT_CHAR_WIDTH, XftTypeInteger, XftFp(norm)->max_advance_width #if OPT_WIDE_ATTRS #define HAVE_ITALICS 1 #define FIND_ITALICS ((pat = XftNameParse(face_name)) != NULL) #elif OPT_ISO_COLORS #define HAVE_ITALICS 1 #define FIND_ITALICS (screen->italicULMode && (pat = XftNameParse(face_name)) != 0) #else #define HAVE_ITALICS 0 #endif #if OPT_DEC_CHRSET freeall_DoubleFT(xw); #endif if ((pat = XftNameParse(face_name)) != NULL) { #define OPEN_XFT(data, tag) xtermOpenXft(xw, data, 0, face_name, data->pattern, tag) norm->pattern = XftPatternDuplicate(pat); XftPatternBuild(norm->pattern, NormXftPattern, (void *) 0); OPEN_XFT(norm, "normal"); if (XftFp(norm) != NULL) { bold->pattern = XftPatternDuplicate(pat); XftPatternBuild(bold->pattern, NormXftPattern, BoldXftPattern(norm), (void *) 0); OPEN_XFT(bold, "bold"); #if HAVE_ITALICS if (FIND_ITALICS) { ital->pattern = XftPatternDuplicate(pat); XftPatternBuild(ital->pattern, NormXftPattern, ItalXftPattern(norm), (void *) 0); OPEN_XFT(ital, "italic"); btal->pattern = XftPatternDuplicate(pat); XftPatternBuild(btal->pattern, NormXftPattern, BtalXftPattern(norm), (void *) 0); OPEN_XFT(btal, "bold-italic"); } #endif /* * FIXME: just assume that the corresponding font has no * graphics characters. */ if (screen->fnt_boxes) { screen->fnt_boxes = 0; TRACE(("Xft opened - will not use internal line-drawing characters\n")); } } CACHE_XFT(norm); CACHE_XFT(bold); if (XftFp(norm) != NULL && !XftFp(bold)) { noUsableXft(xw, "bold"); XftPatternDestroy(bold->pattern); bold->pattern = XftPatternDuplicate(pat); XftPatternBuild(bold->pattern, NormXftPattern, (void *) 0); OPEN_XFT(bold, "bold"); failed = 0; CACHE_XFT(bold); } #if HAVE_ITALICS CACHE_XFT(ital); if (XftFp(norm) != NULL && !XftFp(ital)) { noUsableXft(xw, "italic"); XftPatternDestroy(ital->pattern); ital->pattern = XftPatternDuplicate(pat); XftPatternBuild(ital->pattern, NormXftPattern, (void *) 0); OPEN_XFT(ital, "italics"); failed = 0; CACHE_XFT(ital); } CACHE_XFT(btal); if (XftFp(norm) != NULL && !XftFp(btal)) { noUsableXft(xw, "bold italic"); XftPatternDestroy(btal->pattern); btal->pattern = XftPatternDuplicate(pat); XftPatternBuild(btal->pattern, NormXftPattern, (void *) 0); OPEN_XFT(btal, "bold-italics"); failed = 0; CACHE_XFT(btal); } #endif XftPatternDestroy(pat); } else { failed = 1; } /* * See xtermXftDrawString(). A separate double-width font is nice * to have, but not essential. */ #if OPT_RENDERWIDE if (XftFp(norm) != NULL && screen->wide_chars) { int char_width = XftFp(norm)->max_advance_width * 2; double aspect = ((FirstItemOf(xw->work.fonts.xft.list_w) || screen->renderFontNorm[fontnum].font_info.mixed) ? 1.0 : 2.0); face_name = getFaceName(xw, True); TRACE(("xtermComputeFontInfo wide(face %s, char_width %d)\n", NonNull(face_name), char_width)); #define WideXftPattern \ XFT_FAMILY, XftTypeString, "mono", \ XFT_SIZE, XftTypeDouble, face_size, \ XFT_SPACING, XftTypeInteger, XFT_MONO, \ XFT_CHAR_WIDTH, XftTypeInteger, char_width, \ FC_ASPECT, XftTypeDouble, aspect if (!IsEmpty(face_name) && (pat = XftNameParse(face_name)) != NULL) { wnorm->pattern = XftPatternDuplicate(pat); XftPatternBuild(wnorm->pattern, WideXftPattern, (void *) 0); OPEN_XFT(wnorm, "wide"); if (XftFp(wnorm) != NULL) { wbold->pattern = XftPatternDuplicate(pat); XftPatternBuild(wbold->pattern, WideXftPattern, BoldXftPattern(wnorm), (void *) 0); OPEN_XFT(wbold, "wide-bold"); #if HAVE_ITALICS if (FIND_ITALICS) { wital->pattern = XftPatternDuplicate(pat); XftPatternBuild(wital->pattern, WideXftPattern, ItalXftPattern(wnorm), (void *) 0); OPEN_XFT(wital, "wide-italic"); } CACHE_XFT(wbtal); if (!XftFp(wbtal)) { noUsableXft(xw, "wide bold"); XftPatternDestroy(wbtal->pattern); wbtal->pattern = XftPatternDuplicate(pat); XftPatternBuild(wbtal->pattern, WideXftPattern, (void *) 0); OPEN_XFT(wbtal, "wide-bold-italics"); failed = 0; CACHE_XFT(wbtal); } #endif } CACHE_XFT(wnorm); CACHE_XFT(wbold); if (XftFp(wnorm) != NULL && !XftFp(wbold)) { noUsableXft(xw, "wide-bold"); XftPatternDestroy(wbold->pattern); wbold->pattern = XftPatternDuplicate(pat); XftPatternBuild(bold->pattern, WideXftPattern, (void *) 0); OPEN_XFT(wbold, "wide-bold"); failed = 0; CACHE_XFT(bold); } CACHE_XFT(wital); if (XftFp(wnorm) != NULL && !XftFp(wital)) { noUsableXft(xw, "wide-italic"); XftPatternDestroy(wital->pattern); wital->pattern = XftPatternDuplicate(pat); XftPatternBuild(wital->pattern, WideXftPattern, (void *) 0); OPEN_XFT(wital, "wide-italic"); failed = 0; CACHE_XFT(wital); } XftPatternDestroy(pat); } #undef OPEN_XFT } #endif /* OPT_RENDERWIDE */ } if (XftFp(norm) == NULL) { TRACE(("...no TrueType font found for number %d, disable menu entry\n", fontnum)); xw->work.render_font = False; update_font_renderfont(); /* now we will fall through into the bitmap fonts */ } else { setBrokenBoxChars(xw, False); setRenderFontsize(xw, win, norm, NULL); setRenderFontsize(xw, win, bold, "bold"); setRenderFontsize(xw, win, ital, "ital"); setRenderFontsize(xw, win, btal, "btal"); #if OPT_BOX_CHARS setupPackedFonts(xw); if (screen->force_packed) { XTermXftFonts *use = &(screen->renderFontNorm[fontnum]); SetFontHeight(screen, win, XftFp(use)->ascent + XftFp(use)->descent); SetFontWidth(screen, win, use->font_info.min_width); TRACE(("...packed TrueType font %dx%d vs %d\n", win->f_height, win->f_width, use->font_info.max_width)); } #endif DUMP_XFT(xw, &(screen->renderFontNorm[fontnum])); } } /* * Are we handling a bitmap font? */ else #endif /* OPT_RENDERFONT */ { if (is_double_width_font(font) && !(screen->fnt_prop)) { SetFontWidth(screen, win, font->min_bounds.width); } else { SetFontWidth(screen, win, font->max_bounds.width); } SetFontHeight(screen, win, font->ascent + font->descent); win->f_ascent = font->ascent; win->f_descent = font->descent; } i = 2 * screen->border + sbwidth; j = 2 * screen->border; width = MaxCols(screen) * win->f_width + i; height = MaxRows(screen) * win->f_height + j; win->fullwidth = (Dimension) width; win->fullheight = (Dimension) height; win->width = width - i; win->height = height - j; TRACE(("xtermComputeFontInfo window %dx%d (full %dx%d), fontsize %dx%d (asc %d, dsc %d)\n", win->height, win->width, win->fullheight, win->fullwidth, win->f_height, win->f_width, win->f_ascent, win->f_descent)); checkFontInfo(win->f_height, "height", failed); checkFontInfo(win->f_width, "width", failed); } /* save this information as a side-effect for double-sized characters */ static void xtermSaveFontInfo(TScreen *screen, XFontStruct *font) { screen->fnt_wide = (Dimension) (font->max_bounds.width); screen->fnt_high = (Dimension) (font->ascent + font->descent); TRACE(("xtermSaveFontInfo %dx%d\n", screen->fnt_high, screen->fnt_wide)); } /* * After loading a new font, update the structures that use its size. */ void xtermUpdateFontInfo(XtermWidget xw, Bool doresize) { TScreen *screen = TScreenOf(xw); int scrollbar_width; VTwin *win = &(screen->fullVwin); #if USE_DOUBLE_BUFFER discardRenderDraw(TScreenOf(xw)); #endif /* USE_DOUBLE_BUFFER */ scrollbar_width = (xw->misc.scrollbar ? (screen->scrollWidget->core.width + BorderWidth(screen->scrollWidget)) : 0); xtermComputeFontInfo(xw, win, GetNormalFont(screen, fNorm)->fs, scrollbar_width); xtermSaveFontInfo(screen, GetNormalFont(screen, fNorm)->fs); if (doresize) { if (VWindow(screen)) { xtermClear(xw); } TRACE(("xtermUpdateFontInfo " TRACE_L "\n")); DoResizeScreen(xw); /* set to the new natural size */ ResizeScrollBar(xw); Redraw(); TRACE((TRACE_R " xtermUpdateFontInfo\n")); #ifdef SCROLLBAR_RIGHT updateRightScrollbar(xw); #endif } xtermSetCursorBox(screen); } #if OPT_BOX_CHARS || OPT_REPORT_FONTS /* * Returns true if the given character is missing from the specified font. */ Bool xtermMissingChar(unsigned ch, XTermFonts * font) { Bool result = False; XFontStruct *fs = font->fs; XCharStruct *pc = NULL; if (fs == NULL) { result = True; } else if (fs->max_byte1 == 0) { #if OPT_WIDE_CHARS if (ch < 256) #endif { CI_GET_CHAR_INFO_1D(fs, ch, pc); } } #if OPT_WIDE_CHARS else { unsigned row = (ch >> 8); unsigned col = (ch & 0xff); CI_GET_CHAR_INFO_2D(fs, row, col, pc); } #endif if (pc == NULL || CI_NONEXISTCHAR(pc)) { TRACE2(("xtermMissingChar %#04x (!exists)\n", ch)); result = True; } if (ch < MaxUChar) { font->known_missing[ch] = (Char) (result ? 2 : 1); } return result; } #endif #if OPT_BOX_CHARS || OPT_WIDE_CHARS /* * The grid is arbitrary, enough resolution that nothing's lost in * initialization. */ #define BOX_HIGH 60 #define BOX_WIDE 60 #define MID_HIGH (BOX_HIGH/2) #define MID_WIDE (BOX_WIDE/2) #define CHR_WIDE ((9*BOX_WIDE)/10) #define CHR_HIGH ((9*BOX_HIGH)/10) /* * ...since we'll scale the values anyway. */ #define Scale_XY(n,d,f) ((int)(n) * ((int)(f))) / (d) #define SCALED_X(n) Scale_XY(n, BOX_WIDE, font_width) #define SCALED_Y(n) Scale_XY(n, BOX_HIGH, font_height) #define SCALE_X(n) n = SCALED_X(n) #define SCALE_Y(n) n = SCALED_Y(n) #define SEG(x0,y0,x1,y1) x0,y0, x1,y1 /* * Draw the given graphic character, if it is simple enough (i.e., a * line-drawing character). */ void xtermDrawBoxChar(XTermDraw * params, unsigned ch, GC gc, int x, int y, int cells, Bool xftords) { TScreen *screen = TScreenOf(params->xw); /* *INDENT-OFF* */ static const short glyph_ht[] = { SEG(1*BOX_WIDE/10, 0, 1*BOX_WIDE/10,5*MID_HIGH/6), /* H */ SEG(6*BOX_WIDE/10, 0, 6*BOX_WIDE/10,5*MID_HIGH/6), SEG(1*BOX_WIDE/10,5*MID_HIGH/12,6*BOX_WIDE/10,5*MID_HIGH/12), SEG(2*BOX_WIDE/10, MID_HIGH, CHR_WIDE, MID_HIGH), /* T */ SEG(6*BOX_WIDE/10, MID_HIGH, 6*BOX_WIDE/10, CHR_HIGH), -1 }, glyph_ff[] = { SEG(1*BOX_WIDE/10, 0, 6*BOX_WIDE/10, 0), /* F */ SEG(1*BOX_WIDE/10,5*MID_HIGH/12,6*CHR_WIDE/12,5*MID_HIGH/12), SEG(1*BOX_WIDE/10, 0, 0*BOX_WIDE/3, 5*MID_HIGH/6), SEG(1*BOX_WIDE/3, MID_HIGH, CHR_WIDE, MID_HIGH), /* F */ SEG(1*BOX_WIDE/3, 8*MID_HIGH/6,10*CHR_WIDE/12,8*MID_HIGH/6), SEG(1*BOX_WIDE/3, MID_HIGH, 1*BOX_WIDE/3, CHR_HIGH), -1 }, glyph_lf[] = { SEG(1*BOX_WIDE/10, 0, 1*BOX_WIDE/10,9*MID_HIGH/12), /* L */ SEG(1*BOX_WIDE/10,9*MID_HIGH/12,6*BOX_WIDE/10,9*MID_HIGH/12), SEG(1*BOX_WIDE/3, MID_HIGH, CHR_WIDE, MID_HIGH), /* F */ SEG(1*BOX_WIDE/3, 8*MID_HIGH/6,10*CHR_WIDE/12,8*MID_HIGH/6), SEG(1*BOX_WIDE/3, MID_HIGH, 1*BOX_WIDE/3, CHR_HIGH), -1 }, glyph_nl[] = { SEG(1*BOX_WIDE/10,5*MID_HIGH/6, 1*BOX_WIDE/10, 0), /* N */ SEG(1*BOX_WIDE/10, 0, 5*BOX_WIDE/6, 5*MID_HIGH/6), SEG(5*BOX_WIDE/6, 5*MID_HIGH/6, 5*BOX_WIDE/6, 0), SEG(1*BOX_WIDE/3, MID_HIGH, 1*BOX_WIDE/3, CHR_HIGH), /* L */ SEG(1*BOX_WIDE/3, CHR_HIGH, CHR_WIDE, CHR_HIGH), -1 }, glyph_vt[] = { SEG(1*BOX_WIDE/10, 0, 5*BOX_WIDE/12,5*MID_HIGH/6), /* V */ SEG(5*BOX_WIDE/12,5*MID_HIGH/6, 5*BOX_WIDE/6, 0), SEG(2*BOX_WIDE/10, MID_HIGH, CHR_WIDE, MID_HIGH), /* T */ SEG(6*BOX_WIDE/10, MID_HIGH, 6*BOX_WIDE/10, CHR_HIGH), -1 }, plus_or_minus[] = { SEG( 0, 5*BOX_HIGH/6, CHR_WIDE, 5*BOX_HIGH/6), SEG( MID_WIDE, 2*BOX_HIGH/6, MID_WIDE, 4*BOX_HIGH/6), SEG( 0, 3*BOX_HIGH/6, CHR_WIDE, 3*BOX_HIGH/6), -1 }, lower_right_corner[] = { SEG( 0, MID_HIGH, MID_WIDE, MID_HIGH), SEG( MID_WIDE, MID_HIGH, MID_WIDE, 0), -1 }, upper_right_corner[] = { SEG( 0, MID_HIGH, MID_WIDE, MID_HIGH), SEG( MID_WIDE, MID_HIGH, MID_WIDE, BOX_HIGH), -1 }, upper_left_corner[] = { SEG( MID_WIDE, MID_HIGH, BOX_WIDE, MID_HIGH), SEG( MID_WIDE, MID_HIGH, MID_WIDE, BOX_HIGH), -1 }, lower_left_corner[] = { SEG( MID_WIDE, 0, MID_WIDE, MID_HIGH), SEG( MID_WIDE, MID_WIDE, BOX_WIDE, MID_HIGH), -1 }, cross[] = { SEG( 0, MID_HIGH, BOX_WIDE, MID_HIGH), SEG( MID_WIDE, 0, MID_WIDE, BOX_HIGH), -1 }, scan_line_1[] = { SEG( 0, 0, BOX_WIDE, 0), -1 }, scan_line_3[] = { SEG( 0, BOX_HIGH/4, BOX_WIDE, BOX_HIGH/4), -1 }, scan_line_7[] = { SEG( 0, MID_HIGH, BOX_WIDE, MID_HIGH), -1 }, scan_line_9[] = { SEG( 0, 3*BOX_HIGH/4, BOX_WIDE, 3*BOX_HIGH/4), -1 }, horizontal_line[] = { SEG( 0, BOX_HIGH, BOX_WIDE, BOX_HIGH), -1 }, left_tee[] = { SEG( MID_WIDE, 0, MID_WIDE, BOX_HIGH), SEG( MID_WIDE, MID_HIGH, BOX_WIDE, MID_HIGH), -1 }, right_tee[] = { SEG( MID_WIDE, 0, MID_WIDE, BOX_HIGH), SEG( MID_WIDE, MID_HIGH, 0, MID_HIGH), -1 }, bottom_tee[] = { SEG( 0, MID_HIGH, BOX_WIDE, MID_HIGH), SEG( MID_WIDE, 0, MID_WIDE, MID_HIGH), -1 }, top_tee[] = { SEG( 0, MID_HIGH, BOX_WIDE, MID_HIGH), SEG( MID_WIDE, MID_HIGH, MID_WIDE, BOX_HIGH), -1 }, vertical_line[] = { SEG( MID_WIDE, 0, MID_WIDE, BOX_HIGH), -1 }, less_than_or_equal[] = { SEG( CHR_WIDE, BOX_HIGH/3, 0, MID_HIGH), SEG( CHR_WIDE, 2*BOX_HIGH/3, 0, MID_HIGH), SEG( 0, 3*BOX_HIGH/4, CHR_WIDE, 3*BOX_HIGH/4), -1 }, greater_than_or_equal[] = { SEG( 0, BOX_HIGH/3, CHR_WIDE, MID_HIGH), SEG( 0, 2*BOX_HIGH/3, CHR_WIDE, MID_HIGH), SEG( 0, 3*BOX_HIGH/4, CHR_WIDE, 3*BOX_HIGH/4), -1 }, greek_pi[] = { SEG( 0, MID_HIGH, CHR_WIDE, MID_HIGH), SEG(5*CHR_WIDE/6, MID_HIGH, 5*CHR_WIDE/6, CHR_HIGH), SEG(2*CHR_WIDE/6, MID_HIGH, 2*CHR_WIDE/6, CHR_HIGH), -1 }, not_equal_to[] = { SEG(2*BOX_WIDE/3, 1*BOX_HIGH/3, 1*BOX_WIDE/3, CHR_HIGH), SEG( 0, 2*BOX_HIGH/3, CHR_WIDE, 2*BOX_HIGH/3), SEG( 0, MID_HIGH, CHR_WIDE, MID_HIGH), -1 }, sigma_1[] = { SEG(BOX_WIDE, MID_HIGH, BOX_WIDE/2, MID_HIGH), SEG(BOX_WIDE/2, MID_HIGH, BOX_WIDE, BOX_HIGH), -1 }, sigma_2[] = { SEG(BOX_WIDE, MID_HIGH, BOX_WIDE/2, MID_HIGH), SEG(BOX_WIDE/2, MID_HIGH, BOX_WIDE, 0), -1 }, sigma_3[] = { SEG( 0, 0, BOX_WIDE, BOX_HIGH), -1 }, sigma_4[] = { SEG( 0, BOX_HIGH, BOX_WIDE, 0), -1 }, sigma_5[] = { SEG( 0, MID_HIGH, MID_WIDE, MID_HIGH), SEG(MID_WIDE, MID_HIGH, MID_WIDE, BOX_HIGH), -1 }, sigma_6[] = { SEG( 0, MID_HIGH, MID_WIDE, MID_HIGH), SEG(MID_WIDE, MID_HIGH, MID_WIDE, 0), -1 }, sigma_7[] = { SEG( 0, 0, MID_WIDE, MID_HIGH), SEG( 0, BOX_HIGH, MID_WIDE, MID_HIGH), -1 }; static const struct { const int mode; /* 1=y, 2=x, 3=both */ const short *const data; } lines[] = { { 0, NULL }, /* 00 (unused) */ { 0, NULL }, /* 01 diamond */ { 0, NULL }, /* 02 box */ { 0, glyph_ht }, /* 03 HT */ { 0, glyph_ff }, /* 04 FF */ { 0, NULL }, /* 05 CR */ { 0, glyph_lf }, /* 06 LF */ { 0, NULL }, /* 07 degrees (small circle) */ { 3, plus_or_minus }, /* 08 */ { 0, glyph_nl }, /* 09 */ { 0, glyph_vt }, /* 0A */ { 3, lower_right_corner }, /* 0B */ { 3, upper_right_corner }, /* 0C */ { 3, upper_left_corner }, /* 0D */ { 3, lower_left_corner }, /* 0E */ { 3, cross }, /* 0F */ { 2, scan_line_1 }, /* 10 */ { 2, scan_line_3 }, /* 11 */ { 2, scan_line_7 }, /* 12 */ { 2, scan_line_9 }, /* 13 */ { 2, horizontal_line }, /* 14 */ { 3, left_tee }, /* 15 */ { 3, right_tee }, /* 16 */ { 3, bottom_tee }, /* 17 */ { 3, top_tee }, /* 18 */ { 1, vertical_line }, /* 19 */ { 0, less_than_or_equal }, /* 1A */ { 0, greater_than_or_equal }, /* 1B */ { 0, greek_pi }, /* 1C */ { 0, not_equal_to }, /* 1D */ { 0, NULL }, /* 1E LB */ { 0, NULL }, /* 1F bullet */ { 0, NULL }, /* 20 space */ { 3, sigma_1 }, /* PUA(0) */ { 3, sigma_2 }, /* PUA(1) */ { 3, sigma_3 }, /* PUA(2) */ { 3, sigma_4 }, /* PUA(3) */ { 3, sigma_5 }, /* PUA(4) */ { 3, sigma_6 }, /* PUA(5) */ { 3, sigma_7 }, /* PUA(6) */ }; /* *INDENT-ON* */ GC gc2; CgsEnum cgsId = (ch == 2) ? gcDots : gcLine; VTwin *cgsWin = WhichVWin(screen); const short *p; unsigned font_width = (((params->draw_flags & DOUBLEWFONT) ? 2U : 1U) * screen->fnt_wide); unsigned font_height = (((params->draw_flags & DOUBLEHFONT) ? 2U : 1U) * screen->fnt_high); unsigned thick; if (cells > 1) font_width *= (unsigned) cells; #if OPT_WIDE_CHARS /* * Try to show line-drawing characters if we happen to be in UTF-8 * mode, but have gotten an old-style font. */ if (screen->utf8_mode #if OPT_RENDERFONT && !UsingRenderFont(params->xw) #endif && (ch > 127) && !is_UCS_SPECIAL(ch)) { int which = (params->attr_flags & BOLD) ? fBold : fNorm; unsigned n; for (n = 1; n < 32; n++) { if (xtermMissingChar(n, XTermFontsRef(screen->fnts, which))) continue; if (dec2ucs(screen, n) != ch) continue; TRACE(("...use xterm-style linedrawing U+%04X ->%d\n", ch, n)); ch = n; break; } } #endif #if OPT_VT52_MODE if (!(screen->vtXX_level)) { switch (ch) { case 6: ch = 7; break; default: ch = 256; break; } } #endif /* * Line-drawing characters display using the full (scaled) cellsize, while * other characters should be shifted to center them vertically. */ if (!xftords) { if ((ch < XtNumber(lines)) && (lines[ch].mode & 3) != 0) { font_height = (unsigned) ((float) font_height * screen->scale_height); } else { y += ScaleShift(screen); } } if (xtermIsDecTechnical(ch)) { ch -= XTERM_PUA; ch += 33; } TRACE(("DRAW_BOX(%02X) cell %dx%d at %d,%d%s\n", ch, font_height, font_width, y, x, ((ch >= XtNumber(lines)) ? "-BAD" : ""))); if (cgsId == gcDots) { setCgsFont(params->xw, cgsWin, cgsId, getCgsFont(params->xw, cgsWin, gc)); setCgsFore(params->xw, cgsWin, cgsId, getCgsFore(params->xw, cgsWin, gc)); setCgsBack(params->xw, cgsWin, cgsId, getCgsBack(params->xw, cgsWin, gc)); } else { setCgsFont(params->xw, cgsWin, cgsId, getCgsFont(params->xw, cgsWin, gc)); setCgsFore(params->xw, cgsWin, cgsId, getCgsBack(params->xw, cgsWin, gc)); setCgsBack(params->xw, cgsWin, cgsId, getCgsBack(params->xw, cgsWin, gc)); } gc2 = getCgsGC(params->xw, cgsWin, cgsId); if (!(params->draw_flags & NOBACKGROUND)) { XFillRectangle(screen->display, VDrawable(screen), gc2, x, y, font_width, font_height); } setCgsFont(params->xw, cgsWin, cgsId, getCgsFont(params->xw, cgsWin, gc)); setCgsFore(params->xw, cgsWin, cgsId, getCgsFore(params->xw, cgsWin, gc)); setCgsBack(params->xw, cgsWin, cgsId, getCgsBack(params->xw, cgsWin, gc)); gc2 = getCgsGC(params->xw, cgsWin, cgsId); thick = ((params->attr_flags & BOLD) ? (Max((unsigned) screen->fnt_high / 12, 1)) : (Max((unsigned) screen->fnt_high / 16, 1))); setXtermLineAttributes(screen->display, gc2, thick, ((ch < XtNumber(lines)) ? LineSolid : LineOnOffDash)); if (ch == 32) { /* space! */ ; /* boxing a missing space is pointless */ } else if (ch == 1) { /* diamond */ XPoint points[5]; int npoints = 5, n; points[0].x = MID_WIDE; points[0].y = BOX_HIGH / 4; points[1].x = 8 * BOX_WIDE / 8; points[1].y = MID_HIGH; points[2].x = points[0].x; points[2].y = 3 * BOX_HIGH / 4; points[3].x = 0 * BOX_WIDE / 8; points[3].y = points[1].y; points[4].x = points[0].x; points[4].y = points[0].y; for (n = 0; n < npoints; ++n) { points[n].x = (short) (SCALED_X(points[n].x)); points[n].y = (short) (SCALED_Y(points[n].y)); points[n].x = (short) (points[n].x + x); points[n].y = (short) (points[n].y + y); } XFillPolygon(screen->display, VDrawable(screen), gc2, points, npoints, Convex, CoordModeOrigin); } else if (ch == 7) { /* degrees */ unsigned width = (BOX_WIDE / 3); int x_coord = MID_WIDE - (int) (width / 2); int y_coord = MID_HIGH - (int) width; SCALE_X(x_coord); SCALE_Y(y_coord); width = (unsigned) SCALED_X(width); XDrawArc(screen->display, VDrawable(screen), gc2, x + x_coord, y + y_coord, width, width, 0, 360 * 64); } else if (ch == 0x1f) { /* bullet */ unsigned width = 7 * BOX_WIDE / 10; int x_coord = MID_WIDE - (int) (width / 3); int y_coord = MID_HIGH - (int) (width / 3); SCALE_X(x_coord); SCALE_Y(y_coord); width = (unsigned) SCALED_X(width); XDrawArc(screen->display, VDrawable(screen), gc2, x + x_coord, y + y_coord, width, width, 0, 360 * 64); } else if (ch < XtNumber(lines) && (p = lines[ch].data) != NULL) { int coord[4]; int n = 0; while (*p >= 0) { coord[n++] = *p++; if (n == 4) { SCALE_X(coord[0]); SCALE_Y(coord[1]); SCALE_X(coord[2]); SCALE_Y(coord[3]); XDrawLine(screen->display, VDrawable(screen), gc2, x + coord[0], y + coord[1], x + coord[2], y + coord[3]); n = 0; } } } else if (screen->force_all_chars) { /* bounding rectangle, for debugging */ if ((params->draw_flags & DOUBLEHFONT)) { XRectangle clip; clip.x = 0; clip.y = 0; clip.width = (unsigned short) ((font_width - 1) + (unsigned) thick); clip.height = (unsigned short) ((unsigned) FontHeight(screen) + thick); if ((params->draw_flags & DOUBLEFIRST)) { y -= (2 * FontDescent(screen)); clip.height = (unsigned short) (clip.height - ((unsigned short) FontDescent(screen))); } else { y -= FontHeight(screen); y += FontDescent(screen); clip.y = (short) FontHeight(screen); } XSetClipRectangles(screen->display, gc2, x, y, &clip, 1, Unsorted); } XDrawRectangle(screen->display, VDrawable(screen), gc2, x + (int) thick, y + (int) thick, font_width - (2 * thick), font_height - (2 * thick)); if ((params->draw_flags & DOUBLEHFONT)) { XSetClipMask(screen->display, gc2, None); } } resetXtermLineAttributes(screen->display, gc2); } #endif /* OPT_BOX_CHARS || OPT_WIDE_CHARS */ #if OPT_RENDERFONT static int checkXftGlyph(XtermWidget xw, XftFont *font, unsigned wc) { TScreen *screen = TScreenOf(xw); int result = 0; int expect; if ((expect = CharWidth(screen, wc)) > 0) { XGlyphInfo gi; int actual; int limit = (100 + xw->misc.limit_fontwidth); XftTextExtents32(screen->display, font, &wc, 1, &gi); /* * Some (more than a few) fonts are sloppy; allow 10% outside * the bounding box to accommodate them. */ actual = ((gi.xOff * 100) >= (limit * FontWidth(screen))) ? 2 : 1; if (actual <= expect) { /* allow double-cell if wcwidth agrees */ result = 1; } else { /* * Do not use this font for this specific character, but * possibly other characters can be used. */ result = -1; TRACE(("SKIP U+%04X %d vs %d (%d vs %d) %s\n", wc, gi.xOff, FontWidth(screen), actual, expect, nameOfXftFont(font))); } } else { result = 1; } return result; } /* * Check if the glyph is defined in the given font, and (try to) filter out * cases where double-width glyphs are stuffed into a single-width outline. */ static int foundXftGlyph(XtermWidget xw, XTermXftFonts *data, int fontNum, unsigned wc) { XftFont *font = XftFpN(data, fontNum); int result = 0; if (font != NULL) { if (!xtermXftMissing(xw, data, fontNum, font, wc)) { if (XftIsN(data, fontNum) == xcBogus) { ; } else if (XftIsN(data, fontNum) == xcOpened) { result = 1; } else { result = checkXftGlyph(xw, font, wc); } } } return result; } static void markXftOpened(XtermWidget xw, XTermXftFonts *which, int n, unsigned wc) { if (XftIsN(which, n) != xcOpened) { which->opened++; XftIsN(which, n) = xcOpened; /* XFT_DEBUG=3 will show useful context for this */ if (getenv("XFT_DEBUG") != NULL) { printf("%s: matched U+%04X in fontset #%d [%u:%u]\n", ProgramName, wc, n + 1, which->opened, xw->work.max_fontsets); } } } static char ** xftData2List(XtermWidget xw, const XTermXftFonts *fontData) { TScreen *screen = TScreenOf(xw); VTFontList *lists = &xw->work.fonts.xft; char **result = NULL; int n = screen->menu_font_number; if (fontData == &screen->renderFontNorm[n]) result = lists->list_n; else if (fontData == &screen->renderFontBold[n]) result = lists->list_b; else if (fontData == &screen->renderFontItal[n]) result = lists->list_i; else if (fontData == &screen->renderFontBtal[n]) result = lists->list_bi; #if OPT_RENDERWIDE if (fontData == &screen->renderWideNorm[n]) result = lists->list_w; else if (fontData == &screen->renderWideBold[n]) result = lists->list_wb; else if (fontData == &screen->renderWideItal[n]) result = lists->list_wi; else if (fontData == &screen->renderWideBtal[n]) result = lists->list_wbi; #endif return result; } static FcPattern * mergeXftStyle(XtermWidget xw, FcPattern * myPattern, XTermXftFonts *fontData) { TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; XftFont *given = XftFp(fontData); XftResult mStatus; int iValue; double dValue; if (FcOK(FcPatternGetInteger(fontData->pattern, XFT_WEIGHT, 0, &iValue))) { FcPatternAddInteger(myPattern, XFT_WEIGHT, iValue); } if (FcOK(FcPatternGetInteger(fontData->pattern, XFT_SLANT, 0, &iValue))) { FcPatternAddInteger(myPattern, XFT_SLANT, iValue); } if (FcOK(FcPatternGetDouble(fontData->pattern, FC_ASPECT, 0, &dValue))) { FcPatternAddDouble(myPattern, FC_ASPECT, dValue); } if (FcOK(FcPatternGetDouble(fontData->pattern, XFT_SIZE, 0, &dValue))) { FcPatternAddDouble(myPattern, XFT_SIZE, dValue); } FcPatternAddBool(myPattern, FC_SCALABLE, FcTrue); FcPatternAddInteger(myPattern, XFT_SPACING, XFT_MONO); FcPatternAddInteger(myPattern, FC_CHAR_WIDTH, given->max_advance_width); #ifdef FC_COLOR #if !USE_FC_COLOR FcPatternAddBool(myPattern, FC_COLOR, FcFalse); #endif FcPatternAddBool(myPattern, FC_OUTLINE, FcTrue); #endif FcConfigSubstitute(NULL, myPattern, FcMatchPattern); XftDefaultSubstitute(dpy, DefaultScreen(dpy), myPattern); return FcFontMatch(NULL, myPattern, &mStatus); } /* * Check if the given character has a glyph known to Xft. If it is missing, * try first to replace the font with a fallback that provides the glyph. * * Return -1 if nothing is found. Otherwise, return the index in the cache. */ int findXftGlyph(XtermWidget xw, XTermXftFonts *fontData, unsigned wc) { TScreen *screen = TScreenOf(xw); XftFont *given; XftFont *actual = NULL; FcResult status; int n; int result = -1; /* sanity-check */ if (fontData == NULL) return result; given = XftFp(fontData); /* if fontsets are not wanted, just leave */ if (xw->work.max_fontsets == 0) { return result; } /* ignore codes in private use areas */ if ((wc >= 0xe000 && wc <= 0xf8ff) || (wc >= 0xf0000 && wc <= 0xffffd) || (wc >= 0x100000 && wc <= 0x10fffd)) { return result; } /* the end of the BMP is reserved for non-characters */ if (wc >= 0xfff0 && wc <= 0xffff) { return result; } /* initialize on the first call */ if (fontData->fontset == NULL && fontData->pattern != NULL) { FcFontSet *sortedFonts; FcPattern *myPattern; int j; char **my_list; myPattern = FcPatternDuplicate(fontData->pattern); FcPatternAddBool(myPattern, FC_SCALABLE, FcTrue); FcPatternAddInteger(myPattern, FC_CHAR_WIDTH, given->max_advance_width); FcConfigSubstitute(FcConfigGetCurrent(), myPattern, FcMatchPattern); FcDefaultSubstitute(myPattern); sortedFonts = FcFontSort(NULL, myPattern, FcTrue, NULL, &status); fontData->fontset = FcFontSetCreate(); if (fontData->fontset == NULL || !sortedFonts || sortedFonts->nfont <= 0) { xtermWarning("did not find any usable TrueType font\n"); return 0; } /* * Check if there are additional fonts in the XtermFontNames.xft for * this font-data. */ if ((my_list = xftData2List(xw, fontData)) != NULL && *++my_list != NULL) { for (j = 0; my_list[j] != NULL; ++j) { FcPattern *extraPattern; if ((extraPattern = XftNameParse(my_list[j])) != NULL) { FcPattern *match; match = mergeXftStyle(xw, extraPattern, fontData); if (match != NULL) { FcFontSetAdd(fontData->fontset, match); } FcPatternDestroy(extraPattern); } } } for (j = 0; j < sortedFonts->nfont; j++) { FcPattern *font_pattern; font_pattern = FcFontRenderPrepare(FcConfigGetCurrent(), myPattern, sortedFonts->fonts[j]); if (font_pattern) { FcFontSetAdd(fontData->fontset, font_pattern); } } FcFontSetSortDestroy(sortedFonts); FcPatternDestroy(myPattern); fontData->fs_size = Min(MaxXftCache, fontData->fontset->nfont); } if (fontData->fontset != NULL && fontData->fs_size > 0) { XftFont *check; int empty = fontData->fs_size; for (n = 1; n <= fontData->fs_size; ++n) { XTermXftState usage = XftIsN(fontData, n); if (usage == xcEmpty) { if (empty > n) empty = n; } else if (usage == xcOpened || (usage == xcUnused && (fontData->opened < xw->work.max_fontsets))) { check = XftFpN(fontData, n); if (foundXftGlyph(xw, fontData, (int) n, wc)) { markXftOpened(xw, fontData, n, wc); actual = check; result = (int) n; TRACE_FALLBACK(xw, "old", wc, result, actual); break; } } } if ((actual == NULL) && (empty <= fontData->fs_size) && (fontData->opened < xw->work.max_fontsets)) { FcPattern *myPattern = NULL; FcPattern *myReport = NULL; int defer = -1; if (empty == 0) /* should not happen */ empty++; for (n = empty; n <= fontData->fs_size; ++n) { int found; int nn = n - 1; if (XftIsN(fontData, n) != xcEmpty) { continue; } if (resource.reportFonts) { if (myReport != NULL) FcPatternDestroy(myReport); myReport = FcPatternDuplicate(fontData->fontset->fonts[nn]); } myPattern = FcPatternDuplicate(fontData->fontset->fonts[nn]); check = XftFontOpenPattern(screen->display, myPattern); (void) maybeXftCache(xw, check); XftFpN(fontData, n) = check; if (check == NULL) { ; /* shouldn't happen... */ } else #ifdef FC_COLOR if (isBogusXft(check)) { XftIsN(fontData, n) = xcBogus; } else #endif if ((found = foundXftGlyph(xw, fontData, (int) n, wc)) != 0) { markXftOpened(xw, fontData, n, wc); reportXftFallbackFont(xw, fontData, (int) n, check, myReport); if (found < 0) { if (defer < 0) { defer = (int) n; TRACE(("Deferring font choice #%d\n", n + 1)); continue; } else if (slowXftMissing(xw, check, wc)) { TRACE(("Deferred, continuing #%d\n", n + 1)); continue; } } else if (defer >= 0) { defer = -1; TRACE(("Deferred, replacing %d with %d\n", defer + 1, n + 1)); } actual = check; result = (int) n; TRACE_FALLBACK(xw, "new", wc, result, actual); break; } else { if (defer >= 0 && !slowXftMissing(xw, check, wc) && checkXftGlyph(xw, check, wc)) { XTermFontMap *font_map = &(fontData->font_map); TRACE(("checkrecover2 %d\n", n)); markXftOpened(xw, fontData, n, wc); reportXftFallbackFont(xw, fontData, (int) n, check, myReport); actual = check; result = (int) n; TRACE_FALLBACK(xw, "fix", wc, result, actual); font_map->per_font[wc] = (XTfontNum) (result + 1); break; } else { /* * The slot is opened, but we are not using it yet. */ XftIsN(fontData, n) = xcUnused; } } } if (myReport != NULL) FcPatternDestroy(myReport); } } return result; } /* * Check if the given character has a glyph known to Xft. If it is missing, * return true. * * see xc/lib/Xft/xftglyphs.c */ Bool xtermXftMissing(XtermWidget xw, XTermXftFonts *data, int fontNum, /* 0=primary, 1+ is fallback */ XftFont *font, /* actual font if no data */ unsigned wc) { Bool result = True; (void) xw; if (data != NULL && font != NULL) { XTermFontMap *font_map = &(data->font_map); /* * Each fallback font has one chance to be scanned/cached. * We record in per_font[] the index of the first font containing a * given glyph. */ if (font_map->depth <= fontNum) { FcChar32 last = (xtermXftLastChar(font) | 255) + 1; FcChar32 base; FcChar32 nextPage; FcChar32 map[FC_CHARSET_MAP_SIZE]; unsigned added = 0; unsigned actual = 0; font_map->depth = (fontNum + 1); /* allocate space */ if (last > font_map->last_char) { size_t need = (last * sizeof(XTfontNum)); size_t c1st = (font_map->last_char * sizeof(XTfontNum)); font_map->per_font = realloc(font_map->per_font, need); memset(font_map->per_font + font_map->last_char, 0, (need - c1st)); font_map->last_char = last; } /* scan new font */ base = FcCharSetFirstPage(font->charset, map, &nextPage); do { unsigned row; unsigned col; FcChar32 bits; for (row = 0; row < FC_CHARSET_MAP_SIZE; ++row) { bits = map[row]; for (col = 0; col < 32; ++col) { if ((bits & 1) != 0) { actual++; if (!font_map->per_font[base]) { font_map->per_font[base] = (Char) font_map->depth; ++added; } } bits >>= 1; ++base; } } } while ((base = FcCharSetNextPage(font->charset, map, &nextPage)) != FC_CHARSET_DONE); (void) added; (void) actual; TRACE(("xtermXftMissing U+%04X #%-3d %6u added vs %6u of %6ld %s: %s\n", wc, font_map->depth, added, actual, font_map->last_char + 1, whichXftFonts(xw, data), nameOfXftFont(font))); } if (wc < font_map->last_char) { result = (font_map->per_font[wc] != (fontNum + 1)); } } return result; } #endif /* OPT_RENDERFONT */ #if OPT_WIDE_CHARS #define MY_UCS(ucs,dec) case ucs: result = dec; break unsigned ucs2dec(TScreen *screen, unsigned ch) { unsigned result = ch; (void) screen; if ((ch > 127) && !is_UCS_SPECIAL(ch)) { #if OPT_VT52_MODE if (screen != NULL && !(screen->vtXX_level)) { /* * Intentionally empty: it would be possible to use the built-in * line-drawing fallback in xtermDrawBoxChar(), but for testing * ncurses, this is good enough. */ ; } else #endif switch (ch) { MY_UCS(0x25ae, 0); /* black vertical rectangle */ MY_UCS(0x25c6, 1); /* black diamond */ MY_UCS(0x2592, 2); /* medium shade */ MY_UCS(0x2409, 3); /* symbol for horizontal tabulation */ MY_UCS(0x240c, 4); /* symbol for form feed */ MY_UCS(0x240d, 5); /* symbol for carriage return */ MY_UCS(0x240a, 6); /* symbol for line feed */ MY_UCS(0x00b0, 7); /* degree sign */ MY_UCS(0x00b1, 8); /* plus-minus sign */ MY_UCS(0x2424, 9); /* symbol for newline */ MY_UCS(0x240b, 10); /* symbol for vertical tabulation */ MY_UCS(0x2518, 11); /* box drawings light up and left */ MY_UCS(0x2510, 12); /* box drawings light down and left */ MY_UCS(0x250c, 13); /* box drawings light down and right */ MY_UCS(0x2514, 14); /* box drawings light up and right */ MY_UCS(0x253c, 15); /* box drawings light vertical and horizontal */ MY_UCS(0x23ba, 16); /* box drawings scan 1 */ MY_UCS(0x23bb, 17); /* box drawings scan 3 */ MY_UCS(0x2500, 18); /* box drawings light horizontal */ MY_UCS(0x23bc, 19); /* box drawings scan 7 */ MY_UCS(0x23bd, 20); /* box drawings scan 9 */ MY_UCS(0x251c, 21); /* box drawings light vertical and right */ MY_UCS(0x2524, 22); /* box drawings light vertical and left */ MY_UCS(0x2534, 23); /* box drawings light up and horizontal */ MY_UCS(0x252c, 24); /* box drawings light down and horizontal */ MY_UCS(0x2502, 25); /* box drawings light vertical */ MY_UCS(0x2264, 26); /* less-than or equal to */ MY_UCS(0x2265, 27); /* greater-than or equal to */ MY_UCS(0x03c0, 28); /* greek small letter pi */ MY_UCS(0x2260, 29); /* not equal to */ MY_UCS(0x00a3, 30); /* pound sign */ MY_UCS(0x00b7, 31); /* middle dot */ } } return result; } #undef MY_UCS #define MY_UCS(ucs,dec) case dec: result = ucs; break unsigned dec2ucs(TScreen *screen, unsigned ch) { unsigned result = ch; (void) screen; if (xtermIsDecGraphic(ch)) { #if OPT_VT52_MODE if (screen != NULL && !(screen->vtXX_level)) { switch (ch) { MY_UCS(0x0020, 0); /* nbsp, treat as blank */ MY_UCS(0x0020, 1); /* reserved, treat as blank */ MY_UCS(0x25ae, 2); /* black vertical rectangle */ MY_UCS(0x215f, 3); /* "1/" */ MY_UCS(0x0020, 4); /* "3/", not in Unicode, ignore */ MY_UCS(0x0020, 5); /* "5/", not in Unicode, ignore */ MY_UCS(0x0020, 6); /* "7/", not in Unicode, ignore */ MY_UCS(0x00b0, 7); /* degree sign */ MY_UCS(0x00b1, 8); /* plus-minus sign */ MY_UCS(0x2192, 9); /* right-arrow */ MY_UCS(0x2026, 10); /* ellipsis */ MY_UCS(0x00f7, 11); /* divide by */ MY_UCS(0x2193, 12); /* down arrow */ MY_UCS(0x23ba, 13); /* bar at scan 0 */ MY_UCS(0x23ba, 14); /* bar at scan 1 */ MY_UCS(0x23bb, 15); /* bar at scan 2 */ MY_UCS(0x23bb, 16); /* bar at scan 3 */ MY_UCS(0x23bc, 17); /* bar at scan 4 */ MY_UCS(0x23bc, 18); /* bar at scan 5 */ MY_UCS(0x23bd, 19); /* bar at scan 6 */ MY_UCS(0x23bd, 20); /* bar at scan 7 */ MY_UCS(0x2080, 21); /* subscript 0 */ MY_UCS(0x2081, 22); /* subscript 1 */ MY_UCS(0x2082, 23); /* subscript 2 */ MY_UCS(0x2083, 24); /* subscript 3 */ MY_UCS(0x2084, 25); /* subscript 4 */ MY_UCS(0x2085, 26); /* subscript 5 */ MY_UCS(0x2086, 27); /* subscript 6 */ MY_UCS(0x2087, 28); /* subscript 7 */ MY_UCS(0x2088, 29); /* subscript 8 */ MY_UCS(0x2089, 30); /* subscript 9 */ MY_UCS(0x00b6, 31); /* paragraph */ } } else #endif switch (ch) { MY_UCS(0x25ae, 0); /* black vertical rectangle */ MY_UCS(0x25c6, 1); /* black diamond */ MY_UCS(0x2592, 2); /* medium shade */ MY_UCS(0x2409, 3); /* symbol for horizontal tabulation */ MY_UCS(0x240c, 4); /* symbol for form feed */ MY_UCS(0x240d, 5); /* symbol for carriage return */ MY_UCS(0x240a, 6); /* symbol for line feed */ MY_UCS(0x00b0, 7); /* degree sign */ MY_UCS(0x00b1, 8); /* plus-minus sign */ MY_UCS(0x2424, 9); /* symbol for newline */ MY_UCS(0x240b, 10); /* symbol for vertical tabulation */ MY_UCS(0x2518, 11); /* box drawings light up and left */ MY_UCS(0x2510, 12); /* box drawings light down and left */ MY_UCS(0x250c, 13); /* box drawings light down and right */ MY_UCS(0x2514, 14); /* box drawings light up and right */ MY_UCS(0x253c, 15); /* box drawings light vertical and horizontal */ MY_UCS(0x23ba, 16); /* box drawings scan 1 */ MY_UCS(0x23bb, 17); /* box drawings scan 3 */ MY_UCS(0x2500, 18); /* box drawings light horizontal */ MY_UCS(0x23bc, 19); /* box drawings scan 7 */ MY_UCS(0x23bd, 20); /* box drawings scan 9 */ MY_UCS(0x251c, 21); /* box drawings light vertical and right */ MY_UCS(0x2524, 22); /* box drawings light vertical and left */ MY_UCS(0x2534, 23); /* box drawings light up and horizontal */ MY_UCS(0x252c, 24); /* box drawings light down and horizontal */ MY_UCS(0x2502, 25); /* box drawings light vertical */ MY_UCS(0x2264, 26); /* less-than or equal to */ MY_UCS(0x2265, 27); /* greater-than or equal to */ MY_UCS(0x03c0, 28); /* greek small letter pi */ MY_UCS(0x2260, 29); /* not equal to */ MY_UCS(0x00a3, 30); /* pound sign */ MY_UCS(0x00b7, 31); /* middle dot */ } } return result; } #endif /* OPT_WIDE_CHARS */ #if OPT_RENDERFONT || OPT_SHIFT_FONTS static int lookupOneFontSize(XtermWidget xw, int fontnum) { TScreen *screen = TScreenOf(xw); if (screen->menu_font_sizes[fontnum] == 0) { XTermFonts fnt; memset(&fnt, 0, sizeof(fnt)); screen->menu_font_sizes[fontnum] = -1; if (xtermOpenFont(xw, screen->MenuFontName(fontnum), &fnt, NULL, True)) { if (fontnum <= fontMenu_lastBuiltin || strcmp(fnt.fn, DEFFONT)) { screen->menu_font_sizes[fontnum] = FontSize(fnt.fs); if (screen->menu_font_sizes[fontnum] <= 0) screen->menu_font_sizes[fontnum] = -1; } xtermCloseFont(xw, &fnt); } } return (screen->menu_font_sizes[fontnum] > 0); } /* * Cache the font-sizes so subsequent larger/smaller font actions will go fast. */ static void lookupFontSizes(XtermWidget xw) { int n; for (n = 0; n < NMENUFONTS; n++) { (void) lookupOneFontSize(xw, n); } } #endif /* OPT_RENDERFONT || OPT_SHIFT_FONTS */ #if OPT_RENDERFONT static double defaultFaceSize(void) { double result; float value; if (sscanf(DEFFACESIZE, "%f", &value) == 1) result = (double) value; else result = 14.0; return result; } static void fillInFaceSize(XtermWidget xw, int fontnum) { TScreen *screen = TScreenOf(xw); double face_size = (double) xw->misc.face_size[fontnum]; if (face_size <= 0.0) { #if OPT_SHIFT_FONTS /* * If the user is switching font-sizes, make it follow by * default the same ratios to the default as the fixed fonts * would, for easy comparison. There will be some differences * since the fixed fonts have a variety of height/width ratios, * but this is simpler than adding another resource value - and * as noted above, the data for the fixed fonts are available. */ (void) lookupOneFontSize(xw, 0); if (fontnum == fontMenu_default) { face_size = defaultFaceSize(); } else if (lookupOneFontSize(xw, fontnum) && (screen->menu_font_sizes[0] != screen->menu_font_sizes[fontnum])) { double ratio; long num = screen->menu_font_sizes[fontnum]; long den = screen->menu_font_sizes[0]; if (den <= 0) den = 1; ratio = dimSquareRoot((double) num / (double) den); face_size = (ratio * (double) xw->misc.face_size[0]); TRACE(("scaled[%d] using %3ld/%ld = %.2f -> %f\n", fontnum, num, den, ratio, face_size)); } else #endif { #define LikeBitmap(s) (((s) / 78.0) * (double) xw->misc.face_size[fontMenu_default]) switch (fontnum) { case fontMenu_font1: face_size = LikeBitmap(2.0); break; case fontMenu_font2: face_size = LikeBitmap(35.0); break; case fontMenu_font3: face_size = LikeBitmap(60.0); break; default: face_size = defaultFaceSize(); break; case fontMenu_font4: face_size = LikeBitmap(90.0); break; case fontMenu_font5: face_size = LikeBitmap(135.0); break; case fontMenu_font6: face_size = LikeBitmap(200.0); break; case fontMenu_font7: face_size = LikeBitmap(240.0); break; } TRACE(("builtin[%d] -> %f\n", fontnum, face_size)); } xw->misc.face_size[fontnum] = (float) face_size; } } /* no selection or escape */ #define NMENU_RENDERFONTS (fontMenu_lastBuiltin + 1) /* * Workaround for breakage in font-packages - check if all of the bitmap font * sizes are the same, and if we're using TrueType fonts. */ static Boolean useFaceSizes(XtermWidget xw) { Boolean result = False; TRACE(("useFaceSizes " TRACE_L "\n")); if (UsingRenderFont(xw)) { Boolean nonzero = True; int n; for (n = 0; n < NMENU_RENDERFONTS; ++n) { if (xw->misc.face_size[n] <= 0.0f) { nonzero = False; break; } } if (!nonzero) { Boolean broken_fonts = True; TScreen *screen = TScreenOf(xw); long first; lookupFontSizes(xw); first = screen->menu_font_sizes[0]; for (n = 0; n < NMENUFONTS; n++) { if (screen->menu_font_sizes[n] > 0 && screen->menu_font_sizes[n] != first) { broken_fonts = False; break; } } if (broken_fonts) { TRACE(("bitmap fonts are broken - set faceSize resources\n")); for (n = 0; n < NMENUFONTS; n++) { fillInFaceSize(xw, n); } } } result = True; } TRACE((TRACE_R " useFaceSizes %d\n", result)); return result; } #endif /* OPT_RENDERFONT */ #if OPT_SHIFT_FONTS /* * Find the index of a larger/smaller font (according to the sign of 'relative' * and its magnitude), starting from the 'old' index. */ int lookupRelativeFontSize(XtermWidget xw, int old, int relative) { TScreen *screen = TScreenOf(xw); int m = -1; TRACE(("lookupRelativeFontSize(old=%d, relative=%d)\n", old, relative)); if (!IsIcon(screen)) { #if OPT_RENDERFONT if (useFaceSizes(xw)) { TRACE(("...using FaceSize\n")); if (relative != 0) { int n; for (n = 0; n < NMENU_RENDERFONTS; ++n) { fillInFaceSize(xw, n); if (xw->misc.face_size[n] > 0 && xw->misc.face_size[n] != xw->misc.face_size[old]) { int cmp_0 = ((xw->misc.face_size[n] > xw->misc.face_size[old]) ? relative : -relative); int cmp_m = ((m < 0) ? 1 : ((xw->misc.face_size[n] < xw->misc.face_size[m]) ? relative : -relative)); if (cmp_0 > 0 && cmp_m > 0) { m = n; } } } } } else #endif { TRACE(("...using bitmap areas\n")); lookupFontSizes(xw); if (relative != 0) { int n; for (n = 0; n < NMENUFONTS; ++n) { if (screen->menu_font_sizes[n] > 0 && screen->menu_font_sizes[n] != screen->menu_font_sizes[old]) { int cmp_0 = ((screen->menu_font_sizes[n] > screen->menu_font_sizes[old]) ? relative : -relative); int cmp_m = ((m < 0) ? 1 : ((screen->menu_font_sizes[n] < screen->menu_font_sizes[m]) ? relative : -relative)); if (cmp_0 > 0 && cmp_m > 0) { m = n; } } } } } TRACE(("...new index %d\n", m)); if (m >= 0) { if (relative > 1) m = lookupRelativeFontSize(xw, m, relative - 1); else if (relative < -1) m = lookupRelativeFontSize(xw, m, relative + 1); } } return m; } /* ARGSUSED */ void HandleLargerFont(Widget w, XEvent *event GCC_UNUSED, String *params GCC_UNUSED, Cardinal *param_count GCC_UNUSED) { XtermWidget xw; TRACE(("Handle larger-vt-font for %p\n", (void *) w)); if ((xw = getXtermWidget(w)) != NULL) { if (xw->misc.shift_fonts) { TScreen *screen = TScreenOf(xw); int m; m = lookupRelativeFontSize(xw, screen->menu_font_number, 1); if (m >= 0) { SetVTFont(xw, m, True, NULL); } else { Bell(xw, XkbBI_MinorError, 0); } } } } /* ARGSUSED */ void HandleSmallerFont(Widget w, XEvent *event GCC_UNUSED, String *params GCC_UNUSED, Cardinal *param_count GCC_UNUSED) { XtermWidget xw; TRACE(("Handle smaller-vt-font for %p\n", (void *) w)); if ((xw = getXtermWidget(w)) != NULL) { if (xw->misc.shift_fonts) { TScreen *screen = TScreenOf(xw); int m; m = lookupRelativeFontSize(xw, screen->menu_font_number, -1); if (m >= 0) { SetVTFont(xw, m, True, NULL); } else { Bell(xw, XkbBI_MinorError, 0); } } } } #endif /* OPT_SHIFT_FONTS */ int xtermGetFont(const char *param) { int fontnum; if (param == NULL) param = ""; switch (param[0]) { case 'd': case 'D': case '0': fontnum = fontMenu_default; break; case '1': fontnum = fontMenu_font1; break; case '2': fontnum = fontMenu_font2; break; case '3': fontnum = fontMenu_font3; break; case '4': fontnum = fontMenu_font4; break; case '5': fontnum = fontMenu_font5; break; case '6': fontnum = fontMenu_font6; break; case '7': fontnum = fontMenu_font7; break; case 'e': case 'E': fontnum = fontMenu_fontescape; break; case 's': case 'S': fontnum = fontMenu_fontsel; break; default: fontnum = -1; break; } TRACE(("xtermGetFont(%s) ->%d\n", param, fontnum)); return fontnum; } /* ARGSUSED */ void HandleSetFont(Widget w, XEvent *event GCC_UNUSED, String *params, Cardinal *param_count) { XtermWidget xw; if ((xw = getXtermWidget(w)) != NULL) { int fontnum; VTFontNames fonts; memset(&fonts, 0, sizeof(fonts)); if (*param_count == 0) { fontnum = fontMenu_default; } else { Cardinal maxparams = 1; /* total number of params allowed */ int result = xtermGetFont(params[0]); switch (result) { case fontMenu_default: /* FALLTHRU */ case fontMenu_font1: /* FALLTHRU */ case fontMenu_font2: /* FALLTHRU */ case fontMenu_font3: /* FALLTHRU */ case fontMenu_font4: /* FALLTHRU */ case fontMenu_font5: /* FALLTHRU */ case fontMenu_font6: /* FALLTHRU */ case fontMenu_font7: /* FALLTHRU */ break; case fontMenu_fontescape: #if OPT_WIDE_CHARS maxparams = 5; #else maxparams = 3; #endif break; case fontMenu_fontsel: maxparams = 2; break; default: Bell(xw, XkbBI_MinorError, 0); return; } fontnum = result; if (*param_count > maxparams) { /* see if extra args given */ Bell(xw, XkbBI_MinorError, 0); return; } switch (*param_count) { /* assign 'em */ #if OPT_WIDE_CHARS case 5: fonts.f_wb = x_strdup(params[4]); /* FALLTHRU */ case 4: fonts.f_w = x_strdup(params[3]); #endif /* FALLTHRU */ case 3: fonts.f_b = x_strdup(params[2]); /* FALLTHRU */ case 2: fonts.f_n = x_strdup(params[1]); break; } } SetVTFont(xw, fontnum, True, &fonts); } } Bool SetVTFont(XtermWidget xw, int which, Bool doresize, const VTFontNames * fonts) { TScreen *screen = TScreenOf(xw); Bool result = False; TRACE(("SetVTFont(which=%d, f_n=%s, f_b=%s)\n", which, (fonts && fonts->f_n) ? fonts->f_n : "", (fonts && fonts->f_b) ? fonts->f_b : "")); if (IsIcon(screen)) { Bell(xw, XkbBI_MinorError, 0); } else if (which >= 0 && which < NMENUFONTS) { VTFontNames new_fnames; memset(&new_fnames, 0, sizeof(new_fnames)); if (fonts != NULL) new_fnames = *fonts; if (which == fontMenu_fontsel) { /* go get the selection */ result = FindFontSelection(xw, new_fnames.f_n, False); } else { #define USE_CACHED(field, name) \ if (new_fnames.field == NULL) { \ new_fnames.field = x_strdup(screen->menu_font_names[which][name]); \ TRACE(("set new_fnames." #field " from menu_font_names[%d][" #name "] %s\n", \ which, NonNull(new_fnames.field))); \ } else { \ TRACE(("set new_fnames." #field " reused\n")); \ } #define SAVE_FNAME(field, name) \ if (new_fnames.field != NULL \ && (screen->menu_font_names[which][name] == NULL \ || strcmp(screen->menu_font_names[which][name], new_fnames.field))) { \ TRACE(("updating menu_font_names[%d][" #name "] to \"%s\"\n", \ which, new_fnames.field)); \ FREE_STRING(screen->menu_font_names[which][name]); \ screen->menu_font_names[which][name] = x_strdup(new_fnames.field); \ } USE_CACHED(f_n, fNorm); USE_CACHED(f_b, fBold); #if OPT_WIDE_CHARS USE_CACHED(f_w, fWide); USE_CACHED(f_wb, fWBold); #endif if (xtermLoadFont(xw, &new_fnames, doresize, which)) { /* * If successful, save the data so that a subsequent query via * OSC-50 will return the expected values. */ SAVE_FNAME(f_n, fNorm); SAVE_FNAME(f_b, fBold); #if OPT_WIDE_CHARS SAVE_FNAME(f_w, fWide); SAVE_FNAME(f_wb, fWBold); #endif result = True; } else { Bell(xw, XkbBI_MinorError, 0); } FREE_FNAME(f_n); FREE_FNAME(f_b); #if OPT_WIDE_CHARS FREE_FNAME(f_w); FREE_FNAME(f_wb); #endif } } else { Bell(xw, XkbBI_MinorError, 0); } TRACE(("...SetVTFont: %d\n", result)); return result; } #if OPT_RENDERFONT static void trimSizeFromFace(char *face_name, float *face_size) { char *first = strstr(face_name, ":size="); if (first == NULL) { first = face_name; } else { first++; } if (!strncmp(first, "size=", (size_t) 5)) { char *last = strchr(first, ':'); char mark; float value; char extra; TRACE(("...before trimming, font = \"%s\"\n", face_name)); if (last == NULL) last = first + strlen(first); mark = *last; *last = '\0'; if (sscanf(first, "size=%g%c", &value, &extra) == 1) { TRACE(("...trimmed size from font: %g\n", value)); if (face_size != NULL) *face_size = value; } if (mark) { while ((*first++ = *++last) != '\0') { ; } } else { if (first != face_name) --first; *first = '\0'; } TRACE(("...after trimming, font = \"%s\"\n", face_name)); } } #endif /* * Save a font specification to the proper list. */ static void save2FontList(XtermWidget xw, const char *name, XtermFontNames * fontnames, VTFontEnum which, const char *source, Bool check, Bool ttf) { char *value; size_t plen; Bool marked = False; Bool use_ttf = ttf; (void) xw; if (source == NULL) source = ""; while (isspace(CharOf(*source))) ++source; /* fontconfig patterns can contain ':' separators, but we'll treat * a leading prefix specially to denote whether the pattern might be * XLFD ("x" or "xlfd") versus Xft ("xft"). */ for (plen = 0; source[plen] != '\0'; ++plen) { if (source[plen] == ':') { marked = True; switch (plen) { case 0: ++plen; /* trim leading ':' */ break; case 1: if (!strncmp(source, "x", plen)) { ++plen; use_ttf = False; } else { marked = False; } break; case 3: if (!strncmp(source, "xft", plen)) { ++plen; use_ttf = True; } else { marked = False; } break; case 4: if (!strncmp(source, "xlfd", plen)) { ++plen; use_ttf = False; } else { marked = False; } break; default: marked = False; plen = 0; break; } break; } } if (!marked) plen = 0; value = x_strtrim(source + plen); if (value != NULL) { Bool success = False; #if OPT_RENDERFONT VTFontList *target = (use_ttf ? &(fontnames->xft) : &(fontnames->x11)); #else VTFontList *target = &(fontnames->x11); #endif char ***list = NULL; char **next = NULL; size_t count = 0; (void) use_ttf; switch (which) { case fNorm: list = &(target->list_n); break; case fBold: list = &(target->list_b); break; #if OPT_WIDE_ATTRS || OPT_RENDERWIDE case fItal: list = &(target->list_i); break; case fBtal: list = &(target->list_bi); break; #endif #if OPT_WIDE_CHARS case fWide: list = &(target->list_w); break; case fWBold: list = &(target->list_wb); break; case fWItal: list = &(target->list_wi); break; case fWBtal: list = &(target->list_wbi); break; #endif case fMAX: list = NULL; break; } if (list != NULL) { success = True; if (*list != NULL) { while ((*list)[count] != NULL) { if (IsEmpty((*list)[count])) { TRACE(("... initial %s\n", value)); free((*list)[count]); break; } else if (!strcmp(value, (*list)[count])) { TRACE(("... duplicate %s\n", value)); success = False; break; } ++count; } } if (success) { next = (char **) realloc(*list, sizeof(char *) * (count + 2)); if (next != NULL) { #if OPT_RENDERFONT if (use_ttf) { trimSizeFromFace(value, (count == 0 && which == fNorm) ? &(xw->misc.face_size[0]) : (float *) 0); } #endif next[count++] = value; next[count] = NULL; *list = next; TRACE(("... saved \"%s\" \"%s\" %lu:\"%s\"\n", whichFontList(xw, target), whichFontList2(xw, *list), (unsigned long) count, value)); } else { xtermWarning("realloc failure in save2FontList(%s)\n", name); freeFontList(list); success = False; } } } if (success) { #if (MAX_XFT_FONTS == MAX_XLFD_FONTS) size_t limit = MAX_XFT_FONTS; #else size_t limit = use_ttf ? MAX_XFT_FONTS : MAX_XLFD_FONTS; #endif if (count > limit && *x_skip_blanks(value)) { if (check) { xtermWarning("too many fonts for %s, ignoring %s\n", whichFontEnum(which), value); } if (list && *list) { free((*list)[limit]); (*list)[limit] = NULL; } } } else { free(value); } } } /* * In principle, any of the font-name resources could be extended to be a list * of font-names. That would be bad for performance, but as a basis for an * extension, parse the font-name as a comma-separated list, creating/updating * an array of font-names. */ void allocFontList(XtermWidget xw, const char *name, XtermFontNames * target, VTFontEnum which, const char *source, Bool ttf) { char *blob; blob = x_strdup(source); if (blob != NULL) { int n; int pass; char **list = NULL; TRACE(("allocFontList %s name=\"%s\" source=\"%s\"\n", whichFontEnum(which), name, blob)); for (pass = 0; pass < 2; ++pass) { unsigned count = 0; if (pass) list[0] = blob; for (n = 0; blob[n] != '\0'; ++n) { if (blob[n] == ',') { ++count; if (pass != 0) { blob[n] = '\0'; list[count] = blob + n + 1; } } } if (!pass) { if (count == 0 && *blob == '\0') break; list = TypeCallocN(char *, count + 2); if (list == NULL) break; } } if (list) { for (n = 0; list[n] != NULL; ++n) { if (*list[n]) { save2FontList(xw, name, target, which, list[n], True, ttf); } } free(list); } } free(blob); } static void initFontList(XtermWidget xw, const char *name, XtermFontNames * target, Bool ttf) { int which; TRACE(("initFontList(%s)\n", name)); for (which = 0; which < fMAX; ++which) { save2FontList(xw, name, target, (VTFontEnum) which, "", False, ttf); } } void initFontLists(XtermWidget xw) { TRACE(("initFontLists\n")); initFontList(xw, "x11 font", &(xw->work.fonts), False); #if OPT_RENDERFONT initFontList(xw, "xft font", &(xw->work.fonts), True); #endif #if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS initFontList(xw, "cached font", &(xw->screen.cacheVTFonts.fonts), False); #endif } void copyFontList(char ***targetp, char **source) { freeFontList(targetp); if (source != NULL) { int pass; size_t count; for (pass = 0; pass < 2; ++pass) { for (count = 0; source[count] != NULL; ++count) { if (pass) (*targetp)[count] = x_strdup(source[count]); } if (!pass) { ++count; *targetp = TypeCallocN(char *, count); } } } else { *targetp = TypeCallocN(char *, 2); (*targetp)[0] = x_strdup(""); } } #if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS static Boolean merge_sublist(char ***targetp, char **source) { Boolean result = False; if ((*targetp == NULL || IsEmpty(**targetp)) && !IsEmpty(*source)) { copyFontList(targetp, source); result = True; } return result; } #endif void freeFontList(char ***targetp) { if (targetp != NULL) { char **target = *targetp; if (target != NULL) { int n; for (n = 0; target[n] != NULL; ++n) { free(target[n]); } free(target); *targetp = NULL; } } } void freeFontLists(VTFontList * lists) { int which; TRACE(("freeFontLists\n")); for (which = 0; which < fMAX; ++which) { char ***target = NULL; switch (which) { case fNorm: target = &(lists->list_n); break; case fBold: target = &(lists->list_b); break; #if OPT_WIDE_ATTRS || OPT_RENDERWIDE case fItal: target = &(lists->list_i); break; case fBtal: target = &(lists->list_bi); break; #endif #if OPT_WIDE_CHARS case fWide: target = &(lists->list_w); break; case fWBold: target = &(lists->list_wb); break; case fWItal: target = &(lists->list_wi); break; case fWBtal: target = &(lists->list_wbi); break; #endif default: target = NULL; break; } freeFontList(target); } } /* * Return a pointer to the XLFD font information for a given font class. * XXX make this allocate the font on demand. */ XTermFonts * getNormalFont(TScreen *screen, int which) { XTermFonts *result = NULL; if (which >= 0 && which < fMAX) result = GetNormalFont(screen, which); return result; } #if OPT_DEC_CHRSET XTermFonts * getDoubleFont(TScreen *screen, int which) { XTermFonts *result = NULL; if ((int) which >= 0 && which < NUM_CHRSET) result = GetDoubleFont(screen, which); return result; } #if OPT_RENDERFONT void getDoubleXftFont(XTermDraw * params, XTermXftFonts *data, unsigned chrset, unsigned attr_flags) { XtermWidget xw = params->xw; TScreen *screen = TScreenOf(xw); XftPattern *top_pattern; int fontnum = screen->menu_font_number; const char *face_name = getFaceName(xw, False); if (chrset != CSET_SWL && (top_pattern = XftNameParse(face_name)) != NULL) { double face_size = (double) xw->misc.face_size[fontnum]; XftPattern *sub_pattern = XftPatternDuplicate(top_pattern); const char *category = "doublesize"; switch (chrset) { case CSET_DHL_TOP: category = "DHL_TOP"; goto double_high; case CSET_DHL_BOT: category = "DHL_BOT"; double_high: face_size *= 2; XftPatternBuild(sub_pattern, NormXftPattern, (void *) 0); break; case CSET_DWL: category = "DWL"; XftPatternBuild(sub_pattern, NormXftPattern, FC_ASPECT, XftTypeDouble, 2.0, (void *) 0); break; } if (attr_flags & BOLD) { XftPatternBuild(sub_pattern, XFT_WEIGHT, XftTypeInteger, XFT_WEIGHT_BOLD, (void *) 0); } xtermOpenXft(xw, data, 0, face_name, sub_pattern, category); data->pattern = sub_pattern; } } #endif #endif /* OPT_DEC_CHRSET */ #if OPT_WIDE_ATTRS || OPT_RENDERWIDE XTermFonts * getItalicFont(TScreen *screen, int which) { XTermFonts *result = NULL; #if OPT_WIDE_ATTRS if (which >= 0 && which < fMAX) result = GetItalicFont(screen, which); #else (void) screen; (void) which; #endif return result; } #endif #if OPT_RENDERFONT /* * This returns a pointer to everything known about a given Xft font. * XXX make this allocate the font on demand. */ XTermXftFonts * getMyXftFont(XtermWidget xw, int which, int fontnum) { TScreen *screen = TScreenOf(xw); XTermXftFonts *result = NULL; if (fontnum >= 0 && fontnum < NMENUFONTS) { switch ((VTFontEnum) which) { case fNorm: result = &(screen->renderFontNorm[fontnum]); break; case fBold: result = &(screen->renderFontBold[fontnum]); break; #if OPT_WIDE_ATTRS || OPT_RENDERWIDE case fItal: result = &(screen->renderFontItal[fontnum]); break; case fBtal: result = &(screen->renderFontBtal[fontnum]); break; #endif #if OPT_WIDE_CHARS case fWide: result = &(screen->renderWideNorm[fontnum]); break; case fWBold: result = &(screen->renderWideBold[fontnum]); break; case fWItal: result = &(screen->renderWideItal[fontnum]); break; case fWBtal: result = &(screen->renderWideBtal[fontnum]); break; #endif case fMAX: break; } } return result; } const char * whichXftFonts(XtermWidget xw, const XTermXftFonts *data) { TScreen *screen = TScreenOf(xw); const char *result = "?"; #define CHECK(name) ((data >= &(screen->name[0])) && (data < &(screen->name[NMENUFONTS]))) result = #name if CHECK (renderFontNorm); else if CHECK (renderFontBold); #if OPT_WIDE_ATTRS || OPT_RENDERWIDE else if CHECK (renderFontItal); else if CHECK (renderFontBtal); #endif #if OPT_WIDE_CHARS else if CHECK (renderWideNorm); else if CHECK (renderWideBold); else if CHECK (renderWideItal); else if CHECK (renderWideBtal); #endif #if OPT_DEC_CHRSET #if OPT_RENDERFONT else { int n; for (n = 0; n < NUM_CHRSET; ++n) { if (data == &screen->double_xft_fonts[n]) { result = "double_xft_fonts"; break; } } } #endif #endif /* OPT_DEC_CHRSET */ return result; } XftFont * getXftFont(XtermWidget xw, VTFontEnum which, int fontnum) { XTermXftFonts *data = getMyXftFont(xw, (int) which, fontnum); XftFont *result = NULL; if (data != NULL) result = XftFp(data); return result; } #endif const char * whichFontEnum(VTFontEnum value) { const char *result = "?"; #define DATA(name) case name: result = #name; break switch (value) { DATA(fNorm); DATA(fBold); #if OPT_WIDE_ATTRS || OPT_RENDERWIDE DATA(fItal); DATA(fBtal); #endif #if OPT_WIDE_CHARS DATA(fWide); DATA(fWBold); DATA(fWItal); DATA(fWBtal); #endif DATA(fMAX); } #undef DATA return result; } const char * whichFontList(XtermWidget xw, const VTFontList * value) { const char *result = "?"; if (value == &(xw->work.fonts.x11)) result = "x11_fontnames"; #if OPT_RENDERFONT else if (value == &(xw->work.fonts.xft)) result = "xft_fontnames"; #endif #if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS else if (value == &(xw->screen.cacheVTFonts.fonts.x11)) result = "cached_fontnames"; #endif return result; } static const char * whichFontList2s(VTFontList * list, char **value) { const char *result = NULL; #define DATA(name) if (value == (list->name)) result = #name DATA(list_n); DATA(list_b); #if OPT_WIDE_ATTRS || OPT_RENDERWIDE DATA(list_i); DATA(list_bi); #endif #if OPT_WIDE_CHARS DATA(list_w); DATA(list_wb); DATA(list_wi); DATA(list_wbi); #endif #undef DATA return result; } const char * whichFontList2(XtermWidget xw, char **value) { const char *result = NULL; #define DATA(name) (result = whichFontList2s(&(xw->name), value)) if (DATA(work.fonts.x11) == NULL) { #if OPT_RENDERFONT if (DATA(work.fonts.xft) == NULL) #endif #if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS if (DATA(screen.cacheVTFonts.fonts.x11) == NULL) #endif result = "?"; } #undef DATA return result; } xterm-399/Makefile.in0000644000000000000000000005234414764674661013337 0ustar rootroot## $XTermId: Makefile.in,v 1.267 2025/03/14 00:34:57 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 1997-2023,2025 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- SHELL = /bin/sh #### Start of system configuration section. #### srcdir = @srcdir@ VPATH = @srcdir@ x = @EXEEXT@ o = .@OBJEXT@ CC = @CC@ CPP = @CPP@ AWK = @AWK@ LINK = $(CC) $(CFLAGS) CTAGS = @CTAGS@ ETAGS = @ETAGS@ LN_S = @LN_S@ RM = rm -f LINT = @LINT@ LINT_OPTS = @LINT_OPTS@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_DATA = @INSTALL_DATA@ transform = @program_transform_name@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ EXTRA_CPPFLAGS = @EXTRA_CPPFLAGS@ EXTRA_LOADFLAGS = @IMAKE_LOADFLAGS@ PIXMAPDIR_DEF = @no_pixmapdir@-DPIXMAP_ROOTDIR=\"@PIXMAPDIR@/\" CPPFLAGS = -I. -I$(srcdir) -DHAVE_CONFIG_H @CPPFLAGS@ -DDEFCLASS=\"@APP_CLASS@\" $(PIXMAPDIR_DEF) $(EXTRA_CPPFLAGS) CFLAGS = @CFLAGS@ $(EXTRA_CFLAGS) LDFLAGS = @LDFLAGS@ @EXTRA_LDFLAGS@ LIBS = @LIBS@ prefix = @prefix@ exec_prefix = @exec_prefix@ datarootdir = @datarootdir@ datadir = @datadir@ manext = 1 bindir = @bindir@ libdir = @libdir@ mandir = @mandir@/man$(manext) appsdir = @APPSDIR@ icondir = @ICONDIR@ pixmapdir = @PIXMAPDIR@ #### End of system configuration section. #### ICON_NAME = @ICON_NAME@ ICON_SYMLINK = @ICON_SYMLINK@ DESTDIR = BINDIR = $(DESTDIR)$(bindir) LIBDIR = $(DESTDIR)$(libdir) MANDIR = $(DESTDIR)$(mandir) APPSDIR = $(DESTDIR)$(appsdir) @no_icondir@ICONDIR = $(DESTDIR)$(icondir) @no_pixmapdir@PIXMAPDIR = $(DESTDIR)$(pixmapdir) INSTALL_DIRS = $(BINDIR) $(APPSDIR) $(ICONDIR) $(PIXMAPDIR) $(MANDIR) CLASS = @APP_CLASS@ EXTRAHDR = @EXTRAHDRS@ EXTRASRC = @EXTRASRCS@ EXTRAOBJ = @EXTRAOBJS@ AUTO_SOURCE = \ builtin_icons.h \ VTparse.cin \ Tekparse.cin \ VTparse.hin \ Tekparse.hin SRCS1 = button.c cachedGCs.c charproc.c charsets.c cursor.c \ data.c doublechr.c fontutils.c input.c \ keysym2ucs.c linedata.c main.c menu.c misc.c \ print.c ptydata.c scrollback.c \ screen.c scrollbar.c tabs.c util.c version.c xstrings.c \ xtermcap.c VTPrsTbl.c $(EXTRASRC) OBJS1 = button$o cachedGCs$o charproc$o charsets$o cursor$o \ data$o doublechr$o fontutils$o input$o \ keysym2ucs$o linedata$o main$o menu$o misc$o \ print$o ptydata$o scrollback$o \ screen$o scrollbar$o tabs$o util$o version$o xstrings$o \ xtermcap$o VTPrsTbl$o $(EXTRAOBJ) SRCS2 = resize.c version.c xstrings.c OBJS2 = resize$o version$o xstrings$o SRCS = $(SRCS1) $(SRCS2) OBJS = $(OBJS1) $(OBJS2) HDRS = VTparse.h data.h error.h fontutils.h main.h menu.h \ ptyx.h version.h xstrings.h xterm.h xtermcap.h $(EXTRAHDR) PROGRAMS = xterm$x resize$x TEST_PROGRAMS = test_charclass$x test_ptydata$x test_wcwidth$x all : $(PROGRAMS) ################################################################################ .SUFFIXES : .i .def .cin .hin .$(manext) .ms .man .txt @MAN2HTML_NOTE@ .html @GROFF_NOTE@ .ps .pdf .c$o : @RULE_CC@ @ECHO_CC@$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/$*.c .c.i : @RULE_CC@ @ECHO_CC@$(CPP) -C $(CPPFLAGS) $*.c >$@ .def.cin : @echo "making $@ from $<" @$(AWK) 'BEGIN{printf "/* vile:cmode */\n";}/^CASE_/{printf "{ %d, \"%s\" },\n", n++, $$1; }' < $< >$@ .def.hin : @echo "making $@ from $<" @$(AWK) 'BEGIN{printf "/* vile:cmode */\n";}/^CASE_/{printf "#define %s %d\n", $$1, n++}' < $< >$@ .man.$(manext) : $(SHELL) ./minstall "$(INSTALL_DATA)" $< $@ $* $* @NROFF_NOTE@.$(manext).txt : @NROFF_NOTE@ $(SHELL) -c "tbl $*.$(manext) | nroff -man | col -bx" >$@ @NROFF_NOTE@ @NROFF_NOTE@.ms.txt : @NROFF_NOTE@ $(SHELL) -c "tbl $*.$(manext) | nroff -ms | col -bx" >$@ @NROFF_NOTE@ @MAN2HTML_NOTE@.$(manext).html : @MAN2HTML_NOTE@ ./@MAN2HTML_TEMP@ $* $(manext) man >$@ @MAN2HTML_NOTE@ @GROFF_NOTE@.$(manext).ps : @GROFF_NOTE@ $(SHELL) -c "tbl $*.$(manext) | groff -man" >$@ @GROFF_NOTE@ @GROFF_NOTE@.$(manext).txt : @GROFF_NOTE@ GROFF_NO_SGR=stupid $(SHELL) -c "tbl $*.$(manext) | groff -rHY=0 -Tascii -man | col -bx" >$@ @GROFF_NOTE@ @MAN2HTML_NOTE@.ms.html : @MAN2HTML_NOTE@ ./@MAN2HTML_TEMP@ $* ms ms >$@ @MAN2HTML_NOTE@ @GROFF_NOTE@.ms.ps : @GROFF_NOTE@ $(SHELL) -c "tbl $< | groff -ms" >$@ @GROFF_NOTE@ @GROFF_NOTE@.ms.txt : @GROFF_NOTE@ GROFF_NO_SGR=stupid $(SHELL) -c "tbl $< | groff -rHY=0 -Tascii -ms | col -bx" >$@ @GROFF_NOTE@ @GROFF_NOTE@.ps.pdf : @GROFF_NOTE@ ps2pdf $*.ps ################################################################################ VTPARSE_H = VTparse.h VTparse.hin TEKPARSE_H = Tekparse.h Tekparse.hin main$o : main.h misc$o : version.h $(OBJS1) : xterm.h ptyx.h fontutils.h menu.h xtermcfg.h main$o resize$o screen$o : xterm_io.h xterm$x : $(OBJS1) @ECHO_LD@$(SHELL) $(srcdir)/plink.sh $(LINK) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS1) $(LIBS) $(EXTRA_LOADFLAGS) resize$x : $(OBJS2) @ECHO_LD@$(SHELL) $(srcdir)/plink.sh $(LINK) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS2) $(LIBS) 256colres.h : -$(RM) $@ perl $(srcdir)/256colres.pl > $@ 88colres.h : -$(RM) $@ perl $(srcdir)/88colres.pl > $@ charproc$o : $(VTPARSE_H) main.h @CHARPROC_DEPS@ graphics_regis$o : $(VTPARSE_H) graphics_sixel$o : $(VTPARSE_H) misc$o : $(VTPARSE_H) VTPrsTbl$o : $(VTPARSE_H) charsets$o : charsets.h charproc$o \ graphics$o \ graphics_regis$o \ graphics_sixel$o \ main$o \ misc$o \ screen$o \ util$o : graphics.h TekPrsTbl$o : $(TEKPARSE_H) Tekproc$o : $(TEKPARSE_H) misc$o : builtin_icons.h trace$o : VTparse.cin Tekparse.cin # do this to quiet gcc -Wcast-qual warnings builtin_icons.h : @echo "#if OPT_BUILTIN_XPMS" >$@ @echo "#include " >>$@ @echo "#include " >>$@ @echo "#include " >>$@ @echo "#include " >>$@ @echo "#else" >>$@ @sed -e 's/static char \* /static const char * /' $(srcdir)/icons/mini.xterm_48x48.xpm >>$@ @echo "#endif" >>$@ @echo "made $@" ################################################################################ test_charclass$x : $(srcdir)/charclass.c @ECHO_LD@$(SHELL) $(srcdir)/plink.sh $(CC) -o $@ $(CFLAGS) $(CPPFLAGS) -DTEST_DRIVER $(srcdir)/charclass.c $(LDFLAGS) $(LIBS) ################################################################################ test_ptydata$x : $(srcdir)/ptydata.c @ECHO_LD@$(SHELL) $(srcdir)/plink.sh $(CC) -o $@ $(CFLAGS) $(CPPFLAGS) -DTEST_DRIVER $(srcdir)/ptydata.c $(LDFLAGS) $(LIBS) ################################################################################ test_wcwidth$x : $(srcdir)/wcwidth.c @ECHO_LD@$(SHELL) $(srcdir)/plink.sh $(CC) -o $@ $(CFLAGS) $(CPPFLAGS) -DTEST_DRIVER $(srcdir)/wcwidth.c $(LDFLAGS) $(LIBS) ################################################################################ actual_xterm = `echo xterm| sed '$(transform)'` actual_resize = `echo resize| sed '$(transform)'` actual_uxterm = `echo uxterm| sed '$(transform)'` actual_k8term = `echo koi8rxterm| sed '$(transform)'` binary_xterm = $(actual_xterm)$x binary_resize = $(actual_resize)$x binary_uxterm = $(actual_uxterm) binary_k8term = $(actual_k8term) install \ install-bin \ install-full :: xterm$x resize$x $(BINDIR) @MAY_SETUID@ $(SHELL) $(srcdir)/sinstall.sh @SINSTALL_OPTS@ "$(INSTALL_PROGRAM)" xterm$x @XTERM_PATH@ $(BINDIR)/$(binary_xterm) @NOT_SETUID@ $(INSTALL_PROGRAM) xterm$x $(BINDIR)/$(binary_xterm) $(INSTALL_PROGRAM) -m 755 resize$x $(BINDIR)/$(binary_resize) EDIT_SCRIPT = sed -e s,=xterm,=\$$name, -e s,XTerm,$(CLASS), InstallLink = \ if test @XTERM_SYMLINK@ != NONE \ && test \$$source != NONE \ && test \$$source != \$$target ; then \ cd \$$TARGET && ( \ $(RM) \$$source ; \ $(LN_S) \$$target \$$source ; \ echo \"... created symbolic link:\" ; \ ls -l \$$target \$$source ) ; \ fi InstallBinLink = TARGET=$(BINDIR); $(InstallLink) InstallManLink = TARGET=$(MANDIR); $(InstallLink) InstallScript = \ echo \"... installing $(BINDIR)/\$$target\"; \ name=$(binary_xterm); \ $(EDIT_SCRIPT) $(srcdir)/\$$source >\$$source.tmp; \ $(INSTALL_SCRIPT) -m 755 \$$source.tmp $(BINDIR)/\$$target; \ $(RM) \$$source.tmp install \ install-bin \ install-scripts \ install-full :: $(BINDIR) @$(SHELL) -c "source=\"@XTERM_SYMLINK@\"; \ target=\"$(binary_xterm)\"; \ $(InstallBinLink)" @$(SHELL) -c "source=\"resize\"; \ target=\"$(binary_resize)\"; \ $(InstallBinLink)" @$(SHELL) -c "source=\"uxterm\"; \ target=\"$(binary_uxterm)\"; \ $(InstallScript); \ $(InstallBinLink)" @$(SHELL) -c "source=\"koi8rxterm\"; \ target=\"$(binary_k8term)\"; \ $(InstallScript); \ $(InstallBinLink)" install \ install-man \ install-full :: $(MANDIR) @-$(SHELL) -c "for source in xterm resize uxterm koi8rxterm ; \ do \ target=\`echo \"\$$source\" | sed '@program_transform_name@'\`; \ $(SHELL) ./minstall \"$(INSTALL_DATA)\" \ $(srcdir)/\$$source.man \ $(MANDIR)/\$$target.$(manext) \ \$$source \ \$$target; \ done" @-$(SHELL) -c "if test @XTERM_SYMLINK@ != NONE ; then \ source=$(actual_xterm).$(manext); \ target=@XTERM_SYMLINK@.$(manext); \ cd $(MANDIR) && ( \ $(RM) \$$target ; \ $(LN_S) \$$source \$$target ; \ echo '... created symbolic link:' ; \ ls -l \$$source \$$target ; \ ) \ fi" APP_NAMES = XTerm UXTerm KOI8RXTerm @no_appsdir@install \ @no_appsdir@install-app \ @no_appsdir@install-full :: $(APPSDIR) @no_appsdir@ @-$(SHELL) -c 'for s in $(APP_NAMES); \ @no_appsdir@ do \ @no_appsdir@ echo "** $$s"; \ @no_appsdir@ d=`echo $$s | sed -e s/XTerm/$(CLASS)/`; \ @no_appsdir@ echo installing $(APPSDIR)/$$d; \ @no_appsdir@ sed -e s/XTerm/$(CLASS)/ $(srcdir)/$$s.ad >XTerm.tmp; \ @no_appsdir@ $(INSTALL_DATA) XTerm.tmp $(APPSDIR)/$$d; \ @no_appsdir@ echo installing $(APPSDIR)/$$d-color; \ @no_appsdir@ sed -e s/XTerm/$$d/ $(srcdir)/XTerm-col.ad >XTerm.tmp; \ @no_appsdir@ $(INSTALL_DATA) XTerm.tmp $(APPSDIR)/$$d-color; \ @no_appsdir@ done' @no_appsdir@ @$(RM) XTerm.tmp @no_icondir@ @echo "... installed app-defaults" @no_icondir@ICON_LIST = @ICON_LIST@ @no_icondir@ICON_THEME = @ICON_THEME@ @no_icondir@install \ @no_icondir@install-icon \ @no_icondir@install-full :: $(ICONDIR) @no_icondir@ @ECHO_CC@ACTUAL_XTERM=$(actual_xterm) $(SHELL) -c '\ @no_icondir@ h=$(ICONDIR)/$(ICON_THEME); \ @no_icondir@ for n in $(ICON_LIST); \ @no_icondir@ do \ @no_icondir@ x=$$ACTUAL_XTERM; \ @no_icondir@ l=`echo "$$n" | cut -f1 -d:`; \ @no_icondir@ r=`echo "$$n" | cut -f2 -d: |sed -e "s,xterm,$$ACTUAL_XTERM,"`; \ @no_icondir@ test -z "$$r" && continue; \ @no_icondir@ d=$$h/`echo "$$r" | sed -e "s,/[^/]*$$,,"`; \ @no_icondir@ test -d "$$d" || mkdir -p "$$d"; \ @no_icondir@ echo "installing icon $$h/$$r"; \ @no_icondir@ $(INSTALL_DATA) $$l $$h/$$r; \ @no_icondir@ s=`echo "$$r" | sed -e '"'s,^.*\.,.,'"'`; \ @no_icondir@ t=$(ICON_SYMLINK)$$s; \ @no_icondir@ b=`basename $$n $$s | sed -e "s,_[1-9][0-9]*x.*,,"`; \ @no_icondir@ if test "$(ICON_SYMLINK)" != NONE ; then \ @no_icondir@ if test "$$r" != "$$t" ; then \ @no_icondir@ if test "x$$b" = "x$(ICON_NAME)" ; then \ @no_icondir@ echo "linking $$r -> $$t"; \ @no_icondir@ ( cd $$h; $(RM) $$t; $(LN_S) $$r $$t; ) \ @no_icondir@ fi \ @no_icondir@ fi \ @no_icondir@ fi \ @no_icondir@ done' @no_icondir@ @echo "... installed icons" @no_pixmapdir@install \ @no_pixmapdir@install-icon \ @no_pixmapdir@install-full :: $(PIXMAPDIR) @no_pixmapdir@ @ECHO_CC@ACTUAL_XTERM=$(actual_xterm) $(SHELL) -c '\ @no_pixmapdir@ h=$(PIXMAPDIR); \ @no_pixmapdir@ for n in $(srcdir)/icons/*xterm*_*x*.xpm; \ @no_pixmapdir@ do \ @no_pixmapdir@ l=`basename $$n`; \ @no_pixmapdir@ r=`echo "$$l" | sed -e "s,xterm,$$ACTUAL_XTERM,"`; \ @no_pixmapdir@ echo "installing pixmap $$h/$$r"; \ @no_pixmapdir@ $(INSTALL_DATA) $(srcdir)/icons/$$l $$h/$$r; \ @no_pixmapdir@ s=`echo "$$r" | sed -e '"'s,^.*\.,.,'"'`; \ @no_pixmapdir@ t=$(ICON_SYMLINK)$$s; \ @no_pixmapdir@ b=`basename $$n $$s | sed -e "s,_[1-9][0-9]*x.*,,"`; \ @no_pixmapdir@ if test "$(ICON_SYMLINK)" != NONE ; then \ @no_pixmapdir@ if test "x$$r" != "$$t" ; then \ @no_pixmapdir@ if test "x$$b" = "x$(ICON_NAME)" ; then \ @no_pixmapdir@ echo "linking $$r -> $$t"; \ @no_pixmapdir@ ( cd $$h; $(RM) $$t; $(LN_S) $$r $$t; ) \ @no_pixmapdir@ fi \ @no_pixmapdir@ fi \ @no_pixmapdir@ fi \ @no_pixmapdir@ done' @no_pixmapdir@ @echo "... installed icons" install :: @echo 'Completed installation of executables and documentation.' @echo 'Use "make install-ti" to install terminfo description.' TERMINFO_DIR = @TERMINFO_DIR@ SET_TERMINFO = @SET_TERMINFO@ @no_ticprog@install-full \ @no_ticprog@install-ti :: $(TERMINFO_DIR) @no_ticprog@ @echo "Installing $(srcdir)/terminfo" @no_ticprog@ @$(SHELL) -c "chmod +x ./run-tic.sh" @no_ticprog@ @$(SHELL) -c "$(SET_TERMINFO) ./run-tic.sh $(srcdir)/terminfo" @no_ticprog@ @echo 'Completed installation of terminfo description.' install-full \ install-tc :: @-$(SHELL) -c "if test -f /etc/termcap ; then echo 'You must install the termcap entry manually by editing /etc/termcap'; fi" installdirs : $(INSTALL_DIRS) ################################################################################ UninstallLink = \ if test @XTERM_SYMLINK@ != NONE \ && test \$$source != NONE \ && test \$$source != \$$target \ && test -h \$$TARGET/\$$source ; then \ echo \"... removing \$$TARGET/\$$source\"; \ cd \$$TARGET && \ $(RM) \$$source; \ fi UninstallBinLink = TARGET=$(BINDIR); $(UninstallLink) UninstallManLink = TARGET=$(MANDIR); $(UninstallLink) UninstallBinary = \ echo \"... removing $(BINDIR)/\$$target\"; \ $(RM) $(BINDIR)/\$$target uninstall \ uninstall-bin \ uninstall-full :: @-$(SHELL) -c "source=\"@XTERM_SYMLINK@\"; \ target=\"$(binary_xterm)\"; \ $(UninstallBinLink); \ $(UninstallBinary)" @-$(SHELL) -c "source=\"resize\"; \ target=\"$(binary_resize)\"; \ $(UninstallBinLink); \ $(UninstallBinary)" uninstall \ uninstall-bin \ uninstall-scripts \ uninstall-full :: @-$(SHELL) -c "source=\"uxterm\"; \ target=\"$(binary_uxterm)\"; \ $(UninstallBinLink); \ $(UninstallBinary)" @-$(SHELL) -c "source=\"koi8rxterm\"; \ target=\"$(binary_k8term)\"; \ $(UninstallBinLink); \ $(UninstallBinary)" uninstall \ uninstall-man \ uninstall-full :: @-$(SHELL) -c "\ source=@XTERM_SYMLINK@.$(manext); \ target=$(actual_xterm).$(manext); \ $(UninstallManLink)" @-$(SHELL) -c "for source in \ $(actual_xterm).$(manext) \ $(actual_resize).$(manext) \ $(actual_uxterm).$(manext) \ $(actual_k8term).$(manext); \ do \ echo \"... removing $(MANDIR)/\$$source\"; \ $(RM) $(MANDIR)/\$$source; \ done" @no_appsdir@uninstall \ @no_appsdir@uninstall-app \ @no_appsdir@uninstall-full :: @no_appsdir@ -@ECHO_CC@$(SHELL) -c 'for s in $(APP_NAMES); \ @no_appsdir@ do \ @no_appsdir@ echo "** $$s"; \ @no_appsdir@ d=`echo $$s | sed -e s/XTerm/$(CLASS)/`; \ @no_appsdir@ echo uninstalling $(APPSDIR)/$$d; \ @no_appsdir@ $(RM) $(APPSDIR)/$$d; \ @no_appsdir@ echo uninstalling $(APPSDIR)/$$d-color; \ @no_appsdir@ $(RM) $(APPSDIR)/$$d-color; \ @no_appsdir@ done' @no_icondir@uninstall \ @no_icondir@uninstall-icon \ @no_icondir@uninstall-full :: @no_icondir@ -@ECHO_CC@$(SHELL) -c 'ACTUAL_XTERM=$(actual_xterm) ; \ @no_icondir@ for n in $(ICON_LIST); \ @no_icondir@ do \ @no_icondir@ r=`echo "$$n" | sed -e s,\^.\*:,, -e s,xterm,$$ACTUAL_XTERM,`; \ @no_icondir@ test -z "$$r" && continue; \ @no_icondir@ h=$(ICONDIR)/$(ICON_THEME); \ @no_icondir@ test -f $$h/$$r || continue; \ @no_icondir@ echo removing $$h/$$r; \ @no_icondir@ $(RM) $$h/$$r; \ @no_icondir@ done' @no_icondir@ @echo "... removed icons" @no_pixmapdir@uninstall \ @no_pixmapdir@uninstall-icon \ @no_pixmapdir@uninstall-full :: @no_pixmapdir@ -@$(SHELL) -c 'ACTUAL_XTERM=$(actual_xterm) ; \ @no_pixmapdir@ for n in $(srcdir)/icons/*xterm*_32x32.xpm $(srcdir)/icons/*xterm*_48x48.xpm; \ @no_pixmapdir@ do \ @no_pixmapdir@ l=`basename $$n`; \ @no_pixmapdir@ r=`echo "$$l" | sed -e "s,xterm,$$ACTUAL_XTERM,"`; \ @no_pixmapdir@ echo removing $(PIXMAPDIR)/$$r; \ @no_pixmapdir@ $(RM) $(PIXMAPDIR)/$$r; \ @no_pixmapdir@ done' @no_pixmapdir@ @echo "... removed icons" ################################################################################ # Desktop-utils does not provide an uninstall, and is not uniformly available. @desktop_utils@DESKTOP_FILES = $(srcdir)/xterm.desktop $(srcdir)/uxterm.desktop @desktop_utils@DESKTOP_FLAGS = @DESKTOP_FLAGS@ @desktop_utils@install-desktop \ @desktop_utils@install-full :: @desktop_utils@ ACTUAL_XTERM=$(actual_xterm) \ @desktop_utils@ $(SHELL) -c 'for n in $(DESKTOP_FILES); \ @desktop_utils@ do $(SHELL) df-install $$ACTUAL_XTERM $(ICON_NAME) DESTDIR="$(DESTDIR)" $(DESKTOP_FLAGS) $$n; \ @desktop_utils@ done' ################################################################################ check : $(TEST_PROGRAMS) @ echo "See demos in vttests/* (use vttest for system-level testing)" @ $(SHELL) -c 'echo "** executing test_charclass"; \ ./test_charclass' @ $(SHELL) -c 'echo "** executing test_wcwidth"; \ for range in 32-126 160-0xff00 0x10000-0x11000; \ do echo ".. range $$range"; \ ./test_wcwidth -s $$range; \ ./test_wcwidth -s $$range -w; \ done' @ $(SHELL) -c 'echo "** executing test_ptydata"; \ ./test_ptydata -a' ################################################################################ mostlyclean : -$(RM) *$o *.[is] XTerm[1-9]*.* Xterm.log.* XtermLog.* .pure core *~ *.bak *.BAK *.out *.tmp clean : mostlyclean -$(RM) $(PROGRAMS) $(TEST_PROGRAMS) $(AUTO_SOURCE) sources : $(AUTO_SOURCE) distclean :: clean -$(RM) Makefile config.status config.cache config.log xtermcfg.h -$(RM) df-install minstall run-tic.sh distclean \ docs-clean :: -$(RM) *.ps *.pdf *.png -$(SHELL) -c 'for p in xterm resize uxterm koi8rxterm; \ do \ $(RM) $$p.html $$p.$(manext) $$p.txt; \ done' -$(RM) ctlseqs.html ctlseqs.$(manext) distclean :: -$(RM) man2html.tmp realclean : distclean -$(RM) tags TAGS maintainer-clean : realclean -$(RM) 256colres.h 88colres.h ################################################################################ TIC=tic terminfo.out : terminfo ; $(TIC) -a -I -1 terminfo >$@ termcap.out : termcap ; $(TIC) -a -C -U termcap >$@ ################################################################################ docs-ctlseqs \ docs :: $(srcdir)/ctlseqs.txt @MAN2HTML_NOTE@ ctlseqs.html @GROFF_NOTE@ ctlseqs.pdf ctlseqs.ps ctlseqs.html : $(srcdir)/ctlseqs.ms ctlseqs.pdf : ctlseqs.ps ctlseqs.ps : $(srcdir)/ctlseqs.ms ctlseqs.txt : $(srcdir)/ctlseqs.ms ################################################################################ docs-resize \ docs :: resize.txt @MAN2HTML_NOTE@ resize.html @GROFF_NOTE@ resize.pdf resize.ps resize.html : resize.$(manext) resize.pdf : resize.ps resize.ps : resize.$(manext) resize.txt : resize.$(manext) ################################################################################ docs-xterm \ docs :: xterm.txt @MAN2HTML_NOTE@ xterm.html @GROFF_NOTE@ xterm.pdf xterm.ps xterm.html : xterm.$(manext) xterm.pdf : xterm.ps xterm.ps : xterm.$(manext) xterm.txt : xterm.$(manext) ################################################################################ docs-uxterm \ docs :: uxterm.txt @MAN2HTML_NOTE@ uxterm.html @GROFF_NOTE@ uxterm.pdf uxterm.ps uxterm.html : uxterm.$(manext) uxterm.pdf : uxterm.ps uxterm.ps : uxterm.$(manext) uxterm.txt : uxterm.$(manext) ################################################################################ docs-koi8rxterm \ docs :: koi8rxterm.txt @MAN2HTML_NOTE@ koi8rxterm.html @GROFF_NOTE@ koi8rxterm.pdf koi8rxterm.ps koi8rxterm.html : koi8rxterm.$(manext) koi8rxterm.pdf : koi8rxterm.ps koi8rxterm.ps : koi8rxterm.$(manext) koi8rxterm.txt : koi8rxterm.$(manext) ################################################################################ lint : $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(SRCS1) $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(SRCS2) tags : $(CTAGS) $(SRCS) $(HDRS) TAGS : $(ETAGS) $(SRCS) $(HDRS) $(TERMINFO_DIR) $(INSTALL_DIRS) : mkdir -p $@ ALWAYS : depend : $(TABLES) makedepend -- $(CPPFLAGS) -- $(SRCS) # DO NOT DELETE THIS LINE -- make depend depends on it. xterm-399/xutf8.c0000644000000000000000000001727414774607127012511 0ustar rootroot/* $XTermId: xutf8.c,v 1.20 2025/04/06 23:29:27 tom Exp $ */ /* * Copyright 2002-2020,2025 by Thomas E. Dickey * Copyright (c) 2001 by Juliusz Chroboczek * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #ifndef X_HAVE_UTF8_STRING #undef XA_UTF8_STRING Atom _xa_utf8_string(Display *dpy) { static AtomPtr p = NULL; if (p == NULL) p = XmuMakeAtom("UTF8_STRING"); return XmuInternAtom(dpy, p); } #define XA_UTF8_STRING(dpy) _xa_utf8_string(dpy) static int utf8countBytes(int c) { if (c < 0) return 0; if (c <= 0x7F) { return 1; } else if (c <= 0x7FF) { return 2; } else if (c <= 0xFFFF) { return 3; } else return 4; } static void utf8insert(char *dest, int c, size_t *len_return) { if (c < 0) return; if (c <= 0x7F) { dest[0] = (char) c; *len_return = 1; } else if (c <= 0x7FF) { dest[0] = (char) (0xC0 | ((c >> 6) & 0x1F)); dest[1] = (char) (0x80 | (c & 0x3F)); *len_return = 2; } else if (c <= 0xFFFF) { dest[0] = (char) (0xE0 | ((c >> 12) & 0x0F)); dest[1] = (char) (0x80 | ((c >> 6) & 0x3F)); dest[2] = (char) (0x80 | (c & 0x3F)); *len_return = 3; } else { dest[0] = (char) (0xF0 | ((c >> 18) & 0x07)); dest[1] = (char) (0x80 | ((c >> 12) & 0x3f)); dest[2] = (char) (0x80 | ((c >> 6) & 0x3f)); dest[3] = (char) (0x80 | (c & 0x3f)); *len_return = 4; } } static size_t l1countUtf8Bytes(char *s, size_t len) { size_t l = 0; while (len != 0) { if ((*s & 0x80) == 0) l++; else l += 2; s++; len--; } return l; } static void l1utf8copy(char *d, char *s, size_t len) { size_t l; while (len != 0) { utf8insert(d, (*s) & 0xFF, &l); d += (int) l; s++; len--; } } static void utf8l1strcpy(char *d, char *s) { #define SKIP do { s++; } while(((*s & 0x80) != 0) && (*s & 0xC0) != 0xC0) while (*s) { if ((*s & 0x80) == 0) *d++ = *s++; else if ((*s & 0x7C) == 0x40) { if ((s[1] & 0x80) == 0) { s++; /* incorrect UTF-8 */ continue; } else if ((*s & 0x7C) == 0x40) { *d++ = (char) (((*s & 0x03) << 6) | (s[1] & 0x3F)); s += 2; } else { *d++ = BAD_ASCII; SKIP; } } else { *d++ = BAD_ASCII; SKIP; } } *d = 0; #undef SKIP } /* Keep this in sync with utf8l1strcpy! */ static int utf8l1strlen(char *s) { #define SKIP do { s++; } while(((*s & 0x80) != 0) && (*s & 0xC0) != 0xC0) int len = 0; while (*s) { if ((*s & 0x80) == 0) { s++; len++; } else if ((*s & 0x7C) == 0x40) { if ((s[1] & 0x80) == 0) { s++; continue; } else if ((*s & 0x7C) == 0x40) { len++; s += 2; } else { len++; SKIP; } } else { len++; SKIP; } } #undef SKIP return len; } int Xutf8TextPropertyToTextList(Display *dpy, const XTextProperty * tp, char ***list_return, int *count_return) { int utf8; char **list; int nelements; char *cp; char *start; size_t i; int j; size_t datalen = tp->nitems; size_t len; if (tp->format != 8) return XConverterNotFound; if (tp->encoding == XA_STRING) utf8 = 0; else if (tp->encoding == XA_UTF8_STRING(dpy)) utf8 = 1; else return XConverterNotFound; if (datalen == 0) { *list_return = NULL; *count_return = 0; return 0; } nelements = 1; for (cp = (char *) tp->value, i = datalen; i != 0; cp++, i--) { if (*cp == '\0') nelements++; } list = TypeMallocN(char *, (unsigned) nelements); if (!list) return XNoMemory; if (utf8) len = datalen; else len = l1countUtf8Bytes((char *) tp->value, datalen); start = malloc(len + 1); if (!start) { free(list); return XNoMemory; } if (utf8) memcpy(start, (char *) tp->value, datalen); else l1utf8copy(start, (char *) tp->value, datalen); start[len] = '\0'; for (cp = start, i = len + 1, j = 0; i != 0; cp++, i--) { if (*cp == '\0') { list[j] = start; start = (cp + 1); j++; } } list[j] = NULL; *list_return = list; *count_return = nelements; return 0; } int Xutf8TextListToTextProperty(Display *dpy, char **list, int count, XICCEncodingStyle style, XTextProperty * text_prop) { XTextProperty proto; unsigned int nbytes; int i; if (style != XStringStyle && style != XCompoundTextStyle && style != XStdICCTextStyle && style != XUTF8StringStyle) return XConverterNotFound; if (style == XUTF8StringStyle) { for (i = 0, nbytes = 0; i < count; i++) { nbytes += (unsigned) ((list[i] ? strlen(list[i]) : 0) + 1); } } else { for (i = 0, nbytes = 0; i < count; i++) { nbytes += (unsigned) ((list[i] ? utf8l1strlen(list[i]) : 0) + 1); } } if (style == XCompoundTextStyle) proto.encoding = XA_COMPOUND_TEXT(dpy); else if (style == XUTF8StringStyle) proto.encoding = XA_UTF8_STRING(dpy); else proto.encoding = XA_STRING; proto.format = 8; if (nbytes) proto.nitems = nbytes - 1; else proto.nitems = 0; proto.value = NULL; if (nbytes > 0) { char *buf = TypeMallocN(char, nbytes); if (!buf) return XNoMemory; proto.value = (unsigned char *) buf; for (i = 0; i < count; i++) { char *arg = list[i]; if (arg) { if (style == XUTF8StringStyle) { strcpy(buf, arg); } else { utf8l1strcpy(buf, arg); } buf += (strlen(buf) + 1); } else { *buf++ = '\0'; } } } else { proto.value = CastMalloc(unsigned char); /* easier for client */ if (!proto.value) return XNoMemory; proto.value[0] = '\0'; } *text_prop = proto; return 0; } int Xutf8LookupString(XIC ic GCC_UNUSED, XKeyEvent *ev, char *buffer, int nbytes, KeySym * keysym_return, Status * status_return) { int rc; KeySym keysym; int codepoint; size_t len; rc = XLookupString(ev, buffer, nbytes, &keysym, NULL); if (rc > 0) { codepoint = buffer[0] & 0xFF; } else if (keysym < 0xfd00 || (keysym >= 0x1000000 && keysym < 0x10000000)) { codepoint = keysym2ucs(keysym); } else { codepoint = -1; } if (codepoint < 0) { if (keysym == None) { *status_return = XLookupNone; } else { *status_return = XLookupKeySym; *keysym_return = keysym; } return 0; } if (nbytes < utf8countBytes(codepoint)) { *status_return = XBufferOverflow; return utf8countBytes(codepoint); } utf8insert(buffer, codepoint, &len); if (keysym != None) { *keysym_return = keysym; *status_return = XLookupBoth; } else { *status_return = XLookupChars; } return (int) len; } #else /* X_HAVE_UTF8_STRING */ /* Silence the compiler */ void xutf8_dummy(void) { return; } #endif xterm-399/MANIFEST0000644000000000000000000003706314777541255012420 0ustar rootrootMANIFEST for xterm, version xterm-399 -------------------------------------------------------------------------------- MANIFEST this file 256colres.h resource-definitions for 256-color mode 256colres.pl script to generate 256colres.h 88colres.h resource definitions for 88-color mode 88colres.pl script to generate 88colres.h COPYING license for this program INSTALL configure script: options and related install instructions Imakefile imake template for Makefile KOI8RXTerm.ad resources for koi8rxterm Makefile.in configure script template for Makefile README overview & caveats for 'xterm' README.i18n i18n readme: THANKS list of direct contributors TekPrsTbl.c Tek4014 parser state tables Tekparse.def template for generating Tekparse.h Tekparse.h Tek4014 parser-state definitions Tekproc.c Tek4014 parser-state functions Tests Useful tests for xterm-developers UXTerm.ad alternate resources for UTF-8 VTPrsTbl.c VT100 parser state tables VTparse.def template for generating VTparse.h VTparse.h VT100 parser-state definitions XTerm-col.ad color resource definitions for XTerm class XTerm.ad resource definitions for XTerm class aclocal.m4 configure script: custom macros button.c mouse button and selection processing cachedGCs.c maintain cache of GC's charclass.c compact character-class module charclass.h interface of charclass.c charproc.c VT100 parser functions charsets.c module to translate character-sets charsets.dat raw data to transform into charsets.h charsets.h charset definitions for xterm config.guess configure script: guess the system type config.sub configure script: validate system type configure generated configure.in template for generating configure script ctlseqs.ms documentation: Xterm Control Sequences ctlseqs.txt generated rendition of ctlseqs.ms cursor.c VT100 low-level cursor movement data.c global data declarations data.h global data external-definitions df-install.in utility script for desktop-files doublechr.c VT100 double-size character support error.h error-code definitions for 'xterm' fontutils.c xterm functions for (re)loading fonts fontutils.h interface of fontutils.c gen-charsets.pl script to convert codepages into code gen-pc-fkeys.pl script to generate extended function-key terminfo graphics.c graphics support functions for 'xterm' graphics.h interface of graphics.c graphics_regis.c support for ReGIS graphics_regis.h interface of graphics_regis.c graphics_sixel.c support for Sixels graphics_sixel.h interface of graphics_sixel.c html.c format HTML-screendumps input.c VT100 key-symbol and function-key translation install-sh install-script (needed by configure) keysym2ucs.c lookup-table for UTF-8 to keysyms keysym2ucs.h interface of keysym2ucs.c koi8rxterm KOI-8 wrapper from Debian (originally me) koi8rxterm.man manpage for koi8rxterm linedata.c manage all line-data for VT100 widget main.c main program of 'xterm' main.h default definitions for 'xterm' menu.c popup/pulldown menus for 'xterm' menu.h interface of menu.c minstall.in script for installing manpages misc.c miscellaneous utility functions for 'xterm' plink.sh script to prune unneeded libraries from link precompose.c table of precompose sequences precompose.h interface of precompose.c print.c VT100+ print support functions ptydata.c functions to manipulate data read from pty ptyx.h structure-definitions for 'xterm' resize.c program to compute/modify xterm's window size resize.man manual page for 'resize' run-tic.in run tic, filtering out harmless messages (template) screen.c VT100 screen update functions scrollback.c manage scrollback (a big FIFO) scrollbar.c VT100 scrollbar support functions sinstall.sh install setuid if existing program was svg.c format SVG-screendumps tabs.c VT100 tabstop support-functions termcap termcap entries for 'xterm' terminfo terminfo entries for 'xterm' testxmc.c testing: xmc/magic-cookies trace.c debugging trace functions for 'xterm' trace.h interface of trace.c util.c miscellaneous utility functions for 'xterm' uxterm wrapper script to make unicode-xterm uxterm.desktop sample desktop file for uxterm uxterm.man manpage for uxterm, from Debian version.c xterm package version, used also in resize version.h version of xterm wcwidth.c wide-character utility functions wcwidth.h interface of wcwidth.c xcharmouse.h Jason Bacon's mouse-defs, cleaned up a little xstrings.c a few common string functions xstrings.h interface of xstrings.c xterm.appdata.xml sample "appdata.xml" file xterm.desktop sample desktop file for xterm. xterm.h common includes, definitions and prototypes for 'xterm' xterm.log.html changelog for xterm xterm.man manual page for 'xterm' xterm_io.h split-out definitions of termio/termios/sgtty and winsize from main.c, os2main.c, screen.c and resize.c xtermcap.c termcap-related functions. xtermcap.h interface of xtermcap.c xtermcfg.hin configure script: template for xtermcfg.h xutf8.c JC's cleanup of UTF8 xutf8.h JC's cleanup of UTF8 icons subdirectory icons/filled-xterm.png filled-xterm variants icons/filled-xterm.svg filled-xterm variants icons/filled-xterm.xpms filled-xterm variants icons/filled-xterm_16x16.xpm filled-xterm variants icons/filled-xterm_32x32.xpm filled-xterm variants icons/filled-xterm_48x48.xpm filled-xterm variants icons/make-xpms script to make combined xpm-icons icons/mini.xterm.svg svg format for mini-icon icons/mini.xterm.xpms collection of mini-icons icons/mini.xterm_16x16.png mini-icon 16x16 png icons/mini.xterm_16x16.xpm mini-icon 16x16 pixmap icons/mini.xterm_256x256.png mini-icon 256x256 png icons/mini.xterm_32x32.png mini-icon 32x32 png icons/mini.xterm_32x32.xpm mini-icon 32x32 pixmap icons/mini.xterm_48x48.png mini-icon 48x48 png icons/mini.xterm_48x48.xpm mini-icon 48x48 pixmap icons/terminal_48x48.svg svg-format of "terminal" icons/terminal_48x48.xpm xpm-format of "terminal" icons/xterm-color.png xterm-color 48x48, in png-format icons/xterm-color.svg xterm-color icon icons/xterm-color.xpms collection of color icons icons/xterm-color_16x16.xpm 16x16 color icon icons/xterm-color_32x32.xpm 32x32 color icon icons/xterm-color_48x48.xpm 48x48 color icon icons/xterm.png xterm 48x48, in png-format icons/xterm.svg xterm icon icons/xterm.xpms collection of icons icons/xterm_16x16.xpm normal icon 16x16 pixmap icons/xterm_32x32.xpm 32x32 monochrome icon icons/xterm_48x48.xpm 48x48 monochrome icon package subdirectory package/xterm.spec build-script package/debian subdirectory package/debian/changelog build-script package/debian/color.sed build-script package/debian/compat build-script package/debian/control build-script package/debian/copyright build-script package/debian/postinst post-install script for update-alternatives package/debian/prerm pre-remove script for update-alternatives package/debian/rules build-script package/debian/watch build-script package/debian/xterm-dev.docs build-script package/debian/xterm-dev.lintian-overrides ignore useless warnings from lintian package/debian/xterm-dev.menu Debian menu-file for xterm-dev package. package/debian/xterm-xres.sed build-script package/debian/source subdirectory package/debian/source/format build-script package/freebsd subdirectory package/freebsd/Makefile build-script package/freebsd/distinfo generated sums package/freebsd/pkg-descr build-script package/freebsd/pkg-message.wchar build-script package/freebsd/pkg-plist build-script package/pkgsrc subdirectory package/pkgsrc/DESCR build-script package/pkgsrc/Makefile build-script package/pkgsrc/PLIST build-script package/pkgsrc/distinfo build-script package/pkgsrc/options.mk build-script tektests subdirectory tektests/aitest.tek tek4014 demo: draw a globe tektests/dmerc.tek tek4014 demo: draws a Mercator projection with orbit tektests/fotest.tek tek4014 demo: draw a scatterplot on log scale tektests/imtest.tek tek4014 demo: draw a test pattern tektests/imtesth.tek tek4014 demo: draw a test pattern tektests/ocpred.tek tek4014 demo: an occultation prediction tektests/usmap.tek tek4014 demo: a US map unicode subdirectory unicode/README description of files in ./unicode unicode/convmap.pl perl script for generating the lookup table for UTF-8 to keysym unicode/keysym.map keysym mapping from UTF-8 unicode/make-precompose.sh make precompose.c unicode/precompose.c.head header of precompose.c unicode/precompose.c.tail tail of precompose.c vttests subdirectory vttests/16colors.sh test-script to show 16-colors vttests/256colors.pl script to illustrate 256-colors vttests/256colors2.pl fancy test-script for 256-colors vttests/88colors.pl sample script showing 88-colors vttests/88colors2.pl sample script showing 88-colors vttests/8colors.sh test-script to illustrate 8-colors vttests/acolors.sh demonstrate changing the ANSI colors vttests/acs.pl simple test for mapping alternate-character-set vttests/altchars.sh simple test for alternate-character-set vttests/blink.pl test scrollback of blinking text vttests/bold-italics.pl Test bold-italics for single- and double-width characters. vttests/bounce.sh iconify/deiconify, recording the window properties vttests/closest-rgb.pl demo of color-distances vttests/ctlpix.sh display control/picture codes vttests/cursor.pl exercise cursor-movement, to check color-contrasts vttests/decsed.pl exercise DECSED with/without DECSCA vttests/dl.sh simple test for delete-line with margins vttests/doublechars.sh test script to demonstrate doublesize chars vttests/dynamic.pl demo for dynamic colors vttests/dynamic.sh script to illustrate the dynamic colors control sequence vttests/dynamic2.sh complete example of dynamic colors vttests/erase.pl Generate a test-pattern, erasing parts of the text on each line. vttests/fonts.sh script to demonstrate font-switching sequences vttests/halves.pl test partial-update of double-cell characters vttests/il.sh simple test for insert-line with margins vttests/insdelln.pl Tests insert/delete-line feature in xterm. vttests/iso2022.pl show ISO-2022 characters, by default GL and GR, optionally G1/G2/G3 vttests/lrmm-scroll.pl Tests scroll left/right feature in xterm, optionally using margins. vttests/modify-keys.pl illustrate modifyOtherKeys with a table vttests/mouse-codes demo script for mouse-codes vttests/nrcs.pl a more direct way of exercising character sets than vttest. vttests/other-sgr.sh demonstrate non-VTxx SGRs vttests/palettes.pl Demonstrate how to set palette colors using xterm's control sequences. vttests/paste64.pl script to test base64-selection option vttests/pointer-shapes.sh exercise xterm's pointer-shape control vttests/print-vt-chars.pl demo-script vttests/query-color.pl demonstrate OSC 4 vttests/query-dynamic.pl demonstrate OSC 10 to OSC 19 vttests/query-fonts.pl script to demo/test font-querying vttests/query-status.pl query DECRQSS status vttests/query-xres.pl test/demo for DCS+Q vttests/report-sgr.pl demonstrate report-sgr vttests/resize.pl translated resize.sh to perl since it is easy to test, and I needed vttests/resize.sh script to demonstrate resizing vttests/scroll.pl Tests insert/delete-line feature in xterm. vttests/setpos.pl Exercise CSI 3/13 t which set/get the window position. vttests/sgrPushPop.pl demonstrate xterm SGR push/pop vttests/sgrPushPop2.pl demonstrate xterm SGR push/pop for colors vttests/tab0.sh Demonstrate hard-tabs. vttests/tcapquery.pl script to test tcap-query option vttests/title.sh test-script to show title of xterm in action vttests/titlestack.pl Test the title-stack and title-mode options of xterm. vttests/unascii.sh display the characters recognized by xterm in AsciiEquivs vttests/under-latin.pl Print a text-test pattern using Latin-1 characters. vttests/utf8.pl display the given Unicode characters, given their hex or decimal values. vttests/version.sh Demonstrate version-string from xterm #354 vttests/vt52chars.pl show the vt52 graphic characters, annotatated in a table. vttests/wrap.pl Generates a series of wrapping lines, according to the terminal width. vttests/xorblink.pl walk through the different states of cursor-blinking, with annotation vttests/xtra-scroll.pl Interactively test screen-updates, e.g., cdXtraScroll and and tiXtraScroll xterm-399/graphics_sixel.h0000644000000000000000000000353614640616522014427 0ustar rootroot/* $XTermId: graphics_sixel.h,v 1.9 2024/07/01 21:19:14 tom Exp $ */ /* * Copyright 2014-2016,2024 by Thomas E. Dickey * Copyright 2014,2016 by Ross Combs * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #ifndef included_graphics_sixel_h #define included_graphics_sixel_h /* *INDENT-OFF* */ #include #if OPT_SIXEL_GRAPHICS extern void parse_sixel_init(XtermWidget /* xw */, ANSI * /* params */); extern void parse_sixel_char(char /* cp */); extern void parse_sixel_finished(void); #endif /* *INDENT-ON* */ #endif /* included_graphics_sixel_h */ xterm-399/keysym2ucs.h0000644000000000000000000000036406731024345013533 0ustar rootroot/* $XFree86: xc/programs/xterm/keysym2ucs.h,v 1.1 1999/06/12 15:37:18 dawes Exp $ */ /* * This module converts keysym values into the corresponding ISO 10646-1 * (UCS, Unicode) values. */ #include long keysym2ucs(KeySym keysym); xterm-399/wcwidth.c0000644000000000000000000013300514723173006013057 0ustar rootroot/* $XTermId: wcwidth.c,v 1.76 2024/12/01 23:49:26 tom Exp $ */ /* $XFree86: xc/programs/xterm/wcwidth.c,v 1.9 2006/06/19 00:36:52 dickey Exp $ */ /* * Copyright 2002-2023,2024 by Thomas E. Dickey * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. *----------------------------------------------------------------------------- * This is an updated version of Markus Kuhn's implementation of wcwidth. * * Originally added to xterm in 2000 (patch #141), there were a couple of * updates from Kuhn until 2005 (patch #202), renaming entrypoints and applying * data from Unicode.org (e.g., 3.2, 4.0, 4.1.0). The Unicode data is * transformed into tables in this file by a script "uniset" written by Kuhn. * * While Kuhn implemented the original CJK variant, it was unused by xterm * until Jungshik Shin used it in 2002 to implement the -cjk_width command-line * option. * * Kuhn added a check for the vertical forms block (double-width) in 2007; * other updates were derived from the Unicode.org data (release 5.0). * * Since then, additional updates have been made: * + data-type fixes * + new Unicode releases (6.2.0, 9.0.0, etc), * + additional special symbol blocks have been added to the special cases. * + soft-hyphen behavior has been made configurable. * + added table shows when a character is not part of Unicode. * * Kuhn's original header follows giving the design information: *----------------------------------------------------------------------------- * This is an implementation of wcwidth() and wcswidth() (defined in * IEEE Std 1002.1-2001) for Unicode. * * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html * * In fixed-width output devices, Latin characters all occupy a single * "cell" position of equal width, whereas ideographic CJK characters * occupy two such cells. Interoperability between terminal-line * applications and (teletype-style) character terminals using the * UTF-8 encoding requires agreement on which character should advance * the cursor by how many cell positions. No established formal * standards exist at present on which Unicode character shall occupy * how many cell positions on character terminals. These routines are * a first attempt of defining such behavior based on simple rules * applied to data provided by the Unicode Consortium. * * For some graphical characters, the Unicode standard explicitly * defines a character-cell width via the definition of the East Asian * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes. * In all these cases, there is no ambiguity about which width a * terminal shall use. For characters in the East Asian Ambiguous (A) * class, the width choice depends purely on a preference of backward * compatibility with either historic CJK or Western practice. * Choosing single-width for these characters is easy to justify as * the appropriate long-term solution, as the CJK practice of * displaying these characters as double-width comes from historic * implementation simplicity (8-bit encoded characters were displayed * single-width and 16-bit ones double-width, even for Greek, * Cyrillic, etc.) and not any typographic considerations. * * Much less clear is the choice of width for the Not East Asian * (Neutral) class. Existing practice does not dictate a width for any * of these characters. It would nevertheless make sense * typographically to allocate two character cells to characters such * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be * represented adequately with a single-width glyph. The following * routines at present merely assign a single-cell width to all * neutral characters, in the interest of simplicity. This is not * entirely satisfactory and should be reconsidered before * establishing a formal standard in this area. At the moment, the * decision which Not East Asian (Neutral) characters should be * represented by double-width glyphs cannot yet be answered by * applying a simple rule from the Unicode database content. Setting * up a proper standard for the behavior of UTF-8 character terminals * will require a careful analysis not only of each Unicode character, * but also of each presentation form, something the author of these * routines has avoided to do so far. * * http://www.unicode.org/unicode/reports/tr11/ * * Markus Kuhn -- 2007-05-25 (Unicode 5.0) * * Permission to use, copy, modify, and distribute this software * for any purpose and without fee is hereby granted. The author * disclaims all warranties with regard to this software. * * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c *----------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include #endif #ifdef TEST_DRIVER #include #include /* EXIT_SUCCESS, etc. */ #include /* getopt() */ #include /* strncmp() */ #include /* setlocale() */ #include /* this module */ #endif #ifdef HAVE_WCHAR_H #include /* wcwidth() */ #endif #include struct interval { unsigned long first; unsigned long last; }; static int use_latin1 = 1; /* auxiliary function for binary search in interval table */ static int bisearch(unsigned long ucs, const struct interval *table, int max) { if (ucs >= table[0].first && ucs <= table[max].last) { int min = 0; while (max >= min) { int mid; mid = (min + max) / 2; if (ucs > table[mid].last) min = mid + 1; else if (ucs < table[mid].first) max = mid - 1; else return 1; } } return 0; } /* * Provide a way to change the behavior of soft-hyphen. */ void mk_wcwidth_init(int mode) { use_latin1 = (mode == 0); } /* The following two functions define the column width of an ISO 10646 * character as follows: * * - The null character (U+0000) has a column width of 0. * * - Other C0/C1 control characters and DEL will lead to a return * value of -1. * * - Non-spacing and enclosing combining characters (general * category code Mn or Me in the Unicode database) have a * column width of 0. * * - A few spacing combining marks have a column width of 0. * * - SOFT HYPHEN (U+00AD) has a column width of 1 in Latin-1, 0 in Unicode. * An initialization function is used to switch between the two. * * - Other format characters (general category code Cf in the Unicode * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. * * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) * have a column width of 0. * * - Hangul Jamo Extended-B medial vowels and final consonants for old * Korean (U+D7B0-U+D7FF) have a column width of 0. * * - Spacing characters in the East Asian Wide (W) or East Asian * Full-width (F) category as defined in Unicode Technical * Report #11 have a column width of 2. In that report, some codes * were unassigned. Characters in these blocks use a column width of 1: * 4DC0..4DFF; Yijing Hexagram Symbols * A960..A97F; Hangul Jamo Extended-A * * - All remaining characters (including all printable * ISO 8859-1 and WGL4 characters, Unicode control characters, * etc.) have a column width of 1. * * - Codes which do not correspond to a Unicode character have a column * width of -1. * * This implementation assumes that wchar_t characters are encoded * in ISO 10646. */ int mk_wcwidth(wchar_t ucs) { unsigned long cmp = (unsigned long) ucs; /* sorted list of non-overlapping intervals of formatting characters */ /* generated by * uniset +cat=Cf -00AD -0600-0605 -061C -06DD -070F c */ /* *INDENT-OFF* */ /* generated by run-uniset_ctl 1.1 */ static const struct interval formatting[] = { { 0x0890, 0x0891 }, { 0x08E2, 0x08E2 }, { 0x180E, 0x180E }, { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2064 }, { 0x2066, 0x206F }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, { 0x110BD, 0x110BD }, { 0x110CD, 0x110CD }, { 0x13430, 0x1343F }, { 0x1BCA0, 0x1BCA3 }, { 0x1D173, 0x1D17A }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F } }; /* *INDENT-OFF* */ /* sorted list of non-overlapping intervals of non-spacing characters */ /* generated by * uniset +cat=Me +cat=Mn +0600-0605 +061C +06DD +070F +1160-11FF +D7B0-D7C6 +D7CB-D7FB c */ /* *INDENT-OFF* */ /* generated by run-uniset 1.9 */ static const struct interval combining[] = { { 0x0300, 0x036F }, { 0x0483, 0x0489 }, { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0605 }, { 0x0610, 0x061A }, { 0x061C, 0x061C }, { 0x064B, 0x065F }, { 0x0670, 0x0670 }, { 0x06D6, 0x06DD }, { 0x06DF, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x07FD, 0x07FD }, { 0x0816, 0x0819 }, { 0x081B, 0x0823 }, { 0x0825, 0x0827 }, { 0x0829, 0x082D }, { 0x0859, 0x085B }, { 0x0897, 0x089F }, { 0x08CA, 0x08E1 }, { 0x08E3, 0x0902 }, { 0x093A, 0x093A }, { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0957 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 }, { 0x09FE, 0x09FE }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A51, 0x0A51 }, { 0x0A70, 0x0A71 }, { 0x0A75, 0x0A75 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0AE2, 0x0AE3 }, { 0x0AFA, 0x0AFF }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B44 }, { 0x0B4D, 0x0B4D }, { 0x0B55, 0x0B56 }, { 0x0B62, 0x0B63 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C00, 0x0C00 }, { 0x0C04, 0x0C04 }, { 0x0C3C, 0x0C3C }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0C62, 0x0C63 }, { 0x0C81, 0x0C81 }, { 0x0CBC, 0x0CBC }, { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, { 0x0CE2, 0x0CE3 }, { 0x0D00, 0x0D01 }, { 0x0D3B, 0x0D3C }, { 0x0D41, 0x0D44 }, { 0x0D4D, 0x0D4D }, { 0x0D62, 0x0D63 }, { 0x0D81, 0x0D81 }, { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EBC }, { 0x0EC8, 0x0ECE }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F8D, 0x0F97 }, { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1037 }, { 0x1039, 0x103A }, { 0x103D, 0x103E }, { 0x1058, 0x1059 }, { 0x105E, 0x1060 }, { 0x1071, 0x1074 }, { 0x1082, 0x1082 }, { 0x1085, 0x1086 }, { 0x108D, 0x108D }, { 0x109D, 0x109D }, { 0x1160, 0x11FF }, { 0x135D, 0x135F }, { 0x1712, 0x1714 }, { 0x1732, 0x1733 }, { 0x1752, 0x1753 }, { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, { 0x180B, 0x180D }, { 0x180F, 0x180F }, { 0x1885, 0x1886 }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, { 0x1A17, 0x1A18 }, { 0x1A1B, 0x1A1B }, { 0x1A56, 0x1A56 }, { 0x1A58, 0x1A5E }, { 0x1A60, 0x1A60 }, { 0x1A62, 0x1A62 }, { 0x1A65, 0x1A6C }, { 0x1A73, 0x1A7C }, { 0x1A7F, 0x1A7F }, { 0x1AB0, 0x1ACE }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, { 0x1B6B, 0x1B73 }, { 0x1B80, 0x1B81 }, { 0x1BA2, 0x1BA5 }, { 0x1BA8, 0x1BA9 }, { 0x1BAB, 0x1BAD }, { 0x1BE6, 0x1BE6 }, { 0x1BE8, 0x1BE9 }, { 0x1BED, 0x1BED }, { 0x1BEF, 0x1BF1 }, { 0x1C2C, 0x1C33 }, { 0x1C36, 0x1C37 }, { 0x1CD0, 0x1CD2 }, { 0x1CD4, 0x1CE0 }, { 0x1CE2, 0x1CE8 }, { 0x1CED, 0x1CED }, { 0x1CF4, 0x1CF4 }, { 0x1CF8, 0x1CF9 }, { 0x1DC0, 0x1DFF }, { 0x20D0, 0x20F0 }, { 0x2CEF, 0x2CF1 }, { 0x2D7F, 0x2D7F }, { 0x2DE0, 0x2DFF }, { 0x302A, 0x302D }, { 0x3099, 0x309A }, { 0xA66F, 0xA672 }, { 0xA674, 0xA67D }, { 0xA69E, 0xA69F }, { 0xA6F0, 0xA6F1 }, { 0xA802, 0xA802 }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, { 0xA825, 0xA826 }, { 0xA82C, 0xA82C }, { 0xA8C4, 0xA8C5 }, { 0xA8E0, 0xA8F1 }, { 0xA8FF, 0xA8FF }, { 0xA926, 0xA92D }, { 0xA947, 0xA951 }, { 0xA980, 0xA982 }, { 0xA9B3, 0xA9B3 }, { 0xA9B6, 0xA9B9 }, { 0xA9BC, 0xA9BD }, { 0xA9E5, 0xA9E5 }, { 0xAA29, 0xAA2E }, { 0xAA31, 0xAA32 }, { 0xAA35, 0xAA36 }, { 0xAA43, 0xAA43 }, { 0xAA4C, 0xAA4C }, { 0xAA7C, 0xAA7C }, { 0xAAB0, 0xAAB0 }, { 0xAAB2, 0xAAB4 }, { 0xAAB7, 0xAAB8 }, { 0xAABE, 0xAABF }, { 0xAAC1, 0xAAC1 }, { 0xAAEC, 0xAAED }, { 0xAAF6, 0xAAF6 }, { 0xABE5, 0xABE5 }, { 0xABE8, 0xABE8 }, { 0xABED, 0xABED }, { 0xD7B0, 0xD7C6 }, { 0xD7CB, 0xD7FB }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, { 0xFE20, 0xFE2F }, { 0x101FD, 0x101FD }, { 0x102E0, 0x102E0 }, { 0x10376, 0x1037A }, { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x10AE5, 0x10AE6 }, { 0x10D24, 0x10D27 }, { 0x10D69, 0x10D6D }, { 0x10EAB, 0x10EAC }, { 0x10EFC, 0x10EFF }, { 0x10F46, 0x10F50 }, { 0x10F82, 0x10F85 }, { 0x11001, 0x11001 }, { 0x11038, 0x11046 }, { 0x11070, 0x11070 }, { 0x11073, 0x11074 }, { 0x1107F, 0x11081 }, { 0x110B3, 0x110B6 }, { 0x110B9, 0x110BA }, { 0x110C2, 0x110C2 }, { 0x11100, 0x11102 }, { 0x11127, 0x1112B }, { 0x1112D, 0x11134 }, { 0x11173, 0x11173 }, { 0x11180, 0x11181 }, { 0x111B6, 0x111BE }, { 0x111C9, 0x111CC }, { 0x111CF, 0x111CF }, { 0x1122F, 0x11231 }, { 0x11234, 0x11234 }, { 0x11236, 0x11237 }, { 0x1123E, 0x1123E }, { 0x11241, 0x11241 }, { 0x112DF, 0x112DF }, { 0x112E3, 0x112EA }, { 0x11300, 0x11301 }, { 0x1133B, 0x1133C }, { 0x11340, 0x11340 }, { 0x11366, 0x1136C }, { 0x11370, 0x11374 }, { 0x113BB, 0x113C0 }, { 0x113CE, 0x113CE }, { 0x113D0, 0x113D0 }, { 0x113D2, 0x113D2 }, { 0x113E1, 0x113E2 }, { 0x11438, 0x1143F }, { 0x11442, 0x11444 }, { 0x11446, 0x11446 }, { 0x1145E, 0x1145E }, { 0x114B3, 0x114B8 }, { 0x114BA, 0x114BA }, { 0x114BF, 0x114C0 }, { 0x114C2, 0x114C3 }, { 0x115B2, 0x115B5 }, { 0x115BC, 0x115BD }, { 0x115BF, 0x115C0 }, { 0x115DC, 0x115DD }, { 0x11633, 0x1163A }, { 0x1163D, 0x1163D }, { 0x1163F, 0x11640 }, { 0x116AB, 0x116AB }, { 0x116AD, 0x116AD }, { 0x116B0, 0x116B5 }, { 0x116B7, 0x116B7 }, { 0x1171D, 0x1171D }, { 0x1171F, 0x1171F }, { 0x11722, 0x11725 }, { 0x11727, 0x1172B }, { 0x1182F, 0x11837 }, { 0x11839, 0x1183A }, { 0x1193B, 0x1193C }, { 0x1193E, 0x1193E }, { 0x11943, 0x11943 }, { 0x119D4, 0x119D7 }, { 0x119DA, 0x119DB }, { 0x119E0, 0x119E0 }, { 0x11A01, 0x11A0A }, { 0x11A33, 0x11A38 }, { 0x11A3B, 0x11A3E }, { 0x11A47, 0x11A47 }, { 0x11A51, 0x11A56 }, { 0x11A59, 0x11A5B }, { 0x11A8A, 0x11A96 }, { 0x11A98, 0x11A99 }, { 0x11C30, 0x11C36 }, { 0x11C38, 0x11C3D }, { 0x11C3F, 0x11C3F }, { 0x11C92, 0x11CA7 }, { 0x11CAA, 0x11CB0 }, { 0x11CB2, 0x11CB3 }, { 0x11CB5, 0x11CB6 }, { 0x11D31, 0x11D36 }, { 0x11D3A, 0x11D3A }, { 0x11D3C, 0x11D3D }, { 0x11D3F, 0x11D45 }, { 0x11D47, 0x11D47 }, { 0x11D90, 0x11D91 }, { 0x11D95, 0x11D95 }, { 0x11D97, 0x11D97 }, { 0x11EF3, 0x11EF4 }, { 0x11F00, 0x11F01 }, { 0x11F36, 0x11F3A }, { 0x11F40, 0x11F40 }, { 0x11F42, 0x11F42 }, { 0x11F5A, 0x11F5A }, { 0x13440, 0x13440 }, { 0x13447, 0x13455 }, { 0x1611E, 0x16129 }, { 0x1612D, 0x1612F }, { 0x16AF0, 0x16AF4 }, { 0x16B30, 0x16B36 }, { 0x16F4F, 0x16F4F }, { 0x16F8F, 0x16F92 }, { 0x16FE4, 0x16FE4 }, { 0x1BC9D, 0x1BC9E }, { 0x1CF00, 0x1CF2D }, { 0x1CF30, 0x1CF46 }, { 0x1D167, 0x1D169 }, { 0x1D17B, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, { 0x1D242, 0x1D244 }, { 0x1DA00, 0x1DA36 }, { 0x1DA3B, 0x1DA6C }, { 0x1DA75, 0x1DA75 }, { 0x1DA84, 0x1DA84 }, { 0x1DA9B, 0x1DA9F }, { 0x1DAA1, 0x1DAAF }, { 0x1E000, 0x1E006 }, { 0x1E008, 0x1E018 }, { 0x1E01B, 0x1E021 }, { 0x1E023, 0x1E024 }, { 0x1E026, 0x1E02A }, { 0x1E08F, 0x1E08F }, { 0x1E130, 0x1E136 }, { 0x1E2AE, 0x1E2AE }, { 0x1E2EC, 0x1E2EF }, { 0x1E4EC, 0x1E4EF }, { 0x1E5EE, 0x1E5EF }, { 0x1E8D0, 0x1E8D6 }, { 0x1E944, 0x1E94A }, { 0xE0100, 0xE01EF } }; /* *INDENT-ON* */ /* sorted list of non-overlapping intervals of non-characters */ /* generated by * uniset +0000..DFFF -4e00..9fd5 +F900..10FFFD unknown +2028..2029 c */ /* *INDENT-OFF* */ /* generated by run-uniset_unk 1.6 */ static const struct interval unknowns[] = { { 0x0378, 0x0379 }, { 0x0380, 0x0383 }, { 0x038B, 0x038B }, { 0x038D, 0x038D }, { 0x03A2, 0x03A2 }, { 0x0530, 0x0530 }, { 0x0557, 0x0558 }, { 0x058B, 0x058C }, { 0x0590, 0x0590 }, { 0x05C8, 0x05CF }, { 0x05EB, 0x05EE }, { 0x05F5, 0x05FF }, { 0x070E, 0x070E }, { 0x074B, 0x074C }, { 0x07B2, 0x07BF }, { 0x07FB, 0x07FC }, { 0x082E, 0x082F }, { 0x083F, 0x083F }, { 0x085C, 0x085D }, { 0x085F, 0x085F }, { 0x086B, 0x086F }, { 0x088F, 0x088F }, { 0x0892, 0x0896 }, { 0x0984, 0x0984 }, { 0x098D, 0x098E }, { 0x0991, 0x0992 }, { 0x09A9, 0x09A9 }, { 0x09B1, 0x09B1 }, { 0x09B3, 0x09B5 }, { 0x09BA, 0x09BB }, { 0x09C5, 0x09C6 }, { 0x09C9, 0x09CA }, { 0x09CF, 0x09D6 }, { 0x09D8, 0x09DB }, { 0x09DE, 0x09DE }, { 0x09E4, 0x09E5 }, { 0x09FF, 0x0A00 }, { 0x0A04, 0x0A04 }, { 0x0A0B, 0x0A0E }, { 0x0A11, 0x0A12 }, { 0x0A29, 0x0A29 }, { 0x0A31, 0x0A31 }, { 0x0A34, 0x0A34 }, { 0x0A37, 0x0A37 }, { 0x0A3A, 0x0A3B }, { 0x0A3D, 0x0A3D }, { 0x0A43, 0x0A46 }, { 0x0A49, 0x0A4A }, { 0x0A4E, 0x0A50 }, { 0x0A52, 0x0A58 }, { 0x0A5D, 0x0A5D }, { 0x0A5F, 0x0A65 }, { 0x0A77, 0x0A80 }, { 0x0A84, 0x0A84 }, { 0x0A8E, 0x0A8E }, { 0x0A92, 0x0A92 }, { 0x0AA9, 0x0AA9 }, { 0x0AB1, 0x0AB1 }, { 0x0AB4, 0x0AB4 }, { 0x0ABA, 0x0ABB }, { 0x0AC6, 0x0AC6 }, { 0x0ACA, 0x0ACA }, { 0x0ACE, 0x0ACF }, { 0x0AD1, 0x0ADF }, { 0x0AE4, 0x0AE5 }, { 0x0AF2, 0x0AF8 }, { 0x0B00, 0x0B00 }, { 0x0B04, 0x0B04 }, { 0x0B0D, 0x0B0E }, { 0x0B11, 0x0B12 }, { 0x0B29, 0x0B29 }, { 0x0B31, 0x0B31 }, { 0x0B34, 0x0B34 }, { 0x0B3A, 0x0B3B }, { 0x0B45, 0x0B46 }, { 0x0B49, 0x0B4A }, { 0x0B4E, 0x0B54 }, { 0x0B58, 0x0B5B }, { 0x0B5E, 0x0B5E }, { 0x0B64, 0x0B65 }, { 0x0B78, 0x0B81 }, { 0x0B84, 0x0B84 }, { 0x0B8B, 0x0B8D }, { 0x0B91, 0x0B91 }, { 0x0B96, 0x0B98 }, { 0x0B9B, 0x0B9B }, { 0x0B9D, 0x0B9D }, { 0x0BA0, 0x0BA2 }, { 0x0BA5, 0x0BA7 }, { 0x0BAB, 0x0BAD }, { 0x0BBA, 0x0BBD }, { 0x0BC3, 0x0BC5 }, { 0x0BC9, 0x0BC9 }, { 0x0BCE, 0x0BCF }, { 0x0BD1, 0x0BD6 }, { 0x0BD8, 0x0BE5 }, { 0x0BFB, 0x0BFF }, { 0x0C0D, 0x0C0D }, { 0x0C11, 0x0C11 }, { 0x0C29, 0x0C29 }, { 0x0C3A, 0x0C3B }, { 0x0C45, 0x0C45 }, { 0x0C49, 0x0C49 }, { 0x0C4E, 0x0C54 }, { 0x0C57, 0x0C57 }, { 0x0C5B, 0x0C5C }, { 0x0C5E, 0x0C5F }, { 0x0C64, 0x0C65 }, { 0x0C70, 0x0C76 }, { 0x0C8D, 0x0C8D }, { 0x0C91, 0x0C91 }, { 0x0CA9, 0x0CA9 }, { 0x0CB4, 0x0CB4 }, { 0x0CBA, 0x0CBB }, { 0x0CC5, 0x0CC5 }, { 0x0CC9, 0x0CC9 }, { 0x0CCE, 0x0CD4 }, { 0x0CD7, 0x0CDC }, { 0x0CDF, 0x0CDF }, { 0x0CE4, 0x0CE5 }, { 0x0CF0, 0x0CF0 }, { 0x0CF4, 0x0CFF }, { 0x0D0D, 0x0D0D }, { 0x0D11, 0x0D11 }, { 0x0D45, 0x0D45 }, { 0x0D49, 0x0D49 }, { 0x0D50, 0x0D53 }, { 0x0D64, 0x0D65 }, { 0x0D80, 0x0D80 }, { 0x0D84, 0x0D84 }, { 0x0D97, 0x0D99 }, { 0x0DB2, 0x0DB2 }, { 0x0DBC, 0x0DBC }, { 0x0DBE, 0x0DBF }, { 0x0DC7, 0x0DC9 }, { 0x0DCB, 0x0DCE }, { 0x0DD5, 0x0DD5 }, { 0x0DD7, 0x0DD7 }, { 0x0DE0, 0x0DE5 }, { 0x0DF0, 0x0DF1 }, { 0x0DF5, 0x0E00 }, { 0x0E3B, 0x0E3E }, { 0x0E5C, 0x0E80 }, { 0x0E83, 0x0E83 }, { 0x0E85, 0x0E85 }, { 0x0E8B, 0x0E8B }, { 0x0EA4, 0x0EA4 }, { 0x0EA6, 0x0EA6 }, { 0x0EBE, 0x0EBF }, { 0x0EC5, 0x0EC5 }, { 0x0EC7, 0x0EC7 }, { 0x0ECF, 0x0ECF }, { 0x0EDA, 0x0EDB }, { 0x0EE0, 0x0EFF }, { 0x0F48, 0x0F48 }, { 0x0F6D, 0x0F70 }, { 0x0F98, 0x0F98 }, { 0x0FBD, 0x0FBD }, { 0x0FCD, 0x0FCD }, { 0x0FDB, 0x0FFF }, { 0x10C6, 0x10C6 }, { 0x10C8, 0x10CC }, { 0x10CE, 0x10CF }, { 0x1249, 0x1249 }, { 0x124E, 0x124F }, { 0x1257, 0x1257 }, { 0x1259, 0x1259 }, { 0x125E, 0x125F }, { 0x1289, 0x1289 }, { 0x128E, 0x128F }, { 0x12B1, 0x12B1 }, { 0x12B6, 0x12B7 }, { 0x12BF, 0x12BF }, { 0x12C1, 0x12C1 }, { 0x12C6, 0x12C7 }, { 0x12D7, 0x12D7 }, { 0x1311, 0x1311 }, { 0x1316, 0x1317 }, { 0x135B, 0x135C }, { 0x137D, 0x137F }, { 0x139A, 0x139F }, { 0x13F6, 0x13F7 }, { 0x13FE, 0x13FF }, { 0x169D, 0x169F }, { 0x16F9, 0x16FF }, { 0x1716, 0x171E }, { 0x1737, 0x173F }, { 0x1754, 0x175F }, { 0x176D, 0x176D }, { 0x1771, 0x1771 }, { 0x1774, 0x177F }, { 0x17DE, 0x17DF }, { 0x17EA, 0x17EF }, { 0x17FA, 0x17FF }, { 0x181A, 0x181F }, { 0x1879, 0x187F }, { 0x18AB, 0x18AF }, { 0x18F6, 0x18FF }, { 0x191F, 0x191F }, { 0x192C, 0x192F }, { 0x193C, 0x193F }, { 0x1941, 0x1943 }, { 0x196E, 0x196F }, { 0x1975, 0x197F }, { 0x19AC, 0x19AF }, { 0x19CA, 0x19CF }, { 0x19DB, 0x19DD }, { 0x1A1C, 0x1A1D }, { 0x1A5F, 0x1A5F }, { 0x1A7D, 0x1A7E }, { 0x1A8A, 0x1A8F }, { 0x1A9A, 0x1A9F }, { 0x1AAE, 0x1AAF }, { 0x1ACF, 0x1AFF }, { 0x1B4D, 0x1B4D }, { 0x1BF4, 0x1BFB }, { 0x1C38, 0x1C3A }, { 0x1C4A, 0x1C4C }, { 0x1C8B, 0x1C8F }, { 0x1CBB, 0x1CBC }, { 0x1CC8, 0x1CCF }, { 0x1CFB, 0x1CFF }, { 0x1F16, 0x1F17 }, { 0x1F1E, 0x1F1F }, { 0x1F46, 0x1F47 }, { 0x1F4E, 0x1F4F }, { 0x1F58, 0x1F58 }, { 0x1F5A, 0x1F5A }, { 0x1F5C, 0x1F5C }, { 0x1F5E, 0x1F5E }, { 0x1F7E, 0x1F7F }, { 0x1FB5, 0x1FB5 }, { 0x1FC5, 0x1FC5 }, { 0x1FD4, 0x1FD5 }, { 0x1FDC, 0x1FDC }, { 0x1FF0, 0x1FF1 }, { 0x1FF5, 0x1FF5 }, { 0x1FFF, 0x1FFF }, { 0x2028, 0x2029 }, { 0x2065, 0x2065 }, { 0x2072, 0x2073 }, { 0x208F, 0x208F }, { 0x209D, 0x209F }, { 0x20C1, 0x20CF }, { 0x20F1, 0x20FF }, { 0x218C, 0x218F }, { 0x242A, 0x243F }, { 0x244B, 0x245F }, { 0x2B74, 0x2B75 }, { 0x2B96, 0x2B96 }, { 0x2CF4, 0x2CF8 }, { 0x2D26, 0x2D26 }, { 0x2D28, 0x2D2C }, { 0x2D2E, 0x2D2F }, { 0x2D68, 0x2D6E }, { 0x2D71, 0x2D7E }, { 0x2D97, 0x2D9F }, { 0x2DA7, 0x2DA7 }, { 0x2DAF, 0x2DAF }, { 0x2DB7, 0x2DB7 }, { 0x2DBF, 0x2DBF }, { 0x2DC7, 0x2DC7 }, { 0x2DCF, 0x2DCF }, { 0x2DD7, 0x2DD7 }, { 0x2DDF, 0x2DDF }, { 0x2E5E, 0x2E7F }, { 0x2E9A, 0x2E9A }, { 0x2EF4, 0x2EFF }, { 0x2FD6, 0x2FEF }, { 0x3040, 0x3040 }, { 0x3097, 0x3098 }, { 0x3100, 0x3104 }, { 0x3130, 0x3130 }, { 0x318F, 0x318F }, { 0x31E6, 0x31EE }, { 0x321F, 0x321F }, { 0x4DB6, 0x4DBF }, { 0x9FD6, 0x9FFF }, { 0xA48D, 0xA48F }, { 0xA4C7, 0xA4CF }, { 0xA62C, 0xA63F }, { 0xA6F8, 0xA6FF }, { 0xA7CE, 0xA7CF }, { 0xA7D2, 0xA7D2 }, { 0xA7D4, 0xA7D4 }, { 0xA7DD, 0xA7F1 }, { 0xA82D, 0xA82F }, { 0xA83A, 0xA83F }, { 0xA878, 0xA87F }, { 0xA8C6, 0xA8CD }, { 0xA8DA, 0xA8DF }, { 0xA954, 0xA95E }, { 0xA97D, 0xA97F }, { 0xA9CE, 0xA9CE }, { 0xA9DA, 0xA9DD }, { 0xA9FF, 0xA9FF }, { 0xAA37, 0xAA3F }, { 0xAA4E, 0xAA4F }, { 0xAA5A, 0xAA5B }, { 0xAAC3, 0xAADA }, { 0xAAF7, 0xAB00 }, { 0xAB07, 0xAB08 }, { 0xAB0F, 0xAB10 }, { 0xAB17, 0xAB1F }, { 0xAB27, 0xAB27 }, { 0xAB2F, 0xAB2F }, { 0xAB6C, 0xAB6F }, { 0xABEE, 0xABEF }, { 0xABFA, 0xABFF }, { 0xD7A4, 0xD7AF }, { 0xD7C7, 0xD7CA }, { 0xD7FC, 0xDFFF }, { 0xFA6E, 0xFA6F }, { 0xFADA, 0xFAFF }, { 0xFB07, 0xFB12 }, { 0xFB18, 0xFB1C }, { 0xFB37, 0xFB37 }, { 0xFB3D, 0xFB3D }, { 0xFB3F, 0xFB3F }, { 0xFB42, 0xFB42 }, { 0xFB45, 0xFB45 }, { 0xFBC3, 0xFBD2 }, { 0xFD90, 0xFD91 }, { 0xFDC8, 0xFDCE }, { 0xFDD0, 0xFDEF }, { 0xFE1A, 0xFE1F }, { 0xFE53, 0xFE53 }, { 0xFE67, 0xFE67 }, { 0xFE6C, 0xFE6F }, { 0xFE75, 0xFE75 }, { 0xFEFD, 0xFEFE }, { 0xFF00, 0xFF00 }, { 0xFFBF, 0xFFC1 }, { 0xFFC8, 0xFFC9 }, { 0xFFD0, 0xFFD1 }, { 0xFFD8, 0xFFD9 }, { 0xFFDD, 0xFFDF }, { 0xFFE7, 0xFFE7 }, { 0xFFEF, 0xFFF8 }, { 0xFFFE, 0xFFFF }, { 0x1000C, 0x1000C }, { 0x10027, 0x10027 }, { 0x1003B, 0x1003B }, { 0x1003E, 0x1003E }, { 0x1004E, 0x1004F }, { 0x1005E, 0x1007F }, { 0x100FB, 0x100FF }, { 0x10103, 0x10106 }, { 0x10134, 0x10136 }, { 0x1018F, 0x1018F }, { 0x1019D, 0x1019F }, { 0x101A1, 0x101CF }, { 0x101FE, 0x1027F }, { 0x1029D, 0x1029F }, { 0x102D1, 0x102DF }, { 0x102FC, 0x102FF }, { 0x10324, 0x1032C }, { 0x1034B, 0x1034F }, { 0x1037B, 0x1037F }, { 0x1039E, 0x1039E }, { 0x103C4, 0x103C7 }, { 0x103D6, 0x103FF }, { 0x1049E, 0x1049F }, { 0x104AA, 0x104AF }, { 0x104D4, 0x104D7 }, { 0x104FC, 0x104FF }, { 0x10528, 0x1052F }, { 0x10564, 0x1056E }, { 0x1057B, 0x1057B }, { 0x1058B, 0x1058B }, { 0x10593, 0x10593 }, { 0x10596, 0x10596 }, { 0x105A2, 0x105A2 }, { 0x105B2, 0x105B2 }, { 0x105BA, 0x105BA }, { 0x105BD, 0x105BF }, { 0x105F4, 0x105FF }, { 0x10737, 0x1073F }, { 0x10756, 0x1075F }, { 0x10768, 0x1077F }, { 0x10786, 0x10786 }, { 0x107B1, 0x107B1 }, { 0x107BB, 0x107FF }, { 0x10806, 0x10807 }, { 0x10809, 0x10809 }, { 0x10836, 0x10836 }, { 0x10839, 0x1083B }, { 0x1083D, 0x1083E }, { 0x10856, 0x10856 }, { 0x1089F, 0x108A6 }, { 0x108B0, 0x108DF }, { 0x108F3, 0x108F3 }, { 0x108F6, 0x108FA }, { 0x1091C, 0x1091E }, { 0x1093A, 0x1093E }, { 0x10940, 0x1097F }, { 0x109B8, 0x109BB }, { 0x109D0, 0x109D1 }, { 0x10A04, 0x10A04 }, { 0x10A07, 0x10A0B }, { 0x10A14, 0x10A14 }, { 0x10A18, 0x10A18 }, { 0x10A36, 0x10A37 }, { 0x10A3B, 0x10A3E }, { 0x10A49, 0x10A4F }, { 0x10A59, 0x10A5F }, { 0x10AA0, 0x10ABF }, { 0x10AE7, 0x10AEA }, { 0x10AF7, 0x10AFF }, { 0x10B36, 0x10B38 }, { 0x10B56, 0x10B57 }, { 0x10B73, 0x10B77 }, { 0x10B92, 0x10B98 }, { 0x10B9D, 0x10BA8 }, { 0x10BB0, 0x10BFF }, { 0x10C49, 0x10C7F }, { 0x10CB3, 0x10CBF }, { 0x10CF3, 0x10CF9 }, { 0x10D28, 0x10D2F }, { 0x10D3A, 0x10D3F }, { 0x10D66, 0x10D68 }, { 0x10D86, 0x10D8D }, { 0x10D90, 0x10E5F }, { 0x10E7F, 0x10E7F }, { 0x10EAA, 0x10EAA }, { 0x10EAE, 0x10EAF }, { 0x10EB2, 0x10EC1 }, { 0x10EC5, 0x10EFB }, { 0x10F28, 0x10F2F }, { 0x10F5A, 0x10F6F }, { 0x10F8A, 0x10FAF }, { 0x10FCC, 0x10FDF }, { 0x10FF7, 0x10FFF }, { 0x1104E, 0x11051 }, { 0x11076, 0x1107E }, { 0x110C3, 0x110CC }, { 0x110CE, 0x110CF }, { 0x110E9, 0x110EF }, { 0x110FA, 0x110FF }, { 0x11135, 0x11135 }, { 0x11148, 0x1114F }, { 0x11177, 0x1117F }, { 0x111E0, 0x111E0 }, { 0x111F5, 0x111FF }, { 0x11212, 0x11212 }, { 0x11242, 0x1127F }, { 0x11287, 0x11287 }, { 0x11289, 0x11289 }, { 0x1128E, 0x1128E }, { 0x1129E, 0x1129E }, { 0x112AA, 0x112AF }, { 0x112EB, 0x112EF }, { 0x112FA, 0x112FF }, { 0x11304, 0x11304 }, { 0x1130D, 0x1130E }, { 0x11311, 0x11312 }, { 0x11329, 0x11329 }, { 0x11331, 0x11331 }, { 0x11334, 0x11334 }, { 0x1133A, 0x1133A }, { 0x11345, 0x11346 }, { 0x11349, 0x1134A }, { 0x1134E, 0x1134F }, { 0x11351, 0x11356 }, { 0x11358, 0x1135C }, { 0x11364, 0x11365 }, { 0x1136D, 0x1136F }, { 0x11375, 0x1137F }, { 0x1138A, 0x1138A }, { 0x1138C, 0x1138D }, { 0x1138F, 0x1138F }, { 0x113B6, 0x113B6 }, { 0x113C1, 0x113C1 }, { 0x113C3, 0x113C4 }, { 0x113C6, 0x113C6 }, { 0x113CB, 0x113CB }, { 0x113D6, 0x113D6 }, { 0x113D9, 0x113E0 }, { 0x113E3, 0x113FF }, { 0x1145C, 0x1145C }, { 0x11462, 0x1147F }, { 0x114C8, 0x114CF }, { 0x114DA, 0x1157F }, { 0x115B6, 0x115B7 }, { 0x115DE, 0x115FF }, { 0x11645, 0x1164F }, { 0x1165A, 0x1165F }, { 0x1166D, 0x1167F }, { 0x116BA, 0x116BF }, { 0x116CA, 0x116CF }, { 0x116E4, 0x116FF }, { 0x1171B, 0x1171C }, { 0x1172C, 0x1172F }, { 0x11747, 0x117FF }, { 0x1183C, 0x1189F }, { 0x118F3, 0x118FE }, { 0x11907, 0x11908 }, { 0x1190A, 0x1190B }, { 0x11914, 0x11914 }, { 0x11917, 0x11917 }, { 0x11936, 0x11936 }, { 0x11939, 0x1193A }, { 0x11947, 0x1194F }, { 0x1195A, 0x1199F }, { 0x119A8, 0x119A9 }, { 0x119D8, 0x119D9 }, { 0x119E5, 0x119FF }, { 0x11A48, 0x11A4F }, { 0x11AA3, 0x11AAF }, { 0x11AF9, 0x11AFF }, { 0x11B0A, 0x11BBF }, { 0x11BE2, 0x11BEF }, { 0x11BFA, 0x11BFF }, { 0x11C09, 0x11C09 }, { 0x11C37, 0x11C37 }, { 0x11C46, 0x11C4F }, { 0x11C6D, 0x11C6F }, { 0x11C90, 0x11C91 }, { 0x11CA8, 0x11CA8 }, { 0x11CB7, 0x11CFF }, { 0x11D07, 0x11D07 }, { 0x11D0A, 0x11D0A }, { 0x11D37, 0x11D39 }, { 0x11D3B, 0x11D3B }, { 0x11D3E, 0x11D3E }, { 0x11D48, 0x11D4F }, { 0x11D5A, 0x11D5F }, { 0x11D66, 0x11D66 }, { 0x11D69, 0x11D69 }, { 0x11D8F, 0x11D8F }, { 0x11D92, 0x11D92 }, { 0x11D99, 0x11D9F }, { 0x11DAA, 0x11EDF }, { 0x11EF9, 0x11EFF }, { 0x11F11, 0x11F11 }, { 0x11F3B, 0x11F3D }, { 0x11F5B, 0x11FAF }, { 0x11FB1, 0x11FBF }, { 0x11FF2, 0x11FFE }, { 0x1239A, 0x123FF }, { 0x1246F, 0x1246F }, { 0x12475, 0x1247F }, { 0x12544, 0x12F8F }, { 0x12FF3, 0x12FFF }, { 0x13456, 0x1345F }, { 0x143FB, 0x143FF }, { 0x14647, 0x160FF }, { 0x1613A, 0x167FF }, { 0x16A39, 0x16A3F }, { 0x16A5F, 0x16A5F }, { 0x16A6A, 0x16A6D }, { 0x16ABF, 0x16ABF }, { 0x16ACA, 0x16ACF }, { 0x16AEE, 0x16AEF }, { 0x16AF6, 0x16AFF }, { 0x16B46, 0x16B4F }, { 0x16B5A, 0x16B5A }, { 0x16B62, 0x16B62 }, { 0x16B78, 0x16B7C }, { 0x16B90, 0x16D3F }, { 0x16D7A, 0x16E3F }, { 0x16E9B, 0x16EFF }, { 0x16F4B, 0x16F4E }, { 0x16F88, 0x16F8E }, { 0x16FA0, 0x16FDF }, { 0x16FE5, 0x16FEF }, { 0x16FF2, 0x187FF }, { 0x18CD6, 0x18CFE }, { 0x18D00, 0x1AFEF }, { 0x1AFF4, 0x1AFF4 }, { 0x1AFFC, 0x1AFFC }, { 0x1AFFF, 0x1AFFF }, { 0x1B123, 0x1B131 }, { 0x1B133, 0x1B14F }, { 0x1B153, 0x1B154 }, { 0x1B156, 0x1B163 }, { 0x1B168, 0x1B16F }, { 0x1B2FC, 0x1BBFF }, { 0x1BC6B, 0x1BC6F }, { 0x1BC7D, 0x1BC7F }, { 0x1BC89, 0x1BC8F }, { 0x1BC9A, 0x1BC9B }, { 0x1BCA4, 0x1CBFF }, { 0x1CCFA, 0x1CCFF }, { 0x1CEB4, 0x1CEFF }, { 0x1CF2E, 0x1CF2F }, { 0x1CF47, 0x1CF4F }, { 0x1CFC4, 0x1CFFF }, { 0x1D0F6, 0x1D0FF }, { 0x1D127, 0x1D128 }, { 0x1D1EB, 0x1D1FF }, { 0x1D246, 0x1D2BF }, { 0x1D2D4, 0x1D2DF }, { 0x1D2F4, 0x1D2FF }, { 0x1D357, 0x1D35F }, { 0x1D379, 0x1D3FF }, { 0x1D455, 0x1D455 }, { 0x1D49D, 0x1D49D }, { 0x1D4A0, 0x1D4A1 }, { 0x1D4A3, 0x1D4A4 }, { 0x1D4A7, 0x1D4A8 }, { 0x1D4AD, 0x1D4AD }, { 0x1D4BA, 0x1D4BA }, { 0x1D4BC, 0x1D4BC }, { 0x1D4C4, 0x1D4C4 }, { 0x1D506, 0x1D506 }, { 0x1D50B, 0x1D50C }, { 0x1D515, 0x1D515 }, { 0x1D51D, 0x1D51D }, { 0x1D53A, 0x1D53A }, { 0x1D53F, 0x1D53F }, { 0x1D545, 0x1D545 }, { 0x1D547, 0x1D549 }, { 0x1D551, 0x1D551 }, { 0x1D6A6, 0x1D6A7 }, { 0x1D7CC, 0x1D7CD }, { 0x1DA8C, 0x1DA9A }, { 0x1DAA0, 0x1DAA0 }, { 0x1DAB0, 0x1DEFF }, { 0x1DF1F, 0x1DF24 }, { 0x1DF2B, 0x1DFFF }, { 0x1E007, 0x1E007 }, { 0x1E019, 0x1E01A }, { 0x1E022, 0x1E022 }, { 0x1E025, 0x1E025 }, { 0x1E02B, 0x1E02F }, { 0x1E06E, 0x1E08E }, { 0x1E090, 0x1E0FF }, { 0x1E12D, 0x1E12F }, { 0x1E13E, 0x1E13F }, { 0x1E14A, 0x1E14D }, { 0x1E150, 0x1E28F }, { 0x1E2AF, 0x1E2BF }, { 0x1E2FA, 0x1E2FE }, { 0x1E300, 0x1E4CF }, { 0x1E4FA, 0x1E5CF }, { 0x1E5FB, 0x1E5FE }, { 0x1E600, 0x1E7DF }, { 0x1E7E7, 0x1E7E7 }, { 0x1E7EC, 0x1E7EC }, { 0x1E7EF, 0x1E7EF }, { 0x1E7FF, 0x1E7FF }, { 0x1E8C5, 0x1E8C6 }, { 0x1E8D7, 0x1E8FF }, { 0x1E94C, 0x1E94F }, { 0x1E95A, 0x1E95D }, { 0x1E960, 0x1EC70 }, { 0x1ECB5, 0x1ED00 }, { 0x1ED3E, 0x1EDFF }, { 0x1EE04, 0x1EE04 }, { 0x1EE20, 0x1EE20 }, { 0x1EE23, 0x1EE23 }, { 0x1EE25, 0x1EE26 }, { 0x1EE28, 0x1EE28 }, { 0x1EE33, 0x1EE33 }, { 0x1EE38, 0x1EE38 }, { 0x1EE3A, 0x1EE3A }, { 0x1EE3C, 0x1EE41 }, { 0x1EE43, 0x1EE46 }, { 0x1EE48, 0x1EE48 }, { 0x1EE4A, 0x1EE4A }, { 0x1EE4C, 0x1EE4C }, { 0x1EE50, 0x1EE50 }, { 0x1EE53, 0x1EE53 }, { 0x1EE55, 0x1EE56 }, { 0x1EE58, 0x1EE58 }, { 0x1EE5A, 0x1EE5A }, { 0x1EE5C, 0x1EE5C }, { 0x1EE5E, 0x1EE5E }, { 0x1EE60, 0x1EE60 }, { 0x1EE63, 0x1EE63 }, { 0x1EE65, 0x1EE66 }, { 0x1EE6B, 0x1EE6B }, { 0x1EE73, 0x1EE73 }, { 0x1EE78, 0x1EE78 }, { 0x1EE7D, 0x1EE7D }, { 0x1EE7F, 0x1EE7F }, { 0x1EE8A, 0x1EE8A }, { 0x1EE9C, 0x1EEA0 }, { 0x1EEA4, 0x1EEA4 }, { 0x1EEAA, 0x1EEAA }, { 0x1EEBC, 0x1EEEF }, { 0x1EEF2, 0x1EFFF }, { 0x1F02C, 0x1F02F }, { 0x1F094, 0x1F09F }, { 0x1F0AF, 0x1F0B0 }, { 0x1F0C0, 0x1F0C0 }, { 0x1F0D0, 0x1F0D0 }, { 0x1F0F6, 0x1F0FF }, { 0x1F1AE, 0x1F1E5 }, { 0x1F203, 0x1F20F }, { 0x1F23C, 0x1F23F }, { 0x1F249, 0x1F24F }, { 0x1F252, 0x1F25F }, { 0x1F266, 0x1F2FF }, { 0x1F6D8, 0x1F6DB }, { 0x1F6ED, 0x1F6EF }, { 0x1F6FD, 0x1F6FF }, { 0x1F777, 0x1F77A }, { 0x1F7DA, 0x1F7DF }, { 0x1F7EC, 0x1F7EF }, { 0x1F7F1, 0x1F7FF }, { 0x1F80C, 0x1F80F }, { 0x1F848, 0x1F84F }, { 0x1F85A, 0x1F85F }, { 0x1F888, 0x1F88F }, { 0x1F8AE, 0x1F8AF }, { 0x1F8BC, 0x1F8BF }, { 0x1F8C2, 0x1F8FF }, { 0x1FA54, 0x1FA5F }, { 0x1FA6E, 0x1FA6F }, { 0x1FA7D, 0x1FA7F }, { 0x1FA8A, 0x1FA8E }, { 0x1FAC7, 0x1FACD }, { 0x1FADD, 0x1FADE }, { 0x1FAEA, 0x1FAEF }, { 0x1FAF9, 0x1FAFF }, { 0x1FB93, 0x1FB93 }, { 0x1FBFA, 0x1FFFF }, { 0x2A6D7, 0x2F7FF }, { 0x2FA1E, 0xE0000 }, { 0xE0002, 0xE001F }, { 0xE0080, 0xE00FF }, { 0xE01F0, 0x10FFFD } }; /* *INDENT-ON* */ /* sorted list of non-overlapping intervals of non-characters */ /* generated by * uniset +WIDTH-W -cat=Cn -cat=Mn c */ /* *INDENT-OFF* */ /* generated by run-uniset_dbl 1.2 */ static const struct interval doublewidth[] = { { 0x1100, 0x115F }, { 0x231A, 0x231B }, { 0x2329, 0x232A }, { 0x23E9, 0x23EC }, { 0x23F0, 0x23F0 }, { 0x23F3, 0x23F3 }, { 0x25FD, 0x25FE }, { 0x2614, 0x2615 }, { 0x2630, 0x2637 }, { 0x2648, 0x2653 }, { 0x267F, 0x267F }, { 0x268A, 0x268F }, { 0x2693, 0x2693 }, { 0x26A1, 0x26A1 }, { 0x26AA, 0x26AB }, { 0x26BD, 0x26BE }, { 0x26C4, 0x26C5 }, { 0x26CE, 0x26CE }, { 0x26D4, 0x26D4 }, { 0x26EA, 0x26EA }, { 0x26F2, 0x26F3 }, { 0x26F5, 0x26F5 }, { 0x26FA, 0x26FA }, { 0x26FD, 0x26FD }, { 0x2705, 0x2705 }, { 0x270A, 0x270B }, { 0x2728, 0x2728 }, { 0x274C, 0x274C }, { 0x274E, 0x274E }, { 0x2753, 0x2755 }, { 0x2757, 0x2757 }, { 0x2795, 0x2797 }, { 0x27B0, 0x27B0 }, { 0x27BF, 0x27BF }, { 0x2B1B, 0x2B1C }, { 0x2B50, 0x2B50 }, { 0x2B55, 0x2B55 }, { 0x2E80, 0x2E99 }, { 0x2E9B, 0x2EF3 }, { 0x2F00, 0x2FD5 }, { 0x2FF0, 0x3029 }, { 0x302E, 0x303E }, { 0x3041, 0x3096 }, { 0x309B, 0x30FF }, { 0x3105, 0x312F }, { 0x3131, 0x318E }, { 0x3190, 0x31E5 }, { 0x31EF, 0x321E }, { 0x3220, 0x3247 }, { 0x3250, 0xA48C }, { 0xA490, 0xA4C6 }, { 0xA960, 0xA97C }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFA6D }, { 0xFA70, 0xFAD9 }, { 0xFE10, 0xFE19 }, { 0xFE30, 0xFE52 }, { 0xFE54, 0xFE66 }, { 0xFE68, 0xFE6B }, { 0xFF01, 0xFF60 }, { 0xFFE0, 0xFFE6 }, { 0x16FE0, 0x16FE3 }, { 0x16FF0, 0x16FF1 }, { 0x17000, 0x187F7 }, { 0x18800, 0x18CD5 }, { 0x18CFF, 0x18D08 }, { 0x1AFF0, 0x1AFF3 }, { 0x1AFF5, 0x1AFFB }, { 0x1AFFD, 0x1AFFE }, { 0x1B000, 0x1B122 }, { 0x1B132, 0x1B132 }, { 0x1B150, 0x1B152 }, { 0x1B155, 0x1B155 }, { 0x1B164, 0x1B167 }, { 0x1B170, 0x1B2FB }, { 0x1D300, 0x1D356 }, { 0x1D360, 0x1D376 }, { 0x1F004, 0x1F004 }, { 0x1F0CF, 0x1F0CF }, { 0x1F18E, 0x1F18E }, { 0x1F191, 0x1F19A }, { 0x1F200, 0x1F202 }, { 0x1F210, 0x1F23B }, { 0x1F240, 0x1F248 }, { 0x1F250, 0x1F251 }, { 0x1F260, 0x1F265 }, { 0x1F300, 0x1F320 }, { 0x1F32D, 0x1F335 }, { 0x1F337, 0x1F37C }, { 0x1F37E, 0x1F393 }, { 0x1F3A0, 0x1F3CA }, { 0x1F3CF, 0x1F3D3 }, { 0x1F3E0, 0x1F3F0 }, { 0x1F3F4, 0x1F3F4 }, { 0x1F3F8, 0x1F43E }, { 0x1F440, 0x1F440 }, { 0x1F442, 0x1F4FC }, { 0x1F4FF, 0x1F53D }, { 0x1F54B, 0x1F54E }, { 0x1F550, 0x1F567 }, { 0x1F57A, 0x1F57A }, { 0x1F595, 0x1F596 }, { 0x1F5A4, 0x1F5A4 }, { 0x1F5FB, 0x1F64F }, { 0x1F680, 0x1F6C5 }, { 0x1F6CC, 0x1F6CC }, { 0x1F6D0, 0x1F6D2 }, { 0x1F6D5, 0x1F6D7 }, { 0x1F6DC, 0x1F6DF }, { 0x1F6EB, 0x1F6EC }, { 0x1F6F4, 0x1F6FC }, { 0x1F7E0, 0x1F7EB }, { 0x1F7F0, 0x1F7F0 }, { 0x1F90C, 0x1F93A }, { 0x1F93C, 0x1F945 }, { 0x1F947, 0x1F9FF }, { 0x1FA70, 0x1FA7C }, { 0x1FA80, 0x1FA89 }, { 0x1FA8F, 0x1FAC6 }, { 0x1FACE, 0x1FADC }, { 0x1FADF, 0x1FAE9 }, { 0x1FAF0, 0x1FAF8 }, { 0x20000, 0x2A6DF }, { 0x2A700, 0x2B739 }, { 0x2B740, 0x2B81D }, { 0x2B820, 0x2CEA1 }, { 0x2CEB0, 0x2EBE0 }, { 0x2EBF0, 0x2EE5D }, { 0x2F800, 0x2FA1D }, { 0x30000, 0x3134A }, { 0x31350, 0x323AF } }; /* *INDENT-ON* */ int result; #define Lookup(cmp, table) \ bisearch(cmp, table, \ (int) (sizeof(table) / sizeof(struct interval) - 1)) /* test for 8-bit control characters */ if (cmp == 0) { result = 0; } else if (cmp < 32 || (cmp >= 0x7f && cmp < 0xa0)) { result = -1; } else if (cmp == 0xad) { result = use_latin1; } else if (Lookup(cmp, formatting)) { /* treat formatting characters like control characters */ result = 0; } else if (Lookup(cmp, combining)) { /* binary search in table of non-spacing characters */ result = 0; } else { /* if we arrive here, cmp is not a combining or C0/C1 control character */ result = 1; if (Lookup(cmp, doublewidth)) { result = 2; } else if (cmp >= 0xd800 && cmp <= 0xdfff) { #ifdef HAVE_WCWIDTH result = (wcwidth)(ucs); #else result = -1; #endif } else if (cmp >= unknowns[0].first && Lookup(cmp, unknowns)) { result = -1; } } return result; } #ifdef UNUSED int mk_wcswidth(const wchar_t *pwcs, size_t n) { int width = 0; for (; *pwcs && n-- > 0; pwcs++) { int w; if ((w = mk_wcwidth(*pwcs)) < 0) return -1; else width += w; } return width; } #endif /* UNUSED */ /* * The following functions are the same as mk_wcwidth() and * mk_wcwidth_cjk(), except that spacing characters in the East Asian * Ambiguous (A) category as defined in Unicode Technical Report #11 * have a column width of 2. This variant might be useful for users of * CJK legacy encodings who want to migrate to UCS without changing * the traditional terminal character-width behaviour. It is not * otherwise recommended for general use. */ int mk_wcwidth_cjk(wchar_t ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters, generated by * * uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf \ * +E000..F8FF \ * +F0000..FFFFD \ * +100000..10FFFD c * * "WIDTH-A" is a file extracted from EastAsianWidth.txt by selecting * only those with width "A", and omitting: * * 0xAD * all lines with "COMBINING" */ /* *INDENT-OFF* */ /* generated by run-uniset_cjk 1.5 */ static const struct interval ambiguous[] = { { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 }, { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 }, { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 }, { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 }, { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED }, { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA }, { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 }, { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B }, { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 }, { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 }, { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 }, { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE }, { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 }, { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA }, { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 }, { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 }, { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 }, { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 }, { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 }, { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 }, { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 }, { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 }, { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC }, { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 }, { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 }, { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 }, { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 }, { 0x2189, 0x2189 }, { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 }, { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 }, { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B }, { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 }, { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 }, { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E }, { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 }, { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 }, { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B }, { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 }, { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 }, { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F }, { 0x269E, 0x269F }, { 0x26BF, 0x26BF }, { 0x26C6, 0x26CD }, { 0x26CF, 0x26D3 }, { 0x26D5, 0x26E1 }, { 0x26E3, 0x26E3 }, { 0x26E8, 0x26E9 }, { 0x26EB, 0x26F1 }, { 0x26F4, 0x26F4 }, { 0x26F6, 0x26F9 }, { 0x26FB, 0x26FC }, { 0x26FE, 0x26FF }, { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0x2B56, 0x2B59 }, { 0x3248, 0x324F }, { 0xE000, 0xF8FF }, { 0xFFFD, 0xFFFD }, { 0x1F100, 0x1F10A }, { 0x1F110, 0x1F12D }, { 0x1F130, 0x1F169 }, { 0x1F170, 0x1F18D }, { 0x1F18F, 0x1F190 }, { 0x1F19B, 0x1F1AC }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD } }; /* *INDENT-ON* */ /* binary search in table of non-spacing characters */ if (Lookup((unsigned long) ucs, ambiguous)) return 2; return mk_wcwidth(ucs); } #ifdef UNUSED int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n) { int width = 0; for (; *pwcs && n-- > 0; pwcs++) { int w; if ((w = mk_wcwidth_cjk(*pwcs)) < 0) return -1; else width += w; } return width; } #endif /* UNUSED */ #ifdef TEST_DRIVER static int opt_all = 0; static int opt_quiet = 0; static int opt_wider = 0; static long total_test = 0; static long total_errs = 0; static void usage(void) { static const char *msg[] = { "Usage: test_wcwidth [options] [c1[-c1b] [c2-[c2b] [...]]]", "", "Options:", " -a show all data, rather than just differences", " -s show only summary", " -w use width-characters for ambiguous-width" }; size_t n; for (n = 0; n < sizeof(msg) / sizeof(msg[0]); ++n) { fprintf(stderr, "%s\n", msg[n]); } exit(EXIT_FAILURE); } static int decode_one(const char *source, char **target) { int result = -1; long check; int radix = 0; if ((source[0] == 'u' || source[0] == 'U') && source[1] == '+') { source += 2; radix = 16; } check = strtol(source, target, radix); if (*target != NULL && *target != source) result = (int) check; return result; } static int decode_range(const char *source, int *lo, int *hi) { int result = 0; char *after1; char *after2; if ((*lo = decode_one(source, &after1)) >= 0) { after1 += strspn(after1, ":-.\t "); if ((*hi = decode_one(after1, &after2)) < 0) { *hi = *lo; } result = 1; } return result; } static void do_range(const char *source) { int lo, hi; if (decode_range(source, &lo, &hi)) { while (lo <= hi) { wchar_t wlo = (wchar_t) lo; int local_rc = opt_wider ? mk_wcwidth_cjk(wlo) : mk_wcwidth(wlo); int other_rc = wcwidth(wlo); ++total_test; if (opt_all || (local_rc != other_rc)) { if (!opt_quiet) printf("U+%04X\t%d\t%d\n", lo, local_rc, other_rc); } if (local_rc != other_rc) { ++total_errs; } ++lo; } } } int main(int argc, char **argv) { int ch; setlocale(LC_ALL, ""); while ((ch = getopt(argc, argv, "asw")) != -1) { switch (ch) { case 'a': opt_all = 1; break; case 's': opt_quiet = 1; break; case 'w': opt_wider = 1; break; default: usage(); } } if (optind >= argc) usage(); while (optind < argc) { do_range(argv[optind++]); } if (total_test) { printf("%ld/%ld mismatches (%.0f%%)\n", total_errs, total_test, (100.0 * (double) total_errs) / (double) total_test); } return EXIT_SUCCESS; } #endif xterm-399/88colres.pl0000755000000000000000000000610110632366343013250 0ustar rootroot#!/usr/bin/perl # $XTermId: 88colres.pl,v 1.17 2007/06/08 23:57:23 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 1999-2005,2007 by Thomas E. Dickey # Copyright 1999-2000 by Steve Wall # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Made from 256colres.pl # Construct a header file defining default resources for the # 88-color model of xterm. # use the resources for colors 0-15 - usually more-or-less a # reproduction of the standard ANSI colors, but possibly more # pleasing shades use strict; our ( $line1, $line2, $line3 ); our ( $red, $green, $blue, $gray ); our ( $level, $code, @steps ); print < 0 ) { $level += 23.18181818; } $code = 80 + $gray; printf($line1, $code); printf($line2, $code); printf($line3, int($level), int($level), int($level)); } print < #endif /* ptyx.h */ /* *INDENT-OFF* */ /* @(#)ptyx.h X10/6.6 11/10/86 */ #include #include /* for XtNdieCallback, etc. */ #include /* for standard resource names */ #include /* For Max() and Min(). */ #include #undef bcopy #undef bzero #include #include #include #ifdef XRENDERFONT #include #endif #include #include #if defined(HAVE_STDINT_H) || !defined(HAVE_CONFIG_H) #include #define DECONST(type,s) ((type *)(intptr_t)(const type *)(s)) #else #define DECONST(type,s) ((type *)(s)) #endif /* adapted from IntrinsicI.h */ #define MyStackAlloc(size, stack_cache_array) \ ((size) <= sizeof(stack_cache_array) \ ? (stack_cache_array) \ : (char*)malloc((size_t)(size))) #define MyStackFree(pointer, stack_cache_array) \ if ((pointer) != ((char *)(stack_cache_array))) free(pointer) /* adapted from vile (vi-like-emacs) */ #define TypeCallocN(type,n) (type *)calloc((size_t) (n), sizeof(type)) #define TypeCalloc(type) TypeCallocN(type, 1) #define TypeMallocN(type,n) (type *)malloc(sizeof(type) * (size_t) (n)) #define TypeMalloc(type) TypeMallocN(type, 1) #define TypeRealloc(type,n,p) (type *)realloc(p, (n) * sizeof(type)) #define TypeXtReallocN(t,p,n) (t *)(void *)XtRealloc((char *)(p), (Cardinal)(sizeof(t) * (size_t) (n))) #define TypeXtMallocX(type,n) (type *)(void *)XtMalloc((Cardinal)(sizeof(type) + (size_t) (n))) #define TypeXtMallocN(type,n) (type *)(void *)XtMalloc((Cardinal)(sizeof(type) * (size_t) (n))) #define TypeXtMalloc(type) TypeXtMallocN(type, 1) #define CastMalloc(type) (type *)malloc(sizeof(type)) #define BumpBuffer(type, buffer, size, want) \ if (want >= size) { \ size = 1 + (want * 2); \ buffer = TypeRealloc(type, size, buffer); \ } #define BfBuf(type) screen->bf_buf_##type #define BfLen(type) screen->bf_len_##type #define TypedBuffer(type) \ type *bf_buf_##type; \ Cardinal bf_len_##type #define BumpTypedBuffer(type, want) \ BumpBuffer(type, BfBuf(type), BfLen(type), want) #define FreeTypedBuffer(type) \ do { \ FreeAndNull(BfBuf(type)); \ BfLen(type) = 0; \ } while (0) #define FreeAndNull(value) \ do { \ free((void *)(value)); \ value = NULL; \ } while (0) /* ** System V definitions */ #ifdef att #define ATT #endif #ifdef SVR4 #undef SYSV /* predefined on Solaris 2.4 */ #define SYSV /* SVR4 is (approx) superset of SVR3 */ #define ATT #endif #ifdef SYSV #ifdef X_NOT_POSIX #if !defined(CRAY) && !defined(SVR4) #define dup2(fd1,fd2) ((fd1 == fd2) ? fd1 : \ (close(fd2), fcntl(fd1, F_DUPFD, fd2))) #endif #endif #endif /* SYSV */ /* * Newer versions of have a version number. We use certain * features from that. */ #if defined(XRENDERFONT) && defined(XFT_VERSION) && XFT_VERSION >= 20100 #define HAVE_TYPE_FCCHAR32 1 /* compatible: XftChar16 */ #define HAVE_TYPE_XFTCHARSPEC 1 /* new type XftCharSpec */ #endif /* ** Definitions to simplify ifdef's for pty's. */ #define USE_PTY_DEVICE 1 #define USE_PTY_SEARCH 1 #if defined(__osf__) || (defined(linux) && defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) #undef USE_PTY_DEVICE #undef USE_PTY_SEARCH #define USE_PTS_DEVICE 1 #elif defined(PUCC_PTYD) #undef USE_PTY_SEARCH #elif (defined(sun) && defined(SVR4)) || defined(_ALL_SOURCE) || defined(__CYGWIN__) #undef USE_PTY_SEARCH #elif defined(__OpenBSD__) #undef USE_PTY_SEARCH #undef USE_PTY_DEVICE #endif #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))) #define USE_HANDSHAKE 0 /* "recent" Linux systems do not require handshaking */ #endif #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))) #define USE_USG_PTYS #elif (defined(ATT) && !defined(__sgi)) || (defined(SYSV) && defined(i386)) #define USE_USG_PTYS #endif /* * More systems than not require pty-handshaking. */ #ifndef USE_HANDSHAKE #define USE_HANDSHAKE 1 #endif /* ** allow for mobility of the pty master/slave directories */ #ifndef PTYDEV #if defined(__hpux) #define PTYDEV "/dev/ptym/ptyxx" #else #define PTYDEV "/dev/ptyxx" #endif #endif /* !PTYDEV */ #ifndef TTYDEV #if defined(__hpux) #define TTYDEV "/dev/pty/ttyxx" #elif defined(USE_PTS_DEVICE) #define TTYDEV "/dev/pts/0" #else #define TTYDEV "/dev/ttyxx" #endif #endif /* !TTYDEV */ #ifndef PTYCHAR1 #ifdef __hpux #define PTYCHAR1 "zyxwvutsrqp" #else /* !__hpux */ #define PTYCHAR1 "pqrstuvwxyzPQRSTUVWXYZ" #endif /* !__hpux */ #endif /* !PTYCHAR1 */ #ifndef PTYCHAR2 #ifdef __hpux #define PTYCHAR2 "fedcba9876543210" #else /* !__hpux */ #if defined(__DragonFly__) || defined(__FreeBSD__) #define PTYCHAR2 "0123456789abcdefghijklmnopqrstuv" #else /* !__FreeBSD__ */ #define PTYCHAR2 "0123456789abcdef" #endif /* !__FreeBSD__ */ #endif /* !__hpux */ #endif /* !PTYCHAR2 */ #ifndef TTYFORMAT #if defined(CRAY) #define TTYFORMAT "/dev/ttyp%03d" #else #define TTYFORMAT "/dev/ttyp%d" #endif #endif /* TTYFORMAT */ #ifndef PTYFORMAT #ifdef CRAY #define PTYFORMAT "/dev/pty/%03d" #else #define PTYFORMAT "/dev/ptyp%d" #endif #endif /* PTYFORMAT */ #ifndef PTYCHARLEN #ifdef CRAY #define PTYCHARLEN 3 #else #define PTYCHARLEN 2 #endif #endif #ifndef MAXPTTYS #ifdef CRAY #define MAXPTTYS 256 #else #define MAXPTTYS 2048 #endif #endif /* Until the translation manager comes along, I have to do my own translation of * mouse events into the proper routines. */ typedef enum { NORMAL = 0 , LEFTEXTENSION , RIGHTEXTENSION } EventMode; /* * The origin of a screen is 0, 0. Therefore, the number of rows * on a screen is screen->max_row + 1, and similarly for columns. */ #define MaxCols(screen) ((screen)->max_col + 1) #define MaxRows(screen) ((screen)->max_row + 1) #define MaxUChar 255 typedef unsigned char Char; /* to support 8 bit chars */ typedef Char *ScrnPtr; typedef ScrnPtr *ScrnBuf; /* * Declare an X String, but for unsigned chars. */ #ifdef _CONST_X_STRING typedef const Char *UString; #else typedef Char *UString; #endif #define IsEmpty(s) ((s) == NULL || *(s) == '\0') #define IsSpace(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n') /* * Check strtol result, using "FullS2L" when no more data is expected, and * "PartS2L" when more data may follow in the string. */ #define FullS2L(s,d) (PartS2L(s,d) && (*(d) == '\0')) #define PartS2L(s,d) (isdigit(CharOf(*(s))) && (d) != (s) && (d) != NULL) #define CASETYPE(name) case name: result = #name; break #define AsciiOf(n) (0x7f & (n)) /* extract 7-bit character */ #define CharOf(n) ((Char)(n)) /* extract 8-bit character */ typedef struct { int row; int col; } CELL; typedef struct { Char *data_buffer; /* the current selection */ size_t data_limit; /* size of allocated buffer */ size_t data_length; /* number of significant bytes */ } SelectedCells; #define isSameRow(a,b) ((a)->row == (b)->row) #define isSameCol(a,b) ((a)->col == (b)->col) #define isSameCELL(a,b) (isSameRow(a,b) && isSameCol(a,b)) #define xBIT(n) (1 << (n)) /* * ANSI emulation, special character codes */ #define ANSI_EOT 0x04 #define ANSI_BEL 0x07 #define ANSI_BS 0x08 #define ANSI_HT 0x09 #define ANSI_LF 0x0A #define ANSI_VT 0x0B #define ANSI_FF 0x0C /* C0, C1 control names */ #define ANSI_CR 0x0D #define ANSI_SO 0x0E #define ANSI_SI 0x0F #define ANSI_XON 0x11 /* DC1 */ #define ANSI_XOFF 0x13 /* DC3 */ #define ANSI_NAK 0x15 #define ANSI_CAN 0x18 #define ANSI_ESC 0x1B #define ANSI_SPA 0x20 #define XTERM_POUND 0x1E /* internal mapping for '#' */ #define ANSI_DEL 0x7F #define ANSI_SS2 0x8E #define ANSI_SS3 0x8F #define ANSI_DCS 0x90 #define ANSI_SOS 0x98 #define ANSI_CSI 0x9B #define ANSI_ST 0x9C #define ANSI_OSC 0x9D #define ANSI_PM 0x9E #define ANSI_APC 0x9F #define XTERM_PUA 0xEEEE /* internal mapping for DEC Technical */ #define BAD_ASCII '?' #define NonLatin1(c) (((c) != ANSI_LF) && \ ((c) != ANSI_HT) && \ (((c) < ANSI_SPA) || \ ((c) >= ANSI_DEL && (c) <= ANSI_APC))) #define OnlyLatin1(c) (NonLatin1(c) ? BAD_ASCII : (c)) #define L_BLOK '[' #define R_BLOK ']' #define L_CURL '{' #define R_CURL '}' #define MIN_DECID 52 /* can emulate VT52 */ #define MAX_DECID 525 /* ...through VT525 */ #ifndef DFT_DECID #define DFT_DECID "420" /* default VT420 */ #endif #ifndef DFT_KBD_DIALECT #define DFT_KBD_DIALECT "B" /* default USASCII */ #endif #define MAX_I_PARAM 65535 /* parameters */ #define MAX_I_DELAY 32767 /* time-delay in ReGIS */ #define MAX_U_COLOR 65535u /* colors */ #define MAX_U_COORD 32767u /* coordinates */ #define MAX_U_STRING 65535u /* string-length */ /* constants used for utf8 mode */ #define UCS_REPL 0xfffd #define UCS_LIMIT 0x80000000U /* both limit and flag for non-UCS */ #define TERMCAP_SIZE 1500 /* 1023 is standard; 'screen' exceeds */ #define MAX_XLFD_FONTS 1 #define MAX_XFT_FONTS 2 #define NMENUFONTS 10 /* font entries in fontMenu */ #define NBOX 5 /* Number of Points in box */ #define NPARAM 30 /* Max. parameters */ typedef struct { String opt; String desc; } OptionHelp; typedef struct { int count; /* number of values in params[] */ int has_subparams; /* true if there are any sub's */ int is_sub[NPARAM]; /* true for subparam */ int params[NPARAM]; /* parameter value */ } PARAMS; typedef short ParmType; typedef unsigned short UParm; /* unparseputn passes ParmType */ #define MaxSParm 0x7fff /* limit if a signed value is needed */ #define MaxUParm 0xffff /* limit if unsigned value is needed */ #define SParmOf(n) ((int)(ParmType)(n)) #define UParmOf(n) ((unsigned)(UParm)(n)) typedef struct { Char a_type; /* CSI, etc., see unparseq() */ Char a_pintro; /* private-mode char, if any */ const char * a_delim; /* between parameters (;) */ Char a_inters; /* special (before final-char) */ Char a_final; /* final-char */ ParmType a_nparam; /* # of parameters */ ParmType a_param[NPARAM]; /* Parameters */ Char a_radix[NPARAM]; /* Parameters */ } ANSI; #define TEK_FONT_LARGE 0 #define TEK_FONT_2 1 #define TEK_FONT_3 2 #define TEK_FONT_SMALL 3 #define TEKNUMFONTS 4 /* Actually there are 5 types of lines, but four are non-solid lines */ #define TEKNUMLINES 4 typedef struct { int x; int y; int fontsize; unsigned linetype; } Tmodes; typedef struct { int Twidth; int Theight; } T_fontsize; typedef struct { short *bits; int x; int y; int width; int height; } BitmapBits; /* bit-assignments for extensions to DECRQCRA, to omit DEC features */ typedef enum { csDEC = 0 ,csPOSITIVE = xBIT(0) /* do not negate the result */ ,csATTRIBS = xBIT(1) /* do not report the VT100 video attributes */ ,csNOTRIM = xBIT(2) /* do not omit checksum for blanks */ ,csDRAWN = xBIT(3) /* do not skip uninitialized cells */ ,csBYTE = xBIT(4) /* do not mask cell value to 8 bits or ignore combining chars */ } CSBITS; #define EXCHANGE(a,b,tmp) tmp = a; a = b; b = tmp /***====================================================================***/ #if (XtSpecificationRelease < 6) #ifndef NO_ACTIVE_ICON #define NO_ACTIVE_ICON 1 /* Note: code relies on an X11R6 function */ #endif #endif #ifndef OPT_AIX_COLORS #define OPT_AIX_COLORS 1 /* true if xterm is configured with AIX (16) colors */ #endif #ifndef OPT_ALLOW_XXX_OPS #define OPT_ALLOW_XXX_OPS 1 /* true if xterm adds "Allow XXX Ops" submenu */ #endif #ifndef OPT_BLINK_CURS #define OPT_BLINK_CURS 1 /* true if xterm has blinking cursor capability */ #endif #ifndef OPT_BLINK_TEXT #define OPT_BLINK_TEXT OPT_BLINK_CURS /* true if xterm has blinking text capability */ #endif #ifndef OPT_BLOCK_SELECT #define OPT_BLOCK_SELECT 0 /* true if block-select is supported */ #endif #ifndef OPT_BOX_CHARS #define OPT_BOX_CHARS 1 /* true if xterm can simulate box-characters */ #endif #ifndef OPT_BUILTIN_XPMS #define OPT_BUILTIN_XPMS 0 /* true if all xpm data is compiled-in */ #endif #ifndef OPT_BROKEN_OSC #ifdef linux #define OPT_BROKEN_OSC 1 /* man console_codes, 1st paragraph - cf: ECMA-48 */ #else #define OPT_BROKEN_OSC 0 /* true if xterm allows Linux's broken OSC parsing */ #endif #endif #ifndef OPT_BROKEN_ST #define OPT_BROKEN_ST 1 /* true if xterm allows old/broken OSC parsing */ #endif #ifndef OPT_C1_PRINT #define OPT_C1_PRINT 1 /* true if xterm allows C1 controls to be printable */ #endif #ifndef OPT_CLIP_BOLD #define OPT_CLIP_BOLD 1 /* true if xterm uses clipping to avoid bold-trash */ #endif #ifndef OPT_COLOR_CLASS #define OPT_COLOR_CLASS 1 /* true if xterm uses separate color-resource classes */ #endif #ifndef OPT_DABBREV #define OPT_DABBREV 0 /* dynamic abbreviations */ #endif #ifndef OPT_DEC_CHRSET #define OPT_DEC_CHRSET 1 /* true if xterm is configured for DEC charset */ #endif #ifndef OPT_DEC_LOCATOR #define OPT_DEC_LOCATOR 0 /* true if xterm supports VT220-style mouse events */ #endif #ifndef OPT_DEC_RECTOPS #define OPT_DEC_RECTOPS 1 /* true if xterm is configured for VT420 rectangles */ #endif #ifndef OPT_SGR2_HASH #define OPT_SGR2_HASH 1 /* true if xterm hashes color-lookups for faint color */ #endif #ifndef OPT_SIXEL_GRAPHICS #define OPT_SIXEL_GRAPHICS 0 /* true if xterm supports VT240-style sixel graphics */ #endif #ifndef OPT_PRINT_GRAPHICS #define OPT_PRINT_GRAPHICS 0 /* true if xterm supports screen dumps as sixel graphics */ #endif #ifndef OPT_SCREEN_DUMPS #define OPT_SCREEN_DUMPS 1 /* true if xterm supports screen dumps */ #endif #ifndef OPT_REGIS_GRAPHICS #define OPT_REGIS_GRAPHICS 0 /* true if xterm supports VT125/VT240/VT330 ReGIS graphics */ #endif #ifndef OPT_GRAPHICS #define OPT_GRAPHICS 0 /* true if xterm is configured for any type of graphics */ #endif #ifndef OPT_DEC_SOFTFONT #define OPT_DEC_SOFTFONT 0 /* true if xterm is configured for VT220 softfonts */ #endif #ifndef OPT_DOUBLE_BUFFER #define OPT_DOUBLE_BUFFER 0 /* true if using double-buffering */ #endif #ifndef OPT_EXEC_SELECTION #define OPT_EXEC_SELECTION 1 /* true if xterm can exec to process selection */ #endif #ifndef OPT_EXEC_XTERM #define OPT_EXEC_XTERM 0 /* true if xterm can fork/exec copies of itself */ #endif #ifndef OPT_EXTRA_PASTE #define OPT_EXTRA_PASTE 1 #endif #ifndef OPT_FOCUS_EVENT #define OPT_FOCUS_EVENT 1 /* focus in/out events */ #endif #ifndef OPT_HP_FUNC_KEYS #define OPT_HP_FUNC_KEYS 0 /* true if xterm supports HP-style function keys */ #endif #ifndef OPT_I18N_SUPPORT #if (XtSpecificationRelease >= 5) #define OPT_I18N_SUPPORT 1 /* true if xterm uses internationalization support */ #else #define OPT_I18N_SUPPORT 0 #endif #endif #ifndef OPT_INITIAL_ERASE #define OPT_INITIAL_ERASE 1 /* use pty's erase character if it's not 128 */ #endif #ifndef OPT_INPUT_METHOD #if (XtSpecificationRelease >= 6) #define OPT_INPUT_METHOD OPT_I18N_SUPPORT /* true if xterm uses input-method support */ #else #define OPT_INPUT_METHOD 0 #endif #endif #ifndef OPT_ISO_COLORS #define OPT_ISO_COLORS 1 /* true if xterm is configured with ISO colors */ #endif #ifndef OPT_DIRECT_COLOR #define OPT_DIRECT_COLOR OPT_ISO_COLORS /* true if xterm is configured with direct-colors */ #endif #ifndef OPT_256_COLORS #define OPT_256_COLORS 1 /* true if xterm is configured with 256 colors */ #endif #ifndef OPT_88_COLORS #define OPT_88_COLORS 1 /* true if xterm is configured with 88 colors */ #endif #ifndef OPT_HIGHLIGHT_COLOR #define OPT_HIGHLIGHT_COLOR 1 /* true if xterm supports color highlighting */ #endif #ifndef OPT_LOAD_VTFONTS #define OPT_LOAD_VTFONTS 0 /* true if xterm has load-vt-fonts() action */ #endif #ifndef OPT_LUIT_PROG #define OPT_LUIT_PROG 1 /* true if xterm supports luit */ #endif #ifndef OPT_MAXIMIZE #define OPT_MAXIMIZE 1 /* add actions for iconify ... maximize */ #endif #ifndef OPT_MINI_LUIT #define OPT_MINI_LUIT 0 /* true if xterm supports built-in mini-luit */ #endif #ifndef OPT_MOD_FKEYS #define OPT_MOD_FKEYS 1 /* modify cursor- and function-keys in normal mode */ #endif #ifndef OPT_NUM_LOCK #define OPT_NUM_LOCK 1 /* use NumLock key only for numeric-keypad */ #endif #ifndef OPT_PASTE64 #define OPT_PASTE64 1 /* program control of select/paste via base64 */ #endif #ifndef OPT_PC_COLORS #define OPT_PC_COLORS 1 /* true if xterm supports PC-style (bold) colors */ #endif #ifndef OPT_PRINT_ON_EXIT #define OPT_PRINT_ON_EXIT 1 /* true allows xterm to dump screen on X error */ #endif #ifndef OPT_PTY_HANDSHAKE #define OPT_PTY_HANDSHAKE USE_HANDSHAKE /* avoid pty races on older systems */ #endif #ifndef OPT_PRINT_COLORS #define OPT_PRINT_COLORS 1 /* true if we print color information */ #endif #ifndef OPT_READLINE #define OPT_READLINE 0 /* mouse-click/paste support for readline */ #endif #ifndef OPT_RENDERFONT #ifdef XRENDERFONT #define OPT_RENDERFONT 1 #else #define OPT_RENDERFONT 0 #endif #endif #ifndef OPT_RENDERWIDE #if OPT_RENDERFONT && OPT_WIDE_CHARS && defined(HAVE_TYPE_XFTCHARSPEC) #define OPT_RENDERWIDE 1 #else #define OPT_RENDERWIDE 0 #endif #endif #ifndef OPT_REPORT_CCLASS #define OPT_REPORT_CCLASS 1 /* provide "-report-charclass" option */ #endif #ifndef OPT_REPORT_COLORS #define OPT_REPORT_COLORS 1 /* provide "-report-colors" option */ #endif #ifndef OPT_REPORT_FONTS #define OPT_REPORT_FONTS 1 /* provide "-report-fonts" option */ #endif #ifndef OPT_REPORT_ICONS #define OPT_REPORT_ICONS 1 /* provide "-report-icons" option */ #endif #ifndef OPT_SAME_NAME #define OPT_SAME_NAME 1 /* suppress redundant updates of title, icon, etc. */ #endif #ifndef OPT_SCO_FUNC_KEYS #define OPT_SCO_FUNC_KEYS 0 /* true if xterm supports SCO-style function keys */ #endif #ifndef OPT_SUN_FUNC_KEYS #define OPT_SUN_FUNC_KEYS 1 /* true if xterm supports Sun-style function keys */ #endif #ifndef OPT_SCROLL_LOCK #define OPT_SCROLL_LOCK 1 /* true if xterm interprets fontsize-shifting */ #endif #ifndef OPT_SELECT_REGEX #define OPT_SELECT_REGEX 1 /* true if xterm supports regular-expression selects */ #endif #ifndef OPT_SELECTION_OPS #define OPT_SELECTION_OPS 1 /* true if xterm supports operations on selection */ #endif #ifndef OPT_SESSION_MGT #if defined(XtNdieCallback) && defined(XtNsaveCallback) #define OPT_SESSION_MGT 1 #else #define OPT_SESSION_MGT 0 #endif #endif #ifndef OPT_SHIFT_FONTS #define OPT_SHIFT_FONTS 1 /* true if xterm interprets fontsize-shifting */ #endif #ifndef OPT_STATUS_LINE #define OPT_STATUS_LINE 0 /* true if xterm supports status-line controls */ #endif #ifndef OPT_SUNPC_KBD #define OPT_SUNPC_KBD 1 /* true if xterm supports Sun/PC keyboard map */ #endif #ifndef OPT_TCAP_FKEYS #define OPT_TCAP_FKEYS 1 /* true for termcap function-keys */ #endif #ifndef OPT_TCAP_QUERY #define OPT_TCAP_QUERY 1 /* true for termcap query */ #endif #ifndef OPT_TEK4014 #define OPT_TEK4014 1 /* true if we're using tek4014 emulation */ #endif #ifndef OPT_TOOLBAR #define OPT_TOOLBAR 0 /* true if xterm supports toolbar menus */ #endif #ifndef OPT_TRACE #define OPT_TRACE 0 /* true if we're using debugging traces */ #endif #ifndef OPT_TRACE_FLAGS #define OPT_TRACE_FLAGS 0 /* additional tracing used for SCRN_BUF_FLAGS */ #endif #ifndef OPT_TRACE_UNIQUE #define OPT_TRACE_UNIQUE 0 /* true if we're using multiple trace files */ #endif #ifndef OPT_VT52_MODE #define OPT_VT52_MODE 1 /* true if xterm supports VT52 emulation */ #endif #ifndef OPT_WIDE_ATTRS #define OPT_WIDE_ATTRS 1 /* true if xterm supports 16-bit attributes */ #endif #ifndef OPT_VT525_COLORS #define OPT_VT525_COLORS 1 /* true if xterm is configured for VT525 colors */ #endif #ifndef OPT_WIDE_CHARS #define OPT_WIDE_CHARS 1 /* true if xterm supports 16-bit characters */ #endif #ifndef OPT_WIDER_ICHAR #define OPT_WIDER_ICHAR 1 /* true if xterm uses 32-bits for wide-chars */ #endif #ifndef OPT_XMC_GLITCH #define OPT_XMC_GLITCH 0 /* true if xterm supports xmc (magic cookie glitch) */ #endif #ifndef OPT_XRES_QUERY #define OPT_XRES_QUERY 1 /* true for resource query */ #endif #ifndef OPT_XTERM_SGR #define OPT_XTERM_SGR 1 /* true if xterm supports private SGR controls */ #endif #ifndef OPT_ZICONBEEP #define OPT_ZICONBEEP 1 /* true if xterm supports "-ziconbeep" option */ #endif /***====================================================================***/ #if OPT_AIX_COLORS && !OPT_ISO_COLORS /* You must have ANSI/ISO colors to support AIX colors */ #undef OPT_AIX_COLORS #define OPT_AIX_COLORS 0 #endif #if OPT_PC_COLORS && !OPT_ISO_COLORS /* You must have ANSI/ISO colors to support PC colors */ #undef OPT_PC_COLORS #define OPT_PC_COLORS 0 #endif #if OPT_PRINT_COLORS && !OPT_ISO_COLORS /* You must have ANSI/ISO colors to be able to print them */ #undef OPT_PRINT_COLORS #define OPT_PRINT_COLORS 0 #endif #if OPT_256_COLORS && !OPT_ISO_COLORS /* You must have ANSI/ISO colors to support 256 colors */ #undef OPT_256_COLORS #define OPT_256_COLORS 0 #endif #if OPT_88_COLORS && !OPT_ISO_COLORS /* You must have ANSI/ISO colors to support 88 colors */ #undef OPT_88_COLORS #define OPT_88_COLORS 0 #endif #if OPT_88_COLORS && OPT_256_COLORS /* 256 colors supersedes 88 colors */ #undef OPT_88_COLORS #define OPT_88_COLORS 0 #endif /***====================================================================***/ /* * Indices for menu_font_names[][] */ typedef enum { fNorm = 0 /* normal font */ , fBold /* bold font */ #if OPT_WIDE_ATTRS || OPT_RENDERWIDE , fItal /* italic font */ , fBtal /* bold-italic font */ #endif #if OPT_WIDE_CHARS , fWide /* double-width font */ , fWBold /* double-width bold font */ , fWItal /* double-width italic font */ , fWBtal /* double-width bold-italic font */ #endif , fMAX } VTFontEnum; /* * Indices for cachedGCs.c (unrelated to VTFontEnum). */ typedef enum { gcNorm = 0 , gcBold , gcNormReverse , gcBoldReverse , gcFiller , gcBorder #if OPT_BOX_CHARS || OPT_WIDE_CHARS , gcLine , gcDots #endif #if OPT_DEC_CHRSET , gcCNorm , gcCBold #endif #if OPT_WIDE_CHARS , gcWide , gcWBold , gcWideReverse , gcWBoldReverse #endif , gcVTcursNormal , gcVTcursFilled , gcVTcursReverse , gcVTcursOutline #if OPT_TEK4014 , gcTKcurs #endif , gcMAX } CgsEnum; #define for_each_text_gc(n) for (n = gcNorm; n < gcVTcursNormal; ++n) #define for_each_curs_gc(n) for (n = gcVTcursNormal; n <= gcVTcursOutline; ++n) #define for_each_gc(n) for (n = gcNorm; n < gcMAX; ++n) /* * Indices for the normal terminal colors in screen.Tcolors[]. * See also OscTextColors, which has corresponding values. */ typedef enum { TEXT_FG = 0 /* text foreground */ , TEXT_BG /* text background */ , TEXT_CURSOR /* text cursor */ , MOUSE_FG /* mouse foreground */ , MOUSE_BG /* mouse background */ #if OPT_TEK4014 , TEK_FG = 5 /* tektronix foreground */ , TEK_BG /* tektronix background */ #endif #if OPT_HIGHLIGHT_COLOR , HIGHLIGHT_BG = 7 /* highlight background */ #endif #if OPT_TEK4014 , TEK_CURSOR = 8 /* tektronix cursor */ #endif #if OPT_HIGHLIGHT_COLOR , HIGHLIGHT_FG = 9 /* highlight foreground */ #endif , NCOLORS /* total number of colors */ } TermColors; /* * Enum corresponding to the actual OSC codes rather than the internal * array indices. Compare with TermColors. */ typedef enum { OSC_TEXT_FG = 10 ,OSC_TEXT_BG ,OSC_TEXT_CURSOR ,OSC_MOUSE_FG ,OSC_MOUSE_BG #if OPT_TEK4014 ,OSC_TEK_FG = 15 ,OSC_TEK_BG #endif #if OPT_HIGHLIGHT_COLOR ,OSC_HIGHLIGHT_BG = 17 #endif #if OPT_TEK4014 ,OSC_TEK_CURSOR = 18 #endif #if OPT_HIGHLIGHT_COLOR ,OSC_HIGHLIGHT_FG = 19 #endif ,OSC_NCOLORS } OscTextColors; /* * Definitions for exec-formatted and insert-formatted actions. */ typedef void (*FormatSelect) (Widget, char *, char *, CELL *, CELL *); typedef struct { Boolean done; char *format; char *buffer; FormatSelect format_select; #if OPT_PASTE64 Cardinal base64_paste; #endif #if OPT_PASTE64 || OPT_READLINE unsigned paste_brackets; #endif } InternalSelect; /* * Constants for titleModes resource */ typedef enum { tmSetBase16 = 1 /* set title using hex-string */ , tmGetBase16 = 2 /* get title using hex-string */ #if OPT_WIDE_CHARS #define MAX_TITLEMODE 3 , tmSetUtf8 = 4 /* like utf8Title, but controllable */ , tmGetUtf8 = 8 /* retrieve title encoded as UTF-8 */ #else #define MAX_TITLEMODE 1 #endif } TitleModes; #define ValidTitleMode(code) ((code) >= 0 && (code) <= MAX_TITLEMODE) #define IsTitleMode(xw,mode) (((xw)->screen.title_modes & mode) != 0) #define IsSetUtf8Title(xw) (IsTitleMode(xw, tmSetUtf8) \ || ((xw)->screen.utf8_title) \ || ((xw)->screen.c1_printable)) #include /* * For readability... */ #define nrc_percent 100 #define nrc_dquote 200 #define nrc_ampersand 300 typedef enum { nrc_ASCII = 0 ,nrc_British /* vt100 */ ,nrc_British_Latin_1 /* vt3xx */ ,nrc_DEC_Cyrillic /* vt5xx */ ,nrc_DEC_Spec_Graphic /* vt100 */ ,nrc_DEC_Alt_Chars /* vt100 */ ,nrc_DEC_Alt_Graphics /* vt100 */ ,nrc_DEC_Supp /* vt2xx */ ,nrc_DEC_Supp_Graphic /* vt3xx */ ,nrc_DEC_Technical /* vt3xx */ ,nrc_DEC_UPSS /* vt3xx */ ,nrc_Dutch /* vt2xx */ ,nrc_Finnish /* vt2xx */ ,nrc_Finnish2 /* vt2xx */ ,nrc_French /* vt2xx */ ,nrc_French2 /* vt2xx */ ,nrc_French_Canadian /* vt2xx */ ,nrc_French_Canadian2 /* vt3xx */ ,nrc_German /* vt2xx */ ,nrc_Greek /* vt5xx */ ,nrc_DEC_Greek_Supp /* vt5xx */ ,nrc_ISO_Greek_Supp /* vt5xx */ ,nrc_DEC_Hebrew_Supp /* vt5xx */ ,nrc_Hebrew /* vt5xx */ ,nrc_ISO_Hebrew_Supp /* vt5xx */ ,nrc_Italian /* vt2xx */ ,nrc_ISO_Latin_1_Supp /* vt3xx */ ,nrc_ISO_Latin_2_Supp /* vt5xx */ ,nrc_ISO_Latin_5_Supp /* vt5xx */ ,nrc_ISO_Latin_Cyrillic /* vt5xx */ ,nrc_JIS_Katakana /* vt382 */ ,nrc_JIS_Roman /* vt382 */ ,nrc_Norwegian_Danish /* vt3xx */ ,nrc_Norwegian_Danish2 /* vt2xx */ ,nrc_Norwegian_Danish3 /* vt2xx */ ,nrc_Portugese /* vt3xx */ ,nrc_Russian /* vt5xx */ ,nrc_SCS_NRCS /* vt5xx - probably Serbo/Croatian */ ,nrc_Spanish /* vt2xx */ ,nrc_Swedish /* vt2xx */ ,nrc_Swedish2 /* vt2xx */ ,nrc_Swiss /* vt2xx */ ,nrc_DEC_Turkish_Supp /* vt5xx */ ,nrc_Turkish /* vt5xx */ ,nrc_Unknown } DECNRCM_codes; /* * Default and alternate codes for user-preferred supplemental set. */ #define DFT_UPSS nrc_DEC_Supp_Graphic #define ALT_UPSS nrc_ISO_Latin_1_Supp #define PreferredUPSS(screen) ((screen)->prefer_latin1 ? ALT_UPSS : DFT_UPSS) /* * Use this enumerated type to check consistency among dpmodes(), savemodes() * restoremodes() and do_dec_rqm(). */ typedef enum { srm_DECCKM = 1 /* Cursor Keys Mode */ ,srm_DECANM = 2 /* ANSI Mode */ ,srm_DECCOLM = 3 /* Column Mode */ ,srm_DECSCLM = 4 /* Scrolling Mode */ ,srm_DECSCNM = 5 /* Screen Mode */ ,srm_DECOM = 6 /* Origin Mode */ ,srm_DECAWM = 7 /* Autowrap Mode */ ,srm_DECARM = 8 /* Autorepeat Mode */ ,srm_X10_MOUSE = SET_X10_MOUSE #if OPT_TOOLBAR ,srm_RXVT_TOOLBAR = 10 #else ,srm_DECEDM = 10 /* vt330:edit */ #endif ,srm_DECLTM = 11 /* vt330:line transmit */ #if OPT_BLINK_CURS ,srm_ATT610_BLINK = 12 ,srm_CURSOR_BLINK_OPS = 13 ,srm_XOR_CURSOR_BLINKS = 14 #else ,srm_DECKANAM = 12 /* vt382:Katakana shift */ ,srm_DECSCFDM = 13 /* vt330:space compression field delimiter */ ,srm_DECTEM = 14 /* vt330:transmission execution */ #endif ,srm_DECEKEM = 16 /* vt330:edit key execution */ ,srm_DECPFF = 18 /* vt220:Print Form Feed Mode */ ,srm_DECPEX = 19 /* vt220:Printer Extent Mode */ ,srm_DECTCEM = 25 /* Text Cursor Enable Mode */ ,srm_RXVT_SCROLLBAR = 30 ,srm_DECRLM = 34 /* vt510:Cursor Right to Left Mode */ #if OPT_SHIFT_FONTS ,srm_RXVT_FONTSIZE = 35 /* also vt520:DECHEBM */ #else ,srm_DECHEBM = 35 /* vt520:Hebrew keyboard mapping */ #endif ,srm_DECHEM = 36 /* vt510:Hebrew Encoding Mode */ #if OPT_TEK4014 ,srm_DECTEK = 38 #endif ,srm_132COLS = 40 ,srm_CURSES_HACK = 41 ,srm_DECNRCM = 42 /* National Replacement Character Set Mode */ #if OPT_PRINT_GRAPHICS ,srm_DECGEPM = 43 /* Graphics Expanded Print Mode */ #endif ,srm_MARGIN_BELL = 44 /* also DECGPCM (Graphics Print Color Mode) */ ,srm_REVERSEWRAP = 45 /* also DECGPCS (Graphics Print Color Syntax) */ #ifdef ALLOWLOGGING ,srm_ALLOWLOGGING = 46 /* also DECGPBM (Graphics Print Background Mode) */ #elif OPT_PRINT_GRAPHICS ,srm_DECGPBM = 46 /* Graphics Print Background Mode */ #endif ,srm_ALTBUF = 47 /* also DECGRPM (Graphics Rotated Print Mode) */ ,srm_DEC131TM = 53 /* vt330:VT131 transmit */ ,srm_DECNAKB = 57 /* vt510:Greek/N-A Keyboard Mapping */ ,srm_DECIPEM = 58 /* vt510:IBM ProPrinter Emulation Mode */ ,srm_DECKKDM = 59 /* vt382:Kanji/Katakana */ ,srm_DECHCCM = 60 /* vt420:Horizontal Cursor-Coupling Mode */ ,srm_DECVCCM = 61 /* vt420:Vertical Cursor-Coupling Mode */ ,srm_DECPCCM = 64 /* vt420:Page Cursor-Coupling Mode */ ,srm_DECNKM = 66 /* vt420:Numeric Keypad Mode */ ,srm_DECBKM = 67 /* vt420:Backarrow Key mode */ ,srm_DECKBUM = 68 /* vt420:Keyboard Usage mode */ ,srm_DECLRMM = 69 /* vt420:Vertical Split Screen Mode (DECVSSM) */ ,srm_DECXRLM = 73 /* vt420:Transmit Rate Limiting */ #if OPT_SIXEL_GRAPHICS ,srm_DECSDM = 80 /* vt320:Sixel Display Mode */ #endif ,srm_DECKPM = 81 /* vt420:Key Position Mode */ ,srm_DECNCSM = 95 /* vt510:No Clearing Screen On Column Change */ ,srm_DECRLCM = 96 /* vt510:Right-to-Left Copy */ ,srm_DECCRTSM = 97 /* vt510:CRT Save Mode */ ,srm_DECARSM = 98 /* vt510:Auto Resize Mode */ ,srm_DECMCM = 99 /* vt510:Modem Control Mode */ ,srm_DECAAM = 100 /* vt510:Auto Answerback Mode */ ,srm_DECCANSM = 101 /* vt510:Conceal Answerback Message Mode */ ,srm_DECNULM = 102 /* vt510:Ignoring Null Mode */ ,srm_DECHDPXM = 103 /* vt510:Half-Duplex Mode */ ,srm_DECESKM = 104 /* vt510:enable secondary keyboard language */ ,srm_DECOSCNM = 106 /* vt510:Overscan Mode */ ,srm_DECNUMLK = 108 /* vt510:Num Lock Mode */ ,srm_DECCAPSLK = 109 /* vt510:Caps Lock Mode */ ,srm_DECKLHIM = 110 /* vt510:Keyboard LEDs Host Indicator Mode */ ,srm_DECFWM = 111 /* vt520:Framed Windows Mode */ ,srm_DECRPL = 112 /* vt520:Review Previous Lines */ ,srm_DECHWUM = 113 /* vt520:Host Wake-Up */ ,srm_DECATCUM = 114 /* vt520:Alternate Text Color Underline */ ,srm_DECATCBM = 115 /* vt520:Alternate Text Color Blink */ ,srm_DECBBSM = 116 /* vt520:Bold and Blink Style Mode */ ,srm_DECECM = 117 /* vt520:Erase Color Mode */ ,srm_VT200_MOUSE = SET_VT200_MOUSE ,srm_VT200_HIGHLIGHT_MOUSE = SET_VT200_HIGHLIGHT_MOUSE ,srm_BTN_EVENT_MOUSE = SET_BTN_EVENT_MOUSE ,srm_ANY_EVENT_MOUSE = SET_ANY_EVENT_MOUSE #if OPT_FOCUS_EVENT ,srm_FOCUS_EVENT_MOUSE = SET_FOCUS_EVENT_MOUSE #endif ,srm_EXT_MODE_MOUSE = SET_EXT_MODE_MOUSE ,srm_SGR_EXT_MODE_MOUSE = SET_SGR_EXT_MODE_MOUSE ,srm_URXVT_EXT_MODE_MOUSE = SET_URXVT_EXT_MODE_MOUSE ,srm_PIXEL_POSITION_MOUSE = SET_PIXEL_POSITION_MOUSE ,srm_ALTERNATE_SCROLL = SET_ALTERNATE_SCROLL ,srm_RXVT_SCROLL_TTY_OUTPUT = 1010 ,srm_RXVT_SCROLL_TTY_KEYPRESS = 1011 ,srm_FAST_SCROLL = 1014 ,srm_EIGHT_BIT_META = 1034 #if OPT_NUM_LOCK ,srm_REAL_NUMLOCK = 1035 ,srm_META_SENDS_ESC = 1036 #endif ,srm_DELETE_IS_DEL = 1037 #if OPT_NUM_LOCK ,srm_ALT_SENDS_ESC = 1039 #endif ,srm_KEEP_SELECTION = 1040 ,srm_SELECT_TO_CLIPBOARD = 1041 ,srm_BELL_IS_URGENT = 1042 ,srm_POP_ON_BELL = 1043 ,srm_KEEP_CLIPBOARD = 1044 ,srm_REVERSEWRAP2 = 1045 /* reverse-wrap without limits */ ,srm_ALLOW_ALTBUF = 1046 ,srm_OPT_ALTBUF = 1047 ,srm_SAVE_CURSOR = 1048 ,srm_OPT_ALTBUF_CURSOR = 1049 #if OPT_TCAP_FKEYS ,srm_TCAP_FKEYS = 1050 #endif #if OPT_SUN_FUNC_KEYS ,srm_SUN_FKEYS = 1051 #endif #if OPT_HP_FUNC_KEYS ,srm_HP_FKEYS = 1052 #endif #if OPT_SCO_FUNC_KEYS ,srm_SCO_FKEYS = 1053 #endif ,srm_LEGACY_FKEYS = 1060 #if OPT_SUNPC_KBD ,srm_VT220_FKEYS = 1061 #endif #if OPT_GRAPHICS ,srm_PRIVATE_COLOR_REGISTERS = 1070 #endif #if OPT_PASTE64 || OPT_READLINE ,srm_PASTE_IN_BRACKET = SET_PASTE_IN_BRACKET #endif #if OPT_READLINE ,srm_BUTTON1_MOVE_POINT = SET_BUTTON1_MOVE_POINT ,srm_BUTTON2_MOVE_POINT = SET_BUTTON2_MOVE_POINT ,srm_DBUTTON3_DELETE = SET_DBUTTON3_DELETE ,srm_PASTE_QUOTE = SET_PASTE_QUOTE ,srm_PASTE_LITERAL_NL = SET_PASTE_LITERAL_NL #endif /* OPT_READLINE */ #if OPT_SIXEL_GRAPHICS ,srm_SIXEL_SCROLLS_RIGHT = 8452 #endif } DECSET_codes; /* internal codes for selection atoms */ typedef enum { PRIMARY_CODE = 0 ,CLIPBOARD_CODE ,SECONDARY_CODE ,MAX_SELECTION_CODES } SelectionCodes; /* indices for mapping multiple clicks to selection types */ typedef enum { Select_CHAR=0 ,Select_WORD ,Select_LINE ,Select_GROUP ,Select_PAGE ,Select_ALL #if OPT_SELECT_REGEX ,Select_REGEX #endif ,NSELECTUNITS } SelectUnit; #if OPT_BLINK_CURS typedef enum { cbFalse = 0 , cbTrue , cbAlways , cbNever , cbLAST } BlinkOps; #endif typedef enum { ecSetColor = 1 , ecGetColor , ecGetAnsiColor , ecLAST } ColorOps; typedef enum { efSetFont = 1 , efGetFont , efLAST } FontOps; typedef enum { esFalse = 0 , esTrue , esAlways , esNever , esLAST } FullscreenOps; #ifndef NO_ACTIVE_ICON typedef enum { eiFalse = 0 , eiTrue , eiDefault , eiLAST } AIconOps; #endif typedef enum { emX10 = 1 , emLocator , emVT200Click , emVT200Hilite , emAnyButton , emAnyEvent , emFocusEvent , emExtended , emSGR , emURXVT , emAlternateScroll , emLAST } MouseOps; typedef enum { #define DATA(name) ep##name DATA(NUL) = 0 , DATA(SOH) = 1 , DATA(STX) = 2 , DATA(ETX) = 3 , DATA(EOT) = 4 , DATA(ENQ) = 5 , DATA(ACK) = 6 , DATA(BEL) = 7 , DATA(BS) = 8 , DATA(HT) = 9 , DATA(LF) = 10 , DATA(VT) = 11 , DATA(FF) = 12 , DATA(CR) = 13 , DATA(SO) = 14 , DATA(SI) = 15 , DATA(DLE) = 16 , DATA(DC1) = 17 , DATA(DC2) = 18 , DATA(DC3) = 19 , DATA(DC4) = 20 , DATA(NAK) = 21 , DATA(SYN) = 22 , DATA(ETB) = 23 , DATA(CAN) = 24 , DATA(EM) = 25 , DATA(SUB) = 26 , DATA(ESC) = 27 , DATA(FS) = 28 , DATA(GS) = 29 , DATA(RS) = 30 , DATA(US) = 31 /* aliases */ , DATA(C0) , DATA(DEL) , DATA(STTY) #undef DATA , epLAST } PasteControls; typedef enum { /* legal values for keyboard.shift_escape */ ssFalse = 0 , ssTrue = 1 , ssAlways = 2 , ssNever = 3 , ssLAST } ShiftEscapeOps; /* * xterm uses these codes for the its push-SGR feature. They match where * possible the corresponding SGR coding. The foreground and background colors * do not fit into that scheme (because they are a set of ranges), so those are * chosen arbitrarily -TD */ typedef enum { psBOLD = 1 #if OPT_WIDE_ATTRS , psATR_FAINT = 2 , psATR_ITALIC = 3 #endif , psUNDERLINE = 4 , psBLINK = 5 , psINVERSE = 7 , psINVISIBLE = 8 #if OPT_WIDE_ATTRS , psATR_STRIKEOUT = 9 #endif /* SGR 10-19 correspond to primary/alternate fonts, currently unused */ #if OPT_ISO_COLORS , psFG_COLOR_obs = 10 , psBG_COLOR_obs = 11 #endif #if OPT_WIDE_ATTRS , psATR_DBL_UNDER = 21 #endif /* SGR 22-29 mostly are used to reset SGR 1-9 */ #if OPT_ISO_COLORS , psFG_COLOR = 30 /* stack maps many colors to one state */ , psBG_COLOR = 31 #endif , MAX_PUSH_SGR } PushSGR; typedef enum { etSetTcap = 1 , etGetTcap , etLAST } TcapOps; typedef enum { /* 1-23 are chosen to be the same as the control-sequence coding */ ewRestoreWin = 1 , ewMinimizeWin = 2 , ewSetWinPosition = 3 , ewSetWinSizePixels = 4 , ewRaiseWin = 5 , ewLowerWin = 6 , ewRefreshWin = 7 , ewSetWinSizeChars = 8 #if OPT_MAXIMIZE , ewMaximizeWin = 9 , ewFullscreenWin = 10 #endif , ewGetWinState = 11 , ewGetWinPosition = 13 , ewGetWinSizePixels = 14 #if OPT_MAXIMIZE , ewGetScreenSizePixels = 15 , ewGetCharSizePixels = 16 #endif , ewGetWinSizeChars = 18 #if OPT_MAXIMIZE , ewGetScreenSizeChars = 19 #endif , ewGetIconTitle = 20 , ewGetWinTitle = 21 , ewPushTitle = 22 , ewPopTitle = 23 /* these do not fit into that scheme, which is why we use an array */ , ewSetWinLines , ewSetXprop , ewGetSelection , ewSetSelection , ewGetChecksum , ewSetChecksum , ewStatusLine , ewColumnMode /* get the size of the array... */ , ewLAST } WindowOps; /***====================================================================***/ #define COLOR_DEFINED(s,w) ((s)->which & (unsigned) (1<<(w))) #define COLOR_VALUE(s,w) ((s)->colors[w]) #define SET_COLOR_VALUE(s,w,v) (((s)->colors[w] = (v)), UIntSet((s)->which, (1<<(w)))) #define COLOR_NAME(s,w) ((s)->names[w]) #define SET_COLOR_NAME(s,w,v) (((s)->names[w] = (v)), ((s)->which |= (unsigned) (1<<(w)))) #define UNDEFINE_COLOR(s,w) ((s)->which &= (~((w)<<1))) /***====================================================================***/ #if OPT_ISO_COLORS #if OPT_WIDE_ATTRS #define COLOR_FLAGS (FG_COLOR | BG_COLOR | ATR_DIRECT_FG | ATR_DIRECT_BG) #else #define COLOR_FLAGS (FG_COLOR | BG_COLOR) #endif #define TERM_COLOR_FLAGS(xw) ((xw)->flags & COLOR_FLAGS) #define COLOR_0 0 #define COLOR_1 1 #define COLOR_2 2 #define COLOR_3 3 #define COLOR_4 4 #define COLOR_5 5 #define COLOR_6 6 #define COLOR_7 7 #define COLOR_8 8 #define COLOR_9 9 #define COLOR_10 10 #define COLOR_11 11 #define COLOR_12 12 #define COLOR_13 13 #define COLOR_14 14 #define COLOR_15 15 #define MIN_ANSI_COLORS 16 #if OPT_256_COLORS # define NUM_ANSI_COLORS 256 #elif OPT_88_COLORS # define NUM_ANSI_COLORS 88 #else # define NUM_ANSI_COLORS MIN_ANSI_COLORS #endif #define okIndexedColor(n) ((n) >= 0 && (n) < NUM_ANSI_COLORS) #if NUM_ANSI_COLORS > MIN_ANSI_COLORS # define OPT_EXT_COLORS 1 #else # define OPT_EXT_COLORS 0 #endif #define COLOR_BD (NUM_ANSI_COLORS) /* BOLD */ #define COLOR_UL (NUM_ANSI_COLORS+1) /* UNDERLINE */ #define COLOR_BL (NUM_ANSI_COLORS+2) /* BLINK */ #define COLOR_RV (NUM_ANSI_COLORS+3) /* REVERSE */ #if OPT_WIDE_ATTRS #define COLOR_IT (NUM_ANSI_COLORS+4) /* ITALIC */ #define MAXCOLORS (NUM_ANSI_COLORS+5) #else #define MAXCOLORS (NUM_ANSI_COLORS+4) #endif #ifndef DFT_COLORMODE #define DFT_COLORMODE True /* default colorMode resource */ #endif #define UseItalicFont(screen) (!(screen)->colorITMode) #define ReverseOrHilite(screen,flags,hilite) \ (( screen->colorRVMode && hilite ) || \ ( !screen->colorRVMode && \ (( (flags & INVERSE) && !hilite) || \ (!(flags & INVERSE) && hilite)) )) #else /* !OPT_ISO_COLORS */ #define TERM_COLOR_FLAGS(xw) 0 #define UseItalicFont(screen) True #define ReverseOrHilite(screen,flags,hilite) \ (( (flags & INVERSE) && !hilite) || \ (!(flags & INVERSE) && hilite)) #endif /* OPT_ISO_COLORS */ typedef enum { XK_TCAPNAME = 3 /* Define fake XK codes, we need those for the fake color response in * xtermcapKeycode(). */ #if OPT_ISO_COLORS , XK_COLORS , XK_RGB #endif } TcapQuery; #if OPT_AIX_COLORS #define if_OPT_AIX_COLORS(screen, code) if(screen->colorMode) code #else #define if_OPT_AIX_COLORS(screen, code) /* nothing */ #endif #if OPT_256_COLORS || OPT_88_COLORS || OPT_ISO_COLORS # define if_OPT_ISO_COLORS(screen, code) if (screen->colorMode) code #else # define if_OPT_ISO_COLORS(screen, code) /* nothing */ #endif #if OPT_DIRECT_COLOR # define if_OPT_DIRECT_COLOR(screen, code) if (screen->direct_color) code # define if_OPT_DIRECT_COLOR2(screen, test, code) if (screen->direct_color && (test)) code #else # define if_OPT_DIRECT_COLOR(screen, code) /* nothing */ # define if_OPT_DIRECT_COLOR2(screen, test, code) /* nothing */ #endif #define if_OPT_DIRECT_COLOR2_else(cond, test, stmt) \ if_OPT_DIRECT_COLOR2(cond, test, stmt else) #define COLOR_RES_NAME(root) "color" root #if OPT_COLOR_CLASS #define COLOR_RES_CLASS(root) "Color" root #else #define COLOR_RES_CLASS(root) XtCForeground #endif #define COLOR_RES(root,offset,value) Sres(COLOR_RES_NAME(root), COLOR_RES_CLASS(root), offset.resource, value) #define COLOR_RES2(name,class,offset,value) Sres(name, class, offset.resource, value) #define CLICK_RES_NAME(count) "on" count "Clicks" #define CLICK_RES_CLASS(count) "On" count "Clicks" #define CLICK_RES(count,offset,value) Sres(CLICK_RES_NAME(count), CLICK_RES_CLASS(count), offset, value) /***====================================================================***/ #if OPT_DEC_CHRSET #define if_OPT_DEC_CHRSET(code) code /* Use 2 bits for encoding the double high/wide sense of characters */ #define CSET_SWL 0 /* character set: single-width line */ #define CSET_DHL_TOP 1 /* character set: double-height top line */ #define CSET_DHL_BOT 2 /* character set: double-height bottom line */ #define CSET_DWL 3 /* character set: double-width line */ #define NUM_CHRSET 8 /* normal/bold and 4 CSET_xxx values */ /* Use remaining bits for encoding the other character-sets */ #define CSET_NORMAL(code) ((code) == CSET_SWL) #define CSET_DOUBLE(code) (!CSET_NORMAL(code) && !CSET_EXTEND(code)) #define CSET_EXTEND(code) ((int)(code) > CSET_DWL) #define DBLCS_BITS 4 #define DBLCS_MASK BITS2MASK(DBLCS_BITS) #define GetLineDblCS(ld) ((ld) != NULL ? (((ld)->bufHead >> LINEFLAG_BITS) & DBLCS_MASK) : 0) #define SetLineDblCS(ld,cs) (ld)->bufHead = (RowData) ((ld->bufHead & LINEFLAG_MASK) | (cs << LINEFLAG_BITS)) #define LineCharSet(screen, ld) \ (unsigned) ((CSET_DOUBLE(GetLineDblCS(ld))) \ ? GetLineDblCS(ld) \ : (screen)->cur_chrset) #define LineMaxCol(screen, ld) \ (CSET_DOUBLE(GetLineDblCS(ld)) \ ? (screen->max_col / 2) \ : (screen->max_col)) #define LineCursorX(screen, ld, col) \ (CSET_DOUBLE(GetLineDblCS(ld)) \ ? CursorX(screen, 2*(col)) \ : CursorX(screen, (col))) #define LineFontWidth(screen, ld) \ (CSET_DOUBLE(GetLineDblCS(ld)) \ ? 2*FontWidth(screen) \ : FontWidth(screen)) #else #define if_OPT_DEC_CHRSET(code) /*nothing*/ #define CSET_SWL 0 #define GetLineDblCS(ld) 0U #define LineCharSet(screen, ld) 0U #define LineMaxCol(screen, ld) screen->max_col #define LineCursorX(screen, ld, col) CursorX(screen, col) #define LineFontWidth(screen, ld) FontWidth(screen) #endif #if OPT_LUIT_PROG && !OPT_WIDE_CHARS /* Luit requires the wide-chars configuration */ #undef OPT_LUIT_PROG #define OPT_LUIT_PROG 0 #endif /***====================================================================***/ #if OPT_DEC_RECTOPS #define if_OPT_DEC_RECTOPS(stmt) stmt #else #define if_OPT_DEC_RECTOPS(stmt) /* nothing */ #endif /***====================================================================***/ #define CONTROL(a) ((a) & 037) #define XTERM_ERASE CONTROL('H') #define XTERM_LNEXT CONTROL('V') /***====================================================================***/ #if OPT_TEK4014 #define TEK4014_ACTIVE(xw) ((xw)->misc.TekEmu) #define TEK4014_SHOWN(xw) ((xw)->misc.Tshow) #define CURRENT_EMU_VAL(tek,vt) (TEK4014_ACTIVE(term) ? tek : vt) #define CURRENT_EMU() CURRENT_EMU_VAL((Widget)tekWidget, (Widget)term) #else #define TEK4014_ACTIVE(screen) 0 #define TEK4014_SHOWN(xw) 0 #define CURRENT_EMU_VAL(tek,vt) (vt) #define CURRENT_EMU() ((Widget)term) #endif /***====================================================================***/ #if OPT_TOOLBAR #define SHELL_OF(widget) XtParent(XtParent(widget)) #else #define SHELL_OF(widget) XtParent(widget) #endif /***====================================================================***/ #if OPT_VT52_MODE #define if_OPT_VT52_MODE(screen, code) if(screen->vtXX_level == 0) code #else #define if_OPT_VT52_MODE(screen, code) /* nothing */ #endif /***====================================================================***/ #if OPT_XMC_GLITCH #define if_OPT_XMC_GLITCH(screen, code) if(screen->xmc_glitch) code #define XMC_GLITCH 1 /* the character we'll show */ #define XMC_FLAGS (INVERSE|UNDERLINE|BOLD|BLINK) #else #define if_OPT_XMC_GLITCH(screen, code) /* nothing */ #endif /***====================================================================***/ typedef unsigned IFlags; /* at least 32 bits */ #if OPT_WIDE_ATTRS typedef unsigned short IAttr; /* at least 16 bits */ #else typedef unsigned char IAttr; /* at least 8 bits */ #endif /***====================================================================***/ #define LO_BYTE(ch) CharOf((ch) & 0xff) #define HI_BYTE(ch) CharOf((ch) >> 8) #if OPT_WIDE_CHARS #define if_OPT_WIDE_CHARS(screen, code) if(screen->wide_chars) code #define if_WIDE_OR_NARROW(screen, wide, narrow) if(screen->wide_chars) wide else narrow #define NARROW_ICHAR 0xffff #if OPT_WIDER_ICHAR #define is_NON_CHAR(c) (((c) >= 0xffd0 && (c) <= 0xfdef) || \ (((c) & 0xffff) >= 0xfffe)) #define is_UCS_SPECIAL(c) ((c) >= 0xfff0 && (c) <= 0xffff) #define WIDEST_ICHAR 0x1fffff typedef unsigned IChar; /* for 8-21 bit characters */ #else #define is_NON_CHAR(c) (((c) >= 0xffd0 && (c) <= 0xfdef) || \ ((c) >= 0xfffe && (c) <= 0xffff)) #define is_UCS_SPECIAL(c) ((c) >= 0xfff0) #define WIDEST_ICHAR NARROW_ICHAR typedef unsigned short IChar; /* for 8-16 bit characters */ #endif #else /* !OPT_WIDE_CHARS */ #undef OPT_WIDER_ICHAR #define OPT_WIDER_ICHAR 0 #define is_NON_CHAR(c) ((c) > 255) #define if_OPT_WIDE_CHARS(screen, code) /* nothing */ #define if_WIDE_OR_NARROW(screen, wide, narrow) narrow typedef unsigned char IChar; /* for 8-bit characters */ #endif /***====================================================================***/ #ifndef RES_OFFSET #define RES_OFFSET(offset) XtOffsetOf(XtermWidgetRec, offset) #endif #define RES_NAME(name) name #define RES_CLASS(name) name #define Bres(name, class, offset, dftvalue) \ {RES_NAME(name), RES_CLASS(class), XtRBoolean, sizeof(Boolean), \ RES_OFFSET(offset), XtRImmediate, (XtPointer) dftvalue} #define Cres(name, class, offset, dftvalue) \ {RES_NAME(name), RES_CLASS(class), XtRPixel, sizeof(Pixel), \ RES_OFFSET(offset), XtRString, DECONST(char,dftvalue)} #define Tres(name, class, offset, dftvalue) \ COLOR_RES2(name, class, screen.Tcolors[offset], dftvalue) \ #define Fres(name, class, offset, dftvalue) \ {RES_NAME(name), RES_CLASS(class), XtRFontStruct, sizeof(XFontStruct *), \ RES_OFFSET(offset), XtRString, DECONST(char,dftvalue)} #define Ires(name, class, offset, dftvalue) \ {RES_NAME(name), RES_CLASS(class), XtRInt, sizeof(int), \ RES_OFFSET(offset), XtRImmediate, (XtPointer) dftvalue} #define Dres(name, class, offset, dftvalue) \ {RES_NAME(name), RES_CLASS(class), XtRFloat, sizeof(float), \ RES_OFFSET(offset), XtRString, DECONST(char,dftvalue)} #define Sres(name, class, offset, dftvalue) \ {RES_NAME(name), RES_CLASS(class), XtRString, sizeof(char *), \ RES_OFFSET(offset), XtRString, DECONST(char,dftvalue)} #define Wres(name, class, offset, dftvalue) \ {RES_NAME(name), RES_CLASS(class), XtRWidget, sizeof(Widget), \ RES_OFFSET(offset), XtRWidget, (XtPointer) dftvalue} /***====================================================================***/ #define FRG_SIZE resource.minBufSize #define BUF_SIZE resource.maxBufSize typedef struct { Char *next; Char *last; int update; /* HandleInterpret */ #if OPT_WIDE_CHARS IChar utf_data; /* resulting character */ size_t utf_size; /* ...number of bytes decoded */ Char *write_buf; size_t write_len; #endif Char buffer[1]; } PtyData; /***====================================================================***/ /* * Pixel (and its components) are declared as unsigned long, but even for RGB * we need no more than 32-bits. */ typedef uint32_t MyPixel; typedef int32_t MyColor; #if OPT_ISO_COLORS #if OPT_DIRECT_COLOR typedef struct { MyColor fg; MyColor bg; } CellColor; #define isSameCColor(p,q) (!memcmp(&(p), &(q), sizeof(CellColor))) #elif OPT_256_COLORS || OPT_88_COLORS #define COLOR_BITS 8 typedef unsigned short CellColor; #else #define COLOR_BITS 4 typedef Char CellColor; #endif #else typedef unsigned CellColor; #endif #define NO_COLOR ((unsigned)-1) #ifndef isSameCColor #define isSameCColor(p,q) ((p) == (q)) #endif #define BITS2MASK(b) (xBIT(b) - 1) #define COLOR_MASK BITS2MASK(COLOR_BITS) #if OPT_DIRECT_COLOR #define clrDirectFG(flags) UIntClr(flags, ATR_DIRECT_FG) #define clrDirectBG(flags) UIntClr(flags, ATR_DIRECT_BG) #define GetCellColorFG(data) ((data).fg) #define GetCellColorBG(data) ((data).bg) #define hasDirectFG(flags) ((flags) & ATR_DIRECT_FG) #define hasDirectBG(flags) ((flags) & ATR_DIRECT_BG) #define setDirectFG(flags,test) if (test) UIntSet(flags, ATR_DIRECT_FG); else UIntClr(flags, ATR_DIRECT_FG) #define setDirectBG(flags,test) if (test) UIntSet(flags, ATR_DIRECT_BG); else UIntClr(flags, ATR_DIRECT_BG) #elif OPT_ISO_COLORS #define clrDirectFG(flags) /* nothing */ #define clrDirectBG(flags) /* nothing */ #define GetCellColorFG(data) ((data) & COLOR_MASK) #define GetCellColorBG(data) (((data) >> COLOR_BITS) & COLOR_MASK) #define hasDirectFG(flags) 0 #define hasDirectBG(flags) 0 #define setDirectFG(flags,test) (void)(test) #define setDirectBG(flags,test) (void)(test) #else #define GetCellColorFG(data) 7 #define GetCellColorBG(data) 0 #endif extern CellColor blank_cell_color; typedef Char RowData; /* wrap/blink, and DEC single-double chars */ #define LINEFLAG_BITS 4 #define LINEFLAG_MASK BITS2MASK(LINEFLAG_BITS) #define GetLineFlags(ld) ((ld)->bufHead & LINEFLAG_MASK) #if OPT_DEC_CHRSET #define SetLineFlags(ld,xx) (ld)->bufHead = (RowData) ((ld->bufHead & (DBLCS_MASK << LINEFLAG_BITS)) | (xx & LINEFLAG_MASK)) #else #define SetLineFlags(ld,xx) (ld)->bufHead = (RowData) (xx & LINEFLAG_MASK) #endif typedef IChar CharData; /* * This is the xterm line-data/scrollback structure. */ typedef struct { Dimension lineSize; /* number of columns in this row */ RowData bufHead; /* flag for wrapped lines */ #if OPT_WIDE_CHARS Char combSize; /* number of items in combData[] */ #endif #if OPT_DEC_RECTOPS Char *charSets; /* SCS code (DECNRCM_codes) */ Char *charSeen; /* pre-SCS value */ #endif IAttr *attribs; /* video attributes */ #if OPT_ISO_COLORS CellColor *color; /* foreground+background color numbers */ #endif CharData *charData; /* cell's base character */ CharData *combData[1]; /* first field past fixed-offsets */ } LineData; typedef const LineData CLineData; /* * We use CellData in a few places, when copying a cell's data to a temporary * variable. */ typedef struct { IAttr attribs; /* video attributes */ #if OPT_WIDE_CHARS Char combSize; /* number of items in combData[] */ #endif #if OPT_DEC_RECTOPS Char charSets; /* SCS code (DECNRCM_codes) */ Char charSeen; /* pre-SCS value */ #endif #if OPT_ISO_COLORS CellColor color; /* foreground+background color numbers */ #endif CharData charData; /* cell's base character */ CharData combData[1]; /* array of combining chars */ } CellData; #define for_each_combData(off, ld) for (off = 0; off < ld->combSize; ++off) #define Clear1Cell(ld, x) \ do { \ ld->charData[x] = ' '; \ do { \ if_OPT_WIDE_CHARS(screen, { \ size_t z; \ for_each_combData(z, ld) { \ ld->combData[z][x] = '\0'; \ } \ }) } while (0); \ } while (0) #define Clear2Cell(dst, src, x) \ do { \ dst->charData[x] = ' '; \ dst->attribs[x] = src->attribs[x]; \ do { \ if_OPT_ISO_COLORS(screen, { \ dst->color[x] = src->color[x]; \ }) } while (0); \ do { \ if_OPT_WIDE_CHARS(screen, { \ size_t z; \ for_each_combData(z, dst) { \ dst->combData[z][x] = '\0'; \ } \ }) } while (0); \ } while (0) /* * Accommodate older compilers by not using variable-length arrays. */ #define SizeOfLineData offsetof(LineData, combData) #define SizeOfCellData offsetof(CellData, combData) /* * CellData size depends on the "combiningChars" resource. */ #define CellDataSize(screen) (SizeOfCellData + screen->cellExtra) /* * A "row" is the index within the visible part of the screen, and an * "inx" is the index within the whole set of scrollable lines. */ #define ROW2INX(screen, row) ((row) + (screen)->topline) #define INX2ROW(screen, inx) ((inx) - (screen)->topline) /* these are unused but could be useful for debugging */ #if 0 #define ROW2ABS(screen, row) ((row) + (screen)->savedlines) #define INX2ABS(screen, inx) ROW2ABS(screen, INX2ROW(screen, inx)) #endif #define okScrnRow(screen, row) \ ((row) <= ((screen)->max_row - (screen)->topline) \ && (row) >= -((screen)->savedlines)) /* * Cache data for "proportional" and other fonts containing a mixture * of widths. */ typedef struct { Bool mixed; Dimension min_width; /* nominal cell width for 0..255 */ Dimension max_width; /* maximum cell width */ } XTermFontInfo; /* * Map of characters to simplify/speed-up the checks for missing glyphs * at runtime. * * FIXME: initially implement for Xft, but replace known_missing[] in * X11 fonts as well. */ typedef Char XTfontNum; typedef struct { int depth; /* number of fonts merged for map */ size_t limit; /* allocated size of per_font, etc */ size_t first_char; /* merged first-character index */ size_t last_char; /* merged last-character index */ XTfontNum * per_font; /* index 1-n of first font with char */ } XTermFontMap; typedef enum { fwNever = 0, fwResource, fwAlways } fontWarningTypes; typedef struct { unsigned chrset; unsigned flags; fontWarningTypes warn; XFontStruct * fs; char * fn; XTermFontInfo font_info; Char known_missing[MaxUChar + 1]; } XTermFonts; #if OPT_RENDERFONT typedef enum { erFalse = 0 , erTrue , erDefault , erDefaultOff , erLast } RenderFont; #define DefaultRenderFont(xw) \ if ((xw)->work.render_font == erDefault) \ (xw)->work.render_font = erFalse typedef enum { xcEmpty = 0 /* slot is unused */ , xcBogus /* ignore this pattern */ , xcOpened /* slot has open font descriptor */ , xcUnused /* opened, but unused so far */ } XTermXftState; typedef struct { XftFont * font; XTermXftState usage; } XTermXftCache; #define MaxXftCache MaxUChar typedef struct { XftPattern * pattern; /* pattern for main font */ XftFontSet * fontset; /* ordered list of fallback patterns */ XTermXftCache cache[MaxXftCache + 1]; /* list of open font pointers */ int fs_size; /* last usable index of cache[] */ Char opened; /* number in cache[] with xcOpened */ XTermFontInfo font_info; /* summary of font metrics */ XTermFontMap font_map; /* map of glyphs provided in fontset */ } XTermXftFonts; #define XftFpN(p,n) (p)->cache[(n)].font #define XftIsN(p,n) (p)->cache[(n)].usage #define XftFp(p) XftFpN(p,0) #define XftIs(p) XftIsN(p,0) typedef struct _ListXftFonts { struct _ListXftFonts *next; XftFont * font; } ListXftFonts; #endif typedef struct { int top; int left; int bottom; int right; } XTermRect; /***====================================================================***/ /* indices into save_modes[] */ typedef enum { DP_ALLOW_ALTBUF, DP_ALTERNATE_SCROLL, DP_ALT_SENDS_ESC, DP_BELL_IS_URGENT, DP_CRS_VISIBLE, DP_DECANM, DP_DECARM, DP_DECAWM, DP_DECBKM, DP_DECCKM, DP_DECCOLM, /* IN132COLUMNS */ DP_DECKPAM, DP_DECNRCM, DP_DECOM, DP_DECPEX, DP_DECPFF, DP_DECSCLM, DP_DECSCNM, DP_DECTCEM, DP_DELETE_IS_DEL, DP_EIGHT_BIT_META, DP_FAST_SCROLL, DP_KEEP_CLIPBOARD, DP_KEEP_SELECTION, DP_KEYBOARD_TYPE, DP_POP_ON_BELL, DP_PRN_EXTENT, DP_PRN_FORMFEED, DP_RXVT_SCROLLBAR, DP_RXVT_SCROLL_TTY_KEYPRESS, DP_RXVT_SCROLL_TTY_OUTPUT, DP_SELECT_TO_CLIPBOARD, DP_X_ALTBUF, DP_X_DECCOLM, DP_X_EXT_MOUSE, DP_X_LOGGING, DP_X_LRMM, DP_X_MARGIN, DP_X_MORE, DP_X_MOUSE, DP_X_NCSM, DP_X_REVWRAP, DP_X_REVWRAP2, DP_X_X10MSE, #if OPT_BLINK_CURS DP_CRS_BLINK, #endif #if OPT_FOCUS_EVENT DP_X_FOCUS, #endif #if OPT_NUM_LOCK DP_REAL_NUMLOCK, DP_META_SENDS_ESC, #endif #if OPT_SHIFT_FONTS DP_RXVT_FONTSIZE, #endif #if OPT_SIXEL_GRAPHICS DP_DECSDM, #endif #if OPT_TEK4014 DP_DECTEK, #endif #if OPT_TOOLBAR DP_TOOLBAR, #endif #if OPT_GRAPHICS DP_X_PRIVATE_COLOR_REGISTERS, #endif #if OPT_SIXEL_GRAPHICS DP_SIXEL_SCROLLS_RIGHT, #endif #if OPT_PRINT_GRAPHICS DP_DECGEPM, /* Graphics Expanded Print Mode */ DP_DECGPCM, /* Graphics Print Color Mode */ DP_DECGPCS, /* Graphics Print Color Syntax */ DP_DECGPBM, /* Graphics Print Background Mode */ DP_DECGRPM, /* Graphics Rotated Print Mode */ #endif DP_LAST } SaveModes; #define DoSM(code,value) screen->save_modes[code] = (unsigned) (value) #define DoRM(code,value) value = (Boolean) screen->save_modes[code] #define DoRM0(code,value) value = screen->save_modes[code] /* index into vt_shell[] or tek_shell[] */ typedef enum { noMenu = -1 ,mainMenu ,vtMenu ,fontMenu #if OPT_TEK4014 ,tekMenu #endif } MenuIndex; typedef enum { bvOff = -1, bvLow = 0, bvHigh } BellVolume; #define NUM_POPUP_MENUS 4 typedef struct { String resource; Pixel value; unsigned short red, green, blue; int mode; /* -1=invalid, 0=unset, 1=set */ } ColorRes; /* these are set in getPrinterFlags */ typedef struct { int printer_extent; /* print complete page */ int printer_formfeed; /* print formfeed per function */ int printer_newline; /* print newline per function */ int print_attributes; /* 0=off, 1=normal, 2=color */ int print_everything; /* 0=all, 1=dft, 2=alt, 3=saved */ } PrinterFlags; typedef struct { FILE * fp; /* output file/pipe used */ Boolean isOpen; /* output was opened/tried */ Boolean toFile; /* true when directly to file */ Boolean printer_checked; /* printer_command is checked */ String printer_command; /* pipe/shell command string */ Boolean printer_autoclose; /* close printer when offline */ Boolean printer_extent; /* print complete page */ Boolean printer_formfeed; /* print formfeed per function */ Boolean printer_newline; /* print newline per function */ int printer_controlmode; /* 0=off, 1=auto, 2=controller */ int print_attributes; /* 0=off, 1=normal, 2=color */ int print_everything; /* 0=all, 1=dft, 2=alt, 3=saved */ } PrinterState; typedef struct { unsigned which; /* must have NCOLORS bits */ Pixel colors[NCOLORS]; char *names[NCOLORS]; } ScrnColors; #define NUM_GSETS 4 #define NUM_GSETS2 (NUM_GSETS + 1) /* include user-preferred */ #define gsets_upss gsets[4] #define SAVED_CURSORS 2 typedef struct { Boolean saved; int row; int col; IFlags flags; /* VTxxx saves graphics rendition */ Char curgl; Char curgr; DECNRCM_codes gsets[NUM_GSETS2]; Boolean wrap_flag; #if OPT_ISO_COLORS int cur_foreground; /* current foreground color */ int cur_background; /* current background color */ int sgr_foreground; /* current SGR foreground color */ int sgr_background; /* current SGR background color */ Boolean sgr_38_xcolors; /* true if ISO 8613 extension */ #endif } SavedCursor; typedef struct _SaveTitle { struct _SaveTitle *next; char *iconName; char *windowName; } SaveTitle; #define MAX_SAVED_TITLES 10 typedef struct { int used; /* index to current item */ SaveTitle data[MAX_SAVED_TITLES]; } SavedTitles; typedef struct { int width; /* if > 0, width of scrollbar, */ /* and scrollbar is showing */ Boolean rv_cached; /* see ScrollBarReverseVideo */ int rv_active; /* ...current reverse-video */ Pixel bg; /* ...cached background color */ Pixel fg; /* ...cached foreground color */ Pixel bdr; /* ...cached border color */ Pixmap bdpix; /* ...cached border pixmap */ } SbInfo; #if OPT_TOOLBAR typedef struct { Widget menu_bar; /* toolbar, if initialized */ Dimension menu_height; /* ...and its height */ Dimension menu_border; /* ...and its border */ } TbInfo; #define VT100_TB_INFO(name) screen.fullVwin.tb_info.name #endif typedef struct { Window window; /* X window id */ int width; /* width of columns in pixels */ int height; /* height of rows in pixels */ Dimension fullwidth; /* full width of window */ Dimension fullheight; /* full height of window */ int f_width; /* width of fonts in pixels */ int f_height; /* height of fonts in pixels */ int f_ascent; /* ascent of font in pixels */ int f_descent; /* descent of font in pixels */ SbInfo sb_info; GC filler_gc; /* filler's fg/bg */ GC border_gc; /* inner border's fg/bg */ GC marker_gc[2]; /* wrap-marks */ #if USE_DOUBLE_BUFFER Drawable drawable; /* X drawable id */ #endif #if OPT_TOOLBAR Boolean active; /* true if toolbars are used */ TbInfo tb_info; /* toolbar information */ #endif } VTwin; typedef struct { Window window; /* X window id */ int width; /* width of columns */ int height; /* height of rows */ Dimension fullwidth; /* full width of window */ Dimension fullheight; /* full height of window */ double tekscale; /* scale factor Tek -> vs100 */ } TKwin; typedef struct { char *f_n; /* the normal font */ char *f_b; /* the bold font */ #if OPT_WIDE_CHARS char *f_w; /* the normal wide font */ char *f_wb; /* the bold wide font */ #endif } VTFontNames; typedef struct { char **list_n; /* the normal font */ char **list_b; /* the bold font */ #if OPT_WIDE_ATTRS || OPT_RENDERWIDE char **list_i; /* italic font (Xft only) */ char **list_bi; /* bold-italic font (Xft only) */ #endif #if OPT_WIDE_CHARS char **list_w; /* the normal wide font */ char **list_wb; /* the bold wide font */ char **list_wi; /* wide italic font (Xft only) */ char **list_wbi; /* wide bold-italic font (Xft only) */ #endif } VTFontList; typedef struct { VTFontList x11; #if OPT_RENDERFONT VTFontList xft; #endif } XtermFontNames; typedef struct { VTFontNames default_font; String menu_font_names[NMENUFONTS][fMAX]; XtermFontNames fonts; } SubResourceRec; #if OPT_INPUT_METHOD #define NINPUTWIDGETS 3 typedef struct { Widget w; XIM xim; /* input method attached to 'w' */ XIC xic; /* input context attached to 'xim' */ } TInput; #endif typedef enum { CURSOR_BLOCK = 2 , CURSOR_UNDERLINE = 4 , CURSOR_BAR = 6 } XtCursorShape; #define isCursorBlock(s) ((s)->cursor_shape == CURSOR_BLOCK) #define isCursorUnderline(s) ((s)->cursor_shape == CURSOR_UNDERLINE) #define isCursorBar(s) ((s)->cursor_shape == CURSOR_BAR) typedef enum { DEFAULT_STYLE = 0 , BLINK_BLOCK , STEADY_BLOCK , BLINK_UNDERLINE , STEADY_UNDERLINE , BLINK_BAR , STEADY_BAR } XtCursorStyle; #if OPT_GRAPHICS #define GraphicsTermId(screen) (\ (screen)->graphics_termid \ ? (screen)->graphics_termid \ : (screen)->terminal_id) #else #define GraphicsTermId(screen) (screen)->terminal_id #endif #if OPT_REGIS_GRAPHICS #define optRegisGraphics(screen) \ (GraphicsTermId(screen) == 125 || \ GraphicsTermId(screen) == 240 || \ GraphicsTermId(screen) == 241 || \ GraphicsTermId(screen) == 330 || \ GraphicsTermId(screen) == 340) #else #define optRegisGraphics(screen) False #endif #if OPT_SIXEL_GRAPHICS #define optSixelGraphics(screen) \ (GraphicsTermId(screen) == 240 || \ GraphicsTermId(screen) == 241 || \ GraphicsTermId(screen) == 330 || \ GraphicsTermId(screen) == 340 || \ GraphicsTermId(screen) == 382) #else #define optSixelGraphics(screen) False #endif #if OPT_PRINT_GRAPHICS #define if_PRINT_GRAPHICS2(statement) if (optRegisGraphics(screen)) { statement; } else #else #define if_PRINT_GRAPHICS2(statement) /* nothing */ #endif typedef struct { /* These parameters apply to both windows */ Display *display; /* X display for screen */ int respond; /* socket for responses (position report, etc.) */ int nextEventDelay; /* msecs to delay for x-events */ /* These parameters apply to VT100 window */ IChar *unparse_bfr; unsigned unparse_len; unsigned unparse_max; /* limitResponse resource */ unsigned strings_max; /* maxStringParse resource */ #if OPT_TCAP_QUERY int tc_query_code; Bool tc_query_fkey; #endif pid_t pid; /* pid of process on far side */ uid_t uid; /* user id of actual person */ gid_t gid; /* group id of actual person */ ColorRes Tcolors[NCOLORS]; /* terminal colors */ #if OPT_HIGHLIGHT_COLOR Boolean hilite_color; /* hilite colors override */ Boolean hilite_reverse; /* hilite overrides reverse */ #endif #if OPT_ISO_COLORS XColor * cmap_data; /* color table */ unsigned cmap_size; ColorRes Acolors[MAXCOLORS]; /* ANSI color emulation */ int veryBoldColors; /* modifier for boldColors */ Boolean boldColors; /* can we make bold colors? */ Boolean colorMode; /* are we using color mode? */ Boolean colorULMode; /* use color for underline? */ Boolean italicULMode; /* italic font for underline? */ Boolean colorBDMode; /* use color for bold? */ Boolean colorBLMode; /* use color for blink? */ Boolean colorRVMode; /* use color for reverse? */ Boolean colorAttrMode; /* prefer colorUL/BD to SGR */ #if OPT_WIDE_ATTRS Boolean colorITMode; /* use color for italics? */ #endif #if OPT_DIRECT_COLOR Boolean direct_color; /* direct-color enabled? */ #endif #if OPT_WIDE_ATTRS && OPT_SGR2_HASH Boolean faint_relative; /* faint is relative? */ #endif #if OPT_VT525_COLORS int assigned_fg; /* DECAC */ int assigned_bg; struct { int fg; /* 0..15 */ int bg; /* 0..15 */ } alt_colors[16]; /* DECATC if DECSTGLT is 1 or 2 */ #endif #endif /* OPT_ISO_COLORS */ #if OPT_DEC_CHRSET Boolean font_doublesize;/* enable font-scaling */ int cache_doublesize;/* limit of our cache */ Char cur_chrset; /* character-set index & code */ int fonts_used; /* count items in double_fonts */ XTermFonts double_fonts[NUM_CHRSET]; #if OPT_RENDERFONT XTermXftFonts double_xft_fonts[NUM_CHRSET]; #endif #endif /* OPT_DEC_CHRSET */ #if OPT_DEC_RECTOPS int cur_decsace; /* parameter for DECSACE */ int checksum_ext; /* extensions for DECRQCRA */ int checksum_ext0; /* initial checksumExtension */ #endif #if OPT_WIDE_CHARS Boolean wide_chars; /* true when 16-bit chars */ Boolean vt100_graphics; /* true to allow vt100-graphics */ Boolean utf8_inparse; /* true to enable UTF-8 parser */ Boolean normalized_c; /* true to precompose to Form C */ char * utf8_mode_s; /* use UTF-8 decode/encode */ char * utf8_fonts_s; /* use UTF-8 decode/encode */ char * utf8_title_s; /* use UTF-8 titles */ int utf8_nrc_mode; /* saved UTF-8 mode for DECNRCM */ Boolean utf8_always; /* special case for wideChars */ int utf8_mode; /* use UTF-8 decode/encode: 0-2 */ int utf8_fonts; /* use UTF-8 fonts: 0-2 */ int utf8_title; /* use UTF-8 EWHM props: 0-2 */ int max_combining; /* maximum # of combining chars */ Boolean utf8_latin1; /* use UTF-8 with Latin-1 bias */ Boolean utf8_weblike; /* use UTF-8 with browser bias */ int latin9_mode; /* poor man's luit, latin9 */ int unicode_font; /* font uses unicode encoding */ int utf_count; /* state of utf_char */ IChar utf_char; /* in-progress character */ Boolean char_was_written; int last_written_col; int last_written_row; #endif TypedBuffer(IChar); TypedBuffer(Char); TypedBuffer(XChar2b); #if OPT_BROKEN_OSC Boolean brokenLinuxOSC; /* true to ignore Linux palette ctls */ #endif #if OPT_BROKEN_ST Boolean brokenStringTerm; /* true to match old OSC parse */ #endif #if OPT_C1_PRINT || OPT_WIDE_CHARS Boolean c1_printable; /* true if we treat C1 as print */ #endif int border; /* inner border */ int scrollBarBorder; /* scrollBar border */ long event_mask; unsigned send_mouse_pos; /* user wants mouse transition */ /* and position information */ int extend_coords; /* support large terminals */ #if OPT_FOCUS_EVENT Boolean send_focus_pos; /* user wants focus in/out info */ #endif Boolean quiet_grab; /* true if no cursor change on focus */ #if OPT_PASTE64 Cardinal base64_paste; /* set to send paste in base64 */ int base64_final; /* string-terminator for paste */ /* _qWriteSelectionData expects these to be initialized to zero. * base64_flush() is the last step of the conversion, it clears these * variables. */ unsigned base64_accu; unsigned base64_count; unsigned base64_pad; #endif #if OPT_PASTE64 || OPT_READLINE unsigned paste_brackets; /* not part of bracketed-paste, these are here to simplify ifdefs */ unsigned dclick3_deletes; unsigned paste_literal_nl; #endif #if OPT_READLINE unsigned click1_moves; unsigned paste_moves; unsigned paste_quotes; #endif /* OPT_READLINE */ #if OPT_DEC_LOCATOR Boolean locator_reset; /* turn mouse off after 1 report? */ Boolean locator_pixels; /* report in pixels? */ /* if false, report in cells */ unsigned locator_events; /* what events to report */ Boolean loc_filter; /* is filter rectangle active? */ int loc_filter_top; /* filter rectangle for DEC Locator */ int loc_filter_left; int loc_filter_bottom; int loc_filter_right; #endif /* OPT_DEC_LOCATOR */ int mouse_button; /* current button pressed */ int mouse_row; /* ...and its row */ int mouse_col; /* ...and its column */ int select; /* xterm selected */ Boolean bellOnReset; /* bellOnReset */ Boolean visualbell; /* visual bell mode */ Boolean poponbell; /* pop on bell mode */ Boolean eraseSavedLines; /* eraseSavedLines option */ Boolean eraseSavedLines0; /* initial eraseSavedLines */ Boolean tabCancelsWrap; /* tabCancelsWrap option */ Boolean allowPasteControls; /* PasteControls mode */ Boolean allowColorOps; /* ColorOps mode */ Boolean allowFontOps; /* FontOps mode */ Boolean allowMouseOps; /* MouseOps mode */ Boolean allowSendEvents;/* SendEvent mode */ Boolean allowTcapOps; /* TcapOps mode */ Boolean allowTitleOps; /* TitleOps mode */ Boolean allowWindowOps; /* WindowOps mode */ Boolean allowPasteControl0; /* PasteControls mode */ Boolean allowColorOp0; /* initial ColorOps mode */ Boolean allowFontOp0; /* initial FontOps mode */ Boolean allowMouseOp0; /* initial MouseOps mode */ Boolean allowSendEvent0;/* initial SendEvent mode */ Boolean allowTcapOp0; /* initial TcapOps mode */ Boolean allowTitleOp0; /* initial TitleOps mode */ Boolean allowWindowOp0; /* initial WindowOps mode */ String disallowedColorOps; char disallow_color_ops[ecLAST]; String disallowedFontOps; char disallow_font_ops[efLAST]; String disallowedMouseOps; char disallow_mouse_ops[emLAST]; String disallowedPasteOps; char disallow_paste_ops[epLAST]; String disallowedTcapOps; char disallow_tcap_ops[etLAST]; String disallowedWinOps; char disallow_win_ops[ewLAST]; char color_events[1+OSC_NCOLORS]; /* ok OSC codes */ char * colorEvents; /* initial color-event codes */ Boolean awaitInput; /* select-timeout mode */ Boolean grabbedKbd; /* keyboard is grabbed */ #ifdef ALLOWLOGGING int logging; /* logging mode */ int logfd; /* file descriptor of log */ char *logfile; /* log file name */ Char *logstart; /* current start of log buffer */ #endif int inhibit; /* flags for inhibiting changes */ /* VT window parameters */ Boolean Vshow; /* VT window showing */ VTwin fullVwin; int needSwap; #ifndef NO_ACTIVE_ICON VTwin iconVwin; VTwin *whichVwin; #endif /* NO_ACTIVE_ICON */ int pointer_mode; /* when to use hidden_cursor */ int pointer_mode0; /* ...initial value */ Boolean hide_pointer; /* true to use "hidden_cursor" */ String pointer_shape; /* name of shape in cursor font */ Cursor pointer_cursor; /* current pointer cursor */ Cursor hidden_cursor; /* hidden cursor in window */ String answer_back; /* response to ENQ */ Boolean prefer_latin1; /* preference for UPSS */ PrinterState printer_state; /* actual printer state */ PrinterFlags printer_flags; /* working copy of printer flags */ Boolean print_rawchars; /* true to ignore printer check */ #if OPT_PRINT_ON_EXIT Boolean write_error; #endif Boolean fnt_prop; /* true if proportional fonts */ unsigned fnt_boxes; /* 0=no boxes, 1=old, 2=unicode */ Boolean force_packed; /* true to override proportional */ #if OPT_BOX_CHARS Boolean force_box_chars;/* true if we assume no boxchars */ Boolean broken_box_chars;/* true if broken boxchars */ Boolean assume_all_chars;/* true to allow missing chars */ Boolean allow_packing; /* true to allow packed-fonts */ #endif #if OPT_BOX_CHARS || OPT_WIDE_CHARS Boolean force_all_chars;/* true to outline missing chars */ #endif Dimension fnt_wide; Dimension fnt_high; float scale_height; /* scaling for font-height */ XTermFonts fnts[fMAX]; /* normal/bold/etc for terminal */ Boolean free_bold_box; /* same_font_size's austerity */ Boolean allowBoldFonts; /* do we use bold fonts at all? */ #if OPT_WIDE_ATTRS XTermFonts ifnts[fMAX]; /* normal/bold/etc italic fonts */ Boolean ifnts_ok; /* true if ifnts[] is cached */ #endif #ifndef NO_ACTIVE_ICON XTermFonts fnt_icon; /* icon font */ String icon_fontname; /* name of icon font */ int icon_fontnum; /* number to use for icon font */ #endif /* NO_ACTIVE_ICON */ int enbolden; /* overstrike for bold font */ XPoint *box; /* draw unselected cursor */ int cursor_state; /* ON, OFF, or BLINKED_OFF */ int cursor_busy; /* do not redraw... */ Boolean cursor_underline; /* true if cursor is in underline mode */ Boolean cursor_bar; /* true if cursor is in bar mode */ XtCursorShape cursor_shape; #if OPT_BLINK_CURS BlinkOps cursor_blink; /* cursor blink enable */ BlinkOps cursor_blink_i; /* save cursor blink enable */ char * cursor_blink_s; /* ...resource cursorBlink */ int cursor_blink_esc; /* cursor blink escape-state */ Boolean cursor_blink_xor; /* how to merge menu/escapes */ #endif #if OPT_BLINK_TEXT Boolean blink_as_bold; /* text blink disable */ #endif #if OPT_BLINK_CURS || OPT_BLINK_TEXT int blink_state; /* ON, OFF, or BLINKED_OFF */ int blink_on; /* cursor on time (msecs) */ int blink_off; /* cursor off time (msecs) */ XtIntervalId blink_timer; /* timer-id for cursor-proc */ #endif #if OPT_ZICONBEEP Boolean zIconBeep_flagged; /* True if icon name was changed */ #endif /* OPT_ZICONBEEP */ int cursor_GC; /* see ShowCursor() */ int cursor_set; /* requested state */ CELL cursorp; /* previous cursor row/column */ int cur_col; /* current cursor column */ int cur_row; /* current cursor row */ int max_col; /* rightmost column */ int max_row; /* bottom row */ int top_marg; /* top line of scrolling region */ int bot_marg; /* bottom line of " " */ int lft_marg; /* left column of " " */ int rgt_marg; /* right column of " " */ Widget scrollWidget; /* pointer to scrollbar struct */ #if USE_DOUBLE_BUFFER int buffered_sb; /* nonzero when pending update */ struct timeval buffered_at; /* reference time, for FPS */ #define DbeMsecs(xw) (1000L / (long) resource.buffered_fps) #endif /* * Indices used to keep track of the top of the vt100 window and * the saved lines, taking scrolling into account. */ int topline; /* line number of top, <= 0 */ long saved_fifo; /* number of lines that've ever been saved */ int savedlines; /* number of lines that've been saved */ int savelines; /* number of lines off top to save */ int scroll_amt; /* amount to scroll */ int refresh_amt; /* amount to refresh */ /* * Working variables for getLineData(). */ size_t lineExtra; /* extra space for combining chars */ size_t cellExtra; /* extra space for combining chars */ /* * Pointer to the current visible buffer. */ ScrnBuf visbuf; /* ptr to visible screen buf (main) */ /* * Data for the normal buffer, which may have saved lines to which * the user can scroll. */ ScrnBuf saveBuf_index; Char *saveBuf_data; /* * Data for visible and alternate buffer. */ ScrnBuf editBuf_index[2]; Char *editBuf_data[2]; int whichBuf; /* 0/1 for normal/alternate buf */ Boolean is_running; /* true when buffers are legal */ /* * Workspace used for screen operations. */ Char **save_ptr; /* workspace for save-pointers */ size_t save_len; /* ...and its length */ int scrolllines; /* number of lines to button scroll */ Boolean alternateScroll; /* scroll-actions become keys */ Boolean scrollttyoutput; /* scroll to bottom on tty output */ Boolean scrollkey; /* scroll to bottom on key */ Boolean cursor_moved; /* scrolling makes cursor move */ Boolean do_wrap; /* true if cursor in last column and character just output */ int incopy; /* 0 idle; 1 XCopyArea issued; -1 first GraphicsExpose seen, but last not seen */ int copy_src_x; /* params from last XCopyArea ... */ int copy_src_y; unsigned int copy_width; unsigned int copy_height; int copy_dest_x; int copy_dest_y; Dimension embed_wide; Dimension embed_high; Boolean c132; /* allow change to 132 columns */ Boolean curses; /* kludge line wrap for more */ Boolean hp_ll_bc; /* kludge HP-style ll for xdb */ Boolean marginbell; /* true if margin bell on */ int nmarginbell; /* columns from right margin */ int bellArmed; /* cursor below bell margin */ BellVolume marginVolume; /* margin-bell volume */ BellVolume warningVolume; /* warning-bell volume */ Boolean multiscroll; /* true if multi-scroll */ int scrolls; /* outstanding scroll count, used only with multiscroll */ SavedCursor sc[SAVED_CURSORS]; /* data for restore cursor */ IFlags save_modes[DP_LAST]; /* save dec/xterm private modes */ int title_modes; /* control set/get of titles */ int title_modes0; /* ...initial value */ SavedTitles saved_titles; /* Improved VT100 emulation stuff. */ String keyboard_dialect; /* default keyboard dialect */ DECNRCM_codes gsets[NUM_GSETS2]; /* G0 through G3, plus UPSS */ Char curgl; /* Current GL setting. */ Char curgr; /* Current GR setting. */ Char curss; /* Current single shift. */ String term_id; /* resource for terminal_id */ int terminal_id; /* 100=vt100, 220=vt220, etc. */ int display_da1; /* 100=vt100, 220=vt220, etc. */ int vtXX_level; /* 0=vt52, 1,2,3 = vt100 ... vt320 */ int ansi_level; /* dpANSI levels 1,2,3 */ int protected_mode; /* 0=off, 1=DEC, 2=ISO */ Boolean always_bold_mode; /* compare normal/bold font */ Boolean always_highlight; /* whether to highlight cursor */ Boolean bold_mode; /* use bold font or overstrike */ Boolean delete_is_del; /* true for compatible Delete key */ Boolean jumpscroll; /* whether we should jumpscroll */ Boolean fastscroll; /* whether we should fastscroll */ Boolean old_fkeys; /* true for compatible fkeys */ Boolean old_fkeys0; /* ...initial value */ Boolean underline; /* whether to underline text */ #if OPT_MAXIMIZE Boolean restore_data; int restore_x; int restore_y; unsigned restore_width; unsigned restore_height; #endif #if OPT_REGIS_GRAPHICS String graphics_regis_default_font; /* font for "builtin" */ String graphics_regis_screensize; /* given a size in pixels */ Dimension graphics_regis_def_wide; /* ...corresponding width */ Dimension graphics_regis_def_high; /* ...and height */ #endif #if OPT_GRAPHICS String graph_termid; /* resource for graphics_termid */ int graphics_termid; /* based on terminal_id */ String graphics_max_size; /* given a size in pixels */ Dimension graphics_max_wide; /* ...corresponding width */ Dimension graphics_max_high; /* ...and height */ #endif #if OPT_SCROLL_LOCK Boolean allowScrollLock;/* ScrollLock mode */ Boolean allowScrollLock0;/* initial ScrollLock mode */ Boolean autoScrollLock; /* Auto ScrollLock mode */ Boolean scroll_lock; /* true to keep buffer in view */ Boolean scroll_dirty; /* scrolling makes screen dirty */ #endif #if OPT_SIXEL_GRAPHICS Boolean sixel_scrolling; /* sixel scrolling */ Boolean sixel_scrolls_right; /* sixel scrolling moves cursor to right */ Boolean sixel_scrolls_right0; /* initial sixelScrolling mode */ #endif #if OPT_GRAPHICS int numcolorregisters; /* number of supported color registers */ Boolean privatecolorregisters; /* private color registers for each graphic */ Boolean privatecolorregisters0; /* initial privateColorRegisters */ Boolean incremental_graphics; /* draw graphics incrementally */ #endif /* Graphics Printing */ #if OPT_PRINT_GRAPHICS Boolean graphics_print_to_host; Boolean graphics_expanded_print_mode; Boolean graphics_print_color_mode; Boolean graphics_print_color_syntax; Boolean graphics_print_background_mode; Boolean graphics_rotated_print_mode; #endif #define StatusLineRows 1 /* number of rows in status-line */ #if OPT_STATUS_LINE #define AddStatusLineRows(nrow) nrow += StatusLineRows #define LastRowNumber(screen) \ ( (screen)->max_row \ + (IsStatusShown(screen) ? StatusLineRows : 0) ) #define FirstRowNumber(screen) \ ( (screen)->status_active \ ? LastRowNumber(screen) \ : 0 ) #define IsStatusShown(screen) \ ( ( (screen)->status_type == 2) || \ ( (screen)->status_type == 1) ) #define PlusStatusLine(screen,expr) \ ( (screen)->status_shown \ ? (expr) + StatusLineRows \ : (expr) ) #define if_STATUS_LINE(screen,stmt) \ if (IsStatusShown(screen) && (screen)->status_active) stmt Boolean status_timeout; /* status timeout needs service */ int status_active; /* DECSASD */ int status_type; /* DECSSDT */ int status_shown; /* last-displayed type */ SavedCursor status_data[2]; /* main- and status-cursors */ char * status_fmt; /* format for indicator-status */ #else /* !OPT_STATUS_LINE */ #define AddStatusLineRows(nrow) /* nothing */ #define LastRowNumber(screen) (screen)->max_row #define FirstRowNumber(screen) 0 #define IsStatusShown(screen) False #define PlusStatusLine(screen,expr) (expr) #define if_STATUS_LINE(screen,stmt) /* nothing */ #endif /* OPT_STATUS_LINE */ #if OPT_VT52_MODE IFlags vt52_save_flags; Char vt52_save_curgl; Char vt52_save_curgr; Char vt52_save_curss; DECNRCM_codes vt52_save_gsets[NUM_GSETS2]; #endif /* Testing */ #if OPT_XMC_GLITCH unsigned xmc_glitch; /* # of spaces to pad on SGR's */ IAttr xmc_attributes; /* attrs that make a glitch */ Boolean xmc_inline; /* SGR's propagate only to eol */ Boolean move_sgr_ok; /* SGR is reset on move */ #endif /* * Bell */ int visualBellDelay; /* msecs to delay for visibleBell */ int bellSuppressTime; /* msecs after Bell before another allowed */ Boolean bellInProgress; /* still ringing/flashing prev bell? */ Boolean bellIsUrgent; /* set XUrgency WM hint on bell */ Boolean flash_line; /* show visualBell as current line */ /* * Select/paste state. */ Boolean selectToClipboard; /* primary vs clipboard */ String *mappedSelect; /* mapping for "SELECT" to "PRIMARY" */ Boolean waitingForTrackInfo; int numberOfClicks; int maxClicks; int multiClickTime; /* time between multiclick selects */ SelectUnit selectUnit; SelectUnit selectMap[NSELECTUNITS]; String onClick[NSELECTUNITS + 1]; char *charClass; /* for overriding word selection */ Boolean cutNewline; /* whether or not line cut has \n */ Boolean cutToBeginningOfLine; /* line cuts to BOL? */ Boolean highlight_selection; /* controls appearance of selection */ Boolean show_wrap_marks; /* show lines which are wrapped */ Boolean trim_selection; /* controls trimming of selection */ Boolean i18nSelections; Boolean brokenSelections; Boolean keepClipboard; /* retain data sent to clipboard */ Boolean keepSelection; /* do not lose selection on output */ Boolean replyToEmacs; /* Send emacs escape code when done selecting or extending? */ SelectedCells clipboard_data; /* what we sent to the clipboard */ EventMode eventMode; Time selection_time; /* latest event timestamp */ Time lastButtonUpTime; unsigned lastButton; #define MAX_CUT_BUFFER 8 /* CUT_BUFFER0 to CUT_BUFFER7 */ #define MAX_SELECTIONS (MAX_SELECTION_CODES + MAX_CUT_BUFFER) SelectedCells selected_cells[MAX_SELECTIONS]; CELL rawPos; /* raw position for selection start */ CELL startRaw; /* area before selectUnit processing */ CELL endRaw; /* " " */ CELL startSel; /* area after selectUnit processing */ CELL endSel; /* " " */ CELL startH; /* start highlighted text */ CELL endH; /* end highlighted text */ CELL saveStartW; /* saved WORD state, for LINE */ CELL startExt; /* Start, end of extension */ CELL endExt; /* " " */ CELL saveStartR; /* Saved values of raw selection for extend to restore to */ CELL saveEndR; /* " " */ int startHCoord, endHCoord; int firstValidRow; /* Valid rows for selection clipping */ int lastValidRow; /* " " */ #if OPT_BLOCK_SELECT int lastSelectWasBlock; int blockSelecting; /* non-zero if block selection */ #endif Boolean selectToBuffer; /* copy selection to buffer */ InternalSelect internal_select; String default_string; String eightbit_select_types; Atom* selection_targets_8bit; #if OPT_WIDE_CHARS String utf8_select_types; Atom* selection_targets_utf8; #endif Atom* selection_atoms; /* which selections we own */ Cardinal sel_atoms_size; /* how many atoms allocated */ Cardinal selection_count; /* how many atoms in use */ #if OPT_SELECT_REGEX char * selectExpr[NSELECTUNITS]; #endif /* * Input/output state. */ Boolean input_eight_bits; /* do not send ESC when meta pressed */ int eight_bit_meta; /* use 8th bit when meta pressed */ char * eight_bit_meta_s; /* ...resource eightBitMeta */ Boolean output_eight_bits; /* honor all bits or strip */ Boolean control_eight_bits; /* send CSI as 8-bits */ Boolean backarrow_key; /* backspace/delete */ Boolean alt_is_not_meta; /* use both Alt- and Meta-key */ Boolean alt_sends_esc; /* Alt-key sends ESC prefix */ Boolean meta_sends_esc; /* Meta-key sends ESC prefix */ /* * Fonts */ Pixmap menu_item_bitmap; /* mask for checking items */ String initial_font; char * menu_font_names[NMENUFONTS][fMAX]; #define MenuFontName(n) menu_font_names[n][fNorm] #define EscapeFontName() MenuFontName(fontMenu_fontescape) #define SelectFontName() MenuFontName(fontMenu_fontsel) long menu_font_sizes[NMENUFONTS]; int menu_font_number; #if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS Boolean savedVTFonts; Boolean mergedVTFonts; SubResourceRec cacheVTFonts; #endif #if OPT_CLIP_BOLD Boolean use_border_clipping; Boolean use_clipping; #endif void * main_cgs_cache; #ifndef NO_ACTIVE_ICON void * icon_cgs_cache; #endif #if OPT_RENDERFONT int xft_max_glyph_memory; int xft_max_unref_fonts; Boolean xft_track_mem_usage; Boolean force_xft_height; ListXftFonts *list_xft_fonts; XTermXftFonts renderFontNorm[NMENUFONTS]; XTermXftFonts renderFontBold[NMENUFONTS]; #if OPT_WIDE_ATTRS || OPT_RENDERWIDE XTermXftFonts renderFontItal[NMENUFONTS]; XTermXftFonts renderFontBtal[NMENUFONTS]; #endif #if OPT_RENDERWIDE XTermXftFonts renderWideNorm[NMENUFONTS]; XTermXftFonts renderWideBold[NMENUFONTS]; XTermXftFonts renderWideItal[NMENUFONTS]; XTermXftFonts renderWideBtal[NMENUFONTS]; TypedBuffer(XftCharSpec); #else TypedBuffer(XftChar8); #endif XftDraw * renderDraw; #endif #if OPT_DABBREV Boolean dabbrev_working; /* nonzero during dabbrev process */ unsigned char dabbrev_erase_char; /* used for deleting inserted completion */ #endif char tcapbuf[TERMCAP_SIZE]; char tcap_area[TERMCAP_SIZE]; #if OPT_TCAP_FKEYS char ** tcap_fkeys; #endif String cursor_font_name; /* alternate cursor font */ } TScreen; typedef XTermFonts *(*MyGetFont) (TScreen *, int); typedef struct _TekPart { XFontStruct * Tfont[TEKNUMFONTS]; int tobaseline[TEKNUMFONTS]; /* top-baseline, each font */ char * initial_font; /* large, 2, 3, small */ char * gin_terminator_str; /* ginTerminator resource */ #if OPT_TOOLBAR TbInfo tb_info; /* toolbar information */ #endif } TekPart; /* Tektronix window parameters */ typedef struct _TekScreen { GC TnormalGC; /* normal painting */ GC TcursorGC; /* normal cursor painting */ Boolean waitrefresh; /* postpone refresh */ TKwin fullTwin; #ifndef NO_ACTIVE_ICON TKwin iconTwin; TKwin *whichTwin; #endif /* NO_ACTIVE_ICON */ Cursor arrow; /* arrow cursor */ GC linepat[TEKNUMLINES]; /* line patterns */ int cur_X; /* current x */ int cur_Y; /* current y */ Tmodes cur; /* current tek modes */ Tmodes page; /* starting tek modes on page */ int margin; /* 0 -> margin 1, 1 -> margin 2 */ int pen; /* current Tektronix pen 0=up, 1=dn */ char *TekGIN; /* nonzero if Tektronix GIN mode*/ int gin_terminator; /* Tek strap option */ char tcapbuf[TERMCAP_SIZE]; } TekScreen; #if OPT_PASTE64 || OPT_READLINE #define SCREEN_FLAG(screenp,f) (1&(screenp)->f) #define SCREEN_FLAG_set(screenp,f) ((screenp)->f |= 1) #define SCREEN_FLAG_unset(screenp,f) ((screenp)->f &= (unsigned) ~1L) #define SCREEN_FLAG_save(screenp,f) \ ((screenp)->f = (((screenp)->f)<<1) | SCREEN_FLAG(screenp,f)) #define SCREEN_FLAG_restore(screenp,f) ((screenp)->f = (((screenp)->f)>>1)) #else #define SCREEN_FLAG(screenp,f) (0) #endif /* * After screen-updates, reset the flag that tells us we should do wrapping. * Likewise, reset (in wide-character mode) the flag that tells us where the * "previous" character was written. */ #if OPT_WIDE_CHARS #define ResetWrap(screen) \ (screen)->do_wrap = \ (screen)->char_was_written = False #else #define ResetWrap(screen) \ (screen)->do_wrap = False #endif /* meaning of bits in screen.select flag */ #define INWINDOW 01 /* the mouse is in one of the windows */ #define FOCUS 02 /* one of the windows is the focus window */ #define MULTICLICKTIME 250 /* milliseconds */ typedef struct { const char *name; int code; } FlagList; typedef enum { keyboardIsLegacy, /* bogus vt220 codes for F1-F4, etc. */ keyboardIsDefault, keyboardIsHP, keyboardIsSCO, keyboardIsSun, keyboardIsTermcap, keyboardIsVT220 } xtermKeyboardType; typedef enum { /* legal values for screen.pointer_mode */ pNever = 0 , pNoMouse = 1 , pAlways = 2 , pFocused = 3 } pointerModeTypes; typedef enum { /* legal values for screen.utf8_mode */ uFalse = 0 , uTrue = 1 , uAlways = 2 , uDefault = 3 , uLast } utf8ModeTypes; typedef enum { /* legal values for screen.eight_bit_meta */ ebFalse = 0 , ebTrue = 1 , ebNever = 2 , ebLocale = 3 , ebLast } ebMetaModeTypes; typedef enum { /* legal values for misc.cdXtraScroll */ edFalse = 0 , edTrue = 1 , edTrim = 2 , edLast } edXtraScrollTypes; #define NAME_OLD_KT " legacy" #if OPT_HP_FUNC_KEYS #define NAME_HP_KT " hp" #else #define NAME_HP_KT /*nothing*/ #endif #if OPT_SCO_FUNC_KEYS #define NAME_SCO_KT " sco" #else #define NAME_SCO_KT /*nothing*/ #endif #if OPT_SUN_FUNC_KEYS #define NAME_SUN_KT " sun" #else #define NAME_SUN_KT /*nothing*/ #endif #if OPT_SUNPC_KBD #define NAME_VT220_KT " vt220" #else #define NAME_VT220_KT /*nothing*/ #endif #if OPT_TCAP_FKEYS #define NAME_TCAP_KT " tcap" #else #define NAME_TCAP_KT /*nothing*/ #endif #define KEYBOARD_TYPES NAME_TCAP_KT NAME_HP_KT NAME_SCO_KT NAME_SUN_KT NAME_VT220_KT #if OPT_TRACE #define TRACE_RC(code,func) code = func #else #define TRACE_RC(code,func) func #endif extern const char * visibleKeyboardType(xtermKeyboardType); typedef struct { int allow_keys; /* how to handle legacy/vt220 keyboard */ int cursor_keys; /* how to handle cursor-key modifiers */ int function_keys; /* how to handle function-key modifiers */ int keypad_keys; /* how to handle keypad key-modifiers */ int other_keys; /* how to handle other key-modifiers */ int string_keys; /* how to handle string() modifiers */ int modify_keys; /* how to handle modifier key-modifiers */ int special_keys; /* how to handle special key-modifiers */ } TModify; typedef enum { mfkNone = -1 /* disable the feature */ , mfkOriginal = 0 /* original/obsolete format */ , mfkControl = 1 /* prefix modified controls with CSI */ , mfkParam = 2 /* modifier parameter is second */ , mfkPrivate = 3 /* mark this as a private control */ , mfkExtended = 4 /* modify all special keys */ } MfkModes; /* also modifyCursorKeys, modifyKeypadKeys */ typedef enum { mokNone = 0 /* disable the feature */ , mokUser = 1 /* user-friendly modified-keys */ , mokProgram = 2 /* program-friendly modified-keys */ , mokExtended = 3 /* modify all ordinary keys */ } MokModes; /* modifyOtherKeys */ typedef enum { modifyKeyboard = 0 /* mode */ , modifyCursorKeys = 1 /* keysym parameterized mode */ , modifyFunctionKeys = 2 /* keysym parameterized mode */ , modifyKeypadKeys = 3 /* keysym non-parameterized mode */ , modifyOtherKeys = 4 /* keysym semi-parameterized mode */ , modifyStringKeys = 5 /* reserved */ , modifyModifierKeys = 6 /* used by Xutf8LookupString, etc */ , modifySpecialKeys = 7 /* other special/non-parameterized keysyms */ } ModkeyModes; typedef struct { xtermKeyboardType type; IFlags flags; char *shell_translations; /* shell's translations, for input check */ char *xterm_translations; /* xterm's translations, for input check */ char *extra_translations; char *print_translations; /* printable translations for buttons */ unsigned shift_buttons; /* special shift-modifier for mouse-buttons */ int shift_escape; /* working value of shiftEscape */ char * shift_escape_s; /* resource for shiftEscape */ #if OPT_INITIAL_ERASE int reset_DECBKM; /* reset should set DECBKM */ #endif #if OPT_MOD_FKEYS TModify modify_now; /* current modifier value */ TModify modify_1st; /* original modifier value, for resets */ TModify format_now; /* current formatter value */ TModify format_1st; /* original formatter value, for resets */ TModify ignore_now; /* limit modifiers used in modifyXxxKeys */ TModify ignore_1st; /* original limit on modifiers */ #endif } TKeyboard; #define GravityIsNorthWest(w) ((w)->misc.resizeGravity == NorthWestGravity) #define GravityIsSouthWest(w) ((w)->misc.resizeGravity == SouthWestGravity) typedef struct _Misc { VTFontNames default_font; char *geo_metry; char *T_geometry; #if OPT_WIDE_CHARS Boolean cjk_width; /* true for built-in CJK wcwidth() */ Boolean mk_width; /* true for simpler built-in wcwidth() */ int mk_samplesize; int mk_samplepass; #endif #if OPT_LUIT_PROG Boolean callfilter; /* true to invoke luit */ Boolean use_encoding; /* true to use -encoding option for luit */ char *locale_str; /* "locale" resource */ char *localefilter; /* path for luit */ #endif fontWarningTypes fontWarnings; int limit_resize; #ifdef ALLOWLOGGING Boolean log_on; #endif Boolean color_inner_border; Boolean login_shell; Boolean re_verse; Boolean re_verse0; /* initial value of "-rv" */ Boolean resizeByPixel; XtGravity resizeGravity; Boolean reverseWrap; Boolean autoWrap; Boolean logInhibit; Boolean signalInhibit; #if OPT_TEK4014 Boolean tekInhibit; Boolean tekSmall; /* start tek window in small size */ Boolean TekEmu; /* true if Tektronix emulation */ Boolean Tshow; /* Tek window showing */ #endif Boolean scrollbar; #ifdef SCROLLBAR_RIGHT Boolean useRight; #endif Boolean titeInhibit; Boolean appcursorDefault; Boolean appkeypadDefault; int cdXtraScroll; /* scroll on cd (clear-display) */ char *cdXtraScroll_s; int tiXtraScroll; /* scroll on ti/te (init/end-cup) */ char *tiXtraScroll_s; #if OPT_INPUT_METHOD char* f_x; /* font for XIM */ char* input_method; char* preedit_type; Boolean open_im; /* true if input-method is opened */ int retry_im; #endif Boolean dynamicColors; #ifndef NO_ACTIVE_ICON char *active_icon_s; /* use application icon window */ unsigned icon_border_width; Pixel icon_border_pixel; #endif /* NO_ACTIVE_ICON */ #if OPT_DEC_SOFTFONT Boolean font_loadable; #endif #if OPT_SHIFT_FONTS Boolean shift_fonts; /* true if we interpret fontsize-shifting */ #endif #if OPT_SUNPC_KBD int ctrl_fkeys; /* amount to add to XK_F1 for ctrl modifier */ #endif #if OPT_NUM_LOCK Boolean real_NumLock; /* true if we treat NumLock key specially */ Boolean alwaysUseMods; /* true if we always want f-key modifiers */ #endif #if OPT_RENDERFONT VTFontNames default_xft; float face_size[NMENUFONTS]; char *render_font_s; int limit_fontsets; int limit_fontheight; int limit_fontwidth; #endif } Misc; typedef struct _Work { int dummy; #ifdef SunXK_F36 #define MAX_UDK 37 #else #define MAX_UDK 35 #endif struct { char *str; int len; } user_keys[MAX_UDK]; #define SET_MIN_MOD(xw, value) xw->work.min_mod = (value >= 3) ? 0 : 1 int min_mod; /* zero for modifying control-keys */ #define MAX_POINTER (XC_num_glyphs/2) Cursor pointer_cursors[MAX_POINTER]; /* saved cursors */ #ifndef NO_ACTIVE_ICON int active_icon; /* use application icon window */ char *wm_name; #endif /* NO_ACTIVE_ICON */ #if OPT_INPUT_METHOD Boolean cannot_im; /* true if we cannot use input-method */ XFontSet xim_fs; /* fontset for XIM preedit */ int xim_fs_ascent; /* ascent of fs */ TInput inputs[NINPUTWIDGETS]; #endif Boolean doing_resize; /* currently in RequestResize */ #if OPT_MAXIMIZE #define MAX_EWMH_MODE 3 #define MAX_EWMH_DATA (1 + OPT_TEK4014) struct { int mode; /* fullscreen, etc. */ Boolean checked[MAX_EWMH_MODE + 1]; Boolean allowed[MAX_EWMH_MODE + 1]; } ewmh[MAX_EWMH_DATA]; #endif #if OPT_NUM_LOCK unsigned num_lock; /* modifier for Num_Lock */ unsigned alt_mods; /* modifier for Alt_L or Alt_R */ unsigned meta_mods; /* modifier for Meta_L or Meta_R */ #endif XtermFontNames fonts; Boolean force_wideFont; /* true to single-step wideFont */ #if OPT_RENDERFONT Boolean render_font; FcPattern *xft_defaults; unsigned max_fontsets; #endif #if OPT_DABBREV #define MAX_DABBREV 1024 /* maximum word length as in tcsh */ char dabbrev_data[MAX_DABBREV]; #endif ScrnColors *oldColors; Boolean palette_changed; Boolean broken_box_chars; /* data write dotext/WriteText */ IChar *write_text; /* points to print_area */ #if OPT_DEC_RECTOPS Char *write_sums; /* if non-null, points to buffer_sums */ Char *buffer_sums; /* data for ->charSeen[] */ Char *buffer_sets; /* data for ->charSets[] */ size_t sizeof_sums; /* allocated size of buffer_sums */ #endif } Work; typedef struct {int foo;} XtermClassPart, TekClassPart; typedef struct _XtermClassRec { CoreClassPart core_class; XtermClassPart xterm_class; } XtermClassRec; extern WidgetClass xtermWidgetClass; #define IsXtermWidget(w) (XtClass(w) == xtermWidgetClass) #if OPT_TEK4014 typedef struct _TekClassRec { CoreClassPart core_class; TekClassPart tek_class; } TekClassRec; extern WidgetClass tekWidgetClass; #define IsTekWidget(w) (XtClass(w) == tekWidgetClass) #endif /* define masks for keyboard.flags */ #define MODE_KAM xBIT(0) /* mode 2: keyboard action mode */ #define MODE_DECKPAM xBIT(1) /* keypad application mode */ #define MODE_DECCKM xBIT(2) /* private mode 1: cursor keys */ #define MODE_SRM xBIT(3) /* mode 12: send-receive mode */ #define MODE_DECBKM xBIT(4) /* private mode 67: backarrow */ #define MODE_DECSDM xBIT(5) /* private mode 80: sixel DISPLAY mode -- note, when SDM is off, the terminal is in sixel SCROLLING mode */ #define N_MARGINBELL 10 #define TAB_BITS_SHIFT 5 /* FIXME: 2**5 == 32 (should derive) */ #define TAB_BITS_WIDTH (1 << TAB_BITS_SHIFT) #define TAB_ARRAY_SIZE (1024 / TAB_BITS_WIDTH) #define MAX_TABS (TAB_BITS_WIDTH * TAB_ARRAY_SIZE) #define OkTAB(c) ((c) > 0 && (c) < MAX_TABS) typedef unsigned Tabs [TAB_ARRAY_SIZE]; #if OPT_XTERM_SGR #define MAX_SAVED_SGR 10 typedef struct { int used; struct { IFlags mask; IFlags flags; #if OPT_ISO_COLORS int sgr_foreground; int sgr_background; Boolean sgr_38_xcolors; #endif } stack[MAX_SAVED_SGR]; } SavedSGR; typedef struct { ScrnColors base; ColorRes ansi[1]; } ColorSlot; typedef struct { int used; /* currently saved or restored */ int last; /* maximum number of saved palettes */ ColorSlot *palettes[MAX_SAVED_SGR]; } SavedColors; #endif /* OPT_XTERM_SGR */ typedef struct _XtermWidgetRec { CorePart core; XSizeHints hints; XVisualInfo *visInfo; int numVisuals; unsigned rgb_shifts[3]; unsigned rgb_widths[3]; Bool has_rgb; Bool init_menu; TKeyboard keyboard; /* terminal keyboard */ TScreen screen; /* terminal screen */ IFlags flags; /* mode flags */ int cur_foreground; /* current foreground color */ int cur_background; /* current background color */ Pixel dft_foreground; /* default foreground color */ Pixel dft_background; /* default background color */ Pixel old_foreground; /* original foreground color */ Pixel old_background; /* original background color */ #if OPT_ISO_COLORS int sgr_foreground; /* current SGR foreground color */ int sgr_background; /* current SGR background color */ Boolean sgr_38_xcolors; /* true if ISO 8613 extension */ #endif IFlags initflags; /* initial mode flags */ Tabs tabs; /* tabstops of the terminal */ Misc misc; /* miscellaneous parameters */ Work work; /* workspace (no resources) */ #if OPT_XTERM_SGR SavedSGR saved_sgr; SavedColors saved_colors; #endif } XtermWidgetRec, *XtermWidget; #if OPT_TEK4014 typedef struct _TekWidgetRec { CorePart core; XtermWidget vt; /* main widget has border, etc. */ TekPart tek; /* contains resources */ TekScreen screen; /* contains working data (no resources) */ Bool init_menu; XSizeHints hints; } TekWidgetRec, *TekWidget; #endif /* OPT_TEK4014 */ /* * terminal flags * There are actually two namespaces mixed together here: * a) One is the set of flags that can go in screen->visbuf attributes and * which must fit in an IAttr (either a char or short, depending on whether * wide-attributes are used). * b) The other is the global setting stored in term->flags and * screen->save_modes, which fits in an unsigned (IFlags). */ #define AttrBIT(n) xBIT(n) /* text-attributes */ #define MiscBIT(n) xBIT(n + 16) /* miscellaneous state flags */ /* global flags and character flags (visible character attributes) */ #define INVERSE AttrBIT(0) /* invert the characters to be output */ #define UNDERLINE AttrBIT(1) /* true if underlining */ #define BOLD AttrBIT(2) #define BLINK AttrBIT(3) /* global flags (also character attributes) */ #define BG_COLOR AttrBIT(4) /* true if background set */ #define FG_COLOR AttrBIT(5) /* true if foreground set */ /* character flags (internal attributes) */ #define PROTECTED AttrBIT(6) /* a character that cannot be erased */ #define CHARDRAWN AttrBIT(7) /* a character has been drawn here on the screen. Used to distinguish blanks from empty parts of the screen when selecting */ /* * This does not fit in a byte with the other (more important) attributes, but * if wide-attributes are configured, it is possible to maintain it there. */ #define INVISIBLE AttrBIT(8) /* true if writing invisible text */ #if OPT_WIDE_ATTRS #define ATR_FAINT AttrBIT(9) #define ATR_ITALIC AttrBIT(10) #define ATR_STRIKEOUT AttrBIT(11) #define ATR_DBL_UNDER AttrBIT(12) #define ATR_DIRECT_FG AttrBIT(13) #define ATR_DIRECT_BG AttrBIT(14) #define SGR_MASK2 (ATR_FAINT | ATR_ITALIC | ATR_STRIKEOUT | ATR_DBL_UNDER | ATR_DIRECT_FG | ATR_DIRECT_BG) #define AttrEND 15 #else #define SGR_MASK2 0 #define AttrEND 9 #endif /* * Other flags */ #define REVERSE_VIDEO MiscBIT(0) /* true if screen white on black */ #define WRAPAROUND MiscBIT(1) /* true if auto wraparound mode */ #define REVERSEWRAP MiscBIT(2) /* true if reverse wraparound mode */ #define REVERSEWRAP2 MiscBIT(3) /* true if extended reverse wraparound */ #define LINEFEED MiscBIT(4) /* true if in auto linefeed mode */ #define ORIGIN MiscBIT(5) /* true if in origin mode */ #define INSERT MiscBIT(6) /* true if in insert mode */ #define SMOOTHSCROLL MiscBIT(7) /* true if in smooth scroll mode */ #define IN132COLUMNS MiscBIT(8) /* true if in 132 column mode */ #define NATIONAL MiscBIT(9) /* true if writing national charset */ #define LEFT_RIGHT MiscBIT(10) /* true if left/right margin mode */ #define NOCLEAR_COLM MiscBIT(11) /* true if no clear on DECCOLM change */ /* * Drawing-bits start after the video/color attributes, and are independent * of the miscellaneous flags. */ #define DrawBIT(n) xBIT(n + AttrEND) /* XTermDraw.draw_flags */ /* The following attributes are used in the argument of drawXtermText() */ #define NOBACKGROUND DrawBIT(0) /* Used for overstrike */ #define NOTRANSLATION DrawBIT(1) /* No scan for chars missing in font */ #define DOUBLEWFONT DrawBIT(2) /* The actual X-font is double-width */ #define DOUBLEHFONT DrawBIT(3) /* The actual X-font is double-height */ #define DOUBLEFIRST DrawBIT(4) /* Draw chars one-by-one */ #define CHARBYCHAR DrawBIT(5) /* Draw chars one-by-one */ /* The following attribute is used in the argument of xtermSpecialFont etc */ #define NORESOLUTION DrawBIT(6) /* find the font without resolution */ /* * Groups of attributes */ /* mask for video-attributes only */ #define SGR_MASK (BOLD | BLINK | UNDERLINE | INVERSE) /* mask: user-visible attributes */ #define ATTRIBUTES (SGR_MASK | SGR_MASK2 | BG_COLOR | FG_COLOR | INVISIBLE | PROTECTED) /* The toplevel-call to drawXtermText() should have text-attributes guarded: */ #define DRAWX_MASK (ATTRIBUTES | CHARDRAWN) /* * BOLDATTR is not only nonzero when we will use bold font, but uses the bits * for BOLD/BLINK to match against the video attributes which were originally * requested. */ #define USE_BOLD(screen) ((screen)->allowBoldFonts) #if OPT_BLINK_TEXT #define BOLDATTR(screen) (unsigned) (USE_BOLD(screen) ? (BOLD | ((screen)->blink_as_bold ? BLINK : 0)) : 0) #else #define BOLDATTR(screen) (unsigned) (USE_BOLD(screen) ? (BOLD | BLINK) : 0) #endif /* * Sixel scrolling is on when Sixel Display Mode is off, and vice versa. * (Note: DEC erroneously conflates the two in the VT330/340 manual). */ #define SixelScrolling(xw) (!((xw)->keyboard.flags & MODE_DECSDM)) /* * Per-line flags */ #define LINEWRAPPED AttrBIT(0) /* used once per line to indicate that it wraps onto the next line so we can * tell the difference between lines that have wrapped around and lines that * have ended naturally with a CR at column max_col. */ #define LINEBLINKED AttrBIT(1) /* set when the line contains blinking text. */ #if OPT_ZICONBEEP || OPT_TOOLBAR || (USE_DOUBLE_BUFFER && OPT_RENDERFONT) #define HANDLE_STRUCT_NOTIFY 1 #else #define HANDLE_STRUCT_NOTIFY 0 #endif /* * If we've set protected attributes with the DEC-style DECSCA, then we'll have * to use DECSED or DECSEL to erase preserving protected text. (The normal ED, * EL won't preserve protected-text). If we've used SPA, then normal ED and EL * will preserve protected-text. To keep things simple, just remember the last * control that was used to begin protected-text, and use that to determine how * erases are performed (otherwise we'd need 2 bits per protected character). */ #define OFF_PROTECT 0 #define DEC_PROTECT 1 #define ISO_PROTECT 2 /***====================================================================***/ /* * Reduce parameter-count of drawXtermText by putting less-modified data here. */ typedef struct { XtermWidget xw; unsigned attr_flags; unsigned draw_flags; unsigned this_chrset; unsigned real_chrset; int on_wide; } XTermDraw; /***====================================================================***/ #define TScreenOf(xw) (&(xw)->screen) #define TekScreenOf(tw) (&(tw)->screen) #define PrinterOf(screen) (screen)->printer_state #ifdef SCROLLBAR_RIGHT #define OriginX(screen) (((term->misc.useRight)?0:ScrollbarWidth(screen)) + screen->border) #else #define OriginX(screen) (ScrollbarWidth(screen) + screen->border) #endif #define OriginY(screen) (screen->border) #define CursorMoved(screen) \ ((screen)->cursor_moved || \ ((screen)->cursorp.col != (screen)->cur_col || \ (screen)->cursorp.row != (screen)->cur_row)) #define CursorX2(screen,col,fw) ((col) * (int)(fw) + OriginX(screen)) #define CursorX(screen,col) CursorX2(screen, col, FontWidth(screen)) #define CursorY2(screen,row) (((row) * FontHeight(screen)) + screen->border) #define CursorY(screen,row) CursorY2(screen, INX2ROW(screen, row)) /* * These definitions depend on whether xterm supports active-icon. */ #ifndef NO_ACTIVE_ICON #define IsIconWin(screen,win) ((win) == &(screen)->iconVwin) #define IsIcon(screen) (WhichVWin(screen) == &(screen)->iconVwin) #define WhichVWin(screen) ((screen)->whichVwin) #define WhichTWin(screen) ((screen)->whichTwin) #define WhichVFont(screen,name) (IsIcon(screen) ? getIconicFont(screen) \ : getNormalFont(screen, (int)(name)))->fs #define FontAscent(screen) (IsIcon(screen) ? getIconicFont(screen)->fs->ascent \ : WhichVWin(screen)->f_ascent) #define FontDescent(screen) (IsIcon(screen) ? getIconicFont(screen)->fs->descent \ : WhichVWin(screen)->f_descent) #else /* NO_ACTIVE_ICON */ #define IsIconWin(screen,win) (False) #define IsIcon(screen) (False) #define WhichVWin(screen) (&((screen)->fullVwin)) #define WhichTWin(screen) (&((screen)->fullTwin)) #define WhichVFont(screen,name) getNormalFont(screen, (int)(name))->fs #define FontAscent(screen) WhichVWin(screen)->f_ascent #define FontDescent(screen) WhichVWin(screen)->f_descent #endif /* NO_ACTIVE_ICON */ #define okFont(font) ((font) != NULL && (font)->fid != 0) /* * Macro to check if we are iconified; do not use render for that case. */ #define UsingRenderFont(xw) (((xw)->work.render_font == True) && !IsIcon(TScreenOf(xw))) /* * These definitions do not depend on whether xterm supports active-icon. */ #define VWindow(screen) WhichVWin(screen)->window #define VShellWindow(xw) XtWindow(SHELL_OF(xw)) #define TWindow(screen) WhichTWin(screen)->window #define TShellWindow XtWindow(SHELL_OF(tekWidget)) #if USE_DOUBLE_BUFFER extern Window VDrawable(TScreen * /* screen */); #else #define VDrawable(screen) VWindow(screen) #endif #define Width(screen) WhichVWin(screen)->width #define Height(screen) WhichVWin(screen)->height #define FullWidth(screen) WhichVWin(screen)->fullwidth #define FullHeight(screen) WhichVWin(screen)->fullheight #define FontWidth(screen) WhichVWin(screen)->f_width #define FontHeight(screen) WhichVWin(screen)->f_height #define NormalFont(screen) WhichVFont(screen, fNorm) #define BoldFont(screen) WhichVFont(screen, fBold) #if OPT_WIDE_CHARS #define NormalWFont(screen) WhichVFont(screen, fWide) #define BoldWFont(screen) WhichVFont(screen, fWBold) #endif #define ScrollbarWidth(screen) WhichVWin(screen)->sb_info.width /* y -> y_shift, to center text versus the cursor */ #define ScaleShift(screen) \ (int) ((IsIcon(screen) || (screen->scale_height <= 1.0f)) \ ? 0.0f \ : ((float) WhichVWin(screen)->f_height \ * ((float) screen->scale_height - 1.0f) / 2.0f)) #define BorderGC(w,sp) WhichVWin(sp)->border_gc #define FillerGC(w,sp) WhichVWin(sp)->filler_gc #define NormalGC(w,sp) getCgsGC(w, WhichVWin(sp), gcNorm) #define ReverseGC(w,sp) getCgsGC(w, WhichVWin(sp), gcNormReverse) #define NormalBoldGC(w,sp) getCgsGC(w, WhichVWin(sp), gcBold) #define ReverseBoldGC(w,sp) getCgsGC(w, WhichVWin(sp), gcBoldReverse) #define TWidth(screen) WhichTWin(screen)->width #define THeight(screen) WhichTWin(screen)->height #define TFullWidth(screen) WhichTWin(screen)->fullwidth #define TFullHeight(screen) WhichTWin(screen)->fullheight #define TekScale(screen) WhichTWin(screen)->tekscale /* use these before tek4014 is realized, good enough for default "9x15" font */ #define TDefaultRows 37 #define TDefaultCols 75 #define BorderWidth(w) ((w)->core.border_width) #define BorderPixel(w) ((w)->core.border_pixel) #define AllowXtermOps(w,name) (TScreenOf(w)->name && !TScreenOf(w)->allowSendEvents) #define AllowColorOps(w,name) (AllowXtermOps(w, allowColorOps) || \ !TScreenOf(w)->disallow_color_ops[name]) #define AllowFontOps(w,name) (AllowXtermOps(w, allowFontOps) || \ !TScreenOf(w)->disallow_font_ops[name]) #define AllowMouseOps(w,name) (AllowXtermOps(w, allowMouseOps) || \ !TScreenOf(w)->disallow_mouse_ops[name]) #define AllowTcapOps(w,name) (AllowXtermOps(w, allowTcapOps) || \ !TScreenOf(w)->disallow_tcap_ops[name]) #define AllowTitleOps(w) AllowXtermOps(w, allowTitleOps) #define AllowXResOps(w) True #define SpecialWindowOps(w,name) (!TScreenOf(w)->disallow_win_ops[name]) #define AllowWindowOps(w,name) (AllowXtermOps(w, allowWindowOps) || \ SpecialWindowOps(w,name)) #if OPT_TOOLBAR #define ToolbarHeight(w) ((resource.toolBar) \ ? ((w)->VT100_TB_INFO(menu_height) \ + (w)->VT100_TB_INFO(menu_border) * 2) \ : 0) #else #define ToolbarHeight(w) 0 #endif #if OPT_TEK4014 #define TEK_LINK_BLOCK_SIZE 1024 typedef struct Tek_Link { struct Tek_Link *next; /* pointer to next TekLink in list NULL <=> this is last TekLink */ unsigned short fontsize;/* character size, 0-3 */ unsigned short count; /* number of chars in data */ char *ptr; /* current pointer into data */ char data [TEK_LINK_BLOCK_SIZE]; } TekLink; #endif /* OPT_TEK4014 */ /* flags for cursors */ #define OFF 0 #define ON 1 #define BLINKED_OFF 2 #define CLEAR 0 #define TOGGLE 1 /* flags for inhibit */ #ifdef ALLOWLOGGING #define I_LOG 0x01 #endif #define I_SIGNAL 0x02 #define I_TEK 0x04 /* *INDENT-ON* */ #endif /* included_ptyx_h */ xterm-399/graphics_regis.c0000644000000000000000000066657514773455201014433 0ustar rootroot/* $XTermId: graphics_regis.c,v 1.157 2025/04/03 09:53:05 tom Exp $ */ /* * Copyright 2014-2024,2025 by Thomas E. Dickey * Copyright 2014-2022,2023 by Ross Combs * * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization. */ #include #include #include #include #include #include #include #include #include #include /* get rid of shadowing warnings (we will not draw Bessel functions) */ #define y1 my_y1 #define y0 my_y0 #define SCALE_FIXED_POINT 16U #undef DEBUG_PARSING #undef DEBUG_ALPHABET_LOOKUP #undef DEBUG_ALPHABETS #undef DEBUG_BEZIER #undef DEBUG_SPLINE_SEGMENTS #undef DEBUG_SPLINE_POINTS #undef DEBUG_SPLINE_WITH_ROTATION #undef DEBUG_SPLINE_WITH_OVERDRAW #undef DEBUG_ARC_POINTS #undef DEBUG_ARC_CENTER #undef DEBUG_ARC_START #undef DEBUG_ARC_END #undef DEBUG_SPECIFIC_CHAR_METRICS #define IS_DEBUG_CHAR(CH) ((CH) == 'W') /* glyphs to dump to terminal */ #undef DEBUG_COMPUTED_FONT_METRICS #undef DEBUG_FONT_NAME #undef DEBUG_FONT_SIZE_SEARCH #undef DEBUG_XFT_GLYPH_COPY #undef DEBUG_GLYPH_RETRIEVAL #undef DEBUG_XFT_GLYPH_LOADING #undef DEBUG_LOAD /* controls for extensions over VT3x0 limitations */ #define ENABLE_RGB_COLORSPECS #undef ENABLE_FREE_ROTATION #undef ENABLE_DISTORTIONLESS_ROTATION #define ENABLE_UPLOAD_ALPHABET_FROM_FONT #define ENABLE_UPLOAD_ALPHABET_ZERO #define ENABLE_USER_FONT_SIZE #define ENABLE_VARIABLE_ITALICS #define MIN_ITERATIONS_BEFORE_REFRESH 10U #define MIN_MS_BEFORE_REFRESH 33 /* *INDENT-OFF* */ typedef struct RegisPoint { int x, y; } RegisPoint; typedef struct RegisWriteControls { unsigned pv_multiplier; unsigned pattern; unsigned pattern_multiplier; unsigned invert_pattern; unsigned plane_mask; unsigned write_style; RegisterNum foreground; unsigned shading_enabled; char shading_character; int shading_reference; unsigned shading_reference_dim; unsigned line_width; } RegisWriteControls; typedef struct RegisTextControls { unsigned alphabet_num; unsigned character_set_l; /* default: "(B" (ASCII) */ unsigned character_set_r; /* default: "-@" (Latin-1) */ unsigned character_display_w; unsigned character_display_h; unsigned character_unit_cell_w; unsigned character_unit_cell_h; int character_inc_x; int character_inc_y; int string_rotation; int character_rotation; int slant; /* for italic/oblique */ } RegisTextControls; #define S_QUOTE '\'' #define D_QUOTE '"' #define isQuote(ch) ((ch) == S_QUOTE || (ch) == D_QUOTE) #define PickQuote(ch) ((ch) == S_QUOTE ? D_QUOTE : S_QUOTE) #define isName(c) ((c) == '_' || isalnum(CharOf(c))) #define FixedCopy(dst, src, len) strncpy(dst, src, len - 1)[len - 1] = '\0' #define CopyFontname(dst, src) FixedCopy(dst, src, (size_t) REGIS_FONTNAME_LEN) #define MAX_REGIS_PAGES 8U #define MAX_REGIS_ALPHABETS 8U #define REGIS_ALPHABET_NAME_LEN 11U #define REGIS_FONTNAME_LEN 256U /* enough for a 16x24 font (about 100KB) */ #define MAX_REGIS_ALPHABET_BYTES (256U * 16U * 24U) #define MAX_GLYPH_PIXELS 8192U #define MAX_GLYPHS 256U #define INVALID_ALPHABET_NUM ~0U typedef struct RegisAlphabet { unsigned alphabet_num; unsigned pixw, pixh; char name[REGIS_ALPHABET_NAME_LEN]; char fontname[REGIS_FONTNAME_LEN]; int use_font; int loaded[MAX_GLYPHS]; Char *bytes; } RegisAlphabet; typedef struct RegisDataFragment { char const *start; unsigned pos; unsigned len; } RegisDataFragment; /* *INDENT-ON* */ #define POSITION_STACK_SIZE 16U #define DUMMY_STACK_X -32768 #define DUMMY_STACK_Y -32768 #define CURVE_POSITION_ARC_EDGE 0U #define CURVE_POSITION_ARC_CENTER 1U #define CURVE_POSITION_OPEN_CURVE 2U #define CURVE_POSITION_CLOSED_CURVE 3U #define MAX_INPUT_CURVE_POINTS 16U #define MAX_CURVE_POINTS (MAX_INPUT_CURVE_POINTS + 4U) #define MAX_FILL_POINTS 2048U typedef struct RegisParseState { RegisDataFragment input; char *temp; unsigned templen; char command; char option; /* position stack */ int stack_x[POSITION_STACK_SIZE]; int stack_y[POSITION_STACK_SIZE]; unsigned stack_next; /* next empty position */ /* curve options */ int curve_mode; int arclen; int x_points[MAX_CURVE_POINTS]; int y_points[MAX_CURVE_POINTS]; unsigned num_points; /* load options */ char load_name[REGIS_ALPHABET_NAME_LEN]; unsigned load_alphabet; unsigned load_w, load_h; unsigned load_index; unsigned load_glyph; unsigned load_row; /* text options */ unsigned text_tilt_state; } RegisParseState; #define TEXT_TILT_STATE_READY 0U #define TEXT_TILT_STATE_GOT_D 1U #define TEXT_TILT_STATE_GOT_DS 2U #define TEXT_TILT_STATE_GOT_DSD 3U typedef struct RegisGraphicsContext { XtermWidget current_widget; Graphic *destination_graphic; Graphic *display_graphic; int graphics_termid; int x_off, y_off; int x_div, y_div; int width, height; unsigned all_planes; RegisterNum background; char const *builtin_font; RegisAlphabet alphabets[MAX_REGIS_ALPHABETS]; RegisWriteControls persistent_write_controls; RegisWriteControls temporary_write_controls; RegisTextControls persistent_text_controls; RegisTextControls temporary_text_controls; RegisTextControls *current_text_controls; int multi_input_mode; int graphics_output_cursor_x; int graphics_output_cursor_y; unsigned pattern_count; unsigned pattern_bit; int fill_mode; RegisPoint fill_points[MAX_FILL_POINTS]; unsigned fill_point_count; unsigned destination_page; unsigned display_page; Boolean force_refresh; } RegisGraphicsContext; static RegisGraphicsContext persistent_context; static RegisParseState persistent_state; #define MAX_PATTERN_BITS 8U #define WRITE_STYLE_OVERLAY 1U #define WRITE_STYLE_REPLACE 2U #define WRITE_STYLE_COMPLEMENT 3U #define WRITE_STYLE_ERASE 4U #define WRITE_SHADING_REF_Y 0U #define WRITE_SHADING_REF_X 1U #define WRITE_SHADING_REF_NONE 2U /* keypress event example: http://iraf.net/forum/viewtopic.php?showtopic=61692 */ #define MIN2(X, Y) ( (X) < (Y) ? (X) : (Y) ) #define MIN3(X, Y, Z) ( MIN2(MIN2((X), (Y)), MIN2((Y), (Z))) ) #define MAX2(X, Y) ( (X) > (Y) ? (X) : (Y) ) #define MAX3(X, Y, Z) ( MAX2(MAX2((X), (Y)), MAX2((Y), (Z))) ) #define ROT_LEFT(V) ( (((V) << 1U) & 255U) | ((V) >> 7U) ) /* convert user coordinates to absolute pixel coordinates */ #define SCALE_XCOORD(C, X, S) (int) ( ( (long)(X) * (long)((C)->width - 1) ) / ( (long)(C)->x_div * (long)(S) ) ) #define SCALE_YCOORD(C, Y, S) (int) ( ( (long)(Y) * (long)((C)->height - 1) ) / ( (long)(C)->y_div * (long)(S) ) ) #define TRANSLATE_XCOORD(C, X, S) SCALE_XCOORD((C), (X) - ((C)->x_off * (S)), (S) ) #define TRANSLATE_YCOORD(C, Y, S) SCALE_YCOORD((C), (Y) - ((C)->y_off * (S)), (S) ) #define READ_PIXEL(C, X, Y) read_pixel((C)->destination_graphic, (X), (Y)) #define DRAW_PIXEL(C, X, Y, COL) draw_solid_pixel((C)->destination_graphic, (X), (Y), (COL)) #define DRAW_ALL(C, COL) \ draw_solid_rectangle((C)->destination_graphic, 0, 0, (C)->width, (C)->height, (COL)) static void get_bitmap_of_character(RegisGraphicsContext const *context, int ch, unsigned maxw, unsigned maxh, Char *pixels, unsigned *w, unsigned *h, unsigned max_pixels); static void init_regis_load_state(RegisParseState *state) { state->load_index = MAX_REGIS_ALPHABETS; state->load_w = 8U; state->load_h = 10U; state->load_alphabet = 1U; /* FIXME: is this the correct default */ state->load_name[0] = '\0'; state->load_glyph = (unsigned) (Char) '\0'; state->load_row = 0U; } static void init_regis_parse_state(RegisParseState *state) { state->command = '_'; state->option = '_'; state->stack_next = 0U; state->load_index = MAX_REGIS_ALPHABETS; init_regis_load_state(state); } static int ifloor(double d) { double dl = floor(d); return (int) dl; } static int isqrt(double d) { double dl = sqrt(d); return (int) dl; } static void draw_regis_pixel(RegisGraphicsContext *context, int x, int y, unsigned value) { unsigned color = 0; switch (context->temporary_write_controls.write_style) { case WRITE_STYLE_OVERLAY: /* * Update pixels with foreground when pattern is 1, * don't change when pattern is 0. */ if (!value) { return; } if (context->temporary_write_controls.invert_pattern) { color = context->background; } else { color = context->temporary_write_controls.foreground; } break; case WRITE_STYLE_REPLACE: /* * Update pixels with foreground when pattern is 1, * set to background when pattern is 0. */ { unsigned fg, bg; if (context->temporary_write_controls.invert_pattern) { fg = context->background; bg = context->temporary_write_controls.foreground; } else { fg = context->temporary_write_controls.foreground; bg = context->background; } color = value ? fg : bg; } break; case WRITE_STYLE_COMPLEMENT: /* * Update pixels with background when pattern is 1, * don't change when pattern is 0. */ if (!value) { return; } color = READ_PIXEL(context, x, y); if (color == COLOR_HOLE) color = context->background; color = color ^ context->all_planes; break; case WRITE_STYLE_ERASE: /* Update pixels to foreground. */ if (context->temporary_write_controls.invert_pattern) { color = context->temporary_write_controls.foreground; } else { color = context->background; } break; } if (context->temporary_write_controls.plane_mask != context->all_planes) { unsigned old_color = READ_PIXEL(context, x, y); if (old_color == COLOR_HOLE) old_color = context->background; color = (color & context->temporary_write_controls.plane_mask) | (old_color & ~context->temporary_write_controls.plane_mask); } DRAW_PIXEL(context, x, y, color); } static void shade_pattern_to_pixel(RegisGraphicsContext *context, unsigned dim, int ref, int x, int y) { unsigned value; if (dim == WRITE_SHADING_REF_X) { int delta = x > ref ? 1 : -1; int curr_x; context->pattern_bit = 1U << (((unsigned) y) & 7U); for (curr_x = ref; curr_x != x + delta; curr_x += delta) { value = context->temporary_write_controls.pattern & context->pattern_bit; draw_regis_pixel(context, curr_x, y, value); } } else if (dim == WRITE_SHADING_REF_Y) { int delta = y > ref ? 1 : -1; int curr_y; for (curr_y = ref; curr_y != y + delta; curr_y += delta) { context->pattern_bit = 1U << (((unsigned) curr_y) & 7U); value = context->temporary_write_controls.pattern & context->pattern_bit; draw_regis_pixel(context, x, curr_y, value); } } else { TRACE(("ERROR: shading requested, but there is no reference axis\n")); } } #define ROT_SHEAR_SCALE 8192 #define SIGNED_UNSIGNED_MOD(VAL, BASE) ( (((VAL) % (int) (BASE)) + (int) (BASE)) % (int) (BASE) ) static unsigned get_shade_character_pixel(Char const *pixels, unsigned w, unsigned h, unsigned smaxf, unsigned scale, int slant_dx, int px, int py) { unsigned wx, wy; unsigned fx, fy; wx = (unsigned) SIGNED_UNSIGNED_MOD(px - (slant_dx * SIGNED_UNSIGNED_MOD(py, smaxf)) / ROT_SHEAR_SCALE, smaxf); wy = (unsigned) SIGNED_UNSIGNED_MOD(py, smaxf); fx = (wx * scale) >> SCALE_FIXED_POINT; fy = (wy * scale) >> SCALE_FIXED_POINT; if (fx < w && fy < h) { return (unsigned) pixels[fy * w + fx]; } return 0U; } static void shade_char_to_pixel(RegisGraphicsContext *context, Char const *pixels, unsigned w, unsigned h, unsigned dim, int ref, int x, int y) { unsigned xmaxf = context->current_text_controls->character_unit_cell_w; unsigned ymaxf = context->current_text_controls->character_unit_cell_h; unsigned smaxf; unsigned s; unsigned scale; unsigned value; if (xmaxf > ymaxf) { smaxf = ymaxf; s = h; } else { smaxf = xmaxf; s = w; } scale = (s << SCALE_FIXED_POINT) / smaxf; if (dim == WRITE_SHADING_REF_X) { int delta = x > ref ? 1 : -1; int curr_x; for (curr_x = ref; curr_x != x + delta; curr_x += delta) { value = get_shade_character_pixel(pixels, w, h, smaxf, scale, 0, curr_x, y); draw_regis_pixel(context, curr_x, y, value); } } else if (dim == WRITE_SHADING_REF_Y) { int delta = y > ref ? 1 : -1; int curr_y; for (curr_y = ref; curr_y != y + delta; curr_y += delta) { value = get_shade_character_pixel(pixels, w, h, smaxf, scale, 0, x, curr_y); draw_regis_pixel(context, x, curr_y, value); } } else { TRACE(("ERROR: shading requested, but there is no reference axis\n")); } } static void draw_patterned_pixel(RegisGraphicsContext *context, int x, int y) { if (context->pattern_count >= context->temporary_write_controls.pattern_multiplier) { context->pattern_count = 0U; context->pattern_bit = ROT_LEFT(context->pattern_bit); } context->pattern_count++; draw_regis_pixel(context, x, y, context->temporary_write_controls.pattern & context->pattern_bit); } static void shade_to_pixel(RegisGraphicsContext *context, unsigned dim, int ref, int x, int y) { if (context->temporary_write_controls.shading_character != '\0') { unsigned xmaxf = context->current_text_controls->character_unit_cell_w; unsigned ymaxf = context->current_text_controls->character_unit_cell_h; char ch = context->temporary_write_controls.shading_character; Char pixels[MAX_GLYPH_PIXELS]; unsigned w, h; get_bitmap_of_character(context, ch, xmaxf, ymaxf, pixels, &w, &h, MAX_GLYPH_PIXELS); if (w > 0 && h > 0) { shade_char_to_pixel(context, pixels, w, h, dim, ref, x, y); } } else { shade_pattern_to_pixel(context, dim, ref, x, y); } } static void draw_or_save_patterned_pixel(RegisGraphicsContext *context, int x, int y) { if (context->fill_mode == 1) { if (context->fill_point_count >= MAX_FILL_POINTS) { TRACE(("point %d,%d can not be added to filled polygon\n", x, y)); return; } if (context->fill_point_count > 0U && context->fill_points[context->fill_point_count - 1U].x == x && context->fill_points[context->fill_point_count - 1U].y == y) { return; } context->fill_points[context->fill_point_count].x = x; context->fill_points[context->fill_point_count].y = y; context->fill_point_count++; return; } if (context->temporary_write_controls.shading_enabled) { unsigned dim = context->temporary_write_controls.shading_reference_dim; int ref = context->temporary_write_controls.shading_reference; shade_to_pixel(context, dim, ref, x, y); return; } draw_patterned_pixel(context, x, y); } static int sort_points(void const *l, void const *r) { RegisPoint const *const lp = (RegisPoint const *) l; RegisPoint const *const rp = (RegisPoint const *) r; if (lp->y < rp->y) return -1; if (lp->y > rp->y) return +1; if (lp->x < rp->x) return -1; if (lp->x > rp->x) return +1; return 0; } static void draw_shaded_polygon(RegisGraphicsContext *context) { unsigned p; int old_x, old_y; int inside; Char pixels[MAX_GLYPH_PIXELS]; unsigned w = 1, h = 1; char ch = context->temporary_write_controls.shading_character; unsigned xmaxf = context->current_text_controls->character_unit_cell_w; unsigned ymaxf = context->current_text_controls->character_unit_cell_h; get_bitmap_of_character(context, ch, xmaxf, ymaxf, pixels, &w, &h, MAX_GLYPH_PIXELS); if (w < 1U || h < 1U) { return; } qsort(context->fill_points, (size_t) context->fill_point_count, sizeof(context->fill_points[0]), sort_points); old_x = DUMMY_STACK_X; old_y = DUMMY_STACK_Y; inside = 0; for (p = 0U; p < context->fill_point_count; p++) { int new_x = context->fill_points[p].x; int new_y = context->fill_points[p].y; /* * FIXME: This is using pixels to represent lines which loses * information about exact slope and how many lines are present which * causes misbehavior with some inputs (especially complex polygons). * It also takes more room than remembering vertices, but I'd rather * not have to implement line segments for arcs. Maybe store a count * at each vertex instead (doesn't fix the slope problem). */ /* * FIXME: Change this to only draw inside of polygons, and round * points in a uniform direction to avoid overlapping drawing. As an * option we could continue to support drawing the outline. */ if (new_y != old_y) { if (inside) { /* * Just draw the vertical line when there is not a matching * edge on the right side. */ shade_char_to_pixel(context, pixels, w, h, WRITE_SHADING_REF_X, old_x, old_x, old_y); } inside = 1; } else { if (inside) { shade_char_to_pixel(context, pixels, w, h, WRITE_SHADING_REF_X, old_x, new_x, new_y); } if (new_x > old_x + 1) { inside = !inside; } } old_x = new_x; old_y = new_y; } context->destination_graphic->dirty = True; } static void draw_filled_polygon(RegisGraphicsContext *context) { unsigned p; int old_x, old_y; int inside; qsort(context->fill_points, (size_t) context->fill_point_count, sizeof(context->fill_points[0]), sort_points); old_x = DUMMY_STACK_X; old_y = DUMMY_STACK_Y; inside = 0; for (p = 0U; p < context->fill_point_count; p++) { int new_x = context->fill_points[p].x; int new_y = context->fill_points[p].y; /* * FIXME: This is using pixels to represent lines which loses * information about exact slope and how many lines are present which * causes misbehavior with some inputs (especially complex polygons). * It also takes more room than remembering vertices, but I'd rather * not have to implement line segments for arcs. Maybe store a count * at each vertex instead (doesn't fix the slope problem). */ /* * FIXME: Change this to only draw inside of polygons, and round * points in a uniform direction to avoid overlapping drawing. As an * option we could continue to support drawing the outline. */ if (new_y != old_y) { if (inside) { /* * Just draw the vertical line when there is not a matching * edge on the right side. */ shade_pattern_to_pixel(context, WRITE_SHADING_REF_X, old_x, old_x, old_y); } inside = 1; } else { if (inside) { shade_pattern_to_pixel(context, WRITE_SHADING_REF_X, old_x, new_x, new_y); } if (new_x > old_x + 1) { inside = !inside; } } old_x = new_x; old_y = new_y; } context->destination_graphic->dirty = True; } static void draw_patterned_line(RegisGraphicsContext *context, int x1, int y1, int x2, int y2) { int x, y; int dx, dy; int dir, diff; dx = abs(x1 - x2); dy = abs(y1 - y2); if (dx > dy) { if (x1 > x2) { int tmp; EXCHANGE(x1, x2, tmp); EXCHANGE(y1, y2, tmp); } if (y1 < y2) dir = 1; else if (y1 > y2) dir = -1; else dir = 0; diff = 0; y = y1; for (x = x1; x <= x2; x++) { if (diff >= dx) { diff -= dx; y += dir; } diff += dy; draw_or_save_patterned_pixel(context, x, y); } } else { if (y1 > y2) { int tmp; EXCHANGE(y1, y2, tmp); EXCHANGE(x1, x2, tmp); } if (x1 < x2) dir = 1; else if (x1 > x2) dir = -1; else dir = 0; diff = 0; x = x1; for (y = y1; y <= y2; y++) { if (diff >= dy) { diff -= dy; x += dir; } diff += dx; draw_or_save_patterned_pixel(context, x, y); } } context->destination_graphic->dirty = True; } typedef struct { int dxx; int dxy; int dyx; int dyy; } quadmap_coords; static void draw_patterned_arc(RegisGraphicsContext *context, int cx, int cy, int ex, int ey, int a_start, int a_length, int *ex_final, int *ey_final) { const double third = hypot((double) (cx - ex), (double) (cy - ey)); const int radius = (int) third; const int ra = radius; const int rb = radius; const quadmap_coords neg_quadmap[4] = { {-1, 0, 0, +1}, {0, -1, -1, 0}, {+1, 0, 0, -1}, {0, +1, +1, 0}, }; const quadmap_coords pos_quadmap[4] = { {-1, 0, 0, -1}, {0, -1, +1, 0}, {+1, 0, 0, +1}, {0, +1, -1, 0}, }; const quadmap_coords *quadmap; int total_points; int half_degree; int points_start, points_stop; int points; unsigned iterations; long rx, ry; long dx, dy; int x, y; long e2; long error; TRACE(("orig a_length=%d a_start=%d\n", a_length, a_start)); if (a_length == 0) return; if (a_length > 0) { quadmap = pos_quadmap; } else { quadmap = neg_quadmap; if (a_start != 0) a_start = 3600 - a_start; a_length = abs(a_length); } TRACE(("positive a_length=%d a_start=%d\n", a_length, a_start)); rx = -ra; ry = 0; e2 = rb; dx = (2 * rx + 1) * e2 * e2; dy = rx * rx; error = dx + dy; total_points = 0; do { total_points += 4; e2 = 2 * error; if (e2 >= dx) { rx++; dx += 2 * rb * rb; error += dx; } if (e2 <= dy) { ry++; dy += 2 * ra * ra; error += dy; } } while (rx <= 0); /* FIXME: This is apparently not accurate enough because some arcs start or * end a few pixels off. Maybe compare line slopes in the loop below * instead? */ half_degree = total_points * 5; points_start = (total_points * a_start - half_degree) / 3600; points_stop = (total_points * a_start + total_points * a_length + half_degree) / 3600; TRACE(("drawing arc with %d points clockwise from %g degrees for %g degrees (from point %d to %d out of %d)\n", total_points, a_start / 10.0, a_length / 10.0, points_start, points_stop, total_points)); /* FIXME: The four pixels at the cardinal directions are double-drawn. */ points = 0; for (iterations = 0U; iterations < 8U; iterations++) { int q2 = iterations & 0x3; rx = -ra; ry = 0; e2 = rb; dx = (2 * rx + 1) * e2 * e2; dy = rx * rx; error = dx + dy; do { #ifdef DEBUG_ARC_POINTS double rad = atan2( (double) (quadmap[q2].dyx * rx + quadmap[q2].dyy * ry), (double) (quadmap[q2].dxx * rx + quadmap[q2].dxy * ry)); double deg = (360.0 * rad / (2.0 * M_PI)); if (deg < 0.0) deg += 360.0; #endif if (points >= points_start && points <= points_stop) { x = (int) (cx + quadmap[q2].dxx * rx + quadmap[q2].dxy * ry); y = (int) (cy + quadmap[q2].dyx * rx + quadmap[q2].dyy * ry); #ifdef DEBUG_ARC_POINTS TRACE(("drawing point %u at %d,%d (%.5g deg)\n", points, x, y, deg)); #endif draw_or_save_patterned_pixel(context, x, y); if (ex_final) *ex_final = x; if (ey_final) *ey_final = y; } else { #ifdef DEBUG_ARC_POINTS x = (int) (cx + quadmap[q2].dxx * rx + quadmap[q2].dxy * ry); y = (int) (cy + quadmap[q2].dyx * rx + quadmap[q2].dyy * ry); TRACE(("skipping point %u at %d,%d which is outside of range (%.5g deg)\n", points, x, y, deg)); #endif } points++; e2 = 2 * error; if (e2 >= dx) { rx++; dx += 2 * rb * rb; error += dx; } if (e2 <= dy) { ry++; dy += 2 * ra * ra; error += dy; } } while (rx <= 0); } context->destination_graphic->dirty = True; } /* * The plot* functions are based on optimized rasterization primitives written * by Zingl Alois. * See http://members.chello.at/easyfilter/bresenham.html */ /* * FIXME: * This is a terrible temporary hack. The plot functions below can be adapted * to work like the other rasterization functions but there's no point in doing * that until we know we don't have to write something completely different. */ static RegisGraphicsContext *global_context; static void setPixel(int x, int y) { draw_or_save_patterned_pixel(global_context, x, y); } static void plotLine(int x0, int y0, int x1, int y1) { int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; int err = dx + dy; /* error value e_xy */ for (;;) { /* loop */ int e2; setPixel(x0, y0); e2 = 2 * err; if (e2 >= dy) { /* e_xy+e_x > 0 */ if (x0 == x1) break; err += dy; x0 += sx; } if (e2 <= dx) { /* e_xy+e_y < 0 */ if (y0 == y1) break; err += dx; y0 += sy; } } } static void plotQuadBezierSeg(int x0, int y0, int x1, int y1, int x2, int y2) { /* plot a limited quadratic Bezier segment */ int sx = x2 - x1; int sy = y2 - y1; long xx = (x0 - x1); /* relative values for checks */ long yy = (y0 - y1); double cur = (double) (xx * sy - yy * sx); /* curvature */ assert(xx * sx <= 0 && yy * sy <= 0); /* sign of gradient must not change */ if (sx * (long) sx + sy * (long) sy > xx * xx + yy * yy) { /* begin with longer part */ x2 = x0; x0 = sx + x1; y2 = y0; y0 = sy + y1; cur = -cur; /* swap P0 P2 */ } if (cur != 0.0) { /* no straight line */ long xy; double dx, dy, err; xx += sx; xx *= (sx = (x0 < x2) ? 1 : -1); /* x step direction */ yy += sy; yy *= (sy = (y0 < y2) ? 1 : -1); /* y step direction */ xy = 2 * xx * yy; xx *= xx; yy *= yy; /* differences 2nd degree */ if (cur * sx * sy < 0) { /* negated curvature? */ xx = -xx; yy = -yy; xy = -xy; cur = -cur; } /* differences 1st degree */ dx = ((4.0 * sy * cur * (x1 - x0)) + (double) xx) - (double) xy; dy = ((4.0 * sx * cur * (y0 - y1)) + (double) yy) - (double) xy; xx += xx; yy += yy; err = dx + dy + (double) xy; /* error 1st step */ do { setPixel(x0, y0); /* plot curve */ if (x0 == x2 && y0 == y2) return; /* last pixel -> curve finished */ y1 = (2 * err) < dx; /* save value for test of y step */ if ((2 * err) > dy) { x0 += sx; dx -= (double) xy; dy += (double) yy; err += dy; } /* x step */ if (y1) { y0 += sy; dy -= (double) xy; dx += (double) xx; err += dx; } /* y step */ } while (dy < 0 && dx > 0); /* gradient negates -> algorithm fails */ } plotLine(x0, y0, x2, y2); /* plot remaining part to end */ } #if 0 static void plotQuadBezier(int x0, int y0, int x1, int y1, int x2, int y2) { /* plot any quadratic Bezier curve */ int x = x0 - x1; int y = y0 - y1; double t = x0 - 2 * x1 + x2; double r; if ((long) x * (x2 - x1) > 0) { /* horizontal cut at P4? */ if ((long) y * (y2 - y1) > 0) /* vertical cut at P6 too? */ if (fabs((y0 - 2 * y1 + y2) / t * x) > abs(y)) { /* which first? */ x0 = x2; x2 = x + x1; y0 = y2; y2 = y + y1; /* swap points */ } /* now horizontal cut at P4 comes first */ t = (x0 - x1) / t; r = (1 - t) * ((1 - t) * y0 + 2.0 * t * y1) + t * t * y2; /* By(t=P4) */ t = (x0 * x2 - x1 * x1) * t / (x0 - x1); /* gradient dP4/dx=0 */ x = ifloor(t + 0.5); y = ifloor(r + 0.5); r = (y1 - y0) * (t - x0) / (x1 - x0) + y0; /* intersect P3 | P0 P1 */ plotQuadBezierSeg(x0, y0, x, ifloor(r + 0.5), x, y); r = (y1 - y2) * (t - x2) / (x1 - x2) + y2; /* intersect P4 | P1 P2 */ x0 = x1 = x; y0 = y; y1 = ifloor(r + 0.5); /* P0 = P4, P1 = P8 */ } if ((long) (y0 - y1) * (y2 - y1) > 0) { /* vertical cut at P6? */ t = y0 - 2 * y1 + y2; t = (y0 - y1) / t; r = (1 - t) * ((1 - t) * x0 + 2.0 * t * x1) + t * t * x2; /* Bx(t=P6) */ t = (y0 * y2 - y1 * y1) * t / (y0 - y1); /* gradient dP6/dy=0 */ x = ifloor(r + 0.5); y = ifloor(t + 0.5); r = (x1 - x0) * (t - y0) / (y1 - y0) + x0; /* intersect P6 | P0 P1 */ plotQuadBezierSeg(x0, y0, ifloor(r + 0.5), y, x, y); r = (x1 - x2) * (t - y2) / (y1 - y2) + x2; /* intersect P7 | P1 P2 */ x0 = x; x1 = ifloor(r + 0.5); y0 = y1 = y; /* P0 = P6, P1 = P7 */ } plotQuadBezierSeg(x0, y0, x1, y1, x2, y2); /* remaining part */ } #endif static void plotCubicBezierSeg(int x0, int y0, double x1, double y1, double x2, double y2, int x3, int y3) { /* plot limited cubic Bezier segment */ int f, fx, fy, tt; int leg = 1; int sx = x0 < x3 ? 1 : -1; int sy = y0 < y3 ? 1 : -1; /* step direction */ double xc = -fabs(x0 + x1 - x2 - x3); double xa = xc - 4 * sx * (x1 - x2); double xb = sx * (x0 - x1 - x2 + x3); double yc = -fabs(y0 + y1 - y2 - y3); double ya = yc - 4 * sy * (y1 - y2); double yb = sy * (y0 - y1 - y2 + y3); double ab, ac, bc, cb, xx, xy, yy, dx, dy, ex, *pxy; double EP = 0.01; /* check for curve restrains */ /* slope P0-P1 == P2-P3 and (P0-P3 == P1-P2 or no slope change) */ assert((x1 - x0) * (x2 - x3) < EP && ((x3 - x0) * (x1 - x2) < EP || xb * xb < xa * xc + EP)); assert((y1 - y0) * (y2 - y3) < EP && ((y3 - y0) * (y1 - y2) < EP || yb * yb < ya * yc + EP)); if (xa == 0.0 && ya == 0.0) { /* quadratic Bezier */ sx = ifloor((3 * x1 - x0 + 1) / 2); sy = ifloor((3 * y1 - y0 + 1) / 2); /* new midpoint */ plotQuadBezierSeg(x0, y0, sx, sy, x3, y3); return; } x1 = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) + 1; /* line lengths */ x2 = (x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3) + 1; do { /* loop over both ends */ ab = xa * yb - xb * ya; ac = xa * yc - xc * ya; bc = xb * yc - xc * yb; ex = ab * (ab + ac - 3 * bc) + ac * ac; /* P0 part of self-intersection loop? */ f = ((ex > 0.0) ? 1 : isqrt(1 + 1024 / x1)); /* calculate resolution */ ab *= f; ac *= f; bc *= f; ex *= f * f; /* increase resolution */ xy = 9 * (ab + ac + bc) / 8; cb = 8 * (xa - ya); /* init differences of 1st degree */ dx = 27 * (8 * ab * (yb * yb - ya * yc) + ex * (ya + 2 * yb + yc)) / 64 - ya * ya * (xy - ya); dy = 27 * (8 * ab * (xb * xb - xa * xc) - ex * (xa + 2 * xb + xc)) / 64 - xa * xa * (xy + xa); /* init differences of 2nd degree */ xx = 3 * (3 * ab * (3 * yb * yb - ya * ya - 2 * ya * yc) - ya * (3 * ac * (ya + yb) + ya * cb)) / 4; yy = 3 * (3 * ab * (3 * xb * xb - xa * xa - 2 * xa * xc) - xa * (3 * ac * (xa + xb) + xa * cb)) / 4; xy = xa * ya * (6 * ab + 6 * ac - 3 * bc + cb); ac = ya * ya; cb = xa * xa; xy = 3 * (xy + 9 * f * (cb * yb * yc - xb * xc * ac) - 18 * xb * yb * ab) / 8; if (ex < 0) { /* negate values if inside self-intersection loop */ dx = -dx; dy = -dy; xx = -xx; yy = -yy; xy = -xy; ac = -ac; cb = -cb; } /* init differences of 3rd degree */ ab = 6 * ya * ac; ac = -6 * xa * ac; bc = 6 * ya * cb; cb = -6 * xa * cb; dx += xy; ex = dx + dy; dy += xy; /* error of 1st step */ for (pxy = &xy, fx = fy = f; x0 != x3 && y0 != y3;) { setPixel(x0, y0); /* plot curve */ do { /* move sub-steps of one pixel */ if (dx > *pxy || dy < *pxy) goto exit; /* confusing values */ y1 = 2 * ex - dy; /* save value for test of y step */ if (2 * ex >= dx) { /* x sub-step */ fx--; ex += dx += xx; dy += xy += ac; yy += bc; xx += ab; } if (y1 <= 0) { /* y sub-step */ fy--; ex += dy += yy; dx += xy += bc; xx += ac; yy += cb; } } while (fx > 0 && fy > 0); /* pixel complete? */ if (2 * fx <= f) { x0 += sx; fx += f; } /* x step */ if (2 * fy <= f) { y0 += sy; fy += f; } /* y step */ if (pxy == &xy && dx < 0 && dy > 0) pxy = &EP; /* pixel ahead valid */ } exit: EXCHANGE(x0, x3, tt); sx = -sx; xb = -xb; /* swap legs */ EXCHANGE(y0, y3, tt); sy = -sy; yb = -yb; x1 = x2; } while (leg--); /* try other end */ plotLine(x0, y0, x3, y3); /* remaining part in case of cusp or crunode */ } static void plotCubicBezier(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { /* plot any cubic Bezier curve */ int n = 0, i = 0; long xc = x0 + x1 - x2 - x3; long xa = xc - 4 * (x1 - x2); long xb = x0 - x1 - x2 + x3; long xd = xb + 4 * (x1 + x2); long yc = y0 + y1 - y2 - y3; long ya = yc - 4 * (y1 - y2); long yb = y0 - y1 - y2 + y3; long yd = yb + 4 * (y1 + y2); double fx0 = x0; double fy0 = y0; double t1 = (double) (xb * xb - xa * xc), t2, t[5]; #ifdef DEBUG_BEZIER printf("plotCubicBezier(%d,%d, %d,%d, %d,%d, %d,%d\n", x0, y0, x1, y1, x2, y2, x3, y3); #endif /* sub-divide curve at gradient sign changes */ if (xa == 0) { /* horizontal */ if (labs(xc) < 2 * labs(xb)) t[n++] = (double) xc / (2.0 * (double) xb); /* one change */ } else if (t1 > 0.0) { /* two changes */ t2 = sqrt(t1); t1 = ((double) xb - t2) / (double) xa; if (fabs(t1) < 1.0) t[n++] = t1; t1 = ((double) xb + t2) / (double) xa; if (fabs(t1) < 1.0) t[n++] = t1; } t1 = (double) (yb * yb - ya * yc); if (ya == 0) { /* vertical */ if (labs(yc) < 2 * labs(yb)) t[n++] = (double) yc / (2.0 * (double) yb); /* one change */ } else if (t1 > 0.0) { /* two changes */ t2 = sqrt(t1); t1 = ((double) yb - t2) / (double) ya; if (fabs(t1) < 1.0) t[n++] = t1; t1 = ((double) yb + t2) / (double) ya; if (fabs(t1) < 1.0) t[n++] = t1; } for (i = 1; i < n; i++) /* bubble sort of 4 points */ if ((t1 = t[i - 1]) > t[i]) { t[i - 1] = t[i]; t[i] = t1; i = 0; } t1 = -1.0; t[n] = 1.0; /* begin / end point */ for (i = 0; i <= n; i++) { /* plot each segment separately */ double fx1, fx2, fx3; double fy1, fy2, fy3; t2 = t[i]; /* sub-divide at t[i-1], t[i] */ fx1 = (t1 * (t1 * (double) xb - (double) (2 * xc)) - t2 * (t1 * (t1 * (double) xa - (double) (2 * xb)) + (double) xc) + (double) xd) / 8 - fx0; fy1 = (t1 * (t1 * (double) yb - (double) (2 * yc)) - t2 * (t1 * (t1 * (double) ya - (double) (2 * yb)) + (double) yc) + (double) yd) / 8 - fy0; fx2 = (t2 * (t2 * (double) xb - (double) (2 * xc)) - t1 * (t2 * (t2 * (double) xa - (double) (2 * xb)) + (double) xc) + (double) xd) / 8 - fx0; fy2 = (t2 * (t2 * (double) yb - (double) (2 * yc)) - t1 * (t2 * (t2 * (double) ya - (double) (2 * yb)) + (double) yc) + (double) yd) / 8 - fy0; fx0 -= fx3 = (t2 * (t2 * ((double) (3 * xb) - t2 * (double) xa) - (double) (3 * xc)) + (double) xd) / 8; fy0 -= fy3 = (t2 * (t2 * ((double) (3 * yb) - t2 * (double) ya) - (double) (3 * yc)) + (double) yd) / 8; x3 = ifloor(fx3 + 0.5); y3 = ifloor(fy3 + 0.5); /* scale bounds to int */ if (fx0 != 0.0) { fx1 *= fx0 = (x0 - x3) / fx0; fx2 *= fx0; } if (fy0 != 0.0) { fy1 *= fy0 = (y0 - y3) / fy0; fy2 *= fy0; } if (x0 != x3 || y0 != y3) /* segment t1 - t2 */ plotCubicBezierSeg(x0, y0, x0 + fx1, y0 + fy1, x0 + fx2, y0 + fy2, x3, y3); x0 = x3; y0 = y3; fx0 = fx3; fy0 = fy3; t1 = t2; } } #if 0 static void plotQuadSpline(int n, int x[], int y[], int skip_segments) { /* plot quadratic spline, destroys input arrays x,y */ #define M_MAX 12 double mi = 1, m[M_MAX]; /* diagonal constants of matrix */ int i, x0, y0, x1, y1, x2, y2; #ifdef DEBUG_SPLINE_SEGMENTS int color = 0; #endif assert(n > 1); /* need at least 3 points P[0]..P[n] */ #ifdef DEBUG_SPLINE_POINTS { int save_pattern; i = 0; global_context->temporary_write_controls.foreground = 11; save_pattern = global_context->temporary_write_controls.pattern; global_context->temporary_write_controls.pattern = 0xff; draw_patterned_arc(global_context, x[i], y[i], x[i] + 2, y[i], 0, 3600, NULL, NULL); i++; global_context->temporary_write_controls.foreground = 15; for (; i < n; i++) { draw_patterned_arc(global_context, x[i], y[i], x[i] + 2, y[i], 0, 3600, NULL, NULL); } global_context->temporary_write_controls.foreground = 10; draw_patterned_arc(global_context, x[i], y[n], x[i] + 2, y[i], 0, 3600, NULL, NULL); global_context->temporary_write_controls.pattern = save_pattern; } #endif x2 = x[n]; y2 = y[n]; x[1] = x0 = 8 * x[1] - 2 * x[0]; /* first row of matrix */ y[1] = y0 = 8 * y[1] - 2 * y[0]; for (i = 2; i < n; i++) { /* forward sweep */ if (i - 2 < M_MAX) m[i - 2] = mi = 1.0 / (6.0 - mi); x[i] = x0 = ifloor(8 * x[i] - x0 * mi + 0.5); /* store yi */ y[i] = y0 = ifloor(8 * y[i] - y0 * mi + 0.5); } x1 = ifloor((x0 - 2 * x2) / (5.0 - mi) + 0.5); /* correction last row */ y1 = ifloor((y0 - 2 * y2) / (5.0 - mi) + 0.5); for (i = n - 2; i > 0; i--) { /* back substitution */ if (i <= M_MAX) mi = m[i - 1]; x0 = ifloor((x[i] - x1) * mi + 0.5); /* next corner */ y0 = ifloor((y[i] - y1) * mi + 0.5); #ifdef DEBUG_SPLINE_SEGMENTS color++; global_context->temporary_write_controls.foreground = color; #endif if ((n - 2) - i < skip_segments) plotQuadBezier((x0 + x1) / 2, (y0 + y1) / 2, x1, y1, x2, y2); x2 = (x0 + x1) / 2; x1 = x0; y2 = (y0 + y1) / 2; y1 = y0; } #ifdef DEBUG_SPLINE_SEGMENTS color++; global_context->temporary_write_controls.foreground = color; #endif if (skip_segments > 0) plotQuadBezier(x[0], y[0], x1, y1, x2, y2); } #endif static void plotCubicSpline(int n, int x[], int y[], int skip_first_last) { #define M_MAX 12 double mi = 0.25, m[M_MAX]; /* diagonal constants of matrix */ int x3, y3, x4, y4; int i, x0, y0, x1, y1, x2, y2; #ifdef DEBUG_SPLINE_SEGMENTS RegisterNum color = 0; #endif assert(n > 2); /* need at least 4 points P[0]..P[n] */ #ifdef __CPPCHECK__ memset(m, 0, sizeof(m)); /* work around false-positive */ #endif #ifdef DEBUG_SPLINE_POINTS { unsigned save_pattern; i = 0; global_context->temporary_write_controls.foreground = 11; save_pattern = global_context->temporary_write_controls.pattern; global_context->temporary_write_controls.pattern = 0xff; draw_patterned_arc(global_context, x[i], y[i], x[i] + 2, y[i], 0, 3600, NULL, NULL); i++; global_context->temporary_write_controls.foreground = 15; for (; i < n; i++) { draw_patterned_arc(global_context, x[i], y[i], x[i] + 2, y[i], 0, 3600, NULL, NULL); } global_context->temporary_write_controls.foreground = 10; draw_patterned_arc(global_context, x[i], y[i], x[i] + 2, y[i], 0, 3600, NULL, NULL); global_context->temporary_write_controls.pattern = save_pattern; } #endif x3 = x[n - 1]; y3 = y[n - 1]; x4 = x[n]; y4 = y[n]; x[1] = x0 = 12 * x[1] - 3 * x[0]; /* first row of matrix */ y[1] = y0 = 12 * y[1] - 3 * y[0]; for (i = 2; i < n; i++) { /* forward sweep */ if (i - 2 < M_MAX) m[i - 2] = mi = 0.25 / (2.0 - mi); x[i] = x0 = ifloor(12 * x[i] - 2 * x0 * mi + 0.5); y[i] = y0 = ifloor(12 * y[i] - 2 * y0 * mi + 0.5); } x2 = ifloor((x0 - 3 * x4) / (7 - 4 * mi) + 0.5); /* correct last row */ /* printf("y0=%d, y4=%d mi=%g\n", y0, y4, mi); */ y2 = ifloor((y0 - 3 * y4) / (7 - 4 * mi) + 0.5); /* printf("y2=%d, y3=%d, y4=%d\n", y2, y3, y4); */ #ifdef DEBUG_SPLINE_SEGMENTS color++; global_context->temporary_write_controls.foreground = color; #endif if (!skip_first_last) plotCubicBezier(x3, y3, (x2 + x4) / 2, (y2 + y4) / 2, x4, y4, x4, y4); if (n - 3 < M_MAX) mi = m[n - 3]; x1 = ifloor((x[n - 2] - 2 * x2) * mi + 0.5); y1 = ifloor((y[n - 2] - 2 * y2) * mi + 0.5); for (i = n - 3; i > 0; i--) { /* back substitution */ if (i <= M_MAX) mi = m[i - 1]; x0 = ifloor((x[i] - 2 * x1) * mi + 0.5); y0 = ifloor((y[i] - 2 * y1) * mi + 0.5); x4 = ifloor((x0 + 4 * x1 + x2 + 3) / 6.0); /* reconstruct P[i] */ y4 = ifloor((y0 + 4 * y1 + y2 + 3) / 6.0); #ifdef DEBUG_SPLINE_SEGMENTS color++; global_context->temporary_write_controls.foreground = color; #endif #define CB_PARM(num) ifloor((num) / 3.0 + 0.5) plotCubicBezier(x4, y4, CB_PARM(2 * x1 + x2), CB_PARM(2 * y1 + y2), CB_PARM(x1 + 2 * x2), CB_PARM(y1 + 2 * y2), x3, y3); x3 = x4; y3 = y4; x2 = x1; y2 = y1; x1 = x0; y1 = y0; } x0 = x[0]; x4 = ifloor((3 * x0 + 7 * x1 + 2 * x2 + 6) / 12.0); /* reconstruct P[1] */ y0 = y[0]; y4 = ifloor((3 * y0 + 7 * y1 + 2 * y2 + 6) / 12.0); #ifdef DEBUG_SPLINE_SEGMENTS global_context->temporary_write_controls.foreground = 4; #endif plotCubicBezier(x4, y4, CB_PARM(2 * x1 + x2), CB_PARM(2 * y1 + y2), CB_PARM(x1 + 2 * x2), CB_PARM(y1 + 2 * y2), x3, y3); #ifdef DEBUG_SPLINE_SEGMENTS color++; global_context->temporary_write_controls.foreground = color; #endif if (!skip_first_last) plotCubicBezier(x0, y0, x0, y0, (x0 + x1) / 2, (y0 + y1) / 2, x4, y4); } static unsigned find_free_alphabet_index(RegisGraphicsContext *context, unsigned alphabet, unsigned pixw, unsigned pixh) { unsigned ii, jj; /* try an exact match */ for (ii = 0U; ii < MAX_REGIS_ALPHABETS; ii++) { if (context->alphabets[ii].alphabet_num == alphabet && context->alphabets[ii].pixw == pixw && context->alphabets[ii].pixh == pixh) { return ii; } } /* otherwise use any empty slot */ for (ii = 0U; ii < MAX_REGIS_ALPHABETS; ii++) { if (context->alphabets[ii].alphabet_num == INVALID_ALPHABET_NUM) { context->alphabets[ii].alphabet_num = alphabet; context->alphabets[ii].pixw = pixw; context->alphabets[ii].pixh = pixh; return ii; } } /* otherwise recycle a slot with a different font size */ for (ii = 0U; ii < MAX_REGIS_ALPHABETS; ii++) { if (context->alphabets[ii].alphabet_num == alphabet) { context->alphabets[ii].pixw = pixw; context->alphabets[ii].pixh = pixh; context->alphabets[ii].name[0] = '\0'; context->alphabets[ii].fontname[0] = '\0'; context->alphabets[ii].use_font = 0; if (context->alphabets[ii].bytes != NULL) { free(context->alphabets[ii].bytes); context->alphabets[ii].bytes = NULL; } for (jj = 0U; jj < MAX_GLYPHS; jj++) { context->alphabets[ii].loaded[jj] = 0; } return ii; } } /* finally just recycle this arbitrary slot */ context->alphabets[0U].alphabet_num = alphabet; context->alphabets[0U].pixw = pixw; context->alphabets[0U].pixh = pixh; context->alphabets[0U].name[0] = '\0'; context->alphabets[0U].fontname[0] = '\0'; context->alphabets[0U].use_font = 0; if (context->alphabets[0U].bytes != NULL) { free(context->alphabets[0U].bytes); context->alphabets[0U].bytes = NULL; } for (jj = 0U; jj < MAX_GLYPHS; jj++) { context->alphabets[0U].loaded[jj] = 0; } return 0U; } #ifdef DEBUG_SPECIFIC_CHAR_METRICS static void dump_bitmap_pixels(Char const *pixels, unsigned w, unsigned h) { unsigned yy, xx; for (yy = 0U; yy < h; yy++) { printf(" "); for (xx = 0U; xx < w; xx++) { if (pixels[yy * w + xx]) { printf("#"); } else { printf("_"); } } printf("\n"); } } #endif #if OPT_RENDERFONT && defined(HAVE_TYPE_FCCHAR32) static int copy_bitmap_from_xft_font(XtermWidget xw, XftFont *font, FcChar32 ch, Char *pixels, unsigned w, unsigned h, unsigned xmin, unsigned ymin) { /* * FIXME: cache: * - the bitmap for the last M characters and target dimensions * - reuse the pixmap object where possible */ Display *display = XtDisplay(xw); Screen *screen = XtScreen(xw); XftColor bg, fg; Pixmap bitmap; XftDraw *draw; XImage *image; GC glyph_gc; unsigned bmw, bmh; unsigned xx, yy; bmw = w + xmin; bmh = h; if (bmw < 1 || bmh < 1) { TRACE(("refusing impossible bitmap size w=%d h=%d xmin=%d ymin=%d for ch='%c'\n", bmw, bmh, xmin, ymin, ch)); return 0; } bitmap = XCreatePixmap(display, DefaultRootWindow(display), bmw, bmh, (unsigned) getVisualDepth(xw)); if (bitmap == None) { TRACE(("unable to create Pixmap for Xft\n")); return 0; } draw = XftDrawCreate(display, bitmap, xw->visInfo->visual, XDefaultColormap(display, XScreenNumberOfScreen(screen))); if (!draw) { TRACE(("unable to create XftDraw\n")); XFreePixmap(display, bitmap); return 0; } bg.pixel = 0UL; bg.color.red = 0; bg.color.green = 0; bg.color.blue = 0; bg.color.alpha = 0x0; XftDrawRect(draw, &bg, 0, 0, bmw, bmh); fg.pixel = 1UL; fg.color.red = 0xffff; fg.color.green = 0xffff; fg.color.blue = 0xffff; fg.color.alpha = 0xffff; XftDrawString32(draw, &fg, font, -(int) xmin, font->ascent - (int) ymin, &ch, 1); glyph_gc = XCreateGC(display, bitmap, 0UL, NULL); if (!glyph_gc) { TRACE(("unable to create GC\n")); XftDrawDestroy(draw); XFreePixmap(display, bitmap); return 0; } XSetForeground(display, glyph_gc, 1UL); XSetBackground(display, glyph_gc, 0UL); image = XGetImage(display, bitmap, 0, 0, w, h, 1UL, XYPixmap); if (!image) { TRACE(("unable to create XImage\n")); XFreeGC(display, glyph_gc); XftDrawDestroy(draw); XFreePixmap(display, bitmap); return 0; } for (yy = 0U; yy < h; yy++) { #ifdef DEBUG_XFT_GLYPH_COPY TRACE(("'%c'[%02u]:", ch, yy)); #endif for (xx = 0U; xx < w; xx++) { unsigned long pix; pix = XGetPixel(image, (int) xx, (int) yy); pixels[yy * w + xx] = (unsigned char) pix; #ifdef DEBUG_XFT_GLYPH_COPY TRACE((" %lu", pix)); #endif } #ifdef DEBUG_XFT_GLYPH_COPY TRACE(("\n")); #endif } XFreeGC(display, glyph_gc); XDestroyImage(image); XftDrawDestroy(draw); XFreePixmap(display, bitmap); return 1; } static void get_xft_glyph_dimensions(XtermWidget xw, XftFont *font, unsigned *w, unsigned *h, unsigned *xmin, unsigned *ymin) { unsigned workw, workh; FcChar32 ch; Char *pixels; Char *pixelp; unsigned yy, xx; unsigned char_count, pixel_count; unsigned real_minx, real_maxx, real_miny, real_maxy; unsigned char_minx, char_maxx, char_miny, char_maxy; /* * For each ASCII or ISO-8859-1 printable code, find out what its * dimensions are. * * We actually render the glyphs and determine the extents ourselves * because the font library can lie by several pixels, and since we are * doing manual character placement in fixed areas the glyph boundary needs * to be accurate. * * Ignore control characters and spaces - their extent information is * misleading. */ /* Our "work area" is just a buffer which should be big enough to hold the * largest glyph even if its size is under-reported by a couple of pixels * in each dimension. */ workw = (unsigned) font->max_advance_width + 2U; if (font->ascent + font->descent > font->height) { workh = (unsigned) (font->ascent + font->descent) + 2U; } else { workh = (unsigned) font->height + 2U; } if (!(pixels = TypeMallocN(Char, (size_t) (workw * workh)))) { *w = 0U; *h = 0U; #ifdef DEBUG_COMPUTED_FONT_METRICS TRACE(("reported metrics:\n")); TRACE((" %ux%u ascent=%u descent=%u\n", font->max_advance_width, font->height, font->ascent, font->descent)); TRACE(("computed metrics:\n")); TRACE((" (unable to allocate pixel array)\n")); #endif return; } /* FIXME: ch is in UCS32 -- try to support non-ASCII characters */ char_count = 0U; real_minx = workw - 1U; real_maxx = 0U; real_miny = workh - 1U; real_maxy = 0U; for (ch = 33; ch < 256; ++ch) { if (ch >= 127 && ch <= 160) { #ifdef DEBUG_SPECIFIC_CHAR_METRICS if (IS_DEBUG_CHAR(ch)) printf("char: '%c' not in interesting range; ignoring\n", (char) ch); #endif continue; } if (!FcCharSetHasChar(font->charset, ch)) { #ifdef DEBUG_SPECIFIC_CHAR_METRICS if (IS_DEBUG_CHAR(ch)) printf("char: '%c' not in charset; ignoring\n", (char) ch); #endif continue; } if (!copy_bitmap_from_xft_font(xw, font, ch, pixels, workw, workh, 0U, 0U)) { #ifdef DEBUG_SPECIFIC_CHAR_METRICS if (IS_DEBUG_CHAR(ch)) printf("char: '%c' bitmap could not be copied; ignoring\n", (char) ch); #endif continue; } pixel_count = 0U; char_minx = workh - 1U; char_maxx = 0U; char_miny = workh - 1U; char_maxy = 0U; pixelp = pixels; for (yy = 0U; yy < workh; yy++) { for (xx = 0U; xx < workw; xx++) { if (*pixelp++) { if (xx < char_minx) char_minx = xx; else if (xx > char_maxx) char_maxx = xx; if (yy < char_miny) char_miny = yy; else if (yy > char_maxy) char_maxy = yy; pixel_count++; } } } if (pixel_count < 1U) { #ifdef DEBUG_SPECIFIC_CHAR_METRICS if (IS_DEBUG_CHAR(ch)) printf("char: '%c' has no pixels; ignoring\n", (char) ch); #endif continue; } #ifdef DEBUG_SPECIFIC_CHAR_METRICS if (IS_DEBUG_CHAR(ch)) { printf("char: '%c' (%d)\n", (char) ch, ch); printf(" minx: %u\n", char_minx); printf(" maxx: %u\n", char_maxx); printf(" miny: %u\n", char_miny); printf(" maxy: %u\n", char_maxy); dump_bitmap_pixels(pixels, workw, workh); printf("\n"); } #endif if (char_minx < real_minx) real_minx = char_minx; if (char_maxx > real_maxx) real_maxx = char_maxx; if (char_miny < real_miny) real_miny = char_miny; if (char_maxy > real_maxy) real_maxy = char_maxy; char_count++; } free(pixels); if (char_count < 1U) { #ifdef DEBUG_COMPUTED_FONT_METRICS TRACE(("reported metrics:\n")); TRACE((" %ux%u ascent=%u descent=%u\n", font->max_advance_width, font->height, font->ascent, font->descent)); TRACE(("computed metrics:\n")); TRACE((" (no characters found)\n")); #endif *w = 0U; *h = 0U; return; } *w = (unsigned) (1 + real_maxx - real_minx); *h = (unsigned) (1 + real_maxy - real_miny); *xmin = real_minx; *ymin = real_miny; #ifdef DEBUG_COMPUTED_FONT_METRICS printf("reported metrics:\n"); printf(" %ux%u ascent=%u descent=%u\n", font->max_advance_width, font->height, font->ascent, font->descent); printf("computed metrics:\n"); printf(" real_minx=%u real_maxx=%u real_miny=%u real_maxy=%u\n", real_minx, real_maxx, real_miny, real_maxy); printf(" final: %ux%u xmin=%u ymin=%u\n", *w, *h, *xmin, *ymin); #endif } #define FONT_SIZE_CACHE_SIZE 32U typedef struct { XftFont *font_data; char fontname[REGIS_FONTNAME_LEN]; unsigned maxw, maxh, max_pixels; unsigned targeth; unsigned w, h; unsigned xmin; unsigned ymin; } FONT_CACHE; static FONT_CACHE font_cache[FONT_SIZE_CACHE_SIZE]; static void close_xft_font(XtermWidget xw, XftFont *font) { if (font != NULL) { Display *display = XtDisplay(xw); unsigned ii; for (ii = 0; ii < FONT_SIZE_CACHE_SIZE; ++ii) { if (font == font_cache[ii].font_data) { font_cache[ii].font_data = NULL; break; } } XftFontClose(display, font); } } /* Find the font pixel size which returns the font which is closest to the given * maxw and maxh without overstepping either dimension. */ static XftFont * find_best_xft_font_size(XtermWidget xw, char const *fontname, unsigned maxw, unsigned maxh, unsigned max_pixels, unsigned *w, unsigned *h, unsigned *xmin, unsigned *ymin) { Display *display = XtDisplay(xw); Screen *screen = XtScreen(xw); XftFont *font; unsigned targeth; unsigned ii; FONT_CACHE *cp = NULL; assert(display); assert(screen); assert(fontname); assert(w); assert(h); assert(xmin); assert(ymin); #ifdef DEBUG_FONT_SIZE_SEARCH TRACE(("determining best size of font \"%s\" for %ux%u glyph with max_pixels=%u\n", fontname, maxw, maxh, max_pixels)); #endif for (ii = 0U; ii < FONT_SIZE_CACHE_SIZE; ii++) { if (font_cache[ii].maxw == maxw && font_cache[ii].maxh == maxh && font_cache[ii].max_pixels == max_pixels && strcmp(font_cache[ii].fontname, fontname) == 0) { cp = &font_cache[ii]; if (cp->font_data) { *w = cp->w; *h = cp->h; *xmin = cp->xmin; *ymin = cp->ymin; return cp->font_data; } break; } } if (cp != NULL) { targeth = cp->targeth; } else { targeth = maxh * 8U + 5U; } #define MAX_TARGETH 720U /* above this level, fontconfig chokes */ if (targeth > MAX_TARGETH) targeth = MAX_TARGETH; for (;;) { if (targeth <= 5U) { TRACE(("Giving up finding suitable Xft font size for \"%s\" at %ux%u.\n", fontname, maxw, maxh)); return NULL; } /* * Xft does a bad job at: * - two-color low-resolution anti-aliased fonts * - non-anti-aliased fonts at low resolution unless a font size is * given (pixel size does not help, and the value of the font size * doesn't appear to matter). * * In those two cases it literally drops pixels, sometimes whole * columns, making the glyphs unreadable and at least ugly even when * readable. */ font = NULL; /* * FIXME: * Also, we need to scale the width and height separately. The * CHAR_WIDTH and CHAR_HEIGHT attributes would seem to be ideal, but * don't appear to have any effect if set. Instead we will manually * scale the bitmap later, which may be very ugly because we won't try * to identify different parts of glyphs or preserve density. */ { XftPattern *pat; XftPattern *match; XftResult status; if ((pat = XftNameParse(fontname)) != NULL) { #ifdef DEBUG_FONT_SIZE_SEARCH TRACE(("trying targeth=%g\n", targeth / 10.0)); #endif XftPatternBuild(pat, XFT_PIXEL_SIZE, XftTypeDouble, (double) targeth / 10.0, XFT_SPACING, XftTypeInteger, XFT_MONO, XFT_SLANT, XftTypeInteger, 0, XFT_ANTIALIAS, XftTypeBool, False, NULL); if ((match = XftFontMatch(display, XScreenNumberOfScreen(screen), pat, &status)) != NULL) { font = XftFontOpenPattern(display, match); maybeXftCache(xw, font); } XftPatternDestroy(pat); } } if (!font) { TRACE(("unable to open a monospaced Xft font matching \"%s\" with pixelsize %g\n", fontname, targeth / 10.0)); return NULL; } #ifdef DEBUG_FONT_SIZE_SEARCH { char buffer[1024]; if (XftNameUnparse(font->pattern, buffer, (int) sizeof(buffer))) { TRACE(("Testing font named \"%s\"\n", buffer)); } else { TRACE(("Testing unknown font\n")); } } #endif if (cp != NULL && targeth == cp->targeth) { *w = cp->w; *h = cp->h; *xmin = cp->xmin; *ymin = cp->ymin; } else { get_xft_glyph_dimensions(xw, font, w, h, xmin, ymin); if (*w < 1 || *h < 1) { #ifdef DEBUG_FONT_SIZE_SEARCH TRACE(("got %ux%u dimensions for target size targeth=%d; trying reduced target size\n", *w, *h, targeth)); #endif targeth--; continue; } } #ifdef DEBUG_FONT_SIZE_SEARCH TRACE(("checking max=%ux%u targeth=%u.%u\n", maxw, maxh, targeth / 10U, targeth % 10U)); #endif if (*h > maxh) { float ratio = (float) (*h) / (float) maxh; XftFontClose(display, font); #ifdef DEBUG_FONT_SIZE_SEARCH TRACE(("got %ux%u glyph; too tall; reducing target size\n", *w, *h)); #endif if (targeth >= 10U && ratio > 1.1) { targeth = (unsigned) ((float) targeth / ratio); } else { targeth--; } continue; } if (*w > maxw) { float ratio = (float) (*w) / (float) maxw; XftFontClose(display, font); #ifdef DEBUG_FONT_SIZE_SEARCH TRACE(("got %ux%u glyph; too wide; reducing target size\n", *w, *h)); #endif if (targeth >= 10U && ratio > 1.1) { targeth = (unsigned) ((float) targeth / ratio); } else { targeth--; } continue; } if (*w * *h > max_pixels) { XftFontClose(display, font); #ifdef DEBUG_FONT_SIZE_SEARCH TRACE(("got %ux%u glyph; too many pixels; reducing target size\n", *w, *h)); #endif if (*w * *h > 2U * max_pixels) { unsigned min = *w < *h ? *w : *h; unsigned divisor = (*w * *h) / (max_pixels * min); if (divisor > 1U) { targeth /= divisor; } else if (targeth > 10U) { targeth -= 10U; } else { targeth--; } } else { targeth--; } continue; } #ifdef DEBUG_FONT_NAME { char buffer[1024]; if (XftNameUnparse(font->pattern, buffer, (int) sizeof(buffer))) { TRACE(("Final font for \"%s\" max %dx%d is \"%s\"\n", fontname, maxw, maxh, buffer)); } else { TRACE(("Final font for \"%s\" max %dx%d is unknown\n", fontname, maxw, maxh)); } } #endif if (cp == NULL) { for (ii = 0U; ii < FONT_SIZE_CACHE_SIZE; ii++) { if (font_cache[ii].maxw == 0U || font_cache[ii].maxh == 0U || font_cache[ii].max_pixels == 0U) { cp = &font_cache[ii]; break; } } if (cp == NULL) { ii = targeth % FONT_SIZE_CACHE_SIZE; cp = &font_cache[ii]; close_xft_font(xw, cp->font_data); } CopyFontname(cp->fontname, fontname); cp->maxw = maxw; cp->maxh = maxh; cp->max_pixels = max_pixels; cp->targeth = targeth; cp->w = *w; cp->h = *h; cp->xmin = *xmin; cp->ymin = *ymin; } cp->font_data = font; return font; } } #endif static int get_xft_bitmap_of_character(RegisGraphicsContext const *context, char const *fontname, int ch, unsigned maxw, unsigned maxh, Char *pixels, unsigned max_pixels, unsigned *w, unsigned *h) { /* * See Xft / RENDERFONT stuff in fontutils.c and used in utils.c * Add a separate configuration for ReGIS. */ /* * FIXME: cache: * - reuse the font where possible */ #ifdef XRENDERFONT XtermWidget xw = context->destination_graphic->xw; XftFont *font; unsigned xmin = 0U, ymin = 0U; # ifdef DEBUG_XFT_GLYPH_LOADING TRACE(("trying to load glyph '%c' at max size %dx%d\n", ch, maxw, maxh)); # endif if (!(font = find_best_xft_font_size(xw, fontname, maxw, maxh, max_pixels, w, h, &xmin, &ymin))) { TRACE(("Unable to find suitable Xft font\n")); return 0; } if (*w == 0U || *h == 0U) { TRACE(("empty glyph found for '%c'\n", ch)); close_xft_font(xw, font); return 1; } if (!copy_bitmap_from_xft_font(xw, font, CharOf(ch), pixels, *w, *h, xmin, ymin)) { TRACE(("Unable to create bitmap for '%c'\n", ch)); close_xft_font(xw, font); return 0; } # ifdef DEBUG_XFT_GLYPH_LOADING TRACE(("loaded glyph '%c' at max size %dx%d\n", ch, maxw, maxh)); # endif return 1; #else (void) context; (void) fontname; (void) ch; (void) maxw; (void) maxh; (void) pixels; (void) max_pixels; (void) w; (void) h; TRACE(("Not rendering Xft font for ReGIS (support not compiled in).\n")); return 0; #endif } static unsigned find_best_alphabet_index(RegisGraphicsContext const *context, unsigned minw, unsigned minh, unsigned targetw, unsigned targeth, unsigned max_pixels) { unsigned ii; unsigned bestmatch; unsigned bestw, besth; assert(context); assert(targetw); assert(targeth); assert(max_pixels); bestmatch = MAX_REGIS_ALPHABETS; bestw = 0U; besth = 0U; for (ii = 0U; ii < MAX_REGIS_ALPHABETS; ii++) { if (context->alphabets[ii].alphabet_num == context->current_text_controls->alphabet_num && context->alphabets[ii].pixw >= minw && context->alphabets[ii].pixh >= minh && context->alphabets[ii].pixw <= targetw && context->alphabets[ii].pixh <= targeth && ((context->alphabets[ii].pixw >= bestw && context->alphabets[ii].pixh > besth) || (context->alphabets[ii].pixw > bestw && context->alphabets[ii].pixh >= besth)) && context->alphabets[ii].pixw * context->alphabets[ii].pixh <= max_pixels) { bestmatch = ii; bestw = context->alphabets[ii].pixw; besth = context->alphabets[ii].pixh; } } /* If we can't find one to scale up, look for one to scale down. */ if (bestmatch == MAX_REGIS_ALPHABETS) { bestw = max_pixels; besth = max_pixels; for (ii = 0U; ii < MAX_REGIS_ALPHABETS; ii++) { if (context->alphabets[ii].alphabet_num == context->current_text_controls->alphabet_num && context->alphabets[ii].pixw >= minw && context->alphabets[ii].pixh >= minh && ((context->alphabets[ii].pixw <= bestw && context->alphabets[ii].pixh < besth) || (context->alphabets[ii].pixw < bestw && context->alphabets[ii].pixh <= besth)) && context->alphabets[ii].pixw * context->alphabets[ii].pixh <= max_pixels) { bestmatch = ii; bestw = context->alphabets[ii].pixw; besth = context->alphabets[ii].pixh; } } } #ifdef DEBUG_ALPHABET_LOOKUP if (bestmatch < MAX_REGIS_ALPHABETS) { TRACE(("for target size %ux%u alphabet %u found index %u size %ux%u font=%s\n", targetw, targeth, context->current_text_controls->alphabet_num, bestmatch, bestw, besth, context->alphabets[bestmatch].use_font ? context->alphabets[bestmatch].fontname : "(none)")); } else { TRACE(("for target size %ux%u alphabet %u found no suitable alphabets\n", targetw, targeth, context->current_text_controls->alphabet_num)); } #endif return bestmatch; } #define GLYPH_WIDTH_BYTES(PIXW) ( ((PIXW) + 7U) >> 3U ) static int get_user_bitmap_of_character(RegisGraphicsContext const *context, int ch, unsigned alphabet_index, Char *pixels, unsigned int max_pixels) { const Char *glyph; unsigned w, h; unsigned xx, yy; unsigned byte, bit; assert(context); assert(pixels); if (!context->alphabets[alphabet_index].loaded[(Char) ch]) { TRACE(("BUG: in alphabet %u with alphabet index %u user glyph for '%c' not loaded\n", context->current_text_controls->alphabet_num, alphabet_index, ch)); return 0; } assert(context->alphabets[alphabet_index].bytes); w = context->alphabets[alphabet_index].pixw; h = context->alphabets[alphabet_index].pixh; glyph = &context->alphabets[alphabet_index] .bytes[(Char) ch * GLYPH_WIDTH_BYTES(w) * h]; if (w * h > max_pixels) { TRACE(("in alphabet %u with alphabet index %u user glyph for '%c' is too large: %ux%u (max_pixels=%u)\n", context->current_text_controls->alphabet_num, alphabet_index, ch, w, h, max_pixels)); return 0; } for (yy = 0U; yy < h; yy++) { for (xx = 0U; xx < w; xx++) { byte = yy * GLYPH_WIDTH_BYTES(w) + (xx >> 3U); bit = xx & 7U; pixels[yy * w + xx] = (Char) (((unsigned) glyph[byte] >> (7U - bit)) & 1U); } } return 1; } /* * alphabets * 0 built-in * 1-N custom (max is 3 on VT3X0 -- up to MAX_REGIS_ALPHABETS with xterm) * * built-in 7-bit charsets * (B ASCII * (0 DEC special graphics * (> DEC technical * (A NCR British * (4 NCR Dutch * (5 NCR Finnish * (R NCR French * (9 NCR French Canadian * (K NCR German * (Y NCR Italian * (' NCR Norwegian/Danish * (!6 NCR Portuguese * (Z NCR Spanish * (7 NCR Swedish * (- NCR Swiss * * -@ ??? * * built-in 8-bit charsets * )%5 DEC supplemental graphics * -A ISO Latin-1 supplemental * )< user-preferred supplemental (94 chars) * * defaults * terminal char cell size charsets angle * VT3x0 S1 0:ASCII(94) 0 (positive) * */ static void get_bitmap_of_character(RegisGraphicsContext const *context, int ch, unsigned maxw, unsigned maxh, Char *pixels, unsigned *w, unsigned *h, unsigned max_pixels) { unsigned bestmatch; char const *fontname = NULL; assert(context); assert(w); assert(h); #ifdef DEBUG_GLYPH_RETRIEVAL TRACE(("getting bitmap of glyph %d, current alphabet %d\n", ch, context->current_text_controls->alphabet_num)); #endif if (maxw < 1U || maxh < 1U || max_pixels < 1U) { *w = 0U; *h = 0U; return; } if (context->current_text_controls->alphabet_num == 0) fontname = context->builtin_font; *w = 0U; *h = 0U; bestmatch = find_best_alphabet_index(context, 1U, 1U, maxw, maxh, max_pixels); if (bestmatch < MAX_REGIS_ALPHABETS) { RegisAlphabet const *alpha = &context->alphabets[bestmatch]; #ifdef DEBUG_GLYPH_RETRIEVAL TRACE(("checking user glyph for slot=%u alphabet=%d use_font=%d loaded=%d\n", bestmatch, alpha->alphabet_num, alpha->use_font, alpha->loaded[ch])); #endif if (!alpha->use_font && get_user_bitmap_of_character(context, ch, bestmatch, pixels, max_pixels)) { #ifdef DEBUG_GLYPH_RETRIEVAL TRACE(("found user glyph for alphabet number %d (index %u)\n\n", alpha->alphabet_num, bestmatch)); #endif *w = alpha->pixw; *h = alpha->pixh; return; } if (alpha->use_font) fontname = alpha->fontname; } if (fontname) { #ifdef DEBUG_GLYPH_RETRIEVAL TRACE(("using xft font \"%s\"\n", fontname)); #endif if (get_xft_bitmap_of_character(context, fontname, ch, maxw, maxh, pixels, max_pixels, w, h)) { if (*w > maxw) { TRACE(("BUG: Xft glyph is too wide: %ux%u but max is %ux%u\n", *w, *h, maxw, maxh)); } else if (*h > maxh) { TRACE(("BUG: Xft glyph is too tall: %ux%u but max is %ux%u\n", *w, *h, maxw, maxh)); } else if (*w * *h > max_pixels) { TRACE(("BUG: Xft glyph has too many pixels: %u but max is %u\n", *w * *h, max_pixels)); } else { TRACE(("got glyph from \"%s\" for alphabet number %d\n", fontname, context->current_text_controls->alphabet_num)); #ifdef DEBUG_SPECIFIC_CHAR_METRICS if (IS_DEBUG_CHAR(ch)) { printf("got %ux%u Xft bitmap for '%c' target size %ux%u:\n", *w, *h, ch, maxw, maxh); dump_bitmap_pixels(pixels, *w, *h); printf("\n"); } #endif return; } } } TRACE(("unable to load any bitmap for character '%c' in alphabet number %u at %ux%u\n", ch, context->current_text_controls->alphabet_num, maxw, maxh)); /* * The VT3x0 series (and probably earlier ReGIS implementations) use a solid * block glyph for unknown glyphs. */ { unsigned xx, yy; *w = MIN2(8U, maxh); *h = MIN2(10U, maxw); for (yy = 0U; yy < *h; yy++) for (xx = 0U; xx < *w; xx++) pixels[yy * *w + xx] = '\1'; } } static void draw_character(RegisGraphicsContext *context, int ch, int slant_dx, int rot_shear_x, int rot_shear_y, int x_sign_x, int x_sign_y, int y_sign_x, int y_sign_y) { const unsigned xmaxd = context->current_text_controls->character_display_w; const unsigned ymaxd = context->current_text_controls->character_display_h; const unsigned xmaxf = context->current_text_controls->character_unit_cell_w; const unsigned ymaxf = context->current_text_controls->character_unit_cell_h; unsigned w, h; unsigned xscale, yscale; unsigned fx, fy; unsigned px, py; int sx; int rx, ry; int ox, oy; unsigned pad_left, pad_right; unsigned pad_top, pad_bottom; Char pixels[MAX_GLYPH_PIXELS]; unsigned value; get_bitmap_of_character(context, ch, xmaxf, ymaxf, pixels, &w, &h, MAX_GLYPH_PIXELS); if (w < 1 || h < 1) { return; } if (xmaxd > xmaxf) { pad_left = (xmaxd - xmaxf) / 2U; pad_right = (xmaxd - xmaxf) - pad_left; } else { pad_left = 0U; pad_right = 0U; } if (ymaxd > ymaxf) { pad_top = (ymaxd - ymaxf) / 2U; pad_bottom = (ymaxd - ymaxf) - pad_top; } else { pad_top = 0U; pad_bottom = 0U; } xscale = (w << SCALE_FIXED_POINT) / xmaxf; yscale = (h << SCALE_FIXED_POINT) / ymaxf; for (py = 0U; py < ymaxd; py++) { for (px = 0U; px < xmaxd; px++) { if (py < pad_top || px < pad_left || py >= ymaxd - pad_bottom || px >= xmaxd - pad_right) { value = 0U; } else { fx = ((px - pad_left) * xscale) >> SCALE_FIXED_POINT; fy = ((py - pad_top) * yscale) >> SCALE_FIXED_POINT; if (fx < w && fy < h) { value = (unsigned) pixels[fy * w + fx]; } else { value = 0U; } } sx = (int) px + (slant_dx * (int) py) / ROT_SHEAR_SCALE; rx = x_sign_x * sx + x_sign_y * (int) py; ry = y_sign_x * sx + y_sign_y * (int) py; ox = rx + (rot_shear_x * ry) / ROT_SHEAR_SCALE; oy = ry + (rot_shear_y * ox) / ROT_SHEAR_SCALE; ox += (rot_shear_x * oy) / ROT_SHEAR_SCALE; draw_regis_pixel(context, (int) context->graphics_output_cursor_x + ox, (int) context->graphics_output_cursor_y + oy, value); } } } static void move_text(RegisGraphicsContext *context, int dx, int dy) { double total_rotation; int str_invert; int str_shear_x, str_shear_y; int ox, oy; total_rotation = 2.0 * M_PI * context->current_text_controls->string_rotation / 360.0; while (total_rotation > 1.5 * M_PI) { total_rotation -= 2.0 * M_PI; } if (total_rotation > 0.5 * M_PI) { total_rotation -= M_PI; str_invert = -1; } else { str_invert = 1; } str_shear_x = (int) (ROT_SHEAR_SCALE * -tan(0.5 * -total_rotation)); str_shear_y = (int) (ROT_SHEAR_SCALE * sin(-total_rotation)); total_rotation = 2.0 * M_PI * context->current_text_controls->character_rotation / 360.0; while (total_rotation > 1.5 * M_PI) { total_rotation -= 2.0 * M_PI; } TRACE(("str_shear: %.5f, %.5f (sign=%d)\n", str_shear_x / (double) ROT_SHEAR_SCALE, str_shear_y / (double) ROT_SHEAR_SCALE, str_invert)); ox = str_invert * dx + (str_shear_x * dy) / ROT_SHEAR_SCALE; oy = str_invert * dy + (str_shear_y * ox) / ROT_SHEAR_SCALE; ox += (str_shear_x * oy) / ROT_SHEAR_SCALE; TRACE(("after pv output updating position %+d,%+d\n", ox, oy)); context->graphics_output_cursor_x += ox; context->graphics_output_cursor_y += oy; return; } #define UPSCALE_TEXT_DIMENSION(D) do { \ *(D) = (unsigned)((double)(*(D)) * M_SQRT2); \ } while (0) static void draw_text(RegisGraphicsContext *context, char const *str) { #ifndef ENABLE_DISTORTIONLESS_ROTATION RegisTextControls *old_text_controls = NULL; static RegisTextControls scratch_text_controls; #endif double total_rotation; size_t ii; int str_invert; int str_shear_x, str_shear_y; int slant_dx; int chr_x_sign_x, chr_x_sign_y; int chr_y_sign_x, chr_y_sign_y; int chr_shear_x, chr_shear_y; int begin_x, begin_y; int rx, ry; int ox, oy; #ifdef DEBUG_ALPHABETS { unsigned n; for (n = 0U; n < MAX_REGIS_ALPHABETS; n++) { printf("alphabet index %u\n", n); if (context->alphabets[n].alphabet_num != INVALID_ALPHABET_NUM) { printf(" alphabet_num=%u\n", context->alphabets[n].alphabet_num); printf(" pixw=%d\n", context->alphabets[n].pixw); printf(" pixh=%d\n", context->alphabets[n].pixh); printf(" name=\"%s\"\n", context->alphabets[n].name); printf(" use_font=%d\n", context->alphabets[n].use_font); printf(" fontname=\"%s\"\n", context->alphabets[n].fontname); printf(" bytes=%p\n", context->alphabets[n].bytes); } } } #endif if (context->current_text_controls->slant <= -75 || context->current_text_controls->slant >= +75) { TRACE(("ERROR: unsupported character slant angle %d\n", context->current_text_controls->slant)); return; } /* FIXME: grab when first entering command */ begin_x = context->graphics_output_cursor_x; begin_y = context->graphics_output_cursor_y; #ifndef ENABLE_DISTORTIONLESS_ROTATION if (context->current_text_controls->character_rotation != 0 && context->current_text_controls->character_rotation != 90 && context->current_text_controls->character_rotation != 180 && context->current_text_controls->character_rotation != 270) { old_text_controls = context->current_text_controls; scratch_text_controls = *context->current_text_controls; UPSCALE_TEXT_DIMENSION(&scratch_text_controls.character_display_w); UPSCALE_TEXT_DIMENSION(&scratch_text_controls.character_display_h); /* FIXME: Not sure if this is really scaled. The increment seems to * _not_ be scaled. */ UPSCALE_TEXT_DIMENSION(&scratch_text_controls.character_unit_cell_w); UPSCALE_TEXT_DIMENSION(&scratch_text_controls.character_unit_cell_h); context->current_text_controls = &scratch_text_controls; TRACE(("scaled up text to %dx%d\n", scratch_text_controls.character_display_w, scratch_text_controls.character_display_h)); } #endif total_rotation = 2.0 * M_PI * context->current_text_controls->string_rotation / 360.0; while (total_rotation > 1.5 * M_PI) { total_rotation -= 2.0 * M_PI; } if (total_rotation > 0.5 * M_PI) { total_rotation -= M_PI; str_invert = -1; } else { str_invert = 1; } str_shear_x = (int) (ROT_SHEAR_SCALE * -tan(0.5 * -total_rotation)); str_shear_y = (int) (ROT_SHEAR_SCALE * sin(-total_rotation)); total_rotation = 2.0 * M_PI * context->current_text_controls->character_rotation / 360.0; while (total_rotation > 1.5 * M_PI) { total_rotation -= 2.0 * M_PI; } if (total_rotation > 0.5 * M_PI) { total_rotation -= M_PI; chr_x_sign_x = -1; chr_x_sign_y = 0; chr_y_sign_x = 0; chr_y_sign_y = -1; } else { chr_x_sign_x = 1; chr_x_sign_y = 0; chr_y_sign_x = 0; chr_y_sign_y = 1; } chr_shear_x = (int) (ROT_SHEAR_SCALE * -tan(0.5 * -total_rotation)); chr_shear_y = (int) (ROT_SHEAR_SCALE * sin(-total_rotation)); { const int slant = context->current_text_controls->slant; TRACE(("float version: %.5f\n", tan(2.0 * M_PI * abs(slant) / 360.0))); /* The slant is negative for forward-leaning characters. */ if (slant > 0) { slant_dx = (int) +(tan(2.0 * M_PI * abs(slant) / 360.0) * ROT_SHEAR_SCALE); } else if (slant < 0) { slant_dx = (int) -(tan(2.0 * M_PI * abs(slant) / 360.0) * ROT_SHEAR_SCALE); } else { slant_dx = 0; } TRACE(("string rotation: %d\n", context->current_text_controls->string_rotation)); TRACE(("character rotation: %d\n", context->current_text_controls->character_rotation)); TRACE(("character slant: %d (%.5f pixels per line)\n", slant, slant_dx / (double) ROT_SHEAR_SCALE)); } TRACE(("str_shear: %.5f, %.5f (sign=%d)\n", str_shear_x / (double) ROT_SHEAR_SCALE, str_shear_y / (double) ROT_SHEAR_SCALE, str_invert)); TRACE(("chr_shear: %.5f, %.5f (xsign=%d,%d, ysign=%d,%d)\n", chr_shear_x / (double) ROT_SHEAR_SCALE, chr_shear_y / (double) ROT_SHEAR_SCALE, chr_x_sign_x, chr_x_sign_y, chr_y_sign_x, chr_y_sign_y)); TRACE(("character_inc: %d,%d\n", context->current_text_controls->character_inc_x, context->current_text_controls->character_inc_y)); rx = 0; ry = 0; for (ii = 0U; ii < strlen(str); ii++) { switch (str[ii]) { case '\r': rx = 0; break; case '\n': ry += (int) context->current_text_controls->character_display_h; break; case '\b': rx -= context->current_text_controls->character_inc_x; ry -= context->current_text_controls->character_inc_y; break; case '\t': rx += context->current_text_controls->character_inc_x; ry += context->current_text_controls->character_inc_y; break; default: ox = str_invert * rx + (str_shear_x * ry) / ROT_SHEAR_SCALE; oy = str_invert * ry + (str_shear_y * ox) / ROT_SHEAR_SCALE; ox += (str_shear_x * oy) / ROT_SHEAR_SCALE; TRACE(("during text output updating position to %d,%d + %+d,%+d for '%c'\n", begin_x, begin_y, ox, oy, str[ii])); context->graphics_output_cursor_x = begin_x + ox; context->graphics_output_cursor_y = begin_y + oy; draw_character(context, str[ii], slant_dx, chr_shear_x, chr_shear_y, chr_x_sign_x, chr_x_sign_y, chr_y_sign_x, chr_y_sign_y); rx += context->current_text_controls->character_inc_x; ry += context->current_text_controls->character_inc_y; } } ox = str_invert * rx + (str_shear_x * ry) / ROT_SHEAR_SCALE; oy = str_invert * ry + (str_shear_y * ox) / ROT_SHEAR_SCALE; ox += (str_shear_x * oy) / ROT_SHEAR_SCALE; TRACE(("after text output updating position to %d,%d + %+d,%+d\n", begin_x, begin_y, ox, oy)); context->graphics_output_cursor_x = begin_x + ox; context->graphics_output_cursor_y = begin_y + oy; #ifndef ENABLE_DISTORTIONLESS_ROTATION if (context->current_text_controls->character_rotation != 0 && context->current_text_controls->character_rotation != 90 && context->current_text_controls->character_rotation != 180 && context->current_text_controls->character_rotation != 270) { context->current_text_controls = old_text_controls; } #endif context->destination_graphic->dirty = True; return; } /* * standard character cell sizes * number disp cell unit cell offset * S0 [ 9, 10] [ 8, disp_h] [disp_w, 0] * S1 [ 9, 20] [ 8, disp_h] [disp_w, 0] * S2 [ 18, 30] [ 16, disp_h] [disp_w, 0] * S3 [ 27, 45] [ 24, disp_h] [disp_w, 0] * S4 [ 36, 60] [ 32, disp_h] [disp_w, 0] * S5 [ 45, 75] [ 40, disp_h] [disp_w, 0] * S6 [ 54, 90] [ 48, disp_h] [disp_w, 0] * S7 [ 63,105] [ 56, disp_h] [disp_w, 0] * S8 [ 72,120] [ 64, disp_h] [disp_w, 0] * S9 [ 81,135] [ 72, disp_h] [disp_w, 0] * S10 [ 90,150] [ 80, disp_h] [disp_w, 0] * S11 [ 99,165] [ 88, disp_h] [disp_w, 0] * S12 [108,180] [ 96, disp_h] [disp_w, 0] * S13 [117,195] [104, disp_h] [disp_w, 0] * S14 [126,210] [112, disp_h] [disp_w, 0] * S15 [135,225] [120, disp_h] [disp_w, 0] * S16 [144,240] [128, disp_h] [disp_w, 0] */ static int get_standard_character_size(int standard, unsigned *disp_w, unsigned *disp_h, unsigned *unit_w, unsigned *unit_h, int *off_x, int *off_y) { switch (standard) { case 0: *disp_w = 9U; *disp_h = 10U; *unit_w = 8U; break; case 1: *disp_w = 9U; *disp_h = 20U; *unit_w = 8U; break; case 2: *disp_w = 18U; *disp_h = 30U; *unit_w = 16U; break; case 3: *disp_w = 27U; *disp_h = 45U; *unit_w = 24U; break; case 4: *disp_w = 36U; *disp_h = 60U; *unit_w = 32U; break; case 5: *disp_w = 45U; *disp_h = 75U; *unit_w = 40U; break; case 6: *disp_w = 54U; *disp_h = 90U; *unit_w = 48U; break; case 7: *disp_w = 63U; *disp_h = 105U; *unit_w = 56U; break; case 8: *disp_w = 72U; *disp_h = 120U; *unit_w = 64U; break; case 9: *disp_w = 81U; *disp_h = 135U; *unit_w = 72U; break; case 10: *disp_w = 90U; *disp_h = 150U; *unit_w = 80U; break; case 11: *disp_w = 99U; *disp_h = 165U; *unit_w = 88U; break; case 12: *disp_w = 108U; *disp_h = 180U; *unit_w = 96U; break; case 13: *disp_w = 117U; *disp_h = 195U; *unit_w = 104U; break; case 14: *disp_w = 126U; *disp_h = 210U; *unit_w = 112U; break; case 15: *disp_w = 135U; *disp_h = 225U; *unit_w = 120U; break; case 16: *disp_w = 144U; *disp_h = 240U; *unit_w = 128U; break; default: return 1; } *unit_h = *disp_h; *off_x = (int) *disp_w; *off_y = 0; return 0; } static void init_fragment(RegisDataFragment *fragment, char const *str) { assert(fragment); assert(str); fragment->start = str; fragment->len = (unsigned) strlen(str); fragment->pos = 0U; } static void copy_fragment(RegisDataFragment *dst, RegisDataFragment const *src) { assert(dst); assert(src); dst->start = src->start; dst->len = src->len; dst->pos = src->pos; } static char peek_fragment(RegisDataFragment const *fragment) { assert(fragment); if (fragment->pos < fragment->len) { return fragment->start[fragment->pos]; } return '\0'; } static char pop_fragment(RegisDataFragment *fragment) { assert(fragment); if (fragment->pos < fragment->len) { return fragment->start[fragment->pos++]; } return '\0'; } static char get_fragment(RegisDataFragment const *fragment, unsigned pos) { assert(fragment); if (fragment->pos + pos < fragment->len) { return fragment->start[fragment->pos + pos]; } return '\0'; } #define fragment_length(f) (f)->len static unsigned fragment_remaining(RegisDataFragment const *fragment) { assert(fragment); if (fragment->pos > fragment->len) return 0U; return fragment->len - fragment->pos; } static int fragment_consumed(RegisDataFragment const *fragment) { assert(fragment); return fragment->pos >= fragment->len; } static void fragment_to_string(RegisDataFragment const *fragment, char *out, unsigned outlen) { unsigned remaininglen; unsigned endpos; assert(fragment); assert(out); if (!outlen) return; remaininglen = fragment->len - fragment->pos; if (remaininglen < outlen - 1U) { endpos = remaininglen; } else { endpos = outlen - 1U; } strncpy(out, &fragment->start[fragment->pos], (size_t) endpos); out[endpos] = '\0'; } #define MAX_FRAG 1024 static char const * fragment_to_tempstr(RegisDataFragment const *fragment) { static char tempstr[MAX_FRAG]; assert(fragment); fragment_to_string(fragment, tempstr, MAX_FRAG); return tempstr; } static int skip_regis_whitespace(RegisDataFragment *input) { int skipped = 0; assert(input); while (!fragment_consumed(input)) { char ch = peek_fragment(input); if (ch != ',' && !IsSpace(ch)) { break; } if (ch == '\n') { TRACE(("end of input line\n\n")); } skipped = 1; pop_fragment(input); } if (skipped) return 1; return 0; } static int extract_regis_extent(RegisDataFragment *input, RegisDataFragment *output) { char ch; assert(input); assert(output); output->start = &input->start[input->pos]; output->len = 0U; output->pos = 0U; if (input->pos >= input->len) return 0; ch = input->start[input->pos]; if (ch != '[') return 0; input->pos++; output->start++; /* FIXME: truncate to 16 bit signed integers */ for (; input->pos < input->len; input->pos++, output->len++) { ch = input->start[input->pos]; if (ch == ';') { TRACE(("DATA_ERROR: end of input before closing bracket\n")); break; } if (ch == ']') break; } if (ch == ']') input->pos++; return 1; } static int extract_regis_num(RegisDataFragment *input, RegisDataFragment *output) { char ch = 0; int has_digits = 0; assert(input); assert(output); output->start = &input->start[input->pos]; output->len = 0U; output->pos = 0U; if (input->start[input->pos] == '-' || input->start[input->pos] == '+') { input->pos++; output->len++; } for (; input->pos < input->len; input->pos++, output->len++) { ch = input->start[input->pos]; if (ch != '0' && ch != '1' && ch != '2' && ch != '3' && ch != '4' && ch != '5' && ch != '6' && ch != '7' && ch != '8' && ch != '9') { break; } has_digits = 1; } /* FIXME: what degenerate forms should be accepted ("E10" "1E" "1e" "1." "1ee10")? */ /* FIXME: the terminal is said to support "floating point values", truncating to int... what do these look like? */ if (has_digits && ch == 'E') { input->pos++; output->len++; for (; input->pos < input->len; input->pos++, output->len++) { ch = input->start[input->pos]; if (ch != '0' && ch != '1' && ch != '2' && ch != '3' && ch != '4' && ch != '5' && ch != '6' && ch != '7' && ch != '8' && ch != '9') { break; } } } return has_digits; } static int extract_regis_pixelvector(RegisDataFragment *input, RegisDataFragment *output) { char ch; int has_digits; assert(input); assert(output); output->start = &input->start[input->pos]; output->len = 0U; output->pos = 0U; if (input->pos < input->len) { ch = input->start[input->pos]; if (ch == '+' || ch == '-') { input->pos++; output->len++; } } has_digits = 0; for (; input->pos < input->len; input->pos++, output->len++) { ch = input->start[input->pos]; if (ch != '0' && ch != '1' && ch != '2' && ch != '3' && ch != '4' && ch != '5' && ch != '6' && ch != '7') { break; } has_digits = 1; } return has_digits; } static int extract_regis_command(RegisDataFragment *input, char *command) { char ch; assert(input); assert(command); if (input->pos >= input->len) return 0; ch = input->start[input->pos]; if (ch == '\0' || ch == ';') { return 0; } if (!islower(CharOf(ch)) && !isupper(CharOf(ch)) && ch != '@') { return 0; } *command = ch; input->pos++; return 1; } /* * Check a ReGIS alphabet name before reporting it, to pick an appropriate * delimiter. If the string is empty, or contains nonreportable characters, * just return NUL. */ static int pick_quote(const char *value) { Bool s_quote = False; Bool d_quote = False; if (*value != '\0') { while (*value != '\0') { int ch = CharOf(*value++); if (ch == D_QUOTE) d_quote = True; else if (ch == S_QUOTE) s_quote = True; else if (!isName(ch)) s_quote = d_quote = True; } } else { s_quote = d_quote = True; } return ((s_quote && d_quote) ? 0 : (s_quote ? D_QUOTE : S_QUOTE)); } static int extract_regis_string(RegisDataFragment *input, char *out, unsigned maxlen) { char open_quote_ch; char ch; unsigned outlen; assert(input); assert(out); assert(maxlen > 0U); if (input->pos >= input->len) return 0; ch = peek_fragment(input); if (!isQuote(ch)) return 0; open_quote_ch = ch; outlen = 0U; pop_fragment(input); ch = '\0'; while (!fragment_consumed(input)) { char prev_ch = ch; ch = peek_fragment(input); /* ';' (resync) and '@' (macrograph) are not recognized in strings */ if (prev_ch == open_quote_ch) { if (ch == open_quote_ch) { if (outlen < maxlen) { out[outlen] = ch; } outlen++; pop_fragment(input); ch = '\0'; continue; } if (outlen < maxlen) out[outlen] = '\0'; else out[maxlen] = '\0'; return 1; } if (ch == '\0') break; if (ch != open_quote_ch) { if (outlen < maxlen) out[outlen] = ch; outlen++; } pop_fragment(input); } if (ch == open_quote_ch) { pop_fragment(input); if (outlen < maxlen) out[outlen] = '\0'; else out[maxlen] = '\0'; return 1; } /* FIXME: handle multiple strings concatenated with commas */ TRACE(("DATA_ERROR: end of input before closing quote\n")); return 0; } static int extract_regis_parenthesized_data(RegisDataFragment *input, RegisDataFragment *output) { char ch; char open_quote_ch; int nesting; assert(input); assert(output); output->start = &input->start[input->pos]; output->len = 0U; output->pos = 0U; if (input->pos >= input->len) return 0; ch = input->start[input->pos]; if (ch != '(') return 0; input->pos++; output->start++; nesting = 1; open_quote_ch = '\0'; ch = '\0'; for (; input->pos < input->len; input->pos++, output->len++) { char prev_ch = ch; ch = input->start[input->pos]; if (isQuote(ch)) { if (open_quote_ch == '\0') { open_quote_ch = ch; } else { if (ch == prev_ch && prev_ch == open_quote_ch) { ch = '\0'; } else if (ch == open_quote_ch) { open_quote_ch = '\0'; } } continue; } if (open_quote_ch != '\0') continue; if (ch == ';') { TRACE(("leaving parenthesized data nested %d levels deep due to command termination character\n", nesting)); break; } if (ch == '(') nesting++; if (ch == ')') { nesting--; if (nesting == 0) { input->pos++; return 1; } } } TRACE(("DATA_ERROR: end of input before closing paren (%d levels deep)\n", nesting)); return 0; } static int extract_regis_option(RegisDataFragment *input, char *option, RegisDataFragment *output) { char ch; int paren_level, bracket_level; char open_quote_ch; assert(input); assert(option); assert(output); /* LETTER suboptions* value? */ /* * FIXME: what are the rules for using separate parens vs. sharing between * options? */ output->start = &input->start[input->pos]; output->len = 0U; output->pos = 0U; if (input->pos >= input->len) { return 0; } ch = input->start[input->pos]; /* FIXME: are options always letters or are some special characters ok? */ if (ch == ';' || ch == ',' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || isQuote(ch) || isdigit(CharOf(ch))) { return 0; } *option = ch; input->pos++; output->start++; paren_level = 0; bracket_level = 0; open_quote_ch = '\0'; for (; input->pos < input->len; input->pos++, output->len++) { ch = input->start[input->pos]; TRACE(("looking at char '%c' in option '%c'\n", ch, *option)); /* FIXME: any special rules for commas? */ /* FIXME: handle escaped quotes */ if (isQuote(ch)) { if (open_quote_ch == ch) { open_quote_ch = '\0'; } else { open_quote_ch = ch; } continue; } if (open_quote_ch != '\0') continue; if (ch == '(') { paren_level++; } if (ch == ')') { paren_level--; if (paren_level < 0) { TRACE(("DATA_ERROR: found ReGIS option has value with too many close parens \"%c\"\n", *option)); return 0; } } if (ch == '[') { bracket_level++; } if (ch == ']') { bracket_level--; if (bracket_level < 0) { TRACE(("DATA_ERROR: found ReGIS option has value with too many close brackets \"%c\"\n", *option)); return 0; } } if (paren_level == 0 && bracket_level == 0) { /* * Top-level commas indicate the end of this option and the start of * another. */ if (ch == ',') break; /* * Top-level command/option/suboption names also indicate the end of * this option. "E" is valid as the exponent indicator in a numeric * parameter. */ if (ch != 'E' && ch != 'e' && ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))) break; } if (ch == ';') break; } if (paren_level != 0) { TRACE(("DATA_ERROR: mismatched parens in argument to ReGIS option \"%c\"\n", *option)); return 0; } if (bracket_level != 0) { TRACE(("DATA_ERROR: mismatched brackets in argument to ReGIS option \"%c\"\n", *option)); return 0; } TRACE(("found ReGIS option and value \"%c\" \"%s\"\n", *option, fragment_to_tempstr(output))); return 1; } static int regis_num_to_int(RegisDataFragment const *input, int *out) { char ch; assert(input); assert(out); /* FIXME: handle exponential notation and rounding */ /* FIXME: check for junk after the number */ ch = peek_fragment(input); if (!isdigit(CharOf(ch)) && ch != '+' && ch != '-') { *out = 0; return 0; } TRACE(("converting \"%s\" to an int\n", fragment_to_tempstr(input))); *out = atoi(fragment_to_tempstr(input)); return 1; } #define spec_H xBIT(0) #define spec_L xBIT(1) #define spec_S xBIT(2) #define spec_HLS (spec_H | spec_L | spec_S) #define spec_R xBIT(3) #define spec_G xBIT(4) #define spec_B xBIT(5) #define spec_RGB (spec_R | spec_G | spec_B) static int load_regis_colorspec(RegisGraphicsContext const *context, RegisDataFragment const *input, ColorRegister *colors) { RegisDataFragment colorspec; short r = colors->r; short g = colors->g; short b = colors->b; short l = -1; int simple; unsigned len; unsigned spec = 0; assert(context); assert(input); assert(colors); copy_fragment(&colorspec, input); TRACE(("colorspec option: \"%s\"\n", fragment_to_tempstr(&colorspec))); skip_regis_whitespace(&colorspec); simple = 0; if ((len = fragment_remaining(&colorspec)) == 1U) { simple = 1; } else if (len > 1U) { unsigned n; for (n = 1; n < len; ++n) { char after = get_fragment(&colorspec, n); /* if no parameters, we might see a right-parenthesis, but on error * we can anything */ if (strchr("[(,)]", after) != NULL) { simple = 1; break; } else if (!IsSpace(after)) { break; } } } if (simple) { char ch = pop_fragment(&colorspec); TRACE(("got ReGIS RGB colorspec pattern '%c' with arguments: \"%s\"\n", ch, fragment_to_tempstr(&colorspec))); switch (ch) { case 'D': case 'd': r = 0; g = 0; b = 0; l = 0; break; case 'R': case 'r': r = 100; g = 0; b = 0; l = 46; break; case 'G': case 'g': r = 0; g = 100; b = 0; l = 50; break; case 'B': case 'b': r = 0; g = 0; b = 100; l = 50; break; case 'C': case 'c': r = 0; g = 100; b = 100; l = 50; break; case 'Y': case 'y': r = 100; g = 100; b = 0; l = 50; break; case 'M': case 'm': r = 100; g = 0; b = 100; l = 50; break; case 'W': case 'w': r = 100; g = 100; b = 100; l = 100; break; default: TRACE(("DATA_ERROR: unknown RGB color name: \"%c\"\n", ch)); return 0; } } else { RegisDataFragment num; int max, val; char comp; short h = -1; short s = -1; while (!fragment_consumed(&colorspec)) { if (skip_regis_whitespace(&colorspec)) continue; comp = pop_fragment(&colorspec); switch (comp) { case ',': /* not sure if this is valid, but it is easy to handle */ continue; case 'H': case 'h': max = 360; comp = 'H'; break; case 'L': case 'l': max = 100; comp = 'L'; break; case 'S': case 's': max = 100; comp = 'S'; break; #ifdef ENABLE_RGB_COLORSPECS case 'R': /* RLogin extension */ case 'r': max = 100; comp = 'R'; break; case 'G': /* RLogin extension */ case 'g': max = 100; comp = 'G'; break; case 'B': /* RLogin extension */ case 'b': max = 100; comp = 'B'; break; #endif default: TRACE(("DATA_ERROR: unrecognized component in colorspec: '%c'\n", comp)); return 0; } skip_regis_whitespace(&colorspec); if (!extract_regis_num(&colorspec, &num)) { TRACE(("DATA_ERROR: expected int after '%c' component in colorspec: \"%s\"\n", comp, fragment_to_tempstr(&colorspec))); return 0; } if (!regis_num_to_int(&num, &val)) { TRACE(("DATA_ERROR: component value \"%s\" is not a number\n", fragment_to_tempstr(&num))); return 0; } /* FIXME: error, truncate, wrap, ...? */ if (val < 0 || val > max) { TRACE(("DATA_ERROR: component value %d out of range\n", val)); return 0; } switch (comp) { case 'H': h = (short) val; spec |= spec_H; break; case 'L': l = (short) val; spec |= spec_L; break; case 'S': s = (short) val; spec |= spec_S; break; case 'R': r = (short) val; spec |= spec_R; break; case 'G': g = (short) val; spec |= spec_G; break; case 'B': b = (short) val; spec |= spec_B; break; } } if ((spec & spec_HLS) && (spec & spec_RGB)) { TRACE(("DATA_ERROR: conflicting colorspec format\n")); return 0; } else if (spec == spec_HLS) { TRACE(("found HLS colorspec to be converted: %hd,%hd,%hd\n", h, l, s)); hls2rgb(h, l, s, &r, &g, &b); TRACE(("converted to RGB: %hd,%hd,%hd\n", r, g, b)); } else if (spec == spec_RGB) { TRACE(("found RGB colorspec: %hd,%hd,%hd\n", r, g, b)); l = (short) ((MIN3(r, g, b) + MAX3(r, g, b)) / 2); TRACE(("calculated L: %d\n", l)); } else if ((spec & spec_HLS)) { short old_h, old_l, old_s; TRACE(("using partial HLS %hd,%hd,%hd\n", h, l, s)); rgb2hls(r, g, b, &old_h, &old_l, &old_s); if (h < 0) h = old_h; if (l < 0) l = old_l; if (s < 0) s = old_s; TRACE(("resulting HLS colorspec to convert: %hd,%hd,%hd\n", h, l, s)); hls2rgb(h, l, s, &r, &g, &b); TRACE(("converted to RGB: %hd,%hd,%hd\n", r, g, b)); } else { TRACE(("DATA_ERROR: unrecognized colorspec format\n")); return 0; } } /* * The VT240 and VT330 models convert to the closest grayscale value. */ if (context->graphics_termid == 240 || context->graphics_termid == 330) { hls2rgb(0, l, 0, &r, &g, &b); TRACE(("converted to grayscale: %hd,%hd,%hd\n", r, g, b)); } colors->r = r; colors->g = g; colors->b = b; skip_regis_whitespace(&colorspec); if (!fragment_consumed(&colorspec)) { char skip; skip = pop_fragment(&colorspec); (void) skip; /* variable needed only if tracing */ TRACE(("DATA_ERROR: ignoring unexpected character in ReGIS colorspec \"%c\"\n", skip)); } return 1; } static int load_regis_regnum_or_colorspec(RegisGraphicsContext const *context, RegisDataFragment const *input, RegisterNum *out) { int val; RegisDataFragment colorspec; RegisDataFragment num; RegisDataFragment coloroption; copy_fragment(&colorspec, input); TRACE(("looking at colorspec pattern: \"%s\"\n", fragment_to_tempstr(&colorspec))); skip_regis_whitespace(&colorspec); if (extract_regis_num(&colorspec, &num)) { if (!regis_num_to_int(&num, &val)) { TRACE(("DATA_ERROR: colorspec value \"%s\" is not a valid register\n", fragment_to_tempstr(&num))); return 0; } if (val < 0) { /* FIXME: error, truncate, wrap, ...? */ TRACE(("DATA_ERROR: ignoring negative colorspec value: %d\n", val)); return 0; } if (val >= (int) context->destination_graphic->valid_registers) { /* FIXME: error, truncate, wrap, ...? */ TRACE(("DATA_ERROR: colorspec value %d is too big; wrapping\n", val)); val %= (int) context->destination_graphic->valid_registers; } TRACE(("colorspec contains index for register %u\n", val)); *out = (RegisterNum) val; skip_regis_whitespace(&colorspec); if (!fragment_consumed(&colorspec)) { char skip; skip = pop_fragment(&colorspec); (void) skip; /* variable needed only if tracing */ TRACE(("DATA_ERROR: unexpected character after register \"%c\"\n", skip)); return 0; } return 1; } if (extract_regis_parenthesized_data(&colorspec, &coloroption)) { ColorRegister find_reg = {-1, -1, -1}; if (!load_regis_colorspec(context, &coloroption, &find_reg)) { TRACE(("unable to parse colorspec\n")); return 0; } *out = find_color_register(context->destination_graphic->color_registers, find_reg.r, find_reg.g, find_reg.b); TRACE(("colorspec maps to closest register %u\n", *out)); return 1; } TRACE(("expected register number or colorspec, but found: \"%s\"\n", fragment_to_tempstr(&colorspec))); return 0; } static int to_scaled_int(char const *num, int scale, int *value) { unsigned long whole, frac; char *end; /* FIXME: handle whitespace? how about trailing junk? */ whole = strtoul(num, &end, 10); if (end[0] == '.') { char temp[5] = "0000"; if (end[1] != '\0') { temp[0] = end[1]; if (end[2] != '\0') { temp[1] = end[2]; if (end[3] != '\0') { temp[2] = end[3]; if (end[4] != '\0') { temp[3] = end[4]; } } } } frac = strtoul(temp, NULL, 10); } else if (end[0] == '\0' || end[0] == ',' || IsSpace(end[0])) { frac = 0; } else { TRACE(("unexpected character %c in number %s\n", end[0], num)); return 0; } *value = (int) (whole * (unsigned) scale + (frac * (unsigned) scale) / 10000); return 1; } static int load_regis_raw_extent(char const *extent, int *relx, int *rely, int *xloc, int *yloc, int scale) { int xsign, ysign; char const *xpart; char const *ypart; xpart = extent; if ((ypart = strchr(extent, ',')) != NULL) { ypart++; } else { ypart = ""; } while (IsSpace(xpart[0])) xpart++; while (IsSpace(ypart[0])) ypart++; if (xpart[0] == '-') { xsign = -1; xpart++; } else if (xpart[0] == '+') { xsign = +1; xpart++; } else { xsign = 0; } if (ypart[0] == '-') { ysign = -1; ypart++; } else if (ypart[0] == '+') { ysign = +1; ypart++; } else { ysign = 0; } if (xpart[0] == '\0' || xpart[0] == ',') { *relx = 1; *xloc = 0; } else if (xsign == 0) { int val; if (!to_scaled_int(xpart, scale, &val)) return 0; *relx = 0; *xloc = val; } else { int val; if (!to_scaled_int(xpart, scale, &val)) return 0; *relx = 1; *xloc = xsign * val; } if (ypart[0] == '\0') { *rely = 1; *yloc = 0; } else if (ysign == 0) { int val; if (!to_scaled_int(ypart, scale, &val)) return 0; *rely = 0; *yloc = val; } else { int val; if (!to_scaled_int(ypart, scale, &val)) return 0; *rely = 1; *yloc = ysign * val; } return 1; } static int load_regis_mult_extent(char const *extent, int *w, int *h) { int relx, rely; int px, py; if (!load_regis_raw_extent(extent, &relx, &rely, &px, &py, 1)) { TRACE(("invalid coordinates in extent \"%s\"\n", extent)); return 0; } if (relx | rely) { TRACE(("invalid relative value in multiplier extent \"%s\"\n", extent)); return 0; } *w = px; *h = py; return 1; } static int load_regis_pixel_extent(char const *extent, int origx, int origy, int *xloc, int *yloc) { int relx, rely; int px, py; if (!load_regis_raw_extent(extent, &relx, &rely, &px, &py, 1)) { TRACE(("invalid coordinates in extent \"%s\"\n", extent)); return 0; } *xloc = px; *yloc = py; if (relx) *xloc += origx; if (rely) *yloc += origy; return 1; } #define COORD_SCALE 1000 static int load_regis_coord_extent(RegisGraphicsContext const *context, char const *extent, int origx, int origy, int *xloc, int *yloc) { int relx, rely; int ux, uy; if (!load_regis_raw_extent(extent, &relx, &rely, &ux, &uy, COORD_SCALE)) { TRACE(("invalid coordinates in extent \"%s\"\n", extent)); return 0; } if (relx) { const int px = SCALE_XCOORD(context, ux, COORD_SCALE); TRACE(("converted relative user X coord %.03f to relative pixel X coord %d (width=%d xoff=%d xdiv=%d)\n", ux / (double) COORD_SCALE, px, context->width, context->x_off, context->x_div)); *xloc = origx + px; } else { const int px = TRANSLATE_XCOORD(context, ux, COORD_SCALE); TRACE(("converted absolute user X coord %.03f to absolute pixel X coord %d\n", ux / (double) COORD_SCALE, px)); *xloc = px; } if (rely) { const int py = SCALE_YCOORD(context, uy, COORD_SCALE); TRACE(("converted relative user Y coord %.03f to relative pixel Y coord %d (height=%d yoff=%d ydiv=%d)\n", uy / (double) COORD_SCALE, py, context->height, context->y_off, context->y_div)); *yloc = origy + py; } else { const int py = TRANSLATE_YCOORD(context, uy, COORD_SCALE); TRACE(("converted absolute user Y coord %.03f to absolute pixel Y coord %d\n", uy / (double) COORD_SCALE, py)); *yloc = py; } return 1; } static int load_regis_raw_pixelvector_digit(char const *pixelvector, unsigned *offset, int *dx, int *dy, int mul) { switch (pixelvector[*offset]) { case '0': *dx += mul; break; case '1': *dx += mul; *dy -= mul; break; case '2': *dy -= mul; break; case '3': *dx -= mul; *dy -= mul; break; case '4': *dx -= mul; break; case '5': *dx -= mul; *dy += mul; break; case '6': *dy += mul; break; case '7': *dx += mul; *dy += mul; break; default: return 0; } (*offset)++; return 1; } static int load_regis_pixel_pixelvector(char const *pixelvector, int mul, int origx, int origy, int *xloc, int *yloc) { int found = 0; int px = 0, py = 0; unsigned offset = 0U; while (load_regis_raw_pixelvector_digit(pixelvector, &offset, &px, &py, mul)) found = 1; if (pixelvector[offset] != '\0') { TRACE(("DATA_ERROR: ignoring unknown pixel vector digits: \"%s\"\n", &pixelvector[offset])); } *xloc = origx + px; *yloc = origy + py; return found; } static int load_regis_coord_pixelvector(RegisGraphicsContext const *context, char const *pixelvector, int origx, int origy, int *xloc, int *yloc) { const int mul = (int) (context->temporary_write_controls.pv_multiplier * COORD_SCALE); int found = 0; int ux = 0, uy = 0; unsigned offset = 0U; while (load_regis_raw_pixelvector_digit(pixelvector, &offset, &ux, &uy, mul)) found = 1; if (pixelvector[offset] != '\0') { TRACE(("DATA_ERROR: ignoring unknown pixel vector digits: \"%s\"\n", &pixelvector[offset])); } { const int px = SCALE_XCOORD(context, ux, COORD_SCALE); const int py = SCALE_YCOORD(context, uy, COORD_SCALE); TRACE(("converted relative X coord %.03f to relative pixel X coord %d (width=%d xoff=%d xdiv=%d)\n", ux / (double) COORD_SCALE, px, context->width, context->x_off, context->x_div)); *xloc = origx + px; TRACE(("converted relative Y coord %.03f to relative pixel Y coord %d (height=%d yoff=%d ydiv=%d)\n", uy / (double) COORD_SCALE, py, context->height, context->y_off, context->y_div)); *yloc = origy + py; } return found; } static int load_regis_coord_pixelvector_step(RegisGraphicsContext const *context, char const *pixelvector, unsigned *offset, int origx, int origy, int *xloc, int *yloc) { const int mul = (int) (context->temporary_write_controls.pv_multiplier * COORD_SCALE); int found = 0; int ux = 0, uy = 0; if (load_regis_raw_pixelvector_digit(pixelvector, offset, &ux, &uy, mul)) found = 1; if (!found && pixelvector[*offset] != '\0') { TRACE(("DATA_ERROR: ignoring unknown pixel vector digits: \"%s\"\n", &pixelvector[*offset])); } { const int px = SCALE_XCOORD(context, ux, COORD_SCALE); const int py = SCALE_YCOORD(context, uy, COORD_SCALE); TRACE(("converted relative X coord %.03f to relative pixel X coord %d (width=%d xoff=%d xdiv=%d)\n", ux / (double) COORD_SCALE, px, context->width, context->x_off, context->x_div)); *xloc = origx + px; TRACE(("converted relative Y coord %.03f to relative pixel Y coord %d (height=%d yoff=%d ydiv=%d)\n", uy / (double) COORD_SCALE, py, context->height, context->y_off, context->y_div)); *yloc = origy + py; } return found; } static int load_regis_write_control(RegisParseState *state, RegisGraphicsContext const *context, int cur_x, int cur_y, int option, RegisDataFragment *arg, RegisWriteControls *out) { TRACE(("checking write control option \"%c\" with arg \"%s\"\n", option, fragment_to_tempstr(arg))); switch (option) { case 'A': case 'a': TRACE(("write control alternate display method \"%s\"\n", fragment_to_tempstr(arg))); { int val; if (!regis_num_to_int(arg, &val) || val < 0 || val >= 1) { TRACE(("DATA_ERROR: interpreting out of range value as 0 FIXME\n")); break; } } break; case 'C': case 'c': TRACE(("write control compliment writing mode \"%s\"\n", fragment_to_tempstr(arg))); out->write_style = WRITE_STYLE_COMPLEMENT; break; case 'E': case 'e': TRACE(("write control erase writing mode \"%s\"\n", fragment_to_tempstr(arg))); out->write_style = WRITE_STYLE_ERASE; break; case 'F': case 'f': TRACE(("write control plane write mask \"%s\"\n", fragment_to_tempstr(arg))); { int val; if (!regis_num_to_int(arg, &val) || val < 0 || val >= (int) context->destination_graphic->valid_registers) { TRACE(("DATA_ERROR: interpreting out of range value as 0 FIXME\n")); out->plane_mask = 0U; } else { out->plane_mask = (unsigned) val; } } break; case 'I': case 'i': TRACE(("write control foreground color \"%s\"\n", fragment_to_tempstr(arg))); if (!load_regis_regnum_or_colorspec(context, arg, &out->foreground)) { TRACE(("DATA_ERROR: write control foreground color specifier not recognized: \"%s\"\n", fragment_to_tempstr(arg))); return 0; } break; case 'L': case 'l': TRACE(("write control line width \"%s\" (FIXME: currently ignored)\n", fragment_to_tempstr(arg))); { int val; if (!regis_num_to_int(arg, &val) || val < 0 || val >= (int) 9) { TRACE(("interpreting out of range value as 1 FIXME\n")); out->line_width = 1U; } else { out->line_width = (unsigned) val; } } break; case 'M': case 'm': TRACE(("write control found pixel multiplication factor \"%s\"\n", fragment_to_tempstr(arg))); { int val; if (!regis_num_to_int(arg, &val) || val <= 0) { TRACE(("interpreting out of range value %d as 1 FIXME\n", val)); out->pv_multiplier = 1U; } else { out->pv_multiplier = (unsigned) val; } } break; case 'N': case 'n': TRACE(("write control negative pattern control \"%s\"\n", fragment_to_tempstr(arg))); { int val; if (!regis_num_to_int(arg, &val)) { val = -1; } switch (val) { default: TRACE(("interpreting out of range value %d as 0 FIXME\n", val)); out->invert_pattern = 0U; break; case 0: out->invert_pattern = 0U; break; case 1: out->invert_pattern = 1U; break; } } break; case 'P': case 'p': TRACE(("write control found pattern control \"%s\"\n", fragment_to_tempstr(arg))); { RegisDataFragment suboptionset; RegisDataFragment suboptionarg; RegisDataFragment item; char suboption; while (!fragment_consumed(arg)) { if (skip_regis_whitespace(arg)) continue; TRACE(("looking for option in \"%s\"\n", fragment_to_tempstr(arg))); if (extract_regis_parenthesized_data(arg, &suboptionset)) { TRACE(("got write pattern suboptionset: \"%s\"\n", fragment_to_tempstr(&suboptionset))); while (!fragment_consumed(&suboptionset)) { skip_regis_whitespace(&suboptionset); if (extract_regis_option(&suboptionset, &suboption, &suboptionarg)) { skip_regis_whitespace(&suboptionarg); TRACE(("inspecting write pattern suboption \"%c\" with value \"%s\"\n", suboption, fragment_to_tempstr(&suboptionarg))); switch (suboption) { case 'M': case 'm': TRACE(("found pattern multiplier \"%s\"\n", fragment_to_tempstr(&suboptionarg))); { RegisDataFragment num; int val; if (extract_regis_num(&suboptionarg, &num)) { if (!regis_num_to_int(&num, &val) || val < 1) { TRACE(("interpreting out of range pattern multiplier \"%s\" as 2 FIXME\n", fragment_to_tempstr(&num))); out->pattern_multiplier = 2U; } else { out->pattern_multiplier = (unsigned) val; } skip_regis_whitespace(&suboptionarg); } if (!fragment_consumed(&suboptionarg)) { TRACE(("DATA_ERROR: unknown content after pattern multiplier \"%s\"\n", fragment_to_tempstr(&suboptionarg))); return 0; } } break; default: TRACE(("DATA_ERROR: unknown ReGIS write pattern suboption '%c' arg \"%s\"\n", suboption, fragment_to_tempstr(&suboptionarg))); return 0; } continue; } TRACE(("DATA_ERROR: skipping unknown token in pattern control suboptionset (expecting option): \"%s\"\n", fragment_to_tempstr(&suboptionset))); pop_fragment(&suboptionset); } continue; } TRACE(("looking for int in \"%s\"\n", fragment_to_tempstr(arg))); if (extract_regis_num(arg, &item)) { if (peek_fragment(&item) == '0' || peek_fragment(&item) == '1') { unsigned pattern = 0U; unsigned bitcount; TRACE(("converting pattern bits \"%s\"\n", fragment_to_tempstr(&item))); for (bitcount = 0;; bitcount++) { char ch = pop_fragment(&item); if (ch == '\0') break; switch (ch) { case '0': if (bitcount < MAX_PATTERN_BITS) { pattern <<= 1U; } break; case '1': if (bitcount < MAX_PATTERN_BITS) { pattern <<= 1U; pattern |= 1U; } break; default: TRACE(("DATA_ERROR: unknown ReGIS write pattern bit value \"%c\"\n", ch)); return 0; } } if (bitcount > 0U) { unsigned extrabits; for (extrabits = 0; bitcount + extrabits < MAX_PATTERN_BITS; extrabits++) { if (pattern & (1U << (bitcount - 1U))) { pattern <<= 1U; pattern |= 1U; } else { pattern <<= 1U; } } } out->pattern = pattern; } else { int val; TRACE(("converting pattern id \"%s\"\n", fragment_to_tempstr(&item))); if (!regis_num_to_int(&item, &val)) val = -1; switch (val) { /* FIXME: exponential allowed? */ case 0: out->pattern = 0x00; /* solid bg */ break; case 1: out->pattern = 0xff; /* solid fg */ break; case 2: out->pattern = 0xf0; /* dash */ break; case 3: out->pattern = 0xe4; /* dash dot */ break; case 4: out->pattern = 0xaa; /* dot */ break; case 5: out->pattern = 0xea; /* dash dot dot */ break; case 6: out->pattern = 0x88; /* sparse dot */ break; case 7: out->pattern = 0x84; /* asymmetric sparse dot */ break; case 8: out->pattern = 0xc8; /* sparse dash dot */ break; case 9: out->pattern = 0x86; /* sparse dot dash */ break; default: TRACE(("DATA_ERROR: unknown ReGIS standard write pattern \"%d\"\n", val)); return 0; } } TRACE(("final pattern is %02x\n", out->pattern)); continue; } skip_regis_whitespace(arg); TRACE(("DATA_ERROR: skipping unknown token in pattern suboption: \"%s\"\n", fragment_to_tempstr(arg))); pop_fragment(arg); } } break; case 'R': case 'r': TRACE(("write control switch to replacement writing mode \"%s\"\n", fragment_to_tempstr(arg))); out->write_style = WRITE_STYLE_REPLACE; break; case 'S': case 's': TRACE(("write control shading control \"%s\"\n", fragment_to_tempstr(arg))); { RegisDataFragment suboptionset; RegisDataFragment suboptionarg; RegisDataFragment item; char suboption; char shading_character = '\0'; unsigned reference_dim = WRITE_SHADING_REF_Y; /* FIXME: are relative offsets additive? */ int ref_x = cur_x, ref_y = cur_y; int shading_enabled = 0; while (!fragment_consumed(arg)) { if (skip_regis_whitespace(arg)) continue; if (extract_regis_string(arg, state->temp, state->templen)) { TRACE(("found fill char \"%s\"\n", state->temp)); /* FIXME: allow longer strings, ignore extra chars, or treat as error? */ if (strlen(state->temp) != 1) { TRACE(("DATA_ERROR: expected exactly one char in fill string FIXME\n")); return 0; } shading_character = state->temp[0]; shading_enabled = 1; TRACE(("shading character is: '%c' (%d)\n", shading_character, (int) shading_character)); continue; } if (extract_regis_parenthesized_data(arg, &suboptionset)) { skip_regis_whitespace(&suboptionset); TRACE(("got shading control suboptionset: \"%s\"\n", fragment_to_tempstr(&suboptionset))); while (!fragment_consumed(&suboptionset)) { if (skip_regis_whitespace(&suboptionset)) continue; if (extract_regis_option(&suboptionset, &suboption, &suboptionarg)) { TRACE(("inspecting write shading suboption \"%c\" with value \"%s\"\n", suboption, fragment_to_tempstr(&suboptionarg))); switch (suboption) { case 'X': case 'x': TRACE(("found horizontal shading suboption \"%s\"\n", fragment_to_tempstr(&suboptionarg))); if (!fragment_consumed(&suboptionarg)) { TRACE(("DATA_ERROR: unexpected value to horizontal shading suboption FIXME\n")); return 0; } reference_dim = WRITE_SHADING_REF_X; shading_enabled = 1; break; default: TRACE(("DATA_ERROR: unknown ReGIS write pattern suboption '%c' arg \"%s\"\n", suboption, fragment_to_tempstr(&suboptionarg))); return 0; } continue; } TRACE(("DATA_ERROR: skipping unknown token in shading control suboptionset (expecting option): \"%s\"\n", fragment_to_tempstr(&suboptionset))); pop_fragment(&suboptionset); } continue; } if (extract_regis_extent(arg, &item)) { TRACE(("found extent in shading option curr=%d,%d ref=%d,%d\n", cur_x, cur_y, ref_x, ref_y)); if (!load_regis_coord_extent(context, fragment_to_tempstr(&item), ref_x, ref_y, &ref_x, &ref_y)) { TRACE(("DATA_ERROR: unable to parse extent in write shading option '%c': \"%s\"\n", option, fragment_to_tempstr(&item))); return 0; } TRACE(("shading reference = %d,%d (%s)\n", ref_x, ref_y, ((reference_dim == WRITE_SHADING_REF_X) ? "X" : "Y"))); continue; } if (extract_regis_num(arg, &item)) { if (!regis_num_to_int(&item, &shading_enabled)) { TRACE(("DATA_ERROR: unable to parse int in write shading option '%c': \"%s\"\n", option, fragment_to_tempstr(&item))); return 0; } if (shading_enabled < 0 || shading_enabled > 1) { TRACE(("interpreting out of range value %d as 0 FIXME\n", shading_enabled)); shading_enabled = 0; } TRACE(("shading enabled = %d\n", shading_enabled)); continue; } if (skip_regis_whitespace(arg)) { continue; } TRACE(("DATA_ERROR: skipping unknown token in shade suboption: \"%s\"\n", fragment_to_tempstr(arg))); pop_fragment(arg); } if (shading_enabled) { out->shading_enabled = 1U; out->shading_reference_dim = reference_dim; out->shading_reference = ((reference_dim == WRITE_SHADING_REF_X) ? ref_x : ref_y); out->shading_character = shading_character; TRACE(("final shading state: enabled, dim=%d ref=%d, char=%c\n", out->shading_reference_dim, out->shading_reference, out->shading_character)); } else { /* FIXME: confirm there is no effect if shading isn't enabled * in the same command */ out->shading_enabled = 0U; TRACE(("final shading state: shading disabled\n")); } } break; case 'V': case 'v': TRACE(("write control switch to overlay writing mode \"%s\"\n", fragment_to_tempstr(arg))); out->write_style = WRITE_STYLE_OVERLAY; break; default: TRACE(("DATA_ERROR: ignoring unknown ReGIS write option \"%c\" arg \"%s\"\n", option, fragment_to_tempstr(arg))); return 0; } return 1; } static int load_regis_write_control_set(RegisParseState *state, RegisGraphicsContext const *context, int cur_x, int cur_y, RegisDataFragment *controls, RegisWriteControls *out) { RegisDataFragment optionset; RegisDataFragment arg; char option; while (!fragment_consumed(controls)) { if (skip_regis_whitespace(controls)) continue; if (extract_regis_parenthesized_data(controls, &optionset)) { TRACE(("got write control optionset: \"%s\"\n", fragment_to_tempstr(&optionset))); while (!fragment_consumed(&optionset)) { skip_regis_whitespace(&optionset); if (extract_regis_option(&optionset, &option, &arg)) { skip_regis_whitespace(&arg); TRACE(("got write control option and value: \"%c\" \"%s\"\n", option, fragment_to_tempstr(&arg))); if (!load_regis_write_control(state, context, cur_x, cur_y, option, &arg, out)) { return 0; } continue; } TRACE(("DATA_ERROR: skipping unknown token in write control optionset (expecting option): \"%s\"\n", fragment_to_tempstr(&optionset))); pop_fragment(&optionset); } continue; } TRACE(("DATA_ERROR: skipping unknown token in write controls (expecting optionset): \"%s\"\n", fragment_to_tempstr(controls))); pop_fragment(controls); } return 1; } static void init_regis_write_controls(int graphics_termid, unsigned all_planes, RegisWriteControls *controls) { controls->pv_multiplier = 1U; controls->pattern = 0xff; /* solid */ controls->pattern_multiplier = 2U; controls->invert_pattern = 0U; controls->plane_mask = all_planes; controls->write_style = WRITE_STYLE_OVERLAY; switch (graphics_termid) { case 125: /* FIXME: verify */ case 240: /* FIXME: verify */ case 241: /* FIXME: verify */ case 330: controls->foreground = 3U; break; case 340: default: controls->foreground = 7U; break; case 382: controls->foreground = 1U; /* FIXME: verify */ break; } controls->shading_enabled = 0U; controls->shading_character = '\0'; controls->shading_reference = 0; /* no meaning if shading is disabled */ controls->shading_reference_dim = WRITE_SHADING_REF_NONE; controls->line_width = 1U; /* FIXME: add the rest */ } static void map_regis_graphics_pages(XtermWidget xw, RegisGraphicsContext *context) { const int charrow = 0; const int charcol = 0; unsigned old_display_id = ~0U; if (context->destination_graphic) context->destination_graphic->hidden = True; if (context->display_graphic) { context->display_graphic->hidden = True; old_display_id = context->display_graphic->id; } context->destination_graphic = get_new_or_matching_graphic(xw, charrow, charcol, context->width, context->height, context->destination_page); if (context->destination_graphic) { context->destination_graphic->hidden = True; context->destination_graphic->valid = True; } context->display_graphic = get_new_or_matching_graphic(xw, charrow, charcol, context->width, context->height, context->display_page); if (context->display_graphic) { context->display_graphic->hidden = False; if (old_display_id != context->display_graphic->id) { if (!context->display_graphic->valid) { draw_solid_rectangle(context->display_graphic, 0, 0, context->width, context->height, context->background); } context->display_graphic->dirty = True; context->force_refresh = True; /* FIXME: This isn't really enough. If there are holes in the new * graphic they should be cleared and set to the text from the same * page. But we don't have pages for text in xterm (the alt buffer * is similar though). */ } context->display_graphic->valid = True; } TRACE(("using graphics destination=[%d -> %u] display=[%d -> %u]\n", context->destination_page, (context->destination_graphic ? context->destination_graphic->id : 0U), context->display_page, (context->display_graphic ? context->display_graphic->id : 0U))); } static void copy_regis_write_controls(RegisWriteControls const *src, RegisWriteControls *dst) { dst->pv_multiplier = src->pv_multiplier; dst->pattern = src->pattern; dst->pattern_multiplier = src->pattern_multiplier; dst->invert_pattern = src->invert_pattern; dst->foreground = src->foreground; dst->plane_mask = src->plane_mask; dst->write_style = src->write_style; dst->shading_enabled = src->shading_enabled; dst->shading_character = src->shading_character; dst->shading_reference = src->shading_reference; dst->shading_reference_dim = src->shading_reference_dim; dst->line_width = src->line_width; } static void init_regis_text_controls(RegisTextControls *controls) { controls->alphabet_num = 0U; /* built-in */ controls->character_set_l = 0U; /* ASCII */ controls->character_set_r = 0U; /* Latin-1 */ get_standard_character_size(1, &controls->character_display_w, &controls->character_display_h, &controls->character_unit_cell_w, &controls->character_unit_cell_h, &controls->character_inc_x, &controls->character_inc_y); controls->string_rotation = 0; controls->character_rotation = 0; controls->slant = 0; } static void copy_regis_text_controls(RegisTextControls const *src, RegisTextControls *dst) { dst->alphabet_num = src->alphabet_num; dst->character_set_l = src->character_set_l; dst->character_set_r = src->character_set_r; dst->character_display_w = src->character_display_w; dst->character_display_h = src->character_display_h; dst->character_unit_cell_w = src->character_unit_cell_w; dst->character_unit_cell_h = src->character_unit_cell_h; dst->character_inc_x = src->character_inc_x; dst->character_inc_y = src->character_inc_y; dst->string_rotation = src->string_rotation; dst->character_rotation = src->character_rotation; dst->slant = src->slant; } static void init_regis_alphabets(RegisGraphicsContext *context) { unsigned alphabet_index; for (alphabet_index = 0U; alphabet_index < MAX_REGIS_ALPHABETS; alphabet_index++) { context->alphabets[alphabet_index].alphabet_num = INVALID_ALPHABET_NUM; context->alphabets[alphabet_index].pixw = 0U; context->alphabets[alphabet_index].pixh = 0U; context->alphabets[alphabet_index].name[0] = '\0'; context->alphabets[alphabet_index].fontname[0] = '\0'; context->alphabets[alphabet_index].use_font = 0; context->alphabets[alphabet_index].bytes = NULL; } } static void init_regis_graphics_context(int graphics_termid, int width, int height, unsigned max_colors, const char *builtin_font, RegisGraphicsContext *context) { context->destination_graphic = NULL; context->display_graphic = NULL; context->display_page = 0U; context->destination_page = 0U; context->graphics_termid = graphics_termid; /* reset addressing / clear user coordinates */ context->width = width; context->height = height; context->x_off = 0; context->y_off = 0; context->x_div = width - 1; context->y_div = height - 1; /* * Generate a mask covering all valid color register address bits * (but don't bother past 2**16). */ context->all_planes = max_colors; context->all_planes--; context->all_planes |= 1U; context->all_planes |= context->all_planes >> 1U; context->all_planes |= context->all_planes >> 2U; context->all_planes |= context->all_planes >> 4U; context->all_planes |= context->all_planes >> 8U; context->builtin_font = builtin_font; init_regis_write_controls(graphics_termid, context->all_planes, &context->persistent_write_controls); copy_regis_write_controls(&context->persistent_write_controls, &context->temporary_write_controls); init_regis_text_controls(&context->persistent_text_controls); context->current_text_controls = &context->persistent_text_controls; init_regis_alphabets(context); context->multi_input_mode = 0; /* FIXME: coordinates */ /* FIXME: scrolling */ context->background = 0U; /* FIXME: input cursor location */ /* FIXME: input cursor style */ context->graphics_output_cursor_x = 0; context->graphics_output_cursor_y = 0; /* FIXME: output cursor style */ context->force_refresh = False; } static int parse_regis_command(RegisParseState *state) { char ch; if (!extract_regis_command(&state->input, &ch)) return 0; switch (ch) { case 'C': case 'c': /* Curve * C * (A) # set the arc length in degrees (+ or nothing for * # counter-clockwise, - for clockwise, rounded to the * # closest integer degree) * (B) # begin closed curve sequence (must have at least two * # values; this option can not be nested) * (C) # position is the center, current location is the * # circumference (stays in effect until next command) * (E) # end curve sequence (drawing is performed here) * (S) # begin open curve sequence * (W) # temporary write options (see write command) * [] # center if (C), otherwise point on circumference * []... # if between (B) and (E) * ... # if between (B) and (E) */ TRACE(("found ReGIS command \"%c\" (curve)\n", ch)); state->command = 'c'; state->curve_mode = CURVE_POSITION_ARC_EDGE; state->arclen = 360; state->num_points = 0U; break; case 'F': case 'f': /* Fill * F * (V) # polygon (see vector command) * (C) # curve (see curve command) * (W) # temporary write options (see write command) */ TRACE(("found ReGIS command \"%c\" (filled polygon)\n", ch)); state->command = 'f'; break; case 'L': case 'l': /* Load * L * (A) # set alphabet number or name * (F)"fontname" # load from font (xterm extension) * (S)[w,h] # set glyph size (xterm extension) * "ascii"xx,xx,xx,xx,xx,xx,xx,xx # pixel values */ TRACE(("found ReGIS command \"%c\" (load charset)\n", ch)); state->command = 'l'; break; case 'P': case 'p': /* Position * P * (B) # begin bounded position stack (last point returns to first) * (E) # end position stack * (P) # select graphics page for the input and output cursors * (S) # begin unbounded position stack * (W) # temporary write options (see write command) * # move: 0 == right, 1 == upper right, ..., 7 == lower right * [] # move to position (X, Y, or both) * * Note the stack does not need to be ended before the next command * Note: maximum depth is 16 levels */ TRACE(("found ReGIS command \"%c\" (position)\n", ch)); state->command = 'p'; break; case 'R': case 'r': /* Report * R * (E) # parse error * (I) # set input mode (0 == one-shot, 1 == multiple) (always returns CR) * (L) # current alphabet number and name * (M() # macrograph contents * (M(=) # macrograph storage (free bytes of total bytes) * (P) # absolute output cursor position * (P(I)) # interactive locator mode (in one-shot or multiple mode) * (P(I[xmul,ymul])) # interactive locator mode with arrow key movement multipliers */ TRACE(("found ReGIS command \"%c\" (report status)\n", ch)); state->command = 'r'; break; case 'S': case 's': /* Screen * S * (A[][]) # adjust screen coordinates * (C # 0 (cursor output off), 1 (cursor output on) * (E) # erase to background color, resets shades, curves, and stacks * (F) # print the graphic and erase the screen (DECprint extension) * (H(P)[][) * (I) # set the background to a specific register * (I()) # set the background to the register closest to an "RGB" color * (I(RGB)) # set the background to the register closest to an RGB triplet (RLogin extension) * (I(HLS)) # set the background to the register closest to an HLS triplet * (I(L)) # set the background to the register closest to a grayscale value * (M()...) # codes are D (black), R (red), G (green), B (blue), C (cyan), Y (yellow), M (magenta), W (white) (sets color and grayscale registers) * (M(A)...) # codes are D (black), R (red), G (green), B (blue), C (cyan), Y (yellow), M (magenta), W (white) (sets color registers only) * (M(RGB)...) # 0..100, 0..100, 0..100 (sets color and grayscale registers) (RLogin extension) * (M(ARGB)...) # 0..100, 0..100, 0..100 (sets color registers only) (RLogin extension) * (M(HLS)...) # 0..360, 0..100, 0..100 (sets color and grayscale registers) * (M(AHLS)...) # 0..360, 0..100, 0..100 (sets color registers only) * (M(L)...) # level is 0 ... 100 (sets grayscale registers only) * (P) # 0 (default) or 1 * (S() # scale screen output by scale (default 1, VT125:max=2, VT3x0:unsupported) FIXME * (S(X) # scale screen output horizontally by scale (default 1, VT125:max=2, VT3x0:unsupported) FIXME * (S(Y) # scale screen output vertically by scale (default 1, VT125:max=2, VT3x0:unsupported) FIXME * (T(