=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/tty-keys.c,v retrieving revision 1.86 retrieving revision 1.87 diff -u -r1.86 -r1.87 --- src/usr.bin/tmux/tty-keys.c 2016/04/26 22:19:22 1.86 +++ src/usr.bin/tmux/tty-keys.c 2016/04/27 16:40:12 1.87 @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-keys.c,v 1.86 2016/04/26 22:19:22 nicm Exp $ */ +/* $OpenBSD: tty-keys.c,v 1.87 2016/04/27 16:40:12 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -41,7 +41,7 @@ static struct tty_key *tty_keys_find(struct tty *, const char *, size_t, size_t *); static int tty_keys_next1(struct tty *, const char *, size_t, key_code *, - size_t *); + size_t *, int); static void tty_keys_callback(int, short, void *); static int tty_keys_mouse(struct tty *, const char *, size_t, size_t *); @@ -466,7 +466,7 @@ /* Look up part of the next key. */ static int tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key, - size_t *size) + size_t *size, int expired) { struct tty_key *tk, *tk1; struct utf8_data ud; @@ -474,36 +474,38 @@ u_int i; wchar_t wc; - log_debug("next key is %zu (%.*s)", len, (int)len, buf); + log_debug("next key is %zu (%.*s) (expired=%d)", len, (int)len, buf, + expired); - /* Empty buffer is a partial key. */ - if (len == 0) - return (1); - /* Is this a known key? */ tk = tty_keys_find(tty, buf, len, size); - if (tk != NULL) { + if (tk != NULL && tk->key != KEYC_UNKNOWN) { tk1 = tk; do - log_debug("keys in list: %#llx", tk->key); + log_debug("keys in list: %#llx", tk1->key); while ((tk1 = tk1->next) != NULL); + if (tk->next != NULL && !expired) + return (1); *key = tk->key; - return (tk->next != NULL); + return (0); } /* Is this valid UTF-8? */ more = utf8_open(&ud, (u_char)*buf); if (more == UTF8_MORE) { *size = ud.size; - if (len < ud.size) - return (1); + if (len < ud.size) { + if (!expired) + return (1); + return (-1); + } for (i = 1; i < ud.size; i++) more = utf8_append(&ud, (u_char)buf[i]); if (more != UTF8_DONE) - return (0); + return (-1); if (utf8_combine(&ud, &wc) != UTF8_DONE) - return (0); + return (-1); *key = wc; log_debug("UTF-8 key %.*s %#llx", (int)ud.size, buf, *key); @@ -524,7 +526,7 @@ const char *buf; size_t len, size; cc_t bspace; - int delay, expired = 0; + int delay, expired = 0, n; key_code key; /* Get key buffer. */ @@ -550,61 +552,49 @@ } first_key: - /* If escape is at the start, try without it. */ + /* Handle keys starting with escape. */ if (*buf == '\033') { - switch (tty_keys_next1 (tty, buf + 1, len - 1, &key, &size)) { - case 0: /* found */ - if (key != KEYC_UNKNOWN) - key |= KEYC_ESCAPE; - size++; /* include escape */ + /* A single escape goes as-is if the timer has expired. */ + if (expired && len == 1) { + key = '\033'; + size = 1; goto complete_key; - case -1: /* not found */ - break; - case 1: - if (expired) - goto complete_key; - goto partial_key; } - } - /* Try with the escape. */ - switch (tty_keys_next1 (tty, buf, len, &key, &size)) { - case 0: /* found */ - goto complete_key; - case -1: /* not found */ - break; - case 1: - if (expired) + /* Look for a key without the escape. */ + n = tty_keys_next1(tty, buf + 1, len - 1, &key, &size, expired); + if (n == 0) { /* found */ + key |= KEYC_ESCAPE; + size++; goto complete_key; - goto partial_key; - } + } + if (n == 1) /* partial */ + goto partial_key; - /* Is this an an xterm(1) key? */ - switch (xterm_keys_find(buf, len, &size, &key)) { - case 0: /* found */ - goto complete_key; - case -1: /* not found */ - break; - case 1: - if (expired) - break; - goto partial_key; - } + /* Try with the escape. */ + n = tty_keys_next1(tty, buf, len, &key, &size, expired); + if (n == 0) /* found */ + goto complete_key; + if (n == 1) + goto partial_key; - /* - * If this starts with escape and is at least two keys, it must be - * complete even if the timer has not expired, because otherwise - * tty_keys_next1 would have found a partial key. If just an escape - * alone, it needs to wait for the timer first. - */ - if (*buf == '\033') { + /* Is this an an xterm(1) key? */ + n = xterm_keys_find(buf, len, &size, &key); + if (n == 0) /* found */ + goto complete_key; + if (n == 1 && !expired) + goto partial_key; + + /* + * If this is at least two keys, then it must be complete - + * whether or not the timer has expired - otherwise + * tty_keys_next1 would have returned a partial. + */ if (len >= 2) { key = (u_char)buf[1] | KEYC_ESCAPE; size = 2; goto complete_key; } - if (!expired) - goto partial_key; } /* No longer key found, use the first character. */