keysym: inline find_sym function
It's easier when everything is in one place. Signed-off-by: Ran Benita <ran@unusedvar.com>master
parent
2d87ab08f3
commit
3b506497bf
100
src/keysym.c
100
src/keysym.c
|
@ -91,59 +91,6 @@ xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
|
||||||
return snprintf(buffer, size, "0x%08x", ks);
|
return snprintf(buffer, size, "0x%08x", ks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the correct keysym if one case-insensitive match is given.
|
|
||||||
*
|
|
||||||
* The name_to_keysym table is sorted by istrcmp(). So the binary search may return
|
|
||||||
* _any_ of all possible case-insensitive duplicates. This function searches the
|
|
||||||
* returned entry @entry, all previous and all next entries that match by
|
|
||||||
* case-insensitive comparison and returns the exact match to @name. If @icase
|
|
||||||
* is true, then this returns the best case-insensitive match instead of a
|
|
||||||
* correct match.
|
|
||||||
* The "best" case-insensitive match is the lower-case keysym which we find with
|
|
||||||
* the help of xkb_keysym_is_lower().
|
|
||||||
* The only keysyms that only differ by letter-case are keysyms that are
|
|
||||||
* available as lower-case and upper-case variant (like KEY_a and KEY_A). So
|
|
||||||
* returning the first lower-case match is enough in this case.
|
|
||||||
*/
|
|
||||||
static const struct name_keysym *
|
|
||||||
find_sym(const struct name_keysym *entry, const char *name, bool icase)
|
|
||||||
{
|
|
||||||
const struct name_keysym *iter, *last;
|
|
||||||
size_t len = ARRAY_SIZE(name_to_keysym);
|
|
||||||
|
|
||||||
if (!entry)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!icase && strcmp(get_name(entry), name) == 0)
|
|
||||||
return entry;
|
|
||||||
if (icase && xkb_keysym_is_lower(entry->keysym))
|
|
||||||
return entry;
|
|
||||||
|
|
||||||
for (iter = entry - 1; iter >= name_to_keysym; --iter) {
|
|
||||||
if (!icase && strcmp(get_name(iter), name) == 0)
|
|
||||||
return iter;
|
|
||||||
if (istrcmp(get_name(iter), get_name(entry)) != 0)
|
|
||||||
break;
|
|
||||||
if (icase && xkb_keysym_is_lower(iter->keysym))
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
last = name_to_keysym + len;
|
|
||||||
for (iter = entry + 1; iter < last; ++iter) {
|
|
||||||
if (!icase && strcmp(get_name(iter), name) == 0)
|
|
||||||
return iter;
|
|
||||||
if (istrcmp(get_name(iter), get_name(entry)) != 0)
|
|
||||||
break;
|
|
||||||
if (icase && xkb_keysym_is_lower(iter->keysym))
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (icase)
|
|
||||||
return entry;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
XKB_EXPORT xkb_keysym_t
|
XKB_EXPORT xkb_keysym_t
|
||||||
xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags)
|
xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags)
|
||||||
{
|
{
|
||||||
|
@ -168,9 +115,52 @@ xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entry = find_sym(entry, name, icase);
|
if (entry) {
|
||||||
if (entry)
|
/*
|
||||||
|
* Find the correct keysym if one case-insensitive match is given.
|
||||||
|
*
|
||||||
|
* The name_to_keysym table is sorted by istrcmp(). So the binary search
|
||||||
|
* may return _any_ of all possible case-insensitive duplicates. This
|
||||||
|
* code searches the entry, all previous and all next entries that match
|
||||||
|
* by case-insensitive comparison and returns the exact match to name.
|
||||||
|
* If icase is true, then this returns the best case-insensitive match
|
||||||
|
* instead of a correct match.
|
||||||
|
* The "best" case-insensitive match is the lower-case keysym which we
|
||||||
|
* find with the help of xkb_keysym_is_lower().
|
||||||
|
* The only keysyms that only differ by letter-case are keysyms that are
|
||||||
|
* available as lower-case and upper-case variant (like KEY_a and
|
||||||
|
* KEY_A). So returning the first lower-case match is enough in this
|
||||||
|
* case.
|
||||||
|
*/
|
||||||
|
const struct name_keysym *iter, *last;
|
||||||
|
|
||||||
|
if (!icase && strcmp(get_name(entry), name) == 0)
|
||||||
return entry->keysym;
|
return entry->keysym;
|
||||||
|
if (icase && xkb_keysym_is_lower(entry->keysym))
|
||||||
|
return entry->keysym;
|
||||||
|
|
||||||
|
for (iter = entry - 1; iter >= name_to_keysym; --iter) {
|
||||||
|
if (!icase && strcmp(get_name(iter), name) == 0)
|
||||||
|
return iter->keysym;
|
||||||
|
if (istrcmp(get_name(iter), get_name(entry)) != 0)
|
||||||
|
break;
|
||||||
|
if (icase && xkb_keysym_is_lower(iter->keysym))
|
||||||
|
return iter->keysym;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = name_to_keysym + ARRAY_SIZE(name_to_keysym);
|
||||||
|
for (iter = entry + 1; iter < last; ++iter) {
|
||||||
|
if (!icase && strcmp(get_name(iter), name) == 0)
|
||||||
|
return iter->keysym;
|
||||||
|
if (istrcmp(get_name(iter), get_name(entry)) != 0)
|
||||||
|
break;
|
||||||
|
if (icase && xkb_keysym_is_lower(iter->keysym))
|
||||||
|
return iter->keysym;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (icase)
|
||||||
|
return entry->keysym;
|
||||||
|
}
|
||||||
|
|
||||||
if (*name == 'U' || (icase && *name == 'u')) {
|
if (*name == 'U' || (icase && *name == 'u')) {
|
||||||
val = strtoul(&name[1], &tmp, 16);
|
val = strtoul(&name[1], &tmp, 16);
|
||||||
|
|
Loading…
Reference in New Issue