Fix fileID mess
[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 {
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     unsigned file_id;
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     unsigned file_id;
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, unsigned file_id)
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->file_id = file_id;
114     info->dflt.defs.defined = 0;
115     info->dflt.defs.file_id = file_id;
116     info->dflt.defs.merge = MERGE_OVERRIDE;
117     info->dflt.defs.next = NULL;
118     info->dflt.name = XKB_ATOM_NONE;
119     info->dflt.mask = 0;
120     info->dflt.vmask = 0;
121     info->dflt.groupInfo = false;
122     info->dflt.numLevels = 1;
123     darray_init(info->dflt.entries);
124     darray_init(info->dflt.lvlNames);
125     info->dflt.preserve = NULL;
126     InitVModInfo(&info->vmods, keymap);
127     if (from != NULL)
128     {
129         info->dflt = from->dflt;
130
131         darray_copy(info->dflt.entries, from->dflt.entries);
132         darray_copy(info->dflt.lvlNames, from->dflt.lvlNames);
133
134         if (from->dflt.preserve)
135         {
136             PreserveInfo *old, *new, *last;
137             last = NULL;
138             old = from->dflt.preserve;
139             for (; old; old = (PreserveInfo *) old->defs.next)
140             {
141                 new = uTypedAlloc(PreserveInfo);
142                 if (!new)
143                     return;
144                 *new = *old;
145                 new->defs.next = NULL;
146                 if (last)
147                     last->defs.next = (CommonInfo *) new;
148                 else
149                     info->dflt.preserve = new;
150                 last = new;
151             }
152         }
153     }
154 }
155
156 static void
157 FreeKeyTypeInfo(KeyTypeInfo * type)
158 {
159     darray_free(type->entries);
160     darray_free(type->lvlNames);
161     if (type->preserve != NULL)
162     {
163         ClearCommonInfo(&type->preserve->defs);
164         type->preserve = NULL;
165     }
166 }
167
168 static void
169 FreeKeyTypesInfo(KeyTypesInfo * info)
170 {
171     free(info->name);
172     info->name = NULL;
173     if (info->types)
174     {
175         KeyTypeInfo *type;
176         for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
177         {
178             FreeKeyTypeInfo(type);
179         }
180         info->types = ClearCommonInfo(&info->types->defs);
181     }
182     FreeKeyTypeInfo(&info->dflt);
183 }
184
185 static KeyTypeInfo *
186 NextKeyType(KeyTypesInfo * info)
187 {
188     KeyTypeInfo *type;
189
190     type = uTypedAlloc(KeyTypeInfo);
191     if (type != NULL)
192     {
193         memset(type, 0, sizeof(KeyTypeInfo));
194         type->defs.file_id = info->file_id;
195         info->types = AddCommonInfo(&info->types->defs, &type->defs);
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 == MERGE_REPLACE)
263             || (new->defs.merge == MERGE_OVERRIDE))
264         {
265             KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
266             if (((old->defs.file_id == new->defs.file_id)
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.file_id == new->defs.file_id) && (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                       enum merge_mode 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 != MERGE_DEFAULT)
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                    enum merge_mode 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, FILE_TYPE_TYPES, &rtrn,
351                                 &newMerge))
352     {
353         InitKeyTypesInfo(&included, keymap, info, rtrn->id);
354         included.dflt.defs.merge = newMerge;
355
356         HandleKeyTypesFile(rtrn, keymap, newMerge, &included);
357         if (stmt->stmt != NULL)
358         {
359             free(included.name);
360             included.name = stmt->stmt;
361             stmt->stmt = NULL;
362         }
363         FreeXKBFile(rtrn);
364     }
365     else
366     {
367         info->errorCount += 10;
368         return false;
369     }
370     if ((stmt->next != NULL) && (included.errorCount < 1))
371     {
372         IncludeStmt *next;
373         unsigned op;
374         KeyTypesInfo next_incl;
375
376         for (next = stmt->next; next != NULL; next = next->next)
377         {
378             if ((next->file == NULL) && (next->map == NULL))
379             {
380                 haveSelf = true;
381                 MergeIncludedKeyTypes(&included, info, next->merge, keymap);
382                 FreeKeyTypesInfo(info);
383             }
384             else if (ProcessIncludeFile(keymap->ctx, next, FILE_TYPE_TYPES,
385                                         &rtrn, &op))
386             {
387                 InitKeyTypesInfo(&next_incl, keymap, &included, rtrn->id);
388                 next_incl.dflt.defs.merge = op;
389                 HandleKeyTypesFile(rtrn, keymap, op, &next_incl);
390                 MergeIncludedKeyTypes(&included, &next_incl, op, keymap);
391                 FreeKeyTypesInfo(&next_incl);
392                 FreeXKBFile(rtrn);
393             }
394             else
395             {
396                 info->errorCount += 10;
397                 FreeKeyTypesInfo(&included);
398                 return false;
399             }
400         }
401     }
402     if (haveSelf)
403         *info = included;
404     else
405     {
406         MergeIncludedKeyTypes(info, &included, newMerge, keymap);
407         FreeKeyTypesInfo(&included);
408     }
409     return (info->errorCount == 0);
410 }
411
412 /***====================================================================***/
413
414 static struct xkb_kt_map_entry *
415 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
416 {
417     struct xkb_kt_map_entry *entry;
418
419     darray_foreach(entry, type->entries)
420         if (entry->mods.real_mods == mask && entry->mods.vmods == vmask)
421             return entry;
422
423     return NULL;
424 }
425
426 static void
427 DeleteLevel1MapEntries(KeyTypeInfo * type)
428 {
429     unsigned int i, n;
430
431     /* TODO: Be just a bit more clever here. */
432     for (i = 0; i < darray_size(type->entries); i++) {
433         if (darray_item(type->entries, i).level == 0) {
434             for (n = i; n < darray_size(type->entries) - 1; n++)
435                 darray_item(type->entries, n) =
436                     darray_item(type->entries, n + 1);
437             (void)darray_pop(type->entries);
438         }
439     }
440 }
441
442 static struct xkb_kt_map_entry *
443 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
444 {
445     darray_resize0(type->entries, darray_size(type->entries) + 1);
446     return &darray_item(type->entries, darray_size(type->entries) - 1);
447 }
448
449 static bool
450 AddPreserve(struct xkb_keymap *keymap, KeyTypeInfo *type,
451             PreserveInfo *new, bool clobber, bool report)
452 {
453     PreserveInfo *old;
454
455     old = type->preserve;
456     while (old != NULL)
457     {
458         if ((old->indexMods != new->indexMods) ||
459             (old->indexVMods != new->indexVMods))
460         {
461             old = (PreserveInfo *) old->defs.next;
462             continue;
463         }
464         if ((old->preMods == new->preMods)
465             && (old->preVMods == new->preVMods))
466         {
467             if (warningLevel > 9)
468             {
469                 WARN("Identical definitions for preserve[%s] in %s\n",
470                       PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
471                 ACTION("Ignored\n");
472             }
473             return true;
474         }
475         if (report && (warningLevel > 0))
476         {
477             const char *str;
478             WARN("Multiple definitions for preserve[%s] in %s\n",
479                   PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
480
481             if (clobber)
482                 str = PreserveTxt(keymap, new);
483             else
484                 str = PreserveTxt(keymap, old);
485             ACTION("Using %s, ", str);
486             if (clobber)
487                 str = PreserveTxt(keymap, old);
488             else
489                 str = PreserveTxt(keymap, new);
490             INFO("ignoring %s\n", str);
491         }
492         if (clobber)
493         {
494             old->preMods = new->preMods;
495             old->preVMods = new->preVMods;
496         }
497         return true;
498     }
499     old = uTypedAlloc(PreserveInfo);
500     if (!old)
501     {
502         WSGO("Couldn't allocate preserve in %s\n", TypeTxt(keymap, type));
503         ACTION("Preserve[%s] lost\n", PreserveIndexTxt(keymap, new));
504         return false;
505     }
506     *old = *new;
507     old->matchingMapIndex = -1;
508     type->preserve = AddCommonInfo(&type->preserve->defs, &old->defs);
509     return true;
510 }
511
512 /**
513  * Add a new KTMapEntry to the given key type. If an entry with the same mods
514  * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
515  * entry is created.
516  *
517  * @param clobber Overwrite existing entry.
518  * @param report true if a warning is to be printed on.
519  */
520 static bool
521 AddMapEntry(struct xkb_keymap *keymap, KeyTypeInfo *type,
522             struct xkb_kt_map_entry *new, bool clobber, bool report)
523 {
524     struct xkb_kt_map_entry * old;
525
526     if ((old =
527          FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
528     {
529         if (report && (old->level != new->level))
530         {
531             unsigned use, ignore;
532             if (clobber)
533             {
534                 use = new->level + 1;
535                 ignore = old->level + 1;
536             }
537             else
538             {
539                 use = old->level + 1;
540                 ignore = new->level + 1;
541             }
542             WARN("Multiple map entries for %s in %s\n",
543                   MapEntryTxt(keymap, new), TypeTxt(keymap, type));
544             ACTION("Using %d, ignoring %d\n", use, ignore);
545         }
546         else if (warningLevel > 9)
547         {
548             WARN("Multiple occurences of map[%s]= %d in %s\n",
549                   MapEntryTxt(keymap, new), new->level + 1,
550                   TypeTxt(keymap, type));
551             ACTION("Ignored\n");
552             return true;
553         }
554         if (clobber)
555             old->level = new->level;
556         return true;
557     }
558     if ((old = NextMapEntry(keymap, type)) == NULL)
559         return false;           /* allocation failure, already reported */
560     if (new->level >= type->numLevels)
561         type->numLevels = new->level + 1;
562     old->mods.mask = new->mods.real_mods;
563     old->mods.real_mods = new->mods.real_mods;
564     old->mods.vmods = new->mods.vmods;
565     old->level = new->level;
566     return true;
567 }
568
569 static bool
570 SetMapEntry(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
571             ExprDef *value)
572 {
573     ExprResult rtrn;
574     struct xkb_kt_map_entry entry;
575
576     if (arrayNdx == NULL)
577         return ReportTypeShouldBeArray(keymap, type, "map entry");
578     if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
579         return ReportTypeBadType(keymap, type, "map entry", "modifier mask");
580     entry.mods.real_mods = rtrn.uval & 0xff;      /* modifiers < 512 */
581     entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
582     if ((entry.mods.real_mods & (~type->mask)) ||
583         ((entry.mods.vmods & (~type->vmask)) != 0))
584     {
585         if (warningLevel > 0)
586         {
587             WARN("Map entry for unused modifiers in %s\n", TypeTxt(keymap, type));
588             ACTION("Using %s instead of ",
589                     XkbcVModMaskText(keymap,
590                                     entry.mods.real_mods & type->mask,
591                                     entry.mods.vmods & type->vmask));
592             INFO("%s\n", MapEntryTxt(keymap, &entry));
593         }
594         entry.mods.real_mods &= type->mask;
595         entry.mods.vmods &= type->vmask;
596     }
597     if (!ExprResolveLevel(keymap->ctx, value, &rtrn))
598     {
599         ERROR("Level specifications in a key type must be integer\n");
600         ACTION("Ignoring malformed level specification\n");
601         return false;
602     }
603     entry.level = rtrn.ival - 1;
604     return AddMapEntry(keymap, type, &entry, true, true);
605 }
606
607 static bool
608 SetPreserve(KeyTypeInfo *type, struct xkb_keymap *keymap,
609             ExprDef *arrayNdx, ExprDef *value)
610 {
611     ExprResult rtrn;
612     PreserveInfo new;
613
614     if (arrayNdx == NULL)
615         return ReportTypeShouldBeArray(keymap, type, "preserve entry");
616     if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
617         return ReportTypeBadType(keymap, type, "preserve entry",
618                                  "modifier mask");
619     new.defs = type->defs;
620     new.defs.next = NULL;
621     new.indexMods = rtrn.uval & 0xff;
622     new.indexVMods = (rtrn.uval >> 8) & 0xffff;
623     if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
624     {
625         if (warningLevel > 0)
626         {
627             WARN("Preserve for modifiers not used by the %s type\n",
628                   TypeTxt(keymap, type));
629             ACTION("Index %s converted to ", PreserveIndexTxt(keymap, &new));
630         }
631         new.indexMods &= type->mask;
632         new.indexVMods &= type->vmask;
633         if (warningLevel > 0)
634             INFO("%s\n", PreserveIndexTxt(keymap, &new));
635     }
636     if (!ExprResolveVModMask(value, &rtrn, keymap))
637     {
638         ERROR("Preserve value in a key type is not a modifier mask\n");
639         ACTION("Ignoring preserve[%s] in type %s\n",
640                 PreserveIndexTxt(keymap, &new), TypeTxt(keymap, type));
641         return false;
642     }
643     new.preMods = rtrn.uval & 0xff;
644     new.preVMods = (rtrn.uval >> 16) & 0xffff;
645     if ((new.preMods & (~new.indexMods))
646         || (new.preVMods & (~new.indexVMods)))
647     {
648         if (warningLevel > 0)
649         {
650             WARN("Illegal value for preserve[%s] in type %s\n",
651                   PreserveTxt(keymap, &new), TypeTxt(keymap, type));
652             ACTION("Converted %s to ", PreserveIndexTxt(keymap, &new));
653         }
654         new.preMods &= new.indexMods;
655         new.preVMods &= new.indexVMods;
656         if (warningLevel > 0)
657         {
658             INFO("%s\n", PreserveIndexTxt(keymap, &new));
659         }
660     }
661     return AddPreserve(keymap, type, &new, true, true);
662 }
663
664 /***====================================================================***/
665
666 static bool
667 AddLevelName(struct xkb_keymap *keymap, KeyTypeInfo *type,
668              unsigned level, xkb_atom_t name, bool clobber)
669 {
670     if (level >= darray_size(type->lvlNames))
671         darray_resize0(type->lvlNames, level + 1);
672
673     if (darray_item(type->lvlNames, level) == name) {
674         if (warningLevel > 9) {
675             WARN("Duplicate names for level %d of key type %s\n",
676                  level + 1, TypeTxt(keymap, type));
677             ACTION("Ignored\n");
678         }
679         return true;
680     }
681     else if (darray_item(type->lvlNames, level) != XKB_ATOM_NONE) {
682         if (warningLevel > 0) {
683             const char *old, *new;
684             old = xkb_atom_text(keymap->ctx,
685                                 darray_item(type->lvlNames, level));
686             new = xkb_atom_text(keymap->ctx, name);
687             WARN("Multiple names for level %d of key type %s\n",
688                  level + 1, TypeTxt(keymap, type));
689             if (clobber)
690                 ACTION("Using %s, ignoring %s\n", new, old);
691             else
692                 ACTION("Using %s, ignoring %s\n", old, new);
693         }
694
695         if (!clobber)
696             return true;
697     }
698
699     darray_item(type->lvlNames, level) = name;
700     return true;
701 }
702
703 static bool
704 SetLevelName(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
705              ExprDef *value)
706 {
707     ExprResult rtrn;
708     unsigned level;
709     xkb_atom_t level_name;
710
711     if (arrayNdx == NULL)
712         return ReportTypeShouldBeArray(keymap, type, "level name");
713     if (!ExprResolveLevel(keymap->ctx, arrayNdx, &rtrn))
714         return ReportTypeBadType(keymap, type, "level name", "integer");
715     level = rtrn.ival - 1;
716     if (!ExprResolveString(keymap->ctx, value, &rtrn))
717     {
718         ERROR("Non-string name for level %d in key type %s\n", level + 1,
719                xkb_atom_text(keymap->ctx, type->name));
720         ACTION("Ignoring illegal level name definition\n");
721         return false;
722     }
723     level_name = xkb_atom_intern(keymap->ctx, rtrn.str);
724     free(rtrn.str);
725     return AddLevelName(keymap, type, level, level_name, true);
726 }
727
728 /***====================================================================***/
729
730 /**
731  * Parses the fields in a type "..." { } description.
732  *
733  * @param field The field to parse (e.g. modifiers, map, level_name)
734  */
735 static bool
736 SetKeyTypeField(KeyTypeInfo *type, struct xkb_keymap *keymap,
737                 char *field, ExprDef *arrayNdx, ExprDef *value,
738                 KeyTypesInfo *info)
739 {
740     ExprResult tmp;
741
742     if (strcasecmp(field, "modifiers") == 0)
743     {
744         unsigned mods, vmods;
745         if (arrayNdx != NULL)
746         {
747             WARN("The modifiers field of a key type is not an array\n");
748             ACTION("Illegal array subscript ignored\n");
749         }
750         /* get modifier mask for current type */
751         if (!ExprResolveVModMask(value, &tmp, keymap))
752         {
753             ERROR("Key type mask field must be a modifier mask\n");
754             ACTION("Key type definition ignored\n");
755             return false;
756         }
757         mods = tmp.uval & 0xff; /* core mods */
758         vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
759         if (type->defs.defined & _KT_Mask)
760         {
761             WARN("Multiple modifier mask definitions for key type %s\n",
762                   xkb_atom_text(keymap->ctx, type->name));
763             ACTION("Using %s, ", TypeMaskTxt(type, keymap));
764             INFO("ignoring %s\n", XkbcVModMaskText(keymap, mods, vmods));
765             return false;
766         }
767         type->mask = mods;
768         type->vmask = vmods;
769         type->defs.defined |= _KT_Mask;
770         return true;
771     }
772     else if (strcasecmp(field, "map") == 0)
773     {
774         type->defs.defined |= _KT_Map;
775         return SetMapEntry(type, keymap, arrayNdx, value);
776     }
777     else if (strcasecmp(field, "preserve") == 0)
778     {
779         type->defs.defined |= _KT_Preserve;
780         return SetPreserve(type, keymap, arrayNdx, value);
781     }
782     else if ((strcasecmp(field, "levelname") == 0) ||
783              (strcasecmp(field, "level_name") == 0))
784     {
785         type->defs.defined |= _KT_LevelNames;
786         return SetLevelName(type, keymap, arrayNdx, value);
787     }
788     ERROR("Unknown field %s in key type %s\n", field, TypeTxt(keymap, type));
789     ACTION("Definition ignored\n");
790     return false;
791 }
792
793 static bool
794 HandleKeyTypeVar(VarDef *stmt, struct xkb_keymap *keymap, KeyTypesInfo *info)
795 {
796     ExprResult elem, field;
797     ExprDef *arrayNdx;
798
799     if (!ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx))
800         return false;           /* internal error, already reported */
801     if (elem.str && (strcasecmp(elem.str, "type") == 0))
802         return SetKeyTypeField(&info->dflt, keymap, field.str, arrayNdx,
803                                stmt->value, info);
804     if (elem.str != NULL)
805     {
806         ERROR("Default for unknown element %s\n", uStringText(elem.str));
807         ACTION("Value for field %s ignored\n", uStringText(field.str));
808     }
809     else if (field.str != NULL)
810     {
811         ERROR("Default defined for unknown field %s\n",
812                uStringText(field.str));
813         ACTION("Ignored\n");
814     }
815     return false;
816 }
817
818 static int
819 HandleKeyTypeBody(VarDef *def, struct xkb_keymap *keymap,
820                   KeyTypeInfo *type, KeyTypesInfo *info)
821 {
822     int ok = 1;
823     ExprResult tmp, field;
824     ExprDef *arrayNdx;
825
826     for (; def != NULL; def = (VarDef *) def->common.next)
827     {
828         if ((def->name) && (def->name->type == ExprFieldRef))
829         {
830             ok = HandleKeyTypeVar(def, keymap, info);
831             continue;
832         }
833         ok = ExprResolveLhs(keymap, def->name, &tmp, &field, &arrayNdx);
834         if (ok) {
835             ok = SetKeyTypeField(type, keymap, field.str, arrayNdx,
836                                  def->value, info);
837             free(field.str);
838         }
839     }
840     return ok;
841 }
842
843 /**
844  * Process a type "XYZ" { } specification in the xkb_types section.
845  *
846  */
847 static int
848 HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
849                  enum merge_mode merge, KeyTypesInfo *info)
850 {
851     unsigned int i;
852     KeyTypeInfo type;
853     struct xkb_kt_map_entry *entry;
854
855     if (def->merge != MERGE_DEFAULT)
856         merge = def->merge;
857
858     type.defs.defined = 0;
859     type.defs.file_id = info->file_id;
860     type.defs.merge = merge;
861     type.defs.next = NULL;
862     type.name = def->name;
863     type.mask = info->dflt.mask;
864     type.vmask = info->dflt.vmask;
865     type.groupInfo = info->dflt.groupInfo;
866     type.numLevels = 1;
867     darray_init(type.entries);
868     darray_init(type.lvlNames);
869     type.preserve = NULL;
870
871     /* Parse the actual content. */
872     if (!HandleKeyTypeBody(def->body, keymap, &type, info))
873     {
874         info->errorCount++;
875         return false;
876     }
877
878     /* now copy any appropriate map, preserve or level names from the */
879     /* default type */
880     darray_foreach(entry, info->dflt.entries) {
881         if ((entry->mods.real_mods & type.mask) == entry->mods.real_mods &&
882             (entry->mods.vmods & type.vmask) == entry->mods.vmods)
883             AddMapEntry(keymap, &type, entry, false, false);
884     }
885     if (info->dflt.preserve)
886     {
887         PreserveInfo *dflt = info->dflt.preserve;
888         while (dflt)
889         {
890             if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
891                 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
892             {
893                 AddPreserve(keymap, &type, dflt, false, false);
894             }
895             dflt = (PreserveInfo *) dflt->defs.next;
896         }
897     }
898
899     for (i = 0; i < darray_size(info->dflt.lvlNames); i++) {
900         if (i < type.numLevels &&
901             darray_item(info->dflt.lvlNames, i) != XKB_ATOM_NONE)
902         {
903             AddLevelName(keymap, &type, i,
904                          darray_item(info->dflt.lvlNames, i), false);
905         }
906     }
907
908     /* Now add the new keytype to the info struct */
909     if (!AddKeyType(keymap, info, &type))
910     {
911         info->errorCount++;
912         return false;
913     }
914     return true;
915 }
916
917 /**
918  * Process an xkb_types section.
919  *
920  * @param file The parsed xkb_types section.
921  * @param merge Merge Strategy (e.g. MERGE_OVERRIDE)
922  * @param info Pointer to memory where the outcome will be stored.
923  */
924 static void
925 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
926                    enum merge_mode merge, KeyTypesInfo *info)
927 {
928     ParseCommon *stmt;
929
930     free(info->name);
931     info->name = uDupString(file->name);
932     stmt = file->defs;
933     while (stmt)
934     {
935         switch (stmt->stmtType)
936         {
937         case StmtInclude:
938             if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, keymap, info))
939                 info->errorCount++;
940             break;
941         case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
942             if (!HandleKeyTypeDef((KeyTypeDef *) stmt, keymap, merge, info))
943                 info->errorCount++;
944             break;
945         case StmtVarDef:
946             if (!HandleKeyTypeVar((VarDef *) stmt, keymap, info))
947                 info->errorCount++;
948             break;
949         case StmtVModDef: /* virtual_modifiers NumLock, ... */
950             if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
951                 info->errorCount++;
952             break;
953         case StmtKeyAliasDef:
954             ERROR("Key type files may not include other declarations\n");
955             ACTION("Ignoring definition of key alias\n");
956             info->errorCount++;
957             break;
958         case StmtKeycodeDef:
959             ERROR("Key type files may not include other declarations\n");
960             ACTION("Ignoring definition of key name\n");
961             info->errorCount++;
962             break;
963         case StmtInterpDef:
964             ERROR("Key type files may not include other declarations\n");
965             ACTION("Ignoring definition of symbol interpretation\n");
966             info->errorCount++;
967             break;
968         default:
969             WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
970                   stmt->stmtType);
971             break;
972         }
973         stmt = stmt->next;
974         if (info->errorCount > 10)
975         {
976 #ifdef NOISY
977             ERROR("Too many errors\n");
978 #endif
979             ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
980             break;
981         }
982     }
983 }
984
985 static bool
986 ComputeEffectiveMap(struct xkb_keymap *keymap, struct xkb_key_type *type)
987 {
988     uint32_t tmp;
989     struct xkb_kt_map_entry *entry = NULL;
990
991     if (type->mods.vmods != 0) {
992         tmp = VModsToReal(keymap, type->mods.vmods);
993         type->mods.mask = tmp | type->mods.real_mods;
994         darray_foreach(entry, type->map) {
995             tmp = 0;
996             if (entry->mods.vmods != 0) {
997                 tmp = VModsToReal(keymap, entry->mods.vmods);
998                 if (tmp == 0)
999                     continue;
1000             }
1001             entry->mods.mask = (entry->mods.real_mods | tmp) & type->mods.mask;
1002         }
1003     }
1004     else
1005         type->mods.mask = type->mods.real_mods;
1006
1007     return true;
1008 }
1009
1010 static bool
1011 CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
1012                  KeyTypeInfo *def)
1013 {
1014     unsigned int i;
1015     PreserveInfo *pre;
1016
1017     for (pre = def->preserve; pre != NULL;
1018          pre = (PreserveInfo *) pre->defs.next)
1019     {
1020         struct xkb_kt_map_entry * match;
1021         struct xkb_kt_map_entry tmp;
1022         tmp.mods.real_mods = pre->indexMods;
1023         tmp.mods.vmods = pre->indexVMods;
1024         tmp.level = 0;
1025         AddMapEntry(keymap, def, &tmp, false, false);
1026         match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1027         if (!match)
1028         {
1029             WSGO("Couldn't find matching entry for preserve\n");
1030             ACTION("Aborting\n");
1031             return false;
1032         }
1033         pre->matchingMapIndex = match - &darray_item(def->entries, 0);
1034     }
1035     type->mods.real_mods = def->mask;
1036     type->mods.vmods = def->vmask;
1037     type->num_levels = def->numLevels;
1038     memcpy(&type->map, &def->entries, sizeof(def->entries));
1039     if (def->preserve)
1040     {
1041         type->preserve = uTypedCalloc(darray_size(type->map), struct xkb_mods);
1042         if (!type->preserve)
1043         {
1044             WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1045             ACTION("Preserve setting for type %s lost\n",
1046                     xkb_atom_text(keymap->ctx, def->name));
1047         }
1048         else
1049         {
1050             pre = def->preserve;
1051             for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
1052             {
1053                 int ndx = pre->matchingMapIndex;
1054                 type->preserve[ndx].mask = pre->preMods;
1055                 type->preserve[ndx].real_mods = pre->preMods;
1056                 type->preserve[ndx].vmods = pre->preVMods;
1057             }
1058         }
1059     }
1060     else
1061         type->preserve = NULL;
1062     type->name = xkb_atom_strdup(keymap->ctx, def->name);
1063
1064     if (!darray_empty(def->lvlNames)) {
1065         type->level_names = calloc(darray_size(def->lvlNames),
1066                                    sizeof(*type->level_names));
1067
1068         /* assert def->szNames<=def->numLevels */
1069         for (i = 0; i < darray_size(def->lvlNames); i++)
1070             type->level_names[i] =
1071                 xkb_atom_strdup(keymap->ctx, darray_item(def->lvlNames, i));
1072     }
1073     else {
1074         type->level_names = NULL;
1075     }
1076
1077     darray_init(def->entries);
1078     return ComputeEffectiveMap(keymap, type);
1079 }
1080
1081 static struct xkb_kt_map_entry map2Level[]= {
1082     {
1083         .level = ShiftMask,
1084         .mods = {.mask = 1, .vmods = ShiftMask, .real_mods = 0 }
1085     }
1086 };
1087
1088 static struct xkb_kt_map_entry mapAlpha[]= {
1089     {
1090         .level = ShiftMask,
1091         .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
1092     },
1093     {
1094         .level = LockMask,
1095         .mods = { .mask = 0, .vmods = LockMask,  .real_mods = 0 }
1096     }
1097 };
1098
1099 static struct xkb_mods preAlpha[]= {
1100     { .mask = 0,        .vmods = 0,        .real_mods = 0 },
1101     { .mask = LockMask, .vmods = LockMask, .real_mods = 0 }
1102 };
1103
1104 static struct xkb_kt_map_entry mapKeypad[]= {
1105     {
1106         .level = ShiftMask,
1107         .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
1108     },
1109     {
1110         .level = 0,
1111         .mods = { .mask = 1, .vmods = 0, .real_mods = 0 }
1112     }
1113 };
1114
1115 static const struct xkb_key_type canonicalTypes[XkbNumRequiredTypes] = {
1116     {
1117         .mods = { .mask = 0, .vmods = 0, .real_mods = 0 },
1118         .num_levels = 1,
1119         .preserve = NULL,
1120         .name = NULL,
1121         .level_names = NULL
1122     },
1123     {
1124         .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = 0 },
1125         .num_levels = 2,
1126         .map = darray_lit(map2Level),
1127         .preserve = NULL,
1128         .name = NULL,
1129         .level_names = NULL
1130     },
1131     {
1132         .mods = {
1133             .mask = ShiftMask|LockMask,
1134             .vmods = ShiftMask|LockMask,
1135             .real_mods = 0
1136         },
1137         .num_levels = 2,
1138         .map = darray_lit(mapAlpha),
1139         .preserve = preAlpha,
1140         .name = NULL,
1141         .level_names = NULL
1142     },
1143     {
1144         .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = 0 },
1145         .num_levels = 2,
1146         .map = darray_lit(mapKeypad),
1147         .preserve = NULL,
1148         .name = NULL,
1149         .level_names = NULL
1150     }
1151 };
1152
1153 static int
1154 InitCanonicalKeyTypes(struct xkb_keymap *keymap, unsigned which, int keypadVMod)
1155 {
1156     struct xkb_client_map *map;
1157     const struct xkb_key_type *from;
1158     int rtrn;
1159
1160     rtrn = XkbcAllocClientMap(keymap, XkbKeyTypesMask, XkbNumRequiredTypes);
1161     if (rtrn != Success)
1162         return rtrn;
1163
1164     map = keymap->map;
1165     if ((which & XkbAllRequiredTypes) == 0)
1166         return Success;
1167
1168     rtrn = Success;
1169     from = canonicalTypes;
1170
1171     if (which & XkbOneLevelMask)
1172         rtrn = XkbcCopyKeyType(&from[XkbOneLevelIndex],
1173                                &darray_item(map->types, XkbOneLevelIndex));
1174
1175     if ((which & XkbTwoLevelMask) && rtrn == Success)
1176         rtrn = XkbcCopyKeyType(&from[XkbTwoLevelIndex],
1177                                &darray_item(map->types, XkbTwoLevelIndex));
1178
1179     if ((which & XkbAlphabeticMask) && rtrn == Success)
1180         rtrn = XkbcCopyKeyType(&from[XkbAlphabeticIndex],
1181                                &darray_item(map->types, XkbAlphabeticIndex));
1182
1183     if ((which & XkbKeypadMask) && rtrn == Success) {
1184         struct xkb_key_type *type;
1185
1186         rtrn = XkbcCopyKeyType(&from[XkbKeypadIndex],
1187                                &darray_item(map->types, XkbKeypadIndex));
1188         type = &darray_item(map->types, XkbKeypadIndex);
1189
1190         if (keypadVMod >= 0 && keypadVMod < XkbNumVirtualMods &&
1191             rtrn == Success) {
1192             struct xkb_kt_map_entry *entry;
1193             type->mods.vmods = (1 << keypadVMod);
1194
1195             entry = &darray_item(type->map, 0);
1196             entry->mods.mask = ShiftMask;
1197             entry->mods.real_mods = ShiftMask;
1198             entry->mods.vmods = 0;
1199             entry->level = 1;
1200
1201             entry = &darray_item(type->map, 1);
1202             entry->mods.mask = 0;
1203             entry->mods.real_mods = 0;
1204             entry->mods.vmods = (1 << keypadVMod);
1205             entry->level = 1;
1206         }
1207     }
1208
1209     return Success;
1210 }
1211
1212 bool
1213 CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
1214 {
1215     unsigned int i;
1216     struct xkb_key_type *type, *next;
1217     KeyTypesInfo info;
1218     KeyTypeInfo *def;
1219
1220     InitKeyTypesInfo(&info, keymap, NULL, file->id);
1221
1222     HandleKeyTypesFile(file, keymap, merge, &info);
1223
1224     if (info.errorCount != 0)
1225         goto err_info;
1226
1227     if (info.name) {
1228         if (XkbcAllocNames(keymap, 0, 0) != Success)
1229             goto err_info;
1230         keymap->names->keytypes = strdup(info.name);
1231     }
1232
1233     i = info.nTypes;
1234     if ((info.stdPresent & XkbOneLevelMask) == 0)
1235         i++;
1236     if ((info.stdPresent & XkbTwoLevelMask) == 0)
1237         i++;
1238     if ((info.stdPresent & XkbKeypadMask) == 0)
1239         i++;
1240     if ((info.stdPresent & XkbAlphabeticMask) == 0)
1241         i++;
1242
1243     if (XkbcAllocClientMap(keymap, XkbKeyTypesMask, i) != Success) {
1244         WSGO("Couldn't allocate client map\n");
1245         goto err_info;
1246     }
1247
1248     darray_resize0(keymap->map->types, i);
1249
1250     if (XkbAllRequiredTypes & (~info.stdPresent)) {
1251         unsigned missing, keypadVMod;
1252
1253         missing = XkbAllRequiredTypes & (~info.stdPresent);
1254         keypadVMod = FindKeypadVMod(keymap);
1255
1256         if (InitCanonicalKeyTypes(keymap, missing, keypadVMod) != Success) {
1257             WSGO("Couldn't initialize canonical key types\n");
1258             goto err_info;
1259         }
1260
1261         if (missing & XkbOneLevelMask)
1262             darray_item(keymap->map->types, XkbOneLevelIndex).name =
1263                 xkb_atom_strdup(keymap->ctx, tok_ONE_LEVEL);
1264         if (missing & XkbTwoLevelMask)
1265             darray_item(keymap->map->types, XkbTwoLevelIndex).name =
1266                 xkb_atom_strdup(keymap->ctx, tok_TWO_LEVEL);
1267         if (missing & XkbAlphabeticMask)
1268             darray_item(keymap->map->types, XkbAlphabeticIndex).name =
1269                 xkb_atom_strdup(keymap->ctx, tok_ALPHABETIC);
1270         if (missing & XkbKeypadMask)
1271             darray_item(keymap->map->types, XkbKeypadIndex).name =
1272                 xkb_atom_strdup(keymap->ctx, tok_KEYPAD);
1273     }
1274
1275     next = &darray_item(keymap->map->types, XkbLastRequiredType + 1);
1276     for (i = 0, def = info.types; i < info.nTypes; i++) {
1277         if (def->name == tok_ONE_LEVEL)
1278             type = &darray_item(keymap->map->types, XkbOneLevelIndex);
1279         else if (def->name == tok_TWO_LEVEL)
1280             type = &darray_item(keymap->map->types, XkbTwoLevelIndex);
1281         else if (def->name == tok_ALPHABETIC)
1282             type = &darray_item(keymap->map->types, XkbAlphabeticIndex);
1283         else if (def->name == tok_KEYPAD)
1284             type = &darray_item(keymap->map->types, XkbKeypadIndex);
1285         else
1286             type = next++;
1287
1288         DeleteLevel1MapEntries(def);
1289
1290         if (!CopyDefToKeyType(keymap, type, def))
1291             goto err_info;
1292
1293         def = (KeyTypeInfo *)def->defs.next;
1294     }
1295
1296     FreeKeyTypesInfo(&info);
1297     return true;
1298
1299 err_info:
1300     FreeKeyTypesInfo(&info);
1301     return false;
1302 }