Home | History | Annotate | Download | only in x11
      1 /*
      2  * Copyright  2013 Ran Benita
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  */
     23 
     24 #include "x11-priv.h"
     25 
     26 /*
     27  * References for the lonesome traveler:
     28  * Xkb protocol specification:
     29  *      http://www.x.org/releases/current/doc/kbproto/xkbproto.html
     30  * The XCB xkb XML protocol file:
     31  *      /user/share/xcb/xkb.xml
     32  * The XCB xkb header file:
     33  *      /usr/include/xcb/xkb.h
     34  * The old kbproto header files:
     35  *      /usr/include/X11/extensions/XKB{,proto,str}.h
     36  * Xlib XKB source code:
     37  *      <libX11>/src/xkb/XKBGetMap.c (and friends)
     38  * X server XKB protocol handling:
     39  *      <xserver>/xkb/xkb.c
     40  * Man pages:
     41  *      XkbGetMap(3), XkbGetCompatMap(3), etc.
     42  */
     43 
     44 /* Constants from /usr/include/X11/extensions/XKB.h */
     45 /* XkbNumModifiers. */
     46 #define NUM_REAL_MODS 8u
     47 /* XkbNumVirtualMods. */
     48 #define NUM_VMODS 16u
     49 /* XkbNoModifier. */
     50 #define NO_MODIFIER 0xff
     51 /* XkbNumIndicators. */
     52 #define NUM_INDICATORS 32u
     53 /* XkbAllIndicatorsMask. */
     54 #define ALL_INDICATORS_MASK 0xffffffff
     55 
     56 /* Some macros. Not very nice but it'd be worse without them. */
     57 
     58 /*
     59  * We try not to trust the server too much and be paranoid. If we get
     60  * something which we definitely shouldn't, we fail.
     61  */
     62 #define STRINGIFY(expr) #expr
     63 #define FAIL_UNLESS(expr) do {                                          \
     64     if (!(expr)) {                                                      \
     65         log_err(keymap->ctx,                                            \
     66                 "x11: failed to get keymap from X server: unmet condition in %s(): %s\n", \
     67                 __func__, STRINGIFY(expr));                             \
     68         goto fail;                                                      \
     69     }                                                                   \
     70 } while (0)
     71 
     72 #define FAIL_IF_BAD_REPLY(reply, request_name) do {                     \
     73     if (!reply) {                                                       \
     74         log_err(keymap->ctx,                                            \
     75                 "x11: failed to get keymap from X server: %s request failed\n", \
     76                 (request_name));                                        \
     77         goto fail;                                                      \
     78     }                                                                   \
     79 } while (0)
     80 
     81 #define ALLOC_OR_FAIL(arr, nmemb) do {                                  \
     82     if ((nmemb) > 0) {                                                  \
     83         (arr) = calloc((nmemb), sizeof(*(arr)));                        \
     84         if (!(arr))                                                     \
     85             goto fail;                                                  \
     86     }                                                                   \
     87 } while (0)
     88 
     89 
     90 static xkb_mod_mask_t
     91 translate_mods(uint8_t rmods, uint16_t vmods_low, uint16_t vmods_high)
     92 {
     93     /* We represent mod masks in a single uint32_t value, with real mods
     94      * first and vmods after (though we don't make these distinctions). */
     95     return
     96         ((xkb_mod_mask_t) rmods) |
     97         ((xkb_mod_mask_t) vmods_low << 8) |
     98         ((xkb_mod_mask_t) vmods_high << 16);
     99 }
    100 
    101 static enum xkb_action_controls
    102 translate_controls_mask(uint32_t wire)
    103 {
    104     enum xkb_action_controls ret = 0;
    105     if (wire & XCB_XKB_BOOL_CTRL_REPEAT_KEYS)
    106         ret |= CONTROL_REPEAT;
    107     if (wire & XCB_XKB_BOOL_CTRL_SLOW_KEYS)
    108         ret |= CONTROL_SLOW;
    109     if (wire & XCB_XKB_BOOL_CTRL_BOUNCE_KEYS)
    110         ret |= CONTROL_DEBOUNCE;
    111     if (wire & XCB_XKB_BOOL_CTRL_STICKY_KEYS)
    112         ret |= CONTROL_STICKY;
    113     if (wire & XCB_XKB_BOOL_CTRL_MOUSE_KEYS)
    114         ret |= CONTROL_MOUSEKEYS;
    115     if (wire & XCB_XKB_BOOL_CTRL_MOUSE_KEYS_ACCEL)
    116         ret |= CONTROL_MOUSEKEYS_ACCEL;
    117     if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_KEYS)
    118         ret |= CONTROL_AX;
    119     if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_TIMEOUT_MASK)
    120         ret |= CONTROL_AX_TIMEOUT;
    121     if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_FEEDBACK_MASK)
    122         ret |= CONTROL_AX_FEEDBACK;
    123     if (wire & XCB_XKB_BOOL_CTRL_AUDIBLE_BELL_MASK)
    124         ret |= CONTROL_BELL;
    125     if (wire & XCB_XKB_BOOL_CTRL_IGNORE_GROUP_LOCK_MASK)
    126         ret |= CONTROL_IGNORE_GROUP_LOCK;
    127     /* Some controls are not supported and don't appear here. */
    128     return ret;
    129 }
    130 
    131 static void
    132 translate_action(union xkb_action *action, const xcb_xkb_action_t *wire)
    133 {
    134     switch (wire->type) {
    135     case XCB_XKB_SA_TYPE_SET_MODS:
    136         action->type = ACTION_TYPE_MOD_SET;
    137 
    138         action->mods.mods.mods = translate_mods(wire->setmods.realMods,
    139                                                 wire->setmods.vmodsLow,
    140                                                 wire->setmods.vmodsHigh);
    141         action->mods.mods.mask = translate_mods(wire->setmods.mask, 0, 0);
    142 
    143         if (wire->setmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
    144             action->mods.flags |= ACTION_LOCK_CLEAR;
    145         if (wire->setmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
    146             action->mods.flags |= ACTION_LATCH_TO_LOCK;
    147         if (wire->setmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS)
    148             action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP;
    149 
    150         break;
    151     case XCB_XKB_SA_TYPE_LATCH_MODS:
    152         action->type = ACTION_TYPE_MOD_LATCH;
    153 
    154         action->mods.mods.mods = translate_mods(wire->latchmods.realMods,
    155                                                 wire->latchmods.vmodsLow,
    156                                                 wire->latchmods.vmodsHigh);
    157         action->mods.mods.mask = translate_mods(wire->latchmods.mask, 0, 0);
    158 
    159         if (wire->latchmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
    160             action->mods.flags |= ACTION_LOCK_CLEAR;
    161         if (wire->latchmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
    162             action->mods.flags |= ACTION_LATCH_TO_LOCK;
    163         if (wire->latchmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS)
    164             action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP;
    165 
    166         break;
    167     case XCB_XKB_SA_TYPE_LOCK_MODS:
    168         action->type = ACTION_TYPE_MOD_LOCK;
    169 
    170         action->mods.mods.mods = translate_mods(wire->lockmods.realMods,
    171                                                 wire->lockmods.vmodsLow,
    172                                                 wire->lockmods.vmodsHigh);
    173         action->mods.mods.mask = translate_mods(wire->lockmods.mask, 0, 0);
    174 
    175         if (wire->lockmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_LOCK)
    176             action->mods.flags |= ACTION_LOCK_NO_LOCK;
    177         if (wire->lockmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_UNLOCK)
    178             action->mods.flags |= ACTION_LOCK_NO_UNLOCK;
    179         if (wire->lockmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS)
    180             action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP;
    181 
    182         break;
    183     case XCB_XKB_SA_TYPE_SET_GROUP:
    184         action->type = ACTION_TYPE_GROUP_SET;
    185 
    186         action->group.group = wire->setgroup.group;
    187 
    188         if (wire->setmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
    189             action->group.flags |= ACTION_LOCK_CLEAR;
    190         if (wire->setmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
    191             action->group.flags |= ACTION_LATCH_TO_LOCK;
    192         if (wire->setmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE)
    193             action->group.flags |= ACTION_ABSOLUTE_SWITCH;
    194 
    195         break;
    196     case XCB_XKB_SA_TYPE_LATCH_GROUP:
    197         action->type = ACTION_TYPE_GROUP_LATCH;
    198 
    199         action->group.group = wire->latchgroup.group;
    200 
    201         if (wire->latchmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
    202             action->group.flags |= ACTION_LOCK_CLEAR;
    203         if (wire->latchmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
    204             action->group.flags |= ACTION_LATCH_TO_LOCK;
    205         if (wire->latchmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE)
    206             action->group.flags |= ACTION_ABSOLUTE_SWITCH;
    207 
    208         break;
    209     case XCB_XKB_SA_TYPE_LOCK_GROUP:
    210         action->type = ACTION_TYPE_GROUP_LOCK;
    211 
    212         action->group.group = wire->lockgroup.group;
    213 
    214         if (wire->lockgroup.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE)
    215             action->group.flags |= ACTION_ABSOLUTE_SWITCH;
    216 
    217         break;
    218     case XCB_XKB_SA_TYPE_MOVE_PTR:
    219         action->type = ACTION_TYPE_PTR_MOVE;
    220 
    221         action->ptr.x = (wire->moveptr.xLow | (wire->moveptr.xHigh << 8));
    222         action->ptr.y = (wire->moveptr.yLow | (wire->moveptr.yHigh << 8));
    223 
    224         if (!(wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION))
    225             action->ptr.flags |= ACTION_ACCEL;
    226         if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_X)
    227             action->ptr.flags |= ACTION_ABSOLUTE_X;
    228         if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_Y)
    229             action->ptr.flags |= ACTION_ABSOLUTE_Y;
    230 
    231         break;
    232     case XCB_XKB_SA_TYPE_PTR_BTN:
    233         action->type = ACTION_TYPE_PTR_BUTTON;
    234 
    235         action->btn.count = wire->ptrbtn.count;
    236         action->btn.button = wire->ptrbtn.button;
    237         action->btn.flags = 0;
    238 
    239         break;
    240     case XCB_XKB_SA_TYPE_LOCK_PTR_BTN:
    241         action->type = ACTION_TYPE_PTR_LOCK;
    242 
    243         action->btn.button = wire->lockptrbtn.button;
    244 
    245         if (wire->lockptrbtn.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_LOCK)
    246             action->btn.flags |= ACTION_LOCK_NO_LOCK;
    247         if (wire->lockptrbtn.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_UNLOCK)
    248             action->btn.flags |= ACTION_LOCK_NO_UNLOCK;
    249 
    250         break;
    251     case XCB_XKB_SA_TYPE_SET_PTR_DFLT:
    252         action->type = ACTION_TYPE_PTR_DEFAULT;
    253 
    254         action->dflt.value = wire->setptrdflt.value;
    255 
    256         if (wire->setptrdflt.flags & XCB_XKB_SA_SET_PTR_DFLT_FLAG_DFLT_BTN_ABSOLUTE)
    257             action->dflt.flags |= ACTION_ABSOLUTE_SWITCH;
    258 
    259         break;
    260     case XCB_XKB_SA_TYPE_TERMINATE:
    261         action->type = ACTION_TYPE_TERMINATE;
    262 
    263         break;
    264     case XCB_XKB_SA_TYPE_SWITCH_SCREEN:
    265         action->type = ACTION_TYPE_SWITCH_VT;
    266 
    267         action->screen.screen = wire->switchscreen.newScreen;
    268 
    269         if (!(wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION))
    270             action->screen.flags |= ACTION_SAME_SCREEN;
    271         if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_ABSOLUTE)
    272             action->screen.flags |= ACTION_ABSOLUTE_SWITCH;
    273 
    274         break;
    275     case XCB_XKB_SA_TYPE_SET_CONTROLS:
    276         action->type = ACTION_TYPE_CTRL_SET;
    277         {
    278             const uint16_t mask = (wire->setcontrols.boolCtrlsLow |
    279                                    (wire->setcontrols.boolCtrlsHigh << 8));
    280             action->ctrls.ctrls = translate_controls_mask(mask);
    281         }
    282         break;
    283     case XCB_XKB_SA_TYPE_LOCK_CONTROLS:
    284         action->type = ACTION_TYPE_CTRL_LOCK;
    285         {
    286             const uint16_t mask = (wire->lockcontrols.boolCtrlsLow |
    287                                    (wire->lockcontrols.boolCtrlsHigh << 8));
    288             action->ctrls.ctrls = translate_controls_mask(mask);
    289         }
    290         break;
    291 
    292     case XCB_XKB_SA_TYPE_NO_ACTION:
    293     /* We don't support these. */
    294     case XCB_XKB_SA_TYPE_ISO_LOCK:
    295     case XCB_XKB_SA_TYPE_REDIRECT_KEY:
    296     case XCB_XKB_SA_TYPE_ACTION_MESSAGE:
    297     case XCB_XKB_SA_TYPE_DEVICE_BTN:
    298     case XCB_XKB_SA_TYPE_LOCK_DEVICE_BTN:
    299     case XCB_XKB_SA_TYPE_DEVICE_VALUATOR:
    300         action->type = ACTION_TYPE_NONE;
    301         break;
    302 
    303     default:
    304         if (wire->type < ACTION_TYPE_PRIVATE) {
    305             action->type = ACTION_TYPE_NONE;
    306             break;
    307         }
    308 
    309         /* Treat high unknown actions as Private actions. */
    310         action->priv.type = wire->noaction.type;
    311         STATIC_ASSERT(sizeof(action->priv.data) == 7 &&
    312                       sizeof(wire->noaction.pad0) == 7,
    313                       "The private action data must be 7 bytes long!");
    314         memcpy(action->priv.data, wire->noaction.pad0, 7);
    315         break;
    316     }
    317 }
    318 
    319 static bool
    320 get_types(struct xkb_keymap *keymap, xcb_connection_t *conn,
    321           xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
    322 {
    323     int types_length = xcb_xkb_get_map_map_types_rtrn_length(reply, map);
    324     xcb_xkb_key_type_iterator_t types_iter =
    325         xcb_xkb_get_map_map_types_rtrn_iterator(reply, map);
    326 
    327     FAIL_UNLESS(reply->firstType == 0);
    328 
    329     keymap->num_types = reply->nTypes;
    330     ALLOC_OR_FAIL(keymap->types, keymap->num_types);
    331 
    332     for (int i = 0; i < types_length; i++) {
    333         xcb_xkb_key_type_t *wire_type = types_iter.data;
    334         struct xkb_key_type *type = &keymap->types[i];
    335 
    336         FAIL_UNLESS(wire_type->numLevels > 0);
    337 
    338         type->mods.mods = translate_mods(wire_type->mods_mods,
    339                                          wire_type->mods_vmods, 0);
    340         type->mods.mask = translate_mods(wire_type->mods_mask, 0, 0);
    341         type->num_levels = wire_type->numLevels;
    342 
    343         {
    344             int entries_length = xcb_xkb_key_type_map_length(wire_type);
    345             xcb_xkb_kt_map_entry_iterator_t entries_iter =
    346                 xcb_xkb_key_type_map_iterator(wire_type);
    347 
    348             type->num_entries = wire_type->nMapEntries;
    349             ALLOC_OR_FAIL(type->entries, type->num_entries);
    350 
    351             for (int j = 0; j < entries_length; j++) {
    352                 xcb_xkb_kt_map_entry_t *wire_entry = entries_iter.data;
    353                 struct xkb_key_type_entry *entry = &type->entries[j];
    354 
    355                 FAIL_UNLESS(wire_entry->level < type->num_levels);
    356 
    357                 entry->level = wire_entry->level;
    358                 entry->mods.mods = translate_mods(wire_entry->mods_mods,
    359                                                   wire_entry->mods_vmods, 0);
    360                 entry->mods.mask = translate_mods(wire_entry->mods_mask, 0, 0);
    361 
    362                 xcb_xkb_kt_map_entry_next(&entries_iter);
    363             }
    364         }
    365 
    366         {
    367             int preserves_length = xcb_xkb_key_type_preserve_length(wire_type);
    368             xcb_xkb_mod_def_iterator_t preserves_iter =
    369                 xcb_xkb_key_type_preserve_iterator(wire_type);
    370 
    371             FAIL_UNLESS((unsigned) preserves_length <= type->num_entries);
    372 
    373             for (int j = 0; j < preserves_length; j++) {
    374                 xcb_xkb_mod_def_t *wire_preserve = preserves_iter.data;
    375                 struct xkb_key_type_entry *entry = &type->entries[j];
    376 
    377                 entry->preserve.mods = translate_mods(wire_preserve->realMods,
    378                                                       wire_preserve->vmods, 0);
    379                 entry->preserve.mask = translate_mods(wire_preserve->mask, 0, 0);
    380 
    381                 xcb_xkb_mod_def_next(&preserves_iter);
    382             }
    383         }
    384 
    385         xcb_xkb_key_type_next(&types_iter);
    386     }
    387 
    388     return true;
    389 
    390 fail:
    391     return false;
    392 }
    393 
    394 static bool
    395 get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn,
    396              xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
    397 {
    398     int sym_maps_length = xcb_xkb_get_map_map_syms_rtrn_length(reply, map);
    399     xcb_xkb_key_sym_map_iterator_t sym_maps_iter =
    400         xcb_xkb_get_map_map_syms_rtrn_iterator(reply, map);
    401 
    402     FAIL_UNLESS(reply->minKeyCode <= reply->maxKeyCode);
    403     FAIL_UNLESS(reply->firstKeySym >= reply->minKeyCode);
    404     FAIL_UNLESS(reply->firstKeySym + reply->nKeySyms <= reply->maxKeyCode + 1);
    405 
    406     keymap->min_key_code = reply->minKeyCode;
    407     keymap->max_key_code = reply->maxKeyCode;
    408 
    409     ALLOC_OR_FAIL(keymap->keys, keymap->max_key_code + 1);
    410 
    411     for (xkb_keycode_t kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++)
    412         keymap->keys[kc].keycode = kc;
    413 
    414     for (int i = 0; i < sym_maps_length; i++) {
    415         xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data;
    416         struct xkb_key *key = &keymap->keys[reply->firstKeySym + i];
    417 
    418         key->num_groups = wire_sym_map->groupInfo & 0x0f;
    419         FAIL_UNLESS(key->num_groups <= ARRAY_SIZE(wire_sym_map->kt_index));
    420         ALLOC_OR_FAIL(key->groups, key->num_groups);
    421 
    422         for (unsigned j = 0; j < key->num_groups; j++) {
    423             FAIL_UNLESS(wire_sym_map->kt_index[j] < keymap->num_types);
    424             key->groups[j].type = &keymap->types[wire_sym_map->kt_index[j]];
    425 
    426             ALLOC_OR_FAIL(key->groups[j].levels, key->groups[j].type->num_levels);
    427         }
    428 
    429         key->out_of_range_group_number = (wire_sym_map->groupInfo & 0x30) >> 4;
    430 
    431         FAIL_UNLESS(key->out_of_range_group_number <= key->num_groups);
    432 
    433         if (wire_sym_map->groupInfo & XCB_XKB_GROUPS_WRAP_CLAMP_INTO_RANGE)
    434             key->out_of_range_group_action = RANGE_SATURATE;
    435         else if (wire_sym_map->groupInfo & XCB_XKB_GROUPS_WRAP_REDIRECT_INTO_RANGE)
    436             key->out_of_range_group_action = RANGE_REDIRECT;
    437         else
    438             key->out_of_range_group_action = RANGE_WRAP;
    439 
    440         {
    441             int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map);
    442             xcb_keysym_t *syms_iter = xcb_xkb_key_sym_map_syms(wire_sym_map);
    443 
    444             FAIL_UNLESS((unsigned) syms_length == wire_sym_map->width * key->num_groups);
    445 
    446             for (int j = 0; j < syms_length; j++) {
    447                 xcb_keysym_t wire_keysym = *syms_iter;
    448                 const xkb_layout_index_t group = j / wire_sym_map->width;
    449                 const xkb_level_index_t level = j % wire_sym_map->width;
    450 
    451                 if (level < key->groups[group].type->num_levels &&
    452                     wire_keysym != XKB_KEY_NoSymbol) {
    453                     key->groups[group].levels[level].num_syms = 1;
    454                     key->groups[group].levels[level].u.sym = wire_keysym;
    455                 }
    456 
    457                 syms_iter++;
    458             }
    459         }
    460 
    461         xcb_xkb_key_sym_map_next(&sym_maps_iter);
    462     }
    463 
    464     return true;
    465 
    466 fail:
    467     return false;
    468 }
    469 
    470 static bool
    471 get_actions(struct xkb_keymap *keymap, xcb_connection_t *conn,
    472             xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
    473 {
    474     int acts_count_length =
    475         xcb_xkb_get_map_map_acts_rtrn_count_length(reply, map);
    476     uint8_t *acts_count_iter = xcb_xkb_get_map_map_acts_rtrn_count(map);
    477     xcb_xkb_action_iterator_t acts_iter =
    478         xcb_xkb_get_map_map_acts_rtrn_acts_iterator(reply, map);
    479     xcb_xkb_key_sym_map_iterator_t sym_maps_iter =
    480         xcb_xkb_get_map_map_syms_rtrn_iterator(reply, map);
    481 
    482     FAIL_UNLESS(reply->firstKeyAction == keymap->min_key_code);
    483     FAIL_UNLESS(reply->firstKeyAction + reply->nKeyActions ==
    484                 keymap->max_key_code + 1);
    485 
    486     for (int i = 0; i < acts_count_length; i++) {
    487         xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data;
    488         int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map);
    489         uint8_t wire_count = *acts_count_iter;
    490         struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i];
    491 
    492         FAIL_UNLESS(wire_count == 0 || wire_count == syms_length);
    493 
    494         for (int j = 0; j < wire_count; j++) {
    495             xcb_xkb_action_t *wire_action = acts_iter.data;
    496             const xkb_layout_index_t group = j / wire_sym_map->width;
    497             const xkb_level_index_t level = j % wire_sym_map->width;
    498 
    499             if (level < key->groups[group].type->num_levels) {
    500                 union xkb_action *action =
    501                     &key->groups[group].levels[level].action;
    502 
    503                 translate_action(action, wire_action);
    504             }
    505 
    506             xcb_xkb_action_next(&acts_iter);
    507         }
    508 
    509         acts_count_iter++;
    510         xcb_xkb_key_sym_map_next(&sym_maps_iter);
    511     }
    512 
    513     return true;
    514 
    515 fail:
    516     return false;
    517 }
    518 
    519 static bool
    520 get_vmods(struct xkb_keymap *keymap, xcb_connection_t *conn,
    521           xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
    522 {
    523     uint8_t *iter = xcb_xkb_get_map_map_vmods_rtrn(map);
    524 
    525     keymap->mods.num_mods =
    526         NUM_REAL_MODS + MIN(msb_pos(reply->virtualMods), NUM_VMODS);
    527 
    528     for (unsigned i = 0; i < NUM_VMODS; i++) {
    529         if (reply->virtualMods & (1u << i)) {
    530             uint8_t wire = *iter;
    531             struct xkb_mod *mod = &keymap->mods.mods[NUM_REAL_MODS + i];
    532 
    533             mod->type = MOD_VIRT;
    534             mod->mapping = translate_mods(wire, 0, 0);
    535 
    536             iter++;
    537         }
    538     }
    539 
    540     return true;
    541 }
    542 
    543 static bool
    544 get_explicits(struct xkb_keymap *keymap, xcb_connection_t *conn,
    545               xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
    546 {
    547     int length = xcb_xkb_get_map_map_explicit_rtrn_length(reply, map);
    548     xcb_xkb_set_explicit_iterator_t iter =
    549         xcb_xkb_get_map_map_explicit_rtrn_iterator(reply, map);
    550 
    551     for (int i = 0; i < length; i++) {
    552         xcb_xkb_set_explicit_t *wire = iter.data;
    553         struct xkb_key *key;
    554 
    555         FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
    556                     wire->keycode <= keymap->max_key_code);
    557 
    558         key = &keymap->keys[wire->keycode];
    559 
    560         if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_1) &&
    561             key->num_groups > 0)
    562             key->groups[0].explicit_type = true;
    563         if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_2) &&
    564             key->num_groups > 1)
    565             key->groups[1].explicit_type = true;
    566         if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_3) &&
    567             key->num_groups > 2)
    568             key->groups[2].explicit_type = true;
    569         if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_4) &&
    570             key->num_groups > 3)
    571             key->groups[3].explicit_type = true;
    572         if (wire->explicit & XCB_XKB_EXPLICIT_INTERPRET)
    573             key->explicit |= EXPLICIT_INTERP;
    574         if (wire->explicit & XCB_XKB_EXPLICIT_AUTO_REPEAT)
    575             key->explicit |= EXPLICIT_REPEAT;
    576         if (wire->explicit & XCB_XKB_EXPLICIT_V_MOD_MAP)
    577             key->explicit |= EXPLICIT_VMODMAP;
    578 
    579         xcb_xkb_set_explicit_next(&iter);
    580     }
    581 
    582     return true;
    583 
    584 fail:
    585     return false;
    586 }
    587 
    588 static bool
    589 get_modmaps(struct xkb_keymap *keymap, xcb_connection_t *conn,
    590             xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
    591 {
    592     int length = xcb_xkb_get_map_map_modmap_rtrn_length(reply, map);
    593     xcb_xkb_key_mod_map_iterator_t iter =
    594         xcb_xkb_get_map_map_modmap_rtrn_iterator(reply, map);
    595 
    596     for (int i = 0; i < length; i++) {
    597         xcb_xkb_key_mod_map_t *wire = iter.data;
    598         struct xkb_key *key;
    599 
    600         FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
    601                     wire->keycode <= keymap->max_key_code);
    602 
    603         key = &keymap->keys[wire->keycode];
    604         key->modmap = wire->mods;
    605 
    606         xcb_xkb_key_mod_map_next(&iter);
    607     }
    608 
    609     return true;
    610 
    611 fail:
    612     return false;
    613 }
    614 
    615 static bool
    616 get_vmodmaps(struct xkb_keymap *keymap, xcb_connection_t *conn,
    617              xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
    618 {
    619     int length = xcb_xkb_get_map_map_vmodmap_rtrn_length(reply, map);
    620     xcb_xkb_key_v_mod_map_iterator_t iter =
    621         xcb_xkb_get_map_map_vmodmap_rtrn_iterator(reply, map);
    622 
    623     for (int i = 0; i < length; i++) {
    624         xcb_xkb_key_v_mod_map_t *wire = iter.data;
    625         struct xkb_key *key;
    626 
    627         FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
    628                     wire->keycode <= keymap->max_key_code);
    629 
    630         key = &keymap->keys[wire->keycode];
    631         key->vmodmap = translate_mods(0, wire->vmods, 0);
    632 
    633         xcb_xkb_key_v_mod_map_next(&iter);
    634     }
    635 
    636     return true;
    637 
    638 fail:
    639     return false;
    640 }
    641 
    642 static bool
    643 get_map(struct xkb_keymap *keymap, xcb_connection_t *conn, uint16_t device_id)
    644 {
    645     static const xcb_xkb_map_part_t required_components =
    646         (XCB_XKB_MAP_PART_KEY_TYPES |
    647          XCB_XKB_MAP_PART_KEY_SYMS |
    648          XCB_XKB_MAP_PART_MODIFIER_MAP |
    649          XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
    650          XCB_XKB_MAP_PART_KEY_ACTIONS |
    651          XCB_XKB_MAP_PART_VIRTUAL_MODS |
    652          XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);
    653 
    654     xcb_xkb_get_map_cookie_t cookie =
    655         xcb_xkb_get_map(conn, device_id, required_components,
    656                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    657     xcb_xkb_get_map_reply_t *reply = xcb_xkb_get_map_reply(conn, cookie, NULL);
    658     xcb_xkb_get_map_map_t map;
    659 
    660     FAIL_IF_BAD_REPLY(reply, "XkbGetMap");
    661 
    662     if ((reply->present & required_components) != required_components)
    663         goto fail;
    664 
    665     xcb_xkb_get_map_map_unpack(xcb_xkb_get_map_map(reply),
    666                                reply->nTypes,
    667                                reply->nKeySyms,
    668                                reply->nKeyActions,
    669                                reply->totalActions,
    670                                reply->totalKeyBehaviors,
    671                                reply->virtualMods,
    672                                reply->totalKeyExplicit,
    673                                reply->totalModMapKeys,
    674                                reply->totalVModMapKeys,
    675                                reply->present,
    676                                &map);
    677 
    678     if (!get_types(keymap, conn, reply, &map) ||
    679         !get_sym_maps(keymap, conn, reply, &map) ||
    680         !get_actions(keymap, conn, reply, &map) ||
    681         !get_vmods(keymap, conn, reply, &map) ||
    682         !get_explicits(keymap, conn, reply, &map) ||
    683         !get_modmaps(keymap, conn, reply, &map) ||
    684         !get_vmodmaps(keymap, conn, reply, &map))
    685         goto fail;
    686 
    687     free(reply);
    688     return true;
    689 
    690 fail:
    691     free(reply);
    692     return false;
    693 }
    694 
    695 static bool
    696 get_indicators(struct xkb_keymap *keymap, xcb_connection_t *conn,
    697                xcb_xkb_get_indicator_map_reply_t *reply)
    698 {
    699     xcb_xkb_indicator_map_iterator_t iter =
    700         xcb_xkb_get_indicator_map_maps_iterator(reply);
    701 
    702     keymap->num_leds = msb_pos(reply->which);
    703 
    704     for (unsigned i = 0; i < NUM_INDICATORS; i++) {
    705         if (reply->which & (1u << i)) {
    706             xcb_xkb_indicator_map_t *wire = iter.data;
    707             struct xkb_led *led = &keymap->leds[i];
    708 
    709             if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_BASE)
    710                 led->which_groups |= XKB_STATE_LAYOUT_DEPRESSED;
    711             if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_LATCHED)
    712                 led->which_groups |= XKB_STATE_LAYOUT_LATCHED;
    713             if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_LOCKED)
    714                 led->which_groups |= XKB_STATE_LAYOUT_LOCKED;
    715             if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_EFFECTIVE)
    716                 led->which_groups |= XKB_STATE_LAYOUT_EFFECTIVE;
    717             if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_COMPAT)
    718                 led->which_groups |= XKB_STATE_LAYOUT_EFFECTIVE;
    719 
    720             led->groups = wire->groups;
    721 
    722             if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_BASE)
    723                 led->which_mods |= XKB_STATE_MODS_DEPRESSED;
    724             if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_LATCHED)
    725                 led->which_mods |= XKB_STATE_MODS_LATCHED;
    726             if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_LOCKED)
    727                 led->which_mods |= XKB_STATE_MODS_LOCKED;
    728             if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_EFFECTIVE)
    729                 led->which_mods |= XKB_STATE_MODS_EFFECTIVE;
    730             if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_COMPAT)
    731                 led->which_mods |= XKB_STATE_MODS_EFFECTIVE;
    732 
    733             led->mods.mods = translate_mods(wire->realMods, wire->vmods, 0);
    734             led->mods.mask = translate_mods(wire->mods, 0, 0);
    735 
    736             led->ctrls = translate_controls_mask(wire->ctrls);
    737 
    738             xcb_xkb_indicator_map_next(&iter);
    739         }
    740     }
    741 
    742     return true;
    743 }
    744 
    745 static bool
    746 get_indicator_map(struct xkb_keymap *keymap, xcb_connection_t *conn,
    747                   uint16_t device_id)
    748 {
    749     xcb_xkb_get_indicator_map_cookie_t cookie =
    750         xcb_xkb_get_indicator_map(conn, device_id, ALL_INDICATORS_MASK);
    751     xcb_xkb_get_indicator_map_reply_t *reply =
    752         xcb_xkb_get_indicator_map_reply(conn, cookie, NULL);
    753 
    754     FAIL_IF_BAD_REPLY(reply, "XkbGetIndicatorMap");
    755 
    756     if (!get_indicators(keymap, conn, reply))
    757         goto fail;
    758 
    759     free(reply);
    760     return true;
    761 
    762 fail:
    763     free(reply);
    764     return false;
    765 }
    766 
    767 static bool
    768 get_sym_interprets(struct xkb_keymap *keymap, xcb_connection_t *conn,
    769                    xcb_xkb_get_compat_map_reply_t *reply)
    770 {
    771     int length = xcb_xkb_get_compat_map_si_rtrn_length(reply);
    772     xcb_xkb_sym_interpret_iterator_t iter =
    773         xcb_xkb_get_compat_map_si_rtrn_iterator(reply);
    774 
    775     FAIL_UNLESS(reply->firstSIRtrn == 0);
    776     FAIL_UNLESS(reply->nSIRtrn == reply->nTotalSI);
    777 
    778     keymap->num_sym_interprets = reply->nSIRtrn;
    779     ALLOC_OR_FAIL(keymap->sym_interprets, keymap->num_sym_interprets);
    780 
    781     for (int i = 0; i < length; i++) {
    782         xcb_xkb_sym_interpret_t *wire = iter.data;
    783         struct xkb_sym_interpret *sym_interpret = &keymap->sym_interprets[i];
    784 
    785         sym_interpret->sym = wire->sym;
    786 
    787         switch (wire->match & XCB_XKB_SYM_INTERP_MATCH_OP_MASK) {
    788         case XCB_XKB_SYM_INTERPRET_MATCH_NONE_OF:
    789             sym_interpret->match = MATCH_NONE;
    790             break;
    791         case XCB_XKB_SYM_INTERPRET_MATCH_ANY_OF_OR_NONE:
    792             sym_interpret->match = MATCH_ANY_OR_NONE;
    793             break;
    794         case XCB_XKB_SYM_INTERPRET_MATCH_ANY_OF:
    795             sym_interpret->match = MATCH_ANY;
    796             break;
    797         case XCB_XKB_SYM_INTERPRET_MATCH_ALL_OF:
    798             sym_interpret->match = MATCH_ALL;
    799             break;
    800         case XCB_XKB_SYM_INTERPRET_MATCH_EXACTLY:
    801             sym_interpret->match = MATCH_EXACTLY;
    802             break;
    803         }
    804 
    805         sym_interpret->level_one_only =
    806             (wire->match & XCB_XKB_SYM_INTERP_MATCH_LEVEL_ONE_ONLY);
    807         sym_interpret->mods = wire->mods;
    808 
    809         if (wire->virtualMod == NO_MODIFIER)
    810             sym_interpret->virtual_mod = XKB_MOD_INVALID;
    811         else
    812             sym_interpret->virtual_mod = NUM_REAL_MODS + wire->virtualMod;
    813 
    814         sym_interpret->repeat = (wire->flags & 0x01);
    815         translate_action(&sym_interpret->action,
    816                          (xcb_xkb_action_t *) &wire->action);
    817 
    818         xcb_xkb_sym_interpret_next(&iter);
    819     }
    820 
    821     return true;
    822 
    823 fail:
    824     return false;
    825 }
    826 
    827 static bool
    828 get_compat_map(struct xkb_keymap *keymap, xcb_connection_t *conn,
    829                uint16_t device_id)
    830 {
    831     xcb_xkb_get_compat_map_cookie_t cookie =
    832         xcb_xkb_get_compat_map(conn, device_id, 0, true, 0, 0);
    833     xcb_xkb_get_compat_map_reply_t *reply =
    834         xcb_xkb_get_compat_map_reply(conn, cookie, NULL);
    835 
    836     FAIL_IF_BAD_REPLY(reply, "XkbGetCompatMap");
    837 
    838     if (!get_sym_interprets(keymap, conn, reply))
    839         goto fail;
    840 
    841     free(reply);
    842     return true;
    843 
    844 fail:
    845     free(reply);
    846     return false;
    847 }
    848 
    849 static bool
    850 get_type_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
    851                xcb_xkb_get_names_reply_t *reply,
    852                xcb_xkb_get_names_value_list_t *list)
    853 {
    854     int key_type_names_length =
    855         xcb_xkb_get_names_value_list_type_names_length(reply, list);
    856     xcb_atom_t *key_type_names_iter =
    857         xcb_xkb_get_names_value_list_type_names(list);
    858     int n_levels_per_type_length =
    859         xcb_xkb_get_names_value_list_n_levels_per_type_length(reply, list);
    860     uint8_t *n_levels_per_type_iter =
    861         xcb_xkb_get_names_value_list_n_levels_per_type(list);
    862     xcb_atom_t *kt_level_names_iter =
    863         xcb_xkb_get_names_value_list_kt_level_names(list);
    864 
    865     FAIL_UNLESS(reply->nTypes == keymap->num_types);
    866     FAIL_UNLESS(key_type_names_length == n_levels_per_type_length);
    867 
    868     for (int i = 0; i < key_type_names_length; i++) {
    869         xcb_atom_t wire_type_name = *key_type_names_iter;
    870         uint8_t wire_num_levels = *n_levels_per_type_iter;
    871         struct xkb_key_type *type = &keymap->types[i];
    872 
    873         /* Levels must have names. */
    874         FAIL_UNLESS(type->num_levels == wire_num_levels);
    875 
    876         ALLOC_OR_FAIL(type->level_names, type->num_levels);
    877 
    878         if (!adopt_atom(keymap->ctx, conn, wire_type_name, &type->name))
    879             goto fail;
    880 
    881         if (!adopt_atoms(keymap->ctx, conn,
    882                          kt_level_names_iter, type->level_names,
    883                          wire_num_levels))
    884             goto fail;
    885 
    886         kt_level_names_iter += wire_num_levels;
    887         key_type_names_iter++;
    888         n_levels_per_type_iter++;
    889     }
    890 
    891     return true;
    892 
    893 fail:
    894     return false;
    895 }
    896 
    897 static bool
    898 get_indicator_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
    899                     xcb_xkb_get_names_reply_t *reply,
    900                     xcb_xkb_get_names_value_list_t *list)
    901 {
    902     xcb_atom_t *iter = xcb_xkb_get_names_value_list_indicator_names(list);
    903 
    904     FAIL_UNLESS(msb_pos(reply->indicators) <= keymap->num_leds);
    905 
    906     for (unsigned i = 0; i < NUM_INDICATORS; i++) {
    907         if (reply->indicators & (1u << i)) {
    908             xcb_atom_t wire = *iter;
    909             struct xkb_led *led = &keymap->leds[i];
    910 
    911             if (!adopt_atom(keymap->ctx, conn, wire, &led->name))
    912                 return false;
    913 
    914             iter++;
    915         }
    916     }
    917 
    918     return true;
    919 
    920 fail:
    921     return false;
    922 }
    923 
    924 static bool
    925 get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
    926                xcb_xkb_get_names_reply_t *reply,
    927                xcb_xkb_get_names_value_list_t *list)
    928 {
    929     xcb_atom_t *iter = xcb_xkb_get_names_value_list_virtual_mod_names(list);
    930 
    931     /*
    932      * GetMap's reply->virtualMods is always 0xffff. This one really
    933      * tells us which vmods exist (a vmod must have a name), so we fix
    934      * up the size here.
    935      */
    936     keymap->mods.num_mods =
    937         NUM_REAL_MODS + MIN(msb_pos(reply->virtualMods), NUM_VMODS);
    938 
    939     for (unsigned i = 0; i < NUM_VMODS; i++) {
    940         if (reply->virtualMods & (1u << i)) {
    941             xcb_atom_t wire = *iter;
    942             struct xkb_mod *mod = &keymap->mods.mods[NUM_REAL_MODS + i];
    943 
    944             if (!adopt_atom(keymap->ctx, conn, wire, &mod->name))
    945                 return false;
    946 
    947             iter++;
    948         }
    949     }
    950 
    951     return true;
    952 }
    953 
    954 static bool
    955 get_group_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
    956                 xcb_xkb_get_names_reply_t *reply,
    957                 xcb_xkb_get_names_value_list_t *list)
    958 {
    959     int length = xcb_xkb_get_names_value_list_groups_length(reply, list);
    960     xcb_atom_t *iter = xcb_xkb_get_names_value_list_groups(list);
    961 
    962     keymap->num_group_names = msb_pos(reply->groupNames);
    963     ALLOC_OR_FAIL(keymap->group_names, keymap->num_group_names);
    964 
    965     if (!adopt_atoms(keymap->ctx, conn,
    966                      iter, keymap->group_names, length))
    967         goto fail;
    968 
    969     return true;
    970 
    971 fail:
    972     return false;
    973 }
    974 
    975 static bool
    976 get_key_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
    977               xcb_xkb_get_names_reply_t *reply,
    978               xcb_xkb_get_names_value_list_t *list)
    979 {
    980     int length = xcb_xkb_get_names_value_list_key_names_length(reply, list);
    981     xcb_xkb_key_name_iterator_t iter =
    982         xcb_xkb_get_names_value_list_key_names_iterator(reply, list);
    983 
    984     FAIL_UNLESS(reply->minKeyCode == keymap->min_key_code);
    985     FAIL_UNLESS(reply->maxKeyCode == keymap->max_key_code);
    986     FAIL_UNLESS(reply->firstKey == keymap->min_key_code);
    987     FAIL_UNLESS(reply->firstKey + reply->nKeys - 1U == keymap->max_key_code);
    988 
    989     for (int i = 0; i < length; i++) {
    990         xcb_xkb_key_name_t *wire = iter.data;
    991         xkb_atom_t *key_name = &keymap->keys[reply->firstKey + i].name;
    992 
    993         if (wire->name[0] == '\0') {
    994             *key_name = XKB_ATOM_NONE;
    995         }
    996         else {
    997             *key_name = xkb_atom_intern(keymap->ctx, wire->name,
    998                                         strnlen(wire->name,
    999                                                 XCB_XKB_CONST_KEY_NAME_LENGTH));
   1000             if (!*key_name)
   1001                 return false;
   1002         }
   1003 
   1004         xcb_xkb_key_name_next(&iter);
   1005     }
   1006 
   1007     return true;
   1008 
   1009 fail:
   1010     return false;
   1011 }
   1012 
   1013 static bool
   1014 get_aliases(struct xkb_keymap *keymap, xcb_connection_t *conn,
   1015             xcb_xkb_get_names_reply_t *reply,
   1016             xcb_xkb_get_names_value_list_t *list)
   1017 {
   1018     int length = xcb_xkb_get_names_value_list_key_aliases_length(reply, list);
   1019     xcb_xkb_key_alias_iterator_t iter =
   1020         xcb_xkb_get_names_value_list_key_aliases_iterator(reply, list);
   1021 
   1022     keymap->num_key_aliases = reply->nKeyAliases;
   1023     ALLOC_OR_FAIL(keymap->key_aliases, keymap->num_key_aliases);
   1024 
   1025     for (int i = 0; i < length; i++) {
   1026         xcb_xkb_key_alias_t *wire = iter.data;
   1027         struct xkb_key_alias *alias = &keymap->key_aliases[i];
   1028 
   1029         alias->real =
   1030             xkb_atom_intern(keymap->ctx, wire->real,
   1031                             strnlen(wire->real, XCB_XKB_CONST_KEY_NAME_LENGTH));
   1032         alias->alias =
   1033             xkb_atom_intern(keymap->ctx, wire->alias,
   1034                             strnlen(wire->alias, XCB_XKB_CONST_KEY_NAME_LENGTH));
   1035         if (!alias->real || !alias->alias)
   1036             goto fail;
   1037 
   1038         xcb_xkb_key_alias_next(&iter);
   1039     }
   1040 
   1041     return true;
   1042 
   1043 fail:
   1044     return false;
   1045 }
   1046 
   1047 static bool
   1048 get_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
   1049           uint16_t device_id)
   1050 {
   1051     static const xcb_xkb_name_detail_t wanted =
   1052         (XCB_XKB_NAME_DETAIL_KEYCODES |
   1053          XCB_XKB_NAME_DETAIL_SYMBOLS |
   1054          XCB_XKB_NAME_DETAIL_TYPES |
   1055          XCB_XKB_NAME_DETAIL_COMPAT |
   1056          XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
   1057          XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
   1058          XCB_XKB_NAME_DETAIL_INDICATOR_NAMES |
   1059          XCB_XKB_NAME_DETAIL_KEY_NAMES |
   1060          XCB_XKB_NAME_DETAIL_KEY_ALIASES |
   1061          XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES |
   1062          XCB_XKB_NAME_DETAIL_GROUP_NAMES);
   1063     static const xcb_xkb_name_detail_t required =
   1064         (XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
   1065          XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
   1066          XCB_XKB_NAME_DETAIL_KEY_NAMES |
   1067          XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES);
   1068 
   1069     xcb_xkb_get_names_cookie_t cookie =
   1070         xcb_xkb_get_names(conn, device_id, wanted);
   1071     xcb_xkb_get_names_reply_t *reply =
   1072         xcb_xkb_get_names_reply(conn, cookie, NULL);
   1073     xcb_xkb_get_names_value_list_t list;
   1074 
   1075     FAIL_IF_BAD_REPLY(reply, "XkbGetNames");
   1076 
   1077     FAIL_UNLESS((reply->which & required) == required);
   1078 
   1079     xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply),
   1080                                         reply->nTypes,
   1081                                         reply->indicators,
   1082                                         reply->virtualMods,
   1083                                         reply->groupNames,
   1084                                         reply->nKeys,
   1085                                         reply->nKeyAliases,
   1086                                         reply->nRadioGroups,
   1087                                         reply->which,
   1088                                         &list);
   1089 
   1090     if (!get_atom_name(conn, list.keycodesName, &keymap->keycodes_section_name) ||
   1091         !get_atom_name(conn, list.symbolsName, &keymap->symbols_section_name) ||
   1092         !get_atom_name(conn, list.typesName, &keymap->types_section_name) ||
   1093         !get_atom_name(conn, list.compatName, &keymap->compat_section_name) ||
   1094         !get_type_names(keymap, conn, reply, &list) ||
   1095         !get_indicator_names(keymap, conn, reply, &list) ||
   1096         !get_vmod_names(keymap, conn, reply, &list) ||
   1097         !get_group_names(keymap, conn, reply, &list) ||
   1098         !get_key_names(keymap, conn, reply, &list) ||
   1099         !get_aliases(keymap, conn, reply, &list))
   1100         goto fail;
   1101 
   1102     XkbEscapeMapName(keymap->keycodes_section_name);
   1103     XkbEscapeMapName(keymap->symbols_section_name);
   1104     XkbEscapeMapName(keymap->types_section_name);
   1105     XkbEscapeMapName(keymap->compat_section_name);
   1106 
   1107     free(reply);
   1108     return true;
   1109 
   1110 fail:
   1111     free(reply);
   1112     return false;
   1113 }
   1114 
   1115 static bool
   1116 get_controls(struct xkb_keymap *keymap, xcb_connection_t *conn,
   1117              uint16_t device_id)
   1118 {
   1119     xcb_xkb_get_controls_cookie_t cookie =
   1120         xcb_xkb_get_controls(conn, device_id);
   1121     xcb_xkb_get_controls_reply_t *reply =
   1122         xcb_xkb_get_controls_reply(conn, cookie, NULL);
   1123 
   1124     FAIL_IF_BAD_REPLY(reply, "XkbGetControls");
   1125     FAIL_UNLESS(reply->numGroups > 0 && reply->numGroups <= 4);
   1126 
   1127     keymap->enabled_ctrls = translate_controls_mask(reply->enabledControls);
   1128     keymap->num_groups = reply->numGroups;
   1129 
   1130     FAIL_UNLESS(keymap->max_key_code < XCB_XKB_CONST_PER_KEY_BIT_ARRAY_SIZE * 8);
   1131 
   1132     for (xkb_keycode_t i = keymap->min_key_code; i <= keymap->max_key_code; i++)
   1133         keymap->keys[i].repeats = (reply->perKeyRepeat[i / 8] & (1 << (i % 8)));
   1134 
   1135     free(reply);
   1136     return true;
   1137 
   1138 fail:
   1139     free(reply);
   1140     return false;
   1141 }
   1142 
   1143 XKB_EXPORT struct xkb_keymap *
   1144 xkb_x11_keymap_new_from_device(struct xkb_context *ctx,
   1145                                xcb_connection_t *conn,
   1146                                int32_t device_id,
   1147                                enum xkb_keymap_compile_flags flags)
   1148 {
   1149     struct xkb_keymap *keymap;
   1150     const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1;
   1151 
   1152     if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
   1153         log_err_func(ctx, "unrecognized flags: %#x\n", flags);
   1154         return NULL;
   1155     }
   1156 
   1157     if (device_id < 0 || device_id > 255) {
   1158         log_err_func(ctx, "illegal device ID: %d\n", device_id);
   1159         return NULL;
   1160     }
   1161 
   1162     keymap = xkb_keymap_new(ctx, format, flags);
   1163     if (!keymap)
   1164         return NULL;
   1165 
   1166     if (!get_map(keymap, conn, device_id) ||
   1167         !get_indicator_map(keymap, conn, device_id) ||
   1168         !get_compat_map(keymap, conn, device_id) ||
   1169         !get_names(keymap, conn, device_id) ||
   1170         !get_controls(keymap, conn, device_id)) {
   1171         xkb_keymap_unref(keymap);
   1172         return NULL;
   1173     }
   1174 
   1175     return keymap;
   1176 }
   1177