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