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