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 ********************************************************/
27 #include "xkbcomp-priv.h"
28 #include "parseutils.h"
31 typedef struct _PreserveInfo
34 short matchingMapIndex;
35 unsigned char indexMods;
36 unsigned char preMods;
37 unsigned short indexVMods;
38 unsigned short preVMods;
41 #define _KT_Name (1<<0)
42 #define _KT_Mask (1<<1)
43 #define _KT_Map (1<<2)
44 #define _KT_Preserve (1<<3)
45 #define _KT_LevelNames (1<<4)
47 typedef struct _KeyTypeInfo
58 struct xkb_kt_map_entry * entries;
59 PreserveInfo *preserve;
64 typedef struct _KeyTypesInfo
76 static xkb_atom_t tok_ONE_LEVEL;
77 static xkb_atom_t tok_TWO_LEVEL;
78 static xkb_atom_t tok_ALPHABETIC;
79 static xkb_atom_t tok_KEYPAD;
81 /***====================================================================***/
83 #define ReportTypeShouldBeArray(keymap, t, f) \
84 ReportShouldBeArray("key type", (f), TypeTxt((keymap), (t)))
85 #define ReportTypeBadType(keymap, t, f, w) \
86 ReportBadType("key type", (f), TypeTxt((keymap), (t)), (w))
88 /***====================================================================***/
90 #define MapEntryTxt(x, e) \
91 XkbcVModMaskText((x), (e)->mods.real_mods, (e)->mods.vmods)
92 #define PreserveIndexTxt(x, p) \
93 XkbcVModMaskText((x), (p)->indexMods, (p)->indexVMods)
94 #define PreserveTxt(x, p) \
95 XkbcVModMaskText((x), (p)->preMods, (p)->preVMods)
96 #define TypeTxt(keymap, t) \
97 xkb_atom_text((keymap)->ctx, (t)->name)
98 #define TypeMaskTxt(t, x) \
99 XkbcVModMaskText((x), (t)->mask, (t)->vmask)
101 /***====================================================================***/
104 InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
107 tok_ONE_LEVEL = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
108 tok_TWO_LEVEL = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
109 tok_ALPHABETIC = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
110 tok_KEYPAD = xkb_atom_intern(keymap->ctx, "KEYPAD");
111 info->name = strdup("default");
112 info->errorCount = 0;
113 info->stdPresent = 0;
116 info->dflt.defs.defined = 0;
117 info->dflt.defs.fileID = 0;
118 info->dflt.defs.merge = MergeOverride;
119 info->dflt.defs.next = NULL;
120 info->dflt.name = XKB_ATOM_NONE;
122 info->dflt.vmask = 0;
123 info->dflt.groupInfo = false;
124 info->dflt.numLevels = 1;
125 info->dflt.nEntries = info->dflt.szEntries = 0;
126 info->dflt.entries = NULL;
127 info->dflt.szNames = 0;
128 info->dflt.lvlNames = NULL;
129 info->dflt.preserve = NULL;
130 InitVModInfo(&info->vmods, keymap);
133 info->dflt = from->dflt;
134 if (from->dflt.entries)
136 info->dflt.entries = uTypedCalloc(from->dflt.szEntries,
137 struct xkb_kt_map_entry);
138 if (info->dflt.entries)
140 unsigned sz = from->dflt.nEntries * sizeof(struct xkb_kt_map_entry);
141 memcpy(info->dflt.entries, from->dflt.entries, sz);
144 if (from->dflt.lvlNames)
146 info->dflt.lvlNames = uTypedCalloc(from->dflt.szNames, xkb_atom_t);
147 if (info->dflt.lvlNames)
149 unsigned sz = from->dflt.szNames * sizeof(xkb_atom_t);
150 memcpy(info->dflt.lvlNames, from->dflt.lvlNames, sz);
153 if (from->dflt.preserve)
155 PreserveInfo *old, *new, *last;
157 old = from->dflt.preserve;
158 for (; old; old = (PreserveInfo *) old->defs.next)
160 new = uTypedAlloc(PreserveInfo);
164 new->defs.next = NULL;
166 last->defs.next = (CommonInfo *) new;
168 info->dflt.preserve = new;
176 FreeKeyTypeInfo(KeyTypeInfo * type)
179 type->entries = NULL;
180 free(type->lvlNames);
181 type->lvlNames = NULL;
182 if (type->preserve != NULL)
184 ClearCommonInfo(&type->preserve->defs);
185 type->preserve = NULL;
190 FreeKeyTypesInfo(KeyTypesInfo * info)
197 for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
199 FreeKeyTypeInfo(type);
201 info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs);
203 FreeKeyTypeInfo(&info->dflt);
207 NextKeyType(KeyTypesInfo * info)
211 type = uTypedAlloc(KeyTypeInfo);
214 memset(type, 0, sizeof(KeyTypeInfo));
215 type->defs.fileID = info->fileID;
216 info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs,
217 (CommonInfo *) type);
224 FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
228 for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
230 if (old->name == new->name)
237 ReportTypeBadWidth(const char *type, int has, int needs)
239 ERROR("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
240 ACTION("Illegal type definition ignored\n");
245 AddKeyType(struct xkb_keymap *keymap, KeyTypesInfo *info, KeyTypeInfo *new)
249 if (new->name == tok_ONE_LEVEL)
251 if (new->numLevels > 1)
252 return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
253 info->stdPresent |= XkbOneLevelMask;
255 else if (new->name == tok_TWO_LEVEL)
257 if (new->numLevels > 2)
258 return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
259 else if (new->numLevels < 2)
261 info->stdPresent |= XkbTwoLevelMask;
263 else if (new->name == tok_ALPHABETIC)
265 if (new->numLevels > 2)
266 return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
267 else if (new->numLevels < 2)
269 info->stdPresent |= XkbAlphabeticMask;
271 else if (new->name == tok_KEYPAD)
273 if (new->numLevels > 2)
274 return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
275 else if (new->numLevels < 2)
277 info->stdPresent |= XkbKeypadMask;
280 old = FindMatchingKeyType(info, new);
284 if ((new->defs.merge == MergeReplace)
285 || (new->defs.merge == MergeOverride))
287 KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
288 if (((old->defs.fileID == new->defs.fileID)
289 && (warningLevel > 0)) || (warningLevel > 9))
291 WARN("Multiple definitions of the %s key type\n",
292 xkb_atom_text(keymap->ctx, new->name));
293 ACTION("Earlier definition ignored\n");
295 FreeKeyTypeInfo(old);
297 new->szEntries = new->nEntries = 0;
299 new->preserve = NULL;
300 new->lvlNames = NULL;
301 old->defs.next = &next->defs;
304 report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
307 WARN("Multiple definitions of the %s key type\n",
308 xkb_atom_text(keymap->ctx, new->name));
309 ACTION("Later definition ignored\n");
311 FreeKeyTypeInfo(new);
314 old = NextKeyType(info);
318 old->defs.next = NULL;
319 new->nEntries = new->szEntries = 0;
322 new->lvlNames = NULL;
323 new->preserve = NULL;
327 /***====================================================================***/
330 MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
331 unsigned merge, struct xkb_keymap *keymap)
335 if (from->errorCount > 0)
337 into->errorCount += from->errorCount;
340 if (into->name == NULL)
342 into->name = from->name;
345 for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
347 if (merge != MergeDefault)
348 type->defs.merge = merge;
349 if (!AddKeyType(keymap, into, type))
352 into->stdPresent |= from->stdPresent;
356 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
357 unsigned merge, KeyTypesInfo *info);
360 HandleIncludeKeyTypes(IncludeStmt *stmt, struct xkb_keymap *keymap,
365 KeyTypesInfo included;
369 if ((stmt->file == NULL) && (stmt->map == NULL))
373 memset(info, 0, sizeof(KeyTypesInfo));
375 else if (ProcessIncludeFile(keymap->ctx, stmt, XkmTypesIndex, &rtrn,
378 InitKeyTypesInfo(&included, keymap, info);
379 included.fileID = included.dflt.defs.fileID = rtrn->id;
380 included.dflt.defs.merge = newMerge;
382 HandleKeyTypesFile(rtrn, keymap, newMerge, &included);
383 if (stmt->stmt != NULL)
386 included.name = stmt->stmt;
393 info->errorCount += 10;
396 if ((stmt->next != NULL) && (included.errorCount < 1))
400 KeyTypesInfo next_incl;
402 for (next = stmt->next; next != NULL; next = next->next)
404 if ((next->file == NULL) && (next->map == NULL))
407 MergeIncludedKeyTypes(&included, info, next->merge, keymap);
408 FreeKeyTypesInfo(info);
410 else if (ProcessIncludeFile(keymap->ctx, next, XkmTypesIndex,
413 InitKeyTypesInfo(&next_incl, keymap, &included);
414 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
415 next_incl.dflt.defs.merge = op;
416 HandleKeyTypesFile(rtrn, keymap, op, &next_incl);
417 MergeIncludedKeyTypes(&included, &next_incl, op, keymap);
418 FreeKeyTypesInfo(&next_incl);
423 info->errorCount += 10;
424 FreeKeyTypesInfo(&included);
433 MergeIncludedKeyTypes(info, &included, newMerge, keymap);
434 FreeKeyTypesInfo(&included);
436 return (info->errorCount == 0);
439 /***====================================================================***/
441 static struct xkb_kt_map_entry *
442 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
445 struct xkb_kt_map_entry * entry;
447 for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
449 if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
456 DeleteLevel1MapEntries(KeyTypeInfo * type)
460 for (i = 0; i < type->nEntries; i++)
462 if (type->entries[i].level == 0)
464 for (n = i; n < type->nEntries - 1; n++)
466 type->entries[n] = type->entries[n + 1];
474 * Return a pointer to the next free XkbcKTMapEntry, reallocating space if
477 static struct xkb_kt_map_entry *
478 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
480 if (type->entries == NULL)
482 type->entries = uTypedCalloc(2, struct xkb_kt_map_entry);
483 if (type->entries == NULL)
485 ERROR("Couldn't allocate map entries for %s\n",
486 TypeTxt(keymap, type));
487 ACTION("Map entries lost\n");
493 else if (type->nEntries >= type->szEntries)
495 type->szEntries *= 2;
496 type->entries = uTypedRecalloc(type->entries,
497 type->nEntries, type->szEntries,
498 struct xkb_kt_map_entry);
499 if (type->entries == NULL)
501 ERROR("Couldn't reallocate map entries for %s\n",
502 TypeTxt(keymap, type));
503 ACTION("Map entries lost\n");
507 return &type->entries[type->nEntries++];
511 AddPreserve(struct xkb_keymap *keymap, KeyTypeInfo *type,
512 PreserveInfo *new, bool clobber, bool report)
516 old = type->preserve;
519 if ((old->indexMods != new->indexMods) ||
520 (old->indexVMods != new->indexVMods))
522 old = (PreserveInfo *) old->defs.next;
525 if ((old->preMods == new->preMods)
526 && (old->preVMods == new->preVMods))
528 if (warningLevel > 9)
530 WARN("Identical definitions for preserve[%s] in %s\n",
531 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
536 if (report && (warningLevel > 0))
539 WARN("Multiple definitions for preserve[%s] in %s\n",
540 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
543 str = PreserveTxt(keymap, new);
545 str = PreserveTxt(keymap, old);
546 ACTION("Using %s, ", str);
548 str = PreserveTxt(keymap, old);
550 str = PreserveTxt(keymap, new);
551 INFO("ignoring %s\n", str);
555 old->preMods = new->preMods;
556 old->preVMods = new->preVMods;
560 old = uTypedAlloc(PreserveInfo);
563 WSGO("Couldn't allocate preserve in %s\n", TypeTxt(keymap, type));
564 ACTION("Preserve[%s] lost\n", PreserveIndexTxt(keymap, new));
568 old->matchingMapIndex = -1;
570 (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
575 * Add a new KTMapEntry to the given key type. If an entry with the same mods
576 * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
579 * @param clobber Overwrite existing entry.
580 * @param report true if a warning is to be printed on.
583 AddMapEntry(struct xkb_keymap *keymap, KeyTypeInfo *type,
584 struct xkb_kt_map_entry *new, bool clobber, bool report)
586 struct xkb_kt_map_entry * old;
589 FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
591 if (report && (old->level != new->level))
593 unsigned use, ignore;
596 use = new->level + 1;
597 ignore = old->level + 1;
601 use = old->level + 1;
602 ignore = new->level + 1;
604 WARN("Multiple map entries for %s in %s\n",
605 MapEntryTxt(keymap, new), TypeTxt(keymap, type));
606 ACTION("Using %d, ignoring %d\n", use, ignore);
608 else if (warningLevel > 9)
610 WARN("Multiple occurences of map[%s]= %d in %s\n",
611 MapEntryTxt(keymap, new), new->level + 1,
612 TypeTxt(keymap, type));
617 old->level = new->level;
620 if ((old = NextMapEntry(keymap, type)) == NULL)
621 return false; /* allocation failure, already reported */
622 if (new->level >= type->numLevels)
623 type->numLevels = new->level + 1;
624 if (new->mods.vmods == 0)
628 old->mods.mask = new->mods.real_mods;
629 old->mods.real_mods = new->mods.real_mods;
630 old->mods.vmods = new->mods.vmods;
631 old->level = new->level;
636 SetMapEntry(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
640 struct xkb_kt_map_entry entry;
642 if (arrayNdx == NULL)
643 return ReportTypeShouldBeArray(keymap, type, "map entry");
644 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
645 return ReportTypeBadType(keymap, type, "map entry", "modifier mask");
646 entry.mods.real_mods = rtrn.uval & 0xff; /* modifiers < 512 */
647 entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
648 if ((entry.mods.real_mods & (~type->mask)) ||
649 ((entry.mods.vmods & (~type->vmask)) != 0))
651 if (warningLevel > 0)
653 WARN("Map entry for unused modifiers in %s\n", TypeTxt(keymap, type));
654 ACTION("Using %s instead of ",
655 XkbcVModMaskText(keymap,
656 entry.mods.real_mods & type->mask,
657 entry.mods.vmods & type->vmask));
658 INFO("%s\n", MapEntryTxt(keymap, &entry));
660 entry.mods.real_mods &= type->mask;
661 entry.mods.vmods &= type->vmask;
663 if (!ExprResolveLevel(keymap->ctx, value, &rtrn))
665 ERROR("Level specifications in a key type must be integer\n");
666 ACTION("Ignoring malformed level specification\n");
669 entry.level = rtrn.ival - 1;
670 return AddMapEntry(keymap, type, &entry, true, true);
674 SetPreserve(KeyTypeInfo *type, struct xkb_keymap *keymap,
675 ExprDef *arrayNdx, ExprDef *value)
680 if (arrayNdx == NULL)
681 return ReportTypeShouldBeArray(keymap, type, "preserve entry");
682 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
683 return ReportTypeBadType(keymap, type, "preserve entry",
685 new.defs = type->defs;
686 new.defs.next = NULL;
687 new.indexMods = rtrn.uval & 0xff;
688 new.indexVMods = (rtrn.uval >> 8) & 0xffff;
689 if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
691 if (warningLevel > 0)
693 WARN("Preserve for modifiers not used by the %s type\n",
694 TypeTxt(keymap, type));
695 ACTION("Index %s converted to ", PreserveIndexTxt(keymap, &new));
697 new.indexMods &= type->mask;
698 new.indexVMods &= type->vmask;
699 if (warningLevel > 0)
700 INFO("%s\n", PreserveIndexTxt(keymap, &new));
702 if (!ExprResolveVModMask(value, &rtrn, keymap))
704 ERROR("Preserve value in a key type is not a modifier mask\n");
705 ACTION("Ignoring preserve[%s] in type %s\n",
706 PreserveIndexTxt(keymap, &new), TypeTxt(keymap, type));
709 new.preMods = rtrn.uval & 0xff;
710 new.preVMods = (rtrn.uval >> 16) & 0xffff;
711 if ((new.preMods & (~new.indexMods))
712 || (new.preVMods & (~new.indexVMods)))
714 if (warningLevel > 0)
716 WARN("Illegal value for preserve[%s] in type %s\n",
717 PreserveTxt(keymap, &new), TypeTxt(keymap, type));
718 ACTION("Converted %s to ", PreserveIndexTxt(keymap, &new));
720 new.preMods &= new.indexMods;
721 new.preVMods &= new.indexVMods;
722 if (warningLevel > 0)
724 INFO("%s\n", PreserveIndexTxt(keymap, &new));
727 return AddPreserve(keymap, type, &new, true, true);
730 /***====================================================================***/
733 AddLevelName(struct xkb_keymap *keymap, KeyTypeInfo *type,
734 unsigned level, xkb_atom_t name, bool clobber)
736 if ((type->lvlNames == NULL) || (type->szNames <= level))
739 uTypedRecalloc(type->lvlNames, type->szNames, level + 1, xkb_atom_t);
740 if (type->lvlNames == NULL)
742 ERROR("Couldn't allocate level names for type %s\n",
743 TypeTxt(keymap, type));
744 ACTION("Level names lost\n");
748 type->szNames = level + 1;
750 else if (type->lvlNames[level] == name)
752 if (warningLevel > 9)
754 WARN("Duplicate names for level %d of key type %s\n",
755 level + 1, TypeTxt(keymap, type));
760 else if (type->lvlNames[level] != XKB_ATOM_NONE)
762 if (warningLevel > 0)
764 const char *old, *new;
765 old = xkb_atom_text(keymap->ctx, type->lvlNames[level]);
766 new = xkb_atom_text(keymap->ctx, name);
767 WARN("Multiple names for level %d of key type %s\n",
768 level + 1, TypeTxt(keymap, type));
770 ACTION("Using %s, ignoring %s\n", new, old);
772 ACTION("Using %s, ignoring %s\n", old, new);
777 if (level >= type->numLevels)
778 type->numLevels = level + 1;
779 type->lvlNames[level] = name;
784 SetLevelName(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
789 xkb_atom_t level_name;
791 if (arrayNdx == NULL)
792 return ReportTypeShouldBeArray(keymap, type, "level name");
793 if (!ExprResolveLevel(keymap->ctx, arrayNdx, &rtrn))
794 return ReportTypeBadType(keymap, type, "level name", "integer");
795 level = rtrn.ival - 1;
796 if (!ExprResolveString(keymap->ctx, value, &rtrn))
798 ERROR("Non-string name for level %d in key type %s\n", level + 1,
799 xkb_atom_text(keymap->ctx, type->name));
800 ACTION("Ignoring illegal level name definition\n");
803 level_name = xkb_atom_intern(keymap->ctx, rtrn.str);
805 return AddLevelName(keymap, type, level, level_name, true);
808 /***====================================================================***/
811 * Parses the fields in a type "..." { } description.
813 * @param field The field to parse (e.g. modifiers, map, level_name)
816 SetKeyTypeField(KeyTypeInfo *type, struct xkb_keymap *keymap,
817 char *field, ExprDef *arrayNdx, ExprDef *value,
822 if (strcasecmp(field, "modifiers") == 0)
824 unsigned mods, vmods;
825 if (arrayNdx != NULL)
827 WARN("The modifiers field of a key type is not an array\n");
828 ACTION("Illegal array subscript ignored\n");
830 /* get modifier mask for current type */
831 if (!ExprResolveVModMask(value, &tmp, keymap))
833 ERROR("Key type mask field must be a modifier mask\n");
834 ACTION("Key type definition ignored\n");
837 mods = tmp.uval & 0xff; /* core mods */
838 vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
839 if (type->defs.defined & _KT_Mask)
841 WARN("Multiple modifier mask definitions for key type %s\n",
842 xkb_atom_text(keymap->ctx, type->name));
843 ACTION("Using %s, ", TypeMaskTxt(type, keymap));
844 INFO("ignoring %s\n", XkbcVModMaskText(keymap, mods, vmods));
849 type->defs.defined |= _KT_Mask;
852 else if (strcasecmp(field, "map") == 0)
854 type->defs.defined |= _KT_Map;
855 return SetMapEntry(type, keymap, arrayNdx, value);
857 else if (strcasecmp(field, "preserve") == 0)
859 type->defs.defined |= _KT_Preserve;
860 return SetPreserve(type, keymap, arrayNdx, value);
862 else if ((strcasecmp(field, "levelname") == 0) ||
863 (strcasecmp(field, "level_name") == 0))
865 type->defs.defined |= _KT_LevelNames;
866 return SetLevelName(type, keymap, arrayNdx, value);
868 ERROR("Unknown field %s in key type %s\n", field, TypeTxt(keymap, type));
869 ACTION("Definition ignored\n");
874 HandleKeyTypeVar(VarDef *stmt, struct xkb_keymap *keymap, KeyTypesInfo *info)
876 ExprResult elem, field;
879 if (!ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx))
880 return false; /* internal error, already reported */
881 if (elem.str && (strcasecmp(elem.str, "type") == 0))
882 return SetKeyTypeField(&info->dflt, keymap, field.str, arrayNdx,
884 if (elem.str != NULL)
886 ERROR("Default for unknown element %s\n", uStringText(elem.str));
887 ACTION("Value for field %s ignored\n", uStringText(field.str));
889 else if (field.str != NULL)
891 ERROR("Default defined for unknown field %s\n",
892 uStringText(field.str));
899 HandleKeyTypeBody(VarDef *def, struct xkb_keymap *keymap,
900 KeyTypeInfo *type, KeyTypesInfo *info)
903 ExprResult tmp, field;
906 for (; def != NULL; def = (VarDef *) def->common.next)
908 if ((def->name) && (def->name->type == ExprFieldRef))
910 ok = HandleKeyTypeVar(def, keymap, info);
913 ok = ExprResolveLhs(keymap, def->name, &tmp, &field, &arrayNdx);
915 ok = SetKeyTypeField(type, keymap, field.str, arrayNdx,
924 * Process a type "XYZ" { } specification in the xkb_types section.
928 HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
929 unsigned merge, KeyTypesInfo *info)
934 if (def->merge != MergeDefault)
937 type.defs.defined = 0;
938 type.defs.fileID = info->fileID;
939 type.defs.merge = merge;
940 type.defs.next = NULL;
941 type.name = def->name;
942 type.mask = info->dflt.mask;
943 type.vmask = info->dflt.vmask;
944 type.groupInfo = info->dflt.groupInfo;
946 type.nEntries = type.szEntries = 0;
949 type.lvlNames = NULL;
950 type.preserve = NULL;
952 /* Parse the actual content. */
953 if (!HandleKeyTypeBody(def->body, keymap, &type, info))
959 /* now copy any appropriate map, preserve or level names from the */
961 for (i = 0; i < info->dflt.nEntries; i++)
963 struct xkb_kt_map_entry * dflt;
964 dflt = &info->dflt.entries[i];
965 if (((dflt->mods.real_mods & type.mask) == dflt->mods.real_mods) &&
966 ((dflt->mods.vmods & type.vmask) == dflt->mods.vmods))
968 AddMapEntry(keymap, &type, dflt, false, false);
971 if (info->dflt.preserve)
973 PreserveInfo *dflt = info->dflt.preserve;
976 if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
977 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
979 AddPreserve(keymap, &type, dflt, false, false);
981 dflt = (PreserveInfo *) dflt->defs.next;
984 for (i = 0; i < info->dflt.szNames; i++)
986 if ((i < type.numLevels) && (info->dflt.lvlNames[i] != XKB_ATOM_NONE))
988 AddLevelName(keymap, &type, i, info->dflt.lvlNames[i], false);
991 /* Now add the new keytype to the info struct */
992 if (!AddKeyType(keymap, info, &type))
1001 * Process an xkb_types section.
1003 * @param file The parsed xkb_types section.
1004 * @param merge Merge Strategy (e.g. MergeOverride)
1005 * @param info Pointer to memory where the outcome will be stored.
1008 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
1009 unsigned merge, KeyTypesInfo *info)
1014 info->name = uDupString(file->name);
1018 switch (stmt->stmtType)
1021 if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, keymap, info))
1024 case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
1025 if (!HandleKeyTypeDef((KeyTypeDef *) stmt, keymap, merge, info))
1029 if (!HandleKeyTypeVar((VarDef *) stmt, keymap, info))
1032 case StmtVModDef: /* virtual_modifiers NumLock, ... */
1033 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
1036 case StmtKeyAliasDef:
1037 ERROR("Key type files may not include other declarations\n");
1038 ACTION("Ignoring definition of key alias\n");
1041 case StmtKeycodeDef:
1042 ERROR("Key type files may not include other declarations\n");
1043 ACTION("Ignoring definition of key name\n");
1047 ERROR("Key type files may not include other declarations\n");
1048 ACTION("Ignoring definition of symbol interpretation\n");
1052 WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
1057 if (info->errorCount > 10)
1060 ERROR("Too many errors\n");
1062 ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
1069 CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
1075 for (pre = def->preserve; pre != NULL;
1076 pre = (PreserveInfo *) pre->defs.next)
1078 struct xkb_kt_map_entry * match;
1079 struct xkb_kt_map_entry tmp;
1080 tmp.mods.real_mods = pre->indexMods;
1081 tmp.mods.vmods = pre->indexVMods;
1083 AddMapEntry(keymap, def, &tmp, false, false);
1084 match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1087 WSGO("Couldn't find matching entry for preserve\n");
1088 ACTION("Aborting\n");
1091 pre->matchingMapIndex = match - def->entries;
1093 type->mods.real_mods = def->mask;
1094 type->mods.vmods = def->vmask;
1095 type->num_levels = def->numLevels;
1096 type->map_count = def->nEntries;
1097 type->map = def->entries;
1100 type->preserve = uTypedCalloc(type->map_count, struct xkb_mods);
1101 if (!type->preserve)
1103 WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1104 ACTION("Preserve setting for type %s lost\n",
1105 xkb_atom_text(keymap->ctx, def->name));
1109 pre = def->preserve;
1110 for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
1112 int ndx = pre->matchingMapIndex;
1113 type->preserve[ndx].mask = pre->preMods;
1114 type->preserve[ndx].real_mods = pre->preMods;
1115 type->preserve[ndx].vmods = pre->preVMods;
1120 type->preserve = NULL;
1121 type->name = xkb_atom_strdup(keymap->ctx, def->name);
1122 if (def->szNames > 0)
1124 type->level_names = uTypedCalloc(def->numLevels, const char *);
1126 /* assert def->szNames<=def->numLevels */
1127 for (i = 0; i < def->szNames; i++)
1129 type->level_names[i] = xkb_atom_strdup(keymap->ctx,
1135 type->level_names = NULL;
1138 def->nEntries = def->szEntries = 0;
1139 def->entries = NULL;
1140 return XkbcComputeEffectiveMap(keymap, type, NULL);
1144 CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
1147 struct xkb_key_type *type, *next;
1151 InitKeyTypesInfo(&info, keymap, NULL);
1152 info.fileID = file->id;
1154 HandleKeyTypesFile(file, keymap, merge, &info);
1156 if (info.errorCount != 0)
1160 if ((info.stdPresent & XkbOneLevelMask) == 0)
1162 if ((info.stdPresent & XkbTwoLevelMask) == 0)
1164 if ((info.stdPresent & XkbKeypadMask) == 0)
1166 if ((info.stdPresent & XkbAlphabeticMask) == 0)
1169 if (XkbcAllocClientMap(keymap, XkbKeyTypesMask, i) != Success) {
1170 WSGO("Couldn't allocate client map\n");
1174 keymap->map->num_types = i;
1176 if (XkbAllRequiredTypes & (~info.stdPresent)) {
1177 unsigned missing, keypadVMod;
1179 missing = XkbAllRequiredTypes & (~info.stdPresent);
1180 keypadVMod = FindKeypadVMod(keymap);
1182 if (XkbcInitCanonicalKeyTypes(keymap, missing, keypadVMod) != Success) {
1183 WSGO("Couldn't initialize canonical key types\n");
1187 if (missing & XkbOneLevelMask)
1188 keymap->map->types[XkbOneLevelIndex].name =
1189 xkb_atom_strdup(keymap->ctx, tok_ONE_LEVEL);
1190 if (missing & XkbTwoLevelMask)
1191 keymap->map->types[XkbTwoLevelIndex].name =
1192 xkb_atom_strdup(keymap->ctx, tok_TWO_LEVEL);
1193 if (missing & XkbAlphabeticMask)
1194 keymap->map->types[XkbAlphabeticIndex].name =
1195 xkb_atom_strdup(keymap->ctx, tok_ALPHABETIC);
1196 if (missing & XkbKeypadMask)
1197 keymap->map->types[XkbKeypadIndex].name =
1198 xkb_atom_strdup(keymap->ctx, tok_KEYPAD);
1201 next = &keymap->map->types[XkbLastRequiredType + 1];
1202 for (i = 0, def = info.types; i < info.nTypes; i++) {
1203 if (def->name == tok_ONE_LEVEL)
1204 type = &keymap->map->types[XkbOneLevelIndex];
1205 else if (def->name == tok_TWO_LEVEL)
1206 type = &keymap->map->types[XkbTwoLevelIndex];
1207 else if (def->name == tok_ALPHABETIC)
1208 type = &keymap->map->types[XkbAlphabeticIndex];
1209 else if (def->name == tok_KEYPAD)
1210 type = &keymap->map->types[XkbKeypadIndex];
1214 DeleteLevel1MapEntries(def);
1216 if (!CopyDefToKeyType(keymap, type, def))
1219 def = (KeyTypeInfo *)def->defs.next;
1222 FreeKeyTypesInfo(&info);
1226 FreeKeyTypesInfo(&info);