b19d7bd04f7337ee2d41963fcde09d95b2039cf3
[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                 return False;
439             }
440         }
441     }
442     if (haveSelf)
443         *info = included;
444     else
445     {
446         MergeIncludedKeyTypes(info, &included, newMerge, xkb);
447         FreeKeyTypesInfo(&included);
448     }
449     return (info->errorCount == 0);
450 }
451
452 /***====================================================================***/
453
454 static struct xkb_kt_map_entry *
455 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
456 {
457     register int i;
458     struct xkb_kt_map_entry * entry;
459
460     for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
461     {
462         if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
463             return entry;
464     }
465     return NULL;
466 }
467
468 static void
469 DeleteLevel1MapEntries(KeyTypeInfo * type)
470 {
471     register int i, n;
472
473     for (i = 0; i < type->nEntries; i++)
474     {
475         if (type->entries[i].level == 0)
476         {
477             for (n = i; n < type->nEntries - 1; n++)
478             {
479                 type->entries[n] = type->entries[n + 1];
480             }
481             type->nEntries--;
482         }
483     }
484     return;
485 }
486
487 /**
488  * Return a pointer to the next free XkbcKTMapEntry, reallocating space if
489  * necessary.
490  */
491 static struct xkb_kt_map_entry *
492 NextMapEntry(KeyTypeInfo * type)
493 {
494     if (type->entries == NULL)
495     {
496         type->entries = uTypedCalloc(2, struct xkb_kt_map_entry);
497         if (type->entries == NULL)
498         {
499             ERROR("Couldn't allocate map entries for %s\n", TypeTxt(type));
500             ACTION("Map entries lost\n");
501             return NULL;
502         }
503         type->szEntries = 2;
504         type->nEntries = 0;
505     }
506     else if (type->nEntries >= type->szEntries)
507     {
508         type->szEntries *= 2;
509         type->entries = uTypedRecalloc(type->entries,
510                                        type->nEntries, type->szEntries,
511                                        struct xkb_kt_map_entry);
512         if (type->entries == NULL)
513         {
514             ERROR("Couldn't reallocate map entries for %s\n", TypeTxt(type));
515             ACTION("Map entries lost\n");
516             return NULL;
517         }
518     }
519     return &type->entries[type->nEntries++];
520 }
521
522 static Bool
523 AddPreserve(struct xkb_desc * xkb,
524             KeyTypeInfo * type, PreserveInfo * new, Bool clobber, Bool report)
525 {
526     PreserveInfo *old;
527
528     old = type->preserve;
529     while (old != NULL)
530     {
531         if ((old->indexMods != new->indexMods) ||
532             (old->indexVMods != new->indexVMods))
533         {
534             old = (PreserveInfo *) old->defs.next;
535             continue;
536         }
537         if ((old->preMods == new->preMods)
538             && (old->preVMods == new->preVMods))
539         {
540             if (warningLevel > 9)
541             {
542                 WARN("Identical definitions for preserve[%s] in %s\n",
543                       PreserveIndexTxt(xkb, old), TypeTxt(type));
544                 ACTION("Ignored\n");
545             }
546             return True;
547         }
548         if (report && (warningLevel > 0))
549         {
550             char *str;
551             WARN("Multiple definitions for preserve[%s] in %s\n",
552                   PreserveIndexTxt(xkb, old), TypeTxt(type));
553
554             if (clobber)
555                 str = PreserveTxt(xkb, new);
556             else
557                 str = PreserveTxt(xkb, old);
558             ACTION("Using %s, ", str);
559             if (clobber)
560                 str = PreserveTxt(xkb, old);
561             else
562                 str = PreserveTxt(xkb, new);
563             INFO("ignoring %s\n", str);
564         }
565         if (clobber)
566         {
567             old->preMods = new->preMods;
568             old->preVMods = new->preVMods;
569         }
570         return True;
571     }
572     old = uTypedAlloc(PreserveInfo);
573     if (!old)
574     {
575         WSGO("Couldn't allocate preserve in %s\n", TypeTxt(type));
576         ACTION("Preserve[%s] lost\n", PreserveIndexTxt(xkb, old));
577         return False;
578     }
579     *old = *new;
580     old->matchingMapIndex = -1;
581     type->preserve =
582         (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
583     return True;
584 }
585
586 /**
587  * Add a new KTMapEntry to the given key type. If an entry with the same mods
588  * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
589  * entry is created.
590  *
591  * @param clobber Overwrite existing entry.
592  * @param report True if a warning is to be printed on.
593  */
594 static Bool
595 AddMapEntry(struct xkb_desc * xkb,
596             KeyTypeInfo * type,
597             struct xkb_kt_map_entry * new, Bool clobber, Bool report)
598 {
599     struct xkb_kt_map_entry * old;
600
601     if ((old =
602          FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
603     {
604         if (report && (old->level != new->level))
605         {
606             unsigned use, ignore;
607             if (clobber)
608             {
609                 use = new->level + 1;
610                 ignore = old->level + 1;
611             }
612             else
613             {
614                 use = old->level + 1;
615                 ignore = new->level + 1;
616             }
617             WARN("Multiple map entries for %s in %s\n",
618                   MapEntryTxt(xkb, new), TypeTxt(type));
619             ACTION("Using %d, ignoring %d\n", use, ignore);
620         }
621         else if (warningLevel > 9)
622         {
623             WARN("Multiple occurences of map[%s]= %d in %s\n",
624                   MapEntryTxt(xkb, new), new->level + 1, TypeTxt(type));
625             ACTION("Ignored\n");
626             return True;
627         }
628         if (clobber)
629             old->level = new->level;
630         return True;
631     }
632     if ((old = NextMapEntry(type)) == NULL)
633         return False;           /* allocation failure, already reported */
634     if (new->level >= type->numLevels)
635         type->numLevels = new->level + 1;
636     if (new->mods.vmods == 0)
637         old->active = True;
638     else
639         old->active = False;
640     old->mods.mask = new->mods.real_mods;
641     old->mods.real_mods = new->mods.real_mods;
642     old->mods.vmods = new->mods.vmods;
643     old->level = new->level;
644     return True;
645 }
646
647 static LookupEntry lnames[] = {
648     {"level1", 1},
649     {"level2", 2},
650     {"level3", 3},
651     {"level4", 4},
652     {"level5", 5},
653     {"level6", 6},
654     {"level7", 7},
655     {"level8", 8},
656     {NULL, 0}
657 };
658
659 static Bool
660 SetMapEntry(KeyTypeInfo * type,
661             struct xkb_desc * xkb, ExprDef * arrayNdx, ExprDef * value)
662 {
663     ExprResult rtrn;
664     struct xkb_kt_map_entry entry;
665
666     if (arrayNdx == NULL)
667         return ReportTypeShouldBeArray(type, "map entry");
668     if (!ExprResolveModMask(arrayNdx, &rtrn, LookupVModMask, (char *) xkb))
669         return ReportTypeBadType(type, "map entry", "modifier mask");
670     entry.mods.real_mods = rtrn.uval & 0xff;      /* modifiers < 512 */
671     entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
672     if ((entry.mods.real_mods & (~type->mask)) ||
673         ((entry.mods.vmods & (~type->vmask)) != 0))
674     {
675         if (warningLevel > 0)
676         {
677             WARN("Map entry for unused modifiers in %s\n", TypeTxt(type));
678             ACTION("Using %s instead of ",
679                     XkbcVModMaskText(xkb,
680                                     entry.mods.real_mods & type->mask,
681                                     entry.mods.vmods & type->vmask));
682             INFO("%s\n", MapEntryTxt(xkb, &entry));
683         }
684         entry.mods.real_mods &= type->mask;
685         entry.mods.vmods &= type->vmask;
686     }
687     if (!ExprResolveInteger(value, &rtrn, SimpleLookup, (char *) lnames))
688     {
689         ERROR("Level specifications in a key type must be integer\n");
690         ACTION("Ignoring malformed level specification\n");
691         return False;
692     }
693     if ((rtrn.ival < 1) || (rtrn.ival > XkbMaxShiftLevel + 1))
694     {
695         ERROR("Shift level %d out of range (1..%d) in key type %s\n",
696                XkbMaxShiftLevel + 1, rtrn.ival, TypeTxt(type));
697         ACTION("Ignoring illegal definition of map[%s]\n",
698                 MapEntryTxt(xkb, &entry));
699         return False;
700     }
701     entry.level = rtrn.ival - 1;
702     return AddMapEntry(xkb, type, &entry, True, True);
703 }
704
705 static Bool
706 SetPreserve(KeyTypeInfo * type,
707             struct xkb_desc * xkb, ExprDef * arrayNdx, ExprDef * value)
708 {
709     ExprResult rtrn;
710     PreserveInfo new;
711
712     if (arrayNdx == NULL)
713         return ReportTypeShouldBeArray(type, "preserve entry");
714     if (!ExprResolveModMask(arrayNdx, &rtrn, LookupVModMask, (char *) xkb))
715         return ReportTypeBadType(type, "preserve entry", "modifier mask");
716     new.defs = type->defs;
717     new.defs.next = NULL;
718     new.indexMods = rtrn.uval & 0xff;
719     new.indexVMods = (rtrn.uval >> 8) & 0xffff;
720     if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
721     {
722         if (warningLevel > 0)
723         {
724             WARN("Preserve for modifiers not used by the %s type\n",
725                   TypeTxt(type));
726             ACTION("Index %s converted to ", PreserveIndexTxt(xkb, &new));
727         }
728         new.indexMods &= type->mask;
729         new.indexVMods &= type->vmask;
730         if (warningLevel > 0)
731             INFO("%s\n", PreserveIndexTxt(xkb, &new));
732     }
733     if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (char *) xkb))
734     {
735         ERROR("Preserve value in a key type is not a modifier mask\n");
736         ACTION("Ignoring preserve[%s] in type %s\n",
737                 PreserveIndexTxt(xkb, &new), TypeTxt(type));
738         return False;
739     }
740     new.preMods = rtrn.uval & 0xff;
741     new.preVMods = (rtrn.uval >> 16) & 0xffff;
742     if ((new.preMods & (~new.indexMods))
743         || (new.preVMods && (~new.indexVMods)))
744     {
745         if (warningLevel > 0)
746         {
747             WARN("Illegal value for preserve[%s] in type %s\n",
748                   PreserveTxt(xkb, &new), TypeTxt(type));
749             ACTION("Converted %s to ", PreserveIndexTxt(xkb, &new));
750         }
751         new.preMods &= new.indexMods;
752         new.preVMods &= new.indexVMods;
753         if (warningLevel > 0)
754         {
755             INFO("%s\n", PreserveIndexTxt(xkb, &new));
756         }
757     }
758     return AddPreserve(xkb, type, &new, True, True);
759 }
760
761 /***====================================================================***/
762
763 static Bool
764 AddLevelName(KeyTypeInfo * type,
765              unsigned level, uint32_t name, Bool clobber, Bool report)
766 {
767     if ((type->lvlNames == NULL) || (type->szNames <= level))
768     {
769         type->lvlNames =
770             uTypedRecalloc(type->lvlNames, type->szNames, level + 1, uint32_t);
771         if (type->lvlNames == NULL)
772         {
773             ERROR("Couldn't allocate level names for type %s\n",
774                    TypeTxt(type));
775             ACTION("Level names lost\n");
776             type->szNames = 0;
777             return False;
778         }
779         type->szNames = level + 1;
780     }
781     else if (type->lvlNames[level] == name)
782     {
783         if (warningLevel > 9)
784         {
785             WARN("Duplicate names for level %d of key type %s\n",
786                   level + 1, TypeTxt(type));
787             ACTION("Ignored\n");
788         }
789         return True;
790     }
791     else if (type->lvlNames[level] != None)
792     {
793         if (warningLevel > 0)
794         {
795             const char *old, *new;
796             old = XkbcAtomText(type->lvlNames[level]);
797             new = XkbcAtomText(name);
798             WARN("Multiple names for level %d of key type %s\n",
799                   level + 1, TypeTxt(type));
800             if (clobber)
801                 ACTION("Using %s, ignoring %s\n", new, old);
802             else
803                 ACTION("Using %s, ignoring %s\n", old, new);
804         }
805         if (!clobber)
806             return True;
807     }
808     if (level >= type->numLevels)
809         type->numLevels = level + 1;
810     type->lvlNames[level] = name;
811     return True;
812 }
813
814 static Bool
815 SetLevelName(KeyTypeInfo * type, ExprDef * arrayNdx, ExprDef * value)
816 {
817     ExprResult rtrn;
818     unsigned level;
819     uint32_t level_name;
820
821     if (arrayNdx == NULL)
822         return ReportTypeShouldBeArray(type, "level name");
823     if (!ExprResolveInteger(arrayNdx, &rtrn, SimpleLookup, (char *) lnames))
824         return ReportTypeBadType(type, "level name", "integer");
825     if ((rtrn.ival < 1) || (rtrn.ival > XkbMaxShiftLevel + 1))
826     {
827         ERROR("Level name %d out of range (1..%d) in key type %s\n",
828                rtrn.ival,
829                XkbMaxShiftLevel + 1,
830                XkbcAtomText(type->name));
831         ACTION("Ignoring illegal level name definition\n");
832         return False;
833     }
834     level = rtrn.ival - 1;
835     if (!ExprResolveString(value, &rtrn, NULL, NULL))
836     {
837         ERROR("Non-string name for level %d in key type %s\n", level + 1,
838                XkbcAtomText(type->name));
839         ACTION("Ignoring illegal level name definition\n");
840         return False;
841     }
842     level_name = xkb_intern_atom(rtrn.str);
843     free(rtrn.str);
844     return AddLevelName(type, level, level_name, True, True);
845 }
846
847 /***====================================================================***/
848
849 /**
850  * Parses the fields in a type "..." { } description.
851  *
852  * @param field The field to parse (e.g. modifiers, map, level_name)
853  */
854 static Bool
855 SetKeyTypeField(KeyTypeInfo * type,
856                 struct xkb_desc * xkb,
857                 char *field,
858                 ExprDef * arrayNdx, ExprDef * value, KeyTypesInfo * info)
859 {
860     ExprResult tmp;
861
862     if (uStrCaseCmp(field, "modifiers") == 0)
863     {
864         unsigned mods, vmods;
865         if (arrayNdx != NULL)
866         {
867             WARN("The modifiers field of a key type is not an array\n");
868             ACTION("Illegal array subscript ignored\n");
869         }
870         /* get modifier mask for current type */
871         if (!ExprResolveModMask(value, &tmp, LookupVModMask, (char *) xkb))
872         {
873             ERROR("Key type mask field must be a modifier mask\n");
874             ACTION("Key type definition ignored\n");
875             return False;
876         }
877         mods = tmp.uval & 0xff; /* core mods */
878         vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
879         if (type->defs.defined & _KT_Mask)
880         {
881             WARN("Multiple modifier mask definitions for key type %s\n",
882                   XkbcAtomText(type->name));
883             ACTION("Using %s, ", TypeMaskTxt(type, xkb));
884             INFO("ignoring %s\n", XkbcVModMaskText(xkb, mods, vmods));
885             return False;
886         }
887         type->mask = mods;
888         type->vmask = vmods;
889         type->defs.defined |= _KT_Mask;
890         return True;
891     }
892     else if (uStrCaseCmp(field, "map") == 0)
893     {
894         type->defs.defined |= _KT_Map;
895         return SetMapEntry(type, xkb, arrayNdx, value);
896     }
897     else if (uStrCaseCmp(field, "preserve") == 0)
898     {
899         type->defs.defined |= _KT_Preserve;
900         return SetPreserve(type, xkb, arrayNdx, value);
901     }
902     else if ((uStrCaseCmp(field, "levelname") == 0) ||
903              (uStrCaseCmp(field, "level_name") == 0))
904     {
905         type->defs.defined |= _KT_LevelNames;
906         return SetLevelName(type, arrayNdx, value);
907     }
908     ERROR("Unknown field %s in key type %s\n", field, TypeTxt(type));
909     ACTION("Definition ignored\n");
910     return False;
911 }
912
913 static Bool
914 HandleKeyTypeVar(VarDef * stmt, struct xkb_desc * xkb, KeyTypesInfo * info)
915 {
916     ExprResult elem, field;
917     ExprDef *arrayNdx;
918
919     if (!ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx))
920         return False;           /* internal error, already reported */
921     if (elem.str && (uStrCaseCmp(elem.str, "type") == 0))
922         return SetKeyTypeField(&info->dflt, xkb, field.str, arrayNdx,
923                                stmt->value, info);
924     if (elem.str != NULL)
925     {
926         ERROR("Default for unknown element %s\n", uStringText(elem.str));
927         ACTION("Value for field %s ignored\n", uStringText(field.str));
928     }
929     else if (field.str != NULL)
930     {
931         ERROR("Default defined for unknown field %s\n",
932                uStringText(field.str));
933         ACTION("Ignored\n");
934     }
935     return False;
936 }
937
938 static int
939 HandleKeyTypeBody(VarDef * def,
940                   struct xkb_desc * xkb, KeyTypeInfo * type, KeyTypesInfo * info)
941 {
942     int ok = 1;
943     ExprResult tmp, field;
944     ExprDef *arrayNdx;
945
946     for (; def != NULL; def = (VarDef *) def->common.next)
947     {
948         if ((def->name) && (def->name->type == ExprFieldRef))
949         {
950             ok = HandleKeyTypeVar(def, xkb, info);
951             continue;
952         }
953         ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
954         if (ok)
955             ok = SetKeyTypeField(type, xkb, field.str, arrayNdx, def->value,
956                                  info);
957     }
958     return ok;
959 }
960
961 /**
962  * Process a type "XYZ" { } specification in the xkb_types section.
963  *
964  */
965 static int
966 HandleKeyTypeDef(KeyTypeDef * def,
967                  struct xkb_desc * xkb, unsigned merge, KeyTypesInfo * info)
968 {
969     register int i;
970     KeyTypeInfo type;
971
972     if (def->merge != MergeDefault)
973         merge = def->merge;
974
975     type.defs.defined = 0;
976     type.defs.fileID = info->fileID;
977     type.defs.merge = merge;
978     type.defs.next = NULL;
979     type.name = def->name;
980     type.mask = info->dflt.mask;
981     type.vmask = info->dflt.vmask;
982     type.groupInfo = info->dflt.groupInfo;
983     type.numLevels = 1;
984     type.nEntries = type.szEntries = 0;
985     type.entries = NULL;
986     type.szNames = 0;
987     type.lvlNames = NULL;
988     type.preserve = NULL;
989
990     /* Parse the actual content. */
991     if (!HandleKeyTypeBody(def->body, xkb, &type, info))
992     {
993         info->errorCount++;
994         return False;
995     }
996
997     /* now copy any appropriate map, preserve or level names from the */
998     /* default type */
999     for (i = 0; i < info->dflt.nEntries; i++)
1000     {
1001         struct xkb_kt_map_entry * dflt;
1002         dflt = &info->dflt.entries[i];
1003         if (((dflt->mods.real_mods & type.mask) == dflt->mods.real_mods) &&
1004             ((dflt->mods.vmods & type.vmask) == dflt->mods.vmods))
1005         {
1006             AddMapEntry(xkb, &type, dflt, False, False);
1007         }
1008     }
1009     if (info->dflt.preserve)
1010     {
1011         PreserveInfo *dflt = info->dflt.preserve;
1012         while (dflt)
1013         {
1014             if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
1015                 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
1016             {
1017                 AddPreserve(xkb, &type, dflt, False, False);
1018             }
1019             dflt = (PreserveInfo *) dflt->defs.next;
1020         }
1021     }
1022     for (i = 0; i < info->dflt.szNames; i++)
1023     {
1024         if ((i < type.numLevels) && (info->dflt.lvlNames[i] != None))
1025         {
1026             AddLevelName(&type, i, info->dflt.lvlNames[i], False, False);
1027         }
1028     }
1029     /* Now add the new keytype to the info struct */
1030     if (!AddKeyType(xkb, info, &type))
1031     {
1032         info->errorCount++;
1033         return False;
1034     }
1035     return True;
1036 }
1037
1038 /**
1039  * Process an xkb_types section.
1040  *
1041  * @param file The parsed xkb_types section.
1042  * @param merge Merge Strategy (e.g. MergeOverride)
1043  * @param info Pointer to memory where the outcome will be stored.
1044  */
1045 static void
1046 HandleKeyTypesFile(XkbFile * file,
1047                    struct xkb_desc * xkb, unsigned merge, KeyTypesInfo * info)
1048 {
1049     ParseCommon *stmt;
1050
1051     info->name = _XkbDupString(file->name);
1052     stmt = file->defs;
1053     while (stmt)
1054     {
1055         switch (stmt->stmtType)
1056         {
1057         case StmtInclude:
1058             if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, xkb, info,
1059                                        HandleKeyTypesFile))
1060                 info->errorCount++;
1061             break;
1062         case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
1063             if (!HandleKeyTypeDef((KeyTypeDef *) stmt, xkb, merge, info))
1064                 info->errorCount++;
1065             break;
1066         case StmtVarDef:
1067             if (!HandleKeyTypeVar((VarDef *) stmt, xkb, info))
1068                 info->errorCount++;
1069             break;
1070         case StmtVModDef: /* virtual_modifiers NumLock, ... */
1071             if (!HandleVModDef((VModDef *) stmt, xkb, merge, &info->vmods))
1072                 info->errorCount++;
1073             break;
1074         case StmtKeyAliasDef:
1075             ERROR("Key type files may not include other declarations\n");
1076             ACTION("Ignoring definition of key alias\n");
1077             info->errorCount++;
1078             break;
1079         case StmtKeycodeDef:
1080             ERROR("Key type files may not include other declarations\n");
1081             ACTION("Ignoring definition of key name\n");
1082             info->errorCount++;
1083             break;
1084         case StmtInterpDef:
1085             ERROR("Key type files may not include other declarations\n");
1086             ACTION("Ignoring definition of symbol interpretation\n");
1087             info->errorCount++;
1088             break;
1089         default:
1090             WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
1091                   stmt->stmtType);
1092             break;
1093         }
1094         stmt = stmt->next;
1095         if (info->errorCount > 10)
1096         {
1097 #ifdef NOISY
1098             ERROR("Too many errors\n");
1099 #endif
1100             ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
1101             break;
1102         }
1103     }
1104     return;
1105 }
1106
1107 static Bool
1108 CopyDefToKeyType(struct xkb_desc * xkb, struct xkb_key_type * type, KeyTypeInfo * def)
1109 {
1110     register int i;
1111     PreserveInfo *pre;
1112
1113     for (pre = def->preserve; pre != NULL;
1114          pre = (PreserveInfo *) pre->defs.next)
1115     {
1116         struct xkb_kt_map_entry * match;
1117         struct xkb_kt_map_entry tmp;
1118         tmp.mods.real_mods = pre->indexMods;
1119         tmp.mods.vmods = pre->indexVMods;
1120         tmp.level = 0;
1121         AddMapEntry(xkb, def, &tmp, False, False);
1122         match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1123         if (!match)
1124         {
1125             WSGO("Couldn't find matching entry for preserve\n");
1126             ACTION("Aborting\n");
1127             return False;
1128         }
1129         pre->matchingMapIndex = match - def->entries;
1130     }
1131     type->mods.real_mods = def->mask;
1132     type->mods.vmods = def->vmask;
1133     type->num_levels = def->numLevels;
1134     type->map_count = def->nEntries;
1135     type->map = def->entries;
1136     if (def->preserve)
1137     {
1138         type->preserve = uTypedCalloc(type->map_count, struct xkb_mods);
1139         if (!type->preserve)
1140         {
1141             WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1142             ACTION("Preserve setting for type %s lost\n",
1143                     XkbcAtomText(def->name));
1144         }
1145         else
1146         {
1147             pre = def->preserve;
1148             for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
1149             {
1150                 int ndx = pre->matchingMapIndex;
1151                 type->preserve[ndx].mask = pre->preMods;
1152                 type->preserve[ndx].real_mods = pre->preMods;
1153                 type->preserve[ndx].vmods = pre->preVMods;
1154             }
1155         }
1156     }
1157     else
1158         type->preserve = NULL;
1159     type->name = (uint32_t) def->name;
1160     if (def->szNames > 0)
1161     {
1162         type->level_names = uTypedCalloc(def->numLevels, uint32_t);
1163
1164         /* assert def->szNames<=def->numLevels */
1165         for (i = 0; i < def->szNames; i++)
1166         {
1167             type->level_names[i] = (uint32_t) def->lvlNames[i];
1168         }
1169     }
1170     else
1171     {
1172         type->level_names = NULL;
1173     }
1174
1175     def->nEntries = def->szEntries = 0;
1176     def->entries = NULL;
1177     return XkbcComputeEffectiveMap(xkb, type, NULL);
1178 }
1179
1180 Bool
1181 CompileKeyTypes(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
1182 {
1183     KeyTypesInfo info;
1184
1185     InitKeyTypesInfo(&info, xkb, NULL);
1186     info.fileID = file->id;
1187     HandleKeyTypesFile(file, xkb, merge, &info);
1188
1189     if (info.errorCount == 0)
1190     {
1191         register int i;
1192         register KeyTypeInfo *def;
1193         register struct xkb_key_type *type, *next;
1194
1195         if (info.name != NULL)
1196         {
1197             if (XkbcAllocNames(xkb, XkbTypesNameMask, 0, 0) == Success)
1198                 xkb->names->types = xkb_intern_atom(info.name);
1199             else
1200             {
1201                 WSGO("Couldn't allocate space for types name\n");
1202                 ACTION("Name \"%s\" (from %s) NOT assigned\n",
1203                         scanFile, info.name);
1204             }
1205         }
1206         i = info.nTypes;
1207         if ((info.stdPresent & XkbOneLevelMask) == 0)
1208             i++;
1209         if ((info.stdPresent & XkbTwoLevelMask) == 0)
1210             i++;
1211         if ((info.stdPresent & XkbKeypadMask) == 0)
1212             i++;
1213         if ((info.stdPresent & XkbAlphabeticMask) == 0)
1214             i++;
1215         if (XkbcAllocClientMap(xkb, XkbKeyTypesMask, i) != Success)
1216         {
1217             WSGO("Couldn't allocate client map\n");
1218             return False;
1219         }
1220         xkb->map->num_types = i;
1221         if (XkbAllRequiredTypes & (~info.stdPresent))
1222         {
1223             unsigned missing, keypadVMod;
1224
1225             missing = XkbAllRequiredTypes & (~info.stdPresent);
1226             keypadVMod = FindKeypadVMod(xkb);
1227             if (XkbcInitCanonicalKeyTypes(xkb, missing, keypadVMod) != Success)
1228             {
1229                 WSGO("Couldn't initialize canonical key types\n");
1230                 return False;
1231             }
1232             if (missing & XkbOneLevelMask)
1233                 xkb->map->types[XkbOneLevelIndex].name = tok_ONE_LEVEL;
1234             if (missing & XkbTwoLevelMask)
1235                 xkb->map->types[XkbTwoLevelIndex].name = tok_TWO_LEVEL;
1236             if (missing & XkbAlphabeticMask)
1237                 xkb->map->types[XkbAlphabeticIndex].name = tok_ALPHABETIC;
1238             if (missing & XkbKeypadMask)
1239                 xkb->map->types[XkbKeypadIndex].name = tok_KEYPAD;
1240         }
1241         next = &xkb->map->types[XkbLastRequiredType + 1];
1242         for (i = 0, def = info.types; i < info.nTypes; i++)
1243         {
1244             if (def->name == tok_ONE_LEVEL)
1245                 type = &xkb->map->types[XkbOneLevelIndex];
1246             else if (def->name == tok_TWO_LEVEL)
1247                 type = &xkb->map->types[XkbTwoLevelIndex];
1248             else if (def->name == tok_ALPHABETIC)
1249                 type = &xkb->map->types[XkbAlphabeticIndex];
1250             else if (def->name == tok_KEYPAD)
1251                 type = &xkb->map->types[XkbKeypadIndex];
1252             else
1253                 type = next++;
1254             DeleteLevel1MapEntries(def);
1255             if (!CopyDefToKeyType(xkb, type, def))
1256                 return False;
1257             def = (KeyTypeInfo *) def->defs.next;
1258         }
1259         return True;
1260     }
1261     return False;
1262 }