From e731b2514b96fcf92513c3f680a84666c0de3173 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Thu, 1 Aug 2013 20:24:27 +0300 Subject: [PATCH libxkbcommon 2/3] xkbcomp: handle empty keymaps We should handle empty xkb_keycode and xkb_symbol sections, since xkbcomp handles them, and apparently XQuartz uses it. There are also files for it in xkeyboard-config (rules=base model=empty layout=empty, which translate to keycodes/empty and symbols/empty). https://bugs.freedesktop.org/show_bug.cgi?id=67654 Reported-By: Gatis Paeglis Signed-off-by: Ran Benita --- src/xkbcomp/keycodes.c | 28 +++++++++++++++++++++------- src/xkbcomp/symbols.c | 3 --- test/data/keycodes/empty | 4 ++++ test/data/symbols/empty | 4 ++++ test/data/sync.sh | 3 +++ test/rulescomp.c | 4 ++++ 6 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 test/data/keycodes/empty create mode 100644 test/data/symbols/empty diff --git a/src/xkbcomp/keycodes.c b/src/xkbcomp/keycodes.c index 44e11bc..59916b7 100644 --- a/src/xkbcomp/keycodes.c +++ b/src/xkbcomp/keycodes.c @@ -231,7 +231,10 @@ InitKeyNamesInfo(KeyNamesInfo *info, struct xkb_context *ctx) { memset(info, 0, sizeof(*info)); info->ctx = ctx; - info->min_key_code = XKB_KEYCODE_MAX; + info->min_key_code = XKB_KEYCODE_INVALID; +#if XKB_KEYCODE_INVALID < XKB_KEYCODE_MAX +#error "Hey, you can't be changing stuff like that." +#endif } static xkb_keycode_t @@ -606,15 +609,26 @@ CopyKeyNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info) keymap->keycodes_section_name = strdup_safe(info->name); XkbEscapeMapName(keymap->keycodes_section_name); - keymap->min_key_code = info->min_key_code; - keymap->max_key_code = info->max_key_code; + if (info->min_key_code != XKB_KEYCODE_INVALID) { + keymap->min_key_code = info->min_key_code; + keymap->max_key_code = info->max_key_code; + } + else { + /* + * If the keymap has no keys, let's just use the safest pair + * we know. + */ + keymap->min_key_code = 8; + keymap->max_key_code = 255; + } - /* Copy key names. */ - keymap->keys = calloc(info->max_key_code + 1, sizeof(*keymap->keys)); - for (kc = info->min_key_code; kc <= info->max_key_code; kc++) { + keymap->keys = calloc(keymap->max_key_code + 1, sizeof(*keymap->keys)); + for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) keymap->keys[kc].keycode = kc; + + /* Copy key names. */ + for (kc = info->min_key_code; kc <= info->max_key_code; kc++) keymap->keys[kc].name = darray_item(info->key_names, kc); - } /* * Do some sanity checking on the aliases. We can't do it before diff --git a/src/xkbcomp/symbols.c b/src/xkbcomp/symbols.c index 5cf68d9..6033264 100644 --- a/src/xkbcomp/symbols.c +++ b/src/xkbcomp/symbols.c @@ -1619,9 +1619,6 @@ CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, HandleSymbolsFile(&info, file, merge); - if (darray_empty(info.keys)) - goto err_info; - if (info.errorCount != 0) goto err_info; diff --git a/test/data/keycodes/empty b/test/data/keycodes/empty new file mode 100644 index 0000000..eedc943 --- /dev/null +++ b/test/data/keycodes/empty @@ -0,0 +1,4 @@ +default xkb_keycodes "empty" { + minimum= 8; + maximum= 255; +}; diff --git a/test/data/symbols/empty b/test/data/symbols/empty new file mode 100644 index 0000000..cae3303 --- /dev/null +++ b/test/data/symbols/empty @@ -0,0 +1,4 @@ +default partial alphanumeric_keys modifier_keys +xkb_symbols "basic" { + name[Group1]= "Empty"; +}; diff --git a/test/data/sync.sh b/test/data/sync.sh index 7f2538a..12ed434 100755 --- a/test/data/sync.sh +++ b/test/data/sync.sh @@ -32,9 +32,12 @@ for file in \ symbols/rupeesign \ symbols/kpdl \ symbols/de \ + symbols/ch \ + symbols/empty \ keycodes/xfree86 \ keycodes/aliases \ keycodes/evdev \ + keycodes/empty \ types/complete \ types/pc \ types/basic \ diff --git a/test/rulescomp.c b/test/rulescomp.c index 97b4315..60e7a4c 100644 --- a/test/rulescomp.c +++ b/test/rulescomp.c @@ -231,6 +231,10 @@ main(int argc, char *argv[]) assert(!test_rmlvo_env(ctx, "broken", "what-on-earth", "invalid", "", "", KEY_A, BOTH, XKB_KEY_a, FINISH)); + /* Ensure a keymap with an empty xkb_keycodes compiles fine. */ + assert(test_rmlvo_env(ctx, "base", "empty", "empty", "", "", + KEY_A, BOTH, XKB_KEY_NoSymbol, FINISH)); + xkb_context_unref(ctx); ctx = test_get_context(0); -- 1.8.3.4