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