Fix KeyInfo's syms array size calculation
[profile/ivi/libxkbcommon.git] / src / xkbcomp / symbols.c
1 /************************************************************
2  Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3
4  Permission to use, copy, modify, and distribute this
5  software and its documentation for any purpose and without
6  fee is hereby granted, provided that the above copyright
7  notice appear in all copies and that both that copyright
8  notice and this permission notice appear in supporting
9  documentation, and that the name of Silicon Graphics not be
10  used in advertising or publicity pertaining to distribution
11  of the software without specific prior written permission.
12  Silicon Graphics makes no representation about the suitability
13  of this software for any purpose. It is provided "as is"
14  without any express or implied warranty.
15
16  SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19  GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23  THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25  ********************************************************/
26
27 #include "xkbcomp.h"
28 #include "xkballoc.h"
29 #include "xkbmisc.h"
30 #include "expr.h"
31 #include "parseutils.h"
32
33 #include <X11/keysym.h>
34 #include <stdlib.h>
35
36 #include "expr.h"
37 #include "vmod.h"
38 #include "action.h"
39 #include "keycodes.h"
40 #include "misc.h"
41 #include "alias.h"
42
43 /***====================================================================***/
44
45 #define RepeatYes       1
46 #define RepeatNo        0
47 #define RepeatUndefined ~((unsigned)0)
48
49 #define _Key_Syms       (1<<0)
50 #define _Key_Acts       (1<<1)
51 #define _Key_Repeat     (1<<2)
52 #define _Key_Behavior   (1<<3)
53 #define _Key_Type_Dflt  (1<<4)
54 #define _Key_Types      (1<<5)
55 #define _Key_GroupInfo  (1<<6)
56 #define _Key_VModMap    (1<<7)
57
58 typedef struct _KeyInfo
59 {
60     CommonInfo defs;
61     unsigned long name; /* the 4 chars of the key name, as long */
62     unsigned char groupInfo;
63     unsigned char typesDefined;
64     unsigned char symsDefined;
65     unsigned char actsDefined;
66     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 */ ,
880                              struct xkb_keymap * /* xkb */ ,
881                              unsigned /* merge */ ,
882                              SymbolsInfo *      /* included */
883     );
884
885 static Bool
886 HandleIncludeSymbols(IncludeStmt * stmt,
887                      struct xkb_keymap * xkb, SymbolsInfo * info, FileHandler hndlr)
888 {
889     unsigned newMerge;
890     XkbFile *rtrn;
891     SymbolsInfo included;
892     Bool haveSelf;
893
894     haveSelf = False;
895     if ((stmt->file == NULL) && (stmt->map == NULL))
896     {
897         haveSelf = True;
898         included = *info;
899         memset(info, 0, sizeof(SymbolsInfo));
900     }
901     else if (ProcessIncludeFile(xkb->context, stmt, XkmSymbolsIndex, &rtrn,
902                                 &newMerge))
903     {
904         InitSymbolsInfo(&included, xkb);
905         included.fileID = included.dflt.defs.fileID = rtrn->id;
906         included.merge = included.dflt.defs.merge = MergeOverride;
907         if (stmt->modifier)
908         {
909             included.explicit_group = atoi(stmt->modifier) - 1;
910         }
911         else
912         {
913             included.explicit_group = info->explicit_group;
914         }
915         (*hndlr) (rtrn, xkb, MergeOverride, &included);
916         if (stmt->stmt != NULL)
917         {
918             free(included.name);
919             included.name = stmt->stmt;
920             stmt->stmt = NULL;
921         }
922         FreeXKBFile(rtrn);
923     }
924     else
925     {
926         info->errorCount += 10;
927         return False;
928     }
929     if ((stmt->next != NULL) && (included.errorCount < 1))
930     {
931         IncludeStmt *next;
932         unsigned op;
933         SymbolsInfo next_incl;
934
935         for (next = stmt->next; next != NULL; next = next->next)
936         {
937             if ((next->file == NULL) && (next->map == NULL))
938             {
939                 haveSelf = True;
940                 MergeIncludedSymbols(&included, info, next->merge, xkb);
941                 FreeSymbolsInfo(info);
942             }
943             else if (ProcessIncludeFile(xkb->context, next, XkmSymbolsIndex,
944                                         &rtrn, &op))
945             {
946                 InitSymbolsInfo(&next_incl, xkb);
947                 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
948                 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride;
949                 if (next->modifier)
950                 {
951                     next_incl.explicit_group = atoi(next->modifier) - 1;
952                 }
953                 else
954                 {
955                     next_incl.explicit_group = info->explicit_group;
956                 }
957                 (*hndlr) (rtrn, xkb, MergeOverride, &next_incl);
958                 MergeIncludedSymbols(&included, &next_incl, op, xkb);
959                 FreeSymbolsInfo(&next_incl);
960                 FreeXKBFile(rtrn);
961             }
962             else
963             {
964                 info->errorCount += 10;
965                 FreeSymbolsInfo(&included);
966                 return False;
967             }
968         }
969     }
970     else if (stmt->next)
971     {
972         info->errorCount += included.errorCount;
973     }
974     if (haveSelf)
975         *info = included;
976     else
977     {
978         MergeIncludedSymbols(info, &included, newMerge, xkb);
979         FreeSymbolsInfo(&included);
980     }
981     return (info->errorCount == 0);
982 }
983
984 #define SYMBOLS 1
985 #define ACTIONS 2
986
987 static Bool
988 GetGroupIndex(KeyInfo * key,
989               ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
990 {
991     const char *name;
992     ExprResult tmp;
993
994     if (what == SYMBOLS)
995         name = "symbols";
996     else
997         name = "actions";
998
999     if (arrayNdx == NULL)
1000     {
1001         int i;
1002         unsigned defined;
1003         if (what == SYMBOLS)
1004             defined = key->symsDefined;
1005         else
1006             defined = key->actsDefined;
1007
1008         for (i = 0; i < XkbNumKbdGroups; i++)
1009         {
1010             if ((defined & (1 << i)) == 0)
1011             {
1012                 *ndx_rtrn = i;
1013                 return True;
1014             }
1015         }
1016         ERROR("Too many groups of %s for key %s (max %d)\n", name,
1017                longText(key->name), XkbNumKbdGroups + 1);
1018         ACTION("Ignoring %s defined for extra groups\n", name);
1019         return False;
1020     }
1021     if (!ExprResolveGroup(arrayNdx, &tmp))
1022     {
1023         ERROR("Illegal group index for %s of key %s\n", name,
1024                longText(key->name));
1025         ACTION("Definition with non-integer array index ignored\n");
1026         return False;
1027     }
1028     *ndx_rtrn = tmp.uval - 1;
1029     return True;
1030 }
1031
1032 static Bool
1033 AddSymbolsToKey(KeyInfo * key,
1034                 struct xkb_keymap * xkb,
1035                 char *field,
1036                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1037 {
1038     unsigned ndx, nSyms, nLevels;
1039     unsigned int i;
1040     long j;
1041
1042     if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx))
1043         return False;
1044     if (value == NULL)
1045     {
1046         key->symsDefined |= (1 << ndx);
1047         return True;
1048     }
1049     if (value->op != ExprKeysymList)
1050     {
1051         ERROR("Expected a list of symbols, found %s\n", exprOpText(value->op));
1052         ACTION("Ignoring symbols for group %d of %s\n", ndx + 1,
1053                 longText(key->name));
1054         return False;
1055     }
1056     if (key->sizeSyms[ndx] != 0)
1057     {
1058         ERROR("Symbols for key %s, group %d already defined\n",
1059                longText(key->name), ndx + 1);
1060         ACTION("Ignoring duplicate definition\n");
1061         return False;
1062     }
1063     nSyms = value->value.list.nSyms;
1064     nLevels = value->value.list.nLevels;
1065     if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
1066         (!ResizeKeyGroup(key, ndx, nLevels, nSyms, False)))
1067     {
1068         WSGO("Could not resize group %d of key %s to contain %d levels\n",
1069              ndx + 1, longText(key->name), nSyms);
1070         ACTION("Symbols lost\n");
1071         return False;
1072     }
1073     key->symsDefined |= (1 << ndx);
1074     for (i = 0; i < nLevels; i++) {
1075         key->symsMapIndex[ndx][i] = value->value.list.symsMapIndex[i];
1076         key->symsMapNumEntries[ndx][i] = value->value.list.symsNumEntries[i];
1077         for (j = 0; j < key->symsMapNumEntries[ndx][i]; j++) {
1078             if (key->symsMapIndex[ndx][i] + j >= nSyms)
1079                 abort();
1080             if (!LookupKeysym(value->value.list.syms[value->value.list.symsMapIndex[i] + j],
1081                               &key->syms[ndx][key->symsMapIndex[ndx][i] + j])) {
1082                 WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
1083                      value->value.list.syms[i], longText(key->name), ndx + 1,
1084                      XkbcAtomText(info->groupNames[ndx]), nSyms);
1085                 while (--j >= 0)
1086                     key->syms[ndx][key->symsMapIndex[ndx][i] + j] = NoSymbol;
1087                 key->symsMapIndex[ndx][i] = -1;
1088                 key->symsMapNumEntries[ndx][i] = 0;
1089                 break;
1090             }
1091         }
1092     }
1093     for (j = key->numLevels[ndx] - 1;
1094          j >= 0 && key->symsMapNumEntries[ndx][j] == 0; j--)
1095         key->numLevels[ndx]--;
1096     return True;
1097 }
1098
1099 static Bool
1100 AddActionsToKey(KeyInfo * key,
1101                 struct xkb_keymap * xkb,
1102                 char *field,
1103                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1104 {
1105     unsigned int i;
1106     unsigned ndx, nActs;
1107     ExprDef *act;
1108     struct xkb_any_action *toAct;
1109
1110     if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx))
1111         return False;
1112
1113     if (value == NULL)
1114     {
1115         key->actsDefined |= (1 << ndx);
1116         return True;
1117     }
1118     if (value->op != ExprActionList)
1119     {
1120         WSGO("Bad expression type (%d) for action list value\n", value->op);
1121         ACTION("Ignoring actions for group %d of %s\n", ndx,
1122                 longText(key->name));
1123         return False;
1124     }
1125     if (key->acts[ndx] != NULL)
1126     {
1127         WSGO("Actions for key %s, group %d already defined\n",
1128               longText(key->name), ndx);
1129         return False;
1130     }
1131     for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1132     {
1133         act = (ExprDef *) act->common.next;
1134     }
1135     if (nActs < 1)
1136     {
1137         WSGO("Action list but not actions in AddActionsToKey\n");
1138         return False;
1139     }
1140     if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1141         (!ResizeKeyGroup(key, ndx, nActs, nActs, True)))
1142     {
1143         WSGO("Could not resize group %d of key %s\n", ndx,
1144               longText(key->name));
1145         ACTION("Actions lost\n");
1146         return False;
1147     }
1148     key->actsDefined |= (1 << ndx);
1149
1150     toAct = (struct xkb_any_action *) key->acts[ndx];
1151     act = value->value.child;
1152     for (i = 0; i < nActs; i++, toAct++)
1153     {
1154         if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action))
1155         {
1156             ERROR("Illegal action definition for %s\n",
1157                    longText(key->name));
1158             ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1159         }
1160         act = (ExprDef *) act->common.next;
1161     }
1162     return True;
1163 }
1164
1165 static const LookupEntry lockingEntries[] = {
1166     {"true", XkbKB_Lock},
1167     {"yes", XkbKB_Lock},
1168     {"on", XkbKB_Lock},
1169     {"false", XkbKB_Default},
1170     {"no", XkbKB_Default},
1171     {"off", XkbKB_Default},
1172     {"permanent", XkbKB_Lock | XkbKB_Permanent},
1173     {NULL, 0}
1174 };
1175
1176 static const LookupEntry repeatEntries[] = {
1177     {"true", RepeatYes},
1178     {"yes", RepeatYes},
1179     {"on", RepeatYes},
1180     {"false", RepeatNo},
1181     {"no", RepeatNo},
1182     {"off", RepeatNo},
1183     {"default", RepeatUndefined},
1184     {NULL, 0}
1185 };
1186
1187 static Bool
1188 SetSymbolsField(KeyInfo * key,
1189                 struct xkb_keymap * xkb,
1190                 char *field,
1191                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1192 {
1193     Bool ok = True;
1194     ExprResult tmp;
1195
1196     if (strcasecmp(field, "type") == 0)
1197     {
1198         ExprResult ndx;
1199         if ((!ExprResolveString(value, &tmp))
1200             && (warningLevel > 0))
1201         {
1202             WARN("The type field of a key symbol map must be a string\n");
1203             ACTION("Ignoring illegal type definition\n");
1204         }
1205         if (arrayNdx == NULL)
1206         {
1207             key->dfltType = xkb_intern_atom(tmp.str);
1208             key->defs.defined |= _Key_Type_Dflt;
1209         }
1210         else if (!ExprResolveGroup(arrayNdx, &ndx))
1211         {
1212             ERROR("Illegal group index for type of key %s\n",
1213                    longText(key->name));
1214             ACTION("Definition with non-integer array index ignored\n");
1215             free(tmp.str);
1216             return False;
1217         }
1218         else
1219         {
1220             key->types[ndx.uval - 1] = xkb_intern_atom(tmp.str);
1221             key->typesDefined |= (1 << (ndx.uval - 1));
1222         }
1223         free(tmp.str);
1224     }
1225     else if (strcasecmp(field, "symbols") == 0)
1226         return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1227     else if (strcasecmp(field, "actions") == 0)
1228         return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1229     else if ((strcasecmp(field, "vmods") == 0) ||
1230              (strcasecmp(field, "virtualmods") == 0) ||
1231              (strcasecmp(field, "virtualmodifiers") == 0))
1232     {
1233         ok = ExprResolveVModMask(value, &tmp, xkb);
1234         if (ok)
1235         {
1236             key->vmodmap = (tmp.uval >> 8);
1237             key->defs.defined |= _Key_VModMap;
1238         }
1239         else
1240         {
1241             ERROR("Expected a virtual modifier mask, found %s\n",
1242                    exprOpText(value->op));
1243             ACTION("Ignoring virtual modifiers definition for key %s\n",
1244                     longText(key->name));
1245         }
1246     }
1247     else if ((strcasecmp(field, "locking") == 0) ||
1248              (strcasecmp(field, "lock") == 0) ||
1249              (strcasecmp(field, "locks") == 0))
1250     {
1251         ok = ExprResolveEnum(value, &tmp, lockingEntries);
1252         if (ok)
1253             key->behavior.type = tmp.uval;
1254         key->defs.defined |= _Key_Behavior;
1255     }
1256     else if ((strcasecmp(field, "radiogroup") == 0) ||
1257              (strcasecmp(field, "permanentradiogroup") == 0) ||
1258              (strcasecmp(field, "allownone") == 0))
1259     {
1260         ERROR("Radio groups not supported\n");
1261         ACTION("Ignoring radio group specification for key %s\n", longText(key->name));
1262         return False;
1263     }
1264     else if (uStrCasePrefix("overlay", field) ||
1265              uStrCasePrefix("permanentoverlay", field))
1266     {
1267         ERROR("Overlays not supported\n");
1268         ACTION("Ignoring overlay specification for key %s\n", longText(key->name));
1269     }
1270     else if ((strcasecmp(field, "repeating") == 0) ||
1271              (strcasecmp(field, "repeats") == 0) ||
1272              (strcasecmp(field, "repeat") == 0))
1273     {
1274         ok = ExprResolveEnum(value, &tmp, repeatEntries);
1275         if (!ok)
1276         {
1277             ERROR("Illegal repeat setting for %s\n",
1278                    longText(key->name));
1279             ACTION("Non-boolean repeat setting ignored\n");
1280             return False;
1281         }
1282         key->repeat = tmp.uval;
1283         key->defs.defined |= _Key_Repeat;
1284     }
1285     else if ((strcasecmp(field, "groupswrap") == 0) ||
1286              (strcasecmp(field, "wrapgroups") == 0))
1287     {
1288         ok = ExprResolveBoolean(value, &tmp);
1289         if (!ok)
1290         {
1291             ERROR("Illegal groupsWrap setting for %s\n",
1292                    longText(key->name));
1293             ACTION("Non-boolean value ignored\n");
1294             return False;
1295         }
1296         if (tmp.uval)
1297             key->groupInfo = XkbWrapIntoRange;
1298         else
1299             key->groupInfo = XkbClampIntoRange;
1300         key->defs.defined |= _Key_GroupInfo;
1301     }
1302     else if ((strcasecmp(field, "groupsclamp") == 0) ||
1303              (strcasecmp(field, "clampgroups") == 0))
1304     {
1305         ok = ExprResolveBoolean(value, &tmp);
1306         if (!ok)
1307         {
1308             ERROR("Illegal groupsClamp setting for %s\n",
1309                    longText(key->name));
1310             ACTION("Non-boolean value ignored\n");
1311             return False;
1312         }
1313         if (tmp.uval)
1314             key->groupInfo = XkbClampIntoRange;
1315         else
1316             key->groupInfo = XkbWrapIntoRange;
1317         key->defs.defined |= _Key_GroupInfo;
1318     }
1319     else if ((strcasecmp(field, "groupsredirect") == 0) ||
1320              (strcasecmp(field, "redirectgroups") == 0))
1321     {
1322         if (!ExprResolveGroup(value, &tmp))
1323         {
1324             ERROR("Illegal group index for redirect of key %s\n",
1325                    longText(key->name));
1326             ACTION("Definition with non-integer group ignored\n");
1327             return False;
1328         }
1329         key->groupInfo =
1330             XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1331         key->defs.defined |= _Key_GroupInfo;
1332     }
1333     else
1334     {
1335         ERROR("Unknown field %s in a symbol interpretation\n", field);
1336         ACTION("Definition ignored\n");
1337         ok = False;
1338     }
1339     return ok;
1340 }
1341
1342 static int
1343 SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1344 {
1345     ExprResult tmp, name;
1346
1347     if ((arrayNdx == NULL) && (warningLevel > 0))
1348     {
1349         WARN("You must specify an index when specifying a group name\n");
1350         ACTION("Group name definition without array subscript ignored\n");
1351         return False;
1352     }
1353     if (!ExprResolveGroup(arrayNdx, &tmp))
1354     {
1355         ERROR("Illegal index in group name definition\n");
1356         ACTION("Definition with non-integer array index ignored\n");
1357         return False;
1358     }
1359     if (!ExprResolveString(value, &name))
1360     {
1361         ERROR("Group name must be a string\n");
1362         ACTION("Illegal name for group %d ignored\n", tmp.uval);
1363         return False;
1364     }
1365     info->groupNames[tmp.uval - 1 + info->explicit_group] =
1366         xkb_intern_atom(name.str);
1367     free(name.str);
1368
1369     return True;
1370 }
1371
1372 static int
1373 HandleSymbolsVar(VarDef * stmt, struct xkb_keymap * xkb, SymbolsInfo * info)
1374 {
1375     ExprResult elem, field, tmp;
1376     ExprDef *arrayNdx;
1377     Bool ret;
1378
1379     if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1380         return 0;               /* internal error, already reported */
1381     if (elem.str && (strcasecmp(elem.str, "key") == 0))
1382     {
1383         ret = SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1384                               stmt->value, info);
1385     }
1386     else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) ||
1387                                     (strcasecmp(field.str, "groupname") ==
1388                                      0)))
1389     {
1390         ret = SetGroupName(info, arrayNdx, stmt->value);
1391     }
1392     else if ((elem.str == NULL)
1393              && ((strcasecmp(field.str, "groupswrap") == 0) ||
1394                  (strcasecmp(field.str, "wrapgroups") == 0)))
1395     {
1396         if (!ExprResolveBoolean(stmt->value, &tmp))
1397         {
1398             ERROR("Illegal setting for global groupsWrap\n");
1399             ACTION("Non-boolean value ignored\n");
1400             ret = False;
1401         }
1402         else {
1403             if (tmp.uval)
1404                 info->groupInfo = XkbWrapIntoRange;
1405             else
1406                 info->groupInfo = XkbClampIntoRange;
1407             ret = True;
1408         }
1409     }
1410     else if ((elem.str == NULL)
1411              && ((strcasecmp(field.str, "groupsclamp") == 0) ||
1412                  (strcasecmp(field.str, "clampgroups") == 0)))
1413     {
1414         if (!ExprResolveBoolean(stmt->value, &tmp))
1415         {
1416             ERROR("Illegal setting for global groupsClamp\n");
1417             ACTION("Non-boolean value ignored\n");
1418             return False;
1419         }
1420         else {
1421             if (tmp.uval)
1422                 info->groupInfo = XkbClampIntoRange;
1423             else
1424                 info->groupInfo = XkbWrapIntoRange;
1425             ret = True;
1426         }
1427     }
1428     else if ((elem.str == NULL)
1429              && ((strcasecmp(field.str, "groupsredirect") == 0) ||
1430                  (strcasecmp(field.str, "redirectgroups") == 0)))
1431     {
1432         if (!ExprResolveGroup(stmt->value, &tmp))
1433         {
1434             ERROR("Illegal group index for global groupsRedirect\n");
1435             ACTION("Definition with non-integer group ignored\n");
1436             ret = False;
1437         }
1438         else {
1439             info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange,
1440                                               tmp.uval);
1441             ret = True;
1442         }
1443     }
1444     else if ((elem.str == NULL) && (strcasecmp(field.str, "allownone") == 0))
1445     {
1446         ERROR("Radio groups not supported\n");
1447         ACTION("Ignoring \"allow none\" specification\n");
1448         ret = False;
1449     }
1450     else {
1451         ret = SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1452                              &info->action);
1453     }
1454
1455     free(elem.str);
1456     free(field.str);
1457     return ret;
1458 }
1459
1460 static Bool
1461 HandleSymbolsBody(VarDef * def,
1462                   struct xkb_keymap * xkb, KeyInfo * key, SymbolsInfo * info)
1463 {
1464     Bool ok = True;
1465     ExprResult tmp, field;
1466     ExprDef *arrayNdx;
1467
1468     for (; def != NULL; def = (VarDef *) def->common.next)
1469     {
1470         if ((def->name) && (def->name->type == ExprFieldRef))
1471         {
1472             ok = HandleSymbolsVar(def, xkb, info);
1473             continue;
1474         }
1475         else
1476         {
1477             if (def->name == NULL)
1478             {
1479                 if ((def->value == NULL)
1480                     || (def->value->op == ExprKeysymList))
1481                     field.str = strdup("symbols");
1482                 else
1483                     field.str = strdup("actions");
1484                 arrayNdx = NULL;
1485             }
1486             else
1487             {
1488                 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1489             }
1490             if (ok)
1491                 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1492                                      def->value, info);
1493             free(field.str);
1494         }
1495     }
1496     return ok;
1497 }
1498
1499 static Bool
1500 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1501 {
1502     unsigned group = info->explicit_group;
1503
1504     if (group == 0)
1505         return True;
1506
1507     if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1508     {
1509         int i;
1510         WARN("For the map %s an explicit group specified\n", info->name);
1511         WARN("but key %s has more than one group defined\n",
1512               longText(key->name));
1513         ACTION("All groups except first one will be ignored\n");
1514         for (i = 1; i < XkbNumKbdGroups; i++)
1515         {
1516             key->numLevels[i] = 0;
1517             free(key->syms[i]);
1518             key->syms[i] = NULL;
1519             free(key->acts[i]);
1520             key->acts[i] = NULL;
1521             key->types[i] = 0;
1522         }
1523     }
1524     key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1525
1526     key->numLevels[group] = key->numLevels[0];
1527     key->numLevels[0] = 0;
1528     key->syms[group] = key->syms[0];
1529     key->syms[0] = NULL;
1530     key->sizeSyms[group] = key->sizeSyms[0];
1531     key->sizeSyms[0] = 0;
1532     key->symsMapIndex[group] = key->symsMapIndex[0];
1533     key->symsMapIndex[0] = NULL;
1534     key->symsMapNumEntries[group] = key->symsMapNumEntries[0];
1535     key->symsMapNumEntries[0] = NULL;
1536     key->acts[group] = key->acts[0];
1537     key->acts[0] = NULL;
1538     key->types[group] = key->types[0];
1539     key->types[0] = 0;
1540     return True;
1541 }
1542
1543 static int
1544 HandleSymbolsDef(SymbolsDef * stmt,
1545                  struct xkb_keymap * xkb, unsigned merge, SymbolsInfo * info)
1546 {
1547     KeyInfo key;
1548
1549     InitKeyInfo(&key);
1550     CopyKeyInfo(&info->dflt, &key, False);
1551     key.defs.merge = stmt->merge;
1552     key.name = KeyNameToLong(stmt->keyName);
1553     if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1554     {
1555         info->errorCount++;
1556         return False;
1557     }
1558
1559     if (!SetExplicitGroup(info, &key))
1560     {
1561         info->errorCount++;
1562         return False;
1563     }
1564
1565     if (!AddKeySymbols(info, &key, xkb))
1566     {
1567         info->errorCount++;
1568         return False;
1569     }
1570     return True;
1571 }
1572
1573 static Bool
1574 HandleModMapDef(ModMapDef * def,
1575                 struct xkb_keymap * xkb, unsigned merge, SymbolsInfo * info)
1576 {
1577     ExprDef *key;
1578     ModMapEntry tmp;
1579     ExprResult rtrn;
1580     Bool ok;
1581
1582     if (!LookupModIndex(NULL, def->modifier, TypeInt, &rtrn))
1583     {
1584         ERROR("Illegal modifier map definition\n");
1585         ACTION("Ignoring map for non-modifier \"%s\"\n",
1586                 XkbcAtomText(def->modifier));
1587         return False;
1588     }
1589     ok = True;
1590     tmp.modifier = rtrn.uval;
1591     for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1592     {
1593         if ((key->op == ExprValue) && (key->type == TypeKeyName))
1594         {
1595             tmp.haveSymbol = False;
1596             tmp.u.keyName = KeyNameToLong(key->value.keyName);
1597         }
1598         else if (ExprResolveKeySym(key, &rtrn))
1599         {
1600             tmp.haveSymbol = True;
1601             tmp.u.keySym = rtrn.uval;
1602         }
1603         else
1604         {
1605             ERROR("Modmap entries may contain only key names or keysyms\n");
1606             ACTION("Illegal definition for %s modifier ignored\n",
1607                     XkbcModIndexText(tmp.modifier));
1608             continue;
1609         }
1610
1611         ok = AddModMapEntry(info, &tmp) && ok;
1612     }
1613     return ok;
1614 }
1615
1616 static void
1617 HandleSymbolsFile(XkbFile * file,
1618                   struct xkb_keymap * xkb, unsigned merge, SymbolsInfo * info)
1619 {
1620     ParseCommon *stmt;
1621
1622     free(info->name);
1623     info->name = uDupString(file->name);
1624     stmt = file->defs;
1625     while (stmt)
1626     {
1627         switch (stmt->stmtType)
1628         {
1629         case StmtInclude:
1630             if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1631                                       HandleSymbolsFile))
1632                 info->errorCount++;
1633             break;
1634         case StmtSymbolsDef:
1635             if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1636                 info->errorCount++;
1637             break;
1638         case StmtVarDef:
1639             if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1640                 info->errorCount++;
1641             break;
1642         case StmtVModDef:
1643             if (!HandleVModDef((VModDef *) stmt, xkb, merge, &info->vmods))
1644                 info->errorCount++;
1645             break;
1646         case StmtInterpDef:
1647             ERROR("Interpretation files may not include other types\n");
1648             ACTION("Ignoring definition of symbol interpretation\n");
1649             info->errorCount++;
1650             break;
1651         case StmtKeycodeDef:
1652             ERROR("Interpretation files may not include other types\n");
1653             ACTION("Ignoring definition of key name\n");
1654             info->errorCount++;
1655             break;
1656         case StmtModMapDef:
1657             if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1658                 info->errorCount++;
1659             break;
1660         default:
1661             WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1662                   stmt->stmtType);
1663             break;
1664         }
1665         stmt = stmt->next;
1666         if (info->errorCount > 10)
1667         {
1668 #ifdef NOISY
1669             ERROR("Too many errors\n");
1670 #endif
1671             ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1672             break;
1673         }
1674     }
1675 }
1676
1677 static Bool
1678 FindKeyForSymbol(struct xkb_keymap * xkb, xkb_keysym_t sym, xkb_keycode_t *kc_rtrn)
1679 {
1680     xkb_keycode_t key;
1681     unsigned int group, level;
1682
1683     for (key = xkb->min_key_code; key <= xkb->max_key_code; key++)
1684     {
1685         for (group = 0; group < XkbKeyNumGroups(xkb, key); group++)
1686         {
1687             for (level = 0; level < XkbKeyGroupWidth(xkb, key, group); level++)
1688             {
1689                 if (XkbKeyNumSyms(xkb, key, group, level) != 1 ||
1690                     (XkbKeySymEntry(xkb, key, group, level))[0] != sym)
1691                     continue;
1692                 *kc_rtrn = key;
1693                 return True;
1694             }
1695         }
1696     }
1697
1698     return False;
1699 }
1700
1701 /**
1702  * Find the given name in the xkb->map->types and return its index.
1703  *
1704  * @param atom The atom to search for.
1705  * @param type_rtrn Set to the index of the name if found.
1706  *
1707  * @return True if found, False otherwise.
1708  */
1709 static Bool
1710 FindNamedType(struct xkb_keymap * xkb, xkb_atom_t atom, unsigned *type_rtrn)
1711 {
1712     unsigned n;
1713     const char *name = XkbcAtomText(atom);
1714
1715     if (xkb && xkb->map && xkb->map->types)
1716     {
1717         for (n = 0; n < xkb->map->num_types; n++)
1718         {
1719             if (strcmp(xkb->map->types[n].name, name) == 0)
1720             {
1721                 *type_rtrn = n;
1722                 return True;
1723             }
1724         }
1725     }
1726     return False;
1727 }
1728
1729 /**
1730  * Assign a type to the given sym and return the Atom for the type assigned.
1731  *
1732  * Simple recipe:
1733  * - ONE_LEVEL for width 0/1
1734  * - ALPHABETIC for 2 shift levels, with lower/upercase
1735  * - KEYPAD for keypad keys.
1736  * - TWO_LEVEL for other 2 shift level keys.
1737  * and the same for four level keys.
1738  *
1739  * @param width Number of sysms in syms.
1740  * @param syms The keysyms for the given key (must be size width).
1741  * @param typeNameRtrn Set to the Atom of the type name.
1742  *
1743  * @returns True if a type could be found, False otherwise.
1744  */
1745 static Bool
1746 FindAutomaticType(int width, xkb_keysym_t * syms, xkb_atom_t * typeNameRtrn,
1747                   Bool * autoType)
1748 {
1749     *autoType = False;
1750     if ((width == 1) || (width == 0))
1751     {
1752         *typeNameRtrn = xkb_intern_atom("ONE_LEVEL");
1753         *autoType = True;
1754     }
1755     else if (width == 2)
1756     {
1757         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1758         {
1759             *typeNameRtrn = xkb_intern_atom("ALPHABETIC");
1760         }
1761         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1762         {
1763             *typeNameRtrn = xkb_intern_atom("KEYPAD");
1764             *autoType = True;
1765         }
1766         else
1767         {
1768             *typeNameRtrn = xkb_intern_atom("TWO_LEVEL");
1769             *autoType = True;
1770         }
1771     }
1772     else if (width <= 4)
1773     {
1774         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1775             if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1776                 *typeNameRtrn =
1777                     xkb_intern_atom("FOUR_LEVEL_ALPHABETIC");
1778             else
1779                 *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_SEMIALPHABETIC");
1780
1781         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1782             *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_KEYPAD");
1783         else
1784             *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL");
1785         /* XXX: why not set autoType here? */
1786     }
1787     return ((width >= 0) && (width <= 4));
1788 }
1789
1790 /**
1791  * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1792  * groups, and reduce to one group if all groups are identical anyway.
1793  */
1794 static void
1795 PrepareKeyDef(KeyInfo * key)
1796 {
1797     int i, j, width, defined, lastGroup;
1798     Bool identical;
1799
1800     defined = key->symsDefined | key->actsDefined | key->typesDefined;
1801     /* get highest group number */
1802     for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1803     {
1804         if (defined & (1 << i))
1805             break;
1806     }
1807     lastGroup = i;
1808
1809     if (lastGroup == 0)
1810         return;
1811
1812     /* If there are empty groups between non-empty ones fill them with data */
1813     /* from the first group. */
1814     /* We can make a wrong assumption here. But leaving gaps is worse. */
1815     for (i = lastGroup; i > 0; i--)
1816     {
1817         if (defined & (1 << i))
1818             continue;
1819         width = key->numLevels[0];
1820         if (key->typesDefined & 1)
1821         {
1822             for (j = 0; j < width; j++)
1823             {
1824                 key->types[i] = key->types[0];
1825             }
1826             key->typesDefined |= 1 << i;
1827         }
1828         if ((key->actsDefined & 1) && key->acts[0])
1829         {
1830             key->acts[i] = uTypedCalloc(width, union xkb_action);
1831             if (key->acts[i] == NULL)
1832                 continue;
1833             memcpy(key->acts[i], key->acts[0],
1834                    width * sizeof(union xkb_action));
1835             key->actsDefined |= 1 << i;
1836         }
1837         if ((key->symsDefined & 1) && key->sizeSyms[0])
1838         {
1839             key->syms[i] = uTypedCalloc(key->sizeSyms[0], xkb_keysym_t);
1840             if (key->syms[i] == NULL)
1841                 continue;
1842             memcpy(key->syms[i], key->syms[0],
1843                    key->sizeSyms[0] * sizeof(xkb_keysym_t));
1844             key->symsMapIndex[i] = uTypedCalloc(width, int);
1845             if (!key->symsMapIndex[i])
1846             {
1847                 free(key->syms[i]);
1848                 key->syms[i] = NULL;
1849                 continue;
1850             }
1851             memcpy(key->symsMapIndex[i], key->symsMapIndex[0],
1852                    width * sizeof(int));
1853             key->symsMapNumEntries[i] = uTypedCalloc(width, unsigned int);
1854             if (!key->symsMapNumEntries[i])
1855             {
1856                 free(key->syms[i]);
1857                 key->syms[i] = NULL;
1858                 free(key->symsMapIndex[i]);
1859                 key->symsMapIndex[i] = NULL;
1860                 continue;
1861             }
1862             memcpy(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
1863                    width * sizeof(int));
1864             key->sizeSyms[i] = key->sizeSyms[0];
1865             key->symsDefined |= 1 << i;
1866         }
1867         if (defined & 1)
1868         {
1869             key->numLevels[i] = key->numLevels[0];
1870         }
1871     }
1872     /* If all groups are completely identical remove them all */
1873     /* exept the first one. */
1874     identical = True;
1875     for (i = lastGroup; i > 0; i--)
1876     {
1877         if ((key->numLevels[i] != key->numLevels[0]) ||
1878             (key->types[i] != key->types[0]))
1879         {
1880             identical = False;
1881             break;
1882         }
1883         if ((key->syms[i] != key->syms[0]) &&
1884             (key->syms[i] == NULL || key->syms[0] == NULL ||
1885              key->sizeSyms[i] != key->sizeSyms[0] ||
1886              memcmp(key->syms[i], key->syms[0],
1887                     sizeof(xkb_keysym_t) * key->sizeSyms[0])))
1888         {
1889             identical = False;
1890             break;
1891         }
1892         if ((key->symsMapIndex[i] != key->symsMapIndex[i]) &&
1893             (key->symsMapIndex[i] == NULL || key->symsMapIndex[0] == NULL ||
1894              memcmp(key->symsMapIndex[i], key->symsMapIndex[0],
1895                     key->numLevels[0] * sizeof(int))))
1896         {
1897             identical = False;
1898             continue;
1899         }
1900         if ((key->symsMapNumEntries[i] != key->symsMapNumEntries[i]) &&
1901             (key->symsMapNumEntries[i] == NULL ||
1902              key->symsMapNumEntries[0] == NULL ||
1903              memcmp(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
1904                     key->numLevels[0] * sizeof(int))))
1905         {
1906             identical = False;
1907             continue;
1908         }
1909         if ((key->acts[i] != key->acts[0]) &&
1910             (key->acts[i] == NULL || key->acts[0] == NULL ||
1911              memcmp(key->acts[i], key->acts[0],
1912                     sizeof(union xkb_action) * key->numLevels[0])))
1913         {
1914             identical = False;
1915             break;
1916         }
1917     }
1918     if (identical)
1919     {
1920         for (i = lastGroup; i > 0; i--)
1921         {
1922             key->numLevels[i] = 0;
1923             free(key->syms[i]);
1924             key->syms[i] = NULL;
1925             key->sizeSyms[i] = 0;
1926             free(key->symsMapIndex[i]);
1927             key->symsMapIndex[i] = NULL;
1928             free(key->symsMapNumEntries[i]);
1929             key->symsMapNumEntries[i] = NULL;
1930             free(key->acts[i]);
1931             key->acts[i] = NULL;
1932             key->types[i] = 0;
1933         }
1934         key->symsDefined &= 1;
1935         key->actsDefined &= 1;
1936         key->typesDefined &= 1;
1937     }
1938 }
1939
1940 /**
1941  * Copy the KeyInfo into the keyboard description.
1942  *
1943  * This function recurses.
1944  */
1945 static Bool
1946 CopySymbolsDef(struct xkb_keymap * xkb, KeyInfo *key, int start_from)
1947 {
1948     unsigned int i;
1949     xkb_keycode_t kc;
1950     unsigned int sizeSyms = 0;
1951     unsigned width, tmp, nGroups;
1952     struct xkb_key_type * type;
1953     Bool haveActions, autoType, useAlias;
1954     unsigned types[XkbNumKbdGroups];
1955     union xkb_action *outActs;
1956     unsigned int symIndex = 0;
1957
1958     useAlias = (start_from == 0);
1959
1960     /* get the keycode for the key. */
1961     if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1962                       start_from))
1963     {
1964         if ((start_from == 0) && (warningLevel >= 5))
1965         {
1966             WARN("Key %s not found in keycodes\n", longText(key->name));
1967             ACTION("Symbols ignored\n");
1968         }
1969         return False;
1970     }
1971
1972     haveActions = False;
1973     for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1974     {
1975         if (((i + 1) > nGroups)
1976             && (((key->symsDefined | key->actsDefined) & (1 << i))
1977                 || (key->typesDefined) & (1 << i)))
1978             nGroups = i + 1;
1979         if (key->acts[i])
1980             haveActions = True;
1981         autoType = False;
1982         /* Assign the type to the key, if it is missing. */
1983         if (key->types[i] == XKB_ATOM_NONE)
1984         {
1985             if (key->dfltType != XKB_ATOM_NONE)
1986                 key->types[i] = key->dfltType;
1987             else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1988                                        &key->types[i], &autoType))
1989             {
1990             }
1991             else
1992             {
1993                 if (warningLevel >= 5)
1994                 {
1995                     WARN("No automatic type for %d symbols\n",
1996                           (unsigned int) key->numLevels[i]);
1997                     ACTION("Using %s for the %s key (keycode %d)\n",
1998                             XkbcAtomText(key->types[i]),
1999                             longText(key->name), kc);
2000                 }
2001             }
2002         }
2003         if (FindNamedType(xkb, key->types[i], &types[i]))
2004         {
2005             if (!autoType || key->numLevels[i] > 2)
2006                 xkb->server->explicit[kc] |= (1 << i);
2007         }
2008         else
2009         {
2010             if (warningLevel >= 3)
2011             {
2012                 WARN("Type \"%s\" is not defined\n",
2013                       XkbcAtomText(key->types[i]));
2014                 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
2015                         longText(key->name), kc);
2016             }
2017             types[i] = XkbTwoLevelIndex;
2018         }
2019         /* if the type specifies fewer levels than the key has, shrink the key */
2020         type = &xkb->map->types[types[i]];
2021         if (type->num_levels < key->numLevels[i])
2022         {
2023             if (warningLevel > 0)
2024             {
2025                 WARN("Type \"%s\" has %d levels, but %s has %d symbols\n",
2026                      type->name, type->num_levels,
2027                      XkbcAtomText(key->name), key->numLevels[i]);
2028                 ACTION("Ignoring extra symbols\n");
2029             }
2030             key->numLevels[i] = type->num_levels;
2031         }
2032         if (key->numLevels[i] > width)
2033             width = key->numLevels[i];
2034         if (type->num_levels > width)
2035             width = type->num_levels;
2036         sizeSyms += key->sizeSyms[i];
2037     }
2038
2039     if (!XkbcResizeKeySyms(xkb, kc, sizeSyms))
2040     {
2041         WSGO("Could not enlarge symbols for %s (keycode %d)\n",
2042               longText(key->name), kc);
2043         return False;
2044     }
2045     if (haveActions)
2046     {
2047         outActs = XkbcResizeKeyActions(xkb, kc, width * nGroups);
2048         if (outActs == NULL)
2049         {
2050             WSGO("Could not enlarge actions for %s (key %d)\n",
2051                   longText(key->name), kc);
2052             return False;
2053         }
2054         xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
2055     }
2056     else
2057         outActs = NULL;
2058     if (key->defs.defined & _Key_GroupInfo)
2059         i = key->groupInfo;
2060     else
2061         i = xkb->map->key_sym_map[kc].group_info;
2062
2063     xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2064     xkb->map->key_sym_map[kc].width = width;
2065     xkb->map->key_sym_map[kc].sym_index = uTypedCalloc(nGroups * width, int);
2066     xkb->map->key_sym_map[kc].num_syms = uTypedCalloc(nGroups * width,
2067                                                       unsigned int);
2068     for (i = 0; i < nGroups; i++)
2069     {
2070         /* assign kt_index[i] to the index of the type in map->types.
2071          * kt_index[i] may have been set by a previous run (if we have two
2072          * layouts specified). Let's not overwrite it with the ONE_LEVEL
2073          * default group if we dont even have keys for this group anyway.
2074          *
2075          * FIXME: There should be a better fix for this.
2076          */
2077         if (key->numLevels[i])
2078             xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2079         if (key->sizeSyms[i] != 0)
2080         {
2081             /* fill key to "width" symbols*/
2082             for (tmp = 0; tmp < width; tmp++)
2083             {
2084                 if (tmp < key->numLevels[i] && key->symsMapNumEntries[i][tmp])
2085                 {
2086                     memcpy(&xkb->map->key_sym_map[kc].syms[symIndex],
2087                            &key->syms[i][key->symsMapIndex[i][tmp]],
2088                            key->symsMapNumEntries[i][tmp] *
2089                             sizeof(xkb_keysym_t));
2090                     xkb->map->key_sym_map[kc].sym_index[(i * width) + tmp] =
2091                         symIndex;
2092                     xkb->map->key_sym_map[kc].num_syms[(i * width) + tmp] =
2093                         key->symsMapNumEntries[i][tmp];
2094                     symIndex +=
2095                         xkb->map->key_sym_map[kc].num_syms[(i * width) + tmp];
2096                 }
2097                 else
2098                 {
2099                     xkb->map->key_sym_map[kc].sym_index[(i * width) + tmp] = -1;
2100                     xkb->map->key_sym_map[kc].num_syms[(i * width) + tmp] = 0;
2101                 }
2102                 if ((outActs != NULL) && (key->acts[i] != NULL))
2103                 {
2104                     if (tmp < key->numLevels[i])
2105                         outActs[tmp] = key->acts[i][tmp];
2106                     else
2107                         outActs[tmp].type = XkbSA_NoAction;
2108                 }
2109             }
2110         }
2111     }
2112     switch (key->behavior.type & XkbKB_OpMask)
2113     {
2114     case XkbKB_Default:
2115         break;
2116     default:
2117         xkb->server->behaviors[kc] = key->behavior;
2118         xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2119         break;
2120     }
2121     if (key->defs.defined & _Key_VModMap)
2122     {
2123         xkb->server->vmodmap[kc] = key->vmodmap;
2124         xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2125     }
2126     if (key->repeat != RepeatUndefined)
2127     {
2128         if (key->repeat == RepeatYes)
2129             xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2130         else
2131             xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2132         xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2133     }
2134
2135     if (nGroups > xkb->ctrls->num_groups)
2136         xkb->ctrls->num_groups = nGroups;
2137
2138     /* do the same thing for the next key */
2139     CopySymbolsDef(xkb, key, kc + 1);
2140     return True;
2141 }
2142
2143 static Bool
2144 CopyModMapDef(struct xkb_keymap * xkb, ModMapEntry *entry)
2145 {
2146     xkb_keycode_t kc;
2147
2148     if ((!entry->haveSymbol)
2149         &&
2150         (!FindNamedKey
2151          (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
2152     {
2153         if (warningLevel >= 5)
2154         {
2155             WARN("Key %s not found in keycodes\n",
2156                   longText(entry->u.keyName));
2157             ACTION("Modifier map entry for %s not updated\n",
2158                     XkbcModIndexText(entry->modifier));
2159         }
2160         return False;
2161     }
2162     else if (entry->haveSymbol
2163              && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2164     {
2165         if (warningLevel > 5)
2166         {
2167             WARN("Key \"%s\" not found in symbol map\n",
2168                   XkbcKeysymText(entry->u.keySym));
2169             ACTION("Modifier map entry for %s not updated\n",
2170                     XkbcModIndexText(entry->modifier));
2171         }
2172         return False;
2173     }
2174     xkb->map->modmap[kc] |= (1 << entry->modifier);
2175     return True;
2176 }
2177
2178 /**
2179  * Handle the xkb_symbols section of an xkb file.
2180  *
2181  * @param file The parsed xkb_symbols section of the xkb file.
2182  * @param xkb Handle to the keyboard description to store the symbols in.
2183  * @param merge Merge strategy (e.g. MergeOverride).
2184  */
2185 Bool
2186 CompileSymbols(XkbFile *file, struct xkb_keymap * xkb, unsigned merge)
2187 {
2188     unsigned int i;
2189     SymbolsInfo info;
2190
2191     InitSymbolsInfo(&info, xkb);
2192     info.dflt.defs.fileID = file->id;
2193     info.dflt.defs.merge = merge;
2194     HandleSymbolsFile(file, xkb, merge, &info);
2195
2196     if (info.nKeys == 0) {
2197         FreeSymbolsInfo(&info);
2198         return False;
2199     }
2200
2201     if (info.errorCount == 0)
2202     {
2203         KeyInfo *key;
2204
2205         /* alloc memory in the xkb struct */
2206         if (XkbcAllocNames(xkb, XkbGroupNamesMask, 0) != Success)
2207         {
2208             WSGO("Can not allocate names in CompileSymbols\n");
2209             ACTION("Symbols not added\n");
2210             return False;
2211         }
2212         if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2213             != Success)
2214         {
2215             WSGO("Could not allocate client map in CompileSymbols\n");
2216             ACTION("Symbols not added\n");
2217             return False;
2218         }
2219         if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2220         {
2221             WSGO("Could not allocate server map in CompileSymbols\n");
2222             ACTION("Symbols not added\n");
2223             return False;
2224         }
2225         if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2226         {
2227             WSGO("Could not allocate controls in CompileSymbols\n");
2228             ACTION("Symbols not added\n");
2229             return False;
2230         }
2231
2232         /* now copy info into xkb. */
2233         if (info.aliases)
2234             ApplyAliases(xkb, &info.aliases);
2235         for (i = 0; i < XkbNumKbdGroups; i++)
2236         {
2237             if (info.groupNames[i] != XKB_ATOM_NONE)
2238             {
2239                 free(UNCONSTIFY(xkb->names->groups[i]));
2240                 xkb->names->groups[i] = XkbcAtomGetString(info.groupNames[i]);
2241             }
2242         }
2243         /* sanitize keys */
2244         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2245         {
2246             PrepareKeyDef(key);
2247         }
2248         /* copy! */
2249         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2250         {
2251             if (!CopySymbolsDef(xkb, key, 0))
2252                 info.errorCount++;
2253         }
2254         if (warningLevel > 3)
2255         {
2256             for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2257             {
2258                 if (xkb->names->keys[i].name[0] == '\0')
2259                     continue;
2260                 if (XkbKeyNumGroups(xkb, i) < 1)
2261                 {
2262                     char buf[5];
2263                     memcpy(buf, xkb->names->keys[i].name, 4);
2264                     buf[4] = '\0';
2265                     WARN
2266                         ("No symbols defined for <%s> (keycode %d)\n",
2267                          buf, i);
2268                 }
2269             }
2270         }
2271         if (info.modMap)
2272         {
2273             ModMapEntry *mm, *next;
2274             for (mm = info.modMap; mm != NULL; mm = next)
2275             {
2276                 if (!CopyModMapDef(xkb, mm))
2277                     info.errorCount++;
2278                 next = (ModMapEntry *) mm->defs.next;
2279             }
2280         }
2281         FreeSymbolsInfo(&info);
2282         return True;
2283     }
2284
2285     FreeSymbolsInfo(&info);
2286     return False;
2287 }