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 ********************************************************/
30 #include "parseutils.h"
32 #include <X11/keysym.h>
33 #include <X11/Xutil.h>
43 extern Atom tok_ONE_LEVEL;
44 extern Atom tok_TWO_LEVEL;
45 extern Atom tok_KEYPAD;
47 /***====================================================================***/
51 #define RepeatUndefined ~((unsigned)0)
53 #define _Key_Syms (1<<0)
54 #define _Key_Acts (1<<1)
55 #define _Key_Repeat (1<<2)
56 #define _Key_Behavior (1<<3)
57 #define _Key_Type_Dflt (1<<4)
58 #define _Key_Types (1<<5)
59 #define _Key_GroupInfo (1<<6)
60 #define _Key_VModMap (1<<7)
62 typedef struct _KeyInfo
65 unsigned long name; /* the 4 chars of the key name, as long */
66 unsigned char groupInfo;
67 unsigned char typesDefined;
68 unsigned char symsDefined;
69 unsigned char actsDefined;
70 short numLevels[XkbNumKbdGroups];
71 KeySym *syms[XkbNumKbdGroups];
72 XkbAction *acts[XkbNumKbdGroups];
73 Atom types[XkbNumKbdGroups];
76 unsigned short vmodmap;
77 unsigned long nameForOverlayKey;
78 unsigned long allowNone;
83 * Init the given key info to sane values.
86 InitKeyInfo(KeyInfo * info)
89 static char dflt[4] = "*";
91 info->defs.defined = 0;
92 info->defs.fileID = 0;
93 info->defs.merge = MergeOverride;
94 info->defs.next = NULL;
95 info->name = KeyNameToLong(dflt);
97 info->typesDefined = info->symsDefined = info->actsDefined = 0;
98 for (i = 0; i < XkbNumKbdGroups; i++)
100 info->numLevels[i] = 0;
101 info->types[i] = None;
102 info->syms[i] = NULL;
103 info->acts[i] = NULL;
105 info->dfltType = None;
106 info->behavior.type = XkbKB_Default;
107 info->behavior.data = 0;
109 info->nameForOverlayKey = 0;
110 info->repeat = RepeatUndefined;
116 * Free memory associated with this key info and reset to sane values.
119 FreeKeyInfo(KeyInfo * info)
123 info->defs.defined = 0;
124 info->defs.fileID = 0;
125 info->defs.merge = MergeOverride;
126 info->defs.next = NULL;
128 info->typesDefined = info->symsDefined = info->actsDefined = 0;
129 for (i = 0; i < XkbNumKbdGroups; i++)
131 info->numLevels[i] = 0;
132 info->types[i] = None;
133 if (info->syms[i] != NULL)
134 uFree(info->syms[i]);
135 info->syms[i] = NULL;
136 if (info->acts[i] != NULL)
137 uFree(info->acts[i]);
138 info->acts[i] = NULL;
140 info->dfltType = None;
141 info->behavior.type = XkbKB_Default;
142 info->behavior.data = 0;
144 info->nameForOverlayKey = 0;
145 info->repeat = RepeatUndefined;
151 * Copy old into new, optionally reset old to 0.
152 * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
153 * newly allocated and new points to the new memory areas.
156 CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld)
161 new->defs.next = NULL;
164 for (i = 0; i < XkbNumKbdGroups; i++)
166 old->numLevels[i] = 0;
174 for (i = 0; i < XkbNumKbdGroups; i++)
176 width = new->numLevels[i];
177 if (old->syms[i] != NULL)
179 new->syms[i] = uTypedCalloc(width, KeySym);
183 new->numLevels[i] = 0;
186 memcpy((char *) new->syms[i], (char *) old->syms[i],
187 width * sizeof(KeySym));
189 if (old->acts[i] != NULL)
191 new->acts[i] = uTypedCalloc(width, XkbAction);
197 memcpy((char *) new->acts[i], (char *) old->acts[i],
198 width * sizeof(XkbAction));
205 /***====================================================================***/
207 typedef struct _ModMapEntry
214 unsigned long keyName;
219 #define SYMBOLS_INIT_SIZE 110
220 #define SYMBOLS_CHUNK 20
221 typedef struct _SymbolsInfo
223 char *name; /* e.g. pc+us+inet(evdev) */
227 unsigned explicit_group;
235 Atom groupNames[XkbNumKbdGroups];
242 InitSymbolsInfo(SymbolsInfo * info, XkbDescPtr xkb)
246 tok_ONE_LEVEL = XkbInternAtom(NULL, "ONE_LEVEL", False);
247 tok_TWO_LEVEL = XkbInternAtom(NULL, "TWO_LEVEL", False);
248 tok_KEYPAD = XkbInternAtom(NULL, "KEYPAD", False);
250 info->explicit_group = 0;
251 info->errorCount = 0;
253 info->merge = MergeOverride;
255 info->szKeys = SYMBOLS_INIT_SIZE;
257 info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo);
259 for (i = 0; i < XkbNumKbdGroups; i++)
260 info->groupNames[i] = None;
261 InitKeyInfo(&info->dflt);
262 InitVModInfo(&info->vmods, xkb);
264 info->aliases = NULL;
269 FreeSymbolsInfo(SymbolsInfo * info)
278 for (i = 0; i < info->nKeys; i++)
280 FreeKeyInfo(&info->keys[i]);
287 ClearCommonInfo(&info->modMap->defs);
292 ClearAliases(&info->aliases);
293 info->aliases = NULL;
295 bzero((char *) info, sizeof(SymbolsInfo));
300 ResizeKeyGroup(KeyInfo * key,
301 unsigned group, unsigned atLeastSize, Bool forceActions)
306 tooSmall = (key->numLevels[group] < atLeastSize);
308 newWidth = atLeastSize;
310 newWidth = key->numLevels[group];
312 if ((key->syms[group] == NULL) || tooSmall)
314 key->syms[group] = uTypedRecalloc(key->syms[group],
315 key->numLevels[group], newWidth,
317 if (!key->syms[group])
320 if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) ||
321 (tooSmall && (key->acts[group] != NULL)))
323 key->acts[group] = uTypedRecalloc(key->acts[group],
324 key->numLevels[group], newWidth,
326 if (!key->acts[group])
329 key->numLevels[group] = newWidth;
334 MergeKeyGroups(SymbolsInfo * info,
335 KeyInfo * into, KeyInfo * from, unsigned group)
338 XkbAction *resultActs;
341 Bool report, clobber;
343 clobber = (from->defs.merge != MergeAugment);
344 report = (warningLevel > 9) ||
345 ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
346 if (into->numLevels[group] >= from->numLevels[group])
348 resultSyms = into->syms[group];
349 resultActs = into->acts[group];
350 resultWidth = into->numLevels[group];
354 resultSyms = from->syms[group];
355 resultActs = from->acts[group];
356 resultWidth = from->numLevels[group];
358 if (resultSyms == NULL)
360 resultSyms = uTypedCalloc(resultWidth, KeySym);
363 WSGO("Could not allocate symbols for group merge\n");
364 ACTION2("Group %d of key %s not merged\n", group,
365 longText(into->name, XkbMessage));
369 if ((resultActs == NULL) && (into->acts[group] || from->acts[group]))
371 resultActs = uTypedCalloc(resultWidth, XkbAction);
374 WSGO("Could not allocate actions for group merge\n");
375 ACTION2("Group %d of key %s not merged\n", group,
376 longText(into->name, XkbMessage));
380 for (i = 0; i < resultWidth; i++)
382 KeySym fromSym, toSym;
383 if (from->syms[group] && (i < from->numLevels[group]))
384 fromSym = from->syms[group][i];
387 if (into->syms[group] && (i < into->numLevels[group]))
388 toSym = into->syms[group][i];
391 if ((fromSym == NoSymbol) || (fromSym == toSym))
392 resultSyms[i] = toSym;
393 else if (toSym == NoSymbol)
394 resultSyms[i] = fromSym;
411 ("Multiple symbols for level %d/group %d on key %s\n",
412 i + 1, group + 1, longText(into->name, XkbMessage));
413 ACTION2("Using %s, ignoring %s\n",
414 XkbKeysymText(use, XkbMessage),
415 XkbKeysymText(ignore, XkbMessage));
419 if (resultActs != NULL)
421 XkbAction *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 XkbAction *use, *ignore;
450 ("Multiple actions for level %d/group %d on key %s\n",
451 i + 1, group + 1, longText(into->name, XkbMessage));
452 ACTION2("Using %s, ignoring %s\n",
453 XkbActionTypeText(use->type, XkbMessage),
454 XkbActionTypeText(ignore->type, XkbMessage));
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, XkbMessage));
557 ACTION2("Using %s, ignoring %s\n",
558 XkbAtomText(NULL, use, XkbMessage),
559 XkbAtomText(NULL, ignore, XkbMessage));
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 WARN1("Symbol map for key %s redefined\n",
597 longText(into->name, XkbMessage));
598 ACTION1("Using %s definition for conflicting fields\n",
599 (from->defs.merge == MergeAugment ? "first" : "last"));
605 AddKeySymbols(SymbolsInfo * info, KeyInfo * key, XkbDescPtr 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 XkbKeysymText(new->u.keySym, XkbMessage));
666 ACTION2("Using %s, ignoring %s.\n",
667 XkbModIndexText(use, XkbMessage),
668 XkbModIndexText(ignore, XkbMessage));
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 ERROR1("Key %s added to map for multiple modifiers\n",
690 longText(new->u.keyName, XkbMessage));
691 ACTION2("Using %s, ignoring %s.\n",
692 XkbModIndexText(use, XkbMessage),
693 XkbModIndexText(ignore, XkbMessage));
699 mm = uTypedAlloc(ModMapEntry);
702 WSGO("Could not allocate modifier map entry\n");
703 ACTION1("Modifier map for %s will be incomplete\n",
704 XkbModIndexText(new->modifier, XkbMessage));
708 mm->defs.next = &info->modMap->defs;
713 /***====================================================================***/
716 MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from,
717 unsigned merge, XkbDescPtr 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 XkbDescPtr /* xkb */ ,
768 unsigned /* merge */ ,
769 SymbolsInfo * /* included */
773 HandleIncludeSymbols(IncludeStmt * stmt,
774 XkbDescPtr 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 ERROR3("Too many groups of %s for key %s (max %d)\n", name,
909 longText(key->name, XkbMessage), XkbNumKbdGroups + 1);
910 ACTION1("Ignoring %s defined for extra groups\n", name);
913 if (!ExprResolveInteger
914 (arrayNdx, &tmp, SimpleLookup, (XPointer) groupNames))
916 ERROR2("Illegal group index for %s of key %s\n", name,
917 longText(key->name, XkbMessage));
918 ACTION("Definition with non-integer array index ignored\n");
921 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
923 ERROR3("Group index for %s of key %s is out of range (1..%d)\n",
924 name, longText(key->name, XkbMessage), XkbNumKbdGroups + 1);
925 ACTION2("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 ERROR1("Expected a list of symbols, found %s\n",
951 exprOpText(value->op));
952 ACTION2("Ignoring symbols for group %d of %s\n", ndx,
953 longText(key->name, XkbMessage));
956 if (key->syms[ndx] != NULL)
958 WSGO2("Symbols for key %s, group %d already defined\n",
959 longText(key->name, XkbMessage), ndx);
962 nSyms = value->value.list.nSyms;
963 if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) &&
964 (!ResizeKeyGroup(key, ndx, nSyms, False)))
966 WSGO2("Could not resize group %d of key %s\n", ndx,
967 longText(key->name, XkbMessage));
968 ACTION("Symbols lost\n");
971 key->symsDefined |= (1 << ndx);
972 for (i = 0; i < nSyms; i++) {
973 if (!LookupKeysym(value->value.list.syms[i], &key->syms[ndx][i])) {
974 WSGO1("Could not resolve keysym %s\n", value->value.list.syms[i]);
975 key->syms[ndx][i] = NoSymbol;
978 for (i = key->numLevels[ndx] - 1;
979 (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--)
981 key->numLevels[ndx]--;
987 AddActionsToKey(KeyInfo * key,
990 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
997 if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx))
1002 key->actsDefined |= (1 << ndx);
1005 if (value->op != ExprActionList)
1007 WSGO1("Bad expression type (%d) for action list value\n", value->op);
1008 ACTION2("Ignoring actions for group %d of %s\n", ndx,
1009 longText(key->name, XkbMessage));
1012 if (key->acts[ndx] != NULL)
1014 WSGO2("Actions for key %s, group %d already defined\n",
1015 longText(key->name, XkbMessage), ndx);
1018 for (nActs = 0, act = value->value.child; act != NULL; nActs++)
1020 act = (ExprDef *) act->common.next;
1024 WSGO("Action list but not actions in AddActionsToKey\n");
1027 if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) &&
1028 (!ResizeKeyGroup(key, ndx, nActs, True)))
1030 WSGO2("Could not resize group %d of key %s\n", ndx,
1031 longText(key->name, XkbMessage));
1032 ACTION("Actions lost\n");
1035 key->actsDefined |= (1 << ndx);
1037 toAct = (XkbAnyAction *) key->acts[ndx];
1038 act = value->value.child;
1039 for (i = 0; i < nActs; i++, toAct++)
1041 if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action))
1043 ERROR1("Illegal action definition for %s\n",
1044 longText(key->name, XkbMessage));
1045 ACTION2("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1047 act = (ExprDef *) act->common.next;
1053 SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value)
1056 unsigned radio_groups = 0;
1058 if (arrayNdx == NULL)
1060 radio_groups = XkbAllRadioGroupsMask;
1064 if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL))
1066 ERROR("Illegal index in group name definition\n");
1067 ACTION("Definition with non-integer array index ignored\n");
1070 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1072 ERROR1("Illegal radio group specified (must be 1..%d)\n",
1073 XkbMaxRadioGroups + 1);
1074 ACTION1("Value of \"allow none\" for group %d ignored\n",
1078 radio_groups |= (1 << (tmp.uval - 1));
1080 if (!ExprResolveBoolean(value, &tmp, NULL, NULL))
1082 ERROR1("Illegal \"allow none\" value for %s\n",
1083 longText(key->name, XkbMessage));
1084 ACTION("Non-boolean value ignored\n");
1088 key->allowNone |= radio_groups;
1090 key->allowNone &= ~radio_groups;
1095 static LookupEntry lockingEntries[] = {
1096 {"true", XkbKB_Lock},
1097 {"yes", XkbKB_Lock},
1099 {"false", XkbKB_Default},
1100 {"no", XkbKB_Default},
1101 {"off", XkbKB_Default},
1102 {"permanent", XkbKB_Lock | XkbKB_Permanent},
1106 static LookupEntry repeatEntries[] = {
1107 {"true", RepeatYes},
1110 {"false", RepeatNo},
1113 {"default", RepeatUndefined},
1117 static LookupEntry rgEntries[] = {
1123 SetSymbolsField(KeyInfo * key,
1126 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1131 if (uStrCaseCmp(field, "type") == 0)
1134 if ((!ExprResolveString(value, &tmp, NULL, NULL))
1135 && (warningLevel > 0))
1137 WARN("The type field of a key symbol map must be a string\n");
1138 ACTION("Ignoring illegal type definition\n");
1140 if (arrayNdx == NULL)
1142 key->dfltType = XkbInternAtom(NULL, tmp.str, False);
1143 key->defs.defined |= _Key_Type_Dflt;
1145 else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup,
1146 (XPointer) groupNames))
1148 ERROR1("Illegal group index for type of key %s\n",
1149 longText(key->name, XkbMessage));
1150 ACTION("Definition with non-integer array index ignored\n");
1153 else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups))
1156 ("Group index for type of key %s is out of range (1..%d)\n",
1157 longText(key->name, XkbMessage), XkbNumKbdGroups + 1);
1158 ACTION1("Ignoring type for group %d\n", ndx.uval);
1163 key->types[ndx.uval - 1] = XkbInternAtom(NULL, tmp.str, False);
1164 key->typesDefined |= (1 << (ndx.uval - 1));
1167 else if (uStrCaseCmp(field, "symbols") == 0)
1168 return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1169 else if (uStrCaseCmp(field, "actions") == 0)
1170 return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1171 else if ((uStrCaseCmp(field, "vmods") == 0) ||
1172 (uStrCaseCmp(field, "virtualmods") == 0) ||
1173 (uStrCaseCmp(field, "virtualmodifiers") == 0))
1175 ok = ExprResolveModMask(value, &tmp, LookupVModMask, (XPointer) xkb);
1178 key->vmodmap = (tmp.uval >> 8);
1179 key->defs.defined |= _Key_VModMap;
1183 ERROR1("Expected a virtual modifier mask, found %s\n",
1184 exprOpText(value->op));
1185 ACTION1("Ignoring virtual modifiers definition for key %s\n",
1186 longText(key->name, XkbMessage));
1189 else if ((uStrCaseCmp(field, "locking") == 0)
1190 || (uStrCaseCmp(field, "lock") == 0)
1191 || (uStrCaseCmp(field, "locks") == 0))
1193 ok = ExprResolveEnum(value, &tmp, lockingEntries);
1195 key->behavior.type = tmp.uval;
1196 key->defs.defined |= _Key_Behavior;
1198 else if ((uStrCaseCmp(field, "radiogroup") == 0) ||
1199 (uStrCaseCmp(field, "permanentradiogroup") == 0))
1201 Bool permanent = False;
1202 if (uStrCaseCmp(field, "permanentradiogroup") == 0)
1204 ok = ExprResolveInteger(value, &tmp, SimpleLookup,
1205 (XPointer) rgEntries);
1208 ERROR1("Illegal radio group specification for %s\n",
1209 longText(key->name, XkbMessage));
1210 ACTION("Non-integer radio group ignored\n");
1215 key->behavior.type = XkbKB_Default;
1216 key->behavior.data = 0;
1219 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups))
1222 ("Radio group specification for %s out of range (1..32)\n",
1223 longText(key->name, XkbMessage));
1224 ACTION1("Illegal radio group %d ignored\n", tmp.uval);
1227 key->behavior.type =
1228 XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0);
1229 key->behavior.data = tmp.uval - 1;
1230 if (key->allowNone & (1 << (tmp.uval - 1)))
1231 key->behavior.data |= XkbKB_RGAllowNone;
1232 key->defs.defined |= _Key_Behavior;
1234 else if (uStrCaseEqual(field, "allownone"))
1236 ok = SetAllowNone(key, arrayNdx, value);
1238 else if (uStrCasePrefix("overlay", field) ||
1239 uStrCasePrefix("permanentoverlay", field))
1241 Bool permanent = False;
1244 if (uStrCasePrefix("permanent", field))
1247 which = &field[sizeof("permanentoverlay") - 1];
1251 which = &field[sizeof("overlay") - 1];
1253 if (sscanf(which, "%d", &overlayNdx) == 1)
1255 if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0))
1257 ERROR2("Illegal overlay %d specified for %s\n",
1258 overlayNdx, longText(key->name, XkbMessage));
1259 ACTION("Ignored\n");
1263 else if (*which == '\0')
1265 else if (warningLevel > 0)
1267 ERROR2("Illegal overlay \"%s\" specified for %s\n",
1268 which, longText(key->name, XkbMessage));
1269 ACTION("Ignored\n");
1272 ok = ExprResolveKeyName(value, &tmp, NULL, NULL);
1275 ERROR1("Illegal overlay key specification for %s\n",
1276 longText(key->name, XkbMessage));
1277 ACTION("Overlay key must be specified by name\n");
1280 if (overlayNdx == 1)
1281 key->behavior.type = XkbKB_Overlay1;
1283 key->behavior.type = XkbKB_Overlay2;
1285 key->behavior.type |= XkbKB_Permanent;
1287 key->behavior.data = 0;
1288 key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name);
1289 key->defs.defined |= _Key_Behavior;
1291 else if ((uStrCaseCmp(field, "repeating") == 0) ||
1292 (uStrCaseCmp(field, "repeats") == 0) ||
1293 (uStrCaseCmp(field, "repeat") == 0))
1295 ok = ExprResolveEnum(value, &tmp, repeatEntries);
1298 ERROR1("Illegal repeat setting for %s\n",
1299 longText(key->name, XkbMessage));
1300 ACTION("Non-boolean repeat setting ignored\n");
1303 key->repeat = tmp.uval;
1304 key->defs.defined |= _Key_Repeat;
1306 else if ((uStrCaseCmp(field, "groupswrap") == 0) ||
1307 (uStrCaseCmp(field, "wrapgroups") == 0))
1309 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1312 ERROR1("Illegal groupsWrap setting for %s\n",
1313 longText(key->name, XkbMessage));
1314 ACTION("Non-boolean value ignored\n");
1318 key->groupInfo = XkbWrapIntoRange;
1320 key->groupInfo = XkbClampIntoRange;
1321 key->defs.defined |= _Key_GroupInfo;
1323 else if ((uStrCaseCmp(field, "groupsclamp") == 0) ||
1324 (uStrCaseCmp(field, "clampgroups") == 0))
1326 ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
1329 ERROR1("Illegal groupsClamp setting for %s\n",
1330 longText(key->name, XkbMessage));
1331 ACTION("Non-boolean value ignored\n");
1335 key->groupInfo = XkbClampIntoRange;
1337 key->groupInfo = XkbWrapIntoRange;
1338 key->defs.defined |= _Key_GroupInfo;
1340 else if ((uStrCaseCmp(field, "groupsredirect") == 0) ||
1341 (uStrCaseCmp(field, "redirectgroups") == 0))
1343 if (!ExprResolveInteger
1344 (value, &tmp, SimpleLookup, (XPointer) groupNames))
1346 ERROR1("Illegal group index for redirect of key %s\n",
1347 longText(key->name, XkbMessage));
1348 ACTION("Definition with non-integer group ignored\n");
1351 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1353 ERROR2("Out-of-range (1..%d) group for redirect of key %s\n",
1354 XkbNumKbdGroups, longText(key->name, XkbMessage));
1355 ERROR1("Ignoring illegal group %d\n", tmp.uval);
1359 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1);
1360 key->defs.defined |= _Key_GroupInfo;
1364 ERROR1("Unknown field %s in a symbol interpretation\n", field);
1365 ACTION("Definition ignored\n");
1372 SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1374 ExprResult tmp, name;
1376 if ((arrayNdx == NULL) && (warningLevel > 0))
1378 WARN("You must specify an index when specifying a group name\n");
1379 ACTION("Group name definition without array subscript ignored\n");
1382 if (!ExprResolveInteger
1383 (arrayNdx, &tmp, SimpleLookup, (XPointer) groupNames))
1385 ERROR("Illegal index in group name definition\n");
1386 ACTION("Definition with non-integer array index ignored\n");
1389 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1392 ("Attempt to specify name for illegal group (must be 1..%d)\n",
1393 XkbNumKbdGroups + 1);
1394 ACTION1("Name for group %d ignored\n", tmp.uval);
1397 if (!ExprResolveString(value, &name, NULL, NULL))
1399 ERROR("Group name must be a string\n");
1400 ACTION1("Illegal name for group %d ignored\n", tmp.uval);
1403 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1404 XkbInternAtom(NULL, name.str, False);
1410 HandleSymbolsVar(VarDef * stmt, XkbDescPtr xkb, SymbolsInfo * info)
1412 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 return SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1422 else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) ||
1423 (uStrCaseCmp(field.str, "groupname") ==
1426 return 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");
1439 info->groupInfo = XkbWrapIntoRange;
1441 info->groupInfo = XkbClampIntoRange;
1444 else if ((elem.str == NULL)
1445 && ((uStrCaseCmp(field.str, "groupsclamp") == 0)
1446 || (uStrCaseCmp(field.str, "clampgroups") == 0)))
1448 if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL))
1450 ERROR("Illegal setting for global groupsClamp\n");
1451 ACTION("Non-boolean value ignored\n");
1455 info->groupInfo = XkbClampIntoRange;
1457 info->groupInfo = XkbWrapIntoRange;
1460 else if ((elem.str == NULL)
1461 && ((uStrCaseCmp(field.str, "groupsredirect") == 0)
1462 || (uStrCaseCmp(field.str, "redirectgroups") == 0)))
1464 if (!ExprResolveInteger(stmt->value, &tmp,
1465 SimpleLookup, (XPointer) groupNames))
1467 ERROR("Illegal group index for global groupsRedirect\n");
1468 ACTION("Definition with non-integer group ignored\n");
1471 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups))
1474 ("Out-of-range (1..%d) group for global groupsRedirect\n",
1476 ACTION1("Ignoring illegal group %d\n", tmp.uval);
1479 info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval);
1482 else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0))
1484 return SetAllowNone(&info->dflt, arrayNdx, stmt->value);
1486 return SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1491 HandleSymbolsBody(VarDef * def,
1492 XkbDescPtr xkb, KeyInfo * key, SymbolsInfo * info)
1495 ExprResult tmp, field;
1498 for (; def != NULL; def = (VarDef *) def->common.next)
1500 if ((def->name) && (def->name->type == ExprFieldRef))
1502 ok = HandleSymbolsVar(def, xkb, info);
1507 if (def->name == NULL)
1509 if ((def->value == NULL)
1510 || (def->value->op == ExprKeysymList))
1511 field.str = "symbols";
1513 field.str = "actions";
1518 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1521 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1529 SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1531 unsigned group = info->explicit_group;
1536 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1539 WARN1("For the map %s an explicit group specified\n", info->name);
1540 WARN1("but key %s has more than one group defined\n",
1541 longText(key->name, XkbMessage));
1542 ACTION("All groups except first one will be ignored\n");
1543 for (i = 1; i < XkbNumKbdGroups; i++)
1545 key->numLevels[i] = 0;
1546 if (key->syms[i] != NULL)
1547 uFree(key->syms[i]);
1548 key->syms[i] = (KeySym *) NULL;
1549 if (key->acts[i] != NULL)
1550 uFree(key->acts[i]);
1551 key->acts[i] = (XkbAction *) NULL;
1552 key->types[i] = (Atom) 0;
1555 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1557 key->numLevels[group] = key->numLevels[0];
1558 key->numLevels[0] = 0;
1559 key->syms[group] = key->syms[0];
1560 key->syms[0] = (KeySym *) NULL;
1561 key->acts[group] = key->acts[0];
1562 key->acts[0] = (XkbAction *) NULL;
1563 key->types[group] = key->types[0];
1564 key->types[0] = (Atom) 0;
1569 HandleSymbolsDef(SymbolsDef * stmt,
1570 XkbDescPtr xkb, unsigned merge, SymbolsInfo * info)
1575 CopyKeyInfo(&info->dflt, &key, False);
1576 key.defs.merge = stmt->merge;
1577 key.name = KeyNameToLong(stmt->keyName);
1578 if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1584 if (!SetExplicitGroup(info, &key))
1590 if (!AddKeySymbols(info, &key, xkb))
1599 HandleModMapDef(ModMapDef * def,
1600 XkbDescPtr xkb, unsigned merge, SymbolsInfo * info)
1607 if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn))
1609 ERROR("Illegal modifier map definition\n");
1610 ACTION1("Ignoring map for non-modifier \"%s\"\n",
1611 XkbAtomText(NULL, def->modifier, XkbMessage));
1615 tmp.modifier = rtrn.uval;
1616 for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next)
1618 if ((key->op == ExprValue) && (key->type == TypeKeyName))
1620 tmp.haveSymbol = False;
1621 tmp.u.keyName = KeyNameToLong(key->value.keyName);
1623 else if (ExprResolveKeySym(key, &rtrn, NULL, NULL))
1625 tmp.haveSymbol = True;
1626 tmp.u.keySym = rtrn.uval;
1630 ERROR("Modmap entries may contain only key names or keysyms\n");
1631 ACTION1("Illegal definition for %s modifier ignored\n",
1632 XkbModIndexText(tmp.modifier, XkbMessage));
1636 ok = AddModMapEntry(info, &tmp) && ok;
1642 HandleSymbolsFile(XkbFile * file,
1643 XkbDescPtr xkb, unsigned merge, SymbolsInfo * info)
1647 info->name = uStringDup(file->name);
1651 switch (stmt->stmtType)
1654 if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1658 case StmtSymbolsDef:
1659 if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1663 if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1667 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1671 ERROR("Interpretation files may not include other types\n");
1672 ACTION("Ignoring definition of symbol interpretation\n");
1675 case StmtKeycodeDef:
1676 ERROR("Interpretation files may not include other types\n");
1677 ACTION("Ignoring definition of key name\n");
1681 if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1685 WSGO1("Unexpected statement type %d in HandleSymbolsFile\n",
1690 if (info->errorCount > 10)
1693 ERROR("Too many errors\n");
1695 ACTION1("Abandoning symbols file \"%s\"\n", file->topName);
1703 FindKeyForSymbol(XkbDescPtr xkb, KeySym sym, unsigned int *kc_rtrn)
1706 register Bool gotOne;
1712 for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1714 if (j < (int) XkbKeyNumSyms(xkb, i))
1717 if ((XkbKeySym(xkb, i, j) == sym))
1731 * Find the given name in the xkb->map->types and return its index.
1733 * @param name The atom to search for.
1734 * @param type_rtrn Set to the index of the name if found.
1736 * @return True if found, False otherwise.
1739 FindNamedType(XkbDescPtr xkb, Atom name, unsigned *type_rtrn)
1741 register unsigned n;
1743 if (xkb && xkb->map && xkb->map->types)
1745 for (n = 0; n < xkb->map->num_types; n++)
1747 if (xkb->map->types[n].name == (Atom) name)
1758 KSIsLower(KeySym ks)
1760 KeySym lower, upper;
1761 XConvertCase(ks, &lower, &upper);
1765 return (ks == lower ? True : False);
1769 KSIsUpper(KeySym ks)
1771 KeySym lower, upper;
1772 XConvertCase(ks, &lower, &upper);
1776 return (ks == upper ? True : False);
1780 * Assign a type to the given sym and return the Atom for the type assigned.
1783 * - ONE_LEVEL for width 0/1
1784 * - ALPHABETIC for 2 shift levels, with lower/upercase
1785 * - KEYPAD for keypad keys.
1786 * - TWO_LEVEL for other 2 shift level keys.
1787 * and the same for four level keys.
1789 * @param width Number of sysms in syms.
1790 * @param syms The keysyms for the given key (must be size width).
1791 * @param typeNameRtrn Set to the Atom of the type name.
1793 * @returns True if a type could be found, False otherwise.
1796 FindAutomaticType(int width, KeySym * syms, Atom * typeNameRtrn,
1800 if ((width == 1) || (width == 0))
1802 *typeNameRtrn = XkbInternAtom(NULL, "ONE_LEVEL", False);
1805 else if (width == 2)
1807 if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]))
1809 *typeNameRtrn = XkbInternAtom(NULL, "ALPHABETIC", False);
1811 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1813 *typeNameRtrn = XkbInternAtom(NULL, "KEYPAD", False);
1818 *typeNameRtrn = XkbInternAtom(NULL, "TWO_LEVEL", False);
1822 else if (width <= 4)
1824 if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]))
1825 if (KSIsLower(syms[2]) && KSIsUpper(syms[3]))
1827 XkbInternAtom(NULL, "FOUR_LEVEL_ALPHABETIC", False);
1829 *typeNameRtrn = XkbInternAtom(NULL,
1830 "FOUR_LEVEL_SEMIALPHABETIC",
1833 else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])))
1834 *typeNameRtrn = XkbInternAtom(NULL, "FOUR_LEVEL_KEYPAD", False);
1836 *typeNameRtrn = XkbInternAtom(NULL, "FOUR_LEVEL", False);
1837 /* XXX: why not set autoType here? */
1839 return ((width >= 0) && (width <= 4));
1843 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1844 * groups, and reduce to one group if all groups are identical anyway.
1847 PrepareKeyDef(KeyInfo * key)
1849 int i, j, width, defined, lastGroup;
1852 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1853 /* get highest group number */
1854 for (i = XkbNumKbdGroups - 1; i >= 0; i--)
1856 if (defined & (1 << i))
1864 /* If there are empty groups between non-empty ones fill them with data */
1865 /* from the first group. */
1866 /* We can make a wrong assumption here. But leaving gaps is worse. */
1867 for (i = lastGroup; i > 0; i--)
1869 if (defined & (1 << i))
1871 width = key->numLevels[0];
1872 if (key->typesDefined & 1)
1874 for (j = 0; j < width; j++)
1876 key->types[i] = key->types[0];
1878 key->typesDefined |= 1 << i;
1880 if ((key->actsDefined & 1) && key->acts[0])
1882 key->acts[i] = uTypedCalloc(width, XkbAction);
1883 if (key->acts[i] == NULL)
1885 memcpy((void *) key->acts[i], (void *) key->acts[0],
1886 width * sizeof(XkbAction));
1887 key->actsDefined |= 1 << i;
1889 if ((key->symsDefined & 1) && key->syms[0])
1891 key->syms[i] = uTypedCalloc(width, KeySym);
1892 if (key->syms[i] == NULL)
1894 memcpy((void *) key->syms[i], (void *) key->syms[0],
1895 width * sizeof(KeySym));
1896 key->symsDefined |= 1 << i;
1900 key->numLevels[i] = key->numLevels[0];
1903 /* If all groups are completely identical remove them all */
1904 /* exept the first one. */
1906 for (i = lastGroup; i > 0; i--)
1908 if ((key->numLevels[i] != key->numLevels[0]) ||
1909 (key->types[i] != key->types[0]))
1914 if ((key->syms[i] != key->syms[0]) &&
1915 (key->syms[i] == NULL || key->syms[0] == NULL ||
1916 memcmp((void *) key->syms[i], (void *) key->syms[0],
1917 sizeof(KeySym) * key->numLevels[0])))
1922 if ((key->acts[i] != key->acts[0]) &&
1923 (key->acts[i] == NULL || key->acts[0] == NULL ||
1924 memcmp((void *) key->acts[i], (void *) key->acts[0],
1925 sizeof(XkbAction) * key->numLevels[0])))
1933 for (i = lastGroup; i > 0; i--)
1935 key->numLevels[i] = 0;
1936 if (key->syms[i] != NULL)
1937 uFree(key->syms[i]);
1938 key->syms[i] = (KeySym *) NULL;
1939 if (key->acts[i] != NULL)
1940 uFree(key->acts[i]);
1941 key->acts[i] = (XkbAction *) NULL;
1942 key->types[i] = (Atom) 0;
1944 key->symsDefined &= 1;
1945 key->actsDefined &= 1;
1946 key->typesDefined &= 1;
1952 * Copy the KeyInfo into result.
1954 * This function recurses.
1957 CopySymbolsDef(XkbFileInfo * result, KeyInfo * key, int start_from)
1960 unsigned okc, kc, width, tmp, nGroups;
1962 Bool haveActions, autoType, useAlias;
1966 unsigned types[XkbNumKbdGroups];
1969 useAlias = (start_from == 0);
1971 /* get the keycode for the key. */
1972 if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb),
1975 if ((start_from == 0) && (warningLevel >= 5))
1977 WARN2("Key %s not found in %s keycodes\n",
1978 longText(key->name, XkbMessage),
1979 XkbAtomText(NULL, xkb->names->keycodes, XkbMessage));
1980 ACTION("Symbols ignored\n");
1985 haveActions = False;
1986 for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++)
1988 if (((i + 1) > nGroups)
1989 && (((key->symsDefined | key->actsDefined) & (1 << i))
1990 || (key->typesDefined) & (1 << i)))
1995 /* Assign the type to the key, if it is missing. */
1996 if (key->types[i] == None)
1998 if (key->dfltType != None)
1999 key->types[i] = key->dfltType;
2000 else if (FindAutomaticType(key->numLevels[i], key->syms[i],
2001 &key->types[i], &autoType))
2006 if (warningLevel >= 5)
2008 WARN1("No automatic type for %d symbols\n",
2009 (unsigned int) key->numLevels[i]);
2010 ACTION3("Using %s for the %s key (keycode %d)\n",
2011 XkbAtomText(NULL, key->types[i],
2013 longText(key->name, XkbMessage), kc);
2017 if (FindNamedType(xkb, key->types[i], &types[i]))
2019 if (!autoType || key->numLevels[i] > 2)
2020 xkb->server->explicit[kc] |= (1 << i);
2024 if (warningLevel >= 3)
2026 WARN1("Type \"%s\" is not defined\n",
2027 XkbAtomText(NULL, key->types[i], XkbMessage));
2028 ACTION2("Using TWO_LEVEL for the %s key (keycode %d)\n",
2029 longText(key->name, XkbMessage), kc);
2031 types[i] = XkbTwoLevelIndex;
2033 /* if the type specifies less syms than the key has, shrink the key */
2034 type = &xkb->map->types[types[i]];
2035 if (type->num_levels < key->numLevels[i])
2037 if (warningLevel > 0)
2040 ("Type \"%s\" has %d levels, but %s has %d symbols\n",
2041 XkbAtomText(NULL, type->name, XkbMessage),
2042 (unsigned int) type->num_levels,
2043 longText(key->name, XkbMessage),
2044 (unsigned int) key->numLevels[i]);
2045 ACTION("Ignoring extra symbols\n");
2047 key->numLevels[i] = type->num_levels;
2049 if (key->numLevels[i] > width)
2050 width = key->numLevels[i];
2051 if (type->num_levels > width)
2052 width = type->num_levels;
2055 /* width is now the largest width found */
2057 i = width * nGroups;
2058 outSyms = XkbResizeKeySyms(xkb, kc, i);
2059 if (outSyms == NULL)
2061 WSGO2("Could not enlarge symbols for %s (keycode %d)\n",
2062 longText(key->name, XkbMessage), kc);
2067 outActs = XkbResizeKeyActions(xkb, kc, i);
2068 if (outActs == NULL)
2070 WSGO2("Could not enlarge actions for %s (key %d)\n",
2071 longText(key->name, XkbMessage), kc);
2074 xkb->server->explicit[kc] |= XkbExplicitInterpretMask;
2078 if (key->defs.defined & _Key_GroupInfo)
2081 i = xkb->map->key_sym_map[kc].group_info;
2083 xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups);
2084 xkb->map->key_sym_map[kc].width = width;
2085 for (i = 0; i < nGroups; i++)
2087 /* assign kt_index[i] to the index of the type in map->types.
2088 * kt_index[i] may have been set by a previous run (if we have two
2089 * layouts specified). Let's not overwrite it with the ONE_LEVEL
2090 * default group if we dont even have keys for this group anyway.
2092 * FIXME: There should be a better fix for this.
2094 if (key->numLevels[i])
2095 xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2096 if (key->syms[i] != NULL)
2098 /* fill key to "width" symbols*/
2099 for (tmp = 0; tmp < width; tmp++)
2101 if (tmp < key->numLevels[i])
2102 outSyms[tmp] = key->syms[i][tmp];
2104 outSyms[tmp] = NoSymbol;
2105 if ((outActs != NULL) && (key->acts[i] != NULL))
2107 if (tmp < key->numLevels[i])
2108 outActs[tmp] = key->acts[i][tmp];
2110 outActs[tmp].type = XkbSA_NoAction;
2118 switch (key->behavior.type & XkbKB_OpMask)
2122 case XkbKB_Overlay1:
2123 case XkbKB_Overlay2:
2124 /* find key by name! */
2125 if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True,
2126 CreateKeyNames(xkb), 0))
2128 if (warningLevel >= 1)
2130 WARN2("Key %s not found in %s keycodes\n",
2131 longText(key->nameForOverlayKey, XkbMessage),
2132 XkbAtomText(NULL, xkb->names->keycodes, XkbMessage));
2133 ACTION1("Not treating %s as an overlay key \n",
2134 longText(key->name, XkbMessage));
2138 key->behavior.data = okc;
2140 xkb->server->behaviors[kc] = key->behavior;
2141 xkb->server->explicit[kc] |= XkbExplicitBehaviorMask;
2144 if (key->defs.defined & _Key_VModMap)
2146 xkb->server->vmodmap[kc] = key->vmodmap;
2147 xkb->server->explicit[kc] |= XkbExplicitVModMapMask;
2149 if (key->repeat != RepeatUndefined)
2151 if (key->repeat == RepeatYes)
2152 xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2154 xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2155 xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask;
2158 /* do the same thing for the next key */
2159 CopySymbolsDef(result, key, kc + 1);
2164 CopyModMapDef(XkbFileInfo * result, ModMapEntry * entry)
2170 if ((!entry->haveSymbol)
2173 (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0)))
2175 if (warningLevel >= 5)
2177 WARN2("Key %s not found in %s keycodes\n",
2178 longText(entry->u.keyName, XkbMessage),
2179 XkbAtomText(NULL, xkb->names->keycodes, XkbMessage));
2180 ACTION1("Modifier map entry for %s not updated\n",
2181 XkbModIndexText(entry->modifier, XkbMessage));
2185 else if (entry->haveSymbol
2186 && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2188 if (warningLevel > 5)
2190 WARN2("Key \"%s\" not found in %s symbol map\n",
2191 XkbKeysymText(entry->u.keySym, XkbMessage),
2192 XkbAtomText(NULL, xkb->names->symbols, XkbMessage));
2193 ACTION1("Modifier map entry for %s not updated\n",
2194 XkbModIndexText(entry->modifier, XkbMessage));
2198 xkb->map->modmap[kc] |= (1 << entry->modifier);
2203 * Handle the xkb_symbols section of an xkb file.
2205 * @param file The parsed xkb_symbols section of the xkb file.
2206 * @param result Handle to the data to store the result in.
2207 * @param merge Merge strategy (e.g. MergeOverride).
2210 CompileSymbols(XkbFile * file, XkbFileInfo * result, unsigned merge)
2217 InitSymbolsInfo(&info, xkb);
2218 info.dflt.defs.fileID = file->id;
2219 info.dflt.defs.merge = merge;
2220 HandleSymbolsFile(file, xkb, merge, &info);
2222 if (info.nKeys == 0)
2224 if (info.errorCount == 0)
2228 /* alloc memory in the xkb struct */
2229 if (XkbAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0)
2232 WSGO("Can not allocate names in CompileSymbols\n");
2233 ACTION("Symbols not added\n");
2236 if (XkbAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0)
2239 WSGO("Could not allocate client map in CompileSymbols\n");
2240 ACTION("Symbols not added\n");
2243 if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success)
2245 WSGO("Could not allocate server map in CompileSymbols\n");
2246 ACTION("Symbols not added\n");
2249 if (XkbAllocControls(xkb, XkbPerKeyRepeatMask) != Success)
2251 WSGO("Could not allocate controls in CompileSymbols\n");
2252 ACTION("Symbols not added\n");
2256 /* now copy info into xkb. */
2257 xkb->names->symbols = XkbInternAtom(xkb->dpy, info.name, False);
2259 ApplyAliases(xkb, False, &info.aliases);
2260 for (i = 0; i < XkbNumKbdGroups; i++)
2262 if (info.groupNames[i] != None)
2263 xkb->names->groups[i] = info.groupNames[i];
2266 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2271 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2273 if (!CopySymbolsDef(result, key, 0))
2276 if (warningLevel > 3)
2278 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2280 if (xkb->names->keys[i].name[0] == '\0')
2282 if (XkbKeyNumGroups(xkb, i) < 1)
2285 memcpy(buf, xkb->names->keys[i].name, 4);
2288 ("No symbols defined for <%s> (keycode %d)\n",
2295 ModMapEntry *mm, *next;
2296 for (mm = info.modMap; mm != NULL; mm = next)
2298 if (!CopyModMapDef(result, mm))
2300 next = (ModMapEntry *) mm->defs.next;