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