1 /************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
34 typedef struct _PreserveInfo
37 short matchingMapIndex;
38 unsigned char indexMods;
39 unsigned char preMods;
40 unsigned short indexVMods;
41 unsigned short preVMods;
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)
50 typedef struct _KeyTypeInfo
61 XkbKTMapEntryPtr entries;
62 PreserveInfo *preserve;
67 typedef struct _KeyTypesInfo
84 /***====================================================================***/
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))
91 /***====================================================================***/
93 extern Bool AddMapEntry(XkbcDescPtr /* xkb */ ,
94 KeyTypeInfo * /* type */ ,
95 XkbKTMapEntryPtr /* new */ ,
100 extern Bool AddPreserve(XkbcDescPtr /* xkb */ ,
101 KeyTypeInfo * /* type */ ,
102 PreserveInfo * /* new */ ,
107 extern Bool AddLevelName(KeyTypeInfo * /* type */ ,
108 unsigned /* level */ ,
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)
121 XkbcAtomText((t)->name)
122 #define TypeMaskTxt(t, x) \
123 XkbcVModMaskText((x), (t)->mask, (t)->vmask)
125 /***====================================================================***/
128 InitKeyTypesInfo(KeyTypesInfo * info, XkbcDescPtr xkb, KeyTypesInfo * from)
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;
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;
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);
156 info->dflt = from->dflt;
157 if (from->dflt.entries)
159 info->dflt.entries = uTypedCalloc(from->dflt.szEntries,
161 if (info->dflt.entries)
163 unsigned sz = from->dflt.nEntries * sizeof(XkbKTMapEntryRec);
164 memcpy(info->dflt.entries, from->dflt.entries, sz);
167 if (from->dflt.lvlNames)
169 info->dflt.lvlNames = uTypedCalloc(from->dflt.szNames, Atom);
170 if (info->dflt.lvlNames)
172 register unsigned sz = from->dflt.szNames * sizeof(Atom);
173 memcpy(info->dflt.lvlNames, from->dflt.lvlNames, sz);
176 if (from->dflt.preserve)
178 PreserveInfo *old, *new, *last;
180 old = from->dflt.preserve;
181 for (; old; old = (PreserveInfo *) old->defs.next)
183 new = uTypedAlloc(PreserveInfo);
187 new->defs.next = NULL;
189 last->defs.next = (CommonInfo *) new;
191 info->dflt.preserve = new;
200 FreeKeyTypeInfo(KeyTypeInfo * type)
202 if (type->entries != NULL)
204 uFree(type->entries);
205 type->entries = NULL;
207 if (type->lvlNames != NULL)
209 uFree(type->lvlNames);
210 type->lvlNames = NULL;
212 if (type->preserve != NULL)
214 ClearCommonInfo(&type->preserve->defs);
215 type->preserve = NULL;
221 FreeKeyTypesInfo(KeyTypesInfo * info)
228 register KeyTypeInfo *type;
229 for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
231 FreeKeyTypeInfo(type);
233 info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs);
235 FreeKeyTypeInfo(&info->dflt);
240 NextKeyType(KeyTypesInfo * info)
244 type = uTypedAlloc(KeyTypeInfo);
247 bzero(type, sizeof(KeyTypeInfo));
248 type->defs.fileID = info->fileID;
249 info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs,
250 (CommonInfo *) type);
257 FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
261 for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
263 if (old->name == new->name)
270 ReportTypeBadWidth(const char *type, int has, int needs)
272 ERROR("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
273 ACTION("Illegal type definition ignored\n");
278 AddKeyType(XkbcDescPtr xkb, KeyTypesInfo * info, KeyTypeInfo * new)
282 if (new->name == tok_ONE_LEVEL)
284 if (new->numLevels > 1)
285 return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
286 info->stdPresent |= XkbOneLevelMask;
288 else if (new->name == tok_TWO_LEVEL)
290 if (new->numLevels > 2)
291 return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
292 else if (new->numLevels < 2)
294 info->stdPresent |= XkbTwoLevelMask;
296 else if (new->name == tok_ALPHABETIC)
298 if (new->numLevels > 2)
299 return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
300 else if (new->numLevels < 2)
302 info->stdPresent |= XkbAlphabeticMask;
304 else if (new->name == tok_KEYPAD)
306 if (new->numLevels > 2)
307 return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
308 else if (new->numLevels < 2)
310 info->stdPresent |= XkbKeypadMask;
313 old = FindMatchingKeyType(info, new);
317 if ((new->defs.merge == MergeReplace)
318 || (new->defs.merge == MergeOverride))
320 KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
321 if (((old->defs.fileID == new->defs.fileID)
322 && (warningLevel > 0)) || (warningLevel > 9))
324 WARN("Multiple definitions of the %s key type\n",
325 XkbcAtomGetString(new->name));
326 ACTION("Earlier definition ignored\n");
328 FreeKeyTypeInfo(old);
330 new->szEntries = new->nEntries = 0;
332 new->preserve = NULL;
333 new->lvlNames = NULL;
334 old->defs.next = &next->defs;
337 report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
340 WARN("Multiple definitions of the %s key type\n",
341 XkbcAtomGetString(new->name));
342 ACTION("Later definition ignored\n");
344 FreeKeyTypeInfo(new);
347 old = NextKeyType(info);
351 old->defs.next = NULL;
352 new->nEntries = new->szEntries = 0;
355 new->lvlNames = NULL;
356 new->preserve = NULL;
360 /***====================================================================***/
363 MergeIncludedKeyTypes(KeyTypesInfo * into,
364 KeyTypesInfo * from, unsigned merge, XkbcDescPtr xkb)
368 if (from->errorCount > 0)
370 into->errorCount += from->errorCount;
373 if (into->name == NULL)
375 into->name = from->name;
378 for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
380 if (merge != MergeDefault)
381 type->defs.merge = merge;
382 if (!AddKeyType(xkb, into, type))
385 into->stdPresent |= from->stdPresent;
389 typedef void (*FileHandler) (XkbFile * /* file */ ,
390 XkbcDescPtr /* xkb */ ,
391 unsigned /* merge */ ,
392 KeyTypesInfo * /* included */
396 HandleIncludeKeyTypes(IncludeStmt * stmt,
397 XkbcDescPtr xkb, KeyTypesInfo * info, FileHandler hndlr)
401 KeyTypesInfo included;
405 if ((stmt->file == NULL) && (stmt->map == NULL))
409 bzero(info, sizeof(KeyTypesInfo));
411 else if (ProcessIncludeFile(stmt, XkmTypesIndex, &rtrn, &newMerge))
413 InitKeyTypesInfo(&included, xkb, info);
414 included.fileID = included.dflt.defs.fileID = rtrn->id;
415 included.dflt.defs.merge = newMerge;
417 (*hndlr) (rtrn, xkb, newMerge, &included);
418 if (stmt->stmt != NULL)
420 if (included.name != NULL)
421 uFree(included.name);
422 included.name = stmt->stmt;
428 info->errorCount += 10;
431 if ((stmt->next != NULL) && (included.errorCount < 1))
435 KeyTypesInfo next_incl;
437 for (next = stmt->next; next != NULL; next = next->next)
439 if ((next->file == NULL) && (next->map == NULL))
442 MergeIncludedKeyTypes(&included, info, next->merge, xkb);
443 FreeKeyTypesInfo(info);
445 else if (ProcessIncludeFile(next, XkmTypesIndex, &rtrn, &op))
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);
456 info->errorCount += 10;
465 MergeIncludedKeyTypes(info, &included, newMerge, xkb);
466 FreeKeyTypesInfo(&included);
468 return (info->errorCount == 0);
471 /***====================================================================***/
473 static XkbKTMapEntryPtr
474 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
477 XkbKTMapEntryPtr entry;
479 for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
481 if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
488 DeleteLevel1MapEntries(KeyTypeInfo * type)
492 for (i = 0; i < type->nEntries; i++)
494 if (type->entries[i].level == 0)
496 for (n = i; n < type->nEntries - 1; n++)
498 type->entries[n] = type->entries[n + 1];
507 * Return a pointer to the next free XkbKTMapEntry, reallocating space if
510 static XkbKTMapEntryPtr
511 NextMapEntry(KeyTypeInfo * type)
513 if (type->entries == NULL)
515 type->entries = uTypedCalloc(2, XkbKTMapEntryRec);
516 if (type->entries == NULL)
518 ERROR("Couldn't allocate map entries for %s\n", TypeTxt(type));
519 ACTION("Map entries lost\n");
525 else if (type->nEntries >= type->szEntries)
527 type->szEntries *= 2;
528 type->entries = uTypedRecalloc(type->entries,
529 type->nEntries, type->szEntries,
531 if (type->entries == NULL)
533 ERROR("Couldn't reallocate map entries for %s\n", TypeTxt(type));
534 ACTION("Map entries lost\n");
538 return &type->entries[type->nEntries++];
542 AddPreserve(XkbcDescPtr xkb,
543 KeyTypeInfo * type, PreserveInfo * new, Bool clobber, Bool report)
547 old = type->preserve;
550 if ((old->indexMods != new->indexMods) ||
551 (old->indexVMods != new->indexVMods))
553 old = (PreserveInfo *) old->defs.next;
556 if ((old->preMods == new->preMods)
557 && (old->preVMods == new->preVMods))
559 if (warningLevel > 9)
561 WARN("Identical definitions for preserve[%s] in %s\n",
562 PreserveIndexTxt(xkb, old), TypeTxt(type));
567 if (report && (warningLevel > 0))
570 WARN("Multiple definitions for preserve[%s] in %s\n",
571 PreserveIndexTxt(xkb, old), TypeTxt(type));
574 str = PreserveTxt(xkb, new);
576 str = PreserveTxt(xkb, old);
577 ACTION("Using %s, ", str);
579 str = PreserveTxt(xkb, old);
581 str = PreserveTxt(xkb, new);
582 INFO("ignoring %s\n", str);
586 old->preMods = new->preMods;
587 old->preVMods = new->preVMods;
591 old = uTypedAlloc(PreserveInfo);
594 WSGO("Couldn't allocate preserve in %s\n", TypeTxt(type));
595 ACTION("Preserve[%s] lost\n", PreserveIndexTxt(xkb, old));
599 old->matchingMapIndex = -1;
601 (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
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
610 * @param clobber Overwrite existing entry.
611 * @param report True if a warning is to be printed on.
614 AddMapEntry(XkbcDescPtr xkb,
616 XkbKTMapEntryPtr new, Bool clobber, Bool report)
618 XkbKTMapEntryPtr old;
621 FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
623 if (report && (old->level != new->level))
625 unsigned use, ignore;
628 use = new->level + 1;
629 ignore = old->level + 1;
633 use = old->level + 1;
634 ignore = new->level + 1;
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);
640 else if (warningLevel > 9)
642 WARN("Multiple occurences of map[%s]= %d in %s\n",
643 MapEntryTxt(xkb, new), new->level + 1, TypeTxt(type));
648 old->level = new->level;
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)
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;
666 static LookupEntry lnames[] = {
679 SetMapEntry(KeyTypeInfo * type,
680 XkbcDescPtr xkb, ExprDef * arrayNdx, ExprDef * value)
683 XkbKTMapEntryRec entry;
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))
694 if (warningLevel > 0)
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));
703 entry.mods.real_mods &= type->mask;
704 entry.mods.vmods &= type->vmask;
706 if (!ExprResolveInteger(value, &rtrn, SimpleLookup, (char *) lnames))
708 ERROR("Level specifications in a key type must be integer\n");
709 ACTION("Ignoring malformed level specification\n");
712 if ((rtrn.ival < 1) || (rtrn.ival > XkbMaxShiftLevel + 1))
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));
720 entry.level = rtrn.ival - 1;
721 return AddMapEntry(xkb, type, &entry, True, True);
725 SetPreserve(KeyTypeInfo * type,
726 XkbcDescPtr xkb, ExprDef * arrayNdx, ExprDef * value)
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)))
741 if (warningLevel > 0)
743 WARN("Preserve for modifiers not used by the %s type\n",
745 ACTION("Index %s converted to ", PreserveIndexTxt(xkb, &new));
747 new.indexMods &= type->mask;
748 new.indexVMods &= type->vmask;
749 if (warningLevel > 0)
750 INFO("%s\n", PreserveIndexTxt(xkb, &new));
752 if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (char *) xkb))
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));
759 new.preMods = rtrn.uval & 0xff;
760 new.preVMods = (rtrn.uval >> 16) & 0xffff;
761 if ((new.preMods & (~new.indexMods))
762 || (new.preVMods && (~new.indexVMods)))
764 if (warningLevel > 0)
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));
770 new.preMods &= new.indexMods;
771 new.preVMods &= new.indexVMods;
772 if (warningLevel > 0)
774 INFO("%s\n", PreserveIndexTxt(xkb, &new));
777 return AddPreserve(xkb, type, &new, True, True);
780 /***====================================================================***/
783 AddLevelName(KeyTypeInfo * type,
784 unsigned level, Atom name, Bool clobber, Bool report)
786 if ((type->lvlNames == NULL) || (type->szNames <= level))
789 uTypedRecalloc(type->lvlNames, type->szNames, level + 1, Atom);
790 if (type->lvlNames == NULL)
792 ERROR("Couldn't allocate level names for type %s\n",
794 ACTION("Level names lost\n");
798 type->szNames = level + 1;
800 else if (type->lvlNames[level] == name)
802 if (warningLevel > 9)
804 WARN("Duplicate names for level %d of key type %s\n",
805 level + 1, TypeTxt(type));
810 else if (type->lvlNames[level] != None)
812 if (warningLevel > 0)
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));
820 ACTION("Using %s, ignoring %s\n", new, old);
822 ACTION("Using %s, ignoring %s\n", old, new);
827 if (level >= type->numLevels)
828 type->numLevels = level + 1;
829 type->lvlNames[level] = name;
834 SetLevelName(KeyTypeInfo * type, ExprDef * arrayNdx, ExprDef * value)
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))
845 ERROR("Level name %d out of range (1..%d) in key type %s\n",
847 XkbMaxShiftLevel + 1,
848 XkbcAtomText(type->name));
849 ACTION("Ignoring illegal level name definition\n");
852 level = rtrn.ival - 1;
853 if (!ExprResolveString(value, &rtrn, NULL, NULL))
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");
861 AddLevelName(type, level, XkbcInternAtom(rtrn.str, False), True,
865 /***====================================================================***/
868 * Parses the fields in a type "..." { } description.
870 * @param field The field to parse (e.g. modifiers, map, level_name)
873 SetKeyTypeField(KeyTypeInfo * type,
876 ExprDef * arrayNdx, ExprDef * value, KeyTypesInfo * info)
880 if (uStrCaseCmp(field, "modifiers") == 0)
882 unsigned mods, vmods;
883 if (arrayNdx != NULL)
885 WARN("The modifiers field of a key type is not an array\n");
886 ACTION("Illegal array subscript ignored\n");
888 /* get modifier mask for current type */
889 if (!ExprResolveModMask(value, &tmp, LookupVModMask, (char *) xkb))
891 ERROR("Key type mask field must be a modifier mask\n");
892 ACTION("Key type definition ignored\n");
895 mods = tmp.uval & 0xff; /* core mods */
896 vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
897 if (type->defs.defined & _KT_Mask)
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));
907 type->defs.defined |= _KT_Mask;
910 else if (uStrCaseCmp(field, "map") == 0)
912 type->defs.defined |= _KT_Map;
913 return SetMapEntry(type, xkb, arrayNdx, value);
915 else if (uStrCaseCmp(field, "preserve") == 0)
917 type->defs.defined |= _KT_Preserve;
918 return SetPreserve(type, xkb, arrayNdx, value);
920 else if ((uStrCaseCmp(field, "levelname") == 0) ||
921 (uStrCaseCmp(field, "level_name") == 0))
923 type->defs.defined |= _KT_LevelNames;
924 return SetLevelName(type, arrayNdx, value);
926 ERROR("Unknown field %s in key type %s\n", field, TypeTxt(type));
927 ACTION("Definition ignored\n");
932 HandleKeyTypeVar(VarDef * stmt, XkbcDescPtr xkb, KeyTypesInfo * info)
934 ExprResult elem, field;
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,
942 if (elem.str != NULL)
944 ERROR("Default for unknown element %s\n", uStringText(elem.str));
945 ACTION("Value for field %s ignored\n", uStringText(field.str));
947 else if (field.str != NULL)
949 ERROR("Default defined for unknown field %s\n",
950 uStringText(field.str));
957 HandleKeyTypeBody(VarDef * def,
958 XkbcDescPtr xkb, KeyTypeInfo * type, KeyTypesInfo * info)
961 ExprResult tmp, field;
964 for (; def != NULL; def = (VarDef *) def->common.next)
966 if ((def->name) && (def->name->type == ExprFieldRef))
968 ok = HandleKeyTypeVar(def, xkb, info);
971 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
973 ok = SetKeyTypeField(type, xkb, field.str, arrayNdx, def->value,
980 * Process a type "XYZ" { } specification in the xkb_types section.
984 HandleKeyTypeDef(KeyTypeDef * def,
985 XkbcDescPtr xkb, unsigned merge, KeyTypesInfo * info)
990 if (def->merge != MergeDefault)
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;
1002 type.nEntries = type.szEntries = 0;
1003 type.entries = NULL;
1005 type.lvlNames = NULL;
1006 type.preserve = NULL;
1008 /* Parse the actual content. */
1009 if (!HandleKeyTypeBody(def->body, xkb, &type, info))
1015 /* now copy any appropriate map, preserve or level names from the */
1017 for (i = 0; i < info->dflt.nEntries; i++)
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))
1024 AddMapEntry(xkb, &type, dflt, False, False);
1027 if (info->dflt.preserve)
1029 PreserveInfo *dflt = info->dflt.preserve;
1032 if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
1033 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
1035 AddPreserve(xkb, &type, dflt, False, False);
1037 dflt = (PreserveInfo *) dflt->defs.next;
1040 for (i = 0; i < info->dflt.szNames; i++)
1042 if ((i < type.numLevels) && (info->dflt.lvlNames[i] != None))
1044 AddLevelName(&type, i, info->dflt.lvlNames[i], False, False);
1047 /* Now add the new keytype to the info struct */
1048 if (!AddKeyType(xkb, info, &type))
1057 * Process an xkb_types section.
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.
1064 HandleKeyTypesFile(XkbFile * file,
1065 XkbcDescPtr xkb, unsigned merge, KeyTypesInfo * info)
1069 info->name = uStringDup(file->name);
1073 switch (stmt->stmtType)
1076 if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, xkb, info,
1077 HandleKeyTypesFile))
1080 case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
1081 if (!HandleKeyTypeDef((KeyTypeDef *) stmt, xkb, merge, info))
1085 if (!HandleKeyTypeVar((VarDef *) stmt, xkb, info))
1088 case StmtVModDef: /* virtual_modifiers NumLock, ... */
1089 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1092 case StmtKeyAliasDef:
1093 ERROR("Key type files may not include other declarations\n");
1094 ACTION("Ignoring definition of key alias\n");
1097 case StmtKeycodeDef:
1098 ERROR("Key type files may not include other declarations\n");
1099 ACTION("Ignoring definition of key name\n");
1103 ERROR("Key type files may not include other declarations\n");
1104 ACTION("Ignoring definition of symbol interpretation\n");
1108 WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
1113 if (info->errorCount > 10)
1116 ERROR("Too many errors\n");
1118 ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
1126 CopyDefToKeyType(XkbcDescPtr xkb, XkbKeyTypePtr type, KeyTypeInfo * def)
1131 for (pre = def->preserve; pre != NULL;
1132 pre = (PreserveInfo *) pre->defs.next)
1134 XkbKTMapEntryPtr match;
1135 XkbKTMapEntryRec tmp;
1136 tmp.mods.real_mods = pre->indexMods;
1137 tmp.mods.vmods = pre->indexVMods;
1139 AddMapEntry(xkb, def, &tmp, False, False);
1140 match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1143 WSGO("Couldn't find matching entry for preserve\n");
1144 ACTION("Aborting\n");
1147 pre->matchingMapIndex = match - def->entries;
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;
1156 type->preserve = uTypedCalloc(type->map_count, XkbModsRec);
1157 if (!type->preserve)
1159 WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1160 ACTION("Preserve setting for type %s lost\n",
1161 XkbcAtomText(def->name));
1165 pre = def->preserve;
1166 for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
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;
1176 type->preserve = NULL;
1177 type->name = (Atom) def->name;
1178 if (def->szNames > 0)
1180 type->level_names = uTypedCalloc(def->numLevels, Atom);
1182 /* assert def->szNames<=def->numLevels */
1183 for (i = 0; i < def->szNames; i++)
1185 type->level_names[i] = (Atom) def->lvlNames[i];
1190 type->level_names = NULL;
1193 def->nEntries = def->szEntries = 0;
1194 def->entries = NULL;
1195 return XkbcComputeEffectiveMap(xkb, type, NULL);
1199 CompileKeyTypes(XkbFile *file, XkbcDescPtr xkb, unsigned merge)
1203 InitKeyTypesInfo(&info, xkb, NULL);
1204 info.fileID = file->id;
1205 HandleKeyTypesFile(file, xkb, merge, &info);
1207 if (info.errorCount == 0)
1210 register KeyTypeInfo *def;
1211 register XkbKeyTypePtr type, next;
1213 if (info.name != NULL)
1215 if (XkbcAllocNames(xkb, XkbTypesNameMask, 0, 0) == Success)
1216 xkb->names->types = XkbcInternAtom(info.name, False);
1219 WSGO("Couldn't allocate space for types name\n");
1220 ACTION("Name \"%s\" (from %s) NOT assigned\n",
1221 scanFile, info.name);
1225 if ((info.stdPresent & XkbOneLevelMask) == 0)
1227 if ((info.stdPresent & XkbTwoLevelMask) == 0)
1229 if ((info.stdPresent & XkbKeypadMask) == 0)
1231 if ((info.stdPresent & XkbAlphabeticMask) == 0)
1233 if (XkbcAllocClientMap(xkb, XkbKeyTypesMask, i) != Success)
1235 WSGO("Couldn't allocate client map\n");
1236 ACTION("Exiting\n");
1239 xkb->map->num_types = i;
1240 if (XkbAllRequiredTypes & (~info.stdPresent))
1242 unsigned missing, keypadVMod;
1244 missing = XkbAllRequiredTypes & (~info.stdPresent);
1245 keypadVMod = FindKeypadVMod(xkb);
1246 if (XkbcInitCanonicalKeyTypes(xkb, missing, keypadVMod) != Success)
1248 WSGO("Couldn't initialize canonical key types\n");
1249 ACTION("Exiting\n");
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;
1261 next = &xkb->map->types[XkbLastRequiredType + 1];
1262 for (i = 0, def = info.types; i < info.nTypes; i++)
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];
1274 DeleteLevel1MapEntries(def);
1275 if (!CopyDefToKeyType(xkb, type, def))
1277 def = (KeyTypeInfo *) def->defs.next;