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