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