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