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