charproc.c revision 0bd37d32
10bd37d32Smrg/* $XTermId: charproc.c,v 1.1289 2013/05/26 21:18:52 tom Exp $ */
2d522f475Smrg
3d522f475Smrg/*
40bd37d32Smrg * Copyright 1999-2012,2013 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 <xcharmouse.h>
137d522f475Smrg#include <charclass.h>
138d522f475Smrg#include <xstrings.h>
139d522f475Smrg
14020d2c4d2Smrgtypedef void (*BitFunc) (unsigned * /* p */ ,
14120d2c4d2Smrg			 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 */ ,
15420d2c4d2Smrg		       int /* toBuf */ );
155d522f475Smrgstatic void ToAlternate(XtermWidget /* xw */ );
156d522f475Smrgstatic void ansi_modes(XtermWidget termw,
15720d2c4d2Smrg		       BitFunc /* func */ );
158d522f475Smrgstatic void bitclr(unsigned *p, unsigned mask);
159d522f475Smrgstatic void bitcpy(unsigned *p, unsigned q, unsigned mask);
160d522f475Smrgstatic void bitset(unsigned *p, unsigned mask);
16120d2c4d2Smrgstatic void dpmodes(XtermWidget /* xw */ ,
16220d2c4d2Smrg		    BitFunc /* func */ );
16320d2c4d2Smrgstatic void restoremodes(XtermWidget /* xw */ );
16420d2c4d2Smrgstatic void savemodes(XtermWidget /* xw */ );
16520d2c4d2Smrgstatic void window_ops(XtermWidget /* xw */ );
166d522f475Smrg
167d522f475Smrg#define DoStartBlinking(s) ((s)->cursor_blink ^ (s)->cursor_blink_esc)
168d522f475Smrg
169d522f475Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
1700bd37d32Smrg#define UpdateCursorBlink(screen) SetCursorBlink(screen, screen->cursor_blink)
17120d2c4d2Smrgstatic void SetCursorBlink(TScreen * /* screen */ ,
17220d2c4d2Smrg			   Bool /* enable */ );
17320d2c4d2Smrgstatic void HandleBlinking(XtPointer /* closure */ ,
17420d2c4d2Smrg			   XtIntervalId * /* id */ );
17520d2c4d2Smrgstatic void StartBlinking(TScreen * /* screen */ );
17620d2c4d2Smrgstatic void StopBlinking(TScreen * /* screen */ );
177d522f475Smrg#else
178d522f475Smrg#define StartBlinking(screen)	/* nothing */
179d522f475Smrg#define StopBlinking(screen)	/* nothing */
180d522f475Smrg#endif
181d522f475Smrg
1820bd37d32Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
1830bd37d32Smrgstatic void PreeditPosition(XtermWidget /* xw */ );
184d522f475Smrg#endif
185d522f475Smrg
186d522f475Smrg#define	DEFAULT		-1
187d522f475Smrg#define BELLSUPPRESSMSEC 200
188d522f475Smrg
189d522f475Smrgstatic ANSI reply;
1900bd37d32Smrgstatic PARAMS parms;
1910bd37d32Smrg
1920bd37d32Smrg#define nparam parms.count
1930bd37d32Smrg
1940bd37d32Smrg#define InitParams()  parms.count = parms.is_sub[0] = parms.has_subparams = 0
1950bd37d32Smrg#define GetParam(n)   parms.params[(n)]
1960bd37d32Smrg#define SetParam(n,v) parms.params[(n)] = v
1970bd37d32Smrg#define ParamPair(n)  nparam - (n), parms.params + (n)
1980bd37d32Smrg#define ParamsDone()  InitParams()
199d522f475Smrg
200d522f475Smrgstatic jmp_buf vtjmpbuf;
201d522f475Smrg
202d522f475Smrg/* event handlers */
203d522f475Smrgstatic void HandleBell PROTO_XT_ACTIONS_ARGS;
204d522f475Smrgstatic void HandleIgnore PROTO_XT_ACTIONS_ARGS;
205d522f475Smrgstatic void HandleKeymapChange PROTO_XT_ACTIONS_ARGS;
206d522f475Smrgstatic void HandleVisualBell PROTO_XT_ACTIONS_ARGS;
207d522f475Smrg#if HANDLE_STRUCT_NOTIFY
208d522f475Smrgstatic void HandleStructNotify PROTO_XT_EV_HANDLER_ARGS;
209d522f475Smrg#endif
210d522f475Smrg
211d522f475Smrg/*
212d522f475Smrg * NOTE: VTInitialize zeros out the entire ".screen" component of the
213d522f475Smrg * XtermWidget, so make sure to add an assignment statement in VTInitialize()
214d522f475Smrg * for each new ".screen" field added to this resource list.
215d522f475Smrg */
216d522f475Smrg
217d522f475Smrg/* Defaults */
218d522f475Smrg#if OPT_ISO_COLORS
219d522f475Smrg
220d522f475Smrg/*
221d522f475Smrg * If we default to colorMode enabled, compile-in defaults for the ANSI colors.
222d522f475Smrg */
223d522f475Smrg#if DFT_COLORMODE
224d522f475Smrg#define DFT_COLOR(name) name
225d522f475Smrg#else
226d522f475Smrg#define DFT_COLOR(name) XtDefaultForeground
227d522f475Smrg#endif
228d522f475Smrg#endif
229d522f475Smrg
23020d2c4d2Smrgstatic String _Font_Selected_ = "yes";	/* string is arbitrary */
231d522f475Smrg
232a1f3da82Smrgstatic const char *defaultTranslations;
233d522f475Smrg/* *INDENT-OFF* */
234d522f475Smrgstatic XtActionsRec actionsList[] = {
235d522f475Smrg    { "allow-send-events",	HandleAllowSends },
236d522f475Smrg    { "bell",			HandleBell },
237d522f475Smrg    { "clear-saved-lines",	HandleClearSavedLines },
2386879286fSmrg    { "copy-selection",		HandleCopySelection },
239d522f475Smrg    { "create-menu",		HandleCreateMenu },
240d522f475Smrg    { "delete-is-del",		HandleDeleteIsDEL },
241d522f475Smrg    { "dired-button",		DiredButton },
242d522f475Smrg    { "hard-reset",		HandleHardReset },
243d522f475Smrg    { "ignore",			HandleIgnore },
244d522f475Smrg    { "insert",			HandleKeyPressed },  /* alias for insert-seven-bit */
245d522f475Smrg    { "insert-eight-bit",	HandleEightBitKeyPressed },
246d522f475Smrg    { "insert-selection",	HandleInsertSelection },
247d522f475Smrg    { "insert-seven-bit",	HandleKeyPressed },
248d522f475Smrg    { "interpret",		HandleInterpret },
249d522f475Smrg    { "keymap",			HandleKeymapChange },
250d522f475Smrg    { "popup-menu",		HandlePopupMenu },
251d522f475Smrg    { "print",			HandlePrintScreen },
252956cc18dSsnj    { "print-everything",	HandlePrintEverything },
253d522f475Smrg    { "print-redir",		HandlePrintControlMode },
254d522f475Smrg    { "quit",			HandleQuit },
255d522f475Smrg    { "redraw",			HandleRedraw },
256d522f475Smrg    { "scroll-back",		HandleScrollBack },
257d522f475Smrg    { "scroll-forw",		HandleScrollForward },
258d522f475Smrg    { "secure",			HandleSecure },
259d522f475Smrg    { "select-cursor-end",	HandleKeyboardSelectEnd },
260d522f475Smrg    { "select-cursor-extend",   HandleKeyboardSelectExtend },
261d522f475Smrg    { "select-cursor-start",	HandleKeyboardSelectStart },
262d522f475Smrg    { "select-end",		HandleSelectEnd },
263d522f475Smrg    { "select-extend",		HandleSelectExtend },
264d522f475Smrg    { "select-set",		HandleSelectSet },
265d522f475Smrg    { "select-start",		HandleSelectStart },
266d522f475Smrg    { "send-signal",		HandleSendSignal },
267d522f475Smrg    { "set-8-bit-control",	Handle8BitControl },
268d522f475Smrg    { "set-allow132",		HandleAllow132 },
269d522f475Smrg    { "set-altscreen",		HandleAltScreen },
270d522f475Smrg    { "set-appcursor",		HandleAppCursor },
271d522f475Smrg    { "set-appkeypad",		HandleAppKeypad },
272d522f475Smrg    { "set-autolinefeed",	HandleAutoLineFeed },
273d522f475Smrg    { "set-autowrap",		HandleAutoWrap },
274d522f475Smrg    { "set-backarrow",		HandleBackarrow },
275d522f475Smrg    { "set-bellIsUrgent",	HandleBellIsUrgent },
276d522f475Smrg    { "set-cursesemul",		HandleCursesEmul },
277d522f475Smrg    { "set-jumpscroll",		HandleJumpscroll },
278d522f475Smrg    { "set-keep-selection",	HandleKeepSelection },
279d522f475Smrg    { "set-marginbell",		HandleMarginBell },
280d522f475Smrg    { "set-old-function-keys",	HandleOldFunctionKeys },
281d522f475Smrg    { "set-pop-on-bell",	HandleSetPopOnBell },
282d522f475Smrg    { "set-reverse-video",	HandleReverseVideo },
283d522f475Smrg    { "set-reversewrap",	HandleReverseWrap },
284d522f475Smrg    { "set-scroll-on-key",	HandleScrollKey },
285d522f475Smrg    { "set-scroll-on-tty-output", HandleScrollTtyOutput },
286d522f475Smrg    { "set-scrollbar",		HandleScrollbar },
287d522f475Smrg    { "set-select",		HandleSetSelect },
288d522f475Smrg    { "set-sun-keyboard",	HandleSunKeyboard },
289d522f475Smrg    { "set-titeInhibit",	HandleTiteInhibit },
290d522f475Smrg    { "set-visual-bell",	HandleSetVisualBell },
291d522f475Smrg    { "set-vt-font",		HandleSetFont },
292d522f475Smrg    { "soft-reset",		HandleSoftReset },
293d522f475Smrg    { "start-cursor-extend",	HandleKeyboardStartExtend },
294d522f475Smrg    { "start-extend",		HandleStartExtend },
295d522f475Smrg    { "string",			HandleStringEvent },
296d522f475Smrg    { "vi-button",		ViButton },
297d522f475Smrg    { "visual-bell",		HandleVisualBell },
298d522f475Smrg#ifdef ALLOWLOGGING
299d522f475Smrg    { "set-logging",		HandleLogging },
300d522f475Smrg#endif
301956cc18dSsnj#if OPT_ALLOW_XXX_OPS
30220d2c4d2Smrg    { "allow-color-ops",	HandleAllowColorOps },
303956cc18dSsnj    { "allow-font-ops",		HandleAllowFontOps },
304956cc18dSsnj    { "allow-tcap-ops",		HandleAllowTcapOps },
305956cc18dSsnj    { "allow-title-ops",	HandleAllowTitleOps },
306956cc18dSsnj    { "allow-window-ops",	HandleAllowWindowOps },
307956cc18dSsnj#endif
308d522f475Smrg#if OPT_BLINK_CURS
309d522f475Smrg    { "set-cursorblink",	HandleCursorBlink },
310d522f475Smrg#endif
311d522f475Smrg#if OPT_BOX_CHARS
312d522f475Smrg    { "set-font-linedrawing",	HandleFontBoxChars },
31320d2c4d2Smrg    { "set-font-packed",	HandleFontPacked },
314d522f475Smrg#endif
315d522f475Smrg#if OPT_DABBREV
316d522f475Smrg    { "dabbrev-expand",		HandleDabbrevExpand },
317d522f475Smrg#endif
318d522f475Smrg#if OPT_DEC_CHRSET
319d522f475Smrg    { "set-font-doublesize",	HandleFontDoublesize },
320d522f475Smrg#endif
321d522f475Smrg#if OPT_DEC_SOFTFONT
322d522f475Smrg    { "set-font-loading",	HandleFontLoading },
323d522f475Smrg#endif
324d522f475Smrg#if OPT_EXEC_XTERM
325d522f475Smrg    { "spawn-new-terminal",	HandleSpawnTerminal },
326d522f475Smrg#endif
327d522f475Smrg#if OPT_HP_FUNC_KEYS
328d522f475Smrg    { "set-hp-function-keys",	HandleHpFunctionKeys },
329d522f475Smrg#endif
330d522f475Smrg#if OPT_LOAD_VTFONTS
331d522f475Smrg    { "load-vt-fonts",		HandleLoadVTFonts },
332d522f475Smrg#endif
333d522f475Smrg#if OPT_MAXIMIZE
334d522f475Smrg    { "deiconify",		HandleDeIconify },
335a1f3da82Smrg    { "fullscreen",		HandleFullscreen },
336d522f475Smrg    { "iconify",		HandleIconify },
337d522f475Smrg    { "maximize",		HandleMaximize },
338d522f475Smrg    { "restore",		HandleRestoreSize },
339d522f475Smrg#endif
340d522f475Smrg#if OPT_NUM_LOCK
341d522f475Smrg    { "alt-sends-escape",	HandleAltEsc },
342d522f475Smrg    { "meta-sends-escape",	HandleMetaEsc },
343d522f475Smrg    { "set-num-lock",		HandleNumLock },
344d522f475Smrg#endif
345d522f475Smrg#if OPT_READLINE
346d522f475Smrg    { "readline-button",	ReadLineButton },
347d522f475Smrg#endif
348d522f475Smrg#if OPT_RENDERFONT
349d522f475Smrg    { "set-render-font",	HandleRenderFont },
350d522f475Smrg#endif
351d522f475Smrg#if OPT_SCO_FUNC_KEYS
352d522f475Smrg    { "set-sco-function-keys",	HandleScoFunctionKeys },
353d522f475Smrg#endif
35420d2c4d2Smrg#if OPT_SCROLL_LOCK
35520d2c4d2Smrg    { "scroll-lock",		HandleScrollLock },
35620d2c4d2Smrg#endif
3570bd37d32Smrg#if OPT_SELECTION_OPS
3580bd37d32Smrg    { "exec-formatted",		HandleExecFormatted },
3590bd37d32Smrg    { "exec-selectable",	HandleExecSelectable },
3600bd37d32Smrg    { "insert-formatted",	HandleInsertFormatted },
3610bd37d32Smrg    { "insert-selectable",	HandleInsertSelectable },
3620bd37d32Smrg#endif
363d522f475Smrg#if OPT_SHIFT_FONTS
364d522f475Smrg    { "larger-vt-font",		HandleLargerFont },
365d522f475Smrg    { "smaller-vt-font",	HandleSmallerFont },
366d522f475Smrg#endif
367d522f475Smrg#if OPT_SUN_FUNC_KEYS
368d522f475Smrg    { "set-sun-function-keys",	HandleSunFunctionKeys },
369d522f475Smrg#endif
370d522f475Smrg#if OPT_TEK4014
371d522f475Smrg    { "set-terminal-type",	HandleSetTerminalType },
372d522f475Smrg    { "set-visibility",		HandleVisibility },
373d522f475Smrg    { "set-tek-text",		HandleSetTekText },
374d522f475Smrg    { "tek-page",		HandleTekPage },
375d522f475Smrg    { "tek-reset",		HandleTekReset },
376d522f475Smrg    { "tek-copy",		HandleTekCopy },
377d522f475Smrg#endif
378d522f475Smrg#if OPT_TOOLBAR
379d522f475Smrg    { "set-toolbar",		HandleToolbar },
380d522f475Smrg#endif
381d522f475Smrg#if OPT_WIDE_CHARS
382d522f475Smrg    { "set-utf8-mode",		HandleUTF8Mode },
383e39b573cSmrg    { "set-utf8-fonts",		HandleUTF8Fonts },
384d522f475Smrg    { "set-utf8-title",		HandleUTF8Title },
385d522f475Smrg#endif
386d522f475Smrg};
387d522f475Smrg/* *INDENT-ON* */
388d522f475Smrg
389e39b573cSmrg#define SPS screen.printer_state
390e39b573cSmrg
39120d2c4d2Smrgstatic XtResource xterm_resources[] =
392d522f475Smrg{
3930bd37d32Smrg    Bres(XtNallowPasteControls, XtCAllowPasteControls,
3940bd37d32Smrg	 screen.allowPasteControls, False),
395d522f475Smrg    Bres(XtNallowSendEvents, XtCAllowSendEvents, screen.allowSendEvent0, False),
39620d2c4d2Smrg    Bres(XtNallowColorOps, XtCAllowColorOps, screen.allowColorOp0, DEF_ALLOW_COLOR),
397956cc18dSsnj    Bres(XtNallowFontOps, XtCAllowFontOps, screen.allowFontOp0, DEF_ALLOW_FONT),
398956cc18dSsnj    Bres(XtNallowTcapOps, XtCAllowTcapOps, screen.allowTcapOp0, DEF_ALLOW_TCAP),
399956cc18dSsnj    Bres(XtNallowTitleOps, XtCAllowTitleOps, screen.allowTitleOp0, DEF_ALLOW_TITLE),
400956cc18dSsnj    Bres(XtNallowWindowOps, XtCAllowWindowOps, screen.allowWindowOp0, DEF_ALLOW_WINDOW),
401d522f475Smrg    Bres(XtNaltIsNotMeta, XtCAltIsNotMeta, screen.alt_is_not_meta, False),
4020bd37d32Smrg    Bres(XtNaltSendsEscape, XtCAltSendsEscape, screen.alt_sends_esc, DEF_ALT_SENDS_ESC),
403e39b573cSmrg    Bres(XtNallowBoldFonts, XtCAllowBoldFonts, screen.allowBoldFonts, True),
404d522f475Smrg    Bres(XtNalwaysBoldMode, XtCAlwaysBoldMode, screen.always_bold_mode, False),
405d522f475Smrg    Bres(XtNalwaysHighlight, XtCAlwaysHighlight, screen.always_highlight, False),
406d522f475Smrg    Bres(XtNappcursorDefault, XtCAppcursorDefault, misc.appcursorDefault, False),
407d522f475Smrg    Bres(XtNappkeypadDefault, XtCAppkeypadDefault, misc.appkeypadDefault, False),
4080bd37d32Smrg    Bres(XtNalternateScroll, XtCScrollCond, screen.alternateScroll, False),
409d522f475Smrg    Bres(XtNautoWrap, XtCAutoWrap, misc.autoWrap, True),
410d522f475Smrg    Bres(XtNawaitInput, XtCAwaitInput, screen.awaitInput, False),
411d522f475Smrg    Bres(XtNfreeBoldBox, XtCFreeBoldBox, screen.free_bold_box, False),
4120bd37d32Smrg    Bres(XtNbackarrowKey, XtCBackarrowKey, screen.backarrow_key, DEF_BACKARO_BS),
413d522f475Smrg    Bres(XtNbellIsUrgent, XtCBellIsUrgent, screen.bellIsUrgent, False),
414d522f475Smrg    Bres(XtNbellOnReset, XtCBellOnReset, screen.bellOnReset, True),
415d522f475Smrg    Bres(XtNboldMode, XtCBoldMode, screen.bold_mode, True),
416d522f475Smrg    Bres(XtNbrokenSelections, XtCBrokenSelections, screen.brokenSelections, False),
417d522f475Smrg    Bres(XtNc132, XtCC132, screen.c132, False),
4180bd37d32Smrg    Bres(XtNcdXtraScroll, XtCCdXtraScroll, misc.cdXtraScroll, False),
419d522f475Smrg    Bres(XtNcurses, XtCCurses, screen.curses, False),
420d522f475Smrg    Bres(XtNcutNewline, XtCCutNewline, screen.cutNewline, True),
421d522f475Smrg    Bres(XtNcutToBeginningOfLine, XtCCutToBeginningOfLine,
422d522f475Smrg	 screen.cutToBeginningOfLine, True),
423d522f475Smrg    Bres(XtNdeleteIsDEL, XtCDeleteIsDEL, screen.delete_is_del, DEFDELETE_DEL),
424d522f475Smrg    Bres(XtNdynamicColors, XtCDynamicColors, misc.dynamicColors, True),
425d522f475Smrg    Bres(XtNeightBitControl, XtCEightBitControl, screen.control_eight_bits, False),
426d522f475Smrg    Bres(XtNeightBitInput, XtCEightBitInput, screen.input_eight_bits, True),
427d522f475Smrg    Bres(XtNeightBitOutput, XtCEightBitOutput, screen.output_eight_bits, True),
428d522f475Smrg    Bres(XtNhighlightSelection, XtCHighlightSelection,
429d522f475Smrg	 screen.highlight_selection, False),
430492d43a5Smrg    Bres(XtNshowWrapMarks, XtCShowWrapMarks, screen.show_wrap_marks, False),
431d522f475Smrg    Bres(XtNhpLowerleftBugCompat, XtCHpLowerleftBugCompat, screen.hp_ll_bc, False),
432d522f475Smrg    Bres(XtNi18nSelections, XtCI18nSelections, screen.i18nSelections, True),
433956cc18dSsnj    Bres(XtNfastScroll, XtCFastScroll, screen.fastscroll, False),
434d522f475Smrg    Bres(XtNjumpScroll, XtCJumpScroll, screen.jumpscroll, True),
435956cc18dSsnj    Bres(XtNkeepSelection, XtCKeepSelection, screen.keepSelection, True),
436d522f475Smrg    Bres(XtNloginShell, XtCLoginShell, misc.login_shell, False),
437d522f475Smrg    Bres(XtNmarginBell, XtCMarginBell, screen.marginbell, False),
4380bd37d32Smrg    Bres(XtNmetaSendsEscape, XtCMetaSendsEscape, screen.meta_sends_esc, DEF_META_SENDS_ESC),
439d522f475Smrg    Bres(XtNmultiScroll, XtCMultiScroll, screen.multiscroll, False),
440d522f475Smrg    Bres(XtNoldXtermFKeys, XtCOldXtermFKeys, screen.old_fkeys, False),
441d522f475Smrg    Bres(XtNpopOnBell, XtCPopOnBell, screen.poponbell, False),
442e39b573cSmrg    Bres(XtNprinterAutoClose, XtCPrinterAutoClose, SPS.printer_autoclose, False),
443e39b573cSmrg    Bres(XtNprinterExtent, XtCPrinterExtent, SPS.printer_extent, False),
444e39b573cSmrg    Bres(XtNprinterFormFeed, XtCPrinterFormFeed, SPS.printer_formfeed, False),
445e39b573cSmrg    Bres(XtNprinterNewLine, XtCPrinterNewLine, SPS.printer_newline, True),
446d522f475Smrg    Bres(XtNquietGrab, XtCQuietGrab, screen.quiet_grab, False),
447d522f475Smrg    Bres(XtNreverseVideo, XtCReverseVideo, misc.re_verse, False),
448d522f475Smrg    Bres(XtNreverseWrap, XtCReverseWrap, misc.reverseWrap, False),
449d522f475Smrg    Bres(XtNscrollBar, XtCScrollBar, misc.scrollbar, False),
450d522f475Smrg    Bres(XtNscrollKey, XtCScrollCond, screen.scrollkey, False),
451d522f475Smrg    Bres(XtNscrollTtyOutput, XtCScrollCond, screen.scrollttyoutput, True),
452d522f475Smrg    Bres(XtNselectToClipboard, XtCSelectToClipboard,
453d522f475Smrg	 screen.selectToClipboard, False),
454d522f475Smrg    Bres(XtNsignalInhibit, XtCSignalInhibit, misc.signalInhibit, False),
455d522f475Smrg    Bres(XtNtiteInhibit, XtCTiteInhibit, misc.titeInhibit, False),
456d522f475Smrg    Bres(XtNtiXtraScroll, XtCTiXtraScroll, misc.tiXtraScroll, False),
457d522f475Smrg    Bres(XtNtrimSelection, XtCTrimSelection, screen.trim_selection, False),
458d522f475Smrg    Bres(XtNunderLine, XtCUnderLine, screen.underline, True),
459d522f475Smrg    Bres(XtNvisualBell, XtCVisualBell, screen.visualbell, False),
4600bd37d32Smrg    Bres(XtNvisualBellLine, XtCVisualBellLine, screen.flash_line, False),
4610bd37d32Smrg
4620bd37d32Smrg    Dres(XtNscaleHeight, XtCScaleHeight, screen.scale_height, "1.0"),
463d522f475Smrg
464d522f475Smrg    Ires(XtNbellSuppressTime, XtCBellSuppressTime, screen.bellSuppressTime, BELLSUPPRESSMSEC),
465956cc18dSsnj    Ires(XtNfontWarnings, XtCFontWarnings, misc.fontWarnings, fwResource),
466d522f475Smrg    Ires(XtNinternalBorder, XtCBorderWidth, screen.border, DEFBORDER),
467d522f475Smrg    Ires(XtNlimitResize, XtCLimitResize, misc.limit_resize, 1),
468d522f475Smrg    Ires(XtNmultiClickTime, XtCMultiClickTime, screen.multiClickTime, MULTICLICKTIME),
469d522f475Smrg    Ires(XtNnMarginBell, XtCColumn, screen.nmarginbell, N_MARGINBELL),
470d522f475Smrg    Ires(XtNpointerMode, XtCPointerMode, screen.pointer_mode, DEF_POINTER_MODE),
471d522f475Smrg    Ires(XtNprinterControlMode, XtCPrinterControlMode,
472e39b573cSmrg	 SPS.printer_controlmode, 0),
47320d2c4d2Smrg    Ires(XtNtitleModes, XtCTitleModes, screen.title_modes, DEF_TITLE_MODES),
474d522f475Smrg    Ires(XtNvisualBellDelay, XtCVisualBellDelay, screen.visualBellDelay, 100),
475d522f475Smrg    Ires(XtNsaveLines, XtCSaveLines, screen.savelines, SAVELINES),
476d522f475Smrg    Ires(XtNscrollBarBorder, XtCScrollBarBorder, screen.scrollBarBorder, 1),
477d522f475Smrg    Ires(XtNscrollLines, XtCScrollLines, screen.scrolllines, SCROLLLINES),
478d522f475Smrg
479d522f475Smrg    Sres(XtNinitialFont, XtCInitialFont, screen.initial_font, NULL),
480d522f475Smrg    Sres(XtNfont1, XtCFont1, screen.MenuFontName(fontMenu_font1), NULL),
481d522f475Smrg    Sres(XtNfont2, XtCFont2, screen.MenuFontName(fontMenu_font2), NULL),
482d522f475Smrg    Sres(XtNfont3, XtCFont3, screen.MenuFontName(fontMenu_font3), NULL),
483d522f475Smrg    Sres(XtNfont4, XtCFont4, screen.MenuFontName(fontMenu_font4), NULL),
484d522f475Smrg    Sres(XtNfont5, XtCFont5, screen.MenuFontName(fontMenu_font5), NULL),
485d522f475Smrg    Sres(XtNfont6, XtCFont6, screen.MenuFontName(fontMenu_font6), NULL),
486956cc18dSsnj
487d522f475Smrg    Sres(XtNanswerbackString, XtCAnswerbackString, screen.answer_back, ""),
488d522f475Smrg    Sres(XtNboldFont, XtCBoldFont, misc.default_font.f_b, DEFBOLDFONT),
489d522f475Smrg    Sres(XtNcharClass, XtCCharClass, screen.charClass, NULL),
490d522f475Smrg    Sres(XtNdecTerminalID, XtCDecTerminalID, screen.term_id, DFT_DECID),
491956cc18dSsnj    Sres(XtNdefaultString, XtCDefaultString, screen.default_string, "#"),
49220d2c4d2Smrg    Sres(XtNdisallowedColorOps, XtCDisallowedColorOps,
49320d2c4d2Smrg	 screen.disallowedColorOps, DEF_DISALLOWED_COLOR),
49420d2c4d2Smrg    Sres(XtNdisallowedFontOps, XtCDisallowedFontOps,
49520d2c4d2Smrg	 screen.disallowedFontOps, DEF_DISALLOWED_FONT),
49620d2c4d2Smrg    Sres(XtNdisallowedTcapOps, XtCDisallowedTcapOps,
49720d2c4d2Smrg	 screen.disallowedTcapOps, DEF_DISALLOWED_TCAP),
49820d2c4d2Smrg    Sres(XtNdisallowedWindowOps, XtCDisallowedWindowOps,
49920d2c4d2Smrg	 screen.disallowedWinOps, DEF_DISALLOWED_WINDOW),
5000bd37d32Smrg    Sres(XtNeightBitMeta, XtCEightBitMeta, screen.eight_bit_meta_s, DEF_8BIT_META),
501956cc18dSsnj    Sres(XtNeightBitSelectTypes, XtCEightBitSelectTypes,
502956cc18dSsnj	 screen.eightbit_select_types, NULL),
503d522f475Smrg    Sres(XtNfont, XtCFont, misc.default_font.f_n, DEFFONT),
504d522f475Smrg    Sres(XtNgeometry, XtCGeometry, misc.geo_metry, NULL),
505d522f475Smrg    Sres(XtNkeyboardDialect, XtCKeyboardDialect, screen.keyboard_dialect, DFT_KBD_DIALECT),
506e39b573cSmrg    Sres(XtNprinterCommand, XtCPrinterCommand, SPS.printer_command, ""),
507d522f475Smrg    Sres(XtNtekGeometry, XtCGeometry, misc.T_geometry, NULL),
508d522f475Smrg
509d522f475Smrg    Tres(XtNcursorColor, XtCCursorColor, TEXT_CURSOR, XtDefaultForeground),
510d522f475Smrg    Tres(XtNforeground, XtCForeground, TEXT_FG, XtDefaultForeground),
511d522f475Smrg    Tres(XtNpointerColor, XtCPointerColor, MOUSE_FG, XtDefaultForeground),
512d522f475Smrg    Tres(XtNbackground, XtCBackground, TEXT_BG, XtDefaultBackground),
513d522f475Smrg    Tres(XtNpointerColorBackground, XtCBackground, MOUSE_BG, XtDefaultBackground),
514d522f475Smrg
515d522f475Smrg    {XtNresizeGravity, XtCResizeGravity, XtRGravity, sizeof(XtGravity),
516d522f475Smrg     XtOffsetOf(XtermWidgetRec, misc.resizeGravity),
517d522f475Smrg     XtRImmediate, (XtPointer) SouthWestGravity},
518d522f475Smrg
519d522f475Smrg    {XtNpointerShape, XtCCursor, XtRCursor, sizeof(Cursor),
520d522f475Smrg     XtOffsetOf(XtermWidgetRec, screen.pointer_cursor),
521d522f475Smrg     XtRString, (XtPointer) "xterm"},
522d522f475Smrg
523d522f475Smrg#ifdef ALLOWLOGGING
524d522f475Smrg    Bres(XtNlogInhibit, XtCLogInhibit, misc.logInhibit, False),
525d522f475Smrg    Bres(XtNlogging, XtCLogging, misc.log_on, False),
526d522f475Smrg    Sres(XtNlogFile, XtCLogfile, screen.logfile, NULL),
527d522f475Smrg#endif
528d522f475Smrg
529d522f475Smrg#ifndef NO_ACTIVE_ICON
5300bd37d32Smrg    Sres("activeIcon", "ActiveIcon", misc.active_icon_s, "default"),
531d522f475Smrg    Ires("iconBorderWidth", XtCBorderWidth, misc.icon_border_width, 2),
532492d43a5Smrg    Sres("iconFont", "IconFont", screen.icon_fontname, "nil2"),
533d522f475Smrg    Cres("iconBorderColor", XtCBorderColor, misc.icon_border_pixel, XtDefaultBackground),
534d522f475Smrg#endif				/* NO_ACTIVE_ICON */
535d522f475Smrg
536d522f475Smrg#if OPT_BLINK_CURS
537d522f475Smrg    Bres(XtNcursorBlink, XtCCursorBlink, screen.cursor_blink, False),
538d522f475Smrg#endif
5392eaa94a1Schristos    Bres(XtNcursorUnderline, XtCCursorUnderline, screen.cursor_underline, False),
540d522f475Smrg
541d522f475Smrg#if OPT_BLINK_TEXT
542d522f475Smrg    Bres(XtNshowBlinkAsBold, XtCCursorBlink, screen.blink_as_bold, DEFBLINKASBOLD),
543d522f475Smrg#endif
544d522f475Smrg
545d522f475Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
546d522f475Smrg    Ires(XtNcursorOnTime, XtCCursorOnTime, screen.blink_on, 600),
547d522f475Smrg    Ires(XtNcursorOffTime, XtCCursorOffTime, screen.blink_off, 300),
548d522f475Smrg#endif
549d522f475Smrg
550d522f475Smrg#if OPT_BOX_CHARS
551d522f475Smrg    Bres(XtNforceBoxChars, XtCForceBoxChars, screen.force_box_chars, False),
55220d2c4d2Smrg    Bres(XtNforcePackedFont, XtCForcePackedFont, screen.force_packed, True),
553d522f475Smrg    Bres(XtNshowMissingGlyphs, XtCShowMissingGlyphs, screen.force_all_chars, False),
554d522f475Smrg#endif
555d522f475Smrg
556d522f475Smrg#if OPT_BROKEN_OSC
557d522f475Smrg    Bres(XtNbrokenLinuxOSC, XtCBrokenLinuxOSC, screen.brokenLinuxOSC, True),
558d522f475Smrg#endif
559d522f475Smrg
560d522f475Smrg#if OPT_BROKEN_ST
561e39b573cSmrg    Bres(XtNbrokenStringTerm, XtCBrokenStringTerm, screen.brokenStringTerm, False),
562d522f475Smrg#endif
563d522f475Smrg
564d522f475Smrg#if OPT_C1_PRINT
565d522f475Smrg    Bres(XtNallowC1Printable, XtCAllowC1Printable, screen.c1_printable, False),
566d522f475Smrg#endif
567d522f475Smrg
568d522f475Smrg#if OPT_CLIP_BOLD
569d522f475Smrg    Bres(XtNuseClipping, XtCUseClipping, screen.use_clipping, True),
570d522f475Smrg#endif
571d522f475Smrg
572d522f475Smrg#if OPT_DEC_CHRSET
573d522f475Smrg    Bres(XtNfontDoublesize, XtCFontDoublesize, screen.font_doublesize, True),
574d522f475Smrg    Ires(XtNcacheDoublesize, XtCCacheDoublesize, screen.cache_doublesize, NUM_CHRSET),
575d522f475Smrg#endif
576d522f475Smrg
577d522f475Smrg#if OPT_HIGHLIGHT_COLOR
578d522f475Smrg    Tres(XtNhighlightColor, XtCHighlightColor, HIGHLIGHT_BG, XtDefaultForeground),
579d522f475Smrg    Tres(XtNhighlightTextColor, XtCHighlightTextColor, HIGHLIGHT_FG, XtDefaultBackground),
580d522f475Smrg    Bres(XtNhighlightReverse, XtCHighlightReverse, screen.hilite_reverse, True),
581d522f475Smrg    Bres(XtNhighlightColorMode, XtCHighlightColorMode, screen.hilite_color, Maybe),
582d522f475Smrg#endif				/* OPT_HIGHLIGHT_COLOR */
583d522f475Smrg
584d522f475Smrg#if OPT_INPUT_METHOD
585d522f475Smrg    Bres(XtNopenIm, XtCOpenIm, misc.open_im, True),
586d522f475Smrg    Sres(XtNinputMethod, XtCInputMethod, misc.input_method, NULL),
587d522f475Smrg    Sres(XtNpreeditType, XtCPreeditType, misc.preedit_type,
588d522f475Smrg	 "OverTheSpot,Root"),
589956cc18dSsnj    Ires(XtNretryInputMethod, XtCRetryInputMethod, misc.retry_im, 3),
590d522f475Smrg#endif
591d522f475Smrg
592d522f475Smrg#if OPT_ISO_COLORS
593d522f475Smrg    Bres(XtNboldColors, XtCColorMode, screen.boldColors, True),
594d522f475Smrg    Ires(XtNveryBoldColors, XtCVeryBoldColors, screen.veryBoldColors, 0),
595d522f475Smrg    Bres(XtNcolorMode, XtCColorMode, screen.colorMode, DFT_COLORMODE),
596d522f475Smrg
597d522f475Smrg    Bres(XtNcolorAttrMode, XtCColorAttrMode, screen.colorAttrMode, False),
598d522f475Smrg    Bres(XtNcolorBDMode, XtCColorAttrMode, screen.colorBDMode, False),
599d522f475Smrg    Bres(XtNcolorBLMode, XtCColorAttrMode, screen.colorBLMode, False),
600d522f475Smrg    Bres(XtNcolorRVMode, XtCColorAttrMode, screen.colorRVMode, False),
601d522f475Smrg    Bres(XtNcolorULMode, XtCColorAttrMode, screen.colorULMode, False),
602d522f475Smrg    Bres(XtNitalicULMode, XtCColorAttrMode, screen.italicULMode, False),
603d522f475Smrg
604d522f475Smrg    COLOR_RES("0", screen.Acolors[COLOR_0], DFT_COLOR("black")),
605d522f475Smrg    COLOR_RES("1", screen.Acolors[COLOR_1], DFT_COLOR("red3")),
606d522f475Smrg    COLOR_RES("2", screen.Acolors[COLOR_2], DFT_COLOR("green3")),
607d522f475Smrg    COLOR_RES("3", screen.Acolors[COLOR_3], DFT_COLOR("yellow3")),
608d522f475Smrg    COLOR_RES("4", screen.Acolors[COLOR_4], DFT_COLOR(DEF_COLOR4)),
609d522f475Smrg    COLOR_RES("5", screen.Acolors[COLOR_5], DFT_COLOR("magenta3")),
610d522f475Smrg    COLOR_RES("6", screen.Acolors[COLOR_6], DFT_COLOR("cyan3")),
611d522f475Smrg    COLOR_RES("7", screen.Acolors[COLOR_7], DFT_COLOR("gray90")),
612d522f475Smrg    COLOR_RES("8", screen.Acolors[COLOR_8], DFT_COLOR("gray50")),
613d522f475Smrg    COLOR_RES("9", screen.Acolors[COLOR_9], DFT_COLOR("red")),
614d522f475Smrg    COLOR_RES("10", screen.Acolors[COLOR_10], DFT_COLOR("green")),
615d522f475Smrg    COLOR_RES("11", screen.Acolors[COLOR_11], DFT_COLOR("yellow")),
616d522f475Smrg    COLOR_RES("12", screen.Acolors[COLOR_12], DFT_COLOR(DEF_COLOR12)),
617d522f475Smrg    COLOR_RES("13", screen.Acolors[COLOR_13], DFT_COLOR("magenta")),
618d522f475Smrg    COLOR_RES("14", screen.Acolors[COLOR_14], DFT_COLOR("cyan")),
619d522f475Smrg    COLOR_RES("15", screen.Acolors[COLOR_15], DFT_COLOR("white")),
620d522f475Smrg    COLOR_RES("BD", screen.Acolors[COLOR_BD], DFT_COLOR(XtDefaultForeground)),
621d522f475Smrg    COLOR_RES("BL", screen.Acolors[COLOR_BL], DFT_COLOR(XtDefaultForeground)),
622d522f475Smrg    COLOR_RES("UL", screen.Acolors[COLOR_UL], DFT_COLOR(XtDefaultForeground)),
623d522f475Smrg    COLOR_RES("RV", screen.Acolors[COLOR_RV], DFT_COLOR(XtDefaultForeground)),
624d522f475Smrg
625d522f475Smrg#if !OPT_COLOR_RES2
626d522f475Smrg#if OPT_256_COLORS
627d522f475Smrg# include <256colres.h>
628d522f475Smrg#elif OPT_88_COLORS
629d522f475Smrg# include <88colres.h>
630d522f475Smrg#endif
631d522f475Smrg#endif				/* !OPT_COLOR_RES2 */
632d522f475Smrg
633d522f475Smrg#endif				/* OPT_ISO_COLORS */
634d522f475Smrg
63520d2c4d2Smrg    CLICK_RES("2", screen.onClick[1], "word"),
63620d2c4d2Smrg    CLICK_RES("3", screen.onClick[2], "line"),
63720d2c4d2Smrg    CLICK_RES("4", screen.onClick[3], 0),
63820d2c4d2Smrg    CLICK_RES("5", screen.onClick[4], 0),
63920d2c4d2Smrg
640d522f475Smrg#if OPT_MOD_FKEYS
6410bd37d32Smrg    Ires(XtNmodifyKeyboard, XtCModifyKeyboard,
6420bd37d32Smrg	 keyboard.modify_1st.allow_keys, 0),
643d522f475Smrg    Ires(XtNmodifyCursorKeys, XtCModifyCursorKeys,
644d522f475Smrg	 keyboard.modify_1st.cursor_keys, 2),
645d522f475Smrg    Ires(XtNmodifyFunctionKeys, XtCModifyFunctionKeys,
646d522f475Smrg	 keyboard.modify_1st.function_keys, 2),
647d522f475Smrg    Ires(XtNmodifyKeypadKeys, XtCModifyKeypadKeys,
648d522f475Smrg	 keyboard.modify_1st.keypad_keys, 0),
649d522f475Smrg    Ires(XtNmodifyOtherKeys, XtCModifyOtherKeys,
650d522f475Smrg	 keyboard.modify_1st.other_keys, 0),
651d522f475Smrg    Ires(XtNmodifyStringKeys, XtCModifyStringKeys,
652d522f475Smrg	 keyboard.modify_1st.string_keys, 0),
653d522f475Smrg    Ires(XtNformatOtherKeys, XtCFormatOtherKeys,
654d522f475Smrg	 keyboard.format_keys, 0),
655d522f475Smrg#endif
656d522f475Smrg
657d522f475Smrg#if OPT_NUM_LOCK
658d522f475Smrg    Bres(XtNalwaysUseMods, XtCAlwaysUseMods, misc.alwaysUseMods, False),
659d522f475Smrg    Bres(XtNnumLock, XtCNumLock, misc.real_NumLock, True),
660d522f475Smrg#endif
661d522f475Smrg
662d522f475Smrg#if OPT_PRINT_COLORS
663e39b573cSmrg    Ires(XtNprintAttributes, XtCPrintAttributes, SPS.print_attributes, 1),
664d522f475Smrg#endif
665d522f475Smrg
666d522f475Smrg#if OPT_SHIFT_FONTS
667d522f475Smrg    Bres(XtNshiftFonts, XtCShiftFonts, misc.shift_fonts, True),
668d522f475Smrg#endif
669d522f475Smrg
670d522f475Smrg#if OPT_SUNPC_KBD
671d522f475Smrg    Ires(XtNctrlFKeys, XtCCtrlFKeys, misc.ctrl_fkeys, 10),
672d522f475Smrg#endif
673d522f475Smrg
674d522f475Smrg#if OPT_TEK4014
675d522f475Smrg    Bres(XtNtekInhibit, XtCTekInhibit, misc.tekInhibit, False),
676d522f475Smrg    Bres(XtNtekSmall, XtCTekSmall, misc.tekSmall, False),
677d522f475Smrg    Bres(XtNtekStartup, XtCTekStartup, misc.TekEmu, False),
678d522f475Smrg#endif
679d522f475Smrg
680d522f475Smrg#if OPT_TOOLBAR
681d522f475Smrg    Wres(XtNmenuBar, XtCMenuBar, VT100_TB_INFO(menu_bar), 0),
682d522f475Smrg    Ires(XtNmenuHeight, XtCMenuHeight, VT100_TB_INFO(menu_height), 25),
683d522f475Smrg#endif
684d522f475Smrg
685d522f475Smrg#if OPT_WIDE_CHARS
686d522f475Smrg    Bres(XtNcjkWidth, XtCCjkWidth, misc.cjk_width, False),
687d522f475Smrg    Bres(XtNmkWidth, XtCMkWidth, misc.mk_width, False),
6880bd37d32Smrg    Bres(XtNprecompose, XtCPrecompose, screen.normalized_c, True),
689d522f475Smrg    Bres(XtNutf8Latin1, XtCUtf8Latin1, screen.utf8_latin1, False),
690d522f475Smrg    Bres(XtNutf8Title, XtCUtf8Title, screen.utf8_title, False),
691d522f475Smrg    Bres(XtNvt100Graphics, XtCVT100Graphics, screen.vt100_graphics, True),
692d522f475Smrg    Bres(XtNwideChars, XtCWideChars, screen.wide_chars, False),
693d522f475Smrg    Ires(XtNcombiningChars, XtCCombiningChars, screen.max_combining, 2),
694d522f475Smrg    Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 256),
695d522f475Smrg    Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 1024),
696e39b573cSmrg    Sres(XtNutf8, XtCUtf8, screen.utf8_mode_s, "default"),
697e39b573cSmrg    Sres(XtNutf8Fonts, XtCUtf8Fonts, screen.utf8_fonts_s, "default"),
698d522f475Smrg    Sres(XtNwideBoldFont, XtCWideBoldFont, misc.default_font.f_wb, DEFWIDEBOLDFONT),
699d522f475Smrg    Sres(XtNwideFont, XtCWideFont, misc.default_font.f_w, DEFWIDEFONT),
700956cc18dSsnj    Sres(XtNutf8SelectTypes, XtCUtf8SelectTypes, screen.utf8_select_types, NULL),
701d522f475Smrg#endif
702d522f475Smrg
703d522f475Smrg#if OPT_LUIT_PROG
704d522f475Smrg    Sres(XtNlocale, XtCLocale, misc.locale_str, "medium"),
705d522f475Smrg    Sres(XtNlocaleFilter, XtCLocaleFilter, misc.localefilter, DEFLOCALEFILTER),
706d522f475Smrg#endif
707d522f475Smrg
708d522f475Smrg#if OPT_INPUT_METHOD
709d522f475Smrg    Sres(XtNximFont, XtCXimFont, misc.f_x, DEFXIMFONT),
710d522f475Smrg#endif
711d522f475Smrg
71220d2c4d2Smrg#if OPT_SCROLL_LOCK
71320d2c4d2Smrg    Bres(XtNallowScrollLock, XtCAllowScrollLock, screen.allowScrollLock0, False),
71420d2c4d2Smrg#endif
71520d2c4d2Smrg
716d522f475Smrg#if OPT_XMC_GLITCH
717d522f475Smrg    Bres(XtNxmcInline, XtCXmcInline, screen.xmc_inline, False),
718d522f475Smrg    Bres(XtNxmcMoveSGR, XtCXmcMoveSGR, screen.move_sgr_ok, True),
719d522f475Smrg    Ires(XtNxmcAttributes, XtCXmcAttributes, screen.xmc_attributes, 1),
720d522f475Smrg    Ires(XtNxmcGlitch, XtCXmcGlitch, screen.xmc_glitch, 0),
721d522f475Smrg#endif
722d522f475Smrg
723d522f475Smrg#ifdef SCROLLBAR_RIGHT
724d522f475Smrg    Bres(XtNrightScrollBar, XtCRightScrollBar, misc.useRight, False),
725d522f475Smrg#endif
726d522f475Smrg
727d522f475Smrg#if OPT_RENDERFONT
728d522f475Smrg#define RES_FACESIZE(n) Dres(XtNfaceSize #n, XtCFaceSize #n, misc.face_size[n], "0.0")
729d522f475Smrg    RES_FACESIZE(1),
730d522f475Smrg    RES_FACESIZE(2),
731d522f475Smrg    RES_FACESIZE(3),
732d522f475Smrg    RES_FACESIZE(4),
733d522f475Smrg    RES_FACESIZE(5),
734d522f475Smrg    RES_FACESIZE(6),
735d522f475Smrg    Dres(XtNfaceSize, XtCFaceSize, misc.face_size[0], DEFFACESIZE),
736d522f475Smrg    Sres(XtNfaceName, XtCFaceName, misc.face_name, DEFFACENAME),
737d522f475Smrg    Sres(XtNfaceNameDoublesize, XtCFaceNameDoublesize, misc.face_wide_name, DEFFACENAME),
73820d2c4d2Smrg    Sres(XtNrenderFont, XtCRenderFont, misc.render_font_s, "default"),
739d522f475Smrg#endif
740d522f475Smrg};
741d522f475Smrg
742d522f475Smrgstatic Boolean VTSetValues(Widget cur, Widget request, Widget new_arg,
743d522f475Smrg			   ArgList args, Cardinal *num_args);
744d522f475Smrgstatic void VTClassInit(void);
745d522f475Smrgstatic void VTDestroy(Widget w);
746d522f475Smrgstatic void VTExpose(Widget w, XEvent * event, Region region);
747d522f475Smrgstatic void VTInitialize(Widget wrequest, Widget new_arg, ArgList args,
748d522f475Smrg			 Cardinal *num_args);
749d522f475Smrgstatic void VTRealize(Widget w, XtValueMask * valuemask,
750d522f475Smrg		      XSetWindowAttributes * values);
751d522f475Smrgstatic void VTResize(Widget w);
752d522f475Smrg
753d522f475Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
754956cc18dSsnjstatic void VTInitI18N(XtermWidget);
755d522f475Smrg#endif
756d522f475Smrg
757d522f475Smrg#ifdef VMS
758d522f475Smrgglobaldef {
759d522f475Smrg    "xtermclassrec"
760d522f475Smrg} noshare
761d522f475Smrg
762d522f475Smrg#else
763d522f475Smrgstatic
764d522f475Smrg#endif				/* VMS */
765d522f475SmrgWidgetClassRec xtermClassRec =
766d522f475Smrg{
767d522f475Smrg    {
76820d2c4d2Smrg	/* core_class fields */
76920d2c4d2Smrg	(WidgetClass) & widgetClassRec,		/* superclass   */
770d522f475Smrg	"VT100",		/* class_name                   */
771d522f475Smrg	sizeof(XtermWidgetRec),	/* widget_size                  */
772d522f475Smrg	VTClassInit,		/* class_initialize             */
773d522f475Smrg	NULL,			/* class_part_initialize        */
774d522f475Smrg	False,			/* class_inited                 */
775d522f475Smrg	VTInitialize,		/* initialize                   */
776d522f475Smrg	NULL,			/* initialize_hook              */
777d522f475Smrg	VTRealize,		/* realize                      */
778d522f475Smrg	actionsList,		/* actions                      */
779d522f475Smrg	XtNumber(actionsList),	/* num_actions                  */
78020d2c4d2Smrg	xterm_resources,	/* resources                    */
78120d2c4d2Smrg	XtNumber(xterm_resources),	/* num_resources        */
782d522f475Smrg	NULLQUARK,		/* xrm_class                    */
783d522f475Smrg	True,			/* compress_motion              */
784d522f475Smrg	False,			/* compress_exposure            */
785d522f475Smrg	True,			/* compress_enterleave          */
786d522f475Smrg	False,			/* visible_interest             */
787d522f475Smrg	VTDestroy,		/* destroy                      */
788d522f475Smrg	VTResize,		/* resize                       */
789d522f475Smrg	VTExpose,		/* expose                       */
790d522f475Smrg	VTSetValues,		/* set_values                   */
791d522f475Smrg	NULL,			/* set_values_hook              */
792d522f475Smrg	XtInheritSetValuesAlmost,	/* set_values_almost    */
793d522f475Smrg	NULL,			/* get_values_hook              */
794d522f475Smrg	NULL,			/* accept_focus                 */
795d522f475Smrg	XtVersion,		/* version                      */
796d522f475Smrg	NULL,			/* callback_offsets             */
797a1f3da82Smrg	0,			/* tm_table                     */
798d522f475Smrg	XtInheritQueryGeometry,	/* query_geometry               */
799d522f475Smrg	XtInheritDisplayAccelerator,	/* display_accelerator  */
800d522f475Smrg	NULL			/* extension                    */
801d522f475Smrg    }
802d522f475Smrg};
803d522f475Smrg
804d522f475Smrg#ifdef VMS
805d522f475Smrgglobaldef {
806d522f475Smrg    "xtermwidgetclass"
807d522f475Smrg}
808d522f475Smrgnoshare
809d522f475Smrg#endif /* VMS */
810d522f475SmrgWidgetClass xtermWidgetClass = (WidgetClass) & xtermClassRec;
811d522f475Smrg
812d522f475Smrg/*
813d522f475Smrg * Add input-actions for widgets that are overlooked (scrollbar and toolbar):
814d522f475Smrg *
815d522f475Smrg *	a) Sometimes the scrollbar passes through translations, sometimes it
816d522f475Smrg *	   doesn't.  We add the KeyPress translations here, just to be sure.
817d522f475Smrg *	b) In the normal (non-toolbar) configuration, the xterm widget covers
818d522f475Smrg *	   almost all of the window.  With a toolbar, there's a relatively
819d522f475Smrg *	   large area that the user would expect to enter keystrokes since the
820d522f475Smrg *	   program can get the focus.
821d522f475Smrg */
822d522f475Smrgvoid
823d522f475SmrgxtermAddInput(Widget w)
824d522f475Smrg{
825d522f475Smrg    /* *INDENT-OFF* */
826d522f475Smrg    XtActionsRec input_actions[] = {
827d522f475Smrg	{ "insert",		    HandleKeyPressed }, /* alias */
828d522f475Smrg	{ "insert-eight-bit",	    HandleEightBitKeyPressed },
829d522f475Smrg	{ "insert-seven-bit",	    HandleKeyPressed },
830d522f475Smrg	{ "secure",		    HandleSecure },
831d522f475Smrg	{ "string",		    HandleStringEvent },
832d522f475Smrg	{ "scroll-back",	    HandleScrollBack },
833d522f475Smrg	{ "scroll-forw",	    HandleScrollForward },
834d522f475Smrg	{ "select-cursor-end",	    HandleKeyboardSelectEnd },
835d522f475Smrg	{ "select-cursor-extend",   HandleKeyboardSelectExtend },
836d522f475Smrg	{ "select-cursor-start",    HandleKeyboardSelectStart },
837d522f475Smrg	{ "insert-selection",	    HandleInsertSelection },
838d522f475Smrg	{ "select-start",	    HandleSelectStart },
839d522f475Smrg	{ "select-extend",	    HandleSelectExtend },
840d522f475Smrg	{ "start-extend",	    HandleStartExtend },
841d522f475Smrg	{ "select-end",		    HandleSelectEnd },
842d522f475Smrg	{ "clear-saved-lines",	    HandleClearSavedLines },
843d522f475Smrg	{ "popup-menu",		    HandlePopupMenu },
844d522f475Smrg	{ "bell",		    HandleBell },
845d522f475Smrg	{ "ignore",		    HandleIgnore },
846d522f475Smrg#if OPT_DABBREV
847d522f475Smrg	{ "dabbrev-expand",	    HandleDabbrevExpand },
848d522f475Smrg#endif
849a1f3da82Smrg#if OPT_MAXIMIZE
850a1f3da82Smrg	{ "fullscreen",		    HandleFullscreen },
851a1f3da82Smrg#endif
85220d2c4d2Smrg#if OPT_SCROLL_LOCK
85320d2c4d2Smrg	{ "scroll-lock",	    HandleScrollLock },
85420d2c4d2Smrg#endif
855d522f475Smrg#if OPT_SHIFT_FONTS
856d522f475Smrg	{ "larger-vt-font",	    HandleLargerFont },
857d522f475Smrg	{ "smaller-vt-font",	    HandleSmallerFont },
858d522f475Smrg#endif
859d522f475Smrg    };
860d522f475Smrg    /* *INDENT-ON* */
861d522f475Smrg
862956cc18dSsnj    TRACE_TRANS("BEFORE", w);
863d522f475Smrg    XtAppAddActions(app_con, input_actions, XtNumber(input_actions));
864d522f475Smrg    XtAugmentTranslations(w, XtParseTranslationTable(defaultTranslations));
865956cc18dSsnj    TRACE_TRANS("AFTER:", w);
866d522f475Smrg
867d522f475Smrg#if OPT_EXTRA_PASTE
868d522f475Smrg    if (term && term->keyboard.extra_translations)
869d522f475Smrg	XtOverrideTranslations((Widget) term, XtParseTranslationTable(term->keyboard.extra_translations));
870d522f475Smrg#endif
871d522f475Smrg}
872d522f475Smrg
873d522f475Smrg#if OPT_ISO_COLORS
874956cc18dSsnj#ifdef EXP_BOGUS_FG
875956cc18dSsnjstatic Bool
876956cc18dSsnjCheckBogusForeground(TScreen * screen, const char *tag)
877956cc18dSsnj{
878956cc18dSsnj    int row = -1, col = -1, pass;
879956cc18dSsnj    Bool isClear = True;
880956cc18dSsnj
881956cc18dSsnj    (void) tag;
882956cc18dSsnj    for (pass = 0; pass < 2; ++pass) {
883956cc18dSsnj	row = screen->cur_row;
884956cc18dSsnj	for (; isClear && (row <= screen->max_row); ++row) {
885956cc18dSsnj	    LineData *ld = getLineData(screen, row)->;
88620d2c4d2Smrg
88720d2c4d2Smrg	    if (ld != 0) {
88820d2c4d2Smrg		Char *attribs = ld->attribs;
88920d2c4d2Smrg
89020d2c4d2Smrg		col = (row == screen->cur_row) ? screen->cur_col : 0;
89120d2c4d2Smrg		for (; isClear && (col <= screen->max_col); ++col) {
89220d2c4d2Smrg		    unsigned flags = attribs[col];
89320d2c4d2Smrg		    if (pass) {
89420d2c4d2Smrg			flags &= ~FG_COLOR;
89520d2c4d2Smrg			attribs[col] = (Char) flags;
89620d2c4d2Smrg		    } else if ((flags & BG_COLOR)) {
89720d2c4d2Smrg			isClear = False;
89820d2c4d2Smrg		    } else if ((flags & FG_COLOR)) {
89920d2c4d2Smrg			unsigned ch = ld->charData[col];
90020d2c4d2Smrg			isClear = ((ch == ' ') || (ch == 0));
90120d2c4d2Smrg		    } else {
90220d2c4d2Smrg			isClear = False;
90320d2c4d2Smrg		    }
904956cc18dSsnj		}
905956cc18dSsnj	    }
906956cc18dSsnj	}
907956cc18dSsnj    }
908956cc18dSsnj    TRACE(("%s checked %d,%d to %d,%d %s pass %d\n",
909956cc18dSsnj	   tag, screen->cur_row, screen->cur_col,
910956cc18dSsnj	   row, col,
911956cc18dSsnj	   isClear && pass ? "cleared" : "unchanged",
912956cc18dSsnj	   pass));
913956cc18dSsnj
914956cc18dSsnj    return isClear;
915956cc18dSsnj}
916956cc18dSsnj#endif
917956cc18dSsnj
918d522f475Smrg/*
919d522f475Smrg * The terminal's foreground and background colors are set via two mechanisms:
920d522f475Smrg *	text (cur_foreground, cur_background values that are passed down to
921d522f475Smrg *		XDrawImageString and XDrawString)
922d522f475Smrg *	area (X11 graphics context used in XClearArea and XFillRectangle)
923d522f475Smrg */
924d522f475Smrgvoid
925d522f475SmrgSGR_Foreground(XtermWidget xw, int color)
926d522f475Smrg{
92720d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
928d522f475Smrg    Pixel fg;
929d522f475Smrg
930d522f475Smrg    if (color >= 0) {
93120d2c4d2Smrg	UIntSet(xw->flags, FG_COLOR);
932d522f475Smrg    } else {
93320d2c4d2Smrg	UIntClr(xw->flags, FG_COLOR);
934d522f475Smrg    }
935d522f475Smrg    fg = getXtermForeground(xw, xw->flags, color);
936d522f475Smrg    xw->cur_foreground = color;
937d522f475Smrg
938d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcNorm, fg);
939d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcNormReverse, fg);
940d522f475Smrg
941d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcBold, fg);
942d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcBoldReverse, fg);
943956cc18dSsnj
944956cc18dSsnj#ifdef EXP_BOGUS_FG
945956cc18dSsnj    /*
946956cc18dSsnj     * If we've just turned off the foreground color, check for blank cells
947956cc18dSsnj     * which have no background color, but do have foreground color.  This
948956cc18dSsnj     * could happen due to setting the foreground color just before scrolling.
949956cc18dSsnj     *
950956cc18dSsnj     * Those cells look uncolored, but will confuse ShowCursor(), which looks
95120d2c4d2Smrg     * for the colors in the current cell, and will see the foreground color.
952956cc18dSsnj     * In that case, remove the foreground color from the blank cells.
953956cc18dSsnj     */
954956cc18dSsnj    if (color < 0) {
955956cc18dSsnj	CheckBogusForeground(screen, "SGR_Foreground");
956956cc18dSsnj    }
957956cc18dSsnj#endif
958d522f475Smrg}
959d522f475Smrg
960d522f475Smrgvoid
961d522f475SmrgSGR_Background(XtermWidget xw, int color)
962d522f475Smrg{
96320d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
964d522f475Smrg    Pixel bg;
965d522f475Smrg
966d522f475Smrg    /*
967d522f475Smrg     * An indexing operation may have set screen->scroll_amt, which would
968d522f475Smrg     * normally result in calling FlushScroll() in WriteText().  However,
969d522f475Smrg     * if we're changing the background color now, then the new value
970d522f475Smrg     * should not apply to the pending blank lines.
971d522f475Smrg     */
972d522f475Smrg    if (screen->scroll_amt && (color != xw->cur_background))
973d522f475Smrg	FlushScroll(xw);
974d522f475Smrg
975d522f475Smrg    if (color >= 0) {
97620d2c4d2Smrg	UIntSet(xw->flags, BG_COLOR);
977d522f475Smrg    } else {
97820d2c4d2Smrg	UIntClr(xw->flags, BG_COLOR);
979d522f475Smrg    }
980d522f475Smrg    bg = getXtermBackground(xw, xw->flags, color);
981d522f475Smrg    xw->cur_background = color;
982d522f475Smrg
983d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcNorm, bg);
984d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcNormReverse, bg);
985d522f475Smrg
986d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcBold, bg);
987d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcBoldReverse, bg);
988d522f475Smrg}
989d522f475Smrg
990d522f475Smrg/* Invoked after updating bold/underline flags, computes the extended color
991d522f475Smrg * index to use for foreground.  (See also 'extract_fg()').
992d522f475Smrg */
993d522f475Smrgstatic void
994d522f475SmrgsetExtendedFG(XtermWidget xw)
995d522f475Smrg{
996d522f475Smrg    int fg = xw->sgr_foreground;
997d522f475Smrg
99820d2c4d2Smrg    if (TScreenOf(xw)->colorAttrMode
999d522f475Smrg	|| (fg < 0)) {
100020d2c4d2Smrg	fg = MapToColorMode(fg, TScreenOf(xw), xw->flags);
1001d522f475Smrg    }
1002d522f475Smrg
1003d522f475Smrg    /* This implements the IBM PC-style convention of 8-colors, with one
1004d522f475Smrg     * bit for bold, thus mapping the 0-7 codes to 8-15.  It won't make
1005d522f475Smrg     * much sense for 16-color applications, but we keep it to retain
1006d522f475Smrg     * compatiblity with ANSI-color applications.
1007d522f475Smrg     */
1008d522f475Smrg#if OPT_PC_COLORS		/* XXXJTL should be settable at runtime (resource or OSC?) */
100920d2c4d2Smrg    if (TScreenOf(xw)->boldColors
1010d522f475Smrg	&& (!xw->sgr_extended)
1011d522f475Smrg	&& (fg >= 0)
1012d522f475Smrg	&& (fg < 8)
1013d522f475Smrg	&& (xw->flags & BOLD))
1014d522f475Smrg	fg |= 8;
1015d522f475Smrg#endif
1016d522f475Smrg
1017d522f475Smrg    SGR_Foreground(xw, fg);
1018d522f475Smrg}
1019d522f475Smrg
1020d522f475Smrg/* Invoked after updating inverse flag, computes the extended color
1021d522f475Smrg * index to use for background.  (See also 'extract_bg()').
1022d522f475Smrg */
1023d522f475Smrgstatic void
1024d522f475SmrgsetExtendedBG(XtermWidget xw)
1025d522f475Smrg{
1026d522f475Smrg    int bg = xw->sgr_background;
1027d522f475Smrg
102820d2c4d2Smrg    if (TScreenOf(xw)->colorAttrMode
1029d522f475Smrg	|| (bg < 0)) {
103020d2c4d2Smrg	if (TScreenOf(xw)->colorRVMode && (xw->flags & INVERSE))
1031d522f475Smrg	    bg = COLOR_RV;
1032d522f475Smrg    }
1033d522f475Smrg
1034d522f475Smrg    SGR_Background(xw, bg);
1035d522f475Smrg}
1036d522f475Smrg
1037d522f475Smrgstatic void
1038d522f475Smrgreset_SGR_Foreground(XtermWidget xw)
1039d522f475Smrg{
1040d522f475Smrg    xw->sgr_foreground = -1;
1041d522f475Smrg    xw->sgr_extended = False;
1042d522f475Smrg    setExtendedFG(xw);
1043d522f475Smrg}
1044d522f475Smrg
1045d522f475Smrgstatic void
1046d522f475Smrgreset_SGR_Background(XtermWidget xw)
1047d522f475Smrg{
1048d522f475Smrg    xw->sgr_background = -1;
1049d522f475Smrg    setExtendedBG(xw);
1050d522f475Smrg}
1051d522f475Smrg
1052d522f475Smrgstatic void
1053d522f475Smrgreset_SGR_Colors(XtermWidget xw)
1054d522f475Smrg{
1055d522f475Smrg    reset_SGR_Foreground(xw);
1056d522f475Smrg    reset_SGR_Background(xw);
1057d522f475Smrg}
1058d522f475Smrg#endif /* OPT_ISO_COLORS */
1059d522f475Smrg
1060d522f475Smrgvoid
1061d522f475SmrgresetCharsets(TScreen * screen)
1062d522f475Smrg{
1063d522f475Smrg    TRACE(("resetCharsets\n"));
1064d522f475Smrg
1065d522f475Smrg    screen->gsets[0] = 'B';	/* ASCII_G              */
1066d522f475Smrg    screen->gsets[1] = 'B';	/* ASCII_G              */
1067d522f475Smrg    screen->gsets[2] = 'B';	/* ASCII_G              */
1068d522f475Smrg    screen->gsets[3] = 'B';	/* ASCII_G              */
1069d522f475Smrg
1070d522f475Smrg    screen->curgl = 0;		/* G0 => GL.            */
1071d522f475Smrg    screen->curgr = 2;		/* G2 => GR.            */
1072d522f475Smrg    screen->curss = 0;		/* No single shift.     */
1073d522f475Smrg
1074d522f475Smrg#if OPT_VT52_MODE
1075d522f475Smrg    if (screen->vtXX_level == 0)
1076d522f475Smrg	screen->gsets[1] = '0';	/* Graphics             */
1077d522f475Smrg#endif
1078d522f475Smrg}
1079d522f475Smrg
1080d522f475Smrg/*
1081d522f475Smrg * VT300 and up support three ANSI conformance levels, defined according to
1082d522f475Smrg * the dpANSI X3.134.1 standard.  DEC's manuals equate levels 1 and 2, and
1083d522f475Smrg * are unclear.  This code is written based on the manuals.
1084d522f475Smrg */
1085d522f475Smrgstatic void
1086d522f475Smrgset_ansi_conformance(TScreen * screen, int level)
1087d522f475Smrg{
10880bd37d32Smrg    TRACE(("set_ansi_conformance(%d) dec_level %d:%d, ansi_level %d\n",
1089d522f475Smrg	   level,
10900bd37d32Smrg	   screen->vtXX_level * 100,
1091d522f475Smrg	   screen->terminal_id,
1092d522f475Smrg	   screen->ansi_level));
1093d522f475Smrg    if (screen->vtXX_level >= 3) {
1094d522f475Smrg	switch (screen->ansi_level = level) {
1095d522f475Smrg	case 1:
1096d522f475Smrg	    /* FALLTHRU */
1097d522f475Smrg	case 2:
1098d522f475Smrg	    screen->gsets[0] = 'B';	/* G0 is ASCII */
10990bd37d32Smrg	    screen->gsets[1] = 'B';	/* G1 is ISO Latin-1 */
1100d522f475Smrg	    screen->curgl = 0;
1101d522f475Smrg	    screen->curgr = 1;
1102d522f475Smrg	    break;
1103d522f475Smrg	case 3:
1104d522f475Smrg	    screen->gsets[0] = 'B';	/* G0 is ASCII */
1105d522f475Smrg	    screen->curgl = 0;
1106d522f475Smrg	    break;
1107d522f475Smrg	}
1108d522f475Smrg    }
1109d522f475Smrg}
1110d522f475Smrg
1111d522f475Smrg/*
1112d522f475Smrg * Set scrolling margins.  VTxxx terminals require that the top/bottom are
1113d522f475Smrg * different, so we have at least two lines in the scrolling region.
1114d522f475Smrg */
1115d522f475Smrgvoid
1116d522f475Smrgset_tb_margins(TScreen * screen, int top, int bottom)
1117d522f475Smrg{
1118d522f475Smrg    TRACE(("set_tb_margins %d..%d, prior %d..%d\n",
1119d522f475Smrg	   top, bottom,
1120d522f475Smrg	   screen->top_marg,
1121d522f475Smrg	   screen->bot_marg));
1122d522f475Smrg    if (bottom > top) {
1123d522f475Smrg	screen->top_marg = top;
1124d522f475Smrg	screen->bot_marg = bottom;
1125d522f475Smrg    }
1126d522f475Smrg    if (screen->top_marg > screen->max_row)
1127d522f475Smrg	screen->top_marg = screen->max_row;
1128d522f475Smrg    if (screen->bot_marg > screen->max_row)
1129d522f475Smrg	screen->bot_marg = screen->max_row;
1130d522f475Smrg}
1131d522f475Smrg
11320bd37d32Smrgvoid
11330bd37d32Smrgset_lr_margins(TScreen * screen, int left, int right)
11340bd37d32Smrg{
11350bd37d32Smrg    TRACE(("set_lr_margins %d..%d, prior %d..%d\n",
11360bd37d32Smrg	   left, right,
11370bd37d32Smrg	   screen->lft_marg,
11380bd37d32Smrg	   screen->rgt_marg));
11390bd37d32Smrg    if (right > left) {
11400bd37d32Smrg	screen->lft_marg = left;
11410bd37d32Smrg	screen->rgt_marg = right;
11420bd37d32Smrg    }
11430bd37d32Smrg    if (screen->lft_marg > screen->max_col)
11440bd37d32Smrg	screen->lft_marg = screen->max_col;
11450bd37d32Smrg    if (screen->rgt_marg > screen->max_col)
11460bd37d32Smrg	screen->rgt_marg = screen->max_col;
11470bd37d32Smrg}
11480bd37d32Smrg
11490bd37d32Smrg#define reset_tb_margins(screen) set_tb_margins(screen, 0, screen->max_row)
11500bd37d32Smrg#define reset_lr_margins(screen) set_lr_margins(screen, 0, screen->max_col)
11510bd37d32Smrg
11520bd37d32Smrgstatic void
11530bd37d32Smrgreset_margins(TScreen * screen)
11540bd37d32Smrg{
11550bd37d32Smrg    reset_tb_margins(screen);
11560bd37d32Smrg    reset_lr_margins(screen);
11570bd37d32Smrg}
11580bd37d32Smrg
1159d522f475Smrgvoid
1160d522f475Smrgset_max_col(TScreen * screen, int cols)
1161d522f475Smrg{
1162d522f475Smrg    TRACE(("set_max_col %d, prior %d\n", cols, screen->max_col));
1163d522f475Smrg    if (cols < 0)
1164d522f475Smrg	cols = 0;
1165d522f475Smrg    screen->max_col = cols;
1166d522f475Smrg}
1167d522f475Smrg
1168d522f475Smrgvoid
1169d522f475Smrgset_max_row(TScreen * screen, int rows)
1170d522f475Smrg{
1171d522f475Smrg    TRACE(("set_max_row %d, prior %d\n", rows, screen->max_row));
1172d522f475Smrg    if (rows < 0)
1173d522f475Smrg	rows = 0;
1174d522f475Smrg    screen->max_row = rows;
1175d522f475Smrg}
1176d522f475Smrg
1177d522f475Smrg#if OPT_MOD_FKEYS
1178d522f475Smrgstatic void
1179d522f475Smrgset_mod_fkeys(XtermWidget xw, int which, int what, Bool enabled)
1180d522f475Smrg{
1181d522f475Smrg#define SET_MOD_FKEYS(field) \
1182d522f475Smrg    xw->keyboard.modify_now.field = ((what == DEFAULT) && enabled) \
1183d522f475Smrg				     ? xw->keyboard.modify_1st.field \
1184d522f475Smrg				     : what; \
1185d522f475Smrg    TRACE(("set modify_now.%s to %d\n", #field, \
1186d522f475Smrg	   xw->keyboard.modify_now.field));
1187d522f475Smrg
1188d522f475Smrg    switch (which) {
11890bd37d32Smrg    case 0:
11900bd37d32Smrg	SET_MOD_FKEYS(allow_keys);
11910bd37d32Smrg	break;
1192d522f475Smrg    case 1:
1193d522f475Smrg	SET_MOD_FKEYS(cursor_keys);
1194d522f475Smrg	break;
1195d522f475Smrg    case 2:
1196d522f475Smrg	SET_MOD_FKEYS(function_keys);
1197d522f475Smrg	break;
1198d522f475Smrg    case 3:
1199d522f475Smrg	SET_MOD_FKEYS(keypad_keys);
1200d522f475Smrg	break;
1201d522f475Smrg    case 4:
1202d522f475Smrg	SET_MOD_FKEYS(other_keys);
1203d522f475Smrg	break;
1204d522f475Smrg    case 5:
1205d522f475Smrg	SET_MOD_FKEYS(string_keys);
1206d522f475Smrg	break;
1207d522f475Smrg    }
1208d522f475Smrg}
1209d522f475Smrg#endif /* OPT_MOD_FKEYS */
1210d522f475Smrg
1211d522f475Smrg#if OPT_TRACE
1212d522f475Smrg#define WHICH_TABLE(name) if (table == name) result = #name
121320d2c4d2Smrgstatic const char *
1214d522f475Smrgwhich_table(Const PARSE_T * table)
1215d522f475Smrg{
121620d2c4d2Smrg    const char *result = "?";
1217d522f475Smrg    /* *INDENT-OFF* */
1218d522f475Smrg    WHICH_TABLE (ansi_table);
12192eaa94a1Schristos    else WHICH_TABLE (cigtable);
1220d522f475Smrg    else WHICH_TABLE (csi2_table);
1221d522f475Smrg    else WHICH_TABLE (csi_ex_table);
1222d522f475Smrg    else WHICH_TABLE (csi_quo_table);
12232eaa94a1Schristos    else WHICH_TABLE (csi_table);
1224d522f475Smrg    else WHICH_TABLE (dec2_table);
1225d522f475Smrg    else WHICH_TABLE (dec3_table);
12262eaa94a1Schristos    else WHICH_TABLE (dec_table);
1227d522f475Smrg    else WHICH_TABLE (eigtable);
1228d522f475Smrg    else WHICH_TABLE (esc_sp_table);
12292eaa94a1Schristos    else WHICH_TABLE (esc_table);
1230d522f475Smrg    else WHICH_TABLE (scrtable);
12312eaa94a1Schristos    else WHICH_TABLE (scs96table);
1232d522f475Smrg    else WHICH_TABLE (scstable);
1233d522f475Smrg    else WHICH_TABLE (sos_table);
123420d2c4d2Smrg#if OPT_BLINK_CURS
123520d2c4d2Smrg    else WHICH_TABLE (csi_sp_table);
123620d2c4d2Smrg#endif
12372eaa94a1Schristos#if OPT_DEC_LOCATOR
12382eaa94a1Schristos    else WHICH_TABLE (csi_tick_table);
12392eaa94a1Schristos#endif
12402eaa94a1Schristos#if OPT_DEC_RECTOPS
12412eaa94a1Schristos    else WHICH_TABLE (csi_dollar_table);
12422eaa94a1Schristos    else WHICH_TABLE (csi_star_table);
1243492d43a5Smrg    else WHICH_TABLE (csi_dec_dollar_table);
12442eaa94a1Schristos#endif
1245d522f475Smrg#if OPT_WIDE_CHARS
1246d522f475Smrg    else WHICH_TABLE (esc_pct_table);
1247d522f475Smrg#endif
1248d522f475Smrg#if OPT_VT52_MODE
1249d522f475Smrg    else WHICH_TABLE (vt52_table);
1250d522f475Smrg    else WHICH_TABLE (vt52_esc_table);
1251d522f475Smrg    else WHICH_TABLE (vt52_ignore_table);
1252d522f475Smrg#endif
1253d522f475Smrg    /* *INDENT-ON* */
1254d522f475Smrg
1255d522f475Smrg    return result;
1256d522f475Smrg}
12570bd37d32Smrg#endif
12580bd37d32Smrg
12590bd37d32Smrg#if OPT_TRACE > 0
12600bd37d32Smrgstatic void
12610bd37d32Smrgdump_params(void)
12620bd37d32Smrg{
12630bd37d32Smrg    int n;
12640bd37d32Smrg    int arg;
12650bd37d32Smrg    TRACE(("params %d (%d)\n", nparam, parms.has_subparams));
12660bd37d32Smrg    for (arg = 1, n = 0; n < nparam; ++n) {
12670bd37d32Smrg	TRACE(("%3d.%d %d\n", arg, parms.is_sub[n], parms.params[n]));
12680bd37d32Smrg	if (!parms.is_sub[n])
12690bd37d32Smrg	    ++arg;
12700bd37d32Smrg    }
12710bd37d32Smrg}
12720bd37d32Smrg#define DumpParams() dump_params()
12730bd37d32Smrg#else
12740bd37d32Smrg#define DumpParams()		/* nothing */
1275d522f475Smrg#endif
1276d522f475Smrg
1277d522f475Smrg	/* allocate larger buffer if needed/possible */
1278d522f475Smrg#define SafeAlloc(type, area, used, size) \
1279d522f475Smrg		type *new_string = area; \
128020d2c4d2Smrg		size_t new_length = size; \
1281d522f475Smrg		if (new_length == 0) { \
1282d522f475Smrg		    new_length = 256; \
1283d522f475Smrg		    new_string = TypeMallocN(type, new_length); \
1284d522f475Smrg		} else if (used+1 >= new_length) { \
1285d522f475Smrg		    new_length = size * 2; \
1286d522f475Smrg		    new_string = TypeMallocN(type, new_length); \
1287d522f475Smrg		    if (new_string != 0 \
1288d522f475Smrg		     && area != 0 \
1289d522f475Smrg		     && used != 0) \
1290d522f475Smrg			memcpy(new_string, area, used * sizeof(type)); \
1291d522f475Smrg		}
1292d522f475Smrg
1293d522f475Smrg#define WriteNow() {						\
1294d522f475Smrg	    unsigned single = 0;				\
1295d522f475Smrg								\
1296d522f475Smrg	    if (screen->curss) {				\
1297d522f475Smrg		dotext(xw,					\
1298d522f475Smrg		       screen->gsets[(int) (screen->curss)],	\
1299956cc18dSsnj		       sp->print_area,				\
1300956cc18dSsnj		       (Cardinal) 1);				\
1301d522f475Smrg		screen->curss = 0;				\
1302d522f475Smrg		single++;					\
1303d522f475Smrg	    }							\
1304956cc18dSsnj	    if (sp->print_used > single) {			\
1305d522f475Smrg		dotext(xw,					\
1306d522f475Smrg		       screen->gsets[(int) (screen->curgl)],	\
1307956cc18dSsnj		       sp->print_area + single,			\
1308956cc18dSsnj		       (Cardinal) (sp->print_used - single));	\
1309d522f475Smrg	    }							\
1310956cc18dSsnj	    sp->print_used = 0;					\
1311d522f475Smrg	}							\
1312d522f475Smrg
1313d522f475Smrgstruct ParseState {
1314d522f475Smrg#if OPT_VT52_MODE
1315d522f475Smrg    Bool vt52_cup;
1316d522f475Smrg#endif
1317d522f475Smrg    Const PARSE_T *groundtable;
1318d522f475Smrg    Const PARSE_T *parsestate;
1319d522f475Smrg    int scstype;
13202eaa94a1Schristos    int scssize;
1321d522f475Smrg    Bool private_function;	/* distinguish private-mode from standard */
1322d522f475Smrg    int string_mode;		/* nonzero iff we're processing a string */
1323d522f475Smrg    int lastchar;		/* positive iff we had a graphic character */
1324d522f475Smrg    int nextstate;
1325d522f475Smrg#if OPT_WIDE_CHARS
1326d522f475Smrg    int last_was_wide;
1327d522f475Smrg#endif
1328956cc18dSsnj    /* Buffer for processing printable text */
1329956cc18dSsnj    IChar *print_area;
1330956cc18dSsnj    size_t print_size;
1331956cc18dSsnj    size_t print_used;
1332956cc18dSsnj    /* Buffer for processing strings (e.g., OSC ... ST) */
1333956cc18dSsnj    Char *string_area;
1334956cc18dSsnj    size_t string_size;
1335956cc18dSsnj    size_t string_used;
1336d522f475Smrg};
1337d522f475Smrg
1338d522f475Smrgstatic struct ParseState myState;
1339d522f475Smrg
13402eaa94a1Schristosstatic void
13412eaa94a1Schristosinit_groundtable(TScreen * screen, struct ParseState *sp)
13422eaa94a1Schristos{
1343956cc18dSsnj    (void) screen;
1344956cc18dSsnj
13452eaa94a1Schristos#if OPT_VT52_MODE
13462eaa94a1Schristos    if (!(screen->vtXX_level)) {
13472eaa94a1Schristos	sp->groundtable = vt52_table;
13482eaa94a1Schristos    } else if (screen->terminal_id >= 100)
13492eaa94a1Schristos#endif
13502eaa94a1Schristos    {
13512eaa94a1Schristos	sp->groundtable = ansi_table;
13522eaa94a1Schristos    }
13532eaa94a1Schristos}
13542eaa94a1Schristos
13552eaa94a1Schristosstatic void
13562eaa94a1Schristosselect_charset(struct ParseState *sp, int type, int size)
13572eaa94a1Schristos{
13582eaa94a1Schristos    TRACE(("select_charset %#x %d\n", type, size));
13592eaa94a1Schristos    sp->scstype = type;
13602eaa94a1Schristos    sp->scssize = size;
13612eaa94a1Schristos    if (size == 94) {
13622eaa94a1Schristos	sp->parsestate = scstable;
13632eaa94a1Schristos    } else {
13642eaa94a1Schristos	sp->parsestate = scs96table;
13652eaa94a1Schristos    }
13662eaa94a1Schristos}
13672eaa94a1Schristos
13680bd37d32Smrg/*
13690bd37d32Smrg * Given a parameter number, and subparameter (starting in each case from zero)
13700bd37d32Smrg * return the corresponding index into the parameter array.  If the combination
13710bd37d32Smrg * is not found, return -1.
13720bd37d32Smrg */
1373e39b573cSmrgstatic int
13740bd37d32Smrgsubparam_index(int p, int s)
1375e39b573cSmrg{
13760bd37d32Smrg    int result = -1;
13770bd37d32Smrg    int j, p2, s2;
13780bd37d32Smrg
13790bd37d32Smrg    for (j = p2 = 0; j < nparam; ++j, ++p2) {
13800bd37d32Smrg	if (parms.is_sub[j]) {
13810bd37d32Smrg	    s2 = 0;
13820bd37d32Smrg
13830bd37d32Smrg	    do {
13840bd37d32Smrg		if ((p == p2) && (s == s2)) {
13850bd37d32Smrg		    result = j;
13860bd37d32Smrg		    break;
13870bd37d32Smrg		}
13880bd37d32Smrg		++s2;
13890bd37d32Smrg	    } while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j]));
13900bd37d32Smrg
13910bd37d32Smrg	    if (result >= 0)
13920bd37d32Smrg		break;
13930bd37d32Smrg
13940bd37d32Smrg	    --j;		/* undo the last "while" */
13950bd37d32Smrg	} else if (p == p2) {
13960bd37d32Smrg	    if (s == 0) {
13970bd37d32Smrg		result = j;
13980bd37d32Smrg	    }
13990bd37d32Smrg	    break;
14000bd37d32Smrg	}
14010bd37d32Smrg    }
14020bd37d32Smrg    TRACE2(("...subparam_index %d.%d = %d\n", p + 1, s + 1, result));
14030bd37d32Smrg    return result;
14040bd37d32Smrg}
14050bd37d32Smrg
14060bd37d32Smrg/*
14070bd37d32Smrg * Given an index into the parameter array, return the corresponding parameter
14080bd37d32Smrg * number (starting from zero).
14090bd37d32Smrg */
14100bd37d32Smrgstatic int
14110bd37d32Smrgparam_number(int item)
14120bd37d32Smrg{
14130bd37d32Smrg    int result = -1;
14140bd37d32Smrg    int j, p;
14150bd37d32Smrg
14160bd37d32Smrg    for (j = p = 0; j < nparam; ++j, ++p) {
14170bd37d32Smrg	if (p >= item) {
14180bd37d32Smrg	    result = j;
14190bd37d32Smrg	    break;
14200bd37d32Smrg	}
14210bd37d32Smrg	if (parms.is_sub[j]) {
14220bd37d32Smrg	    while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j])) {
14230bd37d32Smrg		/* EMPTY */
14240bd37d32Smrg	    }
14250bd37d32Smrg	    --j;
14260bd37d32Smrg	}
14270bd37d32Smrg    }
14280bd37d32Smrg
14290bd37d32Smrg    TRACE2(("...param_number(%d) = %d\n", item, result));
14300bd37d32Smrg    return result;
14310bd37d32Smrg}
14320bd37d32Smrg
14330bd37d32Smrgstatic int
14340bd37d32Smrgget_subparam(int p, int s)
14350bd37d32Smrg{
14360bd37d32Smrg    int item = subparam_index(p, s);
14370bd37d32Smrg    int result = (item >= 0) ? parms.params[item] : DEFAULT;
14380bd37d32Smrg    TRACE(("...get_subparam[%d] = %d\n", item, result));
1439e39b573cSmrg    return result;
1440e39b573cSmrg}
1441e39b573cSmrg
14420bd37d32Smrg/*
14430bd37d32Smrg * Check if the given item in the parameter array has subparameters.
14440bd37d32Smrg * If so, return the number of subparameters to use as a loop limit, etc.
14450bd37d32Smrg */
14460bd37d32Smrgstatic int
14470bd37d32Smrgparam_has_subparams(int item)
14480bd37d32Smrg{
14490bd37d32Smrg    int result = 0;
14500bd37d32Smrg    if (parms.has_subparams) {
14510bd37d32Smrg	int n = subparam_index(item, 0);
14520bd37d32Smrg	if (n >= 0 && parms.is_sub[n]) {
14530bd37d32Smrg	    while (n++ < nparam && parms.is_sub[n - 1] < parms.is_sub[n]) {
14540bd37d32Smrg		result++;
14550bd37d32Smrg	    }
14560bd37d32Smrg	}
14570bd37d32Smrg    }
14580bd37d32Smrg    TRACE(("...param_has_subparams(%d) ->%d\n", item, result));
14590bd37d32Smrg    return result;
14600bd37d32Smrg}
14610bd37d32Smrg
14620bd37d32Smrg#if OPT_256_COLORS || OPT_88_COLORS || OPT_ISO_COLORS
14630bd37d32Smrg/*
14640bd37d32Smrg * Some background -
14650bd37d32Smrg *
14660bd37d32Smrg * Todd Larason provided the initial changes to support 256-colors in July 1999.
14670bd37d32Smrg * I pointed out that the description of SGR 38/48 in ECMA-48 was vague, and
14680bd37d32Smrg * was unsure if there would be some standard using those codes.  His response
14690bd37d32Smrg * was that this was documented (it turns out, in equally vague terms) in ITU
14700bd37d32Smrg * T.416
14710bd37d32Smrg *
14720bd37d32Smrg * Discussing this with Todd Larason in mid-1999, my point was that given the
14730bd37d32Smrg * high cost of obtaining ITU T.416 (ISO-8613-6), the standard was not going
14740bd37d32Smrg * to be effective (more than $100 then, more than $200 in 2012)
14750bd37d32Smrg *
14760bd37d32Smrg * We overlooked the detail about ":" as a subparameter delimiter (documented
14770bd37d32Smrg * in 5.4.t2 in ECMA-48).  Some discussion in KDE in mid-2006 led Lars Doelle
14780bd37d32Smrg * to discuss the issue with me.  Lars' initial concern dealt with the fact
14790bd37d32Smrg * that a sequence such as
14800bd37d32Smrg *	CSI 38 ; 5 ; 1 m
14810bd37d32Smrg * violated the principle that SGR parameters could be used in any order.
14820bd37d32Smrg * Further discussion (see KDE #107487) resolved that the standard expected
14830bd37d32Smrg * that the sequence would look like
14840bd37d32Smrg *	CSI 38 ; 5 : 1 m
14850bd37d32Smrg * which still violates that principle, since the "5:1" parameter has to
14860bd37d32Smrg * follow the "38" to be useful.
14870bd37d32Smrg *
14880bd37d32Smrg * This function accepts either format (per request by Paul Leonerd Evans).
14890bd37d32Smrg * It also accepts
14900bd37d32Smrg *	CSI 38 : 5 : 1 m
14910bd37d32Smrg * according to Lars' original assumption.
14920bd37d32Smrg *
14930bd37d32Smrg * By the way - all of the parameters are decimal integers.
14940bd37d32Smrg */
14950bd37d32Smrg#define extended_colors_limit(n) ((n) == 5 ? 1 : ((n) == 2 ? 3 : 0))
14960bd37d32Smrgstatic Boolean
14970bd37d32Smrgparse_extended_colors(XtermWidget xw, int *colorp, int *itemp)
14980bd37d32Smrg{
14990bd37d32Smrg    Boolean result = False;
15000bd37d32Smrg    int item = *itemp;
15010bd37d32Smrg    int next = item;
15020bd37d32Smrg    int base = param_number(item);
15030bd37d32Smrg    int code = -1;
15040bd37d32Smrg    int values[3];		/* maximum number of subparameters */
15050bd37d32Smrg    int need = 0;		/* number of subparameters needed */
15060bd37d32Smrg    int have;
15070bd37d32Smrg    int n;
15080bd37d32Smrg
15090bd37d32Smrg    /*
15100bd37d32Smrg     * On entry, 'item' points to the 38/48 code in the parameter array.
15110bd37d32Smrg     * If that has subparameters, we will expect all of the values to
15120bd37d32Smrg     * be subparameters of that item.
15130bd37d32Smrg     */
15140bd37d32Smrg    if ((have = param_has_subparams(item)) != 0) {
15150bd37d32Smrg	/* accept CSI 38 : 5 : 1 m */
15160bd37d32Smrg	/* accept CSI 38 : 2 : 1 : 2 : 3 m */
15170bd37d32Smrg	code = get_subparam(base, 1);
15180bd37d32Smrg	need = extended_colors_limit(code);
15190bd37d32Smrg	next = item + have;
15200bd37d32Smrg	for (n = 0; n < need && n < 3; ++n) {
15210bd37d32Smrg	    values[n] = get_subparam(base, 2 + n);
15220bd37d32Smrg	}
15230bd37d32Smrg    } else if (++item < nparam) {
15240bd37d32Smrg	++base;
15250bd37d32Smrg	if ((have = param_has_subparams(item)) != 0) {
15260bd37d32Smrg	    /* accept CSI 38 ; 5 : 1 m */
15270bd37d32Smrg	    /* accept CSI 38 ; 2 : 1 : 2 : 3 m */
15280bd37d32Smrg	    code = get_subparam(base, 0);
15290bd37d32Smrg	    need = extended_colors_limit(code);
15300bd37d32Smrg	    next = base + have;
15310bd37d32Smrg	    for (n = 0; n < need && n < 3; ++n) {
15320bd37d32Smrg		values[n] = get_subparam(base, 1 + n);
15330bd37d32Smrg	    }
15340bd37d32Smrg	} else {
15350bd37d32Smrg	    /* accept CSI 38 ; 5 ; 1 m */
15360bd37d32Smrg	    /* accept CSI 38 ; 2 ; 1 ; 2 ; 3 m */
15370bd37d32Smrg	    code = GetParam(item);
15380bd37d32Smrg	    need = extended_colors_limit(code);
15390bd37d32Smrg	    next = item + need;
15400bd37d32Smrg	    for (n = 0; n < need && n < 3; ++n) {
15410bd37d32Smrg		values[n] = GetParam(item + 1 + n);
15420bd37d32Smrg	    }
15430bd37d32Smrg	}
15440bd37d32Smrg    }
15450bd37d32Smrg    item = next;
15460bd37d32Smrg
15470bd37d32Smrg    switch (code) {
15480bd37d32Smrg    case 2:
15490bd37d32Smrg	/* direct color in rgb space */
15500bd37d32Smrg	if ((values[0] >= 0 && values[0] < 256) &&
15510bd37d32Smrg	    (values[1] >= 0 && values[1] < 256) &&
15520bd37d32Smrg	    (values[2] >= 0 && values[2] < 256)) {
15530bd37d32Smrg	    *colorp = xtermClosestColor(xw, values[0], values[1], values[2]);
15540bd37d32Smrg	} else {
15550bd37d32Smrg	    *colorp = -1;
15560bd37d32Smrg	}
15570bd37d32Smrg	break;
15580bd37d32Smrg    case 5:
15590bd37d32Smrg	/* indexed color */
15600bd37d32Smrg	*colorp = values[0];
15610bd37d32Smrg	break;
15620bd37d32Smrg    default:
15630bd37d32Smrg	*colorp = -1;
15640bd37d32Smrg	break;
15650bd37d32Smrg    }
15660bd37d32Smrg
15670bd37d32Smrg    result = (*colorp >= 0 && *colorp < NUM_ANSI_COLORS);
15680bd37d32Smrg    TRACE(("...resulting color %d/%d %s\n",
15690bd37d32Smrg	   *colorp, NUM_ANSI_COLORS,
15700bd37d32Smrg	   result ? "OK" : "ERR"));
15710bd37d32Smrg
15720bd37d32Smrg    *itemp = item;
15730bd37d32Smrg    return result;
15740bd37d32Smrg}
15750bd37d32Smrg#endif /* ...extended_colors */
15760bd37d32Smrg
15770bd37d32Smrgstatic int
15780bd37d32Smrgoptional_param(int which)
15790bd37d32Smrg{
15800bd37d32Smrg    return (nparam > which) ? GetParam(which) : DEFAULT;
15810bd37d32Smrg}
15820bd37d32Smrg
158320d2c4d2Smrgstatic int
158420d2c4d2Smrgzero_if_default(int which)
158520d2c4d2Smrg{
15860bd37d32Smrg    int result = (nparam > which) ? GetParam(which) : 0;
158720d2c4d2Smrg    if (result <= 0)
158820d2c4d2Smrg	result = 0;
158920d2c4d2Smrg    return result;
159020d2c4d2Smrg}
159120d2c4d2Smrg
159220d2c4d2Smrgstatic int
159320d2c4d2Smrgone_if_default(int which)
159420d2c4d2Smrg{
15950bd37d32Smrg    int result = (nparam > which) ? GetParam(which) : 0;
159620d2c4d2Smrg    if (result <= 0)
159720d2c4d2Smrg	result = 1;
159820d2c4d2Smrg    return result;
159920d2c4d2Smrg}
160020d2c4d2Smrg
16010bd37d32Smrg/*
16020bd37d32Smrg * Color palette changes using the OSC controls require a repaint of the
16030bd37d32Smrg * screen - but not immediately.  Do the repaint as soon as we detect a
16040bd37d32Smrg * state which will not lead to another color palette change.
16050bd37d32Smrg */
16060bd37d32Smrgstatic void
16070bd37d32SmrgrepaintWhenPaletteChanged(XtermWidget xw, struct ParseState *sp)
16080bd37d32Smrg{
16090bd37d32Smrg    Boolean ignore = False;
16100bd37d32Smrg
16110bd37d32Smrg    switch (sp->nextstate) {
16120bd37d32Smrg    case CASE_ESC:
16130bd37d32Smrg	ignore = ((sp->parsestate == ansi_table) ||
16140bd37d32Smrg		  (sp->parsestate == sos_table));
16150bd37d32Smrg	break;
16160bd37d32Smrg    case CASE_OSC:
16170bd37d32Smrg	ignore = ((sp->parsestate == ansi_table) ||
16180bd37d32Smrg		  (sp->parsestate == esc_table));
16190bd37d32Smrg	break;
16200bd37d32Smrg    case CASE_IGNORE:
16210bd37d32Smrg	ignore = (sp->parsestate == sos_table);
16220bd37d32Smrg	break;
16230bd37d32Smrg    case CASE_ST:
16240bd37d32Smrg	ignore = ((sp->parsestate == esc_table) ||
16250bd37d32Smrg		  (sp->parsestate == sos_table));
16260bd37d32Smrg	break;
16270bd37d32Smrg    case CASE_ESC_DIGIT:
16280bd37d32Smrg	ignore = (sp->parsestate == csi_table);
16290bd37d32Smrg	break;
16300bd37d32Smrg    case CASE_ESC_SEMI:
16310bd37d32Smrg	ignore = (sp->parsestate == csi2_table);
16320bd37d32Smrg	break;
16330bd37d32Smrg    }
16340bd37d32Smrg
16350bd37d32Smrg    if (!ignore) {
16360bd37d32Smrg	TRACE(("repaintWhenPaletteChanged\n"));
16370bd37d32Smrg	xw->misc.palette_changed = False;
16380bd37d32Smrg	xtermRepaint(xw);
16390bd37d32Smrg    }
16400bd37d32Smrg}
16410bd37d32Smrg
164220d2c4d2Smrg#if OPT_C1_PRINT || OPT_WIDE_CHARS
164320d2c4d2Smrg#define ParseSOS(screen) ((screen)->c1_printable == 0)
164420d2c4d2Smrg#else
164520d2c4d2Smrg#define ParseSOS(screen) 0
164620d2c4d2Smrg#endif
164720d2c4d2Smrg
16480bd37d32Smrg#define ResetState(sp) ParamsDone(), (sp)->parsestate = (sp)->groundtable
164920d2c4d2Smrg
165020d2c4d2Smrgstatic void
165120d2c4d2Smrgillegal_parse(XtermWidget xw, unsigned c, struct ParseState *sp)
165220d2c4d2Smrg{
165320d2c4d2Smrg    ResetState(sp);
165420d2c4d2Smrg    sp->nextstate = sp->parsestate[E2A(c)];
165520d2c4d2Smrg    Bell(xw, XkbBI_MinorError, 0);
165620d2c4d2Smrg}
165720d2c4d2Smrg
1658e39b573cSmrgstatic void
1659e39b573cSmrginit_parser(XtermWidget xw, struct ParseState *sp)
1660e39b573cSmrg{
1661e39b573cSmrg    TScreen *screen = TScreenOf(xw);
1662e39b573cSmrg
1663e39b573cSmrg    memset(sp, 0, sizeof(*sp));
1664e39b573cSmrg    sp->scssize = 94;		/* number of printable/nonspace ASCII */
1665e39b573cSmrg    sp->lastchar = -1;		/* not a legal IChar */
1666e39b573cSmrg    sp->nextstate = -1;		/* not a legal state */
1667e39b573cSmrg
1668e39b573cSmrg    init_groundtable(screen, sp);
1669e39b573cSmrg    ResetState(sp);
1670e39b573cSmrg}
1671e39b573cSmrg
16720bd37d32Smrgstatic void
16730bd37d32Smrginit_reply(unsigned type)
16740bd37d32Smrg{
16750bd37d32Smrg    memset(&reply, 0, sizeof(reply));
16760bd37d32Smrg    reply.a_type = (Char) type;
16770bd37d32Smrg}
16780bd37d32Smrg
1679d522f475Smrgstatic Boolean
1680d522f475Smrgdoparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
1681d522f475Smrg{
168220d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
16830bd37d32Smrg    int item;
1684d522f475Smrg    int count;
16850bd37d32Smrg    int value;
1686d522f475Smrg    int laststate;
1687d522f475Smrg    int thischar = -1;
1688d522f475Smrg    XTermRect myRect;
1689d522f475Smrg
1690d522f475Smrg    do {
1691d522f475Smrg#if OPT_WIDE_CHARS
1692956cc18dSsnj	int this_is_wide = 0;
1693d522f475Smrg
1694d522f475Smrg	/*
1695d522f475Smrg	 * Handle zero-width combining characters.  Make it faster by noting
1696d522f475Smrg	 * that according to the Unicode charts, the majority of Western
1697d522f475Smrg	 * character sets do not use this feature.  There are some unassigned
1698d522f475Smrg	 * codes at 0x242, but no zero-width characters until past 0x300.
1699d522f475Smrg	 */
17000bd37d32Smrg	if (c >= 0x300
17010bd37d32Smrg	    && screen->wide_chars
17020bd37d32Smrg	    && my_wcwidth((wchar_t) c) == 0
1703d522f475Smrg	    && !isWideControl(c)) {
17040bd37d32Smrg	    int prev, test;
17050bd37d32Smrg	    Boolean used = True;
17060bd37d32Smrg	    int use_row;
17070bd37d32Smrg	    int use_col;
1708d522f475Smrg
1709d522f475Smrg	    WriteNow();
17100bd37d32Smrg	    use_row = (screen->char_was_written
17110bd37d32Smrg		       ? screen->last_written_row
17120bd37d32Smrg		       : screen->cur_row);
17130bd37d32Smrg	    use_col = (screen->char_was_written
17140bd37d32Smrg		       ? screen->last_written_col
17150bd37d32Smrg		       : screen->cur_col);
1716d522f475Smrg
17170bd37d32Smrg	    /*
17180bd37d32Smrg	     * Check if the latest data can be added to the base character.
17190bd37d32Smrg	     * If there is already a combining character stored for the cell,
17200bd37d32Smrg	     * we cannot, since that would change the order.
17210bd37d32Smrg	     */
17220bd37d32Smrg	    if (screen->normalized_c
17230bd37d32Smrg		&& !IsCellCombined(screen, use_row, use_col)) {
17240bd37d32Smrg		prev = (int) XTERM_CELL(use_row, use_col);
17250bd37d32Smrg		test = do_precomposition(prev, (int) c);
17260bd37d32Smrg		TRACE(("do_precomposition (U+%04X [%d], U+%04X [%d]) -> U+%04X [%d]\n",
17270bd37d32Smrg		       prev, my_wcwidth((wchar_t) prev),
17280bd37d32Smrg		       (int) c, my_wcwidth((wchar_t) c),
17290bd37d32Smrg		       test, my_wcwidth((wchar_t) test)));
17300bd37d32Smrg	    } else {
17310bd37d32Smrg		prev = -1;
17320bd37d32Smrg		test = -1;
17330bd37d32Smrg	    }
1734d522f475Smrg
1735d522f475Smrg	    /* substitute combined character with precomposed character
1736d522f475Smrg	     * only if it does not change the width of the base character
1737d522f475Smrg	     */
17380bd37d32Smrg	    if (test != -1
17390bd37d32Smrg		&& my_wcwidth((wchar_t) test) == my_wcwidth((wchar_t) prev)) {
17400bd37d32Smrg		putXtermCell(screen, use_row, use_col, test);
17410bd37d32Smrg	    } else if (screen->char_was_written
17420bd37d32Smrg		       || getXtermCell(screen, use_row, use_col) > ' ') {
17430bd37d32Smrg		addXtermCombining(screen, use_row, use_col, c);
1744d522f475Smrg	    } else {
17450bd37d32Smrg		/*
17460bd37d32Smrg		 * none of the above... we will add the combining character as
17470bd37d32Smrg		 * a base character.
17480bd37d32Smrg		 */
17490bd37d32Smrg		used = False;
1750d522f475Smrg	    }
1751d522f475Smrg
17520bd37d32Smrg	    if (used) {
17530bd37d32Smrg		if (!screen->scroll_amt)
17540bd37d32Smrg		    ScrnUpdate(xw, use_row, use_col, 1, 1, 1);
17550bd37d32Smrg		continue;
17560bd37d32Smrg	    }
1757d522f475Smrg	}
1758d522f475Smrg#endif
1759d522f475Smrg
1760d522f475Smrg	/* Intercept characters for printer controller mode */
1761e39b573cSmrg	if (PrinterOf(screen).printer_controlmode == 2) {
1762956cc18dSsnj	    if ((c = (unsigned) xtermPrinterControl(xw, (int) c)) == 0)
1763d522f475Smrg		continue;
1764d522f475Smrg	}
1765d522f475Smrg
1766d522f475Smrg	/*
1767d522f475Smrg	 * VT52 is a little ugly in the one place it has a parameterized
1768d522f475Smrg	 * control sequence, since the parameter falls after the character
1769d522f475Smrg	 * that denotes the type of sequence.
1770d522f475Smrg	 */
1771d522f475Smrg#if OPT_VT52_MODE
1772d522f475Smrg	if (sp->vt52_cup) {
17730bd37d32Smrg	    if (nparam < NPARAM - 1) {
17740bd37d32Smrg		SetParam(nparam++, (int) (c & 0x7f) - 32);
17750bd37d32Smrg		parms.is_sub[nparam] = 0;
17760bd37d32Smrg	    }
1777d522f475Smrg	    if (nparam < 2)
1778d522f475Smrg		continue;
1779d522f475Smrg	    sp->vt52_cup = False;
17800bd37d32Smrg	    CursorSet(screen, zero_if_default(0), zero_if_default(1), xw->flags);
1781d522f475Smrg	    sp->parsestate = vt52_table;
17820bd37d32Smrg	    SetParam(0, 0);
17830bd37d32Smrg	    SetParam(1, 0);
1784d522f475Smrg	    continue;
1785d522f475Smrg	}
1786d522f475Smrg#endif
1787d522f475Smrg
1788d522f475Smrg	laststate = sp->nextstate;
17892eaa94a1Schristos	if (c == ANSI_DEL
17902eaa94a1Schristos	    && sp->parsestate == sp->groundtable
17912eaa94a1Schristos	    && sp->scssize == 96
17922eaa94a1Schristos	    && sp->scstype != 0) {
17932eaa94a1Schristos	    /*
17942eaa94a1Schristos	     * Handle special case of shifts for 96-character sets by checking
17952eaa94a1Schristos	     * if we have a DEL.  The other special case for SPACE will always
17962eaa94a1Schristos	     * be printable.
17972eaa94a1Schristos	     */
17982eaa94a1Schristos	    sp->nextstate = CASE_PRINT;
17992eaa94a1Schristos	} else
1800d522f475Smrg#if OPT_WIDE_CHARS
1801d522f475Smrg	if (c > 255) {
18022eaa94a1Schristos	    /*
18032eaa94a1Schristos	     * The parsing tables all have 256 entries.  If we're supporting
18042eaa94a1Schristos	     * wide characters, we handle them by treating them the same as
18052eaa94a1Schristos	     * printing characters.
18062eaa94a1Schristos	     */
1807d522f475Smrg	    if (sp->parsestate == sp->groundtable) {
1808d522f475Smrg		sp->nextstate = CASE_PRINT;
1809d522f475Smrg	    } else if (sp->parsestate == sos_table) {
1810d522f475Smrg		c &= 0xffff;
1811d522f475Smrg		if (c > 255) {
1812d522f475Smrg		    TRACE(("Found code > 255 while in SOS state: %04X\n", c));
1813d522f475Smrg		    c = '?';
1814d522f475Smrg		}
1815d522f475Smrg	    } else {
1816d522f475Smrg		sp->nextstate = CASE_GROUND_STATE;
1817d522f475Smrg	    }
1818d522f475Smrg	} else
1819d522f475Smrg#endif
1820d522f475Smrg	    sp->nextstate = sp->parsestate[E2A(c)];
1821d522f475Smrg
1822d522f475Smrg#if OPT_BROKEN_OSC
1823d522f475Smrg	/*
1824d522f475Smrg	 * Linux console palette escape sequences start with an OSC, but do
1825d522f475Smrg	 * not terminate correctly.  Some scripts do not check before writing
1826d522f475Smrg	 * them, making xterm appear to hang (it's awaiting a valid string
1827d522f475Smrg	 * terminator).  Just ignore these if we see them - there's no point
1828d522f475Smrg	 * in emulating bad code.
1829d522f475Smrg	 */
1830d522f475Smrg	if (screen->brokenLinuxOSC
1831d522f475Smrg	    && sp->parsestate == sos_table) {
1832956cc18dSsnj	    if (sp->string_used) {
1833956cc18dSsnj		switch (sp->string_area[0]) {
1834d522f475Smrg		case 'P':
1835956cc18dSsnj		    if (sp->string_used <= 7)
1836d522f475Smrg			break;
1837d522f475Smrg		    /* FALLTHRU */
1838d522f475Smrg		case 'R':
183920d2c4d2Smrg		    illegal_parse(xw, c, sp);
1840d522f475Smrg		    TRACE(("Reset to ground state (brokenLinuxOSC)\n"));
1841d522f475Smrg		    break;
1842d522f475Smrg		}
1843d522f475Smrg	    }
1844d522f475Smrg	}
1845d522f475Smrg#endif
1846d522f475Smrg
1847d522f475Smrg#if OPT_BROKEN_ST
1848d522f475Smrg	/*
1849d522f475Smrg	 * Before patch #171, carriage control embedded within an OSC string
1850d522f475Smrg	 * would terminate it.  Some (buggy, of course) applications rely on
1851d522f475Smrg	 * this behavior.  Accommodate them by allowing one to compile xterm
1852d522f475Smrg	 * and emulate the old behavior.
1853d522f475Smrg	 */
1854d522f475Smrg	if (screen->brokenStringTerm
1855d522f475Smrg	    && sp->parsestate == sos_table
1856d522f475Smrg	    && c < 32) {
1857d522f475Smrg	    switch (c) {
185820d2c4d2Smrg	    case ANSI_EOT:	/* FALLTHRU */
185920d2c4d2Smrg	    case ANSI_BS:	/* FALLTHRU */
186020d2c4d2Smrg	    case ANSI_HT:	/* FALLTHRU */
186120d2c4d2Smrg	    case ANSI_LF:	/* FALLTHRU */
186220d2c4d2Smrg	    case ANSI_VT:	/* FALLTHRU */
186320d2c4d2Smrg	    case ANSI_FF:	/* FALLTHRU */
186420d2c4d2Smrg	    case ANSI_CR:	/* FALLTHRU */
186520d2c4d2Smrg	    case ANSI_SO:	/* FALLTHRU */
186620d2c4d2Smrg	    case ANSI_SI:	/* FALLTHRU */
186720d2c4d2Smrg	    case ANSI_XON:	/* FALLTHRU */
186820d2c4d2Smrg	    case ANSI_CAN:
186920d2c4d2Smrg		illegal_parse(xw, c, sp);
1870d522f475Smrg		TRACE(("Reset to ground state (brokenStringTerm)\n"));
1871d522f475Smrg		break;
1872d522f475Smrg	    }
1873d522f475Smrg	}
1874d522f475Smrg#endif
1875d522f475Smrg
1876d522f475Smrg#if OPT_C1_PRINT
1877d522f475Smrg	/*
1878d522f475Smrg	 * This is not completely foolproof, but will allow an application
1879d522f475Smrg	 * with values in the C1 range to use them as printable characters,
1880d522f475Smrg	 * provided that they are not intermixed with an escape sequence.
1881d522f475Smrg	 */
1882d522f475Smrg	if (screen->c1_printable
1883d522f475Smrg	    && (c >= 128 && c < 160)) {
1884d522f475Smrg	    sp->nextstate = (sp->parsestate == esc_table
1885d522f475Smrg			     ? CASE_ESC_IGNORE
1886d522f475Smrg			     : sp->parsestate[E2A(160)]);
1887d522f475Smrg	}
1888d522f475Smrg#endif
1889d522f475Smrg
1890d522f475Smrg#if OPT_WIDE_CHARS
1891d522f475Smrg	/*
1892d522f475Smrg	 * If we have a C1 code and the c1_printable flag is not set, simply
1893d522f475Smrg	 * ignore it when it was translated from UTF-8.  That is because the
1894d522f475Smrg	 * value could not have been present as-is in the UTF-8.
1895d522f475Smrg	 *
1896d522f475Smrg	 * To see that CASE_IGNORE is a consistent value, note that it is
1897d522f475Smrg	 * always used for NUL and other uninteresting C0 controls.
1898d522f475Smrg	 */
1899d522f475Smrg#if OPT_C1_PRINT
1900d522f475Smrg	if (!screen->c1_printable)
1901d522f475Smrg#endif
1902d522f475Smrg	    if (screen->wide_chars
1903d522f475Smrg		&& (c >= 128 && c < 160)) {
1904d522f475Smrg		sp->nextstate = CASE_IGNORE;
1905d522f475Smrg	    }
1906d522f475Smrg
1907d522f475Smrg	/*
1908d522f475Smrg	 * If this character is a different width than the last one, put the
1909d522f475Smrg	 * previous text into the buffer and draw it now.
1910d522f475Smrg	 */
1911956cc18dSsnj	this_is_wide = isWide((int) c);
1912956cc18dSsnj	if (this_is_wide != sp->last_was_wide) {
1913d522f475Smrg	    WriteNow();
1914d522f475Smrg	}
1915d522f475Smrg#endif
1916d522f475Smrg
1917d522f475Smrg	/*
1918d522f475Smrg	 * Accumulate string for printable text.  This may be 8/16-bit
1919d522f475Smrg	 * characters.
1920d522f475Smrg	 */
1921d522f475Smrg	if (sp->nextstate == CASE_PRINT) {
1922956cc18dSsnj	    SafeAlloc(IChar, sp->print_area, sp->print_used, sp->print_size);
1923d522f475Smrg	    if (new_string == 0) {
19240bd37d32Smrg		xtermWarning("Cannot allocate %lu bytes for printable text\n",
19250bd37d32Smrg			     (unsigned long) new_length);
1926d522f475Smrg		continue;
1927d522f475Smrg	    }
1928d522f475Smrg#if OPT_VT52_MODE
1929d522f475Smrg	    /*
1930d522f475Smrg	     * Strip output text to 7-bits for VT52.  We should do this for
1931d522f475Smrg	     * VT100 also (which is a 7-bit device), but xterm has been
1932d522f475Smrg	     * doing this for so long we shouldn't change this behavior.
1933d522f475Smrg	     */
1934d522f475Smrg	    if (screen->vtXX_level < 1)
1935d522f475Smrg		c &= 0x7f;
1936d522f475Smrg#endif
1937956cc18dSsnj	    sp->print_area = new_string;
1938956cc18dSsnj	    sp->print_size = new_length;
1939956cc18dSsnj	    sp->print_area[sp->print_used++] = (IChar) c;
19402eaa94a1Schristos	    sp->lastchar = thischar = (int) c;
1941d522f475Smrg#if OPT_WIDE_CHARS
1942956cc18dSsnj	    sp->last_was_wide = this_is_wide;
1943d522f475Smrg#endif
1944d522f475Smrg	    if (morePtyData(screen, VTbuffer)) {
1945d522f475Smrg		continue;
1946d522f475Smrg	    }
1947d522f475Smrg	}
1948d522f475Smrg
1949d522f475Smrg	if (sp->nextstate == CASE_PRINT
1950956cc18dSsnj	    || (laststate == CASE_PRINT && sp->print_used)) {
1951d522f475Smrg	    WriteNow();
1952d522f475Smrg	}
1953d522f475Smrg
1954d522f475Smrg	/*
1955d522f475Smrg	 * Accumulate string for APC, DCS, PM, OSC, SOS controls
1956d522f475Smrg	 * This should always be 8-bit characters.
1957d522f475Smrg	 */
1958d522f475Smrg	if (sp->parsestate == sos_table) {
1959956cc18dSsnj	    SafeAlloc(Char, sp->string_area, sp->string_used, sp->string_size);
1960d522f475Smrg	    if (new_string == 0) {
19610bd37d32Smrg		xtermWarning("Cannot allocate %lu bytes for string mode %d\n",
19620bd37d32Smrg			     (unsigned long) new_length, sp->string_mode);
1963d522f475Smrg		continue;
1964d522f475Smrg	    }
1965d522f475Smrg#if OPT_WIDE_CHARS
1966d522f475Smrg	    /*
1967d522f475Smrg	     * We cannot display codes above 255, but let's try to
1968d522f475Smrg	     * accommodate the application a little by not aborting the
1969d522f475Smrg	     * string.
1970d522f475Smrg	     */
1971d522f475Smrg	    if ((c & 0xffff) > 255) {
1972d522f475Smrg		sp->nextstate = CASE_PRINT;
1973d522f475Smrg		c = '?';
1974d522f475Smrg	    }
1975d522f475Smrg#endif
1976956cc18dSsnj	    sp->string_area = new_string;
1977956cc18dSsnj	    sp->string_size = new_length;
1978956cc18dSsnj	    sp->string_area[(sp->string_used)++] = CharOf(c);
1979d522f475Smrg	} else if (sp->parsestate != esc_table) {
1980d522f475Smrg	    /* if we were accumulating, we're not any more */
1981d522f475Smrg	    sp->string_mode = 0;
1982956cc18dSsnj	    sp->string_used = 0;
1983d522f475Smrg	}
1984d522f475Smrg
19850bd37d32Smrg	DumpParams();
1986d522f475Smrg	TRACE(("parse %04X -> %d %s\n", c, sp->nextstate, which_table(sp->parsestate)));
1987d522f475Smrg
19880bd37d32Smrg	/*
19890bd37d32Smrg	 * If the parameter list has subparameters (tokens separated by ":")
19900bd37d32Smrg	 * reject any controls that do not accept subparameters.
19910bd37d32Smrg	 */
19920bd37d32Smrg	if (parms.has_subparams) {
19930bd37d32Smrg	    switch (sp->nextstate) {
19940bd37d32Smrg	    case CASE_GROUND_STATE:
19950bd37d32Smrg	    case CASE_CSI_IGNORE:
19960bd37d32Smrg		/* FALLTHRU */
19970bd37d32Smrg
19980bd37d32Smrg	    case CASE_ESC_DIGIT:
19990bd37d32Smrg	    case CASE_ESC_SEMI:
20000bd37d32Smrg	    case CASE_ESC_COLON:
20010bd37d32Smrg		/* these states are required to parse parameter lists */
20020bd37d32Smrg		break;
20030bd37d32Smrg
20040bd37d32Smrg	    case CASE_SGR:
20050bd37d32Smrg		TRACE(("...possible subparam usage\n"));
20060bd37d32Smrg		break;
20070bd37d32Smrg
20080bd37d32Smrg	    case CASE_CSI_DEC_DOLLAR_STATE:
20090bd37d32Smrg	    case CASE_CSI_DOLLAR_STATE:
20100bd37d32Smrg	    case CASE_CSI_EX_STATE:
20110bd37d32Smrg	    case CASE_CSI_QUOTE_STATE:
20120bd37d32Smrg	    case CASE_CSI_SPACE_STATE:
20130bd37d32Smrg	    case CASE_CSI_STAR_STATE:
20140bd37d32Smrg	    case CASE_CSI_TICK_STATE:
20150bd37d32Smrg	    case CASE_DEC2_STATE:
20160bd37d32Smrg	    case CASE_DEC3_STATE:
20170bd37d32Smrg	    case CASE_DEC_STATE:
20180bd37d32Smrg		/* use this branch when we do not yet have the final character */
20190bd37d32Smrg		TRACE(("...unexpected subparam usage\n"));
20200bd37d32Smrg		ParamsDone();
20210bd37d32Smrg		sp->nextstate = CASE_CSI_IGNORE;
20220bd37d32Smrg		break;
20230bd37d32Smrg
20240bd37d32Smrg	    default:
20250bd37d32Smrg		/* use this branch for cases where we have the final character
20260bd37d32Smrg		 * in the table that processed the parameter list.
20270bd37d32Smrg		 */
20280bd37d32Smrg		TRACE(("...unexpected subparam usage\n"));
20290bd37d32Smrg		ResetState(sp);
20300bd37d32Smrg		continue;
20310bd37d32Smrg	    }
20320bd37d32Smrg	}
20330bd37d32Smrg
20340bd37d32Smrg	if (xw->misc.palette_changed) {
20350bd37d32Smrg	    repaintWhenPaletteChanged(xw, sp);
20360bd37d32Smrg	}
20370bd37d32Smrg
2038d522f475Smrg	switch (sp->nextstate) {
2039d522f475Smrg	case CASE_PRINT:
2040d522f475Smrg	    TRACE(("CASE_PRINT - printable characters\n"));
2041d522f475Smrg	    break;
2042d522f475Smrg
2043d522f475Smrg	case CASE_GROUND_STATE:
2044d522f475Smrg	    TRACE(("CASE_GROUND_STATE - exit ignore mode\n"));
204520d2c4d2Smrg	    ResetState(sp);
2046d522f475Smrg	    break;
2047d522f475Smrg
2048d522f475Smrg	case CASE_IGNORE:
2049d522f475Smrg	    TRACE(("CASE_IGNORE - Ignore character %02X\n", c));
2050d522f475Smrg	    break;
2051d522f475Smrg
2052d522f475Smrg	case CASE_ENQ:
2053d522f475Smrg	    TRACE(("CASE_ENQ - answerback\n"));
2054d522f475Smrg	    for (count = 0; screen->answer_back[count] != 0; count++)
2055d522f475Smrg		unparseputc(xw, screen->answer_back[count]);
2056d522f475Smrg	    unparse_end(xw);
2057d522f475Smrg	    break;
2058d522f475Smrg
2059d522f475Smrg	case CASE_BELL:
2060d522f475Smrg	    TRACE(("CASE_BELL - bell\n"));
2061d522f475Smrg	    if (sp->string_mode == ANSI_OSC) {
2062956cc18dSsnj		if (sp->string_used)
2063956cc18dSsnj		    sp->string_area[--(sp->string_used)] = '\0';
2064956cc18dSsnj		do_osc(xw, sp->string_area, sp->string_used, (int) c);
206520d2c4d2Smrg		ResetState(sp);
2066d522f475Smrg	    } else {
2067d522f475Smrg		/* bell */
206820d2c4d2Smrg		Bell(xw, XkbBI_TerminalBell, 0);
2069d522f475Smrg	    }
2070d522f475Smrg	    break;
2071d522f475Smrg
2072d522f475Smrg	case CASE_BS:
2073d522f475Smrg	    TRACE(("CASE_BS - backspace\n"));
2074d522f475Smrg	    CursorBack(xw, 1);
2075d522f475Smrg	    break;
2076d522f475Smrg
2077d522f475Smrg	case CASE_CR:
20780bd37d32Smrg	    TRACE(("CASE_CR\n"));
20790bd37d32Smrg	    CarriageReturn(xw);
2080d522f475Smrg	    break;
2081d522f475Smrg
2082d522f475Smrg	case CASE_ESC:
2083d522f475Smrg	    if_OPT_VT52_MODE(screen, {
2084d522f475Smrg		sp->parsestate = vt52_esc_table;
2085d522f475Smrg		break;
2086d522f475Smrg	    });
2087d522f475Smrg	    sp->parsestate = esc_table;
2088d522f475Smrg	    break;
2089d522f475Smrg
2090d522f475Smrg#if OPT_VT52_MODE
2091d522f475Smrg	case CASE_VT52_CUP:
2092d522f475Smrg	    TRACE(("CASE_VT52_CUP - VT52 cursor addressing\n"));
2093d522f475Smrg	    sp->vt52_cup = True;
20940bd37d32Smrg	    InitParams();
2095d522f475Smrg	    break;
2096d522f475Smrg
2097d522f475Smrg	case CASE_VT52_IGNORE:
2098d522f475Smrg	    TRACE(("CASE_VT52_IGNORE - VT52 ignore-character\n"));
2099d522f475Smrg	    sp->parsestate = vt52_ignore_table;
2100d522f475Smrg	    break;
2101d522f475Smrg#endif
2102d522f475Smrg
2103d522f475Smrg	case CASE_VMOT:
21040bd37d32Smrg	    TRACE(("CASE_VMOT\n"));
2105d522f475Smrg	    /*
2106d522f475Smrg	     * form feed, line feed, vertical tab
2107d522f475Smrg	     */
2108956cc18dSsnj	    xtermAutoPrint(xw, c);
2109d522f475Smrg	    xtermIndex(xw, 1);
2110d522f475Smrg	    if (xw->flags & LINEFEED)
21110bd37d32Smrg		CarriageReturn(xw);
2112d522f475Smrg	    else
2113d522f475Smrg		do_xevents();
2114d522f475Smrg	    break;
2115d522f475Smrg
2116d522f475Smrg	case CASE_CBT:
21170bd37d32Smrg	    TRACE(("CASE_CBT\n"));
2118d522f475Smrg	    /* cursor backward tabulation */
21190bd37d32Smrg	    count = one_if_default(0);
2120d522f475Smrg	    while ((count-- > 0)
2121d522f475Smrg		   && (TabToPrevStop(xw))) ;
212220d2c4d2Smrg	    ResetState(sp);
2123d522f475Smrg	    break;
2124d522f475Smrg
2125d522f475Smrg	case CASE_CHT:
21260bd37d32Smrg	    TRACE(("CASE_CHT\n"));
2127d522f475Smrg	    /* cursor forward tabulation */
21280bd37d32Smrg	    count = one_if_default(0);
2129d522f475Smrg	    while ((count-- > 0)
2130d522f475Smrg		   && (TabToNextStop(xw))) ;
213120d2c4d2Smrg	    ResetState(sp);
2132d522f475Smrg	    break;
2133d522f475Smrg
2134d522f475Smrg	case CASE_TAB:
2135d522f475Smrg	    /* tab */
2136d522f475Smrg	    TabToNextStop(xw);
2137d522f475Smrg	    break;
2138d522f475Smrg
2139d522f475Smrg	case CASE_SI:
2140d522f475Smrg	    screen->curgl = 0;
2141d522f475Smrg	    if_OPT_VT52_MODE(screen, {
214220d2c4d2Smrg		ResetState(sp);
2143d522f475Smrg	    });
2144d522f475Smrg	    break;
2145d522f475Smrg
2146d522f475Smrg	case CASE_SO:
2147d522f475Smrg	    screen->curgl = 1;
2148d522f475Smrg	    if_OPT_VT52_MODE(screen, {
214920d2c4d2Smrg		ResetState(sp);
2150d522f475Smrg	    });
2151d522f475Smrg	    break;
2152d522f475Smrg
2153d522f475Smrg	case CASE_DECDHL:
2154d522f475Smrg	    xterm_DECDHL(xw, c == '3');
215520d2c4d2Smrg	    ResetState(sp);
2156d522f475Smrg	    break;
2157d522f475Smrg
2158d522f475Smrg	case CASE_DECSWL:
2159d522f475Smrg	    xterm_DECSWL(xw);
216020d2c4d2Smrg	    ResetState(sp);
2161d522f475Smrg	    break;
2162d522f475Smrg
2163d522f475Smrg	case CASE_DECDWL:
2164d522f475Smrg	    xterm_DECDWL(xw);
216520d2c4d2Smrg	    ResetState(sp);
2166d522f475Smrg	    break;
2167d522f475Smrg
2168d522f475Smrg	case CASE_SCR_STATE:
2169d522f475Smrg	    /* enter scr state */
2170d522f475Smrg	    sp->parsestate = scrtable;
2171d522f475Smrg	    break;
2172d522f475Smrg
2173d522f475Smrg	case CASE_SCS0_STATE:
2174d522f475Smrg	    /* enter scs state 0 */
21752eaa94a1Schristos	    select_charset(sp, 0, 94);
2176d522f475Smrg	    break;
2177d522f475Smrg
2178d522f475Smrg	case CASE_SCS1_STATE:
2179d522f475Smrg	    /* enter scs state 1 */
21802eaa94a1Schristos	    select_charset(sp, 1, 94);
2181d522f475Smrg	    break;
2182d522f475Smrg
2183d522f475Smrg	case CASE_SCS2_STATE:
2184d522f475Smrg	    /* enter scs state 2 */
21852eaa94a1Schristos	    select_charset(sp, 2, 94);
2186d522f475Smrg	    break;
2187d522f475Smrg
2188d522f475Smrg	case CASE_SCS3_STATE:
2189d522f475Smrg	    /* enter scs state 3 */
21902eaa94a1Schristos	    select_charset(sp, 3, 94);
21912eaa94a1Schristos	    break;
21922eaa94a1Schristos
21932eaa94a1Schristos	case CASE_SCS1A_STATE:
21942eaa94a1Schristos	    /* enter scs state 1 */
21952eaa94a1Schristos	    select_charset(sp, 1, 96);
21962eaa94a1Schristos	    break;
21972eaa94a1Schristos
21982eaa94a1Schristos	case CASE_SCS2A_STATE:
21992eaa94a1Schristos	    /* enter scs state 2 */
22002eaa94a1Schristos	    select_charset(sp, 2, 96);
22012eaa94a1Schristos	    break;
22022eaa94a1Schristos
22032eaa94a1Schristos	case CASE_SCS3A_STATE:
22042eaa94a1Schristos	    /* enter scs state 3 */
22052eaa94a1Schristos	    select_charset(sp, 3, 96);
2206d522f475Smrg	    break;
2207d522f475Smrg
2208d522f475Smrg	case CASE_ESC_IGNORE:
2209d522f475Smrg	    /* unknown escape sequence */
2210d522f475Smrg	    sp->parsestate = eigtable;
2211d522f475Smrg	    break;
2212d522f475Smrg
2213d522f475Smrg	case CASE_ESC_DIGIT:
2214d522f475Smrg	    /* digit in csi or dec mode */
221520d2c4d2Smrg	    if (nparam > 0) {
22160bd37d32Smrg		value = zero_if_default(nparam - 1);
22170bd37d32Smrg		SetParam(nparam - 1, (10 * value) + ((int) c - '0'));
22180bd37d32Smrg		if (GetParam(nparam - 1) > 65535)
22190bd37d32Smrg		    SetParam(nparam - 1, 65535);
222020d2c4d2Smrg		if (sp->parsestate == csi_table)
222120d2c4d2Smrg		    sp->parsestate = csi2_table;
222220d2c4d2Smrg	    }
2223d522f475Smrg	    break;
2224d522f475Smrg
2225d522f475Smrg	case CASE_ESC_SEMI:
2226d522f475Smrg	    /* semicolon in csi or dec mode */
22270bd37d32Smrg	    if (nparam < NPARAM) {
22280bd37d32Smrg		parms.is_sub[nparam] = 0;
22290bd37d32Smrg		SetParam(nparam++, DEFAULT);
22300bd37d32Smrg	    }
2231d522f475Smrg	    if (sp->parsestate == csi_table)
2232d522f475Smrg		sp->parsestate = csi2_table;
2233d522f475Smrg	    break;
2234d522f475Smrg
22350bd37d32Smrg	    /*
22360bd37d32Smrg	     * A _few_ commands accept colon-separated subparameters.
22370bd37d32Smrg	     * Mark the parameter list so that we can exclude (most) bogus
22380bd37d32Smrg	     * commands with simple/fast checks.
22390bd37d32Smrg	     */
22400bd37d32Smrg	case CASE_ESC_COLON:
22410bd37d32Smrg	    if (nparam < NPARAM) {
22420bd37d32Smrg		parms.has_subparams = 1;
22430bd37d32Smrg		if (nparam == 0) {
22440bd37d32Smrg		    parms.is_sub[nparam] = 1;
22450bd37d32Smrg		    SetParam(nparam++, DEFAULT);
22460bd37d32Smrg		} else if (parms.is_sub[nparam - 1] == 0) {
22470bd37d32Smrg		    parms.is_sub[nparam - 1] = 1;
22480bd37d32Smrg		    parms.is_sub[nparam] = 2;
22490bd37d32Smrg		    parms.params[nparam] = 0;
22500bd37d32Smrg		    ++nparam;
22510bd37d32Smrg		} else {
22520bd37d32Smrg		    parms.is_sub[nparam] = 1 + parms.is_sub[nparam - 1];
22530bd37d32Smrg		    parms.params[nparam] = 0;
22540bd37d32Smrg		    ++nparam;
22550bd37d32Smrg		}
22560bd37d32Smrg	    }
22570bd37d32Smrg	    break;
22580bd37d32Smrg
2259d522f475Smrg	case CASE_DEC_STATE:
2260d522f475Smrg	    /* enter dec mode */
2261d522f475Smrg	    sp->parsestate = dec_table;
2262d522f475Smrg	    break;
2263d522f475Smrg
2264d522f475Smrg	case CASE_DEC2_STATE:
2265d522f475Smrg	    /* enter dec2 mode */
2266d522f475Smrg	    sp->parsestate = dec2_table;
2267d522f475Smrg	    break;
2268d522f475Smrg
2269d522f475Smrg	case CASE_DEC3_STATE:
2270d522f475Smrg	    /* enter dec3 mode */
2271d522f475Smrg	    sp->parsestate = dec3_table;
2272d522f475Smrg	    break;
2273d522f475Smrg
2274d522f475Smrg	case CASE_ICH:
2275d522f475Smrg	    TRACE(("CASE_ICH - insert char\n"));
22760bd37d32Smrg	    InsertChar(xw, (unsigned) one_if_default(0));
227720d2c4d2Smrg	    ResetState(sp);
2278d522f475Smrg	    break;
2279d522f475Smrg
2280d522f475Smrg	case CASE_CUU:
2281d522f475Smrg	    TRACE(("CASE_CUU - cursor up\n"));
22820bd37d32Smrg	    CursorUp(screen, one_if_default(0));
228320d2c4d2Smrg	    ResetState(sp);
2284d522f475Smrg	    break;
2285d522f475Smrg
2286d522f475Smrg	case CASE_CUD:
2287d522f475Smrg	    TRACE(("CASE_CUD - cursor down\n"));
22880bd37d32Smrg	    CursorDown(screen, one_if_default(0));
228920d2c4d2Smrg	    ResetState(sp);
2290d522f475Smrg	    break;
2291d522f475Smrg
2292d522f475Smrg	case CASE_CUF:
2293d522f475Smrg	    TRACE(("CASE_CUF - cursor forward\n"));
22940bd37d32Smrg	    CursorForward(xw, one_if_default(0));
229520d2c4d2Smrg	    ResetState(sp);
2296d522f475Smrg	    break;
2297d522f475Smrg
2298d522f475Smrg	case CASE_CUB:
2299d522f475Smrg	    TRACE(("CASE_CUB - cursor backward\n"));
23000bd37d32Smrg	    CursorBack(xw, one_if_default(0));
230120d2c4d2Smrg	    ResetState(sp);
2302d522f475Smrg	    break;
2303d522f475Smrg
2304d522f475Smrg	case CASE_CUP:
2305d522f475Smrg	    TRACE(("CASE_CUP - cursor position\n"));
2306d522f475Smrg	    if_OPT_XMC_GLITCH(screen, {
2307d522f475Smrg		Jump_XMC(xw);
2308d522f475Smrg	    });
23090bd37d32Smrg	    CursorSet(screen, one_if_default(0) - 1, one_if_default(1) - 1, xw->flags);
231020d2c4d2Smrg	    ResetState(sp);
2311d522f475Smrg	    break;
2312d522f475Smrg
2313d522f475Smrg	case CASE_VPA:
23140bd37d32Smrg	    TRACE(("CASE_VPA - vertical position absolute\n"));
23150bd37d32Smrg	    CursorSet(screen, one_if_default(0) - 1, CursorCol(xw), xw->flags);
231620d2c4d2Smrg	    ResetState(sp);
2317d522f475Smrg	    break;
2318d522f475Smrg
2319d522f475Smrg	case CASE_HPA:
23200bd37d32Smrg	    TRACE(("CASE_HPA - horizontal position absolute\n"));
23210bd37d32Smrg	    CursorSet(screen, CursorRow(xw), one_if_default(0) - 1, xw->flags);
23220bd37d32Smrg	    ResetState(sp);
23230bd37d32Smrg	    break;
23240bd37d32Smrg
23250bd37d32Smrg	case CASE_VPR:
23260bd37d32Smrg	    TRACE(("CASE_VPR - vertical position relative\n"));
23270bd37d32Smrg	    CursorSet(screen,
23280bd37d32Smrg		      CursorRow(xw) + one_if_default(0),
23290bd37d32Smrg		      CursorCol(xw),
23300bd37d32Smrg		      xw->flags);
23310bd37d32Smrg	    ResetState(sp);
23320bd37d32Smrg	    break;
23330bd37d32Smrg
23340bd37d32Smrg	case CASE_HPR:
23350bd37d32Smrg	    TRACE(("CASE_HPR - horizontal position relative\n"));
23360bd37d32Smrg	    CursorSet(screen,
23370bd37d32Smrg		      CursorRow(xw),
23380bd37d32Smrg		      CursorCol(xw) + one_if_default(0),
23390bd37d32Smrg		      xw->flags);
234020d2c4d2Smrg	    ResetState(sp);
2341d522f475Smrg	    break;
2342d522f475Smrg
2343d522f475Smrg	case CASE_HP_BUGGY_LL:
2344d522f475Smrg	    TRACE(("CASE_HP_BUGGY_LL\n"));
2345d522f475Smrg	    /* Some HP-UX applications have the bug that they
2346d522f475Smrg	       assume ESC F goes to the lower left corner of
2347d522f475Smrg	       the screen, regardless of what terminfo says. */
2348d522f475Smrg	    if (screen->hp_ll_bc)
2349d522f475Smrg		CursorSet(screen, screen->max_row, 0, xw->flags);
235020d2c4d2Smrg	    ResetState(sp);
2351d522f475Smrg	    break;
2352d522f475Smrg
2353d522f475Smrg	case CASE_ED:
2354d522f475Smrg	    TRACE(("CASE_ED - erase display\n"));
23550bd37d32Smrg	    do_cd_xtra_scroll(xw);
23560bd37d32Smrg	    do_erase_display(xw, zero_if_default(0), OFF_PROTECT);
235720d2c4d2Smrg	    ResetState(sp);
2358d522f475Smrg	    break;
2359d522f475Smrg
2360d522f475Smrg	case CASE_EL:
2361d522f475Smrg	    TRACE(("CASE_EL - erase line\n"));
23620bd37d32Smrg	    do_erase_line(xw, zero_if_default(0), OFF_PROTECT);
236320d2c4d2Smrg	    ResetState(sp);
2364d522f475Smrg	    break;
2365d522f475Smrg
2366d522f475Smrg	case CASE_ECH:
2367d522f475Smrg	    TRACE(("CASE_ECH - erase char\n"));
2368d522f475Smrg	    /* ECH */
23690bd37d32Smrg	    ClearRight(xw, one_if_default(0));
237020d2c4d2Smrg	    ResetState(sp);
2371d522f475Smrg	    break;
2372d522f475Smrg
2373d522f475Smrg	case CASE_IL:
2374d522f475Smrg	    TRACE(("CASE_IL - insert line\n"));
23750bd37d32Smrg	    set_cur_col(screen, ScrnLeftMargin(xw));
23760bd37d32Smrg	    InsertLine(xw, one_if_default(0));
237720d2c4d2Smrg	    ResetState(sp);
2378d522f475Smrg	    break;
2379d522f475Smrg
2380d522f475Smrg	case CASE_DL:
2381d522f475Smrg	    TRACE(("CASE_DL - delete line\n"));
23820bd37d32Smrg	    set_cur_col(screen, ScrnLeftMargin(xw));
23830bd37d32Smrg	    DeleteLine(xw, one_if_default(0));
238420d2c4d2Smrg	    ResetState(sp);
2385d522f475Smrg	    break;
2386d522f475Smrg
2387d522f475Smrg	case CASE_DCH:
2388d522f475Smrg	    TRACE(("CASE_DCH - delete char\n"));
23890bd37d32Smrg	    DeleteChar(xw, (unsigned) one_if_default(0));
239020d2c4d2Smrg	    ResetState(sp);
2391d522f475Smrg	    break;
2392d522f475Smrg
2393d522f475Smrg	case CASE_TRACK_MOUSE:
2394d522f475Smrg	    /*
2395d522f475Smrg	     * A single parameter other than zero is always scroll-down.
2396d522f475Smrg	     * A zero-parameter is used to reset the mouse mode, and is
2397d522f475Smrg	     * not useful for scrolling anyway.
2398d522f475Smrg	     */
23990bd37d32Smrg	    if (nparam > 1 || GetParam(0) == 0) {
2400d522f475Smrg		CELL start;
2401d522f475Smrg
2402d522f475Smrg		TRACE(("CASE_TRACK_MOUSE\n"));
2403d522f475Smrg		/* Track mouse as long as in window and between
2404d522f475Smrg		 * specified rows
2405d522f475Smrg		 */
240620d2c4d2Smrg		start.row = one_if_default(2) - 1;
24070bd37d32Smrg		start.col = GetParam(1) - 1;
2408d522f475Smrg		TrackMouse(xw,
24090bd37d32Smrg			   GetParam(0),
2410d522f475Smrg			   &start,
24110bd37d32Smrg			   GetParam(3) - 1, GetParam(4) - 2);
2412d522f475Smrg	    } else {
2413d522f475Smrg		TRACE(("CASE_SD - scroll down\n"));
2414d522f475Smrg		/* SD */
24150bd37d32Smrg		RevScroll(xw, one_if_default(0));
2416d522f475Smrg		do_xevents();
2417d522f475Smrg	    }
241820d2c4d2Smrg	    ResetState(sp);
2419d522f475Smrg	    break;
2420d522f475Smrg
2421d522f475Smrg	case CASE_DECID:
2422d522f475Smrg	    TRACE(("CASE_DECID\n"));
2423d522f475Smrg	    if_OPT_VT52_MODE(screen, {
2424d522f475Smrg		unparseputc(xw, ANSI_ESC);
2425d522f475Smrg		unparseputc(xw, '/');
2426d522f475Smrg		unparseputc(xw, 'Z');
2427d522f475Smrg		unparse_end(xw);
242820d2c4d2Smrg		ResetState(sp);
2429d522f475Smrg		break;
2430d522f475Smrg	    });
24310bd37d32Smrg	    SetParam(0, DEFAULT);	/* Default ID parameter */
2432d522f475Smrg	    /* FALLTHRU */
2433d522f475Smrg	case CASE_DA1:
2434d522f475Smrg	    TRACE(("CASE_DA1\n"));
24350bd37d32Smrg	    if (GetParam(0) <= 0) {	/* less than means DEFAULT */
2436d522f475Smrg		count = 0;
24370bd37d32Smrg		init_reply(ANSI_CSI);
2438d522f475Smrg		reply.a_pintro = '?';
2439d522f475Smrg
24400bd37d32Smrg		/*
24410bd37d32Smrg		 * The first parameter corresponds to the highest operating
24420bd37d32Smrg		 * level (i.e., service level) of the emulation.  A DEC
24430bd37d32Smrg		 * terminal can be setup to respond with a different DA
24440bd37d32Smrg		 * response, but there's no control sequence that modifies
24450bd37d32Smrg		 * this.  We set it via a resource.
2446d522f475Smrg		 */
2447d522f475Smrg		if (screen->terminal_id < 200) {
2448d522f475Smrg		    switch (screen->terminal_id) {
2449d522f475Smrg		    case 102:
2450d522f475Smrg			reply.a_param[count++] = 6;	/* VT102 */
2451d522f475Smrg			break;
2452d522f475Smrg		    case 101:
2453d522f475Smrg			reply.a_param[count++] = 1;	/* VT101 */
2454d522f475Smrg			reply.a_param[count++] = 0;	/* no options */
2455d522f475Smrg			break;
2456d522f475Smrg		    default:	/* VT100 */
2457d522f475Smrg			reply.a_param[count++] = 1;	/* VT100 */
2458d522f475Smrg			reply.a_param[count++] = 2;	/* AVO */
2459d522f475Smrg			break;
2460d522f475Smrg		    }
2461d522f475Smrg		} else {
24622eaa94a1Schristos		    reply.a_param[count++] = (ParmType) (60
24632eaa94a1Schristos							 + screen->terminal_id
24642eaa94a1Schristos							 / 100);
2465d522f475Smrg		    reply.a_param[count++] = 1;		/* 132-columns */
2466d522f475Smrg		    reply.a_param[count++] = 2;		/* printer */
2467d522f475Smrg		    reply.a_param[count++] = 6;		/* selective-erase */
2468d522f475Smrg#if OPT_SUNPC_KBD
2469d522f475Smrg		    if (xw->keyboard.type == keyboardIsVT220)
2470d522f475Smrg#endif
2471d522f475Smrg			reply.a_param[count++] = 8;	/* user-defined-keys */
2472d522f475Smrg		    reply.a_param[count++] = 9;		/* national replacement charsets */
2473d522f475Smrg		    reply.a_param[count++] = 15;	/* technical characters */
24740bd37d32Smrg		    if (screen->terminal_id >= 400) {
24750bd37d32Smrg			reply.a_param[count++] = 18;	/* windowing capability */
24760bd37d32Smrg			reply.a_param[count++] = 21;	/* horizontal scrolling */
24770bd37d32Smrg		    }
2478d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2479d522f475Smrg			reply.a_param[count++] = 22;	/* ANSI color, VT525 */
2480d522f475Smrg		    });
2481d522f475Smrg#if OPT_DEC_LOCATOR
2482d522f475Smrg		    reply.a_param[count++] = 29;	/* ANSI text locator */
2483d522f475Smrg#endif
2484d522f475Smrg		}
24852eaa94a1Schristos		reply.a_nparam = (ParmType) count;
2486d522f475Smrg		reply.a_inters = 0;
2487d522f475Smrg		reply.a_final = 'c';
2488d522f475Smrg		unparseseq(xw, &reply);
2489d522f475Smrg	    }
249020d2c4d2Smrg	    ResetState(sp);
2491d522f475Smrg	    break;
2492d522f475Smrg
2493d522f475Smrg	case CASE_DA2:
2494d522f475Smrg	    TRACE(("CASE_DA2\n"));
24950bd37d32Smrg	    if (GetParam(0) <= 0) {	/* less than means DEFAULT */
2496d522f475Smrg		count = 0;
24970bd37d32Smrg		init_reply(ANSI_CSI);
2498d522f475Smrg		reply.a_pintro = '>';
2499d522f475Smrg
25000bd37d32Smrg		if (screen->terminal_id >= 200) {
25010bd37d32Smrg		    switch (screen->terminal_id) {
25020bd37d32Smrg		    case 220:
25030bd37d32Smrg		    default:
25040bd37d32Smrg			reply.a_param[count++] = 1;	/* VT220 */
25050bd37d32Smrg			break;
25060bd37d32Smrg		    case 240:
25070bd37d32Smrg			/* http://www.decuslib.com/DECUS/vax87a/gendyn/vt200_kind.lis */
25080bd37d32Smrg			reply.a_param[count++] = 2;	/* VT240 */
25090bd37d32Smrg			break;
25100bd37d32Smrg		    case 320:
25110bd37d32Smrg			/* http://www.vt100.net/docs/vt320-uu/appendixe.html */
25120bd37d32Smrg			reply.a_param[count++] = 24;	/* VT320 */
25130bd37d32Smrg			break;
25140bd37d32Smrg		    case 330:
25150bd37d32Smrg			reply.a_param[count++] = 18;	/* VT330 */
25160bd37d32Smrg			break;
25170bd37d32Smrg		    case 340:
25180bd37d32Smrg			reply.a_param[count++] = 19;	/* VT340 */
25190bd37d32Smrg			break;
25200bd37d32Smrg		    case 420:
25210bd37d32Smrg			reply.a_param[count++] = 41;	/* VT420 */
25220bd37d32Smrg			break;
25230bd37d32Smrg		    case 510:
25240bd37d32Smrg			/* http://www.vt100.net/docs/vt510-rm/DA2 */
25250bd37d32Smrg			reply.a_param[count++] = 61;	/* VT510 */
25260bd37d32Smrg			break;
25270bd37d32Smrg		    case 520:
25280bd37d32Smrg			reply.a_param[count++] = 64;	/* VT520 */
25290bd37d32Smrg			break;
25300bd37d32Smrg		    case 525:
25310bd37d32Smrg			reply.a_param[count++] = 65;	/* VT525 */
25320bd37d32Smrg			break;
25330bd37d32Smrg		    }
25340bd37d32Smrg		} else {
2535d522f475Smrg		    reply.a_param[count++] = 0;		/* VT100 (nonstandard) */
25360bd37d32Smrg		}
2537d522f475Smrg		reply.a_param[count++] = XTERM_PATCH;	/* Version */
2538d522f475Smrg		reply.a_param[count++] = 0;	/* options (none) */
25392eaa94a1Schristos		reply.a_nparam = (ParmType) count;
2540d522f475Smrg		reply.a_inters = 0;
2541d522f475Smrg		reply.a_final = 'c';
2542d522f475Smrg		unparseseq(xw, &reply);
2543d522f475Smrg	    }
254420d2c4d2Smrg	    ResetState(sp);
2545d522f475Smrg	    break;
2546d522f475Smrg
2547d522f475Smrg	case CASE_DECRPTUI:
2548d522f475Smrg	    TRACE(("CASE_DECRPTUI\n"));
25490bd37d32Smrg	    if ((screen->vtXX_level >= 4)
25500bd37d32Smrg		&& (GetParam(0) <= 0)) {	/* less than means DEFAULT */
2551d522f475Smrg		unparseputc1(xw, ANSI_DCS);
2552d522f475Smrg		unparseputc(xw, '!');
2553d522f475Smrg		unparseputc(xw, '|');
2554d522f475Smrg		unparseputc(xw, '0');
2555d522f475Smrg		unparseputc1(xw, ANSI_ST);
2556d522f475Smrg		unparse_end(xw);
2557d522f475Smrg	    }
255820d2c4d2Smrg	    ResetState(sp);
2559d522f475Smrg	    break;
2560d522f475Smrg
2561d522f475Smrg	case CASE_TBC:
2562d522f475Smrg	    TRACE(("CASE_TBC - tab clear\n"));
25630bd37d32Smrg	    if ((value = GetParam(0)) <= 0)	/* less than means default */
2564d522f475Smrg		TabClear(xw->tabs, screen->cur_col);
25650bd37d32Smrg	    else if (value == 3)
2566d522f475Smrg		TabZonk(xw->tabs);
256720d2c4d2Smrg	    ResetState(sp);
2568d522f475Smrg	    break;
2569d522f475Smrg
2570d522f475Smrg	case CASE_SET:
2571d522f475Smrg	    TRACE(("CASE_SET - set mode\n"));
2572d522f475Smrg	    ansi_modes(xw, bitset);
257320d2c4d2Smrg	    ResetState(sp);
2574d522f475Smrg	    break;
2575d522f475Smrg
2576d522f475Smrg	case CASE_RST:
2577d522f475Smrg	    TRACE(("CASE_RST - reset mode\n"));
2578d522f475Smrg	    ansi_modes(xw, bitclr);
257920d2c4d2Smrg	    ResetState(sp);
2580d522f475Smrg	    break;
2581d522f475Smrg
2582d522f475Smrg	case CASE_SGR:
25830bd37d32Smrg	    for (item = 0; item < nparam; ++item) {
25840bd37d32Smrg		int op = GetParam(item);
25850bd37d32Smrg
2586d522f475Smrg		if_OPT_XMC_GLITCH(screen, {
25870bd37d32Smrg		    Mark_XMC(xw, op);
2588d522f475Smrg		});
25890bd37d32Smrg		TRACE(("CASE_SGR %d\n", op));
25900bd37d32Smrg
25910bd37d32Smrg		/*
25920bd37d32Smrg		 * Only SGR 38/48 accept subparameters, and in those cases
25930bd37d32Smrg		 * the values will not be seen at this point.
25940bd37d32Smrg		 */
25950bd37d32Smrg		if (param_has_subparams(item)) {
25960bd37d32Smrg		    switch (op) {
25970bd37d32Smrg		    case 38:
25980bd37d32Smrg		    case 48:
25990bd37d32Smrg			if_OPT_ISO_COLORS(screen, {
26000bd37d32Smrg			    break;
26010bd37d32Smrg			});
26020bd37d32Smrg		    default:
26030bd37d32Smrg			TRACE(("...unexpected subparameter in SGR\n"));
26040bd37d32Smrg			op = 9999;
26050bd37d32Smrg			ResetState(sp);
26060bd37d32Smrg			break;
26070bd37d32Smrg		    }
26080bd37d32Smrg		}
26090bd37d32Smrg
26100bd37d32Smrg		switch (op) {
2611d522f475Smrg		case DEFAULT:
2612d522f475Smrg		case 0:
261320d2c4d2Smrg		    UIntClr(xw->flags,
261420d2c4d2Smrg			    (INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE));
2615d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2616d522f475Smrg			reset_SGR_Colors(xw);
2617d522f475Smrg		    });
2618d522f475Smrg		    break;
2619d522f475Smrg		case 1:	/* Bold                 */
2620d522f475Smrg		    xw->flags |= BOLD;
2621d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2622d522f475Smrg			setExtendedFG(xw);
2623d522f475Smrg		    });
2624d522f475Smrg		    break;
2625d522f475Smrg		case 5:	/* Blink                */
2626d522f475Smrg		    xw->flags |= BLINK;
2627d522f475Smrg		    StartBlinking(screen);
2628d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2629d522f475Smrg			setExtendedFG(xw);
2630d522f475Smrg		    });
2631d522f475Smrg		    break;
2632d522f475Smrg		case 4:	/* Underscore           */
2633d522f475Smrg		    xw->flags |= UNDERLINE;
2634d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2635d522f475Smrg			setExtendedFG(xw);
2636d522f475Smrg		    });
2637d522f475Smrg		    break;
2638d522f475Smrg		case 7:
2639d522f475Smrg		    xw->flags |= INVERSE;
2640d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2641d522f475Smrg			setExtendedBG(xw);
2642d522f475Smrg		    });
2643d522f475Smrg		    break;
2644d522f475Smrg		case 8:
2645d522f475Smrg		    xw->flags |= INVISIBLE;
2646d522f475Smrg		    break;
2647d522f475Smrg		case 22:	/* reset 'bold' */
264820d2c4d2Smrg		    UIntClr(xw->flags, BOLD);
2649d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2650d522f475Smrg			setExtendedFG(xw);
2651d522f475Smrg		    });
2652d522f475Smrg		    break;
2653d522f475Smrg		case 24:
265420d2c4d2Smrg		    UIntClr(xw->flags, UNDERLINE);
2655d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2656d522f475Smrg			setExtendedFG(xw);
2657d522f475Smrg		    });
2658d522f475Smrg		    break;
2659d522f475Smrg		case 25:	/* reset 'blink' */
266020d2c4d2Smrg		    UIntClr(xw->flags, BLINK);
2661d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2662d522f475Smrg			setExtendedFG(xw);
2663d522f475Smrg		    });
2664d522f475Smrg		    break;
2665d522f475Smrg		case 27:
266620d2c4d2Smrg		    UIntClr(xw->flags, INVERSE);
2667d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2668d522f475Smrg			setExtendedBG(xw);
2669d522f475Smrg		    });
2670d522f475Smrg		    break;
2671d522f475Smrg		case 28:
267220d2c4d2Smrg		    UIntClr(xw->flags, INVISIBLE);
2673d522f475Smrg		    break;
2674d522f475Smrg		case 30:
2675d522f475Smrg		case 31:
2676d522f475Smrg		case 32:
2677d522f475Smrg		case 33:
2678d522f475Smrg		case 34:
2679d522f475Smrg		case 35:
2680d522f475Smrg		case 36:
2681d522f475Smrg		case 37:
2682d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
26830bd37d32Smrg			xw->sgr_foreground = (op - 30);
2684d522f475Smrg			xw->sgr_extended = False;
2685d522f475Smrg			setExtendedFG(xw);
2686d522f475Smrg		    });
2687d522f475Smrg		    break;
2688d522f475Smrg		case 38:
26890bd37d32Smrg		    /* This is more complicated than I'd like, but it should
26900bd37d32Smrg		     * properly eat all the parameters for unsupported modes.
2691d522f475Smrg		     */
2692d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
26930bd37d32Smrg			if (parse_extended_colors(xw, &value, &item)) {
26940bd37d32Smrg			    xw->sgr_foreground = value;
26950bd37d32Smrg			    xw->sgr_extended = True;
26960bd37d32Smrg			    setExtendedFG(xw);
2697d522f475Smrg			}
2698d522f475Smrg		    });
2699d522f475Smrg		    break;
2700d522f475Smrg		case 39:
2701d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2702d522f475Smrg			reset_SGR_Foreground(xw);
2703d522f475Smrg		    });
2704d522f475Smrg		    break;
2705d522f475Smrg		case 40:
2706d522f475Smrg		case 41:
2707d522f475Smrg		case 42:
2708d522f475Smrg		case 43:
2709d522f475Smrg		case 44:
2710d522f475Smrg		case 45:
2711d522f475Smrg		case 46:
2712d522f475Smrg		case 47:
2713d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
27140bd37d32Smrg			xw->sgr_background = (op - 40);
2715d522f475Smrg			setExtendedBG(xw);
2716d522f475Smrg		    });
2717d522f475Smrg		    break;
2718d522f475Smrg		case 48:
2719d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
27200bd37d32Smrg			if (parse_extended_colors(xw, &value, &item)) {
27210bd37d32Smrg			    xw->sgr_background = value;
27220bd37d32Smrg			    setExtendedBG(xw);
2723d522f475Smrg			}
2724d522f475Smrg		    });
2725d522f475Smrg		    break;
2726d522f475Smrg		case 49:
2727d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2728d522f475Smrg			reset_SGR_Background(xw);
2729d522f475Smrg		    });
2730d522f475Smrg		    break;
2731d522f475Smrg		case 90:
2732d522f475Smrg		case 91:
2733d522f475Smrg		case 92:
2734d522f475Smrg		case 93:
2735d522f475Smrg		case 94:
2736d522f475Smrg		case 95:
2737d522f475Smrg		case 96:
2738d522f475Smrg		case 97:
2739d522f475Smrg		    if_OPT_AIX_COLORS(screen, {
27400bd37d32Smrg			xw->sgr_foreground = (op - 90 + 8);
2741d522f475Smrg			xw->sgr_extended = False;
2742d522f475Smrg			setExtendedFG(xw);
2743d522f475Smrg		    });
2744d522f475Smrg		    break;
2745d522f475Smrg		case 100:
2746d522f475Smrg#if !OPT_AIX_COLORS
2747d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2748d522f475Smrg			reset_SGR_Foreground(xw);
2749d522f475Smrg			reset_SGR_Background(xw);
2750d522f475Smrg		    });
2751d522f475Smrg		    break;
2752d522f475Smrg#endif
2753d522f475Smrg		case 101:
2754d522f475Smrg		case 102:
2755d522f475Smrg		case 103:
2756d522f475Smrg		case 104:
2757d522f475Smrg		case 105:
2758d522f475Smrg		case 106:
2759d522f475Smrg		case 107:
2760d522f475Smrg		    if_OPT_AIX_COLORS(screen, {
27610bd37d32Smrg			xw->sgr_background = (op - 100 + 8);
2762d522f475Smrg			setExtendedBG(xw);
2763d522f475Smrg		    });
2764d522f475Smrg		    break;
2765d522f475Smrg		}
2766d522f475Smrg	    }
276720d2c4d2Smrg	    ResetState(sp);
2768d522f475Smrg	    break;
2769d522f475Smrg
2770d522f475Smrg	    /* DSR (except for the '?') is a superset of CPR */
2771d522f475Smrg	case CASE_DSR:
2772d522f475Smrg	    sp->private_function = True;
2773d522f475Smrg
2774d522f475Smrg	    /* FALLTHRU */
2775d522f475Smrg	case CASE_CPR:
27760bd37d32Smrg	    TRACE(("CASE_DSR - device status report\n"));
2777d522f475Smrg	    count = 0;
27780bd37d32Smrg	    init_reply(ANSI_CSI);
27792eaa94a1Schristos	    reply.a_pintro = CharOf(sp->private_function ? '?' : 0);
2780d522f475Smrg	    reply.a_inters = 0;
2781d522f475Smrg	    reply.a_final = 'n';
2782d522f475Smrg
27830bd37d32Smrg	    switch (GetParam(0)) {
2784d522f475Smrg	    case 5:
27850bd37d32Smrg		TRACE(("...request operating status\n"));
2786d522f475Smrg		/* operating status */
2787d522f475Smrg		reply.a_param[count++] = 0;	/* (no malfunction ;-) */
2788d522f475Smrg		break;
2789d522f475Smrg	    case 6:
27900bd37d32Smrg		TRACE(("...request %s\n",
27910bd37d32Smrg		       (sp->private_function
27920bd37d32Smrg			? "DECXCPR"
27930bd37d32Smrg			: "CPR")));
2794d522f475Smrg		/* CPR */
27950bd37d32Smrg		/* DECXCPR (with page=1) */
27962eaa94a1Schristos		reply.a_param[count++] = (ParmType) (screen->cur_row + 1);
27972eaa94a1Schristos		reply.a_param[count++] = (ParmType) (screen->cur_col + 1);
27980bd37d32Smrg		if (sp->private_function
27990bd37d32Smrg		    && screen->vtXX_level >= 4) {	/* VT420 */
28000bd37d32Smrg		    reply.a_param[count++] = 1;
28010bd37d32Smrg		}
2802d522f475Smrg		reply.a_final = 'R';
2803d522f475Smrg		break;
2804d522f475Smrg	    case 15:
28050bd37d32Smrg		TRACE(("...request printer status\n"));
28060bd37d32Smrg		if (sp->private_function
28070bd37d32Smrg		    && screen->vtXX_level >= 2) {	/* VT220 */
28082eaa94a1Schristos		    reply.a_param[count++] = 13;	/* implement printer */
28092eaa94a1Schristos		}
2810d522f475Smrg		break;
2811d522f475Smrg	    case 25:
28120bd37d32Smrg		TRACE(("...request UDK status\n"));
28130bd37d32Smrg		if (sp->private_function
28140bd37d32Smrg		    && screen->vtXX_level >= 2) {	/* VT220 */
28152eaa94a1Schristos		    reply.a_param[count++] = 20;	/* UDK always unlocked */
28162eaa94a1Schristos		}
2817d522f475Smrg		break;
2818d522f475Smrg	    case 26:
28190bd37d32Smrg		TRACE(("...request keyboard status\n"));
28200bd37d32Smrg		if (sp->private_function
28210bd37d32Smrg		    && screen->vtXX_level >= 2) {	/* VT220 */
28222eaa94a1Schristos		    reply.a_param[count++] = 27;
28232eaa94a1Schristos		    reply.a_param[count++] = 1;		/* North American */
28240bd37d32Smrg		    if (screen->vtXX_level >= 4) {	/* VT420 */
28252eaa94a1Schristos			reply.a_param[count++] = 0;	/* ready */
28262eaa94a1Schristos			reply.a_param[count++] = 0;	/* LK201 */
28272eaa94a1Schristos		    }
2828d522f475Smrg		}
2829d522f475Smrg		break;
2830d522f475Smrg	    case 53:
28310bd37d32Smrg		TRACE(("...request locator status\n"));
28320bd37d32Smrg		if (sp->private_function
28330bd37d32Smrg		    && screen->vtXX_level >= 2) {	/* VT220 */
2834d522f475Smrg#if OPT_DEC_LOCATOR
28352eaa94a1Schristos		    reply.a_param[count++] = 50;	/* locator ready */
2836d522f475Smrg#else
28372eaa94a1Schristos		    reply.a_param[count++] = 53;	/* no locator */
2838d522f475Smrg#endif
28392eaa94a1Schristos		}
28402eaa94a1Schristos		break;
28410bd37d32Smrg	    case 62:
28420bd37d32Smrg		TRACE(("...request DECMSR - macro space\n"));
28430bd37d32Smrg		if (sp->private_function
28440bd37d32Smrg		    && screen->vtXX_level >= 4) {	/* VT420 */
28450bd37d32Smrg		    reply.a_pintro = 0;
28460bd37d32Smrg		    reply.a_radix[count] = 16;	/* no data */
28470bd37d32Smrg		    reply.a_param[count++] = 0;		/* no space for macros */
28480bd37d32Smrg		    reply.a_inters = '*';
28490bd37d32Smrg		    reply.a_final = '{';
28500bd37d32Smrg		}
28510bd37d32Smrg		break;
28520bd37d32Smrg	    case 63:
28530bd37d32Smrg		TRACE(("...request DECCKSR - memory checksum\n"));
28540bd37d32Smrg		/* DECCKSR - Memory checksum */
28550bd37d32Smrg		if (sp->private_function
28560bd37d32Smrg		    && screen->vtXX_level >= 4) {	/* VT420 */
28570bd37d32Smrg		    init_reply(ANSI_DCS);
28580bd37d32Smrg		    reply.a_param[count++] = (ParmType) GetParam(1);	/* PID */
28590bd37d32Smrg		    reply.a_delim = "!~";	/* delimiter */
28600bd37d32Smrg		    reply.a_radix[count] = 16;	/* use hex */
28610bd37d32Smrg		    reply.a_param[count++] = 0;		/* no data */
28620bd37d32Smrg		}
28630bd37d32Smrg		break;
28640bd37d32Smrg	    case 75:
28650bd37d32Smrg		TRACE(("...request data integrity\n"));
28660bd37d32Smrg		if (sp->private_function
28670bd37d32Smrg		    && screen->vtXX_level >= 4) {	/* VT420 */
28680bd37d32Smrg		    reply.a_param[count++] = 70;	/* no errors */
28690bd37d32Smrg		}
28700bd37d32Smrg		break;
28710bd37d32Smrg	    case 85:
28720bd37d32Smrg		TRACE(("...request multi-session configuration\n"));
28730bd37d32Smrg		if (sp->private_function
28740bd37d32Smrg		    && screen->vtXX_level >= 4) {	/* VT420 */
28750bd37d32Smrg		    reply.a_param[count++] = 83;	/* not configured */
28760bd37d32Smrg		}
28770bd37d32Smrg		break;
28782eaa94a1Schristos	    default:
2879d522f475Smrg		break;
2880d522f475Smrg	    }
2881d522f475Smrg
28822eaa94a1Schristos	    if ((reply.a_nparam = (ParmType) count) != 0)
2883d522f475Smrg		unparseseq(xw, &reply);
2884d522f475Smrg
288520d2c4d2Smrg	    ResetState(sp);
2886d522f475Smrg	    sp->private_function = False;
2887d522f475Smrg	    break;
2888d522f475Smrg
2889d522f475Smrg	case CASE_MC:
2890d522f475Smrg	    TRACE(("CASE_MC - media control\n"));
28910bd37d32Smrg	    xtermMediaControl(xw, GetParam(0), False);
289220d2c4d2Smrg	    ResetState(sp);
2893d522f475Smrg	    break;
2894d522f475Smrg
2895d522f475Smrg	case CASE_DEC_MC:
2896d522f475Smrg	    TRACE(("CASE_DEC_MC - DEC media control\n"));
28970bd37d32Smrg	    xtermMediaControl(xw, GetParam(0), True);
289820d2c4d2Smrg	    ResetState(sp);
2899d522f475Smrg	    break;
2900d522f475Smrg
2901d522f475Smrg	case CASE_HP_MEM_LOCK:
2902d522f475Smrg	case CASE_HP_MEM_UNLOCK:
2903d522f475Smrg	    TRACE(("%s\n", ((sp->parsestate[c] == CASE_HP_MEM_LOCK)
2904d522f475Smrg			    ? "CASE_HP_MEM_LOCK"
2905d522f475Smrg			    : "CASE_HP_MEM_UNLOCK")));
2906d522f475Smrg	    if (screen->scroll_amt)
2907d522f475Smrg		FlushScroll(xw);
2908d522f475Smrg	    if (sp->parsestate[c] == CASE_HP_MEM_LOCK)
2909d522f475Smrg		set_tb_margins(screen, screen->cur_row, screen->bot_marg);
2910d522f475Smrg	    else
2911d522f475Smrg		set_tb_margins(screen, 0, screen->bot_marg);
291220d2c4d2Smrg	    ResetState(sp);
2913d522f475Smrg	    break;
2914d522f475Smrg
2915d522f475Smrg	case CASE_DECSTBM:
2916d522f475Smrg	    TRACE(("CASE_DECSTBM - set scrolling region\n"));
29170bd37d32Smrg	    {
29180bd37d32Smrg		int top;
29190bd37d32Smrg		int bot;
29200bd37d32Smrg		top = one_if_default(0);
29210bd37d32Smrg		if (nparam < 2 || (bot = GetParam(1)) == DEFAULT
29220bd37d32Smrg		    || bot > MaxRows(screen)
29230bd37d32Smrg		    || bot == 0)
29240bd37d32Smrg		    bot = MaxRows(screen);
29250bd37d32Smrg		if (bot > top) {
29260bd37d32Smrg		    if (screen->scroll_amt)
29270bd37d32Smrg			FlushScroll(xw);
29280bd37d32Smrg		    set_tb_margins(screen, top - 1, bot - 1);
29290bd37d32Smrg		    CursorSet(screen, 0, 0, xw->flags);
29300bd37d32Smrg		}
29310bd37d32Smrg		ResetState(sp);
2932d522f475Smrg	    }
2933d522f475Smrg	    break;
2934d522f475Smrg
2935d522f475Smrg	case CASE_DECREQTPARM:
2936d522f475Smrg	    TRACE(("CASE_DECREQTPARM\n"));
2937d522f475Smrg	    if (screen->terminal_id < 200) {	/* VT102 */
29380bd37d32Smrg		value = zero_if_default(0);
29390bd37d32Smrg		if (value == 0 || value == 1) {
29400bd37d32Smrg		    init_reply(ANSI_CSI);
2941d522f475Smrg		    reply.a_pintro = 0;
2942d522f475Smrg		    reply.a_nparam = 7;
29430bd37d32Smrg		    reply.a_param[0] = (ParmType) (value + 2);
2944d522f475Smrg		    reply.a_param[1] = 1;	/* no parity */
2945d522f475Smrg		    reply.a_param[2] = 1;	/* eight bits */
2946d522f475Smrg		    reply.a_param[3] = 128;	/* transmit 38.4k baud */
2947d522f475Smrg		    reply.a_param[4] = 128;	/* receive 38.4k baud */
2948d522f475Smrg		    reply.a_param[5] = 1;	/* clock multiplier ? */
2949d522f475Smrg		    reply.a_param[6] = 0;	/* STP flags ? */
2950d522f475Smrg		    reply.a_inters = 0;
2951d522f475Smrg		    reply.a_final = 'x';
2952d522f475Smrg		    unparseseq(xw, &reply);
2953d522f475Smrg		}
2954d522f475Smrg	    }
295520d2c4d2Smrg	    ResetState(sp);
2956d522f475Smrg	    break;
2957d522f475Smrg
2958d522f475Smrg	case CASE_DECSET:
2959d522f475Smrg	    /* DECSET */
2960d522f475Smrg#if OPT_VT52_MODE
2961d522f475Smrg	    if (screen->vtXX_level != 0)
2962d522f475Smrg#endif
2963d522f475Smrg		dpmodes(xw, bitset);
296420d2c4d2Smrg	    ResetState(sp);
2965d522f475Smrg#if OPT_TEK4014
2966d522f475Smrg	    if (TEK4014_ACTIVE(xw))
2967d522f475Smrg		return False;
2968d522f475Smrg#endif
2969d522f475Smrg	    break;
2970d522f475Smrg
2971d522f475Smrg	case CASE_DECRST:
2972d522f475Smrg	    /* DECRST */
2973d522f475Smrg	    dpmodes(xw, bitclr);
29742eaa94a1Schristos	    init_groundtable(screen, sp);
297520d2c4d2Smrg	    ResetState(sp);
2976d522f475Smrg	    break;
2977d522f475Smrg
2978d522f475Smrg	case CASE_DECALN:
2979d522f475Smrg	    TRACE(("CASE_DECALN - alignment test\n"));
2980d522f475Smrg	    if (screen->cursor_state)
2981d522f475Smrg		HideCursor();
29820bd37d32Smrg	    reset_margins(screen);
2983d522f475Smrg	    CursorSet(screen, 0, 0, xw->flags);
2984d522f475Smrg	    xtermParseRect(xw, 0, 0, &myRect);
2985d522f475Smrg	    ScrnFillRectangle(xw, &myRect, 'E', 0, False);
298620d2c4d2Smrg	    ResetState(sp);
2987d522f475Smrg	    break;
2988d522f475Smrg
2989d522f475Smrg	case CASE_GSETS:
2990d522f475Smrg	    TRACE(("CASE_GSETS(%d) = '%c'\n", sp->scstype, c));
2991d522f475Smrg	    if (screen->vtXX_level != 0)
29922eaa94a1Schristos		screen->gsets[sp->scstype] = CharOf(c);
299320d2c4d2Smrg	    ResetState(sp);
2994d522f475Smrg	    break;
2995d522f475Smrg
29960bd37d32Smrg	case CASE_ANSI_SC:
29970bd37d32Smrg	    if (IsLeftRightMode(xw)) {
29980bd37d32Smrg		int left;
29990bd37d32Smrg		int right;
30000bd37d32Smrg
30010bd37d32Smrg		TRACE(("CASE_DECSLRM - set left and right margin\n"));
30020bd37d32Smrg		left = one_if_default(0);
30030bd37d32Smrg		if (nparam < 2 || (right = GetParam(1)) == DEFAULT
30040bd37d32Smrg		    || right > MaxCols(screen)
30050bd37d32Smrg		    || right == 0)
30060bd37d32Smrg		    right = MaxCols(screen);
30070bd37d32Smrg		if (right > left) {
30080bd37d32Smrg		    set_lr_margins(screen, left - 1, right - 1);
30090bd37d32Smrg		    CursorSet(screen, 0, 0, xw->flags);
30100bd37d32Smrg		}
30110bd37d32Smrg	    } else {
30120bd37d32Smrg		TRACE(("CASE_ANSI_SC - save cursor\n"));
30130bd37d32Smrg		CursorSave(xw);
30140bd37d32Smrg	    }
30150bd37d32Smrg	    ResetState(sp);
30160bd37d32Smrg	    break;
30170bd37d32Smrg
3018d522f475Smrg	case CASE_DECSC:
3019d522f475Smrg	    TRACE(("CASE_DECSC - save cursor\n"));
3020d522f475Smrg	    CursorSave(xw);
302120d2c4d2Smrg	    ResetState(sp);
3022d522f475Smrg	    break;
3023d522f475Smrg
30240bd37d32Smrg	case CASE_ANSI_RC:
3025d522f475Smrg	case CASE_DECRC:
30260bd37d32Smrg	    TRACE(("CASE_%sRC - restore cursor\n",
30270bd37d32Smrg		   (sp->nextstate == CASE_DECRC) ? "DEC" : "ANSI_"));
3028d522f475Smrg	    CursorRestore(xw);
3029d522f475Smrg	    if_OPT_ISO_COLORS(screen, {
3030d522f475Smrg		setExtendedFG(xw);
3031d522f475Smrg	    });
303220d2c4d2Smrg	    ResetState(sp);
3033d522f475Smrg	    break;
3034d522f475Smrg
3035d522f475Smrg	case CASE_DECKPAM:
3036d522f475Smrg	    TRACE(("CASE_DECKPAM\n"));
3037d522f475Smrg	    xw->keyboard.flags |= MODE_DECKPAM;
3038d522f475Smrg	    update_appkeypad();
303920d2c4d2Smrg	    ResetState(sp);
3040d522f475Smrg	    break;
3041d522f475Smrg
3042d522f475Smrg	case CASE_DECKPNM:
3043d522f475Smrg	    TRACE(("CASE_DECKPNM\n"));
304420d2c4d2Smrg	    UIntClr(xw->keyboard.flags, MODE_DECKPAM);
3045d522f475Smrg	    update_appkeypad();
304620d2c4d2Smrg	    ResetState(sp);
3047d522f475Smrg	    break;
3048d522f475Smrg
3049d522f475Smrg	case CASE_CSI_QUOTE_STATE:
3050d522f475Smrg	    sp->parsestate = csi_quo_table;
3051d522f475Smrg	    break;
3052d522f475Smrg
305320d2c4d2Smrg#if OPT_BLINK_CURS
305420d2c4d2Smrg	case CASE_CSI_SPACE_STATE:
305520d2c4d2Smrg	    sp->parsestate = csi_sp_table;
305620d2c4d2Smrg	    break;
305720d2c4d2Smrg
305820d2c4d2Smrg	case CASE_DECSCUSR:
305920d2c4d2Smrg	    TRACE(("CASE_DECSCUSR\n"));
306020d2c4d2Smrg	    {
306120d2c4d2Smrg		Boolean change = True;
30620bd37d32Smrg		Boolean blinks = screen->cursor_blink_esc;
306320d2c4d2Smrg
306420d2c4d2Smrg		HideCursor();
306520d2c4d2Smrg
30660bd37d32Smrg		switch (GetParam(0)) {
306720d2c4d2Smrg		case DEFAULT:
30680bd37d32Smrg		case DEFAULT_STYLE:
30690bd37d32Smrg		case BLINK_BLOCK:
307020d2c4d2Smrg		    blinks = True;
30710bd37d32Smrg		    screen->cursor_shape = CURSOR_BLOCK;
307220d2c4d2Smrg		    break;
30730bd37d32Smrg		case STEADY_BLOCK:
307420d2c4d2Smrg		    blinks = False;
30750bd37d32Smrg		    screen->cursor_shape = CURSOR_BLOCK;
307620d2c4d2Smrg		    break;
30770bd37d32Smrg		case BLINK_UNDERLINE:
307820d2c4d2Smrg		    blinks = True;
30790bd37d32Smrg		    screen->cursor_shape = CURSOR_UNDERLINE;
308020d2c4d2Smrg		    break;
30810bd37d32Smrg		case STEADY_UNDERLINE:
30820bd37d32Smrg		    blinks = False;
30830bd37d32Smrg		    screen->cursor_shape = CURSOR_UNDERLINE;
30840bd37d32Smrg		    break;
30850bd37d32Smrg		case BLINK_BAR:
30860bd37d32Smrg		    blinks = True;
30870bd37d32Smrg		    screen->cursor_shape = CURSOR_BAR;
30880bd37d32Smrg		    break;
30890bd37d32Smrg		case STEADY_BAR:
309020d2c4d2Smrg		    blinks = False;
30910bd37d32Smrg		    screen->cursor_shape = CURSOR_BAR;
309220d2c4d2Smrg		    break;
309320d2c4d2Smrg		default:
309420d2c4d2Smrg		    change = False;
309520d2c4d2Smrg		    break;
309620d2c4d2Smrg		}
309720d2c4d2Smrg
309820d2c4d2Smrg		if (change) {
309920d2c4d2Smrg		    xtermSetCursorBox(screen);
31000bd37d32Smrg		    screen->cursor_blink_esc = blinks;
31010bd37d32Smrg		    UpdateCursorBlink(screen);
310220d2c4d2Smrg		}
310320d2c4d2Smrg	    }
310420d2c4d2Smrg	    ResetState(sp);
310520d2c4d2Smrg	    break;
310620d2c4d2Smrg#endif
310720d2c4d2Smrg
310820d2c4d2Smrg#if OPT_SCROLL_LOCK
310920d2c4d2Smrg	case CASE_DECLL:
311020d2c4d2Smrg	    TRACE(("CASE_DECLL\n"));
311120d2c4d2Smrg	    if (nparam > 0) {
311220d2c4d2Smrg		for (count = 0; count < nparam; ++count) {
31130bd37d32Smrg		    int op = zero_if_default(count);
31140bd37d32Smrg		    switch (op) {
311520d2c4d2Smrg		    case 0:
311620d2c4d2Smrg		    case DEFAULT:
311720d2c4d2Smrg			xtermClearLEDs(screen);
311820d2c4d2Smrg			break;
311920d2c4d2Smrg		    case 1:
312020d2c4d2Smrg		    case 2:
312120d2c4d2Smrg		    case 3:
31220bd37d32Smrg			xtermShowLED(screen,
31230bd37d32Smrg				     (Cardinal) op,
31240bd37d32Smrg				     True);
312520d2c4d2Smrg			break;
312620d2c4d2Smrg		    case 21:
312720d2c4d2Smrg		    case 22:
312820d2c4d2Smrg		    case 23:
31290bd37d32Smrg			xtermShowLED(screen,
31300bd37d32Smrg				     (Cardinal) (op - 20),
31310bd37d32Smrg				     True);
313220d2c4d2Smrg			break;
313320d2c4d2Smrg		    }
313420d2c4d2Smrg		}
313520d2c4d2Smrg	    } else {
313620d2c4d2Smrg		xtermClearLEDs(screen);
313720d2c4d2Smrg	    }
313820d2c4d2Smrg	    ResetState(sp);
313920d2c4d2Smrg	    break;
314020d2c4d2Smrg#endif
314120d2c4d2Smrg
3142d522f475Smrg#if OPT_VT52_MODE
3143d522f475Smrg	case CASE_VT52_FINISH:
3144d522f475Smrg	    TRACE(("CASE_VT52_FINISH terminal_id %d, vtXX_level %d\n",
3145d522f475Smrg		   screen->terminal_id,
3146d522f475Smrg		   screen->vtXX_level));
3147d522f475Smrg	    if (screen->terminal_id >= 100
3148d522f475Smrg		&& screen->vtXX_level == 0) {
3149d522f475Smrg		sp->groundtable =
3150d522f475Smrg		    sp->parsestate = ansi_table;
31510bd37d32Smrg		/*
31520bd37d32Smrg		 * On restore, the terminal does not recognize DECRQSS for
31530bd37d32Smrg		 * DECSCL (per vttest).
31540bd37d32Smrg		 */
31550bd37d32Smrg		screen->vtXX_level = 1;
3156d522f475Smrg		screen->curgl = screen->vt52_save_curgl;
3157d522f475Smrg		screen->curgr = screen->vt52_save_curgr;
3158d522f475Smrg		screen->curss = screen->vt52_save_curss;
3159d522f475Smrg		memmove(screen->gsets, screen->vt52_save_gsets, sizeof(screen->gsets));
3160d522f475Smrg	    }
3161d522f475Smrg	    break;
3162d522f475Smrg#endif
3163d522f475Smrg
3164d522f475Smrg	case CASE_ANSI_LEVEL_1:
3165d522f475Smrg	    TRACE(("CASE_ANSI_LEVEL_1\n"));
3166d522f475Smrg	    set_ansi_conformance(screen, 1);
316720d2c4d2Smrg	    ResetState(sp);
3168d522f475Smrg	    break;
3169d522f475Smrg
3170d522f475Smrg	case CASE_ANSI_LEVEL_2:
3171d522f475Smrg	    TRACE(("CASE_ANSI_LEVEL_2\n"));
3172d522f475Smrg	    set_ansi_conformance(screen, 2);
317320d2c4d2Smrg	    ResetState(sp);
3174d522f475Smrg	    break;
3175d522f475Smrg
3176d522f475Smrg	case CASE_ANSI_LEVEL_3:
3177d522f475Smrg	    TRACE(("CASE_ANSI_LEVEL_3\n"));
3178d522f475Smrg	    set_ansi_conformance(screen, 3);
317920d2c4d2Smrg	    ResetState(sp);
3180d522f475Smrg	    break;
3181d522f475Smrg
3182d522f475Smrg	case CASE_DECSCL:
31830bd37d32Smrg	    TRACE(("CASE_DECSCL(%d,%d)\n", GetParam(0), GetParam(1)));
31840bd37d32Smrg	    /*
31850bd37d32Smrg	     * This changes the emulation level, and is not recognized by
31860bd37d32Smrg	     * VT100s.
31870bd37d32Smrg	     */
31880bd37d32Smrg	    if (screen->terminal_id >= 200) {
3189d522f475Smrg		/*
31900bd37d32Smrg		 * Disallow unrecognized parameters, as well as attempts to set
31910bd37d32Smrg		 * the operating level higher than the given terminal-id.
3192d522f475Smrg		 */
31930bd37d32Smrg		if (GetParam(0) >= 61
31940bd37d32Smrg		    && GetParam(0) <= 60 + (screen->terminal_id / 100)) {
31950bd37d32Smrg		    /*
31960bd37d32Smrg		     * VT300, VT420, VT520 manuals claim that DECSCL does a
31970bd37d32Smrg		     * hard reset (RIS).  VT220 manual states that it is a soft
31980bd37d32Smrg		     * reset.  Perhaps both are right (unlikely).  Kermit says
31990bd37d32Smrg		     * it's soft.
32000bd37d32Smrg		     */
32010bd37d32Smrg		    ReallyReset(xw, False, False);
32020bd37d32Smrg		    init_parser(xw, sp);
32030bd37d32Smrg		    screen->vtXX_level = GetParam(0) - 60;
32040bd37d32Smrg		    if (GetParam(0) > 61) {
32050bd37d32Smrg			switch (zero_if_default(1)) {
32060bd37d32Smrg			case 1:
32070bd37d32Smrg			    show_8bit_control(False);
32080bd37d32Smrg			    break;
32090bd37d32Smrg			case 0:
32100bd37d32Smrg			case 2:
32110bd37d32Smrg			    show_8bit_control(True);
32120bd37d32Smrg			    break;
32130bd37d32Smrg			}
321420d2c4d2Smrg		    }
3215d522f475Smrg		}
3216d522f475Smrg	    }
321720d2c4d2Smrg	    ResetState(sp);
3218d522f475Smrg	    break;
3219d522f475Smrg
3220d522f475Smrg	case CASE_DECSCA:
3221d522f475Smrg	    TRACE(("CASE_DECSCA\n"));
3222d522f475Smrg	    screen->protected_mode = DEC_PROTECT;
32230bd37d32Smrg	    if (GetParam(0) <= 0 || GetParam(0) == 2) {
322420d2c4d2Smrg		UIntClr(xw->flags, PROTECTED);
32250bd37d32Smrg		TRACE(("...clear PROTECTED\n"));
32260bd37d32Smrg	    } else if (GetParam(0) == 1) {
3227d522f475Smrg		xw->flags |= PROTECTED;
32280bd37d32Smrg		TRACE(("...set PROTECTED\n"));
32290bd37d32Smrg	    }
323020d2c4d2Smrg	    ResetState(sp);
3231d522f475Smrg	    break;
3232d522f475Smrg
3233d522f475Smrg	case CASE_DECSED:
3234d522f475Smrg	    TRACE(("CASE_DECSED\n"));
32350bd37d32Smrg	    do_erase_display(xw, zero_if_default(0), DEC_PROTECT);
323620d2c4d2Smrg	    ResetState(sp);
3237d522f475Smrg	    break;
3238d522f475Smrg
3239d522f475Smrg	case CASE_DECSEL:
3240d522f475Smrg	    TRACE(("CASE_DECSEL\n"));
32410bd37d32Smrg	    do_erase_line(xw, zero_if_default(0), DEC_PROTECT);
324220d2c4d2Smrg	    ResetState(sp);
3243d522f475Smrg	    break;
3244d522f475Smrg
3245d522f475Smrg	case CASE_ST:
324620d2c4d2Smrg	    TRACE(("CASE_ST: End of String (%lu bytes)\n", (unsigned long) sp->string_used));
324720d2c4d2Smrg	    ResetState(sp);
3248956cc18dSsnj	    if (!sp->string_used)
3249d522f475Smrg		break;
3250956cc18dSsnj	    sp->string_area[--(sp->string_used)] = '\0';
3251d522f475Smrg	    switch (sp->string_mode) {
3252d522f475Smrg	    case ANSI_APC:
3253d522f475Smrg		/* ignored */
3254d522f475Smrg		break;
3255d522f475Smrg	    case ANSI_DCS:
3256956cc18dSsnj		do_dcs(xw, sp->string_area, sp->string_used);
3257d522f475Smrg		break;
3258d522f475Smrg	    case ANSI_OSC:
3259956cc18dSsnj		do_osc(xw, sp->string_area, sp->string_used, ANSI_ST);
3260d522f475Smrg		break;
3261d522f475Smrg	    case ANSI_PM:
3262d522f475Smrg		/* ignored */
3263d522f475Smrg		break;
3264d522f475Smrg	    case ANSI_SOS:
3265d522f475Smrg		/* ignored */
3266d522f475Smrg		break;
3267d522f475Smrg	    }
3268d522f475Smrg	    break;
3269d522f475Smrg
3270d522f475Smrg	case CASE_SOS:
3271d522f475Smrg	    TRACE(("CASE_SOS: Start of String\n"));
327220d2c4d2Smrg	    if (ParseSOS(screen)) {
327320d2c4d2Smrg		sp->string_mode = ANSI_SOS;
327420d2c4d2Smrg		sp->parsestate = sos_table;
327520d2c4d2Smrg	    } else {
327620d2c4d2Smrg		illegal_parse(xw, c, sp);
327720d2c4d2Smrg	    }
3278d522f475Smrg	    break;
3279d522f475Smrg
3280d522f475Smrg	case CASE_PM:
3281d522f475Smrg	    TRACE(("CASE_PM: Privacy Message\n"));
328220d2c4d2Smrg	    if (ParseSOS(screen)) {
328320d2c4d2Smrg		sp->string_mode = ANSI_PM;
328420d2c4d2Smrg		sp->parsestate = sos_table;
328520d2c4d2Smrg	    } else {
328620d2c4d2Smrg		illegal_parse(xw, c, sp);
328720d2c4d2Smrg	    }
3288d522f475Smrg	    break;
3289d522f475Smrg
3290d522f475Smrg	case CASE_DCS:
3291d522f475Smrg	    TRACE(("CASE_DCS: Device Control String\n"));
3292d522f475Smrg	    sp->string_mode = ANSI_DCS;
3293d522f475Smrg	    sp->parsestate = sos_table;
3294d522f475Smrg	    break;
3295d522f475Smrg
3296d522f475Smrg	case CASE_APC:
3297d522f475Smrg	    TRACE(("CASE_APC: Application Program Command\n"));
329820d2c4d2Smrg	    if (ParseSOS(screen)) {
329920d2c4d2Smrg		sp->string_mode = ANSI_APC;
330020d2c4d2Smrg		sp->parsestate = sos_table;
330120d2c4d2Smrg	    } else {
330220d2c4d2Smrg		illegal_parse(xw, c, sp);
330320d2c4d2Smrg	    }
3304d522f475Smrg	    break;
3305d522f475Smrg
3306d522f475Smrg	case CASE_SPA:
3307d522f475Smrg	    TRACE(("CASE_SPA - start protected area\n"));
3308d522f475Smrg	    screen->protected_mode = ISO_PROTECT;
3309d522f475Smrg	    xw->flags |= PROTECTED;
331020d2c4d2Smrg	    ResetState(sp);
3311d522f475Smrg	    break;
3312d522f475Smrg
3313d522f475Smrg	case CASE_EPA:
3314d522f475Smrg	    TRACE(("CASE_EPA - end protected area\n"));
331520d2c4d2Smrg	    UIntClr(xw->flags, PROTECTED);
331620d2c4d2Smrg	    ResetState(sp);
3317d522f475Smrg	    break;
3318d522f475Smrg
3319d522f475Smrg	case CASE_SU:
3320d522f475Smrg	    TRACE(("CASE_SU - scroll up\n"));
33210bd37d32Smrg	    xtermScroll(xw, one_if_default(0));
33220bd37d32Smrg	    ResetState(sp);
33230bd37d32Smrg	    break;
33240bd37d32Smrg
33250bd37d32Smrg	case CASE_SL:		/* ISO 6429, non-DEC */
33260bd37d32Smrg	    TRACE(("CASE_SL - scroll left\n"));
33270bd37d32Smrg	    xtermScrollLR(xw, one_if_default(0), True);
33280bd37d32Smrg	    ResetState(sp);
33290bd37d32Smrg	    break;
33300bd37d32Smrg
33310bd37d32Smrg	case CASE_SR:		/* ISO 6429, non-DEC */
33320bd37d32Smrg	    TRACE(("CASE_SR - scroll right\n"));
33330bd37d32Smrg	    xtermScrollLR(xw, one_if_default(0), False);
33340bd37d32Smrg	    ResetState(sp);
33350bd37d32Smrg	    break;
33360bd37d32Smrg
33370bd37d32Smrg	case CASE_DECDC:
33380bd37d32Smrg	    TRACE(("CASE_DC - delete column\n"));
33390bd37d32Smrg	    if (screen->vtXX_level >= 4
33400bd37d32Smrg		&& IsLeftRightMode(xw)) {
33410bd37d32Smrg		xtermColScroll(xw, one_if_default(0), True, screen->cur_col);
33420bd37d32Smrg	    }
33430bd37d32Smrg	    ResetState(sp);
33440bd37d32Smrg	    break;
33450bd37d32Smrg
33460bd37d32Smrg	case CASE_DECIC:
33470bd37d32Smrg	    TRACE(("CASE_IC - insert column\n"));
33480bd37d32Smrg	    if (screen->vtXX_level >= 4
33490bd37d32Smrg		&& IsLeftRightMode(xw)) {
33500bd37d32Smrg		xtermColScroll(xw, one_if_default(0), False, screen->cur_col);
33510bd37d32Smrg	    }
33520bd37d32Smrg	    ResetState(sp);
33530bd37d32Smrg	    break;
33540bd37d32Smrg
33550bd37d32Smrg	case CASE_DECBI:
33560bd37d32Smrg	    TRACE(("CASE_BI - back index\n"));
33570bd37d32Smrg	    if (screen->vtXX_level >= 4) {
33580bd37d32Smrg		xtermColIndex(xw, True);
33590bd37d32Smrg	    }
33600bd37d32Smrg	    ResetState(sp);
33610bd37d32Smrg	    break;
33620bd37d32Smrg
33630bd37d32Smrg	case CASE_DECFI:
33640bd37d32Smrg	    TRACE(("CASE_FI - forward index\n"));
33650bd37d32Smrg	    if (screen->vtXX_level >= 4) {
33660bd37d32Smrg		xtermColIndex(xw, False);
33670bd37d32Smrg	    }
336820d2c4d2Smrg	    ResetState(sp);
3369d522f475Smrg	    break;
3370d522f475Smrg
3371d522f475Smrg	case CASE_IND:
3372d522f475Smrg	    TRACE(("CASE_IND - index\n"));
3373d522f475Smrg	    xtermIndex(xw, 1);
3374d522f475Smrg	    do_xevents();
337520d2c4d2Smrg	    ResetState(sp);
3376d522f475Smrg	    break;
3377d522f475Smrg
3378d522f475Smrg	case CASE_CPL:
3379d522f475Smrg	    TRACE(("CASE_CPL - cursor prev line\n"));
33800bd37d32Smrg	    CursorPrevLine(xw, one_if_default(0));
338120d2c4d2Smrg	    ResetState(sp);
3382d522f475Smrg	    break;
3383d522f475Smrg
3384d522f475Smrg	case CASE_CNL:
3385d522f475Smrg	    TRACE(("CASE_CNL - cursor next line\n"));
33860bd37d32Smrg	    CursorNextLine(xw, one_if_default(0));
338720d2c4d2Smrg	    ResetState(sp);
3388d522f475Smrg	    break;
3389d522f475Smrg
3390d522f475Smrg	case CASE_NEL:
3391d522f475Smrg	    TRACE(("CASE_NEL\n"));
3392d522f475Smrg	    xtermIndex(xw, 1);
33930bd37d32Smrg	    CarriageReturn(xw);
339420d2c4d2Smrg	    ResetState(sp);
3395d522f475Smrg	    break;
3396d522f475Smrg
3397d522f475Smrg	case CASE_HTS:
3398d522f475Smrg	    TRACE(("CASE_HTS - horizontal tab set\n"));
3399d522f475Smrg	    TabSet(xw->tabs, screen->cur_col);
340020d2c4d2Smrg	    ResetState(sp);
3401d522f475Smrg	    break;
3402d522f475Smrg
3403d522f475Smrg	case CASE_RI:
3404d522f475Smrg	    TRACE(("CASE_RI - reverse index\n"));
3405d522f475Smrg	    RevIndex(xw, 1);
340620d2c4d2Smrg	    ResetState(sp);
3407d522f475Smrg	    break;
3408d522f475Smrg
3409d522f475Smrg	case CASE_SS2:
3410d522f475Smrg	    TRACE(("CASE_SS2\n"));
3411d522f475Smrg	    screen->curss = 2;
341220d2c4d2Smrg	    ResetState(sp);
3413d522f475Smrg	    break;
3414d522f475Smrg
3415d522f475Smrg	case CASE_SS3:
3416d522f475Smrg	    TRACE(("CASE_SS3\n"));
3417d522f475Smrg	    screen->curss = 3;
341820d2c4d2Smrg	    ResetState(sp);
3419d522f475Smrg	    break;
3420d522f475Smrg
3421d522f475Smrg	case CASE_CSI_STATE:
3422d522f475Smrg	    /* enter csi state */
34230bd37d32Smrg	    InitParams();
34240bd37d32Smrg	    SetParam(nparam++, DEFAULT);
3425d522f475Smrg	    sp->parsestate = csi_table;
3426d522f475Smrg	    break;
3427d522f475Smrg
3428d522f475Smrg	case CASE_ESC_SP_STATE:
3429d522f475Smrg	    /* esc space */
3430d522f475Smrg	    sp->parsestate = esc_sp_table;
3431d522f475Smrg	    break;
3432d522f475Smrg
3433d522f475Smrg	case CASE_CSI_EX_STATE:
3434d522f475Smrg	    /* csi exclamation */
3435d522f475Smrg	    sp->parsestate = csi_ex_table;
3436d522f475Smrg	    break;
3437d522f475Smrg
3438d522f475Smrg#if OPT_DEC_LOCATOR
3439d522f475Smrg	case CASE_CSI_TICK_STATE:
3440d522f475Smrg	    /* csi tick (') */
3441d522f475Smrg	    sp->parsestate = csi_tick_table;
3442d522f475Smrg	    break;
3443d522f475Smrg
3444d522f475Smrg	case CASE_DECEFR:
3445d522f475Smrg	    TRACE(("CASE_DECEFR - Enable Filter Rectangle\n"));
3446d522f475Smrg	    if (screen->send_mouse_pos == DEC_LOCATOR) {
3447d522f475Smrg		MotionOff(screen, xw);
34480bd37d32Smrg		if ((screen->loc_filter_top = GetParam(0)) < 1)
3449d522f475Smrg		    screen->loc_filter_top = LOC_FILTER_POS;
34500bd37d32Smrg		if (nparam < 2
34510bd37d32Smrg		    || (screen->loc_filter_left = GetParam(1)) < 1)
3452d522f475Smrg		    screen->loc_filter_left = LOC_FILTER_POS;
34530bd37d32Smrg		if (nparam < 3
34540bd37d32Smrg		    || (screen->loc_filter_bottom = GetParam(2)) < 1)
3455d522f475Smrg		    screen->loc_filter_bottom = LOC_FILTER_POS;
34560bd37d32Smrg		if (nparam < 4
34570bd37d32Smrg		    || (screen->loc_filter_right = GetParam(3)) < 1)
3458d522f475Smrg		    screen->loc_filter_right = LOC_FILTER_POS;
3459d522f475Smrg		InitLocatorFilter(xw);
3460d522f475Smrg	    }
346120d2c4d2Smrg	    ResetState(sp);
3462d522f475Smrg	    break;
3463d522f475Smrg
3464d522f475Smrg	case CASE_DECELR:
3465d522f475Smrg	    MotionOff(screen, xw);
34660bd37d32Smrg	    if (GetParam(0) <= 0 || GetParam(0) > 2) {
3467d522f475Smrg		screen->send_mouse_pos = MOUSE_OFF;
3468d522f475Smrg		TRACE(("DECELR - Disable Locator Reports\n"));
3469d522f475Smrg	    } else {
3470d522f475Smrg		TRACE(("DECELR - Enable Locator Reports\n"));
3471d522f475Smrg		screen->send_mouse_pos = DEC_LOCATOR;
3472d522f475Smrg		xtermShowPointer(xw, True);
34730bd37d32Smrg		if (GetParam(0) == 2) {
3474d522f475Smrg		    screen->locator_reset = True;
3475d522f475Smrg		} else {
3476d522f475Smrg		    screen->locator_reset = False;
3477d522f475Smrg		}
34780bd37d32Smrg		if (nparam < 2 || GetParam(1) != 1) {
3479d522f475Smrg		    screen->locator_pixels = False;
3480d522f475Smrg		} else {
3481d522f475Smrg		    screen->locator_pixels = True;
3482d522f475Smrg		}
3483d522f475Smrg		screen->loc_filter = False;
3484d522f475Smrg	    }
348520d2c4d2Smrg	    ResetState(sp);
3486d522f475Smrg	    break;
3487d522f475Smrg
3488d522f475Smrg	case CASE_DECSLE:
3489d522f475Smrg	    TRACE(("DECSLE - Select Locator Events\n"));
3490d522f475Smrg	    for (count = 0; count < nparam; ++count) {
34910bd37d32Smrg		switch (zero_if_default(count)) {
3492d522f475Smrg		case 0:
3493d522f475Smrg		    MotionOff(screen, xw);
3494d522f475Smrg		    screen->loc_filter = False;
3495d522f475Smrg		    screen->locator_events = 0;
3496d522f475Smrg		    break;
3497d522f475Smrg		case 1:
3498d522f475Smrg		    screen->locator_events |= LOC_BTNS_DN;
3499d522f475Smrg		    break;
3500d522f475Smrg		case 2:
350120d2c4d2Smrg		    UIntClr(screen->locator_events, LOC_BTNS_DN);
3502d522f475Smrg		    break;
3503d522f475Smrg		case 3:
3504d522f475Smrg		    screen->locator_events |= LOC_BTNS_UP;
3505d522f475Smrg		    break;
3506d522f475Smrg		case 4:
350720d2c4d2Smrg		    UIntClr(screen->locator_events, LOC_BTNS_UP);
3508d522f475Smrg		    break;
3509d522f475Smrg		}
3510d522f475Smrg	    }
351120d2c4d2Smrg	    ResetState(sp);
3512d522f475Smrg	    break;
3513d522f475Smrg
3514d522f475Smrg	case CASE_DECRQLP:
3515d522f475Smrg	    TRACE(("DECRQLP - Request Locator Position\n"));
35160bd37d32Smrg	    if (GetParam(0) < 2) {
3517d522f475Smrg		/* Issue DECLRP Locator Position Report */
3518d522f475Smrg		GetLocatorPosition(xw);
3519d522f475Smrg	    }
352020d2c4d2Smrg	    ResetState(sp);
3521d522f475Smrg	    break;
3522d522f475Smrg#endif /* OPT_DEC_LOCATOR */
3523d522f475Smrg
3524d522f475Smrg#if OPT_DEC_RECTOPS
3525d522f475Smrg	case CASE_CSI_DOLLAR_STATE:
3526492d43a5Smrg	    TRACE(("CASE_CSI_DOLLAR_STATE\n"));
3527d522f475Smrg	    /* csi dollar ($) */
3528492d43a5Smrg	    if (screen->vtXX_level >= 3)
3529d522f475Smrg		sp->parsestate = csi_dollar_table;
3530d522f475Smrg	    else
3531d522f475Smrg		sp->parsestate = eigtable;
3532d522f475Smrg	    break;
3533d522f475Smrg
3534d522f475Smrg	case CASE_CSI_STAR_STATE:
3535492d43a5Smrg	    TRACE(("CASE_CSI_STAR_STATE\n"));
3536492d43a5Smrg	    /* csi star (*) */
3537d522f475Smrg	    if (screen->vtXX_level >= 4)
3538d522f475Smrg		sp->parsestate = csi_star_table;
3539d522f475Smrg	    else
3540d522f475Smrg		sp->parsestate = eigtable;
3541d522f475Smrg	    break;
3542d522f475Smrg
35430bd37d32Smrg	case CASE_DECRQCRA:
35440bd37d32Smrg	    if (screen->vtXX_level >= 4) {
35450bd37d32Smrg		int checksum;
35460bd37d32Smrg
35470bd37d32Smrg		TRACE(("CASE_DECRQCRA - Request checksum of rectangular area\n"));
35480bd37d32Smrg		xtermCheckRect(xw, ParamPair(0), &checksum);
35490bd37d32Smrg		init_reply(ANSI_DCS);
35500bd37d32Smrg		count = 0;
35510bd37d32Smrg		reply.a_param[count++] = (ParmType) GetParam(1);	/* PID */
35520bd37d32Smrg		reply.a_delim = "!~";	/* delimiter */
35530bd37d32Smrg		reply.a_radix[count] = 16;
35540bd37d32Smrg		reply.a_param[count++] = (ParmType) checksum;
35550bd37d32Smrg		reply.a_nparam = (ParmType) count;
35560bd37d32Smrg		unparseseq(xw, &reply);
35570bd37d32Smrg	    }
35580bd37d32Smrg	    ResetState(sp);
35590bd37d32Smrg	    break;
35600bd37d32Smrg
3561d522f475Smrg	case CASE_DECCRA:
3562492d43a5Smrg	    if (screen->vtXX_level >= 4) {
3563492d43a5Smrg		TRACE(("CASE_DECCRA - Copy rectangular area\n"));
35640bd37d32Smrg		xtermParseRect(xw, ParamPair(0), &myRect);
35650bd37d32Smrg		ScrnCopyRectangle(xw, &myRect, ParamPair(5));
3566492d43a5Smrg	    }
356720d2c4d2Smrg	    ResetState(sp);
3568d522f475Smrg	    break;
3569d522f475Smrg
3570d522f475Smrg	case CASE_DECERA:
3571492d43a5Smrg	    if (screen->vtXX_level >= 4) {
3572492d43a5Smrg		TRACE(("CASE_DECERA - Erase rectangular area\n"));
35730bd37d32Smrg		xtermParseRect(xw, ParamPair(0), &myRect);
3574492d43a5Smrg		ScrnFillRectangle(xw, &myRect, ' ', 0, True);
3575492d43a5Smrg	    }
357620d2c4d2Smrg	    ResetState(sp);
3577d522f475Smrg	    break;
3578d522f475Smrg
3579d522f475Smrg	case CASE_DECFRA:
3580492d43a5Smrg	    if (screen->vtXX_level >= 4) {
35810bd37d32Smrg		value = zero_if_default(0);
35820bd37d32Smrg
3583492d43a5Smrg		TRACE(("CASE_DECFRA - Fill rectangular area\n"));
3584492d43a5Smrg		if (nparam > 0
35850bd37d32Smrg		    && ((value >= 32 && value <= 126)
35860bd37d32Smrg			|| (value >= 160 && value <= 255))) {
35870bd37d32Smrg		    xtermParseRect(xw, ParamPair(1), &myRect);
35880bd37d32Smrg		    ScrnFillRectangle(xw, &myRect, value, xw->flags, True);
3589492d43a5Smrg		}
3590d522f475Smrg	    }
359120d2c4d2Smrg	    ResetState(sp);
3592d522f475Smrg	    break;
3593d522f475Smrg
3594d522f475Smrg	case CASE_DECSERA:
3595492d43a5Smrg	    if (screen->vtXX_level >= 4) {
3596492d43a5Smrg		TRACE(("CASE_DECSERA - Selective erase rectangular area\n"));
35970bd37d32Smrg		xtermParseRect(xw, ParamPair(0), &myRect);
3598492d43a5Smrg		ScrnWipeRectangle(xw, &myRect);
3599492d43a5Smrg	    }
360020d2c4d2Smrg	    ResetState(sp);
3601d522f475Smrg	    break;
3602d522f475Smrg
3603d522f475Smrg	case CASE_DECSACE:
3604d522f475Smrg	    TRACE(("CASE_DECSACE - Select attribute change extent\n"));
36050bd37d32Smrg	    screen->cur_decsace = zero_if_default(0);
360620d2c4d2Smrg	    ResetState(sp);
3607d522f475Smrg	    break;
3608d522f475Smrg
3609d522f475Smrg	case CASE_DECCARA:
3610492d43a5Smrg	    if (screen->vtXX_level >= 4) {
3611492d43a5Smrg		TRACE(("CASE_DECCARA - Change attributes in rectangular area\n"));
36120bd37d32Smrg		xtermParseRect(xw, ParamPair(0), &myRect);
36130bd37d32Smrg		ScrnMarkRectangle(xw, &myRect, False, ParamPair(4));
3614492d43a5Smrg	    }
361520d2c4d2Smrg	    ResetState(sp);
3616d522f475Smrg	    break;
3617d522f475Smrg
3618d522f475Smrg	case CASE_DECRARA:
3619492d43a5Smrg	    if (screen->vtXX_level >= 4) {
3620492d43a5Smrg		TRACE(("CASE_DECRARA - Reverse attributes in rectangular area\n"));
36210bd37d32Smrg		xtermParseRect(xw, ParamPair(0), &myRect);
36220bd37d32Smrg		ScrnMarkRectangle(xw, &myRect, True, ParamPair(4));
3623492d43a5Smrg	    }
3624492d43a5Smrg	    ResetState(sp);
3625492d43a5Smrg	    break;
3626492d43a5Smrg
3627492d43a5Smrg	case CASE_RQM:
3628492d43a5Smrg	    TRACE(("CASE_RQM\n"));
36290bd37d32Smrg	    do_rpm(xw, ParamPair(0));
3630492d43a5Smrg	    ResetState(sp);
3631492d43a5Smrg	    break;
3632492d43a5Smrg
3633492d43a5Smrg	case CASE_DECRQM:
3634492d43a5Smrg	    TRACE(("CASE_DECRQM\n"));
36350bd37d32Smrg	    do_decrpm(xw, ParamPair(0));
363620d2c4d2Smrg	    ResetState(sp);
3637d522f475Smrg	    break;
3638492d43a5Smrg
3639492d43a5Smrg	case CASE_CSI_DEC_DOLLAR_STATE:
3640492d43a5Smrg	    TRACE(("CASE_CSI_DEC_DOLLAR_STATE\n"));
3641492d43a5Smrg	    /* csi ? dollar ($) */
3642492d43a5Smrg	    sp->parsestate = csi_dec_dollar_table;
3643492d43a5Smrg	    break;
3644d522f475Smrg#else
3645d522f475Smrg	case CASE_CSI_DOLLAR_STATE:
3646d522f475Smrg	    /* csi dollar ($) */
3647d522f475Smrg	    sp->parsestate = eigtable;
3648d522f475Smrg	    break;
3649d522f475Smrg
3650d522f475Smrg	case CASE_CSI_STAR_STATE:
3651d522f475Smrg	    /* csi dollar (*) */
3652d522f475Smrg	    sp->parsestate = eigtable;
3653d522f475Smrg	    break;
3654492d43a5Smrg
3655492d43a5Smrg	case CASE_CSI_DEC_DOLLAR_STATE:
3656492d43a5Smrg	    /* csi ? dollar ($) */
3657492d43a5Smrg	    sp->parsestate = eigtable;
3658492d43a5Smrg	    break;
3659d522f475Smrg#endif /* OPT_DEC_RECTOPS */
3660d522f475Smrg
3661d522f475Smrg	case CASE_S7C1T:
3662d522f475Smrg	    TRACE(("CASE_S7C1T\n"));
36630bd37d32Smrg	    if (screen->vtXX_level >= 2) {
36640bd37d32Smrg		show_8bit_control(False);
36650bd37d32Smrg		ResetState(sp);
36660bd37d32Smrg	    }
3667d522f475Smrg	    break;
3668d522f475Smrg
3669d522f475Smrg	case CASE_S8C1T:
3670d522f475Smrg	    TRACE(("CASE_S8C1T\n"));
36710bd37d32Smrg	    if (screen->vtXX_level >= 2) {
3672d522f475Smrg#if OPT_VT52_MODE
36730bd37d32Smrg		if (screen->vtXX_level <= 1)
36740bd37d32Smrg		    break;
3675d522f475Smrg#endif
36760bd37d32Smrg		show_8bit_control(True);
36770bd37d32Smrg		ResetState(sp);
36780bd37d32Smrg	    }
3679d522f475Smrg	    break;
3680d522f475Smrg
3681d522f475Smrg	case CASE_OSC:
3682d522f475Smrg	    TRACE(("CASE_OSC: Operating System Command\n"));
3683d522f475Smrg	    sp->parsestate = sos_table;
3684d522f475Smrg	    sp->string_mode = ANSI_OSC;
3685d522f475Smrg	    break;
3686d522f475Smrg
3687d522f475Smrg	case CASE_RIS:
3688d522f475Smrg	    TRACE(("CASE_RIS\n"));
3689d522f475Smrg	    VTReset(xw, True, True);
369020d2c4d2Smrg	    ResetState(sp);
3691d522f475Smrg	    break;
3692d522f475Smrg
3693d522f475Smrg	case CASE_DECSTR:
3694d522f475Smrg	    TRACE(("CASE_DECSTR\n"));
3695d522f475Smrg	    VTReset(xw, False, False);
369620d2c4d2Smrg	    ResetState(sp);
3697d522f475Smrg	    break;
3698d522f475Smrg
3699d522f475Smrg	case CASE_REP:
3700d522f475Smrg	    TRACE(("CASE_REP\n"));
3701d522f475Smrg	    if (sp->lastchar >= 0 &&
3702d522f475Smrg		sp->lastchar < 256 &&
3703d522f475Smrg		sp->groundtable[E2A(sp->lastchar)] == CASE_PRINT) {
3704d522f475Smrg		IChar repeated[2];
37050bd37d32Smrg		count = one_if_default(0);
37062eaa94a1Schristos		repeated[0] = (IChar) sp->lastchar;
3707d522f475Smrg		while (count-- > 0) {
3708d522f475Smrg		    dotext(xw,
3709d522f475Smrg			   screen->gsets[(int) (screen->curgl)],
3710d522f475Smrg			   repeated, 1);
3711d522f475Smrg		}
3712d522f475Smrg	    }
371320d2c4d2Smrg	    ResetState(sp);
3714d522f475Smrg	    break;
3715d522f475Smrg
3716d522f475Smrg	case CASE_LS2:
3717d522f475Smrg	    TRACE(("CASE_LS2\n"));
3718d522f475Smrg	    screen->curgl = 2;
371920d2c4d2Smrg	    ResetState(sp);
3720d522f475Smrg	    break;
3721d522f475Smrg
3722d522f475Smrg	case CASE_LS3:
3723d522f475Smrg	    TRACE(("CASE_LS3\n"));
3724d522f475Smrg	    screen->curgl = 3;
372520d2c4d2Smrg	    ResetState(sp);
3726d522f475Smrg	    break;
3727d522f475Smrg
3728d522f475Smrg	case CASE_LS3R:
3729d522f475Smrg	    TRACE(("CASE_LS3R\n"));
3730d522f475Smrg	    screen->curgr = 3;
373120d2c4d2Smrg	    ResetState(sp);
3732d522f475Smrg	    break;
3733d522f475Smrg
3734d522f475Smrg	case CASE_LS2R:
3735d522f475Smrg	    TRACE(("CASE_LS2R\n"));
3736d522f475Smrg	    screen->curgr = 2;
373720d2c4d2Smrg	    ResetState(sp);
3738d522f475Smrg	    break;
3739d522f475Smrg
3740d522f475Smrg	case CASE_LS1R:
3741d522f475Smrg	    TRACE(("CASE_LS1R\n"));
3742d522f475Smrg	    screen->curgr = 1;
374320d2c4d2Smrg	    ResetState(sp);
3744d522f475Smrg	    break;
3745d522f475Smrg
3746d522f475Smrg	case CASE_XTERM_SAVE:
3747d522f475Smrg	    savemodes(xw);
374820d2c4d2Smrg	    ResetState(sp);
3749d522f475Smrg	    break;
3750d522f475Smrg
3751d522f475Smrg	case CASE_XTERM_RESTORE:
3752d522f475Smrg	    restoremodes(xw);
375320d2c4d2Smrg	    ResetState(sp);
3754d522f475Smrg	    break;
3755d522f475Smrg
3756d522f475Smrg	case CASE_XTERM_WINOPS:
3757d522f475Smrg	    TRACE(("CASE_XTERM_WINOPS\n"));
375820d2c4d2Smrg	    window_ops(xw);
375920d2c4d2Smrg	    ResetState(sp);
3760d522f475Smrg	    break;
3761d522f475Smrg#if OPT_WIDE_CHARS
3762d522f475Smrg	case CASE_ESC_PERCENT:
3763d522f475Smrg	    sp->parsestate = esc_pct_table;
3764d522f475Smrg	    break;
3765d522f475Smrg
3766d522f475Smrg	case CASE_UTF8:
3767d522f475Smrg	    /* If we did not set UTF-8 mode from resource or the
3768d522f475Smrg	     * command-line, allow it to be enabled/disabled by
3769d522f475Smrg	     * control sequence.
3770d522f475Smrg	     */
3771d522f475Smrg	    if (screen->wide_chars
3772d522f475Smrg		&& screen->utf8_mode != uAlways) {
377320d2c4d2Smrg		if (!screen->wide_chars) {
377420d2c4d2Smrg		    WriteNow();
377520d2c4d2Smrg		    ChangeToWide(xw);
377620d2c4d2Smrg		}
3777d522f475Smrg		switchPtyData(screen, c == 'G');
3778d522f475Smrg		TRACE(("UTF8 mode %s\n",
3779d522f475Smrg		       BtoS(screen->utf8_mode)));
3780d522f475Smrg	    } else {
3781d522f475Smrg		TRACE(("UTF8 mode NOT turned %s (%s)\n",
3782d522f475Smrg		       BtoS(c == 'G'),
3783d522f475Smrg		       (screen->utf8_mode == uAlways)
3784d522f475Smrg		       ? "UTF-8 mode set from command-line"
3785d522f475Smrg		       : "wideChars resource was not set"));
3786d522f475Smrg	    }
378720d2c4d2Smrg	    ResetState(sp);
3788d522f475Smrg	    break;
3789d522f475Smrg#endif
3790d522f475Smrg#if OPT_MOD_FKEYS
3791d522f475Smrg	case CASE_SET_MOD_FKEYS:
3792d522f475Smrg	    TRACE(("CASE_SET_MOD_FKEYS\n"));
3793d522f475Smrg	    if (nparam >= 1) {
37940bd37d32Smrg		set_mod_fkeys(xw,
37950bd37d32Smrg			      GetParam(0),
37960bd37d32Smrg			      ((nparam > 1)
37970bd37d32Smrg			       ? GetParam(1)
37980bd37d32Smrg			       : DEFAULT),
37990bd37d32Smrg			      True);
3800d522f475Smrg	    } else {
38010bd37d32Smrg		for (value = 1; value <= 5; ++value)
38020bd37d32Smrg		    set_mod_fkeys(xw, value, DEFAULT, True);
3803d522f475Smrg	    }
3804d522f475Smrg	    break;
3805d522f475Smrg	case CASE_SET_MOD_FKEYS0:
3806d522f475Smrg	    TRACE(("CASE_SET_MOD_FKEYS0\n"));
38070bd37d32Smrg	    if (nparam >= 1 && GetParam(0) != DEFAULT) {
38080bd37d32Smrg		set_mod_fkeys(xw, GetParam(0), -1, False);
3809d522f475Smrg	    } else {
3810d522f475Smrg		xw->keyboard.modify_now.function_keys = -1;
3811d522f475Smrg	    }
3812d522f475Smrg	    break;
3813d522f475Smrg#endif
3814d522f475Smrg	case CASE_HIDE_POINTER:
3815d522f475Smrg	    TRACE(("CASE_HIDE_POINTER\n"));
38160bd37d32Smrg	    if (nparam >= 1 && GetParam(0) != DEFAULT) {
38170bd37d32Smrg		screen->pointer_mode = GetParam(0);
3818d522f475Smrg	    } else {
3819d522f475Smrg		screen->pointer_mode = DEF_POINTER_MODE;
3820d522f475Smrg	    }
3821d522f475Smrg	    break;
3822d522f475Smrg
382320d2c4d2Smrg	case CASE_SM_TITLE:
382420d2c4d2Smrg	    TRACE(("CASE_SM_TITLE\n"));
382520d2c4d2Smrg	    if (nparam >= 1) {
382620d2c4d2Smrg		int n;
382720d2c4d2Smrg		for (n = 0; n < nparam; ++n) {
38280bd37d32Smrg		    if (GetParam(n) != DEFAULT)
38290bd37d32Smrg			screen->title_modes |= (1 << GetParam(n));
383020d2c4d2Smrg		}
383120d2c4d2Smrg	    } else {
383220d2c4d2Smrg		screen->title_modes = DEF_TITLE_MODES;
383320d2c4d2Smrg	    }
383420d2c4d2Smrg	    TRACE(("...title_modes %#x\n", screen->title_modes));
383520d2c4d2Smrg	    break;
383620d2c4d2Smrg
383720d2c4d2Smrg	case CASE_RM_TITLE:
383820d2c4d2Smrg	    TRACE(("CASE_RM_TITLE\n"));
383920d2c4d2Smrg	    if (nparam >= 1) {
384020d2c4d2Smrg		int n;
384120d2c4d2Smrg		for (n = 0; n < nparam; ++n) {
38420bd37d32Smrg		    if (GetParam(n) != DEFAULT)
38430bd37d32Smrg			screen->title_modes &= ~(1 << GetParam(n));
384420d2c4d2Smrg		}
384520d2c4d2Smrg	    } else {
384620d2c4d2Smrg		screen->title_modes = DEF_TITLE_MODES;
384720d2c4d2Smrg	    }
384820d2c4d2Smrg	    TRACE(("...title_modes %#x\n", screen->title_modes));
384920d2c4d2Smrg	    break;
385020d2c4d2Smrg
3851d522f475Smrg	case CASE_CSI_IGNORE:
3852d522f475Smrg	    sp->parsestate = cigtable;
3853d522f475Smrg	    break;
385420d2c4d2Smrg
385520d2c4d2Smrg	case CASE_DECSWBV:
385620d2c4d2Smrg	    TRACE(("CASE_DECSWBV\n"));
38570bd37d32Smrg	    switch (zero_if_default(0)) {
385820d2c4d2Smrg	    case 2:
385920d2c4d2Smrg	    case 3:
386020d2c4d2Smrg	    case 4:
386120d2c4d2Smrg		screen->warningVolume = bvLow;
386220d2c4d2Smrg		break;
386320d2c4d2Smrg	    case 5:
386420d2c4d2Smrg	    case 6:
386520d2c4d2Smrg	    case 7:
386620d2c4d2Smrg	    case 8:
386720d2c4d2Smrg		screen->warningVolume = bvHigh;
386820d2c4d2Smrg		break;
386920d2c4d2Smrg	    default:
387020d2c4d2Smrg		screen->warningVolume = bvOff;
387120d2c4d2Smrg		break;
387220d2c4d2Smrg	    }
387320d2c4d2Smrg	    TRACE(("...warningVolume %d\n", screen->warningVolume));
387420d2c4d2Smrg	    ResetState(sp);
387520d2c4d2Smrg	    break;
387620d2c4d2Smrg
387720d2c4d2Smrg	case CASE_DECSMBV:
387820d2c4d2Smrg	    TRACE(("CASE_DECSMBV\n"));
38790bd37d32Smrg	    switch (zero_if_default(0)) {
388020d2c4d2Smrg	    case 2:
388120d2c4d2Smrg	    case 3:
388220d2c4d2Smrg	    case 4:
388320d2c4d2Smrg		screen->marginVolume = bvLow;
388420d2c4d2Smrg		break;
388520d2c4d2Smrg	    case 0:
388620d2c4d2Smrg	    case 5:
388720d2c4d2Smrg	    case 6:
388820d2c4d2Smrg	    case 7:
388920d2c4d2Smrg	    case 8:
389020d2c4d2Smrg		screen->marginVolume = bvHigh;
389120d2c4d2Smrg		break;
389220d2c4d2Smrg	    default:
389320d2c4d2Smrg		screen->marginVolume = bvOff;
389420d2c4d2Smrg		break;
389520d2c4d2Smrg	    }
389620d2c4d2Smrg	    TRACE(("...marginVolume %d\n", screen->marginVolume));
389720d2c4d2Smrg	    ResetState(sp);
389820d2c4d2Smrg	    break;
3899d522f475Smrg	}
3900d522f475Smrg	if (sp->parsestate == sp->groundtable)
3901d522f475Smrg	    sp->lastchar = thischar;
3902d522f475Smrg    } while (0);
3903d522f475Smrg
3904d522f475Smrg#if OPT_WIDE_CHARS
39052eaa94a1Schristos    screen->utf8_inparse = (Boolean) ((screen->utf8_mode != uFalse)
39062eaa94a1Schristos				      && (sp->parsestate != sos_table));
3907d522f475Smrg#endif
3908d522f475Smrg
3909d522f475Smrg    return True;
3910d522f475Smrg}
3911d522f475Smrg
3912d522f475Smrgstatic void
3913d522f475SmrgVTparse(XtermWidget xw)
3914d522f475Smrg{
3915d522f475Smrg    /* We longjmp back to this point in VTReset() */
3916d522f475Smrg    (void) setjmp(vtjmpbuf);
3917e39b573cSmrg    init_parser(xw, &myState);
39182eaa94a1Schristos
3919d522f475Smrg    do {
3920d522f475Smrg    } while (doparsing(xw, doinput(), &myState));
3921d522f475Smrg}
3922d522f475Smrg
3923d522f475Smrgstatic Char *v_buffer;		/* pointer to physical buffer */
3924d522f475Smrgstatic Char *v_bufstr = NULL;	/* beginning of area to write */
3925d522f475Smrgstatic Char *v_bufptr;		/* end of area to write */
3926d522f475Smrgstatic Char *v_bufend;		/* end of physical buffer */
3927d522f475Smrg
3928d522f475Smrg/* Write data to the pty as typed by the user, pasted with the mouse,
3929d522f475Smrg   or generated by us in response to a query ESC sequence. */
3930d522f475Smrg
393120d2c4d2Smrgvoid
3932492d43a5Smrgv_write(int f, const Char * data, unsigned len)
3933d522f475Smrg{
3934d522f475Smrg    int riten;
3935d522f475Smrg
393620d2c4d2Smrg    TRACE2(("v_write(%d:%s)\n", len, visibleChars(data, len)));
39370bd37d32Smrg    if (v_bufstr == NULL) {
39380bd37d32Smrg	if (len > 0) {
39390bd37d32Smrg	    v_buffer = (Char *) XtMalloc((Cardinal) len);
39400bd37d32Smrg	    v_bufstr = v_buffer;
39410bd37d32Smrg	    v_bufptr = v_buffer;
39420bd37d32Smrg	    v_bufend = v_buffer + len;
39430bd37d32Smrg	}
39440bd37d32Smrg	if (v_bufstr == NULL) {
39450bd37d32Smrg	    return;
39460bd37d32Smrg	}
39470bd37d32Smrg    }
39480bd37d32Smrg    if_DEBUG({
39490bd37d32Smrg	fprintf(stderr, "v_write called with %d bytes (%ld left over)",
39500bd37d32Smrg		len, (long) (v_bufptr - v_bufstr));
3951d522f475Smrg	if (len > 1 && len < 10)
3952492d43a5Smrg	    fprintf(stderr, " \"%.*s\"", len, (const char *) data);
3953d522f475Smrg	fprintf(stderr, "\n");
39540bd37d32Smrg    });
3955d522f475Smrg
3956d522f475Smrg#ifdef VMS
395720d2c4d2Smrg    if ((1 << f) != pty_mask) {
3958492d43a5Smrg	tt_write((const char *) data, len);
395920d2c4d2Smrg	return;
396020d2c4d2Smrg    }
3961d522f475Smrg#else /* VMS */
396220d2c4d2Smrg    if (!FD_ISSET(f, &pty_mask)) {
3963492d43a5Smrg	IGNORE_RC(write(f, (const char *) data, (size_t) len));
396420d2c4d2Smrg	return;
396520d2c4d2Smrg    }
3966d522f475Smrg#endif /* VMS */
3967d522f475Smrg
3968d522f475Smrg    /*
3969d522f475Smrg     * Append to the block we already have.
3970d522f475Smrg     * Always doing this simplifies the code, and
3971d522f475Smrg     * isn't too bad, either.  If this is a short
3972d522f475Smrg     * block, it isn't too expensive, and if this is
3973d522f475Smrg     * a long block, we won't be able to write it all
3974d522f475Smrg     * anyway.
3975d522f475Smrg     */
3976d522f475Smrg
3977d522f475Smrg    if (len > 0) {
3978d522f475Smrg#if OPT_DABBREV
397920d2c4d2Smrg	TScreenOf(term)->dabbrev_working = False;	/* break dabbrev sequence */
3980d522f475Smrg#endif
3981d522f475Smrg	if (v_bufend < v_bufptr + len) {	/* we've run out of room */
3982d522f475Smrg	    if (v_bufstr != v_buffer) {
3983d522f475Smrg		/* there is unused space, move everything down */
3984d522f475Smrg		/* possibly overlapping memmove here */
39850bd37d32Smrg		if_DEBUG({
39860bd37d32Smrg		    fprintf(stderr, "moving data down %ld\n",
39870bd37d32Smrg			    (long) (v_bufstr - v_buffer));
39880bd37d32Smrg		});
398920d2c4d2Smrg		memmove(v_buffer, v_bufstr, (size_t) (v_bufptr - v_bufstr));
3990d522f475Smrg		v_bufptr -= v_bufstr - v_buffer;
3991d522f475Smrg		v_bufstr = v_buffer;
3992d522f475Smrg	    }
3993d522f475Smrg	    if (v_bufend < v_bufptr + len) {
3994d522f475Smrg		/* still won't fit: get more space */
3995d522f475Smrg		/* Don't use XtRealloc because an error is not fatal. */
39962eaa94a1Schristos		unsigned size = (unsigned) (v_bufptr - v_buffer);
3997d522f475Smrg		v_buffer = TypeRealloc(Char, size + len, v_buffer);
3998d522f475Smrg		if (v_buffer) {
39990bd37d32Smrg		    if_DEBUG({
4000d522f475Smrg			fprintf(stderr, "expanded buffer to %d\n",
4001d522f475Smrg				size + len);
40020bd37d32Smrg		    });
4003d522f475Smrg		    v_bufstr = v_buffer;
4004d522f475Smrg		    v_bufptr = v_buffer + size;
4005d522f475Smrg		    v_bufend = v_bufptr + len;
4006d522f475Smrg		} else {
4007d522f475Smrg		    /* no memory: ignore entire write request */
40080bd37d32Smrg		    xtermWarning("cannot allocate buffer space\n");
4009d522f475Smrg		    v_buffer = v_bufstr;	/* restore clobbered pointer */
4010d522f475Smrg		}
4011d522f475Smrg	    }
4012d522f475Smrg	}
4013d522f475Smrg	if (v_bufend >= v_bufptr + len) {
4014d522f475Smrg	    /* new stuff will fit */
401520d2c4d2Smrg	    memmove(v_bufptr, data, (size_t) len);
4016d522f475Smrg	    v_bufptr += len;
4017d522f475Smrg	}
4018d522f475Smrg    }
4019d522f475Smrg
4020d522f475Smrg    /*
4021d522f475Smrg     * Write out as much of the buffer as we can.
4022d522f475Smrg     * Be careful not to overflow the pty's input silo.
4023d522f475Smrg     * We are conservative here and only write
4024d522f475Smrg     * a small amount at a time.
4025d522f475Smrg     *
4026d522f475Smrg     * If we can't push all the data into the pty yet, we expect write
4027d522f475Smrg     * to return a non-negative number less than the length requested
4028d522f475Smrg     * (if some data written) or -1 and set errno to EAGAIN,
4029d522f475Smrg     * EWOULDBLOCK, or EINTR (if no data written).
4030d522f475Smrg     *
4031d522f475Smrg     * (Not all systems do this, sigh, so the code is actually
4032d522f475Smrg     * a little more forgiving.)
4033d522f475Smrg     */
4034d522f475Smrg
4035d522f475Smrg#define MAX_PTY_WRITE 128	/* 1/2 POSIX minimum MAX_INPUT */
4036d522f475Smrg
4037d522f475Smrg    if (v_bufptr > v_bufstr) {
4038d522f475Smrg#ifdef VMS
4039d522f475Smrg	riten = tt_write(v_bufstr,
4040d522f475Smrg			 ((v_bufptr - v_bufstr <= VMS_TERM_BUFFER_SIZE)
4041d522f475Smrg			  ? v_bufptr - v_bufstr
4042d522f475Smrg			  : VMS_TERM_BUFFER_SIZE));
4043d522f475Smrg	if (riten == 0)
4044d522f475Smrg	    return (riten);
4045d522f475Smrg#else /* VMS */
404620d2c4d2Smrg	riten = (int) write(f, v_bufstr,
404720d2c4d2Smrg			    (size_t) ((v_bufptr - v_bufstr <= MAX_PTY_WRITE)
404820d2c4d2Smrg				      ? v_bufptr - v_bufstr
404920d2c4d2Smrg				      : MAX_PTY_WRITE));
4050d522f475Smrg	if (riten < 0)
4051d522f475Smrg#endif /* VMS */
4052d522f475Smrg	{
40530bd37d32Smrg	    if_DEBUG({
4054d522f475Smrg		perror("write");
40550bd37d32Smrg	    });
4056d522f475Smrg	    riten = 0;
4057d522f475Smrg	}
40580bd37d32Smrg	if_DEBUG({
40590bd37d32Smrg	    fprintf(stderr, "write called with %ld, wrote %d\n",
40600bd37d32Smrg		    ((long) ((v_bufptr - v_bufstr) <= MAX_PTY_WRITE)
40610bd37d32Smrg		     ? (long) (v_bufptr - v_bufstr)
40620bd37d32Smrg		     : MAX_PTY_WRITE),
4063d522f475Smrg		    riten);
40640bd37d32Smrg	});
4065d522f475Smrg	v_bufstr += riten;
4066d522f475Smrg	if (v_bufstr >= v_bufptr)	/* we wrote it all */
4067d522f475Smrg	    v_bufstr = v_bufptr = v_buffer;
4068d522f475Smrg    }
4069d522f475Smrg
4070d522f475Smrg    /*
4071d522f475Smrg     * If we have lots of unused memory allocated, return it
4072d522f475Smrg     */
4073d522f475Smrg    if (v_bufend - v_bufptr > 1024) {	/* arbitrary hysteresis */
4074d522f475Smrg	/* save pointers across realloc */
407520d2c4d2Smrg	int start = (int) (v_bufstr - v_buffer);
407620d2c4d2Smrg	int size = (int) (v_bufptr - v_buffer);
4077d522f475Smrg	unsigned allocsize = (unsigned) (size ? size : 1);
4078d522f475Smrg
4079d522f475Smrg	v_buffer = TypeRealloc(Char, allocsize, v_buffer);
4080d522f475Smrg	if (v_buffer) {
4081d522f475Smrg	    v_bufstr = v_buffer + start;
4082d522f475Smrg	    v_bufptr = v_buffer + size;
4083d522f475Smrg	    v_bufend = v_buffer + allocsize;
40840bd37d32Smrg	    if_DEBUG({
4085d522f475Smrg		fprintf(stderr, "shrunk buffer to %d\n", allocsize);
40860bd37d32Smrg	    });
4087d522f475Smrg	} else {
4088d522f475Smrg	    /* should we print a warning if couldn't return memory? */
4089d522f475Smrg	    v_buffer = v_bufstr - start;	/* restore clobbered pointer */
4090d522f475Smrg	}
4091d522f475Smrg    }
4092d522f475Smrg}
4093d522f475Smrg
4094e39b573cSmrgstatic void
4095e39b573cSmrgupdateCursor(TScreen * screen)
4096e39b573cSmrg{
4097e39b573cSmrg    if (screen->cursor_set != screen->cursor_state) {
4098e39b573cSmrg	if (screen->cursor_set)
4099e39b573cSmrg	    ShowCursor();
4100e39b573cSmrg	else
4101e39b573cSmrg	    HideCursor();
4102e39b573cSmrg    }
4103e39b573cSmrg}
4104e39b573cSmrg
41050bd37d32Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
4106e39b573cSmrgstatic void
4107e39b573cSmrgreallyStopBlinking(TScreen * screen)
4108e39b573cSmrg{
4109e39b573cSmrg    if (screen->cursor_state == BLINKED_OFF) {
4110e39b573cSmrg	/* force cursor to display if it is enabled */
4111e39b573cSmrg	screen->cursor_state = !screen->cursor_set;
4112e39b573cSmrg	updateCursor(screen);
4113e39b573cSmrg	xevents();
4114e39b573cSmrg    }
4115e39b573cSmrg}
41160bd37d32Smrg#endif
4117e39b573cSmrg
4118d522f475Smrg#ifdef VMS
4119d522f475Smrg#define	ptymask()	(v_bufptr > v_bufstr ? pty_mask : 0)
4120d522f475Smrg
4121d522f475Smrgstatic void
4122d522f475Smrgin_put(XtermWidget xw)
4123d522f475Smrg{
4124d522f475Smrg    static PtySelect select_mask;
4125d522f475Smrg    static PtySelect write_mask;
4126d522f475Smrg    int update = VTbuffer->update;
4127d522f475Smrg    int size;
4128d522f475Smrg
4129d522f475Smrg    int status;
4130d522f475Smrg    Dimension replyWidth, replyHeight;
4131d522f475Smrg    XtGeometryResult stat;
4132d522f475Smrg
413320d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4134d522f475Smrg    char *cp;
4135d522f475Smrg    int i;
4136d522f475Smrg
4137d522f475Smrg    select_mask = pty_mask;	/* force initial read */
4138d522f475Smrg    for (;;) {
4139d522f475Smrg
4140d522f475Smrg	/* if the terminal changed size, resize the widget */
4141d522f475Smrg	if (tt_changed) {
4142d522f475Smrg	    tt_changed = False;
4143d522f475Smrg
41442eaa94a1Schristos	    stat = REQ_RESIZE((Widget) xw,
41452eaa94a1Schristos			      ((Dimension) FontWidth(screen)
41462eaa94a1Schristos			       * (tt_width)
41472eaa94a1Schristos			       + 2 * screen->border
41482eaa94a1Schristos			       + screen->fullVwin.sb_info.width),
41492eaa94a1Schristos			      ((Dimension) FontHeight(screen)
41502eaa94a1Schristos			       * (tt_length)
41512eaa94a1Schristos			       + 2 * screen->border),
41522eaa94a1Schristos			      &replyWidth, &replyHeight);
4153d522f475Smrg
4154d522f475Smrg	    if (stat == XtGeometryYes || stat == XtGeometryDone) {
4155d522f475Smrg		xw->core.width = replyWidth;
4156d522f475Smrg		xw->core.height = replyHeight;
4157d522f475Smrg
4158d522f475Smrg		ScreenResize(xw, replyWidth, replyHeight, &xw->flags);
4159d522f475Smrg	    }
4160d522f475Smrg	    repairSizeHints();
4161d522f475Smrg	}
4162d522f475Smrg
4163d522f475Smrg	if (screen->eventMode == NORMAL
416420d2c4d2Smrg	    && readPtyData(xw, &select_mask, VTbuffer)) {
4165d522f475Smrg	    if (screen->scrollWidget
4166d522f475Smrg		&& screen->scrollttyoutput
4167d522f475Smrg		&& screen->topline < 0)
4168d522f475Smrg		/* Scroll to bottom */
416920d2c4d2Smrg		WindowScroll(xw, 0, False);
4170d522f475Smrg	    break;
4171d522f475Smrg	}
4172d522f475Smrg	if (screen->scroll_amt)
4173d522f475Smrg	    FlushScroll(xw);
4174d522f475Smrg	if (screen->cursor_set && CursorMoved(screen)) {
4175d522f475Smrg	    if (screen->cursor_state)
4176d522f475Smrg		HideCursor();
4177d522f475Smrg	    ShowCursor();
41780bd37d32Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
41790bd37d32Smrg	    PreeditPosition(xw);
4180d522f475Smrg#endif
4181e39b573cSmrg	} else {
4182e39b573cSmrg	    updateCursor(screen);
4183d522f475Smrg	}
4184d522f475Smrg
4185d522f475Smrg	if (QLength(screen->display)) {
4186d522f475Smrg	    select_mask = X_mask;
4187d522f475Smrg	} else {
4188d522f475Smrg	    write_mask = ptymask();
4189d522f475Smrg	    XFlush(screen->display);
4190d522f475Smrg	    select_mask = Select_mask;
4191d522f475Smrg	    if (screen->eventMode != NORMAL)
4192d522f475Smrg		select_mask = X_mask;
4193d522f475Smrg	}
4194d522f475Smrg	if (write_mask & ptymask()) {
4195d522f475Smrg	    v_write(screen->respond, 0, 0);	/* flush buffer */
4196d522f475Smrg	}
4197d522f475Smrg
4198d522f475Smrg	if (select_mask & X_mask) {
4199d522f475Smrg	    xevents();
4200d522f475Smrg	    if (VTbuffer->update != update)
4201d522f475Smrg		break;
4202d522f475Smrg	}
4203d522f475Smrg    }
4204d522f475Smrg}
4205d522f475Smrg#else /* VMS */
4206d522f475Smrg
4207d522f475Smrgstatic void
4208d522f475Smrgin_put(XtermWidget xw)
4209d522f475Smrg{
4210d522f475Smrg    static PtySelect select_mask;
4211d522f475Smrg    static PtySelect write_mask;
4212d522f475Smrg
421320d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4214d522f475Smrg    int i, time_select;
4215d522f475Smrg    int size;
4216d522f475Smrg    int update = VTbuffer->update;
42170bd37d32Smrg#if OPT_DOUBLE_BUFFER
42180bd37d32Smrg    int should_wait = 1;
42190bd37d32Smrg#endif
4220d522f475Smrg
4221d522f475Smrg    static struct timeval select_timeout;
4222d522f475Smrg
4223d522f475Smrg#if OPT_BLINK_CURS
4224d522f475Smrg    /*
4225d522f475Smrg     * Compute the timeout for the blinking cursor to be much smaller than
4226d522f475Smrg     * the "on" or "off" interval.
4227d522f475Smrg     */
4228d522f475Smrg    int tick = ((screen->blink_on < screen->blink_off)
4229d522f475Smrg		? screen->blink_on
4230d522f475Smrg		: screen->blink_off);
4231d522f475Smrg    tick *= (1000 / 8);		/* 1000 for msec/usec, 8 for "much" smaller */
4232d522f475Smrg    if (tick < 1)
4233d522f475Smrg	tick = 1;
4234d522f475Smrg#endif
4235d522f475Smrg
4236d522f475Smrg    for (;;) {
4237d522f475Smrg	if (screen->eventMode == NORMAL
423820d2c4d2Smrg	    && (size = readPtyData(xw, &select_mask, VTbuffer)) != 0) {
4239d522f475Smrg	    if (screen->scrollWidget
4240d522f475Smrg		&& screen->scrollttyoutput
4241d522f475Smrg		&& screen->topline < 0)
424220d2c4d2Smrg		WindowScroll(xw, 0, False);	/* Scroll to bottom */
4243d522f475Smrg	    /* stop speed reading at some point to look for X stuff */
424420d2c4d2Smrg	    TRACE(("VTbuffer uses %ld/%d\n",
424520d2c4d2Smrg		   (long) (VTbuffer->last - VTbuffer->buffer),
4246d522f475Smrg		   BUF_SIZE));
4247d522f475Smrg	    if ((VTbuffer->last - VTbuffer->buffer) > BUF_SIZE) {
4248d522f475Smrg		FD_CLR(screen->respond, &select_mask);
4249d522f475Smrg		break;
4250d522f475Smrg	    }
42510bd37d32Smrg#if OPT_DOUBLE_BUFFER
42520bd37d32Smrg	    if (should_wait) {
42530bd37d32Smrg		/* wait 25 msec for potential extra data (avoids some bogus flickering) */
42540bd37d32Smrg		/* that's only 40 FPS but hey, it's still lower than the input lag on some consoles! :) */
42550bd37d32Smrg		usleep(25000);
42560bd37d32Smrg		should_wait = 0;
42570bd37d32Smrg	    }
42580bd37d32Smrg	    select_timeout.tv_sec = 0;
42590bd37d32Smrg	    i = Select(max_plus1, &select_mask, &write_mask, 0,
42600bd37d32Smrg		       &select_timeout);
42610bd37d32Smrg	    if (i > 0 && FD_ISSET(screen->respond, &select_mask))
42620bd37d32Smrg		continue;
42630bd37d32Smrg	    else
42640bd37d32Smrg		break;
42650bd37d32Smrg#elif defined(HAVE_SCHED_YIELD)
4266d522f475Smrg	    /*
4267d522f475Smrg	     * If we've read a full (small/fragment) buffer, let the operating
4268d522f475Smrg	     * system have a turn, and we'll resume reading until we've either
4269d522f475Smrg	     * read only a fragment of the buffer, or we've filled the large
4270d522f475Smrg	     * buffer (see above).  Doing this helps keep up with large bursts
4271d522f475Smrg	     * of output.
4272d522f475Smrg	     */
4273d522f475Smrg	    if (size == FRG_SIZE) {
4274d522f475Smrg		select_timeout.tv_sec = 0;
4275d522f475Smrg		i = Select(max_plus1, &select_mask, &write_mask, 0,
4276d522f475Smrg			   &select_timeout);
42770bd37d32Smrg		if (i > 0 && FD_ISSET(screen->respond, &select_mask)) {
4278d522f475Smrg		    sched_yield();
4279d522f475Smrg		} else
4280d522f475Smrg		    break;
4281d522f475Smrg	    } else {
4282d522f475Smrg		break;
4283d522f475Smrg	    }
4284d522f475Smrg#else
4285d522f475Smrg	    (void) size;	/* unused in this branch */
4286d522f475Smrg	    break;
4287d522f475Smrg#endif
4288d522f475Smrg	}
4289d522f475Smrg	/* update the screen */
4290d522f475Smrg	if (screen->scroll_amt)
4291d522f475Smrg	    FlushScroll(xw);
4292d522f475Smrg	if (screen->cursor_set && CursorMoved(screen)) {
4293d522f475Smrg	    if (screen->cursor_state)
4294d522f475Smrg		HideCursor();
4295d522f475Smrg	    ShowCursor();
42960bd37d32Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
42970bd37d32Smrg	    PreeditPosition(xw);
4298d522f475Smrg#endif
4299e39b573cSmrg	} else {
4300e39b573cSmrg	    updateCursor(screen);
4301d522f475Smrg	}
4302d522f475Smrg
4303d522f475Smrg	XFlush(screen->display);	/* always flush writes before waiting */
4304d522f475Smrg
4305d522f475Smrg	/* Update the masks and, unless X events are already in the queue,
4306d522f475Smrg	   wait for I/O to be possible. */
4307d522f475Smrg	XFD_COPYSET(&Select_mask, &select_mask);
4308d522f475Smrg	/* in selection mode xterm does not read pty */
4309d522f475Smrg	if (screen->eventMode != NORMAL)
4310d522f475Smrg	    FD_CLR(screen->respond, &select_mask);
4311d522f475Smrg
4312d522f475Smrg	if (v_bufptr > v_bufstr) {
4313d522f475Smrg	    XFD_COPYSET(&pty_mask, &write_mask);
4314d522f475Smrg	} else
4315d522f475Smrg	    FD_ZERO(&write_mask);
4316d522f475Smrg	select_timeout.tv_sec = 0;
4317d522f475Smrg	time_select = 0;
4318d522f475Smrg
4319d522f475Smrg	/*
4320d522f475Smrg	 * if there's either an XEvent or an XtTimeout pending, just take
4321d522f475Smrg	 * a quick peek, i.e. timeout from the select() immediately.  If
4322d522f475Smrg	 * there's nothing pending, let select() block a little while, but
4323d522f475Smrg	 * for a shorter interval than the arrow-style scrollbar timeout.
4324d522f475Smrg	 * The blocking is optional, because it tends to increase the load
4325d522f475Smrg	 * on the host.
4326d522f475Smrg	 */
43270bd37d32Smrg	if (xtermAppPending()) {
4328d522f475Smrg	    select_timeout.tv_usec = 0;
4329d522f475Smrg	    time_select = 1;
4330d522f475Smrg	} else if (screen->awaitInput) {
4331d522f475Smrg	    select_timeout.tv_usec = 50000;
4332d522f475Smrg	    time_select = 1;
4333d522f475Smrg#if OPT_BLINK_CURS
4334d522f475Smrg	} else if ((screen->blink_timer != 0 &&
4335d522f475Smrg		    ((screen->select & FOCUS) || screen->always_highlight)) ||
4336d522f475Smrg		   (screen->cursor_state == BLINKED_OFF)) {
4337d522f475Smrg	    select_timeout.tv_usec = tick;
4338d522f475Smrg	    while (select_timeout.tv_usec > 1000000) {
4339d522f475Smrg		select_timeout.tv_usec -= 1000000;
4340d522f475Smrg		select_timeout.tv_sec++;
4341d522f475Smrg	    }
4342d522f475Smrg	    time_select = 1;
4343d522f475Smrg#endif
4344d522f475Smrg#if OPT_SESSION_MGT
4345d522f475Smrg	} else if (resource.sessionMgt) {
4346d522f475Smrg	    if (ice_fd >= 0)
4347d522f475Smrg		FD_SET(ice_fd, &select_mask);
4348d522f475Smrg#endif
4349d522f475Smrg	}
4350d522f475Smrg	if (need_cleanup)
43510bd37d32Smrg	    NormalExit();
43520bd37d32Smrg#if OPT_DOUBLE_BUFFER
43530bd37d32Smrg	if (screen->needSwap) {
43540bd37d32Smrg	    XdbeSwapInfo swap;
43550bd37d32Smrg	    swap.swap_window = VWindow(screen);
43560bd37d32Smrg	    swap.swap_action = XdbeCopied;
43570bd37d32Smrg	    XdbeSwapBuffers(XtDisplay(term), &swap, 1);
43580bd37d32Smrg	    XFlush(XtDisplay(xw));
43590bd37d32Smrg	    screen->needSwap = 0;
43600bd37d32Smrg	}
43610bd37d32Smrg#endif
4362d522f475Smrg	i = Select(max_plus1, &select_mask, &write_mask, 0,
4363d522f475Smrg		   (time_select ? &select_timeout : 0));
4364d522f475Smrg	if (i < 0) {
4365d522f475Smrg	    if (errno != EINTR)
4366d522f475Smrg		SysError(ERROR_SELECT);
4367d522f475Smrg	    continue;
4368d522f475Smrg	}
4369d522f475Smrg
4370d522f475Smrg	/* if there is room to write more data to the pty, go write more */
4371d522f475Smrg	if (FD_ISSET(screen->respond, &write_mask)) {
4372d522f475Smrg	    v_write(screen->respond, (Char *) 0, 0);	/* flush buffer */
4373d522f475Smrg	}
4374d522f475Smrg
4375d522f475Smrg	/* if there are X events already in our queue, it
4376d522f475Smrg	   counts as being readable */
43770bd37d32Smrg	if (xtermAppPending() ||
4378d522f475Smrg	    FD_ISSET(ConnectionNumber(screen->display), &select_mask)) {
4379d522f475Smrg	    xevents();
4380d522f475Smrg	    if (VTbuffer->update != update)	/* HandleInterpret */
4381d522f475Smrg		break;
4382d522f475Smrg	}
4383d522f475Smrg
4384d522f475Smrg    }
4385d522f475Smrg}
4386d522f475Smrg#endif /* VMS */
4387d522f475Smrg
4388d522f475Smrgstatic IChar
4389d522f475Smrgdoinput(void)
4390d522f475Smrg{
4391d522f475Smrg    TScreen *screen = TScreenOf(term);
4392d522f475Smrg
4393d522f475Smrg    while (!morePtyData(screen, VTbuffer))
4394d522f475Smrg	in_put(term);
4395d522f475Smrg    return nextPtyData(screen, VTbuffer);
4396d522f475Smrg}
4397d522f475Smrg
43980bd37d32Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
4399d522f475Smrg/*
4400d522f475Smrg *  For OverTheSpot, client has to inform the position for XIM preedit.
4401d522f475Smrg */
4402d522f475Smrgstatic void
44030bd37d32SmrgPreeditPosition(XtermWidget xw)
4404d522f475Smrg{
44050bd37d32Smrg    TInput *input = lookupTInput(xw, (Widget) xw);
44060bd37d32Smrg    TScreen *screen = TScreenOf(xw);
4407956cc18dSsnj    LineData *ld;
4408d522f475Smrg    XPoint spot;
4409d522f475Smrg    XVaNestedList list;
4410d522f475Smrg
44110bd37d32Smrg    if (input && input->xic
4412956cc18dSsnj	&& (ld = getLineData(screen, screen->cur_row)) != 0) {
4413956cc18dSsnj	spot.x = (short) LineCursorX(screen, ld, screen->cur_col);
44140bd37d32Smrg	spot.y = (short) (CursorY(screen, screen->cur_row) + xw->misc.xim_fs_ascent);
4415956cc18dSsnj	list = XVaCreateNestedList(0,
4416956cc18dSsnj				   XNSpotLocation, &spot,
4417956cc18dSsnj				   XNForeground, T_COLOR(screen, TEXT_FG),
4418956cc18dSsnj				   XNBackground, T_COLOR(screen, TEXT_BG),
44190bd37d32Smrg				   (void *) 0);
44200bd37d32Smrg	XSetICValues(input->xic, XNPreeditAttributes, list, (void *) 0);
4421956cc18dSsnj	XFree(list);
4422956cc18dSsnj    }
4423d522f475Smrg}
4424d522f475Smrg#endif
4425d522f475Smrg
4426d522f475Smrgstatic void
4427d522f475SmrgWrapLine(XtermWidget xw)
4428d522f475Smrg{
442920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4430956cc18dSsnj    LineData *ld = getLineData(screen, screen->cur_row);
4431d522f475Smrg
4432956cc18dSsnj    if (ld != 0) {
4433956cc18dSsnj	/* mark that we had to wrap this line */
4434956cc18dSsnj	LineSetFlag(ld, LINEWRAPPED);
4435492d43a5Smrg	if (screen->show_wrap_marks) {
4436492d43a5Smrg	    ShowWrapMarks(xw, screen->cur_row, ld);
4437492d43a5Smrg	}
4438956cc18dSsnj	xtermAutoPrint(xw, '\n');
4439956cc18dSsnj	xtermIndex(xw, 1);
44400bd37d32Smrg	set_cur_col(screen, ScrnLeftMargin(xw));
4441956cc18dSsnj    }
4442d522f475Smrg}
4443d522f475Smrg
4444d522f475Smrg/*
4445d522f475Smrg * process a string of characters according to the character set indicated
4446d522f475Smrg * by charset.  worry about end of line conditions (wraparound if selected).
4447d522f475Smrg */
4448d522f475Smrgvoid
4449d522f475Smrgdotext(XtermWidget xw,
4450d522f475Smrg       int charset,
4451d522f475Smrg       IChar * buf,		/* start of characters to process */
4452d522f475Smrg       Cardinal len)		/* end */
4453d522f475Smrg{
445420d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4455d522f475Smrg#if OPT_WIDE_CHARS
4456d522f475Smrg    Cardinal chars_chomped = 1;
4457d522f475Smrg    int next_col = screen->cur_col;
4458d522f475Smrg#else
4459d522f475Smrg    int next_col, last_col, this_col;	/* must be signed */
4460d522f475Smrg#endif
4461d522f475Smrg    Cardinal offset;
44620bd37d32Smrg    int right = ScrnRightMargin(xw);
4463d522f475Smrg
44640bd37d32Smrg    /*
44650bd37d32Smrg     * It is possible to use CUP, etc., to move outside margins.  In that
44660bd37d32Smrg     * case, the right-margin is ineffective.
44670bd37d32Smrg     */
44680bd37d32Smrg    if (screen->cur_col > right) {
44690bd37d32Smrg	right = screen->max_col;
44700bd37d32Smrg    }
4471d522f475Smrg#if OPT_WIDE_CHARS
4472d522f475Smrg    /* don't translate if we use UTF-8, and are not handling legacy support
4473d522f475Smrg     * for line-drawing characters.
4474d522f475Smrg     */
4475d522f475Smrg    if ((screen->utf8_mode == uFalse)
44762eaa94a1Schristos	|| (screen->vt100_graphics))
4477d522f475Smrg#endif
44782eaa94a1Schristos	if (!xtermCharSetOut(xw, buf, buf + len, charset))
4479d522f475Smrg	    return;
4480d522f475Smrg
4481d522f475Smrg    if_OPT_XMC_GLITCH(screen, {
4482d522f475Smrg	Cardinal n;
4483d522f475Smrg	if (charset != '?') {
4484d522f475Smrg	    for (n = 0; n < len; n++) {
4485d522f475Smrg		if (buf[n] == XMC_GLITCH)
4486d522f475Smrg		    buf[n] = XMC_GLITCH + 1;
4487d522f475Smrg	    }
4488d522f475Smrg	}
4489d522f475Smrg    });
4490d522f475Smrg
4491d522f475Smrg#if OPT_WIDE_CHARS
4492d522f475Smrg    for (offset = 0;
4493d522f475Smrg	 offset < len && (chars_chomped > 0 || screen->do_wrap);
4494d522f475Smrg	 offset += chars_chomped) {
44950bd37d32Smrg	int width_available = right + 1 - screen->cur_col;
4496d522f475Smrg	int width_here = 0;
44970bd37d32Smrg	Boolean force_wrap;
44980bd37d32Smrg	Boolean need_wrap;
44990bd37d32Smrg	Boolean did_wrap;
4500d522f475Smrg	int last_chomp = 0;
4501d522f475Smrg	chars_chomped = 0;
4502d522f475Smrg
45030bd37d32Smrg	do {
45040bd37d32Smrg	    force_wrap = False;
45050bd37d32Smrg	    need_wrap = False;
45060bd37d32Smrg	    did_wrap = False;
45070bd37d32Smrg
45080bd37d32Smrg	    if (screen->do_wrap) {
45090bd37d32Smrg		screen->do_wrap = False;
45100bd37d32Smrg		if ((xw->flags & WRAPAROUND)) {
45110bd37d32Smrg		    WrapLine(xw);
45120bd37d32Smrg		    width_available = right + 1 - screen->cur_col;
45130bd37d32Smrg		    next_col = screen->cur_col;
45140bd37d32Smrg		    did_wrap = True;
45150bd37d32Smrg		}
4516d522f475Smrg	    }
4517d522f475Smrg
45180bd37d32Smrg	    /*
45190bd37d32Smrg	     * This can happen with left/right margins...
45200bd37d32Smrg	     */
45210bd37d32Smrg	    if (width_available <= 0) {
45220bd37d32Smrg		break;
45230bd37d32Smrg	    }
4524d522f475Smrg
45250bd37d32Smrg	    while (width_here <= width_available
45260bd37d32Smrg		   && chars_chomped < (len - offset)) {
45270bd37d32Smrg		if (!screen->utf8_mode
45280bd37d32Smrg		    || (screen->vt100_graphics && charset == '0')) {
45290bd37d32Smrg		    last_chomp = 1;
45300bd37d32Smrg		} else {
45310bd37d32Smrg		    last_chomp = my_wcwidth((wchar_t) buf[chars_chomped + offset]);
45320bd37d32Smrg		}
45330bd37d32Smrg		width_here += last_chomp;
45340bd37d32Smrg		chars_chomped++;
45350bd37d32Smrg	    }
45360bd37d32Smrg
45370bd37d32Smrg	    if (width_here > width_available) {
45380bd37d32Smrg		if (last_chomp > right + 1) {
45390bd37d32Smrg		    break;	/* give up - it is too big */
45400bd37d32Smrg		} else if (chars_chomped-- == 0) {
45410bd37d32Smrg		    /* This can happen with left/right margins... */
45420bd37d32Smrg		    break;
45430bd37d32Smrg		}
45440bd37d32Smrg		width_here -= last_chomp;
45450bd37d32Smrg		if (chars_chomped > 0) {
45460bd37d32Smrg		    need_wrap = True;
45470bd37d32Smrg		}
45480bd37d32Smrg	    } else if (width_here == width_available) {
45490bd37d32Smrg		need_wrap = True;
45500bd37d32Smrg	    } else if (chars_chomped != (len - offset)) {
45512eaa94a1Schristos		need_wrap = True;
4552d522f475Smrg	    }
4553d522f475Smrg
45540bd37d32Smrg	    if (chars_chomped != 0 && next_col <= screen->max_col) {
45550bd37d32Smrg		WriteText(xw, buf + offset, chars_chomped);
45560bd37d32Smrg	    } else if (!did_wrap
45570bd37d32Smrg		       && (xw->flags & WRAPAROUND)
45580bd37d32Smrg		       && screen->cur_col > ScrnLeftMargin(xw)) {
45590bd37d32Smrg		force_wrap = True;
45600bd37d32Smrg		need_wrap = True;
45610bd37d32Smrg	    }
45620bd37d32Smrg	    next_col += width_here;
45630bd37d32Smrg	    screen->do_wrap = need_wrap;
45640bd37d32Smrg	} while (force_wrap);
4565d522f475Smrg    }
45660bd37d32Smrg
45670bd37d32Smrg    /*
45680bd37d32Smrg     * Remember that we wrote something to the screen, for use as a base of
45690bd37d32Smrg     * combining characters.  The logic above may have called cursor-forward
45700bd37d32Smrg     * or carriage-return operations which resets this flag, so we set it at
45710bd37d32Smrg     * the very end.
45720bd37d32Smrg     */
45730bd37d32Smrg    screen->char_was_written = True;
4574d522f475Smrg#else /* ! OPT_WIDE_CHARS */
4575d522f475Smrg
4576a1f3da82Smrg    for (offset = 0; offset < len; offset += (Cardinal) this_col) {
4577956cc18dSsnj#if OPT_DEC_CHRSET
4578956cc18dSsnj	LineData *ld = getLineData(screen, screen->cur_row);
4579956cc18dSsnj#endif
4580956cc18dSsnj
4581956cc18dSsnj	last_col = LineMaxCol(screen, ld);
45820bd37d32Smrg	if (last_col > (right + 1))
45830bd37d32Smrg	    last_col = right + 1;
4584d522f475Smrg	this_col = last_col - screen->cur_col + 1;
4585d522f475Smrg	if (this_col <= 1) {
4586d522f475Smrg	    if (screen->do_wrap) {
45872eaa94a1Schristos		screen->do_wrap = False;
4588d522f475Smrg		if ((xw->flags & WRAPAROUND)) {
4589d522f475Smrg		    WrapLine(xw);
4590d522f475Smrg		}
4591d522f475Smrg	    }
4592d522f475Smrg	    this_col = 1;
4593d522f475Smrg	}
4594a1f3da82Smrg	if (offset + (Cardinal) this_col > len) {
4595a1f3da82Smrg	    this_col = (int) (len - offset);
4596d522f475Smrg	}
4597d522f475Smrg	next_col = screen->cur_col + this_col;
4598d522f475Smrg
4599956cc18dSsnj	WriteText(xw, buf + offset, (unsigned) this_col);
4600d522f475Smrg
4601d522f475Smrg	/*
4602d522f475Smrg	 * The call to WriteText updates screen->cur_col.
4603d522f475Smrg	 * If screen->cur_col is less than next_col, we must have
4604d522f475Smrg	 * hit the right margin - so set the do_wrap flag.
4605d522f475Smrg	 */
4606a1f3da82Smrg	screen->do_wrap = (Boolean) (screen->cur_col < next_col);
4607d522f475Smrg    }
4608d522f475Smrg
4609d522f475Smrg#endif /* OPT_WIDE_CHARS */
4610d522f475Smrg}
4611d522f475Smrg
4612d522f475Smrg#if OPT_WIDE_CHARS
4613d522f475Smrgunsigned
4614956cc18dSsnjvisual_width(IChar * str, Cardinal len)
4615d522f475Smrg{
4616d522f475Smrg    /* returns the visual width of a string (doublewide characters count
4617d522f475Smrg       as 2, normalwide characters count as 1) */
46182eaa94a1Schristos    unsigned my_len = 0;
4619d522f475Smrg    while (len) {
4620956cc18dSsnj	int ch = (int) *str++;
4621956cc18dSsnj	if (isWide(ch))
4622d522f475Smrg	    my_len += 2;
4623d522f475Smrg	else
4624d522f475Smrg	    my_len++;
4625d522f475Smrg	len--;
4626d522f475Smrg    }
4627d522f475Smrg    return my_len;
4628d522f475Smrg}
4629d522f475Smrg#endif
4630d522f475Smrg
4631d522f475Smrg#if HANDLE_STRUCT_NOTIFY
463220d2c4d2Smrg/* Flag icon name with "***" on window output when iconified.
4633d522f475Smrg */
4634d522f475Smrgstatic void
4635d522f475SmrgHandleStructNotify(Widget w GCC_UNUSED,
4636d522f475Smrg		   XtPointer closure GCC_UNUSED,
4637d522f475Smrg		   XEvent * event,
4638d522f475Smrg		   Boolean * cont GCC_UNUSED)
4639d522f475Smrg{
46402eaa94a1Schristos    XtermWidget xw = term;
4641d522f475Smrg
4642d522f475Smrg    switch (event->type) {
4643d522f475Smrg    case MapNotify:
4644d522f475Smrg	TRACE(("HandleStructNotify(MapNotify)\n"));
46450bd37d32Smrg	resetZIconBeep(xw);
4646d522f475Smrg	mapstate = !IsUnmapped;
4647d522f475Smrg	break;
4648d522f475Smrg    case UnmapNotify:
4649d522f475Smrg	TRACE(("HandleStructNotify(UnmapNotify)\n"));
4650d522f475Smrg	mapstate = IsUnmapped;
4651d522f475Smrg	break;
4652d522f475Smrg    case ConfigureNotify:
4653d522f475Smrg	if (event->xconfigure.window == XtWindow(toplevel)) {
465420d2c4d2Smrg#if !OPT_TOOLBAR
46552eaa94a1Schristos	    int height, width;
46562eaa94a1Schristos
46572eaa94a1Schristos	    height = event->xconfigure.height;
46582eaa94a1Schristos	    width = event->xconfigure.width;
465920d2c4d2Smrg#endif
46602eaa94a1Schristos	    TRACE(("HandleStructNotify(ConfigureNotify) %d,%d %dx%d\n",
46612eaa94a1Schristos		   event->xconfigure.y, event->xconfigure.x,
46622eaa94a1Schristos		   event->xconfigure.height, event->xconfigure.width));
46632eaa94a1Schristos
4664d522f475Smrg#if OPT_TOOLBAR
4665d522f475Smrg	    /*
4666d522f475Smrg	     * The notification is for the top-level widget, but we care about
4667d522f475Smrg	     * vt100 (ignore the tek4014 window).
4668d522f475Smrg	     */
466920d2c4d2Smrg	    if (TScreenOf(xw)->Vshow) {
467020d2c4d2Smrg		VTwin *Vwin = WhichVWin(TScreenOf(xw));
4671d522f475Smrg		TbInfo *info = &(Vwin->tb_info);
4672d522f475Smrg		TbInfo save = *info;
4673d522f475Smrg
4674d522f475Smrg		if (info->menu_bar) {
4675d522f475Smrg		    XtVaGetValues(info->menu_bar,
4676d522f475Smrg				  XtNheight, &info->menu_height,
4677d522f475Smrg				  XtNborderWidth, &info->menu_border,
4678d522f475Smrg				  (XtPointer) 0);
4679d522f475Smrg
4680d522f475Smrg		    if (save.menu_height != info->menu_height
4681d522f475Smrg			|| save.menu_border != info->menu_border) {
4682d522f475Smrg
4683d522f475Smrg			TRACE(("...menu_height %d\n", info->menu_height));
4684d522f475Smrg			TRACE(("...menu_border %d\n", info->menu_border));
4685d522f475Smrg			TRACE(("...had height  %d, border %d\n",
4686d522f475Smrg			       save.menu_height,
4687d522f475Smrg			       save.menu_border));
4688d522f475Smrg
4689d522f475Smrg			/*
46900bd37d32Smrg			 * Window manager still may be using the old values.
46910bd37d32Smrg			 * Try to fool it.
4692d522f475Smrg			 */
46932eaa94a1Schristos			REQ_RESIZE((Widget) xw,
46940bd37d32Smrg				   TScreenOf(xw)->fullVwin.fullwidth,
46952eaa94a1Schristos				   (Dimension) (info->menu_height
46962eaa94a1Schristos						- save.menu_height
46970bd37d32Smrg						+ TScreenOf(xw)->fullVwin.fullheight),
46982eaa94a1Schristos				   NULL, NULL);
4699d522f475Smrg			repairSizeHints();
4700d522f475Smrg		    }
4701d522f475Smrg		}
4702d522f475Smrg	    }
4703d522f475Smrg#else
47042eaa94a1Schristos	    if (height != xw->hints.height || width != xw->hints.width)
47052eaa94a1Schristos		RequestResize(xw, height, width, False);
4706d522f475Smrg#endif /* OPT_TOOLBAR */
4707d522f475Smrg	}
4708d522f475Smrg	break;
4709d522f475Smrg    case ReparentNotify:
4710d522f475Smrg	TRACE(("HandleStructNotify(ReparentNotify)\n"));
4711d522f475Smrg	break;
4712d522f475Smrg    default:
4713d522f475Smrg	TRACE(("HandleStructNotify(event %s)\n",
4714d522f475Smrg	       visibleEventType(event->type)));
4715d522f475Smrg	break;
4716d522f475Smrg    }
4717d522f475Smrg}
4718d522f475Smrg#endif /* HANDLE_STRUCT_NOTIFY */
4719d522f475Smrg
4720d522f475Smrg#if OPT_BLINK_CURS
4721d522f475Smrgstatic void
4722956cc18dSsnjSetCursorBlink(TScreen * screen, Bool enable)
4723d522f475Smrg{
4724956cc18dSsnj    screen->cursor_blink = (Boolean) enable;
4725d522f475Smrg    if (DoStartBlinking(screen)) {
4726d522f475Smrg	StartBlinking(screen);
4727d522f475Smrg    } else {
4728a1f3da82Smrg	/* EMPTY */
4729e39b573cSmrg#if OPT_BLINK_TEXT
4730e39b573cSmrg	reallyStopBlinking(screen);
4731e39b573cSmrg#else
4732d522f475Smrg	StopBlinking(screen);
4733d522f475Smrg#endif
4734d522f475Smrg    }
4735d522f475Smrg    update_cursorblink();
4736d522f475Smrg}
4737d522f475Smrg
4738d522f475Smrgvoid
4739d522f475SmrgToggleCursorBlink(TScreen * screen)
4740d522f475Smrg{
4741956cc18dSsnj    SetCursorBlink(screen, (Bool) (!(screen->cursor_blink)));
4742d522f475Smrg}
4743d522f475Smrg#endif
4744d522f475Smrg
4745d522f475Smrg/*
4746d522f475Smrg * process ANSI modes set, reset
4747d522f475Smrg */
4748d522f475Smrgstatic void
474920d2c4d2Smrgansi_modes(XtermWidget xw, BitFunc func)
4750d522f475Smrg{
4751d522f475Smrg    int i;
4752d522f475Smrg
4753d522f475Smrg    for (i = 0; i < nparam; ++i) {
47540bd37d32Smrg	switch (GetParam(i)) {
4755d522f475Smrg	case 2:		/* KAM (if set, keyboard locked */
4756d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_KAM);
4757d522f475Smrg	    break;
4758d522f475Smrg
4759d522f475Smrg	case 4:		/* IRM                          */
4760d522f475Smrg	    (*func) (&xw->flags, INSERT);
4761d522f475Smrg	    break;
4762d522f475Smrg
4763d522f475Smrg	case 12:		/* SRM (if set, local echo      */
4764d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_SRM);
4765d522f475Smrg	    break;
4766d522f475Smrg
4767d522f475Smrg	case 20:		/* LNM                          */
4768d522f475Smrg	    (*func) (&xw->flags, LINEFEED);
4769d522f475Smrg	    update_autolinefeed();
4770d522f475Smrg	    break;
4771d522f475Smrg	}
4772d522f475Smrg    }
4773d522f475Smrg}
4774d522f475Smrg
4775d522f475Smrg#define IsSM() (func == bitset)
4776d522f475Smrg
4777d522f475Smrg#define set_bool_mode(flag) \
47782eaa94a1Schristos	flag = (Boolean) IsSM()
4779d522f475Smrg
4780d522f475Smrgstatic void
4781d522f475Smrgreally_set_mousemode(XtermWidget xw,
4782d522f475Smrg		     Bool enabled,
47832eaa94a1Schristos		     XtermMouseModes mode)
4784d522f475Smrg{
478520d2c4d2Smrg    TScreenOf(xw)->send_mouse_pos = enabled ? mode : MOUSE_OFF;
478620d2c4d2Smrg    if (TScreenOf(xw)->send_mouse_pos != MOUSE_OFF)
4787d522f475Smrg	xtermShowPointer(xw, True);
4788d522f475Smrg}
4789d522f475Smrg
4790d522f475Smrg#define set_mousemode(mode) really_set_mousemode(xw, IsSM(), mode)
4791d522f475Smrg
4792d522f475Smrg#if OPT_READLINE
4793d522f475Smrg#define set_mouseflag(f)		\
4794d522f475Smrg	(IsSM()				\
4795d522f475Smrg	 ? SCREEN_FLAG_set(screen, f)	\
4796d522f475Smrg	 : SCREEN_FLAG_unset(screen, f))
4797d522f475Smrg#endif
4798d522f475Smrg
47990bd37d32Smrg/*
48000bd37d32Smrg * Use this enumerated type to check consistency among dpmodes(), savemodes()
48010bd37d32Smrg * and restoremodes().
48020bd37d32Smrg */
48030bd37d32Smrgtypedef enum {
48040bd37d32Smrg    srm_DECCKM = 1
48050bd37d32Smrg    ,srm_DECANM = 2
48060bd37d32Smrg    ,srm_DECCOLM = 3
48070bd37d32Smrg    ,srm_DECSCLM = 4
48080bd37d32Smrg    ,srm_DECSCNM = 5
48090bd37d32Smrg    ,srm_DECOM = 6
48100bd37d32Smrg    ,srm_DECAWM = 7
48110bd37d32Smrg    ,srm_DECARM = 8
48120bd37d32Smrg    ,srm_X10_MOUSE = SET_X10_MOUSE
48130bd37d32Smrg#if OPT_TOOLBAR
48140bd37d32Smrg    ,srm_RXVT_TOOLBAR = 10
48150bd37d32Smrg#endif
48160bd37d32Smrg#if OPT_BLINK_CURS
48170bd37d32Smrg    ,srm_ATT610_BLINK = 12
48180bd37d32Smrg#endif
48190bd37d32Smrg    ,srm_DECPFF = 18
48200bd37d32Smrg    ,srm_DECPEX = 19
48210bd37d32Smrg    ,srm_DECTCEM = 25
48220bd37d32Smrg    ,srm_RXVT_SCROLLBAR = 30
48230bd37d32Smrg#if OPT_SHIFT_FONTS
48240bd37d32Smrg    ,srm_RXVT_FONTSIZE = 35
48250bd37d32Smrg#endif
48260bd37d32Smrg#if OPT_TEK4014
48270bd37d32Smrg    ,srm_DECTEK = 38
48280bd37d32Smrg#endif
48290bd37d32Smrg    ,srm_132COLS = 40
48300bd37d32Smrg    ,srm_CURSES_HACK = 41
48310bd37d32Smrg    ,srm_DECNRCM = 42
48320bd37d32Smrg    ,srm_MARGIN_BELL = 44
48330bd37d32Smrg    ,srm_REVERSEWRAP = 45
48340bd37d32Smrg#ifdef ALLOWLOGGING
48350bd37d32Smrg    ,srm_ALLOWLOGGING = 46
48360bd37d32Smrg#endif
48370bd37d32Smrg    ,srm_OPT_ALTBUF_CURSOR = 1049
48380bd37d32Smrg    ,srm_OPT_ALTBUF = 1047
48390bd37d32Smrg    ,srm_ALTBUF = 47
48400bd37d32Smrg    ,srm_DECNKM = 66
48410bd37d32Smrg    ,srm_DECBKM = 67
48420bd37d32Smrg    ,srm_DECLRMM = 69
48430bd37d32Smrg    ,srm_DECNCSM = 95
48440bd37d32Smrg    ,srm_VT200_MOUSE = SET_VT200_MOUSE
48450bd37d32Smrg    ,srm_VT200_HIGHLIGHT_MOUSE = SET_VT200_HIGHLIGHT_MOUSE
48460bd37d32Smrg    ,srm_BTN_EVENT_MOUSE = SET_BTN_EVENT_MOUSE
48470bd37d32Smrg    ,srm_ANY_EVENT_MOUSE = SET_ANY_EVENT_MOUSE
48480bd37d32Smrg#if OPT_FOCUS_EVENT
48490bd37d32Smrg    ,srm_FOCUS_EVENT_MOUSE = SET_FOCUS_EVENT_MOUSE
48500bd37d32Smrg#endif
48510bd37d32Smrg    ,srm_EXT_MODE_MOUSE = SET_EXT_MODE_MOUSE
48520bd37d32Smrg    ,srm_SGR_EXT_MODE_MOUSE = SET_SGR_EXT_MODE_MOUSE
48530bd37d32Smrg    ,srm_URXVT_EXT_MODE_MOUSE = SET_URXVT_EXT_MODE_MOUSE
48540bd37d32Smrg    ,srm_ALTERNATE_SCROLL = SET_ALTERNATE_SCROLL
48550bd37d32Smrg    ,srm_RXVT_SCROLL_TTY_OUTPUT = 1010
48560bd37d32Smrg    ,srm_RXVT_SCROLL_TTY_KEYPRESS = 1011
48570bd37d32Smrg    ,srm_EIGHT_BIT_META = 1034
48580bd37d32Smrg#if OPT_NUM_LOCK
48590bd37d32Smrg    ,srm_REAL_NUMLOCK = 1035
48600bd37d32Smrg    ,srm_META_SENDS_ESC = 1036
48610bd37d32Smrg#endif
48620bd37d32Smrg    ,srm_DELETE_IS_DEL = 1037
48630bd37d32Smrg#if OPT_NUM_LOCK
48640bd37d32Smrg    ,srm_ALT_SENDS_ESC = 1039
48650bd37d32Smrg#endif
48660bd37d32Smrg    ,srm_KEEP_SELECTION = 1040
48670bd37d32Smrg    ,srm_SELECT_TO_CLIPBOARD = 1041
48680bd37d32Smrg    ,srm_BELL_IS_URGENT = 1042
48690bd37d32Smrg    ,srm_POP_ON_BELL = 1043
48700bd37d32Smrg    ,srm_TITE_INHIBIT = 1048
48710bd37d32Smrg#if OPT_TCAP_FKEYS
48720bd37d32Smrg    ,srm_TCAP_FKEYS = 1050
48730bd37d32Smrg#endif
48740bd37d32Smrg#if OPT_SUN_FUNC_KEYS
48750bd37d32Smrg    ,srm_SUN_FKEYS = 1051
48760bd37d32Smrg#endif
48770bd37d32Smrg#if OPT_HP_FUNC_KEYS
48780bd37d32Smrg    ,srm_HP_FKEYS = 1052
48790bd37d32Smrg#endif
48800bd37d32Smrg#if OPT_SCO_FUNC_KEYS
48810bd37d32Smrg    ,srm_SCO_FKEYS = 1053
48820bd37d32Smrg#endif
48830bd37d32Smrg    ,srm_LEGACY_FKEYS = 1060
48840bd37d32Smrg#if OPT_SUNPC_KBD
48850bd37d32Smrg    ,srm_VT220_FKEYS = 1061
48860bd37d32Smrg#endif
48870bd37d32Smrg#if OPT_READLINE
48880bd37d32Smrg    ,srm_BUTTON1_MOVE_POINT = SET_BUTTON1_MOVE_POINT
48890bd37d32Smrg    ,srm_BUTTON2_MOVE_POINT = SET_BUTTON2_MOVE_POINT
48900bd37d32Smrg    ,srm_DBUTTON3_DELETE = SET_DBUTTON3_DELETE
48910bd37d32Smrg    ,srm_PASTE_IN_BRACKET = SET_PASTE_IN_BRACKET
48920bd37d32Smrg    ,srm_PASTE_QUOTE = SET_PASTE_QUOTE
48930bd37d32Smrg    ,srm_PASTE_LITERAL_NL = SET_PASTE_LITERAL_NL
48940bd37d32Smrg#endif				/* OPT_READLINE */
48950bd37d32Smrg} DECSET_codes;
48960bd37d32Smrg
4897d522f475Smrg/*
4898d522f475Smrg * process DEC private modes set, reset
4899d522f475Smrg */
4900d522f475Smrgstatic void
490120d2c4d2Smrgdpmodes(XtermWidget xw, BitFunc func)
4902d522f475Smrg{
490320d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4904d522f475Smrg    int i, j;
49052eaa94a1Schristos    unsigned myflags;
4906d522f475Smrg
4907d522f475Smrg    for (i = 0; i < nparam; ++i) {
49080bd37d32Smrg	int code = GetParam(i);
49090bd37d32Smrg
49100bd37d32Smrg	TRACE(("%s %d\n", IsSM()? "DECSET" : "DECRST", code));
49110bd37d32Smrg	switch ((DECSET_codes) code) {
49120bd37d32Smrg	case srm_DECCKM:
4913d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_DECCKM);
4914d522f475Smrg	    update_appcursor();
4915d522f475Smrg	    break;
49160bd37d32Smrg	case srm_DECANM:	/* ANSI/VT52 mode      */
4917d522f475Smrg	    if (IsSM()) {	/* ANSI (VT100) */
4918d522f475Smrg		/*
4919d522f475Smrg		 * Setting DECANM should have no effect, since this function
4920d522f475Smrg		 * cannot be reached from vt52 mode.
4921d522f475Smrg		 */
4922a1f3da82Smrg		/* EMPTY */ ;
4923d522f475Smrg	    }
4924d522f475Smrg#if OPT_VT52_MODE
4925d522f475Smrg	    else if (screen->terminal_id >= 100) {	/* VT52 */
4926d522f475Smrg		TRACE(("DECANM terminal_id %d, vtXX_level %d\n",
4927d522f475Smrg		       screen->terminal_id,
4928d522f475Smrg		       screen->vtXX_level));
4929d522f475Smrg		screen->vtXX_level = 0;
4930d522f475Smrg		screen->vt52_save_curgl = screen->curgl;
4931d522f475Smrg		screen->vt52_save_curgr = screen->curgr;
4932d522f475Smrg		screen->vt52_save_curss = screen->curss;
4933d522f475Smrg		memmove(screen->vt52_save_gsets, screen->gsets, sizeof(screen->gsets));
4934d522f475Smrg		resetCharsets(screen);
49350bd37d32Smrg		InitParams();	/* ignore the remaining params, if any */
4936d522f475Smrg	    }
4937d522f475Smrg#endif
4938d522f475Smrg	    break;
49390bd37d32Smrg	case srm_DECCOLM:
4940d522f475Smrg	    if (screen->c132) {
49410bd37d32Smrg		if (!(xw->flags & NOCLEAR_COLM))
49420bd37d32Smrg		    ClearScreen(xw);
4943d522f475Smrg		CursorSet(screen, 0, 0, xw->flags);
4944d522f475Smrg		if ((j = IsSM()? 132 : 80) !=
4945d522f475Smrg		    ((xw->flags & IN132COLUMNS) ? 132 : 80) ||
4946d522f475Smrg		    j != MaxCols(screen))
4947d522f475Smrg		    RequestResize(xw, -1, j, True);
4948d522f475Smrg		(*func) (&xw->flags, IN132COLUMNS);
49490bd37d32Smrg		if (xw->flags & IN132COLUMNS) {
49500bd37d32Smrg		    UIntClr(xw->flags, LEFT_RIGHT);
49510bd37d32Smrg		    reset_lr_margins(screen);
49520bd37d32Smrg		}
4953d522f475Smrg	    }
4954d522f475Smrg	    break;
49550bd37d32Smrg	case srm_DECSCLM:	/* (slow scroll)        */
4956d522f475Smrg	    if (IsSM()) {
4957d522f475Smrg		screen->jumpscroll = 0;
4958d522f475Smrg		if (screen->scroll_amt)
4959d522f475Smrg		    FlushScroll(xw);
4960d522f475Smrg	    } else
4961d522f475Smrg		screen->jumpscroll = 1;
4962d522f475Smrg	    (*func) (&xw->flags, SMOOTHSCROLL);
4963d522f475Smrg	    update_jumpscroll();
4964d522f475Smrg	    break;
49650bd37d32Smrg	case srm_DECSCNM:
49662eaa94a1Schristos	    myflags = xw->flags;
4967d522f475Smrg	    (*func) (&xw->flags, REVERSE_VIDEO);
49682eaa94a1Schristos	    if ((xw->flags ^ myflags) & REVERSE_VIDEO)
4969d522f475Smrg		ReverseVideo(xw);
4970d522f475Smrg	    /* update_reversevideo done in RevVid */
4971d522f475Smrg	    break;
4972d522f475Smrg
49730bd37d32Smrg	case srm_DECOM:
4974d522f475Smrg	    (*func) (&xw->flags, ORIGIN);
4975d522f475Smrg	    CursorSet(screen, 0, 0, xw->flags);
4976d522f475Smrg	    break;
4977d522f475Smrg
49780bd37d32Smrg	case srm_DECAWM:
4979d522f475Smrg	    (*func) (&xw->flags, WRAPAROUND);
4980d522f475Smrg	    update_autowrap();
4981d522f475Smrg	    break;
49820bd37d32Smrg	case srm_DECARM:
4983d522f475Smrg	    /* ignore autorepeat
4984d522f475Smrg	     * XAutoRepeatOn() and XAutoRepeatOff() can do this, but only
4985d522f475Smrg	     * for the whole display - not limited to a given window.
4986d522f475Smrg	     */
4987d522f475Smrg	    break;
49880bd37d32Smrg	case srm_X10_MOUSE:	/* MIT bogus sequence           */
4989d522f475Smrg	    MotionOff(screen, xw);
4990d522f475Smrg	    set_mousemode(X10_MOUSE);
4991d522f475Smrg	    break;
4992d522f475Smrg#if OPT_TOOLBAR
49930bd37d32Smrg	case srm_RXVT_TOOLBAR:
4994d522f475Smrg	    ShowToolbar(IsSM());
4995d522f475Smrg	    break;
4996d522f475Smrg#endif
4997d522f475Smrg#if OPT_BLINK_CURS
49980bd37d32Smrg	case srm_ATT610_BLINK:	/* att610: Start/stop blinking cursor */
4999d522f475Smrg	    if (screen->cursor_blink_res) {
5000d522f475Smrg		set_bool_mode(screen->cursor_blink_esc);
50010bd37d32Smrg		UpdateCursorBlink(screen);
5002d522f475Smrg	    }
5003d522f475Smrg	    break;
5004d522f475Smrg#endif
50050bd37d32Smrg	case srm_DECPFF:	/* print form feed */
5006e39b573cSmrg	    set_bool_mode(PrinterOf(screen).printer_formfeed);
5007d522f475Smrg	    break;
50080bd37d32Smrg	case srm_DECPEX:	/* print extent */
5009e39b573cSmrg	    set_bool_mode(PrinterOf(screen).printer_extent);
5010d522f475Smrg	    break;
50110bd37d32Smrg	case srm_DECTCEM:	/* Show/hide cursor (VT200) */
5012d522f475Smrg	    set_bool_mode(screen->cursor_set);
5013d522f475Smrg	    break;
50140bd37d32Smrg	case srm_RXVT_SCROLLBAR:
5015d522f475Smrg	    if (screen->fullVwin.sb_info.width != (IsSM()? ON : OFF))
5016d522f475Smrg		ToggleScrollBar(xw);
5017d522f475Smrg	    break;
5018d522f475Smrg#if OPT_SHIFT_FONTS
50190bd37d32Smrg	case srm_RXVT_FONTSIZE:
5020d522f475Smrg	    set_bool_mode(xw->misc.shift_fonts);
5021d522f475Smrg	    break;
5022d522f475Smrg#endif
5023d522f475Smrg#if OPT_TEK4014
50240bd37d32Smrg	case srm_DECTEK:
5025d522f475Smrg	    if (IsSM() && !(screen->inhibit & I_TEK)) {
502620d2c4d2Smrg		FlushLog(xw);
5027d522f475Smrg		TEK4014_ACTIVE(xw) = True;
50280bd37d32Smrg		update_vttekmode();
5029d522f475Smrg	    }
5030d522f475Smrg	    break;
50310bd37d32Smrg#endif
50320bd37d32Smrg	case srm_132COLS:	/* 132 column mode              */
5033d522f475Smrg	    set_bool_mode(screen->c132);
5034d522f475Smrg	    update_allow132();
5035d522f475Smrg	    break;
50360bd37d32Smrg	case srm_CURSES_HACK:
5037d522f475Smrg	    set_bool_mode(screen->curses);
5038d522f475Smrg	    update_cursesemul();
5039d522f475Smrg	    break;
50400bd37d32Smrg	case srm_DECNRCM:	/* national charset (VT220) */
5041d522f475Smrg	    (*func) (&xw->flags, NATIONAL);
5042d522f475Smrg	    break;
50430bd37d32Smrg	case srm_MARGIN_BELL:	/* margin bell                  */
5044d522f475Smrg	    set_bool_mode(screen->marginbell);
5045d522f475Smrg	    if (!screen->marginbell)
504620d2c4d2Smrg		screen->bellArmed = -1;
5047d522f475Smrg	    update_marginbell();
5048d522f475Smrg	    break;
50490bd37d32Smrg	case srm_REVERSEWRAP:	/* reverse wraparound   */
5050d522f475Smrg	    (*func) (&xw->flags, REVERSEWRAP);
5051d522f475Smrg	    update_reversewrap();
5052d522f475Smrg	    break;
5053d522f475Smrg#ifdef ALLOWLOGGING
50540bd37d32Smrg	case srm_ALLOWLOGGING:	/* logging              */
5055d522f475Smrg#ifdef ALLOWLOGFILEONOFF
5056d522f475Smrg	    /*
5057d522f475Smrg	     * if this feature is enabled, logging may be
5058d522f475Smrg	     * enabled and disabled via escape sequences.
5059d522f475Smrg	     */
5060d522f475Smrg	    if (IsSM())
506120d2c4d2Smrg		StartLog(xw);
5062d522f475Smrg	    else
506320d2c4d2Smrg		CloseLog(xw);
5064d522f475Smrg#else
506520d2c4d2Smrg	    Bell(xw, XkbBI_Info, 0);
506620d2c4d2Smrg	    Bell(xw, XkbBI_Info, 0);
5067d522f475Smrg#endif /* ALLOWLOGFILEONOFF */
5068d522f475Smrg	    break;
5069d522f475Smrg#endif
50700bd37d32Smrg	case srm_OPT_ALTBUF_CURSOR:	/* alternate buffer & cursor */
5071d522f475Smrg	    if (!xw->misc.titeInhibit) {
5072d522f475Smrg		if (IsSM()) {
5073d522f475Smrg		    CursorSave(xw);
5074d522f475Smrg		    ToAlternate(xw);
5075d522f475Smrg		    ClearScreen(xw);
5076d522f475Smrg		} else {
5077d522f475Smrg		    FromAlternate(xw);
5078d522f475Smrg		    CursorRestore(xw);
5079d522f475Smrg		}
50800bd37d32Smrg	    } else if (IsSM()) {
50810bd37d32Smrg		do_ti_xtra_scroll(xw);
5082d522f475Smrg	    }
5083d522f475Smrg	    break;
50840bd37d32Smrg	case srm_OPT_ALTBUF:
5085d522f475Smrg	    /* FALLTHRU */
50860bd37d32Smrg	case srm_ALTBUF:	/* alternate buffer */
5087d522f475Smrg	    if (!xw->misc.titeInhibit) {
5088d522f475Smrg		if (IsSM()) {
5089d522f475Smrg		    ToAlternate(xw);
5090d522f475Smrg		} else {
5091956cc18dSsnj		    if (screen->whichBuf
50920bd37d32Smrg			&& (code == 1047))
5093d522f475Smrg			ClearScreen(xw);
5094d522f475Smrg		    FromAlternate(xw);
5095d522f475Smrg		}
50960bd37d32Smrg	    } else if (IsSM()) {
50970bd37d32Smrg		do_ti_xtra_scroll(xw);
5098d522f475Smrg	    }
5099d522f475Smrg	    break;
51000bd37d32Smrg	case srm_DECNKM:
5101d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_DECKPAM);
5102d522f475Smrg	    update_appkeypad();
5103d522f475Smrg	    break;
51040bd37d32Smrg	case srm_DECBKM:
5105d522f475Smrg	    /* back-arrow mapped to backspace or delete(D) */
5106d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_DECBKM);
5107d522f475Smrg	    TRACE(("DECSET DECBKM %s\n",
5108d522f475Smrg		   BtoS(xw->keyboard.flags & MODE_DECBKM)));
5109d522f475Smrg	    update_decbkm();
5110d522f475Smrg	    break;
51110bd37d32Smrg	case srm_DECLRMM:
51120bd37d32Smrg	    if (screen->vtXX_level >= 4) {	/* VT420 */
51130bd37d32Smrg		(*func) (&xw->flags, LEFT_RIGHT);
51140bd37d32Smrg		if (IsLeftRightMode(xw)) {
51150bd37d32Smrg		    xterm_ResetDouble(xw);
51160bd37d32Smrg		} else {
51170bd37d32Smrg		    reset_lr_margins(screen);
51180bd37d32Smrg		}
51190bd37d32Smrg		CursorSet(screen, 0, 0, xw->flags);
51200bd37d32Smrg	    }
51210bd37d32Smrg	    break;
51220bd37d32Smrg	case srm_DECNCSM:
51230bd37d32Smrg	    if (screen->vtXX_level >= 5) {	/* VT510 */
51240bd37d32Smrg		(*func) (&xw->flags, NOCLEAR_COLM);
51250bd37d32Smrg	    }
51260bd37d32Smrg	    break;
51270bd37d32Smrg	case srm_VT200_MOUSE:	/* xterm bogus sequence         */
5128d522f475Smrg	    MotionOff(screen, xw);
5129d522f475Smrg	    set_mousemode(VT200_MOUSE);
5130d522f475Smrg	    break;
51310bd37d32Smrg	case srm_VT200_HIGHLIGHT_MOUSE:	/* xterm sequence w/hilite tracking */
5132d522f475Smrg	    MotionOff(screen, xw);
5133d522f475Smrg	    set_mousemode(VT200_HIGHLIGHT_MOUSE);
5134d522f475Smrg	    break;
51350bd37d32Smrg	case srm_BTN_EVENT_MOUSE:
5136d522f475Smrg	    MotionOff(screen, xw);
5137d522f475Smrg	    set_mousemode(BTN_EVENT_MOUSE);
5138d522f475Smrg	    break;
51390bd37d32Smrg	case srm_ANY_EVENT_MOUSE:
5140d522f475Smrg	    set_mousemode(ANY_EVENT_MOUSE);
5141d522f475Smrg	    if (screen->send_mouse_pos == MOUSE_OFF) {
5142d522f475Smrg		MotionOff(screen, xw);
5143d522f475Smrg	    } else {
5144d522f475Smrg		MotionOn(screen, xw);
5145d522f475Smrg	    }
5146d522f475Smrg	    break;
5147d522f475Smrg#if OPT_FOCUS_EVENT
51480bd37d32Smrg	case srm_FOCUS_EVENT_MOUSE:
5149d522f475Smrg	    set_bool_mode(screen->send_focus_pos);
5150d522f475Smrg	    break;
5151d522f475Smrg#endif
51520bd37d32Smrg	case srm_EXT_MODE_MOUSE:
51530bd37d32Smrg	    /* FALLTHRU */
51540bd37d32Smrg	case srm_SGR_EXT_MODE_MOUSE:
51550bd37d32Smrg	    /* FALLTHRU */
51560bd37d32Smrg	case srm_URXVT_EXT_MODE_MOUSE:
51570bd37d32Smrg	    /*
51580bd37d32Smrg	     * Rather than choose an arbitrary precedence among the coordinate
51590bd37d32Smrg	     * modes, they are mutually exclusive.  For consistency, a reset is
51600bd37d32Smrg	     * only effective against the matching mode.
51610bd37d32Smrg	     */
51620bd37d32Smrg	    if (IsSM()) {
51630bd37d32Smrg		screen->extend_coords = code;
51640bd37d32Smrg	    } else if (screen->extend_coords == code) {
51650bd37d32Smrg		screen->extend_coords = 0;
51660bd37d32Smrg	    }
51670bd37d32Smrg	    break;
51680bd37d32Smrg	case srm_ALTERNATE_SCROLL:
51690bd37d32Smrg	    set_bool_mode(screen->alternateScroll);
5170492d43a5Smrg	    break;
51710bd37d32Smrg	case srm_RXVT_SCROLL_TTY_OUTPUT:
5172d522f475Smrg	    set_bool_mode(screen->scrollttyoutput);
5173d522f475Smrg	    update_scrollttyoutput();
5174d522f475Smrg	    break;
51750bd37d32Smrg	case srm_RXVT_SCROLL_TTY_KEYPRESS:
5176d522f475Smrg	    set_bool_mode(screen->scrollkey);
5177d522f475Smrg	    update_scrollkey();
5178d522f475Smrg	    break;
51790bd37d32Smrg	case srm_EIGHT_BIT_META:
51800bd37d32Smrg	    if (screen->eight_bit_meta != ebNever) {
51810bd37d32Smrg		set_bool_mode(screen->eight_bit_meta);
51820bd37d32Smrg	    }
5183d522f475Smrg	    break;
5184d522f475Smrg#if OPT_NUM_LOCK
51850bd37d32Smrg	case srm_REAL_NUMLOCK:
5186d522f475Smrg	    set_bool_mode(xw->misc.real_NumLock);
5187d522f475Smrg	    update_num_lock();
5188d522f475Smrg	    break;
51890bd37d32Smrg	case srm_META_SENDS_ESC:
5190d522f475Smrg	    set_bool_mode(screen->meta_sends_esc);
5191d522f475Smrg	    update_meta_esc();
5192d522f475Smrg	    break;
5193d522f475Smrg#endif
51940bd37d32Smrg	case srm_DELETE_IS_DEL:
5195d522f475Smrg	    set_bool_mode(screen->delete_is_del);
5196d522f475Smrg	    update_delete_del();
5197d522f475Smrg	    break;
5198d522f475Smrg#if OPT_NUM_LOCK
51990bd37d32Smrg	case srm_ALT_SENDS_ESC:
5200d522f475Smrg	    set_bool_mode(screen->alt_sends_esc);
5201d522f475Smrg	    update_alt_esc();
5202d522f475Smrg	    break;
5203d522f475Smrg#endif
52040bd37d32Smrg	case srm_KEEP_SELECTION:
5205d522f475Smrg	    set_bool_mode(screen->keepSelection);
5206d522f475Smrg	    update_keepSelection();
5207d522f475Smrg	    break;
52080bd37d32Smrg	case srm_SELECT_TO_CLIPBOARD:
5209d522f475Smrg	    set_bool_mode(screen->selectToClipboard);
5210d522f475Smrg	    update_selectToClipboard();
5211d522f475Smrg	    break;
52120bd37d32Smrg	case srm_BELL_IS_URGENT:
5213d522f475Smrg	    set_bool_mode(screen->bellIsUrgent);
5214d522f475Smrg	    update_bellIsUrgent();
5215d522f475Smrg	    break;
52160bd37d32Smrg	case srm_POP_ON_BELL:
5217d522f475Smrg	    set_bool_mode(screen->poponbell);
5218d522f475Smrg	    update_poponbell();
5219d522f475Smrg	    break;
52200bd37d32Smrg	case srm_TITE_INHIBIT:
5221d522f475Smrg	    if (!xw->misc.titeInhibit) {
5222d522f475Smrg		if (IsSM())
5223d522f475Smrg		    CursorSave(xw);
5224d522f475Smrg		else
5225d522f475Smrg		    CursorRestore(xw);
5226d522f475Smrg	    }
5227d522f475Smrg	    break;
5228d522f475Smrg#if OPT_TCAP_FKEYS
52290bd37d32Smrg	case srm_TCAP_FKEYS:
5230d522f475Smrg	    set_keyboard_type(xw, keyboardIsTermcap, IsSM());
5231d522f475Smrg	    break;
5232d522f475Smrg#endif
5233d522f475Smrg#if OPT_SUN_FUNC_KEYS
52340bd37d32Smrg	case srm_SUN_FKEYS:
5235d522f475Smrg	    set_keyboard_type(xw, keyboardIsSun, IsSM());
5236d522f475Smrg	    break;
5237d522f475Smrg#endif
5238d522f475Smrg#if OPT_HP_FUNC_KEYS
52390bd37d32Smrg	case srm_HP_FKEYS:
5240d522f475Smrg	    set_keyboard_type(xw, keyboardIsHP, IsSM());
5241d522f475Smrg	    break;
5242d522f475Smrg#endif
5243d522f475Smrg#if OPT_SCO_FUNC_KEYS
52440bd37d32Smrg	case srm_SCO_FKEYS:
5245d522f475Smrg	    set_keyboard_type(xw, keyboardIsSCO, IsSM());
5246d522f475Smrg	    break;
5247d522f475Smrg#endif
52480bd37d32Smrg	case srm_LEGACY_FKEYS:
5249d522f475Smrg	    set_keyboard_type(xw, keyboardIsLegacy, IsSM());
5250d522f475Smrg	    break;
5251d522f475Smrg#if OPT_SUNPC_KBD
52520bd37d32Smrg	case srm_VT220_FKEYS:
5253d522f475Smrg	    set_keyboard_type(xw, keyboardIsVT220, IsSM());
5254d522f475Smrg	    break;
5255d522f475Smrg#endif
5256d522f475Smrg#if OPT_READLINE
52570bd37d32Smrg	case srm_BUTTON1_MOVE_POINT:
5258d522f475Smrg	    set_mouseflag(click1_moves);
5259d522f475Smrg	    break;
52600bd37d32Smrg	case srm_BUTTON2_MOVE_POINT:
5261d522f475Smrg	    set_mouseflag(paste_moves);
5262d522f475Smrg	    break;
52630bd37d32Smrg	case srm_DBUTTON3_DELETE:
5264d522f475Smrg	    set_mouseflag(dclick3_deletes);
5265d522f475Smrg	    break;
52660bd37d32Smrg	case srm_PASTE_IN_BRACKET:
5267d522f475Smrg	    set_mouseflag(paste_brackets);
5268d522f475Smrg	    break;
52690bd37d32Smrg	case srm_PASTE_QUOTE:
5270d522f475Smrg	    set_mouseflag(paste_quotes);
5271d522f475Smrg	    break;
52720bd37d32Smrg	case srm_PASTE_LITERAL_NL:
5273d522f475Smrg	    set_mouseflag(paste_literal_nl);
5274d522f475Smrg	    break;
5275d522f475Smrg#endif /* OPT_READLINE */
5276d522f475Smrg	}
5277d522f475Smrg    }
5278d522f475Smrg}
5279d522f475Smrg
5280d522f475Smrg/*
5281d522f475Smrg * process xterm private modes save
5282d522f475Smrg */
5283d522f475Smrgstatic void
5284d522f475Smrgsavemodes(XtermWidget xw)
5285d522f475Smrg{
528620d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
5287d522f475Smrg    int i;
5288d522f475Smrg
5289d522f475Smrg    for (i = 0; i < nparam; i++) {
52900bd37d32Smrg	int code = GetParam(i);
52910bd37d32Smrg
52920bd37d32Smrg	TRACE(("savemodes %d\n", code));
52930bd37d32Smrg	switch ((DECSET_codes) code) {
52940bd37d32Smrg	case srm_DECCKM:
5295d522f475Smrg	    DoSM(DP_DECCKM, xw->keyboard.flags & MODE_DECCKM);
5296d522f475Smrg	    break;
52970bd37d32Smrg	case srm_DECANM:	/* ANSI/VT52 mode      */
52980bd37d32Smrg	    /* no effect */
52990bd37d32Smrg	    break;
53000bd37d32Smrg	case srm_DECCOLM:
5301d522f475Smrg	    if (screen->c132)
5302d522f475Smrg		DoSM(DP_DECCOLM, xw->flags & IN132COLUMNS);
5303d522f475Smrg	    break;
53040bd37d32Smrg	case srm_DECSCLM:	/* (slow scroll)        */
5305d522f475Smrg	    DoSM(DP_DECSCLM, xw->flags & SMOOTHSCROLL);
5306d522f475Smrg	    break;
53070bd37d32Smrg	case srm_DECSCNM:
5308d522f475Smrg	    DoSM(DP_DECSCNM, xw->flags & REVERSE_VIDEO);
5309d522f475Smrg	    break;
53100bd37d32Smrg	case srm_DECOM:
5311d522f475Smrg	    DoSM(DP_DECOM, xw->flags & ORIGIN);
5312d522f475Smrg	    break;
53130bd37d32Smrg	case srm_DECAWM:
5314d522f475Smrg	    DoSM(DP_DECAWM, xw->flags & WRAPAROUND);
5315d522f475Smrg	    break;
53160bd37d32Smrg	case srm_DECARM:
5317d522f475Smrg	    /* ignore autorepeat */
5318d522f475Smrg	    break;
53190bd37d32Smrg	case srm_X10_MOUSE:	/* mouse bogus sequence */
5320d522f475Smrg	    DoSM(DP_X_X10MSE, screen->send_mouse_pos);
5321d522f475Smrg	    break;
5322d522f475Smrg#if OPT_TOOLBAR
53230bd37d32Smrg	case srm_RXVT_TOOLBAR:
5324d522f475Smrg	    DoSM(DP_TOOLBAR, resource.toolBar);
5325d522f475Smrg	    break;
5326d522f475Smrg#endif
5327d522f475Smrg#if OPT_BLINK_CURS
53280bd37d32Smrg	case srm_ATT610_BLINK:	/* att610: Start/stop blinking cursor */
5329d522f475Smrg	    if (screen->cursor_blink_res) {
5330d522f475Smrg		DoSM(DP_CRS_BLINK, screen->cursor_blink_esc);
5331d522f475Smrg	    }
5332d522f475Smrg	    break;
5333d522f475Smrg#endif
53340bd37d32Smrg	case srm_DECPFF:	/* print form feed */
5335e39b573cSmrg	    DoSM(DP_PRN_FORMFEED, PrinterOf(screen).printer_formfeed);
5336d522f475Smrg	    break;
53370bd37d32Smrg	case srm_DECPEX:	/* print extent */
5338e39b573cSmrg	    DoSM(DP_PRN_EXTENT, PrinterOf(screen).printer_extent);
5339d522f475Smrg	    break;
53400bd37d32Smrg	case srm_DECTCEM:	/* Show/hide cursor (VT200) */
5341d522f475Smrg	    DoSM(DP_CRS_VISIBLE, screen->cursor_set);
5342d522f475Smrg	    break;
53430bd37d32Smrg	case srm_RXVT_SCROLLBAR:
53440bd37d32Smrg	    DoSM(DP_RXVT_SCROLLBAR, (screen->fullVwin.sb_info.width != 0));
53450bd37d32Smrg	    break;
53460bd37d32Smrg#if OPT_SHIFT_FONTS
53470bd37d32Smrg	case srm_RXVT_FONTSIZE:
53480bd37d32Smrg	    DoSM(DP_RXVT_FONTSIZE, xw->misc.shift_fonts);
53490bd37d32Smrg	    break;
53500bd37d32Smrg#endif
53510bd37d32Smrg#if OPT_TEK4014
53520bd37d32Smrg	case srm_DECTEK:
53530bd37d32Smrg	    DoSM(DP_DECTEK, TEK4014_ACTIVE(xw));
53540bd37d32Smrg	    break;
53550bd37d32Smrg#endif
53560bd37d32Smrg	case srm_132COLS:	/* 132 column mode              */
5357d522f475Smrg	    DoSM(DP_X_DECCOLM, screen->c132);
5358d522f475Smrg	    break;
53590bd37d32Smrg	case srm_CURSES_HACK:	/* curses hack                  */
5360d522f475Smrg	    DoSM(DP_X_MORE, screen->curses);
5361d522f475Smrg	    break;
53620bd37d32Smrg	case srm_DECNRCM:	/* national charset (VT220) */
53630bd37d32Smrg	    DoSM(DP_DECNRCM, xw->flags & NATIONAL);
5364d522f475Smrg	    break;
53650bd37d32Smrg	case srm_MARGIN_BELL:	/* margin bell                  */
5366d522f475Smrg	    DoSM(DP_X_MARGIN, screen->marginbell);
5367d522f475Smrg	    break;
53680bd37d32Smrg	case srm_REVERSEWRAP:	/* reverse wraparound   */
5369d522f475Smrg	    DoSM(DP_X_REVWRAP, xw->flags & REVERSEWRAP);
5370d522f475Smrg	    break;
5371d522f475Smrg#ifdef ALLOWLOGGING
53720bd37d32Smrg	case srm_ALLOWLOGGING:	/* logging              */
5373d522f475Smrg	    DoSM(DP_X_LOGGING, screen->logging);
5374d522f475Smrg	    break;
5375d522f475Smrg#endif
53760bd37d32Smrg	case srm_OPT_ALTBUF_CURSOR:
53770bd37d32Smrg	    /* FALLTHRU */
53780bd37d32Smrg	case srm_OPT_ALTBUF:
5379d522f475Smrg	    /* FALLTHRU */
53800bd37d32Smrg	case srm_ALTBUF:	/* alternate buffer             */
5381956cc18dSsnj	    DoSM(DP_X_ALTSCRN, screen->whichBuf);
5382d522f475Smrg	    break;
53830bd37d32Smrg	case srm_DECNKM:
53840bd37d32Smrg	    DoSM(DP_DECKPAM, xw->keyboard.flags & MODE_DECKPAM);
53850bd37d32Smrg	    break;
53860bd37d32Smrg	case srm_DECBKM:
53870bd37d32Smrg	    DoSM(DP_DECBKM, xw->keyboard.flags & MODE_DECBKM);
53880bd37d32Smrg	    break;
53890bd37d32Smrg	case srm_DECLRMM:	/* left-right */
53900bd37d32Smrg	    DoSM(DP_X_LRMM, LEFT_RIGHT);
53910bd37d32Smrg	    break;
53920bd37d32Smrg	case srm_DECNCSM:	/* noclear */
53930bd37d32Smrg	    DoSM(DP_X_NCSM, NOCLEAR_COLM);
53940bd37d32Smrg	    break;
53950bd37d32Smrg	case srm_VT200_MOUSE:	/* mouse bogus sequence         */
53960bd37d32Smrg	case srm_VT200_HIGHLIGHT_MOUSE:
53970bd37d32Smrg	case srm_BTN_EVENT_MOUSE:
53980bd37d32Smrg	case srm_ANY_EVENT_MOUSE:
5399d522f475Smrg	    DoSM(DP_X_MOUSE, screen->send_mouse_pos);
5400d522f475Smrg	    break;
5401d522f475Smrg#if OPT_FOCUS_EVENT
54020bd37d32Smrg	case srm_FOCUS_EVENT_MOUSE:
5403d522f475Smrg	    DoSM(DP_X_FOCUS, screen->send_focus_pos);
5404d522f475Smrg	    break;
5405d522f475Smrg#endif
54060bd37d32Smrg	case srm_EXT_MODE_MOUSE:
54070bd37d32Smrg	    /* FALLTHRU */
54080bd37d32Smrg	case srm_SGR_EXT_MODE_MOUSE:
54090bd37d32Smrg	    /* FALLTHRU */
54100bd37d32Smrg	case srm_URXVT_EXT_MODE_MOUSE:
54110bd37d32Smrg	    DoSM(DP_X_EXT_MOUSE, screen->extend_coords);
54120bd37d32Smrg	    break;
54130bd37d32Smrg	case srm_ALTERNATE_SCROLL:
54140bd37d32Smrg	    DoSM(DP_ALTERNATE_SCROLL, screen->alternateScroll);
5415492d43a5Smrg	    break;
54160bd37d32Smrg	case srm_RXVT_SCROLL_TTY_OUTPUT:
54170bd37d32Smrg	    DoSM(DP_RXVT_SCROLL_TTY_OUTPUT, screen->scrollttyoutput);
54180bd37d32Smrg	    break;
54190bd37d32Smrg	case srm_RXVT_SCROLL_TTY_KEYPRESS:
54200bd37d32Smrg	    DoSM(DP_RXVT_SCROLL_TTY_KEYPRESS, screen->scrollkey);
54210bd37d32Smrg	    break;
54220bd37d32Smrg	case srm_EIGHT_BIT_META:
54230bd37d32Smrg	    DoSM(DP_EIGHT_BIT_META, screen->eight_bit_meta);
54240bd37d32Smrg	    break;
54250bd37d32Smrg#if OPT_NUM_LOCK
54260bd37d32Smrg	case srm_REAL_NUMLOCK:
54270bd37d32Smrg	    DoSM(DP_REAL_NUMLOCK, xw->misc.real_NumLock);
54280bd37d32Smrg	    break;
54290bd37d32Smrg	case srm_META_SENDS_ESC:
54300bd37d32Smrg	    DoSM(DP_META_SENDS_ESC, screen->meta_sends_esc);
54310bd37d32Smrg	    break;
54320bd37d32Smrg#endif
54330bd37d32Smrg	case srm_DELETE_IS_DEL:
54340bd37d32Smrg	    DoSM(DP_DELETE_IS_DEL, screen->delete_is_del);
54350bd37d32Smrg	    break;
54360bd37d32Smrg#if OPT_NUM_LOCK
54370bd37d32Smrg	case srm_ALT_SENDS_ESC:
54380bd37d32Smrg	    DoSM(DP_ALT_SENDS_ESC, screen->alt_sends_esc);
54390bd37d32Smrg	    break;
54400bd37d32Smrg#endif
54410bd37d32Smrg	case srm_KEEP_SELECTION:
54420bd37d32Smrg	    DoSM(DP_KEEP_SELECTION, screen->keepSelection);
54430bd37d32Smrg	    break;
54440bd37d32Smrg	case srm_SELECT_TO_CLIPBOARD:
54450bd37d32Smrg	    DoSM(DP_SELECT_TO_CLIPBOARD, screen->selectToClipboard);
54460bd37d32Smrg	    break;
54470bd37d32Smrg	case srm_BELL_IS_URGENT:
54480bd37d32Smrg	    DoSM(DP_BELL_IS_URGENT, screen->bellIsUrgent);
54490bd37d32Smrg	    break;
54500bd37d32Smrg	case srm_POP_ON_BELL:
54510bd37d32Smrg	    DoSM(DP_POP_ON_BELL, screen->poponbell);
54520bd37d32Smrg	    break;
54530bd37d32Smrg#if OPT_TCAP_FKEYS
54540bd37d32Smrg	case srm_TCAP_FKEYS:
54550bd37d32Smrg	    /* FALLTHRU */
54560bd37d32Smrg#endif
54570bd37d32Smrg#if OPT_SUN_FUNC_KEYS
54580bd37d32Smrg	case srm_SUN_FKEYS:
54590bd37d32Smrg	    /* FALLTHRU */
54600bd37d32Smrg#endif
54610bd37d32Smrg#if OPT_HP_FUNC_KEYS
54620bd37d32Smrg	case srm_HP_FKEYS:
54630bd37d32Smrg	    /* FALLTHRU */
54640bd37d32Smrg#endif
54650bd37d32Smrg#if OPT_SCO_FUNC_KEYS
54660bd37d32Smrg	case srm_SCO_FKEYS:
54670bd37d32Smrg	    /* FALLTHRU */
54680bd37d32Smrg#endif
54690bd37d32Smrg#if OPT_SUNPC_KBD
54700bd37d32Smrg	case srm_VT220_FKEYS:
54710bd37d32Smrg	    /* FALLTHRU */
54720bd37d32Smrg#endif
54730bd37d32Smrg	case srm_LEGACY_FKEYS:
54740bd37d32Smrg	    DoSM(DP_KEYBOARD_TYPE, xw->keyboard.type);
54750bd37d32Smrg	    break;
54760bd37d32Smrg	case srm_TITE_INHIBIT:
5477d522f475Smrg	    if (!xw->misc.titeInhibit) {
5478d522f475Smrg		CursorSave(xw);
5479d522f475Smrg	    }
5480d522f475Smrg	    break;
5481d522f475Smrg#if OPT_READLINE
54820bd37d32Smrg	case srm_BUTTON1_MOVE_POINT:
5483d522f475Smrg	    SCREEN_FLAG_save(screen, click1_moves);
5484d522f475Smrg	    break;
54850bd37d32Smrg	case srm_BUTTON2_MOVE_POINT:
5486d522f475Smrg	    SCREEN_FLAG_save(screen, paste_moves);
5487d522f475Smrg	    break;
54880bd37d32Smrg	case srm_DBUTTON3_DELETE:
5489d522f475Smrg	    SCREEN_FLAG_save(screen, dclick3_deletes);
5490d522f475Smrg	    break;
54910bd37d32Smrg	case srm_PASTE_IN_BRACKET:
5492d522f475Smrg	    SCREEN_FLAG_save(screen, paste_brackets);
5493d522f475Smrg	    break;
54940bd37d32Smrg	case srm_PASTE_QUOTE:
5495d522f475Smrg	    SCREEN_FLAG_save(screen, paste_quotes);
5496d522f475Smrg	    break;
54970bd37d32Smrg	case srm_PASTE_LITERAL_NL:
5498d522f475Smrg	    SCREEN_FLAG_save(screen, paste_literal_nl);
5499d522f475Smrg	    break;
5500d522f475Smrg#endif /* OPT_READLINE */
5501d522f475Smrg	}
5502d522f475Smrg    }
5503d522f475Smrg}
5504d522f475Smrg
5505d522f475Smrg/*
5506d522f475Smrg * process xterm private modes restore
5507d522f475Smrg */
5508d522f475Smrgstatic void
5509d522f475Smrgrestoremodes(XtermWidget xw)
5510d522f475Smrg{
551120d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
5512d522f475Smrg    int i, j;
5513d522f475Smrg
5514d522f475Smrg    for (i = 0; i < nparam; i++) {
55150bd37d32Smrg	int code = GetParam(i);
55160bd37d32Smrg
55170bd37d32Smrg	TRACE(("restoremodes %d\n", code));
55180bd37d32Smrg	switch ((DECSET_codes) code) {
55190bd37d32Smrg	case srm_DECCKM:
5520d522f475Smrg	    bitcpy(&xw->keyboard.flags,
5521d522f475Smrg		   screen->save_modes[DP_DECCKM], MODE_DECCKM);
5522d522f475Smrg	    update_appcursor();
5523d522f475Smrg	    break;
55240bd37d32Smrg	case srm_DECANM:	/* ANSI/VT52 mode      */
55250bd37d32Smrg	    /* no effect */
55260bd37d32Smrg	    break;
55270bd37d32Smrg	case srm_DECCOLM:
5528d522f475Smrg	    if (screen->c132) {
55290bd37d32Smrg		if (!(xw->flags & NOCLEAR_COLM))
55300bd37d32Smrg		    ClearScreen(xw);
5531d522f475Smrg		CursorSet(screen, 0, 0, xw->flags);
5532d522f475Smrg		if ((j = (screen->save_modes[DP_DECCOLM] & IN132COLUMNS)
5533d522f475Smrg		     ? 132 : 80) != ((xw->flags & IN132COLUMNS)
5534d522f475Smrg				     ? 132 : 80) || j != MaxCols(screen))
5535d522f475Smrg		    RequestResize(xw, -1, j, True);
5536d522f475Smrg		bitcpy(&xw->flags,
5537d522f475Smrg		       screen->save_modes[DP_DECCOLM],
5538d522f475Smrg		       IN132COLUMNS);
5539d522f475Smrg	    }
5540d522f475Smrg	    break;
55410bd37d32Smrg	case srm_DECSCLM:	/* (slow scroll)        */
5542d522f475Smrg	    if (screen->save_modes[DP_DECSCLM] & SMOOTHSCROLL) {
5543d522f475Smrg		screen->jumpscroll = 0;
5544d522f475Smrg		if (screen->scroll_amt)
5545d522f475Smrg		    FlushScroll(xw);
5546d522f475Smrg	    } else
5547d522f475Smrg		screen->jumpscroll = 1;
5548d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECSCLM], SMOOTHSCROLL);
5549d522f475Smrg	    update_jumpscroll();
5550d522f475Smrg	    break;
55510bd37d32Smrg	case srm_DECSCNM:
5552d522f475Smrg	    if ((screen->save_modes[DP_DECSCNM] ^ xw->flags) & REVERSE_VIDEO) {
5553d522f475Smrg		bitcpy(&xw->flags, screen->save_modes[DP_DECSCNM], REVERSE_VIDEO);
5554d522f475Smrg		ReverseVideo(xw);
5555d522f475Smrg		/* update_reversevideo done in RevVid */
5556d522f475Smrg	    }
5557d522f475Smrg	    break;
55580bd37d32Smrg	case srm_DECOM:
5559d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECOM], ORIGIN);
5560d522f475Smrg	    CursorSet(screen, 0, 0, xw->flags);
5561d522f475Smrg	    break;
5562d522f475Smrg
55630bd37d32Smrg	case srm_DECAWM:
5564d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECAWM], WRAPAROUND);
5565d522f475Smrg	    update_autowrap();
5566d522f475Smrg	    break;
55670bd37d32Smrg	case srm_DECARM:
5568d522f475Smrg	    /* ignore autorepeat */
5569d522f475Smrg	    break;
55700bd37d32Smrg	case srm_X10_MOUSE:	/* MIT bogus sequence           */
55712eaa94a1Schristos	    DoRM0(DP_X_X10MSE, screen->send_mouse_pos);
55720bd37d32Smrg	    really_set_mousemode(xw,
55730bd37d32Smrg				 screen->send_mouse_pos != MOUSE_OFF,
55740bd37d32Smrg				 (XtermMouseModes) screen->send_mouse_pos);
5575d522f475Smrg	    break;
5576d522f475Smrg#if OPT_TOOLBAR
55770bd37d32Smrg	case srm_RXVT_TOOLBAR:
5578d522f475Smrg	    DoRM(DP_TOOLBAR, resource.toolBar);
5579d522f475Smrg	    ShowToolbar(resource.toolBar);
5580d522f475Smrg	    break;
5581d522f475Smrg#endif
5582d522f475Smrg#if OPT_BLINK_CURS
55830bd37d32Smrg	case srm_ATT610_BLINK:	/* Start/stop blinking cursor */
5584d522f475Smrg	    if (screen->cursor_blink_res) {
5585d522f475Smrg		DoRM(DP_CRS_BLINK, screen->cursor_blink_esc);
55860bd37d32Smrg		UpdateCursorBlink(screen);
5587d522f475Smrg	    }
5588d522f475Smrg	    break;
5589d522f475Smrg#endif
55900bd37d32Smrg	case srm_DECPFF:	/* print form feed */
5591e39b573cSmrg	    DoRM(DP_PRN_FORMFEED, PrinterOf(screen).printer_formfeed);
5592d522f475Smrg	    break;
55930bd37d32Smrg	case srm_DECPEX:	/* print extent */
55940bd37d32Smrg	    DoRM(DP_PRN_EXTENT, PrinterOf(screen).printer_extent);
55950bd37d32Smrg	    break;
55960bd37d32Smrg	case srm_DECTCEM:	/* Show/hide cursor (VT200) */
55970bd37d32Smrg	    DoRM(DP_CRS_VISIBLE, screen->cursor_set);
55980bd37d32Smrg	    break;
55990bd37d32Smrg	case srm_RXVT_SCROLLBAR:
56000bd37d32Smrg	    if ((screen->fullVwin.sb_info.width != 0) !=
56010bd37d32Smrg		screen->save_modes[DP_RXVT_SCROLLBAR]) {
56020bd37d32Smrg		ToggleScrollBar(xw);
56030bd37d32Smrg	    }
56040bd37d32Smrg	    break;
56050bd37d32Smrg#if OPT_SHIFT_FONTS
56060bd37d32Smrg	case srm_RXVT_FONTSIZE:
56070bd37d32Smrg	    DoRM(DP_RXVT_FONTSIZE, xw->misc.shift_fonts);
5608d522f475Smrg	    break;
56090bd37d32Smrg#endif
56100bd37d32Smrg#if OPT_TEK4014
56110bd37d32Smrg	case srm_DECTEK:
56120bd37d32Smrg	    if (!(screen->inhibit & I_TEK) &&
56130bd37d32Smrg		(TEK4014_ACTIVE(xw) != (Boolean) screen->save_modes[DP_DECTEK])) {
56140bd37d32Smrg		FlushLog(xw);
56150bd37d32Smrg		TEK4014_ACTIVE(xw) = (Boolean) screen->save_modes[DP_DECTEK];
56160bd37d32Smrg		update_vttekmode();
56170bd37d32Smrg	    }
5618d522f475Smrg	    break;
56190bd37d32Smrg#endif
56200bd37d32Smrg	case srm_132COLS:	/* 132 column mode              */
5621d522f475Smrg	    DoRM(DP_X_DECCOLM, screen->c132);
5622d522f475Smrg	    update_allow132();
5623d522f475Smrg	    break;
56240bd37d32Smrg	case srm_CURSES_HACK:	/* curses hack                  */
5625d522f475Smrg	    DoRM(DP_X_MORE, screen->curses);
5626d522f475Smrg	    update_cursesemul();
5627d522f475Smrg	    break;
56280bd37d32Smrg	case srm_DECNRCM:	/* national charset (VT220) */
56290bd37d32Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECNRCM], NATIONAL);
56300bd37d32Smrg	    break;
56310bd37d32Smrg	case srm_MARGIN_BELL:	/* margin bell                  */
5632d522f475Smrg	    if ((DoRM(DP_X_MARGIN, screen->marginbell)) == 0)
563320d2c4d2Smrg		screen->bellArmed = -1;
5634d522f475Smrg	    update_marginbell();
5635d522f475Smrg	    break;
56360bd37d32Smrg	case srm_REVERSEWRAP:	/* reverse wraparound   */
5637d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_X_REVWRAP], REVERSEWRAP);
5638d522f475Smrg	    update_reversewrap();
5639d522f475Smrg	    break;
5640d522f475Smrg#ifdef ALLOWLOGGING
56410bd37d32Smrg	case srm_ALLOWLOGGING:	/* logging              */
5642d522f475Smrg#ifdef ALLOWLOGFILEONOFF
5643d522f475Smrg	    if (screen->save_modes[DP_X_LOGGING])
564420d2c4d2Smrg		StartLog(xw);
5645d522f475Smrg	    else
564620d2c4d2Smrg		CloseLog(xw);
5647d522f475Smrg#endif /* ALLOWLOGFILEONOFF */
5648d522f475Smrg	    /* update_logging done by StartLog and CloseLog */
5649d522f475Smrg	    break;
5650d522f475Smrg#endif
56510bd37d32Smrg	case srm_OPT_ALTBUF_CURSOR:	/* alternate buffer & cursor */
5652d522f475Smrg	    /* FALLTHRU */
56530bd37d32Smrg	case srm_OPT_ALTBUF:
56540bd37d32Smrg	    /* FALLTHRU */
56550bd37d32Smrg	case srm_ALTBUF:	/* alternate buffer */
5656d522f475Smrg	    if (!xw->misc.titeInhibit) {
5657d522f475Smrg		if (screen->save_modes[DP_X_ALTSCRN])
5658d522f475Smrg		    ToAlternate(xw);
5659d522f475Smrg		else
5660d522f475Smrg		    FromAlternate(xw);
5661d522f475Smrg		/* update_altscreen done by ToAlt and FromAlt */
56620bd37d32Smrg	    } else if (screen->save_modes[DP_X_ALTSCRN]) {
56630bd37d32Smrg		do_ti_xtra_scroll(xw);
56640bd37d32Smrg	    }
56650bd37d32Smrg	    break;
56660bd37d32Smrg	case srm_DECNKM:
56670bd37d32Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECKPAM], MODE_DECKPAM);
56680bd37d32Smrg	    update_appkeypad();
56690bd37d32Smrg	    break;
56700bd37d32Smrg	case srm_DECBKM:
56710bd37d32Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECBKM], MODE_DECBKM);
56720bd37d32Smrg	    update_decbkm();
56730bd37d32Smrg	    break;
56740bd37d32Smrg	case srm_DECLRMM:	/* left-right */
56750bd37d32Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_X_LRMM], LEFT_RIGHT);
56760bd37d32Smrg	    if (IsLeftRightMode(xw)) {
56770bd37d32Smrg		xterm_ResetDouble(xw);
56780bd37d32Smrg	    } else {
56790bd37d32Smrg		reset_lr_margins(screen);
5680d522f475Smrg	    }
56810bd37d32Smrg	    CursorSet(screen, 0, 0, xw->flags);
5682d522f475Smrg	    break;
56830bd37d32Smrg	case srm_DECNCSM:	/* noclear */
56840bd37d32Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_X_NCSM], NOCLEAR_COLM);
56850bd37d32Smrg	    break;
56860bd37d32Smrg	case srm_VT200_MOUSE:	/* mouse bogus sequence         */
56870bd37d32Smrg	case srm_VT200_HIGHLIGHT_MOUSE:
56880bd37d32Smrg	case srm_BTN_EVENT_MOUSE:
56890bd37d32Smrg	case srm_ANY_EVENT_MOUSE:
56902eaa94a1Schristos	    DoRM0(DP_X_MOUSE, screen->send_mouse_pos);
56910bd37d32Smrg	    really_set_mousemode(xw,
56920bd37d32Smrg				 screen->send_mouse_pos != MOUSE_OFF,
56930bd37d32Smrg				 (XtermMouseModes) screen->send_mouse_pos);
5694d522f475Smrg	    break;
5695d522f475Smrg#if OPT_FOCUS_EVENT
56960bd37d32Smrg	case srm_FOCUS_EVENT_MOUSE:
5697d522f475Smrg	    DoRM(DP_X_FOCUS, screen->send_focus_pos);
5698d522f475Smrg	    break;
5699d522f475Smrg#endif
57000bd37d32Smrg	case srm_EXT_MODE_MOUSE:
57010bd37d32Smrg	    /* FALLTHRU */
57020bd37d32Smrg	case srm_SGR_EXT_MODE_MOUSE:
57030bd37d32Smrg	    /* FALLTHRU */
57040bd37d32Smrg	case srm_URXVT_EXT_MODE_MOUSE:
57050bd37d32Smrg	    DoRM(DP_X_EXT_MOUSE, screen->extend_coords);
5706492d43a5Smrg	    break;
57070bd37d32Smrg	case srm_TITE_INHIBIT:
5708d522f475Smrg	    if (!xw->misc.titeInhibit) {
5709d522f475Smrg		CursorRestore(xw);
5710d522f475Smrg	    }
5711d522f475Smrg	    break;
57120bd37d32Smrg	case srm_ALTERNATE_SCROLL:
57130bd37d32Smrg	    DoRM(DP_ALTERNATE_SCROLL, screen->alternateScroll);
57140bd37d32Smrg	    break;
57150bd37d32Smrg	case srm_RXVT_SCROLL_TTY_OUTPUT:
57160bd37d32Smrg	    DoRM(DP_RXVT_SCROLL_TTY_OUTPUT, screen->scrollttyoutput);
57170bd37d32Smrg	    update_scrollttyoutput();
57180bd37d32Smrg	    break;
57190bd37d32Smrg	case srm_RXVT_SCROLL_TTY_KEYPRESS:
57200bd37d32Smrg	    DoRM(DP_RXVT_SCROLL_TTY_KEYPRESS, screen->scrollkey);
57210bd37d32Smrg	    update_scrollkey();
57220bd37d32Smrg	    break;
57230bd37d32Smrg	case srm_EIGHT_BIT_META:
57240bd37d32Smrg	    DoRM(DP_EIGHT_BIT_META, screen->eight_bit_meta);
57250bd37d32Smrg	    break;
57260bd37d32Smrg#if OPT_NUM_LOCK
57270bd37d32Smrg	case srm_REAL_NUMLOCK:
57280bd37d32Smrg	    DoRM(DP_REAL_NUMLOCK, xw->misc.real_NumLock);
57290bd37d32Smrg	    update_num_lock();
57300bd37d32Smrg	    break;
57310bd37d32Smrg	case srm_META_SENDS_ESC:
57320bd37d32Smrg	    DoRM(DP_META_SENDS_ESC, screen->meta_sends_esc);
57330bd37d32Smrg	    update_meta_esc();
57340bd37d32Smrg	    break;
57350bd37d32Smrg#endif
57360bd37d32Smrg	case srm_DELETE_IS_DEL:
57370bd37d32Smrg	    DoRM(DP_DELETE_IS_DEL, screen->delete_is_del);
57380bd37d32Smrg	    update_delete_del();
57390bd37d32Smrg	    break;
57400bd37d32Smrg#if OPT_NUM_LOCK
57410bd37d32Smrg	case srm_ALT_SENDS_ESC:
57420bd37d32Smrg	    DoRM(DP_ALT_SENDS_ESC, screen->alt_sends_esc);
57430bd37d32Smrg	    update_alt_esc();
57440bd37d32Smrg	    break;
57450bd37d32Smrg#endif
57460bd37d32Smrg	case srm_KEEP_SELECTION:
57470bd37d32Smrg	    DoRM(DP_KEEP_SELECTION, screen->keepSelection);
57480bd37d32Smrg	    update_keepSelection();
57490bd37d32Smrg	    break;
57500bd37d32Smrg	case srm_SELECT_TO_CLIPBOARD:
57510bd37d32Smrg	    DoRM(DP_SELECT_TO_CLIPBOARD, screen->selectToClipboard);
57520bd37d32Smrg	    update_selectToClipboard();
57530bd37d32Smrg	    break;
57540bd37d32Smrg	case srm_BELL_IS_URGENT:
57550bd37d32Smrg	    DoRM(DP_BELL_IS_URGENT, screen->bellIsUrgent);
57560bd37d32Smrg	    update_bellIsUrgent();
57570bd37d32Smrg	    break;
57580bd37d32Smrg	case srm_POP_ON_BELL:
57590bd37d32Smrg	    DoRM(DP_POP_ON_BELL, screen->poponbell);
57600bd37d32Smrg	    update_poponbell();
57610bd37d32Smrg	    break;
57620bd37d32Smrg#if OPT_TCAP_FKEYS
57630bd37d32Smrg	case srm_TCAP_FKEYS:
57640bd37d32Smrg	    /* FALLTHRU */
57650bd37d32Smrg#endif
57660bd37d32Smrg#if OPT_SUN_FUNC_KEYS
57670bd37d32Smrg	case srm_SUN_FKEYS:
57680bd37d32Smrg	    /* FALLTHRU */
57690bd37d32Smrg#endif
57700bd37d32Smrg#if OPT_HP_FUNC_KEYS
57710bd37d32Smrg	case srm_HP_FKEYS:
57720bd37d32Smrg	    /* FALLTHRU */
57730bd37d32Smrg#endif
57740bd37d32Smrg#if OPT_SCO_FUNC_KEYS
57750bd37d32Smrg	case srm_SCO_FKEYS:
57760bd37d32Smrg	    /* FALLTHRU */
57770bd37d32Smrg#endif
57780bd37d32Smrg#if OPT_SUNPC_KBD
57790bd37d32Smrg	case srm_VT220_FKEYS:
57800bd37d32Smrg	    /* FALLTHRU */
57810bd37d32Smrg#endif
57820bd37d32Smrg	case srm_LEGACY_FKEYS:
57830bd37d32Smrg	    xw->keyboard.type = (xtermKeyboardType) screen->save_modes[DP_KEYBOARD_TYPE];
57840bd37d32Smrg	    break;
5785d522f475Smrg#if OPT_READLINE
57860bd37d32Smrg	case srm_BUTTON1_MOVE_POINT:
5787d522f475Smrg	    SCREEN_FLAG_restore(screen, click1_moves);
5788d522f475Smrg	    break;
57890bd37d32Smrg	case srm_BUTTON2_MOVE_POINT:
5790d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_moves);
5791d522f475Smrg	    break;
57920bd37d32Smrg	case srm_DBUTTON3_DELETE:
5793d522f475Smrg	    SCREEN_FLAG_restore(screen, dclick3_deletes);
5794d522f475Smrg	    break;
57950bd37d32Smrg	case srm_PASTE_IN_BRACKET:
5796d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_brackets);
5797d522f475Smrg	    break;
57980bd37d32Smrg	case srm_PASTE_QUOTE:
5799d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_quotes);
5800d522f475Smrg	    break;
58010bd37d32Smrg	case srm_PASTE_LITERAL_NL:
5802d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_literal_nl);
5803d522f475Smrg	    break;
5804d522f475Smrg#endif /* OPT_READLINE */
5805d522f475Smrg	}
5806d522f475Smrg    }
5807d522f475Smrg}
5808d522f475Smrg
580920d2c4d2Smrg/*
581020d2c4d2Smrg * Convert an XTextProperty to a string.
581120d2c4d2Smrg *
581220d2c4d2Smrg * This frees the data owned by the XTextProperty, and returns in its place the
581320d2c4d2Smrg * string, which must be freed by the caller.
581420d2c4d2Smrg */
581520d2c4d2Smrgstatic char *
581620d2c4d2Smrgproperty_to_string(XtermWidget xw, XTextProperty * text)
581720d2c4d2Smrg{
581820d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
581920d2c4d2Smrg    Display *dpy = screen->display;
582020d2c4d2Smrg    char *result = 0;
582120d2c4d2Smrg    char **list;
582220d2c4d2Smrg    int length = 0;
582320d2c4d2Smrg    int rc;
582420d2c4d2Smrg
582520d2c4d2Smrg    TRACE(("property_to_string value %p, encoding %s, format %d, nitems %ld\n",
582620d2c4d2Smrg	   text->value,
582720d2c4d2Smrg	   XGetAtomName(dpy, text->encoding),
582820d2c4d2Smrg	   text->format,
582920d2c4d2Smrg	   text->nitems));
583020d2c4d2Smrg
583120d2c4d2Smrg#if OPT_WIDE_CHARS
583220d2c4d2Smrg    /*
583320d2c4d2Smrg     * We will use the XmbTextPropertyToTextList call to extract UTF-8 data.
583420d2c4d2Smrg     * The xtermUtf8ToTextList() call is used to convert UTF-8 explicitly to
583520d2c4d2Smrg     * ISO-8859-1.
583620d2c4d2Smrg     */
583720d2c4d2Smrg    if ((text->format != 8)
583820d2c4d2Smrg	|| IsTitleMode(xw, tmGetUtf8)
583920d2c4d2Smrg	|| (rc = xtermUtf8ToTextList(xw, text, &list, &length)) < 0)
584020d2c4d2Smrg#endif
584120d2c4d2Smrg	if ((rc = XmbTextPropertyToTextList(dpy, text, &list, &length)) < 0)
584220d2c4d2Smrg	    rc = XTextPropertyToStringList(text, &list, &length);
584320d2c4d2Smrg
584420d2c4d2Smrg    if (rc >= 0) {
584520d2c4d2Smrg	int n, c, pass;
584620d2c4d2Smrg	size_t need = 0;
584720d2c4d2Smrg
584820d2c4d2Smrg	for (pass = 0; pass < 2; ++pass) {
584920d2c4d2Smrg	    for (n = 0, need = 0; n < length; n++) {
585020d2c4d2Smrg		char *s = list[n];
585120d2c4d2Smrg		while ((c = *s++) != '\0') {
585220d2c4d2Smrg		    if (pass)
585320d2c4d2Smrg			result[need] = (char) c;
585420d2c4d2Smrg		    ++need;
585520d2c4d2Smrg		}
585620d2c4d2Smrg	    }
585720d2c4d2Smrg	    if (pass)
585820d2c4d2Smrg		result[need] = '\0';
585920d2c4d2Smrg	    else
586020d2c4d2Smrg		result = malloc(need + 1);
586120d2c4d2Smrg	    if (result == 0)
586220d2c4d2Smrg		break;
586320d2c4d2Smrg	}
586420d2c4d2Smrg	XFreeStringList(list);
586520d2c4d2Smrg    }
586620d2c4d2Smrg    if (text->value != 0)
586720d2c4d2Smrg	XFree(text->value);
586820d2c4d2Smrg
586920d2c4d2Smrg    return result;
587020d2c4d2Smrg}
587120d2c4d2Smrg
587220d2c4d2Smrgstatic char *
587320d2c4d2Smrgget_icon_label(XtermWidget xw)
587420d2c4d2Smrg{
587520d2c4d2Smrg    XTextProperty text;
587620d2c4d2Smrg    char *result = 0;
587720d2c4d2Smrg
5878a1f3da82Smrg    if (XGetWMIconName(TScreenOf(xw)->display, VShellWindow(xw), &text)) {
587920d2c4d2Smrg	result = property_to_string(xw, &text);
588020d2c4d2Smrg    }
588120d2c4d2Smrg    return result;
588220d2c4d2Smrg}
588320d2c4d2Smrg
588420d2c4d2Smrgstatic char *
588520d2c4d2Smrgget_window_label(XtermWidget xw)
588620d2c4d2Smrg{
588720d2c4d2Smrg    XTextProperty text;
588820d2c4d2Smrg    char *result = 0;
588920d2c4d2Smrg
5890a1f3da82Smrg    if (XGetWMName(TScreenOf(xw)->display, VShellWindow(xw), &text)) {
589120d2c4d2Smrg	result = property_to_string(xw, &text);
589220d2c4d2Smrg    }
589320d2c4d2Smrg    return result;
589420d2c4d2Smrg}
589520d2c4d2Smrg
5896d522f475Smrg/*
5897d522f475Smrg * Report window label (icon or title) in dtterm protocol
5898d522f475Smrg * ESC ] code label ESC backslash
5899d522f475Smrg */
5900d522f475Smrgstatic void
5901d522f475Smrgreport_win_label(XtermWidget xw,
5902d522f475Smrg		 int code,
590320d2c4d2Smrg		 char *text)
5904d522f475Smrg{
5905d522f475Smrg    unparseputc(xw, ANSI_ESC);
5906d522f475Smrg    unparseputc(xw, ']');
5907d522f475Smrg    unparseputc(xw, code);
5908d522f475Smrg
590920d2c4d2Smrg    if (text != 0) {
591020d2c4d2Smrg	int copy = IsTitleMode(xw, tmGetBase16);
591120d2c4d2Smrg	if (copy) {
591220d2c4d2Smrg	    TRACE(("Encoding hex:%s\n", text));
591320d2c4d2Smrg	    text = x_encode_hex(text);
5914d522f475Smrg	}
591520d2c4d2Smrg	unparseputs(xw, text);
591620d2c4d2Smrg	if (copy)
591720d2c4d2Smrg	    free(text);
5918d522f475Smrg    }
5919d522f475Smrg
5920d522f475Smrg    unparseputc(xw, ANSI_ESC);
5921d522f475Smrg    unparseputc(xw, '\\');	/* should be ST */
5922d522f475Smrg    unparse_end(xw);
5923d522f475Smrg}
5924d522f475Smrg
5925d522f475Smrg/*
5926d522f475Smrg * Window operations (from CDE dtterm description, as well as extensions).
5927d522f475Smrg * See also "allowWindowOps" resource.
5928d522f475Smrg */
5929d522f475Smrgstatic void
5930d522f475Smrgwindow_ops(XtermWidget xw)
5931d522f475Smrg{
593220d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
5933d522f475Smrg    XWindowChanges values;
5934d522f475Smrg    XWindowAttributes win_attrs;
5935d522f475Smrg    unsigned value_mask;
5936d522f475Smrg#if OPT_MAXIMIZE
5937d522f475Smrg    unsigned root_width;
5938d522f475Smrg    unsigned root_height;
5939d522f475Smrg#endif
59400bd37d32Smrg    int code = zero_if_default(0);
59410bd37d32Smrg    char *label;
5942d522f475Smrg
59430bd37d32Smrg    TRACE(("window_ops %d\n", code));
59440bd37d32Smrg    switch (code) {
594520d2c4d2Smrg    case ewRestoreWin:		/* Restore (de-iconify) window */
594620d2c4d2Smrg	if (AllowWindowOps(xw, ewRestoreWin)) {
594720d2c4d2Smrg	    TRACE(("...de-iconify window\n"));
594820d2c4d2Smrg	    XMapWindow(screen->display,
5949a1f3da82Smrg		       VShellWindow(xw));
595020d2c4d2Smrg	}
5951d522f475Smrg	break;
5952d522f475Smrg
595320d2c4d2Smrg    case ewMinimizeWin:	/* Minimize (iconify) window */
595420d2c4d2Smrg	if (AllowWindowOps(xw, ewMinimizeWin)) {
595520d2c4d2Smrg	    TRACE(("...iconify window\n"));
595620d2c4d2Smrg	    XIconifyWindow(screen->display,
5957a1f3da82Smrg			   VShellWindow(xw),
595820d2c4d2Smrg			   DefaultScreen(screen->display));
595920d2c4d2Smrg	}
5960d522f475Smrg	break;
5961d522f475Smrg
596220d2c4d2Smrg    case ewSetWinPosition:	/* Move the window to the given position */
596320d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinPosition)) {
596420d2c4d2Smrg	    values.x = zero_if_default(1);
596520d2c4d2Smrg	    values.y = zero_if_default(2);
596620d2c4d2Smrg	    TRACE(("...move window to %d,%d\n", values.x, values.y));
596720d2c4d2Smrg	    value_mask = (CWX | CWY);
596820d2c4d2Smrg	    XReconfigureWMWindow(screen->display,
5969a1f3da82Smrg				 VShellWindow(xw),
597020d2c4d2Smrg				 DefaultScreen(screen->display),
597120d2c4d2Smrg				 value_mask,
597220d2c4d2Smrg				 &values);
597320d2c4d2Smrg	}
5974d522f475Smrg	break;
5975d522f475Smrg
597620d2c4d2Smrg    case ewSetWinSizePixels:	/* Resize the window to given size in pixels */
597720d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinSizePixels)) {
59780bd37d32Smrg	    RequestResize(xw, optional_param(1), optional_param(2), False);
597920d2c4d2Smrg	}
5980d522f475Smrg	break;
5981d522f475Smrg
598220d2c4d2Smrg    case ewRaiseWin:		/* Raise the window to the front of the stack */
598320d2c4d2Smrg	if (AllowWindowOps(xw, ewRaiseWin)) {
598420d2c4d2Smrg	    TRACE(("...raise window\n"));
5985a1f3da82Smrg	    XRaiseWindow(screen->display, VShellWindow(xw));
598620d2c4d2Smrg	}
5987d522f475Smrg	break;
5988d522f475Smrg
598920d2c4d2Smrg    case ewLowerWin:		/* Lower the window to the bottom of the stack */
599020d2c4d2Smrg	if (AllowWindowOps(xw, ewLowerWin)) {
599120d2c4d2Smrg	    TRACE(("...lower window\n"));
5992a1f3da82Smrg	    XLowerWindow(screen->display, VShellWindow(xw));
599320d2c4d2Smrg	}
5994d522f475Smrg	break;
5995d522f475Smrg
599620d2c4d2Smrg    case ewRefreshWin:		/* Refresh the window */
599720d2c4d2Smrg	if (AllowWindowOps(xw, ewRefreshWin)) {
599820d2c4d2Smrg	    TRACE(("...redraw window\n"));
599920d2c4d2Smrg	    Redraw();
600020d2c4d2Smrg	}
6001d522f475Smrg	break;
6002d522f475Smrg
600320d2c4d2Smrg    case ewSetWinSizeChars:	/* Resize the text-area, in characters */
600420d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinSizeChars)) {
60050bd37d32Smrg	    RequestResize(xw, optional_param(1), optional_param(2), True);
600620d2c4d2Smrg	}
6007d522f475Smrg	break;
6008d522f475Smrg
6009d522f475Smrg#if OPT_MAXIMIZE
601020d2c4d2Smrg    case ewMaximizeWin:	/* Maximize or restore */
601120d2c4d2Smrg	if (AllowWindowOps(xw, ewMaximizeWin)) {
601220d2c4d2Smrg	    RequestMaximize(xw, zero_if_default(1));
601320d2c4d2Smrg	}
6014d522f475Smrg	break;
6015a1f3da82Smrg    case ewFullscreenWin:	/* Fullscreen or restore */
6016a1f3da82Smrg	if (AllowWindowOps(xw, ewFullscreenWin)) {
6017a1f3da82Smrg	    FullScreen(xw, zero_if_default(1));
6018a1f3da82Smrg	}
6019a1f3da82Smrg	break;
6020d522f475Smrg#endif
6021d522f475Smrg
602220d2c4d2Smrg    case ewGetWinState:	/* Report the window's state */
602320d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinState)) {
602420d2c4d2Smrg	    TRACE(("...get window attributes\n"));
60250bd37d32Smrg	    xtermGetWinAttrs(screen->display,
60260bd37d32Smrg			     VWindow(screen),
60270bd37d32Smrg			     &win_attrs);
60280bd37d32Smrg	    init_reply(ANSI_CSI);
602920d2c4d2Smrg	    reply.a_pintro = 0;
603020d2c4d2Smrg	    reply.a_nparam = 1;
603120d2c4d2Smrg	    reply.a_param[0] = (ParmType) ((win_attrs.map_state == IsViewable)
603220d2c4d2Smrg					   ? 1
603320d2c4d2Smrg					   : 2);
603420d2c4d2Smrg	    reply.a_inters = 0;
603520d2c4d2Smrg	    reply.a_final = 't';
603620d2c4d2Smrg	    unparseseq(xw, &reply);
603720d2c4d2Smrg	}
6038d522f475Smrg	break;
6039d522f475Smrg
604020d2c4d2Smrg    case ewGetWinPosition:	/* Report the window's position */
604120d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinPosition)) {
604220d2c4d2Smrg	    TRACE(("...get window position\n"));
60430bd37d32Smrg	    xtermGetWinAttrs(screen->display,
60440bd37d32Smrg			     WMFrameWindow(xw),
60450bd37d32Smrg			     &win_attrs);
60460bd37d32Smrg	    init_reply(ANSI_CSI);
604720d2c4d2Smrg	    reply.a_pintro = 0;
604820d2c4d2Smrg	    reply.a_nparam = 3;
604920d2c4d2Smrg	    reply.a_param[0] = 3;
605020d2c4d2Smrg	    reply.a_param[1] = (ParmType) win_attrs.x;
605120d2c4d2Smrg	    reply.a_param[2] = (ParmType) win_attrs.y;
605220d2c4d2Smrg	    reply.a_inters = 0;
605320d2c4d2Smrg	    reply.a_final = 't';
605420d2c4d2Smrg	    unparseseq(xw, &reply);
605520d2c4d2Smrg	}
6056d522f475Smrg	break;
6057d522f475Smrg
605820d2c4d2Smrg    case ewGetWinSizePixels:	/* Report the window's size in pixels */
605920d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinSizePixels)) {
606020d2c4d2Smrg	    TRACE(("...get window size in pixels\n"));
60610bd37d32Smrg	    init_reply(ANSI_CSI);
606220d2c4d2Smrg	    reply.a_pintro = 0;
606320d2c4d2Smrg	    reply.a_nparam = 3;
606420d2c4d2Smrg	    reply.a_param[0] = 4;
606520d2c4d2Smrg	    reply.a_param[1] = (ParmType) Height(screen);
606620d2c4d2Smrg	    reply.a_param[2] = (ParmType) Width(screen);
606720d2c4d2Smrg	    reply.a_inters = 0;
606820d2c4d2Smrg	    reply.a_final = 't';
606920d2c4d2Smrg	    unparseseq(xw, &reply);
607020d2c4d2Smrg	}
6071d522f475Smrg	break;
6072d522f475Smrg
607320d2c4d2Smrg    case ewGetWinSizeChars:	/* Report the text's size in characters */
607420d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinSizeChars)) {
607520d2c4d2Smrg	    TRACE(("...get window size in characters\n"));
60760bd37d32Smrg	    init_reply(ANSI_CSI);
607720d2c4d2Smrg	    reply.a_pintro = 0;
607820d2c4d2Smrg	    reply.a_nparam = 3;
607920d2c4d2Smrg	    reply.a_param[0] = 8;
608020d2c4d2Smrg	    reply.a_param[1] = (ParmType) MaxRows(screen);
608120d2c4d2Smrg	    reply.a_param[2] = (ParmType) MaxCols(screen);
608220d2c4d2Smrg	    reply.a_inters = 0;
608320d2c4d2Smrg	    reply.a_final = 't';
608420d2c4d2Smrg	    unparseseq(xw, &reply);
608520d2c4d2Smrg	}
6086d522f475Smrg	break;
6087d522f475Smrg
6088d522f475Smrg#if OPT_MAXIMIZE
608920d2c4d2Smrg    case ewGetScreenSizeChars:	/* Report the screen's size, in characters */
609020d2c4d2Smrg	if (AllowWindowOps(xw, ewGetScreenSizeChars)) {
609120d2c4d2Smrg	    TRACE(("...get screen size in characters\n"));
60920bd37d32Smrg	    (void) QueryMaximize(xw, &root_height, &root_width);
60930bd37d32Smrg	    init_reply(ANSI_CSI);
609420d2c4d2Smrg	    reply.a_pintro = 0;
609520d2c4d2Smrg	    reply.a_nparam = 3;
609620d2c4d2Smrg	    reply.a_param[0] = 9;
609720d2c4d2Smrg	    reply.a_param[1] = (ParmType) (root_height
609820d2c4d2Smrg					   / (unsigned) FontHeight(screen));
609920d2c4d2Smrg	    reply.a_param[2] = (ParmType) (root_width
610020d2c4d2Smrg					   / (unsigned) FontWidth(screen));
610120d2c4d2Smrg	    reply.a_inters = 0;
610220d2c4d2Smrg	    reply.a_final = 't';
610320d2c4d2Smrg	    unparseseq(xw, &reply);
6104d522f475Smrg	}
6105d522f475Smrg	break;
6106d522f475Smrg#endif
6107d522f475Smrg
610820d2c4d2Smrg    case ewGetIconTitle:	/* Report the icon's label */
610920d2c4d2Smrg	if (AllowWindowOps(xw, ewGetIconTitle)) {
611020d2c4d2Smrg	    TRACE(("...get icon's label\n"));
61110bd37d32Smrg	    report_win_label(xw, 'L', label = get_icon_label(xw));
61120bd37d32Smrg	    free(label);
611320d2c4d2Smrg	}
6114d522f475Smrg	break;
6115d522f475Smrg
611620d2c4d2Smrg    case ewGetWinTitle:	/* Report the window's title */
611720d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinTitle)) {
611820d2c4d2Smrg	    TRACE(("...get window's label\n"));
61190bd37d32Smrg	    report_win_label(xw, 'l', label = get_window_label(xw));
61200bd37d32Smrg	    free(label);
612120d2c4d2Smrg	}
612220d2c4d2Smrg	break;
612320d2c4d2Smrg
612420d2c4d2Smrg    case ewPushTitle:		/* save the window's title(s) on stack */
612520d2c4d2Smrg	if (AllowWindowOps(xw, ewPushTitle)) {
612620d2c4d2Smrg	    SaveTitle *last = screen->save_title;
612720d2c4d2Smrg	    SaveTitle *item = TypeCalloc(SaveTitle);
612820d2c4d2Smrg
612920d2c4d2Smrg	    TRACE(("...push title onto stack\n"));
613020d2c4d2Smrg	    if (item != 0) {
613120d2c4d2Smrg		switch (zero_if_default(1)) {
613220d2c4d2Smrg		case 0:
613320d2c4d2Smrg		    item->iconName = get_icon_label(xw);
613420d2c4d2Smrg		    item->windowName = get_window_label(xw);
613520d2c4d2Smrg		    break;
613620d2c4d2Smrg		case 1:
613720d2c4d2Smrg		    item->iconName = get_icon_label(xw);
613820d2c4d2Smrg		    break;
613920d2c4d2Smrg		case 2:
614020d2c4d2Smrg		    item->windowName = get_window_label(xw);
614120d2c4d2Smrg		    break;
614220d2c4d2Smrg		}
614320d2c4d2Smrg		item->next = last;
614420d2c4d2Smrg		if (item->iconName == 0) {
614520d2c4d2Smrg		    item->iconName = ((last == 0)
614620d2c4d2Smrg				      ? get_icon_label(xw)
614720d2c4d2Smrg				      : x_strdup(last->iconName));
614820d2c4d2Smrg		}
614920d2c4d2Smrg		if (item->windowName == 0) {
615020d2c4d2Smrg		    item->windowName = ((last == 0)
615120d2c4d2Smrg					? get_window_label(xw)
615220d2c4d2Smrg					: x_strdup(last->windowName));
615320d2c4d2Smrg		}
615420d2c4d2Smrg		screen->save_title = item;
615520d2c4d2Smrg	    }
615620d2c4d2Smrg	}
615720d2c4d2Smrg	break;
615820d2c4d2Smrg
615920d2c4d2Smrg    case ewPopTitle:		/* restore the window's title(s) from stack */
616020d2c4d2Smrg	if (AllowWindowOps(xw, ewPopTitle)) {
616120d2c4d2Smrg	    SaveTitle *item = screen->save_title;
616220d2c4d2Smrg
616320d2c4d2Smrg	    TRACE(("...pop title off stack\n"));
616420d2c4d2Smrg	    if (item != 0) {
616520d2c4d2Smrg		switch (zero_if_default(1)) {
616620d2c4d2Smrg		case 0:
616720d2c4d2Smrg		    ChangeIconName(xw, item->iconName);
616820d2c4d2Smrg		    ChangeTitle(xw, item->windowName);
616920d2c4d2Smrg		    break;
617020d2c4d2Smrg		case 1:
617120d2c4d2Smrg		    ChangeIconName(xw, item->iconName);
617220d2c4d2Smrg		    break;
617320d2c4d2Smrg		case 2:
617420d2c4d2Smrg		    ChangeTitle(xw, item->windowName);
617520d2c4d2Smrg		    break;
617620d2c4d2Smrg		}
617720d2c4d2Smrg		screen->save_title = item->next;
617820d2c4d2Smrg		free(item->iconName);
617920d2c4d2Smrg		free(item->windowName);
618020d2c4d2Smrg		free(item);
618120d2c4d2Smrg	    }
618220d2c4d2Smrg	}
6183d522f475Smrg	break;
6184d522f475Smrg
6185d522f475Smrg    default:			/* DECSLPP (24, 25, 36, 48, 72, 144) */
618620d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinLines)) {
61870bd37d32Smrg	    if (code >= 24)
61880bd37d32Smrg		RequestResize(xw, code, -1, True);
618920d2c4d2Smrg	}
6190d522f475Smrg	break;
6191d522f475Smrg    }
6192d522f475Smrg}
6193d522f475Smrg
6194d522f475Smrg/*
6195d522f475Smrg * set a bit in a word given a pointer to the word and a mask.
6196d522f475Smrg */
6197d522f475Smrgstatic void
6198d522f475Smrgbitset(unsigned *p, unsigned mask)
6199d522f475Smrg{
6200d522f475Smrg    *p |= mask;
6201d522f475Smrg}
6202d522f475Smrg
6203d522f475Smrg/*
6204d522f475Smrg * clear a bit in a word given a pointer to the word and a mask.
6205d522f475Smrg */
6206d522f475Smrgstatic void
6207d522f475Smrgbitclr(unsigned *p, unsigned mask)
6208d522f475Smrg{
6209d522f475Smrg    *p &= ~mask;
6210d522f475Smrg}
6211d522f475Smrg
6212d522f475Smrg/*
6213d522f475Smrg * Copy bits from one word to another, given a mask
6214d522f475Smrg */
6215d522f475Smrgstatic void
6216d522f475Smrgbitcpy(unsigned *p, unsigned q, unsigned mask)
6217d522f475Smrg{
6218d522f475Smrg    bitclr(p, mask);
6219d522f475Smrg    bitset(p, q & mask);
6220d522f475Smrg}
6221d522f475Smrg
6222d522f475Smrgvoid
6223d522f475Smrgunparseputc1(XtermWidget xw, int c)
6224d522f475Smrg{
6225d522f475Smrg    if (c >= 0x80 && c <= 0x9F) {
622620d2c4d2Smrg	if (!TScreenOf(xw)->control_eight_bits) {
6227d522f475Smrg	    unparseputc(xw, A2E(ANSI_ESC));
6228d522f475Smrg	    c = A2E(c - 0x40);
6229d522f475Smrg	}
6230d522f475Smrg    }
6231d522f475Smrg    unparseputc(xw, c);
6232d522f475Smrg}
6233d522f475Smrg
6234d522f475Smrgvoid
6235d522f475Smrgunparseseq(XtermWidget xw, ANSI * ap)
6236d522f475Smrg{
6237d522f475Smrg    int c;
6238d522f475Smrg    int i;
6239d522f475Smrg    int inters;
6240d522f475Smrg
6241d522f475Smrg    unparseputc1(xw, c = ap->a_type);
6242d522f475Smrg    if (c == ANSI_ESC
6243d522f475Smrg	|| c == ANSI_DCS
6244d522f475Smrg	|| c == ANSI_CSI
6245d522f475Smrg	|| c == ANSI_OSC
6246d522f475Smrg	|| c == ANSI_PM
6247d522f475Smrg	|| c == ANSI_APC
6248d522f475Smrg	|| c == ANSI_SS3) {
6249d522f475Smrg	if (ap->a_pintro != 0)
6250d522f475Smrg	    unparseputc(xw, ap->a_pintro);
6251d522f475Smrg	for (i = 0; i < ap->a_nparam; ++i) {
62520bd37d32Smrg	    if (i != 0) {
62530bd37d32Smrg		if (ap->a_delim) {
62540bd37d32Smrg		    unparseputs(xw, ap->a_delim);
62550bd37d32Smrg		} else {
62560bd37d32Smrg		    unparseputc(xw, ';');
62570bd37d32Smrg		}
62580bd37d32Smrg	    }
62590bd37d32Smrg	    if (ap->a_radix[i]) {
62600bd37d32Smrg		char temp[8];
62610bd37d32Smrg		sprintf(temp, "%04X", ap->a_param[i] & 0xffff);
62620bd37d32Smrg		unparseputs(xw, temp);
62630bd37d32Smrg	    } else {
62640bd37d32Smrg		unparseputn(xw, (unsigned int) ap->a_param[i]);
62650bd37d32Smrg	    }
6266d522f475Smrg	}
6267d522f475Smrg	if ((inters = ap->a_inters) != 0) {
6268d522f475Smrg	    for (i = 3; i >= 0; --i) {
6269d522f475Smrg		c = CharOf(inters >> (8 * i));
6270d522f475Smrg		if (c != 0)
6271d522f475Smrg		    unparseputc(xw, c);
6272d522f475Smrg	    }
6273d522f475Smrg	}
62740bd37d32Smrg	switch (ap->a_type) {
62750bd37d32Smrg	case ANSI_DCS:
62760bd37d32Smrg	case ANSI_OSC:
62770bd37d32Smrg	case ANSI_PM:
62780bd37d32Smrg	case ANSI_APC:
62790bd37d32Smrg	    unparseputc1(xw, ANSI_ST);
62800bd37d32Smrg	    break;
62810bd37d32Smrg	default:
62820bd37d32Smrg	    unparseputc(xw, (char) ap->a_final);
62830bd37d32Smrg	    break;
62840bd37d32Smrg	}
6285d522f475Smrg    }
6286d522f475Smrg    unparse_end(xw);
6287d522f475Smrg}
6288d522f475Smrg
6289d522f475Smrgvoid
6290d522f475Smrgunparseputn(XtermWidget xw, unsigned int n)
6291d522f475Smrg{
6292d522f475Smrg    unsigned int q;
6293d522f475Smrg
6294d522f475Smrg    q = n / 10;
6295d522f475Smrg    if (q != 0)
6296d522f475Smrg	unparseputn(xw, q);
6297d522f475Smrg    unparseputc(xw, (char) ('0' + (n % 10)));
6298d522f475Smrg}
6299d522f475Smrg
6300d522f475Smrgvoid
630120d2c4d2Smrgunparseputs(XtermWidget xw, const char *s)
6302d522f475Smrg{
630320d2c4d2Smrg    if (s != 0) {
630420d2c4d2Smrg	while (*s)
630520d2c4d2Smrg	    unparseputc(xw, *s++);
630620d2c4d2Smrg    }
6307d522f475Smrg}
6308d522f475Smrg
6309d522f475Smrgvoid
6310d522f475Smrgunparseputc(XtermWidget xw, int c)
6311d522f475Smrg{
6312492d43a5Smrg    TScreen *screen = TScreenOf(xw);
6313492d43a5Smrg    IChar *buf = screen->unparse_bfr;
6314d522f475Smrg    unsigned len;
6315d522f475Smrg
63160bd37d32Smrg    if ((screen->unparse_len + 2) >= sizeof(screen->unparse_bfr) / sizeof(IChar))
6317d522f475Smrg	unparse_end(xw);
6318d522f475Smrg
6319492d43a5Smrg    len = screen->unparse_len;
6320d522f475Smrg
6321d522f475Smrg#if OPT_TCAP_QUERY
6322d522f475Smrg    /*
6323d522f475Smrg     * If we're returning a termcap string, it has to be translated since
6324d522f475Smrg     * a DCS must not contain any characters except for the normal 7-bit
6325d522f475Smrg     * printable ASCII (counting tab, carriage return, etc).  For now,
6326d522f475Smrg     * just use hexadecimal for the whole thing.
6327d522f475Smrg     */
6328492d43a5Smrg    if (screen->tc_query_code >= 0) {
6329d522f475Smrg	char tmp[3];
6330d522f475Smrg	sprintf(tmp, "%02X", c & 0xFF);
63312eaa94a1Schristos	buf[len++] = CharOf(tmp[0]);
63322eaa94a1Schristos	buf[len++] = CharOf(tmp[1]);
6333d522f475Smrg    } else
6334d522f475Smrg#endif
63352eaa94a1Schristos    if ((buf[len++] = (IChar) c) == '\r' && (xw->flags & LINEFEED)) {
6336d522f475Smrg	buf[len++] = '\n';
6337d522f475Smrg    }
6338d522f475Smrg
6339492d43a5Smrg    screen->unparse_len = len;
6340d522f475Smrg
6341d522f475Smrg    /* If send/receive mode is reset, we echo characters locally */
6342d522f475Smrg    if ((xw->keyboard.flags & MODE_SRM) == 0) {
6343d522f475Smrg	(void) doparsing(xw, (unsigned) c, &myState);
6344d522f475Smrg    }
6345d522f475Smrg}
6346d522f475Smrg
6347d522f475Smrgvoid
6348d522f475Smrgunparse_end(XtermWidget xw)
6349d522f475Smrg{
635020d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
635120d2c4d2Smrg
635220d2c4d2Smrg    if (screen->unparse_len) {
6353d522f475Smrg#ifdef VMS
635420d2c4d2Smrg	tt_write(screen->unparse_bfr, screen->unparse_len);
6355d522f475Smrg#else /* VMS */
635620d2c4d2Smrg	writePtyData(screen->respond, screen->unparse_bfr, screen->unparse_len);
6357d522f475Smrg#endif /* VMS */
635820d2c4d2Smrg	screen->unparse_len = 0;
6359d522f475Smrg    }
6360d522f475Smrg}
6361d522f475Smrg
6362d522f475Smrgvoid
6363d522f475SmrgToggleAlternate(XtermWidget xw)
6364d522f475Smrg{
636520d2c4d2Smrg    if (TScreenOf(xw)->whichBuf)
6366d522f475Smrg	FromAlternate(xw);
6367d522f475Smrg    else
6368d522f475Smrg	ToAlternate(xw);
6369d522f475Smrg}
6370d522f475Smrg
6371d522f475Smrgstatic void
6372d522f475SmrgToAlternate(XtermWidget xw)
6373d522f475Smrg{
637420d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6375d522f475Smrg
6376956cc18dSsnj    if (screen->whichBuf == 0) {
6377d522f475Smrg	TRACE(("ToAlternate\n"));
6378956cc18dSsnj	if (!screen->editBuf_index[1])
6379956cc18dSsnj	    screen->editBuf_index[1] = allocScrnBuf(xw,
6380956cc18dSsnj						    (unsigned) MaxRows(screen),
6381956cc18dSsnj						    (unsigned) MaxCols(screen),
6382956cc18dSsnj						    &screen->editBuf_data[1]);
638320d2c4d2Smrg	SwitchBufs(xw, 1);
6384956cc18dSsnj	screen->whichBuf = 1;
6385956cc18dSsnj#if OPT_SAVE_LINES
6386956cc18dSsnj	screen->visbuf = screen->editBuf_index[screen->whichBuf];
6387956cc18dSsnj#endif
6388d522f475Smrg	update_altscreen();
6389d522f475Smrg    }
6390d522f475Smrg}
6391d522f475Smrg
6392d522f475Smrgstatic void
6393d522f475SmrgFromAlternate(XtermWidget xw)
6394d522f475Smrg{
639520d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6396d522f475Smrg
6397956cc18dSsnj    if (screen->whichBuf != 0) {
6398d522f475Smrg	TRACE(("FromAlternate\n"));
6399d522f475Smrg	if (screen->scroll_amt)
6400d522f475Smrg	    FlushScroll(xw);
6401956cc18dSsnj	screen->whichBuf = 0;
640220d2c4d2Smrg	SwitchBufs(xw, 0);
6403956cc18dSsnj#if OPT_SAVE_LINES
6404956cc18dSsnj	screen->visbuf = screen->editBuf_index[screen->whichBuf];
6405956cc18dSsnj#endif
6406d522f475Smrg	update_altscreen();
6407d522f475Smrg    }
6408d522f475Smrg}
6409d522f475Smrg
6410d522f475Smrgstatic void
641120d2c4d2SmrgSwitchBufs(XtermWidget xw, int toBuf)
6412d522f475Smrg{
641320d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6414d522f475Smrg    int rows, top;
6415d522f475Smrg
6416d522f475Smrg    if (screen->cursor_state)
6417d522f475Smrg	HideCursor();
6418d522f475Smrg
6419d522f475Smrg    rows = MaxRows(screen);
642020d2c4d2Smrg    SwitchBufPtrs(screen, toBuf);
6421d522f475Smrg
6422d522f475Smrg    if ((top = INX2ROW(screen, 0)) < rows) {
642320d2c4d2Smrg	if (screen->scroll_amt) {
6424d522f475Smrg	    FlushScroll(xw);
642520d2c4d2Smrg	}
64260bd37d32Smrg#if OPT_DOUBLE_BUFFER
64270bd37d32Smrg	XFillRectangle(screen->display,
64280bd37d32Smrg		       VDrawable(screen),
64290bd37d32Smrg		       ReverseGC(xw, screen),
64300bd37d32Smrg		       (int) OriginX(screen),
64310bd37d32Smrg		       (int) top * FontHeight(screen) + screen->border,
64320bd37d32Smrg		       (unsigned) Width(screen),
64330bd37d32Smrg		       (unsigned) ((rows - top) * FontHeight(screen)));
64340bd37d32Smrg#else
6435d522f475Smrg	XClearArea(screen->display,
6436d522f475Smrg		   VWindow(screen),
6437d522f475Smrg		   (int) OriginX(screen),
6438d522f475Smrg		   (int) top * FontHeight(screen) + screen->border,
6439d522f475Smrg		   (unsigned) Width(screen),
64402eaa94a1Schristos		   (unsigned) ((rows - top) * FontHeight(screen)),
6441d522f475Smrg		   False);
64420bd37d32Smrg#endif
6443d522f475Smrg    }
6444d522f475Smrg    ScrnUpdate(xw, 0, 0, rows, MaxCols(screen), False);
6445d522f475Smrg}
6446d522f475Smrg
6447d522f475SmrgBool
6448d522f475SmrgCheckBufPtrs(TScreen * screen)
6449d522f475Smrg{
6450d522f475Smrg    return (screen->visbuf != 0
6451956cc18dSsnj#if OPT_SAVE_LINES
6452956cc18dSsnj	    && screen->editBuf_index[0] != 0
6453956cc18dSsnj#endif
6454956cc18dSsnj	    && screen->editBuf_index[1] != 0);
6455d522f475Smrg}
6456d522f475Smrg
6457d522f475Smrg/*
6458d522f475Smrg * Swap buffer line pointers between alternate and regular screens.
6459d522f475Smrg */
6460d522f475Smrgvoid
646120d2c4d2SmrgSwitchBufPtrs(TScreen * screen, int toBuf GCC_UNUSED)
6462d522f475Smrg{
6463d522f475Smrg    if (CheckBufPtrs(screen)) {
6464956cc18dSsnj#if OPT_SAVE_LINES
646520d2c4d2Smrg	screen->visbuf = screen->editBuf_index[toBuf];
6466956cc18dSsnj#else
646720d2c4d2Smrg	size_t len = ScrnPointers(screen, (size_t) MaxRows(screen));
6468d522f475Smrg
6469956cc18dSsnj	memcpy(screen->save_ptr, screen->visbuf, len);
6470956cc18dSsnj	memcpy(screen->visbuf, screen->editBuf_index[1], len);
6471956cc18dSsnj	memcpy(screen->editBuf_index[1], screen->save_ptr, len);
6472956cc18dSsnj#endif
6473d522f475Smrg    }
6474d522f475Smrg}
6475d522f475Smrg
6476d522f475Smrgvoid
6477956cc18dSsnjVTRun(XtermWidget xw)
6478d522f475Smrg{
6479956cc18dSsnj    TScreen *screen = TScreenOf(xw);
6480d522f475Smrg
6481d522f475Smrg    TRACE(("VTRun ...\n"));
6482d522f475Smrg
6483d522f475Smrg    if (!screen->Vshow) {
6484d522f475Smrg	set_vt_visibility(True);
6485d522f475Smrg    }
6486d522f475Smrg    update_vttekmode();
6487d522f475Smrg    update_vtshow();
6488d522f475Smrg    update_tekshow();
6489d522f475Smrg    set_vthide_sensitivity();
6490d522f475Smrg
6491956cc18dSsnj    ScrnAllocBuf(xw);
6492d522f475Smrg
6493d522f475Smrg    screen->cursor_state = OFF;
6494d522f475Smrg    screen->cursor_set = ON;
6495d522f475Smrg#if OPT_BLINK_CURS
6496d522f475Smrg    if (DoStartBlinking(screen))
6497d522f475Smrg	StartBlinking(screen);
6498d522f475Smrg#endif
6499d522f475Smrg
6500d522f475Smrg#if OPT_TEK4014
6501d522f475Smrg    if (Tpushb > Tpushback) {
650220d2c4d2Smrg	fillPtyData(xw, VTbuffer, (char *) Tpushback, (int) (Tpushb - Tpushback));
6503d522f475Smrg	Tpushb = Tpushback;
6504d522f475Smrg    }
6505d522f475Smrg#endif
6506d522f475Smrg    screen->is_running = True;
65070bd37d32Smrg    if (screen->embed_high && screen->embed_wide) {
65080bd37d32Smrg	ScreenResize(xw, screen->embed_wide, screen->embed_high, &(xw->flags));
65090bd37d32Smrg    }
6510a1f3da82Smrg#if OPT_MAXIMIZE
65110bd37d32Smrg    else if (resource.fullscreen == esTrue || resource.fullscreen == esAlways)
6512a1f3da82Smrg	FullScreen(term, True);
6513a1f3da82Smrg#endif
6514d522f475Smrg    if (!setjmp(VTend))
6515956cc18dSsnj	VTparse(xw);
6516d522f475Smrg    StopBlinking(screen);
6517d522f475Smrg    HideCursor();
6518d522f475Smrg    screen->cursor_set = OFF;
6519d522f475Smrg    TRACE(("... VTRun\n"));
6520d522f475Smrg}
6521d522f475Smrg
6522d522f475Smrg/*ARGSUSED*/
6523d522f475Smrgstatic void
6524d522f475SmrgVTExpose(Widget w GCC_UNUSED,
6525d522f475Smrg	 XEvent * event,
6526d522f475Smrg	 Region region GCC_UNUSED)
6527d522f475Smrg{
65280bd37d32Smrg    DEBUG_MSG("Expose\n");
6529d522f475Smrg    if (event->type == Expose)
6530d522f475Smrg	HandleExposure(term, event);
6531d522f475Smrg}
6532d522f475Smrg
6533d522f475Smrgstatic void
6534d522f475SmrgVTGraphicsOrNoExpose(XEvent * event)
6535d522f475Smrg{
6536d522f475Smrg    TScreen *screen = TScreenOf(term);
6537d522f475Smrg    if (screen->incopy <= 0) {
6538d522f475Smrg	screen->incopy = 1;
6539d522f475Smrg	if (screen->scrolls > 0)
6540d522f475Smrg	    screen->scrolls--;
6541d522f475Smrg    }
6542d522f475Smrg    if (event->type == GraphicsExpose)
6543d522f475Smrg	if (HandleExposure(term, event))
6544d522f475Smrg	    screen->cursor_state = OFF;
6545d522f475Smrg    if ((event->type == NoExpose)
6546d522f475Smrg	|| ((XGraphicsExposeEvent *) event)->count == 0) {
6547d522f475Smrg	if (screen->incopy <= 0 && screen->scrolls > 0)
6548d522f475Smrg	    screen->scrolls--;
6549d522f475Smrg	if (screen->scrolls)
6550d522f475Smrg	    screen->incopy = -1;
6551d522f475Smrg	else
6552d522f475Smrg	    screen->incopy = 0;
6553d522f475Smrg    }
6554d522f475Smrg}
6555d522f475Smrg
6556d522f475Smrg/*ARGSUSED*/
6557d522f475Smrgstatic void
6558d522f475SmrgVTNonMaskableEvent(Widget w GCC_UNUSED,
6559d522f475Smrg		   XtPointer closure GCC_UNUSED,
6560d522f475Smrg		   XEvent * event,
6561d522f475Smrg		   Boolean * cont GCC_UNUSED)
6562d522f475Smrg{
6563d522f475Smrg    switch (event->type) {
6564d522f475Smrg    case GraphicsExpose:
6565d522f475Smrg    case NoExpose:
6566d522f475Smrg	VTGraphicsOrNoExpose(event);
6567d522f475Smrg	break;
6568d522f475Smrg    }
6569d522f475Smrg}
6570d522f475Smrg
6571d522f475Smrgstatic void
6572d522f475SmrgVTResize(Widget w)
6573d522f475Smrg{
6574d522f475Smrg    if (XtIsRealized(w)) {
6575d522f475Smrg	XtermWidget xw = (XtermWidget) w;
6576d522f475Smrg	ScreenResize(xw, xw->core.width, xw->core.height, &xw->flags);
6577d522f475Smrg    }
6578d522f475Smrg}
6579d522f475Smrg
65802eaa94a1Schristos#define okDimension(src,dst) ((src <= 32767) \
65812eaa94a1Schristos			  && ((dst = (Dimension) src) == src))
6582d522f475Smrg
6583d522f475Smrgstatic void
6584d522f475SmrgRequestResize(XtermWidget xw, int rows, int cols, Bool text)
6585d522f475Smrg{
658620d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6587d522f475Smrg    unsigned long value;
6588d522f475Smrg    Dimension replyWidth, replyHeight;
6589d522f475Smrg    Dimension askedWidth, askedHeight;
6590d522f475Smrg    XtGeometryResult status;
6591d522f475Smrg    XWindowAttributes attrs;
6592d522f475Smrg
6593d522f475Smrg    TRACE(("RequestResize(rows=%d, cols=%d, text=%d)\n", rows, cols, text));
6594d522f475Smrg
659520d2c4d2Smrg    if ((int) (askedWidth = (Dimension) cols) < cols
659620d2c4d2Smrg	|| (int) (askedHeight = (Dimension) rows) < rows)
6597d522f475Smrg	return;
6598d522f475Smrg
6599d522f475Smrg    if (askedHeight == 0
6600d522f475Smrg	|| askedWidth == 0
6601d522f475Smrg	|| xw->misc.limit_resize > 0) {
66020bd37d32Smrg	xtermGetWinAttrs(XtDisplay(xw),
66030bd37d32Smrg			 RootWindowOfScreen(XtScreen(xw)), &attrs);
6604d522f475Smrg    }
6605d522f475Smrg
6606d522f475Smrg    if (text) {
66072eaa94a1Schristos	if ((value = (unsigned long) rows) != 0) {
6608d522f475Smrg	    if (rows < 0)
66092eaa94a1Schristos		value = (unsigned long) MaxRows(screen);
66102eaa94a1Schristos	    value *= (unsigned long) FontHeight(screen);
66112eaa94a1Schristos	    value += (unsigned long) (2 * screen->border);
6612d522f475Smrg	    if (!okDimension(value, askedHeight))
6613d522f475Smrg		return;
6614d522f475Smrg	}
6615d522f475Smrg
66162eaa94a1Schristos	if ((value = (unsigned long) cols) != 0) {
6617d522f475Smrg	    if (cols < 0)
66182eaa94a1Schristos		value = (unsigned long) MaxCols(screen);
66192eaa94a1Schristos	    value *= (unsigned long) FontWidth(screen);
66202eaa94a1Schristos	    value += (unsigned long) ((2 * screen->border)
66212eaa94a1Schristos				      + ScrollbarWidth(screen));
6622d522f475Smrg	    if (!okDimension(value, askedWidth))
6623d522f475Smrg		return;
6624d522f475Smrg	}
6625d522f475Smrg
6626d522f475Smrg    } else {
6627d522f475Smrg	if (rows < 0)
6628d522f475Smrg	    askedHeight = FullHeight(screen);
6629d522f475Smrg	if (cols < 0)
6630d522f475Smrg	    askedWidth = FullWidth(screen);
6631d522f475Smrg    }
6632d522f475Smrg
6633d522f475Smrg    if (rows == 0)
66342eaa94a1Schristos	askedHeight = (Dimension) attrs.height;
6635d522f475Smrg    if (cols == 0)
66362eaa94a1Schristos	askedWidth = (Dimension) attrs.width;
6637d522f475Smrg
6638d522f475Smrg    if (xw->misc.limit_resize > 0) {
66392eaa94a1Schristos	Dimension high = (Dimension) (xw->misc.limit_resize * attrs.height);
66402eaa94a1Schristos	Dimension wide = (Dimension) (xw->misc.limit_resize * attrs.width);
664120d2c4d2Smrg	if ((int) high < attrs.height)
66422eaa94a1Schristos	    high = (Dimension) attrs.height;
6643d522f475Smrg	if (askedHeight > high)
6644d522f475Smrg	    askedHeight = high;
664520d2c4d2Smrg	if ((int) wide < attrs.width)
66462eaa94a1Schristos	    wide = (Dimension) attrs.width;
6647d522f475Smrg	if (askedWidth > wide)
6648d522f475Smrg	    askedWidth = wide;
6649d522f475Smrg    }
6650d522f475Smrg#ifndef nothack
6651d522f475Smrg    getXtermSizeHints(xw);
6652d522f475Smrg#endif
6653d522f475Smrg
6654956cc18dSsnj    TRACE(("...requesting resize %dx%d\n", askedHeight, askedWidth));
66552eaa94a1Schristos    status = REQ_RESIZE((Widget) xw,
66562eaa94a1Schristos			askedWidth, askedHeight,
66572eaa94a1Schristos			&replyWidth, &replyHeight);
6658d522f475Smrg
6659d522f475Smrg    if (status == XtGeometryYes ||
6660d522f475Smrg	status == XtGeometryDone) {
6661d522f475Smrg	ScreenResize(xw, replyWidth, replyHeight, &xw->flags);
6662d522f475Smrg    }
6663d522f475Smrg#ifndef nothack
6664d522f475Smrg    /*
6665d522f475Smrg     * XtMakeResizeRequest() has the undesirable side-effect of clearing
6666d522f475Smrg     * the window manager's hints, even on a failed request.  This would
6667d522f475Smrg     * presumably be fixed if the shell did its own work.
6668d522f475Smrg     */
6669d522f475Smrg    if (xw->hints.flags
6670d522f475Smrg	&& replyHeight
6671d522f475Smrg	&& replyWidth) {
6672d522f475Smrg	xw->hints.height = replyHeight;
6673d522f475Smrg	xw->hints.width = replyWidth;
6674d522f475Smrg
6675d522f475Smrg	TRACE(("%s@%d -- ", __FILE__, __LINE__));
6676d522f475Smrg	TRACE_HINTS(&xw->hints);
6677a1f3da82Smrg	XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints);
6678d522f475Smrg	TRACE(("%s@%d -- ", __FILE__, __LINE__));
6679d522f475Smrg	TRACE_WM_HINTS(xw);
6680d522f475Smrg    }
6681d522f475Smrg#endif
6682d522f475Smrg
6683d522f475Smrg    XSync(screen->display, False);	/* synchronize */
66840bd37d32Smrg    if (xtermAppPending())
6685d522f475Smrg	xevents();
6686d522f475Smrg
6687d522f475Smrg    TRACE(("...RequestResize done\n"));
6688d522f475Smrg}
6689d522f475Smrg
6690d522f475Smrgstatic String xterm_trans =
6691d522f475Smrg"<ClientMessage>WM_PROTOCOLS: DeleteWindow()\n\
6692d522f475Smrg     <MappingNotify>: KeyboardMapping()\n";
6693d522f475Smrg
6694d522f475Smrgint
6695956cc18dSsnjVTInit(XtermWidget xw)
6696d522f475Smrg{
6697956cc18dSsnj    Widget vtparent = SHELL_OF(xw);
6698d522f475Smrg
6699d522f475Smrg    TRACE(("VTInit {{\n"));
6700d522f475Smrg
6701d522f475Smrg    XtRealizeWidget(vtparent);
6702d522f475Smrg    XtOverrideTranslations(vtparent, XtParseTranslationTable(xterm_trans));
6703d522f475Smrg    (void) XSetWMProtocols(XtDisplay(vtparent), XtWindow(vtparent),
6704d522f475Smrg			   &wm_delete_window, 1);
6705d522f475Smrg    TRACE_TRANS("shell", vtparent);
6706956cc18dSsnj    TRACE_TRANS("vt100", (Widget) (xw));
6707d522f475Smrg
6708956cc18dSsnj    ScrnAllocBuf(xw);
6709d522f475Smrg
6710d522f475Smrg    TRACE(("...}} VTInit\n"));
6711d522f475Smrg    return (1);
6712d522f475Smrg}
6713d522f475Smrg
6714d522f475Smrgstatic void
6715d522f475SmrgVTClassInit(void)
6716d522f475Smrg{
6717d522f475Smrg    XtAddConverter(XtRString, XtRGravity, XmuCvtStringToGravity,
6718d522f475Smrg		   (XtConvertArgList) NULL, (Cardinal) 0);
6719d522f475Smrg}
6720d522f475Smrg
6721d522f475Smrg#if OPT_COLOR_RES
6722d522f475Smrg/*
6723d522f475Smrg * Override the use of XtDefaultForeground/XtDefaultBackground to make some
6724d522f475Smrg * colors, such as cursor color, use the actual foreground/background value
6725d522f475Smrg * if there is no explicit resource value used.
6726d522f475Smrg */
6727d522f475Smrgstatic Pixel
6728d522f475Smrgfill_Tres(XtermWidget target, XtermWidget source, int offset)
6729d522f475Smrg{
6730d522f475Smrg    char *name;
6731d522f475Smrg    ScrnColors temp;
67320bd37d32Smrg    TScreen *src = TScreenOf(source);
67330bd37d32Smrg    TScreen *dst = TScreenOf(target);
6734d522f475Smrg
67350bd37d32Smrg    dst->Tcolors[offset] = src->Tcolors[offset];
67360bd37d32Smrg    dst->Tcolors[offset].mode = False;
6737d522f475Smrg
67380bd37d32Smrg    if ((name = x_strtrim(dst->Tcolors[offset].resource)) != 0)
67390bd37d32Smrg	dst->Tcolors[offset].resource = name;
6740d522f475Smrg
6741d522f475Smrg    if (name == 0) {
67420bd37d32Smrg	dst->Tcolors[offset].value = target->dft_foreground;
6743d522f475Smrg    } else if (isDefaultForeground(name)) {
67440bd37d32Smrg	dst->Tcolors[offset].value = ((offset == TEXT_FG || offset == TEXT_BG)
67450bd37d32Smrg				      ? target->dft_foreground
67460bd37d32Smrg				      : dst->Tcolors[TEXT_FG].value);
6747d522f475Smrg    } else if (isDefaultBackground(name)) {
67480bd37d32Smrg	dst->Tcolors[offset].value = ((offset == TEXT_FG || offset == TEXT_BG)
67490bd37d32Smrg				      ? target->dft_background
67500bd37d32Smrg				      : dst->Tcolors[TEXT_BG].value);
6751d522f475Smrg    } else {
6752d522f475Smrg	memset(&temp, 0, sizeof(temp));
675320d2c4d2Smrg	if (AllocateTermColor(target, &temp, offset, name, True)) {
6754d522f475Smrg	    if (COLOR_DEFINED(&(temp), offset))
6755d522f475Smrg		free(temp.names[offset]);
67560bd37d32Smrg	    dst->Tcolors[offset].value = temp.colors[offset];
67570bd37d32Smrg	} else if (offset == TEXT_FG || offset == TEXT_BG) {
67580bd37d32Smrg	    free(name);
67590bd37d32Smrg	    dst->Tcolors[offset].resource = 0;
67600bd37d32Smrg	}
67610bd37d32Smrg    }
67620bd37d32Smrg    return dst->Tcolors[offset].value;
67630bd37d32Smrg}
67640bd37d32Smrg
67650bd37d32Smrg/*
67660bd37d32Smrg * If one or both of the foreground/background colors cannot be allocated,
67670bd37d32Smrg * e.g., due to gross misconfiguration, recover by setting both to the
67680bd37d32Smrg * display's default values.
67690bd37d32Smrg */
67700bd37d32Smrgstatic void
67710bd37d32SmrgrepairColors(XtermWidget target)
67720bd37d32Smrg{
67730bd37d32Smrg    TScreen *screen = TScreenOf(target);
67740bd37d32Smrg
67750bd37d32Smrg    if (screen->Tcolors[TEXT_FG].resource == 0 ||
67760bd37d32Smrg	screen->Tcolors[TEXT_BG].resource == 0) {
67770bd37d32Smrg	xtermWarning("unable to allocate fg/bg colors\n");
67780bd37d32Smrg	screen->Tcolors[TEXT_FG].resource = x_strdup(XtDefaultForeground);
67790bd37d32Smrg	screen->Tcolors[TEXT_BG].resource = x_strdup(XtDefaultBackground);
67800bd37d32Smrg	if (screen->Tcolors[TEXT_FG].resource == 0 ||
67810bd37d32Smrg	    screen->Tcolors[TEXT_BG].resource == 0) {
67820bd37d32Smrg	    Exit(1);
6783d522f475Smrg	}
67840bd37d32Smrg	screen->Tcolors[TEXT_FG].value = target->dft_foreground;
67850bd37d32Smrg	screen->Tcolors[TEXT_BG].value = target->dft_background;
6786d522f475Smrg    }
6787d522f475Smrg}
6788d522f475Smrg#else
6789d522f475Smrg#define fill_Tres(target, source, offset) \
679020d2c4d2Smrg	TScreenOf(target)->Tcolors[offset] = TScreenOf(source)->Tcolors[offset]
67910bd37d32Smrg#define repairColors(target)	/* nothing */
6792d522f475Smrg#endif
6793d522f475Smrg
6794d522f475Smrg#if OPT_WIDE_CHARS
6795d522f475Smrgstatic void
679620d2c4d2SmrgVTInitialize_locale(XtermWidget xw)
6797d522f475Smrg{
679820d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6799d522f475Smrg    Bool is_utf8 = xtermEnvUTF8();
6800d522f475Smrg
6801d522f475Smrg    TRACE(("VTInitialize_locale\n"));
680220d2c4d2Smrg    TRACE(("... request screen.utf8_mode = %d\n", screen->utf8_mode));
6803e39b573cSmrg    TRACE(("... request screen.utf8_fonts = %d\n", screen->utf8_fonts));
6804d522f475Smrg
680520d2c4d2Smrg    if (screen->utf8_mode < 0)
680620d2c4d2Smrg	screen->utf8_mode = uFalse;
6807d522f475Smrg
680820d2c4d2Smrg    if (screen->utf8_mode > 3)
680920d2c4d2Smrg	screen->utf8_mode = uDefault;
6810d522f475Smrg
681120d2c4d2Smrg    screen->latin9_mode = 0;
681220d2c4d2Smrg    screen->unicode_font = 0;
6813d522f475Smrg#if OPT_LUIT_PROG
681420d2c4d2Smrg    xw->misc.callfilter = 0;
681520d2c4d2Smrg    xw->misc.use_encoding = 0;
6816d522f475Smrg
6817d522f475Smrg    TRACE(("... setup for luit:\n"));
681820d2c4d2Smrg    TRACE(("... request misc.locale_str = \"%s\"\n", xw->misc.locale_str));
6819d522f475Smrg
682020d2c4d2Smrg    if (screen->utf8_mode == uFalse) {
6821d522f475Smrg	TRACE(("... command-line +u8 overrides\n"));
6822d522f475Smrg    } else
6823d522f475Smrg#if OPT_MINI_LUIT
682420d2c4d2Smrg    if (x_strcasecmp(xw->misc.locale_str, "CHECKFONT") == 0) {
682520d2c4d2Smrg	int fl = (xw->misc.default_font.f_n
682620d2c4d2Smrg		  ? (int) strlen(xw->misc.default_font.f_n)
6827d522f475Smrg		  : 0);
6828d522f475Smrg	if (fl > 11
682920d2c4d2Smrg	    && x_strcasecmp(xw->misc.default_font.f_n + fl - 11,
6830d522f475Smrg			    "-ISO10646-1") == 0) {
683120d2c4d2Smrg	    screen->unicode_font = 1;
6832d522f475Smrg	    /* unicode font, use True */
6833d522f475Smrg#ifdef HAVE_LANGINFO_CODESET
6834d522f475Smrg	    if (!strcmp(xtermEnvEncoding(), "ANSI_X3.4-1968")
6835d522f475Smrg		|| !strcmp(xtermEnvEncoding(), "ISO-8859-1")) {
683620d2c4d2Smrg		if (screen->utf8_mode == uDefault)
683720d2c4d2Smrg		    screen->utf8_mode = uFalse;
6838d522f475Smrg	    } else if (!strcmp(xtermEnvEncoding(), "ISO-8859-15")) {
683920d2c4d2Smrg		if (screen->utf8_mode == uDefault)
684020d2c4d2Smrg		    screen->utf8_mode = uFalse;
684120d2c4d2Smrg		screen->latin9_mode = 1;
6842d522f475Smrg	    } else {
684320d2c4d2Smrg		xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1);
684420d2c4d2Smrg		screen->utf8_mode = uAlways;
6845d522f475Smrg	    }
6846d522f475Smrg#else
684720d2c4d2Smrg	    xw->misc.callfilter = is_utf8 ? 0 : 1;
684820d2c4d2Smrg	    screen->utf8_mode = uAlways;
6849d522f475Smrg#endif
6850d522f475Smrg	} else {
6851d522f475Smrg	    /* other encoding, use False */
685220d2c4d2Smrg	    if (screen->utf8_mode == uDefault) {
685320d2c4d2Smrg		screen->utf8_mode = is_utf8 ? uAlways : uFalse;
6854d522f475Smrg	    }
6855d522f475Smrg	}
6856d522f475Smrg    } else
6857d522f475Smrg#endif /* OPT_MINI_LUIT */
685820d2c4d2Smrg	if (x_strcasecmp(xw->misc.locale_str, "TRUE") == 0 ||
685920d2c4d2Smrg	    x_strcasecmp(xw->misc.locale_str, "ON") == 0 ||
686020d2c4d2Smrg	    x_strcasecmp(xw->misc.locale_str, "YES") == 0 ||
686120d2c4d2Smrg	    x_strcasecmp(xw->misc.locale_str, "AUTO") == 0 ||
686220d2c4d2Smrg	    strcmp(xw->misc.locale_str, "1") == 0) {
6863d522f475Smrg	/* when true ... fully obeying LC_CTYPE locale */
686420d2c4d2Smrg	xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1);
686520d2c4d2Smrg	screen->utf8_mode = uAlways;
686620d2c4d2Smrg    } else if (x_strcasecmp(xw->misc.locale_str, "FALSE") == 0 ||
686720d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "OFF") == 0 ||
686820d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "NO") == 0 ||
686920d2c4d2Smrg	       strcmp(xw->misc.locale_str, "0") == 0) {
6870d522f475Smrg	/* when false ... original value of utf8_mode is effective */
687120d2c4d2Smrg	if (screen->utf8_mode == uDefault) {
687220d2c4d2Smrg	    screen->utf8_mode = is_utf8 ? uAlways : uFalse;
6873d522f475Smrg	}
687420d2c4d2Smrg    } else if (x_strcasecmp(xw->misc.locale_str, "MEDIUM") == 0 ||
687520d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "SEMIAUTO") == 0) {
6876d522f475Smrg	/* when medium ... obeying locale only for UTF-8 and Asian */
6877d522f475Smrg	if (is_utf8) {
687820d2c4d2Smrg	    screen->utf8_mode = uAlways;
6879d522f475Smrg	} else if (
6880d522f475Smrg#ifdef MB_CUR_MAX
6881d522f475Smrg		      MB_CUR_MAX > 1 ||
6882d522f475Smrg#else
688320d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "ja", (size_t) 2) ||
688420d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "ko", (size_t) 2) ||
688520d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "zh", (size_t) 2) ||
688620d2c4d2Smrg#endif
688720d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "th", (size_t) 2) ||
688820d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "vi", (size_t) 2)) {
688920d2c4d2Smrg	    xw->misc.callfilter = 1;
689020d2c4d2Smrg	    screen->utf8_mode = uAlways;
6891d522f475Smrg	} else {
689220d2c4d2Smrg	    screen->utf8_mode = uFalse;
6893d522f475Smrg	}
689420d2c4d2Smrg    } else if (x_strcasecmp(xw->misc.locale_str, "UTF-8") == 0 ||
689520d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "UTF8") == 0) {
6896d522f475Smrg	/* when UTF-8 ... UTF-8 mode */
689720d2c4d2Smrg	screen->utf8_mode = uAlways;
6898d522f475Smrg    } else {
6899d522f475Smrg	/* other words are regarded as encoding name passed to luit */
690020d2c4d2Smrg	xw->misc.callfilter = 1;
690120d2c4d2Smrg	screen->utf8_mode = uAlways;
690220d2c4d2Smrg	xw->misc.use_encoding = 1;
6903d522f475Smrg    }
690420d2c4d2Smrg    TRACE(("... updated misc.callfilter = %s\n", BtoS(xw->misc.callfilter)));
690520d2c4d2Smrg    TRACE(("... updated misc.use_encoding = %s\n", BtoS(xw->misc.use_encoding)));
6906d522f475Smrg#else
690720d2c4d2Smrg    if (screen->utf8_mode == uDefault) {
690820d2c4d2Smrg	screen->utf8_mode = is_utf8 ? uAlways : uFalse;
6909d522f475Smrg    }
6910d522f475Smrg#endif /* OPT_LUIT_PROG */
6911d522f475Smrg
6912e39b573cSmrg    if (screen->utf8_fonts == uDefault) {
6913e39b573cSmrg	switch (screen->utf8_mode) {
6914e39b573cSmrg	case uFalse:
6915e39b573cSmrg	case uTrue:
6916e39b573cSmrg	    screen->utf8_fonts = screen->utf8_mode;
6917e39b573cSmrg	    break;
6918e39b573cSmrg	case uDefault:
6919e39b573cSmrg	    /* should not happen */
6920e39b573cSmrg	    screen->utf8_fonts = uTrue;
6921e39b573cSmrg	    break;
6922e39b573cSmrg	case uAlways:
6923e39b573cSmrg	    /* use this to disable menu entry */
6924e39b573cSmrg	    break;
6925e39b573cSmrg	}
6926e39b573cSmrg    }
6927e39b573cSmrg
692820d2c4d2Smrg    screen->utf8_inparse = (Boolean) (screen->utf8_mode != uFalse);
6929d522f475Smrg
693020d2c4d2Smrg    TRACE(("... updated screen.utf8_mode = %d\n", screen->utf8_mode));
6931e39b573cSmrg    TRACE(("... updated screen.utf8_fonts = %d\n", screen->utf8_fonts));
6932d522f475Smrg    TRACE(("...VTInitialize_locale done\n"));
6933d522f475Smrg}
6934d522f475Smrg#endif
6935d522f475Smrg
69360bd37d32Smrgvoid
69370bd37d32SmrglookupSelectUnit(XtermWidget xw, Cardinal item, String value)
6938d522f475Smrg{
6939d522f475Smrg    /* *INDENT-OFF* */
6940d522f475Smrg    static struct {
694120d2c4d2Smrg	const char *	name;
6942d522f475Smrg	SelectUnit	code;
6943d522f475Smrg    } table[] = {
6944d522f475Smrg    	{ "char",	Select_CHAR },
6945d522f475Smrg    	{ "word",	Select_WORD },
6946d522f475Smrg    	{ "line",	Select_LINE },
6947d522f475Smrg    	{ "group",	Select_GROUP },
6948d522f475Smrg    	{ "page",	Select_PAGE },
6949d522f475Smrg    	{ "all",	Select_ALL },
6950d522f475Smrg#if OPT_SELECT_REGEX
6951d522f475Smrg    	{ "regex",	Select_REGEX },
6952d522f475Smrg#endif
6953d522f475Smrg    };
6954d522f475Smrg    /* *INDENT-ON* */
6955d522f475Smrg
69560bd37d32Smrg    TScreen *screen = TScreenOf(xw);
69570bd37d32Smrg    String next = x_skip_nonblanks(value);
6958d522f475Smrg    Cardinal n;
6959d522f475Smrg
69600bd37d32Smrg    screen->selectMap[item] = NSELECTUNITS;
6961d522f475Smrg    for (n = 0; n < XtNumber(table); ++n) {
69620bd37d32Smrg	if (!x_strncasecmp(table[n].name, value, (unsigned) (next - value))) {
69630bd37d32Smrg	    screen->selectMap[item] = table[n].code;
6964d522f475Smrg#if OPT_SELECT_REGEX
6965d522f475Smrg	    if (table[n].code == Select_REGEX) {
69660bd37d32Smrg		screen->selectExpr[item] = x_strtrim(next);
69670bd37d32Smrg		TRACE(("Parsed regex \"%s\"\n", screen->selectExpr[item]));
6968d522f475Smrg	    }
6969d522f475Smrg#endif
6970d522f475Smrg	    break;
6971d522f475Smrg	}
6972d522f475Smrg    }
6973d522f475Smrg}
6974d522f475Smrg
69750bd37d32Smrgstatic void
69760bd37d32SmrgParseOnClicks(XtermWidget wnew, XtermWidget wreq, Cardinal item)
69770bd37d32Smrg{
69780bd37d32Smrg    lookupSelectUnit(wnew, item, TScreenOf(wreq)->onClick[item]);
69790bd37d32Smrg}
69800bd37d32Smrg
698120d2c4d2Smrg/*
698220d2c4d2Smrg * Parse a comma-separated list, returning a string which the caller must
698320d2c4d2Smrg * free, and updating the source pointer.
698420d2c4d2Smrg */
698520d2c4d2Smrgstatic char *
698620d2c4d2SmrgParseList(const char **source)
698720d2c4d2Smrg{
698820d2c4d2Smrg    const char *base = *source;
698920d2c4d2Smrg    const char *next;
699020d2c4d2Smrg    size_t size;
699120d2c4d2Smrg    char *value = 0;
699220d2c4d2Smrg    char *result;
699320d2c4d2Smrg
699420d2c4d2Smrg    /* ignore empty values */
699520d2c4d2Smrg    while (*base == ',')
699620d2c4d2Smrg	++base;
699720d2c4d2Smrg    if (*base != '\0') {
699820d2c4d2Smrg	next = base;
699920d2c4d2Smrg	while (*next != '\0' && *next != ',')
700020d2c4d2Smrg	    ++next;
700120d2c4d2Smrg	size = (size_t) (1 + next - base);
700220d2c4d2Smrg	value = malloc(size);
700320d2c4d2Smrg	if (value != 0) {
700420d2c4d2Smrg	    memcpy(value, base, size);
700520d2c4d2Smrg	    value[size - 1] = '\0';
700620d2c4d2Smrg	}
700720d2c4d2Smrg	*source = next;
700820d2c4d2Smrg    } else {
700920d2c4d2Smrg	*source = base;
701020d2c4d2Smrg    }
701120d2c4d2Smrg    result = x_strtrim(value);
701220d2c4d2Smrg    free(value);
701320d2c4d2Smrg    return result;
701420d2c4d2Smrg}
701520d2c4d2Smrg
701620d2c4d2Smrgstatic void
701720d2c4d2Smrgset_flags_from_list(char *target,
701820d2c4d2Smrg		    const char *source,
701920d2c4d2Smrg		    FlagList * list,
702020d2c4d2Smrg		    Cardinal limit)
702120d2c4d2Smrg{
702220d2c4d2Smrg    Cardinal n;
702320d2c4d2Smrg    int value = -1;
702420d2c4d2Smrg
70250bd37d32Smrg    while (!IsEmpty(source)) {
702620d2c4d2Smrg	char *next = ParseList(&source);
702720d2c4d2Smrg	Boolean found = False;
702820d2c4d2Smrg
702920d2c4d2Smrg	if (next == 0)
703020d2c4d2Smrg	    break;
703120d2c4d2Smrg	if (isdigit(CharOf(*next))) {
703220d2c4d2Smrg	    char *temp;
703320d2c4d2Smrg
703420d2c4d2Smrg	    value = (int) strtol(next, &temp, 0);
703520d2c4d2Smrg	    if (!IsEmpty(temp)) {
70360bd37d32Smrg		xtermWarning("Expected a number: %s\n", next);
703720d2c4d2Smrg	    } else {
703820d2c4d2Smrg		for (n = 0; n < limit; ++n) {
703920d2c4d2Smrg		    if (list[n].code == value) {
704020d2c4d2Smrg			target[value] = 1;
704120d2c4d2Smrg			found = True;
704220d2c4d2Smrg			break;
704320d2c4d2Smrg		    }
704420d2c4d2Smrg		}
704520d2c4d2Smrg	    }
704620d2c4d2Smrg	} else {
704720d2c4d2Smrg	    for (n = 0; n < limit; ++n) {
704820d2c4d2Smrg		if (!x_strcasecmp(next, list[n].name)) {
704920d2c4d2Smrg		    value = list[n].code;
705020d2c4d2Smrg		    target[value] = 1;
705120d2c4d2Smrg		    found = True;
705220d2c4d2Smrg		    break;
705320d2c4d2Smrg		}
705420d2c4d2Smrg	    }
705520d2c4d2Smrg	}
705620d2c4d2Smrg	if (!found) {
70570bd37d32Smrg	    xtermWarning("Unrecognized keyword: %s\n", next);
705820d2c4d2Smrg	} else {
705920d2c4d2Smrg	    TRACE(("...found %s (%d)\n", next, value));
706020d2c4d2Smrg	}
706120d2c4d2Smrg	free(next);
706220d2c4d2Smrg    }
706320d2c4d2Smrg}
706420d2c4d2Smrg
7065d522f475Smrg/* ARGSUSED */
7066d522f475Smrgstatic void
7067d522f475SmrgVTInitialize(Widget wrequest,
7068d522f475Smrg	     Widget new_arg,
7069d522f475Smrg	     ArgList args GCC_UNUSED,
7070d522f475Smrg	     Cardinal *num_args GCC_UNUSED)
7071d522f475Smrg{
707220d2c4d2Smrg#define Kolor(name) TScreenOf(wnew)->name.resource
7073d522f475Smrg#define TxtFg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_FG]), Kolor(name))
7074d522f475Smrg#define TxtBg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_BG]), Kolor(name))
7075d522f475Smrg#define DftFg(name) isDefaultForeground(Kolor(name))
7076d522f475Smrg#define DftBg(name) isDefaultBackground(Kolor(name))
7077d522f475Smrg
707820d2c4d2Smrg#define DATA(name) { #name, ec##name }
707920d2c4d2Smrg    static FlagList tblColorOps[] =
708020d2c4d2Smrg    {
708120d2c4d2Smrg	DATA(SetColor)
708220d2c4d2Smrg	,DATA(GetColor)
708320d2c4d2Smrg	,DATA(GetAnsiColor)
708420d2c4d2Smrg    };
708520d2c4d2Smrg#undef DATA
708620d2c4d2Smrg
708720d2c4d2Smrg#define DATA(name) { #name, ef##name }
708820d2c4d2Smrg    static FlagList tblFontOps[] =
708920d2c4d2Smrg    {
709020d2c4d2Smrg	DATA(SetFont)
709120d2c4d2Smrg	,DATA(GetFont)
709220d2c4d2Smrg    };
709320d2c4d2Smrg#undef DATA
709420d2c4d2Smrg
709520d2c4d2Smrg#define DATA(name) { #name, et##name }
709620d2c4d2Smrg    static FlagList tblTcapOps[] =
709720d2c4d2Smrg    {
709820d2c4d2Smrg	DATA(SetTcap)
709920d2c4d2Smrg	,DATA(GetTcap)
710020d2c4d2Smrg    };
710120d2c4d2Smrg#undef DATA
710220d2c4d2Smrg
710320d2c4d2Smrg#define DATA(name) { #name, ew##name }
710420d2c4d2Smrg    static FlagList tblWindowOps[] =
710520d2c4d2Smrg    {
710620d2c4d2Smrg	DATA(RestoreWin)
710720d2c4d2Smrg	,DATA(MinimizeWin)
710820d2c4d2Smrg	,DATA(SetWinPosition)
710920d2c4d2Smrg	,DATA(SetWinSizePixels)
711020d2c4d2Smrg	,DATA(RaiseWin)
711120d2c4d2Smrg	,DATA(LowerWin)
711220d2c4d2Smrg	,DATA(RefreshWin)
711320d2c4d2Smrg	,DATA(SetWinSizeChars)
711420d2c4d2Smrg#if OPT_MAXIMIZE
711520d2c4d2Smrg	,DATA(MaximizeWin)
7116a1f3da82Smrg	,DATA(FullscreenWin)
711720d2c4d2Smrg#endif
711820d2c4d2Smrg	,DATA(GetWinState)
711920d2c4d2Smrg	,DATA(GetWinPosition)
712020d2c4d2Smrg	,DATA(GetWinSizePixels)
712120d2c4d2Smrg	,DATA(GetWinSizeChars)
712220d2c4d2Smrg#if OPT_MAXIMIZE
712320d2c4d2Smrg	,DATA(GetScreenSizeChars)
712420d2c4d2Smrg#endif
712520d2c4d2Smrg	,DATA(GetIconTitle)
712620d2c4d2Smrg	,DATA(GetWinTitle)
712720d2c4d2Smrg	,DATA(PushTitle)
712820d2c4d2Smrg	,DATA(PopTitle)
712920d2c4d2Smrg	,DATA(SetWinLines)
713020d2c4d2Smrg	,DATA(SetXprop)
713120d2c4d2Smrg	,DATA(GetSelection)
713220d2c4d2Smrg	,DATA(SetSelection)
713320d2c4d2Smrg    };
713420d2c4d2Smrg#undef DATA
713520d2c4d2Smrg
713620d2c4d2Smrg#if OPT_RENDERFONT
713720d2c4d2Smrg#define DATA(name) { #name, er##name }
713820d2c4d2Smrg    static FlagList tblRenderFont[] =
713920d2c4d2Smrg    {
714020d2c4d2Smrg	DATA(Default)
714120d2c4d2Smrg    };
714220d2c4d2Smrg#undef DATA
7143e39b573cSmrg#endif
7144e39b573cSmrg
7145e39b573cSmrg#if OPT_WIDE_CHARS
7146e39b573cSmrg#define DATA(name) { #name, u##name }
7147e39b573cSmrg    static FlagList tblUtf8Mode[] =
7148e39b573cSmrg    {
7149e39b573cSmrg	DATA(Always)
7150e39b573cSmrg	,DATA(Default)
7151e39b573cSmrg    };
7152e39b573cSmrg#undef DATA
715320d2c4d2Smrg#endif
715420d2c4d2Smrg
71550bd37d32Smrg#ifndef NO_ACTIVE_ICON
71560bd37d32Smrg#define DATA(name) { #name, ei##name }
71570bd37d32Smrg    static FlagList tblAIconOps[] =
71580bd37d32Smrg    {
71590bd37d32Smrg	DATA(Default)
71600bd37d32Smrg    };
71610bd37d32Smrg#undef DATA
71620bd37d32Smrg#endif
71630bd37d32Smrg
71640bd37d32Smrg#define DATA(name) { #name, eb##name }
71650bd37d32Smrg    static FlagList tbl8BitMeta[] =
71660bd37d32Smrg    {
71670bd37d32Smrg	DATA(Never)
71680bd37d32Smrg	,DATA(Locale)
71690bd37d32Smrg    };
71700bd37d32Smrg#undef DATA
71710bd37d32Smrg
7172d522f475Smrg    XtermWidget request = (XtermWidget) wrequest;
7173d522f475Smrg    XtermWidget wnew = (XtermWidget) new_arg;
7174d522f475Smrg    Widget my_parent = SHELL_OF(wnew);
7175d522f475Smrg    int i;
7176492d43a5Smrg    const char *s;
7177d522f475Smrg
7178d522f475Smrg#if OPT_ISO_COLORS
7179d522f475Smrg    Bool color_ok;
7180d522f475Smrg#endif
7181d522f475Smrg
718220d2c4d2Smrg#if OPT_COLOR_RES2
7183d522f475Smrg    static XtResource fake_resources[] =
7184d522f475Smrg    {
7185d522f475Smrg#if OPT_256_COLORS
7186d522f475Smrg# include <256colres.h>
7187d522f475Smrg#elif OPT_88_COLORS
7188d522f475Smrg# include <88colres.h>
7189d522f475Smrg#endif
7190d522f475Smrg    };
7191d522f475Smrg#endif /* OPT_COLOR_RES2 */
7192d522f475Smrg
719320d2c4d2Smrg    TRACE(("VTInitialize wnew %p, %d / %d resources\n",
719420d2c4d2Smrg	   (void *) wnew, XtNumber(xterm_resources), MAXRESOURCES));
719520d2c4d2Smrg    assert(XtNumber(xterm_resources) < MAXRESOURCES);
7196d522f475Smrg
7197d522f475Smrg    /* Zero out the entire "screen" component of "wnew" widget, then do
7198d522f475Smrg     * field-by-field assignment of "screen" fields that are named in the
7199d522f475Smrg     * resource list.
7200d522f475Smrg     */
720120d2c4d2Smrg    memset(TScreenOf(wnew), 0, sizeof(wnew->screen));
7202d522f475Smrg
7203d522f475Smrg    /* DESCO Sys#67660
7204d522f475Smrg     * Zero out the entire "keyboard" component of "wnew" widget.
7205d522f475Smrg     */
7206956cc18dSsnj    memset(&wnew->keyboard, 0, sizeof(wnew->keyboard));
7207d522f475Smrg
72080bd37d32Smrg    /*
72090bd37d32Smrg     * The workspace has no resources - clear it.
72100bd37d32Smrg     */
72110bd37d32Smrg    memset(&wnew->work, 0, sizeof(wnew->work));
72120bd37d32Smrg
7213d522f475Smrg    /* dummy values so that we don't try to Realize the parent shell with height
7214d522f475Smrg     * or width of 0, which is illegal in X.  The real size is computed in the
7215d522f475Smrg     * xtermWidget's Realize proc, but the shell's Realize proc is called first,
7216d522f475Smrg     * and must see a valid size.
7217d522f475Smrg     */
7218d522f475Smrg    wnew->core.height = wnew->core.width = 1;
7219d522f475Smrg
7220d522f475Smrg    /*
7221d522f475Smrg     * The definition of -rv now is that it changes the definition of
7222d522f475Smrg     * XtDefaultForeground and XtDefaultBackground.  So, we no longer
7223d522f475Smrg     * need to do anything special.
7224d522f475Smrg     */
722520d2c4d2Smrg    TScreenOf(wnew)->display = wnew->core.screen->display;
7226d522f475Smrg
7227d522f475Smrg    /*
7228d522f475Smrg     * We use the default foreground/background colors to compare/check if a
7229d522f475Smrg     * color-resource has been set.
7230d522f475Smrg     */
7231d522f475Smrg#define MyBlackPixel(dpy) BlackPixel(dpy,DefaultScreen(dpy))
7232d522f475Smrg#define MyWhitePixel(dpy) WhitePixel(dpy,DefaultScreen(dpy))
7233d522f475Smrg
7234d522f475Smrg    if (request->misc.re_verse) {
723520d2c4d2Smrg	wnew->dft_foreground = MyWhitePixel(TScreenOf(wnew)->display);
723620d2c4d2Smrg	wnew->dft_background = MyBlackPixel(TScreenOf(wnew)->display);
7237d522f475Smrg    } else {
723820d2c4d2Smrg	wnew->dft_foreground = MyBlackPixel(TScreenOf(wnew)->display);
723920d2c4d2Smrg	wnew->dft_background = MyWhitePixel(TScreenOf(wnew)->display);
7240d522f475Smrg    }
7241e39b573cSmrg
7242d522f475Smrg    init_Tres(TEXT_FG);
7243d522f475Smrg    init_Tres(TEXT_BG);
72440bd37d32Smrg    repairColors(wnew);
7245d522f475Smrg
7246e39b573cSmrg    wnew->old_foreground = T_COLOR(TScreenOf(wnew), TEXT_FG);
7247e39b573cSmrg    wnew->old_background = T_COLOR(TScreenOf(wnew), TEXT_BG);
7248e39b573cSmrg
7249d522f475Smrg    TRACE(("Color resource initialization:\n"));
7250e39b573cSmrg    TRACE(("   Default foreground 0x%06lx\n", wnew->dft_foreground));
7251e39b573cSmrg    TRACE(("   Default background 0x%06lx\n", wnew->dft_background));
7252e39b573cSmrg    TRACE(("   Screen foreground  0x%06lx\n", T_COLOR(TScreenOf(wnew), TEXT_FG)));
7253e39b573cSmrg    TRACE(("   Screen background  0x%06lx\n", T_COLOR(TScreenOf(wnew), TEXT_BG)));
7254e39b573cSmrg    TRACE(("   Actual  foreground 0x%06lx\n", wnew->old_foreground));
7255e39b573cSmrg    TRACE(("   Actual  background 0x%06lx\n", wnew->old_background));
7256d522f475Smrg
72570bd37d32Smrg    TScreenOf(wnew)->mouse_button = 0;
725820d2c4d2Smrg    TScreenOf(wnew)->mouse_row = -1;
725920d2c4d2Smrg    TScreenOf(wnew)->mouse_col = -1;
7260d522f475Smrg
7261d522f475Smrg#if OPT_BOX_CHARS
7262d522f475Smrg    init_Bres(screen.force_box_chars);
726320d2c4d2Smrg    init_Bres(screen.force_packed);
7264d522f475Smrg    init_Bres(screen.force_all_chars);
7265d522f475Smrg#endif
7266d522f475Smrg    init_Bres(screen.free_bold_box);
7267e39b573cSmrg    init_Bres(screen.allowBoldFonts);
7268d522f475Smrg
7269d522f475Smrg    init_Bres(screen.c132);
7270d522f475Smrg    init_Bres(screen.curses);
7271d522f475Smrg    init_Bres(screen.hp_ll_bc);
7272d522f475Smrg#if OPT_XMC_GLITCH
7273d522f475Smrg    init_Ires(screen.xmc_glitch);
7274d522f475Smrg    init_Ires(screen.xmc_attributes);
7275d522f475Smrg    init_Bres(screen.xmc_inline);
7276d522f475Smrg    init_Bres(screen.move_sgr_ok);
7277d522f475Smrg#endif
7278d522f475Smrg#if OPT_BLINK_CURS
7279d522f475Smrg    init_Bres(screen.cursor_blink);
7280d522f475Smrg    init_Ires(screen.blink_on);
7281d522f475Smrg    init_Ires(screen.blink_off);
728220d2c4d2Smrg    TScreenOf(wnew)->cursor_blink_res = TScreenOf(wnew)->cursor_blink;
7283d522f475Smrg#endif
72840bd37d32Smrg    /* resources allow for underline or block, not (yet) bar */
72850bd37d32Smrg    TScreenOf(wnew)->cursor_shape = request->screen.cursor_underline
72860bd37d32Smrg	? CURSOR_UNDERLINE
72870bd37d32Smrg	: CURSOR_BLOCK;
7288d522f475Smrg#if OPT_BLINK_TEXT
7289d522f475Smrg    init_Ires(screen.blink_as_bold);
7290d522f475Smrg#endif
7291d522f475Smrg    init_Ires(screen.border);
7292d522f475Smrg    init_Bres(screen.jumpscroll);
7293956cc18dSsnj    init_Bres(screen.fastscroll);
7294d522f475Smrg    init_Bres(screen.old_fkeys);
7295d522f475Smrg    init_Bres(screen.delete_is_del);
729620d2c4d2Smrg    wnew->keyboard.type = TScreenOf(wnew)->old_fkeys
7297d522f475Smrg	? keyboardIsLegacy
7298d522f475Smrg	: keyboardIsDefault;
7299d522f475Smrg#ifdef ALLOWLOGGING
7300492d43a5Smrg    init_Bres(misc.logInhibit);
7301492d43a5Smrg    init_Bres(misc.log_on);
7302d522f475Smrg    init_Sres(screen.logfile);
7303d522f475Smrg#endif
7304d522f475Smrg    init_Bres(screen.bellIsUrgent);
7305d522f475Smrg    init_Bres(screen.bellOnReset);
7306d522f475Smrg    init_Bres(screen.marginbell);
7307d522f475Smrg    init_Bres(screen.multiscroll);
7308d522f475Smrg    init_Ires(screen.nmarginbell);
7309d522f475Smrg    init_Ires(screen.savelines);
7310d522f475Smrg    init_Ires(screen.scrollBarBorder);
7311d522f475Smrg    init_Ires(screen.scrolllines);
73120bd37d32Smrg    init_Bres(screen.alternateScroll);
7313d522f475Smrg    init_Bres(screen.scrollttyoutput);
7314d522f475Smrg    init_Bres(screen.scrollkey);
7315d522f475Smrg
73160bd37d32Smrg    init_Dres(screen.scale_height);
73170bd37d32Smrg    if (TScreenOf(wnew)->scale_height < 0.9)
73180bd37d32Smrg	TScreenOf(wnew)->scale_height = (float) 0.9;
73190bd37d32Smrg    if (TScreenOf(wnew)->scale_height > 1.5)
73200bd37d32Smrg	TScreenOf(wnew)->scale_height = (float) 1.5;
73210bd37d32Smrg
7322492d43a5Smrg    init_Bres(misc.autoWrap);
7323492d43a5Smrg    init_Bres(misc.login_shell);
7324492d43a5Smrg    init_Bres(misc.reverseWrap);
7325492d43a5Smrg    init_Bres(misc.scrollbar);
7326492d43a5Smrg    init_Sres(misc.geo_metry);
7327492d43a5Smrg    init_Sres(misc.T_geometry);
7328492d43a5Smrg
7329d522f475Smrg    init_Sres(screen.term_id);
733020d2c4d2Smrg    for (s = TScreenOf(request)->term_id; *s; s++) {
7331d522f475Smrg	if (!isalpha(CharOf(*s)))
7332d522f475Smrg	    break;
7333d522f475Smrg    }
733420d2c4d2Smrg    TScreenOf(wnew)->terminal_id = atoi(s);
733520d2c4d2Smrg    if (TScreenOf(wnew)->terminal_id < MIN_DECID)
733620d2c4d2Smrg	TScreenOf(wnew)->terminal_id = MIN_DECID;
733720d2c4d2Smrg    if (TScreenOf(wnew)->terminal_id > MAX_DECID)
733820d2c4d2Smrg	TScreenOf(wnew)->terminal_id = MAX_DECID;
7339d522f475Smrg    TRACE(("term_id '%s' -> terminal_id %d\n",
734020d2c4d2Smrg	   TScreenOf(wnew)->term_id,
734120d2c4d2Smrg	   TScreenOf(wnew)->terminal_id));
734220d2c4d2Smrg
734320d2c4d2Smrg    TScreenOf(wnew)->vtXX_level = (TScreenOf(wnew)->terminal_id / 100);
7344d522f475Smrg
734520d2c4d2Smrg    init_Ires(screen.title_modes);
7346d522f475Smrg    init_Bres(screen.visualbell);
73470bd37d32Smrg    init_Bres(screen.flash_line);
7348d522f475Smrg    init_Ires(screen.visualBellDelay);
7349d522f475Smrg    init_Bres(screen.poponbell);
7350d522f475Smrg    init_Ires(misc.limit_resize);
735120d2c4d2Smrg
7352d522f475Smrg#if OPT_NUM_LOCK
7353d522f475Smrg    init_Bres(misc.real_NumLock);
7354d522f475Smrg    init_Bres(misc.alwaysUseMods);
7355d522f475Smrg#endif
735620d2c4d2Smrg
7357492d43a5Smrg#if OPT_INPUT_METHOD
7358492d43a5Smrg    init_Bres(misc.open_im);
7359492d43a5Smrg    init_Ires(misc.retry_im);
7360492d43a5Smrg    init_Sres(misc.f_x);
7361492d43a5Smrg    init_Sres(misc.input_method);
7362492d43a5Smrg    init_Sres(misc.preedit_type);
7363492d43a5Smrg#endif
7364492d43a5Smrg
7365d522f475Smrg#if OPT_SHIFT_FONTS
7366d522f475Smrg    init_Bres(misc.shift_fonts);
7367d522f475Smrg#endif
7368d522f475Smrg#if OPT_SUNPC_KBD
7369d522f475Smrg    init_Ires(misc.ctrl_fkeys);
7370d522f475Smrg#endif
7371d522f475Smrg#if OPT_TEK4014
7372d522f475Smrg    TEK4014_SHOWN(wnew) = False;	/* not a resource... */
7373d522f475Smrg    init_Bres(misc.tekInhibit);
7374d522f475Smrg    init_Bres(misc.tekSmall);
7375d522f475Smrg    init_Bres(misc.TekEmu);
7376d522f475Smrg#endif
7377d522f475Smrg#if OPT_TCAP_QUERY
737820d2c4d2Smrg    TScreenOf(wnew)->tc_query_code = -1;
7379d522f475Smrg#endif
7380d522f475Smrg    wnew->misc.re_verse0 = request->misc.re_verse;
7381d522f475Smrg    init_Bres(misc.re_verse);
7382d522f475Smrg    init_Ires(screen.multiClickTime);
7383d522f475Smrg    init_Ires(screen.bellSuppressTime);
7384d522f475Smrg    init_Sres(screen.charClass);
7385d522f475Smrg
7386d522f475Smrg    init_Bres(screen.always_highlight);
7387d522f475Smrg    init_Bres(screen.brokenSelections);
7388d522f475Smrg    init_Bres(screen.cutNewline);
7389d522f475Smrg    init_Bres(screen.cutToBeginningOfLine);
7390d522f475Smrg    init_Bres(screen.highlight_selection);
7391492d43a5Smrg    init_Bres(screen.show_wrap_marks);
7392d522f475Smrg    init_Bres(screen.i18nSelections);
7393d522f475Smrg    init_Bres(screen.keepSelection);
7394d522f475Smrg    init_Bres(screen.selectToClipboard);
7395d522f475Smrg    init_Bres(screen.trim_selection);
7396d522f475Smrg
739720d2c4d2Smrg    TScreenOf(wnew)->pointer_cursor = TScreenOf(request)->pointer_cursor;
7398d522f475Smrg    init_Ires(screen.pointer_mode);
7399d522f475Smrg
7400d522f475Smrg    init_Sres(screen.answer_back);
7401d522f475Smrg
74020bd37d32Smrg    wnew->SPS.printer_checked = False;
7403e39b573cSmrg    init_Sres(SPS.printer_command);
7404e39b573cSmrg    init_Bres(SPS.printer_autoclose);
7405e39b573cSmrg    init_Bres(SPS.printer_extent);
7406e39b573cSmrg    init_Bres(SPS.printer_formfeed);
7407e39b573cSmrg    init_Bres(SPS.printer_newline);
7408e39b573cSmrg    init_Ires(SPS.printer_controlmode);
7409d522f475Smrg#if OPT_PRINT_COLORS
7410e39b573cSmrg    init_Ires(SPS.print_attributes);
7411d522f475Smrg#endif
7412d522f475Smrg
7413d522f475Smrg    init_Sres(screen.keyboard_dialect);
7414d522f475Smrg
7415d522f475Smrg    init_Bres(screen.input_eight_bits);
7416d522f475Smrg    init_Bres(screen.output_eight_bits);
7417d522f475Smrg    init_Bres(screen.control_eight_bits);
7418d522f475Smrg    init_Bres(screen.backarrow_key);
7419d522f475Smrg    init_Bres(screen.alt_is_not_meta);
7420d522f475Smrg    init_Bres(screen.alt_sends_esc);
7421d522f475Smrg    init_Bres(screen.meta_sends_esc);
7422d522f475Smrg
74230bd37d32Smrg    init_Bres(screen.allowPasteControls);
7424d522f475Smrg    init_Bres(screen.allowSendEvent0);
742520d2c4d2Smrg    init_Bres(screen.allowColorOp0);
74262eaa94a1Schristos    init_Bres(screen.allowFontOp0);
74272eaa94a1Schristos    init_Bres(screen.allowTcapOp0);
7428d522f475Smrg    init_Bres(screen.allowTitleOp0);
7429d522f475Smrg    init_Bres(screen.allowWindowOp0);
7430d522f475Smrg
743120d2c4d2Smrg#if OPT_SCROLL_LOCK
743220d2c4d2Smrg    init_Bres(screen.allowScrollLock0);
743320d2c4d2Smrg#endif
743420d2c4d2Smrg
743520d2c4d2Smrg    init_Sres(screen.disallowedColorOps);
743620d2c4d2Smrg
743720d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_color_ops,
743820d2c4d2Smrg			TScreenOf(wnew)->disallowedColorOps,
743920d2c4d2Smrg			tblColorOps,
744020d2c4d2Smrg			ecLAST);
744120d2c4d2Smrg
744220d2c4d2Smrg    init_Sres(screen.disallowedFontOps);
744320d2c4d2Smrg
744420d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_font_ops,
744520d2c4d2Smrg			TScreenOf(wnew)->disallowedFontOps,
744620d2c4d2Smrg			tblFontOps,
744720d2c4d2Smrg			efLAST);
744820d2c4d2Smrg
744920d2c4d2Smrg    init_Sres(screen.disallowedTcapOps);
745020d2c4d2Smrg
745120d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_tcap_ops,
745220d2c4d2Smrg			TScreenOf(wnew)->disallowedTcapOps,
745320d2c4d2Smrg			tblTcapOps,
745420d2c4d2Smrg			etLAST);
745520d2c4d2Smrg
745620d2c4d2Smrg    init_Sres(screen.disallowedWinOps);
745720d2c4d2Smrg
745820d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_win_ops,
745920d2c4d2Smrg			TScreenOf(wnew)->disallowedWinOps,
746020d2c4d2Smrg			tblWindowOps,
746120d2c4d2Smrg			ewLAST);
746220d2c4d2Smrg
7463956cc18dSsnj    init_Sres(screen.default_string);
7464956cc18dSsnj    init_Sres(screen.eightbit_select_types);
7465956cc18dSsnj#if OPT_WIDE_CHARS
7466956cc18dSsnj    init_Sres(screen.utf8_select_types);
7467956cc18dSsnj#endif
7468956cc18dSsnj
7469d522f475Smrg    /* make a copy so that editres cannot change the resource after startup */
747020d2c4d2Smrg    TScreenOf(wnew)->allowSendEvents = TScreenOf(wnew)->allowSendEvent0;
747120d2c4d2Smrg    TScreenOf(wnew)->allowColorOps = TScreenOf(wnew)->allowColorOp0;
747220d2c4d2Smrg    TScreenOf(wnew)->allowFontOps = TScreenOf(wnew)->allowFontOp0;
747320d2c4d2Smrg    TScreenOf(wnew)->allowTcapOps = TScreenOf(wnew)->allowTcapOp0;
747420d2c4d2Smrg    TScreenOf(wnew)->allowTitleOps = TScreenOf(wnew)->allowTitleOp0;
747520d2c4d2Smrg    TScreenOf(wnew)->allowWindowOps = TScreenOf(wnew)->allowWindowOp0;
747620d2c4d2Smrg
747720d2c4d2Smrg#if OPT_SCROLL_LOCK
747820d2c4d2Smrg    TScreenOf(wnew)->allowScrollLock = TScreenOf(wnew)->allowScrollLock0;
747920d2c4d2Smrg#endif
7480d522f475Smrg
7481d522f475Smrg    init_Bres(screen.quiet_grab);
7482d522f475Smrg
7483d522f475Smrg#ifndef NO_ACTIVE_ICON
7484492d43a5Smrg    init_Sres(screen.icon_fontname);
7485492d43a5Smrg    TScreenOf(wnew)->fnt_icon.fs = XLoadQueryFont(TScreenOf(wnew)->display,
7486492d43a5Smrg						  TScreenOf(wnew)->icon_fontname);
7487492d43a5Smrg    TRACE(("iconFont '%s' %sloaded successfully\n",
7488492d43a5Smrg	   TScreenOf(wnew)->icon_fontname,
7489492d43a5Smrg	   TScreenOf(wnew)->fnt_icon.fs ? "" : "NOT "));
74900bd37d32Smrg    init_Sres(misc.active_icon_s);
74910bd37d32Smrg    wnew->work.active_icon =
74920bd37d32Smrg	(Boolean) extendedBoolean(wnew->misc.active_icon_s,
74930bd37d32Smrg				  tblAIconOps, eiLAST);
7494d522f475Smrg    init_Ires(misc.icon_border_width);
7495d522f475Smrg    wnew->misc.icon_border_pixel = request->misc.icon_border_pixel;
7496d522f475Smrg#endif /* NO_ACTIVE_ICON */
7497492d43a5Smrg
7498492d43a5Smrg    init_Bres(misc.signalInhibit);
7499d522f475Smrg    init_Bres(misc.titeInhibit);
7500d522f475Smrg    init_Bres(misc.tiXtraScroll);
75010bd37d32Smrg    init_Bres(misc.cdXtraScroll);
7502d522f475Smrg    init_Bres(misc.dynamicColors);
7503d522f475Smrg    for (i = fontMenu_font1; i <= fontMenu_lastBuiltin; i++) {
75042eaa94a1Schristos	init_Sres2(screen.MenuFontName, i);
7505d522f475Smrg    }
7506956cc18dSsnj    init_Ires(misc.fontWarnings);
750720d2c4d2Smrg#define DefaultFontNames TScreenOf(wnew)->menu_font_names[fontMenu_default]
7508492d43a5Smrg    init_Sres(misc.default_font.f_n);
7509492d43a5Smrg    init_Sres(misc.default_font.f_b);
7510492d43a5Smrg    DefaultFontNames[fNorm] = x_strdup(wnew->misc.default_font.f_n);
7511492d43a5Smrg    DefaultFontNames[fBold] = x_strdup(wnew->misc.default_font.f_b);
7512956cc18dSsnj#if OPT_WIDE_CHARS
7513492d43a5Smrg    init_Sres(misc.default_font.f_w);
7514492d43a5Smrg    init_Sres(misc.default_font.f_wb);
7515492d43a5Smrg    DefaultFontNames[fWide] = x_strdup(wnew->misc.default_font.f_w);
7516492d43a5Smrg    DefaultFontNames[fWBold] = x_strdup(wnew->misc.default_font.f_wb);
7517956cc18dSsnj#endif
751820d2c4d2Smrg    TScreenOf(wnew)->MenuFontName(fontMenu_fontescape) = NULL;
751920d2c4d2Smrg    TScreenOf(wnew)->MenuFontName(fontMenu_fontsel) = NULL;
7520d522f475Smrg
752120d2c4d2Smrg    TScreenOf(wnew)->menu_font_number = fontMenu_default;
7522d522f475Smrg    init_Sres(screen.initial_font);
752320d2c4d2Smrg    if (TScreenOf(wnew)->initial_font != 0) {
752420d2c4d2Smrg	int result = xtermGetFont(TScreenOf(wnew)->initial_font);
7525d522f475Smrg	if (result >= 0)
752620d2c4d2Smrg	    TScreenOf(wnew)->menu_font_number = result;
7527d522f475Smrg    }
7528d522f475Smrg#if OPT_BROKEN_OSC
7529d522f475Smrg    init_Bres(screen.brokenLinuxOSC);
7530d522f475Smrg#endif
7531d522f475Smrg
7532d522f475Smrg#if OPT_BROKEN_ST
7533d522f475Smrg    init_Bres(screen.brokenStringTerm);
7534d522f475Smrg#endif
7535d522f475Smrg
7536d522f475Smrg#if OPT_C1_PRINT
7537d522f475Smrg    init_Bres(screen.c1_printable);
7538d522f475Smrg#endif
7539d522f475Smrg
7540d522f475Smrg#if OPT_CLIP_BOLD
7541d522f475Smrg    init_Bres(screen.use_clipping);
7542d522f475Smrg#endif
7543d522f475Smrg
7544d522f475Smrg#if OPT_DEC_CHRSET
7545d522f475Smrg    init_Bres(screen.font_doublesize);
7546d522f475Smrg    init_Ires(screen.cache_doublesize);
754720d2c4d2Smrg    if (TScreenOf(wnew)->cache_doublesize > NUM_CHRSET)
754820d2c4d2Smrg	TScreenOf(wnew)->cache_doublesize = NUM_CHRSET;
754920d2c4d2Smrg    if (TScreenOf(wnew)->cache_doublesize == 0)
755020d2c4d2Smrg	TScreenOf(wnew)->font_doublesize = False;
7551d522f475Smrg    TRACE(("Doublesize%s enabled, up to %d fonts\n",
755220d2c4d2Smrg	   TScreenOf(wnew)->font_doublesize ? "" : " not",
755320d2c4d2Smrg	   TScreenOf(wnew)->cache_doublesize));
7554d522f475Smrg#endif
7555d522f475Smrg
7556d522f475Smrg#if OPT_ISO_COLORS
7557d522f475Smrg    init_Ires(screen.veryBoldColors);
7558d522f475Smrg    init_Bres(screen.boldColors);
7559d522f475Smrg    init_Bres(screen.colorAttrMode);
7560d522f475Smrg    init_Bres(screen.colorBDMode);
7561d522f475Smrg    init_Bres(screen.colorBLMode);
7562d522f475Smrg    init_Bres(screen.colorMode);
7563d522f475Smrg    init_Bres(screen.colorULMode);
7564d522f475Smrg    init_Bres(screen.italicULMode);
7565d522f475Smrg    init_Bres(screen.colorRVMode);
7566d522f475Smrg
756720d2c4d2Smrg#if OPT_COLOR_RES2
756820d2c4d2Smrg    TRACE(("...will fake resources for color%d to color%d\n",
756920d2c4d2Smrg	   MIN_ANSI_COLORS,
757020d2c4d2Smrg	   NUM_ANSI_COLORS - 1));
757120d2c4d2Smrg#endif
7572d522f475Smrg    for (i = 0, color_ok = False; i < MAXCOLORS; i++) {
7573d522f475Smrg
757420d2c4d2Smrg#if OPT_COLOR_RES2
7575d522f475Smrg	/*
7576d522f475Smrg	 * Xt has a hardcoded limit on the maximum number of resources that can
7577d522f475Smrg	 * be used in a widget.  If we configure both luit (which implies
7578d522f475Smrg	 * wide-characters) and 256-colors, it goes over that limit.  Most
7579d522f475Smrg	 * people would not need a resource-file with 256-colors; the default
7580d522f475Smrg	 * values in our table are sufficient.  In that case, fake the resource
7581d522f475Smrg	 * setting by copying the default value from the table.  The #define's
7582d522f475Smrg	 * can be overridden to make these true resources.
7583d522f475Smrg	 */
7584d522f475Smrg	if (i >= MIN_ANSI_COLORS && i < NUM_ANSI_COLORS) {
75856879286fSmrg	    TScreenOf(wnew)->Acolors[i].resource =
75866879286fSmrg		x_strtrim(fake_resources[i - MIN_ANSI_COLORS].default_addr);
758720d2c4d2Smrg	    if (TScreenOf(wnew)->Acolors[i].resource == 0)
758820d2c4d2Smrg		TScreenOf(wnew)->Acolors[i].resource = XtDefaultForeground;
7589d522f475Smrg	} else
7590d522f475Smrg#endif /* OPT_COLOR_RES2 */
75916879286fSmrg	{
759220d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i] = TScreenOf(request)->Acolors[i];
75936879286fSmrg	    TScreenOf(wnew)->Acolors[i].resource =
75946879286fSmrg		x_strtrim(TScreenOf(wnew)->Acolors[i].resource);
75956879286fSmrg	}
7596d522f475Smrg
7597d522f475Smrg#if OPT_COLOR_RES
759820d2c4d2Smrg	TRACE(("Acolors[%d] = %s\n", i, TScreenOf(wnew)->Acolors[i].resource));
759920d2c4d2Smrg	TScreenOf(wnew)->Acolors[i].mode = False;
7600d522f475Smrg	if (DftFg(Acolors[i])) {
760120d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].value = T_COLOR(TScreenOf(wnew), TEXT_FG);
760220d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].mode = True;
7603d522f475Smrg	} else if (DftBg(Acolors[i])) {
760420d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].value = T_COLOR(TScreenOf(wnew), TEXT_BG);
760520d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].mode = True;
7606d522f475Smrg	} else {
7607d522f475Smrg	    color_ok = True;
7608d522f475Smrg	}
7609d522f475Smrg#else
761020d2c4d2Smrg	TRACE(("Acolors[%d] = %#lx\n", i, TScreenOf(request)->Acolors[i]));
761120d2c4d2Smrg	if (TScreenOf(wnew)->Acolors[i] != wnew->dft_foreground &&
761220d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i] != T_COLOR(TScreenOf(wnew), TEXT_FG) &&
761320d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i] != T_COLOR(TScreenOf(wnew), TEXT_BG))
7614d522f475Smrg	    color_ok = True;
7615d522f475Smrg#endif
7616d522f475Smrg    }
7617d522f475Smrg
7618d522f475Smrg    /*
7619d522f475Smrg     * Check if we're trying to use color in a monochrome screen.  Disable
7620d522f475Smrg     * color in that case, since that would make ANSI colors unusable.  A 4-bit
7621d522f475Smrg     * or 8-bit display is usable, so we do not have to check for anything more
7622d522f475Smrg     * specific.
7623d522f475Smrg     */
7624d522f475Smrg    if (color_ok) {
76250bd37d32Smrg	if (getVisualDepth(wnew) <= 1) {
7626d522f475Smrg	    TRACE(("disabling color since screen is monochrome\n"));
7627d522f475Smrg	    color_ok = False;
7628d522f475Smrg	}
7629d522f475Smrg    }
7630d522f475Smrg
7631d522f475Smrg    /* If none of the colors are anything other than the foreground or
7632d522f475Smrg     * background, we'll assume this isn't color, no matter what the colorMode
7633d522f475Smrg     * resource says.  (There doesn't seem to be any good way to determine if
7634d522f475Smrg     * the resource lookup failed versus the user having misconfigured this).
7635d522f475Smrg     */
7636d522f475Smrg    if (!color_ok) {
763720d2c4d2Smrg	TScreenOf(wnew)->colorMode = False;
7638d522f475Smrg	TRACE(("All colors are foreground or background: disable colorMode\n"));
7639d522f475Smrg    }
7640d522f475Smrg    wnew->sgr_foreground = -1;
7641d522f475Smrg    wnew->sgr_background = -1;
7642d522f475Smrg    wnew->sgr_extended = False;
7643d522f475Smrg#endif /* OPT_ISO_COLORS */
7644d522f475Smrg
7645d522f475Smrg    /*
7646d522f475Smrg     * Decode the resources that control the behavior on multiple mouse clicks.
7647d522f475Smrg     * A single click is always bound to normal character selection, but the
7648d522f475Smrg     * other flavors can be changed.
7649d522f475Smrg     */
7650d522f475Smrg    for (i = 0; i < NSELECTUNITS; ++i) {
7651d522f475Smrg	int ck = (i + 1);
765220d2c4d2Smrg	TScreenOf(wnew)->maxClicks = ck;
7653d522f475Smrg	if (i == Select_CHAR)
765420d2c4d2Smrg	    TScreenOf(wnew)->selectMap[i] = Select_CHAR;
765520d2c4d2Smrg	else if (TScreenOf(request)->onClick[i] != 0)
7656d522f475Smrg	    ParseOnClicks(wnew, request, (unsigned) i);
7657d522f475Smrg	else if (i <= Select_LINE)
765820d2c4d2Smrg	    TScreenOf(wnew)->selectMap[i] = (SelectUnit) i;
7659d522f475Smrg	else
7660d522f475Smrg	    break;
7661d522f475Smrg	TRACE(("on%dClicks %s=%d\n", ck,
766220d2c4d2Smrg	       NonNull(TScreenOf(request)->onClick[i]),
766320d2c4d2Smrg	       TScreenOf(wnew)->selectMap[i]));
766420d2c4d2Smrg	if (TScreenOf(wnew)->selectMap[i] == NSELECTUNITS)
7665d522f475Smrg	    break;
7666d522f475Smrg    }
766720d2c4d2Smrg    TRACE(("maxClicks %d\n", TScreenOf(wnew)->maxClicks));
7668d522f475Smrg
7669d522f475Smrg    init_Tres(MOUSE_FG);
7670d522f475Smrg    init_Tres(MOUSE_BG);
7671d522f475Smrg    init_Tres(TEXT_CURSOR);
7672d522f475Smrg#if OPT_HIGHLIGHT_COLOR
7673d522f475Smrg    init_Tres(HIGHLIGHT_BG);
7674d522f475Smrg    init_Tres(HIGHLIGHT_FG);
7675d522f475Smrg    init_Bres(screen.hilite_reverse);
7676d522f475Smrg    init_Bres(screen.hilite_color);
767720d2c4d2Smrg    if (TScreenOf(wnew)->hilite_color == Maybe) {
767820d2c4d2Smrg	TScreenOf(wnew)->hilite_color = False;
7679d522f475Smrg#if OPT_COLOR_RES
7680d522f475Smrg	/*
7681d522f475Smrg	 * If the highlight text/background are both set, and if they are
7682d522f475Smrg	 * not equal to either the text/background or background/text, then
7683d522f475Smrg	 * set the highlightColorMode automatically.
7684d522f475Smrg	 */
7685d522f475Smrg	if (!DftFg(Tcolors[HIGHLIGHT_BG])
7686d522f475Smrg	    && !DftBg(Tcolors[HIGHLIGHT_FG])
7687d522f475Smrg	    && !TxtFg(Tcolors[HIGHLIGHT_BG])
7688d522f475Smrg	    && !TxtBg(Tcolors[HIGHLIGHT_FG])
7689d522f475Smrg	    && !TxtBg(Tcolors[HIGHLIGHT_BG])
7690d522f475Smrg	    && !TxtFg(Tcolors[HIGHLIGHT_FG])) {
7691d522f475Smrg	    TRACE(("...setting hilite_color automatically\n"));
769220d2c4d2Smrg	    TScreenOf(wnew)->hilite_color = True;
7693d522f475Smrg	}
7694d522f475Smrg#endif
7695d522f475Smrg    }
7696d522f475Smrg#endif
7697d522f475Smrg
7698d522f475Smrg#if OPT_TEK4014
7699d522f475Smrg    /*
7700d522f475Smrg     * The Tek4014 window has no separate resources for foreground, background
7701d522f475Smrg     * and cursor color.  Since xterm always creates the vt100 widget first, we
7702d522f475Smrg     * can set the Tektronix colors here.  That lets us use escape sequences to
7703d522f475Smrg     * set its dynamic colors and get consistent behavior whether or not the
7704d522f475Smrg     * window is displayed.
7705d522f475Smrg     */
770620d2c4d2Smrg    TScreenOf(wnew)->Tcolors[TEK_BG] = TScreenOf(wnew)->Tcolors[TEXT_BG];
770720d2c4d2Smrg    TScreenOf(wnew)->Tcolors[TEK_FG] = TScreenOf(wnew)->Tcolors[TEXT_FG];
770820d2c4d2Smrg    TScreenOf(wnew)->Tcolors[TEK_CURSOR] = TScreenOf(wnew)->Tcolors[TEXT_CURSOR];
7709d522f475Smrg#endif
7710d522f475Smrg
7711492d43a5Smrg#ifdef SCROLLBAR_RIGHT
7712492d43a5Smrg    init_Bres(misc.useRight);
7713492d43a5Smrg#endif
7714492d43a5Smrg
7715d522f475Smrg#if OPT_RENDERFONT
7716d522f475Smrg    for (i = 0; i <= fontMenu_lastBuiltin; ++i) {
77172eaa94a1Schristos	init_Dres2(misc.face_size, i);
7718d522f475Smrg    }
7719d522f475Smrg    init_Sres(misc.face_name);
7720d522f475Smrg    init_Sres(misc.face_wide_name);
772120d2c4d2Smrg    init_Sres(misc.render_font_s);
77220bd37d32Smrg    wnew->work.render_font =
772320d2c4d2Smrg	(Boolean) extendedBoolean(wnew->misc.render_font_s,
772420d2c4d2Smrg				  tblRenderFont, erLast);
77250bd37d32Smrg    if (wnew->work.render_font == erDefault) {
772620d2c4d2Smrg	if (IsEmpty(wnew->misc.face_name)) {
77270bd37d32Smrg	    free(wnew->misc.face_name);
772820d2c4d2Smrg	    wnew->misc.face_name = x_strdup(DEFFACENAME_AUTO);
772920d2c4d2Smrg	    TRACE(("will allow runtime switch to render_font using \"%s\"\n",
773020d2c4d2Smrg		   wnew->misc.face_name));
773120d2c4d2Smrg	} else {
77320bd37d32Smrg	    wnew->work.render_font = erTrue;
773320d2c4d2Smrg	    TRACE(("initially using TrueType font\n"));
773420d2c4d2Smrg	}
773520d2c4d2Smrg    }
7736d522f475Smrg    /* minor tweak to make debug traces consistent: */
77370bd37d32Smrg    if (wnew->work.render_font) {
773820d2c4d2Smrg	if (IsEmpty(wnew->misc.face_name)) {
77390bd37d32Smrg	    wnew->work.render_font = False;
7740d522f475Smrg	    TRACE(("reset render_font since there is no face_name\n"));
7741d522f475Smrg	}
7742d522f475Smrg    }
7743d522f475Smrg#endif
7744d522f475Smrg
774520d2c4d2Smrg#if OPT_WIDE_CHARS
7746e39b573cSmrg    /* setup data for next call */
7747e39b573cSmrg    request->screen.utf8_mode =
7748e39b573cSmrg	extendedBoolean(request->screen.utf8_mode_s, tblUtf8Mode, uLast);
7749e39b573cSmrg    request->screen.utf8_fonts =
7750e39b573cSmrg	extendedBoolean(request->screen.utf8_fonts_s, tblUtf8Mode, uLast);
7751e39b573cSmrg
775220d2c4d2Smrg    VTInitialize_locale(request);
77530bd37d32Smrg    init_Bres(screen.normalized_c);
775420d2c4d2Smrg    init_Bres(screen.utf8_latin1);
775520d2c4d2Smrg    init_Bres(screen.utf8_title);
775620d2c4d2Smrg
775720d2c4d2Smrg#if OPT_LUIT_PROG
775820d2c4d2Smrg    init_Bres(misc.callfilter);
775920d2c4d2Smrg    init_Bres(misc.use_encoding);
776020d2c4d2Smrg    init_Sres(misc.locale_str);
776120d2c4d2Smrg    init_Sres(misc.localefilter);
776220d2c4d2Smrg#endif
776320d2c4d2Smrg
7764d522f475Smrg    init_Ires(screen.utf8_inparse);
7765d522f475Smrg    init_Ires(screen.utf8_mode);
7766e39b573cSmrg    init_Ires(screen.utf8_fonts);
7767d522f475Smrg    init_Ires(screen.max_combining);
7768d522f475Smrg
776920d2c4d2Smrg    if (TScreenOf(wnew)->max_combining < 0) {
777020d2c4d2Smrg	TScreenOf(wnew)->max_combining = 0;
7771d522f475Smrg    }
777220d2c4d2Smrg    if (TScreenOf(wnew)->max_combining > 5) {
777320d2c4d2Smrg	TScreenOf(wnew)->max_combining = 5;
7774d522f475Smrg    }
7775d522f475Smrg
7776d522f475Smrg    init_Bres(screen.vt100_graphics);
7777d522f475Smrg    init_Bres(screen.wide_chars);
7778d522f475Smrg    init_Bres(misc.mk_width);
7779d522f475Smrg    init_Bres(misc.cjk_width);
7780d522f475Smrg
7781d522f475Smrg    init_Ires(misc.mk_samplesize);
7782d522f475Smrg    init_Ires(misc.mk_samplepass);
7783d522f475Smrg
7784d522f475Smrg    if (wnew->misc.mk_samplesize > 0xffff)
7785d522f475Smrg	wnew->misc.mk_samplesize = 0xffff;
7786d522f475Smrg    if (wnew->misc.mk_samplesize < 0)
7787d522f475Smrg	wnew->misc.mk_samplesize = 0;
7788d522f475Smrg
7789d522f475Smrg    if (wnew->misc.mk_samplepass > wnew->misc.mk_samplesize)
7790d522f475Smrg	wnew->misc.mk_samplepass = wnew->misc.mk_samplesize;
7791d522f475Smrg    if (wnew->misc.mk_samplepass < 0)
7792d522f475Smrg	wnew->misc.mk_samplepass = 0;
7793d522f475Smrg
779420d2c4d2Smrg    if (TScreenOf(request)->utf8_mode) {
7795d522f475Smrg	TRACE(("setting wide_chars on\n"));
779620d2c4d2Smrg	TScreenOf(wnew)->wide_chars = True;
7797d522f475Smrg    } else {
7798d522f475Smrg	TRACE(("setting utf8_mode to 0\n"));
779920d2c4d2Smrg	TScreenOf(wnew)->utf8_mode = uFalse;
7800d522f475Smrg    }
780120d2c4d2Smrg    TRACE(("initialized UTF-8 mode to %d\n", TScreenOf(wnew)->utf8_mode));
7802d522f475Smrg
7803d522f475Smrg#if OPT_MINI_LUIT
780420d2c4d2Smrg    if (TScreenOf(request)->latin9_mode) {
780520d2c4d2Smrg	TScreenOf(wnew)->latin9_mode = True;
7806d522f475Smrg    }
780720d2c4d2Smrg    if (TScreenOf(request)->unicode_font) {
780820d2c4d2Smrg	TScreenOf(wnew)->unicode_font = True;
7809d522f475Smrg    }
781020d2c4d2Smrg    TRACE(("initialized Latin9 mode to %d\n", TScreenOf(wnew)->latin9_mode));
781120d2c4d2Smrg    TRACE(("initialized unicode_font to %d\n", TScreenOf(wnew)->unicode_font));
7812d522f475Smrg#endif
7813d522f475Smrg
781420d2c4d2Smrg    decode_wcwidth(wnew);
7815e39b573cSmrg    xtermSaveVTFonts(wnew);
7816d522f475Smrg#endif /* OPT_WIDE_CHARS */
7817d522f475Smrg
78180bd37d32Smrg    init_Sres(screen.eight_bit_meta_s);
78190bd37d32Smrg    wnew->screen.eight_bit_meta =
78200bd37d32Smrg	extendedBoolean(request->screen.eight_bit_meta_s, tbl8BitMeta, uLast);
78210bd37d32Smrg    if (wnew->screen.eight_bit_meta == ebLocale) {
78220bd37d32Smrg#if OPT_WIDE_CHARS
78230bd37d32Smrg	if (xtermEnvUTF8()) {
78240bd37d32Smrg	    wnew->screen.eight_bit_meta = ebFalse;
78250bd37d32Smrg	    TRACE(("...eightBitMeta is false due to locale\n"));
78260bd37d32Smrg	} else
78270bd37d32Smrg#endif /* OPT_WIDE_CHARS */
78280bd37d32Smrg	{
78290bd37d32Smrg	    wnew->screen.eight_bit_meta = ebTrue;
78300bd37d32Smrg	    TRACE(("...eightBitMeta is true due to locale\n"));
78310bd37d32Smrg	}
78320bd37d32Smrg    }
78330bd37d32Smrg
7834d522f475Smrg    init_Bres(screen.always_bold_mode);
7835d522f475Smrg    init_Bres(screen.bold_mode);
7836d522f475Smrg    init_Bres(screen.underline);
7837d522f475Smrg
7838d522f475Smrg    wnew->cur_foreground = 0;
7839d522f475Smrg    wnew->cur_background = 0;
7840d522f475Smrg
7841d522f475Smrg    wnew->keyboard.flags = MODE_SRM;
784220d2c4d2Smrg    if (TScreenOf(wnew)->backarrow_key)
7843d522f475Smrg	wnew->keyboard.flags |= MODE_DECBKM;
7844d522f475Smrg    TRACE(("initialized DECBKM %s\n",
7845d522f475Smrg	   BtoS(wnew->keyboard.flags & MODE_DECBKM)));
7846d522f475Smrg
7847d522f475Smrg    /* look for focus related events on the shell, because we need
7848d522f475Smrg     * to care about the shell's border being part of our focus.
7849d522f475Smrg     */
785020d2c4d2Smrg    TRACE(("adding event handlers for my_parent %p\n", (void *) my_parent));
7851d522f475Smrg    XtAddEventHandler(my_parent, EnterWindowMask, False,
7852d522f475Smrg		      HandleEnterWindow, (Opaque) NULL);
7853d522f475Smrg    XtAddEventHandler(my_parent, LeaveWindowMask, False,
7854d522f475Smrg		      HandleLeaveWindow, (Opaque) NULL);
7855d522f475Smrg    XtAddEventHandler(my_parent, FocusChangeMask, False,
7856d522f475Smrg		      HandleFocusChange, (Opaque) NULL);
7857d522f475Smrg    XtAddEventHandler((Widget) wnew, 0L, True,
7858d522f475Smrg		      VTNonMaskableEvent, (Opaque) NULL);
7859d522f475Smrg    XtAddEventHandler((Widget) wnew, PropertyChangeMask, False,
7860d522f475Smrg		      HandleBellPropertyChange, (Opaque) NULL);
7861d522f475Smrg
7862d522f475Smrg#if HANDLE_STRUCT_NOTIFY
7863d522f475Smrg#if OPT_TOOLBAR
7864d522f475Smrg    wnew->VT100_TB_INFO(menu_bar) = request->VT100_TB_INFO(menu_bar);
7865d522f475Smrg    init_Ires(VT100_TB_INFO(menu_height));
7866d522f475Smrg#else
7867d522f475Smrg    /* Flag icon name with "***"  on window output when iconified.
7868d522f475Smrg     * Put in a handler that will tell us when we get Map/Unmap events.
7869d522f475Smrg     */
7870d522f475Smrg    if (resource.zIconBeep)
7871d522f475Smrg#endif
7872d522f475Smrg	XtAddEventHandler(my_parent, StructureNotifyMask, False,
7873d522f475Smrg			  HandleStructNotify, (Opaque) 0);
7874d522f475Smrg#endif /* HANDLE_STRUCT_NOTIFY */
7875d522f475Smrg
787620d2c4d2Smrg    TScreenOf(wnew)->bellInProgress = False;
7877d522f475Smrg
787820d2c4d2Smrg    set_character_class(TScreenOf(wnew)->charClass);
7879d522f475Smrg
7880d522f475Smrg    /* create it, but don't realize it */
7881956cc18dSsnj    ScrollBarOn(wnew, True);
7882d522f475Smrg
7883d522f475Smrg    /* make sure that the resize gravity acceptable */
7884956cc18dSsnj    if (!GravityIsNorthWest(wnew) &&
7885956cc18dSsnj	!GravityIsSouthWest(wnew)) {
7886d522f475Smrg	char value[80];
788720d2c4d2Smrg	String temp[2];
7888d522f475Smrg	Cardinal nparams = 1;
7889d522f475Smrg
789020d2c4d2Smrg	sprintf(value, "%d", wnew->misc.resizeGravity);
789120d2c4d2Smrg	temp[0] = value;
7892d522f475Smrg	temp[1] = 0;
7893d522f475Smrg	XtAppWarningMsg(app_con, "rangeError", "resizeGravity", "XTermError",
7894d522f475Smrg			"unsupported resizeGravity resource value (%s)",
7895d522f475Smrg			temp, &nparams);
7896d522f475Smrg	wnew->misc.resizeGravity = SouthWestGravity;
7897d522f475Smrg    }
7898d522f475Smrg#ifndef NO_ACTIVE_ICON
789920d2c4d2Smrg    TScreenOf(wnew)->whichVwin = &TScreenOf(wnew)->fullVwin;
7900d522f475Smrg#endif /* NO_ACTIVE_ICON */
7901d522f475Smrg
790220d2c4d2Smrg    if (TScreenOf(wnew)->savelines < 0)
790320d2c4d2Smrg	TScreenOf(wnew)->savelines = 0;
7904d522f475Smrg
7905d522f475Smrg    init_Bres(screen.awaitInput);
7906d522f475Smrg
7907d522f475Smrg    wnew->flags = 0;
790820d2c4d2Smrg    if (!TScreenOf(wnew)->jumpscroll)
7909d522f475Smrg	wnew->flags |= SMOOTHSCROLL;
7910d522f475Smrg    if (wnew->misc.reverseWrap)
7911d522f475Smrg	wnew->flags |= REVERSEWRAP;
7912d522f475Smrg    if (wnew->misc.autoWrap)
7913d522f475Smrg	wnew->flags |= WRAPAROUND;
7914d522f475Smrg    if (wnew->misc.re_verse != wnew->misc.re_verse0)
7915d522f475Smrg	wnew->flags |= REVERSE_VIDEO;
791620d2c4d2Smrg    if (TScreenOf(wnew)->c132)
7917d522f475Smrg	wnew->flags |= IN132COLUMNS;
7918d522f475Smrg
7919d522f475Smrg    wnew->initflags = wnew->flags;
7920d522f475Smrg
7921d522f475Smrg#if OPT_MOD_FKEYS
79220bd37d32Smrg    init_Ires(keyboard.modify_1st.allow_keys);
7923d522f475Smrg    init_Ires(keyboard.modify_1st.cursor_keys);
7924d522f475Smrg    init_Ires(keyboard.modify_1st.function_keys);
7925d522f475Smrg    init_Ires(keyboard.modify_1st.keypad_keys);
7926d522f475Smrg    init_Ires(keyboard.modify_1st.other_keys);
7927d522f475Smrg    init_Ires(keyboard.modify_1st.string_keys);
7928d522f475Smrg    init_Ires(keyboard.format_keys);
7929d522f475Smrg    wnew->keyboard.modify_now = wnew->keyboard.modify_1st;
7930d522f475Smrg#endif
7931d522f475Smrg
7932d522f475Smrg    init_Ires(misc.appcursorDefault);
7933d522f475Smrg    if (wnew->misc.appcursorDefault)
7934d522f475Smrg	wnew->keyboard.flags |= MODE_DECCKM;
7935d522f475Smrg
7936d522f475Smrg    init_Ires(misc.appkeypadDefault);
7937d522f475Smrg    if (wnew->misc.appkeypadDefault)
7938d522f475Smrg	wnew->keyboard.flags |= MODE_DECKPAM;
7939d522f475Smrg
7940956cc18dSsnj    initLineData(wnew);
7941d522f475Smrg    return;
7942d522f475Smrg}
7943d522f475Smrg
7944d522f475Smrgvoid
7945d522f475SmrgreleaseCursorGCs(XtermWidget xw)
7946d522f475Smrg{
794720d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
7948d522f475Smrg    VTwin *win = WhichVWin(screen);
7949d522f475Smrg    int n;
7950d522f475Smrg
7951d522f475Smrg    for_each_curs_gc(n) {
7952d522f475Smrg	freeCgs(xw, win, (CgsEnum) n);
7953d522f475Smrg    }
7954d522f475Smrg}
7955d522f475Smrg
7956d522f475Smrgvoid
7957d522f475SmrgreleaseWindowGCs(XtermWidget xw, VTwin * win)
7958d522f475Smrg{
7959d522f475Smrg    int n;
7960d522f475Smrg
7961d522f475Smrg    for_each_text_gc(n) {
7962d522f475Smrg	freeCgs(xw, win, (CgsEnum) n);
7963d522f475Smrg    }
7964d522f475Smrg}
7965d522f475Smrg
7966d522f475Smrg#define TRACE_FREE_LEAK(name) \
7967d522f475Smrg	if (name) { \
79680bd37d32Smrg	    TRACE(("freed " #name ": %p\n", (const void *) name)); \
796920d2c4d2Smrg	    free((void *) name); \
7970d522f475Smrg	    name = 0; \
7971d522f475Smrg	}
7972d522f475Smrg
7973d522f475Smrg#define FREE_LEAK(name) \
7974d522f475Smrg	if (name) { \
797520d2c4d2Smrg	    free((void *) name); \
7976d522f475Smrg	    name = 0; \
7977d522f475Smrg	}
7978d522f475Smrg
79790bd37d32Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
7980956cc18dSsnjstatic void
79810bd37d32SmrgcleanupInputMethod(XtermWidget xw)
7982956cc18dSsnj{
79830bd37d32Smrg    TInput *input = lookupTInput(xw, (Widget) xw);
79840bd37d32Smrg
79850bd37d32Smrg    if (input && input->xim) {
79860bd37d32Smrg	XCloseIM(input->xim);
79870bd37d32Smrg	input->xim = 0;
7988956cc18dSsnj	TRACE(("freed screen->xim\n"));
7989956cc18dSsnj    }
7990956cc18dSsnj}
7991956cc18dSsnj#endif
7992956cc18dSsnj
7993d522f475Smrgstatic void
7994d522f475SmrgVTDestroy(Widget w GCC_UNUSED)
7995d522f475Smrg{
7996d522f475Smrg#ifdef NO_LEAKS
7997d522f475Smrg    XtermWidget xw = (XtermWidget) w;
799820d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
7999d522f475Smrg    Cardinal n;
8000d522f475Smrg
8001d522f475Smrg    StopBlinking(screen);
8002d522f475Smrg
80032eaa94a1Schristos    if (screen->scrollWidget) {
80042eaa94a1Schristos	XtUninstallTranslations(screen->scrollWidget);
8005d522f475Smrg	XtDestroyWidget(screen->scrollWidget);
80062eaa94a1Schristos    }
8007956cc18dSsnj#if OPT_FIFO_LINES
80080bd37d32Smrg    while (screen->saved_fifo > 0) {
80090bd37d32Smrg	deleteScrollback(screen);
8010956cc18dSsnj    }
8011956cc18dSsnj#endif
801220d2c4d2Smrg    while (screen->save_title != 0) {
801320d2c4d2Smrg	SaveTitle *last = screen->save_title;
801420d2c4d2Smrg	screen->save_title = last->next;
801520d2c4d2Smrg	free(last->iconName);
801620d2c4d2Smrg	free(last->windowName);
801720d2c4d2Smrg	free(last);
801820d2c4d2Smrg    }
80190bd37d32Smrg#if OPT_ISO_COLORS
80200bd37d32Smrg    TRACE_FREE_LEAK(screen->cmap_data);
80210bd37d32Smrg    for (n = 0; n < MAXCOLORS; n++) {
80220bd37d32Smrg	TRACE_FREE_LEAK(screen->Acolors[n].resource);
80230bd37d32Smrg    }
80240bd37d32Smrg#endif
80250bd37d32Smrg#if OPT_COLOR_RES
80260bd37d32Smrg    for (n = 0; n < NCOLORS; n++) {
80270bd37d32Smrg	switch (n) {
80280bd37d32Smrg#if OPT_TEK4014
80290bd37d32Smrg	case TEK_BG:
80300bd37d32Smrg	case TEK_FG:
80310bd37d32Smrg	case TEK_CURSOR:
80320bd37d32Smrg	    break;
80330bd37d32Smrg#endif
80340bd37d32Smrg	default:
80350bd37d32Smrg	    TRACE_FREE_LEAK(screen->Tcolors[n].resource);
80360bd37d32Smrg	    break;
80370bd37d32Smrg	}
80380bd37d32Smrg    }
80390bd37d32Smrg#endif
8040d522f475Smrg    TRACE_FREE_LEAK(screen->save_ptr);
8041956cc18dSsnj    TRACE_FREE_LEAK(screen->saveBuf_data);
8042956cc18dSsnj    TRACE_FREE_LEAK(screen->saveBuf_index);
8043956cc18dSsnj    for (n = 0; n < 2; ++n) {
8044956cc18dSsnj	TRACE_FREE_LEAK(screen->editBuf_data[n]);
8045956cc18dSsnj	TRACE_FREE_LEAK(screen->editBuf_index[n]);
8046956cc18dSsnj    }
8047d522f475Smrg    TRACE_FREE_LEAK(screen->keyboard_dialect);
8048d522f475Smrg    TRACE_FREE_LEAK(screen->term_id);
8049d522f475Smrg#if OPT_WIDE_CHARS
8050d522f475Smrg#if OPT_LUIT_PROG
8051d522f475Smrg    TRACE_FREE_LEAK(xw->misc.locale_str);
8052d522f475Smrg    TRACE_FREE_LEAK(xw->misc.localefilter);
8053d522f475Smrg#endif
8054d522f475Smrg#endif
80550bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.T_geometry);
80560bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.geo_metry);
80570bd37d32Smrg    TRACE_FREE_LEAK(xw->screen.term_id);
8058d522f475Smrg#if OPT_INPUT_METHOD
80590bd37d32Smrg    cleanupInputMethod(xw);
80600bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.f_x);
80610bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.input_method);
80620bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.preedit_type);
8063d522f475Smrg#endif
8064d522f475Smrg    releaseCursorGCs(xw);
8065d522f475Smrg    releaseWindowGCs(xw, &(screen->fullVwin));
8066d522f475Smrg#ifndef NO_ACTIVE_ICON
8067d522f475Smrg    releaseWindowGCs(xw, &(screen->iconVwin));
8068d522f475Smrg#endif
80692eaa94a1Schristos    XtUninstallTranslations((Widget) xw);
80702eaa94a1Schristos#if OPT_TOOLBAR
80712eaa94a1Schristos    XtUninstallTranslations((Widget) XtParent(xw));
80722eaa94a1Schristos#endif
80732eaa94a1Schristos    XtUninstallTranslations((Widget) SHELL_OF(xw));
8074d522f475Smrg
8075d522f475Smrg    if (screen->hidden_cursor)
8076d522f475Smrg	XFreeCursor(screen->display, screen->hidden_cursor);
8077d522f475Smrg
8078d522f475Smrg    xtermCloseFonts(xw, screen->fnts);
8079d522f475Smrg    noleaks_cachedCgs(xw);
8080d522f475Smrg
80810bd37d32Smrg    TRACE_FREE_LEAK(screen->selection_targets_8bit);
80820bd37d32Smrg#if OPT_SELECT_REGEX
80830bd37d32Smrg    for (n = 0; n < NSELECTUNITS; ++n) {
80840bd37d32Smrg	if (screen->selectMap[n] == Select_REGEX) {
80850bd37d32Smrg	    TRACE_FREE_LEAK(screen->selectExpr[n]);
80860bd37d32Smrg	}
80870bd37d32Smrg    }
80880bd37d32Smrg#endif
80890bd37d32Smrg
8090d522f475Smrg#if OPT_RENDERFONT
8091d522f475Smrg    for (n = 0; n < NMENUFONTS; ++n) {
8092d522f475Smrg	xtermCloseXft(screen, &(screen->renderFontNorm[n]));
8093d522f475Smrg	xtermCloseXft(screen, &(screen->renderFontBold[n]));
8094d522f475Smrg	xtermCloseXft(screen, &(screen->renderFontItal[n]));
8095956cc18dSsnj#if OPT_RENDERWIDE
8096d522f475Smrg	xtermCloseXft(screen, &(screen->renderWideNorm[n]));
8097d522f475Smrg	xtermCloseXft(screen, &(screen->renderWideBold[n]));
8098d522f475Smrg	xtermCloseXft(screen, &(screen->renderWideItal[n]));
8099956cc18dSsnj#endif
8100d522f475Smrg    }
8101d522f475Smrg#endif
8102d522f475Smrg
810320d2c4d2Smrg    /* free things allocated via init_Sres or Init_Sres2 */
81040bd37d32Smrg#ifndef NO_ACTIVE_ICON
81050bd37d32Smrg    TRACE_FREE_LEAK(screen->icon_fontname);
81060bd37d32Smrg#endif
810720d2c4d2Smrg#ifdef ALLOWLOGGING
810820d2c4d2Smrg    TRACE_FREE_LEAK(screen->logfile);
8109d522f475Smrg#endif
81100bd37d32Smrg    TRACE_FREE_LEAK(screen->eight_bit_meta_s);
811120d2c4d2Smrg    TRACE_FREE_LEAK(screen->term_id);
811220d2c4d2Smrg    TRACE_FREE_LEAK(screen->charClass);
811320d2c4d2Smrg    TRACE_FREE_LEAK(screen->answer_back);
81140bd37d32Smrg    TRACE_FREE_LEAK(screen->printer_state.printer_command);
811520d2c4d2Smrg    TRACE_FREE_LEAK(screen->keyboard_dialect);
811620d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedColorOps);
811720d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedFontOps);
811820d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedTcapOps);
811920d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedWinOps);
812020d2c4d2Smrg    TRACE_FREE_LEAK(screen->default_string);
812120d2c4d2Smrg    TRACE_FREE_LEAK(screen->eightbit_select_types);
812220d2c4d2Smrg#if OPT_WIDE_CHARS
812320d2c4d2Smrg    TRACE_FREE_LEAK(screen->utf8_select_types);
812420d2c4d2Smrg#endif
812520d2c4d2Smrg#if 0
812620d2c4d2Smrg    for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; n++) {
812720d2c4d2Smrg	TRACE_FREE_LEAK(screen->MenuFontName(n));
8128d522f475Smrg    }
8129d522f475Smrg#endif
813020d2c4d2Smrg    TRACE_FREE_LEAK(screen->initial_font);
813120d2c4d2Smrg#if OPT_LUIT_PROG
813220d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.locale_str);
813320d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.localefilter);
813420d2c4d2Smrg#endif
813520d2c4d2Smrg#if OPT_RENDERFONT
813620d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.face_name);
813720d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.face_wide_name);
81380bd37d32Smrg    TRACE_FREE_LEAK(xw->misc.render_font_s);
813920d2c4d2Smrg#endif
814020d2c4d2Smrg
8141d522f475Smrg#if OPT_SELECT_REGEX
8142d522f475Smrg    for (n = 0; n < NSELECTUNITS; ++n) {
8143d522f475Smrg	FREE_LEAK(screen->selectExpr[n]);
8144d522f475Smrg    }
8145d522f475Smrg#endif
8146d522f475Smrg
8147d522f475Smrg    if (screen->selection_atoms)
8148d522f475Smrg	XtFree((char *) (screen->selection_atoms));
8149d522f475Smrg
8150d522f475Smrg    XtFree((char *) (screen->selection_data));
8151d522f475Smrg
81520bd37d32Smrg    TRACE_FREE_LEAK(xtermClassRec.core_class.tm_table);
8153d522f475Smrg    TRACE_FREE_LEAK(xw->keyboard.extra_translations);
8154d522f475Smrg    TRACE_FREE_LEAK(xw->keyboard.shell_translations);
8155d522f475Smrg    TRACE_FREE_LEAK(xw->keyboard.xterm_translations);
8156956cc18dSsnj
8157956cc18dSsnj#if OPT_WIDE_CHARS
8158956cc18dSsnj    FreeTypedBuffer(XChar2b);
8159956cc18dSsnj    FreeTypedBuffer(char);
8160956cc18dSsnj#endif
8161956cc18dSsnj#if OPT_RENDERFONT
8162956cc18dSsnj#if OPT_RENDERWIDE
8163956cc18dSsnj    FreeTypedBuffer(XftCharSpec);
8164956cc18dSsnj#else
8165956cc18dSsnj    FreeTypedBuffer(XftChar8);
8166956cc18dSsnj#endif
8167956cc18dSsnj#endif
8168956cc18dSsnj
8169956cc18dSsnj    TRACE_FREE_LEAK(myState.print_area);
8170956cc18dSsnj    TRACE_FREE_LEAK(myState.string_area);
8171956cc18dSsnj    memset(&myState, 0, sizeof(myState));
8172956cc18dSsnj
8173d522f475Smrg#endif /* defined(NO_LEAKS) */
8174d522f475Smrg}
8175d522f475Smrg
81760bd37d32Smrgstatic void *
81770bd37d32SmrggetProperty(Display * dpy,
81780bd37d32Smrg	    Window w,
81790bd37d32Smrg	    Atom req_type,
81800bd37d32Smrg	    const char *prop_name)
81810bd37d32Smrg{
81820bd37d32Smrg    Atom property;
81830bd37d32Smrg    Atom actual_return_type;
81840bd37d32Smrg    int actual_format_return = 0;
81850bd37d32Smrg    unsigned long nitems_return = 0;
81860bd37d32Smrg    unsigned long bytes_after_return = 0;
81870bd37d32Smrg    unsigned char *prop_return = 0;
81880bd37d32Smrg    long long_length = 1024;
81890bd37d32Smrg    size_t limit;
81900bd37d32Smrg    char *result = 0;
81910bd37d32Smrg
81920bd37d32Smrg    TRACE(("getProperty %s(%s)\n", prop_name,
81930bd37d32Smrg	   req_type ? XGetAtomName(dpy, req_type) : "?"));
81940bd37d32Smrg    property = XInternAtom(dpy, prop_name, False);
81950bd37d32Smrg
81960bd37d32Smrg    if (!xtermGetWinProp(dpy,
81970bd37d32Smrg			 w,
81980bd37d32Smrg			 property,
81990bd37d32Smrg			 0L,
82000bd37d32Smrg			 long_length,
82010bd37d32Smrg			 req_type,
82020bd37d32Smrg			 &actual_return_type,
82030bd37d32Smrg			 &actual_format_return,
82040bd37d32Smrg			 &nitems_return,
82050bd37d32Smrg			 &bytes_after_return,
82060bd37d32Smrg			 &prop_return)) {
82070bd37d32Smrg	TRACE((".. Cannot get %s property.\n", prop_name));
82080bd37d32Smrg    } else if (prop_return != 0) {
82090bd37d32Smrg
82100bd37d32Smrg	if (nitems_return != 0 &&
82110bd37d32Smrg	    actual_format_return != 0 &&
82120bd37d32Smrg	    actual_return_type == req_type) {
82130bd37d32Smrg	    /*
82140bd37d32Smrg	     * Null-terminate the result to make string handling easier.
82150bd37d32Smrg	     * The format==8 corresponds to strings, and the number of items
82160bd37d32Smrg	     * is the number of characters.
82170bd37d32Smrg	     */
82180bd37d32Smrg	    if (actual_format_return == 8) {
82190bd37d32Smrg		limit = nitems_return;
82200bd37d32Smrg	    } else {
82210bd37d32Smrg		/* manpage is misleading - X really uses 'long', not 32-bits */
82220bd37d32Smrg		limit = sizeof(long) * nitems_return;
82230bd37d32Smrg	    }
82240bd37d32Smrg	    if ((result = malloc(limit + 1)) != 0) {
82250bd37d32Smrg		memcpy(result, prop_return, limit);
82260bd37d32Smrg		result[limit] = '\0';
82270bd37d32Smrg	    }
82280bd37d32Smrg	    TRACE(("... result %s\n", result ? ("ok") : "null"));
82290bd37d32Smrg	}
82300bd37d32Smrg	XFree(prop_return);
82310bd37d32Smrg    } else {
82320bd37d32Smrg	TRACE((".. no property returned\n"));
82330bd37d32Smrg    }
82340bd37d32Smrg    return (void *) result;
82350bd37d32Smrg}
82360bd37d32Smrg
82370bd37d32Smrg/*
82380bd37d32Smrg * Active icons are supported by fvwm.  This feature is not supported by
82390bd37d32Smrg * metacity (gnome) or kwin (kde).  Both metacity and kwin support (in
82400bd37d32Smrg * incompatible ways, e.g., one uses the icon theme as a fallback for window
82410bd37d32Smrg * decorations but the other does not, etc, ...) an icon as part of the window
82420bd37d32Smrg * decoration (usually on the upper-left of the window).
82430bd37d32Smrg *
82440bd37d32Smrg * In either case, xterm's icon will only be shown in the window decorations if
82450bd37d32Smrg * xterm does not use the active icon feature.
82460bd37d32Smrg *
82470bd37d32Smrg * This function (tries to) determine the window manager's name, so that we can
82480bd37d32Smrg * provide a useful automatic default for active icons.  It is based on reading
82490bd37d32Smrg * wmctrl, which covers most of EWMH and ICCM.
82500bd37d32Smrg */
82510bd37d32Smrgstatic char *
82520bd37d32SmrggetWindowManagerName(XtermWidget xw)
82530bd37d32Smrg{
82540bd37d32Smrg    TScreen *screen = TScreenOf(xw);
82550bd37d32Smrg    Display *dpy = screen->display;
82560bd37d32Smrg    Window *sup_window = NULL;
82570bd37d32Smrg    char *result = 0;
82580bd37d32Smrg
82590bd37d32Smrg    TRACE(("getWindowManagerName\n"));
82600bd37d32Smrg#define getWinProp(type, name) \
82610bd37d32Smrg    (Window *)getProperty(dpy, DefaultRootWindow(dpy), type, name)
82620bd37d32Smrg    if ((sup_window = getWinProp(XA_WINDOW, "_NET_SUPPORTING_WM_CHECK")) == 0) {
82630bd37d32Smrg	sup_window = getWinProp(XA_CARDINAL, "_WIN_SUPPORTING_WM_CHECK");
82640bd37d32Smrg    }
82650bd37d32Smrg
82660bd37d32Smrg    /*
82670bd37d32Smrg     * If we found the supporting window, get the property containing the
82680bd37d32Smrg     * window manager's name.  EWMH defines _NET_WM_NAME, while ICCM defines
82690bd37d32Smrg     * WM_CLASS.  There is no standard for the names stored there;
82700bd37d32Smrg     * conventionally it is mixed case.  In practice, the former is more often
82710bd37d32Smrg     * set; the latter is not given (or is a lowercased version of the former).
82720bd37d32Smrg     */
82730bd37d32Smrg    if (sup_window != 0) {
82740bd37d32Smrg#define getStringProp(type,name) \
82750bd37d32Smrg	(char *)getProperty(dpy, *sup_window, type, name)
82760bd37d32Smrg	if ((result = getStringProp(XA_UTF8_STRING(dpy), "_NET_WM_NAME")) == 0
82770bd37d32Smrg	    && (result = getStringProp(XA_STRING, "_NET_WM_NAME")) == 0
82780bd37d32Smrg	    && (result = getStringProp(XA_STRING, "WM_CLASS")) == 0) {
82790bd37d32Smrg	    TRACE(("... window manager does not tell its name\n"));
82800bd37d32Smrg	}
82810bd37d32Smrg	free(sup_window);
82820bd37d32Smrg    } else {
82830bd37d32Smrg	TRACE(("... Cannot get window manager info properties\n"));
82840bd37d32Smrg    }
82850bd37d32Smrg    if (result == 0)
82860bd37d32Smrg	result = x_strdup("unknown");
82870bd37d32Smrg    TRACE(("... window manager name is %s\n", result));
82880bd37d32Smrg    return result;
82890bd37d32Smrg}
82900bd37d32Smrg
8291d522f475Smrg/*ARGSUSED*/
8292d522f475Smrgstatic void
8293d522f475SmrgVTRealize(Widget w,
8294d522f475Smrg	  XtValueMask * valuemask,
8295d522f475Smrg	  XSetWindowAttributes * values)
8296d522f475Smrg{
8297d522f475Smrg    XtermWidget xw = (XtermWidget) w;
829820d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
8299d522f475Smrg
8300d522f475Smrg    const VTFontNames *myfont;
8301d522f475Smrg    unsigned width, height;
8302d522f475Smrg    int xpos, ypos, pr;
8303d522f475Smrg    Atom pid_atom;
8304d522f475Smrg    int i;
8305d522f475Smrg
8306d522f475Smrg    TRACE(("VTRealize\n"));
8307d522f475Smrg
83080bd37d32Smrg#if OPT_TOOLBAR
83090bd37d32Smrg    /*
83100bd37d32Smrg     * Layout for the toolbar confuses the Shell widget.  Remind it that we
83110bd37d32Smrg     * would like to be iconified if the corresponding resource was set.
83120bd37d32Smrg     */
83130bd37d32Smrg    if (XtIsRealized(toplevel)) {
83140bd37d32Smrg	Boolean iconic = 0;
83150bd37d32Smrg
83160bd37d32Smrg	XtVaGetValues(toplevel,
83170bd37d32Smrg		      XtNiconic, &iconic,
83180bd37d32Smrg		      (XtPointer) 0);
83190bd37d32Smrg
83200bd37d32Smrg	if (iconic) {
83210bd37d32Smrg	    XIconifyWindow(XtDisplay(toplevel),
83220bd37d32Smrg			   XtWindow(toplevel),
83230bd37d32Smrg			   DefaultScreen(XtDisplay(toplevel)));
83240bd37d32Smrg	}
83250bd37d32Smrg    }
83260bd37d32Smrg#endif
83270bd37d32Smrg
8328d522f475Smrg    TabReset(xw->tabs);
8329d522f475Smrg
8330d522f475Smrg    if (screen->menu_font_number == fontMenu_default) {
8331d522f475Smrg	myfont = &(xw->misc.default_font);
8332d522f475Smrg    } else {
8333d522f475Smrg	myfont = xtermFontName(screen->MenuFontName(screen->menu_font_number));
8334d522f475Smrg    }
8335d522f475Smrg    memset(screen->fnts, 0, sizeof(screen->fnts));
8336d522f475Smrg
8337d522f475Smrg    if (!xtermLoadFont(xw,
8338d522f475Smrg		       myfont,
8339d522f475Smrg		       False,
8340d522f475Smrg		       screen->menu_font_number)) {
8341d522f475Smrg	if (XmuCompareISOLatin1(myfont->f_n, DEFFONT) != 0) {
834220d2c4d2Smrg	    char *use_font = x_strdup(DEFFONT);
83430bd37d32Smrg	    xtermWarning("unable to open font \"%s\", trying \"%s\"....\n",
83440bd37d32Smrg			 myfont->f_n, use_font);
8345d522f475Smrg	    (void) xtermLoadFont(xw,
834620d2c4d2Smrg				 xtermFontName(use_font),
8347d522f475Smrg				 False,
8348d522f475Smrg				 screen->menu_font_number);
834920d2c4d2Smrg	    screen->MenuFontName(screen->menu_font_number) = use_font;
8350d522f475Smrg	}
8351d522f475Smrg    }
8352d522f475Smrg
8353d522f475Smrg    /* really screwed if we couldn't open default font */
8354d522f475Smrg    if (!screen->fnts[fNorm].fs) {
83550bd37d32Smrg	xtermWarning("unable to locate a suitable font\n");
8356d522f475Smrg	Exit(1);
8357d522f475Smrg    }
8358d522f475Smrg#if OPT_WIDE_CHARS
8359e39b573cSmrg    if (screen->utf8_mode) {
8360d522f475Smrg	TRACE(("check if this is a wide font, if not try again\n"));
8361e39b573cSmrg	if (xtermLoadWideFonts(xw, False)) {
8362d522f475Smrg	    SetVTFont(xw, screen->menu_font_number, True, NULL);
8363e39b573cSmrg	    /* we will not be able to switch to ISO-8859-1 */
8364e39b573cSmrg	    if (!screen->mergedVTFonts) {
8365e39b573cSmrg		screen->utf8_fonts = uAlways;
8366e39b573cSmrg		update_font_utf8_fonts();
8367e39b573cSmrg	    }
8368e39b573cSmrg	}
8369d522f475Smrg    }
8370d522f475Smrg#endif
8371d522f475Smrg
8372d522f475Smrg    /* making cursor */
8373d522f475Smrg    if (!screen->pointer_cursor) {
8374d522f475Smrg	screen->pointer_cursor =
8375d522f475Smrg	    make_colored_cursor(XC_xterm,
8376d522f475Smrg				T_COLOR(screen, MOUSE_FG),
8377d522f475Smrg				T_COLOR(screen, MOUSE_BG));
8378d522f475Smrg    } else {
8379d522f475Smrg	recolor_cursor(screen,
8380d522f475Smrg		       screen->pointer_cursor,
8381d522f475Smrg		       T_COLOR(screen, MOUSE_FG),
8382d522f475Smrg		       T_COLOR(screen, MOUSE_BG));
8383d522f475Smrg    }
8384d522f475Smrg
8385d522f475Smrg    /* set defaults */
8386d522f475Smrg    xpos = 1;
8387d522f475Smrg    ypos = 1;
8388d522f475Smrg    width = 80;
8389d522f475Smrg    height = 24;
8390d522f475Smrg
8391d522f475Smrg    TRACE(("parsing geo_metry %s\n", NonNull(xw->misc.geo_metry)));
8392d522f475Smrg    pr = XParseGeometry(xw->misc.geo_metry, &xpos, &ypos,
8393d522f475Smrg			&width, &height);
8394d522f475Smrg    TRACE(("... position %d,%d size %dx%d\n", ypos, xpos, height, width));
8395d522f475Smrg
8396d522f475Smrg    set_max_col(screen, (int) (width - 1));	/* units in character cells */
8397d522f475Smrg    set_max_row(screen, (int) (height - 1));	/* units in character cells */
8398d522f475Smrg    xtermUpdateFontInfo(xw, False);
8399d522f475Smrg
8400d522f475Smrg    width = screen->fullVwin.fullwidth;
8401d522f475Smrg    height = screen->fullVwin.fullheight;
8402d522f475Smrg
8403d522f475Smrg    TRACE(("... border widget %d parent %d shell %d\n",
8404d522f475Smrg	   BorderWidth(xw),
8405d522f475Smrg	   BorderWidth(XtParent(xw)),
8406d522f475Smrg	   BorderWidth(SHELL_OF(xw))));
8407d522f475Smrg
8408d522f475Smrg    if ((pr & XValue) && (XNegative & pr)) {
84092eaa94a1Schristos	xpos += (DisplayWidth(screen->display, DefaultScreen(screen->display))
84102eaa94a1Schristos		 - (int) width
84112eaa94a1Schristos		 - (BorderWidth(XtParent(xw)) * 2));
8412d522f475Smrg    }
8413d522f475Smrg    if ((pr & YValue) && (YNegative & pr)) {
84142eaa94a1Schristos	ypos += (DisplayHeight(screen->display, DefaultScreen(screen->display))
84152eaa94a1Schristos		 - (int) height
84162eaa94a1Schristos		 - (BorderWidth(XtParent(xw)) * 2));
8417d522f475Smrg    }
8418d522f475Smrg
8419d522f475Smrg    /* set up size hints for window manager; min 1 char by 1 char */
8420d522f475Smrg    getXtermSizeHints(xw);
8421d522f475Smrg    xtermSizeHints(xw, (xw->misc.scrollbar
8422d522f475Smrg			? (screen->scrollWidget->core.width
8423d522f475Smrg			   + BorderWidth(screen->scrollWidget))
8424d522f475Smrg			: 0));
8425d522f475Smrg
8426d522f475Smrg    xw->hints.x = xpos;
8427d522f475Smrg    xw->hints.y = ypos;
8428a1f3da82Smrg#if OPT_MAXIMIZE
8429a1f3da82Smrg    /* assure single-increment resize for fullscreen */
84300bd37d32Smrg    if (term->work.ewmh[0].mode) {
8431a1f3da82Smrg	xw->hints.width_inc = 1;
8432a1f3da82Smrg	xw->hints.height_inc = 1;
8433a1f3da82Smrg    }
8434a1f3da82Smrg#endif
8435d522f475Smrg    if ((XValue & pr) || (YValue & pr)) {
8436d522f475Smrg	xw->hints.flags |= USSize | USPosition;
8437d522f475Smrg	xw->hints.flags |= PWinGravity;
8438d522f475Smrg	switch (pr & (XNegative | YNegative)) {
8439d522f475Smrg	case 0:
8440d522f475Smrg	    xw->hints.win_gravity = NorthWestGravity;
8441d522f475Smrg	    break;
8442d522f475Smrg	case XNegative:
8443d522f475Smrg	    xw->hints.win_gravity = NorthEastGravity;
8444d522f475Smrg	    break;
8445d522f475Smrg	case YNegative:
8446d522f475Smrg	    xw->hints.win_gravity = SouthWestGravity;
8447d522f475Smrg	    break;
8448d522f475Smrg	default:
8449d522f475Smrg	    xw->hints.win_gravity = SouthEastGravity;
8450d522f475Smrg	    break;
8451d522f475Smrg	}
8452d522f475Smrg    } else {
8453d522f475Smrg	/* set a default size, but do *not* set position */
8454d522f475Smrg	xw->hints.flags |= PSize;
8455d522f475Smrg    }
8456d522f475Smrg    xw->hints.height = xw->hints.base_height
8457d522f475Smrg	+ xw->hints.height_inc * MaxRows(screen);
8458d522f475Smrg    xw->hints.width = xw->hints.base_width
8459d522f475Smrg	+ xw->hints.width_inc * MaxCols(screen);
8460d522f475Smrg
8461d522f475Smrg    if ((WidthValue & pr) || (HeightValue & pr))
8462d522f475Smrg	xw->hints.flags |= USSize;
8463d522f475Smrg    else
8464d522f475Smrg	xw->hints.flags |= PSize;
8465d522f475Smrg
8466d522f475Smrg    /*
8467d522f475Smrg     * Note that the size-hints are for the shell, while the resize-request
8468d522f475Smrg     * is for the vt100 widget.  They are not the same size.
8469d522f475Smrg     */
84702eaa94a1Schristos    (void) REQ_RESIZE((Widget) xw,
84712eaa94a1Schristos		      (Dimension) width, (Dimension) height,
84722eaa94a1Schristos		      &xw->core.width, &xw->core.height);
8473d522f475Smrg
8474d522f475Smrg    /* XXX This is bogus.  We are parsing geometries too late.  This
8475d522f475Smrg     * is information that the shell widget ought to have before we get
8476d522f475Smrg     * realized, so that it can do the right thing.
8477d522f475Smrg     */
8478d522f475Smrg    if (xw->hints.flags & USPosition)
8479a1f3da82Smrg	XMoveWindow(XtDisplay(xw), VShellWindow(xw),
8480d522f475Smrg		    xw->hints.x, xw->hints.y);
8481d522f475Smrg
8482d522f475Smrg    TRACE(("%s@%d -- ", __FILE__, __LINE__));
8483d522f475Smrg    TRACE_HINTS(&xw->hints);
8484a1f3da82Smrg    XSetWMNormalHints(XtDisplay(xw), VShellWindow(xw), &xw->hints);
8485d522f475Smrg    TRACE(("%s@%d -- ", __FILE__, __LINE__));
8486d522f475Smrg    TRACE_WM_HINTS(xw);
8487d522f475Smrg
8488d522f475Smrg    if ((pid_atom = XInternAtom(XtDisplay(xw), "_NET_WM_PID", False)) != None) {
8489d522f475Smrg	/* XChangeProperty format 32 really is "long" */
8490d522f475Smrg	unsigned long pid_l = (unsigned long) getpid();
8491d522f475Smrg	TRACE(("Setting _NET_WM_PID property to %lu\n", pid_l));
8492a1f3da82Smrg	XChangeProperty(XtDisplay(xw), VShellWindow(xw),
8493d522f475Smrg			pid_atom, XA_CARDINAL, 32, PropModeReplace,
8494d522f475Smrg			(unsigned char *) &pid_l, 1);
8495d522f475Smrg    }
8496d522f475Smrg
8497d522f475Smrg    XFlush(XtDisplay(xw));	/* get it out to window manager */
8498d522f475Smrg
8499d522f475Smrg    /* use ForgetGravity instead of SouthWestGravity because translating
8500d522f475Smrg       the Expose events for ConfigureNotifys is too hard */
8501956cc18dSsnj    values->bit_gravity = (GravityIsNorthWest(xw)
8502d522f475Smrg			   ? NorthWestGravity
8503d522f475Smrg			   : ForgetGravity);
8504e39b573cSmrg    screen->fullVwin.window = XtWindow(xw) =
8505d522f475Smrg	XCreateWindow(XtDisplay(xw), XtWindow(XtParent(xw)),
8506d522f475Smrg		      xw->core.x, xw->core.y,
8507d522f475Smrg		      xw->core.width, xw->core.height, BorderWidth(xw),
8508d522f475Smrg		      (int) xw->core.depth,
8509d522f475Smrg		      InputOutput, CopyFromParent,
8510d522f475Smrg		      *valuemask | CWBitGravity, values);
85110bd37d32Smrg#if OPT_DOUBLE_BUFFER
85120bd37d32Smrg    screen->fullVwin.drawable = screen->fullVwin.window;
85130bd37d32Smrg
85140bd37d32Smrg    {
85150bd37d32Smrg	Window win = screen->fullVwin.window;
85160bd37d32Smrg	Drawable d;
85170bd37d32Smrg	int major, minor;
85180bd37d32Smrg	if (!XdbeQueryExtension(XtDisplay(xw), &major, &minor)) {
85190bd37d32Smrg	    fprintf(stderr, "XdbeQueryExtension returned zero!\n");
85200bd37d32Smrg	    exit(3);
85210bd37d32Smrg	}
85220bd37d32Smrg	d = XdbeAllocateBackBufferName(XtDisplay(xw), win, XdbeCopied);
85230bd37d32Smrg	if (d == None) {
85240bd37d32Smrg	    fprintf(stderr, "Couldn't allocate a back buffer!\n");
85250bd37d32Smrg	    exit(3);
85260bd37d32Smrg	}
85270bd37d32Smrg	screen->fullVwin.drawable = d;
85280bd37d32Smrg	screen->needSwap = 1;
85290bd37d32Smrg    }
85300bd37d32Smrg#endif /* OPT_DOUBLE_BUFFER */
8531d522f475Smrg    screen->event_mask = values->event_mask;
8532d522f475Smrg
8533d522f475Smrg#ifndef NO_ACTIVE_ICON
8534492d43a5Smrg    /*
8535492d43a5Smrg     * Normally, the font-number for icon fonts does not correspond with any of
8536492d43a5Smrg     * the menu-selectable fonts.  If we cannot load the font given for the
8537492d43a5Smrg     * iconFont resource, try with font1 aka "Unreadable".
8538492d43a5Smrg     */
8539492d43a5Smrg    screen->icon_fontnum = -1;
8540492d43a5Smrg    if (screen->fnt_icon.fs == 0) {
8541492d43a5Smrg	screen->fnt_icon.fs = XLoadQueryFont(screen->display,
8542492d43a5Smrg					     screen->MenuFontName(fontMenu_font1));
8543492d43a5Smrg	TRACE(("%susing font1 '%s' as iconFont\n",
8544492d43a5Smrg	       (screen->fnt_icon.fs
8545492d43a5Smrg		? ""
8546492d43a5Smrg		: "NOT "),
8547492d43a5Smrg	       screen->MenuFontName(fontMenu_font1)));
8548492d43a5Smrg    }
8549492d43a5Smrg#if OPT_RENDERFONT
8550492d43a5Smrg    /*
8551492d43a5Smrg     * If we still have no result from iconFont resource (perhaps because fonts
8552492d43a5Smrg     * are missing) but are using Xft, try to use that instead.  We prefer
8553492d43a5Smrg     * bitmap fonts in any case, since scaled fonts are usually less readable,
8554492d43a5Smrg     * particularly at small sizes.
8555492d43a5Smrg     */
8556492d43a5Smrg    if (UsingRenderFont(xw)
8557492d43a5Smrg	&& screen->fnt_icon.fs == 0) {
8558492d43a5Smrg	screen->icon_fontnum = fontMenu_default;
8559492d43a5Smrg	screen->fnt_icon.fs = screen->fnts[0].fs;	/* need for next-if */
8560492d43a5Smrg	TRACE(("using TrueType font as iconFont\n"));
8561492d43a5Smrg    }
8562492d43a5Smrg#endif
85630bd37d32Smrg    if ((xw->work.active_icon == eiDefault) && screen->fnt_icon.fs) {
85640bd37d32Smrg	char *wm_name = getWindowManagerName(xw);
85650bd37d32Smrg	if (x_strncasecmp(wm_name, "fvwm", 4) &&
85660bd37d32Smrg	    x_strncasecmp(wm_name, "window maker", 12))
85670bd37d32Smrg	    xw->work.active_icon = eiFalse;
85680bd37d32Smrg	free(wm_name);
85690bd37d32Smrg    }
85700bd37d32Smrg    if (xw->work.active_icon && screen->fnt_icon.fs) {
8571d522f475Smrg	int iconX = 0, iconY = 0;
8572d522f475Smrg	Widget shell = SHELL_OF(xw);
8573d522f475Smrg	VTwin *win = &(screen->iconVwin);
8574492d43a5Smrg	int save_fontnum = screen->menu_font_number;
8575d522f475Smrg
8576492d43a5Smrg	TRACE(("Initializing active-icon %d\n", screen->icon_fontnum));
8577492d43a5Smrg	screen->menu_font_number = screen->icon_fontnum;
8578492d43a5Smrg	XtVaGetValues(shell,
8579492d43a5Smrg		      XtNiconX, &iconX,
8580492d43a5Smrg		      XtNiconY, &iconY,
8581492d43a5Smrg		      (XtPointer) 0);
8582d522f475Smrg	xtermComputeFontInfo(xw, &(screen->iconVwin), screen->fnt_icon.fs, 0);
8583492d43a5Smrg	screen->menu_font_number = save_fontnum;
8584d522f475Smrg
8585d522f475Smrg	/* since only one client is permitted to select for Button
8586d522f475Smrg	 * events, we have to let the window manager get 'em...
8587d522f475Smrg	 */
8588d522f475Smrg	values->event_mask &= ~(ButtonPressMask | ButtonReleaseMask);
8589d522f475Smrg	values->border_pixel = xw->misc.icon_border_pixel;
8590d522f475Smrg
8591d522f475Smrg	screen->iconVwin.window =
8592d522f475Smrg	    XCreateWindow(XtDisplay(xw),
8593d522f475Smrg			  RootWindowOfScreen(XtScreen(shell)),
8594d522f475Smrg			  iconX, iconY,
8595d522f475Smrg			  screen->iconVwin.fullwidth,
8596d522f475Smrg			  screen->iconVwin.fullheight,
8597d522f475Smrg			  xw->misc.icon_border_width,
8598d522f475Smrg			  (int) xw->core.depth,
8599d522f475Smrg			  InputOutput, CopyFromParent,
8600d522f475Smrg			  *valuemask | CWBitGravity | CWBorderPixel,
8601d522f475Smrg			  values);
86020bd37d32Smrg#if OPT_DOUBLE_BUFFER
86030bd37d32Smrg	screen->iconVwin.drawable = screen->iconVwin.window;
86040bd37d32Smrg#endif
8605d522f475Smrg	XtVaSetValues(shell,
8606d522f475Smrg		      XtNiconWindow, screen->iconVwin.window,
8607d522f475Smrg		      (XtPointer) 0);
8608d522f475Smrg	XtRegisterDrawable(XtDisplay(xw), screen->iconVwin.window, w);
8609d522f475Smrg
8610d522f475Smrg	setCgsFont(xw, win, gcNorm, &(screen->fnt_icon));
8611d522f475Smrg	setCgsFore(xw, win, gcNorm, T_COLOR(screen, TEXT_FG));
8612d522f475Smrg	setCgsBack(xw, win, gcNorm, T_COLOR(screen, TEXT_BG));
8613d522f475Smrg
8614d522f475Smrg	copyCgs(xw, win, gcBold, gcNorm);
8615d522f475Smrg
8616d522f475Smrg	setCgsFont(xw, win, gcNormReverse, &(screen->fnt_icon));
8617d522f475Smrg	setCgsFore(xw, win, gcNormReverse, T_COLOR(screen, TEXT_BG));
8618d522f475Smrg	setCgsBack(xw, win, gcNormReverse, T_COLOR(screen, TEXT_FG));
8619d522f475Smrg
8620d522f475Smrg	copyCgs(xw, win, gcBoldReverse, gcNormReverse);
8621d522f475Smrg
8622d522f475Smrg#if OPT_TOOLBAR
8623d522f475Smrg	/*
8624d522f475Smrg	 * Toolbar is initialized before we get here.  Enable the menu item
8625d522f475Smrg	 * and set it properly.
8626d522f475Smrg	 */
8627d522f475Smrg	SetItemSensitivity(vtMenuEntries[vtMenu_activeicon].widget, True);
8628d522f475Smrg	update_activeicon();
8629d522f475Smrg#endif
8630d522f475Smrg    } else {
8631d522f475Smrg	TRACE(("Disabled active-icon\n"));
86320bd37d32Smrg	xw->work.active_icon = eiFalse;
8633d522f475Smrg    }
8634d522f475Smrg#endif /* NO_ACTIVE_ICON */
8635d522f475Smrg
8636d522f475Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
8637956cc18dSsnj    VTInitI18N(xw);
8638d522f475Smrg#endif
8639d522f475Smrg#if OPT_NUM_LOCK
8640d522f475Smrg    VTInitModifiers(xw);
8641d522f475Smrg#if OPT_EXTRA_PASTE
8642d522f475Smrg    if (xw->keyboard.extra_translations) {
8643d522f475Smrg	XtOverrideTranslations((Widget) xw,
8644d522f475Smrg			       XtParseTranslationTable(xw->keyboard.extra_translations));
8645d522f475Smrg    }
8646d522f475Smrg#endif
8647d522f475Smrg#endif
8648d522f475Smrg
8649d522f475Smrg    set_cursor_gcs(xw);
8650d522f475Smrg
8651d522f475Smrg    /* Reset variables used by ANSI emulation. */
8652d522f475Smrg
8653d522f475Smrg    resetCharsets(screen);
8654d522f475Smrg
8655a1f3da82Smrg    XDefineCursor(screen->display, VShellWindow(xw), screen->pointer_cursor);
8656d522f475Smrg
8657d522f475Smrg    set_cur_col(screen, 0);
8658d522f475Smrg    set_cur_row(screen, 0);
8659d522f475Smrg    set_max_col(screen, Width(screen) / screen->fullVwin.f_width - 1);
8660d522f475Smrg    set_max_row(screen, Height(screen) / screen->fullVwin.f_height - 1);
86610bd37d32Smrg    reset_margins(screen);
8662d522f475Smrg
8663d522f475Smrg    memset(screen->sc, 0, sizeof(screen->sc));
8664d522f475Smrg
8665d522f475Smrg    /* Mark screen buffer as unallocated.  We wait until the run loop so
8666d522f475Smrg       that the child process does not fork and exec with all the dynamic
8667d522f475Smrg       memory it will never use.  If we were to do it here, the
8668d522f475Smrg       swap space for new process would be huge for huge savelines. */
8669d522f475Smrg#if OPT_TEK4014
8670d522f475Smrg    if (!tekWidget)		/* if not called after fork */
8671d522f475Smrg#endif
8672956cc18dSsnj    {
8673956cc18dSsnj	screen->visbuf = NULL;
8674956cc18dSsnj	screen->saveBuf_index = NULL;
8675956cc18dSsnj    }
8676d522f475Smrg
86770bd37d32Smrg    ResetWrap(screen);
8678d522f475Smrg    screen->scrolls = screen->incopy = 0;
8679d522f475Smrg    xtermSetCursorBox(screen);
8680d522f475Smrg
8681d522f475Smrg    screen->savedlines = 0;
8682d522f475Smrg
8683d522f475Smrg    for (i = 0; i < 2; ++i) {
8684956cc18dSsnj	screen->whichBuf = !screen->whichBuf;
8685d522f475Smrg	CursorSave(xw);
8686d522f475Smrg    }
8687d522f475Smrg
86880bd37d32Smrg#ifndef NO_ACTIVE_ICON
86890bd37d32Smrg    if (!xw->work.active_icon)
86900bd37d32Smrg#endif
86910bd37d32Smrg	xtermLoadIcon(xw);
86920bd37d32Smrg
8693d522f475Smrg    /*
8694d522f475Smrg     * Do this last, since it may change the layout via a resize.
8695d522f475Smrg     */
8696d522f475Smrg    if (xw->misc.scrollbar) {
8697d522f475Smrg	screen->fullVwin.sb_info.width = 0;
8698956cc18dSsnj	ScrollBarOn(xw, False);
8699d522f475Smrg    }
8700a1f3da82Smrg
8701d522f475Smrg    return;
8702d522f475Smrg}
8703d522f475Smrg
8704d522f475Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
8705d522f475Smrg
8706d522f475Smrg/* limit this feature to recent XFree86 since X11R6.x core dumps */
8707d522f475Smrg#if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && defined(X_HAVE_UTF8_STRING)
8708d522f475Smrg#define USE_XIM_INSTANTIATE_CB
8709d522f475Smrg
8710d522f475Smrgstatic void
8711d522f475Smrgxim_instantiate_cb(Display * display,
8712d522f475Smrg		   XPointer client_data GCC_UNUSED,
8713d522f475Smrg		   XPointer call_data GCC_UNUSED)
8714d522f475Smrg{
87150bd37d32Smrg    TRACE(("xim_instantiate_cb client=%p, call=%p\n", client_data, call_data));
8716d522f475Smrg
87170bd37d32Smrg    if (display == XtDisplay(term)) {
87180bd37d32Smrg	VTInitI18N(term);
87190bd37d32Smrg    }
8720d522f475Smrg}
8721d522f475Smrg
8722d522f475Smrgstatic void
8723d522f475Smrgxim_destroy_cb(XIM im GCC_UNUSED,
8724d522f475Smrg	       XPointer client_data GCC_UNUSED,
8725d522f475Smrg	       XPointer call_data GCC_UNUSED)
8726d522f475Smrg{
87270bd37d32Smrg    XtermWidget xw = term;
87280bd37d32Smrg    TInput *input = lookupTInput(xw, (Widget) xw);
8729d522f475Smrg
87300bd37d32Smrg    TRACE(("xim_destroy_cb im=%lx, client=%p, call=%p\n",
87310bd37d32Smrg	   (long) im, client_data, call_data));
87320bd37d32Smrg    if (input)
87330bd37d32Smrg	input->xic = NULL;
87340bd37d32Smrg    XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL,
8735d522f475Smrg				   xim_instantiate_cb, NULL);
8736d522f475Smrg}
8737d522f475Smrg#endif /* X11R6+ */
8738d522f475Smrg
87390bd37d32Smrgstatic Boolean
87400bd37d32Smrgxim_create_fs(XtermWidget xw)
87410bd37d32Smrg{
87420bd37d32Smrg    XFontStruct **fonts;
87430bd37d32Smrg    char **font_name_list;
87440bd37d32Smrg    char **missing_charset_list;
87450bd37d32Smrg    char *def_string;
87460bd37d32Smrg    int missing_charset_count;
87470bd37d32Smrg    unsigned i, j;
87480bd37d32Smrg
87490bd37d32Smrg    if (xw->misc.xim_fs == 0) {
87500bd37d32Smrg	xw->misc.xim_fs = XCreateFontSet(XtDisplay(xw),
87510bd37d32Smrg					 xw->misc.f_x,
87520bd37d32Smrg					 &missing_charset_list,
87530bd37d32Smrg					 &missing_charset_count,
87540bd37d32Smrg					 &def_string);
87550bd37d32Smrg	if (xw->misc.xim_fs == NULL) {
87560bd37d32Smrg	    xtermWarning("Preparation of font set "
87570bd37d32Smrg			 "\"%s\" for XIM failed.\n", xw->misc.f_x);
87580bd37d32Smrg	    xw->misc.xim_fs = XCreateFontSet(XtDisplay(xw),
87590bd37d32Smrg					     DEFXIMFONT,
87600bd37d32Smrg					     &missing_charset_list,
87610bd37d32Smrg					     &missing_charset_count,
87620bd37d32Smrg					     &def_string);
87630bd37d32Smrg	}
87640bd37d32Smrg    }
87650bd37d32Smrg    if (xw->misc.xim_fs == NULL) {
87660bd37d32Smrg	xtermWarning("Preparation of default font set "
87670bd37d32Smrg		     "\"%s\" for XIM failed.\n", DEFXIMFONT);
87680bd37d32Smrg	cleanupInputMethod(xw);
87690bd37d32Smrg	xw->misc.cannot_im = True;
87700bd37d32Smrg    } else {
87710bd37d32Smrg	(void) XExtentsOfFontSet(xw->misc.xim_fs);
87720bd37d32Smrg	j = (unsigned) XFontsOfFontSet(xw->misc.xim_fs, &fonts, &font_name_list);
87730bd37d32Smrg	for (i = 0, xw->misc.xim_fs_ascent = 0; i < j; i++) {
87740bd37d32Smrg	    if (xw->misc.xim_fs_ascent < (*fonts)->ascent)
87750bd37d32Smrg		xw->misc.xim_fs_ascent = (*fonts)->ascent;
87760bd37d32Smrg	}
87770bd37d32Smrg    }
87780bd37d32Smrg    return (Boolean) ! (xw->misc.cannot_im);
87790bd37d32Smrg}
87800bd37d32Smrg
8781d522f475Smrgstatic void
87820bd37d32Smrgxim_create_xic(XtermWidget xw, Widget theInput)
8783d522f475Smrg{
87840bd37d32Smrg    Display *myDisplay = XtDisplay(theInput);
87850bd37d32Smrg    Window myWindow = XtWindow(theInput);
8786d522f475Smrg    unsigned i, j;
87870bd37d32Smrg    char *p = NULL, *s, *t, *ns, *end, buf[32];
8788d522f475Smrg    XIMStyles *xim_styles;
8789d522f475Smrg    XIMStyle input_style = 0;
8790d522f475Smrg    Bool found;
8791d522f475Smrg    static struct {
879220d2c4d2Smrg	const char *name;
8793d522f475Smrg	unsigned long code;
8794d522f475Smrg    } known_style[] = {
8795d522f475Smrg	{
8796d522f475Smrg	    "OverTheSpot", (XIMPreeditPosition | XIMStatusNothing)
8797d522f475Smrg	},
8798d522f475Smrg	{
8799d522f475Smrg	    "OffTheSpot", (XIMPreeditArea | XIMStatusArea)
8800d522f475Smrg	},
8801d522f475Smrg	{
8802d522f475Smrg	    "Root", (XIMPreeditNothing | XIMStatusNothing)
8803d522f475Smrg	},
8804d522f475Smrg    };
88050bd37d32Smrg    TInput *input = lookupTInput(xw, theInput);
8806d522f475Smrg
8807956cc18dSsnj    if (xw->misc.cannot_im) {
8808d522f475Smrg	return;
8809d522f475Smrg    }
8810d522f475Smrg
88110bd37d32Smrg    if (input == 0) {
88120bd37d32Smrg	for (i = 0; i < NINPUTWIDGETS; ++i) {
88130bd37d32Smrg	    if (xw->misc.inputs[i].w == 0) {
88140bd37d32Smrg		input = xw->misc.inputs + i;
88150bd37d32Smrg		input->w = theInput;
88160bd37d32Smrg		break;
88170bd37d32Smrg	    }
88180bd37d32Smrg	}
88190bd37d32Smrg    }
88200bd37d32Smrg
88210bd37d32Smrg    if (input == 0) {
88220bd37d32Smrg	xtermWarning("attempted to add too many input widgets\n");
88230bd37d32Smrg	return;
88240bd37d32Smrg    }
88250bd37d32Smrg
88260bd37d32Smrg    TRACE(("xim_real_init\n"));
88270bd37d32Smrg
88280bd37d32Smrg    if (IsEmpty(xw->misc.input_method)) {
88290bd37d32Smrg	if ((p = XSetLocaleModifiers("")) != NULL && *p) {
88300bd37d32Smrg	    input->xim = XOpenIM(myDisplay, NULL, NULL, NULL);
88310bd37d32Smrg	}
8832d522f475Smrg    } else {
8833956cc18dSsnj	s = xw->misc.input_method;
883420d2c4d2Smrg	i = 5 + (unsigned) strlen(s);
883520d2c4d2Smrg
8836d522f475Smrg	t = (char *) MyStackAlloc(i, buf);
883720d2c4d2Smrg	if (t == NULL) {
8838d522f475Smrg	    SysError(ERROR_VINIT);
883920d2c4d2Smrg	} else {
8840d522f475Smrg
884120d2c4d2Smrg	    for (ns = s; ns && *s;) {
884220d2c4d2Smrg		while (*s && isspace(CharOf(*s)))
884320d2c4d2Smrg		    s++;
884420d2c4d2Smrg		if (!*s)
8845d522f475Smrg		    break;
884620d2c4d2Smrg		if ((ns = end = strchr(s, ',')) == 0)
884720d2c4d2Smrg		    end = s + strlen(s);
884820d2c4d2Smrg		while ((end != s) && isspace(CharOf(end[-1])))
884920d2c4d2Smrg		    end--;
885020d2c4d2Smrg
885120d2c4d2Smrg		if (end != s) {
885220d2c4d2Smrg		    strcpy(t, "@im=");
885320d2c4d2Smrg		    strncat(t, s, (size_t) (end - s));
885420d2c4d2Smrg
885520d2c4d2Smrg		    if ((p = XSetLocaleModifiers(t)) != 0 && *p
88560bd37d32Smrg			&& (input->xim = XOpenIM(myDisplay,
88570bd37d32Smrg						 NULL,
88580bd37d32Smrg						 NULL,
88590bd37d32Smrg						 NULL)) != 0) {
886020d2c4d2Smrg			break;
88610bd37d32Smrg		    }
8862d522f475Smrg
886320d2c4d2Smrg		}
886420d2c4d2Smrg		s = ns + 1;
8865d522f475Smrg	    }
886620d2c4d2Smrg	    MyStackFree(t, buf);
8867d522f475Smrg	}
8868d522f475Smrg    }
8869d522f475Smrg
88700bd37d32Smrg    if (input->xim == NULL
8871d522f475Smrg	&& (p = XSetLocaleModifiers("@im=none")) != NULL
8872d522f475Smrg	&& *p) {
88730bd37d32Smrg	input->xim = XOpenIM(myDisplay, NULL, NULL, NULL);
8874d522f475Smrg    }
8875d522f475Smrg
88760bd37d32Smrg    if (!input->xim) {
88770bd37d32Smrg	xtermWarning("Failed to open input method\n");
8878d522f475Smrg	return;
8879d522f475Smrg    }
88800bd37d32Smrg    TRACE(("VTInitI18N opened input method:%s\n", NonNull(p)));
8881d522f475Smrg
88820bd37d32Smrg    if (XGetIMValues(input->xim, XNQueryInputStyle, &xim_styles, (void *) 0)
8883d522f475Smrg	|| !xim_styles
8884d522f475Smrg	|| !xim_styles->count_styles) {
88850bd37d32Smrg	xtermWarning("input method doesn't support any style\n");
88860bd37d32Smrg	cleanupInputMethod(xw);
8887956cc18dSsnj	xw->misc.cannot_im = True;
8888d522f475Smrg	return;
8889d522f475Smrg    }
8890d522f475Smrg
8891d522f475Smrg    found = False;
8892956cc18dSsnj    for (s = xw->misc.preedit_type; s && !found;) {
8893d522f475Smrg	while (*s && isspace(CharOf(*s)))
8894d522f475Smrg	    s++;
8895d522f475Smrg	if (!*s)
8896d522f475Smrg	    break;
8897d522f475Smrg	if ((ns = end = strchr(s, ',')) != 0)
8898d522f475Smrg	    ns++;
8899d522f475Smrg	else
8900d522f475Smrg	    end = s + strlen(s);
8901d522f475Smrg	while ((end != s) && isspace(CharOf(end[-1])))
8902d522f475Smrg	    end--;
8903d522f475Smrg
8904d522f475Smrg	if (end != s) {		/* just in case we have a spurious comma */
890520d2c4d2Smrg	    TRACE(("looking for style '%.*s'\n", (int) (end - s), s));
8906d522f475Smrg	    for (i = 0; i < XtNumber(known_style); i++) {
8907d522f475Smrg		if ((int) strlen(known_style[i].name) == (end - s)
890820d2c4d2Smrg		    && !strncmp(s, known_style[i].name, (size_t) (end - s))) {
8909d522f475Smrg		    input_style = known_style[i].code;
8910d522f475Smrg		    for (j = 0; j < xim_styles->count_styles; j++) {
8911d522f475Smrg			if (input_style == xim_styles->supported_styles[j]) {
8912d522f475Smrg			    found = True;
8913d522f475Smrg			    break;
8914d522f475Smrg			}
8915d522f475Smrg		    }
8916d522f475Smrg		    if (found)
8917d522f475Smrg			break;
8918d522f475Smrg		}
8919d522f475Smrg	    }
8920d522f475Smrg	}
8921d522f475Smrg
8922d522f475Smrg	s = ns;
8923d522f475Smrg    }
8924d522f475Smrg    XFree(xim_styles);
8925d522f475Smrg
8926d522f475Smrg    if (!found) {
89270bd37d32Smrg	xtermWarning("input method doesn't support my preedit type (%s)\n",
89280bd37d32Smrg		     xw->misc.preedit_type);
89290bd37d32Smrg	cleanupInputMethod(xw);
8930956cc18dSsnj	xw->misc.cannot_im = True;
8931d522f475Smrg	return;
8932d522f475Smrg    }
8933d522f475Smrg
8934d522f475Smrg    /*
8935d522f475Smrg     * Check for styles we do not yet support.
8936d522f475Smrg     */
8937d522f475Smrg    TRACE(("input_style %#lx\n", input_style));
8938d522f475Smrg    if (input_style == (XIMPreeditArea | XIMStatusArea)) {
89390bd37d32Smrg	xtermWarning("This program doesn't support the 'OffTheSpot' preedit type\n");
89400bd37d32Smrg	cleanupInputMethod(xw);
8941956cc18dSsnj	xw->misc.cannot_im = True;
8942d522f475Smrg	return;
8943d522f475Smrg    }
8944d522f475Smrg
8945d522f475Smrg    /*
8946d522f475Smrg     * For XIMPreeditPosition (or OverTheSpot), XIM client has to
8947d522f475Smrg     * prepare a font.
8948d522f475Smrg     * The font has to be locale-dependent XFontSet, whereas
8949d522f475Smrg     * XTerm use Unicode font.  This leads a problem that the
8950d522f475Smrg     * same font cannot be used for XIM preedit.
8951d522f475Smrg     */
8952d522f475Smrg    if (input_style != (XIMPreeditNothing | XIMStatusNothing)) {
8953d522f475Smrg	XVaNestedList p_list;
8954d522f475Smrg	XPoint spot =
8955d522f475Smrg	{0, 0};
89560bd37d32Smrg
89570bd37d32Smrg	if (xim_create_fs(xw)) {
89580bd37d32Smrg	    p_list = XVaCreateNestedList(0,
89590bd37d32Smrg					 XNSpotLocation, &spot,
89600bd37d32Smrg					 XNFontSet, xw->misc.xim_fs,
89610bd37d32Smrg					 (void *) 0);
89620bd37d32Smrg	    input->xic = XCreateIC(input->xim,
89630bd37d32Smrg				   XNInputStyle, input_style,
89640bd37d32Smrg				   XNClientWindow, myWindow,
89650bd37d32Smrg				   XNFocusWindow, myWindow,
89660bd37d32Smrg				   XNPreeditAttributes, p_list,
89670bd37d32Smrg				   (void *) 0);
8968d522f475Smrg	}
8969d522f475Smrg    } else {
89700bd37d32Smrg	input->xic = XCreateIC(input->xim, XNInputStyle, input_style,
89710bd37d32Smrg			       XNClientWindow, myWindow,
89720bd37d32Smrg			       XNFocusWindow, myWindow,
89730bd37d32Smrg			       (void *) 0);
8974d522f475Smrg    }
8975d522f475Smrg
89760bd37d32Smrg    if (!input->xic) {
89770bd37d32Smrg	xtermWarning("Failed to create input context\n");
89780bd37d32Smrg	cleanupInputMethod(xw);
8979d522f475Smrg    }
8980d522f475Smrg#if defined(USE_XIM_INSTANTIATE_CB)
8981d522f475Smrg    else {
8982d522f475Smrg	XIMCallback destroy_cb;
8983d522f475Smrg
8984d522f475Smrg	destroy_cb.callback = xim_destroy_cb;
8985d522f475Smrg	destroy_cb.client_data = NULL;
89860bd37d32Smrg	if (XSetIMValues(input->xim,
89870bd37d32Smrg			 XNDestroyCallback,
89880bd37d32Smrg			 &destroy_cb,
89890bd37d32Smrg			 (void *) 0)) {
89900bd37d32Smrg	    xtermWarning("Could not set destroy callback to IM\n");
89910bd37d32Smrg	}
8992d522f475Smrg    }
8993d522f475Smrg#endif
8994d522f475Smrg
8995d522f475Smrg    return;
8996d522f475Smrg}
8997d522f475Smrg
89980bd37d32Smrgstatic void
89990bd37d32Smrgxim_real_init(XtermWidget xw)
90000bd37d32Smrg{
90010bd37d32Smrg    xim_create_xic(xw, (Widget) xw);
90020bd37d32Smrg}
90030bd37d32Smrg
9004d522f475Smrgstatic void
9005956cc18dSsnjVTInitI18N(XtermWidget xw)
9006d522f475Smrg{
9007956cc18dSsnj    if (xw->misc.open_im) {
9008956cc18dSsnj	xim_real_init(xw);
9009d522f475Smrg
9010d522f475Smrg#if defined(USE_XIM_INSTANTIATE_CB)
90110bd37d32Smrg	if (lookupTInput(xw, (Widget) xw) == NULL
9012956cc18dSsnj	    && !xw->misc.cannot_im
9013956cc18dSsnj	    && xw->misc.retry_im-- > 0) {
9014d522f475Smrg	    sleep(3);
9015956cc18dSsnj	    XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL,
9016d522f475Smrg					   xim_instantiate_cb, NULL);
9017d522f475Smrg	}
9018d522f475Smrg#endif
9019d522f475Smrg    }
9020d522f475Smrg}
90210bd37d32Smrg
90220bd37d32SmrgTInput *
90230bd37d32SmrglookupTInput(XtermWidget xw, Widget w)
90240bd37d32Smrg{
90250bd37d32Smrg    TInput *result = 0;
90260bd37d32Smrg    unsigned n;
90270bd37d32Smrg
90280bd37d32Smrg    for (n = 0; n < NINPUTWIDGETS; ++n) {
90290bd37d32Smrg	if (xw->misc.inputs[n].w == w) {
90300bd37d32Smrg	    result = xw->misc.inputs + n;
90310bd37d32Smrg	    break;
90320bd37d32Smrg	}
90330bd37d32Smrg    }
90340bd37d32Smrg
90350bd37d32Smrg    return result;
90360bd37d32Smrg}
9037d522f475Smrg#endif /* OPT_I18N_SUPPORT && OPT_INPUT_METHOD */
9038d522f475Smrg
9039a1f3da82Smrgstatic void
9040a1f3da82Smrgset_cursor_outline_gc(XtermWidget xw,
9041a1f3da82Smrg		      Bool filled,
9042a1f3da82Smrg		      Pixel fg,
9043a1f3da82Smrg		      Pixel bg,
9044a1f3da82Smrg		      Pixel cc)
9045a1f3da82Smrg{
9046a1f3da82Smrg    TScreen *screen = TScreenOf(xw);
9047a1f3da82Smrg    VTwin *win = WhichVWin(screen);
9048a1f3da82Smrg    CgsEnum cgsId = gcVTcursOutline;
9049a1f3da82Smrg
9050a1f3da82Smrg    if (cc == bg)
9051a1f3da82Smrg	cc = fg;
9052a1f3da82Smrg
9053a1f3da82Smrg    if (filled) {
9054a1f3da82Smrg	setCgsFore(xw, win, cgsId, bg);
9055a1f3da82Smrg	setCgsBack(xw, win, cgsId, cc);
9056a1f3da82Smrg    } else {
9057a1f3da82Smrg	setCgsFore(xw, win, cgsId, cc);
9058a1f3da82Smrg	setCgsBack(xw, win, cgsId, bg);
9059a1f3da82Smrg    }
9060a1f3da82Smrg}
9061a1f3da82Smrg
9062d522f475Smrgstatic Boolean
9063d522f475SmrgVTSetValues(Widget cur,
9064d522f475Smrg	    Widget request GCC_UNUSED,
9065d522f475Smrg	    Widget wnew,
9066d522f475Smrg	    ArgList args GCC_UNUSED,
9067d522f475Smrg	    Cardinal *num_args GCC_UNUSED)
9068d522f475Smrg{
9069d522f475Smrg    XtermWidget curvt = (XtermWidget) cur;
9070d522f475Smrg    XtermWidget newvt = (XtermWidget) wnew;
90712eaa94a1Schristos    Boolean refresh_needed = False;
90722eaa94a1Schristos    Boolean fonts_redone = False;
9073d522f475Smrg
907420d2c4d2Smrg    if ((T_COLOR(TScreenOf(curvt), TEXT_BG) !=
907520d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), TEXT_BG)) ||
907620d2c4d2Smrg	(T_COLOR(TScreenOf(curvt), TEXT_FG) !=
907720d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), TEXT_FG)) ||
907820d2c4d2Smrg	(TScreenOf(curvt)->MenuFontName(TScreenOf(curvt)->menu_font_number) !=
907920d2c4d2Smrg	 TScreenOf(newvt)->MenuFontName(TScreenOf(newvt)->menu_font_number)) ||
9080d522f475Smrg	(curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)) {
9081d522f475Smrg	if (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)
908220d2c4d2Smrg	    TScreenOf(newvt)->MenuFontName(fontMenu_default) = newvt->misc.default_font.f_n;
9083d522f475Smrg	if (xtermLoadFont(newvt,
908420d2c4d2Smrg			  xtermFontName(TScreenOf(newvt)->MenuFontName(TScreenOf(curvt)->menu_font_number)),
908520d2c4d2Smrg			  True, TScreenOf(newvt)->menu_font_number)) {
9086d522f475Smrg	    /* resizing does the redisplay, so don't ask for it here */
9087d522f475Smrg	    refresh_needed = True;
9088d522f475Smrg	    fonts_redone = True;
9089d522f475Smrg	} else if (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)
909020d2c4d2Smrg	    TScreenOf(newvt)->MenuFontName(fontMenu_default) = curvt->misc.default_font.f_n;
9091d522f475Smrg    }
9092d522f475Smrg    if (!fonts_redone
909320d2c4d2Smrg	&& (T_COLOR(TScreenOf(curvt), TEXT_CURSOR) !=
909420d2c4d2Smrg	    T_COLOR(TScreenOf(newvt), TEXT_CURSOR))) {
9095492d43a5Smrg	if (set_cursor_gcs(newvt))
9096492d43a5Smrg	    refresh_needed = True;
9097d522f475Smrg    }
9098d522f475Smrg    if (curvt->misc.re_verse != newvt->misc.re_verse) {
9099d522f475Smrg	newvt->flags ^= REVERSE_VIDEO;
9100d522f475Smrg	ReverseVideo(newvt);
91012eaa94a1Schristos	/* ReverseVideo toggles */
91022eaa94a1Schristos	newvt->misc.re_verse = (Boolean) (!newvt->misc.re_verse);
9103d522f475Smrg	refresh_needed = True;
9104d522f475Smrg    }
910520d2c4d2Smrg    if ((T_COLOR(TScreenOf(curvt), MOUSE_FG) !=
910620d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), MOUSE_FG)) ||
910720d2c4d2Smrg	(T_COLOR(TScreenOf(curvt), MOUSE_BG) !=
910820d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), MOUSE_BG))) {
910920d2c4d2Smrg	recolor_cursor(TScreenOf(newvt),
911020d2c4d2Smrg		       TScreenOf(newvt)->pointer_cursor,
911120d2c4d2Smrg		       T_COLOR(TScreenOf(newvt), MOUSE_FG),
911220d2c4d2Smrg		       T_COLOR(TScreenOf(newvt), MOUSE_BG));
9113d522f475Smrg	refresh_needed = True;
9114d522f475Smrg    }
9115d522f475Smrg    if (curvt->misc.scrollbar != newvt->misc.scrollbar) {
9116d522f475Smrg	ToggleScrollBar(newvt);
9117d522f475Smrg    }
9118d522f475Smrg
9119d522f475Smrg    return refresh_needed;
9120d522f475Smrg}
9121d522f475Smrg
9122d522f475Smrg#define setGC(code) set_at = __LINE__, currentCgs = code
9123d522f475Smrg
9124d522f475Smrg#define OutsideSelection(screen,srow,scol)  \
9125d522f475Smrg	 ((srow) > (screen)->endH.row || \
9126d522f475Smrg	  ((srow) == (screen)->endH.row && \
9127d522f475Smrg	   (scol) >= (screen)->endH.col) || \
9128d522f475Smrg	  (srow) < (screen)->startH.row || \
9129d522f475Smrg	  ((srow) == (screen)->startH.row && \
9130d522f475Smrg	   (scol) < (screen)->startH.col))
9131d522f475Smrg
9132d522f475Smrg/*
9133d522f475Smrg * Shows cursor at new cursor position in screen.
9134d522f475Smrg */
9135d522f475Smrgvoid
9136d522f475SmrgShowCursor(void)
9137d522f475Smrg{
9138d522f475Smrg    XtermWidget xw = term;
913920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
9140d522f475Smrg    int x, y;
9141956cc18dSsnj    IChar base;
9142d522f475Smrg    unsigned flags;
9143956cc18dSsnj    CellColor fg_bg = 0;
9144d522f475Smrg    GC currentGC;
914520d2c4d2Smrg    GC outlineGC;
9146d522f475Smrg    CgsEnum currentCgs = gcMAX;
9147d522f475Smrg    VTwin *currentWin = WhichVWin(screen);
9148d522f475Smrg    int set_at;
9149d522f475Smrg    Bool in_selection;
9150d522f475Smrg    Bool reversed;
9151d522f475Smrg    Bool filled;
9152d522f475Smrg    Pixel fg_pix;
9153d522f475Smrg    Pixel bg_pix;
9154d522f475Smrg    Pixel tmp;
9155d522f475Smrg#if OPT_HIGHLIGHT_COLOR
9156d522f475Smrg    Pixel selbg_pix = T_COLOR(screen, HIGHLIGHT_BG);
9157d522f475Smrg    Pixel selfg_pix = T_COLOR(screen, HIGHLIGHT_FG);
9158d522f475Smrg    Boolean use_selbg;
9159d522f475Smrg    Boolean use_selfg;
9160d522f475Smrg#endif
9161d522f475Smrg#if OPT_WIDE_CHARS
9162956cc18dSsnj    size_t off;
9163d522f475Smrg    int my_col = 0;
9164d522f475Smrg#endif
9165d522f475Smrg    int cursor_col;
9166956cc18dSsnj    LineData *ld = 0;
9167d522f475Smrg
9168d522f475Smrg    if (screen->cursor_state == BLINKED_OFF)
9169d522f475Smrg	return;
9170d522f475Smrg
9171d522f475Smrg    if (screen->eventMode != NORMAL)
9172d522f475Smrg	return;
9173d522f475Smrg
9174d522f475Smrg    if (INX2ROW(screen, screen->cur_row) > screen->max_row)
9175d522f475Smrg	return;
9176d522f475Smrg
9177d522f475Smrg    screen->cursorp.row = screen->cur_row;
9178d522f475Smrg    cursor_col = screen->cursorp.col = screen->cur_col;
9179d522f475Smrg    screen->cursor_moved = False;
9180d522f475Smrg
9181d522f475Smrg#ifndef NO_ACTIVE_ICON
9182d522f475Smrg    if (IsIcon(screen)) {
9183d522f475Smrg	screen->cursor_state = ON;
9184d522f475Smrg	return;
9185d522f475Smrg    }
9186d522f475Smrg#endif /* NO_ACTIVE_ICON */
9187d522f475Smrg
9188956cc18dSsnj    ld = getLineData(screen, screen->cur_row);
9189956cc18dSsnj
9190956cc18dSsnj    base = ld->charData[cursor_col];
9191956cc18dSsnj    flags = ld->attribs[cursor_col];
9192d522f475Smrg
9193d522f475Smrg    if_OPT_WIDE_CHARS(screen, {
9194956cc18dSsnj	if (base == HIDDEN_CHAR && cursor_col > 0) {
9195d522f475Smrg	    /* if cursor points to non-initial part of wide character,
9196d522f475Smrg	     * back it up
9197d522f475Smrg	     */
9198d522f475Smrg	    --cursor_col;
9199956cc18dSsnj	    base = ld->charData[cursor_col];
9200d522f475Smrg	}
9201d522f475Smrg	my_col = cursor_col;
9202956cc18dSsnj	if (base == 0)
9203956cc18dSsnj	    base = ' ';
9204956cc18dSsnj	if (isWide((int) base))
9205d522f475Smrg	    my_col += 1;
9206d522f475Smrg    });
9207d522f475Smrg
9208956cc18dSsnj    if (base == 0) {
9209956cc18dSsnj	base = ' ';
9210d522f475Smrg    }
9211956cc18dSsnj#if OPT_ISO_COLORS
9212956cc18dSsnj#ifdef EXP_BOGUS_FG
9213956cc18dSsnj    /*
9214956cc18dSsnj     * If the cursor happens to be on blanks, and we have not set both
9215956cc18dSsnj     * foreground and background color, do not treat it as a colored cell.
9216956cc18dSsnj     */
9217956cc18dSsnj    if (base == ' ') {
9218956cc18dSsnj	if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) {
9219956cc18dSsnj	    TRACE(("ShowCursor - do not treat as a colored cell\n"));
9220956cc18dSsnj	    flags &= ~(FG_COLOR | BG_COLOR);
9221956cc18dSsnj	} else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) {
9222956cc18dSsnj	    TRACE(("ShowCursor - should we treat as a colored cell?\n"));
9223956cc18dSsnj	    if (!(xw->flags & FG_COLOR))
9224956cc18dSsnj		if (CheckBogusForeground(screen, "ShowCursor"))
9225956cc18dSsnj		    flags &= ~(FG_COLOR | BG_COLOR);
9226956cc18dSsnj	}
9227956cc18dSsnj    }
9228956cc18dSsnj#else /* !EXP_BOGUS_FG */
9229d522f475Smrg    /*
9230d522f475Smrg     * If the cursor happens to be on blanks, and the foreground color is set
9231d522f475Smrg     * but not the background, do not treat it as a colored cell.
9232d522f475Smrg     */
92330bd37d32Smrg    if ((flags & TERM_COLOR_FLAGS(xw)) == FG_COLOR
9234956cc18dSsnj	&& base == ' ') {
9235d522f475Smrg	flags &= ~TERM_COLOR_FLAGS(xw);
9236d522f475Smrg    }
9237956cc18dSsnj#endif
9238d522f475Smrg#endif
9239d522f475Smrg
9240d522f475Smrg    /*
9241d522f475Smrg     * Compare the current cell to the last set of colors used for the
9242d522f475Smrg     * cursor and update the GC's if needed.
9243d522f475Smrg     */
9244956cc18dSsnj    if_OPT_ISO_COLORS(screen, {
9245956cc18dSsnj	fg_bg = ld->color[cursor_col];
9246d522f475Smrg    });
924720d2c4d2Smrg
9248d522f475Smrg    fg_pix = getXtermForeground(xw, flags, extract_fg(xw, fg_bg, flags));
9249d522f475Smrg    bg_pix = getXtermBackground(xw, flags, extract_bg(xw, fg_bg, flags));
9250d522f475Smrg
92510bd37d32Smrg    /*
92520bd37d32Smrg     * If we happen to have the same foreground/background colors, choose
92530bd37d32Smrg     * a workable foreground color from which we can obtain a visible cursor.
92540bd37d32Smrg     */
92550bd37d32Smrg    if (fg_pix == bg_pix) {
92560bd37d32Smrg	long bg_diff = (long) (bg_pix - T_COLOR(TScreenOf(xw), TEXT_BG));
92570bd37d32Smrg	long fg_diff = (long) (bg_pix - T_COLOR(TScreenOf(xw), TEXT_FG));
92580bd37d32Smrg	if (bg_diff < 0)
92590bd37d32Smrg	    bg_diff = -bg_diff;
92600bd37d32Smrg	if (fg_diff < 0)
92610bd37d32Smrg	    fg_diff = -fg_diff;
92620bd37d32Smrg	if (bg_diff < fg_diff) {
92630bd37d32Smrg	    fg_pix = T_COLOR(TScreenOf(xw), TEXT_FG);
92640bd37d32Smrg	} else {
92650bd37d32Smrg	    fg_pix = T_COLOR(TScreenOf(xw), TEXT_BG);
92660bd37d32Smrg	}
92670bd37d32Smrg    }
92680bd37d32Smrg
9269d522f475Smrg    if (OutsideSelection(screen, screen->cur_row, screen->cur_col))
9270d522f475Smrg	in_selection = False;
9271d522f475Smrg    else
9272d522f475Smrg	in_selection = True;
9273d522f475Smrg
9274d522f475Smrg    reversed = ReverseOrHilite(screen, flags, in_selection);
9275d522f475Smrg
9276d522f475Smrg    /* This is like updatedXtermGC(), except that we have to worry about
9277d522f475Smrg     * whether the window has focus, since in that case we want just an
9278d522f475Smrg     * outline for the cursor.
9279d522f475Smrg     */
92800bd37d32Smrg    filled = (screen->select || screen->always_highlight) && isCursorBlock(screen);
9281d522f475Smrg#if OPT_HIGHLIGHT_COLOR
9282d522f475Smrg    use_selbg = isNotForeground(xw, fg_pix, bg_pix, selbg_pix);
9283d522f475Smrg    use_selfg = isNotBackground(xw, fg_pix, bg_pix, selfg_pix);
9284d522f475Smrg#endif
9285d522f475Smrg    if (filled) {
9286d522f475Smrg	if (reversed) {		/* text is reverse video */
9287d522f475Smrg	    if (getCgsGC(xw, currentWin, gcVTcursNormal)) {
9288d522f475Smrg		setGC(gcVTcursNormal);
9289d522f475Smrg	    } else {
9290d522f475Smrg		if (flags & BOLDATTR(screen)) {
9291d522f475Smrg		    setGC(gcBold);
9292d522f475Smrg		} else {
9293d522f475Smrg		    setGC(gcNorm);
9294d522f475Smrg		}
9295d522f475Smrg	    }
9296d522f475Smrg	    EXCHANGE(fg_pix, bg_pix, tmp);
9297d522f475Smrg#if OPT_HIGHLIGHT_COLOR
9298d522f475Smrg	    if (screen->hilite_reverse) {
9299d522f475Smrg		if (use_selbg && !use_selfg)
9300d522f475Smrg		    fg_pix = bg_pix;
9301d522f475Smrg		if (use_selfg && !use_selbg)
9302d522f475Smrg		    bg_pix = fg_pix;
9303d522f475Smrg		if (use_selbg)
9304d522f475Smrg		    bg_pix = selbg_pix;
9305d522f475Smrg		if (use_selfg)
9306d522f475Smrg		    fg_pix = selfg_pix;
9307d522f475Smrg	    }
9308d522f475Smrg#endif
9309d522f475Smrg	} else {		/* normal video */
9310d522f475Smrg	    if (getCgsGC(xw, currentWin, gcVTcursReverse)) {
9311d522f475Smrg		setGC(gcVTcursReverse);
9312d522f475Smrg	    } else {
9313d522f475Smrg		if (flags & BOLDATTR(screen)) {
9314d522f475Smrg		    setGC(gcBoldReverse);
9315d522f475Smrg		} else {
9316d522f475Smrg		    setGC(gcNormReverse);
9317d522f475Smrg		}
9318d522f475Smrg	    }
9319d522f475Smrg	}
9320d522f475Smrg	if (T_COLOR(screen, TEXT_CURSOR) == xw->dft_foreground) {
9321d522f475Smrg	    setCgsBack(xw, currentWin, currentCgs, fg_pix);
9322d522f475Smrg	}
9323d522f475Smrg	setCgsFore(xw, currentWin, currentCgs, bg_pix);
9324d522f475Smrg    } else {			/* not selected */
9325d522f475Smrg	if (reversed) {		/* text is reverse video */
9326d522f475Smrg	    EXCHANGE(fg_pix, bg_pix, tmp);
9327d522f475Smrg	    setGC(gcNormReverse);
9328d522f475Smrg	} else {		/* normal video */
9329d522f475Smrg	    setGC(gcNorm);
9330d522f475Smrg	}
9331d522f475Smrg#if OPT_HIGHLIGHT_COLOR
9332d522f475Smrg	if (screen->hilite_reverse) {
9333d522f475Smrg	    if (in_selection && !reversed) {
9334a1f3da82Smrg		/* EMPTY */
9335a1f3da82Smrg		/* really INVERSE ... */
9336a1f3da82Smrg		;
9337d522f475Smrg	    } else if (in_selection || reversed) {
9338d522f475Smrg		if (use_selbg) {
9339d522f475Smrg		    if (use_selfg) {
9340d522f475Smrg			bg_pix = fg_pix;
9341d522f475Smrg		    } else {
9342d522f475Smrg			fg_pix = bg_pix;
9343d522f475Smrg		    }
9344d522f475Smrg		}
9345d522f475Smrg		if (use_selbg) {
9346d522f475Smrg		    bg_pix = selbg_pix;
9347d522f475Smrg		}
9348d522f475Smrg		if (use_selfg) {
9349d522f475Smrg		    fg_pix = selfg_pix;
9350d522f475Smrg		}
9351d522f475Smrg	    }
9352d522f475Smrg	} else {
9353d522f475Smrg	    if (in_selection) {
9354d522f475Smrg		if (use_selbg) {
9355d522f475Smrg		    bg_pix = selbg_pix;
9356d522f475Smrg		}
9357d522f475Smrg		if (use_selfg) {
9358d522f475Smrg		    fg_pix = selfg_pix;
9359d522f475Smrg		}
9360d522f475Smrg	    }
9361d522f475Smrg	}
9362d522f475Smrg#endif
9363d522f475Smrg	setCgsFore(xw, currentWin, currentCgs, fg_pix);
9364d522f475Smrg	setCgsBack(xw, currentWin, currentCgs, bg_pix);
9365d522f475Smrg    }
9366d522f475Smrg
9367d522f475Smrg    if (screen->cursor_busy == 0
9368d522f475Smrg	&& (screen->cursor_state != ON || screen->cursor_GC != set_at)) {
9369d522f475Smrg
9370d522f475Smrg	screen->cursor_GC = set_at;
937120d2c4d2Smrg	TRACE(("ShowCursor calling drawXtermText cur(%d,%d) %s-%s, set_at %d\n",
9372d522f475Smrg	       screen->cur_row, screen->cur_col,
937320d2c4d2Smrg	       (filled ? "filled" : "outline"),
93740bd37d32Smrg	       (isCursorBlock(screen) ? "box" :
93750bd37d32Smrg		isCursorUnderline(screen) ? "underline" : "bar"),
937620d2c4d2Smrg	       set_at));
9377d522f475Smrg
9378d522f475Smrg	currentGC = getCgsGC(xw, currentWin, currentCgs);
937920d2c4d2Smrg	x = LineCursorX(screen, ld, cursor_col);
938020d2c4d2Smrg	y = CursorY(screen, screen->cur_row);
9381d522f475Smrg
93820bd37d32Smrg	if (!isCursorBlock(screen)) {
938320d2c4d2Smrg	    /*
9384a1f3da82Smrg	     * Overriding the combination of filled, reversed, in_selection is
93850bd37d32Smrg	     * too complicated since the underline or bar and the text-cell use
938620d2c4d2Smrg	     * different rules.  Just redraw the text-cell, and draw the
93870bd37d32Smrg	     * underline or bar on top of it.
938820d2c4d2Smrg	     */
938920d2c4d2Smrg	    HideCursor();
939020d2c4d2Smrg
939120d2c4d2Smrg	    /*
939220d2c4d2Smrg	     * Our current-GC is likely to have been modified in HideCursor().
9393a1f3da82Smrg	     * Set up a new request.
939420d2c4d2Smrg	     */
939520d2c4d2Smrg	    if (filled) {
939620d2c4d2Smrg		if (T_COLOR(screen, TEXT_CURSOR) == xw->dft_foreground) {
939720d2c4d2Smrg		    setCgsBack(xw, currentWin, currentCgs, fg_pix);
939820d2c4d2Smrg		}
939920d2c4d2Smrg		setCgsFore(xw, currentWin, currentCgs, bg_pix);
940020d2c4d2Smrg	    } else {
940120d2c4d2Smrg		setCgsFore(xw, currentWin, currentCgs, fg_pix);
940220d2c4d2Smrg		setCgsBack(xw, currentWin, currentCgs, bg_pix);
9403d522f475Smrg	    }
9404a1f3da82Smrg	}
9405a1f3da82Smrg
9406a1f3da82Smrg	/*
9407a1f3da82Smrg	 * Update the outline-gc, to keep the cursor color distinct from the
9408a1f3da82Smrg	 * background color.
9409a1f3da82Smrg	 */
9410a1f3da82Smrg	set_cursor_outline_gc(xw,
9411a1f3da82Smrg			      filled,
9412a1f3da82Smrg			      fg_pix,
9413a1f3da82Smrg			      bg_pix,
9414a1f3da82Smrg			      T_COLOR(screen, TEXT_CURSOR));
9415d522f475Smrg
9416a1f3da82Smrg	outlineGC = getCgsGC(xw, currentWin, gcVTcursOutline);
9417a1f3da82Smrg	if (outlineGC == 0)
9418a1f3da82Smrg	    outlineGC = currentGC;
9419a1f3da82Smrg
94200bd37d32Smrg	if (isCursorUnderline(screen)) {
9421d522f475Smrg
942220d2c4d2Smrg	    /*
942320d2c4d2Smrg	     * Finally, draw the underline.
942420d2c4d2Smrg	     */
94252eaa94a1Schristos	    screen->box->x = (short) x;
942620d2c4d2Smrg	    screen->box->y = (short) (y + FontHeight(screen) - 2);
94270bd37d32Smrg	    XDrawLines(screen->display, VDrawable(screen), outlineGC,
94280bd37d32Smrg		       screen->box, NBOX, CoordModePrevious);
94290bd37d32Smrg	} else if (isCursorBar(screen)) {
94300bd37d32Smrg
94310bd37d32Smrg	    /*
94320bd37d32Smrg	     * Or draw the bar.
94330bd37d32Smrg	     */
94340bd37d32Smrg	    screen->box->x = (short) x;
94350bd37d32Smrg	    screen->box->y = (short) y;
9436d522f475Smrg	    XDrawLines(screen->display, VWindow(screen), outlineGC,
9437d522f475Smrg		       screen->box, NBOX, CoordModePrevious);
943820d2c4d2Smrg	} else {
943920d2c4d2Smrg
944020d2c4d2Smrg	    drawXtermText(xw, flags & DRAWX_MASK,
944120d2c4d2Smrg			  currentGC, x, y,
944220d2c4d2Smrg			  LineCharSet(screen, ld),
944320d2c4d2Smrg			  &base, 1, 0);
944420d2c4d2Smrg
944520d2c4d2Smrg#if OPT_WIDE_CHARS
944620d2c4d2Smrg	    if_OPT_WIDE_CHARS(screen, {
944720d2c4d2Smrg		for_each_combData(off, ld) {
944820d2c4d2Smrg		    if (!(ld->combData[off][my_col]))
944920d2c4d2Smrg			break;
945020d2c4d2Smrg		    drawXtermText(xw, (flags & DRAWX_MASK) | NOBACKGROUND,
945120d2c4d2Smrg				  currentGC, x, y,
945220d2c4d2Smrg				  LineCharSet(screen, ld),
945320d2c4d2Smrg				  ld->combData[off] + my_col,
945420d2c4d2Smrg				  1, isWide((int) base));
945520d2c4d2Smrg		}
945620d2c4d2Smrg	    });
945720d2c4d2Smrg#endif
945820d2c4d2Smrg
945920d2c4d2Smrg	    if (!filled) {
946020d2c4d2Smrg		screen->box->x = (short) x;
946120d2c4d2Smrg		screen->box->y = (short) y;
94620bd37d32Smrg		XDrawLines(screen->display, VDrawable(screen), outlineGC,
946320d2c4d2Smrg			   screen->box, NBOX, CoordModePrevious);
946420d2c4d2Smrg	    }
9465d522f475Smrg	}
9466d522f475Smrg    }
9467d522f475Smrg    screen->cursor_state = ON;
9468956cc18dSsnj
9469956cc18dSsnj    return;
9470d522f475Smrg}
9471d522f475Smrg
9472d522f475Smrg/*
9473d522f475Smrg * hide cursor at previous cursor position in screen.
9474d522f475Smrg */
9475d522f475Smrgvoid
9476d522f475SmrgHideCursor(void)
9477d522f475Smrg{
9478d522f475Smrg    XtermWidget xw = term;
947920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
9480d522f475Smrg    GC currentGC;
9481d522f475Smrg    int x, y;
9482956cc18dSsnj    IChar base;
9483956cc18dSsnj    unsigned flags;
9484956cc18dSsnj    CellColor fg_bg = 0;
9485d522f475Smrg    Bool in_selection;
9486d522f475Smrg#if OPT_WIDE_CHARS
9487956cc18dSsnj    size_t off;
9488d522f475Smrg    int my_col = 0;
9489d522f475Smrg#endif
9490d522f475Smrg    int cursor_col;
9491956cc18dSsnj    LineData *ld = 0;
9492d522f475Smrg
949320d2c4d2Smrg    if (screen->cursor_state == OFF)
9494d522f475Smrg	return;
9495d522f475Smrg    if (INX2ROW(screen, screen->cursorp.row) > screen->max_row)
9496d522f475Smrg	return;
9497d522f475Smrg
9498d522f475Smrg    cursor_col = screen->cursorp.col;
9499d522f475Smrg
9500d522f475Smrg#ifndef NO_ACTIVE_ICON
9501d522f475Smrg    if (IsIcon(screen)) {
9502d522f475Smrg	screen->cursor_state = OFF;
9503d522f475Smrg	return;
9504d522f475Smrg    }
9505d522f475Smrg#endif /* NO_ACTIVE_ICON */
9506d522f475Smrg
9507956cc18dSsnj    ld = getLineData(screen, screen->cursorp.row);
9508956cc18dSsnj
9509956cc18dSsnj    base = ld->charData[cursor_col];
9510956cc18dSsnj    flags = ld->attribs[cursor_col];
9511d522f475Smrg
9512d522f475Smrg    if_OPT_WIDE_CHARS(screen, {
9513956cc18dSsnj	if (base == HIDDEN_CHAR && cursor_col > 0) {
9514d522f475Smrg	    /* if cursor points to non-initial part of wide character,
9515d522f475Smrg	     * back it up
9516d522f475Smrg	     */
9517d522f475Smrg	    --cursor_col;
9518956cc18dSsnj	    base = ld->charData[cursor_col];
9519d522f475Smrg	}
9520d522f475Smrg	my_col = cursor_col;
9521956cc18dSsnj	if (base == 0)
9522956cc18dSsnj	    base = ' ';
9523956cc18dSsnj	if (isWide((int) base))
9524d522f475Smrg	    my_col += 1;
9525d522f475Smrg    });
9526d522f475Smrg
9527956cc18dSsnj    if (base == 0) {
9528956cc18dSsnj	base = ' ';
9529956cc18dSsnj    }
9530956cc18dSsnj#ifdef EXP_BOGUS_FG
9531956cc18dSsnj    /*
9532956cc18dSsnj     * If the cursor happens to be on blanks, and we have not set both
9533956cc18dSsnj     * foreground and background color, do not treat it as a colored cell.
9534956cc18dSsnj     */
9535956cc18dSsnj#if OPT_ISO_COLORS
9536956cc18dSsnj    if (base == ' ') {
9537956cc18dSsnj	if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) {
9538956cc18dSsnj	    TRACE(("HideCursor - do not treat as a colored cell\n"));
9539956cc18dSsnj	    flags &= ~(FG_COLOR | BG_COLOR);
9540956cc18dSsnj	} else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) {
9541956cc18dSsnj	    TRACE(("HideCursor - should we treat as a colored cell?\n"));
9542956cc18dSsnj	    if (!(xw->flags & FG_COLOR))
9543956cc18dSsnj		if (CheckBogusForeground(screen, "HideCursor"))
9544956cc18dSsnj		    flags &= ~(FG_COLOR | BG_COLOR);
9545956cc18dSsnj	}
9546956cc18dSsnj    }
9547956cc18dSsnj#endif
9548956cc18dSsnj#endif
9549956cc18dSsnj#if OPT_ISO_COLORS
9550956cc18dSsnj    fg_bg = 0;
9551956cc18dSsnj#endif
9552956cc18dSsnj
9553956cc18dSsnj    /*
9554956cc18dSsnj     * Compare the current cell to the last set of colors used for the
9555956cc18dSsnj     * cursor and update the GC's if needed.
9556956cc18dSsnj     */
9557956cc18dSsnj    if_OPT_ISO_COLORS(screen, {
9558956cc18dSsnj	fg_bg = ld->color[cursor_col];
9559d522f475Smrg    });
9560d522f475Smrg
9561d522f475Smrg    if (OutsideSelection(screen, screen->cursorp.row, screen->cursorp.col))
9562d522f475Smrg	in_selection = False;
9563d522f475Smrg    else
9564d522f475Smrg	in_selection = True;
9565d522f475Smrg
9566d522f475Smrg    currentGC = updatedXtermGC(xw, flags, fg_bg, in_selection);
9567d522f475Smrg
9568d522f475Smrg    TRACE(("HideCursor calling drawXtermText cur(%d,%d)\n",
9569d522f475Smrg	   screen->cursorp.row, screen->cursorp.col));
957020d2c4d2Smrg
957120d2c4d2Smrg    x = LineCursorX(screen, ld, cursor_col);
957220d2c4d2Smrg    y = CursorY(screen, screen->cursorp.row);
957320d2c4d2Smrg
957420d2c4d2Smrg    drawXtermText(xw, flags & DRAWX_MASK,
957520d2c4d2Smrg		  currentGC, x, y,
9576956cc18dSsnj		  LineCharSet(screen, ld),
9577956cc18dSsnj		  &base, 1, 0);
9578d522f475Smrg
9579d522f475Smrg#if OPT_WIDE_CHARS
9580d522f475Smrg    if_OPT_WIDE_CHARS(screen, {
9581956cc18dSsnj	for_each_combData(off, ld) {
9582956cc18dSsnj	    if (!(ld->combData[off][my_col]))
9583d522f475Smrg		break;
9584d522f475Smrg	    drawXtermText(xw, (flags & DRAWX_MASK) | NOBACKGROUND,
9585d522f475Smrg			  currentGC, x, y,
9586956cc18dSsnj			  LineCharSet(screen, ld),
9587956cc18dSsnj			  ld->combData[off] + my_col,
9588956cc18dSsnj			  1, isWide((int) base));
9589d522f475Smrg	}
9590d522f475Smrg    });
9591d522f475Smrg#endif
9592d522f475Smrg    screen->cursor_state = OFF;
9593d522f475Smrg    resetXtermGC(xw, flags, in_selection);
9594956cc18dSsnj
9595956cc18dSsnj    return;
9596d522f475Smrg}
9597d522f475Smrg
9598d522f475Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
9599d522f475Smrgstatic void
9600d522f475SmrgStartBlinking(TScreen * screen)
9601d522f475Smrg{
9602d522f475Smrg    if (screen->blink_timer == 0) {
96032eaa94a1Schristos	unsigned long interval = (unsigned long) ((screen->cursor_state == ON)
96042eaa94a1Schristos						  ? screen->blink_on
96052eaa94a1Schristos						  : screen->blink_off);
9606d522f475Smrg	if (interval == 0)	/* wow! */
9607d522f475Smrg	    interval = 1;	/* let's humor him anyway */
9608d522f475Smrg	screen->blink_timer = XtAppAddTimeOut(app_con,
9609d522f475Smrg					      interval,
9610d522f475Smrg					      HandleBlinking,
9611d522f475Smrg					      screen);
9612d522f475Smrg    }
9613d522f475Smrg}
9614d522f475Smrg
9615d522f475Smrgstatic void
9616d522f475SmrgStopBlinking(TScreen * screen)
9617d522f475Smrg{
9618e39b573cSmrg    if (screen->blink_timer) {
9619d522f475Smrg	XtRemoveTimeOut(screen->blink_timer);
9620e39b573cSmrg	screen->blink_timer = 0;
9621e39b573cSmrg	reallyStopBlinking(screen);
9622e39b573cSmrg    } else {
9623e39b573cSmrg	screen->blink_timer = 0;
9624e39b573cSmrg    }
9625d522f475Smrg}
9626d522f475Smrg
9627d522f475Smrg#if OPT_BLINK_TEXT
96280bd37d32SmrgBool
9629956cc18dSsnjLineHasBlinking(TScreen * screen, LineData * ld)
9630d522f475Smrg{
9631d522f475Smrg    int col;
9632d522f475Smrg    Bool result = False;
9633d522f475Smrg
9634d522f475Smrg    for (col = 0; col < MaxCols(screen); ++col) {
9635956cc18dSsnj	if (ld->attribs[col] & BLINK) {
9636d522f475Smrg	    result = True;
9637d522f475Smrg	    break;
9638d522f475Smrg	}
9639d522f475Smrg    }
9640d522f475Smrg    return result;
9641d522f475Smrg}
9642d522f475Smrg#endif
9643d522f475Smrg
9644d522f475Smrg/*
9645d522f475Smrg * Blink the cursor by alternately showing/hiding cursor.  We leave the timer
9646d522f475Smrg * running all the time (even though that's a little inefficient) to make the
9647d522f475Smrg * logic simple.
9648d522f475Smrg */
9649d522f475Smrgstatic void
9650d522f475SmrgHandleBlinking(XtPointer closure, XtIntervalId * id GCC_UNUSED)
9651d522f475Smrg{
9652d522f475Smrg    TScreen *screen = (TScreen *) closure;
9653d522f475Smrg    Bool resume = False;
9654d522f475Smrg
9655d522f475Smrg    screen->blink_timer = 0;
9656d522f475Smrg    screen->blink_state = !screen->blink_state;
9657d522f475Smrg
9658d522f475Smrg#if OPT_BLINK_CURS
9659d522f475Smrg    if (DoStartBlinking(screen)) {
9660d522f475Smrg	if (screen->cursor_state == ON) {
9661d522f475Smrg	    if (screen->select || screen->always_highlight) {
9662d522f475Smrg		HideCursor();
9663d522f475Smrg		if (screen->cursor_state == OFF)
9664d522f475Smrg		    screen->cursor_state = BLINKED_OFF;
9665d522f475Smrg	    }
9666d522f475Smrg	} else if (screen->cursor_state == BLINKED_OFF) {
9667d522f475Smrg	    screen->cursor_state = OFF;
9668d522f475Smrg	    ShowCursor();
9669d522f475Smrg	    if (screen->cursor_state == OFF)
9670d522f475Smrg		screen->cursor_state = BLINKED_OFF;
9671d522f475Smrg	}
9672d522f475Smrg	resume = True;
9673d522f475Smrg    }
9674d522f475Smrg#endif
9675d522f475Smrg
9676d522f475Smrg#if OPT_BLINK_TEXT
9677d522f475Smrg    /*
967820d2c4d2Smrg     * Inspect the lines on the current screen to see if any have the BLINK flag
9679d522f475Smrg     * associated with them.  Prune off any that have had the corresponding
9680d522f475Smrg     * cells reset.  If any are left, repaint those lines with ScrnRefresh().
9681d522f475Smrg     */
9682d522f475Smrg    if (!(screen->blink_as_bold)) {
9683d522f475Smrg	int row;
9684d522f475Smrg	int first_row = screen->max_row;
9685d522f475Smrg	int last_row = -1;
9686d522f475Smrg
9687d522f475Smrg	for (row = screen->max_row; row >= 0; row--) {
9688956cc18dSsnj	    LineData *ld = getLineData(screen, ROW2INX(screen, row));
968920d2c4d2Smrg
969020d2c4d2Smrg	    if (ld != 0 && LineTstBlinked(ld)) {
9691956cc18dSsnj		if (LineHasBlinking(screen, ld)) {
9692d522f475Smrg		    resume = True;
9693d522f475Smrg		    if (row > last_row)
9694d522f475Smrg			last_row = row;
9695d522f475Smrg		    if (row < first_row)
9696d522f475Smrg			first_row = row;
9697d522f475Smrg		} else {
9698956cc18dSsnj		    LineClrBlinked(ld);
9699d522f475Smrg		}
9700d522f475Smrg	    }
9701d522f475Smrg	}
9702d522f475Smrg	/*
9703d522f475Smrg	 * FIXME: this could be a little more efficient, e.g,. by limiting the
9704d522f475Smrg	 * columns which are updated.
9705d522f475Smrg	 */
9706d522f475Smrg	if (first_row <= last_row) {
9707d522f475Smrg	    ScrnRefresh(term,
9708d522f475Smrg			first_row,
9709d522f475Smrg			0,
9710d522f475Smrg			last_row + 1 - first_row,
9711d522f475Smrg			MaxCols(screen),
9712d522f475Smrg			True);
9713d522f475Smrg	}
9714d522f475Smrg    }
9715d522f475Smrg#endif
9716d522f475Smrg
9717d522f475Smrg    /*
9718d522f475Smrg     * If either the cursor or text is blinking, restart the timer.
9719d522f475Smrg     */
9720d522f475Smrg    if (resume)
9721d522f475Smrg	StartBlinking(screen);
9722d522f475Smrg}
9723d522f475Smrg#endif /* OPT_BLINK_CURS || OPT_BLINK_TEXT */
9724d522f475Smrg
972520d2c4d2Smrgvoid
972620d2c4d2SmrgRestartBlinking(TScreen * screen GCC_UNUSED)
972720d2c4d2Smrg{
972820d2c4d2Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
972920d2c4d2Smrg    if (screen->blink_timer == 0) {
973020d2c4d2Smrg	Bool resume = False;
973120d2c4d2Smrg
973220d2c4d2Smrg#if OPT_BLINK_CURS
973320d2c4d2Smrg	if (DoStartBlinking(screen)) {
973420d2c4d2Smrg	    resume = True;
973520d2c4d2Smrg	}
973620d2c4d2Smrg#endif
973720d2c4d2Smrg#if OPT_BLINK_TEXT
973820d2c4d2Smrg	if (!resume) {
973920d2c4d2Smrg	    int row;
974020d2c4d2Smrg
974120d2c4d2Smrg	    for (row = screen->max_row; row >= 0; row--) {
974220d2c4d2Smrg		LineData *ld = getLineData(screen, ROW2INX(screen, row));
974320d2c4d2Smrg
974420d2c4d2Smrg		if (ld != 0 && LineTstBlinked(ld)) {
974520d2c4d2Smrg		    if (LineHasBlinking(screen, ld)) {
974620d2c4d2Smrg			resume = True;
974720d2c4d2Smrg			break;
974820d2c4d2Smrg		    }
974920d2c4d2Smrg		}
975020d2c4d2Smrg	    }
975120d2c4d2Smrg	}
975220d2c4d2Smrg#endif
975320d2c4d2Smrg	if (resume)
975420d2c4d2Smrg	    StartBlinking(screen);
975520d2c4d2Smrg    }
975620d2c4d2Smrg#endif
975720d2c4d2Smrg}
975820d2c4d2Smrg
9759d522f475Smrg/*
9760d522f475Smrg * Implement soft or hard (full) reset of the VTxxx emulation.  There are a
9761d522f475Smrg * couple of differences from real DEC VTxxx terminals (to avoid breaking
9762d522f475Smrg * applications which have come to rely on xterm doing this):
9763d522f475Smrg *
9764d522f475Smrg *	+ autowrap mode should be reset (instead it's reset to the resource
9765d522f475Smrg *	  default).
9766d522f475Smrg *	+ the popup menu offers a choice of resetting the savedLines, or not.
9767d522f475Smrg *	  (but the control sequence does this anyway).
9768d522f475Smrg */
9769e39b573cSmrgstatic void
9770e39b573cSmrgReallyReset(XtermWidget xw, Bool full, Bool saved)
9771d522f475Smrg{
977220d2c4d2Smrg    static char empty[1];
977320d2c4d2Smrg
977420d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
9775d522f475Smrg
9776d522f475Smrg    if (!XtIsRealized((Widget) xw) || (CURRENT_EMU() != (Widget) xw)) {
977720d2c4d2Smrg	Bell(xw, XkbBI_MinorError, 0);
9778d522f475Smrg	return;
9779d522f475Smrg    }
9780d522f475Smrg
9781d522f475Smrg    if (saved) {
9782d522f475Smrg	screen->savedlines = 0;
9783d522f475Smrg	ScrollBarDrawThumb(screen->scrollWidget);
9784d522f475Smrg    }
9785d522f475Smrg
9786d522f475Smrg    /* make cursor visible */
9787d522f475Smrg    screen->cursor_set = ON;
9788d522f475Smrg
9789d522f475Smrg    /* reset scrolling region */
97900bd37d32Smrg    reset_margins(screen);
9791d522f475Smrg
9792d522f475Smrg    bitclr(&xw->flags, ORIGIN);
9793d522f475Smrg
9794d522f475Smrg    if_OPT_ISO_COLORS(screen, {
9795d522f475Smrg	reset_SGR_Colors(xw);
979620d2c4d2Smrg	if (ResetAnsiColorRequest(xw, empty, 0))
979720d2c4d2Smrg	    xtermRepaint(xw);
9798d522f475Smrg    });
9799d522f475Smrg
9800d522f475Smrg    /* Reset character-sets to initial state */
9801d522f475Smrg    resetCharsets(screen);
9802d522f475Smrg
9803d522f475Smrg#if OPT_MOD_FKEYS
9804d522f475Smrg    /* Reset modifier-resources to initial state */
9805d522f475Smrg    xw->keyboard.modify_now = xw->keyboard.modify_1st;
9806d522f475Smrg#endif
9807d522f475Smrg
9808d522f475Smrg    /* Reset DECSCA */
9809d522f475Smrg    bitclr(&xw->flags, PROTECTED);
9810d522f475Smrg    screen->protected_mode = OFF_PROTECT;
9811d522f475Smrg
9812d522f475Smrg    if (full) {			/* RIS */
9813d522f475Smrg	if (screen->bellOnReset)
981420d2c4d2Smrg	    Bell(xw, XkbBI_TerminalBell, 0);
9815d522f475Smrg
9816d522f475Smrg	/* reset the mouse mode */
9817d522f475Smrg	screen->send_mouse_pos = MOUSE_OFF;
9818d522f475Smrg	screen->send_focus_pos = OFF;
98190bd37d32Smrg	screen->extend_coords = 0;
9820d522f475Smrg	screen->waitingForTrackInfo = False;
9821d522f475Smrg	screen->eventMode = NORMAL;
9822d522f475Smrg
9823d522f475Smrg	xtermShowPointer(xw, True);
9824d522f475Smrg
9825d522f475Smrg	TabReset(xw->tabs);
9826d522f475Smrg	xw->keyboard.flags = MODE_SRM;
9827d522f475Smrg#if OPT_INITIAL_ERASE
9828d522f475Smrg	if (xw->keyboard.reset_DECBKM == 1)
9829d522f475Smrg	    xw->keyboard.flags |= MODE_DECBKM;
9830d522f475Smrg	else if (xw->keyboard.reset_DECBKM == 2)
9831d522f475Smrg#endif
983220d2c4d2Smrg	    if (TScreenOf(xw)->backarrow_key)
9833d522f475Smrg		xw->keyboard.flags |= MODE_DECBKM;
9834d522f475Smrg	TRACE(("full reset DECBKM %s\n",
9835d522f475Smrg	       BtoS(xw->keyboard.flags & MODE_DECBKM)));
9836d522f475Smrg	update_appcursor();
9837d522f475Smrg	update_appkeypad();
9838d522f475Smrg	update_decbkm();
9839d522f475Smrg	show_8bit_control(False);
9840d522f475Smrg	reset_decudk();
9841d522f475Smrg
9842d522f475Smrg	FromAlternate(xw);
9843d522f475Smrg	ClearScreen(xw);
9844d522f475Smrg	screen->cursor_state = OFF;
9845d522f475Smrg	if (xw->flags & REVERSE_VIDEO)
9846d522f475Smrg	    ReverseVideo(xw);
9847d522f475Smrg
9848d522f475Smrg	xw->flags = xw->initflags;
9849d522f475Smrg	update_reversevideo();
9850d522f475Smrg	update_autowrap();
9851d522f475Smrg	update_reversewrap();
9852d522f475Smrg	update_autolinefeed();
9853d522f475Smrg
98542eaa94a1Schristos	screen->jumpscroll = (Boolean) (!(xw->flags & SMOOTHSCROLL));
9855d522f475Smrg	update_jumpscroll();
9856d522f475Smrg
9857d522f475Smrg	if (screen->c132 && (xw->flags & IN132COLUMNS)) {
98582eaa94a1Schristos	    Dimension reqWidth = (Dimension) (80 * FontWidth(screen)
98592eaa94a1Schristos					      + 2 * screen->border
98602eaa94a1Schristos					      + ScrollbarWidth(screen));
98612eaa94a1Schristos	    Dimension reqHeight = (Dimension) (FontHeight(screen)
98622eaa94a1Schristos					       * MaxRows(screen)
98632eaa94a1Schristos					       + 2 * screen->border);
9864d522f475Smrg	    Dimension replyWidth;
9865d522f475Smrg	    Dimension replyHeight;
9866d522f475Smrg
9867d522f475Smrg	    TRACE(("Making resize-request to restore 80-columns %dx%d\n",
9868d522f475Smrg		   reqHeight, reqWidth));
98692eaa94a1Schristos	    REQ_RESIZE((Widget) xw,
98702eaa94a1Schristos		       reqWidth,
98712eaa94a1Schristos		       reqHeight,
98722eaa94a1Schristos		       &replyWidth, &replyHeight);
9873d522f475Smrg	    repairSizeHints();
9874d522f475Smrg	    XSync(screen->display, False);	/* synchronize */
98750bd37d32Smrg	    if (xtermAppPending())
9876d522f475Smrg		xevents();
9877d522f475Smrg	}
9878d522f475Smrg
9879d522f475Smrg	CursorSet(screen, 0, 0, xw->flags);
9880d522f475Smrg	CursorSave(xw);
9881d522f475Smrg    } else {			/* DECSTR */
9882d522f475Smrg	/*
9883d522f475Smrg	 * There's a tiny difference, to accommodate usage of xterm.
9884d522f475Smrg	 * We reset autowrap to the resource values rather than turning
9885d522f475Smrg	 * it off.
9886d522f475Smrg	 */
988720d2c4d2Smrg	UIntClr(xw->keyboard.flags, (MODE_DECCKM | MODE_KAM | MODE_DECKPAM));
9888d522f475Smrg	bitcpy(&xw->flags, xw->initflags, WRAPAROUND | REVERSEWRAP);
9889d522f475Smrg	bitclr(&xw->flags, INSERT | INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE);
9890d522f475Smrg	if_OPT_ISO_COLORS(screen, {
9891d522f475Smrg	    reset_SGR_Colors(xw);
9892d522f475Smrg	});
9893d522f475Smrg	update_appcursor();
9894d522f475Smrg	update_autowrap();
9895d522f475Smrg	update_reversewrap();
9896d522f475Smrg
9897d522f475Smrg	CursorSave(xw);
9898956cc18dSsnj	screen->sc[screen->whichBuf].row =
9899956cc18dSsnj	    screen->sc[screen->whichBuf].col = 0;
9900d522f475Smrg    }
9901e39b573cSmrg}
9902e39b573cSmrg
9903e39b573cSmrgvoid
9904e39b573cSmrgVTReset(XtermWidget xw, Bool full, Bool saved)
9905e39b573cSmrg{
9906e39b573cSmrg    ReallyReset(xw, full, saved);
9907d522f475Smrg    longjmp(vtjmpbuf, 1);	/* force ground state in parser */
9908d522f475Smrg}
9909d522f475Smrg
9910d522f475Smrg/*
9911d522f475Smrg * set_character_class - takes a string of the form
9912d522f475Smrg *
9913d522f475Smrg *   low[-high]:val[,low[-high]:val[...]]
9914d522f475Smrg *
9915d522f475Smrg * and sets the indicated ranges to the indicated values.
9916d522f475Smrg */
9917d522f475Smrgstatic int
9918d522f475Smrgset_character_class(char *s)
9919d522f475Smrg{
99200bd37d32Smrg#define FMT "%s in range string \"%s\" (position %d)\n"
9921d522f475Smrg    int i;			/* iterator, index into s */
9922d522f475Smrg    int len;			/* length of s */
9923d522f475Smrg    int acc;			/* accumulator */
9924d522f475Smrg    int low, high;		/* bounds of range [0..127] */
9925d522f475Smrg    int base;			/* 8, 10, 16 (octal, decimal, hex) */
9926d522f475Smrg    int numbers;		/* count of numbers per range */
9927d522f475Smrg    int digits;			/* count of digits in a number */
9928d522f475Smrg
9929d522f475Smrg    if (!s || !s[0])
9930d522f475Smrg	return -1;
9931d522f475Smrg
9932d522f475Smrg    base = 10;			/* in case we ever add octal, hex */
9933d522f475Smrg    low = high = -1;		/* out of range */
9934d522f475Smrg
99352eaa94a1Schristos    for (i = 0, len = (int) strlen(s), acc = 0, numbers = digits = 0;
9936d522f475Smrg	 i < len; i++) {
99372eaa94a1Schristos	Char c = CharOf(s[i]);
9938d522f475Smrg
9939d522f475Smrg	if (isspace(c)) {
9940d522f475Smrg	    continue;
9941d522f475Smrg	} else if (isdigit(c)) {
9942d522f475Smrg	    acc = acc * base + (c - '0');
9943d522f475Smrg	    digits++;
9944d522f475Smrg	    continue;
9945d522f475Smrg	} else if (c == '-') {
9946d522f475Smrg	    low = acc;
9947d522f475Smrg	    acc = 0;
9948d522f475Smrg	    if (digits == 0) {
99490bd37d32Smrg		xtermWarning(FMT, "missing number", s, i);
9950d522f475Smrg		return (-1);
9951d522f475Smrg	    }
9952d522f475Smrg	    digits = 0;
9953d522f475Smrg	    numbers++;
9954d522f475Smrg	    continue;
9955d522f475Smrg	} else if (c == ':') {
9956d522f475Smrg	    if (numbers == 0)
9957d522f475Smrg		low = acc;
9958d522f475Smrg	    else if (numbers == 1)
9959d522f475Smrg		high = acc;
9960d522f475Smrg	    else {
99610bd37d32Smrg		xtermWarning(FMT, "too many numbers", s, i);
9962d522f475Smrg		return (-1);
9963d522f475Smrg	    }
9964d522f475Smrg	    digits = 0;
9965d522f475Smrg	    numbers++;
9966d522f475Smrg	    acc = 0;
9967d522f475Smrg	    continue;
9968d522f475Smrg	} else if (c == ',') {
9969d522f475Smrg	    /*
9970d522f475Smrg	     * now, process it
9971d522f475Smrg	     */
9972d522f475Smrg
9973d522f475Smrg	    if (high < 0) {
9974d522f475Smrg		high = low;
9975d522f475Smrg		numbers++;
9976d522f475Smrg	    }
9977d522f475Smrg	    if (numbers != 2) {
99780bd37d32Smrg		xtermWarning(FMT, "bad value number", s, i);
9979d522f475Smrg	    } else if (SetCharacterClassRange(low, high, acc) != 0) {
99800bd37d32Smrg		xtermWarning(FMT, "bad range", s, i);
9981d522f475Smrg	    }
9982d522f475Smrg
9983d522f475Smrg	    low = high = -1;
9984d522f475Smrg	    acc = 0;
9985d522f475Smrg	    digits = 0;
9986d522f475Smrg	    numbers = 0;
9987d522f475Smrg	    continue;
9988d522f475Smrg	} else {
99890bd37d32Smrg	    xtermWarning(FMT, "bad character", s, i);
9990d522f475Smrg	    return (-1);
9991d522f475Smrg	}			/* end if else if ... else */
9992d522f475Smrg
9993d522f475Smrg    }
9994d522f475Smrg
9995d522f475Smrg    if (low < 0 && high < 0)
9996d522f475Smrg	return (0);
9997d522f475Smrg
9998d522f475Smrg    /*
9999d522f475Smrg     * now, process it
10000d522f475Smrg     */
10001d522f475Smrg
10002d522f475Smrg    if (high < 0)
10003d522f475Smrg	high = low;
10004d522f475Smrg    if (numbers < 1 || numbers > 2) {
100050bd37d32Smrg	xtermWarning(FMT, "bad value number", s, i);
10006d522f475Smrg    } else if (SetCharacterClassRange(low, high, acc) != 0) {
100070bd37d32Smrg	xtermWarning(FMT, "bad range", s, i);
10008d522f475Smrg    }
10009d522f475Smrg
10010d522f475Smrg    return (0);
100110bd37d32Smrg#undef FMT
10012d522f475Smrg}
10013d522f475Smrg
10014d522f475Smrg/* ARGSUSED */
10015d522f475Smrgstatic void
10016d522f475SmrgHandleKeymapChange(Widget w,
10017d522f475Smrg		   XEvent * event GCC_UNUSED,
10018d522f475Smrg		   String * params,
10019d522f475Smrg		   Cardinal *param_count)
10020d522f475Smrg{
10021d522f475Smrg    static XtTranslations keymap, original;
10022d522f475Smrg    static XtResource key_resources[] =
10023d522f475Smrg    {
10024d522f475Smrg	{XtNtranslations, XtCTranslations, XtRTranslationTable,
10025d522f475Smrg	 sizeof(XtTranslations), 0, XtRTranslationTable, (XtPointer) NULL}
10026d522f475Smrg    };
10027d522f475Smrg    char mapName[1000];
10028d522f475Smrg    char mapClass[1000];
10029d522f475Smrg    char *pmapName;
10030d522f475Smrg    char *pmapClass;
10031d522f475Smrg    size_t len;
10032d522f475Smrg
10033d522f475Smrg    if (*param_count != 1)
10034d522f475Smrg	return;
10035d522f475Smrg
10036d522f475Smrg    if (original == NULL)
10037d522f475Smrg	original = w->core.tm.translations;
10038d522f475Smrg
10039d522f475Smrg    if (strcmp(params[0], "None") == 0) {
10040d522f475Smrg	XtOverrideTranslations(w, original);
10041d522f475Smrg	return;
10042d522f475Smrg    }
10043d522f475Smrg
10044d522f475Smrg    len = strlen(params[0]) + 7;
10045d522f475Smrg
10046d522f475Smrg    pmapName = (char *) MyStackAlloc(len, mapName);
10047d522f475Smrg    pmapClass = (char *) MyStackAlloc(len, mapClass);
10048d522f475Smrg    if (pmapName == NULL
1004920d2c4d2Smrg	|| pmapClass == NULL) {
10050d522f475Smrg	SysError(ERROR_KMMALLOC1);
1005120d2c4d2Smrg    } else {
1005220d2c4d2Smrg
1005320d2c4d2Smrg	(void) sprintf(pmapName, "%sKeymap", params[0]);
1005420d2c4d2Smrg	(void) strcpy(pmapClass, pmapName);
1005520d2c4d2Smrg	if (islower(CharOf(pmapClass[0])))
1005620d2c4d2Smrg	    pmapClass[0] = x_toupper(pmapClass[0]);
1005720d2c4d2Smrg	XtGetSubresources(w, (XtPointer) &keymap, pmapName, pmapClass,
1005820d2c4d2Smrg			  key_resources, (Cardinal) 1, NULL, (Cardinal) 0);
1005920d2c4d2Smrg	if (keymap != NULL)
1006020d2c4d2Smrg	    XtOverrideTranslations(w, keymap);
10061d522f475Smrg
1006220d2c4d2Smrg	MyStackFree(pmapName, mapName);
1006320d2c4d2Smrg	MyStackFree(pmapClass, mapClass);
1006420d2c4d2Smrg    }
10065d522f475Smrg}
10066d522f475Smrg
10067d522f475Smrg/* ARGSUSED */
10068d522f475Smrgstatic void
10069d522f475SmrgHandleBell(Widget w GCC_UNUSED,
10070d522f475Smrg	   XEvent * event GCC_UNUSED,
10071d522f475Smrg	   String * params,	/* [0] = volume */
10072d522f475Smrg	   Cardinal *param_count)	/* 0 or 1 */
10073d522f475Smrg{
10074d522f475Smrg    int percent = (*param_count) ? atoi(params[0]) : 0;
10075d522f475Smrg
1007620d2c4d2Smrg    Bell(term, XkbBI_TerminalBell, percent);
10077d522f475Smrg}
10078d522f475Smrg
10079d522f475Smrg/* ARGSUSED */
10080d522f475Smrgstatic void
10081d522f475SmrgHandleVisualBell(Widget w GCC_UNUSED,
10082d522f475Smrg		 XEvent * event GCC_UNUSED,
10083d522f475Smrg		 String * params GCC_UNUSED,
10084d522f475Smrg		 Cardinal *param_count GCC_UNUSED)
10085d522f475Smrg{
10086d522f475Smrg    VisualBell();
10087d522f475Smrg}
10088d522f475Smrg
10089d522f475Smrg/* ARGSUSED */
10090d522f475Smrgstatic void
10091d522f475SmrgHandleIgnore(Widget w,
10092d522f475Smrg	     XEvent * event,
10093d522f475Smrg	     String * params GCC_UNUSED,
10094d522f475Smrg	     Cardinal *param_count GCC_UNUSED)
10095d522f475Smrg{
10096956cc18dSsnj    XtermWidget xw;
10097956cc18dSsnj
100980bd37d32Smrg    TRACE(("Handle ignore for %p %s\n",
100990bd37d32Smrg	   (void *) w, visibleEventType(event->type)));
10100956cc18dSsnj    if ((xw = getXtermWidget(w)) != 0) {
10101d522f475Smrg	/* do nothing, but check for funny escape sequences */
10102956cc18dSsnj	(void) SendMousePosition(xw, event);
10103d522f475Smrg    }
10104d522f475Smrg}
10105d522f475Smrg
10106d522f475Smrg/* ARGSUSED */
10107d522f475Smrgstatic void
10108d522f475SmrgDoSetSelectedFont(Widget w,
10109d522f475Smrg		  XtPointer client_data GCC_UNUSED,
10110d522f475Smrg		  Atom * selection GCC_UNUSED,
10111d522f475Smrg		  Atom * type,
10112d522f475Smrg		  XtPointer value,
10113d522f475Smrg		  unsigned long *length,
10114d522f475Smrg		  int *format)
10115d522f475Smrg{
10116956cc18dSsnj    XtermWidget xw = getXtermWidget(w);
10117956cc18dSsnj
101180bd37d32Smrg    if (xw == 0) {
101190bd37d32Smrg	xtermWarning("unexpected widget in DoSetSelectedFont\n");
101200bd37d32Smrg    } else if (*type != XA_STRING || *format != 8) {
1012120d2c4d2Smrg	Bell(xw, XkbBI_MinorError, 0);
10122d522f475Smrg    } else {
10123d522f475Smrg	Boolean failed = False;
1012420d2c4d2Smrg	int oldFont = TScreenOf(xw)->menu_font_number;
1012520d2c4d2Smrg	String save = TScreenOf(xw)->MenuFontName(fontMenu_fontsel);
10126d522f475Smrg	char *val;
10127d522f475Smrg	char *test = 0;
10128d522f475Smrg	char *used = 0;
1012920d2c4d2Smrg	unsigned len = (unsigned) *length;
10130d522f475Smrg	unsigned tst;
10131d522f475Smrg
10132d522f475Smrg	/*
10133d522f475Smrg	 * Some versions of X deliver null-terminated selections, some do not.
10134d522f475Smrg	 */
10135d522f475Smrg	for (tst = 0; tst < len; ++tst) {
10136d522f475Smrg	    if (((char *) value)[tst] == '\0') {
10137d522f475Smrg		len = tst;
10138d522f475Smrg		break;
10139d522f475Smrg	    }
10140d522f475Smrg	}
10141d522f475Smrg
10142d522f475Smrg	if (len > 0 && (val = TypeMallocN(char, len + 1)) != 0) {
1014320d2c4d2Smrg	    memcpy(val, value, (size_t) len);
10144d522f475Smrg	    val[len] = '\0';
10145d522f475Smrg	    used = x_strtrim(val);
101466879286fSmrg	    TRACE(("DoSetSelectedFont(%s)\n", used));
10147d522f475Smrg	    /* Do some sanity checking to avoid sending a long selection
10148d522f475Smrg	       back to the server in an OpenFont that is unlikely to succeed.
10149d522f475Smrg	       XLFD allows up to 255 characters and no control characters;
10150d522f475Smrg	       we are a little more liberal here. */
10151d522f475Smrg	    if (len < 1000
101520bd37d32Smrg		&& used != 0
101536879286fSmrg		&& !strchr(used, '\n')
101546879286fSmrg		&& (test = x_strdup(used)) != 0) {
1015520d2c4d2Smrg		TScreenOf(xw)->MenuFontName(fontMenu_fontsel) = test;
10156d522f475Smrg		if (!xtermLoadFont(term,
101576879286fSmrg				   xtermFontName(used),
10158d522f475Smrg				   True,
10159d522f475Smrg				   fontMenu_fontsel)) {
10160d522f475Smrg		    failed = True;
10161d522f475Smrg		    free(test);
1016220d2c4d2Smrg		    TScreenOf(xw)->MenuFontName(fontMenu_fontsel) = save;
10163d522f475Smrg		}
10164d522f475Smrg	    } else {
10165d522f475Smrg		failed = True;
10166d522f475Smrg	    }
10167d522f475Smrg	    if (failed) {
10168d522f475Smrg		(void) xtermLoadFont(term,
1016920d2c4d2Smrg				     xtermFontName(TScreenOf(xw)->MenuFontName(oldFont)),
10170d522f475Smrg				     True,
10171d522f475Smrg				     oldFont);
1017220d2c4d2Smrg		Bell(xw, XkbBI_MinorError, 0);
10173d522f475Smrg	    }
101746879286fSmrg	    free(used);
10175d522f475Smrg	    free(val);
10176d522f475Smrg	}
10177d522f475Smrg    }
10178d522f475Smrg}
10179d522f475Smrg
10180d522f475Smrgvoid
10181d522f475SmrgFindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe)
10182d522f475Smrg{
1018320d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
10184d522f475Smrg    static AtomPtr *atoms;
101850bd37d32Smrg    static unsigned int atomCount = 0;
10186d522f475Smrg    AtomPtr *pAtom;
101872eaa94a1Schristos    unsigned a;
10188d522f475Smrg    Atom target;
10189d522f475Smrg
10190d522f475Smrg    if (!atom_name)
10191956cc18dSsnj	atom_name = (screen->mappedSelect
10192956cc18dSsnj		     ? screen->mappedSelect[0]
10193d522f475Smrg		     : "PRIMARY");
10194d522f475Smrg    TRACE(("FindFontSelection(%s)\n", atom_name));
10195d522f475Smrg
10196d522f475Smrg    for (pAtom = atoms, a = atomCount; a; a--, pAtom++) {
101970bd37d32Smrg	if (strcmp(atom_name, XmuNameOfAtom(*pAtom)) == 0) {
101980bd37d32Smrg	    TRACE(("...found atom %d:%s\n", a + 1, atom_name));
10199d522f475Smrg	    break;
102000bd37d32Smrg	}
10201d522f475Smrg    }
10202d522f475Smrg    if (!a) {
10203a1f3da82Smrg	atoms = TypeXtReallocN(AtomPtr, atoms, atomCount + 1);
1020420d2c4d2Smrg	*(pAtom = &atoms[atomCount]) = XmuMakeAtom(atom_name);
102050bd37d32Smrg	++atomCount;
102060bd37d32Smrg	TRACE(("...added atom %d:%s\n", atomCount, atom_name));
10207d522f475Smrg    }
10208d522f475Smrg
10209d522f475Smrg    target = XmuInternAtom(XtDisplay(xw), *pAtom);
10210d522f475Smrg    if (justprobe) {
10211956cc18dSsnj	screen->MenuFontName(fontMenu_fontsel) =
10212d522f475Smrg	    XGetSelectionOwner(XtDisplay(xw), target) ? _Font_Selected_ : 0;
10213956cc18dSsnj	TRACE(("...selected fontname '%s'\n",
10214956cc18dSsnj	       NonNull(screen->MenuFontName(fontMenu_fontsel))));
10215d522f475Smrg    } else {
10216d522f475Smrg	XtGetSelectionValue((Widget) xw, target, XA_STRING,
10217d522f475Smrg			    DoSetSelectedFont, NULL,
10218d522f475Smrg			    XtLastTimestampProcessed(XtDisplay(xw)));
10219d522f475Smrg    }
10220d522f475Smrg    return;
10221d522f475Smrg}
10222d522f475Smrg
10223492d43a5SmrgBool
10224d522f475Smrgset_cursor_gcs(XtermWidget xw)
10225d522f475Smrg{
1022620d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
10227d522f475Smrg    VTwin *win = WhichVWin(screen);
10228d522f475Smrg
10229d522f475Smrg    Pixel cc = T_COLOR(screen, TEXT_CURSOR);
10230d522f475Smrg    Pixel fg = T_COLOR(screen, TEXT_FG);
10231d522f475Smrg    Pixel bg = T_COLOR(screen, TEXT_BG);
10232492d43a5Smrg    Bool changed = False;
10233d522f475Smrg
10234d522f475Smrg    /*
10235d522f475Smrg     * Let's see, there are three things that have "color":
10236d522f475Smrg     *
10237d522f475Smrg     *     background
10238d522f475Smrg     *     text
10239d522f475Smrg     *     cursorblock
10240d522f475Smrg     *
10241d522f475Smrg     * And, there are four situations when drawing a cursor, if we decide
10242d522f475Smrg     * that we like have a solid block of cursor color with the letter
10243d522f475Smrg     * that it is highlighting shown in the background color to make it
10244d522f475Smrg     * stand out:
10245d522f475Smrg     *
10246d522f475Smrg     *     selected window, normal video - background on cursor
10247d522f475Smrg     *     selected window, reverse video - foreground on cursor
10248d522f475Smrg     *     unselected window, normal video - foreground on background
10249d522f475Smrg     *     unselected window, reverse video - background on foreground
10250d522f475Smrg     *
10251d522f475Smrg     * Since the last two are really just normalGC and reverseGC, we only
10252d522f475Smrg     * need two new GC's.  Under monochrome, we get the same effect as
10253d522f475Smrg     * above by setting cursor color to foreground.
10254d522f475Smrg     */
10255d522f475Smrg
10256d522f475Smrg    TRACE(("set_cursor_gcs cc=%#lx, fg=%#lx, bg=%#lx\n", cc, fg, bg));
10257d522f475Smrg    if (win != 0 && (cc != bg)) {
10258d522f475Smrg	/* set the fonts to the current one */
10259d522f475Smrg	setCgsFont(xw, win, gcVTcursNormal, 0);
10260d522f475Smrg	setCgsFont(xw, win, gcVTcursFilled, 0);
10261d522f475Smrg	setCgsFont(xw, win, gcVTcursReverse, 0);
10262d522f475Smrg	setCgsFont(xw, win, gcVTcursOutline, 0);
10263d522f475Smrg
10264d522f475Smrg	/* we have a colored cursor */
10265d522f475Smrg	setCgsFore(xw, win, gcVTcursNormal, fg);
10266d522f475Smrg	setCgsBack(xw, win, gcVTcursNormal, cc);
10267d522f475Smrg
10268d522f475Smrg	setCgsFore(xw, win, gcVTcursFilled, cc);
10269d522f475Smrg	setCgsBack(xw, win, gcVTcursFilled, fg);
10270d522f475Smrg
10271d522f475Smrg	if (screen->always_highlight) {
10272d522f475Smrg	    /* both GC's use the same color */
10273d522f475Smrg	    setCgsFore(xw, win, gcVTcursReverse, bg);
10274d522f475Smrg	    setCgsBack(xw, win, gcVTcursReverse, cc);
10275d522f475Smrg	} else {
10276d522f475Smrg	    setCgsFore(xw, win, gcVTcursReverse, bg);
10277d522f475Smrg	    setCgsBack(xw, win, gcVTcursReverse, cc);
10278d522f475Smrg	}
10279a1f3da82Smrg	set_cursor_outline_gc(xw, screen->always_highlight, fg, bg, cc);
10280d522f475Smrg	changed = True;
10281d522f475Smrg    }
10282d522f475Smrg
10283d522f475Smrg    if (changed) {
10284d522f475Smrg	TRACE(("...set_cursor_gcs - done\n"));
10285d522f475Smrg    }
10286492d43a5Smrg    return changed;
10287d522f475Smrg}
10288d522f475Smrg
10289a1f3da82Smrg/*
10290a1f3da82Smrg * Build up the default translations string, allowing the user to suppress
10291a1f3da82Smrg * some of the features.
10292a1f3da82Smrg */
10293a1f3da82Smrgvoid
10294a1f3da82SmrgVTInitTranslations(void)
10295a1f3da82Smrg{
10296a1f3da82Smrg    /* *INDENT-OFF* */
10297a1f3da82Smrg    static struct {
10298a1f3da82Smrg	Boolean wanted;
10299a1f3da82Smrg	const char *name;
10300a1f3da82Smrg	const char *value;
10301a1f3da82Smrg    } table[] = {
10302a1f3da82Smrg	{
10303a1f3da82Smrg	    False,
10304a1f3da82Smrg	    "default",
10305a1f3da82Smrg"\
10306a1f3da82Smrg          Shift <KeyPress> Prior:scroll-back(1,halfpage) \n\
10307a1f3da82Smrg           Shift <KeyPress> Next:scroll-forw(1,halfpage) \n\
10308a1f3da82Smrg         Shift <KeyPress> Select:select-cursor-start() select-cursor-end(SELECT, CUT_BUFFER0) \n\
10309a1f3da82Smrg         Shift <KeyPress> Insert:insert-selection(SELECT, CUT_BUFFER0) \n\
10310a1f3da82Smrg"
10311a1f3da82Smrg	},
10312a1f3da82Smrg#if OPT_MAXIMIZE
10313a1f3da82Smrg	{
10314a1f3da82Smrg	    False,
10315a1f3da82Smrg	    "fullscreen",
10316a1f3da82Smrg"\
10317a1f3da82Smrg                 Alt <Key>Return:fullscreen() \n\
10318a1f3da82Smrg"
10319a1f3da82Smrg	},
10320a1f3da82Smrg#endif
10321a1f3da82Smrg#if OPT_SCROLL_LOCK
10322a1f3da82Smrg	{
10323a1f3da82Smrg	    False,
10324a1f3da82Smrg	    "scroll-lock",
10325a1f3da82Smrg"\
10326a1f3da82Smrg        <KeyRelease> Scroll_Lock:scroll-lock() \n\
10327a1f3da82Smrg"
10328a1f3da82Smrg	},
10329a1f3da82Smrg#endif
10330a1f3da82Smrg#if OPT_SHIFT_FONTS
10331a1f3da82Smrg	{
10332a1f3da82Smrg	    False,
10333a1f3da82Smrg	    "shift-fonts",
10334a1f3da82Smrg"\
10335a1f3da82Smrg    Shift~Ctrl <KeyPress> KP_Add:larger-vt-font() \n\
10336a1f3da82Smrg    Shift Ctrl <KeyPress> KP_Add:smaller-vt-font() \n\
10337a1f3da82Smrg    Shift <KeyPress> KP_Subtract:smaller-vt-font() \n\
10338a1f3da82Smrg"
10339a1f3da82Smrg	},
10340a1f3da82Smrg#endif
10341a1f3da82Smrg	/* PROCURA added "Meta <Btn2Down>:clear-saved-lines()" */
10342a1f3da82Smrg	{
10343a1f3da82Smrg	    False,
10344a1f3da82Smrg	    "default",
10345a1f3da82Smrg"\
10346a1f3da82Smrg                ~Meta <KeyPress>:insert-seven-bit() \n\
10347a1f3da82Smrg                 Meta <KeyPress>:insert-eight-bit() \n\
10348a1f3da82Smrg                !Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
10349a1f3da82Smrg           !Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
10350a1f3da82Smrg !Lock Ctrl @Num_Lock <Btn1Down>:popup-menu(mainMenu) \n\
10351a1f3da82Smrg     ! @Num_Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
10352a1f3da82Smrg                ~Meta <Btn1Down>:select-start() \n\
10353a1f3da82Smrg              ~Meta <Btn1Motion>:select-extend() \n\
10354a1f3da82Smrg                !Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
10355a1f3da82Smrg           !Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
10356a1f3da82Smrg !Lock Ctrl @Num_Lock <Btn2Down>:popup-menu(vtMenu) \n\
10357a1f3da82Smrg     ! @Num_Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
10358a1f3da82Smrg          ~Ctrl ~Meta <Btn2Down>:ignore() \n\
10359a1f3da82Smrg                 Meta <Btn2Down>:clear-saved-lines() \n\
10360a1f3da82Smrg            ~Ctrl ~Meta <Btn2Up>:insert-selection(SELECT, CUT_BUFFER0) \n\
10361a1f3da82Smrg                !Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
10362a1f3da82Smrg           !Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
10363a1f3da82Smrg !Lock Ctrl @Num_Lock <Btn3Down>:popup-menu(fontMenu) \n\
10364a1f3da82Smrg     ! @Num_Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
10365a1f3da82Smrg          ~Ctrl ~Meta <Btn3Down>:start-extend() \n\
10366a1f3da82Smrg              ~Meta <Btn3Motion>:select-extend() \n\
10367a1f3da82Smrg"
10368a1f3da82Smrg	},
10369a1f3da82Smrg	{
10370a1f3da82Smrg	    False,
10371a1f3da82Smrg	    "wheel-mouse",
10372a1f3da82Smrg"\
10373a1f3da82Smrg                 Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
10374a1f3da82Smrg            Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
10375a1f3da82Smrg  Lock @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
10376a1f3da82Smrg       @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
10377a1f3da82Smrg                      <Btn4Down>:scroll-back(5,line,m)     \n\
10378a1f3da82Smrg                 Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
10379a1f3da82Smrg            Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
10380a1f3da82Smrg  Lock @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
10381a1f3da82Smrg       @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
10382a1f3da82Smrg                      <Btn5Down>:scroll-forw(5,line,m)     \n\
10383a1f3da82Smrg"
10384a1f3da82Smrg	},
10385a1f3da82Smrg	{
10386a1f3da82Smrg	    False,
10387a1f3da82Smrg	    "default",
10388a1f3da82Smrg"\
10389a1f3da82Smrg                         <BtnUp>:select-end(SELECT, CUT_BUFFER0) \n\
10390a1f3da82Smrg                       <BtnDown>:ignore() \
10391a1f3da82Smrg"
10392a1f3da82Smrg	}
10393a1f3da82Smrg    };
10394a1f3da82Smrg    /* *INDENT-ON* */
10395a1f3da82Smrg
10396a1f3da82Smrg    size_t needed = 0;
10397a1f3da82Smrg    char *result = 0;
10398a1f3da82Smrg
10399a1f3da82Smrg    int pass;
10400a1f3da82Smrg    Cardinal item;
10401a1f3da82Smrg
10402a1f3da82Smrg    TRACE(("VTInitTranslations\n"));
10403a1f3da82Smrg    for (item = 0; item < XtNumber(table); ++item) {
10404a1f3da82Smrg	table[item].wanted = True;
10405a1f3da82Smrg    }
10406a1f3da82Smrg#if OPT_MAXIMIZE
10407a1f3da82Smrg    /*
10408a1f3da82Smrg     * As a special case, allow for disabling the alt-enter translation if
10409a1f3da82Smrg     * the resource settings prevent fullscreen from being used.  We would
10410a1f3da82Smrg     * do the same for scroll-lock and shift-fonts if they were application
10411a1f3da82Smrg     * resources too, rather than in the widget.
10412a1f3da82Smrg     */
10413a1f3da82Smrg    if (resource.fullscreen == esNever) {
10414a1f3da82Smrg	for (item = 0; item < XtNumber(table); ++item) {
10415e39b573cSmrg	    if (!strcmp(table[item].name, "fullscreen")) {
10416a1f3da82Smrg		table[item].wanted = False;
10417e39b573cSmrg		TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value));
10418e39b573cSmrg	    }
10419a1f3da82Smrg	}
10420a1f3da82Smrg    }
10421a1f3da82Smrg#endif
10422a1f3da82Smrg    if (!IsEmpty(resource.omitTranslation)) {
10423a1f3da82Smrg	char *value;
10424a1f3da82Smrg	const char *source = resource.omitTranslation;
10425a1f3da82Smrg
10426a1f3da82Smrg	while (*source != '\0' && (value = ParseList(&source)) != 0) {
10427a1f3da82Smrg	    size_t len = strlen(value);
10428a1f3da82Smrg
10429a1f3da82Smrg	    TRACE(("parsed:%s\n", value));
10430a1f3da82Smrg	    for (item = 0; item < XtNumber(table); ++item) {
10431a1f3da82Smrg		if (strlen(table[item].name) >= len
10432a1f3da82Smrg		    && x_strncasecmp(table[item].name,
10433a1f3da82Smrg				     value,
10434a1f3da82Smrg				     (unsigned) len) == 0) {
10435a1f3da82Smrg		    table[item].wanted = False;
10436a1f3da82Smrg		    TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value));
10437a1f3da82Smrg		    break;
10438a1f3da82Smrg		}
10439a1f3da82Smrg	    }
10440a1f3da82Smrg	    free(value);
10441a1f3da82Smrg	}
10442a1f3da82Smrg    }
10443a1f3da82Smrg
10444a1f3da82Smrg    for (pass = 0; pass < 2; ++pass) {
10445a1f3da82Smrg	needed = 0;
10446a1f3da82Smrg	for (item = 0; item < XtNumber(table); ++item) {
10447a1f3da82Smrg	    if (table[item].wanted) {
10448a1f3da82Smrg		if (pass) {
10449a1f3da82Smrg		    strcat(result, table[item].value);
10450a1f3da82Smrg		} else {
10451a1f3da82Smrg		    needed += strlen(table[item].value) + 1;
10452a1f3da82Smrg		}
10453a1f3da82Smrg	    }
10454a1f3da82Smrg	}
10455a1f3da82Smrg	if (!pass) {
10456a1f3da82Smrg	    result = XtMalloc((Cardinal) needed);
10457a1f3da82Smrg	    *result = '\0';
10458a1f3da82Smrg	}
10459a1f3da82Smrg    }
10460a1f3da82Smrg
10461a1f3da82Smrg    TRACE(("result:\n%s\n", result));
10462a1f3da82Smrg
10463a1f3da82Smrg    defaultTranslations = result;
10464a1f3da82Smrg    xtermClassRec.core_class.tm_table = result;
10465a1f3da82Smrg}
10466a1f3da82Smrg
10467d522f475Smrg#ifdef NO_LEAKS
10468d522f475Smrgvoid
10469d522f475Smrgnoleaks_charproc(void)
10470d522f475Smrg{
10471d522f475Smrg    if (v_buffer != 0)
10472d522f475Smrg	free(v_buffer);
10473d522f475Smrg}
10474d522f475Smrg#endif
10475