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