"Fossies" - the Fresh Open Source Software Archive 
Member "xterm-379/charproc.c" (15 Feb 2023, 384144 Bytes) of package /linux/misc/xterm-379.tgz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "charproc.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
377_vs_379.
1 /* $XTermId: charproc.c,v 1.1934 2023/02/15 00:10:20 tom Exp $ */
2
3 /*
4 * Copyright 1999-2022,2023 by Thomas E. Dickey
5 *
6 * All Rights Reserved
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Except as contained in this notice, the name(s) of the above copyright
28 * holders shall not be used in advertising or otherwise to promote the
29 * sale, use or other dealings in this Software without prior written
30 * authorization.
31 *
32 *
33 * Copyright 1988 X Consortium
34 *
35 * Permission to use, copy, modify, distribute, and sell this software and its
36 * documentation for any purpose is hereby granted without fee, provided that
37 * the above copyright notice appear in all copies and that both that
38 * copyright notice and this permission notice appear in supporting
39 * documentation.
40 *
41 * The above copyright notice and this permission notice shall be included in
42 * all copies or substantial portions of the Software.
43 *
44 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47 * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
48 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
49 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
50 *
51 * Except as contained in this notice, the name of the X Consortium shall not be
52 * used in advertising or otherwise to promote the sale, use or other dealings
53 * in this Software without prior written authorization from the X Consortium.
54 *
55 */
56 /*
57 * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
58 *
59 * All Rights Reserved
60 *
61 * Permission to use, copy, modify, and distribute this software and its
62 * documentation for any purpose and without fee is hereby granted,
63 * provided that the above copyright notice appear in all copies and that
64 * both that copyright notice and this permission notice appear in
65 * supporting documentation, and that the name of Digital Equipment
66 * Corporation not be used in advertising or publicity pertaining to
67 * distribution of the software without specific, written prior permission.
68 *
69 *
70 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
71 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
72 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
73 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
74 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
75 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
76 * SOFTWARE.
77 */
78
79 /* charproc.c */
80
81 #include <version.h>
82 #include <xterm.h>
83
84 #include <X11/Xatom.h>
85 #include <X11/Xutil.h>
86 #include <X11/Xmu/Atoms.h>
87 #include <X11/Xmu/CharSet.h>
88 #include <X11/Xmu/Converters.h>
89
90 #if OPT_INPUT_METHOD
91
92 #if defined(HAVE_LIB_XAW)
93 #include <X11/Xaw/XawImP.h>
94 #elif defined(HAVE_LIB_XAW3D)
95 #include <X11/Xaw3d/XawImP.h>
96 #elif defined(HAVE_LIB_XAW3DXFT)
97 #include <X11/Xaw3dxft/XawImP.h>
98 #elif defined(HAVE_LIB_NEXTAW)
99 #include <X11/neXtaw/XawImP.h>
100 #elif defined(HAVE_LIB_XAWPLUS)
101 #include <X11/XawPlus/XawImP.h>
102 #endif
103
104 #endif
105
106 #if OPT_WIDE_CHARS
107 #include <xutf8.h>
108 #include <wcwidth.h>
109 #include <precompose.h>
110 #ifdef HAVE_LANGINFO_CODESET
111 #include <langinfo.h>
112 #endif
113 #endif
114
115 #if USE_DOUBLE_BUFFER
116 #include <X11/extensions/Xdbe.h>
117 #endif
118
119 #include <stdio.h>
120 #include <ctype.h>
121 #include <assert.h>
122
123 #if defined(HAVE_SCHED_YIELD)
124 #include <sched.h>
125 #endif
126
127 #include <VTparse.h>
128 #include <data.h>
129 #include <error.h>
130 #include <menu.h>
131 #include <main.h>
132 #include <fontutils.h>
133 #include <charclass.h>
134 #include <xstrings.h>
135 #include <graphics.h>
136
137 #ifdef NO_LEAKS
138 #include <xtermcap.h>
139 #endif
140
141 typedef int (*BitFunc) (unsigned * /* p */ ,
142 unsigned /* mask */ );
143
144 static IChar doinput(XtermWidget /* xw */ );
145 static int set_character_class(char * /*s */ );
146 static void FromAlternate(XtermWidget /* xw */ );
147 static void ReallyReset(XtermWidget /* xw */ ,
148 Bool /* full */ ,
149 Bool /* saved */ );
150 static void RequestResize(XtermWidget /* xw */ ,
151 int /* rows */ ,
152 int /* cols */ ,
153 Bool /* text */ );
154 static void SwitchBufs(XtermWidget /* xw */ ,
155 int /* toBuf */ ,
156 Bool /* clearFirst */ );
157 static void ToAlternate(XtermWidget /* xw */ ,
158 Bool /* clearFirst */ );
159 static void ansi_modes(XtermWidget /* xw */ ,
160 BitFunc /* func */ );
161 static int bitclr(unsigned *p, unsigned mask);
162 static int bitcpy(unsigned *p, unsigned q, unsigned mask);
163 static int bitset(unsigned *p, unsigned mask);
164 static void dpmodes(XtermWidget /* xw */ ,
165 BitFunc /* func */ );
166 static void restoremodes(XtermWidget /* xw */ );
167 static void savemodes(XtermWidget /* xw */ );
168 static void window_ops(XtermWidget /* xw */ );
169
170 #if OPT_BLINK_CURS || OPT_BLINK_TEXT
171 #define SettableCursorBlink(screen) \
172 (((screen)->cursor_blink != cbAlways) && \
173 ((screen)->cursor_blink != cbNever))
174 #define UpdateCursorBlink(xw) \
175 SetCursorBlink(xw, TScreenOf(xw)->cursor_blink)
176 static void SetCursorBlink(XtermWidget /* xw */ ,
177 BlinkOps /* enable */ );
178 static void HandleBlinking(XtPointer /* closure */ ,
179 XtIntervalId * /* id */ );
180 static void StartBlinking(XtermWidget /* xw */ );
181 static void StopBlinking(XtermWidget /* xw */ );
182 #else
183 #define StartBlinking(xw) /* nothing */
184 #define StopBlinking(xw) /* nothing */
185 #endif
186
187 #ifndef NO_ACTIVE_ICON
188 static Boolean discount_frame_extents(XtermWidget /* xw */ ,
189 int * /* height */ ,
190 int * /* width */ );
191 #else
192 #define discount_frame_extents(xw, height, width) False
193 #endif
194
195 #if OPT_INPUT_METHOD
196 static void PreeditPosition(XtermWidget /* xw */ );
197 #endif
198
199 #define DEFAULT -1
200 #define BELLSUPPRESSMSEC 200
201
202 static ANSI reply;
203 static PARAMS parms;
204
205 #define nparam parms.count
206
207 #define InitParams() init_params()
208 #define GetParam(n) parms.params[(n)]
209 #define SetParam(n,v) parms.params[(n)] = v
210 #define ParamPair(n) nparam - (n), parms.params + (n)
211
212 static jmp_buf vtjmpbuf;
213
214 /* event handlers */
215 static void HandleBell PROTO_XT_ACTIONS_ARGS;
216 static void HandleIgnore PROTO_XT_ACTIONS_ARGS;
217 static void HandleKeymapChange PROTO_XT_ACTIONS_ARGS;
218 static void HandleVisualBell PROTO_XT_ACTIONS_ARGS;
219 #if HANDLE_STRUCT_NOTIFY
220 static void HandleStructNotify PROTO_XT_EV_HANDLER_ARGS;
221 #endif
222
223 /*
224 * NOTE: VTInitialize zeros out the entire ".screen" component of the
225 * XtermWidget, so make sure to add an assignment statement in VTInitialize()
226 * for each new ".screen" field added to this resource list.
227 */
228
229 /* Defaults */
230 #if OPT_ISO_COLORS
231
232 /*
233 * If we default to colorMode enabled, compile-in defaults for the ANSI colors.
234 */
235 #if DFT_COLORMODE
236 #define DFT_COLOR(name) name
237 #else
238 #define DFT_COLOR(name) XtDefaultForeground
239 #endif
240 #endif
241
242 static char _Font_Selected_[] = "yes"; /* string is arbitrary */
243
244 static const char *defaultTranslations;
245 /* *INDENT-OFF* */
246 static XtActionsRec actionsList[] = {
247 { "allow-bold-fonts", HandleAllowBoldFonts },
248 { "allow-send-events", HandleAllowSends },
249 { "bell", HandleBell },
250 { "clear-saved-lines", HandleClearSavedLines },
251 { "copy-selection", HandleCopySelection },
252 { "create-menu", HandleCreateMenu },
253 { "delete-is-del", HandleDeleteIsDEL },
254 { "dired-button", DiredButton },
255 { "hard-reset", HandleHardReset },
256 { "ignore", HandleIgnore },
257 { "insert", HandleKeyPressed }, /* alias for insert-seven-bit */
258 { "insert-eight-bit", HandleEightBitKeyPressed },
259 { "insert-selection", HandleInsertSelection },
260 { "insert-seven-bit", HandleKeyPressed },
261 { "interpret", HandleInterpret },
262 { "keymap", HandleKeymapChange },
263 { "pointer-motion", HandlePointerMotion },
264 { "pointer-button", HandlePointerButton },
265 { "popup-menu", HandlePopupMenu },
266 { "print", HandlePrintScreen },
267 { "print-everything", HandlePrintEverything },
268 { "print-redir", HandlePrintControlMode },
269 { "quit", HandleQuit },
270 { "redraw", HandleRedraw },
271 { "scroll-back", HandleScrollBack },
272 { "scroll-forw", HandleScrollForward },
273 { "scroll-to", HandleScrollTo },
274 { "secure", HandleSecure },
275 { "select-cursor-end", HandleKeyboardSelectEnd },
276 { "select-cursor-extend", HandleKeyboardSelectExtend },
277 { "select-cursor-start", HandleKeyboardSelectStart },
278 { "select-end", HandleSelectEnd },
279 { "select-extend", HandleSelectExtend },
280 { "select-set", HandleSelectSet },
281 { "select-start", HandleSelectStart },
282 { "send-signal", HandleSendSignal },
283 { "set-8-bit-control", Handle8BitControl },
284 { "set-allow132", HandleAllow132 },
285 { "set-altscreen", HandleAltScreen },
286 { "set-appcursor", HandleAppCursor },
287 { "set-appkeypad", HandleAppKeypad },
288 { "set-autolinefeed", HandleAutoLineFeed },
289 { "set-autowrap", HandleAutoWrap },
290 { "set-backarrow", HandleBackarrow },
291 { "set-bellIsUrgent", HandleBellIsUrgent },
292 { "set-cursesemul", HandleCursesEmul },
293 { "set-jumpscroll", HandleJumpscroll },
294 { "set-keep-clipboard", HandleKeepClipboard },
295 { "set-keep-selection", HandleKeepSelection },
296 { "set-marginbell", HandleMarginBell },
297 { "set-old-function-keys", HandleOldFunctionKeys },
298 { "set-pop-on-bell", HandleSetPopOnBell },
299 { "set-reverse-video", HandleReverseVideo },
300 { "set-reversewrap", HandleReverseWrap },
301 { "set-scroll-on-key", HandleScrollKey },
302 { "set-scroll-on-tty-output", HandleScrollTtyOutput },
303 { "set-scrollbar", HandleScrollbar },
304 { "set-select", HandleSetSelect },
305 { "set-sun-keyboard", HandleSunKeyboard },
306 { "set-titeInhibit", HandleTiteInhibit },
307 { "set-visual-bell", HandleSetVisualBell },
308 { "set-vt-font", HandleSetFont },
309 { "soft-reset", HandleSoftReset },
310 { "start-cursor-extend", HandleKeyboardStartExtend },
311 { "start-extend", HandleStartExtend },
312 { "string", HandleStringEvent },
313 { "vi-button", ViButton },
314 { "visual-bell", HandleVisualBell },
315 #ifdef ALLOWLOGGING
316 { "set-logging", HandleLogging },
317 #endif
318 #if OPT_ALLOW_XXX_OPS
319 { "allow-color-ops", HandleAllowColorOps },
320 { "allow-font-ops", HandleAllowFontOps },
321 { "allow-mouse-ops", HandleAllowMouseOps },
322 { "allow-tcap-ops", HandleAllowTcapOps },
323 { "allow-title-ops", HandleAllowTitleOps },
324 { "allow-window-ops", HandleAllowWindowOps },
325 #endif
326 #if OPT_BLINK_CURS
327 { "set-cursorblink", HandleCursorBlink },
328 #endif
329 #if OPT_BOX_CHARS
330 { "set-font-linedrawing", HandleFontBoxChars },
331 { "set-font-packed", HandleFontPacked },
332 #endif
333 #if OPT_DABBREV
334 { "dabbrev-expand", HandleDabbrevExpand },
335 #endif
336 #if OPT_DEC_CHRSET
337 { "set-font-doublesize", HandleFontDoublesize },
338 #endif
339 #if OPT_DEC_SOFTFONT
340 { "set-font-loading", HandleFontLoading },
341 #endif
342 #if OPT_EXEC_XTERM
343 { "spawn-new-terminal", HandleSpawnTerminal },
344 #endif
345 #if OPT_GRAPHICS
346 { "set-private-colors", HandleSetPrivateColorRegisters },
347 #endif
348 #if OPT_HP_FUNC_KEYS
349 { "set-hp-function-keys", HandleHpFunctionKeys },
350 #endif
351 #if OPT_LOAD_VTFONTS
352 { "load-vt-fonts", HandleLoadVTFonts },
353 #endif
354 #if OPT_MAXIMIZE
355 { "deiconify", HandleDeIconify },
356 { "fullscreen", HandleFullscreen },
357 { "iconify", HandleIconify },
358 { "maximize", HandleMaximize },
359 { "restore", HandleRestoreSize },
360 #endif
361 #if OPT_NUM_LOCK
362 { "alt-sends-escape", HandleAltEsc },
363 { "meta-sends-escape", HandleMetaEsc },
364 { "set-num-lock", HandleNumLock },
365 #endif
366 #if OPT_PRINT_ON_EXIT
367 { "print-immediate", HandlePrintImmediate },
368 { "print-on-error", HandlePrintOnError },
369 #endif
370 #if OPT_READLINE
371 { "readline-button", ReadLineButton },
372 #endif
373 #if OPT_RENDERFONT
374 { "set-render-font", HandleRenderFont },
375 #endif
376 #if OPT_SCO_FUNC_KEYS
377 { "set-sco-function-keys", HandleScoFunctionKeys },
378 #endif
379 #if OPT_SCREEN_DUMPS
380 { "dump-html", HandleDumpHtml },
381 { "dump-svg", HandleDumpSvg },
382 #endif
383 #if OPT_SCROLL_LOCK
384 { "scroll-lock", HandleScrollLock },
385 #endif
386 #if OPT_SELECTION_OPS
387 #if OPT_EXEC_SELECTION
388 { "exec-formatted", HandleExecFormatted },
389 { "exec-selectable", HandleExecSelectable },
390 #endif
391 { "insert-formatted", HandleInsertFormatted },
392 { "insert-selectable", HandleInsertSelectable },
393 #endif
394 #if OPT_SHIFT_FONTS
395 { "larger-vt-font", HandleLargerFont },
396 { "smaller-vt-font", HandleSmallerFont },
397 #endif
398 #if OPT_SIXEL_GRAPHICS
399 { "set-sixel-scrolling", HandleSixelScrolling },
400 #endif
401 #if OPT_SUN_FUNC_KEYS
402 { "set-sun-function-keys", HandleSunFunctionKeys },
403 #endif
404 #if OPT_TEK4014
405 { "set-terminal-type", HandleSetTerminalType },
406 { "set-visibility", HandleVisibility },
407 { "set-tek-text", HandleSetTekText },
408 { "tek-page", HandleTekPage },
409 { "tek-reset", HandleTekReset },
410 { "tek-copy", HandleTekCopy },
411 #endif
412 #if OPT_TOOLBAR
413 { "set-toolbar", HandleToolbar },
414 #endif
415 #if OPT_WIDE_CHARS
416 { "set-utf8-mode", HandleUTF8Mode },
417 { "set-utf8-fonts", HandleUTF8Fonts },
418 { "set-utf8-title", HandleUTF8Title },
419 #endif
420 };
421 /* *INDENT-ON* */
422
423 #define SPS screen.printer_state
424
425 static XtResource xterm_resources[] =
426 {
427 Bres(XtNallowPasteControls, XtCAllowPasteControls,
428 screen.allowPasteControl0, False),
429 Bres(XtNallowSendEvents, XtCAllowSendEvents, screen.allowSendEvent0, False),
430 Bres(XtNallowColorOps, XtCAllowColorOps, screen.allowColorOp0, DEF_ALLOW_COLOR),
431 Bres(XtNallowFontOps, XtCAllowFontOps, screen.allowFontOp0, DEF_ALLOW_FONT),
432 Bres(XtNallowMouseOps, XtCAllowMouseOps, screen.allowMouseOp0, DEF_ALLOW_MOUSE),
433 Bres(XtNallowTcapOps, XtCAllowTcapOps, screen.allowTcapOp0, DEF_ALLOW_TCAP),
434 Bres(XtNallowTitleOps, XtCAllowTitleOps, screen.allowTitleOp0, DEF_ALLOW_TITLE),
435 Bres(XtNallowWindowOps, XtCAllowWindowOps, screen.allowWindowOp0, DEF_ALLOW_WINDOW),
436 Bres(XtNaltIsNotMeta, XtCAltIsNotMeta, screen.alt_is_not_meta, False),
437 Bres(XtNaltSendsEscape, XtCAltSendsEscape, screen.alt_sends_esc, DEF_ALT_SENDS_ESC),
438 Bres(XtNallowBoldFonts, XtCAllowBoldFonts, screen.allowBoldFonts, True),
439 Bres(XtNalwaysBoldMode, XtCAlwaysBoldMode, screen.always_bold_mode, False),
440 Bres(XtNalwaysHighlight, XtCAlwaysHighlight, screen.always_highlight, False),
441 Bres(XtNappcursorDefault, XtCAppcursorDefault, misc.appcursorDefault, False),
442 Bres(XtNappkeypadDefault, XtCAppkeypadDefault, misc.appkeypadDefault, False),
443 Bres(XtNalternateScroll, XtCScrollCond, screen.alternateScroll, False),
444 Bres(XtNautoWrap, XtCAutoWrap, misc.autoWrap, True),
445 Bres(XtNawaitInput, XtCAwaitInput, screen.awaitInput, False),
446 Bres(XtNfreeBoldBox, XtCFreeBoldBox, screen.free_bold_box, False),
447 Bres(XtNbackarrowKey, XtCBackarrowKey, screen.backarrow_key, DEF_BACKARO_BS),
448 Bres(XtNbellIsUrgent, XtCBellIsUrgent, screen.bellIsUrgent, False),
449 Bres(XtNbellOnReset, XtCBellOnReset, screen.bellOnReset, True),
450 Bres(XtNboldMode, XtCBoldMode, screen.bold_mode, True),
451 Bres(XtNbrokenSelections, XtCBrokenSelections, screen.brokenSelections, False),
452 Bres(XtNc132, XtCC132, screen.c132, False),
453 Sres(XtNcdXtraScroll, XtCCdXtraScroll, misc.cdXtraScroll_s, DEF_CD_XTRA_SCROLL),
454 Bres(XtNcolorInnerBorder, XtCColorInnerBorder, misc.color_inner_border, False),
455 Bres(XtNcurses, XtCCurses, screen.curses, False),
456 Bres(XtNcutNewline, XtCCutNewline, screen.cutNewline, True),
457 Bres(XtNcutToBeginningOfLine, XtCCutToBeginningOfLine,
458 screen.cutToBeginningOfLine, True),
459 Bres(XtNdeleteIsDEL, XtCDeleteIsDEL, screen.delete_is_del, DEFDELETE_DEL),
460 Bres(XtNdynamicColors, XtCDynamicColors, misc.dynamicColors, True),
461 Bres(XtNeightBitControl, XtCEightBitControl, screen.control_eight_bits, False),
462 Bres(XtNeightBitInput, XtCEightBitInput, screen.input_eight_bits, True),
463 Bres(XtNeightBitOutput, XtCEightBitOutput, screen.output_eight_bits, True),
464 Bres(XtNeraseSavedLines, XtCEraseSavedLines, screen.eraseSavedLines0, True),
465 Bres(XtNhighlightSelection, XtCHighlightSelection,
466 screen.highlight_selection, False),
467 Bres(XtNshowWrapMarks, XtCShowWrapMarks, screen.show_wrap_marks, False),
468 Bres(XtNhpLowerleftBugCompat, XtCHpLowerleftBugCompat, screen.hp_ll_bc, False),
469 Bres(XtNi18nSelections, XtCI18nSelections, screen.i18nSelections, True),
470 Bres(XtNfastScroll, XtCFastScroll, screen.fastscroll, False),
471 Bres(XtNjumpScroll, XtCJumpScroll, screen.jumpscroll, True),
472 Bres(XtNkeepClipboard, XtCKeepClipboard, screen.keepClipboard, False),
473 Bres(XtNkeepSelection, XtCKeepSelection, screen.keepSelection, True),
474 Bres(XtNloginShell, XtCLoginShell, misc.login_shell, False),
475 Bres(XtNmarginBell, XtCMarginBell, screen.marginbell, False),
476 Bres(XtNmetaSendsEscape, XtCMetaSendsEscape, screen.meta_sends_esc, DEF_META_SENDS_ESC),
477 Bres(XtNmultiScroll, XtCMultiScroll, screen.multiscroll, False),
478 Bres(XtNoldXtermFKeys, XtCOldXtermFKeys, screen.old_fkeys, False),
479 Bres(XtNpopOnBell, XtCPopOnBell, screen.poponbell, False),
480 Bres(XtNprinterAutoClose, XtCPrinterAutoClose, SPS.printer_autoclose, False),
481 Bres(XtNprinterExtent, XtCPrinterExtent, SPS.printer_extent, False),
482 Bres(XtNprinterFormFeed, XtCPrinterFormFeed, SPS.printer_formfeed, False),
483 Bres(XtNprinterNewLine, XtCPrinterNewLine, SPS.printer_newline, True),
484 Bres(XtNquietGrab, XtCQuietGrab, screen.quiet_grab, False),
485 Bres(XtNresizeByPixel, XtCResizeByPixel, misc.resizeByPixel, False),
486 Bres(XtNreverseVideo, XtCReverseVideo, misc.re_verse, False),
487 Bres(XtNreverseWrap, XtCReverseWrap, misc.reverseWrap, False),
488 Bres(XtNscrollBar, XtCScrollBar, misc.scrollbar, False),
489 Bres(XtNscrollKey, XtCScrollCond, screen.scrollkey, False),
490 Bres(XtNscrollTtyOutput, XtCScrollCond, screen.scrollttyoutput, True),
491 Bres(XtNselectToClipboard, XtCSelectToClipboard,
492 screen.selectToClipboard, False),
493 Bres(XtNsignalInhibit, XtCSignalInhibit, misc.signalInhibit, False),
494 Bres(XtNtiteInhibit, XtCTiteInhibit, misc.titeInhibit, False),
495 Sres(XtNtiXtraScroll, XtCTiXtraScroll, misc.tiXtraScroll_s, DEF_TI_XTRA_SCROLL),
496 Bres(XtNtrimSelection, XtCTrimSelection, screen.trim_selection, False),
497 Bres(XtNunderLine, XtCUnderLine, screen.underline, True),
498 Bres(XtNvisualBell, XtCVisualBell, screen.visualbell, False),
499 Bres(XtNvisualBellLine, XtCVisualBellLine, screen.flash_line, False),
500
501 Dres(XtNscaleHeight, XtCScaleHeight, screen.scale_height, "1.0"),
502
503 Ires(XtNbellSuppressTime, XtCBellSuppressTime, screen.bellSuppressTime, BELLSUPPRESSMSEC),
504 Ires(XtNfontWarnings, XtCFontWarnings, misc.fontWarnings, fwResource),
505 Ires(XtNinternalBorder, XtCBorderWidth, screen.border, DEFBORDER),
506 Ires(XtNlimitResize, XtCLimitResize, misc.limit_resize, 1),
507 Ires(XtNlimitResponse, XtCLimitResponse, screen.unparse_max, DEF_LIMIT_RESPONSE),
508 Ires(XtNmultiClickTime, XtCMultiClickTime, screen.multiClickTime, MULTICLICKTIME),
509 Ires(XtNnMarginBell, XtCColumn, screen.nmarginbell, N_MARGINBELL),
510 Ires(XtNpointerMode, XtCPointerMode, screen.pointer_mode, DEF_POINTER_MODE),
511 Ires(XtNprinterControlMode, XtCPrinterControlMode,
512 SPS.printer_controlmode, 0),
513 Ires(XtNtitleModes, XtCTitleModes, screen.title_modes, DEF_TITLE_MODES),
514 Ires(XtNnextEventDelay, XtCNextEventDelay, screen.nextEventDelay, 1),
515 Ires(XtNvisualBellDelay, XtCVisualBellDelay, screen.visualBellDelay, 100),
516 Ires(XtNsaveLines, XtCSaveLines, screen.savelines, DEF_SAVE_LINES),
517 Ires(XtNscrollBarBorder, XtCScrollBarBorder, screen.scrollBarBorder, 1),
518 Ires(XtNscrollLines, XtCScrollLines, screen.scrolllines, DEF_SCROLL_LINES),
519
520 Sres(XtNinitialFont, XtCInitialFont, screen.initial_font, NULL),
521 Sres(XtNfont1, XtCFont1, screen.MenuFontName(fontMenu_font1), NULL),
522 Sres(XtNfont2, XtCFont2, screen.MenuFontName(fontMenu_font2), NULL),
523 Sres(XtNfont3, XtCFont3, screen.MenuFontName(fontMenu_font3), NULL),
524 Sres(XtNfont4, XtCFont4, screen.MenuFontName(fontMenu_font4), NULL),
525 Sres(XtNfont5, XtCFont5, screen.MenuFontName(fontMenu_font5), NULL),
526 Sres(XtNfont6, XtCFont6, screen.MenuFontName(fontMenu_font6), NULL),
527 Sres(XtNfont7, XtCFont7, screen.MenuFontName(fontMenu_font7), NULL),
528
529 Sres(XtNanswerbackString, XtCAnswerbackString, screen.answer_back, ""),
530 Sres(XtNboldFont, XtCBoldFont, misc.default_font.f_b, DEFBOLDFONT),
531 Sres(XtNcharClass, XtCCharClass, screen.charClass, NULL),
532 Sres(XtNdecTerminalID, XtCDecTerminalID, screen.term_id, DFT_DECID),
533 Sres(XtNdefaultString, XtCDefaultString, screen.default_string, "#"),
534 Sres(XtNdisallowedColorOps, XtCDisallowedColorOps,
535 screen.disallowedColorOps, DEF_DISALLOWED_COLOR),
536 Sres(XtNdisallowedFontOps, XtCDisallowedFontOps,
537 screen.disallowedFontOps, DEF_DISALLOWED_FONT),
538 Sres(XtNdisallowedMouseOps, XtCDisallowedMouseOps,
539 screen.disallowedMouseOps, DEF_DISALLOWED_MOUSE),
540 Sres(XtNdisallowedPasteControls, XtCDisallowedPasteControls,
541 screen.disallowedPasteOps, DEF_DISALLOWED_PASTE_CONTROLS),
542 Sres(XtNdisallowedTcapOps, XtCDisallowedTcapOps,
543 screen.disallowedTcapOps, DEF_DISALLOWED_TCAP),
544 Sres(XtNdisallowedWindowOps, XtCDisallowedWindowOps,
545 screen.disallowedWinOps, DEF_DISALLOWED_WINDOW),
546 Sres(XtNeightBitMeta, XtCEightBitMeta, screen.eight_bit_meta_s, DEF_8BIT_META),
547 Sres(XtNeightBitSelectTypes, XtCEightBitSelectTypes,
548 screen.eightbit_select_types, NULL),
549 Sres(XtNfont, XtCFont, misc.default_font.f_n, DEFFONT),
550 Sres(XtNgeometry, XtCGeometry, misc.geo_metry, NULL),
551 Sres(XtNkeyboardDialect, XtCKeyboardDialect, screen.keyboard_dialect, DFT_KBD_DIALECT),
552 Sres(XtNprinterCommand, XtCPrinterCommand, SPS.printer_command, ""),
553 Sres(XtNtekGeometry, XtCGeometry, misc.T_geometry, NULL),
554 Sres(XtNpointerFont, XtCPointerFont, screen.cursor_font_name, NULL),
555
556 Tres(XtNcursorColor, XtCCursorColor, TEXT_CURSOR, XtDefaultForeground),
557 Tres(XtNforeground, XtCForeground, TEXT_FG, XtDefaultForeground),
558 Tres(XtNpointerColor, XtCPointerColor, MOUSE_FG, XtDefaultForeground),
559 Tres(XtNbackground, XtCBackground, TEXT_BG, XtDefaultBackground),
560 Tres(XtNpointerColorBackground, XtCBackground, MOUSE_BG, XtDefaultBackground),
561
562 {XtNresizeGravity, XtCResizeGravity, XtRGravity, sizeof(XtGravity),
563 XtOffsetOf(XtermWidgetRec, misc.resizeGravity),
564 XtRImmediate, (XtPointer) SouthWestGravity},
565
566 Sres(XtNpointerShape, XtCCursor, screen.pointer_shape, "xterm"),
567
568 #ifdef ALLOWLOGGING
569 Bres(XtNlogInhibit, XtCLogInhibit, misc.logInhibit, False),
570 Bres(XtNlogging, XtCLogging, misc.log_on, False),
571 Sres(XtNlogFile, XtCLogfile, screen.logfile, NULL),
572 #endif
573
574 #ifndef NO_ACTIVE_ICON
575 Sres("activeIcon", "ActiveIcon", misc.active_icon_s, "default"),
576 Ires("iconBorderWidth", XtCBorderWidth, misc.icon_border_width, 2),
577 Sres("iconFont", "IconFont", screen.icon_fontname, "nil2"),
578 Cres("iconBorderColor", XtCBorderColor, misc.icon_border_pixel, XtDefaultBackground),
579 #endif /* NO_ACTIVE_ICON */
580
581 #if OPT_BLINK_CURS
582 Bres(XtNcursorBlinkXOR, XtCCursorBlinkXOR, screen.cursor_blink_xor, True),
583 Sres(XtNcursorBlink, XtCCursorBlink, screen.cursor_blink_s, "false"),
584 #endif
585 Bres(XtNcursorUnderLine, XtCCursorUnderLine, screen.cursor_underline, False),
586 Bres(XtNcursorBar, XtCCursorBar, screen.cursor_bar, False),
587
588 #if OPT_BLINK_TEXT
589 Bres(XtNshowBlinkAsBold, XtCCursorBlink, screen.blink_as_bold, DEFBLINKASBOLD),
590 #endif
591
592 #if OPT_BLINK_CURS || OPT_BLINK_TEXT
593 Ires(XtNcursorOnTime, XtCCursorOnTime, screen.blink_on, 600),
594 Ires(XtNcursorOffTime, XtCCursorOffTime, screen.blink_off, 300),
595 #endif
596
597 #if OPT_BOX_CHARS
598 Bres(XtNforceBoxChars, XtCForceBoxChars, screen.force_box_chars, False),
599 Bres(XtNforcePackedFont, XtCForcePackedFont, screen.force_packed, True),
600 Bres(XtNshowMissingGlyphs, XtCShowMissingGlyphs, screen.force_all_chars, False),
601 Bres(XtNassumeAllChars, XtCAssumeAllChars, screen.assume_all_chars, True),
602 #endif
603
604 #if OPT_BROKEN_OSC
605 Bres(XtNbrokenLinuxOSC, XtCBrokenLinuxOSC, screen.brokenLinuxOSC, True),
606 #endif
607
608 #if OPT_BROKEN_ST
609 Bres(XtNbrokenStringTerm, XtCBrokenStringTerm, screen.brokenStringTerm, False),
610 #endif
611
612 #if OPT_C1_PRINT
613 Bres(XtNallowC1Printable, XtCAllowC1Printable, screen.c1_printable, False),
614 #endif
615
616 #if OPT_CLIP_BOLD
617 Bres(XtNuseClipping, XtCUseClipping, screen.use_clipping, True),
618 Bres(XtNuseBorderClipping, XtCUseBorderClipping,
619 screen.use_border_clipping, False),
620 #endif
621
622 #if OPT_DEC_CHRSET
623 Bres(XtNfontDoublesize, XtCFontDoublesize, screen.font_doublesize, True),
624 Ires(XtNcacheDoublesize, XtCCacheDoublesize, screen.cache_doublesize, NUM_CHRSET),
625 #endif
626
627 #if OPT_DEC_RECTOPS
628 Ires(XtNchecksumExtension, XtCChecksumExtension, screen.checksum_ext0, csDEC),
629 #endif
630
631 #if OPT_HIGHLIGHT_COLOR
632 Tres(XtNhighlightColor, XtCHighlightColor, HIGHLIGHT_BG, XtDefaultForeground),
633 Tres(XtNhighlightTextColor, XtCHighlightTextColor, HIGHLIGHT_FG, XtDefaultBackground),
634 Bres(XtNhighlightReverse, XtCHighlightReverse, screen.hilite_reverse, True),
635 Bres(XtNhighlightColorMode, XtCHighlightColorMode, screen.hilite_color, Maybe),
636 #endif /* OPT_HIGHLIGHT_COLOR */
637
638 #if OPT_INPUT_METHOD
639 Bres(XtNopenIm, XtCOpenIm, misc.open_im, True),
640 Sres(XtNinputMethod, XtCInputMethod, misc.input_method, NULL),
641 Sres(XtNpreeditType, XtCPreeditType, misc.preedit_type,
642 "OverTheSpot,Root"),
643 Ires(XtNretryInputMethod, XtCRetryInputMethod, misc.retry_im, 3),
644 #endif
645
646 #if OPT_ISO_COLORS
647 Bres(XtNboldColors, XtCColorMode, screen.boldColors, True),
648 Ires(XtNveryBoldColors, XtCVeryBoldColors, screen.veryBoldColors, 0),
649 Bres(XtNcolorMode, XtCColorMode, screen.colorMode, DFT_COLORMODE),
650
651 Bres(XtNcolorAttrMode, XtCColorAttrMode, screen.colorAttrMode, False),
652 Bres(XtNcolorBDMode, XtCColorAttrMode, screen.colorBDMode, False),
653 Bres(XtNcolorBLMode, XtCColorAttrMode, screen.colorBLMode, False),
654 Bres(XtNcolorRVMode, XtCColorAttrMode, screen.colorRVMode, False),
655 Bres(XtNcolorULMode, XtCColorAttrMode, screen.colorULMode, False),
656 Bres(XtNitalicULMode, XtCColorAttrMode, screen.italicULMode, False),
657 #if OPT_WIDE_ATTRS
658 Bres(XtNcolorITMode, XtCColorAttrMode, screen.colorITMode, False),
659 #endif
660 #if OPT_DIRECT_COLOR
661 Bres(XtNdirectColor, XtCDirectColor, screen.direct_color, True),
662 #endif
663
664 COLOR_RES("0", screen.Acolors[COLOR_0], DFT_COLOR("black")),
665 COLOR_RES("1", screen.Acolors[COLOR_1], DFT_COLOR("red3")),
666 COLOR_RES("2", screen.Acolors[COLOR_2], DFT_COLOR("green3")),
667 COLOR_RES("3", screen.Acolors[COLOR_3], DFT_COLOR("yellow3")),
668 COLOR_RES("4", screen.Acolors[COLOR_4], DFT_COLOR(DEF_COLOR4)),
669 COLOR_RES("5", screen.Acolors[COLOR_5], DFT_COLOR("magenta3")),
670 COLOR_RES("6", screen.Acolors[COLOR_6], DFT_COLOR("cyan3")),
671 COLOR_RES("7", screen.Acolors[COLOR_7], DFT_COLOR("gray90")),
672 COLOR_RES("8", screen.Acolors[COLOR_8], DFT_COLOR("gray50")),
673 COLOR_RES("9", screen.Acolors[COLOR_9], DFT_COLOR("red")),
674 COLOR_RES("10", screen.Acolors[COLOR_10], DFT_COLOR("green")),
675 COLOR_RES("11", screen.Acolors[COLOR_11], DFT_COLOR("yellow")),
676 COLOR_RES("12", screen.Acolors[COLOR_12], DFT_COLOR(DEF_COLOR12)),
677 COLOR_RES("13", screen.Acolors[COLOR_13], DFT_COLOR("magenta")),
678 COLOR_RES("14", screen.Acolors[COLOR_14], DFT_COLOR("cyan")),
679 COLOR_RES("15", screen.Acolors[COLOR_15], DFT_COLOR("white")),
680 COLOR_RES("BD", screen.Acolors[COLOR_BD], DFT_COLOR(XtDefaultForeground)),
681 COLOR_RES("BL", screen.Acolors[COLOR_BL], DFT_COLOR(XtDefaultForeground)),
682 COLOR_RES("UL", screen.Acolors[COLOR_UL], DFT_COLOR(XtDefaultForeground)),
683 COLOR_RES("RV", screen.Acolors[COLOR_RV], DFT_COLOR(XtDefaultForeground)),
684
685 #if OPT_WIDE_ATTRS
686 COLOR_RES("IT", screen.Acolors[COLOR_IT], DFT_COLOR(XtDefaultForeground)),
687 #endif
688
689 #endif /* OPT_ISO_COLORS */
690
691 CLICK_RES("2", screen.onClick[1], "word"),
692 CLICK_RES("3", screen.onClick[2], "line"),
693 CLICK_RES("4", screen.onClick[3], 0),
694 CLICK_RES("5", screen.onClick[4], 0),
695
696 Sres(XtNshiftEscape, XtCShiftEscape, keyboard.shift_escape_s, "false"),
697
698 #if OPT_MOD_FKEYS
699 Ires(XtNmodifyKeyboard, XtCModifyKeyboard,
700 keyboard.modify_1st.allow_keys, 0),
701 Ires(XtNmodifyCursorKeys, XtCModifyCursorKeys,
702 keyboard.modify_1st.cursor_keys, 2),
703 Ires(XtNmodifyFunctionKeys, XtCModifyFunctionKeys,
704 keyboard.modify_1st.function_keys, 2),
705 Ires(XtNmodifyKeypadKeys, XtCModifyKeypadKeys,
706 keyboard.modify_1st.keypad_keys, 0),
707 Ires(XtNmodifyOtherKeys, XtCModifyOtherKeys,
708 keyboard.modify_1st.other_keys, 0),
709 Ires(XtNmodifyStringKeys, XtCModifyStringKeys,
710 keyboard.modify_1st.string_keys, 0),
711 Ires(XtNformatOtherKeys, XtCFormatOtherKeys,
712 keyboard.format_keys, 0),
713 #endif
714
715 #if OPT_NUM_LOCK
716 Bres(XtNalwaysUseMods, XtCAlwaysUseMods, misc.alwaysUseMods, False),
717 Bres(XtNnumLock, XtCNumLock, misc.real_NumLock, True),
718 #endif
719
720 #if OPT_PRINT_COLORS
721 Ires(XtNprintAttributes, XtCPrintAttributes, SPS.print_attributes, 1),
722 #endif
723
724 #if OPT_REGIS_GRAPHICS
725 Sres(XtNregisDefaultFont, XtCRegisDefaultFont,
726 screen.graphics_regis_default_font, ""),
727 Sres(XtNregisScreenSize, XtCRegisScreenSize,
728 screen.graphics_regis_screensize, "auto"),
729 #endif
730
731 #if OPT_GRAPHICS
732 Sres(XtNdecGraphicsID, XtCDecGraphicsID, screen.graph_termid, DFT_DECID),
733 Sres(XtNmaxGraphicSize, XtCMaxGraphicSize, screen.graphics_max_size,
734 "1000x1000"),
735 #endif
736
737 #if OPT_ISO_COLORS && OPT_WIDE_ATTRS && OPT_SGR2_HASH
738 Bres(XtNfaintIsRelative, XtCFaintIsRelative, screen.faint_relative, False),
739 #endif
740
741 #if OPT_SHIFT_FONTS
742 Bres(XtNshiftFonts, XtCShiftFonts, misc.shift_fonts, True),
743 #endif
744
745 #if OPT_SIXEL_GRAPHICS
746 Bres(XtNsixelScrolling, XtCSixelScrolling, screen.sixel_scrolling, True),
747 Bres(XtNsixelScrollsRight, XtCSixelScrollsRight,
748 screen.sixel_scrolls_right, False),
749 #endif
750
751 #if OPT_GRAPHICS
752 Ires(XtNnumColorRegisters, XtCNumColorRegisters,
753 screen.numcolorregisters, 0),
754 Bres(XtNprivateColorRegisters, XtCPrivateColorRegisters,
755 screen.privatecolorregisters, True),
756 #endif
757
758 #if OPT_STATUS_LINE
759 Sres(XtNindicatorFormat, XtCIndicatorFormat, screen.status_fmt, DEF_SL_FORMAT),
760 #endif
761
762 #if OPT_SUNPC_KBD
763 Ires(XtNctrlFKeys, XtCCtrlFKeys, misc.ctrl_fkeys, 10),
764 #endif
765
766 #if OPT_TEK4014
767 Bres(XtNtekInhibit, XtCTekInhibit, misc.tekInhibit, False),
768 Bres(XtNtekSmall, XtCTekSmall, misc.tekSmall, False),
769 Bres(XtNtekStartup, XtCTekStartup, misc.TekEmu, False),
770 #endif
771
772 #if OPT_TOOLBAR
773 Wres(XtNmenuBar, XtCMenuBar, VT100_TB_INFO(menu_bar), 0),
774 Ires(XtNmenuHeight, XtCMenuHeight, VT100_TB_INFO(menu_height), 25),
775 #endif
776
777 #if OPT_WIDE_CHARS
778 Bres(XtNcjkWidth, XtCCjkWidth, misc.cjk_width, False),
779 Bres(XtNmkWidth, XtCMkWidth, misc.mk_width, False),
780 Bres(XtNprecompose, XtCPrecompose, screen.normalized_c, True),
781 Bres(XtNutf8Latin1, XtCUtf8Latin1, screen.utf8_latin1, False),
782 Bres(XtNutf8Weblike, XtCUtf8Weblike, screen.utf8_weblike, False),
783 Bres(XtNvt100Graphics, XtCVT100Graphics, screen.vt100_graphics, True),
784 Bres(XtNwideChars, XtCWideChars, screen.wide_chars, False),
785 Ires(XtNcombiningChars, XtCCombiningChars, screen.max_combining, 2),
786 Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 655),
787 Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 65536),
788 Sres(XtNutf8, XtCUtf8, screen.utf8_mode_s, "default"),
789 Sres(XtNutf8Fonts, XtCUtf8Fonts, screen.utf8_fonts_s, "default"),
790 Sres(XtNutf8Title, XtCUtf8Title, screen.utf8_title_s, "default"),
791 Sres(XtNwideBoldFont, XtCWideBoldFont, misc.default_font.f_wb, DEFWIDEBOLDFONT),
792 Sres(XtNwideFont, XtCWideFont, misc.default_font.f_w, DEFWIDEFONT),
793 Sres(XtNutf8SelectTypes, XtCUtf8SelectTypes, screen.utf8_select_types, NULL),
794 #endif
795
796 #if OPT_LUIT_PROG
797 Sres(XtNlocale, XtCLocale, misc.locale_str, "medium"),
798 Sres(XtNlocaleFilter, XtCLocaleFilter, misc.localefilter, DEFLOCALEFILTER),
799 #endif
800
801 #if OPT_INPUT_METHOD
802 Sres(XtNximFont, XtCXimFont, misc.f_x, DEFXIMFONT),
803 #endif
804
805 #if OPT_SCROLL_LOCK
806 Bres(XtNallowScrollLock, XtCAllowScrollLock, screen.allowScrollLock0, False),
807 Bres(XtNautoScrollLock, XtCAutoScrollLock, screen.autoScrollLock, False),
808 #endif
809
810 /* these are used only for testing ncurses, not in the manual page */
811 #if OPT_XMC_GLITCH
812 Bres(XtNxmcInline, XtCXmcInline, screen.xmc_inline, False),
813 Bres(XtNxmcMoveSGR, XtCXmcMoveSGR, screen.move_sgr_ok, True),
814 Ires(XtNxmcAttributes, XtCXmcAttributes, screen.xmc_attributes, 1),
815 Ires(XtNxmcGlitch, XtCXmcGlitch, screen.xmc_glitch, 0),
816 #endif
817
818 #ifdef SCROLLBAR_RIGHT
819 Bres(XtNrightScrollBar, XtCRightScrollBar, misc.useRight, False),
820 #endif
821
822 #if OPT_RENDERFONT
823 Bres(XtNforceXftHeight, XtCForceXftHeight, screen.force_xft_height, False),
824 Ires(XtNxftMaxGlyphMemory, XtCXftMaxGlyphMemory,
825 screen.xft_max_glyph_memory, 0),
826 Ires(XtNxftMaxUnrefFonts, XtCXftMaxUnrefFonts,
827 screen.xft_max_unref_fonts, 0),
828 Bres(XtNxftTrackMemUsage, XtCXftTrackMemUsage,
829 screen.xft_track_mem_usage, DEF_TRACK_USAGE),
830 #define RES_FACESIZE(n) Dres(XtNfaceSize #n, XtCFaceSize #n, misc.face_size[n], "0.0")
831 RES_FACESIZE(1),
832 RES_FACESIZE(2),
833 RES_FACESIZE(3),
834 RES_FACESIZE(4),
835 RES_FACESIZE(5),
836 RES_FACESIZE(6),
837 RES_FACESIZE(7),
838 Dres(XtNfaceSize, XtCFaceSize, misc.face_size[0], DEFFACESIZE),
839 Sres(XtNfaceName, XtCFaceName, misc.default_xft.f_n, DEFFACENAME),
840 Sres(XtNrenderFont, XtCRenderFont, misc.render_font_s, "default"),
841 Ires(XtNlimitFontsets, XtCLimitFontsets, misc.limit_fontsets, DEF_XFT_CACHE),
842 Ires(XtNlimitFontWidth, XtCLimitFontWidth, misc.limit_fontwidth, 10),
843 #if OPT_RENDERWIDE
844 Sres(XtNfaceNameDoublesize, XtCFaceNameDoublesize, misc.default_xft.f_w, DEFFACENAME),
845 #endif
846 #endif
847 };
848
849 static Boolean VTSetValues(Widget cur, Widget request, Widget new_arg,
850 ArgList args, Cardinal *num_args);
851 static void VTClassInit(void);
852 static void VTDestroy(Widget w);
853 static void VTExpose(Widget w, XEvent *event, Region region);
854 static void VTInitialize(Widget wrequest, Widget new_arg, ArgList args,
855 Cardinal *num_args);
856 static void VTRealize(Widget w, XtValueMask * valuemask,
857 XSetWindowAttributes * values);
858 static void VTResize(Widget w);
859
860 #if OPT_INPUT_METHOD
861 static void VTInitI18N(XtermWidget);
862 #endif
863
864 #ifdef VMS
865 globaldef {
866 "xtermclassrec"
867 } noshare
868
869 #else
870 static
871 #endif /* VMS */
872 WidgetClassRec xtermClassRec =
873 {
874 {
875 /* core_class fields */
876 (WidgetClass) & widgetClassRec, /* superclass */
877 "VT100", /* class_name */
878 sizeof(XtermWidgetRec), /* widget_size */
879 VTClassInit, /* class_initialize */
880 NULL, /* class_part_initialize */
881 False, /* class_inited */
882 VTInitialize, /* initialize */
883 NULL, /* initialize_hook */
884 VTRealize, /* realize */
885 actionsList, /* actions */
886 XtNumber(actionsList), /* num_actions */
887 xterm_resources, /* resources */
888 XtNumber(xterm_resources), /* num_resources */
889 NULLQUARK, /* xrm_class */
890 True, /* compress_motion */
891 False, /* compress_exposure */
892 True, /* compress_enterleave */
893 False, /* visible_interest */
894 VTDestroy, /* destroy */
895 VTResize, /* resize */
896 VTExpose, /* expose */
897 VTSetValues, /* set_values */
898 NULL, /* set_values_hook */
899 XtInheritSetValuesAlmost, /* set_values_almost */
900 NULL, /* get_values_hook */
901 NULL, /* accept_focus */
902 XtVersion, /* version */
903 NULL, /* callback_offsets */
904 0, /* tm_table */
905 XtInheritQueryGeometry, /* query_geometry */
906 XtInheritDisplayAccelerator, /* display_accelerator */
907 NULL /* extension */
908 }
909 };
910
911 #ifdef VMS
912 globaldef {
913 "xtermwidgetclass"
914 }
915 noshare
916 #endif /* VMS */
917 WidgetClass xtermWidgetClass = (WidgetClass) & xtermClassRec;
918
919 /*
920 * Add input-actions for widgets that are overlooked (scrollbar and toolbar):
921 *
922 * a) Sometimes the scrollbar passes through translations, sometimes it
923 * doesn't. We add the KeyPress translations here, just to be sure.
924 * b) In the normal (non-toolbar) configuration, the xterm widget covers
925 * almost all of the window. With a toolbar, there's a relatively
926 * large area that the user would expect to enter keystrokes since the
927 * program can get the focus.
928 */
929 void
930 xtermAddInput(Widget w)
931 {
932 /* *INDENT-OFF* */
933 XtActionsRec input_actions[] = {
934 { "insert", HandleKeyPressed }, /* alias */
935 { "insert-eight-bit", HandleEightBitKeyPressed },
936 { "insert-seven-bit", HandleKeyPressed },
937 { "pointer-motion", HandlePointerMotion },
938 { "pointer-button", HandlePointerButton },
939 { "secure", HandleSecure },
940 { "string", HandleStringEvent },
941 { "scroll-back", HandleScrollBack },
942 { "scroll-forw", HandleScrollForward },
943 { "scroll-to", HandleScrollTo },
944 { "select-cursor-end", HandleKeyboardSelectEnd },
945 { "select-cursor-extend", HandleKeyboardSelectExtend },
946 { "select-cursor-start", HandleKeyboardSelectStart },
947 { "insert-selection", HandleInsertSelection },
948 { "select-start", HandleSelectStart },
949 { "select-extend", HandleSelectExtend },
950 { "start-extend", HandleStartExtend },
951 { "select-end", HandleSelectEnd },
952 { "clear-saved-lines", HandleClearSavedLines },
953 { "popup-menu", HandlePopupMenu },
954 { "bell", HandleBell },
955 { "ignore", HandleIgnore },
956 #if OPT_DABBREV
957 { "dabbrev-expand", HandleDabbrevExpand },
958 #endif
959 #if OPT_MAXIMIZE
960 { "fullscreen", HandleFullscreen },
961 #endif
962 #if OPT_SCROLL_LOCK
963 { "scroll-lock", HandleScrollLock },
964 #endif
965 #if OPT_SHIFT_FONTS
966 { "larger-vt-font", HandleLargerFont },
967 { "smaller-vt-font", HandleSmallerFont },
968 #endif
969 };
970 /* *INDENT-ON* */
971
972 TRACE_TRANS("BEFORE", w);
973 XtAppAddActions(app_con, input_actions, XtNumber(input_actions));
974 XtAugmentTranslations(w, XtParseTranslationTable(defaultTranslations));
975 TRACE_TRANS("AFTER:", w);
976
977 #if OPT_EXTRA_PASTE
978 if (term && term->keyboard.extra_translations)
979 XtOverrideTranslations((Widget) term, XtParseTranslationTable(term->keyboard.extra_translations));
980 #endif
981 }
982
983 #if OPT_ISO_COLORS
984 #ifdef EXP_BOGUS_FG
985 static Bool
986 CheckBogusForeground(TScreen *screen, const char *tag)
987 {
988 int row = -1, col = -1, pass;
989 Bool isClear = True;
990
991 (void) tag;
992 for (pass = 0; pass < 2; ++pass) {
993 row = screen->cur_row;
994 for (; isClear && (row <= screen->max_row); ++row) {
995 CLineData *ld = getLineData(screen, row);
996
997 if (ld != 0) {
998 IAttr *attribs = ld->attribs;
999
1000 col = (row == screen->cur_row) ? screen->cur_col : 0;
1001 for (; isClear && (col <= screen->max_col); ++col) {
1002 unsigned flags = attribs[col];
1003 if (pass) {
1004 flags &= ~FG_COLOR;
1005 attribs[col] = (IAttr) flags;
1006 } else if ((flags & BG_COLOR)) {
1007 isClear = False;
1008 } else if ((flags & FG_COLOR)) {
1009 unsigned ch = ld->charData[col];
1010 isClear = ((ch == ' ') || (ch == 0));
1011 } else {
1012 isClear = False;
1013 }
1014 }
1015 }
1016 }
1017 }
1018 TRACE(("%s checked %d,%d to %d,%d %s pass %d\n",
1019 tag, screen->cur_row, screen->cur_col,
1020 row, col,
1021 isClear && pass ? "cleared" : "unchanged",
1022 pass));
1023
1024 return isClear;
1025 }
1026 #endif
1027
1028 /*
1029 * The terminal's foreground and background colors are set via two mechanisms:
1030 * text (cur_foreground, cur_background values that are passed down to
1031 * XDrawImageString and XDrawString)
1032 * area (X11 graphics context used in XClearArea and XFillRectangle)
1033 */
1034 void
1035 SGR_Foreground(XtermWidget xw, int color)
1036 {
1037 TScreen *screen = TScreenOf(xw);
1038 Pixel fg;
1039
1040 if (color >= 0) {
1041 UIntSet(xw->flags, FG_COLOR);
1042 } else {
1043 UIntClr(xw->flags, FG_COLOR);
1044 }
1045 fg = getXtermFG(xw, xw->flags, color);
1046 xw->cur_foreground = color;
1047
1048 setCgsFore(xw, WhichVWin(screen), gcNorm, fg);
1049 setCgsBack(xw, WhichVWin(screen), gcNormReverse, fg);
1050
1051 setCgsFore(xw, WhichVWin(screen), gcBold, fg);
1052 setCgsBack(xw, WhichVWin(screen), gcBoldReverse, fg);
1053
1054 #ifdef EXP_BOGUS_FG
1055 /*
1056 * If we've just turned off the foreground color, check for blank cells
1057 * which have no background color, but do have foreground color. This
1058 * could happen due to setting the foreground color just before scrolling.
1059 *
1060 * Those cells look uncolored, but will confuse ShowCursor(), which looks
1061 * for the colors in the current cell, and will see the foreground color.
1062 * In that case, remove the foreground color from the blank cells.
1063 */
1064 if (color < 0) {
1065 CheckBogusForeground(screen, "SGR_Foreground");
1066 }
1067 #endif
1068 }
1069
1070 void
1071 SGR_Background(XtermWidget xw, int color)
1072 {
1073 TScreen *screen = TScreenOf(xw);
1074 Pixel bg;
1075
1076 /*
1077 * An indexing operation may have set screen->scroll_amt, which would
1078 * normally result in calling FlushScroll() in WriteText(). However,
1079 * if we're changing the background color now, then the new value
1080 * should not apply to the pending blank lines.
1081 */
1082 if (screen->scroll_amt && (color != xw->cur_background))
1083 FlushScroll(xw);
1084
1085 if (color >= 0) {
1086 UIntSet(xw->flags, BG_COLOR);
1087 } else {
1088 UIntClr(xw->flags, BG_COLOR);
1089 }
1090 bg = getXtermBG(xw, xw->flags, color);
1091 xw->cur_background = color;
1092
1093 setCgsBack(xw, WhichVWin(screen), gcNorm, bg);
1094 setCgsFore(xw, WhichVWin(screen), gcNormReverse, bg);
1095
1096 setCgsBack(xw, WhichVWin(screen), gcBold, bg);
1097 setCgsFore(xw, WhichVWin(screen), gcBoldReverse, bg);
1098 }
1099
1100 /* Invoked after updating bold/underline flags, computes the extended color
1101 * index to use for foreground. (See also 'extract_fg()').
1102 */
1103 static void
1104 setExtendedFG(XtermWidget xw)
1105 {
1106 int fg = xw->sgr_foreground;
1107
1108 if (TScreenOf(xw)->colorAttrMode
1109 || (fg < 0)) {
1110 fg = MapToColorMode(fg, TScreenOf(xw), xw->flags);
1111 }
1112
1113 /* This implements the IBM PC-style convention of 8-colors, with one
1114 * bit for bold, thus mapping the 0-7 codes to 8-15. It won't make
1115 * much sense for 16-color applications, but we keep it to retain
1116 * compatibility with ANSI-color applications.
1117 */
1118 #if OPT_PC_COLORS /* XXXJTL should be settable at runtime (resource or OSC?) */
1119 if (TScreenOf(xw)->boldColors
1120 && (!xw->sgr_38_xcolors)
1121 && (fg >= 0)
1122 && (fg < 8)
1123 && (xw->flags & BOLD))
1124 fg |= 8;
1125 #endif
1126
1127 SGR_Foreground(xw, fg);
1128 }
1129
1130 /* Invoked after updating inverse flag, computes the extended color
1131 * index to use for background. (See also 'extract_bg()').
1132 */
1133 static void
1134 setExtendedBG(XtermWidget xw)
1135 {
1136 int bg = xw->sgr_background;
1137
1138 if (TScreenOf(xw)->colorAttrMode
1139 || (bg < 0)) {
1140 if (TScreenOf(xw)->colorRVMode && (xw->flags & INVERSE))
1141 bg = COLOR_RV;
1142 }
1143
1144 SGR_Background(xw, bg);
1145 }
1146
1147 void
1148 setExtendedColors(XtermWidget xw)
1149 {
1150 setExtendedFG(xw);
1151 setExtendedBG(xw);
1152 }
1153
1154 static void
1155 reset_SGR_Foreground(XtermWidget xw)
1156 {
1157 xw->sgr_foreground = -1;
1158 xw->sgr_38_xcolors = False;
1159 clrDirectFG(xw->flags);
1160 setExtendedFG(xw);
1161 }
1162
1163 static void
1164 reset_SGR_Background(XtermWidget xw)
1165 {
1166 xw->sgr_background = -1;
1167 clrDirectBG(xw->flags);
1168 setExtendedBG(xw);
1169 }
1170
1171 static void
1172 reset_SGR_Colors(XtermWidget xw)
1173 {
1174 reset_SGR_Foreground(xw);
1175 reset_SGR_Background(xw);
1176 }
1177 #endif /* OPT_ISO_COLORS */
1178
1179 #if OPT_WIDE_ATTRS
1180 /*
1181 * Call this before changing the state of ATR_ITALIC, to update the GC fonts.
1182 */
1183 static void
1184 setItalicFont(XtermWidget xw, Bool enable)
1185 {
1186 if (enable) {
1187 if ((xw->flags & ATR_ITALIC) == 0) {
1188 xtermLoadItalics(xw);
1189 TRACE(("setItalicFont: enabling Italics\n"));
1190 xtermUpdateFontGCs(xw, getItalicFont);
1191 }
1192 } else if ((xw->flags & ATR_ITALIC) != 0) {
1193 TRACE(("setItalicFont: disabling Italics\n"));
1194 xtermUpdateFontGCs(xw, getNormalFont);
1195 }
1196 }
1197
1198 static void
1199 ResetItalics(XtermWidget xw)
1200 {
1201 setItalicFont(xw, False);
1202 UIntClr(xw->flags, ATR_ITALIC);
1203 }
1204
1205 #else
1206 #define ResetItalics(xw) /* nothing */
1207 #endif
1208
1209 static void
1210 initCharset(TScreen *screen, int which, DECNRCM_codes code)
1211 {
1212 screen->gsets[which] = code;
1213 }
1214
1215 void
1216 saveCharsets(TScreen *screen, DECNRCM_codes * target)
1217 {
1218 int g;
1219 for (g = 0; g < NUM_GSETS; ++g) {
1220 target[g] = screen->gsets[g];
1221 }
1222 }
1223
1224 void
1225 restoreCharsets(TScreen *screen, DECNRCM_codes * source)
1226 {
1227 int g;
1228 for (g = 0; g < NUM_GSETS; ++g) {
1229 screen->gsets[g] = source[g];
1230 }
1231 }
1232
1233 void
1234 resetCharsets(TScreen *screen)
1235 {
1236 TRACE(("resetCharsets\n"));
1237
1238 initCharset(screen, 0, nrc_ASCII);
1239 initCharset(screen, 1, nrc_ASCII);
1240 initCharset(screen, 2, nrc_ASCII);
1241 initCharset(screen, 3, nrc_ASCII);
1242
1243 screen->curgl = 0; /* G0 => GL. */
1244 screen->curgr = 2; /* G2 => GR. */
1245 screen->curss = 0; /* No single shift. */
1246
1247 #if OPT_VT52_MODE
1248 if (screen->vtXX_level == 0)
1249 initCharset(screen, 1, nrc_DEC_Spec_Graphic); /* Graphics */
1250 #endif
1251 }
1252
1253 static void
1254 modified_DECNRCM(XtermWidget xw)
1255 {
1256 #if OPT_WIDE_CHARS
1257 TScreen *screen = TScreenOf(xw);
1258 if (screen->wide_chars && (screen->utf8_mode || screen->utf8_nrc_mode)) {
1259 int enabled = ((xw->flags & NATIONAL) != 0);
1260 int modefix;
1261 EXCHANGE(screen->utf8_nrc_mode, screen->utf8_mode, modefix);
1262 switchPtyData(screen, !enabled);
1263 TRACE(("UTF8 mode temporarily %s\n", enabled ? "ON" : "OFF"));
1264 }
1265 #else
1266 (void) xw;
1267 #endif
1268 }
1269
1270 /*
1271 * VT300 and up support three ANSI conformance levels, defined according to
1272 * the dpANSI X3.134.1 standard. DEC's manuals equate levels 1 and 2, and
1273 * are unclear. This code is written based on the manuals.
1274 */
1275 static void
1276 set_ansi_conformance(TScreen *screen, int level)
1277 {
1278 TRACE(("set_ansi_conformance(%d) dec_level %d:%d, ansi_level %d\n",
1279 level,
1280 screen->vtXX_level * 100,
1281 screen->terminal_id,
1282 screen->ansi_level));
1283 if (screen->vtXX_level >= 3) {
1284 switch (screen->ansi_level = level) {
1285 case 1:
1286 /* FALLTHRU */
1287 case 2:
1288 initCharset(screen, 0, nrc_ASCII); /* G0 is ASCII */
1289 initCharset(screen, 1, nrc_ASCII); /* G1 is ISO Latin-1 */
1290 screen->curgl = 0;
1291 screen->curgr = 1;
1292 break;
1293 case 3:
1294 initCharset(screen, 0, nrc_ASCII); /* G0 is ASCII */
1295 screen->curgl = 0;
1296 break;
1297 }
1298 }
1299 }
1300
1301 /*
1302 * Set scrolling margins. VTxxx terminals require that the top/bottom are
1303 * different, so we have at least two lines in the scrolling region.
1304 */
1305 static void
1306 set_tb_margins(TScreen *screen, int top, int bottom)
1307 {
1308 TRACE(("set_tb_margins %d..%d, prior %d..%d\n",
1309 top, bottom,
1310 screen->top_marg,
1311 screen->bot_marg));
1312 if (bottom > top) {
1313 screen->top_marg = top;
1314 screen->bot_marg = bottom;
1315 }
1316 if (screen->top_marg > screen->max_row)
1317 screen->top_marg = screen->max_row;
1318 if (screen->bot_marg > screen->max_row)
1319 screen->bot_marg = screen->max_row;
1320 }
1321
1322 static void
1323 set_lr_margins(TScreen *screen, int left, int right)
1324 {
1325 TRACE(("set_lr_margins %d..%d, prior %d..%d\n",
1326 left, right,
1327 screen->lft_marg,
1328 screen->rgt_marg));
1329 if (right > left) {
1330 screen->lft_marg = left;
1331 screen->rgt_marg = right;
1332 }
1333 if (screen->lft_marg > screen->max_col)
1334 screen->lft_marg = screen->max_col;
1335 if (screen->rgt_marg > screen->max_col)
1336 screen->rgt_marg = screen->max_col;
1337 }
1338
1339 #define reset_tb_margins(screen) set_tb_margins(screen, 0, screen->max_row)
1340 #define reset_lr_margins(screen) set_lr_margins(screen, 0, screen->max_col)
1341
1342 void
1343 resetMargins(XtermWidget xw)
1344 {
1345 TScreen *screen = TScreenOf(xw);
1346
1347 reset_tb_margins(screen);
1348 reset_lr_margins(screen);
1349 }
1350
1351 static void
1352 resetMarginMode(XtermWidget xw)
1353 {
1354 UIntClr(xw->flags, LEFT_RIGHT);
1355 resetMargins(xw);
1356 }
1357
1358 static void
1359 resetRendition(XtermWidget xw)
1360 {
1361 TScreen *screen = TScreenOf(xw);
1362 (void) screen;
1363 ResetItalics(xw);
1364 UIntClr(xw->flags,
1365 (SGR_MASK | SGR_MASK2 | INVISIBLE));
1366 }
1367
1368 void
1369 set_max_col(TScreen *screen, int cols)
1370 {
1371 TRACE(("set_max_col %d, prior %d\n", cols, screen->max_col));
1372 if (cols < 0)
1373 cols = 0;
1374 screen->max_col = cols;
1375 }
1376
1377 void
1378 set_max_row(TScreen *screen, int rows)
1379 {
1380 TRACE(("set_max_row %d, prior %d\n", rows, screen->max_row));
1381 if (rows < 0)
1382 rows = 0;
1383 screen->max_row = rows;
1384 }
1385
1386 #if OPT_TRACE
1387 #define DATA(name) { name, #name }
1388 static const struct {
1389 Const PARSE_T *table;
1390 const char *name;
1391 } all_tables[] = {
1392
1393 DATA(ansi_table)
1394 ,DATA(cigtable)
1395 ,DATA(csi2_table)
1396 ,DATA(csi_ex_table)
1397 ,DATA(csi_quo_table)
1398 ,DATA(csi_table)
1399 ,DATA(dec2_table)
1400 ,DATA(dec3_table)
1401 ,DATA(dec_table)
1402 ,DATA(eigtable)
1403 ,DATA(esc_sp_table)
1404 ,DATA(esc_table)
1405 ,DATA(scrtable)
1406 ,DATA(scs96table)
1407 ,DATA(scstable)
1408 ,DATA(sos_table)
1409 #if OPT_BLINK_CURS
1410 ,DATA(csi_sp_table)
1411 #endif
1412 #if OPT_DEC_LOCATOR
1413 ,DATA(csi_tick_table)
1414 #endif
1415 #if OPT_DEC_RECTOPS
1416 ,DATA(csi_dollar_table)
1417 ,DATA(csi_star_table)
1418 ,DATA(csi_dec_dollar_table)
1419 #endif
1420 #if OPT_WIDE_CHARS
1421 ,DATA(esc_pct_table)
1422 ,DATA(scs_amp_table)
1423 ,DATA(scs_pct_table)
1424 ,DATA(scs_2qt_table)
1425 #endif
1426 #if OPT_VT52_MODE
1427 ,DATA(vt52_table)
1428 ,DATA(vt52_esc_table)
1429 ,DATA(vt52_ignore_table)
1430 #endif
1431 #if OPT_XTERM_SGR
1432 ,DATA(csi_hash_table)
1433 #endif
1434 #undef DATA
1435 };
1436
1437 #define WHICH_TABLE(name) if (table == name) result = #name
1438 static const char *
1439 which_table(Const PARSE_T * table)
1440 {
1441 const char *result = "?";
1442 Cardinal n;
1443 for (n = 0; n < XtNumber(all_tables); ++n) {
1444 if (table == all_tables[n].table) {
1445 result = all_tables[n].name;
1446 break;
1447 }
1448 }
1449
1450 return result;
1451 }
1452
1453 static void
1454 check_tables(void)
1455 {
1456 Cardinal n;
1457 int ch;
1458 int total_codes = 0;
1459 int total_ground = 0;
1460 int total_ignored = 0;
1461
1462 TRACE(("** check_tables\n"));
1463 for (n = 0; n < XtNumber(all_tables); ++n) {
1464 Const PARSE_T *table = all_tables[n].table;
1465 TRACE(("*** %s\n", all_tables[n].name));
1466 /*
1467 * Most of the tables should use the same codes in 0..31, 128..159
1468 * as the "ansi" table.
1469 */
1470 if (strncmp(all_tables[n].name, "ansi", 4) &&
1471 strncmp(all_tables[n].name, "sos_", 4) &&
1472 strncmp(all_tables[n].name, "vt52", 4)) {
1473 for (ch = 0; ch < 32; ++ch) {
1474 int c1 = ch + 128;
1475 PARSE_T st_l = table[ch];
1476 PARSE_T st_r = table[c1];
1477 if (st_l != ansi_table[ch]) {
1478 TRACE((" %3d: %d vs %d\n", ch, st_l, ansi_table[ch]));
1479 }
1480 if (st_r != ansi_table[c1]) {
1481 TRACE((" %3d: %d vs %d\n", c1, st_r, ansi_table[c1]));
1482 }
1483 }
1484 }
1485 /*
1486 * All of the tables should have their GL/GR parts encoded the same.
1487 */
1488 for (ch = 32; ch < 127; ++ch) {
1489 PARSE_T st_l = table[ch];
1490 PARSE_T st_r = table[ch + 128];
1491 if (st_l != st_r) {
1492 if (st_r == CASE_IGNORE &&
1493 !strncmp(all_tables[n].name, "vt52", 4)) {
1494 ;
1495 } else {
1496 TRACE((" %3d: %d vs %d\n", ch, st_l, st_r));
1497 }
1498 }
1499 }
1500 /*
1501 * Just for amusement, show how sparse the encoding tables are.
1502 */
1503 for (ch = 0; ch < 256; ++ch) {
1504 ++total_codes;
1505 switch (table[ch]) {
1506 case CASE_GROUND_STATE:
1507 total_ground++;
1508 break;
1509 case CASE_ESC_IGNORE:
1510 /* FALLTHRU */
1511 case CASE_IGNORE:
1512 /* FALLTHRU */
1513 case CASE_VT52_IGNORE:
1514 total_ignored++;
1515 break;
1516 }
1517 }
1518 }
1519 TRACE(("VTPrsTbl:\n"));
1520 TRACE(("%d total codes\n", total_codes));
1521 TRACE(("%d total ignored\n", total_ignored));
1522 TRACE(("%d total reset/ground\n", total_ground));
1523 }
1524
1525 static void
1526 check_bitmasks(void)
1527 {
1528 #define dMSK 0x100
1529 #define DATA(mode,name) { mode, name, #name }
1530 #define DMSK(what) (dMSK | (what))
1531 #define DGRP(offs) (1 << ((offs) - 1))
1532 static struct {
1533 int mode;
1534 int code;
1535 Const char *name;
1536 } table[] = {
1537 DATA(DGRP(1), INVERSE),
1538 DATA(DGRP(1), UNDERLINE),
1539 DATA(DGRP(1), BOLD),
1540 DATA(DGRP(1), BLINK),
1541 DATA(DMSK(DGRP(1)), SGR_MASK),
1542 DATA(DGRP(2), BG_COLOR),
1543 DATA(DGRP(2), FG_COLOR),
1544 DATA(DGRP(2), PROTECTED),
1545 DATA(DGRP(4), CHARDRAWN),
1546 #if OPT_WIDE_ATTRS
1547 DATA(DGRP(2), ATR_FAINT),
1548 DATA(DGRP(2), ATR_ITALIC),
1549 DATA(DGRP(2), ATR_STRIKEOUT),
1550 DATA(DGRP(2), ATR_DBL_UNDER),
1551 DATA(DGRP(2), ATR_DIRECT_FG),
1552 DATA(DGRP(2), ATR_DIRECT_BG),
1553 #endif
1554 DATA(DMSK(DGRP(2)), SGR_MASK2),
1555 DATA(DGRP(3), WRAPAROUND),
1556 DATA(DGRP(3), REVERSEWRAP),
1557 DATA(DGRP(3), REVERSE_VIDEO),
1558 DATA(DGRP(3), LINEFEED),
1559 DATA(DGRP(3), ORIGIN),
1560 DATA(DGRP(3), INSERT),
1561 DATA(DGRP(3), SMOOTHSCROLL),
1562 DATA(DGRP(3), IN132COLUMNS),
1563 DATA(DGRP(3), INVISIBLE),
1564 DATA(DMSK(DGRP(3)), ATTRIBUTES),
1565 DATA(DGRP(5), NATIONAL),
1566 DATA(DGRP(5), LEFT_RIGHT),
1567 DATA(DGRP(5), NOCLEAR_COLM),
1568 DATA(DGRP(4), NOBACKGROUND),
1569 DATA(DGRP(4), NOTRANSLATION),
1570 DATA(DGRP(4), DOUBLEWFONT),
1571 DATA(DGRP(4), DOUBLEHFONT),
1572 DATA(DGRP(4), CHARBYCHAR),
1573 DATA(DGRP(4), NORESOLUTION),
1574 DATA(DMSK(DGRP(1) | DGRP(2) | DGRP(4)), DRAWX_MASK),
1575 DATA(-1, EOF)
1576 };
1577 #undef DATA
1578 int j, k;
1579 TRACE(("** check_bitmasks:\n"));
1580 for (j = 0; table[j].mode >= 0; ++j) {
1581 TRACE(("%4X %8X %s\n", table[j].mode, table[j].code, table[j].name));
1582 if (table[j].mode & dMSK) {
1583 int mask = dMSK;
1584 for (k = 0; table[k].mode >= 0; ++k) {
1585 if (j == k)
1586 continue;
1587 if (table[k].mode & dMSK)
1588 continue;
1589 if ((table[j].mode & table[k].mode) != 0)
1590 mask |= table[k].mode;
1591 }
1592 if (mask != table[j].mode) {
1593 TRACE(("...expected %08X\n", mask));
1594 }
1595 } else {
1596 for (k = 0; table[k].mode >= 0; ++k) {
1597 if (j == k)
1598 continue;
1599 if (table[k].mode & dMSK)
1600 continue;
1601 if ((table[j].code & table[k].code) != 0) {
1602 TRACE(("...same bits %s\n", table[k].name));
1603 }
1604 }
1605 }
1606 }
1607 }
1608 #endif
1609
1610 static int
1611 init_params(void)
1612 {
1613 while (parms.count-- > 0) {
1614 parms.is_sub[parms.count] = 0;
1615 parms.params[parms.count] = 0;
1616 }
1617 parms.count = 0;
1618 parms.has_subparams = 0;
1619 return 0;
1620 }
1621
1622 #if OPT_TRACE > 0
1623 static void
1624 dump_params(void)
1625 {
1626 int n;
1627 int arg;
1628 TRACE(("params %d (%d)\n", nparam, parms.has_subparams));
1629 for (arg = 1, n = 0; n < nparam; ++n) {
1630 TRACE(("%3d.%d %d\n", arg, parms.is_sub[n], parms.params[n]));
1631 if (!parms.is_sub[n])
1632 ++arg;
1633 }
1634 }
1635 #define DumpParams() dump_params()
1636 #else
1637 #define DumpParams() /* nothing */
1638 #endif
1639
1640 /* allocate larger buffer if needed/possible */
1641 #define SafeAlloc(type, area, used, size) \
1642 type *new_string = area; \
1643 size_t new_length = size; \
1644 if (new_length == 0) { \
1645 new_length = 1024; \
1646 new_string = TypeMallocN(type, new_length); \
1647 } else if (used+1 >= new_length) { \
1648 new_length = size * 2; \
1649 new_string = TypeMallocN(type, new_length); \
1650 if (new_string != 0 \
1651 && area != 0 \
1652 && used != 0) { \
1653 memcpy(new_string, area, used * sizeof(type)); \
1654 } \
1655 }
1656 #define SafeFree(area, size) \
1657 if (area != new_string) { \
1658 free(area); \
1659 area = new_string; \
1660 } \
1661 size = new_length
1662
1663 #define WriteNow() { \
1664 unsigned single = 0; \
1665 \
1666 if (screen->curss) { \
1667 dotext(xw, \
1668 screen->gsets[(int) (screen->curss)], \
1669 sp->print_area, \
1670 (Cardinal) 1); \
1671 screen->curss = 0; \
1672 single++; \
1673 } \
1674 if (sp->print_used > single) { \
1675 dotext(xw, \
1676 screen->gsets[(int) (screen->curgl)], \
1677 sp->print_area + single, \
1678 (Cardinal) (sp->print_used - single)); \
1679 } \
1680 sp->print_used = 0; \
1681 } \
1682
1683 #define PARSE_SRM 1
1684
1685 struct ParseState {
1686 unsigned check_recur;
1687 #if OPT_VT52_MODE
1688 Bool vt52_cup;
1689 #endif
1690 Const PARSE_T *groundtable;
1691 Const PARSE_T *parsestate;
1692 int scstype;
1693 int scssize;
1694 Bool private_function; /* distinguish private-mode from standard */
1695 int string_mode; /* nonzero iff we're processing a string */
1696 int lastchar; /* positive iff we had a graphic character */
1697 int nextstate;
1698 #if OPT_WIDE_CHARS
1699 int last_was_wide;
1700 #endif
1701 /* Buffer for processing printable text */
1702 IChar *print_area;
1703 size_t print_size;
1704 size_t print_used;
1705 /* Buffer for processing strings (e.g., OSC ... ST) */
1706 Char *string_area;
1707 size_t string_size;
1708 size_t string_used;
1709 /* Buffer for deferring input */
1710 Char *defer_area;
1711 size_t defer_size;
1712 size_t defer_used;
1713 };
1714
1715 static struct ParseState myState;
1716
1717 static void
1718 init_groundtable(TScreen *screen, struct ParseState *sp)
1719 {
1720 (void) screen;
1721
1722 #if OPT_VT52_MODE
1723 if (!(screen->vtXX_level)) {
1724 sp->groundtable = vt52_table;
1725 } else if (screen->terminal_id >= 100)
1726 #endif
1727 {
1728 sp->groundtable = ansi_table;
1729 }
1730 }
1731
1732 static void
1733 select_charset(struct ParseState *sp, int type, int size)
1734 {
1735 TRACE(("select_charset G%d size %d -> G%d size %d\n",
1736 sp->scstype, sp->scssize,
1737 type, size));
1738
1739 sp->scstype = type;
1740 sp->scssize = size;
1741 if (size == 94) {
1742 sp->parsestate = scstable;
1743 } else {
1744 sp->parsestate = scs96table;
1745 }
1746 }
1747 /* *INDENT-OFF* */
1748 static const struct {
1749 DECNRCM_codes result;
1750 int prefix;
1751 int suffix;
1752 int min_level;
1753 int max_level;
1754 int need_nrc;
1755 } scs_table[] = {
1756 { nrc_ASCII, 0, 'B', 1, 9, 0 },
1757 { nrc_British, 0, 'A', 1, 9, 0 },
1758 { nrc_DEC_Spec_Graphic, 0, '0', 1, 9, 0 },
1759 { nrc_DEC_Alt_Chars, 0, '1', 1, 1, 0 },
1760 { nrc_DEC_Alt_Graphics, 0, '2', 1, 1, 0 },
1761 /* VT2xx */
1762 { nrc_DEC_Supp, 0, '<', 2, 9, 0 },
1763 { nrc_Dutch, 0, '4', 2, 9, 1 },
1764 { nrc_Finnish, 0, '5', 2, 9, 1 },
1765 { nrc_Finnish2, 0, 'C', 2, 9, 1 },
1766 { nrc_French, 0, 'R', 2, 9, 1 },
1767 { nrc_French2, 0, 'f', 2, 9, 1 },
1768 { nrc_French_Canadian, 0, 'Q', 2, 9, 1 },
1769 { nrc_German, 0, 'K', 2, 9, 1 },
1770 { nrc_Italian, 0, 'Y', 2, 9, 1 },
1771 { nrc_Norwegian_Danish2, 0, 'E', 2, 9, 1 },
1772 { nrc_Norwegian_Danish3, 0, '6', 2, 9, 1 },
1773 { nrc_Spanish, 0, 'Z', 2, 9, 1 },
1774 { nrc_Swedish, 0, '7', 2, 9, 1 },
1775 { nrc_Swedish2, 0, 'H', 2, 9, 1 },
1776 { nrc_Swiss, 0, '=', 2, 9, 1 },
1777 /* VT3xx */
1778 { nrc_British_Latin_1, 0, 'A', 3, 9, 1 },
1779 { nrc_DEC_Supp_Graphic, '%', '5', 3, 9, 0 },
1780 { nrc_DEC_Technical, 0, '>', 3, 9, 0 },
1781 { nrc_French_Canadian2, 0, '9', 3, 9, 1 },
1782 { nrc_Norwegian_Danish, 0, '`', 3, 9, 1 },
1783 { nrc_Portugese, '%', '6', 3, 9, 1 },
1784 { nrc_ISO_Latin_1_Supp, 0, 'A', 3, 9, 0 },
1785 /* VT5xx */
1786 { nrc_Greek, '"', '>', 5, 9, 1 },
1787 { nrc_Hebrew, '%', '=', 5, 9, 1 },
1788 { nrc_Turkish, '%', '2', 5, 9, 1 },
1789 { nrc_DEC_Cyrillic, '&', '4', 5, 9, 0 },
1790 { nrc_DEC_Greek_Supp, '"', '?', 5, 9, 0 },
1791 { nrc_DEC_Hebrew_Supp, '"', '4', 5, 9, 0 },
1792 { nrc_DEC_Turkish_Supp, '%', '0', 5, 9, 0 },
1793 { nrc_ISO_Greek_Supp, 0, 'F', 5, 9, 0 },
1794 { nrc_ISO_Hebrew_Supp, 0, 'H', 5, 9, 0 },
1795 { nrc_ISO_Latin_2_Supp, 0, 'B', 5, 9, 0 },
1796 { nrc_ISO_Latin_5_Supp, 0, 'M', 5, 9, 0 },
1797 { nrc_ISO_Latin_Cyrillic,0, 'L', 5, 9, 0 },
1798 /* VT5xx (not implemented) */
1799 #if 0
1800 { nrc_Russian, '&', '5', 5, 9, 1 },
1801 { nrc_SCS_NRCS, '%', '3', 5, 9, 0 },
1802 #endif
1803 };
1804 /* *INDENT-ON* */
1805
1806 #if OPT_DEC_RECTOPS
1807 static char *
1808 encode_scs(DECNRCM_codes value)
1809 {
1810 static char buffer[3];
1811 Cardinal n;
1812 char *result = buffer;
1813 for (n = 0; n < XtNumber(scs_table); ++n) {
1814 if (scs_table[n].result == value) {
1815 if (scs_table[n].prefix)
1816 *result++ = (char) scs_table[n].prefix;
1817 if (scs_table[n].suffix)
1818 *result++ = (char) scs_table[n].suffix;
1819 break;
1820 }
1821 }
1822 *result = '\0';
1823 return buffer;
1824 }
1825 #endif
1826
1827 void
1828 xtermDecodeSCS(XtermWidget xw, int which, int sgroup, int prefix, int suffix)
1829 {
1830 TScreen *screen = TScreenOf(xw);
1831 Cardinal n;
1832 DECNRCM_codes result = nrc_Unknown;
1833
1834 suffix &= 0x7f;
1835 for (n = 0; n < XtNumber(scs_table); ++n) {
1836 if (prefix == scs_table[n].prefix
1837 && suffix == scs_table[n].suffix
1838 && sgroup == scs_table[n].min_level
1839 && screen->vtXX_level >= scs_table[n].min_level
1840 && screen->vtXX_level <= scs_table[n].max_level
1841 && (scs_table[n].need_nrc == 0 || (xw->flags & NATIONAL) != 0)) {
1842 result = scs_table[n].result;
1843 break;
1844 }
1845 }
1846 if (result != nrc_Unknown) {
1847 initCharset(screen, which, result);
1848 TRACE(("setting G%d to table #%d %s",
1849 which, n, visibleScsCode((int) result)));
1850 } else {
1851 TRACE(("...unknown GSET"));
1852 initCharset(screen, which, nrc_ASCII);
1853 }
1854 #if OPT_TRACE
1855 TRACE((" ("));
1856 if (prefix)
1857 TRACE(("prefix='%c', ", prefix));
1858 TRACE(("suffix='%c', sgroup=%d", suffix, sgroup));
1859 TRACE((")\n"));
1860 #endif
1861 }
1862
1863 /*
1864 * Given a parameter number, and subparameter (starting in each case from zero)
1865 * return the corresponding index into the parameter array. If the combination
1866 * is not found, return -1.
1867 */
1868 static int
1869 subparam_index(int p, int s)
1870 {
1871 int result = -1;
1872 int j, p2, s2;
1873
1874 for (j = p2 = 0; j < nparam; ++j, ++p2) {
1875 if (parms.is_sub[j]) {
1876 s2 = 0;
1877
1878 do {
1879 if ((p == p2) && (s == s2)) {
1880 result = j;
1881 break;
1882 }
1883 ++s2;
1884 } while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j]));
1885
1886 if (result >= 0)
1887 break;
1888
1889 --j; /* undo the last "while" */
1890 } else if (p == p2) {
1891 if (s == 0) {
1892 result = j;
1893 }
1894 break;
1895 }
1896 }
1897 TRACE2(("...subparam_index %d.%d = %d\n", p + 1, s + 1, result));
1898 return result;
1899 }
1900
1901 /*
1902 * Check if the given item in the parameter array has subparameters.
1903 * If so, return the number of subparameters to use as a loop limit, etc.
1904 */
1905 static int
1906 param_has_subparams(int item)
1907 {
1908 int result = 0;
1909 if (parms.has_subparams) {
1910 int n = subparam_index(item, 0);
1911 if (n >= 0 && parms.is_sub[n]) {
1912 while (++n < nparam && parms.is_sub[n - 1] < parms.is_sub[n]) {
1913 result++;
1914 }
1915 }
1916 }
1917 TRACE(("...param_has_subparams(%d) ->%d\n", item, result));
1918 return result;
1919 }
1920
1921 #if OPT_DIRECT_COLOR || OPT_256_COLORS || OPT_88_COLORS || OPT_ISO_COLORS
1922 /*
1923 * Given an index into the parameter array, return the corresponding parameter
1924 * number (starting from zero).
1925 */
1926 static int
1927 param_number(int item)
1928 {
1929 int result = -1;
1930 int j, p;
1931
1932 for (j = p = 0; j < nparam; ++j, ++p) {
1933 if (p >= item) {
1934 result = j;
1935 break;
1936 }
1937 if (parms.is_sub[j]) {
1938 while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j])) {
1939 /* EMPTY */
1940 }
1941 --j;
1942 }
1943 }
1944
1945 TRACE2(("...param_number(%d) = %d\n", item, result));
1946 return result;
1947 }
1948
1949 static int
1950 get_subparam(int p, int s)
1951 {
1952 int item = subparam_index(p, s);
1953 int result = (item >= 0) ? parms.params[item] : DEFAULT;
1954 TRACE(("...get_subparam[%d] = %d\n", item, result));
1955 return result;
1956 }
1957
1958 /*
1959 * Some background -
1960 *
1961 * Todd Larason provided the initial changes to support 256-colors in July 1999.
1962 * I pointed out that the description of SGR 38/48 in ECMA-48 was vague, and
1963 * was unsure if there would be some standard using those codes. His response
1964 * was that this was documented (it turns out, in equally vague terms) in ITU
1965 * T.416
1966 *
1967 * Discussing this with Todd Larason in mid-1999, my point was that given the
1968 * high cost of obtaining ITU T.416 (ISO-8613-6), the standard was not going
1969 * to be effective (more than $100 then, more than $200 in 2012)
1970 *
1971 * We overlooked the detail about ":" as a subparameter delimiter (documented
1972 * in 5.4.2 in ECMA-48). Some discussion in KDE in mid-2006 led Lars Doelle
1973 * to discuss the issue with me. Lars' initial concern dealt with the fact
1974 * that a sequence such as
1975 * CSI 38 ; 5 ; 1 m
1976 * violated the principle that SGR parameters could be used in any order.
1977 * Further discussion (see KDE #107487) resolved that the standard expected
1978 * that the sequence would look like
1979 * CSI 38 ; 5 : 1 m
1980 * which still violates that principle, since the "5:1" parameter has to
1981 * follow the "38" to be useful.
1982 *
1983 * This function accepts either format (per request by Paul Leonerd Evans).
1984 * It also accepts
1985 * CSI 38 : 5 : 1 m
1986 * according to Lars' original assumption. While implementing that, I added
1987 * support for Konsole's interpretation of "CSI 38 : 2" as a 24-bit RGB value.
1988 * ISO-8613-6 documents that as "direct color".
1989 *
1990 * At the time in 2012, no one noticed (or commented) regarding ISO-8613-6's
1991 * quirk in the description of direct color: it mentions a color space
1992 * identifier parameter which should follow the "2" (as parameter 1). In the
1993 * same section, ISO-8613-6 mentions a parameter 6 which can be ignored, as
1994 * well as parameters 7 and 8. Like parameter 1, parameters 7 and 8 are not
1995 * defined clearly in the standard, and a close reading indicates they are
1996 * optional, saying they "may be used". This implementation ignores parameters
1997 * 6 (and above), and provides for the color space identifier by checking the
1998 * number of parameters:
1999 * 3 after "2" (no color space identifier)
2000 * 4 or more after "2" (color space identifier)
2001 *
2002 * By the way - all of the parameters are decimal integers, and missing
2003 * parameters represent a default value. ISO-8613-6 is clear about that.
2004 *
2005 * Aside from ISO-8613-3, there is no standard use of ":" as a delimiter.
2006 * ECMA-48 says only:
2007 *
2008 * 5.4.2 Parameter string format
2009 *
2010 * A parameter string which does not start with a bit combination in the
2011 * range 03/12 to 03/15 shall have the following format:
2012 *
2013 * a) A parameter string consists of one or more parameter
2014 * sub-strings, each of which represents a number in decimal
2015 * notation.
2016 *
2017 * b) Each parameter sub-string consists of one or more bit
2018 * combinations from 03/00 to 03/10; the bit combinations from
2019 * 03/00 to 03/09 represent the digits ZERO to NINE; bit
2020 * combination 03/10 may be used as a separator in a parameter
2021 * sub-string, for example, to separate the fractional part of a
2022 * decimal number from the integer part of that number.
2023 *
2024 * That is, there is no mention in ECMA-48 of the possibility that a parameter
2025 * string might be a list of parameters, as done in ISO-8613-3 (nor does
2026 * ECMA-48 provide an example where the ":" separator might be used). Because
2027 * of this, xterm treats other cases than those needed for ISO-8613-3 as an
2028 * error, and stops interpreting the sequence.
2029 */
2030 #define extended_colors_limit(n) ((n) == 5 ? 1 : ((n) == 2 ? 3 : 0))
2031 static Boolean
2032 parse_extended_colors(XtermWidget xw, int *colorp, int *itemp, Boolean *extended)
2033 {
2034 Boolean result = False;
2035 int item = *itemp;
2036 int next = item;
2037 int base = param_number(item);
2038 int code = -1;
2039 int values[3]; /* maximum number of subparameters */
2040 int need = 0; /* number of subparameters needed */
2041 int have;
2042 int n;
2043
2044 /*
2045 * On entry, 'item' points to the 38/48 code in the parameter array.
2046 * If that has subparameters, we will expect all of the values to
2047 * be subparameters of that item.
2048 */
2049 if ((have = param_has_subparams(item)) != 0) {
2050 /* accept CSI 38 : 5 : 1 m */
2051 /* accept CSI 38 : 2 : 1 : 2 : 3 m */
2052 code = get_subparam(base, 1);
2053 need = extended_colors_limit(code);
2054 next = item + have;
2055 for (n = 0; n < need && n < 3; ++n) {
2056 values[n] = get_subparam(base, 2 + n + (have > 4));
2057 }
2058 } else if (++item < nparam) {
2059 ++base;
2060 if ((have = param_has_subparams(item)) != 0) {
2061 /* accept CSI 38 ; 5 : 1 m */
2062 /* accept CSI 38 ; 2 : 1 : 2 : 3 m */
2063 code = get_subparam(base, 0);
2064 need = extended_colors_limit(code);
2065 next = base + have;
2066 for (n = 0; n < need && n < 3; ++n) {
2067 values[n] = get_subparam(base, 1 + n + (have > 3));
2068 }
2069 } else {
2070 /* accept CSI 38 ; 5 ; 1 m */
2071 /* accept CSI 38 ; 2 ; 1 ; 2 ; 3 m */
2072 code = GetParam(item);
2073 need = extended_colors_limit(code);
2074 next = item + need;
2075 for (n = 0; n < need && n < 3; ++n) {
2076 values[n] = GetParam(item + 1 + n);
2077 }
2078 }
2079 }
2080 item = next;
2081
2082 *extended = False;
2083 switch (code) {
2084 case 2:
2085 /* direct color in rgb space */
2086 if ((values[0] >= 0 && values[0] < 256) &&
2087 (values[1] >= 0 && values[1] < 256) &&
2088 (values[2] >= 0 && values[2] < 256)) {
2089 #if OPT_DIRECT_COLOR
2090 if (TScreenOf(xw)->direct_color && xw->has_rgb) {
2091 *colorp = getDirectColor(xw, values[0], values[1], values[2]);
2092 result = True;
2093 *extended = True;
2094 } else
2095 #endif
2096 {
2097 *colorp = xtermClosestColor(xw, values[0], values[1], values[2]);
2098 result = okIndexedColor(*colorp);
2099 }
2100 } else {
2101 *colorp = -1;
2102 }
2103 break;
2104 case 5:
2105 /* indexed color */
2106 *colorp = values[0];
2107 result = okIndexedColor(*colorp);
2108 break;
2109 default:
2110 *colorp = -1;
2111 break;
2112 }
2113
2114 TRACE(("...resulting color %d/%d %s\n",
2115 *colorp, NUM_ANSI_COLORS,
2116 result ? "OK" : "ERR"));
2117
2118 *itemp = item;
2119 return result;
2120 }
2121 #endif /* ...extended_colors */
2122
2123 static int
2124 optional_param(int which)
2125 {
2126 return (nparam > which) ? GetParam(which) : DEFAULT;
2127 }
2128
2129 static int
2130 zero_if_default(int which)
2131 {
2132 int result = (nparam > which) ? GetParam(which) : 0;
2133 if (result <= 0)
2134 result = 0;
2135 return result;
2136 }
2137
2138 static int
2139 one_if_default(int which)
2140 {
2141 int result = (nparam > which) ? GetParam(which) : 0;
2142 if (result <= 0)
2143 result = 1;
2144 return result;
2145 }
2146
2147 /*
2148 * Color palette changes using the OSC controls require a repaint of the
2149 * screen - but not immediately. Do the repaint as soon as we detect a
2150 * state which will not lead to another color palette change.
2151 */
2152 static void
2153 repaintWhenPaletteChanged(XtermWidget xw, struct ParseState *sp)
2154 {
2155 Boolean ignore = False;
2156
2157 switch (sp->nextstate) {
2158 case CASE_ESC:
2159 ignore = ((sp->parsestate == ansi_table) ||
2160 (sp->parsestate == sos_table));
2161 #if USE_DOUBLE_BUFFER
2162 if (resource.buffered && TScreenOf(xw)->needSwap) {
2163 ignore = False;
2164 }
2165 #endif
2166 break;
2167 case CASE_OSC:
2168 ignore = ((sp->parsestate == ansi_table) ||
2169 (sp->parsestate == esc_table));
2170 break;
2171 case CASE_IGNORE:
2172 ignore = (sp->parsestate == sos_table);
2173 break;
2174 case CASE_ST:
2175 ignore = ((sp->parsestate == esc_table) ||
2176 (sp->parsestate == sos_table));
2177 break;
2178 case CASE_ESC_DIGIT:
2179 ignore = (sp->parsestate == csi_table);
2180 break;
2181 case CASE_ESC_SEMI:
2182 ignore = (sp->parsestate == csi2_table);
2183 break;
2184 }
2185
2186 if (!ignore) {
2187 TRACE(("repaintWhenPaletteChanged\n"));
2188 xw->work.palette_changed = False;
2189 xtermRepaint(xw);
2190 xtermFlushDbe(xw);
2191 }
2192 }
2193
2194 #if OPT_C1_PRINT || OPT_WIDE_CHARS
2195 #define ParseSOS(screen) ((screen)->c1_printable == 0)
2196 #else
2197 #define ParseSOS(screen) 0
2198 #endif
2199
2200 #define ResetState(sp) InitParams(), (sp)->parsestate = (sp)->groundtable
2201
2202 static void
2203 illegal_parse(XtermWidget xw, unsigned c, struct ParseState *sp)
2204 {
2205 ResetState(sp);
2206 sp->nextstate = sp->parsestate[E2A(c)];
2207 Bell(xw, XkbBI_MinorError, 0);
2208 }
2209
2210 static void
2211 init_parser(XtermWidget xw, struct ParseState *sp)
2212 {
2213 TScreen *screen = TScreenOf(xw);
2214
2215 free(sp->defer_area);
2216 free(sp->print_area);
2217 free(sp->string_area);
2218 memset(sp, 0, sizeof(*sp));
2219 sp->scssize = 94; /* number of printable/nonspace ASCII */
2220 sp->lastchar = -1; /* not a legal IChar */
2221 sp->nextstate = -1; /* not a legal state */
2222
2223 init_groundtable(screen, sp);
2224 ResetState(sp);
2225 }
2226
2227 static void
2228 init_reply(unsigned type)
2229 {
2230 memset(&reply, 0, sizeof(reply));
2231 reply.a_type = (Char) type;
2232 }
2233
2234 static void
2235 deferparsing(unsigned c, struct ParseState *sp)
2236 {
2237 SafeAlloc(Char, sp->defer_area, sp->defer_used, sp->defer_size);
2238 if (new_string == 0) {
2239 xtermWarning("Cannot allocate %lu bytes for deferred parsing of %u\n",
2240 (unsigned long) new_length, c);
2241 return;
2242 }
2243 SafeFree(sp->defer_area, sp->defer_size);
2244 sp->defer_area[(sp->defer_used)++] = CharOf(c);
2245 }
2246
2247 #if OPT_MOD_FKEYS
2248 static void
2249 set_mod_fkeys(XtermWidget xw, int which, int what, Bool enabled)
2250 {
2251 #define SET_MOD_FKEYS(field) \
2252 xw->keyboard.modify_now.field = ((what == DEFAULT) && enabled) \
2253 ? xw->keyboard.modify_1st.field \
2254 : what; \
2255 TRACE(("set modify_now.%s to %d\n", #field, \
2256 xw->keyboard.modify_now.field));
2257
2258 switch (which) {
2259 case 0:
2260 SET_MOD_FKEYS(allow_keys);
2261 break;
2262 case 1:
2263 SET_MOD_FKEYS(cursor_keys);
2264 break;
2265 case 2:
2266 SET_MOD_FKEYS(function_keys);
2267 break;
2268 case 3:
2269 SET_MOD_FKEYS(keypad_keys);
2270 break;
2271 case 4:
2272 SET_MOD_FKEYS(other_keys);
2273 break;
2274 case 5:
2275 SET_MOD_FKEYS(string_keys);
2276 break;
2277 }
2278 }
2279
2280 static void
2281 report_mod_fkeys(XtermWidget xw, int which) /* XTQMODKEYS */
2282 {
2283 #define GET_MOD_FKEYS(field) \
2284 reply.a_param[1] = (ParmType) xw->keyboard.modify_now.field
2285
2286 init_reply(ANSI_CSI);
2287 reply.a_pintro = '>'; /* replies look like a set-mode */
2288 reply.a_nparam = 2;
2289 reply.a_final = 'm';
2290
2291 reply.a_param[1] = DEFAULT;
2292 switch (reply.a_param[0] = (ParmType) which) {
2293 case 0:
2294 GET_MOD_FKEYS(allow_keys);
2295 break;
2296 case 1:
2297 GET_MOD_FKEYS(cursor_keys);
2298 break;
2299 case 2:
2300 GET_MOD_FKEYS(function_keys);
2301 break;
2302 case 3:
2303 GET_MOD_FKEYS(keypad_keys);
2304 break;
2305 case 4:
2306 GET_MOD_FKEYS(other_keys);
2307 break;
2308 case 5:
2309 GET_MOD_FKEYS(string_keys);
2310 break;
2311 }
2312 unparseseq(xw, &reply);
2313 }
2314 #endif /* OPT_MOD_FKEYS */
2315
2316 #if OPT_STATUS_LINE
2317 typedef enum {
2318 SLnone = 0, /* no status-line timer needed */
2319 SLclock = 1, /* status-line updates once/second */
2320 SLcoords = 2, /* status-line shows cursor-position */
2321 SLwritten = 3 /* status-line may need asynchronous repainting */
2322 } SL_MODE;
2323
2324 #define SL_BUFSIZ 80
2325
2326 #if OPT_TRACE
2327 static const char *
2328 visibleStatusType(int code)
2329 {
2330 const char *result = "?";
2331 switch (code) {
2332 case 0:
2333 result = "none";
2334 break;
2335 case 1:
2336 result = "indicator";
2337 break;
2338 case 2:
2339 result = "writable";
2340 break;
2341 }
2342 return result;
2343 }
2344
2345 static void
2346 trace_status_line(XtermWidget xw, int lineno, const char *tag)
2347 {
2348 TScreen *screen = TScreenOf(xw);
2349
2350 TRACE(("@%d, %s (%s, %s)%s%s @ (%d,%d) vs %d\n",
2351 lineno,
2352 tag,
2353 screen->status_active ? "active" : "inactive",
2354 visibleStatusType(screen->status_type),
2355 ((screen->status_type != screen->status_shown)
2356 ? " vs "
2357 : ""),
2358 ((screen->status_type != screen->status_shown)
2359 ? visibleStatusType(screen->status_shown)
2360 : ""),
2361 screen->cur_row,
2362 screen->cur_col,
2363 LastRowNumber(screen)));
2364 }
2365
2366 #define TRACE_SL(tag) trace_status_line(xw, __LINE__, tag)
2367 #else
2368 #define TRACE_SL(tag) /* nothing */
2369 #endif
2370
2371 static SL_MODE
2372 find_SL_MODE(XtermWidget xw)
2373 {
2374 TScreen *screen = TScreenOf(xw);
2375 SL_MODE result = SLnone;
2376 const char *parse;
2377
2378 for (parse = screen->status_fmt; *parse != '\0'; ++parse) {
2379 const char *found = parse;
2380 if (*parse == '%') {
2381 if (*++parse == L_CURL) {
2382 const char *check = strchr(parse, '%');
2383 size_t length = 0;
2384
2385 if (check != NULL && check[1] == R_CURL) {
2386 length = (size_t) (2 + check - found);
2387 } else {
2388 length = strlen(found);
2389 }
2390
2391 if (!strncmp(found, "%{unixtime%}", length)) {
2392 if (result == SLnone)
2393 result = SLclock;
2394 } else if (!strncmp(found, "%{position%}", length)) {
2395 result = SLcoords;
2396 }
2397 parse = found + length - 1;
2398 }
2399 #if defined(HAVE_STRFTIME)
2400 else if (*parse != '\0') {
2401 if (result == SLnone && strchr("cEgOrsSTX+", *parse) != NULL) {
2402 result = SLclock;
2403 }
2404 }
2405 #endif
2406 }
2407 }
2408 return result;
2409 }
2410
2411 static long
2412 find_SL_Timeout(XtermWidget xw)
2413 {
2414 long result = 0;
2415 switch (find_SL_MODE(xw)) {
2416 case SLnone:
2417 case SLwritten:
2418 break;
2419 case SLclock:
2420 result = 1000;
2421 break;
2422 case SLcoords:
2423 result = 80;
2424 break;
2425 }
2426 return result;
2427 }
2428
2429 static void
2430 StatusInit(SavedCursor * data)
2431 {
2432 memset(data, 0, sizeof(*data));
2433 data->sgr_foreground = -1;
2434 data->sgr_background = -1;
2435 }
2436
2437 /* save the status-line position, restore main display */
2438 static void
2439 StatusSave(XtermWidget xw)
2440 {
2441 TScreen *screen = TScreenOf(xw);
2442
2443 CursorSave2(xw, &screen->status_data[1]);
2444 CursorRestore2(xw, &screen->status_data[0]);
2445
2446 TRACE(("...StatusSave %d,%d -> %d,%d (main)\n",
2447 screen->status_data[1].row,
2448 screen->status_data[1].col,
2449 screen->cur_row,
2450 screen->cur_col));
2451 }
2452
2453 /* save the main-display position, restore status-line */
2454 static void
2455 StatusRestore(XtermWidget xw)
2456 {
2457 TScreen *screen = TScreenOf(xw);
2458
2459 CursorSave2(xw, &screen->status_data[0]);
2460 CursorRestore2(xw, &screen->status_data[1]);
2461 screen->cur_row = FirstRowNumber(screen);
2462
2463 TRACE(("...StatusRestore %d,%d -> %d,%d (status)\n",
2464 screen->status_data[0].row,
2465 screen->status_data[0].col,
2466 screen->cur_row,
2467 screen->cur_col));
2468 }
2469
2470 static void
2471 StatusPutChars(XtermWidget xw, const char *value, int length)
2472 {
2473 TScreen *screen = TScreenOf(xw);
2474
2475 if (length < 0)
2476 length = (int) strlen(value);
2477
2478 while (length > 0) {
2479 IChar buffer[SL_BUFSIZ + 1];
2480 Cardinal n;
2481 for (n = 0; n < SL_BUFSIZ && length > 0 && *value != '\0'; ++n) {
2482 buffer[n] = CharOf(*value++);
2483 if (buffer[n] < 32 || buffer[n] > 126)
2484 buffer[n] = ' '; /* FIXME - provide for UTF-8 */
2485 --length;
2486 }
2487 buffer[n] = 0;
2488 dotext(xw,
2489 screen->gsets[(int) (screen->curgl)],
2490 buffer, n);
2491 }
2492 }
2493
2494 static void
2495 show_indicator_status(XtPointer closure, XtIntervalId * id GCC_UNUSED)
2496 {
2497 XtermWidget xw = (XtermWidget) closure;
2498 TScreen *screen = TScreenOf(xw);
2499 int right_margin;
2500
2501 time_t now;
2502 const char *parse;
2503 char buffer[SL_BUFSIZ + 1];
2504 long interval;
2505
2506 if (screen->status_type != 1) {
2507 screen->status_timeout = False;
2508 return;
2509 }
2510 if (screen->status_active) {
2511 return;
2512 }
2513
2514 screen->status_active = True;
2515
2516 CursorSave2(xw, &screen->status_data[0]);
2517 screen->cur_row = FirstRowNumber(screen);
2518 screen->cur_col = 0;
2519
2520 xw->flags |= INVERSE;
2521 xw->flags &= (IFlags) (~WRAPAROUND);
2522
2523 now = time((time_t *) 0);
2524
2525 for (parse = screen->status_fmt; *parse != '\0'; ++parse) {
2526 const char *found = parse;
2527 if (*parse == '%') {
2528 if (*++parse == L_CURL) {
2529 const char *check = strchr(parse, '%');
2530 size_t length = 0;
2531
2532 if (check != NULL && check[1] == R_CURL) {
2533 length = (size_t) (2 + check - found);
2534 } else {
2535 length = strlen(found);
2536 }
2537
2538 if (!strncmp(found, "%{version%}", length)) {
2539 StatusPutChars(xw, xtermVersion(), -1);
2540 } else if (!strncmp(found, "%{unixtime%}", length)) {
2541 char *t = x_strtrim(ctime(&now));
2542 if (t != 0) {
2543 StatusPutChars(xw, t, -1);
2544 free(t);
2545 }
2546 } else if (!strncmp(found, "%{position%}", length)) {
2547 sprintf(buffer, "(%02d,%03d)",
2548 screen->status_data[0].row + 1,
2549 screen->status_data[0].col + 1);
2550 StatusPutChars(xw, buffer, -1);
2551 } else {
2552 StatusPutChars(xw, found, (int) length);
2553 }
2554 parse = found + length - 1;
2555 }
2556 #if defined(HAVE_STRFTIME)
2557 else if (*parse != '\0') {
2558 char format[3];
2559 struct tm *tm = localtime(&now);
2560
2561 format[0] = '%';
2562 format[1] = *parse;
2563 format[2] = '\0';
2564 if (strftime(buffer, sizeof(buffer) - 1, format, tm) != 0) {
2565 StatusPutChars(xw, buffer, -1);
2566 } else {
2567 StatusPutChars(xw, "?", 1);
2568 StatusPutChars(xw, parse - 1, 2);
2569 }
2570 }
2571 #endif
2572 } else {
2573 StatusPutChars(xw, parse, 1);
2574 }
2575 }
2576 right_margin = ScrnRightMargin(xw);
2577 memset(buffer, ' ', (size_t) SL_BUFSIZ);
2578 while (screen->cur_col < right_margin) {
2579 int chunk = Min(SL_BUFSIZ, (right_margin - screen->cur_col));
2580 StatusPutChars(xw, buffer, chunk);
2581 }
2582
2583 ScrnRefresh(xw, FirstRowNumber(screen), 0, 1, right_margin, True);
2584 screen->status_active = False;
2585
2586 CursorRestore2(xw, &screen->status_data[0]);
2587
2588 /* if we processed a position or date/time, repeat */
2589 interval = find_SL_Timeout(xw);
2590 if (interval > 0) {
2591 (void) XtAppAddTimeOut(app_con,
2592 (unsigned long) interval,
2593 show_indicator_status, xw);
2594 }
2595 screen->status_timeout = True;
2596 }
2597
2598 static void
2599 clear_status_line(XtermWidget xw)
2600 {
2601 TScreen *screen = TScreenOf(xw);
2602 SavedCursor save_me;
2603 SavedCursor clearit;
2604 int save_type = screen->status_type;
2605
2606 TRACE_SL("clear_status_line");
2607 StatusInit(&clearit);
2608 CursorSave2(xw, &save_me);
2609 CursorRestore2(xw, &clearit);
2610
2611 screen->status_type = 2;
2612 set_cur_row(screen, LastRowNumber(screen));
2613 #if 1
2614 ClearLine(xw);
2615 #else
2616 if (getLineData(screen, screen->cur_row) != NULL) {
2617 int n;
2618 char buffer[SL_BUFSIZ + 1];
2619 CLineData *ld = getLineData(screen, screen->cur_row);
2620 int right_margin = ScrnRightMargin(xw);
2621
2622 TRACE(("...text[%d:%d]:%s\n",
2623 screen->cur_row,
2624 LastRowNumber(screen),
2625 visibleIChars(ld->charData, ld->lineSize)));
2626
2627 memset(buffer, '#', SL_BUFSIZ);
2628 for (n = 0; n < screen->max_col; n += SL_BUFSIZ) {
2629 StatusPutChars(xw, buffer, right_margin - n);
2630 }
2631 }
2632 #endif
2633 CursorRestore2(xw, &save_me);
2634 screen->status_type = save_type;
2635 TRACE_SL("clear_status_line (done)");
2636 }
2637
2638 static void
2639 show_writable_status(XtermWidget xw)
2640 {
2641 TScreen *screen = TScreenOf(xw);
2642
2643 TRACE(("show_writable_status (%d:%d) max=%d\n",
2644 FirstRowNumber(screen),
2645 LastRowNumber(screen),
2646 MaxRows(screen)));
2647 screen->cur_row = FirstRowNumber(screen);
2648 }
2649
2650 /*
2651 * Depending the status-type, make the window grow or shrink by one row to
2652 * show or hide the status-line. Keep the rest of the window from scrolling
2653 * by overriding the resize-gravity.
2654 */
2655 static void
2656 resize_status_line(XtermWidget xw)
2657 {
2658 TScreen *screen = TScreenOf(xw);
2659 XtGravity savedGravity = xw->misc.resizeGravity;
2660
2661 TRACE_SL(screen->status_type
2662 ? "...resize to show status-line"
2663 : "...resize to hide status-line");
2664
2665 xw->misc.resizeGravity = NorthWestGravity;
2666
2667 RequestResize(xw, MaxRows(screen), MaxCols(screen), True);
2668
2669 xw->misc.resizeGravity = savedGravity;
2670 }
2671
2672 /*
2673 * DEC STD 070, chapter 14 "VSRM - Status Display Extension"
2674 */
2675 static void
2676 update_status_line(XtermWidget xw)
2677 {
2678 TScreen *screen = TScreenOf(xw);
2679
2680 TRACE_SL("update_status_line");
2681
2682 if (screen->status_type == 1) {
2683 if (screen->status_type != screen->status_shown) {
2684 if (screen->status_shown == 0) {
2685 resize_status_line(xw);
2686 } else {
2687 clear_status_line(xw);
2688 }
2689 screen->status_shown = screen->status_type;
2690 TRACE_SL("...updating shown");
2691 }
2692 show_indicator_status(xw, NULL);
2693 } else if (screen->status_active) {
2694 if (screen->status_type != screen->status_shown) {
2695 Boolean do_resize = False;
2696
2697 if (screen->status_type == 0) {
2698 if (screen->status_shown >= 2) {
2699 StatusSave(xw);
2700 }
2701 do_resize = True; /* shrink... */
2702 clear_status_line(xw);
2703 StatusInit(&screen->status_data[1]);
2704 } else if (screen->status_shown == 0) {
2705 if (screen->status_type >= 2) {
2706 StatusRestore(xw);
2707 }
2708 do_resize = True; /* grow... */
2709 } else {
2710 clear_status_line(xw);
2711 }
2712 if (do_resize) {
2713 resize_status_line(xw);
2714 }
2715 screen->status_shown = screen->status_type;
2716 TRACE_SL("...updating shown");
2717 }
2718 show_writable_status(xw);
2719 } else {
2720 if (screen->status_shown) {
2721 if (screen->status_type != 0 &&
2722 screen->status_type != screen->status_shown) {
2723 clear_status_line(xw);
2724 }
2725 if (screen->status_shown >= 2) {
2726 StatusSave(xw);
2727 }
2728 if (screen->status_type == 0) {
2729 screen->status_timeout = False;
2730 clear_status_line(xw);
2731 StatusInit(&screen->status_data[1]);
2732 resize_status_line(xw); /* shrink... */
2733 }
2734 screen->status_shown = screen->status_type;
2735 TRACE_SL("...updating shown");
2736 }
2737 }
2738 TRACE_SL("update_status_line (done)");
2739 }
2740
2741 /*
2742 * If the status-type is "2", we can switch the active status display back and
2743 * forth between the main-display and the status-line without clearing the
2744 * status-line (unless the status-line was not shown before).
2745 *
2746 * This has no effect if the status-line displays an indicator (type==1).
2747 */
2748 static void
2749 handle_DECSASD(XtermWidget xw, int value)
2750 {
2751 TScreen *screen = TScreenOf(xw);
2752 Boolean updates = value ? True : False;
2753
2754 TRACE(("CASE_DECSASD - select active status display: %s (currently %s)\n",
2755 BtoS(value),
2756 BtoS(screen->status_active)));
2757
2758 if (screen->status_active != updates) {
2759 screen->status_active = updates;
2760 if (screen->status_type != 1) {
2761 if (updates) {
2762 TRACE(("...@%d, saving main position %d,%d\n",
2763 __LINE__, screen->cur_row, screen->cur_col));
2764 CursorSave2(xw, &screen->status_data[0]);
2765 }
2766 update_status_line(xw);
2767 }
2768 }
2769 }
2770
2771 /*
2772 * If the status-line is inactive (i.e., only the main-display is used),
2773 * changing the status-type between none/writable has no immediate effect.
2774 *
2775 * But if the status-line is active, setting the status-type reinitializes the
2776 * status-line.
2777 *
2778 * Setting the status-type to indicator overrides the DECSASD active-display
2779 * mode.
2780 */
2781 static void
2782 handle_DECSSDT(XtermWidget xw, int value)
2783 {
2784 TScreen *screen = TScreenOf(xw);
2785
2786 TRACE(("CASE_DECSSDT - select type of status display: %d (currently %d)\n",
2787 value,
2788 screen->status_type));
2789 if (value <= 2) {
2790 screen->status_type = value;
2791 if (!screen->status_active) {
2792 TRACE(("...@%d, saving main position %d,%d\n",
2793 __LINE__, screen->cur_row, screen->cur_col));
2794 CursorSave2(xw, &screen->status_data[0]);
2795 }
2796 update_status_line(xw);
2797 }
2798 }
2799 #endif
2800
2801 #if OPT_VT52_MODE
2802 static void
2803 update_vt52_vt100_settings(void)
2804 {
2805 update_autowrap();
2806 update_reversewrap();
2807 update_autolinefeed();
2808 update_appcursor();
2809 update_appkeypad();
2810 update_allow132();
2811 }
2812 #endif
2813
2814 static Boolean
2815 doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
2816 {
2817 TScreen *screen = TScreenOf(xw);
2818 int item;
2819 int count;
2820 int value;
2821 int laststate;
2822 int thischar = -1;
2823 XTermRect myRect;
2824 #if OPT_DEC_RECTOPS
2825 int thispage = 1;
2826 #endif
2827
2828 if (sp->check_recur) {
2829 /* Defer parsing when parser is already running as the parser is not
2830 * safe to reenter.
2831 */
2832 deferparsing(c, sp);
2833 return True;
2834 }
2835 sp->check_recur++;
2836
2837 do {
2838 #if OPT_WIDE_CHARS
2839 int this_is_wide = 0;
2840 int is_formatter = 0;
2841
2842 /*
2843 * Handle zero-width combining characters. Make it faster by noting
2844 * that according to the Unicode charts, the majority of Western
2845 * character sets do not use this feature. There are some unassigned
2846 * codes at 0x242, but no zero-width characters until past 0x300.
2847 */
2848 if (c >= 0x300
2849 && screen->wide_chars
2850 && CharWidth(screen, c) == 0
2851 && !(is_formatter = (CharacterClass((int) c) == CNTRL))) {
2852 int prev, test;
2853 Boolean used = True;
2854 int use_row;
2855 int use_col;
2856
2857 WriteNow();
2858 use_row = (screen->char_was_written
2859 ? screen->last_written_row
2860 : screen->cur_row);
2861 use_col = (screen->char_was_written
2862 ? screen->last_written_col
2863 : screen->cur_col);
2864
2865 /*
2866 * Check if the latest data can be added to the base character.
2867 * If there is already a combining character stored for the cell,
2868 * we cannot, since that would change the order.
2869 */
2870 if (screen->normalized_c
2871 && !IsCellCombined(screen, use_row, use_col)) {
2872 prev = (int) XTERM_CELL(use_row, use_col);
2873 test = do_precomposition(prev, (int) c);
2874 TRACE(("do_precomposition (U+%04X [%d], U+%04X [%d]) -> U+%04X [%d]\n",
2875 prev, CharWidth(screen, prev),
2876 (int) c, CharWidth(screen, c),
2877 test, CharWidth(screen, test)));
2878 } else {
2879 prev = -1;
2880 test = -1;
2881 }
2882
2883 /* substitute combined character with precomposed character
2884 * only if it does not change the width of the base character
2885 */
2886 if (test != -1
2887 && CharWidth(screen, test) == CharWidth(screen, prev)) {
2888 putXtermCell(screen, use_row, use_col, test);
2889 } else if (screen->char_was_written
2890 || getXtermCell(screen, use_row, use_col) >= ' ') {
2891 addXtermCombining(screen, use_row, use_col, c);
2892 } else {
2893 /*
2894 * none of the above... we will add the combining character as
2895 * a base character.
2896 */
2897 used = False;
2898 }
2899
2900 if (used) {
2901 if (!screen->scroll_amt)
2902 ScrnUpdate(xw, use_row, use_col, 1, 1, 1);
2903 continue;
2904 }
2905 }
2906 #endif
2907
2908 /* Intercept characters for printer controller mode */
2909 if (PrinterOf(screen).printer_controlmode == 2) {
2910 if ((c = (unsigned) xtermPrinterControl(xw, (int) c)) == 0)
2911 continue;
2912 }
2913
2914 /*
2915 * VT52 is a little ugly in the one place it has a parameterized
2916 * control sequence, since the parameter falls after the character
2917 * that denotes the type of sequence.
2918 */
2919 #if OPT_VT52_MODE
2920 if (sp->vt52_cup) {
2921 if (nparam < NPARAM - 1) {
2922 SetParam(nparam++, (int) (c & 0x7f) - 32);
2923 parms.is_sub[nparam] = 0;
2924 }
2925 if (nparam < 2)
2926 continue;
2927 sp->vt52_cup = False;
2928 CursorSet(screen, zero_if_default(0), zero_if_default(1), xw->flags);
2929 sp->parsestate = vt52_table;
2930 SetParam(0, 0);
2931 SetParam(1, 0);
2932 continue;
2933 }
2934 #endif
2935
2936 laststate = sp->nextstate;
2937 if (c == ANSI_DEL
2938 && sp->parsestate == sp->groundtable
2939 && sp->scssize == 96
2940 && sp->scstype != 0) {
2941 /*
2942 * Handle special case of shifts for 96-character sets by checking
2943 * if we have a DEL. The other special case for SPACE will always
2944 * be printable.
2945 */
2946 sp->nextstate = CASE_PRINT;
2947 } else
2948 #if OPT_WIDE_CHARS
2949 if (c > 255) {
2950 /*
2951 * The parsing tables all have 256 entries. If we're supporting
2952 * wide characters, we handle them by treating them the same as
2953 * printing characters.
2954 */
2955 if (sp->parsestate == sp->groundtable) {
2956 sp->nextstate = is_formatter ? CASE_IGNORE : CASE_PRINT;
2957 } else if (sp->parsestate == sos_table) {
2958 c &= WIDEST_ICHAR;
2959 if (c > 255) {
2960 TRACE(("Found code > 255 while in SOS state: %04X\n", c));
2961 c = BAD_ASCII;
2962 }
2963 } else {
2964 sp->nextstate = CASE_GROUND_STATE;
2965 }
2966 } else
2967 #endif
2968 sp->nextstate = sp->parsestate[E2A(c)];
2969
2970 #if OPT_BROKEN_OSC
2971 /*
2972 * Linux console palette escape sequences start with an OSC, but do
2973 * not terminate correctly. Some scripts do not check before writing
2974 * them, making xterm appear to hang (it's awaiting a valid string
2975 * terminator). Just ignore these if we see them - there's no point
2976 * in emulating bad code.
2977 */
2978 if (screen->brokenLinuxOSC
2979 && sp->parsestate == sos_table) {
2980 if (sp->string_used) {
2981 switch (sp->string_area[0]) {
2982 case 'P':
2983 if (sp->string_used <= 7)
2984 break;
2985 /* FALLTHRU */
2986 case 'R':
2987 illegal_parse(xw, c, sp);
2988 TRACE(("Reset to ground state (brokenLinuxOSC)\n"));
2989 break;
2990 }
2991 }
2992 }
2993 #endif
2994
2995 #if OPT_BROKEN_ST
2996 /*
2997 * Before patch #171, carriage control embedded within an OSC string
2998 * would terminate it. Some (buggy, of course) applications rely on
2999 * this behavior. Accommodate them by allowing one to compile xterm
3000 * and emulate the old behavior.
3001 */
3002 if (screen->brokenStringTerm
3003 && sp->parsestate == sos_table
3004 && c < 32) {
3005 switch (c) {
3006 case ANSI_EOT: /* FALLTHRU */
3007 case ANSI_BS: /* FALLTHRU */
3008 case ANSI_HT: /* FALLTHRU */
3009 case ANSI_LF: /* FALLTHRU */
3010 case ANSI_VT: /* FALLTHRU */
3011 case ANSI_FF: /* FALLTHRU */
3012 case ANSI_CR: /* FALLTHRU */
3013 case ANSI_SO: /* FALLTHRU */
3014 case ANSI_SI: /* FALLTHRU */
3015 case ANSI_XON: /* FALLTHRU */
3016 case ANSI_CAN:
3017 illegal_parse(xw, c, sp);
3018 TRACE(("Reset to ground state (brokenStringTerm)\n"));
3019 break;
3020 }
3021 }
3022 #endif
3023
3024 #if OPT_C1_PRINT
3025 /*
3026 * This is not completely foolproof, but will allow an application
3027 * with values in the C1 range to use them as printable characters,
3028 * provided that they are not intermixed with an escape sequence.
3029 */
3030 if (screen->c1_printable
3031 && (c >= 128 && c < 256)) {
3032 sp->nextstate = (sp->parsestate == esc_table
3033 ? CASE_ESC_IGNORE
3034 : sp->parsestate[E2A(160)]);
3035 TRACE(("allowC1Printable %04X %s ->%s\n",
3036 c, which_table(sp->parsestate),
3037 visibleVTparse(sp->nextstate)));
3038 }
3039 #endif
3040
3041 #if OPT_WIDE_CHARS
3042 /*
3043 * If we have a C1 code and the c1_printable flag is not set, simply
3044 * ignore it when it was translated from UTF-8. That is because the
3045 * value could not have been present as-is in the UTF-8.
3046 *
3047 * To see that CASE_IGNORE is a consistent value, note that it is
3048 * always used for NUL and other uninteresting C0 controls.
3049 */
3050 #if OPT_C1_PRINT
3051 if (!screen->c1_printable)
3052 #endif
3053 if (screen->wide_chars
3054 && (c >= 128 && c < 160)) {
3055 sp->nextstate = CASE_IGNORE;
3056 }
3057
3058 /*
3059 * If this character is a different width than the last one, put the
3060 * previous text into the buffer and draw it now.
3061 */
3062 this_is_wide = isWide((int) c);
3063 if (this_is_wide != sp->last_was_wide) {
3064 WriteNow();
3065 }
3066 #endif
3067
3068 /*
3069 * Accumulate string for printable text. This may be 8/16-bit
3070 * characters.
3071 */
3072 if (sp->nextstate == CASE_PRINT) {
3073 SafeAlloc(IChar, sp->print_area, sp->print_used, sp->print_size);
3074 if (new_string == 0) {
3075 xtermWarning("Cannot allocate %lu bytes for printable text\n",
3076 (unsigned long) new_length);
3077 continue;
3078 }
3079 SafeFree(sp->print_area, sp->print_size);
3080 #if OPT_VT52_MODE
3081 /*
3082 * Strip output text to 7-bits for VT52. We should do this for
3083 * VT100 also (which is a 7-bit device), but xterm has been
3084 * doing this for so long we shouldn't change this behavior.
3085 */
3086 if (screen->vtXX_level < 1)
3087 c &= 0x7f;
3088 #endif
3089 sp->print_area[sp->print_used++] = (IChar) c;
3090 sp->lastchar = thischar = (int) c;
3091 #if OPT_WIDE_CHARS
3092 sp->last_was_wide = this_is_wide;
3093 #endif
3094 if (morePtyData(screen, VTbuffer)) {
3095 continue;
3096 }
3097 }
3098
3099 if (sp->nextstate == CASE_PRINT
3100 || (laststate == CASE_PRINT && sp->print_used)) {
3101 WriteNow();
3102 }
3103
3104 /*
3105 * Accumulate string for APC, DCS, PM, OSC, SOS controls
3106 * This should always be 8-bit characters.
3107 */
3108 if (sp->parsestate == sos_table) {
3109 SafeAlloc(Char, sp->string_area, sp->string_used, sp->string_size);
3110 if (new_string == 0) {
3111 xtermWarning("Cannot allocate %lu bytes for string mode %d\n",
3112 (unsigned long) new_length, sp->string_mode);
3113 continue;
3114 }
3115 SafeFree(sp->string_area, sp->string_size);
3116 #if OPT_WIDE_CHARS
3117 /*
3118 * We cannot display codes above 255, but let's try to
3119 * accommodate the application a little by not aborting the
3120 * string.
3121 */
3122 if ((c & WIDEST_ICHAR) > 255) {
3123 sp->nextstate = CASE_PRINT;
3124 c = BAD_ASCII;
3125 }
3126 #endif
3127 sp->string_area[(sp->string_used)++] = CharOf(c);
3128 } else if (sp->parsestate != esc_table) {
3129 /* if we were accumulating, we're not any more */
3130 sp->string_mode = 0;
3131 sp->string_used = 0;
3132 }
3133
3134 DumpParams();
3135 TRACE(("parse %04X -> %s %s (used=%lu)\n",
3136 c, visibleVTparse(sp->nextstate),
3137 which_table(sp->parsestate),
3138 (unsigned long) sp->string_used));
3139
3140 /*
3141 * If the parameter list has subparameters (tokens separated by ":")
3142 * reject any controls that do not accept subparameters.
3143 */
3144 if (parms.has_subparams) {
3145 switch (sp->nextstate) {
3146 case CASE_GROUND_STATE:
3147 case CASE_CSI_IGNORE:
3148 /* FALLTHRU */
3149
3150 case CASE_ESC_DIGIT:
3151 case CASE_ESC_SEMI:
3152 case CASE_ESC_COLON:
3153 /* these states are required to parse parameter lists */
3154 break;
3155
3156 case CASE_SGR:
3157 TRACE(("...possible subparam usage\n"));
3158 break;
3159
3160 case CASE_CSI_DEC_DOLLAR_STATE:
3161 case CASE_CSI_DOLLAR_STATE:
3162 case CASE_CSI_HASH_STATE:
3163 case CASE_CSI_EX_STATE:
3164 case CASE_CSI_QUOTE_STATE:
3165 case CASE_CSI_SPACE_STATE:
3166 case CASE_CSI_STAR_STATE:
3167 case CASE_CSI_TICK_STATE:
3168 case CASE_DEC2_STATE:
3169 case CASE_DEC3_STATE:
3170 case CASE_DEC_STATE:
3171 /* use this branch when we do not yet have the final character */
3172 TRACE(("...unexpected subparam usage\n"));
3173 InitParams();
3174 sp->nextstate = CASE_CSI_IGNORE;
3175 break;
3176
3177 default:
3178 /* use this branch for cases where we have the final character
3179 * in the table that processed the parameter list.
3180 */
3181 TRACE(("...unexpected subparam usage\n"));
3182 ResetState(sp);
3183 continue;
3184 }
3185 }
3186
3187 if (xw->work.palette_changed) {
3188 repaintWhenPaletteChanged(xw, sp);
3189 }
3190 #if OPT_STATUS_LINE
3191 /*
3192 * If we are currently writing to the status-line, ignore controls that
3193 * apply only to the full screen, or which use features which we will
3194 * not support in the status-line.
3195 */
3196 if (IsStatusShown(screen) && (screen)->status_active) {
3197 switch (sp->nextstate) {
3198 case CASE_DECDHL:
3199 case CASE_DECSWL:
3200 case CASE_DECDWL:
3201 case CASE_CUU:
3202 case CASE_CUD:
3203 case CASE_VPA:
3204 case CASE_VPR:
3205 case CASE_ED:
3206 case CASE_TRACK_MOUSE:
3207 case CASE_DECSTBM:
3208 case CASE_DECALN:
3209 case CASE_GRAPHICS_ATTRIBUTES:
3210 case CASE_SPA:
3211 case CASE_EPA:
3212 case CASE_SU:
3213 case CASE_IND:
3214 case CASE_CPL:
3215 case CASE_CNL:
3216 case CASE_NEL:
3217 case CASE_RI:
3218 #if OPT_DEC_LOCATOR
3219 case CASE_DECEFR:
3220 case CASE_DECELR:
3221 case CASE_DECSLE:
3222 case CASE_DECRQLP:
3223 #endif
3224 #if OPT_DEC_RECTOPS
3225 case CASE_DECRQCRA:
3226 case CASE_DECCRA:
3227 case CASE_DECERA:
3228 case CASE_DECFRA:
3229 case CASE_DECSERA:
3230 case CASE_DECSACE:
3231 case CASE_DECCARA:
3232 case CASE_DECRARA:
3233 #endif
3234 ResetState(sp);
3235 sp->nextstate = -1; /* not a legal state */
3236 break;
3237 }
3238 }
3239 #endif
3240
3241 switch (sp->nextstate) {
3242 case CASE_PRINT:
3243 TRACE(("CASE_PRINT - printable characters\n"));
3244 break;
3245
3246 case CASE_GROUND_STATE:
3247 TRACE(("CASE_GROUND_STATE - exit ignore mode\n"));
3248 ResetState(sp);
3249 break;
3250
3251 case CASE_IGNORE:
3252 TRACE(("CASE_IGNORE - Ignore character %02X\n", c));
3253 break;
3254
3255 case CASE_ENQ:
3256 TRACE(("CASE_ENQ - answerback\n"));
3257 if (((xw->keyboard.flags & MODE_SRM) == 0)
3258 ? (sp->check_recur == 0)
3259 : (sp->check_recur <= 1)) {
3260 for (count = 0; screen->answer_back[count] != 0; count++)
3261 unparseputc(xw, screen->answer_back[count]);
3262 unparse_end(xw);
3263 }
3264 break;
3265
3266 case CASE_BELL:
3267 TRACE(("CASE_BELL - bell\n"));
3268 if (sp->string_mode == ANSI_OSC) {
3269 if (sp->string_used)
3270 sp->string_area[--(sp->string_used)] = '\0';
3271 if (sp->check_recur <= 1)
3272 do_osc(xw, sp->string_area, sp->string_used, (int) c);
3273 ResetState(sp);
3274 } else {
3275 /* bell */
3276 Bell(xw, XkbBI_TerminalBell, 0);
3277 }
3278 break;
3279
3280 case CASE_BS:
3281 TRACE(("CASE_BS - backspace\n"));
3282 CursorBack(xw, 1);
3283 break;
3284
3285 case CASE_CR:
3286 TRACE(("CASE_CR\n"));
3287 CarriageReturn(xw);
3288 break;
3289
3290 case CASE_ESC:
3291 if_OPT_VT52_MODE(screen, {
3292 sp->parsestate = vt52_esc_table;
3293 break;
3294 });
3295 sp->parsestate = esc_table;
3296 break;
3297
3298 #if OPT_VT52_MODE
3299 case CASE_VT52_CUP:
3300 TRACE(("CASE_VT52_CUP - VT52 cursor addressing\n"));
3301 sp->vt52_cup = True;
3302 ResetState(sp);
3303 break;
3304
3305 case CASE_VT52_IGNORE:
3306 TRACE(("CASE_VT52_IGNORE - VT52 ignore-character\n"));
3307 sp->parsestate = vt52_ignore_table;
3308 break;
3309 #endif
3310
3311 case CASE_VMOT:
3312 TRACE(("CASE_VMOT\n"));
3313 /*
3314 * form feed, line feed, vertical tab
3315 */
3316 xtermAutoPrint(xw, c);
3317 xtermIndex(xw, 1);
3318 if (xw->flags & LINEFEED)
3319 CarriageReturn(xw);
3320 else
3321 do_xevents(xw);
3322 break;
3323
3324 case CASE_CBT:
3325 TRACE(("CASE_CBT\n"));
3326 /* cursor backward tabulation */
3327 count = one_if_default(0);
3328 while ((count-- > 0)
3329 && (TabToPrevStop(xw))) ;
3330 ResetState(sp);
3331 break;
3332
3333 case CASE_CHT:
3334 TRACE(("CASE_CHT\n"));
3335 /* cursor forward tabulation */
3336 count = one_if_default(0);
3337 while ((count-- > 0)
3338 && (TabToNextStop(xw))) ;
3339 ResetState(sp);
3340 break;
3341
3342 case CASE_TAB:
3343 /* tab */
3344 TabToNextStop(xw);
3345 break;
3346
3347 case CASE_SI:
3348 screen->curgl = 0;
3349 if_OPT_VT52_MODE(screen, {
3350 ResetState(sp);
3351 });
3352 break;
3353
3354 case CASE_SO:
3355 screen->curgl = 1;
3356 if_OPT_VT52_MODE(screen, {
3357 ResetState(sp);
3358 });
3359 break;
3360
3361 case CASE_DECDHL:
3362 xterm_DECDHL(xw, c == '3');
3363 ResetState(sp);
3364 break;
3365
3366 case CASE_DECSWL:
3367 xterm_DECSWL(xw);
3368 ResetState(sp);
3369 break;
3370
3371 case CASE_DECDWL:
3372 xterm_DECDWL(xw);
3373 ResetState(sp);
3374 break;
3375
3376 case CASE_SCR_STATE:
3377 /* enter scr state */
3378 sp->parsestate = scrtable;
3379 break;
3380
3381 case CASE_SCS0_STATE:
3382 /* enter scs state 0 */
3383 select_charset(sp, 0, 94);
3384 break;
3385
3386 case CASE_SCS1_STATE:
3387 /* enter scs state 1 */
3388 select_charset(sp, 1, 94);
3389 break;
3390
3391 case CASE_SCS2_STATE:
3392 /* enter scs state 2 */
3393 select_charset(sp, 2, 94);
3394 break;
3395
3396 case CASE_SCS3_STATE:
3397 /* enter scs state 3 */
3398 select_charset(sp, 3, 94);
3399 break;
3400
3401 case CASE_SCS1A_STATE:
3402 /* enter scs state 1 */
3403 select_charset(sp, 1, 96);
3404 break;
3405
3406 case CASE_SCS2A_STATE:
3407 /* enter scs state 2 */
3408 select_charset(sp, 2, 96);
3409 break;
3410
3411 case CASE_SCS3A_STATE:
3412 /* enter scs state 3 */
3413 select_charset(sp, 3, 96);
3414 break;
3415
3416 case CASE_ESC_IGNORE:
3417 /* unknown escape sequence */
3418 sp->parsestate = eigtable;
3419 break;
3420
3421 case CASE_ESC_DIGIT:
3422 /* digit in csi or dec mode */
3423 if (nparam > 0) {
3424 value = zero_if_default(nparam - 1);
3425 SetParam(nparam - 1, (10 * value) + ((int) c - '0'));
3426 if (GetParam(nparam - 1) > MAX_I_PARAM)
3427 SetParam(nparam - 1, MAX_I_PARAM);
3428 if (sp->parsestate == csi_table)
3429 sp->parsestate = csi2_table;
3430 }
3431 break;
3432
3433 case CASE_ESC_SEMI:
3434 /* semicolon in csi or dec mode */
3435 if (nparam < NPARAM) {
3436 parms.is_sub[nparam] = 0;
3437 SetParam(nparam++, DEFAULT);
3438 }
3439 if (sp->parsestate == csi_table)
3440 sp->parsestate = csi2_table;
3441 break;
3442
3443 /*
3444 * A _few_ commands accept colon-separated subparameters.
3445 * Mark the parameter list so that we can exclude (most) bogus
3446 * commands with simple/fast checks.
3447 */
3448 case CASE_ESC_COLON:
3449 if (nparam < NPARAM) {
3450 parms.has_subparams = 1;
3451 if (nparam == 0) {
3452 parms.is_sub[nparam] = 1;
3453 SetParam(nparam++, DEFAULT);
3454 } else if (parms.is_sub[nparam - 1] == 0) {
3455 parms.is_sub[nparam - 1] = 1;
3456 parms.is_sub[nparam] = 2;
3457 parms.params[nparam] = 0;
3458 ++nparam;
3459 } else {
3460 parms.is_sub[nparam] = 1 + parms.is_sub[nparam - 1];
3461 parms.params[nparam] = 0;
3462 ++nparam;
3463 }
3464 }
3465 break;
3466
3467 case CASE_DEC_STATE:
3468 /* enter dec mode */
3469 sp->parsestate = dec_table;
3470 break;
3471
3472 case CASE_DEC2_STATE:
3473 /* enter dec2 mode */
3474 sp->parsestate = dec2_table;
3475 break;
3476
3477 case CASE_DEC3_STATE:
3478 /* enter dec3 mode */
3479 sp->parsestate = dec3_table;
3480 break;
3481
3482 case CASE_ICH:
3483 TRACE(("CASE_ICH - insert char\n"));
3484 InsertChar(xw, (unsigned) one_if_default(0));
3485 ResetState(sp);
3486 break;
3487
3488 case CASE_CUU:
3489 TRACE(("CASE_CUU - cursor up\n"));
3490 CursorUp(screen, one_if_default(0));
3491 ResetState(sp);
3492 break;
3493
3494 case CASE_CUD:
3495 TRACE(("CASE_CUD - cursor down\n"));
3496 CursorDown(screen, one_if_default(0));
3497 ResetState(sp);
3498 break;
3499
3500 case CASE_CUF:
3501 TRACE(("CASE_CUF - cursor forward\n"));
3502 CursorForward(xw, one_if_default(0));
3503 ResetState(sp);
3504 break;
3505
3506 case CASE_CUB:
3507 TRACE(("CASE_CUB - cursor backward\n"));
3508 CursorBack(xw, one_if_default(0));
3509 ResetState(sp);
3510 break;
3511
3512 case CASE_CUP:
3513 TRACE(("CASE_CUP - cursor position\n"));
3514 if_OPT_XMC_GLITCH(screen, {
3515 Jump_XMC(xw);
3516 });
3517 CursorSet(screen, one_if_default(0) - 1, one_if_default(1) - 1, xw->flags);
3518 ResetState(sp);
3519 break;
3520
3521 case CASE_VPA:
3522 TRACE(("CASE_VPA - vertical position absolute\n"));
3523 CursorSet(screen, one_if_default(0) - 1, CursorCol(xw), xw->flags);
3524 ResetState(sp);
3525 break;
3526
3527 case CASE_HPA:
3528 TRACE(("CASE_HPA - horizontal position absolute\n"));
3529 CursorSet(screen, CursorRow(xw), one_if_default(0) - 1, xw->flags);
3530 ResetState(sp);
3531 break;
3532
3533 case CASE_VPR:
3534 TRACE(("CASE_VPR - vertical position relative\n"));
3535 CursorSet(screen,
3536 CursorRow(xw) + one_if_default(0),
3537 CursorCol(xw),
3538 xw->flags);
3539 ResetState(sp);
3540 break;
3541
3542 case CASE_HPR:
3543 TRACE(("CASE_HPR - horizontal position relative\n"));
3544 CursorSet(screen,
3545 CursorRow(xw),
3546 CursorCol(xw) + one_if_default(0),
3547 xw->flags);
3548 ResetState(sp);
3549 break;
3550
3551 case CASE_HP_BUGGY_LL:
3552 TRACE(("CASE_HP_BUGGY_LL\n"));
3553 /* Some HP-UX applications have the bug that they
3554 assume ESC F goes to the lower left corner of
3555 the screen, regardless of what terminfo says. */
3556 if (screen->hp_ll_bc)
3557 CursorSet(screen, screen->max_row, 0, xw->flags);
3558 ResetState(sp);
3559 break;
3560
3561 case CASE_ED:
3562 TRACE(("CASE_ED - erase display\n"));
3563 do_cd_xtra_scroll(xw, zero_if_default(0));
3564 do_erase_display(xw, zero_if_default(0), OFF_PROTECT);
3565 ResetState(sp);
3566 break;
3567
3568 case CASE_EL:
3569 TRACE(("CASE_EL - erase line\n"));
3570 do_erase_line(xw, zero_if_default(0), OFF_PROTECT);
3571 ResetState(sp);
3572 break;
3573
3574 case CASE_ECH:
3575 TRACE(("CASE_ECH - erase char\n"));
3576 /* ECH */
3577 do_erase_char(xw, one_if_default(0), OFF_PROTECT);
3578 ResetState(sp);
3579 break;
3580
3581 case CASE_IL:
3582 TRACE(("CASE_IL - insert line\n"));
3583 InsertLine(xw, one_if_default(0));
3584 ResetState(sp);
3585 break;
3586
3587 case CASE_DL:
3588 TRACE(("CASE_DL - delete line\n"));
3589 DeleteLine(xw, one_if_default(0), True);
3590 ResetState(sp);
3591 break;
3592
3593 case CASE_DCH:
3594 TRACE(("CASE_DCH - delete char\n"));
3595 DeleteChar(xw, (unsigned) one_if_default(0));
3596 ResetState(sp);
3597 break;
3598
3599 case CASE_TRACK_MOUSE:
3600 /*
3601 * A single parameter other than zero is always scroll-down.
3602 * A zero-parameter is used to reset the mouse mode, and is
3603 * not useful for scrolling anyway.
3604 */
3605 if (nparam > 1 || GetParam(0) == 0) {
3606 CELL start;
3607
3608 TRACE(("CASE_TRACK_MOUSE\n"));
3609 /* Track mouse as long as in window and between
3610 * specified rows
3611 */
3612 start.row = one_if_default(2) - 1;
3613 start.col = GetParam(1) - 1;
3614 TrackMouse(xw,
3615 GetParam(0),
3616 &start,
3617 GetParam(3) - 1, GetParam(4) - 2);
3618 } else {
3619 TRACE(("CASE_SD - scroll down\n"));
3620 /* SD */
3621 RevScroll(xw, one_if_default(0));
3622 do_xevents(xw);
3623 }
3624 ResetState(sp);
3625 break;
3626
3627 case CASE_SD:
3628 /*
3629 * Cater to ECMA-48's typographical error...
3630 */
3631 TRACE(("CASE_SD - scroll down\n"));
3632 RevScroll(xw, one_if_default(0));
3633 do_xevents(xw);
3634 ResetState(sp);
3635 break;
3636
3637 case CASE_DECID:
3638 TRACE(("CASE_DECID\n"));
3639 if_OPT_VT52_MODE(screen, {
3640 unparseputc(xw, ANSI_ESC);
3641 unparseputc(xw, '/');
3642 unparseputc(xw, 'Z');
3643 unparse_end(xw);
3644 ResetState(sp);
3645 break;
3646 });
3647 SetParam(0, DEFAULT); /* Default ID parameter */
3648 /* FALLTHRU */
3649 case CASE_DA1:
3650 TRACE(("CASE_DA1\n"));
3651 if (GetParam(0) <= 0) { /* less than means DEFAULT */
3652 count = 0;
3653 init_reply(ANSI_CSI);
3654 reply.a_pintro = '?';
3655
3656 /*
3657 * The first parameter corresponds to the highest operating
3658 * level (i.e., service level) of the emulation. A DEC
3659 * terminal can be setup to respond with a different DA
3660 * response, but there's no control sequence that modifies
3661 * this. We set it via a resource.
3662 */
3663 if (screen->terminal_id < 200) {
3664 switch (screen->terminal_id) {
3665 case 132:
3666 reply.a_param[count++] = 4; /* VT132 */
3667 #if OPT_REGIS_GRAPHICS
3668 reply.a_param[count++] = 6; /* no STP, AVO, GPO (ReGIS) */
3669 #else
3670 reply.a_param[count++] = 2; /* no STP, AVO, no GPO (ReGIS) */
3671 #endif
3672 break;
3673 case 131:
3674 reply.a_param[count++] = 7; /* VT131 */
3675 break;
3676 case 125:
3677 reply.a_param[count++] = 12; /* VT125 */
3678 #if OPT_REGIS_GRAPHICS
3679 reply.a_param[count++] = 0 | 2 | 1; /* no STP, AVO, GPO (ReGIS) */
3680 #else
3681 reply.a_param[count++] = 0 | 2 | 0; /* no STP, AVO, no GPO (ReGIS) */
3682 #endif
3683 reply.a_param[count++] = 0; /* no printer */
3684 reply.a_param[count++] = XTERM_PATCH; /* ROM version */
3685 break;
3686 case 102:
3687 reply.a_param[count++] = 6; /* VT102 */
3688 break;
3689 case 101:
3690 reply.a_param[count++] = 1; /* VT101 */
3691 reply.a_param[count++] = 0; /* no options */
3692 break;
3693 default: /* VT100 */
3694 reply.a_param[count++] = 1; /* VT100 */
3695 reply.a_param[count++] = 2; /* no STP, AVO, no GPO (ReGIS) */
3696 break;
3697 }
3698 } else {
3699 reply.a_param[count++] = (ParmType) (60
3700 + screen->terminal_id
3701 / 100);
3702 reply.a_param[count++] = 1; /* 132-columns */
3703 reply.a_param[count++] = 2; /* printer */
3704 #if OPT_REGIS_GRAPHICS
3705 if (optRegisGraphics(screen)) {
3706 reply.a_param[count++] = 3; /* ReGIS graphics */
3707 }
3708 #endif
3709 #if OPT_SIXEL_GRAPHICS
3710 if (optSixelGraphics(screen)) {
3711 reply.a_param[count++] = 4; /* sixel graphics */
3712 }
3713 #endif
3714 reply.a_param[count++] = 6; /* selective-erase */
3715 #if OPT_SUNPC_KBD
3716 if (xw->keyboard.type == keyboardIsVT220)
3717 #endif
3718 reply.a_param[count++] = 8; /* user-defined-keys */
3719 reply.a_param[count++] = 9; /* national replacement charsets */
3720 reply.a_param[count++] = 15; /* technical characters */
3721 reply.a_param[count++] = 16; /* locator port */
3722 if (screen->terminal_id >= 400) {
3723 reply.a_param[count++] = 17; /* terminal state interrogation */
3724 reply.a_param[count++] = 18; /* windowing extension */
3725 reply.a_param[count++] = 21; /* horizontal scrolling */
3726 }
3727 if_OPT_ISO_COLORS(screen, {
3728 reply.a_param[count++] = 22; /* ANSI color, VT525 */
3729 });
3730 reply.a_param[count++] = 28; /* rectangular editing */
3731 #if OPT_DEC_LOCATOR
3732 reply.a_param[count++] = 29; /* ANSI text locator */
3733 #endif
3734 }
3735 reply.a_nparam = (ParmType) count;
3736 reply.a_final = 'c';
3737 unparseseq(xw, &reply);
3738 }
3739 ResetState(sp);
3740 break;
3741
3742 case CASE_DA2:
3743 TRACE(("CASE_DA2\n"));
3744 if (GetParam(0) <= 0) { /* less than means DEFAULT */
3745 count = 0;
3746 init_reply(ANSI_CSI);
3747 reply.a_pintro = '>';
3748
3749 if (screen->terminal_id >= 200) {
3750 switch (screen->terminal_id) {
3751 case 220:
3752 default:
3753 reply.a_param[count++] = 1; /* VT220 */
3754 break;
3755 case 240:
3756 case 241:
3757 /* http://www.decuslib.com/DECUS/vax87a/gendyn/vt200_kind.lis */
3758 reply.a_param[count++] = 2; /* VT240 */
3759 break;
3760 case 320:
3761 /* http://www.vt100.net/docs/vt320-uu/appendixe.html */
3762 reply.a_param[count++] = 24; /* VT320 */
3763 break;
3764 case 330:
3765 reply.a_param[count++] = 18; /* VT330 */
3766 break;
3767 case 340:
3768 reply.a_param[count++] = 19; /* VT340 */
3769 break;
3770 case 382:
3771 reply.a_param[count++] = 32; /* VT382 */
3772 break;
3773 case 420:
3774 reply.a_param[count++] = 41; /* VT420 */
3775 break;
3776 case 510:
3777 /* http://www.vt100.net/docs/vt510-rm/DA2 */
3778 reply.a_param[count++] = 61; /* VT510 */
3779 break;
3780 case 520:
3781 reply.a_param[count++] = 64; /* VT520 */
3782 break;
3783 case 525:
3784 reply.a_param[count++] = 65; /* VT525 */
3785 break;
3786 }
3787 } else {
3788 reply.a_param[count++] = 0; /* VT100 (nonstandard) */
3789 }
3790 reply.a_param[count++] = XTERM_PATCH; /* Version */
3791 reply.a_param[count++] = 0; /* options (none) */
3792 reply.a_nparam = (ParmType) count;
3793 reply.a_final = 'c';
3794 unparseseq(xw, &reply);
3795 }
3796 ResetState(sp);
3797 break;
3798
3799 case CASE_DECRPTUI:
3800 TRACE(("CASE_DECRPTUI\n"));
3801 if ((screen->vtXX_level >= 4)
3802 && (GetParam(0) <= 0)) { /* less than means DEFAULT */
3803 unparseputc1(xw, ANSI_DCS);
3804 unparseputc(xw, '!');
3805 unparseputc(xw, '|');
3806 /* report the "terminal unit id" as 4 pairs of hexadecimal
3807 * digits -- meaningless for a terminal emulator, but some
3808 * host may care about the format.
3809 */
3810 for (count = 0; count < 8; ++count) {
3811 unparseputc(xw, '0');
3812 }
3813 unparseputc1(xw, ANSI_ST);
3814 unparse_end(xw);
3815 }
3816 ResetState(sp);
3817 break;
3818
3819 case CASE_TBC:
3820 TRACE(("CASE_TBC - tab clear\n"));
3821 if ((value = GetParam(0)) <= 0) /* less than means default */
3822 TabClear(xw->tabs, screen->cur_col);
3823 else if (value == 3)
3824 TabZonk(xw->tabs);
3825 ResetState(sp);
3826 break;
3827
3828 case CASE_SET:
3829 TRACE(("CASE_SET - set mode\n"));
3830 ansi_modes(xw, bitset);
3831 ResetState(sp);
3832 break;
3833
3834 case CASE_RST:
3835 TRACE(("CASE_RST - reset mode\n"));
3836 ansi_modes(xw, bitclr);
3837 ResetState(sp);
3838 break;
3839
3840 case CASE_SGR:
3841 for (item = 0; item < nparam; ++item) {
3842 int op = GetParam(item);
3843 int skip;
3844
3845 if_OPT_XMC_GLITCH(screen, {
3846 Mark_XMC(xw, op);
3847 });
3848 TRACE(("CASE_SGR %d\n", op));
3849
3850 /*
3851 * Only SGR 38/48 accept subparameters, and in those cases
3852 * the values will not be seen at this point.
3853 */
3854 if ((skip = param_has_subparams(item))) {
3855 switch (op) {
3856 case 38:
3857 /* FALLTHRU */
3858 case 48:
3859 if_OPT_ISO_COLORS(screen, {
3860 break;
3861 });
3862 /* FALLTHRU */
3863 default:
3864 TRACE(("...unexpected subparameter in SGR\n"));
3865 item += skip; /* ignore this */
3866 op = NPARAM; /* will never use this, anyway */
3867 break;
3868 }
3869 }
3870
3871 switch (op) {
3872 case DEFAULT:
3873 /* FALLTHRU */
3874 case 0:
3875 resetRendition(xw);
3876 if_OPT_ISO_COLORS(screen, {
3877 reset_SGR_Colors(xw);
3878 });
3879 break;
3880 case 1: /* Bold */
3881 UIntSet(xw->flags, BOLD);
3882 if_OPT_ISO_COLORS(screen, {
3883 setExtendedFG(xw);
3884 });
3885 break;
3886 #if OPT_WIDE_ATTRS
3887 case 2: /* faint, decreased intensity or second colour */
3888 UIntSet(xw->flags, ATR_FAINT);
3889 if_OPT_ISO_COLORS(screen, {
3890 setExtendedFG(xw);
3891 });
3892 break;
3893 case 3: /* italicized */
3894 setItalicFont(xw, UseItalicFont(screen));
3895 UIntSet(xw->flags, ATR_ITALIC);
3896 if_OPT_ISO_COLORS(screen, {
3897 setExtendedFG(xw);
3898 });
3899 break;
3900 #endif
3901 case 4: /* Underscore */
3902 UIntSet(xw->flags, UNDERLINE);
3903 if_OPT_ISO_COLORS(screen, {
3904 setExtendedFG(xw);
3905 });
3906 break;
3907 case 5: /* Blink (less than 150 per minute) */
3908 /* FALLTHRU */
3909 case 6: /* Blink (150 per minute, or more) */
3910 UIntSet(xw->flags, BLINK);
3911 StartBlinking(xw);
3912 if_OPT_ISO_COLORS(screen, {
3913 setExtendedFG(xw);
3914 });
3915 break;
3916 case 7:
3917 UIntSet(xw->flags, INVERSE);
3918 if_OPT_ISO_COLORS(screen, {
3919 setExtendedBG(xw);
3920 });
3921 break;
3922 case 8:
3923 UIntSet(xw->flags, INVISIBLE);
3924 break;
3925 #if OPT_WIDE_ATTRS
3926 case 9: /* crossed-out characters */
3927 UIntSet(xw->flags, ATR_STRIKEOUT);
3928 break;
3929 #endif
3930 #if OPT_WIDE_ATTRS
3931 case 21: /* doubly-underlined */
3932 UIntSet(xw->flags, ATR_DBL_UNDER);
3933 break;
3934 #endif
3935 case 22: /* reset 'bold' */
3936 UIntClr(xw->flags, BOLD);
3937 #if OPT_WIDE_ATTRS
3938 UIntClr(xw->flags, ATR_FAINT);
3939 #endif
3940 if_OPT_ISO_COLORS(screen, {
3941 setExtendedFG(xw);
3942 });
3943 break;
3944 #if OPT_WIDE_ATTRS
3945 case 23: /* not italicized */
3946 ResetItalics(xw);
3947 if_OPT_ISO_COLORS(screen, {
3948 setExtendedFG(xw);
3949 });
3950 break;
3951 #endif
3952 case 24:
3953 UIntClr(xw->flags, UNDERLINE);
3954 #if OPT_WIDE_ATTRS
3955 UIntClr(xw->flags, ATR_DBL_UNDER);
3956 #endif
3957 if_OPT_ISO_COLORS(screen, {
3958 setExtendedFG(xw);
3959 });
3960 break;
3961 case 25: /* reset 'blink' */
3962 UIntClr(xw->flags, BLINK);
3963 if_OPT_ISO_COLORS(screen, {
3964 setExtendedFG(xw);
3965 });
3966 break;
3967 case 27:
3968 UIntClr(xw->flags, INVERSE);
3969 if_OPT_ISO_COLORS(screen, {
3970 setExtendedBG(xw);
3971 });
3972 break;
3973 case 28:
3974 UIntClr(xw->flags, INVISIBLE);
3975 break;
3976 #if OPT_WIDE_ATTRS
3977 case 29: /* not crossed out */
3978 UIntClr(xw->flags, ATR_STRIKEOUT);
3979 break;
3980 #endif
3981 case 30:
3982 /* FALLTHRU */
3983 case 31:
3984 /* FALLTHRU */
3985 case 32:
3986 /* FALLTHRU */
3987 case 33:
3988 /* FALLTHRU */
3989 case 34:
3990 /* FALLTHRU */
3991 case 35:
3992 /* FALLTHRU */
3993 case 36:
3994 /* FALLTHRU */
3995 case 37:
3996 if_OPT_ISO_COLORS(screen, {
3997 xw->sgr_foreground = (op - 30);
3998 xw->sgr_38_xcolors = False;
3999 clrDirectFG(xw->flags);
4000 setExtendedFG(xw);
4001 });
4002 break;
4003 case 38:
4004 /* This is more complicated than I'd like, but it should
4005 * properly eat all the parameters for unsupported modes.
4006 */
4007 if_OPT_ISO_COLORS(screen, {
4008 Boolean extended;
4009 if (parse_extended_colors(xw, &value, &item,
4010 &extended)) {
4011 xw->sgr_foreground = value;
4012 xw->sgr_38_xcolors = True;
4013 setDirectFG(xw->flags, extended);
4014 setExtendedFG(xw);
4015 }
4016 });
4017 break;
4018 case 39:
4019 if_OPT_ISO_COLORS(screen, {
4020 reset_SGR_Foreground(xw);
4021 });
4022 break;
4023 case 40:
4024 /* FALLTHRU */
4025 case 41:
4026 /* FALLTHRU */
4027 case 42:
4028 /* FALLTHRU */
4029 case 43:
4030 /* FALLTHRU */
4031 case 44:
4032 /* FALLTHRU */
4033 case 45:
4034 /* FALLTHRU */
4035 case 46:
4036 /* FALLTHRU */
4037 case 47:
4038 if_OPT_ISO_COLORS(screen, {
4039 xw->sgr_background = (op - 40);
4040 clrDirectBG(xw->flags);
4041 setExtendedBG(xw);
4042 });
4043 break;
4044 case 48:
4045 if_OPT_ISO_COLORS(screen, {
4046 Boolean extended;
4047 if (parse_extended_colors(xw, &value, &item,
4048 &extended)) {
4049 xw->sgr_background = value;
4050 setDirectBG(xw->flags, extended);
4051 setExtendedBG(xw);
4052 }
4053 });
4054 break;
4055 case 49:
4056 if_OPT_ISO_COLORS(screen, {
4057 reset_SGR_Background(xw);
4058 });
4059 break;
4060 case 90:
4061 /* FALLTHRU */
4062 case 91:
4063 /* FALLTHRU */
4064 case 92:
4065 /* FALLTHRU */
4066 case 93:
4067 /* FALLTHRU */
4068 case 94:
4069 /* FALLTHRU */
4070 case 95:
4071 /* FALLTHRU */
4072 case 96:
4073 /* FALLTHRU */
4074 case 97:
4075 if_OPT_AIX_COLORS(screen, {
4076 xw->sgr_foreground = (op - 90 + 8);
4077 clrDirectFG(xw->flags);
4078 setExtendedFG(xw);
4079 });
4080 break;
4081 case 100:
4082 #if !OPT_AIX_COLORS
4083 if_OPT_ISO_COLORS(screen, {
4084 reset_SGR_Foreground(xw);
4085 reset_SGR_Background(xw);
4086 });
4087 break;
4088 #endif
4089 case 101:
4090 /* FALLTHRU */
4091 case 102:
4092 /* FALLTHRU */
4093 case 103:
4094 /* FALLTHRU */
4095 case 104:
4096 /* FALLTHRU */
4097 case 105:
4098 /* FALLTHRU */
4099 case 106:
4100 /* FALLTHRU */
4101 case 107:
4102 if_OPT_AIX_COLORS(screen, {
4103 xw->sgr_background = (op - 100 + 8);
4104 clrDirectBG(xw->flags);
4105 setExtendedBG(xw);
4106 });
4107 break;
4108 default:
4109 /* later: skip += NPARAM; */
4110 break;
4111 }
4112 }
4113 ResetState(sp);
4114 break;
4115
4116 /* DSR (except for the '?') is a superset of CPR */
4117 case CASE_DSR:
4118 sp->private_function = True;
4119
4120 /* FALLTHRU */
4121 case CASE_CPR:
4122 TRACE(("CASE_DSR - device status report\n"));
4123 count = 0;
4124 init_reply(ANSI_CSI);
4125 reply.a_pintro = CharOf(sp->private_function ? '?' : 0);
4126 reply.a_final = 'n';
4127
4128 switch (GetParam(0)) {
4129 case 5:
4130 TRACE(("...request operating status\n"));
4131 /* operating status */
4132 reply.a_param[count++] = 0; /* (no malfunction ;-) */
4133 break;
4134 case 6:
4135 TRACE(("...request %s\n",
4136 (sp->private_function
4137 ? "DECXCPR"
4138 : "CPR")));
4139 /* CPR */
4140 /* DECXCPR (with page=1) */
4141 value = screen->cur_row;
4142 if ((xw->flags & ORIGIN) != 0) {
4143 value -= screen->top_marg;
4144 }
4145 if_STATUS_LINE(screen, {
4146 if ((value -= LastRowNumber(screen)) < 0)
4147 value = 0;
4148 });
4149 reply.a_param[count++] = (ParmType) (value + 1);
4150
4151 value = (screen->cur_col + 1);
4152 if ((xw->flags & ORIGIN) != 0) {
4153 value -= screen->lft_marg;
4154 }
4155 reply.a_param[count++] = (ParmType) value;
4156
4157 if (sp->private_function &&
4158 (screen->vtXX_level >= 4 ||
4159 (screen->terminal_id >= 330 &&
4160 screen->vtXX_level >= 3))) {
4161 /* VT330 (not VT320) and VT420 */
4162 reply.a_param[count++] = 1;
4163 }
4164 reply.a_final = 'R';
4165 break;
4166 case 15:
4167 TRACE(("...request printer status\n"));
4168 if (sp->private_function
4169 && screen->vtXX_level >= 2) { /* VT220 */
4170 reply.a_param[count++] = 13; /* no printer detected */
4171 }
4172 break;
4173 case 25:
4174 TRACE(("...request UDK status\n"));
4175 if (sp->private_function
4176 && screen->vtXX_level >= 2) { /* VT220 */
4177 reply.a_param[count++] = 20; /* UDK always unlocked */
4178 }
4179 break;
4180 case 26:
4181 TRACE(("...request keyboard status\n"));
4182 if (sp->private_function
4183 && screen->vtXX_level >= 2) { /* VT220 */
4184 reply.a_param[count++] = 27;
4185 reply.a_param[count++] = 1; /* North American */
4186 if (screen->vtXX_level >= 3) { /* VT320 */
4187 reply.a_param[count++] = 0; /* ready */
4188 }
4189 if (screen->vtXX_level >= 4) { /* VT420 */
4190 reply.a_param[count++] = 0; /* LK201 */
4191 }
4192 }
4193 break;
4194 case 53: /* according to existing xterm handling */
4195 /* FALLTHRU */
4196 case 55: /* according to the VT330/VT340 Text Programming Manual */
4197 TRACE(("...request locator status\n"));
4198 if (sp->private_function
4199 && screen->vtXX_level >= 3) { /* VT330 */
4200 #if OPT_DEC_LOCATOR
4201 reply.a_param[count++] = 50; /* locator ready */
4202 #else
4203 reply.a_param[count++] = 53; /* no locator */
4204 #endif
4205 }
4206 break;
4207 case 56:
4208 TRACE(("...request locator type\n"));
4209 if (sp->private_function
4210 && screen->vtXX_level >= 3) { /* VT330 */
4211 reply.a_param[count++] = 57;
4212 #if OPT_DEC_LOCATOR
4213 reply.a_param[count++] = 1; /* mouse */
4214 #else
4215 reply.a_param[count++] = 0; /* unknown */
4216 #endif
4217 }
4218 break;
4219 case 62:
4220 TRACE(("...request DECMSR - macro space\n"));
4221 if (sp->private_function
4222 && screen->vtXX_level >= 4) { /* VT420 */
4223 reply.a_pintro = 0;
4224 reply.a_radix[count] = 16; /* no data */
4225 reply.a_param[count++] = 0; /* no space for macros */
4226 reply.a_inters = '*';
4227 reply.a_final = L_CURL;
4228 }
4229 break;
4230 case 63:
4231 TRACE(("...request DECCKSR - memory checksum\n"));
4232 /* DECCKSR - Memory checksum */
4233 if (sp->private_function
4234 && screen->vtXX_level >= 4) { /* VT420 */
4235 init_reply(ANSI_DCS);
4236 reply.a_param[count++] = (ParmType) GetParam(1); /* PID */
4237 reply.a_delim = "!~"; /* delimiter */
4238 reply.a_radix[count] = 16; /* use hex */
4239 reply.a_param[count++] = 0; /* no data */
4240 }
4241 break;
4242 case 75:
4243 TRACE(("...request data integrity\n"));
4244 if (sp->private_function
4245 && screen->vtXX_level >= 4) { /* VT420 */
4246 reply.a_param[count++] = 70; /* no errors */
4247 }
4248 break;
4249 case 85:
4250 TRACE(("...request multi-session configuration\n"));
4251 if (sp->private_function
4252 && screen->vtXX_level >= 4) { /* VT420 */
4253 reply.a_param[count++] = 83; /* not configured */
4254 }
4255 break;
4256 default:
4257 break;
4258 }
4259
4260 if ((reply.a_nparam = (ParmType) count) != 0)
4261 unparseseq(xw, &reply);
4262
4263 ResetState(sp);
4264 sp->private_function = False;
4265 break;
4266
4267 case CASE_MC:
4268 TRACE(("CASE_MC - media control\n"));
4269 xtermMediaControl(xw, GetParam(0), False);
4270 ResetState(sp);
4271 break;
4272
4273 case CASE_DEC_MC:
4274 TRACE(("CASE_DEC_MC - DEC media control\n"));
4275 xtermMediaControl(xw, GetParam(0), True);
4276 ResetState(sp);
4277 break;
4278
4279 case CASE_HP_MEM_LOCK:
4280 /* FALLTHRU */
4281 case CASE_HP_MEM_UNLOCK:
4282 TRACE(("%s\n", ((sp->parsestate[c] == CASE_HP_MEM_LOCK)
4283 ? "CASE_HP_MEM_LOCK"
4284 : "CASE_HP_MEM_UNLOCK")));
4285 if (screen->scroll_amt)
4286 FlushScroll(xw);
4287 if (sp->parsestate[c] == CASE_HP_MEM_LOCK)
4288 set_tb_margins(screen, screen->cur_row, screen->bot_marg);
4289 else
4290 set_tb_margins(screen, 0, screen->bot_marg);
4291 ResetState(sp);
4292 break;
4293
4294 case CASE_DECSTBM:
4295 TRACE(("CASE_DECSTBM - set scrolling region\n"));
4296 {
4297 int top;
4298 int bot;
4299 top = one_if_default(0);
4300 if (nparam < 2 || (bot = GetParam(1)) == DEFAULT
4301 || bot > MaxRows(screen)
4302 || bot == 0)
4303 bot = MaxRows(screen);
4304 if (bot > top) {
4305 if (screen->scroll_amt)
4306 FlushScroll(xw);
4307 set_tb_margins(screen, top - 1, bot - 1);
4308 CursorSet(screen, 0, 0, xw->flags);
4309 }
4310 ResetState(sp);
4311 }
4312 break;
4313
4314 case CASE_DECREQTPARM:
4315 TRACE(("CASE_DECREQTPARM\n"));
4316 if (screen->terminal_id < 200) { /* VT102 */
4317 value = zero_if_default(0);
4318 if (value == 0 || value == 1) {
4319 init_reply(ANSI_CSI);
4320 reply.a_nparam = 7;
4321 reply.a_param[0] = (ParmType) (value + 2);
4322 reply.a_param[1] = 1; /* no parity */
4323 reply.a_param[2] = 1; /* eight bits */
4324 reply.a_param[3] = 128; /* transmit 38.4k baud */
4325 reply.a_param[4] = 128; /* receive 38.4k baud */
4326 reply.a_param[5] = 1; /* clock multiplier ? */
4327 reply.a_param[6] = 0; /* STP flags ? */
4328 reply.a_final = 'x';
4329 unparseseq(xw, &reply);
4330 }
4331 }
4332 ResetState(sp);
4333 break;
4334
4335 case CASE_DECSET:
4336 /* DECSET */
4337 #if OPT_VT52_MODE
4338 if (screen->vtXX_level != 0)
4339 #endif
4340 dpmodes(xw, bitset);
4341 ResetState(sp);
4342 #if OPT_TEK4014
4343 if (TEK4014_ACTIVE(xw)) {
4344 TRACE(("Tek4014 is now active...\n"));
4345 if (sp->check_recur)
4346 sp->check_recur--;
4347 return False;
4348 }
4349 #endif
4350 break;
4351
4352 case CASE_DECRST:
4353 /* DECRST */
4354 dpmodes(xw, bitclr);
4355 init_groundtable(screen, sp);
4356 ResetState(sp);
4357 break;
4358
4359 case CASE_DECALN:
4360 TRACE(("CASE_DECALN - alignment test\n"));
4361 if (screen->cursor_state)
4362 HideCursor(xw);
4363 /*
4364 * DEC STD 070 (see pages D-19 to D-20) does not mention left/right
4365 * margins. The section is dated March 1985, not updated for the
4366 * VT420 (introduced in 1990).
4367 */
4368 UIntClr(xw->flags, ORIGIN);
4369 screen->do_wrap = False;
4370 resetRendition(xw);
4371 resetMargins(xw);
4372 xterm_ResetDouble(xw);
4373 CursorSet(screen, 0, 0, xw->flags);
4374 xtermParseRect(xw, 0, 0, &myRect);
4375 ScrnFillRectangle(xw, &myRect, 'E', 0, False);
4376 ResetState(sp);
4377 break;
4378
4379 case CASE_GSETS5:
4380 if (screen->vtXX_level >= 5) {
4381 TRACE(("CASE_GSETS5(%d) = '%c'\n", sp->scstype, c));
4382 xtermDecodeSCS(xw, sp->scstype, 5, 0, (int) c);
4383 }
4384 ResetState(sp);
4385 break;
4386
4387 case CASE_GSETS3:
4388 if (screen->vtXX_level >= 3) {
4389 TRACE(("CASE_GSETS3(%d) = '%c'\n", sp->scstype, c));
4390 xtermDecodeSCS(xw, sp->scstype, 3, 0, (int) c);
4391 }
4392 ResetState(sp);
4393 break;
4394
4395 case CASE_GSETS:
4396 if (strchr("012AB", (int) c) != 0) {
4397 TRACE(("CASE_GSETS(%d) = '%c'\n", sp->scstype, c));
4398 xtermDecodeSCS(xw, sp->scstype, 1, 0, (int) c);
4399 } else if (screen->vtXX_level >= 2) {
4400 TRACE(("CASE_GSETS(%d) = '%c'\n", sp->scstype, c));
4401 xtermDecodeSCS(xw, sp->scstype, 2, 0, (int) c);
4402 }
4403 ResetState(sp);
4404 break;
4405
4406 case CASE_ANSI_SC:
4407 if (IsLeftRightMode(xw)) {
4408 int left;
4409 int right;
4410
4411 TRACE(("CASE_DECSLRM - set left and right margin\n"));
4412 left = one_if_default(0);
4413 if (nparam < 2 || (right = GetParam(1)) == DEFAULT
4414 || right > MaxCols(screen)
4415 || right == 0)
4416 right = MaxCols(screen);
4417 if (right > left) {
4418 set_lr_margins(screen, left - 1, right - 1);
4419 CursorSet(screen, 0, 0, xw->flags);
4420 }
4421 } else {
4422 TRACE(("CASE_ANSI_SC - save cursor\n"));
4423 CursorSave(xw);
4424 }
4425 ResetState(sp);
4426 break;
4427
4428 case CASE_DECSC:
4429 TRACE(("CASE_DECSC - save cursor\n"));
4430 CursorSave(xw);
4431 ResetState(sp);
4432 break;
4433
4434 case CASE_ANSI_RC:
4435 /* FALLTHRU */
4436 case CASE_DECRC:
4437 TRACE(("CASE_%sRC - restore cursor\n",
4438 (sp->nextstate == CASE_DECRC) ? "DEC" : "ANSI_"));
4439 CursorRestore(xw);
4440 if_OPT_ISO_COLORS(screen, {
4441 setExtendedFG(xw);
4442 });
4443 ResetState(sp);
4444 break;
4445
4446 case CASE_DECKPAM:
4447 TRACE(("CASE_DECKPAM\n"));
4448 xw->keyboard.flags |= MODE_DECKPAM;
4449 update_appkeypad();
4450 ResetState(sp);
4451 break;
4452
4453 case CASE_DECKPNM:
4454 TRACE(("CASE_DECKPNM\n"));
4455 UIntClr(xw->keyboard.flags, MODE_DECKPAM);
4456 update_appkeypad();
4457 ResetState(sp);
4458 break;
4459
4460 case CASE_CSI_QUOTE_STATE:
4461 sp->parsestate = csi_quo_table;
4462 break;
4463
4464 #if OPT_BLINK_CURS
4465 case CASE_CSI_SPACE_STATE:
4466 sp->parsestate = csi_sp_table;
4467 break;
4468
4469 case CASE_DECSCUSR:
4470 TRACE(("CASE_DECSCUSR\n"));
4471 {
4472 Boolean change = True;
4473 int blinks = screen->cursor_blink_esc;
4474
4475 HideCursor(xw);
4476
4477 switch (GetParam(0)) {
4478 case DEFAULT:
4479 /* FALLTHRU */
4480 case DEFAULT_STYLE:
4481 /* FALLTHRU */
4482 case BLINK_BLOCK:
4483 blinks = True;
4484 screen->cursor_shape = CURSOR_BLOCK;
4485 break;
4486 case STEADY_BLOCK:
4487 blinks = False;
4488 screen->cursor_shape = CURSOR_BLOCK;
4489 break;
4490 case BLINK_UNDERLINE:
4491 blinks = True;
4492 screen->cursor_shape = CURSOR_UNDERLINE;
4493 break;
4494 case STEADY_UNDERLINE:
4495 blinks = False;
4496 screen->cursor_shape = CURSOR_UNDERLINE;
4497 break;
4498 case BLINK_BAR:
4499 blinks = True;
4500 screen->cursor_shape = CURSOR_BAR;
4501 break;
4502 case STEADY_BAR:
4503 blinks = False;
4504 screen->cursor_shape = CURSOR_BAR;
4505 break;
4506 default:
4507 change = False;
4508 break;
4509 }
4510 TRACE(("cursor_shape:%d blinks:%s\n",
4511 screen->cursor_shape, BtoS(blinks)));
4512 if (change) {
4513 xtermSetCursorBox(screen);
4514 if (SettableCursorBlink(screen)) {
4515 screen->cursor_blink_esc = blinks;
4516 UpdateCursorBlink(xw);
4517 }
4518 }
4519 }
4520 ResetState(sp);
4521 break;
4522 #endif
4523
4524 #if OPT_SCROLL_LOCK
4525 case CASE_DECLL:
4526 TRACE(("CASE_DECLL\n"));
4527 if (nparam > 0) {
4528 for (count = 0; count < nparam; ++count) {
4529 int op = zero_if_default(count);
4530 switch (op) {
4531 case 0:
4532 case DEFAULT:
4533 xtermClearLEDs(screen);
4534 break;
4535 case 1:
4536 /* FALLTHRU */
4537 case 2:
4538 /* FALLTHRU */
4539 case 3:
4540 xtermShowLED(screen,
4541 (Cardinal) op,
4542 True);
4543 break;
4544 case 21:
4545 /* FALLTHRU */
4546 case 22:
4547 /* FALLTHRU */
4548 case 23:
4549 xtermShowLED(screen,
4550 (Cardinal) (op - 20),
4551 True);
4552 break;
4553 }
4554 }
4555 } else {
4556 xtermClearLEDs(screen);
4557 }
4558 ResetState(sp);
4559 break;
4560 #endif
4561
4562 #if OPT_VT52_MODE
4563 case CASE_VT52_FINISH:
4564 TRACE(("CASE_VT52_FINISH terminal_id %d, vtXX_level %d\n",
4565 screen->terminal_id,
4566 screen->vtXX_level));
4567 if (screen->terminal_id >= 100
4568 && screen->vtXX_level == 0) {
4569 sp->groundtable =
4570 sp->parsestate = ansi_table;
4571 /*
4572 * On restore, the terminal does not recognize DECRQSS for
4573 * DECSCL (per vttest).
4574 */
4575 screen->vtXX_level = 1;
4576 xw->flags = screen->vt52_save_flags;
4577 screen->curgl = screen->vt52_save_curgl;
4578 screen->curgr = screen->vt52_save_curgr;
4579 screen->curss = screen->vt52_save_curss;
4580 restoreCharsets(screen, screen->vt52_save_gsets);
4581 update_vt52_vt100_settings();
4582 }
4583 break;
4584 #endif
4585
4586 case CASE_ANSI_LEVEL_1:
4587 TRACE(("CASE_ANSI_LEVEL_1\n"));
4588 set_ansi_conformance(screen, 1);
4589 ResetState(sp);
4590 break;
4591
4592 case CASE_ANSI_LEVEL_2:
4593 TRACE(("CASE_ANSI_LEVEL_2\n"));
4594 set_ansi_conformance(screen, 2);
4595 ResetState(sp);
4596 break;
4597
4598 case CASE_ANSI_LEVEL_3:
4599 TRACE(("CASE_ANSI_LEVEL_3\n"));
4600 set_ansi_conformance(screen, 3);
4601 ResetState(sp);
4602 break;
4603
4604 case CASE_DECSCL:
4605 TRACE(("CASE_DECSCL(%d,%d)\n", GetParam(0), GetParam(1)));
4606 /*
4607 * This changes the emulation level, and is not recognized by
4608 * VT100s. However, a VT220 or above can be set to conformance
4609 * level 1 to act like a VT100.
4610 */
4611 if (screen->terminal_id >= 200) {
4612 /*
4613 * Disallow unrecognized parameters, as well as attempts to set
4614 * the operating level higher than the given terminal-id.
4615 */
4616 if (GetParam(0) >= 61
4617 && GetParam(0) <= 60 + (screen->terminal_id / 100)) {
4618 int new_vtXX_level = GetParam(0) - 60;
4619 int case_value = zero_if_default(1);
4620 /*
4621 * Note:
4622 *
4623 * The VT300, VT420, VT520 manuals claim that DECSCL does a
4624 * hard reset (RIS).
4625 *
4626 * Both the VT220 manual and DEC STD 070 (which documents
4627 * levels 1-4 in detail) state that it is a soft reset.
4628 *
4629 * Perhaps both sets of manuals are right (unlikely).
4630 * Kermit says it's soft.
4631 */
4632 ReallyReset(xw, False, False);
4633 init_parser(xw, sp);
4634 screen->vtXX_level = new_vtXX_level;
4635 if (new_vtXX_level > 1) {
4636 switch (case_value) {
4637 case 1:
4638 show_8bit_control(False);
4639 break;
4640 case 0:
4641 case 2:
4642 show_8bit_control(True);
4643 break;
4644 }
4645 }
4646 }
4647 }
4648 ResetState(sp);
4649 break;
4650
4651 case CASE_DECSCA:
4652 TRACE(("CASE_DECSCA\n"));
4653 screen->protected_mode = DEC_PROTECT;
4654 if (GetParam(0) <= 0 || GetParam(0) == 2) {
4655 UIntClr(xw->flags, PROTECTED);
4656 TRACE(("...clear PROTECTED\n"));
4657 } else if (GetParam(0) == 1) {
4658 xw->flags |= PROTECTED;
4659 TRACE(("...set PROTECTED\n"));
4660 }
4661 ResetState(sp);
4662 break;
4663
4664 case CASE_DECSED:
4665 TRACE(("CASE_DECSED\n"));
4666 do_erase_display(xw, zero_if_default(0), DEC_PROTECT);
4667 ResetState(sp);
4668 break;
4669
4670 case CASE_DECSEL:
4671 TRACE(("CASE_DECSEL\n"));
4672 do_erase_line(xw, zero_if_default(0), DEC_PROTECT);
4673 ResetState(sp);
4674 break;
4675
4676 case CASE_GRAPHICS_ATTRIBUTES:
4677 #if OPT_GRAPHICS
4678 TRACE(("CASE_GRAPHICS_ATTRIBUTES\n"));
4679 {
4680 /* request: item, action, value */
4681 /* reply: item, status, value */
4682 if (nparam != 3) {
4683 TRACE(("DATA_ERROR: malformed CASE_GRAPHICS_ATTRIBUTES request with %d parameters\n", nparam));
4684 } else {
4685 int status = 3; /* assume failure */
4686 int result = 0;
4687 int result2 = 0;
4688
4689 TRACE(("CASE_GRAPHICS_ATTRIBUTES request: %d, %d, %d\n",
4690 GetParam(0), GetParam(1), GetParam(2)));
4691 switch (GetParam(0)) {
4692 case 1: /* color register count */
4693 switch (GetParam(1)) {
4694 case 1: /* read */
4695 status = 0; /* success */
4696 result = (int) get_color_register_count(screen);
4697 break;
4698 case 2: /* reset */
4699 screen->numcolorregisters = 0;
4700 status = 0; /* success */
4701 result = (int) get_color_register_count(screen);
4702 break;
4703 case 3: /* set */
4704 if (GetParam(2) > 1 &&
4705 (unsigned) GetParam(2) <= MAX_COLOR_REGISTERS) {
4706 screen->numcolorregisters = GetParam(2);
4707 status = 0; /* success */
4708 result = (int) get_color_register_count(screen);
4709 }
4710 break;
4711 case 4: /* read maximum */
4712 status = 0; /* success */
4713 result = MAX_COLOR_REGISTERS;
4714 break;
4715 default:
4716 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES color register count request with unknown action parameter: %d\n",
4717 GetParam(1)));
4718 status = 2; /* error in Pa */
4719 break;
4720 }
4721 if (status == 0 && !(optSixelGraphics(screen)
4722 || optRegisGraphics(screen)))
4723 status = 3;
4724 break;
4725 # if OPT_SIXEL_GRAPHICS
4726 case 2: /* graphics geometry */
4727 switch (GetParam(1)) {
4728 case 1: /* read */
4729 TRACE(("Get sixel graphics geometry\n"));
4730 status = 0; /* success */
4731 result = Min(Width(screen), (int) screen->graphics_max_wide);
4732 result2 = Min(Height(screen), (int) screen->graphics_max_high);
4733 break;
4734 case 2: /* reset */
4735 /* FALLTHRU */
4736 case 3: /* set */
4737 break;
4738 case 4: /* read maximum */
4739 status = 0; /* success */
4740 result = screen->graphics_max_wide;
4741 result2 = screen->graphics_max_high;
4742 break;
4743 default:
4744 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES graphics geometry request with unknown action parameter: %d\n",
4745 GetParam(1)));
4746 status = 2; /* error in Pa */
4747 break;
4748 }
4749 if (status == 0 && !optSixelGraphics(screen))
4750 status = 3;
4751 break;
4752 #endif
4753 # if OPT_REGIS_GRAPHICS
4754 case 3: /* ReGIS geometry */
4755 switch (GetParam(1)) {
4756 case 1: /* read */
4757 status = 0; /* success */
4758 result = screen->graphics_regis_def_wide;
4759 result2 = screen->graphics_regis_def_high;
4760 break;
4761 case 2: /* reset */
4762 /* FALLTHRU */
4763 case 3: /* set */
4764 /* FALLTHRU */
4765 case 4: /* read maximum */
4766 /* not implemented */
4767 break;
4768 default:
4769 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES ReGIS geometry request with unknown action parameter: %d\n",
4770 GetParam(1)));
4771 status = 2; /* error in Pa */
4772 break;
4773 }
4774 if (status == 0 && !optRegisGraphics(screen))
4775 status = 3;
4776 break;
4777 #endif
4778 default:
4779 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES request with unknown item parameter: %d\n",
4780 GetParam(0)));
4781 status = 1;
4782 break;
4783 }
4784
4785 init_reply(ANSI_CSI);
4786 reply.a_pintro = '?';
4787 count = 0;
4788 reply.a_param[count++] = (ParmType) GetParam(0);
4789 reply.a_param[count++] = (ParmType) status;
4790 if (status == 0) {
4791 reply.a_param[count++] = (ParmType) result;
4792 if (GetParam(0) >= 2)
4793 reply.a_param[count++] = (ParmType) result2;
4794 }
4795 reply.a_nparam = (ParmType) count;
4796 reply.a_final = 'S';
4797 unparseseq(xw, &reply);
4798 }
4799 }
4800 #endif
4801 ResetState(sp);
4802 break;
4803
4804 case CASE_ST:
4805 TRACE(("CASE_ST: End of String (%lu bytes) (mode=%d)\n",
4806 (unsigned long) sp->string_used,
4807 sp->string_mode));
4808 ResetState(sp);
4809 if (!sp->string_used)
4810 break;
4811 sp->string_area[--(sp->string_used)] = '\0';
4812 if (sp->check_recur <= 1)
4813 switch (sp->string_mode) {
4814 case ANSI_APC:
4815 /* ignored */
4816 break;
4817 case ANSI_DCS:
4818 do_dcs(xw, sp->string_area, sp->string_used);
4819 break;
4820 case ANSI_OSC:
4821 do_osc(xw, sp->string_area, sp->string_used, ANSI_ST);
4822 break;
4823 case ANSI_PM:
4824 /* ignored */
4825 break;
4826 case ANSI_SOS:
4827 /* ignored */
4828 break;
4829 default:
4830 TRACE(("unknown mode\n"));
4831 break;
4832 }
4833 break;
4834
4835 case CASE_SOS:
4836 TRACE(("CASE_SOS: Start of String\n"));
4837 if (ParseSOS(screen)) {
4838 sp->string_mode = ANSI_SOS;
4839 sp->parsestate = sos_table;
4840 } else {
4841 illegal_parse(xw, c, sp);
4842 }
4843 break;
4844
4845 case CASE_PM:
4846 TRACE(("CASE_PM: Privacy Message\n"));
4847 if (ParseSOS(screen)) {
4848 sp->string_mode = ANSI_PM;
4849 sp->parsestate = sos_table;
4850 } else {
4851 illegal_parse(xw, c, sp);
4852 }
4853 break;
4854
4855 case CASE_DCS:
4856 TRACE(("CASE_DCS: Device Control String\n"));
4857 sp->string_mode = ANSI_DCS;
4858 sp->parsestate = sos_table;
4859 break;
4860
4861 case CASE_APC:
4862 TRACE(("CASE_APC: Application Program Command\n"));
4863 if (ParseSOS(screen)) {
4864 sp->string_mode = ANSI_APC;
4865 sp->parsestate = sos_table;
4866 } else {
4867 illegal_parse(xw, c, sp);
4868 }
4869 break;
4870
4871 case CASE_SPA:
4872 TRACE(("CASE_SPA - start protected area\n"));
4873 screen->protected_mode = ISO_PROTECT;
4874 xw->flags |= PROTECTED;
4875 ResetState(sp);
4876 break;
4877
4878 case CASE_EPA:
4879 TRACE(("CASE_EPA - end protected area\n"));
4880 UIntClr(xw->flags, PROTECTED);
4881 ResetState(sp);
4882 break;
4883
4884 case CASE_SU:
4885 TRACE(("CASE_SU - scroll up\n"));
4886 xtermScroll(xw, one_if_default(0));
4887 ResetState(sp);
4888 break;
4889
4890 case CASE_SL: /* ISO 6429, non-DEC */
4891 TRACE(("CASE_SL - scroll left\n"));
4892 xtermScrollLR(xw, one_if_default(0), True);
4893 ResetState(sp);
4894 break;
4895
4896 case CASE_SR: /* ISO 6429, non-DEC */
4897 TRACE(("CASE_SR - scroll right\n"));
4898 xtermScrollLR(xw, one_if_default(0), False);
4899 ResetState(sp);
4900 break;
4901
4902 case CASE_DECDC:
4903 TRACE(("CASE_DC - delete column\n"));
4904 if (screen->vtXX_level >= 4) {
4905 xtermColScroll(xw, one_if_default(0), True, screen->cur_col);
4906 }
4907 ResetState(sp);
4908 break;
4909
4910 case CASE_DECIC:
4911 TRACE(("CASE_IC - insert column\n"));
4912 if (screen->vtXX_level >= 4) {
4913 xtermColScroll(xw, one_if_default(0), False, screen->cur_col);
4914 }
4915 ResetState(sp);
4916 break;
4917
4918 case CASE_DECBI:
4919 TRACE(("CASE_BI - back index\n"));
4920 if (screen->vtXX_level >= 4) {
4921 xtermColIndex(xw, True);
4922 }
4923 ResetState(sp);
4924 break;
4925
4926 case CASE_DECFI:
4927 TRACE(("CASE_FI - forward index\n"));
4928 if (screen->vtXX_level >= 4) {
4929 xtermColIndex(xw, False);
4930 }
4931 ResetState(sp);
4932 break;
4933
4934 case CASE_IND:
4935 TRACE(("CASE_IND - index\n"));
4936 xtermIndex(xw, 1);
4937 do_xevents(xw);
4938 ResetState(sp);
4939 break;
4940
4941 case CASE_CPL:
4942 TRACE(("CASE_CPL - cursor prev line\n"));
4943 CursorPrevLine(xw, one_if_default(0));
4944 ResetState(sp);
4945 break;
4946
4947 case CASE_CNL:
4948 TRACE(("CASE_CNL - cursor next line\n"));
4949 CursorNextLine(xw, one_if_default(0));
4950 ResetState(sp);
4951 break;
4952
4953 case CASE_NEL:
4954 TRACE(("CASE_NEL\n"));
4955 xtermIndex(xw, 1);
4956 CarriageReturn(xw);
4957 ResetState(sp);
4958 break;
4959
4960 case CASE_HTS:
4961 TRACE(("CASE_HTS - horizontal tab set\n"));
4962 TabSet(xw->tabs, screen->cur_col);
4963 ResetState(sp);
4964 break;
4965
4966 case CASE_REPORT_VERSION:
4967 TRACE(("CASE_REPORT_VERSION - report terminal version\n"));
4968 if (GetParam(0) <= 0) {
4969 unparseputc1(xw, ANSI_DCS);
4970 unparseputc(xw, '>');
4971 unparseputc(xw, '|');
4972 unparseputs(xw, xtermVersion());
4973 unparseputc1(xw, ANSI_ST);
4974 unparse_end(xw);
4975 }
4976 ResetState(sp);
4977 break;
4978
4979 case CASE_RI:
4980 TRACE(("CASE_RI - reverse index\n"));
4981 RevIndex(xw, 1);
4982 ResetState(sp);
4983 break;
4984
4985 case CASE_SS2:
4986 TRACE(("CASE_SS2\n"));
4987 screen->curss = 2;
4988 ResetState(sp);
4989 break;
4990
4991 case CASE_SS3:
4992 TRACE(("CASE_SS3\n"));
4993 screen->curss = 3;
4994 ResetState(sp);
4995 break;
4996
4997 case CASE_CSI_STATE:
4998 /* enter csi state */
4999 InitParams();
5000 SetParam(nparam++, DEFAULT);
5001 sp->parsestate = csi_table;
5002 break;
5003
5004 case CASE_ESC_SP_STATE:
5005 /* esc space */
5006 sp->parsestate = esc_sp_table;
5007 break;
5008
5009 case CASE_CSI_EX_STATE:
5010 /* csi exclamation */
5011 sp->parsestate = csi_ex_table;
5012 break;
5013
5014 case CASE_CSI_TICK_STATE:
5015 /* csi tick (') */
5016 sp->parsestate = csi_tick_table;
5017 break;
5018
5019 #if OPT_DEC_LOCATOR
5020 case CASE_DECEFR:
5021 TRACE(("CASE_DECEFR - Enable Filter Rectangle\n"));
5022 if (okSendMousePos(xw) == DEC_LOCATOR) {
5023 MotionOff(screen, xw);
5024 if ((screen->loc_filter_top = GetParam(0)) < 1)
5025 screen->loc_filter_top = LOC_FILTER_POS;
5026 if (nparam < 2
5027 || (screen->loc_filter_left = GetParam(1)) < 1)
5028 screen->loc_filter_left = LOC_FILTER_POS;
5029 if (nparam < 3
5030 || (screen->loc_filter_bottom = GetParam(2)) < 1)
5031 screen->loc_filter_bottom = LOC_FILTER_POS;
5032 if (nparam < 4
5033 || (screen->loc_filter_right = GetParam(3)) < 1)
5034 screen->loc_filter_right = LOC_FILTER_POS;
5035 InitLocatorFilter(xw);
5036 }
5037 ResetState(sp);
5038 break;
5039
5040 case CASE_DECELR:
5041 MotionOff(screen, xw);
5042 if (GetParam(0) <= 0 || GetParam(0) > 2) {
5043 screen->send_mouse_pos = MOUSE_OFF;
5044 TRACE(("DECELR - Disable Locator Reports\n"));
5045 } else {
5046 TRACE(("DECELR - Enable Locator Reports\n"));
5047 screen->send_mouse_pos = DEC_LOCATOR;
5048 xtermShowPointer(xw, True);
5049 if (GetParam(0) == 2) {
5050 screen->locator_reset = True;
5051 } else {
5052 screen->locator_reset = False;
5053 }
5054 if (nparam < 2 || GetParam(1) != 1) {
5055 screen->locator_pixels = False;
5056 } else {
5057 screen->locator_pixels = True;
5058 }
5059 screen->loc_filter = False;
5060 }
5061 ResetState(sp);
5062 break;
5063
5064 case CASE_DECSLE:
5065 TRACE(("DECSLE - Select Locator Events\n"));
5066 for (count = 0; count < nparam; ++count) {
5067 switch (zero_if_default(count)) {
5068 case 0:
5069 MotionOff(screen, xw);
5070 screen->loc_filter = False;
5071 screen->locator_events = 0;
5072 break;
5073 case 1:
5074 screen->locator_events |= LOC_BTNS_DN;
5075 break;
5076 case 2:
5077 UIntClr(screen->locator_events, LOC_BTNS_DN);
5078 break;
5079 case 3:
5080 screen->locator_events |= LOC_BTNS_UP;
5081 break;
5082 case 4:
5083 UIntClr(screen->locator_events, LOC_BTNS_UP);
5084 break;
5085 }
5086 }
5087 ResetState(sp);
5088 break;
5089
5090 case CASE_DECRQLP:
5091 TRACE(("DECRQLP - Request Locator Position\n"));
5092 if (GetParam(0) < 2) {
5093 /* Issue DECLRP Locator Position Report */
5094 GetLocatorPosition(xw);
5095 }
5096 ResetState(sp);
5097 break;
5098 #endif /* OPT_DEC_LOCATOR */
5099
5100 #if OPT_DEC_RECTOPS
5101 case CASE_CSI_DOLLAR_STATE:
5102 TRACE(("CASE_CSI_DOLLAR_STATE\n"));
5103 /* csi dollar ($) */
5104 if (screen->vtXX_level >= 3)
5105 sp->parsestate = csi_dollar_table;
5106 else
5107 sp->parsestate = eigtable;
5108 break;
5109
5110 case CASE_CSI_STAR_STATE:
5111 TRACE(("CASE_CSI_STAR_STATE\n"));
5112 /* csi star (*) */
5113 if (screen->vtXX_level >= 4)
5114 sp->parsestate = csi_star_table;
5115 else
5116 sp->parsestate = eigtable;
5117 break;
5118
5119 case CASE_DECRQCRA:
5120 if (screen->vtXX_level >= 4 && AllowWindowOps(xw, ewGetChecksum)) {
5121 int checksum;
5122 int pid;
5123
5124 TRACE(("CASE_DECRQCRA - Request checksum of rectangular area\n"));
5125 xtermCheckRect(xw, ParamPair(0), &checksum);
5126 init_reply(ANSI_DCS);
5127 count = 0;
5128 checksum &= 0xffff;
5129 pid = GetParam(0);
5130 reply.a_param[count++] = (ParmType) pid;
5131 reply.a_delim = "!~"; /* delimiter */
5132 reply.a_radix[count] = 16;
5133 reply.a_param[count++] = (ParmType) checksum;
5134 reply.a_nparam = (ParmType) count;
5135 TRACE(("...checksum(%d) = %04X\n", pid, checksum));
5136 unparseseq(xw, &reply);
5137 }
5138 ResetState(sp);
5139 break;
5140
5141 case CASE_DECCRA:
5142 if (screen->vtXX_level >= 4) {
5143 TRACE(("CASE_DECCRA - Copy rectangular area\n"));
5144 xtermParseRect(xw, ParamPair(0), &myRect);
5145 ScrnCopyRectangle(xw, &myRect, ParamPair(5));
5146 }
5147 ResetState(sp);
5148 break;
5149