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