Remove unused global type tokens
[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     }
781     else
782     {
783         info->errorCount += 10;
784         return False;
785     }
786     if ((stmt->next != NULL) && (included.errorCount < 1))
787     {
788         IncludeStmt *next;
789         unsigned op;
790         SymbolsInfo next_incl;
791
792         for (next = stmt->next; next != NULL; next = next->next)
793         {
794             if ((next->file == NULL) && (next->map == NULL))
795             {
796                 haveSelf = True;
797                 MergeIncludedSymbols(&included, info, next->merge, xkb);
798                 FreeSymbolsInfo(info);
799             }
800             else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op))
801             {
802                 InitSymbolsInfo(&next_incl, xkb);
803                 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
804                 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride;
805                 if (next->modifier)
806                 {
807                     next_incl.explicit_group = atoi(next->modifier) - 1;
808                 }
809                 else
810                 {
811                     next_incl.explicit_group = info->explicit_group;
812                 }
813                 (*hndlr) (rtrn, xkb, MergeOverride, &next_incl);
814                 MergeIncludedSymbols(&included, &next_incl, op, xkb);
815                 FreeSymbolsInfo(&next_incl);
816             }
817             else
818             {
819                 info->errorCount += 10;
820                 return False;
821             }
822         }
823     }
824     if (haveSelf)
825         *info = included;
826     else
827     {
828         MergeIncludedSymbols(info, &included, newMerge, xkb);
829         FreeSymbolsInfo(&included);
830     }
831     return (info->errorCount == 0);
832 }
833
834 #define SYMBOLS 1
835 #define ACTIONS 2
836
837 static Bool
838 GetGroupIndex(KeyInfo * key,
839               ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
840 {
841     const char *name;
842     ExprResult tmp;
843
844     if (what == SYMBOLS)
845         name = "symbols";
846     else
847         name = "actions";
848
849     if (arrayNdx == NULL)
850     {
851         int i;
852         unsigned defined;
853         if (what == SYMBOLS)
854             defined = key->symsDefined;
855         else
856             defined = key->actsDefined;
857
858         for (i = 0; i < XkbNumKbdGroups; i++)
859         {
860             if ((defined & (1 << i)) == 0)
861             {
862                 *ndx_rtrn = i;
863                 return True;
864             }
865         }
866         ERROR("Too many groups of %s for key %s (max %d)\n", name,
867                longText(key->name), XkbNumKbdGroups + 1);
868         ACTION("Ignoring %s defined for extra groups\n", name);
869         return False;
870     }
871     if (!ExprResolveGroup(arrayNdx, &tmp))
872     {
873         ERROR("Illegal group index for %s of key %s\n", name,
874                longText(key->name));
875         ACTION("Definition with non-integer array index ignored\n");
876         return False;
877     }
878     *ndx_rtrn = tmp.uval - 1;
879     return True;
880 }
881
882 static Bool
883 AddSymbolsToKey(KeyInfo * key,
884                 struct xkb_desc * xkb,
885                 char *field,
886                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
887 {
888     unsigned ndx, nSyms;
889     int i;
890
891     if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx))
892         return False;
893     if (value == NULL)
894     {
895         key->symsDefined |= (1 << ndx);
896         return True;
897     }
898     if (value->op != ExprKeysymList)
899     {
900         ERROR("Expected a list of symbols, found %s\n",
901                exprOpText(value->op));
902         ACTION("Ignoring symbols for group %d of %s\n", ndx,
903                 longText(key->name));
904         return False;
905     }
906     if (key->syms[ndx] != NULL)
907     {
908         WSGO("Symbols for key %s, group %d already defined\n",
909               longText(key->name), ndx);
910         return False;
911     }
912     nSyms = value->value.list.nSyms;
913     if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
914         (!ResizeKeyGroup(key, ndx, nSyms, False)))
915     {
916         WSGO("Could not resize group %d of key %s\n", ndx,
917               longText(key->name));
918         ACTION("Symbols lost\n");
919         return False;
920     }
921     key->symsDefined |= (1 << ndx);
922     for (i = 0; i < nSyms; i++) {
923         if (!LookupKeysym(value->value.list.syms[i], &key->syms[ndx][i])) {
924             WSGO("Could not resolve keysym %s\n", value->value.list.syms[i]);
925             key->syms[ndx][i] = NoSymbol;
926         }
927     }
928     for (i = key->numLevels[ndx] - 1;
929          (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--)
930     {
931         key->numLevels[ndx]--;
932     }
933     return True;
934 }
935
936 static Bool
937 AddActionsToKey(KeyInfo * key,
938                 struct xkb_desc * xkb,
939                 char *field,
940                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
941 {
942     int i;
943     unsigned ndx, nActs;
944     ExprDef *act;
945     struct xkb_any_action *toAct;
946
947     if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx))
948         return False;
949
950     if (value == NULL)
951     {
952         key->actsDefined |= (1 << ndx);
953         return True;
954     }
955     if (value->op != ExprActionList)
956     {
957         WSGO("Bad expression type (%d) for action list value\n", value->op);
958         ACTION("Ignoring actions for group %d of %s\n", ndx,
959                 longText(key->name));
960         return False;
961     }
962     if (key->acts[ndx] != NULL)
963     {
964         WSGO("Actions for key %s, group %d already defined\n",
965               longText(key->name), ndx);
966         return False;
967     }
968     for (nActs = 0, act = value->value.child; act != NULL; nActs++)
969     {
970         act = (ExprDef *) act->common.next;
971     }
972     if (nActs < 1)
973     {
974         WSGO("Action list but not actions in AddActionsToKey\n");
975         return False;
976     }
977     if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
978         (!ResizeKeyGroup(key, ndx, nActs, True)))
979     {
980         WSGO("Could not resize group %d of key %s\n", ndx,
981               longText(key->name));
982         ACTION("Actions lost\n");
983         return False;
984     }
985     key->actsDefined |= (1 << ndx);
986
987     toAct = (struct xkb_any_action *) key->acts[ndx];
988     act = value->value.child;
989     for (i = 0; i < nActs; i++, toAct++)
990     {
991         if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action))
992         {
993             ERROR("Illegal action definition for %s\n",
994                    longText(key->name));
995             ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
996         }
997         act = (ExprDef *) act->common.next;
998     }
999     return True;
1000 }
1001
1002 static int
1003 SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value)
1004 {
1005     ExprResult tmp;
1006     unsigned radio_groups = 0;
1007
1008     if (arrayNdx == NULL)
1009     {
1010         radio_groups = XkbAllRadioGroupsMask;
1011     }
1012     else
1013     {
1014         if (!ExprResolveRadioGroup(arrayNdx, &tmp))
1015         {
1016             ERROR("Illegal index in group name definition\n");
1017             ACTION("Definition with non-integer array index ignored\n");
1018             return False;
1019         }
1020         if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1021         {
1022             ERROR("Illegal radio group specified (must be 1..%d)\n",
1023                    XkbMaxRadioGroups + 1);
1024             ACTION("Value of \"allow none\" for group %d ignored\n",
1025                     tmp.uval);
1026             return False;
1027         }
1028         radio_groups |= (1 << (tmp.uval - 1));
1029     }
1030     if (!ExprResolveBoolean(value, &tmp))
1031     {
1032         ERROR("Illegal \"allow none\" value for %s\n",
1033                longText(key->name));
1034         ACTION("Non-boolean value ignored\n");
1035         return False;
1036     }
1037     if (tmp.uval)
1038         key->allowNone |= radio_groups;
1039     else
1040         key->allowNone &= ~radio_groups;
1041     return True;
1042 }
1043
1044
1045 static const LookupEntry lockingEntries[] = {
1046     {"true", XkbKB_Lock},
1047     {"yes", XkbKB_Lock},
1048     {"on", XkbKB_Lock},
1049     {"false", XkbKB_Default},
1050     {"no", XkbKB_Default},
1051     {"off", XkbKB_Default},
1052     {"permanent", XkbKB_Lock | XkbKB_Permanent},
1053     {NULL, 0}
1054 };
1055
1056 static const LookupEntry repeatEntries[] = {
1057     {"true", RepeatYes},
1058     {"yes", RepeatYes},
1059     {"on", RepeatYes},
1060     {"false", RepeatNo},
1061     {"no", RepeatNo},
1062     {"off", RepeatNo},
1063     {"default", RepeatUndefined},
1064     {NULL, 0}
1065 };
1066
1067 static Bool
1068 SetSymbolsField(KeyInfo * key,
1069                 struct xkb_desc * xkb,
1070                 char *field,
1071                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1072 {
1073     Bool ok = True;
1074     ExprResult tmp;
1075
1076     if (uStrCaseCmp(field, "type") == 0)
1077     {
1078         ExprResult ndx;
1079         if ((!ExprResolveString(value, &tmp))
1080             && (warningLevel > 0))
1081         {
1082             WARN("The type field of a key symbol map must be a string\n");
1083             ACTION("Ignoring illegal type definition\n");
1084         }
1085         if (arrayNdx == NULL)
1086         {
1087             key->dfltType = xkb_intern_atom(tmp.str);
1088             key->defs.defined |= _Key_Type_Dflt;
1089         }
1090         else if (!ExprResolveGroup(arrayNdx, &ndx))
1091         {
1092             ERROR("Illegal group index for type of key %s\n",
1093                    longText(key->name));
1094             ACTION("Definition with non-integer array index ignored\n");
1095             free(tmp.str);
1096             return False;
1097         }
1098         else
1099         {
1100             key->types[ndx.uval - 1] = xkb_intern_atom(tmp.str);
1101             key->typesDefined |= (1 << (ndx.uval - 1));
1102         }
1103         free(tmp.str);
1104     }
1105     else if (uStrCaseCmp(field, "symbols") == 0)
1106         return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1107     else if (uStrCaseCmp(field, "actions") == 0)
1108         return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1109     else if ((uStrCaseCmp(field, "vmods") == 0) ||
1110              (uStrCaseCmp(field, "virtualmods") == 0) ||
1111              (uStrCaseCmp(field, "virtualmodifiers") == 0))
1112     {
1113         ok = ExprResolveVModMask(value, &tmp, xkb);
1114         if (ok)
1115         {
1116             key->vmodmap = (tmp.uval >> 8);
1117             key->defs.defined |= _Key_VModMap;
1118         }
1119         else
1120         {
1121             ERROR("Expected a virtual modifier mask, found %s\n",
1122                    exprOpText(value->op));
1123             ACTION("Ignoring virtual modifiers definition for key %s\n",
1124                     longText(key->name));
1125         }
1126     }
1127     else if ((uStrCaseCmp(field, "locking") == 0)
1128              || (uStrCaseCmp(field, "lock") == 0)
1129              || (uStrCaseCmp(field, "locks") == 0))
1130     {
1131         ok = ExprResolveEnum(value, &tmp, lockingEntries);
1132         if (ok)
1133             key->behavior.type = tmp.uval;
1134         key->defs.defined |= _Key_Behavior;
1135     }
1136     else if ((uStrCaseCmp(field, "radiogroup") == 0) ||
1137              (uStrCaseCmp(field, "permanentradiogroup") == 0))
1138     {
1139         Bool permanent = False;
1140         if (uStrCaseCmp(field, "permanentradiogroup") == 0)
1141             permanent = True;
1142         if (ExprResolveString(value, &tmp)) {
1143             ok = (strcmp(tmp.str, "none") == 0);
1144             free(tmp.str);
1145             if (ok)
1146                 tmp.uval = 0;
1147         }
1148         else {
1149             ok = ExprResolveInteger(value, &tmp);
1150         }
1151         if (!ok)
1152         {
1153             ERROR("Illegal radio group specification for %s\n",
1154                   longText(key->name));
1155             ACTION("Non-integer radio group ignored\n");
1156             return False;
1157         }
1158         if (tmp.uval == 0)
1159         {
1160             key->behavior.type = XkbKB_Default;
1161             key->behavior.data = 0;
1162             return ok;
1163         }
1164         if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1165         {
1166             ERROR
1167                 ("Radio group specification for %s out of range (1..32)\n",
1168                  longText(key->name));
1169             ACTION("Illegal radio group %d ignored\n", tmp.uval);
1170             return False;
1171         }
1172         key->behavior.type =
1173             XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0);
1174         key->behavior.data = tmp.uval - 1;
1175         if (key->allowNone & (1 << (tmp.uval - 1)))
1176             key->behavior.data |= XkbKB_RGAllowNone;
1177         key->defs.defined |= _Key_Behavior;
1178     }
1179     else if (uStrCaseEqual(field, "allownone"))
1180     {
1181         ok = SetAllowNone(key, arrayNdx, value);
1182     }
1183     else if (uStrCasePrefix("overlay", field) ||
1184              uStrCasePrefix("permanentoverlay", field))
1185     {
1186         Bool permanent = False;
1187         char *which;
1188         int overlayNdx;
1189         if (uStrCasePrefix("permanent", field))
1190         {
1191             permanent = True;
1192             which = &field[sizeof("permanentoverlay") - 1];
1193         }
1194         else
1195         {
1196             which = &field[sizeof("overlay") - 1];
1197         }
1198         if (sscanf(which, "%d", &overlayNdx) == 1)
1199         {
1200             if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0))
1201             {
1202                 ERROR("Illegal overlay %d specified for %s\n",
1203                        overlayNdx, longText(key->name));
1204                 ACTION("Ignored\n");
1205                 return False;
1206             }
1207         }
1208         else if (*which == '\0')
1209             overlayNdx = 1;
1210         else if (warningLevel > 0)
1211         {
1212             ERROR("Illegal overlay \"%s\" specified for %s\n",
1213                    which, longText(key->name));
1214             ACTION("Ignored\n");
1215             return False;
1216         }
1217         ok = ExprResolveKeyName(value, &tmp);
1218         if (!ok)
1219         {
1220             ERROR("Illegal overlay key specification for %s\n",
1221                    longText(key->name));
1222             ACTION("Overlay key must be specified by name\n");
1223             return False;
1224         }
1225         if (overlayNdx == 1)
1226             key->behavior.type = XkbKB_Overlay1;
1227         else
1228             key->behavior.type = XkbKB_Overlay2;
1229         if (permanent)
1230             key->behavior.type |= XkbKB_Permanent;
1231
1232         key->behavior.data = 0;
1233         key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name);
1234         key->defs.defined |= _Key_Behavior;
1235     }
1236     else if ((uStrCaseCmp(field, "repeating") == 0) ||
1237              (uStrCaseCmp(field, "repeats") == 0) ||
1238              (uStrCaseCmp(field, "repeat") == 0))
1239     {
1240         ok = ExprResolveEnum(value, &tmp, repeatEntries);
1241         if (!ok)
1242         {
1243             ERROR("Illegal repeat setting for %s\n",
1244                    longText(key->name));
1245             ACTION("Non-boolean repeat setting ignored\n");
1246             return False;
1247         }
1248         key->repeat = tmp.uval;
1249         key->defs.defined |= _Key_Repeat;
1250     }
1251     else if ((uStrCaseCmp(field, "groupswrap") == 0) ||
1252              (uStrCaseCmp(field, "wrapgroups") == 0))
1253     {
1254         ok = ExprResolveBoolean(value, &tmp);
1255         if (!ok)
1256         {
1257             ERROR("Illegal groupsWrap setting for %s\n",
1258                    longText(key->name));
1259             ACTION("Non-boolean value ignored\n");
1260             return False;
1261         }
1262         if (tmp.uval)
1263             key->groupInfo = XkbWrapIntoRange;
1264         else
1265             key->groupInfo = XkbClampIntoRange;
1266         key->defs.defined |= _Key_GroupInfo;
1267     }
1268     else if ((uStrCaseCmp(field, "groupsclamp") == 0) ||
1269              (uStrCaseCmp(field, "clampgroups") == 0))
1270     {
1271         ok = ExprResolveBoolean(value, &tmp);
1272         if (!ok)
1273         {
1274             ERROR("Illegal groupsClamp setting for %s\n",
1275                    longText(key->name));
1276             ACTION("Non-boolean value ignored\n");
1277             return False;
1278         }
1279         if (tmp.uval)
1280             key->groupInfo = XkbClampIntoRange;
1281         else
1282             key->groupInfo = XkbWrapIntoRange;
1283         key->defs.defined |= _Key_GroupInfo;
1284     }
1285     else if ((uStrCaseCmp(field, "groupsredirect") == 0) ||
1286              (uStrCaseCmp(field, "redirectgroups") == 0))
1287     {
1288         if (!ExprResolveGroup(value, &tmp))
1289         {
1290             ERROR("Illegal group index for redirect of key %s\n",
1291                    longText(key->name));
1292             ACTION("Definition with non-integer group ignored\n");
1293             return False;
1294         }
1295         key->groupInfo =
1296             XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1297         key->defs.defined |= _Key_GroupInfo;
1298     }
1299     else
1300     {
1301         ERROR("Unknown field %s in a symbol interpretation\n", field);
1302         ACTION("Definition ignored\n");
1303         ok = False;
1304     }
1305     return ok;
1306 }
1307
1308 static int
1309 SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1310 {
1311     ExprResult tmp, name;
1312
1313     if ((arrayNdx == NULL) && (warningLevel > 0))
1314     {
1315         WARN("You must specify an index when specifying a group name\n");
1316         ACTION("Group name definition without array subscript ignored\n");
1317         return False;
1318     }
1319     if (!ExprResolveGroup(arrayNdx, &tmp))
1320     {
1321         ERROR("Illegal index in group name definition\n");
1322         ACTION("Definition with non-integer array index ignored\n");
1323         return False;
1324     }
1325     if (!ExprResolveString(value, &name))
1326     {
1327         ERROR("Group name must be a string\n");
1328         ACTION("Illegal name for group %d ignored\n", tmp.uval);
1329         return False;
1330     }
1331     info->groupNames[tmp.uval - 1 + info->explicit_group] =
1332         xkb_intern_atom(name.str);
1333     free(name.str);
1334
1335     return True;
1336 }
1337
1338 static int
1339 HandleSymbolsVar(VarDef * stmt, struct xkb_desc * xkb, SymbolsInfo * info)
1340 {
1341     ExprResult elem, field, tmp;
1342     ExprDef *arrayNdx;
1343     Bool ret;
1344
1345     if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1346         return 0;               /* internal error, already reported */
1347     if (elem.str && (uStrCaseCmp(elem.str, "key") == 0))
1348     {
1349         ret = SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1350                               stmt->value, info);
1351     }
1352     else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) ||
1353                                     (uStrCaseCmp(field.str, "groupname") ==
1354                                      0)))
1355     {
1356         ret = SetGroupName(info, arrayNdx, stmt->value);
1357     }
1358     else if ((elem.str == NULL)
1359              && ((uStrCaseCmp(field.str, "groupswrap") == 0)
1360                  || (uStrCaseCmp(field.str, "wrapgroups") == 0)))
1361     {
1362         if (!ExprResolveBoolean(stmt->value, &tmp))
1363         {
1364             ERROR("Illegal setting for global groupsWrap\n");
1365             ACTION("Non-boolean value ignored\n");
1366             ret = False;
1367         }
1368         else {
1369             if (tmp.uval)
1370                 info->groupInfo = XkbWrapIntoRange;
1371             else
1372                 info->groupInfo = XkbClampIntoRange;
1373             ret = True;
1374         }
1375     }
1376     else if ((elem.str == NULL)
1377              && ((uStrCaseCmp(field.str, "groupsclamp") == 0)
1378                  || (uStrCaseCmp(field.str, "clampgroups") == 0)))
1379     {
1380         if (!ExprResolveBoolean(stmt->value, &tmp))
1381         {
1382             ERROR("Illegal setting for global groupsClamp\n");
1383             ACTION("Non-boolean value ignored\n");
1384             return False;
1385         }
1386         else {
1387             if (tmp.uval)
1388                 info->groupInfo = XkbClampIntoRange;
1389             else
1390                 info->groupInfo = XkbWrapIntoRange;
1391             ret = True;
1392         }
1393     }
1394     else if ((elem.str == NULL)
1395              && ((uStrCaseCmp(field.str, "groupsredirect") == 0)
1396                  || (uStrCaseCmp(field.str, "redirectgroups") == 0)))
1397     {
1398         if (!ExprResolveGroup(stmt->value, &tmp))
1399         {
1400             ERROR("Illegal group index for global groupsRedirect\n");
1401             ACTION("Definition with non-integer group ignored\n");
1402             ret = False;
1403         }
1404         else {
1405             info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange,
1406                                               tmp.uval);
1407             ret = True;
1408         }
1409     }
1410     else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0))
1411     {
1412         ret = SetAllowNone(&info->dflt, arrayNdx, stmt->value);
1413     }
1414     else {
1415         ret = SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1416                              &info->action);
1417     }
1418
1419     free(elem.str);
1420     free(field.str);
1421     return ret;
1422 }
1423
1424 static Bool
1425 HandleSymbolsBody(VarDef * def,
1426                   struct xkb_desc * xkb, KeyInfo * key, SymbolsInfo * info)
1427 {
1428     Bool ok = True;
1429     ExprResult tmp, field;
1430     ExprDef *arrayNdx;
1431
1432     for (; def != NULL; def = (VarDef *) def->common.next)
1433     {
1434         if ((def->name) && (def->name->type == ExprFieldRef))
1435         {
1436             ok = HandleSymbolsVar(def, xkb, info);
1437             continue;
1438         }
1439         else
1440         {
1441             if (def->name == NULL)
1442             {
1443                 if ((def->value == NULL)
1444                     || (def->value->op == ExprKeysymList))
1445                     field.str = strdup("symbols");
1446                 else
1447                     field.str = strdup("actions");
1448                 arrayNdx = NULL;
1449             }
1450             else
1451             {
1452                 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1453             }
1454             if (ok)
1455                 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1456                                      def->value, info);
1457             free(field.str);
1458         }
1459     }
1460     return ok;
1461 }
1462
1463 static Bool
1464 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1465 {
1466     unsigned group = info->explicit_group;
1467
1468     if (group == 0)
1469         return True;
1470
1471     if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1472     {
1473         int i;
1474         WARN("For the map %s an explicit group specified\n", info->name);
1475         WARN("but key %s has more than one group defined\n",
1476               longText(key->name));
1477         ACTION("All groups except first one will be ignored\n");
1478         for (i = 1; i < XkbNumKbdGroups; i++)
1479         {
1480             key->numLevels[i] = 0;
1481             free(key->syms[i]);
1482             key->syms[i] = NULL;
1483             free(key->acts[i]);
1484             key->acts[i] = NULL;
1485             key->types[i] = 0;
1486         }
1487     }
1488     key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1489
1490     key->numLevels[group] = key->numLevels[0];
1491     key->numLevels[0] = 0;
1492     key->syms[group] = key->syms[0];
1493     key->syms[0] = NULL;
1494     key->acts[group] = key->acts[0];
1495     key->acts[0] = NULL;
1496     key->types[group] = key->types[0];
1497     key->types[0] = 0;
1498     return True;
1499 }
1500
1501 static int
1502 HandleSymbolsDef(SymbolsDef * stmt,
1503                  struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1504 {
1505     KeyInfo key;
1506
1507     InitKeyInfo(&key);
1508     CopyKeyInfo(&info->dflt, &key, False);
1509     key.defs.merge = stmt->merge;
1510     key.name = KeyNameToLong(stmt->keyName);
1511     if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1512     {
1513         info->errorCount++;
1514         return False;
1515     }
1516
1517     if (!SetExplicitGroup(info, &key))
1518     {
1519         info->errorCount++;
1520         return False;
1521     }
1522
1523     if (!AddKeySymbols(info, &key, xkb))
1524     {
1525         info->errorCount++;
1526         return False;
1527     }
1528     return True;
1529 }
1530
1531 static Bool
1532 HandleModMapDef(ModMapDef * def,
1533                 struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1534 {
1535     ExprDef *key;
1536     ModMapEntry tmp;
1537     ExprResult rtrn;
1538     Bool ok;
1539
1540     if (!LookupModIndex(NULL, def->modifier, TypeInt, &rtrn))
1541     {
1542         ERROR("Illegal modifier map definition\n");
1543         ACTION("Ignoring map for non-modifier \"%s\"\n",
1544                 XkbcAtomText(def->modifier));
1545         return False;
1546     }
1547     ok = True;
1548     tmp.modifier = rtrn.uval;
1549     for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1550     {
1551         if ((key->op == ExprValue) && (key->type == TypeKeyName))
1552         {
1553             tmp.haveSymbol = False;
1554             tmp.u.keyName = KeyNameToLong(key->value.keyName);
1555         }
1556         else if (ExprResolveKeySym(key, &rtrn))
1557         {
1558             tmp.haveSymbol = True;
1559             tmp.u.keySym = rtrn.uval;
1560         }
1561         else
1562         {
1563             ERROR("Modmap entries may contain only key names or keysyms\n");
1564             ACTION("Illegal definition for %s modifier ignored\n",
1565                     XkbcModIndexText(tmp.modifier));
1566             continue;
1567         }
1568
1569         ok = AddModMapEntry(info, &tmp) && ok;
1570     }
1571     return ok;
1572 }
1573
1574 static void
1575 HandleSymbolsFile(XkbFile * file,
1576                   struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1577 {
1578     ParseCommon *stmt;
1579
1580     info->name = _XkbDupString(file->name);
1581     stmt = file->defs;
1582     while (stmt)
1583     {
1584         switch (stmt->stmtType)
1585         {
1586         case StmtInclude:
1587             if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1588                                       HandleSymbolsFile))
1589                 info->errorCount++;
1590             break;
1591         case StmtSymbolsDef:
1592             if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1593                 info->errorCount++;
1594             break;
1595         case StmtVarDef:
1596             if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1597                 info->errorCount++;
1598             break;
1599         case StmtVModDef:
1600             if (!HandleVModDef((VModDef *) stmt, xkb, merge, &info->vmods))
1601                 info->errorCount++;
1602             break;
1603         case StmtInterpDef:
1604             ERROR("Interpretation files may not include other types\n");
1605             ACTION("Ignoring definition of symbol interpretation\n");
1606             info->errorCount++;
1607             break;
1608         case StmtKeycodeDef:
1609             ERROR("Interpretation files may not include other types\n");
1610             ACTION("Ignoring definition of key name\n");
1611             info->errorCount++;
1612             break;
1613         case StmtModMapDef:
1614             if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1615                 info->errorCount++;
1616             break;
1617         default:
1618             WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1619                   stmt->stmtType);
1620             break;
1621         }
1622         stmt = stmt->next;
1623         if (info->errorCount > 10)
1624         {
1625 #ifdef NOISY
1626             ERROR("Too many errors\n");
1627 #endif
1628             ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1629             break;
1630         }
1631     }
1632 }
1633
1634 static Bool
1635 FindKeyForSymbol(struct xkb_desc * xkb, uint32_t sym, xkb_keycode_t *kc_rtrn)
1636 {
1637     int i, j;
1638     Bool gotOne;
1639
1640     j = 0;
1641     do
1642     {
1643         gotOne = False;
1644         for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1645         {
1646             if (j < (int) XkbKeyNumSyms(xkb, i))
1647             {
1648                 gotOne = True;
1649                 if (XkbKeySym(xkb, i, j) == sym)
1650                 {
1651                     *kc_rtrn = i;
1652                     return True;
1653                 }
1654             }
1655         }
1656         j++;
1657     }
1658     while (gotOne);
1659     return False;
1660 }
1661
1662 /**
1663  * Find the given name in the xkb->map->types and return its index.
1664  *
1665  * @param name The atom to search for.
1666  * @param type_rtrn Set to the index of the name if found.
1667  *
1668  * @return True if found, False otherwise.
1669  */
1670 static Bool
1671 FindNamedType(struct xkb_desc * xkb, uint32_t name, unsigned *type_rtrn)
1672 {
1673     unsigned n;
1674
1675     if (xkb && xkb->map && xkb->map->types)
1676     {
1677         for (n = 0; n < xkb->map->num_types; n++)
1678         {
1679             if (xkb->map->types[n].name == (uint32_t) name)
1680             {
1681                 *type_rtrn = n;
1682                 return True;
1683             }
1684         }
1685     }
1686     return False;
1687 }
1688
1689 /**
1690  * Assign a type to the given sym and return the Atom for the type assigned.
1691  *
1692  * Simple recipe:
1693  * - ONE_LEVEL for width 0/1
1694  * - ALPHABETIC for 2 shift levels, with lower/upercase
1695  * - KEYPAD for keypad keys.
1696  * - TWO_LEVEL for other 2 shift level keys.
1697  * and the same for four level keys.
1698  *
1699  * @param width Number of sysms in syms.
1700  * @param syms The keysyms for the given key (must be size width).
1701  * @param typeNameRtrn Set to the Atom of the type name.
1702  *
1703  * @returns True if a type could be found, False otherwise.
1704  */
1705 static Bool
1706 FindAutomaticType(int width, uint32_t * syms, uint32_t * typeNameRtrn,
1707                   Bool * autoType)
1708 {
1709     *autoType = False;
1710     if ((width == 1) || (width == 0))
1711     {
1712         *typeNameRtrn = xkb_intern_atom("ONE_LEVEL");
1713         *autoType = True;
1714     }
1715     else if (width == 2)
1716     {
1717         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1718         {
1719             *typeNameRtrn = xkb_intern_atom("ALPHABETIC");
1720         }
1721         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1722         {
1723             *typeNameRtrn = xkb_intern_atom("KEYPAD");
1724             *autoType = True;
1725         }
1726         else
1727         {
1728             *typeNameRtrn = xkb_intern_atom("TWO_LEVEL");
1729             *autoType = True;
1730         }
1731     }
1732     else if (width <= 4)
1733     {
1734         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1735             if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1736                 *typeNameRtrn =
1737                     xkb_intern_atom("FOUR_LEVEL_ALPHABETIC");
1738             else
1739                 *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_SEMIALPHABETIC");
1740
1741         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1742             *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_KEYPAD");
1743         else
1744             *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL");
1745         /* XXX: why not set autoType here? */
1746     }
1747     return ((width >= 0) && (width <= 4));
1748 }
1749
1750 /**
1751  * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1752  * groups, and reduce to one group if all groups are identical anyway.
1753  */
1754 static void
1755 PrepareKeyDef(KeyInfo * key)
1756 {
1757     int i, j, width, defined, lastGroup;
1758     Bool identical;
1759
1760     defined = key->symsDefined | key->actsDefined | key->typesDefined;
1761     /* get highest group number */
1762     for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1763     {
1764         if (defined & (1 << i))
1765             break;
1766     }
1767     lastGroup = i;
1768
1769     if (lastGroup == 0)
1770         return;
1771
1772     /* If there are empty groups between non-empty ones fill them with data */
1773     /* from the first group. */
1774     /* We can make a wrong assumption here. But leaving gaps is worse. */
1775     for (i = lastGroup; i > 0; i--)
1776     {
1777         if (defined & (1 << i))
1778             continue;
1779         width = key->numLevels[0];
1780         if (key->typesDefined & 1)
1781         {
1782             for (j = 0; j < width; j++)
1783             {
1784                 key->types[i] = key->types[0];
1785             }
1786             key->typesDefined |= 1 << i;
1787         }
1788         if ((key->actsDefined & 1) && key->acts[0])
1789         {
1790             key->acts[i] = uTypedCalloc(width, union xkb_action);
1791             if (key->acts[i] == NULL)
1792                 continue;
1793             memcpy(key->acts[i], key->acts[0],
1794                    width * sizeof(union xkb_action));
1795             key->actsDefined |= 1 << i;
1796         }
1797         if ((key->symsDefined & 1) && key->syms[0])
1798         {
1799             key->syms[i] = uTypedCalloc(width, uint32_t);
1800             if (key->syms[i] == NULL)
1801                 continue;
1802             memcpy(key->syms[i], key->syms[0], width * sizeof(uint32_t));
1803             key->symsDefined |= 1 << i;
1804         }
1805         if (defined & 1)
1806         {
1807             key->numLevels[i] = key->numLevels[0];
1808         }
1809     }
1810     /* If all groups are completely identical remove them all */
1811     /* exept the first one. */
1812     identical = True;
1813     for (i = lastGroup; i > 0; i--)
1814     {
1815         if ((key->numLevels[i] != key->numLevels[0]) ||
1816             (key->types[i] != key->types[0]))
1817         {
1818             identical = False;
1819             break;
1820         }
1821         if ((key->syms[i] != key->syms[0]) &&
1822             (key->syms[i] == NULL || key->syms[0] == NULL ||
1823              memcmp(key->syms[i], key->syms[0],
1824                     sizeof(uint32_t) * key->numLevels[0])))
1825         {
1826             identical = False;
1827             break;
1828         }
1829         if ((key->acts[i] != key->acts[0]) &&
1830             (key->acts[i] == NULL || key->acts[0] == NULL ||
1831              memcmp(key->acts[i], key->acts[0],
1832                     sizeof(union xkb_action) * key->numLevels[0])))
1833         {
1834             identical = False;
1835             break;
1836         }
1837     }
1838     if (identical)
1839     {
1840         for (i = lastGroup; i > 0; i--)
1841         {
1842             key->numLevels[i] = 0;
1843             free(key->syms[i]);
1844             key->syms[i] = NULL;
1845             free(key->acts[i]);
1846             key->acts[i] = NULL;
1847             key->types[i] = 0;
1848         }
1849         key->symsDefined &= 1;
1850         key->actsDefined &= 1;
1851         key->typesDefined &= 1;
1852     }
1853 }
1854
1855 /**
1856  * Copy the KeyInfo into the keyboard description.
1857  *
1858  * This function recurses.
1859  */
1860 static Bool
1861 CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from)
1862 {
1863     int i;
1864     xkb_keycode_t okc, kc;
1865     unsigned width, tmp, nGroups;
1866     struct xkb_key_type * type;
1867     Bool haveActions, autoType, useAlias;
1868     uint32_t *outSyms;
1869     union xkb_action *outActs;
1870     unsigned types[XkbNumKbdGroups];
1871
1872     useAlias = (start_from == 0);
1873
1874     /* get the keycode for the key. */
1875     if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1876                       start_from))
1877     {
1878         if ((start_from == 0) && (warningLevel >= 5))
1879         {
1880             WARN("Key %s not found in %s keycodes\n",
1881                   longText(key->name),
1882                   XkbcAtomText(xkb->names->keycodes));
1883             ACTION("Symbols ignored\n");
1884         }
1885         return False;
1886     }
1887
1888     haveActions = False;
1889     for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1890     {
1891         if (((i + 1) > nGroups)
1892             && (((key->symsDefined | key->actsDefined) & (1 << i))
1893                 || (key->typesDefined) & (1 << i)))
1894             nGroups = i + 1;
1895         if (key->acts[i])
1896             haveActions = True;
1897         autoType = False;
1898         /* Assign the type to the key, if it is missing. */
1899         if (key->types[i] == None)
1900         {
1901             if (key->dfltType != None)
1902                 key->types[i] = key->dfltType;
1903             else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1904                                        &key->types[i], &autoType))
1905             {
1906             }
1907             else
1908             {
1909                 if (warningLevel >= 5)
1910                 {
1911                     WARN("No automatic type for %d symbols\n",
1912                           (unsigned int) key->numLevels[i]);
1913                     ACTION("Using %s for the %s key (keycode %d)\n",
1914                             XkbcAtomText(key->types[i]),
1915                             longText(key->name), kc);
1916                 }
1917             }
1918         }
1919         if (FindNamedType(xkb, key->types[i], &types[i]))
1920         {
1921             if (!autoType || key->numLevels[i] > 2)
1922                 xkb->server->explicit[kc] |= (1 << i);
1923         }
1924         else
1925         {
1926             if (warningLevel >= 3)
1927             {
1928                 WARN("Type \"%s\" is not defined\n",
1929                       XkbcAtomText(key->types[i]));
1930                 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
1931                         longText(key->name), kc);
1932             }
1933             types[i] = XkbTwoLevelIndex;
1934         }
1935         /* if the type specifies less syms than the key has, shrink the key */
1936         type = &xkb->map->types[types[i]];
1937         if (type->num_levels < key->numLevels[i])
1938         {
1939             if (warningLevel > 0)
1940             {
1941                 WARN
1942                     ("Type \"%s\" has %d levels, but %s has %d symbols\n",
1943                      XkbcAtomText(type->name),
1944                      (unsigned int) type->num_levels,
1945                      longText(key->name),
1946                      (unsigned int) key->numLevels[i]);
1947                 ACTION("Ignoring extra symbols\n");
1948             }
1949             key->numLevels[i] = type->num_levels;
1950         }
1951         if (key->numLevels[i] > width)
1952             width = key->numLevels[i];
1953         if (type->num_levels > width)
1954             width = type->num_levels;
1955     }
1956
1957     /* width is now the largest width found */
1958
1959     i = width * nGroups;
1960     outSyms = XkbcResizeKeySyms(xkb, kc, i);
1961     if (outSyms == NULL)
1962     {
1963         WSGO("Could not enlarge symbols for %s (keycode %d)\n",
1964               longText(key->name), kc);
1965         return False;
1966     }
1967     if (haveActions)
1968     {
1969         outActs = XkbcResizeKeyActions(xkb, kc, i);
1970         if (outActs == NULL)
1971         {
1972             WSGO("Could not enlarge actions for %s (key %d)\n",
1973                   longText(key->name), kc);
1974             return False;
1975         }
1976         xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
1977     }
1978     else
1979         outActs = NULL;
1980     if (key->defs.defined & _Key_GroupInfo)
1981         i = key->groupInfo;
1982     else
1983         i = xkb->map->key_sym_map[kc].group_info;
1984
1985     xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
1986     xkb->map->key_sym_map[kc].width = width;
1987     for (i = 0; i < nGroups; i++)
1988     {
1989         /* assign kt_index[i] to the index of the type in map->types.
1990          * kt_index[i] may have been set by a previous run (if we have two
1991          * layouts specified). Let's not overwrite it with the ONE_LEVEL
1992          * default group if we dont even have keys for this group anyway.
1993          *
1994          * FIXME: There should be a better fix for this.
1995          */
1996         if (key->numLevels[i])
1997             xkb->map->key_sym_map[kc].kt_index[i] = types[i];
1998         if (key->syms[i] != NULL)
1999         {
2000             /* fill key to "width" symbols*/
2001             for (tmp = 0; tmp < width; tmp++)
2002             {
2003                 if (tmp < key->numLevels[i])
2004                     outSyms[tmp] = key->syms[i][tmp];
2005                 else
2006                     outSyms[tmp] = NoSymbol;
2007                 if ((outActs != NULL) && (key->acts[i] != NULL))
2008                 {
2009                     if (tmp < key->numLevels[i])
2010                         outActs[tmp] = key->acts[i][tmp];
2011                     else
2012                         outActs[tmp].type = XkbSA_NoAction;
2013                 }
2014             }
2015         }
2016         outSyms += width;
2017         if (outActs)
2018             outActs += width;
2019     }
2020     switch (key->behavior.type & XkbKB_OpMask)
2021     {
2022     case XkbKB_Default:
2023         break;
2024     case XkbKB_Overlay1:
2025     case XkbKB_Overlay2:
2026         /* find key by name! */
2027         if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True,
2028                           CreateKeyNames(xkb), 0))
2029         {
2030             if (warningLevel >= 1)
2031             {
2032                 WARN("Key %s not found in %s keycodes\n",
2033                       longText(key->nameForOverlayKey),
2034                       XkbcAtomText(xkb->names->keycodes));
2035                 ACTION("Not treating %s as an overlay key \n",
2036                         longText(key->name));
2037             }
2038             break;
2039         }
2040         key->behavior.data = okc;
2041     default:
2042         xkb->server->behaviors[kc] = key->behavior;
2043         xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2044         break;
2045     }
2046     if (key->defs.defined & _Key_VModMap)
2047     {
2048         xkb->server->vmodmap[kc] = key->vmodmap;
2049         xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2050     }
2051     if (key->repeat != RepeatUndefined)
2052     {
2053         if (key->repeat == RepeatYes)
2054             xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2055         else
2056             xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2057         xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2058     }
2059
2060     if (nGroups > xkb->ctrls->num_groups)
2061         xkb->ctrls->num_groups = nGroups;
2062
2063     /* do the same thing for the next key */
2064     CopySymbolsDef(xkb, key, kc + 1);
2065     return True;
2066 }
2067
2068 static Bool
2069 CopyModMapDef(struct xkb_desc * xkb, ModMapEntry *entry)
2070 {
2071     xkb_keycode_t kc;
2072
2073     if ((!entry->haveSymbol)
2074         &&
2075         (!FindNamedKey
2076          (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
2077     {
2078         if (warningLevel >= 5)
2079         {
2080             WARN("Key %s not found in %s keycodes\n",
2081                   longText(entry->u.keyName),
2082                   XkbcAtomText(xkb->names->keycodes));
2083             ACTION("Modifier map entry for %s not updated\n",
2084                     XkbcModIndexText(entry->modifier));
2085         }
2086         return False;
2087     }
2088     else if (entry->haveSymbol
2089              && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2090     {
2091         if (warningLevel > 5)
2092         {
2093             WARN("Key \"%s\" not found in %s symbol map\n",
2094                   XkbcKeysymText(entry->u.keySym),
2095                   XkbcAtomText(xkb->names->symbols));
2096             ACTION("Modifier map entry for %s not updated\n",
2097                     XkbcModIndexText(entry->modifier));
2098         }
2099         return False;
2100     }
2101     xkb->map->modmap[kc] |= (1 << entry->modifier);
2102     return True;
2103 }
2104
2105 /**
2106  * Handle the xkb_symbols section of an xkb file.
2107  *
2108  * @param file The parsed xkb_symbols section of the xkb file.
2109  * @param xkb Handle to the keyboard description to store the symbols in.
2110  * @param merge Merge strategy (e.g. MergeOverride).
2111  */
2112 Bool
2113 CompileSymbols(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
2114 {
2115     int i;
2116     SymbolsInfo info;
2117
2118     InitSymbolsInfo(&info, xkb);
2119     info.dflt.defs.fileID = file->id;
2120     info.dflt.defs.merge = merge;
2121     HandleSymbolsFile(file, xkb, merge, &info);
2122
2123     if (info.nKeys == 0) {
2124         FreeSymbolsInfo(&info);
2125         return True;
2126     }
2127
2128     if (info.errorCount == 0)
2129     {
2130         KeyInfo *key;
2131
2132         /* alloc memory in the xkb struct */
2133         if (XkbcAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0)
2134             != Success)
2135         {
2136             WSGO("Can not allocate names in CompileSymbols\n");
2137             ACTION("Symbols not added\n");
2138             return False;
2139         }
2140         if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2141             != Success)
2142         {
2143             WSGO("Could not allocate client map in CompileSymbols\n");
2144             ACTION("Symbols not added\n");
2145             return False;
2146         }
2147         if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2148         {
2149             WSGO("Could not allocate server map in CompileSymbols\n");
2150             ACTION("Symbols not added\n");
2151             return False;
2152         }
2153         if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2154         {
2155             WSGO("Could not allocate controls in CompileSymbols\n");
2156             ACTION("Symbols not added\n");
2157             return False;
2158         }
2159
2160         /* now copy info into xkb. */
2161         xkb->names->symbols = xkb_intern_atom(info.name);
2162         if (info.aliases)
2163             ApplyAliases(xkb, False, &info.aliases);
2164         for (i = 0; i < XkbNumKbdGroups; i++)
2165         {
2166             if (info.groupNames[i] != None)
2167                 xkb->names->groups[i] = info.groupNames[i];
2168         }
2169         /* sanitize keys */
2170         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2171         {
2172             PrepareKeyDef(key);
2173         }
2174         /* copy! */
2175         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2176         {
2177             if (!CopySymbolsDef(xkb, key, 0))
2178                 info.errorCount++;
2179         }
2180         if (warningLevel > 3)
2181         {
2182             for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2183             {
2184                 if (xkb->names->keys[i].name[0] == '\0')
2185                     continue;
2186                 if (XkbKeyNumGroups(xkb, i) < 1)
2187                 {
2188                     char buf[5];
2189                     memcpy(buf, xkb->names->keys[i].name, 4);
2190                     buf[4] = '\0';
2191                     WARN
2192                         ("No symbols defined for <%s> (keycode %d)\n",
2193                          buf, i);
2194                 }
2195             }
2196         }
2197         if (info.modMap)
2198         {
2199             ModMapEntry *mm, *next;
2200             for (mm = info.modMap; mm != NULL; mm = next)
2201             {
2202                 if (!CopyModMapDef(xkb, mm))
2203                     info.errorCount++;
2204                 next = (ModMapEntry *) mm->defs.next;
2205             }
2206         }
2207         FreeSymbolsInfo(&info);
2208         return True;
2209     }
2210
2211     FreeSymbolsInfo(&info);
2212     return False;
2213 }