version 1.50, 2013/03/21 16:52:02 |
version 1.51, 2013/03/21 18:44:47 |
|
|
tdkr = &tty_default_raw_keys[i]; |
tdkr = &tty_default_raw_keys[i]; |
|
|
s = tdkr->string; |
s = tdkr->string; |
if (s[0] == '\033' && s[1] != '\0') |
if (*s != '\0') |
tty_keys_add(tty, s + 1, tdkr->key); |
tty_keys_add(tty, s, tdkr->key); |
} |
} |
for (i = 0; i < nitems(tty_default_code_keys); i++) { |
for (i = 0; i < nitems(tty_default_code_keys); i++) { |
tdkc = &tty_default_code_keys[i]; |
tdkc = &tty_default_code_keys[i]; |
|
|
s = tty_term_string(tty->term, tdkc->code); |
s = tty_term_string(tty->term, tdkc->code); |
if (s[0] == '\033' || s[1] == '\0') |
if (*s != '\0') |
tty_keys_add(tty, s + 1, tdkc->key); |
tty_keys_add(tty, s, tdkc->key); |
|
|
} |
} |
|
|
|
tty_keys_add(tty, "abc", 'x'); |
} |
} |
|
|
/* Free the entire key tree. */ |
/* Free the entire key tree. */ |
|
|
cc_t bspace; |
cc_t bspace; |
int key, delay; |
int key, delay; |
|
|
|
/* Get key buffer. */ |
buf = EVBUFFER_DATA(tty->event->input); |
buf = EVBUFFER_DATA(tty->event->input); |
len = EVBUFFER_LENGTH(tty->event->input); |
len = EVBUFFER_LENGTH(tty->event->input); |
if (len == 0) |
if (len == 0) |
return (0); |
return (0); |
log_debug("keys are %zu (%.*s)", len, (int) len, buf); |
log_debug("keys are %zu (%.*s)", len, (int) len, buf); |
|
|
/* If a normal key, return it. */ |
|
if (*buf != '\033') { |
|
key = (u_char) *buf; |
|
evbuffer_drain(tty->event->input, 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 handle_key; |
|
} |
|
|
|
/* Is this device attributes response? */ |
/* Is this device attributes response? */ |
switch (tty_keys_device(tty, buf, len, &size)) { |
switch (tty_keys_device(tty, buf, len, &size)) { |
case 0: /* yes */ |
case 0: /* yes */ |
evbuffer_drain(tty->event->input, size); |
|
key = KEYC_NONE; |
key = KEYC_NONE; |
goto handle_key; |
goto complete_key; |
case -1: /* no, or not valid */ |
case -1: /* no, or not valid */ |
break; |
break; |
case 1: /* partial */ |
case 1: /* partial */ |
|
|
/* Is this a mouse key press? */ |
/* Is this a mouse key press? */ |
switch (tty_keys_mouse(tty, buf, len, &size)) { |
switch (tty_keys_mouse(tty, buf, len, &size)) { |
case 0: /* yes */ |
case 0: /* yes */ |
evbuffer_drain(tty->event->input, size); |
|
key = KEYC_MOUSE; |
key = KEYC_MOUSE; |
goto handle_key; |
goto complete_key; |
case -1: /* no, or not valid */ |
case -1: /* no, or not valid */ |
break; |
break; |
case 1: /* partial */ |
case 1: /* partial */ |
|
|
/* Try to parse a key with an xterm-style modifier. */ |
/* Try to parse a key with an xterm-style modifier. */ |
switch (xterm_keys_find(buf, len, &size, &key)) { |
switch (xterm_keys_find(buf, len, &size, &key)) { |
case 0: /* found */ |
case 0: /* found */ |
evbuffer_drain(tty->event->input, size); |
key = KEYC_NONE; |
goto handle_key; |
goto complete_key; |
case -1: /* not found */ |
case -1: /* not found */ |
break; |
break; |
case 1: |
case 1: |
|
|
} |
} |
|
|
/* Look for matching key string and return if found. */ |
/* Look for matching key string and return if found. */ |
tk = tty_keys_find(tty, buf + 1, len - 1, &size); |
tk = tty_keys_find(tty, buf, len, &size); |
if (tk != NULL) { |
if (tk != NULL) { |
|
if (tk->next != NULL) |
|
goto partial_key; |
key = tk->key; |
key = tk->key; |
goto found_key; |
goto complete_key; |
} |
} |
|
|
/* Skip the escape. */ |
/* Is this a meta key? */ |
buf++; |
if (len >= 2 && buf[0] == '\033') { |
len--; |
if (buf[1] != '\033') { |
|
key = buf[1] | KEYC_ESCAPE; |
|
size = 2; |
|
goto complete_key; |
|
} |
|
|
/* Is there a normal key following? */ |
|
if (len != 0 && *buf != '\033') { |
|
key = *buf | KEYC_ESCAPE; |
|
evbuffer_drain(tty->event->input, 2); |
|
goto handle_key; |
|
} |
|
|
|
/* Or a key string? */ |
|
if (len > 1) { |
|
tk = tty_keys_find(tty, buf + 1, len - 1, &size); |
tk = tty_keys_find(tty, buf + 1, len - 1, &size); |
if (tk != NULL) { |
if (tk != NULL) { |
key = tk->key | KEYC_ESCAPE; |
|
size++; /* include escape */ |
size++; /* include escape */ |
goto found_key; |
if (tk->next != NULL) |
|
goto partial_key; |
|
key = tk->key; |
|
if (key != KEYC_NONE) |
|
key |= KEYC_ESCAPE; |
|
goto complete_key; |
} |
} |
} |
} |
|
|
/* Escape and then nothing useful - fall through. */ |
first_key: |
|
/* No key found, take first. */ |
|
key = (u_char) *buf; |
|
size = 1; |
|
|
partial_key: |
|
/* |
/* |
* Escape but no key string. If have already seen an escape and the |
* Check for backspace key using termios VERASE - the terminfo |
* timer has expired, give up waiting and send the escape. |
* kbs entry is extremely unreliable, so cannot be safely |
|
* used. termios should have a better idea. |
*/ |
*/ |
if ((tty->flags & TTY_ESCAPE) && |
bspace = tty->tio.c_cc[VERASE]; |
evtimer_initialized(&tty->key_timer) && |
if (bspace != _POSIX_VDISABLE && key == bspace) |
!evtimer_pending(&tty->key_timer, NULL)) { |
key = KEYC_BSPACE; |
evbuffer_drain(tty->event->input, 1); |
|
key = '\033'; |
|
goto handle_key; |
|
} |
|
|
|
/* Fall through to start the timer. */ |
goto complete_key; |
|
|
start_timer: |
partial_key: |
/* If already waiting for timer, do nothing. */ |
log_debug("partial key %.*s", (int) len, buf); |
if (evtimer_initialized(&tty->key_timer) && |
|
evtimer_pending(&tty->key_timer, NULL)) |
/* If timer is going, check for expiration. */ |
|
if (tty->flags & TTY_TIMER) { |
|
if (evtimer_initialized(&tty->key_timer) && |
|
!evtimer_pending(&tty->key_timer, NULL)) |
|
goto first_key; |
return (0); |
return (0); |
|
} |
|
|
/* Start the timer and wait for expiry or more data. */ |
/* Get the time period. */ |
delay = options_get_number(&global_options, "escape-time"); |
delay = options_get_number(&global_options, "escape-time"); |
tv.tv_sec = delay / 1000; |
tv.tv_sec = delay / 1000; |
tv.tv_usec = (delay % 1000) * 1000L; |
tv.tv_usec = (delay % 1000) * 1000L; |
|
|
|
/* Start the timer. */ |
if (event_initialized(&tty->key_timer)) |
if (event_initialized(&tty->key_timer)) |
evtimer_del(&tty->key_timer); |
evtimer_del(&tty->key_timer); |
evtimer_set(&tty->key_timer, tty_keys_callback, tty); |
evtimer_set(&tty->key_timer, tty_keys_callback, tty); |
evtimer_add(&tty->key_timer, &tv); |
evtimer_add(&tty->key_timer, &tv); |
|
|
tty->flags |= TTY_ESCAPE; |
tty->flags |= TTY_TIMER; |
return (0); |
return (0); |
|
|
found_key: |
complete_key: |
if (tk->next != NULL) { |
log_debug("complete key %.*s %#x", (int) size, buf, key); |
/* Partial key. Start the timer if not already expired. */ |
|
if (!(tty->flags & TTY_ESCAPE)) |
|
goto start_timer; |
|
|
|
/* Otherwise, if no key, send the escape alone. */ |
/* Remove data from buffer. */ |
if (tk->key == KEYC_NONE) |
evbuffer_drain(tty->event->input, size); |
goto partial_key; |
|
|
|
/* Or fall through to send the partial key found. */ |
/* Remove key timer. */ |
} |
|
evbuffer_drain(tty->event->input, size + 1); |
|
|
|
goto handle_key; |
|
|
|
handle_key: |
|
if (event_initialized(&tty->key_timer)) |
if (event_initialized(&tty->key_timer)) |
evtimer_del(&tty->key_timer); |
evtimer_del(&tty->key_timer); |
|
tty->flags &= ~TTY_TIMER; |
|
|
|
/* Fire the key. */ |
if (key != KEYC_NONE) |
if (key != KEYC_NONE) |
server_client_handle_key(tty->client, key); |
server_client_handle_key(tty->client, key); |
|
|
tty->flags &= ~TTY_ESCAPE; |
|
return (1); |
return (1); |
} |
} |
|
|
|
|
{ |
{ |
struct tty *tty = data; |
struct tty *tty = data; |
|
|
if (!(tty->flags & TTY_ESCAPE)) |
if (tty->flags & TTY_TIMER) { |
return; |
while (tty_keys_next(tty)) |
|
; |
while (tty_keys_next(tty)) |
} |
; |
|
} |
} |
|
|
/* |
/* |