From 2f8a39ed648b3533e0fe6b220821ae8ffcbdcbb4 Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Wed, 19 Nov 2014 00:42:59 +0100 Subject: Better support for rxvt input --- driver-csi.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 16 deletions(-) diff --git a/driver-csi.c b/driver-csi.c index d3d3670..a77341b 100644 --- a/driver-csi.c +++ b/driver-csi.c @@ -67,6 +67,54 @@ register_csi_ss3 (termo_type_t type, termo_sym_t sym, unsigned char cmd) register_csi_ss3_full (type, sym, 0, 0, cmd); } +// +// Handler for rxvt special cursor key codes +// + +static termo_result_t +handle_csi_cursor (termo_t *tk, + termo_key_t *key, int cmd, long *arg, int args) +{ + (void) tk; + (void) arg; + (void) args; + + key->type = TERMO_TYPE_KEYSYM; + key->modifiers = 0; + + if (cmd == 'a') key->code.sym = TERMO_SYM_UP; + if (cmd == 'b') key->code.sym = TERMO_SYM_DOWN; + if (cmd == 'c') key->code.sym = TERMO_SYM_RIGHT; + if (cmd == 'd') key->code.sym = TERMO_SYM_LEFT; + + if (key->code.sym == TERMO_SYM_UNKNOWN) + return TERMO_RES_NONE; + + // CSI with small letter stands for Shift + // SS3 with small letter stands for Ctrl but we don't handle that here + if (cmd & 32) + key->modifiers |= TERMO_KEYMOD_SHIFT; + + return TERMO_RES_KEY; +} + +// +// Handler for rxvt SS3-only key combinations +// + +static void +register_ss3 (termo_type_t type, termo_sym_t sym, + int modifier_set, unsigned char cmd) +{ + if (cmd < 0x40 || cmd >= 0x80) + return; + + ss3s[cmd - 0x40].type = type; + ss3s[cmd - 0x40].sym = sym; + ss3s[cmd - 0x40].modifier_set = modifier_set; + ss3s[cmd - 0x40].modifier_mask = 0; +} + // // Handler for SS3 keys with kpad alternate representations // @@ -147,22 +195,31 @@ register_csifunc (termo_type_t type, termo_sym_t sym, int number) } // -// URxvt seems to emit this instead of ~ when holding Ctrl +// rxvt seems to emit these instead of ~ when holding various modifiers // static termo_result_t -handle_csi_caret (termo_t *tk, +handle_csi_rxvt (termo_t *tk, termo_key_t *key, int cmd, long *arg, int args) { + termo_result_t res; switch (cmd) { case '^': - { - termo_result_t res = handle_csifunc (tk, key, cmd, arg, args); + res = handle_csifunc (tk, key, cmd, arg, args); if (res == TERMO_RES_KEY) key->modifiers |= TERMO_KEYMOD_CTRL; return res; - } + case '$': + res = handle_csifunc (tk, key, cmd, arg, args); + if (res == TERMO_RES_KEY) + key->modifiers |= TERMO_KEYMOD_SHIFT; + return res; + case '@': + res = handle_csifunc (tk, key, cmd, arg, args); + if (res == TERMO_RES_KEY) + key->modifiers |= TERMO_KEYMOD_CTRL | TERMO_KEYMOD_SHIFT; + return res; default: return TERMO_RES_NONE; } @@ -489,6 +546,22 @@ register_keys (void) register_csi_ss3 (TERMO_TYPE_FUNCTION, 3, 'R'); register_csi_ss3 (TERMO_TYPE_FUNCTION, 4, 'S'); + // Handle Shift-modified rxvt cursor keys (CSI a, CSI b, CSI c, CSI d) + csi_handlers['a' - 0x40] = &handle_csi_cursor; + csi_handlers['b' - 0x40] = &handle_csi_cursor; + csi_handlers['c' - 0x40] = &handle_csi_cursor; + csi_handlers['d' - 0x40] = &handle_csi_cursor; + + // Handle Ctrl-modified rxvt cursor keys (SS3 a, SS3 b, SS3 c, SS3 d) + register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_UP, TERMO_KEYMOD_CTRL, 'a'); + register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_DOWN, TERMO_KEYMOD_CTRL, 'b'); + register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_RIGHT, TERMO_KEYMOD_CTRL, 'c'); + register_ss3 (TERMO_TYPE_KEYSYM, TERMO_SYM_LEFT, TERMO_KEYMOD_CTRL, 'd'); + + // Unfortunately Ctrl-Shift-modified rxvt cursor keys get eaten up by + // csi_ss3s as unmodified but rxvt-unicode only seems to output Shift codes + // for them anyway, so it's not a huge loss. + register_csi_ss3_full (TERMO_TYPE_KEYSYM, TERMO_SYM_TAB, TERMO_KEYMOD_SHIFT, TERMO_KEYMOD_SHIFT, 'Z'); @@ -550,17 +623,9 @@ register_keys (void) csi_handlers['y' - 0x40] = &handle_csi_y; - // URxvt - register_csi_ss3_full (TERMO_TYPE_KEYSYM, TERMO_SYM_UP, - TERMO_KEYMOD_CTRL, TERMO_KEYMOD_CTRL, 'a'); - register_csi_ss3_full (TERMO_TYPE_KEYSYM, TERMO_SYM_DOWN, - TERMO_KEYMOD_CTRL, TERMO_KEYMOD_CTRL, 'b'); - register_csi_ss3_full (TERMO_TYPE_KEYSYM, TERMO_SYM_RIGHT, - TERMO_KEYMOD_CTRL, TERMO_KEYMOD_CTRL, 'c'); - register_csi_ss3_full (TERMO_TYPE_KEYSYM, TERMO_SYM_LEFT, - TERMO_KEYMOD_CTRL, TERMO_KEYMOD_CTRL, 'd'); - - csi_handlers['^' - 0x40] = &handle_csi_caret; + csi_handlers['^' - 0x40] = &handle_csi_rxvt; + csi_handlers['$' - 0x40] = &handle_csi_rxvt; + csi_handlers['@' - 0x40] = &handle_csi_rxvt; keyinfo_initialised = 1; return 1; -- cgit v1.2.3-70-g09d2