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