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