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