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