1 /************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
27 #include "xkbcomp-priv.h"
28 #include "parseutils.h"
34 /***====================================================================***/
36 /* Needed to work with the typechecker. */
37 typedef darray(xkb_keysym_t) darray_xkb_keysym_t;
41 #define RepeatUndefined ~((unsigned)0)
43 #define _Key_Syms (1<<0)
44 #define _Key_Acts (1<<1)
45 #define _Key_Repeat (1<<2)
46 #define _Key_Behavior (1<<3)
47 #define _Key_Type_Dflt (1<<4)
48 #define _Key_Types (1<<5)
49 #define _Key_GroupInfo (1<<6)
50 #define _Key_VModMap (1<<7)
52 typedef struct _KeyInfo
55 unsigned long name; /* the 4 chars of the key name, as long */
56 unsigned char groupInfo;
57 unsigned char typesDefined;
58 unsigned char symsDefined;
59 unsigned char actsDefined;
60 unsigned int numLevels[XkbNumKbdGroups];
62 /* syms[group] -> Single array for all the keysyms in the group. */
63 darray_xkb_keysym_t syms[XkbNumKbdGroups];
65 * symsMapIndex[group][level] -> The index from which the syms for
66 * the level begin in the syms[group] array. Remember each keycode
67 * can have multiple keysyms in each level (that is, each key press
68 * can result in multiple keysyms).
70 darray(int) symsMapIndex[XkbNumKbdGroups];
72 * symsMapNumEntries[group][level] -> How many syms are in
73 * syms[group][symsMapIndex[group][level]].
75 unsigned int *symsMapNumEntries[XkbNumKbdGroups];
77 union xkb_action *acts[XkbNumKbdGroups];
78 xkb_atom_t types[XkbNumKbdGroups];
80 struct xkb_behavior behavior;
81 unsigned short vmodmap;
86 * Init the given key info to sane values.
89 InitKeyInfo(KeyInfo * info)
92 static const char dflt[4] = "*";
94 info->defs.defined = 0;
95 info->defs.fileID = 0;
96 info->defs.merge = MergeOverride;
97 info->defs.next = NULL;
98 info->name = KeyNameToLong(dflt);
100 info->typesDefined = info->symsDefined = info->actsDefined = 0;
101 for (i = 0; i < XkbNumKbdGroups; i++)
103 info->numLevels[i] = 0;
104 info->types[i] = XKB_ATOM_NONE;
105 darray_init(info->syms[i]);
106 darray_init(info->symsMapIndex[i]);
107 info->symsMapNumEntries[i] = NULL;
108 info->acts[i] = NULL;
110 info->dfltType = XKB_ATOM_NONE;
111 info->behavior.type = XkbKB_Default;
112 info->behavior.data = 0;
114 info->repeat = RepeatUndefined;
118 * Free memory associated with this key info and reset to sane values.
121 FreeKeyInfo(KeyInfo * info)
125 info->defs.defined = 0;
126 info->defs.fileID = 0;
127 info->defs.merge = MergeOverride;
128 info->defs.next = NULL;
130 info->typesDefined = info->symsDefined = info->actsDefined = 0;
131 for (i = 0; i < XkbNumKbdGroups; i++)
133 info->numLevels[i] = 0;
134 info->types[i] = XKB_ATOM_NONE;
135 darray_free(info->syms[i]);
136 darray_free(info->symsMapIndex[i]);
137 free(info->symsMapNumEntries[i]);
138 info->symsMapNumEntries[i] = NULL;
140 info->acts[i] = NULL;
142 info->dfltType = XKB_ATOM_NONE;
143 info->behavior.type = XkbKB_Default;
144 info->behavior.data = 0;
146 info->repeat = RepeatUndefined;
150 * Copy old into new, optionally reset old to 0.
151 * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
152 * newly allocated and new points to the new memory areas.
155 CopyKeyInfo(KeyInfo * old, KeyInfo * new, bool clearOld)
160 new->defs.next = NULL;
163 for (i = 0; i < XkbNumKbdGroups; i++)
165 old->numLevels[i] = 0;
166 darray_init(old->symsMapIndex[i]);
167 old->symsMapNumEntries[i] = NULL;
168 darray_init(old->syms[i]);
175 for (i = 0; i < XkbNumKbdGroups; i++)
177 width = new->numLevels[i];
178 if (!darray_empty(old->syms[i]))
180 darray_copy(new->syms[i], old->syms[i]);
181 darray_copy(new->symsMapIndex[i], old->symsMapIndex[i]);
182 new->symsMapNumEntries[i] = uTypedCalloc(width, unsigned int);
183 if (!new->symsMapNumEntries[i])
185 darray_free(new->syms[i]);
186 darray_free(new->symsMapIndex[i]);
187 new->numLevels[i] = 0;
191 memcpy(new->symsMapNumEntries[i], old->symsMapNumEntries[i],
192 width * sizeof(unsigned int));
194 if (old->acts[i] != NULL)
196 new->acts[i] = uTypedCalloc(width, union xkb_action);
199 darray_free(new->syms[i]);
200 darray_free(new->symsMapIndex[i]);
201 free(new->symsMapNumEntries[i]);
202 new->symsMapNumEntries[i] = NULL;
203 new->numLevels[i] = 0;
206 memcpy(new->acts[i], old->acts[i],
207 width * sizeof(union xkb_action));
214 /***====================================================================***/
216 typedef struct _ModMapEntry
223 unsigned long keyName;
228 typedef struct _SymbolsInfo
230 char *name; /* e.g. pc+us+inet(evdev) */
234 unsigned explicit_group;
235 darray(KeyInfo) keys;
239 xkb_atom_t groupNames[XkbNumKbdGroups];
246 InitSymbolsInfo(SymbolsInfo * info, struct xkb_keymap *keymap)
251 info->explicit_group = 0;
252 info->errorCount = 0;
254 info->merge = MergeOverride;
255 darray_init(info->keys);
256 darray_growalloc(info->keys, 110);
258 for (i = 0; i < XkbNumKbdGroups; i++)
259 info->groupNames[i] = XKB_ATOM_NONE;
260 InitKeyInfo(&info->dflt);
261 InitVModInfo(&info->vmods, keymap);
263 info->aliases = NULL;
267 FreeSymbolsInfo(SymbolsInfo * info)
272 darray_foreach(key, info->keys)
274 darray_free(info->keys);
276 ClearCommonInfo(&info->modMap->defs);
278 ClearAliases(&info->aliases);
279 memset(info, 0, sizeof(SymbolsInfo));
283 ResizeKeyGroup(KeyInfo * key, unsigned int group, unsigned int numLevels,
284 unsigned sizeSyms, bool forceActions)
288 if (darray_size(key->syms[group]) < sizeSyms)
289 darray_resize0(key->syms[group], sizeSyms);
291 if (darray_empty(key->symsMapIndex[group]) ||
292 key->numLevels[group] < numLevels)
294 darray_resize(key->symsMapIndex[group], numLevels);
295 for (i = key->numLevels[group]; i < numLevels; i++)
296 darray_item(key->symsMapIndex[group], i) = -1;
298 if (!key->symsMapNumEntries[group] || key->numLevels[group] < numLevels)
300 key->symsMapNumEntries[group] =
301 uTypedRecalloc(key->symsMapNumEntries[group],
302 key->numLevels[group],
305 if (!key->symsMapNumEntries[group])
309 (key->numLevels[group] < numLevels || (key->acts[group] == NULL))) ||
310 (key->numLevels[group] < numLevels && (key->acts[group] != NULL)))
312 key->acts[group] = uTypedRecalloc(key->acts[group],
313 key->numLevels[group],
316 if (!key->acts[group])
319 if (key->numLevels[group] < numLevels)
320 key->numLevels[group] = numLevels;
324 enum key_group_selector {
331 MergeKeyGroups(SymbolsInfo * info,
332 KeyInfo * into, KeyInfo * from, unsigned group)
334 darray_xkb_keysym_t resultSyms;
335 enum key_group_selector using = NONE;
336 union xkb_action *resultActs;
337 unsigned int resultWidth;
338 unsigned int resultSize = 0;
341 bool report, clobber;
343 clobber = (from->defs.merge != MergeAugment);
345 report = (warningLevel > 9) ||
346 ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
348 darray_init(resultSyms);
350 if (into->numLevels[group] >= from->numLevels[group])
352 resultActs = into->acts[group];
353 resultWidth = into->numLevels[group];
357 resultActs = from->acts[group];
358 resultWidth = from->numLevels[group];
359 darray_resize(into->symsMapIndex[group], from->numLevels[group]);
360 into->symsMapNumEntries[group] =
361 uTypedRecalloc(into->symsMapNumEntries[group],
362 into->numLevels[group],
363 from->numLevels[group],
365 if (!into->symsMapNumEntries[group])
367 WSGO("Could not allocate level indices for key info merge\n");
368 ACTION("Group %d of key %s not merged\n", group,
369 longText(into->name));
373 for (i = into->numLevels[group]; i < from->numLevels[group]; i++)
374 darray_item(into->symsMapIndex[group], i) = -1;
377 if ((resultActs == NULL) && (into->acts[group] || from->acts[group]))
379 resultActs = uTypedCalloc(resultWidth, union xkb_action);
382 WSGO("Could not allocate actions for group merge\n");
383 ACTION("Group %d of key %s not merged\n", group,
384 longText(into->name));
387 for (i = 0; i < resultWidth; i++)
389 union xkb_action *fromAct, *toAct;
390 fromAct = (from->acts[group] ? &from->acts[group][i] : NULL);
391 toAct = (into->acts[group] ? &into->acts[group][i] : NULL);
392 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
395 resultActs[i] = *toAct;
397 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
398 && (fromAct != NULL))
400 resultActs[i] = *fromAct;
404 union xkb_action *use, *ignore;
418 ("Multiple actions for level %d/group %d on key %s\n",
419 i + 1, group + 1, longText(into->name));
420 ACTION("Using %s, ignoring %s\n",
421 XkbcActionTypeText(use->type),
422 XkbcActionTypeText(ignore->type));
425 resultActs[i] = *use;
430 for (i = 0; i < resultWidth; i++)
432 unsigned int fromSize = 0;
435 if (from->symsMapNumEntries[group] && (i < from->numLevels[group]))
436 fromSize = from->symsMapNumEntries[group][i];
437 if (into->symsMapNumEntries[group] && (i < into->numLevels[group]))
438 toSize = into->symsMapNumEntries[group][i];
442 resultSize += toSize;
445 else if (toSize == 0 || clobber)
447 resultSize += fromSize;
452 resultSize += toSize;
462 resultSyms = from->syms[group];
465 else if (using == TO)
467 resultSyms = into->syms[group];
471 darray_resize0(resultSyms, resultSize);
473 for (i = 0; i < resultWidth; i++)
475 enum key_group_selector use = NONE;
476 unsigned int fromSize = 0;
477 unsigned int toSize = 0;
479 if (i < from->numLevels[group])
480 fromSize = from->symsMapNumEntries[group][i];
481 if (i < into->numLevels[group])
482 toSize = into->symsMapNumEntries[group][i];
484 if (fromSize == 0 && toSize == 0)
486 darray_item(into->symsMapIndex[group], i) = -1;
487 into->symsMapNumEntries[group][i] = 0;
493 else if (toSize == 0 || clobber)
498 if (toSize && fromSize && report)
500 INFO("Multiple symbols for group %d, level %d on key %s\n",
501 group + 1, i + 1, longText(into->name));
502 ACTION("Using %s, ignoring %s\n",
503 (use == FROM ? "from" : "to"),
504 (use == FROM ? "to" : "from"));
509 memcpy(darray_mem(resultSyms, cur_idx),
510 darray_mem(from->syms[group],
511 darray_item(from->symsMapIndex[group], i)),
512 from->symsMapNumEntries[group][i] * sizeof(xkb_keysym_t));
513 darray_item(into->symsMapIndex[group], i) = cur_idx;
514 into->symsMapNumEntries[group][i] =
515 from->symsMapNumEntries[group][i];
519 memcpy(darray_mem(resultSyms, cur_idx),
520 darray_mem(into->syms[group],
521 darray_item(into->symsMapIndex[group], i)),
522 into->symsMapNumEntries[group][i] * sizeof(xkb_keysym_t));
523 darray_item(into->symsMapIndex[group], i) = cur_idx;
525 cur_idx += into->symsMapNumEntries[group][i];
529 if (resultActs != into->acts[group])
530 free(into->acts[group]);
531 if (resultActs != from->acts[group])
532 free(from->acts[group]);
533 into->numLevels[group] = resultWidth;
534 if (!darray_same(resultSyms, into->syms[group]))
535 darray_free(into->syms[group]);
536 into->syms[group] = resultSyms;
537 if (!darray_same(resultSyms, from->syms[group]))
538 darray_free(from->syms[group]);
539 darray_init(from->syms[group]);
540 darray_free(from->symsMapIndex[group]);
541 free(from->symsMapNumEntries[group]);
542 from->symsMapNumEntries[group] = NULL;
543 into->acts[group] = resultActs;
544 from->acts[group] = NULL;
545 if (!darray_empty(into->syms[group]))
546 into->symsDefined |= (1 << group);
547 from->symsDefined &= ~(1 << group);
548 into->actsDefined |= (1 << group);
549 from->actsDefined &= ~(1 << group);
555 MergeKeys(SymbolsInfo *info, struct xkb_keymap *keymap,
556 KeyInfo *into, KeyInfo *from)
559 unsigned collide = 0;
562 if (from->defs.merge == MergeReplace)
564 for (i = 0; i < XkbNumKbdGroups; i++)
566 if (into->numLevels[i] != 0)
568 darray_free(into->syms[i]);
573 memset(from, 0, sizeof(KeyInfo));
576 report = ((warningLevel > 9) ||
577 ((into->defs.fileID == from->defs.fileID)
578 && (warningLevel > 0)));
579 for (i = 0; i < XkbNumKbdGroups; i++)
581 if (from->numLevels[i] > 0)
583 if (into->numLevels[i] == 0)
585 into->numLevels[i] = from->numLevels[i];
586 into->syms[i] = from->syms[i];
587 into->symsMapIndex[i] = from->symsMapIndex[i];
588 into->symsMapNumEntries[i] = from->symsMapNumEntries[i];
589 into->acts[i] = from->acts[i];
590 into->symsDefined |= (1 << i);
591 darray_init(from->syms[i]);
592 darray_init(from->symsMapIndex[i]);
593 from->symsMapNumEntries[i] = NULL;
594 from->acts[i] = NULL;
595 from->numLevels[i] = 0;
596 from->symsDefined &= ~(1 << i);
597 if (!darray_empty(into->syms[i]))
598 into->defs.defined |= _Key_Syms;
600 into->defs.defined |= _Key_Acts;
606 if (!darray_empty(into->syms[i]))
607 collide |= _Key_Syms;
609 collide |= _Key_Acts;
611 MergeKeyGroups(info, into, from, (unsigned) i);
614 if (from->types[i] != XKB_ATOM_NONE)
616 if ((into->types[i] != XKB_ATOM_NONE) && report &&
617 (into->types[i] != from->types[i]))
619 xkb_atom_t use, ignore;
620 collide |= _Key_Types;
621 if (from->defs.merge != MergeAugment)
623 use = from->types[i];
624 ignore = into->types[i];
628 use = into->types[i];
629 ignore = from->types[i];
632 ("Multiple definitions for group %d type of key %s\n",
633 i, longText(into->name));
634 ACTION("Using %s, ignoring %s\n",
635 xkb_atom_text(keymap->ctx, use),
636 xkb_atom_text(keymap->ctx, ignore));
638 if ((from->defs.merge != MergeAugment)
639 || (into->types[i] == XKB_ATOM_NONE))
641 into->types[i] = from->types[i];
645 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
647 into->behavior = from->behavior;
648 into->defs.defined |= _Key_Behavior;
650 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
652 into->vmodmap = from->vmodmap;
653 into->defs.defined |= _Key_VModMap;
655 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
657 into->repeat = from->repeat;
658 into->defs.defined |= _Key_Repeat;
660 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
662 into->dfltType = from->dfltType;
663 into->defs.defined |= _Key_Type_Dflt;
665 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
667 into->groupInfo = from->groupInfo;
668 into->defs.defined |= _Key_GroupInfo;
672 WARN("Symbol map for key %s redefined\n",
673 longText(into->name));
674 ACTION("Using %s definition for conflicting fields\n",
675 (from->defs.merge == MergeAugment ? "first" : "last"));
681 AddKeySymbols(SymbolsInfo *info, KeyInfo *key, struct xkb_keymap *keymap)
683 unsigned long real_name;
686 darray_foreach(iter, info->keys)
687 if (iter->name == key->name)
688 return MergeKeys(info, keymap, iter, key);
690 if (FindKeyNameForAlias(keymap, key->name, &real_name))
691 darray_foreach(iter, info->keys)
692 if (iter->name == real_name)
693 return MergeKeys(info, keymap, iter, key);
695 darray_resize0(info->keys, darray_size(info->keys) + 1);
696 new = &darray_item(info->keys, darray_size(info->keys) - 1);
697 return CopyKeyInfo(key, new, true);
701 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
706 clobber = (new->defs.merge != MergeAugment);
707 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
709 if (new->haveSymbol && mm->haveSymbol
710 && (new->u.keySym == mm->u.keySym))
712 unsigned use, ignore;
713 if (mm->modifier != new->modifier)
718 ignore = mm->modifier;
723 ignore = new->modifier;
726 ("%s added to symbol map for multiple modifiers\n",
727 XkbcKeysymText(new->u.keySym));
728 ACTION("Using %s, ignoring %s.\n",
729 XkbcModIndexText(use),
730 XkbcModIndexText(ignore));
735 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
736 (new->u.keyName == mm->u.keyName))
738 unsigned use, ignore;
739 if (mm->modifier != new->modifier)
744 ignore = mm->modifier;
749 ignore = new->modifier;
751 ERROR("Key %s added to map for multiple modifiers\n",
752 longText(new->u.keyName));
753 ACTION("Using %s, ignoring %s.\n",
754 XkbcModIndexText(use),
755 XkbcModIndexText(ignore));
761 mm = uTypedAlloc(ModMapEntry);
764 WSGO("Could not allocate modifier map entry\n");
765 ACTION("Modifier map for %s will be incomplete\n",
766 XkbcModIndexText(new->modifier));
770 mm->defs.next = &info->modMap->defs;
775 /***====================================================================***/
778 MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
779 unsigned merge, struct xkb_keymap *keymap)
784 if (from->errorCount > 0)
786 into->errorCount += from->errorCount;
789 if (into->name == NULL)
791 into->name = from->name;
794 for (i = 0; i < XkbNumKbdGroups; i++)
796 if (from->groupNames[i] != XKB_ATOM_NONE)
798 if ((merge != MergeAugment) ||
799 (into->groupNames[i] == XKB_ATOM_NONE))
800 into->groupNames[i] = from->groupNames[i];
804 darray_foreach(key, from->keys) {
805 if (merge != MergeDefault)
806 key->defs.merge = merge;
808 if (!AddKeySymbols(into, key, keymap))
812 if (from->modMap != NULL)
814 ModMapEntry *mm, *next;
815 for (mm = from->modMap; mm != NULL; mm = next)
817 if (merge != MergeDefault)
818 mm->defs.merge = merge;
819 if (!AddModMapEntry(into, mm))
821 next = (ModMapEntry *) mm->defs.next;
826 if (!MergeAliases(&into->aliases, &from->aliases, merge))
831 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
832 unsigned merge, SymbolsInfo *info);
835 HandleIncludeSymbols(IncludeStmt *stmt, struct xkb_keymap *keymap,
840 SymbolsInfo included;
844 if ((stmt->file == NULL) && (stmt->map == NULL))
848 memset(info, 0, sizeof(SymbolsInfo));
850 else if (ProcessIncludeFile(keymap->ctx, stmt, XkmSymbolsIndex, &rtrn,
853 InitSymbolsInfo(&included, keymap);
854 included.fileID = included.dflt.defs.fileID = rtrn->id;
855 included.merge = included.dflt.defs.merge = MergeOverride;
858 included.explicit_group = atoi(stmt->modifier) - 1;
862 included.explicit_group = info->explicit_group;
864 HandleSymbolsFile(rtrn, keymap, MergeOverride, &included);
865 if (stmt->stmt != NULL)
868 included.name = stmt->stmt;
875 info->errorCount += 10;
878 if ((stmt->next != NULL) && (included.errorCount < 1))
882 SymbolsInfo next_incl;
884 for (next = stmt->next; next != NULL; next = next->next)
886 if ((next->file == NULL) && (next->map == NULL))
889 MergeIncludedSymbols(&included, info, next->merge, keymap);
890 FreeSymbolsInfo(info);
892 else if (ProcessIncludeFile(keymap->ctx, next, XkmSymbolsIndex,
895 InitSymbolsInfo(&next_incl, keymap);
896 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
897 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride;
900 next_incl.explicit_group = atoi(next->modifier) - 1;
904 next_incl.explicit_group = info->explicit_group;
906 HandleSymbolsFile(rtrn, keymap, MergeOverride, &next_incl);
907 MergeIncludedSymbols(&included, &next_incl, op, keymap);
908 FreeSymbolsInfo(&next_incl);
913 info->errorCount += 10;
914 FreeSymbolsInfo(&included);
921 info->errorCount += included.errorCount;
927 MergeIncludedSymbols(info, &included, newMerge, keymap);
928 FreeSymbolsInfo(&included);
930 return (info->errorCount == 0);
937 GetGroupIndex(KeyInfo *key, struct xkb_keymap *keymap,
938 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
948 if (arrayNdx == NULL)
953 defined = key->symsDefined;
955 defined = key->actsDefined;
957 for (i = 0; i < XkbNumKbdGroups; i++)
959 if ((defined & (1 << i)) == 0)
965 ERROR("Too many groups of %s for key %s (max %d)\n", name,
966 longText(key->name), XkbNumKbdGroups + 1);
967 ACTION("Ignoring %s defined for extra groups\n", name);
970 if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp))
972 ERROR("Illegal group index for %s of key %s\n", name,
973 longText(key->name));
974 ACTION("Definition with non-integer array index ignored\n");
977 *ndx_rtrn = tmp.uval - 1;
982 AddSymbolsToKey(KeyInfo *key, struct xkb_keymap *keymap,
983 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
985 unsigned ndx, nSyms, nLevels;
989 if (!GetGroupIndex(key, keymap, arrayNdx, SYMBOLS, &ndx))
993 key->symsDefined |= (1 << ndx);
996 if (value->op != ExprKeysymList)
998 ERROR("Expected a list of symbols, found %s\n", exprOpText(value->op));
999 ACTION("Ignoring symbols for group %d of %s\n", ndx + 1,
1000 longText(key->name));
1003 if (!darray_empty(key->syms[ndx]))
1005 ERROR("Symbols for key %s, group %d already defined\n",
1006 longText(key->name), ndx + 1);
1007 ACTION("Ignoring duplicate definition\n");
1010 nSyms = darray_size(value->value.list.syms);
1011 nLevels = darray_size(value->value.list.symsMapIndex);
1012 if ((key->numLevels[ndx] < nSyms || darray_empty(key->syms[ndx])) &&
1013 (!ResizeKeyGroup(key, ndx, nLevels, nSyms, false)))
1015 WSGO("Could not resize group %d of key %s to contain %d levels\n",
1016 ndx + 1, longText(key->name), nSyms);
1017 ACTION("Symbols lost\n");
1020 key->symsDefined |= (1 << ndx);
1021 for (i = 0; i < nLevels; i++) {
1022 darray_item(key->symsMapIndex[ndx], i) =
1023 darray_item(value->value.list.symsMapIndex, i);
1024 key->symsMapNumEntries[ndx][i] =
1025 darray_item(value->value.list.symsNumEntries, i);
1027 for (j = 0; j < key->symsMapNumEntries[ndx][i]; j++) {
1028 /* FIXME: What's abort() doing here? */
1029 if (darray_item(key->symsMapIndex[ndx], i) + j >= nSyms)
1031 if (!LookupKeysym(darray_item(value->value.list.syms,
1032 darray_item(value->value.list.symsMapIndex, i) + j),
1033 &darray_item(key->syms[ndx],
1034 darray_item(key->symsMapIndex[ndx], i) + j))) {
1035 WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n",
1036 darray_item(value->value.list.syms, i),
1037 longText(key->name),
1039 xkb_atom_text(keymap->ctx, info->groupNames[ndx]), nSyms);
1041 darray_item(key->syms[ndx],
1042 darray_item(key->symsMapIndex[ndx], i) + j) = XKB_KEY_NoSymbol;
1043 darray_item(key->symsMapIndex[ndx], i) = -1;
1044 key->symsMapNumEntries[ndx][i] = 0;
1047 if (key->symsMapNumEntries[ndx][i] == 1 &&
1048 darray_item(key->syms[ndx],
1049 darray_item(key->symsMapIndex[ndx], i) + j) == XKB_KEY_NoSymbol) {
1050 darray_item(key->symsMapIndex[ndx], i) = -1;
1051 key->symsMapNumEntries[ndx][i] = 0;
1055 for (j = key->numLevels[ndx] - 1;
1056 j >= 0 && key->symsMapNumEntries[ndx][j] == 0; j--)
1057 key->numLevels[ndx]--;
1062 AddActionsToKey(KeyInfo *key, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1063 ExprDef *value, SymbolsInfo *info)
1066 unsigned ndx, nActs;
1068 struct xkb_any_action *toAct;
1070 if (!GetGroupIndex(key, keymap, arrayNdx, ACTIONS, &ndx))
1075 key->actsDefined |= (1 << ndx);
1078 if (value->op != ExprActionList)
1080 WSGO("Bad expression type (%d) for action list value\n", value->op);
1081 ACTION("Ignoring actions for group %d of %s\n", ndx,
1082 longText(key->name));
1085 if (key->acts[ndx] != NULL)
1087 WSGO("Actions for key %s, group %d already defined\n",
1088 longText(key->name), ndx);
1091 for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1093 act = (ExprDef *) act->common.next;
1097 WSGO("Action list but not actions in AddActionsToKey\n");
1100 if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1101 (!ResizeKeyGroup(key, ndx, nActs, nActs, true)))
1103 WSGO("Could not resize group %d of key %s\n", ndx,
1104 longText(key->name));
1105 ACTION("Actions lost\n");
1108 key->actsDefined |= (1 << ndx);
1110 toAct = (struct xkb_any_action *) key->acts[ndx];
1111 act = value->value.child;
1112 for (i = 0; i < nActs; i++, toAct++)
1114 if (!HandleActionDef(act, keymap, toAct, info->action))
1116 ERROR("Illegal action definition for %s\n",
1117 longText(key->name));
1118 ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1120 act = (ExprDef *) act->common.next;
1125 static const LookupEntry lockingEntries[] = {
1126 {"true", XkbKB_Lock},
1127 {"yes", XkbKB_Lock},
1129 {"false", XkbKB_Default},
1130 {"no", XkbKB_Default},
1131 {"off", XkbKB_Default},
1132 {"permanent", XkbKB_Lock | XkbKB_Permanent},
1136 static const LookupEntry repeatEntries[] = {
1137 {"true", RepeatYes},
1140 {"false", RepeatNo},
1143 {"default", RepeatUndefined},
1148 SetSymbolsField(KeyInfo *key, struct xkb_keymap *keymap, char *field,
1149 ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info)
1154 if (strcasecmp(field, "type") == 0)
1157 if ((!ExprResolveString(keymap->ctx, value, &tmp))
1158 && (warningLevel > 0))
1160 WARN("The type field of a key symbol map must be a string\n");
1161 ACTION("Ignoring illegal type definition\n");
1163 if (arrayNdx == NULL)
1165 key->dfltType = xkb_atom_intern(keymap->ctx, tmp.str);
1166 key->defs.defined |= _Key_Type_Dflt;
1168 else if (!ExprResolveGroup(keymap->ctx, arrayNdx, &ndx))
1170 ERROR("Illegal group index for type of key %s\n",
1171 longText(key->name));
1172 ACTION("Definition with non-integer array index ignored\n");
1178 key->types[ndx.uval - 1] = xkb_atom_intern(keymap->ctx, tmp.str);
1179 key->typesDefined |= (1 << (ndx.uval - 1));
1183 else if (strcasecmp(field, "symbols") == 0)
1184 return AddSymbolsToKey(key, keymap, arrayNdx, value, info);
1185 else if (strcasecmp(field, "actions") == 0)
1186 return AddActionsToKey(key, keymap, arrayNdx, value, info);
1187 else if ((strcasecmp(field, "vmods") == 0) ||
1188 (strcasecmp(field, "virtualmods") == 0) ||
1189 (strcasecmp(field, "virtualmodifiers") == 0))
1191 ok = ExprResolveVModMask(value, &tmp, keymap);
1194 key->vmodmap = (tmp.uval >> 8);
1195 key->defs.defined |= _Key_VModMap;
1199 ERROR("Expected a virtual modifier mask, found %s\n",
1200 exprOpText(value->op));
1201 ACTION("Ignoring virtual modifiers definition for key %s\n",
1202 longText(key->name));
1205 else if ((strcasecmp(field, "locking") == 0) ||
1206 (strcasecmp(field, "lock") == 0) ||
1207 (strcasecmp(field, "locks") == 0))
1209 ok = ExprResolveEnum(keymap->ctx, value, &tmp, lockingEntries);
1211 key->behavior.type = tmp.uval;
1212 key->defs.defined |= _Key_Behavior;
1214 else if ((strcasecmp(field, "radiogroup") == 0) ||
1215 (strcasecmp(field, "permanentradiogroup") == 0) ||
1216 (strcasecmp(field, "allownone") == 0))
1218 ERROR("Radio groups not supported\n");
1219 ACTION("Ignoring radio group specification for key %s\n", longText(key->name));
1222 else if (uStrCasePrefix("overlay", field) ||
1223 uStrCasePrefix("permanentoverlay", field))
1225 ERROR("Overlays not supported\n");
1226 ACTION("Ignoring overlay specification for key %s\n", longText(key->name));
1228 else if ((strcasecmp(field, "repeating") == 0) ||
1229 (strcasecmp(field, "repeats") == 0) ||
1230 (strcasecmp(field, "repeat") == 0))
1232 ok = ExprResolveEnum(keymap->ctx, value, &tmp, repeatEntries);
1235 ERROR("Illegal repeat setting for %s\n",
1236 longText(key->name));
1237 ACTION("Non-boolean repeat setting ignored\n");
1240 key->repeat = tmp.uval;
1241 key->defs.defined |= _Key_Repeat;
1243 else if ((strcasecmp(field, "groupswrap") == 0) ||
1244 (strcasecmp(field, "wrapgroups") == 0))
1246 ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1249 ERROR("Illegal groupsWrap setting for %s\n",
1250 longText(key->name));
1251 ACTION("Non-boolean value ignored\n");
1255 key->groupInfo = XkbWrapIntoRange;
1257 key->groupInfo = XkbClampIntoRange;
1258 key->defs.defined |= _Key_GroupInfo;
1260 else if ((strcasecmp(field, "groupsclamp") == 0) ||
1261 (strcasecmp(field, "clampgroups") == 0))
1263 ok = ExprResolveBoolean(keymap->ctx, value, &tmp);
1266 ERROR("Illegal groupsClamp setting for %s\n",
1267 longText(key->name));
1268 ACTION("Non-boolean value ignored\n");
1272 key->groupInfo = XkbClampIntoRange;
1274 key->groupInfo = XkbWrapIntoRange;
1275 key->defs.defined |= _Key_GroupInfo;
1277 else if ((strcasecmp(field, "groupsredirect") == 0) ||
1278 (strcasecmp(field, "redirectgroups") == 0))
1280 if (!ExprResolveGroup(keymap->ctx, value, &tmp))
1282 ERROR("Illegal group index for redirect of key %s\n",
1283 longText(key->name));
1284 ACTION("Definition with non-integer group ignored\n");
1288 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1289 key->defs.defined |= _Key_GroupInfo;
1293 ERROR("Unknown field %s in a symbol interpretation\n", field);
1294 ACTION("Definition ignored\n");
1301 SetGroupName(SymbolsInfo *info, struct xkb_keymap *keymap, ExprDef *arrayNdx,
1304 ExprResult tmp, name;
1306 if ((arrayNdx == NULL) && (warningLevel > 0))
1308 WARN("You must specify an index when specifying a group name\n");
1309 ACTION("Group name definition without array subscript ignored\n");
1312 if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp))
1314 ERROR("Illegal index in group name definition\n");
1315 ACTION("Definition with non-integer array index ignored\n");
1318 if (!ExprResolveString(keymap->ctx, value, &name))
1320 ERROR("Group name must be a string\n");
1321 ACTION("Illegal name for group %d ignored\n", tmp.uval);
1324 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1325 xkb_atom_intern(keymap->ctx, name.str);
1332 HandleSymbolsVar(VarDef *stmt, struct xkb_keymap *keymap, SymbolsInfo *info)
1334 ExprResult elem, field;
1338 if (ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx) == 0)
1339 return 0; /* internal error, already reported */
1340 if (elem.str && (strcasecmp(elem.str, "key") == 0))
1342 ret = SetSymbolsField(&info->dflt, keymap, field.str, arrayNdx,
1345 else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) ||
1346 (strcasecmp(field.str, "groupname") ==
1349 ret = SetGroupName(info, keymap, arrayNdx, stmt->value);
1351 else if ((elem.str == NULL)
1352 && ((strcasecmp(field.str, "groupswrap") == 0) ||
1353 (strcasecmp(field.str, "wrapgroups") == 0)))
1355 ERROR("Global \"groupswrap\" not supported\n");
1356 ACTION("Ignored\n");
1359 else if ((elem.str == NULL)
1360 && ((strcasecmp(field.str, "groupsclamp") == 0) ||
1361 (strcasecmp(field.str, "clampgroups") == 0)))
1363 ERROR("Global \"groupsclamp\" not supported\n");
1364 ACTION("Ignored\n");
1367 else if ((elem.str == NULL)
1368 && ((strcasecmp(field.str, "groupsredirect") == 0) ||
1369 (strcasecmp(field.str, "redirectgroups") == 0)))
1371 ERROR("Global \"groupsredirect\" not supported\n");
1372 ACTION("Ignored\n");
1375 else if ((elem.str == NULL) && (strcasecmp(field.str, "allownone") == 0))
1377 ERROR("Radio groups not supported\n");
1378 ACTION("Ignoring \"allownone\" specification\n");
1382 ret = SetActionField(keymap, elem.str, field.str, arrayNdx,
1383 stmt->value, &info->action);
1392 HandleSymbolsBody(VarDef *def, struct xkb_keymap *keymap, KeyInfo *key,
1396 ExprResult tmp, field;
1399 for (; def != NULL; def = (VarDef *) def->common.next)
1401 if ((def->name) && (def->name->type == ExprFieldRef))
1403 ok = HandleSymbolsVar(def, keymap, info);
1408 if (def->name == NULL)
1410 if ((def->value == NULL)
1411 || (def->value->op == ExprKeysymList))
1412 field.str = strdup("symbols");
1414 field.str = strdup("actions");
1419 ok = ExprResolveLhs(keymap, def->name, &tmp, &field,
1423 ok = SetSymbolsField(key, keymap, field.str, arrayNdx,
1432 SetExplicitGroup(SymbolsInfo *info, KeyInfo *key)
1434 unsigned group = info->explicit_group;
1439 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1442 WARN("For the map %s an explicit group specified\n", info->name);
1443 WARN("but key %s has more than one group defined\n",
1444 longText(key->name));
1445 ACTION("All groups except first one will be ignored\n");
1446 for (i = 1; i < XkbNumKbdGroups; i++)
1448 key->numLevels[i] = 0;
1449 darray_free(key->syms[i]);
1451 key->acts[i] = NULL;
1455 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1457 key->numLevels[group] = key->numLevels[0];
1458 key->numLevels[0] = 0;
1459 key->syms[group] = key->syms[0];
1460 darray_init(key->syms[0]);
1461 key->symsMapIndex[group] = key->symsMapIndex[0];
1462 darray_init(key->symsMapIndex[0]);
1463 key->symsMapNumEntries[group] = key->symsMapNumEntries[0];
1464 key->symsMapNumEntries[0] = NULL;
1465 key->acts[group] = key->acts[0];
1466 key->acts[0] = NULL;
1467 key->types[group] = key->types[0];
1473 HandleSymbolsDef(SymbolsDef *stmt, struct xkb_keymap *keymap,
1479 CopyKeyInfo(&info->dflt, &key, false);
1480 key.defs.merge = stmt->merge;
1481 key.name = KeyNameToLong(stmt->keyName);
1482 if (!HandleSymbolsBody((VarDef *) stmt->symbols, keymap, &key, info))
1488 if (!SetExplicitGroup(info, &key))
1494 if (!AddKeySymbols(info, &key, keymap))
1503 HandleModMapDef(ModMapDef *def, struct xkb_keymap *keymap, SymbolsInfo *info)
1510 if (!LookupModIndex(keymap->ctx, NULL, def->modifier, TypeInt, &rtrn))
1512 ERROR("Illegal modifier map definition\n");
1513 ACTION("Ignoring map for non-modifier \"%s\"\n",
1514 xkb_atom_text(keymap->ctx, def->modifier));
1518 tmp.modifier = rtrn.uval;
1519 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1521 if ((key->op == ExprValue) && (key->type == TypeKeyName))
1523 tmp.haveSymbol = false;
1524 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1526 else if (ExprResolveKeySym(keymap->ctx, key, &rtrn))
1528 tmp.haveSymbol = true;
1529 tmp.u.keySym = rtrn.uval;
1533 ERROR("Modmap entries may contain only key names or keysyms\n");
1534 ACTION("Illegal definition for %s modifier ignored\n",
1535 XkbcModIndexText(tmp.modifier));
1539 ok = AddModMapEntry(info, &tmp) && ok;
1545 HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
1546 unsigned merge, SymbolsInfo *info)
1551 info->name = uDupString(file->name);
1555 switch (stmt->stmtType)
1558 if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info))
1561 case StmtSymbolsDef:
1562 if (!HandleSymbolsDef((SymbolsDef *) stmt, keymap, info))
1566 if (!HandleSymbolsVar((VarDef *) stmt, keymap, info))
1570 if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods))
1574 ERROR("Interpretation files may not include other types\n");
1575 ACTION("Ignoring definition of symbol interpretation\n");
1578 case StmtKeycodeDef:
1579 ERROR("Interpretation files may not include other types\n");
1580 ACTION("Ignoring definition of key name\n");
1584 if (!HandleModMapDef((ModMapDef *) stmt, keymap, info))
1588 WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1593 if (info->errorCount > 10)
1596 ERROR("Too many errors\n");
1598 ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1605 FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
1606 xkb_keycode_t *kc_rtrn)
1609 unsigned int group, level;
1611 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++)
1613 for (group = 0; group < XkbKeyNumGroups(keymap, key); group++)
1615 for (level = 0; level < XkbKeyGroupWidth(keymap, key, group);
1618 if (XkbKeyNumSyms(keymap, key, group, level) != 1 ||
1619 (XkbKeySymEntry(keymap, key, group, level))[0] != sym)
1631 * Find the given name in the keymap->map->types and return its index.
1633 * @param atom The atom to search for.
1634 * @param type_rtrn Set to the index of the name if found.
1636 * @return true if found, false otherwise.
1639 FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn)
1642 const char *name = xkb_atom_text(keymap->ctx, atom);
1643 struct xkb_key_type *type;
1645 if (keymap && keymap->map) {
1646 darray_foreach(type, keymap->map->types) {
1647 if (strcmp(type->name, name) == 0) {
1658 * Assign a type to the given sym and return the Atom for the type assigned.
1661 * - ONE_LEVEL for width 0/1
1662 * - ALPHABETIC for 2 shift levels, with lower/upercase
1663 * - KEYPAD for keypad keys.
1664 * - TWO_LEVEL for other 2 shift level keys.
1665 * and the same for four level keys.
1667 * @param width Number of sysms in syms.
1668 * @param syms The keysyms for the given key (must be size width).
1669 * @param typeNameRtrn Set to the Atom of the type name.
1671 * @returns true if a type could be found, false otherwise.
1674 FindAutomaticType(struct xkb_keymap *keymap, int width,
1675 const xkb_keysym_t *syms, xkb_atom_t *typeNameRtrn,
1679 if ((width == 1) || (width == 0))
1681 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ONE_LEVEL");
1684 else if (width == 2)
1686 if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1688 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ALPHABETIC");
1690 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1692 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "KEYPAD");
1697 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "TWO_LEVEL");
1701 else if (width <= 4)
1703 if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1704 if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1706 xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_ALPHABETIC");
1708 *typeNameRtrn = xkb_atom_intern(keymap->ctx,
1709 "FOUR_LEVEL_SEMIALPHABETIC");
1711 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1712 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_KEYPAD");
1714 *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL");
1715 /* XXX: why not set autoType here? */
1717 return ((width >= 0) && (width <= 4));
1721 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1722 * groups, and reduce to one group if all groups are identical anyway.
1725 PrepareKeyDef(KeyInfo * key)
1727 int i, j, width, defined, lastGroup;
1730 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1731 /* get highest group number */
1732 for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1734 if (defined & (1 << i))
1742 /* If there are empty groups between non-empty ones fill them with data */
1743 /* from the first group. */
1744 /* We can make a wrong assumption here. But leaving gaps is worse. */
1745 for (i = lastGroup; i > 0; i--)
1747 if (defined & (1 << i))
1749 width = key->numLevels[0];
1750 if (key->typesDefined & 1)
1752 for (j = 0; j < width; j++)
1754 key->types[i] = key->types[0];
1756 key->typesDefined |= 1 << i;
1758 if ((key->actsDefined & 1) && key->acts[0])
1760 key->acts[i] = uTypedCalloc(width, union xkb_action);
1761 if (key->acts[i] == NULL)
1763 memcpy(key->acts[i], key->acts[0],
1764 width * sizeof(union xkb_action));
1765 key->actsDefined |= 1 << i;
1767 if ((key->symsDefined & 1) && !darray_empty(key->syms[0]))
1769 darray_copy(key->syms[i], key->syms[0]);
1770 darray_copy(key->symsMapIndex[i], key->symsMapIndex[0]);
1771 key->symsMapNumEntries[i] = uTypedCalloc(width, unsigned int);
1772 if (!key->symsMapNumEntries[i])
1774 darray_free(key->syms[i]);
1775 darray_free(key->symsMapIndex[i]);
1778 memcpy(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
1779 width * sizeof(int));
1780 key->symsDefined |= 1 << i;
1784 key->numLevels[i] = key->numLevels[0];
1787 /* If all groups are completely identical remove them all */
1788 /* exept the first one. */
1790 for (i = lastGroup; i > 0; i--)
1792 if ((key->numLevels[i] != key->numLevels[0]) ||
1793 (key->types[i] != key->types[0]))
1798 if (!darray_same(key->syms[i], key->syms[0]) &&
1799 (darray_empty(key->syms[i]) || darray_empty(key->syms[0]) ||
1800 darray_size(key->syms[i]) != darray_size(key->syms[0]) ||
1801 memcmp(darray_mem(key->syms[i], 0),
1802 darray_mem(key->syms[0], 0),
1803 sizeof(xkb_keysym_t) * darray_size(key->syms[0]))))
1808 if (!darray_same(key->symsMapIndex[i], key->symsMapIndex[0]) &&
1809 (darray_empty(key->symsMapIndex[i]) ||
1810 darray_empty(key->symsMapIndex[0]) ||
1811 memcmp(darray_mem(key->symsMapIndex[i], 0),
1812 darray_mem(key->symsMapIndex[0], 0),
1813 key->numLevels[0] * sizeof(int))))
1818 if ((key->symsMapNumEntries[i] != key->symsMapNumEntries[0]) &&
1819 (key->symsMapNumEntries[i] == NULL ||
1820 key->symsMapNumEntries[0] == NULL ||
1821 memcmp(key->symsMapNumEntries[i], key->symsMapNumEntries[0],
1822 key->numLevels[0] * sizeof(int))))
1827 if ((key->acts[i] != key->acts[0]) &&
1828 (key->acts[i] == NULL || key->acts[0] == NULL ||
1829 memcmp(key->acts[i], key->acts[0],
1830 sizeof(union xkb_action) * key->numLevels[0])))
1838 for (i = lastGroup; i > 0; i--)
1840 key->numLevels[i] = 0;
1841 darray_free(key->syms[i]);
1842 darray_free(key->symsMapIndex[i]);
1843 free(key->symsMapNumEntries[i]);
1844 key->symsMapNumEntries[i] = NULL;
1846 key->acts[i] = NULL;
1849 key->symsDefined &= 1;
1850 key->actsDefined &= 1;
1851 key->typesDefined &= 1;
1856 * Copy the KeyInfo into the keyboard description.
1858 * This function recurses.
1861 CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *key, int start_from)
1865 unsigned int sizeSyms = 0;
1866 unsigned width, tmp, nGroups;
1867 struct xkb_key_type * type;
1868 bool haveActions, autoType, useAlias;
1869 unsigned types[XkbNumKbdGroups];
1870 union xkb_action *outActs;
1871 unsigned int symIndex = 0;
1872 struct xkb_sym_map *sym_map;
1874 useAlias = (start_from == 0);
1876 /* get the keycode for the key. */
1877 if (!FindNamedKey(keymap, key->name, &kc, useAlias,
1878 CreateKeyNames(keymap), start_from))
1880 if ((start_from == 0) && (warningLevel >= 5))
1882 WARN("Key %s not found in keycodes\n", longText(key->name));
1883 ACTION("Symbols ignored\n");
1888 haveActions = false;
1889 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1891 if (((i + 1) > nGroups)
1892 && (((key->symsDefined | key->actsDefined) & (1 << i))
1893 || (key->typesDefined) & (1 << i)))
1898 /* Assign the type to the key, if it is missing. */
1899 if (key->types[i] == XKB_ATOM_NONE)
1901 if (key->dfltType != XKB_ATOM_NONE)
1902 key->types[i] = key->dfltType;
1903 else if (FindAutomaticType(keymap, key->numLevels[i],
1904 darray_mem(key->syms[i], 0),
1905 &key->types[i], &autoType))
1910 if (warningLevel >= 5)
1912 WARN("No automatic type for %d symbols\n",
1913 (unsigned int) key->numLevels[i]);
1914 ACTION("Using %s for the %s key (keycode %d)\n",
1915 xkb_atom_text(keymap->ctx, key->types[i]),
1916 longText(key->name), kc);
1920 if (FindNamedType(keymap, key->types[i], &types[i]))
1922 if (!autoType || key->numLevels[i] > 2)
1923 keymap->server->explicit[kc] |= (1 << i);
1927 if (warningLevel >= 3)
1929 WARN("Type \"%s\" is not defined\n",
1930 xkb_atom_text(keymap->ctx, key->types[i]));
1931 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
1932 longText(key->name), kc);
1934 types[i] = XkbTwoLevelIndex;
1936 /* if the type specifies fewer levels than the key has, shrink the key */
1937 type = &darray_item(keymap->map->types, types[i]);
1938 if (type->num_levels < key->numLevels[i])
1940 if (warningLevel > 0)
1942 WARN("Type \"%s\" has %d levels, but %s has %d symbols\n",
1943 type->name, type->num_levels,
1944 xkb_atom_text(keymap->ctx, key->name), key->numLevels[i]);
1945 ACTION("Ignoring extra symbols\n");
1947 key->numLevels[i] = type->num_levels;
1949 if (key->numLevels[i] > width)
1950 width = key->numLevels[i];
1951 if (type->num_levels > width)
1952 width = type->num_levels;
1953 sizeSyms += darray_size(key->syms[i]);
1956 if (!XkbcResizeKeySyms(keymap, kc, sizeSyms))
1958 WSGO("Could not enlarge symbols for %s (keycode %d)\n",
1959 longText(key->name), kc);
1964 outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups);
1965 if (outActs == NULL)
1967 WSGO("Could not enlarge actions for %s (key %d)\n",
1968 longText(key->name), kc);
1971 keymap->server->explicit[kc] |= XkbExplicitInterpretMask;
1976 sym_map = &darray_item(keymap->map->key_sym_map, kc);
1978 if (key->defs.defined & _Key_GroupInfo)
1981 i = sym_map->group_info;
1983 sym_map->group_info = XkbSetNumGroups(i, nGroups);
1984 sym_map->width = width;
1985 sym_map->sym_index = uTypedCalloc(nGroups * width, int);
1986 sym_map->num_syms = uTypedCalloc(nGroups * width, unsigned int);
1988 for (i = 0; i < nGroups; i++)
1990 /* assign kt_index[i] to the index of the type in map->types.
1991 * kt_index[i] may have been set by a previous run (if we have two
1992 * layouts specified). Let's not overwrite it with the ONE_LEVEL
1993 * default group if we dont even have keys for this group anyway.
1995 * FIXME: There should be a better fix for this.
1997 if (key->numLevels[i])
1998 sym_map->kt_index[i] = types[i];
1999 if (!darray_empty(key->syms[i]))
2001 /* fill key to "width" symbols*/
2002 for (tmp = 0; tmp < width; tmp++)
2004 if (tmp < key->numLevels[i] && key->symsMapNumEntries[i][tmp])
2006 memcpy(&sym_map->syms[symIndex],
2007 darray_mem(key->syms[i],
2008 darray_item(key->symsMapIndex[i], tmp)),
2009 key->symsMapNumEntries[i][tmp] *
2010 sizeof(xkb_keysym_t));
2011 sym_map->sym_index[(i * width) + tmp] = symIndex;
2012 sym_map->num_syms[(i * width) + tmp] =
2013 key->symsMapNumEntries[i][tmp];
2014 symIndex += sym_map->num_syms[(i * width) + tmp];
2018 sym_map->sym_index[(i * width) + tmp] = -1;
2019 sym_map->num_syms[(i * width) + tmp] = 0;
2021 if ((outActs != NULL) && (key->acts[i] != NULL))
2023 if (tmp < key->numLevels[i])
2024 outActs[tmp] = key->acts[i][tmp];
2026 outActs[tmp].type = XkbSA_NoAction;
2031 switch (key->behavior.type & XkbKB_OpMask)
2036 keymap->server->behaviors[kc] = key->behavior;
2037 keymap->server->explicit[kc] |= XkbExplicitBehaviorMask;
2040 if (key->defs.defined & _Key_VModMap)
2042 keymap->server->vmodmap[kc] = key->vmodmap;
2043 keymap->server->explicit[kc] |= XkbExplicitVModMapMask;
2045 if (key->repeat != RepeatUndefined)
2047 if (key->repeat == RepeatYes)
2048 keymap->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2050 keymap->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2051 keymap->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2054 if (nGroups > keymap->ctrls->num_groups)
2055 keymap->ctrls->num_groups = nGroups;
2057 /* do the same thing for the next key */
2058 CopySymbolsDef(keymap, key, kc + 1);
2063 CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry)
2067 if (!entry->haveSymbol &&
2068 !FindNamedKey(keymap, entry->u.keyName, &kc, true,
2069 CreateKeyNames(keymap), 0))
2071 if (warningLevel >= 5)
2073 WARN("Key %s not found in keycodes\n",
2074 longText(entry->u.keyName));
2075 ACTION("Modifier map entry for %s not updated\n",
2076 XkbcModIndexText(entry->modifier));
2080 else if (entry->haveSymbol &&
2081 !FindKeyForSymbol(keymap, entry->u.keySym, &kc))
2083 if (warningLevel > 5)
2085 WARN("Key \"%s\" not found in symbol map\n",
2086 XkbcKeysymText(entry->u.keySym));
2087 ACTION("Modifier map entry for %s not updated\n",
2088 XkbcModIndexText(entry->modifier));
2092 keymap->map->modmap[kc] |= (1 << entry->modifier);
2097 * Handle the xkb_symbols section of an xkb file.
2099 * @param file The parsed xkb_symbols section of the xkb file.
2100 * @param keymap Handle to the keyboard description to store the symbols in.
2101 * @param merge Merge strategy (e.g. MergeOverride).
2104 CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
2110 InitSymbolsInfo(&info, keymap);
2111 info.dflt.defs.fileID = file->id;
2112 info.dflt.defs.merge = merge;
2114 HandleSymbolsFile(file, keymap, merge, &info);
2116 if (darray_empty(info.keys))
2119 if (info.errorCount != 0)
2122 /* alloc memory in the xkb struct */
2123 if (XkbcAllocNames(keymap, XkbGroupNamesMask, 0) != Success) {
2124 WSGO("Can not allocate names in CompileSymbols\n");
2125 ACTION("Symbols not added\n");
2129 if (XkbcAllocClientMap(keymap, XkbKeySymsMask | XkbModifierMapMask, 0)
2131 WSGO("Could not allocate client map in CompileSymbols\n");
2132 ACTION("Symbols not added\n");
2136 if (XkbcAllocServerMap(keymap, XkbAllServerInfoMask, 32) != Success) {
2137 WSGO("Could not allocate server map in CompileSymbols\n");
2138 ACTION("Symbols not added\n");
2142 if (XkbcAllocControls(keymap) != Success) {
2143 WSGO("Could not allocate controls in CompileSymbols\n");
2144 ACTION("Symbols not added\n");
2148 /* now copy info into xkb. */
2149 ApplyAliases(keymap, &info.aliases);
2151 for (i = 0; i < XkbNumKbdGroups; i++) {
2152 if (info.groupNames[i] != XKB_ATOM_NONE) {
2153 free(keymap->names->groups[i]);
2154 keymap->names->groups[i] = xkb_atom_strdup(keymap->ctx,
2155 info.groupNames[i]);
2160 darray_foreach(key, info.keys)
2164 darray_foreach(key, info.keys)
2165 if (!CopySymbolsDef(keymap, key, 0))
2168 if (warningLevel > 3) {
2169 for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
2170 if (darray_item(keymap->names->keys, i).name[0] == '\0')
2173 if (XkbKeyNumGroups(keymap, i) < 1) {
2175 memcpy(buf, darray_item(keymap->names->keys, i).name, 4);
2177 WARN("No symbols defined for <%s> (keycode %d)\n", buf, i);
2183 ModMapEntry *mm, *next;
2184 for (mm = info.modMap; mm != NULL; mm = next) {
2185 if (!CopyModMapDef(keymap, mm))
2187 next = (ModMapEntry *) mm->defs.next;
2191 FreeSymbolsInfo(&info);
2195 FreeSymbolsInfo(&info);