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