8b371b986a79667dd761de671a63130b737e9af8
[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 = value->value.list.nSyms;
1053     nLevels = value->value.list.nLevels;
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] = value->value.list.symsMapIndex[i];
1065         key->symsMapNumEntries[ndx][i] = value->value.list.symsNumEntries[i];
1066         for (j = 0; j < key->symsMapNumEntries[ndx][i]; j++) {
1067             if (key->symsMapIndex[ndx][i] + j >= nSyms)
1068                 abort();
1069             if (!LookupKeysym(value->value.list.syms[value->value.list.symsMapIndex[i] + j],
1070                               &key->syms[ndx][key->symsMapIndex[ndx][i] + j])) {
1071                 WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
1072                      value->value.list.syms[i], longText(key->name), ndx + 1,
1073                      xkb_atom_text(keymap->ctx, info->groupNames[ndx]), nSyms);
1074                 while (--j >= 0)
1075                     key->syms[ndx][key->symsMapIndex[ndx][i] + j] = XKB_KEY_NoSymbol;
1076                 key->symsMapIndex[ndx][i] = -1;
1077                 key->symsMapNumEntries[ndx][i] = 0;
1078                 break;
1079             }
1080         }
1081     }
1082     for (j = key->numLevels[ndx] - 1;
1083          j >= 0 && key->symsMapNumEntries[ndx][j] == 0; j--)
1084         key->numLevels[ndx]--;
1085     return true;
1086 }
1087
1088 static bool
1089 AddActionsToKey(KeyInfo *key, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1090                 ExprDef *value, SymbolsInfo *info)
1091 {
1092     unsigned int i;
1093     unsigned ndx, nActs;
1094     ExprDef *act;
1095     struct xkb_any_action *toAct;
1096
1097     if (!GetGroupIndex(key, keymap, arrayNdx, ACTIONS, &ndx))
1098         return false;
1099
1100     if (value == NULL)
1101     {
1102         key->actsDefined |= (1 << ndx);
1103         return true;
1104     }
1105     if (value->op != ExprActionList)
1106     {
1107         WSGO("Bad expression type (%d) for action list value\n", value->op);
1108         ACTION("Ignoring actions for group %d of %s\n", ndx,
1109                 longText(key->name));
1110         return false;
1111     }
1112     if (key->acts[ndx] != NULL)
1113     {
1114         WSGO("Actions for key %s, group %d already defined\n",
1115               longText(key->name), ndx);
1116         return false;
1117     }
1118     for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1119     {
1120         act = (ExprDef *) act->common.next;
1121     }
1122     if (nActs < 1)
1123     {
1124         WSGO("Action list but not actions in AddActionsToKey\n");
1125         return false;
1126     }
1127     if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1128         (!ResizeKeyGroup(key, ndx, nActs, nActs, true)))
1129     {
1130         WSGO("Could not resize group %d of key %s\n", ndx,
1131               longText(key->name));
1132         ACTION("Actions lost\n");
1133         return false;
1134     }
1135     key->actsDefined |= (1 << ndx);
1136
1137     toAct = (struct xkb_any_action *) key->acts[ndx];
1138     act = value->value.child;
1139     for (i = 0; i < nActs; i++, toAct++)
1140     {
1141         if (!HandleActionDef(act, keymap, toAct, info->action))
1142         {
1143             ERROR("Illegal action definition for %s\n",
1144                    longText(key->name));
1145             ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1146         }
1147         act = (ExprDef *) act->common.next;
1148     }
1149     return true;
1150 }
1151
1152 static const LookupEntry lockingEntries[] = {
1153     {"true", XkbKB_Lock},
1154     {"yes", XkbKB_Lock},
1155     {"on", XkbKB_Lock},
1156     {"false", XkbKB_Default},
1157     {"no", XkbKB_Default},
1158     {"off", XkbKB_Default},
1159     {"permanent", XkbKB_Lock | XkbKB_Permanent},
1160     {NULL, 0}
1161 };
1162
1163 static const LookupEntry repeatEntries[] = {
1164     {"true", RepeatYes},
1165     {"yes", RepeatYes},
1166     {"on", RepeatYes},
1167     {"false", RepeatNo},
1168     {"no", RepeatNo},
1169     {"off", RepeatNo},
1170     {"default", RepeatUndefined},
1171     {NULL, 0}
1172 };
1173
1174 static bool
1175 SetSymbolsField(KeyInfo *key, struct xkb_keymap *keymap, char *field,
1176                 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
1177 {
1178     bool ok = true;
1179     ExprResult tmp;
1180
1181     if (strcasecmp(field, "type") == 0)
1182     {
1183         ExprResult ndx;
1184         if ((!ExprResolveString(keymap->ctx, value, &tmp))
1185             && (warningLevel > 0))
1186         {
1187             WARN("The type field of a key symbol map must be a string\n");
1188             ACTION("Ignoring illegal type definition\n");
1189         }
1190         if (arrayNdx == NULL)
1191         {
1192             key->dfltType = xkb_atom_intern(keymap->ctx, tmp.str);
1193             key->defs.defined |= _Key_Type_Dflt;
1194         }
1195         else if (!ExprResolveGroup(keymap->ctx, arrayNdx, &ndx))
1196         {
1197             ERROR("Illegal group index for type of key %s\n",
1198                    longText(key->name));
1199             ACTION("Definition with non-integer array index ignored\n");
1200             free(tmp.str);
1201             return false;
1202         }
1203         else
1204         {
1205             key->types[ndx.uval - 1] = xkb_atom_intern(keymap->ctx, tmp.str);
1206             key->typesDefined |= (1 << (ndx.uval - 1));
1207         }
1208         free(tmp.str);
1209     }
1210     else if (strcasecmp(field, "symbols") == 0)
1211         return AddSymbolsToKey(key, keymap, arrayNdx, value, info);
1212     else if (strcasecmp(field, "actions") == 0)
1213         return AddActionsToKey(key, keymap, arrayNdx, value, info);
1214     else if ((strcasecmp(field, "vmods") == 0) ||
1215              (strcasecmp(field, "virtualmods") == 0) ||
1216              (strcasecmp(field, "virtualmodifiers") == 0))
1217     {
1218         ok = ExprResolveVModMask(value, &tmp, keymap);
1219         if (ok)
1220         {
1221             key->vmodmap = (tmp.uval >> 8);
1222             key->defs.defined |= _Key_VModMap;
1223         }
1224         else
1225         {
1226             ERROR("Expected a virtual modifier mask, found %s\n",
1227                    exprOpText(value->op));
1228             ACTION("Ignoring virtual modifiers definition for key %s\n",
1229                     longText(key->name));
1230         }
1231     }
1232     else if ((strcasecmp(field, "locking") == 0) ||
1233              (strcasecmp(field, "lock") == 0) ||
1234              (strcasecmp(field, "locks") == 0))
1235     {
1236         ok = ExprResolveEnum(keymap->ctx, value, &tmp, lockingEntries);
1237         if (ok)
1238             key->behavior.type = tmp.uval;
1239         key->defs.defined |= _Key_Behavior;
1240     }
1241     else if ((strcasecmp(field, "radiogroup") == 0) ||
1242              (strcasecmp(field, "permanentradiogroup") == 0) ||
1243              (strcasecmp(field, "allownone") == 0))
1244     {
1245         ERROR("Radio groups not supported\n");
1246         ACTION("Ignoring radio group specification for key %s\n", longText(key->name));
1247         return false;
1248     }
1249     else if (uStrCasePrefix("overlay", field) ||
1250              uStrCasePrefix("permanentoverlay", field))
1251     {
1252         ERROR("Overlays not supported\n");
1253         ACTION("Ignoring overlay specification for key %s\n", longText(key->name));
1254     }
1255     else if ((strcasecmp(field, "repeating") == 0) ||
1256              (strcasecmp(field, "repeats") == 0) ||
1257              (strcasecmp(field, "repeat") == 0))
1258     {
1259         ok = ExprResolveEnum(keymap->ctx, value, &tmp, repeatEntries);
1260         if (!ok)
1261         {
1262             ERROR("Illegal repeat setting for %s\n",
1263                    longText(key->name));
1264             ACTION("Non-boolean repeat setting ignored\n");
1265             return false;
1266         }
1267         key->repeat = tmp.uval;
1268         key->defs.defined |= _Key_Repeat;
1269     }
1270     else if ((strcasecmp(field, "groupswrap") == 0) ||
1271              (strcasecmp(field, "wrapgroups") == 0))
1272     {
1273         ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1274         if (!ok)
1275         {
1276             ERROR("Illegal groupsWrap setting for %s\n",
1277                    longText(key->name));
1278             ACTION("Non-boolean value ignored\n");
1279             return false;
1280         }
1281         if (tmp.uval)
1282             key->groupInfo = XkbWrapIntoRange;
1283         else
1284             key->groupInfo = XkbClampIntoRange;
1285         key->defs.defined |= _Key_GroupInfo;
1286     }
1287     else if ((strcasecmp(field, "groupsclamp") == 0) ||
1288              (strcasecmp(field, "clampgroups") == 0))
1289     {
1290         ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1291         if (!ok)
1292         {
1293             ERROR("Illegal groupsClamp setting for %s\n",
1294                    longText(key->name));
1295             ACTION("Non-boolean value ignored\n");
1296             return false;
1297         }
1298         if (tmp.uval)
1299             key->groupInfo = XkbClampIntoRange;
1300         else
1301             key->groupInfo = XkbWrapIntoRange;
1302         key->defs.defined |= _Key_GroupInfo;
1303     }
1304     else if ((strcasecmp(field, "groupsredirect") == 0) ||
1305              (strcasecmp(field, "redirectgroups") == 0))
1306     {
1307         if (!ExprResolveGroup(keymap->ctx, value, &tmp))
1308         {
1309             ERROR("Illegal group index for redirect of key %s\n",
1310                    longText(key->name));
1311             ACTION("Definition with non-integer group ignored\n");
1312             return false;
1313         }
1314         key->groupInfo =
1315             XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1316         key->defs.defined |= _Key_GroupInfo;
1317     }
1318     else
1319     {
1320         ERROR("Unknown field %s in a symbol interpretation\n", field);
1321         ACTION("Definition ignored\n");
1322         ok = false;
1323     }
1324     return ok;
1325 }
1326
1327 static int
1328 SetGroupName(SymbolsInfo *info, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1329              ExprDef *value)
1330 {
1331     ExprResult tmp, name;
1332
1333     if ((arrayNdx == NULL) && (warningLevel > 0))
1334     {
1335         WARN("You must specify an index when specifying a group name\n");
1336         ACTION("Group name definition without array subscript ignored\n");
1337         return false;
1338     }
1339     if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp))
1340     {
1341         ERROR("Illegal index in group name definition\n");
1342         ACTION("Definition with non-integer array index ignored\n");
1343         return false;
1344     }
1345     if (!ExprResolveString(keymap->ctx, value, &name))
1346     {
1347         ERROR("Group name must be a string\n");
1348         ACTION("Illegal name for group %d ignored\n", tmp.uval);
1349         return false;
1350     }
1351     info->groupNames[tmp.uval - 1 + info->explicit_group] =
1352         xkb_atom_intern(keymap->ctx, name.str);
1353     free(name.str);
1354
1355     return true;
1356 }
1357
1358 static int
1359 HandleSymbolsVar(VarDef *stmt, struct xkb_keymap *keymap, SymbolsInfo *info)
1360 {
1361     ExprResult elem, field, tmp;
1362     ExprDef *arrayNdx;
1363     bool ret;
1364
1365     if (ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx) == 0)
1366         return 0;               /* internal error, already reported */
1367     if (elem.str && (strcasecmp(elem.str, "key") == 0))
1368     {
1369         ret = SetSymbolsField(&info->dflt, keymap, field.str, arrayNdx,
1370                               stmt->value, info);
1371     }
1372     else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) ||
1373                                     (strcasecmp(field.str, "groupname") ==
1374                                      0)))
1375     {
1376         ret = SetGroupName(info, keymap, arrayNdx, stmt->value);
1377     }
1378     else if ((elem.str == NULL)
1379              && ((strcasecmp(field.str, "groupswrap") == 0) ||
1380                  (strcasecmp(field.str, "wrapgroups") == 0)))
1381     {
1382         if (!ExprResolveBoolean(keymap->ctx, stmt->value, &tmp))
1383         {
1384             ERROR("Illegal setting for global groupsWrap\n");
1385             ACTION("Non-boolean value ignored\n");
1386             ret = false;
1387         }
1388         else {
1389             if (tmp.uval)
1390                 info->groupInfo = XkbWrapIntoRange;
1391             else
1392                 info->groupInfo = XkbClampIntoRange;
1393             ret = true;
1394         }
1395     }
1396     else if ((elem.str == NULL)
1397              && ((strcasecmp(field.str, "groupsclamp") == 0) ||
1398                  (strcasecmp(field.str, "clampgroups") == 0)))
1399     {
1400         if (!ExprResolveBoolean(keymap->ctx, stmt->value, &tmp))
1401         {
1402             ERROR("Illegal setting for global groupsClamp\n");
1403             ACTION("Non-boolean value ignored\n");
1404             return false;
1405         }
1406         else {
1407             if (tmp.uval)
1408                 info->groupInfo = XkbClampIntoRange;
1409             else
1410                 info->groupInfo = XkbWrapIntoRange;
1411             ret = true;
1412         }
1413     }
1414     else if ((elem.str == NULL)
1415              && ((strcasecmp(field.str, "groupsredirect") == 0) ||
1416                  (strcasecmp(field.str, "redirectgroups") == 0)))
1417     {
1418         if (!ExprResolveGroup(keymap->ctx, stmt->value, &tmp))
1419         {
1420             ERROR("Illegal group index for global groupsRedirect\n");
1421             ACTION("Definition with non-integer group ignored\n");
1422             ret = false;
1423         }
1424         else {
1425             info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange,
1426                                               tmp.uval);
1427             ret = true;
1428         }
1429     }
1430     else if ((elem.str == NULL) && (strcasecmp(field.str, "allownone") == 0))
1431     {
1432         ERROR("Radio groups not supported\n");
1433         ACTION("Ignoring \"allow none\" specification\n");
1434         ret = false;
1435     }
1436     else {
1437         ret = SetActionField(keymap, elem.str, field.str, arrayNdx,
1438                              stmt->value, &info->action);
1439     }
1440
1441     free(elem.str);
1442     free(field.str);
1443     return ret;
1444 }
1445
1446 static bool
1447 HandleSymbolsBody(VarDef *def, struct xkb_keymap *keymap, KeyInfo *key,
1448                   SymbolsInfo *info)
1449 {
1450     bool ok = true;
1451     ExprResult tmp, field;
1452     ExprDef *arrayNdx;
1453
1454     for (; def != NULL; def = (VarDef *) def->common.next)
1455     {
1456         if ((def->name) && (def->name->type == ExprFieldRef))
1457         {
1458             ok = HandleSymbolsVar(def, keymap, info);
1459             continue;
1460         }
1461         else
1462         {
1463             if (def->name == NULL)
1464             {
1465                 if ((def->value == NULL)
1466                     || (def->value->op == ExprKeysymList))
1467                     field.str = strdup("symbols");
1468                 else
1469                     field.str = strdup("actions");
1470                 arrayNdx = NULL;
1471             }
1472             else
1473             {
1474                 ok = ExprResolveLhs(keymap, def->name, &tmp, &field,
1475                                     &arrayNdx);
1476             }
1477             if (ok)
1478                 ok = SetSymbolsField(key, keymap, field.str, arrayNdx,
1479                                      def->value, info);
1480             free(field.str);
1481         }
1482     }
1483     return ok;
1484 }
1485
1486 static bool
1487 SetExplicitGroup(SymbolsInfo *info, KeyInfo *key)
1488 {
1489     unsigned group = info->explicit_group;
1490
1491     if (group == 0)
1492         return true;
1493
1494     if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1495     {
1496         int i;
1497         WARN("For the map %s an explicit group specified\n", info->name);
1498         WARN("but key %s has more than one group defined\n",
1499               longText(key->name));
1500         ACTION("All groups except first one will be ignored\n");
1501         for (i = 1; i < XkbNumKbdGroups; i++)
1502         {
1503             key->numLevels[i] = 0;
1504             free(key->syms[i]);
1505             key->syms[i] = NULL;
1506             free(key->acts[i]);
1507             key->acts[i] = NULL;
1508             key->types[i] = 0;
1509         }
1510     }
1511     key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1512
1513     key->numLevels[group] = key->numLevels[0];
1514     key->numLevels[0] = 0;
1515     key->syms[group] = key->syms[0];
1516     key->syms[0] = NULL;
1517     key->sizeSyms[group] = key->sizeSyms[0];
1518     key->sizeSyms[0] = 0;
1519     key->symsMapIndex[group] = key->symsMapIndex[0];
1520     key->symsMapIndex[0] = NULL;
1521     key->symsMapNumEntries[group] = key->symsMapNumEntries[0];
1522     key->symsMapNumEntries[0] = NULL;
1523     key->acts[group] = key->acts[0];
1524     key->acts[0] = NULL;
1525     key->types[group] = key->types[0];
1526     key->types[0] = 0;
1527     return true;
1528 }
1529
1530 static int
1531 HandleSymbolsDef(SymbolsDef *stmt, struct xkb_keymap *keymap,
1532                  SymbolsInfo *info)
1533 {
1534     KeyInfo key;
1535
1536     InitKeyInfo(&key);
1537     CopyKeyInfo(&info->dflt, &key, false);
1538     key.defs.merge = stmt->merge;
1539     key.name = KeyNameToLong(stmt->keyName);
1540     if (!HandleSymbolsBody((VarDef *) stmt->symbols, keymap, &key, info))
1541     {
1542         info->errorCount++;
1543         return false;
1544     }
1545
1546     if (!SetExplicitGroup(info, &key))
1547     {
1548         info->errorCount++;
1549         return false;
1550     }
1551
1552     if (!AddKeySymbols(info, &key, keymap))
1553     {
1554         info->errorCount++;
1555         return false;
1556     }
1557     return true;
1558 }
1559
1560 static bool
1561 HandleModMapDef(ModMapDef *def, struct xkb_keymap *keymap, SymbolsInfo *info)
1562 {
1563     ExprDef *key;
1564     ModMapEntry tmp;
1565     ExprResult rtrn;
1566     bool ok;
1567
1568     if (!LookupModIndex(keymap->ctx, NULL, def->modifier, TypeInt, &rtrn))
1569     {
1570         ERROR("Illegal modifier map definition\n");
1571         ACTION("Ignoring map for non-modifier \"%s\"\n",
1572                 xkb_atom_text(keymap->ctx, def->modifier));
1573         return false;
1574     }
1575     ok = true;
1576     tmp.modifier = rtrn.uval;
1577     for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1578     {
1579         if ((key->op == ExprValue) && (key->type == TypeKeyName))
1580         {
1581             tmp.haveSymbol = false;
1582             tmp.u.keyName = KeyNameToLong(key->value.keyName);
1583         }
1584         else if (ExprResolveKeySym(keymap->ctx, key, &rtrn))
1585         {
1586             tmp.haveSymbol = true;
1587             tmp.u.keySym = rtrn.uval;
1588         }
1589         else
1590         {
1591             ERROR("Modmap entries may contain only key names or keysyms\n");
1592             ACTION("Illegal definition for %s modifier ignored\n",
1593                     XkbcModIndexText(tmp.modifier));
1594             continue;
1595         }
1596
1597         ok = AddModMapEntry(info, &tmp) && ok;
1598     }
1599     return ok;
1600 }
1601
1602 static void
1603 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
1604                   unsigned merge, SymbolsInfo *info)
1605 {
1606     ParseCommon *stmt;
1607
1608     free(info->name);
1609     info->name = uDupString(file->name);
1610     stmt = file->defs;
1611     while (stmt)
1612     {
1613         switch (stmt->stmtType)
1614         {
1615         case StmtInclude:
1616             if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info))
1617                 info->errorCount++;
1618             break;
1619         case StmtSymbolsDef:
1620             if (!HandleSymbolsDef((SymbolsDef *) stmt, keymap, info))
1621                 info->errorCount++;
1622             break;
1623         case StmtVarDef:
1624             if (!HandleSymbolsVar((VarDef *) stmt, keymap, info))
1625                 info->errorCount++;
1626             break;
1627         case StmtVModDef:
1628             if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
1629                 info->errorCount++;
1630             break;
1631         case StmtInterpDef:
1632             ERROR("Interpretation files may not include other types\n");
1633             ACTION("Ignoring definition of symbol interpretation\n");
1634             info->errorCount++;
1635             break;
1636         case StmtKeycodeDef:
1637             ERROR("Interpretation files may not include other types\n");
1638             ACTION("Ignoring definition of key name\n");
1639             info->errorCount++;
1640             break;
1641         case StmtModMapDef:
1642             if (!HandleModMapDef((ModMapDef *) stmt, keymap, info))
1643                 info->errorCount++;
1644             break;
1645         default:
1646             WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1647                   stmt->stmtType);
1648             break;
1649         }
1650         stmt = stmt->next;
1651         if (info->errorCount > 10)
1652         {
1653 #ifdef NOISY
1654             ERROR("Too many errors\n");
1655 #endif
1656             ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1657             break;
1658         }
1659     }
1660 }
1661
1662 static bool
1663 FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
1664                  xkb_keycode_t *kc_rtrn)
1665 {
1666     xkb_keycode_t key;
1667     unsigned int group, level;
1668
1669     for (key = keymap->min_key_code; key <= keymap->max_key_code; key++)
1670     {
1671         for (group = 0; group < XkbKeyNumGroups(keymap, key); group++)
1672         {
1673             for (level = 0; level < XkbKeyGroupWidth(keymap, key, group);
1674                  level++)
1675             {
1676                 if (XkbKeyNumSyms(keymap, key, group, level) != 1 ||
1677                     (XkbKeySymEntry(keymap, key, group, level))[0] != sym)
1678                     continue;
1679                 *kc_rtrn = key;
1680                 return true;
1681             }
1682         }
1683     }
1684
1685     return false;
1686 }
1687
1688 /**
1689  * Find the given name in the keymap->map->types and return its index.
1690  *
1691  * @param atom The atom to search for.
1692  * @param type_rtrn Set to the index of the name if found.
1693  *
1694  * @return true if found, false otherwise.
1695  */
1696 static bool
1697 FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn)
1698 {
1699     unsigned n = 0;
1700     const char *name = xkb_atom_text(keymap->ctx, atom);
1701     struct xkb_key_type *type;
1702
1703     if (keymap && keymap->map) {
1704         darray_foreach(type, keymap->map->types) {
1705             if (strcmp(type->name, name) == 0) {
1706                 *type_rtrn = n;
1707                 return true;
1708             }
1709             n++;
1710         }
1711     }
1712     return false;
1713 }
1714
1715 /**
1716  * Assign a type to the given sym and return the Atom for the type assigned.
1717  *
1718  * Simple recipe:
1719  * - ONE_LEVEL for width 0/1
1720  * - ALPHABETIC for 2 shift levels, with lower/upercase
1721  * - KEYPAD for keypad keys.
1722  * - TWO_LEVEL for other 2 shift level keys.
1723  * and the same for four level keys.
1724  *
1725  * @param width Number of sysms in syms.
1726  * @param syms The keysyms for the given key (must be size width).
1727  * @param typeNameRtrn Set to the Atom of the type name.
1728  *
1729  * @returns true if a type could be found, false otherwise.
1730  */
1731 static bool
1732 FindAutomaticType(struct xkb_keymap *keymap, int width, xkb_keysym_t *syms,
1733                   xkb_atom_t *typeNameRtrn, bool *autoType)
1734 {
1735     *autoType = false;
1736     if ((width == 1) || (width == 0))
1737     {
1738         *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
1739         *autoType = true;
1740     }
1741     else if (width == 2)
1742     {
1743         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1744         {
1745             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
1746         }
1747         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1748         {
1749             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "KEYPAD");
1750             *autoType = true;
1751         }
1752         else
1753         {
1754             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
1755             *autoType = true;
1756         }
1757     }
1758     else if (width <= 4)
1759     {
1760         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1761             if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1762                 *typeNameRtrn =
1763                     xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_ALPHABETIC");
1764             else
1765                 *typeNameRtrn = xkb_atom_intern(keymap->ctx,
1766                                                 "FOUR_LEVEL_SEMIALPHABETIC");
1767
1768         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1769             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_KEYPAD");
1770         else
1771             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL");
1772         /* XXX: why not set autoType here? */
1773     }
1774     return ((width >= 0) && (width <= 4));
1775 }
1776
1777 /**
1778  * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1779  * groups, and reduce to one group if all groups are identical anyway.
1780  */
1781 static void
1782 PrepareKeyDef(KeyInfo * key)
1783 {
1784     int i, j, width, defined, lastGroup;
1785     bool identical;
1786
1787     defined = key->symsDefined | key->actsDefined | key->typesDefined;
1788     /* get highest group number */
1789     for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1790     {
1791         if (defined & (1 << i))
1792             break;
1793     }
1794     lastGroup = i;
1795
1796     if (lastGroup == 0)
1797         return;
1798
1799     /* If there are empty groups between non-empty ones fill them with data */
1800     /* from the first group. */
1801     /* We can make a wrong assumption here. But leaving gaps is worse. */
1802     for (i = lastGroup; i > 0; i--)
1803     {
1804         if (defined & (1 << i))
1805             continue;
1806         width = key->numLevels[0];
1807         if (key->typesDefined & 1)
1808         {
1809             for (j = 0; j < width; j++)
1810             {
1811                 key->types[i] = key->types[0];
1812             }
1813             key->typesDefined |= 1 << i;
1814         }
1815         if ((key->actsDefined & 1) && key->acts[0])
1816         {
1817             key->acts[i] = uTypedCalloc(width, union xkb_action);
1818             if (key->acts[i] == NULL)
1819                 continue;
1820             memcpy(key->acts[i], key->acts[0],
1821                    width * sizeof(union xkb_action));
1822             key->actsDefined |= 1 << i;
1823         }
1824         if ((key->symsDefined & 1) && key->sizeSyms[0])
1825         {
1826             key->syms[i] = uTypedCalloc(key->sizeSyms[0], xkb_keysym_t);
1827             if (key->syms[i] == NULL)
1828                 continue;
1829             memcpy(key->syms[i], key->syms[0],
1830                    key->sizeSyms[0] * sizeof(xkb_keysym_t));
1831             key->symsMapIndex[i] = uTypedCalloc(width, int);
1832             if (!key->symsMapIndex[i])
1833             {
1834                 free(key->syms[i]);
1835                 key->syms[i] = NULL;
1836                 continue;
1837             }
1838             memcpy(key->symsMapIndex[i], key->symsMapIndex[0],
1839                    width * sizeof(int));
1840             key->symsMapNumEntries[i] = uTypedCalloc(width, unsigned int);
1841             if (!key->symsMapNumEntries[i])
1842             {
1843                 free(key->syms[i]);
1844                 key->syms[i] = NULL;
1845                 free(key->symsMapIndex[i]);
1846                 key->symsMapIndex[i] = NULL;
1847                 continue;
1848             }
1849             memcpy(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
1850                    width * sizeof(int));
1851             key->sizeSyms[i] = key->sizeSyms[0];
1852             key->symsDefined |= 1 << i;
1853         }
1854         if (defined & 1)
1855         {
1856             key->numLevels[i] = key->numLevels[0];
1857         }
1858     }
1859     /* If all groups are completely identical remove them all */
1860     /* exept the first one. */
1861     identical = true;
1862     for (i = lastGroup; i > 0; i--)
1863     {
1864         if ((key->numLevels[i] != key->numLevels[0]) ||
1865             (key->types[i] != key->types[0]))
1866         {
1867             identical = false;
1868             break;
1869         }
1870         if ((key->syms[i] != key->syms[0]) &&
1871             (key->syms[i] == NULL || key->syms[0] == NULL ||
1872              key->sizeSyms[i] != key->sizeSyms[0] ||
1873              memcmp(key->syms[i], key->syms[0],
1874                     sizeof(xkb_keysym_t) * key->sizeSyms[0])))
1875         {
1876             identical = false;
1877             break;
1878         }
1879         if ((key->symsMapIndex[i] != key->symsMapIndex[i]) &&
1880             (key->symsMapIndex[i] == NULL || key->symsMapIndex[0] == NULL ||
1881              memcmp(key->symsMapIndex[i], key->symsMapIndex[0],
1882                     key->numLevels[0] * sizeof(int))))
1883         {
1884             identical = false;
1885             continue;
1886         }
1887         if ((key->symsMapNumEntries[i] != key->symsMapNumEntries[i]) &&
1888             (key->symsMapNumEntries[i] == NULL ||
1889              key->symsMapNumEntries[0] == NULL ||
1890              memcmp(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
1891                     key->numLevels[0] * sizeof(int))))
1892         {
1893             identical = false;
1894             continue;
1895         }
1896         if ((key->acts[i] != key->acts[0]) &&
1897             (key->acts[i] == NULL || key->acts[0] == NULL ||
1898              memcmp(key->acts[i], key->acts[0],
1899                     sizeof(union xkb_action) * key->numLevels[0])))
1900         {
1901             identical = false;
1902             break;
1903         }
1904     }
1905     if (identical)
1906     {
1907         for (i = lastGroup; i > 0; i--)
1908         {
1909             key->numLevels[i] = 0;
1910             free(key->syms[i]);
1911             key->syms[i] = NULL;
1912             key->sizeSyms[i] = 0;
1913             free(key->symsMapIndex[i]);
1914             key->symsMapIndex[i] = NULL;
1915             free(key->symsMapNumEntries[i]);
1916             key->symsMapNumEntries[i] = NULL;
1917             free(key->acts[i]);
1918             key->acts[i] = NULL;
1919             key->types[i] = 0;
1920         }
1921         key->symsDefined &= 1;
1922         key->actsDefined &= 1;
1923         key->typesDefined &= 1;
1924     }
1925 }
1926
1927 /**
1928  * Copy the KeyInfo into the keyboard description.
1929  *
1930  * This function recurses.
1931  */
1932 static bool
1933 CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *key, int start_from)
1934 {
1935     unsigned int i;
1936     xkb_keycode_t kc;
1937     unsigned int sizeSyms = 0;
1938     unsigned width, tmp, nGroups;
1939     struct xkb_key_type * type;
1940     bool haveActions, autoType, useAlias;
1941     unsigned types[XkbNumKbdGroups];
1942     union xkb_action *outActs;
1943     unsigned int symIndex = 0;
1944
1945     useAlias = (start_from == 0);
1946
1947     /* get the keycode for the key. */
1948     if (!FindNamedKey(keymap, key->name, &kc, useAlias,
1949                       CreateKeyNames(keymap), start_from))
1950     {
1951         if ((start_from == 0) && (warningLevel >= 5))
1952         {
1953             WARN("Key %s not found in keycodes\n", longText(key->name));
1954             ACTION("Symbols ignored\n");
1955         }
1956         return false;
1957     }
1958
1959     haveActions = false;
1960     for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1961     {
1962         if (((i + 1) > nGroups)
1963             && (((key->symsDefined | key->actsDefined) & (1 << i))
1964                 || (key->typesDefined) & (1 << i)))
1965             nGroups = i + 1;
1966         if (key->acts[i])
1967             haveActions = true;
1968         autoType = false;
1969         /* Assign the type to the key, if it is missing. */
1970         if (key->types[i] == XKB_ATOM_NONE)
1971         {
1972             if (key->dfltType != XKB_ATOM_NONE)
1973                 key->types[i] = key->dfltType;
1974             else if (FindAutomaticType(keymap, key->numLevels[i], key->syms[i],
1975                                        &key->types[i], &autoType))
1976             {
1977             }
1978             else
1979             {
1980                 if (warningLevel >= 5)
1981                 {
1982                     WARN("No automatic type for %d symbols\n",
1983                           (unsigned int) key->numLevels[i]);
1984                     ACTION("Using %s for the %s key (keycode %d)\n",
1985                             xkb_atom_text(keymap->ctx, key->types[i]),
1986                             longText(key->name), kc);
1987                 }
1988             }
1989         }
1990         if (FindNamedType(keymap, key->types[i], &types[i]))
1991         {
1992             if (!autoType || key->numLevels[i] > 2)
1993                 keymap->server->explicit[kc] |= (1 << i);
1994         }
1995         else
1996         {
1997             if (warningLevel >= 3)
1998             {
1999                 WARN("Type \"%s\" is not defined\n",
2000                       xkb_atom_text(keymap->ctx, key->types[i]));
2001                 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
2002                         longText(key->name), kc);
2003             }
2004             types[i] = XkbTwoLevelIndex;
2005         }
2006         /* if the type specifies fewer levels than the key has, shrink the key */
2007         type = &darray_item(keymap->map->types, types[i]);
2008         if (type->num_levels < key->numLevels[i])
2009         {
2010             if (warningLevel > 0)
2011             {
2012                 WARN("Type \"%s\" has %d levels, but %s has %d symbols\n",
2013                      type->name, type->num_levels,
2014                      xkb_atom_text(keymap->ctx, key->name), key->numLevels[i]);
2015                 ACTION("Ignoring extra symbols\n");
2016             }
2017             key->numLevels[i] = type->num_levels;
2018         }
2019         if (key->numLevels[i] > width)
2020             width = key->numLevels[i];
2021         if (type->num_levels > width)
2022             width = type->num_levels;
2023         sizeSyms += key->sizeSyms[i];
2024     }
2025
2026     if (!XkbcResizeKeySyms(keymap, kc, sizeSyms))
2027     {
2028         WSGO("Could not enlarge symbols for %s (keycode %d)\n",
2029               longText(key->name), kc);
2030         return false;
2031     }
2032     if (haveActions)
2033     {
2034         outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups);
2035         if (outActs == NULL)
2036         {
2037             WSGO("Could not enlarge actions for %s (key %d)\n",
2038                   longText(key->name), kc);
2039             return false;
2040         }
2041         keymap->server->explicit[kc] |= XkbExplicitInterpretMask;
2042     }
2043     else
2044         outActs = NULL;
2045     if (key->defs.defined & _Key_GroupInfo)
2046         i = key->groupInfo;
2047     else
2048         i = keymap->map->key_sym_map[kc].group_info;
2049
2050     keymap->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2051     keymap->map->key_sym_map[kc].width = width;
2052     keymap->map->key_sym_map[kc].sym_index = uTypedCalloc(nGroups * width,
2053                                                           int);
2054     keymap->map->key_sym_map[kc].num_syms = uTypedCalloc(nGroups * width,
2055                                                          unsigned int);
2056     for (i = 0; i < nGroups; i++)
2057     {
2058         /* assign kt_index[i] to the index of the type in map->types.
2059          * kt_index[i] may have been set by a previous run (if we have two
2060          * layouts specified). Let's not overwrite it with the ONE_LEVEL
2061          * default group if we dont even have keys for this group anyway.
2062          *
2063          * FIXME: There should be a better fix for this.
2064          */
2065         if (key->numLevels[i])
2066             keymap->map->key_sym_map[kc].kt_index[i] = types[i];
2067         if (key->sizeSyms[i] != 0)
2068         {
2069             /* fill key to "width" symbols*/
2070             for (tmp = 0; tmp < width; tmp++)
2071             {
2072                 if (tmp < key->numLevels[i] && key->symsMapNumEntries[i][tmp])
2073                 {
2074                     memcpy(&keymap->map->key_sym_map[kc].syms[symIndex],
2075                            &key->syms[i][key->symsMapIndex[i][tmp]],
2076                            key->symsMapNumEntries[i][tmp] *
2077                             sizeof(xkb_keysym_t));
2078                     keymap->map->key_sym_map[kc].sym_index[(i * width) + tmp] =
2079                         symIndex;
2080                     keymap->map->key_sym_map[kc].num_syms[(i * width) + tmp] =
2081                         key->symsMapNumEntries[i][tmp];
2082                     symIndex +=
2083                         keymap->map->key_sym_map[kc].num_syms[(i * width) + tmp];
2084                 }
2085                 else
2086                 {
2087                     keymap->map->key_sym_map[kc].sym_index[(i * width) + tmp] = -1;
2088                     keymap->map->key_sym_map[kc].num_syms[(i * width) + tmp] = 0;
2089                 }
2090                 if ((outActs != NULL) && (key->acts[i] != NULL))
2091                 {
2092                     if (tmp < key->numLevels[i])
2093                         outActs[tmp] = key->acts[i][tmp];
2094                     else
2095                         outActs[tmp].type = XkbSA_NoAction;
2096                 }
2097             }
2098         }
2099     }
2100     switch (key->behavior.type & XkbKB_OpMask)
2101     {
2102     case XkbKB_Default:
2103         break;
2104     default:
2105         keymap->server->behaviors[kc] = key->behavior;
2106         keymap->server->explicit[kc] |= XkbExplicitBehaviorMask;
2107         break;
2108     }
2109     if (key->defs.defined & _Key_VModMap)
2110     {
2111         keymap->server->vmodmap[kc] = key->vmodmap;
2112         keymap->server->explicit[kc] |= XkbExplicitVModMapMask;
2113     }
2114     if (key->repeat != RepeatUndefined)
2115     {
2116         if (key->repeat == RepeatYes)
2117             keymap->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2118         else
2119             keymap->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2120         keymap->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2121     }
2122
2123     if (nGroups > keymap->ctrls->num_groups)
2124         keymap->ctrls->num_groups = nGroups;
2125
2126     /* do the same thing for the next key */
2127     CopySymbolsDef(keymap, key, kc + 1);
2128     return true;
2129 }
2130
2131 static bool
2132 CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry)
2133 {
2134     xkb_keycode_t kc;
2135
2136     if (!entry->haveSymbol &&
2137         !FindNamedKey(keymap, entry->u.keyName, &kc, true,
2138                       CreateKeyNames(keymap), 0))
2139     {
2140         if (warningLevel >= 5)
2141         {
2142             WARN("Key %s not found in keycodes\n",
2143                   longText(entry->u.keyName));
2144             ACTION("Modifier map entry for %s not updated\n",
2145                     XkbcModIndexText(entry->modifier));
2146         }
2147         return false;
2148     }
2149     else if (entry->haveSymbol &&
2150              !FindKeyForSymbol(keymap, entry->u.keySym, &kc))
2151     {
2152         if (warningLevel > 5)
2153         {
2154             WARN("Key \"%s\" not found in symbol map\n",
2155                   XkbcKeysymText(entry->u.keySym));
2156             ACTION("Modifier map entry for %s not updated\n",
2157                     XkbcModIndexText(entry->modifier));
2158         }
2159         return false;
2160     }
2161     keymap->map->modmap[kc] |= (1 << entry->modifier);
2162     return true;
2163 }
2164
2165 /**
2166  * Handle the xkb_symbols section of an xkb file.
2167  *
2168  * @param file The parsed xkb_symbols section of the xkb file.
2169  * @param keymap Handle to the keyboard description to store the symbols in.
2170  * @param merge Merge strategy (e.g. MergeOverride).
2171  */
2172 bool
2173 CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
2174 {
2175     unsigned int i;
2176     SymbolsInfo info;
2177     KeyInfo *key;
2178
2179     InitSymbolsInfo(&info, keymap);
2180     info.dflt.defs.fileID = file->id;
2181     info.dflt.defs.merge = merge;
2182
2183     HandleSymbolsFile(file, keymap, merge, &info);
2184
2185     if (info.nKeys == 0)
2186         goto err_info;
2187
2188     if (info.errorCount != 0)
2189         goto err_info;
2190
2191     /* alloc memory in the xkb struct */
2192     if (XkbcAllocNames(keymap, XkbGroupNamesMask, 0) != Success) {
2193         WSGO("Can not allocate names in CompileSymbols\n");
2194         ACTION("Symbols not added\n");
2195         goto err_info;
2196     }
2197
2198     if (XkbcAllocClientMap(keymap, XkbKeySymsMask | XkbModifierMapMask, 0)
2199         != Success) {
2200         WSGO("Could not allocate client map in CompileSymbols\n");
2201         ACTION("Symbols not added\n");
2202         goto err_info;
2203     }
2204
2205     if (XkbcAllocServerMap(keymap, XkbAllServerInfoMask, 32) != Success) {
2206         WSGO("Could not allocate server map in CompileSymbols\n");
2207         ACTION("Symbols not added\n");
2208         goto err_info;
2209     }
2210
2211     if (XkbcAllocControls(keymap) != Success) {
2212         WSGO("Could not allocate controls in CompileSymbols\n");
2213         ACTION("Symbols not added\n");
2214         goto err_info;
2215     }
2216
2217     /* now copy info into xkb. */
2218     ApplyAliases(keymap, &info.aliases);
2219
2220     for (i = 0; i < XkbNumKbdGroups; i++) {
2221         if (info.groupNames[i] != XKB_ATOM_NONE) {
2222             free(UNCONSTIFY(keymap->names->groups[i]));
2223             keymap->names->groups[i] = xkb_atom_strdup(keymap->ctx,
2224                                                        info.groupNames[i]);
2225         }
2226     }
2227
2228     /* sanitize keys */
2229     for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2230         PrepareKeyDef(key);
2231
2232     /* copy! */
2233     for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2234         if (!CopySymbolsDef(keymap, key, 0))
2235             info.errorCount++;
2236
2237     if (warningLevel > 3) {
2238         for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
2239             if (darray_item(keymap->names->keys, i).name[0] == '\0')
2240                 continue;
2241
2242             if (XkbKeyNumGroups(keymap, i) < 1) {
2243                 char buf[5];
2244                 memcpy(buf, darray_item(keymap->names->keys, i).name, 4);
2245                 buf[4] = '\0';
2246                 WARN("No symbols defined for <%s> (keycode %d)\n", buf, i);
2247             }
2248         }
2249     }
2250
2251     if (info.modMap) {
2252         ModMapEntry *mm, *next;
2253         for (mm = info.modMap; mm != NULL; mm = next) {
2254             if (!CopyModMapDef(keymap, mm))
2255                 info.errorCount++;
2256             next = (ModMapEntry *) mm->defs.next;
2257         }
2258     }
2259
2260     FreeSymbolsInfo(&info);
2261     return true;
2262
2263 err_info:
2264     FreeSymbolsInfo(&info);
2265     return false;
2266 }