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