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