xref: /openbsd-src/usr.bin/tmux/input.c (revision d59bb9942320b767f2a19aaa7690c8c6e30b724c)
1 /* $OpenBSD: input.c,v 1.117 2017/02/19 07:55:11 nicm Exp $ */
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 <resolv.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
27 
28 #include "tmux.h"
29 
30 /*
31  * Based on the description by Paul Williams at:
32  *
33  * http://vt100.net/emu/dec_ansi_parser
34  *
35  * With the following changes:
36  *
37  * - 7-bit only.
38  *
39  * - Support for UTF-8.
40  *
41  * - OSC (but not APC) may be terminated by \007 as well as ST.
42  *
43  * - A state for APC similar to OSC. Some terminals appear to use this to set
44  *   the title.
45  *
46  * - A state for the screen \033k...\033\\ sequence to rename a window. This is
47  *   pretty stupid but not supporting it is more trouble than it is worth.
48  *
49  * - Special handling for ESC inside a DCS to allow arbitrary byte sequences to
50  *   be passed to the underlying terminals.
51  */
52 
53 /* Input parser cell. */
54 struct input_cell {
55 	struct grid_cell	cell;
56 	int			set;
57 	int			g0set;	/* 1 if ACS */
58 	int			g1set;	/* 1 if ACS */
59 };
60 
61 /* Input parser context. */
62 struct input_ctx {
63 	struct window_pane     *wp;
64 	struct screen_write_ctx ctx;
65 
66 	struct input_cell	cell;
67 
68 	struct input_cell	old_cell;
69 	u_int 			old_cx;
70 	u_int			old_cy;
71 
72 	u_char			interm_buf[4];
73 	size_t			interm_len;
74 
75 	u_char			param_buf[64];
76 	size_t			param_len;
77 
78 #define INPUT_BUF_START 32
79 #define INPUT_BUF_LIMIT 1048576
80 	u_char		       *input_buf;
81 	size_t			input_len;
82 	size_t			input_space;
83 
84 	int			param_list[24];	/* -1 not present */
85 	u_int			param_list_len;
86 
87 	struct utf8_data	utf8data;
88 
89 	int			ch;
90 
91 	int			flags;
92 #define INPUT_DISCARD 0x1
93 
94 	const struct input_state *state;
95 
96 	/*
97 	 * All input received since we were last in the ground state. Sent to
98 	 * control clients on connection.
99 	 */
100 	struct evbuffer	 	*since_ground;
101 };
102 
103 /* Helper functions. */
104 struct input_transition;
105 static int	input_split(struct input_ctx *);
106 static int	input_get(struct input_ctx *, u_int, int, int);
107 static void printflike(2, 3) input_reply(struct input_ctx *, const char *, ...);
108 static void	input_set_state(struct window_pane *,
109 		    const struct input_transition *);
110 static void	input_reset_cell(struct input_ctx *);
111 
112 static void	input_osc_4(struct window_pane *, const char *);
113 static void	input_osc_52(struct window_pane *, const char *);
114 static void	input_osc_104(struct window_pane *, const char *);
115 
116 /* Transition entry/exit handlers. */
117 static void	input_clear(struct input_ctx *);
118 static void	input_ground(struct input_ctx *);
119 static void	input_enter_osc(struct input_ctx *);
120 static void	input_exit_osc(struct input_ctx *);
121 static void	input_enter_apc(struct input_ctx *);
122 static void	input_exit_apc(struct input_ctx *);
123 static void	input_enter_rename(struct input_ctx *);
124 static void	input_exit_rename(struct input_ctx *);
125 
126 /* Input state handlers. */
127 static int	input_print(struct input_ctx *);
128 static int	input_intermediate(struct input_ctx *);
129 static int	input_parameter(struct input_ctx *);
130 static int	input_input(struct input_ctx *);
131 static int	input_c0_dispatch(struct input_ctx *);
132 static int	input_esc_dispatch(struct input_ctx *);
133 static int	input_csi_dispatch(struct input_ctx *);
134 static void	input_csi_dispatch_rm(struct input_ctx *);
135 static void	input_csi_dispatch_rm_private(struct input_ctx *);
136 static void	input_csi_dispatch_sm(struct input_ctx *);
137 static void	input_csi_dispatch_sm_private(struct input_ctx *);
138 static void	input_csi_dispatch_winops(struct input_ctx *);
139 static void	input_csi_dispatch_sgr_256(struct input_ctx *, int, u_int *);
140 static void	input_csi_dispatch_sgr_rgb(struct input_ctx *, int, u_int *);
141 static void	input_csi_dispatch_sgr(struct input_ctx *);
142 static int	input_dcs_dispatch(struct input_ctx *);
143 static int	input_utf8_open(struct input_ctx *);
144 static int	input_utf8_add(struct input_ctx *);
145 static int	input_utf8_close(struct input_ctx *);
146 
147 /* Command table comparison function. */
148 static int	input_table_compare(const void *, const void *);
149 
150 /* Command table entry. */
151 struct input_table_entry {
152 	int		ch;
153 	const char     *interm;
154 	int		type;
155 };
156 
157 /* Escape commands. */
158 enum input_esc_type {
159 	INPUT_ESC_DECALN,
160 	INPUT_ESC_DECKPAM,
161 	INPUT_ESC_DECKPNM,
162 	INPUT_ESC_DECRC,
163 	INPUT_ESC_DECSC,
164 	INPUT_ESC_HTS,
165 	INPUT_ESC_IND,
166 	INPUT_ESC_NEL,
167 	INPUT_ESC_RI,
168 	INPUT_ESC_RIS,
169 	INPUT_ESC_SCSG0_OFF,
170 	INPUT_ESC_SCSG0_ON,
171 	INPUT_ESC_SCSG1_OFF,
172 	INPUT_ESC_SCSG1_ON,
173 	INPUT_ESC_ST,
174 };
175 
176 /* Escape command table. */
177 static const struct input_table_entry input_esc_table[] = {
178 	{ '0', "(", INPUT_ESC_SCSG0_ON },
179 	{ '0', ")", INPUT_ESC_SCSG1_ON },
180 	{ '7', "",  INPUT_ESC_DECSC },
181 	{ '8', "",  INPUT_ESC_DECRC },
182 	{ '8', "#", INPUT_ESC_DECALN },
183 	{ '=', "",  INPUT_ESC_DECKPAM },
184 	{ '>', "",  INPUT_ESC_DECKPNM },
185 	{ 'B', "(", INPUT_ESC_SCSG0_OFF },
186 	{ 'B', ")", INPUT_ESC_SCSG1_OFF },
187 	{ 'D', "",  INPUT_ESC_IND },
188 	{ 'E', "",  INPUT_ESC_NEL },
189 	{ 'H', "",  INPUT_ESC_HTS },
190 	{ 'M', "",  INPUT_ESC_RI },
191 	{ '\\', "", INPUT_ESC_ST },
192 	{ 'c', "",  INPUT_ESC_RIS },
193 };
194 
195 /* Control (CSI) commands. */
196 enum input_csi_type {
197 	INPUT_CSI_CBT,
198 	INPUT_CSI_CNL,
199 	INPUT_CSI_CPL,
200 	INPUT_CSI_CUB,
201 	INPUT_CSI_CUD,
202 	INPUT_CSI_CUF,
203 	INPUT_CSI_CUP,
204 	INPUT_CSI_CUU,
205 	INPUT_CSI_DA,
206 	INPUT_CSI_DA_TWO,
207 	INPUT_CSI_DCH,
208 	INPUT_CSI_DECSCUSR,
209 	INPUT_CSI_DECSTBM,
210 	INPUT_CSI_DL,
211 	INPUT_CSI_DSR,
212 	INPUT_CSI_ECH,
213 	INPUT_CSI_ED,
214 	INPUT_CSI_EL,
215 	INPUT_CSI_HPA,
216 	INPUT_CSI_ICH,
217 	INPUT_CSI_IL,
218 	INPUT_CSI_RCP,
219 	INPUT_CSI_RM,
220 	INPUT_CSI_RM_PRIVATE,
221 	INPUT_CSI_SCP,
222 	INPUT_CSI_SGR,
223 	INPUT_CSI_SM,
224 	INPUT_CSI_SM_PRIVATE,
225 	INPUT_CSI_SU,
226 	INPUT_CSI_TBC,
227 	INPUT_CSI_VPA,
228 	INPUT_CSI_WINOPS,
229 };
230 
231 /* Control (CSI) command table. */
232 static const struct input_table_entry input_csi_table[] = {
233 	{ '@', "",  INPUT_CSI_ICH },
234 	{ 'A', "",  INPUT_CSI_CUU },
235 	{ 'B', "",  INPUT_CSI_CUD },
236 	{ 'C', "",  INPUT_CSI_CUF },
237 	{ 'D', "",  INPUT_CSI_CUB },
238 	{ 'E', "",  INPUT_CSI_CNL },
239 	{ 'F', "",  INPUT_CSI_CPL },
240 	{ 'G', "",  INPUT_CSI_HPA },
241 	{ 'H', "",  INPUT_CSI_CUP },
242 	{ 'J', "",  INPUT_CSI_ED },
243 	{ 'K', "",  INPUT_CSI_EL },
244 	{ 'L', "",  INPUT_CSI_IL },
245 	{ 'M', "",  INPUT_CSI_DL },
246 	{ 'P', "",  INPUT_CSI_DCH },
247 	{ 'S', "",  INPUT_CSI_SU },
248 	{ 'X', "",  INPUT_CSI_ECH },
249 	{ 'Z', "",  INPUT_CSI_CBT },
250 	{ 'c', "",  INPUT_CSI_DA },
251 	{ 'c', ">", INPUT_CSI_DA_TWO },
252 	{ 'd', "",  INPUT_CSI_VPA },
253 	{ 'f', "",  INPUT_CSI_CUP },
254 	{ 'g', "",  INPUT_CSI_TBC },
255 	{ 'h', "",  INPUT_CSI_SM },
256 	{ 'h', "?", INPUT_CSI_SM_PRIVATE },
257 	{ 'l', "",  INPUT_CSI_RM },
258 	{ 'l', "?", INPUT_CSI_RM_PRIVATE },
259 	{ 'm', "",  INPUT_CSI_SGR },
260 	{ 'n', "",  INPUT_CSI_DSR },
261 	{ 'q', " ", INPUT_CSI_DECSCUSR },
262 	{ 'r', "",  INPUT_CSI_DECSTBM },
263 	{ 's', "",  INPUT_CSI_SCP },
264 	{ 't', "",  INPUT_CSI_WINOPS },
265 	{ 'u', "",  INPUT_CSI_RCP },
266 };
267 
268 /* Input transition. */
269 struct input_transition {
270 	int				first;
271 	int				last;
272 
273 	int				(*handler)(struct input_ctx *);
274 	const struct input_state       *state;
275 };
276 
277 /* Input state. */
278 struct input_state {
279 	const char			*name;
280 	void				(*enter)(struct input_ctx *);
281 	void				(*exit)(struct input_ctx *);
282 	const struct input_transition	*transitions;
283 };
284 
285 /* State transitions available from all states. */
286 #define INPUT_STATE_ANYWHERE \
287 	{ 0x18, 0x18, input_c0_dispatch, &input_state_ground }, \
288 	{ 0x1a, 0x1a, input_c0_dispatch, &input_state_ground }, \
289 	{ 0x1b, 0x1b, NULL,		 &input_state_esc_enter }
290 
291 /* Forward declarations of state tables. */
292 static const struct input_transition input_state_ground_table[];
293 static const struct input_transition input_state_esc_enter_table[];
294 static const struct input_transition input_state_esc_intermediate_table[];
295 static const struct input_transition input_state_csi_enter_table[];
296 static const struct input_transition input_state_csi_parameter_table[];
297 static const struct input_transition input_state_csi_intermediate_table[];
298 static const struct input_transition input_state_csi_ignore_table[];
299 static const struct input_transition input_state_dcs_enter_table[];
300 static const struct input_transition input_state_dcs_parameter_table[];
301 static const struct input_transition input_state_dcs_intermediate_table[];
302 static const struct input_transition input_state_dcs_handler_table[];
303 static const struct input_transition input_state_dcs_escape_table[];
304 static const struct input_transition input_state_dcs_ignore_table[];
305 static const struct input_transition input_state_osc_string_table[];
306 static const struct input_transition input_state_apc_string_table[];
307 static const struct input_transition input_state_rename_string_table[];
308 static const struct input_transition input_state_consume_st_table[];
309 static const struct input_transition input_state_utf8_three_table[];
310 static const struct input_transition input_state_utf8_two_table[];
311 static const struct input_transition input_state_utf8_one_table[];
312 
313 /* ground state definition. */
314 static const struct input_state input_state_ground = {
315 	"ground",
316 	input_ground, NULL,
317 	input_state_ground_table
318 };
319 
320 /* esc_enter state definition. */
321 static const struct input_state input_state_esc_enter = {
322 	"esc_enter",
323 	input_clear, NULL,
324 	input_state_esc_enter_table
325 };
326 
327 /* esc_intermediate state definition. */
328 static const struct input_state input_state_esc_intermediate = {
329 	"esc_intermediate",
330 	NULL, NULL,
331 	input_state_esc_intermediate_table
332 };
333 
334 /* csi_enter state definition. */
335 static const struct input_state input_state_csi_enter = {
336 	"csi_enter",
337 	input_clear, NULL,
338 	input_state_csi_enter_table
339 };
340 
341 /* csi_parameter state definition. */
342 static const struct input_state input_state_csi_parameter = {
343 	"csi_parameter",
344 	NULL, NULL,
345 	input_state_csi_parameter_table
346 };
347 
348 /* csi_intermediate state definition. */
349 static const struct input_state input_state_csi_intermediate = {
350 	"csi_intermediate",
351 	NULL, NULL,
352 	input_state_csi_intermediate_table
353 };
354 
355 /* csi_ignore state definition. */
356 static const struct input_state input_state_csi_ignore = {
357 	"csi_ignore",
358 	NULL, NULL,
359 	input_state_csi_ignore_table
360 };
361 
362 /* dcs_enter state definition. */
363 static const struct input_state input_state_dcs_enter = {
364 	"dcs_enter",
365 	input_clear, NULL,
366 	input_state_dcs_enter_table
367 };
368 
369 /* dcs_parameter state definition. */
370 static const struct input_state input_state_dcs_parameter = {
371 	"dcs_parameter",
372 	NULL, NULL,
373 	input_state_dcs_parameter_table
374 };
375 
376 /* dcs_intermediate state definition. */
377 static const struct input_state input_state_dcs_intermediate = {
378 	"dcs_intermediate",
379 	NULL, NULL,
380 	input_state_dcs_intermediate_table
381 };
382 
383 /* dcs_handler state definition. */
384 static const struct input_state input_state_dcs_handler = {
385 	"dcs_handler",
386 	NULL, NULL,
387 	input_state_dcs_handler_table
388 };
389 
390 /* dcs_escape state definition. */
391 static const struct input_state input_state_dcs_escape = {
392 	"dcs_escape",
393 	NULL, NULL,
394 	input_state_dcs_escape_table
395 };
396 
397 /* dcs_ignore state definition. */
398 static const struct input_state input_state_dcs_ignore = {
399 	"dcs_ignore",
400 	NULL, NULL,
401 	input_state_dcs_ignore_table
402 };
403 
404 /* osc_string state definition. */
405 static const struct input_state input_state_osc_string = {
406 	"osc_string",
407 	input_enter_osc, input_exit_osc,
408 	input_state_osc_string_table
409 };
410 
411 /* apc_string state definition. */
412 static const struct input_state input_state_apc_string = {
413 	"apc_string",
414 	input_enter_apc, input_exit_apc,
415 	input_state_apc_string_table
416 };
417 
418 /* rename_string state definition. */
419 static const struct input_state input_state_rename_string = {
420 	"rename_string",
421 	input_enter_rename, input_exit_rename,
422 	input_state_rename_string_table
423 };
424 
425 /* consume_st state definition. */
426 static const struct input_state input_state_consume_st = {
427 	"consume_st",
428 	NULL, NULL,
429 	input_state_consume_st_table
430 };
431 
432 /* utf8_three state definition. */
433 static const struct input_state input_state_utf8_three = {
434 	"utf8_three",
435 	NULL, NULL,
436 	input_state_utf8_three_table
437 };
438 
439 /* utf8_two state definition. */
440 static const struct input_state input_state_utf8_two = {
441 	"utf8_two",
442 	NULL, NULL,
443 	input_state_utf8_two_table
444 };
445 
446 /* utf8_one state definition. */
447 static const struct input_state input_state_utf8_one = {
448 	"utf8_one",
449 	NULL, NULL,
450 	input_state_utf8_one_table
451 };
452 
453 /* ground state table. */
454 static const struct input_transition input_state_ground_table[] = {
455 	INPUT_STATE_ANYWHERE,
456 
457 	{ 0x00, 0x17, input_c0_dispatch, NULL },
458 	{ 0x19, 0x19, input_c0_dispatch, NULL },
459 	{ 0x1c, 0x1f, input_c0_dispatch, NULL },
460 	{ 0x20, 0x7e, input_print,	 NULL },
461 	{ 0x7f, 0x7f, NULL,		 NULL },
462 	{ 0x80, 0xc1, NULL,		 NULL },
463 	{ 0xc2, 0xdf, input_utf8_open,	 &input_state_utf8_one },
464 	{ 0xe0, 0xef, input_utf8_open,	 &input_state_utf8_two },
465 	{ 0xf0, 0xf4, input_utf8_open,	 &input_state_utf8_three },
466 	{ 0xf5, 0xff, NULL,		 NULL },
467 
468 	{ -1, -1, NULL, NULL }
469 };
470 
471 /* esc_enter state table. */
472 static const struct input_transition input_state_esc_enter_table[] = {
473 	INPUT_STATE_ANYWHERE,
474 
475 	{ 0x00, 0x17, input_c0_dispatch,  NULL },
476 	{ 0x19, 0x19, input_c0_dispatch,  NULL },
477 	{ 0x1c, 0x1f, input_c0_dispatch,  NULL },
478 	{ 0x20, 0x2f, input_intermediate, &input_state_esc_intermediate },
479 	{ 0x30, 0x4f, input_esc_dispatch, &input_state_ground },
480 	{ 0x50, 0x50, NULL,		  &input_state_dcs_enter },
481 	{ 0x51, 0x57, input_esc_dispatch, &input_state_ground },
482 	{ 0x58, 0x58, NULL,		  &input_state_consume_st },
483 	{ 0x59, 0x59, input_esc_dispatch, &input_state_ground },
484 	{ 0x5a, 0x5a, input_esc_dispatch, &input_state_ground },
485 	{ 0x5b, 0x5b, NULL,		  &input_state_csi_enter },
486 	{ 0x5c, 0x5c, input_esc_dispatch, &input_state_ground },
487 	{ 0x5d, 0x5d, NULL,		  &input_state_osc_string },
488 	{ 0x5e, 0x5e, NULL,		  &input_state_consume_st },
489 	{ 0x5f, 0x5f, NULL,		  &input_state_apc_string },
490 	{ 0x60, 0x6a, input_esc_dispatch, &input_state_ground },
491 	{ 0x6b, 0x6b, NULL,		  &input_state_rename_string },
492 	{ 0x6c, 0x7e, input_esc_dispatch, &input_state_ground },
493 	{ 0x7f, 0xff, NULL,		  NULL },
494 
495 	{ -1, -1, NULL, NULL }
496 };
497 
498 /* esc_interm state table. */
499 static const struct input_transition input_state_esc_intermediate_table[] = {
500 	INPUT_STATE_ANYWHERE,
501 
502 	{ 0x00, 0x17, input_c0_dispatch,  NULL },
503 	{ 0x19, 0x19, input_c0_dispatch,  NULL },
504 	{ 0x1c, 0x1f, input_c0_dispatch,  NULL },
505 	{ 0x20, 0x2f, input_intermediate, NULL },
506 	{ 0x30, 0x7e, input_esc_dispatch, &input_state_ground },
507 	{ 0x7f, 0xff, NULL,		  NULL },
508 
509 	{ -1, -1, NULL, NULL }
510 };
511 
512 /* csi_enter state table. */
513 static const struct input_transition input_state_csi_enter_table[] = {
514 	INPUT_STATE_ANYWHERE,
515 
516 	{ 0x00, 0x17, input_c0_dispatch,  NULL },
517 	{ 0x19, 0x19, input_c0_dispatch,  NULL },
518 	{ 0x1c, 0x1f, input_c0_dispatch,  NULL },
519 	{ 0x20, 0x2f, input_intermediate, &input_state_csi_intermediate },
520 	{ 0x30, 0x39, input_parameter,	  &input_state_csi_parameter },
521 	{ 0x3a, 0x3a, NULL,		  &input_state_csi_ignore },
522 	{ 0x3b, 0x3b, input_parameter,	  &input_state_csi_parameter },
523 	{ 0x3c, 0x3f, input_intermediate, &input_state_csi_parameter },
524 	{ 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
525 	{ 0x7f, 0xff, NULL,		  NULL },
526 
527 	{ -1, -1, NULL, NULL }
528 };
529 
530 /* csi_parameter state table. */
531 static const struct input_transition input_state_csi_parameter_table[] = {
532 	INPUT_STATE_ANYWHERE,
533 
534 	{ 0x00, 0x17, input_c0_dispatch,  NULL },
535 	{ 0x19, 0x19, input_c0_dispatch,  NULL },
536 	{ 0x1c, 0x1f, input_c0_dispatch,  NULL },
537 	{ 0x20, 0x2f, input_intermediate, &input_state_csi_intermediate },
538 	{ 0x30, 0x39, input_parameter,	  NULL },
539 	{ 0x3a, 0x3a, NULL,		  &input_state_csi_ignore },
540 	{ 0x3b, 0x3b, input_parameter,	  NULL },
541 	{ 0x3c, 0x3f, NULL,		  &input_state_csi_ignore },
542 	{ 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
543 	{ 0x7f, 0xff, NULL,		  NULL },
544 
545 	{ -1, -1, NULL, NULL }
546 };
547 
548 /* csi_intermediate state table. */
549 static const struct input_transition input_state_csi_intermediate_table[] = {
550 	INPUT_STATE_ANYWHERE,
551 
552 	{ 0x00, 0x17, input_c0_dispatch,  NULL },
553 	{ 0x19, 0x19, input_c0_dispatch,  NULL },
554 	{ 0x1c, 0x1f, input_c0_dispatch,  NULL },
555 	{ 0x20, 0x2f, input_intermediate, NULL },
556 	{ 0x30, 0x3f, NULL,		  &input_state_csi_ignore },
557 	{ 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
558 	{ 0x7f, 0xff, NULL,		  NULL },
559 
560 	{ -1, -1, NULL, NULL }
561 };
562 
563 /* csi_ignore state table. */
564 static const struct input_transition input_state_csi_ignore_table[] = {
565 	INPUT_STATE_ANYWHERE,
566 
567 	{ 0x00, 0x17, input_c0_dispatch, NULL },
568 	{ 0x19, 0x19, input_c0_dispatch, NULL },
569 	{ 0x1c, 0x1f, input_c0_dispatch, NULL },
570 	{ 0x20, 0x3f, NULL,		 NULL },
571 	{ 0x40, 0x7e, NULL,		 &input_state_ground },
572 	{ 0x7f, 0xff, NULL,		 NULL },
573 
574 	{ -1, -1, NULL, NULL }
575 };
576 
577 /* dcs_enter state table. */
578 static const struct input_transition input_state_dcs_enter_table[] = {
579 	INPUT_STATE_ANYWHERE,
580 
581 	{ 0x00, 0x17, NULL,		  NULL },
582 	{ 0x19, 0x19, NULL,		  NULL },
583 	{ 0x1c, 0x1f, NULL,		  NULL },
584 	{ 0x20, 0x2f, input_intermediate, &input_state_dcs_intermediate },
585 	{ 0x30, 0x39, input_parameter,	  &input_state_dcs_parameter },
586 	{ 0x3a, 0x3a, NULL,		  &input_state_dcs_ignore },
587 	{ 0x3b, 0x3b, input_parameter,	  &input_state_dcs_parameter },
588 	{ 0x3c, 0x3f, input_intermediate, &input_state_dcs_parameter },
589 	{ 0x40, 0x7e, input_input,	  &input_state_dcs_handler },
590 	{ 0x7f, 0xff, NULL,		  NULL },
591 
592 	{ -1, -1, NULL, NULL }
593 };
594 
595 /* dcs_parameter state table. */
596 static const struct input_transition input_state_dcs_parameter_table[] = {
597 	INPUT_STATE_ANYWHERE,
598 
599 	{ 0x00, 0x17, NULL,		  NULL },
600 	{ 0x19, 0x19, NULL,		  NULL },
601 	{ 0x1c, 0x1f, NULL,		  NULL },
602 	{ 0x20, 0x2f, input_intermediate, &input_state_dcs_intermediate },
603 	{ 0x30, 0x39, input_parameter,	  NULL },
604 	{ 0x3a, 0x3a, NULL,		  &input_state_dcs_ignore },
605 	{ 0x3b, 0x3b, input_parameter,	  NULL },
606 	{ 0x3c, 0x3f, NULL,		  &input_state_dcs_ignore },
607 	{ 0x40, 0x7e, input_input,	  &input_state_dcs_handler },
608 	{ 0x7f, 0xff, NULL,		  NULL },
609 
610 	{ -1, -1, NULL, NULL }
611 };
612 
613 /* dcs_interm state table. */
614 static const struct input_transition input_state_dcs_intermediate_table[] = {
615 	INPUT_STATE_ANYWHERE,
616 
617 	{ 0x00, 0x17, NULL,		  NULL },
618 	{ 0x19, 0x19, NULL,		  NULL },
619 	{ 0x1c, 0x1f, NULL,		  NULL },
620 	{ 0x20, 0x2f, input_intermediate, NULL },
621 	{ 0x30, 0x3f, NULL,		  &input_state_dcs_ignore },
622 	{ 0x40, 0x7e, input_input,	  &input_state_dcs_handler },
623 	{ 0x7f, 0xff, NULL,		  NULL },
624 
625 	{ -1, -1, NULL, NULL }
626 };
627 
628 /* dcs_handler state table. */
629 static const struct input_transition input_state_dcs_handler_table[] = {
630 	/* No INPUT_STATE_ANYWHERE */
631 
632 	{ 0x00, 0x1a, input_input,  NULL },
633 	{ 0x1b, 0x1b, NULL,	    &input_state_dcs_escape },
634 	{ 0x1c, 0xff, input_input,  NULL },
635 
636 	{ -1, -1, NULL, NULL }
637 };
638 
639 /* dcs_escape state table. */
640 static const struct input_transition input_state_dcs_escape_table[] = {
641 	/* No INPUT_STATE_ANYWHERE */
642 
643 	{ 0x00, 0x5b, input_input,	  &input_state_dcs_handler },
644 	{ 0x5c, 0x5c, input_dcs_dispatch, &input_state_ground },
645 	{ 0x5d, 0xff, input_input,	  &input_state_dcs_handler },
646 
647 	{ -1, -1, NULL, NULL }
648 };
649 
650 /* dcs_ignore state table. */
651 static const struct input_transition input_state_dcs_ignore_table[] = {
652 	INPUT_STATE_ANYWHERE,
653 
654 	{ 0x00, 0x17, NULL,	    NULL },
655 	{ 0x19, 0x19, NULL,	    NULL },
656 	{ 0x1c, 0x1f, NULL,	    NULL },
657 	{ 0x20, 0xff, NULL,	    NULL },
658 
659 	{ -1, -1, NULL, NULL }
660 };
661 
662 /* osc_string state table. */
663 static const struct input_transition input_state_osc_string_table[] = {
664 	INPUT_STATE_ANYWHERE,
665 
666 	{ 0x00, 0x06, NULL,	    NULL },
667 	{ 0x07, 0x07, NULL,	    &input_state_ground },
668 	{ 0x08, 0x17, NULL,	    NULL },
669 	{ 0x19, 0x19, NULL,	    NULL },
670 	{ 0x1c, 0x1f, NULL,	    NULL },
671 	{ 0x20, 0xff, input_input,  NULL },
672 
673 	{ -1, -1, NULL, NULL }
674 };
675 
676 /* apc_string state table. */
677 static const struct input_transition input_state_apc_string_table[] = {
678 	INPUT_STATE_ANYWHERE,
679 
680 	{ 0x00, 0x17, NULL,	    NULL },
681 	{ 0x19, 0x19, NULL,	    NULL },
682 	{ 0x1c, 0x1f, NULL,	    NULL },
683 	{ 0x20, 0xff, input_input,  NULL },
684 
685 	{ -1, -1, NULL, NULL }
686 };
687 
688 /* rename_string state table. */
689 static const struct input_transition input_state_rename_string_table[] = {
690 	INPUT_STATE_ANYWHERE,
691 
692 	{ 0x00, 0x17, NULL,	    NULL },
693 	{ 0x19, 0x19, NULL,	    NULL },
694 	{ 0x1c, 0x1f, NULL,	    NULL },
695 	{ 0x20, 0xff, input_input,  NULL },
696 
697 	{ -1, -1, NULL, NULL }
698 };
699 
700 /* consume_st state table. */
701 static const struct input_transition input_state_consume_st_table[] = {
702 	INPUT_STATE_ANYWHERE,
703 
704 	{ 0x00, 0x17, NULL,	    NULL },
705 	{ 0x19, 0x19, NULL,	    NULL },
706 	{ 0x1c, 0x1f, NULL,	    NULL },
707 	{ 0x20, 0xff, NULL,	    NULL },
708 
709 	{ -1, -1, NULL, NULL }
710 };
711 
712 /* utf8_three state table. */
713 static const struct input_transition input_state_utf8_three_table[] = {
714 	/* No INPUT_STATE_ANYWHERE */
715 
716 	{ 0x00, 0x7f, NULL,		&input_state_ground },
717 	{ 0x80, 0xbf, input_utf8_add,	&input_state_utf8_two },
718 	{ 0xc0, 0xff, NULL,		&input_state_ground },
719 
720 	{ -1, -1, NULL, NULL }
721 };
722 
723 /* utf8_two state table. */
724 static const struct input_transition input_state_utf8_two_table[] = {
725 	/* No INPUT_STATE_ANYWHERE */
726 
727 	{ 0x00, 0x7f, NULL,	      &input_state_ground },
728 	{ 0x80, 0xbf, input_utf8_add, &input_state_utf8_one },
729 	{ 0xc0, 0xff, NULL,	      &input_state_ground },
730 
731 	{ -1, -1, NULL, NULL }
732 };
733 
734 /* utf8_one state table. */
735 static const struct input_transition input_state_utf8_one_table[] = {
736 	/* No INPUT_STATE_ANYWHERE */
737 
738 	{ 0x00, 0x7f, NULL,		&input_state_ground },
739 	{ 0x80, 0xbf, input_utf8_close, &input_state_ground },
740 	{ 0xc0, 0xff, NULL,		&input_state_ground },
741 
742 	{ -1, -1, NULL, NULL }
743 };
744 
745 /* Input table compare. */
746 static int
747 input_table_compare(const void *key, const void *value)
748 {
749 	const struct input_ctx		*ictx = key;
750 	const struct input_table_entry	*entry = value;
751 
752 	if (ictx->ch != entry->ch)
753 		return (ictx->ch - entry->ch);
754 	return (strcmp(ictx->interm_buf, entry->interm));
755 }
756 
757 /* Reset cell state to default. */
758 static void
759 input_reset_cell(struct input_ctx *ictx)
760 {
761 	memcpy(&ictx->cell.cell, &grid_default_cell, sizeof ictx->cell.cell);
762 	ictx->cell.set = 0;
763 	ictx->cell.g0set = ictx->cell.g1set = 0;
764 
765 	memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
766 	ictx->old_cx = 0;
767 	ictx->old_cy = 0;
768 }
769 
770 /* Initialise input parser. */
771 void
772 input_init(struct window_pane *wp)
773 {
774 	struct input_ctx	*ictx;
775 
776 	ictx = wp->ictx = xcalloc(1, sizeof *ictx);
777 
778 	ictx->input_space = INPUT_BUF_START;
779 	ictx->input_buf = xmalloc(INPUT_BUF_START);
780 
781 	ictx->since_ground = evbuffer_new();
782 
783 	input_reset(wp, 0);
784 }
785 
786 /* Destroy input parser. */
787 void
788 input_free(struct window_pane *wp)
789 {
790 	struct input_ctx	*ictx = wp->ictx;
791 
792 	free(ictx->input_buf);
793 	evbuffer_free(ictx->since_ground);
794 
795 	free(ictx);
796 	wp->ictx = NULL;
797 }
798 
799 /* Reset input state and clear screen. */
800 void
801 input_reset(struct window_pane *wp, int clear)
802 {
803 	struct input_ctx	*ictx = wp->ictx;
804 
805 	input_reset_cell(ictx);
806 
807 	if (clear) {
808 		if (wp->mode == NULL)
809 			screen_write_start(&ictx->ctx, wp, &wp->base);
810 		else
811 			screen_write_start(&ictx->ctx, NULL, &wp->base);
812 		screen_write_reset(&ictx->ctx);
813 		screen_write_stop(&ictx->ctx);
814 	}
815 
816 	*ictx->interm_buf = '\0';
817 	ictx->interm_len = 0;
818 
819 	*ictx->param_buf = '\0';
820 	ictx->param_len = 0;
821 
822 	*ictx->input_buf = '\0';
823 	ictx->input_len = 0;
824 
825 	ictx->state = &input_state_ground;
826 	ictx->flags = 0;
827 }
828 
829 /* Return pending data. */
830 struct evbuffer *
831 input_pending(struct window_pane *wp)
832 {
833 	return (wp->ictx->since_ground);
834 }
835 
836 /* Change input state. */
837 static void
838 input_set_state(struct window_pane *wp, const struct input_transition *itr)
839 {
840 	struct input_ctx	*ictx = wp->ictx;
841 
842 	if (ictx->state->exit != NULL)
843 		ictx->state->exit(ictx);
844 	ictx->state = itr->state;
845 	if (ictx->state->enter != NULL)
846 		ictx->state->enter(ictx);
847 }
848 
849 /* Parse input. */
850 void
851 input_parse(struct window_pane *wp)
852 {
853 	struct input_ctx		*ictx = wp->ictx;
854 	const struct input_transition	*itr;
855 	struct evbuffer			*evb = wp->event->input;
856 	u_char				*buf;
857 	size_t				 len, off;
858 
859 	if (EVBUFFER_LENGTH(evb) == 0)
860 		return;
861 
862 	window_update_activity(wp->window);
863 	wp->flags |= PANE_CHANGED;
864 
865 	/*
866 	 * Open the screen. Use NULL wp if there is a mode set as don't want to
867 	 * update the tty.
868 	 */
869 	if (wp->mode == NULL)
870 		screen_write_start(&ictx->ctx, wp, &wp->base);
871 	else
872 		screen_write_start(&ictx->ctx, NULL, &wp->base);
873 	ictx->wp = wp;
874 
875 	buf = EVBUFFER_DATA(evb);
876 	len = EVBUFFER_LENGTH(evb);
877 	off = 0;
878 
879 	notify_input(wp, evb);
880 
881 	log_debug("%s: %%%u %s, %zu bytes: %.*s", __func__, wp->id,
882 	    ictx->state->name, len, (int)len, buf);
883 
884 	/* Parse the input. */
885 	while (off < len) {
886 		ictx->ch = buf[off++];
887 
888 		/* Find the transition. */
889 		itr = ictx->state->transitions;
890 		while (itr->first != -1 && itr->last != -1) {
891 			if (ictx->ch >= itr->first && ictx->ch <= itr->last)
892 				break;
893 			itr++;
894 		}
895 		if (itr->first == -1 || itr->last == -1) {
896 			/* No transition? Eh? */
897 			fatalx("no transition from state");
898 		}
899 
900 		/*
901 		 * Any state except print stops the current collection. This is
902 		 * an optimization to avoid checking if the attributes have
903 		 * changed for every character. It will stop unnecessarily for
904 		 * sequences that don't make a terminal change, but they should
905 		 * be the minority.
906 		 */
907 		if (itr->handler != input_print)
908 			screen_write_collect_end(&ictx->ctx);
909 
910 		/*
911 		 * Execute the handler, if any. Don't switch state if it
912 		 * returns non-zero.
913 		 */
914 		if (itr->handler != NULL && itr->handler(ictx) != 0)
915 			continue;
916 
917 		/* And switch state, if necessary. */
918 		if (itr->state != NULL)
919 			input_set_state(wp, itr);
920 
921 		/* If not in ground state, save input. */
922 		if (ictx->state != &input_state_ground)
923 			evbuffer_add(ictx->since_ground, &ictx->ch, 1);
924 	}
925 
926 	/* Close the screen. */
927 	screen_write_stop(&ictx->ctx);
928 
929 	evbuffer_drain(evb, len);
930 }
931 
932 /* Split the parameter list (if any). */
933 static int
934 input_split(struct input_ctx *ictx)
935 {
936 	const char	*errstr;
937 	char		*ptr, *out;
938 	int		 n;
939 
940 	ictx->param_list_len = 0;
941 	if (ictx->param_len == 0)
942 		return (0);
943 
944 	ptr = ictx->param_buf;
945 	while ((out = strsep(&ptr, ";")) != NULL) {
946 		if (*out == '\0')
947 			n = -1;
948 		else {
949 			n = strtonum(out, 0, INT_MAX, &errstr);
950 			if (errstr != NULL)
951 				return (-1);
952 		}
953 
954 		ictx->param_list[ictx->param_list_len++] = n;
955 		if (ictx->param_list_len == nitems(ictx->param_list))
956 			return (-1);
957 	}
958 
959 	return (0);
960 }
961 
962 /* Get an argument or return default value. */
963 static int
964 input_get(struct input_ctx *ictx, u_int validx, int minval, int defval)
965 {
966 	int	retval;
967 
968 	if (validx >= ictx->param_list_len)
969 	    return (defval);
970 
971 	retval = ictx->param_list[validx];
972 	if (retval == -1)
973 		return (defval);
974 	if (retval < minval)
975 		return (minval);
976 	return (retval);
977 }
978 
979 /* Reply to terminal query. */
980 static void
981 input_reply(struct input_ctx *ictx, const char *fmt, ...)
982 {
983 	va_list	ap;
984 	char   *reply;
985 
986 	va_start(ap, fmt);
987 	xvasprintf(&reply, fmt, ap);
988 	va_end(ap);
989 
990 	bufferevent_write(ictx->wp->event, reply, strlen(reply));
991 	free(reply);
992 }
993 
994 /* Clear saved state. */
995 static void
996 input_clear(struct input_ctx *ictx)
997 {
998 	*ictx->interm_buf = '\0';
999 	ictx->interm_len = 0;
1000 
1001 	*ictx->param_buf = '\0';
1002 	ictx->param_len = 0;
1003 
1004 	*ictx->input_buf = '\0';
1005 	ictx->input_len = 0;
1006 
1007 	ictx->flags &= ~INPUT_DISCARD;
1008 }
1009 
1010 /* Reset for ground state. */
1011 static void
1012 input_ground(struct input_ctx *ictx)
1013 {
1014 	evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground));
1015 
1016 	if (ictx->input_space > INPUT_BUF_START) {
1017 		ictx->input_space = INPUT_BUF_START;
1018 		ictx->input_buf = xrealloc(ictx->input_buf, INPUT_BUF_START);
1019 	}
1020 }
1021 
1022 /* Output this character to the screen. */
1023 static int
1024 input_print(struct input_ctx *ictx)
1025 {
1026 	int	set;
1027 
1028 	set = ictx->cell.set == 0 ? ictx->cell.g0set : ictx->cell.g1set;
1029 	if (set == 1)
1030 		ictx->cell.cell.attr |= GRID_ATTR_CHARSET;
1031 	else
1032 		ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
1033 
1034 	utf8_set(&ictx->cell.cell.data, ictx->ch);
1035 	screen_write_collect_add(&ictx->ctx, &ictx->cell.cell);
1036 
1037 	ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
1038 
1039 	return (0);
1040 }
1041 
1042 /* Collect intermediate string. */
1043 static int
1044 input_intermediate(struct input_ctx *ictx)
1045 {
1046 	if (ictx->interm_len == (sizeof ictx->interm_buf) - 1)
1047 		ictx->flags |= INPUT_DISCARD;
1048 	else {
1049 		ictx->interm_buf[ictx->interm_len++] = ictx->ch;
1050 		ictx->interm_buf[ictx->interm_len] = '\0';
1051 	}
1052 
1053 	return (0);
1054 }
1055 
1056 /* Collect parameter string. */
1057 static int
1058 input_parameter(struct input_ctx *ictx)
1059 {
1060 	if (ictx->param_len == (sizeof ictx->param_buf) - 1)
1061 		ictx->flags |= INPUT_DISCARD;
1062 	else {
1063 		ictx->param_buf[ictx->param_len++] = ictx->ch;
1064 		ictx->param_buf[ictx->param_len] = '\0';
1065 	}
1066 
1067 	return (0);
1068 }
1069 
1070 /* Collect input string. */
1071 static int
1072 input_input(struct input_ctx *ictx)
1073 {
1074 	size_t available;
1075 
1076 	available = ictx->input_space;
1077 	while (ictx->input_len + 1 >= available) {
1078 		available *= 2;
1079 		if (available > INPUT_BUF_LIMIT) {
1080 			ictx->flags |= INPUT_DISCARD;
1081 			return (0);
1082 		}
1083 		ictx->input_buf = xrealloc(ictx->input_buf, available);
1084 		ictx->input_space = available;
1085 	}
1086 	ictx->input_buf[ictx->input_len++] = ictx->ch;
1087 	ictx->input_buf[ictx->input_len] = '\0';
1088 
1089 	return (0);
1090 }
1091 
1092 /* Execute C0 control sequence. */
1093 static int
1094 input_c0_dispatch(struct input_ctx *ictx)
1095 {
1096 	struct screen_write_ctx	*sctx = &ictx->ctx;
1097 	struct window_pane	*wp = ictx->wp;
1098 	struct screen		*s = sctx->s;
1099 
1100 	log_debug("%s: '%c'", __func__, ictx->ch);
1101 
1102 	switch (ictx->ch) {
1103 	case '\000':	/* NUL */
1104 		break;
1105 	case '\007':	/* BEL */
1106 		alerts_queue(wp->window, WINDOW_BELL);
1107 		break;
1108 	case '\010':	/* BS */
1109 		screen_write_backspace(sctx);
1110 		break;
1111 	case '\011':	/* HT */
1112 		/* Don't tab beyond the end of the line. */
1113 		if (s->cx >= screen_size_x(s) - 1)
1114 			break;
1115 
1116 		/* Find the next tab point, or use the last column if none. */
1117 		do {
1118 			s->cx++;
1119 			if (bit_test(s->tabs, s->cx))
1120 				break;
1121 		} while (s->cx < screen_size_x(s) - 1);
1122 		break;
1123 	case '\012':	/* LF */
1124 	case '\013':	/* VT */
1125 	case '\014':	/* FF */
1126 		screen_write_linefeed(sctx, 0);
1127 		break;
1128 	case '\015':	/* CR */
1129 		screen_write_carriagereturn(sctx);
1130 		break;
1131 	case '\016':	/* SO */
1132 		ictx->cell.set = 1;
1133 		break;
1134 	case '\017':	/* SI */
1135 		ictx->cell.set = 0;
1136 		break;
1137 	default:
1138 		log_debug("%s: unknown '%c'", __func__, ictx->ch);
1139 		break;
1140 	}
1141 
1142 	return (0);
1143 }
1144 
1145 /* Execute escape sequence. */
1146 static int
1147 input_esc_dispatch(struct input_ctx *ictx)
1148 {
1149 	struct screen_write_ctx		*sctx = &ictx->ctx;
1150 	struct screen			*s = sctx->s;
1151 	struct input_table_entry	*entry;
1152 
1153 	if (ictx->flags & INPUT_DISCARD)
1154 		return (0);
1155 	log_debug("%s: '%c', %s", __func__, ictx->ch, ictx->interm_buf);
1156 
1157 	entry = bsearch(ictx, input_esc_table, nitems(input_esc_table),
1158 	    sizeof input_esc_table[0], input_table_compare);
1159 	if (entry == NULL) {
1160 		log_debug("%s: unknown '%c'", __func__, ictx->ch);
1161 		return (0);
1162 	}
1163 
1164 	switch (entry->type) {
1165 	case INPUT_ESC_RIS:
1166 		window_pane_reset_palette(ictx->wp);
1167 		input_reset_cell(ictx);
1168 		screen_write_reset(sctx);
1169 		break;
1170 	case INPUT_ESC_IND:
1171 		screen_write_linefeed(sctx, 0);
1172 		break;
1173 	case INPUT_ESC_NEL:
1174 		screen_write_carriagereturn(sctx);
1175 		screen_write_linefeed(sctx, 0);
1176 		break;
1177 	case INPUT_ESC_HTS:
1178 		if (s->cx < screen_size_x(s))
1179 			bit_set(s->tabs, s->cx);
1180 		break;
1181 	case INPUT_ESC_RI:
1182 		screen_write_reverseindex(sctx);
1183 		break;
1184 	case INPUT_ESC_DECKPAM:
1185 		screen_write_mode_set(sctx, MODE_KKEYPAD);
1186 		break;
1187 	case INPUT_ESC_DECKPNM:
1188 		screen_write_mode_clear(sctx, MODE_KKEYPAD);
1189 		break;
1190 	case INPUT_ESC_DECSC:
1191 		memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
1192 		ictx->old_cx = s->cx;
1193 		ictx->old_cy = s->cy;
1194 		break;
1195 	case INPUT_ESC_DECRC:
1196 		memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell);
1197 		screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy);
1198 		break;
1199 	case INPUT_ESC_DECALN:
1200 		screen_write_alignmenttest(sctx);
1201 		break;
1202 	case INPUT_ESC_SCSG0_ON:
1203 		ictx->cell.g0set = 1;
1204 		break;
1205 	case INPUT_ESC_SCSG0_OFF:
1206 		ictx->cell.g0set = 0;
1207 		break;
1208 	case INPUT_ESC_SCSG1_ON:
1209 		ictx->cell.g1set = 1;
1210 		break;
1211 	case INPUT_ESC_SCSG1_OFF:
1212 		ictx->cell.g1set = 0;
1213 		break;
1214 	case INPUT_ESC_ST:
1215 		/* ST terminates OSC but the state transition already did it. */
1216 		break;
1217 	}
1218 
1219 	return (0);
1220 }
1221 
1222 /* Execute control sequence. */
1223 static int
1224 input_csi_dispatch(struct input_ctx *ictx)
1225 {
1226 	struct screen_write_ctx	       *sctx = &ictx->ctx;
1227 	struct screen		       *s = sctx->s;
1228 	struct input_table_entry       *entry;
1229 	int				n, m;
1230 	u_int				cx;
1231 
1232 	if (ictx->flags & INPUT_DISCARD)
1233 		return (0);
1234 
1235 	log_debug("%s: '%c' \"%s\" \"%s\"",
1236 	    __func__, ictx->ch, ictx->interm_buf, ictx->param_buf);
1237 
1238 	if (input_split(ictx) != 0)
1239 		return (0);
1240 
1241 	entry = bsearch(ictx, input_csi_table, nitems(input_csi_table),
1242 	    sizeof input_csi_table[0], input_table_compare);
1243 	if (entry == NULL) {
1244 		log_debug("%s: unknown '%c'", __func__, ictx->ch);
1245 		return (0);
1246 	}
1247 
1248 	switch (entry->type) {
1249 	case INPUT_CSI_CBT:
1250 		/* Find the previous tab point, n times. */
1251 		cx = s->cx;
1252 		if (cx > screen_size_x(s) - 1)
1253 			cx = screen_size_x(s) - 1;
1254 		n = input_get(ictx, 0, 1, 1);
1255 		while (cx > 0 && n-- > 0) {
1256 			do
1257 				cx--;
1258 			while (cx > 0 && !bit_test(s->tabs, cx));
1259 		}
1260 		s->cx = cx;
1261 		break;
1262 	case INPUT_CSI_CUB:
1263 		screen_write_cursorleft(sctx, input_get(ictx, 0, 1, 1));
1264 		break;
1265 	case INPUT_CSI_CUD:
1266 		screen_write_cursordown(sctx, input_get(ictx, 0, 1, 1));
1267 		break;
1268 	case INPUT_CSI_CUF:
1269 		screen_write_cursorright(sctx, input_get(ictx, 0, 1, 1));
1270 		break;
1271 	case INPUT_CSI_CUP:
1272 		n = input_get(ictx, 0, 1, 1);
1273 		m = input_get(ictx, 1, 1, 1);
1274 		screen_write_cursormove(sctx, m - 1, n - 1);
1275 		break;
1276 	case INPUT_CSI_WINOPS:
1277 		input_csi_dispatch_winops(ictx);
1278 		break;
1279 	case INPUT_CSI_CUU:
1280 		screen_write_cursorup(sctx, input_get(ictx, 0, 1, 1));
1281 		break;
1282 	case INPUT_CSI_CNL:
1283 		screen_write_carriagereturn(sctx);
1284 		screen_write_cursordown(sctx, input_get(ictx, 0, 1, 1));
1285 		break;
1286 	case INPUT_CSI_CPL:
1287 		screen_write_carriagereturn(sctx);
1288 		screen_write_cursorup(sctx, input_get(ictx, 0, 1, 1));
1289 		break;
1290 	case INPUT_CSI_DA:
1291 		switch (input_get(ictx, 0, 0, 0)) {
1292 		case 0:
1293 			input_reply(ictx, "\033[?1;2c");
1294 			break;
1295 		default:
1296 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1297 			break;
1298 		}
1299 		break;
1300 	case INPUT_CSI_DA_TWO:
1301 		switch (input_get(ictx, 0, 0, 0)) {
1302 		case 0:
1303 			input_reply(ictx, "\033[>84;0;0c");
1304 			break;
1305 		default:
1306 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1307 			break;
1308 		}
1309 		break;
1310 	case INPUT_CSI_ECH:
1311 		screen_write_clearcharacter(sctx, input_get(ictx, 0, 1, 1));
1312 		break;
1313 	case INPUT_CSI_DCH:
1314 		screen_write_deletecharacter(sctx, input_get(ictx, 0, 1, 1),
1315 		    ictx->cell.cell.bg);
1316 		break;
1317 	case INPUT_CSI_DECSTBM:
1318 		n = input_get(ictx, 0, 1, 1);
1319 		m = input_get(ictx, 1, 1, screen_size_y(s));
1320 		screen_write_scrollregion(sctx, n - 1, m - 1);
1321 		break;
1322 	case INPUT_CSI_DL:
1323 		screen_write_deleteline(sctx, input_get(ictx, 0, 1, 1),
1324 		    ictx->cell.cell.bg);
1325 		break;
1326 	case INPUT_CSI_DSR:
1327 		switch (input_get(ictx, 0, 0, 0)) {
1328 		case 5:
1329 			input_reply(ictx, "\033[0n");
1330 			break;
1331 		case 6:
1332 			input_reply(ictx, "\033[%u;%uR", s->cy + 1, s->cx + 1);
1333 			break;
1334 		default:
1335 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1336 			break;
1337 		}
1338 		break;
1339 	case INPUT_CSI_ED:
1340 		switch (input_get(ictx, 0, 0, 0)) {
1341 		case 0:
1342 			screen_write_clearendofscreen(sctx, ictx->cell.cell.bg);
1343 			break;
1344 		case 1:
1345 			screen_write_clearstartofscreen(sctx, ictx->cell.cell.bg);
1346 			break;
1347 		case 2:
1348 			screen_write_clearscreen(sctx, ictx->cell.cell.bg);
1349 			break;
1350 		case 3:
1351 			switch (input_get(ictx, 1, 0, 0)) {
1352 			case 0:
1353 				/*
1354 				 * Linux console extension to clear history
1355 				 * (for example before locking the screen).
1356 				 */
1357 				screen_write_clearhistory(sctx);
1358 				break;
1359 			}
1360 			break;
1361 		default:
1362 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1363 			break;
1364 		}
1365 		break;
1366 	case INPUT_CSI_EL:
1367 		switch (input_get(ictx, 0, 0, 0)) {
1368 		case 0:
1369 			screen_write_clearendofline(sctx, ictx->cell.cell.bg);
1370 			break;
1371 		case 1:
1372 			screen_write_clearstartofline(sctx, ictx->cell.cell.bg);
1373 			break;
1374 		case 2:
1375 			screen_write_clearline(sctx, ictx->cell.cell.bg);
1376 			break;
1377 		default:
1378 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1379 			break;
1380 		}
1381 		break;
1382 	case INPUT_CSI_HPA:
1383 		n = input_get(ictx, 0, 1, 1);
1384 		screen_write_cursormove(sctx, n - 1, s->cy);
1385 		break;
1386 	case INPUT_CSI_ICH:
1387 		screen_write_insertcharacter(sctx, input_get(ictx, 0, 1, 1),
1388 		    ictx->cell.cell.bg);
1389 		break;
1390 	case INPUT_CSI_IL:
1391 		screen_write_insertline(sctx, input_get(ictx, 0, 1, 1),
1392 		    ictx->cell.cell.bg);
1393 		break;
1394 	case INPUT_CSI_RCP:
1395 		memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell);
1396 		screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy);
1397 		break;
1398 	case INPUT_CSI_RM:
1399 		input_csi_dispatch_rm(ictx);
1400 		break;
1401 	case INPUT_CSI_RM_PRIVATE:
1402 		input_csi_dispatch_rm_private(ictx);
1403 		break;
1404 	case INPUT_CSI_SCP:
1405 		memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
1406 		ictx->old_cx = s->cx;
1407 		ictx->old_cy = s->cy;
1408 		break;
1409 	case INPUT_CSI_SGR:
1410 		input_csi_dispatch_sgr(ictx);
1411 		break;
1412 	case INPUT_CSI_SM:
1413 		input_csi_dispatch_sm(ictx);
1414 		break;
1415 	case INPUT_CSI_SM_PRIVATE:
1416 		input_csi_dispatch_sm_private(ictx);
1417 		break;
1418 	case INPUT_CSI_SU:
1419 		screen_write_scrollup(sctx, input_get(ictx, 0, 1, 1));
1420 		break;
1421 	case INPUT_CSI_TBC:
1422 		switch (input_get(ictx, 0, 0, 0)) {
1423 		case 0:
1424 			if (s->cx < screen_size_x(s))
1425 				bit_clear(s->tabs, s->cx);
1426 			break;
1427 		case 3:
1428 			bit_nclear(s->tabs, 0, screen_size_x(s) - 1);
1429 			break;
1430 		default:
1431 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1432 			break;
1433 		}
1434 		break;
1435 	case INPUT_CSI_VPA:
1436 		n = input_get(ictx, 0, 1, 1);
1437 		screen_write_cursormove(sctx, s->cx, n - 1);
1438 		break;
1439 	case INPUT_CSI_DECSCUSR:
1440 		n = input_get(ictx, 0, 0, 0);
1441 		screen_set_cursor_style(s, n);
1442 		break;
1443 	}
1444 
1445 	return (0);
1446 }
1447 
1448 /* Handle CSI RM. */
1449 static void
1450 input_csi_dispatch_rm(struct input_ctx *ictx)
1451 {
1452 	u_int	i;
1453 
1454 	for (i = 0; i < ictx->param_list_len; i++) {
1455 		switch (input_get(ictx, i, 0, -1)) {
1456 		case 4:		/* IRM */
1457 			screen_write_mode_clear(&ictx->ctx, MODE_INSERT);
1458 			break;
1459 		case 34:
1460 			screen_write_mode_set(&ictx->ctx, MODE_BLINKING);
1461 			break;
1462 		default:
1463 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1464 			break;
1465 		}
1466 	}
1467 }
1468 
1469 /* Handle CSI private RM. */
1470 static void
1471 input_csi_dispatch_rm_private(struct input_ctx *ictx)
1472 {
1473 	struct window_pane	*wp = ictx->wp;
1474 	u_int			 i;
1475 
1476 	for (i = 0; i < ictx->param_list_len; i++) {
1477 		switch (input_get(ictx, i, 0, -1)) {
1478 		case 1:		/* DECCKM */
1479 			screen_write_mode_clear(&ictx->ctx, MODE_KCURSOR);
1480 			break;
1481 		case 3:		/* DECCOLM */
1482 			screen_write_cursormove(&ictx->ctx, 0, 0);
1483 			screen_write_clearscreen(&ictx->ctx,
1484 			    ictx->cell.cell.bg);
1485 			break;
1486 		case 7:		/* DECAWM */
1487 			screen_write_mode_clear(&ictx->ctx, MODE_WRAP);
1488 			break;
1489 		case 12:
1490 			screen_write_mode_clear(&ictx->ctx, MODE_BLINKING);
1491 			break;
1492 		case 25:	/* TCEM */
1493 			screen_write_mode_clear(&ictx->ctx, MODE_CURSOR);
1494 			break;
1495 		case 1000:
1496 		case 1001:
1497 		case 1002:
1498 		case 1003:
1499 			screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
1500 			break;
1501 		case 1004:
1502 			screen_write_mode_clear(&ictx->ctx, MODE_FOCUSON);
1503 			break;
1504 		case 1005:
1505 			screen_write_mode_clear(&ictx->ctx, MODE_MOUSE_UTF8);
1506 			break;
1507 		case 1006:
1508 			screen_write_mode_clear(&ictx->ctx, MODE_MOUSE_SGR);
1509 			break;
1510 		case 47:
1511 		case 1047:
1512 			window_pane_alternate_off(wp, &ictx->cell.cell, 0);
1513 			break;
1514 		case 1049:
1515 			window_pane_alternate_off(wp, &ictx->cell.cell, 1);
1516 			break;
1517 		case 2004:
1518 			screen_write_mode_clear(&ictx->ctx, MODE_BRACKETPASTE);
1519 			break;
1520 		default:
1521 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1522 			break;
1523 		}
1524 	}
1525 }
1526 
1527 /* Handle CSI SM. */
1528 static void
1529 input_csi_dispatch_sm(struct input_ctx *ictx)
1530 {
1531 	u_int	i;
1532 
1533 	for (i = 0; i < ictx->param_list_len; i++) {
1534 		switch (input_get(ictx, i, 0, -1)) {
1535 		case 4:		/* IRM */
1536 			screen_write_mode_set(&ictx->ctx, MODE_INSERT);
1537 			break;
1538 		case 34:
1539 			screen_write_mode_clear(&ictx->ctx, MODE_BLINKING);
1540 			break;
1541 		default:
1542 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1543 			break;
1544 		}
1545 	}
1546 }
1547 
1548 /* Handle CSI private SM. */
1549 static void
1550 input_csi_dispatch_sm_private(struct input_ctx *ictx)
1551 {
1552 	struct window_pane	*wp = ictx->wp;
1553 	u_int			 i;
1554 
1555 	for (i = 0; i < ictx->param_list_len; i++) {
1556 		switch (input_get(ictx, i, 0, -1)) {
1557 		case 1:		/* DECCKM */
1558 			screen_write_mode_set(&ictx->ctx, MODE_KCURSOR);
1559 			break;
1560 		case 3:		/* DECCOLM */
1561 			screen_write_cursormove(&ictx->ctx, 0, 0);
1562 			screen_write_clearscreen(&ictx->ctx,
1563 			    ictx->cell.cell.bg);
1564 			break;
1565 		case 7:		/* DECAWM */
1566 			screen_write_mode_set(&ictx->ctx, MODE_WRAP);
1567 			break;
1568 		case 12:
1569 			screen_write_mode_set(&ictx->ctx, MODE_BLINKING);
1570 			break;
1571 		case 25:	/* TCEM */
1572 			screen_write_mode_set(&ictx->ctx, MODE_CURSOR);
1573 			break;
1574 		case 1000:
1575 			screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
1576 			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_STANDARD);
1577 			break;
1578 		case 1002:
1579 			screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
1580 			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_BUTTON);
1581 			break;
1582 		case 1003:
1583 			screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
1584 			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_ALL);
1585 			break;
1586 		case 1004:
1587 			if (ictx->ctx.s->mode & MODE_FOCUSON)
1588 				break;
1589 			screen_write_mode_set(&ictx->ctx, MODE_FOCUSON);
1590 			wp->flags |= PANE_FOCUSPUSH; /* force update */
1591 			break;
1592 		case 1005:
1593 			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_UTF8);
1594 			break;
1595 		case 1006:
1596 			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_SGR);
1597 			break;
1598 		case 47:
1599 		case 1047:
1600 			window_pane_alternate_on(wp, &ictx->cell.cell, 0);
1601 			break;
1602 		case 1049:
1603 			window_pane_alternate_on(wp, &ictx->cell.cell, 1);
1604 			break;
1605 		case 2004:
1606 			screen_write_mode_set(&ictx->ctx, MODE_BRACKETPASTE);
1607 			break;
1608 		default:
1609 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1610 			break;
1611 		}
1612 	}
1613 }
1614 
1615 /* Handle CSI window operations. */
1616 static void
1617 input_csi_dispatch_winops(struct input_ctx *ictx)
1618 {
1619 	struct window_pane	*wp = ictx->wp;
1620 	int			 n, m;
1621 
1622 	m = 0;
1623 	while ((n = input_get(ictx, m, 0, -1)) != -1) {
1624 		switch (n) {
1625 		case 1:
1626 		case 2:
1627 		case 5:
1628 		case 6:
1629 		case 7:
1630 		case 11:
1631 		case 13:
1632 		case 14:
1633 		case 19:
1634 		case 20:
1635 		case 21:
1636 		case 24:
1637 			break;
1638 		case 3:
1639 		case 4:
1640 		case 8:
1641 			m++;
1642 			if (input_get(ictx, m, 0, -1) == -1)
1643 				return;
1644 			/* FALLTHROUGH */
1645 		case 9:
1646 		case 10:
1647 		case 22:
1648 		case 23:
1649 			m++;
1650 			if (input_get(ictx, m, 0, -1) == -1)
1651 				return;
1652 			break;
1653 		case 18:
1654 			input_reply(ictx, "\033[8;%u;%ut", wp->sy, wp->sx);
1655 			break;
1656 		default:
1657 			log_debug("%s: unknown '%c'", __func__, ictx->ch);
1658 			break;
1659 		}
1660 		m++;
1661 	}
1662 }
1663 
1664 /* Handle CSI SGR for 256 colours. */
1665 static void
1666 input_csi_dispatch_sgr_256(struct input_ctx *ictx, int fgbg, u_int *i)
1667 {
1668 	struct grid_cell	*gc = &ictx->cell.cell;
1669 	int			 c;
1670 
1671 	(*i)++;
1672 	c = input_get(ictx, *i, 0, -1);
1673 	if (c == -1) {
1674 		if (fgbg == 38)
1675 			gc->fg = 8;
1676 		else if (fgbg == 48)
1677 			gc->bg = 8;
1678 	} else {
1679 		if (fgbg == 38)
1680 			gc->fg = c | COLOUR_FLAG_256;
1681 		else if (fgbg == 48)
1682 			gc->bg = c | COLOUR_FLAG_256;
1683 	}
1684 }
1685 
1686 /* Handle CSI SGR for RGB colours. */
1687 static void
1688 input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
1689 {
1690 	struct grid_cell	*gc = &ictx->cell.cell;
1691 	int			 r, g, b;
1692 
1693 	(*i)++;
1694 	r = input_get(ictx, *i, 0, -1);
1695 	if (r == -1 || r > 255)
1696 		return;
1697 	(*i)++;
1698 	g = input_get(ictx, *i, 0, -1);
1699 	if (g == -1 || g > 255)
1700 		return;
1701 	(*i)++;
1702 	b = input_get(ictx, *i, 0, -1);
1703 	if (b == -1 || b > 255)
1704 		return;
1705 
1706 	if (fgbg == 38)
1707 		gc->fg = colour_join_rgb(r, g, b);
1708 	else if (fgbg == 48)
1709 		gc->bg = colour_join_rgb(r, g, b);
1710 }
1711 
1712 /* Handle CSI SGR. */
1713 static void
1714 input_csi_dispatch_sgr(struct input_ctx *ictx)
1715 {
1716 	struct grid_cell	*gc = &ictx->cell.cell;
1717 	u_int			 i;
1718 	int			 n;
1719 
1720 	if (ictx->param_list_len == 0) {
1721 		memcpy(gc, &grid_default_cell, sizeof *gc);
1722 		return;
1723 	}
1724 
1725 	for (i = 0; i < ictx->param_list_len; i++) {
1726 		n = input_get(ictx, i, 0, 0);
1727 
1728 		if (n == 38 || n == 48) {
1729 			i++;
1730 			switch (input_get(ictx, i, 0, -1)) {
1731 			case 2:
1732 				input_csi_dispatch_sgr_rgb(ictx, n, &i);
1733 				break;
1734 			case 5:
1735 				input_csi_dispatch_sgr_256(ictx, n, &i);
1736 				break;
1737 			}
1738 			continue;
1739 		}
1740 
1741 		switch (n) {
1742 		case 0:
1743 		case 10:
1744 			memcpy(gc, &grid_default_cell, sizeof *gc);
1745 			break;
1746 		case 1:
1747 			gc->attr |= GRID_ATTR_BRIGHT;
1748 			break;
1749 		case 2:
1750 			gc->attr |= GRID_ATTR_DIM;
1751 			break;
1752 		case 3:
1753 			gc->attr |= GRID_ATTR_ITALICS;
1754 			break;
1755 		case 4:
1756 			gc->attr |= GRID_ATTR_UNDERSCORE;
1757 			break;
1758 		case 5:
1759 			gc->attr |= GRID_ATTR_BLINK;
1760 			break;
1761 		case 7:
1762 			gc->attr |= GRID_ATTR_REVERSE;
1763 			break;
1764 		case 8:
1765 			gc->attr |= GRID_ATTR_HIDDEN;
1766 			break;
1767 		case 22:
1768 			gc->attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_DIM);
1769 			break;
1770 		case 23:
1771 			gc->attr &= ~GRID_ATTR_ITALICS;
1772 			break;
1773 		case 24:
1774 			gc->attr &= ~GRID_ATTR_UNDERSCORE;
1775 			break;
1776 		case 25:
1777 			gc->attr &= ~GRID_ATTR_BLINK;
1778 			break;
1779 		case 27:
1780 			gc->attr &= ~GRID_ATTR_REVERSE;
1781 			break;
1782 		case 28:
1783 			gc->attr &= ~GRID_ATTR_HIDDEN;
1784 			break;
1785 		case 30:
1786 		case 31:
1787 		case 32:
1788 		case 33:
1789 		case 34:
1790 		case 35:
1791 		case 36:
1792 		case 37:
1793 			gc->fg = n - 30;
1794 			break;
1795 		case 39:
1796 			gc->fg = 8;
1797 			break;
1798 		case 40:
1799 		case 41:
1800 		case 42:
1801 		case 43:
1802 		case 44:
1803 		case 45:
1804 		case 46:
1805 		case 47:
1806 			gc->bg = n - 40;
1807 			break;
1808 		case 49:
1809 			gc->bg = 8;
1810 			break;
1811 		case 90:
1812 		case 91:
1813 		case 92:
1814 		case 93:
1815 		case 94:
1816 		case 95:
1817 		case 96:
1818 		case 97:
1819 			gc->fg = n;
1820 			break;
1821 		case 100:
1822 		case 101:
1823 		case 102:
1824 		case 103:
1825 		case 104:
1826 		case 105:
1827 		case 106:
1828 		case 107:
1829 			gc->bg = n - 10;
1830 			break;
1831 		}
1832 	}
1833 }
1834 
1835 /* DCS terminator (ST) received. */
1836 static int
1837 input_dcs_dispatch(struct input_ctx *ictx)
1838 {
1839 	const char	prefix[] = "tmux;";
1840 	const u_int	prefix_len = (sizeof prefix) - 1;
1841 
1842 	if (ictx->flags & INPUT_DISCARD)
1843 		return (0);
1844 
1845 	log_debug("%s: \"%s\"", __func__, ictx->input_buf);
1846 
1847 	/* Check for tmux prefix. */
1848 	if (ictx->input_len >= prefix_len &&
1849 	    strncmp(ictx->input_buf, prefix, prefix_len) == 0) {
1850 		screen_write_rawstring(&ictx->ctx,
1851 		    ictx->input_buf + prefix_len, ictx->input_len - prefix_len);
1852 	}
1853 
1854 	return (0);
1855 }
1856 
1857 /* OSC string started. */
1858 static void
1859 input_enter_osc(struct input_ctx *ictx)
1860 {
1861 	log_debug("%s", __func__);
1862 
1863 	input_clear(ictx);
1864 }
1865 
1866 /* OSC terminator (ST) received. */
1867 static void
1868 input_exit_osc(struct input_ctx *ictx)
1869 {
1870 	u_char	*p = ictx->input_buf;
1871 	u_int	 option;
1872 
1873 	if (ictx->flags & INPUT_DISCARD)
1874 		return;
1875 	if (ictx->input_len < 1 || *p < '0' || *p > '9')
1876 		return;
1877 
1878 	log_debug("%s: \"%s\"", __func__, p);
1879 
1880 	option = 0;
1881 	while (*p >= '0' && *p <= '9')
1882 		option = option * 10 + *p++ - '0';
1883 	if (*p == ';')
1884 		p++;
1885 
1886 	switch (option) {
1887 	case 0:
1888 	case 2:
1889 		screen_set_title(ictx->ctx.s, p);
1890 		server_status_window(ictx->wp->window);
1891 		break;
1892 	case 4:
1893 		input_osc_4(ictx->wp, p);
1894 		break;
1895 	case 52:
1896 		input_osc_52(ictx->wp, p);
1897 		break;
1898 	case 12:
1899 		if (*p != '?') /* ? is colour request */
1900 			screen_set_cursor_colour(ictx->ctx.s, p);
1901 		break;
1902 	case 104:
1903 		input_osc_104(ictx->wp, p);
1904 		break;
1905 	case 112:
1906 		if (*p == '\0') /* no arguments allowed */
1907 			screen_set_cursor_colour(ictx->ctx.s, "");
1908 		break;
1909 	default:
1910 		log_debug("%s: unknown '%u'", __func__, option);
1911 		break;
1912 	}
1913 }
1914 
1915 /* APC string started. */
1916 static void
1917 input_enter_apc(struct input_ctx *ictx)
1918 {
1919 	log_debug("%s", __func__);
1920 
1921 	input_clear(ictx);
1922 }
1923 
1924 /* APC terminator (ST) received. */
1925 static void
1926 input_exit_apc(struct input_ctx *ictx)
1927 {
1928 	if (ictx->flags & INPUT_DISCARD)
1929 		return;
1930 	log_debug("%s: \"%s\"", __func__, ictx->input_buf);
1931 
1932 	screen_set_title(ictx->ctx.s, ictx->input_buf);
1933 	server_status_window(ictx->wp->window);
1934 }
1935 
1936 /* Rename string started. */
1937 static void
1938 input_enter_rename(struct input_ctx *ictx)
1939 {
1940 	log_debug("%s", __func__);
1941 
1942 	input_clear(ictx);
1943 }
1944 
1945 /* Rename terminator (ST) received. */
1946 static void
1947 input_exit_rename(struct input_ctx *ictx)
1948 {
1949 	if (ictx->flags & INPUT_DISCARD)
1950 		return;
1951 	if (!options_get_number(ictx->wp->window->options, "allow-rename"))
1952 		return;
1953 	log_debug("%s: \"%s\"", __func__, ictx->input_buf);
1954 
1955 	window_set_name(ictx->wp->window, ictx->input_buf);
1956 	options_set_number(ictx->wp->window->options, "automatic-rename", 0);
1957 
1958 	server_status_window(ictx->wp->window);
1959 }
1960 
1961 /* Open UTF-8 character. */
1962 static int
1963 input_utf8_open(struct input_ctx *ictx)
1964 {
1965 	struct utf8_data	*ud = &ictx->utf8data;
1966 
1967 	if (utf8_open(ud, ictx->ch) != UTF8_MORE)
1968 		fatalx("UTF-8 open invalid %#x", ictx->ch);
1969 
1970 	log_debug("%s %hhu", __func__, ud->size);
1971 
1972 	return (0);
1973 }
1974 
1975 /* Append to UTF-8 character. */
1976 static int
1977 input_utf8_add(struct input_ctx *ictx)
1978 {
1979 	struct utf8_data	*ud = &ictx->utf8data;
1980 
1981 	if (utf8_append(ud, ictx->ch) != UTF8_MORE)
1982 		fatalx("UTF-8 add invalid %#x", ictx->ch);
1983 
1984 	log_debug("%s", __func__);
1985 
1986 	return (0);
1987 }
1988 
1989 /* Close UTF-8 string. */
1990 static int
1991 input_utf8_close(struct input_ctx *ictx)
1992 {
1993 	struct utf8_data	*ud = &ictx->utf8data;
1994 
1995 	if (utf8_append(ud, ictx->ch) != UTF8_DONE) {
1996 		/*
1997 		 * An error here could be invalid UTF-8 or it could be a
1998 		 * nonprintable character for which we can't get the
1999 		 * width. Drop it.
2000 		 */
2001 		return (0);
2002 	}
2003 
2004 	log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size,
2005 	    (int)ud->size, ud->data, ud->width);
2006 
2007 	utf8_copy(&ictx->cell.cell.data, ud);
2008 	screen_write_cell(&ictx->ctx, &ictx->cell.cell);
2009 
2010 	return (0);
2011 }
2012 
2013 /* Handle the OSC 4 sequence for setting (multiple) palette entries. */
2014 static void
2015 input_osc_4(struct window_pane *wp, const char *p)
2016 {
2017 	char	*copy, *s, *next = NULL;
2018 	long	 idx;
2019 	u_int	 r, g, b;
2020 
2021 	copy = s = xstrdup(p);
2022 	while (s != NULL && *s != '\0') {
2023 		idx = strtol(s, &next, 10);
2024 		if (*next++ != ';')
2025 			goto bad;
2026 		if (idx < 0 || idx >= 0x100)
2027 			goto bad;
2028 
2029 		s = strsep(&next, ";");
2030 		if (sscanf(s, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) {
2031 			s = next;
2032 			continue;
2033 		}
2034 
2035 		window_pane_set_palette(wp, idx, colour_join_rgb(r, g, b));
2036 		s = next;
2037 	}
2038 
2039 	free(copy);
2040 	return;
2041 
2042 bad:
2043 	log_debug("bad OSC 4: %s", p);
2044 	free(copy);
2045 }
2046 
2047 /* Handle the OSC 52 sequence for setting the clipboard. */
2048 static void
2049 input_osc_52(struct window_pane *wp, const char *p)
2050 {
2051 	char			*end;
2052 	size_t			 len;
2053 	u_char			*out;
2054 	int			 outlen;
2055 	struct screen_write_ctx	 ctx;
2056 
2057 	if ((end = strchr(p, ';')) == NULL)
2058 		return;
2059 	end++;
2060 	if (*end == '\0')
2061 		return;
2062 
2063 	len = (strlen(end) / 4) * 3;
2064 	if (len == 0)
2065 		return;
2066 
2067 	out = xmalloc(len);
2068 	if ((outlen = b64_pton(end, out, len)) == -1) {
2069 		free(out);
2070 		return;
2071 	}
2072 
2073 	if (options_get_number(global_options, "set-clipboard")) {
2074 		screen_write_start(&ctx, wp, NULL);
2075 		screen_write_setselection(&ctx, out, outlen);
2076 		screen_write_stop(&ctx);
2077 	}
2078 	paste_add(out, outlen);
2079 }
2080 
2081 /* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */
2082 static void
2083 input_osc_104(struct window_pane *wp, const char *p)
2084 {
2085 	char	*copy, *s;
2086 	long	idx;
2087 
2088 	if (*p == '\0') {
2089 		window_pane_reset_palette(wp);
2090 		return;
2091 	}
2092 
2093 	copy = s = xstrdup(p);
2094 	while (*s != '\0') {
2095 		idx = strtol(s, &s, 10);
2096 		if (*s != '\0' && *s != ';')
2097 			goto bad;
2098 		if (idx < 0 || idx >= 0x100)
2099 			goto bad;
2100 
2101 		window_pane_unset_palette(wp, idx);
2102 		if (*s == ';')
2103 			s++;
2104 	}
2105 	free(copy);
2106 	return;
2107 
2108 bad:
2109 	log_debug("bad OSC 104: %s", p);
2110 	free(copy);
2111 }
2112