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