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 = XkbcInternAtom("ONE_LEVEL", False);
246 tok_TWO_LEVEL = XkbcInternAtom("TWO_LEVEL", False);
247 tok_KEYPAD = XkbcInternAtom("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));
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));
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));
412 ACTION2("Using %s, ignoring %s\n",
413 XkbcKeysymText(use), XkbcKeysymText(ignore));
417 if (resultActs != NULL)
419 XkbAction *fromAct, *toAct;
420 fromAct = (from->acts[group] ? &from->acts[group][i] : NULL);
421 toAct = (into->acts[group] ? &into->acts[group][i] : NULL);
422 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
425 resultActs[i] = *toAct;
427 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
428 && (fromAct != NULL))
430 resultActs[i] = *fromAct;
434 XkbAction *use, *ignore;
448 ("Multiple actions for level %d/group %d on key %s\n",
449 i + 1, group + 1, longText(into->name));
450 ACTION2("Using %s, ignoring %s\n",
451 XkbcActionTypeText(use->type),
452 XkbcActionTypeText(ignore->type));
454 resultActs[i] = *use;
458 if ((into->syms[group] != NULL) && (resultSyms != into->syms[group]))
459 uFree(into->syms[group]);
460 if ((from->syms[group] != NULL) && (resultSyms != from->syms[group]))
461 uFree(from->syms[group]);
462 if ((into->acts[group] != NULL) && (resultActs != into->acts[group]))
463 uFree(into->acts[group]);
464 if ((from->acts[group] != NULL) && (resultActs != from->acts[group]))
465 uFree(from->acts[group]);
466 into->numLevels[group] = resultWidth;
467 into->syms[group] = resultSyms;
468 from->syms[group] = NULL;
469 into->acts[group] = resultActs;
470 from->acts[group] = NULL;
471 into->symsDefined |= (1 << group);
472 from->symsDefined &= ~(1 << group);
473 into->actsDefined |= (1 << group);
474 from->actsDefined &= ~(1 << group);
479 MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from)
482 unsigned collide = 0;
485 if (from->defs.merge == MergeReplace)
487 for (i = 0; i < XkbNumKbdGroups; i++)
489 if (into->numLevels[i] != 0)
492 uFree(into->syms[i]);
494 uFree(into->acts[i]);
498 bzero(from, sizeof(KeyInfo));
501 report = ((warningLevel > 9) ||
502 ((into->defs.fileID == from->defs.fileID)
503 && (warningLevel > 0)));
504 for (i = 0; i < XkbNumKbdGroups; i++)
506 if (from->numLevels[i] > 0)
508 if (into->numLevels[i] == 0)
510 into->numLevels[i] = from->numLevels[i];
511 into->syms[i] = from->syms[i];
512 into->acts[i] = from->acts[i];
513 into->symsDefined |= (1 << i);
514 from->syms[i] = NULL;
515 from->acts[i] = NULL;
516 from->numLevels[i] = 0;
517 from->symsDefined &= ~(1 << i);
519 into->defs.defined |= _Key_Syms;
521 into->defs.defined |= _Key_Acts;
528 collide |= _Key_Syms;
530 collide |= _Key_Acts;
532 MergeKeyGroups(info, into, from, (unsigned) i);
535 if (from->types[i] != None)
537 if ((into->types[i] != None) && (report) &&
538 (into->types[i] != from->types[i]))
541 collide |= _Key_Types;
542 if (from->defs.merge != MergeAugment)
544 use = from->types[i];
545 ignore = into->types[i];
549 use = into->types[i];
550 ignore = from->types[i];
553 ("Multiple definitions for group %d type of key %s\n",
554 i, longText(into->name));
555 ACTION2("Using %s, ignoring %s\n",
557 XkbcAtomText(ignore));
559 if ((from->defs.merge != MergeAugment)
560 || (into->types[i] == None))
562 into->types[i] = from->types[i];
566 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
568 into->behavior = from->behavior;
569 into->nameForOverlayKey = from->nameForOverlayKey;
570 into->defs.defined |= _Key_Behavior;
572 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
574 into->vmodmap = from->vmodmap;
575 into->defs.defined |= _Key_VModMap;
577 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
579 into->repeat = from->repeat;
580 into->defs.defined |= _Key_Repeat;
582 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
584 into->dfltType = from->dfltType;
585 into->defs.defined |= _Key_Type_Dflt;
587 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
589 into->groupInfo = from->groupInfo;
590 into->defs.defined |= _Key_GroupInfo;
594 WARN1("Symbol map for key %s redefined\n",
595 longText(into->name));
596 ACTION1("Using %s definition for conflicting fields\n",
597 (from->defs.merge == MergeAugment ? "first" : "last"));
603 AddKeySymbols(SymbolsInfo * info, KeyInfo * key, XkbcDescPtr xkb)
606 unsigned long real_name;
608 for (i = 0; i < info->nKeys; i++)
610 if (info->keys[i].name == key->name)
611 return MergeKeys(info, &info->keys[i], key);
613 if (FindKeyNameForAlias(xkb, key->name, &real_name))
615 for (i = 0; i < info->nKeys; i++)
617 if (info->keys[i].name == real_name)
618 return MergeKeys(info, &info->keys[i], key);
621 if (info->nKeys >= info->szKeys)
623 info->szKeys += SYMBOLS_CHUNK;
625 uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo);
628 WSGO("Could not allocate key symbols descriptions\n");
629 ACTION("Some key symbols definitions may be lost\n");
633 return CopyKeyInfo(key, &info->keys[info->nKeys++], True);
637 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
642 clobber = (new->defs.merge != MergeAugment);
643 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
645 if (new->haveSymbol && mm->haveSymbol
646 && (new->u.keySym == mm->u.keySym))
648 unsigned use, ignore;
649 if (mm->modifier != new->modifier)
654 ignore = mm->modifier;
659 ignore = new->modifier;
662 ("%s added to symbol map for multiple modifiers\n",
663 XkbcKeysymText(new->u.keySym));
664 ACTION2("Using %s, ignoring %s.\n",
665 XkbcModIndexText(use),
666 XkbcModIndexText(ignore));
671 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
672 (new->u.keyName == mm->u.keyName))
674 unsigned use, ignore;
675 if (mm->modifier != new->modifier)
680 ignore = mm->modifier;
685 ignore = new->modifier;
687 ERROR1("Key %s added to map for multiple modifiers\n",
688 longText(new->u.keyName));
689 ACTION2("Using %s, ignoring %s.\n",
690 XkbcModIndexText(use),
691 XkbcModIndexText(ignore));
697 mm = uTypedAlloc(ModMapEntry);
700 WSGO("Could not allocate modifier map entry\n");
701 ACTION1("Modifier map for %s will be incomplete\n",
702 XkbcModIndexText(new->modifier));
706 mm->defs.next = &info->modMap->defs;
711 /***====================================================================***/
714 MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from,
715 unsigned merge, XkbcDescPtr xkb)
720 if (from->errorCount > 0)
722 into->errorCount += from->errorCount;
725 if (into->name == NULL)
727 into->name = from->name;
730 for (i = 0; i < XkbNumKbdGroups; i++)
732 if (from->groupNames[i] != None)
734 if ((merge != MergeAugment) || (into->groupNames[i] == None))
735 into->groupNames[i] = from->groupNames[i];
738 for (i = 0, key = from->keys; i < from->nKeys; i++, key++)
740 if (merge != MergeDefault)
741 key->defs.merge = merge;
742 if (!AddKeySymbols(into, key, xkb))
745 if (from->modMap != NULL)
747 ModMapEntry *mm, *next;
748 for (mm = from->modMap; mm != NULL; mm = next)
750 if (merge != MergeDefault)
751 mm->defs.merge = merge;
752 if (!AddModMapEntry(into, mm))
754 next = (ModMapEntry *) mm->defs.next;
759 if (!MergeAliases(&into->aliases, &from->aliases, merge))
764 typedef void (*FileHandler) (XkbFile * /* rtrn */ ,
765 XkbcDescPtr /* xkb */ ,
766 unsigned /* merge */ ,
767 SymbolsInfo * /* included */
771 HandleIncludeSymbols(IncludeStmt * stmt,
772 XkbcDescPtr xkb, SymbolsInfo * info, FileHandler hndlr)
776 SymbolsInfo included;
780 if ((stmt->file == NULL) && (stmt->map == NULL))
784 bzero(info, sizeof(SymbolsInfo));
786 else if (ProcessIncludeFile(stmt, XkmSymbolsIndex, &rtrn, &newMerge))
788 InitSymbolsInfo(&included, xkb);
789 included.fileID = included.dflt.defs.fileID = rtrn->id;
790 included.merge = included.dflt.defs.merge = MergeOverride;
793 included.explicit_group = atoi(stmt->modifier) - 1;
797 included.explicit_group = info->explicit_group;
799 (*hndlr) (rtrn, xkb, MergeOverride, &included);
800 if (stmt->stmt != NULL)
802 if (included.name != NULL)
803 uFree(included.name);
804 included.name = stmt->stmt;
810 info->errorCount += 10;
813 if ((stmt->next != NULL) && (included.errorCount < 1))
817 SymbolsInfo next_incl;
819 for (next = stmt->next; next != NULL; next = next->next)
821 if ((next->file == NULL) && (next->map == NULL))
824 MergeIncludedSymbols(&included, info, next->merge, xkb);
825 FreeSymbolsInfo(info);
827 else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op))
829 InitSymbolsInfo(&next_incl, xkb);
830 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
831 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride;
834 next_incl.explicit_group = atoi(next->modifier) - 1;
838 next_incl.explicit_group = info->explicit_group;
840 (*hndlr) (rtrn, xkb, MergeOverride, &next_incl);
841 MergeIncludedSymbols(&included, &next_incl, op, xkb);
842 FreeSymbolsInfo(&next_incl);
846 info->errorCount += 10;
855 MergeIncludedSymbols(info, &included, newMerge, xkb);
856 FreeSymbolsInfo(&included);
858 return (info->errorCount == 0);
861 static LookupEntry groupNames[] = {
878 GetGroupIndex(KeyInfo * key,
879 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
889 if (arrayNdx == NULL)
894 defined = key->symsDefined;
896 defined = key->actsDefined;
898 for (i = 0; i < XkbNumKbdGroups; i++)
900 if ((defined & (1 << i)) == 0)
906 ERROR3("Too many groups of %s for key %s (max %d)\n", name,
907 longText(key->name), XkbNumKbdGroups + 1);
908 ACTION1("Ignoring %s defined for extra groups\n", name);
911 if (!ExprResolveInteger
912 (arrayNdx, &tmp, SimpleLookup, (char *) groupNames))
914 ERROR2("Illegal group index for %s of key %s\n", name,
915 longText(key->name));
916 ACTION("Definition with non-integer array index ignored\n");
919 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
921 ERROR3("Group index for %s of key %s is out of range (1..%d)\n",
922 name, longText(key->name), XkbNumKbdGroups + 1);
923 ACTION2("Ignoring %s for group %d\n", name, tmp.uval);
926 *ndx_rtrn = tmp.uval - 1;
931 AddSymbolsToKey(KeyInfo * key,
934 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
939 if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx))
943 key->symsDefined |= (1 << ndx);
946 if (value->op != ExprKeysymList)
948 ERROR1("Expected a list of symbols, found %s\n",
949 exprOpText(value->op));
950 ACTION2("Ignoring symbols for group %d of %s\n", ndx,
951 longText(key->name));
954 if (key->syms[ndx] != NULL)
956 WSGO2("Symbols for key %s, group %d already defined\n",
957 longText(key->name), ndx);
960 nSyms = value->value.list.nSyms;
961 if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
962 (!ResizeKeyGroup(key, ndx, nSyms, False)))
964 WSGO2("Could not resize group %d of key %s\n", ndx,
965 longText(key->name));
966 ACTION("Symbols lost\n");
969 key->symsDefined |= (1 << ndx);
970 memcpy((char *) key->syms[ndx], (char *) value->value.list.syms,
971 nSyms * sizeof(KeySym));
972 for (i = key->numLevels[ndx] - 1;
973 (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--)
975 key->numLevels[ndx]--;
981 AddActionsToKey(KeyInfo * key,
984 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
991 if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx))
996 key->actsDefined |= (1 << ndx);
999 if (value->op != ExprActionList)
1001 WSGO1("Bad expression type (%d) for action list value\n", value->op);
1002 ACTION2("Ignoring actions for group %d of %s\n", ndx,
1003 longText(key->name));
1006 if (key->acts[ndx] != NULL)
1008 WSGO2("Actions for key %s, group %d already defined\n",
1009 longText(key->name), ndx);
1012 for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1014 act = (ExprDef *) act->common.next;
1018 WSGO("Action list but not actions in AddActionsToKey\n");
1021 if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1022 (!ResizeKeyGroup(key, ndx, nActs, True)))
1024 WSGO2("Could not resize group %d of key %s\n", ndx,
1025 longText(key->name));
1026 ACTION("Actions lost\n");
1029 key->actsDefined |= (1 << ndx);
1031 toAct = (XkbAnyAction *) key->acts[ndx];
1032 act = value->value.child;
1033 for (i = 0; i < nActs; i++, toAct++)
1035 if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action))
1037 ERROR1("Illegal action definition for %s\n",
1038 longText(key->name));
1039 ACTION2("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1041 act = (ExprDef *) act->common.next;
1047 SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value)
1050 unsigned radio_groups = 0;
1052 if (arrayNdx == NULL)
1054 radio_groups = XkbAllRadioGroupsMask;
1058 if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL))
1060 ERROR("Illegal index in group name definition\n");
1061 ACTION("Definition with non-integer array index ignored\n");
1064 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1066 ERROR1("Illegal radio group specified (must be 1..%d)\n",
1067 XkbMaxRadioGroups + 1);
1068 ACTION1("Value of \"allow none\" for group %d ignored\n",
1072 radio_groups |= (1 << (tmp.uval - 1));
1074 if (!ExprResolveBoolean(value, &tmp, NULL, NULL))
1076 ERROR1("Illegal \"allow none\" value for %s\n",
1077 longText(key->name));
1078 ACTION("Non-boolean value ignored\n");
1082 key->allowNone |= radio_groups;
1084 key->allowNone &= ~radio_groups;
1089 static LookupEntry lockingEntries[] = {
1090 {"true", XkbKB_Lock},
1091 {"yes", XkbKB_Lock},
1093 {"false", XkbKB_Default},
1094 {"no", XkbKB_Default},
1095 {"off", XkbKB_Default},
1096 {"permanent", XkbKB_Lock | XkbKB_Permanent},
1100 static LookupEntry repeatEntries[] = {
1101 {"true", RepeatYes},
1104 {"false", RepeatNo},
1107 {"default", RepeatUndefined},
1111 static LookupEntry rgEntries[] = {
1117 SetSymbolsField(KeyInfo * key,
1120 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1125 if (uStrCaseCmp(field, "type") == 0)
1128 if ((!ExprResolveString(value, &tmp, NULL, NULL))
1129 && (warningLevel > 0))
1131 WARN("The type field of a key symbol map must be a string\n");
1132 ACTION("Ignoring illegal type definition\n");
1134 if (arrayNdx == NULL)
1136 key->dfltType = XkbcInternAtom(tmp.str, False);
1137 key->defs.defined |= _Key_Type_Dflt;
1139 else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup,
1140 (char *) groupNames))
1142 ERROR1("Illegal group index for type of key %s\n",
1143 longText(key->name));
1144 ACTION("Definition with non-integer array index ignored\n");
1147 else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups))
1150 ("Group index for type of key %s is out of range (1..%d)\n",
1151 longText(key->name), XkbNumKbdGroups + 1);
1152 ACTION1("Ignoring type for group %d\n", ndx.uval);
1157 key->types[ndx.uval - 1] = XkbcInternAtom(tmp.str, False);
1158 key->typesDefined |= (1 << (ndx.uval - 1));
1161 else if (uStrCaseCmp(field, "symbols") == 0)
1162 return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1163 else if (uStrCaseCmp(field, "actions") == 0)
1164 return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1165 else if ((uStrCaseCmp(field, "vmods") == 0) ||
1166 (uStrCaseCmp(field, "virtualmods") == 0) ||
1167 (uStrCaseCmp(field, "virtualmodifiers") == 0))
1169 ok = ExprResolveModMask(value, &tmp, LookupVModMask, (char *) xkb);
1172 key->vmodmap = (tmp.uval >> 8);
1173 key->defs.defined |= _Key_VModMap;
1177 ERROR1("Expected a virtual modifier mask, found %s\n",
1178 exprOpText(value->op));
1179 ACTION1("Ignoring virtual modifiers definition for key %s\n",
1180 longText(key->name));
1183 else if ((uStrCaseCmp(field, "locking") == 0)
1184 || (uStrCaseCmp(field, "lock") == 0)
1185 || (uStrCaseCmp(field, "locks") == 0))
1187 ok = ExprResolveEnum(value, &tmp, lockingEntries);
1189 key->behavior.type = tmp.uval;
1190 key->defs.defined |= _Key_Behavior;
1192 else if ((uStrCaseCmp(field, "radiogroup") == 0) ||
1193 (uStrCaseCmp(field, "permanentradiogroup") == 0))
1195 Bool permanent = False;
1196 if (uStrCaseCmp(field, "permanentradiogroup") == 0)
1198 ok = ExprResolveInteger(value, &tmp, SimpleLookup,
1199 (char *) rgEntries);
1202 ERROR1("Illegal radio group specification for %s\n",
1203 longText(key->name));
1204 ACTION("Non-integer radio group ignored\n");
1209 key->behavior.type = XkbKB_Default;
1210 key->behavior.data = 0;
1213 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1216 ("Radio group specification for %s out of range (1..32)\n",
1217 longText(key->name));
1218 ACTION1("Illegal radio group %d ignored\n", tmp.uval);
1221 key->behavior.type =
1222 XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0);
1223 key->behavior.data = tmp.uval - 1;
1224 if (key->allowNone & (1 << (tmp.uval - 1)))
1225 key->behavior.data |= XkbKB_RGAllowNone;
1226 key->defs.defined |= _Key_Behavior;
1228 else if (uStrCaseEqual(field, "allownone"))
1230 ok = SetAllowNone(key, arrayNdx, value);
1232 else if (uStrCasePrefix("overlay", field) ||
1233 uStrCasePrefix("permanentoverlay", field))
1235 Bool permanent = False;
1238 if (uStrCasePrefix("permanent", field))
1241 which = &field[sizeof("permanentoverlay") - 1];
1245 which = &field[sizeof("overlay") - 1];
1247 if (sscanf(which, "%d", &overlayNdx) == 1)
1249 if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0))
1251 ERROR2("Illegal overlay %d specified for %s\n",
1252 overlayNdx, longText(key->name));
1253 ACTION("Ignored\n");
1257 else if (*which == '\0')
1259 else if (warningLevel > 0)
1261 ERROR2("Illegal overlay \"%s\" specified for %s\n",
1262 which, longText(key->name));
1263 ACTION("Ignored\n");
1266 ok = ExprResolveKeyName(value, &tmp, NULL, NULL);
1269 ERROR1("Illegal overlay key specification for %s\n",
1270 longText(key->name));
1271 ACTION("Overlay key must be specified by name\n");
1274 if (overlayNdx == 1)
1275 key->behavior.type = XkbKB_Overlay1;
1277 key->behavior.type = XkbKB_Overlay2;
1279 key->behavior.type |= XkbKB_Permanent;
1281 key->behavior.data = 0;
1282 key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name);
1283 key->defs.defined |= _Key_Behavior;
1285 else if ((uStrCaseCmp(field, "repeating") == 0) ||
1286 (uStrCaseCmp(field, "repeats") == 0) ||
1287 (uStrCaseCmp(field, "repeat") == 0))
1289 ok = ExprResolveEnum(value, &tmp, repeatEntries);
1292 ERROR1("Illegal repeat setting for %s\n",
1293 longText(key->name));
1294 ACTION("Non-boolean repeat setting ignored\n");
1297 key->repeat = tmp.uval;
1298 key->defs.defined |= _Key_Repeat;
1300 else if ((uStrCaseCmp(field, "groupswrap") == 0) ||
1301 (uStrCaseCmp(field, "wrapgroups") == 0))
1303 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1306 ERROR1("Illegal groupsWrap setting for %s\n",
1307 longText(key->name));
1308 ACTION("Non-boolean value ignored\n");
1312 key->groupInfo = XkbWrapIntoRange;
1314 key->groupInfo = XkbClampIntoRange;
1315 key->defs.defined |= _Key_GroupInfo;
1317 else if ((uStrCaseCmp(field, "groupsclamp") == 0) ||
1318 (uStrCaseCmp(field, "clampgroups") == 0))
1320 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1323 ERROR1("Illegal groupsClamp setting for %s\n",
1324 longText(key->name));
1325 ACTION("Non-boolean value ignored\n");
1329 key->groupInfo = XkbClampIntoRange;
1331 key->groupInfo = XkbWrapIntoRange;
1332 key->defs.defined |= _Key_GroupInfo;
1334 else if ((uStrCaseCmp(field, "groupsredirect") == 0) ||
1335 (uStrCaseCmp(field, "redirectgroups") == 0))
1337 if (!ExprResolveInteger
1338 (value, &tmp, SimpleLookup, (char *) groupNames))
1340 ERROR1("Illegal group index for redirect of key %s\n",
1341 longText(key->name));
1342 ACTION("Definition with non-integer group ignored\n");
1345 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1347 ERROR2("Out-of-range (1..%d) group for redirect of key %s\n",
1348 XkbNumKbdGroups, longText(key->name));
1349 ERROR1("Ignoring illegal group %d\n", tmp.uval);
1353 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1354 key->defs.defined |= _Key_GroupInfo;
1358 ERROR1("Unknown field %s in a symbol interpretation\n", field);
1359 ACTION("Definition ignored\n");
1366 SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1368 ExprResult tmp, name;
1370 if ((arrayNdx == NULL) && (warningLevel > 0))
1372 WARN("You must specify an index when specifying a group name\n");
1373 ACTION("Group name definition without array subscript ignored\n");
1376 if (!ExprResolveInteger
1377 (arrayNdx, &tmp, SimpleLookup, (char *) groupNames))
1379 ERROR("Illegal index in group name definition\n");
1380 ACTION("Definition with non-integer array index ignored\n");
1383 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1386 ("Attempt to specify name for illegal group (must be 1..%d)\n",
1387 XkbNumKbdGroups + 1);
1388 ACTION1("Name for group %d ignored\n", tmp.uval);
1391 if (!ExprResolveString(value, &name, NULL, NULL))
1393 ERROR("Group name must be a string\n");
1394 ACTION1("Illegal name for group %d ignored\n", tmp.uval);
1397 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1398 XkbcInternAtom(name.str, False);
1404 HandleSymbolsVar(VarDef * stmt, XkbcDescPtr xkb, SymbolsInfo * info)
1406 ExprResult elem, field, tmp;
1409 if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1410 return 0; /* internal error, already reported */
1411 if (elem.str && (uStrCaseCmp(elem.str, "key") == 0))
1413 return SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1416 else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) ||
1417 (uStrCaseCmp(field.str, "groupname") ==
1420 return SetGroupName(info, arrayNdx, stmt->value);
1422 else if ((elem.str == NULL)
1423 && ((uStrCaseCmp(field.str, "groupswrap") == 0)
1424 || (uStrCaseCmp(field.str, "wrapgroups") == 0)))
1426 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1428 ERROR("Illegal setting for global groupsWrap\n");
1429 ACTION("Non-boolean value ignored\n");
1433 info->groupInfo = XkbWrapIntoRange;
1435 info->groupInfo = XkbClampIntoRange;
1438 else if ((elem.str == NULL)
1439 && ((uStrCaseCmp(field.str, "groupsclamp") == 0)
1440 || (uStrCaseCmp(field.str, "clampgroups") == 0)))
1442 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1444 ERROR("Illegal setting for global groupsClamp\n");
1445 ACTION("Non-boolean value ignored\n");
1449 info->groupInfo = XkbClampIntoRange;
1451 info->groupInfo = XkbWrapIntoRange;
1454 else if ((elem.str == NULL)
1455 && ((uStrCaseCmp(field.str, "groupsredirect") == 0)
1456 || (uStrCaseCmp(field.str, "redirectgroups") == 0)))
1458 if (!ExprResolveInteger(stmt->value, &tmp,
1459 SimpleLookup, (char *) groupNames))
1461 ERROR("Illegal group index for global groupsRedirect\n");
1462 ACTION("Definition with non-integer group ignored\n");
1465 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1468 ("Out-of-range (1..%d) group for global groupsRedirect\n",
1470 ACTION1("Ignoring illegal group %d\n", tmp.uval);
1473 info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval);
1476 else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0))
1478 return SetAllowNone(&info->dflt, arrayNdx, stmt->value);
1480 return SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1485 HandleSymbolsBody(VarDef * def,
1486 XkbcDescPtr xkb, KeyInfo * key, SymbolsInfo * info)
1489 ExprResult tmp, field;
1492 for (; def != NULL; def = (VarDef *) def->common.next)
1494 if ((def->name) && (def->name->type == ExprFieldRef))
1496 ok = HandleSymbolsVar(def, xkb, info);
1501 if (def->name == NULL)
1503 if ((def->value == NULL)
1504 || (def->value->op == ExprKeysymList))
1505 field.str = "symbols";
1507 field.str = "actions";
1512 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1515 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1523 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1525 unsigned group = info->explicit_group;
1530 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1533 WARN1("For the map %s an explicit group specified\n", info->name);
1534 WARN1("but key %s has more than one group defined\n",
1535 longText(key->name));
1536 ACTION("All groups except first one will be ignored\n");
1537 for (i = 1; i < XkbNumKbdGroups; i++)
1539 key->numLevels[i] = 0;
1540 if (key->syms[i] != NULL)
1541 uFree(key->syms[i]);
1542 key->syms[i] = (KeySym *) NULL;
1543 if (key->acts[i] != NULL)
1544 uFree(key->acts[i]);
1545 key->acts[i] = (XkbAction *) NULL;
1546 key->types[i] = (Atom) 0;
1549 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1551 key->numLevels[group] = key->numLevels[0];
1552 key->numLevels[0] = 0;
1553 key->syms[group] = key->syms[0];
1554 key->syms[0] = (KeySym *) NULL;
1555 key->acts[group] = key->acts[0];
1556 key->acts[0] = (XkbAction *) NULL;
1557 key->types[group] = key->types[0];
1558 key->types[0] = (Atom) 0;
1563 HandleSymbolsDef(SymbolsDef * stmt,
1564 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1569 CopyKeyInfo(&info->dflt, &key, False);
1570 key.defs.merge = stmt->merge;
1571 key.name = KeyNameToLong(stmt->keyName);
1572 if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1578 if (!SetExplicitGroup(info, &key))
1584 if (!AddKeySymbols(info, &key, xkb))
1593 HandleModMapDef(ModMapDef * def,
1594 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1601 if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn))
1603 ERROR("Illegal modifier map definition\n");
1604 ACTION1("Ignoring map for non-modifier \"%s\"\n",
1605 XkbcAtomText(def->modifier));
1609 tmp.modifier = rtrn.uval;
1610 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1612 if ((key->op == ExprValue) && (key->type == TypeKeyName))
1614 tmp.haveSymbol = False;
1615 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1617 else if (ExprResolveKeySym(key, &rtrn, NULL, NULL))
1619 tmp.haveSymbol = True;
1620 tmp.u.keySym = rtrn.uval;
1624 ERROR("Modmap entries may contain only key names or keysyms\n");
1625 ACTION1("Illegal definition for %s modifier ignored\n",
1626 XkbcModIndexText(tmp.modifier));
1630 ok = AddModMapEntry(info, &tmp) && ok;
1636 HandleSymbolsFile(XkbFile * file,
1637 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1641 info->name = uStringDup(file->name);
1645 switch (stmt->stmtType)
1648 if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1652 case StmtSymbolsDef:
1653 if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1657 if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1661 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1665 ERROR("Interpretation files may not include other types\n");
1666 ACTION("Ignoring definition of symbol interpretation\n");
1669 case StmtKeycodeDef:
1670 ERROR("Interpretation files may not include other types\n");
1671 ACTION("Ignoring definition of key name\n");
1675 if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1679 WSGO1("Unexpected statement type %d in HandleSymbolsFile\n",
1684 if (info->errorCount > 10)
1687 ERROR("Too many errors\n");
1689 ACTION1("Abandoning symbols file \"%s\"\n", file->topName);
1697 FindKeyForSymbol(XkbcDescPtr xkb, KeySym sym, unsigned int *kc_rtrn)
1700 register Bool gotOne;
1706 for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1708 if (j < (int) XkbKeyNumSyms(xkb, i))
1711 if ((XkbKeySym(xkb, i, j) == sym))
1725 * Find the given name in the xkb->map->types and return its index.
1727 * @param name The atom to search for.
1728 * @param type_rtrn Set to the index of the name if found.
1730 * @return True if found, False otherwise.
1733 FindNamedType(XkbcDescPtr xkb, Atom name, unsigned *type_rtrn)
1735 register unsigned n;
1737 if (xkb && xkb->map && xkb->map->types)
1739 for (n = 0; n < xkb->map->num_types; n++)
1741 if (xkb->map->types[n].name == (Atom) name)
1752 KSIsLower(KeySym ks)
1754 KeySym lower, upper;
1755 XConvertCase(ks, &lower, &upper);
1759 return (ks == lower ? True : False);
1763 KSIsUpper(KeySym ks)
1765 KeySym lower, upper;
1766 XConvertCase(ks, &lower, &upper);
1770 return (ks == upper ? True : False);
1774 * Assign a type to the given sym and return the Atom for the type assigned.
1777 * - ONE_LEVEL for width 0/1
1778 * - ALPHABETIC for 2 shift levels, with lower/upercase
1779 * - KEYPAD for keypad keys.
1780 * - TWO_LEVEL for other 2 shift level keys.
1781 * and the same for four level keys.
1783 * @param width Number of sysms in syms.
1784 * @param syms The keysyms for the given key (must be size width).
1785 * @param typeNameRtrn Set to the Atom of the type name.
1787 * @returns True if a type could be found, False otherwise.
1790 FindAutomaticType(int width, KeySym * syms, Atom * typeNameRtrn,
1794 if ((width == 1) || (width == 0))
1796 *typeNameRtrn = XkbcInternAtom("ONE_LEVEL", False);
1799 else if (width == 2)
1801 if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]))
1803 *typeNameRtrn = XkbcInternAtom("ALPHABETIC", False);
1805 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1807 *typeNameRtrn = XkbcInternAtom("KEYPAD", False);
1812 *typeNameRtrn = XkbcInternAtom("TWO_LEVEL", False);
1816 else if (width <= 4)
1818 if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]))
1819 if (KSIsLower(syms[2]) && KSIsUpper(syms[3]))
1821 XkbcInternAtom("FOUR_LEVEL_ALPHABETIC", False);
1823 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL_SEMIALPHABETIC",
1826 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1827 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL_KEYPAD", False);
1829 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL", False);
1830 /* XXX: why not set autoType here? */
1832 return ((width >= 0) && (width <= 4));
1836 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1837 * groups, and reduce to one group if all groups are identical anyway.
1840 PrepareKeyDef(KeyInfo * key)
1842 int i, j, width, defined, lastGroup;
1845 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1846 /* get highest group number */
1847 for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1849 if (defined & (1 << i))
1857 /* If there are empty groups between non-empty ones fill them with data */
1858 /* from the first group. */
1859 /* We can make a wrong assumption here. But leaving gaps is worse. */
1860 for (i = lastGroup; i > 0; i--)
1862 if (defined & (1 << i))
1864 width = key->numLevels[0];
1865 if (key->typesDefined & 1)
1867 for (j = 0; j < width; j++)
1869 key->types[i] = key->types[0];
1871 key->typesDefined |= 1 << i;
1873 if ((key->actsDefined & 1) && key->acts[0])
1875 key->acts[i] = uTypedCalloc(width, XkbAction);
1876 if (key->acts[i] == NULL)
1878 memcpy((void *) key->acts[i], (void *) key->acts[0],
1879 width * sizeof(XkbAction));
1880 key->actsDefined |= 1 << i;
1882 if ((key->symsDefined & 1) && key->syms[0])
1884 key->syms[i] = uTypedCalloc(width, KeySym);
1885 if (key->syms[i] == NULL)
1887 memcpy((void *) key->syms[i], (void *) key->syms[0],
1888 width * sizeof(KeySym));
1889 key->symsDefined |= 1 << i;
1893 key->numLevels[i] = key->numLevels[0];
1896 /* If all groups are completely identical remove them all */
1897 /* exept the first one. */
1899 for (i = lastGroup; i > 0; i--)
1901 if ((key->numLevels[i] != key->numLevels[0]) ||
1902 (key->types[i] != key->types[0]))
1907 if ((key->syms[i] != key->syms[0]) &&
1908 (key->syms[i] == NULL || key->syms[0] == NULL ||
1909 memcmp((void *) key->syms[i], (void *) key->syms[0],
1910 sizeof(KeySym) * key->numLevels[0])))
1915 if ((key->acts[i] != key->acts[0]) &&
1916 (key->acts[i] == NULL || key->acts[0] == NULL ||
1917 memcmp((void *) key->acts[i], (void *) key->acts[0],
1918 sizeof(XkbAction) * key->numLevels[0])))
1926 for (i = lastGroup; i > 0; i--)
1928 key->numLevels[i] = 0;
1929 if (key->syms[i] != NULL)
1930 uFree(key->syms[i]);
1931 key->syms[i] = (KeySym *) NULL;
1932 if (key->acts[i] != NULL)
1933 uFree(key->acts[i]);
1934 key->acts[i] = (XkbAction *) NULL;
1935 key->types[i] = (Atom) 0;
1937 key->symsDefined &= 1;
1938 key->actsDefined &= 1;
1939 key->typesDefined &= 1;
1945 * Copy the KeyInfo into the keyboard description.
1947 * This function recurses.
1950 CopySymbolsDef(XkbcDescPtr xkb, KeyInfo *key, int start_from)
1953 unsigned okc, kc, width, tmp, nGroups;
1955 Bool haveActions, autoType, useAlias;
1958 unsigned types[XkbNumKbdGroups];
1960 useAlias = (start_from == 0);
1962 /* get the keycode for the key. */
1963 if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1966 if ((start_from == 0) && (warningLevel >= 5))
1968 WARN2("Key %s not found in %s keycodes\n",
1969 longText(key->name),
1970 XkbcAtomText(xkb->names->keycodes));
1971 ACTION("Symbols ignored\n");
1976 haveActions = False;
1977 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1979 if (((i + 1) > nGroups)
1980 && (((key->symsDefined | key->actsDefined) & (1 << i))
1981 || (key->typesDefined) & (1 << i)))
1986 /* Assign the type to the key, if it is missing. */
1987 if (key->types[i] == None)
1989 if (key->dfltType != None)
1990 key->types[i] = key->dfltType;
1991 else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1992 &key->types[i], &autoType))
1997 if (warningLevel >= 5)
1999 WARN1("No automatic type for %d symbols\n",
2000 (unsigned int) key->numLevels[i]);
2001 ACTION3("Using %s for the %s key (keycode %d)\n",
2002 XkbcAtomText(key->types[i]),
2003 longText(key->name), kc);
2007 if (FindNamedType(xkb, key->types[i], &types[i]))
2009 if (!autoType || key->numLevels[i] > 2)
2010 xkb->server->explicit[kc] |= (1 << i);
2014 if (warningLevel >= 3)
2016 WARN1("Type \"%s\" is not defined\n",
2017 XkbcAtomText(key->types[i]));
2018 ACTION2("Using TWO_LEVEL for the %s key (keycode %d)\n",
2019 longText(key->name), kc);
2021 types[i] = XkbTwoLevelIndex;
2023 /* if the type specifies less syms than the key has, shrink the key */
2024 type = &xkb->map->types[types[i]];
2025 if (type->num_levels < key->numLevels[i])
2027 if (warningLevel > 0)
2030 ("Type \"%s\" has %d levels, but %s has %d symbols\n",
2031 XkbcAtomText(type->name),
2032 (unsigned int) type->num_levels,
2033 longText(key->name),
2034 (unsigned int) key->numLevels[i]);
2035 ACTION("Ignoring extra symbols\n");
2037 key->numLevels[i] = type->num_levels;
2039 if (key->numLevels[i] > width)
2040 width = key->numLevels[i];
2041 if (type->num_levels > width)
2042 width = type->num_levels;
2045 /* width is now the largest width found */
2047 i = width * nGroups;
2048 outSyms = XkbResizeKeySyms(xkb, kc, i);
2049 if (outSyms == NULL)
2051 WSGO2("Could not enlarge symbols for %s (keycode %d)\n",
2052 longText(key->name), kc);
2057 outActs = XkbResizeKeyActions(xkb, kc, i);
2058 if (outActs == NULL)
2060 WSGO2("Could not enlarge actions for %s (key %d)\n",
2061 longText(key->name), kc);
2064 xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
2068 if (key->defs.defined & _Key_GroupInfo)
2071 i = xkb->map->key_sym_map[kc].group_info;
2073 xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2074 xkb->map->key_sym_map[kc].width = width;
2075 for (i = 0; i < nGroups; i++)
2077 /* assign kt_index[i] to the index of the type in map->types.
2078 * kt_index[i] may have been set by a previous run (if we have two
2079 * layouts specified). Let's not overwrite it with the ONE_LEVEL
2080 * default group if we dont even have keys for this group anyway.
2082 * FIXME: There should be a better fix for this.
2084 if (key->numLevels[i])
2085 xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2086 if (key->syms[i] != NULL)
2088 /* fill key to "width" symbols*/
2089 for (tmp = 0; tmp < width; tmp++)
2091 if (tmp < key->numLevels[i])
2092 outSyms[tmp] = key->syms[i][tmp];
2094 outSyms[tmp] = NoSymbol;
2095 if ((outActs != NULL) && (key->acts[i] != NULL))
2097 if (tmp < key->numLevels[i])
2098 outActs[tmp] = key->acts[i][tmp];
2100 outActs[tmp].type = XkbSA_NoAction;
2108 switch (key->behavior.type & XkbKB_OpMask)
2112 case XkbKB_Overlay1:
2113 case XkbKB_Overlay2:
2114 /* find key by name! */
2115 if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True,
2116 CreateKeyNames(xkb), 0))
2118 if (warningLevel >= 1)
2120 WARN2("Key %s not found in %s keycodes\n",
2121 longText(key->nameForOverlayKey),
2122 XkbcAtomText(xkb->names->keycodes));
2123 ACTION1("Not treating %s as an overlay key \n",
2124 longText(key->name));
2128 key->behavior.data = okc;
2130 xkb->server->behaviors[kc] = key->behavior;
2131 xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2134 if (key->defs.defined & _Key_VModMap)
2136 xkb->server->vmodmap[kc] = key->vmodmap;
2137 xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2139 if (key->repeat != RepeatUndefined)
2141 if (key->repeat == RepeatYes)
2142 xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2144 xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2145 xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2148 /* do the same thing for the next key */
2149 CopySymbolsDef(xkb, key, kc + 1);
2154 CopyModMapDef(XkbcDescPtr xkb, ModMapEntry *entry)
2158 if ((!entry->haveSymbol)
2161 (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
2163 if (warningLevel >= 5)
2165 WARN2("Key %s not found in %s keycodes\n",
2166 longText(entry->u.keyName),
2167 XkbcAtomText(xkb->names->keycodes));
2168 ACTION1("Modifier map entry for %s not updated\n",
2169 XkbcModIndexText(entry->modifier));
2173 else if (entry->haveSymbol
2174 && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2176 if (warningLevel > 5)
2178 WARN2("Key \"%s\" not found in %s symbol map\n",
2179 XkbcKeysymText(entry->u.keySym),
2180 XkbcAtomText(xkb->names->symbols));
2181 ACTION1("Modifier map entry for %s not updated\n",
2182 XkbcModIndexText(entry->modifier));
2186 xkb->map->modmap[kc] |= (1 << entry->modifier);
2191 * Handle the xkb_symbols section of an xkb file.
2193 * @param file The parsed xkb_symbols section of the xkb file.
2194 * @param xkb Handle to the keyboard description to store the symbols in.
2195 * @param merge Merge strategy (e.g. MergeOverride).
2198 CompileSymbols(XkbFile *file, XkbcDescPtr xkb, unsigned merge)
2203 InitSymbolsInfo(&info, xkb);
2204 info.dflt.defs.fileID = file->id;
2205 info.dflt.defs.merge = merge;
2206 HandleSymbolsFile(file, xkb, merge, &info);
2208 if (info.nKeys == 0)
2210 if (info.errorCount == 0)
2214 /* alloc memory in the xkb struct */
2215 if (XkbcAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0)
2218 WSGO("Can not allocate names in CompileSymbols\n");
2219 ACTION("Symbols not added\n");
2222 if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2225 WSGO("Could not allocate client map in CompileSymbols\n");
2226 ACTION("Symbols not added\n");
2229 if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2231 WSGO("Could not allocate server map in CompileSymbols\n");
2232 ACTION("Symbols not added\n");
2235 if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2237 WSGO("Could not allocate controls in CompileSymbols\n");
2238 ACTION("Symbols not added\n");
2242 /* now copy info into xkb. */
2243 xkb->names->symbols = XkbcInternAtom(info.name, False);
2245 ApplyAliases(xkb, False, &info.aliases);
2246 for (i = 0; i < XkbNumKbdGroups; i++)
2248 if (info.groupNames[i] != None)
2249 xkb->names->groups[i] = info.groupNames[i];
2252 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2257 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2259 if (!CopySymbolsDef(xkb, key, 0))
2262 if (warningLevel > 3)
2264 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2266 if (xkb->names->keys[i].name[0] == '\0')
2268 if (XkbKeyNumGroups(xkb, i) < 1)
2271 memcpy(buf, xkb->names->keys[i].name, 4);
2274 ("No symbols defined for <%s> (keycode %d)\n",
2281 ModMapEntry *mm, *next;
2282 for (mm = info.modMap; mm != NULL; mm = next)
2284 if (!CopyModMapDef(xkb, mm))
2286 next = (ModMapEntry *) mm->defs.next;