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