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 ********************************************************/
31 #include <X11/keysym.h>
32 #include <X11/Xutil.h>
42 extern Atom tok_ONE_LEVEL;
43 extern Atom tok_TWO_LEVEL;
44 extern Atom tok_KEYPAD;
46 /***====================================================================***/
50 #define RepeatUndefined ~((unsigned)0)
52 #define _Key_Syms (1<<0)
53 #define _Key_Acts (1<<1)
54 #define _Key_Repeat (1<<2)
55 #define _Key_Behavior (1<<3)
56 #define _Key_Type_Dflt (1<<4)
57 #define _Key_Types (1<<5)
58 #define _Key_GroupInfo (1<<6)
59 #define _Key_VModMap (1<<7)
61 typedef struct _KeyInfo
64 unsigned long name; /* the 4 chars of the key name, as long */
65 unsigned char groupInfo;
66 unsigned char typesDefined;
67 unsigned char symsDefined;
68 unsigned char actsDefined;
69 short numLevels[XkbNumKbdGroups];
70 KeySym *syms[XkbNumKbdGroups];
71 XkbAction *acts[XkbNumKbdGroups];
72 Atom types[XkbNumKbdGroups];
75 unsigned short vmodmap;
76 unsigned long nameForOverlayKey;
77 unsigned long allowNone;
82 * Init the given key info to sane values.
85 InitKeyInfo(KeyInfo * info)
88 static char dflt[4] = "*";
90 info->defs.defined = 0;
91 info->defs.fileID = 0;
92 info->defs.merge = MergeOverride;
93 info->defs.next = NULL;
94 info->name = KeyNameToLong(dflt);
96 info->typesDefined = info->symsDefined = info->actsDefined = 0;
97 for (i = 0; i < XkbNumKbdGroups; i++)
99 info->numLevels[i] = 0;
100 info->types[i] = None;
101 info->syms[i] = NULL;
102 info->acts[i] = NULL;
104 info->dfltType = None;
105 info->behavior.type = XkbKB_Default;
106 info->behavior.data = 0;
108 info->nameForOverlayKey = 0;
109 info->repeat = RepeatUndefined;
115 * Free memory associated with this key info and reset to sane values.
118 FreeKeyInfo(KeyInfo * info)
122 info->defs.defined = 0;
123 info->defs.fileID = 0;
124 info->defs.merge = MergeOverride;
125 info->defs.next = NULL;
127 info->typesDefined = info->symsDefined = info->actsDefined = 0;
128 for (i = 0; i < XkbNumKbdGroups; i++)
130 info->numLevels[i] = 0;
131 info->types[i] = None;
132 if (info->syms[i] != NULL)
133 uFree(info->syms[i]);
134 info->syms[i] = NULL;
135 if (info->acts[i] != NULL)
136 uFree(info->acts[i]);
137 info->acts[i] = NULL;
139 info->dfltType = None;
140 info->behavior.type = XkbKB_Default;
141 info->behavior.data = 0;
143 info->nameForOverlayKey = 0;
144 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;
173 for (i = 0; i < XkbNumKbdGroups; i++)
175 width = new->numLevels[i];
176 if (old->syms[i] != NULL)
178 new->syms[i] = uTypedCalloc(width, KeySym);
182 new->numLevels[i] = 0;
185 memcpy((char *) new->syms[i], (char *) old->syms[i],
186 width * sizeof(KeySym));
188 if (old->acts[i] != NULL)
190 new->acts[i] = uTypedCalloc(width, XkbAction);
196 memcpy((char *) new->acts[i], (char *) old->acts[i],
197 width * sizeof(XkbAction));
204 /***====================================================================***/
206 typedef struct _ModMapEntry
213 unsigned long keyName;
218 #define SYMBOLS_INIT_SIZE 110
219 #define SYMBOLS_CHUNK 20
220 typedef struct _SymbolsInfo
222 char *name; /* e.g. pc+us+inet(evdev) */
226 unsigned explicit_group;
234 Atom groupNames[XkbNumKbdGroups];
241 InitSymbolsInfo(SymbolsInfo * info, XkbcDescPtr xkb)
245 tok_ONE_LEVEL = XkbInternAtom(NULL, "ONE_LEVEL", False);
246 tok_TWO_LEVEL = XkbInternAtom(NULL, "TWO_LEVEL", False);
247 tok_KEYPAD = XkbInternAtom(NULL, "KEYPAD", False);
249 info->explicit_group = 0;
250 info->errorCount = 0;
252 info->merge = MergeOverride;
254 info->szKeys = SYMBOLS_INIT_SIZE;
256 info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo);
258 for (i = 0; i < XkbNumKbdGroups; i++)
259 info->groupNames[i] = None;
260 InitKeyInfo(&info->dflt);
261 InitVModInfo(&info->vmods, xkb);
263 info->aliases = NULL;
268 FreeSymbolsInfo(SymbolsInfo * info)
277 for (i = 0; i < info->nKeys; i++)
279 FreeKeyInfo(&info->keys[i]);
286 ClearCommonInfo(&info->modMap->defs);
291 ClearAliases(&info->aliases);
292 info->aliases = NULL;
294 bzero((char *) info, sizeof(SymbolsInfo));
299 ResizeKeyGroup(KeyInfo * key,
300 unsigned group, unsigned atLeastSize, Bool forceActions)
305 tooSmall = (key->numLevels[group] < atLeastSize);
307 newWidth = atLeastSize;
309 newWidth = key->numLevels[group];
311 if ((key->syms[group] == NULL) || tooSmall)
313 key->syms[group] = uTypedRecalloc(key->syms[group],
314 key->numLevels[group], newWidth,
316 if (!key->syms[group])
319 if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) ||
320 (tooSmall && (key->acts[group] != NULL)))
322 key->acts[group] = uTypedRecalloc(key->acts[group],
323 key->numLevels[group], newWidth,
325 if (!key->acts[group])
328 key->numLevels[group] = newWidth;
333 MergeKeyGroups(SymbolsInfo * info,
334 KeyInfo * into, KeyInfo * from, unsigned group)
337 XkbAction *resultActs;
340 Bool report, clobber;
342 clobber = (from->defs.merge != MergeAugment);
343 report = (warningLevel > 9) ||
344 ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
345 if (into->numLevels[group] >= from->numLevels[group])
347 resultSyms = into->syms[group];
348 resultActs = into->acts[group];
349 resultWidth = into->numLevels[group];
353 resultSyms = from->syms[group];
354 resultActs = from->acts[group];
355 resultWidth = from->numLevels[group];
357 if (resultSyms == NULL)
359 resultSyms = uTypedCalloc(resultWidth, KeySym);
362 WSGO("Could not allocate symbols for group merge\n");
363 ACTION2("Group %d of key %s not merged\n", group,
364 longText(into->name, XkbMessage));
368 if ((resultActs == NULL) && (into->acts[group] || from->acts[group]))
370 resultActs = uTypedCalloc(resultWidth, XkbAction);
373 WSGO("Could not allocate actions for group merge\n");
374 ACTION2("Group %d of key %s not merged\n", group,
375 longText(into->name, XkbMessage));
379 for (i = 0; i < resultWidth; i++)
381 KeySym fromSym, toSym;
382 if (from->syms[group] && (i < from->numLevels[group]))
383 fromSym = from->syms[group][i];
386 if (into->syms[group] && (i < into->numLevels[group]))
387 toSym = into->syms[group][i];
390 if ((fromSym == NoSymbol) || (fromSym == toSym))
391 resultSyms[i] = toSym;
392 else if (toSym == NoSymbol)
393 resultSyms[i] = fromSym;
410 ("Multiple symbols for level %d/group %d on key %s\n",
411 i + 1, group + 1, longText(into->name, XkbMessage));
412 ACTION2("Using %s, ignoring %s\n",
413 XkbKeysymText(use, XkbMessage),
414 XkbKeysymText(ignore, XkbMessage));
418 if (resultActs != NULL)
420 XkbAction *fromAct, *toAct;
421 fromAct = (from->acts[group] ? &from->acts[group][i] : NULL);
422 toAct = (into->acts[group] ? &into->acts[group][i] : NULL);
423 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
426 resultActs[i] = *toAct;
428 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
429 && (fromAct != NULL))
431 resultActs[i] = *fromAct;
435 XkbAction *use, *ignore;
449 ("Multiple actions for level %d/group %d on key %s\n",
450 i + 1, group + 1, longText(into->name, XkbMessage));
451 ACTION2("Using %s, ignoring %s\n",
452 XkbActionTypeText(use->type, XkbMessage),
453 XkbActionTypeText(ignore->type, XkbMessage));
455 resultActs[i] = *use;
459 if ((into->syms[group] != NULL) && (resultSyms != into->syms[group]))
460 uFree(into->syms[group]);
461 if ((from->syms[group] != NULL) && (resultSyms != from->syms[group]))
462 uFree(from->syms[group]);
463 if ((into->acts[group] != NULL) && (resultActs != into->acts[group]))
464 uFree(into->acts[group]);
465 if ((from->acts[group] != NULL) && (resultActs != from->acts[group]))
466 uFree(from->acts[group]);
467 into->numLevels[group] = resultWidth;
468 into->syms[group] = resultSyms;
469 from->syms[group] = NULL;
470 into->acts[group] = resultActs;
471 from->acts[group] = NULL;
472 into->symsDefined |= (1 << group);
473 from->symsDefined &= ~(1 << group);
474 into->actsDefined |= (1 << group);
475 from->actsDefined &= ~(1 << group);
480 MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from)
483 unsigned collide = 0;
486 if (from->defs.merge == MergeReplace)
488 for (i = 0; i < XkbNumKbdGroups; i++)
490 if (into->numLevels[i] != 0)
493 uFree(into->syms[i]);
495 uFree(into->acts[i]);
499 bzero(from, sizeof(KeyInfo));
502 report = ((warningLevel > 9) ||
503 ((into->defs.fileID == from->defs.fileID)
504 && (warningLevel > 0)));
505 for (i = 0; i < XkbNumKbdGroups; i++)
507 if (from->numLevels[i] > 0)
509 if (into->numLevels[i] == 0)
511 into->numLevels[i] = from->numLevels[i];
512 into->syms[i] = from->syms[i];
513 into->acts[i] = from->acts[i];
514 into->symsDefined |= (1 << i);
515 from->syms[i] = NULL;
516 from->acts[i] = NULL;
517 from->numLevels[i] = 0;
518 from->symsDefined &= ~(1 << i);
520 into->defs.defined |= _Key_Syms;
522 into->defs.defined |= _Key_Acts;
529 collide |= _Key_Syms;
531 collide |= _Key_Acts;
533 MergeKeyGroups(info, into, from, (unsigned) i);
536 if (from->types[i] != None)
538 if ((into->types[i] != None) && (report) &&
539 (into->types[i] != from->types[i]))
542 collide |= _Key_Types;
543 if (from->defs.merge != MergeAugment)
545 use = from->types[i];
546 ignore = into->types[i];
550 use = into->types[i];
551 ignore = from->types[i];
554 ("Multiple definitions for group %d type of key %s\n",
555 i, longText(into->name, XkbMessage));
556 ACTION2("Using %s, ignoring %s\n",
557 XkbAtomText(NULL, use, XkbMessage),
558 XkbAtomText(NULL, ignore, XkbMessage));
560 if ((from->defs.merge != MergeAugment)
561 || (into->types[i] == None))
563 into->types[i] = from->types[i];
567 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
569 into->behavior = from->behavior;
570 into->nameForOverlayKey = from->nameForOverlayKey;
571 into->defs.defined |= _Key_Behavior;
573 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
575 into->vmodmap = from->vmodmap;
576 into->defs.defined |= _Key_VModMap;
578 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
580 into->repeat = from->repeat;
581 into->defs.defined |= _Key_Repeat;
583 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
585 into->dfltType = from->dfltType;
586 into->defs.defined |= _Key_Type_Dflt;
588 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
590 into->groupInfo = from->groupInfo;
591 into->defs.defined |= _Key_GroupInfo;
595 WARN1("Symbol map for key %s redefined\n",
596 longText(into->name, XkbMessage));
597 ACTION1("Using %s definition for conflicting fields\n",
598 (from->defs.merge == MergeAugment ? "first" : "last"));
604 AddKeySymbols(SymbolsInfo * info, KeyInfo * key, XkbcDescPtr xkb)
607 unsigned long real_name;
609 for (i = 0; i < info->nKeys; i++)
611 if (info->keys[i].name == key->name)
612 return MergeKeys(info, &info->keys[i], key);
614 if (FindKeyNameForAlias(xkb, key->name, &real_name))
616 for (i = 0; i < info->nKeys; i++)
618 if (info->keys[i].name == real_name)
619 return MergeKeys(info, &info->keys[i], key);
622 if (info->nKeys >= info->szKeys)
624 info->szKeys += SYMBOLS_CHUNK;
626 uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo);
629 WSGO("Could not allocate key symbols descriptions\n");
630 ACTION("Some key symbols definitions may be lost\n");
634 return CopyKeyInfo(key, &info->keys[info->nKeys++], True);
638 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
643 clobber = (new->defs.merge != MergeAugment);
644 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
646 if (new->haveSymbol && mm->haveSymbol
647 && (new->u.keySym == mm->u.keySym))
649 unsigned use, ignore;
650 if (mm->modifier != new->modifier)
655 ignore = mm->modifier;
660 ignore = new->modifier;
663 ("%s added to symbol map for multiple modifiers\n",
664 XkbKeysymText(new->u.keySym, XkbMessage));
665 ACTION2("Using %s, ignoring %s.\n",
666 XkbModIndexText(use, XkbMessage),
667 XkbModIndexText(ignore, XkbMessage));
672 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
673 (new->u.keyName == mm->u.keyName))
675 unsigned use, ignore;
676 if (mm->modifier != new->modifier)
681 ignore = mm->modifier;
686 ignore = new->modifier;
688 ERROR1("Key %s added to map for multiple modifiers\n",
689 longText(new->u.keyName, XkbMessage));
690 ACTION2("Using %s, ignoring %s.\n",
691 XkbModIndexText(use, XkbMessage),
692 XkbModIndexText(ignore, XkbMessage));
698 mm = uTypedAlloc(ModMapEntry);
701 WSGO("Could not allocate modifier map entry\n");
702 ACTION1("Modifier map for %s will be incomplete\n",
703 XkbModIndexText(new->modifier, XkbMessage));
707 mm->defs.next = &info->modMap->defs;
712 /***====================================================================***/
715 MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from,
716 unsigned merge, XkbcDescPtr xkb)
721 if (from->errorCount > 0)
723 into->errorCount += from->errorCount;
726 if (into->name == NULL)
728 into->name = from->name;
731 for (i = 0; i < XkbNumKbdGroups; i++)
733 if (from->groupNames[i] != None)
735 if ((merge != MergeAugment) || (into->groupNames[i] == None))
736 into->groupNames[i] = from->groupNames[i];
739 for (i = 0, key = from->keys; i < from->nKeys; i++, key++)
741 if (merge != MergeDefault)
742 key->defs.merge = merge;
743 if (!AddKeySymbols(into, key, xkb))
746 if (from->modMap != NULL)
748 ModMapEntry *mm, *next;
749 for (mm = from->modMap; mm != NULL; mm = next)
751 if (merge != MergeDefault)
752 mm->defs.merge = merge;
753 if (!AddModMapEntry(into, mm))
755 next = (ModMapEntry *) mm->defs.next;
760 if (!MergeAliases(&into->aliases, &from->aliases, merge))
765 typedef void (*FileHandler) (XkbFile * /* rtrn */ ,
766 XkbcDescPtr /* xkb */ ,
767 unsigned /* merge */ ,
768 SymbolsInfo * /* included */
772 HandleIncludeSymbols(IncludeStmt * stmt,
773 XkbcDescPtr xkb, SymbolsInfo * info, FileHandler hndlr)
777 SymbolsInfo included;
781 if ((stmt->file == NULL) && (stmt->map == NULL))
785 bzero(info, sizeof(SymbolsInfo));
787 else if (ProcessIncludeFile(stmt, XkmSymbolsIndex, &rtrn, &newMerge))
789 InitSymbolsInfo(&included, xkb);
790 included.fileID = included.dflt.defs.fileID = rtrn->id;
791 included.merge = included.dflt.defs.merge = MergeOverride;
794 included.explicit_group = atoi(stmt->modifier) - 1;
798 included.explicit_group = info->explicit_group;
800 (*hndlr) (rtrn, xkb, MergeOverride, &included);
801 if (stmt->stmt != NULL)
803 if (included.name != NULL)
804 uFree(included.name);
805 included.name = stmt->stmt;
811 info->errorCount += 10;
814 if ((stmt->next != NULL) && (included.errorCount < 1))
818 SymbolsInfo next_incl;
820 for (next = stmt->next; next != NULL; next = next->next)
822 if ((next->file == NULL) && (next->map == NULL))
825 MergeIncludedSymbols(&included, info, next->merge, xkb);
826 FreeSymbolsInfo(info);
828 else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op))
830 InitSymbolsInfo(&next_incl, xkb);
831 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
832 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride;
835 next_incl.explicit_group = atoi(next->modifier) - 1;
839 next_incl.explicit_group = info->explicit_group;
841 (*hndlr) (rtrn, xkb, MergeOverride, &next_incl);
842 MergeIncludedSymbols(&included, &next_incl, op, xkb);
843 FreeSymbolsInfo(&next_incl);
847 info->errorCount += 10;
856 MergeIncludedSymbols(info, &included, newMerge, xkb);
857 FreeSymbolsInfo(&included);
859 return (info->errorCount == 0);
862 static LookupEntry groupNames[] = {
879 GetGroupIndex(KeyInfo * key,
880 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
890 if (arrayNdx == NULL)
895 defined = key->symsDefined;
897 defined = key->actsDefined;
899 for (i = 0; i < XkbNumKbdGroups; i++)
901 if ((defined & (1 << i)) == 0)
907 ERROR3("Too many groups of %s for key %s (max %d)\n", name,
908 longText(key->name, XkbMessage), XkbNumKbdGroups + 1);
909 ACTION1("Ignoring %s defined for extra groups\n", name);
912 if (!ExprResolveInteger
913 (arrayNdx, &tmp, SimpleLookup, (char *) groupNames))
915 ERROR2("Illegal group index for %s of key %s\n", name,
916 longText(key->name, XkbMessage));
917 ACTION("Definition with non-integer array index ignored\n");
920 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
922 ERROR3("Group index for %s of key %s is out of range (1..%d)\n",
923 name, longText(key->name, XkbMessage), XkbNumKbdGroups + 1);
924 ACTION2("Ignoring %s for group %d\n", name, tmp.uval);
927 *ndx_rtrn = tmp.uval - 1;
932 AddSymbolsToKey(KeyInfo * key,
935 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
940 if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx))
944 key->symsDefined |= (1 << ndx);
947 if (value->op != ExprKeysymList)
949 ERROR1("Expected a list of symbols, found %s\n",
950 exprOpText(value->op));
951 ACTION2("Ignoring symbols for group %d of %s\n", ndx,
952 longText(key->name, XkbMessage));
955 if (key->syms[ndx] != NULL)
957 WSGO2("Symbols for key %s, group %d already defined\n",
958 longText(key->name, XkbMessage), ndx);
961 nSyms = value->value.list.nSyms;
962 if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
963 (!ResizeKeyGroup(key, ndx, nSyms, False)))
965 WSGO2("Could not resize group %d of key %s\n", ndx,
966 longText(key->name, XkbMessage));
967 ACTION("Symbols lost\n");
970 key->symsDefined |= (1 << ndx);
971 memcpy((char *) key->syms[ndx], (char *) value->value.list.syms,
972 nSyms * sizeof(KeySym));
973 for (i = key->numLevels[ndx] - 1;
974 (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--)
976 key->numLevels[ndx]--;
982 AddActionsToKey(KeyInfo * key,
985 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
992 if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx))
997 key->actsDefined |= (1 << ndx);
1000 if (value->op != ExprActionList)
1002 WSGO1("Bad expression type (%d) for action list value\n", value->op);
1003 ACTION2("Ignoring actions for group %d of %s\n", ndx,
1004 longText(key->name, XkbMessage));
1007 if (key->acts[ndx] != NULL)
1009 WSGO2("Actions for key %s, group %d already defined\n",
1010 longText(key->name, XkbMessage), ndx);
1013 for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1015 act = (ExprDef *) act->common.next;
1019 WSGO("Action list but not actions in AddActionsToKey\n");
1022 if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1023 (!ResizeKeyGroup(key, ndx, nActs, True)))
1025 WSGO2("Could not resize group %d of key %s\n", ndx,
1026 longText(key->name, XkbMessage));
1027 ACTION("Actions lost\n");
1030 key->actsDefined |= (1 << ndx);
1032 toAct = (XkbAnyAction *) key->acts[ndx];
1033 act = value->value.child;
1034 for (i = 0; i < nActs; i++, toAct++)
1036 if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action))
1038 ERROR1("Illegal action definition for %s\n",
1039 longText(key->name, XkbMessage));
1040 ACTION2("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1042 act = (ExprDef *) act->common.next;
1048 SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value)
1051 unsigned radio_groups = 0;
1053 if (arrayNdx == NULL)
1055 radio_groups = XkbAllRadioGroupsMask;
1059 if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL))
1061 ERROR("Illegal index in group name definition\n");
1062 ACTION("Definition with non-integer array index ignored\n");
1065 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1067 ERROR1("Illegal radio group specified (must be 1..%d)\n",
1068 XkbMaxRadioGroups + 1);
1069 ACTION1("Value of \"allow none\" for group %d ignored\n",
1073 radio_groups |= (1 << (tmp.uval - 1));
1075 if (!ExprResolveBoolean(value, &tmp, NULL, NULL))
1077 ERROR1("Illegal \"allow none\" value for %s\n",
1078 longText(key->name, XkbMessage));
1079 ACTION("Non-boolean value ignored\n");
1083 key->allowNone |= radio_groups;
1085 key->allowNone &= ~radio_groups;
1090 static LookupEntry lockingEntries[] = {
1091 {"true", XkbKB_Lock},
1092 {"yes", XkbKB_Lock},
1094 {"false", XkbKB_Default},
1095 {"no", XkbKB_Default},
1096 {"off", XkbKB_Default},
1097 {"permanent", XkbKB_Lock | XkbKB_Permanent},
1101 static LookupEntry repeatEntries[] = {
1102 {"true", RepeatYes},
1105 {"false", RepeatNo},
1108 {"default", RepeatUndefined},
1112 static LookupEntry rgEntries[] = {
1118 SetSymbolsField(KeyInfo * key,
1121 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1126 if (uStrCaseCmp(field, "type") == 0)
1129 if ((!ExprResolveString(value, &tmp, NULL, NULL))
1130 && (warningLevel > 0))
1132 WARN("The type field of a key symbol map must be a string\n");
1133 ACTION("Ignoring illegal type definition\n");
1135 if (arrayNdx == NULL)
1137 key->dfltType = XkbInternAtom(NULL, tmp.str, False);
1138 key->defs.defined |= _Key_Type_Dflt;
1140 else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup,
1141 (char *) groupNames))
1143 ERROR1("Illegal group index for type of key %s\n",
1144 longText(key->name, XkbMessage));
1145 ACTION("Definition with non-integer array index ignored\n");
1148 else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups))
1151 ("Group index for type of key %s is out of range (1..%d)\n",
1152 longText(key->name, XkbMessage), XkbNumKbdGroups + 1);
1153 ACTION1("Ignoring type for group %d\n", ndx.uval);
1158 key->types[ndx.uval - 1] = XkbInternAtom(NULL, tmp.str, False);
1159 key->typesDefined |= (1 << (ndx.uval - 1));
1162 else if (uStrCaseCmp(field, "symbols") == 0)
1163 return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1164 else if (uStrCaseCmp(field, "actions") == 0)
1165 return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1166 else if ((uStrCaseCmp(field, "vmods") == 0) ||
1167 (uStrCaseCmp(field, "virtualmods") == 0) ||
1168 (uStrCaseCmp(field, "virtualmodifiers") == 0))
1170 ok = ExprResolveModMask(value, &tmp, LookupVModMask, (char *) xkb);
1173 key->vmodmap = (tmp.uval >> 8);
1174 key->defs.defined |= _Key_VModMap;
1178 ERROR1("Expected a virtual modifier mask, found %s\n",
1179 exprOpText(value->op));
1180 ACTION1("Ignoring virtual modifiers definition for key %s\n",
1181 longText(key->name, XkbMessage));
1184 else if ((uStrCaseCmp(field, "locking") == 0)
1185 || (uStrCaseCmp(field, "lock") == 0)
1186 || (uStrCaseCmp(field, "locks") == 0))
1188 ok = ExprResolveEnum(value, &tmp, lockingEntries);
1190 key->behavior.type = tmp.uval;
1191 key->defs.defined |= _Key_Behavior;
1193 else if ((uStrCaseCmp(field, "radiogroup") == 0) ||
1194 (uStrCaseCmp(field, "permanentradiogroup") == 0))
1196 Bool permanent = False;
1197 if (uStrCaseCmp(field, "permanentradiogroup") == 0)
1199 ok = ExprResolveInteger(value, &tmp, SimpleLookup,
1200 (char *) rgEntries);
1203 ERROR1("Illegal radio group specification for %s\n",
1204 longText(key->name, XkbMessage));
1205 ACTION("Non-integer radio group ignored\n");
1210 key->behavior.type = XkbKB_Default;
1211 key->behavior.data = 0;
1214 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1217 ("Radio group specification for %s out of range (1..32)\n",
1218 longText(key->name, XkbMessage));
1219 ACTION1("Illegal radio group %d ignored\n", tmp.uval);
1222 key->behavior.type =
1223 XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0);
1224 key->behavior.data = tmp.uval - 1;
1225 if (key->allowNone & (1 << (tmp.uval - 1)))
1226 key->behavior.data |= XkbKB_RGAllowNone;
1227 key->defs.defined |= _Key_Behavior;
1229 else if (uStrCaseEqual(field, "allownone"))
1231 ok = SetAllowNone(key, arrayNdx, value);
1233 else if (uStrCasePrefix("overlay", field) ||
1234 uStrCasePrefix("permanentoverlay", field))
1236 Bool permanent = False;
1239 if (uStrCasePrefix("permanent", field))
1242 which = &field[sizeof("permanentoverlay") - 1];
1246 which = &field[sizeof("overlay") - 1];
1248 if (sscanf(which, "%d", &overlayNdx) == 1)
1250 if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0))
1252 ERROR2("Illegal overlay %d specified for %s\n",
1253 overlayNdx, longText(key->name, XkbMessage));
1254 ACTION("Ignored\n");
1258 else if (*which == '\0')
1260 else if (warningLevel > 0)
1262 ERROR2("Illegal overlay \"%s\" specified for %s\n",
1263 which, longText(key->name, XkbMessage));
1264 ACTION("Ignored\n");
1267 ok = ExprResolveKeyName(value, &tmp, NULL, NULL);
1270 ERROR1("Illegal overlay key specification for %s\n",
1271 longText(key->name, XkbMessage));
1272 ACTION("Overlay key must be specified by name\n");
1275 if (overlayNdx == 1)
1276 key->behavior.type = XkbKB_Overlay1;
1278 key->behavior.type = XkbKB_Overlay2;
1280 key->behavior.type |= XkbKB_Permanent;
1282 key->behavior.data = 0;
1283 key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name);
1284 key->defs.defined |= _Key_Behavior;
1286 else if ((uStrCaseCmp(field, "repeating") == 0) ||
1287 (uStrCaseCmp(field, "repeats") == 0) ||
1288 (uStrCaseCmp(field, "repeat") == 0))
1290 ok = ExprResolveEnum(value, &tmp, repeatEntries);
1293 ERROR1("Illegal repeat setting for %s\n",
1294 longText(key->name, XkbMessage));
1295 ACTION("Non-boolean repeat setting ignored\n");
1298 key->repeat = tmp.uval;
1299 key->defs.defined |= _Key_Repeat;
1301 else if ((uStrCaseCmp(field, "groupswrap") == 0) ||
1302 (uStrCaseCmp(field, "wrapgroups") == 0))
1304 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1307 ERROR1("Illegal groupsWrap setting for %s\n",
1308 longText(key->name, XkbMessage));
1309 ACTION("Non-boolean value ignored\n");
1313 key->groupInfo = XkbWrapIntoRange;
1315 key->groupInfo = XkbClampIntoRange;
1316 key->defs.defined |= _Key_GroupInfo;
1318 else if ((uStrCaseCmp(field, "groupsclamp") == 0) ||
1319 (uStrCaseCmp(field, "clampgroups") == 0))
1321 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1324 ERROR1("Illegal groupsClamp setting for %s\n",
1325 longText(key->name, XkbMessage));
1326 ACTION("Non-boolean value ignored\n");
1330 key->groupInfo = XkbClampIntoRange;
1332 key->groupInfo = XkbWrapIntoRange;
1333 key->defs.defined |= _Key_GroupInfo;
1335 else if ((uStrCaseCmp(field, "groupsredirect") == 0) ||
1336 (uStrCaseCmp(field, "redirectgroups") == 0))
1338 if (!ExprResolveInteger
1339 (value, &tmp, SimpleLookup, (char *) groupNames))
1341 ERROR1("Illegal group index for redirect of key %s\n",
1342 longText(key->name, XkbMessage));
1343 ACTION("Definition with non-integer group ignored\n");
1346 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1348 ERROR2("Out-of-range (1..%d) group for redirect of key %s\n",
1349 XkbNumKbdGroups, longText(key->name, XkbMessage));
1350 ERROR1("Ignoring illegal group %d\n", tmp.uval);
1354 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1355 key->defs.defined |= _Key_GroupInfo;
1359 ERROR1("Unknown field %s in a symbol interpretation\n", field);
1360 ACTION("Definition ignored\n");
1367 SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1369 ExprResult tmp, name;
1371 if ((arrayNdx == NULL) && (warningLevel > 0))
1373 WARN("You must specify an index when specifying a group name\n");
1374 ACTION("Group name definition without array subscript ignored\n");
1377 if (!ExprResolveInteger
1378 (arrayNdx, &tmp, SimpleLookup, (char *) groupNames))
1380 ERROR("Illegal index in group name definition\n");
1381 ACTION("Definition with non-integer array index ignored\n");
1384 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1387 ("Attempt to specify name for illegal group (must be 1..%d)\n",
1388 XkbNumKbdGroups + 1);
1389 ACTION1("Name for group %d ignored\n", tmp.uval);
1392 if (!ExprResolveString(value, &name, NULL, NULL))
1394 ERROR("Group name must be a string\n");
1395 ACTION1("Illegal name for group %d ignored\n", tmp.uval);
1398 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1399 XkbInternAtom(NULL, name.str, False);
1405 HandleSymbolsVar(VarDef * stmt, XkbcDescPtr xkb, SymbolsInfo * info)
1407 ExprResult elem, field, tmp;
1410 if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1411 return 0; /* internal error, already reported */
1412 if (elem.str && (uStrCaseCmp(elem.str, "key") == 0))
1414 return SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1417 else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) ||
1418 (uStrCaseCmp(field.str, "groupname") ==
1421 return SetGroupName(info, arrayNdx, stmt->value);
1423 else if ((elem.str == NULL)
1424 && ((uStrCaseCmp(field.str, "groupswrap") == 0)
1425 || (uStrCaseCmp(field.str, "wrapgroups") == 0)))
1427 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1429 ERROR("Illegal setting for global groupsWrap\n");
1430 ACTION("Non-boolean value ignored\n");
1434 info->groupInfo = XkbWrapIntoRange;
1436 info->groupInfo = XkbClampIntoRange;
1439 else if ((elem.str == NULL)
1440 && ((uStrCaseCmp(field.str, "groupsclamp") == 0)
1441 || (uStrCaseCmp(field.str, "clampgroups") == 0)))
1443 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1445 ERROR("Illegal setting for global groupsClamp\n");
1446 ACTION("Non-boolean value ignored\n");
1450 info->groupInfo = XkbClampIntoRange;
1452 info->groupInfo = XkbWrapIntoRange;
1455 else if ((elem.str == NULL)
1456 && ((uStrCaseCmp(field.str, "groupsredirect") == 0)
1457 || (uStrCaseCmp(field.str, "redirectgroups") == 0)))
1459 if (!ExprResolveInteger(stmt->value, &tmp,
1460 SimpleLookup, (char *) groupNames))
1462 ERROR("Illegal group index for global groupsRedirect\n");
1463 ACTION("Definition with non-integer group ignored\n");
1466 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1469 ("Out-of-range (1..%d) group for global groupsRedirect\n",
1471 ACTION1("Ignoring illegal group %d\n", tmp.uval);
1474 info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval);
1477 else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0))
1479 return SetAllowNone(&info->dflt, arrayNdx, stmt->value);
1481 return SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1486 HandleSymbolsBody(VarDef * def,
1487 XkbcDescPtr xkb, KeyInfo * key, SymbolsInfo * info)
1490 ExprResult tmp, field;
1493 for (; def != NULL; def = (VarDef *) def->common.next)
1495 if ((def->name) && (def->name->type == ExprFieldRef))
1497 ok = HandleSymbolsVar(def, xkb, info);
1502 if (def->name == NULL)
1504 if ((def->value == NULL)
1505 || (def->value->op == ExprKeysymList))
1506 field.str = "symbols";
1508 field.str = "actions";
1513 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1516 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1524 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1526 unsigned group = info->explicit_group;
1531 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1534 WARN1("For the map %s an explicit group specified\n", info->name);
1535 WARN1("but key %s has more than one group defined\n",
1536 longText(key->name, XkbMessage));
1537 ACTION("All groups except first one will be ignored\n");
1538 for (i = 1; i < XkbNumKbdGroups; i++)
1540 key->numLevels[i] = 0;
1541 if (key->syms[i] != NULL)
1542 uFree(key->syms[i]);
1543 key->syms[i] = (KeySym *) NULL;
1544 if (key->acts[i] != NULL)
1545 uFree(key->acts[i]);
1546 key->acts[i] = (XkbAction *) NULL;
1547 key->types[i] = (Atom) 0;
1550 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1552 key->numLevels[group] = key->numLevels[0];
1553 key->numLevels[0] = 0;
1554 key->syms[group] = key->syms[0];
1555 key->syms[0] = (KeySym *) NULL;
1556 key->acts[group] = key->acts[0];
1557 key->acts[0] = (XkbAction *) NULL;
1558 key->types[group] = key->types[0];
1559 key->types[0] = (Atom) 0;
1564 HandleSymbolsDef(SymbolsDef * stmt,
1565 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1570 CopyKeyInfo(&info->dflt, &key, False);
1571 key.defs.merge = stmt->merge;
1572 key.name = KeyNameToLong(stmt->keyName);
1573 if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1579 if (!SetExplicitGroup(info, &key))
1585 if (!AddKeySymbols(info, &key, xkb))
1594 HandleModMapDef(ModMapDef * def,
1595 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1602 if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn))
1604 ERROR("Illegal modifier map definition\n");
1605 ACTION1("Ignoring map for non-modifier \"%s\"\n",
1606 XkbAtomText(NULL, def->modifier, XkbMessage));
1610 tmp.modifier = rtrn.uval;
1611 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1613 if ((key->op == ExprValue) && (key->type == TypeKeyName))
1615 tmp.haveSymbol = False;
1616 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1618 else if (ExprResolveKeySym(key, &rtrn, NULL, NULL))
1620 tmp.haveSymbol = True;
1621 tmp.u.keySym = rtrn.uval;
1625 ERROR("Modmap entries may contain only key names or keysyms\n");
1626 ACTION1("Illegal definition for %s modifier ignored\n",
1627 XkbModIndexText(tmp.modifier, XkbMessage));
1631 ok = AddModMapEntry(info, &tmp) && ok;
1637 HandleSymbolsFile(XkbFile * file,
1638 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1642 info->name = uStringDup(file->name);
1646 switch (stmt->stmtType)
1649 if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1653 case StmtSymbolsDef:
1654 if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1658 if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1662 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1666 ERROR("Interpretation files may not include other types\n");
1667 ACTION("Ignoring definition of symbol interpretation\n");
1670 case StmtKeycodeDef:
1671 ERROR("Interpretation files may not include other types\n");
1672 ACTION("Ignoring definition of key name\n");
1676 if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1680 WSGO1("Unexpected statement type %d in HandleSymbolsFile\n",
1685 if (info->errorCount > 10)
1688 ERROR("Too many errors\n");
1690 ACTION1("Abandoning symbols file \"%s\"\n", file->topName);
1698 FindKeyForSymbol(XkbcDescPtr xkb, KeySym sym, unsigned int *kc_rtrn)
1701 register Bool gotOne;
1707 for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1709 if (j < (int) XkbKeyNumSyms(xkb, i))
1712 if ((XkbKeySym(xkb, i, j) == sym))
1726 * Find the given name in the xkb->map->types and return its index.
1728 * @param name The atom to search for.
1729 * @param type_rtrn Set to the index of the name if found.
1731 * @return True if found, False otherwise.
1734 FindNamedType(XkbcDescPtr xkb, Atom name, unsigned *type_rtrn)
1736 register unsigned n;
1738 if (xkb && xkb->map && xkb->map->types)
1740 for (n = 0; n < xkb->map->num_types; n++)
1742 if (xkb->map->types[n].name == (Atom) name)
1753 KSIsLower(KeySym ks)
1755 KeySym lower, upper;
1756 XConvertCase(ks, &lower, &upper);
1760 return (ks == lower ? True : False);
1764 KSIsUpper(KeySym ks)
1766 KeySym lower, upper;
1767 XConvertCase(ks, &lower, &upper);
1771 return (ks == upper ? True : False);
1775 * Assign a type to the given sym and return the Atom for the type assigned.
1778 * - ONE_LEVEL for width 0/1
1779 * - ALPHABETIC for 2 shift levels, with lower/upercase
1780 * - KEYPAD for keypad keys.
1781 * - TWO_LEVEL for other 2 shift level keys.
1782 * and the same for four level keys.
1784 * @param width Number of sysms in syms.
1785 * @param syms The keysyms for the given key (must be size width).
1786 * @param typeNameRtrn Set to the Atom of the type name.
1788 * @returns True if a type could be found, False otherwise.
1791 FindAutomaticType(int width, KeySym * syms, Atom * typeNameRtrn,
1795 if ((width == 1) || (width == 0))
1797 *typeNameRtrn = XkbInternAtom(NULL, "ONE_LEVEL", False);
1800 else if (width == 2)
1802 if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]))
1804 *typeNameRtrn = XkbInternAtom(NULL, "ALPHABETIC", False);
1806 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1808 *typeNameRtrn = XkbInternAtom(NULL, "KEYPAD", False);
1813 *typeNameRtrn = XkbInternAtom(NULL, "TWO_LEVEL", False);
1817 else if (width <= 4)
1819 if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]))
1820 if (KSIsLower(syms[2]) && KSIsUpper(syms[3]))
1822 XkbInternAtom(NULL, "FOUR_LEVEL_ALPHABETIC", False);
1824 *typeNameRtrn = XkbInternAtom(NULL,
1825 "FOUR_LEVEL_SEMIALPHABETIC",
1828 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1829 *typeNameRtrn = XkbInternAtom(NULL, "FOUR_LEVEL_KEYPAD", False);
1831 *typeNameRtrn = XkbInternAtom(NULL, "FOUR_LEVEL", False);
1832 /* XXX: why not set autoType here? */
1834 return ((width >= 0) && (width <= 4));
1838 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1839 * groups, and reduce to one group if all groups are identical anyway.
1842 PrepareKeyDef(KeyInfo * key)
1844 int i, j, width, defined, lastGroup;
1847 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1848 /* get highest group number */
1849 for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1851 if (defined & (1 << i))
1859 /* If there are empty groups between non-empty ones fill them with data */
1860 /* from the first group. */
1861 /* We can make a wrong assumption here. But leaving gaps is worse. */
1862 for (i = lastGroup; i > 0; i--)
1864 if (defined & (1 << i))
1866 width = key->numLevels[0];
1867 if (key->typesDefined & 1)
1869 for (j = 0; j < width; j++)
1871 key->types[i] = key->types[0];
1873 key->typesDefined |= 1 << i;
1875 if ((key->actsDefined & 1) && key->acts[0])
1877 key->acts[i] = uTypedCalloc(width, XkbAction);
1878 if (key->acts[i] == NULL)
1880 memcpy((void *) key->acts[i], (void *) key->acts[0],
1881 width * sizeof(XkbAction));
1882 key->actsDefined |= 1 << i;
1884 if ((key->symsDefined & 1) && key->syms[0])
1886 key->syms[i] = uTypedCalloc(width, KeySym);
1887 if (key->syms[i] == NULL)
1889 memcpy((void *) key->syms[i], (void *) key->syms[0],
1890 width * sizeof(KeySym));
1891 key->symsDefined |= 1 << i;
1895 key->numLevels[i] = key->numLevels[0];
1898 /* If all groups are completely identical remove them all */
1899 /* exept the first one. */
1901 for (i = lastGroup; i > 0; i--)
1903 if ((key->numLevels[i] != key->numLevels[0]) ||
1904 (key->types[i] != key->types[0]))
1909 if ((key->syms[i] != key->syms[0]) &&
1910 (key->syms[i] == NULL || key->syms[0] == NULL ||
1911 memcmp((void *) key->syms[i], (void *) key->syms[0],
1912 sizeof(KeySym) * key->numLevels[0])))
1917 if ((key->acts[i] != key->acts[0]) &&
1918 (key->acts[i] == NULL || key->acts[0] == NULL ||
1919 memcmp((void *) key->acts[i], (void *) key->acts[0],
1920 sizeof(XkbAction) * key->numLevels[0])))
1928 for (i = lastGroup; i > 0; i--)
1930 key->numLevels[i] = 0;
1931 if (key->syms[i] != NULL)
1932 uFree(key->syms[i]);
1933 key->syms[i] = (KeySym *) NULL;
1934 if (key->acts[i] != NULL)
1935 uFree(key->acts[i]);
1936 key->acts[i] = (XkbAction *) NULL;
1937 key->types[i] = (Atom) 0;
1939 key->symsDefined &= 1;
1940 key->actsDefined &= 1;
1941 key->typesDefined &= 1;
1947 * Copy the KeyInfo into the keyboard description.
1949 * This function recurses.
1952 CopySymbolsDef(XkbcDescPtr xkb, KeyInfo *key, int start_from)
1955 unsigned okc, kc, width, tmp, nGroups;
1957 Bool haveActions, autoType, useAlias;
1960 unsigned types[XkbNumKbdGroups];
1962 useAlias = (start_from == 0);
1964 /* get the keycode for the key. */
1965 if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1968 if ((start_from == 0) && (warningLevel >= 5))
1970 WARN2("Key %s not found in %s keycodes\n",
1971 longText(key->name, XkbMessage),
1972 XkbAtomText(NULL, xkb->names->keycodes, XkbMessage));
1973 ACTION("Symbols ignored\n");
1978 haveActions = False;
1979 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1981 if (((i + 1) > nGroups)
1982 && (((key->symsDefined | key->actsDefined) & (1 << i))
1983 || (key->typesDefined) & (1 << i)))
1988 /* Assign the type to the key, if it is missing. */
1989 if (key->types[i] == None)
1991 if (key->dfltType != None)
1992 key->types[i] = key->dfltType;
1993 else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1994 &key->types[i], &autoType))
1999 if (warningLevel >= 5)
2001 WARN1("No automatic type for %d symbols\n",
2002 (unsigned int) key->numLevels[i]);
2003 ACTION3("Using %s for the %s key (keycode %d)\n",
2004 XkbAtomText(NULL, key->types[i],
2006 longText(key->name, XkbMessage), kc);
2010 if (FindNamedType(xkb, key->types[i], &types[i]))
2012 if (!autoType || key->numLevels[i] > 2)
2013 xkb->server->explicit[kc] |= (1 << i);
2017 if (warningLevel >= 3)
2019 WARN1("Type \"%s\" is not defined\n",
2020 XkbAtomText(NULL, key->types[i], XkbMessage));
2021 ACTION2("Using TWO_LEVEL for the %s key (keycode %d)\n",
2022 longText(key->name, XkbMessage), kc);
2024 types[i] = XkbTwoLevelIndex;
2026 /* if the type specifies less syms than the key has, shrink the key */
2027 type = &xkb->map->types[types[i]];
2028 if (type->num_levels < key->numLevels[i])
2030 if (warningLevel > 0)
2033 ("Type \"%s\" has %d levels, but %s has %d symbols\n",
2034 XkbAtomText(NULL, type->name, XkbMessage),
2035 (unsigned int) type->num_levels,
2036 longText(key->name, XkbMessage),
2037 (unsigned int) key->numLevels[i]);
2038 ACTION("Ignoring extra symbols\n");
2040 key->numLevels[i] = type->num_levels;
2042 if (key->numLevels[i] > width)
2043 width = key->numLevels[i];
2044 if (type->num_levels > width)
2045 width = type->num_levels;
2048 /* width is now the largest width found */
2050 i = width * nGroups;
2051 outSyms = XkbResizeKeySyms(xkb, kc, i);
2052 if (outSyms == NULL)
2054 WSGO2("Could not enlarge symbols for %s (keycode %d)\n",
2055 longText(key->name, XkbMessage), kc);
2060 outActs = XkbResizeKeyActions(xkb, kc, i);
2061 if (outActs == NULL)
2063 WSGO2("Could not enlarge actions for %s (key %d)\n",
2064 longText(key->name, XkbMessage), kc);
2067 xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
2071 if (key->defs.defined & _Key_GroupInfo)
2074 i = xkb->map->key_sym_map[kc].group_info;
2076 xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2077 xkb->map->key_sym_map[kc].width = width;
2078 for (i = 0; i < nGroups; i++)
2080 /* assign kt_index[i] to the index of the type in map->types.
2081 * kt_index[i] may have been set by a previous run (if we have two
2082 * layouts specified). Let's not overwrite it with the ONE_LEVEL
2083 * default group if we dont even have keys for this group anyway.
2085 * FIXME: There should be a better fix for this.
2087 if (key->numLevels[i])
2088 xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2089 if (key->syms[i] != NULL)
2091 /* fill key to "width" symbols*/
2092 for (tmp = 0; tmp < width; tmp++)
2094 if (tmp < key->numLevels[i])
2095 outSyms[tmp] = key->syms[i][tmp];
2097 outSyms[tmp] = NoSymbol;
2098 if ((outActs != NULL) && (key->acts[i] != NULL))
2100 if (tmp < key->numLevels[i])
2101 outActs[tmp] = key->acts[i][tmp];
2103 outActs[tmp].type = XkbSA_NoAction;
2111 switch (key->behavior.type & XkbKB_OpMask)
2115 case XkbKB_Overlay1:
2116 case XkbKB_Overlay2:
2117 /* find key by name! */
2118 if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True,
2119 CreateKeyNames(xkb), 0))
2121 if (warningLevel >= 1)
2123 WARN2("Key %s not found in %s keycodes\n",
2124 longText(key->nameForOverlayKey, XkbMessage),
2125 XkbAtomText(NULL, xkb->names->keycodes, XkbMessage));
2126 ACTION1("Not treating %s as an overlay key \n",
2127 longText(key->name, XkbMessage));
2131 key->behavior.data = okc;
2133 xkb->server->behaviors[kc] = key->behavior;
2134 xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2137 if (key->defs.defined & _Key_VModMap)
2139 xkb->server->vmodmap[kc] = key->vmodmap;
2140 xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2142 if (key->repeat != RepeatUndefined)
2144 if (key->repeat == RepeatYes)
2145 xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2147 xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2148 xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2151 /* do the same thing for the next key */
2152 CopySymbolsDef(xkb, key, kc + 1);
2157 CopyModMapDef(XkbcDescPtr xkb, ModMapEntry *entry)
2161 if ((!entry->haveSymbol)
2164 (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
2166 if (warningLevel >= 5)
2168 WARN2("Key %s not found in %s keycodes\n",
2169 longText(entry->u.keyName, XkbMessage),
2170 XkbAtomText(NULL, xkb->names->keycodes, XkbMessage));
2171 ACTION1("Modifier map entry for %s not updated\n",
2172 XkbModIndexText(entry->modifier, XkbMessage));
2176 else if (entry->haveSymbol
2177 && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2179 if (warningLevel > 5)
2181 WARN2("Key \"%s\" not found in %s symbol map\n",
2182 XkbKeysymText(entry->u.keySym, XkbMessage),
2183 XkbAtomText(NULL, xkb->names->symbols, XkbMessage));
2184 ACTION1("Modifier map entry for %s not updated\n",
2185 XkbModIndexText(entry->modifier, XkbMessage));
2189 xkb->map->modmap[kc] |= (1 << entry->modifier);
2194 * Handle the xkb_symbols section of an xkb file.
2196 * @param file The parsed xkb_symbols section of the xkb file.
2197 * @param xkb Handle to the keyboard description to store the symbols in.
2198 * @param merge Merge strategy (e.g. MergeOverride).
2201 CompileSymbols(XkbFile *file, XkbcDescPtr xkb, unsigned merge)
2206 InitSymbolsInfo(&info, xkb);
2207 info.dflt.defs.fileID = file->id;
2208 info.dflt.defs.merge = merge;
2209 HandleSymbolsFile(file, xkb, merge, &info);
2211 if (info.nKeys == 0)
2213 if (info.errorCount == 0)
2217 /* alloc memory in the xkb struct */
2218 if (XkbAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0)
2221 WSGO("Can not allocate names in CompileSymbols\n");
2222 ACTION("Symbols not added\n");
2225 if (XkbAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2228 WSGO("Could not allocate client map in CompileSymbols\n");
2229 ACTION("Symbols not added\n");
2232 if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2234 WSGO("Could not allocate server map in CompileSymbols\n");
2235 ACTION("Symbols not added\n");
2238 if (XkbAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2240 WSGO("Could not allocate controls in CompileSymbols\n");
2241 ACTION("Symbols not added\n");
2245 /* now copy info into xkb. */
2246 xkb->names->symbols = XkbInternAtom(xkb->dpy, info.name, False);
2248 ApplyAliases(xkb, False, &info.aliases);
2249 for (i = 0; i < XkbNumKbdGroups; i++)
2251 if (info.groupNames[i] != None)
2252 xkb->names->groups[i] = info.groupNames[i];
2255 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2260 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2262 if (!CopySymbolsDef(xkb, key, 0))
2265 if (warningLevel > 3)
2267 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2269 if (xkb->names->keys[i].name[0] == '\0')
2271 if (XkbKeyNumGroups(xkb, i) < 1)
2274 memcpy(buf, xkb->names->keys[i].name, 4);
2277 ("No symbols defined for <%s> (keycode %d)\n",
2284 ModMapEntry *mm, *next;
2285 for (mm = info.modMap; mm != NULL; mm = next)
2287 if (!CopyModMapDef(xkb, mm))
2289 next = (ModMapEntry *) mm->defs.next;