keysyms: Fix xkb_keysym_is_modifier
Currently `xkb_keysym_is_modifier` does not detect the following keysyms: - `XKB_KEY_ISO_Level5_Shift` - `XKB_KEY_ISO_Level5_Latch` - `XKB_KEY_ISO_Level5_Lock` Indeed, there is a mistake in the keysym interval that the code checks. The reason seems a confusing order of the keysyms in `xkbcommon-keysyms.h`: the current code has a comment “libX11 only goes up to XKB_KEY_ISO_Level5_Lock”, but in fact the modifiers keysyms are listed in a _semantic_ order in `xkbcommon-keysyms.h`, not in the increasing keysym _value_ order. Fixed by using the same (correct) code as libX11 and added some tests.master
parent
0074baf451
commit
b5a140832b
|
@ -370,8 +370,7 @@ xkb_keysym_is_modifier(xkb_keysym_t keysym)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
(keysym >= XKB_KEY_Shift_L && keysym <= XKB_KEY_Hyper_R) ||
|
(keysym >= XKB_KEY_Shift_L && keysym <= XKB_KEY_Hyper_R) ||
|
||||||
/* libX11 only goes upto XKB_KEY_ISO_Level5_Lock. */
|
(keysym >= XKB_KEY_ISO_Lock && keysym <= XKB_KEY_ISO_Level5_Lock) ||
|
||||||
(keysym >= XKB_KEY_ISO_Lock && keysym <= XKB_KEY_ISO_Last_Group_Lock) ||
|
|
||||||
keysym == XKB_KEY_Mode_switch ||
|
keysym == XKB_KEY_Mode_switch ||
|
||||||
keysym == XKB_KEY_Num_Lock;
|
keysym == XKB_KEY_Num_Lock;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,86 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "keysym.h" /* For unexported is_lower/upper/keypad() */
|
#include "keysym.h" /* For unexported is_lower/upper/keypad() */
|
||||||
|
|
||||||
|
/* Explicit ordered list of modifier keysyms */
|
||||||
|
static const xkb_keysym_t modifier_keysyms[] = {
|
||||||
|
XKB_KEY_ISO_Lock,
|
||||||
|
XKB_KEY_ISO_Level2_Latch,
|
||||||
|
XKB_KEY_ISO_Level3_Shift,
|
||||||
|
XKB_KEY_ISO_Level3_Latch,
|
||||||
|
XKB_KEY_ISO_Level3_Lock,
|
||||||
|
/* XKB_KEY_ISO_Group_Shift == XKB_KEY_Mode_switch */
|
||||||
|
XKB_KEY_ISO_Group_Latch,
|
||||||
|
XKB_KEY_ISO_Group_Lock,
|
||||||
|
XKB_KEY_ISO_Next_Group,
|
||||||
|
XKB_KEY_ISO_Next_Group_Lock,
|
||||||
|
XKB_KEY_ISO_Prev_Group,
|
||||||
|
XKB_KEY_ISO_Prev_Group_Lock,
|
||||||
|
XKB_KEY_ISO_First_Group,
|
||||||
|
XKB_KEY_ISO_First_Group_Lock,
|
||||||
|
XKB_KEY_ISO_Last_Group,
|
||||||
|
XKB_KEY_ISO_Last_Group_Lock,
|
||||||
|
0xfe10, /* Currently unassigned, but xkb_keysym_is_modifier returns true */
|
||||||
|
XKB_KEY_ISO_Level5_Shift,
|
||||||
|
XKB_KEY_ISO_Level5_Latch,
|
||||||
|
XKB_KEY_ISO_Level5_Lock,
|
||||||
|
|
||||||
|
XKB_KEY_Mode_switch,
|
||||||
|
XKB_KEY_Num_Lock,
|
||||||
|
|
||||||
|
XKB_KEY_Shift_L,
|
||||||
|
XKB_KEY_Shift_R,
|
||||||
|
XKB_KEY_Control_L,
|
||||||
|
XKB_KEY_Control_R,
|
||||||
|
XKB_KEY_Caps_Lock,
|
||||||
|
XKB_KEY_Shift_Lock,
|
||||||
|
|
||||||
|
XKB_KEY_Meta_L,
|
||||||
|
XKB_KEY_Meta_R,
|
||||||
|
XKB_KEY_Alt_L,
|
||||||
|
XKB_KEY_Alt_R,
|
||||||
|
XKB_KEY_Super_L,
|
||||||
|
XKB_KEY_Super_R,
|
||||||
|
XKB_KEY_Hyper_L,
|
||||||
|
XKB_KEY_Hyper_R
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MIN_MODIFIER_KEYSYM modifier_keysyms[0]
|
||||||
|
#define MAX_MODIFIER_KEYSYM modifier_keysyms[ARRAY_SIZE(modifier_keysyms) - 1]
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_modifiers_table(void)
|
||||||
|
{
|
||||||
|
xkb_keysym_t ks = XKB_KEY_NoSymbol;
|
||||||
|
|
||||||
|
/* Ensure ordered array */
|
||||||
|
for (size_t k = 0; k < ARRAY_SIZE(modifier_keysyms); k++) {
|
||||||
|
assert_printf(ks < modifier_keysyms[k],
|
||||||
|
"modifier_keysyms[] is not ordered: 0x%04"PRIx32">=0x%04"PRIx32"\n",
|
||||||
|
ks, modifier_keysyms[k]);
|
||||||
|
ks = modifier_keysyms[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unassigned keysym */
|
||||||
|
assert(!xkb_keysym_is_assigned(0xfe10));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
test_modifier(xkb_keysym_t ks)
|
||||||
|
{
|
||||||
|
if (ks < MIN_MODIFIER_KEYSYM || ks > MAX_MODIFIER_KEYSYM)
|
||||||
|
return false;
|
||||||
|
for (size_t k = 0; k < ARRAY_SIZE(modifier_keysyms); k++) {
|
||||||
|
if (ks == modifier_keysyms[k])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
test_string(const char *string, xkb_keysym_t expected)
|
test_string(const char *string, xkb_keysym_t expected)
|
||||||
{
|
{
|
||||||
|
@ -166,6 +242,8 @@ main(void)
|
||||||
assert(xkb_keysym_is_assigned(XKB_KEYSYM_MAX_ASSIGNED));
|
assert(xkb_keysym_is_assigned(XKB_KEYSYM_MAX_ASSIGNED));
|
||||||
assert(!xkb_keysym_is_assigned(XKB_KEYSYM_MAX));
|
assert(!xkb_keysym_is_assigned(XKB_KEYSYM_MAX));
|
||||||
|
|
||||||
|
test_modifiers_table();
|
||||||
|
|
||||||
struct xkb_keysym_iterator *iter = xkb_keysym_iterator_new(false);
|
struct xkb_keysym_iterator *iter = xkb_keysym_iterator_new(false);
|
||||||
xkb_keysym_t ks_prev = XKB_KEYSYM_MIN;
|
xkb_keysym_t ks_prev = XKB_KEYSYM_MIN;
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
|
@ -187,6 +265,12 @@ main(void)
|
||||||
char name[XKB_KEYSYM_NAME_MAX_SIZE];
|
char name[XKB_KEYSYM_NAME_MAX_SIZE];
|
||||||
needed = xkb_keysym_iterator_get_name(iter, name, sizeof(name));
|
needed = xkb_keysym_iterator_get_name(iter, name, sizeof(name));
|
||||||
assert(0 < needed && (size_t)needed <= sizeof(name));
|
assert(0 < needed && (size_t)needed <= sizeof(name));
|
||||||
|
/* Test modifier keysyms */
|
||||||
|
bool expected = test_modifier(ks);
|
||||||
|
bool got = xkb_keysym_is_modifier(ks);
|
||||||
|
assert_printf(got == expected,
|
||||||
|
"xkb_keysym_is_modifier(0x%04"PRIx32"): expected %d, got: %d\n",
|
||||||
|
ks, expected, got);
|
||||||
}
|
}
|
||||||
iter = xkb_keysym_iterator_unref(iter);
|
iter = xkb_keysym_iterator_unref(iter);
|
||||||
assert(ks_prev == XKB_KEYSYM_MAX_ASSIGNED);
|
assert(ks_prev == XKB_KEYSYM_MAX_ASSIGNED);
|
||||||
|
|
Loading…
Reference in New Issue