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