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