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 ********************************************************/
32 #include "parseutils.h"
34 #include <X11/extensions/XKBfilecommon.h>
35 #include <X11/keysym.h>
45 extern Atom tok_ONE_LEVEL;
46 extern Atom tok_TWO_LEVEL;
47 extern Atom tok_KEYPAD;
49 /***====================================================================***/
53 #define RepeatUndefined ~((unsigned)0)
55 #define _Key_Syms (1<<0)
56 #define _Key_Acts (1<<1)
57 #define _Key_Repeat (1<<2)
58 #define _Key_Behavior (1<<3)
59 #define _Key_Type_Dflt (1<<4)
60 #define _Key_Types (1<<5)
61 #define _Key_GroupInfo (1<<6)
62 #define _Key_VModMap (1<<7)
64 typedef struct _KeyInfo
67 unsigned long name; /* the 4 chars of the key name, as long */
68 unsigned char groupInfo;
69 unsigned char typesDefined;
70 unsigned char symsDefined;
71 unsigned char actsDefined;
72 short numLevels[XkbNumKbdGroups];
73 CARD32 *syms[XkbNumKbdGroups];
74 XkbcAction *acts[XkbNumKbdGroups];
75 Atom types[XkbNumKbdGroups];
78 unsigned short vmodmap;
79 unsigned long nameForOverlayKey;
80 unsigned long allowNone;
85 * Init the given key info to sane values.
88 InitKeyInfo(KeyInfo * info)
91 static char dflt[4] = "*";
93 info->defs.defined = 0;
94 info->defs.fileID = 0;
95 info->defs.merge = MergeOverride;
96 info->defs.next = NULL;
97 info->name = KeyNameToLong(dflt);
99 info->typesDefined = info->symsDefined = info->actsDefined = 0;
100 for (i = 0; i < XkbNumKbdGroups; i++)
102 info->numLevels[i] = 0;
103 info->types[i] = None;
104 info->syms[i] = NULL;
105 info->acts[i] = NULL;
107 info->dfltType = None;
108 info->behavior.type = XkbKB_Default;
109 info->behavior.data = 0;
111 info->nameForOverlayKey = 0;
112 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] = None;
135 if (info->syms[i] != NULL)
136 uFree(info->syms[i]);
137 info->syms[i] = NULL;
138 if (info->acts[i] != NULL)
139 uFree(info->acts[i]);
140 info->acts[i] = NULL;
142 info->dfltType = None;
143 info->behavior.type = XkbKB_Default;
144 info->behavior.data = 0;
146 info->nameForOverlayKey = 0;
147 info->repeat = RepeatUndefined;
153 * Copy old into new, optionally reset old to 0.
154 * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
155 * newly allocated and new points to the new memory areas.
158 CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld)
163 new->defs.next = NULL;
166 for (i = 0; i < XkbNumKbdGroups; i++)
168 old->numLevels[i] = 0;
176 for (i = 0; i < XkbNumKbdGroups; i++)
178 width = new->numLevels[i];
179 if (old->syms[i] != NULL)
181 new->syms[i] = uTypedCalloc(width, CARD32);
185 new->numLevels[i] = 0;
188 memcpy((char *) new->syms[i], (char *) old->syms[i],
189 width * sizeof(CARD32));
191 if (old->acts[i] != NULL)
193 new->acts[i] = uTypedCalloc(width, XkbcAction);
199 memcpy((char *) new->acts[i], (char *) old->acts[i],
200 width * sizeof(XkbcAction));
207 /***====================================================================***/
209 typedef struct _ModMapEntry
216 unsigned long keyName;
221 #define SYMBOLS_INIT_SIZE 110
222 #define SYMBOLS_CHUNK 20
223 typedef struct _SymbolsInfo
225 char *name; /* e.g. pc+us+inet(evdev) */
229 unsigned explicit_group;
237 Atom groupNames[XkbNumKbdGroups];
244 InitSymbolsInfo(SymbolsInfo * info, XkbcDescPtr xkb)
248 tok_ONE_LEVEL = XkbcInternAtom("ONE_LEVEL", False);
249 tok_TWO_LEVEL = XkbcInternAtom("TWO_LEVEL", False);
250 tok_KEYPAD = XkbcInternAtom("KEYPAD", False);
252 info->explicit_group = 0;
253 info->errorCount = 0;
255 info->merge = MergeOverride;
257 info->szKeys = SYMBOLS_INIT_SIZE;
259 info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo);
261 for (i = 0; i < XkbNumKbdGroups; i++)
262 info->groupNames[i] = None;
263 InitKeyInfo(&info->dflt);
264 InitVModInfo(&info->vmods, xkb);
266 info->aliases = NULL;
271 FreeSymbolsInfo(SymbolsInfo * info)
280 for (i = 0; i < info->nKeys; i++)
282 FreeKeyInfo(&info->keys[i]);
289 ClearCommonInfo(&info->modMap->defs);
294 ClearAliases(&info->aliases);
295 info->aliases = NULL;
297 bzero((char *) info, sizeof(SymbolsInfo));
302 ResizeKeyGroup(KeyInfo * key,
303 unsigned group, unsigned atLeastSize, Bool forceActions)
308 tooSmall = (key->numLevels[group] < atLeastSize);
310 newWidth = atLeastSize;
312 newWidth = key->numLevels[group];
314 if ((key->syms[group] == NULL) || tooSmall)
316 key->syms[group] = uTypedRecalloc(key->syms[group],
317 key->numLevels[group], newWidth,
319 if (!key->syms[group])
322 if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) ||
323 (tooSmall && (key->acts[group] != NULL)))
325 key->acts[group] = uTypedRecalloc(key->acts[group],
326 key->numLevels[group], newWidth,
328 if (!key->acts[group])
331 key->numLevels[group] = newWidth;
336 MergeKeyGroups(SymbolsInfo * info,
337 KeyInfo * into, KeyInfo * from, unsigned group)
340 XkbcAction *resultActs;
343 Bool report, clobber;
345 clobber = (from->defs.merge != MergeAugment);
346 report = (warningLevel > 9) ||
347 ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
348 if (into->numLevels[group] >= from->numLevels[group])
350 resultSyms = into->syms[group];
351 resultActs = into->acts[group];
352 resultWidth = into->numLevels[group];
356 resultSyms = from->syms[group];
357 resultActs = from->acts[group];
358 resultWidth = from->numLevels[group];
360 if (resultSyms == NULL)
362 resultSyms = uTypedCalloc(resultWidth, CARD32);
365 WSGO("Could not allocate symbols for group merge\n");
366 ACTION("Group %d of key %s not merged\n", group,
367 longText(into->name));
371 if ((resultActs == NULL) && (into->acts[group] || from->acts[group]))
373 resultActs = uTypedCalloc(resultWidth, XkbcAction);
376 WSGO("Could not allocate actions for group merge\n");
377 ACTION("Group %d of key %s not merged\n", group,
378 longText(into->name));
382 for (i = 0; i < resultWidth; i++)
384 CARD32 fromSym, toSym;
385 if (from->syms[group] && (i < from->numLevels[group]))
386 fromSym = from->syms[group][i];
389 if (into->syms[group] && (i < into->numLevels[group]))
390 toSym = into->syms[group][i];
393 if ((fromSym == NoSymbol) || (fromSym == toSym))
394 resultSyms[i] = toSym;
395 else if (toSym == NoSymbol)
396 resultSyms[i] = fromSym;
413 ("Multiple symbols for level %d/group %d on key %s\n",
414 i + 1, group + 1, longText(into->name));
415 ACTION("Using %s, ignoring %s\n",
416 XkbcKeysymText(use), XkbcKeysymText(ignore));
420 if (resultActs != NULL)
422 XkbcAction *fromAct, *toAct;
423 fromAct = (from->acts[group] ? &from->acts[group][i] : NULL);
424 toAct = (into->acts[group] ? &into->acts[group][i] : NULL);
425 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
428 resultActs[i] = *toAct;
430 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
431 && (fromAct != NULL))
433 resultActs[i] = *fromAct;
437 XkbcAction *use, *ignore;
451 ("Multiple actions for level %d/group %d on key %s\n",
452 i + 1, group + 1, longText(into->name));
453 ACTION("Using %s, ignoring %s\n",
454 XkbcActionTypeText(use->type),
455 XkbcActionTypeText(ignore->type));
457 resultActs[i] = *use;
461 if ((into->syms[group] != NULL) && (resultSyms != into->syms[group]))
462 uFree(into->syms[group]);
463 if ((from->syms[group] != NULL) && (resultSyms != from->syms[group]))
464 uFree(from->syms[group]);
465 if ((into->acts[group] != NULL) && (resultActs != into->acts[group]))
466 uFree(into->acts[group]);
467 if ((from->acts[group] != NULL) && (resultActs != from->acts[group]))
468 uFree(from->acts[group]);
469 into->numLevels[group] = resultWidth;
470 into->syms[group] = resultSyms;
471 from->syms[group] = NULL;
472 into->acts[group] = resultActs;
473 from->acts[group] = NULL;
474 into->symsDefined |= (1 << group);
475 from->symsDefined &= ~(1 << group);
476 into->actsDefined |= (1 << group);
477 from->actsDefined &= ~(1 << group);
482 MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from)
485 unsigned collide = 0;
488 if (from->defs.merge == MergeReplace)
490 for (i = 0; i < XkbNumKbdGroups; i++)
492 if (into->numLevels[i] != 0)
495 uFree(into->syms[i]);
497 uFree(into->acts[i]);
501 bzero(from, sizeof(KeyInfo));
504 report = ((warningLevel > 9) ||
505 ((into->defs.fileID == from->defs.fileID)
506 && (warningLevel > 0)));
507 for (i = 0; i < XkbNumKbdGroups; i++)
509 if (from->numLevels[i] > 0)
511 if (into->numLevels[i] == 0)
513 into->numLevels[i] = from->numLevels[i];
514 into->syms[i] = from->syms[i];
515 into->acts[i] = from->acts[i];
516 into->symsDefined |= (1 << i);
517 from->syms[i] = NULL;
518 from->acts[i] = NULL;
519 from->numLevels[i] = 0;
520 from->symsDefined &= ~(1 << i);
522 into->defs.defined |= _Key_Syms;
524 into->defs.defined |= _Key_Acts;
531 collide |= _Key_Syms;
533 collide |= _Key_Acts;
535 MergeKeyGroups(info, into, from, (unsigned) i);
538 if (from->types[i] != None)
540 if ((into->types[i] != None) && (report) &&
541 (into->types[i] != from->types[i]))
544 collide |= _Key_Types;
545 if (from->defs.merge != MergeAugment)
547 use = from->types[i];
548 ignore = into->types[i];
552 use = into->types[i];
553 ignore = from->types[i];
556 ("Multiple definitions for group %d type of key %s\n",
557 i, longText(into->name));
558 ACTION("Using %s, ignoring %s\n",
560 XkbcAtomText(ignore));
562 if ((from->defs.merge != MergeAugment)
563 || (into->types[i] == None))
565 into->types[i] = from->types[i];
569 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
571 into->behavior = from->behavior;
572 into->nameForOverlayKey = from->nameForOverlayKey;
573 into->defs.defined |= _Key_Behavior;
575 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
577 into->vmodmap = from->vmodmap;
578 into->defs.defined |= _Key_VModMap;
580 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
582 into->repeat = from->repeat;
583 into->defs.defined |= _Key_Repeat;
585 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
587 into->dfltType = from->dfltType;
588 into->defs.defined |= _Key_Type_Dflt;
590 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
592 into->groupInfo = from->groupInfo;
593 into->defs.defined |= _Key_GroupInfo;
597 WARN("Symbol map for key %s redefined\n",
598 longText(into->name));
599 ACTION("Using %s definition for conflicting fields\n",
600 (from->defs.merge == MergeAugment ? "first" : "last"));
606 AddKeySymbols(SymbolsInfo * info, KeyInfo * key, XkbcDescPtr xkb)
609 unsigned long real_name;
611 for (i = 0; i < info->nKeys; i++)
613 if (info->keys[i].name == key->name)
614 return MergeKeys(info, &info->keys[i], key);
616 if (FindKeyNameForAlias(xkb, key->name, &real_name))
618 for (i = 0; i < info->nKeys; i++)
620 if (info->keys[i].name == real_name)
621 return MergeKeys(info, &info->keys[i], key);
624 if (info->nKeys >= info->szKeys)
626 info->szKeys += SYMBOLS_CHUNK;
628 uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo);
631 WSGO("Could not allocate key symbols descriptions\n");
632 ACTION("Some key symbols definitions may be lost\n");
636 return CopyKeyInfo(key, &info->keys[info->nKeys++], True);
640 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
645 clobber = (new->defs.merge != MergeAugment);
646 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
648 if (new->haveSymbol && mm->haveSymbol
649 && (new->u.keySym == mm->u.keySym))
651 unsigned use, ignore;
652 if (mm->modifier != new->modifier)
657 ignore = mm->modifier;
662 ignore = new->modifier;
665 ("%s added to symbol map for multiple modifiers\n",
666 XkbcKeysymText(new->u.keySym));
667 ACTION("Using %s, ignoring %s.\n",
668 XkbcModIndexText(use),
669 XkbcModIndexText(ignore));
674 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
675 (new->u.keyName == mm->u.keyName))
677 unsigned use, ignore;
678 if (mm->modifier != new->modifier)
683 ignore = mm->modifier;
688 ignore = new->modifier;
690 ERROR("Key %s added to map for multiple modifiers\n",
691 longText(new->u.keyName));
692 ACTION("Using %s, ignoring %s.\n",
693 XkbcModIndexText(use),
694 XkbcModIndexText(ignore));
700 mm = uTypedAlloc(ModMapEntry);
703 WSGO("Could not allocate modifier map entry\n");
704 ACTION("Modifier map for %s will be incomplete\n",
705 XkbcModIndexText(new->modifier));
709 mm->defs.next = &info->modMap->defs;
714 /***====================================================================***/
717 MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from,
718 unsigned merge, XkbcDescPtr xkb)
723 if (from->errorCount > 0)
725 into->errorCount += from->errorCount;
728 if (into->name == NULL)
730 into->name = from->name;
733 for (i = 0; i < XkbNumKbdGroups; i++)
735 if (from->groupNames[i] != None)
737 if ((merge != MergeAugment) || (into->groupNames[i] == None))
738 into->groupNames[i] = from->groupNames[i];
741 for (i = 0, key = from->keys; i < from->nKeys; i++, key++)
743 if (merge != MergeDefault)
744 key->defs.merge = merge;
745 if (!AddKeySymbols(into, key, xkb))
748 if (from->modMap != NULL)
750 ModMapEntry *mm, *next;
751 for (mm = from->modMap; mm != NULL; mm = next)
753 if (merge != MergeDefault)
754 mm->defs.merge = merge;
755 if (!AddModMapEntry(into, mm))
757 next = (ModMapEntry *) mm->defs.next;
762 if (!MergeAliases(&into->aliases, &from->aliases, merge))
767 typedef void (*FileHandler) (XkbFile * /* rtrn */ ,
768 XkbcDescPtr /* xkb */ ,
769 unsigned /* merge */ ,
770 SymbolsInfo * /* included */
774 HandleIncludeSymbols(IncludeStmt * stmt,
775 XkbcDescPtr xkb, SymbolsInfo * info, FileHandler hndlr)
779 SymbolsInfo included;
783 if ((stmt->file == NULL) && (stmt->map == NULL))
787 bzero(info, sizeof(SymbolsInfo));
789 else if (ProcessIncludeFile(stmt, XkmSymbolsIndex, &rtrn, &newMerge))
791 InitSymbolsInfo(&included, xkb);
792 included.fileID = included.dflt.defs.fileID = rtrn->id;
793 included.merge = included.dflt.defs.merge = MergeOverride;
796 included.explicit_group = atoi(stmt->modifier) - 1;
800 included.explicit_group = info->explicit_group;
802 (*hndlr) (rtrn, xkb, MergeOverride, &included);
803 if (stmt->stmt != NULL)
805 if (included.name != NULL)
806 uFree(included.name);
807 included.name = stmt->stmt;
813 info->errorCount += 10;
816 if ((stmt->next != NULL) && (included.errorCount < 1))
820 SymbolsInfo next_incl;
822 for (next = stmt->next; next != NULL; next = next->next)
824 if ((next->file == NULL) && (next->map == NULL))
827 MergeIncludedSymbols(&included, info, next->merge, xkb);
828 FreeSymbolsInfo(info);
830 else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op))
832 InitSymbolsInfo(&next_incl, xkb);
833 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
834 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride;
837 next_incl.explicit_group = atoi(next->modifier) - 1;
841 next_incl.explicit_group = info->explicit_group;
843 (*hndlr) (rtrn, xkb, MergeOverride, &next_incl);
844 MergeIncludedSymbols(&included, &next_incl, op, xkb);
845 FreeSymbolsInfo(&next_incl);
849 info->errorCount += 10;
858 MergeIncludedSymbols(info, &included, newMerge, xkb);
859 FreeSymbolsInfo(&included);
861 return (info->errorCount == 0);
864 static LookupEntry groupNames[] = {
881 GetGroupIndex(KeyInfo * key,
882 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
892 if (arrayNdx == NULL)
897 defined = key->symsDefined;
899 defined = key->actsDefined;
901 for (i = 0; i < XkbNumKbdGroups; i++)
903 if ((defined & (1 << i)) == 0)
909 ERROR("Too many groups of %s for key %s (max %d)\n", name,
910 longText(key->name), XkbNumKbdGroups + 1);
911 ACTION("Ignoring %s defined for extra groups\n", name);
914 if (!ExprResolveInteger
915 (arrayNdx, &tmp, SimpleLookup, (char *) groupNames))
917 ERROR("Illegal group index for %s of key %s\n", name,
918 longText(key->name));
919 ACTION("Definition with non-integer array index ignored\n");
922 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
924 ERROR("Group index for %s of key %s is out of range (1..%d)\n",
925 name, longText(key->name), XkbNumKbdGroups + 1);
926 ACTION("Ignoring %s for group %d\n", name, tmp.uval);
929 *ndx_rtrn = tmp.uval - 1;
934 AddSymbolsToKey(KeyInfo * key,
937 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
942 if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx))
946 key->symsDefined |= (1 << ndx);
949 if (value->op != ExprKeysymList)
951 ERROR("Expected a list of symbols, found %s\n",
952 exprOpText(value->op));
953 ACTION("Ignoring symbols for group %d of %s\n", ndx,
954 longText(key->name));
957 if (key->syms[ndx] != NULL)
959 WSGO("Symbols for key %s, group %d already defined\n",
960 longText(key->name), ndx);
963 nSyms = value->value.list.nSyms;
964 if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
965 (!ResizeKeyGroup(key, ndx, nSyms, False)))
967 WSGO("Could not resize group %d of key %s\n", ndx,
968 longText(key->name));
969 ACTION("Symbols lost\n");
972 key->symsDefined |= (1 << ndx);
973 for (i = 0; i < nSyms; i++) {
974 if (!LookupKeysym(value->value.list.syms[i], &key->syms[ndx][i])) {
975 WSGO("Could not resolve keysym %s\n", value->value.list.syms[i]);
976 key->syms[ndx][i] = NoSymbol;
979 for (i = key->numLevels[ndx] - 1;
980 (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--)
982 key->numLevels[ndx]--;
988 AddActionsToKey(KeyInfo * key,
991 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
996 XkbcAnyAction *toAct;
998 if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx))
1003 key->actsDefined |= (1 << ndx);
1006 if (value->op != ExprActionList)
1008 WSGO("Bad expression type (%d) for action list value\n", value->op);
1009 ACTION("Ignoring actions for group %d of %s\n", ndx,
1010 longText(key->name));
1013 if (key->acts[ndx] != NULL)
1015 WSGO("Actions for key %s, group %d already defined\n",
1016 longText(key->name), ndx);
1019 for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1021 act = (ExprDef *) act->common.next;
1025 WSGO("Action list but not actions in AddActionsToKey\n");
1028 if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1029 (!ResizeKeyGroup(key, ndx, nActs, True)))
1031 WSGO("Could not resize group %d of key %s\n", ndx,
1032 longText(key->name));
1033 ACTION("Actions lost\n");
1036 key->actsDefined |= (1 << ndx);
1038 toAct = (XkbcAnyAction *) key->acts[ndx];
1039 act = value->value.child;
1040 for (i = 0; i < nActs; i++, toAct++)
1042 if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action))
1044 ERROR("Illegal action definition for %s\n",
1045 longText(key->name));
1046 ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1048 act = (ExprDef *) act->common.next;
1054 SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value)
1057 unsigned radio_groups = 0;
1059 if (arrayNdx == NULL)
1061 radio_groups = XkbAllRadioGroupsMask;
1065 if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL))
1067 ERROR("Illegal index in group name definition\n");
1068 ACTION("Definition with non-integer array index ignored\n");
1071 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1073 ERROR("Illegal radio group specified (must be 1..%d)\n",
1074 XkbMaxRadioGroups + 1);
1075 ACTION("Value of \"allow none\" for group %d ignored\n",
1079 radio_groups |= (1 << (tmp.uval - 1));
1081 if (!ExprResolveBoolean(value, &tmp, NULL, NULL))
1083 ERROR("Illegal \"allow none\" value for %s\n",
1084 longText(key->name));
1085 ACTION("Non-boolean value ignored\n");
1089 key->allowNone |= radio_groups;
1091 key->allowNone &= ~radio_groups;
1096 static LookupEntry lockingEntries[] = {
1097 {"true", XkbKB_Lock},
1098 {"yes", XkbKB_Lock},
1100 {"false", XkbKB_Default},
1101 {"no", XkbKB_Default},
1102 {"off", XkbKB_Default},
1103 {"permanent", XkbKB_Lock | XkbKB_Permanent},
1107 static LookupEntry repeatEntries[] = {
1108 {"true", RepeatYes},
1111 {"false", RepeatNo},
1114 {"default", RepeatUndefined},
1118 static LookupEntry rgEntries[] = {
1124 SetSymbolsField(KeyInfo * key,
1127 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1132 if (uStrCaseCmp(field, "type") == 0)
1135 if ((!ExprResolveString(value, &tmp, NULL, NULL))
1136 && (warningLevel > 0))
1138 WARN("The type field of a key symbol map must be a string\n");
1139 ACTION("Ignoring illegal type definition\n");
1141 if (arrayNdx == NULL)
1143 key->dfltType = XkbcInternAtom(tmp.str, False);
1144 key->defs.defined |= _Key_Type_Dflt;
1146 else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup,
1147 (char *) groupNames))
1149 ERROR("Illegal group index for type of key %s\n",
1150 longText(key->name));
1151 ACTION("Definition with non-integer array index ignored\n");
1155 else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups))
1158 ("Group index for type of key %s is out of range (1..%d)\n",
1159 longText(key->name), XkbNumKbdGroups + 1);
1160 ACTION("Ignoring type for group %d\n", ndx.uval);
1166 key->types[ndx.uval - 1] = XkbcInternAtom(tmp.str, False);
1167 key->typesDefined |= (1 << (ndx.uval - 1));
1171 else if (uStrCaseCmp(field, "symbols") == 0)
1172 return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1173 else if (uStrCaseCmp(field, "actions") == 0)
1174 return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1175 else if ((uStrCaseCmp(field, "vmods") == 0) ||
1176 (uStrCaseCmp(field, "virtualmods") == 0) ||
1177 (uStrCaseCmp(field, "virtualmodifiers") == 0))
1179 ok = ExprResolveModMask(value, &tmp, LookupVModMask, (char *) xkb);
1182 key->vmodmap = (tmp.uval >> 8);
1183 key->defs.defined |= _Key_VModMap;
1187 ERROR("Expected a virtual modifier mask, found %s\n",
1188 exprOpText(value->op));
1189 ACTION("Ignoring virtual modifiers definition for key %s\n",
1190 longText(key->name));
1193 else if ((uStrCaseCmp(field, "locking") == 0)
1194 || (uStrCaseCmp(field, "lock") == 0)
1195 || (uStrCaseCmp(field, "locks") == 0))
1197 ok = ExprResolveEnum(value, &tmp, lockingEntries);
1199 key->behavior.type = tmp.uval;
1200 key->defs.defined |= _Key_Behavior;
1202 else if ((uStrCaseCmp(field, "radiogroup") == 0) ||
1203 (uStrCaseCmp(field, "permanentradiogroup") == 0))
1205 Bool permanent = False;
1206 if (uStrCaseCmp(field, "permanentradiogroup") == 0)
1208 ok = ExprResolveInteger(value, &tmp, SimpleLookup,
1209 (char *) rgEntries);
1212 ERROR("Illegal radio group specification for %s\n",
1213 longText(key->name));
1214 ACTION("Non-integer radio group ignored\n");
1219 key->behavior.type = XkbKB_Default;
1220 key->behavior.data = 0;
1223 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1226 ("Radio group specification for %s out of range (1..32)\n",
1227 longText(key->name));
1228 ACTION("Illegal radio group %d ignored\n", tmp.uval);
1231 key->behavior.type =
1232 XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0);
1233 key->behavior.data = tmp.uval - 1;
1234 if (key->allowNone & (1 << (tmp.uval - 1)))
1235 key->behavior.data |= XkbKB_RGAllowNone;
1236 key->defs.defined |= _Key_Behavior;
1238 else if (uStrCaseEqual(field, "allownone"))
1240 ok = SetAllowNone(key, arrayNdx, value);
1242 else if (uStrCasePrefix("overlay", field) ||
1243 uStrCasePrefix("permanentoverlay", field))
1245 Bool permanent = False;
1248 if (uStrCasePrefix("permanent", field))
1251 which = &field[sizeof("permanentoverlay") - 1];
1255 which = &field[sizeof("overlay") - 1];
1257 if (sscanf(which, "%d", &overlayNdx) == 1)
1259 if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0))
1261 ERROR("Illegal overlay %d specified for %s\n",
1262 overlayNdx, longText(key->name));
1263 ACTION("Ignored\n");
1267 else if (*which == '\0')
1269 else if (warningLevel > 0)
1271 ERROR("Illegal overlay \"%s\" specified for %s\n",
1272 which, longText(key->name));
1273 ACTION("Ignored\n");
1276 ok = ExprResolveKeyName(value, &tmp, NULL, NULL);
1279 ERROR("Illegal overlay key specification for %s\n",
1280 longText(key->name));
1281 ACTION("Overlay key must be specified by name\n");
1284 if (overlayNdx == 1)
1285 key->behavior.type = XkbKB_Overlay1;
1287 key->behavior.type = XkbKB_Overlay2;
1289 key->behavior.type |= XkbKB_Permanent;
1291 key->behavior.data = 0;
1292 key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name);
1293 key->defs.defined |= _Key_Behavior;
1295 else if ((uStrCaseCmp(field, "repeating") == 0) ||
1296 (uStrCaseCmp(field, "repeats") == 0) ||
1297 (uStrCaseCmp(field, "repeat") == 0))
1299 ok = ExprResolveEnum(value, &tmp, repeatEntries);
1302 ERROR("Illegal repeat setting for %s\n",
1303 longText(key->name));
1304 ACTION("Non-boolean repeat setting ignored\n");
1307 key->repeat = tmp.uval;
1308 key->defs.defined |= _Key_Repeat;
1310 else if ((uStrCaseCmp(field, "groupswrap") == 0) ||
1311 (uStrCaseCmp(field, "wrapgroups") == 0))
1313 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1316 ERROR("Illegal groupsWrap setting for %s\n",
1317 longText(key->name));
1318 ACTION("Non-boolean value ignored\n");
1322 key->groupInfo = XkbWrapIntoRange;
1324 key->groupInfo = XkbClampIntoRange;
1325 key->defs.defined |= _Key_GroupInfo;
1327 else if ((uStrCaseCmp(field, "groupsclamp") == 0) ||
1328 (uStrCaseCmp(field, "clampgroups") == 0))
1330 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1333 ERROR("Illegal groupsClamp setting for %s\n",
1334 longText(key->name));
1335 ACTION("Non-boolean value ignored\n");
1339 key->groupInfo = XkbClampIntoRange;
1341 key->groupInfo = XkbWrapIntoRange;
1342 key->defs.defined |= _Key_GroupInfo;
1344 else if ((uStrCaseCmp(field, "groupsredirect") == 0) ||
1345 (uStrCaseCmp(field, "redirectgroups") == 0))
1347 if (!ExprResolveInteger
1348 (value, &tmp, SimpleLookup, (char *) groupNames))
1350 ERROR("Illegal group index for redirect of key %s\n",
1351 longText(key->name));
1352 ACTION("Definition with non-integer group ignored\n");
1355 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1357 ERROR("Out-of-range (1..%d) group for redirect of key %s\n",
1358 XkbNumKbdGroups, longText(key->name));
1359 ERROR("Ignoring illegal group %d\n", tmp.uval);
1363 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1364 key->defs.defined |= _Key_GroupInfo;
1368 ERROR("Unknown field %s in a symbol interpretation\n", field);
1369 ACTION("Definition ignored\n");
1376 SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1378 ExprResult tmp, name;
1380 if ((arrayNdx == NULL) && (warningLevel > 0))
1382 WARN("You must specify an index when specifying a group name\n");
1383 ACTION("Group name definition without array subscript ignored\n");
1386 if (!ExprResolveInteger
1387 (arrayNdx, &tmp, SimpleLookup, (char *) groupNames))
1389 ERROR("Illegal index in group name definition\n");
1390 ACTION("Definition with non-integer array index ignored\n");
1393 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1396 ("Attempt to specify name for illegal group (must be 1..%d)\n",
1397 XkbNumKbdGroups + 1);
1398 ACTION("Name for group %d ignored\n", tmp.uval);
1401 if (!ExprResolveString(value, &name, NULL, NULL))
1403 ERROR("Group name must be a string\n");
1404 ACTION("Illegal name for group %d ignored\n", tmp.uval);
1407 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1408 XkbcInternAtom(name.str, False);
1414 HandleSymbolsVar(VarDef * stmt, XkbcDescPtr xkb, SymbolsInfo * info)
1416 ExprResult elem, field, tmp;
1420 if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1421 return 0; /* internal error, already reported */
1422 if (elem.str && (uStrCaseCmp(elem.str, "key") == 0))
1424 ret = SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1427 else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) ||
1428 (uStrCaseCmp(field.str, "groupname") ==
1431 ret = SetGroupName(info, arrayNdx, stmt->value);
1433 else if ((elem.str == NULL)
1434 && ((uStrCaseCmp(field.str, "groupswrap") == 0)
1435 || (uStrCaseCmp(field.str, "wrapgroups") == 0)))
1437 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1439 ERROR("Illegal setting for global groupsWrap\n");
1440 ACTION("Non-boolean value ignored\n");
1445 info->groupInfo = XkbWrapIntoRange;
1447 info->groupInfo = XkbClampIntoRange;
1451 else if ((elem.str == NULL)
1452 && ((uStrCaseCmp(field.str, "groupsclamp") == 0)
1453 || (uStrCaseCmp(field.str, "clampgroups") == 0)))
1455 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1457 ERROR("Illegal setting for global groupsClamp\n");
1458 ACTION("Non-boolean value ignored\n");
1463 info->groupInfo = XkbClampIntoRange;
1465 info->groupInfo = XkbWrapIntoRange;
1469 else if ((elem.str == NULL)
1470 && ((uStrCaseCmp(field.str, "groupsredirect") == 0)
1471 || (uStrCaseCmp(field.str, "redirectgroups") == 0)))
1473 if (!ExprResolveInteger(stmt->value, &tmp,
1474 SimpleLookup, (char *) groupNames))
1476 ERROR("Illegal group index for global groupsRedirect\n");
1477 ACTION("Definition with non-integer group ignored\n");
1481 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1484 ("Out-of-range (1..%d) group for global groupsRedirect\n",
1486 ACTION("Ignoring illegal group %d\n", tmp.uval);
1490 info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange,
1496 else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0))
1498 ret = SetAllowNone(&info->dflt, arrayNdx, stmt->value);
1501 ret = SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1511 HandleSymbolsBody(VarDef * def,
1512 XkbcDescPtr xkb, KeyInfo * key, SymbolsInfo * info)
1515 ExprResult tmp, field;
1518 for (; def != NULL; def = (VarDef *) def->common.next)
1520 if ((def->name) && (def->name->type == ExprFieldRef))
1522 ok = HandleSymbolsVar(def, xkb, info);
1527 if (def->name == NULL)
1529 if ((def->value == NULL)
1530 || (def->value->op == ExprKeysymList))
1531 field.str = "symbols";
1533 field.str = "actions";
1538 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1541 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1549 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1551 unsigned group = info->explicit_group;
1556 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1559 WARN("For the map %s an explicit group specified\n", info->name);
1560 WARN("but key %s has more than one group defined\n",
1561 longText(key->name));
1562 ACTION("All groups except first one will be ignored\n");
1563 for (i = 1; i < XkbNumKbdGroups; i++)
1565 key->numLevels[i] = 0;
1566 if (key->syms[i] != NULL)
1567 uFree(key->syms[i]);
1568 key->syms[i] = (CARD32 *) NULL;
1569 if (key->acts[i] != NULL)
1570 uFree(key->acts[i]);
1571 key->acts[i] = (XkbcAction *) NULL;
1572 key->types[i] = (Atom) 0;
1575 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1577 key->numLevels[group] = key->numLevels[0];
1578 key->numLevels[0] = 0;
1579 key->syms[group] = key->syms[0];
1580 key->syms[0] = (CARD32 *) NULL;
1581 key->acts[group] = key->acts[0];
1582 key->acts[0] = (XkbcAction *) NULL;
1583 key->types[group] = key->types[0];
1584 key->types[0] = (Atom) 0;
1589 HandleSymbolsDef(SymbolsDef * stmt,
1590 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1595 CopyKeyInfo(&info->dflt, &key, False);
1596 key.defs.merge = stmt->merge;
1597 key.name = KeyNameToLong(stmt->keyName);
1598 if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1604 if (!SetExplicitGroup(info, &key))
1610 if (!AddKeySymbols(info, &key, xkb))
1619 HandleModMapDef(ModMapDef * def,
1620 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1627 if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn))
1629 ERROR("Illegal modifier map definition\n");
1630 ACTION("Ignoring map for non-modifier \"%s\"\n",
1631 XkbcAtomText(def->modifier));
1635 tmp.modifier = rtrn.uval;
1636 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1638 if ((key->op == ExprValue) && (key->type == TypeKeyName))
1640 tmp.haveSymbol = False;
1641 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1643 else if (ExprResolveKeySym(key, &rtrn, NULL, NULL))
1645 tmp.haveSymbol = True;
1646 tmp.u.keySym = rtrn.uval;
1650 ERROR("Modmap entries may contain only key names or keysyms\n");
1651 ACTION("Illegal definition for %s modifier ignored\n",
1652 XkbcModIndexText(tmp.modifier));
1656 ok = AddModMapEntry(info, &tmp) && ok;
1662 HandleSymbolsFile(XkbFile * file,
1663 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1667 info->name = _XkbDupString(file->name);
1671 switch (stmt->stmtType)
1674 if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1678 case StmtSymbolsDef:
1679 if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1683 if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1687 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1691 ERROR("Interpretation files may not include other types\n");
1692 ACTION("Ignoring definition of symbol interpretation\n");
1695 case StmtKeycodeDef:
1696 ERROR("Interpretation files may not include other types\n");
1697 ACTION("Ignoring definition of key name\n");
1701 if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1705 WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1710 if (info->errorCount > 10)
1713 ERROR("Too many errors\n");
1715 ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1723 FindKeyForSymbol(XkbcDescPtr xkb, CARD32 sym, unsigned int *kc_rtrn)
1726 register Bool gotOne;
1732 for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1734 if (j < (int) XkbKeyNumSyms(xkb, i))
1737 if ((XkbKeySym(xkb, i, j) == sym))
1751 * Find the given name in the xkb->map->types and return its index.
1753 * @param name The atom to search for.
1754 * @param type_rtrn Set to the index of the name if found.
1756 * @return True if found, False otherwise.
1759 FindNamedType(XkbcDescPtr xkb, Atom name, unsigned *type_rtrn)
1761 register unsigned n;
1763 if (xkb && xkb->map && xkb->map->types)
1765 for (n = 0; n < xkb->map->num_types; n++)
1767 if (xkb->map->types[n].name == (Atom) name)
1778 * Assign a type to the given sym and return the Atom for the type assigned.
1781 * - ONE_LEVEL for width 0/1
1782 * - ALPHABETIC for 2 shift levels, with lower/upercase
1783 * - KEYPAD for keypad keys.
1784 * - TWO_LEVEL for other 2 shift level keys.
1785 * and the same for four level keys.
1787 * @param width Number of sysms in syms.
1788 * @param syms The keysyms for the given key (must be size width).
1789 * @param typeNameRtrn Set to the Atom of the type name.
1791 * @returns True if a type could be found, False otherwise.
1794 FindAutomaticType(int width, CARD32 * syms, Atom * typeNameRtrn,
1798 if ((width == 1) || (width == 0))
1800 *typeNameRtrn = XkbcInternAtom("ONE_LEVEL", False);
1803 else if (width == 2)
1805 if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1807 *typeNameRtrn = XkbcInternAtom("ALPHABETIC", False);
1809 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1811 *typeNameRtrn = XkbcInternAtom("KEYPAD", False);
1816 *typeNameRtrn = XkbcInternAtom("TWO_LEVEL", False);
1820 else if (width <= 4)
1822 if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1823 if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1825 XkbcInternAtom("FOUR_LEVEL_ALPHABETIC", False);
1827 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL_SEMIALPHABETIC",
1830 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1831 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL_KEYPAD", False);
1833 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL", False);
1834 /* XXX: why not set autoType here? */
1836 return ((width >= 0) && (width <= 4));
1840 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1841 * groups, and reduce to one group if all groups are identical anyway.
1844 PrepareKeyDef(KeyInfo * key)
1846 int i, j, width, defined, lastGroup;
1849 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1850 /* get highest group number */
1851 for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1853 if (defined & (1 << i))
1861 /* If there are empty groups between non-empty ones fill them with data */
1862 /* from the first group. */
1863 /* We can make a wrong assumption here. But leaving gaps is worse. */
1864 for (i = lastGroup; i > 0; i--)
1866 if (defined & (1 << i))
1868 width = key->numLevels[0];
1869 if (key->typesDefined & 1)
1871 for (j = 0; j < width; j++)
1873 key->types[i] = key->types[0];
1875 key->typesDefined |= 1 << i;
1877 if ((key->actsDefined & 1) && key->acts[0])
1879 key->acts[i] = uTypedCalloc(width, XkbcAction);
1880 if (key->acts[i] == NULL)
1882 memcpy((void *) key->acts[i], (void *) key->acts[0],
1883 width * sizeof(XkbcAction));
1884 key->actsDefined |= 1 << i;
1886 if ((key->symsDefined & 1) && key->syms[0])
1888 key->syms[i] = uTypedCalloc(width, CARD32);
1889 if (key->syms[i] == NULL)
1891 memcpy((void *) key->syms[i], (void *) key->syms[0],
1892 width * sizeof(CARD32));
1893 key->symsDefined |= 1 << i;
1897 key->numLevels[i] = key->numLevels[0];
1900 /* If all groups are completely identical remove them all */
1901 /* exept the first one. */
1903 for (i = lastGroup; i > 0; i--)
1905 if ((key->numLevels[i] != key->numLevels[0]) ||
1906 (key->types[i] != key->types[0]))
1911 if ((key->syms[i] != key->syms[0]) &&
1912 (key->syms[i] == NULL || key->syms[0] == NULL ||
1913 memcmp((void *) key->syms[i], (void *) key->syms[0],
1914 sizeof(CARD32) * key->numLevels[0])))
1919 if ((key->acts[i] != key->acts[0]) &&
1920 (key->acts[i] == NULL || key->acts[0] == NULL ||
1921 memcmp((void *) key->acts[i], (void *) key->acts[0],
1922 sizeof(XkbcAction) * key->numLevels[0])))
1930 for (i = lastGroup; i > 0; i--)
1932 key->numLevels[i] = 0;
1933 if (key->syms[i] != NULL)
1934 uFree(key->syms[i]);
1935 key->syms[i] = (CARD32 *) NULL;
1936 if (key->acts[i] != NULL)
1937 uFree(key->acts[i]);
1938 key->acts[i] = (XkbcAction *) NULL;
1939 key->types[i] = (Atom) 0;
1941 key->symsDefined &= 1;
1942 key->actsDefined &= 1;
1943 key->typesDefined &= 1;
1949 * Copy the KeyInfo into the keyboard description.
1951 * This function recurses.
1954 CopySymbolsDef(XkbcDescPtr xkb, KeyInfo *key, int start_from)
1957 unsigned okc, kc, width, tmp, nGroups;
1959 Bool haveActions, autoType, useAlias;
1961 XkbcAction *outActs;
1962 unsigned types[XkbNumKbdGroups];
1964 useAlias = (start_from == 0);
1966 /* get the keycode for the key. */
1967 if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1970 if ((start_from == 0) && (warningLevel >= 5))
1972 WARN("Key %s not found in %s keycodes\n",
1973 longText(key->name),
1974 XkbcAtomText(xkb->names->keycodes));
1975 ACTION("Symbols ignored\n");
1980 haveActions = False;
1981 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1983 if (((i + 1) > nGroups)
1984 && (((key->symsDefined | key->actsDefined) & (1 << i))
1985 || (key->typesDefined) & (1 << i)))
1990 /* Assign the type to the key, if it is missing. */
1991 if (key->types[i] == None)
1993 if (key->dfltType != None)
1994 key->types[i] = key->dfltType;
1995 else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1996 &key->types[i], &autoType))
2001 if (warningLevel >= 5)
2003 WARN("No automatic type for %d symbols\n",
2004 (unsigned int) key->numLevels[i]);
2005 ACTION("Using %s for the %s key (keycode %d)\n",
2006 XkbcAtomText(key->types[i]),
2007 longText(key->name), kc);
2011 if (FindNamedType(xkb, key->types[i], &types[i]))
2013 if (!autoType || key->numLevels[i] > 2)
2014 xkb->server->explicit[kc] |= (1 << i);
2018 if (warningLevel >= 3)
2020 WARN("Type \"%s\" is not defined\n",
2021 XkbcAtomText(key->types[i]));
2022 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
2023 longText(key->name), kc);
2025 types[i] = XkbTwoLevelIndex;
2027 /* if the type specifies less syms than the key has, shrink the key */
2028 type = &xkb->map->types[types[i]];
2029 if (type->num_levels < key->numLevels[i])
2031 if (warningLevel > 0)
2034 ("Type \"%s\" has %d levels, but %s has %d symbols\n",
2035 XkbcAtomText(type->name),
2036 (unsigned int) type->num_levels,
2037 longText(key->name),
2038 (unsigned int) key->numLevels[i]);
2039 ACTION("Ignoring extra symbols\n");
2041 key->numLevels[i] = type->num_levels;
2043 if (key->numLevels[i] > width)
2044 width = key->numLevels[i];
2045 if (type->num_levels > width)
2046 width = type->num_levels;
2049 /* width is now the largest width found */
2051 i = width * nGroups;
2052 outSyms = XkbcResizeKeySyms(xkb, kc, i);
2053 if (outSyms == NULL)
2055 WSGO("Could not enlarge symbols for %s (keycode %d)\n",
2056 longText(key->name), kc);
2061 outActs = XkbcResizeKeyActions(xkb, kc, i);
2062 if (outActs == NULL)
2064 WSGO("Could not enlarge actions for %s (key %d)\n",
2065 longText(key->name), kc);
2068 xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
2072 if (key->defs.defined & _Key_GroupInfo)
2075 i = xkb->map->key_sym_map[kc].group_info;
2077 xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2078 xkb->map->key_sym_map[kc].width = width;
2079 for (i = 0; i < nGroups; i++)
2081 /* assign kt_index[i] to the index of the type in map->types.
2082 * kt_index[i] may have been set by a previous run (if we have two
2083 * layouts specified). Let's not overwrite it with the ONE_LEVEL
2084 * default group if we dont even have keys for this group anyway.
2086 * FIXME: There should be a better fix for this.
2088 if (key->numLevels[i])
2089 xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2090 if (key->syms[i] != NULL)
2092 /* fill key to "width" symbols*/
2093 for (tmp = 0; tmp < width; tmp++)
2095 if (tmp < key->numLevels[i])
2096 outSyms[tmp] = key->syms[i][tmp];
2098 outSyms[tmp] = NoSymbol;
2099 if ((outActs != NULL) && (key->acts[i] != NULL))
2101 if (tmp < key->numLevels[i])
2102 outActs[tmp] = key->acts[i][tmp];
2104 outActs[tmp].type = XkbSA_NoAction;
2112 switch (key->behavior.type & XkbKB_OpMask)
2116 case XkbKB_Overlay1:
2117 case XkbKB_Overlay2:
2118 /* find key by name! */
2119 if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True,
2120 CreateKeyNames(xkb), 0))
2122 if (warningLevel >= 1)
2124 WARN("Key %s not found in %s keycodes\n",
2125 longText(key->nameForOverlayKey),
2126 XkbcAtomText(xkb->names->keycodes));
2127 ACTION("Not treating %s as an overlay key \n",
2128 longText(key->name));
2132 key->behavior.data = okc;
2134 xkb->server->behaviors[kc] = key->behavior;
2135 xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2138 if (key->defs.defined & _Key_VModMap)
2140 xkb->server->vmodmap[kc] = key->vmodmap;
2141 xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2143 if (key->repeat != RepeatUndefined)
2145 if (key->repeat == RepeatYes)
2146 xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2148 xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2149 xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2152 /* do the same thing for the next key */
2153 CopySymbolsDef(xkb, key, kc + 1);
2158 CopyModMapDef(XkbcDescPtr xkb, ModMapEntry *entry)
2162 if ((!entry->haveSymbol)
2165 (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
2167 if (warningLevel >= 5)
2169 WARN("Key %s not found in %s keycodes\n",
2170 longText(entry->u.keyName),
2171 XkbcAtomText(xkb->names->keycodes));
2172 ACTION("Modifier map entry for %s not updated\n",
2173 XkbcModIndexText(entry->modifier));
2177 else if (entry->haveSymbol
2178 && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2180 if (warningLevel > 5)
2182 WARN("Key \"%s\" not found in %s symbol map\n",
2183 XkbcKeysymText(entry->u.keySym),
2184 XkbcAtomText(xkb->names->symbols));
2185 ACTION("Modifier map entry for %s not updated\n",
2186 XkbcModIndexText(entry->modifier));
2190 xkb->map->modmap[kc] |= (1 << entry->modifier);
2195 * Handle the xkb_symbols section of an xkb file.
2197 * @param file The parsed xkb_symbols section of the xkb file.
2198 * @param xkb Handle to the keyboard description to store the symbols in.
2199 * @param merge Merge strategy (e.g. MergeOverride).
2202 CompileSymbols(XkbFile *file, XkbcDescPtr xkb, unsigned merge)
2207 InitSymbolsInfo(&info, xkb);
2208 info.dflt.defs.fileID = file->id;
2209 info.dflt.defs.merge = merge;
2210 HandleSymbolsFile(file, xkb, merge, &info);
2212 if (info.nKeys == 0)
2214 if (info.errorCount == 0)
2218 /* alloc memory in the xkb struct */
2219 if (XkbcAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0)
2222 WSGO("Can not allocate names in CompileSymbols\n");
2223 ACTION("Symbols not added\n");
2226 if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2229 WSGO("Could not allocate client map in CompileSymbols\n");
2230 ACTION("Symbols not added\n");
2233 if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2235 WSGO("Could not allocate server map in CompileSymbols\n");
2236 ACTION("Symbols not added\n");
2239 if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2241 WSGO("Could not allocate controls in CompileSymbols\n");
2242 ACTION("Symbols not added\n");
2246 /* now copy info into xkb. */
2247 xkb->names->symbols = XkbcInternAtom(info.name, False);
2249 ApplyAliases(xkb, False, &info.aliases);
2250 for (i = 0; i < XkbNumKbdGroups; i++)
2252 if (info.groupNames[i] != None)
2253 xkb->names->groups[i] = info.groupNames[i];
2256 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2261 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2263 if (!CopySymbolsDef(xkb, key, 0))
2266 if (warningLevel > 3)
2268 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2270 if (xkb->names->keys[i].name[0] == '\0')
2272 if (XkbKeyNumGroups(xkb, i) < 1)
2275 memcpy(buf, xkb->names->keys[i].name, 4);
2278 ("No symbols defined for <%s> (keycode %d)\n",
2285 ModMapEntry *mm, *next;
2286 for (mm = info.modMap; mm != NULL; mm = next)
2288 if (!CopyModMapDef(xkb, mm))
2290 next = (ModMapEntry *) mm->defs.next;