Remove unused allowNone from KeyInfo
[profile/ivi/libxkbcommon.git] / src / xkbcomp / symbols.c
1 /************************************************************
2  Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3
4  Permission to use, copy, modify, and distribute this
5  software and its documentation for any purpose and without
6  fee is hereby granted, provided that the above copyright
7  notice appear in all copies and that both that copyright
8  notice and this permission notice appear in supporting
9  documentation, and that the name of Silicon Graphics not be
10  used in advertising or publicity pertaining to distribution
11  of the software without specific prior written permission.
12  Silicon Graphics makes no representation about the suitability
13  of this software for any purpose. It is provided "as is"
14  without any express or implied warranty.
15
16  SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19  GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23  THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25  ********************************************************/
26
27 #include "xkbcomp-priv.h"
28 #include "parseutils.h"
29 #include "action.h"
30 #include "alias.h"
31 #include "keycodes.h"
32 #include "vmod.h"
33
34 /***====================================================================***/
35
36 #define RepeatYes       1
37 #define RepeatNo        0
38 #define RepeatUndefined ~((unsigned)0)
39
40 #define _Key_Syms       (1<<0)
41 #define _Key_Acts       (1<<1)
42 #define _Key_Repeat     (1<<2)
43 #define _Key_Behavior   (1<<3)
44 #define _Key_Type_Dflt  (1<<4)
45 #define _Key_Types      (1<<5)
46 #define _Key_GroupInfo  (1<<6)
47 #define _Key_VModMap    (1<<7)
48
49 typedef struct _KeyInfo
50 {
51     CommonInfo defs;
52     unsigned long name; /* the 4 chars of the key name, as long */
53     unsigned char groupInfo;
54     unsigned char typesDefined;
55     unsigned char symsDefined;
56     unsigned char actsDefined;
57     unsigned int numLevels[XkbNumKbdGroups];
58
59     /* syms[group] -> Single array for all the keysyms in the group. */
60     xkb_keysym_t *syms[XkbNumKbdGroups];
61     /* sizeSyms[group] -> The size of the syms[group] array. */
62     int sizeSyms[XkbNumKbdGroups];
63     /*
64      * symsMapIndex[group][level] -> The index from which the syms for
65      * the level begin in the syms[group] array. Remember each keycode
66      * can have multiple keysyms in each level (that is, each key press
67      * can result in multiple keysyms).
68      */
69     int *symsMapIndex[XkbNumKbdGroups];
70     /*
71      * symsMapNumEntries[group][level] -> How many syms are in
72      * syms[group][symsMapIndex[group][level]].
73      */
74     unsigned int *symsMapNumEntries[XkbNumKbdGroups];
75
76     union xkb_action *acts[XkbNumKbdGroups];
77     xkb_atom_t types[XkbNumKbdGroups];
78     unsigned repeat;
79     struct xkb_behavior behavior;
80     unsigned short vmodmap;
81     xkb_atom_t dfltType;
82 } KeyInfo;
83
84 /**
85  * Init the given key info to sane values.
86  */
87 static void
88 InitKeyInfo(KeyInfo * info)
89 {
90     int i;
91     static char dflt[4] = "*";
92
93     info->defs.defined = 0;
94     info->defs.fileID = 0;
95     info->defs.merge = MergeOverride;
96     info->defs.next = NULL;
97     info->name = KeyNameToLong(dflt);
98     info->groupInfo = 0;
99     info->typesDefined = info->symsDefined = info->actsDefined = 0;
100     for (i = 0; i < XkbNumKbdGroups; i++)
101     {
102         info->numLevels[i] = 0;
103         info->types[i] = XKB_ATOM_NONE;
104         info->syms[i] = NULL;
105         info->sizeSyms[i] = 0;
106         info->symsMapIndex[i] = NULL;
107         info->symsMapNumEntries[i] = NULL;
108         info->acts[i] = NULL;
109     }
110     info->dfltType = XKB_ATOM_NONE;
111     info->behavior.type = XkbKB_Default;
112     info->behavior.data = 0;
113     info->vmodmap = 0;
114     info->repeat = RepeatUndefined;
115 }
116
117 /**
118  * Free memory associated with this key info and reset to sane values.
119  */
120 static void
121 FreeKeyInfo(KeyInfo * info)
122 {
123     int i;
124
125     info->defs.defined = 0;
126     info->defs.fileID = 0;
127     info->defs.merge = MergeOverride;
128     info->defs.next = NULL;
129     info->groupInfo = 0;
130     info->typesDefined = info->symsDefined = info->actsDefined = 0;
131     for (i = 0; i < XkbNumKbdGroups; i++)
132     {
133         info->numLevels[i] = 0;
134         info->types[i] = XKB_ATOM_NONE;
135         free(info->syms[i]);
136         info->syms[i] = NULL;
137         info->sizeSyms[i] = 0;
138         free(info->symsMapIndex[i]);
139         info->symsMapIndex[i] = NULL;
140         free(info->symsMapNumEntries[i]);
141         info->symsMapNumEntries[i] = NULL;
142         free(info->acts[i]);
143         info->acts[i] = NULL;
144     }
145     info->dfltType = XKB_ATOM_NONE;
146     info->behavior.type = XkbKB_Default;
147     info->behavior.data = 0;
148     info->vmodmap = 0;
149     info->repeat = RepeatUndefined;
150 }
151
152 /**
153  * Copy old into new, optionally reset old to 0.
154  * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
155  * newly allocated and new points to the new memory areas.
156  */
157 static bool
158 CopyKeyInfo(KeyInfo * old, KeyInfo * new, bool clearOld)
159 {
160     int i;
161
162     *new = *old;
163     new->defs.next = NULL;
164     if (clearOld)
165     {
166         for (i = 0; i < XkbNumKbdGroups; i++)
167         {
168             old->numLevels[i] = 0;
169             old->symsMapIndex[i] = NULL;
170             old->symsMapNumEntries[i] = NULL;
171             old->syms[i] = NULL;
172             old->sizeSyms[i] = 0;
173             old->acts[i] = NULL;
174         }
175     }
176     else
177     {
178         unsigned int width;
179         for (i = 0; i < XkbNumKbdGroups; i++)
180         {
181             width = new->numLevels[i];
182             if (old->syms[i] != NULL)
183             {
184                 new->syms[i] = uTypedCalloc(new->sizeSyms[i], xkb_keysym_t);
185                 if (!new->syms[i])
186                 {
187                     new->syms[i] = NULL;
188                     new->sizeSyms[i] = 0;
189                     new->numLevels[i] = 0;
190                     new->acts[i] = NULL;
191                     return false;
192                 }
193                 memcpy(new->syms[i], old->syms[i],
194                        new->sizeSyms[i] * sizeof(xkb_keysym_t));
195                 new->symsMapIndex[i] = uTypedCalloc(width, int);
196                 if (!new->symsMapIndex[i])
197                 {
198                     free(new->syms[i]);
199                     new->syms[i] = NULL;
200                     new->sizeSyms[i] = 0;
201                     new->numLevels[i] = 0;
202                     new->acts[i] = NULL;
203                     return false;
204                 }
205                 memcpy(new->symsMapIndex[i], old->symsMapIndex[i],
206                        width * sizeof(int));
207                 new->symsMapNumEntries[i] = uTypedCalloc(width, unsigned int);
208                 if (!new->symsMapNumEntries[i])
209                 {
210                     free(new->syms[i]);
211                     new->syms[i] = NULL;
212                     new->sizeSyms[i] = 0;
213                     free(new->symsMapIndex[i]);
214                     new->symsMapIndex[i] = NULL;
215                     new->numLevels[i] = 0;
216                     new->acts[i] = NULL;
217                     return false;
218                 }
219                 memcpy(new->symsMapNumEntries[i], old->symsMapNumEntries[i],
220                        width * sizeof(unsigned int));
221             }
222             if (old->acts[i] != NULL)
223             {
224                 new->acts[i] = uTypedCalloc(width, union xkb_action);
225                 if (!new->acts[i])
226                 {
227                     free(new->syms[i]);
228                     new->syms[i] = NULL;
229                     new->sizeSyms[i] = 0;
230                     free(new->symsMapIndex[i]);
231                     new->symsMapIndex[i] = NULL;
232                     free(new->symsMapNumEntries[i]);
233                     new->symsMapNumEntries[i] = NULL;
234                     new->numLevels[i] = 0;
235                     return false;
236                 }
237                 memcpy(new->acts[i], old->acts[i],
238                        width * sizeof(union xkb_action));
239             }
240         }
241     }
242     return true;
243 }
244
245 /***====================================================================***/
246
247 typedef struct _ModMapEntry
248 {
249     CommonInfo defs;
250     bool haveSymbol;
251     int modifier;
252     union
253     {
254         unsigned long keyName;
255         xkb_keysym_t keySym;
256     } u;
257 } ModMapEntry;
258
259 #define SYMBOLS_INIT_SIZE       110
260 #define SYMBOLS_CHUNK           20
261 typedef struct _SymbolsInfo
262 {
263     char *name;         /* e.g. pc+us+inet(evdev) */
264     int errorCount;
265     unsigned fileID;
266     unsigned merge;
267     unsigned explicit_group;
268     unsigned groupInfo;
269     unsigned szKeys;
270     unsigned nKeys;
271     KeyInfo *keys;
272     KeyInfo dflt;
273     VModInfo vmods;
274     ActionInfo *action;
275     xkb_atom_t groupNames[XkbNumKbdGroups];
276
277     ModMapEntry *modMap;
278     AliasInfo *aliases;
279 } SymbolsInfo;
280
281 static void
282 InitSymbolsInfo(SymbolsInfo * info, struct xkb_keymap *keymap)
283 {
284     int i;
285
286     info->name = NULL;
287     info->explicit_group = 0;
288     info->errorCount = 0;
289     info->fileID = 0;
290     info->merge = MergeOverride;
291     info->groupInfo = 0;
292     info->szKeys = SYMBOLS_INIT_SIZE;
293     info->nKeys = 0;
294     info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo);
295     info->modMap = NULL;
296     for (i = 0; i < XkbNumKbdGroups; i++)
297         info->groupNames[i] = XKB_ATOM_NONE;
298     InitKeyInfo(&info->dflt);
299     InitVModInfo(&info->vmods, keymap);
300     info->action = NULL;
301     info->aliases = NULL;
302 }
303
304 static void
305 FreeSymbolsInfo(SymbolsInfo * info)
306 {
307     unsigned int i;
308
309     free(info->name);
310     if (info->keys)
311     {
312         for (i = 0; i < info->nKeys; i++)
313             FreeKeyInfo(&info->keys[i]);
314         free(info->keys);
315     }
316     if (info->modMap)
317         ClearCommonInfo(&info->modMap->defs);
318     if (info->aliases)
319         ClearAliases(&info->aliases);
320     memset(info, 0, sizeof(SymbolsInfo));
321 }
322
323 static bool
324 ResizeKeyGroup(KeyInfo * key, unsigned int group, unsigned int numLevels,
325                unsigned sizeSyms, bool forceActions)
326 {
327     int i;
328
329     if (key->syms[group] == NULL || key->sizeSyms[group] < sizeSyms)
330     {
331         key->syms[group] = uTypedRecalloc(key->syms[group],
332                                           key->sizeSyms[group],
333                                           sizeSyms,
334                                           xkb_keysym_t);
335         if (!key->syms[group]) {
336             key->sizeSyms[group] = 0;
337             return false;
338         }
339         key->sizeSyms[group] = sizeSyms;
340     }
341     if (!key->symsMapIndex[group] || key->numLevels[group] < numLevels)
342     {
343         key->symsMapIndex[group] = uTypedRealloc(key->symsMapIndex[group],
344                                                  numLevels,
345                                                  int);
346         if (!key->symsMapIndex[group])
347             return false;
348         for (i = key->numLevels[group]; i < numLevels; i++)
349             key->symsMapIndex[group][i] = -1;
350     }
351     if (!key->symsMapNumEntries[group] || key->numLevels[group] < numLevels)
352     {
353         key->symsMapNumEntries[group] =
354             uTypedRecalloc(key->symsMapNumEntries[group],
355                            key->numLevels[group],
356                            numLevels,
357                            unsigned int);
358         if (!key->symsMapNumEntries[group])
359             return false;
360     }
361     if ((forceActions &&
362          (key->numLevels[group] < numLevels || (key->acts[group] == NULL))) ||
363         (key->numLevels[group] < numLevels && (key->acts[group] != NULL)))
364     {
365         key->acts[group] = uTypedRecalloc(key->acts[group],
366                                           key->numLevels[group],
367                                           numLevels,
368                                           union xkb_action);
369         if (!key->acts[group])
370             return false;
371     }
372     if (key->numLevels[group] < numLevels)
373         key->numLevels[group] = numLevels;
374     return true;
375 }
376
377 static bool
378 MergeKeyGroups(SymbolsInfo * info,
379                KeyInfo * into, KeyInfo * from, unsigned group)
380 {
381     xkb_keysym_t *resultSyms = NULL;
382     union xkb_action *resultActs;
383     unsigned int resultWidth;
384     unsigned int resultSize = 0;
385     int cur_idx = 0;
386     int i;
387     bool report, clobber;
388
389     clobber = (from->defs.merge != MergeAugment);
390     report = (warningLevel > 9) ||
391         ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
392     if (into->numLevels[group] >= from->numLevels[group])
393     {
394         resultActs = into->acts[group];
395         resultWidth = into->numLevels[group];
396     }
397     else
398     {
399         resultActs = from->acts[group];
400         resultWidth = from->numLevels[group];
401         into->symsMapIndex[group] = uTypedRealloc(into->symsMapIndex[group],
402                                                   from->numLevels[group],
403                                                   int);
404         into->symsMapNumEntries[group] =
405             uTypedRecalloc(into->symsMapNumEntries[group],
406                            into->numLevels[group],
407                            from->numLevels[group],
408                            unsigned int);
409         if (!into->symsMapIndex[group] || !into->symsMapNumEntries[group])
410         {
411             WSGO("Could not allocate level indices for key info merge\n");
412             ACTION("Group %d of key %s not merged\n", group,
413                    longText(into->name));
414
415             return false;
416         }
417         for (i = into->numLevels[group]; i < from->numLevels[group]; i++)
418             into->symsMapIndex[group][i] = -1;
419     }
420
421     if ((resultActs == NULL) && (into->acts[group] || from->acts[group]))
422     {
423         resultActs = uTypedCalloc(resultWidth, union xkb_action);
424         if (!resultActs)
425         {
426             WSGO("Could not allocate actions for group merge\n");
427             ACTION("Group %d of key %s not merged\n", group,
428                     longText(into->name));
429             return false;
430         }
431         for (i = 0; i < resultWidth; i++)
432         {
433             union xkb_action *fromAct, *toAct;
434             fromAct = (from->acts[group] ? &from->acts[group][i] : NULL);
435             toAct = (into->acts[group] ? &into->acts[group][i] : NULL);
436             if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
437                 && (toAct != NULL))
438             {
439                 resultActs[i] = *toAct;
440             }
441             else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
442                      && (fromAct != NULL))
443             {
444                 resultActs[i] = *fromAct;
445             }
446             else
447             {
448                 union xkb_action *use, *ignore;
449                 if (clobber)
450                 {
451                     use = fromAct;
452                     ignore = toAct;
453                 }
454                 else
455                 {
456                     use = toAct;
457                     ignore = fromAct;
458                 }
459                 if (report)
460                 {
461                     WARN
462                         ("Multiple actions for level %d/group %d on key %s\n",
463                          i + 1, group + 1, longText(into->name));
464                     ACTION("Using %s, ignoring %s\n",
465                             XkbcActionTypeText(use->type),
466                             XkbcActionTypeText(ignore->type));
467                 }
468                 if (use)
469                     resultActs[i] = *use;
470             }
471         }
472     }
473
474     for (i = 0; i < resultWidth; i++)
475     {
476         unsigned int fromSize = 0;
477         unsigned toSize = 0;
478
479         if (from->symsMapNumEntries[group] && (i < from->numLevels[group]))
480             fromSize = from->symsMapNumEntries[group][i];
481         if (into->symsMapNumEntries[group] && (i < into->numLevels[group]))
482             toSize = into->symsMapNumEntries[group][i];
483
484         if (fromSize == 0 || fromSize == toSize || clobber)
485         {
486             fromSize += toSize;
487         }
488         else if (toSize == 0)
489         {
490             resultSize += fromSize;
491         }
492     }
493
494     if (resultSize == 0)
495         goto out;
496
497     resultSyms = uTypedCalloc(resultSize, xkb_keysym_t);
498     if (!resultSyms)
499     {
500         WSGO("Could not allocate symbols for group merge\n");
501         ACTION("Group %d of key %s not merged\n", group, longText(into->name));
502         return false;
503     }
504
505     for (i = 0; i < resultWidth; i++)
506     {
507         enum { NONE, FROM, TO } use;
508         unsigned int fromSize = 0;
509         unsigned int toSize = 0;
510
511         if (from->symsMapNumEntries[group] && (i < from->numLevels[group]))
512             fromSize = from->symsMapNumEntries[group][i];
513         if (into->symsMapNumEntries[group] && (i < into->numLevels[group]))
514             toSize = into->symsMapNumEntries[group][i];
515
516         if (!fromSize && !toSize)
517         {
518             into->symsMapIndex[group][i] = -1;
519             into->symsMapNumEntries[group][i] = 0;
520             continue;
521         }
522
523         if ((fromSize && !toSize) || clobber)
524             use = FROM;
525         else
526             use = TO;
527
528         if (toSize && fromSize && report)
529         {
530             INFO("Multiple symbols for group %d, level %d on key %s\n",
531                  group + 1, i + 1, longText(into->name));
532             ACTION("Using %s, ignoring %s\n",
533                    (use == FROM ? "from" : "to"),
534                    (use == FROM ? "to" : "from"));
535         }
536
537         if (use == FROM)
538         {
539             memcpy(&resultSyms[cur_idx],
540                    &from->syms[group][from->symsMapIndex[group][i]],
541                    from->symsMapNumEntries[group][i] * sizeof(xkb_keysym_t));
542             into->symsMapIndex[group][i] = cur_idx;
543             into->symsMapNumEntries[group][i] =
544                 from->symsMapNumEntries[group][i];
545         }
546         else
547         {
548             memcpy(&resultSyms[cur_idx],
549                    &into->syms[group][from->symsMapIndex[group][i]],
550                    into->symsMapNumEntries[group][i] * sizeof(xkb_keysym_t));
551             into->symsMapIndex[group][i] = cur_idx;
552         }
553         cur_idx += into->symsMapNumEntries[group][i];
554     }
555
556 out:
557     if (resultActs != into->acts[group])
558         free(into->acts[group]);
559     if (resultActs != from->acts[group])
560         free(from->acts[group]);
561     into->numLevels[group] = resultWidth;
562     free(into->syms[group]);
563     into->syms[group] = resultSyms;
564     free(from->syms[group]);
565     from->syms[group] = NULL;
566     from->sizeSyms[group] = 0;
567     into->sizeSyms[group] = resultSize;
568     free(from->symsMapIndex[group]);
569     from->symsMapIndex[group] = NULL;
570     free(from->symsMapNumEntries[group]);
571     from->symsMapNumEntries[group] = NULL;
572     into->acts[group] = resultActs;
573     from->acts[group] = NULL;
574     into->symsDefined |= (1 << group);
575     from->symsDefined &= ~(1 << group);
576     into->actsDefined |= (1 << group);
577     from->actsDefined &= ~(1 << group);
578
579     return true;
580 }
581
582 static bool
583 MergeKeys(SymbolsInfo *info, struct xkb_keymap *keymap,
584           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                         xkb_atom_text(keymap->ctx, use),
666                         xkb_atom_text(keymap->ctx, 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, keymap, &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, keymap, &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->ctx, stmt, XkmSymbolsIndex, &rtrn,
892                                 &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->ctx, next, XkmSymbolsIndex,
934                                         &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, struct xkb_keymap *keymap,
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(keymap->ctx, 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, keymap, 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                      xkb_atom_text(keymap->ctx, info->groupNames[ndx]), nSyms);
1073                 while (--j >= 0)
1074                     key->syms[ndx][key->symsMapIndex[ndx][i] + j] = XKB_KEY_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, keymap, 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(keymap->ctx, 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(keymap->ctx, tmp.str);
1192             key->defs.defined |= _Key_Type_Dflt;
1193         }
1194         else if (!ExprResolveGroup(keymap->ctx, 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(keymap->ctx, 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(keymap->ctx, 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(keymap->ctx, 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(keymap->ctx, 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(keymap->ctx, 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(keymap->ctx, 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 *keymap, 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(keymap->ctx, 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(keymap->ctx, 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(keymap->ctx, 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(keymap, 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, keymap, 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(keymap->ctx, 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(keymap->ctx, 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(keymap->ctx, 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(keymap, def->name, &tmp, &field,
1474                                     &arrayNdx);
1475             }
1476             if (ok)
1477                 ok = SetSymbolsField(key, keymap, field.str, arrayNdx,
1478                                      def->value, info);
1479             free(field.str);
1480         }
1481     }
1482     return ok;
1483 }
1484
1485 static bool
1486 SetExplicitGroup(SymbolsInfo *info, KeyInfo *key)
1487 {
1488     unsigned group = info->explicit_group;
1489
1490     if (group == 0)
1491         return true;
1492
1493     if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1494     {
1495         int i;
1496         WARN("For the map %s an explicit group specified\n", info->name);
1497         WARN("but key %s has more than one group defined\n",
1498               longText(key->name));
1499         ACTION("All groups except first one will be ignored\n");
1500         for (i = 1; i < XkbNumKbdGroups; i++)
1501         {
1502             key->numLevels[i] = 0;
1503             free(key->syms[i]);
1504             key->syms[i] = NULL;
1505             free(key->acts[i]);
1506             key->acts[i] = NULL;
1507             key->types[i] = 0;
1508         }
1509     }
1510     key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1511
1512     key->numLevels[group] = key->numLevels[0];
1513     key->numLevels[0] = 0;
1514     key->syms[group] = key->syms[0];
1515     key->syms[0] = NULL;
1516     key->sizeSyms[group] = key->sizeSyms[0];
1517     key->sizeSyms[0] = 0;
1518     key->symsMapIndex[group] = key->symsMapIndex[0];
1519     key->symsMapIndex[0] = NULL;
1520     key->symsMapNumEntries[group] = key->symsMapNumEntries[0];
1521     key->symsMapNumEntries[0] = NULL;
1522     key->acts[group] = key->acts[0];
1523     key->acts[0] = NULL;
1524     key->types[group] = key->types[0];
1525     key->types[0] = 0;
1526     return true;
1527 }
1528
1529 static int
1530 HandleSymbolsDef(SymbolsDef *stmt, struct xkb_keymap *keymap,
1531                  SymbolsInfo *info)
1532 {
1533     KeyInfo key;
1534
1535     InitKeyInfo(&key);
1536     CopyKeyInfo(&info->dflt, &key, false);
1537     key.defs.merge = stmt->merge;
1538     key.name = KeyNameToLong(stmt->keyName);
1539     if (!HandleSymbolsBody((VarDef *) stmt->symbols, keymap, &key, info))
1540     {
1541         info->errorCount++;
1542         return false;
1543     }
1544
1545     if (!SetExplicitGroup(info, &key))
1546     {
1547         info->errorCount++;
1548         return false;
1549     }
1550
1551     if (!AddKeySymbols(info, &key, keymap))
1552     {
1553         info->errorCount++;
1554         return false;
1555     }
1556     return true;
1557 }
1558
1559 static bool
1560 HandleModMapDef(ModMapDef *def, struct xkb_keymap *keymap, SymbolsInfo *info)
1561 {
1562     ExprDef *key;
1563     ModMapEntry tmp;
1564     ExprResult rtrn;
1565     bool ok;
1566
1567     if (!LookupModIndex(keymap->ctx, NULL, def->modifier, TypeInt, &rtrn))
1568     {
1569         ERROR("Illegal modifier map definition\n");
1570         ACTION("Ignoring map for non-modifier \"%s\"\n",
1571                 xkb_atom_text(keymap->ctx, def->modifier));
1572         return false;
1573     }
1574     ok = true;
1575     tmp.modifier = rtrn.uval;
1576     for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1577     {
1578         if ((key->op == ExprValue) && (key->type == TypeKeyName))
1579         {
1580             tmp.haveSymbol = false;
1581             tmp.u.keyName = KeyNameToLong(key->value.keyName);
1582         }
1583         else if (ExprResolveKeySym(keymap->ctx, key, &rtrn))
1584         {
1585             tmp.haveSymbol = true;
1586             tmp.u.keySym = rtrn.uval;
1587         }
1588         else
1589         {
1590             ERROR("Modmap entries may contain only key names or keysyms\n");
1591             ACTION("Illegal definition for %s modifier ignored\n",
1592                     XkbcModIndexText(tmp.modifier));
1593             continue;
1594         }
1595
1596         ok = AddModMapEntry(info, &tmp) && ok;
1597     }
1598     return ok;
1599 }
1600
1601 static void
1602 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
1603                   unsigned merge, SymbolsInfo *info)
1604 {
1605     ParseCommon *stmt;
1606
1607     free(info->name);
1608     info->name = uDupString(file->name);
1609     stmt = file->defs;
1610     while (stmt)
1611     {
1612         switch (stmt->stmtType)
1613         {
1614         case StmtInclude:
1615             if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info,
1616                                       HandleSymbolsFile))
1617                 info->errorCount++;
1618             break;
1619         case StmtSymbolsDef:
1620             if (!HandleSymbolsDef((SymbolsDef *) stmt, keymap, info))
1621                 info->errorCount++;
1622             break;
1623         case StmtVarDef:
1624             if (!HandleSymbolsVar((VarDef *) stmt, keymap, info))
1625                 info->errorCount++;
1626             break;
1627         case StmtVModDef:
1628             if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
1629                 info->errorCount++;
1630             break;
1631         case StmtInterpDef:
1632             ERROR("Interpretation files may not include other types\n");
1633             ACTION("Ignoring definition of symbol interpretation\n");
1634             info->errorCount++;
1635             break;
1636         case StmtKeycodeDef:
1637             ERROR("Interpretation files may not include other types\n");
1638             ACTION("Ignoring definition of key name\n");
1639             info->errorCount++;
1640             break;
1641         case StmtModMapDef:
1642             if (!HandleModMapDef((ModMapDef *) stmt, keymap, info))
1643                 info->errorCount++;
1644             break;
1645         default:
1646             WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1647                   stmt->stmtType);
1648             break;
1649         }
1650         stmt = stmt->next;
1651         if (info->errorCount > 10)
1652         {
1653 #ifdef NOISY
1654             ERROR("Too many errors\n");
1655 #endif
1656             ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1657             break;
1658         }
1659     }
1660 }
1661
1662 static bool
1663 FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
1664                  xkb_keycode_t *kc_rtrn)
1665 {
1666     xkb_keycode_t key;
1667     unsigned int group, level;
1668
1669     for (key = keymap->min_key_code; key <= keymap->max_key_code; key++)
1670     {
1671         for (group = 0; group < XkbKeyNumGroups(keymap, key); group++)
1672         {
1673             for (level = 0; level < XkbKeyGroupWidth(keymap, key, group);
1674                  level++)
1675             {
1676                 if (XkbKeyNumSyms(keymap, key, group, level) != 1 ||
1677                     (XkbKeySymEntry(keymap, key, group, level))[0] != sym)
1678                     continue;
1679                 *kc_rtrn = key;
1680                 return true;
1681             }
1682         }
1683     }
1684
1685     return false;
1686 }
1687
1688 /**
1689  * Find the given name in the keymap->map->types and return its index.
1690  *
1691  * @param atom The atom to search for.
1692  * @param type_rtrn Set to the index of the name if found.
1693  *
1694  * @return true if found, false otherwise.
1695  */
1696 static bool
1697 FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn)
1698 {
1699     unsigned n;
1700     const char *name = xkb_atom_text(keymap->ctx, atom);
1701
1702     if (keymap && keymap->map && keymap->map->types)
1703     {
1704         for (n = 0; n < keymap->map->num_types; n++)
1705         {
1706             if (strcmp(keymap->map->types[n].name, name) == 0)
1707             {
1708                 *type_rtrn = n;
1709                 return true;
1710             }
1711         }
1712     }
1713     return false;
1714 }
1715
1716 /**
1717  * Assign a type to the given sym and return the Atom for the type assigned.
1718  *
1719  * Simple recipe:
1720  * - ONE_LEVEL for width 0/1
1721  * - ALPHABETIC for 2 shift levels, with lower/upercase
1722  * - KEYPAD for keypad keys.
1723  * - TWO_LEVEL for other 2 shift level keys.
1724  * and the same for four level keys.
1725  *
1726  * @param width Number of sysms in syms.
1727  * @param syms The keysyms for the given key (must be size width).
1728  * @param typeNameRtrn Set to the Atom of the type name.
1729  *
1730  * @returns true if a type could be found, false otherwise.
1731  */
1732 static bool
1733 FindAutomaticType(struct xkb_keymap *keymap, int width, xkb_keysym_t *syms,
1734                   xkb_atom_t *typeNameRtrn, bool *autoType)
1735 {
1736     *autoType = false;
1737     if ((width == 1) || (width == 0))
1738     {
1739         *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
1740         *autoType = true;
1741     }
1742     else if (width == 2)
1743     {
1744         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1745         {
1746             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
1747         }
1748         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1749         {
1750             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "KEYPAD");
1751             *autoType = true;
1752         }
1753         else
1754         {
1755             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
1756             *autoType = true;
1757         }
1758     }
1759     else if (width <= 4)
1760     {
1761         if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1762             if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1763                 *typeNameRtrn =
1764                     xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_ALPHABETIC");
1765             else
1766                 *typeNameRtrn = xkb_atom_intern(keymap->ctx,
1767                                                 "FOUR_LEVEL_SEMIALPHABETIC");
1768
1769         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1770             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_KEYPAD");
1771         else
1772             *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL");
1773         /* XXX: why not set autoType here? */
1774     }
1775     return ((width >= 0) && (width <= 4));
1776 }
1777
1778 /**
1779  * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1780  * groups, and reduce to one group if all groups are identical anyway.
1781  */
1782 static void
1783 PrepareKeyDef(KeyInfo * key)
1784 {
1785     int i, j, width, defined, lastGroup;
1786     bool identical;
1787
1788     defined = key->symsDefined | key->actsDefined | key->typesDefined;
1789     /* get highest group number */
1790     for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1791     {
1792         if (defined & (1 << i))
1793             break;
1794     }
1795     lastGroup = i;
1796
1797     if (lastGroup == 0)
1798         return;
1799
1800     /* If there are empty groups between non-empty ones fill them with data */
1801     /* from the first group. */
1802     /* We can make a wrong assumption here. But leaving gaps is worse. */
1803     for (i = lastGroup; i > 0; i--)
1804     {
1805         if (defined & (1 << i))
1806             continue;
1807         width = key->numLevels[0];
1808         if (key->typesDefined & 1)
1809         {
1810             for (j = 0; j < width; j++)
1811             {
1812                 key->types[i] = key->types[0];
1813             }
1814             key->typesDefined |= 1 << i;
1815         }
1816         if ((key->actsDefined & 1) && key->acts[0])
1817         {
1818             key->acts[i] = uTypedCalloc(width, union xkb_action);
1819             if (key->acts[i] == NULL)
1820                 continue;
1821             memcpy(key->acts[i], key->acts[0],
1822                    width * sizeof(union xkb_action));
1823             key->actsDefined |= 1 << i;
1824         }
1825         if ((key->symsDefined & 1) && key->sizeSyms[0])
1826         {
1827             key->syms[i] = uTypedCalloc(key->sizeSyms[0], xkb_keysym_t);
1828             if (key->syms[i] == NULL)
1829                 continue;
1830             memcpy(key->syms[i], key->syms[0],
1831                    key->sizeSyms[0] * sizeof(xkb_keysym_t));
1832             key->symsMapIndex[i] = uTypedCalloc(width, int);
1833             if (!key->symsMapIndex[i])
1834             {
1835                 free(key->syms[i]);
1836                 key->syms[i] = NULL;
1837                 continue;
1838             }
1839             memcpy(key->symsMapIndex[i], key->symsMapIndex[0],
1840                    width * sizeof(int));
1841             key->symsMapNumEntries[i] = uTypedCalloc(width, unsigned int);
1842             if (!key->symsMapNumEntries[i])
1843             {
1844                 free(key->syms[i]);
1845                 key->syms[i] = NULL;
1846                 free(key->symsMapIndex[i]);
1847                 key->symsMapIndex[i] = NULL;
1848                 continue;
1849             }
1850             memcpy(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
1851                    width * sizeof(int));
1852             key->sizeSyms[i] = key->sizeSyms[0];
1853             key->symsDefined |= 1 << i;
1854         }
1855         if (defined & 1)
1856         {
1857             key->numLevels[i] = key->numLevels[0];
1858         }
1859     }
1860     /* If all groups are completely identical remove them all */
1861     /* exept the first one. */
1862     identical = true;
1863     for (i = lastGroup; i > 0; i--)
1864     {
1865         if ((key->numLevels[i] != key->numLevels[0]) ||
1866             (key->types[i] != key->types[0]))
1867         {
1868             identical = false;
1869             break;
1870         }
1871         if ((key->syms[i] != key->syms[0]) &&
1872             (key->syms[i] == NULL || key->syms[0] == NULL ||
1873              key->sizeSyms[i] != key->sizeSyms[0] ||
1874              memcmp(key->syms[i], key->syms[0],
1875                     sizeof(xkb_keysym_t) * key->sizeSyms[0])))
1876         {
1877             identical = false;
1878             break;
1879         }
1880         if ((key->symsMapIndex[i] != key->symsMapIndex[i]) &&
1881             (key->symsMapIndex[i] == NULL || key->symsMapIndex[0] == NULL ||
1882              memcmp(key->symsMapIndex[i], key->symsMapIndex[0],
1883                     key->numLevels[0] * sizeof(int))))
1884         {
1885             identical = false;
1886             continue;
1887         }
1888         if ((key->symsMapNumEntries[i] != key->symsMapNumEntries[i]) &&
1889             (key->symsMapNumEntries[i] == NULL ||
1890              key->symsMapNumEntries[0] == NULL ||
1891              memcmp(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
1892                     key->numLevels[0] * sizeof(int))))
1893         {
1894             identical = false;
1895             continue;
1896         }
1897         if ((key->acts[i] != key->acts[0]) &&
1898             (key->acts[i] == NULL || key->acts[0] == NULL ||
1899              memcmp(key->acts[i], key->acts[0],
1900                     sizeof(union xkb_action) * key->numLevels[0])))
1901         {
1902             identical = false;
1903             break;
1904         }
1905     }
1906     if (identical)
1907     {
1908         for (i = lastGroup; i > 0; i--)
1909         {
1910             key->numLevels[i] = 0;
1911             free(key->syms[i]);
1912             key->syms[i] = NULL;
1913             key->sizeSyms[i] = 0;
1914             free(key->symsMapIndex[i]);
1915             key->symsMapIndex[i] = NULL;
1916             free(key->symsMapNumEntries[i]);
1917             key->symsMapNumEntries[i] = NULL;
1918             free(key->acts[i]);
1919             key->acts[i] = NULL;
1920             key->types[i] = 0;
1921         }
1922         key->symsDefined &= 1;
1923         key->actsDefined &= 1;
1924         key->typesDefined &= 1;
1925     }
1926 }
1927
1928 /**
1929  * Copy the KeyInfo into the keyboard description.
1930  *
1931  * This function recurses.
1932  */
1933 static bool
1934 CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *key, int start_from)
1935 {
1936     unsigned int i;
1937     xkb_keycode_t kc;
1938     unsigned int sizeSyms = 0;
1939     unsigned width, tmp, nGroups;
1940     struct xkb_key_type * type;
1941     bool haveActions, autoType, useAlias;
1942     unsigned types[XkbNumKbdGroups];
1943     union xkb_action *outActs;
1944     unsigned int symIndex = 0;
1945
1946     useAlias = (start_from == 0);
1947
1948     /* get the keycode for the key. */
1949     if (!FindNamedKey(keymap, key->name, &kc, useAlias,
1950                       CreateKeyNames(keymap), start_from))
1951     {
1952         if ((start_from == 0) && (warningLevel >= 5))
1953         {
1954             WARN("Key %s not found in keycodes\n", longText(key->name));
1955             ACTION("Symbols ignored\n");
1956         }
1957         return false;
1958     }
1959
1960     haveActions = false;
1961     for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1962     {
1963         if (((i + 1) > nGroups)
1964             && (((key->symsDefined | key->actsDefined) & (1 << i))
1965                 || (key->typesDefined) & (1 << i)))
1966             nGroups = i + 1;
1967         if (key->acts[i])
1968             haveActions = true;
1969         autoType = false;
1970         /* Assign the type to the key, if it is missing. */
1971         if (key->types[i] == XKB_ATOM_NONE)
1972         {
1973             if (key->dfltType != XKB_ATOM_NONE)
1974                 key->types[i] = key->dfltType;
1975             else if (FindAutomaticType(keymap, key->numLevels[i], key->syms[i],
1976                                        &key->types[i], &autoType))
1977             {
1978             }
1979             else
1980             {
1981                 if (warningLevel >= 5)
1982                 {
1983                     WARN("No automatic type for %d symbols\n",
1984                           (unsigned int) key->numLevels[i]);
1985                     ACTION("Using %s for the %s key (keycode %d)\n",
1986                             xkb_atom_text(keymap->ctx, key->types[i]),
1987                             longText(key->name), kc);
1988                 }
1989             }
1990         }
1991         if (FindNamedType(keymap, key->types[i], &types[i]))
1992         {
1993             if (!autoType || key->numLevels[i] > 2)
1994                 keymap->server->explicit[kc] |= (1 << i);
1995         }
1996         else
1997         {
1998             if (warningLevel >= 3)
1999             {
2000                 WARN("Type \"%s\" is not defined\n",
2001                       xkb_atom_text(keymap->ctx, key->types[i]));
2002                 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
2003                         longText(key->name), kc);
2004             }
2005             types[i] = XkbTwoLevelIndex;
2006         }
2007         /* if the type specifies fewer levels than the key has, shrink the key */
2008         type = &keymap->map->types[types[i]];
2009         if (type->num_levels < key->numLevels[i])
2010         {
2011             if (warningLevel > 0)
2012             {
2013                 WARN("Type \"%s\" has %d levels, but %s has %d symbols\n",
2014                      type->name, type->num_levels,
2015                      xkb_atom_text(keymap->ctx, key->name), key->numLevels[i]);
2016                 ACTION("Ignoring extra symbols\n");
2017             }
2018             key->numLevels[i] = type->num_levels;
2019         }
2020         if (key->numLevels[i] > width)
2021             width = key->numLevels[i];
2022         if (type->num_levels > width)
2023             width = type->num_levels;
2024         sizeSyms += key->sizeSyms[i];
2025     }
2026
2027     if (!XkbcResizeKeySyms(keymap, kc, sizeSyms))
2028     {
2029         WSGO("Could not enlarge symbols for %s (keycode %d)\n",
2030               longText(key->name), kc);
2031         return false;
2032     }
2033     if (haveActions)
2034     {
2035         outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups);
2036         if (outActs == NULL)
2037         {
2038             WSGO("Could not enlarge actions for %s (key %d)\n",
2039                   longText(key->name), kc);
2040             return false;
2041         }
2042         keymap->server->explicit[kc] |= XkbExplicitInterpretMask;
2043     }
2044     else
2045         outActs = NULL;
2046     if (key->defs.defined & _Key_GroupInfo)
2047         i = key->groupInfo;
2048     else
2049         i = keymap->map->key_sym_map[kc].group_info;
2050
2051     keymap->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2052     keymap->map->key_sym_map[kc].width = width;
2053     keymap->map->key_sym_map[kc].sym_index = uTypedCalloc(nGroups * width,
2054                                                           int);
2055     keymap->map->key_sym_map[kc].num_syms = uTypedCalloc(nGroups * width,
2056                                                          unsigned int);
2057     for (i = 0; i < nGroups; i++)
2058     {
2059         /* assign kt_index[i] to the index of the type in map->types.
2060          * kt_index[i] may have been set by a previous run (if we have two
2061          * layouts specified). Let's not overwrite it with the ONE_LEVEL
2062          * default group if we dont even have keys for this group anyway.
2063          *
2064          * FIXME: There should be a better fix for this.
2065          */
2066         if (key->numLevels[i])
2067             keymap->map->key_sym_map[kc].kt_index[i] = types[i];
2068         if (key->sizeSyms[i] != 0)
2069         {
2070             /* fill key to "width" symbols*/
2071             for (tmp = 0; tmp < width; tmp++)
2072             {
2073                 if (tmp < key->numLevels[i] && key->symsMapNumEntries[i][tmp])
2074                 {
2075                     memcpy(&keymap->map->key_sym_map[kc].syms[symIndex],
2076                            &key->syms[i][key->symsMapIndex[i][tmp]],
2077                            key->symsMapNumEntries[i][tmp] *
2078                             sizeof(xkb_keysym_t));
2079                     keymap->map->key_sym_map[kc].sym_index[(i * width) + tmp] =
2080                         symIndex;
2081                     keymap->map->key_sym_map[kc].num_syms[(i * width) + tmp] =
2082                         key->symsMapNumEntries[i][tmp];
2083                     symIndex +=
2084                         keymap->map->key_sym_map[kc].num_syms[(i * width) + tmp];
2085                 }
2086                 else
2087                 {
2088                     keymap->map->key_sym_map[kc].sym_index[(i * width) + tmp] = -1;
2089                     keymap->map->key_sym_map[kc].num_syms[(i * width) + tmp] = 0;
2090                 }
2091                 if ((outActs != NULL) && (key->acts[i] != NULL))
2092                 {
2093                     if (tmp < key->numLevels[i])
2094                         outActs[tmp] = key->acts[i][tmp];
2095                     else
2096                         outActs[tmp].type = XkbSA_NoAction;
2097                 }
2098             }
2099         }
2100     }
2101     switch (key->behavior.type & XkbKB_OpMask)
2102     {
2103     case XkbKB_Default:
2104         break;
2105     default:
2106         keymap->server->behaviors[kc] = key->behavior;
2107         keymap->server->explicit[kc] |= XkbExplicitBehaviorMask;
2108         break;
2109     }
2110     if (key->defs.defined & _Key_VModMap)
2111     {
2112         keymap->server->vmodmap[kc] = key->vmodmap;
2113         keymap->server->explicit[kc] |= XkbExplicitVModMapMask;
2114     }
2115     if (key->repeat != RepeatUndefined)
2116     {
2117         if (key->repeat == RepeatYes)
2118             keymap->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2119         else
2120             keymap->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2121         keymap->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2122     }
2123
2124     if (nGroups > keymap->ctrls->num_groups)
2125         keymap->ctrls->num_groups = nGroups;
2126
2127     /* do the same thing for the next key */
2128     CopySymbolsDef(keymap, key, kc + 1);
2129     return true;
2130 }
2131
2132 static bool
2133 CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry)
2134 {
2135     xkb_keycode_t kc;
2136
2137     if (!entry->haveSymbol &&
2138         !FindNamedKey(keymap, entry->u.keyName, &kc, true,
2139                       CreateKeyNames(keymap), 0))
2140     {
2141         if (warningLevel >= 5)
2142         {
2143             WARN("Key %s not found in keycodes\n",
2144                   longText(entry->u.keyName));
2145             ACTION("Modifier map entry for %s not updated\n",
2146                     XkbcModIndexText(entry->modifier));
2147         }
2148         return false;
2149     }
2150     else if (entry->haveSymbol &&
2151              !FindKeyForSymbol(keymap, entry->u.keySym, &kc))
2152     {
2153         if (warningLevel > 5)
2154         {
2155             WARN("Key \"%s\" not found in symbol map\n",
2156                   XkbcKeysymText(entry->u.keySym));
2157             ACTION("Modifier map entry for %s not updated\n",
2158                     XkbcModIndexText(entry->modifier));
2159         }
2160         return false;
2161     }
2162     keymap->map->modmap[kc] |= (1 << entry->modifier);
2163     return true;
2164 }
2165
2166 /**
2167  * Handle the xkb_symbols section of an xkb file.
2168  *
2169  * @param file The parsed xkb_symbols section of the xkb file.
2170  * @param keymap Handle to the keyboard description to store the symbols in.
2171  * @param merge Merge strategy (e.g. MergeOverride).
2172  */
2173 bool
2174 CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
2175 {
2176     unsigned int i;
2177     SymbolsInfo info;
2178     KeyInfo *key;
2179
2180     InitSymbolsInfo(&info, keymap);
2181     info.dflt.defs.fileID = file->id;
2182     info.dflt.defs.merge = merge;
2183
2184     HandleSymbolsFile(file, keymap, merge, &info);
2185
2186     if (info.nKeys == 0)
2187         goto err_info;
2188
2189     if (info.errorCount != 0)
2190         goto err_info;
2191
2192     /* alloc memory in the xkb struct */
2193     if (XkbcAllocNames(keymap, XkbGroupNamesMask, 0) != Success) {
2194         WSGO("Can not allocate names in CompileSymbols\n");
2195         ACTION("Symbols not added\n");
2196         goto err_info;
2197     }
2198
2199     if (XkbcAllocClientMap(keymap, XkbKeySymsMask | XkbModifierMapMask, 0)
2200         != Success) {
2201         WSGO("Could not allocate client map in CompileSymbols\n");
2202         ACTION("Symbols not added\n");
2203         goto err_info;
2204     }
2205
2206     if (XkbcAllocServerMap(keymap, XkbAllServerInfoMask, 32) != Success) {
2207         WSGO("Could not allocate server map in CompileSymbols\n");
2208         ACTION("Symbols not added\n");
2209         goto err_info;
2210     }
2211
2212     if (XkbcAllocControls(keymap) != Success) {
2213         WSGO("Could not allocate controls in CompileSymbols\n");
2214         ACTION("Symbols not added\n");
2215         goto err_info;
2216     }
2217
2218     /* now copy info into xkb. */
2219     ApplyAliases(keymap, &info.aliases);
2220
2221     for (i = 0; i < XkbNumKbdGroups; i++) {
2222         if (info.groupNames[i] != XKB_ATOM_NONE) {
2223             free(UNCONSTIFY(keymap->names->groups[i]));
2224             keymap->names->groups[i] = xkb_atom_strdup(keymap->ctx,
2225                                                        info.groupNames[i]);
2226         }
2227     }
2228
2229     /* sanitize keys */
2230     for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2231         PrepareKeyDef(key);
2232
2233     /* copy! */
2234     for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2235         if (!CopySymbolsDef(keymap, key, 0))
2236             info.errorCount++;
2237
2238     if (warningLevel > 3) {
2239         for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
2240             if (keymap->names->keys[i].name[0] == '\0')
2241                 continue;
2242
2243             if (XkbKeyNumGroups(keymap, i) < 1) {
2244                 char buf[5];
2245                 memcpy(buf, keymap->names->keys[i].name, 4);
2246                 buf[4] = '\0';
2247                 WARN("No symbols defined for <%s> (keycode %d)\n", buf, i);
2248             }
2249         }
2250     }
2251
2252     if (info.modMap) {
2253         ModMapEntry *mm, *next;
2254         for (mm = info.modMap; mm != NULL; mm = next) {
2255             if (!CopyModMapDef(keymap, mm))
2256                 info.errorCount++;
2257             next = (ModMapEntry *) mm->defs.next;
2258         }
2259     }
2260
2261     FreeSymbolsInfo(&info);
2262     return true;
2263
2264 err_info:
2265     FreeSymbolsInfo(&info);
2266     return false;
2267 }