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