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