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
58 struct xkb_kt_map_entry * entries;
59 PreserveInfo *preserve;
64 typedef struct _KeyTypesInfo
76 static xkb_atom_t tok_ONE_LEVEL;
77 static xkb_atom_t tok_TWO_LEVEL;
78 static xkb_atom_t tok_ALPHABETIC;
79 static xkb_atom_t tok_KEYPAD;
81 /***====================================================================***/
83 #define ReportTypeShouldBeArray(keymap, t, f) \
84 ReportShouldBeArray("key type", (f), TypeTxt((keymap), (t)))
85 #define ReportTypeBadType(keymap, t, f, w) \
86 ReportBadType("key type", (f), TypeTxt((keymap), (t)), (w))
88 /***====================================================================***/
90 #define MapEntryTxt(x, e) \
91 XkbcVModMaskText((x), (e)->mods.real_mods, (e)->mods.vmods)
92 #define PreserveIndexTxt(x, p) \
93 XkbcVModMaskText((x), (p)->indexMods, (p)->indexVMods)
94 #define PreserveTxt(x, p) \
95 XkbcVModMaskText((x), (p)->preMods, (p)->preVMods)
96 #define TypeTxt(keymap, t) \
97 xkb_atom_text((keymap)->context, (t)->name)
98 #define TypeMaskTxt(t, x) \
99 XkbcVModMaskText((x), (t)->mask, (t)->vmask)
101 /***====================================================================***/
104 InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
107 tok_ONE_LEVEL = xkb_atom_intern(keymap->context, "ONE_LEVEL");
108 tok_TWO_LEVEL = xkb_atom_intern(keymap->context, "TWO_LEVEL");
109 tok_ALPHABETIC = xkb_atom_intern(keymap->context, "ALPHABETIC");
110 tok_KEYPAD = xkb_atom_intern(keymap->context, "KEYPAD");
111 info->name = strdup("default");
112 info->errorCount = 0;
113 info->stdPresent = 0;
116 info->dflt.defs.defined = 0;
117 info->dflt.defs.fileID = 0;
118 info->dflt.defs.merge = MergeOverride;
119 info->dflt.defs.next = NULL;
120 info->dflt.name = XKB_ATOM_NONE;
122 info->dflt.vmask = 0;
123 info->dflt.groupInfo = false;
124 info->dflt.numLevels = 1;
125 info->dflt.nEntries = info->dflt.szEntries = 0;
126 info->dflt.entries = NULL;
127 info->dflt.szNames = 0;
128 info->dflt.lvlNames = NULL;
129 info->dflt.preserve = NULL;
130 InitVModInfo(&info->vmods, keymap);
133 info->dflt = from->dflt;
134 if (from->dflt.entries)
136 info->dflt.entries = uTypedCalloc(from->dflt.szEntries,
137 struct xkb_kt_map_entry);
138 if (info->dflt.entries)
140 unsigned sz = from->dflt.nEntries * sizeof(struct xkb_kt_map_entry);
141 memcpy(info->dflt.entries, from->dflt.entries, sz);
144 if (from->dflt.lvlNames)
146 info->dflt.lvlNames = uTypedCalloc(from->dflt.szNames, xkb_atom_t);
147 if (info->dflt.lvlNames)
149 unsigned sz = from->dflt.szNames * sizeof(xkb_atom_t);
150 memcpy(info->dflt.lvlNames, from->dflt.lvlNames, sz);
153 if (from->dflt.preserve)
155 PreserveInfo *old, *new, *last;
157 old = from->dflt.preserve;
158 for (; old; old = (PreserveInfo *) old->defs.next)
160 new = uTypedAlloc(PreserveInfo);
164 new->defs.next = NULL;
166 last->defs.next = (CommonInfo *) new;
168 info->dflt.preserve = new;
176 FreeKeyTypeInfo(KeyTypeInfo * type)
179 type->entries = NULL;
180 free(type->lvlNames);
181 type->lvlNames = NULL;
182 if (type->preserve != NULL)
184 ClearCommonInfo(&type->preserve->defs);
185 type->preserve = NULL;
190 FreeKeyTypesInfo(KeyTypesInfo * info)
197 for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
199 FreeKeyTypeInfo(type);
201 info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs);
203 FreeKeyTypeInfo(&info->dflt);
207 NextKeyType(KeyTypesInfo * info)
211 type = uTypedAlloc(KeyTypeInfo);
214 memset(type, 0, sizeof(KeyTypeInfo));
215 type->defs.fileID = info->fileID;
216 info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs,
217 (CommonInfo *) type);
224 FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
228 for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
230 if (old->name == new->name)
237 ReportTypeBadWidth(const char *type, int has, int needs)
239 ERROR("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
240 ACTION("Illegal type definition ignored\n");
245 AddKeyType(struct xkb_keymap *keymap, KeyTypesInfo *info, KeyTypeInfo *new)
249 if (new->name == tok_ONE_LEVEL)
251 if (new->numLevels > 1)
252 return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
253 info->stdPresent |= XkbOneLevelMask;
255 else if (new->name == tok_TWO_LEVEL)
257 if (new->numLevels > 2)
258 return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
259 else if (new->numLevels < 2)
261 info->stdPresent |= XkbTwoLevelMask;
263 else if (new->name == tok_ALPHABETIC)
265 if (new->numLevels > 2)
266 return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
267 else if (new->numLevels < 2)
269 info->stdPresent |= XkbAlphabeticMask;
271 else if (new->name == tok_KEYPAD)
273 if (new->numLevels > 2)
274 return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
275 else if (new->numLevels < 2)
277 info->stdPresent |= XkbKeypadMask;
280 old = FindMatchingKeyType(info, new);
284 if ((new->defs.merge == MergeReplace)
285 || (new->defs.merge == MergeOverride))
287 KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
288 if (((old->defs.fileID == new->defs.fileID)
289 && (warningLevel > 0)) || (warningLevel > 9))
291 WARN("Multiple definitions of the %s key type\n",
292 xkb_atom_text(keymap->context, new->name));
293 ACTION("Earlier definition ignored\n");
295 FreeKeyTypeInfo(old);
297 new->szEntries = new->nEntries = 0;
299 new->preserve = NULL;
300 new->lvlNames = NULL;
301 old->defs.next = &next->defs;
304 report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
307 WARN("Multiple definitions of the %s key type\n",
308 xkb_atom_text(keymap->context, new->name));
309 ACTION("Later definition ignored\n");
311 FreeKeyTypeInfo(new);
314 old = NextKeyType(info);
318 old->defs.next = NULL;
319 new->nEntries = new->szEntries = 0;
322 new->lvlNames = NULL;
323 new->preserve = NULL;
327 /***====================================================================***/
330 MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
331 unsigned merge, struct xkb_keymap *keymap)
335 if (from->errorCount > 0)
337 into->errorCount += from->errorCount;
340 if (into->name == NULL)
342 into->name = from->name;
345 for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
347 if (merge != MergeDefault)
348 type->defs.merge = merge;
349 if (!AddKeyType(keymap, into, type))
352 into->stdPresent |= from->stdPresent;
355 typedef void (*FileHandler) (XkbFile *file, struct xkb_keymap *keymap,
356 unsigned merge, KeyTypesInfo *included);
359 HandleIncludeKeyTypes(IncludeStmt *stmt, struct xkb_keymap *keymap,
360 KeyTypesInfo *info, FileHandler hndlr)
364 KeyTypesInfo included;
368 if ((stmt->file == NULL) && (stmt->map == NULL))
372 memset(info, 0, sizeof(KeyTypesInfo));
374 else if (ProcessIncludeFile(keymap->context, stmt, XkmTypesIndex, &rtrn,
377 InitKeyTypesInfo(&included, keymap, info);
378 included.fileID = included.dflt.defs.fileID = rtrn->id;
379 included.dflt.defs.merge = newMerge;
381 (*hndlr) (rtrn, keymap, newMerge, &included);
382 if (stmt->stmt != NULL)
385 included.name = stmt->stmt;
392 info->errorCount += 10;
395 if ((stmt->next != NULL) && (included.errorCount < 1))
399 KeyTypesInfo next_incl;
401 for (next = stmt->next; next != NULL; next = next->next)
403 if ((next->file == NULL) && (next->map == NULL))
406 MergeIncludedKeyTypes(&included, info, next->merge, keymap);
407 FreeKeyTypesInfo(info);
409 else if (ProcessIncludeFile(keymap->context, next, XkmTypesIndex,
412 InitKeyTypesInfo(&next_incl, keymap, &included);
413 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
414 next_incl.dflt.defs.merge = op;
415 (*hndlr) (rtrn, keymap, op, &next_incl);
416 MergeIncludedKeyTypes(&included, &next_incl, op, keymap);
417 FreeKeyTypesInfo(&next_incl);
422 info->errorCount += 10;
423 FreeKeyTypesInfo(&included);
432 MergeIncludedKeyTypes(info, &included, newMerge, keymap);
433 FreeKeyTypesInfo(&included);
435 return (info->errorCount == 0);
438 /***====================================================================***/
440 static struct xkb_kt_map_entry *
441 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
444 struct xkb_kt_map_entry * entry;
446 for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
448 if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
455 DeleteLevel1MapEntries(KeyTypeInfo * type)
459 for (i = 0; i < type->nEntries; i++)
461 if (type->entries[i].level == 0)
463 for (n = i; n < type->nEntries - 1; n++)
465 type->entries[n] = type->entries[n + 1];
473 * Return a pointer to the next free XkbcKTMapEntry, reallocating space if
476 static struct xkb_kt_map_entry *
477 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
479 if (type->entries == NULL)
481 type->entries = uTypedCalloc(2, struct xkb_kt_map_entry);
482 if (type->entries == NULL)
484 ERROR("Couldn't allocate map entries for %s\n",
485 TypeTxt(keymap, type));
486 ACTION("Map entries lost\n");
492 else if (type->nEntries >= type->szEntries)
494 type->szEntries *= 2;
495 type->entries = uTypedRecalloc(type->entries,
496 type->nEntries, type->szEntries,
497 struct xkb_kt_map_entry);
498 if (type->entries == NULL)
500 ERROR("Couldn't reallocate map entries for %s\n",
501 TypeTxt(keymap, type));
502 ACTION("Map entries lost\n");
506 return &type->entries[type->nEntries++];
510 AddPreserve(struct xkb_keymap *keymap, KeyTypeInfo *type,
511 PreserveInfo *new, bool clobber, bool report)
515 old = type->preserve;
518 if ((old->indexMods != new->indexMods) ||
519 (old->indexVMods != new->indexVMods))
521 old = (PreserveInfo *) old->defs.next;
524 if ((old->preMods == new->preMods)
525 && (old->preVMods == new->preVMods))
527 if (warningLevel > 9)
529 WARN("Identical definitions for preserve[%s] in %s\n",
530 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
535 if (report && (warningLevel > 0))
538 WARN("Multiple definitions for preserve[%s] in %s\n",
539 PreserveIndexTxt(keymap, old), TypeTxt(keymap, type));
542 str = PreserveTxt(keymap, new);
544 str = PreserveTxt(keymap, old);
545 ACTION("Using %s, ", str);
547 str = PreserveTxt(keymap, old);
549 str = PreserveTxt(keymap, new);
550 INFO("ignoring %s\n", str);
554 old->preMods = new->preMods;
555 old->preVMods = new->preVMods;
559 old = uTypedAlloc(PreserveInfo);
562 WSGO("Couldn't allocate preserve in %s\n", TypeTxt(keymap, type));
563 ACTION("Preserve[%s] lost\n", PreserveIndexTxt(keymap, new));
567 old->matchingMapIndex = -1;
569 (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
574 * Add a new KTMapEntry to the given key type. If an entry with the same mods
575 * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
578 * @param clobber Overwrite existing entry.
579 * @param report true if a warning is to be printed on.
582 AddMapEntry(struct xkb_keymap *keymap, KeyTypeInfo *type,
583 struct xkb_kt_map_entry *new, bool clobber, bool report)
585 struct xkb_kt_map_entry * old;
588 FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
590 if (report && (old->level != new->level))
592 unsigned use, ignore;
595 use = new->level + 1;
596 ignore = old->level + 1;
600 use = old->level + 1;
601 ignore = new->level + 1;
603 WARN("Multiple map entries for %s in %s\n",
604 MapEntryTxt(keymap, new), TypeTxt(keymap, type));
605 ACTION("Using %d, ignoring %d\n", use, ignore);
607 else if (warningLevel > 9)
609 WARN("Multiple occurences of map[%s]= %d in %s\n",
610 MapEntryTxt(keymap, new), new->level + 1,
611 TypeTxt(keymap, type));
616 old->level = new->level;
619 if ((old = NextMapEntry(keymap, type)) == NULL)
620 return false; /* allocation failure, already reported */
621 if (new->level >= type->numLevels)
622 type->numLevels = new->level + 1;
623 if (new->mods.vmods == 0)
627 old->mods.mask = new->mods.real_mods;
628 old->mods.real_mods = new->mods.real_mods;
629 old->mods.vmods = new->mods.vmods;
630 old->level = new->level;
635 SetMapEntry(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
639 struct xkb_kt_map_entry entry;
641 if (arrayNdx == NULL)
642 return ReportTypeShouldBeArray(keymap, type, "map entry");
643 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
644 return ReportTypeBadType(keymap, type, "map entry", "modifier mask");
645 entry.mods.real_mods = rtrn.uval & 0xff; /* modifiers < 512 */
646 entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
647 if ((entry.mods.real_mods & (~type->mask)) ||
648 ((entry.mods.vmods & (~type->vmask)) != 0))
650 if (warningLevel > 0)
652 WARN("Map entry for unused modifiers in %s\n", TypeTxt(keymap, type));
653 ACTION("Using %s instead of ",
654 XkbcVModMaskText(keymap,
655 entry.mods.real_mods & type->mask,
656 entry.mods.vmods & type->vmask));
657 INFO("%s\n", MapEntryTxt(keymap, &entry));
659 entry.mods.real_mods &= type->mask;
660 entry.mods.vmods &= type->vmask;
662 if (!ExprResolveLevel(keymap->context, value, &rtrn))
664 ERROR("Level specifications in a key type must be integer\n");
665 ACTION("Ignoring malformed level specification\n");
668 entry.level = rtrn.ival - 1;
669 return AddMapEntry(keymap, type, &entry, true, true);
673 SetPreserve(KeyTypeInfo *type, struct xkb_keymap *keymap,
674 ExprDef *arrayNdx, ExprDef *value)
679 if (arrayNdx == NULL)
680 return ReportTypeShouldBeArray(keymap, type, "preserve entry");
681 if (!ExprResolveVModMask(arrayNdx, &rtrn, keymap))
682 return ReportTypeBadType(keymap, type, "preserve entry",
684 new.defs = type->defs;
685 new.defs.next = NULL;
686 new.indexMods = rtrn.uval & 0xff;
687 new.indexVMods = (rtrn.uval >> 8) & 0xffff;
688 if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
690 if (warningLevel > 0)
692 WARN("Preserve for modifiers not used by the %s type\n",
693 TypeTxt(keymap, type));
694 ACTION("Index %s converted to ", PreserveIndexTxt(keymap, &new));
696 new.indexMods &= type->mask;
697 new.indexVMods &= type->vmask;
698 if (warningLevel > 0)
699 INFO("%s\n", PreserveIndexTxt(keymap, &new));
701 if (!ExprResolveVModMask(value, &rtrn, keymap))
703 ERROR("Preserve value in a key type is not a modifier mask\n");
704 ACTION("Ignoring preserve[%s] in type %s\n",
705 PreserveIndexTxt(keymap, &new), TypeTxt(keymap, type));
708 new.preMods = rtrn.uval & 0xff;
709 new.preVMods = (rtrn.uval >> 16) & 0xffff;
710 if ((new.preMods & (~new.indexMods))
711 || (new.preVMods & (~new.indexVMods)))
713 if (warningLevel > 0)
715 WARN("Illegal value for preserve[%s] in type %s\n",
716 PreserveTxt(keymap, &new), TypeTxt(keymap, type));
717 ACTION("Converted %s to ", PreserveIndexTxt(keymap, &new));
719 new.preMods &= new.indexMods;
720 new.preVMods &= new.indexVMods;
721 if (warningLevel > 0)
723 INFO("%s\n", PreserveIndexTxt(keymap, &new));
726 return AddPreserve(keymap, type, &new, true, true);
729 /***====================================================================***/
732 AddLevelName(struct xkb_keymap *keymap, KeyTypeInfo *type,
733 unsigned level, xkb_atom_t name, bool clobber)
735 if ((type->lvlNames == NULL) || (type->szNames <= level))
738 uTypedRecalloc(type->lvlNames, type->szNames, level + 1, xkb_atom_t);
739 if (type->lvlNames == NULL)
741 ERROR("Couldn't allocate level names for type %s\n",
742 TypeTxt(keymap, type));
743 ACTION("Level names lost\n");
747 type->szNames = level + 1;
749 else if (type->lvlNames[level] == name)
751 if (warningLevel > 9)
753 WARN("Duplicate names for level %d of key type %s\n",
754 level + 1, TypeTxt(keymap, type));
759 else if (type->lvlNames[level] != XKB_ATOM_NONE)
761 if (warningLevel > 0)
763 const char *old, *new;
764 old = xkb_atom_text(keymap->context, type->lvlNames[level]);
765 new = xkb_atom_text(keymap->context, name);
766 WARN("Multiple names for level %d of key type %s\n",
767 level + 1, TypeTxt(keymap, type));
769 ACTION("Using %s, ignoring %s\n", new, old);
771 ACTION("Using %s, ignoring %s\n", old, new);
776 if (level >= type->numLevels)
777 type->numLevels = level + 1;
778 type->lvlNames[level] = name;
783 SetLevelName(KeyTypeInfo *type, struct xkb_keymap *keymap, ExprDef *arrayNdx,
788 xkb_atom_t level_name;
790 if (arrayNdx == NULL)
791 return ReportTypeShouldBeArray(keymap, type, "level name");
792 if (!ExprResolveLevel(keymap->context, arrayNdx, &rtrn))
793 return ReportTypeBadType(keymap, type, "level name", "integer");
794 level = rtrn.ival - 1;
795 if (!ExprResolveString(keymap->context, value, &rtrn))
797 ERROR("Non-string name for level %d in key type %s\n", level + 1,
798 xkb_atom_text(keymap->context, type->name));
799 ACTION("Ignoring illegal level name definition\n");
802 level_name = xkb_atom_intern(keymap->context, rtrn.str);
804 return AddLevelName(keymap, type, level, level_name, true);
807 /***====================================================================***/
810 * Parses the fields in a type "..." { } description.
812 * @param field The field to parse (e.g. modifiers, map, level_name)
815 SetKeyTypeField(KeyTypeInfo *type, struct xkb_keymap *keymap,
816 char *field, ExprDef *arrayNdx, ExprDef *value,
821 if (strcasecmp(field, "modifiers") == 0)
823 unsigned mods, vmods;
824 if (arrayNdx != NULL)
826 WARN("The modifiers field of a key type is not an array\n");
827 ACTION("Illegal array subscript ignored\n");
829 /* get modifier mask for current type */
830 if (!ExprResolveVModMask(value, &tmp, keymap))
832 ERROR("Key type mask field must be a modifier mask\n");
833 ACTION("Key type definition ignored\n");
836 mods = tmp.uval & 0xff; /* core mods */
837 vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
838 if (type->defs.defined & _KT_Mask)
840 WARN("Multiple modifier mask definitions for key type %s\n",
841 xkb_atom_text(keymap->context, type->name));
842 ACTION("Using %s, ", TypeMaskTxt(type, keymap));
843 INFO("ignoring %s\n", XkbcVModMaskText(keymap, mods, vmods));
848 type->defs.defined |= _KT_Mask;
851 else if (strcasecmp(field, "map") == 0)
853 type->defs.defined |= _KT_Map;
854 return SetMapEntry(type, keymap, arrayNdx, value);
856 else if (strcasecmp(field, "preserve") == 0)
858 type->defs.defined |= _KT_Preserve;
859 return SetPreserve(type, keymap, arrayNdx, value);
861 else if ((strcasecmp(field, "levelname") == 0) ||
862 (strcasecmp(field, "level_name") == 0))
864 type->defs.defined |= _KT_LevelNames;
865 return SetLevelName(type, keymap, arrayNdx, value);
867 ERROR("Unknown field %s in key type %s\n", field, TypeTxt(keymap, type));
868 ACTION("Definition ignored\n");
873 HandleKeyTypeVar(VarDef *stmt, struct xkb_keymap *keymap, KeyTypesInfo *info)
875 ExprResult elem, field;
878 if (!ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx))
879 return false; /* internal error, already reported */
880 if (elem.str && (strcasecmp(elem.str, "type") == 0))
881 return SetKeyTypeField(&info->dflt, keymap, field.str, arrayNdx,
883 if (elem.str != NULL)
885 ERROR("Default for unknown element %s\n", uStringText(elem.str));
886 ACTION("Value for field %s ignored\n", uStringText(field.str));
888 else if (field.str != NULL)
890 ERROR("Default defined for unknown field %s\n",
891 uStringText(field.str));
898 HandleKeyTypeBody(VarDef *def, struct xkb_keymap *keymap,
899 KeyTypeInfo *type, KeyTypesInfo *info)
902 ExprResult tmp, field;
905 for (; def != NULL; def = (VarDef *) def->common.next)
907 if ((def->name) && (def->name->type == ExprFieldRef))
909 ok = HandleKeyTypeVar(def, keymap, info);
912 ok = ExprResolveLhs(keymap, def->name, &tmp, &field, &arrayNdx);
914 ok = SetKeyTypeField(type, keymap, field.str, arrayNdx,
923 * Process a type "XYZ" { } specification in the xkb_types section.
927 HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
928 unsigned merge, KeyTypesInfo *info)
933 if (def->merge != MergeDefault)
936 type.defs.defined = 0;
937 type.defs.fileID = info->fileID;
938 type.defs.merge = merge;
939 type.defs.next = NULL;
940 type.name = def->name;
941 type.mask = info->dflt.mask;
942 type.vmask = info->dflt.vmask;
943 type.groupInfo = info->dflt.groupInfo;
945 type.nEntries = type.szEntries = 0;
948 type.lvlNames = NULL;
949 type.preserve = NULL;
951 /* Parse the actual content. */
952 if (!HandleKeyTypeBody(def->body, keymap, &type, info))
958 /* now copy any appropriate map, preserve or level names from the */
960 for (i = 0; i < info->dflt.nEntries; i++)
962 struct xkb_kt_map_entry * dflt;
963 dflt = &info->dflt.entries[i];
964 if (((dflt->mods.real_mods & type.mask) == dflt->mods.real_mods) &&
965 ((dflt->mods.vmods & type.vmask) == dflt->mods.vmods))
967 AddMapEntry(keymap, &type, dflt, false, false);
970 if (info->dflt.preserve)
972 PreserveInfo *dflt = info->dflt.preserve;
975 if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
976 ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
978 AddPreserve(keymap, &type, dflt, false, false);
980 dflt = (PreserveInfo *) dflt->defs.next;
983 for (i = 0; i < info->dflt.szNames; i++)
985 if ((i < type.numLevels) && (info->dflt.lvlNames[i] != XKB_ATOM_NONE))
987 AddLevelName(keymap, &type, i, info->dflt.lvlNames[i], false);
990 /* Now add the new keytype to the info struct */
991 if (!AddKeyType(keymap, info, &type))
1000 * Process an xkb_types section.
1002 * @param file The parsed xkb_types section.
1003 * @param merge Merge Strategy (e.g. MergeOverride)
1004 * @param info Pointer to memory where the outcome will be stored.
1007 HandleKeyTypesFile(XkbFile *file, struct xkb_keymap *keymap,
1008 unsigned merge, KeyTypesInfo *info)
1013 info->name = uDupString(file->name);
1017 switch (stmt->stmtType)
1020 if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, keymap, info,
1021 HandleKeyTypesFile))
1024 case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
1025 if (!HandleKeyTypeDef((KeyTypeDef *) stmt, keymap, merge, info))
1029 if (!HandleKeyTypeVar((VarDef *) stmt, keymap, info))
1032 case StmtVModDef: /* virtual_modifiers NumLock, ... */
1033 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
1036 case StmtKeyAliasDef:
1037 ERROR("Key type files may not include other declarations\n");
1038 ACTION("Ignoring definition of key alias\n");
1041 case StmtKeycodeDef:
1042 ERROR("Key type files may not include other declarations\n");
1043 ACTION("Ignoring definition of key name\n");
1047 ERROR("Key type files may not include other declarations\n");
1048 ACTION("Ignoring definition of symbol interpretation\n");
1052 WSGO("Unexpected statement type %d in HandleKeyTypesFile\n",
1057 if (info->errorCount > 10)
1060 ERROR("Too many errors\n");
1062 ACTION("Abandoning keytypes file \"%s\"\n", file->topName);
1069 CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
1075 for (pre = def->preserve; pre != NULL;
1076 pre = (PreserveInfo *) pre->defs.next)
1078 struct xkb_kt_map_entry * match;
1079 struct xkb_kt_map_entry tmp;
1080 tmp.mods.real_mods = pre->indexMods;
1081 tmp.mods.vmods = pre->indexVMods;
1083 AddMapEntry(keymap, def, &tmp, false, false);
1084 match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
1087 WSGO("Couldn't find matching entry for preserve\n");
1088 ACTION("Aborting\n");
1091 pre->matchingMapIndex = match - def->entries;
1093 type->mods.real_mods = def->mask;
1094 type->mods.vmods = def->vmask;
1095 type->num_levels = def->numLevels;
1096 type->map_count = def->nEntries;
1097 type->map = def->entries;
1100 type->preserve = uTypedCalloc(type->map_count, struct xkb_mods);
1101 if (!type->preserve)
1103 WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
1104 ACTION("Preserve setting for type %s lost\n",
1105 xkb_atom_text(keymap->context, def->name));
1109 pre = def->preserve;
1110 for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
1112 int ndx = pre->matchingMapIndex;
1113 type->preserve[ndx].mask = pre->preMods;
1114 type->preserve[ndx].real_mods = pre->preMods;
1115 type->preserve[ndx].vmods = pre->preVMods;
1120 type->preserve = NULL;
1121 type->name = xkb_atom_strdup(keymap->context, def->name);
1122 if (def->szNames > 0)
1124 type->level_names = uTypedCalloc(def->numLevels, const char *);
1126 /* assert def->szNames<=def->numLevels */
1127 for (i = 0; i < def->szNames; i++)
1129 type->level_names[i] = xkb_atom_strdup(keymap->context,
1135 type->level_names = NULL;
1138 def->nEntries = def->szEntries = 0;
1139 def->entries = NULL;
1140 return XkbcComputeEffectiveMap(keymap, type, NULL);
1144 CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
1147 struct xkb_key_type *type, *next;
1151 InitKeyTypesInfo(&info, keymap, NULL);
1152 info.fileID = file->id;
1154 HandleKeyTypesFile(file, keymap, merge, &info);
1156 if (info.errorCount != 0)
1160 if ((info.stdPresent & XkbOneLevelMask) == 0)
1162 if ((info.stdPresent & XkbTwoLevelMask) == 0)
1164 if ((info.stdPresent & XkbKeypadMask) == 0)
1166 if ((info.stdPresent & XkbAlphabeticMask) == 0)
1169 if (XkbcAllocClientMap(keymap, XkbKeyTypesMask, i) != Success) {
1170 WSGO("Couldn't allocate client map\n");
1174 keymap->map->num_types = i;
1176 if (XkbAllRequiredTypes & (~info.stdPresent)) {
1177 unsigned missing, keypadVMod;
1179 missing = XkbAllRequiredTypes & (~info.stdPresent);
1180 keypadVMod = FindKeypadVMod(keymap);
1182 if (XkbcInitCanonicalKeyTypes(keymap, missing, keypadVMod) != Success) {
1183 WSGO("Couldn't initialize canonical key types\n");
1187 if (missing & XkbOneLevelMask)
1188 keymap->map->types[XkbOneLevelIndex].name =
1189 xkb_atom_strdup(keymap->context, tok_ONE_LEVEL);
1190 if (missing & XkbTwoLevelMask)
1191 keymap->map->types[XkbTwoLevelIndex].name =
1192 xkb_atom_strdup(keymap->context, tok_TWO_LEVEL);
1193 if (missing & XkbAlphabeticMask)
1194 keymap->map->types[XkbAlphabeticIndex].name =
1195 xkb_atom_strdup(keymap->context, tok_ALPHABETIC);
1196 if (missing & XkbKeypadMask)
1197 keymap->map->types[XkbKeypadIndex].name =
1198 xkb_atom_strdup(keymap->context, tok_KEYPAD);
1201 next = &keymap->map->types[XkbLastRequiredType + 1];
1202 for (i = 0, def = info.types; i < info.nTypes; i++) {
1203 if (def->name == tok_ONE_LEVEL)
1204 type = &keymap->map->types[XkbOneLevelIndex];
1205 else if (def->name == tok_TWO_LEVEL)
1206 type = &keymap->map->types[XkbTwoLevelIndex];
1207 else if (def->name == tok_ALPHABETIC)
1208 type = &keymap->map->types[XkbAlphabeticIndex];
1209 else if (def->name == tok_KEYPAD)
1210 type = &keymap->map->types[XkbKeypadIndex];
1214 DeleteLevel1MapEntries(def);
1216 if (!CopyDefToKeyType(keymap, type, def))
1219 def = (KeyTypeInfo *)def->defs.next;
1222 FreeKeyTypesInfo(&info);
1226 FreeKeyTypesInfo(&info);