Define our own NoSymbol value and use it
[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     unsigned int numLevels[XkbNumKbdGroups];
67     xkb_keysym_t *syms[XkbNumKbdGroups];
68     union xkb_action *acts[XkbNumKbdGroups];
69     xkb_atom_t types[XkbNumKbdGroups];
70     unsigned repeat;
71     struct xkb_behavior behavior;
72     unsigned short vmodmap;
73     unsigned long allowNone;
74     xkb_atom_t dfltType;
75 } KeyInfo;
76
77 /**
78  * Init the given key info to sane values.
79  */
80 static void
81 InitKeyInfo(KeyInfo * info)
82 {
83     int i;
84     static char dflt[4] = "*";
85
86     info->defs.defined = 0;
87     info->defs.fileID = 0;
88     info->defs.merge = MergeOverride;
89     info->defs.next = NULL;
90     info->name = KeyNameToLong(dflt);
91     info->groupInfo = 0;
92     info->typesDefined = info->symsDefined = info->actsDefined = 0;
93     for (i = 0; i < XkbNumKbdGroups; i++)
94     {
95         info->numLevels[i] = 0;
96         info->types[i] = XKB_ATOM_NONE;
97         info->syms[i] = NULL;
98         info->acts[i] = NULL;
99     }
100     info->dfltType = XKB_ATOM_NONE;
101     info->behavior.type = XkbKB_Default;
102     info->behavior.data = 0;
103     info->vmodmap = 0;
104     info->repeat = RepeatUndefined;
105     info->allowNone = 0;
106 }
107
108 /**
109  * Free memory associated with this key info and reset to sane values.
110  */
111 static void
112 FreeKeyInfo(KeyInfo * info)
113 {
114     int i;
115
116     info->defs.defined = 0;
117     info->defs.fileID = 0;
118     info->defs.merge = MergeOverride;
119     info->defs.next = NULL;
120     info->groupInfo = 0;
121     info->typesDefined = info->symsDefined = info->actsDefined = 0;
122     for (i = 0; i < XkbNumKbdGroups; i++)
123     {
124         info->numLevels[i] = 0;
125         info->types[i] = XKB_ATOM_NONE;
126         free(info->syms[i]);
127         info->syms[i] = NULL;
128         free(info->acts[i]);
129         info->acts[i] = NULL;
130     }
131     info->dfltType = XKB_ATOM_NONE;
132     info->behavior.type = XkbKB_Default;
133     info->behavior.data = 0;
134     info->vmodmap = 0;
135     info->repeat = RepeatUndefined;
136     info->allowNone = 0;
137 }
138
139 /**
140  * Copy old into new, optionally reset old to 0.
141  * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
142  * newly allocated and new points to the new memory areas.
143  */
144 static Bool
145 CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld)
146 {
147     int i;
148
149     *new = *old;
150     new->defs.next = NULL;
151     if (clearOld)
152     {
153         for (i = 0; i < XkbNumKbdGroups; i++)
154         {
155             old->numLevels[i] = 0;
156             old->syms[i] = NULL;
157             old->acts[i] = NULL;
158         }
159     }
160     else
161     {
162         unsigned int width;
163         for (i = 0; i < XkbNumKbdGroups; i++)
164         {
165             width = new->numLevels[i];
166             if (old->syms[i] != NULL)
167             {
168                 new->syms[i] = uTypedCalloc(width, xkb_keysym_t);
169                 if (!new->syms[i])
170                 {
171                     new->syms[i] = NULL;
172                     new->numLevels[i] = 0;
173                     return False;
174                 }
175                 memcpy(new->syms[i], old->syms[i], width * sizeof(xkb_keysym_t));
176             }
177             if (old->acts[i] != NULL)
178             {
179                 new->acts[i] = uTypedCalloc(width, union xkb_action);
180                 if (!new->acts[i])
181                 {
182                     new->acts[i] = NULL;
183                     return False;
184                 }
185                 memcpy(new->acts[i], old->acts[i],
186                        width * sizeof(union xkb_action));
187             }
188         }
189     }
190     return True;
191 }
192
193 /***====================================================================***/
194
195 typedef struct _ModMapEntry
196 {
197     CommonInfo defs;
198     Bool haveSymbol;
199     int modifier;
200     union
201     {
202         unsigned long keyName;
203         xkb_keysym_t keySym;
204     } u;
205 } ModMapEntry;
206
207 #define SYMBOLS_INIT_SIZE       110
208 #define SYMBOLS_CHUNK           20
209 typedef struct _SymbolsInfo
210 {
211     char *name;         /* e.g. pc+us+inet(evdev) */
212     int errorCount;
213     unsigned fileID;
214     unsigned merge;
215     unsigned explicit_group;
216     unsigned groupInfo;
217     unsigned szKeys;
218     unsigned nKeys;
219     KeyInfo *keys;
220     KeyInfo dflt;
221     VModInfo vmods;
222     ActionInfo *action;
223     xkb_atom_t groupNames[XkbNumKbdGroups];
224
225     ModMapEntry *modMap;
226     AliasInfo *aliases;
227 } SymbolsInfo;
228
229 static void
230 InitSymbolsInfo(SymbolsInfo * info, struct xkb_desc * xkb)
231 {
232     int i;
233
234     info->name = NULL;
235     info->explicit_group = 0;
236     info->errorCount = 0;
237     info->fileID = 0;
238     info->merge = MergeOverride;
239     info->groupInfo = 0;
240     info->szKeys = SYMBOLS_INIT_SIZE;
241     info->nKeys = 0;
242     info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo);
243     info->modMap = NULL;
244     for (i = 0; i < XkbNumKbdGroups; i++)
245         info->groupNames[i] = XKB_ATOM_NONE;
246     InitKeyInfo(&info->dflt);
247     InitVModInfo(&info->vmods, xkb);
248     info->action = NULL;
249     info->aliases = NULL;
250 }
251
252 static void
253 FreeSymbolsInfo(SymbolsInfo * info)
254 {
255     unsigned int i;
256
257     free(info->name);
258     if (info->keys)
259     {
260         for (i = 0; i < info->nKeys; i++)
261             FreeKeyInfo(&info->keys[i]);
262         free(info->keys);
263     }
264     if (info->modMap)
265         ClearCommonInfo(&info->modMap->defs);
266     if (info->aliases)
267         ClearAliases(&info->aliases);
268     memset(info, 0, sizeof(SymbolsInfo));
269 }
270
271 static Bool
272 ResizeKeyGroup(KeyInfo * key,
273                unsigned group, unsigned atLeastSize, Bool forceActions)
274 {
275     Bool tooSmall;
276     unsigned newWidth;
277
278     tooSmall = (key->numLevels[group] < atLeastSize);
279     if (tooSmall)
280         newWidth = atLeastSize;
281     else
282         newWidth = key->numLevels[group];
283
284     if ((key->syms[group] == NULL) || tooSmall)
285     {
286         key->syms[group] = uTypedRecalloc(key->syms[group],
287                                           key->numLevels[group], newWidth,
288                                           xkb_keysym_t);
289         if (!key->syms[group])
290             return False;
291     }
292     if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) ||
293         (tooSmall && (key->acts[group] != NULL)))
294     {
295         key->acts[group] = uTypedRecalloc(key->acts[group],
296                                           key->numLevels[group], newWidth,
297                                           union xkb_action);
298         if (!key->acts[group])
299             return False;
300     }
301     key->numLevels[group] = newWidth;
302     return True;
303 }
304
305 static Bool
306 MergeKeyGroups(SymbolsInfo * info,
307                KeyInfo * into, KeyInfo * from, unsigned group)
308 {
309     xkb_keysym_t *resultSyms;
310     union xkb_action *resultActs;
311     unsigned int resultWidth;
312     unsigned int i;
313     Bool report, clobber;
314
315     clobber = (from->defs.merge != MergeAugment);
316     report = (warningLevel > 9) ||
317         ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
318     if (into->numLevels[group] >= from->numLevels[group])
319     {
320         resultSyms = into->syms[group];
321         resultActs = into->acts[group];
322         resultWidth = into->numLevels[group];
323     }
324     else
325     {
326         resultSyms = from->syms[group];
327         resultActs = from->acts[group];
328         resultWidth = from->numLevels[group];
329     }
330     if (resultSyms == NULL)
331     {
332         resultSyms = uTypedCalloc(resultWidth, xkb_keysym_t);
333         if (!resultSyms)
334         {
335             WSGO("Could not allocate symbols for group merge\n");
336             ACTION("Group %d of key %s not merged\n", group,
337                     longText(into->name));
338             return False;
339         }
340     }
341     if ((resultActs == NULL) && (into->acts[group] || from->acts[group]))
342     {
343         resultActs = uTypedCalloc(resultWidth, union xkb_action);
344         if (!resultActs)
345         {
346             WSGO("Could not allocate actions for group merge\n");
347             ACTION("Group %d of key %s not merged\n", group,
348                     longText(into->name));
349             if (resultSyms != into->syms[group] &&
350                 resultSyms != from->syms[group])
351                 free(resultSyms);
352             return False;
353         }
354     }
355     for (i = 0; i < resultWidth; i++)
356     {
357         xkb_keysym_t fromSym, toSym;
358         if (from->syms[group] && (i < from->numLevels[group]))
359             fromSym = from->syms[group][i];
360         else
361             fromSym = XKB_KEYSYM_NO_SYMBOL;
362         if (into->syms[group] && (i < into->numLevels[group]))
363             toSym = into->syms[group][i];
364         else
365             toSym = XKB_KEYSYM_NO_SYMBOL;
366         if ((fromSym == XKB_KEYSYM_NO_SYMBOL) || (fromSym == toSym))
367             resultSyms[i] = toSym;
368         else if (toSym == XKB_KEYSYM_NO_SYMBOL)
369             resultSyms[i] = fromSym;
370         else
371         {
372             xkb_keysym_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] != XKB_ATOM_NONE)
511         {
512             if ((into->types[i] != XKB_ATOM_NONE) && report &&
513                 (into->types[i] != from->types[i]))
514             {
515                 xkb_atom_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] == XKB_ATOM_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->defs.defined |= _Key_Behavior;
545     }
546     if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
547     {
548         into->vmodmap = from->vmodmap;
549         into->defs.defined |= _Key_VModMap;
550     }
551     if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
552     {
553         into->repeat = from->repeat;
554         into->defs.defined |= _Key_Repeat;
555     }
556     if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
557     {
558         into->dfltType = from->dfltType;
559         into->defs.defined |= _Key_Type_Dflt;
560     }
561     if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
562     {
563         into->groupInfo = from->groupInfo;
564         into->defs.defined |= _Key_GroupInfo;
565     }
566     if (collide)
567     {
568         WARN("Symbol map for key %s redefined\n",
569               longText(into->name));
570         ACTION("Using %s definition for conflicting fields\n",
571                 (from->defs.merge == MergeAugment ? "first" : "last"));
572     }
573     return True;
574 }
575
576 static Bool
577 AddKeySymbols(SymbolsInfo * info, KeyInfo * key, struct xkb_desc * xkb)
578 {
579     unsigned int i;
580     unsigned long real_name;
581
582     for (i = 0; i < info->nKeys; i++)
583     {
584         if (info->keys[i].name == key->name)
585             return MergeKeys(info, &info->keys[i], key);
586     }
587     if (FindKeyNameForAlias(xkb, key->name, &real_name))
588     {
589         for (i = 0; i < info->nKeys; i++)
590         {
591             if (info->keys[i].name == real_name)
592                 return MergeKeys(info, &info->keys[i], key);
593         }
594     }
595     if (info->nKeys >= info->szKeys)
596     {
597         info->szKeys += SYMBOLS_CHUNK;
598         info->keys =
599             uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo);
600         if (!info->keys)
601         {
602             WSGO("Could not allocate key symbols descriptions\n");
603             ACTION("Some key symbols definitions may be lost\n");
604             return False;
605         }
606     }
607     return CopyKeyInfo(key, &info->keys[info->nKeys++], True);
608 }
609
610 static Bool
611 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
612 {
613     ModMapEntry *mm;
614     Bool clobber;
615
616     clobber = (new->defs.merge != MergeAugment);
617     for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
618     {
619         if (new->haveSymbol && mm->haveSymbol
620             && (new->u.keySym == mm->u.keySym))
621         {
622             unsigned use, ignore;
623             if (mm->modifier != new->modifier)
624             {
625                 if (clobber)
626                 {
627                     use = new->modifier;
628                     ignore = mm->modifier;
629                 }
630                 else
631                 {
632                     use = mm->modifier;
633                     ignore = new->modifier;
634                 }
635                 ERROR
636                     ("%s added to symbol map for multiple modifiers\n",
637                      XkbcKeysymText(new->u.keySym));
638                 ACTION("Using %s, ignoring %s.\n",
639                         XkbcModIndexText(use),
640                         XkbcModIndexText(ignore));
641                 mm->modifier = use;
642             }
643             return True;
644         }
645         if ((!new->haveSymbol) && (!mm->haveSymbol) &&
646             (new->u.keyName == mm->u.keyName))
647         {
648             unsigned use, ignore;
649             if (mm->modifier != new->modifier)
650             {
651                 if (clobber)
652                 {
653                     use = new->modifier;
654                     ignore = mm->modifier;
655                 }
656                 else
657                 {
658                     use = mm->modifier;
659                     ignore = new->modifier;
660                 }
661                 ERROR("Key %s added to map for multiple modifiers\n",
662                        longText(new->u.keyName));
663                 ACTION("Using %s, ignoring %s.\n",
664                         XkbcModIndexText(use),
665                         XkbcModIndexText(ignore));
666                 mm->modifier = use;
667             }
668             return True;
669         }
670     }
671     mm = uTypedAlloc(ModMapEntry);
672     if (mm == NULL)
673     {
674         WSGO("Could not allocate modifier map entry\n");
675         ACTION("Modifier map for %s will be incomplete\n",
676                 XkbcModIndexText(new->modifier));
677         return False;
678     }
679     *mm = *new;
680     mm->defs.next = &info->modMap->defs;
681     info->modMap = mm;
682     return True;
683 }
684
685 /***====================================================================***/
686
687 static void
688 MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from,
689                      unsigned merge, struct xkb_desc * xkb)
690 {
691     unsigned int i;
692     KeyInfo *key;
693
694     if (from->errorCount > 0)
695     {
696         into->errorCount += from->errorCount;
697         return;
698     }
699     if (into->name == NULL)
700     {
701         into->name = from->name;
702         from->name = NULL;
703     }
704     for (i = 0; i < XkbNumKbdGroups; i++)
705     {
706         if (from->groupNames[i] != XKB_ATOM_NONE)
707         {
708             if ((merge != MergeAugment) ||
709                 (into->groupNames[i] == XKB_ATOM_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     unsigned int i;
892     long j;
893
894     if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx))
895         return False;
896     if (value == NULL)
897     {
898         key->symsDefined |= (1 << ndx);
899         return True;
900     }
901     if (value->op != ExprKeysymList)
902     {
903         ERROR("Expected a list of symbols, found %s\n", exprOpText(value->op));
904         ACTION("Ignoring symbols for group %d of %s\n", ndx + 1,
905                 longText(key->name));
906         return False;
907     }
908     if (key->syms[ndx] != NULL)
909     {
910         ERROR("Symbols for key %s, group %d already defined\n",
911                longText(key->name), ndx + 1);
912         ACTION("Ignoring duplicate definition\n");
913         return False;
914     }
915     nSyms = value->value.list.nSyms;
916     if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
917         (!ResizeKeyGroup(key, ndx, nSyms, False)))
918     {
919         WSGO("Could not resize group %d of key %s to contain %d levels\n",
920              ndx + 1, longText(key->name), nSyms);
921         ACTION("Symbols lost\n");
922         return False;
923     }
924     key->symsDefined |= (1 << ndx);
925     for (i = 0; i < nSyms; i++) {
926         if (!LookupKeysym(value->value.list.syms[i], &key->syms[ndx][i])) {
927             WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
928                   value->value.list.syms[i], longText(key->name), ndx + 1,
929                   XkbcAtomText(info->groupNames[ndx]), nSyms);
930             key->syms[ndx][i] = XKB_KEYSYM_NO_SYMBOL;
931         }
932     }
933     for (j = key->numLevels[ndx] - 1;
934          (j >= 0) && (key->syms[ndx][j] == XKB_KEYSYM_NO_SYMBOL); j--)
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     unsigned 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 const LookupEntry lockingEntries[] = {
1008     {"true", XkbKB_Lock},
1009     {"yes", XkbKB_Lock},
1010     {"on", XkbKB_Lock},
1011     {"false", XkbKB_Default},
1012     {"no", XkbKB_Default},
1013     {"off", XkbKB_Default},
1014     {"permanent", XkbKB_Lock | XkbKB_Permanent},
1015     {NULL, 0}
1016 };
1017
1018 static const LookupEntry repeatEntries[] = {
1019     {"true", RepeatYes},
1020     {"yes", RepeatYes},
1021     {"on", RepeatYes},
1022     {"false", RepeatNo},
1023     {"no", RepeatNo},
1024     {"off", RepeatNo},
1025     {"default", RepeatUndefined},
1026     {NULL, 0}
1027 };
1028
1029 static Bool
1030 SetSymbolsField(KeyInfo * key,
1031                 struct xkb_desc * xkb,
1032                 char *field,
1033                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1034 {
1035     Bool ok = True;
1036     ExprResult tmp;
1037
1038     if (strcasecmp(field, "type") == 0)
1039     {
1040         ExprResult ndx;
1041         if ((!ExprResolveString(value, &tmp))
1042             && (warningLevel > 0))
1043         {
1044             WARN("The type field of a key symbol map must be a string\n");
1045             ACTION("Ignoring illegal type definition\n");
1046         }
1047         if (arrayNdx == NULL)
1048         {
1049             key->dfltType = xkb_intern_atom(tmp.str);
1050             key->defs.defined |= _Key_Type_Dflt;
1051         }
1052         else if (!ExprResolveGroup(arrayNdx, &ndx))
1053         {
1054             ERROR("Illegal group index for type of key %s\n",
1055                    longText(key->name));
1056             ACTION("Definition with non-integer array index ignored\n");
1057             free(tmp.str);
1058             return False;
1059         }
1060         else
1061         {
1062             key->types[ndx.uval - 1] = xkb_intern_atom(tmp.str);
1063             key->typesDefined |= (1 << (ndx.uval - 1));
1064         }
1065         free(tmp.str);
1066     }
1067     else if (strcasecmp(field, "symbols") == 0)
1068         return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1069     else if (strcasecmp(field, "actions") == 0)
1070         return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1071     else if ((strcasecmp(field, "vmods") == 0) ||
1072              (strcasecmp(field, "virtualmods") == 0) ||
1073              (strcasecmp(field, "virtualmodifiers") == 0))
1074     {
1075         ok = ExprResolveVModMask(value, &tmp, xkb);
1076         if (ok)
1077         {
1078             key->vmodmap = (tmp.uval >> 8);
1079             key->defs.defined |= _Key_VModMap;
1080         }
1081         else
1082         {
1083             ERROR("Expected a virtual modifier mask, found %s\n",
1084                    exprOpText(value->op));
1085             ACTION("Ignoring virtual modifiers definition for key %s\n",
1086                     longText(key->name));
1087         }
1088     }
1089     else if ((strcasecmp(field, "locking") == 0) ||
1090              (strcasecmp(field, "lock") == 0) ||
1091              (strcasecmp(field, "locks") == 0))
1092     {
1093         ok = ExprResolveEnum(value, &tmp, lockingEntries);
1094         if (ok)
1095             key->behavior.type = tmp.uval;
1096         key->defs.defined |= _Key_Behavior;
1097     }
1098     else if ((strcasecmp(field, "radiogroup") == 0) ||
1099              (strcasecmp(field, "permanentradiogroup") == 0) ||
1100              (strcasecmp(field, "allownone") == 0))
1101     {
1102         ERROR("Radio groups not supported\n");
1103         ACTION("Ignoring radio group specification for key %s\n", longText(key->name));
1104         return False;
1105     }
1106     else if (uStrCasePrefix("overlay", field) ||
1107              uStrCasePrefix("permanentoverlay", field))
1108     {
1109         ERROR("Overlays not supported\n");
1110         ACTION("Ignoring overlay specification for key %s\n", longText(key->name));
1111     }
1112     else if ((strcasecmp(field, "repeating") == 0) ||
1113              (strcasecmp(field, "repeats") == 0) ||
1114              (strcasecmp(field, "repeat") == 0))
1115     {
1116         ok = ExprResolveEnum(value, &tmp, repeatEntries);
1117         if (!ok)
1118         {
1119             ERROR("Illegal repeat setting for %s\n",
1120                    longText(key->name));
1121             ACTION("Non-boolean repeat setting ignored\n");
1122             return False;
1123         }
1124         key->repeat = tmp.uval;
1125         key->defs.defined |= _Key_Repeat;
1126     }
1127     else if ((strcasecmp(field, "groupswrap") == 0) ||
1128              (strcasecmp(field, "wrapgroups") == 0))
1129     {
1130         ok = ExprResolveBoolean(value, &tmp);
1131         if (!ok)
1132         {
1133             ERROR("Illegal groupsWrap setting for %s\n",
1134                    longText(key->name));
1135             ACTION("Non-boolean value ignored\n");
1136             return False;
1137         }
1138         if (tmp.uval)
1139             key->groupInfo = XkbWrapIntoRange;
1140         else
1141             key->groupInfo = XkbClampIntoRange;
1142         key->defs.defined |= _Key_GroupInfo;
1143     }
1144     else if ((strcasecmp(field, "groupsclamp") == 0) ||
1145              (strcasecmp(field, "clampgroups") == 0))
1146     {
1147         ok = ExprResolveBoolean(value, &tmp);
1148         if (!ok)
1149         {
1150             ERROR("Illegal groupsClamp setting for %s\n",
1151                    longText(key->name));
1152             ACTION("Non-boolean value ignored\n");
1153             return False;
1154         }
1155         if (tmp.uval)
1156             key->groupInfo = XkbClampIntoRange;
1157         else
1158             key->groupInfo = XkbWrapIntoRange;
1159         key->defs.defined |= _Key_GroupInfo;
1160     }
1161     else if ((strcasecmp(field, "groupsredirect") == 0) ||
1162              (strcasecmp(field, "redirectgroups") == 0))
1163     {
1164         if (!ExprResolveGroup(value, &tmp))
1165         {
1166             ERROR("Illegal group index for redirect of key %s\n",
1167                    longText(key->name));
1168             ACTION("Definition with non-integer group ignored\n");
1169             return False;
1170         }
1171         key->groupInfo =
1172             XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1173         key->defs.defined |= _Key_GroupInfo;
1174     }
1175     else
1176     {
1177         ERROR("Unknown field %s in a symbol interpretation\n", field);
1178         ACTION("Definition ignored\n");
1179         ok = False;
1180     }
1181     return ok;
1182 }
1183
1184 static int
1185 SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1186 {
1187     ExprResult tmp, name;
1188
1189     if ((arrayNdx == NULL) && (warningLevel > 0))
1190     {
1191         WARN("You must specify an index when specifying a group name\n");
1192         ACTION("Group name definition without array subscript ignored\n");
1193         return False;
1194     }
1195     if (!ExprResolveGroup(arrayNdx, &tmp))
1196     {
1197         ERROR("Illegal index in group name definition\n");
1198         ACTION("Definition with non-integer array index ignored\n");
1199         return False;
1200     }
1201     if (!ExprResolveString(value, &name))
1202     {
1203         ERROR("Group name must be a string\n");
1204         ACTION("Illegal name for group %d ignored\n", tmp.uval);
1205         return False;
1206     }
1207     info->groupNames[tmp.uval - 1 + info->explicit_group] =
1208         xkb_intern_atom(name.str);
1209     free(name.str);
1210
1211     return True;
1212 }
1213
1214 static int
1215 HandleSymbolsVar(VarDef * stmt, struct xkb_desc * xkb, SymbolsInfo * info)
1216 {
1217     ExprResult elem, field, tmp;
1218     ExprDef *arrayNdx;
1219     Bool ret;
1220
1221     if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1222         return 0;               /* internal error, already reported */
1223     if (elem.str && (strcasecmp(elem.str, "key") == 0))
1224     {
1225         ret = SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1226                               stmt->value, info);
1227     }
1228     else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) ||
1229                                     (strcasecmp(field.str, "groupname") ==
1230                                      0)))
1231     {
1232         ret = SetGroupName(info, arrayNdx, stmt->value);
1233     }
1234     else if ((elem.str == NULL)
1235              && ((strcasecmp(field.str, "groupswrap") == 0) ||
1236                  (strcasecmp(field.str, "wrapgroups") == 0)))
1237     {
1238         if (!ExprResolveBoolean(stmt->value, &tmp))
1239         {
1240             ERROR("Illegal setting for global groupsWrap\n");
1241             ACTION("Non-boolean value ignored\n");
1242             ret = False;
1243         }
1244         else {
1245             if (tmp.uval)
1246                 info->groupInfo = XkbWrapIntoRange;
1247             else
1248                 info->groupInfo = XkbClampIntoRange;
1249             ret = True;
1250         }
1251     }
1252     else if ((elem.str == NULL)
1253              && ((strcasecmp(field.str, "groupsclamp") == 0) ||
1254                  (strcasecmp(field.str, "clampgroups") == 0)))
1255     {
1256         if (!ExprResolveBoolean(stmt->value, &tmp))
1257         {
1258             ERROR("Illegal setting for global groupsClamp\n");
1259             ACTION("Non-boolean value ignored\n");
1260             return False;
1261         }
1262         else {
1263             if (tmp.uval)
1264                 info->groupInfo = XkbClampIntoRange;
1265             else
1266                 info->groupInfo = XkbWrapIntoRange;
1267             ret = True;
1268         }
1269     }
1270     else if ((elem.str == NULL)
1271              && ((strcasecmp(field.str, "groupsredirect") == 0) ||
1272                  (strcasecmp(field.str, "redirectgroups") == 0)))
1273     {
1274         if (!ExprResolveGroup(stmt->value, &tmp))
1275         {
1276             ERROR("Illegal group index for global groupsRedirect\n");
1277             ACTION("Definition with non-integer group ignored\n");
1278             ret = False;
1279         }
1280         else {
1281             info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange,
1282                                               tmp.uval);
1283             ret = True;
1284         }
1285     }
1286     else if ((elem.str == NULL) && (strcasecmp(field.str, "allownone") == 0))
1287     {
1288         ERROR("Radio groups not supported\n");
1289         ACTION("Ignoring \"allow none\" specification\n");
1290         ret = False;
1291     }
1292     else {
1293         ret = SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1294                              &info->action);
1295     }
1296
1297     free(elem.str);
1298     free(field.str);
1299     return ret;
1300 }
1301
1302 static Bool
1303 HandleSymbolsBody(VarDef * def,
1304                   struct xkb_desc * xkb, KeyInfo * key, SymbolsInfo * info)
1305 {
1306     Bool ok = True;
1307     ExprResult tmp, field;
1308     ExprDef *arrayNdx;
1309
1310     for (; def != NULL; def = (VarDef *) def->common.next)
1311     {
1312         if ((def->name) && (def->name->type == ExprFieldRef))
1313         {
1314             ok = HandleSymbolsVar(def, xkb, info);
1315             continue;
1316         }
1317         else
1318         {
1319             if (def->name == NULL)
1320             {
1321                 if ((def->value == NULL)
1322                     || (def->value->op == ExprKeysymList))
1323                     field.str = strdup("symbols");
1324                 else
1325                     field.str = strdup("actions");
1326                 arrayNdx = NULL;
1327             }
1328             else
1329             {
1330                 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1331             }
1332             if (ok)
1333                 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1334                                      def->value, info);
1335             free(field.str);
1336         }
1337     }
1338     return ok;
1339 }
1340
1341 static Bool
1342 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1343 {
1344     unsigned group = info->explicit_group;
1345
1346     if (group == 0)
1347         return True;
1348
1349     if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1350     {
1351         int i;
1352         WARN("For the map %s an explicit group specified\n", info->name);
1353         WARN("but key %s has more than one group defined\n",
1354               longText(key->name));
1355         ACTION("All groups except first one will be ignored\n");
1356         for (i = 1; i < XkbNumKbdGroups; i++)
1357         {
1358             key->numLevels[i] = 0;
1359             free(key->syms[i]);
1360             key->syms[i] = NULL;
1361             free(key->acts[i]);
1362             key->acts[i] = NULL;
1363             key->types[i] = 0;
1364         }
1365     }
1366     key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1367
1368     key->numLevels[group] = key->numLevels[0];
1369     key->numLevels[0] = 0;
1370     key->syms[group] = key->syms[0];
1371     key->syms[0] = NULL;
1372     key->acts[group] = key->acts[0];
1373     key->acts[0] = NULL;
1374     key->types[group] = key->types[0];
1375     key->types[0] = 0;
1376     return True;
1377 }
1378
1379 static int
1380 HandleSymbolsDef(SymbolsDef * stmt,
1381                  struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1382 {
1383     KeyInfo key;
1384
1385     InitKeyInfo(&key);
1386     CopyKeyInfo(&info->dflt, &key, False);
1387     key.defs.merge = stmt->merge;
1388     key.name = KeyNameToLong(stmt->keyName);
1389     if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1390     {
1391         info->errorCount++;
1392         return False;
1393     }
1394
1395     if (!SetExplicitGroup(info, &key))
1396     {
1397         info->errorCount++;
1398         return False;
1399     }
1400
1401     if (!AddKeySymbols(info, &key, xkb))
1402     {
1403         info->errorCount++;
1404         return False;
1405     }
1406     return True;
1407 }
1408
1409 static Bool
1410 HandleModMapDef(ModMapDef * def,
1411                 struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1412 {
1413     ExprDef *key;
1414     ModMapEntry tmp;
1415     ExprResult rtrn;
1416     Bool ok;
1417
1418     if (!LookupModIndex(NULL, def->modifier, TypeInt, &rtrn))
1419     {
1420         ERROR("Illegal modifier map definition\n");
1421         ACTION("Ignoring map for non-modifier \"%s\"\n",
1422                 XkbcAtomText(def->modifier));
1423         return False;
1424     }
1425     ok = True;
1426     tmp.modifier = rtrn.uval;
1427     for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1428     {
1429         if ((key->op == ExprValue) && (key->type == TypeKeyName))
1430         {
1431             tmp.haveSymbol = False;
1432             tmp.u.keyName = KeyNameToLong(key->value.keyName);
1433         }
1434         else if (ExprResolveKeySym(key, &rtrn))
1435         {
1436             tmp.haveSymbol = True;
1437             tmp.u.keySym = rtrn.uval;
1438         }
1439         else
1440         {
1441             ERROR("Modmap entries may contain only key names or keysyms\n");
1442             ACTION("Illegal definition for %s modifier ignored\n",
1443                     XkbcModIndexText(tmp.modifier));
1444             continue;
1445         }
1446
1447         ok = AddModMapEntry(info, &tmp) && ok;
1448     }
1449     return ok;
1450 }
1451
1452 static void
1453 HandleSymbolsFile(XkbFile * file,
1454                   struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1455 {
1456     ParseCommon *stmt;
1457
1458     free(info->name);
1459     info->name = uDupString(file->name);
1460     stmt = file->defs;
1461     while (stmt)
1462     {
1463         switch (stmt->stmtType)
1464         {
1465         case StmtInclude:
1466             if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1467                                       HandleSymbolsFile))
1468                 info->errorCount++;
1469             break;
1470         case StmtSymbolsDef:
1471             if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1472                 info->errorCount++;
1473             break;
1474         case StmtVarDef:
1475             if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1476                 info->errorCount++;
1477             break;
1478         case StmtVModDef:
1479             if (!HandleVModDef((VModDef *) stmt, xkb, merge, &info->vmods))
1480                 info->errorCount++;
1481             break;
1482         case StmtInterpDef:
1483             ERROR("Interpretation files may not include other types\n");
1484             ACTION("Ignoring definition of symbol interpretation\n");
1485             info->errorCount++;
1486             break;
1487         case StmtKeycodeDef:
1488             ERROR("Interpretation files may not include other types\n");
1489             ACTION("Ignoring definition of key name\n");
1490             info->errorCount++;
1491             break;
1492         case StmtModMapDef:
1493             if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1494                 info->errorCount++;
1495             break;
1496         default:
1497             WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1498                   stmt->stmtType);
1499             break;
1500         }
1501         stmt = stmt->next;
1502         if (info->errorCount > 10)
1503         {
1504 #ifdef NOISY
1505             ERROR("Too many errors\n");
1506 #endif
1507             ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1508             break;
1509         }
1510     }
1511 }
1512
1513 static Bool
1514 FindKeyForSymbol(struct xkb_desc * xkb, xkb_keysym_t sym, xkb_keycode_t *kc_rtrn)
1515 {
1516     int i, j;
1517     Bool gotOne;
1518
1519     j = 0;
1520     do
1521     {
1522         gotOne = False;
1523         for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1524         {
1525             if (j < (int) XkbKeyNumSyms(xkb, i))
1526             {
1527                 gotOne = True;
1528                 if (XkbKeySym(xkb, i, j) == sym)
1529                 {
1530                     *kc_rtrn = i;
1531                     return True;
1532                 }
1533             }
1534         }
1535         j++;
1536     }
1537     while (gotOne);
1538     return False;
1539 }
1540
1541 /**
1542  * Find the given name in the xkb->map->types and return its index.
1543  *
1544  * @param atom The atom to search for.
1545  * @param type_rtrn Set to the index of the name if found.
1546  *
1547  * @return True if found, False otherwise.
1548  */
1549 static Bool
1550 FindNamedType(struct xkb_desc * xkb, xkb_atom_t atom, unsigned *type_rtrn)
1551 {
1552     unsigned n;
1553     const char *name = XkbcAtomText(atom);
1554
1555     if (xkb && xkb->map && xkb->map->types)
1556     {
1557         for (n = 0; n < xkb->map->num_types; n++)
1558         {
1559             if (strcmp(xkb->map->types[n].name, name) == 0)
1560             {
1561                 *type_rtrn = n;
1562                 return True;
1563             }
1564         }
1565     }
1566     return False;
1567 }
1568
1569 /**
1570  * Assign a type to the given sym and return the Atom for the type assigned.
1571  *
1572  * Simple recipe:
1573  * - ONE_LEVEL for width 0/1
1574  * - ALPHABETIC for 2 shift levels, with lower/upercase
1575  * - KEYPAD for keypad keys.
1576  * - TWO_LEVEL for other 2 shift level keys.
1577  * and the same for four level keys.
1578  *
1579  * @param width Number of sysms in syms.
1580  * @param syms The keysyms for the given key (must be size width).
1581  * @param typeNameRtrn Set to the Atom of the type name.
1582  *
1583  * @returns True if a type could be found, False otherwise.
1584  */
1585 static Bool
1586 FindAutomaticType(int width, xkb_keysym_t * syms, xkb_atom_t * typeNameRtrn,
1587                   Bool * autoType)
1588 {
1589     *autoType = False;
1590     if ((width == 1) || (width == 0))
1591     {
1592         *typeNameRtrn = xkb_intern_atom("ONE_LEVEL");
1593         *autoType = True;
1594     }
1595     else if (width == 2)
1596     {
1597         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1598         {
1599             *typeNameRtrn = xkb_intern_atom("ALPHABETIC");
1600         }
1601         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1602         {
1603             *typeNameRtrn = xkb_intern_atom("KEYPAD");
1604             *autoType = True;
1605         }
1606         else
1607         {
1608             *typeNameRtrn = xkb_intern_atom("TWO_LEVEL");
1609             *autoType = True;
1610         }
1611     }
1612     else if (width <= 4)
1613     {
1614         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1615             if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1616                 *typeNameRtrn =
1617                     xkb_intern_atom("FOUR_LEVEL_ALPHABETIC");
1618             else
1619                 *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_SEMIALPHABETIC");
1620
1621         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1622             *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_KEYPAD");
1623         else
1624             *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL");
1625         /* XXX: why not set autoType here? */
1626     }
1627     return ((width >= 0) && (width <= 4));
1628 }
1629
1630 /**
1631  * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1632  * groups, and reduce to one group if all groups are identical anyway.
1633  */
1634 static void
1635 PrepareKeyDef(KeyInfo * key)
1636 {
1637     int i, j, width, defined, lastGroup;
1638     Bool identical;
1639
1640     defined = key->symsDefined | key->actsDefined | key->typesDefined;
1641     /* get highest group number */
1642     for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1643     {
1644         if (defined & (1 << i))
1645             break;
1646     }
1647     lastGroup = i;
1648
1649     if (lastGroup == 0)
1650         return;
1651
1652     /* If there are empty groups between non-empty ones fill them with data */
1653     /* from the first group. */
1654     /* We can make a wrong assumption here. But leaving gaps is worse. */
1655     for (i = lastGroup; i > 0; i--)
1656     {
1657         if (defined & (1 << i))
1658             continue;
1659         width = key->numLevels[0];
1660         if (key->typesDefined & 1)
1661         {
1662             for (j = 0; j < width; j++)
1663             {
1664                 key->types[i] = key->types[0];
1665             }
1666             key->typesDefined |= 1 << i;
1667         }
1668         if ((key->actsDefined & 1) && key->acts[0])
1669         {
1670             key->acts[i] = uTypedCalloc(width, union xkb_action);
1671             if (key->acts[i] == NULL)
1672                 continue;
1673             memcpy(key->acts[i], key->acts[0],
1674                    width * sizeof(union xkb_action));
1675             key->actsDefined |= 1 << i;
1676         }
1677         if ((key->symsDefined & 1) && key->syms[0])
1678         {
1679             key->syms[i] = uTypedCalloc(width, xkb_keysym_t);
1680             if (key->syms[i] == NULL)
1681                 continue;
1682             memcpy(key->syms[i], key->syms[0], width * sizeof(xkb_keysym_t));
1683             key->symsDefined |= 1 << i;
1684         }
1685         if (defined & 1)
1686         {
1687             key->numLevels[i] = key->numLevels[0];
1688         }
1689     }
1690     /* If all groups are completely identical remove them all */
1691     /* exept the first one. */
1692     identical = True;
1693     for (i = lastGroup; i > 0; i--)
1694     {
1695         if ((key->numLevels[i] != key->numLevels[0]) ||
1696             (key->types[i] != key->types[0]))
1697         {
1698             identical = False;
1699             break;
1700         }
1701         if ((key->syms[i] != key->syms[0]) &&
1702             (key->syms[i] == NULL || key->syms[0] == NULL ||
1703              memcmp(key->syms[i], key->syms[0],
1704                     sizeof(xkb_keysym_t) * key->numLevels[0])))
1705         {
1706             identical = False;
1707             break;
1708         }
1709         if ((key->acts[i] != key->acts[0]) &&
1710             (key->acts[i] == NULL || key->acts[0] == NULL ||
1711              memcmp(key->acts[i], key->acts[0],
1712                     sizeof(union xkb_action) * key->numLevels[0])))
1713         {
1714             identical = False;
1715             break;
1716         }
1717     }
1718     if (identical)
1719     {
1720         for (i = lastGroup; i > 0; i--)
1721         {
1722             key->numLevels[i] = 0;
1723             free(key->syms[i]);
1724             key->syms[i] = NULL;
1725             free(key->acts[i]);
1726             key->acts[i] = NULL;
1727             key->types[i] = 0;
1728         }
1729         key->symsDefined &= 1;
1730         key->actsDefined &= 1;
1731         key->typesDefined &= 1;
1732     }
1733 }
1734
1735 /**
1736  * Copy the KeyInfo into the keyboard description.
1737  *
1738  * This function recurses.
1739  */
1740 static Bool
1741 CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from)
1742 {
1743     unsigned int i;
1744     xkb_keycode_t kc;
1745     unsigned width, tmp, nGroups;
1746     struct xkb_key_type * type;
1747     Bool haveActions, autoType, useAlias;
1748     xkb_keysym_t *outSyms;
1749     union xkb_action *outActs;
1750     unsigned types[XkbNumKbdGroups];
1751
1752     useAlias = (start_from == 0);
1753
1754     /* get the keycode for the key. */
1755     if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1756                       start_from))
1757     {
1758         if ((start_from == 0) && (warningLevel >= 5))
1759         {
1760             WARN("Key %s not found in keycodes\n", longText(key->name));
1761             ACTION("Symbols ignored\n");
1762         }
1763         return False;
1764     }
1765
1766     haveActions = False;
1767     for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1768     {
1769         if (((i + 1) > nGroups)
1770             && (((key->symsDefined | key->actsDefined) & (1 << i))
1771                 || (key->typesDefined) & (1 << i)))
1772             nGroups = i + 1;
1773         if (key->acts[i])
1774             haveActions = True;
1775         autoType = False;
1776         /* Assign the type to the key, if it is missing. */
1777         if (key->types[i] == XKB_ATOM_NONE)
1778         {
1779             if (key->dfltType != XKB_ATOM_NONE)
1780                 key->types[i] = key->dfltType;
1781             else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1782                                        &key->types[i], &autoType))
1783             {
1784             }
1785             else
1786             {
1787                 if (warningLevel >= 5)
1788                 {
1789                     WARN("No automatic type for %d symbols\n",
1790                           (unsigned int) key->numLevels[i]);
1791                     ACTION("Using %s for the %s key (keycode %d)\n",
1792                             XkbcAtomText(key->types[i]),
1793                             longText(key->name), kc);
1794                 }
1795             }
1796         }
1797         if (FindNamedType(xkb, key->types[i], &types[i]))
1798         {
1799             if (!autoType || key->numLevels[i] > 2)
1800                 xkb->server->explicit[kc] |= (1 << i);
1801         }
1802         else
1803         {
1804             if (warningLevel >= 3)
1805             {
1806                 WARN("Type \"%s\" is not defined\n",
1807                       XkbcAtomText(key->types[i]));
1808                 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
1809                         longText(key->name), kc);
1810             }
1811             types[i] = XkbTwoLevelIndex;
1812         }
1813         /* if the type specifies less syms than the key has, shrink the key */
1814         type = &xkb->map->types[types[i]];
1815         if (type->num_levels < key->numLevels[i])
1816         {
1817             if (warningLevel > 0)
1818             {
1819                 WARN("Type \"%s\" has %d levels, but %s has %d symbols\n",
1820                      type->name, type->num_levels,
1821                      XkbcAtomText(key->name), key->numLevels[i]);
1822                 ACTION("Ignoring extra symbols\n");
1823             }
1824             key->numLevels[i] = type->num_levels;
1825         }
1826         if (key->numLevels[i] > width)
1827             width = key->numLevels[i];
1828         if (type->num_levels > width)
1829             width = type->num_levels;
1830     }
1831
1832     /* width is now the largest width found */
1833
1834     i = width * nGroups;
1835     outSyms = XkbcResizeKeySyms(xkb, kc, i);
1836     if (outSyms == NULL)
1837     {
1838         WSGO("Could not enlarge symbols for %s (keycode %d)\n",
1839               longText(key->name), kc);
1840         return False;
1841     }
1842     if (haveActions)
1843     {
1844         outActs = XkbcResizeKeyActions(xkb, kc, i);
1845         if (outActs == NULL)
1846         {
1847             WSGO("Could not enlarge actions for %s (key %d)\n",
1848                   longText(key->name), kc);
1849             return False;
1850         }
1851         xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
1852     }
1853     else
1854         outActs = NULL;
1855     if (key->defs.defined & _Key_GroupInfo)
1856         i = key->groupInfo;
1857     else
1858         i = xkb->map->key_sym_map[kc].group_info;
1859
1860     xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
1861     xkb->map->key_sym_map[kc].width = width;
1862     for (i = 0; i < nGroups; i++)
1863     {
1864         /* assign kt_index[i] to the index of the type in map->types.
1865          * kt_index[i] may have been set by a previous run (if we have two
1866          * layouts specified). Let's not overwrite it with the ONE_LEVEL
1867          * default group if we dont even have keys for this group anyway.
1868          *
1869          * FIXME: There should be a better fix for this.
1870          */
1871         if (key->numLevels[i])
1872             xkb->map->key_sym_map[kc].kt_index[i] = types[i];
1873         if (key->syms[i] != NULL)
1874         {
1875             /* fill key to "width" symbols*/
1876             for (tmp = 0; tmp < width; tmp++)
1877             {
1878                 if (tmp < key->numLevels[i])
1879                     outSyms[tmp] = key->syms[i][tmp];
1880                 else
1881                     outSyms[tmp] = XKB_KEYSYM_NO_SYMBOL;
1882                 if ((outActs != NULL) && (key->acts[i] != NULL))
1883                 {
1884                     if (tmp < key->numLevels[i])
1885                         outActs[tmp] = key->acts[i][tmp];
1886                     else
1887                         outActs[tmp].type = XkbSA_NoAction;
1888                 }
1889             }
1890         }
1891         outSyms += width;
1892         if (outActs)
1893             outActs += width;
1894     }
1895     switch (key->behavior.type & XkbKB_OpMask)
1896     {
1897     case XkbKB_Default:
1898         break;
1899     default:
1900         xkb->server->behaviors[kc] = key->behavior;
1901         xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
1902         break;
1903     }
1904     if (key->defs.defined & _Key_VModMap)
1905     {
1906         xkb->server->vmodmap[kc] = key->vmodmap;
1907         xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
1908     }
1909     if (key->repeat != RepeatUndefined)
1910     {
1911         if (key->repeat == RepeatYes)
1912             xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
1913         else
1914             xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
1915         xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
1916     }
1917
1918     if (nGroups > xkb->ctrls->num_groups)
1919         xkb->ctrls->num_groups = nGroups;
1920
1921     /* do the same thing for the next key */
1922     CopySymbolsDef(xkb, key, kc + 1);
1923     return True;
1924 }
1925
1926 static Bool
1927 CopyModMapDef(struct xkb_desc * xkb, ModMapEntry *entry)
1928 {
1929     xkb_keycode_t kc;
1930
1931     if ((!entry->haveSymbol)
1932         &&
1933         (!FindNamedKey
1934          (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
1935     {
1936         if (warningLevel >= 5)
1937         {
1938             WARN("Key %s not found in keycodes\n",
1939                   longText(entry->u.keyName));
1940             ACTION("Modifier map entry for %s not updated\n",
1941                     XkbcModIndexText(entry->modifier));
1942         }
1943         return False;
1944     }
1945     else if (entry->haveSymbol
1946              && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
1947     {
1948         if (warningLevel > 5)
1949         {
1950             WARN("Key \"%s\" not found in symbol map\n",
1951                   XkbcKeysymText(entry->u.keySym));
1952             ACTION("Modifier map entry for %s not updated\n",
1953                     XkbcModIndexText(entry->modifier));
1954         }
1955         return False;
1956     }
1957     xkb->map->modmap[kc] |= (1 << entry->modifier);
1958     return True;
1959 }
1960
1961 /**
1962  * Handle the xkb_symbols section of an xkb file.
1963  *
1964  * @param file The parsed xkb_symbols section of the xkb file.
1965  * @param xkb Handle to the keyboard description to store the symbols in.
1966  * @param merge Merge strategy (e.g. MergeOverride).
1967  */
1968 Bool
1969 CompileSymbols(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
1970 {
1971     unsigned int i;
1972     SymbolsInfo info;
1973
1974     InitSymbolsInfo(&info, xkb);
1975     info.dflt.defs.fileID = file->id;
1976     info.dflt.defs.merge = merge;
1977     HandleSymbolsFile(file, xkb, merge, &info);
1978
1979     if (info.nKeys == 0) {
1980         FreeSymbolsInfo(&info);
1981         return True;
1982     }
1983
1984     if (info.errorCount == 0)
1985     {
1986         KeyInfo *key;
1987
1988         /* alloc memory in the xkb struct */
1989         if (XkbcAllocNames(xkb, XkbGroupNamesMask, 0) != Success)
1990         {
1991             WSGO("Can not allocate names in CompileSymbols\n");
1992             ACTION("Symbols not added\n");
1993             return False;
1994         }
1995         if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
1996             != Success)
1997         {
1998             WSGO("Could not allocate client map in CompileSymbols\n");
1999             ACTION("Symbols not added\n");
2000             return False;
2001         }
2002         if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2003         {
2004             WSGO("Could not allocate server map in CompileSymbols\n");
2005             ACTION("Symbols not added\n");
2006             return False;
2007         }
2008         if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2009         {
2010             WSGO("Could not allocate controls in CompileSymbols\n");
2011             ACTION("Symbols not added\n");
2012             return False;
2013         }
2014
2015         /* now copy info into xkb. */
2016         if (info.aliases)
2017             ApplyAliases(xkb, &info.aliases);
2018         for (i = 0; i < XkbNumKbdGroups; i++)
2019         {
2020             if (info.groupNames[i] != XKB_ATOM_NONE)
2021             {
2022                 free(UNCONSTIFY(xkb->names->groups[i]));
2023                 xkb->names->groups[i] = XkbcAtomGetString(info.groupNames[i]);
2024             }
2025         }
2026         /* sanitize keys */
2027         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2028         {
2029             PrepareKeyDef(key);
2030         }
2031         /* copy! */
2032         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2033         {
2034             if (!CopySymbolsDef(xkb, key, 0))
2035                 info.errorCount++;
2036         }
2037         if (warningLevel > 3)
2038         {
2039             for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2040             {
2041                 if (xkb->names->keys[i].name[0] == '\0')
2042                     continue;
2043                 if (XkbKeyNumGroups(xkb, i) < 1)
2044                 {
2045                     char buf[5];
2046                     memcpy(buf, xkb->names->keys[i].name, 4);
2047                     buf[4] = '\0';
2048                     WARN
2049                         ("No symbols defined for <%s> (keycode %d)\n",
2050                          buf, i);
2051                 }
2052             }
2053         }
2054         if (info.modMap)
2055         {
2056             ModMapEntry *mm, *next;
2057             for (mm = info.modMap; mm != NULL; mm = next)
2058             {
2059                 if (!CopyModMapDef(xkb, mm))
2060                     info.errorCount++;
2061                 next = (ModMapEntry *) mm->defs.next;
2062             }
2063         }
2064         FreeSymbolsInfo(&info);
2065         return True;
2066     }
2067
2068     FreeSymbolsInfo(&info);
2069     return False;
2070 }