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)
96 static const char dflt[4] = "*";
98 info->defs.defined = 0;
99 info->defs.fileID = 0;
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.fileID = 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)
222 info->explicit_group = 0;
223 info->errorCount = 0;
225 info->merge = MERGE_OVERRIDE;
226 darray_init(info->keys);
227 darray_growalloc(info->keys, 110);
229 for (i = 0; i < XkbNumKbdGroups; i++)
230 info->groupNames[i] = XKB_ATOM_NONE;
231 InitKeyInfo(&info->dflt);
232 InitVModInfo(&info->vmods, keymap);
234 info->aliases = NULL;
238 FreeSymbolsInfo(SymbolsInfo * info)
243 darray_foreach(key, info->keys)
245 darray_free(info->keys);
247 ClearCommonInfo(&info->modMap->defs);
249 ClearAliases(&info->aliases);
250 memset(info, 0, sizeof(SymbolsInfo));
254 ResizeKeyGroup(KeyInfo * key, unsigned int group, unsigned int numLevels,
255 unsigned sizeSyms, bool forceActions)
259 if (darray_size(key->syms[group]) < sizeSyms)
260 darray_resize0(key->syms[group], sizeSyms);
262 if (darray_empty(key->symsMapIndex[group]) ||
263 key->numLevels[group] < numLevels) {
264 darray_resize(key->symsMapIndex[group], numLevels);
265 for (i = key->numLevels[group]; i < numLevels; i++)
266 darray_item(key->symsMapIndex[group], i) = -1;
269 if (darray_empty(key->symsMapNumEntries[group]) ||
270 key->numLevels[group] < numLevels)
271 darray_resize0(key->symsMapNumEntries[group], numLevels);
273 if ((forceActions && (key->numLevels[group] < numLevels ||
274 darray_empty(key->acts[group]))) ||
275 (key->numLevels[group] < numLevels && !darray_empty(key->acts[group])))
276 darray_resize0(key->acts[group], numLevels);
278 if (key->numLevels[group] < numLevels)
279 key->numLevels[group] = numLevels;
284 enum key_group_selector {
291 MergeKeyGroups(SymbolsInfo * info,
292 KeyInfo * into, KeyInfo * from, unsigned group)
294 darray_xkb_keysym_t resultSyms;
295 enum key_group_selector using = NONE;
296 darray_xkb_action resultActs;
297 unsigned int resultWidth;
298 unsigned int resultSize = 0;
301 bool report, clobber;
303 clobber = (from->defs.merge != MERGE_AUGMENT);
305 report = (warningLevel > 9) ||
306 ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
308 darray_init(resultSyms);
310 if (into->numLevels[group] >= from->numLevels[group])
312 resultActs = into->acts[group];
313 resultWidth = into->numLevels[group];
317 resultActs = from->acts[group];
318 resultWidth = from->numLevels[group];
319 darray_resize(into->symsMapIndex[group],
320 from->numLevels[group]);
321 darray_resize0(into->symsMapNumEntries[group],
322 from->numLevels[group]);
324 for (i = into->numLevels[group]; i < from->numLevels[group]; i++)
325 darray_item(into->symsMapIndex[group], i) = -1;
328 if (darray_empty(resultActs) && (!darray_empty(into->acts[group]) ||
329 !darray_empty(from->acts[group])))
331 darray_resize0(resultActs, resultWidth);
332 for (i = 0; i < resultWidth; i++)
334 union xkb_action *fromAct = NULL, *toAct = NULL;
336 if (!darray_empty(from->acts[group]))
337 fromAct = &darray_item(from->acts[group], i);
339 if (!darray_empty(into->acts[group]))
340 toAct = &darray_item(into->acts[group], i);
342 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
345 darray_item(resultActs, i) = *toAct;
347 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
348 && (fromAct != NULL))
350 darray_item(resultActs, i) = *fromAct;
354 union xkb_action *use, *ignore;
368 ("Multiple actions for level %d/group %d on key %s\n",
369 i + 1, group + 1, longText(into->name));
370 ACTION("Using %s, ignoring %s\n",
371 XkbcActionTypeText(use->type),
372 XkbcActionTypeText(ignore->type));
375 darray_item(resultActs, i) = *use;
380 for (i = 0; i < resultWidth; i++)
382 unsigned int fromSize = 0;
385 if (!darray_empty(from->symsMapNumEntries[group]) &&
386 i < from->numLevels[group])
387 fromSize = darray_item(from->symsMapNumEntries[group], i);
389 if (!darray_empty(into->symsMapNumEntries[group]) &&
390 i < into->numLevels[group])
391 toSize = darray_item(into->symsMapNumEntries[group], i);
395 resultSize += toSize;
398 else if (toSize == 0 || clobber)
400 resultSize += fromSize;
405 resultSize += toSize;
415 resultSyms = from->syms[group];
416 darray_free(into->symsMapNumEntries[group]);
417 darray_free(into->symsMapIndex[group]);
418 into->symsMapNumEntries[group] = from->symsMapNumEntries[group];
419 into->symsMapIndex[group] = from->symsMapIndex[group];
420 darray_init(from->symsMapNumEntries[group]);
421 darray_init(from->symsMapIndex[group]);
424 else if (using == TO)
426 resultSyms = into->syms[group];
430 darray_resize0(resultSyms, resultSize);
432 for (i = 0; i < resultWidth; i++)
434 enum key_group_selector use = NONE;
435 unsigned int fromSize = 0;
436 unsigned int toSize = 0;
438 if (i < from->numLevels[group])
439 fromSize = darray_item(from->symsMapNumEntries[group], i);
441 if (i < into->numLevels[group])
442 toSize = darray_item(into->symsMapNumEntries[group], i);
444 if (fromSize == 0 && toSize == 0)
446 darray_item(into->symsMapIndex[group], i) = -1;
447 darray_item(into->symsMapNumEntries[group], i) = 0;
453 else if (toSize == 0 || clobber)
458 if (toSize && fromSize && report)
460 INFO("Multiple symbols for group %d, level %d on key %s\n",
461 group + 1, i + 1, longText(into->name));
462 ACTION("Using %s, ignoring %s\n",
463 (use == FROM ? "from" : "to"),
464 (use == FROM ? "to" : "from"));
469 memcpy(darray_mem(resultSyms, cur_idx),
470 darray_mem(from->syms[group],
471 darray_item(from->symsMapIndex[group], i)),
472 darray_item(from->symsMapNumEntries[group], i) * sizeof(xkb_keysym_t));
473 darray_item(into->symsMapIndex[group], i) = cur_idx;
474 darray_item(into->symsMapNumEntries[group], i) =
475 darray_item(from->symsMapNumEntries[group], i);
479 memcpy(darray_mem(resultSyms, cur_idx),
480 darray_mem(into->syms[group],
481 darray_item(into->symsMapIndex[group], i)),
482 darray_item(into->symsMapNumEntries[group], i) * sizeof(xkb_keysym_t));
483 darray_item(into->symsMapIndex[group], i) = cur_idx;
485 cur_idx += darray_item(into->symsMapNumEntries[group], i);
489 if (!darray_same(resultActs, into->acts[group]))
490 darray_free(into->acts[group]);
491 if (!darray_same(resultActs, from->acts[group]))
492 darray_free(from->acts[group]);
493 into->numLevels[group] = resultWidth;
494 if (!darray_same(resultSyms, into->syms[group]))
495 darray_free(into->syms[group]);
496 into->syms[group] = resultSyms;
497 if (!darray_same(resultSyms, from->syms[group]))
498 darray_free(from->syms[group]);
499 darray_init(from->syms[group]);
500 darray_free(from->symsMapIndex[group]);
501 darray_free(from->symsMapNumEntries[group]);
502 into->acts[group] = resultActs;
503 darray_init(from->acts[group]);
504 if (!darray_empty(into->syms[group]))
505 into->symsDefined |= (1 << group);
506 from->symsDefined &= ~(1 << group);
507 into->actsDefined |= (1 << group);
508 from->actsDefined &= ~(1 << group);
514 MergeKeys(SymbolsInfo *info, struct xkb_keymap *keymap,
515 KeyInfo *into, KeyInfo *from)
518 unsigned collide = 0;
521 if (from->defs.merge == MERGE_REPLACE)
523 for (i = 0; i < XkbNumKbdGroups; i++)
525 if (into->numLevels[i] != 0)
527 darray_free(into->syms[i]);
528 darray_free(into->acts[i]);
532 memset(from, 0, sizeof(KeyInfo));
535 report = ((warningLevel > 9) ||
536 ((into->defs.fileID == from->defs.fileID)
537 && (warningLevel > 0)));
538 for (i = 0; i < XkbNumKbdGroups; i++)
540 if (from->numLevels[i] > 0)
542 if (into->numLevels[i] == 0)
544 into->numLevels[i] = from->numLevels[i];
545 into->syms[i] = from->syms[i];
546 into->symsMapIndex[i] = from->symsMapIndex[i];
547 into->symsMapNumEntries[i] = from->symsMapNumEntries[i];
548 into->acts[i] = from->acts[i];
549 into->symsDefined |= (1 << i);
550 darray_init(from->syms[i]);
551 darray_init(from->symsMapIndex[i]);
552 darray_init(from->symsMapNumEntries[i]);
553 darray_init(from->acts[i]);
554 from->numLevels[i] = 0;
555 from->symsDefined &= ~(1 << i);
556 if (!darray_empty(into->syms[i]))
557 into->defs.defined |= _Key_Syms;
558 if (!darray_empty(into->acts[i]))
559 into->defs.defined |= _Key_Acts;
565 if (!darray_empty(into->syms[i]))
566 collide |= _Key_Syms;
567 if (!darray_empty(into->acts[i]))
568 collide |= _Key_Acts;
570 MergeKeyGroups(info, into, from, (unsigned) i);
573 if (from->types[i] != XKB_ATOM_NONE)
575 if ((into->types[i] != XKB_ATOM_NONE) && report &&
576 (into->types[i] != from->types[i]))
578 xkb_atom_t use, ignore;
579 collide |= _Key_Types;
580 if (from->defs.merge != MERGE_AUGMENT)
582 use = from->types[i];
583 ignore = into->types[i];
587 use = into->types[i];
588 ignore = from->types[i];
591 ("Multiple definitions for group %d type of key %s\n",
592 i, longText(into->name));
593 ACTION("Using %s, ignoring %s\n",
594 xkb_atom_text(keymap->ctx, use),
595 xkb_atom_text(keymap->ctx, ignore));
597 if ((from->defs.merge != MERGE_AUGMENT)
598 || (into->types[i] == XKB_ATOM_NONE))
600 into->types[i] = from->types[i];
604 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
606 into->behavior = from->behavior;
607 into->defs.defined |= _Key_Behavior;
609 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
611 into->vmodmap = from->vmodmap;
612 into->defs.defined |= _Key_VModMap;
614 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
616 into->repeat = from->repeat;
617 into->defs.defined |= _Key_Repeat;
619 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
621 into->dfltType = from->dfltType;
622 into->defs.defined |= _Key_Type_Dflt;
624 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
626 into->groupInfo = from->groupInfo;
627 into->defs.defined |= _Key_GroupInfo;
631 WARN("Symbol map for key %s redefined\n",
632 longText(into->name));
633 ACTION("Using %s definition for conflicting fields\n",
634 (from->defs.merge == MERGE_AUGMENT ? "first" : "last"));
640 AddKeySymbols(SymbolsInfo *info, KeyInfo *key, struct xkb_keymap *keymap)
642 unsigned long real_name;
645 darray_foreach(iter, info->keys)
646 if (iter->name == key->name)
647 return MergeKeys(info, keymap, iter, key);
649 if (FindKeyNameForAlias(keymap, key->name, &real_name))
650 darray_foreach(iter, info->keys)
651 if (iter->name == real_name)
652 return MergeKeys(info, keymap, iter, key);
654 darray_resize0(info->keys, darray_size(info->keys) + 1);
655 new = &darray_item(info->keys, darray_size(info->keys) - 1);
656 return CopyKeyInfo(key, new, true);
660 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
665 clobber = (new->defs.merge != MERGE_AUGMENT);
666 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
668 if (new->haveSymbol && mm->haveSymbol
669 && (new->u.keySym == mm->u.keySym))
671 unsigned use, ignore;
672 if (mm->modifier != new->modifier)
677 ignore = mm->modifier;
682 ignore = new->modifier;
685 ("%s added to symbol map for multiple modifiers\n",
686 XkbcKeysymText(new->u.keySym));
687 ACTION("Using %s, ignoring %s.\n",
688 XkbcModIndexText(use),
689 XkbcModIndexText(ignore));
694 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
695 (new->u.keyName == mm->u.keyName))
697 unsigned use, ignore;
698 if (mm->modifier != new->modifier)
703 ignore = mm->modifier;
708 ignore = new->modifier;
710 ERROR("Key %s added to map for multiple modifiers\n",
711 longText(new->u.keyName));
712 ACTION("Using %s, ignoring %s.\n",
713 XkbcModIndexText(use),
714 XkbcModIndexText(ignore));
720 mm = uTypedAlloc(ModMapEntry);
723 WSGO("Could not allocate modifier map entry\n");
724 ACTION("Modifier map for %s will be incomplete\n",
725 XkbcModIndexText(new->modifier));
729 mm->defs.next = &info->modMap->defs;
734 /***====================================================================***/
737 MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
738 enum merge_mode merge, struct xkb_keymap *keymap)
743 if (from->errorCount > 0)
745 into->errorCount += from->errorCount;
748 if (into->name == NULL)
750 into->name = from->name;
753 for (i = 0; i < XkbNumKbdGroups; i++)
755 if (from->groupNames[i] != XKB_ATOM_NONE)
757 if ((merge != MERGE_AUGMENT) ||
758 (into->groupNames[i] == XKB_ATOM_NONE))
759 into->groupNames[i] = from->groupNames[i];
763 darray_foreach(key, from->keys) {
764 if (merge != MERGE_DEFAULT)
765 key->defs.merge = merge;
767 if (!AddKeySymbols(into, key, keymap))
771 if (from->modMap != NULL)
773 ModMapEntry *mm, *next;
774 for (mm = from->modMap; mm != NULL; mm = next)
776 if (merge != MERGE_DEFAULT)
777 mm->defs.merge = merge;
778 if (!AddModMapEntry(into, mm))
780 next = (ModMapEntry *) mm->defs.next;
785 if (!MergeAliases(&into->aliases, &from->aliases, merge))
790 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
791 enum merge_mode merge, SymbolsInfo *info);
794 HandleIncludeSymbols(IncludeStmt *stmt, struct xkb_keymap *keymap,
799 SymbolsInfo included;
803 if ((stmt->file == NULL) && (stmt->map == NULL))
807 memset(info, 0, sizeof(SymbolsInfo));
809 else if (ProcessIncludeFile(keymap->ctx, stmt, FILE_TYPE_SYMBOLS, &rtrn,
812 InitSymbolsInfo(&included, keymap);
813 included.fileID = included.dflt.defs.fileID = 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);
855 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
856 next_incl.merge = next_incl.dflt.defs.merge = MERGE_OVERRIDE;
859 next_incl.explicit_group = atoi(next->modifier) - 1;
863 next_incl.explicit_group = info->explicit_group;
865 HandleSymbolsFile(rtrn, keymap, MERGE_OVERRIDE, &next_incl);
866 MergeIncludedSymbols(&included, &next_incl, op, keymap);
867 FreeSymbolsInfo(&next_incl);
872 info->errorCount += 10;
873 FreeSymbolsInfo(&included);
880 info->errorCount += included.errorCount;
886 MergeIncludedSymbols(info, &included, newMerge, keymap);
887 FreeSymbolsInfo(&included);
889 return (info->errorCount == 0);
896 GetGroupIndex(KeyInfo *key, struct xkb_keymap *keymap,
897 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
907 if (arrayNdx == NULL)
912 defined = key->symsDefined;
914 defined = key->actsDefined;
916 for (i = 0; i < XkbNumKbdGroups; i++)
918 if ((defined & (1 << i)) == 0)
924 ERROR("Too many groups of %s for key %s (max %d)\n", name,
925 longText(key->name), XkbNumKbdGroups + 1);
926 ACTION("Ignoring %s defined for extra groups\n", name);
929 if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp))
931 ERROR("Illegal group index for %s of key %s\n", name,
932 longText(key->name));
933 ACTION("Definition with non-integer array index ignored\n");
936 *ndx_rtrn = tmp.uval - 1;
941 AddSymbolsToKey(KeyInfo *key, struct xkb_keymap *keymap,
942 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
944 unsigned ndx, nSyms, nLevels;
948 if (!GetGroupIndex(key, keymap, arrayNdx, SYMBOLS, &ndx))
952 key->symsDefined |= (1 << ndx);
955 if (value->op != ExprKeysymList)
957 ERROR("Expected a list of symbols, found %s\n", exprOpText(value->op));
958 ACTION("Ignoring symbols for group %d of %s\n", ndx + 1,
959 longText(key->name));
962 if (!darray_empty(key->syms[ndx]))
964 ERROR("Symbols for key %s, group %d already defined\n",
965 longText(key->name), ndx + 1);
966 ACTION("Ignoring duplicate definition\n");
969 nSyms = darray_size(value->value.list.syms);
970 nLevels = darray_size(value->value.list.symsMapIndex);
971 if ((key->numLevels[ndx] < nSyms || darray_empty(key->syms[ndx])) &&
972 (!ResizeKeyGroup(key, ndx, nLevels, nSyms, false)))
974 WSGO("Could not resize group %d of key %s to contain %d levels\n",
975 ndx + 1, longText(key->name), nSyms);
976 ACTION("Symbols lost\n");
979 key->symsDefined |= (1 << ndx);
980 for (i = 0; i < nLevels; i++) {
981 darray_item(key->symsMapIndex[ndx], i) =
982 darray_item(value->value.list.symsMapIndex, i);
983 darray_item(key->symsMapNumEntries[ndx], i) =
984 darray_item(value->value.list.symsNumEntries, i);
986 for (j = 0; j < darray_item(key->symsMapNumEntries[ndx], i); j++) {
987 /* FIXME: What's abort() doing here? */
988 if (darray_item(key->symsMapIndex[ndx], i) + j >= nSyms)
990 if (!LookupKeysym(darray_item(value->value.list.syms,
991 darray_item(value->value.list.symsMapIndex, i) + j),
992 &darray_item(key->syms[ndx],
993 darray_item(key->symsMapIndex[ndx], i) + j))) {
994 WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
995 darray_item(value->value.list.syms, i),
998 xkb_atom_text(keymap->ctx, info->groupNames[ndx]), nSyms);
1000 darray_item(key->syms[ndx],
1001 darray_item(key->symsMapIndex[ndx], i) + j) = XKB_KEY_NoSymbol;
1002 darray_item(key->symsMapIndex[ndx], i) = -1;
1003 darray_item(key->symsMapNumEntries[ndx], i) = 0;
1006 if (darray_item(key->symsMapNumEntries[ndx], i) == 1 &&
1007 darray_item(key->syms[ndx],
1008 darray_item(key->symsMapIndex[ndx], i) + j) == XKB_KEY_NoSymbol) {
1009 darray_item(key->symsMapIndex[ndx], i) = -1;
1010 darray_item(key->symsMapNumEntries[ndx], i) = 0;
1014 for (j = key->numLevels[ndx] - 1;
1015 j >= 0 && darray_item(key->symsMapNumEntries[ndx], j) == 0; j--)
1016 key->numLevels[ndx]--;
1021 AddActionsToKey(KeyInfo *key, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1022 ExprDef *value, SymbolsInfo *info)
1025 unsigned ndx, nActs;
1027 struct xkb_any_action *toAct;
1029 if (!GetGroupIndex(key, keymap, arrayNdx, ACTIONS, &ndx))
1034 key->actsDefined |= (1 << ndx);
1037 if (value->op != ExprActionList)
1039 WSGO("Bad expression type (%d) for action list value\n", value->op);
1040 ACTION("Ignoring actions for group %d of %s\n", ndx,
1041 longText(key->name));
1044 if (!darray_empty(key->acts[ndx]))
1046 WSGO("Actions for key %s, group %d already defined\n",
1047 longText(key->name), ndx);
1050 for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1052 act = (ExprDef *) act->common.next;
1056 WSGO("Action list but not actions in AddActionsToKey\n");
1059 if ((key->numLevels[ndx] < nActs || darray_empty(key->acts[ndx])) &&
1060 !ResizeKeyGroup(key, ndx, nActs, nActs, true))
1062 WSGO("Could not resize group %d of key %s\n", ndx,
1063 longText(key->name));
1064 ACTION("Actions lost\n");
1067 key->actsDefined |= (1 << ndx);
1069 toAct = (struct xkb_any_action *) darray_mem(key->acts[ndx], 0);
1070 act = value->value.child;
1071 for (i = 0; i < nActs; i++, toAct++)
1073 if (!HandleActionDef(act, keymap, toAct, info->action))
1075 ERROR("Illegal action definition for %s\n",
1076 longText(key->name));
1077 ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1079 act = (ExprDef *) act->common.next;
1084 static const LookupEntry lockingEntries[] = {
1085 {"true", XkbKB_Lock},
1086 {"yes", XkbKB_Lock},
1088 {"false", XkbKB_Default},
1089 {"no", XkbKB_Default},
1090 {"off", XkbKB_Default},
1091 {"permanent", XkbKB_Lock | XkbKB_Permanent},
1095 static const LookupEntry repeatEntries[] = {
1096 {"true", RepeatYes},
1099 {"false", RepeatNo},
1102 {"default", RepeatUndefined},
1107 SetSymbolsField(KeyInfo *key, struct xkb_keymap *keymap, char *field,
1108 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
1113 if (strcasecmp(field, "type") == 0)
1116 if ((!ExprResolveString(keymap->ctx, value, &tmp))
1117 && (warningLevel > 0))
1119 WARN("The type field of a key symbol map must be a string\n");
1120 ACTION("Ignoring illegal type definition\n");
1122 if (arrayNdx == NULL)
1124 key->dfltType = xkb_atom_intern(keymap->ctx, tmp.str);
1125 key->defs.defined |= _Key_Type_Dflt;
1127 else if (!ExprResolveGroup(keymap->ctx, arrayNdx, &ndx))
1129 ERROR("Illegal group index for type of key %s\n",
1130 longText(key->name));
1131 ACTION("Definition with non-integer array index ignored\n");
1137 key->types[ndx.uval - 1] = xkb_atom_intern(keymap->ctx, tmp.str);
1138 key->typesDefined |= (1 << (ndx.uval - 1));
1142 else if (strcasecmp(field, "symbols") == 0)
1143 return AddSymbolsToKey(key, keymap, arrayNdx, value, info);
1144 else if (strcasecmp(field, "actions") == 0)
1145 return AddActionsToKey(key, keymap, arrayNdx, value, info);
1146 else if ((strcasecmp(field, "vmods") == 0) ||
1147 (strcasecmp(field, "virtualmods") == 0) ||
1148 (strcasecmp(field, "virtualmodifiers") == 0))
1150 ok = ExprResolveVModMask(value, &tmp, keymap);
1153 key->vmodmap = (tmp.uval >> 8);
1154 key->defs.defined |= _Key_VModMap;
1158 ERROR("Expected a virtual modifier mask, found %s\n",
1159 exprOpText(value->op));
1160 ACTION("Ignoring virtual modifiers definition for key %s\n",
1161 longText(key->name));
1164 else if ((strcasecmp(field, "locking") == 0) ||
1165 (strcasecmp(field, "lock") == 0) ||
1166 (strcasecmp(field, "locks") == 0))
1168 ok = ExprResolveEnum(keymap->ctx, value, &tmp, lockingEntries);
1170 key->behavior.type = tmp.uval;
1171 key->defs.defined |= _Key_Behavior;
1173 else if ((strcasecmp(field, "radiogroup") == 0) ||
1174 (strcasecmp(field, "permanentradiogroup") == 0) ||
1175 (strcasecmp(field, "allownone") == 0))
1177 ERROR("Radio groups not supported\n");
1178 ACTION("Ignoring radio group specification for key %s\n", longText(key->name));
1181 else if (uStrCasePrefix("overlay", field) ||
1182 uStrCasePrefix("permanentoverlay", field))
1184 ERROR("Overlays not supported\n");
1185 ACTION("Ignoring overlay specification for key %s\n", longText(key->name));
1187 else if ((strcasecmp(field, "repeating") == 0) ||
1188 (strcasecmp(field, "repeats") == 0) ||
1189 (strcasecmp(field, "repeat") == 0))
1191 ok = ExprResolveEnum(keymap->ctx, value, &tmp, repeatEntries);
1194 ERROR("Illegal repeat setting for %s\n",
1195 longText(key->name));
1196 ACTION("Non-boolean repeat setting ignored\n");
1199 key->repeat = tmp.uval;
1200 key->defs.defined |= _Key_Repeat;
1202 else if ((strcasecmp(field, "groupswrap") == 0) ||
1203 (strcasecmp(field, "wrapgroups") == 0))
1205 ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1208 ERROR("Illegal groupsWrap setting for %s\n",
1209 longText(key->name));
1210 ACTION("Non-boolean value ignored\n");
1214 key->groupInfo = XkbWrapIntoRange;
1216 key->groupInfo = XkbClampIntoRange;
1217 key->defs.defined |= _Key_GroupInfo;
1219 else if ((strcasecmp(field, "groupsclamp") == 0) ||
1220 (strcasecmp(field, "clampgroups") == 0))
1222 ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1225 ERROR("Illegal groupsClamp setting for %s\n",
1226 longText(key->name));
1227 ACTION("Non-boolean value ignored\n");
1231 key->groupInfo = XkbClampIntoRange;
1233 key->groupInfo = XkbWrapIntoRange;
1234 key->defs.defined |= _Key_GroupInfo;
1236 else if ((strcasecmp(field, "groupsredirect") == 0) ||
1237 (strcasecmp(field, "redirectgroups") == 0))
1239 if (!ExprResolveGroup(keymap->ctx, value, &tmp))
1241 ERROR("Illegal group index for redirect of key %s\n",
1242 longText(key->name));
1243 ACTION("Definition with non-integer group ignored\n");
1247 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1248 key->defs.defined |= _Key_GroupInfo;
1252 ERROR("Unknown field %s in a symbol interpretation\n", field);
1253 ACTION("Definition ignored\n");
1260 SetGroupName(SymbolsInfo *info, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1263 ExprResult tmp, name;
1265 if ((arrayNdx == NULL) && (warningLevel > 0))
1267 WARN("You must specify an index when specifying a group name\n");
1268 ACTION("Group name definition without array subscript ignored\n");
1271 if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp))
1273 ERROR("Illegal index in group name definition\n");
1274 ACTION("Definition with non-integer array index ignored\n");
1277 if (!ExprResolveString(keymap->ctx, value, &name))
1279 ERROR("Group name must be a string\n");
1280 ACTION("Illegal name for group %d ignored\n", tmp.uval);
1283 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1284 xkb_atom_intern(keymap->ctx, name.str);
1291 HandleSymbolsVar(VarDef *stmt, struct xkb_keymap *keymap, SymbolsInfo *info)
1293 ExprResult elem, field;
1297 if (ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx) == 0)
1298 return 0; /* internal error, already reported */
1299 if (elem.str && (strcasecmp(elem.str, "key") == 0))
1301 ret = SetSymbolsField(&info->dflt, keymap, field.str, arrayNdx,
1304 else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) ||
1305 (strcasecmp(field.str, "groupname") ==
1308 ret = SetGroupName(info, keymap, arrayNdx, stmt->value);
1310 else if ((elem.str == NULL)
1311 && ((strcasecmp(field.str, "groupswrap") == 0) ||
1312 (strcasecmp(field.str, "wrapgroups") == 0)))
1314 ERROR("Global \"groupswrap\" not supported\n");
1315 ACTION("Ignored\n");
1318 else if ((elem.str == NULL)
1319 && ((strcasecmp(field.str, "groupsclamp") == 0) ||
1320 (strcasecmp(field.str, "clampgroups") == 0)))
1322 ERROR("Global \"groupsclamp\" not supported\n");
1323 ACTION("Ignored\n");
1326 else if ((elem.str == NULL)
1327 && ((strcasecmp(field.str, "groupsredirect") == 0) ||
1328 (strcasecmp(field.str, "redirectgroups") == 0)))
1330 ERROR("Global \"groupsredirect\" not supported\n");
1331 ACTION("Ignored\n");
1334 else if ((elem.str == NULL) && (strcasecmp(field.str, "allownone") == 0))
1336 ERROR("Radio groups not supported\n");
1337 ACTION("Ignoring \"allownone\" specification\n");
1341 ret = SetActionField(keymap, elem.str, field.str, arrayNdx,
1342 stmt->value, &info->action);
1351 HandleSymbolsBody(VarDef *def, struct xkb_keymap *keymap, KeyInfo *key,
1355 ExprResult tmp, field;
1358 for (; def != NULL; def = (VarDef *) def->common.next)
1360 if ((def->name) && (def->name->type == ExprFieldRef))
1362 ok = HandleSymbolsVar(def, keymap, info);
1367 if (def->name == NULL)
1369 if ((def->value == NULL)
1370 || (def->value->op == ExprKeysymList))
1371 field.str = strdup("symbols");
1373 field.str = strdup("actions");
1378 ok = ExprResolveLhs(keymap, def->name, &tmp, &field,
1382 ok = SetSymbolsField(key, keymap, field.str, arrayNdx,
1391 SetExplicitGroup(SymbolsInfo *info, KeyInfo *key)
1393 unsigned group = info->explicit_group;
1398 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1401 WARN("For the map %s an explicit group specified\n", info->name);
1402 WARN("but key %s has more than one group defined\n",
1403 longText(key->name));
1404 ACTION("All groups except first one will be ignored\n");
1405 for (i = 1; i < XkbNumKbdGroups; i++)
1407 key->numLevels[i] = 0;
1408 darray_free(key->syms[i]);
1409 darray_free(key->acts[i]);
1413 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1415 key->numLevels[group] = key->numLevels[0];
1416 key->numLevels[0] = 0;
1417 key->syms[group] = key->syms[0];
1418 darray_init(key->syms[0]);
1419 key->symsMapIndex[group] = key->symsMapIndex[0];
1420 darray_init(key->symsMapIndex[0]);
1421 key->symsMapNumEntries[group] = key->symsMapNumEntries[0];
1422 darray_init(key->symsMapNumEntries[0]);
1423 key->acts[group] = key->acts[0];
1424 darray_init(key->acts[0]);
1425 key->types[group] = key->types[0];
1431 HandleSymbolsDef(SymbolsDef *stmt, struct xkb_keymap *keymap,
1437 CopyKeyInfo(&info->dflt, &key, false);
1438 key.defs.merge = stmt->merge;
1439 key.name = KeyNameToLong(stmt->keyName);
1440 if (!HandleSymbolsBody((VarDef *) stmt->symbols, keymap, &key, info))
1446 if (!SetExplicitGroup(info, &key))
1452 if (!AddKeySymbols(info, &key, keymap))
1461 HandleModMapDef(ModMapDef *def, struct xkb_keymap *keymap, SymbolsInfo *info)
1468 if (!LookupModIndex(keymap->ctx, NULL, def->modifier, TypeInt, &rtrn))
1470 ERROR("Illegal modifier map definition\n");
1471 ACTION("Ignoring map for non-modifier \"%s\"\n",
1472 xkb_atom_text(keymap->ctx, def->modifier));
1476 tmp.modifier = rtrn.uval;
1477 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1479 if ((key->op == ExprValue) && (key->type == TypeKeyName))
1481 tmp.haveSymbol = false;
1482 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1484 else if (ExprResolveKeySym(keymap->ctx, key, &rtrn))
1486 tmp.haveSymbol = true;
1487 tmp.u.keySym = rtrn.uval;
1491 ERROR("Modmap entries may contain only key names or keysyms\n");
1492 ACTION("Illegal definition for %s modifier ignored\n",
1493 XkbcModIndexText(tmp.modifier));
1497 ok = AddModMapEntry(info, &tmp) && ok;
1503 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
1504 enum merge_mode merge, SymbolsInfo *info)
1509 info->name = uDupString(file->name);
1513 switch (stmt->stmtType)
1516 if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info))
1519 case StmtSymbolsDef:
1520 if (!HandleSymbolsDef((SymbolsDef *) stmt, keymap, info))
1524 if (!HandleSymbolsVar((VarDef *) stmt, keymap, info))
1528 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
1532 ERROR("Interpretation files may not include other types\n");
1533 ACTION("Ignoring definition of symbol interpretation\n");
1536 case StmtKeycodeDef:
1537 ERROR("Interpretation files may not include other types\n");
1538 ACTION("Ignoring definition of key name\n");
1542 if (!HandleModMapDef((ModMapDef *) stmt, keymap, info))
1546 WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1551 if (info->errorCount > 10)
1554 ERROR("Too many errors\n");
1556 ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1563 * Given a keysym @sym, find the keycode which generates it
1564 * (returned in @kc_rtrn). This is used for example in a modifier
1565 * map definition, such as:
1566 * modifier_map Lock { Caps_Lock };
1567 * where we want to add the Lock modifier to the modmap of the key
1568 * which matches the keysym Caps_Lock.
1569 * Since there can be many keys which generates the keysym, the key
1570 * is chosen first by lowest group in which the keysym appears, than
1571 * by lowest level and than by lowest key code.
1574 FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
1575 xkb_keycode_t *kc_rtrn)
1578 unsigned int group, level, min_group = UINT_MAX, min_level = UINT_MAX;
1580 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++)
1582 for (group = 0; group < XkbKeyNumGroups(keymap, key); group++)
1584 for (level = 0; level < XkbKeyGroupWidth(keymap, key, group);
1587 if (XkbKeyNumSyms(keymap, key, group, level) != 1 ||
1588 (XkbKeySymEntry(keymap, key, group, level))[0] != sym)
1592 * If the keysym was found in a group or level > 0, we must
1593 * keep looking since we might find a key in which the keysym
1594 * is in a lower group or level.
1596 if (group < min_group ||
1597 (group == min_group && level < min_level)) {
1599 if (group == 0 && level == 0) {
1610 return min_group != UINT_MAX;
1614 * Find the given name in the keymap->map->types and return its index.
1616 * @param atom The atom to search for.
1617 * @param type_rtrn Set to the index of the name if found.
1619 * @return true if found, false otherwise.
1622 FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn)
1625 const char *name = xkb_atom_text(keymap->ctx, atom);
1626 struct xkb_key_type *type;
1628 if (keymap && keymap->map) {
1629 darray_foreach(type, keymap->map->types) {
1630 if (strcmp(type->name, name) == 0) {
1641 * Assign a type to the given sym and return the Atom for the type assigned.
1644 * - ONE_LEVEL for width 0/1
1645 * - ALPHABETIC for 2 shift levels, with lower/upercase
1646 * - KEYPAD for keypad keys.
1647 * - TWO_LEVEL for other 2 shift level keys.
1648 * and the same for four level keys.
1650 * @param width Number of sysms in syms.
1651 * @param syms The keysyms for the given key (must be size width).
1652 * @param typeNameRtrn Set to the Atom of the type name.
1654 * @returns true if a type could be found, false otherwise.
1656 * FIXME: I need to take the KeyInfo so I can look at symsMapIndex and
1657 * all that fun stuff rather than just assuming there's always one
1661 FindAutomaticType(struct xkb_keymap *keymap, int width,
1662 const xkb_keysym_t *syms, xkb_atom_t *typeNameRtrn,
1666 if ((width == 1) || (width == 0))
1668 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
1671 else if (width == 2)
1673 if (syms && xkb_keysym_is_lower(syms[0]) &&
1674 xkb_keysym_is_upper(syms[1]))
1676 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
1678 else if (syms && (xkb_keysym_is_keypad(syms[0]) ||
1679 xkb_keysym_is_keypad(syms[1])))
1681 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "KEYPAD");
1686 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
1690 else if (width <= 4)
1692 if (syms && xkb_keysym_is_lower(syms[0]) &&
1693 xkb_keysym_is_upper(syms[1]))
1694 if (xkb_keysym_is_lower(syms[2]) && xkb_keysym_is_upper(syms[3]))
1696 xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_ALPHABETIC");
1698 *typeNameRtrn = xkb_atom_intern(keymap->ctx,
1699 "FOUR_LEVEL_SEMIALPHABETIC");
1701 else if (syms && (xkb_keysym_is_keypad(syms[0]) ||
1702 xkb_keysym_is_keypad(syms[1])))
1703 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_KEYPAD");
1705 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL");
1706 /* XXX: why not set autoType here? */
1708 return ((width >= 0) && (width <= 4));
1712 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1713 * groups, and reduce to one group if all groups are identical anyway.
1716 PrepareKeyDef(KeyInfo * key)
1718 int i, j, width, defined, lastGroup;
1721 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1722 /* get highest group number */
1723 for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1725 if (defined & (1 << i))
1733 /* If there are empty groups between non-empty ones fill them with data */
1734 /* from the first group. */
1735 /* We can make a wrong assumption here. But leaving gaps is worse. */
1736 for (i = lastGroup; i > 0; i--)
1738 if (defined & (1 << i))
1740 width = key->numLevels[0];
1741 if (key->typesDefined & 1)
1743 for (j = 0; j < width; j++)
1745 key->types[i] = key->types[0];
1747 key->typesDefined |= 1 << i;
1749 if ((key->actsDefined & 1) && !darray_empty(key->acts[0]))
1751 darray_copy(key->acts[i], key->acts[0]);
1752 key->actsDefined |= 1 << i;
1754 if ((key->symsDefined & 1) && !darray_empty(key->syms[0]))
1756 darray_copy(key->syms[i], key->syms[0]);
1757 darray_copy(key->symsMapIndex[i], key->symsMapIndex[0]);
1758 darray_copy(key->symsMapNumEntries[i], key->symsMapNumEntries[0]);
1759 key->symsDefined |= 1 << i;
1763 key->numLevels[i] = key->numLevels[0];
1766 /* If all groups are completely identical remove them all */
1767 /* exept the first one. */
1769 for (i = lastGroup; i > 0; i--)
1771 if ((key->numLevels[i] != key->numLevels[0]) ||
1772 (key->types[i] != key->types[0]))
1777 if (!darray_same(key->syms[i], key->syms[0]) &&
1778 (darray_empty(key->syms[i]) || darray_empty(key->syms[0]) ||
1779 darray_size(key->syms[i]) != darray_size(key->syms[0]) ||
1780 memcmp(darray_mem(key->syms[i], 0),
1781 darray_mem(key->syms[0], 0),
1782 sizeof(xkb_keysym_t) * darray_size(key->syms[0]))))
1787 if (!darray_same(key->symsMapIndex[i], key->symsMapIndex[0]) &&
1788 (darray_empty(key->symsMapIndex[i]) ||
1789 darray_empty(key->symsMapIndex[0]) ||
1790 memcmp(darray_mem(key->symsMapIndex[i], 0),
1791 darray_mem(key->symsMapIndex[0], 0),
1792 key->numLevels[0] * sizeof(int))))
1797 if (!darray_same(key->symsMapNumEntries[i], key->symsMapNumEntries[0]) &&
1798 (darray_empty(key->symsMapNumEntries[i]) ||
1799 darray_empty(key->symsMapNumEntries[0]) ||
1800 memcmp(darray_mem(key->symsMapNumEntries[i], 0),
1801 darray_mem(key->symsMapNumEntries[0], 0),
1802 key->numLevels[0] * sizeof(size_t))))
1807 if (!darray_same(key->acts[i], key->acts[0]) &&
1808 (darray_empty(key->acts[i]) || darray_empty(key->acts[0]) ||
1809 memcmp(darray_mem(key->acts[i], 0),
1810 darray_mem(key->acts[0], 0),
1811 key->numLevels[0] * sizeof(union xkb_action))))
1819 for (i = lastGroup; i > 0; i--)
1821 key->numLevels[i] = 0;
1822 darray_free(key->syms[i]);
1823 darray_free(key->symsMapIndex[i]);
1824 darray_free(key->symsMapNumEntries[i]);
1825 darray_free(key->acts[i]);
1828 key->symsDefined &= 1;
1829 key->actsDefined &= 1;
1830 key->typesDefined &= 1;
1835 * Copy the KeyInfo into the keyboard description.
1837 * This function recurses.
1840 CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *key, int start_from)
1844 unsigned int sizeSyms = 0;
1845 unsigned width, tmp, nGroups;
1846 struct xkb_key_type * type;
1847 bool haveActions, autoType, useAlias;
1848 unsigned types[XkbNumKbdGroups];
1849 union xkb_action *outActs;
1850 unsigned int symIndex = 0;
1851 struct xkb_sym_map *sym_map;
1853 useAlias = (start_from == 0);
1855 /* get the keycode for the key. */
1856 if (!FindNamedKey(keymap, key->name, &kc, useAlias,
1857 CreateKeyNames(keymap), start_from))
1859 if ((start_from == 0) && (warningLevel >= 5))
1861 WARN("Key %s not found in keycodes\n", longText(key->name));
1862 ACTION("Symbols ignored\n");
1867 haveActions = false;
1868 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1870 if (((i + 1) > nGroups)
1871 && (((key->symsDefined | key->actsDefined) & (1 << i))
1872 || (key->typesDefined) & (1 << i)))
1874 if (!darray_empty(key->acts[i]))
1877 /* Assign the type to the key, if it is missing. */
1878 if (key->types[i] == XKB_ATOM_NONE)
1880 if (key->dfltType != XKB_ATOM_NONE)
1881 key->types[i] = key->dfltType;
1882 else if (FindAutomaticType(keymap, key->numLevels[i],
1883 darray_mem(key->syms[i], 0),
1884 &key->types[i], &autoType))
1889 if (warningLevel >= 5)
1891 WARN("No automatic type for %d symbols\n",
1892 (unsigned int) key->numLevels[i]);
1893 ACTION("Using %s for the %s key (keycode %d)\n",
1894 xkb_atom_text(keymap->ctx, key->types[i]),
1895 longText(key->name), kc);
1899 if (FindNamedType(keymap, key->types[i], &types[i]))
1901 if (!autoType || key->numLevels[i] > 2)
1902 keymap->server->explicit[kc] |= (1 << i);
1906 if (warningLevel >= 3)
1908 WARN("Type \"%s\" is not defined\n",
1909 xkb_atom_text(keymap->ctx, key->types[i]));
1910 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
1911 longText(key->name), kc);
1913 types[i] = XkbTwoLevelIndex;
1915 /* if the type specifies fewer levels than the key has, shrink the key */
1916 type = &darray_item(keymap->map->types, types[i]);
1917 if (type->num_levels < key->numLevels[i])
1919 if (warningLevel > 0)
1921 WARN("Type \"%s\" has %d levels, but %s has %d symbols\n",
1922 type->name, type->num_levels,
1923 xkb_atom_text(keymap->ctx, key->name), key->numLevels[i]);
1924 ACTION("Ignoring extra symbols\n");
1926 key->numLevels[i] = type->num_levels;
1928 if (key->numLevels[i] > width)
1929 width = key->numLevels[i];
1930 if (type->num_levels > width)
1931 width = type->num_levels;
1932 sizeSyms += darray_size(key->syms[i]);
1935 if (!XkbcResizeKeySyms(keymap, kc, sizeSyms))
1937 WSGO("Could not enlarge symbols for %s (keycode %d)\n",
1938 longText(key->name), kc);
1943 outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups);
1944 if (outActs == NULL)
1946 WSGO("Could not enlarge actions for %s (key %d)\n",
1947 longText(key->name), kc);
1950 keymap->server->explicit[kc] |= XkbExplicitInterpretMask;
1955 sym_map = &darray_item(keymap->map->key_sym_map, kc);
1957 if (key->defs.defined & _Key_GroupInfo)
1960 i = sym_map->group_info;
1962 sym_map->group_info = XkbSetNumGroups(i, nGroups);
1963 sym_map->width = width;
1964 sym_map->sym_index = uTypedCalloc(nGroups * width, int);
1965 sym_map->num_syms = uTypedCalloc(nGroups * width, unsigned int);
1967 for (i = 0; i < nGroups; i++)
1969 /* assign kt_index[i] to the index of the type in map->types.
1970 * kt_index[i] may have been set by a previous run (if we have two
1971 * layouts specified). Let's not overwrite it with the ONE_LEVEL
1972 * default group if we dont even have keys for this group anyway.
1974 * FIXME: There should be a better fix for this.
1976 if (key->numLevels[i])
1977 sym_map->kt_index[i] = types[i];
1978 if (!darray_empty(key->syms[i]))
1980 /* fill key to "width" symbols*/
1981 for (tmp = 0; tmp < width; tmp++)
1983 if (tmp < key->numLevels[i] &&
1984 darray_item(key->symsMapNumEntries[i], tmp) != 0)
1986 memcpy(darray_mem(sym_map->syms, symIndex),
1987 darray_mem(key->syms[i],
1988 darray_item(key->symsMapIndex[i], tmp)),
1989 darray_item(key->symsMapNumEntries[i], tmp) * sizeof(xkb_keysym_t));
1990 sym_map->sym_index[(i * width) + tmp] = symIndex;
1991 sym_map->num_syms[(i * width) + tmp] =
1992 darray_item(key->symsMapNumEntries[i], tmp);
1993 symIndex += sym_map->num_syms[(i * width) + tmp];
1997 sym_map->sym_index[(i * width) + tmp] = -1;
1998 sym_map->num_syms[(i * width) + tmp] = 0;
2000 if (outActs != NULL && !darray_empty(key->acts[i]))
2002 if (tmp < key->numLevels[i])
2003 outActs[tmp] = darray_item(key->acts[i], tmp);
2005 outActs[tmp].type = XkbSA_NoAction;
2010 switch (key->behavior.type & XkbKB_OpMask)
2015 keymap->server->behaviors[kc] = key->behavior;
2016 keymap->server->explicit[kc] |= XkbExplicitBehaviorMask;
2019 if (key->defs.defined & _Key_VModMap)
2021 keymap->server->vmodmap[kc] = key->vmodmap;
2022 keymap->server->explicit[kc] |= XkbExplicitVModMapMask;
2024 if (key->repeat != RepeatUndefined)
2026 if (key->repeat == RepeatYes)
2027 keymap->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2029 keymap->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2030 keymap->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2033 if (nGroups > keymap->ctrls->num_groups)
2034 keymap->ctrls->num_groups = nGroups;
2036 /* do the same thing for the next key */
2037 CopySymbolsDef(keymap, key, kc + 1);
2042 CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry)
2046 if (!entry->haveSymbol &&
2047 !FindNamedKey(keymap, entry->u.keyName, &kc, true,
2048 CreateKeyNames(keymap), 0))
2050 if (warningLevel >= 5)
2052 WARN("Key %s not found in keycodes\n",
2053 longText(entry->u.keyName));
2054 ACTION("Modifier map entry for %s not updated\n",
2055 XkbcModIndexText(entry->modifier));
2059 else if (entry->haveSymbol &&
2060 !FindKeyForSymbol(keymap, entry->u.keySym, &kc))
2062 if (warningLevel > 5)
2064 WARN("Key \"%s\" not found in symbol map\n",
2065 XkbcKeysymText(entry->u.keySym));
2066 ACTION("Modifier map entry for %s not updated\n",
2067 XkbcModIndexText(entry->modifier));
2071 keymap->map->modmap[kc] |= (1 << entry->modifier);
2076 * Handle the xkb_symbols section of an xkb file.
2078 * @param file The parsed xkb_symbols section of the xkb file.
2079 * @param keymap Handle to the keyboard description to store the symbols in.
2080 * @param merge Merge strategy (e.g. MERGE_OVERRIDE).
2083 CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
2089 InitSymbolsInfo(&info, keymap);
2090 info.dflt.defs.fileID = file->id;
2091 info.dflt.defs.merge = merge;
2093 HandleSymbolsFile(file, keymap, merge, &info);
2095 if (darray_empty(info.keys))
2098 if (info.errorCount != 0)
2101 /* alloc memory in the xkb struct */
2102 if (XkbcAllocNames(keymap, XkbGroupNamesMask, 0) != Success) {
2103 WSGO("Can not allocate names in CompileSymbols\n");
2104 ACTION("Symbols not added\n");
2108 if (XkbcAllocClientMap(keymap, XkbKeySymsMask | XkbModifierMapMask, 0)
2110 WSGO("Could not allocate client map in CompileSymbols\n");
2111 ACTION("Symbols not added\n");
2115 if (XkbcAllocServerMap(keymap, XkbAllServerInfoMask, 32) != Success) {
2116 WSGO("Could not allocate server map in CompileSymbols\n");
2117 ACTION("Symbols not added\n");
2121 if (XkbcAllocControls(keymap) != Success) {
2122 WSGO("Could not allocate controls in CompileSymbols\n");
2123 ACTION("Symbols not added\n");
2128 keymap->names->symbols = strdup(info.name);
2130 /* now copy info into xkb. */
2131 ApplyAliases(keymap, &info.aliases);
2133 for (i = 0; i < XkbNumKbdGroups; i++) {
2134 if (info.groupNames[i] != XKB_ATOM_NONE) {
2135 free(keymap->names->groups[i]);
2136 keymap->names->groups[i] = xkb_atom_strdup(keymap->ctx,
2137 info.groupNames[i]);
2142 darray_foreach(key, info.keys)
2146 darray_foreach(key, info.keys)
2147 if (!CopySymbolsDef(keymap, key, 0))
2150 if (warningLevel > 3) {
2151 for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
2152 if (darray_item(keymap->names->keys, i).name[0] == '\0')
2155 if (XkbKeyNumGroups(keymap, i) < 1) {
2157 memcpy(buf, darray_item(keymap->names->keys, i).name, 4);
2159 WARN("No symbols defined for <%s> (keycode %d)\n", buf, i);
2165 ModMapEntry *mm, *next;
2166 for (mm = info.modMap; mm != NULL; mm = next) {
2167 if (!CopyModMapDef(keymap, mm))
2169 next = (ModMapEntry *) mm->defs.next;
2173 FreeSymbolsInfo(&info);
2177 FreeSymbolsInfo(&info);