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