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