=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/input-keys.c,v retrieving revision 1.74 retrieving revision 1.75 diff -u -r1.74 -r1.75 --- src/usr.bin/tmux/input-keys.c 2020/05/16 16:35:13 1.74 +++ src/usr.bin/tmux/input-keys.c 2020/05/16 16:38:55 1.75 @@ -1,4 +1,4 @@ -/* $OpenBSD: input-keys.c,v 1.74 2020/05/16 16:35:13 nicm Exp $ */ +/* $OpenBSD: input-keys.c,v 1.75 2020/05/16 16:38:55 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -433,9 +433,9 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key) { struct input_key_entry *ike; - size_t datalen; - key_code justkey, newkey; + key_code justkey, newkey, outkey; struct utf8_data ud; + char tmp[64], modifier; /* Mouse keys need a pane. */ if (KEYC_IS_MOUSE(key)) @@ -460,7 +460,7 @@ * If this is a normal 7-bit key, just send it, with a leading escape * if necessary. If it is a UTF-8 key, split it and send it. */ - justkey = (key & ~KEYC_META); + justkey = (key & ~(KEYC_META|KEYC_IMPLIED_META)); if (justkey <= 0x7f) { if (key & KEYC_META) bufferevent_write(bev, "\033", 1); @@ -488,18 +488,106 @@ ike = input_key_get(key); if (ike == NULL && (key & KEYC_META) && (~key & KEYC_IMPLIED_META)) ike = input_key_get(key & ~KEYC_META); - if (ike == NULL) { - log_debug("key 0x%llx missing", key); - return (-1); + if (ike != NULL) { + log_debug("found key 0x%llx: \"%s\"", key, ike->data); + if (key & KEYC_META && (~key & KEYC_IMPLIED_META)) + bufferevent_write(bev, "\033", 1); + bufferevent_write(bev, ike->data, strlen(ike->data)); + return (0); } - datalen = strlen(ike->data); - log_debug("found key 0x%llx: \"%s\"", key, ike->data); - /* Prefix a \033 for escape. */ - if (key & KEYC_META && (~key & KEYC_IMPLIED_META)) - bufferevent_write(bev, "\033", 1); - bufferevent_write(bev, ike->data, datalen); + /* No builtin key sequence; construct an extended key sequence. */ + outkey = (key & KEYC_MASK_KEY); + if (outkey >= KEYC_BASE) { + switch (outkey) { + case KEYC_IC: + outkey = 2; + break; + case KEYC_DC: + outkey = 3; + break; + case KEYC_PPAGE: + outkey = 5; + break; + case KEYC_NPAGE: + outkey = 6; + break; + case KEYC_HOME: + outkey = 7; + break; + case KEYC_END: + outkey = 8; + break; + case KEYC_F1: + outkey = 11; + break; + case KEYC_F2: + outkey = 12; + break; + case KEYC_F3: + outkey = 13; + break; + case KEYC_F4: + outkey = 14; + break; + case KEYC_F5: + outkey = 15; + break; + case KEYC_F6: + outkey = 17; + break; + case KEYC_F7: + outkey = 18; + break; + case KEYC_F8: + outkey = 19; + break; + case KEYC_F9: + outkey = 20; + break; + case KEYC_F10: + outkey = 21; + break; + case KEYC_F11: + outkey = 23; + break; + case KEYC_F12: + outkey = 24; + break; + default: + goto missing; + } + } + switch (key & KEYC_MASK_MODIFIERS) { + case KEYC_SHIFT: + modifier = '2'; + break; + case KEYC_META: + modifier = '3'; + break; + case KEYC_SHIFT|KEYC_META: + modifier = '4'; + break; + case KEYC_CTRL: + modifier = '5'; + break; + case KEYC_SHIFT|KEYC_CTRL: + modifier = '6'; + break; + case KEYC_META|KEYC_CTRL: + modifier = '7'; + break; + case KEYC_SHIFT|KEYC_META|KEYC_CTRL: + modifier = '8'; + break; + } + xsnprintf(tmp, sizeof tmp, "\033[%llu;%cu", outkey, modifier); + bufferevent_write(bev, tmp, strlen(tmp)); return (0); + +missing: + log_debug("key 0x%llx missing", key); + return (-1); } /* Get mouse event string. */