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