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