Add tests for legacy letter key encodings

This commit is contained in:
Kovid Goyal
2021-01-13 08:31:52 +05:30
parent 78d45eb161
commit c519013b20
5 changed files with 466 additions and 21 deletions

View File

@@ -138,6 +138,7 @@ encode_function_key(const KeyEvent *ev, char *output) {
}
}
if (ev->mods.value == SHIFT && key_number == GLFW_FKEY_TAB) { SIMPLE("\x1b[Z"); }
if (ev->mods.value == CTRL && key_number == GLFW_FKEY_BACKSPACE) { SIMPLE("\x08"); }
#undef SIMPLE
#define S(number, trailer) key_number = number; csi_trailer = trailer; break
@@ -180,29 +181,105 @@ encode_function_key(const KeyEvent *ev, char *output) {
return serialize(&ed, output, csi_trailer);
}
static inline char
shifted_ascii_key(const uint32_t key) {
switch(key) {
/* start shifted key map (auto generated by gen-key-constants.py do not edit) */
case '`': return '~';
case '1': return '!';
case '2': return '@';
case '3': return '#';
case '4': return '$';
case '5': return '%';
case '6': return '^';
case '7': return '&';
case '8': return '*';
case '9': return '(';
case '0': return ')';
case '-': return '_';
case '=': return '+';
case '[': return '{';
case ']': return '}';
case '\\': return '|';
case ';': return ':';
case '\'': return '"';
case ',': return '<';
case '.': return '>';
case '/': return '?';
case 'a': return 'A';
case 'b': return 'B';
case 'c': return 'C';
case 'd': return 'D';
case 'e': return 'E';
case 'f': return 'F';
case 'g': return 'G';
case 'h': return 'H';
case 'i': return 'I';
case 'j': return 'J';
case 'k': return 'K';
case 'l': return 'L';
case 'm': return 'M';
case 'n': return 'N';
case 'o': return 'O';
case 'p': return 'P';
case 'q': return 'Q';
case 'r': return 'R';
case 's': return 'S';
case 't': return 'T';
case 'u': return 'U';
case 'v': return 'V';
case 'w': return 'W';
case 'x': return 'X';
case 'y': return 'Y';
case 'z': return 'Z';
/* end shifted key map */
default:
return 0;
}
}
static int
encode_printable_ascii_key_legacy(const KeyEvent *ev, char *output) {
if (!ev->mods.value) return snprintf(output, KEY_BUFFER_SIZE, "%c", (char)ev->key);
if (ev->disambiguate) return 0;
char shifted_key = 0;
if ('a' <= ev->key && ev->key <= 'z') shifted_key = ev->key + ('A' - 'a');
switch(ev->key) {
#define S(which, val) case which: shifted_key = val; break;
S('0', ')') S('9', '(') S('8', '*') S('7', '&') S('6', '^') S('5', '%') S('4', '$') S('3', '#') S('2', '@') S('1', '!')
S('`', '~') S('-', '_') S('=', '+') S('[', '{') S(']', '}') S('\\', '|') S(';', ':') S('\'', '"') S(',', '<') S('.', '>') S('/', '?')
#undef S
}
char shifted_key = shifted_ascii_key(ev->key);
shifted_key = (shifted_key && ev->mods.shift) ? shifted_key : (char)ev->key;
if (ev->mods.value == SHIFT)
return snprintf(output, KEY_BUFFER_SIZE, "%c", shifted_key);
if ((ev->mods.value == ALT || ev->mods.value == (SHIFT | ALT)))
return snprintf(output, KEY_BUFFER_SIZE, "\x1b%c", shifted_key);
if (ev->mods.value == CTRL && ev->key && 0x1f != ev->key)
return snprintf(output, KEY_BUFFER_SIZE, "%c", ev->key & 0x1f);
if (ev->mods.value == CTRL)
return snprintf(output, KEY_BUFFER_SIZE, "%c", ev->key & 0x3f);
if (ev->mods.value == (CTRL | ALT))
return snprintf(output, KEY_BUFFER_SIZE, "\x1b%c", ev->key & 0x1f);
return snprintf(output, KEY_BUFFER_SIZE, "\x1b%c", ev->key & 0x3f);
return 0;
}
static inline bool
is_legacy_ascii_key(uint32_t key) {
START_ALLOW_CASE_RANGE
switch (key) {
case 'a' ... 'z':
case '0' ... '9':
case '`':
case '-':
case '=':
case '[':
case ']':
case '\\':
case ';':
case '\'':
case ',':
case '.':
case '/':
return true;
default:
return false;
}
END_ALLOW_CASE_RANGE
}
static int
encode_key(const KeyEvent *ev, char *output) {
if (!ev->report_all_event_types && ev->action == RELEASE) return 0;
@@ -211,9 +288,14 @@ encode_key(const KeyEvent *ev, char *output) {
init_encoding_data(&ed, ev);
bool simple_encoding_ok = !ed.add_actions && !ed.add_alternates;
if (32 <= ev->key && ev->key <= 126 && simple_encoding_ok) {
int ret = encode_printable_ascii_key_legacy(ev, output);
if (ret > 0) return ret;
if (simple_encoding_ok) {
if (is_legacy_ascii_key(ev->key)) {
int ret = encode_printable_ascii_key_legacy(ev, output);
if (ret > 0) return ret;
} else if (ev->key == ' ' && ev->mods.value == CTRL) {
output[0] = 0;
return 1;
}
}
if (simple_encoding_ok && !ed.has_mods) return encode_utf8(ev->key, output);