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