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_init(info->dflt.entries);
131 darray_from_items(info->dflt.entries,
132 &darray_item(from->dflt.entries, 0),
133 darray_size(from->dflt.entries));
135 darray_init(info->dflt.lvlNames);
136 darray_from_items(info->dflt.lvlNames,
137 &darray_item(from->dflt.lvlNames, 0),
138 darray_size(from->dflt.lvlNames));
140 if (from->dflt.preserve)
142 PreserveInfo *old, *new, *last;
144 old = from->dflt.preserve;
145 for (; old; old = (PreserveInfo *) old->defs.next)
147 new = uTypedAlloc(PreserveInfo);
151 new->defs.next = NULL;
153 last->defs.next = (CommonInfo *) new;
155 info->dflt.preserve = new;
163 FreeKeyTypeInfo(KeyTypeInfo * type)
165 darray_free(type->entries);
166 darray_init(type->entries);
167 darray_free(type->lvlNames);
168 darray_init(type->lvlNames);
169 if (type->preserve != NULL)
171 ClearCommonInfo(&type->preserve->defs);
172 type->preserve = NULL;
177 FreeKeyTypesInfo(KeyTypesInfo * info)
184 for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
186 FreeKeyTypeInfo(type);
188 info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs);
190 FreeKeyTypeInfo(&info->dflt);
194 NextKeyType(KeyTypesInfo * info)
198 type = uTypedAlloc(KeyTypeInfo);
201 memset(type, 0, sizeof(KeyTypeInfo));
202 type->defs.fileID = info->fileID;
203 info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs,
204 (CommonInfo *) type);
211 FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
215 for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
217 if (old->name == new->name)
224 ReportTypeBadWidth(const char *type, int has, int needs)
226 ERROR("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
227 ACTION("Illegal type definition ignored\n");
232 AddKeyType(struct xkb_keymap *keymap, KeyTypesInfo *info, KeyTypeInfo *new)
236 if (new->name == tok_ONE_LEVEL)
238 if (new->numLevels > 1)
239 return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
240 info->stdPresent |= XkbOneLevelMask;
242 else if (new->name == tok_TWO_LEVEL)
244 if (new->numLevels > 2)
245 return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
246 else if (new->numLevels < 2)
248 info->stdPresent |= XkbTwoLevelMask;
250 else if (new->name == tok_ALPHABETIC)
252 if (new->numLevels > 2)
253 return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
254 else if (new->numLevels < 2)
256 info->stdPresent |= XkbAlphabeticMask;
258 else if (new->name == tok_KEYPAD)
260 if (new->numLevels > 2)
261 return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
262 else if (new->numLevels < 2)
264 info->stdPresent |= XkbKeypadMask;
267 old = FindMatchingKeyType(info, new);
271 if ((new->defs.merge == MergeReplace)
272 || (new->defs.merge == MergeOverride))
274 KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
275 if (((old->defs.fileID == new->defs.fileID)
276 && (warningLevel > 0)) || (warningLevel > 9))
278 WARN("Multiple definitions of the %s key type\n",
279 xkb_atom_text(keymap->ctx, new->name));
280 ACTION("Earlier definition ignored\n");
282 FreeKeyTypeInfo(old);
284 darray_init(new->entries);
285 darray_init(new->lvlNames);
286 new->preserve = NULL;
287 old->defs.next = &next->defs;
290 report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
293 WARN("Multiple definitions of the %s key type\n",
294 xkb_atom_text(keymap->ctx, new->name));
295 ACTION("Later definition ignored\n");
297 FreeKeyTypeInfo(new);
300 old = NextKeyType(info);
304 old->defs.next = NULL;
305 darray_init(new->entries);
306 darray_init(new->lvlNames);
307 new->preserve = NULL;
311 /***====================================================================***/
314 MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
315 unsigned merge, struct xkb_keymap *keymap)
319 if (from->errorCount > 0)
321 into->errorCount += from->errorCount;
324 if (into->name == NULL)
326 into->name = from->name;
329 for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
331 if (merge != MergeDefault)
332 type->defs.merge = merge;
333 if (!AddKeyType(keymap, into, type))
336 into->stdPresent |= from->stdPresent;
340 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
341 unsigned merge, KeyTypesInfo *info);
344 HandleIncludeKeyTypes(IncludeStmt *stmt, struct xkb_keymap *keymap,
349 KeyTypesInfo included;
353 if ((stmt->file == NULL) && (stmt->map == NULL))
357 memset(info, 0, sizeof(KeyTypesInfo));
359 else if (ProcessIncludeFile(keymap->ctx, stmt, XkmTypesIndex, &rtrn,
362 InitKeyTypesInfo(&included, keymap, info);
363 included.fileID = included.dflt.defs.fileID = rtrn->id;
364 included.dflt.defs.merge = newMerge;
366 HandleKeyTypesFile(rtrn, keymap, newMerge, &included);
367 if (stmt->stmt != NULL)
370 included.name = stmt->stmt;
377 info->errorCount += 10;
380 if ((stmt->next != NULL) && (included.errorCount < 1))
384 KeyTypesInfo next_incl;
386 for (next = stmt->next; next != NULL; next = next->next)
388 if ((next->file == NULL) && (next->map == NULL))
391 MergeIncludedKeyTypes(&included, info, next->merge, keymap);
392 FreeKeyTypesInfo(info);
394 else if (ProcessIncludeFile(keymap->ctx, next, XkmTypesIndex,
397 InitKeyTypesInfo(&next_incl, keymap, &included);
398 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
399 next_incl.dflt.defs.merge = op;
400 HandleKeyTypesFile(rtrn, keymap, op, &next_incl);
401 MergeIncludedKeyTypes(&included, &next_incl, op, keymap);
402 FreeKeyTypesInfo(&next_incl);
407 info->errorCount += 10;
408 FreeKeyTypesInfo(&included);
417 MergeIncludedKeyTypes(info, &included, newMerge, keymap);
418 FreeKeyTypesInfo(&included);
420 return (info->errorCount == 0);
423 /***====================================================================***/
425 static struct xkb_kt_map_entry *
426 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
428 struct xkb_kt_map_entry *entry;
430 darray_foreach(entry, type->entries)
431 if (entry->mods.real_mods == mask && entry->mods.vmods == vmask)
438 DeleteLevel1MapEntries(KeyTypeInfo * type)
442 /* TODO: Be just a bit more clever here. */
443 for (i = 0; i < darray_size(type->entries); i++) {
444 if (darray_item(type->entries, i).level == 0) {
445 for (n = i; n < darray_size(type->entries) - 1; n++)
446 darray_item(type->entries, n) =
447 darray_item(type->entries, n + 1);
448 (void)darray_pop(type->entries);
453 static struct xkb_kt_map_entry *
454 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
456 darray_resize0(type->entries, darray_size(type->entries) + 1);
457 return &darray_item(type->entries, darray_size(type->entries) - 1);
461 AddPreserve(struct xkb_keymap *keymap, KeyTypeInfo *type,
462 PreserveInfo *new, bool clobber, bool report)
466 old = type->preserve;
469 if ((old->indexMods != new->indexMods) ||
470 (old->indexVMods != new->indexVMods))
472 old = (PreserveInfo *) old->defs.next;
475 if ((old->preMods == new->preMods)
476 && (old->preVMods == new->preVMods))
478 if (warningLevel > 9)
480 WARN("Identical definitions for preserve[%s] in %s\n",
481 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
486 if (report && (warningLevel > 0))
489 WARN("Multiple definitions for preserve[%s] in %s\n",
490 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
493 str = PreserveTxt(keymap, new);
495 str = PreserveTxt(keymap, old);
496 ACTION("Using %s, ", str);
498 str = PreserveTxt(keymap, old);
500 str = PreserveTxt(keymap, new);
501 INFO("ignoring %s\n", str);
505 old->preMods = new->preMods;
506 old->preVMods = new->preVMods;
510 old = uTypedAlloc(PreserveInfo);
513 WSGO("Couldn't allocate preserve in %s\n", TypeTxt(keymap, type));
514 ACTION("Preserve[%s] lost\n", PreserveIndexTxt(keymap, new));
518 old->matchingMapIndex = -1;
520 (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
525 * Add a new KTMapEntry to the given key type. If an entry with the same mods
526 * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
529 * @param clobber Overwrite existing entry.
530 * @param report true if a warning is to be printed on.
533 AddMapEntry(struct xkb_keymap *keymap, KeyTypeInfo *type,
534 struct xkb_kt_map_entry *new, bool clobber, bool report)
536 struct xkb_kt_map_entry * old;
539 FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
541 if (report && (old->level != new->level))
543 unsigned use, ignore;
546 use = new->level + 1;
547 ignore = old->level + 1;
551 use = old->level + 1;
552 ignore = new->level + 1;
554 WARN("Multiple map entries for %s in %s\n",
555 MapEntryTxt(keymap, new), TypeTxt(keymap, type));
556 ACTION("Using %d, ignoring %d\n", use, ignore);
558 else if (warningLevel > 9)
560 WARN("Multiple occurences of map[%s]= %d in %s\n",
561 MapEntryTxt(keymap, new), new->level + 1,
562 TypeTxt(keymap, type));
567 old->level = new->level;
570 if ((old = NextMapEntry(keymap, type)) == NULL)
571 return false; /* allocation failure, already reported */
572 if (new->level >= type->numLevels)
573 type->numLevels = new->level + 1;
574 if (new->mods.vmods == 0)
578 old->mods.mask = new->mods.real_mods;
579 old->mods.real_mods = new->mods.real_mods;
580 old->mods.vmods = new->mods.vmods;
581 old->level = new->level;
586 SetMapEntry(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
590 struct xkb_kt_map_entry entry;
592 if (arrayNdx == NULL)
593 return ReportTypeShouldBeArray(keymap, type, "map entry");
594 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
595 return ReportTypeBadType(keymap, type, "map entry", "modifier mask");
596 entry.mods.real_mods = rtrn.uval & 0xff; /* modifiers < 512 */
597 entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
598 if ((entry.mods.real_mods & (~type->mask)) ||
599 ((entry.mods.vmods & (~type->vmask)) != 0))
601 if (warningLevel > 0)
603 WARN("Map entry for unused modifiers in %s\n", TypeTxt(keymap, type));
604 ACTION("Using %s instead of ",
605 XkbcVModMaskText(keymap,
606 entry.mods.real_mods & type->mask,
607 entry.mods.vmods & type->vmask));
608 INFO("%s\n", MapEntryTxt(keymap, &entry));
610 entry.mods.real_mods &= type->mask;
611 entry.mods.vmods &= type->vmask;
613 if (!ExprResolveLevel(keymap->ctx, value, &rtrn))
615 ERROR("Level specifications in a key type must be integer\n");
616 ACTION("Ignoring malformed level specification\n");
619 entry.level = rtrn.ival - 1;
620 return AddMapEntry(keymap, type, &entry, true, true);
624 SetPreserve(KeyTypeInfo *type, struct xkb_keymap *keymap,
625 ExprDef *arrayNdx, ExprDef *value)
630 if (arrayNdx == NULL)
631 return ReportTypeShouldBeArray(keymap, type, "preserve entry");
632 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
633 return ReportTypeBadType(keymap, type, "preserve entry",
635 new.defs = type->defs;
636 new.defs.next = NULL;
637 new.indexMods = rtrn.uval & 0xff;
638 new.indexVMods = (rtrn.uval >> 8) & 0xffff;
639 if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
641 if (warningLevel > 0)
643 WARN("Preserve for modifiers not used by the %s type\n",
644 TypeTxt(keymap, type));
645 ACTION("Index %s converted to ", PreserveIndexTxt(keymap, &new));
647 new.indexMods &= type->mask;
648 new.indexVMods &= type->vmask;
649 if (warningLevel > 0)
650 INFO("%s\n", PreserveIndexTxt(keymap, &new));
652 if (!ExprResolveVModMask(value, &rtrn, keymap))
654 ERROR("Preserve value in a key type is not a modifier mask\n");
655 ACTION("Ignoring preserve[%s] in type %s\n",
656 PreserveIndexTxt(keymap, &new), TypeTxt(keymap, type));
659 new.preMods = rtrn.uval & 0xff;
660 new.preVMods = (rtrn.uval >> 16) & 0xffff;
661 if ((new.preMods & (~new.indexMods))
662 || (new.preVMods & (~new.indexVMods)))
664 if (warningLevel > 0)
666 WARN("Illegal value for preserve[%s] in type %s\n",
667 PreserveTxt(keymap, &new), TypeTxt(keymap, type));
668 ACTION("Converted %s to ", PreserveIndexTxt(keymap, &new));
670 new.preMods &= new.indexMods;
671 new.preVMods &= new.indexVMods;
672 if (warningLevel > 0)
674 INFO("%s\n", PreserveIndexTxt(keymap, &new));
677 return AddPreserve(keymap, type, &new, true, true);
680 /***====================================================================***/
683 AddLevelName(struct xkb_keymap *keymap, KeyTypeInfo *type,
684 unsigned level, xkb_atom_t name, bool clobber)
686 if (level >= darray_size(type->lvlNames))
687 darray_resize0(type->lvlNames, level + 1);
689 if (darray_item(type->lvlNames, level) == name) {
690 if (warningLevel > 9) {
691 WARN("Duplicate names for level %d of key type %s\n",
692 level + 1, TypeTxt(keymap, type));
697 else if (darray_item(type->lvlNames, level) != XKB_ATOM_NONE) {
698 if (warningLevel > 0) {
699 const char *old, *new;
700 old = xkb_atom_text(keymap->ctx,
701 darray_item(type->lvlNames, level));
702 new = xkb_atom_text(keymap->ctx, name);
703 WARN("Multiple names for level %d of key type %s\n",
704 level + 1, TypeTxt(keymap, type));
706 ACTION("Using %s, ignoring %s\n", new, old);
708 ACTION("Using %s, ignoring %s\n", old, new);
715 darray_item(type->lvlNames, level) = name;
720 SetLevelName(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
725 xkb_atom_t level_name;
727 if (arrayNdx == NULL)
728 return ReportTypeShouldBeArray(keymap, type, "level name");
729 if (!ExprResolveLevel(keymap->ctx, arrayNdx, &rtrn))
730 return ReportTypeBadType(keymap, type, "level name", "integer");
731 level = rtrn.ival - 1;
732 if (!ExprResolveString(keymap->ctx, value, &rtrn))
734 ERROR("Non-string name for level %d in key type %s\n", level + 1,
735 xkb_atom_text(keymap->ctx, type->name));
736 ACTION("Ignoring illegal level name definition\n");
739 level_name = xkb_atom_intern(keymap->ctx, rtrn.str);
741 return AddLevelName(keymap, type, level, level_name, true);
744 /***====================================================================***/
747 * Parses the fields in a type "..." { } description.
749 * @param field The field to parse (e.g. modifiers, map, level_name)
752 SetKeyTypeField(KeyTypeInfo *type, struct xkb_keymap *keymap,
753 char *field, ExprDef *arrayNdx, ExprDef *value,
758 if (strcasecmp(field, "modifiers") == 0)
760 unsigned mods, vmods;
761 if (arrayNdx != NULL)
763 WARN("The modifiers field of a key type is not an array\n");
764 ACTION("Illegal array subscript ignored\n");
766 /* get modifier mask for current type */
767 if (!ExprResolveVModMask(value, &tmp, keymap))
769 ERROR("Key type mask field must be a modifier mask\n");
770 ACTION("Key type definition ignored\n");
773 mods = tmp.uval & 0xff; /* core mods */
774 vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
775 if (type->defs.defined & _KT_Mask)
777 WARN("Multiple modifier mask definitions for key type %s\n",
778 xkb_atom_text(keymap->ctx, type->name));
779 ACTION("Using %s, ", TypeMaskTxt(type, keymap));
780 INFO("ignoring %s\n", XkbcVModMaskText(keymap, mods, vmods));
785 type->defs.defined |= _KT_Mask;
788 else if (strcasecmp(field, "map") == 0)
790 type->defs.defined |= _KT_Map;
791 return SetMapEntry(type, keymap, arrayNdx, value);
793 else if (strcasecmp(field, "preserve") == 0)
795 type->defs.defined |= _KT_Preserve;
796 return SetPreserve(type, keymap, arrayNdx, value);
798 else if ((strcasecmp(field, "levelname") == 0) ||
799 (strcasecmp(field, "level_name") == 0))
801 type->defs.defined |= _KT_LevelNames;
802 return SetLevelName(type, keymap, arrayNdx, value);
804 ERROR("Unknown field %s in key type %s\n", field, TypeTxt(keymap, type));
805 ACTION("Definition ignored\n");
810 HandleKeyTypeVar(VarDef *stmt, struct xkb_keymap *keymap, KeyTypesInfo *info)
812 ExprResult elem, field;
815 if (!ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx))
816 return false; /* internal error, already reported */
817 if (elem.str && (strcasecmp(elem.str, "type") == 0))
818 return SetKeyTypeField(&info->dflt, keymap, field.str, arrayNdx,
820 if (elem.str != NULL)
822 ERROR("Default for unknown element %s\n", uStringText(elem.str));
823 ACTION("Value for field %s ignored\n", uStringText(field.str));
825 else if (field.str != NULL)
827 ERROR("Default defined for unknown field %s\n",
828 uStringText(field.str));
835 HandleKeyTypeBody(VarDef *def, struct xkb_keymap *keymap,
836 KeyTypeInfo *type, KeyTypesInfo *info)
839 ExprResult tmp, field;
842 for (; def != NULL; def = (VarDef *) def->common.next)
844 if ((def->name) && (def->name->type == ExprFieldRef))
846 ok = HandleKeyTypeVar(def, keymap, info);
849 ok = ExprResolveLhs(keymap, def->name, &tmp, &field, &arrayNdx);
851 ok = SetKeyTypeField(type, keymap, field.str, arrayNdx,
860 * Process a type "XYZ" { } specification in the xkb_types section.
864 HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
865 unsigned merge, KeyTypesInfo *info)
869 struct xkb_kt_map_entry *entry;
871 if (def->merge != MergeDefault)
874 type.defs.defined = 0;
875 type.defs.fileID = info->fileID;
876 type.defs.merge = merge;
877 type.defs.next = NULL;
878 type.name = def->name;
879 type.mask = info->dflt.mask;
880 type.vmask = info->dflt.vmask;
881 type.groupInfo = info->dflt.groupInfo;
883 darray_init(type.entries);
884 darray_init(type.lvlNames);
885 type.preserve = NULL;
887 /* Parse the actual content. */
888 if (!HandleKeyTypeBody(def->body, keymap, &type, info))
894 /* now copy any appropriate map, preserve or level names from the */
896 darray_foreach(entry, info->dflt.entries) {
897 if ((entry->mods.real_mods & type.mask) == entry->mods.real_mods &&
898 (entry->mods.vmods & type.vmask) == entry->mods.vmods)
899 AddMapEntry(keymap, &type, entry, false, false);
901 if (info->dflt.preserve)
903 PreserveInfo *dflt = info->dflt.preserve;
906 if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
907 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
909 AddPreserve(keymap, &type, dflt, false, false);
911 dflt = (PreserveInfo *) dflt->defs.next;
915 for (i = 0; i < darray_size(info->dflt.lvlNames); i++) {
916 if (i < type.numLevels &&
917 darray_item(info->dflt.lvlNames, i) != XKB_ATOM_NONE)
919 AddLevelName(keymap, &type, i,
920 darray_item(info->dflt.lvlNames, i), false);
924 /* Now add the new keytype to the info struct */
925 if (!AddKeyType(keymap, info, &type))
934 * Process an xkb_types section.
936 * @param file The parsed xkb_types section.
937 * @param merge Merge Strategy (e.g. MergeOverride)
938 * @param info Pointer to memory where the outcome will be stored.
941 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
942 unsigned merge, KeyTypesInfo *info)
947 info->name = uDupString(file->name);
951 switch (stmt->stmtType)
954 if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, keymap, info))
957 case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
958 if (!HandleKeyTypeDef((KeyTypeDef *) stmt, keymap, merge, info))
962 if (!HandleKeyTypeVar((VarDef *) stmt, keymap, info))
965 case StmtVModDef: /* virtual_modifiers NumLock, ... */
966 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
969 case StmtKeyAliasDef:
970 ERROR("Key type files may not include other declarations\n");
971 ACTION("Ignoring definition of key alias\n");
975 ERROR("Key type files may not include other declarations\n");
976 ACTION("Ignoring definition of key name\n");
980 ERROR("Key type files may not include other declarations\n");
981 ACTION("Ignoring definition of symbol interpretation\n");
985 WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
990 if (info->errorCount > 10)
993 ERROR("Too many errors\n");
995 ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
1002 CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
1008 for (pre = def->preserve; pre != NULL;
1009 pre = (PreserveInfo *) pre->defs.next)
1011 struct xkb_kt_map_entry * match;
1012 struct xkb_kt_map_entry tmp;
1013 tmp.mods.real_mods = pre->indexMods;
1014 tmp.mods.vmods = pre->indexVMods;
1016 AddMapEntry(keymap, def, &tmp, false, false);
1017 match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1020 WSGO("Couldn't find matching entry for preserve\n");
1021 ACTION("Aborting\n");
1024 pre->matchingMapIndex = match - &darray_item(def->entries, 0);
1026 type->mods.real_mods = def->mask;
1027 type->mods.vmods = def->vmask;
1028 type->num_levels = def->numLevels;
1029 memcpy(&type->map, &def->entries, sizeof(def->entries));
1032 type->preserve = uTypedCalloc(darray_size(type->map), struct xkb_mods);
1033 if (!type->preserve)
1035 WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1036 ACTION("Preserve setting for type %s lost\n",
1037 xkb_atom_text(keymap->ctx, def->name));
1041 pre = def->preserve;
1042 for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
1044 int ndx = pre->matchingMapIndex;
1045 type->preserve[ndx].mask = pre->preMods;
1046 type->preserve[ndx].real_mods = pre->preMods;
1047 type->preserve[ndx].vmods = pre->preVMods;
1052 type->preserve = NULL;
1053 type->name = xkb_atom_strdup(keymap->ctx, def->name);
1055 if (!darray_empty(def->lvlNames)) {
1056 type->level_names = calloc(darray_size(def->lvlNames),
1057 sizeof(*type->level_names));
1059 /* assert def->szNames<=def->numLevels */
1060 for (i = 0; i < darray_size(def->lvlNames); i++)
1061 type->level_names[i] =
1062 xkb_atom_strdup(keymap->ctx, darray_item(def->lvlNames, i));
1065 type->level_names = NULL;
1068 darray_init(def->entries);
1069 return XkbcComputeEffectiveMap(keymap, type, NULL);
1073 CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
1076 struct xkb_key_type *type, *next;
1080 InitKeyTypesInfo(&info, keymap, NULL);
1081 info.fileID = file->id;
1083 HandleKeyTypesFile(file, keymap, merge, &info);
1085 if (info.errorCount != 0)
1089 if ((info.stdPresent & XkbOneLevelMask) == 0)
1091 if ((info.stdPresent & XkbTwoLevelMask) == 0)
1093 if ((info.stdPresent & XkbKeypadMask) == 0)
1095 if ((info.stdPresent & XkbAlphabeticMask) == 0)
1098 if (XkbcAllocClientMap(keymap, XkbKeyTypesMask, i) != Success) {
1099 WSGO("Couldn't allocate client map\n");
1103 darray_resize0(keymap->map->types, i);
1105 if (XkbAllRequiredTypes & (~info.stdPresent)) {
1106 unsigned missing, keypadVMod;
1108 missing = XkbAllRequiredTypes & (~info.stdPresent);
1109 keypadVMod = FindKeypadVMod(keymap);
1111 if (XkbcInitCanonicalKeyTypes(keymap, missing, keypadVMod) != Success) {
1112 WSGO("Couldn't initialize canonical key types\n");
1116 if (missing & XkbOneLevelMask)
1117 darray_item(keymap->map->types, XkbOneLevelIndex).name =
1118 xkb_atom_strdup(keymap->ctx, tok_ONE_LEVEL);
1119 if (missing & XkbTwoLevelMask)
1120 darray_item(keymap->map->types, XkbTwoLevelIndex).name =
1121 xkb_atom_strdup(keymap->ctx, tok_TWO_LEVEL);
1122 if (missing & XkbAlphabeticMask)
1123 darray_item(keymap->map->types, XkbAlphabeticIndex).name =
1124 xkb_atom_strdup(keymap->ctx, tok_ALPHABETIC);
1125 if (missing & XkbKeypadMask)
1126 darray_item(keymap->map->types, XkbKeypadIndex).name =
1127 xkb_atom_strdup(keymap->ctx, tok_KEYPAD);
1130 next = &darray_item(keymap->map->types, XkbLastRequiredType + 1);
1131 for (i = 0, def = info.types; i < info.nTypes; i++) {
1132 if (def->name == tok_ONE_LEVEL)
1133 type = &darray_item(keymap->map->types, XkbOneLevelIndex);
1134 else if (def->name == tok_TWO_LEVEL)
1135 type = &darray_item(keymap->map->types, XkbTwoLevelIndex);
1136 else if (def->name == tok_ALPHABETIC)
1137 type = &darray_item(keymap->map->types, XkbAlphabeticIndex);
1138 else if (def->name == tok_KEYPAD)
1139 type = &darray_item(keymap->map->types, XkbKeypadIndex);
1143 DeleteLevel1MapEntries(def);
1145 if (!CopyDefToKeyType(keymap, type, def))
1148 def = (KeyTypeInfo *)def->defs.next;
1151 FreeKeyTypesInfo(&info);
1155 FreeKeyTypesInfo(&info);