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