1 /* $OpenBSD$ */
2 
3 /*
4  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 
21 #include <netinet/in.h>
22 
23 #include <ctype.h>
24 #include <resolv.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>
28 
29 #include "tmux.h"
30 
31 /*
32  * Based on the description by Paul Williams at:
33  *
34  * https://vt100.net/emu/dec_ansi_parser
35  *
36  * With the following changes:
37  *
38  * - 7-bit only.
39  *
40  * - Support for UTF-8.
41  *
42  * - OSC (but not APC) may be terminated by \007 as well as ST.
43  *
44  * - A state for APC similar to OSC. Some terminals appear to use this to set
45  *   the title.
46  *
47  * - A state for the screen \033k...\033\\ sequence to rename a window. This is
48  *   pretty stupid but not supporting it is more trouble than it is worth.
49  *
50  * - Special handling for ESC inside a DCS to allow arbitrary byte sequences to
51  *   be passed to the underlying terminals.
52  */
53 
54 /* Input parser cell. */
55 struct input_cell {
56           struct grid_cell    cell;
57           int                           set;
58           int                           g0set;    /* 1 if ACS */
59           int                           g1set;    /* 1 if ACS */
60 };
61 
62 /* Input parser argument. */
63 struct input_param {
64           enum {
65                     INPUT_MISSING,
66                     INPUT_NUMBER,
67                     INPUT_STRING
68           }                             type;
69           union {
70                     int                 num;
71                     char             *str;
72           };
73 };
74 
75 /* Input parser context. */
76 struct input_ctx {
77           struct window_pane     *wp;
78           struct bufferevent     *event;
79           struct screen_write_ctx ctx;
80           struct colour_palette  *palette;
81 
82           struct input_cell   cell;
83 
84           struct input_cell   old_cell;
85           u_int                         old_cx;
86           u_int                         old_cy;
87           int                           old_mode;
88 
89           u_char                        interm_buf[4];
90           size_t                        interm_len;
91 
92           u_char                        param_buf[64];
93           size_t                        param_len;
94 
95 #define INPUT_BUF_START 32
96 #define INPUT_BUF_LIMIT 1048576
97           u_char                     *input_buf;
98           size_t                        input_len;
99           size_t                        input_space;
100           enum {
101                     INPUT_END_ST,
102                     INPUT_END_BEL
103           }                             input_end;
104 
105           struct input_param  param_list[24];
106           u_int                         param_list_len;
107 
108           struct utf8_data    utf8data;
109           int                           utf8started;
110 
111           int                           ch;
112           struct utf8_data    last;
113 
114           int                           flags;
115 #define INPUT_DISCARD 0x1
116 #define INPUT_LAST 0x2
117 
118           const struct input_state *state;
119 
120           struct event                  timer;
121 
122           /*
123            * All input received since we were last in the ground state. Sent to
124            * control clients on connection.
125            */
126           struct evbuffer               *since_ground;
127 };
128 
129 /* Helper functions. */
130 struct input_transition;
131 static int          input_split(struct input_ctx *);
132 static int          input_get(struct input_ctx *, u_int, int, int);
133 static void printflike(2, 3) input_reply(struct input_ctx *, const char *, ...);
134 static void         input_set_state(struct input_ctx *,
135                         const struct input_transition *);
136 static void         input_reset_cell(struct input_ctx *);
137 
138 static void         input_osc_4(struct input_ctx *, const char *);
139 static void         input_osc_8(struct input_ctx *, const char *);
140 static void         input_osc_10(struct input_ctx *, const char *);
141 static void         input_osc_11(struct input_ctx *, const char *);
142 static void         input_osc_12(struct input_ctx *, const char *);
143 static void         input_osc_52(struct input_ctx *, const char *);
144 static void         input_osc_104(struct input_ctx *, const char *);
145 static void         input_osc_110(struct input_ctx *, const char *);
146 static void         input_osc_111(struct input_ctx *, const char *);
147 static void         input_osc_112(struct input_ctx *, const char *);
148 static void         input_osc_133(struct input_ctx *, const char *);
149 
150 /* Transition entry/exit handlers. */
151 static void         input_clear(struct input_ctx *);
152 static void         input_ground(struct input_ctx *);
153 static void         input_enter_dcs(struct input_ctx *);
154 static void         input_enter_osc(struct input_ctx *);
155 static void         input_exit_osc(struct input_ctx *);
156 static void         input_enter_apc(struct input_ctx *);
157 static void         input_exit_apc(struct input_ctx *);
158 static void         input_enter_rename(struct input_ctx *);
159 static void         input_exit_rename(struct input_ctx *);
160 
161 /* Input state handlers. */
162 static int          input_print(struct input_ctx *);
163 static int          input_intermediate(struct input_ctx *);
164 static int          input_parameter(struct input_ctx *);
165 static int          input_input(struct input_ctx *);
166 static int          input_c0_dispatch(struct input_ctx *);
167 static int          input_esc_dispatch(struct input_ctx *);
168 static int          input_csi_dispatch(struct input_ctx *);
169 static void         input_csi_dispatch_rm(struct input_ctx *);
170 static void         input_csi_dispatch_rm_private(struct input_ctx *);
171 static void         input_csi_dispatch_sm(struct input_ctx *);
172 static void         input_csi_dispatch_sm_private(struct input_ctx *);
173 static void         input_csi_dispatch_sm_graphics(struct input_ctx *);
174 static void         input_csi_dispatch_winops(struct input_ctx *);
175 static void         input_csi_dispatch_sgr_256(struct input_ctx *, int, u_int *);
176 static void         input_csi_dispatch_sgr_rgb(struct input_ctx *, int, u_int *);
177 static void         input_csi_dispatch_sgr(struct input_ctx *);
178 static int          input_dcs_dispatch(struct input_ctx *);
179 static int          input_top_bit_set(struct input_ctx *);
180 static int          input_end_bel(struct input_ctx *);
181 
182 /* Command table comparison function. */
183 static int          input_table_compare(const void *, const void *);
184 
185 /* Command table entry. */
186 struct input_table_entry {
187           int                 ch;
188           const char     *interm;
189           int                 type;
190 };
191 
192 /* Escape commands. */
193 enum input_esc_type {
194           INPUT_ESC_DECALN,
195           INPUT_ESC_DECKPAM,
196           INPUT_ESC_DECKPNM,
197           INPUT_ESC_DECRC,
198           INPUT_ESC_DECSC,
199           INPUT_ESC_HTS,
200           INPUT_ESC_IND,
201           INPUT_ESC_NEL,
202           INPUT_ESC_RI,
203           INPUT_ESC_RIS,
204           INPUT_ESC_SCSG0_OFF,
205           INPUT_ESC_SCSG0_ON,
206           INPUT_ESC_SCSG1_OFF,
207           INPUT_ESC_SCSG1_ON,
208           INPUT_ESC_ST
209 };
210 
211 /* Escape command table. */
212 static const struct input_table_entry input_esc_table[] = {
213           { '0', "(", INPUT_ESC_SCSG0_ON },
214           { '0', ")", INPUT_ESC_SCSG1_ON },
215           { '7', "",  INPUT_ESC_DECSC },
216           { '8', "",  INPUT_ESC_DECRC },
217           { '8', "#", INPUT_ESC_DECALN },
218           { '=', "",  INPUT_ESC_DECKPAM },
219           { '>', "",  INPUT_ESC_DECKPNM },
220           { 'B', "(", INPUT_ESC_SCSG0_OFF },
221           { 'B', ")", INPUT_ESC_SCSG1_OFF },
222           { 'D', "",  INPUT_ESC_IND },
223           { 'E', "",  INPUT_ESC_NEL },
224           { 'H', "",  INPUT_ESC_HTS },
225           { 'M', "",  INPUT_ESC_RI },
226           { '\\', "", INPUT_ESC_ST },
227           { 'c', "",  INPUT_ESC_RIS },
228 };
229 
230 /* Control (CSI) commands. */
231 enum input_csi_type {
232           INPUT_CSI_CBT,
233           INPUT_CSI_CNL,
234           INPUT_CSI_CPL,
235           INPUT_CSI_CUB,
236           INPUT_CSI_CUD,
237           INPUT_CSI_CUF,
238           INPUT_CSI_CUP,
239           INPUT_CSI_CUU,
240           INPUT_CSI_DA,
241           INPUT_CSI_DA_TWO,
242           INPUT_CSI_DCH,
243           INPUT_CSI_DECSCUSR,
244           INPUT_CSI_DECSTBM,
245           INPUT_CSI_DL,
246           INPUT_CSI_DSR,
247           INPUT_CSI_ECH,
248           INPUT_CSI_ED,
249           INPUT_CSI_EL,
250           INPUT_CSI_HPA,
251           INPUT_CSI_ICH,
252           INPUT_CSI_IL,
253           INPUT_CSI_MODOFF,
254           INPUT_CSI_MODSET,
255           INPUT_CSI_RCP,
256           INPUT_CSI_REP,
257           INPUT_CSI_RM,
258           INPUT_CSI_RM_PRIVATE,
259           INPUT_CSI_SCP,
260           INPUT_CSI_SD,
261           INPUT_CSI_SGR,
262           INPUT_CSI_SM,
263           INPUT_CSI_SM_PRIVATE,
264           INPUT_CSI_SM_GRAPHICS,
265           INPUT_CSI_SU,
266           INPUT_CSI_TBC,
267           INPUT_CSI_VPA,
268           INPUT_CSI_WINOPS,
269           INPUT_CSI_XDA
270 };
271 
272 /* Control (CSI) command table. */
273 static const struct input_table_entry input_csi_table[] = {
274           { '@', "",  INPUT_CSI_ICH },
275           { 'A', "",  INPUT_CSI_CUU },
276           { 'B', "",  INPUT_CSI_CUD },
277           { 'C', "",  INPUT_CSI_CUF },
278           { 'D', "",  INPUT_CSI_CUB },
279           { 'E', "",  INPUT_CSI_CNL },
280           { 'F', "",  INPUT_CSI_CPL },
281           { 'G', "",  INPUT_CSI_HPA },
282           { 'H', "",  INPUT_CSI_CUP },
283           { 'J', "",  INPUT_CSI_ED },
284           { 'K', "",  INPUT_CSI_EL },
285           { 'L', "",  INPUT_CSI_IL },
286           { 'M', "",  INPUT_CSI_DL },
287           { 'P', "",  INPUT_CSI_DCH },
288           { 'S', "",  INPUT_CSI_SU },
289           { 'S', "?", INPUT_CSI_SM_GRAPHICS },
290           { 'T', "",  INPUT_CSI_SD },
291           { 'X', "",  INPUT_CSI_ECH },
292           { 'Z', "",  INPUT_CSI_CBT },
293           { '`', "",  INPUT_CSI_HPA },
294           { 'b', "",  INPUT_CSI_REP },
295           { 'c', "",  INPUT_CSI_DA },
296           { 'c', ">", INPUT_CSI_DA_TWO },
297           { 'd', "",  INPUT_CSI_VPA },
298           { 'f', "",  INPUT_CSI_CUP },
299           { 'g', "",  INPUT_CSI_TBC },
300           { 'h', "",  INPUT_CSI_SM },
301           { 'h', "?", INPUT_CSI_SM_PRIVATE },
302           { 'l', "",  INPUT_CSI_RM },
303           { 'l', "?", INPUT_CSI_RM_PRIVATE },
304           { 'm', "",  INPUT_CSI_SGR },
305           { 'm', ">", INPUT_CSI_MODSET },
306           { 'n', "",  INPUT_CSI_DSR },
307           { 'n', ">", INPUT_CSI_MODOFF },
308           { 'q', " ", INPUT_CSI_DECSCUSR },
309           { 'q', ">", INPUT_CSI_XDA },
310           { 'r', "",  INPUT_CSI_DECSTBM },
311           { 's', "",  INPUT_CSI_SCP },
312           { 't', "",  INPUT_CSI_WINOPS },
313           { 'u', "",  INPUT_CSI_RCP }
314 };
315 
316 /* Input transition. */
317 struct input_transition {
318           int                                     first;
319           int                                     last;
320 
321           int                                     (*handler)(struct input_ctx *);
322           const struct input_state       *state;
323 };
324 
325 /* Input state. */
326 struct input_state {
327           const char                              *name;
328           void                                    (*enter)(struct input_ctx *);
329           void                                    (*exit)(struct input_ctx *);
330           const struct input_transition *transitions;
331 };
332 
333 /* State transitions available from all states. */
334 #define INPUT_STATE_ANYWHERE \
335           { 0x18, 0x18, input_c0_dispatch, &input_state_ground }, \
336           { 0x1a, 0x1a, input_c0_dispatch, &input_state_ground }, \
337           { 0x1b, 0x1b, NULL,            &input_state_esc_enter }
338 
339 /* Forward declarations of state tables. */
340 static const struct input_transition input_state_ground_table[];
341 static const struct input_transition input_state_esc_enter_table[];
342 static const struct input_transition input_state_esc_intermediate_table[];
343 static const struct input_transition input_state_csi_enter_table[];
344 static const struct input_transition input_state_csi_parameter_table[];
345 static const struct input_transition input_state_csi_intermediate_table[];
346 static const struct input_transition input_state_csi_ignore_table[];
347 static const struct input_transition input_state_dcs_enter_table[];
348 static const struct input_transition input_state_dcs_parameter_table[];
349 static const struct input_transition input_state_dcs_intermediate_table[];
350 static const struct input_transition input_state_dcs_handler_table[];
351 static const struct input_transition input_state_dcs_escape_table[];
352 static const struct input_transition input_state_dcs_ignore_table[];
353 static const struct input_transition input_state_osc_string_table[];
354 static const struct input_transition input_state_apc_string_table[];
355 static const struct input_transition input_state_rename_string_table[];
356 static const struct input_transition input_state_consume_st_table[];
357 
358 /* ground state definition. */
359 static const struct input_state input_state_ground = {
360           "ground",
361           input_ground, NULL,
362           input_state_ground_table
363 };
364 
365 /* esc_enter state definition. */
366 static const struct input_state input_state_esc_enter = {
367           "esc_enter",
368           input_clear, NULL,
369           input_state_esc_enter_table
370 };
371 
372 /* esc_intermediate state definition. */
373 static const struct input_state input_state_esc_intermediate = {
374           "esc_intermediate",
375           NULL, NULL,
376           input_state_esc_intermediate_table
377 };
378 
379 /* csi_enter state definition. */
380 static const struct input_state input_state_csi_enter = {
381           "csi_enter",
382           input_clear, NULL,
383           input_state_csi_enter_table
384 };
385 
386 /* csi_parameter state definition. */
387 static const struct input_state input_state_csi_parameter = {
388           "csi_parameter",
389           NULL, NULL,
390           input_state_csi_parameter_table
391 };
392 
393 /* csi_intermediate state definition. */
394 static const struct input_state input_state_csi_intermediate = {
395           "csi_intermediate",
396           NULL, NULL,
397           input_state_csi_intermediate_table
398 };
399 
400 /* csi_ignore state definition. */
401 static const struct input_state input_state_csi_ignore = {
402           "csi_ignore",
403           NULL, NULL,
404           input_state_csi_ignore_table
405 };
406 
407 /* dcs_enter state definition. */
408 static const struct input_state input_state_dcs_enter = {
409           "dcs_enter",
410           input_enter_dcs, NULL,
411           input_state_dcs_enter_table
412 };
413 
414 /* dcs_parameter state definition. */
415 static const struct input_state input_state_dcs_parameter = {
416           "dcs_parameter",
417           NULL, NULL,
418           input_state_dcs_parameter_table
419 };
420 
421 /* dcs_intermediate state definition. */
422 static const struct input_state input_state_dcs_intermediate = {
423           "dcs_intermediate",
424           NULL, NULL,
425           input_state_dcs_intermediate_table
426 };
427 
428 /* dcs_handler state definition. */
429 static const struct input_state input_state_dcs_handler = {
430           "dcs_handler",
431           NULL, NULL,
432           input_state_dcs_handler_table
433 };
434 
435 /* dcs_escape state definition. */
436 static const struct input_state input_state_dcs_escape = {
437           "dcs_escape",
438           NULL, NULL,
439           input_state_dcs_escape_table
440 };
441 
442 /* dcs_ignore state definition. */
443 static const struct input_state input_state_dcs_ignore = {
444           "dcs_ignore",
445           NULL, NULL,
446           input_state_dcs_ignore_table
447 };
448 
449 /* osc_string state definition. */
450 static const struct input_state input_state_osc_string = {
451           "osc_string",
452           input_enter_osc, input_exit_osc,
453           input_state_osc_string_table
454 };
455 
456 /* apc_string state definition. */
457 static const struct input_state input_state_apc_string = {
458           "apc_string",
459           input_enter_apc, input_exit_apc,
460           input_state_apc_string_table
461 };
462 
463 /* rename_string state definition. */
464 static const struct input_state input_state_rename_string = {
465           "rename_string",
466           input_enter_rename, input_exit_rename,
467           input_state_rename_string_table
468 };
469 
470 /* consume_st state definition. */
471 static const struct input_state input_state_consume_st = {
472           "consume_st",
473           input_enter_rename, NULL, /* rename also waits for ST */
474           input_state_consume_st_table
475 };
476 
477 /* ground state table. */
478 static const struct input_transition input_state_ground_table[] = {
479           INPUT_STATE_ANYWHERE,
480 
481           { 0x00, 0x17, input_c0_dispatch, NULL },
482           { 0x19, 0x19, input_c0_dispatch, NULL },
483           { 0x1c, 0x1f, input_c0_dispatch, NULL },
484           { 0x20, 0x7e, input_print,     NULL },
485           { 0x7f, 0x7f, NULL,            NULL },
486           { 0x80, 0xff, input_top_bit_set, NULL },
487 
488           { -1, -1, NULL, NULL }
489 };
490 
491 /* esc_enter state table. */
492 static const struct input_transition input_state_esc_enter_table[] = {
493           INPUT_STATE_ANYWHERE,
494 
495           { 0x00, 0x17, input_c0_dispatch,  NULL },
496           { 0x19, 0x19, input_c0_dispatch,  NULL },
497           { 0x1c, 0x1f, input_c0_dispatch,  NULL },
498           { 0x20, 0x2f, input_intermediate, &input_state_esc_intermediate },
499           { 0x30, 0x4f, input_esc_dispatch, &input_state_ground },
500           { 0x50, 0x50, NULL,             &input_state_dcs_enter },
501           { 0x51, 0x57, input_esc_dispatch, &input_state_ground },
502           { 0x58, 0x58, NULL,             &input_state_consume_st },
503           { 0x59, 0x59, input_esc_dispatch, &input_state_ground },
504           { 0x5a, 0x5a, input_esc_dispatch, &input_state_ground },
505           { 0x5b, 0x5b, NULL,             &input_state_csi_enter },
506           { 0x5c, 0x5c, input_esc_dispatch, &input_state_ground },
507           { 0x5d, 0x5d, NULL,             &input_state_osc_string },
508           { 0x5e, 0x5e, NULL,             &input_state_consume_st },
509           { 0x5f, 0x5f, NULL,             &input_state_apc_string },
510           { 0x60, 0x6a, input_esc_dispatch, &input_state_ground },
511           { 0x6b, 0x6b, NULL,             &input_state_rename_string },
512           { 0x6c, 0x7e, input_esc_dispatch, &input_state_ground },
513           { 0x7f, 0xff, NULL,             NULL },
514 
515           { -1, -1, NULL, NULL }
516 };
517 
518 /* esc_intermediate state table. */
519 static const struct input_transition input_state_esc_intermediate_table[] = {
520           INPUT_STATE_ANYWHERE,
521 
522           { 0x00, 0x17, input_c0_dispatch,  NULL },
523           { 0x19, 0x19, input_c0_dispatch,  NULL },
524           { 0x1c, 0x1f, input_c0_dispatch,  NULL },
525           { 0x20, 0x2f, input_intermediate, NULL },
526           { 0x30, 0x7e, input_esc_dispatch, &input_state_ground },
527           { 0x7f, 0xff, NULL,             NULL },
528 
529           { -1, -1, NULL, NULL }
530 };
531 
532 /* csi_enter state table. */
533 static const struct input_transition input_state_csi_enter_table[] = {
534           INPUT_STATE_ANYWHERE,
535 
536           { 0x00, 0x17, input_c0_dispatch,  NULL },
537           { 0x19, 0x19, input_c0_dispatch,  NULL },
538           { 0x1c, 0x1f, input_c0_dispatch,  NULL },
539           { 0x20, 0x2f, input_intermediate, &input_state_csi_intermediate },
540           { 0x30, 0x39, input_parameter,            &input_state_csi_parameter },
541           { 0x3a, 0x3a, input_parameter,            &input_state_csi_parameter },
542           { 0x3b, 0x3b, input_parameter,            &input_state_csi_parameter },
543           { 0x3c, 0x3f, input_intermediate, &input_state_csi_parameter },
544           { 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
545           { 0x7f, 0xff, NULL,             NULL },
546 
547           { -1, -1, NULL, NULL }
548 };
549 
550 /* csi_parameter state table. */
551 static const struct input_transition input_state_csi_parameter_table[] = {
552           INPUT_STATE_ANYWHERE,
553 
554           { 0x00, 0x17, input_c0_dispatch,  NULL },
555           { 0x19, 0x19, input_c0_dispatch,  NULL },
556           { 0x1c, 0x1f, input_c0_dispatch,  NULL },
557           { 0x20, 0x2f, input_intermediate, &input_state_csi_intermediate },
558           { 0x30, 0x39, input_parameter,            NULL },
559           { 0x3a, 0x3a, input_parameter,            NULL },
560           { 0x3b, 0x3b, input_parameter,            NULL },
561           { 0x3c, 0x3f, NULL,             &input_state_csi_ignore },
562           { 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
563           { 0x7f, 0xff, NULL,             NULL },
564 
565           { -1, -1, NULL, NULL }
566 };
567 
568 /* csi_intermediate state table. */
569 static const struct input_transition input_state_csi_intermediate_table[] = {
570           INPUT_STATE_ANYWHERE,
571 
572           { 0x00, 0x17, input_c0_dispatch,  NULL },
573           { 0x19, 0x19, input_c0_dispatch,  NULL },
574           { 0x1c, 0x1f, input_c0_dispatch,  NULL },
575           { 0x20, 0x2f, input_intermediate, NULL },
576           { 0x30, 0x3f, NULL,             &input_state_csi_ignore },
577           { 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
578           { 0x7f, 0xff, NULL,             NULL },
579 
580           { -1, -1, NULL, NULL }
581 };
582 
583 /* csi_ignore state table. */
584 static const struct input_transition input_state_csi_ignore_table[] = {
585           INPUT_STATE_ANYWHERE,
586 
587           { 0x00, 0x17, input_c0_dispatch, NULL },
588           { 0x19, 0x19, input_c0_dispatch, NULL },
589           { 0x1c, 0x1f, input_c0_dispatch, NULL },
590           { 0x20, 0x3f, NULL,            NULL },
591           { 0x40, 0x7e, NULL,            &input_state_ground },
592           { 0x7f, 0xff, NULL,            NULL },
593 
594           { -1, -1, NULL, NULL }
595 };
596 
597 /* dcs_enter state table. */
598 static const struct input_transition input_state_dcs_enter_table[] = {
599           INPUT_STATE_ANYWHERE,
600 
601           { 0x00, 0x17, NULL,             NULL },
602           { 0x19, 0x19, NULL,             NULL },
603           { 0x1c, 0x1f, NULL,             NULL },
604           { 0x20, 0x2f, input_intermediate, &input_state_dcs_intermediate },
605           { 0x30, 0x39, input_parameter,            &input_state_dcs_parameter },
606           { 0x3a, 0x3a, NULL,             &input_state_dcs_ignore },
607           { 0x3b, 0x3b, input_parameter,            &input_state_dcs_parameter },
608           { 0x3c, 0x3f, input_intermediate, &input_state_dcs_parameter },
609           { 0x40, 0x7e, input_input,      &input_state_dcs_handler },
610           { 0x7f, 0xff, NULL,             NULL },
611 
612           { -1, -1, NULL, NULL }
613 };
614 
615 /* dcs_parameter state table. */
616 static const struct input_transition input_state_dcs_parameter_table[] = {
617           INPUT_STATE_ANYWHERE,
618 
619           { 0x00, 0x17, NULL,             NULL },
620           { 0x19, 0x19, NULL,             NULL },
621           { 0x1c, 0x1f, NULL,             NULL },
622           { 0x20, 0x2f, input_intermediate, &input_state_dcs_intermediate },
623           { 0x30, 0x39, input_parameter,            NULL },
624           { 0x3a, 0x3a, NULL,             &input_state_dcs_ignore },
625           { 0x3b, 0x3b, input_parameter,            NULL },
626           { 0x3c, 0x3f, NULL,             &input_state_dcs_ignore },
627           { 0x40, 0x7e, input_input,      &input_state_dcs_handler },
628           { 0x7f, 0xff, NULL,             NULL },
629 
630           { -1, -1, NULL, NULL }
631 };
632 
633 /* dcs_intermediate state table. */
634 static const struct input_transition input_state_dcs_intermediate_table[] = {
635           INPUT_STATE_ANYWHERE,
636 
637           { 0x00, 0x17, NULL,             NULL },
638           { 0x19, 0x19, NULL,             NULL },
639           { 0x1c, 0x1f, NULL,             NULL },
640           { 0x20, 0x2f, input_intermediate, NULL },
641           { 0x30, 0x3f, NULL,             &input_state_dcs_ignore },
642           { 0x40, 0x7e, input_input,      &input_state_dcs_handler },
643           { 0x7f, 0xff, NULL,             NULL },
644 
645           { -1, -1, NULL, NULL }
646 };
647 
648 /* dcs_handler state table. */
649 static const struct input_transition input_state_dcs_handler_table[] = {
650           /* No INPUT_STATE_ANYWHERE */
651 
652           { 0x00, 0x1a, input_input,  NULL },
653           { 0x1b, 0x1b, NULL,     &input_state_dcs_escape },
654           { 0x1c, 0xff, input_input,  NULL },
655 
656           { -1, -1, NULL, NULL }
657 };
658 
659 /* dcs_escape state table. */
660 static const struct input_transition input_state_dcs_escape_table[] = {
661           /* No INPUT_STATE_ANYWHERE */
662 
663           { 0x00, 0x5b, input_input,      &input_state_dcs_handler },
664           { 0x5c, 0x5c, input_dcs_dispatch, &input_state_ground },
665           { 0x5d, 0xff, input_input,      &input_state_dcs_handler },
666 
667           { -1, -1, NULL, NULL }
668 };
669 
670 /* dcs_ignore state table. */
671 static const struct input_transition input_state_dcs_ignore_table[] = {
672           INPUT_STATE_ANYWHERE,
673 
674           { 0x00, 0x17, NULL,     NULL },
675           { 0x19, 0x19, NULL,     NULL },
676           { 0x1c, 0x1f, NULL,     NULL },
677           { 0x20, 0xff, NULL,     NULL },
678 
679           { -1, -1, NULL, NULL }
680 };
681 
682 /* osc_string state table. */
683 static const struct input_transition input_state_osc_string_table[] = {
684           INPUT_STATE_ANYWHERE,
685 
686           { 0x00, 0x06, NULL,      NULL },
687           { 0x07, 0x07, input_end_bel, &input_state_ground },
688           { 0x08, 0x17, NULL,      NULL },
689           { 0x19, 0x19, NULL,      NULL },
690           { 0x1c, 0x1f, NULL,      NULL },
691           { 0x20, 0xff, input_input,   NULL },
692 
693           { -1, -1, NULL, NULL }
694 };
695 
696 /* apc_string state table. */
697 static const struct input_transition input_state_apc_string_table[] = {
698           INPUT_STATE_ANYWHERE,
699 
700           { 0x00, 0x17, NULL,     NULL },
701           { 0x19, 0x19, NULL,     NULL },
702           { 0x1c, 0x1f, NULL,     NULL },
703           { 0x20, 0xff, input_input,  NULL },
704 
705           { -1, -1, NULL, NULL }
706 };
707 
708 /* rename_string state table. */
709 static const struct input_transition input_state_rename_string_table[] = {
710           INPUT_STATE_ANYWHERE,
711 
712           { 0x00, 0x17, NULL,     NULL },
713           { 0x19, 0x19, NULL,     NULL },
714           { 0x1c, 0x1f, NULL,     NULL },
715           { 0x20, 0xff, input_input,  NULL },
716 
717           { -1, -1, NULL, NULL }
718 };
719 
720 /* consume_st state table. */
721 static const struct input_transition input_state_consume_st_table[] = {
722           INPUT_STATE_ANYWHERE,
723 
724           { 0x00, 0x17, NULL,     NULL },
725           { 0x19, 0x19, NULL,     NULL },
726           { 0x1c, 0x1f, NULL,     NULL },
727           { 0x20, 0xff, NULL,     NULL },
728 
729           { -1, -1, NULL, NULL }
730 };
731 
732 /* Input table compare. */
733 static int
input_table_compare(const void * key,const void * value)734 input_table_compare(const void *key, const void *value)
735 {
736           const struct input_ctx                  *ictx = key;
737           const struct input_table_entry          *entry = value;
738 
739           if (ictx->ch != entry->ch)
740                     return (ictx->ch - entry->ch);
741           return (strcmp((const char *)ictx->interm_buf, entry->interm));
742 }
743 
744 /*
745  * Timer - if this expires then have been waiting for a terminator for too
746  * long, so reset to ground.
747  */
748 static void
input_timer_callback(__unused int fd,__unused short events,void * arg)749 input_timer_callback(__unused int fd, __unused short events, void *arg)
750 {
751           struct input_ctx    *ictx = arg;
752 
753           log_debug("%s: %s expired" , __func__, ictx->state->name);
754           input_reset(ictx, 0);
755 }
756 
757 /* Start the timer. */
758 static void
input_start_timer(struct input_ctx * ictx)759 input_start_timer(struct input_ctx *ictx)
760 {
761           struct timeval      tv = { .tv_sec = 5, .tv_usec = 0 };
762 
763           event_del(&ictx->timer);
764           event_add(&ictx->timer, &tv);
765 }
766 
767 /* Reset cell state to default. */
768 static void
input_reset_cell(struct input_ctx * ictx)769 input_reset_cell(struct input_ctx *ictx)
770 {
771           memcpy(&ictx->cell.cell, &grid_default_cell, sizeof ictx->cell.cell);
772           ictx->cell.set = 0;
773           ictx->cell.g0set = ictx->cell.g1set = 0;
774 
775           memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
776           ictx->old_cx = 0;
777           ictx->old_cy = 0;
778 }
779 
780 /* Save screen state. */
781 static void
input_save_state(struct input_ctx * ictx)782 input_save_state(struct input_ctx *ictx)
783 {
784           struct screen_write_ctx       *sctx = &ictx->ctx;
785           struct screen                 *s = sctx->s;
786 
787           memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
788           ictx->old_cx = s->cx;
789           ictx->old_cy = s->cy;
790           ictx->old_mode = s->mode;
791 }
792 
793 /* Restore screen state. */
794 static void
input_restore_state(struct input_ctx * ictx)795 input_restore_state(struct input_ctx *ictx)
796 {
797           struct screen_write_ctx       *sctx = &ictx->ctx;
798 
799           memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell);
800           if (ictx->old_mode & MODE_ORIGIN)
801                     screen_write_mode_set(sctx, MODE_ORIGIN);
802           else
803                     screen_write_mode_clear(sctx, MODE_ORIGIN);
804           screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy, 0);
805 }
806 
807 /* Initialise input parser. */
808 struct input_ctx *
input_init(struct window_pane * wp,struct bufferevent * bev,struct colour_palette * palette)809 input_init(struct window_pane *wp, struct bufferevent *bev,
810     struct colour_palette *palette)
811 {
812           struct input_ctx    *ictx;
813 
814           ictx = xcalloc(1, sizeof *ictx);
815           ictx->wp = wp;
816           ictx->event = bev;
817           ictx->palette = palette;
818 
819           ictx->input_space = INPUT_BUF_START;
820           ictx->input_buf = xmalloc(INPUT_BUF_START);
821 
822           ictx->since_ground = evbuffer_new();
823           if (ictx->since_ground == NULL)
824                     fatalx("out of memory");
825 
826           evtimer_set(&ictx->timer, input_timer_callback, ictx);
827 
828           input_reset(ictx, 0);
829           return (ictx);
830 }
831 
832 /* Destroy input parser. */
833 void
input_free(struct input_ctx * ictx)834 input_free(struct input_ctx *ictx)
835 {
836           u_int     i;
837 
838           for (i = 0; i < ictx->param_list_len; i++) {
839                     if (ictx->param_list[i].type == INPUT_STRING)
840                               free(ictx->param_list[i].str);
841           }
842 
843           event_del(&ictx->timer);
844 
845           free(ictx->input_buf);
846           evbuffer_free(ictx->since_ground);
847 
848           free(ictx);
849 }
850 
851 /* Reset input state and clear screen. */
852 void
input_reset(struct input_ctx * ictx,int clear)853 input_reset(struct input_ctx *ictx, int clear)
854 {
855           struct screen_write_ctx       *sctx = &ictx->ctx;
856           struct window_pane  *wp = ictx->wp;
857 
858           input_reset_cell(ictx);
859 
860           if (clear && wp != NULL) {
861                     if (TAILQ_EMPTY(&wp->modes))
862                               screen_write_start_pane(sctx, wp, &wp->base);
863                     else
864                               screen_write_start(sctx, &wp->base);
865                     screen_write_reset(sctx);
866                     screen_write_stop(sctx);
867           }
868 
869           input_clear(ictx);
870 
871           ictx->state = &input_state_ground;
872           ictx->flags = 0;
873 }
874 
875 /* Return pending data. */
876 struct evbuffer *
input_pending(struct input_ctx * ictx)877 input_pending(struct input_ctx *ictx)
878 {
879           return (ictx->since_ground);
880 }
881 
882 /* Change input state. */
883 static void
input_set_state(struct input_ctx * ictx,const struct input_transition * itr)884 input_set_state(struct input_ctx *ictx, const struct input_transition *itr)
885 {
886           if (ictx->state->exit != NULL)
887                     ictx->state->exit(ictx);
888           ictx->state = itr->state;
889           if (ictx->state->enter != NULL)
890                     ictx->state->enter(ictx);
891 }
892 
893 /* Parse data. */
894 static void
input_parse(struct input_ctx * ictx,u_char * buf,size_t len)895 input_parse(struct input_ctx *ictx, u_char *buf, size_t len)
896 {
897           struct screen_write_ctx                 *sctx = &ictx->ctx;
898           const struct input_state      *state = NULL;
899           const struct input_transition *itr = NULL;
900           size_t                                   off = 0;
901 
902           /* Parse the input. */
903           while (off < len) {
904                     ictx->ch = buf[off++];
905 
906                     /* Find the transition. */
907                     if (ictx->state != state ||
908                         itr == NULL ||
909                         ictx->ch < itr->first ||
910                         ictx->ch > itr->last) {
911                               itr = ictx->state->transitions;
912                               while (itr->first != -1 && itr->last != -1) {
913                                         if (ictx->ch >= itr->first &&
914                                             ictx->ch <= itr->last)
915                                                   break;
916                                         itr++;
917                               }
918                               if (itr->first == -1 || itr->last == -1) {
919                                         /* No transition? Eh? */
920                                         fatalx("no transition from state");
921                               }
922                     }
923                     state = ictx->state;
924 
925                     /*
926                      * Any state except print stops the current collection. This is
927                      * an optimization to avoid checking if the attributes have
928                      * changed for every character. It will stop unnecessarily for
929                      * sequences that don't make a terminal change, but they should
930                      * be the minority.
931                      */
932                     if (itr->handler != input_print)
933                               screen_write_collect_end(sctx);
934 
935                     /*
936                      * Execute the handler, if any. Don't switch state if it
937                      * returns non-zero.
938                      */
939                     if (itr->handler != NULL && itr->handler(ictx) != 0)
940                               continue;
941 
942                     /* And switch state, if necessary. */
943                     if (itr->state != NULL)
944                               input_set_state(ictx, itr);
945 
946                     /* If not in ground state, save input. */
947                     if (ictx->state != &input_state_ground)
948                               evbuffer_add(ictx->since_ground, &ictx->ch, 1);
949           }
950 }
951 
952 /* Parse input from pane. */
953 void
input_parse_pane(struct window_pane * wp)954 input_parse_pane(struct window_pane *wp)
955 {
956           void      *new_data;
957           size_t     new_size;
958 
959           new_data = window_pane_get_new_data(wp, &wp->offset, &new_size);
960           input_parse_buffer(wp, new_data, new_size);
961           window_pane_update_used_data(wp, &wp->offset, new_size);
962 }
963 
964 /* Parse given input. */
965 void
input_parse_buffer(struct window_pane * wp,u_char * buf,size_t len)966 input_parse_buffer(struct window_pane *wp, u_char *buf, size_t len)
967 {
968           struct input_ctx    *ictx = wp->ictx;
969           struct screen_write_ctx       *sctx = &ictx->ctx;
970 
971           if (len == 0)
972                     return;
973 
974           window_update_activity(wp->window);
975           wp->flags |= PANE_CHANGED;
976 
977           /* Flag new input while in a mode. */
978           if (!TAILQ_EMPTY(&wp->modes))
979                     wp->flags |= PANE_UNSEENCHANGES;
980 
981           /* NULL wp if there is a mode set as don't want to update the tty. */
982           if (TAILQ_EMPTY(&wp->modes))
983                     screen_write_start_pane(sctx, wp, &wp->base);
984           else
985                     screen_write_start(sctx, &wp->base);
986 
987           log_debug("%s: %%%u %s, %zu bytes: %.*s", __func__, wp->id,
988               ictx->state->name, len, (int)len, buf);
989 
990           input_parse(ictx, buf, len);
991           screen_write_stop(sctx);
992 }
993 
994 /* Parse given input for screen. */
995 void
input_parse_screen(struct input_ctx * ictx,struct screen * s,screen_write_init_ctx_cb cb,void * arg,u_char * buf,size_t len)996 input_parse_screen(struct input_ctx *ictx, struct screen *s,
997     screen_write_init_ctx_cb cb, void *arg, u_char *buf, size_t len)
998 {
999           struct screen_write_ctx       *sctx = &ictx->ctx;
1000 
1001           if (len == 0)
1002                     return;
1003 
1004           screen_write_start_callback(sctx, s, cb, arg);
1005           input_parse(ictx, buf, len);
1006           screen_write_stop(sctx);
1007 }
1008 
1009 /* Split the parameter list (if any). */
1010 static int
input_split(struct input_ctx * ictx)1011 input_split(struct input_ctx *ictx)
1012 {
1013           const char                    *errstr;
1014           char                          *ptr, *out;
1015           struct input_param  *ip;
1016           u_int                          i;
1017 
1018           for (i = 0; i < ictx->param_list_len; i++) {
1019                     if (ictx->param_list[i].type == INPUT_STRING)
1020                               free(ictx->param_list[i].str);
1021           }
1022           ictx->param_list_len = 0;
1023 
1024           if (ictx->param_len == 0)
1025                     return (0);
1026           ip = &ictx->param_list[0];
1027 
1028           ptr = (char *)ictx->param_buf;
1029           while ((out = strsep(&ptr, ";")) != NULL) {
1030                     if (*out == '\0')
1031                               ip->type = INPUT_MISSING;
1032                     else {
1033                               if (strchr(out, ':') != NULL) {
1034                                         ip->type = INPUT_STRING;
1035                                         ip->str = xstrdup(out);
1036                               } else {
1037                                         ip->type = INPUT_NUMBER;
1038                                         ip->num = strtonum(out, 0, INT_MAX, &errstr);
1039                                         if (errstr != NULL)
1040                                                   return (-1);
1041                               }
1042                     }
1043                     ip = &ictx->param_list[++ictx->param_list_len];
1044                     if (ictx->param_list_len == nitems(ictx->param_list))
1045                               return (-1);
1046           }
1047 
1048           for (i = 0; i < ictx->param_list_len; i++) {
1049                     ip = &ictx->param_list[i];
1050                     if (ip->type == INPUT_MISSING)
1051                               log_debug("parameter %u: missing", i);
1052                     else if (ip->type == INPUT_STRING)
1053                               log_debug("parameter %u: string %s", i, ip->str);
1054                     else if (ip->type == INPUT_NUMBER)
1055                               log_debug("parameter %u: number %d", i, ip->num);
1056           }
1057 
1058           return (0);
1059 }
1060 
1061 /* Get an argument or return default value. */
1062 static int
input_get(struct input_ctx * ictx,u_int validx,int minval,int defval)1063 input_get(struct input_ctx *ictx, u_int validx, int minval, int defval)
1064 {
1065           struct input_param  *ip;
1066           int                            retval;
1067 
1068           if (validx >= ictx->param_list_len)
1069               return (defval);
1070           ip = &ictx->param_list[validx];
1071           if (ip->type == INPUT_MISSING)
1072                     return (defval);
1073           if (ip->type == INPUT_STRING)
1074                     return (-1);
1075           retval = ip->num;
1076           if (retval < minval)
1077                     return (minval);
1078           return (retval);
1079 }
1080 
1081 /* Reply to terminal query. */
1082 static void
input_reply(struct input_ctx * ictx,const char * fmt,...)1083 input_reply(struct input_ctx *ictx, const char *fmt, ...)
1084 {
1085           struct bufferevent  *bev = ictx->event;
1086           va_list                        ap;
1087           char                          *reply;
1088 
1089           if (bev == NULL)
1090                     return;
1091 
1092           va_start(ap, fmt);
1093           xvasprintf(&reply, fmt, ap);
1094           va_end(ap);
1095 
1096           log_debug("%s: %s", __func__, reply);
1097           bufferevent_write(bev, reply, strlen(reply));
1098           free(reply);
1099 }
1100 
1101 /* Clear saved state. */
1102 static void
input_clear(struct input_ctx * ictx)1103 input_clear(struct input_ctx *ictx)
1104 {
1105           event_del(&ictx->timer);
1106 
1107           *ictx->interm_buf = '\0';
1108           ictx->interm_len = 0;
1109 
1110           *ictx->param_buf = '\0';
1111           ictx->param_len = 0;
1112 
1113           *ictx->input_buf = '\0';
1114           ictx->input_len = 0;
1115 
1116           ictx->input_end = INPUT_END_ST;
1117 
1118           ictx->flags &= ~INPUT_DISCARD;
1119 }
1120 
1121 /* Reset for ground state. */
1122 static void
input_ground(struct input_ctx * ictx)1123 input_ground(struct input_ctx *ictx)
1124 {
1125           event_del(&ictx->timer);
1126           evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground));
1127 
1128           if (ictx->input_space > INPUT_BUF_START) {
1129                     ictx->input_space = INPUT_BUF_START;
1130                     ictx->input_buf = xrealloc(ictx->input_buf, INPUT_BUF_START);
1131           }
1132 }
1133 
1134 /* Output this character to the screen. */
1135 static int
input_print(struct input_ctx * ictx)1136 input_print(struct input_ctx *ictx)
1137 {
1138           struct screen_write_ctx       *sctx = &ictx->ctx;
1139           int                            set;
1140 
1141           ictx->utf8started = 0; /* can't be valid UTF-8 */
1142 
1143           set = ictx->cell.set == 0 ? ictx->cell.g0set : ictx->cell.g1set;
1144           if (set == 1)
1145                     ictx->cell.cell.attr |= GRID_ATTR_CHARSET;
1146           else
1147                     ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
1148 
1149           utf8_set(&ictx->cell.cell.data, ictx->ch);
1150           screen_write_collect_add(sctx, &ictx->cell.cell);
1151 
1152           utf8_copy(&ictx->last, &ictx->cell.cell.data);
1153           ictx->flags |= INPUT_LAST;
1154 
1155           ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
1156 
1157           return (0);
1158 }
1159 
1160 /* Collect intermediate string. */
1161 static int
input_intermediate(struct input_ctx * ictx)1162 input_intermediate(struct input_ctx *ictx)
1163 {
1164           if (ictx->interm_len == (sizeof ictx->interm_buf) - 1)
1165                     ictx->flags |= INPUT_DISCARD;
1166           else {
1167                     ictx->interm_buf[ictx->interm_len++] = ictx->ch;
1168                     ictx->interm_buf[ictx->interm_len] = '\0';
1169           }
1170 
1171           return (0);
1172 }
1173 
1174 /* Collect parameter string. */
1175 static int
input_parameter(struct input_ctx * ictx)1176 input_parameter(struct input_ctx *ictx)
1177 {
1178           if (ictx->param_len == (sizeof ictx->param_buf) - 1)
1179                     ictx->flags |= INPUT_DISCARD;
1180           else {
1181                     ictx->param_buf[ictx->param_len++] = ictx->ch;
1182                     ictx->param_buf[ictx->param_len] = '\0';
1183           }
1184 
1185           return (0);
1186 }
1187 
1188 /* Collect input string. */
1189 static int
input_input(struct input_ctx * ictx)1190 input_input(struct input_ctx *ictx)
1191 {
1192           size_t available;
1193 
1194           available = ictx->input_space;
1195           while (ictx->input_len + 1 >= available) {
1196                     available *= 2;
1197                     if (available > INPUT_BUF_LIMIT) {
1198                               ictx->flags |= INPUT_DISCARD;
1199                               return (0);
1200                     }
1201                     ictx->input_buf = xrealloc(ictx->input_buf, available);
1202                     ictx->input_space = available;
1203           }
1204           ictx->input_buf[ictx->input_len++] = ictx->ch;
1205           ictx->input_buf[ictx->input_len] = '\0';
1206 
1207           return (0);
1208 }
1209 
1210 /* Execute C0 control sequence. */
1211 static int
input_c0_dispatch(struct input_ctx * ictx)1212 input_c0_dispatch(struct input_ctx *ictx)
1213 {
1214           struct screen_write_ctx       *sctx = &ictx->ctx;
1215           struct window_pane  *wp = ictx->wp;
1216           struct screen                 *s = sctx->s;
1217 
1218           ictx->utf8started = 0; /* can't be valid UTF-8 */
1219 
1220           log_debug("%s: '%c'", __func__, ictx->ch);
1221 
1222           switch (ictx->ch) {
1223           case '\000':        /* NUL */
1224                     break;
1225           case '\007':        /* BEL */
1226                     if (wp != NULL)
1227                               alerts_queue(wp->window, WINDOW_BELL);
1228                     break;
1229           case '\010':        /* BS */
1230                     screen_write_backspace(sctx);
1231                     break;
1232           case '\011':        /* HT */
1233                     /* Don't tab beyond the end of the line. */
1234                     if (s->cx >= screen_size_x(s) - 1)
1235                               break;
1236 
1237                     /* Find the next tab point, or use the last column if none. */
1238                     do {
1239                               s->cx++;
1240                               if (bit_test(s->tabs, s->cx))
1241                                         break;
1242                     } while (s->cx < screen_size_x(s) - 1);
1243                     break;
1244           case '\012':        /* LF */
1245           case '\013':        /* VT */
1246           case '\014':        /* FF */
1247                     screen_write_linefeed(sctx, 0, ictx->cell.cell.bg);
1248                     if (s->mode & MODE_CRLF)
1249                               screen_write_carriagereturn(sctx);
1250                     break;
1251           case '\015':        /* CR */
1252                     screen_write_carriagereturn(sctx);
1253                     break;
1254           case '\016':        /* SO */
1255                     ictx->cell.set = 1;
1256                     break;
1257           case '\017':        /* SI */
1258                     ictx->cell.set = 0;
1259                     break;
1260           default:
1261                     log_debug("%s: unknown '%c'", __func__, ictx->ch);
1262                     break;
1263           }
1264 
1265           ictx->flags &= ~INPUT_LAST;
1266           return (0);
1267 }
1268 
1269 /* Execute escape sequence. */
1270 static int
input_esc_dispatch(struct input_ctx * ictx)1271 input_esc_dispatch(struct input_ctx *ictx)
1272 {
1273           struct screen_write_ctx                 *sctx = &ictx->ctx;
1274           struct screen                           *s = sctx->s;
1275           struct input_table_entry      *entry;
1276 
1277           if (ictx->flags & INPUT_DISCARD)
1278                     return (0);
1279           log_debug("%s: '%c', %s", __func__, ictx->ch, ictx->interm_buf);
1280 
1281           entry = bsearch(ictx, input_esc_table, nitems(input_esc_table),
1282               sizeof input_esc_table[0], input_table_compare);
1283           if (entry == NULL) {
1284                     log_debug("%s: unknown '%c'", __func__, ictx->ch);
1285                     return (0);
1286           }
1287 
1288           switch (entry->type) {
1289           case INPUT_ESC_RIS:
1290                     colour_palette_clear(ictx->palette);
1291                     input_reset_cell(ictx);
1292                     screen_write_reset(sctx);
1293                     screen_write_fullredraw(sctx);
1294                     break;
1295           case INPUT_ESC_IND:
1296                     screen_write_linefeed(sctx, 0, ictx->cell.cell.bg);
1297                     break;
1298           case INPUT_ESC_NEL:
1299                     screen_write_carriagereturn(sctx);
1300                     screen_write_linefeed(sctx, 0, ictx->cell.cell.bg);
1301                     break;
1302           case INPUT_ESC_HTS:
1303                     if (s->cx < screen_size_x(s))
1304                               bit_set(s->tabs, s->cx);
1305                     break;
1306           case INPUT_ESC_RI:
1307                     screen_write_reverseindex(sctx, ictx->cell.cell.bg);
1308                     break;
1309           case INPUT_ESC_DECKPAM:
1310                     screen_write_mode_set(sctx, MODE_KKEYPAD);
1311                     break;
1312           case INPUT_ESC_DECKPNM:
1313                     screen_write_mode_clear(sctx, MODE_KKEYPAD);
1314                     break;
1315           case INPUT_ESC_DECSC:
1316                     input_save_state(ictx);
1317                     break;
1318           case INPUT_ESC_DECRC:
1319                     input_restore_state(ictx);
1320                     break;
1321           case INPUT_ESC_DECALN:
1322                     screen_write_alignmenttest(sctx);
1323                     break;
1324           case INPUT_ESC_SCSG0_ON:
1325                     ictx->cell.g0set = 1;
1326                     break;
1327           case INPUT_ESC_SCSG0_OFF:
1328                     ictx->cell.g0set = 0;
1329                     break;
1330           case INPUT_ESC_SCSG1_ON:
1331                     ictx->cell.g1set = 1;
1332                     break;
1333           case INPUT_ESC_SCSG1_OFF:
1334                     ictx->cell.g1set = 0;
1335                     break;
1336           case INPUT_ESC_ST:
1337                     /* ST terminates OSC but the state transition already did it. */
1338                     break;
1339           }
1340 
1341           ictx->flags &= ~INPUT_LAST;
1342           return (0);
1343 }
1344 
1345 /* Execute control sequence. */
1346 static int
input_csi_dispatch(struct input_ctx * ictx)1347 input_csi_dispatch(struct input_ctx *ictx)
1348 {
1349           struct screen_write_ctx              *sctx = &ictx->ctx;
1350           struct screen                        *s = sctx->s;
1351           struct input_table_entry       *entry;
1352           int                                     i, n, m, ek;
1353           u_int                                   cx, bg = ictx->cell.cell.bg;
1354 
1355           if (ictx->flags & INPUT_DISCARD)
1356                     return (0);
1357 
1358           log_debug("%s: '%c' \"%s\" \"%s\"", __func__, ictx->ch,
1359               ictx->interm_buf, ictx->param_buf);
1360 
1361           if (input_split(ictx) != 0)
1362                     return (0);
1363 
1364           entry = bsearch(ictx, input_csi_table, nitems(input_csi_table),
1365               sizeof input_csi_table[0], input_table_compare);
1366           if (entry == NULL) {
1367                     log_debug("%s: unknown '%c'", __func__, ictx->ch);
1368                     return (0);
1369           }
1370 
1371           switch (entry->type) {
1372           case INPUT_CSI_CBT:
1373                     /* Find the previous tab point, n times. */
1374                     cx = s->cx;
1375                     if (cx > screen_size_x(s) - 1)
1376                               cx = screen_size_x(s) - 1;
1377                     n = input_get(ictx, 0, 1, 1);
1378                     if (n == -1)
1379                               break;
1380                     while (cx > 0 && n-- > 0) {
1381                               do
1382                                         cx--;
1383                               while (cx > 0 && !bit_test(s->tabs, cx));
1384                     }
1385                     s->cx = cx;
1386                     break;
1387           case INPUT_CSI_CUB:
1388                     n = input_get(ictx, 0, 1, 1);
1389                     if (n != -1)
1390                               screen_write_cursorleft(sctx, n);
1391                     break;
1392           case INPUT_CSI_CUD:
1393                     n = input_get(ictx, 0, 1, 1);
1394                     if (n != -1)
1395                               screen_write_cursordown(sctx, n);
1396                     break;
1397           case INPUT_CSI_CUF:
1398                     n = input_get(ictx, 0, 1, 1);
1399                     if (n != -1)
1400                               screen_write_cursorright(sctx, n);
1401                     break;
1402           case INPUT_CSI_CUP:
1403                     n = input_get(ictx, 0, 1, 1);
1404                     m = input_get(ictx, 1, 1, 1);
1405                     if (n != -1 && m != -1)
1406                               screen_write_cursormove(sctx, m - 1, n - 1, 1);
1407                     break;
1408           case INPUT_CSI_MODSET:
1409                     n = input_get(ictx, 0, 0, 0);
1410                     if (n != 4)
1411                               break;
1412                     m = input_get(ictx, 1, 0, 0);
1413 
1414                     /*
1415                      * Set the extended key reporting mode as per the client
1416                      * request, unless "extended-keys" is set to "off".
1417                      */
1418                     ek = options_get_number(global_options, "extended-keys");
1419                     if (ek == 0)
1420                               break;
1421                     screen_write_mode_clear(sctx, EXTENDED_KEY_MODES);
1422                     if (m == 2)
1423                               screen_write_mode_set(sctx, MODE_KEYS_EXTENDED_2);
1424                     else if (m == 1 || ek == 2)
1425                               screen_write_mode_set(sctx, MODE_KEYS_EXTENDED);
1426                     break;
1427           case INPUT_CSI_MODOFF:
1428                     n = input_get(ictx, 0, 0, 0);
1429                     if (n != 4)
1430                               break;
1431 
1432                     /*
1433                      * Clear the extended key reporting mode as per the client
1434                      * request, unless "extended-keys always" forces into mode 1.
1435                      */
1436                     screen_write_mode_clear(sctx,
1437                         MODE_KEYS_EXTENDED|MODE_KEYS_EXTENDED_2);
1438                     if (options_get_number(global_options, "extended-keys") == 2)
1439                               screen_write_mode_set(sctx, MODE_KEYS_EXTENDED);
1440                     break;
1441           case INPUT_CSI_WINOPS:
1442                     input_csi_dispatch_winops(ictx);
1443                     break;
1444           case INPUT_CSI_CUU:
1445                     n = input_get(ictx, 0, 1, 1);
1446                     if (n != -1)
1447                               screen_write_cursorup(sctx, n);
1448                     break;
1449           case INPUT_CSI_CNL:
1450                     n = input_get(ictx, 0, 1, 1);
1451                     if (n != -1) {
1452                               screen_write_carriagereturn(sctx);
1453                               screen_write_cursordown(sctx, n);
1454                     }
1455                     break;
1456           case INPUT_CSI_CPL:
1457                     n = input_get(ictx, 0, 1, 1);
1458                     if (n != -1) {
1459                               screen_write_carriagereturn(sctx);
1460                               screen_write_cursorup(sctx, n);
1461                     }
1462                     break;
1463           case INPUT_CSI_DA:
1464                     switch (input_get(ictx, 0, 0, 0)) {
1465                     case -1:
1466                               break;
1467                     case 0:
1468 #ifdef ENABLE_SIXEL
1469                               input_reply(ictx, "\033[?1;2;4c");
1470 #else
1471                               input_reply(ictx, "\033[?1;2c");
1472 #endif
1473                               break;
1474                     default:
1475                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1476                               break;
1477                     }
1478                     break;
1479           case INPUT_CSI_DA_TWO:
1480                     switch (input_get(ictx, 0, 0, 0)) {
1481                     case -1:
1482                               break;
1483                     case 0:
1484                               input_reply(ictx, "\033[>84;0;0c");
1485                               break;
1486                     default:
1487                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1488                               break;
1489                     }
1490                     break;
1491           case INPUT_CSI_ECH:
1492                     n = input_get(ictx, 0, 1, 1);
1493                     if (n != -1)
1494                               screen_write_clearcharacter(sctx, n, bg);
1495                     break;
1496           case INPUT_CSI_DCH:
1497                     n = input_get(ictx, 0, 1, 1);
1498                     if (n != -1)
1499                               screen_write_deletecharacter(sctx, n, bg);
1500                     break;
1501           case INPUT_CSI_DECSTBM:
1502                     n = input_get(ictx, 0, 1, 1);
1503                     m = input_get(ictx, 1, 1, screen_size_y(s));
1504                     if (n != -1 && m != -1)
1505                               screen_write_scrollregion(sctx, n - 1, m - 1);
1506                     break;
1507           case INPUT_CSI_DL:
1508                     n = input_get(ictx, 0, 1, 1);
1509                     if (n != -1)
1510                               screen_write_deleteline(sctx, n, bg);
1511                     break;
1512           case INPUT_CSI_DSR:
1513                     switch (input_get(ictx, 0, 0, 0)) {
1514                     case -1:
1515                               break;
1516                     case 5:
1517                               input_reply(ictx, "\033[0n");
1518                               break;
1519                     case 6:
1520                               input_reply(ictx, "\033[%u;%uR", s->cy + 1, s->cx + 1);
1521                               break;
1522                     default:
1523                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1524                               break;
1525                     }
1526                     break;
1527           case INPUT_CSI_ED:
1528                     switch (input_get(ictx, 0, 0, 0)) {
1529                     case -1:
1530                               break;
1531                     case 0:
1532                               screen_write_clearendofscreen(sctx, bg);
1533                               break;
1534                     case 1:
1535                               screen_write_clearstartofscreen(sctx, bg);
1536                               break;
1537                     case 2:
1538                               screen_write_clearscreen(sctx, bg);
1539                               break;
1540                     case 3:
1541                               if (input_get(ictx, 1, 0, 0) == 0) {
1542                                         /*
1543                                          * Linux console extension to clear history
1544                                          * (for example before locking the screen).
1545                                          */
1546                                         screen_write_clearhistory(sctx);
1547                               }
1548                               break;
1549                     default:
1550                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1551                               break;
1552                     }
1553                     break;
1554           case INPUT_CSI_EL:
1555                     switch (input_get(ictx, 0, 0, 0)) {
1556                     case -1:
1557                               break;
1558                     case 0:
1559                               screen_write_clearendofline(sctx, bg);
1560                               break;
1561                     case 1:
1562                               screen_write_clearstartofline(sctx, bg);
1563                               break;
1564                     case 2:
1565                               screen_write_clearline(sctx, bg);
1566                               break;
1567                     default:
1568                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1569                               break;
1570                     }
1571                     break;
1572           case INPUT_CSI_HPA:
1573                     n = input_get(ictx, 0, 1, 1);
1574                     if (n != -1)
1575                               screen_write_cursormove(sctx, n - 1, -1, 1);
1576                     break;
1577           case INPUT_CSI_ICH:
1578                     n = input_get(ictx, 0, 1, 1);
1579                     if (n != -1)
1580                               screen_write_insertcharacter(sctx, n, bg);
1581                     break;
1582           case INPUT_CSI_IL:
1583                     n = input_get(ictx, 0, 1, 1);
1584                     if (n != -1)
1585                               screen_write_insertline(sctx, n, bg);
1586                     break;
1587           case INPUT_CSI_REP:
1588                     n = input_get(ictx, 0, 1, 1);
1589                     if (n == -1)
1590                               break;
1591 
1592                     m = screen_size_x(s) - s->cx;
1593                     if (n > m)
1594                               n = m;
1595 
1596                     if (~ictx->flags & INPUT_LAST)
1597                               break;
1598 
1599                     utf8_copy(&ictx->cell.cell.data, &ictx->last);
1600                     for (i = 0; i < n; i++)
1601                               screen_write_collect_add(sctx, &ictx->cell.cell);
1602                     break;
1603           case INPUT_CSI_RCP:
1604                     input_restore_state(ictx);
1605                     break;
1606           case INPUT_CSI_RM:
1607                     input_csi_dispatch_rm(ictx);
1608                     break;
1609           case INPUT_CSI_RM_PRIVATE:
1610                     input_csi_dispatch_rm_private(ictx);
1611                     break;
1612           case INPUT_CSI_SCP:
1613                     input_save_state(ictx);
1614                     break;
1615           case INPUT_CSI_SGR:
1616                     input_csi_dispatch_sgr(ictx);
1617                     break;
1618           case INPUT_CSI_SM:
1619                     input_csi_dispatch_sm(ictx);
1620                     break;
1621           case INPUT_CSI_SM_PRIVATE:
1622                     input_csi_dispatch_sm_private(ictx);
1623                     break;
1624           case INPUT_CSI_SM_GRAPHICS:
1625                     input_csi_dispatch_sm_graphics(ictx);
1626                     break;
1627           case INPUT_CSI_SU:
1628                     n = input_get(ictx, 0, 1, 1);
1629                     if (n != -1)
1630                               screen_write_scrollup(sctx, n, bg);
1631                     break;
1632           case INPUT_CSI_SD:
1633                     n = input_get(ictx, 0, 1, 1);
1634                     if (n != -1)
1635                               screen_write_scrolldown(sctx, n, bg);
1636                     break;
1637           case INPUT_CSI_TBC:
1638                     switch (input_get(ictx, 0, 0, 0)) {
1639                     case -1:
1640                               break;
1641                     case 0:
1642                               if (s->cx < screen_size_x(s))
1643                                         bit_clear(s->tabs, s->cx);
1644                               break;
1645                     case 3:
1646                               bit_nclear(s->tabs, 0, screen_size_x(s) - 1);
1647                               break;
1648                     default:
1649                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1650                               break;
1651                     }
1652                     break;
1653           case INPUT_CSI_VPA:
1654                     n = input_get(ictx, 0, 1, 1);
1655                     if (n != -1)
1656                               screen_write_cursormove(sctx, -1, n - 1, 1);
1657                     break;
1658           case INPUT_CSI_DECSCUSR:
1659                     n = input_get(ictx, 0, 0, 0);
1660                     if (n != -1)
1661                               screen_set_cursor_style(n, &s->cstyle, &s->mode);
1662                     break;
1663           case INPUT_CSI_XDA:
1664                     n = input_get(ictx, 0, 0, 0);
1665                     if (n == 0)
1666                               input_reply(ictx, "\033P>|tmux %s\033\\", getversion());
1667                     break;
1668 
1669           }
1670 
1671           ictx->flags &= ~INPUT_LAST;
1672           return (0);
1673 }
1674 
1675 /* Handle CSI RM. */
1676 static void
input_csi_dispatch_rm(struct input_ctx * ictx)1677 input_csi_dispatch_rm(struct input_ctx *ictx)
1678 {
1679           struct screen_write_ctx       *sctx = &ictx->ctx;
1680           u_int                          i;
1681 
1682           for (i = 0; i < ictx->param_list_len; i++) {
1683                     switch (input_get(ictx, i, 0, -1)) {
1684                     case -1:
1685                               break;
1686                     case 4:             /* IRM */
1687                               screen_write_mode_clear(sctx, MODE_INSERT);
1688                               break;
1689                     case 34:
1690                               screen_write_mode_set(sctx, MODE_CURSOR_VERY_VISIBLE);
1691                               break;
1692                     default:
1693                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1694                               break;
1695                     }
1696           }
1697 }
1698 
1699 /* Handle CSI private RM. */
1700 static void
input_csi_dispatch_rm_private(struct input_ctx * ictx)1701 input_csi_dispatch_rm_private(struct input_ctx *ictx)
1702 {
1703           struct screen_write_ctx       *sctx = &ictx->ctx;
1704           struct grid_cell    *gc = &ictx->cell.cell;
1705           u_int                          i;
1706 
1707           for (i = 0; i < ictx->param_list_len; i++) {
1708                     switch (input_get(ictx, i, 0, -1)) {
1709                     case -1:
1710                               break;
1711                     case 1:             /* DECCKM */
1712                               screen_write_mode_clear(sctx, MODE_KCURSOR);
1713                               break;
1714                     case 3:             /* DECCOLM */
1715                               screen_write_cursormove(sctx, 0, 0, 1);
1716                               screen_write_clearscreen(sctx, gc->bg);
1717                               break;
1718                     case 6:             /* DECOM */
1719                               screen_write_mode_clear(sctx, MODE_ORIGIN);
1720                               screen_write_cursormove(sctx, 0, 0, 1);
1721                               break;
1722                     case 7:             /* DECAWM */
1723                               screen_write_mode_clear(sctx, MODE_WRAP);
1724                               break;
1725                     case 12:
1726                               screen_write_mode_clear(sctx, MODE_CURSOR_BLINKING);
1727                               screen_write_mode_set(sctx, MODE_CURSOR_BLINKING_SET);
1728                               break;
1729                     case 25:  /* TCEM */
1730                               screen_write_mode_clear(sctx, MODE_CURSOR);
1731                               break;
1732                     case 1000:
1733                     case 1001:
1734                     case 1002:
1735                     case 1003:
1736                               screen_write_mode_clear(sctx, ALL_MOUSE_MODES);
1737                               break;
1738                     case 1004:
1739                               screen_write_mode_clear(sctx, MODE_FOCUSON);
1740                               break;
1741                     case 1005:
1742                               screen_write_mode_clear(sctx, MODE_MOUSE_UTF8);
1743                               break;
1744                     case 1006:
1745                               screen_write_mode_clear(sctx, MODE_MOUSE_SGR);
1746                               break;
1747                     case 47:
1748                     case 1047:
1749                               screen_write_alternateoff(sctx, gc, 0);
1750                               break;
1751                     case 1049:
1752                               screen_write_alternateoff(sctx, gc, 1);
1753                               break;
1754                     case 2004:
1755                               screen_write_mode_clear(sctx, MODE_BRACKETPASTE);
1756                               break;
1757                     default:
1758                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1759                               break;
1760                     }
1761           }
1762 }
1763 
1764 /* Handle CSI SM. */
1765 static void
input_csi_dispatch_sm(struct input_ctx * ictx)1766 input_csi_dispatch_sm(struct input_ctx *ictx)
1767 {
1768           struct screen_write_ctx       *sctx = &ictx->ctx;
1769           u_int                          i;
1770 
1771           for (i = 0; i < ictx->param_list_len; i++) {
1772                     switch (input_get(ictx, i, 0, -1)) {
1773                     case -1:
1774                               break;
1775                     case 4:             /* IRM */
1776                               screen_write_mode_set(sctx, MODE_INSERT);
1777                               break;
1778                     case 34:
1779                               screen_write_mode_clear(sctx, MODE_CURSOR_VERY_VISIBLE);
1780                               break;
1781                     default:
1782                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1783                               break;
1784                     }
1785           }
1786 }
1787 
1788 /* Handle CSI private SM. */
1789 static void
input_csi_dispatch_sm_private(struct input_ctx * ictx)1790 input_csi_dispatch_sm_private(struct input_ctx *ictx)
1791 {
1792           struct screen_write_ctx       *sctx = &ictx->ctx;
1793           struct grid_cell    *gc = &ictx->cell.cell;
1794           u_int                          i;
1795 
1796           for (i = 0; i < ictx->param_list_len; i++) {
1797                     switch (input_get(ictx, i, 0, -1)) {
1798                     case -1:
1799                               break;
1800                     case 1:             /* DECCKM */
1801                               screen_write_mode_set(sctx, MODE_KCURSOR);
1802                               break;
1803                     case 3:             /* DECCOLM */
1804                               screen_write_cursormove(sctx, 0, 0, 1);
1805                               screen_write_clearscreen(sctx, ictx->cell.cell.bg);
1806                               break;
1807                     case 6:             /* DECOM */
1808                               screen_write_mode_set(sctx, MODE_ORIGIN);
1809                               screen_write_cursormove(sctx, 0, 0, 1);
1810                               break;
1811                     case 7:             /* DECAWM */
1812                               screen_write_mode_set(sctx, MODE_WRAP);
1813                               break;
1814                     case 12:
1815                               screen_write_mode_set(sctx, MODE_CURSOR_BLINKING);
1816                               screen_write_mode_set(sctx, MODE_CURSOR_BLINKING_SET);
1817                               break;
1818                     case 25:  /* TCEM */
1819                               screen_write_mode_set(sctx, MODE_CURSOR);
1820                               break;
1821                     case 1000:
1822                               screen_write_mode_clear(sctx, ALL_MOUSE_MODES);
1823                               screen_write_mode_set(sctx, MODE_MOUSE_STANDARD);
1824                               break;
1825                     case 1002:
1826                               screen_write_mode_clear(sctx, ALL_MOUSE_MODES);
1827                               screen_write_mode_set(sctx, MODE_MOUSE_BUTTON);
1828                               break;
1829                     case 1003:
1830                               screen_write_mode_clear(sctx, ALL_MOUSE_MODES);
1831                               screen_write_mode_set(sctx, MODE_MOUSE_ALL);
1832                               break;
1833                     case 1004:
1834                               screen_write_mode_set(sctx, MODE_FOCUSON);
1835                               break;
1836                     case 1005:
1837                               screen_write_mode_set(sctx, MODE_MOUSE_UTF8);
1838                               break;
1839                     case 1006:
1840                               screen_write_mode_set(sctx, MODE_MOUSE_SGR);
1841                               break;
1842                     case 47:
1843                     case 1047:
1844                               screen_write_alternateon(sctx, gc, 0);
1845                               break;
1846                     case 1049:
1847                               screen_write_alternateon(sctx, gc, 1);
1848                               break;
1849                     case 2004:
1850                               screen_write_mode_set(sctx, MODE_BRACKETPASTE);
1851                               break;
1852                     default:
1853                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1854                               break;
1855                     }
1856           }
1857 }
1858 
1859 /* Handle CSI graphics SM. */
1860 static void
input_csi_dispatch_sm_graphics(__unused struct input_ctx * ictx)1861 input_csi_dispatch_sm_graphics(__unused struct input_ctx *ictx)
1862 {
1863 #ifdef ENABLE_SIXEL
1864           int       n, m, o;
1865 
1866           if (ictx->param_list_len > 3)
1867                     return;
1868           n = input_get(ictx, 0, 0, 0);
1869           m = input_get(ictx, 1, 0, 0);
1870           o = input_get(ictx, 2, 0, 0);
1871 
1872           if (n == 1 && (m == 1 || m == 2 || m == 4))
1873                     input_reply(ictx, "\033[?%d;0;%uS", n, SIXEL_COLOUR_REGISTERS);
1874           else
1875                     input_reply(ictx, "\033[?%d;3;%dS", n, o);
1876 #endif
1877 }
1878 
1879 /* Handle CSI window operations. */
1880 static void
input_csi_dispatch_winops(struct input_ctx * ictx)1881 input_csi_dispatch_winops(struct input_ctx *ictx)
1882 {
1883           struct screen_write_ctx       *sctx = &ictx->ctx;
1884           struct screen                 *s = sctx->s;
1885           struct window_pane  *wp = ictx->wp;
1886           struct window                 *w = NULL;
1887           u_int                          x = screen_size_x(s), y = screen_size_y(s);
1888           int                            n, m;
1889 
1890           if (wp != NULL)
1891                     w = wp->window;
1892 
1893           m = 0;
1894           while ((n = input_get(ictx, m, 0, -1)) != -1) {
1895                     switch (n) {
1896                     case 1:
1897                     case 2:
1898                     case 5:
1899                     case 6:
1900                     case 7:
1901                     case 11:
1902                     case 13:
1903                     case 20:
1904                     case 21:
1905                     case 24:
1906                               break;
1907                     case 3:
1908                     case 4:
1909                     case 8:
1910                               m++;
1911                               if (input_get(ictx, m, 0, -1) == -1)
1912                                         return;
1913                               /* FALLTHROUGH */
1914                     case 9:
1915                     case 10:
1916                               m++;
1917                               if (input_get(ictx, m, 0, -1) == -1)
1918                                         return;
1919                               break;
1920                     case 14:
1921                               if (w == NULL)
1922                                         break;
1923                               input_reply(ictx, "\033[4;%u;%ut", y * w->ypixel,
1924                                   x * w->xpixel);
1925                               break;
1926                     case 15:
1927                               if (w == NULL)
1928                                         break;
1929                               input_reply(ictx, "\033[5;%u;%ut", y * w->ypixel,
1930                                   x * w->xpixel);
1931                               break;
1932                     case 16:
1933                               if (w == NULL)
1934                                         break;
1935                               input_reply(ictx, "\033[6;%u;%ut", w->ypixel,
1936                                   w->xpixel);
1937                               break;
1938                     case 18:
1939                               input_reply(ictx, "\033[8;%u;%ut", y, x);
1940                               break;
1941                     case 19:
1942                               input_reply(ictx, "\033[9;%u;%ut", y, x);
1943                               break;
1944                     case 22:
1945                               m++;
1946                               switch (input_get(ictx, m, 0, -1)) {
1947                               case -1:
1948                                         return;
1949                               case 0:
1950                               case 2:
1951                                         screen_push_title(sctx->s);
1952                                         break;
1953                               }
1954                               break;
1955                     case 23:
1956                               m++;
1957                               switch (input_get(ictx, m, 0, -1)) {
1958                               case -1:
1959                                         return;
1960                               case 0:
1961                               case 2:
1962                                         screen_pop_title(sctx->s);
1963                                         if (wp == NULL)
1964                                                   break;
1965                                         notify_pane("pane-title-changed", wp);
1966                                         server_redraw_window_borders(w);
1967                                         server_status_window(w);
1968                                         break;
1969                               }
1970                               break;
1971                     default:
1972                               log_debug("%s: unknown '%c'", __func__, ictx->ch);
1973                               break;
1974                     }
1975                     m++;
1976           }
1977 }
1978 
1979 /* Helper for 256 colour SGR. */
1980 static int
input_csi_dispatch_sgr_256_do(struct input_ctx * ictx,int fgbg,int c)1981 input_csi_dispatch_sgr_256_do(struct input_ctx *ictx, int fgbg, int c)
1982 {
1983           struct grid_cell    *gc = &ictx->cell.cell;
1984 
1985           if (c == -1 || c > 255) {
1986                     if (fgbg == 38)
1987                               gc->fg = 8;
1988                     else if (fgbg == 48)
1989                               gc->bg = 8;
1990           } else {
1991                     if (fgbg == 38)
1992                               gc->fg = c | COLOUR_FLAG_256;
1993                     else if (fgbg == 48)
1994                               gc->bg = c | COLOUR_FLAG_256;
1995                     else if (fgbg == 58)
1996                               gc->us = c | COLOUR_FLAG_256;
1997           }
1998           return (1);
1999 }
2000 
2001 /* Handle CSI SGR for 256 colours. */
2002 static void
input_csi_dispatch_sgr_256(struct input_ctx * ictx,int fgbg,u_int * i)2003 input_csi_dispatch_sgr_256(struct input_ctx *ictx, int fgbg, u_int *i)
2004 {
2005           int       c;
2006 
2007           c = input_get(ictx, (*i) + 1, 0, -1);
2008           if (input_csi_dispatch_sgr_256_do(ictx, fgbg, c))
2009                     (*i)++;
2010 }
2011 
2012 /* Helper for RGB colour SGR. */
2013 static int
input_csi_dispatch_sgr_rgb_do(struct input_ctx * ictx,int fgbg,int r,int g,int b)2014 input_csi_dispatch_sgr_rgb_do(struct input_ctx *ictx, int fgbg, int r, int g,
2015     int b)
2016 {
2017           struct grid_cell    *gc = &ictx->cell.cell;
2018 
2019           if (r == -1 || r > 255)
2020                     return (0);
2021           if (g == -1 || g > 255)
2022                     return (0);
2023           if (b == -1 || b > 255)
2024                     return (0);
2025 
2026           if (fgbg == 38)
2027                     gc->fg = colour_join_rgb(r, g, b);
2028           else if (fgbg == 48)
2029                     gc->bg = colour_join_rgb(r, g, b);
2030           else if (fgbg == 58)
2031                     gc->us = colour_join_rgb(r, g, b);
2032           return (1);
2033 }
2034 
2035 /* Handle CSI SGR for RGB colours. */
2036 static void
input_csi_dispatch_sgr_rgb(struct input_ctx * ictx,int fgbg,u_int * i)2037 input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
2038 {
2039           int       r, g, b;
2040 
2041           r = input_get(ictx, (*i) + 1, 0, -1);
2042           g = input_get(ictx, (*i) + 2, 0, -1);
2043           b = input_get(ictx, (*i) + 3, 0, -1);
2044           if (input_csi_dispatch_sgr_rgb_do(ictx, fgbg, r, g, b))
2045                     (*i) += 3;
2046 }
2047 
2048 /* Handle CSI SGR with a ISO parameter. */
2049 static void
input_csi_dispatch_sgr_colon(struct input_ctx * ictx,u_int i)2050 input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i)
2051 {
2052           struct grid_cell    *gc = &ictx->cell.cell;
2053           char                          *s = ictx->param_list[i].str, *copy, *ptr, *out;
2054           int                            p[8];
2055           u_int                          n;
2056           const char                    *errstr;
2057 
2058           for (n = 0; n < nitems(p); n++)
2059                     p[n] = -1;
2060           n = 0;
2061 
2062           ptr = copy = xstrdup(s);
2063           while ((out = strsep(&ptr, ":")) != NULL) {
2064                     if (*out != '\0') {
2065                               p[n++] = strtonum(out, 0, INT_MAX, &errstr);
2066                               if (errstr != NULL || n == nitems(p)) {
2067                                         free(copy);
2068                                         return;
2069                               }
2070                     } else {
2071                               n++;
2072                               if (n == nitems(p)) {
2073                                         free(copy);
2074                                         return;
2075                               }
2076                     }
2077                     log_debug("%s: %u = %d", __func__, n - 1, p[n - 1]);
2078           }
2079           free(copy);
2080 
2081           if (n == 0)
2082                     return;
2083           if (p[0] == 4) {
2084                     if (n != 2)
2085                               return;
2086                     switch (p[1]) {
2087                     case 0:
2088                               gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
2089                               break;
2090                     case 1:
2091                               gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
2092                               gc->attr |= GRID_ATTR_UNDERSCORE;
2093                               break;
2094                     case 2:
2095                               gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
2096                               gc->attr |= GRID_ATTR_UNDERSCORE_2;
2097                               break;
2098                     case 3:
2099                               gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
2100                               gc->attr |= GRID_ATTR_UNDERSCORE_3;
2101                               break;
2102                     case 4:
2103                               gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
2104                               gc->attr |= GRID_ATTR_UNDERSCORE_4;
2105                               break;
2106                     case 5:
2107                               gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
2108                               gc->attr |= GRID_ATTR_UNDERSCORE_5;
2109                               break;
2110                     }
2111                     return;
2112           }
2113           if (n < 2 || (p[0] != 38 && p[0] != 48 && p[0] != 58))
2114                     return;
2115           switch (p[1]) {
2116           case 2:
2117                     if (n < 3)
2118                               break;
2119                     if (n == 5)
2120                               i = 2;
2121                     else
2122                               i = 3;
2123                     if (n < i + 3)
2124                               break;
2125                     input_csi_dispatch_sgr_rgb_do(ictx, p[0], p[i], p[i + 1],
2126                         p[i + 2]);
2127                     break;
2128           case 5:
2129                     if (n < 3)
2130                               break;
2131                     input_csi_dispatch_sgr_256_do(ictx, p[0], p[2]);
2132                     break;
2133           }
2134 }
2135 
2136 /* Handle CSI SGR. */
2137 static void
input_csi_dispatch_sgr(struct input_ctx * ictx)2138 input_csi_dispatch_sgr(struct input_ctx *ictx)
2139 {
2140           struct grid_cell    *gc = &ictx->cell.cell;
2141           u_int                          i, link;
2142           int                            n;
2143 
2144           if (ictx->param_list_len == 0) {
2145                     memcpy(gc, &grid_default_cell, sizeof *gc);
2146                     return;
2147           }
2148 
2149           for (i = 0; i < ictx->param_list_len; i++) {
2150                     if (ictx->param_list[i].type == INPUT_STRING) {
2151                               input_csi_dispatch_sgr_colon(ictx, i);
2152                               continue;
2153                     }
2154                     n = input_get(ictx, i, 0, 0);
2155                     if (n == -1)
2156                               continue;
2157 
2158                     if (n == 38 || n == 48 || n == 58) {
2159                               i++;
2160                               switch (input_get(ictx, i, 0, -1)) {
2161                               case 2:
2162                                         input_csi_dispatch_sgr_rgb(ictx, n, &i);
2163                                         break;
2164                               case 5:
2165                                         input_csi_dispatch_sgr_256(ictx, n, &i);
2166                                         break;
2167                               }
2168                               continue;
2169                     }
2170 
2171                     switch (n) {
2172                     case 0:
2173                               link = gc->link;
2174                               memcpy(gc, &grid_default_cell, sizeof *gc);
2175                               gc->link = link;
2176                               break;
2177                     case 1:
2178                               gc->attr |= GRID_ATTR_BRIGHT;
2179                               break;
2180                     case 2:
2181                               gc->attr |= GRID_ATTR_DIM;
2182                               break;
2183                     case 3:
2184                               gc->attr |= GRID_ATTR_ITALICS;
2185                               break;
2186                     case 4:
2187                               gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
2188                               gc->attr |= GRID_ATTR_UNDERSCORE;
2189                               break;
2190                     case 5:
2191                     case 6:
2192                               gc->attr |= GRID_ATTR_BLINK;
2193                               break;
2194                     case 7:
2195                               gc->attr |= GRID_ATTR_REVERSE;
2196                               break;
2197                     case 8:
2198                               gc->attr |= GRID_ATTR_HIDDEN;
2199                               break;
2200                     case 9:
2201                               gc->attr |= GRID_ATTR_STRIKETHROUGH;
2202                               break;
2203                     case 21:
2204                               gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
2205                               gc->attr |= GRID_ATTR_UNDERSCORE_2;
2206                               break;
2207                     case 22:
2208                               gc->attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_DIM);
2209                               break;
2210                     case 23:
2211                               gc->attr &= ~GRID_ATTR_ITALICS;
2212                               break;
2213                     case 24:
2214                               gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
2215                               break;
2216                     case 25:
2217                               gc->attr &= ~GRID_ATTR_BLINK;
2218                               break;
2219                     case 27:
2220                               gc->attr &= ~GRID_ATTR_REVERSE;
2221                               break;
2222                     case 28:
2223                               gc->attr &= ~GRID_ATTR_HIDDEN;
2224                               break;
2225                     case 29:
2226                               gc->attr &= ~GRID_ATTR_STRIKETHROUGH;
2227                               break;
2228                     case 30:
2229                     case 31:
2230                     case 32:
2231                     case 33:
2232                     case 34:
2233                     case 35:
2234                     case 36:
2235                     case 37:
2236                               gc->fg = n - 30;
2237                               break;
2238                     case 39:
2239                               gc->fg = 8;
2240                               break;
2241                     case 40:
2242                     case 41:
2243                     case 42:
2244                     case 43:
2245                     case 44:
2246                     case 45:
2247                     case 46:
2248                     case 47:
2249                               gc->bg = n - 40;
2250                               break;
2251                     case 49:
2252                               gc->bg = 8;
2253                               break;
2254                     case 53:
2255                               gc->attr |= GRID_ATTR_OVERLINE;
2256                               break;
2257                     case 55:
2258                               gc->attr &= ~GRID_ATTR_OVERLINE;
2259                               break;
2260                     case 59:
2261                               gc->us = 8;
2262                               break;
2263                     case 90:
2264                     case 91:
2265                     case 92:
2266                     case 93:
2267                     case 94:
2268                     case 95:
2269                     case 96:
2270                     case 97:
2271                               gc->fg = n;
2272                               break;
2273                     case 100:
2274                     case 101:
2275                     case 102:
2276                     case 103:
2277                     case 104:
2278                     case 105:
2279                     case 106:
2280                     case 107:
2281                               gc->bg = n - 10;
2282                               break;
2283                     }
2284           }
2285 }
2286 
2287 /* End of input with BEL. */
2288 static int
input_end_bel(struct input_ctx * ictx)2289 input_end_bel(struct input_ctx *ictx)
2290 {
2291           log_debug("%s", __func__);
2292 
2293           ictx->input_end = INPUT_END_BEL;
2294 
2295           return (0);
2296 }
2297 
2298 /* DCS string started. */
2299 static void
input_enter_dcs(struct input_ctx * ictx)2300 input_enter_dcs(struct input_ctx *ictx)
2301 {
2302           log_debug("%s", __func__);
2303 
2304           input_clear(ictx);
2305           input_start_timer(ictx);
2306           ictx->flags &= ~INPUT_LAST;
2307 }
2308 
2309 /* DCS terminator (ST) received. */
2310 static int
input_dcs_dispatch(struct input_ctx * ictx)2311 input_dcs_dispatch(struct input_ctx *ictx)
2312 {
2313           struct window_pane  *wp = ictx->wp;
2314           struct screen_write_ctx       *sctx = &ictx->ctx;
2315           char                          *buf = (char *)ictx->input_buf;
2316           size_t                         len = ictx->input_len;
2317           const char                     prefix[] = "tmux;";
2318           const u_int                    prefixlen = (sizeof prefix) - 1;
2319           long long            allow_passthrough = 0;
2320 #ifdef ENABLE_SIXEL
2321           struct window                 *w;
2322           struct sixel_image  *si;
2323 #endif
2324 
2325           if (wp == NULL)
2326                     return (0);
2327 
2328           if (ictx->flags & INPUT_DISCARD) {
2329                     log_debug("%s: %zu bytes (discard)", __func__, len);
2330                     return (0);
2331           }
2332 
2333 #ifdef ENABLE_SIXEL
2334           w = wp->window;
2335           if (buf[0] == 'q') {
2336                     si = sixel_parse(buf, len, w->xpixel, w->ypixel);
2337                     if (si != NULL)
2338                               screen_write_sixelimage(sctx, si, ictx->cell.cell.bg);
2339           }
2340 #endif
2341 
2342           allow_passthrough = options_get_number(wp->options, "allow-passthrough");
2343           if (!allow_passthrough)
2344                     return (0);
2345           log_debug("%s: \"%s\"", __func__, buf);
2346 
2347           if (len >= prefixlen && strncmp(buf, prefix, prefixlen) == 0) {
2348                     screen_write_rawstring(sctx, (u_char *)buf + prefixlen, len - prefixlen,
2349                         allow_passthrough == 2);
2350           }
2351 
2352           return (0);
2353 }
2354 
2355 /* OSC string started. */
2356 static void
input_enter_osc(struct input_ctx * ictx)2357 input_enter_osc(struct input_ctx *ictx)
2358 {
2359           log_debug("%s", __func__);
2360 
2361           input_clear(ictx);
2362           input_start_timer(ictx);
2363           ictx->flags &= ~INPUT_LAST;
2364 }
2365 
2366 /* OSC terminator (ST) received. */
2367 static void
input_exit_osc(struct input_ctx * ictx)2368 input_exit_osc(struct input_ctx *ictx)
2369 {
2370           struct screen_write_ctx       *sctx = &ictx->ctx;
2371           struct window_pane  *wp = ictx->wp;
2372           char                          *p = (char *)ictx->input_buf;
2373           u_int                          option;
2374 
2375           if (ictx->flags & INPUT_DISCARD)
2376                     return;
2377           if (ictx->input_len < 1 || *p < '0' || *p > '9')
2378                     return;
2379 
2380           log_debug("%s: \"%s\" (end %s)", __func__, p,
2381               ictx->input_end == INPUT_END_ST ? "ST" : "BEL");
2382 
2383           option = 0;
2384           while (*p >= '0' && *p <= '9')
2385                     option = option * 10 + *p++ - '0';
2386           if (*p != ';' && *p != '\0')
2387                     return;
2388           if (*p == ';')
2389                     p++;
2390 
2391           switch (option) {
2392           case 0:
2393           case 2:
2394                     if (wp != NULL &&
2395                         options_get_number(wp->options, "allow-set-title") &&
2396                         screen_set_title(sctx->s, p)) {
2397                               notify_pane("pane-title-changed", wp);
2398                               server_redraw_window_borders(wp->window);
2399                               server_status_window(wp->window);
2400                     }
2401                     break;
2402           case 4:
2403                     input_osc_4(ictx, p);
2404                     break;
2405           case 7:
2406                     if (utf8_isvalid(p)) {
2407                               screen_set_path(sctx->s, p);
2408                               if (wp != NULL) {
2409                                         server_redraw_window_borders(wp->window);
2410                                         server_status_window(wp->window);
2411                               }
2412                     }
2413                     break;
2414           case 8:
2415                     input_osc_8(ictx, p);
2416                     break;
2417           case 10:
2418                     input_osc_10(ictx, p);
2419                     break;
2420           case 11:
2421                     input_osc_11(ictx, p);
2422                     break;
2423           case 12:
2424                     input_osc_12(ictx, p);
2425                     break;
2426           case 52:
2427                     input_osc_52(ictx, p);
2428                     break;
2429           case 104:
2430                     input_osc_104(ictx, p);
2431                     break;
2432           case 110:
2433                     input_osc_110(ictx, p);
2434                     break;
2435           case 111:
2436                     input_osc_111(ictx, p);
2437                     break;
2438           case 112:
2439                     input_osc_112(ictx, p);
2440                     break;
2441           case 133:
2442                     input_osc_133(ictx, p);
2443                     break;
2444           default:
2445                     log_debug("%s: unknown '%u'", __func__, option);
2446                     break;
2447           }
2448 }
2449 
2450 /* APC string started. */
2451 static void
input_enter_apc(struct input_ctx * ictx)2452 input_enter_apc(struct input_ctx *ictx)
2453 {
2454           log_debug("%s", __func__);
2455 
2456           input_clear(ictx);
2457           input_start_timer(ictx);
2458           ictx->flags &= ~INPUT_LAST;
2459 }
2460 
2461 /* APC terminator (ST) received. */
2462 static void
input_exit_apc(struct input_ctx * ictx)2463 input_exit_apc(struct input_ctx *ictx)
2464 {
2465           struct screen_write_ctx       *sctx = &ictx->ctx;
2466           struct window_pane  *wp = ictx->wp;
2467           char                          *p = (char *)ictx->input_buf;
2468 
2469           if (ictx->flags & INPUT_DISCARD)
2470                     return;
2471           log_debug("%s: \"%s\"", __func__, p);
2472 
2473           if (screen_set_title(sctx->s, p) && wp != NULL) {
2474                     notify_pane("pane-title-changed", wp);
2475                     server_redraw_window_borders(wp->window);
2476                     server_status_window(wp->window);
2477           }
2478 }
2479 
2480 /* Rename string started. */
2481 static void
input_enter_rename(struct input_ctx * ictx)2482 input_enter_rename(struct input_ctx *ictx)
2483 {
2484           log_debug("%s", __func__);
2485 
2486           input_clear(ictx);
2487           input_start_timer(ictx);
2488           ictx->flags &= ~INPUT_LAST;
2489 }
2490 
2491 /* Rename terminator (ST) received. */
2492 static void
input_exit_rename(struct input_ctx * ictx)2493 input_exit_rename(struct input_ctx *ictx)
2494 {
2495           struct window_pane  *wp = ictx->wp;
2496           struct window                 *w;
2497           struct options_entry          *o;
2498           char                          *p = (char *)ictx->input_buf;
2499 
2500           if (wp == NULL)
2501                     return;
2502           if (ictx->flags & INPUT_DISCARD)
2503                     return;
2504           if (!options_get_number(ictx->wp->options, "allow-rename"))
2505                     return;
2506           log_debug("%s: \"%s\"", __func__, p);
2507 
2508           if (!utf8_isvalid(p))
2509                     return;
2510           w = wp->window;
2511 
2512           if (ictx->input_len == 0) {
2513                     o = options_get_only(w->options, "automatic-rename");
2514                     if (o != NULL)
2515                               options_remove_or_default(o, -1, NULL);
2516                     if (!options_get_number(w->options, "automatic-rename"))
2517                               window_set_name(w, "");
2518           } else {
2519                     options_set_number(w->options, "automatic-rename", 0);
2520                     window_set_name(w, ictx->input_buf);
2521           }
2522           server_redraw_window_borders(w);
2523           server_status_window(w);
2524 }
2525 
2526 /* Open UTF-8 character. */
2527 static int
input_top_bit_set(struct input_ctx * ictx)2528 input_top_bit_set(struct input_ctx *ictx)
2529 {
2530           struct screen_write_ctx       *sctx = &ictx->ctx;
2531           struct utf8_data    *ud = &ictx->utf8data;
2532 
2533           ictx->flags &= ~INPUT_LAST;
2534 
2535           if (!ictx->utf8started) {
2536                     if (utf8_open(ud, ictx->ch) != UTF8_MORE)
2537                               return (0);
2538                     ictx->utf8started = 1;
2539                     return (0);
2540           }
2541 
2542           switch (utf8_append(ud, ictx->ch)) {
2543           case UTF8_MORE:
2544                     return (0);
2545           case UTF8_ERROR:
2546                     ictx->utf8started = 0;
2547                     return (0);
2548           case UTF8_DONE:
2549                     break;
2550           }
2551           ictx->utf8started = 0;
2552 
2553           log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size,
2554               (int)ud->size, ud->data, ud->width);
2555 
2556           utf8_copy(&ictx->cell.cell.data, ud);
2557           screen_write_collect_add(sctx, &ictx->cell.cell);
2558 
2559           utf8_copy(&ictx->last, &ictx->cell.cell.data);
2560           ictx->flags |= INPUT_LAST;
2561 
2562           return (0);
2563 }
2564 
2565 /* Reply to a colour request. */
2566 static void
input_osc_colour_reply(struct input_ctx * ictx,u_int n,int c)2567 input_osc_colour_reply(struct input_ctx *ictx, u_int n, int c)
2568 {
2569     u_char           r, g, b;
2570     const char      *end;
2571 
2572     if (c != -1)
2573               c = colour_force_rgb(c);
2574     if (c == -1)
2575               return;
2576     colour_split_rgb(c, &r, &g, &b);
2577 
2578     if (ictx->input_end == INPUT_END_BEL)
2579               end = "\007";
2580     else
2581               end = "\033\\";
2582     input_reply(ictx, "\033]%u;rgb:%02hhx%02hhx/%02hhx%02hhx/%02hhx%02hhx%s",
2583           n, r, r, g, g, b, b, end);
2584 }
2585 
2586 /* Handle the OSC 4 sequence for setting (multiple) palette entries. */
2587 static void
input_osc_4(struct input_ctx * ictx,const char * p)2588 input_osc_4(struct input_ctx *ictx, const char *p)
2589 {
2590           char      *copy, *s, *next = NULL;
2591           long       idx;
2592           int        c, bad = 0, redraw = 0;
2593 
2594           copy = s = xstrdup(p);
2595           while (s != NULL && *s != '\0') {
2596                     idx = strtol(s, &next, 10);
2597                     if (*next++ != ';') {
2598                               bad = 1;
2599                               break;
2600                     }
2601                     if (idx < 0 || idx >= 256) {
2602                               bad = 1;
2603                               break;
2604                     }
2605 
2606                     s = strsep(&next, ";");
2607                     if (strcmp(s, "?") == 0) {
2608                               c = colour_palette_get(ictx->palette, idx);
2609                               if (c != -1)
2610                                         input_osc_colour_reply(ictx, 4, c);
2611                               continue;
2612                     }
2613                     if ((c = colour_parseX11(s)) == -1) {
2614                               s = next;
2615                               continue;
2616                     }
2617                     if (colour_palette_set(ictx->palette, idx, c))
2618                               redraw = 1;
2619                     s = next;
2620           }
2621           if (bad)
2622                     log_debug("bad OSC 4: %s", p);
2623           if (redraw)
2624                     screen_write_fullredraw(&ictx->ctx);
2625           free(copy);
2626 }
2627 
2628 /* Handle the OSC 8 sequence for embedding hyperlinks. */
2629 static void
input_osc_8(struct input_ctx * ictx,const char * p)2630 input_osc_8(struct input_ctx *ictx, const char *p)
2631 {
2632           struct hyperlinks   *hl = ictx->ctx.s->hyperlinks;
2633           struct grid_cell    *gc = &ictx->cell.cell;
2634           const char                    *start, *end, *uri;
2635           char                          *id = NULL;
2636 
2637           for (start = p; (end = strpbrk(start, ":;")) != NULL; start = end + 1) {
2638                     if (end - start >= 4 && strncmp(start, "id=", 3) == 0) {
2639                               if (id != NULL)
2640                                         goto bad;
2641                               id = xstrndup(start + 3, end - start - 3);
2642                     }
2643 
2644                     /* The first ; is the end of parameters and start of the URI. */
2645                     if (*end == ';')
2646                               break;
2647           }
2648           if (end == NULL || *end != ';')
2649                     goto bad;
2650           uri = end + 1;
2651           if (*uri == '\0') {
2652                     gc->link = 0;
2653                     free(id);
2654                     return;
2655           }
2656           gc->link = hyperlinks_put(hl, uri, id);
2657           if (id == NULL)
2658                     log_debug("hyperlink (anonymous) %s = %u", uri, gc->link);
2659           else
2660                     log_debug("hyperlink (id=%s) %s = %u", id, uri, gc->link);
2661           free(id);
2662           return;
2663 
2664 bad:
2665           log_debug("bad OSC 8 %s", p);
2666           free(id);
2667 }
2668 
2669 /*
2670  * Get a client with a foreground for the pane. There isn't much to choose
2671  * between them so just use the first.
2672  */
2673 static int
input_get_fg_client(struct window_pane * wp)2674 input_get_fg_client(struct window_pane *wp)
2675 {
2676           struct window       *w = wp->window;
2677           struct client       *loop;
2678 
2679           TAILQ_FOREACH(loop, &clients, entry) {
2680                     if (loop->flags & CLIENT_UNATTACHEDFLAGS)
2681                               continue;
2682                     if (loop->session == NULL || !session_has(loop->session, w))
2683                               continue;
2684                     if (loop->tty.fg == -1)
2685                               continue;
2686                     return (loop->tty.fg);
2687           }
2688           return (-1);
2689 }
2690 
2691 /* Get a client with a background for the pane. */
2692 static int
input_get_bg_client(struct window_pane * wp)2693 input_get_bg_client(struct window_pane *wp)
2694 {
2695           struct window       *w = wp->window;
2696           struct client       *loop;
2697 
2698           TAILQ_FOREACH(loop, &clients, entry) {
2699                     if (loop->flags & CLIENT_UNATTACHEDFLAGS)
2700                               continue;
2701                     if (loop->session == NULL || !session_has(loop->session, w))
2702                               continue;
2703                     if (loop->tty.bg == -1)
2704                               continue;
2705                     return (loop->tty.bg);
2706           }
2707           return (-1);
2708 }
2709 
2710 /*
2711  * If any control mode client exists that has provided a bg color, return it.
2712  * Otherwise, return -1.
2713  */
2714 static int
input_get_bg_control_client(struct window_pane * wp)2715 input_get_bg_control_client(struct window_pane *wp)
2716 {
2717           struct client       *c;
2718 
2719           if (wp->control_bg == -1)
2720                     return (-1);
2721 
2722           TAILQ_FOREACH(c, &clients, entry) {
2723                     if (c->flags & CLIENT_CONTROL)
2724                               return (wp->control_bg);
2725           }
2726           return (-1);
2727 }
2728 
2729 /*
2730  * If any control mode client exists that has provided a fg color, return it.
2731  * Otherwise, return -1.
2732  */
2733 static int
input_get_fg_control_client(struct window_pane * wp)2734 input_get_fg_control_client(struct window_pane *wp)
2735 {
2736           struct client       *c;
2737 
2738           if (wp->control_fg == -1)
2739                     return (-1);
2740 
2741           TAILQ_FOREACH(c, &clients, entry) {
2742                     if (c->flags & CLIENT_CONTROL)
2743                               return (wp->control_fg);
2744           }
2745           return (-1);
2746 }
2747 
2748 /* Handle the OSC 10 sequence for setting and querying foreground colour. */
2749 static void
input_osc_10(struct input_ctx * ictx,const char * p)2750 input_osc_10(struct input_ctx *ictx, const char *p)
2751 {
2752           struct window_pane  *wp = ictx->wp;
2753           struct grid_cell     defaults;
2754           int                            c;
2755 
2756           if (strcmp(p, "?") == 0) {
2757                     if (wp == NULL)
2758                               return;
2759                     c = input_get_fg_control_client(wp);
2760                     if (c == -1) {
2761                               tty_default_colours(&defaults, wp);
2762                               if (COLOUR_DEFAULT(defaults.fg))
2763                                         c = input_get_fg_client(wp);
2764                               else
2765                                         c = defaults.fg;
2766                     }
2767                     input_osc_colour_reply(ictx, 10, c);
2768                     return;
2769           }
2770 
2771           if ((c = colour_parseX11(p)) == -1) {
2772                     log_debug("bad OSC 10: %s", p);
2773                     return;
2774           }
2775           if (ictx->palette != NULL) {
2776                     ictx->palette->fg = c;
2777                     if (wp != NULL)
2778                               wp->flags |= PANE_STYLECHANGED;
2779                     screen_write_fullredraw(&ictx->ctx);
2780           }
2781 }
2782 
2783 /* Handle the OSC 110 sequence for resetting foreground colour. */
2784 static void
input_osc_110(struct input_ctx * ictx,const char * p)2785 input_osc_110(struct input_ctx *ictx, const char *p)
2786 {
2787           struct window_pane  *wp = ictx->wp;
2788 
2789           if (*p != '\0')
2790                     return;
2791           if (ictx->palette != NULL) {
2792                     ictx->palette->fg = 8;
2793                     if (wp != NULL)
2794                               wp->flags |= PANE_STYLECHANGED;
2795                     screen_write_fullredraw(&ictx->ctx);
2796           }
2797 }
2798 
2799 /* Handle the OSC 11 sequence for setting and querying background colour. */
2800 static void
input_osc_11(struct input_ctx * ictx,const char * p)2801 input_osc_11(struct input_ctx *ictx, const char *p)
2802 {
2803           struct window_pane  *wp = ictx->wp;
2804           struct grid_cell     defaults;
2805           int                            c;
2806 
2807           if (strcmp(p, "?") == 0) {
2808                     if (wp == NULL)
2809                               return;
2810                     c = input_get_bg_control_client(wp);
2811                     if (c == -1) {
2812                               tty_default_colours(&defaults, wp);
2813                               if (COLOUR_DEFAULT(defaults.bg))
2814                                         c = input_get_bg_client(wp);
2815                               else
2816                                         c = defaults.bg;
2817                     }
2818                     input_osc_colour_reply(ictx, 11, c);
2819                     return;
2820           }
2821 
2822           if ((c = colour_parseX11(p)) == -1) {
2823                     log_debug("bad OSC 11: %s", p);
2824                     return;
2825           }
2826           if (ictx->palette != NULL) {
2827                     ictx->palette->bg = c;
2828                     if (wp != NULL)
2829                               wp->flags |= PANE_STYLECHANGED;
2830                     screen_write_fullredraw(&ictx->ctx);
2831           }
2832 }
2833 
2834 /* Handle the OSC 111 sequence for resetting background colour. */
2835 static void
input_osc_111(struct input_ctx * ictx,const char * p)2836 input_osc_111(struct input_ctx *ictx, const char *p)
2837 {
2838           struct window_pane  *wp = ictx->wp;
2839 
2840           if (*p != '\0')
2841                     return;
2842           if (ictx->palette != NULL) {
2843                     ictx->palette->bg = 8;
2844                     if (wp != NULL)
2845                               wp->flags |= PANE_STYLECHANGED;
2846                     screen_write_fullredraw(&ictx->ctx);
2847           }
2848 }
2849 
2850 /* Handle the OSC 12 sequence for setting and querying cursor colour. */
2851 static void
input_osc_12(struct input_ctx * ictx,const char * p)2852 input_osc_12(struct input_ctx *ictx, const char *p)
2853 {
2854           struct window_pane  *wp = ictx->wp;
2855           int                            c;
2856 
2857           if (strcmp(p, "?") == 0) {
2858                     if (wp != NULL) {
2859                               c = ictx->ctx.s->ccolour;
2860                               if (c == -1)
2861                                         c = ictx->ctx.s->default_ccolour;
2862                               input_osc_colour_reply(ictx, 12, c);
2863                     }
2864                     return;
2865           }
2866 
2867           if ((c = colour_parseX11(p)) == -1) {
2868                     log_debug("bad OSC 12: %s", p);
2869                     return;
2870           }
2871           screen_set_cursor_colour(ictx->ctx.s, c);
2872 }
2873 
2874 /* Handle the OSC 112 sequence for resetting cursor colour. */
2875 static void
input_osc_112(struct input_ctx * ictx,const char * p)2876 input_osc_112(struct input_ctx *ictx, const char *p)
2877 {
2878           if (*p == '\0') /* no arguments allowed */
2879                     screen_set_cursor_colour(ictx->ctx.s, -1);
2880 }
2881 
2882 /* Handle the OSC 133 sequence. */
2883 static void
input_osc_133(struct input_ctx * ictx,const char * p)2884 input_osc_133(struct input_ctx *ictx, const char *p)
2885 {
2886           struct grid                   *gd = ictx->ctx.s->grid;
2887           u_int                          line = ictx->ctx.s->cy + gd->hsize;
2888           struct grid_line    *gl;
2889 
2890           if (line > gd->hsize + gd->sy - 1)
2891                     return;
2892           gl = grid_get_line(gd, line);
2893 
2894           switch (*p) {
2895           case 'A':
2896                     gl->flags |= GRID_LINE_START_PROMPT;
2897                     break;
2898           case 'C':
2899                     gl->flags |= GRID_LINE_START_OUTPUT;
2900                     break;
2901           }
2902 }
2903 
2904 /* Handle the OSC 52 sequence for setting the clipboard. */
2905 static void
input_osc_52(struct input_ctx * ictx,const char * p)2906 input_osc_52(struct input_ctx *ictx, const char *p)
2907 {
2908           struct window_pane  *wp = ictx->wp;
2909           char                          *end;
2910           const char                    *buf = NULL;
2911           size_t                         len = 0;
2912           u_char                        *out;
2913           int                            outlen, state;
2914           struct screen_write_ctx        ctx;
2915           struct paste_buffer *pb;
2916           const char*              allow = "cpqs01234567";
2917           char                     flags[sizeof "cpqs01234567"] = "";
2918           u_int                          i, j = 0;
2919 
2920           if (wp == NULL)
2921                     return;
2922           state = options_get_number(global_options, "set-clipboard");
2923           if (state != 2)
2924                     return;
2925 
2926           if ((end = strchr(p, ';')) == NULL)
2927                     return;
2928           end++;
2929           if (*end == '\0')
2930                     return;
2931           log_debug("%s: %s", __func__, end);
2932 
2933           for (i = 0; p + i != end; i++) {
2934                     if (strchr(allow, p[i]) != NULL && strchr(flags, p[i]) == NULL)
2935                               flags[j++] = p[i];
2936           }
2937           log_debug("%s: %.*s %s", __func__, (int)(end - p - 1), p, flags);
2938 
2939           if (strcmp(end, "?") == 0) {
2940                     if ((pb = paste_get_top(NULL)) != NULL)
2941                               buf = paste_buffer_data(pb, &len);
2942                     if (ictx->input_end == INPUT_END_BEL)
2943                               input_reply_clipboard(ictx->event, buf, len, "\007");
2944                     else
2945                               input_reply_clipboard(ictx->event, buf, len, "\033\\");
2946                     return;
2947           }
2948 
2949           len = (strlen(end) / 4) * 3;
2950           if (len == 0)
2951                     return;
2952 
2953           out = xmalloc(len);
2954           if ((outlen = b64_pton(end, out, len)) == -1) {
2955                     free(out);
2956                     return;
2957           }
2958 
2959           screen_write_start_pane(&ctx, wp, NULL);
2960           screen_write_setselection(&ctx, flags, out, outlen);
2961           screen_write_stop(&ctx);
2962           notify_pane("pane-set-clipboard", wp);
2963 
2964           paste_add(NULL, (char *)out, outlen);
2965 }
2966 
2967 /* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */
2968 static void
input_osc_104(struct input_ctx * ictx,const char * p)2969 input_osc_104(struct input_ctx *ictx, const char *p)
2970 {
2971           char      *copy, *s;
2972           long       idx;
2973           int        bad = 0, redraw = 0;
2974 
2975           if (*p == '\0') {
2976                     colour_palette_clear(ictx->palette);
2977                     screen_write_fullredraw(&ictx->ctx);
2978                     return;
2979           }
2980 
2981           copy = s = xstrdup(p);
2982           while (*s != '\0') {
2983                     idx = strtol(s, &s, 10);
2984                     if (*s != '\0' && *s != ';') {
2985                               bad = 1;
2986                               break;
2987                     }
2988                     if (idx < 0 || idx >= 256) {
2989                               bad = 1;
2990                               break;
2991                     }
2992                     if (colour_palette_set(ictx->palette, idx, -1))
2993                               redraw = 1;
2994                     if (*s == ';')
2995                               s++;
2996           }
2997           if (bad)
2998                     log_debug("bad OSC 104: %s", p);
2999           if (redraw)
3000                     screen_write_fullredraw(&ictx->ctx);
3001           free(copy);
3002 }
3003 
3004 void
input_reply_clipboard(struct bufferevent * bev,const char * buf,size_t len,const char * end)3005 input_reply_clipboard(struct bufferevent *bev, const char *buf, size_t len,
3006     const char *end)
3007 {
3008           char      *out = NULL;
3009           int        outlen = 0;
3010 
3011           if (buf != NULL && len != 0) {
3012                     if (len >= ((size_t)INT_MAX * 3 / 4) - 1)
3013                               return;
3014                     outlen = 4 * ((len + 2) / 3) + 1;
3015                     out = xmalloc(outlen);
3016                     if ((outlen = b64_ntop(buf, len, out, outlen)) == -1) {
3017                               free(out);
3018                               return;
3019                     }
3020           }
3021 
3022           bufferevent_write(bev, "\033]52;;", 6);
3023           if (outlen != 0)
3024                     bufferevent_write(bev, out, outlen);
3025           bufferevent_write(bev, end, strlen(end));
3026           free(out);
3027 }
3028