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
102
src/keysym.c
102
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_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;
|
||||
}
|
||||
}
|
||||
entry = find_sym(entry, name, icase);
|
||||
if (entry)
|
||||
return entry->keysym;
|
||||
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;
|
||||
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')) {
|
||||
val = strtoul(&name[1], &tmp, 16);
|
||||
|
|
Loading…
Reference in New Issue