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