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
56 darray(struct xkb_kt_map_entry) entries;
57 PreserveInfo *preserve;
58 darray(xkb_atom_t) lvlNames;
61 typedef struct _KeyTypesInfo
73 static xkb_atom_t tok_ONE_LEVEL;
74 static xkb_atom_t tok_TWO_LEVEL;
75 static xkb_atom_t tok_ALPHABETIC;
76 static xkb_atom_t tok_KEYPAD;
78 /***====================================================================***/
80 #define ReportTypeShouldBeArray(keymap, t, f) \
81 ReportShouldBeArray("key type", (f), TypeTxt((keymap), (t)))
82 #define ReportTypeBadType(keymap, t, f, w) \
83 ReportBadType("key type", (f), TypeTxt((keymap), (t)), (w))
85 /***====================================================================***/
87 #define MapEntryTxt(x, e) \
88 XkbcVModMaskText((x), (e)->mods.real_mods, (e)->mods.vmods)
89 #define PreserveIndexTxt(x, p) \
90 XkbcVModMaskText((x), (p)->indexMods, (p)->indexVMods)
91 #define PreserveTxt(x, p) \
92 XkbcVModMaskText((x), (p)->preMods, (p)->preVMods)
93 #define TypeTxt(keymap, t) \
94 xkb_atom_text((keymap)->ctx, (t)->name)
95 #define TypeMaskTxt(t, x) \
96 XkbcVModMaskText((x), (t)->mask, (t)->vmask)
98 /***====================================================================***/
101 InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
104 tok_ONE_LEVEL = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
105 tok_TWO_LEVEL = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
106 tok_ALPHABETIC = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
107 tok_KEYPAD = xkb_atom_intern(keymap->ctx, "KEYPAD");
108 info->name = strdup("default");
109 info->errorCount = 0;
110 info->stdPresent = 0;
113 info->dflt.defs.defined = 0;
114 info->dflt.defs.fileID = 0;
115 info->dflt.defs.merge = MergeOverride;
116 info->dflt.defs.next = NULL;
117 info->dflt.name = XKB_ATOM_NONE;
119 info->dflt.vmask = 0;
120 info->dflt.groupInfo = false;
121 info->dflt.numLevels = 1;
122 darray_init(info->dflt.entries);
123 darray_init(info->dflt.lvlNames);
124 info->dflt.preserve = NULL;
125 InitVModInfo(&info->vmods, keymap);
128 info->dflt = from->dflt;
130 darray_copy(info->dflt.entries, from->dflt.entries);
131 darray_copy(info->dflt.lvlNames, from->dflt.lvlNames);
133 if (from->dflt.preserve)
135 PreserveInfo *old, *new, *last;
137 old = from->dflt.preserve;
138 for (; old; old = (PreserveInfo *) old->defs.next)
140 new = uTypedAlloc(PreserveInfo);
144 new->defs.next = NULL;
146 last->defs.next = (CommonInfo *) new;
148 info->dflt.preserve = new;
156 FreeKeyTypeInfo(KeyTypeInfo * type)
158 darray_free(type->entries);
159 darray_free(type->lvlNames);
160 if (type->preserve != NULL)
162 ClearCommonInfo(&type->preserve->defs);
163 type->preserve = NULL;
168 FreeKeyTypesInfo(KeyTypesInfo * info)
175 for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
177 FreeKeyTypeInfo(type);
179 info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs);
181 FreeKeyTypeInfo(&info->dflt);
185 NextKeyType(KeyTypesInfo * info)
189 type = uTypedAlloc(KeyTypeInfo);
192 memset(type, 0, sizeof(KeyTypeInfo));
193 type->defs.fileID = info->fileID;
194 info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs,
195 (CommonInfo *) type);
202 FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
206 for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
208 if (old->name == new->name)
215 ReportTypeBadWidth(const char *type, int has, int needs)
217 ERROR("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
218 ACTION("Illegal type definition ignored\n");
223 AddKeyType(struct xkb_keymap *keymap, KeyTypesInfo *info, KeyTypeInfo *new)
227 if (new->name == tok_ONE_LEVEL)
229 if (new->numLevels > 1)
230 return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
231 info->stdPresent |= XkbOneLevelMask;
233 else if (new->name == tok_TWO_LEVEL)
235 if (new->numLevels > 2)
236 return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
237 else if (new->numLevels < 2)
239 info->stdPresent |= XkbTwoLevelMask;
241 else if (new->name == tok_ALPHABETIC)
243 if (new->numLevels > 2)
244 return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
245 else if (new->numLevels < 2)
247 info->stdPresent |= XkbAlphabeticMask;
249 else if (new->name == tok_KEYPAD)
251 if (new->numLevels > 2)
252 return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
253 else if (new->numLevels < 2)
255 info->stdPresent |= XkbKeypadMask;
258 old = FindMatchingKeyType(info, new);
262 if ((new->defs.merge == MergeReplace)
263 || (new->defs.merge == MergeOverride))
265 KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
266 if (((old->defs.fileID == new->defs.fileID)
267 && (warningLevel > 0)) || (warningLevel > 9))
269 WARN("Multiple definitions of the %s key type\n",
270 xkb_atom_text(keymap->ctx, new->name));
271 ACTION("Earlier definition ignored\n");
273 FreeKeyTypeInfo(old);
275 darray_init(new->entries);
276 darray_init(new->lvlNames);
277 new->preserve = NULL;
278 old->defs.next = &next->defs;
281 report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
284 WARN("Multiple definitions of the %s key type\n",
285 xkb_atom_text(keymap->ctx, new->name));
286 ACTION("Later definition ignored\n");
288 FreeKeyTypeInfo(new);
291 old = NextKeyType(info);
295 old->defs.next = NULL;
296 darray_init(new->entries);
297 darray_init(new->lvlNames);
298 new->preserve = NULL;
302 /***====================================================================***/
305 MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
306 unsigned merge, struct xkb_keymap *keymap)
310 if (from->errorCount > 0)
312 into->errorCount += from->errorCount;
315 if (into->name == NULL)
317 into->name = from->name;
320 for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
322 if (merge != MergeDefault)
323 type->defs.merge = merge;
324 if (!AddKeyType(keymap, into, type))
327 into->stdPresent |= from->stdPresent;
331 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
332 unsigned merge, KeyTypesInfo *info);
335 HandleIncludeKeyTypes(IncludeStmt *stmt, struct xkb_keymap *keymap,
340 KeyTypesInfo included;
344 if ((stmt->file == NULL) && (stmt->map == NULL))
348 memset(info, 0, sizeof(KeyTypesInfo));
350 else if (ProcessIncludeFile(keymap->ctx, stmt, XkmTypesIndex, &rtrn,
353 InitKeyTypesInfo(&included, keymap, info);
354 included.fileID = included.dflt.defs.fileID = rtrn->id;
355 included.dflt.defs.merge = newMerge;
357 HandleKeyTypesFile(rtrn, keymap, newMerge, &included);
358 if (stmt->stmt != NULL)
361 included.name = stmt->stmt;
368 info->errorCount += 10;
371 if ((stmt->next != NULL) && (included.errorCount < 1))
375 KeyTypesInfo next_incl;
377 for (next = stmt->next; next != NULL; next = next->next)
379 if ((next->file == NULL) && (next->map == NULL))
382 MergeIncludedKeyTypes(&included, info, next->merge, keymap);
383 FreeKeyTypesInfo(info);
385 else if (ProcessIncludeFile(keymap->ctx, next, XkmTypesIndex,
388 InitKeyTypesInfo(&next_incl, keymap, &included);
389 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
390 next_incl.dflt.defs.merge = op;
391 HandleKeyTypesFile(rtrn, keymap, op, &next_incl);
392 MergeIncludedKeyTypes(&included, &next_incl, op, keymap);
393 FreeKeyTypesInfo(&next_incl);
398 info->errorCount += 10;
399 FreeKeyTypesInfo(&included);
408 MergeIncludedKeyTypes(info, &included, newMerge, keymap);
409 FreeKeyTypesInfo(&included);
411 return (info->errorCount == 0);
414 /***====================================================================***/
416 static struct xkb_kt_map_entry *
417 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
419 struct xkb_kt_map_entry *entry;
421 darray_foreach(entry, type->entries)
422 if (entry->mods.real_mods == mask && entry->mods.vmods == vmask)
429 DeleteLevel1MapEntries(KeyTypeInfo * type)
433 /* TODO: Be just a bit more clever here. */
434 for (i = 0; i < darray_size(type->entries); i++) {
435 if (darray_item(type->entries, i).level == 0) {
436 for (n = i; n < darray_size(type->entries) - 1; n++)
437 darray_item(type->entries, n) =
438 darray_item(type->entries, n + 1);
439 (void)darray_pop(type->entries);
444 static struct xkb_kt_map_entry *
445 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
447 darray_resize0(type->entries, darray_size(type->entries) + 1);
448 return &darray_item(type->entries, darray_size(type->entries) - 1);
452 AddPreserve(struct xkb_keymap *keymap, KeyTypeInfo *type,
453 PreserveInfo *new, bool clobber, bool report)
457 old = type->preserve;
460 if ((old->indexMods != new->indexMods) ||
461 (old->indexVMods != new->indexVMods))
463 old = (PreserveInfo *) old->defs.next;
466 if ((old->preMods == new->preMods)
467 && (old->preVMods == new->preVMods))
469 if (warningLevel > 9)
471 WARN("Identical definitions for preserve[%s] in %s\n",
472 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
477 if (report && (warningLevel > 0))
480 WARN("Multiple definitions for preserve[%s] in %s\n",
481 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
484 str = PreserveTxt(keymap, new);
486 str = PreserveTxt(keymap, old);
487 ACTION("Using %s, ", str);
489 str = PreserveTxt(keymap, old);
491 str = PreserveTxt(keymap, new);
492 INFO("ignoring %s\n", str);
496 old->preMods = new->preMods;
497 old->preVMods = new->preVMods;
501 old = uTypedAlloc(PreserveInfo);
504 WSGO("Couldn't allocate preserve in %s\n", TypeTxt(keymap, type));
505 ACTION("Preserve[%s] lost\n", PreserveIndexTxt(keymap, new));
509 old->matchingMapIndex = -1;
511 (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
516 * Add a new KTMapEntry to the given key type. If an entry with the same mods
517 * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
520 * @param clobber Overwrite existing entry.
521 * @param report true if a warning is to be printed on.
524 AddMapEntry(struct xkb_keymap *keymap, KeyTypeInfo *type,
525 struct xkb_kt_map_entry *new, bool clobber, bool report)
527 struct xkb_kt_map_entry * old;
530 FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
532 if (report && (old->level != new->level))
534 unsigned use, ignore;
537 use = new->level + 1;
538 ignore = old->level + 1;
542 use = old->level + 1;
543 ignore = new->level + 1;
545 WARN("Multiple map entries for %s in %s\n",
546 MapEntryTxt(keymap, new), TypeTxt(keymap, type));
547 ACTION("Using %d, ignoring %d\n", use, ignore);
549 else if (warningLevel > 9)
551 WARN("Multiple occurences of map[%s]= %d in %s\n",
552 MapEntryTxt(keymap, new), new->level + 1,
553 TypeTxt(keymap, type));
558 old->level = new->level;
561 if ((old = NextMapEntry(keymap, type)) == NULL)
562 return false; /* allocation failure, already reported */
563 if (new->level >= type->numLevels)
564 type->numLevels = new->level + 1;
565 if (new->mods.vmods == 0)
569 old->mods.mask = new->mods.real_mods;
570 old->mods.real_mods = new->mods.real_mods;
571 old->mods.vmods = new->mods.vmods;
572 old->level = new->level;
577 SetMapEntry(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
581 struct xkb_kt_map_entry entry;
583 if (arrayNdx == NULL)
584 return ReportTypeShouldBeArray(keymap, type, "map entry");
585 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
586 return ReportTypeBadType(keymap, type, "map entry", "modifier mask");
587 entry.mods.real_mods = rtrn.uval & 0xff; /* modifiers < 512 */
588 entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
589 if ((entry.mods.real_mods & (~type->mask)) ||
590 ((entry.mods.vmods & (~type->vmask)) != 0))
592 if (warningLevel > 0)
594 WARN("Map entry for unused modifiers in %s\n", TypeTxt(keymap, type));
595 ACTION("Using %s instead of ",
596 XkbcVModMaskText(keymap,
597 entry.mods.real_mods & type->mask,
598 entry.mods.vmods & type->vmask));
599 INFO("%s\n", MapEntryTxt(keymap, &entry));
601 entry.mods.real_mods &= type->mask;
602 entry.mods.vmods &= type->vmask;
604 if (!ExprResolveLevel(keymap->ctx, value, &rtrn))
606 ERROR("Level specifications in a key type must be integer\n");
607 ACTION("Ignoring malformed level specification\n");
610 entry.level = rtrn.ival - 1;
611 return AddMapEntry(keymap, type, &entry, true, true);
615 SetPreserve(KeyTypeInfo *type, struct xkb_keymap *keymap,
616 ExprDef *arrayNdx, ExprDef *value)
621 if (arrayNdx == NULL)
622 return ReportTypeShouldBeArray(keymap, type, "preserve entry");
623 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
624 return ReportTypeBadType(keymap, type, "preserve entry",
626 new.defs = type->defs;
627 new.defs.next = NULL;
628 new.indexMods = rtrn.uval & 0xff;
629 new.indexVMods = (rtrn.uval >> 8) & 0xffff;
630 if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
632 if (warningLevel > 0)
634 WARN("Preserve for modifiers not used by the %s type\n",
635 TypeTxt(keymap, type));
636 ACTION("Index %s converted to ", PreserveIndexTxt(keymap, &new));
638 new.indexMods &= type->mask;
639 new.indexVMods &= type->vmask;
640 if (warningLevel > 0)
641 INFO("%s\n", PreserveIndexTxt(keymap, &new));
643 if (!ExprResolveVModMask(value, &rtrn, keymap))
645 ERROR("Preserve value in a key type is not a modifier mask\n");
646 ACTION("Ignoring preserve[%s] in type %s\n",
647 PreserveIndexTxt(keymap, &new), TypeTxt(keymap, type));
650 new.preMods = rtrn.uval & 0xff;
651 new.preVMods = (rtrn.uval >> 16) & 0xffff;
652 if ((new.preMods & (~new.indexMods))
653 || (new.preVMods & (~new.indexVMods)))
655 if (warningLevel > 0)
657 WARN("Illegal value for preserve[%s] in type %s\n",
658 PreserveTxt(keymap, &new), TypeTxt(keymap, type));
659 ACTION("Converted %s to ", PreserveIndexTxt(keymap, &new));
661 new.preMods &= new.indexMods;
662 new.preVMods &= new.indexVMods;
663 if (warningLevel > 0)
665 INFO("%s\n", PreserveIndexTxt(keymap, &new));
668 return AddPreserve(keymap, type, &new, true, true);
671 /***====================================================================***/
674 AddLevelName(struct xkb_keymap *keymap, KeyTypeInfo *type,
675 unsigned level, xkb_atom_t name, bool clobber)
677 if (level >= darray_size(type->lvlNames))
678 darray_resize0(type->lvlNames, level + 1);
680 if (darray_item(type->lvlNames, level) == name) {
681 if (warningLevel > 9) {
682 WARN("Duplicate names for level %d of key type %s\n",
683 level + 1, TypeTxt(keymap, type));
688 else if (darray_item(type->lvlNames, level) != XKB_ATOM_NONE) {
689 if (warningLevel > 0) {
690 const char *old, *new;
691 old = xkb_atom_text(keymap->ctx,
692 darray_item(type->lvlNames, level));
693 new = xkb_atom_text(keymap->ctx, name);
694 WARN("Multiple names for level %d of key type %s\n",
695 level + 1, TypeTxt(keymap, type));
697 ACTION("Using %s, ignoring %s\n", new, old);
699 ACTION("Using %s, ignoring %s\n", old, new);
706 darray_item(type->lvlNames, level) = name;
711 SetLevelName(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
716 xkb_atom_t level_name;
718 if (arrayNdx == NULL)
719 return ReportTypeShouldBeArray(keymap, type, "level name");
720 if (!ExprResolveLevel(keymap->ctx, arrayNdx, &rtrn))
721 return ReportTypeBadType(keymap, type, "level name", "integer");
722 level = rtrn.ival - 1;
723 if (!ExprResolveString(keymap->ctx, value, &rtrn))
725 ERROR("Non-string name for level %d in key type %s\n", level + 1,
726 xkb_atom_text(keymap->ctx, type->name));
727 ACTION("Ignoring illegal level name definition\n");
730 level_name = xkb_atom_intern(keymap->ctx, rtrn.str);
732 return AddLevelName(keymap, type, level, level_name, true);
735 /***====================================================================***/
738 * Parses the fields in a type "..." { } description.
740 * @param field The field to parse (e.g. modifiers, map, level_name)
743 SetKeyTypeField(KeyTypeInfo *type, struct xkb_keymap *keymap,
744 char *field, ExprDef *arrayNdx, ExprDef *value,
749 if (strcasecmp(field, "modifiers") == 0)
751 unsigned mods, vmods;
752 if (arrayNdx != NULL)
754 WARN("The modifiers field of a key type is not an array\n");
755 ACTION("Illegal array subscript ignored\n");
757 /* get modifier mask for current type */
758 if (!ExprResolveVModMask(value, &tmp, keymap))
760 ERROR("Key type mask field must be a modifier mask\n");
761 ACTION("Key type definition ignored\n");
764 mods = tmp.uval & 0xff; /* core mods */
765 vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
766 if (type->defs.defined & _KT_Mask)
768 WARN("Multiple modifier mask definitions for key type %s\n",
769 xkb_atom_text(keymap->ctx, type->name));
770 ACTION("Using %s, ", TypeMaskTxt(type, keymap));
771 INFO("ignoring %s\n", XkbcVModMaskText(keymap, mods, vmods));
776 type->defs.defined |= _KT_Mask;
779 else if (strcasecmp(field, "map") == 0)
781 type->defs.defined |= _KT_Map;
782 return SetMapEntry(type, keymap, arrayNdx, value);
784 else if (strcasecmp(field, "preserve") == 0)
786 type->defs.defined |= _KT_Preserve;
787 return SetPreserve(type, keymap, arrayNdx, value);
789 else if ((strcasecmp(field, "levelname") == 0) ||
790 (strcasecmp(field, "level_name") == 0))
792 type->defs.defined |= _KT_LevelNames;
793 return SetLevelName(type, keymap, arrayNdx, value);
795 ERROR("Unknown field %s in key type %s\n", field, TypeTxt(keymap, type));
796 ACTION("Definition ignored\n");
801 HandleKeyTypeVar(VarDef *stmt, struct xkb_keymap *keymap, KeyTypesInfo *info)
803 ExprResult elem, field;
806 if (!ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx))
807 return false; /* internal error, already reported */
808 if (elem.str && (strcasecmp(elem.str, "type") == 0))
809 return SetKeyTypeField(&info->dflt, keymap, field.str, arrayNdx,
811 if (elem.str != NULL)
813 ERROR("Default for unknown element %s\n", uStringText(elem.str));
814 ACTION("Value for field %s ignored\n", uStringText(field.str));
816 else if (field.str != NULL)
818 ERROR("Default defined for unknown field %s\n",
819 uStringText(field.str));
826 HandleKeyTypeBody(VarDef *def, struct xkb_keymap *keymap,
827 KeyTypeInfo *type, KeyTypesInfo *info)
830 ExprResult tmp, field;
833 for (; def != NULL; def = (VarDef *) def->common.next)
835 if ((def->name) && (def->name->type == ExprFieldRef))
837 ok = HandleKeyTypeVar(def, keymap, info);
840 ok = ExprResolveLhs(keymap, def->name, &tmp, &field, &arrayNdx);
842 ok = SetKeyTypeField(type, keymap, field.str, arrayNdx,
851 * Process a type "XYZ" { } specification in the xkb_types section.
855 HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
856 unsigned merge, KeyTypesInfo *info)
860 struct xkb_kt_map_entry *entry;
862 if (def->merge != MergeDefault)
865 type.defs.defined = 0;
866 type.defs.fileID = info->fileID;
867 type.defs.merge = merge;
868 type.defs.next = NULL;
869 type.name = def->name;
870 type.mask = info->dflt.mask;
871 type.vmask = info->dflt.vmask;
872 type.groupInfo = info->dflt.groupInfo;
874 darray_init(type.entries);
875 darray_init(type.lvlNames);
876 type.preserve = NULL;
878 /* Parse the actual content. */
879 if (!HandleKeyTypeBody(def->body, keymap, &type, info))
885 /* now copy any appropriate map, preserve or level names from the */
887 darray_foreach(entry, info->dflt.entries) {
888 if ((entry->mods.real_mods & type.mask) == entry->mods.real_mods &&
889 (entry->mods.vmods & type.vmask) == entry->mods.vmods)
890 AddMapEntry(keymap, &type, entry, false, false);
892 if (info->dflt.preserve)
894 PreserveInfo *dflt = info->dflt.preserve;
897 if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
898 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
900 AddPreserve(keymap, &type, dflt, false, false);
902 dflt = (PreserveInfo *) dflt->defs.next;
906 for (i = 0; i < darray_size(info->dflt.lvlNames); i++) {
907 if (i < type.numLevels &&
908 darray_item(info->dflt.lvlNames, i) != XKB_ATOM_NONE)
910 AddLevelName(keymap, &type, i,
911 darray_item(info->dflt.lvlNames, i), false);
915 /* Now add the new keytype to the info struct */
916 if (!AddKeyType(keymap, info, &type))
925 * Process an xkb_types section.
927 * @param file The parsed xkb_types section.
928 * @param merge Merge Strategy (e.g. MergeOverride)
929 * @param info Pointer to memory where the outcome will be stored.
932 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
933 unsigned merge, KeyTypesInfo *info)
938 info->name = uDupString(file->name);
942 switch (stmt->stmtType)
945 if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, keymap, info))
948 case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
949 if (!HandleKeyTypeDef((KeyTypeDef *) stmt, keymap, merge, info))
953 if (!HandleKeyTypeVar((VarDef *) stmt, keymap, info))
956 case StmtVModDef: /* virtual_modifiers NumLock, ... */
957 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
960 case StmtKeyAliasDef:
961 ERROR("Key type files may not include other declarations\n");
962 ACTION("Ignoring definition of key alias\n");
966 ERROR("Key type files may not include other declarations\n");
967 ACTION("Ignoring definition of key name\n");
971 ERROR("Key type files may not include other declarations\n");
972 ACTION("Ignoring definition of symbol interpretation\n");
976 WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
981 if (info->errorCount > 10)
984 ERROR("Too many errors\n");
986 ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
993 CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
999 for (pre = def->preserve; pre != NULL;
1000 pre = (PreserveInfo *) pre->defs.next)
1002 struct xkb_kt_map_entry * match;
1003 struct xkb_kt_map_entry tmp;
1004 tmp.mods.real_mods = pre->indexMods;
1005 tmp.mods.vmods = pre->indexVMods;
1007 AddMapEntry(keymap, def, &tmp, false, false);
1008 match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1011 WSGO("Couldn't find matching entry for preserve\n");
1012 ACTION("Aborting\n");
1015 pre->matchingMapIndex = match - &darray_item(def->entries, 0);
1017 type->mods.real_mods = def->mask;
1018 type->mods.vmods = def->vmask;
1019 type->num_levels = def->numLevels;
1020 memcpy(&type->map, &def->entries, sizeof(def->entries));
1023 type->preserve = uTypedCalloc(darray_size(type->map), struct xkb_mods);
1024 if (!type->preserve)
1026 WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1027 ACTION("Preserve setting for type %s lost\n",
1028 xkb_atom_text(keymap->ctx, def->name));
1032 pre = def->preserve;
1033 for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
1035 int ndx = pre->matchingMapIndex;
1036 type->preserve[ndx].mask = pre->preMods;
1037 type->preserve[ndx].real_mods = pre->preMods;
1038 type->preserve[ndx].vmods = pre->preVMods;
1043 type->preserve = NULL;
1044 type->name = xkb_atom_strdup(keymap->ctx, def->name);
1046 if (!darray_empty(def->lvlNames)) {
1047 type->level_names = calloc(darray_size(def->lvlNames),
1048 sizeof(*type->level_names));
1050 /* assert def->szNames<=def->numLevels */
1051 for (i = 0; i < darray_size(def->lvlNames); i++)
1052 type->level_names[i] =
1053 xkb_atom_strdup(keymap->ctx, darray_item(def->lvlNames, i));
1056 type->level_names = NULL;
1059 darray_init(def->entries);
1060 return XkbcComputeEffectiveMap(keymap, type, NULL);
1064 CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
1067 struct xkb_key_type *type, *next;
1071 InitKeyTypesInfo(&info, keymap, NULL);
1072 info.fileID = file->id;
1074 HandleKeyTypesFile(file, keymap, merge, &info);
1076 if (info.errorCount != 0)
1080 if ((info.stdPresent & XkbOneLevelMask) == 0)
1082 if ((info.stdPresent & XkbTwoLevelMask) == 0)
1084 if ((info.stdPresent & XkbKeypadMask) == 0)
1086 if ((info.stdPresent & XkbAlphabeticMask) == 0)
1089 if (XkbcAllocClientMap(keymap, XkbKeyTypesMask, i) != Success) {
1090 WSGO("Couldn't allocate client map\n");
1094 darray_resize0(keymap->map->types, i);
1096 if (XkbAllRequiredTypes & (~info.stdPresent)) {
1097 unsigned missing, keypadVMod;
1099 missing = XkbAllRequiredTypes & (~info.stdPresent);
1100 keypadVMod = FindKeypadVMod(keymap);
1102 if (XkbcInitCanonicalKeyTypes(keymap, missing, keypadVMod) != Success) {
1103 WSGO("Couldn't initialize canonical key types\n");
1107 if (missing & XkbOneLevelMask)
1108 darray_item(keymap->map->types, XkbOneLevelIndex).name =
1109 xkb_atom_strdup(keymap->ctx, tok_ONE_LEVEL);
1110 if (missing & XkbTwoLevelMask)
1111 darray_item(keymap->map->types, XkbTwoLevelIndex).name =
1112 xkb_atom_strdup(keymap->ctx, tok_TWO_LEVEL);
1113 if (missing & XkbAlphabeticMask)
1114 darray_item(keymap->map->types, XkbAlphabeticIndex).name =
1115 xkb_atom_strdup(keymap->ctx, tok_ALPHABETIC);
1116 if (missing & XkbKeypadMask)
1117 darray_item(keymap->map->types, XkbKeypadIndex).name =
1118 xkb_atom_strdup(keymap->ctx, tok_KEYPAD);
1121 next = &darray_item(keymap->map->types, XkbLastRequiredType + 1);
1122 for (i = 0, def = info.types; i < info.nTypes; i++) {
1123 if (def->name == tok_ONE_LEVEL)
1124 type = &darray_item(keymap->map->types, XkbOneLevelIndex);
1125 else if (def->name == tok_TWO_LEVEL)
1126 type = &darray_item(keymap->map->types, XkbTwoLevelIndex);
1127 else if (def->name == tok_ALPHABETIC)
1128 type = &darray_item(keymap->map->types, XkbAlphabeticIndex);
1129 else if (def->name == tok_KEYPAD)
1130 type = &darray_item(keymap->map->types, XkbKeypadIndex);
1134 DeleteLevel1MapEntries(def);
1136 if (!CopyDefToKeyType(keymap, type, def))
1139 def = (KeyTypeInfo *)def->defs.next;
1142 FreeKeyTypesInfo(&info);
1146 FreeKeyTypesInfo(&info);