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