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