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