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