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