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)  

tty-keys.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 #include <sys/time.h>
21 
22 #include <netinet/in.h>
23 
24 #include <ctype.h>
25 #include <limits.h>
26 #include <resolv.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <termios.h>
30 #include <unistd.h>
31 
32 #include "tmux.h"
33 
34 /*
35  * Handle keys input from the outside terminal. tty_default_*_keys[] are a base
36  * table of supported keys which are looked up in terminfo(5) and translated
37  * into a ternary tree.
38  */
39 
40 static void tty_keys_add1(struct tty_key **, const char *, key_code);
41 static void tty_keys_add(struct tty *, const char *, key_code);
42 static void tty_keys_free1(struct tty_key *);
43 static struct tty_key *tty_keys_find1(struct tty_key *, const char *, size_t,
44  size_t *);
45 static struct tty_key *tty_keys_find(struct tty *, const char *, size_t,
46  size_t *);
47 static int tty_keys_next1(struct tty *, const char *, size_t, key_code *,
48  size_t *, int);
49 static void tty_keys_callback(int, short, void *);
50 static int tty_keys_extended_key(struct tty *, const char *, size_t,
51  size_t *, key_code *);
52 static int tty_keys_mouse(struct tty *, const char *, size_t, size_t *,
53  struct mouse_event *);
54 static int tty_keys_clipboard(struct tty *, const char *, size_t,
55  size_t *);
56 static int tty_keys_device_attributes(struct tty *, const char *, size_t,
57  size_t *);
58 static int tty_keys_extended_device_attributes(struct tty *, const char *,
59  size_t, size_t *);
60 
61 /* Default raw keys. */
63  const char *string;
65 };
66 static const struct tty_default_key_raw tty_default_raw_keys[] = {
67  /* Application escape. */
68  { "\033O[", '\033' },
69 
70  /*
71  * Numeric keypad. Just use the vt100 escape sequences here and always
72  * put the terminal into keypad_xmit mode. Translation of numbers
73  * mode/applications mode is done in input-keys.c.
74  */
75  { "\033Oo", KEYC_KP_SLASH|KEYC_KEYPAD },
76  { "\033Oj", KEYC_KP_STAR|KEYC_KEYPAD },
77  { "\033Om", KEYC_KP_MINUS|KEYC_KEYPAD },
78  { "\033Ow", KEYC_KP_SEVEN|KEYC_KEYPAD },
79  { "\033Ox", KEYC_KP_EIGHT|KEYC_KEYPAD },
80  { "\033Oy", KEYC_KP_NINE|KEYC_KEYPAD },
81  { "\033Ok", KEYC_KP_PLUS|KEYC_KEYPAD },
82  { "\033Ot", KEYC_KP_FOUR|KEYC_KEYPAD },
83  { "\033Ou", KEYC_KP_FIVE|KEYC_KEYPAD },
84  { "\033Ov", KEYC_KP_SIX|KEYC_KEYPAD },
85  { "\033Oq", KEYC_KP_ONE|KEYC_KEYPAD },
86  { "\033Or", KEYC_KP_TWO|KEYC_KEYPAD },
87  { "\033Os", KEYC_KP_THREE|KEYC_KEYPAD },
88  { "\033OM", KEYC_KP_ENTER|KEYC_KEYPAD },
89  { "\033Op", KEYC_KP_ZERO|KEYC_KEYPAD },
90  { "\033On", KEYC_KP_PERIOD|KEYC_KEYPAD },
91 
92  /* Arrow keys. */
93  { "\033OA", KEYC_UP|KEYC_CURSOR },
94  { "\033OB", KEYC_DOWN|KEYC_CURSOR },
95  { "\033OC", KEYC_RIGHT|KEYC_CURSOR },
96  { "\033OD", KEYC_LEFT|KEYC_CURSOR },
97 
98  { "\033[A", KEYC_UP|KEYC_CURSOR },
99  { "\033[B", KEYC_DOWN|KEYC_CURSOR },
100  { "\033[C", KEYC_RIGHT|KEYC_CURSOR },
101  { "\033[D", KEYC_LEFT|KEYC_CURSOR },
102 
103  /*
104  * Meta arrow keys. These do not get the IMPLIED_META flag so they
105  * don't match the xterm-style meta keys in the output tree - Escape+Up
106  * should stay as Escape+Up and not become M-Up.
107  */
108  { "\033\033OA", KEYC_UP|KEYC_CURSOR|KEYC_META },
109  { "\033\033OB", KEYC_DOWN|KEYC_CURSOR|KEYC_META },
110  { "\033\033OC", KEYC_RIGHT|KEYC_CURSOR|KEYC_META },
111  { "\033\033OD", KEYC_LEFT|KEYC_CURSOR|KEYC_META },
112 
113  { "\033\033[A", KEYC_UP|KEYC_CURSOR|KEYC_META },
114  { "\033\033[B", KEYC_DOWN|KEYC_CURSOR|KEYC_META },
115  { "\033\033[C", KEYC_RIGHT|KEYC_CURSOR|KEYC_META },
116  { "\033\033[D", KEYC_LEFT|KEYC_CURSOR|KEYC_META },
117 
118  /* Other (xterm) "cursor" keys. */
119  { "\033OH", KEYC_HOME },
120  { "\033OF", KEYC_END },
121 
122  { "\033\033OH", KEYC_HOME|KEYC_META|KEYC_IMPLIED_META },
123  { "\033\033OF", KEYC_END|KEYC_META|KEYC_IMPLIED_META },
124 
125  { "\033[H", KEYC_HOME },
126  { "\033[F", KEYC_END },
127 
128  { "\033\033[H", KEYC_HOME|KEYC_META|KEYC_IMPLIED_META },
129  { "\033\033[F", KEYC_END|KEYC_META|KEYC_IMPLIED_META },
130 
131  /* rxvt-style arrow + modifier keys. */
132  { "\033Oa", KEYC_UP|KEYC_CTRL },
133  { "\033Ob", KEYC_DOWN|KEYC_CTRL },
134  { "\033Oc", KEYC_RIGHT|KEYC_CTRL },
135  { "\033Od", KEYC_LEFT|KEYC_CTRL },
136 
137  { "\033[a", KEYC_UP|KEYC_SHIFT },
138  { "\033[b", KEYC_DOWN|KEYC_SHIFT },
139  { "\033[c", KEYC_RIGHT|KEYC_SHIFT },
140  { "\033[d", KEYC_LEFT|KEYC_SHIFT },
141 
142  /* rxvt-style function + modifier keys (C = ^, S = $, C-S = @). */
143  { "\033[11^", KEYC_F1|KEYC_CTRL },
144  { "\033[12^", KEYC_F2|KEYC_CTRL },
145  { "\033[13^", KEYC_F3|KEYC_CTRL },
146  { "\033[14^", KEYC_F4|KEYC_CTRL },
147  { "\033[15^", KEYC_F5|KEYC_CTRL },
148  { "\033[17^", KEYC_F6|KEYC_CTRL },
149  { "\033[18^", KEYC_F7|KEYC_CTRL },
150  { "\033[19^", KEYC_F8|KEYC_CTRL },
151  { "\033[20^", KEYC_F9|KEYC_CTRL },
152  { "\033[21^", KEYC_F10|KEYC_CTRL },
153  { "\033[23^", KEYC_F11|KEYC_CTRL },
154  { "\033[24^", KEYC_F12|KEYC_CTRL },
155  { "\033[2^", KEYC_IC|KEYC_CTRL },
156  { "\033[3^", KEYC_DC|KEYC_CTRL },
157  { "\033[7^", KEYC_HOME|KEYC_CTRL },
158  { "\033[8^", KEYC_END|KEYC_CTRL },
159  { "\033[6^", KEYC_NPAGE|KEYC_CTRL },
160  { "\033[5^", KEYC_PPAGE|KEYC_CTRL },
161 
162  { "\033[11$", KEYC_F1|KEYC_SHIFT },
163  { "\033[12$", KEYC_F2|KEYC_SHIFT },
164  { "\033[13$", KEYC_F3|KEYC_SHIFT },
165  { "\033[14$", KEYC_F4|KEYC_SHIFT },
166  { "\033[15$", KEYC_F5|KEYC_SHIFT },
167  { "\033[17$", KEYC_F6|KEYC_SHIFT },
168  { "\033[18$", KEYC_F7|KEYC_SHIFT },
169  { "\033[19$", KEYC_F8|KEYC_SHIFT },
170  { "\033[20$", KEYC_F9|KEYC_SHIFT },
171  { "\033[21$", KEYC_F10|KEYC_SHIFT },
172  { "\033[23$", KEYC_F11|KEYC_SHIFT },
173  { "\033[24$", KEYC_F12|KEYC_SHIFT },
174  { "\033[2$", KEYC_IC|KEYC_SHIFT },
175  { "\033[3$", KEYC_DC|KEYC_SHIFT },
176  { "\033[7$", KEYC_HOME|KEYC_SHIFT },
177  { "\033[8$", KEYC_END|KEYC_SHIFT },
178  { "\033[6$", KEYC_NPAGE|KEYC_SHIFT },
179  { "\033[5$", KEYC_PPAGE|KEYC_SHIFT },
180 
181  { "\033[11@", KEYC_F1|KEYC_CTRL|KEYC_SHIFT },
182  { "\033[12@", KEYC_F2|KEYC_CTRL|KEYC_SHIFT },
183  { "\033[13@", KEYC_F3|KEYC_CTRL|KEYC_SHIFT },
184  { "\033[14@", KEYC_F4|KEYC_CTRL|KEYC_SHIFT },
185  { "\033[15@", KEYC_F5|KEYC_CTRL|KEYC_SHIFT },
186  { "\033[17@", KEYC_F6|KEYC_CTRL|KEYC_SHIFT },
187  { "\033[18@", KEYC_F7|KEYC_CTRL|KEYC_SHIFT },
188  { "\033[19@", KEYC_F8|KEYC_CTRL|KEYC_SHIFT },
189  { "\033[20@", KEYC_F9|KEYC_CTRL|KEYC_SHIFT },
190  { "\033[21@", KEYC_F10|KEYC_CTRL|KEYC_SHIFT },
191  { "\033[23@", KEYC_F11|KEYC_CTRL|KEYC_SHIFT },
192  { "\033[24@", KEYC_F12|KEYC_CTRL|KEYC_SHIFT },
193  { "\033[2@", KEYC_IC|KEYC_CTRL|KEYC_SHIFT },
194  { "\033[3@", KEYC_DC|KEYC_CTRL|KEYC_SHIFT },
195  { "\033[7@", KEYC_HOME|KEYC_CTRL|KEYC_SHIFT },
196  { "\033[8@", KEYC_END|KEYC_CTRL|KEYC_SHIFT },
197  { "\033[6@", KEYC_NPAGE|KEYC_CTRL|KEYC_SHIFT },
198  { "\033[5@", KEYC_PPAGE|KEYC_CTRL|KEYC_SHIFT },
199 
200  /* Focus tracking. */
201  { "\033[I", KEYC_FOCUS_IN },
202  { "\033[O", KEYC_FOCUS_OUT },
203 
204  /* Paste keys. */
205  { "\033[200~", KEYC_PASTE_START },
206  { "\033[201~", KEYC_PASTE_END },
207 };
208 
209 /* Default xterm keys. */
211  const char *template;
213 };
214 static const struct tty_default_key_xterm tty_default_xterm_keys[] = {
215  { "\033[1;_P", KEYC_F1 },
216  { "\033O1;_P", KEYC_F1 },
217  { "\033O_P", KEYC_F1 },
218  { "\033[1;_Q", KEYC_F2 },
219  { "\033O1;_Q", KEYC_F2 },
220  { "\033O_Q", KEYC_F2 },
221  { "\033[1;_R", KEYC_F3 },
222  { "\033O1;_R", KEYC_F3 },
223  { "\033O_R", KEYC_F3 },
224  { "\033[1;_S", KEYC_F4 },
225  { "\033O1;_S", KEYC_F4 },
226  { "\033O_S", KEYC_F4 },
227  { "\033[15;_~", KEYC_F5 },
228  { "\033[17;_~", KEYC_F6 },
229  { "\033[18;_~", KEYC_F7 },
230  { "\033[19;_~", KEYC_F8 },
231  { "\033[20;_~", KEYC_F9 },
232  { "\033[21;_~", KEYC_F10 },
233  { "\033[23;_~", KEYC_F11 },
234  { "\033[24;_~", KEYC_F12 },
235  { "\033[1;_A", KEYC_UP },
236  { "\033[1;_B", KEYC_DOWN },
237  { "\033[1;_C", KEYC_RIGHT },
238  { "\033[1;_D", KEYC_LEFT },
239  { "\033[1;_H", KEYC_HOME },
240  { "\033[1;_F", KEYC_END },
241  { "\033[5;_~", KEYC_PPAGE },
242  { "\033[6;_~", KEYC_NPAGE },
243  { "\033[2;_~", KEYC_IC },
244  { "\033[3;_~", KEYC_DC },
245 };
247  0,
248  0,
249  KEYC_SHIFT,
252  KEYC_CTRL,
257 };
258 
259 /*
260  * Default terminfo(5) keys. Any keys that have builtin modifiers (that is,
261  * where the key itself contains the modifiers) has the KEYC_XTERM flag set so
262  * a leading escape is not treated as meta (and probably removed).
263  */
265  enum tty_code_code code;
267 };
268 static const struct tty_default_key_code tty_default_code_keys[] = {
269  /* Function keys. */
270  { TTYC_KF1, KEYC_F1 },
271  { TTYC_KF2, KEYC_F2 },
272  { TTYC_KF3, KEYC_F3 },
273  { TTYC_KF4, KEYC_F4 },
274  { TTYC_KF5, KEYC_F5 },
275  { TTYC_KF6, KEYC_F6 },
276  { TTYC_KF7, KEYC_F7 },
277  { TTYC_KF8, KEYC_F8 },
278  { TTYC_KF9, KEYC_F9 },
279  { TTYC_KF10, KEYC_F10 },
280  { TTYC_KF11, KEYC_F11 },
281  { TTYC_KF12, KEYC_F12 },
282 
295 
308 
321 
334 
338 
339  { TTYC_KICH1, KEYC_IC },
340  { TTYC_KDCH1, KEYC_DC },
341  { TTYC_KHOME, KEYC_HOME },
342  { TTYC_KEND, KEYC_END },
343  { TTYC_KNP, KEYC_NPAGE },
344  { TTYC_KPP, KEYC_PPAGE },
345  { TTYC_KCBT, KEYC_BTAB },
346 
347  /* Arrow keys from terminfo. */
352 
353  /* Key and modifier capabilities. */
416 };
417 
418 /* Add key to tree. */
419 static void
420 tty_keys_add(struct tty *tty, const char *s, key_code key)
421 {
422  struct tty_key *tk;
423  size_t size;
424  const char *keystr;
425 
426  keystr = key_string_lookup_key(key, 1);
427  if ((tk = tty_keys_find(tty, s, strlen(s), &size)) == NULL) {
428  log_debug("new key %s: 0x%llx (%s)", s, key, keystr);
429  tty_keys_add1(&tty->key_tree, s, key);
430  } else {
431  log_debug("replacing key %s: 0x%llx (%s)", s, key, keystr);
432  tk->key = key;
433  }
434 }
435 
436 /* Add next node to the tree. */
437 static void
438 tty_keys_add1(struct tty_key **tkp, const char *s, key_code key)
439 {
440  struct tty_key *tk;
441 
442  /* Allocate a tree entry if there isn't one already. */
443  tk = *tkp;
444  if (tk == NULL) {
445  tk = *tkp = xcalloc(1, sizeof *tk);
446  tk->ch = *s;
447  tk->key = KEYC_UNKNOWN;
448  }
449 
450  /* Find the next entry. */
451  if (*s == tk->ch) {
452  /* Move forward in string. */
453  s++;
454 
455  /* If this is the end of the string, no more is necessary. */
456  if (*s == '\0') {
457  tk->key = key;
458  return;
459  }
460 
461  /* Use the child tree for the next character. */
462  tkp = &tk->next;
463  } else {
464  if (*s < tk->ch)
465  tkp = &tk->left;
466  else if (*s > tk->ch)
467  tkp = &tk->right;
468  }
469 
470  /* And recurse to add it. */
471  tty_keys_add1(tkp, s, key);
472 }
473 
474 /* Initialise a key tree from the table. */
475 void
477 {
478  const struct tty_default_key_raw *tdkr;
479  const struct tty_default_key_xterm *tdkx;
480  const struct tty_default_key_code *tdkc;
481  u_int i, j;
482  const char *s;
483  struct options_entry *o;
484  struct options_array_item *a;
485  union options_value *ov;
486  char copy[16];
487  key_code key;
488 
489  if (tty->key_tree != NULL)
491  tty->key_tree = NULL;
492 
493  for (i = 0; i < nitems(tty_default_xterm_keys); i++) {
494  tdkx = &tty_default_xterm_keys[i];
495  for (j = 2; j < nitems(tty_default_xterm_modifiers); j++) {
496  strlcpy(copy, tdkx->template, sizeof copy);
497  copy[strcspn(copy, "_")] = '0' + j;
498 
500  tty_keys_add(tty, copy, key);
501  }
502  }
503  for (i = 0; i < nitems(tty_default_raw_keys); i++) {
504  tdkr = &tty_default_raw_keys[i];
505 
506  s = tdkr->string;
507  if (*s != '\0')
508  tty_keys_add(tty, s, tdkr->key);
509  }
510  for (i = 0; i < nitems(tty_default_code_keys); i++) {
511  tdkc = &tty_default_code_keys[i];
512 
513  s = tty_term_string(tty->term, tdkc->code);
514  if (*s != '\0')
515  tty_keys_add(tty, s, tdkc->key);
516 
517  }
518 
519  o = options_get(global_options, "user-keys");
520  if (o != NULL) {
521  a = options_array_first(o);
522  while (a != NULL) {
524  ov = options_array_item_value(a);
525  tty_keys_add(tty, ov->string, KEYC_USER + i);
526  a = options_array_next(a);
527  }
528  }
529 }
530 
531 /* Free the entire key tree. */
532 void
534 {
536 }
537 
538 /* Free a single key. */
539 static void
541 {
542  if (tk->next != NULL)
543  tty_keys_free1(tk->next);
544  if (tk->left != NULL)
545  tty_keys_free1(tk->left);
546  if (tk->right != NULL)
547  tty_keys_free1(tk->right);
548  free(tk);
549 }
550 
551 /* Lookup a key in the tree. */
552 static struct tty_key *
553 tty_keys_find(struct tty *tty, const char *buf, size_t len, size_t *size)
554 {
555  *size = 0;
556  return (tty_keys_find1(tty->key_tree, buf, len, size));
557 }
558 
559 /* Find the next node. */
560 static struct tty_key *
561 tty_keys_find1(struct tty_key *tk, const char *buf, size_t len, size_t *size)
562 {
563  /* If no data, no match. */
564  if (len == 0)
565  return (NULL);
566 
567  /* If the node is NULL, this is the end of the tree. No match. */
568  if (tk == NULL)
569  return (NULL);
570 
571  /* Pick the next in the sequence. */
572  if (tk->ch == *buf) {
573  /* Move forward in the string. */
574  buf++; len--;
575  (*size)++;
576 
577  /* At the end of the string, return the current node. */
578  if (len == 0 || (tk->next == NULL && tk->key != KEYC_UNKNOWN))
579  return (tk);
580 
581  /* Move into the next tree for the following character. */
582  tk = tk->next;
583  } else {
584  if (*buf < tk->ch)
585  tk = tk->left;
586  else if (*buf > tk->ch)
587  tk = tk->right;
588  }
589 
590  /* Move to the next in the tree. */
591  return (tty_keys_find1(tk, buf, len, size));
592 }
593 
594 /* Look up part of the next key. */
595 static int
596 tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key,
597  size_t *size, int expired)
598 {
599  struct client *c = tty->client;
600  struct tty_key *tk, *tk1;
601  struct utf8_data ud;
602  enum utf8_state more;
603  utf8_char uc;
604  u_int i;
605 
606  log_debug("%s: next key is %zu (%.*s) (expired=%d)", c->name, len,
607  (int)len, buf, expired);
608 
609  /* Is this a known key? */
610  tk = tty_keys_find(tty, buf, len, size);
611  if (tk != NULL && tk->key != KEYC_UNKNOWN) {
612  tk1 = tk;
613  do
614  log_debug("%s: keys in list: %#llx", c->name, tk1->key);
615  while ((tk1 = tk1->next) != NULL);
616  if (tk->next != NULL && !expired)
617  return (1);
618  *key = tk->key;
619  return (0);
620  }
621 
622  /* Is this valid UTF-8? */
623  more = utf8_open(&ud, (u_char)*buf);
624  if (more == UTF8_MORE) {
625  *size = ud.size;
626  if (len < ud.size) {
627  if (!expired)
628  return (1);
629  return (-1);
630  }
631  for (i = 1; i < ud.size; i++)
632  more = utf8_append(&ud, (u_char)buf[i]);
633  if (more != UTF8_DONE)
634  return (-1);
635 
636  if (utf8_from_data(&ud, &uc) != UTF8_DONE)
637  return (-1);
638  *key = uc;
639 
640  log_debug("%s: UTF-8 key %.*s %#llx", c->name, (int)ud.size,
641  ud.data, *key);
642  return (0);
643  }
644 
645  return (-1);
646 }
647 
648 /* Process at least one key in the buffer. Return 0 if no keys present. */
649 int
651 {
652  struct client *c = tty->client;
653  struct timeval tv;
654  const char *buf;
655  size_t len, size;
656  cc_t bspace;
657  int delay, expired = 0, n;
658  key_code key;
659  struct mouse_event m = { 0 };
660  struct key_event *event;
661 
662  /* Get key buffer. */
663  buf = EVBUFFER_DATA(tty->in);
664  len = EVBUFFER_LENGTH(tty->in);
665  if (len == 0)
666  return (0);
667  log_debug("%s: keys are %zu (%.*s)", c->name, len, (int)len, buf);
668 
669  /* Is this a clipboard response? */
670  switch (tty_keys_clipboard(tty, buf, len, &size)) {
671  case 0: /* yes */
672  key = KEYC_UNKNOWN;
673  goto complete_key;
674  case -1: /* no, or not valid */
675  break;
676  case 1: /* partial */
677  goto partial_key;
678  }
679 
680  /* Is this a device attributes response? */
681  switch (tty_keys_device_attributes(tty, buf, len, &size)) {
682  case 0: /* yes */
683  key = KEYC_UNKNOWN;
684  goto complete_key;
685  case -1: /* no, or not valid */
686  break;
687  case 1: /* partial */
688  goto partial_key;
689  }
690 
691  /* Is this an extended device attributes response? */
692  switch (tty_keys_extended_device_attributes(tty, buf, len, &size)) {
693  case 0: /* yes */
694  key = KEYC_UNKNOWN;
695  goto complete_key;
696  case -1: /* no, or not valid */
697  break;
698  case 1: /* partial */
699  goto partial_key;
700  }
701 
702  /* Is this a mouse key press? */
703  switch (tty_keys_mouse(tty, buf, len, &size, &m)) {
704  case 0: /* yes */
705  key = KEYC_MOUSE;
706  goto complete_key;
707  case -1: /* no, or not valid */
708  break;
709  case -2: /* yes, but we don't care. */
710  key = KEYC_MOUSE;
711  goto discard_key;
712  case 1: /* partial */
713  goto partial_key;
714  }
715 
716  /* Is this an extended key press? */
717  switch (tty_keys_extended_key(tty, buf, len, &size, &key)) {
718  case 0: /* yes */
719  goto complete_key;
720  case -1: /* no, or not valid */
721  break;
722  case 1: /* partial */
723  goto partial_key;
724  }
725 
726 first_key:
727  /* Try to lookup complete key. */
728  n = tty_keys_next1(tty, buf, len, &key, &size, expired);
729  if (n == 0) /* found */
730  goto complete_key;
731  if (n == 1)
732  goto partial_key;
733 
734  /*
735  * If not a complete key, look for key with an escape prefix (meta
736  * modifier).
737  */
738  if (*buf == '\033' && len > 1) {
739  /* Look for a key without the escape. */
740  n = tty_keys_next1(tty, buf + 1, len - 1, &key, &size, expired);
741  if (n == 0) { /* found */
742  if (key & KEYC_IMPLIED_META) {
743  /*
744  * We want the escape key as well as the xterm
745  * key, because the xterm sequence implicitly
746  * includes the escape (so if we see
747  * \033\033[1;3D we know it is an Escape
748  * followed by M-Left, not just M-Left).
749  */
750  key = '\033';
751  size = 1;
752  goto complete_key;
753  }
754  key |= KEYC_META;
755  size++;
756  goto complete_key;
757  }
758  if (n == 1) /* partial */
759  goto partial_key;
760  }
761 
762  /*
763  * At this point, we know the key is not partial (with or without
764  * escape). So pass it through even if the timer has not expired.
765  */
766  if (*buf == '\033' && len >= 2) {
767  key = (u_char)buf[1] | KEYC_META;
768  size = 2;
769  } else {
770  key = (u_char)buf[0];
771  size = 1;
772  }
773  goto complete_key;
774 
775 partial_key:
776  log_debug("%s: partial key %.*s", c->name, (int)len, buf);
777 
778  /* If timer is going, check for expiration. */
779  if (tty->flags & TTY_TIMER) {
780  if (evtimer_initialized(&tty->key_timer) &&
781  !evtimer_pending(&tty->key_timer, NULL)) {
782  expired = 1;
783  goto first_key;
784  }
785  return (0);
786  }
787 
788  /* Get the time period. */
789  delay = options_get_number(global_options, "escape-time");
790  tv.tv_sec = delay / 1000;
791  tv.tv_usec = (delay % 1000) * 1000L;
792 
793  /* Start the timer. */
794  if (event_initialized(&tty->key_timer))
795  evtimer_del(&tty->key_timer);
796  evtimer_set(&tty->key_timer, tty_keys_callback, tty);
797  evtimer_add(&tty->key_timer, &tv);
798 
799  tty->flags |= TTY_TIMER;
800  return (0);
801 
802 complete_key:
803  log_debug("%s: complete key %.*s %#llx", c->name, (int)size, buf, key);
804 
805  /*
806  * Check for backspace key using termios VERASE - the terminfo
807  * kbs entry is extremely unreliable, so cannot be safely
808  * used. termios should have a better idea.
809  */
810  bspace = tty->tio.c_cc[VERASE];
811  if (bspace != _POSIX_VDISABLE && (key & KEYC_MASK_KEY) == bspace)
813 
814  /* Remove data from buffer. */
815  evbuffer_drain(tty->in, size);
816 
817  /* Remove key timer. */
818  if (event_initialized(&tty->key_timer))
819  evtimer_del(&tty->key_timer);
820  tty->flags &= ~~TTY_TIMER;
821 
822  /* Check for focus events. */
823  if (key == KEYC_FOCUS_OUT)
824  tty->client->flags &= ~~CLIENT_FOCUSED;
825  else if (key == KEYC_FOCUS_IN)
827 
828  /* Fire the key. */
829  if (key != KEYC_UNKNOWN) {
830  event = xmalloc(sizeof *event);
831  event->key = key;
832  memcpy(&event->m, &m, sizeof event->m);
833  if (!server_client_handle_key(c, event))
834  free(event);
835  }
836 
837  return (1);
838 
839 discard_key:
840  log_debug("%s: discard key %.*s %#llx", c->name, (int)size, buf, key);
841 
842  /* Remove data from buffer. */
843  evbuffer_drain(tty->in, size);
844 
845  return (1);
846 }
847 
848 /* Key timer callback. */
849 static void
850 tty_keys_callback(__unused int fd, __unused short events, void *data)
851 {
852  struct tty *tty = data;
853 
854  if (tty->flags & TTY_TIMER) {
855  while (tty_keys_next(tty))
856  ;
857  }
858 }
859 
860 /*
861  * Handle extended key input. This has two forms: \033[27;m;k~ and \033[k;mu,
862  * where k is key as a number and m is a modifier. Returns 0 for success, -1
863  * for failure, 1 for partial;
864  */
865 static int
866 tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
867  size_t *size, key_code *key)
868 {
869  struct client *c = tty->client;
870  size_t end;
871  u_int number, modifiers;
872  char tmp[64];
873  cc_t bspace;
874  key_code nkey;
875  key_code onlykey;
876 
877  *size = 0;
878 
879  /* First two bytes are always \033[. */
880  if (buf[0] != '\033')
881  return (-1);
882  if (len == 1)
883  return (1);
884  if (buf[1] != '[')
885  return (-1);
886  if (len == 2)
887  return (1);
888 
889  /*
890  * Look for a terminator. Stop at either '~' or anything that isn't a
891  * number or ';'.
892  */
893  for (end = 2; end < len && end != sizeof tmp; end++) {
894  if (buf[end] == '~')
895  break;
896  if (!isdigit((u_char)buf[end]) && buf[end] != ';')
897  break;
898  }
899  if (end == len)
900  return (1);
901  if (end == sizeof tmp || (buf[end] != '~' && buf[end] != 'u'))
902  return (-1);
903 
904  /* Copy to the buffer. */
905  memcpy(tmp, buf + 2, end);
906  tmp[end] = '\0';
907 
908  /* Try to parse either form of key. */
909  if (buf[end] == '~') {
910  if (sscanf(tmp, "27;%u;%u", &modifiers, &number) != 2)
911  return (-1);
912  } else {
913  if (sscanf(tmp ,"%u;%u", &number, &modifiers) != 2)
914  return (-1);
915  }
916  *size = end + 1;
917 
918  /* Store the key. */
919  bspace = tty->tio.c_cc[VERASE];
920  if (bspace != _POSIX_VDISABLE && number == bspace)
921  nkey = KEYC_BSPACE;
922  else
923  nkey = number;
924 
925  /* Update the modifiers. */
926  switch (modifiers) {
927  case 2:
928  nkey |= KEYC_SHIFT;
929  break;
930  case 3:
931  nkey |= (KEYC_META|KEYC_IMPLIED_META);
932  break;
933  case 4:
935  break;
936  case 5:
937  nkey |= KEYC_CTRL;
938  break;
939  case 6:
940  nkey |= (KEYC_SHIFT|KEYC_CTRL);
941  break;
942  case 7:
943  nkey |= (KEYC_META|KEYC_CTRL);
944  break;
945  case 8:
947  break;
948  case 9:
949  nkey |= (KEYC_META|KEYC_IMPLIED_META);
950  break;
951  default:
952  *key = KEYC_NONE;
953  break;
954  }
955 
956  /*
957  * Don't allow both KEYC_CTRL and as an implied modifier. Also convert
958  * C-X into C-x and so on.
959  */
960  if (nkey & KEYC_CTRL) {
961  onlykey = (nkey & KEYC_MASK_KEY);
962  if (onlykey < 32 &&
963  onlykey != 9 &&
964  onlykey != 13 &&
965  onlykey != 27)
966  /* nothing */;
967  else if (onlykey >= 97 && onlykey <= 122)
968  onlykey -= 96;
969  else if (onlykey >= 64 && onlykey <= 95)
970  onlykey -= 64;
971  else if (onlykey == 32)
972  onlykey = 0;
973  else if (onlykey == 63)
974  onlykey = 127;
975  else
976  onlykey |= KEYC_CTRL;
977  nkey = onlykey|((nkey & KEYC_MASK_MODIFIERS) & ~KEYC_CTRL);
978  }
979 
980  if (log_get_level() != 0) {
981  log_debug("%s: extended key %.*s is %llx (%s)", c->name,
982  (int)*size, buf, nkey, key_string_lookup_key(nkey, 1));
983  }
984  *key = nkey;
985  return (0);
986 }
987 
988 /*
989  * Handle mouse key input. Returns 0 for success, -1 for failure, 1 for partial
990  * (probably a mouse sequence but need more data).
991  */
992 static int
993 tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size,
994  struct mouse_event *m)
995 {
996  struct client *c = tty->client;
997  u_int i, x, y, b, sgr_b;
998  u_char sgr_type, ch;
999 
1000  /*
1001  * Standard mouse sequences are \033[M followed by three characters
1002  * indicating button, X and Y, all based at 32 with 1,1 top-left.
1003  *
1004  * UTF-8 mouse sequences are similar but the three are expressed as
1005  * UTF-8 characters.
1006  *
1007  * SGR extended mouse sequences are \033[< followed by three numbers in
1008  * decimal and separated by semicolons indicating button, X and Y. A
1009  * trailing 'M' is click or scroll and trailing 'm' release. All are
1010  * based at 0 with 1,1 top-left.
1011  */
1012 
1013  *size = 0;
1014  x = y = b = sgr_b = 0;
1015  sgr_type = ' ';
1016 
1017  /* First two bytes are always \033[. */
1018  if (buf[0] != '\033')
1019  return (-1);
1020  if (len == 1)
1021  return (1);
1022  if (buf[1] != '[')
1023  return (-1);
1024  if (len == 2)
1025  return (1);
1026 
1027  /*
1028  * Third byte is M in old standard (and UTF-8 extension which we do not
1029  * support), < in SGR extension.
1030  */
1031  if (buf[2] == 'M') {
1032  /* Read the three inputs. */
1033  *size = 3;
1034  for (i = 0; i < 3; i++) {
1035  if (len <= *size)
1036  return (1);
1037  ch = (u_char)buf[(*size)++];
1038  if (i == 0)
1039  b = ch;
1040  else if (i == 1)
1041  x = ch;
1042  else
1043  y = ch;
1044  }
1045  log_debug("%s: mouse input: %.*s", c->name, (int)*size, buf);
1046 
1047  /* Check and return the mouse input. */
1048  if (b < 32)
1049  return (-1);
1050  b -= 32;
1051  if (x >= 33)
1052  x -= 33;
1053  else
1054  x = 256 - x;
1055  if (y >= 33)
1056  y -= 33;
1057  else
1058  y = 256 - y;
1059  } else if (buf[2] == '<') {
1060  /* Read the three inputs. */
1061  *size = 3;
1062  while (1) {
1063  if (len <= *size)
1064  return (1);
1065  ch = (u_char)buf[(*size)++];
1066  if (ch == ';')
1067  break;
1068  if (ch < '0' || ch > '9')
1069  return (-1);
1070  sgr_b = 10 * sgr_b + (ch - '0');
1071  }
1072  while (1) {
1073  if (len <= *size)
1074  return (1);
1075  ch = (u_char)buf[(*size)++];
1076  if (ch == ';')
1077  break;
1078  if (ch < '0' || ch > '9')
1079  return (-1);
1080  x = 10 * x + (ch - '0');
1081  }
1082  while (1) {
1083  if (len <= *size)
1084  return (1);
1085  ch = (u_char)buf[(*size)++];
1086  if (ch == 'M' || ch == 'm')
1087  break;
1088  if (ch < '0' || ch > '9')
1089  return (-1);
1090  y = 10 * y + (ch - '0');
1091  }
1092  log_debug("%s: mouse input (SGR): %.*s", c->name, (int)*size,
1093  buf);
1094 
1095  /* Check and return the mouse input. */
1096  if (x < 1 || y < 1)
1097  return (-1);
1098  x--;
1099  y--;
1100  b = sgr_b;
1101 
1102  /* Type is M for press, m for release. */
1103  sgr_type = ch;
1104  if (sgr_type == 'm')
1105  b |= 3;
1106 
1107  /*
1108  * Some terminals (like PuTTY 0.63) mistakenly send
1109  * button-release events for scroll-wheel button-press event.
1110  * Discard it before it reaches any program running inside
1111  * tmux.
1112  */
1113  if (sgr_type == 'm' && (sgr_b & 64))
1114  return (-2);
1115  } else
1116  return (-1);
1117 
1118  /* Fill mouse event. */
1119  m->lx = tty->mouse_last_x;
1120  m->x = x;
1121  m->ly = tty->mouse_last_y;
1122  m->y = y;
1123  m->lb = tty->mouse_last_b;
1124  m->b = b;
1125  m->sgr_type = sgr_type;
1126  m->sgr_b = sgr_b;
1127 
1128  /* Update last mouse state. */
1129  tty->mouse_last_x = x;
1130  tty->mouse_last_y = y;
1131  tty->mouse_last_b = b;
1132 
1133  return (0);
1134 }
1135 
1136 /*
1137  * Handle OSC 52 clipboard input. Returns 0 for success, -1 for failure, 1 for
1138  * partial.
1139  */
1140 static int
1141 tty_keys_clipboard(__unused struct tty *tty, const char *buf, size_t len,
1142  size_t *size)
1143 {
1144  size_t end, terminator, needed;
1145  char *copy, *out;
1146  int outlen;
1147 
1148  *size = 0;
1149 
1150  /* First five bytes are always \033]52;. */
1151  if (buf[0] != '\033')
1152  return (-1);
1153  if (len == 1)
1154  return (1);
1155  if (buf[1] != ']')
1156  return (-1);
1157  if (len == 2)
1158  return (1);
1159  if (buf[2] != '5')
1160  return (-1);
1161  if (len == 3)
1162  return (1);
1163  if (buf[3] != '2')
1164  return (-1);
1165  if (len == 4)
1166  return (1);
1167  if (buf[4] != ';')
1168  return (-1);
1169  if (len == 5)
1170  return (1);
1171 
1172  /* Find the terminator if any. */
1173  for (end = 5; end < len; end++) {
1174  if (buf[end] == '\007') {
1175  terminator = 1;
1176  break;
1177  }
1178  if (end > 5 && buf[end - 1] == '\033' && buf[end] == '\\') {
1179  terminator = 2;
1180  break;
1181  }
1182  }
1183  if (end == len)
1184  return (1);
1185  *size = end + terminator;
1186 
1187  /* Skip the initial part. */
1188  buf += 5;
1189  end -= 5;
1190 
1191  /* Get the second argument. */
1192  while (end != 0 && *buf != ';') {
1193  buf++;
1194  end--;
1195  }
1196  if (end == 0 || end == 1)
1197  return (0);
1198  buf++;
1199  end--;
1200 
1201  /* It has to be a string so copy it. */
1202  copy = xmalloc(end + 1);
1203  memcpy(copy, buf, end);
1204  copy[end] = '\0';
1205 
1206  /* Convert from base64. */
1207  needed = (end / 4) * 3;
1208  out = xmalloc(needed);
1209  if ((outlen = b64_pton(copy, out, len)) == -1) {
1210  free(out);
1211  free(copy);
1212  return (0);
1213  }
1214  free(copy);
1215 
1216  /* Create a new paste buffer. */
1217  log_debug("%s: %.*s", __func__, outlen, out);
1218  paste_add(NULL, out, outlen);
1219 
1220  return (0);
1221 }
1222 
1223 /*
1224  * Handle secondary device attributes input. Returns 0 for success, -1 for
1225  * failure, 1 for partial.
1226  */
1227 static int
1228 tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
1229  size_t *size)
1230 {
1231  struct client *c = tty->client;
1232  u_int i, n = 0;
1233  char tmp[64], *endptr, p[32] = { 0 }, *cp, *next;
1234 
1235  *size = 0;
1236  if (tty->flags & TTY_HAVEDA)
1237  return (-1);
1238 
1239  /*
1240  * First three bytes are always \033[>. Some older Terminal.app
1241  * versions respond as for DA (\033[?) so accept and ignore that.
1242  */
1243  if (buf[0] != '\033')
1244  return (-1);
1245  if (len == 1)
1246  return (1);
1247  if (buf[1] != '[')
1248  return (-1);
1249  if (len == 2)
1250  return (1);
1251  if (buf[2] != '>' && buf[2] != '?')
1252  return (-1);
1253  if (len == 3)
1254  return (1);
1255 
1256  /* Copy the rest up to a 'c'. */
1257  for (i = 0; i < (sizeof tmp) - 1; i++) {
1258  if (3 + i == len)
1259  return (1);
1260  if (buf[3 + i] == 'c')
1261  break;
1262  tmp[i] = buf[3 + i];
1263  }
1264  if (i == (sizeof tmp) - 1)
1265  return (-1);
1266  tmp[i] = '\0';
1267  *size = 4 + i;
1268 
1269  /* Ignore DA response. */
1270  if (buf[2] == '?')
1271  return (0);
1272 
1273  /* Convert all arguments to numbers. */
1274  cp = tmp;
1275  while ((next = strsep(&cp, ";")) != NULL) {
1276  p[n] = strtoul(next, &endptr, 10);
1277  if (*endptr != '\0')
1278  p[n] = 0;
1279  n++;
1280  }
1281 
1282  /* Add terminal features. */
1283  switch (p[0]) {
1284  case 41: /* VT420 */
1285  tty_add_features(&c->term_features, "margins,rectfill", ",");
1286  break;
1287  case 'M': /* mintty */
1288  tty_default_features(&c->term_features, "mintty", 0);
1289  break;
1290  case 'T': /* tmux */
1291  tty_default_features(&c->term_features, "tmux", 0);
1292  break;
1293  case 'U': /* rxvt-unicode */
1294  tty_default_features(&c->term_features, "rxvt-unicode", 0);
1295  break;
1296  }
1297  log_debug("%s: received secondary DA %.*s", c->name, (int)*size, buf);
1298 
1300  tty->flags |= TTY_HAVEDA;
1301 
1302  return (0);
1303 }
1304 
1305 /*
1306  * Handle extended device attributes input. Returns 0 for success, -1 for
1307  * failure, 1 for partial.
1308  */
1309 static int
1311  size_t len, size_t *size)
1312 {
1313  struct client *c = tty->client;
1314  u_int i;
1315  char tmp[128];
1316 
1317  *size = 0;
1318  if (tty->flags & TTY_HAVEXDA)
1319  return (-1);
1320 
1321  /* First four bytes are always \033P>|. */
1322  if (buf[0] != '\033')
1323  return (-1);
1324  if (len == 1)
1325  return (1);
1326  if (buf[1] != 'P')
1327  return (-1);
1328  if (len == 2)
1329  return (1);
1330  if (buf[2] != '>')
1331  return (-1);
1332  if (len == 3)
1333  return (1);
1334  if (buf[3] != '|')
1335  return (-1);
1336  if (len == 4)
1337  return (1);
1338 
1339  /* Copy the rest up to a '\033\\'. */
1340  for (i = 0; i < (sizeof tmp) - 1; i++) {
1341  if (4 + i == len)
1342  return (1);
1343  if (buf[4 + i - 1] == '\033' && buf[4 + i] == '\\')
1344  break;
1345  tmp[i] = buf[4 + i];
1346  }
1347  if (i == (sizeof tmp) - 1)
1348  return (-1);
1349  tmp[i - 1] = '\0';
1350  *size = 5 + i;
1351 
1352  /* Add terminal features. */
1353  if (strncmp(tmp, "iTerm2 ", 7) == 0)
1354  tty_default_features(&c->term_features, "iTerm2", 0);
1355  else if (strncmp(tmp, "tmux ", 5) == 0)
1356  tty_default_features(&c->term_features, "tmux", 0);
1357  else if (strncmp(tmp, "XTerm(", 6) == 0)
1358  tty_default_features(&c->term_features, "XTerm", 0);
1359  else if (strncmp(tmp, "mintty ", 7) == 0)
1360  tty_default_features(&c->term_features, "mintty", 0);
1361  log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf);
1362 
1363  free(c->term_type);
1364  c->term_type = xstrdup(tmp);
1365 
1367  tty->flags |= TTY_HAVEXDA;
1368 
1369  return (0);
1370 }
#define __unused
Definition: compat.h:60
char * strsep(char **, const char *)
size_t strlcpy(char *, const char *, size_t)
int b64_pton(const char *, u_char *, size_t)
key_code key
Definition: key-string.c:32
const char * key_string_lookup_key(key_code key, int with_flags)
Definition: key-string.c:265
int log_get_level(void)
Definition: log.c:51
void log_debug(const char *msg,...)
Definition: log.c:130
union options_value * options_array_item_value(struct options_array_item *a)
Definition: options.c:549
struct options_array_item * options_array_first(struct options_entry *o)
Definition: options.c:529
long long options_get_number(struct options *oo, const char *name)
Definition: options.c:699
u_int options_array_item_index(struct options_array_item *a)
Definition: options.c:543
struct options_array_item * options_array_next(struct options_array_item *a)
Definition: options.c:537
struct options_entry * options_get(struct options *oo, const char *name)
Definition: options.c:229
#define nitems(_a)
void paste_add(const char *prefix, char *data, size_t size)
Definition: paste.c:160
int server_client_handle_key(struct client *c, struct key_event *event)
Definition: tmux.h:1608
char * term_type
Definition: tmux.h:1635
const char * name
Definition: tmux.h:1609
uint64_t flags
Definition: tmux.h:1703
int term_features
Definition: tmux.h:1634
struct mouse_event m
Definition: tmux.h:1268
key_code key
Definition: tmux.h:1267
u_int y
Definition: tmux.h:1247
u_int lx
Definition: tmux.h:1250
u_int b
Definition: tmux.h:1248
u_int sgr_type
Definition: tmux.h:1261
u_int x
Definition: tmux.h:1246
u_int ly
Definition: tmux.h:1251
u_int lb
Definition: tmux.h:1252
u_int sgr_b
Definition: tmux.h:1262
Definition: options.c:50
enum tty_code_code code
Definition: tty-keys.c:265
const char * string
Definition: tty-keys.c:63
const char * template
Definition: tty-keys.c:211
Definition: tmux.h:1272
struct tty_key * right
Definition: tmux.h:1277
struct tty_key * next
Definition: tmux.h:1279
struct tty_key * left
Definition: tmux.h:1276
key_code key
Definition: tmux.h:1274
char ch
Definition: tmux.h:1273
Definition: tmux.h:1304
struct tty_term * term
Definition: tmux.h:1357
u_int mouse_last_b
Definition: tmux.h:1361
struct termios tio
Definition: tmux.h:1339
u_int mouse_last_x
Definition: tmux.h:1359
int flags
Definition: tmux.h:1355
struct event key_timer
Definition: tmux.h:1368
struct evbuffer * in
Definition: tmux.h:1333
struct client * client
Definition: tmux.h:1305
struct tty_key * key_tree
Definition: tmux.h:1369
u_int mouse_last_y
Definition: tmux.h:1360
u_char data[21]
Definition: tmux.h:629
u_char size
Definition: tmux.h:632
struct options * global_options
Definition: tmux.c:36
void tty_add_features(int *, const char *, const char *)
Definition: tty-features.c:262
#define KEYC_UNKNOWN
Definition: tmux.h:114
tty_code_code
Definition: tmux.h:274
@ TTYC_KIC6
Definition: tmux.h:429
@ TTYC_KF7
Definition: tmux.h:415
@ TTYC_KEND4
Definition: tmux.h:351
@ TTYC_KF32
Definition: tmux.h:380
@ TTYC_KDC4
Definition: tmux.h:337
@ TTYC_KEND5
Definition: tmux.h:352
@ TTYC_KCUF1
Definition: tmux.h:333
@ TTYC_KF4
Definition: tmux.h:388
@ TTYC_KCUU1
Definition: tmux.h:334
@ TTYC_KF34
Definition: tmux.h:382
@ TTYC_KHOM2
Definition: tmux.h:418
@ TTYC_KRIT6
Definition: tmux.h:459
@ TTYC_KF13
Definition: tmux.h:359
@ TTYC_KF10
Definition: tmux.h:356
@ TTYC_KEND2
Definition: tmux.h:349
@ TTYC_KF15
Definition: tmux.h:361
@ TTYC_KPRV4
Definition: tmux.h:450
@ TTYC_KNXT2
Definition: tmux.h:441
@ TTYC_KF53
Definition: tmux.h:403
@ TTYC_KCUB1
Definition: tmux.h:331
@ TTYC_KIC5
Definition: tmux.h:428
@ TTYC_KF30
Definition: tmux.h:378
@ TTYC_KLFT7
Definition: tmux.h:438
@ TTYC_KRIT3
Definition: tmux.h:456
@ TTYC_KF26
Definition: tmux.h:373
@ TTYC_KF54
Definition: tmux.h:404
@ TTYC_KF36
Definition: tmux.h:384
@ TTYC_KF29
Definition: tmux.h:376
@ TTYC_KDN4
Definition: tmux.h:344
@ TTYC_KNXT6
Definition: tmux.h:445
@ TTYC_KEND3
Definition: tmux.h:350
@ TTYC_KF45
Definition: tmux.h:394
@ TTYC_KDC7
Definition: tmux.h:340
@ TTYC_KF51
Definition: tmux.h:401
@ TTYC_KF20
Definition: tmux.h:367
@ TTYC_KF31
Definition: tmux.h:379
@ TTYC_KF55
Definition: tmux.h:405
@ TTYC_KF3
Definition: tmux.h:377
@ TTYC_KCUD1
Definition: tmux.h:332
@ TTYC_KIND
Definition: tmux.h:432
@ TTYC_KF21
Definition: tmux.h:368
@ TTYC_KUP6
Definition: tmux.h:465
@ TTYC_KF9
Definition: tmux.h:417
@ TTYC_KNP
Definition: tmux.h:440
@ TTYC_KF27
Definition: tmux.h:374
@ TTYC_KF61
Definition: tmux.h:412
@ TTYC_KF44
Definition: tmux.h:393
@ TTYC_KF8
Definition: tmux.h:416
@ TTYC_KICH1
Definition: tmux.h:431
@ TTYC_KDN7
Definition: tmux.h:347
@ TTYC_KIC2
Definition: tmux.h:425
@ TTYC_KF33
Definition: tmux.h:381
@ TTYC_KF24
Definition: tmux.h:371
@ TTYC_KDN5
Definition: tmux.h:345
@ TTYC_KLFT3
Definition: tmux.h:434
@ TTYC_KRIT2
Definition: tmux.h:455
@ TTYC_KF42
Definition: tmux.h:391
@ TTYC_KRIT7
Definition: tmux.h:460
@ TTYC_KRIT4
Definition: tmux.h:457
@ TTYC_KF37
Definition: tmux.h:385
@ TTYC_KNXT4
Definition: tmux.h:443
@ TTYC_KPRV3
Definition: tmux.h:449
@ TTYC_KIC7
Definition: tmux.h:430
@ TTYC_KIC4
Definition: tmux.h:427
@ TTYC_KPP
Definition: tmux.h:447
@ TTYC_KF38
Definition: tmux.h:386
@ TTYC_KHOM7
Definition: tmux.h:423
@ TTYC_KDC5
Definition: tmux.h:338
@ TTYC_KF63
Definition: tmux.h:414
@ TTYC_KHOM4
Definition: tmux.h:420
@ TTYC_KF11
Definition: tmux.h:357
@ TTYC_KDN6
Definition: tmux.h:346
@ TTYC_KLFT5
Definition: tmux.h:436
@ TTYC_KRIT5
Definition: tmux.h:458
@ TTYC_KF48
Definition: tmux.h:397
@ TTYC_KF62
Definition: tmux.h:413
@ TTYC_KF18
Definition: tmux.h:364
@ TTYC_KF56
Definition: tmux.h:406
@ TTYC_KDCH1
Definition: tmux.h:341
@ TTYC_KHOM5
Definition: tmux.h:421
@ TTYC_KF59
Definition: tmux.h:409
@ TTYC_KF46
Definition: tmux.h:395
@ TTYC_KF35
Definition: tmux.h:383
@ TTYC_KIC3
Definition: tmux.h:426
@ TTYC_KF47
Definition: tmux.h:396
@ TTYC_KF28
Definition: tmux.h:375
@ TTYC_KHOM6
Definition: tmux.h:422
@ TTYC_KLFT2
Definition: tmux.h:433
@ TTYC_KLFT4
Definition: tmux.h:435
@ TTYC_KPRV2
Definition: tmux.h:448
@ TTYC_KF16
Definition: tmux.h:362
@ TTYC_KF50
Definition: tmux.h:400
@ TTYC_KUP3
Definition: tmux.h:462
@ TTYC_KF60
Definition: tmux.h:411
@ TTYC_KF14
Definition: tmux.h:360
@ TTYC_KEND6
Definition: tmux.h:353
@ TTYC_KF57
Definition: tmux.h:407
@ TTYC_KRI
Definition: tmux.h:454
@ TTYC_KNXT7
Definition: tmux.h:446
@ TTYC_KF19
Definition: tmux.h:365
@ TTYC_KF49
Definition: tmux.h:398
@ TTYC_KUP5
Definition: tmux.h:464
@ TTYC_KNXT3
Definition: tmux.h:442
@ TTYC_KF2
Definition: tmux.h:366
@ TTYC_KDC3
Definition: tmux.h:336
@ TTYC_KF5
Definition: tmux.h:399
@ TTYC_KF25
Definition: tmux.h:372
@ TTYC_KPRV7
Definition: tmux.h:453
@ TTYC_KF12
Definition: tmux.h:358
@ TTYC_KHOME
Definition: tmux.h:424
@ TTYC_KUP2
Definition: tmux.h:461
@ TTYC_KF43
Definition: tmux.h:392
@ TTYC_KF23
Definition: tmux.h:370
@ TTYC_KDC6
Definition: tmux.h:339
@ TTYC_KLFT6
Definition: tmux.h:437
@ TTYC_KEND
Definition: tmux.h:348
@ TTYC_KCBT
Definition: tmux.h:330
@ TTYC_KF39
Definition: tmux.h:387
@ TTYC_KF22
Definition: tmux.h:369
@ TTYC_KPRV6
Definition: tmux.h:452
@ TTYC_KDN3
Definition: tmux.h:343
@ TTYC_KF17
Definition: tmux.h:363
@ TTYC_KF58
Definition: tmux.h:408
@ TTYC_KDC2
Definition: tmux.h:335
@ TTYC_KF41
Definition: tmux.h:390
@ TTYC_KF40
Definition: tmux.h:389
@ TTYC_KF52
Definition: tmux.h:402
@ TTYC_KF6
Definition: tmux.h:410
@ TTYC_KEND7
Definition: tmux.h:354
@ TTYC_KPRV5
Definition: tmux.h:451
@ TTYC_KUP4
Definition: tmux.h:463
@ TTYC_KNXT5
Definition: tmux.h:444
@ TTYC_KHOM3
Definition: tmux.h:419
@ TTYC_KUP7
Definition: tmux.h:466
@ TTYC_KDN2
Definition: tmux.h:342
@ TTYC_KF1
Definition: tmux.h:355
void tty_default_features(int *, const char *, u_int)
Definition: tty-features.c:344
#define KEYC_META
Definition: tmux.h:124
#define KEYC_SHIFT
Definition: tmux.h:126
u_int utf8_char
Definition: tmux.h:620
#define KEYC_CTRL
Definition: tmux.h:125
void tty_update_features(struct tty *)
Definition: tty.c:452
enum utf8_state utf8_from_data(const struct utf8_data *, utf8_char *)
Definition: utf8.c:127
#define TTY_HAVEDA
Definition: tmux.h:1352
#define KEYC_CURSOR
Definition: tmux.h:131
const char * tty_term_string(struct tty_term *, enum tty_code_code)
Definition: tty-term.c:752
enum utf8_state utf8_open(struct utf8_data *, u_char)
Definition: utf8.c:266
unsigned long long key_code
Definition: tmux.h:177
#define KEYC_NONE
Definition: tmux.h:113
#define CLIENT_FOCUSED
Definition: tmux.h:1669
#define KEYC_KEYPAD
Definition: tmux.h:130
#define KEYC_USER
Definition: tmux.h:121
utf8_state
Definition: tmux.h:636
@ UTF8_DONE
Definition: tmux.h:638
@ UTF8_MORE
Definition: tmux.h:637
@ KEYC_F6
Definition: tmux.h:230
@ KEYC_KP_FOUR
Definition: tmux.h:259
@ KEYC_HOME
Definition: tmux.h:239
@ KEYC_F5
Definition: tmux.h:229
@ KEYC_F7
Definition: tmux.h:231
@ KEYC_UP
Definition: tmux.h:246
@ KEYC_MOUSE
Definition: tmux.h:193
@ KEYC_F11
Definition: tmux.h:235
@ KEYC_F12
Definition: tmux.h:236
@ KEYC_BTAB
Definition: tmux.h:243
@ KEYC_F2
Definition: tmux.h:226
@ KEYC_F9
Definition: tmux.h:233
@ KEYC_KP_PERIOD
Definition: tmux.h:267
@ KEYC_IC
Definition: tmux.h:237
@ KEYC_END
Definition: tmux.h:240
@ KEYC_KP_FIVE
Definition: tmux.h:260
@ KEYC_F4
Definition: tmux.h:228
@ KEYC_F1
Definition: tmux.h:225
@ KEYC_LEFT
Definition: tmux.h:248
@ KEYC_PPAGE
Definition: tmux.h:242
@ KEYC_KP_ZERO
Definition: tmux.h:266
@ KEYC_KP_STAR
Definition: tmux.h:253
@ KEYC_KP_THREE
Definition: tmux.h:264
@ KEYC_FOCUS_OUT
Definition: tmux.h:183
@ KEYC_DOWN
Definition: tmux.h:247
@ KEYC_F3
Definition: tmux.h:227
@ KEYC_KP_EIGHT
Definition: tmux.h:256
@ KEYC_KP_TWO
Definition: tmux.h:263
@ KEYC_KP_MINUS
Definition: tmux.h:254
@ KEYC_KP_PLUS
Definition: tmux.h:258
@ KEYC_KP_SIX
Definition: tmux.h:261
@ KEYC_PASTE_START
Definition: tmux.h:189
@ KEYC_F8
Definition: tmux.h:232
@ KEYC_BSPACE
Definition: tmux.h:222
@ KEYC_NPAGE
Definition: tmux.h:241
@ KEYC_KP_SEVEN
Definition: tmux.h:255
@ KEYC_DC
Definition: tmux.h:238
@ KEYC_KP_ENTER
Definition: tmux.h:265
@ KEYC_KP_SLASH
Definition: tmux.h:252
@ KEYC_PASTE_END
Definition: tmux.h:190
@ KEYC_KP_ONE
Definition: tmux.h:262
@ KEYC_F10
Definition: tmux.h:234
@ KEYC_RIGHT
Definition: tmux.h:249
@ KEYC_FOCUS_IN
Definition: tmux.h:182
@ KEYC_KP_NINE
Definition: tmux.h:257
#define KEYC_MASK_MODIFIERS
Definition: tmux.h:136
#define TTY_TIMER
Definition: tmux.h:1346
#define KEYC_MASK_KEY
Definition: tmux.h:138
enum utf8_state utf8_append(struct utf8_data *, u_char)
Definition: utf8.c:283
#define KEYC_IMPLIED_META
Definition: tmux.h:132
#define TTY_HAVEXDA
Definition: tmux.h:1353
static void tty_keys_free1(struct tty_key *)
Definition: tty-keys.c:540
void tty_keys_build(struct tty *tty)
Definition: tty-keys.c:476
int tty_keys_next(struct tty *tty)
Definition: tty-keys.c:650
void tty_keys_free(struct tty *tty)
Definition: tty-keys.c:533
static struct tty_key * tty_keys_find1(struct tty_key *, const char *, size_t, size_t *)
Definition: tty-keys.c:561
static const struct tty_default_key_code tty_default_code_keys[]
Definition: tty-keys.c:268
static int tty_keys_extended_key(struct tty *, const char *, size_t, size_t *, key_code *)
Definition: tty-keys.c:866
static int tty_keys_extended_device_attributes(struct tty *, const char *, size_t, size_t *)
Definition: tty-keys.c:1310
static void tty_keys_callback(int, short, void *)
Definition: tty-keys.c:850
static int tty_keys_device_attributes(struct tty *, const char *, size_t, size_t *)
Definition: tty-keys.c:1228
static void tty_keys_add(struct tty *, const char *, key_code)
Definition: tty-keys.c:420
static const struct tty_default_key_xterm tty_default_xterm_keys[]
Definition: tty-keys.c:214
static const key_code tty_default_xterm_modifiers[]
Definition: tty-keys.c:246
static int tty_keys_mouse(struct tty *, const char *, size_t, size_t *, struct mouse_event *)
Definition: tty-keys.c:993
static const struct tty_default_key_raw tty_default_raw_keys[]
Definition: tty-keys.c:66
static int tty_keys_next1(struct tty *, const char *, size_t, key_code *, size_t *, int)
Definition: tty-keys.c:596
static int tty_keys_clipboard(struct tty *, const char *, size_t, size_t *)
Definition: tty-keys.c:1141
static struct tty_key * tty_keys_find(struct tty *, const char *, size_t, size_t *)
Definition: tty-keys.c:553
static void tty_keys_add1(struct tty_key **, const char *, key_code)
Definition: tty-keys.c:438
char * string
Definition: tmux.h:1802
void * xmalloc(size_t size)
Definition: xmalloc.c:27
void * xcalloc(size_t nmemb, size_t size)
Definition: xmalloc.c:41
char * xstrdup(const char *str)
Definition: xmalloc.c:89