uvtd: vt: implement VT_GETMODE/SETMODE ioctl state-tracking
[platform/upstream/kmscon.git] / src / tsm_vte.c
1 /*
2  * TSM - VT Emulator
3  *
4  * Copyright (c) 2011 David Herrmann <dh.herrmann@googlemail.com>
5  * Copyright (c) 2011 University of Tuebingen
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files
9  * (the "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26
27 /*
28  * Virtual Terminal Emulator
29  * This is the VT implementation. It is written from scratch. It uses the
30  * screen state-machine as output and is tightly bound to it. It supports
31  * functionality from vt100 up to vt500 series. It doesn't implement an
32  * explicitly selected terminal but tries to support the most important commands
33  * to be compatible with existing implementations. However, full vt102
34  * compatibility is the least that is provided.
35  *
36  * The main parser in this file controls the parser-state and dispatches the
37  * actions to the related handlers. The parser is based on the state-diagram
38  * from Paul Williams: http://vt100.net/emu/
39  * It is written from scratch, though.
40  * This parser is fully compatible up to the vt500 series. It requires UTF-8 and
41  * does not support any other input encoding. The G0 and G1 sets are therefore
42  * defined as subsets of UTF-8. You may still map G0-G3 into GL, though.
43  *
44  * However, the CSI/DCS/etc handlers are not designed after a specific VT
45  * series. We try to support all vt102 commands but implement several other
46  * often used sequences, too. Feel free to add further.
47  *
48  * See ./doc/vte.txt for more information on this VT-emulator.
49  */
50
51 #include <errno.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <xkbcommon/xkbcommon-keysyms.h>
56 #include "shl_llog.h"
57 #include "shl_misc.h"
58 #include "tsm_screen.h"
59 #include "tsm_unicode.h"
60 #include "tsm_vte.h"
61
62 #define LLOG_SUBSYSTEM "tsm_vte"
63
64 /* Input parser states */
65 enum parser_state {
66         STATE_NONE,             /* placeholder */
67         STATE_GROUND,           /* initial state and ground */
68         STATE_ESC,              /* ESC sequence was started */
69         STATE_ESC_INT,          /* intermediate escape characters */
70         STATE_CSI_ENTRY,        /* starting CSI sequence */
71         STATE_CSI_PARAM,        /* CSI parameters */
72         STATE_CSI_INT,          /* intermediate CSI characters */
73         STATE_CSI_IGNORE,       /* CSI error; ignore this CSI sequence */
74         STATE_DCS_ENTRY,        /* starting DCS sequence */
75         STATE_DCS_PARAM,        /* DCS parameters */
76         STATE_DCS_INT,          /* intermediate DCS characters */
77         STATE_DCS_PASS,         /* DCS data passthrough */
78         STATE_DCS_IGNORE,       /* DCS error; ignore this DCS sequence */
79         STATE_OSC_STRING,       /* parsing OCS sequence */
80         STATE_ST_IGNORE,        /* unimplemented seq; ignore until ST */
81         STATE_NUM
82 };
83
84 /* Input parser actions */
85 enum parser_action {
86         ACTION_NONE,            /* placeholder */
87         ACTION_IGNORE,          /* ignore the character entirely */
88         ACTION_PRINT,           /* print the character on the console */
89         ACTION_EXECUTE,         /* execute single control character (C0/C1) */
90         ACTION_CLEAR,           /* clear current parameter state */
91         ACTION_COLLECT,         /* collect intermediate character */
92         ACTION_PARAM,           /* collect parameter character */
93         ACTION_ESC_DISPATCH,    /* dispatch escape sequence */
94         ACTION_CSI_DISPATCH,    /* dispatch csi sequence */
95         ACTION_DCS_START,       /* start of DCS data */
96         ACTION_DCS_COLLECT,     /* collect DCS data */
97         ACTION_DCS_END,         /* end of DCS data */
98         ACTION_OSC_START,       /* start of OSC data */
99         ACTION_OSC_COLLECT,     /* collect OSC data */
100         ACTION_OSC_END,         /* end of OSC data */
101         ACTION_NUM
102 };
103
104 /* CSI flags */
105 #define CSI_BANG        0x0001          /* CSI: ! */
106 #define CSI_CASH        0x0002          /* CSI: $ */
107 #define CSI_WHAT        0x0004          /* CSI: ? */
108 #define CSI_GT          0x0008          /* CSI: > */
109 #define CSI_SPACE       0x0010          /* CSI:   */
110 #define CSI_SQUOTE      0x0020          /* CSI: ' */
111 #define CSI_DQUOTE      0x0040          /* CSI: " */
112 #define CSI_MULT        0x0080          /* CSI: * */
113 #define CSI_PLUS        0x0100          /* CSI: + */
114 #define CSI_POPEN       0x0200          /* CSI: ( */
115 #define CSI_PCLOSE      0x0400          /* CSI: ) */
116
117 /* max CSI arguments */
118 #define CSI_ARG_MAX 16
119
120 /* terminal flags */
121 #define FLAG_CURSOR_KEY_MODE                    0x00000001 /* DEC cursor key mode */
122 #define FLAG_KEYPAD_APPLICATION_MODE            0x00000002 /* DEC keypad application mode; TODO: toggle on numlock? */
123 #define FLAG_LINE_FEED_NEW_LINE_MODE            0x00000004 /* DEC line-feed/new-line mode */
124 #define FLAG_8BIT_MODE                          0x00000008 /* Disable UTF-8 mode and enable 8bit compatible mode */
125 #define FLAG_7BIT_MODE                          0x00000010 /* Disable 8bit mode and use 7bit compatible mode */
126 #define FLAG_USE_C1                             0x00000020 /* Explicitly use 8bit C1 codes; TODO: implement */
127 #define FLAG_KEYBOARD_ACTION_MODE               0x00000040 /* Disable keyboard; TODO: implement? */
128 #define FLAG_INSERT_REPLACE_MODE                0x00000080 /* Enable insert mode */
129 #define FLAG_SEND_RECEIVE_MODE                  0x00000100 /* Disable local echo */
130 #define FLAG_TEXT_CURSOR_MODE                   0x00000200 /* Show cursor */
131 #define FLAG_INVERSE_SCREEN_MODE                0x00000400 /* Inverse colors */
132 #define FLAG_ORIGIN_MODE                        0x00000800 /* Relative origin for cursor */
133 #define FLAG_AUTO_WRAP_MODE                     0x00001000 /* Auto line wrap mode */
134 #define FLAG_AUTO_REPEAT_MODE                   0x00002000 /* Auto repeat key press; TODO: implement */
135 #define FLAG_NATIONAL_CHARSET_MODE              0x00004000 /* Send keys from nation charsets; TODO: implement */
136 #define FLAG_BACKGROUND_COLOR_ERASE_MODE        0x00008000 /* Set background color on erase (bce) */
137 #define FLAG_PREPEND_ESCAPE                     0x00010000 /* Prepend escape character to next output */
138 #define FLAG_TITE_INHIBIT_MODE                  0x00020000 /* Prevent switching to alternate screen buffer */
139
140 struct vte_saved_state {
141         unsigned int cursor_x;
142         unsigned int cursor_y;
143         struct tsm_screen_attr cattr;
144         tsm_vte_charset **gl;
145         tsm_vte_charset **gr;
146         bool wrap_mode;
147         bool origin_mode;
148 };
149
150 struct tsm_vte {
151         unsigned long ref;
152         tsm_log_t llog;
153         void *llog_data;
154         struct tsm_screen *con;
155         tsm_vte_write_cb write_cb;
156         void *data;
157         char *palette_name;
158
159         struct tsm_utf8_mach *mach;
160         unsigned long parse_cnt;
161
162         unsigned int state;
163         unsigned int csi_argc;
164         int csi_argv[CSI_ARG_MAX];
165         unsigned int csi_flags;
166
167         uint8_t (*palette)[3];
168         struct tsm_screen_attr def_attr;
169         struct tsm_screen_attr cattr;
170         unsigned int flags;
171
172         tsm_vte_charset **gl;
173         tsm_vte_charset **gr;
174         tsm_vte_charset **glt;
175         tsm_vte_charset **grt;
176         tsm_vte_charset *g0;
177         tsm_vte_charset *g1;
178         tsm_vte_charset *g2;
179         tsm_vte_charset *g3;
180
181         struct vte_saved_state saved_state;
182         unsigned int alt_cursor_x;
183         unsigned int alt_cursor_y;
184 };
185
186 enum vte_color {
187         COLOR_BLACK,
188         COLOR_RED,
189         COLOR_GREEN,
190         COLOR_YELLOW,
191         COLOR_BLUE,
192         COLOR_MAGENTA,
193         COLOR_CYAN,
194         COLOR_LIGHT_GREY,
195         COLOR_DARK_GREY,
196         COLOR_LIGHT_RED,
197         COLOR_LIGHT_GREEN,
198         COLOR_LIGHT_YELLOW,
199         COLOR_LIGHT_BLUE,
200         COLOR_LIGHT_MAGENTA,
201         COLOR_LIGHT_CYAN,
202         COLOR_WHITE,
203         COLOR_FOREGROUND,
204         COLOR_BACKGROUND,
205         COLOR_NUM
206 };
207
208 static uint8_t color_palette[COLOR_NUM][3] = {
209         [COLOR_BLACK]         = {   0,   0,   0 }, /* black */
210         [COLOR_RED]           = { 205,   0,   0 }, /* red */
211         [COLOR_GREEN]         = {   0, 205,   0 }, /* green */
212         [COLOR_YELLOW]        = { 205, 205,   0 }, /* yellow */
213         [COLOR_BLUE]          = {   0,   0, 238 }, /* blue */
214         [COLOR_MAGENTA]       = { 205,   0, 205 }, /* magenta */
215         [COLOR_CYAN]          = {   0, 205, 205 }, /* cyan */
216         [COLOR_LIGHT_GREY]    = { 229, 229, 229 }, /* light grey */
217         [COLOR_DARK_GREY]     = { 127, 127, 127 }, /* dark grey */
218         [COLOR_LIGHT_RED]     = { 255,   0,   0 }, /* light red */
219         [COLOR_LIGHT_GREEN]   = {   0, 255,   0 }, /* light green */
220         [COLOR_LIGHT_YELLOW]  = { 255, 255,   0 }, /* light yellow */
221         [COLOR_LIGHT_BLUE]    = {  92,  92, 255 }, /* light blue */
222         [COLOR_LIGHT_MAGENTA] = { 255,   0, 255 }, /* light magenta */
223         [COLOR_LIGHT_CYAN]    = {   0, 255, 255 }, /* light cyan */
224         [COLOR_WHITE]         = { 255, 255, 255 }, /* white */
225
226         [COLOR_FOREGROUND]    = { 229, 229, 229 }, /* light grey */
227         [COLOR_BACKGROUND]    = {   0,   0,   0 }, /* black */
228 };
229
230 static uint8_t color_palette_solarized[COLOR_NUM][3] = {
231         [COLOR_BLACK]         = {   7,  54,  66 }, /* black */
232         [COLOR_RED]           = { 220,  50,  47 }, /* red */
233         [COLOR_GREEN]         = { 133, 153,   0 }, /* green */
234         [COLOR_YELLOW]        = { 181, 137,   0 }, /* yellow */
235         [COLOR_BLUE]          = {  38, 139, 210 }, /* blue */
236         [COLOR_MAGENTA]       = { 211,  54, 130 }, /* magenta */
237         [COLOR_CYAN]          = {  42, 161, 152 }, /* cyan */
238         [COLOR_LIGHT_GREY]    = { 238, 232, 213 }, /* light grey */
239         [COLOR_DARK_GREY]     = {   0,  43,  54 }, /* dark grey */
240         [COLOR_LIGHT_RED]     = { 203,  75,  22 }, /* light red */
241         [COLOR_LIGHT_GREEN]   = {  88, 110, 117 }, /* light green */
242         [COLOR_LIGHT_YELLOW]  = { 101, 123, 131 }, /* light yellow */
243         [COLOR_LIGHT_BLUE]    = { 131, 148, 150 }, /* light blue */
244         [COLOR_LIGHT_MAGENTA] = { 108, 113, 196 }, /* light magenta */
245         [COLOR_LIGHT_CYAN]    = { 147, 161, 161 }, /* light cyan */
246         [COLOR_WHITE]         = { 253, 246, 227 }, /* white */
247
248         [COLOR_FOREGROUND]    = { 238, 232, 213 }, /* light grey */
249         [COLOR_BACKGROUND]    = {   7,  54,  66 }, /* black */
250 };
251
252 static uint8_t color_palette_solarized_black[COLOR_NUM][3] = {
253         [COLOR_BLACK]         = {   0,   0,   0 }, /* black */
254         [COLOR_RED]           = { 220,  50,  47 }, /* red */
255         [COLOR_GREEN]         = { 133, 153,   0 }, /* green */
256         [COLOR_YELLOW]        = { 181, 137,   0 }, /* yellow */
257         [COLOR_BLUE]          = {  38, 139, 210 }, /* blue */
258         [COLOR_MAGENTA]       = { 211,  54, 130 }, /* magenta */
259         [COLOR_CYAN]          = {  42, 161, 152 }, /* cyan */
260         [COLOR_LIGHT_GREY]    = { 238, 232, 213 }, /* light grey */
261         [COLOR_DARK_GREY]     = {   0,  43,  54 }, /* dark grey */
262         [COLOR_LIGHT_RED]     = { 203,  75,  22 }, /* light red */
263         [COLOR_LIGHT_GREEN]   = {  88, 110, 117 }, /* light green */
264         [COLOR_LIGHT_YELLOW]  = { 101, 123, 131 }, /* light yellow */
265         [COLOR_LIGHT_BLUE]    = { 131, 148, 150 }, /* light blue */
266         [COLOR_LIGHT_MAGENTA] = { 108, 113, 196 }, /* light magenta */
267         [COLOR_LIGHT_CYAN]    = { 147, 161, 161 }, /* light cyan */
268         [COLOR_WHITE]         = { 253, 246, 227 }, /* white */
269
270         [COLOR_FOREGROUND]    = { 238, 232, 213 }, /* light grey */
271         [COLOR_BACKGROUND]    = {   0,   0,   0 }, /* black */
272 };
273
274 static uint8_t color_palette_solarized_white[COLOR_NUM][3] = {
275         [COLOR_BLACK]         = {   7,  54,  66 }, /* black */
276         [COLOR_RED]           = { 220,  50,  47 }, /* red */
277         [COLOR_GREEN]         = { 133, 153,   0 }, /* green */
278         [COLOR_YELLOW]        = { 181, 137,   0 }, /* yellow */
279         [COLOR_BLUE]          = {  38, 139, 210 }, /* blue */
280         [COLOR_MAGENTA]       = { 211,  54, 130 }, /* magenta */
281         [COLOR_CYAN]          = {  42, 161, 152 }, /* cyan */
282         [COLOR_LIGHT_GREY]    = { 238, 232, 213 }, /* light grey */
283         [COLOR_DARK_GREY]     = {   0,  43,  54 }, /* dark grey */
284         [COLOR_LIGHT_RED]     = { 203,  75,  22 }, /* light red */
285         [COLOR_LIGHT_GREEN]   = {  88, 110, 117 }, /* light green */
286         [COLOR_LIGHT_YELLOW]  = { 101, 123, 131 }, /* light yellow */
287         [COLOR_LIGHT_BLUE]    = { 131, 148, 150 }, /* light blue */
288         [COLOR_LIGHT_MAGENTA] = { 108, 113, 196 }, /* light magenta */
289         [COLOR_LIGHT_CYAN]    = { 147, 161, 161 }, /* light cyan */
290         [COLOR_WHITE]         = { 253, 246, 227 }, /* white */
291
292         [COLOR_FOREGROUND]    = {   7,  54,  66 }, /* black */
293         [COLOR_BACKGROUND]    = { 238, 232, 213 }, /* light grey */
294 };
295
296 static uint8_t (*get_palette(struct tsm_vte *vte))[3]
297 {
298         if (!vte->palette_name)
299                 return color_palette;
300
301         if (!strcmp(vte->palette_name, "solarized"))
302                 return color_palette_solarized;
303         if (!strcmp(vte->palette_name, "solarized-black"))
304                 return color_palette_solarized_black;
305         if (!strcmp(vte->palette_name, "solarized-white"))
306                 return color_palette_solarized_white;
307
308         return color_palette;
309 }
310
311 /* Several effects may occur when non-RGB colors are used. For instance, if bold
312  * is enabled, then a dark color code is always converted to a light color to
313  * simulate bold (even though bold may actually be supported!). To support this,
314  * we need to differentiate between a set color-code and a set rgb-color.
315  * This function actually converts a set color-code into an RGB color. This must
316  * be called before passing the attribute to the console layer so the console
317  * layer can always work with RGB values and does not have to care for color
318  * codes. */
319 static void to_rgb(struct tsm_vte *vte, struct tsm_screen_attr *attr)
320 {
321         int8_t code;
322
323         code = attr->fccode;
324         if (code >= 0) {
325                 /* bold causes light colors */
326                 if (attr->bold && code < 8)
327                         code += 8;
328                 if (code >= COLOR_NUM)
329                         code = COLOR_FOREGROUND;
330
331                 attr->fr = vte->palette[code][0];
332                 attr->fg = vte->palette[code][1];
333                 attr->fb = vte->palette[code][2];
334         }
335
336         code = attr->bccode;
337         if (code >= 0) {
338                 if (code >= COLOR_NUM)
339                         code = COLOR_BACKGROUND;
340
341                 attr->br = vte->palette[code][0];
342                 attr->bg = vte->palette[code][1];
343                 attr->bb = vte->palette[code][2];
344         }
345 }
346
347 static void copy_fcolor(struct tsm_screen_attr *dest,
348                         const struct tsm_screen_attr *src)
349 {
350         dest->fccode = src->fccode;
351         dest->fr = src->fr;
352         dest->fg = src->fg;
353         dest->fb = src->fb;
354 }
355
356 static void copy_bcolor(struct tsm_screen_attr *dest,
357                         const struct tsm_screen_attr *src)
358 {
359         dest->bccode = src->bccode;
360         dest->br = src->br;
361         dest->bg = src->bg;
362         dest->bb = src->bb;
363 }
364
365 SHL_EXPORT
366 int tsm_vte_new(struct tsm_vte **out, struct tsm_screen *con,
367                 tsm_vte_write_cb write_cb, void *data,
368                 tsm_log_t log, void *log_data)
369 {
370         struct tsm_vte *vte;
371         int ret;
372
373         if (!out || !con || !write_cb)
374                 return -EINVAL;
375
376         vte = malloc(sizeof(*vte));
377         if (!vte)
378                 return -ENOMEM;
379
380         memset(vte, 0, sizeof(*vte));
381         vte->ref = 1;
382         vte->llog = log;
383         vte->llog_data = log_data;
384         vte->con = con;
385         vte->write_cb = write_cb;
386         vte->data = data;
387         vte->palette = get_palette(vte);
388         vte->def_attr.fccode = COLOR_FOREGROUND;
389         vte->def_attr.bccode = COLOR_BACKGROUND;
390         to_rgb(vte, &vte->def_attr);
391
392         ret = tsm_utf8_mach_new(&vte->mach);
393         if (ret)
394                 goto err_free;
395
396         tsm_vte_reset(vte);
397         tsm_screen_erase_screen(vte->con, false);
398
399         llog_debug(vte, "new vte object");
400         tsm_screen_ref(vte->con);
401         *out = vte;
402         return 0;
403
404 err_free:
405         free(vte);
406         return ret;
407 }
408
409 SHL_EXPORT
410 void tsm_vte_ref(struct tsm_vte *vte)
411 {
412         if (!vte)
413                 return;
414
415         vte->ref++;
416 }
417
418 SHL_EXPORT
419 void tsm_vte_unref(struct tsm_vte *vte)
420 {
421         if (!vte || !vte->ref)
422                 return;
423
424         if (--vte->ref)
425                 return;
426
427         llog_debug(vte, "destroying vte object");
428         tsm_screen_unref(vte->con);
429         tsm_utf8_mach_free(vte->mach);
430         free(vte);
431 }
432
433 SHL_EXPORT
434 int tsm_vte_set_palette(struct tsm_vte *vte, const char *palette)
435 {
436         char *tmp = NULL;
437
438         if (!vte)
439                 return -EINVAL;
440
441         if (palette) {
442                 tmp = strdup(palette);
443                 if (!tmp)
444                         return -ENOMEM;
445         }
446
447         free(vte->palette_name);
448         vte->palette_name = tmp;
449
450         vte->palette = get_palette(vte);
451         vte->def_attr.fccode = COLOR_FOREGROUND;
452         vte->def_attr.bccode = COLOR_BACKGROUND;
453
454         to_rgb(vte, &vte->def_attr);
455         memcpy(&vte->cattr, &vte->def_attr, sizeof(vte->cattr));
456
457         tsm_screen_set_def_attr(vte->con, &vte->def_attr);
458         tsm_screen_erase_screen(vte->con, false);
459
460         return 0;
461 }
462
463 /*
464  * Write raw byte-stream to pty.
465  * When writing data to the client we must make sure that we send the correct
466  * encoding. For backwards-compatibility reasons we should always send 7bit
467  * characters exclusively. However, when FLAG_7BIT_MODE is not set, then we can
468  * also send raw 8bit characters. For instance, in FLAG_8BIT_MODE we can use the
469  * GR characters as keyboard input and send them directly or even use the C1
470  * escape characters. In unicode mode (default) we can send multi-byte utf-8
471  * characters which are also 8bit. When sending these characters, set the \raw
472  * flag to true so this function does not perform debug checks on data we send.
473  * If debugging is disabled, these checks are also disabled and won't affect
474  * performance.
475  * For better debugging, we also use the __LINE__ and __FILE__ macros. Use the
476  * vte_write() and vte_write_raw() macros below for more convenient use.
477  *
478  * As a rule of thumb do never send 8bit characters in escape sequences and also
479  * avoid all 8bit escape codes including the C1 codes. This will guarantee that
480  * all kind of clients are always compatible to us.
481  *
482  * If SEND_RECEIVE_MODE is off (that is, local echo is on) we have to send all
483  * data directly to ourself again. However, we must avoid recursion when
484  * tsm_vte_input() itself calls vte_write*(), therefore, we increase the
485  * PARSER counter when entering tsm_vte_input() and reset it when leaving it
486  * so we never echo data that origins from tsm_vte_input().
487  * But note that SEND_RECEIVE_MODE is inherently broken for escape sequences
488  * that request answers. That is, if we send a request to the client that awaits
489  * a response and parse that request via local echo ourself, then we will also
490  * send a response to the client even though he didn't request one. This
491  * recursion fix does not avoid this but only prevents us from endless loops
492  * here. Anyway, only few applications rely on local echo so we can safely
493  * ignore this.
494  */
495 static void vte_write_debug(struct tsm_vte *vte, const char *u8, size_t len,
496                             bool raw, const char *file, int line)
497 {
498 #ifdef BUILD_ENABLE_DEBUG
499         /* in debug mode we check that escape sequences are always <0x7f so they
500          * are correctly parsed by non-unicode and non-8bit-mode clients. */
501         size_t i;
502
503         if (!raw) {
504                 for (i = 0; i < len; ++i) {
505                         if (u8[i] & 0x80)
506                                 llog_warning(vte, "sending 8bit character inline to client in %s:%d",
507                                              file, line);
508                 }
509         }
510 #endif
511
512         /* in local echo mode, directly parse the data again */
513         if (!vte->parse_cnt && !(vte->flags & FLAG_SEND_RECEIVE_MODE)) {
514                 if (vte->flags & FLAG_PREPEND_ESCAPE)
515                         tsm_vte_input(vte, "\e", 1);
516                 tsm_vte_input(vte, u8, len);
517         }
518
519         if (vte->flags & FLAG_PREPEND_ESCAPE)
520                 vte->write_cb(vte, "\e", 1, vte->data);
521         vte->write_cb(vte, u8, len, vte->data);
522
523         vte->flags &= ~FLAG_PREPEND_ESCAPE;
524 }
525
526 #define vte_write(_vte, _u8, _len) \
527         vte_write_debug((_vte), (_u8), (_len), false, __FILE__, __LINE__)
528 #define vte_write_raw(_vte, _u8, _len) \
529         vte_write_debug((_vte), (_u8), (_len), true, __FILE__, __LINE__)
530
531 /* write to console */
532 static void write_console(struct tsm_vte *vte, tsm_symbol_t sym)
533 {
534         to_rgb(vte, &vte->cattr);
535         tsm_screen_write(vte->con, sym, &vte->cattr);
536 }
537
538 static void reset_state(struct tsm_vte *vte)
539 {
540         vte->saved_state.cursor_x = 0;
541         vte->saved_state.cursor_y = 0;
542         vte->saved_state.origin_mode = false;
543         vte->saved_state.wrap_mode = true;
544         vte->saved_state.gl = &vte->g0;
545         vte->saved_state.gr = &vte->g1;
546
547         copy_fcolor(&vte->saved_state.cattr, &vte->def_attr);
548         copy_bcolor(&vte->saved_state.cattr, &vte->def_attr);
549         vte->saved_state.cattr.bold = 0;
550         vte->saved_state.cattr.underline = 0;
551         vte->saved_state.cattr.inverse = 0;
552         vte->saved_state.cattr.protect = 0;
553 }
554
555 static void save_state(struct tsm_vte *vte)
556 {
557         vte->saved_state.cursor_x = tsm_screen_get_cursor_x(vte->con);
558         vte->saved_state.cursor_y = tsm_screen_get_cursor_y(vte->con);
559         vte->saved_state.cattr = vte->cattr;
560         vte->saved_state.gl = vte->gl;
561         vte->saved_state.gr = vte->gr;
562         vte->saved_state.wrap_mode = vte->flags & FLAG_AUTO_WRAP_MODE;
563         vte->saved_state.origin_mode = vte->flags & FLAG_ORIGIN_MODE;
564 }
565
566 static void restore_state(struct tsm_vte *vte)
567 {
568         tsm_screen_move_to(vte->con, vte->saved_state.cursor_x,
569                                vte->saved_state.cursor_y);
570         vte->cattr = vte->saved_state.cattr;
571         to_rgb(vte, &vte->cattr);
572         if (vte->flags & FLAG_BACKGROUND_COLOR_ERASE_MODE)
573                 tsm_screen_set_def_attr(vte->con, &vte->cattr);
574         vte->gl = vte->saved_state.gl;
575         vte->gr = vte->saved_state.gr;
576
577         if (vte->saved_state.wrap_mode) {
578                 vte->flags |= FLAG_AUTO_WRAP_MODE;
579                 tsm_screen_set_flags(vte->con, TSM_SCREEN_AUTO_WRAP);
580         } else {
581                 vte->flags &= ~FLAG_AUTO_WRAP_MODE;
582                 tsm_screen_reset_flags(vte->con, TSM_SCREEN_AUTO_WRAP);
583         }
584
585         if (vte->saved_state.origin_mode) {
586                 vte->flags |= FLAG_ORIGIN_MODE;
587                 tsm_screen_set_flags(vte->con, TSM_SCREEN_REL_ORIGIN);
588         } else {
589                 vte->flags &= ~FLAG_ORIGIN_MODE;
590                 tsm_screen_reset_flags(vte->con, TSM_SCREEN_REL_ORIGIN);
591         }
592 }
593
594 /*
595  * Reset VTE state
596  * This performs a soft reset of the VTE. That is, everything is reset to the
597  * same state as when the VTE was created. This does not affect the console,
598  * though.
599  */
600 SHL_EXPORT
601 void tsm_vte_reset(struct tsm_vte *vte)
602 {
603         if (!vte)
604                 return;
605
606         vte->flags = 0;
607         vte->flags |= FLAG_TEXT_CURSOR_MODE;
608         vte->flags |= FLAG_AUTO_REPEAT_MODE;
609         vte->flags |= FLAG_SEND_RECEIVE_MODE;
610         vte->flags |= FLAG_AUTO_WRAP_MODE;
611         vte->flags |= FLAG_BACKGROUND_COLOR_ERASE_MODE;
612         tsm_screen_reset(vte->con);
613         tsm_screen_set_flags(vte->con, TSM_SCREEN_AUTO_WRAP);
614
615         tsm_utf8_mach_reset(vte->mach);
616         vte->state = STATE_GROUND;
617         vte->gl = &vte->g0;
618         vte->gr = &vte->g1;
619         vte->glt = NULL;
620         vte->grt = NULL;
621         vte->g0 = &tsm_vte_unicode_lower;
622         vte->g1 = &tsm_vte_unicode_upper;
623         vte->g2 = &tsm_vte_unicode_lower;
624         vte->g3 = &tsm_vte_unicode_upper;
625
626         memcpy(&vte->cattr, &vte->def_attr, sizeof(vte->cattr));
627         to_rgb(vte, &vte->cattr);
628         tsm_screen_set_def_attr(vte->con, &vte->def_attr);
629
630         reset_state(vte);
631 }
632
633 SHL_EXPORT
634 void tsm_vte_hard_reset(struct tsm_vte *vte)
635 {
636         tsm_vte_reset(vte);
637         tsm_screen_erase_screen(vte->con, false);
638         tsm_screen_clear_sb(vte->con);
639         tsm_screen_move_to(vte->con, 0, 0);
640 }
641
642 static void send_primary_da(struct tsm_vte *vte)
643 {
644         vte_write(vte, "\e[?60;1;6;9;15c", 17);
645 }
646
647 /* execute control character (C0 or C1) */
648 static void do_execute(struct tsm_vte *vte, uint32_t ctrl)
649 {
650         switch (ctrl) {
651         case 0x00: /* NUL */
652                 /* Ignore on input */
653                 break;
654         case 0x05: /* ENQ */
655                 /* Transmit answerback message */
656                 /* TODO: is there a better answer than ACK?  */
657                 vte_write(vte, "\x06", 1);
658                 break;
659         case 0x07: /* BEL */
660                 /* Sound bell tone */
661                 /* TODO: I always considered this annying, however, we
662                  * should at least provide some way to enable it if the
663                  * user *really* wants it.
664                  */
665                 break;
666         case 0x08: /* BS */
667                 /* Move cursor one position left */
668                 tsm_screen_move_left(vte->con, 1);
669                 break;
670         case 0x09: /* HT */
671                 /* Move to next tab stop or end of line */
672                 tsm_screen_tab_right(vte->con, 1);
673                 break;
674         case 0x0a: /* LF */
675         case 0x0b: /* VT */
676         case 0x0c: /* FF */
677                 /* Line feed or newline (CR/NL mode) */
678                 if (vte->flags & FLAG_LINE_FEED_NEW_LINE_MODE)
679                         tsm_screen_newline(vte->con);
680                 else
681                         tsm_screen_move_down(vte->con, 1, true);
682                 break;
683         case 0x0d: /* CR */
684                 /* Move cursor to left margin */
685                 tsm_screen_move_line_home(vte->con);
686                 break;
687         case 0x0e: /* SO */
688                 /* Map G1 character set into GL */
689                 vte->gl = &vte->g1;
690                 break;
691         case 0x0f: /* SI */
692                 /* Map G0 character set into GL */
693                 vte->gl = &vte->g0;
694                 break;
695         case 0x11: /* XON */
696                 /* Resume transmission */
697                 /* TODO */
698                 break;
699         case 0x13: /* XOFF */
700                 /* Stop transmission */
701                 /* TODO */
702                 break;
703         case 0x18: /* CAN */
704                 /* Cancel escape sequence */
705                 /* nothing to do here */
706                 break;
707         case 0x1a: /* SUB */
708                 /* Discard current escape sequence and show err-sym */
709                 write_console(vte, 0xbf);
710                 break;
711         case 0x1b: /* ESC */
712                 /* Invokes an escape sequence */
713                 /* nothing to do here */
714                 break;
715         case 0x1f: /* DEL */
716                 /* Ignored */
717                 break;
718         case 0x84: /* IND */
719                 /* Move down one row, perform scroll-up if needed */
720                 tsm_screen_move_down(vte->con, 1, true);
721                 break;
722         case 0x85: /* NEL */
723                 /* CR/NL with scroll-up if needed */
724                 tsm_screen_newline(vte->con);
725                 break;
726         case 0x88: /* HTS */
727                 /* Set tab stop at current position */
728                 tsm_screen_set_tabstop(vte->con);
729                 break;
730         case 0x8d: /* RI */
731                 /* Move up one row, perform scroll-down if needed */
732                 tsm_screen_move_up(vte->con, 1, true);
733                 break;
734         case 0x8e: /* SS2 */
735                 /* Temporarily map G2 into GL for next char only */
736                 vte->glt = &vte->g2;
737                 break;
738         case 0x8f: /* SS3 */
739                 /* Temporarily map G3 into GL for next char only */
740                 vte->glt = &vte->g3;
741                 break;
742         case 0x9a: /* DECID */
743                 /* Send device attributes response like ANSI DA */
744                 send_primary_da(vte);
745                 break;
746         case 0x9c: /* ST */
747                 /* End control string */
748                 /* nothing to do here */
749                 break;
750         default:
751                 llog_debug(vte, "unhandled control char %u", ctrl);
752         }
753 }
754
755 static void do_clear(struct tsm_vte *vte)
756 {
757         int i;
758
759         vte->csi_argc = 0;
760         for (i = 0; i < CSI_ARG_MAX; ++i)
761                 vte->csi_argv[i] = -1;
762         vte->csi_flags = 0;
763 }
764
765 static void do_collect(struct tsm_vte *vte, uint32_t data)
766 {
767         switch (data) {
768         case '!':
769                 vte->csi_flags |= CSI_BANG;
770                 break;
771         case '$':
772                 vte->csi_flags |= CSI_CASH;
773                 break;
774         case '?':
775                 vte->csi_flags |= CSI_WHAT;
776                 break;
777         case '>':
778                 vte->csi_flags |= CSI_GT;
779                 break;
780         case ' ':
781                 vte->csi_flags |= CSI_SPACE;
782                 break;
783         case '\'':
784                 vte->csi_flags |= CSI_SQUOTE;
785                 break;
786         case '"':
787                 vte->csi_flags |= CSI_DQUOTE;
788                 break;
789         case '*':
790                 vte->csi_flags |= CSI_MULT;
791                 break;
792         case '+':
793                 vte->csi_flags |= CSI_PLUS;
794                 break;
795         case '(':
796                 vte->csi_flags |= CSI_POPEN;
797                 break;
798         case ')':
799                 vte->csi_flags |= CSI_PCLOSE;
800                 break;
801         }
802 }
803
804 static void do_param(struct tsm_vte *vte, uint32_t data)
805 {
806         int new;
807
808         if (data == ';') {
809                 if (vte->csi_argc < CSI_ARG_MAX)
810                         vte->csi_argc++;
811                 return;
812         }
813
814         if (vte->csi_argc >= CSI_ARG_MAX)
815                 return;
816
817         /* avoid integer overflows; max allowed value is 16384 anyway */
818         if (vte->csi_argv[vte->csi_argc] > 0xffff)
819                 return;
820
821         if (data >= '0' && data <= '9') {
822                 new = vte->csi_argv[vte->csi_argc];
823                 if (new <= 0)
824                         new = data - '0';
825                 else
826                         new = new * 10 + data - '0';
827                 vte->csi_argv[vte->csi_argc] = new;
828         }
829 }
830
831 static bool set_charset(struct tsm_vte *vte, tsm_vte_charset *set)
832 {
833         if (vte->csi_flags & CSI_POPEN)
834                 vte->g0 = set;
835         else if (vte->csi_flags & CSI_PCLOSE)
836                 vte->g1 = set;
837         else if (vte->csi_flags & CSI_MULT)
838                 vte->g2 = set;
839         else if (vte->csi_flags & CSI_PLUS)
840                 vte->g3 = set;
841         else
842                 return false;
843
844         return true;
845 }
846
847 static void do_esc(struct tsm_vte *vte, uint32_t data)
848 {
849         switch (data) {
850         case 'B': /* map ASCII into G0-G3 */
851                 if (set_charset(vte, &tsm_vte_unicode_lower))
852                         return;
853                 break;
854         case '<': /* map DEC supplemental into G0-G3 */
855                 if (set_charset(vte, &tsm_vte_dec_supplemental_graphics))
856                         return;
857                 break;
858         case '0': /* map DEC special into G0-G3 */
859                 if (set_charset(vte, &tsm_vte_dec_special_graphics))
860                         return;
861                 break;
862         case 'A': /* map British into G0-G3 */
863                 /* TODO: create British charset from DEC */
864                 if (set_charset(vte, &tsm_vte_unicode_upper))
865                         return;
866                 break;
867         case '4': /* map Dutch into G0-G3 */
868                 /* TODO: create Dutch charset from DEC */
869                 if (set_charset(vte, &tsm_vte_unicode_upper))
870                         return;
871                 break;
872         case 'C':
873         case '5': /* map Finnish into G0-G3 */
874                 /* TODO: create Finnish charset from DEC */
875                 if (set_charset(vte, &tsm_vte_unicode_upper))
876                         return;
877                 break;
878         case 'R': /* map French into G0-G3 */
879                 /* TODO: create French charset from DEC */
880                 if (set_charset(vte, &tsm_vte_unicode_upper))
881                         return;
882                 break;
883         case 'Q': /* map French-Canadian into G0-G3 */
884                 /* TODO: create French-Canadian charset from DEC */
885                 if (set_charset(vte, &tsm_vte_unicode_upper))
886                         return;
887                 break;
888         case 'K': /* map German into G0-G3 */
889                 /* TODO: create German charset from DEC */
890                 if (set_charset(vte, &tsm_vte_unicode_upper))
891                         return;
892                 break;
893         case 'Y': /* map Italian into G0-G3 */
894                 /* TODO: create Italian charset from DEC */
895                 if (set_charset(vte, &tsm_vte_unicode_upper))
896                         return;
897                 break;
898         case 'E':
899         case '6': /* map Norwegian/Danish into G0-G3 */
900                 /* TODO: create Norwegian/Danish charset from DEC */
901                 if (set_charset(vte, &tsm_vte_unicode_upper))
902                         return;
903                 break;
904         case 'Z': /* map Spanish into G0-G3 */
905                 /* TODO: create Spanish charset from DEC */
906                 if (set_charset(vte, &tsm_vte_unicode_upper))
907                         return;
908                 break;
909         case 'H':
910         case '7': /* map Swedish into G0-G3 */
911                 /* TODO: create Swedish charset from DEC */
912                 if (set_charset(vte, &tsm_vte_unicode_upper))
913                         return;
914                 break;
915         case '=': /* map Swiss into G0-G3 */
916                 /* TODO: create Swiss charset from DEC */
917                 if (set_charset(vte, &tsm_vte_unicode_upper))
918                         return;
919                 break;
920         case 'F':
921                 if (vte->csi_flags & CSI_SPACE) {
922                         /* S7C1T */
923                         /* Disable 8bit C1 mode */
924                         vte->flags &= ~FLAG_USE_C1;
925                         return;
926                 }
927                 break;
928         case 'G':
929                 if (vte->csi_flags & CSI_SPACE) {
930                         /* S8C1T */
931                         /* Enable 8bit C1 mode */
932                         vte->flags |= FLAG_USE_C1;
933                         return;
934                 }
935                 break;
936         }
937
938         /* everything below is only valid without CSI flags */
939         if (vte->csi_flags) {
940                 llog_debug(vte, "unhandled escape seq %u", data);
941                 return;
942         }
943
944         switch (data) {
945         case 'D': /* IND */
946                 /* Move down one row, perform scroll-up if needed */
947                 tsm_screen_move_down(vte->con, 1, true);
948                 break;
949         case 'E': /* NEL */
950                 /* CR/NL with scroll-up if needed */
951                 tsm_screen_newline(vte->con);
952                 break;
953         case 'H': /* HTS */
954                 /* Set tab stop at current position */
955                 tsm_screen_set_tabstop(vte->con);
956                 break;
957         case 'M': /* RI */
958                 /* Move up one row, perform scroll-down if needed */
959                 tsm_screen_move_up(vte->con, 1, true);
960                 break;
961         case 'N': /* SS2 */
962                 /* Temporarily map G2 into GL for next char only */
963                 vte->glt = &vte->g2;
964                 break;
965         case 'O': /* SS3 */
966                 /* Temporarily map G3 into GL for next char only */
967                 vte->glt = &vte->g3;
968                 break;
969         case 'Z': /* DECID */
970                 /* Send device attributes response like ANSI DA */
971                 send_primary_da(vte);
972                 break;
973         case '\\': /* ST */
974                 /* End control string */
975                 /* nothing to do here */
976                 break;
977         case '~': /* LS1R */
978                 /* Invoke G1 into GR */
979                 vte->gr = &vte->g1;
980                 break;
981         case 'n': /* LS2 */
982                 /* Invoke G2 into GL */
983                 vte->gl = &vte->g2;
984                 break;
985         case '}': /* LS2R */
986                 /* Invoke G2 into GR */
987                 vte->gr = &vte->g2;
988                 break;
989         case 'o': /* LS3 */
990                 /* Invoke G3 into GL */
991                 vte->gl = &vte->g3;
992                 break;
993         case '|': /* LS3R */
994                 /* Invoke G3 into GR */
995                 vte->gr = &vte->g3;
996                 break;
997         case '=': /* DECKPAM */
998                 /* Set application keypad mode */
999                 vte->flags |= FLAG_KEYPAD_APPLICATION_MODE;
1000                 break;
1001         case '>': /* DECKPNM */
1002                 /* Set numeric keypad mode */
1003                 vte->flags &= ~FLAG_KEYPAD_APPLICATION_MODE;
1004                 break;
1005         case 'c': /* RIS */
1006                 /* hard reset */
1007                 tsm_vte_hard_reset(vte);
1008                 break;
1009         case '7': /* DECSC */
1010                 /* save console state */
1011                 save_state(vte);
1012                 break;
1013         case '8': /* DECRC */
1014                 /* restore console state */
1015                 restore_state(vte);
1016                 break;
1017         default:
1018                 llog_debug(vte, "unhandled escape seq %u", data);
1019         }
1020 }
1021
1022 static void csi_attribute(struct tsm_vte *vte)
1023 {
1024         static const uint8_t bval[6] = { 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff };
1025         unsigned int i, code;
1026
1027         if (vte->csi_argc <= 1 && vte->csi_argv[0] == -1) {
1028                 vte->csi_argc = 1;
1029                 vte->csi_argv[0] = 0;
1030         }
1031
1032         for (i = 0; i < vte->csi_argc; ++i) {
1033                 switch (vte->csi_argv[i]) {
1034                 case -1:
1035                         break;
1036                 case 0:
1037                         copy_fcolor(&vte->cattr, &vte->def_attr);
1038                         copy_bcolor(&vte->cattr, &vte->def_attr);
1039                         vte->cattr.bold = 0;
1040                         vte->cattr.underline = 0;
1041                         vte->cattr.inverse = 0;
1042                         break;
1043                 case 1:
1044                         vte->cattr.bold = 1;
1045                         break;
1046                 case 4:
1047                         vte->cattr.underline = 1;
1048                         break;
1049                 case 7:
1050                         vte->cattr.inverse = 1;
1051                         break;
1052                 case 22:
1053                         vte->cattr.bold = 0;
1054                         break;
1055                 case 24:
1056                         vte->cattr.underline = 0;
1057                         break;
1058                 case 27:
1059                         vte->cattr.inverse = 0;
1060                         break;
1061                 case 30:
1062                         vte->cattr.fccode = COLOR_BLACK;
1063                         break;
1064                 case 31:
1065                         vte->cattr.fccode = COLOR_RED;
1066                         break;
1067                 case 32:
1068                         vte->cattr.fccode = COLOR_GREEN;
1069                         break;
1070                 case 33:
1071                         vte->cattr.fccode = COLOR_YELLOW;
1072                         break;
1073                 case 34:
1074                         vte->cattr.fccode = COLOR_BLUE;
1075                         break;
1076                 case 35:
1077                         vte->cattr.fccode = COLOR_MAGENTA;
1078                         break;
1079                 case 36:
1080                         vte->cattr.fccode = COLOR_CYAN;
1081                         break;
1082                 case 37:
1083                         vte->cattr.fccode = COLOR_LIGHT_GREY;
1084                         break;
1085                 case 39:
1086                         copy_fcolor(&vte->cattr, &vte->def_attr);
1087                         break;
1088                 case 40:
1089                         vte->cattr.bccode = COLOR_BLACK;
1090                         break;
1091                 case 41:
1092                         vte->cattr.bccode = COLOR_RED;
1093                         break;
1094                 case 42:
1095                         vte->cattr.bccode = COLOR_GREEN;
1096                         break;
1097                 case 43:
1098                         vte->cattr.bccode = COLOR_YELLOW;
1099                         break;
1100                 case 44:
1101                         vte->cattr.bccode = COLOR_BLUE;
1102                         break;
1103                 case 45:
1104                         vte->cattr.bccode = COLOR_MAGENTA;
1105                         break;
1106                 case 46:
1107                         vte->cattr.bccode = COLOR_CYAN;
1108                         break;
1109                 case 47:
1110                         vte->cattr.bccode = COLOR_LIGHT_GREY;
1111                         break;
1112                 case 49:
1113                         copy_bcolor(&vte->cattr, &vte->def_attr);
1114                         break;
1115                 case 90:
1116                         vte->cattr.fccode = COLOR_DARK_GREY;
1117                         break;
1118                 case 91:
1119                         vte->cattr.fccode = COLOR_LIGHT_RED;
1120                         break;
1121                 case 92:
1122                         vte->cattr.fccode = COLOR_LIGHT_GREEN;
1123                         break;
1124                 case 93:
1125                         vte->cattr.fccode = COLOR_LIGHT_YELLOW;
1126                         break;
1127                 case 94:
1128                         vte->cattr.fccode = COLOR_LIGHT_BLUE;
1129                         break;
1130                 case 95:
1131                         vte->cattr.fccode = COLOR_LIGHT_MAGENTA;
1132                         break;
1133                 case 96:
1134                         vte->cattr.fccode = COLOR_LIGHT_CYAN;
1135                         break;
1136                 case 97:
1137                         vte->cattr.fccode = COLOR_WHITE;
1138                         break;
1139                 case 100:
1140                         vte->cattr.bccode = COLOR_DARK_GREY;
1141                         break;
1142                 case 101:
1143                         vte->cattr.bccode = COLOR_LIGHT_RED;
1144                         break;
1145                 case 102:
1146                         vte->cattr.bccode = COLOR_LIGHT_GREEN;
1147                         break;
1148                 case 103:
1149                         vte->cattr.bccode = COLOR_LIGHT_YELLOW;
1150                         break;
1151                 case 104:
1152                         vte->cattr.bccode = COLOR_LIGHT_BLUE;
1153                         break;
1154                 case 105:
1155                         vte->cattr.bccode = COLOR_LIGHT_MAGENTA;
1156                         break;
1157                 case 106:
1158                         vte->cattr.bccode = COLOR_LIGHT_CYAN;
1159                         break;
1160                 case 107:
1161                         vte->cattr.bccode = COLOR_WHITE;
1162                         break;
1163                 case 38:
1164                         /* fallthrough */
1165                 case 48:
1166                         if (i + 2 >= vte->csi_argc ||
1167                             vte->csi_argv[i + 1] != 5 ||
1168                             vte->csi_argv[i + 2] < 0) {
1169                                 llog_debug(vte, "invalid 256color SGR");
1170                                 break;
1171                         }
1172
1173                         code = vte->csi_argv[i + 2];
1174                         if (vte->csi_argv[i] == 38) {
1175                                 if (code < 16) {
1176                                         vte->cattr.fccode = code;
1177                                 } else if (code < 232) {
1178                                         vte->cattr.fccode = -1;
1179                                         code -= 16;
1180                                         vte->cattr.fb = bval[code % 6];
1181                                         code /= 6;
1182                                         vte->cattr.fg = bval[code % 6];
1183                                         code /= 6;
1184                                         vte->cattr.fr = bval[code % 6];
1185                                 } else {
1186                                         vte->cattr.fccode = -1;
1187                                         code = (code - 232) * 10 + 8;
1188                                         vte->cattr.fr = code;
1189                                         vte->cattr.fg = code;
1190                                         vte->cattr.fb = code;
1191                                 }
1192                         } else {
1193                                 if (code < 16) {
1194                                         vte->cattr.bccode = code;
1195                                 } else if (code < 232) {
1196                                         vte->cattr.bccode = -1;
1197                                         code -= 16;
1198                                         vte->cattr.bb = bval[code % 6];
1199                                         code /= 6;
1200                                         vte->cattr.bg = bval[code % 6];
1201                                         code /= 6;
1202                                         vte->cattr.br = bval[code % 6];
1203                                 } else {
1204                                         vte->cattr.bccode = -1;
1205                                         code = (code - 232) * 10 + 8;
1206                                         vte->cattr.br = code;
1207                                         vte->cattr.bg = code;
1208                                         vte->cattr.bb = code;
1209                                 }
1210                         }
1211
1212                         i += 2;
1213                         break;
1214                 default:
1215                         llog_debug(vte, "unhandled SGR attr %i",
1216                                    vte->csi_argv[i]);
1217                 }
1218         }
1219
1220         to_rgb(vte, &vte->cattr);
1221         if (vte->flags & FLAG_BACKGROUND_COLOR_ERASE_MODE)
1222                 tsm_screen_set_def_attr(vte->con, &vte->cattr);
1223 }
1224
1225 static void csi_soft_reset(struct tsm_vte *vte)
1226 {
1227         tsm_vte_reset(vte);
1228 }
1229
1230 static void csi_compat_mode(struct tsm_vte *vte)
1231 {
1232         /* always perform soft reset */
1233         csi_soft_reset(vte);
1234
1235         if (vte->csi_argv[0] == 61) {
1236                 /* Switching to VT100 compatibility mode. We do
1237                  * not support this mode, so ignore it. In fact,
1238                  * we are almost compatible to it, anyway, so
1239                  * there is no need to explicitly select it.
1240                  * However, we enable 7bit mode to avoid
1241                  * character-table problems */
1242                 vte->flags |= FLAG_7BIT_MODE;
1243                 vte->g0 = &tsm_vte_unicode_lower;
1244                 vte->g1 = &tsm_vte_dec_supplemental_graphics;
1245         } else if (vte->csi_argv[0] == 62 ||
1246                    vte->csi_argv[0] == 63 ||
1247                    vte->csi_argv[0] == 64) {
1248                 /* Switching to VT2/3/4 compatibility mode. We
1249                  * are always compatible with this so ignore it.
1250                  * We always send 7bit controls so we also do
1251                  * not care for the parameter value here that
1252                  * select the control-mode.
1253                  * VT220 defines argument 2 as 7bit mode but
1254                  * VT3xx up to VT5xx use it as 8bit mode. We
1255                  * choose to conform with the latter here.
1256                  * We also enable 8bit mode when VT220
1257                  * compatibility is requested explicitly. */
1258                 if (vte->csi_argv[1] == 1 ||
1259                     vte->csi_argv[1] == 2)
1260                         vte->flags |= FLAG_USE_C1;
1261
1262                 vte->flags |= FLAG_8BIT_MODE;
1263                 vte->g0 = &tsm_vte_unicode_lower;
1264                 vte->g1 = &tsm_vte_dec_supplemental_graphics;
1265         } else {
1266                 llog_debug(vte, "unhandled DECSCL 'p' CSI %i, switching to utf-8 mode again",
1267                            vte->csi_argv[0]);
1268         }
1269 }
1270
1271 static inline void set_reset_flag(struct tsm_vte *vte, bool set,
1272                                   unsigned int flag)
1273 {
1274         if (set)
1275                 vte->flags |= flag;
1276         else
1277                 vte->flags &= ~flag;
1278 }
1279
1280 static void csi_mode(struct tsm_vte *vte, bool set)
1281 {
1282         unsigned int i;
1283
1284         for (i = 0; i < vte->csi_argc; ++i) {
1285                 if (!(vte->csi_flags & CSI_WHAT)) {
1286                         switch (vte->csi_argv[i]) {
1287                         case -1:
1288                                 continue;
1289                         case 2: /* KAM */
1290                                 set_reset_flag(vte, set,
1291                                                FLAG_KEYBOARD_ACTION_MODE);
1292                                 continue;
1293                         case 4: /* IRM */
1294                                 set_reset_flag(vte, set,
1295                                                FLAG_INSERT_REPLACE_MODE);
1296                                 if (set)
1297                                         tsm_screen_set_flags(vte->con,
1298                                                 TSM_SCREEN_INSERT_MODE);
1299                                 else
1300                                         tsm_screen_reset_flags(vte->con,
1301                                                 TSM_SCREEN_INSERT_MODE);
1302                                 continue;
1303                         case 12: /* SRM */
1304                                 set_reset_flag(vte, set,
1305                                                FLAG_SEND_RECEIVE_MODE);
1306                                 continue;
1307                         case 20: /* LNM */
1308                                 set_reset_flag(vte, set,
1309                                                FLAG_LINE_FEED_NEW_LINE_MODE);
1310                                 continue;
1311                         default:
1312                                 llog_debug(vte, "unknown non-DEC (Re)Set-Mode %d",
1313                                            vte->csi_argv[i]);
1314                                 continue;
1315                         }
1316                 }
1317
1318                 switch (vte->csi_argv[i]) {
1319                 case -1:
1320                         continue;
1321                 case 1: /* DECCKM */
1322                         set_reset_flag(vte, set, FLAG_CURSOR_KEY_MODE);
1323                         continue;
1324                 case 2: /* DECANM */
1325                         /* Select VT52 mode */
1326                         /* We do not support VT52 mode. Is there any reason why
1327                          * we should support it? We ignore it here and do not
1328                          * mark it as to-do item unless someone has strong
1329                          * arguments to support it. */
1330                         continue;
1331                 case 3: /* DECCOLM */
1332                         /* If set, select 132 column mode, otherwise use 80
1333                          * column mode. If neither is selected explicitly, we
1334                          * use dynamic mode, that is, we send SIGWCH when the
1335                          * size changes and we allow arbitrary buffer
1336                          * dimensions. On soft-reset, we automatically fall back
1337                          * to the default, that is, dynamic mode.
1338                          * Dynamic-mode can be forced to a static mode in the
1339                          * config. That is, every time dynamic-mode becomes
1340                          * active, the terminal will be set to the dimensions
1341                          * that were selected in the config. This allows setting
1342                          * a fixed size for the terminal regardless of the
1343                          * display size.
1344                          * TODO: Implement this */
1345                         continue;
1346                 case 4: /* DECSCLM */
1347                         /* Select smooth scrolling. We do not support the
1348                          * classic smooth scrolling because we have a scrollback
1349                          * buffer. There is no need to implement smooth
1350                          * scrolling so ignore this here. */
1351                         continue;
1352                 case 5: /* DECSCNM */
1353                         set_reset_flag(vte, set, FLAG_INVERSE_SCREEN_MODE);
1354                         if (set)
1355                                 tsm_screen_set_flags(vte->con,
1356                                                 TSM_SCREEN_INVERSE);
1357                         else
1358                                 tsm_screen_reset_flags(vte->con,
1359                                                 TSM_SCREEN_INVERSE);
1360                         continue;
1361                 case 6: /* DECOM */
1362                         set_reset_flag(vte, set, FLAG_ORIGIN_MODE);
1363                         if (set)
1364                                 tsm_screen_set_flags(vte->con,
1365                                                 TSM_SCREEN_REL_ORIGIN);
1366                         else
1367                                 tsm_screen_reset_flags(vte->con,
1368                                                 TSM_SCREEN_REL_ORIGIN);
1369                         continue;
1370                 case 7: /* DECAWN */
1371                         set_reset_flag(vte, set, FLAG_AUTO_WRAP_MODE);
1372                         if (set)
1373                                 tsm_screen_set_flags(vte->con,
1374                                                 TSM_SCREEN_AUTO_WRAP);
1375                         else
1376                                 tsm_screen_reset_flags(vte->con,
1377                                                 TSM_SCREEN_AUTO_WRAP);
1378                         continue;
1379                 case 8: /* DECARM */
1380                         set_reset_flag(vte, set, FLAG_AUTO_REPEAT_MODE);
1381                         continue;
1382                 case 12: /* blinking cursor */
1383                         /* TODO: implement */
1384                         continue;
1385                 case 18: /* DECPFF */
1386                         /* If set, a form feed (FF) is sent to the printer after
1387                          * every screen that is printed. We don't have printers
1388                          * these days directly attached to terminals so we
1389                          * ignore this here. */
1390                         continue;
1391                 case 19: /* DECPEX */
1392                         /* If set, the full screen is printed instead of
1393                          * scrolling region only. We have no printer so ignore
1394                          * this mode. */
1395                         continue;
1396                 case 25: /* DECTCEM */
1397                         set_reset_flag(vte, set, FLAG_TEXT_CURSOR_MODE);
1398                         if (set)
1399                                 tsm_screen_reset_flags(vte->con,
1400                                                 TSM_SCREEN_HIDE_CURSOR);
1401                         else
1402                                 tsm_screen_set_flags(vte->con,
1403                                                 TSM_SCREEN_HIDE_CURSOR);
1404                         continue;
1405                 case 42: /* DECNRCM */
1406                         set_reset_flag(vte, set, FLAG_NATIONAL_CHARSET_MODE);
1407                         continue;
1408                 case 47: /* Alternate screen buffer */
1409                         if (vte->flags & FLAG_TITE_INHIBIT_MODE)
1410                                 continue;
1411
1412                         if (set)
1413                                 tsm_screen_set_flags(vte->con,
1414                                                      TSM_SCREEN_ALTERNATE);
1415                         else
1416                                 tsm_screen_reset_flags(vte->con,
1417                                                        TSM_SCREEN_ALTERNATE);
1418                         continue;
1419                 case 1047: /* Alternate screen buffer with post-erase */
1420                         if (vte->flags & FLAG_TITE_INHIBIT_MODE)
1421                                 continue;
1422
1423                         if (set) {
1424                                 tsm_screen_set_flags(vte->con,
1425                                                      TSM_SCREEN_ALTERNATE);
1426                         } else {
1427                                 tsm_screen_erase_screen(vte->con, false);
1428                                 tsm_screen_reset_flags(vte->con,
1429                                                        TSM_SCREEN_ALTERNATE);
1430                         }
1431                         continue;
1432                 case 1048: /* Set/Reset alternate-screen buffer cursor */
1433                         if (vte->flags & FLAG_TITE_INHIBIT_MODE)
1434                                 continue;
1435
1436                         if (set) {
1437                                 vte->alt_cursor_x =
1438                                         tsm_screen_get_cursor_x(vte->con);
1439                                 vte->alt_cursor_y =
1440                                         tsm_screen_get_cursor_y(vte->con);
1441                         } else {
1442                                 tsm_screen_move_to(vte->con, vte->alt_cursor_x,
1443                                                    vte->alt_cursor_y);
1444                         }
1445                         continue;
1446                 case 1049: /* Alternate screen buffer with pre-erase+cursor */
1447                         if (vte->flags & FLAG_TITE_INHIBIT_MODE)
1448                                 continue;
1449
1450                         if (set) {
1451                                 vte->alt_cursor_x =
1452                                         tsm_screen_get_cursor_x(vte->con);
1453                                 vte->alt_cursor_y =
1454                                         tsm_screen_get_cursor_y(vte->con);
1455                                 tsm_screen_set_flags(vte->con,
1456                                                      TSM_SCREEN_ALTERNATE);
1457                                 tsm_screen_erase_screen(vte->con, false);
1458                         } else {
1459                                 tsm_screen_reset_flags(vte->con,
1460                                                        TSM_SCREEN_ALTERNATE);
1461                                 tsm_screen_move_to(vte->con, vte->alt_cursor_x,
1462                                                    vte->alt_cursor_y);
1463                         }
1464                         continue;
1465                 default:
1466                         llog_debug(vte, "unknown DEC %set-Mode %d",
1467                                    set?"S":"Res", vte->csi_argv[i]);
1468                         continue;
1469                 }
1470         }
1471 }
1472
1473 static void csi_dev_attr(struct tsm_vte *vte)
1474 {
1475         if (vte->csi_argc <= 1 && vte->csi_argv[0] <= 0) {
1476                 if (vte->csi_flags == 0) {
1477                         send_primary_da(vte);
1478                         return;
1479                 } else if (vte->csi_flags & CSI_GT) {
1480                         vte_write(vte, "\e[>1;1;0c", 9);
1481                         return;
1482                 }
1483         }
1484
1485         llog_debug(vte, "unhandled DA: %x %d %d %d...", vte->csi_flags,
1486                    vte->csi_argv[0], vte->csi_argv[1], vte->csi_argv[2]);
1487 }
1488
1489 static void csi_dsr(struct tsm_vte *vte)
1490 {
1491         char buf[64];
1492         unsigned int x, y, len;
1493
1494         if (vte->csi_argv[0] == 5) {
1495                 vte_write(vte, "\e[0n", 4);
1496         } else if (vte->csi_argv[0] == 6) {
1497                 x = tsm_screen_get_cursor_x(vte->con);
1498                 y = tsm_screen_get_cursor_y(vte->con);
1499                 len = snprintf(buf, sizeof(buf), "\e[%u;%uR", x, y);
1500                 if (len >= sizeof(buf))
1501                         vte_write(vte, "\e[0;0R", 6);
1502                 else
1503                         vte_write(vte, buf, len);
1504         }
1505 }
1506
1507 static void do_csi(struct tsm_vte *vte, uint32_t data)
1508 {
1509         int num, x, y, upper, lower;
1510         bool protect;
1511
1512         if (vte->csi_argc < CSI_ARG_MAX)
1513                 vte->csi_argc++;
1514
1515         switch (data) {
1516         case 'A': /* CUU */
1517                 /* move cursor up */
1518                 num = vte->csi_argv[0];
1519                 if (num <= 0)
1520                         num = 1;
1521                 tsm_screen_move_up(vte->con, num, false);
1522                 break;
1523         case 'B': /* CUD */
1524                 /* move cursor down */
1525                 num = vte->csi_argv[0];
1526                 if (num <= 0)
1527                         num = 1;
1528                 tsm_screen_move_down(vte->con, num, false);
1529                 break;
1530         case 'C': /* CUF */
1531                 /* move cursor forward */
1532                 num = vte->csi_argv[0];
1533                 if (num <= 0)
1534                         num = 1;
1535                 tsm_screen_move_right(vte->con, num);
1536                 break;
1537         case 'D': /* CUB */
1538                 /* move cursor backward */
1539                 num = vte->csi_argv[0];
1540                 if (num <= 0)
1541                         num = 1;
1542                 tsm_screen_move_left(vte->con, num);
1543                 break;
1544         case 'd': /* VPA */
1545                 /* Vertical Line Position Absolute */
1546                 num = vte->csi_argv[0];
1547                 if (num <= 0)
1548                         num = 1;
1549                 x = tsm_screen_get_cursor_x(vte->con);
1550                 tsm_screen_move_to(vte->con, x, num - 1);
1551                 break;
1552         case 'e': /* VPR */
1553                 /* Vertical Line Position Relative */
1554                 num = vte->csi_argv[0];
1555                 if (num <= 0)
1556                         num = 1;
1557                 x = tsm_screen_get_cursor_x(vte->con);
1558                 y = tsm_screen_get_cursor_y(vte->con);
1559                 tsm_screen_move_to(vte->con, x, y + num);
1560                 break;
1561         case 'H': /* CUP */
1562         case 'f': /* HVP */
1563                 /* position cursor */
1564                 x = vte->csi_argv[0];
1565                 if (x <= 0)
1566                         x = 1;
1567                 y = vte->csi_argv[1];
1568                 if (y <= 0)
1569                         y = 1;
1570                 tsm_screen_move_to(vte->con, y - 1, x - 1);
1571                 break;
1572         case 'G': /* CHA */
1573                 /* Cursor Character Absolute */
1574                 num = vte->csi_argv[0];
1575                 if (num <= 0)
1576                         num = 1;
1577                 y = tsm_screen_get_cursor_y(vte->con);
1578                 tsm_screen_move_to(vte->con, num - 1, y);
1579                 break;
1580         case 'J':
1581                 if (vte->csi_flags & CSI_WHAT)
1582                         protect = true;
1583                 else
1584                         protect = false;
1585
1586                 if (vte->csi_argv[0] <= 0)
1587                         tsm_screen_erase_cursor_to_screen(vte->con,
1588                                                               protect);
1589                 else if (vte->csi_argv[0] == 1)
1590                         tsm_screen_erase_screen_to_cursor(vte->con,
1591                                                               protect);
1592                 else if (vte->csi_argv[0] == 2)
1593                         tsm_screen_erase_screen(vte->con, protect);
1594                 else
1595                         llog_debug(vte, "unknown parameter to CSI-J: %d",
1596                                    vte->csi_argv[0]);
1597                 break;
1598         case 'K':
1599                 if (vte->csi_flags & CSI_WHAT)
1600                         protect = true;
1601                 else
1602                         protect = false;
1603
1604                 if (vte->csi_argv[0] <= 0)
1605                         tsm_screen_erase_cursor_to_end(vte->con, protect);
1606                 else if (vte->csi_argv[0] == 1)
1607                         tsm_screen_erase_home_to_cursor(vte->con, protect);
1608                 else if (vte->csi_argv[0] == 2)
1609                         tsm_screen_erase_current_line(vte->con, protect);
1610                 else
1611                         llog_debug(vte, "unknown parameter to CSI-K: %d",
1612                                    vte->csi_argv[0]);
1613                 break;
1614         case 'X': /* ECH */
1615                 /* erase characters */
1616                 num = vte->csi_argv[0];
1617                 if (num <= 0)
1618                         num = 1;
1619                 tsm_screen_erase_chars(vte->con, num);
1620                 break;
1621         case 'm':
1622                 csi_attribute(vte);
1623                 break;
1624         case 'p':
1625                 if (vte->csi_flags & CSI_GT) {
1626                         /* xterm: select X11 visual cursor mode */
1627                         csi_soft_reset(vte);
1628                 } else if (vte->csi_flags & CSI_BANG) {
1629                         /* DECSTR: Soft Reset */
1630                         csi_soft_reset(vte);
1631                 } else if (vte->csi_flags & CSI_CASH) {
1632                         /* DECRQM: Request DEC Private Mode */
1633                         /* If CSI_WHAT is set, then enable,
1634                          * otherwise disable */
1635                         csi_soft_reset(vte);
1636                 } else {
1637                         /* DECSCL: Compatibility Level */
1638                         /* Sometimes CSI_DQUOTE is set here, too */
1639                         csi_compat_mode(vte);
1640                 }
1641                 break;
1642         case 'h': /* SM: Set Mode */
1643                 csi_mode(vte, true);
1644                 break;
1645         case 'l': /* RM: Reset Mode */
1646                 csi_mode(vte, false);
1647                 break;
1648         case 'r': /* DECSTBM */
1649                 /* set margin size */
1650                 upper = vte->csi_argv[0];
1651                 if (upper < 0)
1652                         upper = 0;
1653                 lower = vte->csi_argv[1];
1654                 if (lower < 0)
1655                         lower = 0;
1656                 tsm_screen_set_margins(vte->con, upper, lower);
1657                 break;
1658         case 'c': /* DA */
1659                 /* device attributes */
1660                 csi_dev_attr(vte);
1661                 break;
1662         case 'L': /* IL */
1663                 /* insert lines */
1664                 num = vte->csi_argv[0];
1665                 if (num <= 0)
1666                         num = 1;
1667                 tsm_screen_insert_lines(vte->con, num);
1668                 break;
1669         case 'M': /* DL */
1670                 /* delete lines */
1671                 num = vte->csi_argv[0];
1672                 if (num <= 0)
1673                         num = 1;
1674                 tsm_screen_delete_lines(vte->con, num);
1675                 break;
1676         case 'g': /* TBC */
1677                 /* tabulation clear */
1678                 num = vte->csi_argv[0];
1679                 if (num <= 0)
1680                         tsm_screen_reset_tabstop(vte->con);
1681                 else if (num == 3)
1682                         tsm_screen_reset_all_tabstops(vte->con);
1683                 else
1684                         llog_debug(vte, "invalid parameter %d to TBC CSI", num);
1685                 break;
1686         case '@': /* ICH */
1687                 /* insert characters */
1688                 num = vte->csi_argv[0];
1689                 if (num <= 0)
1690                         num = 1;
1691                 tsm_screen_insert_chars(vte->con, num);
1692                 break;
1693         case 'P': /* DCH */
1694                 /* delete characters */
1695                 num = vte->csi_argv[0];
1696                 if (num <= 0)
1697                         num = 1;
1698                 tsm_screen_delete_chars(vte->con, num);
1699                 break;
1700         case 'Z': /* CBT */
1701                 /* cursor horizontal backwards tab */
1702                 num = vte->csi_argv[0];
1703                 if (num <= 0)
1704                         num = 1;
1705                 tsm_screen_tab_left(vte->con, num);
1706                 break;
1707         case 'I': /* CHT */
1708                 /* cursor horizontal forward tab */
1709                 num = vte->csi_argv[0];
1710                 if (num <= 0)
1711                         num = 1;
1712                 tsm_screen_tab_right(vte->con, num);
1713                 break;
1714         case 'n': /* DSR */
1715                 /* device status reports */
1716                 csi_dsr(vte);
1717                 break;
1718         case 'S': /* SU */
1719                 /* scroll up */
1720                 num = vte->csi_argv[0];
1721                 if (num <= 0)
1722                         num = 1;
1723                 tsm_screen_scroll_up(vte->con, num);
1724                 break;
1725         case 'T': /* SD */
1726                 /* scroll down */
1727                 num = vte->csi_argv[0];
1728                 if (num <= 0)
1729                         num = 1;
1730                 tsm_screen_scroll_down(vte->con, num);
1731                 break;
1732         default:
1733                 llog_debug(vte, "unhandled CSI sequence %c", data);
1734         }
1735 }
1736
1737 /* map a character according to current GL and GR maps */
1738 static uint32_t vte_map(struct tsm_vte *vte, uint32_t val)
1739 {
1740         /* 32, 127, 160 and 255 map to identity like all values >255 */
1741         switch (val) {
1742         case 33 ... 126:
1743                 if (vte->glt) {
1744                         val = (**vte->glt)[val - 32];
1745                         vte->glt = NULL;
1746                 } else {
1747                         val = (**vte->gl)[val - 32];
1748                 }
1749                 break;
1750         case 161 ... 254:
1751                 if (vte->grt) {
1752                         val = (**vte->grt)[val - 160];
1753                         vte->grt = NULL;
1754                 } else {
1755                         val = (**vte->gr)[val - 160];
1756                 }
1757                 break;
1758         }
1759
1760         return val;
1761 }
1762
1763 /* perform parser action */
1764 static void do_action(struct tsm_vte *vte, uint32_t data, int action)
1765 {
1766         tsm_symbol_t sym;
1767
1768         switch (action) {
1769                 case ACTION_NONE:
1770                         /* do nothing */
1771                         return;
1772                 case ACTION_IGNORE:
1773                         /* ignore character */
1774                         break;
1775                 case ACTION_PRINT:
1776                         sym = tsm_symbol_make(vte_map(vte, data));
1777                         write_console(vte, sym);
1778                         break;
1779                 case ACTION_EXECUTE:
1780                         do_execute(vte, data);
1781                         break;
1782                 case ACTION_CLEAR:
1783                         do_clear(vte);
1784                         break;
1785                 case ACTION_COLLECT:
1786                         do_collect(vte, data);
1787                         break;
1788                 case ACTION_PARAM:
1789                         do_param(vte, data);
1790                         break;
1791                 case ACTION_ESC_DISPATCH:
1792                         do_esc(vte, data);
1793                         break;
1794                 case ACTION_CSI_DISPATCH:
1795                         do_csi(vte, data);
1796                         break;
1797                 case ACTION_DCS_START:
1798                         break;
1799                 case ACTION_DCS_COLLECT:
1800                         break;
1801                 case ACTION_DCS_END:
1802                         break;
1803                 case ACTION_OSC_START:
1804                         break;
1805                 case ACTION_OSC_COLLECT:
1806                         break;
1807                 case ACTION_OSC_END:
1808                         break;
1809                 default:
1810                         llog_warn(vte, "invalid action %d", action);
1811         }
1812 }
1813
1814 /* entry actions to be performed when entering the selected state */
1815 static const int entry_action[] = {
1816         [STATE_CSI_ENTRY] = ACTION_CLEAR,
1817         [STATE_DCS_ENTRY] = ACTION_CLEAR,
1818         [STATE_DCS_PASS] = ACTION_DCS_START,
1819         [STATE_ESC] = ACTION_CLEAR,
1820         [STATE_OSC_STRING] = ACTION_OSC_START,
1821         [STATE_NUM] = ACTION_NONE,
1822 };
1823
1824 /* exit actions to be performed when leaving the selected state */
1825 static const int exit_action[] = {
1826         [STATE_DCS_PASS] = ACTION_DCS_END,
1827         [STATE_OSC_STRING] = ACTION_OSC_END,
1828         [STATE_NUM] = ACTION_NONE,
1829 };
1830
1831 /* perform state transition and dispatch related actions */
1832 static void do_trans(struct tsm_vte *vte, uint32_t data, int state, int act)
1833 {
1834         if (state != STATE_NONE) {
1835                 /* A state transition occurs. Perform exit-action,
1836                  * transition-action and entry-action. Even when performing a
1837                  * transition to the same state as the current state we do this.
1838                  * Use STATE_NONE if this is not the desired behavior.
1839                  */
1840                 do_action(vte, data, exit_action[vte->state]);
1841                 do_action(vte, data, act);
1842                 do_action(vte, data, entry_action[state]);
1843                 vte->state = state;
1844         } else {
1845                 do_action(vte, data, act);
1846         }
1847 }
1848
1849 /*
1850  * Escape sequence parser
1851  * This parses the new input character \data. It performs state transition and
1852  * calls the right callbacks for each action.
1853  */
1854 static void parse_data(struct tsm_vte *vte, uint32_t raw)
1855 {
1856         /* events that may occur in any state */
1857         switch (raw) {
1858                 case 0x18:
1859                 case 0x1a:
1860                 case 0x80 ... 0x8f:
1861                 case 0x91 ... 0x97:
1862                 case 0x99:
1863                 case 0x9a:
1864                 case 0x9c:
1865                         do_trans(vte, raw, STATE_GROUND, ACTION_EXECUTE);
1866                         return;
1867                 case 0x1b:
1868                         do_trans(vte, raw, STATE_ESC, ACTION_NONE);
1869                         return;
1870                 case 0x98:
1871                 case 0x9e:
1872                 case 0x9f:
1873                         do_trans(vte, raw, STATE_ST_IGNORE, ACTION_NONE);
1874                         return;
1875                 case 0x90:
1876                         do_trans(vte, raw, STATE_DCS_ENTRY, ACTION_NONE);
1877                         return;
1878                 case 0x9d:
1879                         do_trans(vte, raw, STATE_OSC_STRING, ACTION_NONE);
1880                         return;
1881                 case 0x9b:
1882                         do_trans(vte, raw, STATE_CSI_ENTRY, ACTION_NONE);
1883                         return;
1884         }
1885
1886         /* events that depend on the current state */
1887         switch (vte->state) {
1888         case STATE_GROUND:
1889                 switch (raw) {
1890                 case 0x00 ... 0x17:
1891                 case 0x19:
1892                 case 0x1c ... 0x1f:
1893                 case 0x80 ... 0x8f:
1894                 case 0x91 ... 0x9a:
1895                 case 0x9c:
1896                         do_trans(vte, raw, STATE_NONE, ACTION_EXECUTE);
1897                         return;
1898                 case 0x20 ... 0x7f:
1899                         do_trans(vte, raw, STATE_NONE, ACTION_PRINT);
1900                         return;
1901                 }
1902                 do_trans(vte, raw, STATE_NONE, ACTION_PRINT);
1903                 return;
1904         case STATE_ESC:
1905                 switch (raw) {
1906                 case 0x00 ... 0x17:
1907                 case 0x19:
1908                 case 0x1c ... 0x1f:
1909                         do_trans(vte, raw, STATE_NONE, ACTION_EXECUTE);
1910                         return;
1911                 case 0x7f:
1912                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
1913                         return;
1914                 case 0x20 ... 0x2f:
1915                         do_trans(vte, raw, STATE_ESC_INT, ACTION_COLLECT);
1916                         return;
1917                 case 0x30 ... 0x4f:
1918                 case 0x51 ... 0x57:
1919                 case 0x59:
1920                 case 0x5a:
1921                 case 0x5c:
1922                 case 0x60 ... 0x7e:
1923                         do_trans(vte, raw, STATE_GROUND, ACTION_ESC_DISPATCH);
1924                         return;
1925                 case 0x5b:
1926                         do_trans(vte, raw, STATE_CSI_ENTRY, ACTION_NONE);
1927                         return;
1928                 case 0x5d:
1929                         do_trans(vte, raw, STATE_OSC_STRING, ACTION_NONE);
1930                         return;
1931                 case 0x50:
1932                         do_trans(vte, raw, STATE_DCS_ENTRY, ACTION_NONE);
1933                         return;
1934                 case 0x58:
1935                 case 0x5e:
1936                 case 0x5f:
1937                         do_trans(vte, raw, STATE_ST_IGNORE, ACTION_NONE);
1938                         return;
1939                 }
1940                 do_trans(vte, raw, STATE_ESC_INT, ACTION_COLLECT);
1941                 return;
1942         case STATE_ESC_INT:
1943                 switch (raw) {
1944                 case 0x00 ... 0x17:
1945                 case 0x19:
1946                 case 0x1c ... 0x1f:
1947                         do_trans(vte, raw, STATE_NONE, ACTION_EXECUTE);
1948                         return;
1949                 case 0x20 ... 0x2f:
1950                         do_trans(vte, raw, STATE_NONE, ACTION_COLLECT);
1951                         return;
1952                 case 0x7f:
1953                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
1954                         return;
1955                 case 0x30 ... 0x7e:
1956                         do_trans(vte, raw, STATE_GROUND, ACTION_ESC_DISPATCH);
1957                         return;
1958                 }
1959                 do_trans(vte, raw, STATE_NONE, ACTION_COLLECT);
1960                 return;
1961         case STATE_CSI_ENTRY:
1962                 switch (raw) {
1963                 case 0x00 ... 0x17:
1964                 case 0x19:
1965                 case 0x1c ... 0x1f:
1966                         do_trans(vte, raw, STATE_NONE, ACTION_EXECUTE);
1967                         return;
1968                 case 0x7f:
1969                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
1970                         return;
1971                 case 0x20 ... 0x2f:
1972                         do_trans(vte, raw, STATE_CSI_INT, ACTION_COLLECT);
1973                         return;
1974                 case 0x3a:
1975                         do_trans(vte, raw, STATE_CSI_IGNORE, ACTION_NONE);
1976                         return;
1977                 case 0x30 ... 0x39:
1978                 case 0x3b:
1979                         do_trans(vte, raw, STATE_CSI_PARAM, ACTION_PARAM);
1980                         return;
1981                 case 0x3c ... 0x3f:
1982                         do_trans(vte, raw, STATE_CSI_PARAM, ACTION_COLLECT);
1983                         return;
1984                 case 0x40 ... 0x7e:
1985                         do_trans(vte, raw, STATE_GROUND, ACTION_CSI_DISPATCH);
1986                         return;
1987                 }
1988                 do_trans(vte, raw, STATE_CSI_IGNORE, ACTION_NONE);
1989                 return;
1990         case STATE_CSI_PARAM:
1991                 switch (raw) {
1992                 case 0x00 ... 0x17:
1993                 case 0x19:
1994                 case 0x1c ... 0x1f:
1995                         do_trans(vte, raw, STATE_NONE, ACTION_EXECUTE);
1996                         return;
1997                 case 0x30 ... 0x39:
1998                 case 0x3b:
1999                         do_trans(vte, raw, STATE_NONE, ACTION_PARAM);
2000                         return;
2001                 case 0x7f:
2002                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2003                         return;
2004                 case 0x3a:
2005                 case 0x3c ... 0x3f:
2006                         do_trans(vte, raw, STATE_CSI_IGNORE, ACTION_NONE);
2007                         return;
2008                 case 0x20 ... 0x2f:
2009                         do_trans(vte, raw, STATE_CSI_INT, ACTION_COLLECT);
2010                         return;
2011                 case 0x40 ... 0x7e:
2012                         do_trans(vte, raw, STATE_GROUND, ACTION_CSI_DISPATCH);
2013                         return;
2014                 }
2015                 do_trans(vte, raw, STATE_CSI_IGNORE, ACTION_NONE);
2016                 return;
2017         case STATE_CSI_INT:
2018                 switch (raw) {
2019                 case 0x00 ... 0x17:
2020                 case 0x19:
2021                 case 0x1c ... 0x1f:
2022                         do_trans(vte, raw, STATE_NONE, ACTION_EXECUTE);
2023                         return;
2024                 case 0x20 ... 0x2f:
2025                         do_trans(vte, raw, STATE_NONE, ACTION_COLLECT);
2026                         return;
2027                 case 0x7f:
2028                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2029                         return;
2030                 case 0x30 ... 0x3f:
2031                         do_trans(vte, raw, STATE_CSI_IGNORE, ACTION_NONE);
2032                         return;
2033                 case 0x40 ... 0x7e:
2034                         do_trans(vte, raw, STATE_GROUND, ACTION_CSI_DISPATCH);
2035                         return;
2036                 }
2037                 do_trans(vte, raw, STATE_CSI_IGNORE, ACTION_NONE);
2038                 return;
2039         case STATE_CSI_IGNORE:
2040                 switch (raw) {
2041                 case 0x00 ... 0x17:
2042                 case 0x19:
2043                 case 0x1c ... 0x1f:
2044                         do_trans(vte, raw, STATE_NONE, ACTION_EXECUTE);
2045                         return;
2046                 case 0x20 ... 0x3f:
2047                 case 0x7f:
2048                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2049                         return;
2050                 case 0x40 ... 0x7e:
2051                         do_trans(vte, raw, STATE_GROUND, ACTION_NONE);
2052                         return;
2053                 }
2054                 do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2055                 return;
2056         case STATE_DCS_ENTRY:
2057                 switch (raw) {
2058                 case 0x00 ... 0x17:
2059                 case 0x19:
2060                 case 0x1c ... 0x1f:
2061                 case 0x7f:
2062                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2063                         return;
2064                 case 0x3a:
2065                         do_trans(vte, raw, STATE_DCS_IGNORE, ACTION_NONE);
2066                         return;
2067                 case 0x20 ... 0x2f:
2068                         do_trans(vte, raw, STATE_DCS_INT, ACTION_COLLECT);
2069                         return;
2070                 case 0x30 ... 0x39:
2071                 case 0x3b:
2072                         do_trans(vte, raw, STATE_DCS_PARAM, ACTION_PARAM);
2073                         return;
2074                 case 0x3c ... 0x3f:
2075                         do_trans(vte, raw, STATE_DCS_PARAM, ACTION_COLLECT);
2076                         return;
2077                 case 0x40 ... 0x7e:
2078                         do_trans(vte, raw, STATE_DCS_PASS, ACTION_NONE);
2079                         return;
2080                 }
2081                 do_trans(vte, raw, STATE_DCS_PASS, ACTION_NONE);
2082                 return;
2083         case STATE_DCS_PARAM:
2084                 switch (raw) {
2085                 case 0x00 ... 0x17:
2086                 case 0x19:
2087                 case 0x1c ... 0x1f:
2088                 case 0x7f:
2089                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2090                         return;
2091                 case 0x30 ... 0x39:
2092                 case 0x3b:
2093                         do_trans(vte, raw, STATE_NONE, ACTION_PARAM);
2094                         return;
2095                 case 0x3a:
2096                 case 0x3c ... 0x3f:
2097                         do_trans(vte, raw, STATE_DCS_IGNORE, ACTION_NONE);
2098                         return;
2099                 case 0x20 ... 0x2f:
2100                         do_trans(vte, raw, STATE_DCS_INT, ACTION_COLLECT);
2101                         return;
2102                 case 0x40 ... 0x7e:
2103                         do_trans(vte, raw, STATE_DCS_PASS, ACTION_NONE);
2104                         return;
2105                 }
2106                 do_trans(vte, raw, STATE_DCS_PASS, ACTION_NONE);
2107                 return;
2108         case STATE_DCS_INT:
2109                 switch (raw) {
2110                 case 0x00 ... 0x17:
2111                 case 0x19:
2112                 case 0x1c ... 0x1f:
2113                 case 0x7f:
2114                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2115                         return;
2116                 case 0x20 ... 0x2f:
2117                         do_trans(vte, raw, STATE_NONE, ACTION_COLLECT);
2118                         return;
2119                 case 0x30 ... 0x3f:
2120                         do_trans(vte, raw, STATE_DCS_IGNORE, ACTION_NONE);
2121                         return;
2122                 case 0x40 ... 0x7e:
2123                         do_trans(vte, raw, STATE_DCS_PASS, ACTION_NONE);
2124                         return;
2125                 }
2126                 do_trans(vte, raw, STATE_DCS_PASS, ACTION_NONE);
2127                 return;
2128         case STATE_DCS_PASS:
2129                 switch (raw) {
2130                 case 0x00 ... 0x17:
2131                 case 0x19:
2132                 case 0x1c ... 0x1f:
2133                 case 0x20 ... 0x7e:
2134                         do_trans(vte, raw, STATE_NONE, ACTION_DCS_COLLECT);
2135                         return;
2136                 case 0x7f:
2137                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2138                         return;
2139                 case 0x9c:
2140                         do_trans(vte, raw, STATE_GROUND, ACTION_NONE);
2141                         return;
2142                 }
2143                 do_trans(vte, raw, STATE_NONE, ACTION_DCS_COLLECT);
2144                 return;
2145         case STATE_DCS_IGNORE:
2146                 switch (raw) {
2147                 case 0x00 ... 0x17:
2148                 case 0x19:
2149                 case 0x1c ... 0x1f:
2150                 case 0x20 ... 0x7f:
2151                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2152                         return;
2153                 case 0x9c:
2154                         do_trans(vte, raw, STATE_GROUND, ACTION_NONE);
2155                         return;
2156                 }
2157                 do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2158                 return;
2159         case STATE_OSC_STRING:
2160                 switch (raw) {
2161                 case 0x00 ... 0x06:
2162                 case 0x08 ... 0x17:
2163                 case 0x19:
2164                 case 0x1c ... 0x1f:
2165                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2166                         return;
2167                 case 0x20 ... 0x7f:
2168                         do_trans(vte, raw, STATE_NONE, ACTION_OSC_COLLECT);
2169                         return;
2170                 case 0x07:
2171                 case 0x9c:
2172                         do_trans(vte, raw, STATE_GROUND, ACTION_NONE);
2173                         return;
2174                 }
2175                 do_trans(vte, raw, STATE_NONE, ACTION_OSC_COLLECT);
2176                 return;
2177         case STATE_ST_IGNORE:
2178                 switch (raw) {
2179                 case 0x00 ... 0x17:
2180                 case 0x19:
2181                 case 0x1c ... 0x1f:
2182                 case 0x20 ... 0x7f:
2183                         do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2184                         return;
2185                 case 0x9c:
2186                         do_trans(vte, raw, STATE_GROUND, ACTION_NONE);
2187                         return;
2188                 }
2189                 do_trans(vte, raw, STATE_NONE, ACTION_IGNORE);
2190                 return;
2191         }
2192
2193         llog_warn(vte, "unhandled input %u in state %d", raw, vte->state);
2194 }
2195
2196 SHL_EXPORT
2197 void tsm_vte_input(struct tsm_vte *vte, const char *u8, size_t len)
2198 {
2199         int state;
2200         uint32_t ucs4;
2201         size_t i;
2202
2203         if (!vte || !vte->con)
2204                 return;
2205
2206         ++vte->parse_cnt;
2207         for (i = 0; i < len; ++i) {
2208                 if (vte->flags & FLAG_7BIT_MODE) {
2209                         if (u8[i] & 0x80)
2210                                 llog_debug(vte, "receiving 8bit character U+%d from pty while in 7bit mode",
2211                                            (int)u8[i]);
2212                         parse_data(vte, u8[i] & 0x7f);
2213                 } else if (vte->flags & FLAG_8BIT_MODE) {
2214                         parse_data(vte, u8[i]);
2215                 } else {
2216                         state = tsm_utf8_mach_feed(vte->mach, u8[i]);
2217                         if (state == TSM_UTF8_ACCEPT ||
2218                             state == TSM_UTF8_REJECT) {
2219                                 ucs4 = tsm_utf8_mach_get(vte->mach);
2220                                 parse_data(vte, ucs4);
2221                         }
2222                 }
2223         }
2224         --vte->parse_cnt;
2225 }
2226
2227 SHL_EXPORT
2228 bool tsm_vte_handle_keyboard(struct tsm_vte *vte, uint32_t keysym,
2229                              uint32_t ascii, unsigned int mods,
2230                              uint32_t unicode)
2231 {
2232         char val, u8[4];
2233         size_t len;
2234         uint32_t sym;
2235
2236         /* MOD1 (mostly labeled 'Alt') prepends an escape character to every
2237          * input that is sent by a key.
2238          * TODO: Transform this huge handler into a lookup table to save a lot
2239          * of code and make such modifiers easier to implement.
2240          * Also check whether altSendsEscape should be the default (xterm
2241          * disables this by default, why?) and whether we should implement the
2242          * fallback shifting that xterm does. */
2243         if (mods & TSM_ALT_MASK)
2244                 vte->flags |= FLAG_PREPEND_ESCAPE;
2245
2246         /* A user might actually use multiple layouts for keyboard input. The
2247          * @keysym variable contains the actual keysym that the user used. But
2248          * if this keysym is not in the ascii range, the input handler does
2249          * check all other layouts that the user specified whether one of them
2250          * maps the key to some ASCII keysym and provides this via @ascii.
2251          * We always use the real keysym except when handling CTRL+<XY>
2252          * shortcuts we use the ascii keysym. This is for compatibility to xterm
2253          * et. al. so ctrl+c always works regardless of the currently active
2254          * keyboard layout.
2255          * But if no ascii-sym is found, we still use the real keysym. */
2256         sym = ascii;
2257         if (sym == XKB_KEY_NoSymbol)
2258                 sym = keysym;
2259
2260         if (mods & TSM_CONTROL_MASK) {
2261                 switch (sym) {
2262                 case XKB_KEY_2:
2263                 case XKB_KEY_space:
2264                         vte_write(vte, "\x00", 1);
2265                         return true;
2266                 case XKB_KEY_a:
2267                 case XKB_KEY_A:
2268                         vte_write(vte, "\x01", 1);
2269                         return true;
2270                 case XKB_KEY_b:
2271                 case XKB_KEY_B:
2272                         vte_write(vte, "\x02", 1);
2273                         return true;
2274                 case XKB_KEY_c:
2275                 case XKB_KEY_C:
2276                         vte_write(vte, "\x03", 1);
2277                         return true;
2278                 case XKB_KEY_d:
2279                 case XKB_KEY_D:
2280                         vte_write(vte, "\x04", 1);
2281                         return true;
2282                 case XKB_KEY_e:
2283                 case XKB_KEY_E:
2284                         vte_write(vte, "\x05", 1);
2285                         return true;
2286                 case XKB_KEY_f:
2287                 case XKB_KEY_F:
2288                         vte_write(vte, "\x06", 1);
2289                         return true;
2290                 case XKB_KEY_g:
2291                 case XKB_KEY_G:
2292                         vte_write(vte, "\x07", 1);
2293                         return true;
2294                 case XKB_KEY_h:
2295                 case XKB_KEY_H:
2296                         vte_write(vte, "\x08", 1);
2297                         return true;
2298                 case XKB_KEY_i:
2299                 case XKB_KEY_I:
2300                         vte_write(vte, "\x09", 1);
2301                         return true;
2302                 case XKB_KEY_j:
2303                 case XKB_KEY_J:
2304                         vte_write(vte, "\x0a", 1);
2305                         return true;
2306                 case XKB_KEY_k:
2307                 case XKB_KEY_K:
2308                         vte_write(vte, "\x0b", 1);
2309                         return true;
2310                 case XKB_KEY_l:
2311                 case XKB_KEY_L:
2312                         vte_write(vte, "\x0c", 1);
2313                         return true;
2314                 case XKB_KEY_m:
2315                 case XKB_KEY_M:
2316                         vte_write(vte, "\x0d", 1);
2317                         return true;
2318                 case XKB_KEY_n:
2319                 case XKB_KEY_N:
2320                         vte_write(vte, "\x0e", 1);
2321                         return true;
2322                 case XKB_KEY_o:
2323                 case XKB_KEY_O:
2324                         vte_write(vte, "\x0f", 1);
2325                         return true;
2326                 case XKB_KEY_p:
2327                 case XKB_KEY_P:
2328                         vte_write(vte, "\x10", 1);
2329                         return true;
2330                 case XKB_KEY_q:
2331                 case XKB_KEY_Q:
2332                         vte_write(vte, "\x11", 1);
2333                         return true;
2334                 case XKB_KEY_r:
2335                 case XKB_KEY_R:
2336                         vte_write(vte, "\x12", 1);
2337                         return true;
2338                 case XKB_KEY_s:
2339                 case XKB_KEY_S:
2340                         vte_write(vte, "\x13", 1);
2341                         return true;
2342                 case XKB_KEY_t:
2343                 case XKB_KEY_T:
2344                         vte_write(vte, "\x14", 1);
2345                         return true;
2346                 case XKB_KEY_u:
2347                 case XKB_KEY_U:
2348                         vte_write(vte, "\x15", 1);
2349                         return true;
2350                 case XKB_KEY_v:
2351                 case XKB_KEY_V:
2352                         vte_write(vte, "\x16", 1);
2353                         return true;
2354                 case XKB_KEY_w:
2355                 case XKB_KEY_W:
2356                         vte_write(vte, "\x17", 1);
2357                         return true;
2358                 case XKB_KEY_x:
2359                 case XKB_KEY_X:
2360                         vte_write(vte, "\x18", 1);
2361                         return true;
2362                 case XKB_KEY_y:
2363                 case XKB_KEY_Y:
2364                         vte_write(vte, "\x19", 1);
2365                         return true;
2366                 case XKB_KEY_z:
2367                 case XKB_KEY_Z:
2368                         vte_write(vte, "\x1a", 1);
2369                         return true;
2370                 case XKB_KEY_3:
2371                 case XKB_KEY_bracketleft:
2372                 case XKB_KEY_braceleft:
2373                         vte_write(vte, "\x1b", 1);
2374                         return true;
2375                 case XKB_KEY_4:
2376                 case XKB_KEY_backslash:
2377                 case XKB_KEY_bar:
2378                         vte_write(vte, "\x1c", 1);
2379                         return true;
2380                 case XKB_KEY_5:
2381                 case XKB_KEY_bracketright:
2382                 case XKB_KEY_braceright:
2383                         vte_write(vte, "\x1d", 1);
2384                         return true;
2385                 case XKB_KEY_6:
2386                 case XKB_KEY_grave:
2387                 case XKB_KEY_asciitilde:
2388                         vte_write(vte, "\x1e", 1);
2389                         return true;
2390                 case XKB_KEY_7:
2391                 case XKB_KEY_slash:
2392                 case XKB_KEY_question:
2393                         vte_write(vte, "\x1f", 1);
2394                         return true;
2395                 case XKB_KEY_8:
2396                         vte_write(vte, "\x7f", 1);
2397                         return true;
2398                 }
2399         }
2400
2401         switch (keysym) {
2402                 case XKB_KEY_BackSpace:
2403                         vte_write(vte, "\x08", 1);
2404                         return true;
2405                 case XKB_KEY_Tab:
2406                 case XKB_KEY_KP_Tab:
2407                         vte_write(vte, "\x09", 1);
2408                         return true;
2409                 case XKB_KEY_ISO_Left_Tab:
2410                         vte_write(vte, "\e[Z", 3);
2411                         return true;
2412                 case XKB_KEY_Linefeed:
2413                         vte_write(vte, "\x0a", 1);
2414                         return true;
2415                 case XKB_KEY_Clear:
2416                         vte_write(vte, "\x0b", 1);
2417                         return true;
2418                 /*
2419                  TODO: What should we do with this key? Sending XOFF is awful as
2420                        there is no simple way on modern keyboards to send XON
2421                        again. If someone wants this, we can re-eanble it and set
2422                        some flag.
2423                 case XKB_KEY_Pause:
2424                         vte_write(vte, "\x13", 1);
2425                         return true;
2426                 */
2427                 /*
2428                  TODO: What should we do on scroll-lock? Sending 0x14 is what
2429                        the specs say but it is not used today the way most
2430                        users would expect so we disable it. If someone wants
2431                        this, we can re-enable it and set some flag.
2432                 case XKB_KEY_Scroll_Lock:
2433                         vte_write(vte, "\x14", 1);
2434                         return true;
2435                 */
2436                 case XKB_KEY_Sys_Req:
2437                         vte_write(vte, "\x15", 1);
2438                         return true;
2439                 case XKB_KEY_Escape:
2440                         vte_write(vte, "\x1b", 1);
2441                         return true;
2442                 case XKB_KEY_KP_Enter:
2443                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE) {
2444                                 vte_write(vte, "\eOM", 3);
2445                                 return true;
2446                         }
2447                         /* fallthrough */
2448                 case XKB_KEY_Return:
2449                         if (vte->flags & FLAG_LINE_FEED_NEW_LINE_MODE)
2450                                 vte_write(vte, "\x0d\x0a", 2);
2451                         else
2452                                 vte_write(vte, "\x0d", 1);
2453                         return true;
2454                 case XKB_KEY_Find:
2455                         vte_write(vte, "\e[1~", 4);
2456                         return true;
2457                 case XKB_KEY_Insert:
2458                         vte_write(vte, "\e[2~", 4);
2459                         return true;
2460                 case XKB_KEY_Delete:
2461                         vte_write(vte, "\e[3~", 4);
2462                         return true;
2463                 case XKB_KEY_Select:
2464                         vte_write(vte, "\e[4~", 4);
2465                         return true;
2466                 case XKB_KEY_Page_Up:
2467                 case XKB_KEY_KP_Page_Up:
2468                         vte_write(vte, "\e[5~", 4);
2469                         return true;
2470                 case XKB_KEY_KP_Page_Down:
2471                 case XKB_KEY_Page_Down:
2472                         vte_write(vte, "\e[6~", 4);
2473                         return true;
2474                 case XKB_KEY_Up:
2475                 case XKB_KEY_KP_Up:
2476                         if (vte->flags & FLAG_CURSOR_KEY_MODE)
2477                                 vte_write(vte, "\eOA", 3);
2478                         else
2479                                 vte_write(vte, "\e[A", 3);
2480                         return true;
2481                 case XKB_KEY_Down:
2482                 case XKB_KEY_KP_Down:
2483                         if (vte->flags & FLAG_CURSOR_KEY_MODE)
2484                                 vte_write(vte, "\eOB", 3);
2485                         else
2486                                 vte_write(vte, "\e[B", 3);
2487                         return true;
2488                 case XKB_KEY_Right:
2489                 case XKB_KEY_KP_Right:
2490                         if (vte->flags & FLAG_CURSOR_KEY_MODE)
2491                                 vte_write(vte, "\eOC", 3);
2492                         else
2493                                 vte_write(vte, "\e[C", 3);
2494                         return true;
2495                 case XKB_KEY_Left:
2496                 case XKB_KEY_KP_Left:
2497                         if (vte->flags & FLAG_CURSOR_KEY_MODE)
2498                                 vte_write(vte, "\eOD", 3);
2499                         else
2500                                 vte_write(vte, "\e[D", 3);
2501                         return true;
2502                 case XKB_KEY_KP_Insert:
2503                 case XKB_KEY_KP_0:
2504                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2505                                 vte_write(vte, "\eOp", 3);
2506                         else
2507                                 vte_write(vte, "0", 1);
2508                         return true;
2509                 case XKB_KEY_KP_1:
2510                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2511                                 vte_write(vte, "\eOq", 3);
2512                         else
2513                                 vte_write(vte, "1", 1);
2514                         return true;
2515                 case XKB_KEY_KP_2:
2516                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2517                                 vte_write(vte, "\eOr", 3);
2518                         else
2519                                 vte_write(vte, "2", 1);
2520                         return true;
2521                 case XKB_KEY_KP_3:
2522                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2523                                 vte_write(vte, "\eOs", 3);
2524                         else
2525                                 vte_write(vte, "3", 1);
2526                         return true;
2527                 case XKB_KEY_KP_4:
2528                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2529                                 vte_write(vte, "\eOt", 3);
2530                         else
2531                                 vte_write(vte, "4", 1);
2532                         return true;
2533                 case XKB_KEY_KP_5:
2534                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2535                                 vte_write(vte, "\eOu", 3);
2536                         else
2537                                 vte_write(vte, "5", 1);
2538                         return true;
2539                 case XKB_KEY_KP_6:
2540                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2541                                 vte_write(vte, "\eOv", 3);
2542                         else
2543                                 vte_write(vte, "6", 1);
2544                         return true;
2545                 case XKB_KEY_KP_7:
2546                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2547                                 vte_write(vte, "\eOw", 3);
2548                         else
2549                                 vte_write(vte, "7", 1);
2550                         return true;
2551                 case XKB_KEY_KP_8:
2552                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2553                                 vte_write(vte, "\eOx", 3);
2554                         else
2555                                 vte_write(vte, "8", 1);
2556                         return true;
2557                 case XKB_KEY_KP_9:
2558                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2559                                 vte_write(vte, "\eOy", 3);
2560                         else
2561                                 vte_write(vte, "9", 1);
2562                         return true;
2563                 case XKB_KEY_KP_Subtract:
2564                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2565                                 vte_write(vte, "\eOm", 3);
2566                         else
2567                                 vte_write(vte, "-", 1);
2568                         return true;
2569                 case XKB_KEY_KP_Separator:
2570                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2571                                 vte_write(vte, "\eOl", 3);
2572                         else
2573                                 vte_write(vte, ",", 1);
2574                         return true;
2575                 case XKB_KEY_KP_Delete:
2576                 case XKB_KEY_KP_Decimal:
2577                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2578                                 vte_write(vte, "\eOn", 3);
2579                         else
2580                                 vte_write(vte, ".", 1);
2581                         return true;
2582                 case XKB_KEY_KP_Equal:
2583                 case XKB_KEY_KP_Divide:
2584                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2585                                 vte_write(vte, "\eOj", 3);
2586                         else
2587                                 vte_write(vte, "/", 1);
2588                         return true;
2589                 case XKB_KEY_KP_Multiply:
2590                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2591                                 vte_write(vte, "\eOo", 3);
2592                         else
2593                                 vte_write(vte, "*", 1);
2594                         return true;
2595                 case XKB_KEY_KP_Add:
2596                         if (vte->flags & FLAG_KEYPAD_APPLICATION_MODE)
2597                                 vte_write(vte, "\eOk", 3);
2598                         else
2599                                 vte_write(vte, "+", 1);
2600                         return true;
2601                 case XKB_KEY_Home:
2602                 case XKB_KEY_KP_Home:
2603                         if (vte->flags & FLAG_CURSOR_KEY_MODE)
2604                                 vte_write(vte, "\eOH", 3);
2605                         else
2606                                 vte_write(vte, "\e[H", 3);
2607                         return true;
2608                 case XKB_KEY_End:
2609                 case XKB_KEY_KP_End:
2610                         if (vte->flags & FLAG_CURSOR_KEY_MODE)
2611                                 vte_write(vte, "\eOF", 3);
2612                         else
2613                                 vte_write(vte, "\e[F", 3);
2614                         return true;
2615                 case XKB_KEY_KP_Space:
2616                         vte_write(vte, " ", 1);
2617                         return true;
2618                 /* TODO: check what to transmit for functions keys when
2619                  * shift/ctrl etc. are pressed. Every terminal behaves
2620                  * differently here which is really weird.
2621                  * We now map F4 to F14 if shift is pressed and so on for all
2622                  * keys. However, such mappings should rather be done via
2623                  * xkb-configurations and we should instead add a flags argument
2624                  * to the CSIs as some of the keys here already do. */
2625                 case XKB_KEY_F1:
2626                 case XKB_KEY_KP_F1:
2627                         if (mods & TSM_SHIFT_MASK)
2628                                 vte_write(vte, "\e[23~", 5);
2629                         else
2630                                 vte_write(vte, "\eOP", 3);
2631                         return true;
2632                 case XKB_KEY_F2:
2633                 case XKB_KEY_KP_F2:
2634                         if (mods & TSM_SHIFT_MASK)
2635                                 vte_write(vte, "\e[24~", 5);
2636                         else
2637                                 vte_write(vte, "\eOQ", 3);
2638                         return true;
2639                 case XKB_KEY_F3:
2640                 case XKB_KEY_KP_F3:
2641                         if (mods & TSM_SHIFT_MASK)
2642                                 vte_write(vte, "\e[25~", 5);
2643                         else
2644                                 vte_write(vte, "\eOR", 3);
2645                         return true;
2646                 case XKB_KEY_F4:
2647                 case XKB_KEY_KP_F4:
2648                         if (mods & TSM_SHIFT_MASK)
2649                                 //vte_write(vte, "\e[1;2S", 6);
2650                                 vte_write(vte, "\e[26~", 5);
2651                         else
2652                                 vte_write(vte, "\eOS", 3);
2653                         return true;
2654                 case XKB_KEY_F5:
2655                         if (mods & TSM_SHIFT_MASK)
2656                                 //vte_write(vte, "\e[15;2~", 7);
2657                                 vte_write(vte, "\e[28~", 5);
2658                         else
2659                                 vte_write(vte, "\e[15~", 5);
2660                         return true;
2661                 case XKB_KEY_F6:
2662                         if (mods & TSM_SHIFT_MASK)
2663                                 //vte_write(vte, "\e[17;2~", 7);
2664                                 vte_write(vte, "\e[29~", 5);
2665                         else
2666                                 vte_write(vte, "\e[17~", 5);
2667                         return true;
2668                 case XKB_KEY_F7:
2669                         if (mods & TSM_SHIFT_MASK)
2670                                 //vte_write(vte, "\e[18;2~", 7);
2671                                 vte_write(vte, "\e[31~", 5);
2672                         else
2673                                 vte_write(vte, "\e[18~", 5);
2674                         return true;
2675                 case XKB_KEY_F8:
2676                         if (mods & TSM_SHIFT_MASK)
2677                                 //vte_write(vte, "\e[19;2~", 7);
2678                                 vte_write(vte, "\e[32~", 5);
2679                         else
2680                                 vte_write(vte, "\e[19~", 5);
2681                         return true;
2682                 case XKB_KEY_F9:
2683                         if (mods & TSM_SHIFT_MASK)
2684                                 //vte_write(vte, "\e[20;2~", 7);
2685                                 vte_write(vte, "\e[33~", 5);
2686                         else
2687                                 vte_write(vte, "\e[20~", 5);
2688                         return true;
2689                 case XKB_KEY_F10:
2690                         if (mods & TSM_SHIFT_MASK)
2691                                 //vte_write(vte, "\e[21;2~", 7);
2692                                 vte_write(vte, "\e[34~", 5);
2693                         else
2694                                 vte_write(vte, "\e[21~", 5);
2695                         return true;
2696                 case XKB_KEY_F11:
2697                         if (mods & TSM_SHIFT_MASK)
2698                                 vte_write(vte, "\e[23;2~", 7);
2699                         else
2700                                 vte_write(vte, "\e[23~", 5);
2701                         return true;
2702                 case XKB_KEY_F12:
2703                         if (mods & TSM_SHIFT_MASK)
2704                                 vte_write(vte, "\e[24;2~", 7);
2705                         else
2706                                 vte_write(vte, "\e[24~", 5);
2707                         return true;
2708                 case XKB_KEY_F13:
2709                         if (mods & TSM_SHIFT_MASK)
2710                                 vte_write(vte, "\e[25;2~", 7);
2711                         else
2712                                 vte_write(vte, "\e[25~", 5);
2713                         return true;
2714                 case XKB_KEY_F14:
2715                         if (mods & TSM_SHIFT_MASK)
2716                                 vte_write(vte, "\e[26;2~", 7);
2717                         else
2718                                 vte_write(vte, "\e[26~", 5);
2719                         return true;
2720                 case XKB_KEY_F15:
2721                         if (mods & TSM_SHIFT_MASK)
2722                                 vte_write(vte, "\e[28;2~", 7);
2723                         else
2724                                 vte_write(vte, "\e[28~", 5);
2725                         return true;
2726                 case XKB_KEY_F16:
2727                         if (mods & TSM_SHIFT_MASK)
2728                                 vte_write(vte, "\e[29;2~", 7);
2729                         else
2730                                 vte_write(vte, "\e[29~", 5);
2731                         return true;
2732                 case XKB_KEY_F17:
2733                         if (mods & TSM_SHIFT_MASK)
2734                                 vte_write(vte, "\e[31;2~", 7);
2735                         else
2736                                 vte_write(vte, "\e[31~", 5);
2737                         return true;
2738                 case XKB_KEY_F18:
2739                         if (mods & TSM_SHIFT_MASK)
2740                                 vte_write(vte, "\e[32;2~", 7);
2741                         else
2742                                 vte_write(vte, "\e[32~", 5);
2743                         return true;
2744                 case XKB_KEY_F19:
2745                         if (mods & TSM_SHIFT_MASK)
2746                                 vte_write(vte, "\e[33;2~", 7);
2747                         else
2748                                 vte_write(vte, "\e[33~", 5);
2749                         return true;
2750                 case XKB_KEY_F20:
2751                         if (mods & TSM_SHIFT_MASK)
2752                                 vte_write(vte, "\e[34;2~", 7);
2753                         else
2754                                 vte_write(vte, "\e[34~", 5);
2755                         return true;
2756         }
2757
2758         if (unicode != TSM_VTE_INVALID) {
2759                 if (vte->flags & FLAG_7BIT_MODE) {
2760                         val = unicode;
2761                         if (unicode & 0x80) {
2762                                 llog_debug(vte, "invalid keyboard input in 7bit mode U+%x; mapping to '?'",
2763                                            unicode);
2764                                 val = '?';
2765                         }
2766                         vte_write(vte, &val, 1);
2767                 } else if (vte->flags & FLAG_8BIT_MODE) {
2768                         val = unicode;
2769                         if (unicode > 0xff) {
2770                                 llog_debug(vte, "invalid keyboard input in 8bit mode U+%x; mapping to '?'",
2771                                            unicode);
2772                                 val = '?';
2773                         }
2774                         vte_write_raw(vte, &val, 1);
2775                 } else {
2776                         len = tsm_ucs4_to_utf8(tsm_symbol_make(unicode), u8);
2777                         vte_write_raw(vte, u8, len);
2778                 }
2779                 return true;
2780         }
2781
2782         vte->flags &= ~FLAG_PREPEND_ESCAPE;
2783         return false;
2784 }