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