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