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