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