mirror of
https://github.com/tmux/tmux.git
synced 2024-12-14 10:58:48 +00:00
Merge branch 'obsd-master'
This commit is contained in:
commit
bac7a68023
125
tty-keys.c
125
tty-keys.c
@ -41,7 +41,7 @@ static struct tty_key *tty_keys_find1(struct tty_key *, const char *, size_t,
|
|||||||
static struct tty_key *tty_keys_find(struct tty *, const char *, size_t,
|
static struct tty_key *tty_keys_find(struct tty *, const char *, size_t,
|
||||||
size_t *);
|
size_t *);
|
||||||
static int tty_keys_next1(struct tty *, const char *, size_t, key_code *,
|
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 void tty_keys_callback(int, short, void *);
|
||||||
static int tty_keys_mouse(struct tty *, const char *, size_t, size_t *);
|
static int tty_keys_mouse(struct tty *, const char *, size_t, size_t *);
|
||||||
|
|
||||||
@ -466,7 +466,7 @@ tty_keys_find1(struct tty_key *tk, const char *buf, size_t len, size_t *size)
|
|||||||
/* Look up part of the next key. */
|
/* Look up part of the next key. */
|
||||||
static int
|
static int
|
||||||
tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key,
|
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 tty_key *tk, *tk1;
|
||||||
struct utf8_data ud;
|
struct utf8_data ud;
|
||||||
@ -474,36 +474,38 @@ tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key,
|
|||||||
u_int i;
|
u_int i;
|
||||||
wchar_t wc;
|
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? */
|
/* Is this a known key? */
|
||||||
tk = tty_keys_find(tty, buf, len, size);
|
tk = tty_keys_find(tty, buf, len, size);
|
||||||
if (tk != NULL) {
|
if (tk != NULL && tk->key != KEYC_UNKNOWN) {
|
||||||
tk1 = tk;
|
tk1 = tk;
|
||||||
do
|
do
|
||||||
log_debug("keys in list: %#llx", tk->key);
|
log_debug("keys in list: %#llx", tk1->key);
|
||||||
while ((tk1 = tk1->next) != NULL);
|
while ((tk1 = tk1->next) != NULL);
|
||||||
|
if (tk->next != NULL && !expired)
|
||||||
|
return (1);
|
||||||
*key = tk->key;
|
*key = tk->key;
|
||||||
return (tk->next != NULL);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is this valid UTF-8? */
|
/* Is this valid UTF-8? */
|
||||||
more = utf8_open(&ud, (u_char)*buf);
|
more = utf8_open(&ud, (u_char)*buf);
|
||||||
if (more == UTF8_MORE) {
|
if (more == UTF8_MORE) {
|
||||||
*size = ud.size;
|
*size = ud.size;
|
||||||
if (len < ud.size)
|
if (len < ud.size) {
|
||||||
return (1);
|
if (!expired)
|
||||||
|
return (1);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
for (i = 1; i < ud.size; i++)
|
for (i = 1; i < ud.size; i++)
|
||||||
more = utf8_append(&ud, (u_char)buf[i]);
|
more = utf8_append(&ud, (u_char)buf[i]);
|
||||||
if (more != UTF8_DONE)
|
if (more != UTF8_DONE)
|
||||||
return (0);
|
return (-1);
|
||||||
|
|
||||||
if (utf8_combine(&ud, &wc) != UTF8_DONE)
|
if (utf8_combine(&ud, &wc) != UTF8_DONE)
|
||||||
return (0);
|
return (-1);
|
||||||
*key = wc;
|
*key = wc;
|
||||||
|
|
||||||
log_debug("UTF-8 key %.*s %#llx", (int)ud.size, buf, *key);
|
log_debug("UTF-8 key %.*s %#llx", (int)ud.size, buf, *key);
|
||||||
@ -524,7 +526,7 @@ tty_keys_next(struct tty *tty)
|
|||||||
const char *buf;
|
const char *buf;
|
||||||
size_t len, size;
|
size_t len, size;
|
||||||
cc_t bspace;
|
cc_t bspace;
|
||||||
int delay, expired = 0;
|
int delay, expired = 0, n;
|
||||||
key_code key;
|
key_code key;
|
||||||
|
|
||||||
/* Get key buffer. */
|
/* Get key buffer. */
|
||||||
@ -550,76 +552,54 @@ tty_keys_next(struct tty *tty)
|
|||||||
}
|
}
|
||||||
|
|
||||||
first_key:
|
first_key:
|
||||||
/* If escape is at the start, try without it. */
|
/* Handle keys starting with escape. */
|
||||||
if (*buf == '\033') {
|
if (*buf == '\033') {
|
||||||
switch (tty_keys_next1 (tty, buf + 1, len - 1, &key, &size)) {
|
/* A single escape goes as-is if the timer has expired. */
|
||||||
case 0: /* found */
|
if (expired && len == 1) {
|
||||||
if (key != KEYC_UNKNOWN)
|
key = '\033';
|
||||||
key |= KEYC_ESCAPE;
|
size = 1;
|
||||||
size++; /* include escape */
|
|
||||||
goto complete_key;
|
goto complete_key;
|
||||||
case -1: /* not found */
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (expired)
|
|
||||||
goto complete_key;
|
|
||||||
goto partial_key;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Try with the escape. */
|
/* Look for a key without the escape. */
|
||||||
switch (tty_keys_next1 (tty, buf, len, &key, &size)) {
|
n = tty_keys_next1(tty, buf + 1, len - 1, &key, &size, expired);
|
||||||
case 0: /* found */
|
if (n == 0) { /* found */
|
||||||
goto complete_key;
|
key |= KEYC_ESCAPE;
|
||||||
case -1: /* not found */
|
size++;
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (expired)
|
|
||||||
goto complete_key;
|
goto complete_key;
|
||||||
goto partial_key;
|
}
|
||||||
}
|
if (n == 1) /* partial */
|
||||||
|
goto partial_key;
|
||||||
|
|
||||||
/* Is this an an xterm(1) key? */
|
/* Try with the escape. */
|
||||||
switch (xterm_keys_find(buf, len, &size, &key)) {
|
n = tty_keys_next1(tty, buf, len, &key, &size, expired);
|
||||||
case 0: /* found */
|
if (n == 0) /* found */
|
||||||
goto complete_key;
|
goto complete_key;
|
||||||
case -1: /* not found */
|
if (n == 1)
|
||||||
break;
|
goto partial_key;
|
||||||
case 1:
|
|
||||||
if (expired)
|
|
||||||
break;
|
|
||||||
goto partial_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/* Is this an an xterm(1) key? */
|
||||||
* If this starts with escape and is at least two keys, it must be
|
n = xterm_keys_find(buf, len, &size, &key);
|
||||||
* complete even if the timer has not expired, because otherwise
|
if (n == 0) /* found */
|
||||||
* tty_keys_next1 would have found a partial key. If just an escape
|
goto complete_key;
|
||||||
* alone, it needs to wait for the timer first.
|
if (n == 1 && !expired)
|
||||||
*/
|
goto partial_key;
|
||||||
if (*buf == '\033') {
|
|
||||||
|
/*
|
||||||
|
* 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) {
|
if (len >= 2) {
|
||||||
key = (u_char)buf[1] | KEYC_ESCAPE;
|
key = (u_char)buf[1] | KEYC_ESCAPE;
|
||||||
size = 2;
|
size = 2;
|
||||||
goto complete_key;
|
goto complete_key;
|
||||||
}
|
}
|
||||||
if (!expired)
|
|
||||||
goto partial_key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No longer key found, use the first character. */
|
/* No longer key found, use the first character. */
|
||||||
key = (u_char)*buf;
|
key = (u_char)*buf;
|
||||||
size = 1;
|
size = 1;
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for backspace key using termios VERASE - the terminfo
|
|
||||||
* kbs entry is extremely unreliable, so cannot be safely
|
|
||||||
* used. termios should have a better idea.
|
|
||||||
*/
|
|
||||||
bspace = tty->tio.c_cc[VERASE];
|
|
||||||
if (bspace != _POSIX_VDISABLE && key == bspace)
|
|
||||||
key = KEYC_BSPACE;
|
|
||||||
|
|
||||||
goto complete_key;
|
goto complete_key;
|
||||||
|
|
||||||
partial_key:
|
partial_key:
|
||||||
@ -652,6 +632,15 @@ partial_key:
|
|||||||
complete_key:
|
complete_key:
|
||||||
log_debug("complete key %.*s %#llx", (int)size, buf, key);
|
log_debug("complete key %.*s %#llx", (int)size, buf, key);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for backspace key using termios VERASE - the terminfo
|
||||||
|
* kbs entry is extremely unreliable, so cannot be safely
|
||||||
|
* used. termios should have a better idea.
|
||||||
|
*/
|
||||||
|
bspace = tty->tio.c_cc[VERASE];
|
||||||
|
if (bspace != _POSIX_VDISABLE && (key & KEYC_MASK_KEY) == bspace)
|
||||||
|
key = (key & KEYC_MASK_MOD) | KEYC_BSPACE;
|
||||||
|
|
||||||
/* Remove data from buffer. */
|
/* Remove data from buffer. */
|
||||||
evbuffer_drain(tty->event->input, size);
|
evbuffer_drain(tty->event->input, size);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user