darray: some changes for convenience
[profile/ivi/libxkbcommon.git] / src / xkbcomp / keytypes.c
1 /************************************************************
2  Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3
4  Permission to use, copy, modify, and distribute this
5  software and its documentation for any purpose and without
6  fee is hereby granted, provided that the above copyright
7  notice appear in all copies and that both that copyright
8  notice and this permission notice appear in supporting
9  documentation, and that the name of Silicon Graphics not be
10  used in advertising or publicity pertaining to distribution
11  of the software without specific prior written permission.
12  Silicon Graphics makes no representation about the suitability
13  of this software for any purpose. It is provided "as is"
14  without any express or implied warranty.
15
16  SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19  GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23  THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25  ********************************************************/
26
27 #include "xkbcomp-priv.h"
28 #include "parseutils.h"
29 #include "vmod.h"
30
31 typedef struct _PreserveInfo
32 {
33     CommonInfo defs;
34     short matchingMapIndex;
35     unsigned char indexMods;
36     unsigned char preMods;
37     unsigned short indexVMods;
38     unsigned short preVMods;
39 } PreserveInfo;
40
41 #define _KT_Name        (1<<0)
42 #define _KT_Mask        (1<<1)
43 #define _KT_Map         (1<<2)
44 #define _KT_Preserve    (1<<3)
45 #define _KT_LevelNames  (1<<4)
46
47 typedef struct _KeyTypeInfo
48 {
49     CommonInfo defs;
50     xkb_atom_t name;
51     int fileID;
52     unsigned mask;
53     unsigned vmask;
54     bool groupInfo;
55     unsigned numLevels;
56     darray(struct xkb_kt_map_entry) entries;
57     PreserveInfo *preserve;
58     darray(xkb_atom_t) lvlNames;
59 } KeyTypeInfo;
60
61 typedef struct _KeyTypesInfo
62 {
63     char *name;
64     int errorCount;
65     int fileID;
66     unsigned stdPresent;
67     unsigned nTypes;
68     KeyTypeInfo *types;
69     KeyTypeInfo dflt;
70     VModInfo vmods;
71 } KeyTypesInfo;
72
73 static xkb_atom_t tok_ONE_LEVEL;
74 static xkb_atom_t tok_TWO_LEVEL;
75 static xkb_atom_t tok_ALPHABETIC;
76 static xkb_atom_t tok_KEYPAD;
77
78 /***====================================================================***/
79
80 #define ReportTypeShouldBeArray(keymap, t, f) \
81     ReportShouldBeArray("key type", (f), TypeTxt((keymap), (t)))
82 #define ReportTypeBadType(keymap, t, f, w) \
83     ReportBadType("key type", (f), TypeTxt((keymap), (t)), (w))
84
85 /***====================================================================***/
86
87 #define MapEntryTxt(x, e) \
88     XkbcVModMaskText((x), (e)->mods.real_mods, (e)->mods.vmods)
89 #define PreserveIndexTxt(x, p) \
90     XkbcVModMaskText((x), (p)->indexMods, (p)->indexVMods)
91 #define PreserveTxt(x, p) \
92     XkbcVModMaskText((x), (p)->preMods, (p)->preVMods)
93 #define TypeTxt(keymap, t) \
94     xkb_atom_text((keymap)->ctx, (t)->name)
95 #define TypeMaskTxt(t, x) \
96     XkbcVModMaskText((x), (t)->mask, (t)->vmask)
97
98 /***====================================================================***/
99
100 static void
101 InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
102                  KeyTypesInfo *from)
103 {
104     tok_ONE_LEVEL = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
105     tok_TWO_LEVEL = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
106     tok_ALPHABETIC = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
107     tok_KEYPAD = xkb_atom_intern(keymap->ctx, "KEYPAD");
108     info->name = strdup("default");
109     info->errorCount = 0;
110     info->stdPresent = 0;
111     info->nTypes = 0;
112     info->types = NULL;
113     info->dflt.defs.defined = 0;
114     info->dflt.defs.fileID = 0;
115     info->dflt.defs.merge = MergeOverride;
116     info->dflt.defs.next = NULL;
117     info->dflt.name = XKB_ATOM_NONE;
118     info->dflt.mask = 0;
119     info->dflt.vmask = 0;
120     info->dflt.groupInfo = false;
121     info->dflt.numLevels = 1;
122     darray_init(info->dflt.entries);
123     darray_init(info->dflt.lvlNames);
124     info->dflt.preserve = NULL;
125     InitVModInfo(&info->vmods, keymap);
126     if (from != NULL)
127     {
128         info->dflt = from->dflt;
129
130         darray_copy(info->dflt.entries, from->dflt.entries);
131         darray_copy(info->dflt.lvlNames, from->dflt.lvlNames);
132
133         if (from->dflt.preserve)
134         {
135             PreserveInfo *old, *new, *last;
136             last = NULL;
137             old = from->dflt.preserve;
138             for (; old; old = (PreserveInfo *) old->defs.next)
139             {
140                 new = uTypedAlloc(PreserveInfo);
141                 if (!new)
142                     return;
143                 *new = *old;
144                 new->defs.next = NULL;
145                 if (last)
146                     last->defs.next = (CommonInfo *) new;
147                 else
148                     info->dflt.preserve = new;
149                 last = new;
150             }
151         }
152     }
153 }
154
155 static void
156 FreeKeyTypeInfo(KeyTypeInfo * type)
157 {
158     darray_free(type->entries);
159     darray_free(type->lvlNames);
160     if (type->preserve != NULL)
161     {
162         ClearCommonInfo(&type->preserve->defs);
163         type->preserve = NULL;
164     }
165 }
166
167 static void
168 FreeKeyTypesInfo(KeyTypesInfo * info)
169 {
170     free(info->name);
171     info->name = NULL;
172     if (info->types)
173     {
174         KeyTypeInfo *type;
175         for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
176         {
177             FreeKeyTypeInfo(type);
178         }
179         info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs);
180     }
181     FreeKeyTypeInfo(&info->dflt);
182 }
183
184 static KeyTypeInfo *
185 NextKeyType(KeyTypesInfo * info)
186 {
187     KeyTypeInfo *type;
188
189     type = uTypedAlloc(KeyTypeInfo);
190     if (type != NULL)
191     {
192         memset(type, 0, sizeof(KeyTypeInfo));
193         type->defs.fileID = info->fileID;
194         info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs,
195                                                     (CommonInfo *) type);
196         info->nTypes++;
197     }
198     return type;
199 }
200
201 static KeyTypeInfo *
202 FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
203 {
204     KeyTypeInfo *old;
205
206     for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
207     {
208         if (old->name == new->name)
209             return old;
210     }
211     return NULL;
212 }
213
214 static bool
215 ReportTypeBadWidth(const char *type, int has, int needs)
216 {
217     ERROR("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
218     ACTION("Illegal type definition ignored\n");
219     return false;
220 }
221
222 static bool
223 AddKeyType(struct xkb_keymap *keymap, KeyTypesInfo *info, KeyTypeInfo *new)
224 {
225     KeyTypeInfo *old;
226
227     if (new->name == tok_ONE_LEVEL)
228     {
229         if (new->numLevels > 1)
230             return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
231         info->stdPresent |= XkbOneLevelMask;
232     }
233     else if (new->name == tok_TWO_LEVEL)
234     {
235         if (new->numLevels > 2)
236             return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
237         else if (new->numLevels < 2)
238             new->numLevels = 2;
239         info->stdPresent |= XkbTwoLevelMask;
240     }
241     else if (new->name == tok_ALPHABETIC)
242     {
243         if (new->numLevels > 2)
244             return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
245         else if (new->numLevels < 2)
246             new->numLevels = 2;
247         info->stdPresent |= XkbAlphabeticMask;
248     }
249     else if (new->name == tok_KEYPAD)
250     {
251         if (new->numLevels > 2)
252             return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
253         else if (new->numLevels < 2)
254             new->numLevels = 2;
255         info->stdPresent |= XkbKeypadMask;
256     }
257
258     old = FindMatchingKeyType(info, new);
259     if (old != NULL)
260     {
261         bool report;
262         if ((new->defs.merge == MergeReplace)
263             || (new->defs.merge == MergeOverride))
264         {
265             KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
266             if (((old->defs.fileID == new->defs.fileID)
267                  && (warningLevel > 0)) || (warningLevel > 9))
268             {
269                 WARN("Multiple definitions of the %s key type\n",
270                      xkb_atom_text(keymap->ctx, new->name));
271                 ACTION("Earlier definition ignored\n");
272             }
273             FreeKeyTypeInfo(old);
274             *old = *new;
275             darray_init(new->entries);
276             darray_init(new->lvlNames);
277             new->preserve = NULL;
278             old->defs.next = &next->defs;
279             return true;
280         }
281         report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
282         if (report)
283         {
284             WARN("Multiple definitions of the %s key type\n",
285                  xkb_atom_text(keymap->ctx, new->name));
286             ACTION("Later definition ignored\n");
287         }
288         FreeKeyTypeInfo(new);
289         return true;
290     }
291     old = NextKeyType(info);
292     if (old == NULL)
293         return false;
294     *old = *new;
295     old->defs.next = NULL;
296     darray_init(new->entries);
297     darray_init(new->lvlNames);
298     new->preserve = NULL;
299     return true;
300 }
301
302 /***====================================================================***/
303
304 static void
305 MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
306                       unsigned merge, struct xkb_keymap *keymap)
307 {
308     KeyTypeInfo *type;
309
310     if (from->errorCount > 0)
311     {
312         into->errorCount += from->errorCount;
313         return;
314     }
315     if (into->name == NULL)
316     {
317         into->name = from->name;
318         from->name = NULL;
319     }
320     for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
321     {
322         if (merge != MergeDefault)
323             type->defs.merge = merge;
324         if (!AddKeyType(keymap, into, type))
325             into->errorCount++;
326     }
327     into->stdPresent |= from->stdPresent;
328 }
329
330 static void
331 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
332                    unsigned merge, KeyTypesInfo *info);
333
334 static bool
335 HandleIncludeKeyTypes(IncludeStmt *stmt, struct xkb_keymap *keymap,
336                       KeyTypesInfo *info)
337 {
338     unsigned newMerge;
339     XkbFile *rtrn;
340     KeyTypesInfo included;
341     bool haveSelf;
342
343     haveSelf = false;
344     if ((stmt->file == NULL) && (stmt->map == NULL))
345     {
346         haveSelf = true;
347         included = *info;
348         memset(info, 0, sizeof(KeyTypesInfo));
349     }
350     else if (ProcessIncludeFile(keymap->ctx, stmt, XkmTypesIndex, &rtrn,
351                                 &newMerge))
352     {
353         InitKeyTypesInfo(&included, keymap, info);
354         included.fileID = included.dflt.defs.fileID = rtrn->id;
355         included.dflt.defs.merge = newMerge;
356
357         HandleKeyTypesFile(rtrn, keymap, newMerge, &included);
358         if (stmt->stmt != NULL)
359         {
360             free(included.name);
361             included.name = stmt->stmt;
362             stmt->stmt = NULL;
363         }
364         FreeXKBFile(rtrn);
365     }
366     else
367     {
368         info->errorCount += 10;
369         return false;
370     }
371     if ((stmt->next != NULL) && (included.errorCount < 1))
372     {
373         IncludeStmt *next;
374         unsigned op;
375         KeyTypesInfo next_incl;
376
377         for (next = stmt->next; next != NULL; next = next->next)
378         {
379             if ((next->file == NULL) && (next->map == NULL))
380             {
381                 haveSelf = true;
382                 MergeIncludedKeyTypes(&included, info, next->merge, keymap);
383                 FreeKeyTypesInfo(info);
384             }
385             else if (ProcessIncludeFile(keymap->ctx, next, XkmTypesIndex,
386                                         &rtrn, &op))
387             {
388                 InitKeyTypesInfo(&next_incl, keymap, &included);
389                 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
390                 next_incl.dflt.defs.merge = op;
391                 HandleKeyTypesFile(rtrn, keymap, op, &next_incl);
392                 MergeIncludedKeyTypes(&included, &next_incl, op, keymap);
393                 FreeKeyTypesInfo(&next_incl);
394                 FreeXKBFile(rtrn);
395             }
396             else
397             {
398                 info->errorCount += 10;
399                 FreeKeyTypesInfo(&included);
400                 return false;
401             }
402         }
403     }
404     if (haveSelf)
405         *info = included;
406     else
407     {
408         MergeIncludedKeyTypes(info, &included, newMerge, keymap);
409         FreeKeyTypesInfo(&included);
410     }
411     return (info->errorCount == 0);
412 }
413
414 /***====================================================================***/
415
416 static struct xkb_kt_map_entry *
417 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
418 {
419     struct xkb_kt_map_entry *entry;
420
421     darray_foreach(entry, type->entries)
422         if (entry->mods.real_mods == mask && entry->mods.vmods == vmask)
423             return entry;
424
425     return NULL;
426 }
427
428 static void
429 DeleteLevel1MapEntries(KeyTypeInfo * type)
430 {
431     unsigned int i, n;
432
433     /* TODO: Be just a bit more clever here. */
434     for (i = 0; i < darray_size(type->entries); i++) {
435         if (darray_item(type->entries, i).level == 0) {
436             for (n = i; n < darray_size(type->entries) - 1; n++)
437                 darray_item(type->entries, n) =
438                     darray_item(type->entries, n + 1);
439             (void)darray_pop(type->entries);
440         }
441     }
442 }
443
444 static struct xkb_kt_map_entry *
445 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
446 {
447     darray_resize0(type->entries, darray_size(type->entries) + 1);
448     return &darray_item(type->entries, darray_size(type->entries) - 1);
449 }
450
451 static bool
452 AddPreserve(struct xkb_keymap *keymap, KeyTypeInfo *type,
453             PreserveInfo *new, bool clobber, bool report)
454 {
455     PreserveInfo *old;
456
457     old = type->preserve;
458     while (old != NULL)
459     {
460         if ((old->indexMods != new->indexMods) ||
461             (old->indexVMods != new->indexVMods))
462         {
463             old = (PreserveInfo *) old->defs.next;
464             continue;
465         }
466         if ((old->preMods == new->preMods)
467             && (old->preVMods == new->preVMods))
468         {
469             if (warningLevel > 9)
470             {
471                 WARN("Identical definitions for preserve[%s] in %s\n",
472                       PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
473                 ACTION("Ignored\n");
474             }
475             return true;
476         }
477         if (report && (warningLevel > 0))
478         {
479             const char *str;
480             WARN("Multiple definitions for preserve[%s] in %s\n",
481                   PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
482
483             if (clobber)
484                 str = PreserveTxt(keymap, new);
485             else
486                 str = PreserveTxt(keymap, old);
487             ACTION("Using %s, ", str);
488             if (clobber)
489                 str = PreserveTxt(keymap, old);
490             else
491                 str = PreserveTxt(keymap, new);
492             INFO("ignoring %s\n", str);
493         }
494         if (clobber)
495         {
496             old->preMods = new->preMods;
497             old->preVMods = new->preVMods;
498         }
499         return true;
500     }
501     old = uTypedAlloc(PreserveInfo);
502     if (!old)
503     {
504         WSGO("Couldn't allocate preserve in %s\n", TypeTxt(keymap, type));
505         ACTION("Preserve[%s] lost\n", PreserveIndexTxt(keymap, new));
506         return false;
507     }
508     *old = *new;
509     old->matchingMapIndex = -1;
510     type->preserve =
511         (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
512     return true;
513 }
514
515 /**
516  * Add a new KTMapEntry to the given key type. If an entry with the same mods
517  * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
518  * entry is created.
519  *
520  * @param clobber Overwrite existing entry.
521  * @param report true if a warning is to be printed on.
522  */
523 static bool
524 AddMapEntry(struct xkb_keymap *keymap, KeyTypeInfo *type,
525             struct xkb_kt_map_entry *new, bool clobber, bool report)
526 {
527     struct xkb_kt_map_entry * old;
528
529     if ((old =
530          FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
531     {
532         if (report && (old->level != new->level))
533         {
534             unsigned use, ignore;
535             if (clobber)
536             {
537                 use = new->level + 1;
538                 ignore = old->level + 1;
539             }
540             else
541             {
542                 use = old->level + 1;
543                 ignore = new->level + 1;
544             }
545             WARN("Multiple map entries for %s in %s\n",
546                   MapEntryTxt(keymap, new), TypeTxt(keymap, type));
547             ACTION("Using %d, ignoring %d\n", use, ignore);
548         }
549         else if (warningLevel > 9)
550         {
551             WARN("Multiple occurences of map[%s]= %d in %s\n",
552                   MapEntryTxt(keymap, new), new->level + 1,
553                   TypeTxt(keymap, type));
554             ACTION("Ignored\n");
555             return true;
556         }
557         if (clobber)
558             old->level = new->level;
559         return true;
560     }
561     if ((old = NextMapEntry(keymap, type)) == NULL)
562         return false;           /* allocation failure, already reported */
563     if (new->level >= type->numLevels)
564         type->numLevels = new->level + 1;
565     if (new->mods.vmods == 0)
566         old->active = true;
567     else
568         old->active = false;
569     old->mods.mask = new->mods.real_mods;
570     old->mods.real_mods = new->mods.real_mods;
571     old->mods.vmods = new->mods.vmods;
572     old->level = new->level;
573     return true;
574 }
575
576 static bool
577 SetMapEntry(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
578             ExprDef *value)
579 {
580     ExprResult rtrn;
581     struct xkb_kt_map_entry entry;
582
583     if (arrayNdx == NULL)
584         return ReportTypeShouldBeArray(keymap, type, "map entry");
585     if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
586         return ReportTypeBadType(keymap, type, "map entry", "modifier mask");
587     entry.mods.real_mods = rtrn.uval & 0xff;      /* modifiers < 512 */
588     entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
589     if ((entry.mods.real_mods & (~type->mask)) ||
590         ((entry.mods.vmods & (~type->vmask)) != 0))
591     {
592         if (warningLevel > 0)
593         {
594             WARN("Map entry for unused modifiers in %s\n", TypeTxt(keymap, type));
595             ACTION("Using %s instead of ",
596                     XkbcVModMaskText(keymap,
597                                     entry.mods.real_mods & type->mask,
598                                     entry.mods.vmods & type->vmask));
599             INFO("%s\n", MapEntryTxt(keymap, &entry));
600         }
601         entry.mods.real_mods &= type->mask;
602         entry.mods.vmods &= type->vmask;
603     }
604     if (!ExprResolveLevel(keymap->ctx, value, &rtrn))
605     {
606         ERROR("Level specifications in a key type must be integer\n");
607         ACTION("Ignoring malformed level specification\n");
608         return false;
609     }
610     entry.level = rtrn.ival - 1;
611     return AddMapEntry(keymap, type, &entry, true, true);
612 }
613
614 static bool
615 SetPreserve(KeyTypeInfo *type, struct xkb_keymap *keymap,
616             ExprDef *arrayNdx, ExprDef *value)
617 {
618     ExprResult rtrn;
619     PreserveInfo new;
620
621     if (arrayNdx == NULL)
622         return ReportTypeShouldBeArray(keymap, type, "preserve entry");
623     if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
624         return ReportTypeBadType(keymap, type, "preserve entry",
625                                  "modifier mask");
626     new.defs = type->defs;
627     new.defs.next = NULL;
628     new.indexMods = rtrn.uval & 0xff;
629     new.indexVMods = (rtrn.uval >> 8) & 0xffff;
630     if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
631     {
632         if (warningLevel > 0)
633         {
634             WARN("Preserve for modifiers not used by the %s type\n",
635                   TypeTxt(keymap, type));
636             ACTION("Index %s converted to ", PreserveIndexTxt(keymap, &new));
637         }
638         new.indexMods &= type->mask;
639         new.indexVMods &= type->vmask;
640         if (warningLevel > 0)
641             INFO("%s\n", PreserveIndexTxt(keymap, &new));
642     }
643     if (!ExprResolveVModMask(value, &rtrn, keymap))
644     {
645         ERROR("Preserve value in a key type is not a modifier mask\n");
646         ACTION("Ignoring preserve[%s] in type %s\n",
647                 PreserveIndexTxt(keymap, &new), TypeTxt(keymap, type));
648         return false;
649     }
650     new.preMods = rtrn.uval & 0xff;
651     new.preVMods = (rtrn.uval >> 16) & 0xffff;
652     if ((new.preMods & (~new.indexMods))
653         || (new.preVMods & (~new.indexVMods)))
654     {
655         if (warningLevel > 0)
656         {
657             WARN("Illegal value for preserve[%s] in type %s\n",
658                   PreserveTxt(keymap, &new), TypeTxt(keymap, type));
659             ACTION("Converted %s to ", PreserveIndexTxt(keymap, &new));
660         }
661         new.preMods &= new.indexMods;
662         new.preVMods &= new.indexVMods;
663         if (warningLevel > 0)
664         {
665             INFO("%s\n", PreserveIndexTxt(keymap, &new));
666         }
667     }
668     return AddPreserve(keymap, type, &new, true, true);
669 }
670
671 /***====================================================================***/
672
673 static bool
674 AddLevelName(struct xkb_keymap *keymap, KeyTypeInfo *type,
675              unsigned level, xkb_atom_t name, bool clobber)
676 {
677     if (level >= darray_size(type->lvlNames))
678         darray_resize0(type->lvlNames, level + 1);
679
680     if (darray_item(type->lvlNames, level) == name) {
681         if (warningLevel > 9) {
682             WARN("Duplicate names for level %d of key type %s\n",
683                  level + 1, TypeTxt(keymap, type));
684             ACTION("Ignored\n");
685         }
686         return true;
687     }
688     else if (darray_item(type->lvlNames, level) != XKB_ATOM_NONE) {
689         if (warningLevel > 0) {
690             const char *old, *new;
691             old = xkb_atom_text(keymap->ctx,
692                                 darray_item(type->lvlNames, level));
693             new = xkb_atom_text(keymap->ctx, name);
694             WARN("Multiple names for level %d of key type %s\n",
695                  level + 1, TypeTxt(keymap, type));
696             if (clobber)
697                 ACTION("Using %s, ignoring %s\n", new, old);
698             else
699                 ACTION("Using %s, ignoring %s\n", old, new);
700         }
701
702         if (!clobber)
703             return true;
704     }
705
706     darray_item(type->lvlNames, level) = name;
707     return true;
708 }
709
710 static bool
711 SetLevelName(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
712              ExprDef *value)
713 {
714     ExprResult rtrn;
715     unsigned level;
716     xkb_atom_t level_name;
717
718     if (arrayNdx == NULL)
719         return ReportTypeShouldBeArray(keymap, type, "level name");
720     if (!ExprResolveLevel(keymap->ctx, arrayNdx, &rtrn))
721         return ReportTypeBadType(keymap, type, "level name", "integer");
722     level = rtrn.ival - 1;
723     if (!ExprResolveString(keymap->ctx, value, &rtrn))
724     {
725         ERROR("Non-string name for level %d in key type %s\n", level + 1,
726                xkb_atom_text(keymap->ctx, type->name));
727         ACTION("Ignoring illegal level name definition\n");
728         return false;
729     }
730     level_name = xkb_atom_intern(keymap->ctx, rtrn.str);
731     free(rtrn.str);
732     return AddLevelName(keymap, type, level, level_name, true);
733 }
734
735 /***====================================================================***/
736
737 /**
738  * Parses the fields in a type "..." { } description.
739  *
740  * @param field The field to parse (e.g. modifiers, map, level_name)
741  */
742 static bool
743 SetKeyTypeField(KeyTypeInfo *type, struct xkb_keymap *keymap,
744                 char *field, ExprDef *arrayNdx, ExprDef *value,
745                 KeyTypesInfo *info)
746 {
747     ExprResult tmp;
748
749     if (strcasecmp(field, "modifiers") == 0)
750     {
751         unsigned mods, vmods;
752         if (arrayNdx != NULL)
753         {
754             WARN("The modifiers field of a key type is not an array\n");
755             ACTION("Illegal array subscript ignored\n");
756         }
757         /* get modifier mask for current type */
758         if (!ExprResolveVModMask(value, &tmp, keymap))
759         {
760             ERROR("Key type mask field must be a modifier mask\n");
761             ACTION("Key type definition ignored\n");
762             return false;
763         }
764         mods = tmp.uval & 0xff; /* core mods */
765         vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
766         if (type->defs.defined & _KT_Mask)
767         {
768             WARN("Multiple modifier mask definitions for key type %s\n",
769                   xkb_atom_text(keymap->ctx, type->name));
770             ACTION("Using %s, ", TypeMaskTxt(type, keymap));
771             INFO("ignoring %s\n", XkbcVModMaskText(keymap, mods, vmods));
772             return false;
773         }
774         type->mask = mods;
775         type->vmask = vmods;
776         type->defs.defined |= _KT_Mask;
777         return true;
778     }
779     else if (strcasecmp(field, "map") == 0)
780     {
781         type->defs.defined |= _KT_Map;
782         return SetMapEntry(type, keymap, arrayNdx, value);
783     }
784     else if (strcasecmp(field, "preserve") == 0)
785     {
786         type->defs.defined |= _KT_Preserve;
787         return SetPreserve(type, keymap, arrayNdx, value);
788     }
789     else if ((strcasecmp(field, "levelname") == 0) ||
790              (strcasecmp(field, "level_name") == 0))
791     {
792         type->defs.defined |= _KT_LevelNames;
793         return SetLevelName(type, keymap, arrayNdx, value);
794     }
795     ERROR("Unknown field %s in key type %s\n", field, TypeTxt(keymap, type));
796     ACTION("Definition ignored\n");
797     return false;
798 }
799
800 static bool
801 HandleKeyTypeVar(VarDef *stmt, struct xkb_keymap *keymap, KeyTypesInfo *info)
802 {
803     ExprResult elem, field;
804     ExprDef *arrayNdx;
805
806     if (!ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx))
807         return false;           /* internal error, already reported */
808     if (elem.str && (strcasecmp(elem.str, "type") == 0))
809         return SetKeyTypeField(&info->dflt, keymap, field.str, arrayNdx,
810                                stmt->value, info);
811     if (elem.str != NULL)
812     {
813         ERROR("Default for unknown element %s\n", uStringText(elem.str));
814         ACTION("Value for field %s ignored\n", uStringText(field.str));
815     }
816     else if (field.str != NULL)
817     {
818         ERROR("Default defined for unknown field %s\n",
819                uStringText(field.str));
820         ACTION("Ignored\n");
821     }
822     return false;
823 }
824
825 static int
826 HandleKeyTypeBody(VarDef *def, struct xkb_keymap *keymap,
827                   KeyTypeInfo *type, KeyTypesInfo *info)
828 {
829     int ok = 1;
830     ExprResult tmp, field;
831     ExprDef *arrayNdx;
832
833     for (; def != NULL; def = (VarDef *) def->common.next)
834     {
835         if ((def->name) && (def->name->type == ExprFieldRef))
836         {
837             ok = HandleKeyTypeVar(def, keymap, info);
838             continue;
839         }
840         ok = ExprResolveLhs(keymap, def->name, &tmp, &field, &arrayNdx);
841         if (ok) {
842             ok = SetKeyTypeField(type, keymap, field.str, arrayNdx,
843                                  def->value, info);
844             free(field.str);
845         }
846     }
847     return ok;
848 }
849
850 /**
851  * Process a type "XYZ" { } specification in the xkb_types section.
852  *
853  */
854 static int
855 HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
856                  unsigned merge, KeyTypesInfo *info)
857 {
858     unsigned int i;
859     KeyTypeInfo type;
860     struct xkb_kt_map_entry *entry;
861
862     if (def->merge != MergeDefault)
863         merge = def->merge;
864
865     type.defs.defined = 0;
866     type.defs.fileID = info->fileID;
867     type.defs.merge = merge;
868     type.defs.next = NULL;
869     type.name = def->name;
870     type.mask = info->dflt.mask;
871     type.vmask = info->dflt.vmask;
872     type.groupInfo = info->dflt.groupInfo;
873     type.numLevels = 1;
874     darray_init(type.entries);
875     darray_init(type.lvlNames);
876     type.preserve = NULL;
877
878     /* Parse the actual content. */
879     if (!HandleKeyTypeBody(def->body, keymap, &type, info))
880     {
881         info->errorCount++;
882         return false;
883     }
884
885     /* now copy any appropriate map, preserve or level names from the */
886     /* default type */
887     darray_foreach(entry, info->dflt.entries) {
888         if ((entry->mods.real_mods & type.mask) == entry->mods.real_mods &&
889             (entry->mods.vmods & type.vmask) == entry->mods.vmods)
890             AddMapEntry(keymap, &type, entry, false, false);
891     }
892     if (info->dflt.preserve)
893     {
894         PreserveInfo *dflt = info->dflt.preserve;
895         while (dflt)
896         {
897             if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
898                 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
899             {
900                 AddPreserve(keymap, &type, dflt, false, false);
901             }
902             dflt = (PreserveInfo *) dflt->defs.next;
903         }
904     }
905
906     for (i = 0; i < darray_size(info->dflt.lvlNames); i++) {
907         if (i < type.numLevels &&
908             darray_item(info->dflt.lvlNames, i) != XKB_ATOM_NONE)
909         {
910             AddLevelName(keymap, &type, i,
911                          darray_item(info->dflt.lvlNames, i), false);
912         }
913     }
914
915     /* Now add the new keytype to the info struct */
916     if (!AddKeyType(keymap, info, &type))
917     {
918         info->errorCount++;
919         return false;
920     }
921     return true;
922 }
923
924 /**
925  * Process an xkb_types section.
926  *
927  * @param file The parsed xkb_types section.
928  * @param merge Merge Strategy (e.g. MergeOverride)
929  * @param info Pointer to memory where the outcome will be stored.
930  */
931 static void
932 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
933                    unsigned merge, KeyTypesInfo *info)
934 {
935     ParseCommon *stmt;
936
937     free(info->name);
938     info->name = uDupString(file->name);
939     stmt = file->defs;
940     while (stmt)
941     {
942         switch (stmt->stmtType)
943         {
944         case StmtInclude:
945             if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, keymap, info))
946                 info->errorCount++;
947             break;
948         case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
949             if (!HandleKeyTypeDef((KeyTypeDef *) stmt, keymap, merge, info))
950                 info->errorCount++;
951             break;
952         case StmtVarDef:
953             if (!HandleKeyTypeVar((VarDef *) stmt, keymap, info))
954                 info->errorCount++;
955             break;
956         case StmtVModDef: /* virtual_modifiers NumLock, ... */
957             if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
958                 info->errorCount++;
959             break;
960         case StmtKeyAliasDef:
961             ERROR("Key type files may not include other declarations\n");
962             ACTION("Ignoring definition of key alias\n");
963             info->errorCount++;
964             break;
965         case StmtKeycodeDef:
966             ERROR("Key type files may not include other declarations\n");
967             ACTION("Ignoring definition of key name\n");
968             info->errorCount++;
969             break;
970         case StmtInterpDef:
971             ERROR("Key type files may not include other declarations\n");
972             ACTION("Ignoring definition of symbol interpretation\n");
973             info->errorCount++;
974             break;
975         default:
976             WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
977                   stmt->stmtType);
978             break;
979         }
980         stmt = stmt->next;
981         if (info->errorCount > 10)
982         {
983 #ifdef NOISY
984             ERROR("Too many errors\n");
985 #endif
986             ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
987             break;
988         }
989     }
990 }
991
992 static bool
993 CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
994                  KeyTypeInfo *def)
995 {
996     unsigned int i;
997     PreserveInfo *pre;
998
999     for (pre = def->preserve; pre != NULL;
1000          pre = (PreserveInfo *) pre->defs.next)
1001     {
1002         struct xkb_kt_map_entry * match;
1003         struct xkb_kt_map_entry tmp;
1004         tmp.mods.real_mods = pre->indexMods;
1005         tmp.mods.vmods = pre->indexVMods;
1006         tmp.level = 0;
1007         AddMapEntry(keymap, def, &tmp, false, false);
1008         match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1009         if (!match)
1010         {
1011             WSGO("Couldn't find matching entry for preserve\n");
1012             ACTION("Aborting\n");
1013             return false;
1014         }
1015         pre->matchingMapIndex = match - &darray_item(def->entries, 0);
1016     }
1017     type->mods.real_mods = def->mask;
1018     type->mods.vmods = def->vmask;
1019     type->num_levels = def->numLevels;
1020     memcpy(&type->map, &def->entries, sizeof(def->entries));
1021     if (def->preserve)
1022     {
1023         type->preserve = uTypedCalloc(darray_size(type->map), struct xkb_mods);
1024         if (!type->preserve)
1025         {
1026             WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1027             ACTION("Preserve setting for type %s lost\n",
1028                     xkb_atom_text(keymap->ctx, def->name));
1029         }
1030         else
1031         {
1032             pre = def->preserve;
1033             for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
1034             {
1035                 int ndx = pre->matchingMapIndex;
1036                 type->preserve[ndx].mask = pre->preMods;
1037                 type->preserve[ndx].real_mods = pre->preMods;
1038                 type->preserve[ndx].vmods = pre->preVMods;
1039             }
1040         }
1041     }
1042     else
1043         type->preserve = NULL;
1044     type->name = xkb_atom_strdup(keymap->ctx, def->name);
1045
1046     if (!darray_empty(def->lvlNames)) {
1047         type->level_names = calloc(darray_size(def->lvlNames),
1048                                    sizeof(*type->level_names));
1049
1050         /* assert def->szNames<=def->numLevels */
1051         for (i = 0; i < darray_size(def->lvlNames); i++)
1052             type->level_names[i] =
1053                 xkb_atom_strdup(keymap->ctx, darray_item(def->lvlNames, i));
1054     }
1055     else {
1056         type->level_names = NULL;
1057     }
1058
1059     darray_init(def->entries);
1060     return XkbcComputeEffectiveMap(keymap, type, NULL);
1061 }
1062
1063 bool
1064 CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
1065 {
1066     unsigned int i;
1067     struct xkb_key_type *type, *next;
1068     KeyTypesInfo info;
1069     KeyTypeInfo *def;
1070
1071     InitKeyTypesInfo(&info, keymap, NULL);
1072     info.fileID = file->id;
1073
1074     HandleKeyTypesFile(file, keymap, merge, &info);
1075
1076     if (info.errorCount != 0)
1077         goto err_info;
1078
1079     i = info.nTypes;
1080     if ((info.stdPresent & XkbOneLevelMask) == 0)
1081         i++;
1082     if ((info.stdPresent & XkbTwoLevelMask) == 0)
1083         i++;
1084     if ((info.stdPresent & XkbKeypadMask) == 0)
1085         i++;
1086     if ((info.stdPresent & XkbAlphabeticMask) == 0)
1087         i++;
1088
1089     if (XkbcAllocClientMap(keymap, XkbKeyTypesMask, i) != Success) {
1090         WSGO("Couldn't allocate client map\n");
1091         goto err_info;
1092     }
1093
1094     darray_resize0(keymap->map->types, i);
1095
1096     if (XkbAllRequiredTypes & (~info.stdPresent)) {
1097         unsigned missing, keypadVMod;
1098
1099         missing = XkbAllRequiredTypes & (~info.stdPresent);
1100         keypadVMod = FindKeypadVMod(keymap);
1101
1102         if (XkbcInitCanonicalKeyTypes(keymap, missing, keypadVMod) != Success) {
1103             WSGO("Couldn't initialize canonical key types\n");
1104             goto err_info;
1105         }
1106
1107         if (missing & XkbOneLevelMask)
1108             darray_item(keymap->map->types, XkbOneLevelIndex).name =
1109                 xkb_atom_strdup(keymap->ctx, tok_ONE_LEVEL);
1110         if (missing & XkbTwoLevelMask)
1111             darray_item(keymap->map->types, XkbTwoLevelIndex).name =
1112                 xkb_atom_strdup(keymap->ctx, tok_TWO_LEVEL);
1113         if (missing & XkbAlphabeticMask)
1114             darray_item(keymap->map->types, XkbAlphabeticIndex).name =
1115                 xkb_atom_strdup(keymap->ctx, tok_ALPHABETIC);
1116         if (missing & XkbKeypadMask)
1117             darray_item(keymap->map->types, XkbKeypadIndex).name =
1118                 xkb_atom_strdup(keymap->ctx, tok_KEYPAD);
1119     }
1120
1121     next = &darray_item(keymap->map->types, XkbLastRequiredType + 1);
1122     for (i = 0, def = info.types; i < info.nTypes; i++) {
1123         if (def->name == tok_ONE_LEVEL)
1124             type = &darray_item(keymap->map->types, XkbOneLevelIndex);
1125         else if (def->name == tok_TWO_LEVEL)
1126             type = &darray_item(keymap->map->types, XkbTwoLevelIndex);
1127         else if (def->name == tok_ALPHABETIC)
1128             type = &darray_item(keymap->map->types, XkbAlphabeticIndex);
1129         else if (def->name == tok_KEYPAD)
1130             type = &darray_item(keymap->map->types, XkbKeypadIndex);
1131         else
1132             type = next++;
1133
1134         DeleteLevel1MapEntries(def);
1135
1136         if (!CopyDefToKeyType(keymap, type, def))
1137             goto err_info;
1138
1139         def = (KeyTypeInfo *)def->defs.next;
1140     }
1141
1142     FreeKeyTypesInfo(&info);
1143     return true;
1144
1145 err_info:
1146     FreeKeyTypesInfo(&info);
1147     return false;
1148 }