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