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