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