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