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