summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/xkbcommon/src/x11/x11-keymap.c
diff options
context:
space:
mode:
authorGatis Paeglis <gatis.paeglis@qt.io>2018-11-16 17:07:33 +0100
committerGatis Paeglis <gatis.paeglis@qt.io>2018-11-30 09:47:03 +0000
commitc3a963da1f9e7b1d37e63eedded61da4fbdaaf9a (patch)
treeabe3ac72e69cd6e85ec3a4cfb587405151076493 /src/3rdparty/xkbcommon/src/x11/x11-keymap.c
parent1f1dc3fc4c2e5e2d94e86dfc7235a4b762da2e72 (diff)
src/3rdparty: remove xkbcommon
The only reason why we bundled this library ~6 years ago was because it was not available on distributions that we supported at the time, but library was a hard dependency for XCB plugin. See: 2122e731abdb619249df89642c0800640b2fa428 Later more and more projects started to depend on it (compose input context plugin, libinput, mir, wayland). The configuration had become too complex, because some projects used bundled and some used the version from the system. Having libxkbcommon in 3rdparty sources is not necessary anymore, after RHEL 6.6 was removed from the list of supported platforms for Qt 5.12. Ubuntu 16.04 - 0.5.0 Ubuntu 18.04 - 0.8.0 openSUSE 42.3 - 0.6.1 RHEL-7.4 - 0.7.1 This will also simplify further development, e.g. QTBUG-42181 Bumped the minimal required version 0.4.1 -> 0.5.0. The patch also contains a code marked with "TRANSITION HACK", which is temporary needed so we can update the dependent wayland module. [ChangeLog][Third-Party Code] Removed xkbcommon from bundled sources. This library is present on all supported platforms. The minimal required version now is 0.5.0. Task-number: QTBUG-65503 Change-Id: Iec50829bb6f8fbb19f3c4e4ad62e332beb837de5 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Diffstat (limited to 'src/3rdparty/xkbcommon/src/x11/x11-keymap.c')
-rw-r--r--src/3rdparty/xkbcommon/src/x11/x11-keymap.c1177
1 files changed, 0 insertions, 1177 deletions
diff --git a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c b/src/3rdparty/xkbcommon/src/x11/x11-keymap.c
deleted file mode 100644
index 701b614b2f..0000000000
--- a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- * Copyright © 2013 Ran Benita
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "x11-priv.h"
-
-/*
- * References for the lonesome traveler:
- * Xkb protocol specification:
- * https://www.x.org/releases/current/doc/kbproto/xkbproto.html
- * The XCB xkb XML protocol file:
- * /user/share/xcb/xkb.xml
- * The XCB xkb header file:
- * /usr/include/xcb/xkb.h
- * The old kbproto header files:
- * /usr/include/X11/extensions/XKB{,proto,str}.h
- * Xlib XKB source code:
- * <libX11>/src/xkb/XKBGetMap.c (and friends)
- * X server XKB protocol handling:
- * <xserver>/xkb/xkb.c
- * Man pages:
- * XkbGetMap(3), XkbGetCompatMap(3), etc.
- */
-
-/* Constants from /usr/include/X11/extensions/XKB.h */
-/* XkbNumModifiers. */
-#define NUM_REAL_MODS 8u
-/* XkbNumVirtualMods. */
-#define NUM_VMODS 16u
-/* XkbNoModifier. */
-#define NO_MODIFIER 0xff
-/* XkbNumIndicators. */
-#define NUM_INDICATORS 32u
-/* XkbAllIndicatorsMask. */
-#define ALL_INDICATORS_MASK 0xffffffff
-
-/* Some macros. Not very nice but it'd be worse without them. */
-
-/*
- * We try not to trust the server too much and be paranoid. If we get
- * something which we definitely shouldn't, we fail.
- */
-#define STRINGIFY(expr) #expr
-#define FAIL_UNLESS(expr) do { \
- if (!(expr)) { \
- log_err(keymap->ctx, \
- "x11: failed to get keymap from X server: unmet condition in %s(): %s\n", \
- __func__, STRINGIFY(expr)); \
- goto fail; \
- } \
-} while (0)
-
-#define FAIL_IF_BAD_REPLY(reply, request_name) do { \
- if (!reply) { \
- log_err(keymap->ctx, \
- "x11: failed to get keymap from X server: %s request failed\n", \
- (request_name)); \
- goto fail; \
- } \
-} while (0)
-
-#define ALLOC_OR_FAIL(arr, nmemb) do { \
- if ((nmemb) > 0) { \
- (arr) = calloc((nmemb), sizeof(*(arr))); \
- if (!(arr)) \
- goto fail; \
- } \
-} while (0)
-
-
-static xkb_mod_mask_t
-translate_mods(uint8_t rmods, uint16_t vmods_low, uint16_t vmods_high)
-{
- /* We represent mod masks in a single uint32_t value, with real mods
- * first and vmods after (though we don't make these distinctions). */
- return
- ((xkb_mod_mask_t) rmods) |
- ((xkb_mod_mask_t) vmods_low << 8) |
- ((xkb_mod_mask_t) vmods_high << 16);
-}
-
-static enum xkb_action_controls
-translate_controls_mask(uint32_t wire)
-{
- enum xkb_action_controls ret = 0;
- if (wire & XCB_XKB_BOOL_CTRL_REPEAT_KEYS)
- ret |= CONTROL_REPEAT;
- if (wire & XCB_XKB_BOOL_CTRL_SLOW_KEYS)
- ret |= CONTROL_SLOW;
- if (wire & XCB_XKB_BOOL_CTRL_BOUNCE_KEYS)
- ret |= CONTROL_DEBOUNCE;
- if (wire & XCB_XKB_BOOL_CTRL_STICKY_KEYS)
- ret |= CONTROL_STICKY;
- if (wire & XCB_XKB_BOOL_CTRL_MOUSE_KEYS)
- ret |= CONTROL_MOUSEKEYS;
- if (wire & XCB_XKB_BOOL_CTRL_MOUSE_KEYS_ACCEL)
- ret |= CONTROL_MOUSEKEYS_ACCEL;
- if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_KEYS)
- ret |= CONTROL_AX;
- if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_TIMEOUT_MASK)
- ret |= CONTROL_AX_TIMEOUT;
- if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_FEEDBACK_MASK)
- ret |= CONTROL_AX_FEEDBACK;
- if (wire & XCB_XKB_BOOL_CTRL_AUDIBLE_BELL_MASK)
- ret |= CONTROL_BELL;
- if (wire & XCB_XKB_BOOL_CTRL_IGNORE_GROUP_LOCK_MASK)
- ret |= CONTROL_IGNORE_GROUP_LOCK;
- /* Some controls are not supported and don't appear here. */
- return ret;
-}
-
-static void
-translate_action(union xkb_action *action, const xcb_xkb_action_t *wire)
-{
- switch (wire->type) {
- case XCB_XKB_SA_TYPE_SET_MODS:
- action->type = ACTION_TYPE_MOD_SET;
-
- action->mods.mods.mods = translate_mods(wire->setmods.realMods,
- wire->setmods.vmodsLow,
- wire->setmods.vmodsHigh);
- action->mods.mods.mask = translate_mods(wire->setmods.mask, 0, 0);
-
- if (wire->setmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
- action->mods.flags |= ACTION_LOCK_CLEAR;
- if (wire->setmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
- action->mods.flags |= ACTION_LATCH_TO_LOCK;
- if (wire->setmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS)
- action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP;
-
- break;
- case XCB_XKB_SA_TYPE_LATCH_MODS:
- action->type = ACTION_TYPE_MOD_LATCH;
-
- action->mods.mods.mods = translate_mods(wire->latchmods.realMods,
- wire->latchmods.vmodsLow,
- wire->latchmods.vmodsHigh);
- action->mods.mods.mask = translate_mods(wire->latchmods.mask, 0, 0);
-
- if (wire->latchmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
- action->mods.flags |= ACTION_LOCK_CLEAR;
- if (wire->latchmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
- action->mods.flags |= ACTION_LATCH_TO_LOCK;
- if (wire->latchmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS)
- action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP;
-
- break;
- case XCB_XKB_SA_TYPE_LOCK_MODS:
- action->type = ACTION_TYPE_MOD_LOCK;
-
- action->mods.mods.mods = translate_mods(wire->lockmods.realMods,
- wire->lockmods.vmodsLow,
- wire->lockmods.vmodsHigh);
- action->mods.mods.mask = translate_mods(wire->lockmods.mask, 0, 0);
-
- if (wire->lockmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_LOCK)
- action->mods.flags |= ACTION_LOCK_NO_LOCK;
- if (wire->lockmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_UNLOCK)
- action->mods.flags |= ACTION_LOCK_NO_UNLOCK;
- if (wire->lockmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS)
- action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP;
-
- break;
- case XCB_XKB_SA_TYPE_SET_GROUP:
- action->type = ACTION_TYPE_GROUP_SET;
-
- action->group.group = wire->setgroup.group;
-
- if (wire->setmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
- action->group.flags |= ACTION_LOCK_CLEAR;
- if (wire->setmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
- action->group.flags |= ACTION_LATCH_TO_LOCK;
- if (wire->setmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE)
- action->group.flags |= ACTION_ABSOLUTE_SWITCH;
-
- break;
- case XCB_XKB_SA_TYPE_LATCH_GROUP:
- action->type = ACTION_TYPE_GROUP_LATCH;
-
- action->group.group = wire->latchgroup.group;
-
- if (wire->latchmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
- action->group.flags |= ACTION_LOCK_CLEAR;
- if (wire->latchmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
- action->group.flags |= ACTION_LATCH_TO_LOCK;
- if (wire->latchmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE)
- action->group.flags |= ACTION_ABSOLUTE_SWITCH;
-
- break;
- case XCB_XKB_SA_TYPE_LOCK_GROUP:
- action->type = ACTION_TYPE_GROUP_LOCK;
-
- action->group.group = wire->lockgroup.group;
-
- if (wire->lockgroup.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE)
- action->group.flags |= ACTION_ABSOLUTE_SWITCH;
-
- break;
- case XCB_XKB_SA_TYPE_MOVE_PTR:
- action->type = ACTION_TYPE_PTR_MOVE;
-
- action->ptr.x = (int16_t) (wire->moveptr.xLow | ((uint16_t) wire->moveptr.xHigh << 8));
- action->ptr.y = (int16_t) (wire->moveptr.yLow | ((uint16_t) wire->moveptr.yHigh << 8));
-
- if (!(wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION))
- action->ptr.flags |= ACTION_ACCEL;
- if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_X)
- action->ptr.flags |= ACTION_ABSOLUTE_X;
- if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_Y)
- action->ptr.flags |= ACTION_ABSOLUTE_Y;
-
- break;
- case XCB_XKB_SA_TYPE_PTR_BTN:
- action->type = ACTION_TYPE_PTR_BUTTON;
-
- action->btn.count = wire->ptrbtn.count;
- action->btn.button = wire->ptrbtn.button;
- action->btn.flags = 0;
-
- break;
- case XCB_XKB_SA_TYPE_LOCK_PTR_BTN:
- action->type = ACTION_TYPE_PTR_LOCK;
-
- action->btn.button = wire->lockptrbtn.button;
-
- if (wire->lockptrbtn.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_LOCK)
- action->btn.flags |= ACTION_LOCK_NO_LOCK;
- if (wire->lockptrbtn.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_UNLOCK)
- action->btn.flags |= ACTION_LOCK_NO_UNLOCK;
-
- break;
- case XCB_XKB_SA_TYPE_SET_PTR_DFLT:
- action->type = ACTION_TYPE_PTR_DEFAULT;
-
- action->dflt.value = wire->setptrdflt.value;
-
- if (wire->setptrdflt.flags & XCB_XKB_SA_SET_PTR_DFLT_FLAG_DFLT_BTN_ABSOLUTE)
- action->dflt.flags |= ACTION_ABSOLUTE_SWITCH;
-
- break;
- case XCB_XKB_SA_TYPE_TERMINATE:
- action->type = ACTION_TYPE_TERMINATE;
-
- break;
- case XCB_XKB_SA_TYPE_SWITCH_SCREEN:
- action->type = ACTION_TYPE_SWITCH_VT;
-
- action->screen.screen = wire->switchscreen.newScreen;
-
- if (!(wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION))
- action->screen.flags |= ACTION_SAME_SCREEN;
- if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_ABSOLUTE)
- action->screen.flags |= ACTION_ABSOLUTE_SWITCH;
-
- break;
- case XCB_XKB_SA_TYPE_SET_CONTROLS:
- action->type = ACTION_TYPE_CTRL_SET;
- {
- const uint16_t mask = (wire->setcontrols.boolCtrlsLow |
- (wire->setcontrols.boolCtrlsHigh << 8));
- action->ctrls.ctrls = translate_controls_mask(mask);
- }
- break;
- case XCB_XKB_SA_TYPE_LOCK_CONTROLS:
- action->type = ACTION_TYPE_CTRL_LOCK;
- {
- const uint16_t mask = (wire->lockcontrols.boolCtrlsLow |
- (wire->lockcontrols.boolCtrlsHigh << 8));
- action->ctrls.ctrls = translate_controls_mask(mask);
- }
- break;
-
- case XCB_XKB_SA_TYPE_NO_ACTION:
- /* We don't support these. */
- case XCB_XKB_SA_TYPE_ISO_LOCK:
- case XCB_XKB_SA_TYPE_REDIRECT_KEY:
- case XCB_XKB_SA_TYPE_ACTION_MESSAGE:
- case XCB_XKB_SA_TYPE_DEVICE_BTN:
- case XCB_XKB_SA_TYPE_LOCK_DEVICE_BTN:
- case XCB_XKB_SA_TYPE_DEVICE_VALUATOR:
- action->type = ACTION_TYPE_NONE;
- break;
-
- default:
- if (wire->type < ACTION_TYPE_PRIVATE) {
- action->type = ACTION_TYPE_NONE;
- break;
- }
-
- /* Treat high unknown actions as Private actions. */
- action->priv.type = wire->noaction.type;
- STATIC_ASSERT(sizeof(action->priv.data) == 7 &&
- sizeof(wire->noaction.pad0) == 7,
- "The private action data must be 7 bytes long!");
- memcpy(action->priv.data, wire->noaction.pad0, 7);
- break;
- }
-}
-
-static bool
-get_types(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
-{
- int types_length = xcb_xkb_get_map_map_types_rtrn_length(reply, map);
- xcb_xkb_key_type_iterator_t types_iter =
- xcb_xkb_get_map_map_types_rtrn_iterator(reply, map);
-
- FAIL_UNLESS(reply->firstType == 0);
-
- keymap->num_types = reply->nTypes;
- ALLOC_OR_FAIL(keymap->types, keymap->num_types);
-
- for (int i = 0; i < types_length; i++) {
- xcb_xkb_key_type_t *wire_type = types_iter.data;
- struct xkb_key_type *type = &keymap->types[i];
-
- FAIL_UNLESS(wire_type->numLevels > 0);
-
- type->mods.mods = translate_mods(wire_type->mods_mods,
- wire_type->mods_vmods, 0);
- type->mods.mask = translate_mods(wire_type->mods_mask, 0, 0);
- type->num_levels = wire_type->numLevels;
-
- {
- int entries_length = xcb_xkb_key_type_map_length(wire_type);
- xcb_xkb_kt_map_entry_iterator_t entries_iter =
- xcb_xkb_key_type_map_iterator(wire_type);
-
- type->num_entries = wire_type->nMapEntries;
- ALLOC_OR_FAIL(type->entries, type->num_entries);
-
- for (int j = 0; j < entries_length; j++) {
- xcb_xkb_kt_map_entry_t *wire_entry = entries_iter.data;
- struct xkb_key_type_entry *entry = &type->entries[j];
-
- FAIL_UNLESS(wire_entry->level < type->num_levels);
-
- entry->level = wire_entry->level;
- entry->mods.mods = translate_mods(wire_entry->mods_mods,
- wire_entry->mods_vmods, 0);
- entry->mods.mask = translate_mods(wire_entry->mods_mask, 0, 0);
-
- xcb_xkb_kt_map_entry_next(&entries_iter);
- }
- }
-
- {
- int preserves_length = xcb_xkb_key_type_preserve_length(wire_type);
- xcb_xkb_mod_def_iterator_t preserves_iter =
- xcb_xkb_key_type_preserve_iterator(wire_type);
-
- FAIL_UNLESS((unsigned) preserves_length <= type->num_entries);
-
- for (int j = 0; j < preserves_length; j++) {
- xcb_xkb_mod_def_t *wire_preserve = preserves_iter.data;
- struct xkb_key_type_entry *entry = &type->entries[j];
-
- entry->preserve.mods = translate_mods(wire_preserve->realMods,
- wire_preserve->vmods, 0);
- entry->preserve.mask = translate_mods(wire_preserve->mask, 0, 0);
-
- xcb_xkb_mod_def_next(&preserves_iter);
- }
- }
-
- xcb_xkb_key_type_next(&types_iter);
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
-{
- int sym_maps_length = xcb_xkb_get_map_map_syms_rtrn_length(reply, map);
- xcb_xkb_key_sym_map_iterator_t sym_maps_iter =
- xcb_xkb_get_map_map_syms_rtrn_iterator(reply, map);
-
- FAIL_UNLESS(reply->minKeyCode <= reply->maxKeyCode);
- FAIL_UNLESS(reply->firstKeySym >= reply->minKeyCode);
- FAIL_UNLESS(reply->firstKeySym + reply->nKeySyms <= reply->maxKeyCode + 1);
-
- keymap->min_key_code = reply->minKeyCode;
- keymap->max_key_code = reply->maxKeyCode;
-
- ALLOC_OR_FAIL(keymap->keys, keymap->max_key_code + 1);
-
- for (xkb_keycode_t kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++)
- keymap->keys[kc].keycode = kc;
-
- for (int i = 0; i < sym_maps_length; i++) {
- xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data;
- struct xkb_key *key = &keymap->keys[reply->firstKeySym + i];
-
- key->num_groups = wire_sym_map->groupInfo & 0x0f;
- FAIL_UNLESS(key->num_groups <= ARRAY_SIZE(wire_sym_map->kt_index));
- ALLOC_OR_FAIL(key->groups, key->num_groups);
-
- for (unsigned j = 0; j < key->num_groups; j++) {
- FAIL_UNLESS(wire_sym_map->kt_index[j] < keymap->num_types);
- key->groups[j].type = &keymap->types[wire_sym_map->kt_index[j]];
-
- ALLOC_OR_FAIL(key->groups[j].levels, key->groups[j].type->num_levels);
- }
-
- key->out_of_range_group_number = (wire_sym_map->groupInfo & 0x30) >> 4;
-
- FAIL_UNLESS(key->out_of_range_group_number <= key->num_groups);
-
- if (wire_sym_map->groupInfo & XCB_XKB_GROUPS_WRAP_CLAMP_INTO_RANGE)
- key->out_of_range_group_action = RANGE_SATURATE;
- else if (wire_sym_map->groupInfo & XCB_XKB_GROUPS_WRAP_REDIRECT_INTO_RANGE)
- key->out_of_range_group_action = RANGE_REDIRECT;
- else
- key->out_of_range_group_action = RANGE_WRAP;
-
- {
- int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map);
- xcb_keysym_t *syms_iter = xcb_xkb_key_sym_map_syms(wire_sym_map);
-
- FAIL_UNLESS((unsigned) syms_length == wire_sym_map->width * key->num_groups);
-
- for (int j = 0; j < syms_length; j++) {
- xcb_keysym_t wire_keysym = *syms_iter;
- const xkb_layout_index_t group = j / wire_sym_map->width;
- const xkb_level_index_t level = j % wire_sym_map->width;
-
- assert(key->groups[group].type != NULL);
- if (level < key->groups[group].type->num_levels &&
- wire_keysym != XKB_KEY_NoSymbol) {
- key->groups[group].levels[level].num_syms = 1;
- key->groups[group].levels[level].u.sym = wire_keysym;
- }
-
- syms_iter++;
- }
- }
-
- xcb_xkb_key_sym_map_next(&sym_maps_iter);
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_actions(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
-{
- int acts_count_length =
- xcb_xkb_get_map_map_acts_rtrn_count_length(reply, map);
- uint8_t *acts_count_iter = xcb_xkb_get_map_map_acts_rtrn_count(map);
- xcb_xkb_action_iterator_t acts_iter =
- xcb_xkb_get_map_map_acts_rtrn_acts_iterator(reply, map);
- xcb_xkb_key_sym_map_iterator_t sym_maps_iter =
- xcb_xkb_get_map_map_syms_rtrn_iterator(reply, map);
-
- FAIL_UNLESS(reply->firstKeyAction == keymap->min_key_code);
- FAIL_UNLESS(reply->firstKeyAction + reply->nKeyActions ==
- keymap->max_key_code + 1);
-
- for (int i = 0; i < acts_count_length; i++) {
- xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data;
- int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map);
- uint8_t wire_count = *acts_count_iter;
- struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i];
-
- FAIL_UNLESS(wire_count == 0 || wire_count == syms_length);
-
- for (int j = 0; j < wire_count; j++) {
- xcb_xkb_action_t *wire_action = acts_iter.data;
- const xkb_layout_index_t group = j / wire_sym_map->width;
- const xkb_level_index_t level = j % wire_sym_map->width;
-
- if (level < key->groups[group].type->num_levels) {
- union xkb_action *action =
- &key->groups[group].levels[level].action;
-
- translate_action(action, wire_action);
- }
-
- xcb_xkb_action_next(&acts_iter);
- }
-
- acts_count_iter++;
- xcb_xkb_key_sym_map_next(&sym_maps_iter);
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_vmods(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
-{
- uint8_t *iter = xcb_xkb_get_map_map_vmods_rtrn(map);
-
- keymap->mods.num_mods =
- NUM_REAL_MODS + MIN(msb_pos(reply->virtualMods), NUM_VMODS);
-
- for (unsigned i = 0; i < NUM_VMODS; i++) {
- if (reply->virtualMods & (1u << i)) {
- uint8_t wire = *iter;
- struct xkb_mod *mod = &keymap->mods.mods[NUM_REAL_MODS + i];
-
- mod->type = MOD_VIRT;
- mod->mapping = translate_mods(wire, 0, 0);
-
- iter++;
- }
- }
-
- return true;
-}
-
-static bool
-get_explicits(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
-{
- int length = xcb_xkb_get_map_map_explicit_rtrn_length(reply, map);
- xcb_xkb_set_explicit_iterator_t iter =
- xcb_xkb_get_map_map_explicit_rtrn_iterator(reply, map);
-
- for (int i = 0; i < length; i++) {
- xcb_xkb_set_explicit_t *wire = iter.data;
- struct xkb_key *key;
-
- FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
- wire->keycode <= keymap->max_key_code);
-
- key = &keymap->keys[wire->keycode];
-
- if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_1) &&
- key->num_groups > 0)
- key->groups[0].explicit_type = true;
- if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_2) &&
- key->num_groups > 1)
- key->groups[1].explicit_type = true;
- if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_3) &&
- key->num_groups > 2)
- key->groups[2].explicit_type = true;
- if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_4) &&
- key->num_groups > 3)
- key->groups[3].explicit_type = true;
- if (wire->explicit & XCB_XKB_EXPLICIT_INTERPRET)
- key->explicit |= EXPLICIT_INTERP;
- if (wire->explicit & XCB_XKB_EXPLICIT_AUTO_REPEAT)
- key->explicit |= EXPLICIT_REPEAT;
- if (wire->explicit & XCB_XKB_EXPLICIT_V_MOD_MAP)
- key->explicit |= EXPLICIT_VMODMAP;
-
- xcb_xkb_set_explicit_next(&iter);
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_modmaps(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
-{
- int length = xcb_xkb_get_map_map_modmap_rtrn_length(reply, map);
- xcb_xkb_key_mod_map_iterator_t iter =
- xcb_xkb_get_map_map_modmap_rtrn_iterator(reply, map);
-
- for (int i = 0; i < length; i++) {
- xcb_xkb_key_mod_map_t *wire = iter.data;
- struct xkb_key *key;
-
- FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
- wire->keycode <= keymap->max_key_code);
-
- key = &keymap->keys[wire->keycode];
- key->modmap = wire->mods;
-
- xcb_xkb_key_mod_map_next(&iter);
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_vmodmaps(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
-{
- int length = xcb_xkb_get_map_map_vmodmap_rtrn_length(reply, map);
- xcb_xkb_key_v_mod_map_iterator_t iter =
- xcb_xkb_get_map_map_vmodmap_rtrn_iterator(reply, map);
-
- for (int i = 0; i < length; i++) {
- xcb_xkb_key_v_mod_map_t *wire = iter.data;
- struct xkb_key *key;
-
- FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
- wire->keycode <= keymap->max_key_code);
-
- key = &keymap->keys[wire->keycode];
- key->vmodmap = translate_mods(0, wire->vmods, 0);
-
- xcb_xkb_key_v_mod_map_next(&iter);
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_map(struct xkb_keymap *keymap, xcb_connection_t *conn, uint16_t device_id)
-{
- static const xcb_xkb_map_part_t required_components =
- (XCB_XKB_MAP_PART_KEY_TYPES |
- XCB_XKB_MAP_PART_KEY_SYMS |
- XCB_XKB_MAP_PART_MODIFIER_MAP |
- XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
- XCB_XKB_MAP_PART_KEY_ACTIONS |
- XCB_XKB_MAP_PART_VIRTUAL_MODS |
- XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);
-
- xcb_xkb_get_map_cookie_t cookie =
- xcb_xkb_get_map(conn, device_id, required_components,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- xcb_xkb_get_map_reply_t *reply = xcb_xkb_get_map_reply(conn, cookie, NULL);
- xcb_xkb_get_map_map_t map;
-
- FAIL_IF_BAD_REPLY(reply, "XkbGetMap");
-
- if ((reply->present & required_components) != required_components)
- goto fail;
-
- xcb_xkb_get_map_map_unpack(xcb_xkb_get_map_map(reply),
- reply->nTypes,
- reply->nKeySyms,
- reply->nKeyActions,
- reply->totalActions,
- reply->totalKeyBehaviors,
- reply->virtualMods,
- reply->totalKeyExplicit,
- reply->totalModMapKeys,
- reply->totalVModMapKeys,
- reply->present,
- &map);
-
- if (!get_types(keymap, conn, reply, &map) ||
- !get_sym_maps(keymap, conn, reply, &map) ||
- !get_actions(keymap, conn, reply, &map) ||
- !get_vmods(keymap, conn, reply, &map) ||
- !get_explicits(keymap, conn, reply, &map) ||
- !get_modmaps(keymap, conn, reply, &map) ||
- !get_vmodmaps(keymap, conn, reply, &map))
- goto fail;
-
- free(reply);
- return true;
-
-fail:
- free(reply);
- return false;
-}
-
-static bool
-get_indicators(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_indicator_map_reply_t *reply)
-{
- xcb_xkb_indicator_map_iterator_t iter =
- xcb_xkb_get_indicator_map_maps_iterator(reply);
-
- keymap->num_leds = msb_pos(reply->which);
-
- for (unsigned i = 0; i < NUM_INDICATORS; i++) {
- if (reply->which & (1u << i)) {
- xcb_xkb_indicator_map_t *wire = iter.data;
- struct xkb_led *led = &keymap->leds[i];
-
- if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_BASE)
- led->which_groups |= XKB_STATE_LAYOUT_DEPRESSED;
- if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_LATCHED)
- led->which_groups |= XKB_STATE_LAYOUT_LATCHED;
- if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_LOCKED)
- led->which_groups |= XKB_STATE_LAYOUT_LOCKED;
- if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_EFFECTIVE)
- led->which_groups |= XKB_STATE_LAYOUT_EFFECTIVE;
- if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_COMPAT)
- led->which_groups |= XKB_STATE_LAYOUT_EFFECTIVE;
-
- led->groups = wire->groups;
-
- if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_BASE)
- led->which_mods |= XKB_STATE_MODS_DEPRESSED;
- if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_LATCHED)
- led->which_mods |= XKB_STATE_MODS_LATCHED;
- if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_LOCKED)
- led->which_mods |= XKB_STATE_MODS_LOCKED;
- if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_EFFECTIVE)
- led->which_mods |= XKB_STATE_MODS_EFFECTIVE;
- if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_COMPAT)
- led->which_mods |= XKB_STATE_MODS_EFFECTIVE;
-
- led->mods.mods = translate_mods(wire->realMods, wire->vmods, 0);
- led->mods.mask = translate_mods(wire->mods, 0, 0);
-
- led->ctrls = translate_controls_mask(wire->ctrls);
-
- xcb_xkb_indicator_map_next(&iter);
- }
- }
-
- return true;
-}
-
-static bool
-get_indicator_map(struct xkb_keymap *keymap, xcb_connection_t *conn,
- uint16_t device_id)
-{
- xcb_xkb_get_indicator_map_cookie_t cookie =
- xcb_xkb_get_indicator_map(conn, device_id, ALL_INDICATORS_MASK);
- xcb_xkb_get_indicator_map_reply_t *reply =
- xcb_xkb_get_indicator_map_reply(conn, cookie, NULL);
-
- FAIL_IF_BAD_REPLY(reply, "XkbGetIndicatorMap");
-
- if (!get_indicators(keymap, conn, reply))
- goto fail;
-
- free(reply);
- return true;
-
-fail:
- free(reply);
- return false;
-}
-
-static bool
-get_sym_interprets(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_compat_map_reply_t *reply)
-{
- int length = xcb_xkb_get_compat_map_si_rtrn_length(reply);
- xcb_xkb_sym_interpret_iterator_t iter =
- xcb_xkb_get_compat_map_si_rtrn_iterator(reply);
-
- FAIL_UNLESS(reply->firstSIRtrn == 0);
- FAIL_UNLESS(reply->nSIRtrn == reply->nTotalSI);
-
- keymap->num_sym_interprets = reply->nSIRtrn;
- ALLOC_OR_FAIL(keymap->sym_interprets, keymap->num_sym_interprets);
-
- for (int i = 0; i < length; i++) {
- xcb_xkb_sym_interpret_t *wire = iter.data;
- struct xkb_sym_interpret *sym_interpret = &keymap->sym_interprets[i];
-
- sym_interpret->sym = wire->sym;
-
- switch (wire->match & XCB_XKB_SYM_INTERP_MATCH_OP_MASK) {
- case XCB_XKB_SYM_INTERPRET_MATCH_NONE_OF:
- sym_interpret->match = MATCH_NONE;
- break;
- case XCB_XKB_SYM_INTERPRET_MATCH_ANY_OF_OR_NONE:
- sym_interpret->match = MATCH_ANY_OR_NONE;
- break;
- case XCB_XKB_SYM_INTERPRET_MATCH_ANY_OF:
- sym_interpret->match = MATCH_ANY;
- break;
- case XCB_XKB_SYM_INTERPRET_MATCH_ALL_OF:
- sym_interpret->match = MATCH_ALL;
- break;
- case XCB_XKB_SYM_INTERPRET_MATCH_EXACTLY:
- sym_interpret->match = MATCH_EXACTLY;
- break;
- }
-
- sym_interpret->level_one_only =
- (wire->match & XCB_XKB_SYM_INTERP_MATCH_LEVEL_ONE_ONLY);
- sym_interpret->mods = wire->mods;
-
- if (wire->virtualMod == NO_MODIFIER)
- sym_interpret->virtual_mod = XKB_MOD_INVALID;
- else
- sym_interpret->virtual_mod = NUM_REAL_MODS + wire->virtualMod;
-
- sym_interpret->repeat = (wire->flags & 0x01);
- translate_action(&sym_interpret->action,
- (xcb_xkb_action_t *) &wire->action);
-
- xcb_xkb_sym_interpret_next(&iter);
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_compat_map(struct xkb_keymap *keymap, xcb_connection_t *conn,
- uint16_t device_id)
-{
- xcb_xkb_get_compat_map_cookie_t cookie =
- xcb_xkb_get_compat_map(conn, device_id, 0, true, 0, 0);
- xcb_xkb_get_compat_map_reply_t *reply =
- xcb_xkb_get_compat_map_reply(conn, cookie, NULL);
-
- FAIL_IF_BAD_REPLY(reply, "XkbGetCompatMap");
-
- if (!get_sym_interprets(keymap, conn, reply))
- goto fail;
-
- free(reply);
- return true;
-
-fail:
- free(reply);
- return false;
-}
-
-static bool
-get_type_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_names_reply_t *reply,
- xcb_xkb_get_names_value_list_t *list)
-{
- int key_type_names_length =
- xcb_xkb_get_names_value_list_type_names_length(reply, list);
- xcb_atom_t *key_type_names_iter =
- xcb_xkb_get_names_value_list_type_names(list);
- int n_levels_per_type_length =
- xcb_xkb_get_names_value_list_n_levels_per_type_length(reply, list);
- uint8_t *n_levels_per_type_iter =
- xcb_xkb_get_names_value_list_n_levels_per_type(list);
- xcb_atom_t *kt_level_names_iter =
- xcb_xkb_get_names_value_list_kt_level_names(list);
-
- FAIL_UNLESS(reply->nTypes == keymap->num_types);
- FAIL_UNLESS(key_type_names_length == n_levels_per_type_length);
-
- for (int i = 0; i < key_type_names_length; i++) {
- xcb_atom_t wire_type_name = *key_type_names_iter;
- uint8_t wire_num_levels = *n_levels_per_type_iter;
- struct xkb_key_type *type = &keymap->types[i];
-
- /* Levels must have names. */
- FAIL_UNLESS(type->num_levels == wire_num_levels);
-
- ALLOC_OR_FAIL(type->level_names, type->num_levels);
-
- if (!adopt_atom(keymap->ctx, conn, wire_type_name, &type->name))
- goto fail;
-
- if (!adopt_atoms(keymap->ctx, conn,
- kt_level_names_iter, type->level_names,
- wire_num_levels))
- goto fail;
-
- kt_level_names_iter += wire_num_levels;
- key_type_names_iter++;
- n_levels_per_type_iter++;
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_indicator_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_names_reply_t *reply,
- xcb_xkb_get_names_value_list_t *list)
-{
- xcb_atom_t *iter = xcb_xkb_get_names_value_list_indicator_names(list);
-
- FAIL_UNLESS(msb_pos(reply->indicators) <= keymap->num_leds);
-
- for (unsigned i = 0; i < NUM_INDICATORS; i++) {
- if (reply->indicators & (1u << i)) {
- xcb_atom_t wire = *iter;
- struct xkb_led *led = &keymap->leds[i];
-
- if (!adopt_atom(keymap->ctx, conn, wire, &led->name))
- return false;
-
- iter++;
- }
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_names_reply_t *reply,
- xcb_xkb_get_names_value_list_t *list)
-{
- xcb_atom_t *iter = xcb_xkb_get_names_value_list_virtual_mod_names(list);
-
- /*
- * GetMap's reply->virtualMods is always 0xffff. This one really
- * tells us which vmods exist (a vmod must have a name), so we fix
- * up the size here.
- */
- keymap->mods.num_mods =
- NUM_REAL_MODS + MIN(msb_pos(reply->virtualMods), NUM_VMODS);
-
- for (unsigned i = 0; i < NUM_VMODS; i++) {
- if (reply->virtualMods & (1u << i)) {
- xcb_atom_t wire = *iter;
- struct xkb_mod *mod = &keymap->mods.mods[NUM_REAL_MODS + i];
-
- if (!adopt_atom(keymap->ctx, conn, wire, &mod->name))
- return false;
-
- iter++;
- }
- }
-
- return true;
-}
-
-static bool
-get_group_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_names_reply_t *reply,
- xcb_xkb_get_names_value_list_t *list)
-{
- int length = xcb_xkb_get_names_value_list_groups_length(reply, list);
- xcb_atom_t *iter = xcb_xkb_get_names_value_list_groups(list);
-
- keymap->num_group_names = msb_pos(reply->groupNames);
- ALLOC_OR_FAIL(keymap->group_names, keymap->num_group_names);
-
- if (!adopt_atoms(keymap->ctx, conn,
- iter, keymap->group_names, length))
- goto fail;
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_key_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_names_reply_t *reply,
- xcb_xkb_get_names_value_list_t *list)
-{
- int length = xcb_xkb_get_names_value_list_key_names_length(reply, list);
- xcb_xkb_key_name_iterator_t iter =
- xcb_xkb_get_names_value_list_key_names_iterator(reply, list);
-
- FAIL_UNLESS(reply->minKeyCode == keymap->min_key_code);
- FAIL_UNLESS(reply->maxKeyCode == keymap->max_key_code);
- FAIL_UNLESS(reply->firstKey == keymap->min_key_code);
- FAIL_UNLESS(reply->firstKey + reply->nKeys - 1U == keymap->max_key_code);
-
- for (int i = 0; i < length; i++) {
- xcb_xkb_key_name_t *wire = iter.data;
- xkb_atom_t *key_name = &keymap->keys[reply->firstKey + i].name;
-
- if (wire->name[0] == '\0') {
- *key_name = XKB_ATOM_NONE;
- }
- else {
- *key_name = xkb_atom_intern(keymap->ctx, wire->name,
- strnlen(wire->name,
- XCB_XKB_CONST_KEY_NAME_LENGTH));
- if (!*key_name)
- return false;
- }
-
- xcb_xkb_key_name_next(&iter);
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_aliases(struct xkb_keymap *keymap, xcb_connection_t *conn,
- xcb_xkb_get_names_reply_t *reply,
- xcb_xkb_get_names_value_list_t *list)
-{
- int length = xcb_xkb_get_names_value_list_key_aliases_length(reply, list);
- xcb_xkb_key_alias_iterator_t iter =
- xcb_xkb_get_names_value_list_key_aliases_iterator(reply, list);
-
- keymap->num_key_aliases = reply->nKeyAliases;
- ALLOC_OR_FAIL(keymap->key_aliases, keymap->num_key_aliases);
-
- for (int i = 0; i < length; i++) {
- xcb_xkb_key_alias_t *wire = iter.data;
- struct xkb_key_alias *alias = &keymap->key_aliases[i];
-
- alias->real =
- xkb_atom_intern(keymap->ctx, wire->real,
- strnlen(wire->real, XCB_XKB_CONST_KEY_NAME_LENGTH));
- alias->alias =
- xkb_atom_intern(keymap->ctx, wire->alias,
- strnlen(wire->alias, XCB_XKB_CONST_KEY_NAME_LENGTH));
- if (!alias->real || !alias->alias)
- goto fail;
-
- xcb_xkb_key_alias_next(&iter);
- }
-
- return true;
-
-fail:
- return false;
-}
-
-static bool
-get_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
- uint16_t device_id)
-{
- static const xcb_xkb_name_detail_t wanted =
- (XCB_XKB_NAME_DETAIL_KEYCODES |
- XCB_XKB_NAME_DETAIL_SYMBOLS |
- XCB_XKB_NAME_DETAIL_TYPES |
- XCB_XKB_NAME_DETAIL_COMPAT |
- XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
- XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
- XCB_XKB_NAME_DETAIL_INDICATOR_NAMES |
- XCB_XKB_NAME_DETAIL_KEY_NAMES |
- XCB_XKB_NAME_DETAIL_KEY_ALIASES |
- XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES |
- XCB_XKB_NAME_DETAIL_GROUP_NAMES);
- static const xcb_xkb_name_detail_t required =
- (XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
- XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
- XCB_XKB_NAME_DETAIL_KEY_NAMES |
- XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES);
-
- xcb_xkb_get_names_cookie_t cookie =
- xcb_xkb_get_names(conn, device_id, wanted);
- xcb_xkb_get_names_reply_t *reply =
- xcb_xkb_get_names_reply(conn, cookie, NULL);
- xcb_xkb_get_names_value_list_t list;
-
- FAIL_IF_BAD_REPLY(reply, "XkbGetNames");
-
- FAIL_UNLESS((reply->which & required) == required);
-
- xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply),
- reply->nTypes,
- reply->indicators,
- reply->virtualMods,
- reply->groupNames,
- reply->nKeys,
- reply->nKeyAliases,
- reply->nRadioGroups,
- reply->which,
- &list);
-
- if (!get_atom_name(conn, list.keycodesName, &keymap->keycodes_section_name) ||
- !get_atom_name(conn, list.symbolsName, &keymap->symbols_section_name) ||
- !get_atom_name(conn, list.typesName, &keymap->types_section_name) ||
- !get_atom_name(conn, list.compatName, &keymap->compat_section_name) ||
- !get_type_names(keymap, conn, reply, &list) ||
- !get_indicator_names(keymap, conn, reply, &list) ||
- !get_vmod_names(keymap, conn, reply, &list) ||
- !get_group_names(keymap, conn, reply, &list) ||
- !get_key_names(keymap, conn, reply, &list) ||
- !get_aliases(keymap, conn, reply, &list))
- goto fail;
-
- XkbEscapeMapName(keymap->keycodes_section_name);
- XkbEscapeMapName(keymap->symbols_section_name);
- XkbEscapeMapName(keymap->types_section_name);
- XkbEscapeMapName(keymap->compat_section_name);
-
- free(reply);
- return true;
-
-fail:
- free(reply);
- return false;
-}
-
-static bool
-get_controls(struct xkb_keymap *keymap, xcb_connection_t *conn,
- uint16_t device_id)
-{
- xcb_xkb_get_controls_cookie_t cookie =
- xcb_xkb_get_controls(conn, device_id);
- xcb_xkb_get_controls_reply_t *reply =
- xcb_xkb_get_controls_reply(conn, cookie, NULL);
-
- FAIL_IF_BAD_REPLY(reply, "XkbGetControls");
- FAIL_UNLESS(reply->numGroups > 0 && reply->numGroups <= 4);
-
- keymap->enabled_ctrls = translate_controls_mask(reply->enabledControls);
- keymap->num_groups = reply->numGroups;
-
- FAIL_UNLESS(keymap->max_key_code < XCB_XKB_CONST_PER_KEY_BIT_ARRAY_SIZE * 8);
-
- for (xkb_keycode_t i = keymap->min_key_code; i <= keymap->max_key_code; i++)
- keymap->keys[i].repeats = (reply->perKeyRepeat[i / 8] & (1 << (i % 8)));
-
- free(reply);
- return true;
-
-fail:
- free(reply);
- return false;
-}
-
-XKB_EXPORT struct xkb_keymap *
-xkb_x11_keymap_new_from_device(struct xkb_context *ctx,
- xcb_connection_t *conn,
- int32_t device_id,
- enum xkb_keymap_compile_flags flags)
-{
- struct xkb_keymap *keymap;
- const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1;
-
- if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
- log_err_func(ctx, "unrecognized flags: %#x\n", flags);
- return NULL;
- }
-
- if (device_id < 0 || device_id > 127) {
- log_err_func(ctx, "illegal device ID: %d\n", device_id);
- return NULL;
- }
-
- keymap = xkb_keymap_new(ctx, format, flags);
- if (!keymap)
- return NULL;
-
- if (!get_map(keymap, conn, device_id) ||
- !get_indicator_map(keymap, conn, device_id) ||
- !get_compat_map(keymap, conn, device_id) ||
- !get_names(keymap, conn, device_id) ||
- !get_controls(keymap, conn, device_id)) {
- xkb_keymap_unref(keymap);
- return NULL;
- }
-
- return keymap;
-}