tmux  3.2a
About: tmux is a terminal multiplexer that lets you switch easily between several programs in one terminal.
  Fossies Dox: tmux-3.2a.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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