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