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