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