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
58 unsigned long name; /* the 4 chars of the key name, as long */
59 unsigned char groupInfo;
60 unsigned char typesDefined;
61 unsigned char symsDefined;
62 unsigned char actsDefined;
63 unsigned int numLevels[XkbNumKbdGroups];
65 /* syms[group] -> Single array for all the keysyms in the group. */
66 darray_xkb_keysym_t syms[XkbNumKbdGroups];
68 * symsMapIndex[group][level] -> The index from which the syms for
69 * the level begin in the syms[group] array. Remember each keycode
70 * can have multiple keysyms in each level (that is, each key press
71 * can result in multiple keysyms).
73 darray(int) symsMapIndex[XkbNumKbdGroups];
75 * symsMapNumEntries[group][level] -> How many syms are in
76 * syms[group][symsMapIndex[group][level]].
78 darray(size_t) symsMapNumEntries[XkbNumKbdGroups];
80 darray_xkb_action acts[XkbNumKbdGroups];
82 xkb_atom_t types[XkbNumKbdGroups];
84 struct xkb_behavior behavior;
85 unsigned short vmodmap;
90 * Init the given key info to sane values.
93 InitKeyInfo(KeyInfo * info, unsigned file_id)
96 static const char dflt[4] = "*";
98 info->defs.defined = 0;
99 info->defs.file_id = file_id;
100 info->defs.merge = MERGE_OVERRIDE;
101 info->defs.next = NULL;
102 info->name = KeyNameToLong(dflt);
104 info->typesDefined = info->symsDefined = info->actsDefined = 0;
105 for (i = 0; i < XkbNumKbdGroups; i++)
107 info->numLevels[i] = 0;
108 info->types[i] = XKB_ATOM_NONE;
109 darray_init(info->syms[i]);
110 darray_init(info->symsMapIndex[i]);
111 darray_init(info->symsMapNumEntries[i]);
112 darray_init(info->acts[i]);
114 info->dfltType = XKB_ATOM_NONE;
115 info->behavior.type = XkbKB_Default;
116 info->behavior.data = 0;
118 info->repeat = RepeatUndefined;
122 * Free memory associated with this key info and reset to sane values.
125 FreeKeyInfo(KeyInfo * info)
129 info->defs.defined = 0;
130 info->defs.file_id = 0;
131 info->defs.merge = MERGE_OVERRIDE;
132 info->defs.next = NULL;
134 info->typesDefined = info->symsDefined = info->actsDefined = 0;
135 for (i = 0; i < XkbNumKbdGroups; i++)
137 info->numLevels[i] = 0;
138 info->types[i] = XKB_ATOM_NONE;
139 darray_free(info->syms[i]);
140 darray_free(info->symsMapIndex[i]);
141 darray_free(info->symsMapNumEntries[i]);
142 darray_free(info->acts[i]);
144 info->dfltType = XKB_ATOM_NONE;
145 info->behavior.type = XkbKB_Default;
146 info->behavior.data = 0;
148 info->repeat = RepeatUndefined;
152 * Copy old into new, optionally reset old to 0.
153 * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
154 * newly allocated and new points to the new memory areas.
157 CopyKeyInfo(KeyInfo * old, KeyInfo * new, bool clearOld)
162 new->defs.next = NULL;
165 for (i = 0; i < XkbNumKbdGroups; i++) {
166 old->numLevels[i] = 0;
167 darray_init(old->symsMapIndex[i]);
168 darray_init(old->symsMapNumEntries[i]);
169 darray_init(old->syms[i]);
170 darray_init(old->acts[i]);
174 for (i = 0; i < XkbNumKbdGroups; i++) {
175 darray_copy(new->syms[i], old->syms[i]);
176 darray_copy(new->symsMapIndex[i], old->symsMapIndex[i]);
177 darray_copy(new->symsMapNumEntries[i], old->symsMapNumEntries[i]);
178 darray_copy(new->acts[i], old->acts[i]);
185 /***====================================================================***/
187 typedef struct _ModMapEntry
194 unsigned long keyName;
199 typedef struct _SymbolsInfo
201 char *name; /* e.g. pc+us+inet(evdev) */
204 enum merge_mode merge;
205 unsigned explicit_group;
206 darray(KeyInfo) keys;
210 xkb_atom_t groupNames[XkbNumKbdGroups];
217 InitSymbolsInfo(SymbolsInfo * info, struct xkb_keymap *keymap,
223 info->explicit_group = 0;
224 info->errorCount = 0;
225 info->file_id = file_id;
226 info->merge = MERGE_OVERRIDE;
227 darray_init(info->keys);
228 darray_growalloc(info->keys, 110);
230 for (i = 0; i < XkbNumKbdGroups; i++)
231 info->groupNames[i] = XKB_ATOM_NONE;
232 InitKeyInfo(&info->dflt, file_id);
233 InitVModInfo(&info->vmods, keymap);
235 info->aliases = NULL;
239 FreeSymbolsInfo(SymbolsInfo * info)
244 darray_foreach(key, info->keys)
246 darray_free(info->keys);
248 ClearCommonInfo(&info->modMap->defs);
250 ClearAliases(&info->aliases);
251 memset(info, 0, sizeof(SymbolsInfo));
255 ResizeKeyGroup(KeyInfo * key, unsigned int group, unsigned int numLevels,
256 unsigned sizeSyms, bool forceActions)
260 if (darray_size(key->syms[group]) < sizeSyms)
261 darray_resize0(key->syms[group], sizeSyms);
263 if (darray_empty(key->symsMapIndex[group]) ||
264 key->numLevels[group] < numLevels) {
265 darray_resize(key->symsMapIndex[group], numLevels);
266 for (i = key->numLevels[group]; i < numLevels; i++)
267 darray_item(key->symsMapIndex[group], i) = -1;
270 if (darray_empty(key->symsMapNumEntries[group]) ||
271 key->numLevels[group] < numLevels)
272 darray_resize0(key->symsMapNumEntries[group], numLevels);
274 if ((forceActions && (key->numLevels[group] < numLevels ||
275 darray_empty(key->acts[group]))) ||
276 (key->numLevels[group] < numLevels && !darray_empty(key->acts[group])))
277 darray_resize0(key->acts[group], numLevels);
279 if (key->numLevels[group] < numLevels)
280 key->numLevels[group] = numLevels;
285 enum key_group_selector {
292 MergeKeyGroups(SymbolsInfo * info,
293 KeyInfo * into, KeyInfo * from, unsigned group)
295 darray_xkb_keysym_t resultSyms;
296 enum key_group_selector using = NONE;
297 darray_xkb_action resultActs;
298 unsigned int resultWidth;
299 unsigned int resultSize = 0;
302 bool report, clobber;
304 clobber = (from->defs.merge != MERGE_AUGMENT);
306 report = (warningLevel > 9) ||
307 ((into->defs.file_id == from->defs.file_id) && (warningLevel > 0));
309 darray_init(resultSyms);
311 if (into->numLevels[group] >= from->numLevels[group])
313 resultActs = into->acts[group];
314 resultWidth = into->numLevels[group];
318 resultActs = from->acts[group];
319 resultWidth = from->numLevels[group];
320 darray_resize(into->symsMapIndex[group],
321 from->numLevels[group]);
322 darray_resize0(into->symsMapNumEntries[group],
323 from->numLevels[group]);
325 for (i = into->numLevels[group]; i < from->numLevels[group]; i++)
326 darray_item(into->symsMapIndex[group], i) = -1;
329 if (darray_empty(resultActs) && (!darray_empty(into->acts[group]) ||
330 !darray_empty(from->acts[group])))
332 darray_resize0(resultActs, resultWidth);
333 for (i = 0; i < resultWidth; i++)
335 union xkb_action *fromAct = NULL, *toAct = NULL;
337 if (!darray_empty(from->acts[group]))
338 fromAct = &darray_item(from->acts[group], i);
340 if (!darray_empty(into->acts[group]))
341 toAct = &darray_item(into->acts[group], i);
343 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
346 darray_item(resultActs, i) = *toAct;
348 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
349 && (fromAct != NULL))
351 darray_item(resultActs, i) = *fromAct;
355 union xkb_action *use, *ignore;
369 ("Multiple actions for level %d/group %d on key %s\n",
370 i + 1, group + 1, longText(into->name));
371 ACTION("Using %s, ignoring %s\n",
372 XkbcActionTypeText(use->type),
373 XkbcActionTypeText(ignore->type));
376 darray_item(resultActs, i) = *use;
381 for (i = 0; i < resultWidth; i++)
383 unsigned int fromSize = 0;
386 if (!darray_empty(from->symsMapNumEntries[group]) &&
387 i < from->numLevels[group])
388 fromSize = darray_item(from->symsMapNumEntries[group], i);
390 if (!darray_empty(into->symsMapNumEntries[group]) &&
391 i < into->numLevels[group])
392 toSize = darray_item(into->symsMapNumEntries[group], i);
396 resultSize += toSize;
399 else if (toSize == 0 || clobber)
401 resultSize += fromSize;
406 resultSize += toSize;
416 resultSyms = from->syms[group];
417 darray_free(into->symsMapNumEntries[group]);
418 darray_free(into->symsMapIndex[group]);
419 into->symsMapNumEntries[group] = from->symsMapNumEntries[group];
420 into->symsMapIndex[group] = from->symsMapIndex[group];
421 darray_init(from->symsMapNumEntries[group]);
422 darray_init(from->symsMapIndex[group]);
425 else if (using == TO)
427 resultSyms = into->syms[group];
431 darray_resize0(resultSyms, resultSize);
433 for (i = 0; i < resultWidth; i++)
435 enum key_group_selector use = NONE;
436 unsigned int fromSize = 0;
437 unsigned int toSize = 0;
439 if (i < from->numLevels[group])
440 fromSize = darray_item(from->symsMapNumEntries[group], i);
442 if (i < into->numLevels[group])
443 toSize = darray_item(into->symsMapNumEntries[group], i);
445 if (fromSize == 0 && toSize == 0)
447 darray_item(into->symsMapIndex[group], i) = -1;
448 darray_item(into->symsMapNumEntries[group], i) = 0;
454 else if (toSize == 0 || clobber)
459 if (toSize && fromSize && report)
461 INFO("Multiple symbols for group %d, level %d on key %s\n",
462 group + 1, i + 1, longText(into->name));
463 ACTION("Using %s, ignoring %s\n",
464 (use == FROM ? "from" : "to"),
465 (use == FROM ? "to" : "from"));
470 memcpy(darray_mem(resultSyms, cur_idx),
471 darray_mem(from->syms[group],
472 darray_item(from->symsMapIndex[group], i)),
473 darray_item(from->symsMapNumEntries[group], i) * sizeof(xkb_keysym_t));
474 darray_item(into->symsMapIndex[group], i) = cur_idx;
475 darray_item(into->symsMapNumEntries[group], i) =
476 darray_item(from->symsMapNumEntries[group], i);
480 memcpy(darray_mem(resultSyms, cur_idx),
481 darray_mem(into->syms[group],
482 darray_item(into->symsMapIndex[group], i)),
483 darray_item(into->symsMapNumEntries[group], i) * sizeof(xkb_keysym_t));
484 darray_item(into->symsMapIndex[group], i) = cur_idx;
486 cur_idx += darray_item(into->symsMapNumEntries[group], i);
490 if (!darray_same(resultActs, into->acts[group]))
491 darray_free(into->acts[group]);
492 if (!darray_same(resultActs, from->acts[group]))
493 darray_free(from->acts[group]);
494 into->numLevels[group] = resultWidth;
495 if (!darray_same(resultSyms, into->syms[group]))
496 darray_free(into->syms[group]);
497 into->syms[group] = resultSyms;
498 if (!darray_same(resultSyms, from->syms[group]))
499 darray_free(from->syms[group]);
500 darray_init(from->syms[group]);
501 darray_free(from->symsMapIndex[group]);
502 darray_free(from->symsMapNumEntries[group]);
503 into->acts[group] = resultActs;
504 darray_init(from->acts[group]);
505 if (!darray_empty(into->syms[group]))
506 into->symsDefined |= (1 << group);
507 from->symsDefined &= ~(1 << group);
508 into->actsDefined |= (1 << group);
509 from->actsDefined &= ~(1 << group);
515 MergeKeys(SymbolsInfo *info, struct xkb_keymap *keymap,
516 KeyInfo *into, KeyInfo *from)
519 unsigned collide = 0;
522 if (from->defs.merge == MERGE_REPLACE)
524 for (i = 0; i < XkbNumKbdGroups; i++)
526 if (into->numLevels[i] != 0)
528 darray_free(into->syms[i]);
529 darray_free(into->acts[i]);
533 memset(from, 0, sizeof(KeyInfo));
536 report = ((warningLevel > 9) ||
537 ((into->defs.file_id == from->defs.file_id)
538 && (warningLevel > 0)));
539 for (i = 0; i < XkbNumKbdGroups; i++)
541 if (from->numLevels[i] > 0)
543 if (into->numLevels[i] == 0)
545 into->numLevels[i] = from->numLevels[i];
546 into->syms[i] = from->syms[i];
547 into->symsMapIndex[i] = from->symsMapIndex[i];
548 into->symsMapNumEntries[i] = from->symsMapNumEntries[i];
549 into->acts[i] = from->acts[i];
550 into->symsDefined |= (1 << i);
551 darray_init(from->syms[i]);
552 darray_init(from->symsMapIndex[i]);
553 darray_init(from->symsMapNumEntries[i]);
554 darray_init(from->acts[i]);
555 from->numLevels[i] = 0;
556 from->symsDefined &= ~(1 << i);
557 if (!darray_empty(into->syms[i]))
558 into->defs.defined |= _Key_Syms;
559 if (!darray_empty(into->acts[i]))
560 into->defs.defined |= _Key_Acts;
566 if (!darray_empty(into->syms[i]))
567 collide |= _Key_Syms;
568 if (!darray_empty(into->acts[i]))
569 collide |= _Key_Acts;
571 MergeKeyGroups(info, into, from, (unsigned) i);
574 if (from->types[i] != XKB_ATOM_NONE)
576 if ((into->types[i] != XKB_ATOM_NONE) && report &&
577 (into->types[i] != from->types[i]))
579 xkb_atom_t use, ignore;
580 collide |= _Key_Types;
581 if (from->defs.merge != MERGE_AUGMENT)
583 use = from->types[i];
584 ignore = into->types[i];
588 use = into->types[i];
589 ignore = from->types[i];
592 ("Multiple definitions for group %d type of key %s\n",
593 i, longText(into->name));
594 ACTION("Using %s, ignoring %s\n",
595 xkb_atom_text(keymap->ctx, use),
596 xkb_atom_text(keymap->ctx, ignore));
598 if ((from->defs.merge != MERGE_AUGMENT)
599 || (into->types[i] == XKB_ATOM_NONE))
601 into->types[i] = from->types[i];
605 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
607 into->behavior = from->behavior;
608 into->defs.defined |= _Key_Behavior;
610 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
612 into->vmodmap = from->vmodmap;
613 into->defs.defined |= _Key_VModMap;
615 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
617 into->repeat = from->repeat;
618 into->defs.defined |= _Key_Repeat;
620 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
622 into->dfltType = from->dfltType;
623 into->defs.defined |= _Key_Type_Dflt;
625 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
627 into->groupInfo = from->groupInfo;
628 into->defs.defined |= _Key_GroupInfo;
632 WARN("Symbol map for key %s redefined\n",
633 longText(into->name));
634 ACTION("Using %s definition for conflicting fields\n",
635 (from->defs.merge == MERGE_AUGMENT ? "first" : "last"));
641 AddKeySymbols(SymbolsInfo *info, KeyInfo *key, struct xkb_keymap *keymap)
643 unsigned long real_name;
646 darray_foreach(iter, info->keys)
647 if (iter->name == key->name)
648 return MergeKeys(info, keymap, iter, key);
650 if (FindKeyNameForAlias(keymap, key->name, &real_name))
651 darray_foreach(iter, info->keys)
652 if (iter->name == real_name)
653 return MergeKeys(info, keymap, iter, key);
655 darray_resize0(info->keys, darray_size(info->keys) + 1);
656 new = &darray_item(info->keys, darray_size(info->keys) - 1);
657 return CopyKeyInfo(key, new, true);
661 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
666 clobber = (new->defs.merge != MERGE_AUGMENT);
667 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
669 if (new->haveSymbol && mm->haveSymbol
670 && (new->u.keySym == mm->u.keySym))
672 unsigned use, ignore;
673 if (mm->modifier != new->modifier)
678 ignore = mm->modifier;
683 ignore = new->modifier;
686 ("%s added to symbol map for multiple modifiers\n",
687 XkbcKeysymText(new->u.keySym));
688 ACTION("Using %s, ignoring %s.\n",
689 XkbcModIndexText(use),
690 XkbcModIndexText(ignore));
695 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
696 (new->u.keyName == mm->u.keyName))
698 unsigned use, ignore;
699 if (mm->modifier != new->modifier)
704 ignore = mm->modifier;
709 ignore = new->modifier;
711 ERROR("Key %s added to map for multiple modifiers\n",
712 longText(new->u.keyName));
713 ACTION("Using %s, ignoring %s.\n",
714 XkbcModIndexText(use),
715 XkbcModIndexText(ignore));
721 mm = uTypedAlloc(ModMapEntry);
724 WSGO("Could not allocate modifier map entry\n");
725 ACTION("Modifier map for %s will be incomplete\n",
726 XkbcModIndexText(new->modifier));
730 mm->defs.next = &info->modMap->defs;
735 /***====================================================================***/
738 MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
739 enum merge_mode merge, struct xkb_keymap *keymap)
744 if (from->errorCount > 0)
746 into->errorCount += from->errorCount;
749 if (into->name == NULL)
751 into->name = from->name;
754 for (i = 0; i < XkbNumKbdGroups; i++)
756 if (from->groupNames[i] != XKB_ATOM_NONE)
758 if ((merge != MERGE_AUGMENT) ||
759 (into->groupNames[i] == XKB_ATOM_NONE))
760 into->groupNames[i] = from->groupNames[i];
764 darray_foreach(key, from->keys) {
765 if (merge != MERGE_DEFAULT)
766 key->defs.merge = merge;
768 if (!AddKeySymbols(into, key, keymap))
772 if (from->modMap != NULL)
774 ModMapEntry *mm, *next;
775 for (mm = from->modMap; mm != NULL; mm = next)
777 if (merge != MERGE_DEFAULT)
778 mm->defs.merge = merge;
779 if (!AddModMapEntry(into, mm))
781 next = (ModMapEntry *) mm->defs.next;
786 if (!MergeAliases(&into->aliases, &from->aliases, merge))
791 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
792 enum merge_mode merge, SymbolsInfo *info);
795 HandleIncludeSymbols(IncludeStmt *stmt, struct xkb_keymap *keymap,
800 SymbolsInfo included;
804 if ((stmt->file == NULL) && (stmt->map == NULL))
808 memset(info, 0, sizeof(SymbolsInfo));
810 else if (ProcessIncludeFile(keymap->ctx, stmt, FILE_TYPE_SYMBOLS, &rtrn,
813 InitSymbolsInfo(&included, keymap, rtrn->id);
814 included.merge = included.dflt.defs.merge = MERGE_OVERRIDE;
817 included.explicit_group = atoi(stmt->modifier) - 1;
821 included.explicit_group = info->explicit_group;
823 HandleSymbolsFile(rtrn, keymap, MERGE_OVERRIDE, &included);
824 if (stmt->stmt != NULL)
827 included.name = stmt->stmt;
834 info->errorCount += 10;
837 if ((stmt->next != NULL) && (included.errorCount < 1))
841 SymbolsInfo next_incl;
843 for (next = stmt->next; next != NULL; next = next->next)
845 if ((next->file == NULL) && (next->map == NULL))
848 MergeIncludedSymbols(&included, info, next->merge, keymap);
849 FreeSymbolsInfo(info);
851 else if (ProcessIncludeFile(keymap->ctx, next, FILE_TYPE_SYMBOLS,
854 InitSymbolsInfo(&next_incl, keymap, rtrn->id);
855 next_incl.merge = next_incl.dflt.defs.merge = MERGE_OVERRIDE;
858 next_incl.explicit_group = atoi(next->modifier) - 1;
862 next_incl.explicit_group = info->explicit_group;
864 HandleSymbolsFile(rtrn, keymap, MERGE_OVERRIDE, &next_incl);
865 MergeIncludedSymbols(&included, &next_incl, op, keymap);
866 FreeSymbolsInfo(&next_incl);
871 info->errorCount += 10;
872 FreeSymbolsInfo(&included);
879 info->errorCount += included.errorCount;
885 MergeIncludedSymbols(info, &included, newMerge, keymap);
886 FreeSymbolsInfo(&included);
888 return (info->errorCount == 0);
895 GetGroupIndex(KeyInfo *key, struct xkb_keymap *keymap,
896 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
906 if (arrayNdx == NULL)
911 defined = key->symsDefined;
913 defined = key->actsDefined;
915 for (i = 0; i < XkbNumKbdGroups; i++)
917 if ((defined & (1 << i)) == 0)
923 ERROR("Too many groups of %s for key %s (max %d)\n", name,
924 longText(key->name), XkbNumKbdGroups + 1);
925 ACTION("Ignoring %s defined for extra groups\n", name);
928 if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp))
930 ERROR("Illegal group index for %s of key %s\n", name,
931 longText(key->name));
932 ACTION("Definition with non-integer array index ignored\n");
935 *ndx_rtrn = tmp.uval - 1;
940 AddSymbolsToKey(KeyInfo *key, struct xkb_keymap *keymap,
941 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
943 unsigned ndx, nSyms, nLevels;
947 if (!GetGroupIndex(key, keymap, arrayNdx, SYMBOLS, &ndx))
951 key->symsDefined |= (1 << ndx);
954 if (value->op != ExprKeysymList)
956 ERROR("Expected a list of symbols, found %s\n", exprOpText(value->op));
957 ACTION("Ignoring symbols for group %d of %s\n", ndx + 1,
958 longText(key->name));
961 if (!darray_empty(key->syms[ndx]))
963 ERROR("Symbols for key %s, group %d already defined\n",
964 longText(key->name), ndx + 1);
965 ACTION("Ignoring duplicate definition\n");
968 nSyms = darray_size(value->value.list.syms);
969 nLevels = darray_size(value->value.list.symsMapIndex);
970 if ((key->numLevels[ndx] < nSyms || darray_empty(key->syms[ndx])) &&
971 (!ResizeKeyGroup(key, ndx, nLevels, nSyms, false)))
973 WSGO("Could not resize group %d of key %s to contain %d levels\n",
974 ndx + 1, longText(key->name), nSyms);
975 ACTION("Symbols lost\n");
978 key->symsDefined |= (1 << ndx);
979 for (i = 0; i < nLevels; i++) {
980 darray_item(key->symsMapIndex[ndx], i) =
981 darray_item(value->value.list.symsMapIndex, i);
982 darray_item(key->symsMapNumEntries[ndx], i) =
983 darray_item(value->value.list.symsNumEntries, i);
985 for (j = 0; j < darray_item(key->symsMapNumEntries[ndx], i); j++) {
986 /* FIXME: What's abort() doing here? */
987 if (darray_item(key->symsMapIndex[ndx], i) + j >= nSyms)
989 if (!LookupKeysym(darray_item(value->value.list.syms,
990 darray_item(value->value.list.symsMapIndex, i) + j),
991 &darray_item(key->syms[ndx],
992 darray_item(key->symsMapIndex[ndx], i) + j))) {
993 WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
994 darray_item(value->value.list.syms, i),
997 xkb_atom_text(keymap->ctx, info->groupNames[ndx]), nSyms);
999 darray_item(key->syms[ndx],
1000 darray_item(key->symsMapIndex[ndx], i) + j) = XKB_KEY_NoSymbol;
1001 darray_item(key->symsMapIndex[ndx], i) = -1;
1002 darray_item(key->symsMapNumEntries[ndx], i) = 0;
1005 if (darray_item(key->symsMapNumEntries[ndx], i) == 1 &&
1006 darray_item(key->syms[ndx],
1007 darray_item(key->symsMapIndex[ndx], i) + j) == XKB_KEY_NoSymbol) {
1008 darray_item(key->symsMapIndex[ndx], i) = -1;
1009 darray_item(key->symsMapNumEntries[ndx], i) = 0;
1013 for (j = key->numLevels[ndx] - 1;
1014 j >= 0 && darray_item(key->symsMapNumEntries[ndx], j) == 0; j--)
1015 key->numLevels[ndx]--;
1020 AddActionsToKey(KeyInfo *key, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1021 ExprDef *value, SymbolsInfo *info)
1024 unsigned ndx, nActs;
1026 struct xkb_any_action *toAct;
1028 if (!GetGroupIndex(key, keymap, arrayNdx, ACTIONS, &ndx))
1033 key->actsDefined |= (1 << ndx);
1036 if (value->op != ExprActionList)
1038 WSGO("Bad expression type (%d) for action list value\n", value->op);
1039 ACTION("Ignoring actions for group %d of %s\n", ndx,
1040 longText(key->name));
1043 if (!darray_empty(key->acts[ndx]))
1045 WSGO("Actions for key %s, group %d already defined\n",
1046 longText(key->name), ndx);
1049 for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1051 act = (ExprDef *) act->common.next;
1055 WSGO("Action list but not actions in AddActionsToKey\n");
1058 if ((key->numLevels[ndx] < nActs || darray_empty(key->acts[ndx])) &&
1059 !ResizeKeyGroup(key, ndx, nActs, nActs, true))
1061 WSGO("Could not resize group %d of key %s\n", ndx,
1062 longText(key->name));
1063 ACTION("Actions lost\n");
1066 key->actsDefined |= (1 << ndx);
1068 toAct = (struct xkb_any_action *) darray_mem(key->acts[ndx], 0);
1069 act = value->value.child;
1070 for (i = 0; i < nActs; i++, toAct++)
1072 if (!HandleActionDef(act, keymap, toAct, info->action))
1074 ERROR("Illegal action definition for %s\n",
1075 longText(key->name));
1076 ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1078 act = (ExprDef *) act->common.next;
1083 static const LookupEntry lockingEntries[] = {
1084 {"true", XkbKB_Lock},
1085 {"yes", XkbKB_Lock},
1087 {"false", XkbKB_Default},
1088 {"no", XkbKB_Default},
1089 {"off", XkbKB_Default},
1090 {"permanent", XkbKB_Lock | XkbKB_Permanent},
1094 static const LookupEntry repeatEntries[] = {
1095 {"true", RepeatYes},
1098 {"false", RepeatNo},
1101 {"default", RepeatUndefined},
1106 SetSymbolsField(KeyInfo *key, struct xkb_keymap *keymap, char *field,
1107 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
1112 if (strcasecmp(field, "type") == 0)
1115 if ((!ExprResolveString(keymap->ctx, value, &tmp))
1116 && (warningLevel > 0))
1118 WARN("The type field of a key symbol map must be a string\n");
1119 ACTION("Ignoring illegal type definition\n");
1121 if (arrayNdx == NULL)
1123 key->dfltType = xkb_atom_intern(keymap->ctx, tmp.str);
1124 key->defs.defined |= _Key_Type_Dflt;
1126 else if (!ExprResolveGroup(keymap->ctx, arrayNdx, &ndx))
1128 ERROR("Illegal group index for type of key %s\n",
1129 longText(key->name));
1130 ACTION("Definition with non-integer array index ignored\n");
1136 key->types[ndx.uval - 1] = xkb_atom_intern(keymap->ctx, tmp.str);
1137 key->typesDefined |= (1 << (ndx.uval - 1));
1141 else if (strcasecmp(field, "symbols") == 0)
1142 return AddSymbolsToKey(key, keymap, arrayNdx, value, info);
1143 else if (strcasecmp(field, "actions") == 0)
1144 return AddActionsToKey(key, keymap, arrayNdx, value, info);
1145 else if ((strcasecmp(field, "vmods") == 0) ||
1146 (strcasecmp(field, "virtualmods") == 0) ||
1147 (strcasecmp(field, "virtualmodifiers") == 0))
1149 ok = ExprResolveVModMask(value, &tmp, keymap);
1152 key->vmodmap = (tmp.uval >> 8);
1153 key->defs.defined |= _Key_VModMap;
1157 ERROR("Expected a virtual modifier mask, found %s\n",
1158 exprOpText(value->op));
1159 ACTION("Ignoring virtual modifiers definition for key %s\n",
1160 longText(key->name));
1163 else if ((strcasecmp(field, "locking") == 0) ||
1164 (strcasecmp(field, "lock") == 0) ||
1165 (strcasecmp(field, "locks") == 0))
1167 ok = ExprResolveEnum(keymap->ctx, value, &tmp, lockingEntries);
1169 key->behavior.type = tmp.uval;
1170 key->defs.defined |= _Key_Behavior;
1172 else if ((strcasecmp(field, "radiogroup") == 0) ||
1173 (strcasecmp(field, "permanentradiogroup") == 0) ||
1174 (strcasecmp(field, "allownone") == 0))
1176 ERROR("Radio groups not supported\n");
1177 ACTION("Ignoring radio group specification for key %s\n", longText(key->name));
1180 else if (uStrCasePrefix("overlay", field) ||
1181 uStrCasePrefix("permanentoverlay", field))
1183 ERROR("Overlays not supported\n");
1184 ACTION("Ignoring overlay specification for key %s\n", longText(key->name));
1186 else if ((strcasecmp(field, "repeating") == 0) ||
1187 (strcasecmp(field, "repeats") == 0) ||
1188 (strcasecmp(field, "repeat") == 0))
1190 ok = ExprResolveEnum(keymap->ctx, value, &tmp, repeatEntries);
1193 ERROR("Illegal repeat setting for %s\n",
1194 longText(key->name));
1195 ACTION("Non-boolean repeat setting ignored\n");
1198 key->repeat = tmp.uval;
1199 key->defs.defined |= _Key_Repeat;
1201 else if ((strcasecmp(field, "groupswrap") == 0) ||
1202 (strcasecmp(field, "wrapgroups") == 0))
1204 ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1207 ERROR("Illegal groupsWrap setting for %s\n",
1208 longText(key->name));
1209 ACTION("Non-boolean value ignored\n");
1213 key->groupInfo = XkbWrapIntoRange;
1215 key->groupInfo = XkbClampIntoRange;
1216 key->defs.defined |= _Key_GroupInfo;
1218 else if ((strcasecmp(field, "groupsclamp") == 0) ||
1219 (strcasecmp(field, "clampgroups") == 0))
1221 ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1224 ERROR("Illegal groupsClamp setting for %s\n",
1225 longText(key->name));
1226 ACTION("Non-boolean value ignored\n");
1230 key->groupInfo = XkbClampIntoRange;
1232 key->groupInfo = XkbWrapIntoRange;
1233 key->defs.defined |= _Key_GroupInfo;
1235 else if ((strcasecmp(field, "groupsredirect") == 0) ||
1236 (strcasecmp(field, "redirectgroups") == 0))
1238 if (!ExprResolveGroup(keymap->ctx, value, &tmp))
1240 ERROR("Illegal group index for redirect of key %s\n",
1241 longText(key->name));
1242 ACTION("Definition with non-integer group ignored\n");
1246 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1247 key->defs.defined |= _Key_GroupInfo;
1251 ERROR("Unknown field %s in a symbol interpretation\n", field);
1252 ACTION("Definition ignored\n");
1259 SetGroupName(SymbolsInfo *info, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1262 ExprResult tmp, name;
1264 if ((arrayNdx == NULL) && (warningLevel > 0))
1266 WARN("You must specify an index when specifying a group name\n");
1267 ACTION("Group name definition without array subscript ignored\n");
1270 if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp))
1272 ERROR("Illegal index in group name definition\n");
1273 ACTION("Definition with non-integer array index ignored\n");
1276 if (!ExprResolveString(keymap->ctx, value, &name))
1278 ERROR("Group name must be a string\n");
1279 ACTION("Illegal name for group %d ignored\n", tmp.uval);
1282 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1283 xkb_atom_intern(keymap->ctx, name.str);
1290 HandleSymbolsVar(VarDef *stmt, struct xkb_keymap *keymap, SymbolsInfo *info)
1292 ExprResult elem, field;
1296 if (ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx) == 0)
1297 return 0; /* internal error, already reported */
1298 if (elem.str && (strcasecmp(elem.str, "key") == 0))
1300 ret = SetSymbolsField(&info->dflt, keymap, field.str, arrayNdx,
1303 else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) ||
1304 (strcasecmp(field.str, "groupname") ==
1307 ret = SetGroupName(info, keymap, arrayNdx, stmt->value);
1309 else if ((elem.str == NULL)
1310 && ((strcasecmp(field.str, "groupswrap") == 0) ||
1311 (strcasecmp(field.str, "wrapgroups") == 0)))
1313 ERROR("Global \"groupswrap\" not supported\n");
1314 ACTION("Ignored\n");
1317 else if ((elem.str == NULL)
1318 && ((strcasecmp(field.str, "groupsclamp") == 0) ||
1319 (strcasecmp(field.str, "clampgroups") == 0)))
1321 ERROR("Global \"groupsclamp\" not supported\n");
1322 ACTION("Ignored\n");
1325 else if ((elem.str == NULL)
1326 && ((strcasecmp(field.str, "groupsredirect") == 0) ||
1327 (strcasecmp(field.str, "redirectgroups") == 0)))
1329 ERROR("Global \"groupsredirect\" not supported\n");
1330 ACTION("Ignored\n");
1333 else if ((elem.str == NULL) && (strcasecmp(field.str, "allownone") == 0))
1335 ERROR("Radio groups not supported\n");
1336 ACTION("Ignoring \"allownone\" specification\n");
1340 ret = SetActionField(keymap, elem.str, field.str, arrayNdx,
1341 stmt->value, &info->action);
1350 HandleSymbolsBody(VarDef *def, struct xkb_keymap *keymap, KeyInfo *key,
1354 ExprResult tmp, field;
1357 for (; def != NULL; def = (VarDef *) def->common.next)
1359 if ((def->name) && (def->name->type == ExprFieldRef))
1361 ok = HandleSymbolsVar(def, keymap, info);
1366 if (def->name == NULL)
1368 if ((def->value == NULL)
1369 || (def->value->op == ExprKeysymList))
1370 field.str = strdup("symbols");
1372 field.str = strdup("actions");
1377 ok = ExprResolveLhs(keymap, def->name, &tmp, &field,
1381 ok = SetSymbolsField(key, keymap, field.str, arrayNdx,
1390 SetExplicitGroup(SymbolsInfo *info, KeyInfo *key)
1392 unsigned group = info->explicit_group;
1397 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1400 WARN("For the map %s an explicit group specified\n", info->name);
1401 WARN("but key %s has more than one group defined\n",
1402 longText(key->name));
1403 ACTION("All groups except first one will be ignored\n");
1404 for (i = 1; i < XkbNumKbdGroups; i++)
1406 key->numLevels[i] = 0;
1407 darray_free(key->syms[i]);
1408 darray_free(key->acts[i]);
1412 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1414 key->numLevels[group] = key->numLevels[0];
1415 key->numLevels[0] = 0;
1416 key->syms[group] = key->syms[0];
1417 darray_init(key->syms[0]);
1418 key->symsMapIndex[group] = key->symsMapIndex[0];
1419 darray_init(key->symsMapIndex[0]);
1420 key->symsMapNumEntries[group] = key->symsMapNumEntries[0];
1421 darray_init(key->symsMapNumEntries[0]);
1422 key->acts[group] = key->acts[0];
1423 darray_init(key->acts[0]);
1424 key->types[group] = key->types[0];
1430 HandleSymbolsDef(SymbolsDef *stmt, struct xkb_keymap *keymap,
1435 InitKeyInfo(&key, info->file_id);
1436 CopyKeyInfo(&info->dflt, &key, false);
1437 key.defs.merge = stmt->merge;
1438 key.name = KeyNameToLong(stmt->keyName);
1439 if (!HandleSymbolsBody((VarDef *) stmt->symbols, keymap, &key, info))
1445 if (!SetExplicitGroup(info, &key))
1451 if (!AddKeySymbols(info, &key, keymap))
1460 HandleModMapDef(ModMapDef *def, struct xkb_keymap *keymap, SymbolsInfo *info)
1467 if (!LookupModIndex(keymap->ctx, NULL, def->modifier, TypeInt, &rtrn))
1469 ERROR("Illegal modifier map definition\n");
1470 ACTION("Ignoring map for non-modifier \"%s\"\n",
1471 xkb_atom_text(keymap->ctx, def->modifier));
1475 tmp.modifier = rtrn.uval;
1476 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1478 if ((key->op == ExprValue) && (key->type == TypeKeyName))
1480 tmp.haveSymbol = false;
1481 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1483 else if (ExprResolveKeySym(keymap->ctx, key, &rtrn))
1485 tmp.haveSymbol = true;
1486 tmp.u.keySym = rtrn.uval;
1490 ERROR("Modmap entries may contain only key names or keysyms\n");
1491 ACTION("Illegal definition for %s modifier ignored\n",
1492 XkbcModIndexText(tmp.modifier));
1496 ok = AddModMapEntry(info, &tmp) && ok;
1502 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
1503 enum merge_mode merge, SymbolsInfo *info)
1508 info->name = uDupString(file->name);
1512 switch (stmt->stmtType)
1515 if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info))
1518 case StmtSymbolsDef:
1519 if (!HandleSymbolsDef((SymbolsDef *) stmt, keymap, info))
1523 if (!HandleSymbolsVar((VarDef *) stmt, keymap, info))
1527 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
1531 ERROR("Interpretation files may not include other types\n");
1532 ACTION("Ignoring definition of symbol interpretation\n");
1535 case StmtKeycodeDef:
1536 ERROR("Interpretation files may not include other types\n");
1537 ACTION("Ignoring definition of key name\n");
1541 if (!HandleModMapDef((ModMapDef *) stmt, keymap, info))
1545 WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1550 if (info->errorCount > 10)
1553 ERROR("Too many errors\n");
1555 ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1562 * Given a keysym @sym, find the keycode which generates it
1563 * (returned in @kc_rtrn). This is used for example in a modifier
1564 * map definition, such as:
1565 * modifier_map Lock { Caps_Lock };
1566 * where we want to add the Lock modifier to the modmap of the key
1567 * which matches the keysym Caps_Lock.
1568 * Since there can be many keys which generates the keysym, the key
1569 * is chosen first by lowest group in which the keysym appears, than
1570 * by lowest level and than by lowest key code.
1573 FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
1574 xkb_keycode_t *kc_rtrn)
1577 unsigned int group, level, min_group = UINT_MAX, min_level = UINT_MAX;
1579 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++)
1581 for (group = 0; group < XkbKeyNumGroups(keymap, key); group++)
1583 for (level = 0; level < XkbKeyGroupWidth(keymap, key, group);
1586 if (XkbKeyNumSyms(keymap, key, group, level) != 1 ||
1587 (XkbKeySymEntry(keymap, key, group, level))[0] != sym)
1591 * If the keysym was found in a group or level > 0, we must
1592 * keep looking since we might find a key in which the keysym
1593 * is in a lower group or level.
1595 if (group < min_group ||
1596 (group == min_group && level < min_level)) {
1598 if (group == 0 && level == 0) {
1609 return min_group != UINT_MAX;
1613 * Find the given name in the keymap->map->types and return its index.
1615 * @param atom The atom to search for.
1616 * @param type_rtrn Set to the index of the name if found.
1618 * @return true if found, false otherwise.
1621 FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn)
1624 const char *name = xkb_atom_text(keymap->ctx, atom);
1625 struct xkb_key_type *type;
1627 if (keymap && keymap->map) {
1628 darray_foreach(type, keymap->map->types) {
1629 if (strcmp(type->name, name) == 0) {
1640 * Assign a type to the given sym and return the Atom for the type assigned.
1643 * - ONE_LEVEL for width 0/1
1644 * - ALPHABETIC for 2 shift levels, with lower/upercase
1645 * - KEYPAD for keypad keys.
1646 * - TWO_LEVEL for other 2 shift level keys.
1647 * and the same for four level keys.
1649 * @param width Number of sysms in syms.
1650 * @param syms The keysyms for the given key (must be size width).
1651 * @param typeNameRtrn Set to the Atom of the type name.
1653 * @returns true if a type could be found, false otherwise.
1655 * FIXME: I need to take the KeyInfo so I can look at symsMapIndex and
1656 * all that fun stuff rather than just assuming there's always one
1660 FindAutomaticType(struct xkb_keymap *keymap, int width,
1661 const xkb_keysym_t *syms, xkb_atom_t *typeNameRtrn,
1665 if ((width == 1) || (width == 0))
1667 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
1670 else if (width == 2)
1672 if (syms && xkb_keysym_is_lower(syms[0]) &&
1673 xkb_keysym_is_upper(syms[1]))
1675 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
1677 else if (syms && (xkb_keysym_is_keypad(syms[0]) ||
1678 xkb_keysym_is_keypad(syms[1])))
1680 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "KEYPAD");
1685 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
1689 else if (width <= 4)
1691 if (syms && xkb_keysym_is_lower(syms[0]) &&
1692 xkb_keysym_is_upper(syms[1]))
1693 if (xkb_keysym_is_lower(syms[2]) && xkb_keysym_is_upper(syms[3]))
1695 xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_ALPHABETIC");
1697 *typeNameRtrn = xkb_atom_intern(keymap->ctx,
1698 "FOUR_LEVEL_SEMIALPHABETIC");
1700 else if (syms && (xkb_keysym_is_keypad(syms[0]) ||
1701 xkb_keysym_is_keypad(syms[1])))
1702 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_KEYPAD");
1704 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL");
1705 /* XXX: why not set autoType here? */
1707 return ((width >= 0) && (width <= 4));
1711 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1712 * groups, and reduce to one group if all groups are identical anyway.
1715 PrepareKeyDef(KeyInfo * key)
1717 int i, j, width, defined, lastGroup;
1720 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1721 /* get highest group number */
1722 for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1724 if (defined & (1 << i))
1732 /* If there are empty groups between non-empty ones fill them with data */
1733 /* from the first group. */
1734 /* We can make a wrong assumption here. But leaving gaps is worse. */
1735 for (i = lastGroup; i > 0; i--)
1737 if (defined & (1 << i))
1739 width = key->numLevels[0];
1740 if (key->typesDefined & 1)
1742 for (j = 0; j < width; j++)
1744 key->types[i] = key->types[0];
1746 key->typesDefined |= 1 << i;
1748 if ((key->actsDefined & 1) && !darray_empty(key->acts[0]))
1750 darray_copy(key->acts[i], key->acts[0]);
1751 key->actsDefined |= 1 << i;
1753 if ((key->symsDefined & 1) && !darray_empty(key->syms[0]))
1755 darray_copy(key->syms[i], key->syms[0]);
1756 darray_copy(key->symsMapIndex[i], key->symsMapIndex[0]);
1757 darray_copy(key->symsMapNumEntries[i], key->symsMapNumEntries[0]);
1758 key->symsDefined |= 1 << i;
1762 key->numLevels[i] = key->numLevels[0];
1765 /* If all groups are completely identical remove them all */
1766 /* exept the first one. */
1768 for (i = lastGroup; i > 0; i--)
1770 if ((key->numLevels[i] != key->numLevels[0]) ||
1771 (key->types[i] != key->types[0]))
1776 if (!darray_same(key->syms[i], key->syms[0]) &&
1777 (darray_empty(key->syms[i]) || darray_empty(key->syms[0]) ||
1778 darray_size(key->syms[i]) != darray_size(key->syms[0]) ||
1779 memcmp(darray_mem(key->syms[i], 0),
1780 darray_mem(key->syms[0], 0),
1781 sizeof(xkb_keysym_t) * darray_size(key->syms[0]))))
1786 if (!darray_same(key->symsMapIndex[i], key->symsMapIndex[0]) &&
1787 (darray_empty(key->symsMapIndex[i]) ||
1788 darray_empty(key->symsMapIndex[0]) ||
1789 memcmp(darray_mem(key->symsMapIndex[i], 0),
1790 darray_mem(key->symsMapIndex[0], 0),
1791 key->numLevels[0] * sizeof(int))))
1796 if (!darray_same(key->symsMapNumEntries[i], key->symsMapNumEntries[0]) &&
1797 (darray_empty(key->symsMapNumEntries[i]) ||
1798 darray_empty(key->symsMapNumEntries[0]) ||
1799 memcmp(darray_mem(key->symsMapNumEntries[i], 0),
1800 darray_mem(key->symsMapNumEntries[0], 0),
1801 key->numLevels[0] * sizeof(size_t))))
1806 if (!darray_same(key->acts[i], key->acts[0]) &&
1807 (darray_empty(key->acts[i]) || darray_empty(key->acts[0]) ||
1808 memcmp(darray_mem(key->acts[i], 0),
1809 darray_mem(key->acts[0], 0),
1810 key->numLevels[0] * sizeof(union xkb_action))))
1818 for (i = lastGroup; i > 0; i--)
1820 key->numLevels[i] = 0;
1821 darray_free(key->syms[i]);
1822 darray_free(key->symsMapIndex[i]);
1823 darray_free(key->symsMapNumEntries[i]);
1824 darray_free(key->acts[i]);
1827 key->symsDefined &= 1;
1828 key->actsDefined &= 1;
1829 key->typesDefined &= 1;
1834 * Copy the KeyInfo into the keyboard description.
1836 * This function recurses.
1839 CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *key, int start_from)
1843 unsigned int sizeSyms = 0;
1844 unsigned width, tmp, nGroups;
1845 struct xkb_key_type * type;
1846 bool haveActions, autoType, useAlias;
1847 unsigned types[XkbNumKbdGroups];
1848 union xkb_action *outActs;
1849 unsigned int symIndex = 0;
1850 struct xkb_sym_map *sym_map;
1852 useAlias = (start_from == 0);
1854 /* get the keycode for the key. */
1855 if (!FindNamedKey(keymap, key->name, &kc, useAlias,
1856 CreateKeyNames(keymap), start_from))
1858 if ((start_from == 0) && (warningLevel >= 5))
1860 WARN("Key %s not found in keycodes\n", longText(key->name));
1861 ACTION("Symbols ignored\n");
1866 haveActions = false;
1867 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1869 if (((i + 1) > nGroups)
1870 && (((key->symsDefined | key->actsDefined) & (1 << i))
1871 || (key->typesDefined) & (1 << i)))
1873 if (!darray_empty(key->acts[i]))
1876 /* Assign the type to the key, if it is missing. */
1877 if (key->types[i] == XKB_ATOM_NONE)
1879 if (key->dfltType != XKB_ATOM_NONE)
1880 key->types[i] = key->dfltType;
1881 else if (FindAutomaticType(keymap, key->numLevels[i],
1882 darray_mem(key->syms[i], 0),
1883 &key->types[i], &autoType))
1888 if (warningLevel >= 5)
1890 WARN("No automatic type for %d symbols\n",
1891 (unsigned int) key->numLevels[i]);
1892 ACTION("Using %s for the %s key (keycode %d)\n",
1893 xkb_atom_text(keymap->ctx, key->types[i]),
1894 longText(key->name), kc);
1898 if (FindNamedType(keymap, key->types[i], &types[i]))
1900 if (!autoType || key->numLevels[i] > 2)
1901 keymap->server->explicit[kc] |= (1 << i);
1905 if (warningLevel >= 3)
1907 WARN("Type \"%s\" is not defined\n",
1908 xkb_atom_text(keymap->ctx, key->types[i]));
1909 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
1910 longText(key->name), kc);
1912 types[i] = XkbTwoLevelIndex;
1914 /* if the type specifies fewer levels than the key has, shrink the key */
1915 type = &darray_item(keymap->map->types, types[i]);
1916 if (type->num_levels < key->numLevels[i])
1918 if (warningLevel > 0)
1920 WARN("Type \"%s\" has %d levels, but %s has %d symbols\n",
1921 type->name, type->num_levels,
1922 xkb_atom_text(keymap->ctx, key->name), key->numLevels[i]);
1923 ACTION("Ignoring extra symbols\n");
1925 key->numLevels[i] = type->num_levels;
1927 if (key->numLevels[i] > width)
1928 width = key->numLevels[i];
1929 if (type->num_levels > width)
1930 width = type->num_levels;
1931 sizeSyms += darray_size(key->syms[i]);
1934 if (!XkbcResizeKeySyms(keymap, kc, sizeSyms))
1936 WSGO("Could not enlarge symbols for %s (keycode %d)\n",
1937 longText(key->name), kc);
1942 outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups);
1943 if (outActs == NULL)
1945 WSGO("Could not enlarge actions for %s (key %d)\n",
1946 longText(key->name), kc);
1949 keymap->server->explicit[kc] |= XkbExplicitInterpretMask;
1954 sym_map = &darray_item(keymap->map->key_sym_map, kc);
1956 if (key->defs.defined & _Key_GroupInfo)
1959 i = sym_map->group_info;
1961 sym_map->group_info = XkbSetNumGroups(i, nGroups);
1962 sym_map->width = width;
1963 sym_map->sym_index = uTypedCalloc(nGroups * width, int);
1964 sym_map->num_syms = uTypedCalloc(nGroups * width, unsigned int);
1966 for (i = 0; i < nGroups; i++)
1968 /* assign kt_index[i] to the index of the type in map->types.
1969 * kt_index[i] may have been set by a previous run (if we have two
1970 * layouts specified). Let's not overwrite it with the ONE_LEVEL
1971 * default group if we dont even have keys for this group anyway.
1973 * FIXME: There should be a better fix for this.
1975 if (key->numLevels[i])
1976 sym_map->kt_index[i] = types[i];
1977 if (!darray_empty(key->syms[i]))
1979 /* fill key to "width" symbols*/
1980 for (tmp = 0; tmp < width; tmp++)
1982 if (tmp < key->numLevels[i] &&
1983 darray_item(key->symsMapNumEntries[i], tmp) != 0)
1985 memcpy(darray_mem(sym_map->syms, symIndex),
1986 darray_mem(key->syms[i],
1987 darray_item(key->symsMapIndex[i], tmp)),
1988 darray_item(key->symsMapNumEntries[i], tmp) * sizeof(xkb_keysym_t));
1989 sym_map->sym_index[(i * width) + tmp] = symIndex;
1990 sym_map->num_syms[(i * width) + tmp] =
1991 darray_item(key->symsMapNumEntries[i], tmp);
1992 symIndex += sym_map->num_syms[(i * width) + tmp];
1996 sym_map->sym_index[(i * width) + tmp] = -1;
1997 sym_map->num_syms[(i * width) + tmp] = 0;
1999 if (outActs != NULL && !darray_empty(key->acts[i]))
2001 if (tmp < key->numLevels[i])
2002 outActs[tmp] = darray_item(key->acts[i], tmp);
2004 outActs[tmp].type = XkbSA_NoAction;
2009 switch (key->behavior.type & XkbKB_OpMask)
2014 keymap->server->behaviors[kc] = key->behavior;
2015 keymap->server->explicit[kc] |= XkbExplicitBehaviorMask;
2018 if (key->defs.defined & _Key_VModMap)
2020 keymap->server->vmodmap[kc] = key->vmodmap;
2021 keymap->server->explicit[kc] |= XkbExplicitVModMapMask;
2023 if (key->repeat != RepeatUndefined)
2025 if (key->repeat == RepeatYes)
2026 keymap->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2028 keymap->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2029 keymap->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2032 if (nGroups > keymap->ctrls->num_groups)
2033 keymap->ctrls->num_groups = nGroups;
2035 /* do the same thing for the next key */
2036 CopySymbolsDef(keymap, key, kc + 1);
2041 CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry)
2045 if (!entry->haveSymbol &&
2046 !FindNamedKey(keymap, entry->u.keyName, &kc, true,
2047 CreateKeyNames(keymap), 0))
2049 if (warningLevel >= 5)
2051 WARN("Key %s not found in keycodes\n",
2052 longText(entry->u.keyName));
2053 ACTION("Modifier map entry for %s not updated\n",
2054 XkbcModIndexText(entry->modifier));
2058 else if (entry->haveSymbol &&
2059 !FindKeyForSymbol(keymap, entry->u.keySym, &kc))
2061 if (warningLevel > 5)
2063 WARN("Key \"%s\" not found in symbol map\n",
2064 XkbcKeysymText(entry->u.keySym));
2065 ACTION("Modifier map entry for %s not updated\n",
2066 XkbcModIndexText(entry->modifier));
2070 keymap->map->modmap[kc] |= (1 << entry->modifier);
2075 * Handle the xkb_symbols section of an xkb file.
2077 * @param file The parsed xkb_symbols section of the xkb file.
2078 * @param keymap Handle to the keyboard description to store the symbols in.
2079 * @param merge Merge strategy (e.g. MERGE_OVERRIDE).
2082 CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
2088 InitSymbolsInfo(&info, keymap, file->id);
2089 info.dflt.defs.merge = merge;
2091 HandleSymbolsFile(file, keymap, merge, &info);
2093 if (darray_empty(info.keys))
2096 if (info.errorCount != 0)
2099 /* alloc memory in the xkb struct */
2100 if (XkbcAllocNames(keymap, XkbGroupNamesMask, 0) != Success) {
2101 WSGO("Can not allocate names in CompileSymbols\n");
2102 ACTION("Symbols not added\n");
2106 if (XkbcAllocClientMap(keymap, XkbKeySymsMask | XkbModifierMapMask, 0)
2108 WSGO("Could not allocate client map in CompileSymbols\n");
2109 ACTION("Symbols not added\n");
2113 if (XkbcAllocServerMap(keymap, XkbAllServerInfoMask, 32) != Success) {
2114 WSGO("Could not allocate server map in CompileSymbols\n");
2115 ACTION("Symbols not added\n");
2119 if (XkbcAllocControls(keymap) != Success) {
2120 WSGO("Could not allocate controls in CompileSymbols\n");
2121 ACTION("Symbols not added\n");
2126 keymap->names->symbols = strdup(info.name);
2128 /* now copy info into xkb. */
2129 ApplyAliases(keymap, &info.aliases);
2131 for (i = 0; i < XkbNumKbdGroups; i++) {
2132 if (info.groupNames[i] != XKB_ATOM_NONE) {
2133 free(keymap->names->groups[i]);
2134 keymap->names->groups[i] = xkb_atom_strdup(keymap->ctx,
2135 info.groupNames[i]);
2140 darray_foreach(key, info.keys)
2144 darray_foreach(key, info.keys)
2145 if (!CopySymbolsDef(keymap, key, 0))
2148 if (warningLevel > 3) {
2149 for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
2150 if (darray_item(keymap->names->keys, i).name[0] == '\0')
2153 if (XkbKeyNumGroups(keymap, i) < 1) {
2155 memcpy(buf, darray_item(keymap->names->keys, i).name, 4);
2157 WARN("No symbols defined for <%s> (keycode %d)\n", buf, i);
2163 ModMapEntry *mm, *next;
2164 for (mm = info.modMap; mm != NULL; mm = next) {
2165 if (!CopyModMapDef(keymap, mm))
2167 next = (ModMapEntry *) mm->defs.next;
2171 FreeSymbolsInfo(&info);
2175 FreeSymbolsInfo(&info);