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-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 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "tmux.h"
25 
26 /*
27  * This file is rather misleadingly named, it contains the code which takes a
28  * key code and translates it into something suitable to be sent to the
29  * application running in a pane (similar to input.c does in the other
30  * direction with output).
31  */
32 
33 static void input_key_mouse(struct window_pane *, struct mouse_event *);
34 
35 /* Entry in the key tree. */
38  const char *data;
39 
40  RB_ENTRY(input_key_entry) entry;
41 };
43 
44 /* Tree of input keys. */
45 static int input_key_cmp(struct input_key_entry *,
46  struct input_key_entry *);
48 struct input_key_tree input_key_tree = RB_INITIALIZER(&input_key_tree);
49 
50 /* List of default keys, the tree is built from this. */
51 static struct input_key_entry input_key_defaults[] = {
52  /* Paste keys. */
53  { .key = KEYC_PASTE_START,
54  .data = "\033[200~"
55  },
56  { .key = KEYC_PASTE_END,
57  .data = "\033[201~"
58  },
59 
60  /* Function keys. */
61  { .key = KEYC_F1,
62  .data = "\033OP"
63  },
64  { .key = KEYC_F2,
65  .data = "\033OQ"
66  },
67  { .key = KEYC_F3,
68  .data = "\033OR"
69  },
70  { .key = KEYC_F4,
71  .data = "\033OS"
72  },
73  { .key = KEYC_F5,
74  .data = "\033[15~"
75  },
76  { .key = KEYC_F6,
77  .data = "\033[17~"
78  },
79  { .key = KEYC_F7,
80  .data = "\033[18~"
81  },
82  { .key = KEYC_F8,
83  .data = "\033[19~"
84  },
85  { .key = KEYC_F9,
86  .data = "\033[20~"
87  },
88  { .key = KEYC_F10,
89  .data = "\033[21~"
90  },
91  { .key = KEYC_F11,
92  .data = "\033[23~"
93  },
94  { .key = KEYC_F12,
95  .data = "\033[24~"
96  },
97  { .key = KEYC_IC,
98  .data = "\033[2~"
99  },
100  { .key = KEYC_DC,
101  .data = "\033[3~"
102  },
103  { .key = KEYC_HOME,
104  .data = "\033[1~"
105  },
106  { .key = KEYC_END,
107  .data = "\033[4~"
108  },
109  { .key = KEYC_NPAGE,
110  .data = "\033[6~"
111  },
112  { .key = KEYC_PPAGE,
113  .data = "\033[5~"
114  },
115  { .key = KEYC_BTAB,
116  .data = "\033[Z"
117  },
118 
119  /* Arrow keys. */
120  { .key = KEYC_UP|KEYC_CURSOR,
121  .data = "\033OA"
122  },
123  { .key = KEYC_DOWN|KEYC_CURSOR,
124  .data = "\033OB"
125  },
126  { .key = KEYC_RIGHT|KEYC_CURSOR,
127  .data = "\033OC"
128  },
129  { .key = KEYC_LEFT|KEYC_CURSOR,
130  .data = "\033OD"
131  },
132  { .key = KEYC_UP,
133  .data = "\033[A"
134  },
135  { .key = KEYC_DOWN,
136  .data = "\033[B"
137  },
138  { .key = KEYC_RIGHT,
139  .data = "\033[C"
140  },
141  { .key = KEYC_LEFT,
142  .data = "\033[D"
143  },
144 
145  /* Keypad keys. */
146  { .key = KEYC_KP_SLASH|KEYC_KEYPAD,
147  .data = "\033Oo"
148  },
149  { .key = KEYC_KP_STAR|KEYC_KEYPAD,
150  .data = "\033Oj"
151  },
152  { .key = KEYC_KP_MINUS|KEYC_KEYPAD,
153  .data = "\033Om"
154  },
155  { .key = KEYC_KP_SEVEN|KEYC_KEYPAD,
156  .data = "\033Ow"
157  },
158  { .key = KEYC_KP_EIGHT|KEYC_KEYPAD,
159  .data = "\033Ox"
160  },
161  { .key = KEYC_KP_NINE|KEYC_KEYPAD,
162  .data = "\033Oy"
163  },
164  { .key = KEYC_KP_PLUS|KEYC_KEYPAD,
165  .data = "\033Ok"
166  },
167  { .key = KEYC_KP_FOUR|KEYC_KEYPAD,
168  .data = "\033Ot"
169  },
170  { .key = KEYC_KP_FIVE|KEYC_KEYPAD,
171  .data = "\033Ou"
172  },
173  { .key = KEYC_KP_SIX|KEYC_KEYPAD,
174  .data = "\033Ov"
175  },
176  { .key = KEYC_KP_ONE|KEYC_KEYPAD,
177  .data = "\033Oq"
178  },
179  { .key = KEYC_KP_TWO|KEYC_KEYPAD,
180  .data = "\033Or"
181  },
182  { .key = KEYC_KP_THREE|KEYC_KEYPAD,
183  .data = "\033Os"
184  },
185  { .key = KEYC_KP_ENTER|KEYC_KEYPAD,
186  .data = "\033OM"
187  },
188  { .key = KEYC_KP_ZERO|KEYC_KEYPAD,
189  .data = "\033Op"
190  },
191  { .key = KEYC_KP_PERIOD|KEYC_KEYPAD,
192  .data = "\033On"
193  },
194  { .key = KEYC_KP_SLASH,
195  .data = "/"
196  },
197  { .key = KEYC_KP_STAR,
198  .data = "*"
199  },
200  { .key = KEYC_KP_MINUS,
201  .data = "-"
202  },
203  { .key = KEYC_KP_SEVEN,
204  .data = "7"
205  },
206  { .key = KEYC_KP_EIGHT,
207  .data = "8"
208  },
209  { .key = KEYC_KP_NINE,
210  .data = "9"
211  },
212  { .key = KEYC_KP_PLUS,
213  .data = "+"
214  },
215  { .key = KEYC_KP_FOUR,
216  .data = "4"
217  },
218  { .key = KEYC_KP_FIVE,
219  .data = "5"
220  },
221  { .key = KEYC_KP_SIX,
222  .data = "6"
223  },
224  { .key = KEYC_KP_ONE,
225  .data = "1"
226  },
227  { .key = KEYC_KP_TWO,
228  .data = "2"
229  },
230  { .key = KEYC_KP_THREE,
231  .data = "3"
232  },
233  { .key = KEYC_KP_ENTER,
234  .data = "\n"
235  },
236  { .key = KEYC_KP_ZERO,
237  .data = "0"
238  },
239  { .key = KEYC_KP_PERIOD,
240  .data = "."
241  },
242 
243  /* Keys with an embedded modifier. */
244  { .key = KEYC_F1|KEYC_BUILD_MODIFIERS,
245  .data = "\033[1;_P"
246  },
247  { .key = KEYC_F2|KEYC_BUILD_MODIFIERS,
248  .data = "\033[1;_Q"
249  },
250  { .key = KEYC_F3|KEYC_BUILD_MODIFIERS,
251  .data = "\033[1;_R"
252  },
253  { .key = KEYC_F4|KEYC_BUILD_MODIFIERS,
254  .data = "\033[1;_S"
255  },
256  { .key = KEYC_F5|KEYC_BUILD_MODIFIERS,
257  .data = "\033[15;_~"
258  },
259  { .key = KEYC_F6|KEYC_BUILD_MODIFIERS,
260  .data = "\033[17;_~"
261  },
262  { .key = KEYC_F7|KEYC_BUILD_MODIFIERS,
263  .data = "\033[18;_~"
264  },
265  { .key = KEYC_F8|KEYC_BUILD_MODIFIERS,
266  .data = "\033[19;_~"
267  },
268  { .key = KEYC_F9|KEYC_BUILD_MODIFIERS,
269  .data = "\033[20;_~"
270  },
272  .data = "\033[21;_~"
273  },
275  .data = "\033[23;_~"
276  },
278  .data = "\033[24;_~"
279  },
280  { .key = KEYC_UP|KEYC_BUILD_MODIFIERS,
281  .data = "\033[1;_A"
282  },
284  .data = "\033[1;_B"
285  },
287  .data = "\033[1;_C"
288  },
290  .data = "\033[1;_D"
291  },
293  .data = "\033[1;_H"
294  },
296  .data = "\033[1;_F"
297  },
299  .data = "\033[5;_~"
300  },
302  .data = "\033[6;_~"
303  },
304  { .key = KEYC_IC|KEYC_BUILD_MODIFIERS,
305  .data = "\033[2;_~"
306  },
307  { .key = KEYC_DC|KEYC_BUILD_MODIFIERS,
308  .data = "\033[3;_~"
309  }
310 };
311 static const key_code input_key_modifiers[] = {
312  0,
313  0,
314  KEYC_SHIFT,
317  KEYC_CTRL,
321 };
322 
323 /* Input key comparison function. */
324 static int
325 input_key_cmp(struct input_key_entry *ike1, struct input_key_entry *ike2)
326 {
327  if (ike1->key < ike2->key)
328  return (-1);
329  if (ike1->key > ike2->key)
330  return (1);
331  return (0);
332 }
333 
334 /* Look for key in tree. */
335 static struct input_key_entry *
337 {
338  struct input_key_entry entry = { .key = key };
339 
340  return (RB_FIND(input_key_tree, &input_key_tree, &entry));
341 }
342 
343 /* Split a character into two UTF-8 bytes. */
344 static size_t
345 input_key_split2(u_int c, u_char *dst)
346 {
347  if (c > 0x7f) {
348  dst[0] = (c >> 6) | 0xc0;
349  dst[1] = (c & 0x3f) | 0x80;
350  return (2);
351  }
352  dst[0] = c;
353  return (1);
354 }
355 
356 /* Build input key tree. */
357 void
359 {
360  struct input_key_entry *ike, *new;
361  u_int i, j;
362  char *data;
363  key_code key;
364 
365  for (i = 0; i < nitems(input_key_defaults); i++) {
366  ike = &input_key_defaults[i];
367  if (~ike->key & KEYC_BUILD_MODIFIERS) {
368  RB_INSERT(input_key_tree, &input_key_tree, ike);
369  continue;
370  }
371 
372  for (j = 2; j < nitems(input_key_modifiers); j++) {
373  key = (ike->key & ~~KEYC_BUILD_MODIFIERS);
374  data = xstrdup(ike->data);
375  data[strcspn(data, "_")] = '0' + j;
376 
377  new = xcalloc(1, sizeof *new);
378  new->key = key|input_key_modifiers[j];
379  new->data = data;
380  RB_INSERT(input_key_tree, &input_key_tree, new);
381  }
382  }
383 
384  RB_FOREACH(ike, input_key_tree, &input_key_tree) {
385  log_debug("%s: 0x%llx (%s) is %s", __func__, ike->key,
386  key_string_lookup_key(ike->key, 1), ike->data);
387  }
388 }
389 
390 /* Translate a key code into an output key sequence for a pane. */
391 int
393 {
394  if (log_get_level() != 0) {
395  log_debug("writing key 0x%llx (%s) to %%%u", key,
396  key_string_lookup_key(key, 1), wp->id);
397  }
398 
399  if (KEYC_IS_MOUSE(key)) {
400  if (m != NULL && m->wp != -1 && (u_int)m->wp == wp->id)
401  input_key_mouse(wp, m);
402  return (0);
403  }
404  return (input_key(wp->screen, wp->event, key));
405 }
406 
407 static void
408 input_key_write(const char *from, struct bufferevent *bev, const char *data,
409  size_t size)
410 {
411  log_debug("%s: %.*s", from, (int)size, data);
412  bufferevent_write(bev, data, size);
413 }
414 
415 /* Translate a key code into an output key sequence. */
416 int
417 input_key(struct screen *s, struct bufferevent *bev, key_code key)
418 {
419  struct input_key_entry *ike;
420  key_code justkey, newkey, outkey;
421  struct utf8_data ud;
422  char tmp[64], modifier;
423 
424  /* Mouse keys need a pane. */
425  if (KEYC_IS_MOUSE(key))
426  return (0);
427 
428  /* Literal keys go as themselves (can't be more than eight bits). */
429  if (key & KEYC_LITERAL) {
430  ud.data[0] = (u_char)key;
431  input_key_write(__func__, bev, &ud.data[0], 1);
432  return (0);
433  }
434 
435  /* Is this backspace? */
436  if ((key & KEYC_MASK_KEY) == KEYC_BSPACE) {
437  newkey = options_get_number(global_options, "backspace");
438  if (newkey >= 0x7f)
439  newkey = '\177';
441  }
442 
443  /*
444  * If this is a normal 7-bit key, just send it, with a leading escape
445  * if necessary. If it is a UTF-8 key, split it and send it.
446  */
447  justkey = (key & ~(KEYC_META|KEYC_IMPLIED_META));
448  if (justkey <= 0x7f) {
449  if (key & KEYC_META)
450  input_key_write(__func__, bev, "\033", 1);
451  ud.data[0] = justkey;
452  input_key_write(__func__, bev, &ud.data[0], 1);
453  return (0);
454  }
455  if (KEYC_IS_UNICODE(justkey)) {
456  if (key & KEYC_META)
457  input_key_write(__func__, bev, "\033", 1);
458  utf8_to_data(justkey, &ud);
459  input_key_write(__func__, bev, ud.data, ud.size);
460  return (0);
461  }
462 
463  /*
464  * Look up in the tree. If not in application keypad or cursor mode,
465  * remove the flags from the key.
466  */
467  if (~s->mode & MODE_KKEYPAD)
468  key &= ~~KEYC_KEYPAD;
469  if (~s->mode & MODE_KCURSOR)
470  key &= ~~KEYC_CURSOR;
471  ike = input_key_get(key);
472  if (ike == NULL && (key & KEYC_META) && (~key & KEYC_IMPLIED_META))
473  ike = input_key_get(key & ~KEYC_META);
474  if (ike == NULL && (key & KEYC_CURSOR))
475  ike = input_key_get(key & ~KEYC_CURSOR);
476  if (ike == NULL && (key & KEYC_KEYPAD))
477  ike = input_key_get(key & ~KEYC_KEYPAD);
478  if (ike != NULL) {
479  log_debug("found key 0x%llx: \"%s\"", key, ike->data);
480  if ((key & KEYC_META) && (~key & KEYC_IMPLIED_META))
481  input_key_write(__func__, bev, "\033", 1);
482  input_key_write(__func__, bev, ike->data, strlen(ike->data));
483  return (0);
484  }
485 
486  /* No builtin key sequence; construct an extended key sequence. */
487  if (~s->mode & MODE_KEXTENDED) {
488  if ((key & KEYC_MASK_MODIFIERS) != KEYC_CTRL)
489  goto missing;
490  justkey = (key & KEYC_MASK_KEY);
491  switch (justkey) {
492  case ' ':
493  case '2':
494  key = 0|(key & ~~KEYC_MASK_KEY);
495  break;
496  case '|':
497  key = 28|(key & ~~KEYC_MASK_KEY);
498  break;
499  case '6':
500  key = 30|(key & ~~KEYC_MASK_KEY);
501  break;
502  case '-':
503  case '/':
504  key = 31|(key & ~~KEYC_MASK_KEY);
505  break;
506  case '?':
507  key = 127|(key & ~~KEYC_MASK_KEY);
508  break;
509  default:
510  if (justkey >= 'A' && justkey <= '_')
511  key = (justkey - 'A')|(key & ~KEYC_MASK_KEY);
512  else if (justkey >= 'a' && justkey <= '~')
513  key = (justkey - 96)|(key & ~KEYC_MASK_KEY);
514  else
515  return (0);
516  break;
517  }
518  return (input_key(s, bev, key & ~KEYC_CTRL));
519  }
520  outkey = (key & KEYC_MASK_KEY);
521  switch (key & KEYC_MASK_MODIFIERS) {
522  case KEYC_SHIFT:
523  modifier = '2';
524  break;
525  case KEYC_META:
526  modifier = '3';
527  break;
528  case KEYC_SHIFT|KEYC_META:
529  modifier = '4';
530  break;
531  case KEYC_CTRL:
532  modifier = '5';
533  break;
534  case KEYC_SHIFT|KEYC_CTRL:
535  modifier = '6';
536  break;
537  case KEYC_META|KEYC_CTRL:
538  modifier = '7';
539  break;
541  modifier = '8';
542  break;
543  default:
544  goto missing;
545  }
546  xsnprintf(tmp, sizeof tmp, "\033[%llu;%cu", outkey, modifier);
547  input_key_write(__func__, bev, tmp, strlen(tmp));
548  return (0);
549 
550 missing:
551  log_debug("key 0x%llx missing", key);
552  return (-1);
553 }
554 
555 /* Get mouse event string. */
556 int
557 input_key_get_mouse(struct screen *s, struct mouse_event *m, u_int x, u_int y,
558  const char **rbuf, size_t *rlen)
559 {
560  static char buf[40];
561  size_t len;
562 
563  *rbuf = NULL;
564  *rlen = 0;
565 
566  /* If this pane is not in button or all mode, discard motion events. */
567  if (MOUSE_DRAG(m->b) && (s->mode & MOTION_MOUSE_MODES) == 0)
568  return (0);
569  if ((s->mode & ALL_MOUSE_MODES) == 0)
570  return (0);
571 
572  /*
573  * If this event is a release event and not in all mode, discard it.
574  * In SGR mode we can tell absolutely because a release is normally
575  * shown by the last character. Without SGR, we check if the last
576  * buttons was also a release.
577  */
578  if (m->sgr_type != ' ') {
579  if (MOUSE_DRAG(m->sgr_b) &&
580  MOUSE_BUTTONS(m->sgr_b) == 3 &&
581  (~s->mode & MODE_MOUSE_ALL))
582  return (0);
583  } else {
584  if (MOUSE_DRAG(m->b) &&
585  MOUSE_BUTTONS(m->b) == 3 &&
586  MOUSE_BUTTONS(m->lb) == 3 &&
587  (~s->mode & MODE_MOUSE_ALL))
588  return (0);
589  }
590 
591  /*
592  * Use the SGR (1006) extension only if the application requested it
593  * and the underlying terminal also sent the event in this format (this
594  * is because an old style mouse release event cannot be converted into
595  * the new SGR format, since the released button is unknown). Otherwise
596  * pretend that tmux doesn't speak this extension, and fall back to the
597  * UTF-8 (1005) extension if the application requested, or to the
598  * legacy format.
599  */
600  if (m->sgr_type != ' ' && (s->mode & MODE_MOUSE_SGR)) {
601  len = xsnprintf(buf, sizeof buf, "\033[<%u;%u;%u%c",
602  m->sgr_b, x + 1, y + 1, m->sgr_type);
603  } else if (s->mode & MODE_MOUSE_UTF8) {
604  if (m->b > 0x7ff - 32 || x > 0x7ff - 33 || y > 0x7ff - 33)
605  return (0);
606  len = xsnprintf(buf, sizeof buf, "\033[M");
607  len += input_key_split2(m->b + 32, &buf[len]);
608  len += input_key_split2(x + 33, &buf[len]);
609  len += input_key_split2(y + 33, &buf[len]);
610  } else {
611  if (m->b > 223)
612  return (0);
613  len = xsnprintf(buf, sizeof buf, "\033[M");
614  buf[len++] = m->b + 32;
615  buf[len++] = x + 33;
616  buf[len++] = y + 33;
617  }
618 
619  *rbuf = buf;
620  *rlen = len;
621  return (1);
622 }
623 
624 /* Translate mouse and output. */
625 static void
627 {
628  struct screen *s = wp->screen;
629  u_int x, y;
630  const char *buf;
631  size_t len;
632 
633  /* Ignore events if no mouse mode or the pane is not visible. */
634  if (m->ignore || (s->mode & ALL_MOUSE_MODES) == 0)
635  return;
636  if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
637  return;
638  if (!window_pane_visible(wp))
639  return;
640  if (!input_key_get_mouse(s, m, x, y, &buf, &len))
641  return;
642  log_debug("writing mouse %.*s to %%%u", (int)len, buf, wp->id);
643  input_key_write(__func__, wp->event, buf, len);
644 }
int cmd_mouse_at(struct window_pane *wp, struct mouse_event *m, u_int *xp, u_int *yp, int last)
Definition: cmd.c:703
int input_key(struct screen *s, struct bufferevent *bev, key_code key)
Definition: input-keys.c:417
int input_key_pane(struct window_pane *wp, key_code key, struct mouse_event *m)
Definition: input-keys.c:392
RB_GENERATE_STATIC(input_key_tree, input_key_entry, entry, input_key_cmp)
static struct input_key_entry * input_key_get(key_code key)
Definition: input-keys.c:336
static void input_key_mouse(struct window_pane *, struct mouse_event *)
Definition: input-keys.c:626
RB_HEAD(input_key_tree, input_key_entry)
static struct input_key_entry input_key_defaults[]
Definition: input-keys.c:51
static int input_key_cmp(struct input_key_entry *, struct input_key_entry *)
Definition: input-keys.c:325
int input_key_get_mouse(struct screen *s, struct mouse_event *m, u_int x, u_int y, const char **rbuf, size_t *rlen)
Definition: input-keys.c:557
static void input_key_write(const char *from, struct bufferevent *bev, const char *data, size_t size)
Definition: input-keys.c:408
static size_t input_key_split2(u_int c, u_char *dst)
Definition: input-keys.c:345
struct input_key_tree input_key_tree
Definition: input-keys.c:48
void input_key_build(void)
Definition: input-keys.c:358
static const key_code input_key_modifiers[]
Definition: input-keys.c:311
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
long long options_get_number(struct options *oo, const char *name)
Definition: options.c:699
#define nitems(_a)
Definition: input-keys.c:36
key_code key
Definition: input-keys.c:37
const char * data
Definition: input-keys.c:38
u_int b
Definition: tmux.h:1248
u_int sgr_type
Definition: tmux.h:1261
int ignore
Definition: tmux.h:1239
int wp
Definition: tmux.h:1259
u_int lb
Definition: tmux.h:1252
u_int sgr_b
Definition: tmux.h:1262
Definition: tmux.h:816
int mode
Definition: tmux.h:832
u_char data[21]
Definition: tmux.h:629
u_char size
Definition: tmux.h:632
struct screen * screen
Definition: tmux.h:1020
struct bufferevent * event
Definition: tmux.h:1002
u_int id
Definition: tmux.h:959
struct options * global_options
Definition: tmux.c:36
#define MODE_MOUSE_UTF8
Definition: tmux.h:606
#define KEYC_IS_MOUSE(key)
Definition: tmux.h:144
#define ALL_MOUSE_MODES
Definition: tmux.h:616
#define KEYC_META
Definition: tmux.h:124
#define KEYC_SHIFT
Definition: tmux.h:126
#define KEYC_CTRL
Definition: tmux.h:125
#define KEYC_CURSOR
Definition: tmux.h:131
#define KEYC_BUILD_MODIFIERS
Definition: tmux.h:133
#define KEYC_LITERAL
Definition: tmux.h:129
unsigned long long key_code
Definition: tmux.h:177
void utf8_to_data(utf8_char, struct utf8_data *)
Definition: utf8.c:159
#define KEYC_KEYPAD
Definition: tmux.h:130
#define KEYC_MASK_FLAGS
Definition: tmux.h:137
#define MOTION_MOUSE_MODES
Definition: tmux.h:617
#define MODE_MOUSE_SGR
Definition: tmux.h:607
#define MOUSE_DRAG(b)
Definition: tmux.h:1233
#define MODE_MOUSE_ALL
Definition: tmux.h:610
int window_pane_visible(struct window_pane *)
Definition: window.c:1189
#define MODE_KKEYPAD
Definition: tmux.h:601
#define MODE_KCURSOR
Definition: tmux.h:600
@ 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_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_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_KP_NINE
Definition: tmux.h:257
#define KEYC_MASK_MODIFIERS
Definition: tmux.h:136
#define KEYC_IS_UNICODE(key)
Definition: tmux.h:149
#define MODE_KEXTENDED
Definition: tmux.h:613
#define MOUSE_BUTTONS(b)
Definition: tmux.h:1231
#define KEYC_MASK_KEY
Definition: tmux.h:138
#define KEYC_IMPLIED_META
Definition: tmux.h:132
int xsnprintf(char *str, size_t len, const char *fmt,...)
Definition: xmalloc.c:135
void * xcalloc(size_t nmemb, size_t size)
Definition: xmalloc.c:41
char * xstrdup(const char *str)
Definition: xmalloc.c:89