charproc.c revision 20d2c4d2
120d2c4d2Smrg/* $XTermId: charproc.c,v 1.1071 2010/06/28 09:03:42 tom Exp $ */
2d522f475Smrg
3d522f475Smrg/*
4d522f475Smrg
520d2c4d2SmrgCopyright 1999-2009,2010 by Thomas E. Dickey
6d522f475Smrg
7d522f475Smrg                        All Rights Reserved
8d522f475Smrg
9d522f475SmrgPermission is hereby granted, free of charge, to any person obtaining a
10d522f475Smrgcopy of this software and associated documentation files (the
11d522f475Smrg"Software"), to deal in the Software without restriction, including
12d522f475Smrgwithout limitation the rights to use, copy, modify, merge, publish,
13d522f475Smrgdistribute, sublicense, and/or sell copies of the Software, and to
14d522f475Smrgpermit persons to whom the Software is furnished to do so, subject to
15d522f475Smrgthe following conditions:
16d522f475Smrg
17d522f475SmrgThe above copyright notice and this permission notice shall be included
18d522f475Smrgin all copies or substantial portions of the Software.
19d522f475Smrg
20d522f475SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21d522f475SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22d522f475SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23d522f475SmrgIN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
24d522f475SmrgCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25d522f475SmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26d522f475SmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27d522f475Smrg
28d522f475SmrgExcept as contained in this notice, the name(s) of the above copyright
29d522f475Smrgholders shall not be used in advertising or otherwise to promote the
30d522f475Smrgsale, use or other dealings in this Software without prior written
31d522f475Smrgauthorization.
32d522f475Smrg
33d522f475SmrgCopyright 1988  The Open Group
34d522f475Smrg
35d522f475SmrgPermission to use, copy, modify, distribute, and sell this software and its
36d522f475Smrgdocumentation for any purpose is hereby granted without fee, provided that
37d522f475Smrgthe above copyright notice appear in all copies and that both that
38d522f475Smrgcopyright notice and this permission notice appear in supporting
39d522f475Smrgdocumentation.
40d522f475Smrg
41d522f475SmrgThe above copyright notice and this permission notice shall be included in
42d522f475Smrgall copies or substantial portions of the Software.
43d522f475Smrg
44d522f475SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45d522f475SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46d522f475SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
47d522f475SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
48d522f475SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
49d522f475SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
50d522f475Smrg
51d522f475SmrgExcept as contained in this notice, the name of The Open Group shall not be
52d522f475Smrgused in advertising or otherwise to promote the sale, use or other dealings
53d522f475Smrgin this Software without prior written authorization from The Open Group.
54d522f475Smrg
55d522f475Smrg*/
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
105d522f475Smrg#if OPT_WIDE_CHARS
106d522f475Smrg#include <wcwidth.h>
107d522f475Smrg#include <precompose.h>
108d522f475Smrg#ifdef HAVE_LANGINFO_CODESET
109d522f475Smrg#include <langinfo.h>
110d522f475Smrg#endif
111d522f475Smrg#endif
112d522f475Smrg
113d522f475Smrg#if OPT_INPUT_METHOD
114d522f475Smrg#include <X11/Xlocale.h>
115d522f475Smrg#endif
116d522f475Smrg
117d522f475Smrg#include <stdio.h>
118d522f475Smrg#include <ctype.h>
11920d2c4d2Smrg#include <assert.h>
120d522f475Smrg
121d522f475Smrg#if defined(HAVE_SCHED_YIELD)
122d522f475Smrg#include <sched.h>
123d522f475Smrg#endif
124d522f475Smrg
125d522f475Smrg#include <VTparse.h>
126d522f475Smrg#include <data.h>
127d522f475Smrg#include <error.h>
128d522f475Smrg#include <menu.h>
129d522f475Smrg#include <main.h>
130d522f475Smrg#include <fontutils.h>
131d522f475Smrg#include <xcharmouse.h>
132d522f475Smrg#include <charclass.h>
133d522f475Smrg#include <xstrings.h>
134d522f475Smrg
13520d2c4d2Smrgtypedef struct {
13620d2c4d2Smrg    const char *name;
13720d2c4d2Smrg    int code;
13820d2c4d2Smrg} FlagList;
13920d2c4d2Smrg
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 */ );
14620d2c4d2Smrgstatic void RequestResize(XtermWidget /* xw */ ,
14720d2c4d2Smrg			  int /* rows */ ,
14820d2c4d2Smrg			  int /* cols */ ,
14920d2c4d2Smrg			  Bool /* text */ );
15020d2c4d2Smrgstatic void SwitchBufs(XtermWidget /* xw */ ,
15120d2c4d2Smrg		       int /* toBuf */ );
152d522f475Smrgstatic void ToAlternate(XtermWidget /* xw */ );
153d522f475Smrgstatic void ansi_modes(XtermWidget termw,
15420d2c4d2Smrg		       BitFunc /* func */ );
155d522f475Smrgstatic void bitclr(unsigned *p, unsigned mask);
156d522f475Smrgstatic void bitcpy(unsigned *p, unsigned q, unsigned mask);
157d522f475Smrgstatic void bitset(unsigned *p, unsigned mask);
15820d2c4d2Smrgstatic void dpmodes(XtermWidget /* xw */ ,
15920d2c4d2Smrg		    BitFunc /* func */ );
16020d2c4d2Smrgstatic void restoremodes(XtermWidget /* xw */ );
16120d2c4d2Smrgstatic void savemodes(XtermWidget /* xw */ );
16220d2c4d2Smrgstatic void window_ops(XtermWidget /* xw */ );
163d522f475Smrg
164d522f475Smrg#define DoStartBlinking(s) ((s)->cursor_blink ^ (s)->cursor_blink_esc)
165d522f475Smrg
166d522f475Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
16720d2c4d2Smrgstatic void SetCursorBlink(TScreen * /* screen */ ,
16820d2c4d2Smrg			   Bool /* enable */ );
16920d2c4d2Smrgstatic void HandleBlinking(XtPointer /* closure */ ,
17020d2c4d2Smrg			   XtIntervalId * /* id */ );
17120d2c4d2Smrgstatic void StartBlinking(TScreen * /* screen */ );
17220d2c4d2Smrgstatic void StopBlinking(TScreen * /* screen */ );
173d522f475Smrg#else
174d522f475Smrg#define StartBlinking(screen)	/* nothing */
175d522f475Smrg#define StopBlinking(screen)	/* nothing */
176d522f475Smrg#endif
177d522f475Smrg
178d522f475Smrg#if OPT_INPUT_METHOD
179d522f475Smrgstatic void PreeditPosition(TScreen * screen);
180d522f475Smrg#endif
181d522f475Smrg
182d522f475Smrg#define	DEFAULT		-1
183d522f475Smrg#define BELLSUPPRESSMSEC 200
184d522f475Smrg
185d522f475Smrgstatic int nparam;
186d522f475Smrgstatic ANSI reply;
187d522f475Smrgstatic int param[NPARAM];
188d522f475Smrg
189d522f475Smrgstatic jmp_buf vtjmpbuf;
190d522f475Smrg
191d522f475Smrg/* event handlers */
192d522f475Smrgstatic void HandleBell PROTO_XT_ACTIONS_ARGS;
193d522f475Smrgstatic void HandleIgnore PROTO_XT_ACTIONS_ARGS;
194d522f475Smrgstatic void HandleKeymapChange PROTO_XT_ACTIONS_ARGS;
195d522f475Smrgstatic void HandleVisualBell PROTO_XT_ACTIONS_ARGS;
196d522f475Smrg#if HANDLE_STRUCT_NOTIFY
197d522f475Smrgstatic void HandleStructNotify PROTO_XT_EV_HANDLER_ARGS;
198d522f475Smrg#endif
199d522f475Smrg
200d522f475Smrg/*
201d522f475Smrg * NOTE: VTInitialize zeros out the entire ".screen" component of the
202d522f475Smrg * XtermWidget, so make sure to add an assignment statement in VTInitialize()
203d522f475Smrg * for each new ".screen" field added to this resource list.
204d522f475Smrg */
205d522f475Smrg
206d522f475Smrg/* Defaults */
207d522f475Smrg#if OPT_ISO_COLORS
208d522f475Smrg
209d522f475Smrg/*
210d522f475Smrg * If we default to colorMode enabled, compile-in defaults for the ANSI colors.
211d522f475Smrg */
212d522f475Smrg#if DFT_COLORMODE
213d522f475Smrg#define DFT_COLOR(name) name
214d522f475Smrg#else
215d522f475Smrg#define DFT_COLOR(name) XtDefaultForeground
216d522f475Smrg#endif
217d522f475Smrg#endif
218d522f475Smrg
21920d2c4d2Smrgstatic String _Font_Selected_ = "yes";	/* string is arbitrary */
220d522f475Smrg
221d522f475Smrgstatic char defaultTranslations[] =
222d522f475Smrg"\
223d522f475Smrg          Shift <KeyPress> Prior:scroll-back(1,halfpage) \n\
224d522f475Smrg           Shift <KeyPress> Next:scroll-forw(1,halfpage) \n\
225d522f475Smrg         Shift <KeyPress> Select:select-cursor-start() select-cursor-end(SELECT, CUT_BUFFER0) \n\
226d522f475Smrg         Shift <KeyPress> Insert:insert-selection(SELECT, CUT_BUFFER0) \n\
227d522f475Smrg"
22820d2c4d2Smrg#if OPT_SCROLL_LOCK
22920d2c4d2Smrg"\
23020d2c4d2Smrg        <KeyRelease> Scroll_Lock:scroll-lock() \n\
23120d2c4d2Smrg"
23220d2c4d2Smrg#endif
233d522f475Smrg#if OPT_SHIFT_FONTS
234d522f475Smrg"\
235d522f475Smrg    Shift~Ctrl <KeyPress> KP_Add:larger-vt-font() \n\
236d522f475Smrg    Shift Ctrl <KeyPress> KP_Add:smaller-vt-font() \n\
237d522f475Smrg    Shift <KeyPress> KP_Subtract:smaller-vt-font() \n\
238d522f475Smrg"
239d522f475Smrg#endif
240d522f475Smrg"\
241d522f475Smrg                ~Meta <KeyPress>:insert-seven-bit() \n\
242d522f475Smrg                 Meta <KeyPress>:insert-eight-bit() \n\
243d522f475Smrg                !Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
244d522f475Smrg           !Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
245d522f475Smrg !Lock Ctrl @Num_Lock <Btn1Down>:popup-menu(mainMenu) \n\
246d522f475Smrg     ! @Num_Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
247d522f475Smrg                ~Meta <Btn1Down>:select-start() \n\
248d522f475Smrg              ~Meta <Btn1Motion>:select-extend() \n\
249d522f475Smrg                !Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
250d522f475Smrg           !Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
251d522f475Smrg !Lock Ctrl @Num_Lock <Btn2Down>:popup-menu(vtMenu) \n\
252d522f475Smrg     ! @Num_Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
253d522f475Smrg          ~Ctrl ~Meta <Btn2Down>:ignore() \n\
254d522f475Smrg                 Meta <Btn2Down>:clear-saved-lines() \n\
255d522f475Smrg            ~Ctrl ~Meta <Btn2Up>:insert-selection(SELECT, CUT_BUFFER0) \n\
256d522f475Smrg                !Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
257d522f475Smrg           !Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
258d522f475Smrg !Lock Ctrl @Num_Lock <Btn3Down>:popup-menu(fontMenu) \n\
259d522f475Smrg     ! @Num_Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
260d522f475Smrg          ~Ctrl ~Meta <Btn3Down>:start-extend() \n\
261d522f475Smrg              ~Meta <Btn3Motion>:select-extend() \n\
262d522f475Smrg                 Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
263d522f475Smrg            Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
264d522f475Smrg  Lock @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
265d522f475Smrg       @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
266d522f475Smrg                      <Btn4Down>:scroll-back(5,line,m)     \n\
267d522f475Smrg                 Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
268d522f475Smrg            Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
269d522f475Smrg  Lock @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
270d522f475Smrg       @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
271d522f475Smrg                      <Btn5Down>:scroll-forw(5,line,m)     \n\
272d522f475Smrg                         <BtnUp>:select-end(SELECT, CUT_BUFFER0) \n\
273d522f475Smrg                       <BtnDown>:ignore() \
274d522f475Smrg";				/* PROCURA added "Meta <Btn2Down>:clear-saved-lines()" */
275d522f475Smrg/* *INDENT-OFF* */
276d522f475Smrgstatic XtActionsRec actionsList[] = {
277d522f475Smrg    { "allow-send-events",	HandleAllowSends },
278d522f475Smrg    { "bell",			HandleBell },
279d522f475Smrg    { "clear-saved-lines",	HandleClearSavedLines },
280d522f475Smrg    { "create-menu",		HandleCreateMenu },
281d522f475Smrg    { "delete-is-del",		HandleDeleteIsDEL },
282d522f475Smrg    { "dired-button",		DiredButton },
283d522f475Smrg    { "hard-reset",		HandleHardReset },
284d522f475Smrg    { "ignore",			HandleIgnore },
285d522f475Smrg    { "insert",			HandleKeyPressed },  /* alias for insert-seven-bit */
286d522f475Smrg    { "insert-eight-bit",	HandleEightBitKeyPressed },
287d522f475Smrg    { "insert-selection",	HandleInsertSelection },
288d522f475Smrg    { "insert-seven-bit",	HandleKeyPressed },
289d522f475Smrg    { "interpret",		HandleInterpret },
290d522f475Smrg    { "keymap",			HandleKeymapChange },
291d522f475Smrg    { "popup-menu",		HandlePopupMenu },
292d522f475Smrg    { "print",			HandlePrintScreen },
293956cc18dSsnj    { "print-everything",	HandlePrintEverything },
294d522f475Smrg    { "print-redir",		HandlePrintControlMode },
295d522f475Smrg    { "quit",			HandleQuit },
296d522f475Smrg    { "redraw",			HandleRedraw },
297d522f475Smrg    { "scroll-back",		HandleScrollBack },
298d522f475Smrg    { "scroll-forw",		HandleScrollForward },
299d522f475Smrg    { "secure",			HandleSecure },
300d522f475Smrg    { "select-cursor-end",	HandleKeyboardSelectEnd },
301d522f475Smrg    { "select-cursor-extend",   HandleKeyboardSelectExtend },
302d522f475Smrg    { "select-cursor-start",	HandleKeyboardSelectStart },
303d522f475Smrg    { "select-end",		HandleSelectEnd },
304d522f475Smrg    { "select-extend",		HandleSelectExtend },
305d522f475Smrg    { "select-set",		HandleSelectSet },
306d522f475Smrg    { "select-start",		HandleSelectStart },
307d522f475Smrg    { "send-signal",		HandleSendSignal },
308d522f475Smrg    { "set-8-bit-control",	Handle8BitControl },
309d522f475Smrg    { "set-allow132",		HandleAllow132 },
310d522f475Smrg    { "set-altscreen",		HandleAltScreen },
311d522f475Smrg    { "set-appcursor",		HandleAppCursor },
312d522f475Smrg    { "set-appkeypad",		HandleAppKeypad },
313d522f475Smrg    { "set-autolinefeed",	HandleAutoLineFeed },
314d522f475Smrg    { "set-autowrap",		HandleAutoWrap },
315d522f475Smrg    { "set-backarrow",		HandleBackarrow },
316d522f475Smrg    { "set-bellIsUrgent",	HandleBellIsUrgent },
317d522f475Smrg    { "set-cursesemul",		HandleCursesEmul },
318d522f475Smrg    { "set-jumpscroll",		HandleJumpscroll },
319d522f475Smrg    { "set-keep-selection",	HandleKeepSelection },
320d522f475Smrg    { "set-marginbell",		HandleMarginBell },
321d522f475Smrg    { "set-old-function-keys",	HandleOldFunctionKeys },
322d522f475Smrg    { "set-pop-on-bell",	HandleSetPopOnBell },
323d522f475Smrg    { "set-reverse-video",	HandleReverseVideo },
324d522f475Smrg    { "set-reversewrap",	HandleReverseWrap },
325d522f475Smrg    { "set-scroll-on-key",	HandleScrollKey },
326d522f475Smrg    { "set-scroll-on-tty-output", HandleScrollTtyOutput },
327d522f475Smrg    { "set-scrollbar",		HandleScrollbar },
328d522f475Smrg    { "set-select",		HandleSetSelect },
329d522f475Smrg    { "set-sun-keyboard",	HandleSunKeyboard },
330d522f475Smrg    { "set-titeInhibit",	HandleTiteInhibit },
331d522f475Smrg    { "set-visual-bell",	HandleSetVisualBell },
332d522f475Smrg    { "set-vt-font",		HandleSetFont },
333d522f475Smrg    { "soft-reset",		HandleSoftReset },
334d522f475Smrg    { "start-cursor-extend",	HandleKeyboardStartExtend },
335d522f475Smrg    { "start-extend",		HandleStartExtend },
336d522f475Smrg    { "string",			HandleStringEvent },
337d522f475Smrg    { "vi-button",		ViButton },
338d522f475Smrg    { "visual-bell",		HandleVisualBell },
339d522f475Smrg#ifdef ALLOWLOGGING
340d522f475Smrg    { "set-logging",		HandleLogging },
341d522f475Smrg#endif
342956cc18dSsnj#if OPT_ALLOW_XXX_OPS
34320d2c4d2Smrg    { "allow-color-ops",	HandleAllowColorOps },
344956cc18dSsnj    { "allow-font-ops",		HandleAllowFontOps },
345956cc18dSsnj    { "allow-tcap-ops",		HandleAllowTcapOps },
346956cc18dSsnj    { "allow-title-ops",	HandleAllowTitleOps },
347956cc18dSsnj    { "allow-window-ops",	HandleAllowWindowOps },
348956cc18dSsnj#endif
349d522f475Smrg#if OPT_BLINK_CURS
350d522f475Smrg    { "set-cursorblink",	HandleCursorBlink },
351d522f475Smrg#endif
352d522f475Smrg#if OPT_BOX_CHARS
353d522f475Smrg    { "set-font-linedrawing",	HandleFontBoxChars },
35420d2c4d2Smrg    { "set-font-packed",	HandleFontPacked },
355d522f475Smrg#endif
356d522f475Smrg#if OPT_DABBREV
357d522f475Smrg    { "dabbrev-expand",		HandleDabbrevExpand },
358d522f475Smrg#endif
359d522f475Smrg#if OPT_DEC_CHRSET
360d522f475Smrg    { "set-font-doublesize",	HandleFontDoublesize },
361d522f475Smrg#endif
362d522f475Smrg#if OPT_DEC_SOFTFONT
363d522f475Smrg    { "set-font-loading",	HandleFontLoading },
364d522f475Smrg#endif
365d522f475Smrg#if OPT_EXEC_XTERM
366d522f475Smrg    { "spawn-new-terminal",	HandleSpawnTerminal },
367d522f475Smrg#endif
368d522f475Smrg#if OPT_HP_FUNC_KEYS
369d522f475Smrg    { "set-hp-function-keys",	HandleHpFunctionKeys },
370d522f475Smrg#endif
371d522f475Smrg#if OPT_LOAD_VTFONTS
372d522f475Smrg    { "load-vt-fonts",		HandleLoadVTFonts },
373d522f475Smrg#endif
374d522f475Smrg#if OPT_MAXIMIZE
375d522f475Smrg    { "deiconify",		HandleDeIconify },
376d522f475Smrg    { "iconify",		HandleIconify },
377d522f475Smrg    { "maximize",		HandleMaximize },
378d522f475Smrg    { "restore",		HandleRestoreSize },
379d522f475Smrg#endif
380d522f475Smrg#if OPT_NUM_LOCK
381d522f475Smrg    { "alt-sends-escape",	HandleAltEsc },
382d522f475Smrg    { "meta-sends-escape",	HandleMetaEsc },
383d522f475Smrg    { "set-num-lock",		HandleNumLock },
384d522f475Smrg#endif
385d522f475Smrg#if OPT_READLINE
386d522f475Smrg    { "readline-button",	ReadLineButton },
387d522f475Smrg#endif
388d522f475Smrg#if OPT_RENDERFONT
389d522f475Smrg    { "set-render-font",	HandleRenderFont },
390d522f475Smrg#endif
391d522f475Smrg#if OPT_SCO_FUNC_KEYS
392d522f475Smrg    { "set-sco-function-keys",	HandleScoFunctionKeys },
393d522f475Smrg#endif
39420d2c4d2Smrg#if OPT_SCROLL_LOCK
39520d2c4d2Smrg    { "scroll-lock",		HandleScrollLock },
39620d2c4d2Smrg#endif
397d522f475Smrg#if OPT_SHIFT_FONTS
398d522f475Smrg    { "larger-vt-font",		HandleLargerFont },
399d522f475Smrg    { "smaller-vt-font",	HandleSmallerFont },
400d522f475Smrg#endif
401d522f475Smrg#if OPT_SUN_FUNC_KEYS
402d522f475Smrg    { "set-sun-function-keys",	HandleSunFunctionKeys },
403d522f475Smrg#endif
404d522f475Smrg#if OPT_TEK4014
405d522f475Smrg    { "set-terminal-type",	HandleSetTerminalType },
406d522f475Smrg    { "set-visibility",		HandleVisibility },
407d522f475Smrg    { "set-tek-text",		HandleSetTekText },
408d522f475Smrg    { "tek-page",		HandleTekPage },
409d522f475Smrg    { "tek-reset",		HandleTekReset },
410d522f475Smrg    { "tek-copy",		HandleTekCopy },
411d522f475Smrg#endif
412d522f475Smrg#if OPT_TOOLBAR
413d522f475Smrg    { "set-toolbar",		HandleToolbar },
414d522f475Smrg#endif
415d522f475Smrg#if OPT_WIDE_CHARS
416d522f475Smrg    { "set-utf8-mode",		HandleUTF8Mode },
417d522f475Smrg    { "set-utf8-title",		HandleUTF8Title },
418d522f475Smrg#endif
419d522f475Smrg};
420d522f475Smrg/* *INDENT-ON* */
421d522f475Smrg
42220d2c4d2Smrgstatic XtResource xterm_resources[] =
423d522f475Smrg{
424d522f475Smrg    Bres(XtNallowSendEvents, XtCAllowSendEvents, screen.allowSendEvent0, False),
42520d2c4d2Smrg    Bres(XtNallowColorOps, XtCAllowColorOps, screen.allowColorOp0, DEF_ALLOW_COLOR),
426956cc18dSsnj    Bres(XtNallowFontOps, XtCAllowFontOps, screen.allowFontOp0, DEF_ALLOW_FONT),
427956cc18dSsnj    Bres(XtNallowTcapOps, XtCAllowTcapOps, screen.allowTcapOp0, DEF_ALLOW_TCAP),
428956cc18dSsnj    Bres(XtNallowTitleOps, XtCAllowTitleOps, screen.allowTitleOp0, DEF_ALLOW_TITLE),
429956cc18dSsnj    Bres(XtNallowWindowOps, XtCAllowWindowOps, screen.allowWindowOp0, DEF_ALLOW_WINDOW),
430d522f475Smrg    Bres(XtNaltIsNotMeta, XtCAltIsNotMeta, screen.alt_is_not_meta, False),
431d522f475Smrg    Bres(XtNaltSendsEscape, XtCAltSendsEscape, screen.alt_sends_esc, False),
432d522f475Smrg    Bres(XtNalwaysBoldMode, XtCAlwaysBoldMode, screen.always_bold_mode, False),
433d522f475Smrg    Bres(XtNalwaysHighlight, XtCAlwaysHighlight, screen.always_highlight, False),
434d522f475Smrg    Bres(XtNappcursorDefault, XtCAppcursorDefault, misc.appcursorDefault, False),
435d522f475Smrg    Bres(XtNappkeypadDefault, XtCAppkeypadDefault, misc.appkeypadDefault, False),
436d522f475Smrg    Bres(XtNautoWrap, XtCAutoWrap, misc.autoWrap, True),
437d522f475Smrg    Bres(XtNawaitInput, XtCAwaitInput, screen.awaitInput, False),
438d522f475Smrg    Bres(XtNfreeBoldBox, XtCFreeBoldBox, screen.free_bold_box, False),
439d522f475Smrg    Bres(XtNbackarrowKey, XtCBackarrowKey, screen.backarrow_key, True),
440d522f475Smrg    Bres(XtNbellIsUrgent, XtCBellIsUrgent, screen.bellIsUrgent, False),
441d522f475Smrg    Bres(XtNbellOnReset, XtCBellOnReset, screen.bellOnReset, True),
442d522f475Smrg    Bres(XtNboldMode, XtCBoldMode, screen.bold_mode, True),
443d522f475Smrg    Bres(XtNbrokenSelections, XtCBrokenSelections, screen.brokenSelections, False),
444d522f475Smrg    Bres(XtNc132, XtCC132, screen.c132, False),
445d522f475Smrg    Bres(XtNcurses, XtCCurses, screen.curses, False),
446d522f475Smrg    Bres(XtNcutNewline, XtCCutNewline, screen.cutNewline, True),
447d522f475Smrg    Bres(XtNcutToBeginningOfLine, XtCCutToBeginningOfLine,
448d522f475Smrg	 screen.cutToBeginningOfLine, True),
449d522f475Smrg    Bres(XtNdeleteIsDEL, XtCDeleteIsDEL, screen.delete_is_del, DEFDELETE_DEL),
450d522f475Smrg    Bres(XtNdynamicColors, XtCDynamicColors, misc.dynamicColors, True),
451d522f475Smrg    Bres(XtNeightBitControl, XtCEightBitControl, screen.control_eight_bits, False),
452d522f475Smrg    Bres(XtNeightBitInput, XtCEightBitInput, screen.input_eight_bits, True),
453d522f475Smrg    Bres(XtNeightBitOutput, XtCEightBitOutput, screen.output_eight_bits, True),
454d522f475Smrg    Bres(XtNhighlightSelection, XtCHighlightSelection,
455d522f475Smrg	 screen.highlight_selection, False),
456d522f475Smrg    Bres(XtNhpLowerleftBugCompat, XtCHpLowerleftBugCompat, screen.hp_ll_bc, False),
457d522f475Smrg    Bres(XtNi18nSelections, XtCI18nSelections, screen.i18nSelections, True),
458956cc18dSsnj    Bres(XtNfastScroll, XtCFastScroll, screen.fastscroll, False),
459d522f475Smrg    Bres(XtNjumpScroll, XtCJumpScroll, screen.jumpscroll, True),
460956cc18dSsnj    Bres(XtNkeepSelection, XtCKeepSelection, screen.keepSelection, True),
461d522f475Smrg    Bres(XtNloginShell, XtCLoginShell, misc.login_shell, False),
462d522f475Smrg    Bres(XtNmarginBell, XtCMarginBell, screen.marginbell, False),
463d522f475Smrg    Bres(XtNmetaSendsEscape, XtCMetaSendsEscape, screen.meta_sends_esc, False),
464d522f475Smrg    Bres(XtNmultiScroll, XtCMultiScroll, screen.multiscroll, False),
465d522f475Smrg    Bres(XtNoldXtermFKeys, XtCOldXtermFKeys, screen.old_fkeys, False),
466d522f475Smrg    Bres(XtNpopOnBell, XtCPopOnBell, screen.poponbell, False),
467d522f475Smrg    Bres(XtNprinterAutoClose, XtCPrinterAutoClose, screen.printer_autoclose, False),
468d522f475Smrg    Bres(XtNprinterExtent, XtCPrinterExtent, screen.printer_extent, False),
469d522f475Smrg    Bres(XtNprinterFormFeed, XtCPrinterFormFeed, screen.printer_formfeed, False),
47020d2c4d2Smrg    Bres(XtNprinterNewLine, XtCPrinterNewLine, screen.printer_newline, True),
471d522f475Smrg    Bres(XtNquietGrab, XtCQuietGrab, screen.quiet_grab, False),
472d522f475Smrg    Bres(XtNreverseVideo, XtCReverseVideo, misc.re_verse, False),
473d522f475Smrg    Bres(XtNreverseWrap, XtCReverseWrap, misc.reverseWrap, False),
474d522f475Smrg    Bres(XtNscrollBar, XtCScrollBar, misc.scrollbar, False),
475d522f475Smrg    Bres(XtNscrollKey, XtCScrollCond, screen.scrollkey, False),
476d522f475Smrg    Bres(XtNscrollTtyOutput, XtCScrollCond, screen.scrollttyoutput, True),
477d522f475Smrg    Bres(XtNselectToClipboard, XtCSelectToClipboard,
478d522f475Smrg	 screen.selectToClipboard, False),
479d522f475Smrg    Bres(XtNsignalInhibit, XtCSignalInhibit, misc.signalInhibit, False),
480d522f475Smrg    Bres(XtNtiteInhibit, XtCTiteInhibit, misc.titeInhibit, False),
481d522f475Smrg    Bres(XtNtiXtraScroll, XtCTiXtraScroll, misc.tiXtraScroll, False),
482d522f475Smrg    Bres(XtNtrimSelection, XtCTrimSelection, screen.trim_selection, False),
483d522f475Smrg    Bres(XtNunderLine, XtCUnderLine, screen.underline, True),
484d522f475Smrg    Bres(XtNvisualBell, XtCVisualBell, screen.visualbell, False),
485d522f475Smrg
486d522f475Smrg    Ires(XtNbellSuppressTime, XtCBellSuppressTime, screen.bellSuppressTime, BELLSUPPRESSMSEC),
487956cc18dSsnj    Ires(XtNfontWarnings, XtCFontWarnings, misc.fontWarnings, fwResource),
488d522f475Smrg    Ires(XtNinternalBorder, XtCBorderWidth, screen.border, DEFBORDER),
489d522f475Smrg    Ires(XtNlimitResize, XtCLimitResize, misc.limit_resize, 1),
490d522f475Smrg    Ires(XtNmultiClickTime, XtCMultiClickTime, screen.multiClickTime, MULTICLICKTIME),
491d522f475Smrg    Ires(XtNnMarginBell, XtCColumn, screen.nmarginbell, N_MARGINBELL),
492d522f475Smrg    Ires(XtNpointerMode, XtCPointerMode, screen.pointer_mode, DEF_POINTER_MODE),
493d522f475Smrg    Ires(XtNprinterControlMode, XtCPrinterControlMode,
494d522f475Smrg	 screen.printer_controlmode, 0),
49520d2c4d2Smrg    Ires(XtNtitleModes, XtCTitleModes, screen.title_modes, DEF_TITLE_MODES),
496d522f475Smrg    Ires(XtNvisualBellDelay, XtCVisualBellDelay, screen.visualBellDelay, 100),
497d522f475Smrg    Ires(XtNsaveLines, XtCSaveLines, screen.savelines, SAVELINES),
498d522f475Smrg    Ires(XtNscrollBarBorder, XtCScrollBarBorder, screen.scrollBarBorder, 1),
499d522f475Smrg    Ires(XtNscrollLines, XtCScrollLines, screen.scrolllines, SCROLLLINES),
500d522f475Smrg
501d522f475Smrg    Sres(XtNinitialFont, XtCInitialFont, screen.initial_font, NULL),
502d522f475Smrg    Sres(XtNfont1, XtCFont1, screen.MenuFontName(fontMenu_font1), NULL),
503d522f475Smrg    Sres(XtNfont2, XtCFont2, screen.MenuFontName(fontMenu_font2), NULL),
504d522f475Smrg    Sres(XtNfont3, XtCFont3, screen.MenuFontName(fontMenu_font3), NULL),
505d522f475Smrg    Sres(XtNfont4, XtCFont4, screen.MenuFontName(fontMenu_font4), NULL),
506d522f475Smrg    Sres(XtNfont5, XtCFont5, screen.MenuFontName(fontMenu_font5), NULL),
507d522f475Smrg    Sres(XtNfont6, XtCFont6, screen.MenuFontName(fontMenu_font6), NULL),
508956cc18dSsnj
509d522f475Smrg    Sres(XtNanswerbackString, XtCAnswerbackString, screen.answer_back, ""),
510d522f475Smrg    Sres(XtNboldFont, XtCBoldFont, misc.default_font.f_b, DEFBOLDFONT),
511d522f475Smrg    Sres(XtNcharClass, XtCCharClass, screen.charClass, NULL),
512d522f475Smrg    Sres(XtNdecTerminalID, XtCDecTerminalID, screen.term_id, DFT_DECID),
513956cc18dSsnj    Sres(XtNdefaultString, XtCDefaultString, screen.default_string, "#"),
51420d2c4d2Smrg    Sres(XtNdisallowedColorOps, XtCDisallowedColorOps,
51520d2c4d2Smrg	 screen.disallowedColorOps, DEF_DISALLOWED_COLOR),
51620d2c4d2Smrg    Sres(XtNdisallowedFontOps, XtCDisallowedFontOps,
51720d2c4d2Smrg	 screen.disallowedFontOps, DEF_DISALLOWED_FONT),
51820d2c4d2Smrg    Sres(XtNdisallowedTcapOps, XtCDisallowedTcapOps,
51920d2c4d2Smrg	 screen.disallowedTcapOps, DEF_DISALLOWED_TCAP),
52020d2c4d2Smrg    Sres(XtNdisallowedWindowOps, XtCDisallowedWindowOps,
52120d2c4d2Smrg	 screen.disallowedWinOps, DEF_DISALLOWED_WINDOW),
522956cc18dSsnj    Sres(XtNeightBitSelectTypes, XtCEightBitSelectTypes,
523956cc18dSsnj	 screen.eightbit_select_types, NULL),
524d522f475Smrg    Sres(XtNfont, XtCFont, misc.default_font.f_n, DEFFONT),
525d522f475Smrg    Sres(XtNgeometry, XtCGeometry, misc.geo_metry, NULL),
526d522f475Smrg    Sres(XtNkeyboardDialect, XtCKeyboardDialect, screen.keyboard_dialect, DFT_KBD_DIALECT),
527d522f475Smrg    Sres(XtNprinterCommand, XtCPrinterCommand, screen.printer_command, ""),
528d522f475Smrg    Sres(XtNtekGeometry, XtCGeometry, misc.T_geometry, NULL),
529d522f475Smrg
530d522f475Smrg    Tres(XtNcursorColor, XtCCursorColor, TEXT_CURSOR, XtDefaultForeground),
531d522f475Smrg    Tres(XtNforeground, XtCForeground, TEXT_FG, XtDefaultForeground),
532d522f475Smrg    Tres(XtNpointerColor, XtCPointerColor, MOUSE_FG, XtDefaultForeground),
533d522f475Smrg    Tres(XtNbackground, XtCBackground, TEXT_BG, XtDefaultBackground),
534d522f475Smrg    Tres(XtNpointerColorBackground, XtCBackground, MOUSE_BG, XtDefaultBackground),
535d522f475Smrg
536d522f475Smrg    {XtNresizeGravity, XtCResizeGravity, XtRGravity, sizeof(XtGravity),
537d522f475Smrg     XtOffsetOf(XtermWidgetRec, misc.resizeGravity),
538d522f475Smrg     XtRImmediate, (XtPointer) SouthWestGravity},
539d522f475Smrg
540d522f475Smrg    {XtNpointerShape, XtCCursor, XtRCursor, sizeof(Cursor),
541d522f475Smrg     XtOffsetOf(XtermWidgetRec, screen.pointer_cursor),
542d522f475Smrg     XtRString, (XtPointer) "xterm"},
543d522f475Smrg
544d522f475Smrg#ifdef ALLOWLOGGING
545d522f475Smrg    Bres(XtNlogInhibit, XtCLogInhibit, misc.logInhibit, False),
546d522f475Smrg    Bres(XtNlogging, XtCLogging, misc.log_on, False),
547d522f475Smrg    Sres(XtNlogFile, XtCLogfile, screen.logfile, NULL),
548d522f475Smrg#endif
549d522f475Smrg
550d522f475Smrg#ifndef NO_ACTIVE_ICON
551d522f475Smrg    Bres("activeIcon", "ActiveIcon", misc.active_icon, False),
552d522f475Smrg    Ires("iconBorderWidth", XtCBorderWidth, misc.icon_border_width, 2),
553d522f475Smrg    Fres("iconFont", "IconFont", screen.fnt_icon.fs, XtDefaultFont),
554d522f475Smrg    Cres("iconBorderColor", XtCBorderColor, misc.icon_border_pixel, XtDefaultBackground),
555d522f475Smrg#endif				/* NO_ACTIVE_ICON */
556d522f475Smrg
557d522f475Smrg#if OPT_BLINK_CURS
558d522f475Smrg    Bres(XtNcursorBlink, XtCCursorBlink, screen.cursor_blink, False),
559d522f475Smrg#endif
5602eaa94a1Schristos    Bres(XtNcursorUnderline, XtCCursorUnderline, screen.cursor_underline, False),
561d522f475Smrg
562d522f475Smrg#if OPT_BLINK_TEXT
563d522f475Smrg    Bres(XtNshowBlinkAsBold, XtCCursorBlink, screen.blink_as_bold, DEFBLINKASBOLD),
564d522f475Smrg#endif
565d522f475Smrg
566d522f475Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
567d522f475Smrg    Ires(XtNcursorOnTime, XtCCursorOnTime, screen.blink_on, 600),
568d522f475Smrg    Ires(XtNcursorOffTime, XtCCursorOffTime, screen.blink_off, 300),
569d522f475Smrg#endif
570d522f475Smrg
571d522f475Smrg#if OPT_BOX_CHARS
572d522f475Smrg    Bres(XtNforceBoxChars, XtCForceBoxChars, screen.force_box_chars, False),
57320d2c4d2Smrg    Bres(XtNforcePackedFont, XtCForcePackedFont, screen.force_packed, True),
574d522f475Smrg    Bres(XtNshowMissingGlyphs, XtCShowMissingGlyphs, screen.force_all_chars, False),
575d522f475Smrg#endif
576d522f475Smrg
577d522f475Smrg#if OPT_BROKEN_OSC
578d522f475Smrg    Bres(XtNbrokenLinuxOSC, XtCBrokenLinuxOSC, screen.brokenLinuxOSC, True),
579d522f475Smrg#endif
580d522f475Smrg
581d522f475Smrg#if OPT_BROKEN_ST
582d522f475Smrg    Bres(XtNbrokenStringTerm, XtCBrokenStringTerm, screen.brokenStringTerm, True),
583d522f475Smrg#endif
584d522f475Smrg
585d522f475Smrg#if OPT_C1_PRINT
586d522f475Smrg    Bres(XtNallowC1Printable, XtCAllowC1Printable, screen.c1_printable, False),
587d522f475Smrg#endif
588d522f475Smrg
589d522f475Smrg#if OPT_CLIP_BOLD
590d522f475Smrg    Bres(XtNuseClipping, XtCUseClipping, screen.use_clipping, True),
591d522f475Smrg#endif
592d522f475Smrg
593d522f475Smrg#if OPT_DEC_CHRSET
594d522f475Smrg    Bres(XtNfontDoublesize, XtCFontDoublesize, screen.font_doublesize, True),
595d522f475Smrg    Ires(XtNcacheDoublesize, XtCCacheDoublesize, screen.cache_doublesize, NUM_CHRSET),
596d522f475Smrg#endif
597d522f475Smrg
598d522f475Smrg#if OPT_HIGHLIGHT_COLOR
599d522f475Smrg    Tres(XtNhighlightColor, XtCHighlightColor, HIGHLIGHT_BG, XtDefaultForeground),
600d522f475Smrg    Tres(XtNhighlightTextColor, XtCHighlightTextColor, HIGHLIGHT_FG, XtDefaultBackground),
601d522f475Smrg    Bres(XtNhighlightReverse, XtCHighlightReverse, screen.hilite_reverse, True),
602d522f475Smrg    Bres(XtNhighlightColorMode, XtCHighlightColorMode, screen.hilite_color, Maybe),
603d522f475Smrg#endif				/* OPT_HIGHLIGHT_COLOR */
604d522f475Smrg
605d522f475Smrg#if OPT_INPUT_METHOD
606d522f475Smrg    Bres(XtNopenIm, XtCOpenIm, misc.open_im, True),
607d522f475Smrg    Sres(XtNinputMethod, XtCInputMethod, misc.input_method, NULL),
608d522f475Smrg    Sres(XtNpreeditType, XtCPreeditType, misc.preedit_type,
609d522f475Smrg	 "OverTheSpot,Root"),
610956cc18dSsnj    Ires(XtNretryInputMethod, XtCRetryInputMethod, misc.retry_im, 3),
611d522f475Smrg#endif
612d522f475Smrg
613d522f475Smrg#if OPT_ISO_COLORS
614d522f475Smrg    Bres(XtNboldColors, XtCColorMode, screen.boldColors, True),
615d522f475Smrg    Ires(XtNveryBoldColors, XtCVeryBoldColors, screen.veryBoldColors, 0),
616d522f475Smrg    Bres(XtNcolorMode, XtCColorMode, screen.colorMode, DFT_COLORMODE),
617d522f475Smrg
618d522f475Smrg    Bres(XtNcolorAttrMode, XtCColorAttrMode, screen.colorAttrMode, False),
619d522f475Smrg    Bres(XtNcolorBDMode, XtCColorAttrMode, screen.colorBDMode, False),
620d522f475Smrg    Bres(XtNcolorBLMode, XtCColorAttrMode, screen.colorBLMode, False),
621d522f475Smrg    Bres(XtNcolorRVMode, XtCColorAttrMode, screen.colorRVMode, False),
622d522f475Smrg    Bres(XtNcolorULMode, XtCColorAttrMode, screen.colorULMode, False),
623d522f475Smrg    Bres(XtNitalicULMode, XtCColorAttrMode, screen.italicULMode, False),
624d522f475Smrg
625d522f475Smrg    COLOR_RES("0", screen.Acolors[COLOR_0], DFT_COLOR("black")),
626d522f475Smrg    COLOR_RES("1", screen.Acolors[COLOR_1], DFT_COLOR("red3")),
627d522f475Smrg    COLOR_RES("2", screen.Acolors[COLOR_2], DFT_COLOR("green3")),
628d522f475Smrg    COLOR_RES("3", screen.Acolors[COLOR_3], DFT_COLOR("yellow3")),
629d522f475Smrg    COLOR_RES("4", screen.Acolors[COLOR_4], DFT_COLOR(DEF_COLOR4)),
630d522f475Smrg    COLOR_RES("5", screen.Acolors[COLOR_5], DFT_COLOR("magenta3")),
631d522f475Smrg    COLOR_RES("6", screen.Acolors[COLOR_6], DFT_COLOR("cyan3")),
632d522f475Smrg    COLOR_RES("7", screen.Acolors[COLOR_7], DFT_COLOR("gray90")),
633d522f475Smrg    COLOR_RES("8", screen.Acolors[COLOR_8], DFT_COLOR("gray50")),
634d522f475Smrg    COLOR_RES("9", screen.Acolors[COLOR_9], DFT_COLOR("red")),
635d522f475Smrg    COLOR_RES("10", screen.Acolors[COLOR_10], DFT_COLOR("green")),
636d522f475Smrg    COLOR_RES("11", screen.Acolors[COLOR_11], DFT_COLOR("yellow")),
637d522f475Smrg    COLOR_RES("12", screen.Acolors[COLOR_12], DFT_COLOR(DEF_COLOR12)),
638d522f475Smrg    COLOR_RES("13", screen.Acolors[COLOR_13], DFT_COLOR("magenta")),
639d522f475Smrg    COLOR_RES("14", screen.Acolors[COLOR_14], DFT_COLOR("cyan")),
640d522f475Smrg    COLOR_RES("15", screen.Acolors[COLOR_15], DFT_COLOR("white")),
641d522f475Smrg    COLOR_RES("BD", screen.Acolors[COLOR_BD], DFT_COLOR(XtDefaultForeground)),
642d522f475Smrg    COLOR_RES("BL", screen.Acolors[COLOR_BL], DFT_COLOR(XtDefaultForeground)),
643d522f475Smrg    COLOR_RES("UL", screen.Acolors[COLOR_UL], DFT_COLOR(XtDefaultForeground)),
644d522f475Smrg    COLOR_RES("RV", screen.Acolors[COLOR_RV], DFT_COLOR(XtDefaultForeground)),
645d522f475Smrg
646d522f475Smrg#if !OPT_COLOR_RES2
647d522f475Smrg#if OPT_256_COLORS
648d522f475Smrg# include <256colres.h>
649d522f475Smrg#elif OPT_88_COLORS
650d522f475Smrg# include <88colres.h>
651d522f475Smrg#endif
652d522f475Smrg#endif				/* !OPT_COLOR_RES2 */
653d522f475Smrg
654d522f475Smrg#endif				/* OPT_ISO_COLORS */
655d522f475Smrg
65620d2c4d2Smrg    CLICK_RES("2", screen.onClick[1], "word"),
65720d2c4d2Smrg    CLICK_RES("3", screen.onClick[2], "line"),
65820d2c4d2Smrg    CLICK_RES("4", screen.onClick[3], 0),
65920d2c4d2Smrg    CLICK_RES("5", screen.onClick[4], 0),
66020d2c4d2Smrg
661d522f475Smrg#if OPT_MOD_FKEYS
662d522f475Smrg    Ires(XtNmodifyCursorKeys, XtCModifyCursorKeys,
663d522f475Smrg	 keyboard.modify_1st.cursor_keys, 2),
664d522f475Smrg    Ires(XtNmodifyFunctionKeys, XtCModifyFunctionKeys,
665d522f475Smrg	 keyboard.modify_1st.function_keys, 2),
666d522f475Smrg    Ires(XtNmodifyKeypadKeys, XtCModifyKeypadKeys,
667d522f475Smrg	 keyboard.modify_1st.keypad_keys, 0),
668d522f475Smrg    Ires(XtNmodifyOtherKeys, XtCModifyOtherKeys,
669d522f475Smrg	 keyboard.modify_1st.other_keys, 0),
670d522f475Smrg    Ires(XtNmodifyStringKeys, XtCModifyStringKeys,
671d522f475Smrg	 keyboard.modify_1st.string_keys, 0),
672d522f475Smrg    Ires(XtNformatOtherKeys, XtCFormatOtherKeys,
673d522f475Smrg	 keyboard.format_keys, 0),
674d522f475Smrg#endif
675d522f475Smrg
676d522f475Smrg#if OPT_NUM_LOCK
677d522f475Smrg    Bres(XtNalwaysUseMods, XtCAlwaysUseMods, misc.alwaysUseMods, False),
678d522f475Smrg    Bres(XtNnumLock, XtCNumLock, misc.real_NumLock, True),
679d522f475Smrg#endif
680d522f475Smrg
681d522f475Smrg#if OPT_PRINT_COLORS
682d522f475Smrg    Ires(XtNprintAttributes, XtCPrintAttributes, screen.print_attributes, 1),
683d522f475Smrg#endif
684d522f475Smrg
685d522f475Smrg#if OPT_SHIFT_FONTS
686d522f475Smrg    Bres(XtNshiftFonts, XtCShiftFonts, misc.shift_fonts, True),
687d522f475Smrg#endif
688d522f475Smrg
689d522f475Smrg#if OPT_SUNPC_KBD
690d522f475Smrg    Ires(XtNctrlFKeys, XtCCtrlFKeys, misc.ctrl_fkeys, 10),
691d522f475Smrg#endif
692d522f475Smrg
693d522f475Smrg#if OPT_TEK4014
694d522f475Smrg    Bres(XtNtekInhibit, XtCTekInhibit, misc.tekInhibit, False),
695d522f475Smrg    Bres(XtNtekSmall, XtCTekSmall, misc.tekSmall, False),
696d522f475Smrg    Bres(XtNtekStartup, XtCTekStartup, misc.TekEmu, False),
697d522f475Smrg#endif
698d522f475Smrg
699d522f475Smrg#if OPT_TOOLBAR
700d522f475Smrg    Wres(XtNmenuBar, XtCMenuBar, VT100_TB_INFO(menu_bar), 0),
701d522f475Smrg    Ires(XtNmenuHeight, XtCMenuHeight, VT100_TB_INFO(menu_height), 25),
702d522f475Smrg#endif
703d522f475Smrg
704d522f475Smrg#if OPT_WIDE_CHARS
705d522f475Smrg    Bres(XtNcjkWidth, XtCCjkWidth, misc.cjk_width, False),
706d522f475Smrg    Bres(XtNmkWidth, XtCMkWidth, misc.mk_width, False),
707d522f475Smrg    Bres(XtNutf8Latin1, XtCUtf8Latin1, screen.utf8_latin1, False),
708d522f475Smrg    Bres(XtNutf8Title, XtCUtf8Title, screen.utf8_title, False),
709d522f475Smrg    Bres(XtNvt100Graphics, XtCVT100Graphics, screen.vt100_graphics, True),
710d522f475Smrg    Bres(XtNwideChars, XtCWideChars, screen.wide_chars, False),
711d522f475Smrg    Ires(XtNcombiningChars, XtCCombiningChars, screen.max_combining, 2),
712d522f475Smrg    Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 256),
713d522f475Smrg    Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 1024),
714d522f475Smrg    Ires(XtNutf8, XtCUtf8, screen.utf8_mode, uDefault),
715d522f475Smrg    Sres(XtNwideBoldFont, XtCWideBoldFont, misc.default_font.f_wb, DEFWIDEBOLDFONT),
716d522f475Smrg    Sres(XtNwideFont, XtCWideFont, misc.default_font.f_w, DEFWIDEFONT),
717956cc18dSsnj    Sres(XtNutf8SelectTypes, XtCUtf8SelectTypes, screen.utf8_select_types, NULL),
718d522f475Smrg#endif
719d522f475Smrg
720d522f475Smrg#if OPT_LUIT_PROG
721d522f475Smrg    Sres(XtNlocale, XtCLocale, misc.locale_str, "medium"),
722d522f475Smrg    Sres(XtNlocaleFilter, XtCLocaleFilter, misc.localefilter, DEFLOCALEFILTER),
723d522f475Smrg#endif
724d522f475Smrg
725d522f475Smrg#if OPT_INPUT_METHOD
726d522f475Smrg    Sres(XtNximFont, XtCXimFont, misc.f_x, DEFXIMFONT),
727d522f475Smrg#endif
728d522f475Smrg
72920d2c4d2Smrg#if OPT_SCROLL_LOCK
73020d2c4d2Smrg    Bres(XtNallowScrollLock, XtCAllowScrollLock, screen.allowScrollLock0, False),
73120d2c4d2Smrg#endif
73220d2c4d2Smrg
733d522f475Smrg#if OPT_XMC_GLITCH
734d522f475Smrg    Bres(XtNxmcInline, XtCXmcInline, screen.xmc_inline, False),
735d522f475Smrg    Bres(XtNxmcMoveSGR, XtCXmcMoveSGR, screen.move_sgr_ok, True),
736d522f475Smrg    Ires(XtNxmcAttributes, XtCXmcAttributes, screen.xmc_attributes, 1),
737d522f475Smrg    Ires(XtNxmcGlitch, XtCXmcGlitch, screen.xmc_glitch, 0),
738d522f475Smrg#endif
739d522f475Smrg
740d522f475Smrg#ifdef SCROLLBAR_RIGHT
741d522f475Smrg    Bres(XtNrightScrollBar, XtCRightScrollBar, misc.useRight, False),
742d522f475Smrg#endif
743d522f475Smrg
744d522f475Smrg#if OPT_RENDERFONT
745d522f475Smrg#define RES_FACESIZE(n) Dres(XtNfaceSize #n, XtCFaceSize #n, misc.face_size[n], "0.0")
746d522f475Smrg    RES_FACESIZE(1),
747d522f475Smrg    RES_FACESIZE(2),
748d522f475Smrg    RES_FACESIZE(3),
749d522f475Smrg    RES_FACESIZE(4),
750d522f475Smrg    RES_FACESIZE(5),
751d522f475Smrg    RES_FACESIZE(6),
752d522f475Smrg    Dres(XtNfaceSize, XtCFaceSize, misc.face_size[0], DEFFACESIZE),
753d522f475Smrg    Sres(XtNfaceName, XtCFaceName, misc.face_name, DEFFACENAME),
754d522f475Smrg    Sres(XtNfaceNameDoublesize, XtCFaceNameDoublesize, misc.face_wide_name, DEFFACENAME),
75520d2c4d2Smrg    Sres(XtNrenderFont, XtCRenderFont, misc.render_font_s, "default"),
756d522f475Smrg#endif
757d522f475Smrg};
758d522f475Smrg
759d522f475Smrgstatic Boolean VTSetValues(Widget cur, Widget request, Widget new_arg,
760d522f475Smrg			   ArgList args, Cardinal *num_args);
761d522f475Smrgstatic void VTClassInit(void);
762d522f475Smrgstatic void VTDestroy(Widget w);
763d522f475Smrgstatic void VTExpose(Widget w, XEvent * event, Region region);
764d522f475Smrgstatic void VTInitialize(Widget wrequest, Widget new_arg, ArgList args,
765d522f475Smrg			 Cardinal *num_args);
766d522f475Smrgstatic void VTRealize(Widget w, XtValueMask * valuemask,
767d522f475Smrg		      XSetWindowAttributes * values);
768d522f475Smrgstatic void VTResize(Widget w);
769d522f475Smrg
770d522f475Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
771956cc18dSsnjstatic void VTInitI18N(XtermWidget);
772d522f475Smrg#endif
773d522f475Smrg
774d522f475Smrg#ifdef VMS
775d522f475Smrgglobaldef {
776d522f475Smrg    "xtermclassrec"
777d522f475Smrg} noshare
778d522f475Smrg
779d522f475Smrg#else
780d522f475Smrgstatic
781d522f475Smrg#endif				/* VMS */
782d522f475SmrgWidgetClassRec xtermClassRec =
783d522f475Smrg{
784d522f475Smrg    {
78520d2c4d2Smrg	/* core_class fields */
78620d2c4d2Smrg	(WidgetClass) & widgetClassRec,		/* superclass   */
787d522f475Smrg	"VT100",		/* class_name                   */
788d522f475Smrg	sizeof(XtermWidgetRec),	/* widget_size                  */
789d522f475Smrg	VTClassInit,		/* class_initialize             */
790d522f475Smrg	NULL,			/* class_part_initialize        */
791d522f475Smrg	False,			/* class_inited                 */
792d522f475Smrg	VTInitialize,		/* initialize                   */
793d522f475Smrg	NULL,			/* initialize_hook              */
794d522f475Smrg	VTRealize,		/* realize                      */
795d522f475Smrg	actionsList,		/* actions                      */
796d522f475Smrg	XtNumber(actionsList),	/* num_actions                  */
79720d2c4d2Smrg	xterm_resources,	/* resources                    */
79820d2c4d2Smrg	XtNumber(xterm_resources),	/* num_resources        */
799d522f475Smrg	NULLQUARK,		/* xrm_class                    */
800d522f475Smrg	True,			/* compress_motion              */
801d522f475Smrg	False,			/* compress_exposure            */
802d522f475Smrg	True,			/* compress_enterleave          */
803d522f475Smrg	False,			/* visible_interest             */
804d522f475Smrg	VTDestroy,		/* destroy                      */
805d522f475Smrg	VTResize,		/* resize                       */
806d522f475Smrg	VTExpose,		/* expose                       */
807d522f475Smrg	VTSetValues,		/* set_values                   */
808d522f475Smrg	NULL,			/* set_values_hook              */
809d522f475Smrg	XtInheritSetValuesAlmost,	/* set_values_almost    */
810d522f475Smrg	NULL,			/* get_values_hook              */
811d522f475Smrg	NULL,			/* accept_focus                 */
812d522f475Smrg	XtVersion,		/* version                      */
813d522f475Smrg	NULL,			/* callback_offsets             */
814d522f475Smrg	defaultTranslations,	/* tm_table                     */
815d522f475Smrg	XtInheritQueryGeometry,	/* query_geometry               */
816d522f475Smrg	XtInheritDisplayAccelerator,	/* display_accelerator  */
817d522f475Smrg	NULL			/* extension                    */
818d522f475Smrg    }
819d522f475Smrg};
820d522f475Smrg
821d522f475Smrg#ifdef VMS
822d522f475Smrgglobaldef {
823d522f475Smrg    "xtermwidgetclass"
824d522f475Smrg}
825d522f475Smrgnoshare
826d522f475Smrg#endif /* VMS */
827d522f475SmrgWidgetClass xtermWidgetClass = (WidgetClass) & xtermClassRec;
828d522f475Smrg
829d522f475Smrg/*
830d522f475Smrg * Add input-actions for widgets that are overlooked (scrollbar and toolbar):
831d522f475Smrg *
832d522f475Smrg *	a) Sometimes the scrollbar passes through translations, sometimes it
833d522f475Smrg *	   doesn't.  We add the KeyPress translations here, just to be sure.
834d522f475Smrg *	b) In the normal (non-toolbar) configuration, the xterm widget covers
835d522f475Smrg *	   almost all of the window.  With a toolbar, there's a relatively
836d522f475Smrg *	   large area that the user would expect to enter keystrokes since the
837d522f475Smrg *	   program can get the focus.
838d522f475Smrg */
839d522f475Smrgvoid
840d522f475SmrgxtermAddInput(Widget w)
841d522f475Smrg{
842d522f475Smrg    /* *INDENT-OFF* */
843d522f475Smrg    XtActionsRec input_actions[] = {
844d522f475Smrg	{ "insert",		    HandleKeyPressed }, /* alias */
845d522f475Smrg	{ "insert-eight-bit",	    HandleEightBitKeyPressed },
846d522f475Smrg	{ "insert-seven-bit",	    HandleKeyPressed },
847d522f475Smrg	{ "secure",		    HandleSecure },
848d522f475Smrg	{ "string",		    HandleStringEvent },
849d522f475Smrg	{ "scroll-back",	    HandleScrollBack },
850d522f475Smrg	{ "scroll-forw",	    HandleScrollForward },
851d522f475Smrg	{ "select-cursor-end",	    HandleKeyboardSelectEnd },
852d522f475Smrg	{ "select-cursor-extend",   HandleKeyboardSelectExtend },
853d522f475Smrg	{ "select-cursor-start",    HandleKeyboardSelectStart },
854d522f475Smrg	{ "insert-selection",	    HandleInsertSelection },
855d522f475Smrg	{ "select-start",	    HandleSelectStart },
856d522f475Smrg	{ "select-extend",	    HandleSelectExtend },
857d522f475Smrg	{ "start-extend",	    HandleStartExtend },
858d522f475Smrg	{ "select-end",		    HandleSelectEnd },
859d522f475Smrg	{ "clear-saved-lines",	    HandleClearSavedLines },
860d522f475Smrg	{ "popup-menu",		    HandlePopupMenu },
861d522f475Smrg	{ "bell",		    HandleBell },
862d522f475Smrg	{ "ignore",		    HandleIgnore },
863d522f475Smrg#if OPT_DABBREV
864d522f475Smrg	{ "dabbrev-expand",	    HandleDabbrevExpand },
865d522f475Smrg#endif
86620d2c4d2Smrg#if OPT_SCROLL_LOCK
86720d2c4d2Smrg	{ "scroll-lock",	    HandleScrollLock },
86820d2c4d2Smrg#endif
869d522f475Smrg#if OPT_SHIFT_FONTS
870d522f475Smrg	{ "larger-vt-font",	    HandleLargerFont },
871d522f475Smrg	{ "smaller-vt-font",	    HandleSmallerFont },
872d522f475Smrg#endif
873d522f475Smrg    };
874d522f475Smrg    /* *INDENT-ON* */
875d522f475Smrg
876956cc18dSsnj    TRACE_TRANS("BEFORE", w);
877d522f475Smrg    XtAppAddActions(app_con, input_actions, XtNumber(input_actions));
878d522f475Smrg    XtAugmentTranslations(w, XtParseTranslationTable(defaultTranslations));
879956cc18dSsnj    TRACE_TRANS("AFTER:", w);
880d522f475Smrg
881d522f475Smrg#if OPT_EXTRA_PASTE
882d522f475Smrg    if (term && term->keyboard.extra_translations)
883d522f475Smrg	XtOverrideTranslations((Widget) term, XtParseTranslationTable(term->keyboard.extra_translations));
884d522f475Smrg#endif
885d522f475Smrg}
886d522f475Smrg
887d522f475Smrg#if OPT_ISO_COLORS
888956cc18dSsnj#ifdef EXP_BOGUS_FG
889956cc18dSsnjstatic Bool
890956cc18dSsnjCheckBogusForeground(TScreen * screen, const char *tag)
891956cc18dSsnj{
892956cc18dSsnj    int row = -1, col = -1, pass;
893956cc18dSsnj    Bool isClear = True;
894956cc18dSsnj
895956cc18dSsnj    (void) tag;
896956cc18dSsnj    for (pass = 0; pass < 2; ++pass) {
897956cc18dSsnj	row = screen->cur_row;
898956cc18dSsnj	for (; isClear && (row <= screen->max_row); ++row) {
899956cc18dSsnj	    LineData *ld = getLineData(screen, row)->;
90020d2c4d2Smrg
90120d2c4d2Smrg	    if (ld != 0) {
90220d2c4d2Smrg		Char *attribs = ld->attribs;
90320d2c4d2Smrg
90420d2c4d2Smrg		col = (row == screen->cur_row) ? screen->cur_col : 0;
90520d2c4d2Smrg		for (; isClear && (col <= screen->max_col); ++col) {
90620d2c4d2Smrg		    unsigned flags = attribs[col];
90720d2c4d2Smrg		    if (pass) {
90820d2c4d2Smrg			flags &= ~FG_COLOR;
90920d2c4d2Smrg			attribs[col] = (Char) flags;
91020d2c4d2Smrg		    } else if ((flags & BG_COLOR)) {
91120d2c4d2Smrg			isClear = False;
91220d2c4d2Smrg		    } else if ((flags & FG_COLOR)) {
91320d2c4d2Smrg			unsigned ch = ld->charData[col];
91420d2c4d2Smrg			isClear = ((ch == ' ') || (ch == 0));
91520d2c4d2Smrg		    } else {
91620d2c4d2Smrg			isClear = False;
91720d2c4d2Smrg		    }
918956cc18dSsnj		}
919956cc18dSsnj	    }
920956cc18dSsnj	}
921956cc18dSsnj    }
922956cc18dSsnj    TRACE(("%s checked %d,%d to %d,%d %s pass %d\n",
923956cc18dSsnj	   tag, screen->cur_row, screen->cur_col,
924956cc18dSsnj	   row, col,
925956cc18dSsnj	   isClear && pass ? "cleared" : "unchanged",
926956cc18dSsnj	   pass));
927956cc18dSsnj
928956cc18dSsnj    return isClear;
929956cc18dSsnj}
930956cc18dSsnj#endif
931956cc18dSsnj
932d522f475Smrg/*
933d522f475Smrg * The terminal's foreground and background colors are set via two mechanisms:
934d522f475Smrg *	text (cur_foreground, cur_background values that are passed down to
935d522f475Smrg *		XDrawImageString and XDrawString)
936d522f475Smrg *	area (X11 graphics context used in XClearArea and XFillRectangle)
937d522f475Smrg */
938d522f475Smrgvoid
939d522f475SmrgSGR_Foreground(XtermWidget xw, int color)
940d522f475Smrg{
94120d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
942d522f475Smrg    Pixel fg;
943d522f475Smrg
944d522f475Smrg    if (color >= 0) {
94520d2c4d2Smrg	UIntSet(xw->flags, FG_COLOR);
946d522f475Smrg    } else {
94720d2c4d2Smrg	UIntClr(xw->flags, FG_COLOR);
948d522f475Smrg    }
949d522f475Smrg    fg = getXtermForeground(xw, xw->flags, color);
950d522f475Smrg    xw->cur_foreground = color;
951d522f475Smrg
952d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcNorm, fg);
953d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcNormReverse, fg);
954d522f475Smrg
955d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcBold, fg);
956d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcBoldReverse, fg);
957956cc18dSsnj
958956cc18dSsnj#ifdef EXP_BOGUS_FG
959956cc18dSsnj    /*
960956cc18dSsnj     * If we've just turned off the foreground color, check for blank cells
961956cc18dSsnj     * which have no background color, but do have foreground color.  This
962956cc18dSsnj     * could happen due to setting the foreground color just before scrolling.
963956cc18dSsnj     *
964956cc18dSsnj     * Those cells look uncolored, but will confuse ShowCursor(), which looks
96520d2c4d2Smrg     * for the colors in the current cell, and will see the foreground color.
966956cc18dSsnj     * In that case, remove the foreground color from the blank cells.
967956cc18dSsnj     */
968956cc18dSsnj    if (color < 0) {
969956cc18dSsnj	CheckBogusForeground(screen, "SGR_Foreground");
970956cc18dSsnj    }
971956cc18dSsnj#endif
972d522f475Smrg}
973d522f475Smrg
974d522f475Smrgvoid
975d522f475SmrgSGR_Background(XtermWidget xw, int color)
976d522f475Smrg{
97720d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
978d522f475Smrg    Pixel bg;
979d522f475Smrg
980d522f475Smrg    /*
981d522f475Smrg     * An indexing operation may have set screen->scroll_amt, which would
982d522f475Smrg     * normally result in calling FlushScroll() in WriteText().  However,
983d522f475Smrg     * if we're changing the background color now, then the new value
984d522f475Smrg     * should not apply to the pending blank lines.
985d522f475Smrg     */
986d522f475Smrg    if (screen->scroll_amt && (color != xw->cur_background))
987d522f475Smrg	FlushScroll(xw);
988d522f475Smrg
989d522f475Smrg    if (color >= 0) {
99020d2c4d2Smrg	UIntSet(xw->flags, BG_COLOR);
991d522f475Smrg    } else {
99220d2c4d2Smrg	UIntClr(xw->flags, BG_COLOR);
993d522f475Smrg    }
994d522f475Smrg    bg = getXtermBackground(xw, xw->flags, color);
995d522f475Smrg    xw->cur_background = color;
996d522f475Smrg
997d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcNorm, bg);
998d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcNormReverse, bg);
999d522f475Smrg
1000d522f475Smrg    setCgsBack(xw, WhichVWin(screen), gcBold, bg);
1001d522f475Smrg    setCgsFore(xw, WhichVWin(screen), gcBoldReverse, bg);
1002d522f475Smrg}
1003d522f475Smrg
1004d522f475Smrg/* Invoked after updating bold/underline flags, computes the extended color
1005d522f475Smrg * index to use for foreground.  (See also 'extract_fg()').
1006d522f475Smrg */
1007d522f475Smrgstatic void
1008d522f475SmrgsetExtendedFG(XtermWidget xw)
1009d522f475Smrg{
1010d522f475Smrg    int fg = xw->sgr_foreground;
1011d522f475Smrg
101220d2c4d2Smrg    if (TScreenOf(xw)->colorAttrMode
1013d522f475Smrg	|| (fg < 0)) {
101420d2c4d2Smrg	fg = MapToColorMode(fg, TScreenOf(xw), xw->flags);
1015d522f475Smrg    }
1016d522f475Smrg
1017d522f475Smrg    /* This implements the IBM PC-style convention of 8-colors, with one
1018d522f475Smrg     * bit for bold, thus mapping the 0-7 codes to 8-15.  It won't make
1019d522f475Smrg     * much sense for 16-color applications, but we keep it to retain
1020d522f475Smrg     * compatiblity with ANSI-color applications.
1021d522f475Smrg     */
1022d522f475Smrg#if OPT_PC_COLORS		/* XXXJTL should be settable at runtime (resource or OSC?) */
102320d2c4d2Smrg    if (TScreenOf(xw)->boldColors
1024d522f475Smrg	&& (!xw->sgr_extended)
1025d522f475Smrg	&& (fg >= 0)
1026d522f475Smrg	&& (fg < 8)
1027d522f475Smrg	&& (xw->flags & BOLD))
1028d522f475Smrg	fg |= 8;
1029d522f475Smrg#endif
1030d522f475Smrg
1031d522f475Smrg    SGR_Foreground(xw, fg);
1032d522f475Smrg}
1033d522f475Smrg
1034d522f475Smrg/* Invoked after updating inverse flag, computes the extended color
1035d522f475Smrg * index to use for background.  (See also 'extract_bg()').
1036d522f475Smrg */
1037d522f475Smrgstatic void
1038d522f475SmrgsetExtendedBG(XtermWidget xw)
1039d522f475Smrg{
1040d522f475Smrg    int bg = xw->sgr_background;
1041d522f475Smrg
104220d2c4d2Smrg    if (TScreenOf(xw)->colorAttrMode
1043d522f475Smrg	|| (bg < 0)) {
104420d2c4d2Smrg	if (TScreenOf(xw)->colorRVMode && (xw->flags & INVERSE))
1045d522f475Smrg	    bg = COLOR_RV;
1046d522f475Smrg    }
1047d522f475Smrg
1048d522f475Smrg    SGR_Background(xw, bg);
1049d522f475Smrg}
1050d522f475Smrg
1051d522f475Smrgstatic void
1052d522f475Smrgreset_SGR_Foreground(XtermWidget xw)
1053d522f475Smrg{
1054d522f475Smrg    xw->sgr_foreground = -1;
1055d522f475Smrg    xw->sgr_extended = False;
1056d522f475Smrg    setExtendedFG(xw);
1057d522f475Smrg}
1058d522f475Smrg
1059d522f475Smrgstatic void
1060d522f475Smrgreset_SGR_Background(XtermWidget xw)
1061d522f475Smrg{
1062d522f475Smrg    xw->sgr_background = -1;
1063d522f475Smrg    setExtendedBG(xw);
1064d522f475Smrg}
1065d522f475Smrg
1066d522f475Smrgstatic void
1067d522f475Smrgreset_SGR_Colors(XtermWidget xw)
1068d522f475Smrg{
1069d522f475Smrg    reset_SGR_Foreground(xw);
1070d522f475Smrg    reset_SGR_Background(xw);
1071d522f475Smrg}
1072d522f475Smrg#endif /* OPT_ISO_COLORS */
1073d522f475Smrg
1074d522f475Smrgvoid
1075d522f475SmrgresetCharsets(TScreen * screen)
1076d522f475Smrg{
1077d522f475Smrg    TRACE(("resetCharsets\n"));
1078d522f475Smrg
1079d522f475Smrg    screen->gsets[0] = 'B';	/* ASCII_G              */
1080d522f475Smrg    screen->gsets[1] = 'B';	/* ASCII_G              */
1081d522f475Smrg    screen->gsets[2] = 'B';	/* ASCII_G              */
1082d522f475Smrg    screen->gsets[3] = 'B';	/* ASCII_G              */
1083d522f475Smrg
1084d522f475Smrg    screen->curgl = 0;		/* G0 => GL.            */
1085d522f475Smrg    screen->curgr = 2;		/* G2 => GR.            */
1086d522f475Smrg    screen->curss = 0;		/* No single shift.     */
1087d522f475Smrg
1088d522f475Smrg#if OPT_VT52_MODE
1089d522f475Smrg    if (screen->vtXX_level == 0)
1090d522f475Smrg	screen->gsets[1] = '0';	/* Graphics             */
1091d522f475Smrg#endif
1092d522f475Smrg}
1093d522f475Smrg
1094d522f475Smrg/*
1095d522f475Smrg * VT300 and up support three ANSI conformance levels, defined according to
1096d522f475Smrg * the dpANSI X3.134.1 standard.  DEC's manuals equate levels 1 and 2, and
1097d522f475Smrg * are unclear.  This code is written based on the manuals.
1098d522f475Smrg */
1099d522f475Smrgstatic void
1100d522f475Smrgset_ansi_conformance(TScreen * screen, int level)
1101d522f475Smrg{
1102d522f475Smrg    TRACE(("set_ansi_conformance(%d) terminal_id %d, ansi_level %d\n",
1103d522f475Smrg	   level,
1104d522f475Smrg	   screen->terminal_id,
1105d522f475Smrg	   screen->ansi_level));
1106d522f475Smrg    if (screen->vtXX_level >= 3) {
1107d522f475Smrg	switch (screen->ansi_level = level) {
1108d522f475Smrg	case 1:
1109d522f475Smrg	    /* FALLTHRU */
1110d522f475Smrg	case 2:
1111d522f475Smrg	    screen->gsets[0] = 'B';	/* G0 is ASCII */
1112d522f475Smrg	    screen->gsets[1] = 'B';	/* G1 is ISO Latin-1 (FIXME) */
1113d522f475Smrg	    screen->curgl = 0;
1114d522f475Smrg	    screen->curgr = 1;
1115d522f475Smrg	    break;
1116d522f475Smrg	case 3:
1117d522f475Smrg	    screen->gsets[0] = 'B';	/* G0 is ASCII */
1118d522f475Smrg	    screen->curgl = 0;
1119d522f475Smrg	    break;
1120d522f475Smrg	}
1121d522f475Smrg    }
1122d522f475Smrg}
1123d522f475Smrg
1124d522f475Smrg/*
1125d522f475Smrg * Set scrolling margins.  VTxxx terminals require that the top/bottom are
1126d522f475Smrg * different, so we have at least two lines in the scrolling region.
1127d522f475Smrg */
1128d522f475Smrgvoid
1129d522f475Smrgset_tb_margins(TScreen * screen, int top, int bottom)
1130d522f475Smrg{
1131d522f475Smrg    TRACE(("set_tb_margins %d..%d, prior %d..%d\n",
1132d522f475Smrg	   top, bottom,
1133d522f475Smrg	   screen->top_marg,
1134d522f475Smrg	   screen->bot_marg));
1135d522f475Smrg    if (bottom > top) {
1136d522f475Smrg	screen->top_marg = top;
1137d522f475Smrg	screen->bot_marg = bottom;
1138d522f475Smrg    }
1139d522f475Smrg    if (screen->top_marg > screen->max_row)
1140d522f475Smrg	screen->top_marg = screen->max_row;
1141d522f475Smrg    if (screen->bot_marg > screen->max_row)
1142d522f475Smrg	screen->bot_marg = screen->max_row;
1143d522f475Smrg}
1144d522f475Smrg
1145d522f475Smrgvoid
1146d522f475Smrgset_max_col(TScreen * screen, int cols)
1147d522f475Smrg{
1148d522f475Smrg    TRACE(("set_max_col %d, prior %d\n", cols, screen->max_col));
1149d522f475Smrg    if (cols < 0)
1150d522f475Smrg	cols = 0;
1151d522f475Smrg    screen->max_col = cols;
1152d522f475Smrg}
1153d522f475Smrg
1154d522f475Smrgvoid
1155d522f475Smrgset_max_row(TScreen * screen, int rows)
1156d522f475Smrg{
1157d522f475Smrg    TRACE(("set_max_row %d, prior %d\n", rows, screen->max_row));
1158d522f475Smrg    if (rows < 0)
1159d522f475Smrg	rows = 0;
1160d522f475Smrg    screen->max_row = rows;
1161d522f475Smrg}
1162d522f475Smrg
1163d522f475Smrg#if OPT_MOD_FKEYS
1164d522f475Smrgstatic void
1165d522f475Smrgset_mod_fkeys(XtermWidget xw, int which, int what, Bool enabled)
1166d522f475Smrg{
1167d522f475Smrg#define SET_MOD_FKEYS(field) \
1168d522f475Smrg    xw->keyboard.modify_now.field = ((what == DEFAULT) && enabled) \
1169d522f475Smrg				     ? xw->keyboard.modify_1st.field \
1170d522f475Smrg				     : what; \
1171d522f475Smrg    TRACE(("set modify_now.%s to %d\n", #field, \
1172d522f475Smrg	   xw->keyboard.modify_now.field));
1173d522f475Smrg
1174d522f475Smrg    switch (which) {
1175d522f475Smrg    case 1:
1176d522f475Smrg	SET_MOD_FKEYS(cursor_keys);
1177d522f475Smrg	break;
1178d522f475Smrg    case 2:
1179d522f475Smrg	SET_MOD_FKEYS(function_keys);
1180d522f475Smrg	break;
1181d522f475Smrg    case 3:
1182d522f475Smrg	SET_MOD_FKEYS(keypad_keys);
1183d522f475Smrg	break;
1184d522f475Smrg    case 4:
1185d522f475Smrg	SET_MOD_FKEYS(other_keys);
1186d522f475Smrg	break;
1187d522f475Smrg    case 5:
1188d522f475Smrg	SET_MOD_FKEYS(string_keys);
1189d522f475Smrg	break;
1190d522f475Smrg    }
1191d522f475Smrg}
1192d522f475Smrg#endif /* OPT_MOD_FKEYS */
1193d522f475Smrg
1194d522f475Smrg#if OPT_TRACE
1195d522f475Smrg#define WHICH_TABLE(name) if (table == name) result = #name
119620d2c4d2Smrgstatic const char *
1197d522f475Smrgwhich_table(Const PARSE_T * table)
1198d522f475Smrg{
119920d2c4d2Smrg    const char *result = "?";
1200d522f475Smrg    /* *INDENT-OFF* */
1201d522f475Smrg    WHICH_TABLE (ansi_table);
12022eaa94a1Schristos    else WHICH_TABLE (cigtable);
1203d522f475Smrg    else WHICH_TABLE (csi2_table);
1204d522f475Smrg    else WHICH_TABLE (csi_ex_table);
1205d522f475Smrg    else WHICH_TABLE (csi_quo_table);
12062eaa94a1Schristos    else WHICH_TABLE (csi_table);
1207d522f475Smrg    else WHICH_TABLE (dec2_table);
1208d522f475Smrg    else WHICH_TABLE (dec3_table);
12092eaa94a1Schristos    else WHICH_TABLE (dec_table);
1210d522f475Smrg    else WHICH_TABLE (eigtable);
1211d522f475Smrg    else WHICH_TABLE (esc_sp_table);
12122eaa94a1Schristos    else WHICH_TABLE (esc_table);
1213d522f475Smrg    else WHICH_TABLE (scrtable);
12142eaa94a1Schristos    else WHICH_TABLE (scs96table);
1215d522f475Smrg    else WHICH_TABLE (scstable);
1216d522f475Smrg    else WHICH_TABLE (sos_table);
121720d2c4d2Smrg#if OPT_BLINK_CURS
121820d2c4d2Smrg    else WHICH_TABLE (csi_sp_table);
121920d2c4d2Smrg#endif
12202eaa94a1Schristos#if OPT_DEC_LOCATOR
12212eaa94a1Schristos    else WHICH_TABLE (csi_tick_table);
12222eaa94a1Schristos#endif
12232eaa94a1Schristos#if OPT_DEC_RECTOPS
12242eaa94a1Schristos    else WHICH_TABLE (csi_dollar_table);
12252eaa94a1Schristos    else WHICH_TABLE (csi_star_table);
12262eaa94a1Schristos#endif
1227d522f475Smrg#if OPT_WIDE_CHARS
1228d522f475Smrg    else WHICH_TABLE (esc_pct_table);
1229d522f475Smrg#endif
1230d522f475Smrg#if OPT_VT52_MODE
1231d522f475Smrg    else WHICH_TABLE (vt52_table);
1232d522f475Smrg    else WHICH_TABLE (vt52_esc_table);
1233d522f475Smrg    else WHICH_TABLE (vt52_ignore_table);
1234d522f475Smrg#endif
1235d522f475Smrg    /* *INDENT-ON* */
1236d522f475Smrg
1237d522f475Smrg    return result;
1238d522f475Smrg}
1239d522f475Smrg#endif
1240d522f475Smrg
1241d522f475Smrg	/* allocate larger buffer if needed/possible */
1242d522f475Smrg#define SafeAlloc(type, area, used, size) \
1243d522f475Smrg		type *new_string = area; \
124420d2c4d2Smrg		size_t new_length = size; \
1245d522f475Smrg		if (new_length == 0) { \
1246d522f475Smrg		    new_length = 256; \
1247d522f475Smrg		    new_string = TypeMallocN(type, new_length); \
1248d522f475Smrg		} else if (used+1 >= new_length) { \
1249d522f475Smrg		    new_length = size * 2; \
1250d522f475Smrg		    new_string = TypeMallocN(type, new_length); \
1251d522f475Smrg		    if (new_string != 0 \
1252d522f475Smrg		     && area != 0 \
1253d522f475Smrg		     && used != 0) \
1254d522f475Smrg			memcpy(new_string, area, used * sizeof(type)); \
1255d522f475Smrg		}
1256d522f475Smrg
1257d522f475Smrg#define WriteNow() {						\
1258d522f475Smrg	    unsigned single = 0;				\
1259d522f475Smrg								\
1260d522f475Smrg	    if (screen->curss) {				\
1261d522f475Smrg		dotext(xw,					\
1262d522f475Smrg		       screen->gsets[(int) (screen->curss)],	\
1263956cc18dSsnj		       sp->print_area,				\
1264956cc18dSsnj		       (Cardinal) 1);				\
1265d522f475Smrg		screen->curss = 0;				\
1266d522f475Smrg		single++;					\
1267d522f475Smrg	    }							\
1268956cc18dSsnj	    if (sp->print_used > single) {			\
1269d522f475Smrg		dotext(xw,					\
1270d522f475Smrg		       screen->gsets[(int) (screen->curgl)],	\
1271956cc18dSsnj		       sp->print_area + single,			\
1272956cc18dSsnj		       (Cardinal) (sp->print_used - single));	\
1273d522f475Smrg	    }							\
1274956cc18dSsnj	    sp->print_used = 0;					\
1275d522f475Smrg	}							\
1276d522f475Smrg
1277d522f475Smrgstruct ParseState {
1278d522f475Smrg#if OPT_VT52_MODE
1279d522f475Smrg    Bool vt52_cup;
1280d522f475Smrg#endif
1281d522f475Smrg    Const PARSE_T *groundtable;
1282d522f475Smrg    Const PARSE_T *parsestate;
1283d522f475Smrg    int scstype;
12842eaa94a1Schristos    int scssize;
1285d522f475Smrg    Bool private_function;	/* distinguish private-mode from standard */
1286d522f475Smrg    int string_mode;		/* nonzero iff we're processing a string */
1287d522f475Smrg    int lastchar;		/* positive iff we had a graphic character */
1288d522f475Smrg    int nextstate;
1289d522f475Smrg#if OPT_WIDE_CHARS
1290d522f475Smrg    int last_was_wide;
1291d522f475Smrg#endif
1292956cc18dSsnj    /* Buffer for processing printable text */
1293956cc18dSsnj    IChar *print_area;
1294956cc18dSsnj    size_t print_size;
1295956cc18dSsnj    size_t print_used;
1296956cc18dSsnj    /* Buffer for processing strings (e.g., OSC ... ST) */
1297956cc18dSsnj    Char *string_area;
1298956cc18dSsnj    size_t string_size;
1299956cc18dSsnj    size_t string_used;
1300d522f475Smrg};
1301d522f475Smrg
1302d522f475Smrgstatic struct ParseState myState;
1303d522f475Smrg
13042eaa94a1Schristosstatic void
13052eaa94a1Schristosinit_groundtable(TScreen * screen, struct ParseState *sp)
13062eaa94a1Schristos{
1307956cc18dSsnj    (void) screen;
1308956cc18dSsnj
13092eaa94a1Schristos#if OPT_VT52_MODE
13102eaa94a1Schristos    if (!(screen->vtXX_level)) {
13112eaa94a1Schristos	sp->groundtable = vt52_table;
13122eaa94a1Schristos    } else if (screen->terminal_id >= 100)
13132eaa94a1Schristos#endif
13142eaa94a1Schristos    {
13152eaa94a1Schristos	sp->groundtable = ansi_table;
13162eaa94a1Schristos    }
13172eaa94a1Schristos}
13182eaa94a1Schristos
13192eaa94a1Schristosstatic void
13202eaa94a1Schristosselect_charset(struct ParseState *sp, int type, int size)
13212eaa94a1Schristos{
13222eaa94a1Schristos    TRACE(("select_charset %#x %d\n", type, size));
13232eaa94a1Schristos    sp->scstype = type;
13242eaa94a1Schristos    sp->scssize = size;
13252eaa94a1Schristos    if (size == 94) {
13262eaa94a1Schristos	sp->parsestate = scstable;
13272eaa94a1Schristos    } else {
13282eaa94a1Schristos	sp->parsestate = scs96table;
13292eaa94a1Schristos    }
13302eaa94a1Schristos}
13312eaa94a1Schristos
133220d2c4d2Smrgstatic int
133320d2c4d2Smrgzero_if_default(int which)
133420d2c4d2Smrg{
133520d2c4d2Smrg    int result = (nparam > which) ? param[which] : 0;
133620d2c4d2Smrg    if (result <= 0)
133720d2c4d2Smrg	result = 0;
133820d2c4d2Smrg    return result;
133920d2c4d2Smrg}
134020d2c4d2Smrg
134120d2c4d2Smrgstatic int
134220d2c4d2Smrgone_if_default(int which)
134320d2c4d2Smrg{
134420d2c4d2Smrg    int result = (nparam > which) ? param[which] : 0;
134520d2c4d2Smrg    if (result <= 0)
134620d2c4d2Smrg	result = 1;
134720d2c4d2Smrg    return result;
134820d2c4d2Smrg}
134920d2c4d2Smrg
135020d2c4d2Smrg#if OPT_C1_PRINT || OPT_WIDE_CHARS
135120d2c4d2Smrg#define ParseSOS(screen) ((screen)->c1_printable == 0)
135220d2c4d2Smrg#else
135320d2c4d2Smrg#define ParseSOS(screen) 0
135420d2c4d2Smrg#endif
135520d2c4d2Smrg
135620d2c4d2Smrg#define ResetState(sp) (sp)->parsestate = (sp)->groundtable
135720d2c4d2Smrg
135820d2c4d2Smrgstatic void
135920d2c4d2Smrgillegal_parse(XtermWidget xw, unsigned c, struct ParseState *sp)
136020d2c4d2Smrg{
136120d2c4d2Smrg    ResetState(sp);
136220d2c4d2Smrg    sp->nextstate = sp->parsestate[E2A(c)];
136320d2c4d2Smrg    Bell(xw, XkbBI_MinorError, 0);
136420d2c4d2Smrg}
136520d2c4d2Smrg
1366d522f475Smrgstatic Boolean
1367d522f475Smrgdoparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
1368d522f475Smrg{
136920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
1370d522f475Smrg    int row;
1371d522f475Smrg    int col;
1372d522f475Smrg    int top;
1373d522f475Smrg    int bot;
1374d522f475Smrg    int count;
1375d522f475Smrg    int laststate;
1376d522f475Smrg    int thischar = -1;
1377d522f475Smrg    XTermRect myRect;
1378d522f475Smrg
1379d522f475Smrg    do {
1380d522f475Smrg#if OPT_WIDE_CHARS
1381956cc18dSsnj	int this_is_wide = 0;
1382d522f475Smrg
1383d522f475Smrg	/*
1384d522f475Smrg	 * Handle zero-width combining characters.  Make it faster by noting
1385d522f475Smrg	 * that according to the Unicode charts, the majority of Western
1386d522f475Smrg	 * character sets do not use this feature.  There are some unassigned
1387d522f475Smrg	 * codes at 0x242, but no zero-width characters until past 0x300.
1388d522f475Smrg	 */
1389d522f475Smrg	if (c >= 0x300 && screen->wide_chars
1390d522f475Smrg	    && my_wcwidth((int) c) == 0
1391d522f475Smrg	    && !isWideControl(c)) {
1392d522f475Smrg	    int prev, precomposed;
1393d522f475Smrg
1394d522f475Smrg	    WriteNow();
1395d522f475Smrg
13962eaa94a1Schristos	    prev = (int) XTERM_CELL(screen->last_written_row,
13972eaa94a1Schristos				    screen->last_written_col);
1398d522f475Smrg	    precomposed = do_precomposition(prev, (int) c);
1399d522f475Smrg	    TRACE(("do_precomposition (U+%04X [%d], U+%04X [%d]) -> U+%04X [%d]\n",
1400d522f475Smrg		   prev, my_wcwidth(prev),
1401d522f475Smrg		   (int) c, my_wcwidth((int) c),
1402d522f475Smrg		   precomposed, my_wcwidth(precomposed)));
1403d522f475Smrg
1404d522f475Smrg	    /* substitute combined character with precomposed character
1405d522f475Smrg	     * only if it does not change the width of the base character
1406d522f475Smrg	     */
1407d522f475Smrg	    if (precomposed != -1 && my_wcwidth(precomposed) == my_wcwidth(prev)) {
1408d522f475Smrg		putXtermCell(screen,
1409d522f475Smrg			     screen->last_written_row,
1410d522f475Smrg			     screen->last_written_col, precomposed);
1411d522f475Smrg	    } else {
1412d522f475Smrg		addXtermCombining(screen,
1413d522f475Smrg				  screen->last_written_row,
1414d522f475Smrg				  screen->last_written_col, c);
1415d522f475Smrg	    }
1416d522f475Smrg
1417d522f475Smrg	    if (!screen->scroll_amt)
1418d522f475Smrg		ScrnUpdate(xw,
1419d522f475Smrg			   screen->last_written_row,
1420d522f475Smrg			   screen->last_written_col, 1, 1, 1);
1421d522f475Smrg	    continue;
1422d522f475Smrg	}
1423d522f475Smrg#endif
1424d522f475Smrg
1425d522f475Smrg	/* Intercept characters for printer controller mode */
1426d522f475Smrg	if (screen->printer_controlmode == 2) {
1427956cc18dSsnj	    if ((c = (unsigned) xtermPrinterControl(xw, (int) c)) == 0)
1428d522f475Smrg		continue;
1429d522f475Smrg	}
1430d522f475Smrg
1431d522f475Smrg	/*
1432d522f475Smrg	 * VT52 is a little ugly in the one place it has a parameterized
1433d522f475Smrg	 * control sequence, since the parameter falls after the character
1434d522f475Smrg	 * that denotes the type of sequence.
1435d522f475Smrg	 */
1436d522f475Smrg#if OPT_VT52_MODE
1437d522f475Smrg	if (sp->vt52_cup) {
1438d522f475Smrg	    if (nparam < NPARAM)
14392eaa94a1Schristos		param[nparam++] = (int) (c & 0x7f) - 32;
1440d522f475Smrg	    if (nparam < 2)
1441d522f475Smrg		continue;
1442d522f475Smrg	    sp->vt52_cup = False;
1443d522f475Smrg	    if ((row = param[0]) < 0)
1444d522f475Smrg		row = 0;
1445d522f475Smrg	    if ((col = param[1]) < 0)
1446d522f475Smrg		col = 0;
1447d522f475Smrg	    CursorSet(screen, row, col, xw->flags);
1448d522f475Smrg	    sp->parsestate = vt52_table;
1449d522f475Smrg	    param[0] = 0;
1450d522f475Smrg	    param[1] = 0;
1451d522f475Smrg	    continue;
1452d522f475Smrg	}
1453d522f475Smrg#endif
1454d522f475Smrg
1455d522f475Smrg	laststate = sp->nextstate;
14562eaa94a1Schristos	if (c == ANSI_DEL
14572eaa94a1Schristos	    && sp->parsestate == sp->groundtable
14582eaa94a1Schristos	    && sp->scssize == 96
14592eaa94a1Schristos	    && sp->scstype != 0) {
14602eaa94a1Schristos	    /*
14612eaa94a1Schristos	     * Handle special case of shifts for 96-character sets by checking
14622eaa94a1Schristos	     * if we have a DEL.  The other special case for SPACE will always
14632eaa94a1Schristos	     * be printable.
14642eaa94a1Schristos	     */
14652eaa94a1Schristos	    sp->nextstate = CASE_PRINT;
14662eaa94a1Schristos	} else
1467d522f475Smrg#if OPT_WIDE_CHARS
1468d522f475Smrg	if (c > 255) {
14692eaa94a1Schristos	    /*
14702eaa94a1Schristos	     * The parsing tables all have 256 entries.  If we're supporting
14712eaa94a1Schristos	     * wide characters, we handle them by treating them the same as
14722eaa94a1Schristos	     * printing characters.
14732eaa94a1Schristos	     */
1474d522f475Smrg	    if (sp->parsestate == sp->groundtable) {
1475d522f475Smrg		sp->nextstate = CASE_PRINT;
1476d522f475Smrg	    } else if (sp->parsestate == sos_table) {
1477d522f475Smrg		c &= 0xffff;
1478d522f475Smrg		if (c > 255) {
1479d522f475Smrg		    TRACE(("Found code > 255 while in SOS state: %04X\n", c));
1480d522f475Smrg		    c = '?';
1481d522f475Smrg		}
1482d522f475Smrg	    } else {
1483d522f475Smrg		sp->nextstate = CASE_GROUND_STATE;
1484d522f475Smrg	    }
1485d522f475Smrg	} else
1486d522f475Smrg#endif
1487d522f475Smrg	    sp->nextstate = sp->parsestate[E2A(c)];
1488d522f475Smrg
1489d522f475Smrg#if OPT_BROKEN_OSC
1490d522f475Smrg	/*
1491d522f475Smrg	 * Linux console palette escape sequences start with an OSC, but do
1492d522f475Smrg	 * not terminate correctly.  Some scripts do not check before writing
1493d522f475Smrg	 * them, making xterm appear to hang (it's awaiting a valid string
1494d522f475Smrg	 * terminator).  Just ignore these if we see them - there's no point
1495d522f475Smrg	 * in emulating bad code.
1496d522f475Smrg	 */
1497d522f475Smrg	if (screen->brokenLinuxOSC
1498d522f475Smrg	    && sp->parsestate == sos_table) {
1499956cc18dSsnj	    if (sp->string_used) {
1500956cc18dSsnj		switch (sp->string_area[0]) {
1501d522f475Smrg		case 'P':
1502956cc18dSsnj		    if (sp->string_used <= 7)
1503d522f475Smrg			break;
1504d522f475Smrg		    /* FALLTHRU */
1505d522f475Smrg		case 'R':
150620d2c4d2Smrg		    illegal_parse(xw, c, sp);
1507d522f475Smrg		    TRACE(("Reset to ground state (brokenLinuxOSC)\n"));
1508d522f475Smrg		    break;
1509d522f475Smrg		}
1510d522f475Smrg	    }
1511d522f475Smrg	}
1512d522f475Smrg#endif
1513d522f475Smrg
1514d522f475Smrg#if OPT_BROKEN_ST
1515d522f475Smrg	/*
1516d522f475Smrg	 * Before patch #171, carriage control embedded within an OSC string
1517d522f475Smrg	 * would terminate it.  Some (buggy, of course) applications rely on
1518d522f475Smrg	 * this behavior.  Accommodate them by allowing one to compile xterm
1519d522f475Smrg	 * and emulate the old behavior.
1520d522f475Smrg	 */
1521d522f475Smrg	if (screen->brokenStringTerm
1522d522f475Smrg	    && sp->parsestate == sos_table
1523d522f475Smrg	    && c < 32) {
1524d522f475Smrg	    switch (c) {
152520d2c4d2Smrg	    case ANSI_EOT:	/* FALLTHRU */
152620d2c4d2Smrg	    case ANSI_BS:	/* FALLTHRU */
152720d2c4d2Smrg	    case ANSI_HT:	/* FALLTHRU */
152820d2c4d2Smrg	    case ANSI_LF:	/* FALLTHRU */
152920d2c4d2Smrg	    case ANSI_VT:	/* FALLTHRU */
153020d2c4d2Smrg	    case ANSI_FF:	/* FALLTHRU */
153120d2c4d2Smrg	    case ANSI_CR:	/* FALLTHRU */
153220d2c4d2Smrg	    case ANSI_SO:	/* FALLTHRU */
153320d2c4d2Smrg	    case ANSI_SI:	/* FALLTHRU */
153420d2c4d2Smrg	    case ANSI_XON:	/* FALLTHRU */
153520d2c4d2Smrg	    case ANSI_CAN:
153620d2c4d2Smrg		illegal_parse(xw, c, sp);
1537d522f475Smrg		TRACE(("Reset to ground state (brokenStringTerm)\n"));
1538d522f475Smrg		break;
1539d522f475Smrg	    }
1540d522f475Smrg	}
1541d522f475Smrg#endif
1542d522f475Smrg
1543d522f475Smrg#if OPT_C1_PRINT
1544d522f475Smrg	/*
1545d522f475Smrg	 * This is not completely foolproof, but will allow an application
1546d522f475Smrg	 * with values in the C1 range to use them as printable characters,
1547d522f475Smrg	 * provided that they are not intermixed with an escape sequence.
1548d522f475Smrg	 */
1549d522f475Smrg	if (screen->c1_printable
1550d522f475Smrg	    && (c >= 128 && c < 160)) {
1551d522f475Smrg	    sp->nextstate = (sp->parsestate == esc_table
1552d522f475Smrg			     ? CASE_ESC_IGNORE
1553d522f475Smrg			     : sp->parsestate[E2A(160)]);
1554d522f475Smrg	}
1555d522f475Smrg#endif
1556d522f475Smrg
1557d522f475Smrg#if OPT_WIDE_CHARS
1558d522f475Smrg	/*
1559d522f475Smrg	 * If we have a C1 code and the c1_printable flag is not set, simply
1560d522f475Smrg	 * ignore it when it was translated from UTF-8.  That is because the
1561d522f475Smrg	 * value could not have been present as-is in the UTF-8.
1562d522f475Smrg	 *
1563d522f475Smrg	 * To see that CASE_IGNORE is a consistent value, note that it is
1564d522f475Smrg	 * always used for NUL and other uninteresting C0 controls.
1565d522f475Smrg	 */
1566d522f475Smrg#if OPT_C1_PRINT
1567d522f475Smrg	if (!screen->c1_printable)
1568d522f475Smrg#endif
1569d522f475Smrg	    if (screen->wide_chars
1570d522f475Smrg		&& (c >= 128 && c < 160)) {
1571d522f475Smrg		sp->nextstate = CASE_IGNORE;
1572d522f475Smrg	    }
1573d522f475Smrg
1574d522f475Smrg	/*
1575d522f475Smrg	 * If this character is a different width than the last one, put the
1576d522f475Smrg	 * previous text into the buffer and draw it now.
1577d522f475Smrg	 */
1578956cc18dSsnj	this_is_wide = isWide((int) c);
1579956cc18dSsnj	if (this_is_wide != sp->last_was_wide) {
1580d522f475Smrg	    WriteNow();
1581d522f475Smrg	}
1582d522f475Smrg#endif
1583d522f475Smrg
1584d522f475Smrg	/*
1585d522f475Smrg	 * Accumulate string for printable text.  This may be 8/16-bit
1586d522f475Smrg	 * characters.
1587d522f475Smrg	 */
1588d522f475Smrg	if (sp->nextstate == CASE_PRINT) {
1589956cc18dSsnj	    SafeAlloc(IChar, sp->print_area, sp->print_used, sp->print_size);
1590d522f475Smrg	    if (new_string == 0) {
1591d522f475Smrg		fprintf(stderr,
159220d2c4d2Smrg			"Cannot allocate %lu bytes for printable text\n",
159320d2c4d2Smrg			(unsigned long) new_length);
1594d522f475Smrg		continue;
1595d522f475Smrg	    }
1596d522f475Smrg#if OPT_VT52_MODE
1597d522f475Smrg	    /*
1598d522f475Smrg	     * Strip output text to 7-bits for VT52.  We should do this for
1599d522f475Smrg	     * VT100 also (which is a 7-bit device), but xterm has been
1600d522f475Smrg	     * doing this for so long we shouldn't change this behavior.
1601d522f475Smrg	     */
1602d522f475Smrg	    if (screen->vtXX_level < 1)
1603d522f475Smrg		c &= 0x7f;
1604d522f475Smrg#endif
1605956cc18dSsnj	    sp->print_area = new_string;
1606956cc18dSsnj	    sp->print_size = new_length;
1607956cc18dSsnj	    sp->print_area[sp->print_used++] = (IChar) c;
16082eaa94a1Schristos	    sp->lastchar = thischar = (int) c;
1609d522f475Smrg#if OPT_WIDE_CHARS
1610956cc18dSsnj	    sp->last_was_wide = this_is_wide;
1611d522f475Smrg#endif
1612d522f475Smrg	    if (morePtyData(screen, VTbuffer)) {
1613d522f475Smrg		continue;
1614d522f475Smrg	    }
1615d522f475Smrg	}
1616d522f475Smrg
1617d522f475Smrg	if (sp->nextstate == CASE_PRINT
1618956cc18dSsnj	    || (laststate == CASE_PRINT && sp->print_used)) {
1619d522f475Smrg	    WriteNow();
1620d522f475Smrg	}
1621d522f475Smrg
1622d522f475Smrg	/*
1623d522f475Smrg	 * Accumulate string for APC, DCS, PM, OSC, SOS controls
1624d522f475Smrg	 * This should always be 8-bit characters.
1625d522f475Smrg	 */
1626d522f475Smrg	if (sp->parsestate == sos_table) {
1627956cc18dSsnj	    SafeAlloc(Char, sp->string_area, sp->string_used, sp->string_size);
1628d522f475Smrg	    if (new_string == 0) {
1629d522f475Smrg		fprintf(stderr,
163020d2c4d2Smrg			"Cannot allocate %lu bytes for string mode %d\n",
163120d2c4d2Smrg			(unsigned long) new_length, sp->string_mode);
1632d522f475Smrg		continue;
1633d522f475Smrg	    }
1634d522f475Smrg#if OPT_WIDE_CHARS
1635d522f475Smrg	    /*
1636d522f475Smrg	     * We cannot display codes above 255, but let's try to
1637d522f475Smrg	     * accommodate the application a little by not aborting the
1638d522f475Smrg	     * string.
1639d522f475Smrg	     */
1640d522f475Smrg	    if ((c & 0xffff) > 255) {
1641d522f475Smrg		sp->nextstate = CASE_PRINT;
1642d522f475Smrg		c = '?';
1643d522f475Smrg	    }
1644d522f475Smrg#endif
1645956cc18dSsnj	    sp->string_area = new_string;
1646956cc18dSsnj	    sp->string_size = new_length;
1647956cc18dSsnj	    sp->string_area[(sp->string_used)++] = CharOf(c);
1648d522f475Smrg	} else if (sp->parsestate != esc_table) {
1649d522f475Smrg	    /* if we were accumulating, we're not any more */
1650d522f475Smrg	    sp->string_mode = 0;
1651956cc18dSsnj	    sp->string_used = 0;
1652d522f475Smrg	}
1653d522f475Smrg
1654d522f475Smrg	TRACE(("parse %04X -> %d %s\n", c, sp->nextstate, which_table(sp->parsestate)));
1655d522f475Smrg
1656d522f475Smrg	switch (sp->nextstate) {
1657d522f475Smrg	case CASE_PRINT:
1658d522f475Smrg	    TRACE(("CASE_PRINT - printable characters\n"));
1659d522f475Smrg	    break;
1660d522f475Smrg
1661d522f475Smrg	case CASE_GROUND_STATE:
1662d522f475Smrg	    TRACE(("CASE_GROUND_STATE - exit ignore mode\n"));
166320d2c4d2Smrg	    ResetState(sp);
1664d522f475Smrg	    break;
1665d522f475Smrg
1666d522f475Smrg	case CASE_IGNORE:
1667d522f475Smrg	    TRACE(("CASE_IGNORE - Ignore character %02X\n", c));
1668d522f475Smrg	    break;
1669d522f475Smrg
1670d522f475Smrg	case CASE_ENQ:
1671d522f475Smrg	    TRACE(("CASE_ENQ - answerback\n"));
1672d522f475Smrg	    for (count = 0; screen->answer_back[count] != 0; count++)
1673d522f475Smrg		unparseputc(xw, screen->answer_back[count]);
1674d522f475Smrg	    unparse_end(xw);
1675d522f475Smrg	    break;
1676d522f475Smrg
1677d522f475Smrg	case CASE_BELL:
1678d522f475Smrg	    TRACE(("CASE_BELL - bell\n"));
1679d522f475Smrg	    if (sp->string_mode == ANSI_OSC) {
1680956cc18dSsnj		if (sp->string_used)
1681956cc18dSsnj		    sp->string_area[--(sp->string_used)] = '\0';
1682956cc18dSsnj		do_osc(xw, sp->string_area, sp->string_used, (int) c);
168320d2c4d2Smrg		ResetState(sp);
1684d522f475Smrg	    } else {
1685d522f475Smrg		/* bell */
168620d2c4d2Smrg		Bell(xw, XkbBI_TerminalBell, 0);
1687d522f475Smrg	    }
1688d522f475Smrg	    break;
1689d522f475Smrg
1690d522f475Smrg	case CASE_BS:
1691d522f475Smrg	    TRACE(("CASE_BS - backspace\n"));
1692d522f475Smrg	    CursorBack(xw, 1);
1693d522f475Smrg	    break;
1694d522f475Smrg
1695d522f475Smrg	case CASE_CR:
1696d522f475Smrg	    /* CR */
1697d522f475Smrg	    CarriageReturn(screen);
1698d522f475Smrg	    break;
1699d522f475Smrg
1700d522f475Smrg	case CASE_ESC:
1701d522f475Smrg	    if_OPT_VT52_MODE(screen, {
1702d522f475Smrg		sp->parsestate = vt52_esc_table;
1703d522f475Smrg		break;
1704d522f475Smrg	    });
1705d522f475Smrg	    sp->parsestate = esc_table;
1706d522f475Smrg	    break;
1707d522f475Smrg
1708d522f475Smrg#if OPT_VT52_MODE
1709d522f475Smrg	case CASE_VT52_CUP:
1710d522f475Smrg	    TRACE(("CASE_VT52_CUP - VT52 cursor addressing\n"));
1711d522f475Smrg	    sp->vt52_cup = True;
1712d522f475Smrg	    nparam = 0;
1713d522f475Smrg	    break;
1714d522f475Smrg
1715d522f475Smrg	case CASE_VT52_IGNORE:
1716d522f475Smrg	    TRACE(("CASE_VT52_IGNORE - VT52 ignore-character\n"));
1717d522f475Smrg	    sp->parsestate = vt52_ignore_table;
1718d522f475Smrg	    break;
1719d522f475Smrg#endif
1720d522f475Smrg
1721d522f475Smrg	case CASE_VMOT:
1722d522f475Smrg	    /*
1723d522f475Smrg	     * form feed, line feed, vertical tab
1724d522f475Smrg	     */
1725956cc18dSsnj	    xtermAutoPrint(xw, c);
1726d522f475Smrg	    xtermIndex(xw, 1);
1727d522f475Smrg	    if (xw->flags & LINEFEED)
1728d522f475Smrg		CarriageReturn(screen);
1729d522f475Smrg	    else
1730d522f475Smrg		do_xevents();
1731d522f475Smrg	    break;
1732d522f475Smrg
1733d522f475Smrg	case CASE_CBT:
1734d522f475Smrg	    /* cursor backward tabulation */
1735d522f475Smrg	    if ((count = param[0]) == DEFAULT)
1736d522f475Smrg		count = 1;
1737d522f475Smrg	    while ((count-- > 0)
1738d522f475Smrg		   && (TabToPrevStop(xw))) ;
173920d2c4d2Smrg	    ResetState(sp);
1740d522f475Smrg	    break;
1741d522f475Smrg
1742d522f475Smrg	case CASE_CHT:
1743d522f475Smrg	    /* cursor forward tabulation */
1744d522f475Smrg	    if ((count = param[0]) == DEFAULT)
1745d522f475Smrg		count = 1;
1746d522f475Smrg	    while ((count-- > 0)
1747d522f475Smrg		   && (TabToNextStop(xw))) ;
174820d2c4d2Smrg	    ResetState(sp);
1749d522f475Smrg	    break;
1750d522f475Smrg
1751d522f475Smrg	case CASE_TAB:
1752d522f475Smrg	    /* tab */
1753d522f475Smrg	    TabToNextStop(xw);
1754d522f475Smrg	    break;
1755d522f475Smrg
1756d522f475Smrg	case CASE_SI:
1757d522f475Smrg	    screen->curgl = 0;
1758d522f475Smrg	    if_OPT_VT52_MODE(screen, {
175920d2c4d2Smrg		ResetState(sp);
1760d522f475Smrg	    });
1761d522f475Smrg	    break;
1762d522f475Smrg
1763d522f475Smrg	case CASE_SO:
1764d522f475Smrg	    screen->curgl = 1;
1765d522f475Smrg	    if_OPT_VT52_MODE(screen, {
176620d2c4d2Smrg		ResetState(sp);
1767d522f475Smrg	    });
1768d522f475Smrg	    break;
1769d522f475Smrg
1770d522f475Smrg	case CASE_DECDHL:
1771d522f475Smrg	    xterm_DECDHL(xw, c == '3');
177220d2c4d2Smrg	    ResetState(sp);
1773d522f475Smrg	    break;
1774d522f475Smrg
1775d522f475Smrg	case CASE_DECSWL:
1776d522f475Smrg	    xterm_DECSWL(xw);
177720d2c4d2Smrg	    ResetState(sp);
1778d522f475Smrg	    break;
1779d522f475Smrg
1780d522f475Smrg	case CASE_DECDWL:
1781d522f475Smrg	    xterm_DECDWL(xw);
178220d2c4d2Smrg	    ResetState(sp);
1783d522f475Smrg	    break;
1784d522f475Smrg
1785d522f475Smrg	case CASE_SCR_STATE:
1786d522f475Smrg	    /* enter scr state */
1787d522f475Smrg	    sp->parsestate = scrtable;
1788d522f475Smrg	    break;
1789d522f475Smrg
1790d522f475Smrg	case CASE_SCS0_STATE:
1791d522f475Smrg	    /* enter scs state 0 */
17922eaa94a1Schristos	    select_charset(sp, 0, 94);
1793d522f475Smrg	    break;
1794d522f475Smrg
1795d522f475Smrg	case CASE_SCS1_STATE:
1796d522f475Smrg	    /* enter scs state 1 */
17972eaa94a1Schristos	    select_charset(sp, 1, 94);
1798d522f475Smrg	    break;
1799d522f475Smrg
1800d522f475Smrg	case CASE_SCS2_STATE:
1801d522f475Smrg	    /* enter scs state 2 */
18022eaa94a1Schristos	    select_charset(sp, 2, 94);
1803d522f475Smrg	    break;
1804d522f475Smrg
1805d522f475Smrg	case CASE_SCS3_STATE:
1806d522f475Smrg	    /* enter scs state 3 */
18072eaa94a1Schristos	    select_charset(sp, 3, 94);
18082eaa94a1Schristos	    break;
18092eaa94a1Schristos
18102eaa94a1Schristos	case CASE_SCS1A_STATE:
18112eaa94a1Schristos	    /* enter scs state 1 */
18122eaa94a1Schristos	    select_charset(sp, 1, 96);
18132eaa94a1Schristos	    break;
18142eaa94a1Schristos
18152eaa94a1Schristos	case CASE_SCS2A_STATE:
18162eaa94a1Schristos	    /* enter scs state 2 */
18172eaa94a1Schristos	    select_charset(sp, 2, 96);
18182eaa94a1Schristos	    break;
18192eaa94a1Schristos
18202eaa94a1Schristos	case CASE_SCS3A_STATE:
18212eaa94a1Schristos	    /* enter scs state 3 */
18222eaa94a1Schristos	    select_charset(sp, 3, 96);
1823d522f475Smrg	    break;
1824d522f475Smrg
1825d522f475Smrg	case CASE_ESC_IGNORE:
1826d522f475Smrg	    /* unknown escape sequence */
1827d522f475Smrg	    sp->parsestate = eigtable;
1828d522f475Smrg	    break;
1829d522f475Smrg
1830d522f475Smrg	case CASE_ESC_DIGIT:
1831d522f475Smrg	    /* digit in csi or dec mode */
183220d2c4d2Smrg	    if (nparam > 0) {
183320d2c4d2Smrg		if ((row = param[nparam - 1]) == DEFAULT)
183420d2c4d2Smrg		    row = 0;
183520d2c4d2Smrg		param[nparam - 1] = (10 * row) + ((int) c - '0');
183620d2c4d2Smrg		if (param[nparam - 1] > 65535)
183720d2c4d2Smrg		    param[nparam - 1] = 65535;
183820d2c4d2Smrg		if (sp->parsestate == csi_table)
183920d2c4d2Smrg		    sp->parsestate = csi2_table;
184020d2c4d2Smrg	    }
1841d522f475Smrg	    break;
1842d522f475Smrg
1843d522f475Smrg	case CASE_ESC_SEMI:
1844d522f475Smrg	    /* semicolon in csi or dec mode */
1845d522f475Smrg	    if (nparam < NPARAM)
1846d522f475Smrg		param[nparam++] = DEFAULT;
1847d522f475Smrg	    if (sp->parsestate == csi_table)
1848d522f475Smrg		sp->parsestate = csi2_table;
1849d522f475Smrg	    break;
1850d522f475Smrg
1851d522f475Smrg	case CASE_DEC_STATE:
1852d522f475Smrg	    /* enter dec mode */
1853d522f475Smrg	    sp->parsestate = dec_table;
1854d522f475Smrg	    break;
1855d522f475Smrg
1856d522f475Smrg	case CASE_DEC2_STATE:
1857d522f475Smrg	    /* enter dec2 mode */
1858d522f475Smrg	    sp->parsestate = dec2_table;
1859d522f475Smrg	    break;
1860d522f475Smrg
1861d522f475Smrg	case CASE_DEC3_STATE:
1862d522f475Smrg	    /* enter dec3 mode */
1863d522f475Smrg	    sp->parsestate = dec3_table;
1864d522f475Smrg	    break;
1865d522f475Smrg
1866d522f475Smrg	case CASE_ICH:
1867d522f475Smrg	    TRACE(("CASE_ICH - insert char\n"));
1868d522f475Smrg	    if ((row = param[0]) < 1)
1869d522f475Smrg		row = 1;
1870d522f475Smrg	    InsertChar(xw, (unsigned) row);
187120d2c4d2Smrg	    ResetState(sp);
1872d522f475Smrg	    break;
1873d522f475Smrg
1874d522f475Smrg	case CASE_CUU:
1875d522f475Smrg	    TRACE(("CASE_CUU - cursor up\n"));
1876d522f475Smrg	    if ((row = param[0]) < 1)
1877d522f475Smrg		row = 1;
1878d522f475Smrg	    CursorUp(screen, row);
187920d2c4d2Smrg	    ResetState(sp);
1880d522f475Smrg	    break;
1881d522f475Smrg
1882d522f475Smrg	case CASE_CUD:
1883d522f475Smrg	    TRACE(("CASE_CUD - cursor down\n"));
1884d522f475Smrg	    if ((row = param[0]) < 1)
1885d522f475Smrg		row = 1;
1886d522f475Smrg	    CursorDown(screen, row);
188720d2c4d2Smrg	    ResetState(sp);
1888d522f475Smrg	    break;
1889d522f475Smrg
1890d522f475Smrg	case CASE_CUF:
1891d522f475Smrg	    TRACE(("CASE_CUF - cursor forward\n"));
1892d522f475Smrg	    if ((col = param[0]) < 1)
1893d522f475Smrg		col = 1;
1894d522f475Smrg	    CursorForward(screen, col);
189520d2c4d2Smrg	    ResetState(sp);
1896d522f475Smrg	    break;
1897d522f475Smrg
1898d522f475Smrg	case CASE_CUB:
1899d522f475Smrg	    TRACE(("CASE_CUB - cursor backward\n"));
1900d522f475Smrg	    if ((col = param[0]) < 1)
1901d522f475Smrg		col = 1;
1902d522f475Smrg	    CursorBack(xw, col);
190320d2c4d2Smrg	    ResetState(sp);
1904d522f475Smrg	    break;
1905d522f475Smrg
1906d522f475Smrg	case CASE_CUP:
1907d522f475Smrg	    TRACE(("CASE_CUP - cursor position\n"));
1908d522f475Smrg	    if_OPT_XMC_GLITCH(screen, {
1909d522f475Smrg		Jump_XMC(xw);
1910d522f475Smrg	    });
1911d522f475Smrg	    if ((row = param[0]) < 1)
1912d522f475Smrg		row = 1;
1913d522f475Smrg	    if (nparam < 2 || (col = param[1]) < 1)
1914d522f475Smrg		col = 1;
1915d522f475Smrg	    CursorSet(screen, row - 1, col - 1, xw->flags);
191620d2c4d2Smrg	    ResetState(sp);
1917d522f475Smrg	    break;
1918d522f475Smrg
1919d522f475Smrg	case CASE_VPA:
1920d522f475Smrg	    TRACE(("CASE_VPA - vertical position\n"));
1921d522f475Smrg	    if ((row = param[0]) < 1)
1922d522f475Smrg		row = 1;
1923d522f475Smrg	    CursorSet(screen, row - 1, screen->cur_col, xw->flags);
192420d2c4d2Smrg	    ResetState(sp);
1925d522f475Smrg	    break;
1926d522f475Smrg
1927d522f475Smrg	case CASE_HPA:
1928d522f475Smrg	    TRACE(("CASE_HPA - horizontal position\n"));
1929d522f475Smrg	    if ((col = param[0]) < 1)
1930d522f475Smrg		col = 1;
1931d522f475Smrg	    CursorSet(screen, screen->cur_row, col - 1, xw->flags);
193220d2c4d2Smrg	    ResetState(sp);
1933d522f475Smrg	    break;
1934d522f475Smrg
1935d522f475Smrg	case CASE_HP_BUGGY_LL:
1936d522f475Smrg	    TRACE(("CASE_HP_BUGGY_LL\n"));
1937d522f475Smrg	    /* Some HP-UX applications have the bug that they
1938d522f475Smrg	       assume ESC F goes to the lower left corner of
1939d522f475Smrg	       the screen, regardless of what terminfo says. */
1940d522f475Smrg	    if (screen->hp_ll_bc)
1941d522f475Smrg		CursorSet(screen, screen->max_row, 0, xw->flags);
194220d2c4d2Smrg	    ResetState(sp);
1943d522f475Smrg	    break;
1944d522f475Smrg
1945d522f475Smrg	case CASE_ED:
1946d522f475Smrg	    TRACE(("CASE_ED - erase display\n"));
1947d522f475Smrg	    do_erase_display(xw, param[0], OFF_PROTECT);
194820d2c4d2Smrg	    ResetState(sp);
1949d522f475Smrg	    break;
1950d522f475Smrg
1951d522f475Smrg	case CASE_EL:
1952d522f475Smrg	    TRACE(("CASE_EL - erase line\n"));
1953d522f475Smrg	    do_erase_line(xw, param[0], OFF_PROTECT);
195420d2c4d2Smrg	    ResetState(sp);
1955d522f475Smrg	    break;
1956d522f475Smrg
1957d522f475Smrg	case CASE_ECH:
1958d522f475Smrg	    TRACE(("CASE_ECH - erase char\n"));
1959d522f475Smrg	    /* ECH */
1960d522f475Smrg	    ClearRight(xw, param[0] < 1 ? 1 : param[0]);
196120d2c4d2Smrg	    ResetState(sp);
1962d522f475Smrg	    break;
1963d522f475Smrg
1964d522f475Smrg	case CASE_IL:
1965d522f475Smrg	    TRACE(("CASE_IL - insert line\n"));
1966d522f475Smrg	    if ((row = param[0]) < 1)
1967d522f475Smrg		row = 1;
1968d522f475Smrg	    InsertLine(xw, row);
196920d2c4d2Smrg	    ResetState(sp);
1970d522f475Smrg	    break;
1971d522f475Smrg
1972d522f475Smrg	case CASE_DL:
1973d522f475Smrg	    TRACE(("CASE_DL - delete line\n"));
1974d522f475Smrg	    if ((row = param[0]) < 1)
1975d522f475Smrg		row = 1;
1976d522f475Smrg	    DeleteLine(xw, row);
197720d2c4d2Smrg	    ResetState(sp);
1978d522f475Smrg	    break;
1979d522f475Smrg
1980d522f475Smrg	case CASE_DCH:
1981d522f475Smrg	    TRACE(("CASE_DCH - delete char\n"));
1982d522f475Smrg	    if ((row = param[0]) < 1)
1983d522f475Smrg		row = 1;
1984d522f475Smrg	    DeleteChar(xw, (unsigned) row);
198520d2c4d2Smrg	    ResetState(sp);
1986d522f475Smrg	    break;
1987d522f475Smrg
1988d522f475Smrg	case CASE_TRACK_MOUSE:
1989d522f475Smrg	    /*
1990d522f475Smrg	     * A single parameter other than zero is always scroll-down.
1991d522f475Smrg	     * A zero-parameter is used to reset the mouse mode, and is
1992d522f475Smrg	     * not useful for scrolling anyway.
1993d522f475Smrg	     */
1994d522f475Smrg	    if (nparam > 1 || param[0] == 0) {
1995d522f475Smrg		CELL start;
1996d522f475Smrg
1997d522f475Smrg		TRACE(("CASE_TRACK_MOUSE\n"));
1998d522f475Smrg		/* Track mouse as long as in window and between
1999d522f475Smrg		 * specified rows
2000d522f475Smrg		 */
200120d2c4d2Smrg		start.row = one_if_default(2) - 1;
2002d522f475Smrg		start.col = param[1] - 1;
2003d522f475Smrg		TrackMouse(xw,
2004d522f475Smrg			   param[0],
2005d522f475Smrg			   &start,
2006d522f475Smrg			   param[3] - 1, param[4] - 2);
2007d522f475Smrg	    } else {
2008d522f475Smrg		TRACE(("CASE_SD - scroll down\n"));
2009d522f475Smrg		/* SD */
2010d522f475Smrg		if ((count = param[0]) < 1)
2011d522f475Smrg		    count = 1;
2012d522f475Smrg		RevScroll(xw, count);
2013d522f475Smrg		do_xevents();
2014d522f475Smrg	    }
201520d2c4d2Smrg	    ResetState(sp);
2016d522f475Smrg	    break;
2017d522f475Smrg
2018d522f475Smrg	case CASE_DECID:
2019d522f475Smrg	    TRACE(("CASE_DECID\n"));
2020d522f475Smrg	    if_OPT_VT52_MODE(screen, {
2021d522f475Smrg		unparseputc(xw, ANSI_ESC);
2022d522f475Smrg		unparseputc(xw, '/');
2023d522f475Smrg		unparseputc(xw, 'Z');
2024d522f475Smrg		unparse_end(xw);
202520d2c4d2Smrg		ResetState(sp);
2026d522f475Smrg		break;
2027d522f475Smrg	    });
2028d522f475Smrg	    param[0] = DEFAULT;	/* Default ID parameter */
2029d522f475Smrg	    /* FALLTHRU */
2030d522f475Smrg	case CASE_DA1:
2031d522f475Smrg	    TRACE(("CASE_DA1\n"));
2032d522f475Smrg	    if (param[0] <= 0) {	/* less than means DEFAULT */
2033d522f475Smrg		count = 0;
2034d522f475Smrg		reply.a_type = ANSI_CSI;
2035d522f475Smrg		reply.a_pintro = '?';
2036d522f475Smrg
2037d522f475Smrg		/* The first param corresponds to the highest
2038d522f475Smrg		 * operating level (i.e., service level) of the
2039d522f475Smrg		 * emulation.  A DEC terminal can be setup to
2040d522f475Smrg		 * respond with a different DA response, but
2041d522f475Smrg		 * there's no control sequence that modifies this.
2042d522f475Smrg		 * We set it via a resource.
2043d522f475Smrg		 */
2044d522f475Smrg		if (screen->terminal_id < 200) {
2045d522f475Smrg		    switch (screen->terminal_id) {
2046d522f475Smrg		    case 102:
2047d522f475Smrg			reply.a_param[count++] = 6;	/* VT102 */
2048d522f475Smrg			break;
2049d522f475Smrg		    case 101:
2050d522f475Smrg			reply.a_param[count++] = 1;	/* VT101 */
2051d522f475Smrg			reply.a_param[count++] = 0;	/* no options */
2052d522f475Smrg			break;
2053d522f475Smrg		    default:	/* VT100 */
2054d522f475Smrg			reply.a_param[count++] = 1;	/* VT100 */
2055d522f475Smrg			reply.a_param[count++] = 2;	/* AVO */
2056d522f475Smrg			break;
2057d522f475Smrg		    }
2058d522f475Smrg		} else {
20592eaa94a1Schristos		    reply.a_param[count++] = (ParmType) (60
20602eaa94a1Schristos							 + screen->terminal_id
20612eaa94a1Schristos							 / 100);
2062d522f475Smrg		    reply.a_param[count++] = 1;		/* 132-columns */
2063d522f475Smrg		    reply.a_param[count++] = 2;		/* printer */
2064d522f475Smrg		    reply.a_param[count++] = 6;		/* selective-erase */
2065d522f475Smrg#if OPT_SUNPC_KBD
2066d522f475Smrg		    if (xw->keyboard.type == keyboardIsVT220)
2067d522f475Smrg#endif
2068d522f475Smrg			reply.a_param[count++] = 8;	/* user-defined-keys */
2069d522f475Smrg		    reply.a_param[count++] = 9;		/* national replacement charsets */
2070d522f475Smrg		    reply.a_param[count++] = 15;	/* technical characters */
2071d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2072d522f475Smrg			reply.a_param[count++] = 22;	/* ANSI color, VT525 */
2073d522f475Smrg		    });
2074d522f475Smrg#if OPT_DEC_LOCATOR
2075d522f475Smrg		    reply.a_param[count++] = 29;	/* ANSI text locator */
2076d522f475Smrg#endif
2077d522f475Smrg		}
20782eaa94a1Schristos		reply.a_nparam = (ParmType) count;
2079d522f475Smrg		reply.a_inters = 0;
2080d522f475Smrg		reply.a_final = 'c';
2081d522f475Smrg		unparseseq(xw, &reply);
2082d522f475Smrg	    }
208320d2c4d2Smrg	    ResetState(sp);
2084d522f475Smrg	    break;
2085d522f475Smrg
2086d522f475Smrg	case CASE_DA2:
2087d522f475Smrg	    TRACE(("CASE_DA2\n"));
2088d522f475Smrg	    if (param[0] <= 0) {	/* less than means DEFAULT */
2089d522f475Smrg		count = 0;
2090d522f475Smrg		reply.a_type = ANSI_CSI;
2091d522f475Smrg		reply.a_pintro = '>';
2092d522f475Smrg
2093d522f475Smrg		if (screen->terminal_id >= 200)
2094d522f475Smrg		    reply.a_param[count++] = 1;		/* VT220 */
2095d522f475Smrg		else
2096d522f475Smrg		    reply.a_param[count++] = 0;		/* VT100 (nonstandard) */
2097d522f475Smrg		reply.a_param[count++] = XTERM_PATCH;	/* Version */
2098d522f475Smrg		reply.a_param[count++] = 0;	/* options (none) */
20992eaa94a1Schristos		reply.a_nparam = (ParmType) count;
2100d522f475Smrg		reply.a_inters = 0;
2101d522f475Smrg		reply.a_final = 'c';
2102d522f475Smrg		unparseseq(xw, &reply);
2103d522f475Smrg	    }
210420d2c4d2Smrg	    ResetState(sp);
2105d522f475Smrg	    break;
2106d522f475Smrg
2107d522f475Smrg	case CASE_DECRPTUI:
2108d522f475Smrg	    TRACE(("CASE_DECRPTUI\n"));
2109d522f475Smrg	    if ((screen->terminal_id >= 400)
2110d522f475Smrg		&& (param[0] <= 0)) {	/* less than means DEFAULT */
2111d522f475Smrg		unparseputc1(xw, ANSI_DCS);
2112d522f475Smrg		unparseputc(xw, '!');
2113d522f475Smrg		unparseputc(xw, '|');
2114d522f475Smrg		unparseputc(xw, '0');
2115d522f475Smrg		unparseputc1(xw, ANSI_ST);
2116d522f475Smrg		unparse_end(xw);
2117d522f475Smrg	    }
211820d2c4d2Smrg	    ResetState(sp);
2119d522f475Smrg	    break;
2120d522f475Smrg
2121d522f475Smrg	case CASE_TBC:
2122d522f475Smrg	    TRACE(("CASE_TBC - tab clear\n"));
2123d522f475Smrg	    if ((row = param[0]) <= 0)	/* less than means default */
2124d522f475Smrg		TabClear(xw->tabs, screen->cur_col);
2125d522f475Smrg	    else if (row == 3)
2126d522f475Smrg		TabZonk(xw->tabs);
212720d2c4d2Smrg	    ResetState(sp);
2128d522f475Smrg	    break;
2129d522f475Smrg
2130d522f475Smrg	case CASE_SET:
2131d522f475Smrg	    TRACE(("CASE_SET - set mode\n"));
2132d522f475Smrg	    ansi_modes(xw, bitset);
213320d2c4d2Smrg	    ResetState(sp);
2134d522f475Smrg	    break;
2135d522f475Smrg
2136d522f475Smrg	case CASE_RST:
2137d522f475Smrg	    TRACE(("CASE_RST - reset mode\n"));
2138d522f475Smrg	    ansi_modes(xw, bitclr);
213920d2c4d2Smrg	    ResetState(sp);
2140d522f475Smrg	    break;
2141d522f475Smrg
2142d522f475Smrg	case CASE_SGR:
2143d522f475Smrg	    for (row = 0; row < nparam; ++row) {
2144d522f475Smrg		if_OPT_XMC_GLITCH(screen, {
2145d522f475Smrg		    Mark_XMC(xw, param[row]);
2146d522f475Smrg		});
2147d522f475Smrg		TRACE(("CASE_SGR %d\n", param[row]));
2148d522f475Smrg		switch (param[row]) {
2149d522f475Smrg		case DEFAULT:
2150d522f475Smrg		case 0:
215120d2c4d2Smrg		    UIntClr(xw->flags,
215220d2c4d2Smrg			    (INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE));
2153d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2154d522f475Smrg			reset_SGR_Colors(xw);
2155d522f475Smrg		    });
2156d522f475Smrg		    break;
2157d522f475Smrg		case 1:	/* Bold                 */
2158d522f475Smrg		    xw->flags |= BOLD;
2159d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2160d522f475Smrg			setExtendedFG(xw);
2161d522f475Smrg		    });
2162d522f475Smrg		    break;
2163d522f475Smrg		case 5:	/* Blink                */
2164d522f475Smrg		    xw->flags |= BLINK;
2165d522f475Smrg		    StartBlinking(screen);
2166d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2167d522f475Smrg			setExtendedFG(xw);
2168d522f475Smrg		    });
2169d522f475Smrg		    break;
2170d522f475Smrg		case 4:	/* Underscore           */
2171d522f475Smrg		    xw->flags |= UNDERLINE;
2172d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2173d522f475Smrg			setExtendedFG(xw);
2174d522f475Smrg		    });
2175d522f475Smrg		    break;
2176d522f475Smrg		case 7:
2177d522f475Smrg		    xw->flags |= INVERSE;
2178d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2179d522f475Smrg			setExtendedBG(xw);
2180d522f475Smrg		    });
2181d522f475Smrg		    break;
2182d522f475Smrg		case 8:
2183d522f475Smrg		    xw->flags |= INVISIBLE;
2184d522f475Smrg		    break;
2185d522f475Smrg		case 22:	/* reset 'bold' */
218620d2c4d2Smrg		    UIntClr(xw->flags, BOLD);
2187d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2188d522f475Smrg			setExtendedFG(xw);
2189d522f475Smrg		    });
2190d522f475Smrg		    break;
2191d522f475Smrg		case 24:
219220d2c4d2Smrg		    UIntClr(xw->flags, UNDERLINE);
2193d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2194d522f475Smrg			setExtendedFG(xw);
2195d522f475Smrg		    });
2196d522f475Smrg		    break;
2197d522f475Smrg		case 25:	/* reset 'blink' */
219820d2c4d2Smrg		    UIntClr(xw->flags, BLINK);
2199d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2200d522f475Smrg			setExtendedFG(xw);
2201d522f475Smrg		    });
2202d522f475Smrg		    break;
2203d522f475Smrg		case 27:
220420d2c4d2Smrg		    UIntClr(xw->flags, INVERSE);
2205d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2206d522f475Smrg			setExtendedBG(xw);
2207d522f475Smrg		    });
2208d522f475Smrg		    break;
2209d522f475Smrg		case 28:
221020d2c4d2Smrg		    UIntClr(xw->flags, INVISIBLE);
2211d522f475Smrg		    break;
2212d522f475Smrg		case 30:
2213d522f475Smrg		case 31:
2214d522f475Smrg		case 32:
2215d522f475Smrg		case 33:
2216d522f475Smrg		case 34:
2217d522f475Smrg		case 35:
2218d522f475Smrg		case 36:
2219d522f475Smrg		case 37:
2220d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2221d522f475Smrg			xw->sgr_foreground = (param[row] - 30);
2222d522f475Smrg			xw->sgr_extended = False;
2223d522f475Smrg			setExtendedFG(xw);
2224d522f475Smrg		    });
2225d522f475Smrg		    break;
2226d522f475Smrg		case 38:
2227d522f475Smrg		    /* This is more complicated than I'd
2228d522f475Smrg		       like, but it should properly eat all
2229d522f475Smrg		       the parameters for unsupported modes
2230d522f475Smrg		     */
2231d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2232d522f475Smrg			row++;
2233d522f475Smrg			if (row < nparam) {
2234d522f475Smrg			    switch (param[row]) {
2235d522f475Smrg			    case 5:
2236d522f475Smrg				row++;
2237d522f475Smrg				if (row < nparam &&
2238d522f475Smrg				    param[row] < NUM_ANSI_COLORS) {
2239d522f475Smrg				    xw->sgr_foreground = param[row];
2240d522f475Smrg				    xw->sgr_extended = True;
2241d522f475Smrg				    setExtendedFG(xw);
2242d522f475Smrg				}
2243d522f475Smrg				break;
2244d522f475Smrg			    default:
2245d522f475Smrg				row += 7;
2246d522f475Smrg				break;
2247d522f475Smrg			    }
2248d522f475Smrg			}
2249d522f475Smrg		    });
2250d522f475Smrg		    break;
2251d522f475Smrg		case 39:
2252d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2253d522f475Smrg			reset_SGR_Foreground(xw);
2254d522f475Smrg		    });
2255d522f475Smrg		    break;
2256d522f475Smrg		case 40:
2257d522f475Smrg		case 41:
2258d522f475Smrg		case 42:
2259d522f475Smrg		case 43:
2260d522f475Smrg		case 44:
2261d522f475Smrg		case 45:
2262d522f475Smrg		case 46:
2263d522f475Smrg		case 47:
2264d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2265d522f475Smrg			xw->sgr_background = (param[row] - 40);
2266d522f475Smrg			setExtendedBG(xw);
2267d522f475Smrg		    });
2268d522f475Smrg		    break;
2269d522f475Smrg		case 48:
2270d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2271d522f475Smrg			row++;
2272d522f475Smrg			if (row < nparam) {
2273d522f475Smrg			    switch (param[row]) {
2274d522f475Smrg			    case 5:
2275d522f475Smrg				row++;
2276d522f475Smrg				if (row < nparam &&
2277d522f475Smrg				    param[row] < NUM_ANSI_COLORS) {
2278d522f475Smrg				    xw->sgr_background = param[row];
2279d522f475Smrg				    setExtendedBG(xw);
2280d522f475Smrg				}
2281d522f475Smrg				break;
2282d522f475Smrg			    default:
2283d522f475Smrg				row += 7;
2284d522f475Smrg				break;
2285d522f475Smrg			    }
2286d522f475Smrg			}
2287d522f475Smrg		    });
2288d522f475Smrg		    break;
2289d522f475Smrg		case 49:
2290d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2291d522f475Smrg			reset_SGR_Background(xw);
2292d522f475Smrg		    });
2293d522f475Smrg		    break;
2294d522f475Smrg		case 90:
2295d522f475Smrg		case 91:
2296d522f475Smrg		case 92:
2297d522f475Smrg		case 93:
2298d522f475Smrg		case 94:
2299d522f475Smrg		case 95:
2300d522f475Smrg		case 96:
2301d522f475Smrg		case 97:
2302d522f475Smrg		    if_OPT_AIX_COLORS(screen, {
2303d522f475Smrg			xw->sgr_foreground = (param[row] - 90 + 8);
2304d522f475Smrg			xw->sgr_extended = False;
2305d522f475Smrg			setExtendedFG(xw);
2306d522f475Smrg		    });
2307d522f475Smrg		    break;
2308d522f475Smrg		case 100:
2309d522f475Smrg#if !OPT_AIX_COLORS
2310d522f475Smrg		    if_OPT_ISO_COLORS(screen, {
2311d522f475Smrg			reset_SGR_Foreground(xw);
2312d522f475Smrg			reset_SGR_Background(xw);
2313d522f475Smrg		    });
2314d522f475Smrg		    break;
2315d522f475Smrg#endif
2316d522f475Smrg		case 101:
2317d522f475Smrg		case 102:
2318d522f475Smrg		case 103:
2319d522f475Smrg		case 104:
2320d522f475Smrg		case 105:
2321d522f475Smrg		case 106:
2322d522f475Smrg		case 107:
2323d522f475Smrg		    if_OPT_AIX_COLORS(screen, {
2324d522f475Smrg			xw->sgr_background = (param[row] - 100 + 8);
2325d522f475Smrg			setExtendedBG(xw);
2326d522f475Smrg		    });
2327d522f475Smrg		    break;
2328d522f475Smrg		}
2329d522f475Smrg	    }
233020d2c4d2Smrg	    ResetState(sp);
2331d522f475Smrg	    break;
2332d522f475Smrg
2333d522f475Smrg	    /* DSR (except for the '?') is a superset of CPR */
2334d522f475Smrg	case CASE_DSR:
2335d522f475Smrg	    sp->private_function = True;
2336d522f475Smrg
2337d522f475Smrg	    /* FALLTHRU */
2338d522f475Smrg	case CASE_CPR:
2339d522f475Smrg	    TRACE(("CASE_CPR - cursor position\n"));
2340d522f475Smrg	    count = 0;
2341d522f475Smrg	    reply.a_type = ANSI_CSI;
23422eaa94a1Schristos	    reply.a_pintro = CharOf(sp->private_function ? '?' : 0);
2343d522f475Smrg	    reply.a_inters = 0;
2344d522f475Smrg	    reply.a_final = 'n';
2345d522f475Smrg
2346d522f475Smrg	    switch (param[0]) {
2347d522f475Smrg	    case 5:
2348d522f475Smrg		/* operating status */
2349d522f475Smrg		reply.a_param[count++] = 0;	/* (no malfunction ;-) */
2350d522f475Smrg		break;
2351d522f475Smrg	    case 6:
2352d522f475Smrg		/* CPR */
2353d522f475Smrg		/* DECXCPR (with page=0) */
23542eaa94a1Schristos		reply.a_param[count++] = (ParmType) (screen->cur_row + 1);
23552eaa94a1Schristos		reply.a_param[count++] = (ParmType) (screen->cur_col + 1);
2356d522f475Smrg		reply.a_final = 'R';
2357d522f475Smrg		break;
2358d522f475Smrg	    case 15:
2359d522f475Smrg		/* printer status */
23602eaa94a1Schristos		if (screen->terminal_id >= 200) {	/* VT220 */
23612eaa94a1Schristos		    reply.a_param[count++] = 13;	/* implement printer */
23622eaa94a1Schristos		}
2363d522f475Smrg		break;
2364d522f475Smrg	    case 25:
2365d522f475Smrg		/* UDK status */
23662eaa94a1Schristos		if (screen->terminal_id >= 200) {	/* VT220 */
23672eaa94a1Schristos		    reply.a_param[count++] = 20;	/* UDK always unlocked */
23682eaa94a1Schristos		}
2369d522f475Smrg		break;
2370d522f475Smrg	    case 26:
2371d522f475Smrg		/* keyboard status */
23722eaa94a1Schristos		if (screen->terminal_id >= 200) {	/* VT220 */
23732eaa94a1Schristos		    reply.a_param[count++] = 27;
23742eaa94a1Schristos		    reply.a_param[count++] = 1;		/* North American */
23752eaa94a1Schristos		    if (screen->terminal_id >= 400) {
23762eaa94a1Schristos			reply.a_param[count++] = 0;	/* ready */
23772eaa94a1Schristos			reply.a_param[count++] = 0;	/* LK201 */
23782eaa94a1Schristos		    }
2379d522f475Smrg		}
2380d522f475Smrg		break;
2381d522f475Smrg	    case 53:
2382d522f475Smrg		/* Locator status */
23832eaa94a1Schristos		if (screen->terminal_id >= 200) {	/* VT220 */
2384d522f475Smrg#if OPT_DEC_LOCATOR
23852eaa94a1Schristos		    reply.a_param[count++] = 50;	/* locator ready */
2386d522f475Smrg#else
23872eaa94a1Schristos		    reply.a_param[count++] = 53;	/* no locator */
2388d522f475Smrg#endif
23892eaa94a1Schristos		}
23902eaa94a1Schristos		break;
23912eaa94a1Schristos	    default:
2392d522f475Smrg		break;
2393d522f475Smrg	    }
2394d522f475Smrg
23952eaa94a1Schristos	    if ((reply.a_nparam = (ParmType) count) != 0)
2396d522f475Smrg		unparseseq(xw, &reply);
2397d522f475Smrg
239820d2c4d2Smrg	    ResetState(sp);
2399d522f475Smrg	    sp->private_function = False;
2400d522f475Smrg	    break;
2401d522f475Smrg
2402d522f475Smrg	case CASE_MC:
2403d522f475Smrg	    TRACE(("CASE_MC - media control\n"));
2404956cc18dSsnj	    xtermMediaControl(xw, param[0], False);
240520d2c4d2Smrg	    ResetState(sp);
2406d522f475Smrg	    break;
2407d522f475Smrg
2408d522f475Smrg	case CASE_DEC_MC:
2409d522f475Smrg	    TRACE(("CASE_DEC_MC - DEC media control\n"));
2410956cc18dSsnj	    xtermMediaControl(xw, param[0], True);
241120d2c4d2Smrg	    ResetState(sp);
2412d522f475Smrg	    break;
2413d522f475Smrg
2414d522f475Smrg	case CASE_HP_MEM_LOCK:
2415d522f475Smrg	case CASE_HP_MEM_UNLOCK:
2416d522f475Smrg	    TRACE(("%s\n", ((sp->parsestate[c] == CASE_HP_MEM_LOCK)
2417d522f475Smrg			    ? "CASE_HP_MEM_LOCK"
2418d522f475Smrg			    : "CASE_HP_MEM_UNLOCK")));
2419d522f475Smrg	    if (screen->scroll_amt)
2420d522f475Smrg		FlushScroll(xw);
2421d522f475Smrg	    if (sp->parsestate[c] == CASE_HP_MEM_LOCK)
2422d522f475Smrg		set_tb_margins(screen, screen->cur_row, screen->bot_marg);
2423d522f475Smrg	    else
2424d522f475Smrg		set_tb_margins(screen, 0, screen->bot_marg);
242520d2c4d2Smrg	    ResetState(sp);
2426d522f475Smrg	    break;
2427d522f475Smrg
2428d522f475Smrg	case CASE_DECSTBM:
2429d522f475Smrg	    TRACE(("CASE_DECSTBM - set scrolling region\n"));
2430d522f475Smrg	    if ((top = param[0]) < 1)
2431d522f475Smrg		top = 1;
2432d522f475Smrg	    if (nparam < 2 || (bot = param[1]) == DEFAULT
2433d522f475Smrg		|| bot > MaxRows(screen)
2434d522f475Smrg		|| bot == 0)
2435d522f475Smrg		bot = MaxRows(screen);
2436d522f475Smrg	    if (bot > top) {
2437d522f475Smrg		if (screen->scroll_amt)
2438d522f475Smrg		    FlushScroll(xw);
2439d522f475Smrg		set_tb_margins(screen, top - 1, bot - 1);
2440d522f475Smrg		CursorSet(screen, 0, 0, xw->flags);
2441d522f475Smrg	    }
244220d2c4d2Smrg	    ResetState(sp);
2443d522f475Smrg	    break;
2444d522f475Smrg
2445d522f475Smrg	case CASE_DECREQTPARM:
2446d522f475Smrg	    TRACE(("CASE_DECREQTPARM\n"));
2447d522f475Smrg	    if (screen->terminal_id < 200) {	/* VT102 */
2448d522f475Smrg		if ((row = param[0]) == DEFAULT)
2449d522f475Smrg		    row = 0;
2450d522f475Smrg		if (row == 0 || row == 1) {
2451d522f475Smrg		    reply.a_type = ANSI_CSI;
2452d522f475Smrg		    reply.a_pintro = 0;
2453d522f475Smrg		    reply.a_nparam = 7;
24542eaa94a1Schristos		    reply.a_param[0] = (ParmType) (row + 2);
2455d522f475Smrg		    reply.a_param[1] = 1;	/* no parity */
2456d522f475Smrg		    reply.a_param[2] = 1;	/* eight bits */
2457d522f475Smrg		    reply.a_param[3] = 128;	/* transmit 38.4k baud */
2458d522f475Smrg		    reply.a_param[4] = 128;	/* receive 38.4k baud */
2459d522f475Smrg		    reply.a_param[5] = 1;	/* clock multiplier ? */
2460d522f475Smrg		    reply.a_param[6] = 0;	/* STP flags ? */
2461d522f475Smrg		    reply.a_inters = 0;
2462d522f475Smrg		    reply.a_final = 'x';
2463d522f475Smrg		    unparseseq(xw, &reply);
2464d522f475Smrg		}
2465d522f475Smrg	    }
246620d2c4d2Smrg	    ResetState(sp);
2467d522f475Smrg	    break;
2468d522f475Smrg
2469d522f475Smrg	case CASE_DECSET:
2470d522f475Smrg	    /* DECSET */
2471d522f475Smrg#if OPT_VT52_MODE
2472d522f475Smrg	    if (screen->vtXX_level != 0)
2473d522f475Smrg#endif
2474d522f475Smrg		dpmodes(xw, bitset);
247520d2c4d2Smrg	    ResetState(sp);
2476d522f475Smrg#if OPT_TEK4014
2477d522f475Smrg	    if (TEK4014_ACTIVE(xw))
2478d522f475Smrg		return False;
2479d522f475Smrg#endif
2480d522f475Smrg	    break;
2481d522f475Smrg
2482d522f475Smrg	case CASE_DECRST:
2483d522f475Smrg	    /* DECRST */
2484d522f475Smrg	    dpmodes(xw, bitclr);
24852eaa94a1Schristos	    init_groundtable(screen, sp);
248620d2c4d2Smrg	    ResetState(sp);
2487d522f475Smrg	    break;
2488d522f475Smrg
2489d522f475Smrg	case CASE_DECALN:
2490d522f475Smrg	    TRACE(("CASE_DECALN - alignment test\n"));
2491d522f475Smrg	    if (screen->cursor_state)
2492d522f475Smrg		HideCursor();
2493d522f475Smrg	    set_tb_margins(screen, 0, screen->max_row);
2494d522f475Smrg	    CursorSet(screen, 0, 0, xw->flags);
2495d522f475Smrg	    xtermParseRect(xw, 0, 0, &myRect);
2496d522f475Smrg	    ScrnFillRectangle(xw, &myRect, 'E', 0, False);
249720d2c4d2Smrg	    ResetState(sp);
2498d522f475Smrg	    break;
2499d522f475Smrg
2500d522f475Smrg	case CASE_GSETS:
2501d522f475Smrg	    TRACE(("CASE_GSETS(%d) = '%c'\n", sp->scstype, c));
2502d522f475Smrg	    if (screen->vtXX_level != 0)
25032eaa94a1Schristos		screen->gsets[sp->scstype] = CharOf(c);
250420d2c4d2Smrg	    ResetState(sp);
2505d522f475Smrg	    break;
2506d522f475Smrg
2507d522f475Smrg	case CASE_DECSC:
2508d522f475Smrg	    TRACE(("CASE_DECSC - save cursor\n"));
2509d522f475Smrg	    CursorSave(xw);
251020d2c4d2Smrg	    ResetState(sp);
2511d522f475Smrg	    break;
2512d522f475Smrg
2513d522f475Smrg	case CASE_DECRC:
2514d522f475Smrg	    TRACE(("CASE_DECRC - restore cursor\n"));
2515d522f475Smrg	    CursorRestore(xw);
2516d522f475Smrg	    if_OPT_ISO_COLORS(screen, {
2517d522f475Smrg		setExtendedFG(xw);
2518d522f475Smrg	    });
251920d2c4d2Smrg	    ResetState(sp);
2520d522f475Smrg	    break;
2521d522f475Smrg
2522d522f475Smrg	case CASE_DECKPAM:
2523d522f475Smrg	    TRACE(("CASE_DECKPAM\n"));
2524d522f475Smrg	    xw->keyboard.flags |= MODE_DECKPAM;
2525d522f475Smrg	    update_appkeypad();
252620d2c4d2Smrg	    ResetState(sp);
2527d522f475Smrg	    break;
2528d522f475Smrg
2529d522f475Smrg	case CASE_DECKPNM:
2530d522f475Smrg	    TRACE(("CASE_DECKPNM\n"));
253120d2c4d2Smrg	    UIntClr(xw->keyboard.flags, MODE_DECKPAM);
2532d522f475Smrg	    update_appkeypad();
253320d2c4d2Smrg	    ResetState(sp);
2534d522f475Smrg	    break;
2535d522f475Smrg
2536d522f475Smrg	case CASE_CSI_QUOTE_STATE:
2537d522f475Smrg	    sp->parsestate = csi_quo_table;
2538d522f475Smrg	    break;
2539d522f475Smrg
254020d2c4d2Smrg#if OPT_BLINK_CURS
254120d2c4d2Smrg	case CASE_CSI_SPACE_STATE:
254220d2c4d2Smrg	    sp->parsestate = csi_sp_table;
254320d2c4d2Smrg	    break;
254420d2c4d2Smrg
254520d2c4d2Smrg	case CASE_DECSCUSR:
254620d2c4d2Smrg	    TRACE(("CASE_DECSCUSR\n"));
254720d2c4d2Smrg	    {
254820d2c4d2Smrg		Boolean change = True;
254920d2c4d2Smrg		Boolean blinks = screen->cursor_blink;
255020d2c4d2Smrg
255120d2c4d2Smrg		HideCursor();
255220d2c4d2Smrg
255320d2c4d2Smrg		switch (param[0]) {
255420d2c4d2Smrg		case 0:
255520d2c4d2Smrg		case 1:
255620d2c4d2Smrg		case DEFAULT:
255720d2c4d2Smrg		    /* blinking block */
255820d2c4d2Smrg		    screen->cursor_underline = False;
255920d2c4d2Smrg		    blinks = True;
256020d2c4d2Smrg		    break;
256120d2c4d2Smrg		case 2:
256220d2c4d2Smrg		    /* steady block */
256320d2c4d2Smrg		    screen->cursor_underline = False;
256420d2c4d2Smrg		    blinks = False;
256520d2c4d2Smrg		    break;
256620d2c4d2Smrg		case 3:
256720d2c4d2Smrg		    /* blinking underline */
256820d2c4d2Smrg		    screen->cursor_underline = True;
256920d2c4d2Smrg		    blinks = True;
257020d2c4d2Smrg		    break;
257120d2c4d2Smrg		case 4:
257220d2c4d2Smrg		    /* steady underline */
257320d2c4d2Smrg		    screen->cursor_underline = True;
257420d2c4d2Smrg		    blinks = False;
257520d2c4d2Smrg		    break;
257620d2c4d2Smrg		default:
257720d2c4d2Smrg		    change = False;
257820d2c4d2Smrg		    break;
257920d2c4d2Smrg		}
258020d2c4d2Smrg
258120d2c4d2Smrg		if (change) {
258220d2c4d2Smrg		    xtermSetCursorBox(screen);
258320d2c4d2Smrg		    SetCursorBlink(screen, blinks);
258420d2c4d2Smrg		}
258520d2c4d2Smrg	    }
258620d2c4d2Smrg	    ResetState(sp);
258720d2c4d2Smrg	    break;
258820d2c4d2Smrg#endif
258920d2c4d2Smrg
259020d2c4d2Smrg#if OPT_SCROLL_LOCK
259120d2c4d2Smrg	case CASE_DECLL:
259220d2c4d2Smrg	    TRACE(("CASE_DECLL\n"));
259320d2c4d2Smrg	    if (nparam > 0) {
259420d2c4d2Smrg		for (count = 0; count < nparam; ++count) {
259520d2c4d2Smrg		    switch (param[count]) {
259620d2c4d2Smrg		    case 0:
259720d2c4d2Smrg		    case DEFAULT:
259820d2c4d2Smrg			xtermClearLEDs(screen);
259920d2c4d2Smrg			break;
260020d2c4d2Smrg		    case 1:
260120d2c4d2Smrg		    case 2:
260220d2c4d2Smrg		    case 3:
260320d2c4d2Smrg			xtermShowLED(screen, (Cardinal) param[count], True);
260420d2c4d2Smrg			break;
260520d2c4d2Smrg		    case 21:
260620d2c4d2Smrg		    case 22:
260720d2c4d2Smrg		    case 23:
260820d2c4d2Smrg			xtermShowLED(screen, (Cardinal) (param[count] - 20), True);
260920d2c4d2Smrg			break;
261020d2c4d2Smrg		    }
261120d2c4d2Smrg		}
261220d2c4d2Smrg	    } else {
261320d2c4d2Smrg		xtermClearLEDs(screen);
261420d2c4d2Smrg	    }
261520d2c4d2Smrg	    ResetState(sp);
261620d2c4d2Smrg	    break;
261720d2c4d2Smrg#endif
261820d2c4d2Smrg
2619d522f475Smrg#if OPT_VT52_MODE
2620d522f475Smrg	case CASE_VT52_FINISH:
2621d522f475Smrg	    TRACE(("CASE_VT52_FINISH terminal_id %d, vtXX_level %d\n",
2622d522f475Smrg		   screen->terminal_id,
2623d522f475Smrg		   screen->vtXX_level));
2624d522f475Smrg	    if (screen->terminal_id >= 100
2625d522f475Smrg		&& screen->vtXX_level == 0) {
2626d522f475Smrg		sp->groundtable =
2627d522f475Smrg		    sp->parsestate = ansi_table;
2628d522f475Smrg		screen->vtXX_level = screen->vt52_save_level;
2629d522f475Smrg		screen->curgl = screen->vt52_save_curgl;
2630d522f475Smrg		screen->curgr = screen->vt52_save_curgr;
2631d522f475Smrg		screen->curss = screen->vt52_save_curss;
2632d522f475Smrg		memmove(screen->gsets, screen->vt52_save_gsets, sizeof(screen->gsets));
2633d522f475Smrg	    }
2634d522f475Smrg	    break;
2635d522f475Smrg#endif
2636d522f475Smrg
2637d522f475Smrg	case CASE_ANSI_LEVEL_1:
2638d522f475Smrg	    TRACE(("CASE_ANSI_LEVEL_1\n"));
2639d522f475Smrg	    set_ansi_conformance(screen, 1);
264020d2c4d2Smrg	    ResetState(sp);
2641d522f475Smrg	    break;
2642d522f475Smrg
2643d522f475Smrg	case CASE_ANSI_LEVEL_2:
2644d522f475Smrg	    TRACE(("CASE_ANSI_LEVEL_2\n"));
2645d522f475Smrg	    set_ansi_conformance(screen, 2);
264620d2c4d2Smrg	    ResetState(sp);
2647d522f475Smrg	    break;
2648d522f475Smrg
2649d522f475Smrg	case CASE_ANSI_LEVEL_3:
2650d522f475Smrg	    TRACE(("CASE_ANSI_LEVEL_3\n"));
2651d522f475Smrg	    set_ansi_conformance(screen, 3);
265220d2c4d2Smrg	    ResetState(sp);
2653d522f475Smrg	    break;
2654d522f475Smrg
2655d522f475Smrg	case CASE_DECSCL:
2656d522f475Smrg	    TRACE(("CASE_DECSCL(%d,%d)\n", param[0], param[1]));
2657d522f475Smrg	    if (param[0] >= 61 && param[0] <= 65) {
2658d522f475Smrg		/*
2659d522f475Smrg		 * VT300, VT420, VT520 manuals claim that DECSCL does a hard
2660d522f475Smrg		 * reset (RIS).  VT220 manual states that it is a soft reset.
2661d522f475Smrg		 * Perhaps both are right (unlikely).  Kermit says it's soft.
2662d522f475Smrg		 */
2663d522f475Smrg		VTReset(xw, False, False);
2664d522f475Smrg		screen->vtXX_level = param[0] - 60;
2665d522f475Smrg		if (param[0] > 61) {
266620d2c4d2Smrg		    switch (zero_if_default(1)) {
266720d2c4d2Smrg		    case 1:
2668d522f475Smrg			show_8bit_control(False);
266920d2c4d2Smrg			break;
267020d2c4d2Smrg		    case 0:
267120d2c4d2Smrg		    case 2:
2672d522f475Smrg			show_8bit_control(True);
267320d2c4d2Smrg			break;
267420d2c4d2Smrg		    }
2675d522f475Smrg		}
2676d522f475Smrg	    }
267720d2c4d2Smrg	    ResetState(sp);
2678d522f475Smrg	    break;
2679d522f475Smrg
2680d522f475Smrg	case CASE_DECSCA:
2681d522f475Smrg	    TRACE(("CASE_DECSCA\n"));
2682d522f475Smrg	    screen->protected_mode = DEC_PROTECT;
2683d522f475Smrg	    if (param[0] <= 0 || param[0] == 2)
268420d2c4d2Smrg		UIntClr(xw->flags, PROTECTED);
2685d522f475Smrg	    else if (param[0] == 1)
2686d522f475Smrg		xw->flags |= PROTECTED;
268720d2c4d2Smrg	    ResetState(sp);
2688d522f475Smrg	    break;
2689d522f475Smrg
2690d522f475Smrg	case CASE_DECSED:
2691d522f475Smrg	    TRACE(("CASE_DECSED\n"));
2692d522f475Smrg	    do_erase_display(xw, param[0], DEC_PROTECT);
269320d2c4d2Smrg	    ResetState(sp);
2694d522f475Smrg	    break;
2695d522f475Smrg
2696d522f475Smrg	case CASE_DECSEL:
2697d522f475Smrg	    TRACE(("CASE_DECSEL\n"));
2698d522f475Smrg	    do_erase_line(xw, param[0], DEC_PROTECT);
269920d2c4d2Smrg	    ResetState(sp);
2700d522f475Smrg	    break;
2701d522f475Smrg
2702d522f475Smrg	case CASE_ST:
270320d2c4d2Smrg	    TRACE(("CASE_ST: End of String (%lu bytes)\n", (unsigned long) sp->string_used));
270420d2c4d2Smrg	    ResetState(sp);
2705956cc18dSsnj	    if (!sp->string_used)
2706d522f475Smrg		break;
2707956cc18dSsnj	    sp->string_area[--(sp->string_used)] = '\0';
2708d522f475Smrg	    switch (sp->string_mode) {
2709d522f475Smrg	    case ANSI_APC:
2710d522f475Smrg		/* ignored */
2711d522f475Smrg		break;
2712d522f475Smrg	    case ANSI_DCS:
2713956cc18dSsnj		do_dcs(xw, sp->string_area, sp->string_used);
2714d522f475Smrg		break;
2715d522f475Smrg	    case ANSI_OSC:
2716956cc18dSsnj		do_osc(xw, sp->string_area, sp->string_used, ANSI_ST);
2717d522f475Smrg		break;
2718d522f475Smrg	    case ANSI_PM:
2719d522f475Smrg		/* ignored */
2720d522f475Smrg		break;
2721d522f475Smrg	    case ANSI_SOS:
2722d522f475Smrg		/* ignored */
2723d522f475Smrg		break;
2724d522f475Smrg	    }
2725d522f475Smrg	    break;
2726d522f475Smrg
2727d522f475Smrg	case CASE_SOS:
2728d522f475Smrg	    TRACE(("CASE_SOS: Start of String\n"));
272920d2c4d2Smrg	    if (ParseSOS(screen)) {
273020d2c4d2Smrg		sp->string_mode = ANSI_SOS;
273120d2c4d2Smrg		sp->parsestate = sos_table;
273220d2c4d2Smrg	    } else {
273320d2c4d2Smrg		illegal_parse(xw, c, sp);
273420d2c4d2Smrg	    }
2735d522f475Smrg	    break;
2736d522f475Smrg
2737d522f475Smrg	case CASE_PM:
2738d522f475Smrg	    TRACE(("CASE_PM: Privacy Message\n"));
273920d2c4d2Smrg	    if (ParseSOS(screen)) {
274020d2c4d2Smrg		sp->string_mode = ANSI_PM;
274120d2c4d2Smrg		sp->parsestate = sos_table;
274220d2c4d2Smrg	    } else {
274320d2c4d2Smrg		illegal_parse(xw, c, sp);
274420d2c4d2Smrg	    }
2745d522f475Smrg	    break;
2746d522f475Smrg
2747d522f475Smrg	case CASE_DCS:
2748d522f475Smrg	    TRACE(("CASE_DCS: Device Control String\n"));
2749d522f475Smrg	    sp->string_mode = ANSI_DCS;
2750d522f475Smrg	    sp->parsestate = sos_table;
2751d522f475Smrg	    break;
2752d522f475Smrg
2753d522f475Smrg	case CASE_APC:
2754d522f475Smrg	    TRACE(("CASE_APC: Application Program Command\n"));
275520d2c4d2Smrg	    if (ParseSOS(screen)) {
275620d2c4d2Smrg		sp->string_mode = ANSI_APC;
275720d2c4d2Smrg		sp->parsestate = sos_table;
275820d2c4d2Smrg	    } else {
275920d2c4d2Smrg		illegal_parse(xw, c, sp);
276020d2c4d2Smrg	    }
2761d522f475Smrg	    break;
2762d522f475Smrg
2763d522f475Smrg	case CASE_SPA:
2764d522f475Smrg	    TRACE(("CASE_SPA - start protected area\n"));
2765d522f475Smrg	    screen->protected_mode = ISO_PROTECT;
2766d522f475Smrg	    xw->flags |= PROTECTED;
276720d2c4d2Smrg	    ResetState(sp);
2768d522f475Smrg	    break;
2769d522f475Smrg
2770d522f475Smrg	case CASE_EPA:
2771d522f475Smrg	    TRACE(("CASE_EPA - end protected area\n"));
277220d2c4d2Smrg	    UIntClr(xw->flags, PROTECTED);
277320d2c4d2Smrg	    ResetState(sp);
2774d522f475Smrg	    break;
2775d522f475Smrg
2776d522f475Smrg	case CASE_SU:
2777d522f475Smrg	    TRACE(("CASE_SU - scroll up\n"));
2778d522f475Smrg	    if ((count = param[0]) < 1)
2779d522f475Smrg		count = 1;
2780d522f475Smrg	    xtermScroll(xw, count);
278120d2c4d2Smrg	    ResetState(sp);
2782d522f475Smrg	    break;
2783d522f475Smrg
2784d522f475Smrg	case CASE_IND:
2785d522f475Smrg	    TRACE(("CASE_IND - index\n"));
2786d522f475Smrg	    xtermIndex(xw, 1);
2787d522f475Smrg	    do_xevents();
278820d2c4d2Smrg	    ResetState(sp);
2789d522f475Smrg	    break;
2790d522f475Smrg
2791d522f475Smrg	case CASE_CPL:
2792d522f475Smrg	    TRACE(("CASE_CPL - cursor prev line\n"));
2793d522f475Smrg	    CursorPrevLine(screen, param[0]);
279420d2c4d2Smrg	    ResetState(sp);
2795d522f475Smrg	    break;
2796d522f475Smrg
2797d522f475Smrg	case CASE_CNL:
2798d522f475Smrg	    TRACE(("CASE_CNL - cursor next line\n"));
2799d522f475Smrg	    CursorNextLine(screen, param[0]);
280020d2c4d2Smrg	    ResetState(sp);
2801d522f475Smrg	    break;
2802d522f475Smrg
2803d522f475Smrg	case CASE_NEL:
2804d522f475Smrg	    TRACE(("CASE_NEL\n"));
2805d522f475Smrg	    xtermIndex(xw, 1);
2806d522f475Smrg	    CarriageReturn(screen);
280720d2c4d2Smrg	    ResetState(sp);
2808d522f475Smrg	    break;
2809d522f475Smrg
2810d522f475Smrg	case CASE_HTS:
2811d522f475Smrg	    TRACE(("CASE_HTS - horizontal tab set\n"));
2812d522f475Smrg	    TabSet(xw->tabs, screen->cur_col);
281320d2c4d2Smrg	    ResetState(sp);
2814d522f475Smrg	    break;
2815d522f475Smrg
2816d522f475Smrg	case CASE_RI:
2817d522f475Smrg	    TRACE(("CASE_RI - reverse index\n"));
2818d522f475Smrg	    RevIndex(xw, 1);
281920d2c4d2Smrg	    ResetState(sp);
2820d522f475Smrg	    break;
2821d522f475Smrg
2822d522f475Smrg	case CASE_SS2:
2823d522f475Smrg	    TRACE(("CASE_SS2\n"));
2824d522f475Smrg	    screen->curss = 2;
282520d2c4d2Smrg	    ResetState(sp);
2826d522f475Smrg	    break;
2827d522f475Smrg
2828d522f475Smrg	case CASE_SS3:
2829d522f475Smrg	    TRACE(("CASE_SS3\n"));
2830d522f475Smrg	    screen->curss = 3;
283120d2c4d2Smrg	    ResetState(sp);
2832d522f475Smrg	    break;
2833d522f475Smrg
2834d522f475Smrg	case CASE_CSI_STATE:
2835d522f475Smrg	    /* enter csi state */
2836d522f475Smrg	    nparam = 1;
2837d522f475Smrg	    param[0] = DEFAULT;
2838d522f475Smrg	    sp->parsestate = csi_table;
2839d522f475Smrg	    break;
2840d522f475Smrg
2841d522f475Smrg	case CASE_ESC_SP_STATE:
2842d522f475Smrg	    /* esc space */
2843d522f475Smrg	    sp->parsestate = esc_sp_table;
2844d522f475Smrg	    break;
2845d522f475Smrg
2846d522f475Smrg	case CASE_CSI_EX_STATE:
2847d522f475Smrg	    /* csi exclamation */
2848d522f475Smrg	    sp->parsestate = csi_ex_table;
2849d522f475Smrg	    break;
2850d522f475Smrg
2851d522f475Smrg#if OPT_DEC_LOCATOR
2852d522f475Smrg	case CASE_CSI_TICK_STATE:
2853d522f475Smrg	    /* csi tick (') */
2854d522f475Smrg	    sp->parsestate = csi_tick_table;
2855d522f475Smrg	    break;
2856d522f475Smrg
2857d522f475Smrg	case CASE_DECEFR:
2858d522f475Smrg	    TRACE(("CASE_DECEFR - Enable Filter Rectangle\n"));
2859d522f475Smrg	    if (screen->send_mouse_pos == DEC_LOCATOR) {
2860d522f475Smrg		MotionOff(screen, xw);
2861d522f475Smrg		if ((screen->loc_filter_top = param[0]) < 1)
2862d522f475Smrg		    screen->loc_filter_top = LOC_FILTER_POS;
2863d522f475Smrg		if (nparam < 2 || (screen->loc_filter_left = param[1]) < 1)
2864d522f475Smrg		    screen->loc_filter_left = LOC_FILTER_POS;
2865d522f475Smrg		if (nparam < 3 || (screen->loc_filter_bottom = param[2]) < 1)
2866d522f475Smrg		    screen->loc_filter_bottom = LOC_FILTER_POS;
2867d522f475Smrg		if (nparam < 4 || (screen->loc_filter_right = param[3]) < 1)
2868d522f475Smrg		    screen->loc_filter_right = LOC_FILTER_POS;
2869d522f475Smrg		InitLocatorFilter(xw);
2870d522f475Smrg	    }
287120d2c4d2Smrg	    ResetState(sp);
2872d522f475Smrg	    break;
2873d522f475Smrg
2874d522f475Smrg	case CASE_DECELR:
2875d522f475Smrg	    MotionOff(screen, xw);
2876d522f475Smrg	    if (param[0] <= 0 || param[0] > 2) {
2877d522f475Smrg		screen->send_mouse_pos = MOUSE_OFF;
2878d522f475Smrg		TRACE(("DECELR - Disable Locator Reports\n"));
2879d522f475Smrg	    } else {
2880d522f475Smrg		TRACE(("DECELR - Enable Locator Reports\n"));
2881d522f475Smrg		screen->send_mouse_pos = DEC_LOCATOR;
2882d522f475Smrg		xtermShowPointer(xw, True);
2883d522f475Smrg		if (param[0] == 2) {
2884d522f475Smrg		    screen->locator_reset = True;
2885d522f475Smrg		} else {
2886d522f475Smrg		    screen->locator_reset = False;
2887d522f475Smrg		}
2888d522f475Smrg		if (nparam < 2 || param[1] != 1) {
2889d522f475Smrg		    screen->locator_pixels = False;
2890d522f475Smrg		} else {
2891d522f475Smrg		    screen->locator_pixels = True;
2892d522f475Smrg		}
2893d522f475Smrg		screen->loc_filter = False;
2894d522f475Smrg	    }
289520d2c4d2Smrg	    ResetState(sp);
2896d522f475Smrg	    break;
2897d522f475Smrg
2898d522f475Smrg	case CASE_DECSLE:
2899d522f475Smrg	    TRACE(("DECSLE - Select Locator Events\n"));
2900d522f475Smrg	    for (count = 0; count < nparam; ++count) {
2901d522f475Smrg		switch (param[count]) {
2902d522f475Smrg		case DEFAULT:
2903d522f475Smrg		case 0:
2904d522f475Smrg		    MotionOff(screen, xw);
2905d522f475Smrg		    screen->loc_filter = False;
2906d522f475Smrg		    screen->locator_events = 0;
2907d522f475Smrg		    break;
2908d522f475Smrg		case 1:
2909d522f475Smrg		    screen->locator_events |= LOC_BTNS_DN;
2910d522f475Smrg		    break;
2911d522f475Smrg		case 2:
291220d2c4d2Smrg		    UIntClr(screen->locator_events, LOC_BTNS_DN);
2913d522f475Smrg		    break;
2914d522f475Smrg		case 3:
2915d522f475Smrg		    screen->locator_events |= LOC_BTNS_UP;
2916d522f475Smrg		    break;
2917d522f475Smrg		case 4:
291820d2c4d2Smrg		    UIntClr(screen->locator_events, LOC_BTNS_UP);
2919d522f475Smrg		    break;
2920d522f475Smrg		}
2921d522f475Smrg	    }
292220d2c4d2Smrg	    ResetState(sp);
2923d522f475Smrg	    break;
2924d522f475Smrg
2925d522f475Smrg	case CASE_DECRQLP:
2926d522f475Smrg	    TRACE(("DECRQLP - Request Locator Position\n"));
2927d522f475Smrg	    if (param[0] < 2) {
2928d522f475Smrg		/* Issue DECLRP Locator Position Report */
2929d522f475Smrg		GetLocatorPosition(xw);
2930d522f475Smrg	    }
293120d2c4d2Smrg	    ResetState(sp);
2932d522f475Smrg	    break;
2933d522f475Smrg#endif /* OPT_DEC_LOCATOR */
2934d522f475Smrg
2935d522f475Smrg#if OPT_DEC_RECTOPS
2936d522f475Smrg	case CASE_CSI_DOLLAR_STATE:
2937d522f475Smrg	    /* csi dollar ($) */
2938d522f475Smrg	    if (screen->vtXX_level >= 4)
2939d522f475Smrg		sp->parsestate = csi_dollar_table;
2940d522f475Smrg	    else
2941d522f475Smrg		sp->parsestate = eigtable;
2942d522f475Smrg	    break;
2943d522f475Smrg
2944d522f475Smrg	case CASE_CSI_STAR_STATE:
2945d522f475Smrg	    /* csi dollar (*) */
2946d522f475Smrg	    if (screen->vtXX_level >= 4)
2947d522f475Smrg		sp->parsestate = csi_star_table;
2948d522f475Smrg	    else
2949d522f475Smrg		sp->parsestate = eigtable;
2950d522f475Smrg	    break;
2951d522f475Smrg
2952d522f475Smrg	case CASE_DECCRA:
2953d522f475Smrg	    TRACE(("CASE_DECCRA - Copy rectangular area\n"));
2954d522f475Smrg	    xtermParseRect(xw, nparam, param, &myRect);
2955d522f475Smrg	    ScrnCopyRectangle(xw, &myRect, nparam - 5, param + 5);
295620d2c4d2Smrg	    ResetState(sp);
2957d522f475Smrg	    break;
2958d522f475Smrg
2959d522f475Smrg	case CASE_DECERA:
2960d522f475Smrg	    TRACE(("CASE_DECERA - Erase rectangular area\n"));
2961d522f475Smrg	    xtermParseRect(xw, nparam, param, &myRect);
2962d522f475Smrg	    ScrnFillRectangle(xw, &myRect, ' ', 0, True);
296320d2c4d2Smrg	    ResetState(sp);
2964d522f475Smrg	    break;
2965d522f475Smrg
2966d522f475Smrg	case CASE_DECFRA:
2967d522f475Smrg	    TRACE(("CASE_DECFRA - Fill rectangular area\n"));
2968d522f475Smrg	    if (nparam > 0
2969d522f475Smrg		&& ((param[0] >= 32 && param[0] <= 126)
2970d522f475Smrg		    || (param[0] >= 160 && param[0] <= 255))) {
2971d522f475Smrg		xtermParseRect(xw, nparam - 1, param + 1, &myRect);
2972d522f475Smrg		ScrnFillRectangle(xw, &myRect, param[0], xw->flags, True);
2973d522f475Smrg	    }
297420d2c4d2Smrg	    ResetState(sp);
2975d522f475Smrg	    break;
2976d522f475Smrg
2977d522f475Smrg	case CASE_DECSERA:
2978d522f475Smrg	    TRACE(("CASE_DECSERA - Selective erase rectangular area\n"));
2979d522f475Smrg	    xtermParseRect(xw, nparam > 4 ? 4 : nparam, param, &myRect);
2980d522f475Smrg	    ScrnWipeRectangle(xw, &myRect);
298120d2c4d2Smrg	    ResetState(sp);
2982d522f475Smrg	    break;
2983d522f475Smrg
2984d522f475Smrg	case CASE_DECSACE:
2985d522f475Smrg	    TRACE(("CASE_DECSACE - Select attribute change extent\n"));
2986d522f475Smrg	    screen->cur_decsace = param[0];
298720d2c4d2Smrg	    ResetState(sp);
2988d522f475Smrg	    break;
2989d522f475Smrg
2990d522f475Smrg	case CASE_DECCARA:
2991d522f475Smrg	    TRACE(("CASE_DECCARA - Change attributes in rectangular area\n"));
2992d522f475Smrg	    xtermParseRect(xw, nparam > 4 ? 4 : nparam, param, &myRect);
2993d522f475Smrg	    ScrnMarkRectangle(xw, &myRect, False, nparam - 4, param + 4);
299420d2c4d2Smrg	    ResetState(sp);
2995d522f475Smrg	    break;
2996d522f475Smrg
2997d522f475Smrg	case CASE_DECRARA:
2998d522f475Smrg	    TRACE(("CASE_DECRARA - Reverse attributes in rectangular area\n"));
2999d522f475Smrg	    xtermParseRect(xw, nparam > 4 ? 4 : nparam, param, &myRect);
3000d522f475Smrg	    ScrnMarkRectangle(xw, &myRect, True, nparam - 4, param + 4);
300120d2c4d2Smrg	    ResetState(sp);
3002d522f475Smrg	    break;
3003d522f475Smrg#else
3004d522f475Smrg	case CASE_CSI_DOLLAR_STATE:
3005d522f475Smrg	    /* csi dollar ($) */
3006d522f475Smrg	    sp->parsestate = eigtable;
3007d522f475Smrg	    break;
3008d522f475Smrg
3009d522f475Smrg	case CASE_CSI_STAR_STATE:
3010d522f475Smrg	    /* csi dollar (*) */
3011d522f475Smrg	    sp->parsestate = eigtable;
3012d522f475Smrg	    break;
3013d522f475Smrg#endif /* OPT_DEC_RECTOPS */
3014d522f475Smrg
3015d522f475Smrg	case CASE_S7C1T:
3016d522f475Smrg	    TRACE(("CASE_S7C1T\n"));
3017d522f475Smrg	    show_8bit_control(False);
301820d2c4d2Smrg	    ResetState(sp);
3019d522f475Smrg	    break;
3020d522f475Smrg
3021d522f475Smrg	case CASE_S8C1T:
3022d522f475Smrg	    TRACE(("CASE_S8C1T\n"));
3023d522f475Smrg#if OPT_VT52_MODE
3024d522f475Smrg	    if (screen->vtXX_level <= 1)
3025d522f475Smrg		break;
3026d522f475Smrg#endif
3027d522f475Smrg	    show_8bit_control(True);
302820d2c4d2Smrg	    ResetState(sp);
3029d522f475Smrg	    break;
3030d522f475Smrg
3031d522f475Smrg	case CASE_OSC:
3032d522f475Smrg	    TRACE(("CASE_OSC: Operating System Command\n"));
3033d522f475Smrg	    sp->parsestate = sos_table;
3034d522f475Smrg	    sp->string_mode = ANSI_OSC;
3035d522f475Smrg	    break;
3036d522f475Smrg
3037d522f475Smrg	case CASE_RIS:
3038d522f475Smrg	    TRACE(("CASE_RIS\n"));
3039d522f475Smrg	    VTReset(xw, True, True);
304020d2c4d2Smrg	    ResetState(sp);
3041d522f475Smrg	    break;
3042d522f475Smrg
3043d522f475Smrg	case CASE_DECSTR:
3044d522f475Smrg	    TRACE(("CASE_DECSTR\n"));
3045d522f475Smrg	    VTReset(xw, False, False);
304620d2c4d2Smrg	    ResetState(sp);
3047d522f475Smrg	    break;
3048d522f475Smrg
3049d522f475Smrg	case CASE_REP:
3050d522f475Smrg	    TRACE(("CASE_REP\n"));
3051d522f475Smrg	    if (sp->lastchar >= 0 &&
3052d522f475Smrg		sp->lastchar < 256 &&
3053d522f475Smrg		sp->groundtable[E2A(sp->lastchar)] == CASE_PRINT) {
3054d522f475Smrg		IChar repeated[2];
3055d522f475Smrg		count = (param[0] < 1) ? 1 : param[0];
30562eaa94a1Schristos		repeated[0] = (IChar) sp->lastchar;
3057d522f475Smrg		while (count-- > 0) {
3058d522f475Smrg		    dotext(xw,
3059d522f475Smrg			   screen->gsets[(int) (screen->curgl)],
3060d522f475Smrg			   repeated, 1);
3061d522f475Smrg		}
3062d522f475Smrg	    }
306320d2c4d2Smrg	    ResetState(sp);
3064d522f475Smrg	    break;
3065d522f475Smrg
3066d522f475Smrg	case CASE_LS2:
3067d522f475Smrg	    TRACE(("CASE_LS2\n"));
3068d522f475Smrg	    screen->curgl = 2;
306920d2c4d2Smrg	    ResetState(sp);
3070d522f475Smrg	    break;
3071d522f475Smrg
3072d522f475Smrg	case CASE_LS3:
3073d522f475Smrg	    TRACE(("CASE_LS3\n"));
3074d522f475Smrg	    screen->curgl = 3;
307520d2c4d2Smrg	    ResetState(sp);
3076d522f475Smrg	    break;
3077d522f475Smrg
3078d522f475Smrg	case CASE_LS3R:
3079d522f475Smrg	    TRACE(("CASE_LS3R\n"));
3080d522f475Smrg	    screen->curgr = 3;
308120d2c4d2Smrg	    ResetState(sp);
3082d522f475Smrg	    break;
3083d522f475Smrg
3084d522f475Smrg	case CASE_LS2R:
3085d522f475Smrg	    TRACE(("CASE_LS2R\n"));
3086d522f475Smrg	    screen->curgr = 2;
308720d2c4d2Smrg	    ResetState(sp);
3088d522f475Smrg	    break;
3089d522f475Smrg
3090d522f475Smrg	case CASE_LS1R:
3091d522f475Smrg	    TRACE(("CASE_LS1R\n"));
3092d522f475Smrg	    screen->curgr = 1;
309320d2c4d2Smrg	    ResetState(sp);
3094d522f475Smrg	    break;
3095d522f475Smrg
3096d522f475Smrg	case CASE_XTERM_SAVE:
3097d522f475Smrg	    savemodes(xw);
309820d2c4d2Smrg	    ResetState(sp);
3099d522f475Smrg	    break;
3100d522f475Smrg
3101d522f475Smrg	case CASE_XTERM_RESTORE:
3102d522f475Smrg	    restoremodes(xw);
310320d2c4d2Smrg	    ResetState(sp);
3104d522f475Smrg	    break;
3105d522f475Smrg
3106d522f475Smrg	case CASE_XTERM_WINOPS:
3107d522f475Smrg	    TRACE(("CASE_XTERM_WINOPS\n"));
310820d2c4d2Smrg	    window_ops(xw);
310920d2c4d2Smrg	    ResetState(sp);
3110d522f475Smrg	    break;
3111d522f475Smrg#if OPT_WIDE_CHARS
3112d522f475Smrg	case CASE_ESC_PERCENT:
3113d522f475Smrg	    sp->parsestate = esc_pct_table;
3114d522f475Smrg	    break;
3115d522f475Smrg
3116d522f475Smrg	case CASE_UTF8:
3117d522f475Smrg	    /* If we did not set UTF-8 mode from resource or the
3118d522f475Smrg	     * command-line, allow it to be enabled/disabled by
3119d522f475Smrg	     * control sequence.
3120d522f475Smrg	     */
3121d522f475Smrg	    if (screen->wide_chars
3122d522f475Smrg		&& screen->utf8_mode != uAlways) {
312320d2c4d2Smrg		if (!screen->wide_chars) {
312420d2c4d2Smrg		    WriteNow();
312520d2c4d2Smrg		    ChangeToWide(xw);
312620d2c4d2Smrg		}
3127d522f475Smrg		switchPtyData(screen, c == 'G');
3128d522f475Smrg		TRACE(("UTF8 mode %s\n",
3129d522f475Smrg		       BtoS(screen->utf8_mode)));
3130d522f475Smrg	    } else {
3131d522f475Smrg		TRACE(("UTF8 mode NOT turned %s (%s)\n",
3132d522f475Smrg		       BtoS(c == 'G'),
3133d522f475Smrg		       (screen->utf8_mode == uAlways)
3134d522f475Smrg		       ? "UTF-8 mode set from command-line"
3135d522f475Smrg		       : "wideChars resource was not set"));
3136d522f475Smrg	    }
313720d2c4d2Smrg	    ResetState(sp);
3138d522f475Smrg	    break;
3139d522f475Smrg#endif
3140d522f475Smrg#if OPT_MOD_FKEYS
3141d522f475Smrg	case CASE_SET_MOD_FKEYS:
3142d522f475Smrg	    TRACE(("CASE_SET_MOD_FKEYS\n"));
3143d522f475Smrg	    if (nparam >= 1) {
3144d522f475Smrg		set_mod_fkeys(xw, param[0], nparam > 1 ? param[1] : DEFAULT, True);
3145d522f475Smrg	    } else {
3146d522f475Smrg		for (row = 1; row <= 5; ++row)
3147d522f475Smrg		    set_mod_fkeys(xw, row, DEFAULT, True);
3148d522f475Smrg	    }
3149d522f475Smrg	    break;
3150d522f475Smrg	case CASE_SET_MOD_FKEYS0:
3151d522f475Smrg	    TRACE(("CASE_SET_MOD_FKEYS0\n"));
3152d522f475Smrg	    if (nparam >= 1 && param[0] != DEFAULT) {
3153d522f475Smrg		set_mod_fkeys(xw, param[0], -1, False);
3154d522f475Smrg	    } else {
3155d522f475Smrg		xw->keyboard.modify_now.function_keys = -1;
3156d522f475Smrg	    }
3157d522f475Smrg	    break;
3158d522f475Smrg#endif
3159d522f475Smrg	case CASE_HIDE_POINTER:
3160d522f475Smrg	    TRACE(("CASE_HIDE_POINTER\n"));
3161d522f475Smrg	    if (nparam >= 1 && param[0] != DEFAULT) {
3162d522f475Smrg		screen->pointer_mode = param[0];
3163d522f475Smrg	    } else {
3164d522f475Smrg		screen->pointer_mode = DEF_POINTER_MODE;
3165d522f475Smrg	    }
3166d522f475Smrg	    break;
3167d522f475Smrg
316820d2c4d2Smrg	case CASE_SM_TITLE:
316920d2c4d2Smrg	    TRACE(("CASE_SM_TITLE\n"));
317020d2c4d2Smrg	    if (nparam >= 1) {
317120d2c4d2Smrg		int n;
317220d2c4d2Smrg		for (n = 0; n < nparam; ++n) {
317320d2c4d2Smrg		    if (param[n] != DEFAULT)
317420d2c4d2Smrg			screen->title_modes |= (1 << param[n]);
317520d2c4d2Smrg		}
317620d2c4d2Smrg	    } else {
317720d2c4d2Smrg		screen->title_modes = DEF_TITLE_MODES;
317820d2c4d2Smrg	    }
317920d2c4d2Smrg	    TRACE(("...title_modes %#x\n", screen->title_modes));
318020d2c4d2Smrg	    break;
318120d2c4d2Smrg
318220d2c4d2Smrg	case CASE_RM_TITLE:
318320d2c4d2Smrg	    TRACE(("CASE_RM_TITLE\n"));
318420d2c4d2Smrg	    if (nparam >= 1) {
318520d2c4d2Smrg		int n;
318620d2c4d2Smrg		for (n = 0; n < nparam; ++n) {
318720d2c4d2Smrg		    if (param[n] != DEFAULT)
318820d2c4d2Smrg			screen->title_modes &= ~(1 << param[n]);
318920d2c4d2Smrg		}
319020d2c4d2Smrg	    } else {
319120d2c4d2Smrg		screen->title_modes = DEF_TITLE_MODES;
319220d2c4d2Smrg	    }
319320d2c4d2Smrg	    TRACE(("...title_modes %#x\n", screen->title_modes));
319420d2c4d2Smrg	    break;
319520d2c4d2Smrg
3196d522f475Smrg	case CASE_CSI_IGNORE:
3197d522f475Smrg	    sp->parsestate = cigtable;
3198d522f475Smrg	    break;
319920d2c4d2Smrg
320020d2c4d2Smrg	case CASE_DECSWBV:
320120d2c4d2Smrg	    TRACE(("CASE_DECSWBV\n"));
320220d2c4d2Smrg	    switch ((nparam >= 1) ? param[0] : DEFAULT) {
320320d2c4d2Smrg	    case 2:
320420d2c4d2Smrg	    case 3:
320520d2c4d2Smrg	    case 4:
320620d2c4d2Smrg		screen->warningVolume = bvLow;
320720d2c4d2Smrg		break;
320820d2c4d2Smrg	    case 5:
320920d2c4d2Smrg	    case 6:
321020d2c4d2Smrg	    case 7:
321120d2c4d2Smrg	    case 8:
321220d2c4d2Smrg		screen->warningVolume = bvHigh;
321320d2c4d2Smrg		break;
321420d2c4d2Smrg	    default:
321520d2c4d2Smrg		screen->warningVolume = bvOff;
321620d2c4d2Smrg		break;
321720d2c4d2Smrg	    }
321820d2c4d2Smrg	    TRACE(("...warningVolume %d\n", screen->warningVolume));
321920d2c4d2Smrg	    ResetState(sp);
322020d2c4d2Smrg	    break;
322120d2c4d2Smrg
322220d2c4d2Smrg	case CASE_DECSMBV:
322320d2c4d2Smrg	    TRACE(("CASE_DECSMBV\n"));
322420d2c4d2Smrg	    switch ((nparam >= 1) ? param[0] : DEFAULT) {
322520d2c4d2Smrg	    case 2:
322620d2c4d2Smrg	    case 3:
322720d2c4d2Smrg	    case 4:
322820d2c4d2Smrg		screen->marginVolume = bvLow;
322920d2c4d2Smrg		break;
323020d2c4d2Smrg	    case 0:
323120d2c4d2Smrg	    case DEFAULT:
323220d2c4d2Smrg	    case 5:
323320d2c4d2Smrg	    case 6:
323420d2c4d2Smrg	    case 7:
323520d2c4d2Smrg	    case 8:
323620d2c4d2Smrg		screen->marginVolume = bvHigh;
323720d2c4d2Smrg		break;
323820d2c4d2Smrg	    default:
323920d2c4d2Smrg		screen->marginVolume = bvOff;
324020d2c4d2Smrg		break;
324120d2c4d2Smrg	    }
324220d2c4d2Smrg	    TRACE(("...marginVolume %d\n", screen->marginVolume));
324320d2c4d2Smrg	    ResetState(sp);
324420d2c4d2Smrg	    break;
3245d522f475Smrg	}
3246d522f475Smrg	if (sp->parsestate == sp->groundtable)
3247d522f475Smrg	    sp->lastchar = thischar;
3248d522f475Smrg    } while (0);
3249d522f475Smrg
3250d522f475Smrg#if OPT_WIDE_CHARS
32512eaa94a1Schristos    screen->utf8_inparse = (Boolean) ((screen->utf8_mode != uFalse)
32522eaa94a1Schristos				      && (sp->parsestate != sos_table));
3253d522f475Smrg#endif
3254d522f475Smrg
3255d522f475Smrg    return True;
3256d522f475Smrg}
3257d522f475Smrg
3258d522f475Smrgstatic void
3259d522f475SmrgVTparse(XtermWidget xw)
3260d522f475Smrg{
3261d522f475Smrg    TScreen *screen;
3262d522f475Smrg
3263d522f475Smrg    /* We longjmp back to this point in VTReset() */
3264d522f475Smrg    (void) setjmp(vtjmpbuf);
326520d2c4d2Smrg    screen = TScreenOf(xw);
3266d522f475Smrg    memset(&myState, 0, sizeof(myState));
32672eaa94a1Schristos    myState.scssize = 94;	/* number of printable/nonspace ASCII */
3268d522f475Smrg    myState.lastchar = -1;	/* not a legal IChar */
3269d522f475Smrg    myState.nextstate = -1;	/* not a legal state */
3270d522f475Smrg
32712eaa94a1Schristos    init_groundtable(screen, &myState);
32722eaa94a1Schristos    myState.parsestate = myState.groundtable;
32732eaa94a1Schristos
3274d522f475Smrg    do {
3275d522f475Smrg    } while (doparsing(xw, doinput(), &myState));
3276d522f475Smrg}
3277d522f475Smrg
3278d522f475Smrgstatic Char *v_buffer;		/* pointer to physical buffer */
3279d522f475Smrgstatic Char *v_bufstr = NULL;	/* beginning of area to write */
3280d522f475Smrgstatic Char *v_bufptr;		/* end of area to write */
3281d522f475Smrgstatic Char *v_bufend;		/* end of physical buffer */
3282d522f475Smrg
3283d522f475Smrg/* Write data to the pty as typed by the user, pasted with the mouse,
3284d522f475Smrg   or generated by us in response to a query ESC sequence. */
3285d522f475Smrg
328620d2c4d2Smrgvoid
3287d522f475Smrgv_write(int f, Char * data, unsigned len)
3288d522f475Smrg{
3289d522f475Smrg    int riten;
3290d522f475Smrg
329120d2c4d2Smrg    TRACE2(("v_write(%d:%s)\n", len, visibleChars(data, len)));
3292d522f475Smrg    if (v_bufstr == NULL && len > 0) {
3293956cc18dSsnj	v_buffer = (Char *) XtMalloc((Cardinal) len);
3294d522f475Smrg	v_bufstr = v_buffer;
3295d522f475Smrg	v_bufptr = v_buffer;
3296d522f475Smrg	v_bufend = v_buffer + len;
3297d522f475Smrg    }
3298d522f475Smrg#ifdef DEBUG
3299d522f475Smrg    if (debug) {
3300d522f475Smrg	fprintf(stderr, "v_write called with %d bytes (%d left over)",
3301d522f475Smrg		len, v_bufptr - v_bufstr);
3302d522f475Smrg	if (len > 1 && len < 10)
3303d522f475Smrg	    fprintf(stderr, " \"%.*s\"", len, (char *) data);
3304d522f475Smrg	fprintf(stderr, "\n");
3305d522f475Smrg    }
3306d522f475Smrg#endif
3307d522f475Smrg
3308d522f475Smrg#ifdef VMS
330920d2c4d2Smrg    if ((1 << f) != pty_mask) {
331020d2c4d2Smrg	tt_write((char *) data, len);
331120d2c4d2Smrg	return;
331220d2c4d2Smrg    }
3313d522f475Smrg#else /* VMS */
331420d2c4d2Smrg    if (!FD_ISSET(f, &pty_mask)) {
331520d2c4d2Smrg	IGNORE_RC(write(f, (char *) data, (size_t) len));
331620d2c4d2Smrg	return;
331720d2c4d2Smrg    }
3318d522f475Smrg#endif /* VMS */
3319d522f475Smrg
3320d522f475Smrg    /*
3321d522f475Smrg     * Append to the block we already have.
3322d522f475Smrg     * Always doing this simplifies the code, and
3323d522f475Smrg     * isn't too bad, either.  If this is a short
3324d522f475Smrg     * block, it isn't too expensive, and if this is
3325d522f475Smrg     * a long block, we won't be able to write it all
3326d522f475Smrg     * anyway.
3327d522f475Smrg     */
3328d522f475Smrg
3329d522f475Smrg    if (len > 0) {
3330d522f475Smrg#if OPT_DABBREV
333120d2c4d2Smrg	TScreenOf(term)->dabbrev_working = False;	/* break dabbrev sequence */
3332d522f475Smrg#endif
3333d522f475Smrg	if (v_bufend < v_bufptr + len) {	/* we've run out of room */
3334d522f475Smrg	    if (v_bufstr != v_buffer) {
3335d522f475Smrg		/* there is unused space, move everything down */
3336d522f475Smrg		/* possibly overlapping memmove here */
3337d522f475Smrg#ifdef DEBUG
3338d522f475Smrg		if (debug)
3339d522f475Smrg		    fprintf(stderr, "moving data down %d\n",
3340d522f475Smrg			    v_bufstr - v_buffer);
3341d522f475Smrg#endif
334220d2c4d2Smrg		memmove(v_buffer, v_bufstr, (size_t) (v_bufptr - v_bufstr));
3343d522f475Smrg		v_bufptr -= v_bufstr - v_buffer;
3344d522f475Smrg		v_bufstr = v_buffer;
3345d522f475Smrg	    }
3346d522f475Smrg	    if (v_bufend < v_bufptr + len) {
3347d522f475Smrg		/* still won't fit: get more space */
3348d522f475Smrg		/* Don't use XtRealloc because an error is not fatal. */
33492eaa94a1Schristos		unsigned size = (unsigned) (v_bufptr - v_buffer);
3350d522f475Smrg		v_buffer = TypeRealloc(Char, size + len, v_buffer);
3351d522f475Smrg		if (v_buffer) {
3352d522f475Smrg#ifdef DEBUG
3353d522f475Smrg		    if (debug)
3354d522f475Smrg			fprintf(stderr, "expanded buffer to %d\n",
3355d522f475Smrg				size + len);
3356d522f475Smrg#endif
3357d522f475Smrg		    v_bufstr = v_buffer;
3358d522f475Smrg		    v_bufptr = v_buffer + size;
3359d522f475Smrg		    v_bufend = v_bufptr + len;
3360d522f475Smrg		} else {
3361d522f475Smrg		    /* no memory: ignore entire write request */
3362d522f475Smrg		    fprintf(stderr, "%s: cannot allocate buffer space\n",
3363d522f475Smrg			    xterm_name);
3364d522f475Smrg		    v_buffer = v_bufstr;	/* restore clobbered pointer */
3365d522f475Smrg		}
3366d522f475Smrg	    }
3367d522f475Smrg	}
3368d522f475Smrg	if (v_bufend >= v_bufptr + len) {
3369d522f475Smrg	    /* new stuff will fit */
337020d2c4d2Smrg	    memmove(v_bufptr, data, (size_t) len);
3371d522f475Smrg	    v_bufptr += len;
3372d522f475Smrg	}
3373d522f475Smrg    }
3374d522f475Smrg
3375d522f475Smrg    /*
3376d522f475Smrg     * Write out as much of the buffer as we can.
3377d522f475Smrg     * Be careful not to overflow the pty's input silo.
3378d522f475Smrg     * We are conservative here and only write
3379d522f475Smrg     * a small amount at a time.
3380d522f475Smrg     *
3381d522f475Smrg     * If we can't push all the data into the pty yet, we expect write
3382d522f475Smrg     * to return a non-negative number less than the length requested
3383d522f475Smrg     * (if some data written) or -1 and set errno to EAGAIN,
3384d522f475Smrg     * EWOULDBLOCK, or EINTR (if no data written).
3385d522f475Smrg     *
3386d522f475Smrg     * (Not all systems do this, sigh, so the code is actually
3387d522f475Smrg     * a little more forgiving.)
3388d522f475Smrg     */
3389d522f475Smrg
3390d522f475Smrg#define MAX_PTY_WRITE 128	/* 1/2 POSIX minimum MAX_INPUT */
3391d522f475Smrg
3392d522f475Smrg    if (v_bufptr > v_bufstr) {
3393d522f475Smrg#ifdef VMS
3394d522f475Smrg	riten = tt_write(v_bufstr,
3395d522f475Smrg			 ((v_bufptr - v_bufstr <= VMS_TERM_BUFFER_SIZE)
3396d522f475Smrg			  ? v_bufptr - v_bufstr
3397d522f475Smrg			  : VMS_TERM_BUFFER_SIZE));
3398d522f475Smrg	if (riten == 0)
3399d522f475Smrg	    return (riten);
3400d522f475Smrg#else /* VMS */
340120d2c4d2Smrg	riten = (int) write(f, v_bufstr,
340220d2c4d2Smrg			    (size_t) ((v_bufptr - v_bufstr <= MAX_PTY_WRITE)
340320d2c4d2Smrg				      ? v_bufptr - v_bufstr
340420d2c4d2Smrg				      : MAX_PTY_WRITE));
3405d522f475Smrg	if (riten < 0)
3406d522f475Smrg#endif /* VMS */
3407d522f475Smrg	{
3408d522f475Smrg#ifdef DEBUG
3409d522f475Smrg	    if (debug)
3410d522f475Smrg		perror("write");
3411d522f475Smrg#endif
3412d522f475Smrg	    riten = 0;
3413d522f475Smrg	}
3414d522f475Smrg#ifdef DEBUG
3415d522f475Smrg	if (debug)
3416d522f475Smrg	    fprintf(stderr, "write called with %d, wrote %d\n",
3417d522f475Smrg		    v_bufptr - v_bufstr <= MAX_PTY_WRITE ?
3418d522f475Smrg		    v_bufptr - v_bufstr : MAX_PTY_WRITE,
3419d522f475Smrg		    riten);
3420d522f475Smrg#endif
3421d522f475Smrg	v_bufstr += riten;
3422d522f475Smrg	if (v_bufstr >= v_bufptr)	/* we wrote it all */
3423d522f475Smrg	    v_bufstr = v_bufptr = v_buffer;
3424d522f475Smrg    }
3425d522f475Smrg
3426d522f475Smrg    /*
3427d522f475Smrg     * If we have lots of unused memory allocated, return it
3428d522f475Smrg     */
3429d522f475Smrg    if (v_bufend - v_bufptr > 1024) {	/* arbitrary hysteresis */
3430d522f475Smrg	/* save pointers across realloc */
343120d2c4d2Smrg	int start = (int) (v_bufstr - v_buffer);
343220d2c4d2Smrg	int size = (int) (v_bufptr - v_buffer);
3433d522f475Smrg	unsigned allocsize = (unsigned) (size ? size : 1);
3434d522f475Smrg
3435d522f475Smrg	v_buffer = TypeRealloc(Char, allocsize, v_buffer);
3436d522f475Smrg	if (v_buffer) {
3437d522f475Smrg	    v_bufstr = v_buffer + start;
3438d522f475Smrg	    v_bufptr = v_buffer + size;
3439d522f475Smrg	    v_bufend = v_buffer + allocsize;
3440d522f475Smrg#ifdef DEBUG
3441d522f475Smrg	    if (debug)
3442d522f475Smrg		fprintf(stderr, "shrunk buffer to %d\n", allocsize);
3443d522f475Smrg#endif
3444d522f475Smrg	} else {
3445d522f475Smrg	    /* should we print a warning if couldn't return memory? */
3446d522f475Smrg	    v_buffer = v_bufstr - start;	/* restore clobbered pointer */
3447d522f475Smrg	}
3448d522f475Smrg    }
3449d522f475Smrg}
3450d522f475Smrg
3451d522f475Smrg#ifdef VMS
3452d522f475Smrg#define	ptymask()	(v_bufptr > v_bufstr ? pty_mask : 0)
3453d522f475Smrg
3454d522f475Smrgstatic void
3455d522f475Smrgin_put(XtermWidget xw)
3456d522f475Smrg{
3457d522f475Smrg    static PtySelect select_mask;
3458d522f475Smrg    static PtySelect write_mask;
3459d522f475Smrg    int update = VTbuffer->update;
3460d522f475Smrg    int size;
3461d522f475Smrg
3462d522f475Smrg    int status;
3463d522f475Smrg    Dimension replyWidth, replyHeight;
3464d522f475Smrg    XtGeometryResult stat;
3465d522f475Smrg
346620d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
3467d522f475Smrg    char *cp;
3468d522f475Smrg    int i;
3469d522f475Smrg
3470d522f475Smrg    select_mask = pty_mask;	/* force initial read */
3471d522f475Smrg    for (;;) {
3472d522f475Smrg
3473d522f475Smrg	/* if the terminal changed size, resize the widget */
3474d522f475Smrg	if (tt_changed) {
3475d522f475Smrg	    tt_changed = False;
3476d522f475Smrg
34772eaa94a1Schristos	    stat = REQ_RESIZE((Widget) xw,
34782eaa94a1Schristos			      ((Dimension) FontWidth(screen)
34792eaa94a1Schristos			       * (tt_width)
34802eaa94a1Schristos			       + 2 * screen->border
34812eaa94a1Schristos			       + screen->fullVwin.sb_info.width),
34822eaa94a1Schristos			      ((Dimension) FontHeight(screen)
34832eaa94a1Schristos			       * (tt_length)
34842eaa94a1Schristos			       + 2 * screen->border),
34852eaa94a1Schristos			      &replyWidth, &replyHeight);
3486d522f475Smrg
3487d522f475Smrg	    if (stat == XtGeometryYes || stat == XtGeometryDone) {
3488d522f475Smrg		xw->core.width = replyWidth;
3489d522f475Smrg		xw->core.height = replyHeight;
3490d522f475Smrg
3491d522f475Smrg		ScreenResize(xw, replyWidth, replyHeight, &xw->flags);
3492d522f475Smrg	    }
3493d522f475Smrg	    repairSizeHints();
3494d522f475Smrg	}
3495d522f475Smrg
3496d522f475Smrg	if (screen->eventMode == NORMAL
349720d2c4d2Smrg	    && readPtyData(xw, &select_mask, VTbuffer)) {
3498d522f475Smrg	    if (screen->scrollWidget
3499d522f475Smrg		&& screen->scrollttyoutput
3500d522f475Smrg		&& screen->topline < 0)
3501d522f475Smrg		/* Scroll to bottom */
350220d2c4d2Smrg		WindowScroll(xw, 0, False);
3503d522f475Smrg	    break;
3504d522f475Smrg	}
3505d522f475Smrg	if (screen->scroll_amt)
3506d522f475Smrg	    FlushScroll(xw);
3507d522f475Smrg	if (screen->cursor_set && CursorMoved(screen)) {
3508d522f475Smrg	    if (screen->cursor_state)
3509d522f475Smrg		HideCursor();
3510d522f475Smrg	    ShowCursor();
3511d522f475Smrg#if OPT_INPUT_METHOD
3512d522f475Smrg	    PreeditPosition(screen);
3513d522f475Smrg#endif
3514d522f475Smrg	} else if (screen->cursor_set != screen->cursor_state) {
3515d522f475Smrg	    if (screen->cursor_set)
3516d522f475Smrg		ShowCursor();
3517d522f475Smrg	    else
3518d522f475Smrg		HideCursor();
3519d522f475Smrg	}
3520d522f475Smrg
3521d522f475Smrg	if (QLength(screen->display)) {
3522d522f475Smrg	    select_mask = X_mask;
3523d522f475Smrg	} else {
3524d522f475Smrg	    write_mask = ptymask();
3525d522f475Smrg	    XFlush(screen->display);
3526d522f475Smrg	    select_mask = Select_mask;
3527d522f475Smrg	    if (screen->eventMode != NORMAL)
3528d522f475Smrg		select_mask = X_mask;
3529d522f475Smrg	}
3530d522f475Smrg	if (write_mask & ptymask()) {
3531d522f475Smrg	    v_write(screen->respond, 0, 0);	/* flush buffer */
3532d522f475Smrg	}
3533d522f475Smrg
3534d522f475Smrg	if (select_mask & X_mask) {
3535d522f475Smrg	    xevents();
3536d522f475Smrg	    if (VTbuffer->update != update)
3537d522f475Smrg		break;
3538d522f475Smrg	}
3539d522f475Smrg    }
3540d522f475Smrg}
3541d522f475Smrg#else /* VMS */
3542d522f475Smrg
3543d522f475Smrgstatic void
3544d522f475Smrgin_put(XtermWidget xw)
3545d522f475Smrg{
3546d522f475Smrg    static PtySelect select_mask;
3547d522f475Smrg    static PtySelect write_mask;
3548d522f475Smrg
354920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
3550d522f475Smrg    int i, time_select;
3551d522f475Smrg    int size;
3552d522f475Smrg    int update = VTbuffer->update;
3553d522f475Smrg
3554d522f475Smrg    static struct timeval select_timeout;
3555d522f475Smrg
3556d522f475Smrg#if OPT_BLINK_CURS
3557d522f475Smrg    /*
3558d522f475Smrg     * Compute the timeout for the blinking cursor to be much smaller than
3559d522f475Smrg     * the "on" or "off" interval.
3560d522f475Smrg     */
3561d522f475Smrg    int tick = ((screen->blink_on < screen->blink_off)
3562d522f475Smrg		? screen->blink_on
3563d522f475Smrg		: screen->blink_off);
3564d522f475Smrg    tick *= (1000 / 8);		/* 1000 for msec/usec, 8 for "much" smaller */
3565d522f475Smrg    if (tick < 1)
3566d522f475Smrg	tick = 1;
3567d522f475Smrg#endif
3568d522f475Smrg
3569d522f475Smrg    for (;;) {
3570d522f475Smrg	if (screen->eventMode == NORMAL
357120d2c4d2Smrg	    && (size = readPtyData(xw, &select_mask, VTbuffer)) != 0) {
3572d522f475Smrg	    if (screen->scrollWidget
3573d522f475Smrg		&& screen->scrollttyoutput
3574d522f475Smrg		&& screen->topline < 0)
357520d2c4d2Smrg		WindowScroll(xw, 0, False);	/* Scroll to bottom */
3576d522f475Smrg	    /* stop speed reading at some point to look for X stuff */
357720d2c4d2Smrg	    TRACE(("VTbuffer uses %ld/%d\n",
357820d2c4d2Smrg		   (long) (VTbuffer->last - VTbuffer->buffer),
3579d522f475Smrg		   BUF_SIZE));
3580d522f475Smrg	    if ((VTbuffer->last - VTbuffer->buffer) > BUF_SIZE) {
3581d522f475Smrg		FD_CLR(screen->respond, &select_mask);
3582d522f475Smrg		break;
3583d522f475Smrg	    }
3584d522f475Smrg#if defined(HAVE_SCHED_YIELD)
3585d522f475Smrg	    /*
3586d522f475Smrg	     * If we've read a full (small/fragment) buffer, let the operating
3587d522f475Smrg	     * system have a turn, and we'll resume reading until we've either
3588d522f475Smrg	     * read only a fragment of the buffer, or we've filled the large
3589d522f475Smrg	     * buffer (see above).  Doing this helps keep up with large bursts
3590d522f475Smrg	     * of output.
3591d522f475Smrg	     */
3592d522f475Smrg	    if (size == FRG_SIZE) {
3593d522f475Smrg		select_timeout.tv_sec = 0;
3594d522f475Smrg		i = Select(max_plus1, &select_mask, &write_mask, 0,
3595d522f475Smrg			   &select_timeout);
3596d522f475Smrg		if (i > 0) {
3597d522f475Smrg		    sched_yield();
3598d522f475Smrg		} else
3599d522f475Smrg		    break;
3600d522f475Smrg	    } else {
3601d522f475Smrg		break;
3602d522f475Smrg	    }
3603d522f475Smrg#else
3604d522f475Smrg	    (void) size;	/* unused in this branch */
3605d522f475Smrg	    break;
3606d522f475Smrg#endif
3607d522f475Smrg	}
3608d522f475Smrg	/* update the screen */
3609d522f475Smrg	if (screen->scroll_amt)
3610d522f475Smrg	    FlushScroll(xw);
3611d522f475Smrg	if (screen->cursor_set && CursorMoved(screen)) {
3612d522f475Smrg	    if (screen->cursor_state)
3613d522f475Smrg		HideCursor();
3614d522f475Smrg	    ShowCursor();
3615d522f475Smrg#if OPT_INPUT_METHOD
3616d522f475Smrg	    PreeditPosition(screen);
3617d522f475Smrg#endif
3618d522f475Smrg	} else if (screen->cursor_set != screen->cursor_state) {
3619d522f475Smrg	    if (screen->cursor_set)
3620d522f475Smrg		ShowCursor();
3621d522f475Smrg	    else
3622d522f475Smrg		HideCursor();
3623d522f475Smrg	}
3624d522f475Smrg
3625d522f475Smrg	XFlush(screen->display);	/* always flush writes before waiting */
3626d522f475Smrg
3627d522f475Smrg	/* Update the masks and, unless X events are already in the queue,
3628d522f475Smrg	   wait for I/O to be possible. */
3629d522f475Smrg	XFD_COPYSET(&Select_mask, &select_mask);
3630d522f475Smrg	/* in selection mode xterm does not read pty */
3631d522f475Smrg	if (screen->eventMode != NORMAL)
3632d522f475Smrg	    FD_CLR(screen->respond, &select_mask);
3633d522f475Smrg
3634d522f475Smrg	if (v_bufptr > v_bufstr) {
3635d522f475Smrg	    XFD_COPYSET(&pty_mask, &write_mask);
3636d522f475Smrg	} else
3637d522f475Smrg	    FD_ZERO(&write_mask);
3638d522f475Smrg	select_timeout.tv_sec = 0;
3639d522f475Smrg	time_select = 0;
3640d522f475Smrg
3641d522f475Smrg	/*
3642d522f475Smrg	 * if there's either an XEvent or an XtTimeout pending, just take
3643d522f475Smrg	 * a quick peek, i.e. timeout from the select() immediately.  If
3644d522f475Smrg	 * there's nothing pending, let select() block a little while, but
3645d522f475Smrg	 * for a shorter interval than the arrow-style scrollbar timeout.
3646d522f475Smrg	 * The blocking is optional, because it tends to increase the load
3647d522f475Smrg	 * on the host.
3648d522f475Smrg	 */
3649d522f475Smrg	if (XtAppPending(app_con)) {
3650d522f475Smrg	    select_timeout.tv_usec = 0;
3651d522f475Smrg	    time_select = 1;
3652d522f475Smrg	} else if (screen->awaitInput) {
3653d522f475Smrg	    select_timeout.tv_usec = 50000;
3654d522f475Smrg	    time_select = 1;
3655d522f475Smrg#if OPT_BLINK_CURS
3656d522f475Smrg	} else if ((screen->blink_timer != 0 &&
3657d522f475Smrg		    ((screen->select & FOCUS) || screen->always_highlight)) ||
3658d522f475Smrg		   (screen->cursor_state == BLINKED_OFF)) {
3659d522f475Smrg	    select_timeout.tv_usec = tick;
3660d522f475Smrg	    while (select_timeout.tv_usec > 1000000) {
3661d522f475Smrg		select_timeout.tv_usec -= 1000000;
3662d522f475Smrg		select_timeout.tv_sec++;
3663d522f475Smrg	    }
3664d522f475Smrg	    time_select = 1;
3665d522f475Smrg#endif
3666d522f475Smrg#if OPT_SESSION_MGT
3667d522f475Smrg	} else if (resource.sessionMgt) {
3668d522f475Smrg	    if (ice_fd >= 0)
3669d522f475Smrg		FD_SET(ice_fd, &select_mask);
3670d522f475Smrg#endif
3671d522f475Smrg	}
3672d522f475Smrg	if (need_cleanup)
3673d522f475Smrg	    Cleanup(0);
3674d522f475Smrg	i = Select(max_plus1, &select_mask, &write_mask, 0,
3675d522f475Smrg		   (time_select ? &select_timeout : 0));
3676d522f475Smrg	if (i < 0) {
3677d522f475Smrg	    if (errno != EINTR)
3678d522f475Smrg		SysError(ERROR_SELECT);
3679d522f475Smrg	    continue;
3680d522f475Smrg	}
3681d522f475Smrg
3682d522f475Smrg	/* if there is room to write more data to the pty, go write more */
3683d522f475Smrg	if (FD_ISSET(screen->respond, &write_mask)) {
3684d522f475Smrg	    v_write(screen->respond, (Char *) 0, 0);	/* flush buffer */
3685d522f475Smrg	}
3686d522f475Smrg
3687d522f475Smrg	/* if there are X events already in our queue, it
3688d522f475Smrg	   counts as being readable */
3689d522f475Smrg	if (XtAppPending(app_con) ||
3690d522f475Smrg	    FD_ISSET(ConnectionNumber(screen->display), &select_mask)) {
3691d522f475Smrg	    xevents();
3692d522f475Smrg	    if (VTbuffer->update != update)	/* HandleInterpret */
3693d522f475Smrg		break;
3694d522f475Smrg	}
3695d522f475Smrg
3696d522f475Smrg    }
3697d522f475Smrg}
3698d522f475Smrg#endif /* VMS */
3699d522f475Smrg
3700d522f475Smrgstatic IChar
3701d522f475Smrgdoinput(void)
3702d522f475Smrg{
3703d522f475Smrg    TScreen *screen = TScreenOf(term);
3704d522f475Smrg
3705d522f475Smrg    while (!morePtyData(screen, VTbuffer))
3706d522f475Smrg	in_put(term);
3707d522f475Smrg    return nextPtyData(screen, VTbuffer);
3708d522f475Smrg}
3709d522f475Smrg
3710d522f475Smrg#if OPT_INPUT_METHOD
3711d522f475Smrg/*
3712d522f475Smrg *  For OverTheSpot, client has to inform the position for XIM preedit.
3713d522f475Smrg */
3714d522f475Smrgstatic void
3715d522f475SmrgPreeditPosition(TScreen * screen)
3716d522f475Smrg{
3717956cc18dSsnj    LineData *ld;
3718d522f475Smrg    XPoint spot;
3719d522f475Smrg    XVaNestedList list;
3720d522f475Smrg
3721956cc18dSsnj    if (screen->xic
3722956cc18dSsnj	&& (ld = getLineData(screen, screen->cur_row)) != 0) {
3723956cc18dSsnj	spot.x = (short) LineCursorX(screen, ld, screen->cur_col);
3724956cc18dSsnj	spot.y = (short) (CursorY(screen, screen->cur_row) + screen->fs_ascent);
3725956cc18dSsnj	list = XVaCreateNestedList(0,
3726956cc18dSsnj				   XNSpotLocation, &spot,
3727956cc18dSsnj				   XNForeground, T_COLOR(screen, TEXT_FG),
3728956cc18dSsnj				   XNBackground, T_COLOR(screen, TEXT_BG),
3729956cc18dSsnj				   NULL);
3730956cc18dSsnj	XSetICValues(screen->xic, XNPreeditAttributes, list, NULL);
3731956cc18dSsnj	XFree(list);
3732956cc18dSsnj    }
3733d522f475Smrg}
3734d522f475Smrg#endif
3735d522f475Smrg
3736d522f475Smrgstatic void
3737d522f475SmrgWrapLine(XtermWidget xw)
3738d522f475Smrg{
373920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
3740956cc18dSsnj    LineData *ld = getLineData(screen, screen->cur_row);
3741d522f475Smrg
3742956cc18dSsnj    if (ld != 0) {
3743956cc18dSsnj	/* mark that we had to wrap this line */
3744956cc18dSsnj	LineSetFlag(ld, LINEWRAPPED);
3745956cc18dSsnj	xtermAutoPrint(xw, '\n');
3746956cc18dSsnj	xtermIndex(xw, 1);
3747956cc18dSsnj	set_cur_col(screen, 0);
3748956cc18dSsnj    }
3749d522f475Smrg}
3750d522f475Smrg
3751d522f475Smrg/*
3752d522f475Smrg * process a string of characters according to the character set indicated
3753d522f475Smrg * by charset.  worry about end of line conditions (wraparound if selected).
3754d522f475Smrg */
3755d522f475Smrgvoid
3756d522f475Smrgdotext(XtermWidget xw,
3757d522f475Smrg       int charset,
3758d522f475Smrg       IChar * buf,		/* start of characters to process */
3759d522f475Smrg       Cardinal len)		/* end */
3760d522f475Smrg{
376120d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
3762d522f475Smrg#if OPT_WIDE_CHARS
3763d522f475Smrg    Cardinal chars_chomped = 1;
3764d522f475Smrg    int next_col = screen->cur_col;
3765d522f475Smrg#else
3766d522f475Smrg    int next_col, last_col, this_col;	/* must be signed */
3767d522f475Smrg#endif
3768d522f475Smrg    Cardinal offset;
3769d522f475Smrg
3770d522f475Smrg#if OPT_WIDE_CHARS
3771d522f475Smrg    /* don't translate if we use UTF-8, and are not handling legacy support
3772d522f475Smrg     * for line-drawing characters.
3773d522f475Smrg     */
3774d522f475Smrg    if ((screen->utf8_mode == uFalse)
37752eaa94a1Schristos	|| (screen->vt100_graphics))
3776d522f475Smrg#endif
37772eaa94a1Schristos	if (!xtermCharSetOut(xw, buf, buf + len, charset))
3778d522f475Smrg	    return;
3779d522f475Smrg
3780d522f475Smrg    if_OPT_XMC_GLITCH(screen, {
3781d522f475Smrg	Cardinal n;
3782d522f475Smrg	if (charset != '?') {
3783d522f475Smrg	    for (n = 0; n < len; n++) {
3784d522f475Smrg		if (buf[n] == XMC_GLITCH)
3785d522f475Smrg		    buf[n] = XMC_GLITCH + 1;
3786d522f475Smrg	    }
3787d522f475Smrg	}
3788d522f475Smrg    });
3789d522f475Smrg
3790d522f475Smrg#if OPT_WIDE_CHARS
3791d522f475Smrg    for (offset = 0;
3792d522f475Smrg	 offset < len && (chars_chomped > 0 || screen->do_wrap);
3793d522f475Smrg	 offset += chars_chomped) {
3794d522f475Smrg	int width_available = MaxCols(screen) - screen->cur_col;
3795d522f475Smrg	int width_here = 0;
37962eaa94a1Schristos	Boolean need_wrap = False;
3797d522f475Smrg	int last_chomp = 0;
3798d522f475Smrg	chars_chomped = 0;
3799d522f475Smrg
3800d522f475Smrg	if (screen->do_wrap) {
38012eaa94a1Schristos	    screen->do_wrap = False;
3802d522f475Smrg	    if ((xw->flags & WRAPAROUND)) {
3803d522f475Smrg		WrapLine(xw);
3804d522f475Smrg		width_available = MaxCols(screen) - screen->cur_col;
3805d522f475Smrg		next_col = screen->cur_col;
3806d522f475Smrg	    }
3807d522f475Smrg	}
3808d522f475Smrg
3809d522f475Smrg	while (width_here <= width_available && chars_chomped < (len - offset)) {
3810d522f475Smrg	    if (!screen->utf8_mode
3811d522f475Smrg		|| (screen->vt100_graphics && charset == '0'))
3812d522f475Smrg		last_chomp = 1;
3813d522f475Smrg	    else
3814d522f475Smrg		last_chomp = my_wcwidth((int) buf[chars_chomped + offset]);
3815d522f475Smrg	    width_here += last_chomp;
3816d522f475Smrg	    chars_chomped++;
3817d522f475Smrg	}
3818d522f475Smrg
3819d522f475Smrg	if (width_here > width_available) {
3820d522f475Smrg	    if (last_chomp > MaxCols(screen))
3821d522f475Smrg		break;		/* give up - it is too big */
3822d522f475Smrg	    chars_chomped--;
3823d522f475Smrg	    width_here -= last_chomp;
3824d522f475Smrg	    if (chars_chomped > 0) {
38252eaa94a1Schristos		need_wrap = True;
3826d522f475Smrg	    }
3827d522f475Smrg	} else if (width_here == width_available) {
38282eaa94a1Schristos	    need_wrap = True;
3829d522f475Smrg	} else if (chars_chomped != (len - offset)) {
38302eaa94a1Schristos	    need_wrap = True;
3831d522f475Smrg	}
3832d522f475Smrg
3833d522f475Smrg	/*
3834d522f475Smrg	 * Split the wide characters back into separate arrays of 8-bit
3835d522f475Smrg	 * characters so we can use the existing interface.
3836d522f475Smrg	 *
3837d522f475Smrg	 * FIXME:  If we rewrote this interface, it would involve
3838d522f475Smrg	 * rewriting all of the memory-management for the screen
3839d522f475Smrg	 * buffers (perhaps this is simpler).
3840d522f475Smrg	 */
3841d522f475Smrg	if (chars_chomped != 0 && next_col <= screen->max_col) {
3842956cc18dSsnj	    WriteText(xw, buf + offset, chars_chomped);
3843d522f475Smrg	}
3844d522f475Smrg	next_col += width_here;
3845d522f475Smrg	screen->do_wrap = need_wrap;
3846d522f475Smrg    }
3847d522f475Smrg#else /* ! OPT_WIDE_CHARS */
3848d522f475Smrg
3849d522f475Smrg    for (offset = 0; offset < len; offset += this_col) {
3850956cc18dSsnj#if OPT_DEC_CHRSET
3851956cc18dSsnj	LineData *ld = getLineData(screen, screen->cur_row);
3852956cc18dSsnj#endif
3853956cc18dSsnj
3854956cc18dSsnj	last_col = LineMaxCol(screen, ld);
3855d522f475Smrg	this_col = last_col - screen->cur_col + 1;
3856d522f475Smrg	if (this_col <= 1) {
3857d522f475Smrg	    if (screen->do_wrap) {
38582eaa94a1Schristos		screen->do_wrap = False;
3859d522f475Smrg		if ((xw->flags & WRAPAROUND)) {
3860d522f475Smrg		    WrapLine(xw);
3861d522f475Smrg		}
3862d522f475Smrg	    }
3863d522f475Smrg	    this_col = 1;
3864d522f475Smrg	}
3865d522f475Smrg	if (offset + this_col > len) {
3866d522f475Smrg	    this_col = len - offset;
3867d522f475Smrg	}
3868d522f475Smrg	next_col = screen->cur_col + this_col;
3869d522f475Smrg
3870956cc18dSsnj	WriteText(xw, buf + offset, (unsigned) this_col);
3871d522f475Smrg
3872d522f475Smrg	/*
3873d522f475Smrg	 * The call to WriteText updates screen->cur_col.
3874d522f475Smrg	 * If screen->cur_col is less than next_col, we must have
3875d522f475Smrg	 * hit the right margin - so set the do_wrap flag.
3876d522f475Smrg	 */
3877d522f475Smrg	screen->do_wrap = (screen->cur_col < next_col);
3878d522f475Smrg    }
3879d522f475Smrg
3880d522f475Smrg#endif /* OPT_WIDE_CHARS */
3881d522f475Smrg}
3882d522f475Smrg
3883d522f475Smrg#if OPT_WIDE_CHARS
3884d522f475Smrgunsigned
3885956cc18dSsnjvisual_width(IChar * str, Cardinal len)
3886d522f475Smrg{
3887d522f475Smrg    /* returns the visual width of a string (doublewide characters count
3888d522f475Smrg       as 2, normalwide characters count as 1) */
38892eaa94a1Schristos    unsigned my_len = 0;
3890d522f475Smrg    while (len) {
3891956cc18dSsnj	int ch = (int) *str++;
3892956cc18dSsnj	if (isWide(ch))
3893d522f475Smrg	    my_len += 2;
3894d522f475Smrg	else
3895d522f475Smrg	    my_len++;
3896d522f475Smrg	len--;
3897d522f475Smrg    }
3898d522f475Smrg    return my_len;
3899d522f475Smrg}
3900d522f475Smrg#endif
3901d522f475Smrg
3902d522f475Smrg#if HANDLE_STRUCT_NOTIFY
390320d2c4d2Smrg/* Flag icon name with "***" on window output when iconified.
3904d522f475Smrg */
3905d522f475Smrgstatic void
3906d522f475SmrgHandleStructNotify(Widget w GCC_UNUSED,
3907d522f475Smrg		   XtPointer closure GCC_UNUSED,
3908d522f475Smrg		   XEvent * event,
3909d522f475Smrg		   Boolean * cont GCC_UNUSED)
3910d522f475Smrg{
3911d522f475Smrg    static char *icon_name;
3912d522f475Smrg    static Arg args[] =
3913d522f475Smrg    {
3914d522f475Smrg	{XtNiconName, (XtArgVal) & icon_name}
3915d522f475Smrg    };
39162eaa94a1Schristos    XtermWidget xw = term;
39172eaa94a1Schristos    TScreen *screen = TScreenOf(xw);
3918d522f475Smrg
3919d522f475Smrg    switch (event->type) {
3920d522f475Smrg    case MapNotify:
3921d522f475Smrg	TRACE(("HandleStructNotify(MapNotify)\n"));
3922d522f475Smrg#if OPT_ZICONBEEP
3923d522f475Smrg	if (screen->zIconBeep_flagged) {
3924d522f475Smrg	    screen->zIconBeep_flagged = False;
3925d522f475Smrg	    icon_name = NULL;
3926d522f475Smrg	    XtGetValues(toplevel, args, XtNumber(args));
3927d522f475Smrg	    if (icon_name != NULL) {
3928d522f475Smrg		char *buf = CastMallocN(char, strlen(icon_name));
3929d522f475Smrg		if (buf == NULL) {
3930d522f475Smrg		    screen->zIconBeep_flagged = True;
3931d522f475Smrg		    return;
3932d522f475Smrg		}
3933d522f475Smrg		strcpy(buf, icon_name + 4);
3934956cc18dSsnj		ChangeIconName(xw, buf);
3935d522f475Smrg		free(buf);
3936d522f475Smrg	    }
3937d522f475Smrg	}
3938d522f475Smrg#endif /* OPT_ZICONBEEP */
3939d522f475Smrg	mapstate = !IsUnmapped;
3940d522f475Smrg	break;
3941d522f475Smrg    case UnmapNotify:
3942d522f475Smrg	TRACE(("HandleStructNotify(UnmapNotify)\n"));
3943d522f475Smrg	mapstate = IsUnmapped;
3944d522f475Smrg	break;
3945d522f475Smrg    case ConfigureNotify:
3946d522f475Smrg	if (event->xconfigure.window == XtWindow(toplevel)) {
394720d2c4d2Smrg#if !OPT_TOOLBAR
39482eaa94a1Schristos	    int height, width;
39492eaa94a1Schristos
39502eaa94a1Schristos	    height = event->xconfigure.height;
39512eaa94a1Schristos	    width = event->xconfigure.width;
395220d2c4d2Smrg#endif
39532eaa94a1Schristos	    TRACE(("HandleStructNotify(ConfigureNotify) %d,%d %dx%d\n",
39542eaa94a1Schristos		   event->xconfigure.y, event->xconfigure.x,
39552eaa94a1Schristos		   event->xconfigure.height, event->xconfigure.width));
39562eaa94a1Schristos
3957d522f475Smrg#if OPT_TOOLBAR
3958d522f475Smrg	    /*
3959d522f475Smrg	     * The notification is for the top-level widget, but we care about
3960d522f475Smrg	     * vt100 (ignore the tek4014 window).
3961d522f475Smrg	     */
396220d2c4d2Smrg	    if (TScreenOf(xw)->Vshow) {
396320d2c4d2Smrg		VTwin *Vwin = WhichVWin(TScreenOf(xw));
3964d522f475Smrg		TbInfo *info = &(Vwin->tb_info);
3965d522f475Smrg		TbInfo save = *info;
3966d522f475Smrg
3967d522f475Smrg		if (info->menu_bar) {
3968d522f475Smrg		    XtVaGetValues(info->menu_bar,
3969d522f475Smrg				  XtNheight, &info->menu_height,
3970d522f475Smrg				  XtNborderWidth, &info->menu_border,
3971d522f475Smrg				  (XtPointer) 0);
3972d522f475Smrg
3973d522f475Smrg		    if (save.menu_height != info->menu_height
3974d522f475Smrg			|| save.menu_border != info->menu_border) {
3975d522f475Smrg
3976d522f475Smrg			TRACE(("...menu_height %d\n", info->menu_height));
3977d522f475Smrg			TRACE(("...menu_border %d\n", info->menu_border));
3978d522f475Smrg			TRACE(("...had height  %d, border %d\n",
3979d522f475Smrg			       save.menu_height,
3980d522f475Smrg			       save.menu_border));
3981d522f475Smrg
3982d522f475Smrg			/*
3983d522f475Smrg			 * FIXME:  Window manager still may be using the old
3984d522f475Smrg			 * values.  Try to fool it.
3985d522f475Smrg			 */
39862eaa94a1Schristos			REQ_RESIZE((Widget) xw,
39872eaa94a1Schristos				   screen->fullVwin.fullwidth,
39882eaa94a1Schristos				   (Dimension) (info->menu_height
39892eaa94a1Schristos						- save.menu_height
39902eaa94a1Schristos						+ screen->fullVwin.fullheight),
39912eaa94a1Schristos				   NULL, NULL);
3992d522f475Smrg			repairSizeHints();
3993d522f475Smrg		    }
3994d522f475Smrg		}
3995d522f475Smrg	    }
3996d522f475Smrg#else
39972eaa94a1Schristos	    if (height != xw->hints.height || width != xw->hints.width)
39982eaa94a1Schristos		RequestResize(xw, height, width, False);
3999d522f475Smrg#endif /* OPT_TOOLBAR */
4000d522f475Smrg	}
4001d522f475Smrg	break;
4002d522f475Smrg    case ReparentNotify:
4003d522f475Smrg	TRACE(("HandleStructNotify(ReparentNotify)\n"));
4004d522f475Smrg	break;
4005d522f475Smrg    default:
4006d522f475Smrg	TRACE(("HandleStructNotify(event %s)\n",
4007d522f475Smrg	       visibleEventType(event->type)));
4008d522f475Smrg	break;
4009d522f475Smrg    }
4010d522f475Smrg}
4011d522f475Smrg#endif /* HANDLE_STRUCT_NOTIFY */
4012d522f475Smrg
4013d522f475Smrg#if OPT_BLINK_CURS
4014d522f475Smrgstatic void
4015956cc18dSsnjSetCursorBlink(TScreen * screen, Bool enable)
4016d522f475Smrg{
4017956cc18dSsnj    screen->cursor_blink = (Boolean) enable;
4018d522f475Smrg    if (DoStartBlinking(screen)) {
4019d522f475Smrg	StartBlinking(screen);
4020d522f475Smrg    } else {
4021d522f475Smrg#if !OPT_BLINK_TEXT
4022d522f475Smrg	StopBlinking(screen);
4023d522f475Smrg#endif
4024d522f475Smrg    }
4025d522f475Smrg    update_cursorblink();
4026d522f475Smrg}
4027d522f475Smrg
4028d522f475Smrgvoid
4029d522f475SmrgToggleCursorBlink(TScreen * screen)
4030d522f475Smrg{
4031956cc18dSsnj    SetCursorBlink(screen, (Bool) (!(screen->cursor_blink)));
4032d522f475Smrg}
4033d522f475Smrg#endif
4034d522f475Smrg
4035d522f475Smrg/*
4036d522f475Smrg * process ANSI modes set, reset
4037d522f475Smrg */
4038d522f475Smrgstatic void
403920d2c4d2Smrgansi_modes(XtermWidget xw, BitFunc func)
4040d522f475Smrg{
4041d522f475Smrg    int i;
4042d522f475Smrg
4043d522f475Smrg    for (i = 0; i < nparam; ++i) {
4044d522f475Smrg	switch (param[i]) {
4045d522f475Smrg	case 2:		/* KAM (if set, keyboard locked */
4046d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_KAM);
4047d522f475Smrg	    break;
4048d522f475Smrg
4049d522f475Smrg	case 4:		/* IRM                          */
4050d522f475Smrg	    (*func) (&xw->flags, INSERT);
4051d522f475Smrg	    break;
4052d522f475Smrg
4053d522f475Smrg	case 12:		/* SRM (if set, local echo      */
4054d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_SRM);
4055d522f475Smrg	    break;
4056d522f475Smrg
4057d522f475Smrg	case 20:		/* LNM                          */
4058d522f475Smrg	    (*func) (&xw->flags, LINEFEED);
4059d522f475Smrg	    update_autolinefeed();
4060d522f475Smrg	    break;
4061d522f475Smrg	}
4062d522f475Smrg    }
4063d522f475Smrg}
4064d522f475Smrg
4065d522f475Smrg#define IsSM() (func == bitset)
4066d522f475Smrg
4067d522f475Smrg#define set_bool_mode(flag) \
40682eaa94a1Schristos	flag = (Boolean) IsSM()
4069d522f475Smrg
4070d522f475Smrgstatic void
4071d522f475Smrgreally_set_mousemode(XtermWidget xw,
4072d522f475Smrg		     Bool enabled,
40732eaa94a1Schristos		     XtermMouseModes mode)
4074d522f475Smrg{
407520d2c4d2Smrg    TScreenOf(xw)->send_mouse_pos = enabled ? mode : MOUSE_OFF;
407620d2c4d2Smrg    if (TScreenOf(xw)->send_mouse_pos != MOUSE_OFF)
4077d522f475Smrg	xtermShowPointer(xw, True);
4078d522f475Smrg}
4079d522f475Smrg
4080d522f475Smrg#define set_mousemode(mode) really_set_mousemode(xw, IsSM(), mode)
4081d522f475Smrg
4082d522f475Smrg#if OPT_READLINE
4083d522f475Smrg#define set_mouseflag(f)		\
4084d522f475Smrg	(IsSM()				\
4085d522f475Smrg	 ? SCREEN_FLAG_set(screen, f)	\
4086d522f475Smrg	 : SCREEN_FLAG_unset(screen, f))
4087d522f475Smrg#endif
4088d522f475Smrg
4089d522f475Smrg/*
4090d522f475Smrg * process DEC private modes set, reset
4091d522f475Smrg */
4092d522f475Smrgstatic void
409320d2c4d2Smrgdpmodes(XtermWidget xw, BitFunc func)
4094d522f475Smrg{
409520d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4096d522f475Smrg    int i, j;
40972eaa94a1Schristos    unsigned myflags;
4098d522f475Smrg
4099d522f475Smrg    for (i = 0; i < nparam; ++i) {
4100d522f475Smrg	TRACE(("%s %d\n", IsSM()? "DECSET" : "DECRST", param[i]));
4101d522f475Smrg	switch (param[i]) {
4102d522f475Smrg	case 1:		/* DECCKM                       */
4103d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_DECCKM);
4104d522f475Smrg	    update_appcursor();
4105d522f475Smrg	    break;
4106d522f475Smrg	case 2:		/* DECANM - ANSI/VT52 mode      */
4107d522f475Smrg	    if (IsSM()) {	/* ANSI (VT100) */
4108d522f475Smrg		/*
4109d522f475Smrg		 * Setting DECANM should have no effect, since this function
4110d522f475Smrg		 * cannot be reached from vt52 mode.
4111d522f475Smrg		 */
4112d522f475Smrg		;
4113d522f475Smrg	    }
4114d522f475Smrg#if OPT_VT52_MODE
4115d522f475Smrg	    else if (screen->terminal_id >= 100) {	/* VT52 */
4116d522f475Smrg		TRACE(("DECANM terminal_id %d, vtXX_level %d\n",
4117d522f475Smrg		       screen->terminal_id,
4118d522f475Smrg		       screen->vtXX_level));
4119d522f475Smrg		screen->vt52_save_level = screen->vtXX_level;
4120d522f475Smrg		screen->vtXX_level = 0;
4121d522f475Smrg		screen->vt52_save_curgl = screen->curgl;
4122d522f475Smrg		screen->vt52_save_curgr = screen->curgr;
4123d522f475Smrg		screen->vt52_save_curss = screen->curss;
4124d522f475Smrg		memmove(screen->vt52_save_gsets, screen->gsets, sizeof(screen->gsets));
4125d522f475Smrg		resetCharsets(screen);
4126d522f475Smrg		nparam = 0;	/* ignore the remaining params, if any */
4127d522f475Smrg	    }
4128d522f475Smrg#endif
4129d522f475Smrg	    break;
4130d522f475Smrg	case 3:		/* DECCOLM                      */
4131d522f475Smrg	    if (screen->c132) {
4132d522f475Smrg		ClearScreen(xw);
4133d522f475Smrg		CursorSet(screen, 0, 0, xw->flags);
4134d522f475Smrg		if ((j = IsSM()? 132 : 80) !=
4135d522f475Smrg		    ((xw->flags & IN132COLUMNS) ? 132 : 80) ||
4136d522f475Smrg		    j != MaxCols(screen))
4137d522f475Smrg		    RequestResize(xw, -1, j, True);
4138d522f475Smrg		(*func) (&xw->flags, IN132COLUMNS);
4139d522f475Smrg	    }
4140d522f475Smrg	    break;
4141d522f475Smrg	case 4:		/* DECSCLM (slow scroll)        */
4142d522f475Smrg	    if (IsSM()) {
4143d522f475Smrg		screen->jumpscroll = 0;
4144d522f475Smrg		if (screen->scroll_amt)
4145d522f475Smrg		    FlushScroll(xw);
4146d522f475Smrg	    } else
4147d522f475Smrg		screen->jumpscroll = 1;
4148d522f475Smrg	    (*func) (&xw->flags, SMOOTHSCROLL);
4149d522f475Smrg	    update_jumpscroll();
4150d522f475Smrg	    break;
4151d522f475Smrg	case 5:		/* DECSCNM                      */
41522eaa94a1Schristos	    myflags = xw->flags;
4153d522f475Smrg	    (*func) (&xw->flags, REVERSE_VIDEO);
41542eaa94a1Schristos	    if ((xw->flags ^ myflags) & REVERSE_VIDEO)
4155d522f475Smrg		ReverseVideo(xw);
4156d522f475Smrg	    /* update_reversevideo done in RevVid */
4157d522f475Smrg	    break;
4158d522f475Smrg
4159d522f475Smrg	case 6:		/* DECOM                        */
4160d522f475Smrg	    (*func) (&xw->flags, ORIGIN);
4161d522f475Smrg	    CursorSet(screen, 0, 0, xw->flags);
4162d522f475Smrg	    break;
4163d522f475Smrg
4164d522f475Smrg	case 7:		/* DECAWM                       */
4165d522f475Smrg	    (*func) (&xw->flags, WRAPAROUND);
4166d522f475Smrg	    update_autowrap();
4167d522f475Smrg	    break;
4168d522f475Smrg	case 8:		/* DECARM                       */
4169d522f475Smrg	    /* ignore autorepeat
4170d522f475Smrg	     * XAutoRepeatOn() and XAutoRepeatOff() can do this, but only
4171d522f475Smrg	     * for the whole display - not limited to a given window.
4172d522f475Smrg	     */
4173d522f475Smrg	    break;
4174d522f475Smrg	case SET_X10_MOUSE:	/* MIT bogus sequence           */
4175d522f475Smrg	    MotionOff(screen, xw);
4176d522f475Smrg	    set_mousemode(X10_MOUSE);
4177d522f475Smrg	    break;
4178d522f475Smrg#if OPT_TOOLBAR
4179d522f475Smrg	case 10:		/* rxvt */
4180d522f475Smrg	    ShowToolbar(IsSM());
4181d522f475Smrg	    break;
4182d522f475Smrg#endif
4183d522f475Smrg#if OPT_BLINK_CURS
4184d522f475Smrg	case 12:		/* att610: Start/stop blinking cursor */
4185d522f475Smrg	    if (screen->cursor_blink_res) {
4186d522f475Smrg		set_bool_mode(screen->cursor_blink_esc);
4187d522f475Smrg		SetCursorBlink(screen, screen->cursor_blink);
4188d522f475Smrg	    }
4189d522f475Smrg	    break;
4190d522f475Smrg#endif
4191d522f475Smrg	case 18:		/* DECPFF: print form feed */
4192d522f475Smrg	    set_bool_mode(screen->printer_formfeed);
4193d522f475Smrg	    break;
4194d522f475Smrg	case 19:		/* DECPEX: print extent */
4195d522f475Smrg	    set_bool_mode(screen->printer_extent);
4196d522f475Smrg	    break;
4197d522f475Smrg	case 25:		/* DECTCEM: Show/hide cursor (VT200) */
4198d522f475Smrg	    set_bool_mode(screen->cursor_set);
4199d522f475Smrg	    break;
4200d522f475Smrg	case 30:		/* rxvt */
4201d522f475Smrg	    if (screen->fullVwin.sb_info.width != (IsSM()? ON : OFF))
4202d522f475Smrg		ToggleScrollBar(xw);
4203d522f475Smrg	    break;
4204d522f475Smrg#if OPT_SHIFT_FONTS
4205d522f475Smrg	case 35:		/* rxvt */
4206d522f475Smrg	    set_bool_mode(xw->misc.shift_fonts);
4207d522f475Smrg	    break;
4208d522f475Smrg#endif
4209d522f475Smrg	case 38:		/* DECTEK                       */
4210d522f475Smrg#if OPT_TEK4014
4211d522f475Smrg	    if (IsSM() && !(screen->inhibit & I_TEK)) {
421220d2c4d2Smrg		FlushLog(xw);
4213d522f475Smrg		TEK4014_ACTIVE(xw) = True;
4214d522f475Smrg	    }
4215d522f475Smrg#endif
4216d522f475Smrg	    break;
4217d522f475Smrg	case 40:		/* 132 column mode              */
4218d522f475Smrg	    set_bool_mode(screen->c132);
4219d522f475Smrg	    update_allow132();
4220d522f475Smrg	    break;
4221d522f475Smrg	case 41:		/* curses hack                  */
4222d522f475Smrg	    set_bool_mode(screen->curses);
4223d522f475Smrg	    update_cursesemul();
4224d522f475Smrg	    break;
4225d522f475Smrg	case 42:		/* DECNRCM national charset (VT220) */
4226d522f475Smrg	    (*func) (&xw->flags, NATIONAL);
4227d522f475Smrg	    break;
4228d522f475Smrg	case 44:		/* margin bell                  */
4229d522f475Smrg	    set_bool_mode(screen->marginbell);
4230d522f475Smrg	    if (!screen->marginbell)
423120d2c4d2Smrg		screen->bellArmed = -1;
4232d522f475Smrg	    update_marginbell();
4233d522f475Smrg	    break;
4234d522f475Smrg	case 45:		/* reverse wraparound   */
4235d522f475Smrg	    (*func) (&xw->flags, REVERSEWRAP);
4236d522f475Smrg	    update_reversewrap();
4237d522f475Smrg	    break;
4238d522f475Smrg#ifdef ALLOWLOGGING
4239d522f475Smrg	case 46:		/* logging              */
4240d522f475Smrg#ifdef ALLOWLOGFILEONOFF
4241d522f475Smrg	    /*
4242d522f475Smrg	     * if this feature is enabled, logging may be
4243d522f475Smrg	     * enabled and disabled via escape sequences.
4244d522f475Smrg	     */
4245d522f475Smrg	    if (IsSM())
424620d2c4d2Smrg		StartLog(xw);
4247d522f475Smrg	    else
424820d2c4d2Smrg		CloseLog(xw);
4249d522f475Smrg#else
425020d2c4d2Smrg	    Bell(xw, XkbBI_Info, 0);
425120d2c4d2Smrg	    Bell(xw, XkbBI_Info, 0);
4252d522f475Smrg#endif /* ALLOWLOGFILEONOFF */
4253d522f475Smrg	    break;
4254d522f475Smrg#endif
4255d522f475Smrg	case 1049:		/* alternate buffer & cursor */
4256d522f475Smrg	    if (!xw->misc.titeInhibit) {
4257d522f475Smrg		if (IsSM()) {
4258d522f475Smrg		    CursorSave(xw);
4259d522f475Smrg		    ToAlternate(xw);
4260d522f475Smrg		    ClearScreen(xw);
4261d522f475Smrg		} else {
4262d522f475Smrg		    FromAlternate(xw);
4263d522f475Smrg		    CursorRestore(xw);
4264d522f475Smrg		}
4265d522f475Smrg	    } else if (xw->misc.tiXtraScroll) {
4266d522f475Smrg		if (IsSM()) {
4267d522f475Smrg		    xtermScroll(xw, screen->max_row);
4268d522f475Smrg		}
4269d522f475Smrg	    }
4270d522f475Smrg	    break;
4271d522f475Smrg	case 1047:
4272d522f475Smrg	    /* FALLTHRU */
4273d522f475Smrg	case 47:		/* alternate buffer */
4274d522f475Smrg	    if (!xw->misc.titeInhibit) {
4275d522f475Smrg		if (IsSM()) {
4276d522f475Smrg		    ToAlternate(xw);
4277d522f475Smrg		} else {
4278956cc18dSsnj		    if (screen->whichBuf
4279d522f475Smrg			&& (param[i] == 1047))
4280d522f475Smrg			ClearScreen(xw);
4281d522f475Smrg		    FromAlternate(xw);
4282d522f475Smrg		}
4283d522f475Smrg	    } else if (xw->misc.tiXtraScroll) {
4284d522f475Smrg		if (IsSM()) {
4285d522f475Smrg		    xtermScroll(xw, screen->max_row);
4286d522f475Smrg		}
4287d522f475Smrg	    }
4288d522f475Smrg	    break;
4289d522f475Smrg	case 66:		/* DECNKM */
4290d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_DECKPAM);
4291d522f475Smrg	    update_appkeypad();
4292d522f475Smrg	    break;
4293d522f475Smrg	case 67:		/* DECBKM */
4294d522f475Smrg	    /* back-arrow mapped to backspace or delete(D) */
4295d522f475Smrg	    (*func) (&xw->keyboard.flags, MODE_DECBKM);
4296d522f475Smrg	    TRACE(("DECSET DECBKM %s\n",
4297d522f475Smrg		   BtoS(xw->keyboard.flags & MODE_DECBKM)));
4298d522f475Smrg	    update_decbkm();
4299d522f475Smrg	    break;
4300d522f475Smrg	case SET_VT200_MOUSE:	/* xterm bogus sequence         */
4301d522f475Smrg	    MotionOff(screen, xw);
4302d522f475Smrg	    set_mousemode(VT200_MOUSE);
4303d522f475Smrg	    break;
4304d522f475Smrg	case SET_VT200_HIGHLIGHT_MOUSE:	/* xterm sequence w/hilite tracking */
4305d522f475Smrg	    MotionOff(screen, xw);
4306d522f475Smrg	    set_mousemode(VT200_HIGHLIGHT_MOUSE);
4307d522f475Smrg	    break;
4308d522f475Smrg	case SET_BTN_EVENT_MOUSE:
4309d522f475Smrg	    MotionOff(screen, xw);
4310d522f475Smrg	    set_mousemode(BTN_EVENT_MOUSE);
4311d522f475Smrg	    break;
4312d522f475Smrg	case SET_ANY_EVENT_MOUSE:
4313d522f475Smrg	    set_mousemode(ANY_EVENT_MOUSE);
4314d522f475Smrg	    if (screen->send_mouse_pos == MOUSE_OFF) {
4315d522f475Smrg		MotionOff(screen, xw);
4316d522f475Smrg	    } else {
4317d522f475Smrg		MotionOn(screen, xw);
4318d522f475Smrg	    }
4319d522f475Smrg	    break;
4320d522f475Smrg#if OPT_FOCUS_EVENT
4321d522f475Smrg	case SET_FOCUS_EVENT_MOUSE:
4322d522f475Smrg	    set_bool_mode(screen->send_focus_pos);
4323d522f475Smrg	    break;
4324d522f475Smrg#endif
4325d522f475Smrg	case 1010:		/* rxvt */
4326d522f475Smrg	    set_bool_mode(screen->scrollttyoutput);
4327d522f475Smrg	    update_scrollttyoutput();
4328d522f475Smrg	    break;
4329d522f475Smrg	case 1011:		/* rxvt */
4330d522f475Smrg	    set_bool_mode(screen->scrollkey);
4331d522f475Smrg	    update_scrollkey();
4332d522f475Smrg	    break;
4333d522f475Smrg	case 1034:
433420d2c4d2Smrg	    set_bool_mode(TScreenOf(xw)->input_eight_bits);
4335d522f475Smrg	    update_alt_esc();
4336d522f475Smrg	    break;
4337d522f475Smrg#if OPT_NUM_LOCK
4338d522f475Smrg	case 1035:
4339d522f475Smrg	    set_bool_mode(xw->misc.real_NumLock);
4340d522f475Smrg	    update_num_lock();
4341d522f475Smrg	    break;
4342d522f475Smrg	case 1036:
4343d522f475Smrg	    set_bool_mode(screen->meta_sends_esc);
4344d522f475Smrg	    update_meta_esc();
4345d522f475Smrg	    break;
4346d522f475Smrg#endif
4347d522f475Smrg	case 1037:
4348d522f475Smrg	    set_bool_mode(screen->delete_is_del);
4349d522f475Smrg	    update_delete_del();
4350d522f475Smrg	    break;
4351d522f475Smrg#if OPT_NUM_LOCK
4352d522f475Smrg	case 1039:
4353d522f475Smrg	    set_bool_mode(screen->alt_sends_esc);
4354d522f475Smrg	    update_alt_esc();
4355d522f475Smrg	    break;
4356d522f475Smrg#endif
4357d522f475Smrg	case 1040:
4358d522f475Smrg	    set_bool_mode(screen->keepSelection);
4359d522f475Smrg	    update_keepSelection();
4360d522f475Smrg	    break;
4361d522f475Smrg	case 1041:
4362d522f475Smrg	    set_bool_mode(screen->selectToClipboard);
4363d522f475Smrg	    update_selectToClipboard();
4364d522f475Smrg	    break;
4365d522f475Smrg	case 1042:
4366d522f475Smrg	    set_bool_mode(screen->bellIsUrgent);
4367d522f475Smrg	    update_bellIsUrgent();
4368d522f475Smrg	    break;
4369d522f475Smrg	case 1043:
4370d522f475Smrg	    set_bool_mode(screen->poponbell);
4371d522f475Smrg	    update_poponbell();
4372d522f475Smrg	    break;
4373d522f475Smrg	case 1048:
4374d522f475Smrg	    if (!xw->misc.titeInhibit) {
4375d522f475Smrg		if (IsSM())
4376d522f475Smrg		    CursorSave(xw);
4377d522f475Smrg		else
4378d522f475Smrg		    CursorRestore(xw);
4379d522f475Smrg	    }
4380d522f475Smrg	    break;
4381d522f475Smrg#if OPT_TCAP_FKEYS
4382d522f475Smrg	case 1050:
4383d522f475Smrg	    set_keyboard_type(xw, keyboardIsTermcap, IsSM());
4384d522f475Smrg	    break;
4385d522f475Smrg#endif
4386d522f475Smrg#if OPT_SUN_FUNC_KEYS
4387d522f475Smrg	case 1051:
4388d522f475Smrg	    set_keyboard_type(xw, keyboardIsSun, IsSM());
4389d522f475Smrg	    break;
4390d522f475Smrg#endif
4391d522f475Smrg#if OPT_HP_FUNC_KEYS
4392d522f475Smrg	case 1052:
4393d522f475Smrg	    set_keyboard_type(xw, keyboardIsHP, IsSM());
4394d522f475Smrg	    break;
4395d522f475Smrg#endif
4396d522f475Smrg#if OPT_SCO_FUNC_KEYS
4397d522f475Smrg	case 1053:
4398d522f475Smrg	    set_keyboard_type(xw, keyboardIsSCO, IsSM());
4399d522f475Smrg	    break;
4400d522f475Smrg#endif
4401d522f475Smrg	case 1060:
4402d522f475Smrg	    set_keyboard_type(xw, keyboardIsLegacy, IsSM());
4403d522f475Smrg	    break;
4404d522f475Smrg#if OPT_SUNPC_KBD
4405d522f475Smrg	case 1061:
4406d522f475Smrg	    set_keyboard_type(xw, keyboardIsVT220, IsSM());
4407d522f475Smrg	    break;
4408d522f475Smrg#endif
4409d522f475Smrg#if OPT_READLINE
4410d522f475Smrg	case SET_BUTTON1_MOVE_POINT:
4411d522f475Smrg	    set_mouseflag(click1_moves);
4412d522f475Smrg	    break;
4413d522f475Smrg	case SET_BUTTON2_MOVE_POINT:
4414d522f475Smrg	    set_mouseflag(paste_moves);
4415d522f475Smrg	    break;
4416d522f475Smrg	case SET_DBUTTON3_DELETE:
4417d522f475Smrg	    set_mouseflag(dclick3_deletes);
4418d522f475Smrg	    break;
4419d522f475Smrg	case SET_PASTE_IN_BRACKET:
4420d522f475Smrg	    set_mouseflag(paste_brackets);
4421d522f475Smrg	    break;
4422d522f475Smrg	case SET_PASTE_QUOTE:
4423d522f475Smrg	    set_mouseflag(paste_quotes);
4424d522f475Smrg	    break;
4425d522f475Smrg	case SET_PASTE_LITERAL_NL:
4426d522f475Smrg	    set_mouseflag(paste_literal_nl);
4427d522f475Smrg	    break;
4428d522f475Smrg#endif /* OPT_READLINE */
4429d522f475Smrg	}
4430d522f475Smrg    }
4431d522f475Smrg}
4432d522f475Smrg
4433d522f475Smrg/*
4434d522f475Smrg * process xterm private modes save
4435d522f475Smrg */
4436d522f475Smrgstatic void
4437d522f475Smrgsavemodes(XtermWidget xw)
4438d522f475Smrg{
443920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4440d522f475Smrg    int i;
4441d522f475Smrg
4442d522f475Smrg    for (i = 0; i < nparam; i++) {
4443d522f475Smrg	TRACE(("savemodes %d\n", param[i]));
4444d522f475Smrg	switch (param[i]) {
4445d522f475Smrg	case 1:		/* DECCKM                       */
4446d522f475Smrg	    DoSM(DP_DECCKM, xw->keyboard.flags & MODE_DECCKM);
4447d522f475Smrg	    break;
4448d522f475Smrg	case 3:		/* DECCOLM                      */
4449d522f475Smrg	    if (screen->c132)
4450d522f475Smrg		DoSM(DP_DECCOLM, xw->flags & IN132COLUMNS);
4451d522f475Smrg	    break;
4452d522f475Smrg	case 4:		/* DECSCLM (slow scroll)        */
4453d522f475Smrg	    DoSM(DP_DECSCLM, xw->flags & SMOOTHSCROLL);
4454d522f475Smrg	    break;
4455d522f475Smrg	case 5:		/* DECSCNM                      */
4456d522f475Smrg	    DoSM(DP_DECSCNM, xw->flags & REVERSE_VIDEO);
4457d522f475Smrg	    break;
4458d522f475Smrg	case 6:		/* DECOM                        */
4459d522f475Smrg	    DoSM(DP_DECOM, xw->flags & ORIGIN);
4460d522f475Smrg	    break;
4461d522f475Smrg	case 7:		/* DECAWM                       */
4462d522f475Smrg	    DoSM(DP_DECAWM, xw->flags & WRAPAROUND);
4463d522f475Smrg	    break;
4464d522f475Smrg	case 8:		/* DECARM                       */
4465d522f475Smrg	    /* ignore autorepeat */
4466d522f475Smrg	    break;
4467d522f475Smrg	case SET_X10_MOUSE:	/* mouse bogus sequence */
4468d522f475Smrg	    DoSM(DP_X_X10MSE, screen->send_mouse_pos);
4469d522f475Smrg	    break;
4470d522f475Smrg#if OPT_TOOLBAR
4471d522f475Smrg	case 10:		/* rxvt */
4472d522f475Smrg	    DoSM(DP_TOOLBAR, resource.toolBar);
4473d522f475Smrg	    break;
4474d522f475Smrg#endif
4475d522f475Smrg#if OPT_BLINK_CURS
4476d522f475Smrg	case 12:		/* att610: Start/stop blinking cursor */
4477d522f475Smrg	    if (screen->cursor_blink_res) {
4478d522f475Smrg		DoSM(DP_CRS_BLINK, screen->cursor_blink_esc);
4479d522f475Smrg	    }
4480d522f475Smrg	    break;
4481d522f475Smrg#endif
4482d522f475Smrg	case 18:		/* DECPFF: print form feed */
4483d522f475Smrg	    DoSM(DP_PRN_FORMFEED, screen->printer_formfeed);
4484d522f475Smrg	    break;
4485d522f475Smrg	case 19:		/* DECPEX: print extent */
4486d522f475Smrg	    DoSM(DP_PRN_EXTENT, screen->printer_extent);
4487d522f475Smrg	    break;
4488d522f475Smrg	case 25:		/* DECTCEM: Show/hide cursor (VT200) */
4489d522f475Smrg	    DoSM(DP_CRS_VISIBLE, screen->cursor_set);
4490d522f475Smrg	    break;
4491d522f475Smrg	case 40:		/* 132 column mode              */
4492d522f475Smrg	    DoSM(DP_X_DECCOLM, screen->c132);
4493d522f475Smrg	    break;
4494d522f475Smrg	case 41:		/* curses hack                  */
4495d522f475Smrg	    DoSM(DP_X_MORE, screen->curses);
4496d522f475Smrg	    break;
4497d522f475Smrg	case 42:		/* DECNRCM national charset (VT220) */
4498d522f475Smrg	    /* do nothing */
4499d522f475Smrg	    break;
4500d522f475Smrg	case 44:		/* margin bell                  */
4501d522f475Smrg	    DoSM(DP_X_MARGIN, screen->marginbell);
4502d522f475Smrg	    break;
4503d522f475Smrg	case 45:		/* reverse wraparound   */
4504d522f475Smrg	    DoSM(DP_X_REVWRAP, xw->flags & REVERSEWRAP);
4505d522f475Smrg	    break;
4506d522f475Smrg#ifdef ALLOWLOGGING
4507d522f475Smrg	case 46:		/* logging              */
4508d522f475Smrg	    DoSM(DP_X_LOGGING, screen->logging);
4509d522f475Smrg	    break;
4510d522f475Smrg#endif
4511d522f475Smrg	case 1047:		/* alternate buffer             */
4512d522f475Smrg	    /* FALLTHRU */
4513d522f475Smrg	case 47:		/* alternate buffer             */
4514956cc18dSsnj	    DoSM(DP_X_ALTSCRN, screen->whichBuf);
4515d522f475Smrg	    break;
4516d522f475Smrg	case SET_VT200_MOUSE:	/* mouse bogus sequence         */
4517d522f475Smrg	case SET_VT200_HIGHLIGHT_MOUSE:
4518d522f475Smrg	case SET_BTN_EVENT_MOUSE:
4519d522f475Smrg	case SET_ANY_EVENT_MOUSE:
4520d522f475Smrg	    DoSM(DP_X_MOUSE, screen->send_mouse_pos);
4521d522f475Smrg	    break;
4522d522f475Smrg#if OPT_FOCUS_EVENT
4523d522f475Smrg	case SET_FOCUS_EVENT_MOUSE:
4524d522f475Smrg	    DoSM(DP_X_FOCUS, screen->send_focus_pos);
4525d522f475Smrg	    break;
4526d522f475Smrg#endif
4527d522f475Smrg	case 1048:
4528d522f475Smrg	    if (!xw->misc.titeInhibit) {
4529d522f475Smrg		CursorSave(xw);
4530d522f475Smrg	    }
4531d522f475Smrg	    break;
4532d522f475Smrg#if OPT_READLINE
4533d522f475Smrg	case SET_BUTTON1_MOVE_POINT:
4534d522f475Smrg	    SCREEN_FLAG_save(screen, click1_moves);
4535d522f475Smrg	    break;
4536d522f475Smrg	case SET_BUTTON2_MOVE_POINT:
4537d522f475Smrg	    SCREEN_FLAG_save(screen, paste_moves);
4538d522f475Smrg	    break;
4539d522f475Smrg	case SET_DBUTTON3_DELETE:
4540d522f475Smrg	    SCREEN_FLAG_save(screen, dclick3_deletes);
4541d522f475Smrg	    break;
4542d522f475Smrg	case SET_PASTE_IN_BRACKET:
4543d522f475Smrg	    SCREEN_FLAG_save(screen, paste_brackets);
4544d522f475Smrg	    break;
4545d522f475Smrg	case SET_PASTE_QUOTE:
4546d522f475Smrg	    SCREEN_FLAG_save(screen, paste_quotes);
4547d522f475Smrg	    break;
4548d522f475Smrg	case SET_PASTE_LITERAL_NL:
4549d522f475Smrg	    SCREEN_FLAG_save(screen, paste_literal_nl);
4550d522f475Smrg	    break;
4551d522f475Smrg#endif /* OPT_READLINE */
4552d522f475Smrg	}
4553d522f475Smrg    }
4554d522f475Smrg}
4555d522f475Smrg
4556d522f475Smrg/*
4557d522f475Smrg * process xterm private modes restore
4558d522f475Smrg */
4559d522f475Smrgstatic void
4560d522f475Smrgrestoremodes(XtermWidget xw)
4561d522f475Smrg{
456220d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4563d522f475Smrg    int i, j;
4564d522f475Smrg
4565d522f475Smrg    for (i = 0; i < nparam; i++) {
4566d522f475Smrg	TRACE(("restoremodes %d\n", param[i]));
4567d522f475Smrg	switch (param[i]) {
4568d522f475Smrg	case 1:		/* DECCKM                       */
4569d522f475Smrg	    bitcpy(&xw->keyboard.flags,
4570d522f475Smrg		   screen->save_modes[DP_DECCKM], MODE_DECCKM);
4571d522f475Smrg	    update_appcursor();
4572d522f475Smrg	    break;
4573d522f475Smrg	case 3:		/* DECCOLM                      */
4574d522f475Smrg	    if (screen->c132) {
4575d522f475Smrg		ClearScreen(xw);
4576d522f475Smrg		CursorSet(screen, 0, 0, xw->flags);
4577d522f475Smrg		if ((j = (screen->save_modes[DP_DECCOLM] & IN132COLUMNS)
4578d522f475Smrg		     ? 132 : 80) != ((xw->flags & IN132COLUMNS)
4579d522f475Smrg				     ? 132 : 80) || j != MaxCols(screen))
4580d522f475Smrg		    RequestResize(xw, -1, j, True);
4581d522f475Smrg		bitcpy(&xw->flags,
4582d522f475Smrg		       screen->save_modes[DP_DECCOLM],
4583d522f475Smrg		       IN132COLUMNS);
4584d522f475Smrg	    }
4585d522f475Smrg	    break;
4586d522f475Smrg	case 4:		/* DECSCLM (slow scroll)        */
4587d522f475Smrg	    if (screen->save_modes[DP_DECSCLM] & SMOOTHSCROLL) {
4588d522f475Smrg		screen->jumpscroll = 0;
4589d522f475Smrg		if (screen->scroll_amt)
4590d522f475Smrg		    FlushScroll(xw);
4591d522f475Smrg	    } else
4592d522f475Smrg		screen->jumpscroll = 1;
4593d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECSCLM], SMOOTHSCROLL);
4594d522f475Smrg	    update_jumpscroll();
4595d522f475Smrg	    break;
4596d522f475Smrg	case 5:		/* DECSCNM                      */
4597d522f475Smrg	    if ((screen->save_modes[DP_DECSCNM] ^ xw->flags) & REVERSE_VIDEO) {
4598d522f475Smrg		bitcpy(&xw->flags, screen->save_modes[DP_DECSCNM], REVERSE_VIDEO);
4599d522f475Smrg		ReverseVideo(xw);
4600d522f475Smrg		/* update_reversevideo done in RevVid */
4601d522f475Smrg	    }
4602d522f475Smrg	    break;
4603d522f475Smrg	case 6:		/* DECOM                        */
4604d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECOM], ORIGIN);
4605d522f475Smrg	    CursorSet(screen, 0, 0, xw->flags);
4606d522f475Smrg	    break;
4607d522f475Smrg
4608d522f475Smrg	case 7:		/* DECAWM                       */
4609d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_DECAWM], WRAPAROUND);
4610d522f475Smrg	    update_autowrap();
4611d522f475Smrg	    break;
4612d522f475Smrg	case 8:		/* DECARM                       */
4613d522f475Smrg	    /* ignore autorepeat */
4614d522f475Smrg	    break;
4615d522f475Smrg	case SET_X10_MOUSE:	/* MIT bogus sequence           */
46162eaa94a1Schristos	    DoRM0(DP_X_X10MSE, screen->send_mouse_pos);
4617d522f475Smrg	    break;
4618d522f475Smrg#if OPT_TOOLBAR
4619d522f475Smrg	case 10:		/* rxvt */
4620d522f475Smrg	    DoRM(DP_TOOLBAR, resource.toolBar);
4621d522f475Smrg	    ShowToolbar(resource.toolBar);
4622d522f475Smrg	    break;
4623d522f475Smrg#endif
4624d522f475Smrg#if OPT_BLINK_CURS
4625d522f475Smrg	case 12:		/* att610: Start/stop blinking cursor */
4626d522f475Smrg	    if (screen->cursor_blink_res) {
4627d522f475Smrg		DoRM(DP_CRS_BLINK, screen->cursor_blink_esc);
4628d522f475Smrg		SetCursorBlink(screen, screen->cursor_blink);
4629d522f475Smrg	    }
4630d522f475Smrg	    break;
4631d522f475Smrg#endif
4632d522f475Smrg	case 18:		/* DECPFF: print form feed */
4633d522f475Smrg	    DoRM(DP_PRN_FORMFEED, screen->printer_formfeed);
4634d522f475Smrg	    break;
4635d522f475Smrg	case 19:		/* DECPEX: print extent */
4636d522f475Smrg	    DoRM(DP_PRN_EXTENT, screen->printer_extent);
4637d522f475Smrg	    break;
4638d522f475Smrg	case 25:		/* DECTCEM: Show/hide cursor (VT200) */
4639d522f475Smrg	    DoRM(DP_CRS_VISIBLE, screen->cursor_set);
4640d522f475Smrg	    break;
4641d522f475Smrg	case 40:		/* 132 column mode              */
4642d522f475Smrg	    DoRM(DP_X_DECCOLM, screen->c132);
4643d522f475Smrg	    update_allow132();
4644d522f475Smrg	    break;
4645d522f475Smrg	case 41:		/* curses hack                  */
4646d522f475Smrg	    DoRM(DP_X_MORE, screen->curses);
4647d522f475Smrg	    update_cursesemul();
4648d522f475Smrg	    break;
4649d522f475Smrg	case 44:		/* margin bell                  */
4650d522f475Smrg	    if ((DoRM(DP_X_MARGIN, screen->marginbell)) == 0)
465120d2c4d2Smrg		screen->bellArmed = -1;
4652d522f475Smrg	    update_marginbell();
4653d522f475Smrg	    break;
4654d522f475Smrg	case 45:		/* reverse wraparound   */
4655d522f475Smrg	    bitcpy(&xw->flags, screen->save_modes[DP_X_REVWRAP], REVERSEWRAP);
4656d522f475Smrg	    update_reversewrap();
4657d522f475Smrg	    break;
4658d522f475Smrg#ifdef ALLOWLOGGING
4659d522f475Smrg	case 46:		/* logging              */
4660d522f475Smrg#ifdef ALLOWLOGFILEONOFF
4661d522f475Smrg	    if (screen->save_modes[DP_X_LOGGING])
466220d2c4d2Smrg		StartLog(xw);
4663d522f475Smrg	    else
466420d2c4d2Smrg		CloseLog(xw);
4665d522f475Smrg#endif /* ALLOWLOGFILEONOFF */
4666d522f475Smrg	    /* update_logging done by StartLog and CloseLog */
4667d522f475Smrg	    break;
4668d522f475Smrg#endif
4669d522f475Smrg	case 1047:		/* alternate buffer */
4670d522f475Smrg	    /* FALLTHRU */
4671d522f475Smrg	case 47:		/* alternate buffer */
4672d522f475Smrg	    if (!xw->misc.titeInhibit) {
4673d522f475Smrg		if (screen->save_modes[DP_X_ALTSCRN])
4674d522f475Smrg		    ToAlternate(xw);
4675d522f475Smrg		else
4676d522f475Smrg		    FromAlternate(xw);
4677d522f475Smrg		/* update_altscreen done by ToAlt and FromAlt */
4678d522f475Smrg	    } else if (xw->misc.tiXtraScroll) {
4679d522f475Smrg		if (screen->save_modes[DP_X_ALTSCRN]) {
4680d522f475Smrg		    xtermScroll(xw, screen->max_row);
4681d522f475Smrg		}
4682d522f475Smrg	    }
4683d522f475Smrg	    break;
4684d522f475Smrg	case SET_VT200_MOUSE:	/* mouse bogus sequence         */
4685d522f475Smrg	case SET_VT200_HIGHLIGHT_MOUSE:
4686d522f475Smrg	case SET_BTN_EVENT_MOUSE:
4687d522f475Smrg	case SET_ANY_EVENT_MOUSE:
46882eaa94a1Schristos	    DoRM0(DP_X_MOUSE, screen->send_mouse_pos);
4689d522f475Smrg	    break;
4690d522f475Smrg#if OPT_FOCUS_EVENT
4691d522f475Smrg	case SET_FOCUS_EVENT_MOUSE:
4692d522f475Smrg	    DoRM(DP_X_FOCUS, screen->send_focus_pos);
4693d522f475Smrg	    break;
4694d522f475Smrg#endif
4695d522f475Smrg	case 1048:
4696d522f475Smrg	    if (!xw->misc.titeInhibit) {
4697d522f475Smrg		CursorRestore(xw);
4698d522f475Smrg	    }
4699d522f475Smrg	    break;
4700d522f475Smrg#if OPT_READLINE
4701d522f475Smrg	case SET_BUTTON1_MOVE_POINT:
4702d522f475Smrg	    SCREEN_FLAG_restore(screen, click1_moves);
4703d522f475Smrg	    break;
4704d522f475Smrg	case SET_BUTTON2_MOVE_POINT:
4705d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_moves);
4706d522f475Smrg	    break;
4707d522f475Smrg	case SET_DBUTTON3_DELETE:
4708d522f475Smrg	    SCREEN_FLAG_restore(screen, dclick3_deletes);
4709d522f475Smrg	    break;
4710d522f475Smrg	case SET_PASTE_IN_BRACKET:
4711d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_brackets);
4712d522f475Smrg	    break;
4713d522f475Smrg	case SET_PASTE_QUOTE:
4714d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_quotes);
4715d522f475Smrg	    break;
4716d522f475Smrg	case SET_PASTE_LITERAL_NL:
4717d522f475Smrg	    SCREEN_FLAG_restore(screen, paste_literal_nl);
4718d522f475Smrg	    break;
4719d522f475Smrg#endif /* OPT_READLINE */
4720d522f475Smrg	}
4721d522f475Smrg    }
4722d522f475Smrg}
4723d522f475Smrg
472420d2c4d2Smrg/*
472520d2c4d2Smrg * Convert an XTextProperty to a string.
472620d2c4d2Smrg *
472720d2c4d2Smrg * This frees the data owned by the XTextProperty, and returns in its place the
472820d2c4d2Smrg * string, which must be freed by the caller.
472920d2c4d2Smrg */
473020d2c4d2Smrgstatic char *
473120d2c4d2Smrgproperty_to_string(XtermWidget xw, XTextProperty * text)
473220d2c4d2Smrg{
473320d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
473420d2c4d2Smrg    Display *dpy = screen->display;
473520d2c4d2Smrg    char *result = 0;
473620d2c4d2Smrg    char **list;
473720d2c4d2Smrg    int length = 0;
473820d2c4d2Smrg    int rc;
473920d2c4d2Smrg
474020d2c4d2Smrg    TRACE(("property_to_string value %p, encoding %s, format %d, nitems %ld\n",
474120d2c4d2Smrg	   text->value,
474220d2c4d2Smrg	   XGetAtomName(dpy, text->encoding),
474320d2c4d2Smrg	   text->format,
474420d2c4d2Smrg	   text->nitems));
474520d2c4d2Smrg
474620d2c4d2Smrg#if OPT_WIDE_CHARS
474720d2c4d2Smrg    /*
474820d2c4d2Smrg     * We will use the XmbTextPropertyToTextList call to extract UTF-8 data.
474920d2c4d2Smrg     * The xtermUtf8ToTextList() call is used to convert UTF-8 explicitly to
475020d2c4d2Smrg     * ISO-8859-1.
475120d2c4d2Smrg     */
475220d2c4d2Smrg    if ((text->format != 8)
475320d2c4d2Smrg	|| IsTitleMode(xw, tmGetUtf8)
475420d2c4d2Smrg	|| (rc = xtermUtf8ToTextList(xw, text, &list, &length)) < 0)
475520d2c4d2Smrg#endif
475620d2c4d2Smrg	if ((rc = XmbTextPropertyToTextList(dpy, text, &list, &length)) < 0)
475720d2c4d2Smrg	    rc = XTextPropertyToStringList(text, &list, &length);
475820d2c4d2Smrg
475920d2c4d2Smrg    if (rc >= 0) {
476020d2c4d2Smrg	int n, c, pass;
476120d2c4d2Smrg	size_t need = 0;
476220d2c4d2Smrg
476320d2c4d2Smrg	for (pass = 0; pass < 2; ++pass) {
476420d2c4d2Smrg	    for (n = 0, need = 0; n < length; n++) {
476520d2c4d2Smrg		char *s = list[n];
476620d2c4d2Smrg		while ((c = *s++) != '\0') {
476720d2c4d2Smrg		    if (pass)
476820d2c4d2Smrg			result[need] = (char) c;
476920d2c4d2Smrg		    ++need;
477020d2c4d2Smrg		}
477120d2c4d2Smrg	    }
477220d2c4d2Smrg	    if (pass)
477320d2c4d2Smrg		result[need] = '\0';
477420d2c4d2Smrg	    else
477520d2c4d2Smrg		result = malloc(need + 1);
477620d2c4d2Smrg	    if (result == 0)
477720d2c4d2Smrg		break;
477820d2c4d2Smrg	}
477920d2c4d2Smrg	XFreeStringList(list);
478020d2c4d2Smrg    }
478120d2c4d2Smrg    if (text->value != 0)
478220d2c4d2Smrg	XFree(text->value);
478320d2c4d2Smrg
478420d2c4d2Smrg    return result;
478520d2c4d2Smrg}
478620d2c4d2Smrg
478720d2c4d2Smrgstatic char *
478820d2c4d2Smrgget_icon_label(XtermWidget xw)
478920d2c4d2Smrg{
479020d2c4d2Smrg    XTextProperty text;
479120d2c4d2Smrg    char *result = 0;
479220d2c4d2Smrg
479320d2c4d2Smrg    if (XGetWMIconName(TScreenOf(xw)->display, VShellWindow, &text)) {
479420d2c4d2Smrg	result = property_to_string(xw, &text);
479520d2c4d2Smrg    }
479620d2c4d2Smrg    return result;
479720d2c4d2Smrg}
479820d2c4d2Smrg
479920d2c4d2Smrgstatic char *
480020d2c4d2Smrgget_window_label(XtermWidget xw)
480120d2c4d2Smrg{
480220d2c4d2Smrg    XTextProperty text;
480320d2c4d2Smrg    char *result = 0;
480420d2c4d2Smrg
480520d2c4d2Smrg    if (XGetWMName(TScreenOf(xw)->display, VShellWindow, &text)) {
480620d2c4d2Smrg	result = property_to_string(xw, &text);
480720d2c4d2Smrg    }
480820d2c4d2Smrg    return result;
480920d2c4d2Smrg}
481020d2c4d2Smrg
4811d522f475Smrg/*
4812d522f475Smrg * Report window label (icon or title) in dtterm protocol
4813d522f475Smrg * ESC ] code label ESC backslash
4814d522f475Smrg */
4815d522f475Smrgstatic void
4816d522f475Smrgreport_win_label(XtermWidget xw,
4817d522f475Smrg		 int code,
481820d2c4d2Smrg		 char *text)
4819d522f475Smrg{
4820d522f475Smrg    reply.a_type = ANSI_ESC;
4821d522f475Smrg    unparseputc(xw, ANSI_ESC);
4822d522f475Smrg    unparseputc(xw, ']');
4823d522f475Smrg    unparseputc(xw, code);
4824d522f475Smrg
482520d2c4d2Smrg    if (text != 0) {
482620d2c4d2Smrg	int copy = IsTitleMode(xw, tmGetBase16);
482720d2c4d2Smrg	if (copy) {
482820d2c4d2Smrg	    TRACE(("Encoding hex:%s\n", text));
482920d2c4d2Smrg	    text = x_encode_hex(text);
4830d522f475Smrg	}
483120d2c4d2Smrg	unparseputs(xw, text);
483220d2c4d2Smrg	if (copy)
483320d2c4d2Smrg	    free(text);
4834d522f475Smrg    }
4835d522f475Smrg
4836d522f475Smrg    unparseputc(xw, ANSI_ESC);
4837d522f475Smrg    unparseputc(xw, '\\');	/* should be ST */
4838d522f475Smrg    unparse_end(xw);
4839d522f475Smrg}
4840d522f475Smrg
4841d522f475Smrg/*
4842d522f475Smrg * Window operations (from CDE dtterm description, as well as extensions).
4843d522f475Smrg * See also "allowWindowOps" resource.
4844d522f475Smrg */
4845d522f475Smrgstatic void
4846d522f475Smrgwindow_ops(XtermWidget xw)
4847d522f475Smrg{
484820d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
4849d522f475Smrg    XWindowChanges values;
4850d522f475Smrg    XWindowAttributes win_attrs;
4851d522f475Smrg    unsigned value_mask;
4852d522f475Smrg#if OPT_MAXIMIZE
4853d522f475Smrg    unsigned root_width;
4854d522f475Smrg    unsigned root_height;
4855d522f475Smrg#endif
4856d522f475Smrg
4857d522f475Smrg    TRACE(("window_ops %d\n", param[0]));
4858d522f475Smrg    switch (param[0]) {
485920d2c4d2Smrg    case ewRestoreWin:		/* Restore (de-iconify) window */
486020d2c4d2Smrg	if (AllowWindowOps(xw, ewRestoreWin)) {
486120d2c4d2Smrg	    TRACE(("...de-iconify window\n"));
486220d2c4d2Smrg	    XMapWindow(screen->display,
486320d2c4d2Smrg		       VShellWindow);
486420d2c4d2Smrg	}
4865d522f475Smrg	break;
4866d522f475Smrg
486720d2c4d2Smrg    case ewMinimizeWin:	/* Minimize (iconify) window */
486820d2c4d2Smrg	if (AllowWindowOps(xw, ewMinimizeWin)) {
486920d2c4d2Smrg	    TRACE(("...iconify window\n"));
487020d2c4d2Smrg	    XIconifyWindow(screen->display,
487120d2c4d2Smrg			   VShellWindow,
487220d2c4d2Smrg			   DefaultScreen(screen->display));
487320d2c4d2Smrg	}
4874d522f475Smrg	break;
4875d522f475Smrg
487620d2c4d2Smrg    case ewSetWinPosition:	/* Move the window to the given position */
487720d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinPosition)) {
487820d2c4d2Smrg	    values.x = zero_if_default(1);
487920d2c4d2Smrg	    values.y = zero_if_default(2);
488020d2c4d2Smrg	    TRACE(("...move window to %d,%d\n", values.x, values.y));
488120d2c4d2Smrg	    value_mask = (CWX | CWY);
488220d2c4d2Smrg	    XReconfigureWMWindow(screen->display,
488320d2c4d2Smrg				 VShellWindow,
488420d2c4d2Smrg				 DefaultScreen(screen->display),
488520d2c4d2Smrg				 value_mask,
488620d2c4d2Smrg				 &values);
488720d2c4d2Smrg	}
4888d522f475Smrg	break;
4889d522f475Smrg
489020d2c4d2Smrg    case ewSetWinSizePixels:	/* Resize the window to given size in pixels */
489120d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinSizePixels)) {
489220d2c4d2Smrg	    RequestResize(xw, zero_if_default(1), zero_if_default(2), False);
489320d2c4d2Smrg	}
4894d522f475Smrg	break;
4895d522f475Smrg
489620d2c4d2Smrg    case ewRaiseWin:		/* Raise the window to the front of the stack */
489720d2c4d2Smrg	if (AllowWindowOps(xw, ewRaiseWin)) {
489820d2c4d2Smrg	    TRACE(("...raise window\n"));
489920d2c4d2Smrg	    XRaiseWindow(screen->display, VShellWindow);
490020d2c4d2Smrg	}
4901d522f475Smrg	break;
4902d522f475Smrg
490320d2c4d2Smrg    case ewLowerWin:		/* Lower the window to the bottom of the stack */
490420d2c4d2Smrg	if (AllowWindowOps(xw, ewLowerWin)) {
490520d2c4d2Smrg	    TRACE(("...lower window\n"));
490620d2c4d2Smrg	    XLowerWindow(screen->display, VShellWindow);
490720d2c4d2Smrg	}
4908d522f475Smrg	break;
4909d522f475Smrg
491020d2c4d2Smrg    case ewRefreshWin:		/* Refresh the window */
491120d2c4d2Smrg	if (AllowWindowOps(xw, ewRefreshWin)) {
491220d2c4d2Smrg	    TRACE(("...redraw window\n"));
491320d2c4d2Smrg	    Redraw();
491420d2c4d2Smrg	}
4915d522f475Smrg	break;
4916d522f475Smrg
491720d2c4d2Smrg    case ewSetWinSizeChars:	/* Resize the text-area, in characters */
491820d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinSizeChars)) {
491920d2c4d2Smrg	    RequestResize(xw, zero_if_default(1), zero_if_default(2), True);
492020d2c4d2Smrg	}
4921d522f475Smrg	break;
4922d522f475Smrg
4923d522f475Smrg#if OPT_MAXIMIZE
492420d2c4d2Smrg    case ewMaximizeWin:	/* Maximize or restore */
492520d2c4d2Smrg	if (AllowWindowOps(xw, ewMaximizeWin)) {
492620d2c4d2Smrg	    RequestMaximize(xw, zero_if_default(1));
492720d2c4d2Smrg	}
4928d522f475Smrg	break;
4929d522f475Smrg#endif
4930d522f475Smrg
493120d2c4d2Smrg    case ewGetWinState:	/* Report the window's state */
493220d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinState)) {
493320d2c4d2Smrg	    TRACE(("...get window attributes\n"));
493420d2c4d2Smrg	    XGetWindowAttributes(screen->display,
493520d2c4d2Smrg				 VWindow(screen),
493620d2c4d2Smrg				 &win_attrs);
493720d2c4d2Smrg	    reply.a_type = ANSI_CSI;
493820d2c4d2Smrg	    reply.a_pintro = 0;
493920d2c4d2Smrg	    reply.a_nparam = 1;
494020d2c4d2Smrg	    reply.a_param[0] = (ParmType) ((win_attrs.map_state == IsViewable)
494120d2c4d2Smrg					   ? 1
494220d2c4d2Smrg					   : 2);
494320d2c4d2Smrg	    reply.a_inters = 0;
494420d2c4d2Smrg	    reply.a_final = 't';
494520d2c4d2Smrg	    unparseseq(xw, &reply);
494620d2c4d2Smrg	}
4947d522f475Smrg	break;
4948d522f475Smrg
494920d2c4d2Smrg    case ewGetWinPosition:	/* Report the window's position */
495020d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinPosition)) {
495120d2c4d2Smrg	    TRACE(("...get window position\n"));
495220d2c4d2Smrg	    XGetWindowAttributes(screen->display,
495320d2c4d2Smrg				 WMFrameWindow(xw),
495420d2c4d2Smrg				 &win_attrs);
495520d2c4d2Smrg	    reply.a_type = ANSI_CSI;
495620d2c4d2Smrg	    reply.a_pintro = 0;
495720d2c4d2Smrg	    reply.a_nparam = 3;
495820d2c4d2Smrg	    reply.a_param[0] = 3;
495920d2c4d2Smrg	    reply.a_param[1] = (ParmType) win_attrs.x;
496020d2c4d2Smrg	    reply.a_param[2] = (ParmType) win_attrs.y;
496120d2c4d2Smrg	    reply.a_inters = 0;
496220d2c4d2Smrg	    reply.a_final = 't';
496320d2c4d2Smrg	    unparseseq(xw, &reply);
496420d2c4d2Smrg	}
4965d522f475Smrg	break;
4966d522f475Smrg
496720d2c4d2Smrg    case ewGetWinSizePixels:	/* Report the window's size in pixels */
496820d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinSizePixels)) {
496920d2c4d2Smrg	    TRACE(("...get window size in pixels\n"));
497020d2c4d2Smrg	    XGetWindowAttributes(screen->display,
497120d2c4d2Smrg				 VWindow(screen),
497220d2c4d2Smrg				 &win_attrs);
497320d2c4d2Smrg	    reply.a_type = ANSI_CSI;
497420d2c4d2Smrg	    reply.a_pintro = 0;
497520d2c4d2Smrg	    reply.a_nparam = 3;
497620d2c4d2Smrg	    reply.a_param[0] = 4;
497720d2c4d2Smrg	    /*FIXME: find if dtterm uses
497820d2c4d2Smrg	     *    win_attrs.height or Height
497920d2c4d2Smrg	     *      win_attrs.width  or Width
498020d2c4d2Smrg	     */
498120d2c4d2Smrg	    reply.a_param[1] = (ParmType) Height(screen);
498220d2c4d2Smrg	    reply.a_param[2] = (ParmType) Width(screen);
498320d2c4d2Smrg	    reply.a_inters = 0;
498420d2c4d2Smrg	    reply.a_final = 't';
498520d2c4d2Smrg	    unparseseq(xw, &reply);
498620d2c4d2Smrg	}
4987d522f475Smrg	break;
4988d522f475Smrg
498920d2c4d2Smrg    case ewGetWinSizeChars:	/* Report the text's size in characters */
499020d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinSizeChars)) {
499120d2c4d2Smrg	    TRACE(("...get window size in characters\n"));
499220d2c4d2Smrg	    reply.a_type = ANSI_CSI;
499320d2c4d2Smrg	    reply.a_pintro = 0;
499420d2c4d2Smrg	    reply.a_nparam = 3;
499520d2c4d2Smrg	    reply.a_param[0] = 8;
499620d2c4d2Smrg	    reply.a_param[1] = (ParmType) MaxRows(screen);
499720d2c4d2Smrg	    reply.a_param[2] = (ParmType) MaxCols(screen);
499820d2c4d2Smrg	    reply.a_inters = 0;
499920d2c4d2Smrg	    reply.a_final = 't';
500020d2c4d2Smrg	    unparseseq(xw, &reply);
500120d2c4d2Smrg	}
5002d522f475Smrg	break;
5003d522f475Smrg
5004d522f475Smrg#if OPT_MAXIMIZE
500520d2c4d2Smrg    case ewGetScreenSizeChars:	/* Report the screen's size, in characters */
500620d2c4d2Smrg	if (AllowWindowOps(xw, ewGetScreenSizeChars)) {
500720d2c4d2Smrg	    TRACE(("...get screen size in characters\n"));
500820d2c4d2Smrg	    if (!QueryMaximize(xw, &root_height, &root_width)) {
500920d2c4d2Smrg		root_height = 0;
501020d2c4d2Smrg		root_width = 0;
501120d2c4d2Smrg	    }
501220d2c4d2Smrg	    reply.a_type = ANSI_CSI;
501320d2c4d2Smrg	    reply.a_pintro = 0;
501420d2c4d2Smrg	    reply.a_nparam = 3;
501520d2c4d2Smrg	    reply.a_param[0] = 9;
501620d2c4d2Smrg	    reply.a_param[1] = (ParmType) (root_height
501720d2c4d2Smrg					   / (unsigned) FontHeight(screen));
501820d2c4d2Smrg	    reply.a_param[2] = (ParmType) (root_width
501920d2c4d2Smrg					   / (unsigned) FontWidth(screen));
502020d2c4d2Smrg	    reply.a_inters = 0;
502120d2c4d2Smrg	    reply.a_final = 't';
502220d2c4d2Smrg	    unparseseq(xw, &reply);
5023d522f475Smrg	}
5024d522f475Smrg	break;
5025d522f475Smrg#endif
5026d522f475Smrg
502720d2c4d2Smrg    case ewGetIconTitle:	/* Report the icon's label */
502820d2c4d2Smrg	if (AllowWindowOps(xw, ewGetIconTitle)) {
502920d2c4d2Smrg	    TRACE(("...get icon's label\n"));
503020d2c4d2Smrg	    report_win_label(xw, 'L', get_icon_label(xw));
503120d2c4d2Smrg	}
5032d522f475Smrg	break;
5033d522f475Smrg
503420d2c4d2Smrg    case ewGetWinTitle:	/* Report the window's title */
503520d2c4d2Smrg	if (AllowWindowOps(xw, ewGetWinTitle)) {
503620d2c4d2Smrg	    TRACE(("...get window's label\n"));
503720d2c4d2Smrg	    report_win_label(xw, 'l', get_window_label(xw));
503820d2c4d2Smrg	}
503920d2c4d2Smrg	break;
504020d2c4d2Smrg
504120d2c4d2Smrg    case ewPushTitle:		/* save the window's title(s) on stack */
504220d2c4d2Smrg	if (AllowWindowOps(xw, ewPushTitle)) {
504320d2c4d2Smrg	    SaveTitle *last = screen->save_title;
504420d2c4d2Smrg	    SaveTitle *item = TypeCalloc(SaveTitle);
504520d2c4d2Smrg
504620d2c4d2Smrg	    TRACE(("...push title onto stack\n"));
504720d2c4d2Smrg	    if (item != 0) {
504820d2c4d2Smrg		switch (zero_if_default(1)) {
504920d2c4d2Smrg		case 0:
505020d2c4d2Smrg		    item->iconName = get_icon_label(xw);
505120d2c4d2Smrg		    item->windowName = get_window_label(xw);
505220d2c4d2Smrg		    break;
505320d2c4d2Smrg		case 1:
505420d2c4d2Smrg		    item->iconName = get_icon_label(xw);
505520d2c4d2Smrg		    break;
505620d2c4d2Smrg		case 2:
505720d2c4d2Smrg		    item->windowName = get_window_label(xw);
505820d2c4d2Smrg		    break;
505920d2c4d2Smrg		}
506020d2c4d2Smrg		item->next = last;
506120d2c4d2Smrg		if (item->iconName == 0) {
506220d2c4d2Smrg		    item->iconName = ((last == 0)
506320d2c4d2Smrg				      ? get_icon_label(xw)
506420d2c4d2Smrg				      : x_strdup(last->iconName));
506520d2c4d2Smrg		}
506620d2c4d2Smrg		if (item->windowName == 0) {
506720d2c4d2Smrg		    item->windowName = ((last == 0)
506820d2c4d2Smrg					? get_window_label(xw)
506920d2c4d2Smrg					: x_strdup(last->windowName));
507020d2c4d2Smrg		}
507120d2c4d2Smrg		screen->save_title = item;
507220d2c4d2Smrg	    }
507320d2c4d2Smrg	}
507420d2c4d2Smrg	break;
507520d2c4d2Smrg
507620d2c4d2Smrg    case ewPopTitle:		/* restore the window's title(s) from stack */
507720d2c4d2Smrg	if (AllowWindowOps(xw, ewPopTitle)) {
507820d2c4d2Smrg	    SaveTitle *item = screen->save_title;
507920d2c4d2Smrg
508020d2c4d2Smrg	    TRACE(("...pop title off stack\n"));
508120d2c4d2Smrg	    if (item != 0) {
508220d2c4d2Smrg		switch (zero_if_default(1)) {
508320d2c4d2Smrg		case 0:
508420d2c4d2Smrg		    ChangeIconName(xw, item->iconName);
508520d2c4d2Smrg		    ChangeTitle(xw, item->windowName);
508620d2c4d2Smrg		    break;
508720d2c4d2Smrg		case 1:
508820d2c4d2Smrg		    ChangeIconName(xw, item->iconName);
508920d2c4d2Smrg		    break;
509020d2c4d2Smrg		case 2:
509120d2c4d2Smrg		    ChangeTitle(xw, item->windowName);
509220d2c4d2Smrg		    break;
509320d2c4d2Smrg		}
509420d2c4d2Smrg		screen->save_title = item->next;
509520d2c4d2Smrg		free(item->iconName);
509620d2c4d2Smrg		free(item->windowName);
509720d2c4d2Smrg		free(item);
509820d2c4d2Smrg	    }
509920d2c4d2Smrg	}
5100d522f475Smrg	break;
5101d522f475Smrg
5102d522f475Smrg    default:			/* DECSLPP (24, 25, 36, 48, 72, 144) */
510320d2c4d2Smrg	if (AllowWindowOps(xw, ewSetWinLines)) {
510420d2c4d2Smrg	    if (param[0] >= 24)
510520d2c4d2Smrg		RequestResize(xw, param[0], -1, True);
510620d2c4d2Smrg	}
5107d522f475Smrg	break;
5108d522f475Smrg    }
5109d522f475Smrg}
5110d522f475Smrg
5111d522f475Smrg/*
5112d522f475Smrg * set a bit in a word given a pointer to the word and a mask.
5113d522f475Smrg */
5114d522f475Smrgstatic void
5115d522f475Smrgbitset(unsigned *p, unsigned mask)
5116d522f475Smrg{
5117d522f475Smrg    *p |= mask;
5118d522f475Smrg}
5119d522f475Smrg
5120d522f475Smrg/*
5121d522f475Smrg * clear a bit in a word given a pointer to the word and a mask.
5122d522f475Smrg */
5123d522f475Smrgstatic void
5124d522f475Smrgbitclr(unsigned *p, unsigned mask)
5125d522f475Smrg{
5126d522f475Smrg    *p &= ~mask;
5127d522f475Smrg}
5128d522f475Smrg
5129d522f475Smrg/*
5130d522f475Smrg * Copy bits from one word to another, given a mask
5131d522f475Smrg */
5132d522f475Smrgstatic void
5133d522f475Smrgbitcpy(unsigned *p, unsigned q, unsigned mask)
5134d522f475Smrg{
5135d522f475Smrg    bitclr(p, mask);
5136d522f475Smrg    bitset(p, q & mask);
5137d522f475Smrg}
5138d522f475Smrg
5139d522f475Smrgvoid
5140d522f475Smrgunparseputc1(XtermWidget xw, int c)
5141d522f475Smrg{
5142d522f475Smrg    if (c >= 0x80 && c <= 0x9F) {
514320d2c4d2Smrg	if (!TScreenOf(xw)->control_eight_bits) {
5144d522f475Smrg	    unparseputc(xw, A2E(ANSI_ESC));
5145d522f475Smrg	    c = A2E(c - 0x40);
5146d522f475Smrg	}
5147d522f475Smrg    }
5148d522f475Smrg    unparseputc(xw, c);
5149d522f475Smrg}
5150d522f475Smrg
5151d522f475Smrgvoid
5152d522f475Smrgunparseseq(XtermWidget xw, ANSI * ap)
5153d522f475Smrg{
5154d522f475Smrg    int c;
5155d522f475Smrg    int i;
5156d522f475Smrg    int inters;
5157d522f475Smrg
5158d522f475Smrg    unparseputc1(xw, c = ap->a_type);
5159d522f475Smrg    if (c == ANSI_ESC
5160d522f475Smrg	|| c == ANSI_DCS
5161d522f475Smrg	|| c == ANSI_CSI
5162d522f475Smrg	|| c == ANSI_OSC
5163d522f475Smrg	|| c == ANSI_PM
5164d522f475Smrg	|| c == ANSI_APC
5165d522f475Smrg	|| c == ANSI_SS3) {
5166d522f475Smrg	if (ap->a_pintro != 0)
5167d522f475Smrg	    unparseputc(xw, ap->a_pintro);
5168d522f475Smrg	for (i = 0; i < ap->a_nparam; ++i) {
5169d522f475Smrg	    if (i != 0)
5170d522f475Smrg		unparseputc(xw, ';');
5171d522f475Smrg	    unparseputn(xw, (unsigned int) ap->a_param[i]);
5172d522f475Smrg	}
5173d522f475Smrg	if ((inters = ap->a_inters) != 0) {
5174d522f475Smrg	    for (i = 3; i >= 0; --i) {
5175d522f475Smrg		c = CharOf(inters >> (8 * i));
5176d522f475Smrg		if (c != 0)
5177d522f475Smrg		    unparseputc(xw, c);
5178d522f475Smrg	    }
5179d522f475Smrg	}
5180d522f475Smrg	unparseputc(xw, (char) ap->a_final);
5181d522f475Smrg    }
5182d522f475Smrg    unparse_end(xw);
5183d522f475Smrg}
5184d522f475Smrg
5185d522f475Smrgvoid
5186d522f475Smrgunparseputn(XtermWidget xw, unsigned int n)
5187d522f475Smrg{
5188d522f475Smrg    unsigned int q;
5189d522f475Smrg
5190d522f475Smrg    q = n / 10;
5191d522f475Smrg    if (q != 0)
5192d522f475Smrg	unparseputn(xw, q);
5193d522f475Smrg    unparseputc(xw, (char) ('0' + (n % 10)));
5194d522f475Smrg}
5195d522f475Smrg
5196d522f475Smrgvoid
519720d2c4d2Smrgunparseputs(XtermWidget xw, const char *s)
5198d522f475Smrg{
519920d2c4d2Smrg    if (s != 0) {
520020d2c4d2Smrg	while (*s)
520120d2c4d2Smrg	    unparseputc(xw, *s++);
520220d2c4d2Smrg    }
5203d522f475Smrg}
5204d522f475Smrg
5205d522f475Smrgvoid
5206d522f475Smrgunparseputc(XtermWidget xw, int c)
5207d522f475Smrg{
520820d2c4d2Smrg    IChar *buf = TScreenOf(xw)->unparse_bfr;
5209d522f475Smrg    unsigned len;
5210d522f475Smrg
521120d2c4d2Smrg    if ((TScreenOf(xw)->unparse_len + 2) >= sizeof(TScreenOf(xw)->unparse_bfr))
5212d522f475Smrg	unparse_end(xw);
5213d522f475Smrg
521420d2c4d2Smrg    len = TScreenOf(xw)->unparse_len;
5215d522f475Smrg
5216d522f475Smrg#if OPT_TCAP_QUERY
5217d522f475Smrg    /*
5218d522f475Smrg     * If we're returning a termcap string, it has to be translated since
5219d522f475Smrg     * a DCS must not contain any characters except for the normal 7-bit
5220d522f475Smrg     * printable ASCII (counting tab, carriage return, etc).  For now,
5221d522f475Smrg     * just use hexadecimal for the whole thing.
5222d522f475Smrg     */
522320d2c4d2Smrg    if (TScreenOf(xw)->tc_query_code >= 0) {
5224d522f475Smrg	char tmp[3];
5225d522f475Smrg	sprintf(tmp, "%02X", c & 0xFF);
52262eaa94a1Schristos	buf[len++] = CharOf(tmp[0]);
52272eaa94a1Schristos	buf[len++] = CharOf(tmp[1]);
5228d522f475Smrg    } else
5229d522f475Smrg#endif
52302eaa94a1Schristos    if ((buf[len++] = (IChar) c) == '\r' && (xw->flags & LINEFEED)) {
5231d522f475Smrg	buf[len++] = '\n';
5232d522f475Smrg    }
5233d522f475Smrg
523420d2c4d2Smrg    TScreenOf(xw)->unparse_len = len;
5235d522f475Smrg
5236d522f475Smrg    /* If send/receive mode is reset, we echo characters locally */
5237d522f475Smrg    if ((xw->keyboard.flags & MODE_SRM) == 0) {
5238d522f475Smrg	(void) doparsing(xw, (unsigned) c, &myState);
5239d522f475Smrg    }
5240d522f475Smrg}
5241d522f475Smrg
5242d522f475Smrgvoid
5243d522f475Smrgunparse_end(XtermWidget xw)
5244d522f475Smrg{
524520d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
524620d2c4d2Smrg
524720d2c4d2Smrg    if (screen->unparse_len) {
5248d522f475Smrg#ifdef VMS
524920d2c4d2Smrg	tt_write(screen->unparse_bfr, screen->unparse_len);
5250d522f475Smrg#else /* VMS */
525120d2c4d2Smrg	writePtyData(screen->respond, screen->unparse_bfr, screen->unparse_len);
5252d522f475Smrg#endif /* VMS */
525320d2c4d2Smrg	screen->unparse_len = 0;
5254d522f475Smrg    }
5255d522f475Smrg}
5256d522f475Smrg
5257d522f475Smrgvoid
5258d522f475SmrgToggleAlternate(XtermWidget xw)
5259d522f475Smrg{
526020d2c4d2Smrg    if (TScreenOf(xw)->whichBuf)
5261d522f475Smrg	FromAlternate(xw);
5262d522f475Smrg    else
5263d522f475Smrg	ToAlternate(xw);
5264d522f475Smrg}
5265d522f475Smrg
5266d522f475Smrgstatic void
5267d522f475SmrgToAlternate(XtermWidget xw)
5268d522f475Smrg{
526920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
5270d522f475Smrg
5271956cc18dSsnj    if (screen->whichBuf == 0) {
5272d522f475Smrg	TRACE(("ToAlternate\n"));
5273956cc18dSsnj	if (!screen->editBuf_index[1])
5274956cc18dSsnj	    screen->editBuf_index[1] = allocScrnBuf(xw,
5275956cc18dSsnj						    (unsigned) MaxRows(screen),
5276956cc18dSsnj						    (unsigned) MaxCols(screen),
5277956cc18dSsnj						    &screen->editBuf_data[1]);
527820d2c4d2Smrg	SwitchBufs(xw, 1);
5279956cc18dSsnj	screen->whichBuf = 1;
5280956cc18dSsnj#if OPT_SAVE_LINES
5281956cc18dSsnj	screen->visbuf = screen->editBuf_index[screen->whichBuf];
5282956cc18dSsnj#endif
5283d522f475Smrg	update_altscreen();
5284d522f475Smrg    }
5285d522f475Smrg}
5286d522f475Smrg
5287d522f475Smrgstatic void
5288d522f475SmrgFromAlternate(XtermWidget xw)
5289d522f475Smrg{
529020d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
5291d522f475Smrg
5292956cc18dSsnj    if (screen->whichBuf != 0) {
5293d522f475Smrg	TRACE(("FromAlternate\n"));
5294d522f475Smrg	if (screen->scroll_amt)
5295d522f475Smrg	    FlushScroll(xw);
5296956cc18dSsnj	screen->whichBuf = 0;
529720d2c4d2Smrg	SwitchBufs(xw, 0);
5298956cc18dSsnj#if OPT_SAVE_LINES
5299956cc18dSsnj	screen->visbuf = screen->editBuf_index[screen->whichBuf];
5300956cc18dSsnj#endif
5301d522f475Smrg	update_altscreen();
5302d522f475Smrg    }
5303d522f475Smrg}
5304d522f475Smrg
5305d522f475Smrgstatic void
530620d2c4d2SmrgSwitchBufs(XtermWidget xw, int toBuf)
5307d522f475Smrg{
530820d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
5309d522f475Smrg    int rows, top;
5310d522f475Smrg
5311d522f475Smrg    if (screen->cursor_state)
5312d522f475Smrg	HideCursor();
5313d522f475Smrg
5314d522f475Smrg    rows = MaxRows(screen);
531520d2c4d2Smrg    SwitchBufPtrs(screen, toBuf);
5316d522f475Smrg
5317d522f475Smrg    if ((top = INX2ROW(screen, 0)) < rows) {
531820d2c4d2Smrg	if (screen->scroll_amt) {
5319d522f475Smrg	    FlushScroll(xw);
532020d2c4d2Smrg	}
5321d522f475Smrg	XClearArea(screen->display,
5322d522f475Smrg		   VWindow(screen),
5323d522f475Smrg		   (int) OriginX(screen),
5324d522f475Smrg		   (int) top * FontHeight(screen) + screen->border,
5325d522f475Smrg		   (unsigned) Width(screen),
53262eaa94a1Schristos		   (unsigned) ((rows - top) * FontHeight(screen)),
5327d522f475Smrg		   False);
5328d522f475Smrg    }
5329d522f475Smrg    ScrnUpdate(xw, 0, 0, rows, MaxCols(screen), False);
5330d522f475Smrg}
5331d522f475Smrg
5332d522f475SmrgBool
5333d522f475SmrgCheckBufPtrs(TScreen * screen)
5334d522f475Smrg{
5335d522f475Smrg    return (screen->visbuf != 0
5336956cc18dSsnj#if OPT_SAVE_LINES
5337956cc18dSsnj	    && screen->editBuf_index[0] != 0
5338956cc18dSsnj#endif
5339956cc18dSsnj	    && screen->editBuf_index[1] != 0);
5340d522f475Smrg}
5341d522f475Smrg
5342d522f475Smrg/*
5343d522f475Smrg * Swap buffer line pointers between alternate and regular screens.
5344d522f475Smrg */
5345d522f475Smrgvoid
534620d2c4d2SmrgSwitchBufPtrs(TScreen * screen, int toBuf GCC_UNUSED)
5347d522f475Smrg{
5348d522f475Smrg    if (CheckBufPtrs(screen)) {
5349956cc18dSsnj#if OPT_SAVE_LINES
535020d2c4d2Smrg	screen->visbuf = screen->editBuf_index[toBuf];
5351956cc18dSsnj#else
535220d2c4d2Smrg	size_t len = ScrnPointers(screen, (size_t) MaxRows(screen));
5353d522f475Smrg
5354956cc18dSsnj	memcpy(screen->save_ptr, screen->visbuf, len);
5355956cc18dSsnj	memcpy(screen->visbuf, screen->editBuf_index[1], len);
5356956cc18dSsnj	memcpy(screen->editBuf_index[1], screen->save_ptr, len);
5357956cc18dSsnj#endif
5358d522f475Smrg    }
5359d522f475Smrg}
5360d522f475Smrg
5361d522f475Smrgvoid
5362956cc18dSsnjVTRun(XtermWidget xw)
5363d522f475Smrg{
5364956cc18dSsnj    TScreen *screen = TScreenOf(xw);
5365d522f475Smrg
5366d522f475Smrg    TRACE(("VTRun ...\n"));
5367d522f475Smrg
5368d522f475Smrg    if (!screen->Vshow) {
5369d522f475Smrg	set_vt_visibility(True);
5370d522f475Smrg    }
5371d522f475Smrg    update_vttekmode();
5372d522f475Smrg    update_vtshow();
5373d522f475Smrg    update_tekshow();
5374d522f475Smrg    set_vthide_sensitivity();
5375d522f475Smrg
5376956cc18dSsnj    ScrnAllocBuf(xw);
5377d522f475Smrg
5378d522f475Smrg    screen->cursor_state = OFF;
5379d522f475Smrg    screen->cursor_set = ON;
5380d522f475Smrg#if OPT_BLINK_CURS
5381d522f475Smrg    if (DoStartBlinking(screen))
5382d522f475Smrg	StartBlinking(screen);
5383d522f475Smrg#endif
5384d522f475Smrg
5385d522f475Smrg#if OPT_TEK4014
5386d522f475Smrg    if (Tpushb > Tpushback) {
538720d2c4d2Smrg	fillPtyData(xw, VTbuffer, (char *) Tpushback, (int) (Tpushb - Tpushback));
5388d522f475Smrg	Tpushb = Tpushback;
5389d522f475Smrg    }
5390d522f475Smrg#endif
5391d522f475Smrg    screen->is_running = True;
5392d522f475Smrg    if (!setjmp(VTend))
5393956cc18dSsnj	VTparse(xw);
5394d522f475Smrg    StopBlinking(screen);
5395d522f475Smrg    HideCursor();
5396d522f475Smrg    screen->cursor_set = OFF;
5397d522f475Smrg    TRACE(("... VTRun\n"));
5398d522f475Smrg}
5399d522f475Smrg
5400d522f475Smrg/*ARGSUSED*/
5401d522f475Smrgstatic void
5402d522f475SmrgVTExpose(Widget w GCC_UNUSED,
5403d522f475Smrg	 XEvent * event,
5404d522f475Smrg	 Region region GCC_UNUSED)
5405d522f475Smrg{
5406d522f475Smrg#ifdef DEBUG
5407d522f475Smrg    if (debug)
5408d522f475Smrg	fputs("Expose\n", stderr);
5409d522f475Smrg#endif /* DEBUG */
5410d522f475Smrg    if (event->type == Expose)
5411d522f475Smrg	HandleExposure(term, event);
5412d522f475Smrg}
5413d522f475Smrg
5414d522f475Smrgstatic void
5415d522f475SmrgVTGraphicsOrNoExpose(XEvent * event)
5416d522f475Smrg{
5417d522f475Smrg    TScreen *screen = TScreenOf(term);
5418d522f475Smrg    if (screen->incopy <= 0) {
5419d522f475Smrg	screen->incopy = 1;
5420d522f475Smrg	if (screen->scrolls > 0)
5421d522f475Smrg	    screen->scrolls--;
5422d522f475Smrg    }
5423d522f475Smrg    if (event->type == GraphicsExpose)
5424d522f475Smrg	if (HandleExposure(term, event))
5425d522f475Smrg	    screen->cursor_state = OFF;
5426d522f475Smrg    if ((event->type == NoExpose)
5427d522f475Smrg	|| ((XGraphicsExposeEvent *) event)->count == 0) {
5428d522f475Smrg	if (screen->incopy <= 0 && screen->scrolls > 0)
5429d522f475Smrg	    screen->scrolls--;
5430d522f475Smrg	if (screen->scrolls)
5431d522f475Smrg	    screen->incopy = -1;
5432d522f475Smrg	else
5433d522f475Smrg	    screen->incopy = 0;
5434d522f475Smrg    }
5435d522f475Smrg}
5436d522f475Smrg
5437d522f475Smrg/*ARGSUSED*/
5438d522f475Smrgstatic void
5439d522f475SmrgVTNonMaskableEvent(Widget w GCC_UNUSED,
5440d522f475Smrg		   XtPointer closure GCC_UNUSED,
5441d522f475Smrg		   XEvent * event,
5442d522f475Smrg		   Boolean * cont GCC_UNUSED)
5443d522f475Smrg{
5444d522f475Smrg    switch (event->type) {
5445d522f475Smrg    case GraphicsExpose:
5446d522f475Smrg    case NoExpose:
5447d522f475Smrg	VTGraphicsOrNoExpose(event);
5448d522f475Smrg	break;
5449d522f475Smrg    }
5450d522f475Smrg}
5451d522f475Smrg
5452d522f475Smrgstatic void
5453d522f475SmrgVTResize(Widget w)
5454d522f475Smrg{
5455d522f475Smrg    if (XtIsRealized(w)) {
5456d522f475Smrg	XtermWidget xw = (XtermWidget) w;
5457d522f475Smrg	ScreenResize(xw, xw->core.width, xw->core.height, &xw->flags);
5458d522f475Smrg    }
5459d522f475Smrg}
5460d522f475Smrg
54612eaa94a1Schristos#define okDimension(src,dst) ((src <= 32767) \
54622eaa94a1Schristos			  && ((dst = (Dimension) src) == src))
5463d522f475Smrg
5464d522f475Smrgstatic void
5465d522f475SmrgRequestResize(XtermWidget xw, int rows, int cols, Bool text)
5466d522f475Smrg{
546720d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
5468d522f475Smrg    unsigned long value;
5469d522f475Smrg    Dimension replyWidth, replyHeight;
5470d522f475Smrg    Dimension askedWidth, askedHeight;
5471d522f475Smrg    XtGeometryResult status;
5472d522f475Smrg    XWindowAttributes attrs;
5473d522f475Smrg
5474d522f475Smrg    TRACE(("RequestResize(rows=%d, cols=%d, text=%d)\n", rows, cols, text));
5475d522f475Smrg
547620d2c4d2Smrg    if ((int) (askedWidth = (Dimension) cols) < cols
547720d2c4d2Smrg	|| (int) (askedHeight = (Dimension) rows) < rows)
5478d522f475Smrg	return;
5479d522f475Smrg
5480d522f475Smrg    if (askedHeight == 0
5481d522f475Smrg	|| askedWidth == 0
5482d522f475Smrg	|| xw->misc.limit_resize > 0) {
5483d522f475Smrg	XGetWindowAttributes(XtDisplay(xw),
5484d522f475Smrg			     RootWindowOfScreen(XtScreen(xw)), &attrs);
5485d522f475Smrg    }
5486d522f475Smrg
5487d522f475Smrg    if (text) {
54882eaa94a1Schristos	if ((value = (unsigned long) rows) != 0) {
5489d522f475Smrg	    if (rows < 0)
54902eaa94a1Schristos		value = (unsigned long) MaxRows(screen);
54912eaa94a1Schristos	    value *= (unsigned long) FontHeight(screen);
54922eaa94a1Schristos	    value += (unsigned long) (2 * screen->border);
5493d522f475Smrg	    if (!okDimension(value, askedHeight))
5494d522f475Smrg		return;
5495d522f475Smrg	}
5496d522f475Smrg
54972eaa94a1Schristos	if ((value = (unsigned long) cols) != 0) {
5498d522f475Smrg	    if (cols < 0)
54992eaa94a1Schristos		value = (unsigned long) MaxCols(screen);
55002eaa94a1Schristos	    value *= (unsigned long) FontWidth(screen);
55012eaa94a1Schristos	    value += (unsigned long) ((2 * screen->border)
55022eaa94a1Schristos				      + ScrollbarWidth(screen));
5503d522f475Smrg	    if (!okDimension(value, askedWidth))
5504d522f475Smrg		return;
5505d522f475Smrg	}
5506d522f475Smrg
5507d522f475Smrg    } else {
5508d522f475Smrg	if (rows < 0)
5509d522f475Smrg	    askedHeight = FullHeight(screen);
5510d522f475Smrg	if (cols < 0)
5511d522f475Smrg	    askedWidth = FullWidth(screen);
5512d522f475Smrg    }
5513d522f475Smrg
5514d522f475Smrg    if (rows == 0)
55152eaa94a1Schristos	askedHeight = (Dimension) attrs.height;
5516d522f475Smrg    if (cols == 0)
55172eaa94a1Schristos	askedWidth = (Dimension) attrs.width;
5518d522f475Smrg
5519d522f475Smrg    if (xw->misc.limit_resize > 0) {
55202eaa94a1Schristos	Dimension high = (Dimension) (xw->misc.limit_resize * attrs.height);
55212eaa94a1Schristos	Dimension wide = (Dimension) (xw->misc.limit_resize * attrs.width);
552220d2c4d2Smrg	if ((int) high < attrs.height)
55232eaa94a1Schristos	    high = (Dimension) attrs.height;
5524d522f475Smrg	if (askedHeight > high)
5525d522f475Smrg	    askedHeight = high;
552620d2c4d2Smrg	if ((int) wide < attrs.width)
55272eaa94a1Schristos	    wide = (Dimension) attrs.width;
5528d522f475Smrg	if (askedWidth > wide)
5529d522f475Smrg	    askedWidth = wide;
5530d522f475Smrg    }
5531d522f475Smrg#ifndef nothack
5532d522f475Smrg    getXtermSizeHints(xw);
5533d522f475Smrg#endif
5534d522f475Smrg
5535956cc18dSsnj    TRACE(("...requesting resize %dx%d\n", askedHeight, askedWidth));
55362eaa94a1Schristos    status = REQ_RESIZE((Widget) xw,
55372eaa94a1Schristos			askedWidth, askedHeight,
55382eaa94a1Schristos			&replyWidth, &replyHeight);
5539d522f475Smrg
5540d522f475Smrg    if (status == XtGeometryYes ||
5541d522f475Smrg	status == XtGeometryDone) {
5542d522f475Smrg	ScreenResize(xw, replyWidth, replyHeight, &xw->flags);
5543d522f475Smrg    }
5544d522f475Smrg#ifndef nothack
5545d522f475Smrg    /*
5546d522f475Smrg     * XtMakeResizeRequest() has the undesirable side-effect of clearing
5547d522f475Smrg     * the window manager's hints, even on a failed request.  This would
5548d522f475Smrg     * presumably be fixed if the shell did its own work.
5549d522f475Smrg     */
5550d522f475Smrg    if (xw->hints.flags
5551d522f475Smrg	&& replyHeight
5552d522f475Smrg	&& replyWidth) {
5553d522f475Smrg	xw->hints.height = replyHeight;
5554d522f475Smrg	xw->hints.width = replyWidth;
5555d522f475Smrg
5556d522f475Smrg	TRACE(("%s@%d -- ", __FILE__, __LINE__));
5557d522f475Smrg	TRACE_HINTS(&xw->hints);
5558d522f475Smrg	XSetWMNormalHints(screen->display, VShellWindow, &xw->hints);
5559d522f475Smrg	TRACE(("%s@%d -- ", __FILE__, __LINE__));
5560d522f475Smrg	TRACE_WM_HINTS(xw);
5561d522f475Smrg    }
5562d522f475Smrg#endif
5563d522f475Smrg
5564d522f475Smrg    XSync(screen->display, False);	/* synchronize */
5565d522f475Smrg    if (XtAppPending(app_con))
5566d522f475Smrg	xevents();
5567d522f475Smrg
5568d522f475Smrg    TRACE(("...RequestResize done\n"));
5569d522f475Smrg}
5570d522f475Smrg
5571d522f475Smrgstatic String xterm_trans =
5572d522f475Smrg"<ClientMessage>WM_PROTOCOLS: DeleteWindow()\n\
5573d522f475Smrg     <MappingNotify>: KeyboardMapping()\n";
5574d522f475Smrg
5575d522f475Smrgint
5576956cc18dSsnjVTInit(XtermWidget xw)
5577d522f475Smrg{
5578956cc18dSsnj    Widget vtparent = SHELL_OF(xw);
5579d522f475Smrg
5580d522f475Smrg    TRACE(("VTInit {{\n"));
5581d522f475Smrg
5582d522f475Smrg    XtRealizeWidget(vtparent);
5583d522f475Smrg    XtOverrideTranslations(vtparent, XtParseTranslationTable(xterm_trans));
5584d522f475Smrg    (void) XSetWMProtocols(XtDisplay(vtparent), XtWindow(vtparent),
5585d522f475Smrg			   &wm_delete_window, 1);
5586d522f475Smrg    TRACE_TRANS("shell", vtparent);
5587956cc18dSsnj    TRACE_TRANS("vt100", (Widget) (xw));
5588d522f475Smrg
5589956cc18dSsnj    ScrnAllocBuf(xw);
5590d522f475Smrg
5591d522f475Smrg    TRACE(("...}} VTInit\n"));
5592d522f475Smrg    return (1);
5593d522f475Smrg}
5594d522f475Smrg
5595d522f475Smrgstatic void
5596d522f475SmrgVTClassInit(void)
5597d522f475Smrg{
5598d522f475Smrg    XtAddConverter(XtRString, XtRGravity, XmuCvtStringToGravity,
5599d522f475Smrg		   (XtConvertArgList) NULL, (Cardinal) 0);
5600d522f475Smrg}
5601d522f475Smrg
5602d522f475Smrg/*
5603d522f475Smrg * The whole wnew->screen struct is zeroed in VTInitialize.  Use these macros
5604d522f475Smrg * where applicable for copying the pieces from the request widget into the
5605d522f475Smrg * new widget.  We do not have to use them for wnew->misc, but the associated
5606d522f475Smrg * traces are very useful for debugging.
5607d522f475Smrg */
5608d522f475Smrg#if OPT_TRACE
5609d522f475Smrg#define init_Bres(name) \
5610d522f475Smrg	TRACE(("init " #name " = %s\n", \
5611d522f475Smrg		BtoS(wnew->name = request->name)))
56122eaa94a1Schristos#define init_Dres2(name,i) \
56132eaa94a1Schristos	TRACE(("init " #name "[%d] = %f\n", i, \
56142eaa94a1Schristos		wnew->name[i] = request->name[i]))
5615d522f475Smrg#define init_Ires(name) \
5616d522f475Smrg	TRACE(("init " #name " = %d\n", \
5617d522f475Smrg		wnew->name = request->name))
5618d522f475Smrg#define init_Sres(name) \
5619d522f475Smrg	TRACE(("init " #name " = \"%s\"\n", \
5620d522f475Smrg		(wnew->name = x_strtrim(request->name)) != NULL \
5621d522f475Smrg			? wnew->name : "<null>"))
56222eaa94a1Schristos#define init_Sres2(name,i) \
56232eaa94a1Schristos	TRACE(("init " #name "[%d] = \"%s\"\n", i, \
56242eaa94a1Schristos		(wnew->name(i) = x_strtrim(request->name(i))) != NULL \
56252eaa94a1Schristos			? wnew->name(i) : "<null>"))
5626d522f475Smrg#define init_Tres(offset) \
5627d522f475Smrg	TRACE(("init screen.Tcolors[" #offset "] = %#lx\n", \
5628d522f475Smrg		fill_Tres(wnew, request, offset)))
5629d522f475Smrg#else
56302eaa94a1Schristos#define init_Bres(name)    wnew->name = request->name
56312eaa94a1Schristos#define init_Dres2(name,i) wnew->name[i] = request->name[i]
56322eaa94a1Schristos#define init_Ires(name)    wnew->name = request->name
56332eaa94a1Schristos#define init_Sres(name)    wnew->name = x_strtrim(request->name)
56342eaa94a1Schristos#define init_Sres2(name,i) wnew->name(i) = x_strtrim(request->name(i))
56352eaa94a1Schristos#define init_Tres(offset)  fill_Tres(wnew, request, offset)
5636d522f475Smrg#endif
5637d522f475Smrg
5638d522f475Smrg#if OPT_COLOR_RES
5639d522f475Smrg/*
5640d522f475Smrg * Override the use of XtDefaultForeground/XtDefaultBackground to make some
5641d522f475Smrg * colors, such as cursor color, use the actual foreground/background value
5642d522f475Smrg * if there is no explicit resource value used.
5643d522f475Smrg */
5644d522f475Smrgstatic Pixel
5645d522f475Smrgfill_Tres(XtermWidget target, XtermWidget source, int offset)
5646d522f475Smrg{
5647d522f475Smrg    char *name;
5648d522f475Smrg    ScrnColors temp;
5649d522f475Smrg
565020d2c4d2Smrg    TScreenOf(target)->Tcolors[offset] = TScreenOf(source)->Tcolors[offset];
565120d2c4d2Smrg    TScreenOf(target)->Tcolors[offset].mode = False;
5652d522f475Smrg
565320d2c4d2Smrg    if ((name = x_strtrim(TScreenOf(target)->Tcolors[offset].resource)) != 0)
565420d2c4d2Smrg	TScreenOf(target)->Tcolors[offset].resource = name;
5655d522f475Smrg
5656d522f475Smrg    if (name == 0) {
565720d2c4d2Smrg	TScreenOf(target)->Tcolors[offset].value = target->dft_foreground;
5658d522f475Smrg    } else if (isDefaultForeground(name)) {
565920d2c4d2Smrg	TScreenOf(target)->Tcolors[offset].value =
5660d522f475Smrg	    ((offset == TEXT_FG || offset == TEXT_BG)
5661d522f475Smrg	     ? target->dft_foreground
566220d2c4d2Smrg	     : TScreenOf(target)->Tcolors[TEXT_FG].value);
5663d522f475Smrg    } else if (isDefaultBackground(name)) {
566420d2c4d2Smrg	TScreenOf(target)->Tcolors[offset].value =
5665d522f475Smrg	    ((offset == TEXT_FG || offset == TEXT_BG)
5666d522f475Smrg	     ? target->dft_background
566720d2c4d2Smrg	     : TScreenOf(target)->Tcolors[TEXT_BG].value);
5668d522f475Smrg    } else {
5669d522f475Smrg	memset(&temp, 0, sizeof(temp));
567020d2c4d2Smrg	if (AllocateTermColor(target, &temp, offset, name, True)) {
5671d522f475Smrg	    if (COLOR_DEFINED(&(temp), offset))
5672d522f475Smrg		free(temp.names[offset]);
567320d2c4d2Smrg	    TScreenOf(target)->Tcolors[offset].value = temp.colors[offset];
5674d522f475Smrg	}
5675d522f475Smrg    }
567620d2c4d2Smrg    return TScreenOf(target)->Tcolors[offset].value;
5677d522f475Smrg}
5678d522f475Smrg#else
5679d522f475Smrg#define fill_Tres(target, source, offset) \
568020d2c4d2Smrg	TScreenOf(target)->Tcolors[offset] = TScreenOf(source)->Tcolors[offset]
5681d522f475Smrg#endif
5682d522f475Smrg
5683d522f475Smrg#if OPT_WIDE_CHARS
5684d522f475Smrgstatic void
568520d2c4d2SmrgVTInitialize_locale(XtermWidget xw)
5686d522f475Smrg{
568720d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
5688d522f475Smrg    Bool is_utf8 = xtermEnvUTF8();
5689d522f475Smrg
5690d522f475Smrg    TRACE(("VTInitialize_locale\n"));
569120d2c4d2Smrg    TRACE(("... request screen.utf8_mode = %d\n", screen->utf8_mode));
5692d522f475Smrg
569320d2c4d2Smrg    if (screen->utf8_mode < 0)
569420d2c4d2Smrg	screen->utf8_mode = uFalse;
5695d522f475Smrg
569620d2c4d2Smrg    if (screen->utf8_mode > 3)
569720d2c4d2Smrg	screen->utf8_mode = uDefault;
5698d522f475Smrg
569920d2c4d2Smrg    screen->latin9_mode = 0;
570020d2c4d2Smrg    screen->unicode_font = 0;
5701d522f475Smrg#if OPT_LUIT_PROG
570220d2c4d2Smrg    xw->misc.callfilter = 0;
570320d2c4d2Smrg    xw->misc.use_encoding = 0;
5704d522f475Smrg
5705d522f475Smrg    TRACE(("... setup for luit:\n"));
570620d2c4d2Smrg    TRACE(("... request misc.locale_str = \"%s\"\n", xw->misc.locale_str));
5707d522f475Smrg
570820d2c4d2Smrg    if (screen->utf8_mode == uFalse) {
5709d522f475Smrg	TRACE(("... command-line +u8 overrides\n"));
5710d522f475Smrg    } else
5711d522f475Smrg#if OPT_MINI_LUIT
571220d2c4d2Smrg    if (x_strcasecmp(xw->misc.locale_str, "CHECKFONT") == 0) {
571320d2c4d2Smrg	int fl = (xw->misc.default_font.f_n
571420d2c4d2Smrg		  ? (int) strlen(xw->misc.default_font.f_n)
5715d522f475Smrg		  : 0);
5716d522f475Smrg	if (fl > 11
571720d2c4d2Smrg	    && x_strcasecmp(xw->misc.default_font.f_n + fl - 11,
5718d522f475Smrg			    "-ISO10646-1") == 0) {
571920d2c4d2Smrg	    screen->unicode_font = 1;
5720d522f475Smrg	    /* unicode font, use True */
5721d522f475Smrg#ifdef HAVE_LANGINFO_CODESET
5722d522f475Smrg	    if (!strcmp(xtermEnvEncoding(), "ANSI_X3.4-1968")
5723d522f475Smrg		|| !strcmp(xtermEnvEncoding(), "ISO-8859-1")) {
572420d2c4d2Smrg		if (screen->utf8_mode == uDefault)
572520d2c4d2Smrg		    screen->utf8_mode = uFalse;
5726d522f475Smrg	    } else if (!strcmp(xtermEnvEncoding(), "ISO-8859-15")) {
572720d2c4d2Smrg		if (screen->utf8_mode == uDefault)
572820d2c4d2Smrg		    screen->utf8_mode = uFalse;
572920d2c4d2Smrg		screen->latin9_mode = 1;
5730d522f475Smrg	    } else {
573120d2c4d2Smrg		xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1);
573220d2c4d2Smrg		screen->utf8_mode = uAlways;
5733d522f475Smrg	    }
5734d522f475Smrg#else
573520d2c4d2Smrg	    xw->misc.callfilter = is_utf8 ? 0 : 1;
573620d2c4d2Smrg	    screen->utf8_mode = uAlways;
5737d522f475Smrg#endif
5738d522f475Smrg	} else {
5739d522f475Smrg	    /* other encoding, use False */
574020d2c4d2Smrg	    if (screen->utf8_mode == uDefault) {
574120d2c4d2Smrg		screen->utf8_mode = is_utf8 ? uAlways : uFalse;
5742d522f475Smrg	    }
5743d522f475Smrg	}
5744d522f475Smrg    } else
5745d522f475Smrg#endif /* OPT_MINI_LUIT */
574620d2c4d2Smrg	if (x_strcasecmp(xw->misc.locale_str, "TRUE") == 0 ||
574720d2c4d2Smrg	    x_strcasecmp(xw->misc.locale_str, "ON") == 0 ||
574820d2c4d2Smrg	    x_strcasecmp(xw->misc.locale_str, "YES") == 0 ||
574920d2c4d2Smrg	    x_strcasecmp(xw->misc.locale_str, "AUTO") == 0 ||
575020d2c4d2Smrg	    strcmp(xw->misc.locale_str, "1") == 0) {
5751d522f475Smrg	/* when true ... fully obeying LC_CTYPE locale */
575220d2c4d2Smrg	xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1);
575320d2c4d2Smrg	screen->utf8_mode = uAlways;
575420d2c4d2Smrg    } else if (x_strcasecmp(xw->misc.locale_str, "FALSE") == 0 ||
575520d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "OFF") == 0 ||
575620d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "NO") == 0 ||
575720d2c4d2Smrg	       strcmp(xw->misc.locale_str, "0") == 0) {
5758d522f475Smrg	/* when false ... original value of utf8_mode is effective */
575920d2c4d2Smrg	if (screen->utf8_mode == uDefault) {
576020d2c4d2Smrg	    screen->utf8_mode = is_utf8 ? uAlways : uFalse;
5761d522f475Smrg	}
576220d2c4d2Smrg    } else if (x_strcasecmp(xw->misc.locale_str, "MEDIUM") == 0 ||
576320d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "SEMIAUTO") == 0) {
5764d522f475Smrg	/* when medium ... obeying locale only for UTF-8 and Asian */
5765d522f475Smrg	if (is_utf8) {
576620d2c4d2Smrg	    screen->utf8_mode = uAlways;
5767d522f475Smrg	} else if (
5768d522f475Smrg#ifdef MB_CUR_MAX
5769d522f475Smrg		      MB_CUR_MAX > 1 ||
5770d522f475Smrg#else
577120d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "ja", (size_t) 2) ||
577220d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "ko", (size_t) 2) ||
577320d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "zh", (size_t) 2) ||
577420d2c4d2Smrg#endif
577520d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "th", (size_t) 2) ||
577620d2c4d2Smrg		      !strncmp(xtermEnvLocale(), "vi", (size_t) 2)) {
577720d2c4d2Smrg	    xw->misc.callfilter = 1;
577820d2c4d2Smrg	    screen->utf8_mode = uAlways;
5779d522f475Smrg	} else {
578020d2c4d2Smrg	    screen->utf8_mode = uFalse;
5781d522f475Smrg	}
578220d2c4d2Smrg    } else if (x_strcasecmp(xw->misc.locale_str, "UTF-8") == 0 ||
578320d2c4d2Smrg	       x_strcasecmp(xw->misc.locale_str, "UTF8") == 0) {
5784d522f475Smrg	/* when UTF-8 ... UTF-8 mode */
578520d2c4d2Smrg	screen->utf8_mode = uAlways;
5786d522f475Smrg    } else {
5787d522f475Smrg	/* other words are regarded as encoding name passed to luit */
578820d2c4d2Smrg	xw->misc.callfilter = 1;
578920d2c4d2Smrg	screen->utf8_mode = uAlways;
579020d2c4d2Smrg	xw->misc.use_encoding = 1;
5791d522f475Smrg    }
579220d2c4d2Smrg    TRACE(("... updated misc.callfilter = %s\n", BtoS(xw->misc.callfilter)));
579320d2c4d2Smrg    TRACE(("... updated misc.use_encoding = %s\n", BtoS(xw->misc.use_encoding)));
5794d522f475Smrg#else
579520d2c4d2Smrg    if (screen->utf8_mode == uDefault) {
579620d2c4d2Smrg	screen->utf8_mode = is_utf8 ? uAlways : uFalse;
5797d522f475Smrg    }
5798d522f475Smrg#endif /* OPT_LUIT_PROG */
5799d522f475Smrg
580020d2c4d2Smrg    screen->utf8_inparse = (Boolean) (screen->utf8_mode != uFalse);
5801d522f475Smrg
580220d2c4d2Smrg    TRACE(("... updated screen.utf8_mode = %d\n", screen->utf8_mode));
5803d522f475Smrg    TRACE(("...VTInitialize_locale done\n"));
5804d522f475Smrg}
5805d522f475Smrg#endif
5806d522f475Smrg
5807d522f475Smrgstatic void
5808d522f475SmrgParseOnClicks(XtermWidget wnew, XtermWidget wreq, Cardinal item)
5809d522f475Smrg{
5810d522f475Smrg    /* *INDENT-OFF* */
5811d522f475Smrg    static struct {
581220d2c4d2Smrg	const char *	name;
5813d522f475Smrg	SelectUnit	code;
5814d522f475Smrg    } table[] = {
5815d522f475Smrg    	{ "char",	Select_CHAR },
5816d522f475Smrg    	{ "word",	Select_WORD },
5817d522f475Smrg    	{ "line",	Select_LINE },
5818d522f475Smrg    	{ "group",	Select_GROUP },
5819d522f475Smrg    	{ "page",	Select_PAGE },
5820d522f475Smrg    	{ "all",	Select_ALL },
5821d522f475Smrg#if OPT_SELECT_REGEX
5822d522f475Smrg    	{ "regex",	Select_REGEX },
5823d522f475Smrg#endif
5824d522f475Smrg    };
5825d522f475Smrg    /* *INDENT-ON* */
5826d522f475Smrg
582720d2c4d2Smrg    String res = TScreenOf(wreq)->onClick[item];
5828d522f475Smrg    String next = x_skip_nonblanks(res);
5829d522f475Smrg    Cardinal n;
5830d522f475Smrg
583120d2c4d2Smrg    TScreenOf(wnew)->selectMap[item] = NSELECTUNITS;
5832d522f475Smrg    for (n = 0; n < XtNumber(table); ++n) {
5833d522f475Smrg	if (!x_strncasecmp(table[n].name, res, (unsigned) (next - res))) {
583420d2c4d2Smrg	    TScreenOf(wnew)->selectMap[item] = table[n].code;
5835d522f475Smrg#if OPT_SELECT_REGEX
5836d522f475Smrg	    if (table[n].code == Select_REGEX) {
583720d2c4d2Smrg		TScreenOf(wnew)->selectExpr[item] = x_strtrim(next);
583820d2c4d2Smrg		TRACE(("Parsed regex \"%s\"\n", TScreenOf(wnew)->selectExpr[item]));
5839d522f475Smrg	    }
5840d522f475Smrg#endif
5841d522f475Smrg	    break;
5842d522f475Smrg	}
5843d522f475Smrg    }
5844d522f475Smrg}
5845d522f475Smrg
584620d2c4d2Smrg/*
584720d2c4d2Smrg * Parse a comma-separated list, returning a string which the caller must
584820d2c4d2Smrg * free, and updating the source pointer.
584920d2c4d2Smrg */
585020d2c4d2Smrgstatic char *
585120d2c4d2SmrgParseList(const char **source)
585220d2c4d2Smrg{
585320d2c4d2Smrg    const char *base = *source;
585420d2c4d2Smrg    const char *next;
585520d2c4d2Smrg    size_t size;
585620d2c4d2Smrg    char *value = 0;
585720d2c4d2Smrg    char *result;
585820d2c4d2Smrg
585920d2c4d2Smrg    /* ignore empty values */
586020d2c4d2Smrg    while (*base == ',')
586120d2c4d2Smrg	++base;
586220d2c4d2Smrg    if (*base != '\0') {
586320d2c4d2Smrg	next = base;
586420d2c4d2Smrg	while (*next != '\0' && *next != ',')
586520d2c4d2Smrg	    ++next;
586620d2c4d2Smrg	size = (size_t) (1 + next - base);
586720d2c4d2Smrg	value = malloc(size);
586820d2c4d2Smrg	if (value != 0) {
586920d2c4d2Smrg	    memcpy(value, base, size);
587020d2c4d2Smrg	    value[size - 1] = '\0';
587120d2c4d2Smrg	}
587220d2c4d2Smrg	*source = next;
587320d2c4d2Smrg    } else {
587420d2c4d2Smrg	*source = base;
587520d2c4d2Smrg    }
587620d2c4d2Smrg    result = x_strtrim(value);
587720d2c4d2Smrg    free(value);
587820d2c4d2Smrg    return result;
587920d2c4d2Smrg}
588020d2c4d2Smrg
588120d2c4d2Smrgstatic void
588220d2c4d2Smrgset_flags_from_list(char *target,
588320d2c4d2Smrg		    const char *source,
588420d2c4d2Smrg		    FlagList * list,
588520d2c4d2Smrg		    Cardinal limit)
588620d2c4d2Smrg{
588720d2c4d2Smrg    Cardinal n;
588820d2c4d2Smrg    int value = -1;
588920d2c4d2Smrg
589020d2c4d2Smrg    while (*source != '\0') {
589120d2c4d2Smrg	char *next = ParseList(&source);
589220d2c4d2Smrg	Boolean found = False;
589320d2c4d2Smrg
589420d2c4d2Smrg	if (next == 0)
589520d2c4d2Smrg	    break;
589620d2c4d2Smrg	if (isdigit(CharOf(*next))) {
589720d2c4d2Smrg	    char *temp;
589820d2c4d2Smrg
589920d2c4d2Smrg	    value = (int) strtol(next, &temp, 0);
590020d2c4d2Smrg	    if (!IsEmpty(temp)) {
590120d2c4d2Smrg		fprintf(stderr, "Expected a number: %s\n", next);
590220d2c4d2Smrg	    } else {
590320d2c4d2Smrg		for (n = 0; n < limit; ++n) {
590420d2c4d2Smrg		    if (list[n].code == value) {
590520d2c4d2Smrg			target[value] = 1;
590620d2c4d2Smrg			found = True;
590720d2c4d2Smrg			break;
590820d2c4d2Smrg		    }
590920d2c4d2Smrg		}
591020d2c4d2Smrg	    }
591120d2c4d2Smrg	} else {
591220d2c4d2Smrg	    for (n = 0; n < limit; ++n) {
591320d2c4d2Smrg		if (!x_strcasecmp(next, list[n].name)) {
591420d2c4d2Smrg		    value = list[n].code;
591520d2c4d2Smrg		    target[value] = 1;
591620d2c4d2Smrg		    found = True;
591720d2c4d2Smrg		    break;
591820d2c4d2Smrg		}
591920d2c4d2Smrg	    }
592020d2c4d2Smrg	}
592120d2c4d2Smrg	if (!found) {
592220d2c4d2Smrg	    fprintf(stderr, "Unrecognized keyword: %s\n", next);
592320d2c4d2Smrg	} else {
592420d2c4d2Smrg	    TRACE(("...found %s (%d)\n", next, value));
592520d2c4d2Smrg	}
592620d2c4d2Smrg	free(next);
592720d2c4d2Smrg    }
592820d2c4d2Smrg}
592920d2c4d2Smrg
593020d2c4d2Smrg/*
593120d2c4d2Smrg * Extend a (normally) boolean resource value by checking for additional values
593220d2c4d2Smrg * which will be mapped into true/false.
593320d2c4d2Smrg */
593420d2c4d2Smrg#if OPT_RENDERFONT
593520d2c4d2Smrgstatic int
593620d2c4d2SmrgextendedBoolean(const char *value, FlagList * table, Cardinal limit)
593720d2c4d2Smrg{
593820d2c4d2Smrg    int result = -1;
593920d2c4d2Smrg    long check;
594020d2c4d2Smrg    char *next;
594120d2c4d2Smrg    Cardinal n;
594220d2c4d2Smrg
594320d2c4d2Smrg    if ((x_strcasecmp(value, "true") == 0)
594420d2c4d2Smrg	|| (x_strcasecmp(value, "yes") == 0)
594520d2c4d2Smrg	|| (x_strcasecmp(value, "on") == 0)) {
594620d2c4d2Smrg	result = True;
594720d2c4d2Smrg    } else if ((x_strcasecmp(value, "false") == 0)
594820d2c4d2Smrg	       || (x_strcasecmp(value, "no") == 0)
594920d2c4d2Smrg	       || (x_strcasecmp(value, "off") == 0)) {
595020d2c4d2Smrg	result = False;
595120d2c4d2Smrg    } else if ((check = strtol(value, &next, 0)) >= 0 && *next == '\0') {
595220d2c4d2Smrg	if (check >= (long) limit)
595320d2c4d2Smrg	    check = True;
595420d2c4d2Smrg	result = (int) check;
595520d2c4d2Smrg    } else {
595620d2c4d2Smrg	for (n = 0; n < limit; ++n) {
595720d2c4d2Smrg	    if (x_strcasecmp(value, table[n].name) == 0) {
595820d2c4d2Smrg		result = table[n].code;
595920d2c4d2Smrg		break;
596020d2c4d2Smrg	    }
596120d2c4d2Smrg	}
596220d2c4d2Smrg    }
596320d2c4d2Smrg
596420d2c4d2Smrg    if (result < 0) {
596520d2c4d2Smrg	fprintf(stderr, "Unrecognized keyword: %s\n", value);
596620d2c4d2Smrg	result = False;
596720d2c4d2Smrg    }
596820d2c4d2Smrg
596920d2c4d2Smrg    return result;
597020d2c4d2Smrg}
597120d2c4d2Smrg#endif /* OPT_RENDERFONT */
597220d2c4d2Smrg
5973d522f475Smrg/* ARGSUSED */
5974d522f475Smrgstatic void
5975d522f475SmrgVTInitialize(Widget wrequest,
5976d522f475Smrg	     Widget new_arg,
5977d522f475Smrg	     ArgList args GCC_UNUSED,
5978d522f475Smrg	     Cardinal *num_args GCC_UNUSED)
5979d522f475Smrg{
598020d2c4d2Smrg#define Kolor(name) TScreenOf(wnew)->name.resource
5981d522f475Smrg#define TxtFg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_FG]), Kolor(name))
5982d522f475Smrg#define TxtBg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_BG]), Kolor(name))
5983d522f475Smrg#define DftFg(name) isDefaultForeground(Kolor(name))
5984d522f475Smrg#define DftBg(name) isDefaultBackground(Kolor(name))
5985d522f475Smrg
598620d2c4d2Smrg#define DATA(name) { #name, ec##name }
598720d2c4d2Smrg    static FlagList tblColorOps[] =
598820d2c4d2Smrg    {
598920d2c4d2Smrg	DATA(SetColor)
599020d2c4d2Smrg	,DATA(GetColor)
599120d2c4d2Smrg	,DATA(GetAnsiColor)
599220d2c4d2Smrg    };
599320d2c4d2Smrg#undef DATA
599420d2c4d2Smrg
599520d2c4d2Smrg#define DATA(name) { #name, ef##name }
599620d2c4d2Smrg    static FlagList tblFontOps[] =
599720d2c4d2Smrg    {
599820d2c4d2Smrg	DATA(SetFont)
599920d2c4d2Smrg	,DATA(GetFont)
600020d2c4d2Smrg    };
600120d2c4d2Smrg#undef DATA
600220d2c4d2Smrg
600320d2c4d2Smrg#define DATA(name) { #name, et##name }
600420d2c4d2Smrg    static FlagList tblTcapOps[] =
600520d2c4d2Smrg    {
600620d2c4d2Smrg	DATA(SetTcap)
600720d2c4d2Smrg	,DATA(GetTcap)
600820d2c4d2Smrg    };
600920d2c4d2Smrg#undef DATA
601020d2c4d2Smrg
601120d2c4d2Smrg#define DATA(name) { #name, ew##name }
601220d2c4d2Smrg    static FlagList tblWindowOps[] =
601320d2c4d2Smrg    {
601420d2c4d2Smrg	DATA(RestoreWin)
601520d2c4d2Smrg	,DATA(MinimizeWin)
601620d2c4d2Smrg	,DATA(SetWinPosition)
601720d2c4d2Smrg	,DATA(SetWinSizePixels)
601820d2c4d2Smrg	,DATA(RaiseWin)
601920d2c4d2Smrg	,DATA(LowerWin)
602020d2c4d2Smrg	,DATA(RefreshWin)
602120d2c4d2Smrg	,DATA(SetWinSizeChars)
602220d2c4d2Smrg#if OPT_MAXIMIZE
602320d2c4d2Smrg	,DATA(MaximizeWin)
602420d2c4d2Smrg#endif
602520d2c4d2Smrg	,DATA(GetWinState)
602620d2c4d2Smrg	,DATA(GetWinPosition)
602720d2c4d2Smrg	,DATA(GetWinSizePixels)
602820d2c4d2Smrg	,DATA(GetWinSizeChars)
602920d2c4d2Smrg#if OPT_MAXIMIZE
603020d2c4d2Smrg	,DATA(GetScreenSizeChars)
603120d2c4d2Smrg#endif
603220d2c4d2Smrg	,DATA(GetIconTitle)
603320d2c4d2Smrg	,DATA(GetWinTitle)
603420d2c4d2Smrg	,DATA(PushTitle)
603520d2c4d2Smrg	,DATA(PopTitle)
603620d2c4d2Smrg	,DATA(SetWinLines)
603720d2c4d2Smrg	,DATA(SetXprop)
603820d2c4d2Smrg	,DATA(GetSelection)
603920d2c4d2Smrg	,DATA(SetSelection)
604020d2c4d2Smrg    };
604120d2c4d2Smrg#undef DATA
604220d2c4d2Smrg
604320d2c4d2Smrg#if OPT_RENDERFONT
604420d2c4d2Smrg#define DATA(name) { #name, er##name }
604520d2c4d2Smrg    static FlagList tblRenderFont[] =
604620d2c4d2Smrg    {
604720d2c4d2Smrg	DATA(Default)
604820d2c4d2Smrg    };
604920d2c4d2Smrg#undef DATA
605020d2c4d2Smrg#endif
605120d2c4d2Smrg
6052d522f475Smrg    XtermWidget request = (XtermWidget) wrequest;
6053d522f475Smrg    XtermWidget wnew = (XtermWidget) new_arg;
6054d522f475Smrg    Widget my_parent = SHELL_OF(wnew);
6055d522f475Smrg    int i;
6056d522f475Smrg    char *s;
6057d522f475Smrg
6058d522f475Smrg#if OPT_ISO_COLORS
6059d522f475Smrg    Bool color_ok;
6060d522f475Smrg#endif
6061d522f475Smrg
606220d2c4d2Smrg#if OPT_COLOR_RES2
6063d522f475Smrg    static XtResource fake_resources[] =
6064d522f475Smrg    {
6065d522f475Smrg#if OPT_256_COLORS
6066d522f475Smrg# include <256colres.h>
6067d522f475Smrg#elif OPT_88_COLORS
6068d522f475Smrg# include <88colres.h>
6069d522f475Smrg#endif
6070d522f475Smrg    };
6071d522f475Smrg#endif /* OPT_COLOR_RES2 */
6072d522f475Smrg
607320d2c4d2Smrg    TRACE(("VTInitialize wnew %p, %d / %d resources\n",
607420d2c4d2Smrg	   (void *) wnew, XtNumber(xterm_resources), MAXRESOURCES));
607520d2c4d2Smrg    assert(XtNumber(xterm_resources) < MAXRESOURCES);
6076d522f475Smrg
6077d522f475Smrg    /* Zero out the entire "screen" component of "wnew" widget, then do
6078d522f475Smrg     * field-by-field assignment of "screen" fields that are named in the
6079d522f475Smrg     * resource list.
6080d522f475Smrg     */
608120d2c4d2Smrg    memset(TScreenOf(wnew), 0, sizeof(wnew->screen));
6082d522f475Smrg
6083d522f475Smrg    /* DESCO Sys#67660
6084d522f475Smrg     * Zero out the entire "keyboard" component of "wnew" widget.
6085d522f475Smrg     */
6086956cc18dSsnj    memset(&wnew->keyboard, 0, sizeof(wnew->keyboard));
6087d522f475Smrg
6088d522f475Smrg    /* dummy values so that we don't try to Realize the parent shell with height
6089d522f475Smrg     * or width of 0, which is illegal in X.  The real size is computed in the
6090d522f475Smrg     * xtermWidget's Realize proc, but the shell's Realize proc is called first,
6091d522f475Smrg     * and must see a valid size.
6092d522f475Smrg     */
6093d522f475Smrg    wnew->core.height = wnew->core.width = 1;
6094d522f475Smrg
6095d522f475Smrg    /*
6096d522f475Smrg     * The definition of -rv now is that it changes the definition of
6097d522f475Smrg     * XtDefaultForeground and XtDefaultBackground.  So, we no longer
6098d522f475Smrg     * need to do anything special.
6099d522f475Smrg     */
610020d2c4d2Smrg    TScreenOf(wnew)->display = wnew->core.screen->display;
6101d522f475Smrg
6102d522f475Smrg    /*
6103d522f475Smrg     * We use the default foreground/background colors to compare/check if a
6104d522f475Smrg     * color-resource has been set.
6105d522f475Smrg     */
6106d522f475Smrg#define MyBlackPixel(dpy) BlackPixel(dpy,DefaultScreen(dpy))
6107d522f475Smrg#define MyWhitePixel(dpy) WhitePixel(dpy,DefaultScreen(dpy))
6108d522f475Smrg
6109d522f475Smrg    if (request->misc.re_verse) {
611020d2c4d2Smrg	wnew->dft_foreground = MyWhitePixel(TScreenOf(wnew)->display);
611120d2c4d2Smrg	wnew->dft_background = MyBlackPixel(TScreenOf(wnew)->display);
6112d522f475Smrg    } else {
611320d2c4d2Smrg	wnew->dft_foreground = MyBlackPixel(TScreenOf(wnew)->display);
611420d2c4d2Smrg	wnew->dft_background = MyWhitePixel(TScreenOf(wnew)->display);
6115d522f475Smrg    }
6116d522f475Smrg    init_Tres(TEXT_FG);
6117d522f475Smrg    init_Tres(TEXT_BG);
6118d522f475Smrg
6119d522f475Smrg    TRACE(("Color resource initialization:\n"));
6120d522f475Smrg    TRACE(("   Default foreground %#lx\n", wnew->dft_foreground));
6121d522f475Smrg    TRACE(("   Default background %#lx\n", wnew->dft_background));
612220d2c4d2Smrg    TRACE(("   Screen foreground  %#lx\n", T_COLOR(TScreenOf(wnew), TEXT_FG)));
612320d2c4d2Smrg    TRACE(("   Screen background  %#lx\n", T_COLOR(TScreenOf(wnew), TEXT_BG)));
6124d522f475Smrg
612520d2c4d2Smrg    TScreenOf(wnew)->mouse_button = -1;
612620d2c4d2Smrg    TScreenOf(wnew)->mouse_row = -1;
612720d2c4d2Smrg    TScreenOf(wnew)->mouse_col = -1;
6128d522f475Smrg
6129d522f475Smrg#if OPT_BOX_CHARS
6130d522f475Smrg    init_Bres(screen.force_box_chars);
613120d2c4d2Smrg    init_Bres(screen.force_packed);
6132d522f475Smrg    init_Bres(screen.force_all_chars);
6133d522f475Smrg#endif
6134d522f475Smrg    init_Bres(screen.free_bold_box);
6135d522f475Smrg
6136d522f475Smrg    init_Bres(screen.c132);
6137d522f475Smrg    init_Bres(screen.curses);
6138d522f475Smrg    init_Bres(screen.hp_ll_bc);
6139d522f475Smrg#if OPT_XMC_GLITCH
6140d522f475Smrg    init_Ires(screen.xmc_glitch);
6141d522f475Smrg    init_Ires(screen.xmc_attributes);
6142d522f475Smrg    init_Bres(screen.xmc_inline);
6143d522f475Smrg    init_Bres(screen.move_sgr_ok);
6144d522f475Smrg#endif
6145d522f475Smrg#if OPT_BLINK_CURS
6146d522f475Smrg    init_Bres(screen.cursor_blink);
6147d522f475Smrg    init_Ires(screen.blink_on);
6148d522f475Smrg    init_Ires(screen.blink_off);
614920d2c4d2Smrg    TScreenOf(wnew)->cursor_blink_res = TScreenOf(wnew)->cursor_blink;
6150d522f475Smrg#endif
61512eaa94a1Schristos    init_Bres(screen.cursor_underline);
6152d522f475Smrg#if OPT_BLINK_TEXT
6153d522f475Smrg    init_Ires(screen.blink_as_bold);
6154d522f475Smrg#endif
6155d522f475Smrg    init_Ires(screen.border);
6156d522f475Smrg    init_Bres(screen.jumpscroll);
6157956cc18dSsnj    init_Bres(screen.fastscroll);
6158d522f475Smrg    init_Bres(screen.old_fkeys);
6159d522f475Smrg    init_Bres(screen.delete_is_del);
616020d2c4d2Smrg    wnew->keyboard.type = TScreenOf(wnew)->old_fkeys
6161d522f475Smrg	? keyboardIsLegacy
6162d522f475Smrg	: keyboardIsDefault;
6163d522f475Smrg#ifdef ALLOWLOGGING
6164d522f475Smrg    init_Sres(screen.logfile);
6165d522f475Smrg#endif
6166d522f475Smrg    init_Bres(screen.bellIsUrgent);
6167d522f475Smrg    init_Bres(screen.bellOnReset);
6168d522f475Smrg    init_Bres(screen.marginbell);
6169d522f475Smrg    init_Bres(screen.multiscroll);
6170d522f475Smrg    init_Ires(screen.nmarginbell);
6171d522f475Smrg    init_Ires(screen.savelines);
6172d522f475Smrg    init_Ires(screen.scrollBarBorder);
6173d522f475Smrg    init_Ires(screen.scrolllines);
6174d522f475Smrg    init_Bres(screen.scrollttyoutput);
6175d522f475Smrg    init_Bres(screen.scrollkey);
6176d522f475Smrg
6177d522f475Smrg    init_Sres(screen.term_id);
617820d2c4d2Smrg    for (s = TScreenOf(request)->term_id; *s; s++) {
6179d522f475Smrg	if (!isalpha(CharOf(*s)))
6180d522f475Smrg	    break;
6181d522f475Smrg    }
618220d2c4d2Smrg    TScreenOf(wnew)->terminal_id = atoi(s);
618320d2c4d2Smrg    if (TScreenOf(wnew)->terminal_id < MIN_DECID)
618420d2c4d2Smrg	TScreenOf(wnew)->terminal_id = MIN_DECID;
618520d2c4d2Smrg    if (TScreenOf(wnew)->terminal_id > MAX_DECID)
618620d2c4d2Smrg	TScreenOf(wnew)->terminal_id = MAX_DECID;
6187d522f475Smrg    TRACE(("term_id '%s' -> terminal_id %d\n",
618820d2c4d2Smrg	   TScreenOf(wnew)->term_id,
618920d2c4d2Smrg	   TScreenOf(wnew)->terminal_id));
619020d2c4d2Smrg
619120d2c4d2Smrg    TScreenOf(wnew)->vtXX_level = (TScreenOf(wnew)->terminal_id / 100);
6192d522f475Smrg
619320d2c4d2Smrg    init_Ires(screen.title_modes);
6194d522f475Smrg    init_Bres(screen.visualbell);
6195d522f475Smrg    init_Ires(screen.visualBellDelay);
6196d522f475Smrg    init_Bres(screen.poponbell);
6197d522f475Smrg    init_Ires(misc.limit_resize);
619820d2c4d2Smrg
6199d522f475Smrg#if OPT_NUM_LOCK
6200d522f475Smrg    init_Bres(misc.real_NumLock);
6201d522f475Smrg    init_Bres(misc.alwaysUseMods);
6202d522f475Smrg    wnew->misc.num_lock = 0;
6203d522f475Smrg    wnew->misc.alt_mods = 0;
6204d522f475Smrg    wnew->misc.meta_mods = 0;
6205d522f475Smrg    wnew->misc.other_mods = 0;
6206d522f475Smrg#endif
620720d2c4d2Smrg
6208d522f475Smrg#if OPT_SHIFT_FONTS
6209d522f475Smrg    init_Bres(misc.shift_fonts);
6210d522f475Smrg#endif
6211d522f475Smrg#if OPT_SUNPC_KBD
6212d522f475Smrg    init_Ires(misc.ctrl_fkeys);
6213d522f475Smrg#endif
6214d522f475Smrg#if OPT_TEK4014
6215d522f475Smrg    TEK4014_SHOWN(wnew) = False;	/* not a resource... */
6216d522f475Smrg    init_Bres(misc.tekInhibit);
6217d522f475Smrg    init_Bres(misc.tekSmall);
6218d522f475Smrg    init_Bres(misc.TekEmu);
6219d522f475Smrg#endif
6220d522f475Smrg#if OPT_TCAP_QUERY
622120d2c4d2Smrg    TScreenOf(wnew)->tc_query_code = -1;
6222d522f475Smrg#endif
6223d522f475Smrg    wnew->misc.re_verse0 = request->misc.re_verse;
6224d522f475Smrg    init_Bres(misc.re_verse);
6225d522f475Smrg    init_Ires(screen.multiClickTime);
6226d522f475Smrg    init_Ires(screen.bellSuppressTime);
6227d522f475Smrg    init_Sres(screen.charClass);
6228d522f475Smrg
6229d522f475Smrg    init_Bres(screen.always_highlight);
6230d522f475Smrg    init_Bres(screen.brokenSelections);
6231d522f475Smrg    init_Bres(screen.cutNewline);
6232d522f475Smrg    init_Bres(screen.cutToBeginningOfLine);
6233d522f475Smrg    init_Bres(screen.highlight_selection);
6234d522f475Smrg    init_Bres(screen.i18nSelections);
6235d522f475Smrg    init_Bres(screen.keepSelection);
6236d522f475Smrg    init_Bres(screen.selectToClipboard);
6237d522f475Smrg    init_Bres(screen.trim_selection);
6238d522f475Smrg
623920d2c4d2Smrg    TScreenOf(wnew)->pointer_cursor = TScreenOf(request)->pointer_cursor;
6240d522f475Smrg    init_Ires(screen.pointer_mode);
6241d522f475Smrg
6242d522f475Smrg    init_Sres(screen.answer_back);
6243d522f475Smrg
6244d522f475Smrg    init_Sres(screen.printer_command);
6245d522f475Smrg    init_Bres(screen.printer_autoclose);
6246d522f475Smrg    init_Bres(screen.printer_extent);
6247d522f475Smrg    init_Bres(screen.printer_formfeed);
624820d2c4d2Smrg    init_Bres(screen.printer_newline);
6249d522f475Smrg    init_Ires(screen.printer_controlmode);
6250d522f475Smrg#if OPT_PRINT_COLORS
6251d522f475Smrg    init_Ires(screen.print_attributes);
6252d522f475Smrg#endif
6253d522f475Smrg
6254d522f475Smrg    init_Sres(screen.keyboard_dialect);
6255d522f475Smrg
6256d522f475Smrg    init_Bres(screen.input_eight_bits);
6257d522f475Smrg    init_Bres(screen.output_eight_bits);
6258d522f475Smrg    init_Bres(screen.control_eight_bits);
6259d522f475Smrg    init_Bres(screen.backarrow_key);
6260d522f475Smrg    init_Bres(screen.alt_is_not_meta);
6261d522f475Smrg    init_Bres(screen.alt_sends_esc);
6262d522f475Smrg    init_Bres(screen.meta_sends_esc);
6263d522f475Smrg
6264d522f475Smrg    init_Bres(screen.allowSendEvent0);
626520d2c4d2Smrg    init_Bres(screen.allowColorOp0);
62662eaa94a1Schristos    init_Bres(screen.allowFontOp0);
62672eaa94a1Schristos    init_Bres(screen.allowTcapOp0);
6268d522f475Smrg    init_Bres(screen.allowTitleOp0);
6269d522f475Smrg    init_Bres(screen.allowWindowOp0);
6270d522f475Smrg
627120d2c4d2Smrg#if OPT_SCROLL_LOCK
627220d2c4d2Smrg    init_Bres(screen.allowScrollLock0);
627320d2c4d2Smrg#endif
627420d2c4d2Smrg
627520d2c4d2Smrg    init_Sres(screen.disallowedColorOps);
627620d2c4d2Smrg
627720d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_color_ops,
627820d2c4d2Smrg			TScreenOf(wnew)->disallowedColorOps,
627920d2c4d2Smrg			tblColorOps,
628020d2c4d2Smrg			ecLAST);
628120d2c4d2Smrg
628220d2c4d2Smrg    init_Sres(screen.disallowedFontOps);
628320d2c4d2Smrg
628420d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_font_ops,
628520d2c4d2Smrg			TScreenOf(wnew)->disallowedFontOps,
628620d2c4d2Smrg			tblFontOps,
628720d2c4d2Smrg			efLAST);
628820d2c4d2Smrg
628920d2c4d2Smrg    init_Sres(screen.disallowedTcapOps);
629020d2c4d2Smrg
629120d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_tcap_ops,
629220d2c4d2Smrg			TScreenOf(wnew)->disallowedTcapOps,
629320d2c4d2Smrg			tblTcapOps,
629420d2c4d2Smrg			etLAST);
629520d2c4d2Smrg
629620d2c4d2Smrg    init_Sres(screen.disallowedWinOps);
629720d2c4d2Smrg
629820d2c4d2Smrg    set_flags_from_list(TScreenOf(wnew)->disallow_win_ops,
629920d2c4d2Smrg			TScreenOf(wnew)->disallowedWinOps,
630020d2c4d2Smrg			tblWindowOps,
630120d2c4d2Smrg			ewLAST);
630220d2c4d2Smrg
6303956cc18dSsnj    init_Sres(screen.default_string);
6304956cc18dSsnj    init_Sres(screen.eightbit_select_types);
6305956cc18dSsnj#if OPT_WIDE_CHARS
6306956cc18dSsnj    init_Sres(screen.utf8_select_types);
6307956cc18dSsnj#endif
6308956cc18dSsnj
6309d522f475Smrg    /* make a copy so that editres cannot change the resource after startup */
631020d2c4d2Smrg    TScreenOf(wnew)->allowSendEvents = TScreenOf(wnew)->allowSendEvent0;
631120d2c4d2Smrg    TScreenOf(wnew)->allowColorOps = TScreenOf(wnew)->allowColorOp0;
631220d2c4d2Smrg    TScreenOf(wnew)->allowFontOps = TScreenOf(wnew)->allowFontOp0;
631320d2c4d2Smrg    TScreenOf(wnew)->allowTcapOps = TScreenOf(wnew)->allowTcapOp0;
631420d2c4d2Smrg    TScreenOf(wnew)->allowTitleOps = TScreenOf(wnew)->allowTitleOp0;
631520d2c4d2Smrg    TScreenOf(wnew)->allowWindowOps = TScreenOf(wnew)->allowWindowOp0;
631620d2c4d2Smrg
631720d2c4d2Smrg#if OPT_SCROLL_LOCK
631820d2c4d2Smrg    TScreenOf(wnew)->allowScrollLock = TScreenOf(wnew)->allowScrollLock0;
631920d2c4d2Smrg#endif
6320d522f475Smrg
6321d522f475Smrg    init_Bres(screen.quiet_grab);
6322d522f475Smrg
6323d522f475Smrg#ifndef NO_ACTIVE_ICON
632420d2c4d2Smrg    TScreenOf(wnew)->fnt_icon.fs = TScreenOf(request)->fnt_icon.fs;
6325d522f475Smrg    init_Bres(misc.active_icon);
6326d522f475Smrg    init_Ires(misc.icon_border_width);
6327d522f475Smrg    wnew->misc.icon_border_pixel = request->misc.icon_border_pixel;
6328d522f475Smrg#endif /* NO_ACTIVE_ICON */
6329d522f475Smrg    init_Bres(misc.titeInhibit);
6330d522f475Smrg    init_Bres(misc.tiXtraScroll);
6331d522f475Smrg    init_Bres(misc.dynamicColors);
6332d522f475Smrg    for (i = fontMenu_font1; i <= fontMenu_lastBuiltin; i++) {
63332eaa94a1Schristos	init_Sres2(screen.MenuFontName, i);
6334d522f475Smrg    }
6335956cc18dSsnj    init_Ires(misc.fontWarnings);
633620d2c4d2Smrg#define DefaultFontNames TScreenOf(wnew)->menu_font_names[fontMenu_default]
6337956cc18dSsnj    DefaultFontNames[fNorm] = wnew->misc.default_font.f_n;
6338956cc18dSsnj    DefaultFontNames[fBold] = wnew->misc.default_font.f_b;
6339956cc18dSsnj#if OPT_WIDE_CHARS
6340956cc18dSsnj    DefaultFontNames[fWide] = wnew->misc.default_font.f_w;
6341956cc18dSsnj    DefaultFontNames[fWBold] = wnew->misc.default_font.f_wb;
6342956cc18dSsnj#endif
634320d2c4d2Smrg    TScreenOf(wnew)->MenuFontName(fontMenu_fontescape) = NULL;
634420d2c4d2Smrg    TScreenOf(wnew)->MenuFontName(fontMenu_fontsel) = NULL;
6345d522f475Smrg
634620d2c4d2Smrg    TScreenOf(wnew)->menu_font_number = fontMenu_default;
6347d522f475Smrg    init_Sres(screen.initial_font);
634820d2c4d2Smrg    if (TScreenOf(wnew)->initial_font != 0) {
634920d2c4d2Smrg	int result = xtermGetFont(TScreenOf(wnew)->initial_font);
6350d522f475Smrg	if (result >= 0)
635120d2c4d2Smrg	    TScreenOf(wnew)->menu_font_number = result;
6352d522f475Smrg    }
6353d522f475Smrg#if OPT_BROKEN_OSC
6354d522f475Smrg    init_Bres(screen.brokenLinuxOSC);
6355d522f475Smrg#endif
6356d522f475Smrg
6357d522f475Smrg#if OPT_BROKEN_ST
6358d522f475Smrg    init_Bres(screen.brokenStringTerm);
6359d522f475Smrg#endif
6360d522f475Smrg
6361d522f475Smrg#if OPT_C1_PRINT
6362d522f475Smrg    init_Bres(screen.c1_printable);
6363d522f475Smrg#endif
6364d522f475Smrg
6365d522f475Smrg#if OPT_CLIP_BOLD
6366d522f475Smrg    init_Bres(screen.use_clipping);
6367d522f475Smrg#endif
6368d522f475Smrg
6369d522f475Smrg#if OPT_DEC_CHRSET
6370d522f475Smrg    init_Bres(screen.font_doublesize);
6371d522f475Smrg    init_Ires(screen.cache_doublesize);
637220d2c4d2Smrg    if (TScreenOf(wnew)->cache_doublesize > NUM_CHRSET)
637320d2c4d2Smrg	TScreenOf(wnew)->cache_doublesize = NUM_CHRSET;
637420d2c4d2Smrg    if (TScreenOf(wnew)->cache_doublesize == 0)
637520d2c4d2Smrg	TScreenOf(wnew)->font_doublesize = False;
6376d522f475Smrg    TRACE(("Doublesize%s enabled, up to %d fonts\n",
637720d2c4d2Smrg	   TScreenOf(wnew)->font_doublesize ? "" : " not",
637820d2c4d2Smrg	   TScreenOf(wnew)->cache_doublesize));
6379d522f475Smrg#endif
6380d522f475Smrg
6381d522f475Smrg#if OPT_ISO_COLORS
6382d522f475Smrg    init_Ires(screen.veryBoldColors);
6383d522f475Smrg    init_Bres(screen.boldColors);
6384d522f475Smrg    init_Bres(screen.colorAttrMode);
6385d522f475Smrg    init_Bres(screen.colorBDMode);
6386d522f475Smrg    init_Bres(screen.colorBLMode);
6387d522f475Smrg    init_Bres(screen.colorMode);
6388d522f475Smrg    init_Bres(screen.colorULMode);
6389d522f475Smrg    init_Bres(screen.italicULMode);
6390d522f475Smrg    init_Bres(screen.colorRVMode);
6391d522f475Smrg
639220d2c4d2Smrg#if OPT_COLOR_RES2
639320d2c4d2Smrg    TRACE(("...will fake resources for color%d to color%d\n",
639420d2c4d2Smrg	   MIN_ANSI_COLORS,
639520d2c4d2Smrg	   NUM_ANSI_COLORS - 1));
639620d2c4d2Smrg#endif
6397d522f475Smrg    for (i = 0, color_ok = False; i < MAXCOLORS; i++) {
6398d522f475Smrg
639920d2c4d2Smrg#if OPT_COLOR_RES2
6400d522f475Smrg	/*
6401d522f475Smrg	 * Xt has a hardcoded limit on the maximum number of resources that can
6402d522f475Smrg	 * be used in a widget.  If we configure both luit (which implies
6403d522f475Smrg	 * wide-characters) and 256-colors, it goes over that limit.  Most
6404d522f475Smrg	 * people would not need a resource-file with 256-colors; the default
6405d522f475Smrg	 * values in our table are sufficient.  In that case, fake the resource
6406d522f475Smrg	 * setting by copying the default value from the table.  The #define's
6407d522f475Smrg	 * can be overridden to make these true resources.
6408d522f475Smrg	 */
6409d522f475Smrg	if (i >= MIN_ANSI_COLORS && i < NUM_ANSI_COLORS) {
641020d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].resource
6411d522f475Smrg		= ((char *) fake_resources[i - MIN_ANSI_COLORS].default_addr);
641220d2c4d2Smrg	    if (TScreenOf(wnew)->Acolors[i].resource == 0)
641320d2c4d2Smrg		TScreenOf(wnew)->Acolors[i].resource = XtDefaultForeground;
6414d522f475Smrg	} else
6415d522f475Smrg#endif /* OPT_COLOR_RES2 */
641620d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i] = TScreenOf(request)->Acolors[i];
6417d522f475Smrg
6418d522f475Smrg#if OPT_COLOR_RES
641920d2c4d2Smrg	TRACE(("Acolors[%d] = %s\n", i, TScreenOf(wnew)->Acolors[i].resource));
642020d2c4d2Smrg	TScreenOf(wnew)->Acolors[i].mode = False;
6421d522f475Smrg	if (DftFg(Acolors[i])) {
642220d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].value = T_COLOR(TScreenOf(wnew), TEXT_FG);
642320d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].mode = True;
6424d522f475Smrg	} else if (DftBg(Acolors[i])) {
642520d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].value = T_COLOR(TScreenOf(wnew), TEXT_BG);
642620d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i].mode = True;
6427d522f475Smrg	} else {
6428d522f475Smrg	    color_ok = True;
6429d522f475Smrg	}
6430d522f475Smrg#else
643120d2c4d2Smrg	TRACE(("Acolors[%d] = %#lx\n", i, TScreenOf(request)->Acolors[i]));
643220d2c4d2Smrg	if (TScreenOf(wnew)->Acolors[i] != wnew->dft_foreground &&
643320d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i] != T_COLOR(TScreenOf(wnew), TEXT_FG) &&
643420d2c4d2Smrg	    TScreenOf(wnew)->Acolors[i] != T_COLOR(TScreenOf(wnew), TEXT_BG))
6435d522f475Smrg	    color_ok = True;
6436d522f475Smrg#endif
6437d522f475Smrg    }
6438d522f475Smrg
6439d522f475Smrg    /*
6440d522f475Smrg     * Check if we're trying to use color in a monochrome screen.  Disable
6441d522f475Smrg     * color in that case, since that would make ANSI colors unusable.  A 4-bit
6442d522f475Smrg     * or 8-bit display is usable, so we do not have to check for anything more
6443d522f475Smrg     * specific.
6444d522f475Smrg     */
6445d522f475Smrg    if (color_ok) {
644620d2c4d2Smrg	Display *display = TScreenOf(wnew)->display;
6447d522f475Smrg	XVisualInfo myTemplate, *visInfoPtr;
6448d522f475Smrg	int numFound;
6449d522f475Smrg
6450d522f475Smrg	myTemplate.visualid = XVisualIDFromVisual(DefaultVisual(display,
6451d522f475Smrg								XDefaultScreen(display)));
6452d522f475Smrg	visInfoPtr = XGetVisualInfo(display, (long) VisualIDMask,
6453d522f475Smrg				    &myTemplate, &numFound);
6454d522f475Smrg	if (visInfoPtr == 0
6455d522f475Smrg	    || numFound == 0
6456d522f475Smrg	    || visInfoPtr->depth <= 1) {
6457d522f475Smrg	    TRACE(("disabling color since screen is monochrome\n"));
6458d522f475Smrg	    color_ok = False;
6459d522f475Smrg	} else {
6460d522f475Smrg	    XFree(visInfoPtr);
6461d522f475Smrg	}
6462d522f475Smrg    }
6463d522f475Smrg
6464d522f475Smrg    /* If none of the colors are anything other than the foreground or
6465d522f475Smrg     * background, we'll assume this isn't color, no matter what the colorMode
6466d522f475Smrg     * resource says.  (There doesn't seem to be any good way to determine if
6467d522f475Smrg     * the resource lookup failed versus the user having misconfigured this).
6468d522f475Smrg     */
6469d522f475Smrg    if (!color_ok) {
647020d2c4d2Smrg	TScreenOf(wnew)->colorMode = False;
6471d522f475Smrg	TRACE(("All colors are foreground or background: disable colorMode\n"));
6472d522f475Smrg    }
6473d522f475Smrg    wnew->sgr_foreground = -1;
6474d522f475Smrg    wnew->sgr_background = -1;
6475d522f475Smrg    wnew->sgr_extended = False;
6476d522f475Smrg#endif /* OPT_ISO_COLORS */
6477d522f475Smrg
6478d522f475Smrg    /*
6479d522f475Smrg     * Decode the resources that control the behavior on multiple mouse clicks.
6480d522f475Smrg     * A single click is always bound to normal character selection, but the
6481d522f475Smrg     * other flavors can be changed.
6482d522f475Smrg     */
6483d522f475Smrg    for (i = 0; i < NSELECTUNITS; ++i) {
6484d522f475Smrg	int ck = (i + 1);
648520d2c4d2Smrg	TScreenOf(wnew)->maxClicks = ck;
6486d522f475Smrg	if (i == Select_CHAR)
648720d2c4d2Smrg	    TScreenOf(wnew)->selectMap[i] = Select_CHAR;
648820d2c4d2Smrg	else if (TScreenOf(request)->onClick[i] != 0)
6489d522f475Smrg	    ParseOnClicks(wnew, request, (unsigned) i);
6490d522f475Smrg	else if (i <= Select_LINE)
649120d2c4d2Smrg	    TScreenOf(wnew)->selectMap[i] = (SelectUnit) i;
6492d522f475Smrg	else
6493d522f475Smrg	    break;
6494d522f475Smrg	TRACE(("on%dClicks %s=%d\n", ck,
649520d2c4d2Smrg	       NonNull(TScreenOf(request)->onClick[i]),
649620d2c4d2Smrg	       TScreenOf(wnew)->selectMap[i]));
649720d2c4d2Smrg	if (TScreenOf(wnew)->selectMap[i] == NSELECTUNITS)
6498d522f475Smrg	    break;
6499d522f475Smrg    }
650020d2c4d2Smrg    TRACE(("maxClicks %d\n", TScreenOf(wnew)->maxClicks));
6501d522f475Smrg
6502d522f475Smrg    init_Tres(MOUSE_FG);
6503d522f475Smrg    init_Tres(MOUSE_BG);
6504d522f475Smrg    init_Tres(TEXT_CURSOR);
6505d522f475Smrg#if OPT_HIGHLIGHT_COLOR
6506d522f475Smrg    init_Tres(HIGHLIGHT_BG);
6507d522f475Smrg    init_Tres(HIGHLIGHT_FG);
6508d522f475Smrg    init_Bres(screen.hilite_reverse);
6509d522f475Smrg    init_Bres(screen.hilite_color);
651020d2c4d2Smrg    if (TScreenOf(wnew)->hilite_color == Maybe) {
651120d2c4d2Smrg	TScreenOf(wnew)->hilite_color = False;
6512d522f475Smrg#if OPT_COLOR_RES
6513d522f475Smrg	/*
6514d522f475Smrg	 * If the highlight text/background are both set, and if they are
6515d522f475Smrg	 * not equal to either the text/background or background/text, then
6516d522f475Smrg	 * set the highlightColorMode automatically.
6517d522f475Smrg	 */
6518d522f475Smrg	if (!DftFg(Tcolors[HIGHLIGHT_BG])
6519d522f475Smrg	    && !DftBg(Tcolors[HIGHLIGHT_FG])
6520d522f475Smrg	    && !TxtFg(Tcolors[HIGHLIGHT_BG])
6521d522f475Smrg	    && !TxtBg(Tcolors[HIGHLIGHT_FG])
6522d522f475Smrg	    && !TxtBg(Tcolors[HIGHLIGHT_BG])
6523d522f475Smrg	    && !TxtFg(Tcolors[HIGHLIGHT_FG])) {
6524d522f475Smrg	    TRACE(("...setting hilite_color automatically\n"));
652520d2c4d2Smrg	    TScreenOf(wnew)->hilite_color = True;
6526d522f475Smrg	}
6527d522f475Smrg#endif
6528d522f475Smrg    }
6529d522f475Smrg#endif
6530d522f475Smrg
6531d522f475Smrg#if OPT_TEK4014
6532d522f475Smrg    /*
6533d522f475Smrg     * The Tek4014 window has no separate resources for foreground, background
6534d522f475Smrg     * and cursor color.  Since xterm always creates the vt100 widget first, we
6535d522f475Smrg     * can set the Tektronix colors here.  That lets us use escape sequences to
6536d522f475Smrg     * set its dynamic colors and get consistent behavior whether or not the
6537d522f475Smrg     * window is displayed.
6538d522f475Smrg     */
653920d2c4d2Smrg    TScreenOf(wnew)->Tcolors[TEK_BG] = TScreenOf(wnew)->Tcolors[TEXT_BG];
654020d2c4d2Smrg    TScreenOf(wnew)->Tcolors[TEK_FG] = TScreenOf(wnew)->Tcolors[TEXT_FG];
654120d2c4d2Smrg    TScreenOf(wnew)->Tcolors[TEK_CURSOR] = TScreenOf(wnew)->Tcolors[TEXT_CURSOR];
6542d522f475Smrg#endif
6543d522f475Smrg
6544d522f475Smrg#if OPT_RENDERFONT
6545d522f475Smrg    for (i = 0; i <= fontMenu_lastBuiltin; ++i) {
65462eaa94a1Schristos	init_Dres2(misc.face_size, i);
6547d522f475Smrg    }
6548d522f475Smrg    init_Sres(misc.face_name);
6549d522f475Smrg    init_Sres(misc.face_wide_name);
655020d2c4d2Smrg    init_Sres(misc.render_font_s);
655120d2c4d2Smrg    wnew->misc.render_font =
655220d2c4d2Smrg	(Boolean) extendedBoolean(wnew->misc.render_font_s,
655320d2c4d2Smrg				  tblRenderFont, erLast);
655420d2c4d2Smrg    if (wnew->misc.render_font == erDefault) {
655520d2c4d2Smrg	if (IsEmpty(wnew->misc.face_name)) {
655620d2c4d2Smrg	    wnew->misc.face_name = x_strdup(DEFFACENAME_AUTO);
655720d2c4d2Smrg	    TRACE(("will allow runtime switch to render_font using \"%s\"\n",
655820d2c4d2Smrg		   wnew->misc.face_name));
655920d2c4d2Smrg	} else {
656020d2c4d2Smrg	    wnew->misc.render_font = erTrue;
656120d2c4d2Smrg	    TRACE(("initially using TrueType font\n"));
656220d2c4d2Smrg	}
656320d2c4d2Smrg    }
6564d522f475Smrg    /* minor tweak to make debug traces consistent: */
6565d522f475Smrg    if (wnew->misc.render_font) {
656620d2c4d2Smrg	if (IsEmpty(wnew->misc.face_name)) {
6567d522f475Smrg	    wnew->misc.render_font = False;
6568d522f475Smrg	    TRACE(("reset render_font since there is no face_name\n"));
6569d522f475Smrg	}
6570d522f475Smrg    }
6571d522f475Smrg#endif
6572d522f475Smrg
657320d2c4d2Smrg#if OPT_WIDE_CHARS
657420d2c4d2Smrg    VTInitialize_locale(request);
657520d2c4d2Smrg    init_Bres(screen.utf8_latin1);
657620d2c4d2Smrg    init_Bres(screen.utf8_title);
657720d2c4d2Smrg
657820d2c4d2Smrg#if OPT_LUIT_PROG
657920d2c4d2Smrg    init_Bres(misc.callfilter);
658020d2c4d2Smrg    init_Bres(misc.use_encoding);
658120d2c4d2Smrg    init_Sres(misc.locale_str);
658220d2c4d2Smrg    init_Sres(misc.localefilter);
658320d2c4d2Smrg#endif
658420d2c4d2Smrg
6585d522f475Smrg    init_Ires(screen.utf8_inparse);
6586d522f475Smrg    init_Ires(screen.utf8_mode);
6587d522f475Smrg    init_Ires(screen.max_combining);
6588d522f475Smrg
658920d2c4d2Smrg    if (TScreenOf(wnew)->max_combining < 0) {
659020d2c4d2Smrg	TScreenOf(wnew)->max_combining = 0;
6591d522f475Smrg    }
659220d2c4d2Smrg    if (TScreenOf(wnew)->max_combining > 5) {
659320d2c4d2Smrg	TScreenOf(wnew)->max_combining = 5;
6594d522f475Smrg    }
6595d522f475Smrg
6596d522f475Smrg    init_Bres(screen.vt100_graphics);
6597d522f475Smrg    init_Bres(screen.wide_chars);
6598d522f475Smrg    init_Bres(misc.mk_width);
6599d522f475Smrg    init_Bres(misc.cjk_width);
6600d522f475Smrg
6601d522f475Smrg    init_Ires(misc.mk_samplesize);
6602d522f475Smrg    init_Ires(misc.mk_samplepass);
6603d522f475Smrg
6604d522f475Smrg    if (wnew->misc.mk_samplesize > 0xffff)
6605d522f475Smrg	wnew->misc.mk_samplesize = 0xffff;
6606d522f475Smrg    if (wnew->misc.mk_samplesize < 0)
6607d522f475Smrg	wnew->misc.mk_samplesize = 0;
6608d522f475Smrg
6609d522f475Smrg    if (wnew->misc.mk_samplepass > wnew->misc.mk_samplesize)
6610d522f475Smrg	wnew->misc.mk_samplepass = wnew->misc.mk_samplesize;
6611d522f475Smrg    if (wnew->misc.mk_samplepass < 0)
6612d522f475Smrg	wnew->misc.mk_samplepass = 0;
6613d522f475Smrg
661420d2c4d2Smrg    if (TScreenOf(request)->utf8_mode) {
6615d522f475Smrg	TRACE(("setting wide_chars on\n"));
661620d2c4d2Smrg	TScreenOf(wnew)->wide_chars = True;
6617d522f475Smrg    } else {
6618d522f475Smrg	TRACE(("setting utf8_mode to 0\n"));
661920d2c4d2Smrg	TScreenOf(wnew)->utf8_mode = uFalse;
6620d522f475Smrg    }
662120d2c4d2Smrg    TRACE(("initialized UTF-8 mode to %d\n", TScreenOf(wnew)->utf8_mode));
6622d522f475Smrg
6623d522f475Smrg#if OPT_MINI_LUIT
662420d2c4d2Smrg    if (TScreenOf(request)->latin9_mode) {
662520d2c4d2Smrg	TScreenOf(wnew)->latin9_mode = True;
6626d522f475Smrg    }
662720d2c4d2Smrg    if (TScreenOf(request)->unicode_font) {
662820d2c4d2Smrg	TScreenOf(wnew)->unicode_font = True;
6629d522f475Smrg    }
663020d2c4d2Smrg    TRACE(("initialized Latin9 mode to %d\n", TScreenOf(wnew)->latin9_mode));
663120d2c4d2Smrg    TRACE(("initialized unicode_font to %d\n", TScreenOf(wnew)->unicode_font));
6632d522f475Smrg#endif
6633d522f475Smrg
663420d2c4d2Smrg    decode_wcwidth(wnew);
6635d522f475Smrg#endif /* OPT_WIDE_CHARS */
6636d522f475Smrg
6637d522f475Smrg    init_Bres(screen.always_bold_mode);
6638d522f475Smrg    init_Bres(screen.bold_mode);
6639d522f475Smrg    init_Bres(screen.underline);
6640d522f475Smrg
6641d522f475Smrg    wnew->cur_foreground = 0;
6642d522f475Smrg    wnew->cur_background = 0;
6643d522f475Smrg
6644d522f475Smrg    wnew->keyboard.flags = MODE_SRM;
664520d2c4d2Smrg    if (TScreenOf(wnew)->backarrow_key)
6646d522f475Smrg	wnew->keyboard.flags |= MODE_DECBKM;
6647d522f475Smrg    TRACE(("initialized DECBKM %s\n",
6648d522f475Smrg	   BtoS(wnew->keyboard.flags & MODE_DECBKM)));
6649d522f475Smrg
6650d522f475Smrg    /* look for focus related events on the shell, because we need
6651d522f475Smrg     * to care about the shell's border being part of our focus.
6652d522f475Smrg     */
665320d2c4d2Smrg    TRACE(("adding event handlers for my_parent %p\n", (void *) my_parent));
6654d522f475Smrg    XtAddEventHandler(my_parent, EnterWindowMask, False,
6655d522f475Smrg		      HandleEnterWindow, (Opaque) NULL);
6656d522f475Smrg    XtAddEventHandler(my_parent, LeaveWindowMask, False,
6657d522f475Smrg		      HandleLeaveWindow, (Opaque) NULL);
6658d522f475Smrg    XtAddEventHandler(my_parent, FocusChangeMask, False,
6659d522f475Smrg		      HandleFocusChange, (Opaque) NULL);
6660d522f475Smrg    XtAddEventHandler((Widget) wnew, 0L, True,
6661d522f475Smrg		      VTNonMaskableEvent, (Opaque) NULL);
6662d522f475Smrg    XtAddEventHandler((Widget) wnew, PropertyChangeMask, False,
6663d522f475Smrg		      HandleBellPropertyChange, (Opaque) NULL);
6664d522f475Smrg
6665d522f475Smrg#if HANDLE_STRUCT_NOTIFY
6666d522f475Smrg#if OPT_TOOLBAR
6667d522f475Smrg    wnew->VT100_TB_INFO(menu_bar) = request->VT100_TB_INFO(menu_bar);
6668d522f475Smrg    init_Ires(VT100_TB_INFO(menu_height));
6669d522f475Smrg#else
6670d522f475Smrg    /* Flag icon name with "***"  on window output when iconified.
6671d522f475Smrg     * Put in a handler that will tell us when we get Map/Unmap events.
6672d522f475Smrg     */
6673d522f475Smrg    if (resource.zIconBeep)
6674d522f475Smrg#endif
6675d522f475Smrg	XtAddEventHandler(my_parent, StructureNotifyMask, False,
6676d522f475Smrg			  HandleStructNotify, (Opaque) 0);
6677d522f475Smrg#endif /* HANDLE_STRUCT_NOTIFY */
6678d522f475Smrg
667920d2c4d2Smrg    TScreenOf(wnew)->bellInProgress = False;
6680d522f475Smrg
668120d2c4d2Smrg    set_character_class(TScreenOf(wnew)->charClass);
6682d522f475Smrg
6683d522f475Smrg    /* create it, but don't realize it */
6684956cc18dSsnj    ScrollBarOn(wnew, True);
6685d522f475Smrg
6686d522f475Smrg    /* make sure that the resize gravity acceptable */
6687956cc18dSsnj    if (!GravityIsNorthWest(wnew) &&
6688956cc18dSsnj	!GravityIsSouthWest(wnew)) {
6689d522f475Smrg	char value[80];
669020d2c4d2Smrg	String temp[2];
6691d522f475Smrg	Cardinal nparams = 1;
6692d522f475Smrg
669320d2c4d2Smrg	sprintf(value, "%d", wnew->misc.resizeGravity);
669420d2c4d2Smrg	temp[0] = value;
6695d522f475Smrg	temp[1] = 0;
6696d522f475Smrg	XtAppWarningMsg(app_con, "rangeError", "resizeGravity", "XTermError",
6697d522f475Smrg			"unsupported resizeGravity resource value (%s)",
6698d522f475Smrg			temp, &nparams);
6699d522f475Smrg	wnew->misc.resizeGravity = SouthWestGravity;
6700d522f475Smrg    }
6701d522f475Smrg#ifndef NO_ACTIVE_ICON
670220d2c4d2Smrg    TScreenOf(wnew)->whichVwin = &TScreenOf(wnew)->fullVwin;
6703d522f475Smrg#endif /* NO_ACTIVE_ICON */
6704d522f475Smrg
670520d2c4d2Smrg    if (TScreenOf(wnew)->savelines < 0)
670620d2c4d2Smrg	TScreenOf(wnew)->savelines = 0;
6707d522f475Smrg
6708d522f475Smrg    init_Bres(screen.awaitInput);
6709d522f475Smrg
6710d522f475Smrg    wnew->flags = 0;
671120d2c4d2Smrg    if (!TScreenOf(wnew)->jumpscroll)
6712d522f475Smrg	wnew->flags |= SMOOTHSCROLL;
6713d522f475Smrg    if (wnew->misc.reverseWrap)
6714d522f475Smrg	wnew->flags |= REVERSEWRAP;
6715d522f475Smrg    if (wnew->misc.autoWrap)
6716d522f475Smrg	wnew->flags |= WRAPAROUND;
6717d522f475Smrg    if (wnew->misc.re_verse != wnew->misc.re_verse0)
6718d522f475Smrg	wnew->flags |= REVERSE_VIDEO;
671920d2c4d2Smrg    if (TScreenOf(wnew)->c132)
6720d522f475Smrg	wnew->flags |= IN132COLUMNS;
6721d522f475Smrg
6722d522f475Smrg    wnew->initflags = wnew->flags;
6723d522f475Smrg
6724d522f475Smrg#if OPT_MOD_FKEYS
6725d522f475Smrg    init_Ires(keyboard.modify_1st.cursor_keys);
6726d522f475Smrg    init_Ires(keyboard.modify_1st.function_keys);
6727d522f475Smrg    init_Ires(keyboard.modify_1st.keypad_keys);
6728d522f475Smrg    init_Ires(keyboard.modify_1st.other_keys);
6729d522f475Smrg    init_Ires(keyboard.modify_1st.string_keys);
6730d522f475Smrg    init_Ires(keyboard.format_keys);
6731d522f475Smrg    wnew->keyboard.modify_now = wnew->keyboard.modify_1st;
6732d522f475Smrg#endif
6733d522f475Smrg
6734d522f475Smrg    init_Ires(misc.appcursorDefault);
6735d522f475Smrg    if (wnew->misc.appcursorDefault)
6736d522f475Smrg	wnew->keyboard.flags |= MODE_DECCKM;
6737d522f475Smrg
6738d522f475Smrg    init_Ires(misc.appkeypadDefault);
6739d522f475Smrg    if (wnew->misc.appkeypadDefault)
6740d522f475Smrg	wnew->keyboard.flags |= MODE_DECKPAM;
6741d522f475Smrg
6742956cc18dSsnj    initLineData(wnew);
6743d522f475Smrg    return;
6744d522f475Smrg}
6745d522f475Smrg
6746d522f475Smrgvoid
6747d522f475SmrgreleaseCursorGCs(XtermWidget xw)
6748d522f475Smrg{
674920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6750d522f475Smrg    VTwin *win = WhichVWin(screen);
6751d522f475Smrg    int n;
6752d522f475Smrg
6753d522f475Smrg    for_each_curs_gc(n) {
6754d522f475Smrg	freeCgs(xw, win, (CgsEnum) n);
6755d522f475Smrg    }
6756d522f475Smrg}
6757d522f475Smrg
6758d522f475Smrgvoid
6759d522f475SmrgreleaseWindowGCs(XtermWidget xw, VTwin * win)
6760d522f475Smrg{
6761d522f475Smrg    int n;
6762d522f475Smrg
6763d522f475Smrg    for_each_text_gc(n) {
6764d522f475Smrg	freeCgs(xw, win, (CgsEnum) n);
6765d522f475Smrg    }
6766d522f475Smrg}
6767d522f475Smrg
6768d522f475Smrg#define TRACE_FREE_LEAK(name) \
6769d522f475Smrg	if (name) { \
677020d2c4d2Smrg	    free((void *) name); \
6771d522f475Smrg	    name = 0; \
6772d522f475Smrg	    TRACE(("freed " #name "\n")); \
6773d522f475Smrg	}
6774d522f475Smrg
6775d522f475Smrg#define FREE_LEAK(name) \
6776d522f475Smrg	if (name) { \
677720d2c4d2Smrg	    free((void *) name); \
6778d522f475Smrg	    name = 0; \
6779d522f475Smrg	}
6780d522f475Smrg
6781956cc18dSsnj#if OPT_INPUT_METHOD
6782956cc18dSsnjstatic void
6783956cc18dSsnjcleanupInputMethod(TScreen * screen)
6784956cc18dSsnj{
6785956cc18dSsnj    if (screen->xim) {
6786956cc18dSsnj	XCloseIM(screen->xim);
6787956cc18dSsnj	screen->xim = 0;
6788956cc18dSsnj	TRACE(("freed screen->xim\n"));
6789956cc18dSsnj    }
6790956cc18dSsnj}
6791956cc18dSsnj#endif
6792956cc18dSsnj
6793d522f475Smrgstatic void
6794d522f475SmrgVTDestroy(Widget w GCC_UNUSED)
6795d522f475Smrg{
6796d522f475Smrg#ifdef NO_LEAKS
6797d522f475Smrg    XtermWidget xw = (XtermWidget) w;
679820d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6799d522f475Smrg    Cardinal n;
6800d522f475Smrg
6801d522f475Smrg    StopBlinking(screen);
6802d522f475Smrg
68032eaa94a1Schristos    if (screen->scrollWidget) {
68042eaa94a1Schristos	XtUninstallTranslations(screen->scrollWidget);
6805d522f475Smrg	XtDestroyWidget(screen->scrollWidget);
68062eaa94a1Schristos    }
6807956cc18dSsnj#if OPT_FIFO_LINES
6808956cc18dSsnj    while (screen->saved_fifo-- > 0) {
6809956cc18dSsnj	deleteScrollback(screen, 0);
6810956cc18dSsnj    }
6811956cc18dSsnj#endif
681220d2c4d2Smrg    while (screen->save_title != 0) {
681320d2c4d2Smrg	SaveTitle *last = screen->save_title;
681420d2c4d2Smrg	screen->save_title = last->next;
681520d2c4d2Smrg	free(last->iconName);
681620d2c4d2Smrg	free(last->windowName);
681720d2c4d2Smrg	free(last);
681820d2c4d2Smrg    }
6819d522f475Smrg    TRACE_FREE_LEAK(screen->save_ptr);
6820956cc18dSsnj    TRACE_FREE_LEAK(screen->saveBuf_data);
6821956cc18dSsnj    TRACE_FREE_LEAK(screen->saveBuf_index);
6822956cc18dSsnj    for (n = 0; n < 2; ++n) {
6823956cc18dSsnj	TRACE_FREE_LEAK(screen->editBuf_data[n]);
6824956cc18dSsnj	TRACE_FREE_LEAK(screen->editBuf_index[n]);
6825956cc18dSsnj    }
6826d522f475Smrg    TRACE_FREE_LEAK(screen->keyboard_dialect);
6827d522f475Smrg    TRACE_FREE_LEAK(screen->term_id);
6828d522f475Smrg#if OPT_WIDE_CHARS
6829d522f475Smrg#if OPT_LUIT_PROG
6830d522f475Smrg    TRACE_FREE_LEAK(xw->misc.locale_str);
6831d522f475Smrg    TRACE_FREE_LEAK(xw->misc.localefilter);
6832d522f475Smrg#endif
6833d522f475Smrg#endif
6834d522f475Smrg#if OPT_INPUT_METHOD
6835956cc18dSsnj    cleanupInputMethod(screen);
6836d522f475Smrg#endif
6837d522f475Smrg    releaseCursorGCs(xw);
6838d522f475Smrg    releaseWindowGCs(xw, &(screen->fullVwin));
6839d522f475Smrg#ifndef NO_ACTIVE_ICON
6840d522f475Smrg    releaseWindowGCs(xw, &(screen->iconVwin));
6841d522f475Smrg#endif
68422eaa94a1Schristos    XtUninstallTranslations((Widget) xw);
68432eaa94a1Schristos#if OPT_TOOLBAR
68442eaa94a1Schristos    XtUninstallTranslations((Widget) XtParent(xw));
68452eaa94a1Schristos#endif
68462eaa94a1Schristos    XtUninstallTranslations((Widget) SHELL_OF(xw));
6847d522f475Smrg
6848d522f475Smrg    if (screen->hidden_cursor)
6849d522f475Smrg	XFreeCursor(screen->display, screen->hidden_cursor);
6850d522f475Smrg
6851d522f475Smrg    xtermCloseFonts(xw, screen->fnts);
6852d522f475Smrg    noleaks_cachedCgs(xw);
6853d522f475Smrg
6854d522f475Smrg#if OPT_RENDERFONT
6855d522f475Smrg    for (n = 0; n < NMENUFONTS; ++n) {
6856d522f475Smrg	xtermCloseXft(screen, &(screen->renderFontNorm[n]));
6857d522f475Smrg	xtermCloseXft(screen, &(screen->renderFontBold[n]));
6858d522f475Smrg	xtermCloseXft(screen, &(screen->renderFontItal[n]));
6859956cc18dSsnj#if OPT_RENDERWIDE
6860d522f475Smrg	xtermCloseXft(screen, &(screen->renderWideNorm[n]));
6861d522f475Smrg	xtermCloseXft(screen, &(screen->renderWideBold[n]));
6862d522f475Smrg	xtermCloseXft(screen, &(screen->renderWideItal[n]));
6863956cc18dSsnj#endif
6864d522f475Smrg    }
6865d522f475Smrg#endif
6866d522f475Smrg
686720d2c4d2Smrg    /* free things allocated via init_Sres or Init_Sres2 */
686820d2c4d2Smrg#ifdef ALLOWLOGGING
686920d2c4d2Smrg    TRACE_FREE_LEAK(screen->logfile);
6870d522f475Smrg#endif
687120d2c4d2Smrg    TRACE_FREE_LEAK(screen->term_id);
687220d2c4d2Smrg    TRACE_FREE_LEAK(screen->charClass);
687320d2c4d2Smrg    TRACE_FREE_LEAK(screen->answer_back);
687420d2c4d2Smrg    TRACE_FREE_LEAK(screen->printer_command);
687520d2c4d2Smrg    TRACE_FREE_LEAK(screen->keyboard_dialect);
687620d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedColorOps);
687720d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedFontOps);
687820d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedTcapOps);
687920d2c4d2Smrg    TRACE_FREE_LEAK(screen->disallowedWinOps);
688020d2c4d2Smrg    TRACE_FREE_LEAK(screen->default_string);
688120d2c4d2Smrg    TRACE_FREE_LEAK(screen->eightbit_select_types);
688220d2c4d2Smrg#if OPT_WIDE_CHARS
688320d2c4d2Smrg    TRACE_FREE_LEAK(screen->utf8_select_types);
688420d2c4d2Smrg#endif
688520d2c4d2Smrg#if 0
688620d2c4d2Smrg    for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; n++) {
688720d2c4d2Smrg	TRACE_FREE_LEAK(screen->MenuFontName(n));
6888d522f475Smrg    }
6889d522f475Smrg#endif
689020d2c4d2Smrg    TRACE_FREE_LEAK(screen->initial_font);
689120d2c4d2Smrg#if OPT_LUIT_PROG
689220d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.locale_str);
689320d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.localefilter);
689420d2c4d2Smrg#endif
689520d2c4d2Smrg#if OPT_RENDERFONT
689620d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.face_name);
689720d2c4d2Smrg    TRACE_FREE_LEAK(xw->misc.face_wide_name);
689820d2c4d2Smrg#endif
689920d2c4d2Smrg
6900d522f475Smrg#if OPT_SELECT_REGEX
6901d522f475Smrg    for (n = 0; n < NSELECTUNITS; ++n) {
6902d522f475Smrg	FREE_LEAK(screen->selectExpr[n]);
6903d522f475Smrg    }
6904d522f475Smrg#endif
6905d522f475Smrg
6906d522f475Smrg    if (screen->selection_atoms)
6907d522f475Smrg	XtFree((char *) (screen->selection_atoms));
6908d522f475Smrg
6909d522f475Smrg    XtFree((char *) (screen->selection_data));
6910d522f475Smrg
6911d522f475Smrg    TRACE_FREE_LEAK(xw->keyboard.extra_translations);
6912d522f475Smrg    TRACE_FREE_LEAK(xw->keyboard.shell_translations);
6913d522f475Smrg    TRACE_FREE_LEAK(xw->keyboard.xterm_translations);
6914956cc18dSsnj
6915956cc18dSsnj#if OPT_WIDE_CHARS
6916956cc18dSsnj    FreeTypedBuffer(XChar2b);
6917956cc18dSsnj    FreeTypedBuffer(char);
6918956cc18dSsnj#endif
6919956cc18dSsnj#if OPT_RENDERFONT
6920956cc18dSsnj#if OPT_RENDERWIDE
6921956cc18dSsnj    FreeTypedBuffer(XftCharSpec);
6922956cc18dSsnj#else
6923956cc18dSsnj    FreeTypedBuffer(XftChar8);
6924956cc18dSsnj#endif
6925956cc18dSsnj#endif
6926956cc18dSsnj
6927956cc18dSsnj    TRACE_FREE_LEAK(myState.print_area);
6928956cc18dSsnj    TRACE_FREE_LEAK(myState.string_area);
6929956cc18dSsnj    memset(&myState, 0, sizeof(myState));
6930956cc18dSsnj
6931d522f475Smrg#endif /* defined(NO_LEAKS) */
6932d522f475Smrg}
6933d522f475Smrg
6934d522f475Smrg/*ARGSUSED*/
6935d522f475Smrgstatic void
6936d522f475SmrgVTRealize(Widget w,
6937d522f475Smrg	  XtValueMask * valuemask,
6938d522f475Smrg	  XSetWindowAttributes * values)
6939d522f475Smrg{
6940d522f475Smrg    XtermWidget xw = (XtermWidget) w;
694120d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
6942d522f475Smrg
6943d522f475Smrg    const VTFontNames *myfont;
6944d522f475Smrg    unsigned width, height;
6945d522f475Smrg    int xpos, ypos, pr;
6946d522f475Smrg    Atom pid_atom;
6947d522f475Smrg    int i;
6948d522f475Smrg
6949d522f475Smrg    TRACE(("VTRealize\n"));
6950d522f475Smrg
6951d522f475Smrg    TabReset(xw->tabs);
6952d522f475Smrg
6953d522f475Smrg    if (screen->menu_font_number == fontMenu_default) {
6954d522f475Smrg	myfont = &(xw->misc.default_font);
6955d522f475Smrg    } else {
6956d522f475Smrg	myfont = xtermFontName(screen->MenuFontName(screen->menu_font_number));
6957d522f475Smrg    }
6958d522f475Smrg    memset(screen->fnts, 0, sizeof(screen->fnts));
6959d522f475Smrg
6960d522f475Smrg    if (!xtermLoadFont(xw,
6961d522f475Smrg		       myfont,
6962d522f475Smrg		       False,
6963d522f475Smrg		       screen->menu_font_number)) {
6964d522f475Smrg	if (XmuCompareISOLatin1(myfont->f_n, DEFFONT) != 0) {
696520d2c4d2Smrg	    char *use_font = x_strdup(DEFFONT);
6966d522f475Smrg	    fprintf(stderr,
6967d522f475Smrg		    "%s:  unable to open font \"%s\", trying \"%s\"....\n",
696820d2c4d2Smrg		    xterm_name, myfont->f_n, use_font);
6969d522f475Smrg	    (void) xtermLoadFont(xw,
697020d2c4d2Smrg				 xtermFontName(use_font),
6971d522f475Smrg				 False,
6972d522f475Smrg				 screen->menu_font_number);
697320d2c4d2Smrg	    screen->MenuFontName(screen->menu_font_number) = use_font;
6974d522f475Smrg	}
6975d522f475Smrg    }
6976d522f475Smrg
6977d522f475Smrg    /* really screwed if we couldn't open default font */
6978d522f475Smrg    if (!screen->fnts[fNorm].fs) {
6979d522f475Smrg	fprintf(stderr, "%s:  unable to locate a suitable font\n",
6980d522f475Smrg		xterm_name);
6981d522f475Smrg	Exit(1);
6982d522f475Smrg    }
6983d522f475Smrg#if OPT_WIDE_CHARS
698420d2c4d2Smrg    if (TScreenOf(xw)->utf8_mode) {
6985d522f475Smrg	TRACE(("check if this is a wide font, if not try again\n"));
6986d522f475Smrg	if (xtermLoadWideFonts(xw, False))
6987d522f475Smrg	    SetVTFont(xw, screen->menu_font_number, True, NULL);
6988d522f475Smrg    }
6989d522f475Smrg#endif
6990d522f475Smrg
6991d522f475Smrg    /* making cursor */
6992d522f475Smrg    if (!screen->pointer_cursor) {
6993d522f475Smrg	screen->pointer_cursor =
6994d522f475Smrg	    make_colored_cursor(XC_xterm,
6995d522f475Smrg				T_COLOR(screen, MOUSE_FG),
6996d522f475Smrg				T_COLOR(screen, MOUSE_BG));
6997d522f475Smrg    } else {
6998d522f475Smrg	recolor_cursor(screen,
6999d522f475Smrg		       screen->pointer_cursor,
7000d522f475Smrg		       T_COLOR(screen, MOUSE_FG),
7001d522f475Smrg		       T_COLOR(screen, MOUSE_BG));
7002d522f475Smrg    }
7003d522f475Smrg
7004d522f475Smrg    /* set defaults */
7005d522f475Smrg    xpos = 1;
7006d522f475Smrg    ypos = 1;
7007d522f475Smrg    width = 80;
7008d522f475Smrg    height = 24;
7009d522f475Smrg
7010d522f475Smrg    TRACE(("parsing geo_metry %s\n", NonNull(xw->misc.geo_metry)));
7011d522f475Smrg    pr = XParseGeometry(xw->misc.geo_metry, &xpos, &ypos,
7012d522f475Smrg			&width, &height);
7013d522f475Smrg    TRACE(("... position %d,%d size %dx%d\n", ypos, xpos, height, width));
7014d522f475Smrg
7015d522f475Smrg    set_max_col(screen, (int) (width - 1));	/* units in character cells */
7016d522f475Smrg    set_max_row(screen, (int) (height - 1));	/* units in character cells */
7017d522f475Smrg    xtermUpdateFontInfo(xw, False);
7018d522f475Smrg
7019d522f475Smrg    width = screen->fullVwin.fullwidth;
7020d522f475Smrg    height = screen->fullVwin.fullheight;
7021d522f475Smrg
7022d522f475Smrg    TRACE(("... border widget %d parent %d shell %d\n",
7023d522f475Smrg	   BorderWidth(xw),
7024d522f475Smrg	   BorderWidth(XtParent(xw)),
7025d522f475Smrg	   BorderWidth(SHELL_OF(xw))));
7026d522f475Smrg
7027d522f475Smrg    if ((pr & XValue) && (XNegative & pr)) {
70282eaa94a1Schristos	xpos += (DisplayWidth(screen->display, DefaultScreen(screen->display))
70292eaa94a1Schristos		 - (int) width
70302eaa94a1Schristos		 - (BorderWidth(XtParent(xw)) * 2));
7031d522f475Smrg    }
7032d522f475Smrg    if ((pr & YValue) && (YNegative & pr)) {
70332eaa94a1Schristos	ypos += (DisplayHeight(screen->display, DefaultScreen(screen->display))
70342eaa94a1Schristos		 - (int) height
70352eaa94a1Schristos		 - (BorderWidth(XtParent(xw)) * 2));
7036d522f475Smrg    }
7037d522f475Smrg
7038d522f475Smrg    /* set up size hints for window manager; min 1 char by 1 char */
7039d522f475Smrg    getXtermSizeHints(xw);
7040d522f475Smrg    xtermSizeHints(xw, (xw->misc.scrollbar
7041d522f475Smrg			? (screen->scrollWidget->core.width
7042d522f475Smrg			   + BorderWidth(screen->scrollWidget))
7043d522f475Smrg			: 0));
7044d522f475Smrg
7045d522f475Smrg    xw->hints.x = xpos;
7046d522f475Smrg    xw->hints.y = ypos;
7047d522f475Smrg    if ((XValue & pr) || (YValue & pr)) {
7048d522f475Smrg	xw->hints.flags |= USSize | USPosition;
7049d522f475Smrg	xw->hints.flags |= PWinGravity;
7050d522f475Smrg	switch (pr & (XNegative | YNegative)) {
7051d522f475Smrg	case 0:
7052d522f475Smrg	    xw->hints.win_gravity = NorthWestGravity;
7053d522f475Smrg	    break;
7054d522f475Smrg	case XNegative:
7055d522f475Smrg	    xw->hints.win_gravity = NorthEastGravity;
7056d522f475Smrg	    break;
7057d522f475Smrg	case YNegative:
7058d522f475Smrg	    xw->hints.win_gravity = SouthWestGravity;
7059d522f475Smrg	    break;
7060d522f475Smrg	default:
7061d522f475Smrg	    xw->hints.win_gravity = SouthEastGravity;
7062d522f475Smrg	    break;
7063d522f475Smrg	}
7064d522f475Smrg    } else {
7065d522f475Smrg	/* set a default size, but do *not* set position */
7066d522f475Smrg	xw->hints.flags |= PSize;
7067d522f475Smrg    }
7068d522f475Smrg    xw->hints.height = xw->hints.base_height
7069d522f475Smrg	+ xw->hints.height_inc * MaxRows(screen);
7070d522f475Smrg    xw->hints.width = xw->hints.base_width
7071d522f475Smrg	+ xw->hints.width_inc * MaxCols(screen);
7072d522f475Smrg
7073d522f475Smrg    if ((WidthValue & pr) || (HeightValue & pr))
7074d522f475Smrg	xw->hints.flags |= USSize;
7075d522f475Smrg    else
7076d522f475Smrg	xw->hints.flags |= PSize;
7077d522f475Smrg
7078d522f475Smrg    /*
7079d522f475Smrg     * Note that the size-hints are for the shell, while the resize-request
7080d522f475Smrg     * is for the vt100 widget.  They are not the same size.
7081d522f475Smrg     */
70822eaa94a1Schristos    (void) REQ_RESIZE((Widget) xw,
70832eaa94a1Schristos		      (Dimension) width, (Dimension) height,
70842eaa94a1Schristos		      &xw->core.width, &xw->core.height);
7085d522f475Smrg
7086d522f475Smrg    /* XXX This is bogus.  We are parsing geometries too late.  This
7087d522f475Smrg     * is information that the shell widget ought to have before we get
7088d522f475Smrg     * realized, so that it can do the right thing.
7089d522f475Smrg     */
7090d522f475Smrg    if (xw->hints.flags & USPosition)
7091d522f475Smrg	XMoveWindow(XtDisplay(xw), XtWindow(SHELL_OF(xw)),
7092d522f475Smrg		    xw->hints.x, xw->hints.y);
7093d522f475Smrg
7094d522f475Smrg    TRACE(("%s@%d -- ", __FILE__, __LINE__));
7095d522f475Smrg    TRACE_HINTS(&xw->hints);
7096d522f475Smrg    XSetWMNormalHints(XtDisplay(xw), XtWindow(SHELL_OF(xw)), &xw->hints);
7097d522f475Smrg    TRACE(("%s@%d -- ", __FILE__, __LINE__));
7098d522f475Smrg    TRACE_WM_HINTS(xw);
7099d522f475Smrg
7100d522f475Smrg    if ((pid_atom = XInternAtom(XtDisplay(xw), "_NET_WM_PID", False)) != None) {
7101d522f475Smrg	/* XChangeProperty format 32 really is "long" */
7102d522f475Smrg	unsigned long pid_l = (unsigned long) getpid();
7103d522f475Smrg	TRACE(("Setting _NET_WM_PID property to %lu\n", pid_l));
7104d522f475Smrg	XChangeProperty(XtDisplay(xw), VShellWindow,
7105d522f475Smrg			pid_atom, XA_CARDINAL, 32, PropModeReplace,
7106d522f475Smrg			(unsigned char *) &pid_l, 1);
7107d522f475Smrg    }
7108d522f475Smrg
7109d522f475Smrg    XFlush(XtDisplay(xw));	/* get it out to window manager */
7110d522f475Smrg
7111d522f475Smrg    /* use ForgetGravity instead of SouthWestGravity because translating
7112d522f475Smrg       the Expose events for ConfigureNotifys is too hard */
7113956cc18dSsnj    values->bit_gravity = (GravityIsNorthWest(xw)
7114d522f475Smrg			   ? NorthWestGravity
7115d522f475Smrg			   : ForgetGravity);
711620d2c4d2Smrg    TScreenOf(xw)->fullVwin.window = XtWindow(xw) =
7117d522f475Smrg	XCreateWindow(XtDisplay(xw), XtWindow(XtParent(xw)),
7118d522f475Smrg		      xw->core.x, xw->core.y,
7119d522f475Smrg		      xw->core.width, xw->core.height, BorderWidth(xw),
7120d522f475Smrg		      (int) xw->core.depth,
7121d522f475Smrg		      InputOutput, CopyFromParent,
7122d522f475Smrg		      *valuemask | CWBitGravity, values);
7123d522f475Smrg    screen->event_mask = values->event_mask;
7124d522f475Smrg
7125d522f475Smrg#ifndef NO_ACTIVE_ICON
7126d522f475Smrg    if (xw->misc.active_icon && screen->fnt_icon.fs) {
7127d522f475Smrg	int iconX = 0, iconY = 0;
7128d522f475Smrg	Widget shell = SHELL_OF(xw);
7129d522f475Smrg	VTwin *win = &(screen->iconVwin);
7130d522f475Smrg
7131d522f475Smrg	TRACE(("Initializing active-icon\n"));
7132d522f475Smrg	XtVaGetValues(shell, XtNiconX, &iconX, XtNiconY, &iconY, (XtPointer) 0);
7133d522f475Smrg	xtermComputeFontInfo(xw, &(screen->iconVwin), screen->fnt_icon.fs, 0);
7134d522f475Smrg
7135d522f475Smrg	/* since only one client is permitted to select for Button
7136d522f475Smrg	 * events, we have to let the window manager get 'em...
7137d522f475Smrg	 */
7138d522f475Smrg	values->event_mask &= ~(ButtonPressMask | ButtonReleaseMask);
7139d522f475Smrg	values->border_pixel = xw->misc.icon_border_pixel;
7140d522f475Smrg
7141d522f475Smrg	screen->iconVwin.window =
7142d522f475Smrg	    XCreateWindow(XtDisplay(xw),
7143d522f475Smrg			  RootWindowOfScreen(XtScreen(shell)),
7144d522f475Smrg			  iconX, iconY,
7145d522f475Smrg			  screen->iconVwin.fullwidth,
7146d522f475Smrg			  screen->iconVwin.fullheight,
7147d522f475Smrg			  xw->misc.icon_border_width,
7148d522f475Smrg			  (int) xw->core.depth,
7149d522f475Smrg			  InputOutput, CopyFromParent,
7150d522f475Smrg			  *valuemask | CWBitGravity | CWBorderPixel,
7151d522f475Smrg			  values);
7152d522f475Smrg	XtVaSetValues(shell,
7153d522f475Smrg		      XtNiconWindow, screen->iconVwin.window,
7154d522f475Smrg		      (XtPointer) 0);
7155d522f475Smrg	XtRegisterDrawable(XtDisplay(xw), screen->iconVwin.window, w);
7156d522f475Smrg
7157d522f475Smrg	setCgsFont(xw, win, gcNorm, &(screen->fnt_icon));
7158d522f475Smrg	setCgsFore(xw, win, gcNorm, T_COLOR(screen, TEXT_FG));
7159d522f475Smrg	setCgsBack(xw, win, gcNorm, T_COLOR(screen, TEXT_BG));
7160d522f475Smrg
7161d522f475Smrg	copyCgs(xw, win, gcBold, gcNorm);
7162d522f475Smrg
7163d522f475Smrg	setCgsFont(xw, win, gcNormReverse, &(screen->fnt_icon));
7164d522f475Smrg	setCgsFore(xw, win, gcNormReverse, T_COLOR(screen, TEXT_BG));
7165d522f475Smrg	setCgsBack(xw, win, gcNormReverse, T_COLOR(screen, TEXT_FG));
7166d522f475Smrg
7167d522f475Smrg	copyCgs(xw, win, gcBoldReverse, gcNormReverse);
7168d522f475Smrg
7169d522f475Smrg#if OPT_TOOLBAR
7170d522f475Smrg	/*
7171d522f475Smrg	 * Toolbar is initialized before we get here.  Enable the menu item
7172d522f475Smrg	 * and set it properly.
7173d522f475Smrg	 */
7174d522f475Smrg	SetItemSensitivity(vtMenuEntries[vtMenu_activeicon].widget, True);
7175d522f475Smrg	update_activeicon();
7176d522f475Smrg#endif
7177d522f475Smrg    } else {
7178d522f475Smrg	TRACE(("Disabled active-icon\n"));
7179d522f475Smrg	xw->misc.active_icon = False;
7180d522f475Smrg    }
7181d522f475Smrg#endif /* NO_ACTIVE_ICON */
7182d522f475Smrg
7183d522f475Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
7184956cc18dSsnj    VTInitI18N(xw);
7185d522f475Smrg#else
718620d2c4d2Smrg    TScreenOf(xw)->xic = NULL;
7187d522f475Smrg#endif
7188d522f475Smrg#if OPT_NUM_LOCK
7189d522f475Smrg    VTInitModifiers(xw);
7190d522f475Smrg#if OPT_EXTRA_PASTE
7191d522f475Smrg    if (xw->keyboard.extra_translations) {
7192d522f475Smrg	XtOverrideTranslations((Widget) xw,
7193d522f475Smrg			       XtParseTranslationTable(xw->keyboard.extra_translations));
7194d522f475Smrg    }
7195d522f475Smrg#endif
7196d522f475Smrg#endif
7197d522f475Smrg
7198d522f475Smrg    set_cursor_gcs(xw);
7199d522f475Smrg
7200d522f475Smrg    /* Reset variables used by ANSI emulation. */
7201d522f475Smrg
7202d522f475Smrg    resetCharsets(screen);
7203d522f475Smrg
7204d522f475Smrg    XDefineCursor(screen->display, VShellWindow, screen->pointer_cursor);
7205d522f475Smrg
7206d522f475Smrg    set_cur_col(screen, 0);
7207d522f475Smrg    set_cur_row(screen, 0);
7208d522f475Smrg    set_max_col(screen, Width(screen) / screen->fullVwin.f_width - 1);
7209d522f475Smrg    set_max_row(screen, Height(screen) / screen->fullVwin.f_height - 1);
7210d522f475Smrg    set_tb_margins(screen, 0, screen->max_row);
7211d522f475Smrg
7212d522f475Smrg    memset(screen->sc, 0, sizeof(screen->sc));
7213d522f475Smrg
7214d522f475Smrg    /* Mark screen buffer as unallocated.  We wait until the run loop so
7215d522f475Smrg       that the child process does not fork and exec with all the dynamic
7216d522f475Smrg       memory it will never use.  If we were to do it here, the
7217d522f475Smrg       swap space for new process would be huge for huge savelines. */
7218d522f475Smrg#if OPT_TEK4014
7219d522f475Smrg    if (!tekWidget)		/* if not called after fork */
7220d522f475Smrg#endif
7221956cc18dSsnj    {
7222956cc18dSsnj	screen->visbuf = NULL;
7223956cc18dSsnj	screen->saveBuf_index = NULL;
7224956cc18dSsnj    }
7225d522f475Smrg
72262eaa94a1Schristos    screen->do_wrap = False;
7227d522f475Smrg    screen->scrolls = screen->incopy = 0;
7228d522f475Smrg    xtermSetCursorBox(screen);
7229d522f475Smrg
7230d522f475Smrg    screen->savedlines = 0;
7231d522f475Smrg
7232d522f475Smrg    for (i = 0; i < 2; ++i) {
7233956cc18dSsnj	screen->whichBuf = !screen->whichBuf;
7234d522f475Smrg	CursorSave(xw);
7235d522f475Smrg    }
7236d522f475Smrg
7237d522f475Smrg    /*
7238d522f475Smrg     * Do this last, since it may change the layout via a resize.
7239d522f475Smrg     */
7240d522f475Smrg    if (xw->misc.scrollbar) {
7241d522f475Smrg	screen->fullVwin.sb_info.width = 0;
7242956cc18dSsnj	ScrollBarOn(xw, False);
7243d522f475Smrg    }
7244d522f475Smrg    return;
7245d522f475Smrg}
7246d522f475Smrg
7247d522f475Smrg#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
7248d522f475Smrg
7249d522f475Smrg/* limit this feature to recent XFree86 since X11R6.x core dumps */
7250d522f475Smrg#if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && defined(X_HAVE_UTF8_STRING)
7251d522f475Smrg#define USE_XIM_INSTANTIATE_CB
7252d522f475Smrg
7253d522f475Smrgstatic void
7254d522f475Smrgxim_instantiate_cb(Display * display,
7255d522f475Smrg		   XPointer client_data GCC_UNUSED,
7256d522f475Smrg		   XPointer call_data GCC_UNUSED)
7257d522f475Smrg{
7258d522f475Smrg    if (display != XtDisplay(term))
7259d522f475Smrg	return;
7260d522f475Smrg
7261956cc18dSsnj    VTInitI18N(term);
7262d522f475Smrg}
7263d522f475Smrg
7264d522f475Smrgstatic void
7265d522f475Smrgxim_destroy_cb(XIM im GCC_UNUSED,
7266d522f475Smrg	       XPointer client_data GCC_UNUSED,
7267d522f475Smrg	       XPointer call_data GCC_UNUSED)
7268d522f475Smrg{
726920d2c4d2Smrg    TScreenOf(term)->xic = NULL;
7270d522f475Smrg
7271d522f475Smrg    XRegisterIMInstantiateCallback(XtDisplay(term), NULL, NULL, NULL,
7272d522f475Smrg				   xim_instantiate_cb, NULL);
7273d522f475Smrg}
7274d522f475Smrg#endif /* X11R6+ */
7275d522f475Smrg
7276d522f475Smrgstatic void
7277956cc18dSsnjxim_real_init(XtermWidget xw)
7278d522f475Smrg{
7279956cc18dSsnj    TScreen *screen = TScreenOf(xw);
7280d522f475Smrg    unsigned i, j;
7281d522f475Smrg    char *p, *s, *t, *ns, *end, buf[32];
7282d522f475Smrg    XIMStyles *xim_styles;
7283d522f475Smrg    XIMStyle input_style = 0;
7284d522f475Smrg    Bool found;
7285d522f475Smrg    static struct {
728620d2c4d2Smrg	const char *name;
7287d522f475Smrg	unsigned long code;
7288d522f475Smrg    } known_style[] = {
7289d522f475Smrg	{
7290d522f475Smrg	    "OverTheSpot", (XIMPreeditPosition | XIMStatusNothing)
7291d522f475Smrg	},
7292d522f475Smrg	{
7293d522f475Smrg	    "OffTheSpot", (XIMPreeditArea | XIMStatusArea)
7294d522f475Smrg	},
7295d522f475Smrg	{
7296d522f475Smrg	    "Root", (XIMPreeditNothing | XIMStatusNothing)
7297d522f475Smrg	},
7298d522f475Smrg    };
7299d522f475Smrg
7300956cc18dSsnj    screen->xic = NULL;
7301d522f475Smrg
7302956cc18dSsnj    if (xw->misc.cannot_im) {
7303d522f475Smrg	return;
7304d522f475Smrg    }
7305d522f475Smrg
7306956cc18dSsnj    if (!xw->misc.input_method || !*xw->misc.input_method) {
7307d522f475Smrg	if ((p = XSetLocaleModifiers("")) != NULL && *p)
7308956cc18dSsnj	    screen->xim = XOpenIM(XtDisplay(xw), NULL, NULL, NULL);
7309d522f475Smrg    } else {
7310956cc18dSsnj	s = xw->misc.input_method;
731120d2c4d2Smrg	i = 5 + (unsigned) strlen(s);
731220d2c4d2Smrg
7313d522f475Smrg	t = (char *) MyStackAlloc(i, buf);
731420d2c4d2Smrg	if (t == NULL) {
7315d522f475Smrg	    SysError(ERROR_VINIT);
731620d2c4d2Smrg	} else {
7317d522f475Smrg
731820d2c4d2Smrg	    for (ns = s; ns && *s;) {
731920d2c4d2Smrg		while (*s && isspace(CharOf(*s)))
732020d2c4d2Smrg		    s++;
732120d2c4d2Smrg		if (!*s)
7322d522f475Smrg		    break;
732320d2c4d2Smrg		if ((ns = end = strchr(s, ',')) == 0)
732420d2c4d2Smrg		    end = s + strlen(s);
732520d2c4d2Smrg		while ((end != s) && isspace(CharOf(end[-1])))
732620d2c4d2Smrg		    end--;
732720d2c4d2Smrg
732820d2c4d2Smrg		if (end != s) {
732920d2c4d2Smrg		    strcpy(t, "@im=");
733020d2c4d2Smrg		    strncat(t, s, (size_t) (end - s));
733120d2c4d2Smrg
733220d2c4d2Smrg		    if ((p = XSetLocaleModifiers(t)) != 0 && *p
733320d2c4d2Smrg			&& (screen->xim = XOpenIM(XtDisplay(xw),
733420d2c4d2Smrg						  NULL,
733520d2c4d2Smrg						  NULL,
733620d2c4d2Smrg						  NULL)) != 0)
733720d2c4d2Smrg			break;
7338d522f475Smrg
733920d2c4d2Smrg		}
734020d2c4d2Smrg		s = ns + 1;
7341d522f475Smrg	    }
734220d2c4d2Smrg	    MyStackFree(t, buf);
7343d522f475Smrg	}
7344d522f475Smrg    }
7345d522f475Smrg
7346956cc18dSsnj    if (screen->xim == NULL
7347d522f475Smrg	&& (p = XSetLocaleModifiers("@im=none")) != NULL
7348d522f475Smrg	&& *p) {
7349956cc18dSsnj	screen->xim = XOpenIM(XtDisplay(xw), NULL, NULL, NULL);
7350d522f475Smrg    }
7351d522f475Smrg
7352956cc18dSsnj    if (!screen->xim) {
7353d522f475Smrg	fprintf(stderr, "Failed to open input method\n");
7354d522f475Smrg	return;
7355d522f475Smrg    }
7356d522f475Smrg    TRACE(("VTInitI18N opened input method\n"));
7357d522f475Smrg
7358956cc18dSsnj    if (XGetIMValues(screen->xim, XNQueryInputStyle, &xim_styles, NULL)
7359d522f475Smrg	|| !xim_styles
7360d522f475Smrg	|| !xim_styles->count_styles) {
7361d522f475Smrg	fprintf(stderr, "input method doesn't support any style\n");
7362956cc18dSsnj	cleanupInputMethod(screen);
7363956cc18dSsnj	xw->misc.cannot_im = True;
7364d522f475Smrg	return;
7365d522f475Smrg    }
7366d522f475Smrg
7367d522f475Smrg    found = False;
7368956cc18dSsnj    for (s = xw->misc.preedit_type; s && !found;) {
7369d522f475Smrg	while (*s && isspace(CharOf(*s)))
7370d522f475Smrg	    s++;
7371d522f475Smrg	if (!*s)
7372d522f475Smrg	    break;
7373d522f475Smrg	if ((ns = end = strchr(s, ',')) != 0)
7374d522f475Smrg	    ns++;
7375d522f475Smrg	else
7376d522f475Smrg	    end = s + strlen(s);
7377d522f475Smrg	while ((end != s) && isspace(CharOf(end[-1])))
7378d522f475Smrg	    end--;
7379d522f475Smrg
7380d522f475Smrg	if (end != s) {		/* just in case we have a spurious comma */
738120d2c4d2Smrg	    TRACE(("looking for style '%.*s'\n", (int) (end - s), s));
7382d522f475Smrg	    for (i = 0; i < XtNumber(known_style); i++) {
7383d522f475Smrg		if ((int) strlen(known_style[i].name) == (end - s)
738420d2c4d2Smrg		    && !strncmp(s, known_style[i].name, (size_t) (end - s))) {
7385d522f475Smrg		    input_style = known_style[i].code;
7386d522f475Smrg		    for (j = 0; j < xim_styles->count_styles; j++) {
7387d522f475Smrg			if (input_style == xim_styles->supported_styles[j]) {
7388d522f475Smrg			    found = True;
7389d522f475Smrg			    break;
7390d522f475Smrg			}
7391d522f475Smrg		    }
7392d522f475Smrg		    if (found)
7393d522f475Smrg			break;
7394d522f475Smrg		}
7395d522f475Smrg	    }
7396d522f475Smrg	}
7397d522f475Smrg
7398d522f475Smrg	s = ns;
7399d522f475Smrg    }
7400d522f475Smrg    XFree(xim_styles);
7401d522f475Smrg
7402d522f475Smrg    if (!found) {
7403d522f475Smrg	fprintf(stderr,
7404d522f475Smrg		"input method doesn't support my preedit type (%s)\n",
7405956cc18dSsnj		xw->misc.preedit_type);
7406956cc18dSsnj	cleanupInputMethod(screen);
7407956cc18dSsnj	xw->misc.cannot_im = True;
7408d522f475Smrg	return;
7409d522f475Smrg    }
7410d522f475Smrg
7411d522f475Smrg    /*
7412d522f475Smrg     * Check for styles we do not yet support.
7413d522f475Smrg     */
7414d522f475Smrg    TRACE(("input_style %#lx\n", input_style));
7415d522f475Smrg    if (input_style == (XIMPreeditArea | XIMStatusArea)) {
7416d522f475Smrg	fprintf(stderr,
7417d522f475Smrg		"This program doesn't support the 'OffTheSpot' preedit type\n");
7418956cc18dSsnj	cleanupInputMethod(screen);
7419956cc18dSsnj	xw->misc.cannot_im = True;
7420d522f475Smrg	return;
7421d522f475Smrg    }
7422d522f475Smrg
7423d522f475Smrg    /*
7424d522f475Smrg     * For XIMPreeditPosition (or OverTheSpot), XIM client has to
7425d522f475Smrg     * prepare a font.
7426d522f475Smrg     * The font has to be locale-dependent XFontSet, whereas
7427d522f475Smrg     * XTerm use Unicode font.  This leads a problem that the
7428d522f475Smrg     * same font cannot be used for XIM preedit.
7429d522f475Smrg     */
7430d522f475Smrg    if (input_style != (XIMPreeditNothing | XIMStatusNothing)) {
7431d522f475Smrg	char **missing_charset_list;
7432d522f475Smrg	int missing_charset_count;
7433d522f475Smrg	char *def_string;
7434d522f475Smrg	XVaNestedList p_list;
7435d522f475Smrg	XPoint spot =
7436d522f475Smrg	{0, 0};
7437d522f475Smrg	XFontStruct **fonts;
7438d522f475Smrg	char **font_name_list;
7439d522f475Smrg
7440956cc18dSsnj	screen->fs = XCreateFontSet(XtDisplay(xw),
7441956cc18dSsnj				    xw->misc.f_x,
7442956cc18dSsnj				    &missing_charset_list,
7443956cc18dSsnj				    &missing_charset_count,
7444956cc18dSsnj				    &def_string);
7445956cc18dSsnj	if (screen->fs == NULL) {
7446d522f475Smrg	    fprintf(stderr, "Preparation of font set "
7447956cc18dSsnj		    "\"%s\" for XIM failed.\n", xw->misc.f_x);
7448956cc18dSsnj	    screen->fs = XCreateFontSet(XtDisplay(xw),
7449956cc18dSsnj					DEFXIMFONT,
7450956cc18dSsnj					&missing_charset_list,
7451956cc18dSsnj					&missing_charset_count,
7452956cc18dSsnj					&def_string);
7453d522f475Smrg	}
7454956cc18dSsnj	if (screen->fs == NULL) {
7455d522f475Smrg	    fprintf(stderr, "Preparation of default font set "
7456d522f475Smrg		    "\"%s\" for XIM failed.\n", DEFXIMFONT);
7457956cc18dSsnj	    cleanupInputMethod(screen);
7458956cc18dSsnj	    xw->misc.cannot_im = True;
7459d522f475Smrg	    return;
7460d522f475Smrg	}
7461956cc18dSsnj	(void) XExtentsOfFontSet(screen->fs);
7462956cc18dSsnj	j = (unsigned) XFontsOfFontSet(screen->fs, &fonts, &font_name_list);
7463956cc18dSsnj	for (i = 0, screen->fs_ascent = 0; i < j; i++) {
7464956cc18dSsnj	    if (screen->fs_ascent < (*fonts)->ascent)
7465956cc18dSsnj		screen->fs_ascent = (*fonts)->ascent;
7466d522f475Smrg	}
7467d522f475Smrg	p_list = XVaCreateNestedList(0,
7468d522f475Smrg				     XNSpotLocation, &spot,
7469956cc18dSsnj				     XNFontSet, screen->fs,
7470d522f475Smrg				     NULL);
7471956cc18dSsnj	screen->xic = XCreateIC(screen->xim,
7472956cc18dSsnj				XNInputStyle, input_style,
7473956cc18dSsnj				XNClientWindow, XtWindow(xw),
7474956cc18dSsnj				XNFocusWindow, XtWindow(xw),
7475956cc18dSsnj				XNPreeditAttributes, p_list,
7476956cc18dSsnj				NULL);
7477d522f475Smrg    } else {
7478956cc18dSsnj	screen->xic = XCreateIC(screen->xim, XNInputStyle, input_style,
7479956cc18dSsnj				XNClientWindow, XtWindow(xw),
7480956cc18dSsnj				XNFocusWindow, XtWindow(xw),
7481956cc18dSsnj				NULL);
7482d522f475Smrg    }
7483d522f475Smrg
7484956cc18dSsnj    if (!screen->xic) {
7485d522f475Smrg	fprintf(stderr, "Failed to create input context\n");
7486956cc18dSsnj	cleanupInputMethod(screen);
7487d522f475Smrg    }
7488d522f475Smrg#if defined(USE_XIM_INSTANTIATE_CB)
7489d522f475Smrg    else {
7490d522f475Smrg	XIMCallback destroy_cb;
7491d522f475Smrg
7492d522f475Smrg	destroy_cb.callback = xim_destroy_cb;
7493d522f475Smrg	destroy_cb.client_data = NULL;
7494956cc18dSsnj	if (XSetIMValues(screen->xim, XNDestroyCallback, &destroy_cb, NULL))
7495d522f475Smrg	    fprintf(stderr, "Could not set destroy callback to IM\n");
7496d522f475Smrg    }
7497d522f475Smrg#endif
7498d522f475Smrg
7499d522f475Smrg    return;
7500d522f475Smrg}
7501d522f475Smrg
7502d522f475Smrgstatic void
7503956cc18dSsnjVTInitI18N(XtermWidget xw)
7504d522f475Smrg{
7505956cc18dSsnj    if (xw->misc.open_im) {
7506956cc18dSsnj	xim_real_init(xw);
7507d522f475Smrg
7508d522f475Smrg#if defined(USE_XIM_INSTANTIATE_CB)
750920d2c4d2Smrg	if (TScreenOf(xw)->xic == NULL
7510956cc18dSsnj	    && !xw->misc.cannot_im
7511956cc18dSsnj	    && xw->misc.retry_im-- > 0) {
7512d522f475Smrg	    sleep(3);
7513956cc18dSsnj	    XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL,
7514d522f475Smrg					   xim_instantiate_cb, NULL);
7515d522f475Smrg	}
7516d522f475Smrg#endif
7517d522f475Smrg    }
7518d522f475Smrg}
7519d522f475Smrg#endif /* OPT_I18N_SUPPORT && OPT_INPUT_METHOD */
7520d522f475Smrg
7521d522f475Smrgstatic Boolean
7522d522f475SmrgVTSetValues(Widget cur,
7523d522f475Smrg	    Widget request GCC_UNUSED,
7524d522f475Smrg	    Widget wnew,
7525d522f475Smrg	    ArgList args GCC_UNUSED,
7526d522f475Smrg	    Cardinal *num_args GCC_UNUSED)
7527d522f475Smrg{
7528d522f475Smrg    XtermWidget curvt = (XtermWidget) cur;
7529d522f475Smrg    XtermWidget newvt = (XtermWidget) wnew;
75302eaa94a1Schristos    Boolean refresh_needed = False;
75312eaa94a1Schristos    Boolean fonts_redone = False;
7532d522f475Smrg
753320d2c4d2Smrg    if ((T_COLOR(TScreenOf(curvt), TEXT_BG) !=
753420d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), TEXT_BG)) ||
753520d2c4d2Smrg	(T_COLOR(TScreenOf(curvt), TEXT_FG) !=
753620d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), TEXT_FG)) ||
753720d2c4d2Smrg	(TScreenOf(curvt)->MenuFontName(TScreenOf(curvt)->menu_font_number) !=
753820d2c4d2Smrg	 TScreenOf(newvt)->MenuFontName(TScreenOf(newvt)->menu_font_number)) ||
7539d522f475Smrg	(curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)) {
7540d522f475Smrg	if (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)
754120d2c4d2Smrg	    TScreenOf(newvt)->MenuFontName(fontMenu_default) = newvt->misc.default_font.f_n;
7542d522f475Smrg	if (xtermLoadFont(newvt,
754320d2c4d2Smrg			  xtermFontName(TScreenOf(newvt)->MenuFontName(TScreenOf(curvt)->menu_font_number)),
754420d2c4d2Smrg			  True, TScreenOf(newvt)->menu_font_number)) {
7545d522f475Smrg	    /* resizing does the redisplay, so don't ask for it here */
7546d522f475Smrg	    refresh_needed = True;
7547d522f475Smrg	    fonts_redone = True;
7548d522f475Smrg	} else if (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)
754920d2c4d2Smrg	    TScreenOf(newvt)->MenuFontName(fontMenu_default) = curvt->misc.default_font.f_n;
7550d522f475Smrg    }
7551d522f475Smrg    if (!fonts_redone
755220d2c4d2Smrg	&& (T_COLOR(TScreenOf(curvt), TEXT_CURSOR) !=
755320d2c4d2Smrg	    T_COLOR(TScreenOf(newvt), TEXT_CURSOR))) {
7554d522f475Smrg	set_cursor_gcs(newvt);
7555d522f475Smrg	refresh_needed = True;
7556d522f475Smrg    }
7557d522f475Smrg    if (curvt->misc.re_verse != newvt->misc.re_verse) {
7558d522f475Smrg	newvt->flags ^= REVERSE_VIDEO;
7559d522f475Smrg	ReverseVideo(newvt);
75602eaa94a1Schristos	/* ReverseVideo toggles */
75612eaa94a1Schristos	newvt->misc.re_verse = (Boolean) (!newvt->misc.re_verse);
7562d522f475Smrg	refresh_needed = True;
7563d522f475Smrg    }
756420d2c4d2Smrg    if ((T_COLOR(TScreenOf(curvt), MOUSE_FG) !=
756520d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), MOUSE_FG)) ||
756620d2c4d2Smrg	(T_COLOR(TScreenOf(curvt), MOUSE_BG) !=
756720d2c4d2Smrg	 T_COLOR(TScreenOf(newvt), MOUSE_BG))) {
756820d2c4d2Smrg	recolor_cursor(TScreenOf(newvt),
756920d2c4d2Smrg		       TScreenOf(newvt)->pointer_cursor,
757020d2c4d2Smrg		       T_COLOR(TScreenOf(newvt), MOUSE_FG),
757120d2c4d2Smrg		       T_COLOR(TScreenOf(newvt), MOUSE_BG));
7572d522f475Smrg	refresh_needed = True;
7573d522f475Smrg    }
7574d522f475Smrg    if (curvt->misc.scrollbar != newvt->misc.scrollbar) {
7575d522f475Smrg	ToggleScrollBar(newvt);
7576d522f475Smrg    }
7577d522f475Smrg
7578d522f475Smrg    return refresh_needed;
7579d522f475Smrg}
7580d522f475Smrg
7581d522f475Smrg#define setGC(code) set_at = __LINE__, currentCgs = code
7582d522f475Smrg
7583d522f475Smrg#define OutsideSelection(screen,srow,scol)  \
7584d522f475Smrg	 ((srow) > (screen)->endH.row || \
7585d522f475Smrg	  ((srow) == (screen)->endH.row && \
7586d522f475Smrg	   (scol) >= (screen)->endH.col) || \
7587d522f475Smrg	  (srow) < (screen)->startH.row || \
7588d522f475Smrg	  ((srow) == (screen)->startH.row && \
7589d522f475Smrg	   (scol) < (screen)->startH.col))
7590d522f475Smrg
7591d522f475Smrg/*
7592d522f475Smrg * Shows cursor at new cursor position in screen.
7593d522f475Smrg */
7594d522f475Smrgvoid
7595d522f475SmrgShowCursor(void)
7596d522f475Smrg{
7597d522f475Smrg    XtermWidget xw = term;
759820d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
7599d522f475Smrg    int x, y;
7600956cc18dSsnj    IChar base;
7601d522f475Smrg    unsigned flags;
7602956cc18dSsnj    CellColor fg_bg = 0;
7603d522f475Smrg    GC currentGC;
760420d2c4d2Smrg    GC outlineGC;
7605d522f475Smrg    CgsEnum currentCgs = gcMAX;
7606d522f475Smrg    VTwin *currentWin = WhichVWin(screen);
7607d522f475Smrg    int set_at;
7608d522f475Smrg    Bool in_selection;
7609d522f475Smrg    Bool reversed;
7610d522f475Smrg    Bool filled;
7611d522f475Smrg    Pixel fg_pix;
7612d522f475Smrg    Pixel bg_pix;
7613d522f475Smrg    Pixel tmp;
7614d522f475Smrg#if OPT_HIGHLIGHT_COLOR
7615d522f475Smrg    Pixel selbg_pix = T_COLOR(screen, HIGHLIGHT_BG);
7616d522f475Smrg    Pixel selfg_pix = T_COLOR(screen, HIGHLIGHT_FG);
7617d522f475Smrg    Boolean use_selbg;
7618d522f475Smrg    Boolean use_selfg;
7619d522f475Smrg#endif
7620d522f475Smrg#if OPT_WIDE_CHARS
7621956cc18dSsnj    size_t off;
7622d522f475Smrg    int my_col = 0;
7623d522f475Smrg#endif
7624d522f475Smrg    int cursor_col;
7625956cc18dSsnj    LineData *ld = 0;
7626d522f475Smrg
7627d522f475Smrg    if (screen->cursor_state == BLINKED_OFF)
7628d522f475Smrg	return;
7629d522f475Smrg
7630d522f475Smrg    if (screen->eventMode != NORMAL)
7631d522f475Smrg	return;
7632d522f475Smrg
7633d522f475Smrg    if (INX2ROW(screen, screen->cur_row) > screen->max_row)
7634d522f475Smrg	return;
7635d522f475Smrg
7636d522f475Smrg    screen->cursorp.row = screen->cur_row;
7637d522f475Smrg    cursor_col = screen->cursorp.col = screen->cur_col;
7638d522f475Smrg    screen->cursor_moved = False;
7639d522f475Smrg
7640d522f475Smrg#ifndef NO_ACTIVE_ICON
7641d522f475Smrg    if (IsIcon(screen)) {
7642d522f475Smrg	screen->cursor_state = ON;
7643d522f475Smrg	return;
7644d522f475Smrg    }
7645d522f475Smrg#endif /* NO_ACTIVE_ICON */
7646d522f475Smrg
7647956cc18dSsnj    ld = getLineData(screen, screen->cur_row);
7648956cc18dSsnj
7649956cc18dSsnj    base = ld->charData[cursor_col];
7650956cc18dSsnj    flags = ld->attribs[cursor_col];
7651d522f475Smrg
7652d522f475Smrg    if_OPT_WIDE_CHARS(screen, {
7653956cc18dSsnj	if (base == HIDDEN_CHAR && cursor_col > 0) {
7654d522f475Smrg	    /* if cursor points to non-initial part of wide character,
7655d522f475Smrg	     * back it up
7656d522f475Smrg	     */
7657d522f475Smrg	    --cursor_col;
7658956cc18dSsnj	    base = ld->charData[cursor_col];
7659d522f475Smrg	}
7660d522f475Smrg	my_col = cursor_col;
7661956cc18dSsnj	if (base == 0)
7662956cc18dSsnj	    base = ' ';
7663956cc18dSsnj	if (isWide((int) base))
7664d522f475Smrg	    my_col += 1;
7665d522f475Smrg    });
7666d522f475Smrg
7667956cc18dSsnj    if (base == 0) {
7668956cc18dSsnj	base = ' ';
7669d522f475Smrg    }
7670956cc18dSsnj#if OPT_ISO_COLORS
7671956cc18dSsnj#ifdef EXP_BOGUS_FG
7672956cc18dSsnj    /*
7673956cc18dSsnj     * If the cursor happens to be on blanks, and we have not set both
7674956cc18dSsnj     * foreground and background color, do not treat it as a colored cell.
7675956cc18dSsnj     */
7676956cc18dSsnj    if (base == ' ') {
7677956cc18dSsnj	if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) {
7678956cc18dSsnj	    TRACE(("ShowCursor - do not treat as a colored cell\n"));
7679956cc18dSsnj	    flags &= ~(FG_COLOR | BG_COLOR);
7680956cc18dSsnj	} else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) {
7681956cc18dSsnj	    TRACE(("ShowCursor - should we treat as a colored cell?\n"));
7682956cc18dSsnj	    if (!(xw->flags & FG_COLOR))
7683956cc18dSsnj		if (CheckBogusForeground(screen, "ShowCursor"))
7684956cc18dSsnj		    flags &= ~(FG_COLOR | BG_COLOR);
7685956cc18dSsnj	}
7686956cc18dSsnj    }
7687956cc18dSsnj#else /* !EXP_BOGUS_FG */
7688d522f475Smrg    /*
7689d522f475Smrg     * If the cursor happens to be on blanks, and the foreground color is set
7690d522f475Smrg     * but not the background, do not treat it as a colored cell.
7691d522f475Smrg     */
7692d522f475Smrg    if ((flags & TERM_COLOR_FLAGS(xw)) == BG_COLOR
7693956cc18dSsnj	&& base == ' ') {
7694d522f475Smrg	flags &= ~TERM_COLOR_FLAGS(xw);
7695d522f475Smrg    }
7696956cc18dSsnj#endif
7697d522f475Smrg#endif
7698d522f475Smrg
7699d522f475Smrg    /*
7700d522f475Smrg     * Compare the current cell to the last set of colors used for the
7701d522f475Smrg     * cursor and update the GC's if needed.
7702d522f475Smrg     */
7703956cc18dSsnj    if_OPT_ISO_COLORS(screen, {
7704956cc18dSsnj	fg_bg = ld->color[cursor_col];
7705d522f475Smrg    });
770620d2c4d2Smrg
7707d522f475Smrg    fg_pix = getXtermForeground(xw, flags, extract_fg(xw, fg_bg, flags));
7708d522f475Smrg    bg_pix = getXtermBackground(xw, flags, extract_bg(xw, fg_bg, flags));
7709d522f475Smrg
7710d522f475Smrg    if (OutsideSelection(screen, screen->cur_row, screen->cur_col))
7711d522f475Smrg	in_selection = False;
7712d522f475Smrg    else
7713d522f475Smrg	in_selection = True;
7714d522f475Smrg
7715d522f475Smrg    reversed = ReverseOrHilite(screen, flags, in_selection);
7716d522f475Smrg
7717d522f475Smrg    /* This is like updatedXtermGC(), except that we have to worry about
7718d522f475Smrg     * whether the window has focus, since in that case we want just an
7719d522f475Smrg     * outline for the cursor.
7720d522f475Smrg     */
77212eaa94a1Schristos    filled = (screen->select || screen->always_highlight) && !screen->cursor_underline;
7722d522f475Smrg#if OPT_HIGHLIGHT_COLOR
7723d522f475Smrg    use_selbg = isNotForeground(xw, fg_pix, bg_pix, selbg_pix);
7724d522f475Smrg    use_selfg = isNotBackground(xw, fg_pix, bg_pix, selfg_pix);
7725d522f475Smrg#endif
7726d522f475Smrg    if (filled) {
7727d522f475Smrg	if (reversed) {		/* text is reverse video */
7728d522f475Smrg	    if (getCgsGC(xw, currentWin, gcVTcursNormal)) {
7729d522f475Smrg		setGC(gcVTcursNormal);
7730d522f475Smrg	    } else {
7731d522f475Smrg		if (flags & BOLDATTR(screen)) {
7732d522f475Smrg		    setGC(gcBold);
7733d522f475Smrg		} else {
7734d522f475Smrg		    setGC(gcNorm);
7735d522f475Smrg		}
7736d522f475Smrg	    }
7737d522f475Smrg	    EXCHANGE(fg_pix, bg_pix, tmp);
7738d522f475Smrg#if OPT_HIGHLIGHT_COLOR
7739d522f475Smrg	    if (screen->hilite_reverse) {
7740d522f475Smrg		if (use_selbg && !use_selfg)
7741d522f475Smrg		    fg_pix = bg_pix;
7742d522f475Smrg		if (use_selfg && !use_selbg)
7743d522f475Smrg		    bg_pix = fg_pix;
7744d522f475Smrg		if (use_selbg)
7745d522f475Smrg		    bg_pix = selbg_pix;
7746d522f475Smrg		if (use_selfg)
7747d522f475Smrg		    fg_pix = selfg_pix;
7748d522f475Smrg	    }
7749d522f475Smrg#endif
7750d522f475Smrg	} else {		/* normal video */
7751d522f475Smrg	    if (getCgsGC(xw, currentWin, gcVTcursReverse)) {
7752d522f475Smrg		setGC(gcVTcursReverse);
7753d522f475Smrg	    } else {
7754d522f475Smrg		if (flags & BOLDATTR(screen)) {
7755d522f475Smrg		    setGC(gcBoldReverse);
7756d522f475Smrg		} else {
7757d522f475Smrg		    setGC(gcNormReverse);
7758d522f475Smrg		}
7759d522f475Smrg	    }
7760d522f475Smrg	}
7761d522f475Smrg	if (T_COLOR(screen, TEXT_CURSOR) == xw->dft_foreground) {
7762d522f475Smrg	    setCgsBack(xw, currentWin, currentCgs, fg_pix);
7763d522f475Smrg	}
7764d522f475Smrg	setCgsFore(xw, currentWin, currentCgs, bg_pix);
7765d522f475Smrg    } else {			/* not selected */
7766d522f475Smrg	if (reversed) {		/* text is reverse video */
7767d522f475Smrg	    EXCHANGE(fg_pix, bg_pix, tmp);
7768d522f475Smrg	    setGC(gcNormReverse);
7769d522f475Smrg	} else {		/* normal video */
7770d522f475Smrg	    setGC(gcNorm);
7771d522f475Smrg	}
7772d522f475Smrg#if OPT_HIGHLIGHT_COLOR
7773d522f475Smrg	if (screen->hilite_reverse) {
7774d522f475Smrg	    if (in_selection && !reversed) {
7775d522f475Smrg		;		/* really INVERSE ... */
7776d522f475Smrg	    } else if (in_selection || reversed) {
7777d522f475Smrg		if (use_selbg) {
7778d522f475Smrg		    if (use_selfg) {
7779d522f475Smrg			bg_pix = fg_pix;
7780d522f475Smrg		    } else {
7781d522f475Smrg			fg_pix = bg_pix;
7782d522f475Smrg		    }
7783d522f475Smrg		}
7784d522f475Smrg		if (use_selbg) {
7785d522f475Smrg		    bg_pix = selbg_pix;
7786d522f475Smrg		}
7787d522f475Smrg		if (use_selfg) {
7788d522f475Smrg		    fg_pix = selfg_pix;
7789d522f475Smrg		}
7790d522f475Smrg	    }
7791d522f475Smrg	} else {
7792d522f475Smrg	    if (in_selection) {
7793d522f475Smrg		if (use_selbg) {
7794d522f475Smrg		    bg_pix = selbg_pix;
7795d522f475Smrg		}
7796d522f475Smrg		if (use_selfg) {
7797d522f475Smrg		    fg_pix = selfg_pix;
7798d522f475Smrg		}
7799d522f475Smrg	    }
7800d522f475Smrg	}
7801d522f475Smrg#endif
7802d522f475Smrg	setCgsFore(xw, currentWin, currentCgs, fg_pix);
7803d522f475Smrg	setCgsBack(xw, currentWin, currentCgs, bg_pix);
7804d522f475Smrg    }
7805d522f475Smrg
7806d522f475Smrg    if (screen->cursor_busy == 0
7807d522f475Smrg	&& (screen->cursor_state != ON || screen->cursor_GC != set_at)) {
7808d522f475Smrg
7809d522f475Smrg	screen->cursor_GC = set_at;
781020d2c4d2Smrg	TRACE(("ShowCursor calling drawXtermText cur(%d,%d) %s-%s, set_at %d\n",
7811d522f475Smrg	       screen->cur_row, screen->cur_col,
781220d2c4d2Smrg	       (filled ? "filled" : "outline"),
781320d2c4d2Smrg	       (screen->cursor_underline ? "underline" : "box"),
781420d2c4d2Smrg	       set_at));
7815d522f475Smrg
7816d522f475Smrg	currentGC = getCgsGC(xw, currentWin, currentCgs);
781720d2c4d2Smrg	x = LineCursorX(screen, ld, cursor_col);
781820d2c4d2Smrg	y = CursorY(screen, screen->cur_row);
7819d522f475Smrg
782020d2c4d2Smrg	if (screen->cursor_underline) {
782120d2c4d2Smrg
782220d2c4d2Smrg	    /*
782320d2c4d2Smrg	     * Overriding the combination of filled, reversed, in_selection
782420d2c4d2Smrg	     * is too complicated since the underline and the text-cell use
782520d2c4d2Smrg	     * different rules.  Just redraw the text-cell, and draw the
782620d2c4d2Smrg	     * underline on top of it.
782720d2c4d2Smrg	     */
782820d2c4d2Smrg	    HideCursor();
782920d2c4d2Smrg
783020d2c4d2Smrg	    /*
783120d2c4d2Smrg	     * Our current-GC is likely to have been modified in HideCursor().
783220d2c4d2Smrg	     * Setup a new request.
783320d2c4d2Smrg	     */
783420d2c4d2Smrg	    if (filled) {
783520d2c4d2Smrg		if (T_COLOR(screen, TEXT_CURSOR) == xw->dft_foreground) {
783620d2c4d2Smrg		    setCgsBack(xw, currentWin, currentCgs, fg_pix);
783720d2c4d2Smrg		}
783820d2c4d2Smrg		setCgsFore(xw, currentWin, currentCgs, bg_pix);
783920d2c4d2Smrg	    } else {
784020d2c4d2Smrg		setCgsFore(xw, currentWin, currentCgs, fg_pix);
784120d2c4d2Smrg		setCgsBack(xw, currentWin, currentCgs, bg_pix);
7842d522f475Smrg	    }
7843d522f475Smrg
784420d2c4d2Smrg	    outlineGC = getCgsGC(xw, currentWin, gcVTcursOutline);
7845d522f475Smrg	    if (outlineGC == 0)
7846d522f475Smrg		outlineGC = currentGC;
7847d522f475Smrg
784820d2c4d2Smrg	    /*
784920d2c4d2Smrg	     * Finally, draw the underline.
785020d2c4d2Smrg	     */
78512eaa94a1Schristos	    screen->box->x = (short) x;
785220d2c4d2Smrg	    screen->box->y = (short) (y + FontHeight(screen) - 2);
7853d522f475Smrg	    XDrawLines(screen->display, VWindow(screen), outlineGC,
7854d522f475Smrg		       screen->box, NBOX, CoordModePrevious);
785520d2c4d2Smrg	} else {
785620d2c4d2Smrg	    outlineGC = getCgsGC(xw, currentWin, gcVTcursOutline);
785720d2c4d2Smrg	    if (outlineGC == 0)
785820d2c4d2Smrg		outlineGC = currentGC;
785920d2c4d2Smrg
786020d2c4d2Smrg	    drawXtermText(xw, flags & DRAWX_MASK,
786120d2c4d2Smrg			  currentGC, x, y,
786220d2c4d2Smrg			  LineCharSet(screen, ld),
786320d2c4d2Smrg			  &base, 1, 0);
786420d2c4d2Smrg
786520d2c4d2Smrg#if OPT_WIDE_CHARS
786620d2c4d2Smrg	    if_OPT_WIDE_CHARS(screen, {
786720d2c4d2Smrg		for_each_combData(off, ld) {
786820d2c4d2Smrg		    if (!(ld->combData[off][my_col]))
786920d2c4d2Smrg			break;
787020d2c4d2Smrg		    drawXtermText(xw, (flags & DRAWX_MASK) | NOBACKGROUND,
787120d2c4d2Smrg				  currentGC, x, y,
787220d2c4d2Smrg				  LineCharSet(screen, ld),
787320d2c4d2Smrg				  ld->combData[off] + my_col,
787420d2c4d2Smrg				  1, isWide((int) base));
787520d2c4d2Smrg		}
787620d2c4d2Smrg	    });
787720d2c4d2Smrg#endif
787820d2c4d2Smrg
787920d2c4d2Smrg	    if (!filled) {
788020d2c4d2Smrg		screen->box->x = (short) x;
788120d2c4d2Smrg		screen->box->y = (short) y;
788220d2c4d2Smrg		XDrawLines(screen->display, VWindow(screen), outlineGC,
788320d2c4d2Smrg			   screen->box, NBOX, CoordModePrevious);
788420d2c4d2Smrg	    }
7885d522f475Smrg	}
7886d522f475Smrg    }
7887d522f475Smrg    screen->cursor_state = ON;
7888956cc18dSsnj
7889956cc18dSsnj    return;
7890d522f475Smrg}
7891d522f475Smrg
7892d522f475Smrg/*
7893d522f475Smrg * hide cursor at previous cursor position in screen.
7894d522f475Smrg */
7895d522f475Smrgvoid
7896d522f475SmrgHideCursor(void)
7897d522f475Smrg{
7898d522f475Smrg    XtermWidget xw = term;
789920d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
7900d522f475Smrg    GC currentGC;
7901d522f475Smrg    int x, y;
7902956cc18dSsnj    IChar base;
7903956cc18dSsnj    unsigned flags;
7904956cc18dSsnj    CellColor fg_bg = 0;
7905d522f475Smrg    Bool in_selection;
7906d522f475Smrg#if OPT_WIDE_CHARS
7907956cc18dSsnj    size_t off;
7908d522f475Smrg    int my_col = 0;
7909d522f475Smrg#endif
7910d522f475Smrg    int cursor_col;
7911956cc18dSsnj    LineData *ld = 0;
7912d522f475Smrg
791320d2c4d2Smrg    if (screen->cursor_state == OFF)
7914d522f475Smrg	return;
7915d522f475Smrg    if (INX2ROW(screen, screen->cursorp.row) > screen->max_row)
7916d522f475Smrg	return;
7917d522f475Smrg
7918d522f475Smrg    cursor_col = screen->cursorp.col;
7919d522f475Smrg
7920d522f475Smrg#ifndef NO_ACTIVE_ICON
7921d522f475Smrg    if (IsIcon(screen)) {
7922d522f475Smrg	screen->cursor_state = OFF;
7923d522f475Smrg	return;
7924d522f475Smrg    }
7925d522f475Smrg#endif /* NO_ACTIVE_ICON */
7926d522f475Smrg
7927956cc18dSsnj    ld = getLineData(screen, screen->cursorp.row);
7928956cc18dSsnj
7929956cc18dSsnj    base = ld->charData[cursor_col];
7930956cc18dSsnj    flags = ld->attribs[cursor_col];
7931d522f475Smrg
7932d522f475Smrg    if_OPT_WIDE_CHARS(screen, {
7933956cc18dSsnj	if (base == HIDDEN_CHAR && cursor_col > 0) {
7934d522f475Smrg	    /* if cursor points to non-initial part of wide character,
7935d522f475Smrg	     * back it up
7936d522f475Smrg	     */
7937d522f475Smrg	    --cursor_col;
7938956cc18dSsnj	    base = ld->charData[cursor_col];
7939d522f475Smrg	}
7940d522f475Smrg	my_col = cursor_col;
7941956cc18dSsnj	if (base == 0)
7942956cc18dSsnj	    base = ' ';
7943956cc18dSsnj	if (isWide((int) base))
7944d522f475Smrg	    my_col += 1;
7945d522f475Smrg    });
7946d522f475Smrg
7947956cc18dSsnj    if (base == 0) {
7948956cc18dSsnj	base = ' ';
7949956cc18dSsnj    }
7950956cc18dSsnj#ifdef EXP_BOGUS_FG
7951956cc18dSsnj    /*
7952956cc18dSsnj     * If the cursor happens to be on blanks, and we have not set both
7953956cc18dSsnj     * foreground and background color, do not treat it as a colored cell.
7954956cc18dSsnj     */
7955956cc18dSsnj#if OPT_ISO_COLORS
7956956cc18dSsnj    if (base == ' ') {
7957956cc18dSsnj	if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) {
7958956cc18dSsnj	    TRACE(("HideCursor - do not treat as a colored cell\n"));
7959956cc18dSsnj	    flags &= ~(FG_COLOR | BG_COLOR);
7960956cc18dSsnj	} else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) {
7961956cc18dSsnj	    TRACE(("HideCursor - should we treat as a colored cell?\n"));
7962956cc18dSsnj	    if (!(xw->flags & FG_COLOR))
7963956cc18dSsnj		if (CheckBogusForeground(screen, "HideCursor"))
7964956cc18dSsnj		    flags &= ~(FG_COLOR | BG_COLOR);
7965956cc18dSsnj	}
7966956cc18dSsnj    }
7967956cc18dSsnj#endif
7968956cc18dSsnj#endif
7969956cc18dSsnj#if OPT_ISO_COLORS
7970956cc18dSsnj    fg_bg = 0;
7971956cc18dSsnj#endif
7972956cc18dSsnj
7973956cc18dSsnj    /*
7974956cc18dSsnj     * Compare the current cell to the last set of colors used for the
7975956cc18dSsnj     * cursor and update the GC's if needed.
7976956cc18dSsnj     */
7977956cc18dSsnj    if_OPT_ISO_COLORS(screen, {
7978956cc18dSsnj	fg_bg = ld->color[cursor_col];
7979d522f475Smrg    });
7980d522f475Smrg
7981d522f475Smrg    if (OutsideSelection(screen, screen->cursorp.row, screen->cursorp.col))
7982d522f475Smrg	in_selection = False;
7983d522f475Smrg    else
7984d522f475Smrg	in_selection = True;
7985d522f475Smrg
7986d522f475Smrg    currentGC = updatedXtermGC(xw, flags, fg_bg, in_selection);
7987d522f475Smrg
7988d522f475Smrg    TRACE(("HideCursor calling drawXtermText cur(%d,%d)\n",
7989d522f475Smrg	   screen->cursorp.row, screen->cursorp.col));
799020d2c4d2Smrg
799120d2c4d2Smrg    x = LineCursorX(screen, ld, cursor_col);
799220d2c4d2Smrg    y = CursorY(screen, screen->cursorp.row);
799320d2c4d2Smrg
799420d2c4d2Smrg    drawXtermText(xw, flags & DRAWX_MASK,
799520d2c4d2Smrg		  currentGC, x, y,
7996956cc18dSsnj		  LineCharSet(screen, ld),
7997956cc18dSsnj		  &base, 1, 0);
7998d522f475Smrg
7999d522f475Smrg#if OPT_WIDE_CHARS
8000d522f475Smrg    if_OPT_WIDE_CHARS(screen, {
8001956cc18dSsnj	for_each_combData(off, ld) {
8002956cc18dSsnj	    if (!(ld->combData[off][my_col]))
8003d522f475Smrg		break;
8004d522f475Smrg	    drawXtermText(xw, (flags & DRAWX_MASK) | NOBACKGROUND,
8005d522f475Smrg			  currentGC, x, y,
8006956cc18dSsnj			  LineCharSet(screen, ld),
8007956cc18dSsnj			  ld->combData[off] + my_col,
8008956cc18dSsnj			  1, isWide((int) base));
8009d522f475Smrg	}
8010d522f475Smrg    });
8011d522f475Smrg#endif
8012d522f475Smrg    screen->cursor_state = OFF;
8013d522f475Smrg    resetXtermGC(xw, flags, in_selection);
8014956cc18dSsnj
8015956cc18dSsnj    return;
8016d522f475Smrg}
8017d522f475Smrg
8018d522f475Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
8019d522f475Smrgstatic void
8020d522f475SmrgStartBlinking(TScreen * screen)
8021d522f475Smrg{
8022d522f475Smrg    if (screen->blink_timer == 0) {
80232eaa94a1Schristos	unsigned long interval = (unsigned long) ((screen->cursor_state == ON)
80242eaa94a1Schristos						  ? screen->blink_on
80252eaa94a1Schristos						  : screen->blink_off);
8026d522f475Smrg	if (interval == 0)	/* wow! */
8027d522f475Smrg	    interval = 1;	/* let's humor him anyway */
8028d522f475Smrg	screen->blink_timer = XtAppAddTimeOut(app_con,
8029d522f475Smrg					      interval,
8030d522f475Smrg					      HandleBlinking,
8031d522f475Smrg					      screen);
8032d522f475Smrg    }
8033d522f475Smrg}
8034d522f475Smrg
8035d522f475Smrgstatic void
8036d522f475SmrgStopBlinking(TScreen * screen)
8037d522f475Smrg{
8038d522f475Smrg    if (screen->blink_timer)
8039d522f475Smrg	XtRemoveTimeOut(screen->blink_timer);
8040d522f475Smrg    screen->blink_timer = 0;
8041d522f475Smrg}
8042d522f475Smrg
8043d522f475Smrg#if OPT_BLINK_TEXT
8044d522f475Smrgstatic Bool
8045956cc18dSsnjLineHasBlinking(TScreen * screen, LineData * ld)
8046d522f475Smrg{
8047d522f475Smrg    int col;
8048d522f475Smrg    Bool result = False;
8049d522f475Smrg
8050d522f475Smrg    for (col = 0; col < MaxCols(screen); ++col) {
8051956cc18dSsnj	if (ld->attribs[col] & BLINK) {
8052d522f475Smrg	    result = True;
8053d522f475Smrg	    break;
8054d522f475Smrg	}
8055d522f475Smrg    }
8056d522f475Smrg    return result;
8057d522f475Smrg}
8058d522f475Smrg#endif
8059d522f475Smrg
8060d522f475Smrg/*
8061d522f475Smrg * Blink the cursor by alternately showing/hiding cursor.  We leave the timer
8062d522f475Smrg * running all the time (even though that's a little inefficient) to make the
8063d522f475Smrg * logic simple.
8064d522f475Smrg */
8065d522f475Smrgstatic void
8066d522f475SmrgHandleBlinking(XtPointer closure, XtIntervalId * id GCC_UNUSED)
8067d522f475Smrg{
8068d522f475Smrg    TScreen *screen = (TScreen *) closure;
8069d522f475Smrg    Bool resume = False;
8070d522f475Smrg
8071d522f475Smrg    screen->blink_timer = 0;
8072d522f475Smrg    screen->blink_state = !screen->blink_state;
8073d522f475Smrg
8074d522f475Smrg#if OPT_BLINK_CURS
8075d522f475Smrg    if (DoStartBlinking(screen)) {
8076d522f475Smrg	if (screen->cursor_state == ON) {
8077d522f475Smrg	    if (screen->select || screen->always_highlight) {
8078d522f475Smrg		HideCursor();
8079d522f475Smrg		if (screen->cursor_state == OFF)
8080d522f475Smrg		    screen->cursor_state = BLINKED_OFF;
8081d522f475Smrg	    }
8082d522f475Smrg	} else if (screen->cursor_state == BLINKED_OFF) {
8083d522f475Smrg	    screen->cursor_state = OFF;
8084d522f475Smrg	    ShowCursor();
8085d522f475Smrg	    if (screen->cursor_state == OFF)
8086d522f475Smrg		screen->cursor_state = BLINKED_OFF;
8087d522f475Smrg	}
8088d522f475Smrg	resume = True;
8089d522f475Smrg    }
8090d522f475Smrg#endif
8091d522f475Smrg
8092d522f475Smrg#if OPT_BLINK_TEXT
8093d522f475Smrg    /*
809420d2c4d2Smrg     * Inspect the lines on the current screen to see if any have the BLINK flag
8095d522f475Smrg     * associated with them.  Prune off any that have had the corresponding
8096d522f475Smrg     * cells reset.  If any are left, repaint those lines with ScrnRefresh().
8097d522f475Smrg     */
8098d522f475Smrg    if (!(screen->blink_as_bold)) {
8099d522f475Smrg	int row;
8100d522f475Smrg	int first_row = screen->max_row;
8101d522f475Smrg	int last_row = -1;
8102d522f475Smrg
8103d522f475Smrg	for (row = screen->max_row; row >= 0; row--) {
8104956cc18dSsnj	    LineData *ld = getLineData(screen, ROW2INX(screen, row));
810520d2c4d2Smrg
810620d2c4d2Smrg	    if (ld != 0 && LineTstBlinked(ld)) {
8107956cc18dSsnj		if (LineHasBlinking(screen, ld)) {
8108d522f475Smrg		    resume = True;
8109d522f475Smrg		    if (row > last_row)
8110d522f475Smrg			last_row = row;
8111d522f475Smrg		    if (row < first_row)
8112d522f475Smrg			first_row = row;
8113d522f475Smrg		} else {
8114956cc18dSsnj		    LineClrBlinked(ld);
8115d522f475Smrg		}
8116d522f475Smrg	    }
8117d522f475Smrg	}
8118d522f475Smrg	/*
8119d522f475Smrg	 * FIXME: this could be a little more efficient, e.g,. by limiting the
8120d522f475Smrg	 * columns which are updated.
8121d522f475Smrg	 */
8122d522f475Smrg	if (first_row <= last_row) {
8123d522f475Smrg	    ScrnRefresh(term,
8124d522f475Smrg			first_row,
8125d522f475Smrg			0,
8126d522f475Smrg			last_row + 1 - first_row,
8127d522f475Smrg			MaxCols(screen),
8128d522f475Smrg			True);
8129d522f475Smrg	}
8130d522f475Smrg    }
8131d522f475Smrg#endif
8132d522f475Smrg
8133d522f475Smrg    /*
8134d522f475Smrg     * If either the cursor or text is blinking, restart the timer.
8135d522f475Smrg     */
8136d522f475Smrg    if (resume)
8137d522f475Smrg	StartBlinking(screen);
8138d522f475Smrg}
8139d522f475Smrg#endif /* OPT_BLINK_CURS || OPT_BLINK_TEXT */
8140d522f475Smrg
814120d2c4d2Smrgvoid
814220d2c4d2SmrgRestartBlinking(TScreen * screen GCC_UNUSED)
814320d2c4d2Smrg{
814420d2c4d2Smrg#if OPT_BLINK_CURS || OPT_BLINK_TEXT
814520d2c4d2Smrg    if (screen->blink_timer == 0) {
814620d2c4d2Smrg	Bool resume = False;
814720d2c4d2Smrg
814820d2c4d2Smrg#if OPT_BLINK_CURS
814920d2c4d2Smrg	if (DoStartBlinking(screen)) {
815020d2c4d2Smrg	    resume = True;
815120d2c4d2Smrg	}
815220d2c4d2Smrg#endif
815320d2c4d2Smrg#if OPT_BLINK_TEXT
815420d2c4d2Smrg	if (!resume) {
815520d2c4d2Smrg	    int row;
815620d2c4d2Smrg
815720d2c4d2Smrg	    for (row = screen->max_row; row >= 0; row--) {
815820d2c4d2Smrg		LineData *ld = getLineData(screen, ROW2INX(screen, row));
815920d2c4d2Smrg
816020d2c4d2Smrg		if (ld != 0 && LineTstBlinked(ld)) {
816120d2c4d2Smrg		    if (LineHasBlinking(screen, ld)) {
816220d2c4d2Smrg			resume = True;
816320d2c4d2Smrg			break;
816420d2c4d2Smrg		    }
816520d2c4d2Smrg		}
816620d2c4d2Smrg	    }
816720d2c4d2Smrg	}
816820d2c4d2Smrg#endif
816920d2c4d2Smrg	if (resume)
817020d2c4d2Smrg	    StartBlinking(screen);
817120d2c4d2Smrg    }
817220d2c4d2Smrg#endif
817320d2c4d2Smrg}
817420d2c4d2Smrg
8175d522f475Smrg/*
8176d522f475Smrg * Implement soft or hard (full) reset of the VTxxx emulation.  There are a
8177d522f475Smrg * couple of differences from real DEC VTxxx terminals (to avoid breaking
8178d522f475Smrg * applications which have come to rely on xterm doing this):
8179d522f475Smrg *
8180d522f475Smrg *	+ autowrap mode should be reset (instead it's reset to the resource
8181d522f475Smrg *	  default).
8182d522f475Smrg *	+ the popup menu offers a choice of resetting the savedLines, or not.
8183d522f475Smrg *	  (but the control sequence does this anyway).
8184d522f475Smrg */
8185d522f475Smrgvoid
8186d522f475SmrgVTReset(XtermWidget xw, Bool full, Bool saved)
8187d522f475Smrg{
818820d2c4d2Smrg    static char empty[1];
818920d2c4d2Smrg
819020d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
8191d522f475Smrg
8192d522f475Smrg    if (!XtIsRealized((Widget) xw) || (CURRENT_EMU() != (Widget) xw)) {
819320d2c4d2Smrg	Bell(xw, XkbBI_MinorError, 0);
8194d522f475Smrg	return;
8195d522f475Smrg    }
8196d522f475Smrg
8197d522f475Smrg    if (saved) {
8198d522f475Smrg	screen->savedlines = 0;
8199d522f475Smrg	ScrollBarDrawThumb(screen->scrollWidget);
8200d522f475Smrg    }
8201d522f475Smrg
8202d522f475Smrg    /* make cursor visible */
8203d522f475Smrg    screen->cursor_set = ON;
8204d522f475Smrg
8205d522f475Smrg    /* reset scrolling region */
8206d522f475Smrg    set_tb_margins(screen, 0, screen->max_row);
8207d522f475Smrg
8208d522f475Smrg    bitclr(&xw->flags, ORIGIN);
8209d522f475Smrg
8210d522f475Smrg    if_OPT_ISO_COLORS(screen, {
8211d522f475Smrg	reset_SGR_Colors(xw);
821220d2c4d2Smrg	if (ResetAnsiColorRequest(xw, empty, 0))
821320d2c4d2Smrg	    xtermRepaint(xw);
8214d522f475Smrg    });
8215d522f475Smrg
8216d522f475Smrg    /* Reset character-sets to initial state */
8217d522f475Smrg    resetCharsets(screen);
8218d522f475Smrg
8219d522f475Smrg#if OPT_MOD_FKEYS
8220d522f475Smrg    /* Reset modifier-resources to initial state */
8221d522f475Smrg    xw->keyboard.modify_now = xw->keyboard.modify_1st;
8222d522f475Smrg#endif
8223d522f475Smrg
8224d522f475Smrg    /* Reset DECSCA */
8225d522f475Smrg    bitclr(&xw->flags, PROTECTED);
8226d522f475Smrg    screen->protected_mode = OFF_PROTECT;
8227d522f475Smrg
8228d522f475Smrg    if (full) {			/* RIS */
8229d522f475Smrg	if (screen->bellOnReset)
823020d2c4d2Smrg	    Bell(xw, XkbBI_TerminalBell, 0);
8231d522f475Smrg
8232d522f475Smrg	/* reset the mouse mode */
8233d522f475Smrg	screen->send_mouse_pos = MOUSE_OFF;
8234d522f475Smrg	screen->send_focus_pos = OFF;
8235d522f475Smrg	screen->waitingForTrackInfo = False;
8236d522f475Smrg	screen->eventMode = NORMAL;
8237d522f475Smrg
8238d522f475Smrg	xtermShowPointer(xw, True);
8239d522f475Smrg
8240d522f475Smrg	TabReset(xw->tabs);
8241d522f475Smrg	xw->keyboard.flags = MODE_SRM;
8242d522f475Smrg#if OPT_INITIAL_ERASE
8243d522f475Smrg	if (xw->keyboard.reset_DECBKM == 1)
8244d522f475Smrg	    xw->keyboard.flags |= MODE_DECBKM;
8245d522f475Smrg	else if (xw->keyboard.reset_DECBKM == 2)
8246d522f475Smrg#endif
824720d2c4d2Smrg	    if (TScreenOf(xw)->backarrow_key)
8248d522f475Smrg		xw->keyboard.flags |= MODE_DECBKM;
8249d522f475Smrg	TRACE(("full reset DECBKM %s\n",
8250d522f475Smrg	       BtoS(xw->keyboard.flags & MODE_DECBKM)));
8251d522f475Smrg	update_appcursor();
8252d522f475Smrg	update_appkeypad();
8253d522f475Smrg	update_decbkm();
8254d522f475Smrg	show_8bit_control(False);
8255d522f475Smrg	reset_decudk();
8256d522f475Smrg
8257d522f475Smrg	FromAlternate(xw);
8258d522f475Smrg	ClearScreen(xw);
8259d522f475Smrg	screen->cursor_state = OFF;
8260d522f475Smrg	if (xw->flags & REVERSE_VIDEO)
8261d522f475Smrg	    ReverseVideo(xw);
8262d522f475Smrg
8263d522f475Smrg	xw->flags = xw->initflags;
8264d522f475Smrg	update_reversevideo();
8265d522f475Smrg	update_autowrap();
8266d522f475Smrg	update_reversewrap();
8267d522f475Smrg	update_autolinefeed();
8268d522f475Smrg
82692eaa94a1Schristos	screen->jumpscroll = (Boolean) (!(xw->flags & SMOOTHSCROLL));
8270d522f475Smrg	update_jumpscroll();
8271d522f475Smrg
8272d522f475Smrg	if (screen->c132 && (xw->flags & IN132COLUMNS)) {
82732eaa94a1Schristos	    Dimension reqWidth = (Dimension) (80 * FontWidth(screen)
82742eaa94a1Schristos					      + 2 * screen->border
82752eaa94a1Schristos					      + ScrollbarWidth(screen));
82762eaa94a1Schristos	    Dimension reqHeight = (Dimension) (FontHeight(screen)
82772eaa94a1Schristos					       * MaxRows(screen)
82782eaa94a1Schristos					       + 2 * screen->border);
8279d522f475Smrg	    Dimension replyWidth;
8280d522f475Smrg	    Dimension replyHeight;
8281d522f475Smrg
8282d522f475Smrg	    TRACE(("Making resize-request to restore 80-columns %dx%d\n",
8283d522f475Smrg		   reqHeight, reqWidth));
82842eaa94a1Schristos	    REQ_RESIZE((Widget) xw,
82852eaa94a1Schristos		       reqWidth,
82862eaa94a1Schristos		       reqHeight,
82872eaa94a1Schristos		       &replyWidth, &replyHeight);
8288d522f475Smrg	    repairSizeHints();
8289d522f475Smrg	    XSync(screen->display, False);	/* synchronize */
8290d522f475Smrg	    if (XtAppPending(app_con))
8291d522f475Smrg		xevents();
8292d522f475Smrg	}
8293d522f475Smrg
8294d522f475Smrg	CursorSet(screen, 0, 0, xw->flags);
8295d522f475Smrg	CursorSave(xw);
8296d522f475Smrg    } else {			/* DECSTR */
8297d522f475Smrg	/*
8298d522f475Smrg	 * There's a tiny difference, to accommodate usage of xterm.
8299d522f475Smrg	 * We reset autowrap to the resource values rather than turning
8300d522f475Smrg	 * it off.
8301d522f475Smrg	 */
830220d2c4d2Smrg	UIntClr(xw->keyboard.flags, (MODE_DECCKM | MODE_KAM | MODE_DECKPAM));
8303d522f475Smrg	bitcpy(&xw->flags, xw->initflags, WRAPAROUND | REVERSEWRAP);
8304d522f475Smrg	bitclr(&xw->flags, INSERT | INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE);
8305d522f475Smrg	if_OPT_ISO_COLORS(screen, {
8306d522f475Smrg	    reset_SGR_Colors(xw);
8307d522f475Smrg	});
8308d522f475Smrg	update_appcursor();
8309d522f475Smrg	update_autowrap();
8310d522f475Smrg	update_reversewrap();
8311d522f475Smrg
8312d522f475Smrg	CursorSave(xw);
8313956cc18dSsnj	screen->sc[screen->whichBuf].row =
8314956cc18dSsnj	    screen->sc[screen->whichBuf].col = 0;
8315d522f475Smrg    }
8316d522f475Smrg    longjmp(vtjmpbuf, 1);	/* force ground state in parser */
8317d522f475Smrg}
8318d522f475Smrg
8319d522f475Smrg/*
8320d522f475Smrg * set_character_class - takes a string of the form
8321d522f475Smrg *
8322d522f475Smrg *   low[-high]:val[,low[-high]:val[...]]
8323d522f475Smrg *
8324d522f475Smrg * and sets the indicated ranges to the indicated values.
8325d522f475Smrg */
8326d522f475Smrgstatic int
8327d522f475Smrgset_character_class(char *s)
8328d522f475Smrg{
8329d522f475Smrg    int i;			/* iterator, index into s */
8330d522f475Smrg    int len;			/* length of s */
8331d522f475Smrg    int acc;			/* accumulator */
8332d522f475Smrg    int low, high;		/* bounds of range [0..127] */
8333d522f475Smrg    int base;			/* 8, 10, 16 (octal, decimal, hex) */
8334d522f475Smrg    int numbers;		/* count of numbers per range */
8335d522f475Smrg    int digits;			/* count of digits in a number */
833620d2c4d2Smrg    static const char *errfmt = "%s:  %s in range string \"%s\" (position %d)\n";
8337d522f475Smrg
8338d522f475Smrg    if (!s || !s[0])
8339d522f475Smrg	return -1;
8340d522f475Smrg
8341d522f475Smrg    base = 10;			/* in case we ever add octal, hex */
8342d522f475Smrg    low = high = -1;		/* out of range */
8343d522f475Smrg
83442eaa94a1Schristos    for (i = 0, len = (int) strlen(s), acc = 0, numbers = digits = 0;
8345d522f475Smrg	 i < len; i++) {
83462eaa94a1Schristos	Char c = CharOf(s[i]);
8347d522f475Smrg
8348d522f475Smrg	if (isspace(c)) {
8349d522f475Smrg	    continue;
8350d522f475Smrg	} else if (isdigit(c)) {
8351d522f475Smrg	    acc = acc * base + (c - '0');
8352d522f475Smrg	    digits++;
8353d522f475Smrg	    continue;
8354d522f475Smrg	} else if (c == '-') {
8355d522f475Smrg	    low = acc;
8356d522f475Smrg	    acc = 0;
8357d522f475Smrg	    if (digits == 0) {
8358d522f475Smrg		fprintf(stderr, errfmt, ProgramName, "missing number", s, i);
8359d522f475Smrg		return (-1);
8360d522f475Smrg	    }
8361d522f475Smrg	    digits = 0;
8362d522f475Smrg	    numbers++;
8363d522f475Smrg	    continue;
8364d522f475Smrg	} else if (c == ':') {
8365d522f475Smrg	    if (numbers == 0)
8366d522f475Smrg		low = acc;
8367d522f475Smrg	    else if (numbers == 1)
8368d522f475Smrg		high = acc;
8369d522f475Smrg	    else {
8370d522f475Smrg		fprintf(stderr, errfmt, ProgramName, "too many numbers",
8371d522f475Smrg			s, i);
8372d522f475Smrg		return (-1);
8373d522f475Smrg	    }
8374d522f475Smrg	    digits = 0;
8375d522f475Smrg	    numbers++;
8376d522f475Smrg	    acc = 0;
8377d522f475Smrg	    continue;
8378d522f475Smrg	} else if (c == ',') {
8379d522f475Smrg	    /*
8380d522f475Smrg	     * now, process it
8381d522f475Smrg	     */
8382d522f475Smrg
8383d522f475Smrg	    if (high < 0) {
8384d522f475Smrg		high = low;
8385d522f475Smrg		numbers++;
8386d522f475Smrg	    }
8387d522f475Smrg	    if (numbers != 2) {
8388d522f475Smrg		fprintf(stderr, errfmt, ProgramName, "bad value number",
8389d522f475Smrg			s, i);
8390d522f475Smrg	    } else if (SetCharacterClassRange(low, high, acc) != 0) {
8391d522f475Smrg		fprintf(stderr, errfmt, ProgramName, "bad range", s, i);
8392d522f475Smrg	    }
8393d522f475Smrg
8394d522f475Smrg	    low = high = -1;
8395d522f475Smrg	    acc = 0;
8396d522f475Smrg	    digits = 0;
8397d522f475Smrg	    numbers = 0;
8398d522f475Smrg	    continue;
8399d522f475Smrg	} else {
8400d522f475Smrg	    fprintf(stderr, errfmt, ProgramName, "bad character", s, i);
8401d522f475Smrg	    return (-1);
8402d522f475Smrg	}			/* end if else if ... else */
8403d522f475Smrg
8404d522f475Smrg    }
8405d522f475Smrg
8406d522f475Smrg    if (low < 0 && high < 0)
8407d522f475Smrg	return (0);
8408d522f475Smrg
8409d522f475Smrg    /*
8410d522f475Smrg     * now, process it
8411d522f475Smrg     */
8412d522f475Smrg
8413d522f475Smrg    if (high < 0)
8414d522f475Smrg	high = low;
8415d522f475Smrg    if (numbers < 1 || numbers > 2) {
8416d522f475Smrg	fprintf(stderr, errfmt, ProgramName, "bad value number", s, i);
8417d522f475Smrg    } else if (SetCharacterClassRange(low, high, acc) != 0) {
8418d522f475Smrg	fprintf(stderr, errfmt, ProgramName, "bad range", s, i);
8419d522f475Smrg    }
8420d522f475Smrg
8421d522f475Smrg    return (0);
8422d522f475Smrg}
8423d522f475Smrg
8424d522f475Smrg/* ARGSUSED */
8425d522f475Smrgstatic void
8426d522f475SmrgHandleKeymapChange(Widget w,
8427d522f475Smrg		   XEvent * event GCC_UNUSED,
8428d522f475Smrg		   String * params,
8429d522f475Smrg		   Cardinal *param_count)
8430d522f475Smrg{
8431d522f475Smrg    static XtTranslations keymap, original;
8432d522f475Smrg    static XtResource key_resources[] =
8433d522f475Smrg    {
8434d522f475Smrg	{XtNtranslations, XtCTranslations, XtRTranslationTable,
8435d522f475Smrg	 sizeof(XtTranslations), 0, XtRTranslationTable, (XtPointer) NULL}
8436d522f475Smrg    };
8437d522f475Smrg    char mapName[1000];
8438d522f475Smrg    char mapClass[1000];
8439d522f475Smrg    char *pmapName;
8440d522f475Smrg    char *pmapClass;
8441d522f475Smrg    size_t len;
8442d522f475Smrg
8443d522f475Smrg    if (*param_count != 1)
8444d522f475Smrg	return;
8445d522f475Smrg
8446d522f475Smrg    if (original == NULL)
8447d522f475Smrg	original = w->core.tm.translations;
8448d522f475Smrg
8449d522f475Smrg    if (strcmp(params[0], "None") == 0) {
8450d522f475Smrg	XtOverrideTranslations(w, original);
8451d522f475Smrg	return;
8452d522f475Smrg    }
8453d522f475Smrg
8454d522f475Smrg    len = strlen(params[0]) + 7;
8455d522f475Smrg
8456d522f475Smrg    pmapName = (char *) MyStackAlloc(len, mapName);
8457d522f475Smrg    pmapClass = (char *) MyStackAlloc(len, mapClass);
8458d522f475Smrg    if (pmapName == NULL
845920d2c4d2Smrg	|| pmapClass == NULL) {
8460d522f475Smrg	SysError(ERROR_KMMALLOC1);
846120d2c4d2Smrg    } else {
846220d2c4d2Smrg
846320d2c4d2Smrg	(void) sprintf(pmapName, "%sKeymap", params[0]);
846420d2c4d2Smrg	(void) strcpy(pmapClass, pmapName);
846520d2c4d2Smrg	if (islower(CharOf(pmapClass[0])))
846620d2c4d2Smrg	    pmapClass[0] = x_toupper(pmapClass[0]);
846720d2c4d2Smrg	XtGetSubresources(w, (XtPointer) &keymap, pmapName, pmapClass,
846820d2c4d2Smrg			  key_resources, (Cardinal) 1, NULL, (Cardinal) 0);
846920d2c4d2Smrg	if (keymap != NULL)
847020d2c4d2Smrg	    XtOverrideTranslations(w, keymap);
8471d522f475Smrg
847220d2c4d2Smrg	MyStackFree(pmapName, mapName);
847320d2c4d2Smrg	MyStackFree(pmapClass, mapClass);
847420d2c4d2Smrg    }
8475d522f475Smrg}
8476d522f475Smrg
8477d522f475Smrg/* ARGSUSED */
8478d522f475Smrgstatic void
8479d522f475SmrgHandleBell(Widget w GCC_UNUSED,
8480d522f475Smrg	   XEvent * event GCC_UNUSED,
8481d522f475Smrg	   String * params,	/* [0] = volume */
8482d522f475Smrg	   Cardinal *param_count)	/* 0 or 1 */
8483d522f475Smrg{
8484d522f475Smrg    int percent = (*param_count) ? atoi(params[0]) : 0;
8485d522f475Smrg
848620d2c4d2Smrg    Bell(term, XkbBI_TerminalBell, percent);
8487d522f475Smrg}
8488d522f475Smrg
8489d522f475Smrg/* ARGSUSED */
8490d522f475Smrgstatic void
8491d522f475SmrgHandleVisualBell(Widget w GCC_UNUSED,
8492d522f475Smrg		 XEvent * event GCC_UNUSED,
8493d522f475Smrg		 String * params GCC_UNUSED,
8494d522f475Smrg		 Cardinal *param_count GCC_UNUSED)
8495d522f475Smrg{
8496d522f475Smrg    VisualBell();
8497d522f475Smrg}
8498d522f475Smrg
8499d522f475Smrg/* ARGSUSED */
8500d522f475Smrgstatic void
8501d522f475SmrgHandleIgnore(Widget w,
8502d522f475Smrg	     XEvent * event,
8503d522f475Smrg	     String * params GCC_UNUSED,
8504d522f475Smrg	     Cardinal *param_count GCC_UNUSED)
8505d522f475Smrg{
8506956cc18dSsnj    XtermWidget xw;
8507956cc18dSsnj
850820d2c4d2Smrg    TRACE(("Handle ignore for %p\n", (void *) w));
8509956cc18dSsnj    if ((xw = getXtermWidget(w)) != 0) {
8510d522f475Smrg	/* do nothing, but check for funny escape sequences */
8511956cc18dSsnj	(void) SendMousePosition(xw, event);
8512d522f475Smrg    }
8513d522f475Smrg}
8514d522f475Smrg
8515d522f475Smrg/* ARGSUSED */
8516d522f475Smrgstatic void
8517d522f475SmrgDoSetSelectedFont(Widget w,
8518d522f475Smrg		  XtPointer client_data GCC_UNUSED,
8519d522f475Smrg		  Atom * selection GCC_UNUSED,
8520d522f475Smrg		  Atom * type,
8521d522f475Smrg		  XtPointer value,
8522d522f475Smrg		  unsigned long *length,
8523d522f475Smrg		  int *format)
8524d522f475Smrg{
8525956cc18dSsnj    XtermWidget xw = getXtermWidget(w);
8526956cc18dSsnj
8527956cc18dSsnj    if ((xw == 0) || *type != XA_STRING || *format != 8) {
852820d2c4d2Smrg	Bell(xw, XkbBI_MinorError, 0);
8529d522f475Smrg    } else {
8530d522f475Smrg	Boolean failed = False;
853120d2c4d2Smrg	int oldFont = TScreenOf(xw)->menu_font_number;
853220d2c4d2Smrg	String save = TScreenOf(xw)->MenuFontName(fontMenu_fontsel);
8533d522f475Smrg	char *val;
8534d522f475Smrg	char *test = 0;
8535d522f475Smrg	char *used = 0;
853620d2c4d2Smrg	unsigned len = (unsigned) *length;
8537d522f475Smrg	unsigned tst;
8538d522f475Smrg
8539d522f475Smrg	/*
8540d522f475Smrg	 * Some versions of X deliver null-terminated selections, some do not.
8541d522f475Smrg	 */
8542d522f475Smrg	for (tst = 0; tst < len; ++tst) {
8543d522f475Smrg	    if (((char *) value)[tst] == '\0') {
8544d522f475Smrg		len = tst;
8545d522f475Smrg		break;
8546d522f475Smrg	    }
8547d522f475Smrg	}
8548d522f475Smrg
8549d522f475Smrg	if (len > 0 && (val = TypeMallocN(char, len + 1)) != 0) {
855020d2c4d2Smrg	    memcpy(val, value, (size_t) len);
8551d522f475Smrg	    val[len] = '\0';
8552d522f475Smrg	    used = x_strtrim(val);
8553d522f475Smrg	    TRACE(("DoSetSelectedFont(%s)\n", val));
8554d522f475Smrg	    /* Do some sanity checking to avoid sending a long selection
8555d522f475Smrg	       back to the server in an OpenFont that is unlikely to succeed.
8556d522f475Smrg	       XLFD allows up to 255 characters and no control characters;
8557d522f475Smrg	       we are a little more liberal here. */
8558d522f475Smrg	    if (len < 1000
8559d522f475Smrg		&& !strchr(val, '\n')
8560d522f475Smrg		&& (test = x_strdup(val)) != 0) {
856120d2c4d2Smrg		TScreenOf(xw)->MenuFontName(fontMenu_fontsel) = test;
8562d522f475Smrg		if (!xtermLoadFont(term,
8563d522f475Smrg				   xtermFontName(val),
8564d522f475Smrg				   True,
8565d522f475Smrg				   fontMenu_fontsel)) {
8566d522f475Smrg		    failed = True;
8567d522f475Smrg		    free(test);
856820d2c4d2Smrg		    TScreenOf(xw)->MenuFontName(fontMenu_fontsel) = save;
8569d522f475Smrg		}
8570d522f475Smrg	    } else {
8571d522f475Smrg		failed = True;
8572d522f475Smrg	    }
8573d522f475Smrg	    if (failed) {
8574d522f475Smrg		(void) xtermLoadFont(term,
857520d2c4d2Smrg				     xtermFontName(TScreenOf(xw)->MenuFontName(oldFont)),
8576d522f475Smrg				     True,
8577d522f475Smrg				     oldFont);
857820d2c4d2Smrg		Bell(xw, XkbBI_MinorError, 0);
8579d522f475Smrg	    }
8580d522f475Smrg	    if (used != val)
8581d522f475Smrg		free(used);
8582d522f475Smrg	    free(val);
8583d522f475Smrg	}
8584d522f475Smrg    }
8585d522f475Smrg}
8586d522f475Smrg
8587d522f475Smrgvoid
8588d522f475SmrgFindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe)
8589d522f475Smrg{
859020d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
8591d522f475Smrg    static AtomPtr *atoms;
85922eaa94a1Schristos    unsigned int atomCount = 0;
8593d522f475Smrg    AtomPtr *pAtom;
85942eaa94a1Schristos    unsigned a;
8595d522f475Smrg    Atom target;
8596d522f475Smrg
8597d522f475Smrg    if (!atom_name)
8598956cc18dSsnj	atom_name = (screen->mappedSelect
8599956cc18dSsnj		     ? screen->mappedSelect[0]
8600d522f475Smrg		     : "PRIMARY");
8601d522f475Smrg    TRACE(("FindFontSelection(%s)\n", atom_name));
8602d522f475Smrg
8603d522f475Smrg    for (pAtom = atoms, a = atomCount; a; a--, pAtom++) {
8604d522f475Smrg	if (strcmp(atom_name, XmuNameOfAtom(*pAtom)) == 0)
8605d522f475Smrg	    break;
8606d522f475Smrg    }
8607d522f475Smrg    if (!a) {
8608d522f475Smrg	atoms = (AtomPtr *) XtRealloc((char *) atoms,
860920d2c4d2Smrg				      (Cardinal) sizeof(AtomPtr)
861020d2c4d2Smrg				      * (atomCount + 1));
861120d2c4d2Smrg	*(pAtom = &atoms[atomCount]) = XmuMakeAtom(atom_name);
8612d522f475Smrg    }
8613d522f475Smrg
8614d522f475Smrg    target = XmuInternAtom(XtDisplay(xw), *pAtom);
8615d522f475Smrg    if (justprobe) {
8616956cc18dSsnj	screen->MenuFontName(fontMenu_fontsel) =
8617d522f475Smrg	    XGetSelectionOwner(XtDisplay(xw), target) ? _Font_Selected_ : 0;
8618956cc18dSsnj	TRACE(("...selected fontname '%s'\n",
8619956cc18dSsnj	       NonNull(screen->MenuFontName(fontMenu_fontsel))));
8620d522f475Smrg    } else {
8621d522f475Smrg	XtGetSelectionValue((Widget) xw, target, XA_STRING,
8622d522f475Smrg			    DoSetSelectedFont, NULL,
8623d522f475Smrg			    XtLastTimestampProcessed(XtDisplay(xw)));
8624d522f475Smrg    }
8625d522f475Smrg    return;
8626d522f475Smrg}
8627d522f475Smrg
8628d522f475Smrgvoid
8629d522f475Smrgset_cursor_gcs(XtermWidget xw)
8630d522f475Smrg{
863120d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
8632d522f475Smrg    VTwin *win = WhichVWin(screen);
8633d522f475Smrg
8634d522f475Smrg    Pixel cc = T_COLOR(screen, TEXT_CURSOR);
8635d522f475Smrg    Pixel fg = T_COLOR(screen, TEXT_FG);
8636d522f475Smrg    Pixel bg = T_COLOR(screen, TEXT_BG);
8637d522f475Smrg    Boolean changed = False;
8638d522f475Smrg
8639d522f475Smrg    /*
8640d522f475Smrg     * Let's see, there are three things that have "color":
8641d522f475Smrg     *
8642d522f475Smrg     *     background
8643d522f475Smrg     *     text
8644d522f475Smrg     *     cursorblock
8645d522f475Smrg     *
8646d522f475Smrg     * And, there are four situations when drawing a cursor, if we decide
8647d522f475Smrg     * that we like have a solid block of cursor color with the letter
8648d522f475Smrg     * that it is highlighting shown in the background color to make it
8649d522f475Smrg     * stand out:
8650d522f475Smrg     *
8651d522f475Smrg     *     selected window, normal video - background on cursor
8652d522f475Smrg     *     selected window, reverse video - foreground on cursor
8653d522f475Smrg     *     unselected window, normal video - foreground on background
8654d522f475Smrg     *     unselected window, reverse video - background on foreground
8655d522f475Smrg     *
8656d522f475Smrg     * Since the last two are really just normalGC and reverseGC, we only
8657d522f475Smrg     * need two new GC's.  Under monochrome, we get the same effect as
8658d522f475Smrg     * above by setting cursor color to foreground.
8659d522f475Smrg     */
8660d522f475Smrg
8661d522f475Smrg    TRACE(("set_cursor_gcs cc=%#lx, fg=%#lx, bg=%#lx\n", cc, fg, bg));
8662d522f475Smrg    if (win != 0 && (cc != bg)) {
8663d522f475Smrg	/* set the fonts to the current one */
8664d522f475Smrg	setCgsFont(xw, win, gcVTcursNormal, 0);
8665d522f475Smrg	setCgsFont(xw, win, gcVTcursFilled, 0);
8666d522f475Smrg	setCgsFont(xw, win, gcVTcursReverse, 0);
8667d522f475Smrg	setCgsFont(xw, win, gcVTcursOutline, 0);
8668d522f475Smrg
8669d522f475Smrg	/* we have a colored cursor */
8670d522f475Smrg	setCgsFore(xw, win, gcVTcursNormal, fg);
8671d522f475Smrg	setCgsBack(xw, win, gcVTcursNormal, cc);
8672d522f475Smrg
8673d522f475Smrg	setCgsFore(xw, win, gcVTcursFilled, cc);
8674d522f475Smrg	setCgsBack(xw, win, gcVTcursFilled, fg);
8675d522f475Smrg
8676d522f475Smrg	if (screen->always_highlight) {
8677d522f475Smrg	    /* both GC's use the same color */
8678d522f475Smrg	    setCgsFore(xw, win, gcVTcursReverse, bg);
8679d522f475Smrg	    setCgsBack(xw, win, gcVTcursReverse, cc);
8680d522f475Smrg
8681d522f475Smrg	    setCgsFore(xw, win, gcVTcursOutline, bg);
8682d522f475Smrg	    setCgsBack(xw, win, gcVTcursOutline, cc);
8683d522f475Smrg	} else {
8684d522f475Smrg	    setCgsFore(xw, win, gcVTcursReverse, bg);
8685d522f475Smrg	    setCgsBack(xw, win, gcVTcursReverse, cc);
8686d522f475Smrg
8687d522f475Smrg	    setCgsFore(xw, win, gcVTcursOutline, cc);
8688d522f475Smrg	    setCgsBack(xw, win, gcVTcursOutline, bg);
8689d522f475Smrg	}
8690d522f475Smrg	changed = True;
8691d522f475Smrg    }
8692d522f475Smrg
8693d522f475Smrg    if (changed) {
8694d522f475Smrg	TRACE(("...set_cursor_gcs - done\n"));
8695d522f475Smrg    }
8696d522f475Smrg}
8697d522f475Smrg
8698d522f475Smrg#ifdef NO_LEAKS
8699d522f475Smrgvoid
8700d522f475Smrgnoleaks_charproc(void)
8701d522f475Smrg{
8702d522f475Smrg    if (v_buffer != 0)
8703d522f475Smrg	free(v_buffer);
8704d522f475Smrg}
8705d522f475Smrg#endif
8706