diff options
Diffstat (limited to 'console-client/xkb/symname.c')
-rw-r--r-- | console-client/xkb/symname.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/console-client/xkb/symname.c b/console-client/xkb/symname.c index 9f219513..5815f288 100644 --- a/console-client/xkb/symname.c +++ b/console-client/xkb/symname.c @@ -1,3 +1,5 @@ +#include <limits.h> +#include <stdlib.h> #include <string.h> #define NEEDKTABLE #include "ks_tables.h" @@ -31,9 +33,10 @@ KeySym XStringToKeysym(char *s) { entry = &_XkeyTable[idx]; if ((entry[0] == sig1) && (entry[1] == sig2) && - !strcmp(s, (char *)entry + 4)) + !strcmp(s, (char *)entry + 6)) { - val = (entry[2] << 8) | entry[3]; + val = (entry[2] << 24) | (entry[3] << 16) | + (entry[4] << 8) | entry[5]; if (!val) val = XK_VoidSymbol; return val; @@ -86,11 +89,41 @@ KeySym XStringToKeysym(char *s) else if ('a' <= c && c <= 'f') val = (val<<4)+c-'a'+10; else if ('A' <= c && c <= 'F') val = (val<<4)+c-'A'+10; else return NoSymbol; + if (val > 0x10ffff) + return NoSymbol; } - if (val >= 0x01000000) + if (val < 0x20 || (val > 0x7e && val < 0xa0)) return NoSymbol; + if (val < 0x100) + return val; return val | 0x01000000; } - return (NoSymbol); + + if (strlen(s) > 2 && s[0] == '0' && s[1] == 'x') + { + char *tmp = NULL; + val = strtoul(s, &tmp, 16); + if (val == ULONG_MAX || (tmp && *tmp != '\0')) + return NoSymbol; + else + return val; + } + + /* Stupid inconsistency between the headers and XKeysymDB: the former has + * no separating underscore, while some XF86* syms in the latter did. + * As a last ditch effort, try without. */ + if (strncmp(s, "XF86_", 5) == 0) + { + KeySym ret; + char *tmp = strdup(s); + if (!tmp) + return NoSymbol; + memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1); + ret = XStringToKeysym(tmp); + free(tmp); + return ret; + } + + return NoSymbol; } |