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