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