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