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