Update xkb->ctrls->num_groups when copying the keysyms
[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 = XkbcInternAtom("ONE_LEVEL", False);
248     tok_TWO_LEVEL = XkbcInternAtom("TWO_LEVEL", False);
249     tok_KEYPAD = XkbcInternAtom("KEYPAD", False);
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, NULL, NULL))
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, NULL, NULL))
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 = XkbcInternAtom(tmp.str, False);
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] = XkbcInternAtom(tmp.str, False);
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 = ExprResolveModMask(value, &tmp, LookupVModMask, (char *) 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, NULL, NULL);
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, NULL, NULL);
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, NULL, NULL);
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, NULL, NULL))
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         XkbcInternAtom(name.str, False);
1408
1409     return True;
1410 }
1411
1412 static int
1413 HandleSymbolsVar(VarDef * stmt, struct xkb_desc * xkb, SymbolsInfo * info)
1414 {
1415     ExprResult elem, field, tmp;
1416     ExprDef *arrayNdx;
1417     Bool ret;
1418
1419     if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1420         return 0;               /* internal error, already reported */
1421     if (elem.str && (uStrCaseCmp(elem.str, "key") == 0))
1422     {
1423         ret = SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1424                               stmt->value, info);
1425     }
1426     else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) ||
1427                                     (uStrCaseCmp(field.str, "groupname") ==
1428                                      0)))
1429     {
1430         ret = SetGroupName(info, arrayNdx, stmt->value);
1431     }
1432     else if ((elem.str == NULL)
1433              && ((uStrCaseCmp(field.str, "groupswrap") == 0)
1434                  || (uStrCaseCmp(field.str, "wrapgroups") == 0)))
1435     {
1436         if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1437         {
1438             ERROR("Illegal setting for global groupsWrap\n");
1439             ACTION("Non-boolean value ignored\n");
1440             ret = False;
1441         }
1442         else {
1443             if (tmp.uval)
1444                 info->groupInfo = XkbWrapIntoRange;
1445             else
1446                 info->groupInfo = XkbClampIntoRange;
1447             ret = True;
1448         }
1449     }
1450     else if ((elem.str == NULL)
1451              && ((uStrCaseCmp(field.str, "groupsclamp") == 0)
1452                  || (uStrCaseCmp(field.str, "clampgroups") == 0)))
1453     {
1454         if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1455         {
1456             ERROR("Illegal setting for global groupsClamp\n");
1457             ACTION("Non-boolean value ignored\n");
1458             return False;
1459         }
1460         else {
1461             if (tmp.uval)
1462                 info->groupInfo = XkbClampIntoRange;
1463             else
1464                 info->groupInfo = XkbWrapIntoRange;
1465             ret = True;
1466         }
1467     }
1468     else if ((elem.str == NULL)
1469              && ((uStrCaseCmp(field.str, "groupsredirect") == 0)
1470                  || (uStrCaseCmp(field.str, "redirectgroups") == 0)))
1471     {
1472         if (!ExprResolveInteger(stmt->value, &tmp,
1473                                 SimpleLookup, (char *) groupNames))
1474         {
1475             ERROR("Illegal group index for global groupsRedirect\n");
1476             ACTION("Definition with non-integer group ignored\n");
1477             ret = False;
1478         }
1479         else {
1480             if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1481             {
1482                 ERROR
1483                     ("Out-of-range (1..%d) group for global groupsRedirect\n",
1484                      XkbNumKbdGroups);
1485                 ACTION("Ignoring illegal group %d\n", tmp.uval);
1486                 ret = False;
1487             }
1488             else {
1489                 info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange,
1490                                                   tmp.uval);
1491                 ret = True;
1492             }
1493         }
1494     }
1495     else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0))
1496     {
1497         ret = SetAllowNone(&info->dflt, arrayNdx, stmt->value);
1498     }
1499     else {
1500         ret = SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1501                              &info->action);
1502     }
1503
1504     free(elem.str);
1505     free(field.str);
1506     return ret;
1507 }
1508
1509 static Bool
1510 HandleSymbolsBody(VarDef * def,
1511                   struct xkb_desc * xkb, KeyInfo * key, SymbolsInfo * info)
1512 {
1513     Bool ok = True;
1514     ExprResult tmp, field;
1515     ExprDef *arrayNdx;
1516
1517     for (; def != NULL; def = (VarDef *) def->common.next)
1518     {
1519         if ((def->name) && (def->name->type == ExprFieldRef))
1520         {
1521             ok = HandleSymbolsVar(def, xkb, info);
1522             continue;
1523         }
1524         else
1525         {
1526             if (def->name == NULL)
1527             {
1528                 if ((def->value == NULL)
1529                     || (def->value->op == ExprKeysymList))
1530                     field.str = "symbols";
1531                 else
1532                     field.str = "actions";
1533                 arrayNdx = NULL;
1534             }
1535             else
1536             {
1537                 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1538             }
1539             if (ok)
1540                 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1541                                      def->value, info);
1542         }
1543     }
1544     return ok;
1545 }
1546
1547 static Bool
1548 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1549 {
1550     unsigned group = info->explicit_group;
1551
1552     if (group == 0)
1553         return True;
1554
1555     if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1556     {
1557         int i;
1558         WARN("For the map %s an explicit group specified\n", info->name);
1559         WARN("but key %s has more than one group defined\n",
1560               longText(key->name));
1561         ACTION("All groups except first one will be ignored\n");
1562         for (i = 1; i < XkbNumKbdGroups; i++)
1563         {
1564             key->numLevels[i] = 0;
1565             if (key->syms[i] != NULL)
1566                 free(key->syms[i]);
1567             key->syms[i] = (uint32_t *) NULL;
1568             if (key->acts[i] != NULL)
1569                 free(key->acts[i]);
1570             key->acts[i] = (union xkb_action *) NULL;
1571             key->types[i] = (uint32_t) 0;
1572         }
1573     }
1574     key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1575
1576     key->numLevels[group] = key->numLevels[0];
1577     key->numLevels[0] = 0;
1578     key->syms[group] = key->syms[0];
1579     key->syms[0] = (uint32_t *) NULL;
1580     key->acts[group] = key->acts[0];
1581     key->acts[0] = (union xkb_action *) NULL;
1582     key->types[group] = key->types[0];
1583     key->types[0] = (uint32_t) 0;
1584     return True;
1585 }
1586
1587 static int
1588 HandleSymbolsDef(SymbolsDef * stmt,
1589                  struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1590 {
1591     KeyInfo key;
1592
1593     InitKeyInfo(&key);
1594     CopyKeyInfo(&info->dflt, &key, False);
1595     key.defs.merge = stmt->merge;
1596     key.name = KeyNameToLong(stmt->keyName);
1597     if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1598     {
1599         info->errorCount++;
1600         return False;
1601     }
1602
1603     if (!SetExplicitGroup(info, &key))
1604     {
1605         info->errorCount++;
1606         return False;
1607     }
1608
1609     if (!AddKeySymbols(info, &key, xkb))
1610     {
1611         info->errorCount++;
1612         return False;
1613     }
1614     return True;
1615 }
1616
1617 static Bool
1618 HandleModMapDef(ModMapDef * def,
1619                 struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1620 {
1621     ExprDef *key;
1622     ModMapEntry tmp;
1623     ExprResult rtrn;
1624     Bool ok;
1625
1626     if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn))
1627     {
1628         ERROR("Illegal modifier map definition\n");
1629         ACTION("Ignoring map for non-modifier \"%s\"\n",
1630                 XkbcAtomText(def->modifier));
1631         return False;
1632     }
1633     ok = True;
1634     tmp.modifier = rtrn.uval;
1635     for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1636     {
1637         if ((key->op == ExprValue) && (key->type == TypeKeyName))
1638         {
1639             tmp.haveSymbol = False;
1640             tmp.u.keyName = KeyNameToLong(key->value.keyName);
1641         }
1642         else if (ExprResolveKeySym(key, &rtrn, NULL, NULL))
1643         {
1644             tmp.haveSymbol = True;
1645             tmp.u.keySym = rtrn.uval;
1646         }
1647         else
1648         {
1649             ERROR("Modmap entries may contain only key names or keysyms\n");
1650             ACTION("Illegal definition for %s modifier ignored\n",
1651                     XkbcModIndexText(tmp.modifier));
1652             continue;
1653         }
1654
1655         ok = AddModMapEntry(info, &tmp) && ok;
1656     }
1657     return ok;
1658 }
1659
1660 static void
1661 HandleSymbolsFile(XkbFile * file,
1662                   struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1663 {
1664     ParseCommon *stmt;
1665
1666     info->name = _XkbDupString(file->name);
1667     stmt = file->defs;
1668     while (stmt)
1669     {
1670         switch (stmt->stmtType)
1671         {
1672         case StmtInclude:
1673             if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1674                                       HandleSymbolsFile))
1675                 info->errorCount++;
1676             break;
1677         case StmtSymbolsDef:
1678             if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1679                 info->errorCount++;
1680             break;
1681         case StmtVarDef:
1682             if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1683                 info->errorCount++;
1684             break;
1685         case StmtVModDef:
1686             if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1687                 info->errorCount++;
1688             break;
1689         case StmtInterpDef:
1690             ERROR("Interpretation files may not include other types\n");
1691             ACTION("Ignoring definition of symbol interpretation\n");
1692             info->errorCount++;
1693             break;
1694         case StmtKeycodeDef:
1695             ERROR("Interpretation files may not include other types\n");
1696             ACTION("Ignoring definition of key name\n");
1697             info->errorCount++;
1698             break;
1699         case StmtModMapDef:
1700             if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1701                 info->errorCount++;
1702             break;
1703         default:
1704             WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1705                   stmt->stmtType);
1706             break;
1707         }
1708         stmt = stmt->next;
1709         if (info->errorCount > 10)
1710         {
1711 #ifdef NOISY
1712             ERROR("Too many errors\n");
1713 #endif
1714             ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1715             break;
1716         }
1717     }
1718     return;
1719 }
1720
1721 static Bool
1722 FindKeyForSymbol(struct xkb_desc * xkb, uint32_t sym, unsigned int *kc_rtrn)
1723 {
1724     register int i, j;
1725     register Bool gotOne;
1726
1727     j = 0;
1728     do
1729     {
1730         gotOne = False;
1731         for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1732         {
1733             if (j < (int) XkbKeyNumSyms(xkb, i))
1734             {
1735                 gotOne = True;
1736                 if ((XkbKeySym(xkb, i, j) == sym))
1737                 {
1738                     *kc_rtrn = i;
1739                     return True;
1740                 }
1741             }
1742         }
1743         j++;
1744     }
1745     while (gotOne);
1746     return False;
1747 }
1748
1749 /**
1750  * Find the given name in the xkb->map->types and return its index.
1751  *
1752  * @param name The atom to search for.
1753  * @param type_rtrn Set to the index of the name if found.
1754  *
1755  * @return True if found, False otherwise.
1756  */
1757 static Bool
1758 FindNamedType(struct xkb_desc * xkb, uint32_t name, unsigned *type_rtrn)
1759 {
1760     register unsigned n;
1761
1762     if (xkb && xkb->map && xkb->map->types)
1763     {
1764         for (n = 0; n < xkb->map->num_types; n++)
1765         {
1766             if (xkb->map->types[n].name == (uint32_t) name)
1767             {
1768                 *type_rtrn = n;
1769                 return True;
1770             }
1771         }
1772     }
1773     return False;
1774 }
1775
1776 /**
1777  * Assign a type to the given sym and return the Atom for the type assigned.
1778  *
1779  * Simple recipe:
1780  * - ONE_LEVEL for width 0/1
1781  * - ALPHABETIC for 2 shift levels, with lower/upercase
1782  * - KEYPAD for keypad keys.
1783  * - TWO_LEVEL for other 2 shift level keys.
1784  * and the same for four level keys.
1785  *
1786  * @param width Number of sysms in syms.
1787  * @param syms The keysyms for the given key (must be size width).
1788  * @param typeNameRtrn Set to the Atom of the type name.
1789  *
1790  * @returns True if a type could be found, False otherwise.
1791  */
1792 static Bool
1793 FindAutomaticType(int width, uint32_t * syms, uint32_t * typeNameRtrn,
1794                   Bool * autoType)
1795 {
1796     *autoType = False;
1797     if ((width == 1) || (width == 0))
1798     {
1799         *typeNameRtrn = XkbcInternAtom("ONE_LEVEL", False);
1800         *autoType = True;
1801     }
1802     else if (width == 2)
1803     {
1804         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1805         {
1806             *typeNameRtrn = XkbcInternAtom("ALPHABETIC", False);
1807         }
1808         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1809         {
1810             *typeNameRtrn = XkbcInternAtom("KEYPAD", False);
1811             *autoType = True;
1812         }
1813         else
1814         {
1815             *typeNameRtrn = XkbcInternAtom("TWO_LEVEL", False);
1816             *autoType = True;
1817         }
1818     }
1819     else if (width <= 4)
1820     {
1821         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1822             if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1823                 *typeNameRtrn =
1824                     XkbcInternAtom("FOUR_LEVEL_ALPHABETIC", False);
1825             else
1826                 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL_SEMIALPHABETIC",
1827                                               False);
1828
1829         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1830             *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL_KEYPAD", False);
1831         else
1832             *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL", False);
1833         /* XXX: why not set autoType here? */
1834     }
1835     return ((width >= 0) && (width <= 4));
1836 }
1837
1838 /**
1839  * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1840  * groups, and reduce to one group if all groups are identical anyway.
1841  */
1842 static void
1843 PrepareKeyDef(KeyInfo * key)
1844 {
1845     int i, j, width, defined, lastGroup;
1846     Bool identical;
1847
1848     defined = key->symsDefined | key->actsDefined | key->typesDefined;
1849     /* get highest group number */
1850     for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1851     {
1852         if (defined & (1 << i))
1853             break;
1854     }
1855     lastGroup = i;
1856
1857     if (lastGroup == 0)
1858         return;
1859
1860     /* If there are empty groups between non-empty ones fill them with data */
1861     /* from the first group. */
1862     /* We can make a wrong assumption here. But leaving gaps is worse. */
1863     for (i = lastGroup; i > 0; i--)
1864     {
1865         if (defined & (1 << i))
1866             continue;
1867         width = key->numLevels[0];
1868         if (key->typesDefined & 1)
1869         {
1870             for (j = 0; j < width; j++)
1871             {
1872                 key->types[i] = key->types[0];
1873             }
1874             key->typesDefined |= 1 << i;
1875         }
1876         if ((key->actsDefined & 1) && key->acts[0])
1877         {
1878             key->acts[i] = uTypedCalloc(width, union xkb_action);
1879             if (key->acts[i] == NULL)
1880                 continue;
1881             memcpy((void *) key->acts[i], (void *) key->acts[0],
1882                    width * sizeof(union xkb_action));
1883             key->actsDefined |= 1 << i;
1884         }
1885         if ((key->symsDefined & 1) && key->syms[0])
1886         {
1887             key->syms[i] = uTypedCalloc(width, uint32_t);
1888             if (key->syms[i] == NULL)
1889                 continue;
1890             memcpy((void *) key->syms[i], (void *) key->syms[0],
1891                    width * sizeof(uint32_t));
1892             key->symsDefined |= 1 << i;
1893         }
1894         if (defined & 1)
1895         {
1896             key->numLevels[i] = key->numLevels[0];
1897         }
1898     }
1899     /* If all groups are completely identical remove them all */
1900     /* exept the first one. */
1901     identical = True;
1902     for (i = lastGroup; i > 0; i--)
1903     {
1904         if ((key->numLevels[i] != key->numLevels[0]) ||
1905             (key->types[i] != key->types[0]))
1906         {
1907             identical = False;
1908             break;
1909         }
1910         if ((key->syms[i] != key->syms[0]) &&
1911             (key->syms[i] == NULL || key->syms[0] == NULL ||
1912              memcmp((void *) key->syms[i], (void *) key->syms[0],
1913                     sizeof(uint32_t) * key->numLevels[0])))
1914         {
1915             identical = False;
1916             break;
1917         }
1918         if ((key->acts[i] != key->acts[0]) &&
1919             (key->acts[i] == NULL || key->acts[0] == NULL ||
1920              memcmp((void *) key->acts[i], (void *) key->acts[0],
1921                     sizeof(union xkb_action) * key->numLevels[0])))
1922         {
1923             identical = False;
1924             break;
1925         }
1926     }
1927     if (identical)
1928     {
1929         for (i = lastGroup; i > 0; i--)
1930         {
1931             key->numLevels[i] = 0;
1932             if (key->syms[i] != NULL)
1933                 free(key->syms[i]);
1934             key->syms[i] = (uint32_t *) NULL;
1935             if (key->acts[i] != NULL)
1936                 free(key->acts[i]);
1937             key->acts[i] = (union xkb_action *) NULL;
1938             key->types[i] = (uint32_t) 0;
1939         }
1940         key->symsDefined &= 1;
1941         key->actsDefined &= 1;
1942         key->typesDefined &= 1;
1943     }
1944     return;
1945 }
1946
1947 /**
1948  * Copy the KeyInfo into the keyboard description.
1949  *
1950  * This function recurses.
1951  */
1952 static Bool
1953 CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from)
1954 {
1955     register int i;
1956     unsigned okc, kc, width, tmp, nGroups;
1957     struct xkb_key_type * type;
1958     Bool haveActions, autoType, useAlias;
1959     uint32_t *outSyms;
1960     union xkb_action *outActs;
1961     unsigned types[XkbNumKbdGroups];
1962
1963     useAlias = (start_from == 0);
1964
1965     /* get the keycode for the key. */
1966     if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1967                       start_from))
1968     {
1969         if ((start_from == 0) && (warningLevel >= 5))
1970         {
1971             WARN("Key %s not found in %s keycodes\n",
1972                   longText(key->name),
1973                   XkbcAtomText(xkb->names->keycodes));
1974             ACTION("Symbols ignored\n");
1975         }
1976         return False;
1977     }
1978
1979     haveActions = False;
1980     for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1981     {
1982         if (((i + 1) > nGroups)
1983             && (((key->symsDefined | key->actsDefined) & (1 << i))
1984                 || (key->typesDefined) & (1 << i)))
1985             nGroups = i + 1;
1986         if (key->acts[i])
1987             haveActions = True;
1988         autoType = False;
1989         /* Assign the type to the key, if it is missing. */
1990         if (key->types[i] == None)
1991         {
1992             if (key->dfltType != None)
1993                 key->types[i] = key->dfltType;
1994             else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1995                                        &key->types[i], &autoType))
1996             {
1997             }
1998             else
1999             {
2000                 if (warningLevel >= 5)
2001                 {
2002                     WARN("No automatic type for %d symbols\n",
2003                           (unsigned int) key->numLevels[i]);
2004                     ACTION("Using %s for the %s key (keycode %d)\n",
2005                             XkbcAtomText(key->types[i]),
2006                             longText(key->name), kc);
2007                 }
2008             }
2009         }
2010         if (FindNamedType(xkb, key->types[i], &types[i]))
2011         {
2012             if (!autoType || key->numLevels[i] > 2)
2013                 xkb->server->explicit[kc] |= (1 << i);
2014         }
2015         else
2016         {
2017             if (warningLevel >= 3)
2018             {
2019                 WARN("Type \"%s\" is not defined\n",
2020                       XkbcAtomText(key->types[i]));
2021                 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
2022                         longText(key->name), kc);
2023             }
2024             types[i] = XkbTwoLevelIndex;
2025         }
2026         /* if the type specifies less syms than the key has, shrink the key */
2027         type = &xkb->map->types[types[i]];
2028         if (type->num_levels < key->numLevels[i])
2029         {
2030             if (warningLevel > 0)
2031             {
2032                 WARN
2033                     ("Type \"%s\" has %d levels, but %s has %d symbols\n",
2034                      XkbcAtomText(type->name),
2035                      (unsigned int) type->num_levels,
2036                      longText(key->name),
2037                      (unsigned int) key->numLevels[i]);
2038                 ACTION("Ignoring extra symbols\n");
2039             }
2040             key->numLevels[i] = type->num_levels;
2041         }
2042         if (key->numLevels[i] > width)
2043             width = key->numLevels[i];
2044         if (type->num_levels > width)
2045             width = type->num_levels;
2046     }
2047
2048     /* width is now the largest width found */
2049
2050     i = width * nGroups;
2051     outSyms = XkbcResizeKeySyms(xkb, kc, i);
2052     if (outSyms == NULL)
2053     {
2054         WSGO("Could not enlarge symbols for %s (keycode %d)\n",
2055               longText(key->name), kc);
2056         return False;
2057     }
2058     if (haveActions)
2059     {
2060         outActs = XkbcResizeKeyActions(xkb, kc, i);
2061         if (outActs == NULL)
2062         {
2063             WSGO("Could not enlarge actions for %s (key %d)\n",
2064                   longText(key->name), kc);
2065             return False;
2066         }
2067         xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
2068     }
2069     else
2070         outActs = NULL;
2071     if (key->defs.defined & _Key_GroupInfo)
2072         i = key->groupInfo;
2073     else
2074         i = xkb->map->key_sym_map[kc].group_info;
2075
2076     xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2077     xkb->map->key_sym_map[kc].width = width;
2078     for (i = 0; i < nGroups; i++)
2079     {
2080         /* assign kt_index[i] to the index of the type in map->types.
2081          * kt_index[i] may have been set by a previous run (if we have two
2082          * layouts specified). Let's not overwrite it with the ONE_LEVEL
2083          * default group if we dont even have keys for this group anyway.
2084          *
2085          * FIXME: There should be a better fix for this.
2086          */
2087         if (key->numLevels[i])
2088             xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2089         if (key->syms[i] != NULL)
2090         {
2091             /* fill key to "width" symbols*/
2092             for (tmp = 0; tmp < width; tmp++)
2093             {
2094                 if (tmp < key->numLevels[i])
2095                     outSyms[tmp] = key->syms[i][tmp];
2096                 else
2097                     outSyms[tmp] = NoSymbol;
2098                 if ((outActs != NULL) && (key->acts[i] != NULL))
2099                 {
2100                     if (tmp < key->numLevels[i])
2101                         outActs[tmp] = key->acts[i][tmp];
2102                     else
2103                         outActs[tmp].type = XkbSA_NoAction;
2104                 }
2105             }
2106         }
2107         outSyms += width;
2108         if (outActs)
2109             outActs += width;
2110     }
2111     switch (key->behavior.type & XkbKB_OpMask)
2112     {
2113     case XkbKB_Default:
2114         break;
2115     case XkbKB_Overlay1:
2116     case XkbKB_Overlay2:
2117         /* find key by name! */
2118         if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True,
2119                           CreateKeyNames(xkb), 0))
2120         {
2121             if (warningLevel >= 1)
2122             {
2123                 WARN("Key %s not found in %s keycodes\n",
2124                       longText(key->nameForOverlayKey),
2125                       XkbcAtomText(xkb->names->keycodes));
2126                 ACTION("Not treating %s as an overlay key \n",
2127                         longText(key->name));
2128             }
2129             break;
2130         }
2131         key->behavior.data = okc;
2132     default:
2133         xkb->server->behaviors[kc] = key->behavior;
2134         xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2135         break;
2136     }
2137     if (key->defs.defined & _Key_VModMap)
2138     {
2139         xkb->server->vmodmap[kc] = key->vmodmap;
2140         xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2141     }
2142     if (key->repeat != RepeatUndefined)
2143     {
2144         if (key->repeat == RepeatYes)
2145             xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2146         else
2147             xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2148         xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2149     }
2150
2151     if (nGroups > xkb->ctrls->num_groups)
2152         xkb->ctrls->num_groups = nGroups;
2153
2154     /* do the same thing for the next key */
2155     CopySymbolsDef(xkb, key, kc + 1);
2156     return True;
2157 }
2158
2159 static Bool
2160 CopyModMapDef(struct xkb_desc * xkb, ModMapEntry *entry)
2161 {
2162     unsigned kc;
2163
2164     if ((!entry->haveSymbol)
2165         &&
2166         (!FindNamedKey
2167          (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
2168     {
2169         if (warningLevel >= 5)
2170         {
2171             WARN("Key %s not found in %s keycodes\n",
2172                   longText(entry->u.keyName),
2173                   XkbcAtomText(xkb->names->keycodes));
2174             ACTION("Modifier map entry for %s not updated\n",
2175                     XkbcModIndexText(entry->modifier));
2176         }
2177         return False;
2178     }
2179     else if (entry->haveSymbol
2180              && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2181     {
2182         if (warningLevel > 5)
2183         {
2184             WARN("Key \"%s\" not found in %s symbol map\n",
2185                   XkbcKeysymText(entry->u.keySym),
2186                   XkbcAtomText(xkb->names->symbols));
2187             ACTION("Modifier map entry for %s not updated\n",
2188                     XkbcModIndexText(entry->modifier));
2189         }
2190         return False;
2191     }
2192     xkb->map->modmap[kc] |= (1 << entry->modifier);
2193     return True;
2194 }
2195
2196 /**
2197  * Handle the xkb_symbols section of an xkb file.
2198  *
2199  * @param file The parsed xkb_symbols section of the xkb file.
2200  * @param xkb Handle to the keyboard description to store the symbols in.
2201  * @param merge Merge strategy (e.g. MergeOverride).
2202  */
2203 Bool
2204 CompileSymbols(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
2205 {
2206     register int i;
2207     SymbolsInfo info;
2208
2209     InitSymbolsInfo(&info, xkb);
2210     info.dflt.defs.fileID = file->id;
2211     info.dflt.defs.merge = merge;
2212     HandleSymbolsFile(file, xkb, merge, &info);
2213
2214     if (info.nKeys == 0)
2215         return True;
2216     if (info.errorCount == 0)
2217     {
2218         KeyInfo *key;
2219
2220         /* alloc memory in the xkb struct */
2221         if (XkbcAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0)
2222             != Success)
2223         {
2224             WSGO("Can not allocate names in CompileSymbols\n");
2225             ACTION("Symbols not added\n");
2226             return False;
2227         }
2228         if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2229             != Success)
2230         {
2231             WSGO("Could not allocate client map in CompileSymbols\n");
2232             ACTION("Symbols not added\n");
2233             return False;
2234         }
2235         if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2236         {
2237             WSGO("Could not allocate server map in CompileSymbols\n");
2238             ACTION("Symbols not added\n");
2239             return False;
2240         }
2241         if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2242         {
2243             WSGO("Could not allocate controls in CompileSymbols\n");
2244             ACTION("Symbols not added\n");
2245             return False;
2246         }
2247
2248         /* now copy info into xkb. */
2249         xkb->names->symbols = XkbcInternAtom(info.name, False);
2250         if (info.aliases)
2251             ApplyAliases(xkb, False, &info.aliases);
2252         for (i = 0; i < XkbNumKbdGroups; i++)
2253         {
2254             if (info.groupNames[i] != None)
2255                 xkb->names->groups[i] = info.groupNames[i];
2256         }
2257         /* sanitize keys */
2258         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2259         {
2260             PrepareKeyDef(key);
2261         }
2262         /* copy! */
2263         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2264         {
2265             if (!CopySymbolsDef(xkb, key, 0))
2266                 info.errorCount++;
2267         }
2268         if (warningLevel > 3)
2269         {
2270             for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2271             {
2272                 if (xkb->names->keys[i].name[0] == '\0')
2273                     continue;
2274                 if (XkbKeyNumGroups(xkb, i) < 1)
2275                 {
2276                     char buf[5];
2277                     memcpy(buf, xkb->names->keys[i].name, 4);
2278                     buf[4] = '\0';
2279                     WARN
2280                         ("No symbols defined for <%s> (keycode %d)\n",
2281                          buf, i);
2282                 }
2283             }
2284         }
2285         if (info.modMap)
2286         {
2287             ModMapEntry *mm, *next;
2288             for (mm = info.modMap; mm != NULL; mm = next)
2289             {
2290                 if (!CopyModMapDef(xkb, mm))
2291                     info.errorCount++;
2292                 next = (ModMapEntry *) mm->defs.next;
2293             }
2294         }
2295         return True;
2296     }
2297     return False;
2298 }