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