Make the context available for XkbcAtomText
[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)->context, (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->context, "ONE_LEVEL");
108     tok_TWO_LEVEL = xkb_atom_intern(keymap->context, "TWO_LEVEL");
109     tok_ALPHABETIC = xkb_atom_intern(keymap->context, "ALPHABETIC");
110     tok_KEYPAD = xkb_atom_intern(keymap->context, "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->context, 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->context, 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 typedef void (*FileHandler) (XkbFile *file, struct xkb_keymap *keymap,
356                              unsigned merge, KeyTypesInfo *included);
357
358 static bool
359 HandleIncludeKeyTypes(IncludeStmt *stmt, struct xkb_keymap *keymap,
360                       KeyTypesInfo *info, FileHandler hndlr)
361 {
362     unsigned newMerge;
363     XkbFile *rtrn;
364     KeyTypesInfo included;
365     bool haveSelf;
366
367     haveSelf = false;
368     if ((stmt->file == NULL) && (stmt->map == NULL))
369     {
370         haveSelf = true;
371         included = *info;
372         memset(info, 0, sizeof(KeyTypesInfo));
373     }
374     else if (ProcessIncludeFile(keymap->context, stmt, XkmTypesIndex, &rtrn,
375                                 &newMerge))
376     {
377         InitKeyTypesInfo(&included, keymap, info);
378         included.fileID = included.dflt.defs.fileID = rtrn->id;
379         included.dflt.defs.merge = newMerge;
380
381         (*hndlr) (rtrn, keymap, newMerge, &included);
382         if (stmt->stmt != NULL)
383         {
384             free(included.name);
385             included.name = stmt->stmt;
386             stmt->stmt = NULL;
387         }
388         FreeXKBFile(rtrn);
389     }
390     else
391     {
392         info->errorCount += 10;
393         return false;
394     }
395     if ((stmt->next != NULL) && (included.errorCount < 1))
396     {
397         IncludeStmt *next;
398         unsigned op;
399         KeyTypesInfo next_incl;
400
401         for (next = stmt->next; next != NULL; next = next->next)
402         {
403             if ((next->file == NULL) && (next->map == NULL))
404             {
405                 haveSelf = true;
406                 MergeIncludedKeyTypes(&included, info, next->merge, keymap);
407                 FreeKeyTypesInfo(info);
408             }
409             else if (ProcessIncludeFile(keymap->context, next, XkmTypesIndex,
410                                         &rtrn, &op))
411             {
412                 InitKeyTypesInfo(&next_incl, keymap, &included);
413                 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
414                 next_incl.dflt.defs.merge = op;
415                 (*hndlr) (rtrn, keymap, op, &next_incl);
416                 MergeIncludedKeyTypes(&included, &next_incl, op, keymap);
417                 FreeKeyTypesInfo(&next_incl);
418                 FreeXKBFile(rtrn);
419             }
420             else
421             {
422                 info->errorCount += 10;
423                 FreeKeyTypesInfo(&included);
424                 return false;
425             }
426         }
427     }
428     if (haveSelf)
429         *info = included;
430     else
431     {
432         MergeIncludedKeyTypes(info, &included, newMerge, keymap);
433         FreeKeyTypesInfo(&included);
434     }
435     return (info->errorCount == 0);
436 }
437
438 /***====================================================================***/
439
440 static struct xkb_kt_map_entry *
441 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
442 {
443     unsigned int i;
444     struct xkb_kt_map_entry * entry;
445
446     for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
447     {
448         if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
449             return entry;
450     }
451     return NULL;
452 }
453
454 static void
455 DeleteLevel1MapEntries(KeyTypeInfo * type)
456 {
457     unsigned int i, n;
458
459     for (i = 0; i < type->nEntries; i++)
460     {
461         if (type->entries[i].level == 0)
462         {
463             for (n = i; n < type->nEntries - 1; n++)
464             {
465                 type->entries[n] = type->entries[n + 1];
466             }
467             type->nEntries--;
468         }
469     }
470 }
471
472 /**
473  * Return a pointer to the next free XkbcKTMapEntry, reallocating space if
474  * necessary.
475  */
476 static struct xkb_kt_map_entry *
477 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
478 {
479     if (type->entries == NULL)
480     {
481         type->entries = uTypedCalloc(2, struct xkb_kt_map_entry);
482         if (type->entries == NULL)
483         {
484             ERROR("Couldn't allocate map entries for %s\n",
485                   TypeTxt(keymap, type));
486             ACTION("Map entries lost\n");
487             return NULL;
488         }
489         type->szEntries = 2;
490         type->nEntries = 0;
491     }
492     else if (type->nEntries >= type->szEntries)
493     {
494         type->szEntries *= 2;
495         type->entries = uTypedRecalloc(type->entries,
496                                        type->nEntries, type->szEntries,
497                                        struct xkb_kt_map_entry);
498         if (type->entries == NULL)
499         {
500             ERROR("Couldn't reallocate map entries for %s\n",
501                   TypeTxt(keymap, type));
502             ACTION("Map entries lost\n");
503             return NULL;
504         }
505     }
506     return &type->entries[type->nEntries++];
507 }
508
509 static bool
510 AddPreserve(struct xkb_keymap *keymap, KeyTypeInfo *type,
511             PreserveInfo *new, bool clobber, bool report)
512 {
513     PreserveInfo *old;
514
515     old = type->preserve;
516     while (old != NULL)
517     {
518         if ((old->indexMods != new->indexMods) ||
519             (old->indexVMods != new->indexVMods))
520         {
521             old = (PreserveInfo *) old->defs.next;
522             continue;
523         }
524         if ((old->preMods == new->preMods)
525             && (old->preVMods == new->preVMods))
526         {
527             if (warningLevel > 9)
528             {
529                 WARN("Identical definitions for preserve[%s] in %s\n",
530                       PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
531                 ACTION("Ignored\n");
532             }
533             return true;
534         }
535         if (report && (warningLevel > 0))
536         {
537             const char *str;
538             WARN("Multiple definitions for preserve[%s] in %s\n",
539                   PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
540
541             if (clobber)
542                 str = PreserveTxt(keymap, new);
543             else
544                 str = PreserveTxt(keymap, old);
545             ACTION("Using %s, ", str);
546             if (clobber)
547                 str = PreserveTxt(keymap, old);
548             else
549                 str = PreserveTxt(keymap, new);
550             INFO("ignoring %s\n", str);
551         }
552         if (clobber)
553         {
554             old->preMods = new->preMods;
555             old->preVMods = new->preVMods;
556         }
557         return true;
558     }
559     old = uTypedAlloc(PreserveInfo);
560     if (!old)
561     {
562         WSGO("Couldn't allocate preserve in %s\n", TypeTxt(keymap, type));
563         ACTION("Preserve[%s] lost\n", PreserveIndexTxt(keymap, new));
564         return false;
565     }
566     *old = *new;
567     old->matchingMapIndex = -1;
568     type->preserve =
569         (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
570     return true;
571 }
572
573 /**
574  * Add a new KTMapEntry to the given key type. If an entry with the same mods
575  * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
576  * entry is created.
577  *
578  * @param clobber Overwrite existing entry.
579  * @param report true if a warning is to be printed on.
580  */
581 static bool
582 AddMapEntry(struct xkb_keymap *keymap, KeyTypeInfo *type,
583             struct xkb_kt_map_entry *new, bool clobber, bool report)
584 {
585     struct xkb_kt_map_entry * old;
586
587     if ((old =
588          FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
589     {
590         if (report && (old->level != new->level))
591         {
592             unsigned use, ignore;
593             if (clobber)
594             {
595                 use = new->level + 1;
596                 ignore = old->level + 1;
597             }
598             else
599             {
600                 use = old->level + 1;
601                 ignore = new->level + 1;
602             }
603             WARN("Multiple map entries for %s in %s\n",
604                   MapEntryTxt(keymap, new), TypeTxt(keymap, type));
605             ACTION("Using %d, ignoring %d\n", use, ignore);
606         }
607         else if (warningLevel > 9)
608         {
609             WARN("Multiple occurences of map[%s]= %d in %s\n",
610                   MapEntryTxt(keymap, new), new->level + 1,
611                   TypeTxt(keymap, type));
612             ACTION("Ignored\n");
613             return true;
614         }
615         if (clobber)
616             old->level = new->level;
617         return true;
618     }
619     if ((old = NextMapEntry(keymap, type)) == NULL)
620         return false;           /* allocation failure, already reported */
621     if (new->level >= type->numLevels)
622         type->numLevels = new->level + 1;
623     if (new->mods.vmods == 0)
624         old->active = true;
625     else
626         old->active = false;
627     old->mods.mask = new->mods.real_mods;
628     old->mods.real_mods = new->mods.real_mods;
629     old->mods.vmods = new->mods.vmods;
630     old->level = new->level;
631     return true;
632 }
633
634 static bool
635 SetMapEntry(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
636             ExprDef *value)
637 {
638     ExprResult rtrn;
639     struct xkb_kt_map_entry entry;
640
641     if (arrayNdx == NULL)
642         return ReportTypeShouldBeArray(keymap, type, "map entry");
643     if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
644         return ReportTypeBadType(keymap, type, "map entry", "modifier mask");
645     entry.mods.real_mods = rtrn.uval & 0xff;      /* modifiers < 512 */
646     entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
647     if ((entry.mods.real_mods & (~type->mask)) ||
648         ((entry.mods.vmods & (~type->vmask)) != 0))
649     {
650         if (warningLevel > 0)
651         {
652             WARN("Map entry for unused modifiers in %s\n", TypeTxt(keymap, type));
653             ACTION("Using %s instead of ",
654                     XkbcVModMaskText(keymap,
655                                     entry.mods.real_mods & type->mask,
656                                     entry.mods.vmods & type->vmask));
657             INFO("%s\n", MapEntryTxt(keymap, &entry));
658         }
659         entry.mods.real_mods &= type->mask;
660         entry.mods.vmods &= type->vmask;
661     }
662     if (!ExprResolveLevel(keymap->context, value, &rtrn))
663     {
664         ERROR("Level specifications in a key type must be integer\n");
665         ACTION("Ignoring malformed level specification\n");
666         return false;
667     }
668     entry.level = rtrn.ival - 1;
669     return AddMapEntry(keymap, type, &entry, true, true);
670 }
671
672 static bool
673 SetPreserve(KeyTypeInfo *type, struct xkb_keymap *keymap,
674             ExprDef *arrayNdx, ExprDef *value)
675 {
676     ExprResult rtrn;
677     PreserveInfo new;
678
679     if (arrayNdx == NULL)
680         return ReportTypeShouldBeArray(keymap, type, "preserve entry");
681     if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
682         return ReportTypeBadType(keymap, type, "preserve entry",
683                                  "modifier mask");
684     new.defs = type->defs;
685     new.defs.next = NULL;
686     new.indexMods = rtrn.uval & 0xff;
687     new.indexVMods = (rtrn.uval >> 8) & 0xffff;
688     if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
689     {
690         if (warningLevel > 0)
691         {
692             WARN("Preserve for modifiers not used by the %s type\n",
693                   TypeTxt(keymap, type));
694             ACTION("Index %s converted to ", PreserveIndexTxt(keymap, &new));
695         }
696         new.indexMods &= type->mask;
697         new.indexVMods &= type->vmask;
698         if (warningLevel > 0)
699             INFO("%s\n", PreserveIndexTxt(keymap, &new));
700     }
701     if (!ExprResolveVModMask(value, &rtrn, keymap))
702     {
703         ERROR("Preserve value in a key type is not a modifier mask\n");
704         ACTION("Ignoring preserve[%s] in type %s\n",
705                 PreserveIndexTxt(keymap, &new), TypeTxt(keymap, type));
706         return false;
707     }
708     new.preMods = rtrn.uval & 0xff;
709     new.preVMods = (rtrn.uval >> 16) & 0xffff;
710     if ((new.preMods & (~new.indexMods))
711         || (new.preVMods & (~new.indexVMods)))
712     {
713         if (warningLevel > 0)
714         {
715             WARN("Illegal value for preserve[%s] in type %s\n",
716                   PreserveTxt(keymap, &new), TypeTxt(keymap, type));
717             ACTION("Converted %s to ", PreserveIndexTxt(keymap, &new));
718         }
719         new.preMods &= new.indexMods;
720         new.preVMods &= new.indexVMods;
721         if (warningLevel > 0)
722         {
723             INFO("%s\n", PreserveIndexTxt(keymap, &new));
724         }
725     }
726     return AddPreserve(keymap, type, &new, true, true);
727 }
728
729 /***====================================================================***/
730
731 static bool
732 AddLevelName(struct xkb_keymap *keymap, KeyTypeInfo *type,
733              unsigned level, xkb_atom_t name, bool clobber)
734 {
735     if ((type->lvlNames == NULL) || (type->szNames <= level))
736     {
737         type->lvlNames =
738             uTypedRecalloc(type->lvlNames, type->szNames, level + 1, xkb_atom_t);
739         if (type->lvlNames == NULL)
740         {
741             ERROR("Couldn't allocate level names for type %s\n",
742                    TypeTxt(keymap, type));
743             ACTION("Level names lost\n");
744             type->szNames = 0;
745             return false;
746         }
747         type->szNames = level + 1;
748     }
749     else if (type->lvlNames[level] == name)
750     {
751         if (warningLevel > 9)
752         {
753             WARN("Duplicate names for level %d of key type %s\n",
754                   level + 1, TypeTxt(keymap, type));
755             ACTION("Ignored\n");
756         }
757         return true;
758     }
759     else if (type->lvlNames[level] != XKB_ATOM_NONE)
760     {
761         if (warningLevel > 0)
762         {
763             const char *old, *new;
764             old = xkb_atom_text(keymap->context, type->lvlNames[level]);
765             new = xkb_atom_text(keymap->context, name);
766             WARN("Multiple names for level %d of key type %s\n",
767                   level + 1, TypeTxt(keymap, type));
768             if (clobber)
769                 ACTION("Using %s, ignoring %s\n", new, old);
770             else
771                 ACTION("Using %s, ignoring %s\n", old, new);
772         }
773         if (!clobber)
774             return true;
775     }
776     if (level >= type->numLevels)
777         type->numLevels = level + 1;
778     type->lvlNames[level] = name;
779     return true;
780 }
781
782 static bool
783 SetLevelName(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
784              ExprDef *value)
785 {
786     ExprResult rtrn;
787     unsigned level;
788     xkb_atom_t level_name;
789
790     if (arrayNdx == NULL)
791         return ReportTypeShouldBeArray(keymap, type, "level name");
792     if (!ExprResolveLevel(keymap->context, arrayNdx, &rtrn))
793         return ReportTypeBadType(keymap, type, "level name", "integer");
794     level = rtrn.ival - 1;
795     if (!ExprResolveString(keymap->context, value, &rtrn))
796     {
797         ERROR("Non-string name for level %d in key type %s\n", level + 1,
798                xkb_atom_text(keymap->context, type->name));
799         ACTION("Ignoring illegal level name definition\n");
800         return false;
801     }
802     level_name = xkb_atom_intern(keymap->context, rtrn.str);
803     free(rtrn.str);
804     return AddLevelName(keymap, type, level, level_name, true);
805 }
806
807 /***====================================================================***/
808
809 /**
810  * Parses the fields in a type "..." { } description.
811  *
812  * @param field The field to parse (e.g. modifiers, map, level_name)
813  */
814 static bool
815 SetKeyTypeField(KeyTypeInfo *type, struct xkb_keymap *keymap,
816                 char *field, ExprDef *arrayNdx, ExprDef *value,
817                 KeyTypesInfo *info)
818 {
819     ExprResult tmp;
820
821     if (strcasecmp(field, "modifiers") == 0)
822     {
823         unsigned mods, vmods;
824         if (arrayNdx != NULL)
825         {
826             WARN("The modifiers field of a key type is not an array\n");
827             ACTION("Illegal array subscript ignored\n");
828         }
829         /* get modifier mask for current type */
830         if (!ExprResolveVModMask(value, &tmp, keymap))
831         {
832             ERROR("Key type mask field must be a modifier mask\n");
833             ACTION("Key type definition ignored\n");
834             return false;
835         }
836         mods = tmp.uval & 0xff; /* core mods */
837         vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
838         if (type->defs.defined & _KT_Mask)
839         {
840             WARN("Multiple modifier mask definitions for key type %s\n",
841                   xkb_atom_text(keymap->context, type->name));
842             ACTION("Using %s, ", TypeMaskTxt(type, keymap));
843             INFO("ignoring %s\n", XkbcVModMaskText(keymap, mods, vmods));
844             return false;
845         }
846         type->mask = mods;
847         type->vmask = vmods;
848         type->defs.defined |= _KT_Mask;
849         return true;
850     }
851     else if (strcasecmp(field, "map") == 0)
852     {
853         type->defs.defined |= _KT_Map;
854         return SetMapEntry(type, keymap, arrayNdx, value);
855     }
856     else if (strcasecmp(field, "preserve") == 0)
857     {
858         type->defs.defined |= _KT_Preserve;
859         return SetPreserve(type, keymap, arrayNdx, value);
860     }
861     else if ((strcasecmp(field, "levelname") == 0) ||
862              (strcasecmp(field, "level_name") == 0))
863     {
864         type->defs.defined |= _KT_LevelNames;
865         return SetLevelName(type, keymap, arrayNdx, value);
866     }
867     ERROR("Unknown field %s in key type %s\n", field, TypeTxt(keymap, type));
868     ACTION("Definition ignored\n");
869     return false;
870 }
871
872 static bool
873 HandleKeyTypeVar(VarDef *stmt, struct xkb_keymap *keymap, KeyTypesInfo *info)
874 {
875     ExprResult elem, field;
876     ExprDef *arrayNdx;
877
878     if (!ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx))
879         return false;           /* internal error, already reported */
880     if (elem.str && (strcasecmp(elem.str, "type") == 0))
881         return SetKeyTypeField(&info->dflt, keymap, field.str, arrayNdx,
882                                stmt->value, info);
883     if (elem.str != NULL)
884     {
885         ERROR("Default for unknown element %s\n", uStringText(elem.str));
886         ACTION("Value for field %s ignored\n", uStringText(field.str));
887     }
888     else if (field.str != NULL)
889     {
890         ERROR("Default defined for unknown field %s\n",
891                uStringText(field.str));
892         ACTION("Ignored\n");
893     }
894     return false;
895 }
896
897 static int
898 HandleKeyTypeBody(VarDef *def, struct xkb_keymap *keymap,
899                   KeyTypeInfo *type, KeyTypesInfo *info)
900 {
901     int ok = 1;
902     ExprResult tmp, field;
903     ExprDef *arrayNdx;
904
905     for (; def != NULL; def = (VarDef *) def->common.next)
906     {
907         if ((def->name) && (def->name->type == ExprFieldRef))
908         {
909             ok = HandleKeyTypeVar(def, keymap, info);
910             continue;
911         }
912         ok = ExprResolveLhs(keymap, def->name, &tmp, &field, &arrayNdx);
913         if (ok) {
914             ok = SetKeyTypeField(type, keymap, field.str, arrayNdx,
915                                  def->value, info);
916             free(field.str);
917         }
918     }
919     return ok;
920 }
921
922 /**
923  * Process a type "XYZ" { } specification in the xkb_types section.
924  *
925  */
926 static int
927 HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
928                  unsigned merge, KeyTypesInfo *info)
929 {
930     unsigned int i;
931     KeyTypeInfo type;
932
933     if (def->merge != MergeDefault)
934         merge = def->merge;
935
936     type.defs.defined = 0;
937     type.defs.fileID = info->fileID;
938     type.defs.merge = merge;
939     type.defs.next = NULL;
940     type.name = def->name;
941     type.mask = info->dflt.mask;
942     type.vmask = info->dflt.vmask;
943     type.groupInfo = info->dflt.groupInfo;
944     type.numLevels = 1;
945     type.nEntries = type.szEntries = 0;
946     type.entries = NULL;
947     type.szNames = 0;
948     type.lvlNames = NULL;
949     type.preserve = NULL;
950
951     /* Parse the actual content. */
952     if (!HandleKeyTypeBody(def->body, keymap, &type, info))
953     {
954         info->errorCount++;
955         return false;
956     }
957
958     /* now copy any appropriate map, preserve or level names from the */
959     /* default type */
960     for (i = 0; i < info->dflt.nEntries; i++)
961     {
962         struct xkb_kt_map_entry * dflt;
963         dflt = &info->dflt.entries[i];
964         if (((dflt->mods.real_mods & type.mask) == dflt->mods.real_mods) &&
965             ((dflt->mods.vmods & type.vmask) == dflt->mods.vmods))
966         {
967             AddMapEntry(keymap, &type, dflt, false, false);
968         }
969     }
970     if (info->dflt.preserve)
971     {
972         PreserveInfo *dflt = info->dflt.preserve;
973         while (dflt)
974         {
975             if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
976                 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
977             {
978                 AddPreserve(keymap, &type, dflt, false, false);
979             }
980             dflt = (PreserveInfo *) dflt->defs.next;
981         }
982     }
983     for (i = 0; i < info->dflt.szNames; i++)
984     {
985         if ((i < type.numLevels) && (info->dflt.lvlNames[i] != XKB_ATOM_NONE))
986         {
987             AddLevelName(keymap, &type, i, info->dflt.lvlNames[i], false);
988         }
989     }
990     /* Now add the new keytype to the info struct */
991     if (!AddKeyType(keymap, info, &type))
992     {
993         info->errorCount++;
994         return false;
995     }
996     return true;
997 }
998
999 /**
1000  * Process an xkb_types section.
1001  *
1002  * @param file The parsed xkb_types section.
1003  * @param merge Merge Strategy (e.g. MergeOverride)
1004  * @param info Pointer to memory where the outcome will be stored.
1005  */
1006 static void
1007 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
1008                    unsigned merge, KeyTypesInfo *info)
1009 {
1010     ParseCommon *stmt;
1011
1012     free(info->name);
1013     info->name = uDupString(file->name);
1014     stmt = file->defs;
1015     while (stmt)
1016     {
1017         switch (stmt->stmtType)
1018         {
1019         case StmtInclude:
1020             if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, keymap, info,
1021                                        HandleKeyTypesFile))
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->context, 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->context, 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->context,
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->context, tok_ONE_LEVEL);
1190         if (missing & XkbTwoLevelMask)
1191             keymap->map->types[XkbTwoLevelIndex].name =
1192                 xkb_atom_strdup(keymap->context, tok_TWO_LEVEL);
1193         if (missing & XkbAlphabeticMask)
1194             keymap->map->types[XkbAlphabeticIndex].name =
1195                 xkb_atom_strdup(keymap->context, tok_ALPHABETIC);
1196         if (missing & XkbKeypadMask)
1197             keymap->map->types[XkbKeypadIndex].name =
1198                 xkb_atom_strdup(keymap->context, 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 }