Full support for multiple keysyms per level
[platform/upstream/libxkbcommon.git] / src / xkbcomp / symbols.c
1 /************************************************************
2  Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3
4  Permission to use, copy, modify, and distribute this
5  software and its documentation for any purpose and without
6  fee is hereby granted, provided that the above copyright
7  notice appear in all copies and that both that copyright
8  notice and this permission notice appear in supporting
9  documentation, and that the name of Silicon Graphics not be
10  used in advertising or publicity pertaining to distribution
11  of the software without specific prior written permission.
12  Silicon Graphics makes no representation about the suitability
13  of this software for any purpose. It is provided "as is"
14  without any express or implied warranty.
15
16  SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19  GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23  THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25  ********************************************************/
26
27 #include "xkbcomp.h"
28 #include "xkballoc.h"
29 #include "xkbmisc.h"
30 #include "expr.h"
31 #include "parseutils.h"
32
33 #include <X11/keysym.h>
34 #include <stdlib.h>
35
36 #include "expr.h"
37 #include "vmod.h"
38 #include "action.h"
39 #include "keycodes.h"
40 #include "misc.h"
41 #include "alias.h"
42
43 /***====================================================================***/
44
45 #define RepeatYes       1
46 #define RepeatNo        0
47 #define RepeatUndefined ~((unsigned)0)
48
49 #define _Key_Syms       (1<<0)
50 #define _Key_Acts       (1<<1)
51 #define _Key_Repeat     (1<<2)
52 #define _Key_Behavior   (1<<3)
53 #define _Key_Type_Dflt  (1<<4)
54 #define _Key_Types      (1<<5)
55 #define _Key_GroupInfo  (1<<6)
56 #define _Key_VModMap    (1<<7)
57
58 typedef struct _KeyInfo
59 {
60     CommonInfo defs;
61     unsigned long name; /* the 4 chars of the key name, as long */
62     unsigned char groupInfo;
63     unsigned char typesDefined;
64     unsigned char symsDefined;
65     unsigned char actsDefined;
66     unsigned int numLevels[XkbNumKbdGroups];
67     xkb_keysym_t *syms[XkbNumKbdGroups];
68     int sizeSyms[XkbNumKbdGroups];
69     int *symsMapIndex[XkbNumKbdGroups];
70     unsigned int *symsMapNumEntries[XkbNumKbdGroups];
71     union xkb_action *acts[XkbNumKbdGroups];
72     xkb_atom_t types[XkbNumKbdGroups];
73     unsigned repeat;
74     struct xkb_behavior behavior;
75     unsigned short vmodmap;
76     unsigned long allowNone;
77     xkb_atom_t dfltType;
78 } KeyInfo;
79
80 /**
81  * Init the given key info to sane values.
82  */
83 static void
84 InitKeyInfo(KeyInfo * info)
85 {
86     int i;
87     static char dflt[4] = "*";
88
89     info->defs.defined = 0;
90     info->defs.fileID = 0;
91     info->defs.merge = MergeOverride;
92     info->defs.next = NULL;
93     info->name = KeyNameToLong(dflt);
94     info->groupInfo = 0;
95     info->typesDefined = info->symsDefined = info->actsDefined = 0;
96     for (i = 0; i < XkbNumKbdGroups; i++)
97     {
98         info->numLevels[i] = 0;
99         info->types[i] = XKB_ATOM_NONE;
100         info->syms[i] = NULL;
101         info->sizeSyms[i] = 0;
102         info->symsMapIndex[i] = NULL;
103         info->symsMapNumEntries[i] = NULL;
104         info->acts[i] = NULL;
105     }
106     info->dfltType = XKB_ATOM_NONE;
107     info->behavior.type = XkbKB_Default;
108     info->behavior.data = 0;
109     info->vmodmap = 0;
110     info->repeat = RepeatUndefined;
111     info->allowNone = 0;
112 }
113
114 /**
115  * Free memory associated with this key info and reset to sane values.
116  */
117 static void
118 FreeKeyInfo(KeyInfo * info)
119 {
120     int i;
121
122     info->defs.defined = 0;
123     info->defs.fileID = 0;
124     info->defs.merge = MergeOverride;
125     info->defs.next = NULL;
126     info->groupInfo = 0;
127     info->typesDefined = info->symsDefined = info->actsDefined = 0;
128     for (i = 0; i < XkbNumKbdGroups; i++)
129     {
130         info->numLevels[i] = 0;
131         info->types[i] = XKB_ATOM_NONE;
132         free(info->syms[i]);
133         info->syms[i] = NULL;
134         info->sizeSyms[i] = 0;
135         free(info->symsMapIndex[i]);
136         info->symsMapIndex[i] = NULL;
137         free(info->symsMapNumEntries[i]);
138         info->symsMapNumEntries[i] = NULL;
139         free(info->acts[i]);
140         info->acts[i] = NULL;
141     }
142     info->dfltType = XKB_ATOM_NONE;
143     info->behavior.type = XkbKB_Default;
144     info->behavior.data = 0;
145     info->vmodmap = 0;
146     info->repeat = RepeatUndefined;
147     info->allowNone = 0;
148 }
149
150 /**
151  * Copy old into new, optionally reset old to 0.
152  * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
153  * newly allocated and new points to the new memory areas.
154  */
155 static Bool
156 CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld)
157 {
158     int i;
159
160     *new = *old;
161     new->defs.next = NULL;
162     if (clearOld)
163     {
164         for (i = 0; i < XkbNumKbdGroups; i++)
165         {
166             old->numLevels[i] = 0;
167             old->symsMapIndex[i] = NULL;
168             old->symsMapNumEntries[i] = NULL;
169             old->syms[i] = NULL;
170             old->sizeSyms[i] = 0;
171             old->acts[i] = NULL;
172         }
173     }
174     else
175     {
176         unsigned int width;
177         for (i = 0; i < XkbNumKbdGroups; i++)
178         {
179             width = new->numLevels[i];
180             if (old->syms[i] != NULL)
181             {
182                 new->syms[i] = uTypedCalloc(new->sizeSyms[i], xkb_keysym_t);
183                 if (!new->syms[i])
184                 {
185                     new->syms[i] = NULL;
186                     new->sizeSyms[i] = 0;
187                     new->numLevels[i] = 0;
188                     new->acts[i] = NULL;
189                     return False;
190                 }
191                 memcpy(new->syms[i], old->syms[i],
192                        new->sizeSyms[i] * sizeof(xkb_keysym_t));
193                 new->symsMapIndex[i] = uTypedCalloc(width, int);
194                 if (!new->symsMapIndex[i])
195                 {
196                     free(new->syms[i]);
197                     new->syms[i] = NULL;
198                     new->sizeSyms[i] = 0;
199                     new->numLevels[i] = 0;
200                     new->acts[i] = NULL;
201                     return False;
202                 }
203                 memcpy(new->symsMapIndex[i], old->symsMapIndex[i],
204                        width * sizeof(int));
205                 new->symsMapNumEntries[i] = uTypedCalloc(width, unsigned int);
206                 if (!new->symsMapNumEntries[i])
207                 {
208                     free(new->syms[i]);
209                     new->syms[i] = NULL;
210                     new->sizeSyms[i] = 0;
211                     free(new->symsMapIndex[i]);
212                     new->symsMapIndex[i] = NULL;
213                     new->numLevels[i] = 0;
214                     new->acts[i] = NULL;
215                     return False;
216                 }
217                 memcpy(new->symsMapNumEntries[i], old->symsMapNumEntries[i],
218                        sizeof(unsigned int));
219             }
220             if (old->acts[i] != NULL)
221             {
222                 new->acts[i] = uTypedCalloc(width, union xkb_action);
223                 if (!new->acts[i])
224                 {
225                     free(new->syms[i]);
226                     new->syms[i] = NULL;
227                     new->sizeSyms[i] = 0;
228                     free(new->symsMapIndex[i]);
229                     new->symsMapIndex[i] = NULL;
230                     free(new->symsMapNumEntries[i]);
231                     new->symsMapNumEntries[i] = NULL;
232                     new->numLevels[i] = 0;
233                     return False;
234                 }
235                 memcpy(new->acts[i], old->acts[i],
236                        width * sizeof(union xkb_action));
237             }
238         }
239     }
240     return True;
241 }
242
243 /***====================================================================***/
244
245 typedef struct _ModMapEntry
246 {
247     CommonInfo defs;
248     Bool haveSymbol;
249     int modifier;
250     union
251     {
252         unsigned long keyName;
253         xkb_keysym_t keySym;
254     } u;
255 } ModMapEntry;
256
257 #define SYMBOLS_INIT_SIZE       110
258 #define SYMBOLS_CHUNK           20
259 typedef struct _SymbolsInfo
260 {
261     char *name;         /* e.g. pc+us+inet(evdev) */
262     int errorCount;
263     unsigned fileID;
264     unsigned merge;
265     unsigned explicit_group;
266     unsigned groupInfo;
267     unsigned szKeys;
268     unsigned nKeys;
269     KeyInfo *keys;
270     KeyInfo dflt;
271     VModInfo vmods;
272     ActionInfo *action;
273     xkb_atom_t groupNames[XkbNumKbdGroups];
274
275     ModMapEntry *modMap;
276     AliasInfo *aliases;
277 } SymbolsInfo;
278
279 static void
280 InitSymbolsInfo(SymbolsInfo * info, struct xkb_desc * xkb)
281 {
282     int i;
283
284     info->name = NULL;
285     info->explicit_group = 0;
286     info->errorCount = 0;
287     info->fileID = 0;
288     info->merge = MergeOverride;
289     info->groupInfo = 0;
290     info->szKeys = SYMBOLS_INIT_SIZE;
291     info->nKeys = 0;
292     info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo);
293     info->modMap = NULL;
294     for (i = 0; i < XkbNumKbdGroups; i++)
295         info->groupNames[i] = XKB_ATOM_NONE;
296     InitKeyInfo(&info->dflt);
297     InitVModInfo(&info->vmods, xkb);
298     info->action = NULL;
299     info->aliases = NULL;
300 }
301
302 static void
303 FreeSymbolsInfo(SymbolsInfo * info)
304 {
305     unsigned int i;
306
307     free(info->name);
308     if (info->keys)
309     {
310         for (i = 0; i < info->nKeys; i++)
311             FreeKeyInfo(&info->keys[i]);
312         free(info->keys);
313     }
314     if (info->modMap)
315         ClearCommonInfo(&info->modMap->defs);
316     if (info->aliases)
317         ClearAliases(&info->aliases);
318     memset(info, 0, sizeof(SymbolsInfo));
319 }
320
321 static Bool
322 ResizeKeyGroup(KeyInfo * key, unsigned int group, unsigned int numLevels,
323                unsigned sizeSyms, Bool forceActions)
324 {
325     Bool tooSmall;
326     unsigned newWidth;
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;
382     union xkb_action *resultActs;
383     unsigned int resultWidth;
384     unsigned int resultSize = 0;
385     int cur_idx = 0;
386     int i, j;
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                            from->numLevels[group],
407                            into->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, KeyInfo * into, KeyInfo * from)
584 {
585     int i;
586     unsigned collide = 0;
587     Bool report;
588
589     if (from->defs.merge == MergeReplace)
590     {
591         for (i = 0; i < XkbNumKbdGroups; i++)
592         {
593             if (into->numLevels[i] != 0)
594             {
595                 free(into->syms[i]);
596                 free(into->acts[i]);
597             }
598         }
599         *into = *from;
600         memset(from, 0, sizeof(KeyInfo));
601         return True;
602     }
603     report = ((warningLevel > 9) ||
604               ((into->defs.fileID == from->defs.fileID)
605                && (warningLevel > 0)));
606     for (i = 0; i < XkbNumKbdGroups; i++)
607     {
608         if (from->numLevels[i] > 0)
609         {
610             if (into->numLevels[i] == 0)
611             {
612                 into->numLevels[i] = from->numLevels[i];
613                 into->syms[i] = from->syms[i];
614                 into->sizeSyms[i] = from->sizeSyms[i];
615                 into->symsMapIndex[i] = from->symsMapIndex[i];
616                 into->symsMapNumEntries[i] = from->symsMapNumEntries[i];
617                 into->acts[i] = from->acts[i];
618                 into->symsDefined |= (1 << i);
619                 from->syms[i] = NULL;
620                 from->sizeSyms[i] = 0;
621                 from->symsMapIndex[i] = NULL;
622                 from->symsMapNumEntries[i] = NULL;
623                 from->acts[i] = NULL;
624                 from->numLevels[i] = 0;
625                 from->symsDefined &= ~(1 << i);
626                 if (into->syms[i])
627                     into->defs.defined |= _Key_Syms;
628                 if (into->acts[i])
629                     into->defs.defined |= _Key_Acts;
630             }
631             else
632             {
633                 if (report)
634                 {
635                     if (into->syms[i])
636                         collide |= _Key_Syms;
637                     if (into->acts[i])
638                         collide |= _Key_Acts;
639                 }
640                 MergeKeyGroups(info, into, from, (unsigned) i);
641             }
642         }
643         if (from->types[i] != XKB_ATOM_NONE)
644         {
645             if ((into->types[i] != XKB_ATOM_NONE) && report &&
646                 (into->types[i] != from->types[i]))
647             {
648                 xkb_atom_t use, ignore;
649                 collide |= _Key_Types;
650                 if (from->defs.merge != MergeAugment)
651                 {
652                     use = from->types[i];
653                     ignore = into->types[i];
654                 }
655                 else
656                 {
657                     use = into->types[i];
658                     ignore = from->types[i];
659                 }
660                 WARN
661                     ("Multiple definitions for group %d type of key %s\n",
662                      i, longText(into->name));
663                 ACTION("Using %s, ignoring %s\n",
664                         XkbcAtomText(use),
665                         XkbcAtomText(ignore));
666             }
667             if ((from->defs.merge != MergeAugment)
668                 || (into->types[i] == XKB_ATOM_NONE))
669             {
670                 into->types[i] = from->types[i];
671             }
672         }
673     }
674     if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
675     {
676         into->behavior = from->behavior;
677         into->defs.defined |= _Key_Behavior;
678     }
679     if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
680     {
681         into->vmodmap = from->vmodmap;
682         into->defs.defined |= _Key_VModMap;
683     }
684     if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
685     {
686         into->repeat = from->repeat;
687         into->defs.defined |= _Key_Repeat;
688     }
689     if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
690     {
691         into->dfltType = from->dfltType;
692         into->defs.defined |= _Key_Type_Dflt;
693     }
694     if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
695     {
696         into->groupInfo = from->groupInfo;
697         into->defs.defined |= _Key_GroupInfo;
698     }
699     if (collide)
700     {
701         WARN("Symbol map for key %s redefined\n",
702               longText(into->name));
703         ACTION("Using %s definition for conflicting fields\n",
704                 (from->defs.merge == MergeAugment ? "first" : "last"));
705     }
706     return True;
707 }
708
709 static Bool
710 AddKeySymbols(SymbolsInfo * info, KeyInfo * key, struct xkb_desc * xkb)
711 {
712     unsigned int i;
713     unsigned long real_name;
714
715     for (i = 0; i < info->nKeys; i++)
716     {
717         if (info->keys[i].name == key->name)
718             return MergeKeys(info, &info->keys[i], key);
719     }
720     if (FindKeyNameForAlias(xkb, key->name, &real_name))
721     {
722         for (i = 0; i < info->nKeys; i++)
723         {
724             if (info->keys[i].name == real_name)
725                 return MergeKeys(info, &info->keys[i], key);
726         }
727     }
728     if (info->nKeys >= info->szKeys)
729     {
730         info->szKeys += SYMBOLS_CHUNK;
731         info->keys =
732             uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo);
733         if (!info->keys)
734         {
735             WSGO("Could not allocate key symbols descriptions\n");
736             ACTION("Some key symbols definitions may be lost\n");
737             return False;
738         }
739     }
740     return CopyKeyInfo(key, &info->keys[info->nKeys++], True);
741 }
742
743 static Bool
744 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
745 {
746     ModMapEntry *mm;
747     Bool clobber;
748
749     clobber = (new->defs.merge != MergeAugment);
750     for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
751     {
752         if (new->haveSymbol && mm->haveSymbol
753             && (new->u.keySym == mm->u.keySym))
754         {
755             unsigned use, ignore;
756             if (mm->modifier != new->modifier)
757             {
758                 if (clobber)
759                 {
760                     use = new->modifier;
761                     ignore = mm->modifier;
762                 }
763                 else
764                 {
765                     use = mm->modifier;
766                     ignore = new->modifier;
767                 }
768                 ERROR
769                     ("%s added to symbol map for multiple modifiers\n",
770                      XkbcKeysymText(new->u.keySym));
771                 ACTION("Using %s, ignoring %s.\n",
772                         XkbcModIndexText(use),
773                         XkbcModIndexText(ignore));
774                 mm->modifier = use;
775             }
776             return True;
777         }
778         if ((!new->haveSymbol) && (!mm->haveSymbol) &&
779             (new->u.keyName == mm->u.keyName))
780         {
781             unsigned use, ignore;
782             if (mm->modifier != new->modifier)
783             {
784                 if (clobber)
785                 {
786                     use = new->modifier;
787                     ignore = mm->modifier;
788                 }
789                 else
790                 {
791                     use = mm->modifier;
792                     ignore = new->modifier;
793                 }
794                 ERROR("Key %s added to map for multiple modifiers\n",
795                        longText(new->u.keyName));
796                 ACTION("Using %s, ignoring %s.\n",
797                         XkbcModIndexText(use),
798                         XkbcModIndexText(ignore));
799                 mm->modifier = use;
800             }
801             return True;
802         }
803     }
804     mm = uTypedAlloc(ModMapEntry);
805     if (mm == NULL)
806     {
807         WSGO("Could not allocate modifier map entry\n");
808         ACTION("Modifier map for %s will be incomplete\n",
809                 XkbcModIndexText(new->modifier));
810         return False;
811     }
812     *mm = *new;
813     mm->defs.next = &info->modMap->defs;
814     info->modMap = mm;
815     return True;
816 }
817
818 /***====================================================================***/
819
820 static void
821 MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from,
822                      unsigned merge, struct xkb_desc * xkb)
823 {
824     unsigned int i;
825     KeyInfo *key;
826
827     if (from->errorCount > 0)
828     {
829         into->errorCount += from->errorCount;
830         return;
831     }
832     if (into->name == NULL)
833     {
834         into->name = from->name;
835         from->name = NULL;
836     }
837     for (i = 0; i < XkbNumKbdGroups; i++)
838     {
839         if (from->groupNames[i] != XKB_ATOM_NONE)
840         {
841             if ((merge != MergeAugment) ||
842                 (into->groupNames[i] == XKB_ATOM_NONE))
843                 into->groupNames[i] = from->groupNames[i];
844         }
845     }
846     for (i = 0, key = from->keys; i < from->nKeys; i++, key++)
847     {
848         if (merge != MergeDefault)
849             key->defs.merge = merge;
850         if (!AddKeySymbols(into, key, xkb))
851             into->errorCount++;
852     }
853     if (from->modMap != NULL)
854     {
855         ModMapEntry *mm, *next;
856         for (mm = from->modMap; mm != NULL; mm = next)
857         {
858             if (merge != MergeDefault)
859                 mm->defs.merge = merge;
860             if (!AddModMapEntry(into, mm))
861                 into->errorCount++;
862             next = (ModMapEntry *) mm->defs.next;
863             free(mm);
864         }
865         from->modMap = NULL;
866     }
867     if (!MergeAliases(&into->aliases, &from->aliases, merge))
868         into->errorCount++;
869 }
870
871 typedef void (*FileHandler) (XkbFile * /* rtrn */ ,
872                              struct xkb_desc * /* xkb */ ,
873                              unsigned /* merge */ ,
874                              SymbolsInfo *      /* included */
875     );
876
877 static Bool
878 HandleIncludeSymbols(IncludeStmt * stmt,
879                      struct xkb_desc * xkb, SymbolsInfo * info, FileHandler hndlr)
880 {
881     unsigned newMerge;
882     XkbFile *rtrn;
883     SymbolsInfo included;
884     Bool haveSelf;
885
886     haveSelf = False;
887     if ((stmt->file == NULL) && (stmt->map == NULL))
888     {
889         haveSelf = True;
890         included = *info;
891         memset(info, 0, sizeof(SymbolsInfo));
892     }
893     else if (ProcessIncludeFile(xkb->context, stmt, XkmSymbolsIndex, &rtrn,
894                                 &newMerge))
895     {
896         InitSymbolsInfo(&included, xkb);
897         included.fileID = included.dflt.defs.fileID = rtrn->id;
898         included.merge = included.dflt.defs.merge = MergeOverride;
899         if (stmt->modifier)
900         {
901             included.explicit_group = atoi(stmt->modifier) - 1;
902         }
903         else
904         {
905             included.explicit_group = info->explicit_group;
906         }
907         (*hndlr) (rtrn, xkb, MergeOverride, &included);
908         if (stmt->stmt != NULL)
909         {
910             free(included.name);
911             included.name = stmt->stmt;
912             stmt->stmt = NULL;
913         }
914         FreeXKBFile(rtrn);
915     }
916     else
917     {
918         info->errorCount += 10;
919         return False;
920     }
921     if ((stmt->next != NULL) && (included.errorCount < 1))
922     {
923         IncludeStmt *next;
924         unsigned op;
925         SymbolsInfo next_incl;
926
927         for (next = stmt->next; next != NULL; next = next->next)
928         {
929             if ((next->file == NULL) && (next->map == NULL))
930             {
931                 haveSelf = True;
932                 MergeIncludedSymbols(&included, info, next->merge, xkb);
933                 FreeSymbolsInfo(info);
934             }
935             else if (ProcessIncludeFile(xkb->context, next, XkmSymbolsIndex,
936                                         &rtrn, &op))
937             {
938                 InitSymbolsInfo(&next_incl, xkb);
939                 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
940                 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride;
941                 if (next->modifier)
942                 {
943                     next_incl.explicit_group = atoi(next->modifier) - 1;
944                 }
945                 else
946                 {
947                     next_incl.explicit_group = info->explicit_group;
948                 }
949                 (*hndlr) (rtrn, xkb, MergeOverride, &next_incl);
950                 MergeIncludedSymbols(&included, &next_incl, op, xkb);
951                 FreeSymbolsInfo(&next_incl);
952                 FreeXKBFile(rtrn);
953             }
954             else
955             {
956                 info->errorCount += 10;
957                 return False;
958             }
959         }
960     }
961     if (haveSelf)
962         *info = included;
963     else
964     {
965         MergeIncludedSymbols(info, &included, newMerge, xkb);
966         FreeSymbolsInfo(&included);
967     }
968     return (info->errorCount == 0);
969 }
970
971 #define SYMBOLS 1
972 #define ACTIONS 2
973
974 static Bool
975 GetGroupIndex(KeyInfo * key,
976               ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
977 {
978     const char *name;
979     ExprResult tmp;
980
981     if (what == SYMBOLS)
982         name = "symbols";
983     else
984         name = "actions";
985
986     if (arrayNdx == NULL)
987     {
988         int i;
989         unsigned defined;
990         if (what == SYMBOLS)
991             defined = key->symsDefined;
992         else
993             defined = key->actsDefined;
994
995         for (i = 0; i < XkbNumKbdGroups; i++)
996         {
997             if ((defined & (1 << i)) == 0)
998             {
999                 *ndx_rtrn = i;
1000                 return True;
1001             }
1002         }
1003         ERROR("Too many groups of %s for key %s (max %d)\n", name,
1004                longText(key->name), XkbNumKbdGroups + 1);
1005         ACTION("Ignoring %s defined for extra groups\n", name);
1006         return False;
1007     }
1008     if (!ExprResolveGroup(arrayNdx, &tmp))
1009     {
1010         ERROR("Illegal group index for %s of key %s\n", name,
1011                longText(key->name));
1012         ACTION("Definition with non-integer array index ignored\n");
1013         return False;
1014     }
1015     *ndx_rtrn = tmp.uval - 1;
1016     return True;
1017 }
1018
1019 static Bool
1020 AddSymbolsToKey(KeyInfo * key,
1021                 struct xkb_desc * xkb,
1022                 char *field,
1023                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1024 {
1025     unsigned ndx, nSyms, nLevels;
1026     unsigned int i;
1027     long j;
1028
1029     if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx))
1030         return False;
1031     if (value == NULL)
1032     {
1033         key->symsDefined |= (1 << ndx);
1034         return True;
1035     }
1036     if (value->op != ExprKeysymList)
1037     {
1038         ERROR("Expected a list of symbols, found %s\n", exprOpText(value->op));
1039         ACTION("Ignoring symbols for group %d of %s\n", ndx + 1,
1040                 longText(key->name));
1041         return False;
1042     }
1043     if (key->sizeSyms[ndx] != 0)
1044     {
1045         ERROR("Symbols for key %s, group %d already defined\n",
1046                longText(key->name), ndx + 1);
1047         ACTION("Ignoring duplicate definition\n");
1048         return False;
1049     }
1050     nSyms = value->value.list.nSyms;
1051     nLevels = value->value.list.nLevels;
1052     if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
1053         (!ResizeKeyGroup(key, ndx, nLevels, nSyms, False)))
1054     {
1055         WSGO("Could not resize group %d of key %s to contain %d levels\n",
1056              ndx + 1, longText(key->name), nSyms);
1057         ACTION("Symbols lost\n");
1058         return False;
1059     }
1060     key->symsDefined |= (1 << ndx);
1061     for (i = 0; i < nLevels; i++) {
1062         key->symsMapIndex[ndx][i] = value->value.list.symsMapIndex[i];
1063         key->symsMapNumEntries[ndx][i] = value->value.list.symsNumEntries[i];
1064         for (j = 0; j < key->symsMapNumEntries[ndx][i]; j++) {
1065             if (key->symsMapIndex[ndx][i] + j >= nSyms)
1066                 abort();
1067             if (!LookupKeysym(value->value.list.syms[value->value.list.symsMapIndex[i] + j],
1068                               &key->syms[ndx][key->symsMapIndex[ndx][i] + j])) {
1069                 WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
1070                      value->value.list.syms[i], longText(key->name), ndx + 1,
1071                      XkbcAtomText(info->groupNames[ndx]), nSyms);
1072                 while (--j >= 0)
1073                     key->syms[ndx][key->symsMapIndex[ndx][i] + j] = NoSymbol;
1074                 key->symsMapIndex[ndx][i] = -1;
1075                 key->symsMapNumEntries[ndx][i] = 0;
1076                 break;
1077             }
1078         }
1079     }
1080     for (j = key->numLevels[ndx] - 1;
1081          j >= 0 && key->symsMapNumEntries[ndx][j] == 0; j--)
1082         key->numLevels[ndx]--;
1083     return True;
1084 }
1085
1086 static Bool
1087 AddActionsToKey(KeyInfo * key,
1088                 struct xkb_desc * xkb,
1089                 char *field,
1090                 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1091 {
1092     unsigned int i;
1093     unsigned ndx, nActs;
1094     ExprDef *act;
1095     struct xkb_any_action *toAct;
1096
1097     if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx))
1098         return False;
1099
1100     if (value == NULL)
1101     {
1102         key->actsDefined |= (1 << ndx);
1103         return True;
1104     }
1105     if (value->op != ExprActionList)
1106     {
1107         WSGO("Bad expression type (%d) for action list value\n", value->op);
1108         ACTION("Ignoring actions for group %d of %s\n", ndx,
1109                 longText(key->name));
1110         return False;
1111     }
1112     if (key->acts[ndx] != NULL)
1113     {
1114         WSGO("Actions for key %s, group %d already defined\n",
1115               longText(key->name), ndx);
1116         return False;
1117     }
1118     for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1119     {
1120         act = (ExprDef *) act->common.next;
1121     }
1122     if (nActs < 1)
1123     {
1124         WSGO("Action list but not actions in AddActionsToKey\n");
1125         return False;
1126     }
1127     if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1128         (!ResizeKeyGroup(key, ndx, nActs, nActs, True)))
1129     {
1130         WSGO("Could not resize group %d of key %s\n", ndx,
1131               longText(key->name));
1132         ACTION("Actions lost\n");
1133         return False;
1134     }
1135     key->actsDefined |= (1 << ndx);
1136
1137     toAct = (struct xkb_any_action *) key->acts[ndx];
1138     act = value->value.child;
1139     for (i = 0; i < nActs; i++, toAct++)
1140     {
1141         if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action))
1142         {
1143             ERROR("Illegal action definition for %s\n",
1144                    longText(key->name));
1145             ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1146         }
1147         act = (ExprDef *) act->common.next;
1148     }
1149     return True;
1150 }
1151
1152 static const LookupEntry lockingEntries[] = {
1153     {"true", XkbKB_Lock},
1154     {"yes", XkbKB_Lock},
1155     {"on", XkbKB_Lock},
1156     {"false", XkbKB_Default},
1157     {"no", XkbKB_Default},
1158     {"off", XkbKB_Default},
1159     {"permanent", XkbKB_Lock | XkbKB_Permanent},
1160     {NULL, 0}
1161 };
1162
1163 static const LookupEntry repeatEntries[] = {
1164     {"true", RepeatYes},
1165     {"yes", RepeatYes},
1166     {"on", RepeatYes},
1167     {"false", RepeatNo},
1168     {"no", RepeatNo},
1169     {"off", RepeatNo},
1170     {"default", RepeatUndefined},
1171     {NULL, 0}
1172 };
1173
1174 static Bool
1175 SetSymbolsField(KeyInfo * key,
1176                 struct xkb_desc * xkb,
1177                 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(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_intern_atom(tmp.str);
1195             key->defs.defined |= _Key_Type_Dflt;
1196         }
1197         else if (!ExprResolveGroup(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_intern_atom(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, xkb, field, arrayNdx, value, info);
1214     else if (strcasecmp(field, "actions") == 0)
1215         return AddActionsToKey(key, xkb, field, 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, xkb);
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(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(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(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(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(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, ExprDef * arrayNdx, ExprDef * value)
1331 {
1332     ExprResult tmp, name;
1333
1334     if ((arrayNdx == NULL) && (warningLevel > 0))
1335     {
1336         WARN("You must specify an index when specifying a group name\n");
1337         ACTION("Group name definition without array subscript ignored\n");
1338         return False;
1339     }
1340     if (!ExprResolveGroup(arrayNdx, &tmp))
1341     {
1342         ERROR("Illegal index in group name definition\n");
1343         ACTION("Definition with non-integer array index ignored\n");
1344         return False;
1345     }
1346     if (!ExprResolveString(value, &name))
1347     {
1348         ERROR("Group name must be a string\n");
1349         ACTION("Illegal name for group %d ignored\n", tmp.uval);
1350         return False;
1351     }
1352     info->groupNames[tmp.uval - 1 + info->explicit_group] =
1353         xkb_intern_atom(name.str);
1354     free(name.str);
1355
1356     return True;
1357 }
1358
1359 static int
1360 HandleSymbolsVar(VarDef * stmt, struct xkb_desc * xkb, SymbolsInfo * info)
1361 {
1362     ExprResult elem, field, tmp;
1363     ExprDef *arrayNdx;
1364     Bool ret;
1365
1366     if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1367         return 0;               /* internal error, already reported */
1368     if (elem.str && (strcasecmp(elem.str, "key") == 0))
1369     {
1370         ret = SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1371                               stmt->value, info);
1372     }
1373     else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) ||
1374                                     (strcasecmp(field.str, "groupname") ==
1375                                      0)))
1376     {
1377         ret = SetGroupName(info, arrayNdx, stmt->value);
1378     }
1379     else if ((elem.str == NULL)
1380              && ((strcasecmp(field.str, "groupswrap") == 0) ||
1381                  (strcasecmp(field.str, "wrapgroups") == 0)))
1382     {
1383         if (!ExprResolveBoolean(stmt->value, &tmp))
1384         {
1385             ERROR("Illegal setting for global groupsWrap\n");
1386             ACTION("Non-boolean value ignored\n");
1387             ret = False;
1388         }
1389         else {
1390             if (tmp.uval)
1391                 info->groupInfo = XkbWrapIntoRange;
1392             else
1393                 info->groupInfo = XkbClampIntoRange;
1394             ret = True;
1395         }
1396     }
1397     else if ((elem.str == NULL)
1398              && ((strcasecmp(field.str, "groupsclamp") == 0) ||
1399                  (strcasecmp(field.str, "clampgroups") == 0)))
1400     {
1401         if (!ExprResolveBoolean(stmt->value, &tmp))
1402         {
1403             ERROR("Illegal setting for global groupsClamp\n");
1404             ACTION("Non-boolean value ignored\n");
1405             return False;
1406         }
1407         else {
1408             if (tmp.uval)
1409                 info->groupInfo = XkbClampIntoRange;
1410             else
1411                 info->groupInfo = XkbWrapIntoRange;
1412             ret = True;
1413         }
1414     }
1415     else if ((elem.str == NULL)
1416              && ((strcasecmp(field.str, "groupsredirect") == 0) ||
1417                  (strcasecmp(field.str, "redirectgroups") == 0)))
1418     {
1419         if (!ExprResolveGroup(stmt->value, &tmp))
1420         {
1421             ERROR("Illegal group index for global groupsRedirect\n");
1422             ACTION("Definition with non-integer group ignored\n");
1423             ret = False;
1424         }
1425         else {
1426             info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange,
1427                                               tmp.uval);
1428             ret = True;
1429         }
1430     }
1431     else if ((elem.str == NULL) && (strcasecmp(field.str, "allownone") == 0))
1432     {
1433         ERROR("Radio groups not supported\n");
1434         ACTION("Ignoring \"allow none\" specification\n");
1435         ret = False;
1436     }
1437     else {
1438         ret = SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1439                              &info->action);
1440     }
1441
1442     free(elem.str);
1443     free(field.str);
1444     return ret;
1445 }
1446
1447 static Bool
1448 HandleSymbolsBody(VarDef * def,
1449                   struct xkb_desc * xkb, KeyInfo * key, SymbolsInfo * info)
1450 {
1451     Bool ok = True;
1452     ExprResult tmp, field;
1453     ExprDef *arrayNdx;
1454
1455     for (; def != NULL; def = (VarDef *) def->common.next)
1456     {
1457         if ((def->name) && (def->name->type == ExprFieldRef))
1458         {
1459             ok = HandleSymbolsVar(def, xkb, info);
1460             continue;
1461         }
1462         else
1463         {
1464             if (def->name == NULL)
1465             {
1466                 if ((def->value == NULL)
1467                     || (def->value->op == ExprKeysymList))
1468                     field.str = strdup("symbols");
1469                 else
1470                     field.str = strdup("actions");
1471                 arrayNdx = NULL;
1472             }
1473             else
1474             {
1475                 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1476             }
1477             if (ok)
1478                 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1479                                      def->value, info);
1480             free(field.str);
1481         }
1482     }
1483     return ok;
1484 }
1485
1486 static Bool
1487 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1488 {
1489     unsigned group = info->explicit_group;
1490
1491     if (group == 0)
1492         return True;
1493
1494     if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1495     {
1496         int i;
1497         WARN("For the map %s an explicit group specified\n", info->name);
1498         WARN("but key %s has more than one group defined\n",
1499               longText(key->name));
1500         ACTION("All groups except first one will be ignored\n");
1501         for (i = 1; i < XkbNumKbdGroups; i++)
1502         {
1503             key->numLevels[i] = 0;
1504             free(key->syms[i]);
1505             key->syms[i] = NULL;
1506             free(key->acts[i]);
1507             key->acts[i] = NULL;
1508             key->types[i] = 0;
1509         }
1510     }
1511     key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1512
1513     key->numLevels[group] = key->numLevels[0];
1514     key->numLevels[0] = 0;
1515     key->syms[group] = key->syms[0];
1516     key->syms[0] = NULL;
1517     key->sizeSyms[group] = key->sizeSyms[0];
1518     key->sizeSyms[0] = 0;
1519     key->symsMapIndex[group] = key->symsMapIndex[0];
1520     key->symsMapIndex[0] = NULL;
1521     key->symsMapNumEntries[group] = key->symsMapNumEntries[0];
1522     key->symsMapNumEntries[0] = NULL;
1523     key->acts[group] = key->acts[0];
1524     key->acts[0] = NULL;
1525     key->types[group] = key->types[0];
1526     key->types[0] = 0;
1527     return True;
1528 }
1529
1530 static int
1531 HandleSymbolsDef(SymbolsDef * stmt,
1532                  struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1533 {
1534     KeyInfo key;
1535
1536     InitKeyInfo(&key);
1537     CopyKeyInfo(&info->dflt, &key, False);
1538     key.defs.merge = stmt->merge;
1539     key.name = KeyNameToLong(stmt->keyName);
1540     if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1541     {
1542         info->errorCount++;
1543         return False;
1544     }
1545
1546     if (!SetExplicitGroup(info, &key))
1547     {
1548         info->errorCount++;
1549         return False;
1550     }
1551
1552     if (!AddKeySymbols(info, &key, xkb))
1553     {
1554         info->errorCount++;
1555         return False;
1556     }
1557     return True;
1558 }
1559
1560 static Bool
1561 HandleModMapDef(ModMapDef * def,
1562                 struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1563 {
1564     ExprDef *key;
1565     ModMapEntry tmp;
1566     ExprResult rtrn;
1567     Bool ok;
1568
1569     if (!LookupModIndex(NULL, def->modifier, TypeInt, &rtrn))
1570     {
1571         ERROR("Illegal modifier map definition\n");
1572         ACTION("Ignoring map for non-modifier \"%s\"\n",
1573                 XkbcAtomText(def->modifier));
1574         return False;
1575     }
1576     ok = True;
1577     tmp.modifier = rtrn.uval;
1578     for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1579     {
1580         if ((key->op == ExprValue) && (key->type == TypeKeyName))
1581         {
1582             tmp.haveSymbol = False;
1583             tmp.u.keyName = KeyNameToLong(key->value.keyName);
1584         }
1585         else if (ExprResolveKeySym(key, &rtrn))
1586         {
1587             tmp.haveSymbol = True;
1588             tmp.u.keySym = rtrn.uval;
1589         }
1590         else
1591         {
1592             ERROR("Modmap entries may contain only key names or keysyms\n");
1593             ACTION("Illegal definition for %s modifier ignored\n",
1594                     XkbcModIndexText(tmp.modifier));
1595             continue;
1596         }
1597
1598         ok = AddModMapEntry(info, &tmp) && ok;
1599     }
1600     return ok;
1601 }
1602
1603 static void
1604 HandleSymbolsFile(XkbFile * file,
1605                   struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info)
1606 {
1607     ParseCommon *stmt;
1608
1609     free(info->name);
1610     info->name = uDupString(file->name);
1611     stmt = file->defs;
1612     while (stmt)
1613     {
1614         switch (stmt->stmtType)
1615         {
1616         case StmtInclude:
1617             if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1618                                       HandleSymbolsFile))
1619                 info->errorCount++;
1620             break;
1621         case StmtSymbolsDef:
1622             if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1623                 info->errorCount++;
1624             break;
1625         case StmtVarDef:
1626             if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1627                 info->errorCount++;
1628             break;
1629         case StmtVModDef:
1630             if (!HandleVModDef((VModDef *) stmt, xkb, merge, &info->vmods))
1631                 info->errorCount++;
1632             break;
1633         case StmtInterpDef:
1634             ERROR("Interpretation files may not include other types\n");
1635             ACTION("Ignoring definition of symbol interpretation\n");
1636             info->errorCount++;
1637             break;
1638         case StmtKeycodeDef:
1639             ERROR("Interpretation files may not include other types\n");
1640             ACTION("Ignoring definition of key name\n");
1641             info->errorCount++;
1642             break;
1643         case StmtModMapDef:
1644             if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1645                 info->errorCount++;
1646             break;
1647         default:
1648             WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1649                   stmt->stmtType);
1650             break;
1651         }
1652         stmt = stmt->next;
1653         if (info->errorCount > 10)
1654         {
1655 #ifdef NOISY
1656             ERROR("Too many errors\n");
1657 #endif
1658             ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1659             break;
1660         }
1661     }
1662 }
1663
1664 static Bool
1665 FindKeyForSymbol(struct xkb_desc * xkb, xkb_keysym_t sym, xkb_keycode_t *kc_rtrn)
1666 {
1667     xkb_keycode_t key;
1668     unsigned int group, level;
1669
1670     for (key = xkb->min_key_code; key <= xkb->max_key_code; key++)
1671     {
1672         for (group = 0; group < XkbKeyNumGroups(xkb, key); group++)
1673         {
1674             for (level = 0; level < XkbKeyGroupWidth(xkb, key, group); level++)
1675             {
1676                 if (XkbKeyNumSyms(xkb, key, group, level) != 1 ||
1677                     (XkbKeySymEntry(xkb, 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 xkb->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_desc * xkb, xkb_atom_t atom, unsigned *type_rtrn)
1698 {
1699     unsigned n;
1700     const char *name = XkbcAtomText(atom);
1701
1702     if (xkb && xkb->map && xkb->map->types)
1703     {
1704         for (n = 0; n < xkb->map->num_types; n++)
1705         {
1706             if (strcmp(xkb->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(int width, xkb_keysym_t * syms, xkb_atom_t * typeNameRtrn,
1734                   Bool * autoType)
1735 {
1736     *autoType = False;
1737     if ((width == 1) || (width == 0))
1738     {
1739         *typeNameRtrn = xkb_intern_atom("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_intern_atom("ALPHABETIC");
1747         }
1748         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1749         {
1750             *typeNameRtrn = xkb_intern_atom("KEYPAD");
1751             *autoType = True;
1752         }
1753         else
1754         {
1755             *typeNameRtrn = xkb_intern_atom("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_intern_atom("FOUR_LEVEL_ALPHABETIC");
1765             else
1766                 *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_SEMIALPHABETIC");
1767
1768         else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1769             *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_KEYPAD");
1770         else
1771             *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL");
1772         /* XXX: why not set autoType here? */
1773     }
1774     return ((width >= 0) && (width <= 4));
1775 }
1776
1777 /**
1778  * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1779  * groups, and reduce to one group if all groups are identical anyway.
1780  */
1781 static void
1782 PrepareKeyDef(KeyInfo * key)
1783 {
1784     int i, j, width, defined, lastGroup;
1785     Bool identical;
1786
1787     defined = key->symsDefined | key->actsDefined | key->typesDefined;
1788     /* get highest group number */
1789     for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1790     {
1791         if (defined & (1 << i))
1792             break;
1793     }
1794     lastGroup = i;
1795
1796     if (lastGroup == 0)
1797         return;
1798
1799     /* If there are empty groups between non-empty ones fill them with data */
1800     /* from the first group. */
1801     /* We can make a wrong assumption here. But leaving gaps is worse. */
1802     for (i = lastGroup; i > 0; i--)
1803     {
1804         if (defined & (1 << i))
1805             continue;
1806         width = key->numLevels[0];
1807         if (key->typesDefined & 1)
1808         {
1809             for (j = 0; j < width; j++)
1810             {
1811                 key->types[i] = key->types[0];
1812             }
1813             key->typesDefined |= 1 << i;
1814         }
1815         if ((key->actsDefined & 1) && key->acts[0])
1816         {
1817             key->acts[i] = uTypedCalloc(width, union xkb_action);
1818             if (key->acts[i] == NULL)
1819                 continue;
1820             memcpy(key->acts[i], key->acts[0],
1821                    width * sizeof(union xkb_action));
1822             key->actsDefined |= 1 << i;
1823         }
1824         if ((key->symsDefined & 1) && key->sizeSyms[0])
1825         {
1826             key->syms[i] = uTypedCalloc(key->sizeSyms[0], xkb_keysym_t);
1827             if (key->syms[i] == NULL)
1828                 continue;
1829             memcpy(key->syms[i], key->syms[0],
1830                    key->sizeSyms[0] * sizeof(xkb_keysym_t));
1831             key->symsMapIndex[i] = uTypedCalloc(width, int);
1832             if (!key->symsMapIndex[i])
1833             {
1834                 free(key->syms[i]);
1835                 key->syms[i] = NULL;
1836                 continue;
1837             }
1838             memcpy(key->symsMapIndex[i], key->symsMapIndex[0],
1839                    width * sizeof(int));
1840             key->symsMapNumEntries[i] = uTypedCalloc(width, unsigned int);
1841             if (!key->symsMapNumEntries[i])
1842             {
1843                 free(key->syms[i]);
1844                 key->syms[i] = NULL;
1845                 free(key->symsMapIndex[i]);
1846                 key->symsMapIndex[i] = NULL;
1847                 continue;
1848             }
1849             memcpy(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
1850                    width * sizeof(int));
1851             key->sizeSyms[i] = key->sizeSyms[0];
1852             key->symsDefined |= 1 << i;
1853         }
1854         if (defined & 1)
1855         {
1856             key->numLevels[i] = key->numLevels[0];
1857         }
1858     }
1859     /* If all groups are completely identical remove them all */
1860     /* exept the first one. */
1861     identical = True;
1862     for (i = lastGroup; i > 0; i--)
1863     {
1864         if ((key->numLevels[i] != key->numLevels[0]) ||
1865             (key->types[i] != key->types[0]))
1866         {
1867             identical = False;
1868             break;
1869         }
1870         if ((key->syms[i] != key->syms[0]) &&
1871             (key->syms[i] == NULL || key->syms[0] == NULL ||
1872              key->sizeSyms[i] != key->sizeSyms[0] ||
1873              memcmp(key->syms[i], key->syms[0],
1874                     sizeof(xkb_keysym_t) * key->sizeSyms[0])))
1875         {
1876             identical = False;
1877             break;
1878         }
1879         if ((key->symsMapIndex[i] != key->symsMapIndex[i]) &&
1880             (key->symsMapIndex[i] == NULL || key->symsMapIndex[0] == NULL ||
1881              memcmp(key->symsMapIndex[i], key->symsMapIndex[0],
1882                     key->numLevels[0] * sizeof(int))))
1883         {
1884             identical = False;
1885             continue;
1886         }
1887         if ((key->symsMapNumEntries[i] != key->symsMapNumEntries[i]) &&
1888             (key->symsMapNumEntries[i] == NULL ||
1889              key->symsMapNumEntries[0] == NULL ||
1890              memcmp(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
1891                     key->numLevels[0] * sizeof(int))))
1892         {
1893             identical = False;
1894             continue;
1895         }
1896         if ((key->acts[i] != key->acts[0]) &&
1897             (key->acts[i] == NULL || key->acts[0] == NULL ||
1898              memcmp(key->acts[i], key->acts[0],
1899                     sizeof(union xkb_action) * key->numLevels[0])))
1900         {
1901             identical = False;
1902             break;
1903         }
1904     }
1905     if (identical)
1906     {
1907         for (i = lastGroup; i > 0; i--)
1908         {
1909             key->numLevels[i] = 0;
1910             free(key->syms[i]);
1911             key->syms[i] = NULL;
1912             key->sizeSyms[i] = 0;
1913             free(key->symsMapIndex[i]);
1914             key->symsMapIndex[i] = NULL;
1915             free(key->symsMapNumEntries[i]);
1916             key->symsMapNumEntries[i] = NULL;
1917             free(key->acts[i]);
1918             key->acts[i] = NULL;
1919             key->types[i] = 0;
1920         }
1921         key->symsDefined &= 1;
1922         key->actsDefined &= 1;
1923         key->typesDefined &= 1;
1924     }
1925 }
1926
1927 /**
1928  * Copy the KeyInfo into the keyboard description.
1929  *
1930  * This function recurses.
1931  */
1932 static Bool
1933 CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from)
1934 {
1935     unsigned int i;
1936     xkb_keycode_t kc;
1937     unsigned int sizeSyms = 0;
1938     unsigned width, tmp, nGroups;
1939     struct xkb_key_type * type;
1940     Bool haveActions, autoType, useAlias;
1941     xkb_keysym_t *outSyms;
1942     union xkb_action *outActs;
1943     unsigned types[XkbNumKbdGroups];
1944     unsigned int symIndex = 0;
1945
1946     useAlias = (start_from == 0);
1947
1948     /* get the keycode for the key. */
1949     if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1950                       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(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                             XkbcAtomText(key->types[i]),
1987                             longText(key->name), kc);
1988                 }
1989             }
1990         }
1991         if (FindNamedType(xkb, key->types[i], &types[i]))
1992         {
1993             if (!autoType || key->numLevels[i] > 2)
1994                 xkb->server->explicit[kc] |= (1 << i);
1995         }
1996         else
1997         {
1998             if (warningLevel >= 3)
1999             {
2000                 WARN("Type \"%s\" is not defined\n",
2001                       XkbcAtomText(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 = &xkb->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                      XkbcAtomText(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(xkb, 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(xkb, 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         xkb->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 = xkb->map->key_sym_map[kc].group_info;
2050
2051     xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2052     xkb->map->key_sym_map[kc].width = width;
2053     xkb->map->key_sym_map[kc].sym_index = uTypedCalloc(nGroups * width, int);
2054     xkb->map->key_sym_map[kc].num_syms = uTypedCalloc(nGroups * width,
2055                                                       unsigned int);
2056     for (i = 0; i < nGroups; i++)
2057     {
2058         /* assign kt_index[i] to the index of the type in map->types.
2059          * kt_index[i] may have been set by a previous run (if we have two
2060          * layouts specified). Let's not overwrite it with the ONE_LEVEL
2061          * default group if we dont even have keys for this group anyway.
2062          *
2063          * FIXME: There should be a better fix for this.
2064          */
2065         if (key->numLevels[i])
2066             xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2067         if (key->sizeSyms[i] != 0)
2068         {
2069             /* fill key to "width" symbols*/
2070             for (tmp = 0; tmp < width; tmp++)
2071             {
2072                 if (tmp < key->numLevels[i] && key->symsMapNumEntries[i][tmp])
2073                 {
2074                     memcpy(&xkb->map->key_sym_map[kc].syms[symIndex],
2075                            &key->syms[i][key->symsMapIndex[i][tmp]],
2076                            key->symsMapNumEntries[i][tmp] *
2077                             sizeof(xkb_keysym_t));
2078                     xkb->map->key_sym_map[kc].sym_index[(i * width) + tmp] =
2079                         symIndex;
2080                     xkb->map->key_sym_map[kc].num_syms[(i * width) + tmp] =
2081                         key->symsMapNumEntries[i][tmp];
2082                     symIndex +=
2083                         xkb->map->key_sym_map[kc].num_syms[(i * width) + tmp];
2084                 }
2085                 else
2086                 {
2087                     xkb->map->key_sym_map[kc].sym_index[(i * width) + tmp] = -1;
2088                     xkb->map->key_sym_map[kc].num_syms[(i * width) + tmp] = 0;
2089                 }
2090                 if ((outActs != NULL) && (key->acts[i] != NULL))
2091                 {
2092                     if (tmp < key->numLevels[i])
2093                         outActs[tmp] = key->acts[i][tmp];
2094                     else
2095                         outActs[tmp].type = XkbSA_NoAction;
2096                 }
2097             }
2098         }
2099     }
2100     switch (key->behavior.type & XkbKB_OpMask)
2101     {
2102     case XkbKB_Default:
2103         break;
2104     default:
2105         xkb->server->behaviors[kc] = key->behavior;
2106         xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2107         break;
2108     }
2109     if (key->defs.defined & _Key_VModMap)
2110     {
2111         xkb->server->vmodmap[kc] = key->vmodmap;
2112         xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2113     }
2114     if (key->repeat != RepeatUndefined)
2115     {
2116         if (key->repeat == RepeatYes)
2117             xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2118         else
2119             xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2120         xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2121     }
2122
2123     if (nGroups > xkb->ctrls->num_groups)
2124         xkb->ctrls->num_groups = nGroups;
2125
2126     /* do the same thing for the next key */
2127     CopySymbolsDef(xkb, key, kc + 1);
2128     return True;
2129 }
2130
2131 static Bool
2132 CopyModMapDef(struct xkb_desc * xkb, ModMapEntry *entry)
2133 {
2134     xkb_keycode_t kc;
2135
2136     if ((!entry->haveSymbol)
2137         &&
2138         (!FindNamedKey
2139          (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 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(xkb, 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     xkb->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 xkb 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_desc * xkb, unsigned merge)
2175 {
2176     unsigned int i;
2177     SymbolsInfo info;
2178
2179     InitSymbolsInfo(&info, xkb);
2180     info.dflt.defs.fileID = file->id;
2181     info.dflt.defs.merge = merge;
2182     HandleSymbolsFile(file, xkb, merge, &info);
2183
2184     if (info.nKeys == 0) {
2185         FreeSymbolsInfo(&info);
2186         return True;
2187     }
2188
2189     if (info.errorCount == 0)
2190     {
2191         KeyInfo *key;
2192
2193         /* alloc memory in the xkb struct */
2194         if (XkbcAllocNames(xkb, XkbGroupNamesMask, 0) != Success)
2195         {
2196             WSGO("Can not allocate names in CompileSymbols\n");
2197             ACTION("Symbols not added\n");
2198             return False;
2199         }
2200         if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2201             != Success)
2202         {
2203             WSGO("Could not allocate client map in CompileSymbols\n");
2204             ACTION("Symbols not added\n");
2205             return False;
2206         }
2207         if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2208         {
2209             WSGO("Could not allocate server map in CompileSymbols\n");
2210             ACTION("Symbols not added\n");
2211             return False;
2212         }
2213         if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2214         {
2215             WSGO("Could not allocate controls in CompileSymbols\n");
2216             ACTION("Symbols not added\n");
2217             return False;
2218         }
2219
2220         /* now copy info into xkb. */
2221         if (info.aliases)
2222             ApplyAliases(xkb, &info.aliases);
2223         for (i = 0; i < XkbNumKbdGroups; i++)
2224         {
2225             if (info.groupNames[i] != XKB_ATOM_NONE)
2226             {
2227                 free(UNCONSTIFY(xkb->names->groups[i]));
2228                 xkb->names->groups[i] = XkbcAtomGetString(info.groupNames[i]);
2229             }
2230         }
2231         /* sanitize keys */
2232         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2233         {
2234             PrepareKeyDef(key);
2235         }
2236         /* copy! */
2237         for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2238         {
2239             if (!CopySymbolsDef(xkb, key, 0))
2240                 info.errorCount++;
2241         }
2242         if (warningLevel > 3)
2243         {
2244             for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2245             {
2246                 if (xkb->names->keys[i].name[0] == '\0')
2247                     continue;
2248                 if (XkbKeyNumGroups(xkb, i) < 1)
2249                 {
2250                     char buf[5];
2251                     memcpy(buf, xkb->names->keys[i].name, 4);
2252                     buf[4] = '\0';
2253                     WARN
2254                         ("No symbols defined for <%s> (keycode %d)\n",
2255                          buf, i);
2256                 }
2257             }
2258         }
2259         if (info.modMap)
2260         {
2261             ModMapEntry *mm, *next;
2262             for (mm = info.modMap; mm != NULL; mm = next)
2263             {
2264                 if (!CopyModMapDef(xkb, mm))
2265                     info.errorCount++;
2266                 next = (ModMapEntry *) mm->defs.next;
2267             }
2268         }
2269         FreeSymbolsInfo(&info);
2270         return True;
2271     }
2272
2273     FreeSymbolsInfo(&info);
2274     return False;
2275 }