Get rid of struct xkb_key_name
[platform/upstream/libxkbcommon.git] / src / xkbcomp / symbols.c
1 /************************************************************
2  * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3  *
4  * Permission to use, copy, modify, and distribute this
5  * software and its documentation for any purpose and without
6  * fee is hereby granted, provided that the above copyright
7  * notice appear in all copies and that both that copyright
8  * notice and this permission notice appear in supporting
9  * documentation, and that the name of Silicon Graphics not be
10  * used in advertising or publicity pertaining to distribution
11  * of the software without specific prior written permission.
12  * Silicon Graphics makes no representation about the suitability
13  * of this software for any purpose. It is provided "as is"
14  * without any express or implied warranty.
15  *
16  * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18  * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19  * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
24  *
25  ********************************************************/
26
27 #include <limits.h>
28
29 #include "xkbcomp-priv.h"
30 #include "parseutils.h"
31 #include "action.h"
32 #include "alias.h"
33 #include "keycodes.h"
34 #include "vmod.h"
35
36 /***====================================================================***/
37
38 /* Needed to work with the typechecker. */
39 typedef darray (xkb_keysym_t) darray_xkb_keysym_t;
40 typedef darray (union xkb_action) darray_xkb_action;
41
42 #define RepeatYes       1
43 #define RepeatNo        0
44 #define RepeatUndefined ~((unsigned) 0)
45
46 #define _Key_Syms       (1 << 0)
47 #define _Key_Acts       (1 << 1)
48 #define _Key_Repeat     (1 << 2)
49 #define _Key_Behavior   (1 << 3)
50 #define _Key_Type_Dflt  (1 << 4)
51 #define _Key_Types      (1 << 5)
52 #define _Key_GroupInfo  (1 << 6)
53 #define _Key_VModMap    (1 << 7)
54
55 typedef struct _KeyInfo {
56     CommonInfo defs;
57     unsigned long name; /* the 4 chars of the key name, as long */
58     unsigned char groupInfo;
59     unsigned char typesDefined;
60     unsigned char symsDefined;
61     unsigned char actsDefined;
62     unsigned int numLevels[XkbNumKbdGroups];
63
64     /* syms[group] -> Single array for all the keysyms in the group. */
65     darray_xkb_keysym_t syms[XkbNumKbdGroups];
66     /*
67      * symsMapIndex[group][level] -> The index from which the syms for
68      * the level begin in the syms[group] array. Remember each keycode
69      * can have multiple keysyms in each level (that is, each key press
70      * can result in multiple keysyms).
71      */
72     darray(int) symsMapIndex[XkbNumKbdGroups];
73     /*
74      * symsMapNumEntries[group][level] -> How many syms are in
75      * syms[group][symsMapIndex[group][level]].
76      */
77     darray(size_t) symsMapNumEntries[XkbNumKbdGroups];
78
79     darray_xkb_action acts[XkbNumKbdGroups];
80
81     xkb_atom_t types[XkbNumKbdGroups];
82     unsigned repeat;
83     struct xkb_behavior behavior;
84     unsigned short vmodmap;
85     xkb_atom_t dfltType;
86 } KeyInfo;
87
88 /**
89  * Init the given key info to sane values.
90  */
91 static void
92 InitKeyInfo(KeyInfo *keyi, unsigned file_id)
93 {
94     int i;
95     static const char dflt[4] = "*";
96
97     keyi->defs.defined = 0;
98     keyi->defs.file_id = file_id;
99     keyi->defs.merge = MERGE_OVERRIDE;
100     keyi->defs.next = NULL;
101     keyi->name = KeyNameToLong(dflt);
102     keyi->groupInfo = 0;
103     keyi->typesDefined = keyi->symsDefined = keyi->actsDefined = 0;
104
105     for (i = 0; i < XkbNumKbdGroups; i++) {
106         keyi->numLevels[i] = 0;
107         keyi->types[i] = XKB_ATOM_NONE;
108         darray_init(keyi->syms[i]);
109         darray_init(keyi->symsMapIndex[i]);
110         darray_init(keyi->symsMapNumEntries[i]);
111         darray_init(keyi->acts[i]);
112     }
113
114     keyi->dfltType = XKB_ATOM_NONE;
115     keyi->behavior.type = XkbKB_Default;
116     keyi->behavior.data = 0;
117     keyi->vmodmap = 0;
118     keyi->repeat = RepeatUndefined;
119 }
120
121 /**
122  * Free memory associated with this key keyi and reset to sane values.
123  */
124 static void
125 FreeKeyInfo(KeyInfo *keyi)
126 {
127     int i;
128
129     keyi->defs.defined = 0;
130     keyi->defs.file_id = 0;
131     keyi->defs.merge = MERGE_OVERRIDE;
132     keyi->defs.next = NULL;
133     keyi->groupkeyi = 0;
134     keyi->typesDefined = keyi->symsDefined = keyi->actsDefined = 0;
135     for (i = 0; i < XkbNumKbdGroups; i++) {
136         keyi->numLevels[i] = 0;
137         keyi->types[i] = XKB_ATOM_NONE;
138         darray_free(keyi->syms[i]);
139         darray_free(keyi->symsMapIndex[i]);
140         darray_free(keyi->symsMapNumEntries[i]);
141         darray_free(keyi->acts[i]);
142     }
143     keyi->dfltType = XKB_ATOM_NONE;
144     keyi->behavior.type = XkbKB_Default;
145     keyi->behavior.data = 0;
146     keyi->vmodmap = 0;
147     keyi->repeat = RepeatUndefined;
148 }
149
150 /**
151  * Copy old into new, optionally reset old to 0.
152  * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
153  * newly allocated and new points to the new memory areas.
154  */
155 static bool
156 CopyKeyInfo(KeyInfo * old, KeyInfo * new, bool clearOld)
157 {
158     int i;
159
160     *new = *old;
161     new->defs.next = NULL;
162
163     if (clearOld) {
164         for (i = 0; i < XkbNumKbdGroups; i++) {
165             old->numLevels[i] = 0;
166             darray_init(old->symsMapIndex[i]);
167             darray_init(old->symsMapNumEntries[i]);
168             darray_init(old->syms[i]);
169             darray_init(old->acts[i]);
170         }
171     }
172     else {
173         for (i = 0; i < XkbNumKbdGroups; i++) {
174             darray_copy(new->syms[i], old->syms[i]);
175             darray_copy(new->symsMapIndex[i], old->symsMapIndex[i]);
176             darray_copy(new->symsMapNumEntries[i], old->symsMapNumEntries[i]);
177             darray_copy(new->acts[i], old->acts[i]);
178         }
179     }
180
181     return true;
182 }
183
184 /***====================================================================***/
185
186 typedef struct _ModMapEntry {
187     CommonInfo defs;
188     bool haveSymbol;
189     int modifier;
190     union {
191         unsigned long keyName;
192         xkb_keysym_t keySym;
193     } u;
194 } ModMapEntry;
195
196 typedef struct _SymbolsInfo {
197     char *name;         /* e.g. pc+us+inet(evdev) */
198     int errorCount;
199     unsigned file_id;
200     enum merge_mode merge;
201     unsigned explicit_group;
202     darray(KeyInfo) keys;
203     KeyInfo dflt;
204     VModInfo vmods;
205     ActionInfo *action;
206     xkb_atom_t groupNames[XkbNumKbdGroups];
207
208     ModMapEntry *modMap;
209     AliasInfo *aliases;
210 } SymbolsInfo;
211
212 static void
213 InitSymbolsInfo(SymbolsInfo * info, struct xkb_keymap *keymap,
214                 unsigned file_id)
215 {
216     int i;
217
218     info->name = NULL;
219     info->explicit_group = 0;
220     info->errorCount = 0;
221     info->file_id = file_id;
222     info->merge = MERGE_OVERRIDE;
223     darray_init(info->keys);
224     darray_growalloc(info->keys, 110);
225     info->modMap = NULL;
226     for (i = 0; i < XkbNumKbdGroups; i++)
227         info->groupNames[i] = XKB_ATOM_NONE;
228     InitKeyInfo(&info->dflt, file_id);
229     InitVModInfo(&info->vmods, keymap);
230     info->action = NULL;
231     info->aliases = NULL;
232 }
233
234 static void
235 FreeSymbolsInfo(SymbolsInfo * info)
236 {
237     KeyInfo *keyi;
238
239     free(info->name);
240     darray_foreach(keyi, info->keys)
241         FreeKeyInfo(keyi);
242     darray_free(info->keys);
243     if (info->modMap)
244         ClearCommonInfo(&info->modMap->defs);
245     if (info->aliases)
246         ClearAliases(&info->aliases);
247     memset(info, 0, sizeof(SymbolsInfo));
248 }
249
250 static bool
251 ResizeKeyGroup(KeyInfo *keyi, unsigned int group, unsigned int numLevels,
252                unsigned sizeSyms, bool forceActions)
253 {
254     int i;
255
256     if (darray_size(keyi->syms[group]) < sizeSyms)
257         darray_resize0(keyi->syms[group], sizeSyms);
258
259     if (darray_empty(keyi->symsMapIndex[group]) ||
260         keyi->numLevels[group] < numLevels) {
261         darray_resize(keyi->symsMapIndex[group], numLevels);
262         for (i = keyi->numLevels[group]; i < numLevels; i++)
263             darray_item(keyi->symsMapIndex[group], i) = -1;
264     }
265
266     if (darray_empty(keyi->symsMapNumEntries[group]) ||
267         keyi->numLevels[group] < numLevels)
268         darray_resize0(keyi->symsMapNumEntries[group], numLevels);
269
270     if ((forceActions && (keyi->numLevels[group] < numLevels ||
271                           darray_empty(keyi->acts[group]))) ||
272         (keyi->numLevels[group] < numLevels && !darray_empty(keyi->acts[group])))
273         darray_resize0(keyi->acts[group], numLevels);
274
275     if (keyi->numLevels[group] < numLevels)
276         keyi->numLevels[group] = numLevels;
277
278     return true;
279 }
280
281 enum key_group_selector {
282     NONE = 0,
283     FROM = (1 << 0),
284     TO = (1 << 1),
285 };
286
287 static bool
288 MergeKeyGroups(SymbolsInfo * info,
289                KeyInfo * into, KeyInfo * from, unsigned group)
290 {
291     darray_xkb_keysym_t resultSyms;
292     enum key_group_selector using = NONE;
293     darray_xkb_action resultActs;
294     unsigned int resultWidth;
295     unsigned int resultSize = 0;
296     int cur_idx = 0;
297     int i;
298     bool report, clobber;
299
300     clobber = (from->defs.merge != MERGE_AUGMENT);
301
302     report = (warningLevel > 9) ||
303              ((into->defs.file_id == from->defs.file_id) && (warningLevel > 0));
304
305     darray_init(resultSyms);
306
307     if (into->numLevels[group] >= from->numLevels[group]) {
308         resultActs = into->acts[group];
309         resultWidth = into->numLevels[group];
310     }
311     else {
312         resultActs = from->acts[group];
313         resultWidth = from->numLevels[group];
314         darray_resize(into->symsMapIndex[group],
315                       from->numLevels[group]);
316         darray_resize0(into->symsMapNumEntries[group],
317                        from->numLevels[group]);
318
319         for (i = into->numLevels[group]; i < from->numLevels[group]; i++)
320             darray_item(into->symsMapIndex[group], i) = -1;
321     }
322
323     if (darray_empty(resultActs) && (!darray_empty(into->acts[group]) ||
324                                      !darray_empty(from->acts[group]))) {
325         darray_resize0(resultActs, resultWidth);
326         for (i = 0; i < resultWidth; i++) {
327             union xkb_action *fromAct = NULL, *toAct = NULL;
328
329             if (!darray_empty(from->acts[group]))
330                 fromAct = &darray_item(from->acts[group], i);
331
332             if (!darray_empty(into->acts[group]))
333                 toAct = &darray_item(into->acts[group], i);
334
335             if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
336                 && (toAct != NULL)) {
337                 darray_item(resultActs, i) = *toAct;
338             }
339             else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
340                      && (fromAct != NULL)) {
341                 darray_item(resultActs, i) = *fromAct;
342             }
343             else {
344                 union xkb_action *use, *ignore;
345                 if (clobber) {
346                     use = fromAct;
347                     ignore = toAct;
348                 }
349                 else {
350                     use = toAct;
351                     ignore = fromAct;
352                 }
353                 if (report) {
354                     WARN
355                         ("Multiple actions for level %d/group %d on key %s\n",
356                         i + 1, group + 1, longText(into->name));
357                     ACTION("Using %s, ignoring %s\n",
358                            XkbcActionTypeText(use->type),
359                            XkbcActionTypeText(ignore->type));
360                 }
361                 if (use)
362                     darray_item(resultActs, i) = *use;
363             }
364         }
365     }
366
367     for (i = 0; i < resultWidth; i++) {
368         unsigned int fromSize = 0;
369         unsigned toSize = 0;
370
371         if (!darray_empty(from->symsMapNumEntries[group]) &&
372             i < from->numLevels[group])
373             fromSize = darray_item(from->symsMapNumEntries[group], i);
374
375         if (!darray_empty(into->symsMapNumEntries[group]) &&
376             i < into->numLevels[group])
377             toSize = darray_item(into->symsMapNumEntries[group], i);
378
379         if (fromSize == 0) {
380             resultSize += toSize;
381             using |= TO;
382         }
383         else if (toSize == 0 || clobber) {
384             resultSize += fromSize;
385             using |= FROM;
386         }
387         else {
388             resultSize += toSize;
389             using |= TO;
390         }
391     }
392
393     if (resultSize == 0)
394         goto out;
395
396     if (using == FROM) {
397         resultSyms = from->syms[group];
398         darray_free(into->symsMapNumEntries[group]);
399         darray_free(into->symsMapIndex[group]);
400         into->symsMapNumEntries[group] = from->symsMapNumEntries[group];
401         into->symsMapIndex[group] = from->symsMapIndex[group];
402         darray_init(from->symsMapNumEntries[group]);
403         darray_init(from->symsMapIndex[group]);
404         goto out;
405     }
406     else if (using == TO) {
407         resultSyms = into->syms[group];
408         goto out;
409     }
410
411     darray_resize0(resultSyms, resultSize);
412
413     for (i = 0; i < resultWidth; i++) {
414         enum key_group_selector use = NONE;
415         unsigned int fromSize = 0;
416         unsigned int toSize = 0;
417
418         if (i < from->numLevels[group])
419             fromSize = darray_item(from->symsMapNumEntries[group], i);
420
421         if (i < into->numLevels[group])
422             toSize = darray_item(into->symsMapNumEntries[group], i);
423
424         if (fromSize == 0 && toSize == 0) {
425             darray_item(into->symsMapIndex[group], i) = -1;
426             darray_item(into->symsMapNumEntries[group], i) = 0;
427             continue;
428         }
429
430         if (fromSize == 0)
431             use = TO;
432         else if (toSize == 0 || clobber)
433             use = FROM;
434         else
435             use = TO;
436
437         if (toSize && fromSize && report) {
438             INFO("Multiple symbols for group %d, level %d on key %s\n",
439                  group + 1, i + 1, longText(into->name));
440             ACTION("Using %s, ignoring %s\n",
441                    (use == FROM ? "from" : "to"),
442                    (use == FROM ? "to" : "from"));
443         }
444
445         if (use == FROM) {
446             memcpy(darray_mem(resultSyms, cur_idx),
447                    darray_mem(from->syms[group],
448                               darray_item(from->symsMapIndex[group], i)),
449                    darray_item(from->symsMapNumEntries[group],
450                                i) * sizeof(xkb_keysym_t));
451             darray_item(into->symsMapIndex[group], i) = cur_idx;
452             darray_item(into->symsMapNumEntries[group], i) =
453                 darray_item(from->symsMapNumEntries[group], i);
454         }
455         else {
456             memcpy(darray_mem(resultSyms, cur_idx),
457                    darray_mem(into->syms[group],
458                               darray_item(into->symsMapIndex[group], i)),
459                    darray_item(into->symsMapNumEntries[group],
460                                i) * sizeof(xkb_keysym_t));
461             darray_item(into->symsMapIndex[group], i) = cur_idx;
462         }
463         cur_idx += darray_item(into->symsMapNumEntries[group], i);
464     }
465
466 out:
467     if (!darray_same(resultActs, into->acts[group]))
468         darray_free(into->acts[group]);
469     if (!darray_same(resultActs, from->acts[group]))
470         darray_free(from->acts[group]);
471     into->numLevels[group] = resultWidth;
472     if (!darray_same(resultSyms, into->syms[group]))
473         darray_free(into->syms[group]);
474     into->syms[group] = resultSyms;
475     if (!darray_same(resultSyms, from->syms[group]))
476         darray_free(from->syms[group]);
477     darray_init(from->syms[group]);
478     darray_free(from->symsMapIndex[group]);
479     darray_free(from->symsMapNumEntries[group]);
480     into->acts[group] = resultActs;
481     darray_init(from->acts[group]);
482     if (!darray_empty(into->syms[group]))
483         into->symsDefined |= (1 << group);
484     from->symsDefined &= ~(1 << group);
485     into->actsDefined |= (1 << group);
486     from->actsDefined &= ~(1 << group);
487
488     return true;
489 }
490
491 static bool
492 MergeKeys(SymbolsInfo *info, struct xkb_keymap *keymap,
493           KeyInfo *into, KeyInfo *from)
494 {
495     int i;
496     unsigned collide = 0;
497     bool report;
498
499     if (from->defs.merge == MERGE_REPLACE) {
500         for (i = 0; i < XkbNumKbdGroups; i++) {
501             if (into->numLevels[i] != 0) {
502                 darray_free(into->syms[i]);
503                 darray_free(into->acts[i]);
504             }
505         }
506         *into = *from;
507         memset(from, 0, sizeof(KeyInfo));
508         return true;
509     }
510     report = ((warningLevel > 9) ||
511               ((into->defs.file_id == from->defs.file_id)
512                && (warningLevel > 0)));
513     for (i = 0; i < XkbNumKbdGroups; i++) {
514         if (from->numLevels[i] > 0) {
515             if (into->numLevels[i] == 0) {
516                 into->numLevels[i] = from->numLevels[i];
517                 into->syms[i] = from->syms[i];
518                 into->symsMapIndex[i] = from->symsMapIndex[i];
519                 into->symsMapNumEntries[i] = from->symsMapNumEntries[i];
520                 into->acts[i] = from->acts[i];
521                 into->symsDefined |= (1 << i);
522                 darray_init(from->syms[i]);
523                 darray_init(from->symsMapIndex[i]);
524                 darray_init(from->symsMapNumEntries[i]);
525                 darray_init(from->acts[i]);
526                 from->numLevels[i] = 0;
527                 from->symsDefined &= ~(1 << i);
528                 if (!darray_empty(into->syms[i]))
529                     into->defs.defined |= _Key_Syms;
530                 if (!darray_empty(into->acts[i]))
531                     into->defs.defined |= _Key_Acts;
532             }
533             else {
534                 if (report) {
535                     if (!darray_empty(into->syms[i]))
536                         collide |= _Key_Syms;
537                     if (!darray_empty(into->acts[i]))
538                         collide |= _Key_Acts;
539                 }
540                 MergeKeyGroups(info, into, from, (unsigned) i);
541             }
542         }
543         if (from->types[i] != XKB_ATOM_NONE) {
544             if ((into->types[i] != XKB_ATOM_NONE) && report &&
545                 (into->types[i] != from->types[i])) {
546                 xkb_atom_t use, ignore;
547                 collide |= _Key_Types;
548                 if (from->defs.merge != MERGE_AUGMENT) {
549                     use = from->types[i];
550                     ignore = into->types[i];
551                 }
552                 else {
553                     use = into->types[i];
554                     ignore = from->types[i];
555                 }
556                 WARN
557                     ("Multiple definitions for group %d type of key %s\n",
558                     i, longText(into->name));
559                 ACTION("Using %s, ignoring %s\n",
560                        xkb_atom_text(keymap->ctx, use),
561                        xkb_atom_text(keymap->ctx, ignore));
562             }
563             if ((from->defs.merge != MERGE_AUGMENT)
564                 || (into->types[i] == XKB_ATOM_NONE)) {
565                 into->types[i] = from->types[i];
566             }
567         }
568     }
569     if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide)) {
570         into->behavior = from->behavior;
571         into->defs.defined |= _Key_Behavior;
572     }
573     if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide)) {
574         into->vmodmap = from->vmodmap;
575         into->defs.defined |= _Key_VModMap;
576     }
577     if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide)) {
578         into->repeat = from->repeat;
579         into->defs.defined |= _Key_Repeat;
580     }
581     if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide)) {
582         into->dfltType = from->dfltType;
583         into->defs.defined |= _Key_Type_Dflt;
584     }
585     if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide)) {
586         into->groupInfo = from->groupInfo;
587         into->defs.defined |= _Key_GroupInfo;
588     }
589     if (collide) {
590         WARN("Symbol map for key %s redefined\n",
591              longText(into->name));
592         ACTION("Using %s definition for conflicting fields\n",
593                (from->defs.merge == MERGE_AUGMENT ? "first" : "last"));
594     }
595     return true;
596 }
597
598 static bool
599 AddKeySymbols(SymbolsInfo *info, KeyInfo *keyi, struct xkb_keymap *keymap)
600 {
601     unsigned long real_name;
602     KeyInfo *iter, *new;
603
604     darray_foreach(iter, info->keys)
605         if (iter->name == keyi->name)
606             return MergeKeys(info, keymap, iter, keyi);
607
608     if (FindKeyNameForAlias(keymap, keyi->name, &real_name))
609         darray_foreach(iter, info->keys)
610             if (iter->name == real_name)
611                 return MergeKeys(info, keymap, iter, keyi);
612
613     darray_resize0(info->keys, darray_size(info->keys) + 1);
614     new = &darray_item(info->keys, darray_size(info->keys) - 1);
615     return CopyKeyInfo(keyi, new, true);
616 }
617
618 static bool
619 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
620 {
621     ModMapEntry *mm;
622     bool clobber;
623
624     clobber = (new->defs.merge != MERGE_AUGMENT);
625     for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next) {
626         if (new->haveSymbol && mm->haveSymbol
627             && (new->u.keySym == mm->u.keySym)) {
628             unsigned use, ignore;
629             if (mm->modifier != new->modifier) {
630                 if (clobber) {
631                     use = new->modifier;
632                     ignore = mm->modifier;
633                 }
634                 else {
635                     use = mm->modifier;
636                     ignore = new->modifier;
637                 }
638                 ERROR
639                     ("%s added to symbol map for multiple modifiers\n",
640                     XkbcKeysymText(new->u.keySym));
641                 ACTION("Using %s, ignoring %s.\n",
642                        XkbcModIndexText(use),
643                        XkbcModIndexText(ignore));
644                 mm->modifier = use;
645             }
646             return true;
647         }
648         if ((!new->haveSymbol) && (!mm->haveSymbol) &&
649             (new->u.keyName == mm->u.keyName)) {
650             unsigned use, ignore;
651             if (mm->modifier != new->modifier) {
652                 if (clobber) {
653                     use = new->modifier;
654                     ignore = mm->modifier;
655                 }
656                 else {
657                     use = mm->modifier;
658                     ignore = new->modifier;
659                 }
660                 ERROR("Key %s added to map for multiple modifiers\n",
661                       longText(new->u.keyName));
662                 ACTION("Using %s, ignoring %s.\n",
663                        XkbcModIndexText(use),
664                        XkbcModIndexText(ignore));
665                 mm->modifier = use;
666             }
667             return true;
668         }
669     }
670     mm = uTypedAlloc(ModMapEntry);
671     if (mm == NULL) {
672         WSGO("Could not allocate modifier map entry\n");
673         ACTION("Modifier map for %s will be incomplete\n",
674                XkbcModIndexText(new->modifier));
675         return false;
676     }
677     *mm = *new;
678     mm->defs.next = &info->modMap->defs;
679     info->modMap = mm;
680     return true;
681 }
682
683 /***====================================================================***/
684
685 static void
686 MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
687                      enum merge_mode merge, struct xkb_keymap *keymap)
688 {
689     unsigned int i;
690     KeyInfo *keyi;
691
692     if (from->errorCount > 0) {
693         into->errorCount += from->errorCount;
694         return;
695     }
696     if (into->name == NULL) {
697         into->name = from->name;
698         from->name = NULL;
699     }
700     for (i = 0; i < XkbNumKbdGroups; i++) {
701         if (from->groupNames[i] != XKB_ATOM_NONE) {
702             if ((merge != MERGE_AUGMENT) ||
703                 (into->groupNames[i] == XKB_ATOM_NONE))
704                 into->groupNames[i] = from->groupNames[i];
705         }
706     }
707
708     darray_foreach(keyi, from->keys) {
709         if (merge != MERGE_DEFAULT)
710             keyi->defs.merge = merge;
711
712         if (!AddKeySymbols(into, keyi, keymap))
713             into->errorCount++;
714     }
715
716     if (from->modMap != NULL) {
717         ModMapEntry *mm, *next;
718         for (mm = from->modMap; mm != NULL; mm = next) {
719             if (merge != MERGE_DEFAULT)
720                 mm->defs.merge = merge;
721             if (!AddModMapEntry(into, mm))
722                 into->errorCount++;
723             next = (ModMapEntry *) mm->defs.next;
724             free(mm);
725         }
726         from->modMap = NULL;
727     }
728     if (!MergeAliases(&into->aliases, &from->aliases, merge))
729         into->errorCount++;
730 }
731
732 static void
733 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
734                   enum merge_mode merge,
735                   SymbolsInfo *info);
736
737 static bool
738 HandleIncludeSymbols(IncludeStmt *stmt, struct xkb_keymap *keymap,
739                      SymbolsInfo *info)
740 {
741     enum merge_mode newMerge;
742     XkbFile *rtrn;
743     SymbolsInfo included;
744     bool haveSelf;
745
746     haveSelf = false;
747     if ((stmt->file == NULL) && (stmt->map == NULL)) {
748         haveSelf = true;
749         included = *info;
750         memset(info, 0, sizeof(SymbolsInfo));
751     }
752     else if (ProcessIncludeFile(keymap->ctx, stmt, FILE_TYPE_SYMBOLS, &rtrn,
753                                 &newMerge)) {
754         InitSymbolsInfo(&included, keymap, rtrn->id);
755         included.merge = included.dflt.defs.merge = MERGE_OVERRIDE;
756         if (stmt->modifier) {
757             included.explicit_group = atoi(stmt->modifier) - 1;
758         }
759         else {
760             included.explicit_group = info->explicit_group;
761         }
762         HandleSymbolsFile(rtrn, keymap, MERGE_OVERRIDE, &included);
763         if (stmt->stmt != NULL) {
764             free(included.name);
765             included.name = stmt->stmt;
766             stmt->stmt = NULL;
767         }
768         FreeXKBFile(rtrn);
769     }
770     else {
771         info->errorCount += 10;
772         return false;
773     }
774     if ((stmt->next != NULL) && (included.errorCount < 1)) {
775         IncludeStmt *next;
776         unsigned op;
777         SymbolsInfo next_incl;
778
779         for (next = stmt->next; next != NULL; next = next->next) {
780             if ((next->file == NULL) && (next->map == NULL)) {
781                 haveSelf = true;
782                 MergeIncludedSymbols(&included, info, next->merge, keymap);
783                 FreeSymbolsInfo(info);
784             }
785             else if (ProcessIncludeFile(keymap->ctx, next, FILE_TYPE_SYMBOLS,
786                                         &rtrn, &op)) {
787                 InitSymbolsInfo(&next_incl, keymap, rtrn->id);
788                 next_incl.merge = next_incl.dflt.defs.merge = MERGE_OVERRIDE;
789                 if (next->modifier) {
790                     next_incl.explicit_group = atoi(next->modifier) - 1;
791                 }
792                 else {
793                     next_incl.explicit_group = info->explicit_group;
794                 }
795                 HandleSymbolsFile(rtrn, keymap, MERGE_OVERRIDE, &next_incl);
796                 MergeIncludedSymbols(&included, &next_incl, op, keymap);
797                 FreeSymbolsInfo(&next_incl);
798                 FreeXKBFile(rtrn);
799             }
800             else {
801                 info->errorCount += 10;
802                 FreeSymbolsInfo(&included);
803                 return false;
804             }
805         }
806     }
807     else if (stmt->next) {
808         info->errorCount += included.errorCount;
809     }
810     if (haveSelf)
811         *info = included;
812     else {
813         MergeIncludedSymbols(info, &included, newMerge, keymap);
814         FreeSymbolsInfo(&included);
815     }
816     return (info->errorCount == 0);
817 }
818
819 #define SYMBOLS 1
820 #define ACTIONS 2
821
822 static bool
823 GetGroupIndex(KeyInfo *keyi, struct xkb_keymap *keymap,
824               ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
825 {
826     const char *name;
827     ExprResult tmp;
828
829     if (what == SYMBOLS)
830         name = "symbols";
831     else
832         name = "actions";
833
834     if (arrayNdx == NULL) {
835         int i;
836         unsigned defined;
837         if (what == SYMBOLS)
838             defined = keyi->symsDefined;
839         else
840             defined = keyi->actsDefined;
841
842         for (i = 0; i < XkbNumKbdGroups; i++) {
843             if ((defined & (1 << i)) == 0) {
844                 *ndx_rtrn = i;
845                 return true;
846             }
847         }
848         ERROR("Too many groups of %s for key %s (max %d)\n", name,
849               longText(keyi->name), XkbNumKbdGroups + 1);
850         ACTION("Ignoring %s defined for extra groups\n", name);
851         return false;
852     }
853     if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp)) {
854         ERROR("Illegal group index for %s of key %s\n", name,
855               longText(keyi->name));
856         ACTION("Definition with non-integer array index ignored\n");
857         return false;
858     }
859     *ndx_rtrn = tmp.uval - 1;
860     return true;
861 }
862
863 static bool
864 AddSymbolsToKey(KeyInfo *keyi, struct xkb_keymap *keymap,
865                 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
866 {
867     unsigned ndx, nSyms, nLevels;
868     unsigned int i;
869     long j;
870
871     if (!GetGroupIndex(keyi, keymap, arrayNdx, SYMBOLS, &ndx))
872         return false;
873     if (value == NULL) {
874         keyi->symsDefined |= (1 << ndx);
875         return true;
876     }
877     if (value->op != ExprKeysymList) {
878         ERROR("Expected a list of symbols, found %s\n", exprOpText(value->op));
879         ACTION("Ignoring symbols for group %d of %s\n", ndx + 1,
880                longText(keyi->name));
881         return false;
882     }
883     if (!darray_empty(keyi->syms[ndx])) {
884         ERROR("Symbols for key %s, group %d already defined\n",
885                longText(keyi->name), ndx + 1);
886         ACTION("Ignoring duplicate definition\n");
887         return false;
888     }
889     nSyms = darray_size(value->value.list.syms);
890     nLevels = darray_size(value->value.list.symsMapIndex);
891     if ((keyi->numLevels[ndx] < nSyms || darray_empty(keyi->syms[ndx])) &&
892         (!ResizeKeyGroup(keyi, ndx, nLevels, nSyms, false))) {
893         WSGO("Could not resize group %d of key %s to contain %d levels\n",
894              ndx + 1, longText(keyi->name), nSyms);
895         ACTION("Symbols lost\n");
896         return false;
897     }
898     keyi->symsDefined |= (1 << ndx);
899     for (i = 0; i < nLevels; i++) {
900         darray_item(keyi->symsMapIndex[ndx], i) =
901             darray_item(value->value.list.symsMapIndex, i);
902         darray_item(keyi->symsMapNumEntries[ndx], i) =
903             darray_item(value->value.list.symsNumEntries, i);
904
905         for (j = 0; j < darray_item(keyi->symsMapNumEntries[ndx], i); j++) {
906             /* FIXME: What's abort() doing here? */
907             if (darray_item(keyi->symsMapIndex[ndx], i) + j >= nSyms)
908                 abort();
909             if (!LookupKeysym(darray_item(value->value.list.syms,
910                                           darray_item(value->value.list.symsMapIndex,
911                                                       i) + j),
912                               &darray_item(keyi->syms[ndx],
913                                            darray_item(keyi->symsMapIndex[ndx],
914                                                        i) + j))) {
915                 WARN(
916                     "Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
917                     darray_item(value->value.list.syms, i),
918                     longText(keyi->name),
919                     ndx + 1,
920                     xkb_atom_text(keymap->ctx, info->groupNames[ndx]), nSyms);
921                 while (--j >= 0)
922                     darray_item(keyi->syms[ndx],
923                                 darray_item(keyi->symsMapIndex[ndx],
924                                             i) + j) = XKB_KEY_NoSymbol;
925                 darray_item(keyi->symsMapIndex[ndx], i) = -1;
926                 darray_item(keyi->symsMapNumEntries[ndx], i) = 0;
927                 break;
928             }
929             if (darray_item(keyi->symsMapNumEntries[ndx], i) == 1 &&
930                 darray_item(keyi->syms[ndx],
931                             darray_item(keyi->symsMapIndex[ndx],
932                                         i) + j) == XKB_KEY_NoSymbol) {
933                 darray_item(keyi->symsMapIndex[ndx], i) = -1;
934                 darray_item(keyi->symsMapNumEntries[ndx], i) = 0;
935             }
936         }
937     }
938     for (j = keyi->numLevels[ndx] - 1;
939          j >= 0 && darray_item(keyi->symsMapNumEntries[ndx], j) == 0; j--)
940         keyi->numLevels[ndx]--;
941     return true;
942 }
943
944 static bool
945 AddActionsToKey(KeyInfo *keyi, struct xkb_keymap *keymap, ExprDef *arrayNdx,
946                 ExprDef *value, SymbolsInfo *info)
947 {
948     unsigned int i;
949     unsigned ndx, nActs;
950     ExprDef *act;
951     struct xkb_any_action *toAct;
952
953     if (!GetGroupIndex(keyi, keymap, arrayNdx, ACTIONS, &ndx))
954         return false;
955
956     if (value == NULL) {
957         keyi->actsDefined |= (1 << ndx);
958         return true;
959     }
960     if (value->op != ExprActionList) {
961         WSGO("Bad expression type (%d) for action list value\n", value->op);
962         ACTION("Ignoring actions for group %d of %s\n", ndx,
963                longText(keyi->name));
964         return false;
965     }
966     if (!darray_empty(keyi->acts[ndx])) {
967         WSGO("Actions for key %s, group %d already defined\n",
968              longText(keyi->name), ndx);
969         return false;
970     }
971     for (nActs = 0, act = value->value.child; act != NULL; nActs++) {
972         act = (ExprDef *) act->common.next;
973     }
974     if (nActs < 1) {
975         WSGO("Action list but not actions in AddActionsToKey\n");
976         return false;
977     }
978     if ((keyi->numLevels[ndx] < nActs || darray_empty(keyi->acts[ndx])) &&
979         !ResizeKeyGroup(keyi, ndx, nActs, nActs, true)) {
980         WSGO("Could not resize group %d of key %s\n", ndx,
981               longText(keyi->name));
982         ACTION("Actions lost\n");
983         return false;
984     }
985     keyi->actsDefined |= (1 << ndx);
986
987     toAct = (struct xkb_any_action *) darray_mem(keyi->acts[ndx], 0);
988     act = value->value.child;
989     for (i = 0; i < nActs; i++, toAct++) {
990         if (!HandleActionDef(act, keymap, toAct, info->action)) {
991             ERROR("Illegal action definition for %s\n",
992                   longText(keyi->name));
993             ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
994         }
995         act = (ExprDef *) act->common.next;
996     }
997     return true;
998 }
999
1000 static const LookupEntry lockingEntries[] = {
1001     { "true", XkbKB_Lock },
1002     { "yes", XkbKB_Lock },
1003     { "on", XkbKB_Lock },
1004     { "false", XkbKB_Default },
1005     { "no", XkbKB_Default },
1006     { "off", XkbKB_Default },
1007     { "permanent", XkbKB_Lock | XkbKB_Permanent },
1008     { NULL, 0 }
1009 };
1010
1011 static const LookupEntry repeatEntries[] = {
1012     { "true", RepeatYes },
1013     { "yes", RepeatYes },
1014     { "on", RepeatYes },
1015     { "false", RepeatNo },
1016     { "no", RepeatNo },
1017     { "off", RepeatNo },
1018     { "default", RepeatUndefined },
1019     { NULL, 0 }
1020 };
1021
1022 static bool
1023 SetSymbolsField(KeyInfo *keyi, struct xkb_keymap *keymap, char *field,
1024                 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
1025 {
1026     bool ok = true;
1027     ExprResult tmp;
1028
1029     if (strcasecmp(field, "type") == 0) {
1030         ExprResult ndx;
1031         if ((!ExprResolveString(keymap->ctx, value, &tmp))
1032             && (warningLevel > 0)) {
1033             WARN("The type field of a key symbol map must be a string\n");
1034             ACTION("Ignoring illegal type definition\n");
1035         }
1036         if (arrayNdx == NULL) {
1037             keyi->dfltType = xkb_atom_intern(keymap->ctx, tmp.str);
1038             keyi->defs.defined |= _Key_Type_Dflt;
1039         }
1040         else if (!ExprResolveGroup(keymap->ctx, arrayNdx, &ndx)) {
1041             ERROR("Illegal group index for type of key %s\n",
1042                   longText(keyi->name));
1043             ACTION("Definition with non-integer array index ignored\n");
1044             free(tmp.str);
1045             return false;
1046         }
1047         else {
1048             keyi->types[ndx.uval - 1] = xkb_atom_intern(keymap->ctx, tmp.str);
1049             keyi->typesDefined |= (1 << (ndx.uval - 1));
1050         }
1051         free(tmp.str);
1052     }
1053     else if (strcasecmp(field, "symbols") == 0)
1054         return AddSymbolsToKey(keyi, keymap, arrayNdx, value, info);
1055     else if (strcasecmp(field, "actions") == 0)
1056         return AddActionsToKey(keyi, keymap, arrayNdx, value, info);
1057     else if ((strcasecmp(field, "vmods") == 0) ||
1058              (strcasecmp(field, "virtualmods") == 0) ||
1059              (strcasecmp(field, "virtualmodifiers") == 0)) {
1060         ok = ExprResolveVModMask(value, &tmp, keymap);
1061         if (ok) {
1062             keyi->vmodmap = (tmp.uval >> 8);
1063             keyi->defs.defined |= _Key_VModMap;
1064         }
1065         else {
1066             ERROR("Expected a virtual modifier mask, found %s\n",
1067                   exprOpText(value->op));
1068             ACTION("Ignoring virtual modifiers definition for key %s\n",
1069                    longText(keyi->name));
1070         }
1071     }
1072     else if ((strcasecmp(field, "locking") == 0) ||
1073              (strcasecmp(field, "lock") == 0) ||
1074              (strcasecmp(field, "locks") == 0)) {
1075         ok = ExprResolveEnum(keymap->ctx, value, &tmp, lockingEntries);
1076         if (ok)
1077             keyi->behavior.type = tmp.uval;
1078         keyi->defs.defined |= _Key_Behavior;
1079     }
1080     else if ((strcasecmp(field, "radiogroup") == 0) ||
1081              (strcasecmp(field, "permanentradiogroup") == 0) ||
1082              (strcasecmp(field, "allownone") == 0)) {
1083         ERROR("Radio groups not supported\n");
1084         ACTION("Ignoring radio group specification for key %s\n",
1085                longText(keyi->name));
1086         return false;
1087     }
1088     else if (uStrCasePrefix("overlay", field) ||
1089              uStrCasePrefix("permanentoverlay", field)) {
1090         ERROR("Overlays not supported\n");
1091         ACTION("Ignoring overlay specification for key %s\n",
1092                longText(keyi->name));
1093     }
1094     else if ((strcasecmp(field, "repeating") == 0) ||
1095              (strcasecmp(field, "repeats") == 0) ||
1096              (strcasecmp(field, "repeat") == 0)) {
1097         ok = ExprResolveEnum(keymap->ctx, value, &tmp, repeatEntries);
1098         if (!ok) {
1099             ERROR("Illegal repeat setting for %s\n",
1100                   longText(keyi->name));
1101             ACTION("Non-boolean repeat setting ignored\n");
1102             return false;
1103         }
1104         keyi->repeat = tmp.uval;
1105         keyi->defs.defined |= _Key_Repeat;
1106     }
1107     else if ((strcasecmp(field, "groupswrap") == 0) ||
1108              (strcasecmp(field, "wrapgroups") == 0)) {
1109         ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1110         if (!ok) {
1111             ERROR("Illegal groupsWrap setting for %s\n",
1112                   longText(keyi->name));
1113             ACTION("Non-boolean value ignored\n");
1114             return false;
1115         }
1116         if (tmp.uval)
1117             keyi->groupInfo = XkbWrapIntoRange;
1118         else
1119             keyi->groupInfo = XkbClampIntoRange;
1120         keyi->defs.defined |= _Key_GroupInfo;
1121     }
1122     else if ((strcasecmp(field, "groupsclamp") == 0) ||
1123              (strcasecmp(field, "clampgroups") == 0)) {
1124         ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1125         if (!ok) {
1126             ERROR("Illegal groupsClamp setting for %s\n",
1127                   longText(keyi->name));
1128             ACTION("Non-boolean value ignored\n");
1129             return false;
1130         }
1131         if (tmp.uval)
1132             keyi->groupInfo = XkbClampIntoRange;
1133         else
1134             keyi->groupInfo = XkbWrapIntoRange;
1135         keyi->defs.defined |= _Key_GroupInfo;
1136     }
1137     else if ((strcasecmp(field, "groupsredirect") == 0) ||
1138              (strcasecmp(field, "redirectgroups") == 0)) {
1139         if (!ExprResolveGroup(keymap->ctx, value, &tmp)) {
1140             ERROR("Illegal group index for redirect of key %s\n",
1141                   longText(keyi->name));
1142             ACTION("Definition with non-integer group ignored\n");
1143             return false;
1144         }
1145         keyi->groupInfo =
1146             XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1147         keyi->defs.defined |= _Key_GroupInfo;
1148     }
1149     else {
1150         ERROR("Unknown field %s in a symbol interpretation\n", field);
1151         ACTION("Definition ignored\n");
1152         ok = false;
1153     }
1154     return ok;
1155 }
1156
1157 static int
1158 SetGroupName(SymbolsInfo *info, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1159              ExprDef *value)
1160 {
1161     ExprResult tmp, name;
1162
1163     if ((arrayNdx == NULL) && (warningLevel > 0)) {
1164         WARN("You must specify an index when specifying a group name\n");
1165         ACTION("Group name definition without array subscript ignored\n");
1166         return false;
1167     }
1168     if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp)) {
1169         ERROR("Illegal index in group name definition\n");
1170         ACTION("Definition with non-integer array index ignored\n");
1171         return false;
1172     }
1173     if (!ExprResolveString(keymap->ctx, value, &name)) {
1174         ERROR("Group name must be a string\n");
1175         ACTION("Illegal name for group %d ignored\n", tmp.uval);
1176         return false;
1177     }
1178     info->groupNames[tmp.uval - 1 + info->explicit_group] =
1179         xkb_atom_intern(keymap->ctx, name.str);
1180     free(name.str);
1181
1182     return true;
1183 }
1184
1185 static int
1186 HandleSymbolsVar(VarDef *stmt, struct xkb_keymap *keymap, SymbolsInfo *info)
1187 {
1188     ExprResult elem, field;
1189     ExprDef *arrayNdx;
1190     bool ret;
1191
1192     if (ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx) == 0)
1193         return 0;               /* internal error, already reported */
1194     if (elem.str && (strcasecmp(elem.str, "key") == 0)) {
1195         ret = SetSymbolsField(&info->dflt, keymap, field.str, arrayNdx,
1196                               stmt->value, info);
1197     }
1198     else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) ||
1199                                     (strcasecmp(field.str, "groupname") ==
1200                                      0))) {
1201         ret = SetGroupName(info, keymap, arrayNdx, stmt->value);
1202     }
1203     else if ((elem.str == NULL)
1204              && ((strcasecmp(field.str, "groupswrap") == 0) ||
1205                  (strcasecmp(field.str, "wrapgroups") == 0))) {
1206         ERROR("Global \"groupswrap\" not supported\n");
1207         ACTION("Ignored\n");
1208         ret = true;
1209     }
1210     else if ((elem.str == NULL)
1211              && ((strcasecmp(field.str, "groupsclamp") == 0) ||
1212                  (strcasecmp(field.str, "clampgroups") == 0))) {
1213         ERROR("Global \"groupsclamp\" not supported\n");
1214         ACTION("Ignored\n");
1215         ret = true;
1216     }
1217     else if ((elem.str == NULL)
1218              && ((strcasecmp(field.str, "groupsredirect") == 0) ||
1219                  (strcasecmp(field.str, "redirectgroups") == 0))) {
1220         ERROR("Global \"groupsredirect\" not supported\n");
1221         ACTION("Ignored\n");
1222         ret = true;
1223     }
1224     else if ((elem.str == NULL) &&
1225              (strcasecmp(field.str, "allownone") == 0)) {
1226         ERROR("Radio groups not supported\n");
1227         ACTION("Ignoring \"allownone\" specification\n");
1228         ret = true;
1229     }
1230     else {
1231         ret = SetActionField(keymap, elem.str, field.str, arrayNdx,
1232                              stmt->value, &info->action);
1233     }
1234
1235     free(elem.str);
1236     free(field.str);
1237     return ret;
1238 }
1239
1240 static bool
1241 HandleSymbolsBody(VarDef *def, struct xkb_keymap *keymap, KeyInfo *keyi,
1242                   SymbolsInfo *info)
1243 {
1244     bool ok = true;
1245     ExprResult tmp, field;
1246     ExprDef *arrayNdx;
1247
1248     for (; def != NULL; def = (VarDef *) def->common.next) {
1249         if ((def->name) && (def->name->type == ExprFieldRef)) {
1250             ok = HandleSymbolsVar(def, keymap, info);
1251             continue;
1252         }
1253         else {
1254             if (def->name == NULL) {
1255                 if ((def->value == NULL)
1256                     || (def->value->op == ExprKeysymList))
1257                     field.str = strdup("symbols");
1258                 else
1259                     field.str = strdup("actions");
1260                 arrayNdx = NULL;
1261             }
1262             else {
1263                 ok = ExprResolveLhs(keymap, def->name, &tmp, &field,
1264                                     &arrayNdx);
1265             }
1266             if (ok)
1267                 ok = SetSymbolsField(keyi, keymap, field.str, arrayNdx,
1268                                      def->value, info);
1269             free(field.str);
1270         }
1271     }
1272     return ok;
1273 }
1274
1275 static bool
1276 SetExplicitGroup(SymbolsInfo *info, KeyInfo *keyi)
1277 {
1278     unsigned group = info->explicit_group;
1279
1280     if (group == 0)
1281         return true;
1282
1283     if ((keyi->typesDefined | keyi->symsDefined | keyi->actsDefined) & ~1) {
1284         int i;
1285         WARN("For the map %s an explicit group specified\n", info->name);
1286         WARN("but key %s has more than one group defined\n",
1287              longText(keyi->name));
1288         ACTION("All groups except first one will be ignored\n");
1289         for (i = 1; i < XkbNumKbdGroups; i++) {
1290             keyi->numLevels[i] = 0;
1291             darray_free(keyi->syms[i]);
1292             darray_free(keyi->acts[i]);
1293             keyi->types[i] = 0;
1294         }
1295     }
1296     keyi->typesDefined = keyi->symsDefined = keyi->actsDefined = 1 << group;
1297
1298     keyi->numLevels[group] = keyi->numLevels[0];
1299     keyi->numLevels[0] = 0;
1300     keyi->syms[group] = keyi->syms[0];
1301     darray_init(keyi->syms[0]);
1302     keyi->symsMapIndex[group] = keyi->symsMapIndex[0];
1303     darray_init(keyi->symsMapIndex[0]);
1304     keyi->symsMapNumEntries[group] = keyi->symsMapNumEntries[0];
1305     darray_init(keyi->symsMapNumEntries[0]);
1306     keyi->acts[group] = keyi->acts[0];
1307     darray_init(keyi->acts[0]);
1308     keyi->types[group] = keyi->types[0];
1309     keyi->types[0] = 0;
1310     return true;
1311 }
1312
1313 static int
1314 HandleSymbolsDef(SymbolsDef *stmt, struct xkb_keymap *keymap,
1315                  SymbolsInfo *info)
1316 {
1317     KeyInfo keyi;
1318
1319     InitKeyInfo(&keyi, info->file_id);
1320     CopyKeyInfo(&info->dflt, &keyi, false);
1321     keyi.defs.merge = stmt->merge;
1322     keyi.name = KeyNameToLong(stmt->keyName);
1323     if (!HandleSymbolsBody((VarDef *) stmt->symbols, keymap, &keyi, info)) {
1324         info->errorCount++;
1325         return false;
1326     }
1327
1328     if (!SetExplicitGroup(info, &keyi)) {
1329         info->errorCount++;
1330         return false;
1331     }
1332
1333     if (!AddKeySymbols(info, &keyi, keymap)) {
1334         info->errorCount++;
1335         return false;
1336     }
1337     return true;
1338 }
1339
1340 static bool
1341 HandleModMapDef(ModMapDef *def, struct xkb_keymap *keymap, SymbolsInfo *info)
1342 {
1343     ExprDef *key;
1344     ModMapEntry tmp;
1345     ExprResult rtrn;
1346     bool ok;
1347
1348     if (!LookupModIndex(keymap->ctx, NULL, def->modifier, TypeInt, &rtrn)) {
1349         ERROR("Illegal modifier map definition\n");
1350         ACTION("Ignoring map for non-modifier \"%s\"\n",
1351                xkb_atom_text(keymap->ctx, def->modifier));
1352         return false;
1353     }
1354     ok = true;
1355     tmp.modifier = rtrn.uval;
1356     for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) {
1357         if ((key->op == ExprValue) && (key->type == TypeKeyName)) {
1358             tmp.haveSymbol = false;
1359             tmp.u.keyName = KeyNameToLong(key->value.keyName);
1360         }
1361         else if (ExprResolveKeySym(keymap->ctx, key, &rtrn)) {
1362             tmp.haveSymbol = true;
1363             tmp.u.keySym = rtrn.uval;
1364         }
1365         else {
1366             ERROR("Modmap entries may contain only key names or keysyms\n");
1367             ACTION("Illegal definition for %s modifier ignored\n",
1368                    XkbcModIndexText(tmp.modifier));
1369             continue;
1370         }
1371
1372         ok = AddModMapEntry(info, &tmp) && ok;
1373     }
1374     return ok;
1375 }
1376
1377 static void
1378 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
1379                   enum merge_mode merge, SymbolsInfo *info)
1380 {
1381     ParseCommon *stmt;
1382
1383     free(info->name);
1384     info->name = uDupString(file->name);
1385     stmt = file->defs;
1386     while (stmt)
1387     {
1388         switch (stmt->stmtType) {
1389         case StmtInclude:
1390             if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info))
1391                 info->errorCount++;
1392             break;
1393         case StmtSymbolsDef:
1394             if (!HandleSymbolsDef((SymbolsDef *) stmt, keymap, info))
1395                 info->errorCount++;
1396             break;
1397         case StmtVarDef:
1398             if (!HandleSymbolsVar((VarDef *) stmt, keymap, info))
1399                 info->errorCount++;
1400             break;
1401         case StmtVModDef:
1402             if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
1403                 info->errorCount++;
1404             break;
1405         case StmtInterpDef:
1406             ERROR("Interpretation files may not include other types\n");
1407             ACTION("Ignoring definition of symbol interpretation\n");
1408             info->errorCount++;
1409             break;
1410         case StmtKeycodeDef:
1411             ERROR("Interpretation files may not include other types\n");
1412             ACTION("Ignoring definition of key name\n");
1413             info->errorCount++;
1414             break;
1415         case StmtModMapDef:
1416             if (!HandleModMapDef((ModMapDef *) stmt, keymap, info))
1417                 info->errorCount++;
1418             break;
1419         default:
1420             WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1421                  stmt->stmtType);
1422             break;
1423         }
1424         stmt = stmt->next;
1425         if (info->errorCount > 10) {
1426 #ifdef NOISY
1427             ERROR("Too many errors\n");
1428 #endif
1429             ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1430             break;
1431         }
1432     }
1433 }
1434
1435 /**
1436  * Given a keysym @sym, find the keycode which generates it
1437  * (returned in @kc_rtrn). This is used for example in a modifier
1438  * map definition, such as:
1439  *      modifier_map Lock           { Caps_Lock };
1440  * where we want to add the Lock modifier to the modmap of the key
1441  * which matches the keysym Caps_Lock.
1442  * Since there can be many keys which generates the keysym, the key
1443  * is chosen first by lowest group in which the keysym appears, than
1444  * by lowest level and than by lowest key code.
1445  */
1446 static bool
1447 FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
1448                  xkb_keycode_t *kc_rtrn)
1449 {
1450     xkb_keycode_t kc;
1451     unsigned int group, level, min_group = UINT_MAX, min_level = UINT_MAX;
1452
1453     for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
1454         for (group = 0; group < XkbKeyNumGroups(keymap, kc); group++) {
1455             for (level = 0; level < XkbKeyGroupWidth(keymap, kc, group);
1456                  level++) {
1457                 if (XkbKeyNumSyms(keymap, kc, group, level) != 1 ||
1458                     (XkbKeySymEntry(keymap, kc, group, level))[0] != sym)
1459                     continue;
1460
1461                 /*
1462                  * If the keysym was found in a group or level > 0, we must
1463                  * keep looking since we might find a key in which the keysym
1464                  * is in a lower group or level.
1465                  */
1466                 if (group < min_group ||
1467                     (group == min_group && level < min_level)) {
1468                     *kc_rtrn = kc;
1469                     if (group == 0 && level == 0) {
1470                         return true;
1471                     }
1472                     else {
1473                         min_group = group;
1474                         min_level = level;
1475                     }
1476                 }
1477             }
1478         }
1479     }
1480
1481     return min_group != UINT_MAX;
1482 }
1483
1484 /**
1485  * Find the given name in the keymap->map->types and return its index.
1486  *
1487  * @param atom The atom to search for.
1488  * @param type_rtrn Set to the index of the name if found.
1489  *
1490  * @return true if found, false otherwise.
1491  */
1492 static bool
1493 FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn)
1494 {
1495     unsigned n = 0;
1496     const char *name = xkb_atom_text(keymap->ctx, atom);
1497     struct xkb_key_type *type;
1498
1499     if (keymap) {
1500         darray_foreach(type, keymap->types) {
1501             if (strcmp(type->name, name) == 0) {
1502                 *type_rtrn = n;
1503                 return true;
1504             }
1505             n++;
1506         }
1507     }
1508     return false;
1509 }
1510
1511 /**
1512  * Assign a type to the given sym and return the Atom for the type assigned.
1513  *
1514  * Simple recipe:
1515  * - ONE_LEVEL for width 0/1
1516  * - ALPHABETIC for 2 shift levels, with lower/upercase
1517  * - KEYPAD for keypad keys.
1518  * - TWO_LEVEL for other 2 shift level keys.
1519  * and the same for four level keys.
1520  *
1521  * @param width Number of sysms in syms.
1522  * @param syms The keysyms for the given key (must be size width).
1523  * @param typeNameRtrn Set to the Atom of the type name.
1524  *
1525  * @returns true if a type could be found, false otherwise.
1526  *
1527  * FIXME: I need to take the KeyInfo so I can look at symsMapIndex and
1528  *        all that fun stuff rather than just assuming there's always one
1529  *        symbol per level.
1530  */
1531 static bool
1532 FindAutomaticType(struct xkb_keymap *keymap, int width,
1533                   const xkb_keysym_t *syms, xkb_atom_t *typeNameRtrn,
1534                   bool *autoType)
1535 {
1536     *autoType = false;
1537     if ((width == 1) || (width == 0)) {
1538         *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
1539         *autoType = true;
1540     }
1541     else if (width == 2) {
1542         if (syms && xkb_keysym_is_lower(syms[0]) &&
1543             xkb_keysym_is_upper(syms[1])) {
1544             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
1545         }
1546         else if (syms && (xkb_keysym_is_keypad(syms[0]) ||
1547                           xkb_keysym_is_keypad(syms[1]))) {
1548             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "KEYPAD");
1549             *autoType = true;
1550         }
1551         else {
1552             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
1553             *autoType = true;
1554         }
1555     }
1556     else if (width <= 4) {
1557         if (syms && xkb_keysym_is_lower(syms[0]) &&
1558             xkb_keysym_is_upper(syms[1]))
1559             if (xkb_keysym_is_lower(syms[2]) && xkb_keysym_is_upper(syms[3]))
1560                 *typeNameRtrn =
1561                     xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_ALPHABETIC");
1562             else
1563                 *typeNameRtrn = xkb_atom_intern(keymap->ctx,
1564                                                 "FOUR_LEVEL_SEMIALPHABETIC");
1565
1566         else if (syms && (xkb_keysym_is_keypad(syms[0]) ||
1567                           xkb_keysym_is_keypad(syms[1])))
1568             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_KEYPAD");
1569         else
1570             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL");
1571         /* XXX: why not set autoType here? */
1572     }
1573     return ((width >= 0) && (width <= 4));
1574 }
1575
1576 /**
1577  * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1578  * groups, and reduce to one group if all groups are identical anyway.
1579  */
1580 static void
1581 PrepareKeyDef(KeyInfo *keyi)
1582 {
1583     int i, j, width, defined, lastGroup;
1584     bool identical;
1585
1586     defined = keyi->symsDefined | keyi->actsDefined | keyi->typesDefined;
1587     /* get highest group number */
1588     for (i = XkbNumKbdGroups - 1; i >= 0; i--) {
1589         if (defined & (1 << i))
1590             break;
1591     }
1592     lastGroup = i;
1593
1594     if (lastGroup == 0)
1595         return;
1596
1597     /* If there are empty groups between non-empty ones fill them with data */
1598     /* from the first group. */
1599     /* We can make a wrong assumption here. But leaving gaps is worse. */
1600     for (i = lastGroup; i > 0; i--) {
1601         if (defined & (1 << i))
1602             continue;
1603         width = keyi->numLevels[0];
1604         if (keyi->typesDefined & 1) {
1605             for (j = 0; j < width; j++) {
1606                 keyi->types[i] = keyi->types[0];
1607             }
1608             keyi->typesDefined |= 1 << i;
1609         }
1610         if ((keyi->actsDefined & 1) && !darray_empty(keyi->acts[0])) {
1611             darray_copy(keyi->acts[i], keyi->acts[0]);
1612             keyi->actsDefined |= 1 << i;
1613         }
1614         if ((keyi->symsDefined & 1) && !darray_empty(keyi->syms[0])) {
1615             darray_copy(keyi->syms[i], keyi->syms[0]);
1616             darray_copy(keyi->symsMapIndex[i], keyi->symsMapIndex[0]);
1617             darray_copy(keyi->symsMapNumEntries[i],
1618                         keyi->symsMapNumEntries[0]);
1619             keyi->symsDefined |= 1 << i;
1620         }
1621         if (defined & 1) {
1622             keyi->numLevels[i] = keyi->numLevels[0];
1623         }
1624     }
1625     /* If all groups are completely identical remove them all */
1626     /* exept the first one. */
1627     identical = true;
1628     for (i = lastGroup; i > 0; i--) {
1629         if ((keyi->numLevels[i] != keyi->numLevels[0]) ||
1630             (keyi->types[i] != keyi->types[0])) {
1631             identical = false;
1632             break;
1633         }
1634         if (!darray_same(keyi->syms[i], keyi->syms[0]) &&
1635             (darray_empty(keyi->syms[i]) || darray_empty(keyi->syms[0]) ||
1636              darray_size(keyi->syms[i]) != darray_size(keyi->syms[0]) ||
1637              memcmp(darray_mem(keyi->syms[i], 0),
1638                     darray_mem(keyi->syms[0], 0),
1639                    sizeof(xkb_keysym_t) * darray_size(keyi->syms[0])))) {
1640             identical = false;
1641             break;
1642         }
1643         if (!darray_same(keyi->symsMapIndex[i], keyi->symsMapIndex[0]) &&
1644             (darray_empty(keyi->symsMapIndex[i]) ||
1645              darray_empty(keyi->symsMapIndex[0]) ||
1646              memcmp(darray_mem(keyi->symsMapIndex[i], 0),
1647                     darray_mem(keyi->symsMapIndex[0], 0),
1648                     keyi->numLevels[0] * sizeof(int)))) {
1649             identical = false;
1650             continue;
1651         }
1652         if (!darray_same(keyi->symsMapNumEntries[i],
1653                          keyi->symsMapNumEntries[0]) &&
1654             (darray_empty(keyi->symsMapNumEntries[i]) ||
1655              darray_empty(keyi->symsMapNumEntries[0]) ||
1656              memcmp(darray_mem(keyi->symsMapNumEntries[i], 0),
1657                     darray_mem(keyi->symsMapNumEntries[0], 0),
1658                     keyi->numLevels[0] * sizeof(size_t)))) {
1659             identical = false;
1660             continue;
1661         }
1662         if (!darray_same(keyi->acts[i], keyi->acts[0]) &&
1663             (darray_empty(keyi->acts[i]) || darray_empty(keyi->acts[0]) ||
1664              memcmp(darray_mem(keyi->acts[i], 0),
1665                     darray_mem(keyi->acts[0], 0),
1666                     keyi->numLevels[0] * sizeof(union xkb_action)))) {
1667             identical = false;
1668             break;
1669         }
1670     }
1671     if (identical) {
1672         for (i = lastGroup; i > 0; i--) {
1673             keyi->numLevels[i] = 0;
1674             darray_free(keyi->syms[i]);
1675             darray_free(keyi->symsMapIndex[i]);
1676             darray_free(keyi->symsMapNumEntries[i]);
1677             darray_free(keyi->acts[i]);
1678             keyi->types[i] = 0;
1679         }
1680         keyi->symsDefined &= 1;
1681         keyi->actsDefined &= 1;
1682         keyi->typesDefined &= 1;
1683     }
1684 }
1685
1686 /**
1687  * Copy the KeyInfo into the keyboard description.
1688  *
1689  * This function recurses.
1690  */
1691 static bool
1692 CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *keyi, int start_from)
1693 {
1694     unsigned int i;
1695     xkb_keycode_t kc;
1696     struct xkb_key *key;
1697     unsigned int sizeSyms = 0;
1698     unsigned width, tmp, nGroups;
1699     struct xkb_key_type * type;
1700     bool haveActions, autoType, useAlias;
1701     unsigned types[XkbNumKbdGroups];
1702     union xkb_action *outActs;
1703     unsigned int symIndex = 0;
1704     struct xkb_sym_map *sym_map;
1705
1706     useAlias = (start_from == 0);
1707
1708     /* get the keycode for the key. */
1709     if (!FindNamedKey(keymap, keyi->name, &kc, useAlias,
1710                       CreateKeyNames(keymap), start_from)) {
1711         if ((start_from == 0) && (warningLevel >= 5)) {
1712             WARN("Key %s not found in keycodes\n", longText(keyi->name));
1713             ACTION("Symbols ignored\n");
1714         }
1715         return false;
1716     }
1717
1718     key = XkbKey(keymap, kc);
1719
1720     haveActions = false;
1721     for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++) {
1722         if (((i + 1) > nGroups)
1723             && (((keyi->symsDefined | keyi->actsDefined) & (1 << i))
1724                 || (keyi->typesDefined) & (1 << i)))
1725             nGroups = i + 1;
1726         if (!darray_empty(keyi->acts[i]))
1727             haveActions = true;
1728         autoType = false;
1729         /* Assign the type to the key, if it is missing. */
1730         if (keyi->types[i] == XKB_ATOM_NONE) {
1731             if (keyi->dfltType != XKB_ATOM_NONE)
1732                 keyi->types[i] = keyi->dfltType;
1733             else if (FindAutomaticType(keymap, keyi->numLevels[i],
1734                                        darray_mem(keyi->syms[i], 0),
1735                                        &keyi->types[i], &autoType)) { }
1736             else {
1737                 if (warningLevel >= 5) {
1738                     WARN("No automatic type for %d symbols\n",
1739                           (unsigned int) keyi->numLevels[i]);
1740                     ACTION("Using %s for the %s key (keycode %d)\n",
1741                             xkb_atom_text(keymap->ctx, keyi->types[i]),
1742                             longText(keyi->name), kc);
1743                 }
1744             }
1745         }
1746         if (FindNamedType(keymap, keyi->types[i], &types[i])) {
1747             if (!autoType || keyi->numLevels[i] > 2)
1748                 key->explicit |= (1 << i);
1749         }
1750         else {
1751             if (warningLevel >= 3) {
1752                 WARN("Type \"%s\" is not defined\n",
1753                      xkb_atom_text(keymap->ctx, keyi->types[i]));
1754                 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
1755                        longText(keyi->name), kc);
1756             }
1757             types[i] = XkbTwoLevelIndex;
1758         }
1759         /* if the type specifies fewer levels than the key has, shrink the key */
1760         type = &darray_item(keymap->types, types[i]);
1761         if (type->num_levels < keyi->numLevels[i]) {
1762             if (warningLevel > 0) {
1763                 WARN("Type \"%s\" has %d levels, but %s has %d symbols\n",
1764                      type->name, type->num_levels,
1765                      xkb_atom_text(keymap->ctx, keyi->name), keyi->numLevels[i]);
1766                 ACTION("Ignoring extra symbols\n");
1767             }
1768             keyi->numLevels[i] = type->num_levels;
1769         }
1770         if (keyi->numLevels[i] > width)
1771             width = keyi->numLevels[i];
1772         if (type->num_levels > width)
1773             width = type->num_levels;
1774         sizeSyms += darray_size(keyi->syms[i]);
1775     }
1776
1777     if (!XkbcResizeKeySyms(keymap, kc, sizeSyms)) {
1778         WSGO("Could not enlarge symbols for %s (keycode %d)\n",
1779              longText(keyi->name), kc);
1780         return false;
1781     }
1782     if (haveActions) {
1783         outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups);
1784         if (outActs == NULL) {
1785             WSGO("Could not enlarge actions for %s (key %d)\n",
1786                  longText(keyi->name), kc);
1787             return false;
1788         }
1789         key->explicit |= XkbExplicitInterpretMask;
1790     }
1791     else
1792         outActs = NULL;
1793
1794     sym_map = &key->sym_map;
1795
1796     if (keyi->defs.defined & _Key_GroupInfo)
1797         i = keyi->groupInfo;
1798     else
1799         i = sym_map->group_info;
1800
1801     sym_map->group_info = XkbSetNumGroups(i, nGroups);
1802     sym_map->width = width;
1803     sym_map->sym_index = uTypedCalloc(nGroups * width, int);
1804     sym_map->num_syms = uTypedCalloc(nGroups * width, unsigned int);
1805
1806     for (i = 0; i < nGroups; i++) {
1807         /* assign kt_index[i] to the index of the type in map->types.
1808          * kt_index[i] may have been set by a previous run (if we have two
1809          * layouts specified). Let's not overwrite it with the ONE_LEVEL
1810          * default group if we dont even have keys for this group anyway.
1811          *
1812          * FIXME: There should be a better fix for this.
1813          */
1814         if (keyi->numLevels[i])
1815             sym_map->kt_index[i] = types[i];
1816         if (!darray_empty(keyi->syms[i])) {
1817             /* fill key to "width" symbols*/
1818             for (tmp = 0; tmp < width; tmp++) {
1819                 if (tmp < keyi->numLevels[i] &&
1820                     darray_item(keyi->symsMapNumEntries[i], tmp) != 0) {
1821                     memcpy(darray_mem(sym_map->syms, symIndex),
1822                            darray_mem(keyi->syms[i],
1823                                       darray_item(keyi->symsMapIndex[i], tmp)),
1824                            darray_item(keyi->symsMapNumEntries[i],
1825                                        tmp) * sizeof(xkb_keysym_t));
1826                     sym_map->sym_index[(i * width) + tmp] = symIndex;
1827                     sym_map->num_syms[(i * width) + tmp] =
1828                         darray_item(keyi->symsMapNumEntries[i], tmp);
1829                     symIndex += sym_map->num_syms[(i * width) + tmp];
1830                 }
1831                 else {
1832                     sym_map->sym_index[(i * width) + tmp] = -1;
1833                     sym_map->num_syms[(i * width) + tmp] = 0;
1834                 }
1835                 if (outActs != NULL && !darray_empty(keyi->acts[i])) {
1836                     if (tmp < keyi->numLevels[i])
1837                         outActs[tmp] = darray_item(keyi->acts[i], tmp);
1838                     else
1839                         outActs[tmp].type = XkbSA_NoAction;
1840                 }
1841             }
1842         }
1843     }
1844     switch (keyi->behavior.type & XkbKB_OpMask) {
1845     case XkbKB_Default:
1846         break;
1847
1848     default:
1849         key->behavior = keyi->behavior;
1850         key->explicit |= XkbExplicitBehaviorMask;
1851         break;
1852     }
1853     if (keyi->defs.defined & _Key_VModMap) {
1854         key->vmodmap = keyi->vmodmap;
1855         key->explicit |= XkbExplicitVModMapMask;
1856     }
1857     if (keyi->repeat != RepeatUndefined) {
1858         key->repeats = keyi->repeat == RepeatYes;
1859         key->explicit |= XkbExplicitAutoRepeatMask;
1860     }
1861
1862     /* do the same thing for the next key */
1863     CopySymbolsDef(keymap, keyi, kc + 1);
1864     return true;
1865 }
1866
1867 static bool
1868 CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry)
1869 {
1870     xkb_keycode_t kc;
1871
1872     if (!entry->haveSymbol &&
1873         !FindNamedKey(keymap, entry->u.keyName, &kc, true,
1874                       CreateKeyNames(keymap), 0)) {
1875         if (warningLevel >= 5) {
1876             WARN("Key %s not found in keycodes\n",
1877                  longText(entry->u.keyName));
1878             ACTION("Modifier map entry for %s not updated\n",
1879                    XkbcModIndexText(entry->modifier));
1880         }
1881         return false;
1882     }
1883     else if (entry->haveSymbol &&
1884              !FindKeyForSymbol(keymap, entry->u.keySym, &kc)) {
1885         if (warningLevel > 5) {
1886             WARN("Key \"%s\" not found in symbol map\n",
1887                  XkbcKeysymText(entry->u.keySym));
1888             ACTION("Modifier map entry for %s not updated\n",
1889                    XkbcModIndexText(entry->modifier));
1890         }
1891         return false;
1892     }
1893
1894     XkbKey(keymap, kc)->modmap |= (1 << entry->modifier);
1895     return true;
1896 }
1897
1898 static bool
1899 InitKeymapForSymbols(struct xkb_keymap *keymap)
1900 {
1901     size_t nKeys = keymap->max_key_code + 1;
1902
1903     darray_resize0(keymap->keys, nKeys);
1904
1905     darray_resize0(keymap->acts, darray_size(keymap->acts) + 32 + 1);
1906
1907     return true;
1908 }
1909
1910 /**
1911  * Handle the xkb_symbols section of an xkb file.
1912  *
1913  * @param file The parsed xkb_symbols section of the xkb file.
1914  * @param keymap Handle to the keyboard description to store the symbols in.
1915  * @param merge Merge strategy (e.g. MERGE_OVERRIDE).
1916  */
1917 bool
1918 CompileSymbols(XkbFile *file, struct xkb_keymap *keymap,
1919                enum merge_mode merge)
1920 {
1921     int i;
1922     bool ok;
1923     xkb_keycode_t kc;
1924     struct xkb_key *key;
1925     SymbolsInfo info;
1926     KeyInfo *keyi;
1927
1928     InitSymbolsInfo(&info, keymap, file->id);
1929     info.dflt.defs.merge = merge;
1930
1931     HandleSymbolsFile(file, keymap, merge, &info);
1932
1933     if (darray_empty(info.keys))
1934         goto err_info;
1935
1936     if (info.errorCount != 0)
1937         goto err_info;
1938
1939     ok = InitKeymapForSymbols(keymap);
1940     if (!ok)
1941         goto err_info;
1942
1943     if (info.name)
1944         keymap->symbols_section_name = strdup(info.name);
1945
1946     /* now copy info into xkb. */
1947     ApplyAliases(keymap, &info.aliases);
1948
1949     for (i = 0; i < XkbNumKbdGroups; i++) {
1950         if (info.groupNames[i] != XKB_ATOM_NONE) {
1951             free(keymap->group_names[i]);
1952             keymap->group_names[i] = xkb_atom_strdup(keymap->ctx,
1953                                                      info.groupNames[i]);
1954         }
1955     }
1956
1957     /* sanitize keys */
1958     darray_foreach(keyi, info.keys)
1959         PrepareKeyDef(keyi);
1960
1961     /* copy! */
1962     darray_foreach(keyi, info.keys)
1963         if (!CopySymbolsDef(keymap, keyi, 0))
1964             info.errorCount++;
1965
1966     if (warningLevel > 3) {
1967         for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
1968             key = XkbKey(keymap, kc);
1969             if (key->name[0] == '\0')
1970                 continue;
1971
1972             if (XkbKeyNumGroups(keymap, kc) < 1)
1973                 WARN("No symbols defined for <%.4s> (keycode %d)\n",
1974                      key->name, kc);
1975         }
1976     }
1977
1978     if (info.modMap) {
1979         ModMapEntry *mm, *next;
1980         for (mm = info.modMap; mm != NULL; mm = next) {
1981             if (!CopyModMapDef(keymap, mm))
1982                 info.errorCount++;
1983             next = (ModMapEntry *) mm->defs.next;
1984         }
1985     }
1986
1987     FreeSymbolsInfo(&info);
1988     return true;
1989
1990 err_info:
1991     FreeSymbolsInfo(&info);
1992     return false;
1993 }