Add tests for legacy letter key encodings
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user