1*2b949d04SAndroid Build Coastguard Worker /*
2*2b949d04SAndroid Build Coastguard Worker * Copyright © 2009 Dan Nicholson
3*2b949d04SAndroid Build Coastguard Worker * Copyright © 2012 Intel Corporation
4*2b949d04SAndroid Build Coastguard Worker * Copyright © 2012 Ran Benita <[email protected]>
5*2b949d04SAndroid Build Coastguard Worker *
6*2b949d04SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*2b949d04SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
8*2b949d04SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
9*2b949d04SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*2b949d04SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
11*2b949d04SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
12*2b949d04SAndroid Build Coastguard Worker *
13*2b949d04SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
14*2b949d04SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
15*2b949d04SAndroid Build Coastguard Worker * Software.
16*2b949d04SAndroid Build Coastguard Worker *
17*2b949d04SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*2b949d04SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*2b949d04SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*2b949d04SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21*2b949d04SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22*2b949d04SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23*2b949d04SAndroid Build Coastguard Worker * DEALINGS IN THE SOFTWARE.
24*2b949d04SAndroid Build Coastguard Worker *
25*2b949d04SAndroid Build Coastguard Worker * Author: Dan Nicholson <[email protected]>
26*2b949d04SAndroid Build Coastguard Worker * Daniel Stone <[email protected]>
27*2b949d04SAndroid Build Coastguard Worker * Ran Benita <[email protected]>
28*2b949d04SAndroid Build Coastguard Worker */
29*2b949d04SAndroid Build Coastguard Worker
30*2b949d04SAndroid Build Coastguard Worker #include "config.h"
31*2b949d04SAndroid Build Coastguard Worker
32*2b949d04SAndroid Build Coastguard Worker #include "xkbcomp-priv.h"
33*2b949d04SAndroid Build Coastguard Worker
34*2b949d04SAndroid Build Coastguard Worker static void
ComputeEffectiveMask(struct xkb_keymap * keymap,struct xkb_mods * mods)35*2b949d04SAndroid Build Coastguard Worker ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods)
36*2b949d04SAndroid Build Coastguard Worker {
37*2b949d04SAndroid Build Coastguard Worker mods->mask = mod_mask_get_effective(keymap, mods->mods);
38*2b949d04SAndroid Build Coastguard Worker }
39*2b949d04SAndroid Build Coastguard Worker
40*2b949d04SAndroid Build Coastguard Worker static void
UpdateActionMods(struct xkb_keymap * keymap,union xkb_action * act,xkb_mod_mask_t modmap)41*2b949d04SAndroid Build Coastguard Worker UpdateActionMods(struct xkb_keymap *keymap, union xkb_action *act,
42*2b949d04SAndroid Build Coastguard Worker xkb_mod_mask_t modmap)
43*2b949d04SAndroid Build Coastguard Worker {
44*2b949d04SAndroid Build Coastguard Worker switch (act->type) {
45*2b949d04SAndroid Build Coastguard Worker case ACTION_TYPE_MOD_SET:
46*2b949d04SAndroid Build Coastguard Worker case ACTION_TYPE_MOD_LATCH:
47*2b949d04SAndroid Build Coastguard Worker case ACTION_TYPE_MOD_LOCK:
48*2b949d04SAndroid Build Coastguard Worker if (act->mods.flags & ACTION_MODS_LOOKUP_MODMAP)
49*2b949d04SAndroid Build Coastguard Worker act->mods.mods.mods = modmap;
50*2b949d04SAndroid Build Coastguard Worker ComputeEffectiveMask(keymap, &act->mods.mods);
51*2b949d04SAndroid Build Coastguard Worker break;
52*2b949d04SAndroid Build Coastguard Worker default:
53*2b949d04SAndroid Build Coastguard Worker break;
54*2b949d04SAndroid Build Coastguard Worker }
55*2b949d04SAndroid Build Coastguard Worker }
56*2b949d04SAndroid Build Coastguard Worker
57*2b949d04SAndroid Build Coastguard Worker static const struct xkb_sym_interpret default_interpret = {
58*2b949d04SAndroid Build Coastguard Worker .sym = XKB_KEY_NoSymbol,
59*2b949d04SAndroid Build Coastguard Worker .repeat = true,
60*2b949d04SAndroid Build Coastguard Worker .match = MATCH_ANY_OR_NONE,
61*2b949d04SAndroid Build Coastguard Worker .mods = 0,
62*2b949d04SAndroid Build Coastguard Worker .virtual_mod = XKB_MOD_INVALID,
63*2b949d04SAndroid Build Coastguard Worker .action = { .type = ACTION_TYPE_NONE },
64*2b949d04SAndroid Build Coastguard Worker };
65*2b949d04SAndroid Build Coastguard Worker
66*2b949d04SAndroid Build Coastguard Worker /**
67*2b949d04SAndroid Build Coastguard Worker * Find an interpretation which applies to this particular level, either by
68*2b949d04SAndroid Build Coastguard Worker * finding an exact match for the symbol and modifier combination, or a
69*2b949d04SAndroid Build Coastguard Worker * generic XKB_KEY_NoSymbol match.
70*2b949d04SAndroid Build Coastguard Worker */
71*2b949d04SAndroid Build Coastguard Worker static const struct xkb_sym_interpret *
FindInterpForKey(struct xkb_keymap * keymap,const struct xkb_key * key,xkb_layout_index_t group,xkb_level_index_t level)72*2b949d04SAndroid Build Coastguard Worker FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key,
73*2b949d04SAndroid Build Coastguard Worker xkb_layout_index_t group, xkb_level_index_t level)
74*2b949d04SAndroid Build Coastguard Worker {
75*2b949d04SAndroid Build Coastguard Worker const xkb_keysym_t *syms;
76*2b949d04SAndroid Build Coastguard Worker int num_syms;
77*2b949d04SAndroid Build Coastguard Worker
78*2b949d04SAndroid Build Coastguard Worker num_syms = xkb_keymap_key_get_syms_by_level(keymap, key->keycode, group,
79*2b949d04SAndroid Build Coastguard Worker level, &syms);
80*2b949d04SAndroid Build Coastguard Worker if (num_syms == 0)
81*2b949d04SAndroid Build Coastguard Worker return NULL;
82*2b949d04SAndroid Build Coastguard Worker
83*2b949d04SAndroid Build Coastguard Worker /*
84*2b949d04SAndroid Build Coastguard Worker * There may be multiple matchings interprets; we should always return
85*2b949d04SAndroid Build Coastguard Worker * the most specific. Here we rely on compat.c to set up the
86*2b949d04SAndroid Build Coastguard Worker * sym_interprets array from the most specific to the least specific,
87*2b949d04SAndroid Build Coastguard Worker * such that when we find a match we return immediately.
88*2b949d04SAndroid Build Coastguard Worker */
89*2b949d04SAndroid Build Coastguard Worker for (unsigned i = 0; i < keymap->num_sym_interprets; i++) {
90*2b949d04SAndroid Build Coastguard Worker const struct xkb_sym_interpret *interp = &keymap->sym_interprets[i];
91*2b949d04SAndroid Build Coastguard Worker
92*2b949d04SAndroid Build Coastguard Worker xkb_mod_mask_t mods;
93*2b949d04SAndroid Build Coastguard Worker bool found = false;
94*2b949d04SAndroid Build Coastguard Worker
95*2b949d04SAndroid Build Coastguard Worker if ((num_syms > 1 || interp->sym != syms[0]) &&
96*2b949d04SAndroid Build Coastguard Worker interp->sym != XKB_KEY_NoSymbol)
97*2b949d04SAndroid Build Coastguard Worker continue;
98*2b949d04SAndroid Build Coastguard Worker
99*2b949d04SAndroid Build Coastguard Worker if (interp->level_one_only && level != 0)
100*2b949d04SAndroid Build Coastguard Worker mods = 0;
101*2b949d04SAndroid Build Coastguard Worker else
102*2b949d04SAndroid Build Coastguard Worker mods = key->modmap;
103*2b949d04SAndroid Build Coastguard Worker
104*2b949d04SAndroid Build Coastguard Worker switch (interp->match) {
105*2b949d04SAndroid Build Coastguard Worker case MATCH_NONE:
106*2b949d04SAndroid Build Coastguard Worker found = !(interp->mods & mods);
107*2b949d04SAndroid Build Coastguard Worker break;
108*2b949d04SAndroid Build Coastguard Worker case MATCH_ANY_OR_NONE:
109*2b949d04SAndroid Build Coastguard Worker found = (!mods || (interp->mods & mods));
110*2b949d04SAndroid Build Coastguard Worker break;
111*2b949d04SAndroid Build Coastguard Worker case MATCH_ANY:
112*2b949d04SAndroid Build Coastguard Worker found = (interp->mods & mods);
113*2b949d04SAndroid Build Coastguard Worker break;
114*2b949d04SAndroid Build Coastguard Worker case MATCH_ALL:
115*2b949d04SAndroid Build Coastguard Worker found = ((interp->mods & mods) == interp->mods);
116*2b949d04SAndroid Build Coastguard Worker break;
117*2b949d04SAndroid Build Coastguard Worker case MATCH_EXACTLY:
118*2b949d04SAndroid Build Coastguard Worker found = (interp->mods == mods);
119*2b949d04SAndroid Build Coastguard Worker break;
120*2b949d04SAndroid Build Coastguard Worker }
121*2b949d04SAndroid Build Coastguard Worker
122*2b949d04SAndroid Build Coastguard Worker if (found)
123*2b949d04SAndroid Build Coastguard Worker return interp;
124*2b949d04SAndroid Build Coastguard Worker }
125*2b949d04SAndroid Build Coastguard Worker
126*2b949d04SAndroid Build Coastguard Worker return &default_interpret;
127*2b949d04SAndroid Build Coastguard Worker }
128*2b949d04SAndroid Build Coastguard Worker
129*2b949d04SAndroid Build Coastguard Worker static bool
ApplyInterpsToKey(struct xkb_keymap * keymap,struct xkb_key * key)130*2b949d04SAndroid Build Coastguard Worker ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key)
131*2b949d04SAndroid Build Coastguard Worker {
132*2b949d04SAndroid Build Coastguard Worker xkb_mod_mask_t vmodmap = 0;
133*2b949d04SAndroid Build Coastguard Worker xkb_layout_index_t group;
134*2b949d04SAndroid Build Coastguard Worker xkb_level_index_t level;
135*2b949d04SAndroid Build Coastguard Worker
136*2b949d04SAndroid Build Coastguard Worker /* If we've been told not to bind interps to this key, then don't. */
137*2b949d04SAndroid Build Coastguard Worker if (key->explicit & EXPLICIT_INTERP)
138*2b949d04SAndroid Build Coastguard Worker return true;
139*2b949d04SAndroid Build Coastguard Worker
140*2b949d04SAndroid Build Coastguard Worker for (group = 0; group < key->num_groups; group++) {
141*2b949d04SAndroid Build Coastguard Worker for (level = 0; level < XkbKeyNumLevels(key, group); level++) {
142*2b949d04SAndroid Build Coastguard Worker const struct xkb_sym_interpret *interp;
143*2b949d04SAndroid Build Coastguard Worker
144*2b949d04SAndroid Build Coastguard Worker interp = FindInterpForKey(keymap, key, group, level);
145*2b949d04SAndroid Build Coastguard Worker if (!interp)
146*2b949d04SAndroid Build Coastguard Worker continue;
147*2b949d04SAndroid Build Coastguard Worker
148*2b949d04SAndroid Build Coastguard Worker /* Infer default key behaviours from the base level. */
149*2b949d04SAndroid Build Coastguard Worker if (group == 0 && level == 0)
150*2b949d04SAndroid Build Coastguard Worker if (!(key->explicit & EXPLICIT_REPEAT) && interp->repeat)
151*2b949d04SAndroid Build Coastguard Worker key->repeats = true;
152*2b949d04SAndroid Build Coastguard Worker
153*2b949d04SAndroid Build Coastguard Worker if ((group == 0 && level == 0) || !interp->level_one_only)
154*2b949d04SAndroid Build Coastguard Worker if (interp->virtual_mod != XKB_MOD_INVALID)
155*2b949d04SAndroid Build Coastguard Worker vmodmap |= (1u << interp->virtual_mod);
156*2b949d04SAndroid Build Coastguard Worker
157*2b949d04SAndroid Build Coastguard Worker if (interp->action.type != ACTION_TYPE_NONE)
158*2b949d04SAndroid Build Coastguard Worker key->groups[group].levels[level].action = interp->action;
159*2b949d04SAndroid Build Coastguard Worker }
160*2b949d04SAndroid Build Coastguard Worker }
161*2b949d04SAndroid Build Coastguard Worker
162*2b949d04SAndroid Build Coastguard Worker if (!(key->explicit & EXPLICIT_VMODMAP))
163*2b949d04SAndroid Build Coastguard Worker key->vmodmap = vmodmap;
164*2b949d04SAndroid Build Coastguard Worker
165*2b949d04SAndroid Build Coastguard Worker return true;
166*2b949d04SAndroid Build Coastguard Worker }
167*2b949d04SAndroid Build Coastguard Worker
168*2b949d04SAndroid Build Coastguard Worker /**
169*2b949d04SAndroid Build Coastguard Worker * This collects a bunch of disparate functions which was done in the server
170*2b949d04SAndroid Build Coastguard Worker * at various points that really should've been done within xkbcomp. Turns out
171*2b949d04SAndroid Build Coastguard Worker * your actions and types are a lot more useful when any of your modifiers
172*2b949d04SAndroid Build Coastguard Worker * other than Shift actually do something ...
173*2b949d04SAndroid Build Coastguard Worker */
174*2b949d04SAndroid Build Coastguard Worker static bool
UpdateDerivedKeymapFields(struct xkb_keymap * keymap)175*2b949d04SAndroid Build Coastguard Worker UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
176*2b949d04SAndroid Build Coastguard Worker {
177*2b949d04SAndroid Build Coastguard Worker struct xkb_key *key;
178*2b949d04SAndroid Build Coastguard Worker struct xkb_mod *mod;
179*2b949d04SAndroid Build Coastguard Worker struct xkb_led *led;
180*2b949d04SAndroid Build Coastguard Worker unsigned int i, j;
181*2b949d04SAndroid Build Coastguard Worker
182*2b949d04SAndroid Build Coastguard Worker /* Find all the interprets for the key and bind them to actions,
183*2b949d04SAndroid Build Coastguard Worker * which will also update the vmodmap. */
184*2b949d04SAndroid Build Coastguard Worker xkb_keys_foreach(key, keymap)
185*2b949d04SAndroid Build Coastguard Worker if (!ApplyInterpsToKey(keymap, key))
186*2b949d04SAndroid Build Coastguard Worker return false;
187*2b949d04SAndroid Build Coastguard Worker
188*2b949d04SAndroid Build Coastguard Worker /* Update keymap->mods, the virtual -> real mod mapping. */
189*2b949d04SAndroid Build Coastguard Worker xkb_keys_foreach(key, keymap)
190*2b949d04SAndroid Build Coastguard Worker xkb_mods_enumerate(i, mod, &keymap->mods)
191*2b949d04SAndroid Build Coastguard Worker if (key->vmodmap & (1u << i))
192*2b949d04SAndroid Build Coastguard Worker mod->mapping |= key->modmap;
193*2b949d04SAndroid Build Coastguard Worker
194*2b949d04SAndroid Build Coastguard Worker /* Now update the level masks for all the types to reflect the vmods. */
195*2b949d04SAndroid Build Coastguard Worker for (i = 0; i < keymap->num_types; i++) {
196*2b949d04SAndroid Build Coastguard Worker ComputeEffectiveMask(keymap, &keymap->types[i].mods);
197*2b949d04SAndroid Build Coastguard Worker
198*2b949d04SAndroid Build Coastguard Worker for (j = 0; j < keymap->types[i].num_entries; j++) {
199*2b949d04SAndroid Build Coastguard Worker ComputeEffectiveMask(keymap, &keymap->types[i].entries[j].mods);
200*2b949d04SAndroid Build Coastguard Worker ComputeEffectiveMask(keymap, &keymap->types[i].entries[j].preserve);
201*2b949d04SAndroid Build Coastguard Worker }
202*2b949d04SAndroid Build Coastguard Worker }
203*2b949d04SAndroid Build Coastguard Worker
204*2b949d04SAndroid Build Coastguard Worker /* Update action modifiers. */
205*2b949d04SAndroid Build Coastguard Worker xkb_keys_foreach(key, keymap)
206*2b949d04SAndroid Build Coastguard Worker for (i = 0; i < key->num_groups; i++)
207*2b949d04SAndroid Build Coastguard Worker for (j = 0; j < XkbKeyNumLevels(key, i); j++)
208*2b949d04SAndroid Build Coastguard Worker UpdateActionMods(keymap, &key->groups[i].levels[j].action,
209*2b949d04SAndroid Build Coastguard Worker key->modmap);
210*2b949d04SAndroid Build Coastguard Worker
211*2b949d04SAndroid Build Coastguard Worker /* Update vmod -> led maps. */
212*2b949d04SAndroid Build Coastguard Worker xkb_leds_foreach(led, keymap)
213*2b949d04SAndroid Build Coastguard Worker ComputeEffectiveMask(keymap, &led->mods);
214*2b949d04SAndroid Build Coastguard Worker
215*2b949d04SAndroid Build Coastguard Worker /* Find maximum number of groups out of all keys in the keymap. */
216*2b949d04SAndroid Build Coastguard Worker xkb_keys_foreach(key, keymap)
217*2b949d04SAndroid Build Coastguard Worker keymap->num_groups = MAX(keymap->num_groups, key->num_groups);
218*2b949d04SAndroid Build Coastguard Worker
219*2b949d04SAndroid Build Coastguard Worker return true;
220*2b949d04SAndroid Build Coastguard Worker }
221*2b949d04SAndroid Build Coastguard Worker
222*2b949d04SAndroid Build Coastguard Worker typedef bool (*compile_file_fn)(XkbFile *file,
223*2b949d04SAndroid Build Coastguard Worker struct xkb_keymap *keymap,
224*2b949d04SAndroid Build Coastguard Worker enum merge_mode merge);
225*2b949d04SAndroid Build Coastguard Worker
226*2b949d04SAndroid Build Coastguard Worker static const compile_file_fn compile_file_fns[LAST_KEYMAP_FILE_TYPE + 1] = {
227*2b949d04SAndroid Build Coastguard Worker [FILE_TYPE_KEYCODES] = CompileKeycodes,
228*2b949d04SAndroid Build Coastguard Worker [FILE_TYPE_TYPES] = CompileKeyTypes,
229*2b949d04SAndroid Build Coastguard Worker [FILE_TYPE_COMPAT] = CompileCompatMap,
230*2b949d04SAndroid Build Coastguard Worker [FILE_TYPE_SYMBOLS] = CompileSymbols,
231*2b949d04SAndroid Build Coastguard Worker };
232*2b949d04SAndroid Build Coastguard Worker
233*2b949d04SAndroid Build Coastguard Worker bool
CompileKeymap(XkbFile * file,struct xkb_keymap * keymap,enum merge_mode merge)234*2b949d04SAndroid Build Coastguard Worker CompileKeymap(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
235*2b949d04SAndroid Build Coastguard Worker {
236*2b949d04SAndroid Build Coastguard Worker bool ok;
237*2b949d04SAndroid Build Coastguard Worker XkbFile *files[LAST_KEYMAP_FILE_TYPE + 1] = { NULL };
238*2b949d04SAndroid Build Coastguard Worker enum xkb_file_type type;
239*2b949d04SAndroid Build Coastguard Worker struct xkb_context *ctx = keymap->ctx;
240*2b949d04SAndroid Build Coastguard Worker
241*2b949d04SAndroid Build Coastguard Worker /* Collect section files and check for duplicates. */
242*2b949d04SAndroid Build Coastguard Worker for (file = (XkbFile *) file->defs; file;
243*2b949d04SAndroid Build Coastguard Worker file = (XkbFile *) file->common.next) {
244*2b949d04SAndroid Build Coastguard Worker if (file->file_type < FIRST_KEYMAP_FILE_TYPE ||
245*2b949d04SAndroid Build Coastguard Worker file->file_type > LAST_KEYMAP_FILE_TYPE) {
246*2b949d04SAndroid Build Coastguard Worker if (file->file_type == FILE_TYPE_GEOMETRY) {
247*2b949d04SAndroid Build Coastguard Worker log_vrb(ctx, 1,
248*2b949d04SAndroid Build Coastguard Worker "Geometry sections are not supported; ignoring\n");
249*2b949d04SAndroid Build Coastguard Worker } else {
250*2b949d04SAndroid Build Coastguard Worker log_err(ctx, "Cannot define %s in a keymap file\n",
251*2b949d04SAndroid Build Coastguard Worker xkb_file_type_to_string(file->file_type));
252*2b949d04SAndroid Build Coastguard Worker }
253*2b949d04SAndroid Build Coastguard Worker continue;
254*2b949d04SAndroid Build Coastguard Worker }
255*2b949d04SAndroid Build Coastguard Worker
256*2b949d04SAndroid Build Coastguard Worker if (files[file->file_type]) {
257*2b949d04SAndroid Build Coastguard Worker log_err(ctx,
258*2b949d04SAndroid Build Coastguard Worker "More than one %s section in keymap file; "
259*2b949d04SAndroid Build Coastguard Worker "All sections after the first ignored\n",
260*2b949d04SAndroid Build Coastguard Worker xkb_file_type_to_string(file->file_type));
261*2b949d04SAndroid Build Coastguard Worker continue;
262*2b949d04SAndroid Build Coastguard Worker }
263*2b949d04SAndroid Build Coastguard Worker
264*2b949d04SAndroid Build Coastguard Worker files[file->file_type] = file;
265*2b949d04SAndroid Build Coastguard Worker }
266*2b949d04SAndroid Build Coastguard Worker
267*2b949d04SAndroid Build Coastguard Worker /*
268*2b949d04SAndroid Build Coastguard Worker * Check that all required section were provided.
269*2b949d04SAndroid Build Coastguard Worker * Report everything before failing.
270*2b949d04SAndroid Build Coastguard Worker */
271*2b949d04SAndroid Build Coastguard Worker ok = true;
272*2b949d04SAndroid Build Coastguard Worker for (type = FIRST_KEYMAP_FILE_TYPE;
273*2b949d04SAndroid Build Coastguard Worker type <= LAST_KEYMAP_FILE_TYPE;
274*2b949d04SAndroid Build Coastguard Worker type++) {
275*2b949d04SAndroid Build Coastguard Worker if (files[type] == NULL) {
276*2b949d04SAndroid Build Coastguard Worker log_err(ctx, "Required section %s missing from keymap\n",
277*2b949d04SAndroid Build Coastguard Worker xkb_file_type_to_string(type));
278*2b949d04SAndroid Build Coastguard Worker ok = false;
279*2b949d04SAndroid Build Coastguard Worker }
280*2b949d04SAndroid Build Coastguard Worker }
281*2b949d04SAndroid Build Coastguard Worker if (!ok)
282*2b949d04SAndroid Build Coastguard Worker return false;
283*2b949d04SAndroid Build Coastguard Worker
284*2b949d04SAndroid Build Coastguard Worker /* Compile sections. */
285*2b949d04SAndroid Build Coastguard Worker for (type = FIRST_KEYMAP_FILE_TYPE;
286*2b949d04SAndroid Build Coastguard Worker type <= LAST_KEYMAP_FILE_TYPE;
287*2b949d04SAndroid Build Coastguard Worker type++) {
288*2b949d04SAndroid Build Coastguard Worker log_dbg(ctx, "Compiling %s \"%s\"\n",
289*2b949d04SAndroid Build Coastguard Worker xkb_file_type_to_string(type), files[type]->name);
290*2b949d04SAndroid Build Coastguard Worker
291*2b949d04SAndroid Build Coastguard Worker ok = compile_file_fns[type](files[type], keymap, merge);
292*2b949d04SAndroid Build Coastguard Worker if (!ok) {
293*2b949d04SAndroid Build Coastguard Worker log_err(ctx, "Failed to compile %s\n",
294*2b949d04SAndroid Build Coastguard Worker xkb_file_type_to_string(type));
295*2b949d04SAndroid Build Coastguard Worker return false;
296*2b949d04SAndroid Build Coastguard Worker }
297*2b949d04SAndroid Build Coastguard Worker }
298*2b949d04SAndroid Build Coastguard Worker
299*2b949d04SAndroid Build Coastguard Worker return UpdateDerivedKeymapFields(keymap);
300*2b949d04SAndroid Build Coastguard Worker }
301