Fixes for extended keys: 1) allow C-x and C-X to be bound separately

since some terminals report them differently 2) use the "backspace"
option to translate backspace 3) map ctrl which are have the ctrl
implied (such as C-x) properly when the terminal reports both the key
and the modifier.

Note that any key bindings for C-X where C-x is meant must now be
changed.
This commit is contained in:
nicm 2021-04-07 07:30:02 +00:00
parent 10470cea67
commit ba99996676
2 changed files with 48 additions and 23 deletions

View File

@ -45,9 +45,9 @@ static const struct {
{ "F11", KEYC_F11|KEYC_IMPLIED_META }, { "F11", KEYC_F11|KEYC_IMPLIED_META },
{ "F12", KEYC_F12|KEYC_IMPLIED_META }, { "F12", KEYC_F12|KEYC_IMPLIED_META },
{ "IC", KEYC_IC|KEYC_IMPLIED_META }, { "IC", KEYC_IC|KEYC_IMPLIED_META },
{ "Insert", KEYC_IC|KEYC_IMPLIED_META }, { "Insert", KEYC_IC|KEYC_IMPLIED_META },
{ "DC", KEYC_DC|KEYC_IMPLIED_META }, { "DC", KEYC_DC|KEYC_IMPLIED_META },
{ "Delete", KEYC_DC|KEYC_IMPLIED_META }, { "Delete", KEYC_DC|KEYC_IMPLIED_META },
{ "Home", KEYC_HOME|KEYC_IMPLIED_META }, { "Home", KEYC_HOME|KEYC_IMPLIED_META },
{ "End", KEYC_END|KEYC_IMPLIED_META }, { "End", KEYC_END|KEYC_IMPLIED_META },
{ "NPage", KEYC_NPAGE|KEYC_IMPLIED_META }, { "NPage", KEYC_NPAGE|KEYC_IMPLIED_META },
@ -70,7 +70,7 @@ static const struct {
{ "Right", KEYC_RIGHT|KEYC_CURSOR|KEYC_IMPLIED_META }, { "Right", KEYC_RIGHT|KEYC_CURSOR|KEYC_IMPLIED_META },
/* Numeric keypad. */ /* Numeric keypad. */
{ "KP/", KEYC_KP_SLASH|KEYC_KEYPAD }, { "KP/", KEYC_KP_SLASH|KEYC_KEYPAD },
{ "KP*", KEYC_KP_STAR|KEYC_KEYPAD }, { "KP*", KEYC_KP_STAR|KEYC_KEYPAD },
{ "KP-", KEYC_KP_MINUS|KEYC_KEYPAD }, { "KP-", KEYC_KP_MINUS|KEYC_KEYPAD },
{ "KP7", KEYC_KP_SEVEN|KEYC_KEYPAD }, { "KP7", KEYC_KP_SEVEN|KEYC_KEYPAD },
@ -164,7 +164,7 @@ key_string_get_modifiers(const char **string)
key_code key_code
key_string_lookup_string(const char *string) key_string_lookup_string(const char *string)
{ {
static const char *other = "!#()+,-.0123456789:;<=>'\r\t"; static const char *other = "!#()+,-.0123456789:;<=>'\r\t\177";
key_code key, modifiers; key_code key, modifiers;
u_int u, i; u_int u, i;
struct utf8_data ud, *udp; struct utf8_data ud, *udp;
@ -181,8 +181,8 @@ key_string_lookup_string(const char *string)
/* Is this a hexadecimal value? */ /* Is this a hexadecimal value? */
if (string[0] == '0' && string[1] == 'x') { if (string[0] == '0' && string[1] == 'x') {
if (sscanf(string + 2, "%x", &u) != 1) if (sscanf(string + 2, "%x", &u) != 1)
return (KEYC_UNKNOWN); return (KEYC_UNKNOWN);
mlen = wctomb(m, u); mlen = wctomb(m, u);
if (mlen <= 0 || mlen > MB_LEN_MAX) if (mlen <= 0 || mlen > MB_LEN_MAX)
return (KEYC_UNKNOWN); return (KEYC_UNKNOWN);
@ -238,11 +238,11 @@ key_string_lookup_string(const char *string)
} }
/* Convert the standard control keys. */ /* Convert the standard control keys. */
if (key < KEYC_BASE && (modifiers & KEYC_CTRL) && !strchr(other, key)) { if (key < KEYC_BASE && (modifiers & KEYC_CTRL) &&
strchr(other, key) == NULL &&
(key < 64 || key > 95)) {
if (key >= 97 && key <= 122) if (key >= 97 && key <= 122)
key -= 96; key -= 96;
else if (key >= 64 && key <= 95)
key -= 64;
else if (key == 32) else if (key == 32)
key = 0; key = 0;
else if (key == 63) else if (key == 63)

View File

@ -61,7 +61,7 @@ static int tty_keys_extended_device_attributes(struct tty *, const char *,
/* Default raw keys. */ /* Default raw keys. */
struct tty_default_key_raw { struct tty_default_key_raw {
const char *string; const char *string;
key_code key; key_code key;
}; };
static const struct tty_default_key_raw tty_default_raw_keys[] = { static const struct tty_default_key_raw tty_default_raw_keys[] = {
/* Application escape. */ /* Application escape. */
@ -262,7 +262,7 @@ static const key_code tty_default_xterm_modifiers[] = {
*/ */
struct tty_default_key_code { struct tty_default_key_code {
enum tty_code_code code; enum tty_code_code code;
key_code key; key_code key;
}; };
static const struct tty_default_key_code tty_default_code_keys[] = { static const struct tty_default_key_code tty_default_code_keys[] = {
/* Function keys. */ /* Function keys. */
@ -420,7 +420,7 @@ tty_keys_add(struct tty *tty, const char *s, key_code key)
{ {
struct tty_key *tk; struct tty_key *tk;
size_t size; size_t size;
const char *keystr; const char *keystr;
keystr = key_string_lookup_key(key, 1); keystr = key_string_lookup_key(key, 1);
if ((tk = tty_keys_find(tty, s, strlen(s), &size)) == NULL) { if ((tk = tty_keys_find(tty, s, strlen(s), &size)) == NULL) {
@ -477,7 +477,7 @@ tty_keys_build(struct tty *tty)
const struct tty_default_key_raw *tdkr; const struct tty_default_key_raw *tdkr;
const struct tty_default_key_xterm *tdkx; const struct tty_default_key_xterm *tdkx;
const struct tty_default_key_code *tdkc; const struct tty_default_key_code *tdkc;
u_int i, j; u_int i, j;
const char *s; const char *s;
struct options_entry *o; struct options_entry *o;
struct options_array_item *a; struct options_array_item *a;
@ -869,6 +869,8 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
size_t end; size_t end;
u_int number, modifiers; u_int number, modifiers;
char tmp[64]; char tmp[64];
cc_t bspace;
key_code nkey;
*size = 0; *size = 0;
@ -911,38 +913,61 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
} }
*size = end + 1; *size = end + 1;
/* Store the key and modifiers. */ /* Store the key. */
*key = number; bspace = tty->tio.c_cc[VERASE];
if (bspace != _POSIX_VDISABLE && number == bspace)
nkey = KEYC_BSPACE;
else
nkey = number;
/* Update the modifiers. */
switch (modifiers) { switch (modifiers) {
case 2: case 2:
(*key) |= KEYC_SHIFT; nkey |= KEYC_SHIFT;
break; break;
case 3: case 3:
(*key) |= (KEYC_META|KEYC_IMPLIED_META); nkey |= (KEYC_META|KEYC_IMPLIED_META);
break; break;
case 4: case 4:
(*key) |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META); nkey |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META);
break; break;
case 5: case 5:
(*key) |= KEYC_CTRL; nkey |= KEYC_CTRL;
break; break;
case 6: case 6:
(*key) |= (KEYC_SHIFT|KEYC_CTRL); nkey |= (KEYC_SHIFT|KEYC_CTRL);
break; break;
case 7: case 7:
(*key) |= (KEYC_META|KEYC_CTRL); nkey |= (KEYC_META|KEYC_CTRL);
break; break;
case 8: case 8:
(*key) |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL); nkey |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL);
break; break;
default: default:
*key = KEYC_NONE; *key = KEYC_NONE;
break; break;
} }
/* Don't allow both KEYC_CTRL and implied. */
if ((nkey & KEYC_CTRL) && (nkey & KEYC_MASK_KEY) < 32)
nkey &= ~KEYC_CTRL;
if ((nkey & KEYC_MASK_MODIFIERS) == KEYC_CTRL) {
nkey &= KEYC_MASK_KEY;
if (nkey >= 97 && nkey <= 122)
nkey -= 96;
else if (nkey == 32)
nkey = 0;
else if (nkey == 63)
nkey = 127;
else
nkey |= KEYC_CTRL;
}
if (log_get_level() != 0) { if (log_get_level() != 0) {
log_debug("%s: extended key %.*s is %llx (%s)", c->name, log_debug("%s: extended key %.*s is %llx (%s)", c->name,
(int)*size, buf, *key, key_string_lookup_key(*key, 1)); (int)*size, buf, nkey, key_string_lookup_key(nkey, 1));
} }
*key = nkey;
return (0); return (0);
} }