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 ********************************************************/
29 #include "xkbcomp-priv.h"
30 #include "parseutils.h"
36 /***====================================================================***/
38 /* Needed to work with the typechecker. */
39 typedef darray (xkb_keysym_t) darray_xkb_keysym_t;
40 typedef darray (union xkb_action) darray_xkb_action;
44 #define RepeatUndefined ~((unsigned) 0)
46 #define _Key_Syms (1 << 0)
47 #define _Key_Acts (1 << 1)
48 #define _Key_Repeat (1 << 2)
49 #define _Key_Behavior (1 << 3)
50 #define _Key_Type_Dflt (1 << 4)
51 #define _Key_Types (1 << 5)
52 #define _Key_GroupInfo (1 << 6)
53 #define _Key_VModMap (1 << 7)
55 typedef struct _KeyInfo {
57 unsigned long name; /* the 4 chars of the key name, as long */
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;
86 uint8_t out_of_range_group_action;
87 uint8_t out_of_range_group_number;
91 * Init the given key info to sane values.
94 InitKeyInfo(KeyInfo *keyi, unsigned file_id)
97 static const char dflt[4] = "*";
99 keyi->defs.defined = 0;
100 keyi->defs.file_id = file_id;
101 keyi->defs.merge = MERGE_OVERRIDE;
102 keyi->defs.next = NULL;
103 keyi->name = KeyNameToLong(dflt);
104 keyi->typesDefined = keyi->symsDefined = keyi->actsDefined = 0;
106 for (i = 0; i < XkbNumKbdGroups; i++) {
107 keyi->numLevels[i] = 0;
108 keyi->types[i] = XKB_ATOM_NONE;
109 darray_init(keyi->syms[i]);
110 darray_init(keyi->symsMapIndex[i]);
111 darray_init(keyi->symsMapNumEntries[i]);
112 darray_init(keyi->acts[i]);
115 keyi->dfltType = XKB_ATOM_NONE;
116 keyi->behavior.type = XkbKB_Default;
117 keyi->behavior.data = 0;
119 keyi->repeat = RepeatUndefined;
120 keyi->out_of_range_group_action = 0;
121 keyi->out_of_range_group_number = 0;
125 FreeKeyInfo(KeyInfo *keyi)
129 for (i = 0; i < XkbNumKbdGroups; i++) {
130 darray_free(keyi->syms[i]);
131 darray_free(keyi->symsMapIndex[i]);
132 darray_free(keyi->symsMapNumEntries[i]);
133 darray_free(keyi->acts[i]);
138 * Copy old into new, optionally reset old to 0.
139 * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
140 * newly allocated and new points to the new memory areas.
143 CopyKeyInfo(KeyInfo * old, KeyInfo * new, bool clearOld)
148 new->defs.next = NULL;
151 for (i = 0; i < XkbNumKbdGroups; i++) {
152 old->numLevels[i] = 0;
153 darray_init(old->symsMapIndex[i]);
154 darray_init(old->symsMapNumEntries[i]);
155 darray_init(old->syms[i]);
156 darray_init(old->acts[i]);
160 for (i = 0; i < XkbNumKbdGroups; i++) {
161 darray_copy(new->syms[i], old->syms[i]);
162 darray_copy(new->symsMapIndex[i], old->symsMapIndex[i]);
163 darray_copy(new->symsMapNumEntries[i], old->symsMapNumEntries[i]);
164 darray_copy(new->acts[i], old->acts[i]);
171 /***====================================================================***/
173 typedef struct _ModMapEntry {
178 unsigned long keyName;
183 typedef struct _SymbolsInfo {
184 char *name; /* e.g. pc+us+inet(evdev) */
187 enum merge_mode merge;
188 unsigned explicit_group;
189 darray(KeyInfo) keys;
193 xkb_atom_t groupNames[XkbNumKbdGroups];
200 InitSymbolsInfo(SymbolsInfo * info, struct xkb_keymap *keymap,
206 info->explicit_group = 0;
207 info->errorCount = 0;
208 info->file_id = file_id;
209 info->merge = MERGE_OVERRIDE;
210 darray_init(info->keys);
211 darray_growalloc(info->keys, 110);
213 for (i = 0; i < XkbNumKbdGroups; i++)
214 info->groupNames[i] = XKB_ATOM_NONE;
215 InitKeyInfo(&info->dflt, file_id);
216 InitVModInfo(&info->vmods, keymap);
218 info->aliases = NULL;
222 FreeSymbolsInfo(SymbolsInfo * info)
227 darray_foreach(keyi, info->keys) {
230 darray_free(info->keys);
232 ClearCommonInfo(&info->modMap->defs);
234 ClearAliases(&info->aliases);
235 memset(info, 0, sizeof(SymbolsInfo));
239 ResizeKeyGroup(KeyInfo *keyi, unsigned int group, unsigned int numLevels,
240 unsigned sizeSyms, bool forceActions)
244 if (darray_size(keyi->syms[group]) < sizeSyms)
245 darray_resize0(keyi->syms[group], sizeSyms);
247 if (darray_empty(keyi->symsMapIndex[group]) ||
248 keyi->numLevels[group] < numLevels) {
249 darray_resize(keyi->symsMapIndex[group], numLevels);
250 for (i = keyi->numLevels[group]; i < numLevels; i++)
251 darray_item(keyi->symsMapIndex[group], i) = -1;
254 if (darray_empty(keyi->symsMapNumEntries[group]) ||
255 keyi->numLevels[group] < numLevels)
256 darray_resize0(keyi->symsMapNumEntries[group], numLevels);
258 if ((forceActions && (keyi->numLevels[group] < numLevels ||
259 darray_empty(keyi->acts[group]))) ||
260 (keyi->numLevels[group] < numLevels && !darray_empty(keyi->acts[group])))
261 darray_resize0(keyi->acts[group], numLevels);
263 if (keyi->numLevels[group] < numLevels)
264 keyi->numLevels[group] = numLevels;
269 enum key_group_selector {
276 MergeKeyGroups(SymbolsInfo * info,
277 KeyInfo * into, KeyInfo * from, unsigned group)
279 darray_xkb_keysym_t resultSyms;
280 enum key_group_selector using = NONE;
281 darray_xkb_action resultActs;
282 unsigned int resultWidth;
283 unsigned int resultSize = 0;
286 bool report, clobber;
288 clobber = (from->defs.merge != MERGE_AUGMENT);
290 report = (warningLevel > 9) ||
291 ((into->defs.file_id == from->defs.file_id) && (warningLevel > 0));
293 darray_init(resultSyms);
295 if (into->numLevels[group] >= from->numLevels[group]) {
296 resultActs = into->acts[group];
297 resultWidth = into->numLevels[group];
300 resultActs = from->acts[group];
301 resultWidth = from->numLevels[group];
302 darray_resize(into->symsMapIndex[group],
303 from->numLevels[group]);
304 darray_resize0(into->symsMapNumEntries[group],
305 from->numLevels[group]);
307 for (i = into->numLevels[group]; i < from->numLevels[group]; i++)
308 darray_item(into->symsMapIndex[group], i) = -1;
311 if (darray_empty(resultActs) && (!darray_empty(into->acts[group]) ||
312 !darray_empty(from->acts[group]))) {
313 darray_resize0(resultActs, resultWidth);
314 for (i = 0; i < resultWidth; i++) {
315 union xkb_action *fromAct = NULL, *toAct = NULL;
317 if (!darray_empty(from->acts[group]))
318 fromAct = &darray_item(from->acts[group], i);
320 if (!darray_empty(into->acts[group]))
321 toAct = &darray_item(into->acts[group], i);
323 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
324 && (toAct != NULL)) {
325 darray_item(resultActs, i) = *toAct;
327 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
328 && (fromAct != NULL)) {
329 darray_item(resultActs, i) = *fromAct;
332 union xkb_action *use, *ignore;
343 ("Multiple actions for level %d/group %d on key %s\n",
344 i + 1, group + 1, longText(into->name));
345 ACTION("Using %s, ignoring %s\n",
346 XkbcActionTypeText(use->type),
347 XkbcActionTypeText(ignore->type));
350 darray_item(resultActs, i) = *use;
355 for (i = 0; i < resultWidth; i++) {
356 unsigned int fromSize = 0;
359 if (!darray_empty(from->symsMapNumEntries[group]) &&
360 i < from->numLevels[group])
361 fromSize = darray_item(from->symsMapNumEntries[group], i);
363 if (!darray_empty(into->symsMapNumEntries[group]) &&
364 i < into->numLevels[group])
365 toSize = darray_item(into->symsMapNumEntries[group], i);
368 resultSize += toSize;
371 else if (toSize == 0 || clobber) {
372 resultSize += fromSize;
376 resultSize += toSize;
385 resultSyms = from->syms[group];
386 darray_free(into->symsMapNumEntries[group]);
387 darray_free(into->symsMapIndex[group]);
388 into->symsMapNumEntries[group] = from->symsMapNumEntries[group];
389 into->symsMapIndex[group] = from->symsMapIndex[group];
390 darray_init(from->symsMapNumEntries[group]);
391 darray_init(from->symsMapIndex[group]);
394 else if (using == TO) {
395 resultSyms = into->syms[group];
399 darray_resize0(resultSyms, resultSize);
401 for (i = 0; i < resultWidth; i++) {
402 enum key_group_selector use = NONE;
403 unsigned int fromSize = 0;
404 unsigned int toSize = 0;
406 if (i < from->numLevels[group])
407 fromSize = darray_item(from->symsMapNumEntries[group], i);
409 if (i < into->numLevels[group])
410 toSize = darray_item(into->symsMapNumEntries[group], i);
412 if (fromSize == 0 && toSize == 0) {
413 darray_item(into->symsMapIndex[group], i) = -1;
414 darray_item(into->symsMapNumEntries[group], i) = 0;
420 else if (toSize == 0 || clobber)
425 if (toSize && fromSize && report) {
426 INFO("Multiple symbols for group %d, level %d on key %s\n",
427 group + 1, i + 1, longText(into->name));
428 ACTION("Using %s, ignoring %s\n",
429 (use == FROM ? "from" : "to"),
430 (use == FROM ? "to" : "from"));
434 memcpy(darray_mem(resultSyms, cur_idx),
435 darray_mem(from->syms[group],
436 darray_item(from->symsMapIndex[group], i)),
437 darray_item(from->symsMapNumEntries[group],
438 i) * sizeof(xkb_keysym_t));
439 darray_item(into->symsMapIndex[group], i) = cur_idx;
440 darray_item(into->symsMapNumEntries[group], i) =
441 darray_item(from->symsMapNumEntries[group], i);
444 memcpy(darray_mem(resultSyms, cur_idx),
445 darray_mem(into->syms[group],
446 darray_item(into->symsMapIndex[group], i)),
447 darray_item(into->symsMapNumEntries[group],
448 i) * sizeof(xkb_keysym_t));
449 darray_item(into->symsMapIndex[group], i) = cur_idx;
451 cur_idx += darray_item(into->symsMapNumEntries[group], i);
455 if (!darray_same(resultActs, into->acts[group]))
456 darray_free(into->acts[group]);
457 if (!darray_same(resultActs, from->acts[group]))
458 darray_free(from->acts[group]);
459 into->numLevels[group] = resultWidth;
460 if (!darray_same(resultSyms, into->syms[group]))
461 darray_free(into->syms[group]);
462 into->syms[group] = resultSyms;
463 if (!darray_same(resultSyms, from->syms[group]))
464 darray_free(from->syms[group]);
465 darray_init(from->syms[group]);
466 darray_free(from->symsMapIndex[group]);
467 darray_free(from->symsMapNumEntries[group]);
468 into->acts[group] = resultActs;
469 darray_init(from->acts[group]);
470 if (!darray_empty(into->syms[group]))
471 into->symsDefined |= (1 << group);
472 from->symsDefined &= ~(1 << group);
473 into->actsDefined |= (1 << group);
474 from->actsDefined &= ~(1 << group);
480 MergeKeys(SymbolsInfo *info, struct xkb_keymap *keymap,
481 KeyInfo *into, KeyInfo *from)
484 unsigned collide = 0;
487 if (from->defs.merge == MERGE_REPLACE) {
488 for (i = 0; i < XkbNumKbdGroups; i++) {
489 if (into->numLevels[i] != 0) {
490 darray_free(into->syms[i]);
491 darray_free(into->acts[i]);
495 memset(from, 0, sizeof(KeyInfo));
498 report = ((warningLevel > 9) ||
499 ((into->defs.file_id == from->defs.file_id)
500 && (warningLevel > 0)));
501 for (i = 0; i < XkbNumKbdGroups; i++) {
502 if (from->numLevels[i] > 0) {
503 if (into->numLevels[i] == 0) {
504 into->numLevels[i] = from->numLevels[i];
505 into->syms[i] = from->syms[i];
506 into->symsMapIndex[i] = from->symsMapIndex[i];
507 into->symsMapNumEntries[i] = from->symsMapNumEntries[i];
508 into->acts[i] = from->acts[i];
509 into->symsDefined |= (1 << i);
510 darray_init(from->syms[i]);
511 darray_init(from->symsMapIndex[i]);
512 darray_init(from->symsMapNumEntries[i]);
513 darray_init(from->acts[i]);
514 from->numLevels[i] = 0;
515 from->symsDefined &= ~(1 << i);
516 if (!darray_empty(into->syms[i]))
517 into->defs.defined |= _Key_Syms;
518 if (!darray_empty(into->acts[i]))
519 into->defs.defined |= _Key_Acts;
523 if (!darray_empty(into->syms[i]))
524 collide |= _Key_Syms;
525 if (!darray_empty(into->acts[i]))
526 collide |= _Key_Acts;
528 MergeKeyGroups(info, into, from, (unsigned) i);
531 if (from->types[i] != XKB_ATOM_NONE) {
532 if ((into->types[i] != XKB_ATOM_NONE) && report &&
533 (into->types[i] != from->types[i])) {
534 xkb_atom_t use, ignore;
535 collide |= _Key_Types;
536 if (from->defs.merge != MERGE_AUGMENT) {
537 use = from->types[i];
538 ignore = into->types[i];
541 use = into->types[i];
542 ignore = from->types[i];
545 ("Multiple definitions for group %d type of key %s\n",
546 i, longText(into->name));
547 ACTION("Using %s, ignoring %s\n",
548 xkb_atom_text(keymap->ctx, use),
549 xkb_atom_text(keymap->ctx, ignore));
551 if ((from->defs.merge != MERGE_AUGMENT)
552 || (into->types[i] == XKB_ATOM_NONE)) {
553 into->types[i] = from->types[i];
557 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide)) {
558 into->behavior = from->behavior;
559 into->defs.defined |= _Key_Behavior;
561 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide)) {
562 into->vmodmap = from->vmodmap;
563 into->defs.defined |= _Key_VModMap;
565 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide)) {
566 into->repeat = from->repeat;
567 into->defs.defined |= _Key_Repeat;
569 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide)) {
570 into->dfltType = from->dfltType;
571 into->defs.defined |= _Key_Type_Dflt;
573 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide)) {
574 into->out_of_range_group_action = from->out_of_range_group_action;
575 into->out_of_range_group_number = from->out_of_range_group_number;
576 into->defs.defined |= _Key_GroupInfo;
579 WARN("Symbol map for key %s redefined\n",
580 longText(into->name));
581 ACTION("Using %s definition for conflicting fields\n",
582 (from->defs.merge == MERGE_AUGMENT ? "first" : "last"));
588 AddKeySymbols(SymbolsInfo *info, KeyInfo *keyi, struct xkb_keymap *keymap)
590 unsigned long real_name;
593 darray_foreach(iter, info->keys)
594 if (iter->name == keyi->name)
595 return MergeKeys(info, keymap, iter, keyi);
597 if (FindKeyNameForAlias(keymap, keyi->name, &real_name))
598 darray_foreach(iter, info->keys)
599 if (iter->name == real_name)
600 return MergeKeys(info, keymap, iter, keyi);
602 darray_resize0(info->keys, darray_size(info->keys) + 1);
603 new = &darray_item(info->keys, darray_size(info->keys) - 1);
604 return CopyKeyInfo(keyi, new, true);
608 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
613 clobber = (new->defs.merge != MERGE_AUGMENT);
614 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next) {
615 if (new->haveSymbol && mm->haveSymbol
616 && (new->u.keySym == mm->u.keySym)) {
617 unsigned use, ignore;
618 if (mm->modifier != new->modifier) {
621 ignore = mm->modifier;
625 ignore = new->modifier;
628 ("%s added to symbol map for multiple modifiers\n",
629 XkbcKeysymText(new->u.keySym));
630 ACTION("Using %s, ignoring %s.\n",
631 XkbcModIndexText(use),
632 XkbcModIndexText(ignore));
637 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
638 (new->u.keyName == mm->u.keyName)) {
639 unsigned use, ignore;
640 if (mm->modifier != new->modifier) {
643 ignore = mm->modifier;
647 ignore = new->modifier;
649 ERROR("Key %s added to map for multiple modifiers\n",
650 longText(new->u.keyName));
651 ACTION("Using %s, ignoring %s.\n",
652 XkbcModIndexText(use),
653 XkbcModIndexText(ignore));
659 mm = uTypedAlloc(ModMapEntry);
661 WSGO("Could not allocate modifier map entry\n");
662 ACTION("Modifier map for %s will be incomplete\n",
663 XkbcModIndexText(new->modifier));
667 mm->defs.next = &info->modMap->defs;
672 /***====================================================================***/
675 MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
676 enum merge_mode merge, struct xkb_keymap *keymap)
681 if (from->errorCount > 0) {
682 into->errorCount += from->errorCount;
685 if (into->name == NULL) {
686 into->name = from->name;
689 for (i = 0; i < XkbNumKbdGroups; i++) {
690 if (from->groupNames[i] != XKB_ATOM_NONE) {
691 if ((merge != MERGE_AUGMENT) ||
692 (into->groupNames[i] == XKB_ATOM_NONE))
693 into->groupNames[i] = from->groupNames[i];
697 darray_foreach(keyi, from->keys) {
698 if (merge != MERGE_DEFAULT)
699 keyi->defs.merge = merge;
701 if (!AddKeySymbols(into, keyi, keymap))
705 if (from->modMap != NULL) {
706 ModMapEntry *mm, *next;
707 for (mm = from->modMap; mm != NULL; mm = next) {
708 if (merge != MERGE_DEFAULT)
709 mm->defs.merge = merge;
710 if (!AddModMapEntry(into, mm))
712 next = (ModMapEntry *) mm->defs.next;
717 if (!MergeAliases(&into->aliases, &from->aliases, merge))
722 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
723 enum merge_mode merge,
727 HandleIncludeSymbols(IncludeStmt *stmt, struct xkb_keymap *keymap,
730 enum merge_mode newMerge;
732 SymbolsInfo included;
736 if ((stmt->file == NULL) && (stmt->map == NULL)) {
739 memset(info, 0, sizeof(SymbolsInfo));
741 else if (ProcessIncludeFile(keymap->ctx, stmt, FILE_TYPE_SYMBOLS, &rtrn,
743 InitSymbolsInfo(&included, keymap, rtrn->id);
744 included.merge = included.dflt.defs.merge = MERGE_OVERRIDE;
745 if (stmt->modifier) {
746 included.explicit_group = atoi(stmt->modifier) - 1;
749 included.explicit_group = info->explicit_group;
751 HandleSymbolsFile(rtrn, keymap, MERGE_OVERRIDE, &included);
752 if (stmt->stmt != NULL) {
754 included.name = stmt->stmt;
760 info->errorCount += 10;
763 if ((stmt->next != NULL) && (included.errorCount < 1)) {
766 SymbolsInfo next_incl;
768 for (next = stmt->next; next != NULL; next = next->next) {
769 if ((next->file == NULL) && (next->map == NULL)) {
771 MergeIncludedSymbols(&included, info, next->merge, keymap);
772 FreeSymbolsInfo(info);
774 else if (ProcessIncludeFile(keymap->ctx, next, FILE_TYPE_SYMBOLS,
776 InitSymbolsInfo(&next_incl, keymap, rtrn->id);
777 next_incl.merge = next_incl.dflt.defs.merge = MERGE_OVERRIDE;
778 if (next->modifier) {
779 next_incl.explicit_group = atoi(next->modifier) - 1;
782 next_incl.explicit_group = info->explicit_group;
784 HandleSymbolsFile(rtrn, keymap, MERGE_OVERRIDE, &next_incl);
785 MergeIncludedSymbols(&included, &next_incl, op, keymap);
786 FreeSymbolsInfo(&next_incl);
790 info->errorCount += 10;
791 FreeSymbolsInfo(&included);
796 else if (stmt->next) {
797 info->errorCount += included.errorCount;
802 MergeIncludedSymbols(info, &included, newMerge, keymap);
803 FreeSymbolsInfo(&included);
805 return (info->errorCount == 0);
812 GetGroupIndex(KeyInfo *keyi, struct xkb_keymap *keymap,
813 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
823 if (arrayNdx == NULL) {
827 defined = keyi->symsDefined;
829 defined = keyi->actsDefined;
831 for (i = 0; i < XkbNumKbdGroups; i++) {
832 if ((defined & (1 << i)) == 0) {
837 ERROR("Too many groups of %s for key %s (max %d)\n", name,
838 longText(keyi->name), XkbNumKbdGroups + 1);
839 ACTION("Ignoring %s defined for extra groups\n", name);
842 if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp)) {
843 ERROR("Illegal group index for %s of key %s\n", name,
844 longText(keyi->name));
845 ACTION("Definition with non-integer array index ignored\n");
848 *ndx_rtrn = tmp.uval - 1;
853 AddSymbolsToKey(KeyInfo *keyi, struct xkb_keymap *keymap,
854 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
856 unsigned ndx, nSyms, nLevels;
860 if (!GetGroupIndex(keyi, keymap, arrayNdx, SYMBOLS, &ndx))
863 keyi->symsDefined |= (1 << ndx);
866 if (value->op != ExprKeysymList) {
867 ERROR("Expected a list of symbols, found %s\n", exprOpText(value->op));
868 ACTION("Ignoring symbols for group %d of %s\n", ndx + 1,
869 longText(keyi->name));
872 if (!darray_empty(keyi->syms[ndx])) {
873 ERROR("Symbols for key %s, group %d already defined\n",
874 longText(keyi->name), ndx + 1);
875 ACTION("Ignoring duplicate definition\n");
878 nSyms = darray_size(value->value.list.syms);
879 nLevels = darray_size(value->value.list.symsMapIndex);
880 if ((keyi->numLevels[ndx] < nSyms || darray_empty(keyi->syms[ndx])) &&
881 (!ResizeKeyGroup(keyi, ndx, nLevels, nSyms, false))) {
882 WSGO("Could not resize group %d of key %s to contain %d levels\n",
883 ndx + 1, longText(keyi->name), nSyms);
884 ACTION("Symbols lost\n");
887 keyi->symsDefined |= (1 << ndx);
888 for (i = 0; i < nLevels; i++) {
889 darray_item(keyi->symsMapIndex[ndx], i) =
890 darray_item(value->value.list.symsMapIndex, i);
891 darray_item(keyi->symsMapNumEntries[ndx], i) =
892 darray_item(value->value.list.symsNumEntries, i);
894 for (j = 0; j < darray_item(keyi->symsMapNumEntries[ndx], i); j++) {
895 /* FIXME: What's abort() doing here? */
896 if (darray_item(keyi->symsMapIndex[ndx], i) + j >= nSyms)
898 if (!LookupKeysym(darray_item(value->value.list.syms,
899 darray_item(value->value.list.symsMapIndex,
901 &darray_item(keyi->syms[ndx],
902 darray_item(keyi->symsMapIndex[ndx],
905 "Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
906 darray_item(value->value.list.syms, i),
907 longText(keyi->name),
909 xkb_atom_text(keymap->ctx, info->groupNames[ndx]), nSyms);
911 darray_item(keyi->syms[ndx],
912 darray_item(keyi->symsMapIndex[ndx],
913 i) + j) = XKB_KEY_NoSymbol;
914 darray_item(keyi->symsMapIndex[ndx], i) = -1;
915 darray_item(keyi->symsMapNumEntries[ndx], i) = 0;
918 if (darray_item(keyi->symsMapNumEntries[ndx], i) == 1 &&
919 darray_item(keyi->syms[ndx],
920 darray_item(keyi->symsMapIndex[ndx],
921 i) + j) == XKB_KEY_NoSymbol) {
922 darray_item(keyi->symsMapIndex[ndx], i) = -1;
923 darray_item(keyi->symsMapNumEntries[ndx], i) = 0;
927 for (j = keyi->numLevels[ndx] - 1;
928 j >= 0 && darray_item(keyi->symsMapNumEntries[ndx], j) == 0; j--)
929 keyi->numLevels[ndx]--;
934 AddActionsToKey(KeyInfo *keyi, struct xkb_keymap *keymap, ExprDef *arrayNdx,
935 ExprDef *value, SymbolsInfo *info)
940 struct xkb_any_action *toAct;
942 if (!GetGroupIndex(keyi, keymap, arrayNdx, ACTIONS, &ndx))
946 keyi->actsDefined |= (1 << ndx);
949 if (value->op != ExprActionList) {
950 WSGO("Bad expression type (%d) for action list value\n", value->op);
951 ACTION("Ignoring actions for group %d of %s\n", ndx,
952 longText(keyi->name));
955 if (!darray_empty(keyi->acts[ndx])) {
956 WSGO("Actions for key %s, group %d already defined\n",
957 longText(keyi->name), ndx);
960 for (nActs = 0, act = value->value.child; act != NULL; nActs++) {
961 act = (ExprDef *) act->common.next;
964 WSGO("Action list but not actions in AddActionsToKey\n");
967 if ((keyi->numLevels[ndx] < nActs || darray_empty(keyi->acts[ndx])) &&
968 !ResizeKeyGroup(keyi, ndx, nActs, nActs, true)) {
969 WSGO("Could not resize group %d of key %s\n", ndx,
970 longText(keyi->name));
971 ACTION("Actions lost\n");
974 keyi->actsDefined |= (1 << ndx);
976 toAct = (struct xkb_any_action *) darray_mem(keyi->acts[ndx], 0);
977 act = value->value.child;
978 for (i = 0; i < nActs; i++, toAct++) {
979 if (!HandleActionDef(act, keymap, toAct, info->action)) {
980 ERROR("Illegal action definition for %s\n",
981 longText(keyi->name));
982 ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
984 act = (ExprDef *) act->common.next;
989 static const LookupEntry lockingEntries[] = {
990 { "true", XkbKB_Lock },
991 { "yes", XkbKB_Lock },
992 { "on", XkbKB_Lock },
993 { "false", XkbKB_Default },
994 { "no", XkbKB_Default },
995 { "off", XkbKB_Default },
996 { "permanent", XkbKB_Lock | XkbKB_Permanent },
1000 static const LookupEntry repeatEntries[] = {
1001 { "true", RepeatYes },
1002 { "yes", RepeatYes },
1003 { "on", RepeatYes },
1004 { "false", RepeatNo },
1006 { "off", RepeatNo },
1007 { "default", RepeatUndefined },
1012 SetSymbolsField(KeyInfo *keyi, struct xkb_keymap *keymap, char *field,
1013 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
1018 if (strcasecmp(field, "type") == 0) {
1020 if ((!ExprResolveString(keymap->ctx, value, &tmp))
1021 && (warningLevel > 0)) {
1022 WARN("The type field of a key symbol map must be a string\n");
1023 ACTION("Ignoring illegal type definition\n");
1025 if (arrayNdx == NULL) {
1026 keyi->dfltType = xkb_atom_intern(keymap->ctx, tmp.str);
1027 keyi->defs.defined |= _Key_Type_Dflt;
1029 else if (!ExprResolveGroup(keymap->ctx, arrayNdx, &ndx)) {
1030 ERROR("Illegal group index for type of key %s\n",
1031 longText(keyi->name));
1032 ACTION("Definition with non-integer array index ignored\n");
1037 keyi->types[ndx.uval - 1] = xkb_atom_intern(keymap->ctx, tmp.str);
1038 keyi->typesDefined |= (1 << (ndx.uval - 1));
1042 else if (strcasecmp(field, "symbols") == 0)
1043 return AddSymbolsToKey(keyi, keymap, arrayNdx, value, info);
1044 else if (strcasecmp(field, "actions") == 0)
1045 return AddActionsToKey(keyi, keymap, arrayNdx, value, info);
1046 else if ((strcasecmp(field, "vmods") == 0) ||
1047 (strcasecmp(field, "virtualmods") == 0) ||
1048 (strcasecmp(field, "virtualmodifiers") == 0)) {
1049 ok = ExprResolveVModMask(value, &tmp, keymap);
1051 keyi->vmodmap = (tmp.uval >> 8);
1052 keyi->defs.defined |= _Key_VModMap;
1055 ERROR("Expected a virtual modifier mask, found %s\n",
1056 exprOpText(value->op));
1057 ACTION("Ignoring virtual modifiers definition for key %s\n",
1058 longText(keyi->name));
1061 else if ((strcasecmp(field, "locking") == 0) ||
1062 (strcasecmp(field, "lock") == 0) ||
1063 (strcasecmp(field, "locks") == 0)) {
1064 ok = ExprResolveEnum(keymap->ctx, value, &tmp, lockingEntries);
1066 keyi->behavior.type = tmp.uval;
1067 keyi->defs.defined |= _Key_Behavior;
1069 else if ((strcasecmp(field, "radiogroup") == 0) ||
1070 (strcasecmp(field, "permanentradiogroup") == 0) ||
1071 (strcasecmp(field, "allownone") == 0)) {
1072 ERROR("Radio groups not supported\n");
1073 ACTION("Ignoring radio group specification for key %s\n",
1074 longText(keyi->name));
1077 else if (uStrCasePrefix("overlay", field) ||
1078 uStrCasePrefix("permanentoverlay", field)) {
1079 ERROR("Overlays not supported\n");
1080 ACTION("Ignoring overlay specification for key %s\n",
1081 longText(keyi->name));
1083 else if ((strcasecmp(field, "repeating") == 0) ||
1084 (strcasecmp(field, "repeats") == 0) ||
1085 (strcasecmp(field, "repeat") == 0)) {
1086 ok = ExprResolveEnum(keymap->ctx, value, &tmp, repeatEntries);
1088 ERROR("Illegal repeat setting for %s\n",
1089 longText(keyi->name));
1090 ACTION("Non-boolean repeat setting ignored\n");
1093 keyi->repeat = tmp.uval;
1094 keyi->defs.defined |= _Key_Repeat;
1096 else if ((strcasecmp(field, "groupswrap") == 0) ||
1097 (strcasecmp(field, "wrapgroups") == 0)) {
1098 ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1100 ERROR("Illegal groupsWrap setting for %s\n",
1101 longText(keyi->name));
1102 ACTION("Non-boolean value ignored\n");
1106 keyi->out_of_range_group_action = XkbWrapIntoRange;
1108 keyi->out_of_range_group_action = XkbClampIntoRange;
1109 keyi->defs.defined |= _Key_GroupInfo;
1111 else if ((strcasecmp(field, "groupsclamp") == 0) ||
1112 (strcasecmp(field, "clampgroups") == 0)) {
1113 ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1115 ERROR("Illegal groupsClamp setting for %s\n",
1116 longText(keyi->name));
1117 ACTION("Non-boolean value ignored\n");
1121 keyi->out_of_range_group_action = XkbClampIntoRange;
1123 keyi->out_of_range_group_action = XkbWrapIntoRange;
1124 keyi->defs.defined |= _Key_GroupInfo;
1126 else if ((strcasecmp(field, "groupsredirect") == 0) ||
1127 (strcasecmp(field, "redirectgroups") == 0)) {
1128 if (!ExprResolveGroup(keymap->ctx, value, &tmp)) {
1129 ERROR("Illegal group index for redirect of key %s\n",
1130 longText(keyi->name));
1131 ACTION("Definition with non-integer group ignored\n");
1134 keyi->out_of_range_group_action = XkbRedirectIntoRange;
1135 keyi->out_of_range_group_number = tmp.uval - 1;
1136 keyi->defs.defined |= _Key_GroupInfo;
1139 ERROR("Unknown field %s in a symbol interpretation\n", field);
1140 ACTION("Definition ignored\n");
1147 SetGroupName(SymbolsInfo *info, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1150 ExprResult tmp, name;
1152 if ((arrayNdx == NULL) && (warningLevel > 0)) {
1153 WARN("You must specify an index when specifying a group name\n");
1154 ACTION("Group name definition without array subscript ignored\n");
1157 if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp)) {
1158 ERROR("Illegal index in group name definition\n");
1159 ACTION("Definition with non-integer array index ignored\n");
1162 if (!ExprResolveString(keymap->ctx, value, &name)) {
1163 ERROR("Group name must be a string\n");
1164 ACTION("Illegal name for group %d ignored\n", tmp.uval);
1167 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1168 xkb_atom_intern(keymap->ctx, name.str);
1175 HandleSymbolsVar(VarDef *stmt, struct xkb_keymap *keymap, SymbolsInfo *info)
1177 ExprResult elem, field;
1181 if (ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx) == 0)
1182 return 0; /* internal error, already reported */
1183 if (elem.str && (strcasecmp(elem.str, "key") == 0)) {
1184 ret = SetSymbolsField(&info->dflt, keymap, field.str, arrayNdx,
1187 else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) ||
1188 (strcasecmp(field.str, "groupname") ==
1190 ret = SetGroupName(info, keymap, arrayNdx, stmt->value);
1192 else if ((elem.str == NULL)
1193 && ((strcasecmp(field.str, "groupswrap") == 0) ||
1194 (strcasecmp(field.str, "wrapgroups") == 0))) {
1195 ERROR("Global \"groupswrap\" not supported\n");
1196 ACTION("Ignored\n");
1199 else if ((elem.str == NULL)
1200 && ((strcasecmp(field.str, "groupsclamp") == 0) ||
1201 (strcasecmp(field.str, "clampgroups") == 0))) {
1202 ERROR("Global \"groupsclamp\" not supported\n");
1203 ACTION("Ignored\n");
1206 else if ((elem.str == NULL)
1207 && ((strcasecmp(field.str, "groupsredirect") == 0) ||
1208 (strcasecmp(field.str, "redirectgroups") == 0))) {
1209 ERROR("Global \"groupsredirect\" not supported\n");
1210 ACTION("Ignored\n");
1213 else if ((elem.str == NULL) &&
1214 (strcasecmp(field.str, "allownone") == 0)) {
1215 ERROR("Radio groups not supported\n");
1216 ACTION("Ignoring \"allownone\" specification\n");
1220 ret = SetActionField(keymap, elem.str, field.str, arrayNdx,
1221 stmt->value, &info->action);
1230 HandleSymbolsBody(VarDef *def, struct xkb_keymap *keymap, KeyInfo *keyi,
1234 ExprResult tmp, field;
1237 for (; def != NULL; def = (VarDef *) def->common.next) {
1238 if ((def->name) && (def->name->type == ExprFieldRef)) {
1239 ok = HandleSymbolsVar(def, keymap, info);
1243 if (def->name == NULL) {
1244 if ((def->value == NULL)
1245 || (def->value->op == ExprKeysymList))
1246 field.str = strdup("symbols");
1248 field.str = strdup("actions");
1252 ok = ExprResolveLhs(keymap, def->name, &tmp, &field,
1256 ok = SetSymbolsField(keyi, keymap, field.str, arrayNdx,
1265 SetExplicitGroup(SymbolsInfo *info, KeyInfo *keyi)
1267 unsigned group = info->explicit_group;
1272 if ((keyi->typesDefined | keyi->symsDefined | keyi->actsDefined) & ~1) {
1274 WARN("For the map %s an explicit group specified\n", info->name);
1275 WARN("but key %s has more than one group defined\n",
1276 longText(keyi->name));
1277 ACTION("All groups except first one will be ignored\n");
1278 for (i = 1; i < XkbNumKbdGroups; i++) {
1279 keyi->numLevels[i] = 0;
1280 darray_free(keyi->syms[i]);
1281 darray_free(keyi->acts[i]);
1285 keyi->typesDefined = keyi->symsDefined = keyi->actsDefined = 1 << group;
1287 keyi->numLevels[group] = keyi->numLevels[0];
1288 keyi->numLevels[0] = 0;
1289 keyi->syms[group] = keyi->syms[0];
1290 darray_init(keyi->syms[0]);
1291 keyi->symsMapIndex[group] = keyi->symsMapIndex[0];
1292 darray_init(keyi->symsMapIndex[0]);
1293 keyi->symsMapNumEntries[group] = keyi->symsMapNumEntries[0];
1294 darray_init(keyi->symsMapNumEntries[0]);
1295 keyi->acts[group] = keyi->acts[0];
1296 darray_init(keyi->acts[0]);
1297 keyi->types[group] = keyi->types[0];
1303 HandleSymbolsDef(SymbolsDef *stmt, struct xkb_keymap *keymap,
1308 InitKeyInfo(&keyi, info->file_id);
1309 CopyKeyInfo(&info->dflt, &keyi, false);
1310 keyi.defs.merge = stmt->merge;
1311 keyi.name = KeyNameToLong(stmt->keyName);
1312 if (!HandleSymbolsBody((VarDef *) stmt->symbols, keymap, &keyi, info)) {
1317 if (!SetExplicitGroup(info, &keyi)) {
1322 if (!AddKeySymbols(info, &keyi, keymap)) {
1330 HandleModMapDef(ModMapDef *def, struct xkb_keymap *keymap, SymbolsInfo *info)
1337 if (!LookupModIndex(keymap->ctx, NULL, def->modifier, TypeInt, &rtrn)) {
1338 ERROR("Illegal modifier map definition\n");
1339 ACTION("Ignoring map for non-modifier \"%s\"\n",
1340 xkb_atom_text(keymap->ctx, def->modifier));
1344 tmp.modifier = rtrn.uval;
1345 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) {
1346 if ((key->op == ExprValue) && (key->type == TypeKeyName)) {
1347 tmp.haveSymbol = false;
1348 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1350 else if (ExprResolveKeySym(keymap->ctx, key, &rtrn)) {
1351 tmp.haveSymbol = true;
1352 tmp.u.keySym = rtrn.uval;
1355 ERROR("Modmap entries may contain only key names or keysyms\n");
1356 ACTION("Illegal definition for %s modifier ignored\n",
1357 XkbcModIndexText(tmp.modifier));
1361 ok = AddModMapEntry(info, &tmp) && ok;
1367 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
1368 enum merge_mode merge, SymbolsInfo *info)
1373 info->name = uDupString(file->name);
1377 switch (stmt->stmtType) {
1379 if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info))
1382 case StmtSymbolsDef:
1383 if (!HandleSymbolsDef((SymbolsDef *) stmt, keymap, info))
1387 if (!HandleSymbolsVar((VarDef *) stmt, keymap, info))
1391 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
1395 ERROR("Interpretation files may not include other types\n");
1396 ACTION("Ignoring definition of symbol interpretation\n");
1399 case StmtKeycodeDef:
1400 ERROR("Interpretation files may not include other types\n");
1401 ACTION("Ignoring definition of key name\n");
1405 if (!HandleModMapDef((ModMapDef *) stmt, keymap, info))
1409 WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1414 if (info->errorCount > 10) {
1416 ERROR("Too many errors\n");
1418 ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1425 * Given a keysym @sym, find the keycode which generates it
1426 * (returned in @kc_rtrn). This is used for example in a modifier
1427 * map definition, such as:
1428 * modifier_map Lock { Caps_Lock };
1429 * where we want to add the Lock modifier to the modmap of the key
1430 * which matches the keysym Caps_Lock.
1431 * Since there can be many keys which generates the keysym, the key
1432 * is chosen first by lowest group in which the keysym appears, than
1433 * by lowest level and than by lowest key code.
1436 FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
1437 xkb_keycode_t *kc_rtrn)
1440 struct xkb_key *key;
1441 unsigned int group, level, min_group = UINT_MAX, min_level = UINT_MAX;
1443 for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
1444 key = XkbKey(keymap, kc);
1446 for (group = 0; group < key->num_groups; group++) {
1447 for (level = 0; level < XkbKeyGroupWidth(keymap, kc, group);
1449 if (XkbKeyNumSyms(keymap, kc, group, level) != 1 ||
1450 (XkbKeySymEntry(keymap, kc, group, level))[0] != sym)
1454 * If the keysym was found in a group or level > 0, we must
1455 * keep looking since we might find a key in which the keysym
1456 * is in a lower group or level.
1458 if (group < min_group ||
1459 (group == min_group && level < min_level)) {
1461 if (group == 0 && level == 0) {
1473 return min_group != UINT_MAX;
1477 * Find the given name in the keymap->map->types and return its index.
1479 * @param atom The atom to search for.
1480 * @param type_rtrn Set to the index of the name if found.
1482 * @return true if found, false otherwise.
1485 FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn)
1488 const char *name = xkb_atom_text(keymap->ctx, atom);
1489 struct xkb_key_type *type;
1492 darray_foreach(type, keymap->types) {
1493 if (strcmp(type->name, name) == 0) {
1504 * Assign a type to the given sym and return the Atom for the type assigned.
1507 * - ONE_LEVEL for width 0/1
1508 * - ALPHABETIC for 2 shift levels, with lower/upercase
1509 * - KEYPAD for keypad keys.
1510 * - TWO_LEVEL for other 2 shift level keys.
1511 * and the same for four level keys.
1513 * @param width Number of sysms in syms.
1514 * @param syms The keysyms for the given key (must be size width).
1515 * @param typeNameRtrn Set to the Atom of the type name.
1517 * @returns true if a type could be found, false otherwise.
1519 * FIXME: I need to take the KeyInfo so I can look at symsMapIndex and
1520 * all that fun stuff rather than just assuming there's always one
1524 FindAutomaticType(struct xkb_keymap *keymap, int width,
1525 const xkb_keysym_t *syms, xkb_atom_t *typeNameRtrn,
1529 if ((width == 1) || (width == 0)) {
1530 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
1533 else if (width == 2) {
1534 if (syms && xkb_keysym_is_lower(syms[0]) &&
1535 xkb_keysym_is_upper(syms[1])) {
1536 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
1538 else if (syms && (xkb_keysym_is_keypad(syms[0]) ||
1539 xkb_keysym_is_keypad(syms[1]))) {
1540 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "KEYPAD");
1544 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
1548 else if (width <= 4) {
1549 if (syms && xkb_keysym_is_lower(syms[0]) &&
1550 xkb_keysym_is_upper(syms[1]))
1551 if (xkb_keysym_is_lower(syms[2]) && xkb_keysym_is_upper(syms[3]))
1553 xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_ALPHABETIC");
1555 *typeNameRtrn = xkb_atom_intern(keymap->ctx,
1556 "FOUR_LEVEL_SEMIALPHABETIC");
1558 else if (syms && (xkb_keysym_is_keypad(syms[0]) ||
1559 xkb_keysym_is_keypad(syms[1])))
1560 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_KEYPAD");
1562 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL");
1563 /* XXX: why not set autoType here? */
1565 return ((width >= 0) && (width <= 4));
1569 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1570 * groups, and reduce to one group if all groups are identical anyway.
1573 PrepareKeyDef(KeyInfo *keyi)
1575 int i, j, width, defined, lastGroup;
1578 defined = keyi->symsDefined | keyi->actsDefined | keyi->typesDefined;
1579 /* get highest group number */
1580 for (i = XkbNumKbdGroups - 1; i >= 0; i--) {
1581 if (defined & (1 << i))
1589 /* If there are empty groups between non-empty ones fill them with data */
1590 /* from the first group. */
1591 /* We can make a wrong assumption here. But leaving gaps is worse. */
1592 for (i = lastGroup; i > 0; i--) {
1593 if (defined & (1 << i))
1595 width = keyi->numLevels[0];
1596 if (keyi->typesDefined & 1) {
1597 for (j = 0; j < width; j++) {
1598 keyi->types[i] = keyi->types[0];
1600 keyi->typesDefined |= 1 << i;
1602 if ((keyi->actsDefined & 1) && !darray_empty(keyi->acts[0])) {
1603 darray_copy(keyi->acts[i], keyi->acts[0]);
1604 keyi->actsDefined |= 1 << i;
1606 if ((keyi->symsDefined & 1) && !darray_empty(keyi->syms[0])) {
1607 darray_copy(keyi->syms[i], keyi->syms[0]);
1608 darray_copy(keyi->symsMapIndex[i], keyi->symsMapIndex[0]);
1609 darray_copy(keyi->symsMapNumEntries[i],
1610 keyi->symsMapNumEntries[0]);
1611 keyi->symsDefined |= 1 << i;
1614 keyi->numLevels[i] = keyi->numLevels[0];
1617 /* If all groups are completely identical remove them all */
1618 /* exept the first one. */
1620 for (i = lastGroup; i > 0; i--) {
1621 if ((keyi->numLevels[i] != keyi->numLevels[0]) ||
1622 (keyi->types[i] != keyi->types[0])) {
1626 if (!darray_same(keyi->syms[i], keyi->syms[0]) &&
1627 (darray_empty(keyi->syms[i]) || darray_empty(keyi->syms[0]) ||
1628 darray_size(keyi->syms[i]) != darray_size(keyi->syms[0]) ||
1629 memcmp(darray_mem(keyi->syms[i], 0),
1630 darray_mem(keyi->syms[0], 0),
1631 sizeof(xkb_keysym_t) * darray_size(keyi->syms[0])))) {
1635 if (!darray_same(keyi->symsMapIndex[i], keyi->symsMapIndex[0]) &&
1636 (darray_empty(keyi->symsMapIndex[i]) ||
1637 darray_empty(keyi->symsMapIndex[0]) ||
1638 memcmp(darray_mem(keyi->symsMapIndex[i], 0),
1639 darray_mem(keyi->symsMapIndex[0], 0),
1640 keyi->numLevels[0] * sizeof(int)))) {
1644 if (!darray_same(keyi->symsMapNumEntries[i],
1645 keyi->symsMapNumEntries[0]) &&
1646 (darray_empty(keyi->symsMapNumEntries[i]) ||
1647 darray_empty(keyi->symsMapNumEntries[0]) ||
1648 memcmp(darray_mem(keyi->symsMapNumEntries[i], 0),
1649 darray_mem(keyi->symsMapNumEntries[0], 0),
1650 keyi->numLevels[0] * sizeof(size_t)))) {
1654 if (!darray_same(keyi->acts[i], keyi->acts[0]) &&
1655 (darray_empty(keyi->acts[i]) || darray_empty(keyi->acts[0]) ||
1656 memcmp(darray_mem(keyi->acts[i], 0),
1657 darray_mem(keyi->acts[0], 0),
1658 keyi->numLevels[0] * sizeof(union xkb_action)))) {
1664 for (i = lastGroup; i > 0; i--) {
1665 keyi->numLevels[i] = 0;
1666 darray_free(keyi->syms[i]);
1667 darray_free(keyi->symsMapIndex[i]);
1668 darray_free(keyi->symsMapNumEntries[i]);
1669 darray_free(keyi->acts[i]);
1672 keyi->symsDefined &= 1;
1673 keyi->actsDefined &= 1;
1674 keyi->typesDefined &= 1;
1679 * Copy the KeyInfo into the keyboard description.
1681 * This function recurses.
1684 CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *keyi, int start_from)
1688 struct xkb_key *key;
1689 unsigned int sizeSyms = 0;
1690 unsigned width, tmp, nGroups;
1691 struct xkb_key_type * type;
1692 bool haveActions, autoType, useAlias;
1693 unsigned types[XkbNumKbdGroups];
1694 union xkb_action *outActs;
1695 unsigned int symIndex = 0;
1697 useAlias = (start_from == 0);
1699 /* get the keycode for the key. */
1700 if (!FindNamedKey(keymap, keyi->name, &kc, useAlias,
1701 CreateKeyNames(keymap), start_from)) {
1702 if ((start_from == 0) && (warningLevel >= 5)) {
1703 WARN("Key %s not found in keycodes\n", longText(keyi->name));
1704 ACTION("Symbols ignored\n");
1709 key = XkbKey(keymap, kc);
1711 haveActions = false;
1712 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++) {
1713 if (((i + 1) > nGroups)
1714 && (((keyi->symsDefined | keyi->actsDefined) & (1 << i))
1715 || (keyi->typesDefined) & (1 << i)))
1717 if (!darray_empty(keyi->acts[i]))
1720 /* Assign the type to the key, if it is missing. */
1721 if (keyi->types[i] == XKB_ATOM_NONE) {
1722 if (keyi->dfltType != XKB_ATOM_NONE)
1723 keyi->types[i] = keyi->dfltType;
1724 else if (FindAutomaticType(keymap, keyi->numLevels[i],
1725 darray_mem(keyi->syms[i], 0),
1726 &keyi->types[i], &autoType)) { }
1728 if (warningLevel >= 5) {
1729 WARN("No automatic type for %d symbols\n",
1730 (unsigned int) keyi->numLevels[i]);
1731 ACTION("Using %s for the %s key (keycode %d)\n",
1732 xkb_atom_text(keymap->ctx, keyi->types[i]),
1733 longText(keyi->name), kc);
1737 if (FindNamedType(keymap, keyi->types[i], &types[i])) {
1738 if (!autoType || keyi->numLevels[i] > 2)
1739 key->explicit |= (1 << i);
1742 if (warningLevel >= 3) {
1743 WARN("Type \"%s\" is not defined\n",
1744 xkb_atom_text(keymap->ctx, keyi->types[i]));
1745 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
1746 longText(keyi->name), kc);
1748 types[i] = XkbTwoLevelIndex;
1750 /* if the type specifies fewer levels than the key has, shrink the key */
1751 type = &darray_item(keymap->types, types[i]);
1752 if (type->num_levels < keyi->numLevels[i]) {
1753 if (warningLevel > 0) {
1754 WARN("Type \"%s\" has %d levels, but %s has %d symbols\n",
1755 type->name, type->num_levels,
1756 xkb_atom_text(keymap->ctx, keyi->name), keyi->numLevels[i]);
1757 ACTION("Ignoring extra symbols\n");
1759 keyi->numLevels[i] = type->num_levels;
1761 if (keyi->numLevels[i] > width)
1762 width = keyi->numLevels[i];
1763 if (type->num_levels > width)
1764 width = type->num_levels;
1765 sizeSyms += darray_size(keyi->syms[i]);
1768 darray_resize0(key->syms, sizeSyms);
1771 outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups);
1772 if (outActs == NULL) {
1773 WSGO("Could not enlarge actions for %s (key %d)\n",
1774 longText(keyi->name), kc);
1777 key->explicit |= XkbExplicitInterpretMask;
1782 key->num_groups = nGroups;
1783 if (keyi->defs.defined & _Key_GroupInfo) {
1784 key->out_of_range_group_number = keyi->out_of_range_group_number;
1785 key->out_of_range_group_action = keyi->out_of_range_group_action;
1788 key->sym_index = calloc(nGroups * width, sizeof(*key->sym_index));
1789 key->num_syms = calloc(nGroups * width, sizeof(*key->num_syms));
1791 for (i = 0; i < nGroups; i++) {
1792 /* assign kt_index[i] to the index of the type in map->types.
1793 * kt_index[i] may have been set by a previous run (if we have two
1794 * layouts specified). Let's not overwrite it with the ONE_LEVEL
1795 * default group if we dont even have keys for this group anyway.
1797 * FIXME: There should be a better fix for this.
1799 if (keyi->numLevels[i])
1800 key->kt_index[i] = types[i];
1801 if (!darray_empty(keyi->syms[i])) {
1802 /* fill key to "width" symbols*/
1803 for (tmp = 0; tmp < width; tmp++) {
1804 if (tmp < keyi->numLevels[i] &&
1805 darray_item(keyi->symsMapNumEntries[i], tmp) != 0) {
1806 memcpy(darray_mem(key->syms, symIndex),
1807 darray_mem(keyi->syms[i],
1808 darray_item(keyi->symsMapIndex[i], tmp)),
1809 darray_item(keyi->symsMapNumEntries[i],
1810 tmp) * sizeof(xkb_keysym_t));
1811 key->sym_index[(i * width) + tmp] = symIndex;
1812 key->num_syms[(i * width) + tmp] =
1813 darray_item(keyi->symsMapNumEntries[i], tmp);
1814 symIndex += key->num_syms[(i * width) + tmp];
1817 key->sym_index[(i * width) + tmp] = -1;
1818 key->num_syms[(i * width) + tmp] = 0;
1820 if (outActs != NULL && !darray_empty(keyi->acts[i])) {
1821 if (tmp < keyi->numLevels[i])
1822 outActs[tmp] = darray_item(keyi->acts[i], tmp);
1824 outActs[tmp].type = XkbSA_NoAction;
1829 switch (keyi->behavior.type & XkbKB_OpMask) {
1834 key->behavior = keyi->behavior;
1835 key->explicit |= XkbExplicitBehaviorMask;
1838 if (keyi->defs.defined & _Key_VModMap) {
1839 key->vmodmap = keyi->vmodmap;
1840 key->explicit |= XkbExplicitVModMapMask;
1842 if (keyi->repeat != RepeatUndefined) {
1843 key->repeats = keyi->repeat == RepeatYes;
1844 key->explicit |= XkbExplicitAutoRepeatMask;
1847 /* do the same thing for the next key */
1848 CopySymbolsDef(keymap, keyi, kc + 1);
1853 CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry)
1857 if (!entry->haveSymbol &&
1858 !FindNamedKey(keymap, entry->u.keyName, &kc, true,
1859 CreateKeyNames(keymap), 0)) {
1860 if (warningLevel >= 5) {
1861 WARN("Key %s not found in keycodes\n",
1862 longText(entry->u.keyName));
1863 ACTION("Modifier map entry for %s not updated\n",
1864 XkbcModIndexText(entry->modifier));
1868 else if (entry->haveSymbol &&
1869 !FindKeyForSymbol(keymap, entry->u.keySym, &kc)) {
1870 if (warningLevel > 5) {
1871 WARN("Key \"%s\" not found in symbol map\n",
1872 XkbcKeysymText(entry->u.keySym));
1873 ACTION("Modifier map entry for %s not updated\n",
1874 XkbcModIndexText(entry->modifier));
1879 XkbKey(keymap, kc)->modmap |= (1 << entry->modifier);
1884 * Handle the xkb_symbols section of an xkb file.
1886 * @param file The parsed xkb_symbols section of the xkb file.
1887 * @param keymap Handle to the keyboard description to store the symbols in.
1888 * @param merge Merge strategy (e.g. MERGE_OVERRIDE).
1891 CompileSymbols(XkbFile *file, struct xkb_keymap *keymap,
1892 enum merge_mode merge)
1896 struct xkb_key *key;
1900 InitSymbolsInfo(&info, keymap, file->id);
1901 info.dflt.defs.merge = merge;
1903 HandleSymbolsFile(file, keymap, merge, &info);
1905 if (darray_empty(info.keys))
1908 if (info.errorCount != 0)
1911 darray_resize0(keymap->acts, darray_size(keymap->acts) + 32 + 1);
1914 keymap->symbols_section_name = strdup(info.name);
1916 /* now copy info into xkb. */
1917 ApplyAliases(keymap, &info.aliases);
1919 for (i = 0; i < XkbNumKbdGroups; i++) {
1920 if (info.groupNames[i] != XKB_ATOM_NONE) {
1921 free(keymap->group_names[i]);
1922 keymap->group_names[i] = xkb_atom_strdup(keymap->ctx,
1923 info.groupNames[i]);
1928 darray_foreach(keyi, info.keys)
1929 PrepareKeyDef(keyi);
1932 darray_foreach(keyi, info.keys)
1933 if (!CopySymbolsDef(keymap, keyi, 0))
1936 if (warningLevel > 3) {
1937 for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
1938 key = XkbKey(keymap, kc);
1939 if (key->name[0] == '\0')
1942 if (key->num_groups < 1)
1943 WARN("No symbols defined for <%.4s> (keycode %d)\n",
1949 ModMapEntry *mm, *next;
1950 for (mm = info.modMap; mm != NULL; mm = next) {
1951 if (!CopyModMapDef(keymap, mm))
1953 next = (ModMapEntry *) mm->defs.next;
1957 FreeSymbolsInfo(&info);
1961 FreeSymbolsInfo(&info);