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"
34 /***====================================================================***/
36 /* Needed to work with the typechecker. */
37 typedef darray(xkb_keysym_t) darray_xkb_keysym_t;
38 typedef darray(union xkb_action) darray_xkb_action;
42 #define RepeatUndefined ~((unsigned)0)
44 #define _Key_Syms (1<<0)
45 #define _Key_Acts (1<<1)
46 #define _Key_Repeat (1<<2)
47 #define _Key_Behavior (1<<3)
48 #define _Key_Type_Dflt (1<<4)
49 #define _Key_Types (1<<5)
50 #define _Key_GroupInfo (1<<6)
51 #define _Key_VModMap (1<<7)
53 typedef struct _KeyInfo
56 unsigned long name; /* the 4 chars of the key name, as long */
57 unsigned char groupInfo;
58 unsigned char typesDefined;
59 unsigned char symsDefined;
60 unsigned char actsDefined;
61 unsigned int numLevels[XkbNumKbdGroups];
63 /* syms[group] -> Single array for all the keysyms in the group. */
64 darray_xkb_keysym_t syms[XkbNumKbdGroups];
66 * symsMapIndex[group][level] -> The index from which the syms for
67 * the level begin in the syms[group] array. Remember each keycode
68 * can have multiple keysyms in each level (that is, each key press
69 * can result in multiple keysyms).
71 darray(int) symsMapIndex[XkbNumKbdGroups];
73 * symsMapNumEntries[group][level] -> How many syms are in
74 * syms[group][symsMapIndex[group][level]].
76 darray(size_t) symsMapNumEntries[XkbNumKbdGroups];
78 darray_xkb_action acts[XkbNumKbdGroups];
80 xkb_atom_t types[XkbNumKbdGroups];
82 struct xkb_behavior behavior;
83 unsigned short vmodmap;
88 * Init the given key info to sane values.
91 InitKeyInfo(KeyInfo * info)
94 static const char dflt[4] = "*";
96 info->defs.defined = 0;
97 info->defs.fileID = 0;
98 info->defs.merge = MERGE_OVERRIDE;
99 info->defs.next = NULL;
100 info->name = KeyNameToLong(dflt);
102 info->typesDefined = info->symsDefined = info->actsDefined = 0;
103 for (i = 0; i < XkbNumKbdGroups; i++)
105 info->numLevels[i] = 0;
106 info->types[i] = XKB_ATOM_NONE;
107 darray_init(info->syms[i]);
108 darray_init(info->symsMapIndex[i]);
109 darray_init(info->symsMapNumEntries[i]);
110 darray_init(info->acts[i]);
112 info->dfltType = XKB_ATOM_NONE;
113 info->behavior.type = XkbKB_Default;
114 info->behavior.data = 0;
116 info->repeat = RepeatUndefined;
120 * Free memory associated with this key info and reset to sane values.
123 FreeKeyInfo(KeyInfo * info)
127 info->defs.defined = 0;
128 info->defs.fileID = 0;
129 info->defs.merge = MERGE_OVERRIDE;
130 info->defs.next = NULL;
132 info->typesDefined = info->symsDefined = info->actsDefined = 0;
133 for (i = 0; i < XkbNumKbdGroups; i++)
135 info->numLevels[i] = 0;
136 info->types[i] = XKB_ATOM_NONE;
137 darray_free(info->syms[i]);
138 darray_free(info->symsMapIndex[i]);
139 darray_free(info->symsMapNumEntries[i]);
140 darray_free(info->acts[i]);
142 info->dfltType = XKB_ATOM_NONE;
143 info->behavior.type = XkbKB_Default;
144 info->behavior.data = 0;
146 info->repeat = RepeatUndefined;
150 * Copy old into new, optionally reset old to 0.
151 * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
152 * newly allocated and new points to the new memory areas.
155 CopyKeyInfo(KeyInfo * old, KeyInfo * new, bool clearOld)
160 new->defs.next = NULL;
163 for (i = 0; i < XkbNumKbdGroups; i++) {
164 old->numLevels[i] = 0;
165 darray_init(old->symsMapIndex[i]);
166 darray_init(old->symsMapNumEntries[i]);
167 darray_init(old->syms[i]);
168 darray_init(old->acts[i]);
172 for (i = 0; i < XkbNumKbdGroups; i++) {
173 darray_copy(new->syms[i], old->syms[i]);
174 darray_copy(new->symsMapIndex[i], old->symsMapIndex[i]);
175 darray_copy(new->symsMapNumEntries[i], old->symsMapNumEntries[i]);
176 darray_copy(new->acts[i], old->acts[i]);
183 /***====================================================================***/
185 typedef struct _ModMapEntry
192 unsigned long keyName;
197 typedef struct _SymbolsInfo
199 char *name; /* e.g. pc+us+inet(evdev) */
202 enum merge_mode merge;
203 unsigned explicit_group;
204 darray(KeyInfo) keys;
208 xkb_atom_t groupNames[XkbNumKbdGroups];
215 InitSymbolsInfo(SymbolsInfo * info, struct xkb_keymap *keymap)
220 info->explicit_group = 0;
221 info->errorCount = 0;
223 info->merge = MERGE_OVERRIDE;
224 darray_init(info->keys);
225 darray_growalloc(info->keys, 110);
227 for (i = 0; i < XkbNumKbdGroups; i++)
228 info->groupNames[i] = XKB_ATOM_NONE;
229 InitKeyInfo(&info->dflt);
230 InitVModInfo(&info->vmods, keymap);
232 info->aliases = NULL;
236 FreeSymbolsInfo(SymbolsInfo * info)
241 darray_foreach(key, info->keys)
243 darray_free(info->keys);
245 ClearCommonInfo(&info->modMap->defs);
247 ClearAliases(&info->aliases);
248 memset(info, 0, sizeof(SymbolsInfo));
252 ResizeKeyGroup(KeyInfo * key, unsigned int group, unsigned int numLevels,
253 unsigned sizeSyms, bool forceActions)
257 if (darray_size(key->syms[group]) < sizeSyms)
258 darray_resize0(key->syms[group], sizeSyms);
260 if (darray_empty(key->symsMapIndex[group]) ||
261 key->numLevels[group] < numLevels) {
262 darray_resize(key->symsMapIndex[group], numLevels);
263 for (i = key->numLevels[group]; i < numLevels; i++)
264 darray_item(key->symsMapIndex[group], i) = -1;
267 if (darray_empty(key->symsMapNumEntries[group]) ||
268 key->numLevels[group] < numLevels)
269 darray_resize0(key->symsMapNumEntries[group], numLevels);
271 if ((forceActions && (key->numLevels[group] < numLevels ||
272 darray_empty(key->acts[group]))) ||
273 (key->numLevels[group] < numLevels && !darray_empty(key->acts[group])))
274 darray_resize0(key->acts[group], numLevels);
276 if (key->numLevels[group] < numLevels)
277 key->numLevels[group] = numLevels;
282 enum key_group_selector {
289 MergeKeyGroups(SymbolsInfo * info,
290 KeyInfo * into, KeyInfo * from, unsigned group)
292 darray_xkb_keysym_t resultSyms;
293 enum key_group_selector using = NONE;
294 darray_xkb_action resultActs;
295 unsigned int resultWidth;
296 unsigned int resultSize = 0;
299 bool report, clobber;
301 clobber = (from->defs.merge != MERGE_AUGMENT);
303 report = (warningLevel > 9) ||
304 ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
306 darray_init(resultSyms);
308 if (into->numLevels[group] >= from->numLevels[group])
310 resultActs = into->acts[group];
311 resultWidth = into->numLevels[group];
315 resultActs = from->acts[group];
316 resultWidth = from->numLevels[group];
317 darray_resize(into->symsMapIndex[group],
318 from->numLevels[group]);
319 darray_resize0(into->symsMapNumEntries[group],
320 from->numLevels[group]);
322 for (i = into->numLevels[group]; i < from->numLevels[group]; i++)
323 darray_item(into->symsMapIndex[group], i) = -1;
326 if (darray_empty(resultActs) && (!darray_empty(into->acts[group]) ||
327 !darray_empty(from->acts[group])))
329 darray_resize0(resultActs, resultWidth);
330 for (i = 0; i < resultWidth; i++)
332 union xkb_action *fromAct = NULL, *toAct = NULL;
334 if (!darray_empty(from->acts[group]))
335 fromAct = &darray_item(from->acts[group], i);
337 if (!darray_empty(into->acts[group]))
338 toAct = &darray_item(into->acts[group], i);
340 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
343 darray_item(resultActs, i) = *toAct;
345 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
346 && (fromAct != NULL))
348 darray_item(resultActs, i) = *fromAct;
352 union xkb_action *use, *ignore;
366 ("Multiple actions for level %d/group %d on key %s\n",
367 i + 1, group + 1, longText(into->name));
368 ACTION("Using %s, ignoring %s\n",
369 XkbcActionTypeText(use->type),
370 XkbcActionTypeText(ignore->type));
373 darray_item(resultActs, i) = *use;
378 for (i = 0; i < resultWidth; i++)
380 unsigned int fromSize = 0;
383 if (!darray_empty(from->symsMapNumEntries[group]) &&
384 i < from->numLevels[group])
385 fromSize = darray_item(from->symsMapNumEntries[group], i);
387 if (!darray_empty(into->symsMapNumEntries[group]) &&
388 i < into->numLevels[group])
389 toSize = darray_item(into->symsMapNumEntries[group], i);
393 resultSize += toSize;
396 else if (toSize == 0 || clobber)
398 resultSize += fromSize;
403 resultSize += toSize;
413 resultSyms = from->syms[group];
414 darray_free(into->symsMapNumEntries[group]);
415 darray_free(into->symsMapIndex[group]);
416 into->symsMapNumEntries[group] = from->symsMapNumEntries[group];
417 into->symsMapIndex[group] = from->symsMapIndex[group];
418 darray_init(from->symsMapNumEntries[group]);
419 darray_init(from->symsMapIndex[group]);
422 else if (using == TO)
424 resultSyms = into->syms[group];
428 darray_resize0(resultSyms, resultSize);
430 for (i = 0; i < resultWidth; i++)
432 enum key_group_selector use = NONE;
433 unsigned int fromSize = 0;
434 unsigned int toSize = 0;
436 if (i < from->numLevels[group])
437 fromSize = darray_item(from->symsMapNumEntries[group], i);
439 if (i < into->numLevels[group])
440 toSize = darray_item(into->symsMapNumEntries[group], i);
442 if (fromSize == 0 && toSize == 0)
444 darray_item(into->symsMapIndex[group], i) = -1;
445 darray_item(into->symsMapNumEntries[group], i) = 0;
451 else if (toSize == 0 || clobber)
456 if (toSize && fromSize && report)
458 INFO("Multiple symbols for group %d, level %d on key %s\n",
459 group + 1, i + 1, longText(into->name));
460 ACTION("Using %s, ignoring %s\n",
461 (use == FROM ? "from" : "to"),
462 (use == FROM ? "to" : "from"));
467 memcpy(darray_mem(resultSyms, cur_idx),
468 darray_mem(from->syms[group],
469 darray_item(from->symsMapIndex[group], i)),
470 darray_item(from->symsMapNumEntries[group], i) * sizeof(xkb_keysym_t));
471 darray_item(into->symsMapIndex[group], i) = cur_idx;
472 darray_item(into->symsMapNumEntries[group], i) =
473 darray_item(from->symsMapNumEntries[group], i);
477 memcpy(darray_mem(resultSyms, cur_idx),
478 darray_mem(into->syms[group],
479 darray_item(into->symsMapIndex[group], i)),
480 darray_item(into->symsMapNumEntries[group], i) * sizeof(xkb_keysym_t));
481 darray_item(into->symsMapIndex[group], i) = cur_idx;
483 cur_idx += darray_item(into->symsMapNumEntries[group], i);
487 if (!darray_same(resultActs, into->acts[group]))
488 darray_free(into->acts[group]);
489 if (!darray_same(resultActs, from->acts[group]))
490 darray_free(from->acts[group]);
491 into->numLevels[group] = resultWidth;
492 if (!darray_same(resultSyms, into->syms[group]))
493 darray_free(into->syms[group]);
494 into->syms[group] = resultSyms;
495 if (!darray_same(resultSyms, from->syms[group]))
496 darray_free(from->syms[group]);
497 darray_init(from->syms[group]);
498 darray_free(from->symsMapIndex[group]);
499 darray_free(from->symsMapNumEntries[group]);
500 into->acts[group] = resultActs;
501 darray_init(from->acts[group]);
502 if (!darray_empty(into->syms[group]))
503 into->symsDefined |= (1 << group);
504 from->symsDefined &= ~(1 << group);
505 into->actsDefined |= (1 << group);
506 from->actsDefined &= ~(1 << group);
512 MergeKeys(SymbolsInfo *info, struct xkb_keymap *keymap,
513 KeyInfo *into, KeyInfo *from)
516 unsigned collide = 0;
519 if (from->defs.merge == MERGE_REPLACE)
521 for (i = 0; i < XkbNumKbdGroups; i++)
523 if (into->numLevels[i] != 0)
525 darray_free(into->syms[i]);
526 darray_free(into->acts[i]);
530 memset(from, 0, sizeof(KeyInfo));
533 report = ((warningLevel > 9) ||
534 ((into->defs.fileID == from->defs.fileID)
535 && (warningLevel > 0)));
536 for (i = 0; i < XkbNumKbdGroups; i++)
538 if (from->numLevels[i] > 0)
540 if (into->numLevels[i] == 0)
542 into->numLevels[i] = from->numLevels[i];
543 into->syms[i] = from->syms[i];
544 into->symsMapIndex[i] = from->symsMapIndex[i];
545 into->symsMapNumEntries[i] = from->symsMapNumEntries[i];
546 into->acts[i] = from->acts[i];
547 into->symsDefined |= (1 << i);
548 darray_init(from->syms[i]);
549 darray_init(from->symsMapIndex[i]);
550 darray_init(from->symsMapNumEntries[i]);
551 darray_init(from->acts[i]);
552 from->numLevels[i] = 0;
553 from->symsDefined &= ~(1 << i);
554 if (!darray_empty(into->syms[i]))
555 into->defs.defined |= _Key_Syms;
556 if (!darray_empty(into->acts[i]))
557 into->defs.defined |= _Key_Acts;
563 if (!darray_empty(into->syms[i]))
564 collide |= _Key_Syms;
565 if (!darray_empty(into->acts[i]))
566 collide |= _Key_Acts;
568 MergeKeyGroups(info, into, from, (unsigned) i);
571 if (from->types[i] != XKB_ATOM_NONE)
573 if ((into->types[i] != XKB_ATOM_NONE) && report &&
574 (into->types[i] != from->types[i]))
576 xkb_atom_t use, ignore;
577 collide |= _Key_Types;
578 if (from->defs.merge != MERGE_AUGMENT)
580 use = from->types[i];
581 ignore = into->types[i];
585 use = into->types[i];
586 ignore = from->types[i];
589 ("Multiple definitions for group %d type of key %s\n",
590 i, longText(into->name));
591 ACTION("Using %s, ignoring %s\n",
592 xkb_atom_text(keymap->ctx, use),
593 xkb_atom_text(keymap->ctx, ignore));
595 if ((from->defs.merge != MERGE_AUGMENT)
596 || (into->types[i] == XKB_ATOM_NONE))
598 into->types[i] = from->types[i];
602 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
604 into->behavior = from->behavior;
605 into->defs.defined |= _Key_Behavior;
607 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
609 into->vmodmap = from->vmodmap;
610 into->defs.defined |= _Key_VModMap;
612 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
614 into->repeat = from->repeat;
615 into->defs.defined |= _Key_Repeat;
617 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
619 into->dfltType = from->dfltType;
620 into->defs.defined |= _Key_Type_Dflt;
622 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
624 into->groupInfo = from->groupInfo;
625 into->defs.defined |= _Key_GroupInfo;
629 WARN("Symbol map for key %s redefined\n",
630 longText(into->name));
631 ACTION("Using %s definition for conflicting fields\n",
632 (from->defs.merge == MERGE_AUGMENT ? "first" : "last"));
638 AddKeySymbols(SymbolsInfo *info, KeyInfo *key, struct xkb_keymap *keymap)
640 unsigned long real_name;
643 darray_foreach(iter, info->keys)
644 if (iter->name == key->name)
645 return MergeKeys(info, keymap, iter, key);
647 if (FindKeyNameForAlias(keymap, key->name, &real_name))
648 darray_foreach(iter, info->keys)
649 if (iter->name == real_name)
650 return MergeKeys(info, keymap, iter, key);
652 darray_resize0(info->keys, darray_size(info->keys) + 1);
653 new = &darray_item(info->keys, darray_size(info->keys) - 1);
654 return CopyKeyInfo(key, new, true);
658 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
663 clobber = (new->defs.merge != MERGE_AUGMENT);
664 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
666 if (new->haveSymbol && mm->haveSymbol
667 && (new->u.keySym == mm->u.keySym))
669 unsigned use, ignore;
670 if (mm->modifier != new->modifier)
675 ignore = mm->modifier;
680 ignore = new->modifier;
683 ("%s added to symbol map for multiple modifiers\n",
684 XkbcKeysymText(new->u.keySym));
685 ACTION("Using %s, ignoring %s.\n",
686 XkbcModIndexText(use),
687 XkbcModIndexText(ignore));
692 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
693 (new->u.keyName == mm->u.keyName))
695 unsigned use, ignore;
696 if (mm->modifier != new->modifier)
701 ignore = mm->modifier;
706 ignore = new->modifier;
708 ERROR("Key %s added to map for multiple modifiers\n",
709 longText(new->u.keyName));
710 ACTION("Using %s, ignoring %s.\n",
711 XkbcModIndexText(use),
712 XkbcModIndexText(ignore));
718 mm = uTypedAlloc(ModMapEntry);
721 WSGO("Could not allocate modifier map entry\n");
722 ACTION("Modifier map for %s will be incomplete\n",
723 XkbcModIndexText(new->modifier));
727 mm->defs.next = &info->modMap->defs;
732 /***====================================================================***/
735 MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
736 enum merge_mode merge, struct xkb_keymap *keymap)
741 if (from->errorCount > 0)
743 into->errorCount += from->errorCount;
746 if (into->name == NULL)
748 into->name = from->name;
751 for (i = 0; i < XkbNumKbdGroups; i++)
753 if (from->groupNames[i] != XKB_ATOM_NONE)
755 if ((merge != MERGE_AUGMENT) ||
756 (into->groupNames[i] == XKB_ATOM_NONE))
757 into->groupNames[i] = from->groupNames[i];
761 darray_foreach(key, from->keys) {
762 if (merge != MERGE_DEFAULT)
763 key->defs.merge = merge;
765 if (!AddKeySymbols(into, key, keymap))
769 if (from->modMap != NULL)
771 ModMapEntry *mm, *next;
772 for (mm = from->modMap; mm != NULL; mm = next)
774 if (merge != MERGE_DEFAULT)
775 mm->defs.merge = merge;
776 if (!AddModMapEntry(into, mm))
778 next = (ModMapEntry *) mm->defs.next;
783 if (!MergeAliases(&into->aliases, &from->aliases, merge))
788 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
789 enum merge_mode merge, SymbolsInfo *info);
792 HandleIncludeSymbols(IncludeStmt *stmt, struct xkb_keymap *keymap,
797 SymbolsInfo included;
801 if ((stmt->file == NULL) && (stmt->map == NULL))
805 memset(info, 0, sizeof(SymbolsInfo));
807 else if (ProcessIncludeFile(keymap->ctx, stmt, FILE_TYPE_SYMBOLS, &rtrn,
810 InitSymbolsInfo(&included, keymap);
811 included.fileID = included.dflt.defs.fileID = rtrn->id;
812 included.merge = included.dflt.defs.merge = MERGE_OVERRIDE;
815 included.explicit_group = atoi(stmt->modifier) - 1;
819 included.explicit_group = info->explicit_group;
821 HandleSymbolsFile(rtrn, keymap, MERGE_OVERRIDE, &included);
822 if (stmt->stmt != NULL)
825 included.name = stmt->stmt;
832 info->errorCount += 10;
835 if ((stmt->next != NULL) && (included.errorCount < 1))
839 SymbolsInfo next_incl;
841 for (next = stmt->next; next != NULL; next = next->next)
843 if ((next->file == NULL) && (next->map == NULL))
846 MergeIncludedSymbols(&included, info, next->merge, keymap);
847 FreeSymbolsInfo(info);
849 else if (ProcessIncludeFile(keymap->ctx, next, FILE_TYPE_SYMBOLS,
852 InitSymbolsInfo(&next_incl, keymap);
853 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
854 next_incl.merge = next_incl.dflt.defs.merge = MERGE_OVERRIDE;
857 next_incl.explicit_group = atoi(next->modifier) - 1;
861 next_incl.explicit_group = info->explicit_group;
863 HandleSymbolsFile(rtrn, keymap, MERGE_OVERRIDE, &next_incl);
864 MergeIncludedSymbols(&included, &next_incl, op, keymap);
865 FreeSymbolsInfo(&next_incl);
870 info->errorCount += 10;
871 FreeSymbolsInfo(&included);
878 info->errorCount += included.errorCount;
884 MergeIncludedSymbols(info, &included, newMerge, keymap);
885 FreeSymbolsInfo(&included);
887 return (info->errorCount == 0);
894 GetGroupIndex(KeyInfo *key, struct xkb_keymap *keymap,
895 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
905 if (arrayNdx == NULL)
910 defined = key->symsDefined;
912 defined = key->actsDefined;
914 for (i = 0; i < XkbNumKbdGroups; i++)
916 if ((defined & (1 << i)) == 0)
922 ERROR("Too many groups of %s for key %s (max %d)\n", name,
923 longText(key->name), XkbNumKbdGroups + 1);
924 ACTION("Ignoring %s defined for extra groups\n", name);
927 if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp))
929 ERROR("Illegal group index for %s of key %s\n", name,
930 longText(key->name));
931 ACTION("Definition with non-integer array index ignored\n");
934 *ndx_rtrn = tmp.uval - 1;
939 AddSymbolsToKey(KeyInfo *key, struct xkb_keymap *keymap,
940 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
942 unsigned ndx, nSyms, nLevels;
946 if (!GetGroupIndex(key, keymap, arrayNdx, SYMBOLS, &ndx))
950 key->symsDefined |= (1 << ndx);
953 if (value->op != ExprKeysymList)
955 ERROR("Expected a list of symbols, found %s\n", exprOpText(value->op));
956 ACTION("Ignoring symbols for group %d of %s\n", ndx + 1,
957 longText(key->name));
960 if (!darray_empty(key->syms[ndx]))
962 ERROR("Symbols for key %s, group %d already defined\n",
963 longText(key->name), ndx + 1);
964 ACTION("Ignoring duplicate definition\n");
967 nSyms = darray_size(value->value.list.syms);
968 nLevels = darray_size(value->value.list.symsMapIndex);
969 if ((key->numLevels[ndx] < nSyms || darray_empty(key->syms[ndx])) &&
970 (!ResizeKeyGroup(key, ndx, nLevels, nSyms, false)))
972 WSGO("Could not resize group %d of key %s to contain %d levels\n",
973 ndx + 1, longText(key->name), nSyms);
974 ACTION("Symbols lost\n");
977 key->symsDefined |= (1 << ndx);
978 for (i = 0; i < nLevels; i++) {
979 darray_item(key->symsMapIndex[ndx], i) =
980 darray_item(value->value.list.symsMapIndex, i);
981 darray_item(key->symsMapNumEntries[ndx], i) =
982 darray_item(value->value.list.symsNumEntries, i);
984 for (j = 0; j < darray_item(key->symsMapNumEntries[ndx], i); j++) {
985 /* FIXME: What's abort() doing here? */
986 if (darray_item(key->symsMapIndex[ndx], i) + j >= nSyms)
988 if (!LookupKeysym(darray_item(value->value.list.syms,
989 darray_item(value->value.list.symsMapIndex, i) + j),
990 &darray_item(key->syms[ndx],
991 darray_item(key->symsMapIndex[ndx], i) + j))) {
992 WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
993 darray_item(value->value.list.syms, i),
996 xkb_atom_text(keymap->ctx, info->groupNames[ndx]), nSyms);
998 darray_item(key->syms[ndx],
999 darray_item(key->symsMapIndex[ndx], i) + j) = XKB_KEY_NoSymbol;
1000 darray_item(key->symsMapIndex[ndx], i) = -1;
1001 darray_item(key->symsMapNumEntries[ndx], i) = 0;
1004 if (darray_item(key->symsMapNumEntries[ndx], i) == 1 &&
1005 darray_item(key->syms[ndx],
1006 darray_item(key->symsMapIndex[ndx], i) + j) == XKB_KEY_NoSymbol) {
1007 darray_item(key->symsMapIndex[ndx], i) = -1;
1008 darray_item(key->symsMapNumEntries[ndx], i) = 0;
1012 for (j = key->numLevels[ndx] - 1;
1013 j >= 0 && darray_item(key->symsMapNumEntries[ndx], j) == 0; j--)
1014 key->numLevels[ndx]--;
1019 AddActionsToKey(KeyInfo *key, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1020 ExprDef *value, SymbolsInfo *info)
1023 unsigned ndx, nActs;
1025 struct xkb_any_action *toAct;
1027 if (!GetGroupIndex(key, keymap, arrayNdx, ACTIONS, &ndx))
1032 key->actsDefined |= (1 << ndx);
1035 if (value->op != ExprActionList)
1037 WSGO("Bad expression type (%d) for action list value\n", value->op);
1038 ACTION("Ignoring actions for group %d of %s\n", ndx,
1039 longText(key->name));
1042 if (!darray_empty(key->acts[ndx]))
1044 WSGO("Actions for key %s, group %d already defined\n",
1045 longText(key->name), ndx);
1048 for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1050 act = (ExprDef *) act->common.next;
1054 WSGO("Action list but not actions in AddActionsToKey\n");
1057 if ((key->numLevels[ndx] < nActs || darray_empty(key->acts[ndx])) &&
1058 !ResizeKeyGroup(key, ndx, nActs, nActs, true))
1060 WSGO("Could not resize group %d of key %s\n", ndx,
1061 longText(key->name));
1062 ACTION("Actions lost\n");
1065 key->actsDefined |= (1 << ndx);
1067 toAct = (struct xkb_any_action *) darray_mem(key->acts[ndx], 0);
1068 act = value->value.child;
1069 for (i = 0; i < nActs; i++, toAct++)
1071 if (!HandleActionDef(act, keymap, toAct, info->action))
1073 ERROR("Illegal action definition for %s\n",
1074 longText(key->name));
1075 ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1077 act = (ExprDef *) act->common.next;
1082 static const LookupEntry lockingEntries[] = {
1083 {"true", XkbKB_Lock},
1084 {"yes", XkbKB_Lock},
1086 {"false", XkbKB_Default},
1087 {"no", XkbKB_Default},
1088 {"off", XkbKB_Default},
1089 {"permanent", XkbKB_Lock | XkbKB_Permanent},
1093 static const LookupEntry repeatEntries[] = {
1094 {"true", RepeatYes},
1097 {"false", RepeatNo},
1100 {"default", RepeatUndefined},
1105 SetSymbolsField(KeyInfo *key, struct xkb_keymap *keymap, char *field,
1106 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
1111 if (strcasecmp(field, "type") == 0)
1114 if ((!ExprResolveString(keymap->ctx, value, &tmp))
1115 && (warningLevel > 0))
1117 WARN("The type field of a key symbol map must be a string\n");
1118 ACTION("Ignoring illegal type definition\n");
1120 if (arrayNdx == NULL)
1122 key->dfltType = xkb_atom_intern(keymap->ctx, tmp.str);
1123 key->defs.defined |= _Key_Type_Dflt;
1125 else if (!ExprResolveGroup(keymap->ctx, arrayNdx, &ndx))
1127 ERROR("Illegal group index for type of key %s\n",
1128 longText(key->name));
1129 ACTION("Definition with non-integer array index ignored\n");
1135 key->types[ndx.uval - 1] = xkb_atom_intern(keymap->ctx, tmp.str);
1136 key->typesDefined |= (1 << (ndx.uval - 1));
1140 else if (strcasecmp(field, "symbols") == 0)
1141 return AddSymbolsToKey(key, keymap, arrayNdx, value, info);
1142 else if (strcasecmp(field, "actions") == 0)
1143 return AddActionsToKey(key, keymap, arrayNdx, value, info);
1144 else if ((strcasecmp(field, "vmods") == 0) ||
1145 (strcasecmp(field, "virtualmods") == 0) ||
1146 (strcasecmp(field, "virtualmodifiers") == 0))
1148 ok = ExprResolveVModMask(value, &tmp, keymap);
1151 key->vmodmap = (tmp.uval >> 8);
1152 key->defs.defined |= _Key_VModMap;
1156 ERROR("Expected a virtual modifier mask, found %s\n",
1157 exprOpText(value->op));
1158 ACTION("Ignoring virtual modifiers definition for key %s\n",
1159 longText(key->name));
1162 else if ((strcasecmp(field, "locking") == 0) ||
1163 (strcasecmp(field, "lock") == 0) ||
1164 (strcasecmp(field, "locks") == 0))
1166 ok = ExprResolveEnum(keymap->ctx, value, &tmp, lockingEntries);
1168 key->behavior.type = tmp.uval;
1169 key->defs.defined |= _Key_Behavior;
1171 else if ((strcasecmp(field, "radiogroup") == 0) ||
1172 (strcasecmp(field, "permanentradiogroup") == 0) ||
1173 (strcasecmp(field, "allownone") == 0))
1175 ERROR("Radio groups not supported\n");
1176 ACTION("Ignoring radio group specification for key %s\n", longText(key->name));
1179 else if (uStrCasePrefix("overlay", field) ||
1180 uStrCasePrefix("permanentoverlay", field))
1182 ERROR("Overlays not supported\n");
1183 ACTION("Ignoring overlay specification for key %s\n", longText(key->name));
1185 else if ((strcasecmp(field, "repeating") == 0) ||
1186 (strcasecmp(field, "repeats") == 0) ||
1187 (strcasecmp(field, "repeat") == 0))
1189 ok = ExprResolveEnum(keymap->ctx, value, &tmp, repeatEntries);
1192 ERROR("Illegal repeat setting for %s\n",
1193 longText(key->name));
1194 ACTION("Non-boolean repeat setting ignored\n");
1197 key->repeat = tmp.uval;
1198 key->defs.defined |= _Key_Repeat;
1200 else if ((strcasecmp(field, "groupswrap") == 0) ||
1201 (strcasecmp(field, "wrapgroups") == 0))
1203 ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1206 ERROR("Illegal groupsWrap setting for %s\n",
1207 longText(key->name));
1208 ACTION("Non-boolean value ignored\n");
1212 key->groupInfo = XkbWrapIntoRange;
1214 key->groupInfo = XkbClampIntoRange;
1215 key->defs.defined |= _Key_GroupInfo;
1217 else if ((strcasecmp(field, "groupsclamp") == 0) ||
1218 (strcasecmp(field, "clampgroups") == 0))
1220 ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1223 ERROR("Illegal groupsClamp setting for %s\n",
1224 longText(key->name));
1225 ACTION("Non-boolean value ignored\n");
1229 key->groupInfo = XkbClampIntoRange;
1231 key->groupInfo = XkbWrapIntoRange;
1232 key->defs.defined |= _Key_GroupInfo;
1234 else if ((strcasecmp(field, "groupsredirect") == 0) ||
1235 (strcasecmp(field, "redirectgroups") == 0))
1237 if (!ExprResolveGroup(keymap->ctx, value, &tmp))
1239 ERROR("Illegal group index for redirect of key %s\n",
1240 longText(key->name));
1241 ACTION("Definition with non-integer group ignored\n");
1245 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1246 key->defs.defined |= _Key_GroupInfo;
1250 ERROR("Unknown field %s in a symbol interpretation\n", field);
1251 ACTION("Definition ignored\n");
1258 SetGroupName(SymbolsInfo *info, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1261 ExprResult tmp, name;
1263 if ((arrayNdx == NULL) && (warningLevel > 0))
1265 WARN("You must specify an index when specifying a group name\n");
1266 ACTION("Group name definition without array subscript ignored\n");
1269 if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp))
1271 ERROR("Illegal index in group name definition\n");
1272 ACTION("Definition with non-integer array index ignored\n");
1275 if (!ExprResolveString(keymap->ctx, value, &name))
1277 ERROR("Group name must be a string\n");
1278 ACTION("Illegal name for group %d ignored\n", tmp.uval);
1281 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1282 xkb_atom_intern(keymap->ctx, name.str);
1289 HandleSymbolsVar(VarDef *stmt, struct xkb_keymap *keymap, SymbolsInfo *info)
1291 ExprResult elem, field;
1295 if (ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx) == 0)
1296 return 0; /* internal error, already reported */
1297 if (elem.str && (strcasecmp(elem.str, "key") == 0))
1299 ret = SetSymbolsField(&info->dflt, keymap, field.str, arrayNdx,
1302 else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) ||
1303 (strcasecmp(field.str, "groupname") ==
1306 ret = SetGroupName(info, keymap, arrayNdx, stmt->value);
1308 else if ((elem.str == NULL)
1309 && ((strcasecmp(field.str, "groupswrap") == 0) ||
1310 (strcasecmp(field.str, "wrapgroups") == 0)))
1312 ERROR("Global \"groupswrap\" not supported\n");
1313 ACTION("Ignored\n");
1316 else if ((elem.str == NULL)
1317 && ((strcasecmp(field.str, "groupsclamp") == 0) ||
1318 (strcasecmp(field.str, "clampgroups") == 0)))
1320 ERROR("Global \"groupsclamp\" not supported\n");
1321 ACTION("Ignored\n");
1324 else if ((elem.str == NULL)
1325 && ((strcasecmp(field.str, "groupsredirect") == 0) ||
1326 (strcasecmp(field.str, "redirectgroups") == 0)))
1328 ERROR("Global \"groupsredirect\" not supported\n");
1329 ACTION("Ignored\n");
1332 else if ((elem.str == NULL) && (strcasecmp(field.str, "allownone") == 0))
1334 ERROR("Radio groups not supported\n");
1335 ACTION("Ignoring \"allownone\" specification\n");
1339 ret = SetActionField(keymap, elem.str, field.str, arrayNdx,
1340 stmt->value, &info->action);
1349 HandleSymbolsBody(VarDef *def, struct xkb_keymap *keymap, KeyInfo *key,
1353 ExprResult tmp, field;
1356 for (; def != NULL; def = (VarDef *) def->common.next)
1358 if ((def->name) && (def->name->type == ExprFieldRef))
1360 ok = HandleSymbolsVar(def, keymap, info);
1365 if (def->name == NULL)
1367 if ((def->value == NULL)
1368 || (def->value->op == ExprKeysymList))
1369 field.str = strdup("symbols");
1371 field.str = strdup("actions");
1376 ok = ExprResolveLhs(keymap, def->name, &tmp, &field,
1380 ok = SetSymbolsField(key, keymap, field.str, arrayNdx,
1389 SetExplicitGroup(SymbolsInfo *info, KeyInfo *key)
1391 unsigned group = info->explicit_group;
1396 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1399 WARN("For the map %s an explicit group specified\n", info->name);
1400 WARN("but key %s has more than one group defined\n",
1401 longText(key->name));
1402 ACTION("All groups except first one will be ignored\n");
1403 for (i = 1; i < XkbNumKbdGroups; i++)
1405 key->numLevels[i] = 0;
1406 darray_free(key->syms[i]);
1407 darray_free(key->acts[i]);
1411 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1413 key->numLevels[group] = key->numLevels[0];
1414 key->numLevels[0] = 0;
1415 key->syms[group] = key->syms[0];
1416 darray_init(key->syms[0]);
1417 key->symsMapIndex[group] = key->symsMapIndex[0];
1418 darray_init(key->symsMapIndex[0]);
1419 key->symsMapNumEntries[group] = key->symsMapNumEntries[0];
1420 darray_init(key->symsMapNumEntries[0]);
1421 key->acts[group] = key->acts[0];
1422 darray_init(key->acts[0]);
1423 key->types[group] = key->types[0];
1429 HandleSymbolsDef(SymbolsDef *stmt, struct xkb_keymap *keymap,
1435 CopyKeyInfo(&info->dflt, &key, false);
1436 key.defs.merge = stmt->merge;
1437 key.name = KeyNameToLong(stmt->keyName);
1438 if (!HandleSymbolsBody((VarDef *) stmt->symbols, keymap, &key, info))
1444 if (!SetExplicitGroup(info, &key))
1450 if (!AddKeySymbols(info, &key, keymap))
1459 HandleModMapDef(ModMapDef *def, struct xkb_keymap *keymap, SymbolsInfo *info)
1466 if (!LookupModIndex(keymap->ctx, NULL, def->modifier, TypeInt, &rtrn))
1468 ERROR("Illegal modifier map definition\n");
1469 ACTION("Ignoring map for non-modifier \"%s\"\n",
1470 xkb_atom_text(keymap->ctx, def->modifier));
1474 tmp.modifier = rtrn.uval;
1475 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1477 if ((key->op == ExprValue) && (key->type == TypeKeyName))
1479 tmp.haveSymbol = false;
1480 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1482 else if (ExprResolveKeySym(keymap->ctx, key, &rtrn))
1484 tmp.haveSymbol = true;
1485 tmp.u.keySym = rtrn.uval;
1489 ERROR("Modmap entries may contain only key names or keysyms\n");
1490 ACTION("Illegal definition for %s modifier ignored\n",
1491 XkbcModIndexText(tmp.modifier));
1495 ok = AddModMapEntry(info, &tmp) && ok;
1501 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
1502 enum merge_mode merge, SymbolsInfo *info)
1507 info->name = uDupString(file->name);
1511 switch (stmt->stmtType)
1514 if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info))
1517 case StmtSymbolsDef:
1518 if (!HandleSymbolsDef((SymbolsDef *) stmt, keymap, info))
1522 if (!HandleSymbolsVar((VarDef *) stmt, keymap, info))
1526 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
1530 ERROR("Interpretation files may not include other types\n");
1531 ACTION("Ignoring definition of symbol interpretation\n");
1534 case StmtKeycodeDef:
1535 ERROR("Interpretation files may not include other types\n");
1536 ACTION("Ignoring definition of key name\n");
1540 if (!HandleModMapDef((ModMapDef *) stmt, keymap, info))
1544 WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1549 if (info->errorCount > 10)
1552 ERROR("Too many errors\n");
1554 ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1561 FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
1562 xkb_keycode_t *kc_rtrn)
1565 unsigned int group, level;
1567 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++)
1569 for (group = 0; group < XkbKeyNumGroups(keymap, key); group++)
1571 for (level = 0; level < XkbKeyGroupWidth(keymap, key, group);
1574 if (XkbKeyNumSyms(keymap, key, group, level) != 1 ||
1575 (XkbKeySymEntry(keymap, key, group, level))[0] != sym)
1587 * Find the given name in the keymap->map->types and return its index.
1589 * @param atom The atom to search for.
1590 * @param type_rtrn Set to the index of the name if found.
1592 * @return true if found, false otherwise.
1595 FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn)
1598 const char *name = xkb_atom_text(keymap->ctx, atom);
1599 struct xkb_key_type *type;
1601 if (keymap && keymap->map) {
1602 darray_foreach(type, keymap->map->types) {
1603 if (strcmp(type->name, name) == 0) {
1614 * Assign a type to the given sym and return the Atom for the type assigned.
1617 * - ONE_LEVEL for width 0/1
1618 * - ALPHABETIC for 2 shift levels, with lower/upercase
1619 * - KEYPAD for keypad keys.
1620 * - TWO_LEVEL for other 2 shift level keys.
1621 * and the same for four level keys.
1623 * @param width Number of sysms in syms.
1624 * @param syms The keysyms for the given key (must be size width).
1625 * @param typeNameRtrn Set to the Atom of the type name.
1627 * @returns true if a type could be found, false otherwise.
1630 FindAutomaticType(struct xkb_keymap *keymap, int width,
1631 const xkb_keysym_t *syms, xkb_atom_t *typeNameRtrn,
1635 if ((width == 1) || (width == 0))
1637 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
1640 else if (width == 2)
1642 if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1644 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
1646 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1648 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "KEYPAD");
1653 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
1657 else if (width <= 4)
1659 if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1660 if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1662 xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_ALPHABETIC");
1664 *typeNameRtrn = xkb_atom_intern(keymap->ctx,
1665 "FOUR_LEVEL_SEMIALPHABETIC");
1667 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1668 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_KEYPAD");
1670 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL");
1671 /* XXX: why not set autoType here? */
1673 return ((width >= 0) && (width <= 4));
1677 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1678 * groups, and reduce to one group if all groups are identical anyway.
1681 PrepareKeyDef(KeyInfo * key)
1683 int i, j, width, defined, lastGroup;
1686 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1687 /* get highest group number */
1688 for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1690 if (defined & (1 << i))
1698 /* If there are empty groups between non-empty ones fill them with data */
1699 /* from the first group. */
1700 /* We can make a wrong assumption here. But leaving gaps is worse. */
1701 for (i = lastGroup; i > 0; i--)
1703 if (defined & (1 << i))
1705 width = key->numLevels[0];
1706 if (key->typesDefined & 1)
1708 for (j = 0; j < width; j++)
1710 key->types[i] = key->types[0];
1712 key->typesDefined |= 1 << i;
1714 if ((key->actsDefined & 1) && !darray_empty(key->acts[0]))
1716 darray_copy(key->acts[i], key->acts[0]);
1717 key->actsDefined |= 1 << i;
1719 if ((key->symsDefined & 1) && !darray_empty(key->syms[0]))
1721 darray_copy(key->syms[i], key->syms[0]);
1722 darray_copy(key->symsMapIndex[i], key->symsMapIndex[0]);
1723 darray_copy(key->symsMapNumEntries[i], key->symsMapNumEntries[0]);
1724 key->symsDefined |= 1 << i;
1728 key->numLevels[i] = key->numLevels[0];
1731 /* If all groups are completely identical remove them all */
1732 /* exept the first one. */
1734 for (i = lastGroup; i > 0; i--)
1736 if ((key->numLevels[i] != key->numLevels[0]) ||
1737 (key->types[i] != key->types[0]))
1742 if (!darray_same(key->syms[i], key->syms[0]) &&
1743 (darray_empty(key->syms[i]) || darray_empty(key->syms[0]) ||
1744 darray_size(key->syms[i]) != darray_size(key->syms[0]) ||
1745 memcmp(darray_mem(key->syms[i], 0),
1746 darray_mem(key->syms[0], 0),
1747 sizeof(xkb_keysym_t) * darray_size(key->syms[0]))))
1752 if (!darray_same(key->symsMapIndex[i], key->symsMapIndex[0]) &&
1753 (darray_empty(key->symsMapIndex[i]) ||
1754 darray_empty(key->symsMapIndex[0]) ||
1755 memcmp(darray_mem(key->symsMapIndex[i], 0),
1756 darray_mem(key->symsMapIndex[0], 0),
1757 key->numLevels[0] * sizeof(int))))
1762 if (!darray_same(key->symsMapNumEntries[i], key->symsMapNumEntries[0]) &&
1763 (darray_empty(key->symsMapNumEntries[i]) ||
1764 darray_empty(key->symsMapNumEntries[0]) ||
1765 memcmp(darray_mem(key->symsMapNumEntries[i], 0),
1766 darray_mem(key->symsMapNumEntries[0], 0),
1767 key->numLevels[0] * sizeof(size_t))))
1772 if (!darray_same(key->acts[i], key->acts[0]) &&
1773 (darray_empty(key->acts[i]) || darray_empty(key->acts[0]) ||
1774 memcmp(darray_mem(key->acts[i], 0),
1775 darray_mem(key->acts[0], 0),
1776 key->numLevels[0] * sizeof(union xkb_action))))
1784 for (i = lastGroup; i > 0; i--)
1786 key->numLevels[i] = 0;
1787 darray_free(key->syms[i]);
1788 darray_free(key->symsMapIndex[i]);
1789 darray_free(key->symsMapNumEntries[i]);
1790 darray_free(key->acts[i]);
1793 key->symsDefined &= 1;
1794 key->actsDefined &= 1;
1795 key->typesDefined &= 1;
1800 * Copy the KeyInfo into the keyboard description.
1802 * This function recurses.
1805 CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *key, int start_from)
1809 unsigned int sizeSyms = 0;
1810 unsigned width, tmp, nGroups;
1811 struct xkb_key_type * type;
1812 bool haveActions, autoType, useAlias;
1813 unsigned types[XkbNumKbdGroups];
1814 union xkb_action *outActs;
1815 unsigned int symIndex = 0;
1816 struct xkb_sym_map *sym_map;
1818 useAlias = (start_from == 0);
1820 /* get the keycode for the key. */
1821 if (!FindNamedKey(keymap, key->name, &kc, useAlias,
1822 CreateKeyNames(keymap), start_from))
1824 if ((start_from == 0) && (warningLevel >= 5))
1826 WARN("Key %s not found in keycodes\n", longText(key->name));
1827 ACTION("Symbols ignored\n");
1832 haveActions = false;
1833 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1835 if (((i + 1) > nGroups)
1836 && (((key->symsDefined | key->actsDefined) & (1 << i))
1837 || (key->typesDefined) & (1 << i)))
1839 if (!darray_empty(key->acts[i]))
1842 /* Assign the type to the key, if it is missing. */
1843 if (key->types[i] == XKB_ATOM_NONE)
1845 if (key->dfltType != XKB_ATOM_NONE)
1846 key->types[i] = key->dfltType;
1847 else if (FindAutomaticType(keymap, key->numLevels[i],
1848 darray_mem(key->syms[i], 0),
1849 &key->types[i], &autoType))
1854 if (warningLevel >= 5)
1856 WARN("No automatic type for %d symbols\n",
1857 (unsigned int) key->numLevels[i]);
1858 ACTION("Using %s for the %s key (keycode %d)\n",
1859 xkb_atom_text(keymap->ctx, key->types[i]),
1860 longText(key->name), kc);
1864 if (FindNamedType(keymap, key->types[i], &types[i]))
1866 if (!autoType || key->numLevels[i] > 2)
1867 keymap->server->explicit[kc] |= (1 << i);
1871 if (warningLevel >= 3)
1873 WARN("Type \"%s\" is not defined\n",
1874 xkb_atom_text(keymap->ctx, key->types[i]));
1875 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
1876 longText(key->name), kc);
1878 types[i] = XkbTwoLevelIndex;
1880 /* if the type specifies fewer levels than the key has, shrink the key */
1881 type = &darray_item(keymap->map->types, types[i]);
1882 if (type->num_levels < key->numLevels[i])
1884 if (warningLevel > 0)
1886 WARN("Type \"%s\" has %d levels, but %s has %d symbols\n",
1887 type->name, type->num_levels,
1888 xkb_atom_text(keymap->ctx, key->name), key->numLevels[i]);
1889 ACTION("Ignoring extra symbols\n");
1891 key->numLevels[i] = type->num_levels;
1893 if (key->numLevels[i] > width)
1894 width = key->numLevels[i];
1895 if (type->num_levels > width)
1896 width = type->num_levels;
1897 sizeSyms += darray_size(key->syms[i]);
1900 if (!XkbcResizeKeySyms(keymap, kc, sizeSyms))
1902 WSGO("Could not enlarge symbols for %s (keycode %d)\n",
1903 longText(key->name), kc);
1908 outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups);
1909 if (outActs == NULL)
1911 WSGO("Could not enlarge actions for %s (key %d)\n",
1912 longText(key->name), kc);
1915 keymap->server->explicit[kc] |= XkbExplicitInterpretMask;
1920 sym_map = &darray_item(keymap->map->key_sym_map, kc);
1922 if (key->defs.defined & _Key_GroupInfo)
1925 i = sym_map->group_info;
1927 sym_map->group_info = XkbSetNumGroups(i, nGroups);
1928 sym_map->width = width;
1929 sym_map->sym_index = uTypedCalloc(nGroups * width, int);
1930 sym_map->num_syms = uTypedCalloc(nGroups * width, unsigned int);
1932 for (i = 0; i < nGroups; i++)
1934 /* assign kt_index[i] to the index of the type in map->types.
1935 * kt_index[i] may have been set by a previous run (if we have two
1936 * layouts specified). Let's not overwrite it with the ONE_LEVEL
1937 * default group if we dont even have keys for this group anyway.
1939 * FIXME: There should be a better fix for this.
1941 if (key->numLevels[i])
1942 sym_map->kt_index[i] = types[i];
1943 if (!darray_empty(key->syms[i]))
1945 /* fill key to "width" symbols*/
1946 for (tmp = 0; tmp < width; tmp++)
1948 if (tmp < key->numLevels[i] &&
1949 darray_item(key->symsMapNumEntries[i], tmp) != 0)
1951 memcpy(darray_mem(sym_map->syms, symIndex),
1952 darray_mem(key->syms[i],
1953 darray_item(key->symsMapIndex[i], tmp)),
1954 darray_item(key->symsMapNumEntries[i], tmp) * sizeof(xkb_keysym_t));
1955 sym_map->sym_index[(i * width) + tmp] = symIndex;
1956 sym_map->num_syms[(i * width) + tmp] =
1957 darray_item(key->symsMapNumEntries[i], tmp);
1958 symIndex += sym_map->num_syms[(i * width) + tmp];
1962 sym_map->sym_index[(i * width) + tmp] = -1;
1963 sym_map->num_syms[(i * width) + tmp] = 0;
1965 if (outActs != NULL && !darray_empty(key->acts[i]))
1967 if (tmp < key->numLevels[i])
1968 outActs[tmp] = darray_item(key->acts[i], tmp);
1970 outActs[tmp].type = XkbSA_NoAction;
1975 switch (key->behavior.type & XkbKB_OpMask)
1980 keymap->server->behaviors[kc] = key->behavior;
1981 keymap->server->explicit[kc] |= XkbExplicitBehaviorMask;
1984 if (key->defs.defined & _Key_VModMap)
1986 keymap->server->vmodmap[kc] = key->vmodmap;
1987 keymap->server->explicit[kc] |= XkbExplicitVModMapMask;
1989 if (key->repeat != RepeatUndefined)
1991 if (key->repeat == RepeatYes)
1992 keymap->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
1994 keymap->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
1995 keymap->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
1998 if (nGroups > keymap->ctrls->num_groups)
1999 keymap->ctrls->num_groups = nGroups;
2001 /* do the same thing for the next key */
2002 CopySymbolsDef(keymap, key, kc + 1);
2007 CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry)
2011 if (!entry->haveSymbol &&
2012 !FindNamedKey(keymap, entry->u.keyName, &kc, true,
2013 CreateKeyNames(keymap), 0))
2015 if (warningLevel >= 5)
2017 WARN("Key %s not found in keycodes\n",
2018 longText(entry->u.keyName));
2019 ACTION("Modifier map entry for %s not updated\n",
2020 XkbcModIndexText(entry->modifier));
2024 else if (entry->haveSymbol &&
2025 !FindKeyForSymbol(keymap, entry->u.keySym, &kc))
2027 if (warningLevel > 5)
2029 WARN("Key \"%s\" not found in symbol map\n",
2030 XkbcKeysymText(entry->u.keySym));
2031 ACTION("Modifier map entry for %s not updated\n",
2032 XkbcModIndexText(entry->modifier));
2036 keymap->map->modmap[kc] |= (1 << entry->modifier);
2041 * Handle the xkb_symbols section of an xkb file.
2043 * @param file The parsed xkb_symbols section of the xkb file.
2044 * @param keymap Handle to the keyboard description to store the symbols in.
2045 * @param merge Merge strategy (e.g. MERGE_OVERRIDE).
2048 CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
2054 InitSymbolsInfo(&info, keymap);
2055 info.dflt.defs.fileID = file->id;
2056 info.dflt.defs.merge = merge;
2058 HandleSymbolsFile(file, keymap, merge, &info);
2060 if (darray_empty(info.keys))
2063 if (info.errorCount != 0)
2066 /* alloc memory in the xkb struct */
2067 if (XkbcAllocNames(keymap, XkbGroupNamesMask, 0) != Success) {
2068 WSGO("Can not allocate names in CompileSymbols\n");
2069 ACTION("Symbols not added\n");
2073 if (XkbcAllocClientMap(keymap, XkbKeySymsMask | XkbModifierMapMask, 0)
2075 WSGO("Could not allocate client map in CompileSymbols\n");
2076 ACTION("Symbols not added\n");
2080 if (XkbcAllocServerMap(keymap, XkbAllServerInfoMask, 32) != Success) {
2081 WSGO("Could not allocate server map in CompileSymbols\n");
2082 ACTION("Symbols not added\n");
2086 if (XkbcAllocControls(keymap) != Success) {
2087 WSGO("Could not allocate controls in CompileSymbols\n");
2088 ACTION("Symbols not added\n");
2092 /* now copy info into xkb. */
2093 ApplyAliases(keymap, &info.aliases);
2095 for (i = 0; i < XkbNumKbdGroups; i++) {
2096 if (info.groupNames[i] != XKB_ATOM_NONE) {
2097 free(keymap->names->groups[i]);
2098 keymap->names->groups[i] = xkb_atom_strdup(keymap->ctx,
2099 info.groupNames[i]);
2104 darray_foreach(key, info.keys)
2108 darray_foreach(key, info.keys)
2109 if (!CopySymbolsDef(keymap, key, 0))
2112 if (warningLevel > 3) {
2113 for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
2114 if (darray_item(keymap->names->keys, i).name[0] == '\0')
2117 if (XkbKeyNumGroups(keymap, i) < 1) {
2119 memcpy(buf, darray_item(keymap->names->keys, i).name, 4);
2121 WARN("No symbols defined for <%s> (keycode %d)\n", buf, i);
2127 ModMapEntry *mm, *next;
2128 for (mm = info.modMap; mm != NULL; mm = next) {
2129 if (!CopyModMapDef(keymap, mm))
2131 next = (ModMapEntry *) mm->defs.next;
2135 FreeSymbolsInfo(&info);
2139 FreeSymbolsInfo(&info);