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