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