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,
102 KeyTypesInfo *from, unsigned file_id)
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->file_id = file_id;
114 info->dflt.defs.defined = 0;
115 info->dflt.defs.file_id = file_id;
116 info->dflt.defs.merge = MERGE_OVERRIDE;
117 info->dflt.defs.next = NULL;
118 info->dflt.name = XKB_ATOM_NONE;
120 info->dflt.vmask = 0;
121 info->dflt.groupInfo = false;
122 info->dflt.numLevels = 1;
123 darray_init(info->dflt.entries);
124 darray_init(info->dflt.lvlNames);
125 info->dflt.preserve = NULL;
126 InitVModInfo(&info->vmods, keymap);
129 info->dflt = from->dflt;
131 darray_copy(info->dflt.entries, from->dflt.entries);
132 darray_copy(info->dflt.lvlNames, from->dflt.lvlNames);
134 if (from->dflt.preserve)
136 PreserveInfo *old, *new, *last;
138 old = from->dflt.preserve;
139 for (; old; old = (PreserveInfo *) old->defs.next)
141 new = uTypedAlloc(PreserveInfo);
145 new->defs.next = NULL;
147 last->defs.next = (CommonInfo *) new;
149 info->dflt.preserve = new;
157 FreeKeyTypeInfo(KeyTypeInfo * type)
159 darray_free(type->entries);
160 darray_free(type->lvlNames);
161 if (type->preserve != NULL)
163 ClearCommonInfo(&type->preserve->defs);
164 type->preserve = NULL;
169 FreeKeyTypesInfo(KeyTypesInfo * info)
176 for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
178 FreeKeyTypeInfo(type);
180 info->types = ClearCommonInfo(&info->types->defs);
182 FreeKeyTypeInfo(&info->dflt);
186 NextKeyType(KeyTypesInfo * info)
190 type = uTypedAlloc(KeyTypeInfo);
193 memset(type, 0, sizeof(KeyTypeInfo));
194 type->defs.file_id = info->file_id;
195 info->types = AddCommonInfo(&info->types->defs, &type->defs);
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 == MERGE_REPLACE)
263 || (new->defs.merge == MERGE_OVERRIDE))
265 KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
266 if (((old->defs.file_id == new->defs.file_id)
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.file_id == new->defs.file_id) && (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 enum merge_mode 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 != MERGE_DEFAULT)
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 enum merge_mode 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, FILE_TYPE_TYPES, &rtrn,
353 InitKeyTypesInfo(&included, keymap, info, 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, rtrn->id);
388 next_incl.dflt.defs.merge = op;
389 HandleKeyTypesFile(rtrn, keymap, op, &next_incl);
390 MergeIncludedKeyTypes(&included, &next_incl, op, keymap);
391 FreeKeyTypesInfo(&next_incl);
396 info->errorCount += 10;
397 FreeKeyTypesInfo(&included);
406 MergeIncludedKeyTypes(info, &included, newMerge, keymap);
407 FreeKeyTypesInfo(&included);
409 return (info->errorCount == 0);
412 /***====================================================================***/
414 static struct xkb_kt_map_entry *
415 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
417 struct xkb_kt_map_entry *entry;
419 darray_foreach(entry, type->entries)
420 if (entry->mods.real_mods == mask && entry->mods.vmods == vmask)
427 DeleteLevel1MapEntries(KeyTypeInfo * type)
431 /* TODO: Be just a bit more clever here. */
432 for (i = 0; i < darray_size(type->entries); i++) {
433 if (darray_item(type->entries, i).level == 0) {
434 for (n = i; n < darray_size(type->entries) - 1; n++)
435 darray_item(type->entries, n) =
436 darray_item(type->entries, n + 1);
437 (void)darray_pop(type->entries);
442 static struct xkb_kt_map_entry *
443 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
445 darray_resize0(type->entries, darray_size(type->entries) + 1);
446 return &darray_item(type->entries, darray_size(type->entries) - 1);
450 AddPreserve(struct xkb_keymap *keymap, KeyTypeInfo *type,
451 PreserveInfo *new, bool clobber, bool report)
455 old = type->preserve;
458 if ((old->indexMods != new->indexMods) ||
459 (old->indexVMods != new->indexVMods))
461 old = (PreserveInfo *) old->defs.next;
464 if ((old->preMods == new->preMods)
465 && (old->preVMods == new->preVMods))
467 if (warningLevel > 9)
469 WARN("Identical definitions for preserve[%s] in %s\n",
470 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
475 if (report && (warningLevel > 0))
478 WARN("Multiple definitions for preserve[%s] in %s\n",
479 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
482 str = PreserveTxt(keymap, new);
484 str = PreserveTxt(keymap, old);
485 ACTION("Using %s, ", str);
487 str = PreserveTxt(keymap, old);
489 str = PreserveTxt(keymap, new);
490 INFO("ignoring %s\n", str);
494 old->preMods = new->preMods;
495 old->preVMods = new->preVMods;
499 old = uTypedAlloc(PreserveInfo);
502 WSGO("Couldn't allocate preserve in %s\n", TypeTxt(keymap, type));
503 ACTION("Preserve[%s] lost\n", PreserveIndexTxt(keymap, new));
507 old->matchingMapIndex = -1;
508 type->preserve = AddCommonInfo(&type->preserve->defs, &old->defs);
513 * Add a new KTMapEntry to the given key type. If an entry with the same mods
514 * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
517 * @param clobber Overwrite existing entry.
518 * @param report true if a warning is to be printed on.
521 AddMapEntry(struct xkb_keymap *keymap, KeyTypeInfo *type,
522 struct xkb_kt_map_entry *new, bool clobber, bool report)
524 struct xkb_kt_map_entry * old;
527 FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
529 if (report && (old->level != new->level))
531 unsigned use, ignore;
534 use = new->level + 1;
535 ignore = old->level + 1;
539 use = old->level + 1;
540 ignore = new->level + 1;
542 WARN("Multiple map entries for %s in %s\n",
543 MapEntryTxt(keymap, new), TypeTxt(keymap, type));
544 ACTION("Using %d, ignoring %d\n", use, ignore);
546 else if (warningLevel > 9)
548 WARN("Multiple occurences of map[%s]= %d in %s\n",
549 MapEntryTxt(keymap, new), new->level + 1,
550 TypeTxt(keymap, type));
555 old->level = new->level;
558 if ((old = NextMapEntry(keymap, type)) == NULL)
559 return false; /* allocation failure, already reported */
560 if (new->level >= type->numLevels)
561 type->numLevels = new->level + 1;
562 old->mods.mask = new->mods.real_mods;
563 old->mods.real_mods = new->mods.real_mods;
564 old->mods.vmods = new->mods.vmods;
565 old->level = new->level;
570 SetMapEntry(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
574 struct xkb_kt_map_entry entry;
576 if (arrayNdx == NULL)
577 return ReportTypeShouldBeArray(keymap, type, "map entry");
578 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
579 return ReportTypeBadType(keymap, type, "map entry", "modifier mask");
580 entry.mods.real_mods = rtrn.uval & 0xff; /* modifiers < 512 */
581 entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
582 if ((entry.mods.real_mods & (~type->mask)) ||
583 ((entry.mods.vmods & (~type->vmask)) != 0))
585 if (warningLevel > 0)
587 WARN("Map entry for unused modifiers in %s\n", TypeTxt(keymap, type));
588 ACTION("Using %s instead of ",
589 XkbcVModMaskText(keymap,
590 entry.mods.real_mods & type->mask,
591 entry.mods.vmods & type->vmask));
592 INFO("%s\n", MapEntryTxt(keymap, &entry));
594 entry.mods.real_mods &= type->mask;
595 entry.mods.vmods &= type->vmask;
597 if (!ExprResolveLevel(keymap->ctx, value, &rtrn))
599 ERROR("Level specifications in a key type must be integer\n");
600 ACTION("Ignoring malformed level specification\n");
603 entry.level = rtrn.ival - 1;
604 return AddMapEntry(keymap, type, &entry, true, true);
608 SetPreserve(KeyTypeInfo *type, struct xkb_keymap *keymap,
609 ExprDef *arrayNdx, ExprDef *value)
614 if (arrayNdx == NULL)
615 return ReportTypeShouldBeArray(keymap, type, "preserve entry");
616 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
617 return ReportTypeBadType(keymap, type, "preserve entry",
619 new.defs = type->defs;
620 new.defs.next = NULL;
621 new.indexMods = rtrn.uval & 0xff;
622 new.indexVMods = (rtrn.uval >> 8) & 0xffff;
623 if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
625 if (warningLevel > 0)
627 WARN("Preserve for modifiers not used by the %s type\n",
628 TypeTxt(keymap, type));
629 ACTION("Index %s converted to ", PreserveIndexTxt(keymap, &new));
631 new.indexMods &= type->mask;
632 new.indexVMods &= type->vmask;
633 if (warningLevel > 0)
634 INFO("%s\n", PreserveIndexTxt(keymap, &new));
636 if (!ExprResolveVModMask(value, &rtrn, keymap))
638 ERROR("Preserve value in a key type is not a modifier mask\n");
639 ACTION("Ignoring preserve[%s] in type %s\n",
640 PreserveIndexTxt(keymap, &new), TypeTxt(keymap, type));
643 new.preMods = rtrn.uval & 0xff;
644 new.preVMods = (rtrn.uval >> 16) & 0xffff;
645 if ((new.preMods & (~new.indexMods))
646 || (new.preVMods & (~new.indexVMods)))
648 if (warningLevel > 0)
650 WARN("Illegal value for preserve[%s] in type %s\n",
651 PreserveTxt(keymap, &new), TypeTxt(keymap, type));
652 ACTION("Converted %s to ", PreserveIndexTxt(keymap, &new));
654 new.preMods &= new.indexMods;
655 new.preVMods &= new.indexVMods;
656 if (warningLevel > 0)
658 INFO("%s\n", PreserveIndexTxt(keymap, &new));
661 return AddPreserve(keymap, type, &new, true, true);
664 /***====================================================================***/
667 AddLevelName(struct xkb_keymap *keymap, KeyTypeInfo *type,
668 unsigned level, xkb_atom_t name, bool clobber)
670 if (level >= darray_size(type->lvlNames))
671 darray_resize0(type->lvlNames, level + 1);
673 if (darray_item(type->lvlNames, level) == name) {
674 if (warningLevel > 9) {
675 WARN("Duplicate names for level %d of key type %s\n",
676 level + 1, TypeTxt(keymap, type));
681 else if (darray_item(type->lvlNames, level) != XKB_ATOM_NONE) {
682 if (warningLevel > 0) {
683 const char *old, *new;
684 old = xkb_atom_text(keymap->ctx,
685 darray_item(type->lvlNames, level));
686 new = xkb_atom_text(keymap->ctx, name);
687 WARN("Multiple names for level %d of key type %s\n",
688 level + 1, TypeTxt(keymap, type));
690 ACTION("Using %s, ignoring %s\n", new, old);
692 ACTION("Using %s, ignoring %s\n", old, new);
699 darray_item(type->lvlNames, level) = name;
704 SetLevelName(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
709 xkb_atom_t level_name;
711 if (arrayNdx == NULL)
712 return ReportTypeShouldBeArray(keymap, type, "level name");
713 if (!ExprResolveLevel(keymap->ctx, arrayNdx, &rtrn))
714 return ReportTypeBadType(keymap, type, "level name", "integer");
715 level = rtrn.ival - 1;
716 if (!ExprResolveString(keymap->ctx, value, &rtrn))
718 ERROR("Non-string name for level %d in key type %s\n", level + 1,
719 xkb_atom_text(keymap->ctx, type->name));
720 ACTION("Ignoring illegal level name definition\n");
723 level_name = xkb_atom_intern(keymap->ctx, rtrn.str);
725 return AddLevelName(keymap, type, level, level_name, true);
728 /***====================================================================***/
731 * Parses the fields in a type "..." { } description.
733 * @param field The field to parse (e.g. modifiers, map, level_name)
736 SetKeyTypeField(KeyTypeInfo *type, struct xkb_keymap *keymap,
737 char *field, ExprDef *arrayNdx, ExprDef *value,
742 if (strcasecmp(field, "modifiers") == 0)
744 unsigned mods, vmods;
745 if (arrayNdx != NULL)
747 WARN("The modifiers field of a key type is not an array\n");
748 ACTION("Illegal array subscript ignored\n");
750 /* get modifier mask for current type */
751 if (!ExprResolveVModMask(value, &tmp, keymap))
753 ERROR("Key type mask field must be a modifier mask\n");
754 ACTION("Key type definition ignored\n");
757 mods = tmp.uval & 0xff; /* core mods */
758 vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
759 if (type->defs.defined & _KT_Mask)
761 WARN("Multiple modifier mask definitions for key type %s\n",
762 xkb_atom_text(keymap->ctx, type->name));
763 ACTION("Using %s, ", TypeMaskTxt(type, keymap));
764 INFO("ignoring %s\n", XkbcVModMaskText(keymap, mods, vmods));
769 type->defs.defined |= _KT_Mask;
772 else if (strcasecmp(field, "map") == 0)
774 type->defs.defined |= _KT_Map;
775 return SetMapEntry(type, keymap, arrayNdx, value);
777 else if (strcasecmp(field, "preserve") == 0)
779 type->defs.defined |= _KT_Preserve;
780 return SetPreserve(type, keymap, arrayNdx, value);
782 else if ((strcasecmp(field, "levelname") == 0) ||
783 (strcasecmp(field, "level_name") == 0))
785 type->defs.defined |= _KT_LevelNames;
786 return SetLevelName(type, keymap, arrayNdx, value);
788 ERROR("Unknown field %s in key type %s\n", field, TypeTxt(keymap, type));
789 ACTION("Definition ignored\n");
794 HandleKeyTypeVar(VarDef *stmt, struct xkb_keymap *keymap, KeyTypesInfo *info)
796 ExprResult elem, field;
799 if (!ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx))
800 return false; /* internal error, already reported */
801 if (elem.str && (strcasecmp(elem.str, "type") == 0))
802 return SetKeyTypeField(&info->dflt, keymap, field.str, arrayNdx,
804 if (elem.str != NULL)
806 ERROR("Default for unknown element %s\n", uStringText(elem.str));
807 ACTION("Value for field %s ignored\n", uStringText(field.str));
809 else if (field.str != NULL)
811 ERROR("Default defined for unknown field %s\n",
812 uStringText(field.str));
819 HandleKeyTypeBody(VarDef *def, struct xkb_keymap *keymap,
820 KeyTypeInfo *type, KeyTypesInfo *info)
823 ExprResult tmp, field;
826 for (; def != NULL; def = (VarDef *) def->common.next)
828 if ((def->name) && (def->name->type == ExprFieldRef))
830 ok = HandleKeyTypeVar(def, keymap, info);
833 ok = ExprResolveLhs(keymap, def->name, &tmp, &field, &arrayNdx);
835 ok = SetKeyTypeField(type, keymap, field.str, arrayNdx,
844 * Process a type "XYZ" { } specification in the xkb_types section.
848 HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
849 enum merge_mode merge, KeyTypesInfo *info)
853 struct xkb_kt_map_entry *entry;
855 if (def->merge != MERGE_DEFAULT)
858 type.defs.defined = 0;
859 type.defs.file_id = info->file_id;
860 type.defs.merge = merge;
861 type.defs.next = NULL;
862 type.name = def->name;
863 type.mask = info->dflt.mask;
864 type.vmask = info->dflt.vmask;
865 type.groupInfo = info->dflt.groupInfo;
867 darray_init(type.entries);
868 darray_init(type.lvlNames);
869 type.preserve = NULL;
871 /* Parse the actual content. */
872 if (!HandleKeyTypeBody(def->body, keymap, &type, info))
878 /* now copy any appropriate map, preserve or level names from the */
880 darray_foreach(entry, info->dflt.entries) {
881 if ((entry->mods.real_mods & type.mask) == entry->mods.real_mods &&
882 (entry->mods.vmods & type.vmask) == entry->mods.vmods)
883 AddMapEntry(keymap, &type, entry, false, false);
885 if (info->dflt.preserve)
887 PreserveInfo *dflt = info->dflt.preserve;
890 if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
891 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
893 AddPreserve(keymap, &type, dflt, false, false);
895 dflt = (PreserveInfo *) dflt->defs.next;
899 for (i = 0; i < darray_size(info->dflt.lvlNames); i++) {
900 if (i < type.numLevels &&
901 darray_item(info->dflt.lvlNames, i) != XKB_ATOM_NONE)
903 AddLevelName(keymap, &type, i,
904 darray_item(info->dflt.lvlNames, i), false);
908 /* Now add the new keytype to the info struct */
909 if (!AddKeyType(keymap, info, &type))
918 * Process an xkb_types section.
920 * @param file The parsed xkb_types section.
921 * @param merge Merge Strategy (e.g. MERGE_OVERRIDE)
922 * @param info Pointer to memory where the outcome will be stored.
925 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
926 enum merge_mode merge, KeyTypesInfo *info)
931 info->name = uDupString(file->name);
935 switch (stmt->stmtType)
938 if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, keymap, info))
941 case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
942 if (!HandleKeyTypeDef((KeyTypeDef *) stmt, keymap, merge, info))
946 if (!HandleKeyTypeVar((VarDef *) stmt, keymap, info))
949 case StmtVModDef: /* virtual_modifiers NumLock, ... */
950 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
953 case StmtKeyAliasDef:
954 ERROR("Key type files may not include other declarations\n");
955 ACTION("Ignoring definition of key alias\n");
959 ERROR("Key type files may not include other declarations\n");
960 ACTION("Ignoring definition of key name\n");
964 ERROR("Key type files may not include other declarations\n");
965 ACTION("Ignoring definition of symbol interpretation\n");
969 WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
974 if (info->errorCount > 10)
977 ERROR("Too many errors\n");
979 ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
986 ComputeEffectiveMap(struct xkb_keymap *keymap, struct xkb_key_type *type)
989 struct xkb_kt_map_entry *entry = NULL;
991 if (type->mods.vmods != 0) {
992 tmp = VModsToReal(keymap, type->mods.vmods);
993 type->mods.mask = tmp | type->mods.real_mods;
994 darray_foreach(entry, type->map) {
996 if (entry->mods.vmods != 0) {
997 tmp = VModsToReal(keymap, entry->mods.vmods);
1001 entry->mods.mask = (entry->mods.real_mods | tmp) & type->mods.mask;
1005 type->mods.mask = type->mods.real_mods;
1011 CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
1017 for (pre = def->preserve; pre != NULL;
1018 pre = (PreserveInfo *) pre->defs.next)
1020 struct xkb_kt_map_entry * match;
1021 struct xkb_kt_map_entry tmp;
1022 tmp.mods.real_mods = pre->indexMods;
1023 tmp.mods.vmods = pre->indexVMods;
1025 AddMapEntry(keymap, def, &tmp, false, false);
1026 match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1029 WSGO("Couldn't find matching entry for preserve\n");
1030 ACTION("Aborting\n");
1033 pre->matchingMapIndex = match - &darray_item(def->entries, 0);
1035 type->mods.real_mods = def->mask;
1036 type->mods.vmods = def->vmask;
1037 type->num_levels = def->numLevels;
1038 memcpy(&type->map, &def->entries, sizeof(def->entries));
1041 type->preserve = uTypedCalloc(darray_size(type->map), struct xkb_mods);
1042 if (!type->preserve)
1044 WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1045 ACTION("Preserve setting for type %s lost\n",
1046 xkb_atom_text(keymap->ctx, def->name));
1050 pre = def->preserve;
1051 for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
1053 int ndx = pre->matchingMapIndex;
1054 type->preserve[ndx].mask = pre->preMods;
1055 type->preserve[ndx].real_mods = pre->preMods;
1056 type->preserve[ndx].vmods = pre->preVMods;
1061 type->preserve = NULL;
1062 type->name = xkb_atom_strdup(keymap->ctx, def->name);
1064 if (!darray_empty(def->lvlNames)) {
1065 type->level_names = calloc(darray_size(def->lvlNames),
1066 sizeof(*type->level_names));
1068 /* assert def->szNames<=def->numLevels */
1069 for (i = 0; i < darray_size(def->lvlNames); i++)
1070 type->level_names[i] =
1071 xkb_atom_strdup(keymap->ctx, darray_item(def->lvlNames, i));
1074 type->level_names = NULL;
1077 darray_init(def->entries);
1078 return ComputeEffectiveMap(keymap, type);
1081 static struct xkb_kt_map_entry map2Level[]= {
1084 .mods = {.mask = 1, .vmods = ShiftMask, .real_mods = 0 }
1088 static struct xkb_kt_map_entry mapAlpha[]= {
1091 .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
1095 .mods = { .mask = 0, .vmods = LockMask, .real_mods = 0 }
1099 static struct xkb_mods preAlpha[]= {
1100 { .mask = 0, .vmods = 0, .real_mods = 0 },
1101 { .mask = LockMask, .vmods = LockMask, .real_mods = 0 }
1104 static struct xkb_kt_map_entry mapKeypad[]= {
1107 .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
1111 .mods = { .mask = 1, .vmods = 0, .real_mods = 0 }
1115 static const struct xkb_key_type canonicalTypes[XkbNumRequiredTypes] = {
1117 .mods = { .mask = 0, .vmods = 0, .real_mods = 0 },
1124 .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = 0 },
1126 .map = darray_lit(map2Level),
1133 .mask = ShiftMask|LockMask,
1134 .vmods = ShiftMask|LockMask,
1138 .map = darray_lit(mapAlpha),
1139 .preserve = preAlpha,
1144 .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = 0 },
1146 .map = darray_lit(mapKeypad),
1154 InitCanonicalKeyTypes(struct xkb_keymap *keymap, unsigned which, int keypadVMod)
1156 struct xkb_client_map *map;
1157 const struct xkb_key_type *from;
1160 rtrn = XkbcAllocClientMap(keymap, XkbKeyTypesMask, XkbNumRequiredTypes);
1161 if (rtrn != Success)
1165 if ((which & XkbAllRequiredTypes) == 0)
1169 from = canonicalTypes;
1171 if (which & XkbOneLevelMask)
1172 rtrn = XkbcCopyKeyType(&from[XkbOneLevelIndex],
1173 &darray_item(map->types, XkbOneLevelIndex));
1175 if ((which & XkbTwoLevelMask) && rtrn == Success)
1176 rtrn = XkbcCopyKeyType(&from[XkbTwoLevelIndex],
1177 &darray_item(map->types, XkbTwoLevelIndex));
1179 if ((which & XkbAlphabeticMask) && rtrn == Success)
1180 rtrn = XkbcCopyKeyType(&from[XkbAlphabeticIndex],
1181 &darray_item(map->types, XkbAlphabeticIndex));
1183 if ((which & XkbKeypadMask) && rtrn == Success) {
1184 struct xkb_key_type *type;
1186 rtrn = XkbcCopyKeyType(&from[XkbKeypadIndex],
1187 &darray_item(map->types, XkbKeypadIndex));
1188 type = &darray_item(map->types, XkbKeypadIndex);
1190 if (keypadVMod >= 0 && keypadVMod < XkbNumVirtualMods &&
1192 struct xkb_kt_map_entry *entry;
1193 type->mods.vmods = (1 << keypadVMod);
1195 entry = &darray_item(type->map, 0);
1196 entry->mods.mask = ShiftMask;
1197 entry->mods.real_mods = ShiftMask;
1198 entry->mods.vmods = 0;
1201 entry = &darray_item(type->map, 1);
1202 entry->mods.mask = 0;
1203 entry->mods.real_mods = 0;
1204 entry->mods.vmods = (1 << keypadVMod);
1213 CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
1216 struct xkb_key_type *type, *next;
1220 InitKeyTypesInfo(&info, keymap, NULL, file->id);
1222 HandleKeyTypesFile(file, keymap, merge, &info);
1224 if (info.errorCount != 0)
1228 if (XkbcAllocNames(keymap, 0, 0) != Success)
1230 keymap->names->keytypes = strdup(info.name);
1234 if ((info.stdPresent & XkbOneLevelMask) == 0)
1236 if ((info.stdPresent & XkbTwoLevelMask) == 0)
1238 if ((info.stdPresent & XkbKeypadMask) == 0)
1240 if ((info.stdPresent & XkbAlphabeticMask) == 0)
1243 if (XkbcAllocClientMap(keymap, XkbKeyTypesMask, i) != Success) {
1244 WSGO("Couldn't allocate client map\n");
1248 darray_resize0(keymap->map->types, i);
1250 if (XkbAllRequiredTypes & (~info.stdPresent)) {
1251 unsigned missing, keypadVMod;
1253 missing = XkbAllRequiredTypes & (~info.stdPresent);
1254 keypadVMod = FindKeypadVMod(keymap);
1256 if (InitCanonicalKeyTypes(keymap, missing, keypadVMod) != Success) {
1257 WSGO("Couldn't initialize canonical key types\n");
1261 if (missing & XkbOneLevelMask)
1262 darray_item(keymap->map->types, XkbOneLevelIndex).name =
1263 xkb_atom_strdup(keymap->ctx, tok_ONE_LEVEL);
1264 if (missing & XkbTwoLevelMask)
1265 darray_item(keymap->map->types, XkbTwoLevelIndex).name =
1266 xkb_atom_strdup(keymap->ctx, tok_TWO_LEVEL);
1267 if (missing & XkbAlphabeticMask)
1268 darray_item(keymap->map->types, XkbAlphabeticIndex).name =
1269 xkb_atom_strdup(keymap->ctx, tok_ALPHABETIC);
1270 if (missing & XkbKeypadMask)
1271 darray_item(keymap->map->types, XkbKeypadIndex).name =
1272 xkb_atom_strdup(keymap->ctx, tok_KEYPAD);
1275 next = &darray_item(keymap->map->types, XkbLastRequiredType + 1);
1276 for (i = 0, def = info.types; i < info.nTypes; i++) {
1277 if (def->name == tok_ONE_LEVEL)
1278 type = &darray_item(keymap->map->types, XkbOneLevelIndex);
1279 else if (def->name == tok_TWO_LEVEL)
1280 type = &darray_item(keymap->map->types, XkbTwoLevelIndex);
1281 else if (def->name == tok_ALPHABETIC)
1282 type = &darray_item(keymap->map->types, XkbAlphabeticIndex);
1283 else if (def->name == tok_KEYPAD)
1284 type = &darray_item(keymap->map->types, XkbKeypadIndex);
1288 DeleteLevel1MapEntries(def);
1290 if (!CopyDefToKeyType(keymap, type, def))
1293 def = (KeyTypeInfo *)def->defs.next;
1296 FreeKeyTypesInfo(&info);
1300 FreeKeyTypesInfo(&info);