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 ********************************************************/
33 #include <X11/extensions/XKBfilecommon.h>
34 #include <X11/keysym.h>
44 extern Atom tok_ONE_LEVEL;
45 extern Atom tok_TWO_LEVEL;
46 extern Atom tok_KEYPAD;
48 /***====================================================================***/
52 #define RepeatUndefined ~((unsigned)0)
54 #define _Key_Syms (1<<0)
55 #define _Key_Acts (1<<1)
56 #define _Key_Repeat (1<<2)
57 #define _Key_Behavior (1<<3)
58 #define _Key_Type_Dflt (1<<4)
59 #define _Key_Types (1<<5)
60 #define _Key_GroupInfo (1<<6)
61 #define _Key_VModMap (1<<7)
63 typedef struct _KeyInfo
66 unsigned long name; /* the 4 chars of the key name, as long */
67 unsigned char groupInfo;
68 unsigned char typesDefined;
69 unsigned char symsDefined;
70 unsigned char actsDefined;
71 short numLevels[XkbNumKbdGroups];
72 KeySym *syms[XkbNumKbdGroups];
73 XkbcAction *acts[XkbNumKbdGroups];
74 Atom types[XkbNumKbdGroups];
77 unsigned short vmodmap;
78 unsigned long nameForOverlayKey;
79 unsigned long allowNone;
84 * Init the given key info to sane values.
87 InitKeyInfo(KeyInfo * info)
90 static char dflt[4] = "*";
92 info->defs.defined = 0;
93 info->defs.fileID = 0;
94 info->defs.merge = MergeOverride;
95 info->defs.next = NULL;
96 info->name = KeyNameToLong(dflt);
98 info->typesDefined = info->symsDefined = info->actsDefined = 0;
99 for (i = 0; i < XkbNumKbdGroups; i++)
101 info->numLevels[i] = 0;
102 info->types[i] = None;
103 info->syms[i] = NULL;
104 info->acts[i] = NULL;
106 info->dfltType = None;
107 info->behavior.type = XkbKB_Default;
108 info->behavior.data = 0;
110 info->nameForOverlayKey = 0;
111 info->repeat = RepeatUndefined;
117 * Free memory associated with this key info and reset to sane values.
120 FreeKeyInfo(KeyInfo * info)
124 info->defs.defined = 0;
125 info->defs.fileID = 0;
126 info->defs.merge = MergeOverride;
127 info->defs.next = NULL;
129 info->typesDefined = info->symsDefined = info->actsDefined = 0;
130 for (i = 0; i < XkbNumKbdGroups; i++)
132 info->numLevels[i] = 0;
133 info->types[i] = None;
134 if (info->syms[i] != NULL)
135 uFree(info->syms[i]);
136 info->syms[i] = NULL;
137 if (info->acts[i] != NULL)
138 uFree(info->acts[i]);
139 info->acts[i] = NULL;
141 info->dfltType = None;
142 info->behavior.type = XkbKB_Default;
143 info->behavior.data = 0;
145 info->nameForOverlayKey = 0;
146 info->repeat = RepeatUndefined;
152 * Copy old into new, optionally reset old to 0.
153 * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
154 * newly allocated and new points to the new memory areas.
157 CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld)
162 new->defs.next = NULL;
165 for (i = 0; i < XkbNumKbdGroups; i++)
167 old->numLevels[i] = 0;
175 for (i = 0; i < XkbNumKbdGroups; i++)
177 width = new->numLevels[i];
178 if (old->syms[i] != NULL)
180 new->syms[i] = uTypedCalloc(width, KeySym);
184 new->numLevels[i] = 0;
187 memcpy((char *) new->syms[i], (char *) old->syms[i],
188 width * sizeof(KeySym));
190 if (old->acts[i] != NULL)
192 new->acts[i] = uTypedCalloc(width, XkbcAction);
198 memcpy((char *) new->acts[i], (char *) old->acts[i],
199 width * sizeof(XkbcAction));
206 /***====================================================================***/
208 typedef struct _ModMapEntry
215 unsigned long keyName;
220 #define SYMBOLS_INIT_SIZE 110
221 #define SYMBOLS_CHUNK 20
222 typedef struct _SymbolsInfo
224 char *name; /* e.g. pc+us+inet(evdev) */
228 unsigned explicit_group;
236 Atom groupNames[XkbNumKbdGroups];
243 InitSymbolsInfo(SymbolsInfo * info, XkbcDescPtr xkb)
247 tok_ONE_LEVEL = XkbcInternAtom("ONE_LEVEL", False);
248 tok_TWO_LEVEL = XkbcInternAtom("TWO_LEVEL", False);
249 tok_KEYPAD = XkbcInternAtom("KEYPAD", False);
251 info->explicit_group = 0;
252 info->errorCount = 0;
254 info->merge = MergeOverride;
256 info->szKeys = SYMBOLS_INIT_SIZE;
258 info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo);
260 for (i = 0; i < XkbNumKbdGroups; i++)
261 info->groupNames[i] = None;
262 InitKeyInfo(&info->dflt);
263 InitVModInfo(&info->vmods, xkb);
265 info->aliases = NULL;
270 FreeSymbolsInfo(SymbolsInfo * info)
279 for (i = 0; i < info->nKeys; i++)
281 FreeKeyInfo(&info->keys[i]);
288 ClearCommonInfo(&info->modMap->defs);
293 ClearAliases(&info->aliases);
294 info->aliases = NULL;
296 bzero((char *) info, sizeof(SymbolsInfo));
301 ResizeKeyGroup(KeyInfo * key,
302 unsigned group, unsigned atLeastSize, Bool forceActions)
307 tooSmall = (key->numLevels[group] < atLeastSize);
309 newWidth = atLeastSize;
311 newWidth = key->numLevels[group];
313 if ((key->syms[group] == NULL) || tooSmall)
315 key->syms[group] = uTypedRecalloc(key->syms[group],
316 key->numLevels[group], newWidth,
318 if (!key->syms[group])
321 if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) ||
322 (tooSmall && (key->acts[group] != NULL)))
324 key->acts[group] = uTypedRecalloc(key->acts[group],
325 key->numLevels[group], newWidth,
327 if (!key->acts[group])
330 key->numLevels[group] = newWidth;
335 MergeKeyGroups(SymbolsInfo * info,
336 KeyInfo * into, KeyInfo * from, unsigned group)
339 XkbcAction *resultActs;
342 Bool report, clobber;
344 clobber = (from->defs.merge != MergeAugment);
345 report = (warningLevel > 9) ||
346 ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
347 if (into->numLevels[group] >= from->numLevels[group])
349 resultSyms = into->syms[group];
350 resultActs = into->acts[group];
351 resultWidth = into->numLevels[group];
355 resultSyms = from->syms[group];
356 resultActs = from->acts[group];
357 resultWidth = from->numLevels[group];
359 if (resultSyms == NULL)
361 resultSyms = uTypedCalloc(resultWidth, KeySym);
364 WSGO("Could not allocate symbols for group merge\n");
365 ACTION("Group %d of key %s not merged\n", group,
366 longText(into->name));
370 if ((resultActs == NULL) && (into->acts[group] || from->acts[group]))
372 resultActs = uTypedCalloc(resultWidth, XkbcAction);
375 WSGO("Could not allocate actions for group merge\n");
376 ACTION("Group %d of key %s not merged\n", group,
377 longText(into->name));
381 for (i = 0; i < resultWidth; i++)
383 KeySym fromSym, toSym;
384 if (from->syms[group] && (i < from->numLevels[group]))
385 fromSym = from->syms[group][i];
388 if (into->syms[group] && (i < into->numLevels[group]))
389 toSym = into->syms[group][i];
392 if ((fromSym == NoSymbol) || (fromSym == toSym))
393 resultSyms[i] = toSym;
394 else if (toSym == NoSymbol)
395 resultSyms[i] = fromSym;
412 ("Multiple symbols for level %d/group %d on key %s\n",
413 i + 1, group + 1, longText(into->name));
414 ACTION("Using %s, ignoring %s\n",
415 XkbcKeysymText(use), XkbcKeysymText(ignore));
419 if (resultActs != NULL)
421 XkbcAction *fromAct, *toAct;
422 fromAct = (from->acts[group] ? &from->acts[group][i] : NULL);
423 toAct = (into->acts[group] ? &into->acts[group][i] : NULL);
424 if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction))
427 resultActs[i] = *toAct;
429 else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction))
430 && (fromAct != NULL))
432 resultActs[i] = *fromAct;
436 XkbcAction *use, *ignore;
450 ("Multiple actions for level %d/group %d on key %s\n",
451 i + 1, group + 1, longText(into->name));
452 ACTION("Using %s, ignoring %s\n",
453 XkbcActionTypeText(use->type),
454 XkbcActionTypeText(ignore->type));
456 resultActs[i] = *use;
460 if ((into->syms[group] != NULL) && (resultSyms != into->syms[group]))
461 uFree(into->syms[group]);
462 if ((from->syms[group] != NULL) && (resultSyms != from->syms[group]))
463 uFree(from->syms[group]);
464 if ((into->acts[group] != NULL) && (resultActs != into->acts[group]))
465 uFree(into->acts[group]);
466 if ((from->acts[group] != NULL) && (resultActs != from->acts[group]))
467 uFree(from->acts[group]);
468 into->numLevels[group] = resultWidth;
469 into->syms[group] = resultSyms;
470 from->syms[group] = NULL;
471 into->acts[group] = resultActs;
472 from->acts[group] = NULL;
473 into->symsDefined |= (1 << group);
474 from->symsDefined &= ~(1 << group);
475 into->actsDefined |= (1 << group);
476 from->actsDefined &= ~(1 << group);
481 MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from)
484 unsigned collide = 0;
487 if (from->defs.merge == MergeReplace)
489 for (i = 0; i < XkbNumKbdGroups; i++)
491 if (into->numLevels[i] != 0)
494 uFree(into->syms[i]);
496 uFree(into->acts[i]);
500 bzero(from, sizeof(KeyInfo));
503 report = ((warningLevel > 9) ||
504 ((into->defs.fileID == from->defs.fileID)
505 && (warningLevel > 0)));
506 for (i = 0; i < XkbNumKbdGroups; i++)
508 if (from->numLevels[i] > 0)
510 if (into->numLevels[i] == 0)
512 into->numLevels[i] = from->numLevels[i];
513 into->syms[i] = from->syms[i];
514 into->acts[i] = from->acts[i];
515 into->symsDefined |= (1 << i);
516 from->syms[i] = NULL;
517 from->acts[i] = NULL;
518 from->numLevels[i] = 0;
519 from->symsDefined &= ~(1 << i);
521 into->defs.defined |= _Key_Syms;
523 into->defs.defined |= _Key_Acts;
530 collide |= _Key_Syms;
532 collide |= _Key_Acts;
534 MergeKeyGroups(info, into, from, (unsigned) i);
537 if (from->types[i] != None)
539 if ((into->types[i] != None) && (report) &&
540 (into->types[i] != from->types[i]))
543 collide |= _Key_Types;
544 if (from->defs.merge != MergeAugment)
546 use = from->types[i];
547 ignore = into->types[i];
551 use = into->types[i];
552 ignore = from->types[i];
555 ("Multiple definitions for group %d type of key %s\n",
556 i, longText(into->name));
557 ACTION("Using %s, ignoring %s\n",
559 XkbcAtomText(ignore));
561 if ((from->defs.merge != MergeAugment)
562 || (into->types[i] == None))
564 into->types[i] = from->types[i];
568 if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide))
570 into->behavior = from->behavior;
571 into->nameForOverlayKey = from->nameForOverlayKey;
572 into->defs.defined |= _Key_Behavior;
574 if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide))
576 into->vmodmap = from->vmodmap;
577 into->defs.defined |= _Key_VModMap;
579 if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide))
581 into->repeat = from->repeat;
582 into->defs.defined |= _Key_Repeat;
584 if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide))
586 into->dfltType = from->dfltType;
587 into->defs.defined |= _Key_Type_Dflt;
589 if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide))
591 into->groupInfo = from->groupInfo;
592 into->defs.defined |= _Key_GroupInfo;
596 WARN("Symbol map for key %s redefined\n",
597 longText(into->name));
598 ACTION("Using %s definition for conflicting fields\n",
599 (from->defs.merge == MergeAugment ? "first" : "last"));
605 AddKeySymbols(SymbolsInfo * info, KeyInfo * key, XkbcDescPtr xkb)
608 unsigned long real_name;
610 for (i = 0; i < info->nKeys; i++)
612 if (info->keys[i].name == key->name)
613 return MergeKeys(info, &info->keys[i], key);
615 if (FindKeyNameForAlias(xkb, key->name, &real_name))
617 for (i = 0; i < info->nKeys; i++)
619 if (info->keys[i].name == real_name)
620 return MergeKeys(info, &info->keys[i], key);
623 if (info->nKeys >= info->szKeys)
625 info->szKeys += SYMBOLS_CHUNK;
627 uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo);
630 WSGO("Could not allocate key symbols descriptions\n");
631 ACTION("Some key symbols definitions may be lost\n");
635 return CopyKeyInfo(key, &info->keys[info->nKeys++], True);
639 AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
644 clobber = (new->defs.merge != MergeAugment);
645 for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next)
647 if (new->haveSymbol && mm->haveSymbol
648 && (new->u.keySym == mm->u.keySym))
650 unsigned use, ignore;
651 if (mm->modifier != new->modifier)
656 ignore = mm->modifier;
661 ignore = new->modifier;
664 ("%s added to symbol map for multiple modifiers\n",
665 XkbcKeysymText(new->u.keySym));
666 ACTION("Using %s, ignoring %s.\n",
667 XkbcModIndexText(use),
668 XkbcModIndexText(ignore));
673 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
674 (new->u.keyName == mm->u.keyName))
676 unsigned use, ignore;
677 if (mm->modifier != new->modifier)
682 ignore = mm->modifier;
687 ignore = new->modifier;
689 ERROR("Key %s added to map for multiple modifiers\n",
690 longText(new->u.keyName));
691 ACTION("Using %s, ignoring %s.\n",
692 XkbcModIndexText(use),
693 XkbcModIndexText(ignore));
699 mm = uTypedAlloc(ModMapEntry);
702 WSGO("Could not allocate modifier map entry\n");
703 ACTION("Modifier map for %s will be incomplete\n",
704 XkbcModIndexText(new->modifier));
708 mm->defs.next = &info->modMap->defs;
713 /***====================================================================***/
716 MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from,
717 unsigned merge, XkbcDescPtr xkb)
722 if (from->errorCount > 0)
724 into->errorCount += from->errorCount;
727 if (into->name == NULL)
729 into->name = from->name;
732 for (i = 0; i < XkbNumKbdGroups; i++)
734 if (from->groupNames[i] != None)
736 if ((merge != MergeAugment) || (into->groupNames[i] == None))
737 into->groupNames[i] = from->groupNames[i];
740 for (i = 0, key = from->keys; i < from->nKeys; i++, key++)
742 if (merge != MergeDefault)
743 key->defs.merge = merge;
744 if (!AddKeySymbols(into, key, xkb))
747 if (from->modMap != NULL)
749 ModMapEntry *mm, *next;
750 for (mm = from->modMap; mm != NULL; mm = next)
752 if (merge != MergeDefault)
753 mm->defs.merge = merge;
754 if (!AddModMapEntry(into, mm))
756 next = (ModMapEntry *) mm->defs.next;
761 if (!MergeAliases(&into->aliases, &from->aliases, merge))
766 typedef void (*FileHandler) (XkbFile * /* rtrn */ ,
767 XkbcDescPtr /* xkb */ ,
768 unsigned /* merge */ ,
769 SymbolsInfo * /* included */
773 HandleIncludeSymbols(IncludeStmt * stmt,
774 XkbcDescPtr xkb, SymbolsInfo * info, FileHandler hndlr)
778 SymbolsInfo included;
782 if ((stmt->file == NULL) && (stmt->map == NULL))
786 bzero(info, sizeof(SymbolsInfo));
788 else if (ProcessIncludeFile(stmt, XkmSymbolsIndex, &rtrn, &newMerge))
790 InitSymbolsInfo(&included, xkb);
791 included.fileID = included.dflt.defs.fileID = rtrn->id;
792 included.merge = included.dflt.defs.merge = MergeOverride;
795 included.explicit_group = atoi(stmt->modifier) - 1;
799 included.explicit_group = info->explicit_group;
801 (*hndlr) (rtrn, xkb, MergeOverride, &included);
802 if (stmt->stmt != NULL)
804 if (included.name != NULL)
805 uFree(included.name);
806 included.name = stmt->stmt;
812 info->errorCount += 10;
815 if ((stmt->next != NULL) && (included.errorCount < 1))
819 SymbolsInfo next_incl;
821 for (next = stmt->next; next != NULL; next = next->next)
823 if ((next->file == NULL) && (next->map == NULL))
826 MergeIncludedSymbols(&included, info, next->merge, xkb);
827 FreeSymbolsInfo(info);
829 else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op))
831 InitSymbolsInfo(&next_incl, xkb);
832 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
833 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride;
836 next_incl.explicit_group = atoi(next->modifier) - 1;
840 next_incl.explicit_group = info->explicit_group;
842 (*hndlr) (rtrn, xkb, MergeOverride, &next_incl);
843 MergeIncludedSymbols(&included, &next_incl, op, xkb);
844 FreeSymbolsInfo(&next_incl);
848 info->errorCount += 10;
857 MergeIncludedSymbols(info, &included, newMerge, xkb);
858 FreeSymbolsInfo(&included);
860 return (info->errorCount == 0);
863 static LookupEntry groupNames[] = {
880 GetGroupIndex(KeyInfo * key,
881 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
891 if (arrayNdx == NULL)
896 defined = key->symsDefined;
898 defined = key->actsDefined;
900 for (i = 0; i < XkbNumKbdGroups; i++)
902 if ((defined & (1 << i)) == 0)
908 ERROR("Too many groups of %s for key %s (max %d)\n", name,
909 longText(key->name), XkbNumKbdGroups + 1);
910 ACTION("Ignoring %s defined for extra groups\n", name);
913 if (!ExprResolveInteger
914 (arrayNdx, &tmp, SimpleLookup, (char *) groupNames))
916 ERROR("Illegal group index for %s of key %s\n", name,
917 longText(key->name));
918 ACTION("Definition with non-integer array index ignored\n");
921 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
923 ERROR("Group index for %s of key %s is out of range (1..%d)\n",
924 name, longText(key->name), XkbNumKbdGroups + 1);
925 ACTION("Ignoring %s for group %d\n", name, tmp.uval);
928 *ndx_rtrn = tmp.uval - 1;
933 AddSymbolsToKey(KeyInfo * key,
936 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
941 if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx))
945 key->symsDefined |= (1 << ndx);
948 if (value->op != ExprKeysymList)
950 ERROR("Expected a list of symbols, found %s\n",
951 exprOpText(value->op));
952 ACTION("Ignoring symbols for group %d of %s\n", ndx,
953 longText(key->name));
956 if (key->syms[ndx] != NULL)
958 WSGO("Symbols for key %s, group %d already defined\n",
959 longText(key->name), ndx);
962 nSyms = value->value.list.nSyms;
963 if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
964 (!ResizeKeyGroup(key, ndx, nSyms, False)))
966 WSGO("Could not resize group %d of key %s\n", ndx,
967 longText(key->name));
968 ACTION("Symbols lost\n");
971 key->symsDefined |= (1 << ndx);
972 memcpy((char *) key->syms[ndx], (char *) value->value.list.syms,
973 nSyms * sizeof(KeySym));
974 for (i = key->numLevels[ndx] - 1;
975 (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--)
977 key->numLevels[ndx]--;
983 AddActionsToKey(KeyInfo * key,
986 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
993 if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx))
998 key->actsDefined |= (1 << ndx);
1001 if (value->op != ExprActionList)
1003 WSGO("Bad expression type (%d) for action list value\n", value->op);
1004 ACTION("Ignoring actions for group %d of %s\n", ndx,
1005 longText(key->name));
1008 if (key->acts[ndx] != NULL)
1010 WSGO("Actions for key %s, group %d already defined\n",
1011 longText(key->name), ndx);
1014 for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1016 act = (ExprDef *) act->common.next;
1020 WSGO("Action list but not actions in AddActionsToKey\n");
1023 if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1024 (!ResizeKeyGroup(key, ndx, nActs, True)))
1026 WSGO("Could not resize group %d of key %s\n", ndx,
1027 longText(key->name));
1028 ACTION("Actions lost\n");
1031 key->actsDefined |= (1 << ndx);
1033 toAct = (XkbAnyAction *) key->acts[ndx];
1034 act = value->value.child;
1035 for (i = 0; i < nActs; i++, toAct++)
1037 if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action))
1039 ERROR("Illegal action definition for %s\n",
1040 longText(key->name));
1041 ACTION("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1043 act = (ExprDef *) act->common.next;
1049 SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value)
1052 unsigned radio_groups = 0;
1054 if (arrayNdx == NULL)
1056 radio_groups = XkbAllRadioGroupsMask;
1060 if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL))
1062 ERROR("Illegal index in group name definition\n");
1063 ACTION("Definition with non-integer array index ignored\n");
1066 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1068 ERROR("Illegal radio group specified (must be 1..%d)\n",
1069 XkbMaxRadioGroups + 1);
1070 ACTION("Value of \"allow none\" for group %d ignored\n",
1074 radio_groups |= (1 << (tmp.uval - 1));
1076 if (!ExprResolveBoolean(value, &tmp, NULL, NULL))
1078 ERROR("Illegal \"allow none\" value for %s\n",
1079 longText(key->name));
1080 ACTION("Non-boolean value ignored\n");
1084 key->allowNone |= radio_groups;
1086 key->allowNone &= ~radio_groups;
1091 static LookupEntry lockingEntries[] = {
1092 {"true", XkbKB_Lock},
1093 {"yes", XkbKB_Lock},
1095 {"false", XkbKB_Default},
1096 {"no", XkbKB_Default},
1097 {"off", XkbKB_Default},
1098 {"permanent", XkbKB_Lock | XkbKB_Permanent},
1102 static LookupEntry repeatEntries[] = {
1103 {"true", RepeatYes},
1106 {"false", RepeatNo},
1109 {"default", RepeatUndefined},
1113 static LookupEntry rgEntries[] = {
1119 SetSymbolsField(KeyInfo * key,
1122 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1127 if (uStrCaseCmp(field, "type") == 0)
1130 if ((!ExprResolveString(value, &tmp, NULL, NULL))
1131 && (warningLevel > 0))
1133 WARN("The type field of a key symbol map must be a string\n");
1134 ACTION("Ignoring illegal type definition\n");
1136 if (arrayNdx == NULL)
1138 key->dfltType = XkbcInternAtom(tmp.str, False);
1139 key->defs.defined |= _Key_Type_Dflt;
1141 else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup,
1142 (char *) groupNames))
1144 ERROR("Illegal group index for type of key %s\n",
1145 longText(key->name));
1146 ACTION("Definition with non-integer array index ignored\n");
1150 else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups))
1153 ("Group index for type of key %s is out of range (1..%d)\n",
1154 longText(key->name), XkbNumKbdGroups + 1);
1155 ACTION("Ignoring type for group %d\n", ndx.uval);
1161 key->types[ndx.uval - 1] = XkbcInternAtom(tmp.str, False);
1162 key->typesDefined |= (1 << (ndx.uval - 1));
1166 else if (uStrCaseCmp(field, "symbols") == 0)
1167 return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1168 else if (uStrCaseCmp(field, "actions") == 0)
1169 return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1170 else if ((uStrCaseCmp(field, "vmods") == 0) ||
1171 (uStrCaseCmp(field, "virtualmods") == 0) ||
1172 (uStrCaseCmp(field, "virtualmodifiers") == 0))
1174 ok = ExprResolveModMask(value, &tmp, LookupVModMask, (char *) xkb);
1177 key->vmodmap = (tmp.uval >> 8);
1178 key->defs.defined |= _Key_VModMap;
1182 ERROR("Expected a virtual modifier mask, found %s\n",
1183 exprOpText(value->op));
1184 ACTION("Ignoring virtual modifiers definition for key %s\n",
1185 longText(key->name));
1188 else if ((uStrCaseCmp(field, "locking") == 0)
1189 || (uStrCaseCmp(field, "lock") == 0)
1190 || (uStrCaseCmp(field, "locks") == 0))
1192 ok = ExprResolveEnum(value, &tmp, lockingEntries);
1194 key->behavior.type = tmp.uval;
1195 key->defs.defined |= _Key_Behavior;
1197 else if ((uStrCaseCmp(field, "radiogroup") == 0) ||
1198 (uStrCaseCmp(field, "permanentradiogroup") == 0))
1200 Bool permanent = False;
1201 if (uStrCaseCmp(field, "permanentradiogroup") == 0)
1203 ok = ExprResolveInteger(value, &tmp, SimpleLookup,
1204 (char *) rgEntries);
1207 ERROR("Illegal radio group specification for %s\n",
1208 longText(key->name));
1209 ACTION("Non-integer radio group ignored\n");
1214 key->behavior.type = XkbKB_Default;
1215 key->behavior.data = 0;
1218 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1221 ("Radio group specification for %s out of range (1..32)\n",
1222 longText(key->name));
1223 ACTION("Illegal radio group %d ignored\n", tmp.uval);
1226 key->behavior.type =
1227 XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0);
1228 key->behavior.data = tmp.uval - 1;
1229 if (key->allowNone & (1 << (tmp.uval - 1)))
1230 key->behavior.data |= XkbKB_RGAllowNone;
1231 key->defs.defined |= _Key_Behavior;
1233 else if (uStrCaseEqual(field, "allownone"))
1235 ok = SetAllowNone(key, arrayNdx, value);
1237 else if (uStrCasePrefix("overlay", field) ||
1238 uStrCasePrefix("permanentoverlay", field))
1240 Bool permanent = False;
1243 if (uStrCasePrefix("permanent", field))
1246 which = &field[sizeof("permanentoverlay") - 1];
1250 which = &field[sizeof("overlay") - 1];
1252 if (sscanf(which, "%d", &overlayNdx) == 1)
1254 if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0))
1256 ERROR("Illegal overlay %d specified for %s\n",
1257 overlayNdx, longText(key->name));
1258 ACTION("Ignored\n");
1262 else if (*which == '\0')
1264 else if (warningLevel > 0)
1266 ERROR("Illegal overlay \"%s\" specified for %s\n",
1267 which, longText(key->name));
1268 ACTION("Ignored\n");
1271 ok = ExprResolveKeyName(value, &tmp, NULL, NULL);
1274 ERROR("Illegal overlay key specification for %s\n",
1275 longText(key->name));
1276 ACTION("Overlay key must be specified by name\n");
1279 if (overlayNdx == 1)
1280 key->behavior.type = XkbKB_Overlay1;
1282 key->behavior.type = XkbKB_Overlay2;
1284 key->behavior.type |= XkbKB_Permanent;
1286 key->behavior.data = 0;
1287 key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name);
1288 key->defs.defined |= _Key_Behavior;
1290 else if ((uStrCaseCmp(field, "repeating") == 0) ||
1291 (uStrCaseCmp(field, "repeats") == 0) ||
1292 (uStrCaseCmp(field, "repeat") == 0))
1294 ok = ExprResolveEnum(value, &tmp, repeatEntries);
1297 ERROR("Illegal repeat setting for %s\n",
1298 longText(key->name));
1299 ACTION("Non-boolean repeat setting ignored\n");
1302 key->repeat = tmp.uval;
1303 key->defs.defined |= _Key_Repeat;
1305 else if ((uStrCaseCmp(field, "groupswrap") == 0) ||
1306 (uStrCaseCmp(field, "wrapgroups") == 0))
1308 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1311 ERROR("Illegal groupsWrap setting for %s\n",
1312 longText(key->name));
1313 ACTION("Non-boolean value ignored\n");
1317 key->groupInfo = XkbWrapIntoRange;
1319 key->groupInfo = XkbClampIntoRange;
1320 key->defs.defined |= _Key_GroupInfo;
1322 else if ((uStrCaseCmp(field, "groupsclamp") == 0) ||
1323 (uStrCaseCmp(field, "clampgroups") == 0))
1325 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1328 ERROR("Illegal groupsClamp setting for %s\n",
1329 longText(key->name));
1330 ACTION("Non-boolean value ignored\n");
1334 key->groupInfo = XkbClampIntoRange;
1336 key->groupInfo = XkbWrapIntoRange;
1337 key->defs.defined |= _Key_GroupInfo;
1339 else if ((uStrCaseCmp(field, "groupsredirect") == 0) ||
1340 (uStrCaseCmp(field, "redirectgroups") == 0))
1342 if (!ExprResolveInteger
1343 (value, &tmp, SimpleLookup, (char *) groupNames))
1345 ERROR("Illegal group index for redirect of key %s\n",
1346 longText(key->name));
1347 ACTION("Definition with non-integer group ignored\n");
1350 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1352 ERROR("Out-of-range (1..%d) group for redirect of key %s\n",
1353 XkbNumKbdGroups, longText(key->name));
1354 ERROR("Ignoring illegal group %d\n", tmp.uval);
1358 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1359 key->defs.defined |= _Key_GroupInfo;
1363 ERROR("Unknown field %s in a symbol interpretation\n", field);
1364 ACTION("Definition ignored\n");
1371 SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1373 ExprResult tmp, name;
1375 if ((arrayNdx == NULL) && (warningLevel > 0))
1377 WARN("You must specify an index when specifying a group name\n");
1378 ACTION("Group name definition without array subscript ignored\n");
1381 if (!ExprResolveInteger
1382 (arrayNdx, &tmp, SimpleLookup, (char *) groupNames))
1384 ERROR("Illegal index in group name definition\n");
1385 ACTION("Definition with non-integer array index ignored\n");
1388 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1391 ("Attempt to specify name for illegal group (must be 1..%d)\n",
1392 XkbNumKbdGroups + 1);
1393 ACTION("Name for group %d ignored\n", tmp.uval);
1396 if (!ExprResolveString(value, &name, NULL, NULL))
1398 ERROR("Group name must be a string\n");
1399 ACTION("Illegal name for group %d ignored\n", tmp.uval);
1402 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1403 XkbcInternAtom(name.str, False);
1409 HandleSymbolsVar(VarDef * stmt, XkbcDescPtr xkb, SymbolsInfo * info)
1411 ExprResult elem, field, tmp;
1415 if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1416 return 0; /* internal error, already reported */
1417 if (elem.str && (uStrCaseCmp(elem.str, "key") == 0))
1419 ret = SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1422 else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) ||
1423 (uStrCaseCmp(field.str, "groupname") ==
1426 ret = SetGroupName(info, arrayNdx, stmt->value);
1428 else if ((elem.str == NULL)
1429 && ((uStrCaseCmp(field.str, "groupswrap") == 0)
1430 || (uStrCaseCmp(field.str, "wrapgroups") == 0)))
1432 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1434 ERROR("Illegal setting for global groupsWrap\n");
1435 ACTION("Non-boolean value ignored\n");
1440 info->groupInfo = XkbWrapIntoRange;
1442 info->groupInfo = XkbClampIntoRange;
1446 else if ((elem.str == NULL)
1447 && ((uStrCaseCmp(field.str, "groupsclamp") == 0)
1448 || (uStrCaseCmp(field.str, "clampgroups") == 0)))
1450 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1452 ERROR("Illegal setting for global groupsClamp\n");
1453 ACTION("Non-boolean value ignored\n");
1458 info->groupInfo = XkbClampIntoRange;
1460 info->groupInfo = XkbWrapIntoRange;
1464 else if ((elem.str == NULL)
1465 && ((uStrCaseCmp(field.str, "groupsredirect") == 0)
1466 || (uStrCaseCmp(field.str, "redirectgroups") == 0)))
1468 if (!ExprResolveInteger(stmt->value, &tmp,
1469 SimpleLookup, (char *) groupNames))
1471 ERROR("Illegal group index for global groupsRedirect\n");
1472 ACTION("Definition with non-integer group ignored\n");
1476 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1479 ("Out-of-range (1..%d) group for global groupsRedirect\n",
1481 ACTION("Ignoring illegal group %d\n", tmp.uval);
1485 info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange,
1491 else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0))
1493 ret = SetAllowNone(&info->dflt, arrayNdx, stmt->value);
1496 ret = SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1506 HandleSymbolsBody(VarDef * def,
1507 XkbcDescPtr xkb, KeyInfo * key, SymbolsInfo * info)
1510 ExprResult tmp, field;
1513 for (; def != NULL; def = (VarDef *) def->common.next)
1515 if ((def->name) && (def->name->type == ExprFieldRef))
1517 ok = HandleSymbolsVar(def, xkb, info);
1522 if (def->name == NULL)
1524 if ((def->value == NULL)
1525 || (def->value->op == ExprKeysymList))
1526 field.str = "symbols";
1528 field.str = "actions";
1533 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1536 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1544 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1546 unsigned group = info->explicit_group;
1551 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1554 WARN("For the map %s an explicit group specified\n", info->name);
1555 WARN("but key %s has more than one group defined\n",
1556 longText(key->name));
1557 ACTION("All groups except first one will be ignored\n");
1558 for (i = 1; i < XkbNumKbdGroups; i++)
1560 key->numLevels[i] = 0;
1561 if (key->syms[i] != NULL)
1562 uFree(key->syms[i]);
1563 key->syms[i] = (KeySym *) NULL;
1564 if (key->acts[i] != NULL)
1565 uFree(key->acts[i]);
1566 key->acts[i] = (XkbcAction *) NULL;
1567 key->types[i] = (Atom) 0;
1570 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1572 key->numLevels[group] = key->numLevels[0];
1573 key->numLevels[0] = 0;
1574 key->syms[group] = key->syms[0];
1575 key->syms[0] = (KeySym *) NULL;
1576 key->acts[group] = key->acts[0];
1577 key->acts[0] = (XkbcAction *) NULL;
1578 key->types[group] = key->types[0];
1579 key->types[0] = (Atom) 0;
1584 HandleSymbolsDef(SymbolsDef * stmt,
1585 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1590 CopyKeyInfo(&info->dflt, &key, False);
1591 key.defs.merge = stmt->merge;
1592 key.name = KeyNameToLong(stmt->keyName);
1593 if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1599 if (!SetExplicitGroup(info, &key))
1605 if (!AddKeySymbols(info, &key, xkb))
1614 HandleModMapDef(ModMapDef * def,
1615 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1622 if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn))
1624 ERROR("Illegal modifier map definition\n");
1625 ACTION("Ignoring map for non-modifier \"%s\"\n",
1626 XkbcAtomText(def->modifier));
1630 tmp.modifier = rtrn.uval;
1631 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1633 if ((key->op == ExprValue) && (key->type == TypeKeyName))
1635 tmp.haveSymbol = False;
1636 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1638 else if (ExprResolveKeySym(key, &rtrn, NULL, NULL))
1640 tmp.haveSymbol = True;
1641 tmp.u.keySym = rtrn.uval;
1645 ERROR("Modmap entries may contain only key names or keysyms\n");
1646 ACTION("Illegal definition for %s modifier ignored\n",
1647 XkbcModIndexText(tmp.modifier));
1651 ok = AddModMapEntry(info, &tmp) && ok;
1657 HandleSymbolsFile(XkbFile * file,
1658 XkbcDescPtr xkb, unsigned merge, SymbolsInfo * info)
1662 info->name = _XkbDupString(file->name);
1666 switch (stmt->stmtType)
1669 if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1673 case StmtSymbolsDef:
1674 if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1678 if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1682 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1686 ERROR("Interpretation files may not include other types\n");
1687 ACTION("Ignoring definition of symbol interpretation\n");
1690 case StmtKeycodeDef:
1691 ERROR("Interpretation files may not include other types\n");
1692 ACTION("Ignoring definition of key name\n");
1696 if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1700 WSGO("Unexpected statement type %d in HandleSymbolsFile\n",
1705 if (info->errorCount > 10)
1708 ERROR("Too many errors\n");
1710 ACTION("Abandoning symbols file \"%s\"\n", file->topName);
1718 FindKeyForSymbol(XkbcDescPtr xkb, KeySym sym, unsigned int *kc_rtrn)
1721 register Bool gotOne;
1727 for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1729 if (j < (int) XkbKeyNumSyms(xkb, i))
1732 if ((XkbKeySym(xkb, i, j) == sym))
1746 * Find the given name in the xkb->map->types and return its index.
1748 * @param name The atom to search for.
1749 * @param type_rtrn Set to the index of the name if found.
1751 * @return True if found, False otherwise.
1754 FindNamedType(XkbcDescPtr xkb, Atom name, unsigned *type_rtrn)
1756 register unsigned n;
1758 if (xkb && xkb->map && xkb->map->types)
1760 for (n = 0; n < xkb->map->num_types; n++)
1762 if (xkb->map->types[n].name == (Atom) name)
1773 * Assign a type to the given sym and return the Atom for the type assigned.
1776 * - ONE_LEVEL for width 0/1
1777 * - ALPHABETIC for 2 shift levels, with lower/upercase
1778 * - KEYPAD for keypad keys.
1779 * - TWO_LEVEL for other 2 shift level keys.
1780 * and the same for four level keys.
1782 * @param width Number of sysms in syms.
1783 * @param syms The keysyms for the given key (must be size width).
1784 * @param typeNameRtrn Set to the Atom of the type name.
1786 * @returns True if a type could be found, False otherwise.
1789 FindAutomaticType(int width, KeySym * syms, Atom * typeNameRtrn,
1793 if ((width == 1) || (width == 0))
1795 *typeNameRtrn = XkbcInternAtom("ONE_LEVEL", False);
1798 else if (width == 2)
1800 if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1802 *typeNameRtrn = XkbcInternAtom("ALPHABETIC", False);
1804 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1806 *typeNameRtrn = XkbcInternAtom("KEYPAD", False);
1811 *typeNameRtrn = XkbcInternAtom("TWO_LEVEL", False);
1815 else if (width <= 4)
1817 if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1]))
1818 if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3]))
1820 XkbcInternAtom("FOUR_LEVEL_ALPHABETIC", False);
1822 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL_SEMIALPHABETIC",
1825 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1826 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL_KEYPAD", False);
1828 *typeNameRtrn = XkbcInternAtom("FOUR_LEVEL", False);
1829 /* XXX: why not set autoType here? */
1831 return ((width >= 0) && (width <= 4));
1835 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1836 * groups, and reduce to one group if all groups are identical anyway.
1839 PrepareKeyDef(KeyInfo * key)
1841 int i, j, width, defined, lastGroup;
1844 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1845 /* get highest group number */
1846 for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1848 if (defined & (1 << i))
1856 /* If there are empty groups between non-empty ones fill them with data */
1857 /* from the first group. */
1858 /* We can make a wrong assumption here. But leaving gaps is worse. */
1859 for (i = lastGroup; i > 0; i--)
1861 if (defined & (1 << i))
1863 width = key->numLevels[0];
1864 if (key->typesDefined & 1)
1866 for (j = 0; j < width; j++)
1868 key->types[i] = key->types[0];
1870 key->typesDefined |= 1 << i;
1872 if ((key->actsDefined & 1) && key->acts[0])
1874 key->acts[i] = uTypedCalloc(width, XkbcAction);
1875 if (key->acts[i] == NULL)
1877 memcpy((void *) key->acts[i], (void *) key->acts[0],
1878 width * sizeof(XkbcAction));
1879 key->actsDefined |= 1 << i;
1881 if ((key->symsDefined & 1) && key->syms[0])
1883 key->syms[i] = uTypedCalloc(width, KeySym);
1884 if (key->syms[i] == NULL)
1886 memcpy((void *) key->syms[i], (void *) key->syms[0],
1887 width * sizeof(KeySym));
1888 key->symsDefined |= 1 << i;
1892 key->numLevels[i] = key->numLevels[0];
1895 /* If all groups are completely identical remove them all */
1896 /* exept the first one. */
1898 for (i = lastGroup; i > 0; i--)
1900 if ((key->numLevels[i] != key->numLevels[0]) ||
1901 (key->types[i] != key->types[0]))
1906 if ((key->syms[i] != key->syms[0]) &&
1907 (key->syms[i] == NULL || key->syms[0] == NULL ||
1908 memcmp((void *) key->syms[i], (void *) key->syms[0],
1909 sizeof(KeySym) * key->numLevels[0])))
1914 if ((key->acts[i] != key->acts[0]) &&
1915 (key->acts[i] == NULL || key->acts[0] == NULL ||
1916 memcmp((void *) key->acts[i], (void *) key->acts[0],
1917 sizeof(XkbcAction) * key->numLevels[0])))
1925 for (i = lastGroup; i > 0; i--)
1927 key->numLevels[i] = 0;
1928 if (key->syms[i] != NULL)
1929 uFree(key->syms[i]);
1930 key->syms[i] = (KeySym *) NULL;
1931 if (key->acts[i] != NULL)
1932 uFree(key->acts[i]);
1933 key->acts[i] = (XkbcAction *) NULL;
1934 key->types[i] = (Atom) 0;
1936 key->symsDefined &= 1;
1937 key->actsDefined &= 1;
1938 key->typesDefined &= 1;
1944 * Copy the KeyInfo into the keyboard description.
1946 * This function recurses.
1949 CopySymbolsDef(XkbcDescPtr xkb, KeyInfo *key, int start_from)
1952 unsigned okc, kc, width, tmp, nGroups;
1954 Bool haveActions, autoType, useAlias;
1956 XkbcAction *outActs;
1957 unsigned types[XkbNumKbdGroups];
1959 useAlias = (start_from == 0);
1961 /* get the keycode for the key. */
1962 if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1965 if ((start_from == 0) && (warningLevel >= 5))
1967 WARN("Key %s not found in %s keycodes\n",
1968 longText(key->name),
1969 XkbcAtomText(xkb->names->keycodes));
1970 ACTION("Symbols ignored\n");
1975 haveActions = False;
1976 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1978 if (((i + 1) > nGroups)
1979 && (((key->symsDefined | key->actsDefined) & (1 << i))
1980 || (key->typesDefined) & (1 << i)))
1985 /* Assign the type to the key, if it is missing. */
1986 if (key->types[i] == None)
1988 if (key->dfltType != None)
1989 key->types[i] = key->dfltType;
1990 else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1991 &key->types[i], &autoType))
1996 if (warningLevel >= 5)
1998 WARN("No automatic type for %d symbols\n",
1999 (unsigned int) key->numLevels[i]);
2000 ACTION("Using %s for the %s key (keycode %d)\n",
2001 XkbcAtomText(key->types[i]),
2002 longText(key->name), kc);
2006 if (FindNamedType(xkb, key->types[i], &types[i]))
2008 if (!autoType || key->numLevels[i] > 2)
2009 xkb->server->explicit[kc] |= (1 << i);
2013 if (warningLevel >= 3)
2015 WARN("Type \"%s\" is not defined\n",
2016 XkbcAtomText(key->types[i]));
2017 ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n",
2018 longText(key->name), kc);
2020 types[i] = XkbTwoLevelIndex;
2022 /* if the type specifies less syms than the key has, shrink the key */
2023 type = &xkb->map->types[types[i]];
2024 if (type->num_levels < key->numLevels[i])
2026 if (warningLevel > 0)
2029 ("Type \"%s\" has %d levels, but %s has %d symbols\n",
2030 XkbcAtomText(type->name),
2031 (unsigned int) type->num_levels,
2032 longText(key->name),
2033 (unsigned int) key->numLevels[i]);
2034 ACTION("Ignoring extra symbols\n");
2036 key->numLevels[i] = type->num_levels;
2038 if (key->numLevels[i] > width)
2039 width = key->numLevels[i];
2040 if (type->num_levels > width)
2041 width = type->num_levels;
2044 /* width is now the largest width found */
2046 i = width * nGroups;
2047 outSyms = XkbcResizeKeySyms(xkb, kc, i);
2048 if (outSyms == NULL)
2050 WSGO("Could not enlarge symbols for %s (keycode %d)\n",
2051 longText(key->name), kc);
2056 outActs = XkbcResizeKeyActions(xkb, kc, i);
2057 if (outActs == NULL)
2059 WSGO("Could not enlarge actions for %s (key %d)\n",
2060 longText(key->name), kc);
2063 xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
2067 if (key->defs.defined & _Key_GroupInfo)
2070 i = xkb->map->key_sym_map[kc].group_info;
2072 xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2073 xkb->map->key_sym_map[kc].width = width;
2074 for (i = 0; i < nGroups; i++)
2076 /* assign kt_index[i] to the index of the type in map->types.
2077 * kt_index[i] may have been set by a previous run (if we have two
2078 * layouts specified). Let's not overwrite it with the ONE_LEVEL
2079 * default group if we dont even have keys for this group anyway.
2081 * FIXME: There should be a better fix for this.
2083 if (key->numLevels[i])
2084 xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2085 if (key->syms[i] != NULL)
2087 /* fill key to "width" symbols*/
2088 for (tmp = 0; tmp < width; tmp++)
2090 if (tmp < key->numLevels[i])
2091 outSyms[tmp] = key->syms[i][tmp];
2093 outSyms[tmp] = NoSymbol;
2094 if ((outActs != NULL) && (key->acts[i] != NULL))
2096 if (tmp < key->numLevels[i])
2097 outActs[tmp] = key->acts[i][tmp];
2099 outActs[tmp].type = XkbSA_NoAction;
2107 switch (key->behavior.type & XkbKB_OpMask)
2111 case XkbKB_Overlay1:
2112 case XkbKB_Overlay2:
2113 /* find key by name! */
2114 if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True,
2115 CreateKeyNames(xkb), 0))
2117 if (warningLevel >= 1)
2119 WARN("Key %s not found in %s keycodes\n",
2120 longText(key->nameForOverlayKey),
2121 XkbcAtomText(xkb->names->keycodes));
2122 ACTION("Not treating %s as an overlay key \n",
2123 longText(key->name));
2127 key->behavior.data = okc;
2129 xkb->server->behaviors[kc] = key->behavior;
2130 xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2133 if (key->defs.defined & _Key_VModMap)
2135 xkb->server->vmodmap[kc] = key->vmodmap;
2136 xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2138 if (key->repeat != RepeatUndefined)
2140 if (key->repeat == RepeatYes)
2141 xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2143 xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2144 xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2147 /* do the same thing for the next key */
2148 CopySymbolsDef(xkb, key, kc + 1);
2153 CopyModMapDef(XkbcDescPtr xkb, ModMapEntry *entry)
2157 if ((!entry->haveSymbol)
2160 (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
2162 if (warningLevel >= 5)
2164 WARN("Key %s not found in %s keycodes\n",
2165 longText(entry->u.keyName),
2166 XkbcAtomText(xkb->names->keycodes));
2167 ACTION("Modifier map entry for %s not updated\n",
2168 XkbcModIndexText(entry->modifier));
2172 else if (entry->haveSymbol
2173 && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2175 if (warningLevel > 5)
2177 WARN("Key \"%s\" not found in %s symbol map\n",
2178 XkbcKeysymText(entry->u.keySym),
2179 XkbcAtomText(xkb->names->symbols));
2180 ACTION("Modifier map entry for %s not updated\n",
2181 XkbcModIndexText(entry->modifier));
2185 xkb->map->modmap[kc] |= (1 << entry->modifier);
2190 * Handle the xkb_symbols section of an xkb file.
2192 * @param file The parsed xkb_symbols section of the xkb file.
2193 * @param xkb Handle to the keyboard description to store the symbols in.
2194 * @param merge Merge strategy (e.g. MergeOverride).
2197 CompileSymbols(XkbFile *file, XkbcDescPtr xkb, unsigned merge)
2202 InitSymbolsInfo(&info, xkb);
2203 info.dflt.defs.fileID = file->id;
2204 info.dflt.defs.merge = merge;
2205 HandleSymbolsFile(file, xkb, merge, &info);
2207 if (info.nKeys == 0)
2209 if (info.errorCount == 0)
2213 /* alloc memory in the xkb struct */
2214 if (XkbcAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0)
2217 WSGO("Can not allocate names in CompileSymbols\n");
2218 ACTION("Symbols not added\n");
2221 if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2224 WSGO("Could not allocate client map in CompileSymbols\n");
2225 ACTION("Symbols not added\n");
2228 if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2230 WSGO("Could not allocate server map in CompileSymbols\n");
2231 ACTION("Symbols not added\n");
2234 if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2236 WSGO("Could not allocate controls in CompileSymbols\n");
2237 ACTION("Symbols not added\n");
2241 /* now copy info into xkb. */
2242 xkb->names->symbols = XkbcInternAtom(info.name, False);
2244 ApplyAliases(xkb, False, &info.aliases);
2245 for (i = 0; i < XkbNumKbdGroups; i++)
2247 if (info.groupNames[i] != None)
2248 xkb->names->groups[i] = info.groupNames[i];
2251 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2256 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2258 if (!CopySymbolsDef(xkb, key, 0))
2261 if (warningLevel > 3)
2263 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2265 if (xkb->names->keys[i].name[0] == '\0')
2267 if (XkbKeyNumGroups(xkb, i) < 1)
2270 memcpy(buf, xkb->names->keys[i].name, 4);
2273 ("No symbols defined for <%s> (keycode %d)\n",
2280 ModMapEntry *mm, *next;
2281 for (mm = info.modMap; mm != NULL; mm = next)
2283 if (!CopyModMapDef(xkb, mm))
2285 next = (ModMapEntry *) mm->defs.next;