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