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