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