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 ********************************************************/
36 typedef struct _PreserveInfo
39 short matchingMapIndex;
40 unsigned char indexMods;
41 unsigned char preMods;
42 unsigned short indexVMods;
43 unsigned short preVMods;
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)
52 typedef struct _KeyTypeInfo
63 XkbKTMapEntryPtr entries;
64 PreserveInfo *preserve;
69 typedef struct _KeyTypesInfo
83 CARD32 tok_ALPHABETIC;
86 /***====================================================================***/
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))
93 /***====================================================================***/
95 extern Bool AddMapEntry(XkbcDescPtr /* xkb */ ,
96 KeyTypeInfo * /* type */ ,
97 XkbKTMapEntryPtr /* new */ ,
102 extern Bool AddPreserve(XkbcDescPtr /* xkb */ ,
103 KeyTypeInfo * /* type */ ,
104 PreserveInfo * /* new */ ,
109 extern Bool AddLevelName(KeyTypeInfo * /* type */ ,
110 unsigned /* level */ ,
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)
123 XkbcAtomText((t)->name)
124 #define TypeMaskTxt(t, x) \
125 XkbcVModMaskText((x), (t)->mask, (t)->vmask)
127 /***====================================================================***/
130 InitKeyTypesInfo(KeyTypesInfo * info, XkbcDescPtr xkb, KeyTypesInfo * from)
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;
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;
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);
158 info->dflt = from->dflt;
159 if (from->dflt.entries)
161 info->dflt.entries = uTypedCalloc(from->dflt.szEntries,
163 if (info->dflt.entries)
165 unsigned sz = from->dflt.nEntries * sizeof(XkbKTMapEntryRec);
166 memcpy(info->dflt.entries, from->dflt.entries, sz);
169 if (from->dflt.lvlNames)
171 info->dflt.lvlNames = uTypedCalloc(from->dflt.szNames, CARD32);
172 if (info->dflt.lvlNames)
174 register unsigned sz = from->dflt.szNames * sizeof(CARD32);
175 memcpy(info->dflt.lvlNames, from->dflt.lvlNames, sz);
178 if (from->dflt.preserve)
180 PreserveInfo *old, *new, *last;
182 old = from->dflt.preserve;
183 for (; old; old = (PreserveInfo *) old->defs.next)
185 new = uTypedAlloc(PreserveInfo);
189 new->defs.next = NULL;
191 last->defs.next = (CommonInfo *) new;
193 info->dflt.preserve = new;
202 FreeKeyTypeInfo(KeyTypeInfo * type)
204 if (type->entries != NULL)
206 uFree(type->entries);
207 type->entries = NULL;
209 if (type->lvlNames != NULL)
211 uFree(type->lvlNames);
212 type->lvlNames = NULL;
214 if (type->preserve != NULL)
216 ClearCommonInfo(&type->preserve->defs);
217 type->preserve = NULL;
223 FreeKeyTypesInfo(KeyTypesInfo * info)
230 register KeyTypeInfo *type;
231 for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
233 FreeKeyTypeInfo(type);
235 info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs);
237 FreeKeyTypeInfo(&info->dflt);
242 NextKeyType(KeyTypesInfo * info)
246 type = uTypedAlloc(KeyTypeInfo);
249 bzero(type, sizeof(KeyTypeInfo));
250 type->defs.fileID = info->fileID;
251 info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs,
252 (CommonInfo *) type);
259 FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
263 for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
265 if (old->name == new->name)
272 ReportTypeBadWidth(const char *type, int has, int needs)
274 ERROR("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
275 ACTION("Illegal type definition ignored\n");
280 AddKeyType(XkbcDescPtr xkb, KeyTypesInfo * info, KeyTypeInfo * new)
284 if (new->name == tok_ONE_LEVEL)
286 if (new->numLevels > 1)
287 return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
288 info->stdPresent |= XkbOneLevelMask;
290 else if (new->name == tok_TWO_LEVEL)
292 if (new->numLevels > 2)
293 return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
294 else if (new->numLevels < 2)
296 info->stdPresent |= XkbTwoLevelMask;
298 else if (new->name == tok_ALPHABETIC)
300 if (new->numLevels > 2)
301 return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
302 else if (new->numLevels < 2)
304 info->stdPresent |= XkbAlphabeticMask;
306 else if (new->name == tok_KEYPAD)
308 if (new->numLevels > 2)
309 return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
310 else if (new->numLevels < 2)
312 info->stdPresent |= XkbKeypadMask;
315 old = FindMatchingKeyType(info, new);
319 if ((new->defs.merge == MergeReplace)
320 || (new->defs.merge == MergeOverride))
322 KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
323 if (((old->defs.fileID == new->defs.fileID)
324 && (warningLevel > 0)) || (warningLevel > 9))
326 WARN("Multiple definitions of the %s key type\n",
327 XkbcAtomText(new->name));
328 ACTION("Earlier definition ignored\n");
330 FreeKeyTypeInfo(old);
332 new->szEntries = new->nEntries = 0;
334 new->preserve = NULL;
335 new->lvlNames = NULL;
336 old->defs.next = &next->defs;
339 report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
342 WARN("Multiple definitions of the %s key type\n",
343 XkbcAtomText(new->name));
344 ACTION("Later definition ignored\n");
346 FreeKeyTypeInfo(new);
349 old = NextKeyType(info);
353 old->defs.next = NULL;
354 new->nEntries = new->szEntries = 0;
357 new->lvlNames = NULL;
358 new->preserve = NULL;
362 /***====================================================================***/
365 MergeIncludedKeyTypes(KeyTypesInfo * into,
366 KeyTypesInfo * from, unsigned merge, XkbcDescPtr xkb)
370 if (from->errorCount > 0)
372 into->errorCount += from->errorCount;
375 if (into->name == NULL)
377 into->name = from->name;
380 for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
382 if (merge != MergeDefault)
383 type->defs.merge = merge;
384 if (!AddKeyType(xkb, into, type))
387 into->stdPresent |= from->stdPresent;
391 typedef void (*FileHandler) (XkbFile * /* file */ ,
392 XkbcDescPtr /* xkb */ ,
393 unsigned /* merge */ ,
394 KeyTypesInfo * /* included */
398 HandleIncludeKeyTypes(IncludeStmt * stmt,
399 XkbcDescPtr xkb, KeyTypesInfo * info, FileHandler hndlr)
403 KeyTypesInfo included;
407 if ((stmt->file == NULL) && (stmt->map == NULL))
411 bzero(info, sizeof(KeyTypesInfo));
413 else if (ProcessIncludeFile(stmt, XkmTypesIndex, &rtrn, &newMerge))
415 InitKeyTypesInfo(&included, xkb, info);
416 included.fileID = included.dflt.defs.fileID = rtrn->id;
417 included.dflt.defs.merge = newMerge;
419 (*hndlr) (rtrn, xkb, newMerge, &included);
420 if (stmt->stmt != NULL)
422 if (included.name != NULL)
423 uFree(included.name);
424 included.name = stmt->stmt;
430 info->errorCount += 10;
433 if ((stmt->next != NULL) && (included.errorCount < 1))
437 KeyTypesInfo next_incl;
439 for (next = stmt->next; next != NULL; next = next->next)
441 if ((next->file == NULL) && (next->map == NULL))
444 MergeIncludedKeyTypes(&included, info, next->merge, xkb);
445 FreeKeyTypesInfo(info);
447 else if (ProcessIncludeFile(next, XkmTypesIndex, &rtrn, &op))
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);
458 info->errorCount += 10;
467 MergeIncludedKeyTypes(info, &included, newMerge, xkb);
468 FreeKeyTypesInfo(&included);
470 return (info->errorCount == 0);
473 /***====================================================================***/
475 static XkbKTMapEntryPtr
476 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
479 XkbKTMapEntryPtr entry;
481 for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
483 if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
490 DeleteLevel1MapEntries(KeyTypeInfo * type)
494 for (i = 0; i < type->nEntries; i++)
496 if (type->entries[i].level == 0)
498 for (n = i; n < type->nEntries - 1; n++)
500 type->entries[n] = type->entries[n + 1];
509 * Return a pointer to the next free XkbKTMapEntry, reallocating space if
512 static XkbKTMapEntryPtr
513 NextMapEntry(KeyTypeInfo * type)
515 if (type->entries == NULL)
517 type->entries = uTypedCalloc(2, XkbKTMapEntryRec);
518 if (type->entries == NULL)
520 ERROR("Couldn't allocate map entries for %s\n", TypeTxt(type));
521 ACTION("Map entries lost\n");
527 else if (type->nEntries >= type->szEntries)
529 type->szEntries *= 2;
530 type->entries = uTypedRecalloc(type->entries,
531 type->nEntries, type->szEntries,
533 if (type->entries == NULL)
535 ERROR("Couldn't reallocate map entries for %s\n", TypeTxt(type));
536 ACTION("Map entries lost\n");
540 return &type->entries[type->nEntries++];
544 AddPreserve(XkbcDescPtr xkb,
545 KeyTypeInfo * type, PreserveInfo * new, Bool clobber, Bool report)
549 old = type->preserve;
552 if ((old->indexMods != new->indexMods) ||
553 (old->indexVMods != new->indexVMods))
555 old = (PreserveInfo *) old->defs.next;
558 if ((old->preMods == new->preMods)
559 && (old->preVMods == new->preVMods))
561 if (warningLevel > 9)
563 WARN("Identical definitions for preserve[%s] in %s\n",
564 PreserveIndexTxt(xkb, old), TypeTxt(type));
569 if (report && (warningLevel > 0))
572 WARN("Multiple definitions for preserve[%s] in %s\n",
573 PreserveIndexTxt(xkb, old), TypeTxt(type));
576 str = PreserveTxt(xkb, new);
578 str = PreserveTxt(xkb, old);
579 ACTION("Using %s, ", str);
581 str = PreserveTxt(xkb, old);
583 str = PreserveTxt(xkb, new);
584 INFO("ignoring %s\n", str);
588 old->preMods = new->preMods;
589 old->preVMods = new->preVMods;
593 old = uTypedAlloc(PreserveInfo);
596 WSGO("Couldn't allocate preserve in %s\n", TypeTxt(type));
597 ACTION("Preserve[%s] lost\n", PreserveIndexTxt(xkb, old));
601 old->matchingMapIndex = -1;
603 (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
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
612 * @param clobber Overwrite existing entry.
613 * @param report True if a warning is to be printed on.
616 AddMapEntry(XkbcDescPtr xkb,
618 XkbKTMapEntryPtr new, Bool clobber, Bool report)
620 XkbKTMapEntryPtr old;
623 FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
625 if (report && (old->level != new->level))
627 unsigned use, ignore;
630 use = new->level + 1;
631 ignore = old->level + 1;
635 use = old->level + 1;
636 ignore = new->level + 1;
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);
642 else if (warningLevel > 9)
644 WARN("Multiple occurences of map[%s]= %d in %s\n",
645 MapEntryTxt(xkb, new), new->level + 1, TypeTxt(type));
650 old->level = new->level;
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)
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;
668 static LookupEntry lnames[] = {
681 SetMapEntry(KeyTypeInfo * type,
682 XkbcDescPtr xkb, ExprDef * arrayNdx, ExprDef * value)
685 XkbKTMapEntryRec entry;
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))
696 if (warningLevel > 0)
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));
705 entry.mods.real_mods &= type->mask;
706 entry.mods.vmods &= type->vmask;
708 if (!ExprResolveInteger(value, &rtrn, SimpleLookup, (char *) lnames))
710 ERROR("Level specifications in a key type must be integer\n");
711 ACTION("Ignoring malformed level specification\n");
714 if ((rtrn.ival < 1) || (rtrn.ival > XkbMaxShiftLevel + 1))
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));
722 entry.level = rtrn.ival - 1;
723 return AddMapEntry(xkb, type, &entry, True, True);
727 SetPreserve(KeyTypeInfo * type,
728 XkbcDescPtr xkb, ExprDef * arrayNdx, ExprDef * value)
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)))
743 if (warningLevel > 0)
745 WARN("Preserve for modifiers not used by the %s type\n",
747 ACTION("Index %s converted to ", PreserveIndexTxt(xkb, &new));
749 new.indexMods &= type->mask;
750 new.indexVMods &= type->vmask;
751 if (warningLevel > 0)
752 INFO("%s\n", PreserveIndexTxt(xkb, &new));
754 if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (char *) xkb))
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));
761 new.preMods = rtrn.uval & 0xff;
762 new.preVMods = (rtrn.uval >> 16) & 0xffff;
763 if ((new.preMods & (~new.indexMods))
764 || (new.preVMods && (~new.indexVMods)))
766 if (warningLevel > 0)
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));
772 new.preMods &= new.indexMods;
773 new.preVMods &= new.indexVMods;
774 if (warningLevel > 0)
776 INFO("%s\n", PreserveIndexTxt(xkb, &new));
779 return AddPreserve(xkb, type, &new, True, True);
782 /***====================================================================***/
785 AddLevelName(KeyTypeInfo * type,
786 unsigned level, CARD32 name, Bool clobber, Bool report)
788 if ((type->lvlNames == NULL) || (type->szNames <= level))
791 uTypedRecalloc(type->lvlNames, type->szNames, level + 1, CARD32);
792 if (type->lvlNames == NULL)
794 ERROR("Couldn't allocate level names for type %s\n",
796 ACTION("Level names lost\n");
800 type->szNames = level + 1;
802 else if (type->lvlNames[level] == name)
804 if (warningLevel > 9)
806 WARN("Duplicate names for level %d of key type %s\n",
807 level + 1, TypeTxt(type));
812 else if (type->lvlNames[level] != None)
814 if (warningLevel > 0)
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));
822 ACTION("Using %s, ignoring %s\n", new, old);
824 ACTION("Using %s, ignoring %s\n", old, new);
829 if (level >= type->numLevels)
830 type->numLevels = level + 1;
831 type->lvlNames[level] = name;
836 SetLevelName(KeyTypeInfo * type, ExprDef * arrayNdx, ExprDef * value)
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))
848 ERROR("Level name %d out of range (1..%d) in key type %s\n",
850 XkbMaxShiftLevel + 1,
851 XkbcAtomText(type->name));
852 ACTION("Ignoring illegal level name definition\n");
855 level = rtrn.ival - 1;
856 if (!ExprResolveString(value, &rtrn, NULL, NULL))
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");
863 level_name = XkbcInternAtom(rtrn.str, False);
865 return AddLevelName(type, level, level_name, True, True);
868 /***====================================================================***/
871 * Parses the fields in a type "..." { } description.
873 * @param field The field to parse (e.g. modifiers, map, level_name)
876 SetKeyTypeField(KeyTypeInfo * type,
879 ExprDef * arrayNdx, ExprDef * value, KeyTypesInfo * info)
883 if (uStrCaseCmp(field, "modifiers") == 0)
885 unsigned mods, vmods;
886 if (arrayNdx != NULL)
888 WARN("The modifiers field of a key type is not an array\n");
889 ACTION("Illegal array subscript ignored\n");
891 /* get modifier mask for current type */
892 if (!ExprResolveModMask(value, &tmp, LookupVModMask, (char *) xkb))
894 ERROR("Key type mask field must be a modifier mask\n");
895 ACTION("Key type definition ignored\n");
898 mods = tmp.uval & 0xff; /* core mods */
899 vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
900 if (type->defs.defined & _KT_Mask)
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));
910 type->defs.defined |= _KT_Mask;
913 else if (uStrCaseCmp(field, "map") == 0)
915 type->defs.defined |= _KT_Map;
916 return SetMapEntry(type, xkb, arrayNdx, value);
918 else if (uStrCaseCmp(field, "preserve") == 0)
920 type->defs.defined |= _KT_Preserve;
921 return SetPreserve(type, xkb, arrayNdx, value);
923 else if ((uStrCaseCmp(field, "levelname") == 0) ||
924 (uStrCaseCmp(field, "level_name") == 0))
926 type->defs.defined |= _KT_LevelNames;
927 return SetLevelName(type, arrayNdx, value);
929 ERROR("Unknown field %s in key type %s\n", field, TypeTxt(type));
930 ACTION("Definition ignored\n");
935 HandleKeyTypeVar(VarDef * stmt, XkbcDescPtr xkb, KeyTypesInfo * info)
937 ExprResult elem, field;
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,
945 if (elem.str != NULL)
947 ERROR("Default for unknown element %s\n", uStringText(elem.str));
948 ACTION("Value for field %s ignored\n", uStringText(field.str));
950 else if (field.str != NULL)
952 ERROR("Default defined for unknown field %s\n",
953 uStringText(field.str));
960 HandleKeyTypeBody(VarDef * def,
961 XkbcDescPtr xkb, KeyTypeInfo * type, KeyTypesInfo * info)
964 ExprResult tmp, field;
967 for (; def != NULL; def = (VarDef *) def->common.next)
969 if ((def->name) && (def->name->type == ExprFieldRef))
971 ok = HandleKeyTypeVar(def, xkb, info);
974 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
976 ok = SetKeyTypeField(type, xkb, field.str, arrayNdx, def->value,
983 * Process a type "XYZ" { } specification in the xkb_types section.
987 HandleKeyTypeDef(KeyTypeDef * def,
988 XkbcDescPtr xkb, unsigned merge, KeyTypesInfo * info)
993 if (def->merge != MergeDefault)
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;
1005 type.nEntries = type.szEntries = 0;
1006 type.entries = NULL;
1008 type.lvlNames = NULL;
1009 type.preserve = NULL;
1011 /* Parse the actual content. */
1012 if (!HandleKeyTypeBody(def->body, xkb, &type, info))
1018 /* now copy any appropriate map, preserve or level names from the */
1020 for (i = 0; i < info->dflt.nEntries; i++)
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))
1027 AddMapEntry(xkb, &type, dflt, False, False);
1030 if (info->dflt.preserve)
1032 PreserveInfo *dflt = info->dflt.preserve;
1035 if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
1036 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
1038 AddPreserve(xkb, &type, dflt, False, False);
1040 dflt = (PreserveInfo *) dflt->defs.next;
1043 for (i = 0; i < info->dflt.szNames; i++)
1045 if ((i < type.numLevels) && (info->dflt.lvlNames[i] != None))
1047 AddLevelName(&type, i, info->dflt.lvlNames[i], False, False);
1050 /* Now add the new keytype to the info struct */
1051 if (!AddKeyType(xkb, info, &type))
1060 * Process an xkb_types section.
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.
1067 HandleKeyTypesFile(XkbFile * file,
1068 XkbcDescPtr xkb, unsigned merge, KeyTypesInfo * info)
1072 info->name = _XkbDupString(file->name);
1076 switch (stmt->stmtType)
1079 if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, xkb, info,
1080 HandleKeyTypesFile))
1083 case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
1084 if (!HandleKeyTypeDef((KeyTypeDef *) stmt, xkb, merge, info))
1088 if (!HandleKeyTypeVar((VarDef *) stmt, xkb, info))
1091 case StmtVModDef: /* virtual_modifiers NumLock, ... */
1092 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1095 case StmtKeyAliasDef:
1096 ERROR("Key type files may not include other declarations\n");
1097 ACTION("Ignoring definition of key alias\n");
1100 case StmtKeycodeDef:
1101 ERROR("Key type files may not include other declarations\n");
1102 ACTION("Ignoring definition of key name\n");
1106 ERROR("Key type files may not include other declarations\n");
1107 ACTION("Ignoring definition of symbol interpretation\n");
1111 WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
1116 if (info->errorCount > 10)
1119 ERROR("Too many errors\n");
1121 ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
1129 CopyDefToKeyType(XkbcDescPtr xkb, XkbcKeyTypePtr type, KeyTypeInfo * def)
1134 for (pre = def->preserve; pre != NULL;
1135 pre = (PreserveInfo *) pre->defs.next)
1137 XkbKTMapEntryPtr match;
1138 XkbKTMapEntryRec tmp;
1139 tmp.mods.real_mods = pre->indexMods;
1140 tmp.mods.vmods = pre->indexVMods;
1142 AddMapEntry(xkb, def, &tmp, False, False);
1143 match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1146 WSGO("Couldn't find matching entry for preserve\n");
1147 ACTION("Aborting\n");
1150 pre->matchingMapIndex = match - def->entries;
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;
1159 type->preserve = uTypedCalloc(type->map_count, XkbModsRec);
1160 if (!type->preserve)
1162 WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1163 ACTION("Preserve setting for type %s lost\n",
1164 XkbcAtomText(def->name));
1168 pre = def->preserve;
1169 for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
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;
1179 type->preserve = NULL;
1180 type->name = (CARD32) def->name;
1181 if (def->szNames > 0)
1183 type->level_names = uTypedCalloc(def->numLevels, CARD32);
1185 /* assert def->szNames<=def->numLevels */
1186 for (i = 0; i < def->szNames; i++)
1188 type->level_names[i] = (CARD32) def->lvlNames[i];
1193 type->level_names = NULL;
1196 def->nEntries = def->szEntries = 0;
1197 def->entries = NULL;
1198 return XkbcComputeEffectiveMap(xkb, type, NULL);
1202 CompileKeyTypes(XkbFile *file, XkbcDescPtr xkb, unsigned merge)
1206 InitKeyTypesInfo(&info, xkb, NULL);
1207 info.fileID = file->id;
1208 HandleKeyTypesFile(file, xkb, merge, &info);
1210 if (info.errorCount == 0)
1213 register KeyTypeInfo *def;
1214 register XkbcKeyTypePtr type, next;
1216 if (info.name != NULL)
1218 if (XkbcAllocNames(xkb, XkbTypesNameMask, 0, 0) == Success)
1219 xkb->names->types = XkbcInternAtom(info.name, False);
1222 WSGO("Couldn't allocate space for types name\n");
1223 ACTION("Name \"%s\" (from %s) NOT assigned\n",
1224 scanFile, info.name);
1228 if ((info.stdPresent & XkbOneLevelMask) == 0)
1230 if ((info.stdPresent & XkbTwoLevelMask) == 0)
1232 if ((info.stdPresent & XkbKeypadMask) == 0)
1234 if ((info.stdPresent & XkbAlphabeticMask) == 0)
1236 if (XkbcAllocClientMap(xkb, XkbKeyTypesMask, i) != Success)
1238 WSGO("Couldn't allocate client map\n");
1241 xkb->map->num_types = i;
1242 if (XkbAllRequiredTypes & (~info.stdPresent))
1244 unsigned missing, keypadVMod;
1246 missing = XkbAllRequiredTypes & (~info.stdPresent);
1247 keypadVMod = FindKeypadVMod(xkb);
1248 if (XkbcInitCanonicalKeyTypes(xkb, missing, keypadVMod) != Success)
1250 WSGO("Couldn't initialize canonical key types\n");
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;
1262 next = &xkb->map->types[XkbLastRequiredType + 1];
1263 for (i = 0, def = info.types; i < info.nTypes; i++)
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];
1275 DeleteLevel1MapEntries(def);
1276 if (!CopyDefToKeyType(xkb, type, def))
1278 def = (KeyTypeInfo *) def->defs.next;