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