diff options
author | Nicholas Marriott <nicholas.marriott@gmail.com> | 2009-01-09 16:45:58 +0000 |
---|---|---|
committer | Nicholas Marriott <nicholas.marriott@gmail.com> | 2009-01-09 16:45:58 +0000 |
commit | ed1031b358967b9a3037a8c5c72caae17ce2961c (patch) | |
tree | b53b670692057cb4b9560984444c5144ff2eca31 /input-keys.c | |
parent | 622d4def2283e6fdc13dae33d8814e2af5169a65 (diff) | |
download | rtmux-ed1031b358967b9a3037a8c5c72caae17ce2961c.tar.gz rtmux-ed1031b358967b9a3037a8c5c72caae17ce2961c.tar.bz2 rtmux-ed1031b358967b9a3037a8c5c72caae17ce2961c.zip |
Update key handling code. Simplify, support ctrl properly and add a new window option (xterm-keys) to output xterm key codes including ctrl and, if available, alt and shift.
Diffstat (limited to 'input-keys.c')
-rw-r--r-- | input-keys.c | 150 |
1 files changed, 106 insertions, 44 deletions
diff --git a/input-keys.c b/input-keys.c index 19a42198..0c2e1f70 100644 --- a/input-keys.c +++ b/input-keys.c @@ -1,4 +1,4 @@ -/* $Id: input-keys.c,v 1.17 2009-01-08 22:28:02 nicm Exp $ */ +/* $Id: input-keys.c,v 1.18 2009-01-09 16:45:58 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -24,42 +24,47 @@ #include "tmux.h" -#define INPUTKEY_KEYPAD 0x1 -#define INPUTKEY_CURSOR 0x2 -struct { +struct input_key_ent { int key; const char *data; + int flags; -} input_keys[] = { +#define INPUTKEY_KEYPAD 0x1 /* keypad key */ +#define INPUTKEY_CURSOR 0x2 /* cursor key */ +#define INPUTKEY_MODIFIER 0x4 /* may be adjusted by modifiers */ +#define INPUTKEY_XTERM 0x4 /* may have xterm argument appended */ +}; + +struct input_key_ent input_keys[] = { /* Function keys. */ - { KEYC_F1, "\033OP", 0 }, - { KEYC_F2, "\033OQ", 0 }, - { KEYC_F3, "\033OR", 0 }, - { KEYC_F4, "\033OS", 0 }, - { KEYC_F5, "\033[15~", 0 }, - { KEYC_F6, "\033[17~", 0 }, - { KEYC_F7, "\033[18~", 0 }, - { KEYC_F8, "\033[19~", 0 }, - { KEYC_F9, "\033[20~", 0 }, - { KEYC_F10, "\033[21~", 0 }, - { KEYC_F11, "\033[23~", 0 }, - { KEYC_F12, "\033[24~", 0 }, - { KEYC_IC, "\033[2~", 0 }, - { KEYC_DC, "\033[3~", 0 }, - { KEYC_HOME, "\033[1~", 0 }, - { KEYC_END, "\033[4~", 0 }, - { KEYC_NPAGE, "\033[6~", 0 }, - { KEYC_PPAGE, "\033[5~", 0 }, + { KEYC_F1, "\033OP", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F2, "\033OQ", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F3, "\033OR", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F4, "\033OS", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F5, "\033[15~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F6, "\033[17~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F7, "\033[18~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F8, "\033[19~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F9, "\033[20~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F10, "\033[21~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F11, "\033[23~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_F12, "\033[24~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_IC, "\033[2~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_DC, "\033[3~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_HOME, "\033[1~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_END, "\033[4~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_NPAGE, "\033[6~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, + { KEYC_PPAGE, "\033[5~", INPUTKEY_MODIFIER|INPUTKEY_XTERM }, /* Arrow keys. Cursor versions must come first. */ - { KEYC_UP, "\033OA", INPUTKEY_CURSOR }, - { KEYC_DOWN, "\033OB", INPUTKEY_CURSOR }, - { KEYC_LEFT, "\033OD", INPUTKEY_CURSOR }, - { KEYC_RIGHT, "\033OC", INPUTKEY_CURSOR }, - { KEYC_UP, "\033[A", 0 }, - { KEYC_DOWN, "\033[B", 0 }, - { KEYC_LEFT, "\033[D", 0 }, - { KEYC_RIGHT, "\033[C", 0 }, + { KEYC_UP, "\033OA", INPUTKEY_MODIFIER|INPUTKEY_CURSOR }, + { KEYC_DOWN, "\033OB", INPUTKEY_MODIFIER|INPUTKEY_CURSOR }, + { KEYC_LEFT, "\033OD", INPUTKEY_MODIFIER|INPUTKEY_CURSOR }, + { KEYC_RIGHT, "\033OC", INPUTKEY_MODIFIER|INPUTKEY_CURSOR }, + { KEYC_UP, "\033[A", INPUTKEY_MODIFIER }, + { KEYC_DOWN, "\033[B", INPUTKEY_MODIFIER }, + { KEYC_LEFT, "\033[D", INPUTKEY_MODIFIER }, + { KEYC_RIGHT, "\033[C", INPUTKEY_MODIFIER }, /* Keypad keys. Keypad versions must come first. */ { KEYC_KP0_1, "/", INPUTKEY_KEYPAD }, @@ -100,35 +105,92 @@ struct { void input_key(struct window *w, int key) { - u_int i; + struct input_key_ent *ike; + u_int i; + char ch; + size_t dlen; log_debug2("writing key 0x%x", key); - if (KEYC_ISESCAPE(key)) { - buffer_write8(w->out, '\033'); - key = KEYC_REMOVEESCAPE(key); - } - - if (key != KEYC_NONE && key < KEYC_OFFSET) { - buffer_write8(w->out, (uint8_t) key); + if (key != KEYC_NONE && KEYC_REMOVEESC(key) < KEYC_OFFSET) { + if (KEYC_ISESC(key)) + buffer_write8(w->out, '\033'); + buffer_write8(w->out, (uint8_t) KEYC_REMOVEESC(key)); return; } for (i = 0; i < nitems(input_keys); i++) { - if ((input_keys[i].flags & INPUTKEY_KEYPAD) && + ike = &input_keys[i]; + + if ((ike->flags & INPUTKEY_KEYPAD) && !(w->screen->mode & MODE_KKEYPAD)) continue; - if ((input_keys[i].flags & INPUTKEY_CURSOR) && + if ((ike->flags & INPUTKEY_CURSOR) && !(w->screen->mode & MODE_KCURSOR)) continue; - if (input_keys[i].key == key) + + if (ike->flags & INPUTKEY_MODIFIER) { + if (KEYC_ISCTL(key) && KEYC_ADDCTL(ike->key) == key) + break; + if (KEYC_ISESC(key) && KEYC_ADDESC(ike->key) == key) + break; + if (KEYC_ISSFT(key) && KEYC_ADDSFT(ike->key) == key) + break; + } + if (ike->key == key) break; } if (i == nitems(input_keys)) { log_debug2("key 0x%x missing", key); return; } + dlen = strlen(ike->data); + + log_debug2("found key 0x%x: \"%s\"", key, ike->data); + + if (ike->flags & INPUTKEY_XTERM && + options_get_number(&w->options, "xterm-keys")) { + /* In xterm keys mode, append modifier argument. */ + ch = '\0'; + if (KEYC_ISSFT(key) && KEYC_ISESC(key) && KEYC_ISCTL(key)) + ch = '8'; + else if (KEYC_ISESC(key) && KEYC_ISCTL(key)) + ch = '7'; + else if (KEYC_ISSFT(key) && KEYC_ISCTL(key)) + ch = '6'; + else if (KEYC_ISCTL(key)) + ch = '5'; + else if (KEYC_ISSFT(key) && KEYC_ISESC(key)) + ch = '4'; + else if (KEYC_ISESC(key)) + ch = '3'; + else if (KEYC_ISSFT(key)) + ch = '2'; + if (ch != '\0') { + log_debug("output argument is: %c", ch); + buffer_write(w->out, ike->data, dlen - 1); + buffer_write8(w->out, ';'); + buffer_write8(w->out, ch); + buffer_write8(w->out, ike->data[dlen - 1]); + } else + buffer_write(w->out, ike->data, dlen); + return; + } + if (ike->flags & INPUTKEY_MODIFIER) { + /* + * If not in xterm keys or not an xterm key handle escape and + * control (shift not supported). + */ + if (KEYC_ISESC(key)) + buffer_write8(w->out, '\033'); + if (!KEYC_ISCTL(key)) { + buffer_write(w->out, ike->data, dlen); + return; + } + buffer_write(w->out, ike->data, dlen - 1); + buffer_write8(w->out, ike->data[dlen - 1] ^ 0x20); + return; + } - log_debug2("found key 0x%x: \"%s\"", key, input_keys[i].data); - buffer_write(w->out, input_keys[i].data, strlen(input_keys[i].data)); + buffer_write(w->out, ike->data, dlen); } |