aboutsummaryrefslogtreecommitdiff
path: root/tty-keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'tty-keys.c')
-rw-r--r--tty-keys.c484
1 files changed, 320 insertions, 164 deletions
diff --git a/tty-keys.c b/tty-keys.c
index dc064a17..5a2b3817 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -21,6 +21,7 @@
#include <netinet/in.h>
+#include <ctype.h>
#include <limits.h>
#include <resolv.h>
#include <stdlib.h>
@@ -46,6 +47,8 @@ static struct tty_key *tty_keys_find(struct tty *, const char *, size_t,
static int tty_keys_next1(struct tty *, const char *, size_t, key_code *,
size_t *, int);
static void tty_keys_callback(int, short, void *);
+static int tty_keys_extended_key(struct tty *, const char *, size_t,
+ size_t *, key_code *);
static int tty_keys_mouse(struct tty *, const char *, size_t, size_t *,
struct mouse_event *);
static int tty_keys_clipboard(struct tty *, const char *, size_t,
@@ -69,33 +72,33 @@ static const struct tty_default_key_raw tty_default_raw_keys[] = {
* put the terminal into keypad_xmit mode. Translation of numbers
* mode/applications mode is done in input-keys.c.
*/
- { "\033Oo", KEYC_KP_SLASH },
- { "\033Oj", KEYC_KP_STAR },
- { "\033Om", KEYC_KP_MINUS },
- { "\033Ow", KEYC_KP_SEVEN },
- { "\033Ox", KEYC_KP_EIGHT },
- { "\033Oy", KEYC_KP_NINE },
- { "\033Ok", KEYC_KP_PLUS },
- { "\033Ot", KEYC_KP_FOUR },
- { "\033Ou", KEYC_KP_FIVE },
- { "\033Ov", KEYC_KP_SIX },
- { "\033Oq", KEYC_KP_ONE },
- { "\033Or", KEYC_KP_TWO },
- { "\033Os", KEYC_KP_THREE },
- { "\033OM", KEYC_KP_ENTER },
- { "\033Op", KEYC_KP_ZERO },
- { "\033On", KEYC_KP_PERIOD },
+ { "\033Oo", KEYC_KP_SLASH|KEYC_KEYPAD },
+ { "\033Oj", KEYC_KP_STAR|KEYC_KEYPAD },
+ { "\033Om", KEYC_KP_MINUS|KEYC_KEYPAD },
+ { "\033Ow", KEYC_KP_SEVEN|KEYC_KEYPAD },
+ { "\033Ox", KEYC_KP_EIGHT|KEYC_KEYPAD },
+ { "\033Oy", KEYC_KP_NINE|KEYC_KEYPAD },
+ { "\033Ok", KEYC_KP_PLUS|KEYC_KEYPAD },
+ { "\033Ot", KEYC_KP_FOUR|KEYC_KEYPAD },
+ { "\033Ou", KEYC_KP_FIVE|KEYC_KEYPAD },
+ { "\033Ov", KEYC_KP_SIX|KEYC_KEYPAD },
+ { "\033Oq", KEYC_KP_ONE|KEYC_KEYPAD },
+ { "\033Or", KEYC_KP_TWO|KEYC_KEYPAD },
+ { "\033Os", KEYC_KP_THREE|KEYC_KEYPAD },
+ { "\033OM", KEYC_KP_ENTER|KEYC_KEYPAD },
+ { "\033Op", KEYC_KP_ZERO|KEYC_KEYPAD },
+ { "\033On", KEYC_KP_PERIOD|KEYC_KEYPAD },
/* Arrow keys. */
- { "\033OA", KEYC_UP },
- { "\033OB", KEYC_DOWN },
- { "\033OC", KEYC_RIGHT },
- { "\033OD", KEYC_LEFT },
+ { "\033OA", KEYC_UP|KEYC_CURSOR },
+ { "\033OB", KEYC_DOWN|KEYC_CURSOR },
+ { "\033OC", KEYC_RIGHT|KEYC_CURSOR },
+ { "\033OD", KEYC_LEFT|KEYC_CURSOR },
- { "\033[A", KEYC_UP },
- { "\033[B", KEYC_DOWN },
- { "\033[C", KEYC_RIGHT },
- { "\033[D", KEYC_LEFT },
+ { "\033[A", KEYC_UP|KEYC_CURSOR },
+ { "\033[B", KEYC_DOWN|KEYC_CURSOR },
+ { "\033[C", KEYC_RIGHT|KEYC_CURSOR },
+ { "\033[D", KEYC_LEFT|KEYC_CURSOR },
/* Other (xterm) "cursor" keys. */
{ "\033OH", KEYC_HOME },
@@ -182,11 +185,59 @@ static const struct tty_default_key_raw tty_default_raw_keys[] = {
{ "\033[201~", KEYC_PASTE_END },
};
+/* Default xterm keys. */
+struct tty_default_key_xterm {
+ const char *template;
+ key_code key;
+};
+static const struct tty_default_key_xterm tty_default_xterm_keys[] = {
+ { "\033[1;_P", KEYC_F1 },
+ { "\033O1;_P", KEYC_F1 },
+ { "\033O_P", KEYC_F1 },
+ { "\033[1;_Q", KEYC_F2 },
+ { "\033O1;_Q", KEYC_F2 },
+ { "\033O_Q", KEYC_F2 },
+ { "\033[1;_R", KEYC_F3 },
+ { "\033O1;_R", KEYC_F3 },
+ { "\033O_R", KEYC_F3 },
+ { "\033[1;_S", KEYC_F4 },
+ { "\033O1;_S", KEYC_F4 },
+ { "\033O_S", KEYC_F4 },
+ { "\033[15;_~", KEYC_F5 },
+ { "\033[17;_~", KEYC_F6 },
+ { "\033[18;_~", KEYC_F7 },
+ { "\033[19;_~", KEYC_F8 },
+ { "\033[20;_~", KEYC_F9 },
+ { "\033[21;_~", KEYC_F10 },
+ { "\033[23;_~", KEYC_F11 },
+ { "\033[24;_~", KEYC_F12 },
+ { "\033[1;_A", KEYC_UP },
+ { "\033[1;_B", KEYC_DOWN },
+ { "\033[1;_C", KEYC_RIGHT },
+ { "\033[1;_D", KEYC_LEFT },
+ { "\033[1;_H", KEYC_HOME },
+ { "\033[1;_F", KEYC_END },
+ { "\033[5;_~", KEYC_PPAGE },
+ { "\033[6;_~", KEYC_NPAGE },
+ { "\033[2;_~", KEYC_IC },
+ { "\033[3;_~", KEYC_DC },
+};
+static const key_code tty_default_xterm_modifiers[] = {
+ 0,
+ 0,
+ KEYC_SHIFT,
+ KEYC_META|KEYC_IMPLIED_META,
+ KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META,
+ KEYC_CTRL,
+ KEYC_SHIFT|KEYC_CTRL,
+ KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL,
+ KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL
+};
+
/*
- * Default terminfo(5) keys. Any keys that have builtin modifiers
- * (that is, where the key itself contains the modifiers) has the
- * KEYC_XTERM flag set so a leading escape is not treated as meta (and
- * probably removed).
+ * Default terminfo(5) keys. Any keys that have builtin modifiers (that is,
+ * where the key itself contains the modifiers) has the KEYC_XTERM flag set so
+ * a leading escape is not treated as meta (and probably removed).
*/
struct tty_default_key_code {
enum tty_code_code code;
@@ -207,61 +258,61 @@ static const struct tty_default_key_code tty_default_code_keys[] = {
{ TTYC_KF11, KEYC_F11 },
{ TTYC_KF12, KEYC_F12 },
- { TTYC_KF13, KEYC_F1|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF14, KEYC_F2|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF15, KEYC_F3|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF16, KEYC_F4|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF17, KEYC_F5|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF18, KEYC_F6|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF19, KEYC_F7|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF20, KEYC_F8|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF21, KEYC_F9|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF22, KEYC_F10|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF23, KEYC_F11|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF24, KEYC_F12|KEYC_SHIFT|KEYC_XTERM },
-
- { TTYC_KF25, KEYC_F1|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF26, KEYC_F2|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF27, KEYC_F3|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF28, KEYC_F4|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF29, KEYC_F5|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF30, KEYC_F6|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF31, KEYC_F7|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF32, KEYC_F8|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF33, KEYC_F9|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF34, KEYC_F10|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF35, KEYC_F11|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF36, KEYC_F12|KEYC_CTRL|KEYC_XTERM },
-
- { TTYC_KF37, KEYC_F1|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF38, KEYC_F2|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF39, KEYC_F3|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF40, KEYC_F4|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF41, KEYC_F5|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF42, KEYC_F6|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF43, KEYC_F7|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF44, KEYC_F8|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF45, KEYC_F9|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF46, KEYC_F10|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF47, KEYC_F11|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KF48, KEYC_F12|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
-
- { TTYC_KF49, KEYC_F1|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF50, KEYC_F2|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF51, KEYC_F3|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF52, KEYC_F4|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF53, KEYC_F5|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF54, KEYC_F6|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF55, KEYC_F7|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF56, KEYC_F8|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF57, KEYC_F9|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF58, KEYC_F10|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF59, KEYC_F11|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KF60, KEYC_F12|KEYC_ESCAPE|KEYC_XTERM },
-
- { TTYC_KF61, KEYC_F1|KEYC_ESCAPE|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF62, KEYC_F2|KEYC_ESCAPE|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KF63, KEYC_F3|KEYC_ESCAPE|KEYC_SHIFT|KEYC_XTERM },
+ { TTYC_KF13, KEYC_F1|KEYC_SHIFT },
+ { TTYC_KF14, KEYC_F2|KEYC_SHIFT },
+ { TTYC_KF15, KEYC_F3|KEYC_SHIFT },
+ { TTYC_KF16, KEYC_F4|KEYC_SHIFT },
+ { TTYC_KF17, KEYC_F5|KEYC_SHIFT },
+ { TTYC_KF18, KEYC_F6|KEYC_SHIFT },
+ { TTYC_KF19, KEYC_F7|KEYC_SHIFT },
+ { TTYC_KF20, KEYC_F8|KEYC_SHIFT },
+ { TTYC_KF21, KEYC_F9|KEYC_SHIFT },
+ { TTYC_KF22, KEYC_F10|KEYC_SHIFT },
+ { TTYC_KF23, KEYC_F11|KEYC_SHIFT },
+ { TTYC_KF24, KEYC_F12|KEYC_SHIFT },
+
+ { TTYC_KF25, KEYC_F1|KEYC_CTRL },
+ { TTYC_KF26, KEYC_F2|KEYC_CTRL },
+ { TTYC_KF27, KEYC_F3|KEYC_CTRL },
+ { TTYC_KF28, KEYC_F4|KEYC_CTRL },
+ { TTYC_KF29, KEYC_F5|KEYC_CTRL },
+ { TTYC_KF30, KEYC_F6|KEYC_CTRL },
+ { TTYC_KF31, KEYC_F7|KEYC_CTRL },
+ { TTYC_KF32, KEYC_F8|KEYC_CTRL },
+ { TTYC_KF33, KEYC_F9|KEYC_CTRL },
+ { TTYC_KF34, KEYC_F10|KEYC_CTRL },
+ { TTYC_KF35, KEYC_F11|KEYC_CTRL },
+ { TTYC_KF36, KEYC_F12|KEYC_CTRL },
+
+ { TTYC_KF37, KEYC_F1|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF38, KEYC_F2|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF39, KEYC_F3|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF40, KEYC_F4|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF41, KEYC_F5|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF42, KEYC_F6|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF43, KEYC_F7|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF44, KEYC_F8|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF45, KEYC_F9|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF46, KEYC_F10|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF47, KEYC_F11|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KF48, KEYC_F12|KEYC_SHIFT|KEYC_CTRL },
+
+ { TTYC_KF49, KEYC_F1|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF50, KEYC_F2|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF51, KEYC_F3|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF52, KEYC_F4|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF53, KEYC_F5|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF54, KEYC_F6|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF55, KEYC_F7|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF56, KEYC_F8|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF57, KEYC_F9|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF58, KEYC_F10|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF59, KEYC_F11|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KF60, KEYC_F12|KEYC_META|KEYC_IMPLIED_META },
+
+ { TTYC_KF61, KEYC_F1|KEYC_META|KEYC_IMPLIED_META|KEYC_SHIFT },
+ { TTYC_KF62, KEYC_F2|KEYC_META|KEYC_IMPLIED_META|KEYC_SHIFT },
+ { TTYC_KF63, KEYC_F3|KEYC_META|KEYC_IMPLIED_META|KEYC_SHIFT },
{ TTYC_KICH1, KEYC_IC },
{ TTYC_KDCH1, KEYC_DC },
@@ -272,74 +323,74 @@ static const struct tty_default_key_code tty_default_code_keys[] = {
{ TTYC_KCBT, KEYC_BTAB },
/* Arrow keys from terminfo. */
- { TTYC_KCUU1, KEYC_UP },
- { TTYC_KCUD1, KEYC_DOWN },
- { TTYC_KCUB1, KEYC_LEFT },
- { TTYC_KCUF1, KEYC_RIGHT },
+ { TTYC_KCUU1, KEYC_UP|KEYC_CURSOR },
+ { TTYC_KCUD1, KEYC_DOWN|KEYC_CURSOR },
+ { TTYC_KCUB1, KEYC_LEFT|KEYC_CURSOR },
+ { TTYC_KCUF1, KEYC_RIGHT|KEYC_CURSOR },
/* Key and modifier capabilities. */
- { TTYC_KDC2, KEYC_DC|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KDC3, KEYC_DC|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KDC4, KEYC_DC|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KDC5, KEYC_DC|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KDC6, KEYC_DC|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KDC7, KEYC_DC|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KIND, KEYC_DOWN|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KDN2, KEYC_DOWN|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KDN3, KEYC_DOWN|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KDN4, KEYC_DOWN|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KDN5, KEYC_DOWN|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KDN6, KEYC_DOWN|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KDN7, KEYC_DOWN|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KEND2, KEYC_END|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KEND3, KEYC_END|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KEND4, KEYC_END|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KEND5, KEYC_END|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KEND6, KEYC_END|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KEND7, KEYC_END|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KHOM2, KEYC_HOME|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KHOM3, KEYC_HOME|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KHOM4, KEYC_HOME|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KHOM5, KEYC_HOME|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KHOM6, KEYC_HOME|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KHOM7, KEYC_HOME|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KIC2, KEYC_IC|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KIC3, KEYC_IC|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KIC4, KEYC_IC|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KIC5, KEYC_IC|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KIC6, KEYC_IC|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KIC7, KEYC_IC|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KLFT2, KEYC_LEFT|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KLFT3, KEYC_LEFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KLFT4, KEYC_LEFT|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KLFT5, KEYC_LEFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KLFT6, KEYC_LEFT|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KLFT7, KEYC_LEFT|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KNXT2, KEYC_NPAGE|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KNXT3, KEYC_NPAGE|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KNXT4, KEYC_NPAGE|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KNXT5, KEYC_NPAGE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KNXT6, KEYC_NPAGE|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KNXT7, KEYC_NPAGE|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KPRV2, KEYC_PPAGE|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KPRV3, KEYC_PPAGE|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KPRV4, KEYC_PPAGE|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KPRV5, KEYC_PPAGE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KPRV6, KEYC_PPAGE|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KPRV7, KEYC_PPAGE|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KRIT2, KEYC_RIGHT|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KRIT3, KEYC_RIGHT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KRIT4, KEYC_RIGHT|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KRIT5, KEYC_RIGHT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KRIT6, KEYC_RIGHT|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KRIT7, KEYC_RIGHT|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KRI, KEYC_UP|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KUP2, KEYC_UP|KEYC_SHIFT|KEYC_XTERM },
- { TTYC_KUP3, KEYC_UP|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KUP4, KEYC_UP|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
- { TTYC_KUP5, KEYC_UP|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KUP6, KEYC_UP|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
- { TTYC_KUP7, KEYC_UP|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
+ { TTYC_KDC2, KEYC_DC|KEYC_SHIFT },
+ { TTYC_KDC3, KEYC_DC|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KDC4, KEYC_DC|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KDC5, KEYC_DC|KEYC_CTRL },
+ { TTYC_KDC6, KEYC_DC|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KDC7, KEYC_DC|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL },
+ { TTYC_KIND, KEYC_DOWN|KEYC_SHIFT },
+ { TTYC_KDN2, KEYC_DOWN|KEYC_SHIFT },
+ { TTYC_KDN3, KEYC_DOWN|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KDN4, KEYC_DOWN|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KDN5, KEYC_DOWN|KEYC_CTRL },
+ { TTYC_KDN6, KEYC_DOWN|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KDN7, KEYC_DOWN|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL },
+ { TTYC_KEND2, KEYC_END|KEYC_SHIFT },
+ { TTYC_KEND3, KEYC_END|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KEND4, KEYC_END|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KEND5, KEYC_END|KEYC_CTRL },
+ { TTYC_KEND6, KEYC_END|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KEND7, KEYC_END|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL },
+ { TTYC_KHOM2, KEYC_HOME|KEYC_SHIFT },
+ { TTYC_KHOM3, KEYC_HOME|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KHOM4, KEYC_HOME|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KHOM5, KEYC_HOME|KEYC_CTRL },
+ { TTYC_KHOM6, KEYC_HOME|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KHOM7, KEYC_HOME|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL },
+ { TTYC_KIC2, KEYC_IC|KEYC_SHIFT },
+ { TTYC_KIC3, KEYC_IC|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KIC4, KEYC_IC|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KIC5, KEYC_IC|KEYC_CTRL },
+ { TTYC_KIC6, KEYC_IC|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KIC7, KEYC_IC|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL },
+ { TTYC_KLFT2, KEYC_LEFT|KEYC_SHIFT },
+ { TTYC_KLFT3, KEYC_LEFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KLFT4, KEYC_LEFT|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KLFT5, KEYC_LEFT|KEYC_CTRL },
+ { TTYC_KLFT6, KEYC_LEFT|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KLFT7, KEYC_LEFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL },
+ { TTYC_KNXT2, KEYC_NPAGE|KEYC_SHIFT },
+ { TTYC_KNXT3, KEYC_NPAGE|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KNXT4, KEYC_NPAGE|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KNXT5, KEYC_NPAGE|KEYC_CTRL },
+ { TTYC_KNXT6, KEYC_NPAGE|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KNXT7, KEYC_NPAGE|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL },
+ { TTYC_KPRV2, KEYC_PPAGE|KEYC_SHIFT },
+ { TTYC_KPRV3, KEYC_PPAGE|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KPRV4, KEYC_PPAGE|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KPRV5, KEYC_PPAGE|KEYC_CTRL },
+ { TTYC_KPRV6, KEYC_PPAGE|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KPRV7, KEYC_PPAGE|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL },
+ { TTYC_KRIT2, KEYC_RIGHT|KEYC_SHIFT },
+ { TTYC_KRIT3, KEYC_RIGHT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KRIT4, KEYC_RIGHT|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KRIT5, KEYC_RIGHT|KEYC_CTRL },
+ { TTYC_KRIT6, KEYC_RIGHT|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KRIT7, KEYC_RIGHT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL },
+ { TTYC_KRI, KEYC_UP|KEYC_SHIFT },
+ { TTYC_KUP2, KEYC_UP|KEYC_SHIFT },
+ { TTYC_KUP3, KEYC_UP|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KUP4, KEYC_UP|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META },
+ { TTYC_KUP5, KEYC_UP|KEYC_CTRL },
+ { TTYC_KUP6, KEYC_UP|KEYC_SHIFT|KEYC_CTRL },
+ { TTYC_KUP7, KEYC_UP|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL },
};
/* Add key to tree. */
@@ -350,7 +401,7 @@ tty_keys_add(struct tty *tty, const char *s, key_code key)
size_t size;
const char *keystr;
- keystr = key_string_lookup_key(key);
+ keystr = key_string_lookup_key(key, 1);
if ((tk = tty_keys_find(tty, s, strlen(s), &size)) == NULL) {
log_debug("new key %s: 0x%llx (%s)", s, key, keystr);
tty_keys_add1(&tty->key_tree, s, key);
@@ -403,17 +454,30 @@ void
tty_keys_build(struct tty *tty)
{
const struct tty_default_key_raw *tdkr;
+ const struct tty_default_key_xterm *tdkx;
const struct tty_default_key_code *tdkc;
- u_int i;
+ u_int i, j;
const char *s;
struct options_entry *o;
struct options_array_item *a;
union options_value *ov;
+ char copy[16];
+ key_code key;
if (tty->key_tree != NULL)
tty_keys_free(tty);
tty->key_tree = NULL;
+ for (i = 0; i < nitems(tty_default_xterm_keys); i++) {
+ tdkx = &tty_default_xterm_keys[i];
+ for (j = 2; j < nitems(tty_default_xterm_modifiers); j++) {
+ strlcpy(copy, tdkx->template, sizeof copy);
+ copy[strcspn(copy, "_")] = '0' + j;
+
+ key = tdkx->key|tty_default_xterm_modifiers[j];
+ tty_keys_add(tty, copy, key);
+ }
+ }
for (i = 0; i < nitems(tty_default_raw_keys); i++) {
tdkr = &tty_default_raw_keys[i];
@@ -516,7 +580,6 @@ tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key,
enum utf8_state more;
u_int i;
wchar_t wc;
- int n;
log_debug("%s: next key is %zu (%.*s) (expired=%d)", c->name, len,
(int)len, buf, expired);
@@ -534,13 +597,6 @@ tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key,
return (0);
}
- /* Is this an an xterm(1) key? */
- n = xterm_keys_find(buf, len, size, key);
- if (n == 0)
- return (0);
- if (n == 1 && !expired)
- return (1);
-
/* Is this valid UTF-8? */
more = utf8_open(&ud, (u_char)*buf);
if (more == UTF8_MORE) {
@@ -637,6 +693,16 @@ tty_keys_next(struct tty *tty)
goto partial_key;
}
+ /* Is this an extended key press? */
+ switch (tty_keys_extended_key(tty, buf, len, &size, &key)) {
+ case 0: /* yes */
+ goto complete_key;
+ case -1: /* no, or not valid */
+ break;
+ case 1: /* partial */
+ goto partial_key;
+ }
+
first_key:
/* Try to lookup complete key. */
n = tty_keys_next1(tty, buf, len, &key, &size, expired);
@@ -653,7 +719,7 @@ first_key:
/* Look for a key without the escape. */
n = tty_keys_next1(tty, buf + 1, len - 1, &key, &size, expired);
if (n == 0) { /* found */
- if (key & KEYC_XTERM) {
+ if (key & KEYC_IMPLIED_META) {
/*
* We want the escape key as well as the xterm
* key, because the xterm sequence implicitly
@@ -665,7 +731,7 @@ first_key:
size = 1;
goto complete_key;
}
- key |= KEYC_ESCAPE;
+ key |= KEYC_META;
size++;
goto complete_key;
}
@@ -678,7 +744,7 @@ first_key:
* escape). So pass it through even if the timer has not expired.
*/
if (*buf == '\033' && len >= 2) {
- key = (u_char)buf[1] | KEYC_ESCAPE;
+ key = (u_char)buf[1] | KEYC_META;
size = 2;
} else {
key = (u_char)buf[0];
@@ -723,7 +789,7 @@ complete_key:
*/
bspace = tty->tio.c_cc[VERASE];
if (bspace != _POSIX_VDISABLE && (key & KEYC_MASK_KEY) == bspace)
- key = (key & KEYC_MASK_MOD) | KEYC_BSPACE;
+ key = (key & KEYC_MASK_MODIFIERS)|KEYC_BSPACE;
/* Remove data from buffer. */
evbuffer_drain(tty->in, size);
@@ -775,6 +841,96 @@ tty_keys_callback(__unused int fd, __unused short events, void *data)
}
/*
+ * Handle extended key input. This has two forms: \033[27;m;k~ and \033[k;mu,
+ * where k is key as a number and m is a modifier. Returns 0 for success, -1
+ * for failure, 1 for partial;
+ */
+static int
+tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
+ size_t *size, key_code *key)
+{
+ struct client *c = tty->client;
+ size_t end;
+ u_int number, modifiers;
+ char tmp[64];
+
+ *size = 0;
+
+ /* First two bytes are always \033[. */
+ if (buf[0] != '\033')
+ return (-1);
+ if (len == 1)
+ return (1);
+ if (buf[1] != '[')
+ return (-1);
+ if (len == 2)
+ return (1);
+
+ /*
+ * Look for a terminator. Stop at either '~' or anything that isn't a
+ * number or ';'.
+ */
+ for (end = 2; end < len && end != sizeof tmp; end++) {
+ if (buf[end] == '~')
+ break;
+ if (!isdigit((u_char)buf[end]) && buf[end] != ';')
+ break;
+ }
+ if (end == len)
+ return (1);
+ if (end == sizeof tmp || (buf[end] != '~' && buf[end] != 'u'))
+ return (-1);
+
+ /* Copy to the buffer. */
+ memcpy(tmp, buf + 2, end);
+ tmp[end] = '\0';
+
+ /* Try to parse either form of key. */
+ if (buf[end] == '~') {
+ if (sscanf(tmp, "27;%u;%u", &modifiers, &number) != 2)
+ return (-1);
+ } else {
+ if (sscanf(tmp ,"%u;%u", &number, &modifiers) != 2)
+ return (-1);
+ }
+ *size = end + 1;
+
+ /* Store the key and modifiers. */
+ *key = number;
+ switch (modifiers) {
+ case 2:
+ (*key) |= KEYC_SHIFT;
+ break;
+ case 3:
+ (*key) |= (KEYC_META|KEYC_IMPLIED_META);
+ break;
+ case 4:
+ (*key) |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META);
+ break;
+ case 5:
+ (*key) |= KEYC_CTRL;
+ break;
+ case 6:
+ (*key) |= (KEYC_SHIFT|KEYC_CTRL);
+ break;
+ case 7:
+ (*key) |= (KEYC_META|KEYC_CTRL);
+ break;
+ case 8:
+ (*key) |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL);
+ break;
+ default:
+ *key = KEYC_NONE;
+ break;
+ }
+ if (log_get_level() != 0) {
+ log_debug("%s: extended key %.*s is %llx (%s)", c->name,
+ (int)*size, buf, *key, key_string_lookup_key(*key, 1));
+ }
+ return (0);
+}
+
+/*
* Handle mouse key input. Returns 0 for success, -1 for failure, 1 for partial
* (probably a mouse sequence but need more data).
*/
@@ -1137,7 +1293,7 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf,
else if (strncmp(tmp, "tmux ", 5) == 0)
tty_default_features(&c->term_features, "tmux", 0);
else if (strncmp(tmp, "XTerm(", 6) == 0)
- tty_default_features(&c->term_features, "xterm", 0);
+ tty_default_features(&c->term_features, "XTerm", 0);
else if (strncmp(tmp, "mintty ", 7) == 0)
tty_default_features(&c->term_features, "mintty", 0);
log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf);