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 = MERGE_OVERRIDE;
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 = 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 = AddCommonInfo(&info->types->defs, &type->defs);
201 FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
205 for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
207 if (old->name == new->name)
214 ReportTypeBadWidth(const char *type, int has, int needs)
216 ERROR("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
217 ACTION("Illegal type definition ignored\n");
222 AddKeyType(struct xkb_keymap *keymap, KeyTypesInfo *info, KeyTypeInfo *new)
226 if (new->name == tok_ONE_LEVEL)
228 if (new->numLevels > 1)
229 return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
230 info->stdPresent |= XkbOneLevelMask;
232 else if (new->name == tok_TWO_LEVEL)
234 if (new->numLevels > 2)
235 return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
236 else if (new->numLevels < 2)
238 info->stdPresent |= XkbTwoLevelMask;
240 else if (new->name == tok_ALPHABETIC)
242 if (new->numLevels > 2)
243 return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
244 else if (new->numLevels < 2)
246 info->stdPresent |= XkbAlphabeticMask;
248 else if (new->name == tok_KEYPAD)
250 if (new->numLevels > 2)
251 return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
252 else if (new->numLevels < 2)
254 info->stdPresent |= XkbKeypadMask;
257 old = FindMatchingKeyType(info, new);
261 if ((new->defs.merge == MERGE_REPLACE)
262 || (new->defs.merge == MERGE_OVERRIDE))
264 KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
265 if (((old->defs.fileID == new->defs.fileID)
266 && (warningLevel > 0)) || (warningLevel > 9))
268 WARN("Multiple definitions of the %s key type\n",
269 xkb_atom_text(keymap->ctx, new->name));
270 ACTION("Earlier definition ignored\n");
272 FreeKeyTypeInfo(old);
274 darray_init(new->entries);
275 darray_init(new->lvlNames);
276 new->preserve = NULL;
277 old->defs.next = &next->defs;
280 report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
283 WARN("Multiple definitions of the %s key type\n",
284 xkb_atom_text(keymap->ctx, new->name));
285 ACTION("Later definition ignored\n");
287 FreeKeyTypeInfo(new);
290 old = NextKeyType(info);
294 old->defs.next = NULL;
295 darray_init(new->entries);
296 darray_init(new->lvlNames);
297 new->preserve = NULL;
301 /***====================================================================***/
304 MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
305 enum merge_mode merge, struct xkb_keymap *keymap)
309 if (from->errorCount > 0)
311 into->errorCount += from->errorCount;
314 if (into->name == NULL)
316 into->name = from->name;
319 for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
321 if (merge != MERGE_DEFAULT)
322 type->defs.merge = merge;
323 if (!AddKeyType(keymap, into, type))
326 into->stdPresent |= from->stdPresent;
330 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
331 enum merge_mode merge, KeyTypesInfo *info);
334 HandleIncludeKeyTypes(IncludeStmt *stmt, struct xkb_keymap *keymap,
339 KeyTypesInfo included;
343 if ((stmt->file == NULL) && (stmt->map == NULL))
347 memset(info, 0, sizeof(KeyTypesInfo));
349 else if (ProcessIncludeFile(keymap->ctx, stmt, FILE_TYPE_TYPES, &rtrn,
352 InitKeyTypesInfo(&included, keymap, info);
353 included.fileID = included.dflt.defs.fileID = rtrn->id;
354 included.dflt.defs.merge = newMerge;
356 HandleKeyTypesFile(rtrn, keymap, newMerge, &included);
357 if (stmt->stmt != NULL)
360 included.name = stmt->stmt;
367 info->errorCount += 10;
370 if ((stmt->next != NULL) && (included.errorCount < 1))
374 KeyTypesInfo next_incl;
376 for (next = stmt->next; next != NULL; next = next->next)
378 if ((next->file == NULL) && (next->map == NULL))
381 MergeIncludedKeyTypes(&included, info, next->merge, keymap);
382 FreeKeyTypesInfo(info);
384 else if (ProcessIncludeFile(keymap->ctx, next, FILE_TYPE_TYPES,
387 InitKeyTypesInfo(&next_incl, keymap, &included);
388 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
389 next_incl.dflt.defs.merge = op;
390 HandleKeyTypesFile(rtrn, keymap, op, &next_incl);
391 MergeIncludedKeyTypes(&included, &next_incl, op, keymap);
392 FreeKeyTypesInfo(&next_incl);
397 info->errorCount += 10;
398 FreeKeyTypesInfo(&included);
407 MergeIncludedKeyTypes(info, &included, newMerge, keymap);
408 FreeKeyTypesInfo(&included);
410 return (info->errorCount == 0);
413 /***====================================================================***/
415 static struct xkb_kt_map_entry *
416 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
418 struct xkb_kt_map_entry *entry;
420 darray_foreach(entry, type->entries)
421 if (entry->mods.real_mods == mask && entry->mods.vmods == vmask)
428 DeleteLevel1MapEntries(KeyTypeInfo * type)
432 /* TODO: Be just a bit more clever here. */
433 for (i = 0; i < darray_size(type->entries); i++) {
434 if (darray_item(type->entries, i).level == 0) {
435 for (n = i; n < darray_size(type->entries) - 1; n++)
436 darray_item(type->entries, n) =
437 darray_item(type->entries, n + 1);
438 (void)darray_pop(type->entries);
443 static struct xkb_kt_map_entry *
444 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
446 darray_resize0(type->entries, darray_size(type->entries) + 1);
447 return &darray_item(type->entries, darray_size(type->entries) - 1);
451 AddPreserve(struct xkb_keymap *keymap, KeyTypeInfo *type,
452 PreserveInfo *new, bool clobber, bool report)
456 old = type->preserve;
459 if ((old->indexMods != new->indexMods) ||
460 (old->indexVMods != new->indexVMods))
462 old = (PreserveInfo *) old->defs.next;
465 if ((old->preMods == new->preMods)
466 && (old->preVMods == new->preVMods))
468 if (warningLevel > 9)
470 WARN("Identical definitions for preserve[%s] in %s\n",
471 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
476 if (report && (warningLevel > 0))
479 WARN("Multiple definitions for preserve[%s] in %s\n",
480 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
483 str = PreserveTxt(keymap, new);
485 str = PreserveTxt(keymap, old);
486 ACTION("Using %s, ", str);
488 str = PreserveTxt(keymap, old);
490 str = PreserveTxt(keymap, new);
491 INFO("ignoring %s\n", str);
495 old->preMods = new->preMods;
496 old->preVMods = new->preVMods;
500 old = uTypedAlloc(PreserveInfo);
503 WSGO("Couldn't allocate preserve in %s\n", TypeTxt(keymap, type));
504 ACTION("Preserve[%s] lost\n", PreserveIndexTxt(keymap, new));
508 old->matchingMapIndex = -1;
509 type->preserve = AddCommonInfo(&type->preserve->defs, &old->defs);
514 * Add a new KTMapEntry to the given key type. If an entry with the same mods
515 * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
518 * @param clobber Overwrite existing entry.
519 * @param report true if a warning is to be printed on.
522 AddMapEntry(struct xkb_keymap *keymap, KeyTypeInfo *type,
523 struct xkb_kt_map_entry *new, bool clobber, bool report)
525 struct xkb_kt_map_entry * old;
528 FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
530 if (report && (old->level != new->level))
532 unsigned use, ignore;
535 use = new->level + 1;
536 ignore = old->level + 1;
540 use = old->level + 1;
541 ignore = new->level + 1;
543 WARN("Multiple map entries for %s in %s\n",
544 MapEntryTxt(keymap, new), TypeTxt(keymap, type));
545 ACTION("Using %d, ignoring %d\n", use, ignore);
547 else if (warningLevel > 9)
549 WARN("Multiple occurences of map[%s]= %d in %s\n",
550 MapEntryTxt(keymap, new), new->level + 1,
551 TypeTxt(keymap, type));
556 old->level = new->level;
559 if ((old = NextMapEntry(keymap, type)) == NULL)
560 return false; /* allocation failure, already reported */
561 if (new->level >= type->numLevels)
562 type->numLevels = new->level + 1;
563 if (new->mods.vmods == 0)
567 old->mods.mask = new->mods.real_mods;
568 old->mods.real_mods = new->mods.real_mods;
569 old->mods.vmods = new->mods.vmods;
570 old->level = new->level;
575 SetMapEntry(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
579 struct xkb_kt_map_entry entry;
581 if (arrayNdx == NULL)
582 return ReportTypeShouldBeArray(keymap, type, "map entry");
583 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
584 return ReportTypeBadType(keymap, type, "map entry", "modifier mask");
585 entry.mods.real_mods = rtrn.uval & 0xff; /* modifiers < 512 */
586 entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
587 if ((entry.mods.real_mods & (~type->mask)) ||
588 ((entry.mods.vmods & (~type->vmask)) != 0))
590 if (warningLevel > 0)
592 WARN("Map entry for unused modifiers in %s\n", TypeTxt(keymap, type));
593 ACTION("Using %s instead of ",
594 XkbcVModMaskText(keymap,
595 entry.mods.real_mods & type->mask,
596 entry.mods.vmods & type->vmask));
597 INFO("%s\n", MapEntryTxt(keymap, &entry));
599 entry.mods.real_mods &= type->mask;
600 entry.mods.vmods &= type->vmask;
602 if (!ExprResolveLevel(keymap->ctx, value, &rtrn))
604 ERROR("Level specifications in a key type must be integer\n");
605 ACTION("Ignoring malformed level specification\n");
608 entry.level = rtrn.ival - 1;
609 return AddMapEntry(keymap, type, &entry, true, true);
613 SetPreserve(KeyTypeInfo *type, struct xkb_keymap *keymap,
614 ExprDef *arrayNdx, ExprDef *value)
619 if (arrayNdx == NULL)
620 return ReportTypeShouldBeArray(keymap, type, "preserve entry");
621 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
622 return ReportTypeBadType(keymap, type, "preserve entry",
624 new.defs = type->defs;
625 new.defs.next = NULL;
626 new.indexMods = rtrn.uval & 0xff;
627 new.indexVMods = (rtrn.uval >> 8) & 0xffff;
628 if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
630 if (warningLevel > 0)
632 WARN("Preserve for modifiers not used by the %s type\n",
633 TypeTxt(keymap, type));
634 ACTION("Index %s converted to ", PreserveIndexTxt(keymap, &new));
636 new.indexMods &= type->mask;
637 new.indexVMods &= type->vmask;
638 if (warningLevel > 0)
639 INFO("%s\n", PreserveIndexTxt(keymap, &new));
641 if (!ExprResolveVModMask(value, &rtrn, keymap))
643 ERROR("Preserve value in a key type is not a modifier mask\n");
644 ACTION("Ignoring preserve[%s] in type %s\n",
645 PreserveIndexTxt(keymap, &new), TypeTxt(keymap, type));
648 new.preMods = rtrn.uval & 0xff;
649 new.preVMods = (rtrn.uval >> 16) & 0xffff;
650 if ((new.preMods & (~new.indexMods))
651 || (new.preVMods & (~new.indexVMods)))
653 if (warningLevel > 0)
655 WARN("Illegal value for preserve[%s] in type %s\n",
656 PreserveTxt(keymap, &new), TypeTxt(keymap, type));
657 ACTION("Converted %s to ", PreserveIndexTxt(keymap, &new));
659 new.preMods &= new.indexMods;
660 new.preVMods &= new.indexVMods;
661 if (warningLevel > 0)
663 INFO("%s\n", PreserveIndexTxt(keymap, &new));
666 return AddPreserve(keymap, type, &new, true, true);
669 /***====================================================================***/
672 AddLevelName(struct xkb_keymap *keymap, KeyTypeInfo *type,
673 unsigned level, xkb_atom_t name, bool clobber)
675 if (level >= darray_size(type->lvlNames))
676 darray_resize0(type->lvlNames, level + 1);
678 if (darray_item(type->lvlNames, level) == name) {
679 if (warningLevel > 9) {
680 WARN("Duplicate names for level %d of key type %s\n",
681 level + 1, TypeTxt(keymap, type));
686 else if (darray_item(type->lvlNames, level) != XKB_ATOM_NONE) {
687 if (warningLevel > 0) {
688 const char *old, *new;
689 old = xkb_atom_text(keymap->ctx,
690 darray_item(type->lvlNames, level));
691 new = xkb_atom_text(keymap->ctx, name);
692 WARN("Multiple names for level %d of key type %s\n",
693 level + 1, TypeTxt(keymap, type));
695 ACTION("Using %s, ignoring %s\n", new, old);
697 ACTION("Using %s, ignoring %s\n", old, new);
704 darray_item(type->lvlNames, level) = name;
709 SetLevelName(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
714 xkb_atom_t level_name;
716 if (arrayNdx == NULL)
717 return ReportTypeShouldBeArray(keymap, type, "level name");
718 if (!ExprResolveLevel(keymap->ctx, arrayNdx, &rtrn))
719 return ReportTypeBadType(keymap, type, "level name", "integer");
720 level = rtrn.ival - 1;
721 if (!ExprResolveString(keymap->ctx, value, &rtrn))
723 ERROR("Non-string name for level %d in key type %s\n", level + 1,
724 xkb_atom_text(keymap->ctx, type->name));
725 ACTION("Ignoring illegal level name definition\n");
728 level_name = xkb_atom_intern(keymap->ctx, rtrn.str);
730 return AddLevelName(keymap, type, level, level_name, true);
733 /***====================================================================***/
736 * Parses the fields in a type "..." { } description.
738 * @param field The field to parse (e.g. modifiers, map, level_name)
741 SetKeyTypeField(KeyTypeInfo *type, struct xkb_keymap *keymap,
742 char *field, ExprDef *arrayNdx, ExprDef *value,
747 if (strcasecmp(field, "modifiers") == 0)
749 unsigned mods, vmods;
750 if (arrayNdx != NULL)
752 WARN("The modifiers field of a key type is not an array\n");
753 ACTION("Illegal array subscript ignored\n");
755 /* get modifier mask for current type */
756 if (!ExprResolveVModMask(value, &tmp, keymap))
758 ERROR("Key type mask field must be a modifier mask\n");
759 ACTION("Key type definition ignored\n");
762 mods = tmp.uval & 0xff; /* core mods */
763 vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
764 if (type->defs.defined & _KT_Mask)
766 WARN("Multiple modifier mask definitions for key type %s\n",
767 xkb_atom_text(keymap->ctx, type->name));
768 ACTION("Using %s, ", TypeMaskTxt(type, keymap));
769 INFO("ignoring %s\n", XkbcVModMaskText(keymap, mods, vmods));
774 type->defs.defined |= _KT_Mask;
777 else if (strcasecmp(field, "map") == 0)
779 type->defs.defined |= _KT_Map;
780 return SetMapEntry(type, keymap, arrayNdx, value);
782 else if (strcasecmp(field, "preserve") == 0)
784 type->defs.defined |= _KT_Preserve;
785 return SetPreserve(type, keymap, arrayNdx, value);
787 else if ((strcasecmp(field, "levelname") == 0) ||
788 (strcasecmp(field, "level_name") == 0))
790 type->defs.defined |= _KT_LevelNames;
791 return SetLevelName(type, keymap, arrayNdx, value);
793 ERROR("Unknown field %s in key type %s\n", field, TypeTxt(keymap, type));
794 ACTION("Definition ignored\n");
799 HandleKeyTypeVar(VarDef *stmt, struct xkb_keymap *keymap, KeyTypesInfo *info)
801 ExprResult elem, field;
804 if (!ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx))
805 return false; /* internal error, already reported */
806 if (elem.str && (strcasecmp(elem.str, "type") == 0))
807 return SetKeyTypeField(&info->dflt, keymap, field.str, arrayNdx,
809 if (elem.str != NULL)
811 ERROR("Default for unknown element %s\n", uStringText(elem.str));
812 ACTION("Value for field %s ignored\n", uStringText(field.str));
814 else if (field.str != NULL)
816 ERROR("Default defined for unknown field %s\n",
817 uStringText(field.str));
824 HandleKeyTypeBody(VarDef *def, struct xkb_keymap *keymap,
825 KeyTypeInfo *type, KeyTypesInfo *info)
828 ExprResult tmp, field;
831 for (; def != NULL; def = (VarDef *) def->common.next)
833 if ((def->name) && (def->name->type == ExprFieldRef))
835 ok = HandleKeyTypeVar(def, keymap, info);
838 ok = ExprResolveLhs(keymap, def->name, &tmp, &field, &arrayNdx);
840 ok = SetKeyTypeField(type, keymap, field.str, arrayNdx,
849 * Process a type "XYZ" { } specification in the xkb_types section.
853 HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
854 enum merge_mode merge, KeyTypesInfo *info)
858 struct xkb_kt_map_entry *entry;
860 if (def->merge != MERGE_DEFAULT)
863 type.defs.defined = 0;
864 type.defs.fileID = info->fileID;
865 type.defs.merge = merge;
866 type.defs.next = NULL;
867 type.name = def->name;
868 type.mask = info->dflt.mask;
869 type.vmask = info->dflt.vmask;
870 type.groupInfo = info->dflt.groupInfo;
872 darray_init(type.entries);
873 darray_init(type.lvlNames);
874 type.preserve = NULL;
876 /* Parse the actual content. */
877 if (!HandleKeyTypeBody(def->body, keymap, &type, info))
883 /* now copy any appropriate map, preserve or level names from the */
885 darray_foreach(entry, info->dflt.entries) {
886 if ((entry->mods.real_mods & type.mask) == entry->mods.real_mods &&
887 (entry->mods.vmods & type.vmask) == entry->mods.vmods)
888 AddMapEntry(keymap, &type, entry, false, false);
890 if (info->dflt.preserve)
892 PreserveInfo *dflt = info->dflt.preserve;
895 if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
896 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
898 AddPreserve(keymap, &type, dflt, false, false);
900 dflt = (PreserveInfo *) dflt->defs.next;
904 for (i = 0; i < darray_size(info->dflt.lvlNames); i++) {
905 if (i < type.numLevels &&
906 darray_item(info->dflt.lvlNames, i) != XKB_ATOM_NONE)
908 AddLevelName(keymap, &type, i,
909 darray_item(info->dflt.lvlNames, i), false);
913 /* Now add the new keytype to the info struct */
914 if (!AddKeyType(keymap, info, &type))
923 * Process an xkb_types section.
925 * @param file The parsed xkb_types section.
926 * @param merge Merge Strategy (e.g. MERGE_OVERRIDE)
927 * @param info Pointer to memory where the outcome will be stored.
930 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
931 enum merge_mode merge, KeyTypesInfo *info)
936 info->name = uDupString(file->name);
940 switch (stmt->stmtType)
943 if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, keymap, info))
946 case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
947 if (!HandleKeyTypeDef((KeyTypeDef *) stmt, keymap, merge, info))
951 if (!HandleKeyTypeVar((VarDef *) stmt, keymap, info))
954 case StmtVModDef: /* virtual_modifiers NumLock, ... */
955 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
958 case StmtKeyAliasDef:
959 ERROR("Key type files may not include other declarations\n");
960 ACTION("Ignoring definition of key alias\n");
964 ERROR("Key type files may not include other declarations\n");
965 ACTION("Ignoring definition of key name\n");
969 ERROR("Key type files may not include other declarations\n");
970 ACTION("Ignoring definition of symbol interpretation\n");
974 WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
979 if (info->errorCount > 10)
982 ERROR("Too many errors\n");
984 ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
991 CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
997 for (pre = def->preserve; pre != NULL;
998 pre = (PreserveInfo *) pre->defs.next)
1000 struct xkb_kt_map_entry * match;
1001 struct xkb_kt_map_entry tmp;
1002 tmp.mods.real_mods = pre->indexMods;
1003 tmp.mods.vmods = pre->indexVMods;
1005 AddMapEntry(keymap, def, &tmp, false, false);
1006 match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1009 WSGO("Couldn't find matching entry for preserve\n");
1010 ACTION("Aborting\n");
1013 pre->matchingMapIndex = match - &darray_item(def->entries, 0);
1015 type->mods.real_mods = def->mask;
1016 type->mods.vmods = def->vmask;
1017 type->num_levels = def->numLevels;
1018 memcpy(&type->map, &def->entries, sizeof(def->entries));
1021 type->preserve = uTypedCalloc(darray_size(type->map), struct xkb_mods);
1022 if (!type->preserve)
1024 WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1025 ACTION("Preserve setting for type %s lost\n",
1026 xkb_atom_text(keymap->ctx, def->name));
1030 pre = def->preserve;
1031 for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
1033 int ndx = pre->matchingMapIndex;
1034 type->preserve[ndx].mask = pre->preMods;
1035 type->preserve[ndx].real_mods = pre->preMods;
1036 type->preserve[ndx].vmods = pre->preVMods;
1041 type->preserve = NULL;
1042 type->name = xkb_atom_strdup(keymap->ctx, def->name);
1044 if (!darray_empty(def->lvlNames)) {
1045 type->level_names = calloc(darray_size(def->lvlNames),
1046 sizeof(*type->level_names));
1048 /* assert def->szNames<=def->numLevels */
1049 for (i = 0; i < darray_size(def->lvlNames); i++)
1050 type->level_names[i] =
1051 xkb_atom_strdup(keymap->ctx, darray_item(def->lvlNames, i));
1054 type->level_names = NULL;
1057 darray_init(def->entries);
1058 return XkbcComputeEffectiveMap(keymap, type, NULL);
1062 CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
1065 struct xkb_key_type *type, *next;
1069 InitKeyTypesInfo(&info, keymap, NULL);
1070 info.fileID = file->id;
1072 HandleKeyTypesFile(file, keymap, merge, &info);
1074 if (info.errorCount != 0)
1078 if (XkbcAllocNames(keymap, 0, 0) != Success)
1080 keymap->names->keytypes = strdup(info.name);
1084 if ((info.stdPresent & XkbOneLevelMask) == 0)
1086 if ((info.stdPresent & XkbTwoLevelMask) == 0)
1088 if ((info.stdPresent & XkbKeypadMask) == 0)
1090 if ((info.stdPresent & XkbAlphabeticMask) == 0)
1093 if (XkbcAllocClientMap(keymap, XkbKeyTypesMask, i) != Success) {
1094 WSGO("Couldn't allocate client map\n");
1098 darray_resize0(keymap->map->types, i);
1100 if (XkbAllRequiredTypes & (~info.stdPresent)) {
1101 unsigned missing, keypadVMod;
1103 missing = XkbAllRequiredTypes & (~info.stdPresent);
1104 keypadVMod = FindKeypadVMod(keymap);
1106 if (XkbcInitCanonicalKeyTypes(keymap, missing, keypadVMod) != Success) {
1107 WSGO("Couldn't initialize canonical key types\n");
1111 if (missing & XkbOneLevelMask)
1112 darray_item(keymap->map->types, XkbOneLevelIndex).name =
1113 xkb_atom_strdup(keymap->ctx, tok_ONE_LEVEL);
1114 if (missing & XkbTwoLevelMask)
1115 darray_item(keymap->map->types, XkbTwoLevelIndex).name =
1116 xkb_atom_strdup(keymap->ctx, tok_TWO_LEVEL);
1117 if (missing & XkbAlphabeticMask)
1118 darray_item(keymap->map->types, XkbAlphabeticIndex).name =
1119 xkb_atom_strdup(keymap->ctx, tok_ALPHABETIC);
1120 if (missing & XkbKeypadMask)
1121 darray_item(keymap->map->types, XkbKeypadIndex).name =
1122 xkb_atom_strdup(keymap->ctx, tok_KEYPAD);
1125 next = &darray_item(keymap->map->types, XkbLastRequiredType + 1);
1126 for (i = 0, def = info.types; i < info.nTypes; i++) {
1127 if (def->name == tok_ONE_LEVEL)
1128 type = &darray_item(keymap->map->types, XkbOneLevelIndex);
1129 else if (def->name == tok_TWO_LEVEL)
1130 type = &darray_item(keymap->map->types, XkbTwoLevelIndex);
1131 else if (def->name == tok_ALPHABETIC)
1132 type = &darray_item(keymap->map->types, XkbAlphabeticIndex);
1133 else if (def->name == tok_KEYPAD)
1134 type = &darray_item(keymap->map->types, XkbKeypadIndex);
1138 DeleteLevel1MapEntries(def);
1140 if (!CopyDefToKeyType(keymap, type, def))
1143 def = (KeyTypeInfo *)def->defs.next;
1146 FreeKeyTypesInfo(&info);
1150 FreeKeyTypesInfo(&info);