X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fxkbcomp%2Fsymbols.c;h=a61a52ba09a1a5b648bd9175ac245afbbd62c6b6;hb=cb631c2de040768478e50db1e606d23ab5286e73;hp=72bd020546f55cc9ebc36b25fa7b932f2389ee3e;hpb=4e22851141d89436c0659e68da57e91bbf971461;p=profile%2Fivi%2Flibxkbcommon.git diff --git a/src/xkbcomp/symbols.c b/src/xkbcomp/symbols.c index 72bd020..a61a52b 100644 --- a/src/xkbcomp/symbols.c +++ b/src/xkbcomp/symbols.c @@ -24,26 +24,12 @@ ********************************************************/ -#include "xkbcomp.h" -#include "xkballoc.h" -#include "xkbmisc.h" -#include "tokens.h" -#include "expr.h" +#include "xkbcomp-priv.h" #include "parseutils.h" - -#include -#include - -#include "expr.h" -#include "vmod.h" #include "action.h" -#include "keycodes.h" -#include "misc.h" #include "alias.h" - -extern uint32_t tok_ONE_LEVEL; -extern uint32_t tok_TWO_LEVEL; -extern uint32_t tok_KEYPAD; +#include "keycodes.h" +#include "vmod.h" /***====================================================================***/ @@ -68,16 +54,31 @@ typedef struct _KeyInfo unsigned char typesDefined; unsigned char symsDefined; unsigned char actsDefined; - short numLevels[XkbNumKbdGroups]; - uint32_t *syms[XkbNumKbdGroups]; + unsigned int numLevels[XkbNumKbdGroups]; + + /* syms[group] -> Single array for all the keysyms in the group. */ + xkb_keysym_t *syms[XkbNumKbdGroups]; + /* sizeSyms[group] -> The size of the syms[group] array. */ + int sizeSyms[XkbNumKbdGroups]; + /* + * symsMapIndex[group][level] -> The index from which the syms for + * the level begin in the syms[group] array. Remember each keycode + * can have multiple keysyms in each level (that is, each key press + * can result in multiple keysyms). + */ + int *symsMapIndex[XkbNumKbdGroups]; + /* + * symsMapNumEntries[group][level] -> How many syms are in + * syms[group][symsMapIndex[group][level]]. + */ + unsigned int *symsMapNumEntries[XkbNumKbdGroups]; + union xkb_action *acts[XkbNumKbdGroups]; - uint32_t types[XkbNumKbdGroups]; + xkb_atom_t types[XkbNumKbdGroups]; unsigned repeat; struct xkb_behavior behavior; unsigned short vmodmap; - unsigned long nameForOverlayKey; - unsigned long allowNone; - uint32_t dfltType; + xkb_atom_t dfltType; } KeyInfo; /** @@ -86,8 +87,8 @@ typedef struct _KeyInfo static void InitKeyInfo(KeyInfo * info) { - register int i; - static char dflt[4] = "*"; + int i; + static const char dflt[4] = "*"; info->defs.defined = 0; info->defs.fileID = 0; @@ -99,18 +100,18 @@ InitKeyInfo(KeyInfo * info) for (i = 0; i < XkbNumKbdGroups; i++) { info->numLevels[i] = 0; - info->types[i] = None; + info->types[i] = XKB_ATOM_NONE; info->syms[i] = NULL; + info->sizeSyms[i] = 0; + info->symsMapIndex[i] = NULL; + info->symsMapNumEntries[i] = NULL; info->acts[i] = NULL; } - info->dfltType = None; + info->dfltType = XKB_ATOM_NONE; info->behavior.type = XkbKB_Default; info->behavior.data = 0; info->vmodmap = 0; - info->nameForOverlayKey = 0; info->repeat = RepeatUndefined; - info->allowNone = 0; - return; } /** @@ -119,7 +120,7 @@ InitKeyInfo(KeyInfo * info) static void FreeKeyInfo(KeyInfo * info) { - register int i; + int i; info->defs.defined = 0; info->defs.fileID = 0; @@ -130,22 +131,22 @@ FreeKeyInfo(KeyInfo * info) for (i = 0; i < XkbNumKbdGroups; i++) { info->numLevels[i] = 0; - info->types[i] = None; - if (info->syms[i] != NULL) - free(info->syms[i]); + info->types[i] = XKB_ATOM_NONE; + free(info->syms[i]); info->syms[i] = NULL; - if (info->acts[i] != NULL) - free(info->acts[i]); + info->sizeSyms[i] = 0; + free(info->symsMapIndex[i]); + info->symsMapIndex[i] = NULL; + free(info->symsMapNumEntries[i]); + info->symsMapNumEntries[i] = NULL; + free(info->acts[i]); info->acts[i] = NULL; } - info->dfltType = None; + info->dfltType = XKB_ATOM_NONE; info->behavior.type = XkbKB_Default; info->behavior.data = 0; info->vmodmap = 0; - info->nameForOverlayKey = 0; info->repeat = RepeatUndefined; - info->allowNone = 0; - return; } /** @@ -153,10 +154,10 @@ FreeKeyInfo(KeyInfo * info) * If old is reset, new simply re-uses old's memory. Otherwise, the memory is * newly allocated and new points to the new memory areas. */ -static Bool -CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld) +static bool +CopyKeyInfo(KeyInfo * old, KeyInfo * new, bool clearOld) { - register int i; + int i; *new = *old; new->defs.next = NULL; @@ -165,42 +166,80 @@ CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld) for (i = 0; i < XkbNumKbdGroups; i++) { old->numLevels[i] = 0; + old->symsMapIndex[i] = NULL; + old->symsMapNumEntries[i] = NULL; old->syms[i] = NULL; + old->sizeSyms[i] = 0; old->acts[i] = NULL; } } else { - int width; + unsigned int width; for (i = 0; i < XkbNumKbdGroups; i++) { width = new->numLevels[i]; if (old->syms[i] != NULL) { - new->syms[i] = uTypedCalloc(width, uint32_t); + new->syms[i] = uTypedCalloc(new->sizeSyms[i], xkb_keysym_t); if (!new->syms[i]) { new->syms[i] = NULL; + new->sizeSyms[i] = 0; new->numLevels[i] = 0; - return False; + new->acts[i] = NULL; + return false; + } + memcpy(new->syms[i], old->syms[i], + new->sizeSyms[i] * sizeof(xkb_keysym_t)); + new->symsMapIndex[i] = uTypedCalloc(width, int); + if (!new->symsMapIndex[i]) + { + free(new->syms[i]); + new->syms[i] = NULL; + new->sizeSyms[i] = 0; + new->numLevels[i] = 0; + new->acts[i] = NULL; + return false; } - memcpy((char *) new->syms[i], (char *) old->syms[i], - width * sizeof(uint32_t)); + memcpy(new->symsMapIndex[i], old->symsMapIndex[i], + width * sizeof(int)); + new->symsMapNumEntries[i] = uTypedCalloc(width, unsigned int); + if (!new->symsMapNumEntries[i]) + { + free(new->syms[i]); + new->syms[i] = NULL; + new->sizeSyms[i] = 0; + free(new->symsMapIndex[i]); + new->symsMapIndex[i] = NULL; + new->numLevels[i] = 0; + new->acts[i] = NULL; + return false; + } + memcpy(new->symsMapNumEntries[i], old->symsMapNumEntries[i], + width * sizeof(unsigned int)); } if (old->acts[i] != NULL) { new->acts[i] = uTypedCalloc(width, union xkb_action); if (!new->acts[i]) { - new->acts[i] = NULL; - return False; + free(new->syms[i]); + new->syms[i] = NULL; + new->sizeSyms[i] = 0; + free(new->symsMapIndex[i]); + new->symsMapIndex[i] = NULL; + free(new->symsMapNumEntries[i]); + new->symsMapNumEntries[i] = NULL; + new->numLevels[i] = 0; + return false; } - memcpy((char *) new->acts[i], (char *) old->acts[i], + memcpy(new->acts[i], old->acts[i], width * sizeof(union xkb_action)); } } } - return True; + return true; } /***====================================================================***/ @@ -208,17 +247,17 @@ CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld) typedef struct _ModMapEntry { CommonInfo defs; - Bool haveSymbol; + bool haveSymbol; int modifier; union { unsigned long keyName; - uint32_t keySym; + xkb_keysym_t keySym; } u; } ModMapEntry; -#define SYMBOLS_INIT_SIZE 110 -#define SYMBOLS_CHUNK 20 +#define SYMBOLS_INIT_SIZE 110 + typedef struct _SymbolsInfo { char *name; /* e.g. pc+us+inet(evdev) */ @@ -226,147 +265,158 @@ typedef struct _SymbolsInfo unsigned fileID; unsigned merge; unsigned explicit_group; - unsigned groupInfo; - unsigned szKeys; - unsigned nKeys; - KeyInfo *keys; + darray(KeyInfo) keys; KeyInfo dflt; VModInfo vmods; ActionInfo *action; - uint32_t groupNames[XkbNumKbdGroups]; + xkb_atom_t groupNames[XkbNumKbdGroups]; ModMapEntry *modMap; AliasInfo *aliases; } SymbolsInfo; static void -InitSymbolsInfo(SymbolsInfo * info, struct xkb_desc * xkb) +InitSymbolsInfo(SymbolsInfo * info, struct xkb_keymap *keymap) { - register int i; + int i; - tok_ONE_LEVEL = xkb_intern_atom("ONE_LEVEL"); - tok_TWO_LEVEL = xkb_intern_atom("TWO_LEVEL"); - tok_KEYPAD = xkb_intern_atom("KEYPAD"); info->name = NULL; info->explicit_group = 0; info->errorCount = 0; info->fileID = 0; info->merge = MergeOverride; - info->groupInfo = 0; - info->szKeys = SYMBOLS_INIT_SIZE; - info->nKeys = 0; - info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo); + darray_init(info->keys); + darray_growalloc(info->keys, SYMBOLS_INIT_SIZE); info->modMap = NULL; for (i = 0; i < XkbNumKbdGroups; i++) - info->groupNames[i] = None; + info->groupNames[i] = XKB_ATOM_NONE; InitKeyInfo(&info->dflt); - InitVModInfo(&info->vmods, xkb); + InitVModInfo(&info->vmods, keymap); info->action = NULL; info->aliases = NULL; - return; } static void FreeSymbolsInfo(SymbolsInfo * info) { - register int i; + KeyInfo *key; - if (info->name) - free(info->name); - info->name = NULL; - if (info->keys) - { - for (i = 0; i < info->nKeys; i++) - { - FreeKeyInfo(&info->keys[i]); - } - free(info->keys); - info->keys = NULL; - } + free(info->name); + darray_foreach(key, info->keys) + FreeKeyInfo(key); + darray_free(info->keys); if (info->modMap) - { ClearCommonInfo(&info->modMap->defs); - info->modMap = NULL; - } if (info->aliases) - { ClearAliases(&info->aliases); - info->aliases = NULL; - } - bzero((char *) info, sizeof(SymbolsInfo)); - return; + memset(info, 0, sizeof(SymbolsInfo)); } -static Bool -ResizeKeyGroup(KeyInfo * key, - unsigned group, unsigned atLeastSize, Bool forceActions) +static bool +ResizeKeyGroup(KeyInfo * key, unsigned int group, unsigned int numLevels, + unsigned sizeSyms, bool forceActions) { - Bool tooSmall; - unsigned newWidth; - - tooSmall = (key->numLevels[group] < atLeastSize); - if (tooSmall) - newWidth = atLeastSize; - else - newWidth = key->numLevels[group]; + int i; - if ((key->syms[group] == NULL) || tooSmall) + if (key->syms[group] == NULL || key->sizeSyms[group] < sizeSyms) { key->syms[group] = uTypedRecalloc(key->syms[group], - key->numLevels[group], newWidth, - uint32_t); - if (!key->syms[group]) - return False; - } - if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) || - (tooSmall && (key->acts[group] != NULL))) + key->sizeSyms[group], + sizeSyms, + xkb_keysym_t); + if (!key->syms[group]) { + key->sizeSyms[group] = 0; + return false; + } + key->sizeSyms[group] = sizeSyms; + } + if (!key->symsMapIndex[group] || key->numLevels[group] < numLevels) + { + key->symsMapIndex[group] = uTypedRealloc(key->symsMapIndex[group], + numLevels, + int); + if (!key->symsMapIndex[group]) + return false; + for (i = key->numLevels[group]; i < numLevels; i++) + key->symsMapIndex[group][i] = -1; + } + if (!key->symsMapNumEntries[group] || key->numLevels[group] < numLevels) + { + key->symsMapNumEntries[group] = + uTypedRecalloc(key->symsMapNumEntries[group], + key->numLevels[group], + numLevels, + unsigned int); + if (!key->symsMapNumEntries[group]) + return false; + } + if ((forceActions && + (key->numLevels[group] < numLevels || (key->acts[group] == NULL))) || + (key->numLevels[group] < numLevels && (key->acts[group] != NULL))) { key->acts[group] = uTypedRecalloc(key->acts[group], - key->numLevels[group], newWidth, + key->numLevels[group], + numLevels, union xkb_action); if (!key->acts[group]) - return False; + return false; } - key->numLevels[group] = newWidth; - return True; + if (key->numLevels[group] < numLevels) + key->numLevels[group] = numLevels; + return true; } -static Bool +enum key_group_selector { + NONE = 0, + FROM = (1 << 0), + TO = (1 << 1), +}; + +static bool MergeKeyGroups(SymbolsInfo * info, KeyInfo * into, KeyInfo * from, unsigned group) { - uint32_t *resultSyms; + xkb_keysym_t *resultSyms = NULL; + enum key_group_selector using = NONE; union xkb_action *resultActs; - int resultWidth; - register int i; - Bool report, clobber; + unsigned int resultWidth; + unsigned int resultSize = 0; + int cur_idx = 0; + int i; + bool report, clobber; clobber = (from->defs.merge != MergeAugment); report = (warningLevel > 9) || ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0)); if (into->numLevels[group] >= from->numLevels[group]) { - resultSyms = into->syms[group]; resultActs = into->acts[group]; resultWidth = into->numLevels[group]; } else { - resultSyms = from->syms[group]; resultActs = from->acts[group]; resultWidth = from->numLevels[group]; - } - if (resultSyms == NULL) - { - resultSyms = uTypedCalloc(resultWidth, uint32_t); - if (!resultSyms) - { - WSGO("Could not allocate symbols for group merge\n"); + into->symsMapIndex[group] = uTypedRealloc(into->symsMapIndex[group], + from->numLevels[group], + int); + into->symsMapNumEntries[group] = + uTypedRecalloc(into->symsMapNumEntries[group], + into->numLevels[group], + from->numLevels[group], + unsigned int); + if (!into->symsMapIndex[group] || !into->symsMapNumEntries[group]) + { + WSGO("Could not allocate level indices for key info merge\n"); ACTION("Group %d of key %s not merged\n", group, - longText(into->name)); - return False; + longText(into->name)); + + return false; } + for (i = into->numLevels[group]; i < from->numLevels[group]; i++) + into->symsMapIndex[group][i] = -1; } + if ((resultActs == NULL) && (into->acts[group] || from->acts[group])) { resultActs = uTypedCalloc(resultWidth, union xkb_action); @@ -375,48 +425,9 @@ MergeKeyGroups(SymbolsInfo * info, WSGO("Could not allocate actions for group merge\n"); ACTION("Group %d of key %s not merged\n", group, longText(into->name)); - return False; + return false; } - } - for (i = 0; i < resultWidth; i++) - { - uint32_t fromSym, toSym; - if (from->syms[group] && (i < from->numLevels[group])) - fromSym = from->syms[group][i]; - else - fromSym = NoSymbol; - if (into->syms[group] && (i < into->numLevels[group])) - toSym = into->syms[group][i]; - else - toSym = NoSymbol; - if ((fromSym == NoSymbol) || (fromSym == toSym)) - resultSyms[i] = toSym; - else if (toSym == NoSymbol) - resultSyms[i] = fromSym; - else - { - uint32_t use, ignore; - if (clobber) - { - use = fromSym; - ignore = toSym; - } - else - { - use = toSym; - ignore = fromSym; - } - if (report) - { - WARN - ("Multiple symbols for level %d/group %d on key %s\n", - i + 1, group + 1, longText(into->name)); - ACTION("Using %s, ignoring %s\n", - XkbcKeysymText(use), XkbcKeysymText(ignore)); - } - resultSyms[i] = use; - } - if (resultActs != NULL) + for (i = 0; i < resultWidth; i++) { union xkb_action *fromAct, *toAct; fromAct = (from->acts[group] ? &from->acts[group][i] : NULL); @@ -453,36 +464,150 @@ MergeKeyGroups(SymbolsInfo * info, XkbcActionTypeText(use->type), XkbcActionTypeText(ignore->type)); } - resultActs[i] = *use; + if (use) + resultActs[i] = *use; } } } - if ((into->syms[group] != NULL) && (resultSyms != into->syms[group])) - free(into->syms[group]); - if ((from->syms[group] != NULL) && (resultSyms != from->syms[group])) - free(from->syms[group]); - if ((into->acts[group] != NULL) && (resultActs != into->acts[group])) + + for (i = 0; i < resultWidth; i++) + { + unsigned int fromSize = 0; + unsigned toSize = 0; + + if (from->symsMapNumEntries[group] && (i < from->numLevels[group])) + fromSize = from->symsMapNumEntries[group][i]; + if (into->symsMapNumEntries[group] && (i < into->numLevels[group])) + toSize = into->symsMapNumEntries[group][i]; + + if (fromSize == 0) + { + resultSize += toSize; + using |= TO; + } + else if (toSize == 0 || clobber) + { + resultSize += fromSize; + using |= FROM; + } + else + { + resultSize += toSize; + using |= TO; + } + } + + if (resultSize == 0) + goto out; + + if (using == FROM) + { + resultSyms = from->syms[group]; + goto out; + } + else if (using == TO) + { + resultSyms = into->syms[group]; + goto out; + } + + resultSyms = uTypedCalloc(resultSize, xkb_keysym_t); + if (!resultSyms) + { + WSGO("Could not allocate symbols for group merge\n"); + ACTION("Group %d of key %s not merged\n", group, longText(into->name)); + return false; + } + + for (i = 0; i < resultWidth; i++) + { + enum key_group_selector use = NONE; + unsigned int fromSize = 0; + unsigned int toSize = 0; + + if (i < from->numLevels[group]) + fromSize = from->symsMapNumEntries[group][i]; + if (i < into->numLevels[group]) + toSize = into->symsMapNumEntries[group][i]; + + if (fromSize == 0 && toSize == 0) + { + into->symsMapIndex[group][i] = -1; + into->symsMapNumEntries[group][i] = 0; + continue; + } + + if (fromSize == 0) + use = TO; + else if (toSize == 0 || clobber) + use = FROM; + else + use = TO; + + if (toSize && fromSize && report) + { + INFO("Multiple symbols for group %d, level %d on key %s\n", + group + 1, i + 1, longText(into->name)); + ACTION("Using %s, ignoring %s\n", + (use == FROM ? "from" : "to"), + (use == FROM ? "to" : "from")); + } + + if (use == FROM) + { + memcpy(&resultSyms[cur_idx], + &from->syms[group][from->symsMapIndex[group][i]], + from->symsMapNumEntries[group][i] * sizeof(xkb_keysym_t)); + into->symsMapIndex[group][i] = cur_idx; + into->symsMapNumEntries[group][i] = + from->symsMapNumEntries[group][i]; + } + else + { + memcpy(&resultSyms[cur_idx], + &into->syms[group][into->symsMapIndex[group][i]], + into->symsMapNumEntries[group][i] * sizeof(xkb_keysym_t)); + into->symsMapIndex[group][i] = cur_idx; + } + cur_idx += into->symsMapNumEntries[group][i]; + } + +out: + if (resultActs != into->acts[group]) free(into->acts[group]); - if ((from->acts[group] != NULL) && (resultActs != from->acts[group])) + if (resultActs != from->acts[group]) free(from->acts[group]); into->numLevels[group] = resultWidth; + if (resultSyms != into->syms[group]) + free(into->syms[group]); into->syms[group] = resultSyms; + if (resultSyms != from->syms[group]) + free(from->syms[group]); from->syms[group] = NULL; + from->sizeSyms[group] = 0; + into->sizeSyms[group] = resultSize; + free(from->symsMapIndex[group]); + from->symsMapIndex[group] = NULL; + free(from->symsMapNumEntries[group]); + from->symsMapNumEntries[group] = NULL; into->acts[group] = resultActs; from->acts[group] = NULL; - into->symsDefined |= (1 << group); + if (into->syms[group]) + into->symsDefined |= (1 << group); from->symsDefined &= ~(1 << group); into->actsDefined |= (1 << group); from->actsDefined &= ~(1 << group); - return True; + + return true; } -static Bool -MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) +static bool +MergeKeys(SymbolsInfo *info, struct xkb_keymap *keymap, + KeyInfo *into, KeyInfo *from) { - register int i; + int i; unsigned collide = 0; - Bool report; + bool report; if (from->defs.merge == MergeReplace) { @@ -490,15 +615,13 @@ MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) { if (into->numLevels[i] != 0) { - if (into->syms[i]) - free(into->syms[i]); - if (into->acts[i]) - free(into->acts[i]); + free(into->syms[i]); + free(into->acts[i]); } } *into = *from; - bzero(from, sizeof(KeyInfo)); - return True; + memset(from, 0, sizeof(KeyInfo)); + return true; } report = ((warningLevel > 9) || ((into->defs.fileID == from->defs.fileID) @@ -511,9 +634,15 @@ MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) { into->numLevels[i] = from->numLevels[i]; into->syms[i] = from->syms[i]; + into->sizeSyms[i] = from->sizeSyms[i]; + into->symsMapIndex[i] = from->symsMapIndex[i]; + into->symsMapNumEntries[i] = from->symsMapNumEntries[i]; into->acts[i] = from->acts[i]; into->symsDefined |= (1 << i); from->syms[i] = NULL; + from->sizeSyms[i] = 0; + from->symsMapIndex[i] = NULL; + from->symsMapNumEntries[i] = NULL; from->acts[i] = NULL; from->numLevels[i] = 0; from->symsDefined &= ~(1 << i); @@ -534,12 +663,12 @@ MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) MergeKeyGroups(info, into, from, (unsigned) i); } } - if (from->types[i] != None) + if (from->types[i] != XKB_ATOM_NONE) { - if ((into->types[i] != None) && (report) && + if ((into->types[i] != XKB_ATOM_NONE) && report && (into->types[i] != from->types[i])) { - uint32_t use, ignore; + xkb_atom_t use, ignore; collide |= _Key_Types; if (from->defs.merge != MergeAugment) { @@ -555,11 +684,11 @@ MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) ("Multiple definitions for group %d type of key %s\n", i, longText(into->name)); ACTION("Using %s, ignoring %s\n", - XkbcAtomText(use), - XkbcAtomText(ignore)); + xkb_atom_text(keymap->ctx, use), + xkb_atom_text(keymap->ctx, ignore)); } if ((from->defs.merge != MergeAugment) - || (into->types[i] == None)) + || (into->types[i] == XKB_ATOM_NONE)) { into->types[i] = from->types[i]; } @@ -568,7 +697,6 @@ MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide)) { into->behavior = from->behavior; - into->nameForOverlayKey = from->nameForOverlayKey; into->defs.defined |= _Key_Behavior; } if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide)) @@ -598,48 +726,34 @@ MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) ACTION("Using %s definition for conflicting fields\n", (from->defs.merge == MergeAugment ? "first" : "last")); } - return True; + return true; } -static Bool -AddKeySymbols(SymbolsInfo * info, KeyInfo * key, struct xkb_desc * xkb) +static bool +AddKeySymbols(SymbolsInfo *info, KeyInfo *key, struct xkb_keymap *keymap) { - register int i; unsigned long real_name; + KeyInfo *iter, *new; - for (i = 0; i < info->nKeys; i++) - { - if (info->keys[i].name == key->name) - return MergeKeys(info, &info->keys[i], key); - } - if (FindKeyNameForAlias(xkb, key->name, &real_name)) - { - for (i = 0; i < info->nKeys; i++) - { - if (info->keys[i].name == real_name) - return MergeKeys(info, &info->keys[i], key); - } - } - if (info->nKeys >= info->szKeys) - { - info->szKeys += SYMBOLS_CHUNK; - info->keys = - uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo); - if (!info->keys) - { - WSGO("Could not allocate key symbols descriptions\n"); - ACTION("Some key symbols definitions may be lost\n"); - return False; - } - } - return CopyKeyInfo(key, &info->keys[info->nKeys++], True); + darray_foreach(iter, info->keys) + if (iter->name == key->name) + return MergeKeys(info, keymap, iter, key); + + if (FindKeyNameForAlias(keymap, key->name, &real_name)) + darray_foreach(iter, info->keys) + if (iter->name == real_name) + return MergeKeys(info, keymap, iter, key); + + darray_resize0(info->keys, darray_size(info->keys) + 1); + new = &darray_item(info->keys, darray_size(info->keys) - 1); + return CopyKeyInfo(key, new, true); } -static Bool +static bool AddModMapEntry(SymbolsInfo * info, ModMapEntry * new) { ModMapEntry *mm; - Bool clobber; + bool clobber; clobber = (new->defs.merge != MergeAugment); for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next) @@ -668,7 +782,7 @@ AddModMapEntry(SymbolsInfo * info, ModMapEntry * new) XkbcModIndexText(ignore)); mm->modifier = use; } - return True; + return true; } if ((!new->haveSymbol) && (!mm->haveSymbol) && (new->u.keyName == mm->u.keyName)) @@ -693,7 +807,7 @@ AddModMapEntry(SymbolsInfo * info, ModMapEntry * new) XkbcModIndexText(ignore)); mm->modifier = use; } - return True; + return true; } } mm = uTypedAlloc(ModMapEntry); @@ -702,21 +816,21 @@ AddModMapEntry(SymbolsInfo * info, ModMapEntry * new) WSGO("Could not allocate modifier map entry\n"); ACTION("Modifier map for %s will be incomplete\n", XkbcModIndexText(new->modifier)); - return False; + return false; } *mm = *new; mm->defs.next = &info->modMap->defs; info->modMap = mm; - return True; + return true; } /***====================================================================***/ static void -MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from, - unsigned merge, struct xkb_desc * xkb) +MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from, + unsigned merge, struct xkb_keymap *keymap) { - register int i; + unsigned int i; KeyInfo *key; if (from->errorCount > 0) @@ -731,19 +845,22 @@ MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from, } for (i = 0; i < XkbNumKbdGroups; i++) { - if (from->groupNames[i] != None) + if (from->groupNames[i] != XKB_ATOM_NONE) { - if ((merge != MergeAugment) || (into->groupNames[i] == None)) + if ((merge != MergeAugment) || + (into->groupNames[i] == XKB_ATOM_NONE)) into->groupNames[i] = from->groupNames[i]; } } - for (i = 0, key = from->keys; i < from->nKeys; i++, key++) - { + + darray_foreach(key, from->keys) { if (merge != MergeDefault) key->defs.merge = merge; - if (!AddKeySymbols(into, key, xkb)) + + if (!AddKeySymbols(into, key, keymap)) into->errorCount++; } + if (from->modMap != NULL) { ModMapEntry *mm, *next; @@ -760,34 +877,32 @@ MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from, } if (!MergeAliases(&into->aliases, &from->aliases, merge)) into->errorCount++; - return; } -typedef void (*FileHandler) (XkbFile * /* rtrn */ , - struct xkb_desc * /* xkb */ , - unsigned /* merge */ , - SymbolsInfo * /* included */ - ); +static void +HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap, + unsigned merge, SymbolsInfo *info); -static Bool -HandleIncludeSymbols(IncludeStmt * stmt, - struct xkb_desc * xkb, SymbolsInfo * info, FileHandler hndlr) +static bool +HandleIncludeSymbols(IncludeStmt *stmt, struct xkb_keymap *keymap, + SymbolsInfo *info) { unsigned newMerge; XkbFile *rtrn; SymbolsInfo included; - Bool haveSelf; + bool haveSelf; - haveSelf = False; + haveSelf = false; if ((stmt->file == NULL) && (stmt->map == NULL)) { - haveSelf = True; + haveSelf = true; included = *info; - bzero(info, sizeof(SymbolsInfo)); + memset(info, 0, sizeof(SymbolsInfo)); } - else if (ProcessIncludeFile(stmt, XkmSymbolsIndex, &rtrn, &newMerge)) + else if (ProcessIncludeFile(keymap->ctx, stmt, XkmSymbolsIndex, &rtrn, + &newMerge)) { - InitSymbolsInfo(&included, xkb); + InitSymbolsInfo(&included, keymap); included.fileID = included.dflt.defs.fileID = rtrn->id; included.merge = included.dflt.defs.merge = MergeOverride; if (stmt->modifier) @@ -798,19 +913,19 @@ HandleIncludeSymbols(IncludeStmt * stmt, { included.explicit_group = info->explicit_group; } - (*hndlr) (rtrn, xkb, MergeOverride, &included); + HandleSymbolsFile(rtrn, keymap, MergeOverride, &included); if (stmt->stmt != NULL) { - if (included.name != NULL) - free(included.name); + free(included.name); included.name = stmt->stmt; stmt->stmt = NULL; } + FreeXKBFile(rtrn); } else { info->errorCount += 10; - return False; + return false; } if ((stmt->next != NULL) && (included.errorCount < 1)) { @@ -822,13 +937,14 @@ HandleIncludeSymbols(IncludeStmt * stmt, { if ((next->file == NULL) && (next->map == NULL)) { - haveSelf = True; - MergeIncludedSymbols(&included, info, next->merge, xkb); + haveSelf = true; + MergeIncludedSymbols(&included, info, next->merge, keymap); FreeSymbolsInfo(info); } - else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op)) + else if (ProcessIncludeFile(keymap->ctx, next, XkmSymbolsIndex, + &rtrn, &op)) { - InitSymbolsInfo(&next_incl, xkb); + InitSymbolsInfo(&next_incl, keymap); next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id; next_incl.merge = next_incl.dflt.defs.merge = MergeOverride; if (next->modifier) @@ -839,45 +955,38 @@ HandleIncludeSymbols(IncludeStmt * stmt, { next_incl.explicit_group = info->explicit_group; } - (*hndlr) (rtrn, xkb, MergeOverride, &next_incl); - MergeIncludedSymbols(&included, &next_incl, op, xkb); + HandleSymbolsFile(rtrn, keymap, MergeOverride, &next_incl); + MergeIncludedSymbols(&included, &next_incl, op, keymap); FreeSymbolsInfo(&next_incl); + FreeXKBFile(rtrn); } else { info->errorCount += 10; - return False; + FreeSymbolsInfo(&included); + return false; } } } + else if (stmt->next) + { + info->errorCount += included.errorCount; + } if (haveSelf) *info = included; else { - MergeIncludedSymbols(info, &included, newMerge, xkb); + MergeIncludedSymbols(info, &included, newMerge, keymap); FreeSymbolsInfo(&included); } return (info->errorCount == 0); } -static LookupEntry groupNames[] = { - {"group1", 1}, - {"group2", 2}, - {"group3", 3}, - {"group4", 4}, - {"group5", 5}, - {"group6", 6}, - {"group7", 7}, - {"group8", 8}, - {NULL, 0} -}; - - #define SYMBOLS 1 #define ACTIONS 2 -static Bool -GetGroupIndex(KeyInfo * key, +static bool +GetGroupIndex(KeyInfo *key, struct xkb_keymap *keymap, ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn) { const char *name; @@ -890,7 +999,7 @@ GetGroupIndex(KeyInfo * key, if (arrayNdx == NULL) { - register int i; + int i; unsigned defined; if (what == SYMBOLS) defined = key->symsDefined; @@ -902,118 +1011,130 @@ GetGroupIndex(KeyInfo * key, if ((defined & (1 << i)) == 0) { *ndx_rtrn = i; - return True; + return true; } } ERROR("Too many groups of %s for key %s (max %d)\n", name, longText(key->name), XkbNumKbdGroups + 1); ACTION("Ignoring %s defined for extra groups\n", name); - return False; + return false; } - if (!ExprResolveInteger - (arrayNdx, &tmp, SimpleLookup, (char *) groupNames)) + if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp)) { ERROR("Illegal group index for %s of key %s\n", name, longText(key->name)); ACTION("Definition with non-integer array index ignored\n"); - return False; - } - if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) - { - ERROR("Group index for %s of key %s is out of range (1..%d)\n", - name, longText(key->name), XkbNumKbdGroups + 1); - ACTION("Ignoring %s for group %d\n", name, tmp.uval); - return False; + return false; } *ndx_rtrn = tmp.uval - 1; - return True; + return true; } -static Bool -AddSymbolsToKey(KeyInfo * key, - struct xkb_desc * xkb, - char *field, - ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info) +static bool +AddSymbolsToKey(KeyInfo *key, struct xkb_keymap *keymap, + ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info) { - unsigned ndx, nSyms; - int i; + unsigned ndx, nSyms, nLevels; + unsigned int i; + long j; - if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx)) - return False; + if (!GetGroupIndex(key, keymap, arrayNdx, SYMBOLS, &ndx)) + return false; if (value == NULL) { key->symsDefined |= (1 << ndx); - return True; + return true; } if (value->op != ExprKeysymList) { - ERROR("Expected a list of symbols, found %s\n", - exprOpText(value->op)); - ACTION("Ignoring symbols for group %d of %s\n", ndx, + ERROR("Expected a list of symbols, found %s\n", exprOpText(value->op)); + ACTION("Ignoring symbols for group %d of %s\n", ndx + 1, longText(key->name)); - return False; + return false; } - if (key->syms[ndx] != NULL) + if (key->sizeSyms[ndx] != 0) { - WSGO("Symbols for key %s, group %d already defined\n", - longText(key->name), ndx); - return False; + ERROR("Symbols for key %s, group %d already defined\n", + longText(key->name), ndx + 1); + ACTION("Ignoring duplicate definition\n"); + return false; } - nSyms = value->value.list.nSyms; + nSyms = darray_size(value->value.list.syms); + nLevels = darray_size(value->value.list.symsMapIndex); if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) && - (!ResizeKeyGroup(key, ndx, nSyms, False))) + (!ResizeKeyGroup(key, ndx, nLevels, nSyms, false))) { - WSGO("Could not resize group %d of key %s\n", ndx, - longText(key->name)); + WSGO("Could not resize group %d of key %s to contain %d levels\n", + ndx + 1, longText(key->name), nSyms); ACTION("Symbols lost\n"); - return False; + return false; } key->symsDefined |= (1 << ndx); - for (i = 0; i < nSyms; i++) { - if (!LookupKeysym(value->value.list.syms[i], &key->syms[ndx][i])) { - WSGO("Could not resolve keysym %s\n", value->value.list.syms[i]); - key->syms[ndx][i] = NoSymbol; + for (i = 0; i < nLevels; i++) { + key->symsMapIndex[ndx][i] = + darray_item(value->value.list.symsMapIndex, i); + key->symsMapNumEntries[ndx][i] = + darray_item(value->value.list.symsNumEntries, i); + + for (j = 0; j < key->symsMapNumEntries[ndx][i]; j++) { + if (key->symsMapIndex[ndx][i] + j >= nSyms) + abort(); + if (!LookupKeysym(darray_item(value->value.list.syms, + darray_item(value->value.list.symsMapIndex, i) + j), + &key->syms[ndx][key->symsMapIndex[ndx][i] + j])) { + WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n", + darray_item(value->value.list.syms, i), + longText(key->name), + ndx + 1, + xkb_atom_text(keymap->ctx, info->groupNames[ndx]), nSyms); + while (--j >= 0) + key->syms[ndx][key->symsMapIndex[ndx][i] + j] = XKB_KEY_NoSymbol; + key->symsMapIndex[ndx][i] = -1; + key->symsMapNumEntries[ndx][i] = 0; + break; + } + if (key->symsMapNumEntries[ndx][i] == 1 && + key->syms[ndx][key->symsMapIndex[ndx][i] + j] == XKB_KEY_NoSymbol) { + key->symsMapIndex[ndx][i] = -1; + key->symsMapNumEntries[ndx][i] = 0; + } } } - for (i = key->numLevels[ndx] - 1; - (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--) - { + for (j = key->numLevels[ndx] - 1; + j >= 0 && key->symsMapNumEntries[ndx][j] == 0; j--) key->numLevels[ndx]--; - } - return True; + return true; } -static Bool -AddActionsToKey(KeyInfo * key, - struct xkb_desc * xkb, - char *field, - ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info) +static bool +AddActionsToKey(KeyInfo *key, struct xkb_keymap *keymap, ExprDef *arrayNdx, + ExprDef *value, SymbolsInfo *info) { - register int i; + unsigned int i; unsigned ndx, nActs; ExprDef *act; struct xkb_any_action *toAct; - if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx)) - return False; + if (!GetGroupIndex(key, keymap, arrayNdx, ACTIONS, &ndx)) + return false; if (value == NULL) { key->actsDefined |= (1 << ndx); - return True; + return true; } if (value->op != ExprActionList) { WSGO("Bad expression type (%d) for action list value\n", value->op); ACTION("Ignoring actions for group %d of %s\n", ndx, longText(key->name)); - return False; + return false; } if (key->acts[ndx] != NULL) { WSGO("Actions for key %s, group %d already defined\n", longText(key->name), ndx); - return False; + return false; } for (nActs = 0, act = value->value.child; act != NULL; nActs++) { @@ -1022,15 +1143,15 @@ AddActionsToKey(KeyInfo * key, if (nActs < 1) { WSGO("Action list but not actions in AddActionsToKey\n"); - return False; + return false; } if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) && - (!ResizeKeyGroup(key, ndx, nActs, True))) + (!ResizeKeyGroup(key, ndx, nActs, nActs, true))) { WSGO("Could not resize group %d of key %s\n", ndx, longText(key->name)); ACTION("Actions lost\n"); - return False; + return false; } key->actsDefined |= (1 << ndx); @@ -1038,7 +1159,7 @@ AddActionsToKey(KeyInfo * key, act = value->value.child; for (i = 0; i < nActs; i++, toAct++) { - if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action)) + if (!HandleActionDef(act, keymap, toAct, info->action)) { ERROR("Illegal action definition for %s\n", longText(key->name)); @@ -1046,53 +1167,10 @@ AddActionsToKey(KeyInfo * key, } act = (ExprDef *) act->common.next; } - return True; + return true; } -static int -SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value) -{ - ExprResult tmp; - unsigned radio_groups = 0; - - if (arrayNdx == NULL) - { - radio_groups = XkbAllRadioGroupsMask; - } - else - { - if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL)) - { - ERROR("Illegal index in group name definition\n"); - ACTION("Definition with non-integer array index ignored\n"); - return False; - } - if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups)) - { - ERROR("Illegal radio group specified (must be 1..%d)\n", - XkbMaxRadioGroups + 1); - ACTION("Value of \"allow none\" for group %d ignored\n", - tmp.uval); - return False; - } - radio_groups |= (1 << (tmp.uval - 1)); - } - if (!ExprResolveBoolean(value, &tmp, NULL, NULL)) - { - ERROR("Illegal \"allow none\" value for %s\n", - longText(key->name)); - ACTION("Non-boolean value ignored\n"); - return False; - } - if (tmp.uval) - key->allowNone |= radio_groups; - else - key->allowNone &= ~radio_groups; - return True; -} - - -static LookupEntry lockingEntries[] = { +static const LookupEntry lockingEntries[] = { {"true", XkbKB_Lock}, {"yes", XkbKB_Lock}, {"on", XkbKB_Lock}, @@ -1103,7 +1181,7 @@ static LookupEntry lockingEntries[] = { {NULL, 0} }; -static LookupEntry repeatEntries[] = { +static const LookupEntry repeatEntries[] = { {"true", RepeatYes}, {"yes", RepeatYes}, {"on", RepeatYes}, @@ -1114,24 +1192,17 @@ static LookupEntry repeatEntries[] = { {NULL, 0} }; -static LookupEntry rgEntries[] = { - {"none", 0}, - {NULL, 0} -}; - -static Bool -SetSymbolsField(KeyInfo * key, - struct xkb_desc * xkb, - char *field, - ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info) +static bool +SetSymbolsField(KeyInfo *key, struct xkb_keymap *keymap, char *field, + ExprDef *arrayNdx, ExprDef *value, SymbolsInfo *info) { - Bool ok = True; + bool ok = true; ExprResult tmp; - if (uStrCaseCmp(field, "type") == 0) + if (strcasecmp(field, "type") == 0) { ExprResult ndx; - if ((!ExprResolveString(value, &tmp, NULL, NULL)) + if ((!ExprResolveString(keymap->ctx, value, &tmp)) && (warningLevel > 0)) { WARN("The type field of a key symbol map must be a string\n"); @@ -1139,43 +1210,33 @@ SetSymbolsField(KeyInfo * key, } if (arrayNdx == NULL) { - key->dfltType = xkb_intern_atom(tmp.str); + key->dfltType = xkb_atom_intern(keymap->ctx, tmp.str); key->defs.defined |= _Key_Type_Dflt; } - else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup, - (char *) groupNames)) + else if (!ExprResolveGroup(keymap->ctx, arrayNdx, &ndx)) { ERROR("Illegal group index for type of key %s\n", longText(key->name)); ACTION("Definition with non-integer array index ignored\n"); free(tmp.str); - return False; - } - else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups)) - { - ERROR - ("Group index for type of key %s is out of range (1..%d)\n", - longText(key->name), XkbNumKbdGroups + 1); - ACTION("Ignoring type for group %d\n", ndx.uval); - free(tmp.str); - return False; + return false; } else { - key->types[ndx.uval - 1] = xkb_intern_atom(tmp.str); + key->types[ndx.uval - 1] = xkb_atom_intern(keymap->ctx, tmp.str); key->typesDefined |= (1 << (ndx.uval - 1)); } free(tmp.str); } - else if (uStrCaseCmp(field, "symbols") == 0) - return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info); - else if (uStrCaseCmp(field, "actions") == 0) - return AddActionsToKey(key, xkb, field, arrayNdx, value, info); - else if ((uStrCaseCmp(field, "vmods") == 0) || - (uStrCaseCmp(field, "virtualmods") == 0) || - (uStrCaseCmp(field, "virtualmodifiers") == 0)) + else if (strcasecmp(field, "symbols") == 0) + return AddSymbolsToKey(key, keymap, arrayNdx, value, info); + else if (strcasecmp(field, "actions") == 0) + return AddActionsToKey(key, keymap, arrayNdx, value, info); + else if ((strcasecmp(field, "vmods") == 0) || + (strcasecmp(field, "virtualmods") == 0) || + (strcasecmp(field, "virtualmodifiers") == 0)) { - ok = ExprResolveModMask(value, &tmp, LookupVModMask, (char *) xkb); + ok = ExprResolveVModMask(value, &tmp, keymap); if (ok) { key->vmodmap = (tmp.uval >> 8); @@ -1189,133 +1250,54 @@ SetSymbolsField(KeyInfo * key, longText(key->name)); } } - else if ((uStrCaseCmp(field, "locking") == 0) - || (uStrCaseCmp(field, "lock") == 0) - || (uStrCaseCmp(field, "locks") == 0)) + else if ((strcasecmp(field, "locking") == 0) || + (strcasecmp(field, "lock") == 0) || + (strcasecmp(field, "locks") == 0)) { - ok = ExprResolveEnum(value, &tmp, lockingEntries); + ok = ExprResolveEnum(keymap->ctx, value, &tmp, lockingEntries); if (ok) key->behavior.type = tmp.uval; key->defs.defined |= _Key_Behavior; } - else if ((uStrCaseCmp(field, "radiogroup") == 0) || - (uStrCaseCmp(field, "permanentradiogroup") == 0)) - { - Bool permanent = False; - if (uStrCaseCmp(field, "permanentradiogroup") == 0) - permanent = True; - ok = ExprResolveInteger(value, &tmp, SimpleLookup, - (char *) rgEntries); - if (!ok) - { - ERROR("Illegal radio group specification for %s\n", - longText(key->name)); - ACTION("Non-integer radio group ignored\n"); - return False; - } - if (tmp.uval == 0) - { - key->behavior.type = XkbKB_Default; - key->behavior.data = 0; - return ok; - } - if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups)) - { - ERROR - ("Radio group specification for %s out of range (1..32)\n", - longText(key->name)); - ACTION("Illegal radio group %d ignored\n", tmp.uval); - return False; - } - key->behavior.type = - XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0); - key->behavior.data = tmp.uval - 1; - if (key->allowNone & (1 << (tmp.uval - 1))) - key->behavior.data |= XkbKB_RGAllowNone; - key->defs.defined |= _Key_Behavior; - } - else if (uStrCaseEqual(field, "allownone")) + else if ((strcasecmp(field, "radiogroup") == 0) || + (strcasecmp(field, "permanentradiogroup") == 0) || + (strcasecmp(field, "allownone") == 0)) { - ok = SetAllowNone(key, arrayNdx, value); + ERROR("Radio groups not supported\n"); + ACTION("Ignoring radio group specification for key %s\n", longText(key->name)); + return false; } else if (uStrCasePrefix("overlay", field) || uStrCasePrefix("permanentoverlay", field)) { - Bool permanent = False; - char *which; - int overlayNdx; - if (uStrCasePrefix("permanent", field)) - { - permanent = True; - which = &field[sizeof("permanentoverlay") - 1]; - } - else - { - which = &field[sizeof("overlay") - 1]; - } - if (sscanf(which, "%d", &overlayNdx) == 1) - { - if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0)) - { - ERROR("Illegal overlay %d specified for %s\n", - overlayNdx, longText(key->name)); - ACTION("Ignored\n"); - return False; - } - } - else if (*which == '\0') - overlayNdx = 1; - else if (warningLevel > 0) - { - ERROR("Illegal overlay \"%s\" specified for %s\n", - which, longText(key->name)); - ACTION("Ignored\n"); - return False; - } - ok = ExprResolveKeyName(value, &tmp, NULL, NULL); - if (!ok) - { - ERROR("Illegal overlay key specification for %s\n", - longText(key->name)); - ACTION("Overlay key must be specified by name\n"); - return False; - } - if (overlayNdx == 1) - key->behavior.type = XkbKB_Overlay1; - else - key->behavior.type = XkbKB_Overlay2; - if (permanent) - key->behavior.type |= XkbKB_Permanent; - - key->behavior.data = 0; - key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name); - key->defs.defined |= _Key_Behavior; + ERROR("Overlays not supported\n"); + ACTION("Ignoring overlay specification for key %s\n", longText(key->name)); } - else if ((uStrCaseCmp(field, "repeating") == 0) || - (uStrCaseCmp(field, "repeats") == 0) || - (uStrCaseCmp(field, "repeat") == 0)) + else if ((strcasecmp(field, "repeating") == 0) || + (strcasecmp(field, "repeats") == 0) || + (strcasecmp(field, "repeat") == 0)) { - ok = ExprResolveEnum(value, &tmp, repeatEntries); + ok = ExprResolveEnum(keymap->ctx, value, &tmp, repeatEntries); if (!ok) { ERROR("Illegal repeat setting for %s\n", longText(key->name)); ACTION("Non-boolean repeat setting ignored\n"); - return False; + return false; } key->repeat = tmp.uval; key->defs.defined |= _Key_Repeat; } - else if ((uStrCaseCmp(field, "groupswrap") == 0) || - (uStrCaseCmp(field, "wrapgroups") == 0)) + else if ((strcasecmp(field, "groupswrap") == 0) || + (strcasecmp(field, "wrapgroups") == 0)) { - ok = ExprResolveBoolean(value, &tmp, NULL, NULL); + ok = ExprResolveBoolean(keymap->ctx, value, &tmp); if (!ok) { ERROR("Illegal groupsWrap setting for %s\n", longText(key->name)); ACTION("Non-boolean value ignored\n"); - return False; + return false; } if (tmp.uval) key->groupInfo = XkbWrapIntoRange; @@ -1323,16 +1305,16 @@ SetSymbolsField(KeyInfo * key, key->groupInfo = XkbClampIntoRange; key->defs.defined |= _Key_GroupInfo; } - else if ((uStrCaseCmp(field, "groupsclamp") == 0) || - (uStrCaseCmp(field, "clampgroups") == 0)) + else if ((strcasecmp(field, "groupsclamp") == 0) || + (strcasecmp(field, "clampgroups") == 0)) { - ok = ExprResolveBoolean(value, &tmp, NULL, NULL); + ok = ExprResolveBoolean(keymap->ctx, value, &tmp); if (!ok) { ERROR("Illegal groupsClamp setting for %s\n", longText(key->name)); ACTION("Non-boolean value ignored\n"); - return False; + return false; } if (tmp.uval) key->groupInfo = XkbClampIntoRange; @@ -1340,23 +1322,15 @@ SetSymbolsField(KeyInfo * key, key->groupInfo = XkbWrapIntoRange; key->defs.defined |= _Key_GroupInfo; } - else if ((uStrCaseCmp(field, "groupsredirect") == 0) || - (uStrCaseCmp(field, "redirectgroups") == 0)) + else if ((strcasecmp(field, "groupsredirect") == 0) || + (strcasecmp(field, "redirectgroups") == 0)) { - if (!ExprResolveInteger - (value, &tmp, SimpleLookup, (char *) groupNames)) + if (!ExprResolveGroup(keymap->ctx, value, &tmp)) { ERROR("Illegal group index for redirect of key %s\n", longText(key->name)); ACTION("Definition with non-integer group ignored\n"); - return False; - } - if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) - { - ERROR("Out-of-range (1..%d) group for redirect of key %s\n", - XkbNumKbdGroups, longText(key->name)); - ERROR("Ignoring illegal group %d\n", tmp.uval); - return False; + return false; } key->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1); @@ -1366,13 +1340,14 @@ SetSymbolsField(KeyInfo * key, { ERROR("Unknown field %s in a symbol interpretation\n", field); ACTION("Definition ignored\n"); - ok = False; + ok = false; } return ok; } static int -SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value) +SetGroupName(SymbolsInfo *info, struct xkb_keymap *keymap, ExprDef *arrayNdx, + ExprDef *value) { ExprResult tmp, name; @@ -1380,125 +1355,80 @@ SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value) { WARN("You must specify an index when specifying a group name\n"); ACTION("Group name definition without array subscript ignored\n"); - return False; + return false; } - if (!ExprResolveInteger - (arrayNdx, &tmp, SimpleLookup, (char *) groupNames)) + if (!ExprResolveGroup(keymap->ctx, arrayNdx, &tmp)) { ERROR("Illegal index in group name definition\n"); ACTION("Definition with non-integer array index ignored\n"); - return False; - } - if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) - { - ERROR - ("Attempt to specify name for illegal group (must be 1..%d)\n", - XkbNumKbdGroups + 1); - ACTION("Name for group %d ignored\n", tmp.uval); - return False; + return false; } - if (!ExprResolveString(value, &name, NULL, NULL)) + if (!ExprResolveString(keymap->ctx, value, &name)) { ERROR("Group name must be a string\n"); ACTION("Illegal name for group %d ignored\n", tmp.uval); - return False; + return false; } info->groupNames[tmp.uval - 1 + info->explicit_group] = - xkb_intern_atom(name.str); + xkb_atom_intern(keymap->ctx, name.str); + free(name.str); - return True; + return true; } static int -HandleSymbolsVar(VarDef * stmt, struct xkb_desc * xkb, SymbolsInfo * info) +HandleSymbolsVar(VarDef *stmt, struct xkb_keymap *keymap, SymbolsInfo *info) { - ExprResult elem, field, tmp; + ExprResult elem, field; ExprDef *arrayNdx; - Bool ret; + bool ret; - if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0) + if (ExprResolveLhs(keymap, stmt->name, &elem, &field, &arrayNdx) == 0) return 0; /* internal error, already reported */ - if (elem.str && (uStrCaseCmp(elem.str, "key") == 0)) + if (elem.str && (strcasecmp(elem.str, "key") == 0)) { - ret = SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx, + ret = SetSymbolsField(&info->dflt, keymap, field.str, arrayNdx, stmt->value, info); } - else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) || - (uStrCaseCmp(field.str, "groupname") == + else if ((elem.str == NULL) && ((strcasecmp(field.str, "name") == 0) || + (strcasecmp(field.str, "groupname") == 0))) { - ret = SetGroupName(info, arrayNdx, stmt->value); + ret = SetGroupName(info, keymap, arrayNdx, stmt->value); } else if ((elem.str == NULL) - && ((uStrCaseCmp(field.str, "groupswrap") == 0) - || (uStrCaseCmp(field.str, "wrapgroups") == 0))) + && ((strcasecmp(field.str, "groupswrap") == 0) || + (strcasecmp(field.str, "wrapgroups") == 0))) { - if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL)) - { - ERROR("Illegal setting for global groupsWrap\n"); - ACTION("Non-boolean value ignored\n"); - ret = False; - } - else { - if (tmp.uval) - info->groupInfo = XkbWrapIntoRange; - else - info->groupInfo = XkbClampIntoRange; - ret = True; - } + ERROR("Global \"groupswrap\" not supported\n"); + ACTION("Ignored\n"); + ret = true; } else if ((elem.str == NULL) - && ((uStrCaseCmp(field.str, "groupsclamp") == 0) - || (uStrCaseCmp(field.str, "clampgroups") == 0))) + && ((strcasecmp(field.str, "groupsclamp") == 0) || + (strcasecmp(field.str, "clampgroups") == 0))) { - if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL)) - { - ERROR("Illegal setting for global groupsClamp\n"); - ACTION("Non-boolean value ignored\n"); - return False; - } - else { - if (tmp.uval) - info->groupInfo = XkbClampIntoRange; - else - info->groupInfo = XkbWrapIntoRange; - ret = True; - } + ERROR("Global \"groupsclamp\" not supported\n"); + ACTION("Ignored\n"); + ret = true; } else if ((elem.str == NULL) - && ((uStrCaseCmp(field.str, "groupsredirect") == 0) - || (uStrCaseCmp(field.str, "redirectgroups") == 0))) + && ((strcasecmp(field.str, "groupsredirect") == 0) || + (strcasecmp(field.str, "redirectgroups") == 0))) { - if (!ExprResolveInteger(stmt->value, &tmp, - SimpleLookup, (char *) groupNames)) - { - ERROR("Illegal group index for global groupsRedirect\n"); - ACTION("Definition with non-integer group ignored\n"); - ret = False; - } - else { - if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) - { - ERROR - ("Out-of-range (1..%d) group for global groupsRedirect\n", - XkbNumKbdGroups); - ACTION("Ignoring illegal group %d\n", tmp.uval); - ret = False; - } - else { - info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, - tmp.uval); - ret = True; - } - } + ERROR("Global \"groupsredirect\" not supported\n"); + ACTION("Ignored\n"); + ret = true; } - else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0)) + else if ((elem.str == NULL) && (strcasecmp(field.str, "allownone") == 0)) { - ret = SetAllowNone(&info->dflt, arrayNdx, stmt->value); + ERROR("Radio groups not supported\n"); + ACTION("Ignoring \"allownone\" specification\n"); + ret = true; } else { - ret = SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value, - &info->action); + ret = SetActionField(keymap, elem.str, field.str, arrayNdx, + stmt->value, &info->action); } free(elem.str); @@ -1506,11 +1436,11 @@ HandleSymbolsVar(VarDef * stmt, struct xkb_desc * xkb, SymbolsInfo * info) return ret; } -static Bool -HandleSymbolsBody(VarDef * def, - struct xkb_desc * xkb, KeyInfo * key, SymbolsInfo * info) +static bool +HandleSymbolsBody(VarDef *def, struct xkb_keymap *keymap, KeyInfo *key, + SymbolsInfo *info) { - Bool ok = True; + bool ok = true; ExprResult tmp, field; ExprDef *arrayNdx; @@ -1518,7 +1448,7 @@ HandleSymbolsBody(VarDef * def, { if ((def->name) && (def->name->type == ExprFieldRef)) { - ok = HandleSymbolsVar(def, xkb, info); + ok = HandleSymbolsVar(def, keymap, info); continue; } else @@ -1527,30 +1457,32 @@ HandleSymbolsBody(VarDef * def, { if ((def->value == NULL) || (def->value->op == ExprKeysymList)) - field.str = "symbols"; + field.str = strdup("symbols"); else - field.str = "actions"; + field.str = strdup("actions"); arrayNdx = NULL; } else { - ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx); + ok = ExprResolveLhs(keymap, def->name, &tmp, &field, + &arrayNdx); } if (ok) - ok = SetSymbolsField(key, xkb, field.str, arrayNdx, + ok = SetSymbolsField(key, keymap, field.str, arrayNdx, def->value, info); + free(field.str); } } return ok; } -static Bool -SetExplicitGroup(SymbolsInfo * info, KeyInfo * key) +static bool +SetExplicitGroup(SymbolsInfo *info, KeyInfo *key) { unsigned group = info->explicit_group; if (group == 0) - return True; + return true; if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1) { @@ -1562,13 +1494,11 @@ SetExplicitGroup(SymbolsInfo * info, KeyInfo * key) for (i = 1; i < XkbNumKbdGroups; i++) { key->numLevels[i] = 0; - if (key->syms[i] != NULL) - free(key->syms[i]); - key->syms[i] = (uint32_t *) NULL; - if (key->acts[i] != NULL) - free(key->acts[i]); - key->acts[i] = (union xkb_action *) NULL; - key->types[i] = (uint32_t) 0; + free(key->syms[i]); + key->syms[i] = NULL; + free(key->acts[i]); + key->acts[i] = NULL; + key->types[i] = 0; } } key->typesDefined = key->symsDefined = key->actsDefined = 1 << group; @@ -1576,72 +1506,77 @@ SetExplicitGroup(SymbolsInfo * info, KeyInfo * key) key->numLevels[group] = key->numLevels[0]; key->numLevels[0] = 0; key->syms[group] = key->syms[0]; - key->syms[0] = (uint32_t *) NULL; + key->syms[0] = NULL; + key->sizeSyms[group] = key->sizeSyms[0]; + key->sizeSyms[0] = 0; + key->symsMapIndex[group] = key->symsMapIndex[0]; + key->symsMapIndex[0] = NULL; + key->symsMapNumEntries[group] = key->symsMapNumEntries[0]; + key->symsMapNumEntries[0] = NULL; key->acts[group] = key->acts[0]; - key->acts[0] = (union xkb_action *) NULL; + key->acts[0] = NULL; key->types[group] = key->types[0]; - key->types[0] = (uint32_t) 0; - return True; + key->types[0] = 0; + return true; } static int -HandleSymbolsDef(SymbolsDef * stmt, - struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info) +HandleSymbolsDef(SymbolsDef *stmt, struct xkb_keymap *keymap, + SymbolsInfo *info) { KeyInfo key; InitKeyInfo(&key); - CopyKeyInfo(&info->dflt, &key, False); + CopyKeyInfo(&info->dflt, &key, false); key.defs.merge = stmt->merge; key.name = KeyNameToLong(stmt->keyName); - if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info)) + if (!HandleSymbolsBody((VarDef *) stmt->symbols, keymap, &key, info)) { info->errorCount++; - return False; + return false; } if (!SetExplicitGroup(info, &key)) { info->errorCount++; - return False; + return false; } - if (!AddKeySymbols(info, &key, xkb)) + if (!AddKeySymbols(info, &key, keymap)) { info->errorCount++; - return False; + return false; } - return True; + return true; } -static Bool -HandleModMapDef(ModMapDef * def, - struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info) +static bool +HandleModMapDef(ModMapDef *def, struct xkb_keymap *keymap, SymbolsInfo *info) { ExprDef *key; ModMapEntry tmp; ExprResult rtrn; - Bool ok; + bool ok; - if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn)) + if (!LookupModIndex(keymap->ctx, NULL, def->modifier, TypeInt, &rtrn)) { ERROR("Illegal modifier map definition\n"); ACTION("Ignoring map for non-modifier \"%s\"\n", - XkbcAtomText(def->modifier)); - return False; + xkb_atom_text(keymap->ctx, def->modifier)); + return false; } - ok = True; + ok = true; tmp.modifier = rtrn.uval; for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) { if ((key->op == ExprValue) && (key->type == TypeKeyName)) { - tmp.haveSymbol = False; + tmp.haveSymbol = false; tmp.u.keyName = KeyNameToLong(key->value.keyName); } - else if (ExprResolveKeySym(key, &rtrn, NULL, NULL)) + else if (ExprResolveKeySym(keymap->ctx, key, &rtrn)) { - tmp.haveSymbol = True; + tmp.haveSymbol = true; tmp.u.keySym = rtrn.uval; } else @@ -1658,32 +1593,32 @@ HandleModMapDef(ModMapDef * def, } static void -HandleSymbolsFile(XkbFile * file, - struct xkb_desc * xkb, unsigned merge, SymbolsInfo * info) +HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap, + unsigned merge, SymbolsInfo *info) { ParseCommon *stmt; - info->name = _XkbDupString(file->name); + free(info->name); + info->name = uDupString(file->name); stmt = file->defs; while (stmt) { switch (stmt->stmtType) { case StmtInclude: - if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info, - HandleSymbolsFile)) + if (!HandleIncludeSymbols((IncludeStmt *) stmt, keymap, info)) info->errorCount++; break; case StmtSymbolsDef: - if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info)) + if (!HandleSymbolsDef((SymbolsDef *) stmt, keymap, info)) info->errorCount++; break; case StmtVarDef: - if (!HandleSymbolsVar((VarDef *) stmt, xkb, info)) + if (!HandleSymbolsVar((VarDef *) stmt, keymap, info)) info->errorCount++; break; case StmtVModDef: - if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods)) + if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods)) info->errorCount++; break; case StmtInterpDef: @@ -1697,7 +1632,7 @@ HandleSymbolsFile(XkbFile * file, info->errorCount++; break; case StmtModMapDef: - if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info)) + if (!HandleModMapDef((ModMapDef *) stmt, keymap, info)) info->errorCount++; break; default: @@ -1715,62 +1650,59 @@ HandleSymbolsFile(XkbFile * file, break; } } - return; } -static Bool -FindKeyForSymbol(struct xkb_desc * xkb, uint32_t sym, xkb_keycode_t *kc_rtrn) +static bool +FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym, + xkb_keycode_t *kc_rtrn) { - register int i, j; - register Bool gotOne; + xkb_keycode_t key; + unsigned int group, level; - j = 0; - do + for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) { - gotOne = False; - for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) + for (group = 0; group < XkbKeyNumGroups(keymap, key); group++) { - if (j < (int) XkbKeyNumSyms(xkb, i)) + for (level = 0; level < XkbKeyGroupWidth(keymap, key, group); + level++) { - gotOne = True; - if ((XkbKeySym(xkb, i, j) == sym)) - { - *kc_rtrn = i; - return True; - } + if (XkbKeyNumSyms(keymap, key, group, level) != 1 || + (XkbKeySymEntry(keymap, key, group, level))[0] != sym) + continue; + *kc_rtrn = key; + return true; } } - j++; } - while (gotOne); - return False; + + return false; } /** - * Find the given name in the xkb->map->types and return its index. + * Find the given name in the keymap->map->types and return its index. * - * @param name The atom to search for. + * @param atom The atom to search for. * @param type_rtrn Set to the index of the name if found. * - * @return True if found, False otherwise. + * @return true if found, false otherwise. */ -static Bool -FindNamedType(struct xkb_desc * xkb, uint32_t name, unsigned *type_rtrn) +static bool +FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn) { - register unsigned n; + unsigned n = 0; + const char *name = xkb_atom_text(keymap->ctx, atom); + struct xkb_key_type *type; - if (xkb && xkb->map && xkb->map->types) - { - for (n = 0; n < xkb->map->num_types; n++) - { - if (xkb->map->types[n].name == (uint32_t) name) - { + if (keymap && keymap->map) { + darray_foreach(type, keymap->map->types) { + if (strcmp(type->name, name) == 0) { *type_rtrn = n; - return True; + return true; } + n++; } } - return False; + return false; } /** @@ -1787,33 +1719,33 @@ FindNamedType(struct xkb_desc * xkb, uint32_t name, unsigned *type_rtrn) * @param syms The keysyms for the given key (must be size width). * @param typeNameRtrn Set to the Atom of the type name. * - * @returns True if a type could be found, False otherwise. + * @returns true if a type could be found, false otherwise. */ -static Bool -FindAutomaticType(int width, uint32_t * syms, uint32_t * typeNameRtrn, - Bool * autoType) +static bool +FindAutomaticType(struct xkb_keymap *keymap, int width, xkb_keysym_t *syms, + xkb_atom_t *typeNameRtrn, bool *autoType) { - *autoType = False; + *autoType = false; if ((width == 1) || (width == 0)) { - *typeNameRtrn = xkb_intern_atom("ONE_LEVEL"); - *autoType = True; + *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ONE_LEVEL"); + *autoType = true; } else if (width == 2) { if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1])) { - *typeNameRtrn = xkb_intern_atom("ALPHABETIC"); + *typeNameRtrn = xkb_atom_intern(keymap->ctx, "ALPHABETIC"); } else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1]))) { - *typeNameRtrn = xkb_intern_atom("KEYPAD"); - *autoType = True; + *typeNameRtrn = xkb_atom_intern(keymap->ctx, "KEYPAD"); + *autoType = true; } else { - *typeNameRtrn = xkb_intern_atom("TWO_LEVEL"); - *autoType = True; + *typeNameRtrn = xkb_atom_intern(keymap->ctx, "TWO_LEVEL"); + *autoType = true; } } else if (width <= 4) @@ -1821,14 +1753,15 @@ FindAutomaticType(int width, uint32_t * syms, uint32_t * typeNameRtrn, if (syms && XkbcKSIsLower(syms[0]) && XkbcKSIsUpper(syms[1])) if (XkbcKSIsLower(syms[2]) && XkbcKSIsUpper(syms[3])) *typeNameRtrn = - xkb_intern_atom("FOUR_LEVEL_ALPHABETIC"); + xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_ALPHABETIC"); else - *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_SEMIALPHABETIC"); + *typeNameRtrn = xkb_atom_intern(keymap->ctx, + "FOUR_LEVEL_SEMIALPHABETIC"); else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1]))) - *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL_KEYPAD"); + *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL_KEYPAD"); else - *typeNameRtrn = xkb_intern_atom("FOUR_LEVEL"); + *typeNameRtrn = xkb_atom_intern(keymap->ctx, "FOUR_LEVEL"); /* XXX: why not set autoType here? */ } return ((width >= 0) && (width <= 4)); @@ -1842,7 +1775,7 @@ static void PrepareKeyDef(KeyInfo * key) { int i, j, width, defined, lastGroup; - Bool identical; + bool identical; defined = key->symsDefined | key->actsDefined | key->typesDefined; /* get highest group number */ @@ -1877,17 +1810,38 @@ PrepareKeyDef(KeyInfo * key) key->acts[i] = uTypedCalloc(width, union xkb_action); if (key->acts[i] == NULL) continue; - memcpy((void *) key->acts[i], (void *) key->acts[0], + memcpy(key->acts[i], key->acts[0], width * sizeof(union xkb_action)); key->actsDefined |= 1 << i; } - if ((key->symsDefined & 1) && key->syms[0]) + if ((key->symsDefined & 1) && key->sizeSyms[0]) { - key->syms[i] = uTypedCalloc(width, uint32_t); + key->syms[i] = uTypedCalloc(key->sizeSyms[0], xkb_keysym_t); if (key->syms[i] == NULL) continue; - memcpy((void *) key->syms[i], (void *) key->syms[0], - width * sizeof(uint32_t)); + memcpy(key->syms[i], key->syms[0], + key->sizeSyms[0] * sizeof(xkb_keysym_t)); + key->symsMapIndex[i] = uTypedCalloc(width, int); + if (!key->symsMapIndex[i]) + { + free(key->syms[i]); + key->syms[i] = NULL; + continue; + } + memcpy(key->symsMapIndex[i], key->symsMapIndex[0], + width * sizeof(int)); + key->symsMapNumEntries[i] = uTypedCalloc(width, unsigned int); + if (!key->symsMapNumEntries[i]) + { + free(key->syms[i]); + key->syms[i] = NULL; + free(key->symsMapIndex[i]); + key->symsMapIndex[i] = NULL; + continue; + } + memcpy(key->symsMapNumEntries[i], key->symsMapNumEntries[0], + width * sizeof(int)); + key->sizeSyms[i] = key->sizeSyms[0]; key->symsDefined |= 1 << i; } if (defined & 1) @@ -1897,29 +1851,47 @@ PrepareKeyDef(KeyInfo * key) } /* If all groups are completely identical remove them all */ /* exept the first one. */ - identical = True; + identical = true; for (i = lastGroup; i > 0; i--) { if ((key->numLevels[i] != key->numLevels[0]) || (key->types[i] != key->types[0])) { - identical = False; + identical = false; break; } if ((key->syms[i] != key->syms[0]) && (key->syms[i] == NULL || key->syms[0] == NULL || - memcmp((void *) key->syms[i], (void *) key->syms[0], - sizeof(uint32_t) * key->numLevels[0]))) + key->sizeSyms[i] != key->sizeSyms[0] || + memcmp(key->syms[i], key->syms[0], + sizeof(xkb_keysym_t) * key->sizeSyms[0]))) { - identical = False; + identical = false; break; } + if ((key->symsMapIndex[i] != key->symsMapIndex[0]) && + (key->symsMapIndex[i] == NULL || key->symsMapIndex[0] == NULL || + memcmp(key->symsMapIndex[i], key->symsMapIndex[0], + key->numLevels[0] * sizeof(int)))) + { + identical = false; + continue; + } + if ((key->symsMapNumEntries[i] != key->symsMapNumEntries[0]) && + (key->symsMapNumEntries[i] == NULL || + key->symsMapNumEntries[0] == NULL || + memcmp(key->symsMapNumEntries[i], key->symsMapNumEntries[0], + key->numLevels[0] * sizeof(int)))) + { + identical = false; + continue; + } if ((key->acts[i] != key->acts[0]) && (key->acts[i] == NULL || key->acts[0] == NULL || - memcmp((void *) key->acts[i], (void *) key->acts[0], + memcmp(key->acts[i], key->acts[0], sizeof(union xkb_action) * key->numLevels[0]))) { - identical = False; + identical = false; break; } } @@ -1928,19 +1900,21 @@ PrepareKeyDef(KeyInfo * key) for (i = lastGroup; i > 0; i--) { key->numLevels[i] = 0; - if (key->syms[i] != NULL) - free(key->syms[i]); - key->syms[i] = (uint32_t *) NULL; - if (key->acts[i] != NULL) - free(key->acts[i]); - key->acts[i] = (union xkb_action *) NULL; - key->types[i] = (uint32_t) 0; + free(key->syms[i]); + key->syms[i] = NULL; + key->sizeSyms[i] = 0; + free(key->symsMapIndex[i]); + key->symsMapIndex[i] = NULL; + free(key->symsMapNumEntries[i]); + key->symsMapNumEntries[i] = NULL; + free(key->acts[i]); + key->acts[i] = NULL; + key->types[i] = 0; } key->symsDefined &= 1; key->actsDefined &= 1; key->typesDefined &= 1; } - return; } /** @@ -1948,35 +1922,35 @@ PrepareKeyDef(KeyInfo * key) * * This function recurses. */ -static Bool -CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from) +static bool +CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *key, int start_from) { - register int i; - xkb_keycode_t okc, kc; + unsigned int i; + xkb_keycode_t kc; + unsigned int sizeSyms = 0; unsigned width, tmp, nGroups; struct xkb_key_type * type; - Bool haveActions, autoType, useAlias; - uint32_t *outSyms; - union xkb_action *outActs; + bool haveActions, autoType, useAlias; unsigned types[XkbNumKbdGroups]; + union xkb_action *outActs; + unsigned int symIndex = 0; + struct xkb_sym_map *sym_map; useAlias = (start_from == 0); /* get the keycode for the key. */ - if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb), - start_from)) + if (!FindNamedKey(keymap, key->name, &kc, useAlias, + CreateKeyNames(keymap), start_from)) { if ((start_from == 0) && (warningLevel >= 5)) { - WARN("Key %s not found in %s keycodes\n", - longText(key->name), - XkbcAtomText(xkb->names->keycodes)); + WARN("Key %s not found in keycodes\n", longText(key->name)); ACTION("Symbols ignored\n"); } - return False; + return false; } - haveActions = False; + haveActions = false; for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++) { if (((i + 1) > nGroups) @@ -1984,14 +1958,14 @@ CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from) || (key->typesDefined) & (1 << i))) nGroups = i + 1; if (key->acts[i]) - haveActions = True; - autoType = False; + haveActions = true; + autoType = false; /* Assign the type to the key, if it is missing. */ - if (key->types[i] == None) + if (key->types[i] == XKB_ATOM_NONE) { - if (key->dfltType != None) + if (key->dfltType != XKB_ATOM_NONE) key->types[i] = key->dfltType; - else if (FindAutomaticType(key->numLevels[i], key->syms[i], + else if (FindAutomaticType(keymap, key->numLevels[i], key->syms[i], &key->types[i], &autoType)) { } @@ -2002,39 +1976,36 @@ CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from) WARN("No automatic type for %d symbols\n", (unsigned int) key->numLevels[i]); ACTION("Using %s for the %s key (keycode %d)\n", - XkbcAtomText(key->types[i]), + xkb_atom_text(keymap->ctx, key->types[i]), longText(key->name), kc); } } } - if (FindNamedType(xkb, key->types[i], &types[i])) + if (FindNamedType(keymap, key->types[i], &types[i])) { if (!autoType || key->numLevels[i] > 2) - xkb->server->explicit[kc] |= (1 << i); + keymap->server->explicit[kc] |= (1 << i); } else { if (warningLevel >= 3) { WARN("Type \"%s\" is not defined\n", - XkbcAtomText(key->types[i])); + xkb_atom_text(keymap->ctx, key->types[i])); ACTION("Using TWO_LEVEL for the %s key (keycode %d)\n", longText(key->name), kc); } types[i] = XkbTwoLevelIndex; } - /* if the type specifies less syms than the key has, shrink the key */ - type = &xkb->map->types[types[i]]; + /* if the type specifies fewer levels than the key has, shrink the key */ + type = &darray_item(keymap->map->types, types[i]); if (type->num_levels < key->numLevels[i]) { if (warningLevel > 0) { - WARN - ("Type \"%s\" has %d levels, but %s has %d symbols\n", - XkbcAtomText(type->name), - (unsigned int) type->num_levels, - longText(key->name), - (unsigned int) key->numLevels[i]); + WARN("Type \"%s\" has %d levels, but %s has %d symbols\n", + type->name, type->num_levels, + xkb_atom_text(keymap->ctx, key->name), key->numLevels[i]); ACTION("Ignoring extra symbols\n"); } key->numLevels[i] = type->num_levels; @@ -2043,38 +2014,41 @@ CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from) width = key->numLevels[i]; if (type->num_levels > width) width = type->num_levels; + sizeSyms += key->sizeSyms[i]; } - /* width is now the largest width found */ - - i = width * nGroups; - outSyms = XkbcResizeKeySyms(xkb, kc, i); - if (outSyms == NULL) + if (!XkbcResizeKeySyms(keymap, kc, sizeSyms)) { WSGO("Could not enlarge symbols for %s (keycode %d)\n", longText(key->name), kc); - return False; + return false; } if (haveActions) { - outActs = XkbcResizeKeyActions(xkb, kc, i); + outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups); if (outActs == NULL) { WSGO("Could not enlarge actions for %s (key %d)\n", longText(key->name), kc); - return False; + return false; } - xkb->server->explicit[kc] |= XkbExplicitInterpretMask; + keymap->server->explicit[kc] |= XkbExplicitInterpretMask; } else outActs = NULL; + + sym_map = &darray_item(keymap->map->key_sym_map, kc); + if (key->defs.defined & _Key_GroupInfo) i = key->groupInfo; else - i = xkb->map->key_sym_map[kc].group_info; + i = sym_map->group_info; + + sym_map->group_info = XkbSetNumGroups(i, nGroups); + sym_map->width = width; + sym_map->sym_index = uTypedCalloc(nGroups * width, int); + sym_map->num_syms = uTypedCalloc(nGroups * width, unsigned int); - xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups); - xkb->map->key_sym_map[kc].width = width; for (i = 0; i < nGroups; i++) { /* assign kt_index[i] to the index of the type in map->types. @@ -2085,16 +2059,28 @@ CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from) * FIXME: There should be a better fix for this. */ if (key->numLevels[i]) - xkb->map->key_sym_map[kc].kt_index[i] = types[i]; - if (key->syms[i] != NULL) + sym_map->kt_index[i] = types[i]; + if (key->sizeSyms[i] != 0) { /* fill key to "width" symbols*/ for (tmp = 0; tmp < width; tmp++) { - if (tmp < key->numLevels[i]) - outSyms[tmp] = key->syms[i][tmp]; + if (tmp < key->numLevels[i] && key->symsMapNumEntries[i][tmp]) + { + memcpy(&sym_map->syms[symIndex], + &key->syms[i][key->symsMapIndex[i][tmp]], + key->symsMapNumEntries[i][tmp] * + sizeof(xkb_keysym_t)); + sym_map->sym_index[(i * width) + tmp] = symIndex; + sym_map->num_syms[(i * width) + tmp] = + key->symsMapNumEntries[i][tmp]; + symIndex += sym_map->num_syms[(i * width) + tmp]; + } else - outSyms[tmp] = NoSymbol; + { + sym_map->sym_index[(i * width) + tmp] = -1; + sym_map->num_syms[(i * width) + tmp] = 0; + } if ((outActs != NULL) && (key->acts[i] != NULL)) { if (tmp < key->numLevels[i]) @@ -2104,195 +2090,171 @@ CopySymbolsDef(struct xkb_desc * xkb, KeyInfo *key, int start_from) } } } - outSyms += width; - if (outActs) - outActs += width; } switch (key->behavior.type & XkbKB_OpMask) { case XkbKB_Default: break; - case XkbKB_Overlay1: - case XkbKB_Overlay2: - /* find key by name! */ - if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True, - CreateKeyNames(xkb), 0)) - { - if (warningLevel >= 1) - { - WARN("Key %s not found in %s keycodes\n", - longText(key->nameForOverlayKey), - XkbcAtomText(xkb->names->keycodes)); - ACTION("Not treating %s as an overlay key \n", - longText(key->name)); - } - break; - } - key->behavior.data = okc; default: - xkb->server->behaviors[kc] = key->behavior; - xkb->server->explicit[kc] |= XkbExplicitBehaviorMask; + keymap->server->behaviors[kc] = key->behavior; + keymap->server->explicit[kc] |= XkbExplicitBehaviorMask; break; } if (key->defs.defined & _Key_VModMap) { - xkb->server->vmodmap[kc] = key->vmodmap; - xkb->server->explicit[kc] |= XkbExplicitVModMapMask; + keymap->server->vmodmap[kc] = key->vmodmap; + keymap->server->explicit[kc] |= XkbExplicitVModMapMask; } if (key->repeat != RepeatUndefined) { if (key->repeat == RepeatYes) - xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8)); + keymap->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8)); else - xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8)); - xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask; + keymap->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8)); + keymap->server->explicit[kc] |= XkbExplicitAutoRepeatMask; } - if (nGroups > xkb->ctrls->num_groups) - xkb->ctrls->num_groups = nGroups; + if (nGroups > keymap->ctrls->num_groups) + keymap->ctrls->num_groups = nGroups; /* do the same thing for the next key */ - CopySymbolsDef(xkb, key, kc + 1); - return True; + CopySymbolsDef(keymap, key, kc + 1); + return true; } -static Bool -CopyModMapDef(struct xkb_desc * xkb, ModMapEntry *entry) +static bool +CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry) { xkb_keycode_t kc; - if ((!entry->haveSymbol) - && - (!FindNamedKey - (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0))) + if (!entry->haveSymbol && + !FindNamedKey(keymap, entry->u.keyName, &kc, true, + CreateKeyNames(keymap), 0)) { if (warningLevel >= 5) { - WARN("Key %s not found in %s keycodes\n", - longText(entry->u.keyName), - XkbcAtomText(xkb->names->keycodes)); + WARN("Key %s not found in keycodes\n", + longText(entry->u.keyName)); ACTION("Modifier map entry for %s not updated\n", XkbcModIndexText(entry->modifier)); } - return False; + return false; } - else if (entry->haveSymbol - && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc))) + else if (entry->haveSymbol && + !FindKeyForSymbol(keymap, entry->u.keySym, &kc)) { if (warningLevel > 5) { - WARN("Key \"%s\" not found in %s symbol map\n", - XkbcKeysymText(entry->u.keySym), - XkbcAtomText(xkb->names->symbols)); + WARN("Key \"%s\" not found in symbol map\n", + XkbcKeysymText(entry->u.keySym)); ACTION("Modifier map entry for %s not updated\n", XkbcModIndexText(entry->modifier)); } - return False; + return false; } - xkb->map->modmap[kc] |= (1 << entry->modifier); - return True; + keymap->map->modmap[kc] |= (1 << entry->modifier); + return true; } /** * Handle the xkb_symbols section of an xkb file. * * @param file The parsed xkb_symbols section of the xkb file. - * @param xkb Handle to the keyboard description to store the symbols in. + * @param keymap Handle to the keyboard description to store the symbols in. * @param merge Merge strategy (e.g. MergeOverride). */ -Bool -CompileSymbols(XkbFile *file, struct xkb_desc * xkb, unsigned merge) +bool +CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, unsigned merge) { - register int i; + unsigned int i; SymbolsInfo info; + KeyInfo *key; - InitSymbolsInfo(&info, xkb); + InitSymbolsInfo(&info, keymap); info.dflt.defs.fileID = file->id; info.dflt.defs.merge = merge; - HandleSymbolsFile(file, xkb, merge, &info); - if (info.nKeys == 0) - return True; - if (info.errorCount == 0) - { - KeyInfo *key; + HandleSymbolsFile(file, keymap, merge, &info); - /* alloc memory in the xkb struct */ - if (XkbcAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0) - != Success) - { - WSGO("Can not allocate names in CompileSymbols\n"); - ACTION("Symbols not added\n"); - return False; - } - if (XkbcAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0) - != Success) - { - WSGO("Could not allocate client map in CompileSymbols\n"); - ACTION("Symbols not added\n"); - return False; - } - if (XkbcAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success) - { - WSGO("Could not allocate server map in CompileSymbols\n"); - ACTION("Symbols not added\n"); - return False; - } - if (XkbcAllocControls(xkb, XkbPerKeyRepeatMask) != Success) - { - WSGO("Could not allocate controls in CompileSymbols\n"); - ACTION("Symbols not added\n"); - return False; - } + if (darray_empty(info.keys)) + goto err_info; - /* now copy info into xkb. */ - xkb->names->symbols = xkb_intern_atom(info.name); - if (info.aliases) - ApplyAliases(xkb, False, &info.aliases); - for (i = 0; i < XkbNumKbdGroups; i++) - { - if (info.groupNames[i] != None) - xkb->names->groups[i] = info.groupNames[i]; - } - /* sanitize keys */ - for (key = info.keys, i = 0; i < info.nKeys; i++, key++) - { - PrepareKeyDef(key); - } - /* copy! */ - for (key = info.keys, i = 0; i < info.nKeys; i++, key++) - { - if (!CopySymbolsDef(xkb, key, 0)) - info.errorCount++; + if (info.errorCount != 0) + goto err_info; + + /* alloc memory in the xkb struct */ + if (XkbcAllocNames(keymap, XkbGroupNamesMask, 0) != Success) { + WSGO("Can not allocate names in CompileSymbols\n"); + ACTION("Symbols not added\n"); + goto err_info; + } + + if (XkbcAllocClientMap(keymap, XkbKeySymsMask | XkbModifierMapMask, 0) + != Success) { + WSGO("Could not allocate client map in CompileSymbols\n"); + ACTION("Symbols not added\n"); + goto err_info; + } + + if (XkbcAllocServerMap(keymap, XkbAllServerInfoMask, 32) != Success) { + WSGO("Could not allocate server map in CompileSymbols\n"); + ACTION("Symbols not added\n"); + goto err_info; + } + + if (XkbcAllocControls(keymap) != Success) { + WSGO("Could not allocate controls in CompileSymbols\n"); + ACTION("Symbols not added\n"); + goto err_info; + } + + /* now copy info into xkb. */ + ApplyAliases(keymap, &info.aliases); + + for (i = 0; i < XkbNumKbdGroups; i++) { + if (info.groupNames[i] != XKB_ATOM_NONE) { + free(keymap->names->groups[i]); + keymap->names->groups[i] = xkb_atom_strdup(keymap->ctx, + info.groupNames[i]); } - if (warningLevel > 3) - { - for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) - { - if (xkb->names->keys[i].name[0] == '\0') - continue; - if (XkbKeyNumGroups(xkb, i) < 1) - { - char buf[5]; - memcpy(buf, xkb->names->keys[i].name, 4); - buf[4] = '\0'; - WARN - ("No symbols defined for <%s> (keycode %d)\n", - buf, i); - } + } + + /* sanitize keys */ + darray_foreach(key, info.keys) + PrepareKeyDef(key); + + /* copy! */ + darray_foreach(key, info.keys) + if (!CopySymbolsDef(keymap, key, 0)) + info.errorCount++; + + if (warningLevel > 3) { + for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) { + if (darray_item(keymap->names->keys, i).name[0] == '\0') + continue; + + if (XkbKeyNumGroups(keymap, i) < 1) { + char buf[5]; + memcpy(buf, darray_item(keymap->names->keys, i).name, 4); + buf[4] = '\0'; + WARN("No symbols defined for <%s> (keycode %d)\n", buf, i); } } - if (info.modMap) - { - ModMapEntry *mm, *next; - for (mm = info.modMap; mm != NULL; mm = next) - { - if (!CopyModMapDef(xkb, mm)) - info.errorCount++; - next = (ModMapEntry *) mm->defs.next; - } + } + + if (info.modMap) { + ModMapEntry *mm, *next; + for (mm = info.modMap; mm != NULL; mm = next) { + if (!CopyModMapDef(keymap, mm)) + info.errorCount++; + next = (ModMapEntry *) mm->defs.next; } - return True; } - return False; + + FreeSymbolsInfo(&info); + return true; + +err_info: + FreeSymbolsInfo(&info); + return false; }