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 {
33 short matchingMapIndex;
34 unsigned char indexMods;
35 unsigned char preMods;
36 unsigned short indexVMods;
37 unsigned short preVMods;
40 #define _KT_Name (1 << 0)
41 #define _KT_Mask (1 << 1)
42 #define _KT_Map (1 << 2)
43 #define _KT_Preserve (1 << 3)
44 #define _KT_LevelNames (1 << 4)
46 typedef struct _KeyTypeInfo {
53 darray(struct xkb_kt_map_entry) entries;
54 struct list preserves;
55 darray(xkb_atom_t) lvlNames;
58 typedef struct _KeyTypesInfo {
68 xkb_atom_t tok_ONE_LEVEL;
69 xkb_atom_t tok_TWO_LEVEL;
70 xkb_atom_t tok_ALPHABETIC;
71 xkb_atom_t tok_KEYPAD;
74 /***====================================================================***/
76 static inline const char *
77 MapEntryTxt(struct xkb_keymap *keymap, struct xkb_kt_map_entry *entry)
79 return XkbcVModMaskText(keymap, entry->mods.real_mods, entry->mods.vmods);
82 static inline const char *
83 PreserveIndexTxt(struct xkb_keymap *keymap, PreserveInfo *pi)
85 return XkbcVModMaskText(keymap, pi->indexMods, pi->indexVMods);
88 static inline const char *
89 PreserveTxt(struct xkb_keymap *keymap, PreserveInfo *pi)
91 return XkbcVModMaskText(keymap, pi->preMods, pi->preVMods);
94 static inline const char *
95 TypeTxt(struct xkb_keymap *keymap, KeyTypeInfo *type)
97 return xkb_atom_text(keymap->ctx, type->name);
100 static inline const char *
101 TypeMaskTxt(struct xkb_keymap *keymap, KeyTypeInfo *type)
103 return XkbcVModMaskText(keymap, type->mask, type->vmask);
107 ReportTypeShouldBeArray(struct xkb_keymap *keymap, KeyTypeInfo *type,
110 return ReportShouldBeArray("key type", field, TypeTxt(keymap, type));
114 ReportTypeBadType(struct xkb_keymap *keymap, KeyTypeInfo *type,
115 const char *field, const char *wanted)
117 return ReportBadType("key type", field, TypeTxt(keymap, type), wanted);
120 /***====================================================================***/
123 InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
124 KeyTypesInfo *from, unsigned file_id)
126 PreserveInfo *old, *new;
128 info->tok_ONE_LEVEL = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
129 info->tok_TWO_LEVEL = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
130 info->tok_ALPHABETIC = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
131 info->tok_KEYPAD = xkb_atom_intern(keymap->ctx, "KEYPAD");
132 info->name = strdup("default");
133 info->errorCount = 0;
134 info->stdPresent = 0;
137 info->file_id = file_id;
138 info->dflt.defs.defined = 0;
139 info->dflt.defs.file_id = file_id;
140 info->dflt.defs.merge = MERGE_OVERRIDE;
141 info->dflt.defs.next = NULL;
142 info->dflt.name = XKB_ATOM_NONE;
144 info->dflt.vmask = 0;
145 info->dflt.numLevels = 1;
146 darray_init(info->dflt.entries);
147 darray_init(info->dflt.lvlNames);
148 list_init(&info->dflt.preserves);
149 InitVModInfo(&info->vmods, keymap);
154 info->dflt = from->dflt;
156 darray_copy(info->dflt.entries, from->dflt.entries);
157 darray_copy(info->dflt.lvlNames, from->dflt.lvlNames);
159 list_init(&info->dflt.preserves);
160 list_foreach(old, &from->dflt.preserves, entry) {
161 new = malloc(sizeof(*new));
166 list_append(&new->entry, &info->dflt.preserves);
171 FreeKeyTypeInfo(KeyTypeInfo * type)
173 PreserveInfo *pi, *next_pi;
174 darray_free(type->entries);
175 darray_free(type->lvlNames);
176 list_foreach_safe(pi, next_pi, &type->preserves, entry)
178 list_init(&type->preserves);
182 FreeKeyTypesInfo(KeyTypesInfo * info)
188 for (type = info->types; type; type =
189 (KeyTypeInfo *) type->defs.next) {
190 FreeKeyTypeInfo(type);
192 info->types = ClearCommonInfo(&info->types->defs);
194 FreeKeyTypeInfo(&info->dflt);
198 NextKeyType(KeyTypesInfo * info)
202 type = uTypedAlloc(KeyTypeInfo);
204 memset(type, 0, sizeof(KeyTypeInfo));
205 list_init(&type->preserves);
206 type->defs.file_id = info->file_id;
207 info->types = AddCommonInfo(&info->types->defs, &type->defs);
214 FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
218 for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next) {
219 if (old->name == new->name)
226 ReportTypeBadWidth(const char *type, int has, int needs)
228 ERROR("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
229 ACTION("Illegal type definition ignored\n");
234 AddKeyType(struct xkb_keymap *keymap, KeyTypesInfo *info, KeyTypeInfo *new)
239 if (new->name == info->tok_ONE_LEVEL) {
240 if (new->numLevels > 1)
241 return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
242 info->stdPresent |= XkbOneLevelMask;
244 else if (new->name == info->tok_TWO_LEVEL) {
245 if (new->numLevels > 2)
246 return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
247 else if (new->numLevels < 2)
249 info->stdPresent |= XkbTwoLevelMask;
251 else if (new->name == info->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 == info->tok_KEYPAD) {
259 if (new->numLevels > 2)
260 return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
261 else if (new->numLevels < 2)
263 info->stdPresent |= XkbKeypadMask;
266 old = FindMatchingKeyType(info, new);
269 if ((new->defs.merge == MERGE_REPLACE)
270 || (new->defs.merge == MERGE_OVERRIDE)) {
271 KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
272 if (((old->defs.file_id == new->defs.file_id)
273 && (warningLevel > 0)) || (warningLevel > 9)) {
274 WARN("Multiple definitions of the %s key type\n",
275 xkb_atom_text(keymap->ctx, new->name));
276 ACTION("Earlier definition ignored\n");
278 FreeKeyTypeInfo(old);
280 darray_init(new->entries);
281 darray_init(new->lvlNames);
282 list_init(&new->preserves);
283 old->defs.next = &next->defs;
286 report = (old->defs.file_id == new->defs.file_id) &&
289 WARN("Multiple definitions of the %s key type\n",
290 xkb_atom_text(keymap->ctx, new->name));
291 ACTION("Later definition ignored\n");
293 FreeKeyTypeInfo(new);
296 old = NextKeyType(info);
299 list_replace(&new->preserves, &old->preserves);
300 entry = old->preserves;
302 old->preserves = entry;
303 old->defs.next = NULL;
304 darray_init(new->entries);
305 darray_init(new->lvlNames);
306 list_init(&new->preserves);
310 /***====================================================================***/
313 MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
314 enum merge_mode merge, struct xkb_keymap *keymap)
318 if (from->errorCount > 0) {
319 into->errorCount += from->errorCount;
322 if (into->name == NULL) {
323 into->name = from->name;
326 for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next) {
327 if (merge != MERGE_DEFAULT)
328 type->defs.merge = merge;
329 if (!AddKeyType(keymap, into, type))
332 into->stdPresent |= from->stdPresent;
336 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
337 enum merge_mode merge,
341 HandleIncludeKeyTypes(IncludeStmt *stmt, struct xkb_keymap *keymap,
344 enum merge_mode merge = MERGE_DEFAULT;
346 KeyTypesInfo included, next_incl;
348 InitKeyTypesInfo(&included, keymap, info, info->file_id);
351 included.name = stmt->stmt;
355 for (; stmt; stmt = stmt->next) {
356 if (!ProcessIncludeFile(keymap->ctx, stmt, FILE_TYPE_TYPES,
358 info->errorCount += 10;
359 FreeKeyTypesInfo(&included);
363 InitKeyTypesInfo(&next_incl, keymap, &included, rtrn->id);
364 next_incl.dflt.defs.merge = merge;
366 HandleKeyTypesFile(rtrn, keymap, merge, &next_incl);
368 MergeIncludedKeyTypes(&included, &next_incl, merge, keymap);
370 FreeKeyTypesInfo(&next_incl);
374 MergeIncludedKeyTypes(info, &included, merge, keymap);
375 FreeKeyTypesInfo(&included);
377 return (info->errorCount == 0);
380 /***====================================================================***/
382 static struct xkb_kt_map_entry *
383 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
385 struct xkb_kt_map_entry *entry;
387 darray_foreach(entry, type->entries)
388 if (entry->mods.real_mods == mask && entry->mods.vmods == vmask)
395 DeleteLevel1MapEntries(KeyTypeInfo * type)
399 /* TODO: Be just a bit more clever here. */
400 for (i = 0; i < darray_size(type->entries); i++) {
401 if (darray_item(type->entries, i).level == 0) {
402 for (n = i; n < darray_size(type->entries) - 1; n++)
403 darray_item(type->entries, n) =
404 darray_item(type->entries, n + 1);
405 (void) darray_pop(type->entries);
410 static struct xkb_kt_map_entry *
411 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
413 darray_resize0(type->entries, darray_size(type->entries) + 1);
414 return &darray_item(type->entries, darray_size(type->entries) - 1);
418 AddPreserve(struct xkb_keymap *keymap, KeyTypeInfo *type,
419 PreserveInfo *new, bool clobber, bool report)
423 list_foreach(old, &type->preserves, entry) {
424 if (old->indexMods != new->indexMods ||
425 old->indexVMods != new->indexVMods)
428 if (old->preMods == new->preMods && old->preVMods == new->preVMods) {
429 if (warningLevel > 9) {
430 WARN("Identical definitions for preserve[%s] in %s\n",
431 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
437 if (report && warningLevel > 0) {
439 WARN("Multiple definitions for preserve[%s] in %s\n",
440 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
441 str = PreserveTxt(keymap, clobber ? new : old);
442 ACTION("Using %s, ", str);
443 str = PreserveTxt(keymap, clobber ? old : new);
444 INFO("ignoring %s\n", str);
448 old->preMods = new->preMods;
449 old->preVMods = new->preVMods;
455 old = malloc(sizeof(*old));
457 WSGO("Couldn't allocate preserve in %s\n", TypeTxt(keymap, type));
458 ACTION("Preserve[%s] lost\n", PreserveIndexTxt(keymap, new));
463 old->matchingMapIndex = -1;
464 list_append(&old->entry, &type->preserves);
470 * Add a new KTMapEntry to the given key type. If an entry with the same mods
471 * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
474 * @param clobber Overwrite existing entry.
475 * @param report true if a warning is to be printed on.
478 AddMapEntry(struct xkb_keymap *keymap, KeyTypeInfo *type,
479 struct xkb_kt_map_entry *new, bool clobber, bool report)
481 struct xkb_kt_map_entry * old;
484 FindMatchingMapEntry(type, new->mods.real_mods,
486 if (report && (old->level != new->level)) {
487 unsigned use, ignore;
489 use = new->level + 1;
490 ignore = old->level + 1;
493 use = old->level + 1;
494 ignore = new->level + 1;
496 WARN("Multiple map entries for %s in %s\n",
497 MapEntryTxt(keymap, new), TypeTxt(keymap, type));
498 ACTION("Using %d, ignoring %d\n", use, ignore);
500 else if (warningLevel > 9) {
501 WARN("Multiple occurences of map[%s]= %d in %s\n",
502 MapEntryTxt(keymap, new), new->level + 1,
503 TypeTxt(keymap, type));
508 old->level = new->level;
511 if ((old = NextMapEntry(keymap, type)) == NULL)
512 return false; /* allocation failure, already reported */
513 if (new->level >= type->numLevels)
514 type->numLevels = new->level + 1;
515 old->mods.mask = new->mods.real_mods;
516 old->mods.real_mods = new->mods.real_mods;
517 old->mods.vmods = new->mods.vmods;
518 old->level = new->level;
523 SetMapEntry(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
527 struct xkb_kt_map_entry entry;
529 if (arrayNdx == NULL)
530 return ReportTypeShouldBeArray(keymap, type, "map entry");
531 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
532 return ReportTypeBadType(keymap, type, "map entry", "modifier mask");
533 entry.mods.real_mods = rtrn.uval & 0xff; /* modifiers < 512 */
534 entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
535 if ((entry.mods.real_mods & (~type->mask)) ||
536 ((entry.mods.vmods & (~type->vmask)) != 0)) {
537 if (warningLevel > 0) {
538 WARN("Map entry for unused modifiers in %s\n",
539 TypeTxt(keymap, type));
540 ACTION("Using %s instead of ",
541 XkbcVModMaskText(keymap,
542 entry.mods.real_mods & type->mask,
543 entry.mods.vmods & type->vmask));
544 INFO("%s\n", MapEntryTxt(keymap, &entry));
546 entry.mods.real_mods &= type->mask;
547 entry.mods.vmods &= type->vmask;
549 if (!ExprResolveLevel(keymap->ctx, value, &rtrn)) {
550 ERROR("Level specifications in a key type must be integer\n");
551 ACTION("Ignoring malformed level specification\n");
554 entry.level = rtrn.ival - 1;
555 return AddMapEntry(keymap, type, &entry, true, true);
559 SetPreserve(KeyTypeInfo *type, struct xkb_keymap *keymap,
560 ExprDef *arrayNdx, ExprDef *value)
565 if (arrayNdx == NULL)
566 return ReportTypeShouldBeArray(keymap, type, "preserve entry");
567 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
568 return ReportTypeBadType(keymap, type, "preserve entry",
570 new.indexMods = rtrn.uval & 0xff;
571 new.indexVMods = (rtrn.uval >> 8) & 0xffff;
572 if ((new.indexMods & (~type->mask)) ||
573 (new.indexVMods & (~type->vmask))) {
574 if (warningLevel > 0) {
575 WARN("Preserve for modifiers not used by the %s type\n",
576 TypeTxt(keymap, type));
577 ACTION("Index %s converted to ", PreserveIndexTxt(keymap, &new));
579 new.indexMods &= type->mask;
580 new.indexVMods &= type->vmask;
581 if (warningLevel > 0)
582 INFO("%s\n", PreserveIndexTxt(keymap, &new));
584 if (!ExprResolveVModMask(value, &rtrn, keymap)) {
585 ERROR("Preserve value in a key type is not a modifier mask\n");
586 ACTION("Ignoring preserve[%s] in type %s\n",
587 PreserveIndexTxt(keymap, &new), TypeTxt(keymap, type));
590 new.preMods = rtrn.uval & 0xff;
591 new.preVMods = (rtrn.uval >> 16) & 0xffff;
592 if ((new.preMods & (~new.indexMods))
593 || (new.preVMods & (~new.indexVMods))) {
594 if (warningLevel > 0) {
595 WARN("Illegal value for preserve[%s] in type %s\n",
596 PreserveTxt(keymap, &new), TypeTxt(keymap, type));
597 ACTION("Converted %s to ", PreserveIndexTxt(keymap, &new));
599 new.preMods &= new.indexMods;
600 new.preVMods &= new.indexVMods;
601 if (warningLevel > 0) {
602 INFO("%s\n", PreserveIndexTxt(keymap, &new));
605 return AddPreserve(keymap, type, &new, true, true);
608 /***====================================================================***/
611 AddLevelName(struct xkb_keymap *keymap, KeyTypeInfo *type,
612 unsigned level, xkb_atom_t name, bool clobber)
614 if (level >= darray_size(type->lvlNames))
615 darray_resize0(type->lvlNames, level + 1);
617 if (darray_item(type->lvlNames, level) == name) {
618 if (warningLevel > 9) {
619 WARN("Duplicate names for level %d of key type %s\n",
620 level + 1, TypeTxt(keymap, type));
625 else if (darray_item(type->lvlNames, level) != XKB_ATOM_NONE) {
626 if (warningLevel > 0) {
627 const char *old, *new;
628 old = xkb_atom_text(keymap->ctx,
629 darray_item(type->lvlNames, level));
630 new = xkb_atom_text(keymap->ctx, name);
631 WARN("Multiple names for level %d of key type %s\n",
632 level + 1, TypeTxt(keymap, type));
634 ACTION("Using %s, ignoring %s\n", new, old);
636 ACTION("Using %s, ignoring %s\n", old, new);
643 darray_item(type->lvlNames, level) = name;
648 SetLevelName(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
653 xkb_atom_t level_name;
655 if (arrayNdx == NULL)
656 return ReportTypeShouldBeArray(keymap, type, "level name");
657 if (!ExprResolveLevel(keymap->ctx, arrayNdx, &rtrn))
658 return ReportTypeBadType(keymap, type, "level name", "integer");
659 level = rtrn.ival - 1;
660 if (!ExprResolveString(keymap->ctx, value, &rtrn)) {
661 ERROR("Non-string name for level %d in key type %s\n", level + 1,
662 xkb_atom_text(keymap->ctx, type->name));
663 ACTION("Ignoring illegal level name definition\n");
666 level_name = xkb_atom_intern(keymap->ctx, rtrn.str);
668 return AddLevelName(keymap, type, level, level_name, true);
671 /***====================================================================***/
674 * Parses the fields in a type "..." { } description.
676 * @param field The field to parse (e.g. modifiers, map, level_name)
679 SetKeyTypeField(KeyTypeInfo *type, struct xkb_keymap *keymap,
680 char *field, ExprDef *arrayNdx, ExprDef *value,
685 if (strcasecmp(field, "modifiers") == 0) {
686 unsigned mods, vmods;
687 if (arrayNdx != NULL) {
688 WARN("The modifiers field of a key type is not an array\n");
689 ACTION("Illegal array subscript ignored\n");
691 /* get modifier mask for current type */
692 if (!ExprResolveVModMask(value, &tmp, keymap)) {
693 ERROR("Key type mask field must be a modifier mask\n");
694 ACTION("Key type definition ignored\n");
697 mods = tmp.uval & 0xff; /* core mods */
698 vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
699 if (type->defs.defined & _KT_Mask) {
700 WARN("Multiple modifier mask definitions for key type %s\n",
701 xkb_atom_text(keymap->ctx, type->name));
702 ACTION("Using %s, ", TypeMaskTxt(keymap, type));
703 INFO("ignoring %s\n", XkbcVModMaskText(keymap, mods, vmods));
708 type->defs.defined |= _KT_Mask;
711 else if (strcasecmp(field, "map") == 0) {
712 type->defs.defined |= _KT_Map;
713 return SetMapEntry(type, keymap, arrayNdx, value);
715 else if (strcasecmp(field, "preserve") == 0) {
716 type->defs.defined |= _KT_Preserve;
717 return SetPreserve(type, keymap, arrayNdx, value);
719 else if ((strcasecmp(field, "levelname") == 0) ||
720 (strcasecmp(field, "level_name") == 0)) {
721 type->defs.defined |= _KT_LevelNames;
722 return SetLevelName(type, keymap, arrayNdx, value);
724 ERROR("Unknown field %s in key type %s\n", field, TypeTxt(keymap, type));
725 ACTION("Definition ignored\n");
730 HandleKeyTypeVar(VarDef *stmt, struct xkb_keymap *keymap, KeyTypesInfo *info)
732 ExprResult elem, field;
735 if (!ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx))
736 return false; /* internal error, already reported */
737 if (elem.str && (strcasecmp(elem.str, "type") == 0))
738 return SetKeyTypeField(&info->dflt, keymap, field.str, arrayNdx,
740 if (elem.str != NULL) {
741 ERROR("Default for unknown element %s\n", uStringText(elem.str));
742 ACTION("Value for field %s ignored\n", uStringText(field.str));
744 else if (field.str != NULL) {
745 ERROR("Default defined for unknown field %s\n",
746 uStringText(field.str));
753 HandleKeyTypeBody(VarDef *def, struct xkb_keymap *keymap,
754 KeyTypeInfo *type, KeyTypesInfo *info)
757 ExprResult tmp, field;
760 for (; def != NULL; def = (VarDef *) def->common.next) {
761 if ((def->name) && (def->name->type == ExprFieldRef)) {
762 ok = HandleKeyTypeVar(def, keymap, info);
765 ok = ExprResolveLhs(keymap, def->name, &tmp, &field, &arrayNdx);
767 ok = SetKeyTypeField(type, keymap, field.str, arrayNdx,
776 * Process a type "XYZ" { } specification in the xkb_types section.
780 HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
781 enum merge_mode merge, KeyTypesInfo *info)
785 struct xkb_kt_map_entry *entry;
786 PreserveInfo *pi, *pi_next;
788 if (def->merge != MERGE_DEFAULT)
791 type.defs.defined = 0;
792 type.defs.file_id = info->file_id;
793 type.defs.merge = merge;
794 type.defs.next = NULL;
795 type.name = def->name;
796 type.mask = info->dflt.mask;
797 type.vmask = info->dflt.vmask;
799 darray_init(type.entries);
800 darray_init(type.lvlNames);
801 list_init(&type.preserves);
803 /* Parse the actual content. */
804 if (!HandleKeyTypeBody(def->body, keymap, &type, info)) {
809 /* now copy any appropriate map, preserve or level names from the */
811 darray_foreach(entry, info->dflt.entries) {
812 if ((entry->mods.real_mods & type.mask) == entry->mods.real_mods &&
813 (entry->mods.vmods & type.vmask) == entry->mods.vmods)
814 AddMapEntry(keymap, &type, entry, false, false);
817 list_foreach_safe(pi, pi_next, &info->dflt.preserves, entry) {
818 if ((pi->indexMods & type.mask) == pi->indexMods &&
819 (pi->indexVMods & type.vmask) == pi->indexVMods)
820 AddPreserve(keymap, &type, pi, false, false);
823 for (i = 0; i < darray_size(info->dflt.lvlNames); i++) {
824 if (i < type.numLevels &&
825 darray_item(info->dflt.lvlNames, i) != XKB_ATOM_NONE) {
826 AddLevelName(keymap, &type, i,
827 darray_item(info->dflt.lvlNames, i), false);
831 /* Now add the new keytype to the info struct */
832 if (!AddKeyType(keymap, info, &type)) {
840 * Process an xkb_types section.
842 * @param file The parsed xkb_types section.
843 * @param merge Merge Strategy (e.g. MERGE_OVERRIDE)
844 * @param info Pointer to memory where the outcome will be stored.
847 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
848 enum merge_mode merge, KeyTypesInfo *info)
853 info->name = uDupString(file->name);
857 switch (stmt->stmtType) {
859 if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, keymap, info))
862 case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
863 if (!HandleKeyTypeDef((KeyTypeDef *) stmt, keymap, merge, info))
867 if (!HandleKeyTypeVar((VarDef *) stmt, keymap, info))
870 case StmtVModDef: /* virtual_modifiers NumLock, ... */
871 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
874 case StmtKeyAliasDef:
875 ERROR("Key type files may not include other declarations\n");
876 ACTION("Ignoring definition of key alias\n");
880 ERROR("Key type files may not include other declarations\n");
881 ACTION("Ignoring definition of key name\n");
885 ERROR("Key type files may not include other declarations\n");
886 ACTION("Ignoring definition of symbol interpretation\n");
890 WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
895 if (info->errorCount > 10) {
897 ERROR("Too many errors\n");
899 ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
906 ComputeEffectiveMap(struct xkb_keymap *keymap, struct xkb_key_type *type)
909 struct xkb_kt_map_entry *entry = NULL;
911 if (type->mods.vmods != 0) {
912 tmp = VModsToReal(keymap, type->mods.vmods);
913 type->mods.mask = tmp | type->mods.real_mods;
914 darray_foreach(entry, type->map) {
916 if (entry->mods.vmods != 0) {
917 tmp = VModsToReal(keymap, entry->mods.vmods);
922 (entry->mods.real_mods | tmp) & type->mods.mask;
926 type->mods.mask = type->mods.real_mods;
932 CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
938 list_foreach(pre, &def->preserves, entry) {
939 struct xkb_kt_map_entry * match;
940 struct xkb_kt_map_entry tmp;
941 tmp.mods.real_mods = pre->indexMods;
942 tmp.mods.vmods = pre->indexVMods;
944 AddMapEntry(keymap, def, &tmp, false, false);
945 match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
947 WSGO("Couldn't find matching entry for preserve\n");
948 ACTION("Aborting\n");
951 pre->matchingMapIndex = match - &darray_item(def->entries, 0);
953 type->mods.real_mods = def->mask;
954 type->mods.vmods = def->vmask;
955 type->num_levels = def->numLevels;
956 memcpy(&type->map, &def->entries, sizeof(def->entries));
957 if (!list_empty(&def->preserves)) {
958 type->preserve = uTypedCalloc(darray_size(type->map), struct xkb_mods);
959 if (!type->preserve) {
960 WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
961 ACTION("Preserve setting for type %s lost\n",
962 xkb_atom_text(keymap->ctx, def->name));
965 list_foreach(pre, &def->preserves, entry) {
966 int ndx = pre->matchingMapIndex;
967 type->preserve[ndx].mask = pre->preMods;
968 type->preserve[ndx].real_mods = pre->preMods;
969 type->preserve[ndx].vmods = pre->preVMods;
974 type->preserve = NULL;
975 type->name = xkb_atom_strdup(keymap->ctx, def->name);
977 if (!darray_empty(def->lvlNames)) {
978 type->level_names = calloc(darray_size(def->lvlNames),
979 sizeof(*type->level_names));
981 /* assert def->szNames<=def->numLevels */
982 for (i = 0; i < darray_size(def->lvlNames); i++)
983 type->level_names[i] =
984 xkb_atom_strdup(keymap->ctx, darray_item(def->lvlNames, i));
987 type->level_names = NULL;
990 darray_init(def->entries);
991 return ComputeEffectiveMap(keymap, type);
994 static struct xkb_kt_map_entry map2Level[] = {
997 .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
1001 static struct xkb_kt_map_entry mapAlpha[] = {
1004 .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
1008 .mods = { .mask = 0, .vmods = LockMask, .real_mods = 0 }
1012 static struct xkb_mods preAlpha[] = {
1013 { .mask = 0, .vmods = 0, .real_mods = 0 },
1014 { .mask = LockMask, .vmods = LockMask, .real_mods = 0 }
1017 static struct xkb_kt_map_entry mapKeypad[] = {
1020 .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
1024 .mods = { .mask = 1, .vmods = 0, .real_mods = 0 }
1028 static const struct xkb_key_type canonicalTypes[XkbNumRequiredTypes] = {
1030 .mods = { .mask = 0, .vmods = 0, .real_mods = 0 },
1037 .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = 0 },
1039 .map = darray_lit(map2Level),
1046 .mask = ShiftMask | LockMask,
1047 .vmods = ShiftMask | LockMask,
1051 .map = darray_lit(mapAlpha),
1052 .preserve = preAlpha,
1057 .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = 0 },
1059 .map = darray_lit(mapKeypad),
1067 InitCanonicalKeyTypes(struct xkb_keymap *keymap, unsigned which,
1070 const struct xkb_key_type *from;
1073 darray_growalloc(keymap->types, XkbNumRequiredTypes);
1075 if ((which & XkbAllRequiredTypes) == 0)
1079 from = canonicalTypes;
1081 if (which & XkbOneLevelMask)
1082 rtrn = XkbcCopyKeyType(&from[XkbOneLevelIndex],
1083 &darray_item(keymap->types, XkbOneLevelIndex));
1085 if ((which & XkbTwoLevelMask) && rtrn == Success)
1086 rtrn = XkbcCopyKeyType(&from[XkbTwoLevelIndex],
1087 &darray_item(keymap->types, XkbTwoLevelIndex));
1089 if ((which & XkbAlphabeticMask) && rtrn == Success)
1090 rtrn = XkbcCopyKeyType(&from[XkbAlphabeticIndex],
1091 &darray_item(keymap->types, XkbAlphabeticIndex));
1093 if ((which & XkbKeypadMask) && rtrn == Success) {
1094 struct xkb_key_type *type;
1096 rtrn = XkbcCopyKeyType(&from[XkbKeypadIndex],
1097 &darray_item(keymap->types, XkbKeypadIndex));
1098 type = &darray_item(keymap->types, XkbKeypadIndex);
1100 if (keypadVMod >= 0 && keypadVMod < XkbNumVirtualMods &&
1102 struct xkb_kt_map_entry *entry;
1103 type->mods.vmods = (1 << keypadVMod);
1105 entry = &darray_item(type->map, 0);
1106 entry->mods.mask = ShiftMask;
1107 entry->mods.real_mods = ShiftMask;
1108 entry->mods.vmods = 0;
1111 entry = &darray_item(type->map, 1);
1112 entry->mods.mask = 0;
1113 entry->mods.real_mods = 0;
1114 entry->mods.vmods = (1 << keypadVMod);
1123 CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
1124 enum merge_mode merge)
1127 struct xkb_key_type *type, *next;
1131 InitKeyTypesInfo(&info, keymap, NULL, file->id);
1133 HandleKeyTypesFile(file, keymap, merge, &info);
1135 if (info.errorCount != 0)
1139 keymap->types_section_name = strdup(info.name);
1142 if ((info.stdPresent & XkbOneLevelMask) == 0)
1144 if ((info.stdPresent & XkbTwoLevelMask) == 0)
1146 if ((info.stdPresent & XkbKeypadMask) == 0)
1148 if ((info.stdPresent & XkbAlphabeticMask) == 0)
1151 darray_resize0(keymap->types, i);
1153 if (XkbAllRequiredTypes & (~info.stdPresent)) {
1154 unsigned missing, keypadVMod;
1156 missing = XkbAllRequiredTypes & (~info.stdPresent);
1157 keypadVMod = FindKeypadVMod(keymap);
1159 if (InitCanonicalKeyTypes(keymap, missing, keypadVMod) != Success) {
1160 WSGO("Couldn't initialize canonical key types\n");
1164 if (missing & XkbOneLevelMask)
1165 darray_item(keymap->types, XkbOneLevelIndex).name =
1166 xkb_atom_strdup(keymap->ctx, info.tok_ONE_LEVEL);
1167 if (missing & XkbTwoLevelMask)
1168 darray_item(keymap->types, XkbTwoLevelIndex).name =
1169 xkb_atom_strdup(keymap->ctx, info.tok_TWO_LEVEL);
1170 if (missing & XkbAlphabeticMask)
1171 darray_item(keymap->types, XkbAlphabeticIndex).name =
1172 xkb_atom_strdup(keymap->ctx, info.tok_ALPHABETIC);
1173 if (missing & XkbKeypadMask)
1174 darray_item(keymap->types, XkbKeypadIndex).name =
1175 xkb_atom_strdup(keymap->ctx, info.tok_KEYPAD);
1178 next = &darray_item(keymap->types, XkbLastRequiredType + 1);
1179 for (i = 0, def = info.types; i < info.nTypes; i++) {
1180 if (def->name == info.tok_ONE_LEVEL)
1181 type = &darray_item(keymap->types, XkbOneLevelIndex);
1182 else if (def->name == info.tok_TWO_LEVEL)
1183 type = &darray_item(keymap->types, XkbTwoLevelIndex);
1184 else if (def->name == info.tok_ALPHABETIC)
1185 type = &darray_item(keymap->types, XkbAlphabeticIndex);
1186 else if (def->name == info.tok_KEYPAD)
1187 type = &darray_item(keymap->types, XkbKeypadIndex);
1191 DeleteLevel1MapEntries(def);
1193 if (!CopyDefToKeyType(keymap, type, def))
1196 def = (KeyTypeInfo *) def->defs.next;
1199 FreeKeyTypesInfo(&info);
1203 FreeKeyTypesInfo(&info);