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