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