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>
41 extern Atom tok_ONE_LEVEL;
42 extern Atom tok_TWO_LEVEL;
43 extern Atom tok_KEYPAD;
45 /***====================================================================***/
49 #define RepeatUndefined ~((unsigned)0)
51 #define _Key_Syms (1<<0)
52 #define _Key_Acts (1<<1)
53 #define _Key_Repeat (1<<2)
54 #define _Key_Behavior (1<<3)
55 #define _Key_Type_Dflt (1<<4)
56 #define _Key_Types (1<<5)
57 #define _Key_GroupInfo (1<<6)
58 #define _Key_VModMap (1<<7)
60 typedef struct _KeyInfo
63 unsigned long name; /* the 4 chars of the key name, as long */
64 unsigned char groupInfo;
65 unsigned char typesDefined;
66 unsigned char symsDefined;
67 unsigned char actsDefined;
68 short numLevels[XkbNumKbdGroups];
69 KeySym *syms[XkbNumKbdGroups];
70 XkbcAction *acts[XkbNumKbdGroups];
71 Atom types[XkbNumKbdGroups];
74 unsigned short vmodmap;
75 unsigned long nameForOverlayKey;
76 unsigned long allowNone;
81 * Init the given key info to sane values.
84 InitKeyInfo(KeyInfo * info)
87 static char dflt[4] = "*";
89 info->defs.defined = 0;
90 info->defs.fileID = 0;
91 info->defs.merge = MergeOverride;
92 info->defs.next = NULL;
93 info->name = KeyNameToLong(dflt);
95 info->typesDefined = info->symsDefined = info->actsDefined = 0;
96 for (i = 0; i < XkbNumKbdGroups; i++)
98 info->numLevels[i] = 0;
99 info->types[i] = None;
100 info->syms[i] = NULL;
101 info->acts[i] = NULL;
103 info->dfltType = None;
104 info->behavior.type = XkbKB_Default;
105 info->behavior.data = 0;
107 info->nameForOverlayKey = 0;
108 info->repeat = RepeatUndefined;
114 * Free memory associated with this key info and reset to sane values.
117 FreeKeyInfo(KeyInfo * info)
121 info->defs.defined = 0;
122 info->defs.fileID = 0;
123 info->defs.merge = MergeOverride;
124 info->defs.next = NULL;
126 info->typesDefined = info->symsDefined = info->actsDefined = 0;
127 for (i = 0; i < XkbNumKbdGroups; i++)
129 info->numLevels[i] = 0;
130 info->types[i] = None;
131 if (info->syms[i] != NULL)
132 uFree(info->syms[i]);
133 info->syms[i] = NULL;
134 if (info->acts[i] != NULL)
135 uFree(info->acts[i]);
136 info->acts[i] = NULL;
138 info->dfltType = None;
139 info->behavior.type = XkbKB_Default;
140 info->behavior.data = 0;
142 info->nameForOverlayKey = 0;
143 info->repeat = RepeatUndefined;
149 * Copy old into new, optionally reset old to 0.
150 * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
151 * newly allocated and new points to the new memory areas.
154 CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld)
159 new->defs.next = NULL;
162 for (i = 0; i < XkbNumKbdGroups; i++)
164 old->numLevels[i] = 0;
172 for (i = 0; i < XkbNumKbdGroups; i++)
174 width = new->numLevels[i];
175 if (old->syms[i] != NULL)
177 new->syms[i] = uTypedCalloc(width, KeySym);
181 new->numLevels[i] = 0;
184 memcpy((char *) new->syms[i], (char *) old->syms[i],
185 width * sizeof(KeySym));
187 if (old->acts[i] != NULL)
189 new->acts[i] = uTypedCalloc(width, XkbcAction);
195 memcpy((char *) new->acts[i], (char *) old->acts[i],
196 width * sizeof(XkbcAction));
203 /***====================================================================***/
205 typedef struct _ModMapEntry
212 unsigned long keyName;
217 #define SYMBOLS_INIT_SIZE 110
218 #define SYMBOLS_CHUNK 20
219 typedef struct _SymbolsInfo
221 char *name; /* e.g. pc+us+inet(evdev) */
225 unsigned explicit_group;
233 Atom groupNames[XkbNumKbdGroups];
240 InitSymbolsInfo(SymbolsInfo * info, XkbcDescPtr xkb)
244 tok_ONE_LEVEL = XkbcInternAtom("ONE_LEVEL", False);
245 tok_TWO_LEVEL = XkbcInternAtom("TWO_LEVEL", False);
246 tok_KEYPAD = XkbcInternAtom("KEYPAD", False);
248 info->explicit_group = 0;
249 info->errorCount = 0;
251 info->merge = MergeOverride;
253 info->szKeys = SYMBOLS_INIT_SIZE;
255 info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo);
257 for (i = 0; i < XkbNumKbdGroups; i++)
258 info->groupNames[i] = None;
259 InitKeyInfo(&info->dflt);
260 InitVModInfo(&info->vmods, xkb);
262 info->aliases = NULL;
267 FreeSymbolsInfo(SymbolsInfo * info)
276 for (i = 0; i < info->nKeys; i++)
278 FreeKeyInfo(&info->keys[i]);
285 ClearCommonInfo(&info->modMap->defs);
290 ClearAliases(&info->aliases);
291 info->aliases = NULL;
293 bzero((char *) info, sizeof(SymbolsInfo));
298 ResizeKeyGroup(KeyInfo * key,
299 unsigned group, unsigned atLeastSize, Bool forceActions)
304 tooSmall = (key->numLevels[group] < atLeastSize);
306 newWidth = atLeastSize;
308 newWidth = key->numLevels[group];
310 if ((key->syms[group] == NULL) || tooSmall)
312 key->syms[group] = uTypedRecalloc(key->syms[group],
313 key->numLevels[group], newWidth,
315 if (!key->syms[group])
318 if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) ||
319 (tooSmall && (key->acts[group] != NULL)))
321 key->acts[group] = uTypedRecalloc(key->acts[group],
322 key->numLevels[group], newWidth,
324 if (!key->acts[group])
327 key->numLevels[group] = newWidth;
332 MergeKeyGroups(SymbolsInfo * info,
333 KeyInfo * into, KeyInfo * from, unsigned group)
336 XkbcAction *resultActs;
339 Bool report, clobber;
341 clobber = (from->defs.merge != MergeAugment);
342 report = (warningLevel > 9) ||
343 ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
344 if (into->numLevels[group] >= from->numLevels[group])
346 resultSyms = into->syms[group];
347 resultActs = into->acts[group];
348 resultWidth = into->numLevels[group];
352 resultSyms = from->syms[group];
353 resultActs = from->acts[group];
354 resultWidth = from->numLevels[group];
356 if (resultSyms == NULL)
358 resultSyms = uTypedCalloc(resultWidth, KeySym);
361 WSGO("Could not allocate symbols for group merge\n");
362 ACTION("Group %d of key %s not merged\n", group,
363 longText(into->name));
367 if ((resultActs == NULL) && (into->acts[group] || from->acts[group]))
369 resultActs = uTypedCalloc(resultWidth, XkbcAction);
372 WSGO("Could not allocate actions for group merge\n");
373 ACTION("Group %d of key %s not merged\n", group,
374 longText(into->name));
378 for (i = 0; i < resultWidth; i++)
380 KeySym fromSym, toSym;
381 if (from->syms[group] && (i < from->numLevels[group]))
382 fromSym = from->syms[group][i];
385 if (into->syms[group] && (i < into->numLevels[group]))
386 toSym = into->syms[group][i];
389 if ((fromSym == NoSymbol) || (fromSym == toSym))
390 resultSyms[i] = toSym;
391 else if (toSym == NoSymbol)
392 resultSyms[i] = fromSym;
409 ("Multiple symbols for level %d/group %d on key %s\n",
410 i + 1, group + 1, longText(into->name));
411 ACTION("Using %s, ignoring %s\n",
412 XkbcKeysymText(use), XkbcKeysymText(ignore));
416 if (resultActs != NULL)
418 XkbcAction *fromAct, *toAct;
419 fromAct = (from->acts[group] ? &from->acts[group][i] : NULL);
420 toAct = (into->acts[group] ? &into->acts[group][i] : NULL);
421 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
424 resultActs[i] = *toAct;
426 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
427 && (fromAct != NULL))
429 resultActs[i] = *fromAct;
433 XkbcAction *use, *ignore;
447 ("Multiple actions for level %d/group %d on key %s\n",
448 i + 1, group + 1, longText(into->name));
449 ACTION("Using %s, ignoring %s\n",
450 XkbcActionTypeText(use->type),
451 XkbcActionTypeText(ignore->type));
453 resultActs[i] = *use;
457 if ((into->syms[group] != NULL) && (resultSyms != into->syms[group]))
458 uFree(into->syms[group]);
459 if ((from->syms[group] != NULL) && (resultSyms != from->syms[group]))
460 uFree(from->syms[group]);
461 if ((into->acts[group] != NULL) && (resultActs != into->acts[group]))
462 uFree(into->acts[group]);
463 if ((from->acts[group] != NULL) && (resultActs != from->acts[group]))
464 uFree(from->acts[group]);
465 into->numLevels[group] = resultWidth;
466 into->syms[group] = resultSyms;
467 from->syms[group] = NULL;
468 into->acts[group] = resultActs;
469 from->acts[group] = NULL;
470 into->symsDefined |= (1 << group);
471 from->symsDefined &= ~(1 << group);
472 into->actsDefined |= (1 << group);
473 from->actsDefined &= ~(1 << group);
478 MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from)
481 unsigned collide = 0;
484 if (from->defs.merge == MergeReplace)
486 for (i = 0; i < XkbNumKbdGroups; i++)
488 if (into->numLevels[i] != 0)
491 uFree(into->syms[i]);
493 uFree(into->acts[i]);
497 bzero(from, sizeof(KeyInfo));
500 report = ((warningLevel > 9) ||
501 ((into->defs.fileID == from->defs.fileID)
502 && (warningLevel > 0)));
503 for (i = 0; i < XkbNumKbdGroups; i++)
505 if (from->numLevels[i] > 0)
507 if (into->numLevels[i] == 0)
509 into->numLevels[i] = from->numLevels[i];
510 into->syms[i] = from->syms[i];
511 into->acts[i] = from->acts[i];
512 into->symsDefined |= (1 << i);
513 from->syms[i] = NULL;
514 from->acts[i] = NULL;
515 from->numLevels[i] = 0;
516 from->symsDefined &= ~(1 << i);
518 into->defs.defined |= _Key_Syms;
520 into->defs.defined |= _Key_Acts;
527 collide |= _Key_Syms;
529 collide |= _Key_Acts;
531 MergeKeyGroups(info, into, from, (unsigned) i);
534 if (from->types[i] != None)
536 if ((into->types[i] != None) && (report) &&
537 (into->types[i] != from->types[i]))
540 collide |= _Key_Types;
541 if (from->defs.merge != MergeAugment)
543 use = from->types[i];
544 ignore = into->types[i];
548 use = into->types[i];
549 ignore = from->types[i];
552 ("Multiple definitions for group %d type of key %s\n",
553 i, longText(into->name));
554 ACTION("Using %s, ignoring %s\n",
556 XkbcAtomText(ignore));
558 if ((from->defs.merge != MergeAugment)
559 || (into->types[i] == None))
561 into->types[i] = from->types[i];
565 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
567 into->behavior = from->behavior;
568 into->nameForOverlayKey = from->nameForOverlayKey;
569 into->defs.defined |= _Key_Behavior;
571 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
573 into->vmodmap = from->vmodmap;
574 into->defs.defined |= _Key_VModMap;
576 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
578 into->repeat = from->repeat;
579 into->defs.defined |= _Key_Repeat;
581 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
583 into->dfltType = from->dfltType;
584 into->defs.defined |= _Key_Type_Dflt;
586 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
588 into->groupInfo = from->groupInfo;
589 into->defs.defined |= _Key_GroupInfo;
593 WARN("Symbol map for key %s redefined\n",
594 longText(into->name));
595 ACTION("Using %s definition for conflicting fields\n",
596 (from->defs.merge == MergeAugment ? "first" : "last"));
602 AddKeySymbols(SymbolsInfo * info, KeyInfo * key, XkbcDescPtr xkb)
605 unsigned long real_name;
607 for (i = 0; i < info->nKeys; i++)
609 if (info->keys[i].name == key->name)
610 return MergeKeys(info, &info->keys[i], key);
612 if (FindKeyNameForAlias(xkb, key->name, &real_name))
614 for (i = 0; i < info->nKeys; i++)
616 if (info->keys[i].name == real_name)
617 return MergeKeys(info, &info->keys[i], key);
620 if (info->nKeys >= info->szKeys)
622 info->szKeys += SYMBOLS_CHUNK;
624 uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo);
627 WSGO("Could not allocate key symbols descriptions\n");
628 ACTION("Some key symbols definitions may be lost\n");
632 return CopyKeyInfo(key, &info->keys[info->nKeys++], True);
636 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
641 clobber = (new->defs.merge != MergeAugment);
642 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
644 if (new->haveSymbol && mm->haveSymbol
645 && (new->u.keySym == mm->u.keySym))
647 unsigned use, ignore;
648 if (mm->modifier != new->modifier)
653 ignore = mm->modifier;
658 ignore = new->modifier;
661 ("%s added to symbol map for multiple modifiers\n",
662 XkbcKeysymText(new->u.keySym));
663 ACTION("Using %s, ignoring %s.\n",
664 XkbcModIndexText(use),
665 XkbcModIndexText(ignore));
670 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
671 (new->u.keyName == mm->u.keyName))
673 unsigned use, ignore;
674 if (mm->modifier != new->modifier)
679 ignore = mm->modifier;
684 ignore = new->modifier;
686 ERROR("Key %s added to map for multiple modifiers\n",
687 longText(new->u.keyName));
688 ACTION("Using %s, ignoring %s.\n",
689 XkbcModIndexText(use),
690 XkbcModIndexText(ignore));
696 mm = uTypedAlloc(ModMapEntry);
699 WSGO("Could not allocate modifier map entry\n");
700 ACTION("Modifier map for %s will be incomplete\n",
701 XkbcModIndexText(new->modifier));
705 mm->defs.next = &info->modMap->defs;
710 /***====================================================================***/
713 MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from,
714 unsigned merge, XkbcDescPtr xkb)
719 if (from->errorCount > 0)
721 into->errorCount += from->errorCount;
724 if (into->name == NULL)
726 into->name = from->name;
729 for (i = 0; i < XkbNumKbdGroups; i++)
731 if (from->groupNames[i] != None)
733 if ((merge != MergeAugment) || (into->groupNames[i] == None))
734 into->groupNames[i] = from->groupNames[i];
737 for (i = 0, key = from->keys; i < from->nKeys; i++, key++)
739 if (merge != MergeDefault)
740 key->defs.merge = merge;
741 if (!AddKeySymbols(into, key, xkb))
744 if (from->modMap != NULL)
746 ModMapEntry *mm, *next;
747 for (mm = from->modMap; mm != NULL; mm = next)
749 if (merge != MergeDefault)
750 mm->defs.merge = merge;
751 if (!AddModMapEntry(into, mm))
753 next = (ModMapEntry *) mm->defs.next;
758 if (!MergeAliases(&into->aliases, &from->aliases, merge))
763 typedef void (*FileHandler) (XkbFile * /* rtrn */ ,
764 XkbcDescPtr /* xkb */ ,
765 unsigned /* merge */ ,
766 SymbolsInfo * /* included */
770 HandleIncludeSymbols(IncludeStmt * stmt,
771 XkbcDescPtr xkb, SymbolsInfo * info, FileHandler hndlr)
775 SymbolsInfo included;
779 if ((stmt->file == NULL) && (stmt->map == NULL))
783 bzero(info, sizeof(SymbolsInfo));
785 else if (ProcessIncludeFile(stmt, XkmSymbolsIndex, &rtrn, &newMerge))
787 InitSymbolsInfo(&included, xkb);
788 included.fileID = included.dflt.defs.fileID = rtrn->id;
789 included.merge = included.dflt.defs.merge = MergeOverride;
792 included.explicit_group = atoi(stmt->modifier) - 1;
796 included.explicit_group = info->explicit_group;
798 (*hndlr) (rtrn, xkb, MergeOverride, &included);
799 if (stmt->stmt != NULL)
801 if (included.name != NULL)
802 uFree(included.name);
803 included.name = stmt->stmt;
809 info->errorCount += 10;
812 if ((stmt->next != NULL) && (included.errorCount < 1))
816 SymbolsInfo next_incl;
818 for (next = stmt->next; next != NULL; next = next->next)
820 if ((next->file == NULL) && (next->map == NULL))
823 MergeIncludedSymbols(&included, info, next->merge, xkb);
824 FreeSymbolsInfo(info);
826 else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op))
828 InitSymbolsInfo(&next_incl, xkb);
829 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
830 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride;
833 next_incl.explicit_group = atoi(next->modifier) - 1;
837 next_incl.explicit_group = info->explicit_group;
839 (*hndlr) (rtrn, xkb, MergeOverride, &next_incl);
840 MergeIncludedSymbols(&included, &next_incl, op, xkb);
841 FreeSymbolsInfo(&next_incl);
845 info->errorCount += 10;
854 MergeIncludedSymbols(info, &included, newMerge, xkb);
855 FreeSymbolsInfo(&included);
857 return (info->errorCount == 0);
860 static LookupEntry groupNames[] = {
877 GetGroupIndex(KeyInfo * key,
878 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
888 if (arrayNdx == NULL)
893 defined = key->symsDefined;
895 defined = key->actsDefined;
897 for (i = 0; i < XkbNumKbdGroups; i++)
899 if ((defined & (1 << i)) == 0)
905 ERROR("Too many groups of %s for key %s (max %d)\n", name,
906 longText(key->name), XkbNumKbdGroups + 1);
907 ACTION("Ignoring %s defined for extra groups\n", name);
910 if (!ExprResolveInteger
911 (arrayNdx, &tmp, SimpleLookup, (char *) groupNames))
913 ERROR("Illegal group index for %s of key %s\n", name,
914 longText(key->name));
915 ACTION("Definition with non-integer array index ignored\n");
918 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
920 ERROR("Group index for %s of key %s is out of range (1..%d)\n",
921 name, longText(key->name), XkbNumKbdGroups + 1);
922 ACTION("Ignoring %s for group %d\n", name, tmp.uval);
925 *ndx_rtrn = tmp.uval - 1;
930 AddSymbolsToKey(KeyInfo * key,
933 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
938 if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx))
942 key->symsDefined |= (1 << ndx);
945 if (value->op != ExprKeysymList)
947 ERROR("Expected a list of symbols, found %s\n",
948 exprOpText(value->op));
949 ACTION("Ignoring symbols for group %d of %s\n", ndx,
950 longText(key->name));
953 if (key->syms[ndx] != NULL)
955 WSGO("Symbols for key %s, group %d already defined\n",
956 longText(key->name), ndx);
959 nSyms = value->value.list.nSyms;
960 if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
961 (!ResizeKeyGroup(key, ndx, nSyms, False)))
963 WSGO("Could not resize group %d of key %s\n", ndx,
964 longText(key->name));
965 ACTION("Symbols lost\n");
968 key->symsDefined |= (1 << ndx);
969 memcpy((char *) key->syms[ndx], (char *) value->value.list.syms,
970 nSyms * sizeof(KeySym));
971 for (i = key->numLevels[ndx] - 1;
972 (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--)
974 key->numLevels[ndx]--;
980 AddActionsToKey(KeyInfo * key,
983 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
990 if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx))
995 key->actsDefined |= (1 << ndx);
998 if (value->op != ExprActionList)
1000 WSGO("Bad expression type (%d) for action list value\n", value->op);
1001 ACTION("Ignoring actions for group %d of %s\n", ndx,
1002 longText(key->name));
1005 if (key->acts[ndx] != NULL)
1007 WSGO("Actions for key %s, group %d already defined\n",
1008 longText(key->name), ndx);
1011 for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1013 act = (ExprDef *) act->common.next;
1017 WSGO("Action list but not actions in AddActionsToKey\n");
1020 if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1021 (!ResizeKeyGroup(key, ndx, nActs, True)))
1023 WSGO("Could not resize group %d of key %s\n", ndx,
1024 longText(key->name));
1025 ACTION("Actions lost\n");
1028 key->actsDefined |= (1 << ndx);
1030 toAct = (XkbAnyAction *) key->acts[ndx];
1031 act = value->value.child;
1032 for (i = 0; i < nActs; i++, toAct++)
1034 if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action))
1036 ERROR("Illegal action definition for %s\n",
1037 longText(key->name));
1038 ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1040 act = (ExprDef *) act->common.next;
1046 SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value)
1049 unsigned radio_groups = 0;
1051 if (arrayNdx == NULL)
1053 radio_groups = XkbAllRadioGroupsMask;
1057 if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL))
1059 ERROR("Illegal index in group name definition\n");
1060 ACTION("Definition with non-integer array index ignored\n");
1063 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1065 ERROR("Illegal radio group specified (must be 1..%d)\n",
1066 XkbMaxRadioGroups + 1);
1067 ACTION("Value of \"allow none\" for group %d ignored\n",
1071 radio_groups |= (1 << (tmp.uval - 1));
1073 if (!ExprResolveBoolean(value, &tmp, NULL, NULL))
1075 ERROR("Illegal \"allow none\" value for %s\n",
1076 longText(key->name));
1077 ACTION("Non-boolean value ignored\n");
1081 key->allowNone |= radio_groups;
1083 key->allowNone &= ~radio_groups;
1088 static LookupEntry lockingEntries[] = {
1089 {"true", XkbKB_Lock},
1090 {"yes", XkbKB_Lock},
1092 {"false", XkbKB_Default},
1093 {"no", XkbKB_Default},
1094 {"off", XkbKB_Default},
1095 {"permanent", XkbKB_Lock | XkbKB_Permanent},
1099 static LookupEntry repeatEntries[] = {
1100 {"true", RepeatYes},
1103 {"false", RepeatNo},
1106 {"default", RepeatUndefined},
1110 static LookupEntry rgEntries[] = {
1116 SetSymbolsField(KeyInfo * key,
1119 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1124 if (uStrCaseCmp(field, "type") == 0)
1127 if ((!ExprResolveString(value, &tmp, NULL, NULL))
1128 && (warningLevel > 0))
1130 WARN("The type field of a key symbol map must be a string\n");
1131 ACTION("Ignoring illegal type definition\n");
1133 if (arrayNdx == NULL)
1135 key->dfltType = XkbcInternAtom(tmp.str, False);
1136 key->defs.defined |= _Key_Type_Dflt;
1138 else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup,
1139 (char *) groupNames))
1141 ERROR("Illegal group index for type of key %s\n",
1142 longText(key->name));
1143 ACTION("Definition with non-integer array index ignored\n");
1146 else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups))
1149 ("Group index for type of key %s is out of range (1..%d)\n",
1150 longText(key->name), XkbNumKbdGroups + 1);
1151 ACTION("Ignoring type for group %d\n", ndx.uval);
1156 key->types[ndx.uval - 1] = XkbcInternAtom(tmp.str, False);
1157 key->typesDefined |= (1 << (ndx.uval - 1));
1160 else if (uStrCaseCmp(field, "symbols") == 0)
1161 return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1162 else if (uStrCaseCmp(field, "actions") == 0)
1163 return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1164 else if ((uStrCaseCmp(field, "vmods") == 0) ||
1165 (uStrCaseCmp(field, "virtualmods") == 0) ||
1166 (uStrCaseCmp(field, "virtualmodifiers") == 0))
1168 ok = ExprResolveModMask(value, &tmp, LookupVModMask, (char *) xkb);
1171 key->vmodmap = (tmp.uval >> 8);
1172 key->defs.defined |= _Key_VModMap;
1176 ERROR("Expected a virtual modifier mask, found %s\n",
1177 exprOpText(value->op));
1178 ACTION("Ignoring virtual modifiers definition for key %s\n",
1179 longText(key->name));
1182 else if ((uStrCaseCmp(field, "locking") == 0)
1183 || (uStrCaseCmp(field, "lock") == 0)
1184 || (uStrCaseCmp(field, "locks") == 0))
1186 ok = ExprResolveEnum(value, &tmp, lockingEntries);
1188 key->behavior.type = tmp.uval;
1189 key->defs.defined |= _Key_Behavior;
1191 else if ((uStrCaseCmp(field, "radiogroup") == 0) ||
1192 (uStrCaseCmp(field, "permanentradiogroup") == 0))
1194 Bool permanent = False;
1195 if (uStrCaseCmp(field, "permanentradiogroup") == 0)
1197 ok = ExprResolveInteger(value, &tmp, SimpleLookup,
1198 (char *) rgEntries);
1201 ERROR("Illegal radio group specification for %s\n",
1202 longText(key->name));
1203 ACTION("Non-integer radio group ignored\n");
1208 key->behavior.type = XkbKB_Default;
1209 key->behavior.data = 0;
1212 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1215 ("Radio group specification for %s out of range (1..32)\n",
1216 longText(key->name));
1217 ACTION("Illegal radio group %d ignored\n", tmp.uval);
1220 key->behavior.type =
1221 XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0);
1222 key->behavior.data = tmp.uval - 1;
1223 if (key->allowNone & (1 << (tmp.uval - 1)))
1224 key->behavior.data |= XkbKB_RGAllowNone;
1225 key->defs.defined |= _Key_Behavior;
1227 else if (uStrCaseEqual(field, "allownone"))
1229 ok = SetAllowNone(key, arrayNdx, value);
1231 else if (uStrCasePrefix("overlay", field) ||
1232 uStrCasePrefix("permanentoverlay", field))
1234 Bool permanent = False;
1237 if (uStrCasePrefix("permanent", field))
1240 which = &field[sizeof("permanentoverlay") - 1];
1244 which = &field[sizeof("overlay") - 1];
1246 if (sscanf(which, "%d", &overlayNdx) == 1)
1248 if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0))
1250 ERROR("Illegal overlay %d specified for %s\n",
1251 overlayNdx, longText(key->name));
1252 ACTION("Ignored\n");
1256 else if (*which == '\0')
1258 else if (warningLevel > 0)
1260 ERROR("Illegal overlay \"%s\" specified for %s\n",
1261 which, longText(key->name));
1262 ACTION("Ignored\n");
1265 ok = ExprResolveKeyName(value, &tmp, NULL, NULL);
1268 ERROR("Illegal overlay key specification for %s\n",
1269 longText(key->name));
1270 ACTION("Overlay key must be specified by name\n");
1273 if (overlayNdx == 1)
1274 key->behavior.type = XkbKB_Overlay1;
1276 key->behavior.type = XkbKB_Overlay2;
1278 key->behavior.type |= XkbKB_Permanent;
1280 key->behavior.data = 0;
1281 key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name);
1282 key->defs.defined |= _Key_Behavior;
1284 else if ((uStrCaseCmp(field, "repeating") == 0) ||
1285 (uStrCaseCmp(field, "repeats") == 0) ||
1286 (uStrCaseCmp(field, "repeat") == 0))
1288 ok = ExprResolveEnum(value, &tmp, repeatEntries);
1291 ERROR("Illegal repeat setting for %s\n",
1292 longText(key->name));
1293 ACTION("Non-boolean repeat setting ignored\n");
1296 key->repeat = tmp.uval;
1297 key->defs.defined |= _Key_Repeat;
1299 else if ((uStrCaseCmp(field, "groupswrap") == 0) ||
1300 (uStrCaseCmp(field, "wrapgroups") == 0))
1302 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1305 ERROR("Illegal groupsWrap setting for %s\n",
1306 longText(key->name));
1307 ACTION("Non-boolean value ignored\n");
1311 key->groupInfo = XkbWrapIntoRange;
1313 key->groupInfo = XkbClampIntoRange;
1314 key->defs.defined |= _Key_GroupInfo;
1316 else if ((uStrCaseCmp(field, "groupsclamp") == 0) ||
1317 (uStrCaseCmp(field, "clampgroups") == 0))
1319 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1322 ERROR("Illegal groupsClamp setting for %s\n",
1323 longText(key->name));
1324 ACTION("Non-boolean value ignored\n");
1328 key->groupInfo = XkbClampIntoRange;
1330 key->groupInfo = XkbWrapIntoRange;
1331 key->defs.defined |= _Key_GroupInfo;
1333 else if ((uStrCaseCmp(field, "groupsredirect") == 0) ||
1334 (uStrCaseCmp(field, "redirectgroups") == 0))
1336 if (!ExprResolveInteger
1337 (value, &tmp, SimpleLookup, (char *) groupNames))
1339 ERROR("Illegal group index for redirect of key %s\n",
1340 longText(key->name));
1341 ACTION("Definition with non-integer group ignored\n");
1344 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1346 ERROR("Out-of-range (1..%d) group for redirect of key %s\n",
1347 XkbNumKbdGroups, longText(key->name));
1348 ERROR("Ignoring illegal group %d\n", tmp.uval);
1352 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1353 key->defs.defined |= _Key_GroupInfo;
1357 ERROR("Unknown field %s in a symbol interpretation\n", field);
1358 ACTION("Definition ignored\n");
1365 SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1367 ExprResult tmp, name;
1369 if ((arrayNdx == NULL) && (warningLevel > 0))
1371 WARN("You must specify an index when specifying a group name\n");
1372 ACTION("Group name definition without array subscript ignored\n");
1375 if (!ExprResolveInteger
1376 (arrayNdx, &tmp, SimpleLookup, (char *) groupNames))
1378 ERROR("Illegal index in group name definition\n");
1379 ACTION("Definition with non-integer array index ignored\n");
1382 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1385 ("Attempt to specify name for illegal group (must be 1..%d)\n",
1386 XkbNumKbdGroups + 1);
1387 ACTION("Name for group %d ignored\n", tmp.uval);
1390 if (!ExprResolveString(value, &name, NULL, NULL))
1392 ERROR("Group name must be a string\n");
1393 ACTION("Illegal name for group %d ignored\n", tmp.uval);
1396 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1397 XkbcInternAtom(name.str, False);
1403 HandleSymbolsVar(VarDef * stmt, XkbcDescPtr xkb, SymbolsInfo * info)
1405 ExprResult elem, field, tmp;
1408 if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1409 return 0; /* internal error, already reported */
1410 if (elem.str && (uStrCaseCmp(elem.str, "key") == 0))
1412 return SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1415 else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) ||
1416 (uStrCaseCmp(field.str, "groupname") ==
1419 return SetGroupName(info, arrayNdx, stmt->value);
1421 else if ((elem.str == NULL)
1422 && ((uStrCaseCmp(field.str, "groupswrap") == 0)
1423 || (uStrCaseCmp(field.str, "wrapgroups") == 0)))
1425 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1427 ERROR("Illegal setting for global groupsWrap\n");
1428 ACTION("Non-boolean value ignored\n");
1432 info->groupInfo = XkbWrapIntoRange;
1434 info->groupInfo = XkbClampIntoRange;
1437 else if ((elem.str == NULL)
1438 && ((uStrCaseCmp(field.str, "groupsclamp") == 0)
1439 || (uStrCaseCmp(field.str, "clampgroups") == 0)))
1441 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1443 ERROR("Illegal setting for global groupsClamp\n");
1444 ACTION("Non-boolean value ignored\n");
1448 info->groupInfo = XkbClampIntoRange;
1450 info->groupInfo = XkbWrapIntoRange;
1453 else if ((elem.str == NULL)
1454 && ((uStrCaseCmp(field.str, "groupsredirect") == 0)
1455 || (uStrCaseCmp(field.str, "redirectgroups") == 0)))
1457 if (!ExprResolveInteger(stmt->value, &tmp,
1458 SimpleLookup, (char *) groupNames))
1460 ERROR("Illegal group index for global groupsRedirect\n");
1461 ACTION("Definition with non-integer group ignored\n");
1464 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1467 ("Out-of-range (1..%d) group for global groupsRedirect\n",
1469 ACTION("Ignoring illegal group %d\n", tmp.uval);
1472 info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval);
1475 else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0))
1477 return SetAllowNone(&info->dflt, arrayNdx, stmt->value);
1479 return SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1484 HandleSymbolsBody(VarDef * def,
1485 XkbcDescPtr xkb, KeyInfo * key, SymbolsInfo * info)
1488 ExprResult tmp, field;
1491 for (; def != NULL; def = (VarDef *) def->common.next)
1493 if ((def->name) && (def->name->type == ExprFieldRef))
1495 ok = HandleSymbolsVar(def, xkb, info);
1500 if (def->name == NULL)
1502 if ((def->value == NULL)
1503 || (def->value->op == ExprKeysymList))
1504 field.str = "symbols";
1506 field.str = "actions";
1511 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1514 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1522 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1524 unsigned group = info->explicit_group;
1529 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1532 WARN("For the map %s an explicit group specified\n", info->name);
1533 WARN("but key %s has more than one group defined\n",
1534 longText(key->name));
1535 ACTION("All groups except first one will be ignored\n");
1536 for (i = 1; i < XkbNumKbdGroups; i++)
1538 key->numLevels[i] = 0;
1539 if (key->syms[i] != NULL)
1540 uFree(key->syms[i]);
1541 key->syms[i] = (KeySym *) NULL;
1542 if (key->acts[i] != NULL)
1543 uFree(key->acts[i]);
1544 key->acts[i] = (XkbcAction *) NULL;
1545 key->types[i] = (Atom) 0;
1548 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1550 key->numLevels[group] = key->numLevels[0];
1551 key->numLevels[0] = 0;
1552 key->syms[group] = key->syms[0];
1553 key->syms[0] = (KeySym *) NULL;
1554 key->acts[group] = key->acts[0];
1555 key->acts[0] = (XkbcAction *) NULL;
1556 key->types[group] = key->types[0];
1557 key->types[0] = (Atom) 0;
1562 HandleSymbolsDef(SymbolsDef * stmt,
1563 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1568 CopyKeyInfo(&info->dflt, &key, False);
1569 key.defs.merge = stmt->merge;
1570 key.name = KeyNameToLong(stmt->keyName);
1571 if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1577 if (!SetExplicitGroup(info, &key))
1583 if (!AddKeySymbols(info, &key, xkb))
1592 HandleModMapDef(ModMapDef * def,
1593 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1600 if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn))
1602 ERROR("Illegal modifier map definition\n");
1603 ACTION("Ignoring map for non-modifier \"%s\"\n",
1604 XkbcAtomText(def->modifier));
1608 tmp.modifier = rtrn.uval;
1609 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1611 if ((key->op == ExprValue) && (key->type == TypeKeyName))
1613 tmp.haveSymbol = False;
1614 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1616 else if (ExprResolveKeySym(key, &rtrn, NULL, NULL))
1618 tmp.haveSymbol = True;
1619 tmp.u.keySym = rtrn.uval;
1623 ERROR("Modmap entries may contain only key names or keysyms\n");
1624 ACTION("Illegal definition for %s modifier ignored\n",
1625 XkbcModIndexText(tmp.modifier));
1629 ok = AddModMapEntry(info, &tmp) && ok;
1635 HandleSymbolsFile(XkbFile * file,
1636 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1640 info->name = uStringDup(file->name);
1644 switch (stmt->stmtType)
1647 if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1651 case StmtSymbolsDef:
1652 if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1656 if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1660 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1664 ERROR("Interpretation files may not include other types\n");
1665 ACTION("Ignoring definition of symbol interpretation\n");
1668 case StmtKeycodeDef:
1669 ERROR("Interpretation files may not include other types\n");
1670 ACTION("Ignoring definition of key name\n");
1674 if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1678 WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1683 if (info->errorCount > 10)
1686 ERROR("Too many errors\n");
1688 ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1696 FindKeyForSymbol(XkbcDescPtr xkb, KeySym sym, unsigned int *kc_rtrn)
1699 register Bool gotOne;
1705 for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1707 if (j < (int) XkbKeyNumSyms(xkb, i))
1710 if ((XkbKeySym(xkb, i, j) == sym))
1724 * Find the given name in the xkb->map->types and return its index.
1726 * @param name The atom to search for.
1727 * @param type_rtrn Set to the index of the name if found.
1729 * @return True if found, False otherwise.
1732 FindNamedType(XkbcDescPtr xkb, Atom name, unsigned *type_rtrn)
1734 register unsigned n;
1736 if (xkb && xkb->map && xkb->map->types)
1738 for (n = 0; n < xkb->map->num_types; n++)
1740 if (xkb->map->types[n].name == (Atom) name)
1751 * Assign a type to the given sym and return the Atom for the type assigned.
1754 * - ONE_LEVEL for width 0/1
1755 * - ALPHABETIC for 2 shift levels, with lower/upercase
1756 * - KEYPAD for keypad keys.
1757 * - TWO_LEVEL for other 2 shift level keys.
1758 * and the same for four level keys.
1760 * @param width Number of sysms in syms.
1761 * @param syms The keysyms for the given key (must be size width).
1762 * @param typeNameRtrn Set to the Atom of the type name.
1764 * @returns True if a type could be found, False otherwise.
1767 FindAutomaticType(int width, KeySym * syms, Atom * typeNameRtrn,
1771 if ((width == 1) || (width == 0))
1773 *typeNameRtrn = XkbcInternAtom("ONE_LEVEL", False);
1776 else if (width == 2)
1778 if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1780 *typeNameRtrn = XkbcInternAtom("ALPHABETIC", False);
1782 else if (syms && (XkbcKSIsKeypad(syms[0]) || XkbcKSIsKeypad(syms[1])))
1784 *typeNameRtrn = XkbcInternAtom("KEYPAD", False);
1789 *typeNameRtrn = XkbcInternAtom("TWO_LEVEL", False);
1793 else if (width <= 4)
1795 if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1796 if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1798 XkbcInternAtom("FOUR_LEVEL_ALPHABETIC", False);
1800 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL_SEMIALPHABETIC",
1803 else if (syms && (XkbcKSIsKeypad(syms[0]) || XkbcKSIsKeypad(syms[1])))
1804 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL_KEYPAD", False);
1806 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL", False);
1807 /* XXX: why not set autoType here? */
1809 return ((width >= 0) && (width <= 4));
1813 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1814 * groups, and reduce to one group if all groups are identical anyway.
1817 PrepareKeyDef(KeyInfo * key)
1819 int i, j, width, defined, lastGroup;
1822 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1823 /* get highest group number */
1824 for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1826 if (defined & (1 << i))
1834 /* If there are empty groups between non-empty ones fill them with data */
1835 /* from the first group. */
1836 /* We can make a wrong assumption here. But leaving gaps is worse. */
1837 for (i = lastGroup; i > 0; i--)
1839 if (defined & (1 << i))
1841 width = key->numLevels[0];
1842 if (key->typesDefined & 1)
1844 for (j = 0; j < width; j++)
1846 key->types[i] = key->types[0];
1848 key->typesDefined |= 1 << i;
1850 if ((key->actsDefined & 1) && key->acts[0])
1852 key->acts[i] = uTypedCalloc(width, XkbcAction);
1853 if (key->acts[i] == NULL)
1855 memcpy((void *) key->acts[i], (void *) key->acts[0],
1856 width * sizeof(XkbcAction));
1857 key->actsDefined |= 1 << i;
1859 if ((key->symsDefined & 1) && key->syms[0])
1861 key->syms[i] = uTypedCalloc(width, KeySym);
1862 if (key->syms[i] == NULL)
1864 memcpy((void *) key->syms[i], (void *) key->syms[0],
1865 width * sizeof(KeySym));
1866 key->symsDefined |= 1 << i;
1870 key->numLevels[i] = key->numLevels[0];
1873 /* If all groups are completely identical remove them all */
1874 /* exept the first one. */
1876 for (i = lastGroup; i > 0; i--)
1878 if ((key->numLevels[i] != key->numLevels[0]) ||
1879 (key->types[i] != key->types[0]))
1884 if ((key->syms[i] != key->syms[0]) &&
1885 (key->syms[i] == NULL || key->syms[0] == NULL ||
1886 memcmp((void *) key->syms[i], (void *) key->syms[0],
1887 sizeof(KeySym) * key->numLevels[0])))
1892 if ((key->acts[i] != key->acts[0]) &&
1893 (key->acts[i] == NULL || key->acts[0] == NULL ||
1894 memcmp((void *) key->acts[i], (void *) key->acts[0],
1895 sizeof(XkbcAction) * key->numLevels[0])))
1903 for (i = lastGroup; i > 0; i--)
1905 key->numLevels[i] = 0;
1906 if (key->syms[i] != NULL)
1907 uFree(key->syms[i]);
1908 key->syms[i] = (KeySym *) NULL;
1909 if (key->acts[i] != NULL)
1910 uFree(key->acts[i]);
1911 key->acts[i] = (XkbcAction *) NULL;
1912 key->types[i] = (Atom) 0;
1914 key->symsDefined &= 1;
1915 key->actsDefined &= 1;
1916 key->typesDefined &= 1;
1922 * Copy the KeyInfo into the keyboard description.
1924 * This function recurses.
1927 CopySymbolsDef(XkbcDescPtr xkb, KeyInfo *key, int start_from)
1930 unsigned okc, kc, width, tmp, nGroups;
1932 Bool haveActions, autoType, useAlias;
1934 XkbcAction *outActs;
1935 unsigned types[XkbNumKbdGroups];
1937 useAlias = (start_from == 0);
1939 /* get the keycode for the key. */
1940 if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1943 if ((start_from == 0) && (warningLevel >= 5))
1945 WARN("Key %s not found in %s keycodes\n",
1946 longText(key->name),
1947 XkbcAtomText(xkb->names->keycodes));
1948 ACTION("Symbols ignored\n");
1953 haveActions = False;
1954 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1956 if (((i + 1) > nGroups)
1957 && (((key->symsDefined | key->actsDefined) & (1 << i))
1958 || (key->typesDefined) & (1 << i)))
1963 /* Assign the type to the key, if it is missing. */
1964 if (key->types[i] == None)
1966 if (key->dfltType != None)
1967 key->types[i] = key->dfltType;
1968 else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1969 &key->types[i], &autoType))
1974 if (warningLevel >= 5)
1976 WARN("No automatic type for %d symbols\n",
1977 (unsigned int) key->numLevels[i]);
1978 ACTION("Using %s for the %s key (keycode %d)\n",
1979 XkbcAtomText(key->types[i]),
1980 longText(key->name), kc);
1984 if (FindNamedType(xkb, key->types[i], &types[i]))
1986 if (!autoType || key->numLevels[i] > 2)
1987 xkb->server->explicit[kc] |= (1 << i);
1991 if (warningLevel >= 3)
1993 WARN("Type \"%s\" is not defined\n",
1994 XkbcAtomText(key->types[i]));
1995 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
1996 longText(key->name), kc);
1998 types[i] = XkbTwoLevelIndex;
2000 /* if the type specifies less syms than the key has, shrink the key */
2001 type = &xkb->map->types[types[i]];
2002 if (type->num_levels < key->numLevels[i])
2004 if (warningLevel > 0)
2007 ("Type \"%s\" has %d levels, but %s has %d symbols\n",
2008 XkbcAtomText(type->name),
2009 (unsigned int) type->num_levels,
2010 longText(key->name),
2011 (unsigned int) key->numLevels[i]);
2012 ACTION("Ignoring extra symbols\n");
2014 key->numLevels[i] = type->num_levels;
2016 if (key->numLevels[i] > width)
2017 width = key->numLevels[i];
2018 if (type->num_levels > width)
2019 width = type->num_levels;
2022 /* width is now the largest width found */
2024 i = width * nGroups;
2025 outSyms = XkbcResizeKeySyms(xkb, kc, i);
2026 if (outSyms == NULL)
2028 WSGO("Could not enlarge symbols for %s (keycode %d)\n",
2029 longText(key->name), kc);
2034 outActs = XkbcResizeKeyActions(xkb, kc, i);
2035 if (outActs == NULL)
2037 WSGO("Could not enlarge actions for %s (key %d)\n",
2038 longText(key->name), kc);
2041 xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
2045 if (key->defs.defined & _Key_GroupInfo)
2048 i = xkb->map->key_sym_map[kc].group_info;
2050 xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2051 xkb->map->key_sym_map[kc].width = width;
2052 for (i = 0; i < nGroups; i++)
2054 /* assign kt_index[i] to the index of the type in map->types.
2055 * kt_index[i] may have been set by a previous run (if we have two
2056 * layouts specified). Let's not overwrite it with the ONE_LEVEL
2057 * default group if we dont even have keys for this group anyway.
2059 * FIXME: There should be a better fix for this.
2061 if (key->numLevels[i])
2062 xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2063 if (key->syms[i] != NULL)
2065 /* fill key to "width" symbols*/
2066 for (tmp = 0; tmp < width; tmp++)
2068 if (tmp < key->numLevels[i])
2069 outSyms[tmp] = key->syms[i][tmp];
2071 outSyms[tmp] = NoSymbol;
2072 if ((outActs != NULL) && (key->acts[i] != NULL))
2074 if (tmp < key->numLevels[i])
2075 outActs[tmp] = key->acts[i][tmp];
2077 outActs[tmp].type = XkbSA_NoAction;
2085 switch (key->behavior.type & XkbKB_OpMask)
2089 case XkbKB_Overlay1:
2090 case XkbKB_Overlay2:
2091 /* find key by name! */
2092 if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True,
2093 CreateKeyNames(xkb), 0))
2095 if (warningLevel >= 1)
2097 WARN("Key %s not found in %s keycodes\n",
2098 longText(key->nameForOverlayKey),
2099 XkbcAtomText(xkb->names->keycodes));
2100 ACTION("Not treating %s as an overlay key \n",
2101 longText(key->name));
2105 key->behavior.data = okc;
2107 xkb->server->behaviors[kc] = key->behavior;
2108 xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2111 if (key->defs.defined & _Key_VModMap)
2113 xkb->server->vmodmap[kc] = key->vmodmap;
2114 xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2116 if (key->repeat != RepeatUndefined)
2118 if (key->repeat == RepeatYes)
2119 xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2121 xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2122 xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2125 /* do the same thing for the next key */
2126 CopySymbolsDef(xkb, key, kc + 1);
2131 CopyModMapDef(XkbcDescPtr xkb, ModMapEntry *entry)
2135 if ((!entry->haveSymbol)
2138 (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
2140 if (warningLevel >= 5)
2142 WARN("Key %s not found in %s keycodes\n",
2143 longText(entry->u.keyName),
2144 XkbcAtomText(xkb->names->keycodes));
2145 ACTION("Modifier map entry for %s not updated\n",
2146 XkbcModIndexText(entry->modifier));
2150 else if (entry->haveSymbol
2151 && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2153 if (warningLevel > 5)
2155 WARN("Key \"%s\" not found in %s symbol map\n",
2156 XkbcKeysymText(entry->u.keySym),
2157 XkbcAtomText(xkb->names->symbols));
2158 ACTION("Modifier map entry for %s not updated\n",
2159 XkbcModIndexText(entry->modifier));
2163 xkb->map->modmap[kc] |= (1 << entry->modifier);
2168 * Handle the xkb_symbols section of an xkb file.
2170 * @param file The parsed xkb_symbols section of the xkb file.
2171 * @param xkb Handle to the keyboard description to store the symbols in.
2172 * @param merge Merge strategy (e.g. MergeOverride).
2175 CompileSymbols(XkbFile *file, XkbcDescPtr xkb, unsigned merge)
2180 InitSymbolsInfo(&info, xkb);
2181 info.dflt.defs.fileID = file->id;
2182 info.dflt.defs.merge = merge;
2183 HandleSymbolsFile(file, xkb, merge, &info);
2185 if (info.nKeys == 0)
2187 if (info.errorCount == 0)
2191 /* alloc memory in the xkb struct */
2192 if (XkbcAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0)
2195 WSGO("Can not allocate names in CompileSymbols\n");
2196 ACTION("Symbols not added\n");
2199 if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2202 WSGO("Could not allocate client map in CompileSymbols\n");
2203 ACTION("Symbols not added\n");
2206 if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2208 WSGO("Could not allocate server map in CompileSymbols\n");
2209 ACTION("Symbols not added\n");
2212 if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2214 WSGO("Could not allocate controls in CompileSymbols\n");
2215 ACTION("Symbols not added\n");
2219 /* now copy info into xkb. */
2220 xkb->names->symbols = XkbcInternAtom(info.name, False);
2222 ApplyAliases(xkb, False, &info.aliases);
2223 for (i = 0; i < XkbNumKbdGroups; i++)
2225 if (info.groupNames[i] != None)
2226 xkb->names->groups[i] = info.groupNames[i];
2229 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2234 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2236 if (!CopySymbolsDef(xkb, key, 0))
2239 if (warningLevel > 3)
2241 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2243 if (xkb->names->keys[i].name[0] == '\0')
2245 if (XkbKeyNumGroups(xkb, i) < 1)
2248 memcpy(buf, xkb->names->keys[i].name, 4);
2251 ("No symbols defined for <%s> (keycode %d)\n",
2258 ModMapEntry *mm, *next;
2259 for (mm = info.modMap; mm != NULL; mm = next)
2261 if (!CopyModMapDef(xkb, mm))
2263 next = (ModMapEntry *) mm->defs.next;