charproc.c revision e0a2b6df
1e0a2b6dfSmrg/* $XTermId: charproc.c,v 1.1322 2014/03/02 23:32:05 tom Exp $ */
2d522f475Smrg
3d522f475Smrg/*
4e0a2b6dfSmrg * Copyright 1999-2013,2014 by Thomas E. Dickey
5a1f3da82Smrg *
6a1f3da82Smrg *                         All Rights Reserved
7a1f3da82Smrg *
8a1f3da82Smrg * Permission is hereby granted, free of charge, to any person obtaining a
9a1f3da82Smrg * copy of this software and associated documentation files (the
10a1f3da82Smrg * "Software"), to deal in the Software without restriction, including
11a1f3da82Smrg * without limitation the rights to use, copy, modify, merge, publish,
12a1f3da82Smrg * distribute, sublicense, and/or sell copies of the Software, and to
13a1f3da82Smrg * permit persons to whom the Software is furnished to do so, subject to
14a1f3da82Smrg * the following conditions:
15a1f3da82Smrg *
16a1f3da82Smrg * The above copyright notice and this permission notice shall be included
17a1f3da82Smrg * in all copies or substantial portions of the Software.
18a1f3da82Smrg *
19a1f3da82Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20a1f3da82Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21a1f3da82Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22a1f3da82Smrg * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
23a1f3da82Smrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24a1f3da82Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25a1f3da82Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26a1f3da82Smrg *
27a1f3da82Smrg * Except as contained in this notice, the name(s) of the above copyright
28a1f3da82Smrg * holders shall not be used in advertising or otherwise to promote the
29a1f3da82Smrg * sale, use or other dealings in this Software without prior written
30a1f3da82Smrg * authorization.
31a1f3da82Smrg *
32a1f3da82Smrg *
33a1f3da82Smrg * Copyright 1988  The Open Group
34a1f3da82Smrg *
35a1f3da82Smrg * Permission to use, copy, modify, distribute, and sell this software and its
36a1f3da82Smrg * documentation for any purpose is hereby granted without fee, provided that
37a1f3da82Smrg * the above copyright notice appear in all copies and that both that
38a1f3da82Smrg * copyright notice and this permission notice appear in supporting
39a1f3da82Smrg * documentation.
40a1f3da82Smrg *
41a1f3da82Smrg * The above copyright notice and this permission notice shall be included in
42a1f3da82Smrg * all copies or substantial portions of the Software.
43a1f3da82Smrg *
44a1f3da82Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45a1f3da82Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46a1f3da82Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
47a1f3da82Smrg * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
48a1f3da82Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
49a1f3da82Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
50a1f3da82Smrg *
51a1f3da82Smrg * Except as contained in this notice, the name of The Open Group shall not be
52a1f3da82Smrg * used in advertising or otherwise to promote the sale, use or other dealings
53a1f3da82Smrg * in this Software without prior written authorization from The Open Group.
54a1f3da82Smrg *
55a1f3da82Smrg */
56d522f475Smrg/*
57d522f475Smrg * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
58d522f475Smrg *
59d522f475Smrg *                         All Rights Reserved
60d522f475Smrg *
61d522f475Smrg * Permission to use, copy, modify, and distribute this software and its
62d522f475Smrg * documentation for any purpose and without fee is hereby granted,
63d522f475Smrg * provided that the above copyright notice appear in all copies and that
64d522f475Smrg * both that copyright notice and this permission notice appear in
65d522f475Smrg * supporting documentation, and that the name of Digital Equipment
66d522f475Smrg * Corporation not be used in advertising or publicity pertaining to
67d522f475Smrg * distribution of the software without specific, written prior permission.
68d522f475Smrg *
69d522f475Smrg *
70d522f475Smrg * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
71d522f475Smrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
72d522f475Smrg * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
73d522f475Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
74d522f475Smrg * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
75d522f475Smrg * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
76d522f475Smrg * SOFTWARE.
77d522f475Smrg */
78d522f475Smrg
79d522f475Smrg/* charproc.c */
80d522f475Smrg
81d522f475Smrg#include <version.h>
82d522f475Smrg#include <xterm.h>
83d522f475Smrg
84d522f475Smrg#include <X11/Xatom.h>
85d522f475Smrg#include <X11/Xutil.h>
86d522f475Smrg#include <X11/cursorfont.h>
87d522f475Smrg#include <X11/Xmu/Atoms.h>
88d522f475Smrg#include <X11/Xmu/CharSet.h>
89d522f475Smrg#include <X11/Xmu/Converters.h>
90d522f475Smrg
91d522f475Smrg#if OPT_INPUT_METHOD
92d522f475Smrg
93d522f475Smrg#if defined(HAVE_LIB_XAW)
94d522f475Smrg#include <X11/Xaw/XawImP.h>
95d522f475Smrg#elif defined(HAVE_LIB_XAW3D)
96d522f475Smrg#include <X11/Xaw3d/XawImP.h>
97d522f475Smrg#elif defined(HAVE_LIB_NEXTAW)
98d522f475Smrg#include <X11/neXtaw/XawImP.h>
99d522f475Smrg#elif defined(HAVE_LIB_XAWPLUS)
100d522f475Smrg#include <X11/XawPlus/XawImP.h>
101d522f475Smrg#endif
102d522f475Smrg
103d522f475Smrg#endif
104d522f475Smrg
1050bd37d32Smrg#if OPT_DOUBLE_BUFFER
1060bd37d32Smrg#include <X11/extensions/Xdbe.h>
1070bd37d32Smrg#endif
1080bd37d32Smrg
109d522f475Smrg#if OPT_WIDE_CHARS
1100bd37d32Smrg#include <xutf8.h>
111d522f475Smrg#include <wcwidth.h>
112d522f475Smrg#include <precompose.h>
113d522f475Smrg#ifdef HAVE_LANGINFO_CODESET
114d522f475Smrg#include <langinfo.h>
115d522f475Smrg#endif
116d522f475Smrg#endif
117d522f475Smrg
118d522f475Smrg#if OPT_INPUT_METHOD
119d522f475Smrg#include <X11/Xlocale.h>
120d522f475Smrg#endif
121d522f475Smrg
122d522f475Smrg#include <stdio.h>
123d522f475Smrg#include <ctype.h>
12420d2c4d2Smrg#include <assert.h>
125d522f475Smrg
126d522f475Smrg#if defined(HAVE_SCHED_YIELD)
127d522f475Smrg#include <sched.h>
128d522f475Smrg#endif
129d522f475Smrg
130d522f475Smrg#include <VTparse.h>
131d522f475Smrg#include <data.h>
132d522f475Smrg#include <error.h>
133d522f475Smrg#include <menu.h>
134d522f475Smrg#include <main.h>
135d522f475Smrg#include <fontutils.h>
136d522f475Smrg#include <charclass.h>
137d522f475Smrg#include <xstrings.h>
138e0a2b6dfSmrg#include <graphics.h>
139d522f475Smrg
140e0a2b6dfSmrgtypedef int (*BitFunc) (unsigned * /* p */ ,
141e0a2b6dfSmrg			unsigned /* mask */ );
14220d2c4d2Smrg
143d522f475Smrgstatic IChar doinput(void);
14420d2c4d2Smrgstatic int set_character_class(char * /*s */ );
145d522f475Smrgstatic void FromAlternate(XtermWidget /* xw */ );
146e39b573cSmrgstatic void ReallyReset(XtermWidget /* xw */ ,
147e39b573cSmrg			Bool /* full */ ,
148e39b573cSmrg			Bool /* saved */ );
14920d2c4d2Smrgstatic void RequestResize(XtermWidget /* xw */ ,
15020d2c4d2Smrg			  int /* rows */ ,
15120d2c4d2Smrg			  int /* cols */ ,
15220d2c4d2Smrg			  Bool /* text */ );
15320d2c4d2Smrgstatic void SwitchBufs(XtermWidget /* xw */ ,
154e0a2b6dfSmrg		       int /* toBuf */ ,
155e0a2b6dfSmrg		       Bool /* clearFirst */ );
156e0a2b6dfSmrgstatic void ToAlternate(XtermWidget /* xw */ ,
157e0a2b6dfSmrg			Bool /* clearFirst */ );
158d522f475Smrgstatic void ansi_modes(XtermWidget termw,
15920d2c4d2Smrg		       BitFunc /* func */ );
160e0a2b6dfSmrgstatic int bitclr(unsigned *p, unsigned mask);
161e0a2b6dfSmrgstatic int bitcpy(unsigned *p, unsigned q, unsigned mask);
162e0a2b6dfSmrgstatic int bitset(unsigned *p, unsigned mask);
16320d2c4d2Smrgstatic void dpmodes(XtermWidget /* xw */ ,
16420d2c4d2Smrg		    BitFunc /* func */ );
16520d2c4d2Smrgstatic void restoremodes(XtermWidget /* xw */ );
16620d2c4d2Smrgstatic void savemodes(XtermWidget /* xw */ );
16720d2c4d2Smrgstatic void window_ops(XtermWidget /* xw */ );
168d522f475Smrg
169d522f475Smrg#define DoStartBlinking(s) ((s)->cursor_blink ^ (s)->cursor_blink_esc)
170d522f475Smrg
171d522f475Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
1720bd37d32Smrg#define UpdateCursorBlink(screen) SetCursorBlink(screen, screen->cursor_blink)
17320d2c4d2Smrgstatic void SetCursorBlink(TScreen * /* screen */ ,
17420d2c4d2Smrg			   Bool /* enable */ );
17520d2c4d2Smrgstatic void HandleBlinking(XtPointer /* closure */ ,
17620d2c4d2Smrg			   XtIntervalId * /* id */ );
17720d2c4d2Smrgstatic void StartBlinking(TScreen * /* screen */ );
17820d2c4d2Smrgstatic void StopBlinking(TScreen * /* screen */ );
179d522f475Smrg#else
180d522f475Smrg#define StartBlinking(screen)	/* nothing */
181d522f475Smrg#define StopBlinking(screen)	/* nothing */
182d522f475Smrg#endif
183d522f475Smrg
1840bd37d32Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
1850bd37d32Smrgstatic void PreeditPosition(XtermWidget /* xw */ );
186d522f475Smrg#endif
187d522f475Smrg
188d522f475Smrg#define	DEFAULT		-1
189d522f475Smrg#define BELLSUPPRESSMSEC 200
190d522f475Smrg
191d522f475Smrgstatic ANSI reply;
1920bd37d32Smrgstatic PARAMS parms;
1930bd37d32Smrg
1940bd37d32Smrg#define nparam parms.count
1950bd37d32Smrg
1960bd37d32Smrg#define InitParams()  parms.count = parms.is_sub[0] = parms.has_subparams = 0
1970bd37d32Smrg#define GetParam(n)   parms.params[(n)]
1980bd37d32Smrg#define SetParam(n,v) parms.params[(n)] = v
1990bd37d32Smrg#define ParamPair(n)  nparam - (n), parms.params + (n)
2000bd37d32Smrg#define ParamsDone()  InitParams()
201d522f475Smrg
202d522f475Smrgstatic jmp_buf vtjmpbuf;
203d522f475Smrg
204d522f475Smrg/* event handlers */
205d522f475Smrgstatic void HandleBell PROTO_XT_ACTIONS_ARGS;
206d522f475Smrgstatic void HandleIgnore PROTO_XT_ACTIONS_ARGS;
207d522f475Smrgstatic void HandleKeymapChange PROTO_XT_ACTIONS_ARGS;
208d522f475Smrgstatic void HandleVisualBell PROTO_XT_ACTIONS_ARGS;
209d522f475Smrg#if HANDLE_STRUCT_NOTIFY
210d522f475Smrgstatic void HandleStructNotify PROTO_XT_EV_HANDLER_ARGS;
211d522f475Smrg#endif
212d522f475Smrg
213d522f475Smrg/*
214d522f475Smrg * NOTE: VTInitialize zeros out the entire ".screen" component of the
215d522f475Smrg * XtermWidget, so make sure to add an assignment statement in VTInitialize()
216d522f475Smrg * for each new ".screen" field added to this resource list.
217d522f475Smrg */
218d522f475Smrg
219d522f475Smrg/* Defaults */
220d522f475Smrg#if OPT_ISO_COLORS
221d522f475Smrg
222d522f475Smrg/*
223d522f475Smrg * If we default to colorMode enabled, compile-in defaults for the ANSI colors.
224d522f475Smrg */
225d522f475Smrg#if DFT_COLORMODE
226d522f475Smrg#define DFT_COLOR(name) name
227d522f475Smrg#else
228d522f475Smrg#define DFT_COLOR(name) XtDefaultForeground
229d522f475Smrg#endif
230d522f475Smrg#endif
231d522f475Smrg
23220d2c4d2Smrgstatic String _Font_Selected_ = "yes";	/* string is arbitrary */
233d522f475Smrg
234a1f3da82Smrgstatic const char *defaultTranslations;
235d522f475Smrg/* *INDENT-OFF* */
236d522f475Smrgstatic XtActionsRec actionsList[] = {
237d522f475Smrg    { "allow-send-events",	HandleAllowSends },
238d522f475Smrg    { "bell",			HandleBell },
239d522f475Smrg    { "clear-saved-lines",	HandleClearSavedLines },
2406879286fSmrg    { "copy-selection",		HandleCopySelection },
241d522f475Smrg    { "create-menu",		HandleCreateMenu },
242d522f475Smrg    { "delete-is-del",		HandleDeleteIsDEL },
243d522f475Smrg    { "dired-button",		DiredButton },
244d522f475Smrg    { "hard-reset",		HandleHardReset },
245d522f475Smrg    { "ignore",			HandleIgnore },
246d522f475Smrg    { "insert",			HandleKeyPressed },  /* alias for insert-seven-bit */
247d522f475Smrg    { "insert-eight-bit",	HandleEightBitKeyPressed },
248d522f475Smrg    { "insert-selection",	HandleInsertSelection },
249d522f475Smrg    { "insert-seven-bit",	HandleKeyPressed },
250d522f475Smrg    { "interpret",		HandleInterpret },
251d522f475Smrg    { "keymap",			HandleKeymapChange },
252d522f475Smrg    { "popup-menu",		HandlePopupMenu },
253d522f475Smrg    { "print",			HandlePrintScreen },
254956cc18dSsnj    { "print-everything",	HandlePrintEverything },
255d522f475Smrg    { "print-redir",		HandlePrintControlMode },
256d522f475Smrg    { "quit",			HandleQuit },
257d522f475Smrg    { "redraw",			HandleRedraw },
258d522f475Smrg    { "scroll-back",		HandleScrollBack },
259d522f475Smrg    { "scroll-forw",		HandleScrollForward },
260d522f475Smrg    { "secure",			HandleSecure },
261d522f475Smrg    { "select-cursor-end",	HandleKeyboardSelectEnd },
262d522f475Smrg    { "select-cursor-extend",   HandleKeyboardSelectExtend },
263d522f475Smrg    { "select-cursor-start",	HandleKeyboardSelectStart },
264d522f475Smrg    { "select-end",		HandleSelectEnd },
265d522f475Smrg    { "select-extend",		HandleSelectExtend },
266d522f475Smrg    { "select-set",		HandleSelectSet },
267d522f475Smrg    { "select-start",		HandleSelectStart },
268d522f475Smrg    { "send-signal",		HandleSendSignal },
269d522f475Smrg    { "set-8-bit-control",	Handle8BitControl },
270d522f475Smrg    { "set-allow132",		HandleAllow132 },
271d522f475Smrg    { "set-altscreen",		HandleAltScreen },
272d522f475Smrg    { "set-appcursor",		HandleAppCursor },
273d522f475Smrg    { "set-appkeypad",		HandleAppKeypad },
274d522f475Smrg    { "set-autolinefeed",	HandleAutoLineFeed },
275d522f475Smrg    { "set-autowrap",		HandleAutoWrap },
276d522f475Smrg    { "set-backarrow",		HandleBackarrow },
277d522f475Smrg    { "set-bellIsUrgent",	HandleBellIsUrgent },
278d522f475Smrg    { "set-cursesemul",		HandleCursesEmul },
279d522f475Smrg    { "set-jumpscroll",		HandleJumpscroll },
280d522f475Smrg    { "set-keep-selection",	HandleKeepSelection },
281d522f475Smrg    { "set-marginbell",		HandleMarginBell },
282d522f475Smrg    { "set-old-function-keys",	HandleOldFunctionKeys },
283d522f475Smrg    { "set-pop-on-bell",	HandleSetPopOnBell },
284d522f475Smrg    { "set-reverse-video",	HandleReverseVideo },
285d522f475Smrg    { "set-reversewrap",	HandleReverseWrap },
286d522f475Smrg    { "set-scroll-on-key",	HandleScrollKey },
287d522f475Smrg    { "set-scroll-on-tty-output", HandleScrollTtyOutput },
288d522f475Smrg    { "set-scrollbar",		HandleScrollbar },
289d522f475Smrg    { "set-select",		HandleSetSelect },
290d522f475Smrg    { "set-sun-keyboard",	HandleSunKeyboard },
291d522f475Smrg    { "set-titeInhibit",	HandleTiteInhibit },
292d522f475Smrg    { "set-visual-bell",	HandleSetVisualBell },
293d522f475Smrg    { "set-vt-font",		HandleSetFont },
294d522f475Smrg    { "soft-reset",		HandleSoftReset },
295d522f475Smrg    { "start-cursor-extend",	HandleKeyboardStartExtend },
296d522f475Smrg    { "start-extend",		HandleStartExtend },
297d522f475Smrg    { "string",			HandleStringEvent },
298d522f475Smrg    { "vi-button",		ViButton },
299d522f475Smrg    { "visual-bell",		HandleVisualBell },
300d522f475Smrg#ifdef ALLOWLOGGING
301d522f475Smrg    { "set-logging",		HandleLogging },
302d522f475Smrg#endif
303956cc18dSsnj#if OPT_ALLOW_XXX_OPS
30420d2c4d2Smrg    { "allow-color-ops",	HandleAllowColorOps },
305956cc18dSsnj    { "allow-font-ops",		HandleAllowFontOps },
306956cc18dSsnj    { "allow-tcap-ops",		HandleAllowTcapOps },
307956cc18dSsnj    { "allow-title-ops",	HandleAllowTitleOps },
308956cc18dSsnj    { "allow-window-ops",	HandleAllowWindowOps },
309956cc18dSsnj#endif
310d522f475Smrg#if OPT_BLINK_CURS
311d522f475Smrg    { "set-cursorblink",	HandleCursorBlink },
312d522f475Smrg#endif
313d522f475Smrg#if OPT_BOX_CHARS
314d522f475Smrg    { "set-font-linedrawing",	HandleFontBoxChars },
31520d2c4d2Smrg    { "set-font-packed",	HandleFontPacked },
316d522f475Smrg#endif
317d522f475Smrg#if OPT_DABBREV
318d522f475Smrg    { "dabbrev-expand",		HandleDabbrevExpand },
319d522f475Smrg#endif
320d522f475Smrg#if OPT_DEC_CHRSET
321d522f475Smrg    { "set-font-doublesize",	HandleFontDoublesize },
322d522f475Smrg#endif
323d522f475Smrg#if OPT_DEC_SOFTFONT
324d522f475Smrg    { "set-font-loading",	HandleFontLoading },
325d522f475Smrg#endif
326d522f475Smrg#if OPT_EXEC_XTERM
327d522f475Smrg    { "spawn-new-terminal",	HandleSpawnTerminal },
328d522f475Smrg#endif
329d522f475Smrg#if OPT_HP_FUNC_KEYS
330d522f475Smrg    { "set-hp-function-keys",	HandleHpFunctionKeys },
331d522f475Smrg#endif
332d522f475Smrg#if OPT_LOAD_VTFONTS
333d522f475Smrg    { "load-vt-fonts",		HandleLoadVTFonts },
334d522f475Smrg#endif
335d522f475Smrg#if OPT_MAXIMIZE
336d522f475Smrg    { "deiconify",		HandleDeIconify },
337a1f3da82Smrg    { "fullscreen",		HandleFullscreen },
338d522f475Smrg    { "iconify",		HandleIconify },
339d522f475Smrg    { "maximize",		HandleMaximize },
340d522f475Smrg    { "restore",		HandleRestoreSize },
341d522f475Smrg#endif
342d522f475Smrg#if OPT_NUM_LOCK
343d522f475Smrg    { "alt-sends-escape",	HandleAltEsc },
344d522f475Smrg    { "meta-sends-escape",	HandleMetaEsc },
345d522f475Smrg    { "set-num-lock",		HandleNumLock },
346d522f475Smrg#endif
347d522f475Smrg#if OPT_READLINE
348d522f475Smrg    { "readline-button",	ReadLineButton },
349d522f475Smrg#endif
350d522f475Smrg#if OPT_RENDERFONT
351d522f475Smrg    { "set-render-font",	HandleRenderFont },
352d522f475Smrg#endif
353d522f475Smrg#if OPT_SCO_FUNC_KEYS
354d522f475Smrg    { "set-sco-function-keys",	HandleScoFunctionKeys },
355d522f475Smrg#endif
35620d2c4d2Smrg#if OPT_SCROLL_LOCK
35720d2c4d2Smrg    { "scroll-lock",		HandleScrollLock },
35820d2c4d2Smrg#endif
3590bd37d32Smrg#if OPT_SELECTION_OPS
3600bd37d32Smrg    { "exec-formatted",		HandleExecFormatted },
3610bd37d32Smrg    { "exec-selectable",	HandleExecSelectable },
3620bd37d32Smrg    { "insert-formatted",	HandleInsertFormatted },
3630bd37d32Smrg    { "insert-selectable",	HandleInsertSelectable },
3640bd37d32Smrg#endif
365d522f475Smrg#if OPT_SHIFT_FONTS
366d522f475Smrg    { "larger-vt-font",		HandleLargerFont },
367d522f475Smrg    { "smaller-vt-font",	HandleSmallerFont },
368d522f475Smrg#endif
369e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
370e0a2b6dfSmrg    { "set-private-colors",	HandleSetPrivateColorRegisters },
371e0a2b6dfSmrg    { "set-sixel-scrolling",	HandleSixelScrolling },
372e0a2b6dfSmrg#endif
373d522f475Smrg#if OPT_SUN_FUNC_KEYS
374d522f475Smrg    { "set-sun-function-keys",	HandleSunFunctionKeys },
375d522f475Smrg#endif
376d522f475Smrg#if OPT_TEK4014
377d522f475Smrg    { "set-terminal-type",	HandleSetTerminalType },
378d522f475Smrg    { "set-visibility",		HandleVisibility },
379d522f475Smrg    { "set-tek-text",		HandleSetTekText },
380d522f475Smrg    { "tek-page",		HandleTekPage },
381d522f475Smrg    { "tek-reset",		HandleTekReset },
382d522f475Smrg    { "tek-copy",		HandleTekCopy },
383d522f475Smrg#endif
384d522f475Smrg#if OPT_TOOLBAR
385d522f475Smrg    { "set-toolbar",		HandleToolbar },
386d522f475Smrg#endif
387d522f475Smrg#if OPT_WIDE_CHARS
388d522f475Smrg    { "set-utf8-mode",		HandleUTF8Mode },
389e39b573cSmrg    { "set-utf8-fonts",		HandleUTF8Fonts },
390d522f475Smrg    { "set-utf8-title",		HandleUTF8Title },
391d522f475Smrg#endif
392d522f475Smrg};
393d522f475Smrg/* *INDENT-ON* */
394d522f475Smrg
395e39b573cSmrg#define SPS screen.printer_state
396e39b573cSmrg
39720d2c4d2Smrgstatic XtResource xterm_resources[] =
398d522f475Smrg{
3990bd37d32Smrg    Bres(XtNallowPasteControls, XtCAllowPasteControls,
4000bd37d32Smrg	 screen.allowPasteControls, False),
401d522f475Smrg    Bres(XtNallowSendEvents, XtCAllowSendEvents, screen.allowSendEvent0, False),
40220d2c4d2Smrg    Bres(XtNallowColorOps, XtCAllowColorOps, screen.allowColorOp0, DEF_ALLOW_COLOR),
403956cc18dSsnj    Bres(XtNallowFontOps, XtCAllowFontOps, screen.allowFontOp0, DEF_ALLOW_FONT),
404956cc18dSsnj    Bres(XtNallowTcapOps, XtCAllowTcapOps, screen.allowTcapOp0, DEF_ALLOW_TCAP),
405956cc18dSsnj    Bres(XtNallowTitleOps, XtCAllowTitleOps, screen.allowTitleOp0, DEF_ALLOW_TITLE),
406956cc18dSsnj    Bres(XtNallowWindowOps, XtCAllowWindowOps, screen.allowWindowOp0, DEF_ALLOW_WINDOW),
407d522f475Smrg    Bres(XtNaltIsNotMeta, XtCAltIsNotMeta, screen.alt_is_not_meta, False),
4080bd37d32Smrg    Bres(XtNaltSendsEscape, XtCAltSendsEscape, screen.alt_sends_esc, DEF_ALT_SENDS_ESC),
409e39b573cSmrg    Bres(XtNallowBoldFonts, XtCAllowBoldFonts, screen.allowBoldFonts, True),
410d522f475Smrg    Bres(XtNalwaysBoldMode, XtCAlwaysBoldMode, screen.always_bold_mode, False),
411d522f475Smrg    Bres(XtNalwaysHighlight, XtCAlwaysHighlight, screen.always_highlight, False),
412d522f475Smrg    Bres(XtNappcursorDefault, XtCAppcursorDefault, misc.appcursorDefault, False),
413d522f475Smrg    Bres(XtNappkeypadDefault, XtCAppkeypadDefault, misc.appkeypadDefault, False),
4140bd37d32Smrg    Bres(XtNalternateScroll, XtCScrollCond, screen.alternateScroll, False),
415d522f475Smrg    Bres(XtNautoWrap, XtCAutoWrap, misc.autoWrap, True),
416d522f475Smrg    Bres(XtNawaitInput, XtCAwaitInput, screen.awaitInput, False),
417d522f475Smrg    Bres(XtNfreeBoldBox, XtCFreeBoldBox, screen.free_bold_box, False),
4180bd37d32Smrg    Bres(XtNbackarrowKey, XtCBackarrowKey, screen.backarrow_key, DEF_BACKARO_BS),
419d522f475Smrg    Bres(XtNbellIsUrgent, XtCBellIsUrgent, screen.bellIsUrgent, False),
420d522f475Smrg    Bres(XtNbellOnReset, XtCBellOnReset, screen.bellOnReset, True),
421d522f475Smrg    Bres(XtNboldMode, XtCBoldMode, screen.bold_mode, True),
422d522f475Smrg    Bres(XtNbrokenSelections, XtCBrokenSelections, screen.brokenSelections, False),
423d522f475Smrg    Bres(XtNc132, XtCC132, screen.c132, False),
4240bd37d32Smrg    Bres(XtNcdXtraScroll, XtCCdXtraScroll, misc.cdXtraScroll, False),
425d522f475Smrg    Bres(XtNcurses, XtCCurses, screen.curses, False),
426d522f475Smrg    Bres(XtNcutNewline, XtCCutNewline, screen.cutNewline, True),
427d522f475Smrg    Bres(XtNcutToBeginningOfLine, XtCCutToBeginningOfLine,
428d522f475Smrg	 screen.cutToBeginningOfLine, True),
429d522f475Smrg    Bres(XtNdeleteIsDEL, XtCDeleteIsDEL, screen.delete_is_del, DEFDELETE_DEL),
430d522f475Smrg    Bres(XtNdynamicColors, XtCDynamicColors, misc.dynamicColors, True),
431d522f475Smrg    Bres(XtNeightBitControl, XtCEightBitControl, screen.control_eight_bits, False),
432d522f475Smrg    Bres(XtNeightBitInput, XtCEightBitInput, screen.input_eight_bits, True),
433d522f475Smrg    Bres(XtNeightBitOutput, XtCEightBitOutput, screen.output_eight_bits, True),
434d522f475Smrg    Bres(XtNhighlightSelection, XtCHighlightSelection,
435d522f475Smrg	 screen.highlight_selection, False),
436492d43a5Smrg    Bres(XtNshowWrapMarks, XtCShowWrapMarks, screen.show_wrap_marks, False),
437d522f475Smrg    Bres(XtNhpLowerleftBugCompat, XtCHpLowerleftBugCompat, screen.hp_ll_bc, False),
438d522f475Smrg    Bres(XtNi18nSelections, XtCI18nSelections, screen.i18nSelections, True),
439956cc18dSsnj    Bres(XtNfastScroll, XtCFastScroll, screen.fastscroll, False),
440d522f475Smrg    Bres(XtNjumpScroll, XtCJumpScroll, screen.jumpscroll, True),
441956cc18dSsnj    Bres(XtNkeepSelection, XtCKeepSelection, screen.keepSelection, True),
442d522f475Smrg    Bres(XtNloginShell, XtCLoginShell, misc.login_shell, False),
443d522f475Smrg    Bres(XtNmarginBell, XtCMarginBell, screen.marginbell, False),
4440bd37d32Smrg    Bres(XtNmetaSendsEscape, XtCMetaSendsEscape, screen.meta_sends_esc, DEF_META_SENDS_ESC),
445d522f475Smrg    Bres(XtNmultiScroll, XtCMultiScroll, screen.multiscroll, False),
446d522f475Smrg    Bres(XtNoldXtermFKeys, XtCOldXtermFKeys, screen.old_fkeys, False),
447d522f475Smrg    Bres(XtNpopOnBell, XtCPopOnBell, screen.poponbell, False),
448e39b573cSmrg    Bres(XtNprinterAutoClose, XtCPrinterAutoClose, SPS.printer_autoclose, False),
449e39b573cSmrg    Bres(XtNprinterExtent, XtCPrinterExtent, SPS.printer_extent, False),
450e39b573cSmrg    Bres(XtNprinterFormFeed, XtCPrinterFormFeed, SPS.printer_formfeed, False),
451e39b573cSmrg    Bres(XtNprinterNewLine, XtCPrinterNewLine, SPS.printer_newline, True),
452d522f475Smrg    Bres(XtNquietGrab, XtCQuietGrab, screen.quiet_grab, False),
453d522f475Smrg    Bres(XtNreverseVideo, XtCReverseVideo, misc.re_verse, False),
454d522f475Smrg    Bres(XtNreverseWrap, XtCReverseWrap, misc.reverseWrap, False),
455d522f475Smrg    Bres(XtNscrollBar, XtCScrollBar, misc.scrollbar, False),
456d522f475Smrg    Bres(XtNscrollKey, XtCScrollCond, screen.scrollkey, False),
457d522f475Smrg    Bres(XtNscrollTtyOutput, XtCScrollCond, screen.scrollttyoutput, True),
458d522f475Smrg    Bres(XtNselectToClipboard, XtCSelectToClipboard,
459d522f475Smrg	 screen.selectToClipboard, False),
460d522f475Smrg    Bres(XtNsignalInhibit, XtCSignalInhibit, misc.signalInhibit, False),
461d522f475Smrg    Bres(XtNtiteInhibit, XtCTiteInhibit, misc.titeInhibit, False),
462d522f475Smrg    Bres(XtNtiXtraScroll, XtCTiXtraScroll, misc.tiXtraScroll, False),
463d522f475Smrg    Bres(XtNtrimSelection, XtCTrimSelection, screen.trim_selection, False),
464d522f475Smrg    Bres(XtNunderLine, XtCUnderLine, screen.underline, True),
465d522f475Smrg    Bres(XtNvisualBell, XtCVisualBell, screen.visualbell, False),
4660bd37d32Smrg    Bres(XtNvisualBellLine, XtCVisualBellLine, screen.flash_line, False),
4670bd37d32Smrg
4680bd37d32Smrg    Dres(XtNscaleHeight, XtCScaleHeight, screen.scale_height, "1.0"),
469d522f475Smrg
470d522f475Smrg    Ires(XtNbellSuppressTime, XtCBellSuppressTime, screen.bellSuppressTime, BELLSUPPRESSMSEC),
471956cc18dSsnj    Ires(XtNfontWarnings, XtCFontWarnings, misc.fontWarnings, fwResource),
472d522f475Smrg    Ires(XtNinternalBorder, XtCBorderWidth, screen.border, DEFBORDER),
473d522f475Smrg    Ires(XtNlimitResize, XtCLimitResize, misc.limit_resize, 1),
474d522f475Smrg    Ires(XtNmultiClickTime, XtCMultiClickTime, screen.multiClickTime, MULTICLICKTIME),
475d522f475Smrg    Ires(XtNnMarginBell, XtCColumn, screen.nmarginbell, N_MARGINBELL),
476d522f475Smrg    Ires(XtNpointerMode, XtCPointerMode, screen.pointer_mode, DEF_POINTER_MODE),
477d522f475Smrg    Ires(XtNprinterControlMode, XtCPrinterControlMode,
478e39b573cSmrg	 SPS.printer_controlmode, 0),
47920d2c4d2Smrg    Ires(XtNtitleModes, XtCTitleModes, screen.title_modes, DEF_TITLE_MODES),
480d522f475Smrg    Ires(XtNvisualBellDelay, XtCVisualBellDelay, screen.visualBellDelay, 100),
481d522f475Smrg    Ires(XtNsaveLines, XtCSaveLines, screen.savelines, SAVELINES),
482d522f475Smrg    Ires(XtNscrollBarBorder, XtCScrollBarBorder, screen.scrollBarBorder, 1),
483d522f475Smrg    Ires(XtNscrollLines, XtCScrollLines, screen.scrolllines, SCROLLLINES),
484d522f475Smrg
485d522f475Smrg    Sres(XtNinitialFont, XtCInitialFont, screen.initial_font, NULL),
486d522f475Smrg    Sres(XtNfont1, XtCFont1, screen.MenuFontName(fontMenu_font1), NULL),
487d522f475Smrg    Sres(XtNfont2, XtCFont2, screen.MenuFontName(fontMenu_font2), NULL),
488d522f475Smrg    Sres(XtNfont3, XtCFont3, screen.MenuFontName(fontMenu_font3), NULL),
489d522f475Smrg    Sres(XtNfont4, XtCFont4, screen.MenuFontName(fontMenu_font4), NULL),
490d522f475Smrg    Sres(XtNfont5, XtCFont5, screen.MenuFontName(fontMenu_font5), NULL),
491d522f475Smrg    Sres(XtNfont6, XtCFont6, screen.MenuFontName(fontMenu_font6), NULL),
492956cc18dSsnj
493d522f475Smrg    Sres(XtNanswerbackString, XtCAnswerbackString, screen.answer_back, ""),
494d522f475Smrg    Sres(XtNboldFont, XtCBoldFont, misc.default_font.f_b, DEFBOLDFONT),
495d522f475Smrg    Sres(XtNcharClass, XtCCharClass, screen.charClass, NULL),
496d522f475Smrg    Sres(XtNdecTerminalID, XtCDecTerminalID, screen.term_id, DFT_DECID),
497956cc18dSsnj    Sres(XtNdefaultString, XtCDefaultString, screen.default_string, "#"),
49820d2c4d2Smrg    Sres(XtNdisallowedColorOps, XtCDisallowedColorOps,
49920d2c4d2Smrg	 screen.disallowedColorOps, DEF_DISALLOWED_COLOR),
50020d2c4d2Smrg    Sres(XtNdisallowedFontOps, XtCDisallowedFontOps,
50120d2c4d2Smrg	 screen.disallowedFontOps, DEF_DISALLOWED_FONT),
50220d2c4d2Smrg    Sres(XtNdisallowedTcapOps, XtCDisallowedTcapOps,
50320d2c4d2Smrg	 screen.disallowedTcapOps, DEF_DISALLOWED_TCAP),
50420d2c4d2Smrg    Sres(XtNdisallowedWindowOps, XtCDisallowedWindowOps,
50520d2c4d2Smrg	 screen.disallowedWinOps, DEF_DISALLOWED_WINDOW),
5060bd37d32Smrg    Sres(XtNeightBitMeta, XtCEightBitMeta, screen.eight_bit_meta_s, DEF_8BIT_META),
507956cc18dSsnj    Sres(XtNeightBitSelectTypes, XtCEightBitSelectTypes,
508956cc18dSsnj	 screen.eightbit_select_types, NULL),
509d522f475Smrg    Sres(XtNfont, XtCFont, misc.default_font.f_n, DEFFONT),
510d522f475Smrg    Sres(XtNgeometry, XtCGeometry, misc.geo_metry, NULL),
511d522f475Smrg    Sres(XtNkeyboardDialect, XtCKeyboardDialect, screen.keyboard_dialect, DFT_KBD_DIALECT),
512e39b573cSmrg    Sres(XtNprinterCommand, XtCPrinterCommand, SPS.printer_command, ""),
513d522f475Smrg    Sres(XtNtekGeometry, XtCGeometry, misc.T_geometry, NULL),
514d522f475Smrg
515d522f475Smrg    Tres(XtNcursorColor, XtCCursorColor, TEXT_CURSOR, XtDefaultForeground),
516d522f475Smrg    Tres(XtNforeground, XtCForeground, TEXT_FG, XtDefaultForeground),
517d522f475Smrg    Tres(XtNpointerColor, XtCPointerColor, MOUSE_FG, XtDefaultForeground),
518d522f475Smrg    Tres(XtNbackground, XtCBackground, TEXT_BG, XtDefaultBackground),
519d522f475Smrg    Tres(XtNpointerColorBackground, XtCBackground, MOUSE_BG, XtDefaultBackground),
520d522f475Smrg
521d522f475Smrg    {XtNresizeGravity, XtCResizeGravity, XtRGravity, sizeof(XtGravity),
522d522f475Smrg     XtOffsetOf(XtermWidgetRec, misc.resizeGravity),
523d522f475Smrg     XtRImmediate, (XtPointer) SouthWestGravity},
524d522f475Smrg
525d522f475Smrg    {XtNpointerShape, XtCCursor, XtRCursor, sizeof(Cursor),
526d522f475Smrg     XtOffsetOf(XtermWidgetRec, screen.pointer_cursor),
527d522f475Smrg     XtRString, (XtPointer) "xterm"},
528d522f475Smrg
529d522f475Smrg#ifdef ALLOWLOGGING
530d522f475Smrg    Bres(XtNlogInhibit, XtCLogInhibit, misc.logInhibit, False),
531d522f475Smrg    Bres(XtNlogging, XtCLogging, misc.log_on, False),
532d522f475Smrg    Sres(XtNlogFile, XtCLogfile, screen.logfile, NULL),
533d522f475Smrg#endif
534d522f475Smrg
535d522f475Smrg#ifndef NO_ACTIVE_ICON
5360bd37d32Smrg    Sres("activeIcon", "ActiveIcon", misc.active_icon_s, "default"),
537d522f475Smrg    Ires("iconBorderWidth", XtCBorderWidth, misc.icon_border_width, 2),
538492d43a5Smrg    Sres("iconFont", "IconFont", screen.icon_fontname, "nil2"),
539d522f475Smrg    Cres("iconBorderColor", XtCBorderColor, misc.icon_border_pixel, XtDefaultBackground),
540d522f475Smrg#endif				/* NO_ACTIVE_ICON */
541d522f475Smrg
542d522f475Smrg#if OPT_BLINK_CURS
543d522f475Smrg    Bres(XtNcursorBlink, XtCCursorBlink, screen.cursor_blink, False),
544d522f475Smrg#endif
5452eaa94a1Schristos    Bres(XtNcursorUnderline, XtCCursorUnderline, screen.cursor_underline, False),
546d522f475Smrg
547d522f475Smrg#if OPT_BLINK_TEXT
548d522f475Smrg    Bres(XtNshowBlinkAsBold, XtCCursorBlink, screen.blink_as_bold, DEFBLINKASBOLD),
549d522f475Smrg#endif
550d522f475Smrg
551d522f475Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
552d522f475Smrg    Ires(XtNcursorOnTime, XtCCursorOnTime, screen.blink_on, 600),
553d522f475Smrg    Ires(XtNcursorOffTime, XtCCursorOffTime, screen.blink_off, 300),
554d522f475Smrg#endif
555d522f475Smrg
556d522f475Smrg#if OPT_BOX_CHARS
557d522f475Smrg    Bres(XtNforceBoxChars, XtCForceBoxChars, screen.force_box_chars, False),
55820d2c4d2Smrg    Bres(XtNforcePackedFont, XtCForcePackedFont, screen.force_packed, True),
559d522f475Smrg    Bres(XtNshowMissingGlyphs, XtCShowMissingGlyphs, screen.force_all_chars, False),
560e0a2b6dfSmrg    Bres(XtNassumeAllChars, XtCAssumeAllChars, screen.assume_all_chars, True),
561d522f475Smrg#endif
562d522f475Smrg
563d522f475Smrg#if OPT_BROKEN_OSC
564d522f475Smrg    Bres(XtNbrokenLinuxOSC, XtCBrokenLinuxOSC, screen.brokenLinuxOSC, True),
565d522f475Smrg#endif
566d522f475Smrg
567d522f475Smrg#if OPT_BROKEN_ST
568e39b573cSmrg    Bres(XtNbrokenStringTerm, XtCBrokenStringTerm, screen.brokenStringTerm, False),
569d522f475Smrg#endif
570d522f475Smrg
571d522f475Smrg#if OPT_C1_PRINT
572d522f475Smrg    Bres(XtNallowC1Printable, XtCAllowC1Printable, screen.c1_printable, False),
573d522f475Smrg#endif
574d522f475Smrg
575d522f475Smrg#if OPT_CLIP_BOLD
576d522f475Smrg    Bres(XtNuseClipping, XtCUseClipping, screen.use_clipping, True),
577d522f475Smrg#endif
578d522f475Smrg
579d522f475Smrg#if OPT_DEC_CHRSET
580d522f475Smrg    Bres(XtNfontDoublesize, XtCFontDoublesize, screen.font_doublesize, True),
581d522f475Smrg    Ires(XtNcacheDoublesize, XtCCacheDoublesize, screen.cache_doublesize, NUM_CHRSET),
582d522f475Smrg#endif
583d522f475Smrg
584d522f475Smrg#if OPT_HIGHLIGHT_COLOR
585d522f475Smrg    Tres(XtNhighlightColor, XtCHighlightColor, HIGHLIGHT_BG, XtDefaultForeground),
586d522f475Smrg    Tres(XtNhighlightTextColor, XtCHighlightTextColor, HIGHLIGHT_FG, XtDefaultBackground),
587d522f475Smrg    Bres(XtNhighlightReverse, XtCHighlightReverse, screen.hilite_reverse, True),
588d522f475Smrg    Bres(XtNhighlightColorMode, XtCHighlightColorMode, screen.hilite_color, Maybe),
589d522f475Smrg#endif				/* OPT_HIGHLIGHT_COLOR */
590d522f475Smrg
591d522f475Smrg#if OPT_INPUT_METHOD
592d522f475Smrg    Bres(XtNopenIm, XtCOpenIm, misc.open_im, True),
593d522f475Smrg    Sres(XtNinputMethod, XtCInputMethod, misc.input_method, NULL),
594d522f475Smrg    Sres(XtNpreeditType, XtCPreeditType, misc.preedit_type,
595d522f475Smrg	 "OverTheSpot,Root"),
596956cc18dSsnj    Ires(XtNretryInputMethod, XtCRetryInputMethod, misc.retry_im, 3),
597d522f475Smrg#endif
598d522f475Smrg
599d522f475Smrg#if OPT_ISO_COLORS
600d522f475Smrg    Bres(XtNboldColors, XtCColorMode, screen.boldColors, True),
601d522f475Smrg    Ires(XtNveryBoldColors, XtCVeryBoldColors, screen.veryBoldColors, 0),
602d522f475Smrg    Bres(XtNcolorMode, XtCColorMode, screen.colorMode, DFT_COLORMODE),
603d522f475Smrg
604d522f475Smrg    Bres(XtNcolorAttrMode, XtCColorAttrMode, screen.colorAttrMode, False),
605d522f475Smrg    Bres(XtNcolorBDMode, XtCColorAttrMode, screen.colorBDMode, False),
606d522f475Smrg    Bres(XtNcolorBLMode, XtCColorAttrMode, screen.colorBLMode, False),
607d522f475Smrg    Bres(XtNcolorRVMode, XtCColorAttrMode, screen.colorRVMode, False),
608d522f475Smrg    Bres(XtNcolorULMode, XtCColorAttrMode, screen.colorULMode, False),
609d522f475Smrg    Bres(XtNitalicULMode, XtCColorAttrMode, screen.italicULMode, False),
610d522f475Smrg
611d522f475Smrg    COLOR_RES("0", screen.Acolors[COLOR_0], DFT_COLOR("black")),
612d522f475Smrg    COLOR_RES("1", screen.Acolors[COLOR_1], DFT_COLOR("red3")),
613d522f475Smrg    COLOR_RES("2", screen.Acolors[COLOR_2], DFT_COLOR("green3")),
614d522f475Smrg    COLOR_RES("3", screen.Acolors[COLOR_3], DFT_COLOR("yellow3")),
615d522f475Smrg    COLOR_RES("4", screen.Acolors[COLOR_4], DFT_COLOR(DEF_COLOR4)),
616d522f475Smrg    COLOR_RES("5", screen.Acolors[COLOR_5], DFT_COLOR("magenta3")),
617d522f475Smrg    COLOR_RES("6", screen.Acolors[COLOR_6], DFT_COLOR("cyan3")),
618d522f475Smrg    COLOR_RES("7", screen.Acolors[COLOR_7], DFT_COLOR("gray90")),
619d522f475Smrg    COLOR_RES("8", screen.Acolors[COLOR_8], DFT_COLOR("gray50")),
620d522f475Smrg    COLOR_RES("9", screen.Acolors[COLOR_9], DFT_COLOR("red")),
621d522f475Smrg    COLOR_RES("10", screen.Acolors[COLOR_10], DFT_COLOR("green")),
622d522f475Smrg    COLOR_RES("11", screen.Acolors[COLOR_11], DFT_COLOR("yellow")),
623d522f475Smrg    COLOR_RES("12", screen.Acolors[COLOR_12], DFT_COLOR(DEF_COLOR12)),
624d522f475Smrg    COLOR_RES("13", screen.Acolors[COLOR_13], DFT_COLOR("magenta")),
625d522f475Smrg    COLOR_RES("14", screen.Acolors[COLOR_14], DFT_COLOR("cyan")),
626d522f475Smrg    COLOR_RES("15", screen.Acolors[COLOR_15], DFT_COLOR("white")),
627d522f475Smrg    COLOR_RES("BD", screen.Acolors[COLOR_BD], DFT_COLOR(XtDefaultForeground)),
628d522f475Smrg    COLOR_RES("BL", screen.Acolors[COLOR_BL], DFT_COLOR(XtDefaultForeground)),
629d522f475Smrg    COLOR_RES("UL", screen.Acolors[COLOR_UL], DFT_COLOR(XtDefaultForeground)),
630d522f475Smrg    COLOR_RES("RV", screen.Acolors[COLOR_RV], DFT_COLOR(XtDefaultForeground)),
631d522f475Smrg
632d522f475Smrg#if !OPT_COLOR_RES2
633d522f475Smrg#if OPT_256_COLORS
634d522f475Smrg# include <256colres.h>
635d522f475Smrg#elif OPT_88_COLORS
636d522f475Smrg# include <88colres.h>
637d522f475Smrg#endif
638d522f475Smrg#endif				/* !OPT_COLOR_RES2 */
639d522f475Smrg
640d522f475Smrg#endif				/* OPT_ISO_COLORS */
641d522f475Smrg
64220d2c4d2Smrg    CLICK_RES("2", screen.onClick[1], "word"),
64320d2c4d2Smrg    CLICK_RES("3", screen.onClick[2], "line"),
64420d2c4d2Smrg    CLICK_RES("4", screen.onClick[3], 0),
64520d2c4d2Smrg    CLICK_RES("5", screen.onClick[4], 0),
64620d2c4d2Smrg
647d522f475Smrg#if OPT_MOD_FKEYS
6480bd37d32Smrg    Ires(XtNmodifyKeyboard, XtCModifyKeyboard,
6490bd37d32Smrg	 keyboard.modify_1st.allow_keys, 0),
650d522f475Smrg    Ires(XtNmodifyCursorKeys, XtCModifyCursorKeys,
651d522f475Smrg	 keyboard.modify_1st.cursor_keys, 2),
652d522f475Smrg    Ires(XtNmodifyFunctionKeys, XtCModifyFunctionKeys,
653d522f475Smrg	 keyboard.modify_1st.function_keys, 2),
654d522f475Smrg    Ires(XtNmodifyKeypadKeys, XtCModifyKeypadKeys,
655d522f475Smrg	 keyboard.modify_1st.keypad_keys, 0),
656d522f475Smrg    Ires(XtNmodifyOtherKeys, XtCModifyOtherKeys,
657d522f475Smrg	 keyboard.modify_1st.other_keys, 0),
658d522f475Smrg    Ires(XtNmodifyStringKeys, XtCModifyStringKeys,
659d522f475Smrg	 keyboard.modify_1st.string_keys, 0),
660d522f475Smrg    Ires(XtNformatOtherKeys, XtCFormatOtherKeys,
661d522f475Smrg	 keyboard.format_keys, 0),
662d522f475Smrg#endif
663d522f475Smrg
664d522f475Smrg#if OPT_NUM_LOCK
665d522f475Smrg    Bres(XtNalwaysUseMods, XtCAlwaysUseMods, misc.alwaysUseMods, False),
666d522f475Smrg    Bres(XtNnumLock, XtCNumLock, misc.real_NumLock, True),
667d522f475Smrg#endif
668d522f475Smrg
669d522f475Smrg#if OPT_PRINT_COLORS
670e39b573cSmrg    Ires(XtNprintAttributes, XtCPrintAttributes, SPS.print_attributes, 1),
671d522f475Smrg#endif
672d522f475Smrg
673d522f475Smrg#if OPT_SHIFT_FONTS
674d522f475Smrg    Bres(XtNshiftFonts, XtCShiftFonts, misc.shift_fonts, True),
675d522f475Smrg#endif
676d522f475Smrg
677e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
678e0a2b6dfSmrg    Bres(XtNprivateColorRegisters, XtCPrivateColorRegisters,
679e0a2b6dfSmrg	 screen.privatecolorregisters, True),
680e0a2b6dfSmrg    Bres(XtNsixelScrolling, XtCSixelScrolling, screen.sixel_scrolling, False),
681e0a2b6dfSmrg#endif
682e0a2b6dfSmrg
683d522f475Smrg#if OPT_SUNPC_KBD
684d522f475Smrg    Ires(XtNctrlFKeys, XtCCtrlFKeys, misc.ctrl_fkeys, 10),
685d522f475Smrg#endif
686d522f475Smrg
687d522f475Smrg#if OPT_TEK4014
688d522f475Smrg    Bres(XtNtekInhibit, XtCTekInhibit, misc.tekInhibit, False),
689d522f475Smrg    Bres(XtNtekSmall, XtCTekSmall, misc.tekSmall, False),
690d522f475Smrg    Bres(XtNtekStartup, XtCTekStartup, misc.TekEmu, False),
691d522f475Smrg#endif
692d522f475Smrg
693d522f475Smrg#if OPT_TOOLBAR
694d522f475Smrg    Wres(XtNmenuBar, XtCMenuBar, VT100_TB_INFO(menu_bar), 0),
695d522f475Smrg    Ires(XtNmenuHeight, XtCMenuHeight, VT100_TB_INFO(menu_height), 25),
696d522f475Smrg#endif
697d522f475Smrg
698d522f475Smrg#if OPT_WIDE_CHARS
699d522f475Smrg    Bres(XtNcjkWidth, XtCCjkWidth, misc.cjk_width, False),
700d522f475Smrg    Bres(XtNmkWidth, XtCMkWidth, misc.mk_width, False),
7010bd37d32Smrg    Bres(XtNprecompose, XtCPrecompose, screen.normalized_c, True),
702d522f475Smrg    Bres(XtNutf8Latin1, XtCUtf8Latin1, screen.utf8_latin1, False),
703d522f475Smrg    Bres(XtNutf8Title, XtCUtf8Title, screen.utf8_title, False),
704d522f475Smrg    Bres(XtNvt100Graphics, XtCVT100Graphics, screen.vt100_graphics, True),
705d522f475Smrg    Bres(XtNwideChars, XtCWideChars, screen.wide_chars, False),
706d522f475Smrg    Ires(XtNcombiningChars, XtCCombiningChars, screen.max_combining, 2),
707d522f475Smrg    Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 256),
708d522f475Smrg    Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 1024),
709e39b573cSmrg    Sres(XtNutf8, XtCUtf8, screen.utf8_mode_s, "default"),
710e39b573cSmrg    Sres(XtNutf8Fonts, XtCUtf8Fonts, screen.utf8_fonts_s, "default"),
711d522f475Smrg    Sres(XtNwideBoldFont, XtCWideBoldFont, misc.default_font.f_wb, DEFWIDEBOLDFONT),
712d522f475Smrg    Sres(XtNwideFont, XtCWideFont, misc.default_font.f_w, DEFWIDEFONT),
713956cc18dSsnj    Sres(XtNutf8SelectTypes, XtCUtf8SelectTypes, screen.utf8_select_types, NULL),
714d522f475Smrg#endif
715d522f475Smrg
716d522f475Smrg#if OPT_LUIT_PROG
717d522f475Smrg    Sres(XtNlocale, XtCLocale, misc.locale_str, "medium"),
718d522f475Smrg    Sres(XtNlocaleFilter, XtCLocaleFilter, misc.localefilter, DEFLOCALEFILTER),
719d522f475Smrg#endif
720d522f475Smrg
721d522f475Smrg#if OPT_INPUT_METHOD
722d522f475Smrg    Sres(XtNximFont, XtCXimFont, misc.f_x, DEFXIMFONT),
723d522f475Smrg#endif
724d522f475Smrg
72520d2c4d2Smrg#if OPT_SCROLL_LOCK
72620d2c4d2Smrg    Bres(XtNallowScrollLock, XtCAllowScrollLock, screen.allowScrollLock0, False),
72720d2c4d2Smrg#endif
72820d2c4d2Smrg
729d522f475Smrg#if OPT_XMC_GLITCH
730d522f475Smrg    Bres(XtNxmcInline, XtCXmcInline, screen.xmc_inline, False),
731d522f475Smrg    Bres(XtNxmcMoveSGR, XtCXmcMoveSGR, screen.move_sgr_ok, True),
732d522f475Smrg    Ires(XtNxmcAttributes, XtCXmcAttributes, screen.xmc_attributes, 1),
733d522f475Smrg    Ires(XtNxmcGlitch, XtCXmcGlitch, screen.xmc_glitch, 0),
734d522f475Smrg#endif
735d522f475Smrg
736d522f475Smrg#ifdef SCROLLBAR_RIGHT
737d522f475Smrg    Bres(XtNrightScrollBar, XtCRightScrollBar, misc.useRight, False),
738d522f475Smrg#endif
739d522f475Smrg
740d522f475Smrg#if OPT_RENDERFONT
741d522f475Smrg#define RES_FACESIZE(n) Dres(XtNfaceSize #n, XtCFaceSize #n, misc.face_size[n], "0.0")
742d522f475Smrg    RES_FACESIZE(1),
743d522f475Smrg    RES_FACESIZE(2),
744d522f475Smrg    RES_FACESIZE(3),
745d522f475Smrg    RES_FACESIZE(4),
746d522f475Smrg    RES_FACESIZE(5),
747d522f475Smrg    RES_FACESIZE(6),
748d522f475Smrg    Dres(XtNfaceSize, XtCFaceSize, misc.face_size[0], DEFFACESIZE),
749d522f475Smrg    Sres(XtNfaceName, XtCFaceName, misc.face_name, DEFFACENAME),
750d522f475Smrg    Sres(XtNfaceNameDoublesize, XtCFaceNameDoublesize, misc.face_wide_name, DEFFACENAME),
75120d2c4d2Smrg    Sres(XtNrenderFont, XtCRenderFont, misc.render_font_s, "default"),
752d522f475Smrg#endif
753d522f475Smrg};
754d522f475Smrg
755d522f475Smrgstatic Boolean VTSetValues(Widget cur, Widget request, Widget new_arg,
756d522f475Smrg			   ArgList args, Cardinal *num_args);
757d522f475Smrgstatic void VTClassInit(void);
758d522f475Smrgstatic void VTDestroy(Widget w);
759d522f475Smrgstatic void VTExpose(Widget w, XEvent * event, Region region);
760d522f475Smrgstatic void VTInitialize(Widget wrequest, Widget new_arg, ArgList args,
761d522f475Smrg			 Cardinal *num_args);
762d522f475Smrgstatic void VTRealize(Widget w, XtValueMask * valuemask,
763d522f475Smrg		      XSetWindowAttributes * values);
764d522f475Smrgstatic void VTResize(Widget w);
765d522f475Smrg
766d522f475Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
767956cc18dSsnjstatic void VTInitI18N(XtermWidget);
768d522f475Smrg#endif
769d522f475Smrg
770d522f475Smrg#ifdef VMS
771d522f475Smrgglobaldef {
772d522f475Smrg    "xtermclassrec"
773d522f475Smrg} noshare
774d522f475Smrg
775d522f475Smrg#else
776d522f475Smrgstatic
777d522f475Smrg#endif				/* VMS */
778d522f475SmrgWidgetClassRec xtermClassRec =
779d522f475Smrg{
780d522f475Smrg    {
78120d2c4d2Smrg	/* core_class fields */
78220d2c4d2Smrg	(WidgetClass) & widgetClassRec,		/* superclass   */
783d522f475Smrg	"VT100",		/* class_name                   */
784d522f475Smrg	sizeof(XtermWidgetRec),	/* widget_size                  */
785d522f475Smrg	VTClassInit,		/* class_initialize             */
786d522f475Smrg	NULL,			/* class_part_initialize        */
787d522f475Smrg	False,			/* class_inited                 */
788d522f475Smrg	VTInitialize,		/* initialize                   */
789d522f475Smrg	NULL,			/* initialize_hook              */
790d522f475Smrg	VTRealize,		/* realize                      */
791d522f475Smrg	actionsList,		/* actions                      */
792d522f475Smrg	XtNumber(actionsList),	/* num_actions                  */
79320d2c4d2Smrg	xterm_resources,	/* resources                    */
79420d2c4d2Smrg	XtNumber(xterm_resources),	/* num_resources        */
795d522f475Smrg	NULLQUARK,		/* xrm_class                    */
796d522f475Smrg	True,			/* compress_motion              */
797d522f475Smrg	False,			/* compress_exposure            */
798d522f475Smrg	True,			/* compress_enterleave          */
799d522f475Smrg	False,			/* visible_interest             */
800d522f475Smrg	VTDestroy,		/* destroy                      */
801d522f475Smrg	VTResize,		/* resize                       */
802d522f475Smrg	VTExpose,		/* expose                       */
803d522f475Smrg	VTSetValues,		/* set_values                   */
804d522f475Smrg	NULL,			/* set_values_hook              */
805d522f475Smrg	XtInheritSetValuesAlmost,	/* set_values_almost    */
806d522f475Smrg	NULL,			/* get_values_hook              */
807d522f475Smrg	NULL,			/* accept_focus                 */
808d522f475Smrg	XtVersion,		/* version                      */
809d522f475Smrg	NULL,			/* callback_offsets             */
810a1f3da82Smrg	0,			/* tm_table                     */
811d522f475Smrg	XtInheritQueryGeometry,	/* query_geometry               */
812d522f475Smrg	XtInheritDisplayAccelerator,	/* display_accelerator  */
813d522f475Smrg	NULL			/* extension                    */
814d522f475Smrg    }
815d522f475Smrg};
816d522f475Smrg
817d522f475Smrg#ifdef VMS
818d522f475Smrgglobaldef {
819d522f475Smrg    "xtermwidgetclass"
820d522f475Smrg}
821d522f475Smrgnoshare
822d522f475Smrg#endif /* VMS */
823d522f475SmrgWidgetClass xtermWidgetClass = (WidgetClass) & xtermClassRec;
824d522f475Smrg
825d522f475Smrg/*
826d522f475Smrg * Add input-actions for widgets that are overlooked (scrollbar and toolbar):
827d522f475Smrg *
828d522f475Smrg *	a) Sometimes the scrollbar passes through translations, sometimes it
829d522f475Smrg *	   doesn't.  We add the KeyPress translations here, just to be sure.
830d522f475Smrg *	b) In the normal (non-toolbar) configuration, the xterm widget covers
831d522f475Smrg *	   almost all of the window.  With a toolbar, there's a relatively
832d522f475Smrg *	   large area that the user would expect to enter keystrokes since the
833d522f475Smrg *	   program can get the focus.
834d522f475Smrg */
835d522f475Smrgvoid
836d522f475SmrgxtermAddInput(Widget w)
837d522f475Smrg{
838d522f475Smrg    /* *INDENT-OFF* */
839d522f475Smrg    XtActionsRec input_actions[] = {
840d522f475Smrg	{ "insert",		    HandleKeyPressed }, /* alias */
841d522f475Smrg	{ "insert-eight-bit",	    HandleEightBitKeyPressed },
842d522f475Smrg	{ "insert-seven-bit",	    HandleKeyPressed },
843d522f475Smrg	{ "secure",		    HandleSecure },
844d522f475Smrg	{ "string",		    HandleStringEvent },
845d522f475Smrg	{ "scroll-back",	    HandleScrollBack },
846d522f475Smrg	{ "scroll-forw",	    HandleScrollForward },
847d522f475Smrg	{ "select-cursor-end",	    HandleKeyboardSelectEnd },
848d522f475Smrg	{ "select-cursor-extend",   HandleKeyboardSelectExtend },
849d522f475Smrg	{ "select-cursor-start",    HandleKeyboardSelectStart },
850d522f475Smrg	{ "insert-selection",	    HandleInsertSelection },
851d522f475Smrg	{ "select-start",	    HandleSelectStart },
852d522f475Smrg	{ "select-extend",	    HandleSelectExtend },
853d522f475Smrg	{ "start-extend",	    HandleStartExtend },
854d522f475Smrg	{ "select-end",		    HandleSelectEnd },
855d522f475Smrg	{ "clear-saved-lines",	    HandleClearSavedLines },
856d522f475Smrg	{ "popup-menu",		    HandlePopupMenu },
857d522f475Smrg	{ "bell",		    HandleBell },
858d522f475Smrg	{ "ignore",		    HandleIgnore },
859d522f475Smrg#if OPT_DABBREV
860d522f475Smrg	{ "dabbrev-expand",	    HandleDabbrevExpand },
861d522f475Smrg#endif
862a1f3da82Smrg#if OPT_MAXIMIZE
863a1f3da82Smrg	{ "fullscreen",		    HandleFullscreen },
864a1f3da82Smrg#endif
86520d2c4d2Smrg#if OPT_SCROLL_LOCK
86620d2c4d2Smrg	{ "scroll-lock",	    HandleScrollLock },
86720d2c4d2Smrg#endif
868d522f475Smrg#if OPT_SHIFT_FONTS
869d522f475Smrg	{ "larger-vt-font",	    HandleLargerFont },
870d522f475Smrg	{ "smaller-vt-font",	    HandleSmallerFont },
871d522f475Smrg#endif
872d522f475Smrg    };
873d522f475Smrg    /* *INDENT-ON* */
874d522f475Smrg
875956cc18dSsnj    TRACE_TRANS("BEFORE", w);
876d522f475Smrg    XtAppAddActions(app_con, input_actions, XtNumber(input_actions));
877d522f475Smrg    XtAugmentTranslations(w, XtParseTranslationTable(defaultTranslations));
878956cc18dSsnj    TRACE_TRANS("AFTER:", w);
879d522f475Smrg
880d522f475Smrg#if OPT_EXTRA_PASTE
881d522f475Smrg    if (term && term->keyboard.extra_translations)
882d522f475Smrg	XtOverrideTranslations((Widget) term, XtParseTranslationTable(term->keyboard.extra_translations));
883d522f475Smrg#endif
884d522f475Smrg}
885d522f475Smrg
886d522f475Smrg#if OPT_ISO_COLORS
887956cc18dSsnj#ifdef EXP_BOGUS_FG
888956cc18dSsnjstatic Bool
889e0a2b6dfSmrgCheckBogusForeground(TScreen *screen, const char *tag)
890956cc18dSsnj{
891956cc18dSsnj    int row = -1, col = -1, pass;
892956cc18dSsnj    Bool isClear = True;
893956cc18dSsnj
894956cc18dSsnj    (void) tag;
895956cc18dSsnj    for (pass = 0; pass < 2; ++pass) {
896956cc18dSsnj	row = screen->cur_row;
897956cc18dSsnj	for (; isClear && (row <= screen->max_row); ++row) {
898956cc18dSsnj	    LineData *ld = getLineData(screen, row)->;
89920d2c4d2Smrg
90020d2c4d2Smrg	    if (ld != 0) {
90120d2c4d2Smrg		Char *attribs = ld->attribs;
90220d2c4d2Smrg
90320d2c4d2Smrg		col = (row == screen->cur_row) ? screen->cur_col : 0;
90420d2c4d2Smrg		for (; isClear && (col <= screen->max_col); ++col) {
90520d2c4d2Smrg		    unsigned flags = attribs[col];
90620d2c4d2Smrg		    if (pass) {
90720d2c4d2Smrg			flags &= ~FG_COLOR;
90820d2c4d2Smrg			attribs[col] = (Char) flags;
90920d2c4d2Smrg		    } else if ((flags & BG_COLOR)) {
91020d2c4d2Smrg			isClear = False;
91120d2c4d2Smrg		    } else if ((flags & FG_COLOR)) {
91220d2c4d2Smrg			unsigned ch = ld->charData[col];
91320d2c4d2Smrg			isClear = ((ch == ' ') || (ch == 0));
91420d2c4d2Smrg		    } else {
91520d2c4d2Smrg			isClear = False;
91620d2c4d2Smrg		    }
917956cc18dSsnj		}
918956cc18dSsnj	    }
919956cc18dSsnj	}
920956cc18dSsnj    }
921956cc18dSsnj    TRACE(("%s checked %d,%d to %d,%d %s pass %d\n",
922956cc18dSsnj	   tag, screen->cur_row, screen->cur_col,
923956cc18dSsnj	   row, col,
924956cc18dSsnj	   isClear && pass ? "cleared" : "unchanged",
925956cc18dSsnj	   pass));
926956cc18dSsnj
927956cc18dSsnj    return isClear;
928956cc18dSsnj}
929956cc18dSsnj#endif
930956cc18dSsnj
931d522f475Smrg/*
932d522f475Smrg * The terminal's foreground and background colors are set via two mechanisms:
933d522f475Smrg *	text (cur_foreground, cur_background values that are passed down to
934d522f475Smrg *		XDrawImageString and XDrawString)
935d522f475Smrg *	area (X11 graphics context used in XClearArea and XFillRectangle)
936d522f475Smrg */
937d522f475Smrgvoid
938d522f475SmrgSGR_Foreground(XtermWidget xw, int color)
939d522f475Smrg{
94020d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
941d522f475Smrg    Pixel fg;
942d522f475Smrg
943d522f475Smrg    if (color >= 0) {
94420d2c4d2Smrg	UIntSet(xw->flags, FG_COLOR);
945d522f475Smrg    } else {
94620d2c4d2Smrg	UIntClr(xw->flags, FG_COLOR);
947d522f475Smrg    }
948d522f475Smrg    fg = getXtermForeground(xw, xw->flags, color);
949d522f475Smrg    xw->cur_foreground = color;
950d522f475Smrg
951d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcNorm, fg);
952d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcNormReverse, fg);
953d522f475Smrg
954d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcBold, fg);
955d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcBoldReverse, fg);
956956cc18dSsnj
957956cc18dSsnj#ifdef EXP_BOGUS_FG
958956cc18dSsnj    /*
959956cc18dSsnj     * If we've just turned off the foreground color, check for blank cells
960956cc18dSsnj     * which have no background color, but do have foreground color.  This
961956cc18dSsnj     * could happen due to setting the foreground color just before scrolling.
962956cc18dSsnj     *
963956cc18dSsnj     * Those cells look uncolored, but will confuse ShowCursor(), which looks
96420d2c4d2Smrg     * for the colors in the current cell, and will see the foreground color.
965956cc18dSsnj     * In that case, remove the foreground color from the blank cells.
966956cc18dSsnj     */
967956cc18dSsnj    if (color < 0) {
968956cc18dSsnj	CheckBogusForeground(screen, "SGR_Foreground");
969956cc18dSsnj    }
970956cc18dSsnj#endif
971d522f475Smrg}
972d522f475Smrg
973d522f475Smrgvoid
974d522f475SmrgSGR_Background(XtermWidget xw, int color)
975d522f475Smrg{
97620d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
977d522f475Smrg    Pixel bg;
978d522f475Smrg
979d522f475Smrg    /*
980d522f475Smrg     * An indexing operation may have set screen->scroll_amt, which would
981d522f475Smrg     * normally result in calling FlushScroll() in WriteText().  However,
982d522f475Smrg     * if we're changing the background color now, then the new value
983d522f475Smrg     * should not apply to the pending blank lines.
984d522f475Smrg     */
985d522f475Smrg    if (screen->scroll_amt && (color != xw->cur_background))
986d522f475Smrg	FlushScroll(xw);
987d522f475Smrg
988d522f475Smrg    if (color >= 0) {
98920d2c4d2Smrg	UIntSet(xw->flags, BG_COLOR);
990d522f475Smrg    } else {
99120d2c4d2Smrg	UIntClr(xw->flags, BG_COLOR);
992d522f475Smrg    }
993d522f475Smrg    bg = getXtermBackground(xw, xw->flags, color);
994d522f475Smrg    xw->cur_background = color;
995d522f475Smrg
996d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcNorm, bg);
997d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcNormReverse, bg);
998d522f475Smrg
999d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcBold, bg);
1000d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcBoldReverse, bg);
1001d522f475Smrg}
1002d522f475Smrg
1003d522f475Smrg/* Invoked after updating bold/underline flags, computes the extended color
1004d522f475Smrg * index to use for foreground.  (See also 'extract_fg()').
1005d522f475Smrg */
1006d522f475Smrgstatic void
1007d522f475SmrgsetExtendedFG(XtermWidget xw)
1008d522f475Smrg{
1009d522f475Smrg    int fg = xw->sgr_foreground;
1010d522f475Smrg
101120d2c4d2Smrg    if (TScreenOf(xw)->colorAttrMode
1012d522f475Smrg	|| (fg < 0)) {
101320d2c4d2Smrg	fg = MapToColorMode(fg, TScreenOf(xw), xw->flags);
1014d522f475Smrg    }
1015d522f475Smrg
1016d522f475Smrg    /* This implements the IBM PC-style convention of 8-colors, with one
1017d522f475Smrg     * bit for bold, thus mapping the 0-7 codes to 8-15.  It won't make
1018d522f475Smrg     * much sense for 16-color applications, but we keep it to retain
1019d522f475Smrg     * compatiblity with ANSI-color applications.
1020d522f475Smrg     */
1021d522f475Smrg#if OPT_PC_COLORS		/* XXXJTL should be settable at runtime (resource or OSC?) */
102220d2c4d2Smrg    if (TScreenOf(xw)->boldColors
1023d522f475Smrg	&& (!xw->sgr_extended)
1024d522f475Smrg	&& (fg >= 0)
1025d522f475Smrg	&& (fg < 8)
1026d522f475Smrg	&& (xw->flags & BOLD))
1027d522f475Smrg	fg |= 8;
1028d522f475Smrg#endif
1029d522f475Smrg
1030d522f475Smrg    SGR_Foreground(xw, fg);
1031d522f475Smrg}
1032d522f475Smrg
1033d522f475Smrg/* Invoked after updating inverse flag, computes the extended color
1034d522f475Smrg * index to use for background.  (See also 'extract_bg()').
1035d522f475Smrg */
1036d522f475Smrgstatic void
1037d522f475SmrgsetExtendedBG(XtermWidget xw)
1038d522f475Smrg{
1039d522f475Smrg    int bg = xw->sgr_background;
1040d522f475Smrg
104120d2c4d2Smrg    if (TScreenOf(xw)->colorAttrMode
1042d522f475Smrg	|| (bg < 0)) {
104320d2c4d2Smrg	if (TScreenOf(xw)->colorRVMode && (xw->flags & INVERSE))
1044d522f475Smrg	    bg = COLOR_RV;
1045d522f475Smrg    }
1046d522f475Smrg
1047d522f475Smrg    SGR_Background(xw, bg);
1048d522f475Smrg}
1049d522f475Smrg
1050d522f475Smrgstatic void
1051d522f475Smrgreset_SGR_Foreground(XtermWidget xw)
1052d522f475Smrg{
1053d522f475Smrg    xw->sgr_foreground = -1;
1054d522f475Smrg    xw->sgr_extended = False;
1055d522f475Smrg    setExtendedFG(xw);
1056d522f475Smrg}
1057d522f475Smrg
1058d522f475Smrgstatic void
1059d522f475Smrgreset_SGR_Background(XtermWidget xw)
1060d522f475Smrg{
1061d522f475Smrg    xw->sgr_background = -1;
1062d522f475Smrg    setExtendedBG(xw);
1063d522f475Smrg}
1064d522f475Smrg
1065d522f475Smrgstatic void
1066d522f475Smrgreset_SGR_Colors(XtermWidget xw)
1067d522f475Smrg{
1068d522f475Smrg    reset_SGR_Foreground(xw);
1069d522f475Smrg    reset_SGR_Background(xw);
1070d522f475Smrg}
1071d522f475Smrg#endif /* OPT_ISO_COLORS */
1072d522f475Smrg
1073d522f475Smrgvoid
1074e0a2b6dfSmrgresetCharsets(TScreen *screen)
1075d522f475Smrg{
1076d522f475Smrg    TRACE(("resetCharsets\n"));
1077d522f475Smrg
1078e0a2b6dfSmrg    screen->gsets[0] = nrc_ASCII;
1079e0a2b6dfSmrg    screen->gsets[1] = nrc_ASCII;
1080e0a2b6dfSmrg    screen->gsets[2] = nrc_ASCII;
1081e0a2b6dfSmrg    screen->gsets[3] = nrc_ASCII;
1082d522f475Smrg
1083d522f475Smrg    screen->curgl = 0;		/* G0 => GL.            */
1084d522f475Smrg    screen->curgr = 2;		/* G2 => GR.            */
1085d522f475Smrg    screen->curss = 0;		/* No single shift.     */
1086d522f475Smrg
1087d522f475Smrg#if OPT_VT52_MODE
1088d522f475Smrg    if (screen->vtXX_level == 0)
1089d522f475Smrg	screen->gsets[1] = '0';	/* Graphics             */
1090d522f475Smrg#endif
1091d522f475Smrg}
1092d522f475Smrg
1093e0a2b6dfSmrgstatic void
1094e0a2b6dfSmrgmodified_DECNRCM(XtermWidget xw)
1095e0a2b6dfSmrg{
1096e0a2b6dfSmrg#if OPT_WIDE_CHARS
1097e0a2b6dfSmrg    TScreen *screen = TScreenOf(xw);
1098e0a2b6dfSmrg    if (screen->wide_chars && (screen->utf8_mode || screen->utf8_nrc_mode)) {
1099e0a2b6dfSmrg	int enabled = ((xw->flags & NATIONAL) != 0);
1100e0a2b6dfSmrg	int modefix;
1101e0a2b6dfSmrg	EXCHANGE(screen->utf8_nrc_mode, screen->utf8_mode, modefix);
1102e0a2b6dfSmrg	switchPtyData(screen, !enabled);
1103e0a2b6dfSmrg	TRACE(("UTF8 mode temporarily %s\n", enabled ? "ON" : "OFF"));
1104e0a2b6dfSmrg    }
1105e0a2b6dfSmrg#endif
1106e0a2b6dfSmrg}
1107e0a2b6dfSmrg
1108d522f475Smrg/*
1109d522f475Smrg * VT300 and up support three ANSI conformance levels, defined according to
1110d522f475Smrg * the dpANSI X3.134.1 standard.  DEC's manuals equate levels 1 and 2, and
1111d522f475Smrg * are unclear.  This code is written based on the manuals.
1112d522f475Smrg */
1113d522f475Smrgstatic void
1114e0a2b6dfSmrgset_ansi_conformance(TScreen *screen, int level)
1115d522f475Smrg{
11160bd37d32Smrg    TRACE(("set_ansi_conformance(%d) dec_level %d:%d, ansi_level %d\n",
1117d522f475Smrg	   level,
11180bd37d32Smrg	   screen->vtXX_level * 100,
1119d522f475Smrg	   screen->terminal_id,
1120d522f475Smrg	   screen->ansi_level));
1121d522f475Smrg    if (screen->vtXX_level >= 3) {
1122d522f475Smrg	switch (screen->ansi_level = level) {
1123d522f475Smrg	case 1:
1124d522f475Smrg	    /* FALLTHRU */
1125d522f475Smrg	case 2:
1126e0a2b6dfSmrg	    screen->gsets[0] = nrc_ASCII;	/* G0 is ASCII */
1127e0a2b6dfSmrg	    screen->gsets[1] = nrc_ASCII;	/* G1 is ISO Latin-1 */
1128d522f475Smrg	    screen->curgl = 0;
1129d522f475Smrg	    screen->curgr = 1;
1130d522f475Smrg	    break;
1131d522f475Smrg	case 3:
1132e0a2b6dfSmrg	    screen->gsets[0] = nrc_ASCII;	/* G0 is ASCII */
1133d522f475Smrg	    screen->curgl = 0;
1134d522f475Smrg	    break;
1135d522f475Smrg	}
1136d522f475Smrg    }
1137d522f475Smrg}
1138d522f475Smrg
1139d522f475Smrg/*
1140d522f475Smrg * Set scrolling margins.  VTxxx terminals require that the top/bottom are
1141d522f475Smrg * different, so we have at least two lines in the scrolling region.
1142d522f475Smrg */
1143d522f475Smrgvoid
1144e0a2b6dfSmrgset_tb_margins(TScreen *screen, int top, int bottom)
1145d522f475Smrg{
1146d522f475Smrg    TRACE(("set_tb_margins %d..%d, prior %d..%d\n",
1147d522f475Smrg	   top, bottom,
1148d522f475Smrg	   screen->top_marg,
1149d522f475Smrg	   screen->bot_marg));
1150d522f475Smrg    if (bottom > top) {
1151d522f475Smrg	screen->top_marg = top;
1152d522f475Smrg	screen->bot_marg = bottom;
1153d522f475Smrg    }
1154d522f475Smrg    if (screen->top_marg > screen->max_row)
1155d522f475Smrg	screen->top_marg = screen->max_row;
1156d522f475Smrg    if (screen->bot_marg > screen->max_row)
1157d522f475Smrg	screen->bot_marg = screen->max_row;
1158d522f475Smrg}
1159d522f475Smrg
11600bd37d32Smrgvoid
1161e0a2b6dfSmrgset_lr_margins(TScreen *screen, int left, int right)
11620bd37d32Smrg{
11630bd37d32Smrg    TRACE(("set_lr_margins %d..%d, prior %d..%d\n",
11640bd37d32Smrg	   left, right,
11650bd37d32Smrg	   screen->lft_marg,
11660bd37d32Smrg	   screen->rgt_marg));
11670bd37d32Smrg    if (right > left) {
11680bd37d32Smrg	screen->lft_marg = left;
11690bd37d32Smrg	screen->rgt_marg = right;
11700bd37d32Smrg    }
11710bd37d32Smrg    if (screen->lft_marg > screen->max_col)
11720bd37d32Smrg	screen->lft_marg = screen->max_col;
11730bd37d32Smrg    if (screen->rgt_marg > screen->max_col)
11740bd37d32Smrg	screen->rgt_marg = screen->max_col;
11750bd37d32Smrg}
11760bd37d32Smrg
11770bd37d32Smrg#define reset_tb_margins(screen) set_tb_margins(screen, 0, screen->max_row)
11780bd37d32Smrg#define reset_lr_margins(screen) set_lr_margins(screen, 0, screen->max_col)
11790bd37d32Smrg
11800bd37d32Smrgstatic void
1181e0a2b6dfSmrgreset_margins(TScreen *screen)
11820bd37d32Smrg{
11830bd37d32Smrg    reset_tb_margins(screen);
11840bd37d32Smrg    reset_lr_margins(screen);
11850bd37d32Smrg}
11860bd37d32Smrg
1187d522f475Smrgvoid
1188e0a2b6dfSmrgset_max_col(TScreen *screen, int cols)
1189d522f475Smrg{
1190d522f475Smrg    TRACE(("set_max_col %d, prior %d\n", cols, screen->max_col));
1191d522f475Smrg    if (cols < 0)
1192d522f475Smrg	cols = 0;
1193d522f475Smrg    screen->max_col = cols;
1194d522f475Smrg}
1195d522f475Smrg
1196d522f475Smrgvoid
1197e0a2b6dfSmrgset_max_row(TScreen *screen, int rows)
1198d522f475Smrg{
1199d522f475Smrg    TRACE(("set_max_row %d, prior %d\n", rows, screen->max_row));
1200d522f475Smrg    if (rows < 0)
1201d522f475Smrg	rows = 0;
1202d522f475Smrg    screen->max_row = rows;
1203d522f475Smrg}
1204d522f475Smrg
1205d522f475Smrg#if OPT_MOD_FKEYS
1206d522f475Smrgstatic void
1207d522f475Smrgset_mod_fkeys(XtermWidget xw, int which, int what, Bool enabled)
1208d522f475Smrg{
1209d522f475Smrg#define SET_MOD_FKEYS(field) \
1210d522f475Smrg    xw->keyboard.modify_now.field = ((what == DEFAULT) && enabled) \
1211d522f475Smrg				     ? xw->keyboard.modify_1st.field \
1212d522f475Smrg				     : what; \
1213d522f475Smrg    TRACE(("set modify_now.%s to %d\n", #field, \
1214d522f475Smrg	   xw->keyboard.modify_now.field));
1215d522f475Smrg
1216d522f475Smrg    switch (which) {
12170bd37d32Smrg    case 0:
12180bd37d32Smrg	SET_MOD_FKEYS(allow_keys);
12190bd37d32Smrg	break;
1220d522f475Smrg    case 1:
1221d522f475Smrg	SET_MOD_FKEYS(cursor_keys);
1222d522f475Smrg	break;
1223d522f475Smrg    case 2:
1224d522f475Smrg	SET_MOD_FKEYS(function_keys);
1225d522f475Smrg	break;
1226d522f475Smrg    case 3:
1227d522f475Smrg	SET_MOD_FKEYS(keypad_keys);
1228d522f475Smrg	break;
1229d522f475Smrg    case 4:
1230d522f475Smrg	SET_MOD_FKEYS(other_keys);
1231d522f475Smrg	break;
1232d522f475Smrg    case 5:
1233d522f475Smrg	SET_MOD_FKEYS(string_keys);
1234d522f475Smrg	break;
1235d522f475Smrg    }
1236d522f475Smrg}
1237d522f475Smrg#endif /* OPT_MOD_FKEYS */
1238d522f475Smrg
1239d522f475Smrg#if OPT_TRACE
1240d522f475Smrg#define WHICH_TABLE(name) if (table == name) result = #name
124120d2c4d2Smrgstatic const char *
1242d522f475Smrgwhich_table(Const PARSE_T * table)
1243d522f475Smrg{
124420d2c4d2Smrg    const char *result = "?";
1245d522f475Smrg    /* *INDENT-OFF* */
1246d522f475Smrg    WHICH_TABLE (ansi_table);
12472eaa94a1Schristos    else WHICH_TABLE (cigtable);
1248d522f475Smrg    else WHICH_TABLE (csi2_table);
1249d522f475Smrg    else WHICH_TABLE (csi_ex_table);
1250d522f475Smrg    else WHICH_TABLE (csi_quo_table);
12512eaa94a1Schristos    else WHICH_TABLE (csi_table);
1252d522f475Smrg    else WHICH_TABLE (dec2_table);
1253d522f475Smrg    else WHICH_TABLE (dec3_table);
12542eaa94a1Schristos    else WHICH_TABLE (dec_table);
1255d522f475Smrg    else WHICH_TABLE (eigtable);
1256d522f475Smrg    else WHICH_TABLE (esc_sp_table);
12572eaa94a1Schristos    else WHICH_TABLE (esc_table);
1258d522f475Smrg    else WHICH_TABLE (scrtable);
12592eaa94a1Schristos    else WHICH_TABLE (scs96table);
1260d522f475Smrg    else WHICH_TABLE (scstable);
1261d522f475Smrg    else WHICH_TABLE (sos_table);
126220d2c4d2Smrg#if OPT_BLINK_CURS
126320d2c4d2Smrg    else WHICH_TABLE (csi_sp_table);
126420d2c4d2Smrg#endif
12652eaa94a1Schristos#if OPT_DEC_LOCATOR
12662eaa94a1Schristos    else WHICH_TABLE (csi_tick_table);
12672eaa94a1Schristos#endif
12682eaa94a1Schristos#if OPT_DEC_RECTOPS
12692eaa94a1Schristos    else WHICH_TABLE (csi_dollar_table);
12702eaa94a1Schristos    else WHICH_TABLE (csi_star_table);
1271492d43a5Smrg    else WHICH_TABLE (csi_dec_dollar_table);
12722eaa94a1Schristos#endif
1273d522f475Smrg#if OPT_WIDE_CHARS
1274d522f475Smrg    else WHICH_TABLE (esc_pct_table);
1275e0a2b6dfSmrg    else WHICH_TABLE (scs_pct_table);
1276d522f475Smrg#endif
1277d522f475Smrg#if OPT_VT52_MODE
1278d522f475Smrg    else WHICH_TABLE (vt52_table);
1279d522f475Smrg    else WHICH_TABLE (vt52_esc_table);
1280d522f475Smrg    else WHICH_TABLE (vt52_ignore_table);
1281d522f475Smrg#endif
1282d522f475Smrg    /* *INDENT-ON* */
1283d522f475Smrg
1284d522f475Smrg    return result;
1285d522f475Smrg}
12860bd37d32Smrg#endif
12870bd37d32Smrg
12880bd37d32Smrg#if OPT_TRACE > 0
12890bd37d32Smrgstatic void
12900bd37d32Smrgdump_params(void)
12910bd37d32Smrg{
12920bd37d32Smrg    int n;
12930bd37d32Smrg    int arg;
12940bd37d32Smrg    TRACE(("params %d (%d)\n", nparam, parms.has_subparams));
12950bd37d32Smrg    for (arg = 1, n = 0; n < nparam; ++n) {
12960bd37d32Smrg	TRACE(("%3d.%d %d\n", arg, parms.is_sub[n], parms.params[n]));
12970bd37d32Smrg	if (!parms.is_sub[n])
12980bd37d32Smrg	    ++arg;
12990bd37d32Smrg    }
13000bd37d32Smrg}
13010bd37d32Smrg#define DumpParams() dump_params()
13020bd37d32Smrg#else
13030bd37d32Smrg#define DumpParams()		/* nothing */
1304d522f475Smrg#endif
1305d522f475Smrg
1306d522f475Smrg	/* allocate larger buffer if needed/possible */
1307d522f475Smrg#define SafeAlloc(type, area, used, size) \
1308d522f475Smrg		type *new_string = area; \
130920d2c4d2Smrg		size_t new_length = size; \
1310d522f475Smrg		if (new_length == 0) { \
1311d522f475Smrg		    new_length = 256; \
1312d522f475Smrg		    new_string = TypeMallocN(type, new_length); \
1313d522f475Smrg		} else if (used+1 >= new_length) { \
1314d522f475Smrg		    new_length = size * 2; \
1315d522f475Smrg		    new_string = TypeMallocN(type, new_length); \
1316d522f475Smrg		    if (new_string != 0 \
1317d522f475Smrg		     && area != 0 \
1318d522f475Smrg		     && used != 0) \
1319d522f475Smrg			memcpy(new_string, area, used * sizeof(type)); \
1320d522f475Smrg		}
1321d522f475Smrg
1322d522f475Smrg#define WriteNow() {						\
1323d522f475Smrg	    unsigned single = 0;				\
1324d522f475Smrg								\
1325d522f475Smrg	    if (screen->curss) {				\
1326d522f475Smrg		dotext(xw,					\
1327d522f475Smrg		       screen->gsets[(int) (screen->curss)],	\
1328956cc18dSsnj		       sp->print_area,				\
1329956cc18dSsnj		       (Cardinal) 1);				\
1330d522f475Smrg		screen->curss = 0;				\
1331d522f475Smrg		single++;					\
1332d522f475Smrg	    }							\
1333956cc18dSsnj	    if (sp->print_used > single) {			\
1334d522f475Smrg		dotext(xw,					\
1335d522f475Smrg		       screen->gsets[(int) (screen->curgl)],	\
1336956cc18dSsnj		       sp->print_area + single,			\
1337956cc18dSsnj		       (Cardinal) (sp->print_used - single));	\
1338d522f475Smrg	    }							\
1339956cc18dSsnj	    sp->print_used = 0;					\
1340d522f475Smrg	}							\
1341d522f475Smrg
1342d522f475Smrgstruct ParseState {
1343d522f475Smrg#if OPT_VT52_MODE
1344d522f475Smrg    Bool vt52_cup;
1345d522f475Smrg#endif
1346d522f475Smrg    Const PARSE_T *groundtable;
1347d522f475Smrg    Const PARSE_T *parsestate;
1348d522f475Smrg    int scstype;
13492eaa94a1Schristos    int scssize;
1350d522f475Smrg    Bool private_function;	/* distinguish private-mode from standard */
1351d522f475Smrg    int string_mode;		/* nonzero iff we're processing a string */
1352d522f475Smrg    int lastchar;		/* positive iff we had a graphic character */
1353d522f475Smrg    int nextstate;
1354d522f475Smrg#if OPT_WIDE_CHARS
1355d522f475Smrg    int last_was_wide;
1356d522f475Smrg#endif
1357956cc18dSsnj    /* Buffer for processing printable text */
1358956cc18dSsnj    IChar *print_area;
1359956cc18dSsnj    size_t print_size;
1360956cc18dSsnj    size_t print_used;
1361956cc18dSsnj    /* Buffer for processing strings (e.g., OSC ... ST) */
1362956cc18dSsnj    Char *string_area;
1363956cc18dSsnj    size_t string_size;
1364956cc18dSsnj    size_t string_used;
1365d522f475Smrg};
1366d522f475Smrg
1367d522f475Smrgstatic struct ParseState myState;
1368d522f475Smrg
13692eaa94a1Schristosstatic void
1370e0a2b6dfSmrginit_groundtable(TScreen *screen, struct ParseState *sp)
13712eaa94a1Schristos{
1372956cc18dSsnj    (void) screen;
1373956cc18dSsnj
13742eaa94a1Schristos#if OPT_VT52_MODE
13752eaa94a1Schristos    if (!(screen->vtXX_level)) {
13762eaa94a1Schristos	sp->groundtable = vt52_table;
13772eaa94a1Schristos    } else if (screen->terminal_id >= 100)
13782eaa94a1Schristos#endif
13792eaa94a1Schristos    {
13802eaa94a1Schristos	sp->groundtable = ansi_table;
13812eaa94a1Schristos    }
13822eaa94a1Schristos}
13832eaa94a1Schristos
13842eaa94a1Schristosstatic void
13852eaa94a1Schristosselect_charset(struct ParseState *sp, int type, int size)
13862eaa94a1Schristos{
1387e0a2b6dfSmrg    TRACE(("select_charset %d %d\n", type, size));
13882eaa94a1Schristos    sp->scstype = type;
13892eaa94a1Schristos    sp->scssize = size;
13902eaa94a1Schristos    if (size == 94) {
13912eaa94a1Schristos	sp->parsestate = scstable;
13922eaa94a1Schristos    } else {
13932eaa94a1Schristos	sp->parsestate = scs96table;
13942eaa94a1Schristos    }
13952eaa94a1Schristos}
13962eaa94a1Schristos
1397e0a2b6dfSmrgstatic void
1398e0a2b6dfSmrgdecode_scs(XtermWidget xw, int which, int prefix, int suffix)
1399e0a2b6dfSmrg{
1400e0a2b6dfSmrg    /* *INDENT-OFF* */
1401e0a2b6dfSmrg    static struct {
1402e0a2b6dfSmrg	DECNRCM_codes result;
1403e0a2b6dfSmrg	int prefix;
1404e0a2b6dfSmrg	int suffix;
1405e0a2b6dfSmrg	int min_level;
1406e0a2b6dfSmrg	int max_level;
1407e0a2b6dfSmrg	int need_nrc;
1408e0a2b6dfSmrg    } table[] = {
1409e0a2b6dfSmrg	{ nrc_ASCII,             0,   'B', 1, 9, 0 },
1410e0a2b6dfSmrg	{ nrc_British,           0,   'A', 1, 9, 0 },
1411e0a2b6dfSmrg	{ nrc_DEC_Spec_Graphic,  0,   '0', 1, 9, 0 },
1412e0a2b6dfSmrg	{ nrc_DEC_Alt_Chars,     0,   '1', 1, 1, 0 },
1413e0a2b6dfSmrg	{ nrc_DEC_Alt_Graphics,  0,   '2', 1, 1, 0 },
1414e0a2b6dfSmrg	/* VT2xx */
1415e0a2b6dfSmrg	{ nrc_DEC_Supp,          0,   '<', 2, 9, 0 },
1416e0a2b6dfSmrg	{ nrc_Dutch,             0,   '4', 2, 9, 1 },
1417e0a2b6dfSmrg	{ nrc_Finnish,           0,   '5', 2, 9, 1 },
1418e0a2b6dfSmrg	{ nrc_Finnish2,          0,   'C', 2, 9, 1 },
1419e0a2b6dfSmrg	{ nrc_French,            0,   'R', 2, 9, 1 },
1420e0a2b6dfSmrg	{ nrc_French2,           0,   'f', 2, 9, 1 },
1421e0a2b6dfSmrg	{ nrc_French_Canadian,   0,   'Q', 2, 9, 1 },
1422e0a2b6dfSmrg	{ nrc_German,            0,   'K', 2, 9, 1 },
1423e0a2b6dfSmrg	{ nrc_Italian,           0,   'Y', 2, 9, 1 },
1424e0a2b6dfSmrg	{ nrc_Norwegian_Danish2, 0,   'E', 2, 9, 1 },
1425e0a2b6dfSmrg	{ nrc_Norwegian_Danish3, 0,   '6', 2, 9, 1 },
1426e0a2b6dfSmrg	{ nrc_Spanish,           0,   'Z', 2, 9, 1 },
1427e0a2b6dfSmrg	{ nrc_Swedish,           0,   '7', 2, 9, 1 },
1428e0a2b6dfSmrg	{ nrc_Swedish2,          0,   'H', 2, 9, 1 },
1429e0a2b6dfSmrg	{ nrc_Swiss,             0,   '=', 2, 9, 1 },
1430e0a2b6dfSmrg	/* VT3xx */
1431e0a2b6dfSmrg	{ nrc_British_Latin_1,   0,   'A', 3, 9, 1 },
1432e0a2b6dfSmrg	{ nrc_DEC_Supp_Graphic,  '%', '5', 3, 9, 0 },
1433e0a2b6dfSmrg	{ nrc_DEC_Technical,     0,   '>', 3, 9, 0 },
1434e0a2b6dfSmrg	{ nrc_French_Canadian2,  0,   '9', 3, 9, 1 },
1435e0a2b6dfSmrg	{ nrc_Norwegian_Danish,  0,   '`', 3, 9, 1 },
1436e0a2b6dfSmrg	{ nrc_Portugese,         '%', '6', 3, 9, 1 },
1437e0a2b6dfSmrg#if 0
1438e0a2b6dfSmrg	/* VT5xx (not implemented) */
1439e0a2b6dfSmrg	{ nrc_Cyrillic,          '&', '4', 5, 9, 0 },
1440e0a2b6dfSmrg	{ nrc_Greek,             '"', '?', 5, 9, 0 },
1441e0a2b6dfSmrg	{ nrc_Greek_Supp,        0,   'F', 5, 9, 0 },
1442e0a2b6dfSmrg	{ nrc_Hebrew,            '"', '4', 5, 9, 0 },
1443e0a2b6dfSmrg	{ nrc_Hebrew2,           '%', '=', 5, 9, 1 },
1444e0a2b6dfSmrg	{ nrc_Hebrew_Supp,       0,   'H', 5, 9, 0 },
1445e0a2b6dfSmrg	{ nrc_Latin_5_Supp,      0,   'M', 5, 9, 0 },
1446e0a2b6dfSmrg	{ nrc_Latin_Cyrillic,    0,   'L', 5, 9, 0 },
1447e0a2b6dfSmrg	{ nrc_Russian,           '&', '5', 5, 9, 1 },
1448e0a2b6dfSmrg	{ nrc_SCS_NRCS,          '%', '3', 5, 9, 0 },
1449e0a2b6dfSmrg	{ nrc_Turkish,           '%', '0', 5, 9, 0 },
1450e0a2b6dfSmrg	{ nrc_Turkish2,		 '%', '2', 5, 9, 1 },
1451e0a2b6dfSmrg#endif
1452e0a2b6dfSmrg    };
1453e0a2b6dfSmrg    /* *INDENT-ON* */
1454e0a2b6dfSmrg
1455e0a2b6dfSmrg    TScreen *screen = TScreenOf(xw);
1456e0a2b6dfSmrg    Cardinal n;
1457e0a2b6dfSmrg    DECNRCM_codes result = nrc_Unknown;
1458e0a2b6dfSmrg
1459e0a2b6dfSmrg    suffix &= 0x7f;
1460e0a2b6dfSmrg    for (n = 0; n < XtNumber(table); ++n) {
1461e0a2b6dfSmrg	if (prefix == table[n].prefix
1462e0a2b6dfSmrg	    && suffix == table[n].suffix
1463e0a2b6dfSmrg	    && screen->vtXX_level >= table[n].min_level
1464e0a2b6dfSmrg	    && screen->vtXX_level <= table[n].max_level
1465e0a2b6dfSmrg	    && (table[n].need_nrc == 0 || (xw->flags & NATIONAL) != 0)) {
1466e0a2b6dfSmrg	    result = table[n].result;
1467e0a2b6dfSmrg	    break;
1468e0a2b6dfSmrg	}
1469e0a2b6dfSmrg    }
1470e0a2b6dfSmrg    if (result != nrc_Unknown) {
1471e0a2b6dfSmrg	screen->gsets[which] = result;
1472e0a2b6dfSmrg	TRACE(("setting G%d to %s\n", which, visibleScsCode((int) result)));
1473e0a2b6dfSmrg    } else {
1474e0a2b6dfSmrg	TRACE(("...unknown GSET\n"));
1475e0a2b6dfSmrg    }
1476e0a2b6dfSmrg}
1477e0a2b6dfSmrg
14780bd37d32Smrg/*
14790bd37d32Smrg * Given a parameter number, and subparameter (starting in each case from zero)
14800bd37d32Smrg * return the corresponding index into the parameter array.  If the combination
14810bd37d32Smrg * is not found, return -1.
14820bd37d32Smrg */
1483e39b573cSmrgstatic int
14840bd37d32Smrgsubparam_index(int p, int s)
1485e39b573cSmrg{
14860bd37d32Smrg    int result = -1;
14870bd37d32Smrg    int j, p2, s2;
14880bd37d32Smrg
14890bd37d32Smrg    for (j = p2 = 0; j < nparam; ++j, ++p2) {
14900bd37d32Smrg	if (parms.is_sub[j]) {
14910bd37d32Smrg	    s2 = 0;
14920bd37d32Smrg
14930bd37d32Smrg	    do {
14940bd37d32Smrg		if ((p == p2) && (s == s2)) {
14950bd37d32Smrg		    result = j;
14960bd37d32Smrg		    break;
14970bd37d32Smrg		}
14980bd37d32Smrg		++s2;
14990bd37d32Smrg	    } while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j]));
15000bd37d32Smrg
15010bd37d32Smrg	    if (result >= 0)
15020bd37d32Smrg		break;
15030bd37d32Smrg
15040bd37d32Smrg	    --j;		/* undo the last "while" */
15050bd37d32Smrg	} else if (p == p2) {
15060bd37d32Smrg	    if (s == 0) {
15070bd37d32Smrg		result = j;
15080bd37d32Smrg	    }
15090bd37d32Smrg	    break;
15100bd37d32Smrg	}
15110bd37d32Smrg    }
15120bd37d32Smrg    TRACE2(("...subparam_index %d.%d = %d\n", p + 1, s + 1, result));
15130bd37d32Smrg    return result;
15140bd37d32Smrg}
15150bd37d32Smrg
15160bd37d32Smrg/*
15170bd37d32Smrg * Given an index into the parameter array, return the corresponding parameter
15180bd37d32Smrg * number (starting from zero).
15190bd37d32Smrg */
15200bd37d32Smrgstatic int
15210bd37d32Smrgparam_number(int item)
15220bd37d32Smrg{
15230bd37d32Smrg    int result = -1;
15240bd37d32Smrg    int j, p;
15250bd37d32Smrg
15260bd37d32Smrg    for (j = p = 0; j < nparam; ++j, ++p) {
15270bd37d32Smrg	if (p >= item) {
15280bd37d32Smrg	    result = j;
15290bd37d32Smrg	    break;
15300bd37d32Smrg	}
15310bd37d32Smrg	if (parms.is_sub[j]) {
15320bd37d32Smrg	    while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j])) {
15330bd37d32Smrg		/* EMPTY */
15340bd37d32Smrg	    }
15350bd37d32Smrg	    --j;
15360bd37d32Smrg	}
15370bd37d32Smrg    }
15380bd37d32Smrg
15390bd37d32Smrg    TRACE2(("...param_number(%d) = %d\n", item, result));
15400bd37d32Smrg    return result;
15410bd37d32Smrg}
15420bd37d32Smrg
15430bd37d32Smrgstatic int
15440bd37d32Smrgget_subparam(int p, int s)
15450bd37d32Smrg{
15460bd37d32Smrg    int item = subparam_index(p, s);
15470bd37d32Smrg    int result = (item >= 0) ? parms.params[item] : DEFAULT;
15480bd37d32Smrg    TRACE(("...get_subparam[%d] = %d\n", item, result));
1549e39b573cSmrg    return result;
1550e39b573cSmrg}
1551e39b573cSmrg
15520bd37d32Smrg/*
15530bd37d32Smrg * Check if the given item in the parameter array has subparameters.
15540bd37d32Smrg * If so, return the number of subparameters to use as a loop limit, etc.
15550bd37d32Smrg */
15560bd37d32Smrgstatic int
15570bd37d32Smrgparam_has_subparams(int item)
15580bd37d32Smrg{
15590bd37d32Smrg    int result = 0;
15600bd37d32Smrg    if (parms.has_subparams) {
15610bd37d32Smrg	int n = subparam_index(item, 0);
15620bd37d32Smrg	if (n >= 0 && parms.is_sub[n]) {
15630bd37d32Smrg	    while (n++ < nparam && parms.is_sub[n - 1] < parms.is_sub[n]) {
15640bd37d32Smrg		result++;
15650bd37d32Smrg	    }
15660bd37d32Smrg	}
15670bd37d32Smrg    }
15680bd37d32Smrg    TRACE(("...param_has_subparams(%d) ->%d\n", item, result));
15690bd37d32Smrg    return result;
15700bd37d32Smrg}
15710bd37d32Smrg
15720bd37d32Smrg#if OPT_256_COLORS || OPT_88_COLORS || OPT_ISO_COLORS
15730bd37d32Smrg/*
15740bd37d32Smrg * Some background -
15750bd37d32Smrg *
15760bd37d32Smrg * Todd Larason provided the initial changes to support 256-colors in July 1999.
15770bd37d32Smrg * I pointed out that the description of SGR 38/48 in ECMA-48 was vague, and
15780bd37d32Smrg * was unsure if there would be some standard using those codes.  His response
15790bd37d32Smrg * was that this was documented (it turns out, in equally vague terms) in ITU
15800bd37d32Smrg * T.416
15810bd37d32Smrg *
15820bd37d32Smrg * Discussing this with Todd Larason in mid-1999, my point was that given the
15830bd37d32Smrg * high cost of obtaining ITU T.416 (ISO-8613-6), the standard was not going
15840bd37d32Smrg * to be effective (more than $100 then, more than $200 in 2012)
15850bd37d32Smrg *
15860bd37d32Smrg * We overlooked the detail about ":" as a subparameter delimiter (documented
15870bd37d32Smrg * in 5.4.t2 in ECMA-48).  Some discussion in KDE in mid-2006 led Lars Doelle
15880bd37d32Smrg * to discuss the issue with me.  Lars' initial concern dealt with the fact
15890bd37d32Smrg * that a sequence such as
15900bd37d32Smrg *	CSI 38 ; 5 ; 1 m
15910bd37d32Smrg * violated the principle that SGR parameters could be used in any order.
15920bd37d32Smrg * Further discussion (see KDE #107487) resolved that the standard expected
15930bd37d32Smrg * that the sequence would look like
15940bd37d32Smrg *	CSI 38 ; 5 : 1 m
15950bd37d32Smrg * which still violates that principle, since the "5:1" parameter has to
15960bd37d32Smrg * follow the "38" to be useful.
15970bd37d32Smrg *
15980bd37d32Smrg * This function accepts either format (per request by Paul Leonerd Evans).
15990bd37d32Smrg * It also accepts
16000bd37d32Smrg *	CSI 38 : 5 : 1 m
16010bd37d32Smrg * according to Lars' original assumption.
16020bd37d32Smrg *
16030bd37d32Smrg * By the way - all of the parameters are decimal integers.
16040bd37d32Smrg */
16050bd37d32Smrg#define extended_colors_limit(n) ((n) == 5 ? 1 : ((n) == 2 ? 3 : 0))
16060bd37d32Smrgstatic Boolean
16070bd37d32Smrgparse_extended_colors(XtermWidget xw, int *colorp, int *itemp)
16080bd37d32Smrg{
16090bd37d32Smrg    Boolean result = False;
16100bd37d32Smrg    int item = *itemp;
16110bd37d32Smrg    int next = item;
16120bd37d32Smrg    int base = param_number(item);
16130bd37d32Smrg    int code = -1;
16140bd37d32Smrg    int values[3];		/* maximum number of subparameters */
16150bd37d32Smrg    int need = 0;		/* number of subparameters needed */
16160bd37d32Smrg    int have;
16170bd37d32Smrg    int n;
16180bd37d32Smrg
16190bd37d32Smrg    /*
16200bd37d32Smrg     * On entry, 'item' points to the 38/48 code in the parameter array.
16210bd37d32Smrg     * If that has subparameters, we will expect all of the values to
16220bd37d32Smrg     * be subparameters of that item.
16230bd37d32Smrg     */
16240bd37d32Smrg    if ((have = param_has_subparams(item)) != 0) {
16250bd37d32Smrg	/* accept CSI 38 : 5 : 1 m */
16260bd37d32Smrg	/* accept CSI 38 : 2 : 1 : 2 : 3 m */
16270bd37d32Smrg	code = get_subparam(base, 1);
16280bd37d32Smrg	need = extended_colors_limit(code);
16290bd37d32Smrg	next = item + have;
16300bd37d32Smrg	for (n = 0; n < need && n < 3; ++n) {
16310bd37d32Smrg	    values[n] = get_subparam(base, 2 + n);
16320bd37d32Smrg	}
16330bd37d32Smrg    } else if (++item < nparam) {
16340bd37d32Smrg	++base;
16350bd37d32Smrg	if ((have = param_has_subparams(item)) != 0) {
16360bd37d32Smrg	    /* accept CSI 38 ; 5 : 1 m */
16370bd37d32Smrg	    /* accept CSI 38 ; 2 : 1 : 2 : 3 m */
16380bd37d32Smrg	    code = get_subparam(base, 0);
16390bd37d32Smrg	    need = extended_colors_limit(code);
16400bd37d32Smrg	    next = base + have;
16410bd37d32Smrg	    for (n = 0; n < need && n < 3; ++n) {
16420bd37d32Smrg		values[n] = get_subparam(base, 1 + n);
16430bd37d32Smrg	    }
16440bd37d32Smrg	} else {
16450bd37d32Smrg	    /* accept CSI 38 ; 5 ; 1 m */
16460bd37d32Smrg	    /* accept CSI 38 ; 2 ; 1 ; 2 ; 3 m */
16470bd37d32Smrg	    code = GetParam(item);
16480bd37d32Smrg	    need = extended_colors_limit(code);
16490bd37d32Smrg	    next = item + need;
16500bd37d32Smrg	    for (n = 0; n < need && n < 3; ++n) {
16510bd37d32Smrg		values[n] = GetParam(item + 1 + n);
16520bd37d32Smrg	    }
16530bd37d32Smrg	}
16540bd37d32Smrg    }
16550bd37d32Smrg    item = next;
16560bd37d32Smrg
16570bd37d32Smrg    switch (code) {
16580bd37d32Smrg    case 2:
16590bd37d32Smrg	/* direct color in rgb space */
16600bd37d32Smrg	if ((values[0] >= 0 && values[0] < 256) &&
16610bd37d32Smrg	    (values[1] >= 0 && values[1] < 256) &&
16620bd37d32Smrg	    (values[2] >= 0 && values[2] < 256)) {
16630bd37d32Smrg	    *colorp = xtermClosestColor(xw, values[0], values[1], values[2]);
16640bd37d32Smrg	} else {
16650bd37d32Smrg	    *colorp = -1;
16660bd37d32Smrg	}
16670bd37d32Smrg	break;
16680bd37d32Smrg    case 5:
16690bd37d32Smrg	/* indexed color */
16700bd37d32Smrg	*colorp = values[0];
16710bd37d32Smrg	break;
16720bd37d32Smrg    default:
16730bd37d32Smrg	*colorp = -1;
16740bd37d32Smrg	break;
16750bd37d32Smrg    }
16760bd37d32Smrg
16770bd37d32Smrg    result = (*colorp >= 0 && *colorp < NUM_ANSI_COLORS);
16780bd37d32Smrg    TRACE(("...resulting color %d/%d %s\n",
16790bd37d32Smrg	   *colorp, NUM_ANSI_COLORS,
16800bd37d32Smrg	   result ? "OK" : "ERR"));
16810bd37d32Smrg
16820bd37d32Smrg    *itemp = item;
16830bd37d32Smrg    return result;
16840bd37d32Smrg}
16850bd37d32Smrg#endif /* ...extended_colors */
16860bd37d32Smrg
16870bd37d32Smrgstatic int
16880bd37d32Smrgoptional_param(int which)
16890bd37d32Smrg{
16900bd37d32Smrg    return (nparam > which) ? GetParam(which) : DEFAULT;
16910bd37d32Smrg}
16920bd37d32Smrg
169320d2c4d2Smrgstatic int
169420d2c4d2Smrgzero_if_default(int which)
169520d2c4d2Smrg{
16960bd37d32Smrg    int result = (nparam > which) ? GetParam(which) : 0;
169720d2c4d2Smrg    if (result <= 0)
169820d2c4d2Smrg	result = 0;
169920d2c4d2Smrg    return result;
170020d2c4d2Smrg}
170120d2c4d2Smrg
170220d2c4d2Smrgstatic int
170320d2c4d2Smrgone_if_default(int which)
170420d2c4d2Smrg{
17050bd37d32Smrg    int result = (nparam > which) ? GetParam(which) : 0;
170620d2c4d2Smrg    if (result <= 0)
170720d2c4d2Smrg	result = 1;
170820d2c4d2Smrg    return result;
170920d2c4d2Smrg}
171020d2c4d2Smrg
17110bd37d32Smrg/*
17120bd37d32Smrg * Color palette changes using the OSC controls require a repaint of the
17130bd37d32Smrg * screen - but not immediately.  Do the repaint as soon as we detect a
17140bd37d32Smrg * state which will not lead to another color palette change.
17150bd37d32Smrg */
17160bd37d32Smrgstatic void
17170bd37d32SmrgrepaintWhenPaletteChanged(XtermWidget xw, struct ParseState *sp)
17180bd37d32Smrg{
17190bd37d32Smrg    Boolean ignore = False;
17200bd37d32Smrg
17210bd37d32Smrg    switch (sp->nextstate) {
17220bd37d32Smrg    case CASE_ESC:
17230bd37d32Smrg	ignore = ((sp->parsestate == ansi_table) ||
17240bd37d32Smrg		  (sp->parsestate == sos_table));
17250bd37d32Smrg	break;
17260bd37d32Smrg    case CASE_OSC:
17270bd37d32Smrg	ignore = ((sp->parsestate == ansi_table) ||
17280bd37d32Smrg		  (sp->parsestate == esc_table));
17290bd37d32Smrg	break;
17300bd37d32Smrg    case CASE_IGNORE:
17310bd37d32Smrg	ignore = (sp->parsestate == sos_table);
17320bd37d32Smrg	break;
17330bd37d32Smrg    case CASE_ST:
17340bd37d32Smrg	ignore = ((sp->parsestate == esc_table) ||
17350bd37d32Smrg		  (sp->parsestate == sos_table));
17360bd37d32Smrg	break;
17370bd37d32Smrg    case CASE_ESC_DIGIT:
17380bd37d32Smrg	ignore = (sp->parsestate == csi_table);
17390bd37d32Smrg	break;
17400bd37d32Smrg    case CASE_ESC_SEMI:
17410bd37d32Smrg	ignore = (sp->parsestate == csi2_table);
17420bd37d32Smrg	break;
17430bd37d32Smrg    }
17440bd37d32Smrg
17450bd37d32Smrg    if (!ignore) {
17460bd37d32Smrg	TRACE(("repaintWhenPaletteChanged\n"));
17470bd37d32Smrg	xw->misc.palette_changed = False;
17480bd37d32Smrg	xtermRepaint(xw);
17490bd37d32Smrg    }
17500bd37d32Smrg}
17510bd37d32Smrg
175220d2c4d2Smrg#if OPT_C1_PRINT || OPT_WIDE_CHARS
175320d2c4d2Smrg#define ParseSOS(screen) ((screen)->c1_printable == 0)
175420d2c4d2Smrg#else
175520d2c4d2Smrg#define ParseSOS(screen) 0
175620d2c4d2Smrg#endif
175720d2c4d2Smrg
17580bd37d32Smrg#define ResetState(sp) ParamsDone(), (sp)->parsestate = (sp)->groundtable
175920d2c4d2Smrg
176020d2c4d2Smrgstatic void
176120d2c4d2Smrgillegal_parse(XtermWidget xw, unsigned c, struct ParseState *sp)
176220d2c4d2Smrg{
176320d2c4d2Smrg    ResetState(sp);
176420d2c4d2Smrg    sp->nextstate = sp->parsestate[E2A(c)];
176520d2c4d2Smrg    Bell(xw, XkbBI_MinorError, 0);
176620d2c4d2Smrg}
176720d2c4d2Smrg
1768e39b573cSmrgstatic void
1769e39b573cSmrginit_parser(XtermWidget xw, struct ParseState *sp)
1770e39b573cSmrg{
1771e39b573cSmrg    TScreen *screen = TScreenOf(xw);
1772e39b573cSmrg
1773e39b573cSmrg    memset(sp, 0, sizeof(*sp));
1774e39b573cSmrg    sp->scssize = 94;		/* number of printable/nonspace ASCII */
1775e39b573cSmrg    sp->lastchar = -1;		/* not a legal IChar */
1776e39b573cSmrg    sp->nextstate = -1;		/* not a legal state */
1777e39b573cSmrg
1778e39b573cSmrg    init_groundtable(screen, sp);
1779e39b573cSmrg    ResetState(sp);
1780e39b573cSmrg}
1781e39b573cSmrg
17820bd37d32Smrgstatic void
17830bd37d32Smrginit_reply(unsigned type)
17840bd37d32Smrg{
17850bd37d32Smrg    memset(&reply, 0, sizeof(reply));
17860bd37d32Smrg    reply.a_type = (Char) type;
17870bd37d32Smrg}
17880bd37d32Smrg
1789d522f475Smrgstatic Boolean
1790d522f475Smrgdoparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
1791d522f475Smrg{
179220d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
17930bd37d32Smrg    int item;
1794d522f475Smrg    int count;
17950bd37d32Smrg    int value;
1796d522f475Smrg    int laststate;
1797d522f475Smrg    int thischar = -1;
1798d522f475Smrg    XTermRect myRect;
1799d522f475Smrg
1800d522f475Smrg    do {
1801d522f475Smrg#if OPT_WIDE_CHARS
1802956cc18dSsnj	int this_is_wide = 0;
1803d522f475Smrg
1804d522f475Smrg	/*
1805d522f475Smrg	 * Handle zero-width combining characters.  Make it faster by noting
1806d522f475Smrg	 * that according to the Unicode charts, the majority of Western
1807d522f475Smrg	 * character sets do not use this feature.  There are some unassigned
1808d522f475Smrg	 * codes at 0x242, but no zero-width characters until past 0x300.
1809d522f475Smrg	 */
18100bd37d32Smrg	if (c >= 0x300
18110bd37d32Smrg	    && screen->wide_chars
18120bd37d32Smrg	    && my_wcwidth((wchar_t) c) == 0
1813d522f475Smrg	    && !isWideControl(c)) {
18140bd37d32Smrg	    int prev, test;
18150bd37d32Smrg	    Boolean used = True;
18160bd37d32Smrg	    int use_row;
18170bd37d32Smrg	    int use_col;
1818d522f475Smrg
1819d522f475Smrg	    WriteNow();
18200bd37d32Smrg	    use_row = (screen->char_was_written
18210bd37d32Smrg		       ? screen->last_written_row
18220bd37d32Smrg		       : screen->cur_row);
18230bd37d32Smrg	    use_col = (screen->char_was_written
18240bd37d32Smrg		       ? screen->last_written_col
18250bd37d32Smrg		       : screen->cur_col);
1826d522f475Smrg
18270bd37d32Smrg	    /*
18280bd37d32Smrg	     * Check if the latest data can be added to the base character.
18290bd37d32Smrg	     * If there is already a combining character stored for the cell,
18300bd37d32Smrg	     * we cannot, since that would change the order.
18310bd37d32Smrg	     */
18320bd37d32Smrg	    if (screen->normalized_c
18330bd37d32Smrg		&& !IsCellCombined(screen, use_row, use_col)) {
18340bd37d32Smrg		prev = (int) XTERM_CELL(use_row, use_col);
18350bd37d32Smrg		test = do_precomposition(prev, (int) c);
18360bd37d32Smrg		TRACE(("do_precomposition (U+%04X [%d], U+%04X [%d]) -> U+%04X [%d]\n",
18370bd37d32Smrg		       prev, my_wcwidth((wchar_t) prev),
18380bd37d32Smrg		       (int) c, my_wcwidth((wchar_t) c),
18390bd37d32Smrg		       test, my_wcwidth((wchar_t) test)));
18400bd37d32Smrg	    } else {
18410bd37d32Smrg		prev = -1;
18420bd37d32Smrg		test = -1;
18430bd37d32Smrg	    }
1844d522f475Smrg
1845d522f475Smrg	    /* substitute combined character with precomposed character
1846d522f475Smrg	     * only if it does not change the width of the base character
1847d522f475Smrg	     */
18480bd37d32Smrg	    if (test != -1
18490bd37d32Smrg		&& my_wcwidth((wchar_t) test) == my_wcwidth((wchar_t) prev)) {
18500bd37d32Smrg		putXtermCell(screen, use_row, use_col, test);
18510bd37d32Smrg	    } else if (screen->char_was_written
18520bd37d32Smrg		       || getXtermCell(screen, use_row, use_col) > ' ') {
18530bd37d32Smrg		addXtermCombining(screen, use_row, use_col, c);
1854d522f475Smrg	    } else {
18550bd37d32Smrg		/*
18560bd37d32Smrg		 * none of the above... we will add the combining character as
18570bd37d32Smrg		 * a base character.
18580bd37d32Smrg		 */
18590bd37d32Smrg		used = False;
1860d522f475Smrg	    }
1861d522f475Smrg
18620bd37d32Smrg	    if (used) {
18630bd37d32Smrg		if (!screen->scroll_amt)
18640bd37d32Smrg		    ScrnUpdate(xw, use_row, use_col, 1, 1, 1);
18650bd37d32Smrg		continue;
18660bd37d32Smrg	    }
1867d522f475Smrg	}
1868d522f475Smrg#endif
1869d522f475Smrg
1870d522f475Smrg	/* Intercept characters for printer controller mode */
1871e39b573cSmrg	if (PrinterOf(screen).printer_controlmode == 2) {
1872956cc18dSsnj	    if ((c = (unsigned) xtermPrinterControl(xw, (int) c)) == 0)
1873d522f475Smrg		continue;
1874d522f475Smrg	}
1875d522f475Smrg
1876d522f475Smrg	/*
1877d522f475Smrg	 * VT52 is a little ugly in the one place it has a parameterized
1878d522f475Smrg	 * control sequence, since the parameter falls after the character
1879d522f475Smrg	 * that denotes the type of sequence.
1880d522f475Smrg	 */
1881d522f475Smrg#if OPT_VT52_MODE
1882d522f475Smrg	if (sp->vt52_cup) {
18830bd37d32Smrg	    if (nparam < NPARAM - 1) {
18840bd37d32Smrg		SetParam(nparam++, (int) (c & 0x7f) - 32);
18850bd37d32Smrg		parms.is_sub[nparam] = 0;
18860bd37d32Smrg	    }
1887d522f475Smrg	    if (nparam < 2)
1888d522f475Smrg		continue;
1889d522f475Smrg	    sp->vt52_cup = False;
18900bd37d32Smrg	    CursorSet(screen, zero_if_default(0), zero_if_default(1), xw->flags);
1891d522f475Smrg	    sp->parsestate = vt52_table;
18920bd37d32Smrg	    SetParam(0, 0);
18930bd37d32Smrg	    SetParam(1, 0);
1894d522f475Smrg	    continue;
1895d522f475Smrg	}
1896d522f475Smrg#endif
1897d522f475Smrg
1898d522f475Smrg	laststate = sp->nextstate;
18992eaa94a1Schristos	if (c == ANSI_DEL
19002eaa94a1Schristos	    && sp->parsestate == sp->groundtable
19012eaa94a1Schristos	    && sp->scssize == 96
19022eaa94a1Schristos	    && sp->scstype != 0) {
19032eaa94a1Schristos	    /*
19042eaa94a1Schristos	     * Handle special case of shifts for 96-character sets by checking
19052eaa94a1Schristos	     * if we have a DEL.  The other special case for SPACE will always
19062eaa94a1Schristos	     * be printable.
19072eaa94a1Schristos	     */
19082eaa94a1Schristos	    sp->nextstate = CASE_PRINT;
19092eaa94a1Schristos	} else
1910d522f475Smrg#if OPT_WIDE_CHARS
1911d522f475Smrg	if (c > 255) {
19122eaa94a1Schristos	    /*
19132eaa94a1Schristos	     * The parsing tables all have 256 entries.  If we're supporting
19142eaa94a1Schristos	     * wide characters, we handle them by treating them the same as
19152eaa94a1Schristos	     * printing characters.
19162eaa94a1Schristos	     */
1917d522f475Smrg	    if (sp->parsestate == sp->groundtable) {
1918d522f475Smrg		sp->nextstate = CASE_PRINT;
1919d522f475Smrg	    } else if (sp->parsestate == sos_table) {
1920d522f475Smrg		c &= 0xffff;
1921d522f475Smrg		if (c > 255) {
1922d522f475Smrg		    TRACE(("Found code > 255 while in SOS state: %04X\n", c));
1923d522f475Smrg		    c = '?';
1924d522f475Smrg		}
1925d522f475Smrg	    } else {
1926d522f475Smrg		sp->nextstate = CASE_GROUND_STATE;
1927d522f475Smrg	    }
1928d522f475Smrg	} else
1929d522f475Smrg#endif
1930d522f475Smrg	    sp->nextstate = sp->parsestate[E2A(c)];
1931d522f475Smrg
1932d522f475Smrg#if OPT_BROKEN_OSC
1933d522f475Smrg	/*
1934d522f475Smrg	 * Linux console palette escape sequences start with an OSC, but do
1935d522f475Smrg	 * not terminate correctly.  Some scripts do not check before writing
1936d522f475Smrg	 * them, making xterm appear to hang (it's awaiting a valid string
1937d522f475Smrg	 * terminator).  Just ignore these if we see them - there's no point
1938d522f475Smrg	 * in emulating bad code.
1939d522f475Smrg	 */
1940d522f475Smrg	if (screen->brokenLinuxOSC
1941d522f475Smrg	    && sp->parsestate == sos_table) {
1942956cc18dSsnj	    if (sp->string_used) {
1943956cc18dSsnj		switch (sp->string_area[0]) {
1944d522f475Smrg		case 'P':
1945956cc18dSsnj		    if (sp->string_used <= 7)
1946d522f475Smrg			break;
1947d522f475Smrg		    /* FALLTHRU */
1948d522f475Smrg		case 'R':
194920d2c4d2Smrg		    illegal_parse(xw, c, sp);
1950d522f475Smrg		    TRACE(("Reset to ground state (brokenLinuxOSC)\n"));
1951d522f475Smrg		    break;
1952d522f475Smrg		}
1953d522f475Smrg	    }
1954d522f475Smrg	}
1955d522f475Smrg#endif
1956d522f475Smrg
1957d522f475Smrg#if OPT_BROKEN_ST
1958d522f475Smrg	/*
1959d522f475Smrg	 * Before patch #171, carriage control embedded within an OSC string
1960d522f475Smrg	 * would terminate it.  Some (buggy, of course) applications rely on
1961d522f475Smrg	 * this behavior.  Accommodate them by allowing one to compile xterm
1962d522f475Smrg	 * and emulate the old behavior.
1963d522f475Smrg	 */
1964d522f475Smrg	if (screen->brokenStringTerm
1965d522f475Smrg	    && sp->parsestate == sos_table
1966d522f475Smrg	    && c < 32) {
1967d522f475Smrg	    switch (c) {
196820d2c4d2Smrg	    case ANSI_EOT:	/* FALLTHRU */
196920d2c4d2Smrg	    case ANSI_BS:	/* FALLTHRU */
197020d2c4d2Smrg	    case ANSI_HT:	/* FALLTHRU */
197120d2c4d2Smrg	    case ANSI_LF:	/* FALLTHRU */
197220d2c4d2Smrg	    case ANSI_VT:	/* FALLTHRU */
197320d2c4d2Smrg	    case ANSI_FF:	/* FALLTHRU */
197420d2c4d2Smrg	    case ANSI_CR:	/* FALLTHRU */
197520d2c4d2Smrg	    case ANSI_SO:	/* FALLTHRU */
197620d2c4d2Smrg	    case ANSI_SI:	/* FALLTHRU */
197720d2c4d2Smrg	    case ANSI_XON:	/* FALLTHRU */
197820d2c4d2Smrg	    case ANSI_CAN:
197920d2c4d2Smrg		illegal_parse(xw, c, sp);
1980d522f475Smrg		TRACE(("Reset to ground state (brokenStringTerm)\n"));
1981d522f475Smrg		break;
1982d522f475Smrg	    }
1983d522f475Smrg	}
1984d522f475Smrg#endif
1985d522f475Smrg
1986d522f475Smrg#if OPT_C1_PRINT
1987d522f475Smrg	/*
1988d522f475Smrg	 * This is not completely foolproof, but will allow an application
1989d522f475Smrg	 * with values in the C1 range to use them as printable characters,
1990d522f475Smrg	 * provided that they are not intermixed with an escape sequence.
1991d522f475Smrg	 */
1992d522f475Smrg	if (screen->c1_printable
1993d522f475Smrg	    && (c >= 128 && c < 160)) {
1994d522f475Smrg	    sp->nextstate = (sp->parsestate == esc_table
1995d522f475Smrg			     ? CASE_ESC_IGNORE
1996d522f475Smrg			     : sp->parsestate[E2A(160)]);
1997d522f475Smrg	}
1998d522f475Smrg#endif
1999d522f475Smrg
2000d522f475Smrg#if OPT_WIDE_CHARS
2001d522f475Smrg	/*
2002d522f475Smrg	 * If we have a C1 code and the c1_printable flag is not set, simply
2003d522f475Smrg	 * ignore it when it was translated from UTF-8.  That is because the
2004d522f475Smrg	 * value could not have been present as-is in the UTF-8.
2005d522f475Smrg	 *
2006d522f475Smrg	 * To see that CASE_IGNORE is a consistent value, note that it is
2007d522f475Smrg	 * always used for NUL and other uninteresting C0 controls.
2008d522f475Smrg	 */
2009d522f475Smrg#if OPT_C1_PRINT
2010d522f475Smrg	if (!screen->c1_printable)
2011d522f475Smrg#endif
2012d522f475Smrg	    if (screen->wide_chars
2013d522f475Smrg		&& (c >= 128 && c < 160)) {
2014d522f475Smrg		sp->nextstate = CASE_IGNORE;
2015d522f475Smrg	    }
2016d522f475Smrg
2017d522f475Smrg	/*
2018d522f475Smrg	 * If this character is a different width than the last one, put the
2019d522f475Smrg	 * previous text into the buffer and draw it now.
2020d522f475Smrg	 */
2021956cc18dSsnj	this_is_wide = isWide((int) c);
2022956cc18dSsnj	if (this_is_wide != sp->last_was_wide) {
2023d522f475Smrg	    WriteNow();
2024d522f475Smrg	}
2025d522f475Smrg#endif
2026d522f475Smrg
2027d522f475Smrg	/*
2028d522f475Smrg	 * Accumulate string for printable text.  This may be 8/16-bit
2029d522f475Smrg	 * characters.
2030d522f475Smrg	 */
2031d522f475Smrg	if (sp->nextstate == CASE_PRINT) {
2032956cc18dSsnj	    SafeAlloc(IChar, sp->print_area, sp->print_used, sp->print_size);
2033d522f475Smrg	    if (new_string == 0) {
20340bd37d32Smrg		xtermWarning("Cannot allocate %lu bytes for printable text\n",
20350bd37d32Smrg			     (unsigned long) new_length);
2036d522f475Smrg		continue;
2037d522f475Smrg	    }
2038d522f475Smrg#if OPT_VT52_MODE
2039d522f475Smrg	    /*
2040d522f475Smrg	     * Strip output text to 7-bits for VT52.  We should do this for
2041d522f475Smrg	     * VT100 also (which is a 7-bit device), but xterm has been
2042d522f475Smrg	     * doing this for so long we shouldn't change this behavior.
2043d522f475Smrg	     */
2044d522f475Smrg	    if (screen->vtXX_level < 1)
2045d522f475Smrg		c &= 0x7f;
2046d522f475Smrg#endif
2047956cc18dSsnj	    sp->print_area = new_string;
2048956cc18dSsnj	    sp->print_size = new_length;
2049956cc18dSsnj	    sp->print_area[sp->print_used++] = (IChar) c;
20502eaa94a1Schristos	    sp->lastchar = thischar = (int) c;
2051d522f475Smrg#if OPT_WIDE_CHARS
2052956cc18dSsnj	    sp->last_was_wide = this_is_wide;
2053d522f475Smrg#endif
2054d522f475Smrg	    if (morePtyData(screen, VTbuffer)) {
2055d522f475Smrg		continue;
2056d522f475Smrg	    }
2057d522f475Smrg	}
2058d522f475Smrg
2059d522f475Smrg	if (sp->nextstate == CASE_PRINT
2060956cc18dSsnj	    || (laststate == CASE_PRINT && sp->print_used)) {
2061d522f475Smrg	    WriteNow();
2062d522f475Smrg	}
2063d522f475Smrg
2064d522f475Smrg	/*
2065d522f475Smrg	 * Accumulate string for APC, DCS, PM, OSC, SOS controls
2066d522f475Smrg	 * This should always be 8-bit characters.
2067d522f475Smrg	 */
2068d522f475Smrg	if (sp->parsestate == sos_table) {
2069956cc18dSsnj	    SafeAlloc(Char, sp->string_area, sp->string_used, sp->string_size);
2070d522f475Smrg	    if (new_string == 0) {
20710bd37d32Smrg		xtermWarning("Cannot allocate %lu bytes for string mode %d\n",
20720bd37d32Smrg			     (unsigned long) new_length, sp->string_mode);
2073d522f475Smrg		continue;
2074d522f475Smrg	    }
2075d522f475Smrg#if OPT_WIDE_CHARS
2076d522f475Smrg	    /*
2077d522f475Smrg	     * We cannot display codes above 255, but let's try to
2078d522f475Smrg	     * accommodate the application a little by not aborting the
2079d522f475Smrg	     * string.
2080d522f475Smrg	     */
2081d522f475Smrg	    if ((c & 0xffff) > 255) {
2082d522f475Smrg		sp->nextstate = CASE_PRINT;
2083d522f475Smrg		c = '?';
2084d522f475Smrg	    }
2085d522f475Smrg#endif
2086956cc18dSsnj	    sp->string_area = new_string;
2087956cc18dSsnj	    sp->string_size = new_length;
2088956cc18dSsnj	    sp->string_area[(sp->string_used)++] = CharOf(c);
2089d522f475Smrg	} else if (sp->parsestate != esc_table) {
2090d522f475Smrg	    /* if we were accumulating, we're not any more */
2091d522f475Smrg	    sp->string_mode = 0;
2092956cc18dSsnj	    sp->string_used = 0;
2093d522f475Smrg	}
2094d522f475Smrg
20950bd37d32Smrg	DumpParams();
2096e0a2b6dfSmrg	TRACE(("parse %04X -> %d %s (used=%lu)\n",
2097e0a2b6dfSmrg	       c, sp->nextstate,
2098e0a2b6dfSmrg	       which_table(sp->parsestate),
2099e0a2b6dfSmrg	       (unsigned long) sp->string_used));
2100d522f475Smrg
21010bd37d32Smrg	/*
21020bd37d32Smrg	 * If the parameter list has subparameters (tokens separated by ":")
21030bd37d32Smrg	 * reject any controls that do not accept subparameters.
21040bd37d32Smrg	 */
21050bd37d32Smrg	if (parms.has_subparams) {
21060bd37d32Smrg	    switch (sp->nextstate) {
21070bd37d32Smrg	    case CASE_GROUND_STATE:
21080bd37d32Smrg	    case CASE_CSI_IGNORE:
21090bd37d32Smrg		/* FALLTHRU */
21100bd37d32Smrg
21110bd37d32Smrg	    case CASE_ESC_DIGIT:
21120bd37d32Smrg	    case CASE_ESC_SEMI:
21130bd37d32Smrg	    case CASE_ESC_COLON:
21140bd37d32Smrg		/* these states are required to parse parameter lists */
21150bd37d32Smrg		break;
21160bd37d32Smrg
21170bd37d32Smrg	    case CASE_SGR:
21180bd37d32Smrg		TRACE(("...possible subparam usage\n"));
21190bd37d32Smrg		break;
21200bd37d32Smrg
21210bd37d32Smrg	    case CASE_CSI_DEC_DOLLAR_STATE:
21220bd37d32Smrg	    case CASE_CSI_DOLLAR_STATE:
21230bd37d32Smrg	    case CASE_CSI_EX_STATE:
21240bd37d32Smrg	    case CASE_CSI_QUOTE_STATE:
21250bd37d32Smrg	    case CASE_CSI_SPACE_STATE:
21260bd37d32Smrg	    case CASE_CSI_STAR_STATE:
21270bd37d32Smrg	    case CASE_CSI_TICK_STATE:
21280bd37d32Smrg	    case CASE_DEC2_STATE:
21290bd37d32Smrg	    case CASE_DEC3_STATE:
21300bd37d32Smrg	    case CASE_DEC_STATE:
21310bd37d32Smrg		/* use this branch when we do not yet have the final character */
21320bd37d32Smrg		TRACE(("...unexpected subparam usage\n"));
21330bd37d32Smrg		ParamsDone();
21340bd37d32Smrg		sp->nextstate = CASE_CSI_IGNORE;
21350bd37d32Smrg		break;
21360bd37d32Smrg
21370bd37d32Smrg	    default:
21380bd37d32Smrg		/* use this branch for cases where we have the final character
21390bd37d32Smrg		 * in the table that processed the parameter list.
21400bd37d32Smrg		 */
21410bd37d32Smrg		TRACE(("...unexpected subparam usage\n"));
21420bd37d32Smrg		ResetState(sp);
21430bd37d32Smrg		continue;
21440bd37d32Smrg	    }
21450bd37d32Smrg	}
21460bd37d32Smrg
21470bd37d32Smrg	if (xw->misc.palette_changed) {
21480bd37d32Smrg	    repaintWhenPaletteChanged(xw, sp);
21490bd37d32Smrg	}
21500bd37d32Smrg
2151d522f475Smrg	switch (sp->nextstate) {
2152d522f475Smrg	case CASE_PRINT:
2153d522f475Smrg	    TRACE(("CASE_PRINT - printable characters\n"));
2154d522f475Smrg	    break;
2155d522f475Smrg
2156d522f475Smrg	case CASE_GROUND_STATE:
2157d522f475Smrg	    TRACE(("CASE_GROUND_STATE - exit ignore mode\n"));
215820d2c4d2Smrg	    ResetState(sp);
2159d522f475Smrg	    break;
2160d522f475Smrg
2161d522f475Smrg	case CASE_IGNORE:
2162d522f475Smrg	    TRACE(("CASE_IGNORE - Ignore character %02X\n", c));
2163d522f475Smrg	    break;
2164d522f475Smrg
2165d522f475Smrg	case CASE_ENQ:
2166d522f475Smrg	    TRACE(("CASE_ENQ - answerback\n"));
2167d522f475Smrg	    for (count = 0; screen->answer_back[count] != 0; count++)
2168d522f475Smrg		unparseputc(xw, screen->answer_back[count]);
2169d522f475Smrg	    unparse_end(xw);
2170d522f475Smrg	    break;
2171d522f475Smrg
2172d522f475Smrg	case CASE_BELL:
2173d522f475Smrg	    TRACE(("CASE_BELL - bell\n"));
2174d522f475Smrg	    if (sp->string_mode == ANSI_OSC) {
2175956cc18dSsnj		if (sp->string_used)
2176956cc18dSsnj		    sp->string_area[--(sp->string_used)] = '\0';
2177956cc18dSsnj		do_osc(xw, sp->string_area, sp->string_used, (int) c);
217820d2c4d2Smrg		ResetState(sp);
2179d522f475Smrg	    } else {
2180d522f475Smrg		/* bell */
218120d2c4d2Smrg		Bell(xw, XkbBI_TerminalBell, 0);
2182d522f475Smrg	    }
2183d522f475Smrg	    break;
2184d522f475Smrg
2185d522f475Smrg	case CASE_BS:
2186d522f475Smrg	    TRACE(("CASE_BS - backspace\n"));
2187d522f475Smrg	    CursorBack(xw, 1);
2188d522f475Smrg	    break;
2189d522f475Smrg
2190d522f475Smrg	case CASE_CR:
21910bd37d32Smrg	    TRACE(("CASE_CR\n"));
21920bd37d32Smrg	    CarriageReturn(xw);
2193d522f475Smrg	    break;
2194d522f475Smrg
2195d522f475Smrg	case CASE_ESC:
2196d522f475Smrg	    if_OPT_VT52_MODE(screen, {
2197d522f475Smrg		sp->parsestate = vt52_esc_table;
2198d522f475Smrg		break;
2199d522f475Smrg	    });
2200d522f475Smrg	    sp->parsestate = esc_table;
2201d522f475Smrg	    break;
2202d522f475Smrg
2203d522f475Smrg#if OPT_VT52_MODE
2204d522f475Smrg	case CASE_VT52_CUP:
2205d522f475Smrg	    TRACE(("CASE_VT52_CUP - VT52 cursor addressing\n"));
2206d522f475Smrg	    sp->vt52_cup = True;
22070bd37d32Smrg	    InitParams();
2208d522f475Smrg	    break;
2209d522f475Smrg
2210d522f475Smrg	case CASE_VT52_IGNORE:
2211d522f475Smrg	    TRACE(("CASE_VT52_IGNORE - VT52 ignore-character\n"));
2212d522f475Smrg	    sp->parsestate = vt52_ignore_table;
2213d522f475Smrg	    break;
2214d522f475Smrg#endif
2215d522f475Smrg
2216d522f475Smrg	case CASE_VMOT:
22170bd37d32Smrg	    TRACE(("CASE_VMOT\n"));
2218d522f475Smrg	    /*
2219d522f475Smrg	     * form feed, line feed, vertical tab
2220d522f475Smrg	     */
2221956cc18dSsnj	    xtermAutoPrint(xw, c);
2222d522f475Smrg	    xtermIndex(xw, 1);
2223d522f475Smrg	    if (xw->flags & LINEFEED)
22240bd37d32Smrg		CarriageReturn(xw);
2225d522f475Smrg	    else
2226d522f475Smrg		do_xevents();
2227d522f475Smrg	    break;
2228d522f475Smrg
2229d522f475Smrg	case CASE_CBT:
22300bd37d32Smrg	    TRACE(("CASE_CBT\n"));
2231d522f475Smrg	    /* cursor backward tabulation */
22320bd37d32Smrg	    count = one_if_default(0);
2233d522f475Smrg	    while ((count-- > 0)
2234d522f475Smrg		   && (TabToPrevStop(xw))) ;
223520d2c4d2Smrg	    ResetState(sp);
2236d522f475Smrg	    break;
2237d522f475Smrg
2238d522f475Smrg	case CASE_CHT:
22390bd37d32Smrg	    TRACE(("CASE_CHT\n"));
2240d522f475Smrg	    /* cursor forward tabulation */
22410bd37d32Smrg	    count = one_if_default(0);
2242d522f475Smrg	    while ((count-- > 0)
2243d522f475Smrg		   && (TabToNextStop(xw))) ;
224420d2c4d2Smrg	    ResetState(sp);
2245d522f475Smrg	    break;
2246d522f475Smrg
2247d522f475Smrg	case CASE_TAB:
2248d522f475Smrg	    /* tab */
2249d522f475Smrg	    TabToNextStop(xw);
2250d522f475Smrg	    break;
2251d522f475Smrg
2252d522f475Smrg	case CASE_SI:
2253d522f475Smrg	    screen->curgl = 0;
2254d522f475Smrg	    if_OPT_VT52_MODE(screen, {
225520d2c4d2Smrg		ResetState(sp);
2256d522f475Smrg	    });
2257d522f475Smrg	    break;
2258d522f475Smrg
2259d522f475Smrg	case CASE_SO:
2260d522f475Smrg	    screen->curgl = 1;
2261d522f475Smrg	    if_OPT_VT52_MODE(screen, {
226220d2c4d2Smrg		ResetState(sp);
2263d522f475Smrg	    });
2264d522f475Smrg	    break;
2265d522f475Smrg
2266d522f475Smrg	case CASE_DECDHL:
2267d522f475Smrg	    xterm_DECDHL(xw, c == '3');
226820d2c4d2Smrg	    ResetState(sp);
2269d522f475Smrg	    break;
2270d522f475Smrg
2271d522f475Smrg	case CASE_DECSWL:
2272d522f475Smrg	    xterm_DECSWL(xw);
227320d2c4d2Smrg	    ResetState(sp);
2274d522f475Smrg	    break;
2275d522f475Smrg
2276d522f475Smrg	case CASE_DECDWL:
2277d522f475Smrg	    xterm_DECDWL(xw);
227820d2c4d2Smrg	    ResetState(sp);
2279d522f475Smrg	    break;
2280d522f475Smrg
2281d522f475Smrg	case CASE_SCR_STATE:
2282d522f475Smrg	    /* enter scr state */
2283d522f475Smrg	    sp->parsestate = scrtable;
2284d522f475Smrg	    break;
2285d522f475Smrg
2286d522f475Smrg	case CASE_SCS0_STATE:
2287d522f475Smrg	    /* enter scs state 0 */
22882eaa94a1Schristos	    select_charset(sp, 0, 94);
2289d522f475Smrg	    break;
2290d522f475Smrg
2291d522f475Smrg	case CASE_SCS1_STATE:
2292d522f475Smrg	    /* enter scs state 1 */
22932eaa94a1Schristos	    select_charset(sp, 1, 94);
2294d522f475Smrg	    break;
2295d522f475Smrg
2296d522f475Smrg	case CASE_SCS2_STATE:
2297d522f475Smrg	    /* enter scs state 2 */
22982eaa94a1Schristos	    select_charset(sp, 2, 94);
2299d522f475Smrg	    break;
2300d522f475Smrg
2301d522f475Smrg	case CASE_SCS3_STATE:
2302d522f475Smrg	    /* enter scs state 3 */
23032eaa94a1Schristos	    select_charset(sp, 3, 94);
23042eaa94a1Schristos	    break;
23052eaa94a1Schristos
23062eaa94a1Schristos	case CASE_SCS1A_STATE:
23072eaa94a1Schristos	    /* enter scs state 1 */
23082eaa94a1Schristos	    select_charset(sp, 1, 96);
23092eaa94a1Schristos	    break;
23102eaa94a1Schristos
23112eaa94a1Schristos	case CASE_SCS2A_STATE:
23122eaa94a1Schristos	    /* enter scs state 2 */
23132eaa94a1Schristos	    select_charset(sp, 2, 96);
23142eaa94a1Schristos	    break;
23152eaa94a1Schristos
23162eaa94a1Schristos	case CASE_SCS3A_STATE:
23172eaa94a1Schristos	    /* enter scs state 3 */
23182eaa94a1Schristos	    select_charset(sp, 3, 96);
2319d522f475Smrg	    break;
2320d522f475Smrg
2321d522f475Smrg	case CASE_ESC_IGNORE:
2322d522f475Smrg	    /* unknown escape sequence */
2323d522f475Smrg	    sp->parsestate = eigtable;
2324d522f475Smrg	    break;
2325d522f475Smrg
2326d522f475Smrg	case CASE_ESC_DIGIT:
2327d522f475Smrg	    /* digit in csi or dec mode */
232820d2c4d2Smrg	    if (nparam > 0) {
23290bd37d32Smrg		value = zero_if_default(nparam - 1);
23300bd37d32Smrg		SetParam(nparam - 1, (10 * value) + ((int) c - '0'));
23310bd37d32Smrg		if (GetParam(nparam - 1) > 65535)
23320bd37d32Smrg		    SetParam(nparam - 1, 65535);
233320d2c4d2Smrg		if (sp->parsestate == csi_table)
233420d2c4d2Smrg		    sp->parsestate = csi2_table;
233520d2c4d2Smrg	    }
2336d522f475Smrg	    break;
2337d522f475Smrg
2338d522f475Smrg	case CASE_ESC_SEMI:
2339d522f475Smrg	    /* semicolon in csi or dec mode */
23400bd37d32Smrg	    if (nparam < NPARAM) {
23410bd37d32Smrg		parms.is_sub[nparam] = 0;
23420bd37d32Smrg		SetParam(nparam++, DEFAULT);
23430bd37d32Smrg	    }
2344d522f475Smrg	    if (sp->parsestate == csi_table)
2345d522f475Smrg		sp->parsestate = csi2_table;
2346d522f475Smrg	    break;
2347d522f475Smrg
23480bd37d32Smrg	    /*
23490bd37d32Smrg	     * A _few_ commands accept colon-separated subparameters.
23500bd37d32Smrg	     * Mark the parameter list so that we can exclude (most) bogus
23510bd37d32Smrg	     * commands with simple/fast checks.
23520bd37d32Smrg	     */
23530bd37d32Smrg	case CASE_ESC_COLON:
23540bd37d32Smrg	    if (nparam < NPARAM) {
23550bd37d32Smrg		parms.has_subparams = 1;
23560bd37d32Smrg		if (nparam == 0) {
23570bd37d32Smrg		    parms.is_sub[nparam] = 1;
23580bd37d32Smrg		    SetParam(nparam++, DEFAULT);
23590bd37d32Smrg		} else if (parms.is_sub[nparam - 1] == 0) {
23600bd37d32Smrg		    parms.is_sub[nparam - 1] = 1;
23610bd37d32Smrg		    parms.is_sub[nparam] = 2;
23620bd37d32Smrg		    parms.params[nparam] = 0;
23630bd37d32Smrg		    ++nparam;
23640bd37d32Smrg		} else {
23650bd37d32Smrg		    parms.is_sub[nparam] = 1 + parms.is_sub[nparam - 1];
23660bd37d32Smrg		    parms.params[nparam] = 0;
23670bd37d32Smrg		    ++nparam;
23680bd37d32Smrg		}
23690bd37d32Smrg	    }
23700bd37d32Smrg	    break;
23710bd37d32Smrg
2372d522f475Smrg	case CASE_DEC_STATE:
2373d522f475Smrg	    /* enter dec mode */
2374d522f475Smrg	    sp->parsestate = dec_table;
2375d522f475Smrg	    break;
2376d522f475Smrg
2377d522f475Smrg	case CASE_DEC2_STATE:
2378d522f475Smrg	    /* enter dec2 mode */
2379d522f475Smrg	    sp->parsestate = dec2_table;
2380d522f475Smrg	    break;
2381d522f475Smrg
2382d522f475Smrg	case CASE_DEC3_STATE:
2383d522f475Smrg	    /* enter dec3 mode */
2384d522f475Smrg	    sp->parsestate = dec3_table;
2385d522f475Smrg	    break;
2386d522f475Smrg
2387d522f475Smrg	case CASE_ICH:
2388d522f475Smrg	    TRACE(("CASE_ICH - insert char\n"));
23890bd37d32Smrg	    InsertChar(xw, (unsigned) one_if_default(0));
239020d2c4d2Smrg	    ResetState(sp);
2391d522f475Smrg	    break;
2392d522f475Smrg
2393d522f475Smrg	case CASE_CUU:
2394d522f475Smrg	    TRACE(("CASE_CUU - cursor up\n"));
23950bd37d32Smrg	    CursorUp(screen, one_if_default(0));
239620d2c4d2Smrg	    ResetState(sp);
2397d522f475Smrg	    break;
2398d522f475Smrg
2399d522f475Smrg	case CASE_CUD:
2400d522f475Smrg	    TRACE(("CASE_CUD - cursor down\n"));
24010bd37d32Smrg	    CursorDown(screen, one_if_default(0));
240220d2c4d2Smrg	    ResetState(sp);
2403d522f475Smrg	    break;
2404d522f475Smrg
2405d522f475Smrg	case CASE_CUF:
2406d522f475Smrg	    TRACE(("CASE_CUF - cursor forward\n"));
24070bd37d32Smrg	    CursorForward(xw, one_if_default(0));
240820d2c4d2Smrg	    ResetState(sp);
2409d522f475Smrg	    break;
2410d522f475Smrg
2411d522f475Smrg	case CASE_CUB:
2412d522f475Smrg	    TRACE(("CASE_CUB - cursor backward\n"));
24130bd37d32Smrg	    CursorBack(xw, one_if_default(0));
241420d2c4d2Smrg	    ResetState(sp);
2415d522f475Smrg	    break;
2416d522f475Smrg
2417d522f475Smrg	case CASE_CUP:
2418d522f475Smrg	    TRACE(("CASE_CUP - cursor position\n"));
2419d522f475Smrg	    if_OPT_XMC_GLITCH(screen, {
2420d522f475Smrg		Jump_XMC(xw);
2421d522f475Smrg	    });
24220bd37d32Smrg	    CursorSet(screen, one_if_default(0) - 1, one_if_default(1) - 1, xw->flags);
242320d2c4d2Smrg	    ResetState(sp);
2424d522f475Smrg	    break;
2425d522f475Smrg
2426d522f475Smrg	case CASE_VPA:
24270bd37d32Smrg	    TRACE(("CASE_VPA - vertical position absolute\n"));
24280bd37d32Smrg	    CursorSet(screen, one_if_default(0) - 1, CursorCol(xw), xw->flags);
242920d2c4d2Smrg	    ResetState(sp);
2430d522f475Smrg	    break;
2431d522f475Smrg
2432d522f475Smrg	case CASE_HPA:
24330bd37d32Smrg	    TRACE(("CASE_HPA - horizontal position absolute\n"));
24340bd37d32Smrg	    CursorSet(screen, CursorRow(xw), one_if_default(0) - 1, xw->flags);
24350bd37d32Smrg	    ResetState(sp);
24360bd37d32Smrg	    break;
24370bd37d32Smrg
24380bd37d32Smrg	case CASE_VPR:
24390bd37d32Smrg	    TRACE(("CASE_VPR - vertical position relative\n"));
24400bd37d32Smrg	    CursorSet(screen,
24410bd37d32Smrg		      CursorRow(xw) + one_if_default(0),
24420bd37d32Smrg		      CursorCol(xw),
24430bd37d32Smrg		      xw->flags);
24440bd37d32Smrg	    ResetState(sp);
24450bd37d32Smrg	    break;
24460bd37d32Smrg
24470bd37d32Smrg	case CASE_HPR:
24480bd37d32Smrg	    TRACE(("CASE_HPR - horizontal position relative\n"));
24490bd37d32Smrg	    CursorSet(screen,
24500bd37d32Smrg		      CursorRow(xw),
24510bd37d32Smrg		      CursorCol(xw) + one_if_default(0),
24520bd37d32Smrg		      xw->flags);
245320d2c4d2Smrg	    ResetState(sp);
2454d522f475Smrg	    break;
2455d522f475Smrg
2456d522f475Smrg	case CASE_HP_BUGGY_LL:
2457d522f475Smrg	    TRACE(("CASE_HP_BUGGY_LL\n"));
2458d522f475Smrg	    /* Some HP-UX applications have the bug that they
2459d522f475Smrg	       assume ESC F goes to the lower left corner of
2460d522f475Smrg	       the screen, regardless of what terminfo says. */
2461d522f475Smrg	    if (screen->hp_ll_bc)
2462d522f475Smrg		CursorSet(screen, screen->max_row, 0, xw->flags);
246320d2c4d2Smrg	    ResetState(sp);
2464d522f475Smrg	    break;
2465d522f475Smrg
2466d522f475Smrg	case CASE_ED:
2467d522f475Smrg	    TRACE(("CASE_ED - erase display\n"));
24680bd37d32Smrg	    do_cd_xtra_scroll(xw);
24690bd37d32Smrg	    do_erase_display(xw, zero_if_default(0), OFF_PROTECT);
247020d2c4d2Smrg	    ResetState(sp);
2471d522f475Smrg	    break;
2472d522f475Smrg
2473d522f475Smrg	case CASE_EL:
2474d522f475Smrg	    TRACE(("CASE_EL - erase line\n"));
24750bd37d32Smrg	    do_erase_line(xw, zero_if_default(0), OFF_PROTECT);
247620d2c4d2Smrg	    ResetState(sp);
2477d522f475Smrg	    break;
2478d522f475Smrg
2479d522f475Smrg	case CASE_ECH:
2480d522f475Smrg	    TRACE(("CASE_ECH - erase char\n"));
2481d522f475Smrg	    /* ECH */
24820bd37d32Smrg	    ClearRight(xw, one_if_default(0));
248320d2c4d2Smrg	    ResetState(sp);
2484d522f475Smrg	    break;
2485d522f475Smrg
2486d522f475Smrg	case CASE_IL:
2487d522f475Smrg	    TRACE(("CASE_IL - insert line\n"));
24880bd37d32Smrg	    set_cur_col(screen, ScrnLeftMargin(xw));
24890bd37d32Smrg	    InsertLine(xw, one_if_default(0));
249020d2c4d2Smrg	    ResetState(sp);
2491d522f475Smrg	    break;
2492d522f475Smrg
2493d522f475Smrg	case CASE_DL:
2494d522f475Smrg	    TRACE(("CASE_DL - delete line\n"));
24950bd37d32Smrg	    set_cur_col(screen, ScrnLeftMargin(xw));
24960bd37d32Smrg	    DeleteLine(xw, one_if_default(0));
249720d2c4d2Smrg	    ResetState(sp);
2498d522f475Smrg	    break;
2499d522f475Smrg
2500d522f475Smrg	case CASE_DCH:
2501d522f475Smrg	    TRACE(("CASE_DCH - delete char\n"));
25020bd37d32Smrg	    DeleteChar(xw, (unsigned) one_if_default(0));
250320d2c4d2Smrg	    ResetState(sp);
2504d522f475Smrg	    break;
2505d522f475Smrg
2506d522f475Smrg	case CASE_TRACK_MOUSE:
2507d522f475Smrg	    /*
2508d522f475Smrg	     * A single parameter other than zero is always scroll-down.
2509d522f475Smrg	     * A zero-parameter is used to reset the mouse mode, and is
2510d522f475Smrg	     * not useful for scrolling anyway.
2511d522f475Smrg	     */
25120bd37d32Smrg	    if (nparam > 1 || GetParam(0) == 0) {
2513d522f475Smrg		CELL start;
2514d522f475Smrg
2515d522f475Smrg		TRACE(("CASE_TRACK_MOUSE\n"));
2516d522f475Smrg		/* Track mouse as long as in window and between
2517d522f475Smrg		 * specified rows
2518d522f475Smrg		 */
251920d2c4d2Smrg		start.row = one_if_default(2) - 1;
25200bd37d32Smrg		start.col = GetParam(1) - 1;
2521d522f475Smrg		TrackMouse(xw,
25220bd37d32Smrg			   GetParam(0),
2523d522f475Smrg			   &start,
25240bd37d32Smrg			   GetParam(3) - 1, GetParam(4) - 2);
2525d522f475Smrg	    } else {
2526d522f475Smrg		TRACE(("CASE_SD - scroll down\n"));
2527d522f475Smrg		/* SD */
25280bd37d32Smrg		RevScroll(xw, one_if_default(0));
2529d522f475Smrg		do_xevents();
2530d522f475Smrg	    }
253120d2c4d2Smrg	    ResetState(sp);
2532d522f475Smrg	    break;
2533d522f475Smrg
2534d522f475Smrg	case CASE_DECID:
2535d522f475Smrg	    TRACE(("CASE_DECID\n"));
2536d522f475Smrg	    if_OPT_VT52_MODE(screen, {
2537d522f475Smrg		unparseputc(xw, ANSI_ESC);
2538d522f475Smrg		unparseputc(xw, '/');
2539d522f475Smrg		unparseputc(xw, 'Z');
2540d522f475Smrg		unparse_end(xw);
254120d2c4d2Smrg		ResetState(sp);
2542d522f475Smrg		break;
2543d522f475Smrg	    });
25440bd37d32Smrg	    SetParam(0, DEFAULT);	/* Default ID parameter */
2545d522f475Smrg	    /* FALLTHRU */
2546d522f475Smrg	case CASE_DA1:
2547d522f475Smrg	    TRACE(("CASE_DA1\n"));
25480bd37d32Smrg	    if (GetParam(0) <= 0) {	/* less than means DEFAULT */
2549d522f475Smrg		count = 0;
25500bd37d32Smrg		init_reply(ANSI_CSI);
2551d522f475Smrg		reply.a_pintro = '?';
2552d522f475Smrg
25530bd37d32Smrg		/*
25540bd37d32Smrg		 * The first parameter corresponds to the highest operating
25550bd37d32Smrg		 * level (i.e., service level) of the emulation.  A DEC
25560bd37d32Smrg		 * terminal can be setup to respond with a different DA
25570bd37d32Smrg		 * response, but there's no control sequence that modifies
25580bd37d32Smrg		 * this.  We set it via a resource.
2559d522f475Smrg		 */
2560d522f475Smrg		if (screen->terminal_id < 200) {
2561d522f475Smrg		    switch (screen->terminal_id) {
2562e0a2b6dfSmrg		    case 125:
2563e0a2b6dfSmrg			reply.a_param[count++] = 12;	/* VT125 */
2564e0a2b6dfSmrg			reply.a_param[count++] = 0 | 2 | 0;	/* no STP, AVO, no GPO (ReGIS) */
2565e0a2b6dfSmrg			reply.a_param[count++] = 0;	/* no printer */
2566e0a2b6dfSmrg			reply.a_param[count++] = XTERM_PATCH;	/* ROM version */
2567e0a2b6dfSmrg			break;
2568d522f475Smrg		    case 102:
2569d522f475Smrg			reply.a_param[count++] = 6;	/* VT102 */
2570d522f475Smrg			break;
2571d522f475Smrg		    case 101:
2572d522f475Smrg			reply.a_param[count++] = 1;	/* VT101 */
2573d522f475Smrg			reply.a_param[count++] = 0;	/* no options */
2574d522f475Smrg			break;
2575d522f475Smrg		    default:	/* VT100 */
2576d522f475Smrg			reply.a_param[count++] = 1;	/* VT100 */
2577e0a2b6dfSmrg			reply.a_param[count++] = 0 | 2 | 0;	/* no STP, AVO, no GPO (ReGIS) */
2578d522f475Smrg			break;
2579d522f475Smrg		    }
2580d522f475Smrg		} else {
25812eaa94a1Schristos		    reply.a_param[count++] = (ParmType) (60
25822eaa94a1Schristos							 + screen->terminal_id
25832eaa94a1Schristos							 / 100);
2584d522f475Smrg		    reply.a_param[count++] = 1;		/* 132-columns */
2585d522f475Smrg		    reply.a_param[count++] = 2;		/* printer */
2586e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
2587e0a2b6dfSmrg		    if (screen->terminal_id == 240 ||
2588e0a2b6dfSmrg			screen->terminal_id == 241 ||
2589e0a2b6dfSmrg			screen->terminal_id == 330 ||
2590e0a2b6dfSmrg			screen->terminal_id == 340) {
2591e0a2b6dfSmrg			reply.a_param[count++] = 3;	/* ReGIS graphics */
2592e0a2b6dfSmrg			reply.a_param[count++] = 4;	/* sixel graphics */
2593e0a2b6dfSmrg		    }
2594e0a2b6dfSmrg#endif
2595d522f475Smrg		    reply.a_param[count++] = 6;		/* selective-erase */
2596d522f475Smrg#if OPT_SUNPC_KBD
2597d522f475Smrg		    if (xw->keyboard.type == keyboardIsVT220)
2598d522f475Smrg#endif
2599d522f475Smrg			reply.a_param[count++] = 8;	/* user-defined-keys */
2600d522f475Smrg		    reply.a_param[count++] = 9;		/* national replacement charsets */
2601d522f475Smrg		    reply.a_param[count++] = 15;	/* technical characters */
26020bd37d32Smrg		    if (screen->terminal_id >= 400) {
26030bd37d32Smrg			reply.a_param[count++] = 18;	/* windowing capability */
26040bd37d32Smrg			reply.a_param[count++] = 21;	/* horizontal scrolling */
26050bd37d32Smrg		    }
2606d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2607d522f475Smrg			reply.a_param[count++] = 22;	/* ANSI color, VT525 */
2608d522f475Smrg		    });
2609d522f475Smrg#if OPT_DEC_LOCATOR
2610d522f475Smrg		    reply.a_param[count++] = 29;	/* ANSI text locator */
2611d522f475Smrg#endif
2612d522f475Smrg		}
26132eaa94a1Schristos		reply.a_nparam = (ParmType) count;
2614d522f475Smrg		reply.a_inters = 0;
2615d522f475Smrg		reply.a_final = 'c';
2616d522f475Smrg		unparseseq(xw, &reply);
2617d522f475Smrg	    }
261820d2c4d2Smrg	    ResetState(sp);
2619d522f475Smrg	    break;
2620d522f475Smrg
2621d522f475Smrg	case CASE_DA2:
2622d522f475Smrg	    TRACE(("CASE_DA2\n"));
26230bd37d32Smrg	    if (GetParam(0) <= 0) {	/* less than means DEFAULT */
2624d522f475Smrg		count = 0;
26250bd37d32Smrg		init_reply(ANSI_CSI);
2626d522f475Smrg		reply.a_pintro = '>';
2627d522f475Smrg
26280bd37d32Smrg		if (screen->terminal_id >= 200) {
26290bd37d32Smrg		    switch (screen->terminal_id) {
26300bd37d32Smrg		    case 220:
26310bd37d32Smrg		    default:
26320bd37d32Smrg			reply.a_param[count++] = 1;	/* VT220 */
26330bd37d32Smrg			break;
26340bd37d32Smrg		    case 240:
26350bd37d32Smrg			/* http://www.decuslib.com/DECUS/vax87a/gendyn/vt200_kind.lis */
26360bd37d32Smrg			reply.a_param[count++] = 2;	/* VT240 */
26370bd37d32Smrg			break;
26380bd37d32Smrg		    case 320:
26390bd37d32Smrg			/* http://www.vt100.net/docs/vt320-uu/appendixe.html */
26400bd37d32Smrg			reply.a_param[count++] = 24;	/* VT320 */
26410bd37d32Smrg			break;
26420bd37d32Smrg		    case 330:
26430bd37d32Smrg			reply.a_param[count++] = 18;	/* VT330 */
26440bd37d32Smrg			break;
26450bd37d32Smrg		    case 340:
26460bd37d32Smrg			reply.a_param[count++] = 19;	/* VT340 */
26470bd37d32Smrg			break;
26480bd37d32Smrg		    case 420:
26490bd37d32Smrg			reply.a_param[count++] = 41;	/* VT420 */
26500bd37d32Smrg			break;
26510bd37d32Smrg		    case 510:
26520bd37d32Smrg			/* http://www.vt100.net/docs/vt510-rm/DA2 */
26530bd37d32Smrg			reply.a_param[count++] = 61;	/* VT510 */
26540bd37d32Smrg			break;
26550bd37d32Smrg		    case 520:
26560bd37d32Smrg			reply.a_param[count++] = 64;	/* VT520 */
26570bd37d32Smrg			break;
26580bd37d32Smrg		    case 525:
26590bd37d32Smrg			reply.a_param[count++] = 65;	/* VT525 */
26600bd37d32Smrg			break;
26610bd37d32Smrg		    }
26620bd37d32Smrg		} else {
2663d522f475Smrg		    reply.a_param[count++] = 0;		/* VT100 (nonstandard) */
26640bd37d32Smrg		}
2665d522f475Smrg		reply.a_param[count++] = XTERM_PATCH;	/* Version */
2666d522f475Smrg		reply.a_param[count++] = 0;	/* options (none) */
26672eaa94a1Schristos		reply.a_nparam = (ParmType) count;
2668d522f475Smrg		reply.a_inters = 0;
2669d522f475Smrg		reply.a_final = 'c';
2670d522f475Smrg		unparseseq(xw, &reply);
2671d522f475Smrg	    }
267220d2c4d2Smrg	    ResetState(sp);
2673d522f475Smrg	    break;
2674d522f475Smrg
2675d522f475Smrg	case CASE_DECRPTUI:
2676d522f475Smrg	    TRACE(("CASE_DECRPTUI\n"));
26770bd37d32Smrg	    if ((screen->vtXX_level >= 4)
26780bd37d32Smrg		&& (GetParam(0) <= 0)) {	/* less than means DEFAULT */
2679d522f475Smrg		unparseputc1(xw, ANSI_DCS);
2680d522f475Smrg		unparseputc(xw, '!');
2681d522f475Smrg		unparseputc(xw, '|');
2682d522f475Smrg		unparseputc(xw, '0');
2683d522f475Smrg		unparseputc1(xw, ANSI_ST);
2684d522f475Smrg		unparse_end(xw);
2685d522f475Smrg	    }
268620d2c4d2Smrg	    ResetState(sp);
2687d522f475Smrg	    break;
2688d522f475Smrg
2689d522f475Smrg	case CASE_TBC:
2690d522f475Smrg	    TRACE(("CASE_TBC - tab clear\n"));
26910bd37d32Smrg	    if ((value = GetParam(0)) <= 0)	/* less than means default */
2692d522f475Smrg		TabClear(xw->tabs, screen->cur_col);
26930bd37d32Smrg	    else if (value == 3)
2694d522f475Smrg		TabZonk(xw->tabs);
269520d2c4d2Smrg	    ResetState(sp);
2696d522f475Smrg	    break;
2697d522f475Smrg
2698d522f475Smrg	case CASE_SET:
2699d522f475Smrg	    TRACE(("CASE_SET - set mode\n"));
2700d522f475Smrg	    ansi_modes(xw, bitset);
270120d2c4d2Smrg	    ResetState(sp);
2702d522f475Smrg	    break;
2703d522f475Smrg
2704d522f475Smrg	case CASE_RST:
2705d522f475Smrg	    TRACE(("CASE_RST - reset mode\n"));
2706d522f475Smrg	    ansi_modes(xw, bitclr);
270720d2c4d2Smrg	    ResetState(sp);
2708d522f475Smrg	    break;
2709d522f475Smrg
2710d522f475Smrg	case CASE_SGR:
27110bd37d32Smrg	    for (item = 0; item < nparam; ++item) {
27120bd37d32Smrg		int op = GetParam(item);
27130bd37d32Smrg
2714d522f475Smrg		if_OPT_XMC_GLITCH(screen, {
27150bd37d32Smrg		    Mark_XMC(xw, op);
2716d522f475Smrg		});
27170bd37d32Smrg		TRACE(("CASE_SGR %d\n", op));
27180bd37d32Smrg
27190bd37d32Smrg		/*
27200bd37d32Smrg		 * Only SGR 38/48 accept subparameters, and in those cases
27210bd37d32Smrg		 * the values will not be seen at this point.
27220bd37d32Smrg		 */
27230bd37d32Smrg		if (param_has_subparams(item)) {
27240bd37d32Smrg		    switch (op) {
27250bd37d32Smrg		    case 38:
27260bd37d32Smrg		    case 48:
27270bd37d32Smrg			if_OPT_ISO_COLORS(screen, {
27280bd37d32Smrg			    break;
27290bd37d32Smrg			});
27300bd37d32Smrg		    default:
27310bd37d32Smrg			TRACE(("...unexpected subparameter in SGR\n"));
27320bd37d32Smrg			op = 9999;
27330bd37d32Smrg			ResetState(sp);
27340bd37d32Smrg			break;
27350bd37d32Smrg		    }
27360bd37d32Smrg		}
27370bd37d32Smrg
27380bd37d32Smrg		switch (op) {
2739d522f475Smrg		case DEFAULT:
2740d522f475Smrg		case 0:
274120d2c4d2Smrg		    UIntClr(xw->flags,
274220d2c4d2Smrg			    (INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE));
2743d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2744d522f475Smrg			reset_SGR_Colors(xw);
2745d522f475Smrg		    });
2746d522f475Smrg		    break;
2747d522f475Smrg		case 1:	/* Bold                 */
2748d522f475Smrg		    xw->flags |= BOLD;
2749d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2750d522f475Smrg			setExtendedFG(xw);
2751d522f475Smrg		    });
2752d522f475Smrg		    break;
2753d522f475Smrg		case 5:	/* Blink                */
2754d522f475Smrg		    xw->flags |= BLINK;
2755d522f475Smrg		    StartBlinking(screen);
2756d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2757d522f475Smrg			setExtendedFG(xw);
2758d522f475Smrg		    });
2759d522f475Smrg		    break;
2760d522f475Smrg		case 4:	/* Underscore           */
2761d522f475Smrg		    xw->flags |= UNDERLINE;
2762d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2763d522f475Smrg			setExtendedFG(xw);
2764d522f475Smrg		    });
2765d522f475Smrg		    break;
2766d522f475Smrg		case 7:
2767d522f475Smrg		    xw->flags |= INVERSE;
2768d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2769d522f475Smrg			setExtendedBG(xw);
2770d522f475Smrg		    });
2771d522f475Smrg		    break;
2772d522f475Smrg		case 8:
2773d522f475Smrg		    xw->flags |= INVISIBLE;
2774d522f475Smrg		    break;
2775d522f475Smrg		case 22:	/* reset 'bold' */
277620d2c4d2Smrg		    UIntClr(xw->flags, BOLD);
2777d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2778d522f475Smrg			setExtendedFG(xw);
2779d522f475Smrg		    });
2780d522f475Smrg		    break;
2781d522f475Smrg		case 24:
278220d2c4d2Smrg		    UIntClr(xw->flags, UNDERLINE);
2783d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2784d522f475Smrg			setExtendedFG(xw);
2785d522f475Smrg		    });
2786d522f475Smrg		    break;
2787d522f475Smrg		case 25:	/* reset 'blink' */
278820d2c4d2Smrg		    UIntClr(xw->flags, BLINK);
2789d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2790d522f475Smrg			setExtendedFG(xw);
2791d522f475Smrg		    });
2792d522f475Smrg		    break;
2793d522f475Smrg		case 27:
279420d2c4d2Smrg		    UIntClr(xw->flags, INVERSE);
2795d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2796d522f475Smrg			setExtendedBG(xw);
2797d522f475Smrg		    });
2798d522f475Smrg		    break;
2799d522f475Smrg		case 28:
280020d2c4d2Smrg		    UIntClr(xw->flags, INVISIBLE);
2801d522f475Smrg		    break;
2802d522f475Smrg		case 30:
2803d522f475Smrg		case 31:
2804d522f475Smrg		case 32:
2805d522f475Smrg		case 33:
2806d522f475Smrg		case 34:
2807d522f475Smrg		case 35:
2808d522f475Smrg		case 36:
2809d522f475Smrg		case 37:
2810d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
28110bd37d32Smrg			xw->sgr_foreground = (op - 30);
2812d522f475Smrg			xw->sgr_extended = False;
2813d522f475Smrg			setExtendedFG(xw);
2814d522f475Smrg		    });
2815d522f475Smrg		    break;
2816d522f475Smrg		case 38:
28170bd37d32Smrg		    /* This is more complicated than I'd like, but it should
28180bd37d32Smrg		     * properly eat all the parameters for unsupported modes.
2819d522f475Smrg		     */
2820d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
28210bd37d32Smrg			if (parse_extended_colors(xw, &value, &item)) {
28220bd37d32Smrg			    xw->sgr_foreground = value;
28230bd37d32Smrg			    xw->sgr_extended = True;
28240bd37d32Smrg			    setExtendedFG(xw);
2825d522f475Smrg			}
2826d522f475Smrg		    });
2827d522f475Smrg		    break;
2828d522f475Smrg		case 39:
2829d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2830d522f475Smrg			reset_SGR_Foreground(xw);
2831d522f475Smrg		    });
2832d522f475Smrg		    break;
2833d522f475Smrg		case 40:
2834d522f475Smrg		case 41:
2835d522f475Smrg		case 42:
2836d522f475Smrg		case 43:
2837d522f475Smrg		case 44:
2838d522f475Smrg		case 45:
2839d522f475Smrg		case 46:
2840d522f475Smrg		case 47:
2841d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
28420bd37d32Smrg			xw->sgr_background = (op - 40);
2843d522f475Smrg			setExtendedBG(xw);
2844d522f475Smrg		    });
2845d522f475Smrg		    break;
2846d522f475Smrg		case 48:
2847d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
28480bd37d32Smrg			if (parse_extended_colors(xw, &value, &item)) {
28490bd37d32Smrg			    xw->sgr_background = value;
28500bd37d32Smrg			    setExtendedBG(xw);
2851d522f475Smrg			}
2852d522f475Smrg		    });
2853d522f475Smrg		    break;
2854d522f475Smrg		case 49:
2855d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2856d522f475Smrg			reset_SGR_Background(xw);
2857d522f475Smrg		    });
2858d522f475Smrg		    break;
2859d522f475Smrg		case 90:
2860d522f475Smrg		case 91:
2861d522f475Smrg		case 92:
2862d522f475Smrg		case 93:
2863d522f475Smrg		case 94:
2864d522f475Smrg		case 95:
2865d522f475Smrg		case 96:
2866d522f475Smrg		case 97:
2867d522f475Smrg		    if_OPT_AIX_COLORS(screen, {
28680bd37d32Smrg			xw->sgr_foreground = (op - 90 + 8);
2869d522f475Smrg			xw->sgr_extended = False;
2870d522f475Smrg			setExtendedFG(xw);
2871d522f475Smrg		    });
2872d522f475Smrg		    break;
2873d522f475Smrg		case 100:
2874d522f475Smrg#if !OPT_AIX_COLORS
2875d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2876d522f475Smrg			reset_SGR_Foreground(xw);
2877d522f475Smrg			reset_SGR_Background(xw);
2878d522f475Smrg		    });
2879d522f475Smrg		    break;
2880d522f475Smrg#endif
2881d522f475Smrg		case 101:
2882d522f475Smrg		case 102:
2883d522f475Smrg		case 103:
2884d522f475Smrg		case 104:
2885d522f475Smrg		case 105:
2886d522f475Smrg		case 106:
2887d522f475Smrg		case 107:
2888d522f475Smrg		    if_OPT_AIX_COLORS(screen, {
28890bd37d32Smrg			xw->sgr_background = (op - 100 + 8);
2890d522f475Smrg			setExtendedBG(xw);
2891d522f475Smrg		    });
2892d522f475Smrg		    break;
2893d522f475Smrg		}
2894d522f475Smrg	    }
289520d2c4d2Smrg	    ResetState(sp);
2896d522f475Smrg	    break;
2897d522f475Smrg
2898d522f475Smrg	    /* DSR (except for the '?') is a superset of CPR */
2899d522f475Smrg	case CASE_DSR:
2900d522f475Smrg	    sp->private_function = True;
2901d522f475Smrg
2902d522f475Smrg	    /* FALLTHRU */
2903d522f475Smrg	case CASE_CPR:
29040bd37d32Smrg	    TRACE(("CASE_DSR - device status report\n"));
2905d522f475Smrg	    count = 0;
29060bd37d32Smrg	    init_reply(ANSI_CSI);
29072eaa94a1Schristos	    reply.a_pintro = CharOf(sp->private_function ? '?' : 0);
2908d522f475Smrg	    reply.a_inters = 0;
2909d522f475Smrg	    reply.a_final = 'n';
2910d522f475Smrg
29110bd37d32Smrg	    switch (GetParam(0)) {
2912d522f475Smrg	    case 5:
29130bd37d32Smrg		TRACE(("...request operating status\n"));
2914d522f475Smrg		/* operating status */
2915d522f475Smrg		reply.a_param[count++] = 0;	/* (no malfunction ;-) */
2916d522f475Smrg		break;
2917d522f475Smrg	    case 6:
29180bd37d32Smrg		TRACE(("...request %s\n",
29190bd37d32Smrg		       (sp->private_function
29200bd37d32Smrg			? "DECXCPR"
29210bd37d32Smrg			: "CPR")));
2922d522f475Smrg		/* CPR */
29230bd37d32Smrg		/* DECXCPR (with page=1) */
2924e0a2b6dfSmrg		value = (screen->cur_row + 1);
2925e0a2b6dfSmrg		if ((xw->flags & ORIGIN) != 0) {
2926e0a2b6dfSmrg		    value -= screen->top_marg;
2927e0a2b6dfSmrg		}
2928e0a2b6dfSmrg		reply.a_param[count++] = (ParmType) value;
2929e0a2b6dfSmrg
2930e0a2b6dfSmrg		value = (screen->cur_col + 1);
2931e0a2b6dfSmrg		if ((xw->flags & ORIGIN) != 0) {
2932e0a2b6dfSmrg		    value -= screen->lft_marg;
2933e0a2b6dfSmrg		}
2934e0a2b6dfSmrg		reply.a_param[count++] = (ParmType) value;
2935e0a2b6dfSmrg
29360bd37d32Smrg		if (sp->private_function
29370bd37d32Smrg		    && screen->vtXX_level >= 4) {	/* VT420 */
29380bd37d32Smrg		    reply.a_param[count++] = 1;
29390bd37d32Smrg		}
2940d522f475Smrg		reply.a_final = 'R';
2941d522f475Smrg		break;
2942d522f475Smrg	    case 15:
29430bd37d32Smrg		TRACE(("...request printer status\n"));
29440bd37d32Smrg		if (sp->private_function
29450bd37d32Smrg		    && screen->vtXX_level >= 2) {	/* VT220 */
2946e0a2b6dfSmrg		    reply.a_param[count++] = 13;	/* no printer detected */
29472eaa94a1Schristos		}
2948d522f475Smrg		break;
2949d522f475Smrg	    case 25:
29500bd37d32Smrg		TRACE(("...request UDK status\n"));
29510bd37d32Smrg		if (sp->private_function
29520bd37d32Smrg		    && screen->vtXX_level >= 2) {	/* VT220 */
29532eaa94a1Schristos		    reply.a_param[count++] = 20;	/* UDK always unlocked */
29542eaa94a1Schristos		}
2955d522f475Smrg		break;
2956d522f475Smrg	    case 26:
29570bd37d32Smrg		TRACE(("...request keyboard status\n"));
29580bd37d32Smrg		if (sp->private_function
29590bd37d32Smrg		    && screen->vtXX_level >= 2) {	/* VT220 */
29602eaa94a1Schristos		    reply.a_param[count++] = 27;
29612eaa94a1Schristos		    reply.a_param[count++] = 1;		/* North American */
29620bd37d32Smrg		    if (screen->vtXX_level >= 4) {	/* VT420 */
29632eaa94a1Schristos			reply.a_param[count++] = 0;	/* ready */
29642eaa94a1Schristos			reply.a_param[count++] = 0;	/* LK201 */
29652eaa94a1Schristos		    }
2966d522f475Smrg		}
2967d522f475Smrg		break;
2968e0a2b6dfSmrg	    case 53:		/* according to existing xterm handling */
2969e0a2b6dfSmrg	    case 55:		/* according to the VT330/VT340 Text Programming Manual */
29700bd37d32Smrg		TRACE(("...request locator status\n"));
29710bd37d32Smrg		if (sp->private_function
29720bd37d32Smrg		    && screen->vtXX_level >= 2) {	/* VT220 */
2973d522f475Smrg#if OPT_DEC_LOCATOR
29742eaa94a1Schristos		    reply.a_param[count++] = 50;	/* locator ready */
2975d522f475Smrg#else
29762eaa94a1Schristos		    reply.a_param[count++] = 53;	/* no locator */
2977e0a2b6dfSmrg#endif
2978e0a2b6dfSmrg		}
2979e0a2b6dfSmrg		break;
2980e0a2b6dfSmrg	    case 56:
2981e0a2b6dfSmrg		TRACE(("...request locator type\n"));
2982e0a2b6dfSmrg		if (sp->private_function
2983e0a2b6dfSmrg		    && screen->vtXX_level >= 3) {	/* VT330 (FIXME: what about VT220?) */
2984e0a2b6dfSmrg		    reply.a_param[count++] = 57;
2985e0a2b6dfSmrg#if OPT_DEC_LOCATOR
2986e0a2b6dfSmrg		    reply.a_param[count++] = 1;		/* mouse */
2987e0a2b6dfSmrg#else
2988e0a2b6dfSmrg		    reply.a_param[count++] = 0;		/* unknown */
2989d522f475Smrg#endif
29902eaa94a1Schristos		}
29912eaa94a1Schristos		break;
29920bd37d32Smrg	    case 62:
29930bd37d32Smrg		TRACE(("...request DECMSR - macro space\n"));
29940bd37d32Smrg		if (sp->private_function
29950bd37d32Smrg		    && screen->vtXX_level >= 4) {	/* VT420 */
29960bd37d32Smrg		    reply.a_pintro = 0;
29970bd37d32Smrg		    reply.a_radix[count] = 16;	/* no data */
29980bd37d32Smrg		    reply.a_param[count++] = 0;		/* no space for macros */
29990bd37d32Smrg		    reply.a_inters = '*';
30000bd37d32Smrg		    reply.a_final = '{';
30010bd37d32Smrg		}
30020bd37d32Smrg		break;
30030bd37d32Smrg	    case 63:
30040bd37d32Smrg		TRACE(("...request DECCKSR - memory checksum\n"));
30050bd37d32Smrg		/* DECCKSR - Memory checksum */
30060bd37d32Smrg		if (sp->private_function
30070bd37d32Smrg		    && screen->vtXX_level >= 4) {	/* VT420 */
30080bd37d32Smrg		    init_reply(ANSI_DCS);
30090bd37d32Smrg		    reply.a_param[count++] = (ParmType) GetParam(1);	/* PID */
30100bd37d32Smrg		    reply.a_delim = "!~";	/* delimiter */
30110bd37d32Smrg		    reply.a_radix[count] = 16;	/* use hex */
30120bd37d32Smrg		    reply.a_param[count++] = 0;		/* no data */
30130bd37d32Smrg		}
30140bd37d32Smrg		break;
30150bd37d32Smrg	    case 75:
30160bd37d32Smrg		TRACE(("...request data integrity\n"));
30170bd37d32Smrg		if (sp->private_function
30180bd37d32Smrg		    && screen->vtXX_level >= 4) {	/* VT420 */
30190bd37d32Smrg		    reply.a_param[count++] = 70;	/* no errors */
30200bd37d32Smrg		}
30210bd37d32Smrg		break;
30220bd37d32Smrg	    case 85:
30230bd37d32Smrg		TRACE(("...request multi-session configuration\n"));
30240bd37d32Smrg		if (sp->private_function
30250bd37d32Smrg		    && screen->vtXX_level >= 4) {	/* VT420 */
30260bd37d32Smrg		    reply.a_param[count++] = 83;	/* not configured */
30270bd37d32Smrg		}
30280bd37d32Smrg		break;
30292eaa94a1Schristos	    default:
3030d522f475Smrg		break;
3031d522f475Smrg	    }
3032d522f475Smrg
30332eaa94a1Schristos	    if ((reply.a_nparam = (ParmType) count) != 0)
3034d522f475Smrg		unparseseq(xw, &reply);
3035d522f475Smrg
303620d2c4d2Smrg	    ResetState(sp);
3037d522f475Smrg	    sp->private_function = False;
3038d522f475Smrg	    break;
3039d522f475Smrg
3040d522f475Smrg	case CASE_MC:
3041d522f475Smrg	    TRACE(("CASE_MC - media control\n"));
30420bd37d32Smrg	    xtermMediaControl(xw, GetParam(0), False);
304320d2c4d2Smrg	    ResetState(sp);
3044d522f475Smrg	    break;
3045d522f475Smrg
3046d522f475Smrg	case CASE_DEC_MC:
3047d522f475Smrg	    TRACE(("CASE_DEC_MC - DEC media control\n"));
30480bd37d32Smrg	    xtermMediaControl(xw, GetParam(0), True);
304920d2c4d2Smrg	    ResetState(sp);
3050d522f475Smrg	    break;
3051d522f475Smrg
3052d522f475Smrg	case CASE_HP_MEM_LOCK:
3053d522f475Smrg	case CASE_HP_MEM_UNLOCK:
3054d522f475Smrg	    TRACE(("%s\n", ((sp->parsestate[c] == CASE_HP_MEM_LOCK)
3055d522f475Smrg			    ? "CASE_HP_MEM_LOCK"
3056d522f475Smrg			    : "CASE_HP_MEM_UNLOCK")));
3057d522f475Smrg	    if (screen->scroll_amt)
3058d522f475Smrg		FlushScroll(xw);
3059d522f475Smrg	    if (sp->parsestate[c] == CASE_HP_MEM_LOCK)
3060d522f475Smrg		set_tb_margins(screen, screen->cur_row, screen->bot_marg);
3061d522f475Smrg	    else
3062d522f475Smrg		set_tb_margins(screen, 0, screen->bot_marg);
306320d2c4d2Smrg	    ResetState(sp);
3064d522f475Smrg	    break;
3065d522f475Smrg
3066d522f475Smrg	case CASE_DECSTBM:
3067d522f475Smrg	    TRACE(("CASE_DECSTBM - set scrolling region\n"));
30680bd37d32Smrg	    {
30690bd37d32Smrg		int top;
30700bd37d32Smrg		int bot;
30710bd37d32Smrg		top = one_if_default(0);
30720bd37d32Smrg		if (nparam < 2 || (bot = GetParam(1)) == DEFAULT
30730bd37d32Smrg		    || bot > MaxRows(screen)
30740bd37d32Smrg		    || bot == 0)
30750bd37d32Smrg		    bot = MaxRows(screen);
30760bd37d32Smrg		if (bot > top) {
30770bd37d32Smrg		    if (screen->scroll_amt)
30780bd37d32Smrg			FlushScroll(xw);
30790bd37d32Smrg		    set_tb_margins(screen, top - 1, bot - 1);
30800bd37d32Smrg		    CursorSet(screen, 0, 0, xw->flags);
30810bd37d32Smrg		}
30820bd37d32Smrg		ResetState(sp);
3083d522f475Smrg	    }
3084d522f475Smrg	    break;
3085d522f475Smrg
3086d522f475Smrg	case CASE_DECREQTPARM:
3087d522f475Smrg	    TRACE(("CASE_DECREQTPARM\n"));
3088d522f475Smrg	    if (screen->terminal_id < 200) {	/* VT102 */
30890bd37d32Smrg		value = zero_if_default(0);
30900bd37d32Smrg		if (value == 0 || value == 1) {
30910bd37d32Smrg		    init_reply(ANSI_CSI);
3092d522f475Smrg		    reply.a_pintro = 0;
3093d522f475Smrg		    reply.a_nparam = 7;
30940bd37d32Smrg		    reply.a_param[0] = (ParmType) (value + 2);
3095d522f475Smrg		    reply.a_param[1] = 1;	/* no parity */
3096d522f475Smrg		    reply.a_param[2] = 1;	/* eight bits */
3097d522f475Smrg		    reply.a_param[3] = 128;	/* transmit 38.4k baud */
3098d522f475Smrg		    reply.a_param[4] = 128;	/* receive 38.4k baud */
3099d522f475Smrg		    reply.a_param[5] = 1;	/* clock multiplier ? */
3100d522f475Smrg		    reply.a_param[6] = 0;	/* STP flags ? */
3101d522f475Smrg		    reply.a_inters = 0;
3102d522f475Smrg		    reply.a_final = 'x';
3103d522f475Smrg		    unparseseq(xw, &reply);
3104d522f475Smrg		}
3105d522f475Smrg	    }
310620d2c4d2Smrg	    ResetState(sp);
3107d522f475Smrg	    break;
3108d522f475Smrg
3109d522f475Smrg	case CASE_DECSET:
3110d522f475Smrg	    /* DECSET */
3111d522f475Smrg#if OPT_VT52_MODE
3112d522f475Smrg	    if (screen->vtXX_level != 0)
3113d522f475Smrg#endif
3114d522f475Smrg		dpmodes(xw, bitset);
311520d2c4d2Smrg	    ResetState(sp);
3116d522f475Smrg#if OPT_TEK4014
3117d522f475Smrg	    if (TEK4014_ACTIVE(xw))
3118d522f475Smrg		return False;
3119d522f475Smrg#endif
3120d522f475Smrg	    break;
3121d522f475Smrg
3122d522f475Smrg	case CASE_DECRST:
3123d522f475Smrg	    /* DECRST */
3124d522f475Smrg	    dpmodes(xw, bitclr);
31252eaa94a1Schristos	    init_groundtable(screen, sp);
312620d2c4d2Smrg	    ResetState(sp);
3127d522f475Smrg	    break;
3128d522f475Smrg
3129d522f475Smrg	case CASE_DECALN:
3130d522f475Smrg	    TRACE(("CASE_DECALN - alignment test\n"));
3131d522f475Smrg	    if (screen->cursor_state)
3132d522f475Smrg		HideCursor();
31330bd37d32Smrg	    reset_margins(screen);
3134d522f475Smrg	    CursorSet(screen, 0, 0, xw->flags);
3135d522f475Smrg	    xtermParseRect(xw, 0, 0, &myRect);
3136d522f475Smrg	    ScrnFillRectangle(xw, &myRect, 'E', 0, False);
313720d2c4d2Smrg	    ResetState(sp);
3138d522f475Smrg	    break;
3139d522f475Smrg
3140d522f475Smrg	case CASE_GSETS:
3141d522f475Smrg	    TRACE(("CASE_GSETS(%d) = '%c'\n", sp->scstype, c));
3142e0a2b6dfSmrg	    decode_scs(xw, sp->scstype, 0, (int) c);
314320d2c4d2Smrg	    ResetState(sp);
3144d522f475Smrg	    break;
3145d522f475Smrg
31460bd37d32Smrg	case CASE_ANSI_SC:
31470bd37d32Smrg	    if (IsLeftRightMode(xw)) {
31480bd37d32Smrg		int left;
31490bd37d32Smrg		int right;
31500bd37d32Smrg
31510bd37d32Smrg		TRACE(("CASE_DECSLRM - set left and right margin\n"));
31520bd37d32Smrg		left = one_if_default(0);
31530bd37d32Smrg		if (nparam < 2 || (right = GetParam(1)) == DEFAULT
31540bd37d32Smrg		    || right > MaxCols(screen)
31550bd37d32Smrg		    || right == 0)
31560bd37d32Smrg		    right = MaxCols(screen);
31570bd37d32Smrg		if (right > left) {
31580bd37d32Smrg		    set_lr_margins(screen, left - 1, right - 1);
31590bd37d32Smrg		    CursorSet(screen, 0, 0, xw->flags);
31600bd37d32Smrg		}
31610bd37d32Smrg	    } else {
31620bd37d32Smrg		TRACE(("CASE_ANSI_SC - save cursor\n"));
31630bd37d32Smrg		CursorSave(xw);
31640bd37d32Smrg	    }
31650bd37d32Smrg	    ResetState(sp);
31660bd37d32Smrg	    break;
31670bd37d32Smrg
3168d522f475Smrg	case CASE_DECSC:
3169d522f475Smrg	    TRACE(("CASE_DECSC - save cursor\n"));
3170d522f475Smrg	    CursorSave(xw);
317120d2c4d2Smrg	    ResetState(sp);
3172d522f475Smrg	    break;
3173d522f475Smrg
31740bd37d32Smrg	case CASE_ANSI_RC:
3175d522f475Smrg	case CASE_DECRC:
31760bd37d32Smrg	    TRACE(("CASE_%sRC - restore cursor\n",
31770bd37d32Smrg		   (sp->nextstate == CASE_DECRC) ? "DEC" : "ANSI_"));
3178d522f475Smrg	    CursorRestore(xw);
3179d522f475Smrg	    if_OPT_ISO_COLORS(screen, {
3180d522f475Smrg		setExtendedFG(xw);
3181d522f475Smrg	    });
318220d2c4d2Smrg	    ResetState(sp);
3183d522f475Smrg	    break;
3184d522f475Smrg
3185d522f475Smrg	case CASE_DECKPAM:
3186d522f475Smrg	    TRACE(("CASE_DECKPAM\n"));
3187d522f475Smrg	    xw->keyboard.flags |= MODE_DECKPAM;
3188d522f475Smrg	    update_appkeypad();
318920d2c4d2Smrg	    ResetState(sp);
3190d522f475Smrg	    break;
3191d522f475Smrg
3192d522f475Smrg	case CASE_DECKPNM:
3193d522f475Smrg	    TRACE(("CASE_DECKPNM\n"));
319420d2c4d2Smrg	    UIntClr(xw->keyboard.flags, MODE_DECKPAM);
3195d522f475Smrg	    update_appkeypad();
319620d2c4d2Smrg	    ResetState(sp);
3197d522f475Smrg	    break;
3198d522f475Smrg
3199d522f475Smrg	case CASE_CSI_QUOTE_STATE:
3200d522f475Smrg	    sp->parsestate = csi_quo_table;
3201d522f475Smrg	    break;
3202d522f475Smrg
320320d2c4d2Smrg#if OPT_BLINK_CURS
320420d2c4d2Smrg	case CASE_CSI_SPACE_STATE:
320520d2c4d2Smrg	    sp->parsestate = csi_sp_table;
320620d2c4d2Smrg	    break;
320720d2c4d2Smrg
320820d2c4d2Smrg	case CASE_DECSCUSR:
320920d2c4d2Smrg	    TRACE(("CASE_DECSCUSR\n"));
321020d2c4d2Smrg	    {
321120d2c4d2Smrg		Boolean change = True;
32120bd37d32Smrg		Boolean blinks = screen->cursor_blink_esc;
321320d2c4d2Smrg
321420d2c4d2Smrg		HideCursor();
321520d2c4d2Smrg
32160bd37d32Smrg		switch (GetParam(0)) {
321720d2c4d2Smrg		case DEFAULT:
32180bd37d32Smrg		case DEFAULT_STYLE:
32190bd37d32Smrg		case BLINK_BLOCK:
322020d2c4d2Smrg		    blinks = True;
32210bd37d32Smrg		    screen->cursor_shape = CURSOR_BLOCK;
322220d2c4d2Smrg		    break;
32230bd37d32Smrg		case STEADY_BLOCK:
322420d2c4d2Smrg		    blinks = False;
32250bd37d32Smrg		    screen->cursor_shape = CURSOR_BLOCK;
322620d2c4d2Smrg		    break;
32270bd37d32Smrg		case BLINK_UNDERLINE:
322820d2c4d2Smrg		    blinks = True;
32290bd37d32Smrg		    screen->cursor_shape = CURSOR_UNDERLINE;
323020d2c4d2Smrg		    break;
32310bd37d32Smrg		case STEADY_UNDERLINE:
32320bd37d32Smrg		    blinks = False;
32330bd37d32Smrg		    screen->cursor_shape = CURSOR_UNDERLINE;
32340bd37d32Smrg		    break;
32350bd37d32Smrg		case BLINK_BAR:
32360bd37d32Smrg		    blinks = True;
32370bd37d32Smrg		    screen->cursor_shape = CURSOR_BAR;
32380bd37d32Smrg		    break;
32390bd37d32Smrg		case STEADY_BAR:
324020d2c4d2Smrg		    blinks = False;
32410bd37d32Smrg		    screen->cursor_shape = CURSOR_BAR;
324220d2c4d2Smrg		    break;
324320d2c4d2Smrg		default:
324420d2c4d2Smrg		    change = False;
324520d2c4d2Smrg		    break;
324620d2c4d2Smrg		}
324720d2c4d2Smrg
324820d2c4d2Smrg		if (change) {
324920d2c4d2Smrg		    xtermSetCursorBox(screen);
32500bd37d32Smrg		    screen->cursor_blink_esc = blinks;
32510bd37d32Smrg		    UpdateCursorBlink(screen);
325220d2c4d2Smrg		}
325320d2c4d2Smrg	    }
325420d2c4d2Smrg	    ResetState(sp);
325520d2c4d2Smrg	    break;
325620d2c4d2Smrg#endif
325720d2c4d2Smrg
325820d2c4d2Smrg#if OPT_SCROLL_LOCK
325920d2c4d2Smrg	case CASE_DECLL:
326020d2c4d2Smrg	    TRACE(("CASE_DECLL\n"));
326120d2c4d2Smrg	    if (nparam > 0) {
326220d2c4d2Smrg		for (count = 0; count < nparam; ++count) {
32630bd37d32Smrg		    int op = zero_if_default(count);
32640bd37d32Smrg		    switch (op) {
326520d2c4d2Smrg		    case 0:
326620d2c4d2Smrg		    case DEFAULT:
326720d2c4d2Smrg			xtermClearLEDs(screen);
326820d2c4d2Smrg			break;
326920d2c4d2Smrg		    case 1:
327020d2c4d2Smrg		    case 2:
327120d2c4d2Smrg		    case 3:
32720bd37d32Smrg			xtermShowLED(screen,
32730bd37d32Smrg				     (Cardinal) op,
32740bd37d32Smrg				     True);
327520d2c4d2Smrg			break;
327620d2c4d2Smrg		    case 21:
327720d2c4d2Smrg		    case 22:
327820d2c4d2Smrg		    case 23:
32790bd37d32Smrg			xtermShowLED(screen,
32800bd37d32Smrg				     (Cardinal) (op - 20),
32810bd37d32Smrg				     True);
328220d2c4d2Smrg			break;
328320d2c4d2Smrg		    }
328420d2c4d2Smrg		}
328520d2c4d2Smrg	    } else {
328620d2c4d2Smrg		xtermClearLEDs(screen);
328720d2c4d2Smrg	    }
328820d2c4d2Smrg	    ResetState(sp);
328920d2c4d2Smrg	    break;
329020d2c4d2Smrg#endif
329120d2c4d2Smrg
3292d522f475Smrg#if OPT_VT52_MODE
3293d522f475Smrg	case CASE_VT52_FINISH:
3294d522f475Smrg	    TRACE(("CASE_VT52_FINISH terminal_id %d, vtXX_level %d\n",
3295d522f475Smrg		   screen->terminal_id,
3296d522f475Smrg		   screen->vtXX_level));
3297d522f475Smrg	    if (screen->terminal_id >= 100
3298d522f475Smrg		&& screen->vtXX_level == 0) {
3299d522f475Smrg		sp->groundtable =
3300d522f475Smrg		    sp->parsestate = ansi_table;
33010bd37d32Smrg		/*
33020bd37d32Smrg		 * On restore, the terminal does not recognize DECRQSS for
33030bd37d32Smrg		 * DECSCL (per vttest).
33040bd37d32Smrg		 */
33050bd37d32Smrg		screen->vtXX_level = 1;
3306d522f475Smrg		screen->curgl = screen->vt52_save_curgl;
3307d522f475Smrg		screen->curgr = screen->vt52_save_curgr;
3308d522f475Smrg		screen->curss = screen->vt52_save_curss;
3309d522f475Smrg		memmove(screen->gsets, screen->vt52_save_gsets, sizeof(screen->gsets));
3310d522f475Smrg	    }
3311d522f475Smrg	    break;
3312d522f475Smrg#endif
3313d522f475Smrg
3314d522f475Smrg	case CASE_ANSI_LEVEL_1:
3315d522f475Smrg	    TRACE(("CASE_ANSI_LEVEL_1\n"));
3316d522f475Smrg	    set_ansi_conformance(screen, 1);
331720d2c4d2Smrg	    ResetState(sp);
3318d522f475Smrg	    break;
3319d522f475Smrg
3320d522f475Smrg	case CASE_ANSI_LEVEL_2:
3321d522f475Smrg	    TRACE(("CASE_ANSI_LEVEL_2\n"));
3322d522f475Smrg	    set_ansi_conformance(screen, 2);
332320d2c4d2Smrg	    ResetState(sp);
3324d522f475Smrg	    break;
3325d522f475Smrg
3326d522f475Smrg	case CASE_ANSI_LEVEL_3:
3327d522f475Smrg	    TRACE(("CASE_ANSI_LEVEL_3\n"));
3328d522f475Smrg	    set_ansi_conformance(screen, 3);
332920d2c4d2Smrg	    ResetState(sp);
3330d522f475Smrg	    break;
3331d522f475Smrg
3332d522f475Smrg	case CASE_DECSCL:
33330bd37d32Smrg	    TRACE(("CASE_DECSCL(%d,%d)\n", GetParam(0), GetParam(1)));
33340bd37d32Smrg	    /*
33350bd37d32Smrg	     * This changes the emulation level, and is not recognized by
33360bd37d32Smrg	     * VT100s.
33370bd37d32Smrg	     */
33380bd37d32Smrg	    if (screen->terminal_id >= 200) {
3339d522f475Smrg		/*
33400bd37d32Smrg		 * Disallow unrecognized parameters, as well as attempts to set
33410bd37d32Smrg		 * the operating level higher than the given terminal-id.
3342d522f475Smrg		 */
33430bd37d32Smrg		if (GetParam(0) >= 61
33440bd37d32Smrg		    && GetParam(0) <= 60 + (screen->terminal_id / 100)) {
33450bd37d32Smrg		    /*
33460bd37d32Smrg		     * VT300, VT420, VT520 manuals claim that DECSCL does a
33470bd37d32Smrg		     * hard reset (RIS).  VT220 manual states that it is a soft
33480bd37d32Smrg		     * reset.  Perhaps both are right (unlikely).  Kermit says
33490bd37d32Smrg		     * it's soft.
33500bd37d32Smrg		     */
33510bd37d32Smrg		    ReallyReset(xw, False, False);
33520bd37d32Smrg		    init_parser(xw, sp);
33530bd37d32Smrg		    screen->vtXX_level = GetParam(0) - 60;
33540bd37d32Smrg		    if (GetParam(0) > 61) {
33550bd37d32Smrg			switch (zero_if_default(1)) {
33560bd37d32Smrg			case 1:
33570bd37d32Smrg			    show_8bit_control(False);
33580bd37d32Smrg			    break;
33590bd37d32Smrg			case 0:
33600bd37d32Smrg			case 2:
33610bd37d32Smrg			    show_8bit_control(True);
33620bd37d32Smrg			    break;
33630bd37d32Smrg			}
336420d2c4d2Smrg		    }
3365d522f475Smrg		}
3366d522f475Smrg	    }
336720d2c4d2Smrg	    ResetState(sp);
3368d522f475Smrg	    break;
3369d522f475Smrg
3370d522f475Smrg	case CASE_DECSCA:
3371d522f475Smrg	    TRACE(("CASE_DECSCA\n"));
3372d522f475Smrg	    screen->protected_mode = DEC_PROTECT;
33730bd37d32Smrg	    if (GetParam(0) <= 0 || GetParam(0) == 2) {
337420d2c4d2Smrg		UIntClr(xw->flags, PROTECTED);
33750bd37d32Smrg		TRACE(("...clear PROTECTED\n"));
33760bd37d32Smrg	    } else if (GetParam(0) == 1) {
3377d522f475Smrg		xw->flags |= PROTECTED;
33780bd37d32Smrg		TRACE(("...set PROTECTED\n"));
33790bd37d32Smrg	    }
338020d2c4d2Smrg	    ResetState(sp);
3381d522f475Smrg	    break;
3382d522f475Smrg
3383d522f475Smrg	case CASE_DECSED:
3384d522f475Smrg	    TRACE(("CASE_DECSED\n"));
33850bd37d32Smrg	    do_erase_display(xw, zero_if_default(0), DEC_PROTECT);
338620d2c4d2Smrg	    ResetState(sp);
3387d522f475Smrg	    break;
3388d522f475Smrg
3389d522f475Smrg	case CASE_DECSEL:
3390d522f475Smrg	    TRACE(("CASE_DECSEL\n"));
33910bd37d32Smrg	    do_erase_line(xw, zero_if_default(0), DEC_PROTECT);
339220d2c4d2Smrg	    ResetState(sp);
3393d522f475Smrg	    break;
3394d522f475Smrg
3395d522f475Smrg	case CASE_ST:
3396e0a2b6dfSmrg	    TRACE(("CASE_ST: End of String (%lu bytes) (mode=%d)\n",
3397e0a2b6dfSmrg		   (unsigned long) sp->string_used,
3398e0a2b6dfSmrg		   sp->string_mode));
339920d2c4d2Smrg	    ResetState(sp);
3400956cc18dSsnj	    if (!sp->string_used)
3401d522f475Smrg		break;
3402956cc18dSsnj	    sp->string_area[--(sp->string_used)] = '\0';
3403d522f475Smrg	    switch (sp->string_mode) {
3404d522f475Smrg	    case ANSI_APC:
3405d522f475Smrg		/* ignored */
3406d522f475Smrg		break;
3407d522f475Smrg	    case ANSI_DCS:
3408956cc18dSsnj		do_dcs(xw, sp->string_area, sp->string_used);
3409d522f475Smrg		break;
3410d522f475Smrg	    case ANSI_OSC:
3411956cc18dSsnj		do_osc(xw, sp->string_area, sp->string_used, ANSI_ST);
3412d522f475Smrg		break;
3413d522f475Smrg	    case ANSI_PM:
3414d522f475Smrg		/* ignored */
3415d522f475Smrg		break;
3416d522f475Smrg	    case ANSI_SOS:
3417d522f475Smrg		/* ignored */
3418d522f475Smrg		break;
3419e0a2b6dfSmrg	    default:
3420e0a2b6dfSmrg		TRACE(("unknown mode\n"));
3421e0a2b6dfSmrg		break;
3422d522f475Smrg	    }
3423d522f475Smrg	    break;
3424d522f475Smrg
3425d522f475Smrg	case CASE_SOS:
3426d522f475Smrg	    TRACE(("CASE_SOS: Start of String\n"));
342720d2c4d2Smrg	    if (ParseSOS(screen)) {
342820d2c4d2Smrg		sp->string_mode = ANSI_SOS;
342920d2c4d2Smrg		sp->parsestate = sos_table;
343020d2c4d2Smrg	    } else {
343120d2c4d2Smrg		illegal_parse(xw, c, sp);
343220d2c4d2Smrg	    }
3433d522f475Smrg	    break;
3434d522f475Smrg
3435d522f475Smrg	case CASE_PM:
3436d522f475Smrg	    TRACE(("CASE_PM: Privacy Message\n"));
343720d2c4d2Smrg	    if (ParseSOS(screen)) {
343820d2c4d2Smrg		sp->string_mode = ANSI_PM;
343920d2c4d2Smrg		sp->parsestate = sos_table;
344020d2c4d2Smrg	    } else {
344120d2c4d2Smrg		illegal_parse(xw, c, sp);
344220d2c4d2Smrg	    }
3443d522f475Smrg	    break;
3444d522f475Smrg
3445d522f475Smrg	case CASE_DCS:
3446d522f475Smrg	    TRACE(("CASE_DCS: Device Control String\n"));
3447d522f475Smrg	    sp->string_mode = ANSI_DCS;
3448d522f475Smrg	    sp->parsestate = sos_table;
3449d522f475Smrg	    break;
3450d522f475Smrg
3451d522f475Smrg	case CASE_APC:
3452d522f475Smrg	    TRACE(("CASE_APC: Application Program Command\n"));
345320d2c4d2Smrg	    if (ParseSOS(screen)) {
345420d2c4d2Smrg		sp->string_mode = ANSI_APC;
345520d2c4d2Smrg		sp->parsestate = sos_table;
345620d2c4d2Smrg	    } else {
345720d2c4d2Smrg		illegal_parse(xw, c, sp);
345820d2c4d2Smrg	    }
3459d522f475Smrg	    break;
3460d522f475Smrg
3461d522f475Smrg	case CASE_SPA:
3462d522f475Smrg	    TRACE(("CASE_SPA - start protected area\n"));
3463d522f475Smrg	    screen->protected_mode = ISO_PROTECT;
3464d522f475Smrg	    xw->flags |= PROTECTED;
346520d2c4d2Smrg	    ResetState(sp);
3466d522f475Smrg	    break;
3467d522f475Smrg
3468d522f475Smrg	case CASE_EPA:
3469d522f475Smrg	    TRACE(("CASE_EPA - end protected area\n"));
347020d2c4d2Smrg	    UIntClr(xw->flags, PROTECTED);
347120d2c4d2Smrg	    ResetState(sp);
3472d522f475Smrg	    break;
3473d522f475Smrg
3474d522f475Smrg	case CASE_SU:
3475d522f475Smrg	    TRACE(("CASE_SU - scroll up\n"));
34760bd37d32Smrg	    xtermScroll(xw, one_if_default(0));
34770bd37d32Smrg	    ResetState(sp);
34780bd37d32Smrg	    break;
34790bd37d32Smrg
34800bd37d32Smrg	case CASE_SL:		/* ISO 6429, non-DEC */
34810bd37d32Smrg	    TRACE(("CASE_SL - scroll left\n"));
34820bd37d32Smrg	    xtermScrollLR(xw, one_if_default(0), True);
34830bd37d32Smrg	    ResetState(sp);
34840bd37d32Smrg	    break;
34850bd37d32Smrg
34860bd37d32Smrg	case CASE_SR:		/* ISO 6429, non-DEC */
34870bd37d32Smrg	    TRACE(("CASE_SR - scroll right\n"));
34880bd37d32Smrg	    xtermScrollLR(xw, one_if_default(0), False);
34890bd37d32Smrg	    ResetState(sp);
34900bd37d32Smrg	    break;
34910bd37d32Smrg
34920bd37d32Smrg	case CASE_DECDC:
34930bd37d32Smrg	    TRACE(("CASE_DC - delete column\n"));
34940bd37d32Smrg	    if (screen->vtXX_level >= 4
34950bd37d32Smrg		&& IsLeftRightMode(xw)) {
34960bd37d32Smrg		xtermColScroll(xw, one_if_default(0), True, screen->cur_col);
34970bd37d32Smrg	    }
34980bd37d32Smrg	    ResetState(sp);
34990bd37d32Smrg	    break;
35000bd37d32Smrg
35010bd37d32Smrg	case CASE_DECIC:
35020bd37d32Smrg	    TRACE(("CASE_IC - insert column\n"));
35030bd37d32Smrg	    if (screen->vtXX_level >= 4
35040bd37d32Smrg		&& IsLeftRightMode(xw)) {
35050bd37d32Smrg		xtermColScroll(xw, one_if_default(0), False, screen->cur_col);
35060bd37d32Smrg	    }
35070bd37d32Smrg	    ResetState(sp);
35080bd37d32Smrg	    break;
35090bd37d32Smrg
35100bd37d32Smrg	case CASE_DECBI:
35110bd37d32Smrg	    TRACE(("CASE_BI - back index\n"));
35120bd37d32Smrg	    if (screen->vtXX_level >= 4) {
35130bd37d32Smrg		xtermColIndex(xw, True);
35140bd37d32Smrg	    }
35150bd37d32Smrg	    ResetState(sp);
35160bd37d32Smrg	    break;
35170bd37d32Smrg
35180bd37d32Smrg	case CASE_DECFI:
35190bd37d32Smrg	    TRACE(("CASE_FI - forward index\n"));
35200bd37d32Smrg	    if (screen->vtXX_level >= 4) {
35210bd37d32Smrg		xtermColIndex(xw, False);
35220bd37d32Smrg	    }
352320d2c4d2Smrg	    ResetState(sp);
3524d522f475Smrg	    break;
3525d522f475Smrg
3526d522f475Smrg	case CASE_IND:
3527d522f475Smrg	    TRACE(("CASE_IND - index\n"));
3528d522f475Smrg	    xtermIndex(xw, 1);
3529d522f475Smrg	    do_xevents();
353020d2c4d2Smrg	    ResetState(sp);
3531d522f475Smrg	    break;
3532d522f475Smrg
3533d522f475Smrg	case CASE_CPL:
3534d522f475Smrg	    TRACE(("CASE_CPL - cursor prev line\n"));
35350bd37d32Smrg	    CursorPrevLine(xw, one_if_default(0));
353620d2c4d2Smrg	    ResetState(sp);
3537d522f475Smrg	    break;
3538d522f475Smrg
3539d522f475Smrg	case CASE_CNL:
3540d522f475Smrg	    TRACE(("CASE_CNL - cursor next line\n"));
35410bd37d32Smrg	    CursorNextLine(xw, one_if_default(0));
354220d2c4d2Smrg	    ResetState(sp);
3543d522f475Smrg	    break;
3544d522f475Smrg
3545d522f475Smrg	case CASE_NEL:
3546d522f475Smrg	    TRACE(("CASE_NEL\n"));
3547d522f475Smrg	    xtermIndex(xw, 1);
35480bd37d32Smrg	    CarriageReturn(xw);
354920d2c4d2Smrg	    ResetState(sp);
3550d522f475Smrg	    break;
3551d522f475Smrg
3552d522f475Smrg	case CASE_HTS:
3553d522f475Smrg	    TRACE(("CASE_HTS - horizontal tab set\n"));
3554d522f475Smrg	    TabSet(xw->tabs, screen->cur_col);
355520d2c4d2Smrg	    ResetState(sp);
3556d522f475Smrg	    break;
3557d522f475Smrg
3558d522f475Smrg	case CASE_RI:
3559d522f475Smrg	    TRACE(("CASE_RI - reverse index\n"));
3560d522f475Smrg	    RevIndex(xw, 1);
356120d2c4d2Smrg	    ResetState(sp);
3562d522f475Smrg	    break;
3563d522f475Smrg
3564d522f475Smrg	case CASE_SS2:
3565d522f475Smrg	    TRACE(("CASE_SS2\n"));
3566d522f475Smrg	    screen->curss = 2;
356720d2c4d2Smrg	    ResetState(sp);
3568d522f475Smrg	    break;
3569d522f475Smrg
3570d522f475Smrg	case CASE_SS3:
3571d522f475Smrg	    TRACE(("CASE_SS3\n"));
3572d522f475Smrg	    screen->curss = 3;
357320d2c4d2Smrg	    ResetState(sp);
3574d522f475Smrg	    break;
3575d522f475Smrg
3576d522f475Smrg	case CASE_CSI_STATE:
3577d522f475Smrg	    /* enter csi state */
35780bd37d32Smrg	    InitParams();
35790bd37d32Smrg	    SetParam(nparam++, DEFAULT);
3580d522f475Smrg	    sp->parsestate = csi_table;
3581d522f475Smrg	    break;
3582d522f475Smrg
3583d522f475Smrg	case CASE_ESC_SP_STATE:
3584d522f475Smrg	    /* esc space */
3585d522f475Smrg	    sp->parsestate = esc_sp_table;
3586d522f475Smrg	    break;
3587d522f475Smrg
3588d522f475Smrg	case CASE_CSI_EX_STATE:
3589d522f475Smrg	    /* csi exclamation */
3590d522f475Smrg	    sp->parsestate = csi_ex_table;
3591d522f475Smrg	    break;
3592d522f475Smrg
3593d522f475Smrg#if OPT_DEC_LOCATOR
3594d522f475Smrg	case CASE_CSI_TICK_STATE:
3595d522f475Smrg	    /* csi tick (') */
3596d522f475Smrg	    sp->parsestate = csi_tick_table;
3597d522f475Smrg	    break;
3598d522f475Smrg
3599d522f475Smrg	case CASE_DECEFR:
3600d522f475Smrg	    TRACE(("CASE_DECEFR - Enable Filter Rectangle\n"));
3601d522f475Smrg	    if (screen->send_mouse_pos == DEC_LOCATOR) {
3602d522f475Smrg		MotionOff(screen, xw);
36030bd37d32Smrg		if ((screen->loc_filter_top = GetParam(0)) < 1)
3604d522f475Smrg		    screen->loc_filter_top = LOC_FILTER_POS;
36050bd37d32Smrg		if (nparam < 2
36060bd37d32Smrg		    || (screen->loc_filter_left = GetParam(1)) < 1)
3607d522f475Smrg		    screen->loc_filter_left = LOC_FILTER_POS;
36080bd37d32Smrg		if (nparam < 3
36090bd37d32Smrg		    || (screen->loc_filter_bottom = GetParam(2)) < 1)
3610d522f475Smrg		    screen->loc_filter_bottom = LOC_FILTER_POS;
36110bd37d32Smrg		if (nparam < 4
36120bd37d32Smrg		    || (screen->loc_filter_right = GetParam(3)) < 1)
3613d522f475Smrg		    screen->loc_filter_right = LOC_FILTER_POS;
3614d522f475Smrg		InitLocatorFilter(xw);
3615d522f475Smrg	    }
361620d2c4d2Smrg	    ResetState(sp);
3617d522f475Smrg	    break;
3618d522f475Smrg
3619d522f475Smrg	case CASE_DECELR:
3620d522f475Smrg	    MotionOff(screen, xw);
36210bd37d32Smrg	    if (GetParam(0) <= 0 || GetParam(0) > 2) {
3622d522f475Smrg		screen->send_mouse_pos = MOUSE_OFF;
3623d522f475Smrg		TRACE(("DECELR - Disable Locator Reports\n"));
3624d522f475Smrg	    } else {
3625d522f475Smrg		TRACE(("DECELR - Enable Locator Reports\n"));
3626d522f475Smrg		screen->send_mouse_pos = DEC_LOCATOR;
3627d522f475Smrg		xtermShowPointer(xw, True);
36280bd37d32Smrg		if (GetParam(0) == 2) {
3629d522f475Smrg		    screen->locator_reset = True;
3630d522f475Smrg		} else {
3631d522f475Smrg		    screen->locator_reset = False;
3632d522f475Smrg		}
36330bd37d32Smrg		if (nparam < 2 || GetParam(1) != 1) {
3634d522f475Smrg		    screen->locator_pixels = False;
3635d522f475Smrg		} else {
3636d522f475Smrg		    screen->locator_pixels = True;
3637d522f475Smrg		}
3638d522f475Smrg		screen->loc_filter = False;
3639d522f475Smrg	    }
364020d2c4d2Smrg	    ResetState(sp);
3641d522f475Smrg	    break;
3642d522f475Smrg
3643d522f475Smrg	case CASE_DECSLE:
3644d522f475Smrg	    TRACE(("DECSLE - Select Locator Events\n"));
3645d522f475Smrg	    for (count = 0; count < nparam; ++count) {
36460bd37d32Smrg		switch (zero_if_default(count)) {
3647d522f475Smrg		case 0:
3648d522f475Smrg		    MotionOff(screen, xw);
3649d522f475Smrg		    screen->loc_filter = False;
3650d522f475Smrg		    screen->locator_events = 0;
3651d522f475Smrg		    break;
3652d522f475Smrg		case 1:
3653d522f475Smrg		    screen->locator_events |= LOC_BTNS_DN;
3654d522f475Smrg		    break;
3655d522f475Smrg		case 2:
365620d2c4d2Smrg		    UIntClr(screen->locator_events, LOC_BTNS_DN);
3657d522f475Smrg		    break;
3658d522f475Smrg		case 3:
3659d522f475Smrg		    screen->locator_events |= LOC_BTNS_UP;
3660d522f475Smrg		    break;
3661d522f475Smrg		case 4:
366220d2c4d2Smrg		    UIntClr(screen->locator_events, LOC_BTNS_UP);
3663d522f475Smrg		    break;
3664d522f475Smrg		}
3665d522f475Smrg	    }
366620d2c4d2Smrg	    ResetState(sp);
3667d522f475Smrg	    break;
3668d522f475Smrg
3669d522f475Smrg	case CASE_DECRQLP:
3670d522f475Smrg	    TRACE(("DECRQLP - Request Locator Position\n"));
36710bd37d32Smrg	    if (GetParam(0) < 2) {
3672d522f475Smrg		/* Issue DECLRP Locator Position Report */
3673d522f475Smrg		GetLocatorPosition(xw);
3674d522f475Smrg	    }
367520d2c4d2Smrg	    ResetState(sp);
3676d522f475Smrg	    break;
3677d522f475Smrg#endif /* OPT_DEC_LOCATOR */
3678d522f475Smrg
3679d522f475Smrg#if OPT_DEC_RECTOPS
3680d522f475Smrg	case CASE_CSI_DOLLAR_STATE:
3681492d43a5Smrg	    TRACE(("CASE_CSI_DOLLAR_STATE\n"));
3682d522f475Smrg	    /* csi dollar ($) */
3683492d43a5Smrg	    if (screen->vtXX_level >= 3)
3684d522f475Smrg		sp->parsestate = csi_dollar_table;
3685d522f475Smrg	    else
3686d522f475Smrg		sp->parsestate = eigtable;
3687d522f475Smrg	    break;
3688d522f475Smrg
3689d522f475Smrg	case CASE_CSI_STAR_STATE:
3690492d43a5Smrg	    TRACE(("CASE_CSI_STAR_STATE\n"));
3691492d43a5Smrg	    /* csi star (*) */
3692d522f475Smrg	    if (screen->vtXX_level >= 4)
3693d522f475Smrg		sp->parsestate = csi_star_table;
3694d522f475Smrg	    else
3695d522f475Smrg		sp->parsestate = eigtable;
3696d522f475Smrg	    break;
3697d522f475Smrg
36980bd37d32Smrg	case CASE_DECRQCRA:
36990bd37d32Smrg	    if (screen->vtXX_level >= 4) {
37000bd37d32Smrg		int checksum;
37010bd37d32Smrg
37020bd37d32Smrg		TRACE(("CASE_DECRQCRA - Request checksum of rectangular area\n"));
37030bd37d32Smrg		xtermCheckRect(xw, ParamPair(0), &checksum);
37040bd37d32Smrg		init_reply(ANSI_DCS);
37050bd37d32Smrg		count = 0;
37060bd37d32Smrg		reply.a_param[count++] = (ParmType) GetParam(1);	/* PID */
37070bd37d32Smrg		reply.a_delim = "!~";	/* delimiter */
37080bd37d32Smrg		reply.a_radix[count] = 16;
37090bd37d32Smrg		reply.a_param[count++] = (ParmType) checksum;
37100bd37d32Smrg		reply.a_nparam = (ParmType) count;
37110bd37d32Smrg		unparseseq(xw, &reply);
37120bd37d32Smrg	    }
37130bd37d32Smrg	    ResetState(sp);
37140bd37d32Smrg	    break;
37150bd37d32Smrg
3716d522f475Smrg	case CASE_DECCRA:
3717492d43a5Smrg	    if (screen->vtXX_level >= 4) {
3718492d43a5Smrg		TRACE(("CASE_DECCRA - Copy rectangular area\n"));
37190bd37d32Smrg		xtermParseRect(xw, ParamPair(0), &myRect);
37200bd37d32Smrg		ScrnCopyRectangle(xw, &myRect, ParamPair(5));
3721492d43a5Smrg	    }
372220d2c4d2Smrg	    ResetState(sp);
3723d522f475Smrg	    break;
3724d522f475Smrg
3725d522f475Smrg	case CASE_DECERA:
3726492d43a5Smrg	    if (screen->vtXX_level >= 4) {
3727492d43a5Smrg		TRACE(("CASE_DECERA - Erase rectangular area\n"));
37280bd37d32Smrg		xtermParseRect(xw, ParamPair(0), &myRect);
3729492d43a5Smrg		ScrnFillRectangle(xw, &myRect, ' ', 0, True);
3730492d43a5Smrg	    }
373120d2c4d2Smrg	    ResetState(sp);
3732d522f475Smrg	    break;
3733d522f475Smrg
3734d522f475Smrg	case CASE_DECFRA:
3735492d43a5Smrg	    if (screen->vtXX_level >= 4) {
37360bd37d32Smrg		value = zero_if_default(0);
37370bd37d32Smrg
3738492d43a5Smrg		TRACE(("CASE_DECFRA - Fill rectangular area\n"));
3739492d43a5Smrg		if (nparam > 0
37400bd37d32Smrg		    && ((value >= 32 && value <= 126)
37410bd37d32Smrg			|| (value >= 160 && value <= 255))) {
37420bd37d32Smrg		    xtermParseRect(xw, ParamPair(1), &myRect);
37430bd37d32Smrg		    ScrnFillRectangle(xw, &myRect, value, xw->flags, True);
3744492d43a5Smrg		}
3745d522f475Smrg	    }
374620d2c4d2Smrg	    ResetState(sp);
3747d522f475Smrg	    break;
3748d522f475Smrg
3749d522f475Smrg	case CASE_DECSERA:
3750492d43a5Smrg	    if (screen->vtXX_level >= 4) {
3751492d43a5Smrg		TRACE(("CASE_DECSERA - Selective erase rectangular area\n"));
37520bd37d32Smrg		xtermParseRect(xw, ParamPair(0), &myRect);
3753492d43a5Smrg		ScrnWipeRectangle(xw, &myRect);
3754492d43a5Smrg	    }
375520d2c4d2Smrg	    ResetState(sp);
3756d522f475Smrg	    break;
3757d522f475Smrg
3758d522f475Smrg	case CASE_DECSACE:
3759d522f475Smrg	    TRACE(("CASE_DECSACE - Select attribute change extent\n"));
37600bd37d32Smrg	    screen->cur_decsace = zero_if_default(0);
376120d2c4d2Smrg	    ResetState(sp);
3762d522f475Smrg	    break;
3763d522f475Smrg
3764d522f475Smrg	case CASE_DECCARA:
3765492d43a5Smrg	    if (screen->vtXX_level >= 4) {
3766492d43a5Smrg		TRACE(("CASE_DECCARA - Change attributes in rectangular area\n"));
37670bd37d32Smrg		xtermParseRect(xw, ParamPair(0), &myRect);
37680bd37d32Smrg		ScrnMarkRectangle(xw, &myRect, False, ParamPair(4));
3769492d43a5Smrg	    }
377020d2c4d2Smrg	    ResetState(sp);
3771d522f475Smrg	    break;
3772d522f475Smrg
3773d522f475Smrg	case CASE_DECRARA:
3774492d43a5Smrg	    if (screen->vtXX_level >= 4) {
3775492d43a5Smrg		TRACE(("CASE_DECRARA - Reverse attributes in rectangular area\n"));
37760bd37d32Smrg		xtermParseRect(xw, ParamPair(0), &myRect);
37770bd37d32Smrg		ScrnMarkRectangle(xw, &myRect, True, ParamPair(4));
3778492d43a5Smrg	    }
3779492d43a5Smrg	    ResetState(sp);
3780492d43a5Smrg	    break;
3781492d43a5Smrg
3782492d43a5Smrg	case CASE_RQM:
3783492d43a5Smrg	    TRACE(("CASE_RQM\n"));
37840bd37d32Smrg	    do_rpm(xw, ParamPair(0));
3785492d43a5Smrg	    ResetState(sp);
3786492d43a5Smrg	    break;
3787492d43a5Smrg
3788492d43a5Smrg	case CASE_DECRQM:
3789492d43a5Smrg	    TRACE(("CASE_DECRQM\n"));
37900bd37d32Smrg	    do_decrpm(xw, ParamPair(0));
379120d2c4d2Smrg	    ResetState(sp);
3792d522f475Smrg	    break;
3793492d43a5Smrg
3794492d43a5Smrg	case CASE_CSI_DEC_DOLLAR_STATE:
3795492d43a5Smrg	    TRACE(("CASE_CSI_DEC_DOLLAR_STATE\n"));
3796492d43a5Smrg	    /* csi ? dollar ($) */
3797492d43a5Smrg	    sp->parsestate = csi_dec_dollar_table;
3798492d43a5Smrg	    break;
3799d522f475Smrg#else
3800d522f475Smrg	case CASE_CSI_DOLLAR_STATE:
3801d522f475Smrg	    /* csi dollar ($) */
3802d522f475Smrg	    sp->parsestate = eigtable;
3803d522f475Smrg	    break;
3804d522f475Smrg
3805d522f475Smrg	case CASE_CSI_STAR_STATE:
3806d522f475Smrg	    /* csi dollar (*) */
3807d522f475Smrg	    sp->parsestate = eigtable;
3808d522f475Smrg	    break;
3809492d43a5Smrg
3810492d43a5Smrg	case CASE_CSI_DEC_DOLLAR_STATE:
3811492d43a5Smrg	    /* csi ? dollar ($) */
3812492d43a5Smrg	    sp->parsestate = eigtable;
3813492d43a5Smrg	    break;
3814d522f475Smrg#endif /* OPT_DEC_RECTOPS */
3815d522f475Smrg
3816d522f475Smrg	case CASE_S7C1T:
3817d522f475Smrg	    TRACE(("CASE_S7C1T\n"));
38180bd37d32Smrg	    if (screen->vtXX_level >= 2) {
38190bd37d32Smrg		show_8bit_control(False);
38200bd37d32Smrg		ResetState(sp);
38210bd37d32Smrg	    }
3822d522f475Smrg	    break;
3823d522f475Smrg
3824d522f475Smrg	case CASE_S8C1T:
3825d522f475Smrg	    TRACE(("CASE_S8C1T\n"));
38260bd37d32Smrg	    if (screen->vtXX_level >= 2) {
3827d522f475Smrg#if OPT_VT52_MODE
38280bd37d32Smrg		if (screen->vtXX_level <= 1)
38290bd37d32Smrg		    break;
3830d522f475Smrg#endif
38310bd37d32Smrg		show_8bit_control(True);
38320bd37d32Smrg		ResetState(sp);
38330bd37d32Smrg	    }
3834d522f475Smrg	    break;
3835d522f475Smrg
3836d522f475Smrg	case CASE_OSC:
3837d522f475Smrg	    TRACE(("CASE_OSC: Operating System Command\n"));
3838d522f475Smrg	    sp->parsestate = sos_table;
3839d522f475Smrg	    sp->string_mode = ANSI_OSC;
3840d522f475Smrg	    break;
3841d522f475Smrg
3842d522f475Smrg	case CASE_RIS:
3843d522f475Smrg	    TRACE(("CASE_RIS\n"));
3844d522f475Smrg	    VTReset(xw, True, True);
384520d2c4d2Smrg	    ResetState(sp);
3846d522f475Smrg	    break;
3847d522f475Smrg
3848d522f475Smrg	case CASE_DECSTR:
3849d522f475Smrg	    TRACE(("CASE_DECSTR\n"));
3850d522f475Smrg	    VTReset(xw, False, False);
385120d2c4d2Smrg	    ResetState(sp);
3852d522f475Smrg	    break;
3853d522f475Smrg
3854d522f475Smrg	case CASE_REP:
3855d522f475Smrg	    TRACE(("CASE_REP\n"));
3856d522f475Smrg	    if (sp->lastchar >= 0 &&
3857d522f475Smrg		sp->lastchar < 256 &&
3858d522f475Smrg		sp->groundtable[E2A(sp->lastchar)] == CASE_PRINT) {
3859d522f475Smrg		IChar repeated[2];
38600bd37d32Smrg		count = one_if_default(0);
38612eaa94a1Schristos		repeated[0] = (IChar) sp->lastchar;
3862d522f475Smrg		while (count-- > 0) {
3863d522f475Smrg		    dotext(xw,
3864d522f475Smrg			   screen->gsets[(int) (screen->curgl)],
3865d522f475Smrg			   repeated, 1);
3866d522f475Smrg		}
3867d522f475Smrg	    }
386820d2c4d2Smrg	    ResetState(sp);
3869d522f475Smrg	    break;
3870d522f475Smrg
3871d522f475Smrg	case CASE_LS2:
3872d522f475Smrg	    TRACE(("CASE_LS2\n"));
3873d522f475Smrg	    screen->curgl = 2;
387420d2c4d2Smrg	    ResetState(sp);
3875d522f475Smrg	    break;
3876d522f475Smrg
3877d522f475Smrg	case CASE_LS3:
3878d522f475Smrg	    TRACE(("CASE_LS3\n"));
3879d522f475Smrg	    screen->curgl = 3;
388020d2c4d2Smrg	    ResetState(sp);
3881d522f475Smrg	    break;
3882d522f475Smrg
3883d522f475Smrg	case CASE_LS3R:
3884d522f475Smrg	    TRACE(("CASE_LS3R\n"));
3885d522f475Smrg	    screen->curgr = 3;
388620d2c4d2Smrg	    ResetState(sp);
3887d522f475Smrg	    break;
3888d522f475Smrg
3889d522f475Smrg	case CASE_LS2R:
3890d522f475Smrg	    TRACE(("CASE_LS2R\n"));
3891d522f475Smrg	    screen->curgr = 2;
389220d2c4d2Smrg	    ResetState(sp);
3893d522f475Smrg	    break;
3894d522f475Smrg
3895d522f475Smrg	case CASE_LS1R:
3896d522f475Smrg	    TRACE(("CASE_LS1R\n"));
3897d522f475Smrg	    screen->curgr = 1;
389820d2c4d2Smrg	    ResetState(sp);
3899d522f475Smrg	    break;
3900d522f475Smrg
3901d522f475Smrg	case CASE_XTERM_SAVE:
3902d522f475Smrg	    savemodes(xw);
390320d2c4d2Smrg	    ResetState(sp);
3904d522f475Smrg	    break;
3905d522f475Smrg
3906d522f475Smrg	case CASE_XTERM_RESTORE:
3907d522f475Smrg	    restoremodes(xw);
390820d2c4d2Smrg	    ResetState(sp);
3909d522f475Smrg	    break;
3910d522f475Smrg
3911d522f475Smrg	case CASE_XTERM_WINOPS:
3912d522f475Smrg	    TRACE(("CASE_XTERM_WINOPS\n"));
391320d2c4d2Smrg	    window_ops(xw);
391420d2c4d2Smrg	    ResetState(sp);
3915d522f475Smrg	    break;
3916d522f475Smrg#if OPT_WIDE_CHARS
3917d522f475Smrg	case CASE_ESC_PERCENT:
3918e0a2b6dfSmrg	    TRACE(("CASE_ESC_PERCENT\n"));
3919d522f475Smrg	    sp->parsestate = esc_pct_table;
3920d522f475Smrg	    break;
3921d522f475Smrg
3922d522f475Smrg	case CASE_UTF8:
3923d522f475Smrg	    /* If we did not set UTF-8 mode from resource or the
3924d522f475Smrg	     * command-line, allow it to be enabled/disabled by
3925d522f475Smrg	     * control sequence.
3926d522f475Smrg	     */
3927e0a2b6dfSmrg	    TRACE(("CASE_UTF8 wide:%d, utf8:%d, req:%s\n",
3928e0a2b6dfSmrg		   screen->wide_chars,
3929e0a2b6dfSmrg		   screen->utf8_mode,
3930e0a2b6dfSmrg		   BtoS(c == 'G')));
3931e0a2b6dfSmrg	    if ((!screen->wide_chars) && (c == 'G')) {
3932e0a2b6dfSmrg		WriteNow();
3933e0a2b6dfSmrg		ChangeToWide(xw);
3934e0a2b6dfSmrg	    }
3935d522f475Smrg	    if (screen->wide_chars
3936e0a2b6dfSmrg		&& !screen->utf8_always) {
3937d522f475Smrg		switchPtyData(screen, c == 'G');
3938d522f475Smrg		TRACE(("UTF8 mode %s\n",
3939d522f475Smrg		       BtoS(screen->utf8_mode)));
3940d522f475Smrg	    } else {
3941d522f475Smrg		TRACE(("UTF8 mode NOT turned %s (%s)\n",
3942d522f475Smrg		       BtoS(c == 'G'),
3943d522f475Smrg		       (screen->utf8_mode == uAlways)
3944d522f475Smrg		       ? "UTF-8 mode set from command-line"
3945d522f475Smrg		       : "wideChars resource was not set"));
3946d522f475Smrg	    }
394720d2c4d2Smrg	    ResetState(sp);
3948d522f475Smrg	    break;
3949e0a2b6dfSmrg
3950e0a2b6dfSmrg	case CASE_SCS_PERCENT:
3951e0a2b6dfSmrg	    TRACE(("CASE_SCS_PERCENT\n"));
3952e0a2b6dfSmrg	    sp->parsestate = scs_pct_table;
3953e0a2b6dfSmrg	    break;
3954e0a2b6dfSmrg
3955e0a2b6dfSmrg	case CASE_GSETS_PERCENT:
3956e0a2b6dfSmrg	    TRACE(("CASE_GSETS_PERCENT(%d) = '%c'\n", sp->scstype, c));
3957e0a2b6dfSmrg	    decode_scs(xw, sp->scstype, '%', (int) c);
3958e0a2b6dfSmrg	    ResetState(sp);
3959e0a2b6dfSmrg	    break;
3960d522f475Smrg#endif
3961d522f475Smrg#if OPT_MOD_FKEYS
3962d522f475Smrg	case CASE_SET_MOD_FKEYS:
3963d522f475Smrg	    TRACE(("CASE_SET_MOD_FKEYS\n"));
3964d522f475Smrg	    if (nparam >= 1) {
39650bd37d32Smrg		set_mod_fkeys(xw,
39660bd37d32Smrg			      GetParam(0),
39670bd37d32Smrg			      ((nparam > 1)
39680bd37d32Smrg			       ? GetParam(1)
39690bd37d32Smrg			       : DEFAULT),
39700bd37d32Smrg			      True);
3971d522f475Smrg	    } else {
39720bd37d32Smrg		for (value = 1; value <= 5; ++value)
39730bd37d32Smrg		    set_mod_fkeys(xw, value, DEFAULT, True);
3974d522f475Smrg	    }
3975d522f475Smrg	    break;
3976d522f475Smrg	case CASE_SET_MOD_FKEYS0:
3977d522f475Smrg	    TRACE(("CASE_SET_MOD_FKEYS0\n"));
39780bd37d32Smrg	    if (nparam >= 1 && GetParam(0) != DEFAULT) {
39790bd37d32Smrg		set_mod_fkeys(xw, GetParam(0), -1, False);
3980d522f475Smrg	    } else {
3981d522f475Smrg		xw->keyboard.modify_now.function_keys = -1;
3982d522f475Smrg	    }
3983d522f475Smrg	    break;
3984d522f475Smrg#endif
3985d522f475Smrg	case CASE_HIDE_POINTER:
3986d522f475Smrg	    TRACE(("CASE_HIDE_POINTER\n"));
39870bd37d32Smrg	    if (nparam >= 1 && GetParam(0) != DEFAULT) {
39880bd37d32Smrg		screen->pointer_mode = GetParam(0);
3989d522f475Smrg	    } else {
3990d522f475Smrg		screen->pointer_mode = DEF_POINTER_MODE;
3991d522f475Smrg	    }
3992d522f475Smrg	    break;
3993d522f475Smrg
399420d2c4d2Smrg	case CASE_SM_TITLE:
399520d2c4d2Smrg	    TRACE(("CASE_SM_TITLE\n"));
399620d2c4d2Smrg	    if (nparam >= 1) {
399720d2c4d2Smrg		int n;
399820d2c4d2Smrg		for (n = 0; n < nparam; ++n) {
39990bd37d32Smrg		    if (GetParam(n) != DEFAULT)
40000bd37d32Smrg			screen->title_modes |= (1 << GetParam(n));
400120d2c4d2Smrg		}
400220d2c4d2Smrg	    } else {
400320d2c4d2Smrg		screen->title_modes = DEF_TITLE_MODES;
400420d2c4d2Smrg	    }
400520d2c4d2Smrg	    TRACE(("...title_modes %#x\n", screen->title_modes));
400620d2c4d2Smrg	    break;
400720d2c4d2Smrg
400820d2c4d2Smrg	case CASE_RM_TITLE:
400920d2c4d2Smrg	    TRACE(("CASE_RM_TITLE\n"));
401020d2c4d2Smrg	    if (nparam >= 1) {
401120d2c4d2Smrg		int n;
401220d2c4d2Smrg		for (n = 0; n < nparam; ++n) {
40130bd37d32Smrg		    if (GetParam(n) != DEFAULT)
40140bd37d32Smrg			screen->title_modes &= ~(1 << GetParam(n));
401520d2c4d2Smrg		}
401620d2c4d2Smrg	    } else {
401720d2c4d2Smrg		screen->title_modes = DEF_TITLE_MODES;
401820d2c4d2Smrg	    }
401920d2c4d2Smrg	    TRACE(("...title_modes %#x\n", screen->title_modes));
402020d2c4d2Smrg	    break;
402120d2c4d2Smrg
4022d522f475Smrg	case CASE_CSI_IGNORE:
4023d522f475Smrg	    sp->parsestate = cigtable;
4024d522f475Smrg	    break;
402520d2c4d2Smrg
402620d2c4d2Smrg	case CASE_DECSWBV:
402720d2c4d2Smrg	    TRACE(("CASE_DECSWBV\n"));
40280bd37d32Smrg	    switch (zero_if_default(0)) {
402920d2c4d2Smrg	    case 2:
403020d2c4d2Smrg	    case 3:
403120d2c4d2Smrg	    case 4:
403220d2c4d2Smrg		screen->warningVolume = bvLow;
403320d2c4d2Smrg		break;
403420d2c4d2Smrg	    case 5:
403520d2c4d2Smrg	    case 6:
403620d2c4d2Smrg	    case 7:
403720d2c4d2Smrg	    case 8:
403820d2c4d2Smrg		screen->warningVolume = bvHigh;
403920d2c4d2Smrg		break;
404020d2c4d2Smrg	    default:
404120d2c4d2Smrg		screen->warningVolume = bvOff;
404220d2c4d2Smrg		break;
404320d2c4d2Smrg	    }
404420d2c4d2Smrg	    TRACE(("...warningVolume %d\n", screen->warningVolume));
404520d2c4d2Smrg	    ResetState(sp);
404620d2c4d2Smrg	    break;
404720d2c4d2Smrg
404820d2c4d2Smrg	case CASE_DECSMBV:
404920d2c4d2Smrg	    TRACE(("CASE_DECSMBV\n"));
40500bd37d32Smrg	    switch (zero_if_default(0)) {
405120d2c4d2Smrg	    case 2:
405220d2c4d2Smrg	    case 3:
405320d2c4d2Smrg	    case 4:
405420d2c4d2Smrg		screen->marginVolume = bvLow;
405520d2c4d2Smrg		break;
405620d2c4d2Smrg	    case 0:
405720d2c4d2Smrg	    case 5:
405820d2c4d2Smrg	    case 6:
405920d2c4d2Smrg	    case 7:
406020d2c4d2Smrg	    case 8:
406120d2c4d2Smrg		screen->marginVolume = bvHigh;
406220d2c4d2Smrg		break;
406320d2c4d2Smrg	    default:
406420d2c4d2Smrg		screen->marginVolume = bvOff;
406520d2c4d2Smrg		break;
406620d2c4d2Smrg	    }
406720d2c4d2Smrg	    TRACE(("...marginVolume %d\n", screen->marginVolume));
406820d2c4d2Smrg	    ResetState(sp);
406920d2c4d2Smrg	    break;
4070d522f475Smrg	}
4071d522f475Smrg	if (sp->parsestate == sp->groundtable)
4072d522f475Smrg	    sp->lastchar = thischar;
4073d522f475Smrg    } while (0);
4074d522f475Smrg
4075d522f475Smrg#if OPT_WIDE_CHARS
40762eaa94a1Schristos    screen->utf8_inparse = (Boolean) ((screen->utf8_mode != uFalse)
40772eaa94a1Schristos				      && (sp->parsestate != sos_table));
4078d522f475Smrg#endif
4079d522f475Smrg
4080d522f475Smrg    return True;
4081d522f475Smrg}
4082d522f475Smrg
4083d522f475Smrgstatic void
4084d522f475SmrgVTparse(XtermWidget xw)
4085d522f475Smrg{
4086d522f475Smrg    /* We longjmp back to this point in VTReset() */
4087d522f475Smrg    (void) setjmp(vtjmpbuf);
4088e39b573cSmrg    init_parser(xw, &myState);
40892eaa94a1Schristos
4090d522f475Smrg    do {
4091d522f475Smrg    } while (doparsing(xw, doinput(), &myState));
4092d522f475Smrg}
4093d522f475Smrg
4094d522f475Smrgstatic Char *v_buffer;		/* pointer to physical buffer */
4095d522f475Smrgstatic Char *v_bufstr = NULL;	/* beginning of area to write */
4096d522f475Smrgstatic Char *v_bufptr;		/* end of area to write */
4097d522f475Smrgstatic Char *v_bufend;		/* end of physical buffer */
4098d522f475Smrg
4099d522f475Smrg/* Write data to the pty as typed by the user, pasted with the mouse,
4100d522f475Smrg   or generated by us in response to a query ESC sequence. */
4101d522f475Smrg
410220d2c4d2Smrgvoid
4103e0a2b6dfSmrgv_write(int f, const Char *data, unsigned len)
4104d522f475Smrg{
4105d522f475Smrg    int riten;
4106d522f475Smrg
410720d2c4d2Smrg    TRACE2(("v_write(%d:%s)\n", len, visibleChars(data, len)));
41080bd37d32Smrg    if (v_bufstr == NULL) {
41090bd37d32Smrg	if (len > 0) {
41100bd37d32Smrg	    v_buffer = (Char *) XtMalloc((Cardinal) len);
41110bd37d32Smrg	    v_bufstr = v_buffer;
41120bd37d32Smrg	    v_bufptr = v_buffer;
41130bd37d32Smrg	    v_bufend = v_buffer + len;
41140bd37d32Smrg	}
41150bd37d32Smrg	if (v_bufstr == NULL) {
41160bd37d32Smrg	    return;
41170bd37d32Smrg	}
41180bd37d32Smrg    }
41190bd37d32Smrg    if_DEBUG({
41200bd37d32Smrg	fprintf(stderr, "v_write called with %d bytes (%ld left over)",
41210bd37d32Smrg		len, (long) (v_bufptr - v_bufstr));
4122d522f475Smrg	if (len > 1 && len < 10)
4123492d43a5Smrg	    fprintf(stderr, " \"%.*s\"", len, (const char *) data);
4124d522f475Smrg	fprintf(stderr, "\n");
41250bd37d32Smrg    });
4126d522f475Smrg
4127d522f475Smrg#ifdef VMS
412820d2c4d2Smrg    if ((1 << f) != pty_mask) {
4129492d43a5Smrg	tt_write((const char *) data, len);
413020d2c4d2Smrg	return;
413120d2c4d2Smrg    }
4132d522f475Smrg#else /* VMS */
413320d2c4d2Smrg    if (!FD_ISSET(f, &pty_mask)) {
4134492d43a5Smrg	IGNORE_RC(write(f, (const char *) data, (size_t) len));
413520d2c4d2Smrg	return;
413620d2c4d2Smrg    }
4137d522f475Smrg#endif /* VMS */
4138d522f475Smrg
4139d522f475Smrg    /*
4140d522f475Smrg     * Append to the block we already have.
4141d522f475Smrg     * Always doing this simplifies the code, and
4142d522f475Smrg     * isn't too bad, either.  If this is a short
4143d522f475Smrg     * block, it isn't too expensive, and if this is
4144d522f475Smrg     * a long block, we won't be able to write it all
4145d522f475Smrg     * anyway.
4146d522f475Smrg     */
4147d522f475Smrg
4148d522f475Smrg    if (len > 0) {
4149d522f475Smrg#if OPT_DABBREV
415020d2c4d2Smrg	TScreenOf(term)->dabbrev_working = False;	/* break dabbrev sequence */
4151d522f475Smrg#endif
4152d522f475Smrg	if (v_bufend < v_bufptr + len) {	/* we've run out of room */
4153d522f475Smrg	    if (v_bufstr != v_buffer) {
4154d522f475Smrg		/* there is unused space, move everything down */
4155d522f475Smrg		/* possibly overlapping memmove here */
41560bd37d32Smrg		if_DEBUG({
41570bd37d32Smrg		    fprintf(stderr, "moving data down %ld\n",
41580bd37d32Smrg			    (long) (v_bufstr - v_buffer));
41590bd37d32Smrg		});
416020d2c4d2Smrg		memmove(v_buffer, v_bufstr, (size_t) (v_bufptr - v_bufstr));
4161d522f475Smrg		v_bufptr -= v_bufstr - v_buffer;
4162d522f475Smrg		v_bufstr = v_buffer;
4163d522f475Smrg	    }
4164d522f475Smrg	    if (v_bufend < v_bufptr + len) {
4165d522f475Smrg		/* still won't fit: get more space */
4166d522f475Smrg		/* Don't use XtRealloc because an error is not fatal. */
41672eaa94a1Schristos		unsigned size = (unsigned) (v_bufptr - v_buffer);
4168d522f475Smrg		v_buffer = TypeRealloc(Char, size + len, v_buffer);
4169d522f475Smrg		if (v_buffer) {
41700bd37d32Smrg		    if_DEBUG({
4171d522f475Smrg			fprintf(stderr, "expanded buffer to %d\n",
4172d522f475Smrg				size + len);
41730bd37d32Smrg		    });
4174d522f475Smrg		    v_bufstr = v_buffer;
4175d522f475Smrg		    v_bufptr = v_buffer + size;
4176d522f475Smrg		    v_bufend = v_bufptr + len;
4177d522f475Smrg		} else {
4178d522f475Smrg		    /* no memory: ignore entire write request */
41790bd37d32Smrg		    xtermWarning("cannot allocate buffer space\n");
4180d522f475Smrg		    v_buffer = v_bufstr;	/* restore clobbered pointer */
4181d522f475Smrg		}
4182d522f475Smrg	    }
4183d522f475Smrg	}
4184d522f475Smrg	if (v_bufend >= v_bufptr + len) {
4185d522f475Smrg	    /* new stuff will fit */
418620d2c4d2Smrg	    memmove(v_bufptr, data, (size_t) len);
4187d522f475Smrg	    v_bufptr += len;
4188d522f475Smrg	}
4189d522f475Smrg    }
4190d522f475Smrg
4191d522f475Smrg    /*
4192d522f475Smrg     * Write out as much of the buffer as we can.
4193d522f475Smrg     * Be careful not to overflow the pty's input silo.
4194d522f475Smrg     * We are conservative here and only write
4195d522f475Smrg     * a small amount at a time.
4196d522f475Smrg     *
4197d522f475Smrg     * If we can't push all the data into the pty yet, we expect write
4198d522f475Smrg     * to return a non-negative number less than the length requested
4199d522f475Smrg     * (if some data written) or -1 and set errno to EAGAIN,
4200d522f475Smrg     * EWOULDBLOCK, or EINTR (if no data written).
4201d522f475Smrg     *
4202d522f475Smrg     * (Not all systems do this, sigh, so the code is actually
4203d522f475Smrg     * a little more forgiving.)
4204d522f475Smrg     */
4205d522f475Smrg
4206d522f475Smrg#define MAX_PTY_WRITE 128	/* 1/2 POSIX minimum MAX_INPUT */
4207d522f475Smrg
4208d522f475Smrg    if (v_bufptr > v_bufstr) {
4209d522f475Smrg#ifdef VMS
4210d522f475Smrg	riten = tt_write(v_bufstr,
4211d522f475Smrg			 ((v_bufptr - v_bufstr <= VMS_TERM_BUFFER_SIZE)
4212d522f475Smrg			  ? v_bufptr - v_bufstr
4213d522f475Smrg			  : VMS_TERM_BUFFER_SIZE));
4214d522f475Smrg	if (riten == 0)
4215d522f475Smrg	    return (riten);
4216d522f475Smrg#else /* VMS */
421720d2c4d2Smrg	riten = (int) write(f, v_bufstr,
421820d2c4d2Smrg			    (size_t) ((v_bufptr - v_bufstr <= MAX_PTY_WRITE)
421920d2c4d2Smrg				      ? v_bufptr - v_bufstr
422020d2c4d2Smrg				      : MAX_PTY_WRITE));
4221d522f475Smrg	if (riten < 0)
4222d522f475Smrg#endif /* VMS */
4223d522f475Smrg	{
42240bd37d32Smrg	    if_DEBUG({
4225d522f475Smrg		perror("write");
42260bd37d32Smrg	    });
4227d522f475Smrg	    riten = 0;
4228d522f475Smrg	}
42290bd37d32Smrg	if_DEBUG({
42300bd37d32Smrg	    fprintf(stderr, "write called with %ld, wrote %d\n",
42310bd37d32Smrg		    ((long) ((v_bufptr - v_bufstr) <= MAX_PTY_WRITE)
42320bd37d32Smrg		     ? (long) (v_bufptr - v_bufstr)
42330bd37d32Smrg		     : MAX_PTY_WRITE),
4234d522f475Smrg		    riten);
42350bd37d32Smrg	});
4236d522f475Smrg	v_bufstr += riten;
4237d522f475Smrg	if (v_bufstr >= v_bufptr)	/* we wrote it all */
4238d522f475Smrg	    v_bufstr = v_bufptr = v_buffer;
4239d522f475Smrg    }
4240d522f475Smrg
4241d522f475Smrg    /*
4242d522f475Smrg     * If we have lots of unused memory allocated, return it
4243d522f475Smrg     */
4244d522f475Smrg    if (v_bufend - v_bufptr > 1024) {	/* arbitrary hysteresis */
4245d522f475Smrg	/* save pointers across realloc */
424620d2c4d2Smrg	int start = (int) (v_bufstr - v_buffer);
424720d2c4d2Smrg	int size = (int) (v_bufptr - v_buffer);
4248d522f475Smrg	unsigned allocsize = (unsigned) (size ? size : 1);
4249d522f475Smrg
4250d522f475Smrg	v_buffer = TypeRealloc(Char, allocsize, v_buffer);
4251d522f475Smrg	if (v_buffer) {
4252d522f475Smrg	    v_bufstr = v_buffer + start;
4253d522f475Smrg	    v_bufptr = v_buffer + size;
4254d522f475Smrg	    v_bufend = v_buffer + allocsize;
42550bd37d32Smrg	    if_DEBUG({
4256d522f475Smrg		fprintf(stderr, "shrunk buffer to %d\n", allocsize);
42570bd37d32Smrg	    });
4258d522f475Smrg	} else {
4259d522f475Smrg	    /* should we print a warning if couldn't return memory? */
4260d522f475Smrg	    v_buffer = v_bufstr - start;	/* restore clobbered pointer */
4261d522f475Smrg	}
4262d522f475Smrg    }
4263d522f475Smrg}
4264d522f475Smrg
4265e39b573cSmrgstatic void
4266e0a2b6dfSmrgupdateCursor(TScreen *screen)
4267e39b573cSmrg{
4268e39b573cSmrg    if (screen->cursor_set != screen->cursor_state) {
4269e39b573cSmrg	if (screen->cursor_set)
4270e39b573cSmrg	    ShowCursor();
4271e39b573cSmrg	else
4272e39b573cSmrg	    HideCursor();
4273e39b573cSmrg    }
4274e39b573cSmrg}
4275e39b573cSmrg
42760bd37d32Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
4277e39b573cSmrgstatic void
4278e0a2b6dfSmrgreallyStopBlinking(TScreen *screen)
4279e39b573cSmrg{
4280e39b573cSmrg    if (screen->cursor_state == BLINKED_OFF) {
4281e39b573cSmrg	/* force cursor to display if it is enabled */
4282e39b573cSmrg	screen->cursor_state = !screen->cursor_set;
4283e39b573cSmrg	updateCursor(screen);
4284e39b573cSmrg	xevents();
4285e39b573cSmrg    }
4286e39b573cSmrg}
42870bd37d32Smrg#endif
4288e39b573cSmrg
4289d522f475Smrg#ifdef VMS
4290d522f475Smrg#define	ptymask()	(v_bufptr > v_bufstr ? pty_mask : 0)
4291d522f475Smrg
4292d522f475Smrgstatic void
4293d522f475Smrgin_put(XtermWidget xw)
4294d522f475Smrg{
4295d522f475Smrg    static PtySelect select_mask;
4296d522f475Smrg    static PtySelect write_mask;
4297d522f475Smrg    int update = VTbuffer->update;
4298d522f475Smrg    int size;
4299d522f475Smrg
4300d522f475Smrg    int status;
4301d522f475Smrg    Dimension replyWidth, replyHeight;
4302d522f475Smrg    XtGeometryResult stat;
4303d522f475Smrg
430420d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4305d522f475Smrg    char *cp;
4306d522f475Smrg    int i;
4307d522f475Smrg
4308d522f475Smrg    select_mask = pty_mask;	/* force initial read */
4309d522f475Smrg    for (;;) {
4310d522f475Smrg
4311d522f475Smrg	/* if the terminal changed size, resize the widget */
4312d522f475Smrg	if (tt_changed) {
4313d522f475Smrg	    tt_changed = False;
4314d522f475Smrg
43152eaa94a1Schristos	    stat = REQ_RESIZE((Widget) xw,
43162eaa94a1Schristos			      ((Dimension) FontWidth(screen)
43172eaa94a1Schristos			       * (tt_width)
43182eaa94a1Schristos			       + 2 * screen->border
43192eaa94a1Schristos			       + screen->fullVwin.sb_info.width),
43202eaa94a1Schristos			      ((Dimension) FontHeight(screen)
43212eaa94a1Schristos			       * (tt_length)
43222eaa94a1Schristos			       + 2 * screen->border),
43232eaa94a1Schristos			      &replyWidth, &replyHeight);
4324d522f475Smrg
4325d522f475Smrg	    if (stat == XtGeometryYes || stat == XtGeometryDone) {
4326d522f475Smrg		xw->core.width = replyWidth;
4327d522f475Smrg		xw->core.height = replyHeight;
4328d522f475Smrg
4329d522f475Smrg		ScreenResize(xw, replyWidth, replyHeight, &xw->flags);
4330d522f475Smrg	    }
4331d522f475Smrg	    repairSizeHints();
4332d522f475Smrg	}
4333d522f475Smrg
4334d522f475Smrg	if (screen->eventMode == NORMAL
433520d2c4d2Smrg	    && readPtyData(xw, &select_mask, VTbuffer)) {
4336d522f475Smrg	    if (screen->scrollWidget
4337d522f475Smrg		&& screen->scrollttyoutput
4338d522f475Smrg		&& screen->topline < 0)
4339d522f475Smrg		/* Scroll to bottom */
434020d2c4d2Smrg		WindowScroll(xw, 0, False);
4341d522f475Smrg	    break;
4342d522f475Smrg	}
4343d522f475Smrg	if (screen->scroll_amt)
4344d522f475Smrg	    FlushScroll(xw);
4345d522f475Smrg	if (screen->cursor_set && CursorMoved(screen)) {
4346d522f475Smrg	    if (screen->cursor_state)
4347d522f475Smrg		HideCursor();
4348d522f475Smrg	    ShowCursor();
43490bd37d32Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
43500bd37d32Smrg	    PreeditPosition(xw);
4351d522f475Smrg#endif
4352e39b573cSmrg	} else {
4353e39b573cSmrg	    updateCursor(screen);
4354d522f475Smrg	}
4355d522f475Smrg
4356d522f475Smrg	if (QLength(screen->display)) {
4357d522f475Smrg	    select_mask = X_mask;
4358d522f475Smrg	} else {
4359d522f475Smrg	    write_mask = ptymask();
4360d522f475Smrg	    XFlush(screen->display);
4361d522f475Smrg	    select_mask = Select_mask;
4362d522f475Smrg	    if (screen->eventMode != NORMAL)
4363d522f475Smrg		select_mask = X_mask;
4364d522f475Smrg	}
4365d522f475Smrg	if (write_mask & ptymask()) {
4366d522f475Smrg	    v_write(screen->respond, 0, 0);	/* flush buffer */
4367d522f475Smrg	}
4368d522f475Smrg
4369d522f475Smrg	if (select_mask & X_mask) {
4370d522f475Smrg	    xevents();
4371d522f475Smrg	    if (VTbuffer->update != update)
4372d522f475Smrg		break;
4373d522f475Smrg	}
4374d522f475Smrg    }
4375d522f475Smrg}
4376d522f475Smrg#else /* VMS */
4377d522f475Smrg
4378d522f475Smrgstatic void
4379d522f475Smrgin_put(XtermWidget xw)
4380d522f475Smrg{
4381d522f475Smrg    static PtySelect select_mask;
4382d522f475Smrg    static PtySelect write_mask;
4383d522f475Smrg
438420d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4385d522f475Smrg    int i, time_select;
4386d522f475Smrg    int size;
4387d522f475Smrg    int update = VTbuffer->update;
43880bd37d32Smrg#if OPT_DOUBLE_BUFFER
43890bd37d32Smrg    int should_wait = 1;
43900bd37d32Smrg#endif
4391d522f475Smrg
4392d522f475Smrg    static struct timeval select_timeout;
4393d522f475Smrg
4394d522f475Smrg#if OPT_BLINK_CURS
4395d522f475Smrg    /*
4396d522f475Smrg     * Compute the timeout for the blinking cursor to be much smaller than
4397d522f475Smrg     * the "on" or "off" interval.
4398d522f475Smrg     */
4399d522f475Smrg    int tick = ((screen->blink_on < screen->blink_off)
4400d522f475Smrg		? screen->blink_on
4401d522f475Smrg		: screen->blink_off);
4402d522f475Smrg    tick *= (1000 / 8);		/* 1000 for msec/usec, 8 for "much" smaller */
4403d522f475Smrg    if (tick < 1)
4404d522f475Smrg	tick = 1;
4405d522f475Smrg#endif
4406d522f475Smrg
4407d522f475Smrg    for (;;) {
4408d522f475Smrg	if (screen->eventMode == NORMAL
440920d2c4d2Smrg	    && (size = readPtyData(xw, &select_mask, VTbuffer)) != 0) {
4410d522f475Smrg	    if (screen->scrollWidget
4411d522f475Smrg		&& screen->scrollttyoutput
4412d522f475Smrg		&& screen->topline < 0)
441320d2c4d2Smrg		WindowScroll(xw, 0, False);	/* Scroll to bottom */
4414d522f475Smrg	    /* stop speed reading at some point to look for X stuff */
441520d2c4d2Smrg	    TRACE(("VTbuffer uses %ld/%d\n",
441620d2c4d2Smrg		   (long) (VTbuffer->last - VTbuffer->buffer),
4417d522f475Smrg		   BUF_SIZE));
4418d522f475Smrg	    if ((VTbuffer->last - VTbuffer->buffer) > BUF_SIZE) {
4419d522f475Smrg		FD_CLR(screen->respond, &select_mask);
4420d522f475Smrg		break;
4421d522f475Smrg	    }
44220bd37d32Smrg#if OPT_DOUBLE_BUFFER
44230bd37d32Smrg	    if (should_wait) {
44240bd37d32Smrg		/* wait 25 msec for potential extra data (avoids some bogus flickering) */
44250bd37d32Smrg		/* that's only 40 FPS but hey, it's still lower than the input lag on some consoles! :) */
44260bd37d32Smrg		usleep(25000);
44270bd37d32Smrg		should_wait = 0;
44280bd37d32Smrg	    }
44290bd37d32Smrg	    select_timeout.tv_sec = 0;
44300bd37d32Smrg	    i = Select(max_plus1, &select_mask, &write_mask, 0,
44310bd37d32Smrg		       &select_timeout);
44320bd37d32Smrg	    if (i > 0 && FD_ISSET(screen->respond, &select_mask))
44330bd37d32Smrg		continue;
44340bd37d32Smrg	    else
44350bd37d32Smrg		break;
44360bd37d32Smrg#elif defined(HAVE_SCHED_YIELD)
4437d522f475Smrg	    /*
4438d522f475Smrg	     * If we've read a full (small/fragment) buffer, let the operating
4439d522f475Smrg	     * system have a turn, and we'll resume reading until we've either
4440d522f475Smrg	     * read only a fragment of the buffer, or we've filled the large
4441d522f475Smrg	     * buffer (see above).  Doing this helps keep up with large bursts
4442d522f475Smrg	     * of output.
4443d522f475Smrg	     */
4444d522f475Smrg	    if (size == FRG_SIZE) {
4445d522f475Smrg		select_timeout.tv_sec = 0;
4446d522f475Smrg		i = Select(max_plus1, &select_mask, &write_mask, 0,
4447d522f475Smrg			   &select_timeout);
44480bd37d32Smrg		if (i > 0 && FD_ISSET(screen->respond, &select_mask)) {
4449d522f475Smrg		    sched_yield();
4450d522f475Smrg		} else
4451d522f475Smrg		    break;
4452d522f475Smrg	    } else {
4453d522f475Smrg		break;
4454d522f475Smrg	    }
4455d522f475Smrg#else
4456d522f475Smrg	    (void) size;	/* unused in this branch */
4457d522f475Smrg	    break;
4458d522f475Smrg#endif
4459d522f475Smrg	}
4460d522f475Smrg	/* update the screen */
4461d522f475Smrg	if (screen->scroll_amt)
4462d522f475Smrg	    FlushScroll(xw);
4463d522f475Smrg	if (screen->cursor_set && CursorMoved(screen)) {
4464d522f475Smrg	    if (screen->cursor_state)
4465d522f475Smrg		HideCursor();
4466d522f475Smrg	    ShowCursor();
44670bd37d32Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
44680bd37d32Smrg	    PreeditPosition(xw);
4469d522f475Smrg#endif
4470e39b573cSmrg	} else {
4471e39b573cSmrg	    updateCursor(screen);
4472d522f475Smrg	}
4473d522f475Smrg
4474d522f475Smrg	XFlush(screen->display);	/* always flush writes before waiting */
4475d522f475Smrg
4476d522f475Smrg	/* Update the masks and, unless X events are already in the queue,
4477d522f475Smrg	   wait for I/O to be possible. */
4478d522f475Smrg	XFD_COPYSET(&Select_mask, &select_mask);
4479d522f475Smrg	/* in selection mode xterm does not read pty */
4480d522f475Smrg	if (screen->eventMode != NORMAL)
4481d522f475Smrg	    FD_CLR(screen->respond, &select_mask);
4482d522f475Smrg
4483d522f475Smrg	if (v_bufptr > v_bufstr) {
4484d522f475Smrg	    XFD_COPYSET(&pty_mask, &write_mask);
4485d522f475Smrg	} else
4486d522f475Smrg	    FD_ZERO(&write_mask);
4487d522f475Smrg	select_timeout.tv_sec = 0;
4488d522f475Smrg	time_select = 0;
4489d522f475Smrg
4490d522f475Smrg	/*
4491d522f475Smrg	 * if there's either an XEvent or an XtTimeout pending, just take
4492d522f475Smrg	 * a quick peek, i.e. timeout from the select() immediately.  If
4493d522f475Smrg	 * there's nothing pending, let select() block a little while, but
4494d522f475Smrg	 * for a shorter interval than the arrow-style scrollbar timeout.
4495d522f475Smrg	 * The blocking is optional, because it tends to increase the load
4496d522f475Smrg	 * on the host.
4497d522f475Smrg	 */
44980bd37d32Smrg	if (xtermAppPending()) {
4499d522f475Smrg	    select_timeout.tv_usec = 0;
4500d522f475Smrg	    time_select = 1;
4501d522f475Smrg	} else if (screen->awaitInput) {
4502d522f475Smrg	    select_timeout.tv_usec = 50000;
4503d522f475Smrg	    time_select = 1;
4504d522f475Smrg#if OPT_BLINK_CURS
4505d522f475Smrg	} else if ((screen->blink_timer != 0 &&
4506d522f475Smrg		    ((screen->select & FOCUS) || screen->always_highlight)) ||
4507d522f475Smrg		   (screen->cursor_state == BLINKED_OFF)) {
4508d522f475Smrg	    select_timeout.tv_usec = tick;
4509d522f475Smrg	    while (select_timeout.tv_usec > 1000000) {
4510d522f475Smrg		select_timeout.tv_usec -= 1000000;
4511d522f475Smrg		select_timeout.tv_sec++;
4512d522f475Smrg	    }
4513d522f475Smrg	    time_select = 1;
4514d522f475Smrg#endif
4515d522f475Smrg#if OPT_SESSION_MGT
4516d522f475Smrg	} else if (resource.sessionMgt) {
4517d522f475Smrg	    if (ice_fd >= 0)
4518d522f475Smrg		FD_SET(ice_fd, &select_mask);
4519d522f475Smrg#endif
4520d522f475Smrg	}
4521d522f475Smrg	if (need_cleanup)
45220bd37d32Smrg	    NormalExit();
45230bd37d32Smrg#if OPT_DOUBLE_BUFFER
45240bd37d32Smrg	if (screen->needSwap) {
45250bd37d32Smrg	    XdbeSwapInfo swap;
45260bd37d32Smrg	    swap.swap_window = VWindow(screen);
45270bd37d32Smrg	    swap.swap_action = XdbeCopied;
45280bd37d32Smrg	    XdbeSwapBuffers(XtDisplay(term), &swap, 1);
45290bd37d32Smrg	    XFlush(XtDisplay(xw));
45300bd37d32Smrg	    screen->needSwap = 0;
45310bd37d32Smrg	}
45320bd37d32Smrg#endif
4533d522f475Smrg	i = Select(max_plus1, &select_mask, &write_mask, 0,
4534d522f475Smrg		   (time_select ? &select_timeout : 0));
4535d522f475Smrg	if (i < 0) {
4536d522f475Smrg	    if (errno != EINTR)
4537d522f475Smrg		SysError(ERROR_SELECT);
4538d522f475Smrg	    continue;
4539d522f475Smrg	}
4540d522f475Smrg
4541d522f475Smrg	/* if there is room to write more data to the pty, go write more */
4542d522f475Smrg	if (FD_ISSET(screen->respond, &write_mask)) {
4543d522f475Smrg	    v_write(screen->respond, (Char *) 0, 0);	/* flush buffer */
4544d522f475Smrg	}
4545d522f475Smrg
4546d522f475Smrg	/* if there are X events already in our queue, it
4547d522f475Smrg	   counts as being readable */
45480bd37d32Smrg	if (xtermAppPending() ||
4549d522f475Smrg	    FD_ISSET(ConnectionNumber(screen->display), &select_mask)) {
4550d522f475Smrg	    xevents();
4551d522f475Smrg	    if (VTbuffer->update != update)	/* HandleInterpret */
4552d522f475Smrg		break;
4553d522f475Smrg	}
4554d522f475Smrg
4555d522f475Smrg    }
4556d522f475Smrg}
4557d522f475Smrg#endif /* VMS */
4558d522f475Smrg
4559d522f475Smrgstatic IChar
4560d522f475Smrgdoinput(void)
4561d522f475Smrg{
4562d522f475Smrg    TScreen *screen = TScreenOf(term);
4563d522f475Smrg
4564d522f475Smrg    while (!morePtyData(screen, VTbuffer))
4565d522f475Smrg	in_put(term);
4566d522f475Smrg    return nextPtyData(screen, VTbuffer);
4567d522f475Smrg}
4568d522f475Smrg
45690bd37d32Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
4570d522f475Smrg/*
4571d522f475Smrg *  For OverTheSpot, client has to inform the position for XIM preedit.
4572d522f475Smrg */
4573d522f475Smrgstatic void
45740bd37d32SmrgPreeditPosition(XtermWidget xw)
4575d522f475Smrg{
45760bd37d32Smrg    TInput *input = lookupTInput(xw, (Widget) xw);
45770bd37d32Smrg    TScreen *screen = TScreenOf(xw);
4578956cc18dSsnj    LineData *ld;
4579d522f475Smrg    XPoint spot;
4580d522f475Smrg    XVaNestedList list;
4581d522f475Smrg
45820bd37d32Smrg    if (input && input->xic
4583956cc18dSsnj	&& (ld = getLineData(screen, screen->cur_row)) != 0) {
4584956cc18dSsnj	spot.x = (short) LineCursorX(screen, ld, screen->cur_col);
45850bd37d32Smrg	spot.y = (short) (CursorY(screen, screen->cur_row) + xw->misc.xim_fs_ascent);
4586956cc18dSsnj	list = XVaCreateNestedList(0,
4587956cc18dSsnj				   XNSpotLocation, &spot,
4588956cc18dSsnj				   XNForeground, T_COLOR(screen, TEXT_FG),
4589956cc18dSsnj				   XNBackground, T_COLOR(screen, TEXT_BG),
45900bd37d32Smrg				   (void *) 0);
45910bd37d32Smrg	XSetICValues(input->xic, XNPreeditAttributes, list, (void *) 0);
4592956cc18dSsnj	XFree(list);
4593956cc18dSsnj    }
4594d522f475Smrg}
4595d522f475Smrg#endif
4596d522f475Smrg
4597d522f475Smrgstatic void
4598d522f475SmrgWrapLine(XtermWidget xw)
4599d522f475Smrg{
460020d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4601956cc18dSsnj    LineData *ld = getLineData(screen, screen->cur_row);
4602d522f475Smrg
4603956cc18dSsnj    if (ld != 0) {
4604956cc18dSsnj	/* mark that we had to wrap this line */
4605956cc18dSsnj	LineSetFlag(ld, LINEWRAPPED);
4606492d43a5Smrg	if (screen->show_wrap_marks) {
4607492d43a5Smrg	    ShowWrapMarks(xw, screen->cur_row, ld);
4608492d43a5Smrg	}
4609956cc18dSsnj	xtermAutoPrint(xw, '\n');
4610956cc18dSsnj	xtermIndex(xw, 1);
46110bd37d32Smrg	set_cur_col(screen, ScrnLeftMargin(xw));
4612956cc18dSsnj    }
4613d522f475Smrg}
4614d522f475Smrg
4615d522f475Smrg/*
4616d522f475Smrg * process a string of characters according to the character set indicated
4617d522f475Smrg * by charset.  worry about end of line conditions (wraparound if selected).
4618d522f475Smrg */
4619d522f475Smrgvoid
4620d522f475Smrgdotext(XtermWidget xw,
4621d522f475Smrg       int charset,
4622e0a2b6dfSmrg       IChar *buf,		/* start of characters to process */
4623d522f475Smrg       Cardinal len)		/* end */
4624d522f475Smrg{
462520d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4626d522f475Smrg#if OPT_WIDE_CHARS
4627d522f475Smrg    Cardinal chars_chomped = 1;
4628d522f475Smrg    int next_col = screen->cur_col;
4629d522f475Smrg#else
4630d522f475Smrg    int next_col, last_col, this_col;	/* must be signed */
4631d522f475Smrg#endif
4632d522f475Smrg    Cardinal offset;
46330bd37d32Smrg    int right = ScrnRightMargin(xw);
4634d522f475Smrg
46350bd37d32Smrg    /*
46360bd37d32Smrg     * It is possible to use CUP, etc., to move outside margins.  In that
46370bd37d32Smrg     * case, the right-margin is ineffective.
46380bd37d32Smrg     */
46390bd37d32Smrg    if (screen->cur_col > right) {
46400bd37d32Smrg	right = screen->max_col;
46410bd37d32Smrg    }
4642d522f475Smrg#if OPT_WIDE_CHARS
4643e0a2b6dfSmrg    if (screen->vt100_graphics)
4644d522f475Smrg#endif
46452eaa94a1Schristos	if (!xtermCharSetOut(xw, buf, buf + len, charset))
4646d522f475Smrg	    return;
4647d522f475Smrg
4648d522f475Smrg    if_OPT_XMC_GLITCH(screen, {
4649d522f475Smrg	Cardinal n;
4650d522f475Smrg	if (charset != '?') {
4651d522f475Smrg	    for (n = 0; n < len; n++) {
4652d522f475Smrg		if (buf[n] == XMC_GLITCH)
4653d522f475Smrg		    buf[n] = XMC_GLITCH + 1;
4654d522f475Smrg	    }
4655d522f475Smrg	}
4656d522f475Smrg    });
4657d522f475Smrg
4658d522f475Smrg#if OPT_WIDE_CHARS
4659d522f475Smrg    for (offset = 0;
4660d522f475Smrg	 offset < len && (chars_chomped > 0 || screen->do_wrap);
4661d522f475Smrg	 offset += chars_chomped) {
46620bd37d32Smrg	int width_available = right + 1 - screen->cur_col;
4663d522f475Smrg	int width_here = 0;
46640bd37d32Smrg	Boolean force_wrap;
46650bd37d32Smrg	Boolean need_wrap;
46660bd37d32Smrg	Boolean did_wrap;
4667d522f475Smrg	int last_chomp = 0;
4668d522f475Smrg	chars_chomped = 0;
4669d522f475Smrg
46700bd37d32Smrg	do {
46710bd37d32Smrg	    force_wrap = False;
46720bd37d32Smrg	    need_wrap = False;
46730bd37d32Smrg	    did_wrap = False;
46740bd37d32Smrg
46750bd37d32Smrg	    if (screen->do_wrap) {
46760bd37d32Smrg		screen->do_wrap = False;
46770bd37d32Smrg		if ((xw->flags & WRAPAROUND)) {
46780bd37d32Smrg		    WrapLine(xw);
46790bd37d32Smrg		    width_available = right + 1 - screen->cur_col;
46800bd37d32Smrg		    next_col = screen->cur_col;
46810bd37d32Smrg		    did_wrap = True;
46820bd37d32Smrg		}
4683d522f475Smrg	    }
4684d522f475Smrg
46850bd37d32Smrg	    /*
46860bd37d32Smrg	     * This can happen with left/right margins...
46870bd37d32Smrg	     */
46880bd37d32Smrg	    if (width_available <= 0) {
46890bd37d32Smrg		break;
46900bd37d32Smrg	    }
4691d522f475Smrg
46920bd37d32Smrg	    while (width_here <= width_available
46930bd37d32Smrg		   && chars_chomped < (len - offset)) {
46940bd37d32Smrg		if (!screen->utf8_mode
46950bd37d32Smrg		    || (screen->vt100_graphics && charset == '0')) {
46960bd37d32Smrg		    last_chomp = 1;
46970bd37d32Smrg		} else {
46980bd37d32Smrg		    last_chomp = my_wcwidth((wchar_t) buf[chars_chomped + offset]);
46990bd37d32Smrg		}
47000bd37d32Smrg		width_here += last_chomp;
47010bd37d32Smrg		chars_chomped++;
47020bd37d32Smrg	    }
47030bd37d32Smrg
47040bd37d32Smrg	    if (width_here > width_available) {
47050bd37d32Smrg		if (last_chomp > right + 1) {
47060bd37d32Smrg		    break;	/* give up - it is too big */
47070bd37d32Smrg		} else if (chars_chomped-- == 0) {
47080bd37d32Smrg		    /* This can happen with left/right margins... */
47090bd37d32Smrg		    break;
47100bd37d32Smrg		}
47110bd37d32Smrg		width_here -= last_chomp;
47120bd37d32Smrg		if (chars_chomped > 0) {
47130bd37d32Smrg		    need_wrap = True;
47140bd37d32Smrg		}
47150bd37d32Smrg	    } else if (width_here == width_available) {
47160bd37d32Smrg		need_wrap = True;
47170bd37d32Smrg	    } else if (chars_chomped != (len - offset)) {
47182eaa94a1Schristos		need_wrap = True;
4719d522f475Smrg	    }
4720d522f475Smrg
47210bd37d32Smrg	    if (chars_chomped != 0 && next_col <= screen->max_col) {
47220bd37d32Smrg		WriteText(xw, buf + offset, chars_chomped);
47230bd37d32Smrg	    } else if (!did_wrap
47240bd37d32Smrg		       && (xw->flags & WRAPAROUND)
47250bd37d32Smrg		       && screen->cur_col > ScrnLeftMargin(xw)) {
47260bd37d32Smrg		force_wrap = True;
47270bd37d32Smrg		need_wrap = True;
47280bd37d32Smrg	    }
47290bd37d32Smrg	    next_col += width_here;
47300bd37d32Smrg	    screen->do_wrap = need_wrap;
47310bd37d32Smrg	} while (force_wrap);
4732d522f475Smrg    }
47330bd37d32Smrg
47340bd37d32Smrg    /*
47350bd37d32Smrg     * Remember that we wrote something to the screen, for use as a base of
47360bd37d32Smrg     * combining characters.  The logic above may have called cursor-forward
47370bd37d32Smrg     * or carriage-return operations which resets this flag, so we set it at
47380bd37d32Smrg     * the very end.
47390bd37d32Smrg     */
47400bd37d32Smrg    screen->char_was_written = True;
4741d522f475Smrg#else /* ! OPT_WIDE_CHARS */
4742d522f475Smrg
4743a1f3da82Smrg    for (offset = 0; offset < len; offset += (Cardinal) this_col) {
4744956cc18dSsnj#if OPT_DEC_CHRSET
4745956cc18dSsnj	LineData *ld = getLineData(screen, screen->cur_row);
4746956cc18dSsnj#endif
4747956cc18dSsnj
4748956cc18dSsnj	last_col = LineMaxCol(screen, ld);
47490bd37d32Smrg	if (last_col > (right + 1))
47500bd37d32Smrg	    last_col = right + 1;
4751d522f475Smrg	this_col = last_col - screen->cur_col + 1;
4752d522f475Smrg	if (this_col <= 1) {
4753d522f475Smrg	    if (screen->do_wrap) {
47542eaa94a1Schristos		screen->do_wrap = False;
4755d522f475Smrg		if ((xw->flags & WRAPAROUND)) {
4756d522f475Smrg		    WrapLine(xw);
4757d522f475Smrg		}
4758d522f475Smrg	    }
4759d522f475Smrg	    this_col = 1;
4760d522f475Smrg	}
4761a1f3da82Smrg	if (offset + (Cardinal) this_col > len) {
4762a1f3da82Smrg	    this_col = (int) (len - offset);
4763d522f475Smrg	}
4764d522f475Smrg	next_col = screen->cur_col + this_col;
4765d522f475Smrg
4766956cc18dSsnj	WriteText(xw, buf + offset, (unsigned) this_col);
4767d522f475Smrg
4768d522f475Smrg	/*
4769d522f475Smrg	 * The call to WriteText updates screen->cur_col.
4770d522f475Smrg	 * If screen->cur_col is less than next_col, we must have
4771d522f475Smrg	 * hit the right margin - so set the do_wrap flag.
4772d522f475Smrg	 */
4773a1f3da82Smrg	screen->do_wrap = (Boolean) (screen->cur_col < next_col);
4774d522f475Smrg    }
4775d522f475Smrg
4776d522f475Smrg#endif /* OPT_WIDE_CHARS */
4777d522f475Smrg}
4778d522f475Smrg
4779d522f475Smrg#if OPT_WIDE_CHARS
4780d522f475Smrgunsigned
4781e0a2b6dfSmrgvisual_width(IChar *str, Cardinal len)
4782d522f475Smrg{
4783d522f475Smrg    /* returns the visual width of a string (doublewide characters count
4784d522f475Smrg       as 2, normalwide characters count as 1) */
47852eaa94a1Schristos    unsigned my_len = 0;
4786d522f475Smrg    while (len) {
4787956cc18dSsnj	int ch = (int) *str++;
4788956cc18dSsnj	if (isWide(ch))
4789d522f475Smrg	    my_len += 2;
4790d522f475Smrg	else
4791d522f475Smrg	    my_len++;
4792d522f475Smrg	len--;
4793d522f475Smrg    }
4794d522f475Smrg    return my_len;
4795d522f475Smrg}
4796d522f475Smrg#endif
4797d522f475Smrg
4798d522f475Smrg#if HANDLE_STRUCT_NOTIFY
479920d2c4d2Smrg/* Flag icon name with "***" on window output when iconified.
4800d522f475Smrg */
4801d522f475Smrgstatic void
4802d522f475SmrgHandleStructNotify(Widget w GCC_UNUSED,
4803d522f475Smrg		   XtPointer closure GCC_UNUSED,
4804d522f475Smrg		   XEvent * event,
4805e0a2b6dfSmrg		   Boolean *cont GCC_UNUSED)
4806d522f475Smrg{
48072eaa94a1Schristos    XtermWidget xw = term;
4808d522f475Smrg
4809d522f475Smrg    switch (event->type) {
4810d522f475Smrg    case MapNotify:
4811d522f475Smrg	TRACE(("HandleStructNotify(MapNotify)\n"));
48120bd37d32Smrg	resetZIconBeep(xw);
4813d522f475Smrg	mapstate = !IsUnmapped;
4814d522f475Smrg	break;
4815d522f475Smrg    case UnmapNotify:
4816d522f475Smrg	TRACE(("HandleStructNotify(UnmapNotify)\n"));
4817d522f475Smrg	mapstate = IsUnmapped;
4818d522f475Smrg	break;
4819d522f475Smrg    case ConfigureNotify:
4820d522f475Smrg	if (event->xconfigure.window == XtWindow(toplevel)) {
482120d2c4d2Smrg#if !OPT_TOOLBAR
48222eaa94a1Schristos	    int height, width;
48232eaa94a1Schristos
48242eaa94a1Schristos	    height = event->xconfigure.height;
48252eaa94a1Schristos	    width = event->xconfigure.width;
482620d2c4d2Smrg#endif
48272eaa94a1Schristos	    TRACE(("HandleStructNotify(ConfigureNotify) %d,%d %dx%d\n",
48282eaa94a1Schristos		   event->xconfigure.y, event->xconfigure.x,
48292eaa94a1Schristos		   event->xconfigure.height, event->xconfigure.width));
48302eaa94a1Schristos
4831d522f475Smrg#if OPT_TOOLBAR
4832d522f475Smrg	    /*
4833d522f475Smrg	     * The notification is for the top-level widget, but we care about
4834d522f475Smrg	     * vt100 (ignore the tek4014 window).
4835d522f475Smrg	     */
483620d2c4d2Smrg	    if (TScreenOf(xw)->Vshow) {
483720d2c4d2Smrg		VTwin *Vwin = WhichVWin(TScreenOf(xw));
4838d522f475Smrg		TbInfo *info = &(Vwin->tb_info);
4839d522f475Smrg		TbInfo save = *info;
4840d522f475Smrg
4841d522f475Smrg		if (info->menu_bar) {
4842d522f475Smrg		    XtVaGetValues(info->menu_bar,
4843d522f475Smrg				  XtNheight, &info->menu_height,
4844d522f475Smrg				  XtNborderWidth, &info->menu_border,
4845d522f475Smrg				  (XtPointer) 0);
4846d522f475Smrg
4847d522f475Smrg		    if (save.menu_height != info->menu_height
4848d522f475Smrg			|| save.menu_border != info->menu_border) {
4849d522f475Smrg
4850d522f475Smrg			TRACE(("...menu_height %d\n", info->menu_height));
4851d522f475Smrg			TRACE(("...menu_border %d\n", info->menu_border));
4852d522f475Smrg			TRACE(("...had height  %d, border %d\n",
4853d522f475Smrg			       save.menu_height,
4854d522f475Smrg			       save.menu_border));
4855d522f475Smrg
4856d522f475Smrg			/*
48570bd37d32Smrg			 * Window manager still may be using the old values.
48580bd37d32Smrg			 * Try to fool it.
4859d522f475Smrg			 */
48602eaa94a1Schristos			REQ_RESIZE((Widget) xw,
48610bd37d32Smrg				   TScreenOf(xw)->fullVwin.fullwidth,
48622eaa94a1Schristos				   (Dimension) (info->menu_height
48632eaa94a1Schristos						- save.menu_height
48640bd37d32Smrg						+ TScreenOf(xw)->fullVwin.fullheight),
48652eaa94a1Schristos				   NULL, NULL);
4866d522f475Smrg			repairSizeHints();
4867d522f475Smrg		    }
4868d522f475Smrg		}
4869d522f475Smrg	    }
4870d522f475Smrg#else
48712eaa94a1Schristos	    if (height != xw->hints.height || width != xw->hints.width)
48722eaa94a1Schristos		RequestResize(xw, height, width, False);
4873d522f475Smrg#endif /* OPT_TOOLBAR */
4874d522f475Smrg	}
4875d522f475Smrg	break;
4876d522f475Smrg    case ReparentNotify:
4877d522f475Smrg	TRACE(("HandleStructNotify(ReparentNotify)\n"));
4878d522f475Smrg	break;
4879d522f475Smrg    default:
4880d522f475Smrg	TRACE(("HandleStructNotify(event %s)\n",
4881d522f475Smrg	       visibleEventType(event->type)));
4882d522f475Smrg	break;
4883d522f475Smrg    }
4884d522f475Smrg}
4885d522f475Smrg#endif /* HANDLE_STRUCT_NOTIFY */
4886d522f475Smrg
4887d522f475Smrg#if OPT_BLINK_CURS
4888d522f475Smrgstatic void
4889e0a2b6dfSmrgSetCursorBlink(TScreen *screen, Bool enable)
4890d522f475Smrg{
4891956cc18dSsnj    screen->cursor_blink = (Boolean) enable;
4892d522f475Smrg    if (DoStartBlinking(screen)) {
4893d522f475Smrg	StartBlinking(screen);
4894d522f475Smrg    } else {
4895a1f3da82Smrg	/* EMPTY */
4896e39b573cSmrg#if OPT_BLINK_TEXT
4897e39b573cSmrg	reallyStopBlinking(screen);
4898e39b573cSmrg#else
4899d522f475Smrg	StopBlinking(screen);
4900d522f475Smrg#endif
4901d522f475Smrg    }
4902d522f475Smrg    update_cursorblink();
4903d522f475Smrg}
4904d522f475Smrg
4905d522f475Smrgvoid
4906e0a2b6dfSmrgToggleCursorBlink(TScreen *screen)
4907d522f475Smrg{
4908956cc18dSsnj    SetCursorBlink(screen, (Bool) (!(screen->cursor_blink)));
4909d522f475Smrg}
4910d522f475Smrg#endif
4911d522f475Smrg
4912d522f475Smrg/*
4913d522f475Smrg * process ANSI modes set, reset
4914d522f475Smrg */
4915d522f475Smrgstatic void
491620d2c4d2Smrgansi_modes(XtermWidget xw, BitFunc func)
4917d522f475Smrg{
4918d522f475Smrg    int i;
4919d522f475Smrg
4920d522f475Smrg    for (i = 0; i < nparam; ++i) {
49210bd37d32Smrg	switch (GetParam(i)) {
4922d522f475Smrg	case 2:		/* KAM (if set, keyboard locked */
4923d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_KAM);
4924d522f475Smrg	    break;
4925d522f475Smrg
4926d522f475Smrg	case 4:		/* IRM                          */
4927d522f475Smrg	    (*func) (&xw->flags, INSERT);
4928d522f475Smrg	    break;
4929d522f475Smrg
4930d522f475Smrg	case 12:		/* SRM (if set, local echo      */
4931d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_SRM);
4932d522f475Smrg	    break;
4933d522f475Smrg
4934d522f475Smrg	case 20:		/* LNM                          */
4935d522f475Smrg	    (*func) (&xw->flags, LINEFEED);
4936d522f475Smrg	    update_autolinefeed();
4937d522f475Smrg	    break;
4938d522f475Smrg	}
4939d522f475Smrg    }
4940d522f475Smrg}
4941d522f475Smrg
4942d522f475Smrg#define IsSM() (func == bitset)
4943d522f475Smrg
4944d522f475Smrg#define set_bool_mode(flag) \
49452eaa94a1Schristos	flag = (Boolean) IsSM()
4946d522f475Smrg
4947d522f475Smrgstatic void
4948d522f475Smrgreally_set_mousemode(XtermWidget xw,
4949d522f475Smrg		     Bool enabled,
49502eaa94a1Schristos		     XtermMouseModes mode)
4951d522f475Smrg{
495220d2c4d2Smrg    TScreenOf(xw)->send_mouse_pos = enabled ? mode : MOUSE_OFF;
495320d2c4d2Smrg    if (TScreenOf(xw)->send_mouse_pos != MOUSE_OFF)
4954d522f475Smrg	xtermShowPointer(xw, True);
4955d522f475Smrg}
4956d522f475Smrg
4957d522f475Smrg#define set_mousemode(mode) really_set_mousemode(xw, IsSM(), mode)
4958d522f475Smrg
4959d522f475Smrg#if OPT_READLINE
4960d522f475Smrg#define set_mouseflag(f)		\
4961d522f475Smrg	(IsSM()				\
4962d522f475Smrg	 ? SCREEN_FLAG_set(screen, f)	\
4963d522f475Smrg	 : SCREEN_FLAG_unset(screen, f))
4964d522f475Smrg#endif
4965d522f475Smrg
4966d522f475Smrg/*
4967d522f475Smrg * process DEC private modes set, reset
4968d522f475Smrg */
4969d522f475Smrgstatic void
497020d2c4d2Smrgdpmodes(XtermWidget xw, BitFunc func)
4971d522f475Smrg{
497220d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4973d522f475Smrg    int i, j;
49742eaa94a1Schristos    unsigned myflags;
4975d522f475Smrg
4976e0a2b6dfSmrg    TRACE(("changing %d DEC private modes\n", nparam));
4977d522f475Smrg    for (i = 0; i < nparam; ++i) {
49780bd37d32Smrg	int code = GetParam(i);
49790bd37d32Smrg
49800bd37d32Smrg	TRACE(("%s %d\n", IsSM()? "DECSET" : "DECRST", code));
49810bd37d32Smrg	switch ((DECSET_codes) code) {
49820bd37d32Smrg	case srm_DECCKM:
4983d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_DECCKM);
4984d522f475Smrg	    update_appcursor();
4985d522f475Smrg	    break;
49860bd37d32Smrg	case srm_DECANM:	/* ANSI/VT52 mode      */
4987d522f475Smrg	    if (IsSM()) {	/* ANSI (VT100) */
4988d522f475Smrg		/*
4989d522f475Smrg		 * Setting DECANM should have no effect, since this function
4990d522f475Smrg		 * cannot be reached from vt52 mode.
4991d522f475Smrg		 */
4992a1f3da82Smrg		/* EMPTY */ ;
4993d522f475Smrg	    }
4994d522f475Smrg#if OPT_VT52_MODE
4995d522f475Smrg	    else if (screen->terminal_id >= 100) {	/* VT52 */
4996d522f475Smrg		TRACE(("DECANM terminal_id %d, vtXX_level %d\n",
4997d522f475Smrg		       screen->terminal_id,
4998d522f475Smrg		       screen->vtXX_level));
4999d522f475Smrg		screen->vtXX_level = 0;
5000d522f475Smrg		screen->vt52_save_curgl = screen->curgl;
5001d522f475Smrg		screen->vt52_save_curgr = screen->curgr;
5002d522f475Smrg		screen->vt52_save_curss = screen->curss;
5003d522f475Smrg		memmove(screen->vt52_save_gsets, screen->gsets, sizeof(screen->gsets));
5004d522f475Smrg		resetCharsets(screen);
50050bd37d32Smrg		InitParams();	/* ignore the remaining params, if any */
5006d522f475Smrg	    }
5007d522f475Smrg#endif
5008d522f475Smrg	    break;
50090bd37d32Smrg	case srm_DECCOLM:
5010d522f475Smrg	    if (screen->c132) {
50110bd37d32Smrg		if (!(xw->flags & NOCLEAR_COLM))
50120bd37d32Smrg		    ClearScreen(xw);
5013d522f475Smrg		CursorSet(screen, 0, 0, xw->flags);
5014d522f475Smrg		if ((j = IsSM()? 132 : 80) !=
5015d522f475Smrg		    ((xw->flags & IN132COLUMNS) ? 132 : 80) ||
5016d522f475Smrg		    j != MaxCols(screen))
5017d522f475Smrg		    RequestResize(xw, -1, j, True);
5018d522f475Smrg		(*func) (&xw->flags, IN132COLUMNS);
50190bd37d32Smrg		if (xw->flags & IN132COLUMNS) {
50200bd37d32Smrg		    UIntClr(xw->flags, LEFT_RIGHT);
50210bd37d32Smrg		    reset_lr_margins(screen);
50220bd37d32Smrg		}
5023d522f475Smrg	    }
5024d522f475Smrg	    break;
50250bd37d32Smrg	case srm_DECSCLM:	/* (slow scroll)        */
5026d522f475Smrg	    if (IsSM()) {
5027d522f475Smrg		screen->jumpscroll = 0;
5028d522f475Smrg		if (screen->scroll_amt)
5029d522f475Smrg		    FlushScroll(xw);
5030d522f475Smrg	    } else
5031d522f475Smrg		screen->jumpscroll = 1;
5032d522f475Smrg	    (*func) (&xw->flags, SMOOTHSCROLL);
5033d522f475Smrg	    update_jumpscroll();
5034d522f475Smrg	    break;
50350bd37d32Smrg	case srm_DECSCNM:
50362eaa94a1Schristos	    myflags = xw->flags;
5037d522f475Smrg	    (*func) (&xw->flags, REVERSE_VIDEO);
50382eaa94a1Schristos	    if ((xw->flags ^ myflags) & REVERSE_VIDEO)
5039d522f475Smrg		ReverseVideo(xw);
5040d522f475Smrg	    /* update_reversevideo done in RevVid */
5041d522f475Smrg	    break;
5042d522f475Smrg
50430bd37d32Smrg	case srm_DECOM:
5044d522f475Smrg	    (*func) (&xw->flags, ORIGIN);
5045d522f475Smrg	    CursorSet(screen, 0, 0, xw->flags);
5046d522f475Smrg	    break;
5047d522f475Smrg
50480bd37d32Smrg	case srm_DECAWM:
5049d522f475Smrg	    (*func) (&xw->flags, WRAPAROUND);
5050d522f475Smrg	    update_autowrap();
5051d522f475Smrg	    break;
50520bd37d32Smrg	case srm_DECARM:
5053d522f475Smrg	    /* ignore autorepeat
5054d522f475Smrg	     * XAutoRepeatOn() and XAutoRepeatOff() can do this, but only
5055d522f475Smrg	     * for the whole display - not limited to a given window.
5056d522f475Smrg	     */
5057d522f475Smrg	    break;
50580bd37d32Smrg	case srm_X10_MOUSE:	/* MIT bogus sequence           */
5059d522f475Smrg	    MotionOff(screen, xw);
5060d522f475Smrg	    set_mousemode(X10_MOUSE);
5061d522f475Smrg	    break;
5062d522f475Smrg#if OPT_TOOLBAR
50630bd37d32Smrg	case srm_RXVT_TOOLBAR:
5064d522f475Smrg	    ShowToolbar(IsSM());
5065d522f475Smrg	    break;
5066d522f475Smrg#endif
5067d522f475Smrg#if OPT_BLINK_CURS
50680bd37d32Smrg	case srm_ATT610_BLINK:	/* att610: Start/stop blinking cursor */
5069d522f475Smrg	    if (screen->cursor_blink_res) {
5070d522f475Smrg		set_bool_mode(screen->cursor_blink_esc);
50710bd37d32Smrg		UpdateCursorBlink(screen);
5072d522f475Smrg	    }
5073d522f475Smrg	    break;
5074d522f475Smrg#endif
50750bd37d32Smrg	case srm_DECPFF:	/* print form feed */
5076e39b573cSmrg	    set_bool_mode(PrinterOf(screen).printer_formfeed);
5077d522f475Smrg	    break;
50780bd37d32Smrg	case srm_DECPEX:	/* print extent */
5079e39b573cSmrg	    set_bool_mode(PrinterOf(screen).printer_extent);
5080d522f475Smrg	    break;
50810bd37d32Smrg	case srm_DECTCEM:	/* Show/hide cursor (VT200) */
5082d522f475Smrg	    set_bool_mode(screen->cursor_set);
5083d522f475Smrg	    break;
50840bd37d32Smrg	case srm_RXVT_SCROLLBAR:
5085d522f475Smrg	    if (screen->fullVwin.sb_info.width != (IsSM()? ON : OFF))
5086d522f475Smrg		ToggleScrollBar(xw);
5087d522f475Smrg	    break;
5088d522f475Smrg#if OPT_SHIFT_FONTS
50890bd37d32Smrg	case srm_RXVT_FONTSIZE:
5090d522f475Smrg	    set_bool_mode(xw->misc.shift_fonts);
5091d522f475Smrg	    break;
5092d522f475Smrg#endif
5093d522f475Smrg#if OPT_TEK4014
50940bd37d32Smrg	case srm_DECTEK:
5095d522f475Smrg	    if (IsSM() && !(screen->inhibit & I_TEK)) {
509620d2c4d2Smrg		FlushLog(xw);
5097d522f475Smrg		TEK4014_ACTIVE(xw) = True;
50980bd37d32Smrg		update_vttekmode();
5099d522f475Smrg	    }
5100d522f475Smrg	    break;
51010bd37d32Smrg#endif
51020bd37d32Smrg	case srm_132COLS:	/* 132 column mode              */
5103d522f475Smrg	    set_bool_mode(screen->c132);
5104d522f475Smrg	    update_allow132();
5105d522f475Smrg	    break;
51060bd37d32Smrg	case srm_CURSES_HACK:
5107d522f475Smrg	    set_bool_mode(screen->curses);
5108d522f475Smrg	    update_cursesemul();
5109d522f475Smrg	    break;
51100bd37d32Smrg	case srm_DECNRCM:	/* national charset (VT220) */
5111e0a2b6dfSmrg	    if (screen->vtXX_level >= 2) {
5112e0a2b6dfSmrg		if ((*func) (&xw->flags, NATIONAL)) {
5113e0a2b6dfSmrg		    modified_DECNRCM(xw);
5114e0a2b6dfSmrg		}
5115e0a2b6dfSmrg	    }
5116d522f475Smrg	    break;
51170bd37d32Smrg	case srm_MARGIN_BELL:	/* margin bell                  */
5118d522f475Smrg	    set_bool_mode(screen->marginbell);
5119d522f475Smrg	    if (!screen->marginbell)
512020d2c4d2Smrg		screen->bellArmed = -1;
5121d522f475Smrg	    update_marginbell();
5122d522f475Smrg	    break;
51230bd37d32Smrg	case srm_REVERSEWRAP:	/* reverse wraparound   */
5124d522f475Smrg	    (*func) (&xw->flags, REVERSEWRAP);
5125d522f475Smrg	    update_reversewrap();
5126d522f475Smrg	    break;
5127d522f475Smrg#ifdef ALLOWLOGGING
51280bd37d32Smrg	case srm_ALLOWLOGGING:	/* logging              */
5129d522f475Smrg#ifdef ALLOWLOGFILEONOFF
5130d522f475Smrg	    /*
5131d522f475Smrg	     * if this feature is enabled, logging may be
5132d522f475Smrg	     * enabled and disabled via escape sequences.
5133d522f475Smrg	     */
5134d522f475Smrg	    if (IsSM())
513520d2c4d2Smrg		StartLog(xw);
5136d522f475Smrg	    else
513720d2c4d2Smrg		CloseLog(xw);
5138d522f475Smrg#else
513920d2c4d2Smrg	    Bell(xw, XkbBI_Info, 0);
514020d2c4d2Smrg	    Bell(xw, XkbBI_Info, 0);
5141d522f475Smrg#endif /* ALLOWLOGFILEONOFF */
5142d522f475Smrg	    break;
5143d522f475Smrg#endif
51440bd37d32Smrg	case srm_OPT_ALTBUF_CURSOR:	/* alternate buffer & cursor */
5145d522f475Smrg	    if (!xw->misc.titeInhibit) {
5146d522f475Smrg		if (IsSM()) {
5147d522f475Smrg		    CursorSave(xw);
5148e0a2b6dfSmrg		    ToAlternate(xw, True);
5149d522f475Smrg		    ClearScreen(xw);
5150d522f475Smrg		} else {
5151d522f475Smrg		    FromAlternate(xw);
5152d522f475Smrg		    CursorRestore(xw);
5153d522f475Smrg		}
51540bd37d32Smrg	    } else if (IsSM()) {
51550bd37d32Smrg		do_ti_xtra_scroll(xw);
5156d522f475Smrg	    }
5157d522f475Smrg	    break;
51580bd37d32Smrg	case srm_OPT_ALTBUF:
5159d522f475Smrg	    /* FALLTHRU */
51600bd37d32Smrg	case srm_ALTBUF:	/* alternate buffer */
5161d522f475Smrg	    if (!xw->misc.titeInhibit) {
5162d522f475Smrg		if (IsSM()) {
5163e0a2b6dfSmrg		    ToAlternate(xw, False);
5164d522f475Smrg		} else {
5165956cc18dSsnj		    if (screen->whichBuf
51660bd37d32Smrg			&& (code == 1047))
5167d522f475Smrg			ClearScreen(xw);
5168d522f475Smrg		    FromAlternate(xw);
5169d522f475Smrg		}
51700bd37d32Smrg	    } else if (IsSM()) {
51710bd37d32Smrg		do_ti_xtra_scroll(xw);
5172d522f475Smrg	    }
5173d522f475Smrg	    break;
51740bd37d32Smrg	case srm_DECNKM:
5175d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_DECKPAM);
5176d522f475Smrg	    update_appkeypad();
5177d522f475Smrg	    break;
51780bd37d32Smrg	case srm_DECBKM:
5179d522f475Smrg	    /* back-arrow mapped to backspace or delete(D) */
5180d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_DECBKM);
5181d522f475Smrg	    TRACE(("DECSET DECBKM %s\n",
5182d522f475Smrg		   BtoS(xw->keyboard.flags & MODE_DECBKM)));
5183d522f475Smrg	    update_decbkm();
5184d522f475Smrg	    break;
51850bd37d32Smrg	case srm_DECLRMM:
51860bd37d32Smrg	    if (screen->vtXX_level >= 4) {	/* VT420 */
51870bd37d32Smrg		(*func) (&xw->flags, LEFT_RIGHT);
51880bd37d32Smrg		if (IsLeftRightMode(xw)) {
51890bd37d32Smrg		    xterm_ResetDouble(xw);
51900bd37d32Smrg		} else {
51910bd37d32Smrg		    reset_lr_margins(screen);
51920bd37d32Smrg		}
51930bd37d32Smrg	    }
51940bd37d32Smrg	    break;
5195e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
5196e0a2b6dfSmrg	case srm_DECSDM:	/* sixel scrolling */
5197e0a2b6dfSmrg	    if (screen->terminal_id == 240 ||
5198e0a2b6dfSmrg		screen->terminal_id == 241 ||
5199e0a2b6dfSmrg		screen->terminal_id == 330 ||
5200e0a2b6dfSmrg		screen->terminal_id == 340) {
5201e0a2b6dfSmrg		(*func) (&xw->keyboard.flags, MODE_DECSDM);
5202e0a2b6dfSmrg		TRACE(("DECSET/DECRST DECSDM %s (resource default is %d)\n",
5203e0a2b6dfSmrg		       BtoS(xw->keyboard.flags & MODE_DECSDM),
5204e0a2b6dfSmrg		       TScreenOf(xw)->sixel_scrolling));
5205e0a2b6dfSmrg		update_decsdm();
5206e0a2b6dfSmrg	    }
5207e0a2b6dfSmrg	    break;
5208e0a2b6dfSmrg#endif
52090bd37d32Smrg	case srm_DECNCSM:
52100bd37d32Smrg	    if (screen->vtXX_level >= 5) {	/* VT510 */
52110bd37d32Smrg		(*func) (&xw->flags, NOCLEAR_COLM);
52120bd37d32Smrg	    }
52130bd37d32Smrg	    break;
52140bd37d32Smrg	case srm_VT200_MOUSE:	/* xterm bogus sequence         */
5215d522f475Smrg	    MotionOff(screen, xw);
5216d522f475Smrg	    set_mousemode(VT200_MOUSE);
5217d522f475Smrg	    break;
52180bd37d32Smrg	case srm_VT200_HIGHLIGHT_MOUSE:	/* xterm sequence w/hilite tracking */
5219d522f475Smrg	    MotionOff(screen, xw);
5220d522f475Smrg	    set_mousemode(VT200_HIGHLIGHT_MOUSE);
5221d522f475Smrg	    break;
52220bd37d32Smrg	case srm_BTN_EVENT_MOUSE:
5223d522f475Smrg	    MotionOff(screen, xw);
5224d522f475Smrg	    set_mousemode(BTN_EVENT_MOUSE);
5225d522f475Smrg	    break;
52260bd37d32Smrg	case srm_ANY_EVENT_MOUSE:
5227d522f475Smrg	    set_mousemode(ANY_EVENT_MOUSE);
5228d522f475Smrg	    if (screen->send_mouse_pos == MOUSE_OFF) {
5229d522f475Smrg		MotionOff(screen, xw);
5230d522f475Smrg	    } else {
5231d522f475Smrg		MotionOn(screen, xw);
5232d522f475Smrg	    }
5233d522f475Smrg	    break;
5234d522f475Smrg#if OPT_FOCUS_EVENT
52350bd37d32Smrg	case srm_FOCUS_EVENT_MOUSE:
5236d522f475Smrg	    set_bool_mode(screen->send_focus_pos);
5237d522f475Smrg	    break;
5238d522f475Smrg#endif
52390bd37d32Smrg	case srm_EXT_MODE_MOUSE:
52400bd37d32Smrg	    /* FALLTHRU */
52410bd37d32Smrg	case srm_SGR_EXT_MODE_MOUSE:
52420bd37d32Smrg	    /* FALLTHRU */
52430bd37d32Smrg	case srm_URXVT_EXT_MODE_MOUSE:
52440bd37d32Smrg	    /*
52450bd37d32Smrg	     * Rather than choose an arbitrary precedence among the coordinate
52460bd37d32Smrg	     * modes, they are mutually exclusive.  For consistency, a reset is
52470bd37d32Smrg	     * only effective against the matching mode.
52480bd37d32Smrg	     */
52490bd37d32Smrg	    if (IsSM()) {
52500bd37d32Smrg		screen->extend_coords = code;
52510bd37d32Smrg	    } else if (screen->extend_coords == code) {
52520bd37d32Smrg		screen->extend_coords = 0;
52530bd37d32Smrg	    }
52540bd37d32Smrg	    break;
52550bd37d32Smrg	case srm_ALTERNATE_SCROLL:
52560bd37d32Smrg	    set_bool_mode(screen->alternateScroll);
5257492d43a5Smrg	    break;
52580bd37d32Smrg	case srm_RXVT_SCROLL_TTY_OUTPUT:
5259d522f475Smrg	    set_bool_mode(screen->scrollttyoutput);
5260d522f475Smrg	    update_scrollttyoutput();
5261d522f475Smrg	    break;
52620bd37d32Smrg	case srm_RXVT_SCROLL_TTY_KEYPRESS:
5263d522f475Smrg	    set_bool_mode(screen->scrollkey);
5264d522f475Smrg	    update_scrollkey();
5265d522f475Smrg	    break;
52660bd37d32Smrg	case srm_EIGHT_BIT_META:
52670bd37d32Smrg	    if (screen->eight_bit_meta != ebNever) {
52680bd37d32Smrg		set_bool_mode(screen->eight_bit_meta);
52690bd37d32Smrg	    }
5270d522f475Smrg	    break;
5271d522f475Smrg#if OPT_NUM_LOCK
52720bd37d32Smrg	case srm_REAL_NUMLOCK:
5273d522f475Smrg	    set_bool_mode(xw->misc.real_NumLock);
5274d522f475Smrg	    update_num_lock();
5275d522f475Smrg	    break;
52760bd37d32Smrg	case srm_META_SENDS_ESC:
5277d522f475Smrg	    set_bool_mode(screen->meta_sends_esc);
5278d522f475Smrg	    update_meta_esc();
5279d522f475Smrg	    break;
5280d522f475Smrg#endif
52810bd37d32Smrg	case srm_DELETE_IS_DEL:
5282d522f475Smrg	    set_bool_mode(screen->delete_is_del);
5283d522f475Smrg	    update_delete_del();
5284d522f475Smrg	    break;
5285d522f475Smrg#if OPT_NUM_LOCK
52860bd37d32Smrg	case srm_ALT_SENDS_ESC:
5287d522f475Smrg	    set_bool_mode(screen->alt_sends_esc);
5288d522f475Smrg	    update_alt_esc();
5289d522f475Smrg	    break;
5290d522f475Smrg#endif
52910bd37d32Smrg	case srm_KEEP_SELECTION:
5292d522f475Smrg	    set_bool_mode(screen->keepSelection);
5293d522f475Smrg	    update_keepSelection();
5294d522f475Smrg	    break;
52950bd37d32Smrg	case srm_SELECT_TO_CLIPBOARD:
5296d522f475Smrg	    set_bool_mode(screen->selectToClipboard);
5297d522f475Smrg	    update_selectToClipboard();
5298d522f475Smrg	    break;
52990bd37d32Smrg	case srm_BELL_IS_URGENT:
5300d522f475Smrg	    set_bool_mode(screen->bellIsUrgent);
5301d522f475Smrg	    update_bellIsUrgent();
5302d522f475Smrg	    break;
53030bd37d32Smrg	case srm_POP_ON_BELL:
5304d522f475Smrg	    set_bool_mode(screen->poponbell);
5305d522f475Smrg	    update_poponbell();
5306d522f475Smrg	    break;
53070bd37d32Smrg	case srm_TITE_INHIBIT:
5308d522f475Smrg	    if (!xw->misc.titeInhibit) {
5309d522f475Smrg		if (IsSM())
5310d522f475Smrg		    CursorSave(xw);
5311d522f475Smrg		else
5312d522f475Smrg		    CursorRestore(xw);
5313d522f475Smrg	    }
5314d522f475Smrg	    break;
5315d522f475Smrg#if OPT_TCAP_FKEYS
53160bd37d32Smrg	case srm_TCAP_FKEYS:
5317d522f475Smrg	    set_keyboard_type(xw, keyboardIsTermcap, IsSM());
5318d522f475Smrg	    break;
5319d522f475Smrg#endif
5320d522f475Smrg#if OPT_SUN_FUNC_KEYS
53210bd37d32Smrg	case srm_SUN_FKEYS:
5322d522f475Smrg	    set_keyboard_type(xw, keyboardIsSun, IsSM());
5323d522f475Smrg	    break;
5324d522f475Smrg#endif
5325d522f475Smrg#if OPT_HP_FUNC_KEYS
53260bd37d32Smrg	case srm_HP_FKEYS:
5327d522f475Smrg	    set_keyboard_type(xw, keyboardIsHP, IsSM());
5328d522f475Smrg	    break;
5329d522f475Smrg#endif
5330d522f475Smrg#if OPT_SCO_FUNC_KEYS
53310bd37d32Smrg	case srm_SCO_FKEYS:
5332d522f475Smrg	    set_keyboard_type(xw, keyboardIsSCO, IsSM());
5333d522f475Smrg	    break;
5334d522f475Smrg#endif
53350bd37d32Smrg	case srm_LEGACY_FKEYS:
5336d522f475Smrg	    set_keyboard_type(xw, keyboardIsLegacy, IsSM());
5337d522f475Smrg	    break;
5338d522f475Smrg#if OPT_SUNPC_KBD
53390bd37d32Smrg	case srm_VT220_FKEYS:
5340d522f475Smrg	    set_keyboard_type(xw, keyboardIsVT220, IsSM());
5341d522f475Smrg	    break;
5342d522f475Smrg#endif
5343d522f475Smrg#if OPT_READLINE
53440bd37d32Smrg	case srm_BUTTON1_MOVE_POINT:
5345d522f475Smrg	    set_mouseflag(click1_moves);
5346d522f475Smrg	    break;
53470bd37d32Smrg	case srm_BUTTON2_MOVE_POINT:
5348d522f475Smrg	    set_mouseflag(paste_moves);
5349d522f475Smrg	    break;
53500bd37d32Smrg	case srm_DBUTTON3_DELETE:
5351d522f475Smrg	    set_mouseflag(dclick3_deletes);
5352d522f475Smrg	    break;
53530bd37d32Smrg	case srm_PASTE_IN_BRACKET:
5354d522f475Smrg	    set_mouseflag(paste_brackets);
5355d522f475Smrg	    break;
53560bd37d32Smrg	case srm_PASTE_QUOTE:
5357d522f475Smrg	    set_mouseflag(paste_quotes);
5358d522f475Smrg	    break;
53590bd37d32Smrg	case srm_PASTE_LITERAL_NL:
5360d522f475Smrg	    set_mouseflag(paste_literal_nl);
5361d522f475Smrg	    break;
5362d522f475Smrg#endif /* OPT_READLINE */
5363e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
5364e0a2b6dfSmrg	case srm_PRIVATE_COLOR_REGISTERS:	/* private color registers for each graphic */
5365e0a2b6dfSmrg	    TRACE(("DECSET/DECRST PRIVATE_COLOR_REGISTERS %s\n",
5366e0a2b6dfSmrg		   BtoS(screen->privatecolorregisters)));
5367e0a2b6dfSmrg	    set_bool_mode(screen->privatecolorregisters);
5368e0a2b6dfSmrg	    update_privatecolorregisters();
5369e0a2b6dfSmrg	    break;
5370e0a2b6dfSmrg#endif
5371e0a2b6dfSmrg	default:
5372e0a2b6dfSmrg	    TRACE(("DATA_ERROR: unknown private code %d\n", code));
5373e0a2b6dfSmrg	    break;
5374d522f475Smrg	}
5375d522f475Smrg    }
5376d522f475Smrg}
5377d522f475Smrg
5378d522f475Smrg/*
5379d522f475Smrg * process xterm private modes save
5380d522f475Smrg */
5381d522f475Smrgstatic void
5382d522f475Smrgsavemodes(XtermWidget xw)
5383d522f475Smrg{
538420d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
5385d522f475Smrg    int i;
5386d522f475Smrg
5387d522f475Smrg    for (i = 0; i < nparam; i++) {
53880bd37d32Smrg	int code = GetParam(i);
53890bd37d32Smrg
53900bd37d32Smrg	TRACE(("savemodes %d\n", code));
53910bd37d32Smrg	switch ((DECSET_codes) code) {
53920bd37d32Smrg	case srm_DECCKM:
5393d522f475Smrg	    DoSM(DP_DECCKM, xw->keyboard.flags & MODE_DECCKM);
5394d522f475Smrg	    break;
53950bd37d32Smrg	case srm_DECANM:	/* ANSI/VT52 mode      */
53960bd37d32Smrg	    /* no effect */
53970bd37d32Smrg	    break;
53980bd37d32Smrg	case srm_DECCOLM:
5399d522f475Smrg	    if (screen->c132)
5400d522f475Smrg		DoSM(DP_DECCOLM, xw->flags & IN132COLUMNS);
5401d522f475Smrg	    break;
54020bd37d32Smrg	case srm_DECSCLM:	/* (slow scroll)        */
5403d522f475Smrg	    DoSM(DP_DECSCLM, xw->flags & SMOOTHSCROLL);
5404d522f475Smrg	    break;
54050bd37d32Smrg	case srm_DECSCNM:
5406d522f475Smrg	    DoSM(DP_DECSCNM, xw->flags & REVERSE_VIDEO);
5407d522f475Smrg	    break;
54080bd37d32Smrg	case srm_DECOM:
5409d522f475Smrg	    DoSM(DP_DECOM, xw->flags & ORIGIN);
5410d522f475Smrg	    break;
54110bd37d32Smrg	case srm_DECAWM:
5412d522f475Smrg	    DoSM(DP_DECAWM, xw->flags & WRAPAROUND);
5413d522f475Smrg	    break;
54140bd37d32Smrg	case srm_DECARM:
5415d522f475Smrg	    /* ignore autorepeat */
5416d522f475Smrg	    break;
54170bd37d32Smrg	case srm_X10_MOUSE:	/* mouse bogus sequence */
5418d522f475Smrg	    DoSM(DP_X_X10MSE, screen->send_mouse_pos);
5419d522f475Smrg	    break;
5420d522f475Smrg#if OPT_TOOLBAR
54210bd37d32Smrg	case srm_RXVT_TOOLBAR:
5422d522f475Smrg	    DoSM(DP_TOOLBAR, resource.toolBar);
5423d522f475Smrg	    break;
5424d522f475Smrg#endif
5425d522f475Smrg#if OPT_BLINK_CURS
54260bd37d32Smrg	case srm_ATT610_BLINK:	/* att610: Start/stop blinking cursor */
5427d522f475Smrg	    if (screen->cursor_blink_res) {
5428d522f475Smrg		DoSM(DP_CRS_BLINK, screen->cursor_blink_esc);
5429d522f475Smrg	    }
5430d522f475Smrg	    break;
5431d522f475Smrg#endif
54320bd37d32Smrg	case srm_DECPFF:	/* print form feed */
5433e39b573cSmrg	    DoSM(DP_PRN_FORMFEED, PrinterOf(screen).printer_formfeed);
5434d522f475Smrg	    break;
54350bd37d32Smrg	case srm_DECPEX:	/* print extent */
5436e39b573cSmrg	    DoSM(DP_PRN_EXTENT, PrinterOf(screen).printer_extent);
5437d522f475Smrg	    break;
54380bd37d32Smrg	case srm_DECTCEM:	/* Show/hide cursor (VT200) */
5439d522f475Smrg	    DoSM(DP_CRS_VISIBLE, screen->cursor_set);
5440d522f475Smrg	    break;
54410bd37d32Smrg	case srm_RXVT_SCROLLBAR:
54420bd37d32Smrg	    DoSM(DP_RXVT_SCROLLBAR, (screen->fullVwin.sb_info.width != 0));
54430bd37d32Smrg	    break;
54440bd37d32Smrg#if OPT_SHIFT_FONTS
54450bd37d32Smrg	case srm_RXVT_FONTSIZE:
54460bd37d32Smrg	    DoSM(DP_RXVT_FONTSIZE, xw->misc.shift_fonts);
54470bd37d32Smrg	    break;
54480bd37d32Smrg#endif
54490bd37d32Smrg#if OPT_TEK4014
54500bd37d32Smrg	case srm_DECTEK:
54510bd37d32Smrg	    DoSM(DP_DECTEK, TEK4014_ACTIVE(xw));
54520bd37d32Smrg	    break;
54530bd37d32Smrg#endif
54540bd37d32Smrg	case srm_132COLS:	/* 132 column mode              */
5455d522f475Smrg	    DoSM(DP_X_DECCOLM, screen->c132);
5456d522f475Smrg	    break;
54570bd37d32Smrg	case srm_CURSES_HACK:	/* curses hack                  */
5458d522f475Smrg	    DoSM(DP_X_MORE, screen->curses);
5459d522f475Smrg	    break;
54600bd37d32Smrg	case srm_DECNRCM:	/* national charset (VT220) */
5461e0a2b6dfSmrg	    if (screen->vtXX_level >= 2) {
5462e0a2b6dfSmrg		DoSM(DP_DECNRCM, xw->flags & NATIONAL);
5463e0a2b6dfSmrg	    }
5464d522f475Smrg	    break;
54650bd37d32Smrg	case srm_MARGIN_BELL:	/* margin bell                  */
5466d522f475Smrg	    DoSM(DP_X_MARGIN, screen->marginbell);
5467d522f475Smrg	    break;
54680bd37d32Smrg	case srm_REVERSEWRAP:	/* reverse wraparound   */
5469d522f475Smrg	    DoSM(DP_X_REVWRAP, xw->flags & REVERSEWRAP);
5470d522f475Smrg	    break;
5471d522f475Smrg#ifdef ALLOWLOGGING
54720bd37d32Smrg	case srm_ALLOWLOGGING:	/* logging              */
5473d522f475Smrg	    DoSM(DP_X_LOGGING, screen->logging);
5474d522f475Smrg	    break;
5475d522f475Smrg#endif
54760bd37d32Smrg	case srm_OPT_ALTBUF_CURSOR:
54770bd37d32Smrg	    /* FALLTHRU */
54780bd37d32Smrg	case srm_OPT_ALTBUF:
5479d522f475Smrg	    /* FALLTHRU */
54800bd37d32Smrg	case srm_ALTBUF:	/* alternate buffer             */
5481956cc18dSsnj	    DoSM(DP_X_ALTSCRN, screen->whichBuf);
5482d522f475Smrg	    break;
54830bd37d32Smrg	case srm_DECNKM:
54840bd37d32Smrg	    DoSM(DP_DECKPAM, xw->keyboard.flags & MODE_DECKPAM);
54850bd37d32Smrg	    break;
5486e0a2b6dfSmrg	case srm_DECBKM:	/* backarrow mapping */
54870bd37d32Smrg	    DoSM(DP_DECBKM, xw->keyboard.flags & MODE_DECBKM);
54880bd37d32Smrg	    break;
54890bd37d32Smrg	case srm_DECLRMM:	/* left-right */
54900bd37d32Smrg	    DoSM(DP_X_LRMM, LEFT_RIGHT);
54910bd37d32Smrg	    break;
5492e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
5493e0a2b6dfSmrg	case srm_DECSDM:	/* sixel scrolling */
5494e0a2b6dfSmrg	    DoSM(DP_DECSDM, xw->keyboard.flags & MODE_DECSDM);
5495e0a2b6dfSmrg	    update_decsdm();
5496e0a2b6dfSmrg	    break;
5497e0a2b6dfSmrg#endif
54980bd37d32Smrg	case srm_DECNCSM:	/* noclear */
54990bd37d32Smrg	    DoSM(DP_X_NCSM, NOCLEAR_COLM);
55000bd37d32Smrg	    break;
55010bd37d32Smrg	case srm_VT200_MOUSE:	/* mouse bogus sequence         */
55020bd37d32Smrg	case srm_VT200_HIGHLIGHT_MOUSE:
55030bd37d32Smrg	case srm_BTN_EVENT_MOUSE:
55040bd37d32Smrg	case srm_ANY_EVENT_MOUSE:
5505d522f475Smrg	    DoSM(DP_X_MOUSE, screen->send_mouse_pos);
5506d522f475Smrg	    break;
5507d522f475Smrg#if OPT_FOCUS_EVENT
55080bd37d32Smrg	case srm_FOCUS_EVENT_MOUSE:
5509d522f475Smrg	    DoSM(DP_X_FOCUS, screen->send_focus_pos);
5510d522f475Smrg	    break;
5511d522f475Smrg#endif
55120bd37d32Smrg	case srm_EXT_MODE_MOUSE:
55130bd37d32Smrg	    /* FALLTHRU */
55140bd37d32Smrg	case srm_SGR_EXT_MODE_MOUSE:
55150bd37d32Smrg	    /* FALLTHRU */
55160bd37d32Smrg	case srm_URXVT_EXT_MODE_MOUSE:
55170bd37d32Smrg	    DoSM(DP_X_EXT_MOUSE, screen->extend_coords);
55180bd37d32Smrg	    break;
55190bd37d32Smrg	case srm_ALTERNATE_SCROLL:
55200bd37d32Smrg	    DoSM(DP_ALTERNATE_SCROLL, screen->alternateScroll);
5521492d43a5Smrg	    break;
55220bd37d32Smrg	case srm_RXVT_SCROLL_TTY_OUTPUT:
55230bd37d32Smrg	    DoSM(DP_RXVT_SCROLL_TTY_OUTPUT, screen->scrollttyoutput);
55240bd37d32Smrg	    break;
55250bd37d32Smrg	case srm_RXVT_SCROLL_TTY_KEYPRESS:
55260bd37d32Smrg	    DoSM(DP_RXVT_SCROLL_TTY_KEYPRESS, screen->scrollkey);
55270bd37d32Smrg	    break;
55280bd37d32Smrg	case srm_EIGHT_BIT_META:
55290bd37d32Smrg	    DoSM(DP_EIGHT_BIT_META, screen->eight_bit_meta);
55300bd37d32Smrg	    break;
55310bd37d32Smrg#if OPT_NUM_LOCK
55320bd37d32Smrg	case srm_REAL_NUMLOCK:
55330bd37d32Smrg	    DoSM(DP_REAL_NUMLOCK, xw->misc.real_NumLock);
55340bd37d32Smrg	    break;
55350bd37d32Smrg	case srm_META_SENDS_ESC:
55360bd37d32Smrg	    DoSM(DP_META_SENDS_ESC, screen->meta_sends_esc);
55370bd37d32Smrg	    break;
55380bd37d32Smrg#endif
55390bd37d32Smrg	case srm_DELETE_IS_DEL:
55400bd37d32Smrg	    DoSM(DP_DELETE_IS_DEL, screen->delete_is_del);
55410bd37d32Smrg	    break;
55420bd37d32Smrg#if OPT_NUM_LOCK
55430bd37d32Smrg	case srm_ALT_SENDS_ESC:
55440bd37d32Smrg	    DoSM(DP_ALT_SENDS_ESC, screen->alt_sends_esc);
55450bd37d32Smrg	    break;
55460bd37d32Smrg#endif
55470bd37d32Smrg	case srm_KEEP_SELECTION:
55480bd37d32Smrg	    DoSM(DP_KEEP_SELECTION, screen->keepSelection);
55490bd37d32Smrg	    break;
55500bd37d32Smrg	case srm_SELECT_TO_CLIPBOARD:
55510bd37d32Smrg	    DoSM(DP_SELECT_TO_CLIPBOARD, screen->selectToClipboard);
55520bd37d32Smrg	    break;
55530bd37d32Smrg	case srm_BELL_IS_URGENT:
55540bd37d32Smrg	    DoSM(DP_BELL_IS_URGENT, screen->bellIsUrgent);
55550bd37d32Smrg	    break;
55560bd37d32Smrg	case srm_POP_ON_BELL:
55570bd37d32Smrg	    DoSM(DP_POP_ON_BELL, screen->poponbell);
55580bd37d32Smrg	    break;
55590bd37d32Smrg#if OPT_TCAP_FKEYS
55600bd37d32Smrg	case srm_TCAP_FKEYS:
55610bd37d32Smrg	    /* FALLTHRU */
55620bd37d32Smrg#endif
55630bd37d32Smrg#if OPT_SUN_FUNC_KEYS
55640bd37d32Smrg	case srm_SUN_FKEYS:
55650bd37d32Smrg	    /* FALLTHRU */
55660bd37d32Smrg#endif
55670bd37d32Smrg#if OPT_HP_FUNC_KEYS
55680bd37d32Smrg	case srm_HP_FKEYS:
55690bd37d32Smrg	    /* FALLTHRU */
55700bd37d32Smrg#endif
55710bd37d32Smrg#if OPT_SCO_FUNC_KEYS
55720bd37d32Smrg	case srm_SCO_FKEYS:
55730bd37d32Smrg	    /* FALLTHRU */
55740bd37d32Smrg#endif
55750bd37d32Smrg#if OPT_SUNPC_KBD
55760bd37d32Smrg	case srm_VT220_FKEYS:
55770bd37d32Smrg	    /* FALLTHRU */
55780bd37d32Smrg#endif
55790bd37d32Smrg	case srm_LEGACY_FKEYS:
55800bd37d32Smrg	    DoSM(DP_KEYBOARD_TYPE, xw->keyboard.type);
55810bd37d32Smrg	    break;
55820bd37d32Smrg	case srm_TITE_INHIBIT:
5583d522f475Smrg	    if (!xw->misc.titeInhibit) {
5584d522f475Smrg		CursorSave(xw);
5585d522f475Smrg	    }
5586d522f475Smrg	    break;
5587d522f475Smrg#if OPT_READLINE
55880bd37d32Smrg	case srm_BUTTON1_MOVE_POINT:
5589d522f475Smrg	    SCREEN_FLAG_save(screen, click1_moves);
5590d522f475Smrg	    break;
55910bd37d32Smrg	case srm_BUTTON2_MOVE_POINT:
5592d522f475Smrg	    SCREEN_FLAG_save(screen, paste_moves);
5593d522f475Smrg	    break;
55940bd37d32Smrg	case srm_DBUTTON3_DELETE:
5595d522f475Smrg	    SCREEN_FLAG_save(screen, dclick3_deletes);
5596d522f475Smrg	    break;
55970bd37d32Smrg	case srm_PASTE_IN_BRACKET:
5598d522f475Smrg	    SCREEN_FLAG_save(screen, paste_brackets);
5599d522f475Smrg	    break;
56000bd37d32Smrg	case srm_PASTE_QUOTE:
5601d522f475Smrg	    SCREEN_FLAG_save(screen, paste_quotes);
5602d522f475Smrg	    break;
56030bd37d32Smrg	case srm_PASTE_LITERAL_NL:
5604d522f475Smrg	    SCREEN_FLAG_save(screen, paste_literal_nl);
5605d522f475Smrg	    break;
5606d522f475Smrg#endif /* OPT_READLINE */
5607e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
5608e0a2b6dfSmrg	case srm_PRIVATE_COLOR_REGISTERS:	/* private color registers for each graphic */
5609e0a2b6dfSmrg	    TRACE(("save PRIVATE_COLOR_REGISTERS %s\n",
5610e0a2b6dfSmrg		   BtoS(screen->privatecolorregisters)));
5611e0a2b6dfSmrg	    DoSM(DP_X_PRIVATE_COLOR_REGISTERS, screen->privatecolorregisters);
5612e0a2b6dfSmrg	    update_privatecolorregisters();
5613e0a2b6dfSmrg	    break;
5614e0a2b6dfSmrg#endif
5615d522f475Smrg	}
5616d522f475Smrg    }
5617d522f475Smrg}
5618d522f475Smrg
5619d522f475Smrg/*
5620d522f475Smrg * process xterm private modes restore
5621d522f475Smrg */
5622d522f475Smrgstatic void
5623d522f475Smrgrestoremodes(XtermWidget xw)
5624d522f475Smrg{
562520d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
5626d522f475Smrg    int i, j;
5627d522f475Smrg
5628d522f475Smrg    for (i = 0; i < nparam; i++) {
56290bd37d32Smrg	int code = GetParam(i);
56300bd37d32Smrg
56310bd37d32Smrg	TRACE(("restoremodes %d\n", code));
56320bd37d32Smrg	switch ((DECSET_codes) code) {
56330bd37d32Smrg	case srm_DECCKM:
5634d522f475Smrg	    bitcpy(&xw->keyboard.flags,
5635d522f475Smrg		   screen->save_modes[DP_DECCKM], MODE_DECCKM);
5636d522f475Smrg	    update_appcursor();
5637d522f475Smrg	    break;
56380bd37d32Smrg	case srm_DECANM:	/* ANSI/VT52 mode      */
56390bd37d32Smrg	    /* no effect */
56400bd37d32Smrg	    break;
56410bd37d32Smrg	case srm_DECCOLM:
5642d522f475Smrg	    if (screen->c132) {
56430bd37d32Smrg		if (!(xw->flags & NOCLEAR_COLM))
56440bd37d32Smrg		    ClearScreen(xw);
5645d522f475Smrg		CursorSet(screen, 0, 0, xw->flags);
5646d522f475Smrg		if ((j = (screen->save_modes[DP_DECCOLM] & IN132COLUMNS)
5647d522f475Smrg		     ? 132 : 80) != ((xw->flags & IN132COLUMNS)
5648d522f475Smrg				     ? 132 : 80) || j != MaxCols(screen))
5649d522f475Smrg		    RequestResize(xw, -1, j, True);
5650d522f475Smrg		bitcpy(&xw->flags,
5651d522f475Smrg		       screen->save_modes[DP_DECCOLM],
5652d522f475Smrg		       IN132COLUMNS);
5653d522f475Smrg	    }
5654d522f475Smrg	    break;
56550bd37d32Smrg	case srm_DECSCLM:	/* (slow scroll)        */
5656d522f475Smrg	    if (screen->save_modes[DP_DECSCLM] & SMOOTHSCROLL) {
5657d522f475Smrg		screen->jumpscroll = 0;
5658d522f475Smrg		if (screen->scroll_amt)
5659d522f475Smrg		    FlushScroll(xw);
5660d522f475Smrg	    } else
5661d522f475Smrg		screen->jumpscroll = 1;
5662d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECSCLM], SMOOTHSCROLL);
5663d522f475Smrg	    update_jumpscroll();
5664d522f475Smrg	    break;
56650bd37d32Smrg	case srm_DECSCNM:
5666d522f475Smrg	    if ((screen->save_modes[DP_DECSCNM] ^ xw->flags) & REVERSE_VIDEO) {
5667d522f475Smrg		bitcpy(&xw->flags, screen->save_modes[DP_DECSCNM], REVERSE_VIDEO);
5668d522f475Smrg		ReverseVideo(xw);
5669d522f475Smrg		/* update_reversevideo done in RevVid */
5670d522f475Smrg	    }
5671d522f475Smrg	    break;
56720bd37d32Smrg	case srm_DECOM:
5673d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECOM], ORIGIN);
5674d522f475Smrg	    CursorSet(screen, 0, 0, xw->flags);
5675d522f475Smrg	    break;
5676d522f475Smrg
56770bd37d32Smrg	case srm_DECAWM:
5678d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECAWM], WRAPAROUND);
5679d522f475Smrg	    update_autowrap();
5680d522f475Smrg	    break;
56810bd37d32Smrg	case srm_DECARM:
5682d522f475Smrg	    /* ignore autorepeat */
5683d522f475Smrg	    break;
56840bd37d32Smrg	case srm_X10_MOUSE:	/* MIT bogus sequence           */
56852eaa94a1Schristos	    DoRM0(DP_X_X10MSE, screen->send_mouse_pos);
56860bd37d32Smrg	    really_set_mousemode(xw,
56870bd37d32Smrg				 screen->send_mouse_pos != MOUSE_OFF,
56880bd37d32Smrg				 (XtermMouseModes) screen->send_mouse_pos);
5689d522f475Smrg	    break;
5690d522f475Smrg#if OPT_TOOLBAR
56910bd37d32Smrg	case srm_RXVT_TOOLBAR:
5692d522f475Smrg	    DoRM(DP_TOOLBAR, resource.toolBar);
5693d522f475Smrg	    ShowToolbar(resource.toolBar);
5694d522f475Smrg	    break;
5695d522f475Smrg#endif
5696d522f475Smrg#if OPT_BLINK_CURS
56970bd37d32Smrg	case srm_ATT610_BLINK:	/* Start/stop blinking cursor */
5698d522f475Smrg	    if (screen->cursor_blink_res) {
5699d522f475Smrg		DoRM(DP_CRS_BLINK, screen->cursor_blink_esc);
57000bd37d32Smrg		UpdateCursorBlink(screen);
5701d522f475Smrg	    }
5702d522f475Smrg	    break;
5703d522f475Smrg#endif
57040bd37d32Smrg	case srm_DECPFF:	/* print form feed */
5705e39b573cSmrg	    DoRM(DP_PRN_FORMFEED, PrinterOf(screen).printer_formfeed);
5706d522f475Smrg	    break;
57070bd37d32Smrg	case srm_DECPEX:	/* print extent */
57080bd37d32Smrg	    DoRM(DP_PRN_EXTENT, PrinterOf(screen).printer_extent);
57090bd37d32Smrg	    break;
57100bd37d32Smrg	case srm_DECTCEM:	/* Show/hide cursor (VT200) */
57110bd37d32Smrg	    DoRM(DP_CRS_VISIBLE, screen->cursor_set);
57120bd37d32Smrg	    break;
57130bd37d32Smrg	case srm_RXVT_SCROLLBAR:
57140bd37d32Smrg	    if ((screen->fullVwin.sb_info.width != 0) !=
57150bd37d32Smrg		screen->save_modes[DP_RXVT_SCROLLBAR]) {
57160bd37d32Smrg		ToggleScrollBar(xw);
57170bd37d32Smrg	    }
57180bd37d32Smrg	    break;
57190bd37d32Smrg#if OPT_SHIFT_FONTS
57200bd37d32Smrg	case srm_RXVT_FONTSIZE:
57210bd37d32Smrg	    DoRM(DP_RXVT_FONTSIZE, xw->misc.shift_fonts);
5722d522f475Smrg	    break;
57230bd37d32Smrg#endif
57240bd37d32Smrg#if OPT_TEK4014
57250bd37d32Smrg	case srm_DECTEK:
57260bd37d32Smrg	    if (!(screen->inhibit & I_TEK) &&
57270bd37d32Smrg		(TEK4014_ACTIVE(xw) != (Boolean) screen->save_modes[DP_DECTEK])) {
57280bd37d32Smrg		FlushLog(xw);
57290bd37d32Smrg		TEK4014_ACTIVE(xw) = (Boolean) screen->save_modes[DP_DECTEK];
57300bd37d32Smrg		update_vttekmode();
57310bd37d32Smrg	    }
5732d522f475Smrg	    break;
57330bd37d32Smrg#endif
57340bd37d32Smrg	case srm_132COLS:	/* 132 column mode              */
5735d522f475Smrg	    DoRM(DP_X_DECCOLM, screen->c132);
5736d522f475Smrg	    update_allow132();
5737d522f475Smrg	    break;
57380bd37d32Smrg	case srm_CURSES_HACK:	/* curses hack                  */
5739d522f475Smrg	    DoRM(DP_X_MORE, screen->curses);
5740d522f475Smrg	    update_cursesemul();
5741d522f475Smrg	    break;
57420bd37d32Smrg	case srm_DECNRCM:	/* national charset (VT220) */
5743e0a2b6dfSmrg	    if (screen->vtXX_level >= 2) {
5744e0a2b6dfSmrg		if (bitcpy(&xw->flags, screen->save_modes[DP_DECNRCM], NATIONAL))
5745e0a2b6dfSmrg		    modified_DECNRCM(xw);
5746e0a2b6dfSmrg	    }
57470bd37d32Smrg	    break;
57480bd37d32Smrg	case srm_MARGIN_BELL:	/* margin bell                  */
5749d522f475Smrg	    if ((DoRM(DP_X_MARGIN, screen->marginbell)) == 0)
575020d2c4d2Smrg		screen->bellArmed = -1;
5751d522f475Smrg	    update_marginbell();
5752d522f475Smrg	    break;
57530bd37d32Smrg	case srm_REVERSEWRAP:	/* reverse wraparound   */
5754d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_X_REVWRAP], REVERSEWRAP);
5755d522f475Smrg	    update_reversewrap();
5756d522f475Smrg	    break;
5757d522f475Smrg#ifdef ALLOWLOGGING
57580bd37d32Smrg	case srm_ALLOWLOGGING:	/* logging              */
5759d522f475Smrg#ifdef ALLOWLOGFILEONOFF
5760d522f475Smrg	    if (screen->save_modes[DP_X_LOGGING])
576120d2c4d2Smrg		StartLog(xw);
5762d522f475Smrg	    else
576320d2c4d2Smrg		CloseLog(xw);
5764d522f475Smrg#endif /* ALLOWLOGFILEONOFF */
5765d522f475Smrg	    /* update_logging done by StartLog and CloseLog */
5766d522f475Smrg	    break;
5767d522f475Smrg#endif
57680bd37d32Smrg	case srm_OPT_ALTBUF_CURSOR:	/* alternate buffer & cursor */
5769d522f475Smrg	    /* FALLTHRU */
57700bd37d32Smrg	case srm_OPT_ALTBUF:
57710bd37d32Smrg	    /* FALLTHRU */
57720bd37d32Smrg	case srm_ALTBUF:	/* alternate buffer */
5773d522f475Smrg	    if (!xw->misc.titeInhibit) {
5774d522f475Smrg		if (screen->save_modes[DP_X_ALTSCRN])
5775e0a2b6dfSmrg		    ToAlternate(xw, False);
5776d522f475Smrg		else
5777d522f475Smrg		    FromAlternate(xw);
5778d522f475Smrg		/* update_altscreen done by ToAlt and FromAlt */
57790bd37d32Smrg	    } else if (screen->save_modes[DP_X_ALTSCRN]) {
57800bd37d32Smrg		do_ti_xtra_scroll(xw);
57810bd37d32Smrg	    }
57820bd37d32Smrg	    break;
57830bd37d32Smrg	case srm_DECNKM:
57840bd37d32Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECKPAM], MODE_DECKPAM);
57850bd37d32Smrg	    update_appkeypad();
57860bd37d32Smrg	    break;
5787e0a2b6dfSmrg	case srm_DECBKM:	/* backarrow mapping */
57880bd37d32Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECBKM], MODE_DECBKM);
57890bd37d32Smrg	    update_decbkm();
57900bd37d32Smrg	    break;
57910bd37d32Smrg	case srm_DECLRMM:	/* left-right */
57920bd37d32Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_X_LRMM], LEFT_RIGHT);
57930bd37d32Smrg	    if (IsLeftRightMode(xw)) {
57940bd37d32Smrg		xterm_ResetDouble(xw);
57950bd37d32Smrg	    } else {
57960bd37d32Smrg		reset_lr_margins(screen);
5797d522f475Smrg	    }
5798d522f475Smrg	    break;
5799e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
5800e0a2b6dfSmrg	case srm_DECSDM:	/* sixel scrolling */
5801e0a2b6dfSmrg	    bitcpy(&xw->keyboard.flags, screen->save_modes[DP_DECSDM], MODE_DECSDM);
5802e0a2b6dfSmrg	    update_decsdm();
5803e0a2b6dfSmrg	    break;
5804e0a2b6dfSmrg#endif
58050bd37d32Smrg	case srm_DECNCSM:	/* noclear */
58060bd37d32Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_X_NCSM], NOCLEAR_COLM);
58070bd37d32Smrg	    break;
58080bd37d32Smrg	case srm_VT200_MOUSE:	/* mouse bogus sequence         */
58090bd37d32Smrg	case srm_VT200_HIGHLIGHT_MOUSE:
58100bd37d32Smrg	case srm_BTN_EVENT_MOUSE:
58110bd37d32Smrg	case srm_ANY_EVENT_MOUSE:
58122eaa94a1Schristos	    DoRM0(DP_X_MOUSE, screen->send_mouse_pos);
58130bd37d32Smrg	    really_set_mousemode(xw,
58140bd37d32Smrg				 screen->send_mouse_pos != MOUSE_OFF,
58150bd37d32Smrg				 (XtermMouseModes) screen->send_mouse_pos);
5816d522f475Smrg	    break;
5817d522f475Smrg#if OPT_FOCUS_EVENT
58180bd37d32Smrg	case srm_FOCUS_EVENT_MOUSE:
5819d522f475Smrg	    DoRM(DP_X_FOCUS, screen->send_focus_pos);
5820d522f475Smrg	    break;
5821d522f475Smrg#endif
58220bd37d32Smrg	case srm_EXT_MODE_MOUSE:
58230bd37d32Smrg	    /* FALLTHRU */
58240bd37d32Smrg	case srm_SGR_EXT_MODE_MOUSE:
58250bd37d32Smrg	    /* FALLTHRU */
58260bd37d32Smrg	case srm_URXVT_EXT_MODE_MOUSE:
58270bd37d32Smrg	    DoRM(DP_X_EXT_MOUSE, screen->extend_coords);
5828492d43a5Smrg	    break;
58290bd37d32Smrg	case srm_TITE_INHIBIT:
5830d522f475Smrg	    if (!xw->misc.titeInhibit) {
5831d522f475Smrg		CursorRestore(xw);
5832d522f475Smrg	    }
5833d522f475Smrg	    break;
58340bd37d32Smrg	case srm_ALTERNATE_SCROLL:
58350bd37d32Smrg	    DoRM(DP_ALTERNATE_SCROLL, screen->alternateScroll);
58360bd37d32Smrg	    break;
58370bd37d32Smrg	case srm_RXVT_SCROLL_TTY_OUTPUT:
58380bd37d32Smrg	    DoRM(DP_RXVT_SCROLL_TTY_OUTPUT, screen->scrollttyoutput);
58390bd37d32Smrg	    update_scrollttyoutput();
58400bd37d32Smrg	    break;
58410bd37d32Smrg	case srm_RXVT_SCROLL_TTY_KEYPRESS:
58420bd37d32Smrg	    DoRM(DP_RXVT_SCROLL_TTY_KEYPRESS, screen->scrollkey);
58430bd37d32Smrg	    update_scrollkey();
58440bd37d32Smrg	    break;
58450bd37d32Smrg	case srm_EIGHT_BIT_META:
58460bd37d32Smrg	    DoRM(DP_EIGHT_BIT_META, screen->eight_bit_meta);
58470bd37d32Smrg	    break;
58480bd37d32Smrg#if OPT_NUM_LOCK
58490bd37d32Smrg	case srm_REAL_NUMLOCK:
58500bd37d32Smrg	    DoRM(DP_REAL_NUMLOCK, xw->misc.real_NumLock);
58510bd37d32Smrg	    update_num_lock();
58520bd37d32Smrg	    break;
58530bd37d32Smrg	case srm_META_SENDS_ESC:
58540bd37d32Smrg	    DoRM(DP_META_SENDS_ESC, screen->meta_sends_esc);
58550bd37d32Smrg	    update_meta_esc();
58560bd37d32Smrg	    break;
58570bd37d32Smrg#endif
58580bd37d32Smrg	case srm_DELETE_IS_DEL:
58590bd37d32Smrg	    DoRM(DP_DELETE_IS_DEL, screen->delete_is_del);
58600bd37d32Smrg	    update_delete_del();
58610bd37d32Smrg	    break;
58620bd37d32Smrg#if OPT_NUM_LOCK
58630bd37d32Smrg	case srm_ALT_SENDS_ESC:
58640bd37d32Smrg	    DoRM(DP_ALT_SENDS_ESC, screen->alt_sends_esc);
58650bd37d32Smrg	    update_alt_esc();
58660bd37d32Smrg	    break;
58670bd37d32Smrg#endif
58680bd37d32Smrg	case srm_KEEP_SELECTION:
58690bd37d32Smrg	    DoRM(DP_KEEP_SELECTION, screen->keepSelection);
58700bd37d32Smrg	    update_keepSelection();
58710bd37d32Smrg	    break;
58720bd37d32Smrg	case srm_SELECT_TO_CLIPBOARD:
58730bd37d32Smrg	    DoRM(DP_SELECT_TO_CLIPBOARD, screen->selectToClipboard);
58740bd37d32Smrg	    update_selectToClipboard();
58750bd37d32Smrg	    break;
58760bd37d32Smrg	case srm_BELL_IS_URGENT:
58770bd37d32Smrg	    DoRM(DP_BELL_IS_URGENT, screen->bellIsUrgent);
58780bd37d32Smrg	    update_bellIsUrgent();
58790bd37d32Smrg	    break;
58800bd37d32Smrg	case srm_POP_ON_BELL:
58810bd37d32Smrg	    DoRM(DP_POP_ON_BELL, screen->poponbell);
58820bd37d32Smrg	    update_poponbell();
58830bd37d32Smrg	    break;
58840bd37d32Smrg#if OPT_TCAP_FKEYS
58850bd37d32Smrg	case srm_TCAP_FKEYS:
58860bd37d32Smrg	    /* FALLTHRU */
58870bd37d32Smrg#endif
58880bd37d32Smrg#if OPT_SUN_FUNC_KEYS
58890bd37d32Smrg	case srm_SUN_FKEYS:
58900bd37d32Smrg	    /* FALLTHRU */
58910bd37d32Smrg#endif
58920bd37d32Smrg#if OPT_HP_FUNC_KEYS
58930bd37d32Smrg	case srm_HP_FKEYS:
58940bd37d32Smrg	    /* FALLTHRU */
58950bd37d32Smrg#endif
58960bd37d32Smrg#if OPT_SCO_FUNC_KEYS
58970bd37d32Smrg	case srm_SCO_FKEYS:
58980bd37d32Smrg	    /* FALLTHRU */
58990bd37d32Smrg#endif
59000bd37d32Smrg#if OPT_SUNPC_KBD
59010bd37d32Smrg	case srm_VT220_FKEYS:
59020bd37d32Smrg	    /* FALLTHRU */
59030bd37d32Smrg#endif
59040bd37d32Smrg	case srm_LEGACY_FKEYS:
59050bd37d32Smrg	    xw->keyboard.type = (xtermKeyboardType) screen->save_modes[DP_KEYBOARD_TYPE];
59060bd37d32Smrg	    break;
5907d522f475Smrg#if OPT_READLINE
59080bd37d32Smrg	case srm_BUTTON1_MOVE_POINT:
5909d522f475Smrg	    SCREEN_FLAG_restore(screen, click1_moves);
5910d522f475Smrg	    break;
59110bd37d32Smrg	case srm_BUTTON2_MOVE_POINT:
5912d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_moves);
5913d522f475Smrg	    break;
59140bd37d32Smrg	case srm_DBUTTON3_DELETE:
5915d522f475Smrg	    SCREEN_FLAG_restore(screen, dclick3_deletes);
5916d522f475Smrg	    break;
59170bd37d32Smrg	case srm_PASTE_IN_BRACKET:
5918d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_brackets);
5919d522f475Smrg	    break;
59200bd37d32Smrg	case srm_PASTE_QUOTE:
5921d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_quotes);
5922d522f475Smrg	    break;
59230bd37d32Smrg	case srm_PASTE_LITERAL_NL:
5924d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_literal_nl);
5925d522f475Smrg	    break;
5926d522f475Smrg#endif /* OPT_READLINE */
5927e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
5928e0a2b6dfSmrg	case srm_PRIVATE_COLOR_REGISTERS:	/* private color registers for each graphic */
5929e0a2b6dfSmrg	    TRACE(("restore PRIVATE_COLOR_REGISTERS %s\n",
5930e0a2b6dfSmrg		   BtoS(screen->privatecolorregisters)));
5931e0a2b6dfSmrg	    DoRM(DP_X_PRIVATE_COLOR_REGISTERS, screen->privatecolorregisters);
5932e0a2b6dfSmrg	    update_privatecolorregisters();
5933e0a2b6dfSmrg	    break;
5934e0a2b6dfSmrg#endif
5935d522f475Smrg	}
5936d522f475Smrg    }
5937d522f475Smrg}
5938d522f475Smrg
593920d2c4d2Smrg/*
594020d2c4d2Smrg * Convert an XTextProperty to a string.
594120d2c4d2Smrg *
594220d2c4d2Smrg * This frees the data owned by the XTextProperty, and returns in its place the
594320d2c4d2Smrg * string, which must be freed by the caller.
594420d2c4d2Smrg */
594520d2c4d2Smrgstatic char *
594620d2c4d2Smrgproperty_to_string(XtermWidget xw, XTextProperty * text)
594720d2c4d2Smrg{
594820d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
594920d2c4d2Smrg    Display *dpy = screen->display;
595020d2c4d2Smrg    char *result = 0;
595120d2c4d2Smrg    char **list;
595220d2c4d2Smrg    int length = 0;
595320d2c4d2Smrg    int rc;
595420d2c4d2Smrg
595520d2c4d2Smrg    TRACE(("property_to_string value %p, encoding %s, format %d, nitems %ld\n",
595620d2c4d2Smrg	   text->value,
595720d2c4d2Smrg	   XGetAtomName(dpy, text->encoding),
595820d2c4d2Smrg	   text->format,
595920d2c4d2Smrg	   text->nitems));
596020d2c4d2Smrg
596120d2c4d2Smrg#if OPT_WIDE_CHARS
596220d2c4d2Smrg    /*
596320d2c4d2Smrg     * We will use the XmbTextPropertyToTextList call to extract UTF-8 data.
596420d2c4d2Smrg     * The xtermUtf8ToTextList() call is used to convert UTF-8 explicitly to
596520d2c4d2Smrg     * ISO-8859-1.
596620d2c4d2Smrg     */
596720d2c4d2Smrg    if ((text->format != 8)
596820d2c4d2Smrg	|| IsTitleMode(xw, tmGetUtf8)
596920d2c4d2Smrg	|| (rc = xtermUtf8ToTextList(xw, text, &list, &length)) < 0)
597020d2c4d2Smrg#endif
597120d2c4d2Smrg	if ((rc = XmbTextPropertyToTextList(dpy, text, &list, &length)) < 0)
597220d2c4d2Smrg	    rc = XTextPropertyToStringList(text, &list, &length);
597320d2c4d2Smrg
597420d2c4d2Smrg    if (rc >= 0) {
597520d2c4d2Smrg	int n, c, pass;
597620d2c4d2Smrg	size_t need = 0;
597720d2c4d2Smrg
597820d2c4d2Smrg	for (pass = 0; pass < 2; ++pass) {
597920d2c4d2Smrg	    for (n = 0, need = 0; n < length; n++) {
598020d2c4d2Smrg		char *s = list[n];
598120d2c4d2Smrg		while ((c = *s++) != '\0') {
598220d2c4d2Smrg		    if (pass)
598320d2c4d2Smrg			result[need] = (char) c;
598420d2c4d2Smrg		    ++need;
598520d2c4d2Smrg		}
598620d2c4d2Smrg	    }
598720d2c4d2Smrg	    if (pass)
598820d2c4d2Smrg		result[need] = '\0';
598920d2c4d2Smrg	    else
599020d2c4d2Smrg		result = malloc(need + 1);
599120d2c4d2Smrg	    if (result == 0)
599220d2c4d2Smrg		break;
599320d2c4d2Smrg	}
599420d2c4d2Smrg	XFreeStringList(list);
599520d2c4d2Smrg    }
599620d2c4d2Smrg    if (text->value != 0)
599720d2c4d2Smrg	XFree(text->value);
599820d2c4d2Smrg
599920d2c4d2Smrg    return result;
600020d2c4d2Smrg}
600120d2c4d2Smrg
600220d2c4d2Smrgstatic char *
600320d2c4d2Smrgget_icon_label(XtermWidget xw)
600420d2c4d2Smrg{
600520d2c4d2Smrg    XTextProperty text;
600620d2c4d2Smrg    char *result = 0;
600720d2c4d2Smrg
6008a1f3da82Smrg    if (XGetWMIconName(TScreenOf(xw)->display, VShellWindow(xw), &text)) {
600920d2c4d2Smrg	result = property_to_string(xw, &text);
601020d2c4d2Smrg    }
601120d2c4d2Smrg    return result;
601220d2c4d2Smrg}
601320d2c4d2Smrg
601420d2c4d2Smrgstatic char *
601520d2c4d2Smrgget_window_label(XtermWidget xw)
601620d2c4d2Smrg{
601720d2c4d2Smrg    XTextProperty text;
601820d2c4d2Smrg    char *result = 0;
601920d2c4d2Smrg
6020a1f3da82Smrg    if (XGetWMName(TScreenOf(xw)->display, VShellWindow(xw), &text)) {
602120d2c4d2Smrg	result = property_to_string(xw, &text);
602220d2c4d2Smrg    }
602320d2c4d2Smrg    return result;
602420d2c4d2Smrg}
602520d2c4d2Smrg
6026d522f475Smrg/*
6027d522f475Smrg * Report window label (icon or title) in dtterm protocol
6028d522f475Smrg * ESC ] code label ESC backslash
6029d522f475Smrg */
6030d522f475Smrgstatic void
6031d522f475Smrgreport_win_label(XtermWidget xw,
6032d522f475Smrg		 int code,
603320d2c4d2Smrg		 char *text)
6034d522f475Smrg{
6035d522f475Smrg    unparseputc(xw, ANSI_ESC);
6036d522f475Smrg    unparseputc(xw, ']');
6037d522f475Smrg    unparseputc(xw, code);
6038d522f475Smrg
603920d2c4d2Smrg    if (text != 0) {
604020d2c4d2Smrg	int copy = IsTitleMode(xw, tmGetBase16);
604120d2c4d2Smrg	if (copy) {
604220d2c4d2Smrg	    TRACE(("Encoding hex:%s\n", text));
604320d2c4d2Smrg	    text = x_encode_hex(text);
6044d522f475Smrg	}
604520d2c4d2Smrg	unparseputs(xw, text);
604620d2c4d2Smrg	if (copy)
604720d2c4d2Smrg	    free(text);
6048d522f475Smrg    }
6049d522f475Smrg
6050d522f475Smrg    unparseputc(xw, ANSI_ESC);
6051d522f475Smrg    unparseputc(xw, '\\');	/* should be ST */
6052d522f475Smrg    unparse_end(xw);
6053d522f475Smrg}
6054d522f475Smrg
6055d522f475Smrg/*
6056d522f475Smrg * Window operations (from CDE dtterm description, as well as extensions).
6057d522f475Smrg * See also "allowWindowOps" resource.
6058d522f475Smrg */
6059d522f475Smrgstatic void
6060d522f475Smrgwindow_ops(XtermWidget xw)
6061d522f475Smrg{
606220d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6063d522f475Smrg    XWindowChanges values;
6064d522f475Smrg    XWindowAttributes win_attrs;
6065d522f475Smrg    unsigned value_mask;
6066d522f475Smrg#if OPT_MAXIMIZE
6067d522f475Smrg    unsigned root_width;
6068d522f475Smrg    unsigned root_height;
6069d522f475Smrg#endif
60700bd37d32Smrg    int code = zero_if_default(0);
60710bd37d32Smrg    char *label;
6072d522f475Smrg
60730bd37d32Smrg    TRACE(("window_ops %d\n", code));
60740bd37d32Smrg    switch (code) {
607520d2c4d2Smrg    case ewRestoreWin:		/* Restore (de-iconify) window */
607620d2c4d2Smrg	if (AllowWindowOps(xw, ewRestoreWin)) {
607720d2c4d2Smrg	    TRACE(("...de-iconify window\n"));
607820d2c4d2Smrg	    XMapWindow(screen->display,
6079a1f3da82Smrg		       VShellWindow(xw));
608020d2c4d2Smrg	}
6081d522f475Smrg	break;
6082d522f475Smrg
608320d2c4d2Smrg    case ewMinimizeWin:	/* Minimize (iconify) window */
608420d2c4d2Smrg	if (AllowWindowOps(xw, ewMinimizeWin)) {
608520d2c4d2Smrg	    TRACE(("...iconify window\n"));
608620d2c4d2Smrg	    XIconifyWindow(screen->display,
6087a1f3da82Smrg			   VShellWindow(xw),
608820d2c4d2Smrg			   DefaultScreen(screen->display));
608920d2c4d2Smrg	}
6090d522f475Smrg	break;
6091d522f475Smrg
609220d2c4d2Smrg    case ewSetWinPosition:	/* Move the window to the given position */
609320d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinPosition)) {
609420d2c4d2Smrg	    values.x = zero_if_default(1);
609520d2c4d2Smrg	    values.y = zero_if_default(2);
609620d2c4d2Smrg	    TRACE(("...move window to %d,%d\n", values.x, values.y));
609720d2c4d2Smrg	    value_mask = (CWX | CWY);
609820d2c4d2Smrg	    XReconfigureWMWindow(screen->display,
6099a1f3da82Smrg				 VShellWindow(xw),
610020d2c4d2Smrg				 DefaultScreen(screen->display),
610120d2c4d2Smrg				 value_mask,
610220d2c4d2Smrg				 &values);
610320d2c4d2Smrg	}
6104d522f475Smrg	break;
6105d522f475Smrg
610620d2c4d2Smrg    case ewSetWinSizePixels:	/* Resize the window to given size in pixels */
610720d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinSizePixels)) {
61080bd37d32Smrg	    RequestResize(xw, optional_param(1), optional_param(2), False);
610920d2c4d2Smrg	}
6110d522f475Smrg	break;
6111d522f475Smrg
611220d2c4d2Smrg    case ewRaiseWin:		/* Raise the window to the front of the stack */
611320d2c4d2Smrg	if (AllowWindowOps(xw, ewRaiseWin)) {
611420d2c4d2Smrg	    TRACE(("...raise window\n"));
6115a1f3da82Smrg	    XRaiseWindow(screen->display, VShellWindow(xw));
611620d2c4d2Smrg	}
6117d522f475Smrg	break;
6118d522f475Smrg
611920d2c4d2Smrg    case ewLowerWin:		/* Lower the window to the bottom of the stack */
612020d2c4d2Smrg	if (AllowWindowOps(xw, ewLowerWin)) {
612120d2c4d2Smrg	    TRACE(("...lower window\n"));
6122a1f3da82Smrg	    XLowerWindow(screen->display, VShellWindow(xw));
612320d2c4d2Smrg	}
6124d522f475Smrg	break;
6125d522f475Smrg
612620d2c4d2Smrg    case ewRefreshWin:		/* Refresh the window */
612720d2c4d2Smrg	if (AllowWindowOps(xw, ewRefreshWin)) {
612820d2c4d2Smrg	    TRACE(("...redraw window\n"));
612920d2c4d2Smrg	    Redraw();
613020d2c4d2Smrg	}
6131d522f475Smrg	break;
6132d522f475Smrg
613320d2c4d2Smrg    case ewSetWinSizeChars:	/* Resize the text-area, in characters */
613420d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinSizeChars)) {
61350bd37d32Smrg	    RequestResize(xw, optional_param(1), optional_param(2), True);
613620d2c4d2Smrg	}
6137d522f475Smrg	break;
6138d522f475Smrg
6139d522f475Smrg#if OPT_MAXIMIZE
614020d2c4d2Smrg    case ewMaximizeWin:	/* Maximize or restore */
614120d2c4d2Smrg	if (AllowWindowOps(xw, ewMaximizeWin)) {
614220d2c4d2Smrg	    RequestMaximize(xw, zero_if_default(1));
614320d2c4d2Smrg	}
6144d522f475Smrg	break;
6145a1f3da82Smrg    case ewFullscreenWin:	/* Fullscreen or restore */
6146a1f3da82Smrg	if (AllowWindowOps(xw, ewFullscreenWin)) {
6147a1f3da82Smrg	    FullScreen(xw, zero_if_default(1));
6148a1f3da82Smrg	}
6149a1f3da82Smrg	break;
6150d522f475Smrg#endif
6151d522f475Smrg
615220d2c4d2Smrg    case ewGetWinState:	/* Report the window's state */
615320d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinState)) {
615420d2c4d2Smrg	    TRACE(("...get window attributes\n"));
61550bd37d32Smrg	    xtermGetWinAttrs(screen->display,
61560bd37d32Smrg			     VWindow(screen),
61570bd37d32Smrg			     &win_attrs);
61580bd37d32Smrg	    init_reply(ANSI_CSI);
615920d2c4d2Smrg	    reply.a_pintro = 0;
616020d2c4d2Smrg	    reply.a_nparam = 1;
616120d2c4d2Smrg	    reply.a_param[0] = (ParmType) ((win_attrs.map_state == IsViewable)
616220d2c4d2Smrg					   ? 1
616320d2c4d2Smrg					   : 2);
616420d2c4d2Smrg	    reply.a_inters = 0;
616520d2c4d2Smrg	    reply.a_final = 't';
616620d2c4d2Smrg	    unparseseq(xw, &reply);
616720d2c4d2Smrg	}
6168d522f475Smrg	break;
6169d522f475Smrg
617020d2c4d2Smrg    case ewGetWinPosition:	/* Report the window's position */
617120d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinPosition)) {
617220d2c4d2Smrg	    TRACE(("...get window position\n"));
61730bd37d32Smrg	    xtermGetWinAttrs(screen->display,
61740bd37d32Smrg			     WMFrameWindow(xw),
61750bd37d32Smrg			     &win_attrs);
61760bd37d32Smrg	    init_reply(ANSI_CSI);
617720d2c4d2Smrg	    reply.a_pintro = 0;
617820d2c4d2Smrg	    reply.a_nparam = 3;
617920d2c4d2Smrg	    reply.a_param[0] = 3;
618020d2c4d2Smrg	    reply.a_param[1] = (ParmType) win_attrs.x;
618120d2c4d2Smrg	    reply.a_param[2] = (ParmType) win_attrs.y;
618220d2c4d2Smrg	    reply.a_inters = 0;
618320d2c4d2Smrg	    reply.a_final = 't';
618420d2c4d2Smrg	    unparseseq(xw, &reply);
618520d2c4d2Smrg	}
6186d522f475Smrg	break;
6187d522f475Smrg
618820d2c4d2Smrg    case ewGetWinSizePixels:	/* Report the window's size in pixels */
618920d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinSizePixels)) {
619020d2c4d2Smrg	    TRACE(("...get window size in pixels\n"));
61910bd37d32Smrg	    init_reply(ANSI_CSI);
619220d2c4d2Smrg	    reply.a_pintro = 0;
619320d2c4d2Smrg	    reply.a_nparam = 3;
619420d2c4d2Smrg	    reply.a_param[0] = 4;
619520d2c4d2Smrg	    reply.a_param[1] = (ParmType) Height(screen);
619620d2c4d2Smrg	    reply.a_param[2] = (ParmType) Width(screen);
619720d2c4d2Smrg	    reply.a_inters = 0;
619820d2c4d2Smrg	    reply.a_final = 't';
619920d2c4d2Smrg	    unparseseq(xw, &reply);
620020d2c4d2Smrg	}
6201d522f475Smrg	break;
6202d522f475Smrg
620320d2c4d2Smrg    case ewGetWinSizeChars:	/* Report the text's size in characters */
620420d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinSizeChars)) {
620520d2c4d2Smrg	    TRACE(("...get window size in characters\n"));
62060bd37d32Smrg	    init_reply(ANSI_CSI);
620720d2c4d2Smrg	    reply.a_pintro = 0;
620820d2c4d2Smrg	    reply.a_nparam = 3;
620920d2c4d2Smrg	    reply.a_param[0] = 8;
621020d2c4d2Smrg	    reply.a_param[1] = (ParmType) MaxRows(screen);
621120d2c4d2Smrg	    reply.a_param[2] = (ParmType) MaxCols(screen);
621220d2c4d2Smrg	    reply.a_inters = 0;
621320d2c4d2Smrg	    reply.a_final = 't';
621420d2c4d2Smrg	    unparseseq(xw, &reply);
621520d2c4d2Smrg	}
6216d522f475Smrg	break;
6217d522f475Smrg
6218d522f475Smrg#if OPT_MAXIMIZE
621920d2c4d2Smrg    case ewGetScreenSizeChars:	/* Report the screen's size, in characters */
622020d2c4d2Smrg	if (AllowWindowOps(xw, ewGetScreenSizeChars)) {
622120d2c4d2Smrg	    TRACE(("...get screen size in characters\n"));
62220bd37d32Smrg	    (void) QueryMaximize(xw, &root_height, &root_width);
62230bd37d32Smrg	    init_reply(ANSI_CSI);
622420d2c4d2Smrg	    reply.a_pintro = 0;
622520d2c4d2Smrg	    reply.a_nparam = 3;
622620d2c4d2Smrg	    reply.a_param[0] = 9;
622720d2c4d2Smrg	    reply.a_param[1] = (ParmType) (root_height
622820d2c4d2Smrg					   / (unsigned) FontHeight(screen));
622920d2c4d2Smrg	    reply.a_param[2] = (ParmType) (root_width
623020d2c4d2Smrg					   / (unsigned) FontWidth(screen));
623120d2c4d2Smrg	    reply.a_inters = 0;
623220d2c4d2Smrg	    reply.a_final = 't';
623320d2c4d2Smrg	    unparseseq(xw, &reply);
6234d522f475Smrg	}
6235d522f475Smrg	break;
6236d522f475Smrg#endif
6237d522f475Smrg
623820d2c4d2Smrg    case ewGetIconTitle:	/* Report the icon's label */
623920d2c4d2Smrg	if (AllowWindowOps(xw, ewGetIconTitle)) {
624020d2c4d2Smrg	    TRACE(("...get icon's label\n"));
62410bd37d32Smrg	    report_win_label(xw, 'L', label = get_icon_label(xw));
62420bd37d32Smrg	    free(label);
624320d2c4d2Smrg	}
6244d522f475Smrg	break;
6245d522f475Smrg
624620d2c4d2Smrg    case ewGetWinTitle:	/* Report the window's title */
624720d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinTitle)) {
624820d2c4d2Smrg	    TRACE(("...get window's label\n"));
62490bd37d32Smrg	    report_win_label(xw, 'l', label = get_window_label(xw));
62500bd37d32Smrg	    free(label);
625120d2c4d2Smrg	}
625220d2c4d2Smrg	break;
625320d2c4d2Smrg
625420d2c4d2Smrg    case ewPushTitle:		/* save the window's title(s) on stack */
625520d2c4d2Smrg	if (AllowWindowOps(xw, ewPushTitle)) {
625620d2c4d2Smrg	    SaveTitle *last = screen->save_title;
625720d2c4d2Smrg	    SaveTitle *item = TypeCalloc(SaveTitle);
625820d2c4d2Smrg
625920d2c4d2Smrg	    TRACE(("...push title onto stack\n"));
626020d2c4d2Smrg	    if (item != 0) {
626120d2c4d2Smrg		switch (zero_if_default(1)) {
626220d2c4d2Smrg		case 0:
626320d2c4d2Smrg		    item->iconName = get_icon_label(xw);
626420d2c4d2Smrg		    item->windowName = get_window_label(xw);
626520d2c4d2Smrg		    break;
626620d2c4d2Smrg		case 1:
626720d2c4d2Smrg		    item->iconName = get_icon_label(xw);
626820d2c4d2Smrg		    break;
626920d2c4d2Smrg		case 2:
627020d2c4d2Smrg		    item->windowName = get_window_label(xw);
627120d2c4d2Smrg		    break;
627220d2c4d2Smrg		}
627320d2c4d2Smrg		item->next = last;
627420d2c4d2Smrg		if (item->iconName == 0) {
627520d2c4d2Smrg		    item->iconName = ((last == 0)
627620d2c4d2Smrg				      ? get_icon_label(xw)
627720d2c4d2Smrg				      : x_strdup(last->iconName));
627820d2c4d2Smrg		}
627920d2c4d2Smrg		if (item->windowName == 0) {
628020d2c4d2Smrg		    item->windowName = ((last == 0)
628120d2c4d2Smrg					? get_window_label(xw)
628220d2c4d2Smrg					: x_strdup(last->windowName));
628320d2c4d2Smrg		}
628420d2c4d2Smrg		screen->save_title = item;
628520d2c4d2Smrg	    }
628620d2c4d2Smrg	}
628720d2c4d2Smrg	break;
628820d2c4d2Smrg
628920d2c4d2Smrg    case ewPopTitle:		/* restore the window's title(s) from stack */
629020d2c4d2Smrg	if (AllowWindowOps(xw, ewPopTitle)) {
629120d2c4d2Smrg	    SaveTitle *item = screen->save_title;
629220d2c4d2Smrg
629320d2c4d2Smrg	    TRACE(("...pop title off stack\n"));
629420d2c4d2Smrg	    if (item != 0) {
629520d2c4d2Smrg		switch (zero_if_default(1)) {
629620d2c4d2Smrg		case 0:
629720d2c4d2Smrg		    ChangeIconName(xw, item->iconName);
629820d2c4d2Smrg		    ChangeTitle(xw, item->windowName);
629920d2c4d2Smrg		    break;
630020d2c4d2Smrg		case 1:
630120d2c4d2Smrg		    ChangeIconName(xw, item->iconName);
630220d2c4d2Smrg		    break;
630320d2c4d2Smrg		case 2:
630420d2c4d2Smrg		    ChangeTitle(xw, item->windowName);
630520d2c4d2Smrg		    break;
630620d2c4d2Smrg		}
630720d2c4d2Smrg		screen->save_title = item->next;
630820d2c4d2Smrg		free(item->iconName);
630920d2c4d2Smrg		free(item->windowName);
631020d2c4d2Smrg		free(item);
631120d2c4d2Smrg	    }
631220d2c4d2Smrg	}
6313d522f475Smrg	break;
6314d522f475Smrg
6315d522f475Smrg    default:			/* DECSLPP (24, 25, 36, 48, 72, 144) */
631620d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinLines)) {
63170bd37d32Smrg	    if (code >= 24)
63180bd37d32Smrg		RequestResize(xw, code, -1, True);
631920d2c4d2Smrg	}
6320d522f475Smrg	break;
6321d522f475Smrg    }
6322d522f475Smrg}
6323d522f475Smrg
6324d522f475Smrg/*
6325d522f475Smrg * set a bit in a word given a pointer to the word and a mask.
6326d522f475Smrg */
6327e0a2b6dfSmrgstatic int
6328d522f475Smrgbitset(unsigned *p, unsigned mask)
6329d522f475Smrg{
6330e0a2b6dfSmrg    unsigned before = *p;
6331d522f475Smrg    *p |= mask;
6332e0a2b6dfSmrg    return (before != *p);
6333d522f475Smrg}
6334d522f475Smrg
6335d522f475Smrg/*
6336d522f475Smrg * clear a bit in a word given a pointer to the word and a mask.
6337d522f475Smrg */
6338e0a2b6dfSmrgstatic int
6339d522f475Smrgbitclr(unsigned *p, unsigned mask)
6340d522f475Smrg{
6341e0a2b6dfSmrg    unsigned before = *p;
6342d522f475Smrg    *p &= ~mask;
6343e0a2b6dfSmrg    return (before != *p);
6344d522f475Smrg}
6345d522f475Smrg
6346d522f475Smrg/*
6347d522f475Smrg * Copy bits from one word to another, given a mask
6348d522f475Smrg */
6349e0a2b6dfSmrgstatic int
6350d522f475Smrgbitcpy(unsigned *p, unsigned q, unsigned mask)
6351d522f475Smrg{
6352e0a2b6dfSmrg    unsigned before = *p;
6353d522f475Smrg    bitclr(p, mask);
6354d522f475Smrg    bitset(p, q & mask);
6355e0a2b6dfSmrg    return (before != *p);
6356d522f475Smrg}
6357d522f475Smrg
6358d522f475Smrgvoid
6359d522f475Smrgunparseputc1(XtermWidget xw, int c)
6360d522f475Smrg{
6361d522f475Smrg    if (c >= 0x80 && c <= 0x9F) {
636220d2c4d2Smrg	if (!TScreenOf(xw)->control_eight_bits) {
6363d522f475Smrg	    unparseputc(xw, A2E(ANSI_ESC));
6364d522f475Smrg	    c = A2E(c - 0x40);
6365d522f475Smrg	}
6366d522f475Smrg    }
6367d522f475Smrg    unparseputc(xw, c);
6368d522f475Smrg}
6369d522f475Smrg
6370d522f475Smrgvoid
6371e0a2b6dfSmrgunparseseq(XtermWidget xw, ANSI *ap)
6372d522f475Smrg{
6373d522f475Smrg    int c;
6374d522f475Smrg    int i;
6375d522f475Smrg    int inters;
6376d522f475Smrg
6377d522f475Smrg    unparseputc1(xw, c = ap->a_type);
6378d522f475Smrg    if (c == ANSI_ESC
6379d522f475Smrg	|| c == ANSI_DCS
6380d522f475Smrg	|| c == ANSI_CSI
6381d522f475Smrg	|| c == ANSI_OSC
6382d522f475Smrg	|| c == ANSI_PM
6383d522f475Smrg	|| c == ANSI_APC
6384d522f475Smrg	|| c == ANSI_SS3) {
6385d522f475Smrg	if (ap->a_pintro != 0)
6386d522f475Smrg	    unparseputc(xw, ap->a_pintro);
6387d522f475Smrg	for (i = 0; i < ap->a_nparam; ++i) {
63880bd37d32Smrg	    if (i != 0) {
63890bd37d32Smrg		if (ap->a_delim) {
63900bd37d32Smrg		    unparseputs(xw, ap->a_delim);
63910bd37d32Smrg		} else {
63920bd37d32Smrg		    unparseputc(xw, ';');
63930bd37d32Smrg		}
63940bd37d32Smrg	    }
63950bd37d32Smrg	    if (ap->a_radix[i]) {
63960bd37d32Smrg		char temp[8];
63970bd37d32Smrg		sprintf(temp, "%04X", ap->a_param[i] & 0xffff);
63980bd37d32Smrg		unparseputs(xw, temp);
63990bd37d32Smrg	    } else {
64000bd37d32Smrg		unparseputn(xw, (unsigned int) ap->a_param[i]);
64010bd37d32Smrg	    }
6402d522f475Smrg	}
6403d522f475Smrg	if ((inters = ap->a_inters) != 0) {
6404d522f475Smrg	    for (i = 3; i >= 0; --i) {
6405d522f475Smrg		c = CharOf(inters >> (8 * i));
6406d522f475Smrg		if (c != 0)
6407d522f475Smrg		    unparseputc(xw, c);
6408d522f475Smrg	    }
6409d522f475Smrg	}
64100bd37d32Smrg	switch (ap->a_type) {
64110bd37d32Smrg	case ANSI_DCS:
64120bd37d32Smrg	case ANSI_OSC:
64130bd37d32Smrg	case ANSI_PM:
64140bd37d32Smrg	case ANSI_APC:
64150bd37d32Smrg	    unparseputc1(xw, ANSI_ST);
64160bd37d32Smrg	    break;
64170bd37d32Smrg	default:
64180bd37d32Smrg	    unparseputc(xw, (char) ap->a_final);
64190bd37d32Smrg	    break;
64200bd37d32Smrg	}
6421d522f475Smrg    }
6422d522f475Smrg    unparse_end(xw);
6423d522f475Smrg}
6424d522f475Smrg
6425d522f475Smrgvoid
6426d522f475Smrgunparseputn(XtermWidget xw, unsigned int n)
6427d522f475Smrg{
6428d522f475Smrg    unsigned int q;
6429d522f475Smrg
6430d522f475Smrg    q = n / 10;
6431d522f475Smrg    if (q != 0)
6432d522f475Smrg	unparseputn(xw, q);
6433d522f475Smrg    unparseputc(xw, (char) ('0' + (n % 10)));
6434d522f475Smrg}
6435d522f475Smrg
6436d522f475Smrgvoid
643720d2c4d2Smrgunparseputs(XtermWidget xw, const char *s)
6438d522f475Smrg{
643920d2c4d2Smrg    if (s != 0) {
644020d2c4d2Smrg	while (*s)
644120d2c4d2Smrg	    unparseputc(xw, *s++);
644220d2c4d2Smrg    }
6443d522f475Smrg}
6444d522f475Smrg
6445d522f475Smrgvoid
6446d522f475Smrgunparseputc(XtermWidget xw, int c)
6447d522f475Smrg{
6448492d43a5Smrg    TScreen *screen = TScreenOf(xw);
6449492d43a5Smrg    IChar *buf = screen->unparse_bfr;
6450d522f475Smrg    unsigned len;
6451d522f475Smrg
64520bd37d32Smrg    if ((screen->unparse_len + 2) >= sizeof(screen->unparse_bfr) / sizeof(IChar))
6453e0a2b6dfSmrg	  unparse_end(xw);
6454d522f475Smrg
6455492d43a5Smrg    len = screen->unparse_len;
6456d522f475Smrg
6457d522f475Smrg#if OPT_TCAP_QUERY
6458d522f475Smrg    /*
6459d522f475Smrg     * If we're returning a termcap string, it has to be translated since
6460d522f475Smrg     * a DCS must not contain any characters except for the normal 7-bit
6461d522f475Smrg     * printable ASCII (counting tab, carriage return, etc).  For now,
6462d522f475Smrg     * just use hexadecimal for the whole thing.
6463d522f475Smrg     */
6464492d43a5Smrg    if (screen->tc_query_code >= 0) {
6465d522f475Smrg	char tmp[3];
6466d522f475Smrg	sprintf(tmp, "%02X", c & 0xFF);
64672eaa94a1Schristos	buf[len++] = CharOf(tmp[0]);
64682eaa94a1Schristos	buf[len++] = CharOf(tmp[1]);
6469d522f475Smrg    } else
6470d522f475Smrg#endif
64712eaa94a1Schristos    if ((buf[len++] = (IChar) c) == '\r' && (xw->flags & LINEFEED)) {
6472d522f475Smrg	buf[len++] = '\n';
6473d522f475Smrg    }
6474d522f475Smrg
6475492d43a5Smrg    screen->unparse_len = len;
6476d522f475Smrg
6477d522f475Smrg    /* If send/receive mode is reset, we echo characters locally */
6478d522f475Smrg    if ((xw->keyboard.flags & MODE_SRM) == 0) {
6479d522f475Smrg	(void) doparsing(xw, (unsigned) c, &myState);
6480d522f475Smrg    }
6481d522f475Smrg}
6482d522f475Smrg
6483d522f475Smrgvoid
6484d522f475Smrgunparse_end(XtermWidget xw)
6485d522f475Smrg{
648620d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
648720d2c4d2Smrg
648820d2c4d2Smrg    if (screen->unparse_len) {
6489d522f475Smrg#ifdef VMS
649020d2c4d2Smrg	tt_write(screen->unparse_bfr, screen->unparse_len);
6491d522f475Smrg#else /* VMS */
649220d2c4d2Smrg	writePtyData(screen->respond, screen->unparse_bfr, screen->unparse_len);
6493d522f475Smrg#endif /* VMS */
649420d2c4d2Smrg	screen->unparse_len = 0;
6495d522f475Smrg    }
6496d522f475Smrg}
6497d522f475Smrg
6498d522f475Smrgvoid
6499d522f475SmrgToggleAlternate(XtermWidget xw)
6500d522f475Smrg{
650120d2c4d2Smrg    if (TScreenOf(xw)->whichBuf)
6502d522f475Smrg	FromAlternate(xw);
6503d522f475Smrg    else
6504e0a2b6dfSmrg	ToAlternate(xw, False);
6505d522f475Smrg}
6506d522f475Smrg
6507d522f475Smrgstatic void
6508e0a2b6dfSmrgToAlternate(XtermWidget xw, Bool clearFirst)
6509d522f475Smrg{
651020d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6511d522f475Smrg
6512956cc18dSsnj    if (screen->whichBuf == 0) {
6513d522f475Smrg	TRACE(("ToAlternate\n"));
6514956cc18dSsnj	if (!screen->editBuf_index[1])
6515956cc18dSsnj	    screen->editBuf_index[1] = allocScrnBuf(xw,
6516956cc18dSsnj						    (unsigned) MaxRows(screen),
6517956cc18dSsnj						    (unsigned) MaxCols(screen),
6518956cc18dSsnj						    &screen->editBuf_data[1]);
6519e0a2b6dfSmrg	SwitchBufs(xw, 1, clearFirst);
6520956cc18dSsnj	screen->whichBuf = 1;
6521956cc18dSsnj#if OPT_SAVE_LINES
6522956cc18dSsnj	screen->visbuf = screen->editBuf_index[screen->whichBuf];
6523956cc18dSsnj#endif
6524d522f475Smrg	update_altscreen();
6525d522f475Smrg    }
6526d522f475Smrg}
6527d522f475Smrg
6528d522f475Smrgstatic void
6529d522f475SmrgFromAlternate(XtermWidget xw)
6530d522f475Smrg{
653120d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6532d522f475Smrg
6533956cc18dSsnj    if (screen->whichBuf != 0) {
6534d522f475Smrg	TRACE(("FromAlternate\n"));
6535d522f475Smrg	if (screen->scroll_amt)
6536d522f475Smrg	    FlushScroll(xw);
6537956cc18dSsnj	screen->whichBuf = 0;
6538e0a2b6dfSmrg	SwitchBufs(xw, 0, False);
6539956cc18dSsnj#if OPT_SAVE_LINES
6540956cc18dSsnj	screen->visbuf = screen->editBuf_index[screen->whichBuf];
6541956cc18dSsnj#endif
6542d522f475Smrg	update_altscreen();
6543d522f475Smrg    }
6544d522f475Smrg}
6545d522f475Smrg
6546d522f475Smrgstatic void
6547e0a2b6dfSmrgSwitchBufs(XtermWidget xw, int toBuf, Bool clearFirst)
6548d522f475Smrg{
654920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6550d522f475Smrg    int rows, top;
6551d522f475Smrg
6552d522f475Smrg    if (screen->cursor_state)
6553d522f475Smrg	HideCursor();
6554d522f475Smrg
6555d522f475Smrg    rows = MaxRows(screen);
655620d2c4d2Smrg    SwitchBufPtrs(screen, toBuf);
6557d522f475Smrg
6558d522f475Smrg    if ((top = INX2ROW(screen, 0)) < rows) {
655920d2c4d2Smrg	if (screen->scroll_amt) {
6560d522f475Smrg	    FlushScroll(xw);
656120d2c4d2Smrg	}
65620bd37d32Smrg#if OPT_DOUBLE_BUFFER
65630bd37d32Smrg	XFillRectangle(screen->display,
65640bd37d32Smrg		       VDrawable(screen),
65650bd37d32Smrg		       ReverseGC(xw, screen),
65660bd37d32Smrg		       (int) OriginX(screen),
65670bd37d32Smrg		       (int) top * FontHeight(screen) + screen->border,
65680bd37d32Smrg		       (unsigned) Width(screen),
65690bd37d32Smrg		       (unsigned) ((rows - top) * FontHeight(screen)));
65700bd37d32Smrg#else
6571d522f475Smrg	XClearArea(screen->display,
6572d522f475Smrg		   VWindow(screen),
6573d522f475Smrg		   (int) OriginX(screen),
6574d522f475Smrg		   (int) top * FontHeight(screen) + screen->border,
6575d522f475Smrg		   (unsigned) Width(screen),
65762eaa94a1Schristos		   (unsigned) ((rows - top) * FontHeight(screen)),
6577d522f475Smrg		   False);
65780bd37d32Smrg#endif
6579e0a2b6dfSmrg	if (clearFirst) {
6580e0a2b6dfSmrg	    ClearBufRows(xw, top, rows);
6581e0a2b6dfSmrg	}
6582d522f475Smrg    }
6583d522f475Smrg    ScrnUpdate(xw, 0, 0, rows, MaxCols(screen), False);
6584d522f475Smrg}
6585d522f475Smrg
6586d522f475SmrgBool
6587e0a2b6dfSmrgCheckBufPtrs(TScreen *screen)
6588d522f475Smrg{
6589d522f475Smrg    return (screen->visbuf != 0
6590956cc18dSsnj#if OPT_SAVE_LINES
6591956cc18dSsnj	    && screen->editBuf_index[0] != 0
6592956cc18dSsnj#endif
6593956cc18dSsnj	    && screen->editBuf_index[1] != 0);
6594d522f475Smrg}
6595d522f475Smrg
6596d522f475Smrg/*
6597d522f475Smrg * Swap buffer line pointers between alternate and regular screens.
6598d522f475Smrg */
6599d522f475Smrgvoid
6600e0a2b6dfSmrgSwitchBufPtrs(TScreen *screen, int toBuf GCC_UNUSED)
6601d522f475Smrg{
6602d522f475Smrg    if (CheckBufPtrs(screen)) {
6603956cc18dSsnj#if OPT_SAVE_LINES
660420d2c4d2Smrg	screen->visbuf = screen->editBuf_index[toBuf];
6605956cc18dSsnj#else
660620d2c4d2Smrg	size_t len = ScrnPointers(screen, (size_t) MaxRows(screen));
6607d522f475Smrg
6608956cc18dSsnj	memcpy(screen->save_ptr, screen->visbuf, len);
6609956cc18dSsnj	memcpy(screen->visbuf, screen->editBuf_index[1], len);
6610956cc18dSsnj	memcpy(screen->editBuf_index[1], screen->save_ptr, len);
6611956cc18dSsnj#endif
6612d522f475Smrg    }
6613d522f475Smrg}
6614d522f475Smrg
6615d522f475Smrgvoid
6616956cc18dSsnjVTRun(XtermWidget xw)
6617d522f475Smrg{
6618956cc18dSsnj    TScreen *screen = TScreenOf(xw);
6619d522f475Smrg
6620d522f475Smrg    TRACE(("VTRun ...\n"));
6621d522f475Smrg
6622d522f475Smrg    if (!screen->Vshow) {
6623d522f475Smrg	set_vt_visibility(True);
6624d522f475Smrg    }
6625d522f475Smrg    update_vttekmode();
6626d522f475Smrg    update_vtshow();
6627d522f475Smrg    update_tekshow();
6628d522f475Smrg    set_vthide_sensitivity();
6629d522f475Smrg
6630956cc18dSsnj    ScrnAllocBuf(xw);
6631d522f475Smrg
6632d522f475Smrg    screen->cursor_state = OFF;
6633d522f475Smrg    screen->cursor_set = ON;
6634d522f475Smrg#if OPT_BLINK_CURS
6635d522f475Smrg    if (DoStartBlinking(screen))
6636d522f475Smrg	StartBlinking(screen);
6637d522f475Smrg#endif
6638d522f475Smrg
6639d522f475Smrg#if OPT_TEK4014
6640d522f475Smrg    if (Tpushb > Tpushback) {
664120d2c4d2Smrg	fillPtyData(xw, VTbuffer, (char *) Tpushback, (int) (Tpushb - Tpushback));
6642d522f475Smrg	Tpushb = Tpushback;
6643d522f475Smrg    }
6644d522f475Smrg#endif
6645d522f475Smrg    screen->is_running = True;
66460bd37d32Smrg    if (screen->embed_high && screen->embed_wide) {
66470bd37d32Smrg	ScreenResize(xw, screen->embed_wide, screen->embed_high, &(xw->flags));
66480bd37d32Smrg    }
6649a1f3da82Smrg#if OPT_MAXIMIZE
66500bd37d32Smrg    else if (resource.fullscreen == esTrue || resource.fullscreen == esAlways)
6651a1f3da82Smrg	FullScreen(term, True);
6652a1f3da82Smrg#endif
6653d522f475Smrg    if (!setjmp(VTend))
6654956cc18dSsnj	VTparse(xw);
6655d522f475Smrg    StopBlinking(screen);
6656d522f475Smrg    HideCursor();
6657d522f475Smrg    screen->cursor_set = OFF;
6658d522f475Smrg    TRACE(("... VTRun\n"));
6659d522f475Smrg}
6660d522f475Smrg
6661d522f475Smrg/*ARGSUSED*/
6662d522f475Smrgstatic void
6663d522f475SmrgVTExpose(Widget w GCC_UNUSED,
6664d522f475Smrg	 XEvent * event,
6665d522f475Smrg	 Region region GCC_UNUSED)
6666d522f475Smrg{
66670bd37d32Smrg    DEBUG_MSG("Expose\n");
6668d522f475Smrg    if (event->type == Expose)
6669d522f475Smrg	HandleExposure(term, event);
6670d522f475Smrg}
6671d522f475Smrg
6672d522f475Smrgstatic void
6673d522f475SmrgVTGraphicsOrNoExpose(XEvent * event)
6674d522f475Smrg{
6675d522f475Smrg    TScreen *screen = TScreenOf(term);
6676d522f475Smrg    if (screen->incopy <= 0) {
6677d522f475Smrg	screen->incopy = 1;
6678d522f475Smrg	if (screen->scrolls > 0)
6679d522f475Smrg	    screen->scrolls--;
6680d522f475Smrg    }
6681d522f475Smrg    if (event->type == GraphicsExpose)
6682d522f475Smrg	if (HandleExposure(term, event))
6683d522f475Smrg	    screen->cursor_state = OFF;
6684d522f475Smrg    if ((event->type == NoExpose)
6685d522f475Smrg	|| ((XGraphicsExposeEvent *) event)->count == 0) {
6686d522f475Smrg	if (screen->incopy <= 0 && screen->scrolls > 0)
6687d522f475Smrg	    screen->scrolls--;
6688d522f475Smrg	if (screen->scrolls)
6689d522f475Smrg	    screen->incopy = -1;
6690d522f475Smrg	else
6691d522f475Smrg	    screen->incopy = 0;
6692d522f475Smrg    }
6693d522f475Smrg}
6694d522f475Smrg
6695d522f475Smrg/*ARGSUSED*/
6696d522f475Smrgstatic void
6697d522f475SmrgVTNonMaskableEvent(Widget w GCC_UNUSED,
6698d522f475Smrg		   XtPointer closure GCC_UNUSED,
6699d522f475Smrg		   XEvent * event,
6700e0a2b6dfSmrg		   Boolean *cont GCC_UNUSED)
6701d522f475Smrg{
6702d522f475Smrg    switch (event->type) {
6703d522f475Smrg    case GraphicsExpose:
6704d522f475Smrg    case NoExpose:
6705d522f475Smrg	VTGraphicsOrNoExpose(event);
6706d522f475Smrg	break;
6707d522f475Smrg    }
6708d522f475Smrg}
6709d522f475Smrg
6710d522f475Smrgstatic void
6711d522f475SmrgVTResize(Widget w)
6712d522f475Smrg{
6713d522f475Smrg    if (XtIsRealized(w)) {
6714d522f475Smrg	XtermWidget xw = (XtermWidget) w;
6715d522f475Smrg	ScreenResize(xw, xw->core.width, xw->core.height, &xw->flags);
6716d522f475Smrg    }
6717d522f475Smrg}
6718d522f475Smrg
67192eaa94a1Schristos#define okDimension(src,dst) ((src <= 32767) \
67202eaa94a1Schristos			  && ((dst = (Dimension) src) == src))
6721d522f475Smrg
6722d522f475Smrgstatic void
6723d522f475SmrgRequestResize(XtermWidget xw, int rows, int cols, Bool text)
6724d522f475Smrg{
672520d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6726d522f475Smrg    unsigned long value;
6727d522f475Smrg    Dimension replyWidth, replyHeight;
6728d522f475Smrg    Dimension askedWidth, askedHeight;
6729d522f475Smrg    XtGeometryResult status;
6730d522f475Smrg    XWindowAttributes attrs;
6731d522f475Smrg
6732d522f475Smrg    TRACE(("RequestResize(rows=%d, cols=%d, text=%d)\n", rows, cols, text));
6733d522f475Smrg
673420d2c4d2Smrg    if ((int) (askedWidth = (Dimension) cols) < cols
673520d2c4d2Smrg	|| (int) (askedHeight = (Dimension) rows) < rows)
6736d522f475Smrg	return;
6737d522f475Smrg
6738d522f475Smrg    if (askedHeight == 0
6739d522f475Smrg	|| askedWidth == 0
6740d522f475Smrg	|| xw->misc.limit_resize > 0) {
67410bd37d32Smrg	xtermGetWinAttrs(XtDisplay(xw),
67420bd37d32Smrg			 RootWindowOfScreen(XtScreen(xw)), &attrs);
6743d522f475Smrg    }
6744d522f475Smrg
6745d522f475Smrg    if (text) {
67462eaa94a1Schristos	if ((value = (unsigned long) rows) != 0) {
6747d522f475Smrg	    if (rows < 0)
67482eaa94a1Schristos		value = (unsigned long) MaxRows(screen);
67492eaa94a1Schristos	    value *= (unsigned long) FontHeight(screen);
67502eaa94a1Schristos	    value += (unsigned long) (2 * screen->border);
6751d522f475Smrg	    if (!okDimension(value, askedHeight))
6752d522f475Smrg		return;
6753d522f475Smrg	}
6754d522f475Smrg
67552eaa94a1Schristos	if ((value = (unsigned long) cols) != 0) {
6756d522f475Smrg	    if (cols < 0)
67572eaa94a1Schristos		value = (unsigned long) MaxCols(screen);
67582eaa94a1Schristos	    value *= (unsigned long) FontWidth(screen);
67592eaa94a1Schristos	    value += (unsigned long) ((2 * screen->border)
67602eaa94a1Schristos				      + ScrollbarWidth(screen));
6761d522f475Smrg	    if (!okDimension(value, askedWidth))
6762d522f475Smrg		return;
6763d522f475Smrg	}
6764d522f475Smrg
6765d522f475Smrg    } else {
6766d522f475Smrg	if (rows < 0)
6767d522f475Smrg	    askedHeight = FullHeight(screen);
6768d522f475Smrg	if (cols < 0)
6769d522f475Smrg	    askedWidth = FullWidth(screen);
6770d522f475Smrg    }
6771d522f475Smrg
6772d522f475Smrg    if (rows == 0)
67732eaa94a1Schristos	askedHeight = (Dimension) attrs.height;
6774d522f475Smrg    if (cols == 0)
67752eaa94a1Schristos	askedWidth = (Dimension) attrs.width;
6776d522f475Smrg
6777d522f475Smrg    if (xw->misc.limit_resize > 0) {
67782eaa94a1Schristos	Dimension high = (Dimension) (xw->misc.limit_resize * attrs.height);
67792eaa94a1Schristos	Dimension wide = (Dimension) (xw->misc.limit_resize * attrs.width);
678020d2c4d2Smrg	if ((int) high < attrs.height)
67812eaa94a1Schristos	    high = (Dimension) attrs.height;
6782d522f475Smrg	if (askedHeight > high)
6783d522f475Smrg	    askedHeight = high;
678420d2c4d2Smrg	if ((int) wide < attrs.width)
67852eaa94a1Schristos	    wide = (Dimension) attrs.width;
6786d522f475Smrg	if (askedWidth > wide)
6787d522f475Smrg	    askedWidth = wide;
6788d522f475Smrg    }
6789d522f475Smrg#ifndef nothack
6790d522f475Smrg    getXtermSizeHints(xw);
6791d522f475Smrg#endif
6792d522f475Smrg
6793956cc18dSsnj    TRACE(("...requesting resize %dx%d\n", askedHeight, askedWidth));
67942eaa94a1Schristos    status = REQ_RESIZE((Widget) xw,
67952eaa94a1Schristos			askedWidth, askedHeight,
67962eaa94a1Schristos			&replyWidth, &replyHeight);
6797d522f475Smrg
6798d522f475Smrg    if (status == XtGeometryYes ||
6799d522f475Smrg	status == XtGeometryDone) {
6800d522f475Smrg	ScreenResize(xw, replyWidth, replyHeight, &xw->flags);
6801d522f475Smrg    }
6802d522f475Smrg#ifndef nothack
6803d522f475Smrg    /*
6804d522f475Smrg     * XtMakeResizeRequest() has the undesirable side-effect of clearing
6805d522f475Smrg     * the window manager's hints, even on a failed request.  This would
6806d522f475Smrg     * presumably be fixed if the shell did its own work.
6807d522f475Smrg     */
6808d522f475Smrg    if (xw->hints.flags
6809d522f475Smrg	&& replyHeight
6810d522f475Smrg	&& replyWidth) {
6811d522f475Smrg	xw->hints.height = replyHeight;
6812d522f475Smrg	xw->hints.width = replyWidth;
6813d522f475Smrg
6814d522f475Smrg	TRACE(("%s@%d -- ", __FILE__, __LINE__));
6815d522f475Smrg	TRACE_HINTS(&xw->hints);
6816a1f3da82Smrg	XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints);
6817d522f475Smrg	TRACE(("%s@%d -- ", __FILE__, __LINE__));
6818d522f475Smrg	TRACE_WM_HINTS(xw);
6819d522f475Smrg    }
6820d522f475Smrg#endif
6821d522f475Smrg
6822d522f475Smrg    XSync(screen->display, False);	/* synchronize */
68230bd37d32Smrg    if (xtermAppPending())
6824d522f475Smrg	xevents();
6825d522f475Smrg
6826d522f475Smrg    TRACE(("...RequestResize done\n"));
6827d522f475Smrg}
6828d522f475Smrg
6829d522f475Smrgstatic String xterm_trans =
6830d522f475Smrg"<ClientMessage>WM_PROTOCOLS: DeleteWindow()\n\
6831d522f475Smrg     <MappingNotify>: KeyboardMapping()\n";
6832d522f475Smrg
6833d522f475Smrgint
6834956cc18dSsnjVTInit(XtermWidget xw)
6835d522f475Smrg{
6836956cc18dSsnj    Widget vtparent = SHELL_OF(xw);
6837d522f475Smrg
6838d522f475Smrg    TRACE(("VTInit {{\n"));
6839d522f475Smrg
6840d522f475Smrg    XtRealizeWidget(vtparent);
6841d522f475Smrg    XtOverrideTranslations(vtparent, XtParseTranslationTable(xterm_trans));
6842d522f475Smrg    (void) XSetWMProtocols(XtDisplay(vtparent), XtWindow(vtparent),
6843d522f475Smrg			   &wm_delete_window, 1);
6844d522f475Smrg    TRACE_TRANS("shell", vtparent);
6845956cc18dSsnj    TRACE_TRANS("vt100", (Widget) (xw));
6846d522f475Smrg
6847956cc18dSsnj    ScrnAllocBuf(xw);
6848d522f475Smrg
6849d522f475Smrg    TRACE(("...}} VTInit\n"));
6850d522f475Smrg    return (1);
6851d522f475Smrg}
6852d522f475Smrg
6853d522f475Smrgstatic void
6854d522f475SmrgVTClassInit(void)
6855d522f475Smrg{
6856d522f475Smrg    XtAddConverter(XtRString, XtRGravity, XmuCvtStringToGravity,
6857d522f475Smrg		   (XtConvertArgList) NULL, (Cardinal) 0);
6858d522f475Smrg}
6859d522f475Smrg
6860d522f475Smrg#if OPT_COLOR_RES
6861d522f475Smrg/*
6862d522f475Smrg * Override the use of XtDefaultForeground/XtDefaultBackground to make some
6863d522f475Smrg * colors, such as cursor color, use the actual foreground/background value
6864d522f475Smrg * if there is no explicit resource value used.
6865d522f475Smrg */
6866d522f475Smrgstatic Pixel
6867d522f475Smrgfill_Tres(XtermWidget target, XtermWidget source, int offset)
6868d522f475Smrg{
6869d522f475Smrg    char *name;
6870d522f475Smrg    ScrnColors temp;
68710bd37d32Smrg    TScreen *src = TScreenOf(source);
68720bd37d32Smrg    TScreen *dst = TScreenOf(target);
6873d522f475Smrg
68740bd37d32Smrg    dst->Tcolors[offset] = src->Tcolors[offset];
68750bd37d32Smrg    dst->Tcolors[offset].mode = False;
6876d522f475Smrg
68770bd37d32Smrg    if ((name = x_strtrim(dst->Tcolors[offset].resource)) != 0)
68780bd37d32Smrg	dst->Tcolors[offset].resource = name;
6879d522f475Smrg
6880d522f475Smrg    if (name == 0) {
68810bd37d32Smrg	dst->Tcolors[offset].value = target->dft_foreground;
6882d522f475Smrg    } else if (isDefaultForeground(name)) {
68830bd37d32Smrg	dst->Tcolors[offset].value = ((offset == TEXT_FG || offset == TEXT_BG)
68840bd37d32Smrg				      ? target->dft_foreground
68850bd37d32Smrg				      : dst->Tcolors[TEXT_FG].value);
6886d522f475Smrg    } else if (isDefaultBackground(name)) {
68870bd37d32Smrg	dst->Tcolors[offset].value = ((offset == TEXT_FG || offset == TEXT_BG)
68880bd37d32Smrg				      ? target->dft_background
68890bd37d32Smrg				      : dst->Tcolors[TEXT_BG].value);
6890d522f475Smrg    } else {
6891d522f475Smrg	memset(&temp, 0, sizeof(temp));
689220d2c4d2Smrg	if (AllocateTermColor(target, &temp, offset, name, True)) {
6893d522f475Smrg	    if (COLOR_DEFINED(&(temp), offset))
6894d522f475Smrg		free(temp.names[offset]);
68950bd37d32Smrg	    dst->Tcolors[offset].value = temp.colors[offset];
68960bd37d32Smrg	} else if (offset == TEXT_FG || offset == TEXT_BG) {
68970bd37d32Smrg	    free(name);
68980bd37d32Smrg	    dst->Tcolors[offset].resource = 0;
68990bd37d32Smrg	}
69000bd37d32Smrg    }
69010bd37d32Smrg    return dst->Tcolors[offset].value;
69020bd37d32Smrg}
69030bd37d32Smrg
69040bd37d32Smrg/*
69050bd37d32Smrg * If one or both of the foreground/background colors cannot be allocated,
69060bd37d32Smrg * e.g., due to gross misconfiguration, recover by setting both to the
69070bd37d32Smrg * display's default values.
69080bd37d32Smrg */
69090bd37d32Smrgstatic void
69100bd37d32SmrgrepairColors(XtermWidget target)
69110bd37d32Smrg{
69120bd37d32Smrg    TScreen *screen = TScreenOf(target);
69130bd37d32Smrg
69140bd37d32Smrg    if (screen->Tcolors[TEXT_FG].resource == 0 ||
69150bd37d32Smrg	screen->Tcolors[TEXT_BG].resource == 0) {
69160bd37d32Smrg	xtermWarning("unable to allocate fg/bg colors\n");
69170bd37d32Smrg	screen->Tcolors[TEXT_FG].resource = x_strdup(XtDefaultForeground);
69180bd37d32Smrg	screen->Tcolors[TEXT_BG].resource = x_strdup(XtDefaultBackground);
69190bd37d32Smrg	if (screen->Tcolors[TEXT_FG].resource == 0 ||
69200bd37d32Smrg	    screen->Tcolors[TEXT_BG].resource == 0) {
69210bd37d32Smrg	    Exit(1);
6922d522f475Smrg	}
69230bd37d32Smrg	screen->Tcolors[TEXT_FG].value = target->dft_foreground;
69240bd37d32Smrg	screen->Tcolors[TEXT_BG].value = target->dft_background;
6925d522f475Smrg    }
6926d522f475Smrg}
6927d522f475Smrg#else
6928d522f475Smrg#define fill_Tres(target, source, offset) \
692920d2c4d2Smrg	TScreenOf(target)->Tcolors[offset] = TScreenOf(source)->Tcolors[offset]
69300bd37d32Smrg#define repairColors(target)	/* nothing */
6931d522f475Smrg#endif
6932d522f475Smrg
6933d522f475Smrg#if OPT_WIDE_CHARS
6934d522f475Smrgstatic void
693520d2c4d2SmrgVTInitialize_locale(XtermWidget xw)
6936d522f475Smrg{
693720d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6938d522f475Smrg    Bool is_utf8 = xtermEnvUTF8();
6939d522f475Smrg
6940d522f475Smrg    TRACE(("VTInitialize_locale\n"));
694120d2c4d2Smrg    TRACE(("... request screen.utf8_mode = %d\n", screen->utf8_mode));
6942e39b573cSmrg    TRACE(("... request screen.utf8_fonts = %d\n", screen->utf8_fonts));
6943d522f475Smrg
6944e0a2b6dfSmrg    screen->utf8_always = (screen->utf8_mode == uAlways);
694520d2c4d2Smrg    if (screen->utf8_mode < 0)
694620d2c4d2Smrg	screen->utf8_mode = uFalse;
6947d522f475Smrg
694820d2c4d2Smrg    if (screen->utf8_mode > 3)
694920d2c4d2Smrg	screen->utf8_mode = uDefault;
6950d522f475Smrg
695120d2c4d2Smrg    screen->latin9_mode = 0;
695220d2c4d2Smrg    screen->unicode_font = 0;
6953d522f475Smrg#if OPT_LUIT_PROG
695420d2c4d2Smrg    xw->misc.callfilter = 0;
695520d2c4d2Smrg    xw->misc.use_encoding = 0;
6956d522f475Smrg
6957d522f475Smrg    TRACE(("... setup for luit:\n"));
695820d2c4d2Smrg    TRACE(("... request misc.locale_str = \"%s\"\n", xw->misc.locale_str));
6959d522f475Smrg
696020d2c4d2Smrg    if (screen->utf8_mode == uFalse) {
6961d522f475Smrg	TRACE(("... command-line +u8 overrides\n"));
6962d522f475Smrg    } else
6963d522f475Smrg#if OPT_MINI_LUIT
696420d2c4d2Smrg    if (x_strcasecmp(xw->misc.locale_str, "CHECKFONT") == 0) {
696520d2c4d2Smrg	int fl = (xw->misc.default_font.f_n
696620d2c4d2Smrg		  ? (int) strlen(xw->misc.default_font.f_n)
6967d522f475Smrg		  : 0);
6968d522f475Smrg	if (fl > 11
696920d2c4d2Smrg	    && x_strcasecmp(xw->misc.default_font.f_n + fl - 11,
6970d522f475Smrg			    "-ISO10646-1") == 0) {
697120d2c4d2Smrg	    screen->unicode_font = 1;
6972d522f475Smrg	    /* unicode font, use True */
6973d522f475Smrg#ifdef HAVE_LANGINFO_CODESET
6974d522f475Smrg	    if (!strcmp(xtermEnvEncoding(), "ANSI_X3.4-1968")
6975d522f475Smrg		|| !strcmp(xtermEnvEncoding(), "ISO-8859-1")) {
697620d2c4d2Smrg		if (screen->utf8_mode == uDefault)
697720d2c4d2Smrg		    screen->utf8_mode = uFalse;
6978d522f475Smrg	    } else if (!strcmp(xtermEnvEncoding(), "ISO-8859-15")) {
697920d2c4d2Smrg		if (screen->utf8_mode == uDefault)
698020d2c4d2Smrg		    screen->utf8_mode = uFalse;
698120d2c4d2Smrg		screen->latin9_mode = 1;
6982d522f475Smrg	    } else {
698320d2c4d2Smrg		xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1);
698420d2c4d2Smrg		screen->utf8_mode = uAlways;
6985d522f475Smrg	    }
6986d522f475Smrg#else
698720d2c4d2Smrg	    xw->misc.callfilter = is_utf8 ? 0 : 1;
698820d2c4d2Smrg	    screen->utf8_mode = uAlways;
6989d522f475Smrg#endif
6990d522f475Smrg	} else {
6991d522f475Smrg	    /* other encoding, use False */
699220d2c4d2Smrg	    if (screen->utf8_mode == uDefault) {
699320d2c4d2Smrg		screen->utf8_mode = is_utf8 ? uAlways : uFalse;
6994d522f475Smrg	    }
6995d522f475Smrg	}
6996d522f475Smrg    } else
6997d522f475Smrg#endif /* OPT_MINI_LUIT */
699820d2c4d2Smrg	if (x_strcasecmp(xw->misc.locale_str, "TRUE") == 0 ||
699920d2c4d2Smrg	    x_strcasecmp(xw->misc.locale_str, "ON") == 0 ||
700020d2c4d2Smrg	    x_strcasecmp(xw->misc.locale_str, "YES") == 0 ||
700120d2c4d2Smrg	    x_strcasecmp(xw->misc.locale_str, "AUTO") == 0 ||
700220d2c4d2Smrg	    strcmp(xw->misc.locale_str, "1") == 0) {
7003d522f475Smrg	/* when true ... fully obeying LC_CTYPE locale */
700420d2c4d2Smrg	xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1);
700520d2c4d2Smrg	screen->utf8_mode = uAlways;
700620d2c4d2Smrg    } else if (x_strcasecmp(xw->misc.locale_str, "FALSE") == 0 ||
700720d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "OFF") == 0 ||
700820d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "NO") == 0 ||
700920d2c4d2Smrg	       strcmp(xw->misc.locale_str, "0") == 0) {
7010d522f475Smrg	/* when false ... original value of utf8_mode is effective */
701120d2c4d2Smrg	if (screen->utf8_mode == uDefault) {
701220d2c4d2Smrg	    screen->utf8_mode = is_utf8 ? uAlways : uFalse;
7013d522f475Smrg	}
701420d2c4d2Smrg    } else if (x_strcasecmp(xw->misc.locale_str, "MEDIUM") == 0 ||
701520d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "SEMIAUTO") == 0) {
7016d522f475Smrg	/* when medium ... obeying locale only for UTF-8 and Asian */
7017d522f475Smrg	if (is_utf8) {
701820d2c4d2Smrg	    screen->utf8_mode = uAlways;
7019d522f475Smrg	} else if (
7020d522f475Smrg#ifdef MB_CUR_MAX
7021d522f475Smrg		      MB_CUR_MAX > 1 ||
7022d522f475Smrg#else
702320d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "ja", (size_t) 2) ||
702420d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "ko", (size_t) 2) ||
702520d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "zh", (size_t) 2) ||
702620d2c4d2Smrg#endif
702720d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "th", (size_t) 2) ||
702820d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "vi", (size_t) 2)) {
702920d2c4d2Smrg	    xw->misc.callfilter = 1;
703020d2c4d2Smrg	    screen->utf8_mode = uAlways;
7031d522f475Smrg	} else {
703220d2c4d2Smrg	    screen->utf8_mode = uFalse;
7033d522f475Smrg	}
703420d2c4d2Smrg    } else if (x_strcasecmp(xw->misc.locale_str, "UTF-8") == 0 ||
703520d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "UTF8") == 0) {
7036d522f475Smrg	/* when UTF-8 ... UTF-8 mode */
703720d2c4d2Smrg	screen->utf8_mode = uAlways;
7038d522f475Smrg    } else {
7039d522f475Smrg	/* other words are regarded as encoding name passed to luit */
704020d2c4d2Smrg	xw->misc.callfilter = 1;
704120d2c4d2Smrg	screen->utf8_mode = uAlways;
704220d2c4d2Smrg	xw->misc.use_encoding = 1;
7043d522f475Smrg    }
704420d2c4d2Smrg    TRACE(("... updated misc.callfilter = %s\n", BtoS(xw->misc.callfilter)));
704520d2c4d2Smrg    TRACE(("... updated misc.use_encoding = %s\n", BtoS(xw->misc.use_encoding)));
7046d522f475Smrg#else
704720d2c4d2Smrg    if (screen->utf8_mode == uDefault) {
704820d2c4d2Smrg	screen->utf8_mode = is_utf8 ? uAlways : uFalse;
7049d522f475Smrg    }
7050d522f475Smrg#endif /* OPT_LUIT_PROG */
7051d522f475Smrg
7052e39b573cSmrg    if (screen->utf8_fonts == uDefault) {
7053e39b573cSmrg	switch (screen->utf8_mode) {
7054e39b573cSmrg	case uFalse:
7055e39b573cSmrg	case uTrue:
7056e39b573cSmrg	    screen->utf8_fonts = screen->utf8_mode;
7057e39b573cSmrg	    break;
7058e39b573cSmrg	case uDefault:
7059e39b573cSmrg	    /* should not happen */
7060e39b573cSmrg	    screen->utf8_fonts = uTrue;
7061e39b573cSmrg	    break;
7062e39b573cSmrg	case uAlways:
7063e39b573cSmrg	    /* use this to disable menu entry */
7064e39b573cSmrg	    break;
7065e39b573cSmrg	}
7066e39b573cSmrg    }
7067e39b573cSmrg
706820d2c4d2Smrg    screen->utf8_inparse = (Boolean) (screen->utf8_mode != uFalse);
7069d522f475Smrg
707020d2c4d2Smrg    TRACE(("... updated screen.utf8_mode = %d\n", screen->utf8_mode));
7071e39b573cSmrg    TRACE(("... updated screen.utf8_fonts = %d\n", screen->utf8_fonts));
7072d522f475Smrg    TRACE(("...VTInitialize_locale done\n"));
7073d522f475Smrg}
7074d522f475Smrg#endif
7075d522f475Smrg
70760bd37d32Smrgvoid
70770bd37d32SmrglookupSelectUnit(XtermWidget xw, Cardinal item, String value)
7078d522f475Smrg{
7079d522f475Smrg    /* *INDENT-OFF* */
7080d522f475Smrg    static struct {
708120d2c4d2Smrg	const char *	name;
7082d522f475Smrg	SelectUnit	code;
7083d522f475Smrg    } table[] = {
7084d522f475Smrg    	{ "char",	Select_CHAR },
7085d522f475Smrg    	{ "word",	Select_WORD },
7086d522f475Smrg    	{ "line",	Select_LINE },
7087d522f475Smrg    	{ "group",	Select_GROUP },
7088d522f475Smrg    	{ "page",	Select_PAGE },
7089d522f475Smrg    	{ "all",	Select_ALL },
7090d522f475Smrg#if OPT_SELECT_REGEX
7091d522f475Smrg    	{ "regex",	Select_REGEX },
7092d522f475Smrg#endif
7093d522f475Smrg    };
7094d522f475Smrg    /* *INDENT-ON* */
7095d522f475Smrg
70960bd37d32Smrg    TScreen *screen = TScreenOf(xw);
70970bd37d32Smrg    String next = x_skip_nonblanks(value);
7098d522f475Smrg    Cardinal n;
7099d522f475Smrg
71000bd37d32Smrg    screen->selectMap[item] = NSELECTUNITS;
7101d522f475Smrg    for (n = 0; n < XtNumber(table); ++n) {
71020bd37d32Smrg	if (!x_strncasecmp(table[n].name, value, (unsigned) (next - value))) {
71030bd37d32Smrg	    screen->selectMap[item] = table[n].code;
7104d522f475Smrg#if OPT_SELECT_REGEX
7105d522f475Smrg	    if (table[n].code == Select_REGEX) {
71060bd37d32Smrg		screen->selectExpr[item] = x_strtrim(next);
71070bd37d32Smrg		TRACE(("Parsed regex \"%s\"\n", screen->selectExpr[item]));
7108d522f475Smrg	    }
7109d522f475Smrg#endif
7110d522f475Smrg	    break;
7111d522f475Smrg	}
7112d522f475Smrg    }
7113d522f475Smrg}
7114d522f475Smrg
71150bd37d32Smrgstatic void
71160bd37d32SmrgParseOnClicks(XtermWidget wnew, XtermWidget wreq, Cardinal item)
71170bd37d32Smrg{
71180bd37d32Smrg    lookupSelectUnit(wnew, item, TScreenOf(wreq)->onClick[item]);
71190bd37d32Smrg}
71200bd37d32Smrg
712120d2c4d2Smrg/*
712220d2c4d2Smrg * Parse a comma-separated list, returning a string which the caller must
712320d2c4d2Smrg * free, and updating the source pointer.
712420d2c4d2Smrg */
712520d2c4d2Smrgstatic char *
712620d2c4d2SmrgParseList(const char **source)
712720d2c4d2Smrg{
712820d2c4d2Smrg    const char *base = *source;
712920d2c4d2Smrg    const char *next;
713020d2c4d2Smrg    size_t size;
713120d2c4d2Smrg    char *value = 0;
713220d2c4d2Smrg    char *result;
713320d2c4d2Smrg
713420d2c4d2Smrg    /* ignore empty values */
713520d2c4d2Smrg    while (*base == ',')
713620d2c4d2Smrg	++base;
713720d2c4d2Smrg    if (*base != '\0') {
713820d2c4d2Smrg	next = base;
713920d2c4d2Smrg	while (*next != '\0' && *next != ',')
714020d2c4d2Smrg	    ++next;
714120d2c4d2Smrg	size = (size_t) (1 + next - base);
714220d2c4d2Smrg	value = malloc(size);
714320d2c4d2Smrg	if (value != 0) {
714420d2c4d2Smrg	    memcpy(value, base, size);
714520d2c4d2Smrg	    value[size - 1] = '\0';
714620d2c4d2Smrg	}
714720d2c4d2Smrg	*source = next;
714820d2c4d2Smrg    } else {
714920d2c4d2Smrg	*source = base;
715020d2c4d2Smrg    }
715120d2c4d2Smrg    result = x_strtrim(value);
715220d2c4d2Smrg    free(value);
715320d2c4d2Smrg    return result;
715420d2c4d2Smrg}
715520d2c4d2Smrg
715620d2c4d2Smrgstatic void
715720d2c4d2Smrgset_flags_from_list(char *target,
715820d2c4d2Smrg		    const char *source,
715920d2c4d2Smrg		    FlagList * list,
716020d2c4d2Smrg		    Cardinal limit)
716120d2c4d2Smrg{
716220d2c4d2Smrg    Cardinal n;
716320d2c4d2Smrg    int value = -1;
716420d2c4d2Smrg
71650bd37d32Smrg    while (!IsEmpty(source)) {
716620d2c4d2Smrg	char *next = ParseList(&source);
716720d2c4d2Smrg	Boolean found = False;
716820d2c4d2Smrg
716920d2c4d2Smrg	if (next == 0)
717020d2c4d2Smrg	    break;
717120d2c4d2Smrg	if (isdigit(CharOf(*next))) {
717220d2c4d2Smrg	    char *temp;
717320d2c4d2Smrg
717420d2c4d2Smrg	    value = (int) strtol(next, &temp, 0);
717520d2c4d2Smrg	    if (!IsEmpty(temp)) {
71760bd37d32Smrg		xtermWarning("Expected a number: %s\n", next);
717720d2c4d2Smrg	    } else {
717820d2c4d2Smrg		for (n = 0; n < limit; ++n) {
717920d2c4d2Smrg		    if (list[n].code == value) {
718020d2c4d2Smrg			target[value] = 1;
718120d2c4d2Smrg			found = True;
718220d2c4d2Smrg			break;
718320d2c4d2Smrg		    }
718420d2c4d2Smrg		}
718520d2c4d2Smrg	    }
718620d2c4d2Smrg	} else {
718720d2c4d2Smrg	    for (n = 0; n < limit; ++n) {
718820d2c4d2Smrg		if (!x_strcasecmp(next, list[n].name)) {
718920d2c4d2Smrg		    value = list[n].code;
719020d2c4d2Smrg		    target[value] = 1;
719120d2c4d2Smrg		    found = True;
719220d2c4d2Smrg		    break;
719320d2c4d2Smrg		}
719420d2c4d2Smrg	    }
719520d2c4d2Smrg	}
719620d2c4d2Smrg	if (!found) {
71970bd37d32Smrg	    xtermWarning("Unrecognized keyword: %s\n", next);
719820d2c4d2Smrg	} else {
719920d2c4d2Smrg	    TRACE(("...found %s (%d)\n", next, value));
720020d2c4d2Smrg	}
720120d2c4d2Smrg	free(next);
720220d2c4d2Smrg    }
720320d2c4d2Smrg}
720420d2c4d2Smrg
7205e0a2b6dfSmrg#if OPT_RENDERFONT
7206e0a2b6dfSmrgstatic void
7207e0a2b6dfSmrgtrimSizeFromFace(char *face_name, float *face_size)
7208e0a2b6dfSmrg{
7209e0a2b6dfSmrg    char *first = strstr(face_name, ":size=");
7210e0a2b6dfSmrg    if (first == 0) {
7211e0a2b6dfSmrg	first = face_name;
7212e0a2b6dfSmrg    } else {
7213e0a2b6dfSmrg	first++;
7214e0a2b6dfSmrg    }
7215e0a2b6dfSmrg    if (!strncmp(first, "size=", (size_t) 5)) {
7216e0a2b6dfSmrg	char *last = strchr(first, ':');
7217e0a2b6dfSmrg	char mark;
7218e0a2b6dfSmrg	float value;
7219e0a2b6dfSmrg	char extra;
7220e0a2b6dfSmrg	if (last == 0)
7221e0a2b6dfSmrg	    last = first + strlen(first);
7222e0a2b6dfSmrg	mark = *last;
7223e0a2b6dfSmrg	*last = '\0';
7224e0a2b6dfSmrg	if (sscanf(first, "size=%g%c", &value, &extra) == 1) {
7225e0a2b6dfSmrg	    TRACE(("...trimmed size from font: %g\n", value));
7226e0a2b6dfSmrg	    if (face_size != 0)
7227e0a2b6dfSmrg		*face_size = value;
7228e0a2b6dfSmrg	}
7229e0a2b6dfSmrg	if (mark) {
7230e0a2b6dfSmrg	    while ((*first++ = *++last) != '\0') {
7231e0a2b6dfSmrg		;
7232e0a2b6dfSmrg	    }
7233e0a2b6dfSmrg	} else {
7234e0a2b6dfSmrg	    if (first != face_name)
7235e0a2b6dfSmrg		--first;
7236e0a2b6dfSmrg	    *first = '\0';
7237e0a2b6dfSmrg	}
7238e0a2b6dfSmrg	TRACE(("...after trimming, font = \"%s\"\n", face_name));
7239e0a2b6dfSmrg    }
7240e0a2b6dfSmrg}
7241e0a2b6dfSmrg#endif
7242e0a2b6dfSmrg
7243d522f475Smrg/* ARGSUSED */
7244d522f475Smrgstatic void
7245d522f475SmrgVTInitialize(Widget wrequest,
7246d522f475Smrg	     Widget new_arg,
7247d522f475Smrg	     ArgList args GCC_UNUSED,
7248d522f475Smrg	     Cardinal *num_args GCC_UNUSED)
7249d522f475Smrg{
725020d2c4d2Smrg#define Kolor(name) TScreenOf(wnew)->name.resource
7251d522f475Smrg#define TxtFg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_FG]), Kolor(name))
7252d522f475Smrg#define TxtBg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_BG]), Kolor(name))
7253d522f475Smrg#define DftFg(name) isDefaultForeground(Kolor(name))
7254d522f475Smrg#define DftBg(name) isDefaultBackground(Kolor(name))
7255d522f475Smrg
725620d2c4d2Smrg#define DATA(name) { #name, ec##name }
725720d2c4d2Smrg    static FlagList tblColorOps[] =
725820d2c4d2Smrg    {
725920d2c4d2Smrg	DATA(SetColor)
726020d2c4d2Smrg	,DATA(GetColor)
726120d2c4d2Smrg	,DATA(GetAnsiColor)
726220d2c4d2Smrg    };
726320d2c4d2Smrg#undef DATA
726420d2c4d2Smrg
726520d2c4d2Smrg#define DATA(name) { #name, ef##name }
726620d2c4d2Smrg    static FlagList tblFontOps[] =
726720d2c4d2Smrg    {
726820d2c4d2Smrg	DATA(SetFont)
726920d2c4d2Smrg	,DATA(GetFont)
727020d2c4d2Smrg    };
727120d2c4d2Smrg#undef DATA
727220d2c4d2Smrg
727320d2c4d2Smrg#define DATA(name) { #name, et##name }
727420d2c4d2Smrg    static FlagList tblTcapOps[] =
727520d2c4d2Smrg    {
727620d2c4d2Smrg	DATA(SetTcap)
727720d2c4d2Smrg	,DATA(GetTcap)
727820d2c4d2Smrg    };
727920d2c4d2Smrg#undef DATA
728020d2c4d2Smrg
728120d2c4d2Smrg#define DATA(name) { #name, ew##name }
728220d2c4d2Smrg    static FlagList tblWindowOps[] =
728320d2c4d2Smrg    {
728420d2c4d2Smrg	DATA(RestoreWin)
728520d2c4d2Smrg	,DATA(MinimizeWin)
728620d2c4d2Smrg	,DATA(SetWinPosition)
728720d2c4d2Smrg	,DATA(SetWinSizePixels)
728820d2c4d2Smrg	,DATA(RaiseWin)
728920d2c4d2Smrg	,DATA(LowerWin)
729020d2c4d2Smrg	,DATA(RefreshWin)
729120d2c4d2Smrg	,DATA(SetWinSizeChars)
729220d2c4d2Smrg#if OPT_MAXIMIZE
729320d2c4d2Smrg	,DATA(MaximizeWin)
7294a1f3da82Smrg	,DATA(FullscreenWin)
729520d2c4d2Smrg#endif
729620d2c4d2Smrg	,DATA(GetWinState)
729720d2c4d2Smrg	,DATA(GetWinPosition)
729820d2c4d2Smrg	,DATA(GetWinSizePixels)
729920d2c4d2Smrg	,DATA(GetWinSizeChars)
730020d2c4d2Smrg#if OPT_MAXIMIZE
730120d2c4d2Smrg	,DATA(GetScreenSizeChars)
730220d2c4d2Smrg#endif
730320d2c4d2Smrg	,DATA(GetIconTitle)
730420d2c4d2Smrg	,DATA(GetWinTitle)
730520d2c4d2Smrg	,DATA(PushTitle)
730620d2c4d2Smrg	,DATA(PopTitle)
730720d2c4d2Smrg	,DATA(SetWinLines)
730820d2c4d2Smrg	,DATA(SetXprop)
730920d2c4d2Smrg	,DATA(GetSelection)
731020d2c4d2Smrg	,DATA(SetSelection)
731120d2c4d2Smrg    };
731220d2c4d2Smrg#undef DATA
731320d2c4d2Smrg
731420d2c4d2Smrg#if OPT_RENDERFONT
731520d2c4d2Smrg#define DATA(name) { #name, er##name }
731620d2c4d2Smrg    static FlagList tblRenderFont[] =
731720d2c4d2Smrg    {
731820d2c4d2Smrg	DATA(Default)
731920d2c4d2Smrg    };
732020d2c4d2Smrg#undef DATA
7321e39b573cSmrg#endif
7322e39b573cSmrg
7323e39b573cSmrg#if OPT_WIDE_CHARS
7324e39b573cSmrg#define DATA(name) { #name, u##name }
7325e39b573cSmrg    static FlagList tblUtf8Mode[] =
7326e39b573cSmrg    {
7327e39b573cSmrg	DATA(Always)
7328e39b573cSmrg	,DATA(Default)
7329e39b573cSmrg    };
7330e39b573cSmrg#undef DATA
733120d2c4d2Smrg#endif
733220d2c4d2Smrg
73330bd37d32Smrg#ifndef NO_ACTIVE_ICON
73340bd37d32Smrg#define DATA(name) { #name, ei##name }
73350bd37d32Smrg    static FlagList tblAIconOps[] =
73360bd37d32Smrg    {
73370bd37d32Smrg	DATA(Default)
73380bd37d32Smrg    };
73390bd37d32Smrg#undef DATA
73400bd37d32Smrg#endif
73410bd37d32Smrg
73420bd37d32Smrg#define DATA(name) { #name, eb##name }
73430bd37d32Smrg    static FlagList tbl8BitMeta[] =
73440bd37d32Smrg    {
73450bd37d32Smrg	DATA(Never)
73460bd37d32Smrg	,DATA(Locale)
73470bd37d32Smrg    };
73480bd37d32Smrg#undef DATA
73490bd37d32Smrg
7350d522f475Smrg    XtermWidget request = (XtermWidget) wrequest;
7351d522f475Smrg    XtermWidget wnew = (XtermWidget) new_arg;
7352d522f475Smrg    Widget my_parent = SHELL_OF(wnew);
7353d522f475Smrg    int i;
7354492d43a5Smrg    const char *s;
7355d522f475Smrg
7356d522f475Smrg#if OPT_ISO_COLORS
7357d522f475Smrg    Bool color_ok;
7358d522f475Smrg#endif
7359d522f475Smrg
736020d2c4d2Smrg#if OPT_COLOR_RES2
7361d522f475Smrg    static XtResource fake_resources[] =
7362d522f475Smrg    {
7363d522f475Smrg#if OPT_256_COLORS
7364d522f475Smrg# include <256colres.h>
7365d522f475Smrg#elif OPT_88_COLORS
7366d522f475Smrg# include <88colres.h>
7367d522f475Smrg#endif
7368d522f475Smrg    };
7369d522f475Smrg#endif /* OPT_COLOR_RES2 */
7370d522f475Smrg
737120d2c4d2Smrg    TRACE(("VTInitialize wnew %p, %d / %d resources\n",
737220d2c4d2Smrg	   (void *) wnew, XtNumber(xterm_resources), MAXRESOURCES));
737320d2c4d2Smrg    assert(XtNumber(xterm_resources) < MAXRESOURCES);
7374d522f475Smrg
7375d522f475Smrg    /* Zero out the entire "screen" component of "wnew" widget, then do
7376d522f475Smrg     * field-by-field assignment of "screen" fields that are named in the
7377d522f475Smrg     * resource list.
7378d522f475Smrg     */
737920d2c4d2Smrg    memset(TScreenOf(wnew), 0, sizeof(wnew->screen));
7380d522f475Smrg
7381d522f475Smrg    /* DESCO Sys#67660
7382d522f475Smrg     * Zero out the entire "keyboard" component of "wnew" widget.
7383d522f475Smrg     */
7384956cc18dSsnj    memset(&wnew->keyboard, 0, sizeof(wnew->keyboard));
7385d522f475Smrg
73860bd37d32Smrg    /*
73870bd37d32Smrg     * The workspace has no resources - clear it.
73880bd37d32Smrg     */
73890bd37d32Smrg    memset(&wnew->work, 0, sizeof(wnew->work));
73900bd37d32Smrg
7391d522f475Smrg    /* dummy values so that we don't try to Realize the parent shell with height
7392d522f475Smrg     * or width of 0, which is illegal in X.  The real size is computed in the
7393d522f475Smrg     * xtermWidget's Realize proc, but the shell's Realize proc is called first,
7394d522f475Smrg     * and must see a valid size.
7395d522f475Smrg     */
7396d522f475Smrg    wnew->core.height = wnew->core.width = 1;
7397d522f475Smrg
7398d522f475Smrg    /*
7399d522f475Smrg     * The definition of -rv now is that it changes the definition of
7400d522f475Smrg     * XtDefaultForeground and XtDefaultBackground.  So, we no longer
7401d522f475Smrg     * need to do anything special.
7402d522f475Smrg     */
740320d2c4d2Smrg    TScreenOf(wnew)->display = wnew->core.screen->display;
7404d522f475Smrg
7405e0a2b6dfSmrg    /* prep getVisualInfo() */
7406e0a2b6dfSmrg    wnew->visInfo = 0;
7407e0a2b6dfSmrg    wnew->numVisuals = 0;
7408e0a2b6dfSmrg    (void) getVisualInfo(wnew);
7409e0a2b6dfSmrg
7410d522f475Smrg    /*
7411d522f475Smrg     * We use the default foreground/background colors to compare/check if a
7412d522f475Smrg     * color-resource has been set.
7413d522f475Smrg     */
7414d522f475Smrg#define MyBlackPixel(dpy) BlackPixel(dpy,DefaultScreen(dpy))
7415d522f475Smrg#define MyWhitePixel(dpy) WhitePixel(dpy,DefaultScreen(dpy))
7416d522f475Smrg
7417d522f475Smrg    if (request->misc.re_verse) {
741820d2c4d2Smrg	wnew->dft_foreground = MyWhitePixel(TScreenOf(wnew)->display);
741920d2c4d2Smrg	wnew->dft_background = MyBlackPixel(TScreenOf(wnew)->display);
7420d522f475Smrg    } else {
742120d2c4d2Smrg	wnew->dft_foreground = MyBlackPixel(TScreenOf(wnew)->display);
742220d2c4d2Smrg	wnew->dft_background = MyWhitePixel(TScreenOf(wnew)->display);
7423d522f475Smrg    }
7424e39b573cSmrg
7425d522f475Smrg    init_Tres(TEXT_FG);
7426d522f475Smrg    init_Tres(TEXT_BG);
74270bd37d32Smrg    repairColors(wnew);
7428d522f475Smrg
7429e39b573cSmrg    wnew->old_foreground = T_COLOR(TScreenOf(wnew), TEXT_FG);
7430e39b573cSmrg    wnew->old_background = T_COLOR(TScreenOf(wnew), TEXT_BG);
7431e39b573cSmrg
7432d522f475Smrg    TRACE(("Color resource initialization:\n"));
7433e39b573cSmrg    TRACE(("   Default foreground 0x%06lx\n", wnew->dft_foreground));
7434e39b573cSmrg    TRACE(("   Default background 0x%06lx\n", wnew->dft_background));
7435e39b573cSmrg    TRACE(("   Screen foreground  0x%06lx\n", T_COLOR(TScreenOf(wnew), TEXT_FG)));
7436e39b573cSmrg    TRACE(("   Screen background  0x%06lx\n", T_COLOR(TScreenOf(wnew), TEXT_BG)));
7437e39b573cSmrg    TRACE(("   Actual  foreground 0x%06lx\n", wnew->old_foreground));
7438e39b573cSmrg    TRACE(("   Actual  background 0x%06lx\n", wnew->old_background));
7439d522f475Smrg
74400bd37d32Smrg    TScreenOf(wnew)->mouse_button = 0;
744120d2c4d2Smrg    TScreenOf(wnew)->mouse_row = -1;
744220d2c4d2Smrg    TScreenOf(wnew)->mouse_col = -1;
7443d522f475Smrg
7444d522f475Smrg#if OPT_BOX_CHARS
7445d522f475Smrg    init_Bres(screen.force_box_chars);
744620d2c4d2Smrg    init_Bres(screen.force_packed);
7447d522f475Smrg    init_Bres(screen.force_all_chars);
7448e0a2b6dfSmrg    init_Bres(screen.assume_all_chars);
7449d522f475Smrg#endif
7450d522f475Smrg    init_Bres(screen.free_bold_box);
7451e39b573cSmrg    init_Bres(screen.allowBoldFonts);
7452d522f475Smrg
7453d522f475Smrg    init_Bres(screen.c132);
7454d522f475Smrg    init_Bres(screen.curses);
7455d522f475Smrg    init_Bres(screen.hp_ll_bc);
7456d522f475Smrg#if OPT_XMC_GLITCH
7457d522f475Smrg    init_Ires(screen.xmc_glitch);
7458d522f475Smrg    init_Ires(screen.xmc_attributes);
7459d522f475Smrg    init_Bres(screen.xmc_inline);
7460d522f475Smrg    init_Bres(screen.move_sgr_ok);
7461d522f475Smrg#endif
7462d522f475Smrg#if OPT_BLINK_CURS
7463d522f475Smrg    init_Bres(screen.cursor_blink);
7464d522f475Smrg    init_Ires(screen.blink_on);
7465d522f475Smrg    init_Ires(screen.blink_off);
746620d2c4d2Smrg    TScreenOf(wnew)->cursor_blink_res = TScreenOf(wnew)->cursor_blink;
7467d522f475Smrg#endif
74680bd37d32Smrg    /* resources allow for underline or block, not (yet) bar */
74690bd37d32Smrg    TScreenOf(wnew)->cursor_shape = request->screen.cursor_underline
74700bd37d32Smrg	? CURSOR_UNDERLINE
74710bd37d32Smrg	: CURSOR_BLOCK;
7472d522f475Smrg#if OPT_BLINK_TEXT
7473d522f475Smrg    init_Ires(screen.blink_as_bold);
7474d522f475Smrg#endif
7475d522f475Smrg    init_Ires(screen.border);
7476d522f475Smrg    init_Bres(screen.jumpscroll);
7477956cc18dSsnj    init_Bres(screen.fastscroll);
7478d522f475Smrg    init_Bres(screen.old_fkeys);
7479d522f475Smrg    init_Bres(screen.delete_is_del);
748020d2c4d2Smrg    wnew->keyboard.type = TScreenOf(wnew)->old_fkeys
7481d522f475Smrg	? keyboardIsLegacy
7482d522f475Smrg	: keyboardIsDefault;
7483d522f475Smrg#ifdef ALLOWLOGGING
7484492d43a5Smrg    init_Bres(misc.logInhibit);
7485492d43a5Smrg    init_Bres(misc.log_on);
7486d522f475Smrg    init_Sres(screen.logfile);
7487d522f475Smrg#endif
7488d522f475Smrg    init_Bres(screen.bellIsUrgent);
7489d522f475Smrg    init_Bres(screen.bellOnReset);
7490d522f475Smrg    init_Bres(screen.marginbell);
7491d522f475Smrg    init_Bres(screen.multiscroll);
7492d522f475Smrg    init_Ires(screen.nmarginbell);
7493d522f475Smrg    init_Ires(screen.savelines);
7494d522f475Smrg    init_Ires(screen.scrollBarBorder);
7495d522f475Smrg    init_Ires(screen.scrolllines);
74960bd37d32Smrg    init_Bres(screen.alternateScroll);
7497d522f475Smrg    init_Bres(screen.scrollttyoutput);
7498d522f475Smrg    init_Bres(screen.scrollkey);
7499d522f475Smrg
75000bd37d32Smrg    init_Dres(screen.scale_height);
75010bd37d32Smrg    if (TScreenOf(wnew)->scale_height < 0.9)
75020bd37d32Smrg	TScreenOf(wnew)->scale_height = (float) 0.9;
75030bd37d32Smrg    if (TScreenOf(wnew)->scale_height > 1.5)
75040bd37d32Smrg	TScreenOf(wnew)->scale_height = (float) 1.5;
75050bd37d32Smrg
7506492d43a5Smrg    init_Bres(misc.autoWrap);
7507492d43a5Smrg    init_Bres(misc.login_shell);
7508492d43a5Smrg    init_Bres(misc.reverseWrap);
7509492d43a5Smrg    init_Bres(misc.scrollbar);
7510492d43a5Smrg    init_Sres(misc.geo_metry);
7511492d43a5Smrg    init_Sres(misc.T_geometry);
7512492d43a5Smrg
7513d522f475Smrg    init_Sres(screen.term_id);
751420d2c4d2Smrg    for (s = TScreenOf(request)->term_id; *s; s++) {
7515d522f475Smrg	if (!isalpha(CharOf(*s)))
7516d522f475Smrg	    break;
7517d522f475Smrg    }
751820d2c4d2Smrg    TScreenOf(wnew)->terminal_id = atoi(s);
751920d2c4d2Smrg    if (TScreenOf(wnew)->terminal_id < MIN_DECID)
752020d2c4d2Smrg	TScreenOf(wnew)->terminal_id = MIN_DECID;
752120d2c4d2Smrg    if (TScreenOf(wnew)->terminal_id > MAX_DECID)
752220d2c4d2Smrg	TScreenOf(wnew)->terminal_id = MAX_DECID;
7523d522f475Smrg    TRACE(("term_id '%s' -> terminal_id %d\n",
752420d2c4d2Smrg	   TScreenOf(wnew)->term_id,
752520d2c4d2Smrg	   TScreenOf(wnew)->terminal_id));
752620d2c4d2Smrg
752720d2c4d2Smrg    TScreenOf(wnew)->vtXX_level = (TScreenOf(wnew)->terminal_id / 100);
7528d522f475Smrg
752920d2c4d2Smrg    init_Ires(screen.title_modes);
7530d522f475Smrg    init_Bres(screen.visualbell);
75310bd37d32Smrg    init_Bres(screen.flash_line);
7532d522f475Smrg    init_Ires(screen.visualBellDelay);
7533d522f475Smrg    init_Bres(screen.poponbell);
7534d522f475Smrg    init_Ires(misc.limit_resize);
753520d2c4d2Smrg
7536d522f475Smrg#if OPT_NUM_LOCK
7537d522f475Smrg    init_Bres(misc.real_NumLock);
7538d522f475Smrg    init_Bres(misc.alwaysUseMods);
7539d522f475Smrg#endif
754020d2c4d2Smrg
7541492d43a5Smrg#if OPT_INPUT_METHOD
7542492d43a5Smrg    init_Bres(misc.open_im);
7543492d43a5Smrg    init_Ires(misc.retry_im);
7544492d43a5Smrg    init_Sres(misc.f_x);
7545492d43a5Smrg    init_Sres(misc.input_method);
7546492d43a5Smrg    init_Sres(misc.preedit_type);
7547492d43a5Smrg#endif
7548492d43a5Smrg
7549d522f475Smrg#if OPT_SHIFT_FONTS
7550d522f475Smrg    init_Bres(misc.shift_fonts);
7551d522f475Smrg#endif
7552d522f475Smrg#if OPT_SUNPC_KBD
7553d522f475Smrg    init_Ires(misc.ctrl_fkeys);
7554d522f475Smrg#endif
7555d522f475Smrg#if OPT_TEK4014
7556d522f475Smrg    TEK4014_SHOWN(wnew) = False;	/* not a resource... */
7557d522f475Smrg    init_Bres(misc.tekInhibit);
7558d522f475Smrg    init_Bres(misc.tekSmall);
7559d522f475Smrg    init_Bres(misc.TekEmu);
7560d522f475Smrg#endif
7561d522f475Smrg#if OPT_TCAP_QUERY
756220d2c4d2Smrg    TScreenOf(wnew)->tc_query_code = -1;
7563d522f475Smrg#endif
7564d522f475Smrg    wnew->misc.re_verse0 = request->misc.re_verse;
7565d522f475Smrg    init_Bres(misc.re_verse);
7566d522f475Smrg    init_Ires(screen.multiClickTime);
7567d522f475Smrg    init_Ires(screen.bellSuppressTime);
7568d522f475Smrg    init_Sres(screen.charClass);
7569d522f475Smrg
7570d522f475Smrg    init_Bres(screen.always_highlight);
7571d522f475Smrg    init_Bres(screen.brokenSelections);
7572d522f475Smrg    init_Bres(screen.cutNewline);
7573d522f475Smrg    init_Bres(screen.cutToBeginningOfLine);
7574d522f475Smrg    init_Bres(screen.highlight_selection);
7575492d43a5Smrg    init_Bres(screen.show_wrap_marks);
7576d522f475Smrg    init_Bres(screen.i18nSelections);
7577d522f475Smrg    init_Bres(screen.keepSelection);
7578d522f475Smrg    init_Bres(screen.selectToClipboard);
7579d522f475Smrg    init_Bres(screen.trim_selection);
7580d522f475Smrg
758120d2c4d2Smrg    TScreenOf(wnew)->pointer_cursor = TScreenOf(request)->pointer_cursor;
7582d522f475Smrg    init_Ires(screen.pointer_mode);
7583d522f475Smrg
7584d522f475Smrg    init_Sres(screen.answer_back);
7585d522f475Smrg
75860bd37d32Smrg    wnew->SPS.printer_checked = False;
7587e39b573cSmrg    init_Sres(SPS.printer_command);
7588e39b573cSmrg    init_Bres(SPS.printer_autoclose);
7589e39b573cSmrg    init_Bres(SPS.printer_extent);
7590e39b573cSmrg    init_Bres(SPS.printer_formfeed);
7591e39b573cSmrg    init_Bres(SPS.printer_newline);
7592e39b573cSmrg    init_Ires(SPS.printer_controlmode);
7593d522f475Smrg#if OPT_PRINT_COLORS
7594e39b573cSmrg    init_Ires(SPS.print_attributes);
7595d522f475Smrg#endif
7596d522f475Smrg
7597d522f475Smrg    init_Sres(screen.keyboard_dialect);
7598d522f475Smrg
7599d522f475Smrg    init_Bres(screen.input_eight_bits);
7600d522f475Smrg    init_Bres(screen.output_eight_bits);
7601d522f475Smrg    init_Bres(screen.control_eight_bits);
7602d522f475Smrg    init_Bres(screen.backarrow_key);
7603d522f475Smrg    init_Bres(screen.alt_is_not_meta);
7604d522f475Smrg    init_Bres(screen.alt_sends_esc);
7605d522f475Smrg    init_Bres(screen.meta_sends_esc);
7606d522f475Smrg
76070bd37d32Smrg    init_Bres(screen.allowPasteControls);
7608d522f475Smrg    init_Bres(screen.allowSendEvent0);
760920d2c4d2Smrg    init_Bres(screen.allowColorOp0);
76102eaa94a1Schristos    init_Bres(screen.allowFontOp0);
76112eaa94a1Schristos    init_Bres(screen.allowTcapOp0);
7612d522f475Smrg    init_Bres(screen.allowTitleOp0);
7613d522f475Smrg    init_Bres(screen.allowWindowOp0);
7614d522f475Smrg
761520d2c4d2Smrg#if OPT_SCROLL_LOCK
761620d2c4d2Smrg    init_Bres(screen.allowScrollLock0);
761720d2c4d2Smrg#endif
761820d2c4d2Smrg
761920d2c4d2Smrg    init_Sres(screen.disallowedColorOps);
762020d2c4d2Smrg
762120d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_color_ops,
762220d2c4d2Smrg			TScreenOf(wnew)->disallowedColorOps,
762320d2c4d2Smrg			tblColorOps,
762420d2c4d2Smrg			ecLAST);
762520d2c4d2Smrg
762620d2c4d2Smrg    init_Sres(screen.disallowedFontOps);
762720d2c4d2Smrg
762820d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_font_ops,
762920d2c4d2Smrg			TScreenOf(wnew)->disallowedFontOps,
763020d2c4d2Smrg			tblFontOps,
763120d2c4d2Smrg			efLAST);
763220d2c4d2Smrg
763320d2c4d2Smrg    init_Sres(screen.disallowedTcapOps);
763420d2c4d2Smrg
763520d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_tcap_ops,
763620d2c4d2Smrg			TScreenOf(wnew)->disallowedTcapOps,
763720d2c4d2Smrg			tblTcapOps,
763820d2c4d2Smrg			etLAST);
763920d2c4d2Smrg
764020d2c4d2Smrg    init_Sres(screen.disallowedWinOps);
764120d2c4d2Smrg
764220d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_win_ops,
764320d2c4d2Smrg			TScreenOf(wnew)->disallowedWinOps,
764420d2c4d2Smrg			tblWindowOps,
764520d2c4d2Smrg			ewLAST);
764620d2c4d2Smrg
7647956cc18dSsnj    init_Sres(screen.default_string);
7648956cc18dSsnj    init_Sres(screen.eightbit_select_types);
7649956cc18dSsnj#if OPT_WIDE_CHARS
7650956cc18dSsnj    init_Sres(screen.utf8_select_types);
7651956cc18dSsnj#endif
7652956cc18dSsnj
7653d522f475Smrg    /* make a copy so that editres cannot change the resource after startup */
765420d2c4d2Smrg    TScreenOf(wnew)->allowSendEvents = TScreenOf(wnew)->allowSendEvent0;
765520d2c4d2Smrg    TScreenOf(wnew)->allowColorOps = TScreenOf(wnew)->allowColorOp0;
765620d2c4d2Smrg    TScreenOf(wnew)->allowFontOps = TScreenOf(wnew)->allowFontOp0;
765720d2c4d2Smrg    TScreenOf(wnew)->allowTcapOps = TScreenOf(wnew)->allowTcapOp0;
765820d2c4d2Smrg    TScreenOf(wnew)->allowTitleOps = TScreenOf(wnew)->allowTitleOp0;
765920d2c4d2Smrg    TScreenOf(wnew)->allowWindowOps = TScreenOf(wnew)->allowWindowOp0;
766020d2c4d2Smrg
766120d2c4d2Smrg#if OPT_SCROLL_LOCK
766220d2c4d2Smrg    TScreenOf(wnew)->allowScrollLock = TScreenOf(wnew)->allowScrollLock0;
766320d2c4d2Smrg#endif
7664d522f475Smrg
7665d522f475Smrg    init_Bres(screen.quiet_grab);
7666d522f475Smrg
7667d522f475Smrg#ifndef NO_ACTIVE_ICON
7668492d43a5Smrg    init_Sres(screen.icon_fontname);
7669492d43a5Smrg    TScreenOf(wnew)->fnt_icon.fs = XLoadQueryFont(TScreenOf(wnew)->display,
7670492d43a5Smrg						  TScreenOf(wnew)->icon_fontname);
7671492d43a5Smrg    TRACE(("iconFont '%s' %sloaded successfully\n",
7672492d43a5Smrg	   TScreenOf(wnew)->icon_fontname,
7673492d43a5Smrg	   TScreenOf(wnew)->fnt_icon.fs ? "" : "NOT "));
76740bd37d32Smrg    init_Sres(misc.active_icon_s);
76750bd37d32Smrg    wnew->work.active_icon =
76760bd37d32Smrg	(Boolean) extendedBoolean(wnew->misc.active_icon_s,
76770bd37d32Smrg				  tblAIconOps, eiLAST);
7678d522f475Smrg    init_Ires(misc.icon_border_width);
7679d522f475Smrg    wnew->misc.icon_border_pixel = request->misc.icon_border_pixel;
7680d522f475Smrg#endif /* NO_ACTIVE_ICON */
7681492d43a5Smrg
7682492d43a5Smrg    init_Bres(misc.signalInhibit);
7683d522f475Smrg    init_Bres(misc.titeInhibit);
7684d522f475Smrg    init_Bres(misc.tiXtraScroll);
76850bd37d32Smrg    init_Bres(misc.cdXtraScroll);
7686d522f475Smrg    init_Bres(misc.dynamicColors);
7687d522f475Smrg    for (i = fontMenu_font1; i <= fontMenu_lastBuiltin; i++) {
76882eaa94a1Schristos	init_Sres2(screen.MenuFontName, i);
7689d522f475Smrg    }
7690956cc18dSsnj    init_Ires(misc.fontWarnings);
769120d2c4d2Smrg#define DefaultFontNames TScreenOf(wnew)->menu_font_names[fontMenu_default]
7692492d43a5Smrg    init_Sres(misc.default_font.f_n);
7693492d43a5Smrg    init_Sres(misc.default_font.f_b);
7694492d43a5Smrg    DefaultFontNames[fNorm] = x_strdup(wnew->misc.default_font.f_n);
7695492d43a5Smrg    DefaultFontNames[fBold] = x_strdup(wnew->misc.default_font.f_b);
7696956cc18dSsnj#if OPT_WIDE_CHARS
7697492d43a5Smrg    init_Sres(misc.default_font.f_w);
7698492d43a5Smrg    init_Sres(misc.default_font.f_wb);
7699492d43a5Smrg    DefaultFontNames[fWide] = x_strdup(wnew->misc.default_font.f_w);
7700492d43a5Smrg    DefaultFontNames[fWBold] = x_strdup(wnew->misc.default_font.f_wb);
7701956cc18dSsnj#endif
770220d2c4d2Smrg    TScreenOf(wnew)->MenuFontName(fontMenu_fontescape) = NULL;
770320d2c4d2Smrg    TScreenOf(wnew)->MenuFontName(fontMenu_fontsel) = NULL;
7704d522f475Smrg
770520d2c4d2Smrg    TScreenOf(wnew)->menu_font_number = fontMenu_default;
7706d522f475Smrg    init_Sres(screen.initial_font);
770720d2c4d2Smrg    if (TScreenOf(wnew)->initial_font != 0) {
770820d2c4d2Smrg	int result = xtermGetFont(TScreenOf(wnew)->initial_font);
7709d522f475Smrg	if (result >= 0)
771020d2c4d2Smrg	    TScreenOf(wnew)->menu_font_number = result;
7711d522f475Smrg    }
7712d522f475Smrg#if OPT_BROKEN_OSC
7713d522f475Smrg    init_Bres(screen.brokenLinuxOSC);
7714d522f475Smrg#endif
7715d522f475Smrg
7716d522f475Smrg#if OPT_BROKEN_ST
7717d522f475Smrg    init_Bres(screen.brokenStringTerm);
7718d522f475Smrg#endif
7719d522f475Smrg
7720d522f475Smrg#if OPT_C1_PRINT
7721d522f475Smrg    init_Bres(screen.c1_printable);
7722d522f475Smrg#endif
7723d522f475Smrg
7724d522f475Smrg#if OPT_CLIP_BOLD
7725d522f475Smrg    init_Bres(screen.use_clipping);
7726d522f475Smrg#endif
7727d522f475Smrg
7728d522f475Smrg#if OPT_DEC_CHRSET
7729d522f475Smrg    init_Bres(screen.font_doublesize);
7730d522f475Smrg    init_Ires(screen.cache_doublesize);
773120d2c4d2Smrg    if (TScreenOf(wnew)->cache_doublesize > NUM_CHRSET)
773220d2c4d2Smrg	TScreenOf(wnew)->cache_doublesize = NUM_CHRSET;
773320d2c4d2Smrg    if (TScreenOf(wnew)->cache_doublesize == 0)
773420d2c4d2Smrg	TScreenOf(wnew)->font_doublesize = False;
7735d522f475Smrg    TRACE(("Doublesize%s enabled, up to %d fonts\n",
773620d2c4d2Smrg	   TScreenOf(wnew)->font_doublesize ? "" : " not",
773720d2c4d2Smrg	   TScreenOf(wnew)->cache_doublesize));
7738d522f475Smrg#endif
7739d522f475Smrg
7740d522f475Smrg#if OPT_ISO_COLORS
7741d522f475Smrg    init_Ires(screen.veryBoldColors);
7742d522f475Smrg    init_Bres(screen.boldColors);
7743d522f475Smrg    init_Bres(screen.colorAttrMode);
7744d522f475Smrg    init_Bres(screen.colorBDMode);
7745d522f475Smrg    init_Bres(screen.colorBLMode);
7746d522f475Smrg    init_Bres(screen.colorMode);
7747d522f475Smrg    init_Bres(screen.colorULMode);
7748d522f475Smrg    init_Bres(screen.italicULMode);
7749d522f475Smrg    init_Bres(screen.colorRVMode);
7750d522f475Smrg
775120d2c4d2Smrg#if OPT_COLOR_RES2
775220d2c4d2Smrg    TRACE(("...will fake resources for color%d to color%d\n",
775320d2c4d2Smrg	   MIN_ANSI_COLORS,
775420d2c4d2Smrg	   NUM_ANSI_COLORS - 1));
775520d2c4d2Smrg#endif
7756d522f475Smrg    for (i = 0, color_ok = False; i < MAXCOLORS; i++) {
7757d522f475Smrg
775820d2c4d2Smrg#if OPT_COLOR_RES2
7759d522f475Smrg	/*
7760d522f475Smrg	 * Xt has a hardcoded limit on the maximum number of resources that can
7761d522f475Smrg	 * be used in a widget.  If we configure both luit (which implies
7762d522f475Smrg	 * wide-characters) and 256-colors, it goes over that limit.  Most
7763d522f475Smrg	 * people would not need a resource-file with 256-colors; the default
7764d522f475Smrg	 * values in our table are sufficient.  In that case, fake the resource
7765d522f475Smrg	 * setting by copying the default value from the table.  The #define's
7766d522f475Smrg	 * can be overridden to make these true resources.
7767d522f475Smrg	 */
7768d522f475Smrg	if (i >= MIN_ANSI_COLORS && i < NUM_ANSI_COLORS) {
77696879286fSmrg	    TScreenOf(wnew)->Acolors[i].resource =
77706879286fSmrg		x_strtrim(fake_resources[i - MIN_ANSI_COLORS].default_addr);
777120d2c4d2Smrg	    if (TScreenOf(wnew)->Acolors[i].resource == 0)
777220d2c4d2Smrg		TScreenOf(wnew)->Acolors[i].resource = XtDefaultForeground;
7773d522f475Smrg	} else
7774d522f475Smrg#endif /* OPT_COLOR_RES2 */
77756879286fSmrg	{
777620d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i] = TScreenOf(request)->Acolors[i];
77776879286fSmrg	    TScreenOf(wnew)->Acolors[i].resource =
77786879286fSmrg		x_strtrim(TScreenOf(wnew)->Acolors[i].resource);
77796879286fSmrg	}
7780d522f475Smrg
7781d522f475Smrg#if OPT_COLOR_RES
778220d2c4d2Smrg	TRACE(("Acolors[%d] = %s\n", i, TScreenOf(wnew)->Acolors[i].resource));
778320d2c4d2Smrg	TScreenOf(wnew)->Acolors[i].mode = False;
7784d522f475Smrg	if (DftFg(Acolors[i])) {
778520d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].value = T_COLOR(TScreenOf(wnew), TEXT_FG);
778620d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].mode = True;
7787d522f475Smrg	} else if (DftBg(Acolors[i])) {
778820d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].value = T_COLOR(TScreenOf(wnew), TEXT_BG);
778920d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].mode = True;
7790d522f475Smrg	} else {
7791d522f475Smrg	    color_ok = True;
7792d522f475Smrg	}
7793d522f475Smrg#else
779420d2c4d2Smrg	TRACE(("Acolors[%d] = %#lx\n", i, TScreenOf(request)->Acolors[i]));
779520d2c4d2Smrg	if (TScreenOf(wnew)->Acolors[i] != wnew->dft_foreground &&
779620d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i] != T_COLOR(TScreenOf(wnew), TEXT_FG) &&
779720d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i] != T_COLOR(TScreenOf(wnew), TEXT_BG))
7798d522f475Smrg	    color_ok = True;
7799d522f475Smrg#endif
7800d522f475Smrg    }
7801d522f475Smrg
7802d522f475Smrg    /*
7803d522f475Smrg     * Check if we're trying to use color in a monochrome screen.  Disable
7804d522f475Smrg     * color in that case, since that would make ANSI colors unusable.  A 4-bit
7805d522f475Smrg     * or 8-bit display is usable, so we do not have to check for anything more
7806d522f475Smrg     * specific.
7807d522f475Smrg     */
7808d522f475Smrg    if (color_ok) {
78090bd37d32Smrg	if (getVisualDepth(wnew) <= 1) {
7810d522f475Smrg	    TRACE(("disabling color since screen is monochrome\n"));
7811d522f475Smrg	    color_ok = False;
7812d522f475Smrg	}
7813d522f475Smrg    }
7814d522f475Smrg
7815d522f475Smrg    /* If none of the colors are anything other than the foreground or
7816d522f475Smrg     * background, we'll assume this isn't color, no matter what the colorMode
7817d522f475Smrg     * resource says.  (There doesn't seem to be any good way to determine if
7818d522f475Smrg     * the resource lookup failed versus the user having misconfigured this).
7819d522f475Smrg     */
7820d522f475Smrg    if (!color_ok) {
782120d2c4d2Smrg	TScreenOf(wnew)->colorMode = False;
7822d522f475Smrg	TRACE(("All colors are foreground or background: disable colorMode\n"));
7823d522f475Smrg    }
7824d522f475Smrg    wnew->sgr_foreground = -1;
7825d522f475Smrg    wnew->sgr_background = -1;
7826d522f475Smrg    wnew->sgr_extended = False;
7827d522f475Smrg#endif /* OPT_ISO_COLORS */
7828d522f475Smrg
7829d522f475Smrg    /*
7830d522f475Smrg     * Decode the resources that control the behavior on multiple mouse clicks.
7831d522f475Smrg     * A single click is always bound to normal character selection, but the
7832d522f475Smrg     * other flavors can be changed.
7833d522f475Smrg     */
7834d522f475Smrg    for (i = 0; i < NSELECTUNITS; ++i) {
7835d522f475Smrg	int ck = (i + 1);
783620d2c4d2Smrg	TScreenOf(wnew)->maxClicks = ck;
7837d522f475Smrg	if (i == Select_CHAR)
783820d2c4d2Smrg	    TScreenOf(wnew)->selectMap[i] = Select_CHAR;
783920d2c4d2Smrg	else if (TScreenOf(request)->onClick[i] != 0)
7840d522f475Smrg	    ParseOnClicks(wnew, request, (unsigned) i);
7841d522f475Smrg	else if (i <= Select_LINE)
784220d2c4d2Smrg	    TScreenOf(wnew)->selectMap[i] = (SelectUnit) i;
7843d522f475Smrg	else
7844d522f475Smrg	    break;
7845d522f475Smrg	TRACE(("on%dClicks %s=%d\n", ck,
784620d2c4d2Smrg	       NonNull(TScreenOf(request)->onClick[i]),
784720d2c4d2Smrg	       TScreenOf(wnew)->selectMap[i]));
784820d2c4d2Smrg	if (TScreenOf(wnew)->selectMap[i] == NSELECTUNITS)
7849d522f475Smrg	    break;
7850d522f475Smrg    }
785120d2c4d2Smrg    TRACE(("maxClicks %d\n", TScreenOf(wnew)->maxClicks));
7852d522f475Smrg
7853d522f475Smrg    init_Tres(MOUSE_FG);
7854d522f475Smrg    init_Tres(MOUSE_BG);
7855d522f475Smrg    init_Tres(TEXT_CURSOR);
7856d522f475Smrg#if OPT_HIGHLIGHT_COLOR
7857d522f475Smrg    init_Tres(HIGHLIGHT_BG);
7858d522f475Smrg    init_Tres(HIGHLIGHT_FG);
7859d522f475Smrg    init_Bres(screen.hilite_reverse);
7860d522f475Smrg    init_Bres(screen.hilite_color);
786120d2c4d2Smrg    if (TScreenOf(wnew)->hilite_color == Maybe) {
786220d2c4d2Smrg	TScreenOf(wnew)->hilite_color = False;
7863d522f475Smrg#if OPT_COLOR_RES
7864d522f475Smrg	/*
7865d522f475Smrg	 * If the highlight text/background are both set, and if they are
7866d522f475Smrg	 * not equal to either the text/background or background/text, then
7867d522f475Smrg	 * set the highlightColorMode automatically.
7868d522f475Smrg	 */
7869d522f475Smrg	if (!DftFg(Tcolors[HIGHLIGHT_BG])
7870d522f475Smrg	    && !DftBg(Tcolors[HIGHLIGHT_FG])
7871d522f475Smrg	    && !TxtFg(Tcolors[HIGHLIGHT_BG])
7872d522f475Smrg	    && !TxtBg(Tcolors[HIGHLIGHT_FG])
7873d522f475Smrg	    && !TxtBg(Tcolors[HIGHLIGHT_BG])
7874d522f475Smrg	    && !TxtFg(Tcolors[HIGHLIGHT_FG])) {
7875d522f475Smrg	    TRACE(("...setting hilite_color automatically\n"));
787620d2c4d2Smrg	    TScreenOf(wnew)->hilite_color = True;
7877d522f475Smrg	}
7878d522f475Smrg#endif
7879d522f475Smrg    }
7880d522f475Smrg#endif
7881d522f475Smrg
7882d522f475Smrg#if OPT_TEK4014
7883d522f475Smrg    /*
7884d522f475Smrg     * The Tek4014 window has no separate resources for foreground, background
7885d522f475Smrg     * and cursor color.  Since xterm always creates the vt100 widget first, we
7886d522f475Smrg     * can set the Tektronix colors here.  That lets us use escape sequences to
7887d522f475Smrg     * set its dynamic colors and get consistent behavior whether or not the
7888d522f475Smrg     * window is displayed.
7889d522f475Smrg     */
789020d2c4d2Smrg    TScreenOf(wnew)->Tcolors[TEK_BG] = TScreenOf(wnew)->Tcolors[TEXT_BG];
789120d2c4d2Smrg    TScreenOf(wnew)->Tcolors[TEK_FG] = TScreenOf(wnew)->Tcolors[TEXT_FG];
789220d2c4d2Smrg    TScreenOf(wnew)->Tcolors[TEK_CURSOR] = TScreenOf(wnew)->Tcolors[TEXT_CURSOR];
7893d522f475Smrg#endif
7894d522f475Smrg
7895492d43a5Smrg#ifdef SCROLLBAR_RIGHT
7896492d43a5Smrg    init_Bres(misc.useRight);
7897492d43a5Smrg#endif
7898492d43a5Smrg
7899d522f475Smrg#if OPT_RENDERFONT
7900d522f475Smrg    for (i = 0; i <= fontMenu_lastBuiltin; ++i) {
79012eaa94a1Schristos	init_Dres2(misc.face_size, i);
7902d522f475Smrg    }
7903d522f475Smrg    init_Sres(misc.face_name);
7904d522f475Smrg    init_Sres(misc.face_wide_name);
7905e0a2b6dfSmrg    trimSizeFromFace(wnew->misc.face_wide_name, (float *) 0);
7906e0a2b6dfSmrg    trimSizeFromFace(wnew->misc.face_name, &(wnew->misc.face_size[0]));
790720d2c4d2Smrg    init_Sres(misc.render_font_s);
79080bd37d32Smrg    wnew->work.render_font =
790920d2c4d2Smrg	(Boolean) extendedBoolean(wnew->misc.render_font_s,
791020d2c4d2Smrg				  tblRenderFont, erLast);
79110bd37d32Smrg    if (wnew->work.render_font == erDefault) {
791220d2c4d2Smrg	if (IsEmpty(wnew->misc.face_name)) {
79130bd37d32Smrg	    free(wnew->misc.face_name);
791420d2c4d2Smrg	    wnew->misc.face_name = x_strdup(DEFFACENAME_AUTO);
791520d2c4d2Smrg	    TRACE(("will allow runtime switch to render_font using \"%s\"\n",
791620d2c4d2Smrg		   wnew->misc.face_name));
791720d2c4d2Smrg	} else {
79180bd37d32Smrg	    wnew->work.render_font = erTrue;
791920d2c4d2Smrg	    TRACE(("initially using TrueType font\n"));
792020d2c4d2Smrg	}
792120d2c4d2Smrg    }
7922d522f475Smrg    /* minor tweak to make debug traces consistent: */
79230bd37d32Smrg    if (wnew->work.render_font) {
792420d2c4d2Smrg	if (IsEmpty(wnew->misc.face_name)) {
79250bd37d32Smrg	    wnew->work.render_font = False;
7926d522f475Smrg	    TRACE(("reset render_font since there is no face_name\n"));
7927d522f475Smrg	}
7928d522f475Smrg    }
7929d522f475Smrg#endif
7930d522f475Smrg
793120d2c4d2Smrg#if OPT_WIDE_CHARS
7932e39b573cSmrg    /* setup data for next call */
7933e39b573cSmrg    request->screen.utf8_mode =
7934e39b573cSmrg	extendedBoolean(request->screen.utf8_mode_s, tblUtf8Mode, uLast);
7935e39b573cSmrg    request->screen.utf8_fonts =
7936e39b573cSmrg	extendedBoolean(request->screen.utf8_fonts_s, tblUtf8Mode, uLast);
7937e39b573cSmrg
793820d2c4d2Smrg    VTInitialize_locale(request);
79390bd37d32Smrg    init_Bres(screen.normalized_c);
794020d2c4d2Smrg    init_Bres(screen.utf8_latin1);
794120d2c4d2Smrg    init_Bres(screen.utf8_title);
794220d2c4d2Smrg
794320d2c4d2Smrg#if OPT_LUIT_PROG
794420d2c4d2Smrg    init_Bres(misc.callfilter);
794520d2c4d2Smrg    init_Bres(misc.use_encoding);
794620d2c4d2Smrg    init_Sres(misc.locale_str);
794720d2c4d2Smrg    init_Sres(misc.localefilter);
794820d2c4d2Smrg#endif
794920d2c4d2Smrg
7950d522f475Smrg    init_Ires(screen.utf8_inparse);
7951d522f475Smrg    init_Ires(screen.utf8_mode);
7952e39b573cSmrg    init_Ires(screen.utf8_fonts);
7953d522f475Smrg    init_Ires(screen.max_combining);
7954d522f475Smrg
795520d2c4d2Smrg    if (TScreenOf(wnew)->max_combining < 0) {
795620d2c4d2Smrg	TScreenOf(wnew)->max_combining = 0;
7957d522f475Smrg    }
795820d2c4d2Smrg    if (TScreenOf(wnew)->max_combining > 5) {
795920d2c4d2Smrg	TScreenOf(wnew)->max_combining = 5;
7960d522f475Smrg    }
7961d522f475Smrg
7962d522f475Smrg    init_Bres(screen.vt100_graphics);
7963d522f475Smrg    init_Bres(screen.wide_chars);
7964d522f475Smrg    init_Bres(misc.mk_width);
7965d522f475Smrg    init_Bres(misc.cjk_width);
7966d522f475Smrg
7967d522f475Smrg    init_Ires(misc.mk_samplesize);
7968d522f475Smrg    init_Ires(misc.mk_samplepass);
7969d522f475Smrg
7970d522f475Smrg    if (wnew->misc.mk_samplesize > 0xffff)
7971d522f475Smrg	wnew->misc.mk_samplesize = 0xffff;
7972d522f475Smrg    if (wnew->misc.mk_samplesize < 0)
7973d522f475Smrg	wnew->misc.mk_samplesize = 0;
7974d522f475Smrg
7975d522f475Smrg    if (wnew->misc.mk_samplepass > wnew->misc.mk_samplesize)
7976d522f475Smrg	wnew->misc.mk_samplepass = wnew->misc.mk_samplesize;
7977d522f475Smrg    if (wnew->misc.mk_samplepass < 0)
7978d522f475Smrg	wnew->misc.mk_samplepass = 0;
7979d522f475Smrg
798020d2c4d2Smrg    if (TScreenOf(request)->utf8_mode) {
7981d522f475Smrg	TRACE(("setting wide_chars on\n"));
798220d2c4d2Smrg	TScreenOf(wnew)->wide_chars = True;
7983d522f475Smrg    } else {
7984d522f475Smrg	TRACE(("setting utf8_mode to 0\n"));
798520d2c4d2Smrg	TScreenOf(wnew)->utf8_mode = uFalse;
7986d522f475Smrg    }
798720d2c4d2Smrg    TRACE(("initialized UTF-8 mode to %d\n", TScreenOf(wnew)->utf8_mode));
7988d522f475Smrg
7989d522f475Smrg#if OPT_MINI_LUIT
799020d2c4d2Smrg    if (TScreenOf(request)->latin9_mode) {
799120d2c4d2Smrg	TScreenOf(wnew)->latin9_mode = True;
7992d522f475Smrg    }
799320d2c4d2Smrg    if (TScreenOf(request)->unicode_font) {
799420d2c4d2Smrg	TScreenOf(wnew)->unicode_font = True;
7995d522f475Smrg    }
799620d2c4d2Smrg    TRACE(("initialized Latin9 mode to %d\n", TScreenOf(wnew)->latin9_mode));
799720d2c4d2Smrg    TRACE(("initialized unicode_font to %d\n", TScreenOf(wnew)->unicode_font));
7998d522f475Smrg#endif
7999d522f475Smrg
800020d2c4d2Smrg    decode_wcwidth(wnew);
8001e39b573cSmrg    xtermSaveVTFonts(wnew);
8002d522f475Smrg#endif /* OPT_WIDE_CHARS */
8003d522f475Smrg
80040bd37d32Smrg    init_Sres(screen.eight_bit_meta_s);
80050bd37d32Smrg    wnew->screen.eight_bit_meta =
80060bd37d32Smrg	extendedBoolean(request->screen.eight_bit_meta_s, tbl8BitMeta, uLast);
80070bd37d32Smrg    if (wnew->screen.eight_bit_meta == ebLocale) {
80080bd37d32Smrg#if OPT_WIDE_CHARS
80090bd37d32Smrg	if (xtermEnvUTF8()) {
80100bd37d32Smrg	    wnew->screen.eight_bit_meta = ebFalse;
80110bd37d32Smrg	    TRACE(("...eightBitMeta is false due to locale\n"));
80120bd37d32Smrg	} else
80130bd37d32Smrg#endif /* OPT_WIDE_CHARS */
80140bd37d32Smrg	{
80150bd37d32Smrg	    wnew->screen.eight_bit_meta = ebTrue;
80160bd37d32Smrg	    TRACE(("...eightBitMeta is true due to locale\n"));
80170bd37d32Smrg	}
80180bd37d32Smrg    }
80190bd37d32Smrg
8020d522f475Smrg    init_Bres(screen.always_bold_mode);
8021d522f475Smrg    init_Bres(screen.bold_mode);
8022d522f475Smrg    init_Bres(screen.underline);
8023d522f475Smrg
8024d522f475Smrg    wnew->cur_foreground = 0;
8025d522f475Smrg    wnew->cur_background = 0;
8026d522f475Smrg
8027d522f475Smrg    wnew->keyboard.flags = MODE_SRM;
802820d2c4d2Smrg    if (TScreenOf(wnew)->backarrow_key)
8029d522f475Smrg	wnew->keyboard.flags |= MODE_DECBKM;
8030d522f475Smrg    TRACE(("initialized DECBKM %s\n",
8031d522f475Smrg	   BtoS(wnew->keyboard.flags & MODE_DECBKM)));
8032d522f475Smrg
8033e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
8034e0a2b6dfSmrg    init_Bres(screen.sixel_scrolling);
8035e0a2b6dfSmrg    if (TScreenOf(wnew)->sixel_scrolling)	/* FIXME: should this be off unconditionally here? */
8036e0a2b6dfSmrg	wnew->keyboard.flags |= MODE_DECSDM;
8037e0a2b6dfSmrg    TRACE(("initialized DECSDM %s (resource default is %d)\n",
8038e0a2b6dfSmrg	   BtoS(wnew->keyboard.flags & MODE_DECSDM),
8039e0a2b6dfSmrg	   TScreenOf(wnew)->sixel_scrolling));
8040e0a2b6dfSmrg
8041e0a2b6dfSmrg    init_Bres(screen.privatecolorregisters);	/* FIXME: should this be off unconditionally here? */
8042e0a2b6dfSmrg    TRACE(("initialized PRIVATE_COLOR_REGISTERS to resource default %s\n",
8043e0a2b6dfSmrg	   BtoS(TScreenOf(wnew)->privatecolorregisters)));
8044e0a2b6dfSmrg#endif
8045e0a2b6dfSmrg
8046d522f475Smrg    /* look for focus related events on the shell, because we need
8047d522f475Smrg     * to care about the shell's border being part of our focus.
8048d522f475Smrg     */
804920d2c4d2Smrg    TRACE(("adding event handlers for my_parent %p\n", (void *) my_parent));
8050d522f475Smrg    XtAddEventHandler(my_parent, EnterWindowMask, False,
8051d522f475Smrg		      HandleEnterWindow, (Opaque) NULL);
8052d522f475Smrg    XtAddEventHandler(my_parent, LeaveWindowMask, False,
8053d522f475Smrg		      HandleLeaveWindow, (Opaque) NULL);
8054d522f475Smrg    XtAddEventHandler(my_parent, FocusChangeMask, False,
8055d522f475Smrg		      HandleFocusChange, (Opaque) NULL);
8056d522f475Smrg    XtAddEventHandler((Widget) wnew, 0L, True,
8057d522f475Smrg		      VTNonMaskableEvent, (Opaque) NULL);
8058d522f475Smrg    XtAddEventHandler((Widget) wnew, PropertyChangeMask, False,
8059d522f475Smrg		      HandleBellPropertyChange, (Opaque) NULL);
8060d522f475Smrg
8061d522f475Smrg#if HANDLE_STRUCT_NOTIFY
8062d522f475Smrg#if OPT_TOOLBAR
8063d522f475Smrg    wnew->VT100_TB_INFO(menu_bar) = request->VT100_TB_INFO(menu_bar);
8064d522f475Smrg    init_Ires(VT100_TB_INFO(menu_height));
8065d522f475Smrg#else
8066d522f475Smrg    /* Flag icon name with "***"  on window output when iconified.
8067d522f475Smrg     * Put in a handler that will tell us when we get Map/Unmap events.
8068d522f475Smrg     */
8069d522f475Smrg    if (resource.zIconBeep)
8070d522f475Smrg#endif
8071d522f475Smrg	XtAddEventHandler(my_parent, StructureNotifyMask, False,
8072d522f475Smrg			  HandleStructNotify, (Opaque) 0);
8073d522f475Smrg#endif /* HANDLE_STRUCT_NOTIFY */
8074d522f475Smrg
807520d2c4d2Smrg    TScreenOf(wnew)->bellInProgress = False;
8076d522f475Smrg
807720d2c4d2Smrg    set_character_class(TScreenOf(wnew)->charClass);
8078d522f475Smrg
8079d522f475Smrg    /* create it, but don't realize it */
8080956cc18dSsnj    ScrollBarOn(wnew, True);
8081d522f475Smrg
8082d522f475Smrg    /* make sure that the resize gravity acceptable */
8083956cc18dSsnj    if (!GravityIsNorthWest(wnew) &&
8084956cc18dSsnj	!GravityIsSouthWest(wnew)) {
8085d522f475Smrg	char value[80];
808620d2c4d2Smrg	String temp[2];
8087d522f475Smrg	Cardinal nparams = 1;
8088d522f475Smrg
808920d2c4d2Smrg	sprintf(value, "%d", wnew->misc.resizeGravity);
809020d2c4d2Smrg	temp[0] = value;
8091d522f475Smrg	temp[1] = 0;
8092d522f475Smrg	XtAppWarningMsg(app_con, "rangeError", "resizeGravity", "XTermError",
8093d522f475Smrg			"unsupported resizeGravity resource value (%s)",
8094d522f475Smrg			temp, &nparams);
8095d522f475Smrg	wnew->misc.resizeGravity = SouthWestGravity;
8096d522f475Smrg    }
8097d522f475Smrg#ifndef NO_ACTIVE_ICON
809820d2c4d2Smrg    TScreenOf(wnew)->whichVwin = &TScreenOf(wnew)->fullVwin;
8099d522f475Smrg#endif /* NO_ACTIVE_ICON */
8100d522f475Smrg
810120d2c4d2Smrg    if (TScreenOf(wnew)->savelines < 0)
810220d2c4d2Smrg	TScreenOf(wnew)->savelines = 0;
8103d522f475Smrg
8104d522f475Smrg    init_Bres(screen.awaitInput);
8105d522f475Smrg
8106d522f475Smrg    wnew->flags = 0;
810720d2c4d2Smrg    if (!TScreenOf(wnew)->jumpscroll)
8108d522f475Smrg	wnew->flags |= SMOOTHSCROLL;
8109d522f475Smrg    if (wnew->misc.reverseWrap)
8110d522f475Smrg	wnew->flags |= REVERSEWRAP;
8111d522f475Smrg    if (wnew->misc.autoWrap)
8112d522f475Smrg	wnew->flags |= WRAPAROUND;
8113d522f475Smrg    if (wnew->misc.re_verse != wnew->misc.re_verse0)
8114d522f475Smrg	wnew->flags |= REVERSE_VIDEO;
811520d2c4d2Smrg    if (TScreenOf(wnew)->c132)
8116d522f475Smrg	wnew->flags |= IN132COLUMNS;
8117d522f475Smrg
8118d522f475Smrg    wnew->initflags = wnew->flags;
8119d522f475Smrg
8120d522f475Smrg#if OPT_MOD_FKEYS
81210bd37d32Smrg    init_Ires(keyboard.modify_1st.allow_keys);
8122d522f475Smrg    init_Ires(keyboard.modify_1st.cursor_keys);
8123d522f475Smrg    init_Ires(keyboard.modify_1st.function_keys);
8124d522f475Smrg    init_Ires(keyboard.modify_1st.keypad_keys);
8125d522f475Smrg    init_Ires(keyboard.modify_1st.other_keys);
8126d522f475Smrg    init_Ires(keyboard.modify_1st.string_keys);
8127d522f475Smrg    init_Ires(keyboard.format_keys);
8128d522f475Smrg    wnew->keyboard.modify_now = wnew->keyboard.modify_1st;
8129d522f475Smrg#endif
8130d522f475Smrg
8131d522f475Smrg    init_Ires(misc.appcursorDefault);
8132d522f475Smrg    if (wnew->misc.appcursorDefault)
8133d522f475Smrg	wnew->keyboard.flags |= MODE_DECCKM;
8134d522f475Smrg
8135d522f475Smrg    init_Ires(misc.appkeypadDefault);
8136d522f475Smrg    if (wnew->misc.appkeypadDefault)
8137d522f475Smrg	wnew->keyboard.flags |= MODE_DECKPAM;
8138d522f475Smrg
8139956cc18dSsnj    initLineData(wnew);
8140d522f475Smrg    return;
8141d522f475Smrg}
8142d522f475Smrg
8143d522f475Smrgvoid
8144d522f475SmrgreleaseCursorGCs(XtermWidget xw)
8145d522f475Smrg{
814620d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
8147d522f475Smrg    VTwin *win = WhichVWin(screen);
8148d522f475Smrg    int n;
8149d522f475Smrg
8150d522f475Smrg    for_each_curs_gc(n) {
8151d522f475Smrg	freeCgs(xw, win, (CgsEnum) n);
8152d522f475Smrg    }
8153d522f475Smrg}
8154d522f475Smrg
8155d522f475Smrgvoid
8156d522f475SmrgreleaseWindowGCs(XtermWidget xw, VTwin * win)
8157d522f475Smrg{
8158d522f475Smrg    int n;
8159d522f475Smrg
8160d522f475Smrg    for_each_text_gc(n) {
8161d522f475Smrg	freeCgs(xw, win, (CgsEnum) n);
8162d522f475Smrg    }
8163d522f475Smrg}
8164d522f475Smrg
8165d522f475Smrg#define TRACE_FREE_LEAK(name) \
8166d522f475Smrg	if (name) { \
81670bd37d32Smrg	    TRACE(("freed " #name ": %p\n", (const void *) name)); \
816820d2c4d2Smrg	    free((void *) name); \
8169d522f475Smrg	    name = 0; \
8170d522f475Smrg	}
8171d522f475Smrg
8172d522f475Smrg#define FREE_LEAK(name) \
8173d522f475Smrg	if (name) { \
817420d2c4d2Smrg	    free((void *) name); \
8175d522f475Smrg	    name = 0; \
8176d522f475Smrg	}
8177d522f475Smrg
81780bd37d32Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
8179956cc18dSsnjstatic void
81800bd37d32SmrgcleanupInputMethod(XtermWidget xw)
8181956cc18dSsnj{
81820bd37d32Smrg    TInput *input = lookupTInput(xw, (Widget) xw);
81830bd37d32Smrg
81840bd37d32Smrg    if (input && input->xim) {
81850bd37d32Smrg	XCloseIM(input->xim);
81860bd37d32Smrg	input->xim = 0;
8187956cc18dSsnj	TRACE(("freed screen->xim\n"));
8188956cc18dSsnj    }
8189956cc18dSsnj}
8190956cc18dSsnj#endif
8191956cc18dSsnj
8192d522f475Smrgstatic void
8193d522f475SmrgVTDestroy(Widget w GCC_UNUSED)
8194d522f475Smrg{
8195d522f475Smrg#ifdef NO_LEAKS
8196d522f475Smrg    XtermWidget xw = (XtermWidget) w;
819720d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
8198d522f475Smrg    Cardinal n;
8199d522f475Smrg
8200d522f475Smrg    StopBlinking(screen);
8201d522f475Smrg
82022eaa94a1Schristos    if (screen->scrollWidget) {
82032eaa94a1Schristos	XtUninstallTranslations(screen->scrollWidget);
8204d522f475Smrg	XtDestroyWidget(screen->scrollWidget);
82052eaa94a1Schristos    }
8206956cc18dSsnj#if OPT_FIFO_LINES
82070bd37d32Smrg    while (screen->saved_fifo > 0) {
82080bd37d32Smrg	deleteScrollback(screen);
8209956cc18dSsnj    }
8210956cc18dSsnj#endif
821120d2c4d2Smrg    while (screen->save_title != 0) {
821220d2c4d2Smrg	SaveTitle *last = screen->save_title;
821320d2c4d2Smrg	screen->save_title = last->next;
821420d2c4d2Smrg	free(last->iconName);
821520d2c4d2Smrg	free(last->windowName);
821620d2c4d2Smrg	free(last);
821720d2c4d2Smrg    }
82180bd37d32Smrg#if OPT_ISO_COLORS
82190bd37d32Smrg    TRACE_FREE_LEAK(screen->cmap_data);
82200bd37d32Smrg    for (n = 0; n < MAXCOLORS; n++) {
82210bd37d32Smrg	TRACE_FREE_LEAK(screen->Acolors[n].resource);
82220bd37d32Smrg    }
82230bd37d32Smrg#endif
82240bd37d32Smrg#if OPT_COLOR_RES
82250bd37d32Smrg    for (n = 0; n < NCOLORS; n++) {
82260bd37d32Smrg	switch (n) {
82270bd37d32Smrg#if OPT_TEK4014
82280bd37d32Smrg	case TEK_BG:
82290bd37d32Smrg	case TEK_FG:
82300bd37d32Smrg	case TEK_CURSOR:
82310bd37d32Smrg	    break;
82320bd37d32Smrg#endif
82330bd37d32Smrg	default:
82340bd37d32Smrg	    TRACE_FREE_LEAK(screen->Tcolors[n].resource);
82350bd37d32Smrg	    break;
82360bd37d32Smrg	}
82370bd37d32Smrg    }
82380bd37d32Smrg#endif
8239d522f475Smrg    TRACE_FREE_LEAK(screen->save_ptr);
8240956cc18dSsnj    TRACE_FREE_LEAK(screen->saveBuf_data);
8241956cc18dSsnj    TRACE_FREE_LEAK(screen->saveBuf_index);
8242956cc18dSsnj    for (n = 0; n < 2; ++n) {
8243956cc18dSsnj	TRACE_FREE_LEAK(screen->editBuf_data[n]);
8244956cc18dSsnj	TRACE_FREE_LEAK(screen->editBuf_index[n]);
8245956cc18dSsnj    }
8246d522f475Smrg    TRACE_FREE_LEAK(screen->keyboard_dialect);
8247d522f475Smrg    TRACE_FREE_LEAK(screen->term_id);
8248d522f475Smrg#if OPT_WIDE_CHARS
8249d522f475Smrg#if OPT_LUIT_PROG
8250d522f475Smrg    TRACE_FREE_LEAK(xw->misc.locale_str);
8251d522f475Smrg    TRACE_FREE_LEAK(xw->misc.localefilter);
8252d522f475Smrg#endif
8253d522f475Smrg#endif
82540bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.T_geometry);
82550bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.geo_metry);
82560bd37d32Smrg    TRACE_FREE_LEAK(xw->screen.term_id);
8257d522f475Smrg#if OPT_INPUT_METHOD
82580bd37d32Smrg    cleanupInputMethod(xw);
82590bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.f_x);
82600bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.input_method);
82610bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.preedit_type);
8262d522f475Smrg#endif
8263d522f475Smrg    releaseCursorGCs(xw);
8264d522f475Smrg    releaseWindowGCs(xw, &(screen->fullVwin));
8265d522f475Smrg#ifndef NO_ACTIVE_ICON
8266d522f475Smrg    releaseWindowGCs(xw, &(screen->iconVwin));
8267d522f475Smrg#endif
82682eaa94a1Schristos    XtUninstallTranslations((Widget) xw);
82692eaa94a1Schristos#if OPT_TOOLBAR
82702eaa94a1Schristos    XtUninstallTranslations((Widget) XtParent(xw));
82712eaa94a1Schristos#endif
82722eaa94a1Schristos    XtUninstallTranslations((Widget) SHELL_OF(xw));
8273d522f475Smrg
8274d522f475Smrg    if (screen->hidden_cursor)
8275d522f475Smrg	XFreeCursor(screen->display, screen->hidden_cursor);
8276d522f475Smrg
8277d522f475Smrg    xtermCloseFonts(xw, screen->fnts);
8278d522f475Smrg    noleaks_cachedCgs(xw);
8279d522f475Smrg
82800bd37d32Smrg    TRACE_FREE_LEAK(screen->selection_targets_8bit);
82810bd37d32Smrg#if OPT_SELECT_REGEX
82820bd37d32Smrg    for (n = 0; n < NSELECTUNITS; ++n) {
82830bd37d32Smrg	if (screen->selectMap[n] == Select_REGEX) {
82840bd37d32Smrg	    TRACE_FREE_LEAK(screen->selectExpr[n]);
82850bd37d32Smrg	}
82860bd37d32Smrg    }
82870bd37d32Smrg#endif
82880bd37d32Smrg
8289d522f475Smrg#if OPT_RENDERFONT
8290d522f475Smrg    for (n = 0; n < NMENUFONTS; ++n) {
8291d522f475Smrg	xtermCloseXft(screen, &(screen->renderFontNorm[n]));
8292d522f475Smrg	xtermCloseXft(screen, &(screen->renderFontBold[n]));
8293d522f475Smrg	xtermCloseXft(screen, &(screen->renderFontItal[n]));
8294956cc18dSsnj#if OPT_RENDERWIDE
8295d522f475Smrg	xtermCloseXft(screen, &(screen->renderWideNorm[n]));
8296d522f475Smrg	xtermCloseXft(screen, &(screen->renderWideBold[n]));
8297d522f475Smrg	xtermCloseXft(screen, &(screen->renderWideItal[n]));
8298956cc18dSsnj#endif
8299d522f475Smrg    }
8300d522f475Smrg#endif
8301d522f475Smrg
830220d2c4d2Smrg    /* free things allocated via init_Sres or Init_Sres2 */
83030bd37d32Smrg#ifndef NO_ACTIVE_ICON
83040bd37d32Smrg    TRACE_FREE_LEAK(screen->icon_fontname);
83050bd37d32Smrg#endif
830620d2c4d2Smrg#ifdef ALLOWLOGGING
830720d2c4d2Smrg    TRACE_FREE_LEAK(screen->logfile);
8308d522f475Smrg#endif
83090bd37d32Smrg    TRACE_FREE_LEAK(screen->eight_bit_meta_s);
831020d2c4d2Smrg    TRACE_FREE_LEAK(screen->term_id);
831120d2c4d2Smrg    TRACE_FREE_LEAK(screen->charClass);
831220d2c4d2Smrg    TRACE_FREE_LEAK(screen->answer_back);
83130bd37d32Smrg    TRACE_FREE_LEAK(screen->printer_state.printer_command);
831420d2c4d2Smrg    TRACE_FREE_LEAK(screen->keyboard_dialect);
831520d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedColorOps);
831620d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedFontOps);
831720d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedTcapOps);
831820d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedWinOps);
831920d2c4d2Smrg    TRACE_FREE_LEAK(screen->default_string);
832020d2c4d2Smrg    TRACE_FREE_LEAK(screen->eightbit_select_types);
832120d2c4d2Smrg#if OPT_WIDE_CHARS
832220d2c4d2Smrg    TRACE_FREE_LEAK(screen->utf8_select_types);
832320d2c4d2Smrg#endif
832420d2c4d2Smrg#if 0
832520d2c4d2Smrg    for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; n++) {
832620d2c4d2Smrg	TRACE_FREE_LEAK(screen->MenuFontName(n));
8327d522f475Smrg    }
8328d522f475Smrg#endif
832920d2c4d2Smrg    TRACE_FREE_LEAK(screen->initial_font);
833020d2c4d2Smrg#if OPT_LUIT_PROG
833120d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.locale_str);
833220d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.localefilter);
833320d2c4d2Smrg#endif
833420d2c4d2Smrg#if OPT_RENDERFONT
833520d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.face_name);
833620d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.face_wide_name);
83370bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.render_font_s);
833820d2c4d2Smrg#endif
833920d2c4d2Smrg
8340d522f475Smrg#if OPT_SELECT_REGEX
8341d522f475Smrg    for (n = 0; n < NSELECTUNITS; ++n) {
8342d522f475Smrg	FREE_LEAK(screen->selectExpr[n]);
8343d522f475Smrg    }
8344d522f475Smrg#endif
8345d522f475Smrg
8346d522f475Smrg    if (screen->selection_atoms)
8347e0a2b6dfSmrg	XtFree((void *) (screen->selection_atoms));
8348d522f475Smrg
8349e0a2b6dfSmrg    XtFree((void *) (screen->selection_data));
8350d522f475Smrg
83510bd37d32Smrg    TRACE_FREE_LEAK(xtermClassRec.core_class.tm_table);
8352d522f475Smrg    TRACE_FREE_LEAK(xw->keyboard.extra_translations);
8353d522f475Smrg    TRACE_FREE_LEAK(xw->keyboard.shell_translations);
8354d522f475Smrg    TRACE_FREE_LEAK(xw->keyboard.xterm_translations);
8355956cc18dSsnj
8356e0a2b6dfSmrg    XtFree((void *) (xw->visInfo));
8357e0a2b6dfSmrg
8358956cc18dSsnj#if OPT_WIDE_CHARS
8359956cc18dSsnj    FreeTypedBuffer(XChar2b);
8360956cc18dSsnj    FreeTypedBuffer(char);
8361956cc18dSsnj#endif
8362956cc18dSsnj#if OPT_RENDERFONT
8363956cc18dSsnj#if OPT_RENDERWIDE
8364956cc18dSsnj    FreeTypedBuffer(XftCharSpec);
8365956cc18dSsnj#else
8366956cc18dSsnj    FreeTypedBuffer(XftChar8);
8367956cc18dSsnj#endif
8368956cc18dSsnj#endif
8369956cc18dSsnj
8370956cc18dSsnj    TRACE_FREE_LEAK(myState.print_area);
8371956cc18dSsnj    TRACE_FREE_LEAK(myState.string_area);
8372956cc18dSsnj    memset(&myState, 0, sizeof(myState));
8373956cc18dSsnj
8374d522f475Smrg#endif /* defined(NO_LEAKS) */
8375d522f475Smrg}
8376d522f475Smrg
83770bd37d32Smrgstatic void *
8378e0a2b6dfSmrggetProperty(Display *dpy,
83790bd37d32Smrg	    Window w,
83800bd37d32Smrg	    Atom req_type,
83810bd37d32Smrg	    const char *prop_name)
83820bd37d32Smrg{
83830bd37d32Smrg    Atom property;
83840bd37d32Smrg    Atom actual_return_type;
83850bd37d32Smrg    int actual_format_return = 0;
83860bd37d32Smrg    unsigned long nitems_return = 0;
83870bd37d32Smrg    unsigned long bytes_after_return = 0;
83880bd37d32Smrg    unsigned char *prop_return = 0;
83890bd37d32Smrg    long long_length = 1024;
83900bd37d32Smrg    size_t limit;
83910bd37d32Smrg    char *result = 0;
83920bd37d32Smrg
83930bd37d32Smrg    TRACE(("getProperty %s(%s)\n", prop_name,
83940bd37d32Smrg	   req_type ? XGetAtomName(dpy, req_type) : "?"));
83950bd37d32Smrg    property = XInternAtom(dpy, prop_name, False);
83960bd37d32Smrg
83970bd37d32Smrg    if (!xtermGetWinProp(dpy,
83980bd37d32Smrg			 w,
83990bd37d32Smrg			 property,
84000bd37d32Smrg			 0L,
84010bd37d32Smrg			 long_length,
84020bd37d32Smrg			 req_type,
84030bd37d32Smrg			 &actual_return_type,
84040bd37d32Smrg			 &actual_format_return,
84050bd37d32Smrg			 &nitems_return,
84060bd37d32Smrg			 &bytes_after_return,
84070bd37d32Smrg			 &prop_return)) {
84080bd37d32Smrg	TRACE((".. Cannot get %s property.\n", prop_name));
84090bd37d32Smrg    } else if (prop_return != 0) {
84100bd37d32Smrg
84110bd37d32Smrg	if (nitems_return != 0 &&
84120bd37d32Smrg	    actual_format_return != 0 &&
84130bd37d32Smrg	    actual_return_type == req_type) {
84140bd37d32Smrg	    /*
84150bd37d32Smrg	     * Null-terminate the result to make string handling easier.
84160bd37d32Smrg	     * The format==8 corresponds to strings, and the number of items
84170bd37d32Smrg	     * is the number of characters.
84180bd37d32Smrg	     */
84190bd37d32Smrg	    if (actual_format_return == 8) {
84200bd37d32Smrg		limit = nitems_return;
84210bd37d32Smrg	    } else {
84220bd37d32Smrg		/* manpage is misleading - X really uses 'long', not 32-bits */
84230bd37d32Smrg		limit = sizeof(long) * nitems_return;
84240bd37d32Smrg	    }
84250bd37d32Smrg	    if ((result = malloc(limit + 1)) != 0) {
84260bd37d32Smrg		memcpy(result, prop_return, limit);
84270bd37d32Smrg		result[limit] = '\0';
84280bd37d32Smrg	    }
84290bd37d32Smrg	    TRACE(("... result %s\n", result ? ("ok") : "null"));
84300bd37d32Smrg	}
84310bd37d32Smrg	XFree(prop_return);
84320bd37d32Smrg    } else {
84330bd37d32Smrg	TRACE((".. no property returned\n"));
84340bd37d32Smrg    }
84350bd37d32Smrg    return (void *) result;
84360bd37d32Smrg}
84370bd37d32Smrg
84380bd37d32Smrg/*
84390bd37d32Smrg * Active icons are supported by fvwm.  This feature is not supported by
84400bd37d32Smrg * metacity (gnome) or kwin (kde).  Both metacity and kwin support (in
84410bd37d32Smrg * incompatible ways, e.g., one uses the icon theme as a fallback for window
84420bd37d32Smrg * decorations but the other does not, etc, ...) an icon as part of the window
84430bd37d32Smrg * decoration (usually on the upper-left of the window).
84440bd37d32Smrg *
84450bd37d32Smrg * In either case, xterm's icon will only be shown in the window decorations if
84460bd37d32Smrg * xterm does not use the active icon feature.
84470bd37d32Smrg *
84480bd37d32Smrg * This function (tries to) determine the window manager's name, so that we can
84490bd37d32Smrg * provide a useful automatic default for active icons.  It is based on reading
84500bd37d32Smrg * wmctrl, which covers most of EWMH and ICCM.
84510bd37d32Smrg */
84520bd37d32Smrgstatic char *
84530bd37d32SmrggetWindowManagerName(XtermWidget xw)
84540bd37d32Smrg{
84550bd37d32Smrg    TScreen *screen = TScreenOf(xw);
84560bd37d32Smrg    Display *dpy = screen->display;
84570bd37d32Smrg    Window *sup_window = NULL;
84580bd37d32Smrg    char *result = 0;
84590bd37d32Smrg
84600bd37d32Smrg    TRACE(("getWindowManagerName\n"));
84610bd37d32Smrg#define getWinProp(type, name) \
84620bd37d32Smrg    (Window *)getProperty(dpy, DefaultRootWindow(dpy), type, name)
84630bd37d32Smrg    if ((sup_window = getWinProp(XA_WINDOW, "_NET_SUPPORTING_WM_CHECK")) == 0) {
84640bd37d32Smrg	sup_window = getWinProp(XA_CARDINAL, "_WIN_SUPPORTING_WM_CHECK");
84650bd37d32Smrg    }
84660bd37d32Smrg
84670bd37d32Smrg    /*
84680bd37d32Smrg     * If we found the supporting window, get the property containing the
84690bd37d32Smrg     * window manager's name.  EWMH defines _NET_WM_NAME, while ICCM defines
84700bd37d32Smrg     * WM_CLASS.  There is no standard for the names stored there;
84710bd37d32Smrg     * conventionally it is mixed case.  In practice, the former is more often
84720bd37d32Smrg     * set; the latter is not given (or is a lowercased version of the former).
84730bd37d32Smrg     */
84740bd37d32Smrg    if (sup_window != 0) {
84750bd37d32Smrg#define getStringProp(type,name) \
84760bd37d32Smrg	(char *)getProperty(dpy, *sup_window, type, name)
84770bd37d32Smrg	if ((result = getStringProp(XA_UTF8_STRING(dpy), "_NET_WM_NAME")) == 0
84780bd37d32Smrg	    && (result = getStringProp(XA_STRING, "_NET_WM_NAME")) == 0
84790bd37d32Smrg	    && (result = getStringProp(XA_STRING, "WM_CLASS")) == 0) {
84800bd37d32Smrg	    TRACE(("... window manager does not tell its name\n"));
84810bd37d32Smrg	}
84820bd37d32Smrg	free(sup_window);
84830bd37d32Smrg    } else {
84840bd37d32Smrg	TRACE(("... Cannot get window manager info properties\n"));
84850bd37d32Smrg    }
84860bd37d32Smrg    if (result == 0)
84870bd37d32Smrg	result = x_strdup("unknown");
84880bd37d32Smrg    TRACE(("... window manager name is %s\n", result));
84890bd37d32Smrg    return result;
84900bd37d32Smrg}
84910bd37d32Smrg
8492d522f475Smrg/*ARGSUSED*/
8493d522f475Smrgstatic void
8494d522f475SmrgVTRealize(Widget w,
8495d522f475Smrg	  XtValueMask * valuemask,
8496d522f475Smrg	  XSetWindowAttributes * values)
8497d522f475Smrg{
8498d522f475Smrg    XtermWidget xw = (XtermWidget) w;
849920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
8500d522f475Smrg
8501d522f475Smrg    const VTFontNames *myfont;
8502d522f475Smrg    unsigned width, height;
8503d522f475Smrg    int xpos, ypos, pr;
8504d522f475Smrg    Atom pid_atom;
8505d522f475Smrg    int i;
8506d522f475Smrg
8507d522f475Smrg    TRACE(("VTRealize\n"));
8508d522f475Smrg
85090bd37d32Smrg#if OPT_TOOLBAR
85100bd37d32Smrg    /*
85110bd37d32Smrg     * Layout for the toolbar confuses the Shell widget.  Remind it that we
85120bd37d32Smrg     * would like to be iconified if the corresponding resource was set.
85130bd37d32Smrg     */
85140bd37d32Smrg    if (XtIsRealized(toplevel)) {
85150bd37d32Smrg	Boolean iconic = 0;
85160bd37d32Smrg
85170bd37d32Smrg	XtVaGetValues(toplevel,
85180bd37d32Smrg		      XtNiconic, &iconic,
85190bd37d32Smrg		      (XtPointer) 0);
85200bd37d32Smrg
85210bd37d32Smrg	if (iconic) {
85220bd37d32Smrg	    XIconifyWindow(XtDisplay(toplevel),
85230bd37d32Smrg			   XtWindow(toplevel),
85240bd37d32Smrg			   DefaultScreen(XtDisplay(toplevel)));
85250bd37d32Smrg	}
85260bd37d32Smrg    }
85270bd37d32Smrg#endif
85280bd37d32Smrg
8529d522f475Smrg    TabReset(xw->tabs);
8530d522f475Smrg
8531d522f475Smrg    if (screen->menu_font_number == fontMenu_default) {
8532d522f475Smrg	myfont = &(xw->misc.default_font);
8533d522f475Smrg    } else {
8534d522f475Smrg	myfont = xtermFontName(screen->MenuFontName(screen->menu_font_number));
8535d522f475Smrg    }
8536d522f475Smrg    memset(screen->fnts, 0, sizeof(screen->fnts));
8537d522f475Smrg
8538d522f475Smrg    if (!xtermLoadFont(xw,
8539d522f475Smrg		       myfont,
8540d522f475Smrg		       False,
8541d522f475Smrg		       screen->menu_font_number)) {
8542d522f475Smrg	if (XmuCompareISOLatin1(myfont->f_n, DEFFONT) != 0) {
854320d2c4d2Smrg	    char *use_font = x_strdup(DEFFONT);
85440bd37d32Smrg	    xtermWarning("unable to open font \"%s\", trying \"%s\"....\n",
85450bd37d32Smrg			 myfont->f_n, use_font);
8546d522f475Smrg	    (void) xtermLoadFont(xw,
854720d2c4d2Smrg				 xtermFontName(use_font),
8548d522f475Smrg				 False,
8549d522f475Smrg				 screen->menu_font_number);
855020d2c4d2Smrg	    screen->MenuFontName(screen->menu_font_number) = use_font;
8551d522f475Smrg	}
8552d522f475Smrg    }
8553d522f475Smrg
8554d522f475Smrg    /* really screwed if we couldn't open default font */
8555d522f475Smrg    if (!screen->fnts[fNorm].fs) {
85560bd37d32Smrg	xtermWarning("unable to locate a suitable font\n");
8557d522f475Smrg	Exit(1);
8558d522f475Smrg    }
8559d522f475Smrg#if OPT_WIDE_CHARS
8560e39b573cSmrg    if (screen->utf8_mode) {
8561d522f475Smrg	TRACE(("check if this is a wide font, if not try again\n"));
8562e39b573cSmrg	if (xtermLoadWideFonts(xw, False)) {
8563d522f475Smrg	    SetVTFont(xw, screen->menu_font_number, True, NULL);
8564e39b573cSmrg	    /* we will not be able to switch to ISO-8859-1 */
8565e39b573cSmrg	    if (!screen->mergedVTFonts) {
8566e39b573cSmrg		screen->utf8_fonts = uAlways;
8567e39b573cSmrg		update_font_utf8_fonts();
8568e39b573cSmrg	    }
8569e39b573cSmrg	}
8570d522f475Smrg    }
8571d522f475Smrg#endif
8572d522f475Smrg
8573d522f475Smrg    /* making cursor */
8574d522f475Smrg    if (!screen->pointer_cursor) {
8575d522f475Smrg	screen->pointer_cursor =
8576d522f475Smrg	    make_colored_cursor(XC_xterm,
8577d522f475Smrg				T_COLOR(screen, MOUSE_FG),
8578d522f475Smrg				T_COLOR(screen, MOUSE_BG));
8579d522f475Smrg    } else {
8580d522f475Smrg	recolor_cursor(screen,
8581d522f475Smrg		       screen->pointer_cursor,
8582d522f475Smrg		       T_COLOR(screen, MOUSE_FG),
8583d522f475Smrg		       T_COLOR(screen, MOUSE_BG));
8584d522f475Smrg    }
8585d522f475Smrg
8586d522f475Smrg    /* set defaults */
8587d522f475Smrg    xpos = 1;
8588d522f475Smrg    ypos = 1;
8589d522f475Smrg    width = 80;
8590d522f475Smrg    height = 24;
8591d522f475Smrg
8592d522f475Smrg    TRACE(("parsing geo_metry %s\n", NonNull(xw->misc.geo_metry)));
8593d522f475Smrg    pr = XParseGeometry(xw->misc.geo_metry, &xpos, &ypos,
8594d522f475Smrg			&width, &height);
8595d522f475Smrg    TRACE(("... position %d,%d size %dx%d\n", ypos, xpos, height, width));
8596d522f475Smrg
8597d522f475Smrg    set_max_col(screen, (int) (width - 1));	/* units in character cells */
8598d522f475Smrg    set_max_row(screen, (int) (height - 1));	/* units in character cells */
8599d522f475Smrg    xtermUpdateFontInfo(xw, False);
8600d522f475Smrg
8601d522f475Smrg    width = screen->fullVwin.fullwidth;
8602d522f475Smrg    height = screen->fullVwin.fullheight;
8603d522f475Smrg
8604d522f475Smrg    TRACE(("... border widget %d parent %d shell %d\n",
8605d522f475Smrg	   BorderWidth(xw),
8606d522f475Smrg	   BorderWidth(XtParent(xw)),
8607d522f475Smrg	   BorderWidth(SHELL_OF(xw))));
8608d522f475Smrg
8609d522f475Smrg    if ((pr & XValue) && (XNegative & pr)) {
86102eaa94a1Schristos	xpos += (DisplayWidth(screen->display, DefaultScreen(screen->display))
86112eaa94a1Schristos		 - (int) width
86122eaa94a1Schristos		 - (BorderWidth(XtParent(xw)) * 2));
8613d522f475Smrg    }
8614d522f475Smrg    if ((pr & YValue) && (YNegative & pr)) {
86152eaa94a1Schristos	ypos += (DisplayHeight(screen->display, DefaultScreen(screen->display))
86162eaa94a1Schristos		 - (int) height
86172eaa94a1Schristos		 - (BorderWidth(XtParent(xw)) * 2));
8618d522f475Smrg    }
8619d522f475Smrg
8620d522f475Smrg    /* set up size hints for window manager; min 1 char by 1 char */
8621d522f475Smrg    getXtermSizeHints(xw);
8622d522f475Smrg    xtermSizeHints(xw, (xw->misc.scrollbar
8623d522f475Smrg			? (screen->scrollWidget->core.width
8624d522f475Smrg			   + BorderWidth(screen->scrollWidget))
8625d522f475Smrg			: 0));
8626d522f475Smrg
8627d522f475Smrg    xw->hints.x = xpos;
8628d522f475Smrg    xw->hints.y = ypos;
8629a1f3da82Smrg#if OPT_MAXIMIZE
8630a1f3da82Smrg    /* assure single-increment resize for fullscreen */
86310bd37d32Smrg    if (term->work.ewmh[0].mode) {
8632a1f3da82Smrg	xw->hints.width_inc = 1;
8633a1f3da82Smrg	xw->hints.height_inc = 1;
8634a1f3da82Smrg    }
8635a1f3da82Smrg#endif
8636d522f475Smrg    if ((XValue & pr) || (YValue & pr)) {
8637d522f475Smrg	xw->hints.flags |= USSize | USPosition;
8638d522f475Smrg	xw->hints.flags |= PWinGravity;
8639d522f475Smrg	switch (pr & (XNegative | YNegative)) {
8640d522f475Smrg	case 0:
8641d522f475Smrg	    xw->hints.win_gravity = NorthWestGravity;
8642d522f475Smrg	    break;
8643d522f475Smrg	case XNegative:
8644d522f475Smrg	    xw->hints.win_gravity = NorthEastGravity;
8645d522f475Smrg	    break;
8646d522f475Smrg	case YNegative:
8647d522f475Smrg	    xw->hints.win_gravity = SouthWestGravity;
8648d522f475Smrg	    break;
8649d522f475Smrg	default:
8650d522f475Smrg	    xw->hints.win_gravity = SouthEastGravity;
8651d522f475Smrg	    break;
8652d522f475Smrg	}
8653d522f475Smrg    } else {
8654d522f475Smrg	/* set a default size, but do *not* set position */
8655d522f475Smrg	xw->hints.flags |= PSize;
8656d522f475Smrg    }
8657d522f475Smrg    xw->hints.height = xw->hints.base_height
8658d522f475Smrg	+ xw->hints.height_inc * MaxRows(screen);
8659d522f475Smrg    xw->hints.width = xw->hints.base_width
8660d522f475Smrg	+ xw->hints.width_inc * MaxCols(screen);
8661d522f475Smrg
8662d522f475Smrg    if ((WidthValue & pr) || (HeightValue & pr))
8663d522f475Smrg	xw->hints.flags |= USSize;
8664d522f475Smrg    else
8665d522f475Smrg	xw->hints.flags |= PSize;
8666d522f475Smrg
8667d522f475Smrg    /*
8668d522f475Smrg     * Note that the size-hints are for the shell, while the resize-request
8669d522f475Smrg     * is for the vt100 widget.  They are not the same size.
8670d522f475Smrg     */
86712eaa94a1Schristos    (void) REQ_RESIZE((Widget) xw,
86722eaa94a1Schristos		      (Dimension) width, (Dimension) height,
86732eaa94a1Schristos		      &xw->core.width, &xw->core.height);
8674d522f475Smrg
8675d522f475Smrg    /* XXX This is bogus.  We are parsing geometries too late.  This
8676d522f475Smrg     * is information that the shell widget ought to have before we get
8677d522f475Smrg     * realized, so that it can do the right thing.
8678d522f475Smrg     */
8679d522f475Smrg    if (xw->hints.flags & USPosition)
8680a1f3da82Smrg	XMoveWindow(XtDisplay(xw), VShellWindow(xw),
8681d522f475Smrg		    xw->hints.x, xw->hints.y);
8682d522f475Smrg
8683d522f475Smrg    TRACE(("%s@%d -- ", __FILE__, __LINE__));
8684d522f475Smrg    TRACE_HINTS(&xw->hints);
8685a1f3da82Smrg    XSetWMNormalHints(XtDisplay(xw), VShellWindow(xw), &xw->hints);
8686d522f475Smrg    TRACE(("%s@%d -- ", __FILE__, __LINE__));
8687d522f475Smrg    TRACE_WM_HINTS(xw);
8688d522f475Smrg
8689d522f475Smrg    if ((pid_atom = XInternAtom(XtDisplay(xw), "_NET_WM_PID", False)) != None) {
8690d522f475Smrg	/* XChangeProperty format 32 really is "long" */
8691d522f475Smrg	unsigned long pid_l = (unsigned long) getpid();
8692d522f475Smrg	TRACE(("Setting _NET_WM_PID property to %lu\n", pid_l));
8693a1f3da82Smrg	XChangeProperty(XtDisplay(xw), VShellWindow(xw),
8694d522f475Smrg			pid_atom, XA_CARDINAL, 32, PropModeReplace,
8695d522f475Smrg			(unsigned char *) &pid_l, 1);
8696d522f475Smrg    }
8697d522f475Smrg
8698d522f475Smrg    XFlush(XtDisplay(xw));	/* get it out to window manager */
8699d522f475Smrg
8700d522f475Smrg    /* use ForgetGravity instead of SouthWestGravity because translating
8701d522f475Smrg       the Expose events for ConfigureNotifys is too hard */
8702956cc18dSsnj    values->bit_gravity = (GravityIsNorthWest(xw)
8703d522f475Smrg			   ? NorthWestGravity
8704d522f475Smrg			   : ForgetGravity);
8705e39b573cSmrg    screen->fullVwin.window = XtWindow(xw) =
8706d522f475Smrg	XCreateWindow(XtDisplay(xw), XtWindow(XtParent(xw)),
8707d522f475Smrg		      xw->core.x, xw->core.y,
8708d522f475Smrg		      xw->core.width, xw->core.height, BorderWidth(xw),
8709d522f475Smrg		      (int) xw->core.depth,
8710d522f475Smrg		      InputOutput, CopyFromParent,
8711d522f475Smrg		      *valuemask | CWBitGravity, values);
87120bd37d32Smrg#if OPT_DOUBLE_BUFFER
87130bd37d32Smrg    screen->fullVwin.drawable = screen->fullVwin.window;
87140bd37d32Smrg
87150bd37d32Smrg    {
87160bd37d32Smrg	Window win = screen->fullVwin.window;
87170bd37d32Smrg	Drawable d;
87180bd37d32Smrg	int major, minor;
87190bd37d32Smrg	if (!XdbeQueryExtension(XtDisplay(xw), &major, &minor)) {
87200bd37d32Smrg	    fprintf(stderr, "XdbeQueryExtension returned zero!\n");
87210bd37d32Smrg	    exit(3);
87220bd37d32Smrg	}
87230bd37d32Smrg	d = XdbeAllocateBackBufferName(XtDisplay(xw), win, XdbeCopied);
87240bd37d32Smrg	if (d == None) {
87250bd37d32Smrg	    fprintf(stderr, "Couldn't allocate a back buffer!\n");
87260bd37d32Smrg	    exit(3);
87270bd37d32Smrg	}
87280bd37d32Smrg	screen->fullVwin.drawable = d;
87290bd37d32Smrg	screen->needSwap = 1;
87300bd37d32Smrg    }
87310bd37d32Smrg#endif /* OPT_DOUBLE_BUFFER */
8732d522f475Smrg    screen->event_mask = values->event_mask;
8733d522f475Smrg
8734d522f475Smrg#ifndef NO_ACTIVE_ICON
8735492d43a5Smrg    /*
8736492d43a5Smrg     * Normally, the font-number for icon fonts does not correspond with any of
8737492d43a5Smrg     * the menu-selectable fonts.  If we cannot load the font given for the
8738492d43a5Smrg     * iconFont resource, try with font1 aka "Unreadable".
8739492d43a5Smrg     */
8740492d43a5Smrg    screen->icon_fontnum = -1;
8741492d43a5Smrg    if (screen->fnt_icon.fs == 0) {
8742492d43a5Smrg	screen->fnt_icon.fs = XLoadQueryFont(screen->display,
8743492d43a5Smrg					     screen->MenuFontName(fontMenu_font1));
8744492d43a5Smrg	TRACE(("%susing font1 '%s' as iconFont\n",
8745492d43a5Smrg	       (screen->fnt_icon.fs
8746492d43a5Smrg		? ""
8747492d43a5Smrg		: "NOT "),
8748492d43a5Smrg	       screen->MenuFontName(fontMenu_font1)));
8749492d43a5Smrg    }
8750492d43a5Smrg#if OPT_RENDERFONT
8751492d43a5Smrg    /*
8752492d43a5Smrg     * If we still have no result from iconFont resource (perhaps because fonts
8753492d43a5Smrg     * are missing) but are using Xft, try to use that instead.  We prefer
8754492d43a5Smrg     * bitmap fonts in any case, since scaled fonts are usually less readable,
8755492d43a5Smrg     * particularly at small sizes.
8756492d43a5Smrg     */
8757492d43a5Smrg    if (UsingRenderFont(xw)
8758492d43a5Smrg	&& screen->fnt_icon.fs == 0) {
8759492d43a5Smrg	screen->icon_fontnum = fontMenu_default;
8760492d43a5Smrg	screen->fnt_icon.fs = screen->fnts[0].fs;	/* need for next-if */
8761492d43a5Smrg	TRACE(("using TrueType font as iconFont\n"));
8762492d43a5Smrg    }
8763492d43a5Smrg#endif
87640bd37d32Smrg    if ((xw->work.active_icon == eiDefault) && screen->fnt_icon.fs) {
87650bd37d32Smrg	char *wm_name = getWindowManagerName(xw);
87660bd37d32Smrg	if (x_strncasecmp(wm_name, "fvwm", 4) &&
87670bd37d32Smrg	    x_strncasecmp(wm_name, "window maker", 12))
87680bd37d32Smrg	    xw->work.active_icon = eiFalse;
87690bd37d32Smrg	free(wm_name);
87700bd37d32Smrg    }
87710bd37d32Smrg    if (xw->work.active_icon && screen->fnt_icon.fs) {
8772d522f475Smrg	int iconX = 0, iconY = 0;
8773d522f475Smrg	Widget shell = SHELL_OF(xw);
8774d522f475Smrg	VTwin *win = &(screen->iconVwin);
8775492d43a5Smrg	int save_fontnum = screen->menu_font_number;
8776d522f475Smrg
8777492d43a5Smrg	TRACE(("Initializing active-icon %d\n", screen->icon_fontnum));
8778492d43a5Smrg	screen->menu_font_number = screen->icon_fontnum;
8779492d43a5Smrg	XtVaGetValues(shell,
8780492d43a5Smrg		      XtNiconX, &iconX,
8781492d43a5Smrg		      XtNiconY, &iconY,
8782492d43a5Smrg		      (XtPointer) 0);
8783d522f475Smrg	xtermComputeFontInfo(xw, &(screen->iconVwin), screen->fnt_icon.fs, 0);
8784492d43a5Smrg	screen->menu_font_number = save_fontnum;
8785d522f475Smrg
8786d522f475Smrg	/* since only one client is permitted to select for Button
8787d522f475Smrg	 * events, we have to let the window manager get 'em...
8788d522f475Smrg	 */
8789d522f475Smrg	values->event_mask &= ~(ButtonPressMask | ButtonReleaseMask);
8790d522f475Smrg	values->border_pixel = xw->misc.icon_border_pixel;
8791d522f475Smrg
8792d522f475Smrg	screen->iconVwin.window =
8793d522f475Smrg	    XCreateWindow(XtDisplay(xw),
8794d522f475Smrg			  RootWindowOfScreen(XtScreen(shell)),
8795d522f475Smrg			  iconX, iconY,
8796d522f475Smrg			  screen->iconVwin.fullwidth,
8797d522f475Smrg			  screen->iconVwin.fullheight,
8798d522f475Smrg			  xw->misc.icon_border_width,
8799d522f475Smrg			  (int) xw->core.depth,
8800d522f475Smrg			  InputOutput, CopyFromParent,
8801d522f475Smrg			  *valuemask | CWBitGravity | CWBorderPixel,
8802d522f475Smrg			  values);
88030bd37d32Smrg#if OPT_DOUBLE_BUFFER
88040bd37d32Smrg	screen->iconVwin.drawable = screen->iconVwin.window;
88050bd37d32Smrg#endif
8806d522f475Smrg	XtVaSetValues(shell,
8807d522f475Smrg		      XtNiconWindow, screen->iconVwin.window,
8808d522f475Smrg		      (XtPointer) 0);
8809d522f475Smrg	XtRegisterDrawable(XtDisplay(xw), screen->iconVwin.window, w);
8810d522f475Smrg
8811d522f475Smrg	setCgsFont(xw, win, gcNorm, &(screen->fnt_icon));
8812d522f475Smrg	setCgsFore(xw, win, gcNorm, T_COLOR(screen, TEXT_FG));
8813d522f475Smrg	setCgsBack(xw, win, gcNorm, T_COLOR(screen, TEXT_BG));
8814d522f475Smrg
8815d522f475Smrg	copyCgs(xw, win, gcBold, gcNorm);
8816d522f475Smrg
8817d522f475Smrg	setCgsFont(xw, win, gcNormReverse, &(screen->fnt_icon));
8818d522f475Smrg	setCgsFore(xw, win, gcNormReverse, T_COLOR(screen, TEXT_BG));
8819d522f475Smrg	setCgsBack(xw, win, gcNormReverse, T_COLOR(screen, TEXT_FG));
8820d522f475Smrg
8821d522f475Smrg	copyCgs(xw, win, gcBoldReverse, gcNormReverse);
8822d522f475Smrg
8823d522f475Smrg#if OPT_TOOLBAR
8824d522f475Smrg	/*
8825d522f475Smrg	 * Toolbar is initialized before we get here.  Enable the menu item
8826d522f475Smrg	 * and set it properly.
8827d522f475Smrg	 */
8828d522f475Smrg	SetItemSensitivity(vtMenuEntries[vtMenu_activeicon].widget, True);
8829d522f475Smrg	update_activeicon();
8830d522f475Smrg#endif
8831d522f475Smrg    } else {
8832d522f475Smrg	TRACE(("Disabled active-icon\n"));
88330bd37d32Smrg	xw->work.active_icon = eiFalse;
8834d522f475Smrg    }
8835d522f475Smrg#endif /* NO_ACTIVE_ICON */
8836d522f475Smrg
8837d522f475Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
8838956cc18dSsnj    VTInitI18N(xw);
8839d522f475Smrg#endif
8840d522f475Smrg#if OPT_NUM_LOCK
8841d522f475Smrg    VTInitModifiers(xw);
8842d522f475Smrg#if OPT_EXTRA_PASTE
8843d522f475Smrg    if (xw->keyboard.extra_translations) {
8844d522f475Smrg	XtOverrideTranslations((Widget) xw,
8845d522f475Smrg			       XtParseTranslationTable(xw->keyboard.extra_translations));
8846d522f475Smrg    }
8847d522f475Smrg#endif
8848d522f475Smrg#endif
8849d522f475Smrg
8850d522f475Smrg    set_cursor_gcs(xw);
8851d522f475Smrg
8852d522f475Smrg    /* Reset variables used by ANSI emulation. */
8853d522f475Smrg
8854d522f475Smrg    resetCharsets(screen);
8855d522f475Smrg
8856a1f3da82Smrg    XDefineCursor(screen->display, VShellWindow(xw), screen->pointer_cursor);
8857d522f475Smrg
8858d522f475Smrg    set_cur_col(screen, 0);
8859d522f475Smrg    set_cur_row(screen, 0);
8860d522f475Smrg    set_max_col(screen, Width(screen) / screen->fullVwin.f_width - 1);
8861d522f475Smrg    set_max_row(screen, Height(screen) / screen->fullVwin.f_height - 1);
88620bd37d32Smrg    reset_margins(screen);
8863d522f475Smrg
8864d522f475Smrg    memset(screen->sc, 0, sizeof(screen->sc));
8865d522f475Smrg
8866d522f475Smrg    /* Mark screen buffer as unallocated.  We wait until the run loop so
8867d522f475Smrg       that the child process does not fork and exec with all the dynamic
8868d522f475Smrg       memory it will never use.  If we were to do it here, the
8869d522f475Smrg       swap space for new process would be huge for huge savelines. */
8870d522f475Smrg#if OPT_TEK4014
8871d522f475Smrg    if (!tekWidget)		/* if not called after fork */
8872d522f475Smrg#endif
8873956cc18dSsnj    {
8874956cc18dSsnj	screen->visbuf = NULL;
8875956cc18dSsnj	screen->saveBuf_index = NULL;
8876956cc18dSsnj    }
8877d522f475Smrg
88780bd37d32Smrg    ResetWrap(screen);
8879d522f475Smrg    screen->scrolls = screen->incopy = 0;
8880d522f475Smrg    xtermSetCursorBox(screen);
8881d522f475Smrg
8882d522f475Smrg    screen->savedlines = 0;
8883d522f475Smrg
8884d522f475Smrg    for (i = 0; i < 2; ++i) {
8885956cc18dSsnj	screen->whichBuf = !screen->whichBuf;
8886d522f475Smrg	CursorSave(xw);
8887d522f475Smrg    }
8888d522f475Smrg
88890bd37d32Smrg#ifndef NO_ACTIVE_ICON
88900bd37d32Smrg    if (!xw->work.active_icon)
88910bd37d32Smrg#endif
88920bd37d32Smrg	xtermLoadIcon(xw);
88930bd37d32Smrg
8894d522f475Smrg    /*
8895d522f475Smrg     * Do this last, since it may change the layout via a resize.
8896d522f475Smrg     */
8897d522f475Smrg    if (xw->misc.scrollbar) {
8898d522f475Smrg	screen->fullVwin.sb_info.width = 0;
8899956cc18dSsnj	ScrollBarOn(xw, False);
8900d522f475Smrg    }
8901a1f3da82Smrg
8902d522f475Smrg    return;
8903d522f475Smrg}
8904d522f475Smrg
8905d522f475Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
8906d522f475Smrg
8907d522f475Smrg/* limit this feature to recent XFree86 since X11R6.x core dumps */
8908d522f475Smrg#if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && defined(X_HAVE_UTF8_STRING)
8909d522f475Smrg#define USE_XIM_INSTANTIATE_CB
8910d522f475Smrg
8911d522f475Smrgstatic void
8912e0a2b6dfSmrgxim_instantiate_cb(Display *display,
8913d522f475Smrg		   XPointer client_data GCC_UNUSED,
8914d522f475Smrg		   XPointer call_data GCC_UNUSED)
8915d522f475Smrg{
89160bd37d32Smrg    TRACE(("xim_instantiate_cb client=%p, call=%p\n", client_data, call_data));
8917d522f475Smrg
89180bd37d32Smrg    if (display == XtDisplay(term)) {
89190bd37d32Smrg	VTInitI18N(term);
89200bd37d32Smrg    }
8921d522f475Smrg}
8922d522f475Smrg
8923d522f475Smrgstatic void
8924d522f475Smrgxim_destroy_cb(XIM im GCC_UNUSED,
8925d522f475Smrg	       XPointer client_data GCC_UNUSED,
8926d522f475Smrg	       XPointer call_data GCC_UNUSED)
8927d522f475Smrg{
89280bd37d32Smrg    XtermWidget xw = term;
89290bd37d32Smrg    TInput *input = lookupTInput(xw, (Widget) xw);
8930d522f475Smrg
89310bd37d32Smrg    TRACE(("xim_destroy_cb im=%lx, client=%p, call=%p\n",
89320bd37d32Smrg	   (long) im, client_data, call_data));
89330bd37d32Smrg    if (input)
89340bd37d32Smrg	input->xic = NULL;
89350bd37d32Smrg    XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL,
8936d522f475Smrg				   xim_instantiate_cb, NULL);
8937d522f475Smrg}
8938d522f475Smrg#endif /* X11R6+ */
8939d522f475Smrg
89400bd37d32Smrgstatic Boolean
89410bd37d32Smrgxim_create_fs(XtermWidget xw)
89420bd37d32Smrg{
89430bd37d32Smrg    XFontStruct **fonts;
89440bd37d32Smrg    char **font_name_list;
89450bd37d32Smrg    char **missing_charset_list;
89460bd37d32Smrg    char *def_string;
89470bd37d32Smrg    int missing_charset_count;
89480bd37d32Smrg    unsigned i, j;
89490bd37d32Smrg
89500bd37d32Smrg    if (xw->misc.xim_fs == 0) {
89510bd37d32Smrg	xw->misc.xim_fs = XCreateFontSet(XtDisplay(xw),
89520bd37d32Smrg					 xw->misc.f_x,
89530bd37d32Smrg					 &missing_charset_list,
89540bd37d32Smrg					 &missing_charset_count,
89550bd37d32Smrg					 &def_string);
89560bd37d32Smrg	if (xw->misc.xim_fs == NULL) {
89570bd37d32Smrg	    xtermWarning("Preparation of font set "
89580bd37d32Smrg			 "\"%s\" for XIM failed.\n", xw->misc.f_x);
89590bd37d32Smrg	    xw->misc.xim_fs = XCreateFontSet(XtDisplay(xw),
89600bd37d32Smrg					     DEFXIMFONT,
89610bd37d32Smrg					     &missing_charset_list,
89620bd37d32Smrg					     &missing_charset_count,
89630bd37d32Smrg					     &def_string);
89640bd37d32Smrg	}
89650bd37d32Smrg    }
89660bd37d32Smrg    if (xw->misc.xim_fs == NULL) {
89670bd37d32Smrg	xtermWarning("Preparation of default font set "
89680bd37d32Smrg		     "\"%s\" for XIM failed.\n", DEFXIMFONT);
89690bd37d32Smrg	cleanupInputMethod(xw);
89700bd37d32Smrg	xw->misc.cannot_im = True;
89710bd37d32Smrg    } else {
89720bd37d32Smrg	(void) XExtentsOfFontSet(xw->misc.xim_fs);
89730bd37d32Smrg	j = (unsigned) XFontsOfFontSet(xw->misc.xim_fs, &fonts, &font_name_list);
89740bd37d32Smrg	for (i = 0, xw->misc.xim_fs_ascent = 0; i < j; i++) {
89750bd37d32Smrg	    if (xw->misc.xim_fs_ascent < (*fonts)->ascent)
89760bd37d32Smrg		xw->misc.xim_fs_ascent = (*fonts)->ascent;
89770bd37d32Smrg	}
89780bd37d32Smrg    }
8979e0a2b6dfSmrg    return (Boolean) !(xw->misc.cannot_im);
89800bd37d32Smrg}
89810bd37d32Smrg
8982d522f475Smrgstatic void
89830bd37d32Smrgxim_create_xic(XtermWidget xw, Widget theInput)
8984d522f475Smrg{
89850bd37d32Smrg    Display *myDisplay = XtDisplay(theInput);
89860bd37d32Smrg    Window myWindow = XtWindow(theInput);
8987d522f475Smrg    unsigned i, j;
89880bd37d32Smrg    char *p = NULL, *s, *t, *ns, *end, buf[32];
8989d522f475Smrg    XIMStyles *xim_styles;
8990d522f475Smrg    XIMStyle input_style = 0;
8991d522f475Smrg    Bool found;
8992d522f475Smrg    static struct {
899320d2c4d2Smrg	const char *name;
8994d522f475Smrg	unsigned long code;
8995d522f475Smrg    } known_style[] = {
8996d522f475Smrg	{
8997d522f475Smrg	    "OverTheSpot", (XIMPreeditPosition | XIMStatusNothing)
8998d522f475Smrg	},
8999d522f475Smrg	{
9000d522f475Smrg	    "OffTheSpot", (XIMPreeditArea | XIMStatusArea)
9001d522f475Smrg	},
9002d522f475Smrg	{
9003d522f475Smrg	    "Root", (XIMPreeditNothing | XIMStatusNothing)
9004d522f475Smrg	},
9005d522f475Smrg    };
90060bd37d32Smrg    TInput *input = lookupTInput(xw, theInput);
9007d522f475Smrg
9008956cc18dSsnj    if (xw->misc.cannot_im) {
9009d522f475Smrg	return;
9010d522f475Smrg    }
9011d522f475Smrg
90120bd37d32Smrg    if (input == 0) {
90130bd37d32Smrg	for (i = 0; i < NINPUTWIDGETS; ++i) {
90140bd37d32Smrg	    if (xw->misc.inputs[i].w == 0) {
90150bd37d32Smrg		input = xw->misc.inputs + i;
90160bd37d32Smrg		input->w = theInput;
90170bd37d32Smrg		break;
90180bd37d32Smrg	    }
90190bd37d32Smrg	}
90200bd37d32Smrg    }
90210bd37d32Smrg
90220bd37d32Smrg    if (input == 0) {
90230bd37d32Smrg	xtermWarning("attempted to add too many input widgets\n");
90240bd37d32Smrg	return;
90250bd37d32Smrg    }
90260bd37d32Smrg
90270bd37d32Smrg    TRACE(("xim_real_init\n"));
90280bd37d32Smrg
90290bd37d32Smrg    if (IsEmpty(xw->misc.input_method)) {
90300bd37d32Smrg	if ((p = XSetLocaleModifiers("")) != NULL && *p) {
90310bd37d32Smrg	    input->xim = XOpenIM(myDisplay, NULL, NULL, NULL);
90320bd37d32Smrg	}
9033d522f475Smrg    } else {
9034956cc18dSsnj	s = xw->misc.input_method;
903520d2c4d2Smrg	i = 5 + (unsigned) strlen(s);
903620d2c4d2Smrg
9037d522f475Smrg	t = (char *) MyStackAlloc(i, buf);
903820d2c4d2Smrg	if (t == NULL) {
9039d522f475Smrg	    SysError(ERROR_VINIT);
904020d2c4d2Smrg	} else {
9041d522f475Smrg
904220d2c4d2Smrg	    for (ns = s; ns && *s;) {
904320d2c4d2Smrg		while (*s && isspace(CharOf(*s)))
904420d2c4d2Smrg		    s++;
904520d2c4d2Smrg		if (!*s)
9046d522f475Smrg		    break;
904720d2c4d2Smrg		if ((ns = end = strchr(s, ',')) == 0)
904820d2c4d2Smrg		    end = s + strlen(s);
904920d2c4d2Smrg		while ((end != s) && isspace(CharOf(end[-1])))
905020d2c4d2Smrg		    end--;
905120d2c4d2Smrg
905220d2c4d2Smrg		if (end != s) {
905320d2c4d2Smrg		    strcpy(t, "@im=");
905420d2c4d2Smrg		    strncat(t, s, (size_t) (end - s));
905520d2c4d2Smrg
905620d2c4d2Smrg		    if ((p = XSetLocaleModifiers(t)) != 0 && *p
90570bd37d32Smrg			&& (input->xim = XOpenIM(myDisplay,
90580bd37d32Smrg						 NULL,
90590bd37d32Smrg						 NULL,
90600bd37d32Smrg						 NULL)) != 0) {
906120d2c4d2Smrg			break;
90620bd37d32Smrg		    }
9063d522f475Smrg
906420d2c4d2Smrg		}
906520d2c4d2Smrg		s = ns + 1;
9066d522f475Smrg	    }
906720d2c4d2Smrg	    MyStackFree(t, buf);
9068d522f475Smrg	}
9069d522f475Smrg    }
9070d522f475Smrg
90710bd37d32Smrg    if (input->xim == NULL
9072d522f475Smrg	&& (p = XSetLocaleModifiers("@im=none")) != NULL
9073d522f475Smrg	&& *p) {
90740bd37d32Smrg	input->xim = XOpenIM(myDisplay, NULL, NULL, NULL);
9075d522f475Smrg    }
9076d522f475Smrg
90770bd37d32Smrg    if (!input->xim) {
90780bd37d32Smrg	xtermWarning("Failed to open input method\n");
9079d522f475Smrg	return;
9080d522f475Smrg    }
90810bd37d32Smrg    TRACE(("VTInitI18N opened input method:%s\n", NonNull(p)));
9082d522f475Smrg
90830bd37d32Smrg    if (XGetIMValues(input->xim, XNQueryInputStyle, &xim_styles, (void *) 0)
9084d522f475Smrg	|| !xim_styles
9085d522f475Smrg	|| !xim_styles->count_styles) {
90860bd37d32Smrg	xtermWarning("input method doesn't support any style\n");
90870bd37d32Smrg	cleanupInputMethod(xw);
9088956cc18dSsnj	xw->misc.cannot_im = True;
9089d522f475Smrg	return;
9090d522f475Smrg    }
9091d522f475Smrg
9092d522f475Smrg    found = False;
9093956cc18dSsnj    for (s = xw->misc.preedit_type; s && !found;) {
9094d522f475Smrg	while (*s && isspace(CharOf(*s)))
9095d522f475Smrg	    s++;
9096d522f475Smrg	if (!*s)
9097d522f475Smrg	    break;
9098d522f475Smrg	if ((ns = end = strchr(s, ',')) != 0)
9099d522f475Smrg	    ns++;
9100d522f475Smrg	else
9101d522f475Smrg	    end = s + strlen(s);
9102d522f475Smrg	while ((end != s) && isspace(CharOf(end[-1])))
9103d522f475Smrg	    end--;
9104d522f475Smrg
9105d522f475Smrg	if (end != s) {		/* just in case we have a spurious comma */
910620d2c4d2Smrg	    TRACE(("looking for style '%.*s'\n", (int) (end - s), s));
9107d522f475Smrg	    for (i = 0; i < XtNumber(known_style); i++) {
9108d522f475Smrg		if ((int) strlen(known_style[i].name) == (end - s)
910920d2c4d2Smrg		    && !strncmp(s, known_style[i].name, (size_t) (end - s))) {
9110d522f475Smrg		    input_style = known_style[i].code;
9111d522f475Smrg		    for (j = 0; j < xim_styles->count_styles; j++) {
9112d522f475Smrg			if (input_style == xim_styles->supported_styles[j]) {
9113d522f475Smrg			    found = True;
9114d522f475Smrg			    break;
9115d522f475Smrg			}
9116d522f475Smrg		    }
9117d522f475Smrg		    if (found)
9118d522f475Smrg			break;
9119d522f475Smrg		}
9120d522f475Smrg	    }
9121d522f475Smrg	}
9122d522f475Smrg
9123d522f475Smrg	s = ns;
9124d522f475Smrg    }
9125d522f475Smrg    XFree(xim_styles);
9126d522f475Smrg
9127d522f475Smrg    if (!found) {
91280bd37d32Smrg	xtermWarning("input method doesn't support my preedit type (%s)\n",
91290bd37d32Smrg		     xw->misc.preedit_type);
91300bd37d32Smrg	cleanupInputMethod(xw);
9131956cc18dSsnj	xw->misc.cannot_im = True;
9132d522f475Smrg	return;
9133d522f475Smrg    }
9134d522f475Smrg
9135d522f475Smrg    /*
9136d522f475Smrg     * Check for styles we do not yet support.
9137d522f475Smrg     */
9138d522f475Smrg    TRACE(("input_style %#lx\n", input_style));
9139d522f475Smrg    if (input_style == (XIMPreeditArea | XIMStatusArea)) {
91400bd37d32Smrg	xtermWarning("This program doesn't support the 'OffTheSpot' preedit type\n");
91410bd37d32Smrg	cleanupInputMethod(xw);
9142956cc18dSsnj	xw->misc.cannot_im = True;
9143d522f475Smrg	return;
9144d522f475Smrg    }
9145d522f475Smrg
9146d522f475Smrg    /*
9147d522f475Smrg     * For XIMPreeditPosition (or OverTheSpot), XIM client has to
9148d522f475Smrg     * prepare a font.
9149d522f475Smrg     * The font has to be locale-dependent XFontSet, whereas
9150d522f475Smrg     * XTerm use Unicode font.  This leads a problem that the
9151d522f475Smrg     * same font cannot be used for XIM preedit.
9152d522f475Smrg     */
9153d522f475Smrg    if (input_style != (XIMPreeditNothing | XIMStatusNothing)) {
9154d522f475Smrg	XVaNestedList p_list;
9155d522f475Smrg	XPoint spot =
9156d522f475Smrg	{0, 0};
91570bd37d32Smrg
91580bd37d32Smrg	if (xim_create_fs(xw)) {
91590bd37d32Smrg	    p_list = XVaCreateNestedList(0,
91600bd37d32Smrg					 XNSpotLocation, &spot,
91610bd37d32Smrg					 XNFontSet, xw->misc.xim_fs,
91620bd37d32Smrg					 (void *) 0);
91630bd37d32Smrg	    input->xic = XCreateIC(input->xim,
91640bd37d32Smrg				   XNInputStyle, input_style,
91650bd37d32Smrg				   XNClientWindow, myWindow,
91660bd37d32Smrg				   XNFocusWindow, myWindow,
91670bd37d32Smrg				   XNPreeditAttributes, p_list,
91680bd37d32Smrg				   (void *) 0);
9169d522f475Smrg	}
9170d522f475Smrg    } else {
91710bd37d32Smrg	input->xic = XCreateIC(input->xim, XNInputStyle, input_style,
91720bd37d32Smrg			       XNClientWindow, myWindow,
91730bd37d32Smrg			       XNFocusWindow, myWindow,
91740bd37d32Smrg			       (void *) 0);
9175d522f475Smrg    }
9176d522f475Smrg
91770bd37d32Smrg    if (!input->xic) {
91780bd37d32Smrg	xtermWarning("Failed to create input context\n");
91790bd37d32Smrg	cleanupInputMethod(xw);
9180d522f475Smrg    }
9181d522f475Smrg#if defined(USE_XIM_INSTANTIATE_CB)
9182d522f475Smrg    else {
9183d522f475Smrg	XIMCallback destroy_cb;
9184d522f475Smrg
9185d522f475Smrg	destroy_cb.callback = xim_destroy_cb;
9186d522f475Smrg	destroy_cb.client_data = NULL;
91870bd37d32Smrg	if (XSetIMValues(input->xim,
91880bd37d32Smrg			 XNDestroyCallback,
91890bd37d32Smrg			 &destroy_cb,
91900bd37d32Smrg			 (void *) 0)) {
91910bd37d32Smrg	    xtermWarning("Could not set destroy callback to IM\n");
91920bd37d32Smrg	}
9193d522f475Smrg    }
9194d522f475Smrg#endif
9195d522f475Smrg
9196d522f475Smrg    return;
9197d522f475Smrg}
9198d522f475Smrg
91990bd37d32Smrgstatic void
92000bd37d32Smrgxim_real_init(XtermWidget xw)
92010bd37d32Smrg{
92020bd37d32Smrg    xim_create_xic(xw, (Widget) xw);
92030bd37d32Smrg}
92040bd37d32Smrg
9205d522f475Smrgstatic void
9206956cc18dSsnjVTInitI18N(XtermWidget xw)
9207d522f475Smrg{
9208956cc18dSsnj    if (xw->misc.open_im) {
9209956cc18dSsnj	xim_real_init(xw);
9210d522f475Smrg
9211d522f475Smrg#if defined(USE_XIM_INSTANTIATE_CB)
92120bd37d32Smrg	if (lookupTInput(xw, (Widget) xw) == NULL
9213956cc18dSsnj	    && !xw->misc.cannot_im
9214956cc18dSsnj	    && xw->misc.retry_im-- > 0) {
9215d522f475Smrg	    sleep(3);
9216956cc18dSsnj	    XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL,
9217d522f475Smrg					   xim_instantiate_cb, NULL);
9218d522f475Smrg	}
9219d522f475Smrg#endif
9220d522f475Smrg    }
9221d522f475Smrg}
92220bd37d32Smrg
92230bd37d32SmrgTInput *
92240bd37d32SmrglookupTInput(XtermWidget xw, Widget w)
92250bd37d32Smrg{
92260bd37d32Smrg    TInput *result = 0;
92270bd37d32Smrg    unsigned n;
92280bd37d32Smrg
92290bd37d32Smrg    for (n = 0; n < NINPUTWIDGETS; ++n) {
92300bd37d32Smrg	if (xw->misc.inputs[n].w == w) {
92310bd37d32Smrg	    result = xw->misc.inputs + n;
92320bd37d32Smrg	    break;
92330bd37d32Smrg	}
92340bd37d32Smrg    }
92350bd37d32Smrg
92360bd37d32Smrg    return result;
92370bd37d32Smrg}
9238d522f475Smrg#endif /* OPT_I18N_SUPPORT && OPT_INPUT_METHOD */
9239d522f475Smrg
9240a1f3da82Smrgstatic void
9241a1f3da82Smrgset_cursor_outline_gc(XtermWidget xw,
9242a1f3da82Smrg		      Bool filled,
9243a1f3da82Smrg		      Pixel fg,
9244a1f3da82Smrg		      Pixel bg,
9245a1f3da82Smrg		      Pixel cc)
9246a1f3da82Smrg{
9247a1f3da82Smrg    TScreen *screen = TScreenOf(xw);
9248a1f3da82Smrg    VTwin *win = WhichVWin(screen);
9249a1f3da82Smrg    CgsEnum cgsId = gcVTcursOutline;
9250a1f3da82Smrg
9251a1f3da82Smrg    if (cc == bg)
9252a1f3da82Smrg	cc = fg;
9253a1f3da82Smrg
9254a1f3da82Smrg    if (filled) {
9255a1f3da82Smrg	setCgsFore(xw, win, cgsId, bg);
9256a1f3da82Smrg	setCgsBack(xw, win, cgsId, cc);
9257a1f3da82Smrg    } else {
9258a1f3da82Smrg	setCgsFore(xw, win, cgsId, cc);
9259a1f3da82Smrg	setCgsBack(xw, win, cgsId, bg);
9260a1f3da82Smrg    }
9261a1f3da82Smrg}
9262a1f3da82Smrg
9263d522f475Smrgstatic Boolean
9264d522f475SmrgVTSetValues(Widget cur,
9265d522f475Smrg	    Widget request GCC_UNUSED,
9266d522f475Smrg	    Widget wnew,
9267d522f475Smrg	    ArgList args GCC_UNUSED,
9268d522f475Smrg	    Cardinal *num_args GCC_UNUSED)
9269d522f475Smrg{
9270d522f475Smrg    XtermWidget curvt = (XtermWidget) cur;
9271d522f475Smrg    XtermWidget newvt = (XtermWidget) wnew;
92722eaa94a1Schristos    Boolean refresh_needed = False;
92732eaa94a1Schristos    Boolean fonts_redone = False;
9274d522f475Smrg
927520d2c4d2Smrg    if ((T_COLOR(TScreenOf(curvt), TEXT_BG) !=
927620d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), TEXT_BG)) ||
927720d2c4d2Smrg	(T_COLOR(TScreenOf(curvt), TEXT_FG) !=
927820d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), TEXT_FG)) ||
927920d2c4d2Smrg	(TScreenOf(curvt)->MenuFontName(TScreenOf(curvt)->menu_font_number) !=
928020d2c4d2Smrg	 TScreenOf(newvt)->MenuFontName(TScreenOf(newvt)->menu_font_number)) ||
9281d522f475Smrg	(curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)) {
9282d522f475Smrg	if (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)
928320d2c4d2Smrg	    TScreenOf(newvt)->MenuFontName(fontMenu_default) = newvt->misc.default_font.f_n;
9284d522f475Smrg	if (xtermLoadFont(newvt,
928520d2c4d2Smrg			  xtermFontName(TScreenOf(newvt)->MenuFontName(TScreenOf(curvt)->menu_font_number)),
928620d2c4d2Smrg			  True, TScreenOf(newvt)->menu_font_number)) {
9287d522f475Smrg	    /* resizing does the redisplay, so don't ask for it here */
9288d522f475Smrg	    refresh_needed = True;
9289d522f475Smrg	    fonts_redone = True;
9290d522f475Smrg	} else if (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)
929120d2c4d2Smrg	    TScreenOf(newvt)->MenuFontName(fontMenu_default) = curvt->misc.default_font.f_n;
9292d522f475Smrg    }
9293d522f475Smrg    if (!fonts_redone
929420d2c4d2Smrg	&& (T_COLOR(TScreenOf(curvt), TEXT_CURSOR) !=
929520d2c4d2Smrg	    T_COLOR(TScreenOf(newvt), TEXT_CURSOR))) {
9296492d43a5Smrg	if (set_cursor_gcs(newvt))
9297492d43a5Smrg	    refresh_needed = True;
9298d522f475Smrg    }
9299d522f475Smrg    if (curvt->misc.re_verse != newvt->misc.re_verse) {
9300d522f475Smrg	newvt->flags ^= REVERSE_VIDEO;
9301d522f475Smrg	ReverseVideo(newvt);
93022eaa94a1Schristos	/* ReverseVideo toggles */
93032eaa94a1Schristos	newvt->misc.re_verse = (Boolean) (!newvt->misc.re_verse);
9304d522f475Smrg	refresh_needed = True;
9305d522f475Smrg    }
930620d2c4d2Smrg    if ((T_COLOR(TScreenOf(curvt), MOUSE_FG) !=
930720d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), MOUSE_FG)) ||
930820d2c4d2Smrg	(T_COLOR(TScreenOf(curvt), MOUSE_BG) !=
930920d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), MOUSE_BG))) {
931020d2c4d2Smrg	recolor_cursor(TScreenOf(newvt),
931120d2c4d2Smrg		       TScreenOf(newvt)->pointer_cursor,
931220d2c4d2Smrg		       T_COLOR(TScreenOf(newvt), MOUSE_FG),
931320d2c4d2Smrg		       T_COLOR(TScreenOf(newvt), MOUSE_BG));
9314d522f475Smrg	refresh_needed = True;
9315d522f475Smrg    }
9316d522f475Smrg    if (curvt->misc.scrollbar != newvt->misc.scrollbar) {
9317d522f475Smrg	ToggleScrollBar(newvt);
9318d522f475Smrg    }
9319d522f475Smrg
9320d522f475Smrg    return refresh_needed;
9321d522f475Smrg}
9322d522f475Smrg
9323d522f475Smrg#define setGC(code) set_at = __LINE__, currentCgs = code
9324d522f475Smrg
9325d522f475Smrg#define OutsideSelection(screen,srow,scol)  \
9326d522f475Smrg	 ((srow) > (screen)->endH.row || \
9327d522f475Smrg	  ((srow) == (screen)->endH.row && \
9328d522f475Smrg	   (scol) >= (screen)->endH.col) || \
9329d522f475Smrg	  (srow) < (screen)->startH.row || \
9330d522f475Smrg	  ((srow) == (screen)->startH.row && \
9331d522f475Smrg	   (scol) < (screen)->startH.col))
9332d522f475Smrg
9333d522f475Smrg/*
9334d522f475Smrg * Shows cursor at new cursor position in screen.
9335d522f475Smrg */
9336d522f475Smrgvoid
9337d522f475SmrgShowCursor(void)
9338d522f475Smrg{
9339d522f475Smrg    XtermWidget xw = term;
934020d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
9341d522f475Smrg    int x, y;
9342956cc18dSsnj    IChar base;
9343d522f475Smrg    unsigned flags;
9344956cc18dSsnj    CellColor fg_bg = 0;
9345d522f475Smrg    GC currentGC;
934620d2c4d2Smrg    GC outlineGC;
9347d522f475Smrg    CgsEnum currentCgs = gcMAX;
9348d522f475Smrg    VTwin *currentWin = WhichVWin(screen);
9349d522f475Smrg    int set_at;
9350d522f475Smrg    Bool in_selection;
9351d522f475Smrg    Bool reversed;
9352d522f475Smrg    Bool filled;
9353d522f475Smrg    Pixel fg_pix;
9354d522f475Smrg    Pixel bg_pix;
9355d522f475Smrg    Pixel tmp;
9356d522f475Smrg#if OPT_HIGHLIGHT_COLOR
9357d522f475Smrg    Pixel selbg_pix = T_COLOR(screen, HIGHLIGHT_BG);
9358d522f475Smrg    Pixel selfg_pix = T_COLOR(screen, HIGHLIGHT_FG);
9359d522f475Smrg    Boolean use_selbg;
9360d522f475Smrg    Boolean use_selfg;
9361d522f475Smrg#endif
9362d522f475Smrg#if OPT_WIDE_CHARS
9363956cc18dSsnj    size_t off;
9364d522f475Smrg    int my_col = 0;
9365d522f475Smrg#endif
9366d522f475Smrg    int cursor_col;
9367956cc18dSsnj    LineData *ld = 0;
9368d522f475Smrg
9369d522f475Smrg    if (screen->cursor_state == BLINKED_OFF)
9370d522f475Smrg	return;
9371d522f475Smrg
9372d522f475Smrg    if (screen->eventMode != NORMAL)
9373d522f475Smrg	return;
9374d522f475Smrg
9375d522f475Smrg    if (INX2ROW(screen, screen->cur_row) > screen->max_row)
9376d522f475Smrg	return;
9377d522f475Smrg
9378d522f475Smrg    screen->cursorp.row = screen->cur_row;
9379d522f475Smrg    cursor_col = screen->cursorp.col = screen->cur_col;
9380d522f475Smrg    screen->cursor_moved = False;
9381d522f475Smrg
9382d522f475Smrg#ifndef NO_ACTIVE_ICON
9383d522f475Smrg    if (IsIcon(screen)) {
9384d522f475Smrg	screen->cursor_state = ON;
9385d522f475Smrg	return;
9386d522f475Smrg    }
9387d522f475Smrg#endif /* NO_ACTIVE_ICON */
9388d522f475Smrg
9389956cc18dSsnj    ld = getLineData(screen, screen->cur_row);
9390956cc18dSsnj
9391956cc18dSsnj    base = ld->charData[cursor_col];
9392956cc18dSsnj    flags = ld->attribs[cursor_col];
9393d522f475Smrg
9394d522f475Smrg    if_OPT_WIDE_CHARS(screen, {
9395956cc18dSsnj	if (base == HIDDEN_CHAR && cursor_col > 0) {
9396d522f475Smrg	    /* if cursor points to non-initial part of wide character,
9397d522f475Smrg	     * back it up
9398d522f475Smrg	     */
9399d522f475Smrg	    --cursor_col;
9400956cc18dSsnj	    base = ld->charData[cursor_col];
9401d522f475Smrg	}
9402d522f475Smrg	my_col = cursor_col;
9403956cc18dSsnj	if (base == 0)
9404956cc18dSsnj	    base = ' ';
9405956cc18dSsnj	if (isWide((int) base))
9406d522f475Smrg	    my_col += 1;
9407d522f475Smrg    });
9408d522f475Smrg
9409956cc18dSsnj    if (base == 0) {
9410956cc18dSsnj	base = ' ';
9411d522f475Smrg    }
9412956cc18dSsnj#if OPT_ISO_COLORS
9413956cc18dSsnj#ifdef EXP_BOGUS_FG
9414956cc18dSsnj    /*
9415956cc18dSsnj     * If the cursor happens to be on blanks, and we have not set both
9416956cc18dSsnj     * foreground and background color, do not treat it as a colored cell.
9417956cc18dSsnj     */
9418956cc18dSsnj    if (base == ' ') {
9419956cc18dSsnj	if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) {
9420956cc18dSsnj	    TRACE(("ShowCursor - do not treat as a colored cell\n"));
9421956cc18dSsnj	    flags &= ~(FG_COLOR | BG_COLOR);
9422956cc18dSsnj	} else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) {
9423956cc18dSsnj	    TRACE(("ShowCursor - should we treat as a colored cell?\n"));
9424956cc18dSsnj	    if (!(xw->flags & FG_COLOR))
9425956cc18dSsnj		if (CheckBogusForeground(screen, "ShowCursor"))
9426956cc18dSsnj		    flags &= ~(FG_COLOR | BG_COLOR);
9427956cc18dSsnj	}
9428956cc18dSsnj    }
9429956cc18dSsnj#else /* !EXP_BOGUS_FG */
9430d522f475Smrg    /*
9431d522f475Smrg     * If the cursor happens to be on blanks, and the foreground color is set
9432d522f475Smrg     * but not the background, do not treat it as a colored cell.
9433d522f475Smrg     */
94340bd37d32Smrg    if ((flags & TERM_COLOR_FLAGS(xw)) == FG_COLOR
9435956cc18dSsnj	&& base == ' ') {
9436d522f475Smrg	flags &= ~TERM_COLOR_FLAGS(xw);
9437d522f475Smrg    }
9438956cc18dSsnj#endif
9439d522f475Smrg#endif
9440d522f475Smrg
9441d522f475Smrg    /*
9442d522f475Smrg     * Compare the current cell to the last set of colors used for the
9443d522f475Smrg     * cursor and update the GC's if needed.
9444d522f475Smrg     */
9445956cc18dSsnj    if_OPT_ISO_COLORS(screen, {
9446956cc18dSsnj	fg_bg = ld->color[cursor_col];
9447d522f475Smrg    });
944820d2c4d2Smrg
9449d522f475Smrg    fg_pix = getXtermForeground(xw, flags, extract_fg(xw, fg_bg, flags));
9450d522f475Smrg    bg_pix = getXtermBackground(xw, flags, extract_bg(xw, fg_bg, flags));
9451d522f475Smrg
94520bd37d32Smrg    /*
94530bd37d32Smrg     * If we happen to have the same foreground/background colors, choose
94540bd37d32Smrg     * a workable foreground color from which we can obtain a visible cursor.
94550bd37d32Smrg     */
94560bd37d32Smrg    if (fg_pix == bg_pix) {
94570bd37d32Smrg	long bg_diff = (long) (bg_pix - T_COLOR(TScreenOf(xw), TEXT_BG));
94580bd37d32Smrg	long fg_diff = (long) (bg_pix - T_COLOR(TScreenOf(xw), TEXT_FG));
94590bd37d32Smrg	if (bg_diff < 0)
94600bd37d32Smrg	    bg_diff = -bg_diff;
94610bd37d32Smrg	if (fg_diff < 0)
94620bd37d32Smrg	    fg_diff = -fg_diff;
94630bd37d32Smrg	if (bg_diff < fg_diff) {
94640bd37d32Smrg	    fg_pix = T_COLOR(TScreenOf(xw), TEXT_FG);
94650bd37d32Smrg	} else {
94660bd37d32Smrg	    fg_pix = T_COLOR(TScreenOf(xw), TEXT_BG);
94670bd37d32Smrg	}
94680bd37d32Smrg    }
94690bd37d32Smrg
9470d522f475Smrg    if (OutsideSelection(screen, screen->cur_row, screen->cur_col))
9471d522f475Smrg	in_selection = False;
9472d522f475Smrg    else
9473d522f475Smrg	in_selection = True;
9474d522f475Smrg
9475d522f475Smrg    reversed = ReverseOrHilite(screen, flags, in_selection);
9476d522f475Smrg
9477d522f475Smrg    /* This is like updatedXtermGC(), except that we have to worry about
9478d522f475Smrg     * whether the window has focus, since in that case we want just an
9479d522f475Smrg     * outline for the cursor.
9480d522f475Smrg     */
94810bd37d32Smrg    filled = (screen->select || screen->always_highlight) && isCursorBlock(screen);
9482d522f475Smrg#if OPT_HIGHLIGHT_COLOR
9483d522f475Smrg    use_selbg = isNotForeground(xw, fg_pix, bg_pix, selbg_pix);
9484d522f475Smrg    use_selfg = isNotBackground(xw, fg_pix, bg_pix, selfg_pix);
9485d522f475Smrg#endif
9486d522f475Smrg    if (filled) {
9487d522f475Smrg	if (reversed) {		/* text is reverse video */
9488d522f475Smrg	    if (getCgsGC(xw, currentWin, gcVTcursNormal)) {
9489d522f475Smrg		setGC(gcVTcursNormal);
9490d522f475Smrg	    } else {
9491d522f475Smrg		if (flags & BOLDATTR(screen)) {
9492d522f475Smrg		    setGC(gcBold);
9493d522f475Smrg		} else {
9494d522f475Smrg		    setGC(gcNorm);
9495d522f475Smrg		}
9496d522f475Smrg	    }
9497d522f475Smrg	    EXCHANGE(fg_pix, bg_pix, tmp);
9498d522f475Smrg#if OPT_HIGHLIGHT_COLOR
9499d522f475Smrg	    if (screen->hilite_reverse) {
9500d522f475Smrg		if (use_selbg && !use_selfg)
9501d522f475Smrg		    fg_pix = bg_pix;
9502d522f475Smrg		if (use_selfg && !use_selbg)
9503d522f475Smrg		    bg_pix = fg_pix;
9504d522f475Smrg		if (use_selbg)
9505d522f475Smrg		    bg_pix = selbg_pix;
9506d522f475Smrg		if (use_selfg)
9507d522f475Smrg		    fg_pix = selfg_pix;
9508d522f475Smrg	    }
9509d522f475Smrg#endif
9510d522f475Smrg	} else {		/* normal video */
9511d522f475Smrg	    if (getCgsGC(xw, currentWin, gcVTcursReverse)) {
9512d522f475Smrg		setGC(gcVTcursReverse);
9513d522f475Smrg	    } else {
9514d522f475Smrg		if (flags & BOLDATTR(screen)) {
9515d522f475Smrg		    setGC(gcBoldReverse);
9516d522f475Smrg		} else {
9517d522f475Smrg		    setGC(gcNormReverse);
9518d522f475Smrg		}
9519d522f475Smrg	    }
9520d522f475Smrg	}
9521d522f475Smrg	if (T_COLOR(screen, TEXT_CURSOR) == xw->dft_foreground) {
9522d522f475Smrg	    setCgsBack(xw, currentWin, currentCgs, fg_pix);
9523d522f475Smrg	}
9524d522f475Smrg	setCgsFore(xw, currentWin, currentCgs, bg_pix);
9525d522f475Smrg    } else {			/* not selected */
9526d522f475Smrg	if (reversed) {		/* text is reverse video */
9527d522f475Smrg	    EXCHANGE(fg_pix, bg_pix, tmp);
9528d522f475Smrg	    setGC(gcNormReverse);
9529d522f475Smrg	} else {		/* normal video */
9530d522f475Smrg	    setGC(gcNorm);
9531d522f475Smrg	}
9532d522f475Smrg#if OPT_HIGHLIGHT_COLOR
9533d522f475Smrg	if (screen->hilite_reverse) {
9534d522f475Smrg	    if (in_selection && !reversed) {
9535a1f3da82Smrg		/* EMPTY */
9536a1f3da82Smrg		/* really INVERSE ... */
9537a1f3da82Smrg		;
9538d522f475Smrg	    } else if (in_selection || reversed) {
9539d522f475Smrg		if (use_selbg) {
9540d522f475Smrg		    if (use_selfg) {
9541d522f475Smrg			bg_pix = fg_pix;
9542d522f475Smrg		    } else {
9543d522f475Smrg			fg_pix = bg_pix;
9544d522f475Smrg		    }
9545d522f475Smrg		}
9546d522f475Smrg		if (use_selbg) {
9547d522f475Smrg		    bg_pix = selbg_pix;
9548d522f475Smrg		}
9549d522f475Smrg		if (use_selfg) {
9550d522f475Smrg		    fg_pix = selfg_pix;
9551d522f475Smrg		}
9552d522f475Smrg	    }
9553d522f475Smrg	} else {
9554d522f475Smrg	    if (in_selection) {
9555d522f475Smrg		if (use_selbg) {
9556d522f475Smrg		    bg_pix = selbg_pix;
9557d522f475Smrg		}
9558d522f475Smrg		if (use_selfg) {
9559d522f475Smrg		    fg_pix = selfg_pix;
9560d522f475Smrg		}
9561d522f475Smrg	    }
9562d522f475Smrg	}
9563d522f475Smrg#endif
9564d522f475Smrg	setCgsFore(xw, currentWin, currentCgs, fg_pix);
9565d522f475Smrg	setCgsBack(xw, currentWin, currentCgs, bg_pix);
9566d522f475Smrg    }
9567d522f475Smrg
9568d522f475Smrg    if (screen->cursor_busy == 0
9569d522f475Smrg	&& (screen->cursor_state != ON || screen->cursor_GC != set_at)) {
9570d522f475Smrg
9571d522f475Smrg	screen->cursor_GC = set_at;
957220d2c4d2Smrg	TRACE(("ShowCursor calling drawXtermText cur(%d,%d) %s-%s, set_at %d\n",
9573d522f475Smrg	       screen->cur_row, screen->cur_col,
957420d2c4d2Smrg	       (filled ? "filled" : "outline"),
95750bd37d32Smrg	       (isCursorBlock(screen) ? "box" :
95760bd37d32Smrg		isCursorUnderline(screen) ? "underline" : "bar"),
957720d2c4d2Smrg	       set_at));
9578d522f475Smrg
9579d522f475Smrg	currentGC = getCgsGC(xw, currentWin, currentCgs);
958020d2c4d2Smrg	x = LineCursorX(screen, ld, cursor_col);
958120d2c4d2Smrg	y = CursorY(screen, screen->cur_row);
9582d522f475Smrg
95830bd37d32Smrg	if (!isCursorBlock(screen)) {
958420d2c4d2Smrg	    /*
9585a1f3da82Smrg	     * Overriding the combination of filled, reversed, in_selection is
95860bd37d32Smrg	     * too complicated since the underline or bar and the text-cell use
958720d2c4d2Smrg	     * different rules.  Just redraw the text-cell, and draw the
95880bd37d32Smrg	     * underline or bar on top of it.
958920d2c4d2Smrg	     */
959020d2c4d2Smrg	    HideCursor();
959120d2c4d2Smrg
959220d2c4d2Smrg	    /*
959320d2c4d2Smrg	     * Our current-GC is likely to have been modified in HideCursor().
9594a1f3da82Smrg	     * Set up a new request.
959520d2c4d2Smrg	     */
959620d2c4d2Smrg	    if (filled) {
959720d2c4d2Smrg		if (T_COLOR(screen, TEXT_CURSOR) == xw->dft_foreground) {
959820d2c4d2Smrg		    setCgsBack(xw, currentWin, currentCgs, fg_pix);
959920d2c4d2Smrg		}
960020d2c4d2Smrg		setCgsFore(xw, currentWin, currentCgs, bg_pix);
960120d2c4d2Smrg	    } else {
960220d2c4d2Smrg		setCgsFore(xw, currentWin, currentCgs, fg_pix);
960320d2c4d2Smrg		setCgsBack(xw, currentWin, currentCgs, bg_pix);
9604d522f475Smrg	    }
9605a1f3da82Smrg	}
9606a1f3da82Smrg
9607a1f3da82Smrg	/*
9608a1f3da82Smrg	 * Update the outline-gc, to keep the cursor color distinct from the
9609a1f3da82Smrg	 * background color.
9610a1f3da82Smrg	 */
9611a1f3da82Smrg	set_cursor_outline_gc(xw,
9612a1f3da82Smrg			      filled,
9613a1f3da82Smrg			      fg_pix,
9614a1f3da82Smrg			      bg_pix,
9615a1f3da82Smrg			      T_COLOR(screen, TEXT_CURSOR));
9616d522f475Smrg
9617a1f3da82Smrg	outlineGC = getCgsGC(xw, currentWin, gcVTcursOutline);
9618a1f3da82Smrg	if (outlineGC == 0)
9619a1f3da82Smrg	    outlineGC = currentGC;
9620a1f3da82Smrg
96210bd37d32Smrg	if (isCursorUnderline(screen)) {
9622d522f475Smrg
962320d2c4d2Smrg	    /*
962420d2c4d2Smrg	     * Finally, draw the underline.
962520d2c4d2Smrg	     */
96262eaa94a1Schristos	    screen->box->x = (short) x;
962720d2c4d2Smrg	    screen->box->y = (short) (y + FontHeight(screen) - 2);
96280bd37d32Smrg	    XDrawLines(screen->display, VDrawable(screen), outlineGC,
96290bd37d32Smrg		       screen->box, NBOX, CoordModePrevious);
96300bd37d32Smrg	} else if (isCursorBar(screen)) {
96310bd37d32Smrg
96320bd37d32Smrg	    /*
96330bd37d32Smrg	     * Or draw the bar.
96340bd37d32Smrg	     */
96350bd37d32Smrg	    screen->box->x = (short) x;
96360bd37d32Smrg	    screen->box->y = (short) y;
9637d522f475Smrg	    XDrawLines(screen->display, VWindow(screen), outlineGC,
9638d522f475Smrg		       screen->box, NBOX, CoordModePrevious);
963920d2c4d2Smrg	} else {
964020d2c4d2Smrg
964120d2c4d2Smrg	    drawXtermText(xw, flags & DRAWX_MASK,
964220d2c4d2Smrg			  currentGC, x, y,
964320d2c4d2Smrg			  LineCharSet(screen, ld),
964420d2c4d2Smrg			  &base, 1, 0);
964520d2c4d2Smrg
964620d2c4d2Smrg#if OPT_WIDE_CHARS
964720d2c4d2Smrg	    if_OPT_WIDE_CHARS(screen, {
964820d2c4d2Smrg		for_each_combData(off, ld) {
964920d2c4d2Smrg		    if (!(ld->combData[off][my_col]))
965020d2c4d2Smrg			break;
965120d2c4d2Smrg		    drawXtermText(xw, (flags & DRAWX_MASK) | NOBACKGROUND,
965220d2c4d2Smrg				  currentGC, x, y,
965320d2c4d2Smrg				  LineCharSet(screen, ld),
965420d2c4d2Smrg				  ld->combData[off] + my_col,
965520d2c4d2Smrg				  1, isWide((int) base));
965620d2c4d2Smrg		}
965720d2c4d2Smrg	    });
965820d2c4d2Smrg#endif
965920d2c4d2Smrg
966020d2c4d2Smrg	    if (!filled) {
966120d2c4d2Smrg		screen->box->x = (short) x;
966220d2c4d2Smrg		screen->box->y = (short) y;
96630bd37d32Smrg		XDrawLines(screen->display, VDrawable(screen), outlineGC,
966420d2c4d2Smrg			   screen->box, NBOX, CoordModePrevious);
966520d2c4d2Smrg	    }
9666d522f475Smrg	}
9667d522f475Smrg    }
9668d522f475Smrg    screen->cursor_state = ON;
9669956cc18dSsnj
9670956cc18dSsnj    return;
9671d522f475Smrg}
9672d522f475Smrg
9673d522f475Smrg/*
9674d522f475Smrg * hide cursor at previous cursor position in screen.
9675d522f475Smrg */
9676d522f475Smrgvoid
9677d522f475SmrgHideCursor(void)
9678d522f475Smrg{
9679d522f475Smrg    XtermWidget xw = term;
968020d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
9681d522f475Smrg    GC currentGC;
9682d522f475Smrg    int x, y;
9683956cc18dSsnj    IChar base;
9684956cc18dSsnj    unsigned flags;
9685956cc18dSsnj    CellColor fg_bg = 0;
9686d522f475Smrg    Bool in_selection;
9687d522f475Smrg#if OPT_WIDE_CHARS
9688956cc18dSsnj    size_t off;
9689d522f475Smrg    int my_col = 0;
9690d522f475Smrg#endif
9691d522f475Smrg    int cursor_col;
9692956cc18dSsnj    LineData *ld = 0;
9693d522f475Smrg
969420d2c4d2Smrg    if (screen->cursor_state == OFF)
9695d522f475Smrg	return;
9696d522f475Smrg    if (INX2ROW(screen, screen->cursorp.row) > screen->max_row)
9697d522f475Smrg	return;
9698d522f475Smrg
9699d522f475Smrg    cursor_col = screen->cursorp.col;
9700d522f475Smrg
9701d522f475Smrg#ifndef NO_ACTIVE_ICON
9702d522f475Smrg    if (IsIcon(screen)) {
9703d522f475Smrg	screen->cursor_state = OFF;
9704d522f475Smrg	return;
9705d522f475Smrg    }
9706d522f475Smrg#endif /* NO_ACTIVE_ICON */
9707d522f475Smrg
9708956cc18dSsnj    ld = getLineData(screen, screen->cursorp.row);
9709956cc18dSsnj
9710956cc18dSsnj    base = ld->charData[cursor_col];
9711956cc18dSsnj    flags = ld->attribs[cursor_col];
9712d522f475Smrg
9713d522f475Smrg    if_OPT_WIDE_CHARS(screen, {
9714956cc18dSsnj	if (base == HIDDEN_CHAR && cursor_col > 0) {
9715d522f475Smrg	    /* if cursor points to non-initial part of wide character,
9716d522f475Smrg	     * back it up
9717d522f475Smrg	     */
9718d522f475Smrg	    --cursor_col;
9719956cc18dSsnj	    base = ld->charData[cursor_col];
9720d522f475Smrg	}
9721d522f475Smrg	my_col = cursor_col;
9722956cc18dSsnj	if (base == 0)
9723956cc18dSsnj	    base = ' ';
9724956cc18dSsnj	if (isWide((int) base))
9725d522f475Smrg	    my_col += 1;
9726d522f475Smrg    });
9727d522f475Smrg
9728956cc18dSsnj    if (base == 0) {
9729956cc18dSsnj	base = ' ';
9730956cc18dSsnj    }
9731956cc18dSsnj#ifdef EXP_BOGUS_FG
9732956cc18dSsnj    /*
9733956cc18dSsnj     * If the cursor happens to be on blanks, and we have not set both
9734956cc18dSsnj     * foreground and background color, do not treat it as a colored cell.
9735956cc18dSsnj     */
9736956cc18dSsnj#if OPT_ISO_COLORS
9737956cc18dSsnj    if (base == ' ') {
9738956cc18dSsnj	if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) {
9739956cc18dSsnj	    TRACE(("HideCursor - do not treat as a colored cell\n"));
9740956cc18dSsnj	    flags &= ~(FG_COLOR | BG_COLOR);
9741956cc18dSsnj	} else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) {
9742956cc18dSsnj	    TRACE(("HideCursor - should we treat as a colored cell?\n"));
9743956cc18dSsnj	    if (!(xw->flags & FG_COLOR))
9744956cc18dSsnj		if (CheckBogusForeground(screen, "HideCursor"))
9745956cc18dSsnj		    flags &= ~(FG_COLOR | BG_COLOR);
9746956cc18dSsnj	}
9747956cc18dSsnj    }
9748956cc18dSsnj#endif
9749956cc18dSsnj#endif
9750956cc18dSsnj#if OPT_ISO_COLORS
9751956cc18dSsnj    fg_bg = 0;
9752956cc18dSsnj#endif
9753956cc18dSsnj
9754956cc18dSsnj    /*
9755956cc18dSsnj     * Compare the current cell to the last set of colors used for the
9756956cc18dSsnj     * cursor and update the GC's if needed.
9757956cc18dSsnj     */
9758956cc18dSsnj    if_OPT_ISO_COLORS(screen, {
9759956cc18dSsnj	fg_bg = ld->color[cursor_col];
9760d522f475Smrg    });
9761d522f475Smrg
9762d522f475Smrg    if (OutsideSelection(screen, screen->cursorp.row, screen->cursorp.col))
9763d522f475Smrg	in_selection = False;
9764d522f475Smrg    else
9765d522f475Smrg	in_selection = True;
9766d522f475Smrg
9767d522f475Smrg    currentGC = updatedXtermGC(xw, flags, fg_bg, in_selection);
9768d522f475Smrg
9769d522f475Smrg    TRACE(("HideCursor calling drawXtermText cur(%d,%d)\n",
9770d522f475Smrg	   screen->cursorp.row, screen->cursorp.col));
977120d2c4d2Smrg
977220d2c4d2Smrg    x = LineCursorX(screen, ld, cursor_col);
977320d2c4d2Smrg    y = CursorY(screen, screen->cursorp.row);
977420d2c4d2Smrg
977520d2c4d2Smrg    drawXtermText(xw, flags & DRAWX_MASK,
977620d2c4d2Smrg		  currentGC, x, y,
9777956cc18dSsnj		  LineCharSet(screen, ld),
9778956cc18dSsnj		  &base, 1, 0);
9779d522f475Smrg
9780d522f475Smrg#if OPT_WIDE_CHARS
9781d522f475Smrg    if_OPT_WIDE_CHARS(screen, {
9782956cc18dSsnj	for_each_combData(off, ld) {
9783956cc18dSsnj	    if (!(ld->combData[off][my_col]))
9784d522f475Smrg		break;
9785d522f475Smrg	    drawXtermText(xw, (flags & DRAWX_MASK) | NOBACKGROUND,
9786d522f475Smrg			  currentGC, x, y,
9787956cc18dSsnj			  LineCharSet(screen, ld),
9788956cc18dSsnj			  ld->combData[off] + my_col,
9789956cc18dSsnj			  1, isWide((int) base));
9790d522f475Smrg	}
9791d522f475Smrg    });
9792d522f475Smrg#endif
9793d522f475Smrg    screen->cursor_state = OFF;
9794d522f475Smrg    resetXtermGC(xw, flags, in_selection);
9795956cc18dSsnj
9796e0a2b6dfSmrg    refresh_displayed_graphics(screen,
9797e0a2b6dfSmrg			       screen->cursorp.col,
9798e0a2b6dfSmrg			       screen->cursorp.row,
9799e0a2b6dfSmrg			       1, 1);
9800e0a2b6dfSmrg
9801956cc18dSsnj    return;
9802d522f475Smrg}
9803d522f475Smrg
9804d522f475Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
9805d522f475Smrgstatic void
9806e0a2b6dfSmrgStartBlinking(TScreen *screen)
9807d522f475Smrg{
9808d522f475Smrg    if (screen->blink_timer == 0) {
98092eaa94a1Schristos	unsigned long interval = (unsigned long) ((screen->cursor_state == ON)
98102eaa94a1Schristos						  ? screen->blink_on
98112eaa94a1Schristos						  : screen->blink_off);
9812d522f475Smrg	if (interval == 0)	/* wow! */
9813d522f475Smrg	    interval = 1;	/* let's humor him anyway */
9814d522f475Smrg	screen->blink_timer = XtAppAddTimeOut(app_con,
9815d522f475Smrg					      interval,
9816d522f475Smrg					      HandleBlinking,
9817d522f475Smrg					      screen);
9818d522f475Smrg    }
9819d522f475Smrg}
9820d522f475Smrg
9821d522f475Smrgstatic void
9822e0a2b6dfSmrgStopBlinking(TScreen *screen)
9823d522f475Smrg{
9824e39b573cSmrg    if (screen->blink_timer) {
9825d522f475Smrg	XtRemoveTimeOut(screen->blink_timer);
9826e39b573cSmrg	screen->blink_timer = 0;
9827e39b573cSmrg	reallyStopBlinking(screen);
9828e39b573cSmrg    } else {
9829e39b573cSmrg	screen->blink_timer = 0;
9830e39b573cSmrg    }
9831d522f475Smrg}
9832d522f475Smrg
9833d522f475Smrg#if OPT_BLINK_TEXT
98340bd37d32SmrgBool
9835e0a2b6dfSmrgLineHasBlinking(TScreen *screen, LineData *ld)
9836d522f475Smrg{
9837d522f475Smrg    int col;
9838d522f475Smrg    Bool result = False;
9839d522f475Smrg
9840d522f475Smrg    for (col = 0; col < MaxCols(screen); ++col) {
9841956cc18dSsnj	if (ld->attribs[col] & BLINK) {
9842d522f475Smrg	    result = True;
9843d522f475Smrg	    break;
9844d522f475Smrg	}
9845d522f475Smrg    }
9846d522f475Smrg    return result;
9847d522f475Smrg}
9848d522f475Smrg#endif
9849d522f475Smrg
9850d522f475Smrg/*
9851d522f475Smrg * Blink the cursor by alternately showing/hiding cursor.  We leave the timer
9852d522f475Smrg * running all the time (even though that's a little inefficient) to make the
9853d522f475Smrg * logic simple.
9854d522f475Smrg */
9855d522f475Smrgstatic void
9856d522f475SmrgHandleBlinking(XtPointer closure, XtIntervalId * id GCC_UNUSED)
9857d522f475Smrg{
9858d522f475Smrg    TScreen *screen = (TScreen *) closure;
9859d522f475Smrg    Bool resume = False;
9860d522f475Smrg
9861d522f475Smrg    screen->blink_timer = 0;
9862d522f475Smrg    screen->blink_state = !screen->blink_state;
9863d522f475Smrg
9864d522f475Smrg#if OPT_BLINK_CURS
9865d522f475Smrg    if (DoStartBlinking(screen)) {
9866d522f475Smrg	if (screen->cursor_state == ON) {
9867d522f475Smrg	    if (screen->select || screen->always_highlight) {
9868d522f475Smrg		HideCursor();
9869d522f475Smrg		if (screen->cursor_state == OFF)
9870d522f475Smrg		    screen->cursor_state = BLINKED_OFF;
9871d522f475Smrg	    }
9872d522f475Smrg	} else if (screen->cursor_state == BLINKED_OFF) {
9873d522f475Smrg	    screen->cursor_state = OFF;
9874d522f475Smrg	    ShowCursor();
9875d522f475Smrg	    if (screen->cursor_state == OFF)
9876d522f475Smrg		screen->cursor_state = BLINKED_OFF;
9877d522f475Smrg	}
9878d522f475Smrg	resume = True;
9879d522f475Smrg    }
9880d522f475Smrg#endif
9881d522f475Smrg
9882d522f475Smrg#if OPT_BLINK_TEXT
9883d522f475Smrg    /*
988420d2c4d2Smrg     * Inspect the lines on the current screen to see if any have the BLINK flag
9885d522f475Smrg     * associated with them.  Prune off any that have had the corresponding
9886d522f475Smrg     * cells reset.  If any are left, repaint those lines with ScrnRefresh().
9887d522f475Smrg     */
9888d522f475Smrg    if (!(screen->blink_as_bold)) {
9889d522f475Smrg	int row;
9890d522f475Smrg	int first_row = screen->max_row;
9891d522f475Smrg	int last_row = -1;
9892d522f475Smrg
9893d522f475Smrg	for (row = screen->max_row; row >= 0; row--) {
9894956cc18dSsnj	    LineData *ld = getLineData(screen, ROW2INX(screen, row));
989520d2c4d2Smrg
989620d2c4d2Smrg	    if (ld != 0 && LineTstBlinked(ld)) {
9897956cc18dSsnj		if (LineHasBlinking(screen, ld)) {
9898d522f475Smrg		    resume = True;
9899d522f475Smrg		    if (row > last_row)
9900d522f475Smrg			last_row = row;
9901d522f475Smrg		    if (row < first_row)
9902d522f475Smrg			first_row = row;
9903d522f475Smrg		} else {
9904956cc18dSsnj		    LineClrBlinked(ld);
9905d522f475Smrg		}
9906d522f475Smrg	    }
9907d522f475Smrg	}
9908d522f475Smrg	/*
9909d522f475Smrg	 * FIXME: this could be a little more efficient, e.g,. by limiting the
9910d522f475Smrg	 * columns which are updated.
9911d522f475Smrg	 */
9912d522f475Smrg	if (first_row <= last_row) {
9913d522f475Smrg	    ScrnRefresh(term,
9914d522f475Smrg			first_row,
9915d522f475Smrg			0,
9916d522f475Smrg			last_row + 1 - first_row,
9917d522f475Smrg			MaxCols(screen),
9918d522f475Smrg			True);
9919d522f475Smrg	}
9920d522f475Smrg    }
9921d522f475Smrg#endif
9922d522f475Smrg
9923d522f475Smrg    /*
9924d522f475Smrg     * If either the cursor or text is blinking, restart the timer.
9925d522f475Smrg     */
9926d522f475Smrg    if (resume)
9927d522f475Smrg	StartBlinking(screen);
9928d522f475Smrg}
9929d522f475Smrg#endif /* OPT_BLINK_CURS || OPT_BLINK_TEXT */
9930d522f475Smrg
993120d2c4d2Smrgvoid
9932e0a2b6dfSmrgRestartBlinking(TScreen *screen GCC_UNUSED)
993320d2c4d2Smrg{
993420d2c4d2Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
993520d2c4d2Smrg    if (screen->blink_timer == 0) {
993620d2c4d2Smrg	Bool resume = False;
993720d2c4d2Smrg
993820d2c4d2Smrg#if OPT_BLINK_CURS
993920d2c4d2Smrg	if (DoStartBlinking(screen)) {
994020d2c4d2Smrg	    resume = True;
994120d2c4d2Smrg	}
994220d2c4d2Smrg#endif
994320d2c4d2Smrg#if OPT_BLINK_TEXT
994420d2c4d2Smrg	if (!resume) {
994520d2c4d2Smrg	    int row;
994620d2c4d2Smrg
994720d2c4d2Smrg	    for (row = screen->max_row; row >= 0; row--) {
994820d2c4d2Smrg		LineData *ld = getLineData(screen, ROW2INX(screen, row));
994920d2c4d2Smrg
995020d2c4d2Smrg		if (ld != 0 && LineTstBlinked(ld)) {
995120d2c4d2Smrg		    if (LineHasBlinking(screen, ld)) {
995220d2c4d2Smrg			resume = True;
995320d2c4d2Smrg			break;
995420d2c4d2Smrg		    }
995520d2c4d2Smrg		}
995620d2c4d2Smrg	    }
995720d2c4d2Smrg	}
995820d2c4d2Smrg#endif
995920d2c4d2Smrg	if (resume)
996020d2c4d2Smrg	    StartBlinking(screen);
996120d2c4d2Smrg    }
996220d2c4d2Smrg#endif
996320d2c4d2Smrg}
996420d2c4d2Smrg
9965d522f475Smrg/*
9966d522f475Smrg * Implement soft or hard (full) reset of the VTxxx emulation.  There are a
9967d522f475Smrg * couple of differences from real DEC VTxxx terminals (to avoid breaking
9968d522f475Smrg * applications which have come to rely on xterm doing this):
9969d522f475Smrg *
9970d522f475Smrg *	+ autowrap mode should be reset (instead it's reset to the resource
9971d522f475Smrg *	  default).
9972d522f475Smrg *	+ the popup menu offers a choice of resetting the savedLines, or not.
9973d522f475Smrg *	  (but the control sequence does this anyway).
9974d522f475Smrg */
9975e39b573cSmrgstatic void
9976e39b573cSmrgReallyReset(XtermWidget xw, Bool full, Bool saved)
9977d522f475Smrg{
997820d2c4d2Smrg    static char empty[1];
997920d2c4d2Smrg
998020d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
9981d522f475Smrg
9982d522f475Smrg    if (!XtIsRealized((Widget) xw) || (CURRENT_EMU() != (Widget) xw)) {
998320d2c4d2Smrg	Bell(xw, XkbBI_MinorError, 0);
9984d522f475Smrg	return;
9985d522f475Smrg    }
9986d522f475Smrg
9987d522f475Smrg    if (saved) {
9988d522f475Smrg	screen->savedlines = 0;
9989d522f475Smrg	ScrollBarDrawThumb(screen->scrollWidget);
9990d522f475Smrg    }
9991d522f475Smrg
9992d522f475Smrg    /* make cursor visible */
9993d522f475Smrg    screen->cursor_set = ON;
9994d522f475Smrg
9995d522f475Smrg    /* reset scrolling region */
99960bd37d32Smrg    reset_margins(screen);
9997d522f475Smrg
9998d522f475Smrg    bitclr(&xw->flags, ORIGIN);
9999d522f475Smrg
10000d522f475Smrg    if_OPT_ISO_COLORS(screen, {
10001d522f475Smrg	reset_SGR_Colors(xw);
1000220d2c4d2Smrg	if (ResetAnsiColorRequest(xw, empty, 0))
1000320d2c4d2Smrg	    xtermRepaint(xw);
10004d522f475Smrg    });
10005d522f475Smrg
10006d522f475Smrg    /* Reset character-sets to initial state */
10007d522f475Smrg    resetCharsets(screen);
10008d522f475Smrg
10009d522f475Smrg#if OPT_MOD_FKEYS
10010d522f475Smrg    /* Reset modifier-resources to initial state */
10011d522f475Smrg    xw->keyboard.modify_now = xw->keyboard.modify_1st;
10012d522f475Smrg#endif
10013d522f475Smrg
10014d522f475Smrg    /* Reset DECSCA */
10015d522f475Smrg    bitclr(&xw->flags, PROTECTED);
10016d522f475Smrg    screen->protected_mode = OFF_PROTECT;
10017d522f475Smrg
10018e0a2b6dfSmrg    reset_displayed_graphics(screen);
10019e0a2b6dfSmrg
10020d522f475Smrg    if (full) {			/* RIS */
10021d522f475Smrg	if (screen->bellOnReset)
1002220d2c4d2Smrg	    Bell(xw, XkbBI_TerminalBell, 0);
10023d522f475Smrg
10024d522f475Smrg	/* reset the mouse mode */
10025d522f475Smrg	screen->send_mouse_pos = MOUSE_OFF;
10026d522f475Smrg	screen->send_focus_pos = OFF;
100270bd37d32Smrg	screen->extend_coords = 0;
10028d522f475Smrg	screen->waitingForTrackInfo = False;
10029d522f475Smrg	screen->eventMode = NORMAL;
10030d522f475Smrg
10031d522f475Smrg	xtermShowPointer(xw, True);
10032d522f475Smrg
10033d522f475Smrg	TabReset(xw->tabs);
10034d522f475Smrg	xw->keyboard.flags = MODE_SRM;
10035d522f475Smrg#if OPT_INITIAL_ERASE
10036d522f475Smrg	if (xw->keyboard.reset_DECBKM == 1)
10037d522f475Smrg	    xw->keyboard.flags |= MODE_DECBKM;
10038d522f475Smrg	else if (xw->keyboard.reset_DECBKM == 2)
10039d522f475Smrg#endif
1004020d2c4d2Smrg	    if (TScreenOf(xw)->backarrow_key)
10041d522f475Smrg		xw->keyboard.flags |= MODE_DECBKM;
10042d522f475Smrg	TRACE(("full reset DECBKM %s\n",
10043d522f475Smrg	       BtoS(xw->keyboard.flags & MODE_DECBKM)));
10044e0a2b6dfSmrg#if OPT_SIXEL_GRAPHICS
10045e0a2b6dfSmrg	if (TScreenOf(xw)->sixel_scrolling)	/* FIXME: should this be off unconditionally here? */
10046e0a2b6dfSmrg	    xw->keyboard.flags |= MODE_DECSDM;
10047e0a2b6dfSmrg	TRACE(("full reset DECSDM %s (resource default is %d)\n",
10048e0a2b6dfSmrg	       BtoS(xw->keyboard.flags & MODE_DECSDM),
10049e0a2b6dfSmrg	       TScreenOf(xw)->sixel_scrolling));
10050e0a2b6dfSmrg#endif
10051d522f475Smrg	update_appcursor();
10052d522f475Smrg	update_appkeypad();
10053d522f475Smrg	update_decbkm();
10054e0a2b6dfSmrg	update_decsdm();
10055d522f475Smrg	show_8bit_control(False);
10056d522f475Smrg	reset_decudk();
10057d522f475Smrg
10058d522f475Smrg	FromAlternate(xw);
10059d522f475Smrg	ClearScreen(xw);
10060d522f475Smrg	screen->cursor_state = OFF;
10061d522f475Smrg	if (xw->flags & REVERSE_VIDEO)
10062d522f475Smrg	    ReverseVideo(xw);
10063d522f475Smrg
10064d522f475Smrg	xw->flags = xw->initflags;
10065d522f475Smrg	update_reversevideo();
10066d522f475Smrg	update_autowrap();
10067d522f475Smrg	update_reversewrap();
10068d522f475Smrg	update_autolinefeed();
10069d522f475Smrg
100702eaa94a1Schristos	screen->jumpscroll = (Boolean) (!(xw->flags & SMOOTHSCROLL));
10071d522f475Smrg	update_jumpscroll();
10072d522f475Smrg
10073d522f475Smrg	if (screen->c132 && (xw->flags & IN132COLUMNS)) {
100742eaa94a1Schristos	    Dimension reqWidth = (Dimension) (80 * FontWidth(screen)
100752eaa94a1Schristos					      + 2 * screen->border
100762eaa94a1Schristos					      + ScrollbarWidth(screen));
100772eaa94a1Schristos	    Dimension reqHeight = (Dimension) (FontHeight(screen)
100782eaa94a1Schristos					       * MaxRows(screen)
100792eaa94a1Schristos					       + 2 * screen->border);
10080d522f475Smrg	    Dimension replyWidth;
10081d522f475Smrg	    Dimension replyHeight;
10082d522f475Smrg
10083d522f475Smrg	    TRACE(("Making resize-request to restore 80-columns %dx%d\n",
10084d522f475Smrg		   reqHeight, reqWidth));
100852eaa94a1Schristos	    REQ_RESIZE((Widget) xw,
100862eaa94a1Schristos		       reqWidth,
100872eaa94a1Schristos		       reqHeight,
100882eaa94a1Schristos		       &replyWidth, &replyHeight);
10089d522f475Smrg	    repairSizeHints();
10090d522f475Smrg	    XSync(screen->display, False);	/* synchronize */
100910bd37d32Smrg	    if (xtermAppPending())
10092d522f475Smrg		xevents();
10093d522f475Smrg	}
10094d522f475Smrg
10095d522f475Smrg	CursorSet(screen, 0, 0, xw->flags);
10096d522f475Smrg	CursorSave(xw);
10097d522f475Smrg    } else {			/* DECSTR */
10098d522f475Smrg	/*
10099d522f475Smrg	 * There's a tiny difference, to accommodate usage of xterm.
10100d522f475Smrg	 * We reset autowrap to the resource values rather than turning
10101d522f475Smrg	 * it off.
10102d522f475Smrg	 */
1010320d2c4d2Smrg	UIntClr(xw->keyboard.flags, (MODE_DECCKM | MODE_KAM | MODE_DECKPAM));
10104d522f475Smrg	bitcpy(&xw->flags, xw->initflags, WRAPAROUND | REVERSEWRAP);
10105d522f475Smrg	bitclr(&xw->flags, INSERT | INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE);
10106d522f475Smrg	if_OPT_ISO_COLORS(screen, {
10107d522f475Smrg	    reset_SGR_Colors(xw);
10108d522f475Smrg	});
10109d522f475Smrg	update_appcursor();
10110d522f475Smrg	update_autowrap();
10111d522f475Smrg	update_reversewrap();
10112d522f475Smrg
10113d522f475Smrg	CursorSave(xw);
10114956cc18dSsnj	screen->sc[screen->whichBuf].row =
10115956cc18dSsnj	    screen->sc[screen->whichBuf].col = 0;
10116d522f475Smrg    }
10117e39b573cSmrg}
10118e39b573cSmrg
10119e39b573cSmrgvoid
10120e39b573cSmrgVTReset(XtermWidget xw, Bool full, Bool saved)
10121e39b573cSmrg{
10122e39b573cSmrg    ReallyReset(xw, full, saved);
10123d522f475Smrg    longjmp(vtjmpbuf, 1);	/* force ground state in parser */
10124d522f475Smrg}
10125d522f475Smrg
10126d522f475Smrg/*
10127d522f475Smrg * set_character_class - takes a string of the form
10128d522f475Smrg *
10129d522f475Smrg *   low[-high]:val[,low[-high]:val[...]]
10130d522f475Smrg *
10131d522f475Smrg * and sets the indicated ranges to the indicated values.
10132d522f475Smrg */
10133d522f475Smrgstatic int
10134d522f475Smrgset_character_class(char *s)
10135d522f475Smrg{
101360bd37d32Smrg#define FMT "%s in range string \"%s\" (position %d)\n"
10137d522f475Smrg    int i;			/* iterator, index into s */
10138d522f475Smrg    int len;			/* length of s */
10139d522f475Smrg    int acc;			/* accumulator */
10140d522f475Smrg    int low, high;		/* bounds of range [0..127] */
10141d522f475Smrg    int base;			/* 8, 10, 16 (octal, decimal, hex) */
10142d522f475Smrg    int numbers;		/* count of numbers per range */
10143d522f475Smrg    int digits;			/* count of digits in a number */
10144d522f475Smrg
10145d522f475Smrg    if (!s || !s[0])
10146d522f475Smrg	return -1;
10147d522f475Smrg
10148d522f475Smrg    base = 10;			/* in case we ever add octal, hex */
10149d522f475Smrg    low = high = -1;		/* out of range */
10150d522f475Smrg
101512eaa94a1Schristos    for (i = 0, len = (int) strlen(s), acc = 0, numbers = digits = 0;
10152d522f475Smrg	 i < len; i++) {
101532eaa94a1Schristos	Char c = CharOf(s[i]);
10154d522f475Smrg
10155d522f475Smrg	if (isspace(c)) {
10156d522f475Smrg	    continue;
10157d522f475Smrg	} else if (isdigit(c)) {
10158d522f475Smrg	    acc = acc * base + (c - '0');
10159d522f475Smrg	    digits++;
10160d522f475Smrg	    continue;
10161d522f475Smrg	} else if (c == '-') {
10162d522f475Smrg	    low = acc;
10163d522f475Smrg	    acc = 0;
10164d522f475Smrg	    if (digits == 0) {
101650bd37d32Smrg		xtermWarning(FMT, "missing number", s, i);
10166d522f475Smrg		return (-1);
10167d522f475Smrg	    }
10168d522f475Smrg	    digits = 0;
10169d522f475Smrg	    numbers++;
10170d522f475Smrg	    continue;
10171d522f475Smrg	} else if (c == ':') {
10172d522f475Smrg	    if (numbers == 0)
10173d522f475Smrg		low = acc;
10174d522f475Smrg	    else if (numbers == 1)
10175d522f475Smrg		high = acc;
10176d522f475Smrg	    else {
101770bd37d32Smrg		xtermWarning(FMT, "too many numbers", s, i);
10178d522f475Smrg		return (-1);
10179d522f475Smrg	    }
10180d522f475Smrg	    digits = 0;
10181d522f475Smrg	    numbers++;
10182d522f475Smrg	    acc = 0;
10183d522f475Smrg	    continue;
10184d522f475Smrg	} else if (c == ',') {
10185d522f475Smrg	    /*
10186d522f475Smrg	     * now, process it
10187d522f475Smrg	     */
10188d522f475Smrg
10189d522f475Smrg	    if (high < 0) {
10190d522f475Smrg		high = low;
10191d522f475Smrg		numbers++;
10192d522f475Smrg	    }
10193d522f475Smrg	    if (numbers != 2) {
101940bd37d32Smrg		xtermWarning(FMT, "bad value number", s, i);
10195d522f475Smrg	    } else if (SetCharacterClassRange(low, high, acc) != 0) {
101960bd37d32Smrg		xtermWarning(FMT, "bad range", s, i);
10197d522f475Smrg	    }
10198d522f475Smrg
10199d522f475Smrg	    low = high = -1;
10200d522f475Smrg	    acc = 0;
10201d522f475Smrg	    digits = 0;
10202d522f475Smrg	    numbers = 0;
10203d522f475Smrg	    continue;
10204d522f475Smrg	} else {
102050bd37d32Smrg	    xtermWarning(FMT, "bad character", s, i);
10206d522f475Smrg	    return (-1);
10207d522f475Smrg	}			/* end if else if ... else */
10208d522f475Smrg
10209d522f475Smrg    }
10210d522f475Smrg
10211d522f475Smrg    if (low < 0 && high < 0)
10212d522f475Smrg	return (0);
10213d522f475Smrg
10214d522f475Smrg    /*
10215d522f475Smrg     * now, process it
10216d522f475Smrg     */
10217d522f475Smrg
10218d522f475Smrg    if (high < 0)
10219d522f475Smrg	high = low;
10220d522f475Smrg    if (numbers < 1 || numbers > 2) {
102210bd37d32Smrg	xtermWarning(FMT, "bad value number", s, i);
10222d522f475Smrg    } else if (SetCharacterClassRange(low, high, acc) != 0) {
102230bd37d32Smrg	xtermWarning(FMT, "bad range", s, i);
10224d522f475Smrg    }
10225d522f475Smrg
10226d522f475Smrg    return (0);
102270bd37d32Smrg#undef FMT
10228d522f475Smrg}
10229d522f475Smrg
10230d522f475Smrg/* ARGSUSED */
10231d522f475Smrgstatic void
10232d522f475SmrgHandleKeymapChange(Widget w,
10233d522f475Smrg		   XEvent * event GCC_UNUSED,
10234e0a2b6dfSmrg		   String *params,
10235d522f475Smrg		   Cardinal *param_count)
10236d522f475Smrg{
10237d522f475Smrg    static XtTranslations keymap, original;
10238d522f475Smrg    static XtResource key_resources[] =
10239d522f475Smrg    {
10240d522f475Smrg	{XtNtranslations, XtCTranslations, XtRTranslationTable,
10241d522f475Smrg	 sizeof(XtTranslations), 0, XtRTranslationTable, (XtPointer) NULL}
10242d522f475Smrg    };
10243d522f475Smrg    char mapName[1000];
10244d522f475Smrg    char mapClass[1000];
10245d522f475Smrg    char *pmapName;
10246d522f475Smrg    char *pmapClass;
10247d522f475Smrg    size_t len;
10248d522f475Smrg
10249d522f475Smrg    if (*param_count != 1)
10250d522f475Smrg	return;
10251d522f475Smrg
10252d522f475Smrg    if (original == NULL)
10253d522f475Smrg	original = w->core.tm.translations;
10254d522f475Smrg
10255d522f475Smrg    if (strcmp(params[0], "None") == 0) {
10256d522f475Smrg	XtOverrideTranslations(w, original);
10257d522f475Smrg	return;
10258d522f475Smrg    }
10259d522f475Smrg
10260d522f475Smrg    len = strlen(params[0]) + 7;
10261d522f475Smrg
10262d522f475Smrg    pmapName = (char *) MyStackAlloc(len, mapName);
10263d522f475Smrg    pmapClass = (char *) MyStackAlloc(len, mapClass);
10264d522f475Smrg    if (pmapName == NULL
1026520d2c4d2Smrg	|| pmapClass == NULL) {
10266d522f475Smrg	SysError(ERROR_KMMALLOC1);
1026720d2c4d2Smrg    } else {
1026820d2c4d2Smrg
1026920d2c4d2Smrg	(void) sprintf(pmapName, "%sKeymap", params[0]);
1027020d2c4d2Smrg	(void) strcpy(pmapClass, pmapName);
1027120d2c4d2Smrg	if (islower(CharOf(pmapClass[0])))
1027220d2c4d2Smrg	    pmapClass[0] = x_toupper(pmapClass[0]);
1027320d2c4d2Smrg	XtGetSubresources(w, (XtPointer) &keymap, pmapName, pmapClass,
1027420d2c4d2Smrg			  key_resources, (Cardinal) 1, NULL, (Cardinal) 0);
1027520d2c4d2Smrg	if (keymap != NULL)
1027620d2c4d2Smrg	    XtOverrideTranslations(w, keymap);
10277d522f475Smrg
1027820d2c4d2Smrg	MyStackFree(pmapName, mapName);
1027920d2c4d2Smrg	MyStackFree(pmapClass, mapClass);
1028020d2c4d2Smrg    }
10281d522f475Smrg}
10282d522f475Smrg
10283d522f475Smrg/* ARGSUSED */
10284d522f475Smrgstatic void
10285d522f475SmrgHandleBell(Widget w GCC_UNUSED,
10286d522f475Smrg	   XEvent * event GCC_UNUSED,
10287e0a2b6dfSmrg	   String *params,	/* [0] = volume */
10288d522f475Smrg	   Cardinal *param_count)	/* 0 or 1 */
10289d522f475Smrg{
10290d522f475Smrg    int percent = (*param_count) ? atoi(params[0]) : 0;
10291d522f475Smrg
1029220d2c4d2Smrg    Bell(term, XkbBI_TerminalBell, percent);
10293d522f475Smrg}
10294d522f475Smrg
10295d522f475Smrg/* ARGSUSED */
10296d522f475Smrgstatic void
10297d522f475SmrgHandleVisualBell(Widget w GCC_UNUSED,
10298d522f475Smrg		 XEvent * event GCC_UNUSED,
10299e0a2b6dfSmrg		 String *params GCC_UNUSED,
10300d522f475Smrg		 Cardinal *param_count GCC_UNUSED)
10301d522f475Smrg{
10302d522f475Smrg    VisualBell();
10303d522f475Smrg}
10304d522f475Smrg
10305d522f475Smrg/* ARGSUSED */
10306d522f475Smrgstatic void
10307d522f475SmrgHandleIgnore(Widget w,
10308d522f475Smrg	     XEvent * event,
10309e0a2b6dfSmrg	     String *params GCC_UNUSED,
10310d522f475Smrg	     Cardinal *param_count GCC_UNUSED)
10311d522f475Smrg{
10312956cc18dSsnj    XtermWidget xw;
10313956cc18dSsnj
103140bd37d32Smrg    TRACE(("Handle ignore for %p %s\n",
103150bd37d32Smrg	   (void *) w, visibleEventType(event->type)));
10316956cc18dSsnj    if ((xw = getXtermWidget(w)) != 0) {
10317d522f475Smrg	/* do nothing, but check for funny escape sequences */
10318956cc18dSsnj	(void) SendMousePosition(xw, event);
10319d522f475Smrg    }
10320d522f475Smrg}
10321d522f475Smrg
10322d522f475Smrg/* ARGSUSED */
10323d522f475Smrgstatic void
10324d522f475SmrgDoSetSelectedFont(Widget w,
10325d522f475Smrg		  XtPointer client_data GCC_UNUSED,
10326d522f475Smrg		  Atom * selection GCC_UNUSED,
10327d522f475Smrg		  Atom * type,
10328d522f475Smrg		  XtPointer value,
10329d522f475Smrg		  unsigned long *length,
10330d522f475Smrg		  int *format)
10331d522f475Smrg{
10332956cc18dSsnj    XtermWidget xw = getXtermWidget(w);
10333956cc18dSsnj
103340bd37d32Smrg    if (xw == 0) {
103350bd37d32Smrg	xtermWarning("unexpected widget in DoSetSelectedFont\n");
103360bd37d32Smrg    } else if (*type != XA_STRING || *format != 8) {
1033720d2c4d2Smrg	Bell(xw, XkbBI_MinorError, 0);
10338d522f475Smrg    } else {
10339d522f475Smrg	Boolean failed = False;
1034020d2c4d2Smrg	int oldFont = TScreenOf(xw)->menu_font_number;
1034120d2c4d2Smrg	String save = TScreenOf(xw)->MenuFontName(fontMenu_fontsel);
10342d522f475Smrg	char *val;
10343d522f475Smrg	char *test = 0;
10344d522f475Smrg	char *used = 0;
1034520d2c4d2Smrg	unsigned len = (unsigned) *length;
10346d522f475Smrg	unsigned tst;
10347d522f475Smrg
10348d522f475Smrg	/*
10349d522f475Smrg	 * Some versions of X deliver null-terminated selections, some do not.
10350d522f475Smrg	 */
10351d522f475Smrg	for (tst = 0; tst < len; ++tst) {
10352d522f475Smrg	    if (((char *) value)[tst] == '\0') {
10353d522f475Smrg		len = tst;
10354d522f475Smrg		break;
10355d522f475Smrg	    }
10356d522f475Smrg	}
10357d522f475Smrg
10358d522f475Smrg	if (len > 0 && (val = TypeMallocN(char, len + 1)) != 0) {
1035920d2c4d2Smrg	    memcpy(val, value, (size_t) len);
10360d522f475Smrg	    val[len] = '\0';
10361d522f475Smrg	    used = x_strtrim(val);
103626879286fSmrg	    TRACE(("DoSetSelectedFont(%s)\n", used));
10363d522f475Smrg	    /* Do some sanity checking to avoid sending a long selection
10364d522f475Smrg	       back to the server in an OpenFont that is unlikely to succeed.
10365d522f475Smrg	       XLFD allows up to 255 characters and no control characters;
10366d522f475Smrg	       we are a little more liberal here. */
10367d522f475Smrg	    if (len < 1000
103680bd37d32Smrg		&& used != 0
103696879286fSmrg		&& !strchr(used, '\n')
103706879286fSmrg		&& (test = x_strdup(used)) != 0) {
1037120d2c4d2Smrg		TScreenOf(xw)->MenuFontName(fontMenu_fontsel) = test;
10372d522f475Smrg		if (!xtermLoadFont(term,
103736879286fSmrg				   xtermFontName(used),
10374d522f475Smrg				   True,
10375d522f475Smrg				   fontMenu_fontsel)) {
10376d522f475Smrg		    failed = True;
10377d522f475Smrg		    free(test);
1037820d2c4d2Smrg		    TScreenOf(xw)->MenuFontName(fontMenu_fontsel) = save;
10379d522f475Smrg		}
10380d522f475Smrg	    } else {
10381d522f475Smrg		failed = True;
10382d522f475Smrg	    }
10383d522f475Smrg	    if (failed) {
10384d522f475Smrg		(void) xtermLoadFont(term,
1038520d2c4d2Smrg				     xtermFontName(TScreenOf(xw)->MenuFontName(oldFont)),
10386d522f475Smrg				     True,
10387d522f475Smrg				     oldFont);
1038820d2c4d2Smrg		Bell(xw, XkbBI_MinorError, 0);
10389d522f475Smrg	    }
103906879286fSmrg	    free(used);
10391d522f475Smrg	    free(val);
10392d522f475Smrg	}
10393d522f475Smrg    }
10394d522f475Smrg}
10395d522f475Smrg
10396d522f475Smrgvoid
10397d522f475SmrgFindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe)
10398d522f475Smrg{
1039920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
10400d522f475Smrg    static AtomPtr *atoms;
104010bd37d32Smrg    static unsigned int atomCount = 0;
10402d522f475Smrg    AtomPtr *pAtom;
104032eaa94a1Schristos    unsigned a;
10404d522f475Smrg    Atom target;
10405d522f475Smrg
10406d522f475Smrg    if (!atom_name)
10407956cc18dSsnj	atom_name = (screen->mappedSelect
10408956cc18dSsnj		     ? screen->mappedSelect[0]
10409d522f475Smrg		     : "PRIMARY");
10410d522f475Smrg    TRACE(("FindFontSelection(%s)\n", atom_name));
10411d522f475Smrg
10412d522f475Smrg    for (pAtom = atoms, a = atomCount; a; a--, pAtom++) {
104130bd37d32Smrg	if (strcmp(atom_name, XmuNameOfAtom(*pAtom)) == 0) {
104140bd37d32Smrg	    TRACE(("...found atom %d:%s\n", a + 1, atom_name));
10415d522f475Smrg	    break;
104160bd37d32Smrg	}
10417d522f475Smrg    }
10418d522f475Smrg    if (!a) {
10419a1f3da82Smrg	atoms = TypeXtReallocN(AtomPtr, atoms, atomCount + 1);
1042020d2c4d2Smrg	*(pAtom = &atoms[atomCount]) = XmuMakeAtom(atom_name);
104210bd37d32Smrg	++atomCount;
104220bd37d32Smrg	TRACE(("...added atom %d:%s\n", atomCount, atom_name));
10423d522f475Smrg    }
10424d522f475Smrg
10425d522f475Smrg    target = XmuInternAtom(XtDisplay(xw), *pAtom);
10426d522f475Smrg    if (justprobe) {
10427956cc18dSsnj	screen->MenuFontName(fontMenu_fontsel) =
10428d522f475Smrg	    XGetSelectionOwner(XtDisplay(xw), target) ? _Font_Selected_ : 0;
10429956cc18dSsnj	TRACE(("...selected fontname '%s'\n",
10430956cc18dSsnj	       NonNull(screen->MenuFontName(fontMenu_fontsel))));
10431d522f475Smrg    } else {
10432d522f475Smrg	XtGetSelectionValue((Widget) xw, target, XA_STRING,
10433d522f475Smrg			    DoSetSelectedFont, NULL,
10434d522f475Smrg			    XtLastTimestampProcessed(XtDisplay(xw)));
10435d522f475Smrg    }
10436d522f475Smrg    return;
10437d522f475Smrg}
10438d522f475Smrg
10439492d43a5SmrgBool
10440d522f475Smrgset_cursor_gcs(XtermWidget xw)
10441d522f475Smrg{
1044220d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
10443d522f475Smrg    VTwin *win = WhichVWin(screen);
10444d522f475Smrg
10445d522f475Smrg    Pixel cc = T_COLOR(screen, TEXT_CURSOR);
10446d522f475Smrg    Pixel fg = T_COLOR(screen, TEXT_FG);
10447d522f475Smrg    Pixel bg = T_COLOR(screen, TEXT_BG);
10448492d43a5Smrg    Bool changed = False;
10449d522f475Smrg
10450d522f475Smrg    /*
10451d522f475Smrg     * Let's see, there are three things that have "color":
10452d522f475Smrg     *
10453d522f475Smrg     *     background
10454d522f475Smrg     *     text
10455d522f475Smrg     *     cursorblock
10456d522f475Smrg     *
10457d522f475Smrg     * And, there are four situations when drawing a cursor, if we decide
10458d522f475Smrg     * that we like have a solid block of cursor color with the letter
10459d522f475Smrg     * that it is highlighting shown in the background color to make it
10460d522f475Smrg     * stand out:
10461d522f475Smrg     *
10462d522f475Smrg     *     selected window, normal video - background on cursor
10463d522f475Smrg     *     selected window, reverse video - foreground on cursor
10464d522f475Smrg     *     unselected window, normal video - foreground on background
10465d522f475Smrg     *     unselected window, reverse video - background on foreground
10466d522f475Smrg     *
10467d522f475Smrg     * Since the last two are really just normalGC and reverseGC, we only
10468d522f475Smrg     * need two new GC's.  Under monochrome, we get the same effect as
10469d522f475Smrg     * above by setting cursor color to foreground.
10470d522f475Smrg     */
10471d522f475Smrg
10472d522f475Smrg    TRACE(("set_cursor_gcs cc=%#lx, fg=%#lx, bg=%#lx\n", cc, fg, bg));
10473d522f475Smrg    if (win != 0 && (cc != bg)) {
10474d522f475Smrg	/* set the fonts to the current one */
10475d522f475Smrg	setCgsFont(xw, win, gcVTcursNormal, 0);
10476d522f475Smrg	setCgsFont(xw, win, gcVTcursFilled, 0);
10477d522f475Smrg	setCgsFont(xw, win, gcVTcursReverse, 0);
10478d522f475Smrg	setCgsFont(xw, win, gcVTcursOutline, 0);
10479d522f475Smrg
10480d522f475Smrg	/* we have a colored cursor */
10481d522f475Smrg	setCgsFore(xw, win, gcVTcursNormal, fg);
10482d522f475Smrg	setCgsBack(xw, win, gcVTcursNormal, cc);
10483d522f475Smrg
10484d522f475Smrg	setCgsFore(xw, win, gcVTcursFilled, cc);
10485d522f475Smrg	setCgsBack(xw, win, gcVTcursFilled, fg);
10486d522f475Smrg
10487d522f475Smrg	if (screen->always_highlight) {
10488d522f475Smrg	    /* both GC's use the same color */
10489d522f475Smrg	    setCgsFore(xw, win, gcVTcursReverse, bg);
10490d522f475Smrg	    setCgsBack(xw, win, gcVTcursReverse, cc);
10491d522f475Smrg	} else {
10492d522f475Smrg	    setCgsFore(xw, win, gcVTcursReverse, bg);
10493d522f475Smrg	    setCgsBack(xw, win, gcVTcursReverse, cc);
10494d522f475Smrg	}
10495a1f3da82Smrg	set_cursor_outline_gc(xw, screen->always_highlight, fg, bg, cc);
10496d522f475Smrg	changed = True;
10497d522f475Smrg    }
10498d522f475Smrg
10499d522f475Smrg    if (changed) {
10500d522f475Smrg	TRACE(("...set_cursor_gcs - done\n"));
10501d522f475Smrg    }
10502492d43a5Smrg    return changed;
10503d522f475Smrg}
10504d522f475Smrg
10505a1f3da82Smrg/*
10506a1f3da82Smrg * Build up the default translations string, allowing the user to suppress
10507a1f3da82Smrg * some of the features.
10508a1f3da82Smrg */
10509a1f3da82Smrgvoid
10510a1f3da82SmrgVTInitTranslations(void)
10511a1f3da82Smrg{
10512a1f3da82Smrg    /* *INDENT-OFF* */
10513a1f3da82Smrg    static struct {
10514a1f3da82Smrg	Boolean wanted;
10515a1f3da82Smrg	const char *name;
10516a1f3da82Smrg	const char *value;
10517a1f3da82Smrg    } table[] = {
10518a1f3da82Smrg	{
10519a1f3da82Smrg	    False,
10520a1f3da82Smrg	    "default",
10521a1f3da82Smrg"\
10522a1f3da82Smrg          Shift <KeyPress> Prior:scroll-back(1,halfpage) \n\
10523a1f3da82Smrg           Shift <KeyPress> Next:scroll-forw(1,halfpage) \n\
10524a1f3da82Smrg         Shift <KeyPress> Select:select-cursor-start() select-cursor-end(SELECT, CUT_BUFFER0) \n\
10525a1f3da82Smrg         Shift <KeyPress> Insert:insert-selection(SELECT, CUT_BUFFER0) \n\
10526a1f3da82Smrg"
10527a1f3da82Smrg	},
10528a1f3da82Smrg#if OPT_MAXIMIZE
10529a1f3da82Smrg	{
10530a1f3da82Smrg	    False,
10531a1f3da82Smrg	    "fullscreen",
10532a1f3da82Smrg"\
10533a1f3da82Smrg                 Alt <Key>Return:fullscreen() \n\
10534a1f3da82Smrg"
10535a1f3da82Smrg	},
10536a1f3da82Smrg#endif
10537a1f3da82Smrg#if OPT_SCROLL_LOCK
10538a1f3da82Smrg	{
10539a1f3da82Smrg	    False,
10540a1f3da82Smrg	    "scroll-lock",
10541a1f3da82Smrg"\
10542a1f3da82Smrg        <KeyRelease> Scroll_Lock:scroll-lock() \n\
10543a1f3da82Smrg"
10544a1f3da82Smrg	},
10545a1f3da82Smrg#endif
10546a1f3da82Smrg#if OPT_SHIFT_FONTS
10547a1f3da82Smrg	{
10548a1f3da82Smrg	    False,
10549a1f3da82Smrg	    "shift-fonts",
10550a1f3da82Smrg"\
10551a1f3da82Smrg    Shift~Ctrl <KeyPress> KP_Add:larger-vt-font() \n\
10552a1f3da82Smrg    Shift Ctrl <KeyPress> KP_Add:smaller-vt-font() \n\
10553a1f3da82Smrg    Shift <KeyPress> KP_Subtract:smaller-vt-font() \n\
10554a1f3da82Smrg"
10555a1f3da82Smrg	},
10556a1f3da82Smrg#endif
10557a1f3da82Smrg	/* PROCURA added "Meta <Btn2Down>:clear-saved-lines()" */
10558a1f3da82Smrg	{
10559a1f3da82Smrg	    False,
10560a1f3da82Smrg	    "default",
10561a1f3da82Smrg"\
10562a1f3da82Smrg                ~Meta <KeyPress>:insert-seven-bit() \n\
10563a1f3da82Smrg                 Meta <KeyPress>:insert-eight-bit() \n\
10564a1f3da82Smrg                !Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
10565a1f3da82Smrg           !Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
10566a1f3da82Smrg !Lock Ctrl @Num_Lock <Btn1Down>:popup-menu(mainMenu) \n\
10567a1f3da82Smrg     ! @Num_Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
10568a1f3da82Smrg                ~Meta <Btn1Down>:select-start() \n\
10569a1f3da82Smrg              ~Meta <Btn1Motion>:select-extend() \n\
10570a1f3da82Smrg                !Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
10571a1f3da82Smrg           !Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
10572a1f3da82Smrg !Lock Ctrl @Num_Lock <Btn2Down>:popup-menu(vtMenu) \n\
10573a1f3da82Smrg     ! @Num_Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
10574a1f3da82Smrg          ~Ctrl ~Meta <Btn2Down>:ignore() \n\
10575a1f3da82Smrg                 Meta <Btn2Down>:clear-saved-lines() \n\
10576a1f3da82Smrg            ~Ctrl ~Meta <Btn2Up>:insert-selection(SELECT, CUT_BUFFER0) \n\
10577a1f3da82Smrg                !Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
10578a1f3da82Smrg           !Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
10579a1f3da82Smrg !Lock Ctrl @Num_Lock <Btn3Down>:popup-menu(fontMenu) \n\
10580a1f3da82Smrg     ! @Num_Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
10581a1f3da82Smrg          ~Ctrl ~Meta <Btn3Down>:start-extend() \n\
10582a1f3da82Smrg              ~Meta <Btn3Motion>:select-extend() \n\
10583a1f3da82Smrg"
10584a1f3da82Smrg	},
10585a1f3da82Smrg	{
10586a1f3da82Smrg	    False,
10587a1f3da82Smrg	    "wheel-mouse",
10588a1f3da82Smrg"\
10589a1f3da82Smrg                 Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
10590a1f3da82Smrg            Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
10591a1f3da82Smrg  Lock @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
10592a1f3da82Smrg       @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
10593a1f3da82Smrg                      <Btn4Down>:scroll-back(5,line,m)     \n\
10594a1f3da82Smrg                 Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
10595a1f3da82Smrg            Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
10596a1f3da82Smrg  Lock @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
10597a1f3da82Smrg       @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
10598a1f3da82Smrg                      <Btn5Down>:scroll-forw(5,line,m)     \n\
10599a1f3da82Smrg"
10600a1f3da82Smrg	},
10601a1f3da82Smrg	{
10602a1f3da82Smrg	    False,
10603a1f3da82Smrg	    "default",
10604a1f3da82Smrg"\
10605a1f3da82Smrg                         <BtnUp>:select-end(SELECT, CUT_BUFFER0) \n\
10606a1f3da82Smrg                       <BtnDown>:ignore() \
10607a1f3da82Smrg"
10608a1f3da82Smrg	}
10609a1f3da82Smrg    };
10610a1f3da82Smrg    /* *INDENT-ON* */
10611a1f3da82Smrg
10612a1f3da82Smrg    size_t needed = 0;
10613a1f3da82Smrg    char *result = 0;
10614a1f3da82Smrg
10615a1f3da82Smrg    int pass;
10616a1f3da82Smrg    Cardinal item;
10617a1f3da82Smrg
10618a1f3da82Smrg    TRACE(("VTInitTranslations\n"));
10619a1f3da82Smrg    for (item = 0; item < XtNumber(table); ++item) {
10620a1f3da82Smrg	table[item].wanted = True;
10621a1f3da82Smrg    }
10622a1f3da82Smrg#if OPT_MAXIMIZE
10623a1f3da82Smrg    /*
10624a1f3da82Smrg     * As a special case, allow for disabling the alt-enter translation if
10625a1f3da82Smrg     * the resource settings prevent fullscreen from being used.  We would
10626a1f3da82Smrg     * do the same for scroll-lock and shift-fonts if they were application
10627a1f3da82Smrg     * resources too, rather than in the widget.
10628a1f3da82Smrg     */
10629a1f3da82Smrg    if (resource.fullscreen == esNever) {
10630a1f3da82Smrg	for (item = 0; item < XtNumber(table); ++item) {
10631e39b573cSmrg	    if (!strcmp(table[item].name, "fullscreen")) {
10632a1f3da82Smrg		table[item].wanted = False;
10633e39b573cSmrg		TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value));
10634e39b573cSmrg	    }
10635a1f3da82Smrg	}
10636a1f3da82Smrg    }
10637a1f3da82Smrg#endif
10638a1f3da82Smrg    if (!IsEmpty(resource.omitTranslation)) {
10639a1f3da82Smrg	char *value;
10640a1f3da82Smrg	const char *source = resource.omitTranslation;
10641a1f3da82Smrg
10642a1f3da82Smrg	while (*source != '\0' && (value = ParseList(&source)) != 0) {
10643a1f3da82Smrg	    size_t len = strlen(value);
10644a1f3da82Smrg
10645a1f3da82Smrg	    TRACE(("parsed:%s\n", value));
10646a1f3da82Smrg	    for (item = 0; item < XtNumber(table); ++item) {
10647a1f3da82Smrg		if (strlen(table[item].name) >= len
10648a1f3da82Smrg		    && x_strncasecmp(table[item].name,
10649a1f3da82Smrg				     value,
10650a1f3da82Smrg				     (unsigned) len) == 0) {
10651a1f3da82Smrg		    table[item].wanted = False;
10652a1f3da82Smrg		    TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value));
10653a1f3da82Smrg		    break;
10654a1f3da82Smrg		}
10655a1f3da82Smrg	    }
10656a1f3da82Smrg	    free(value);
10657a1f3da82Smrg	}
10658a1f3da82Smrg    }
10659a1f3da82Smrg
10660a1f3da82Smrg    for (pass = 0; pass < 2; ++pass) {
10661a1f3da82Smrg	needed = 0;
10662a1f3da82Smrg	for (item = 0; item < XtNumber(table); ++item) {
10663a1f3da82Smrg	    if (table[item].wanted) {
10664a1f3da82Smrg		if (pass) {
10665a1f3da82Smrg		    strcat(result, table[item].value);
10666a1f3da82Smrg		} else {
10667a1f3da82Smrg		    needed += strlen(table[item].value) + 1;
10668a1f3da82Smrg		}
10669a1f3da82Smrg	    }
10670a1f3da82Smrg	}
10671a1f3da82Smrg	if (!pass) {
10672a1f3da82Smrg	    result = XtMalloc((Cardinal) needed);
10673a1f3da82Smrg	    *result = '\0';
10674a1f3da82Smrg	}
10675a1f3da82Smrg    }
10676a1f3da82Smrg
10677a1f3da82Smrg    TRACE(("result:\n%s\n", result));
10678a1f3da82Smrg
10679a1f3da82Smrg    defaultTranslations = result;
10680a1f3da82Smrg    xtermClassRec.core_class.tm_table = result;
10681a1f3da82Smrg}
10682a1f3da82Smrg
10683d522f475Smrg#ifdef NO_LEAKS
10684d522f475Smrgvoid
10685d522f475Smrgnoleaks_charproc(void)
10686d522f475Smrg{
10687d522f475Smrg    if (v_buffer != 0)
10688d522f475Smrg	free(v_buffer);
10689d522f475Smrg}
10690d522f475Smrg#endif
10691