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