X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fxkbcomp%2Fsymbols.c;h=a61a52ba09a1a5b648bd9175ac245afbbd62c6b6;hb=cb631c2de040768478e50db1e606d23ab5286e73;hp=a1980bfea59a14a9a4bec654ebffcb93c6bbda83;hpb=034ffce66437592856497e605cb0943d5dbaf82c;p=profile%2Fivi%2Flibxkbcommon.git diff --git a/src/xkbcomp/symbols.c b/src/xkbcomp/symbols.c index a1980bf..a61a52b 100644 --- a/src/xkbcomp/symbols.c +++ b/src/xkbcomp/symbols.c @@ -24,21 +24,12 @@ ********************************************************/ -#include "xkbcomp.h" -#include "xkballoc.h" -#include "xkbmisc.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" +#include "keycodes.h" +#include "vmod.h" /***====================================================================***/ @@ -64,13 +55,29 @@ typedef struct _KeyInfo unsigned char symsDefined; unsigned char actsDefined; 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]; xkb_atom_t types[XkbNumKbdGroups]; unsigned repeat; struct xkb_behavior behavior; unsigned short vmodmap; - unsigned long allowNone; xkb_atom_t dfltType; } KeyInfo; @@ -81,7 +88,7 @@ static void InitKeyInfo(KeyInfo * info) { int i; - static char dflt[4] = "*"; + static const char dflt[4] = "*"; info->defs.defined = 0; info->defs.fileID = 0; @@ -95,6 +102,9 @@ InitKeyInfo(KeyInfo * info) info->numLevels[i] = 0; 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 = XKB_ATOM_NONE; @@ -102,7 +112,6 @@ InitKeyInfo(KeyInfo * info) info->behavior.data = 0; info->vmodmap = 0; info->repeat = RepeatUndefined; - info->allowNone = 0; } /** @@ -125,6 +134,11 @@ FreeKeyInfo(KeyInfo * info) info->types[i] = XKB_ATOM_NONE; free(info->syms[i]); info->syms[i] = NULL; + 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; } @@ -133,7 +147,6 @@ FreeKeyInfo(KeyInfo * info) info->behavior.data = 0; info->vmodmap = 0; info->repeat = RepeatUndefined; - info->allowNone = 0; } /** @@ -141,8 +154,8 @@ 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) { int i; @@ -153,7 +166,10 @@ 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; } } @@ -165,29 +181,65 @@ CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld) width = new->numLevels[i]; if (old->syms[i] != NULL) { - new->syms[i] = uTypedCalloc(width, xkb_keysym_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; + 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(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; - return False; + new->acts[i] = NULL; + return false; } - memcpy(new->syms[i], old->syms[i], width * sizeof(xkb_keysym_t)); + 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(new->acts[i], old->acts[i], width * sizeof(union xkb_action)); } } } - return True; + return true; } /***====================================================================***/ @@ -195,7 +247,7 @@ CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld) typedef struct _ModMapEntry { CommonInfo defs; - Bool haveSymbol; + bool haveSymbol; int modifier; union { @@ -204,8 +256,8 @@ typedef struct _ModMapEntry } 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) */ @@ -213,10 +265,7 @@ 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; @@ -227,7 +276,7 @@ typedef struct _SymbolsInfo } SymbolsInfo; static void -InitSymbolsInfo(SymbolsInfo * info, struct xkb_desc * xkb) +InitSymbolsInfo(SymbolsInfo * info, struct xkb_keymap *keymap) { int i; @@ -236,15 +285,13 @@ InitSymbolsInfo(SymbolsInfo * info, struct xkb_desc * xkb) 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] = XKB_ATOM_NONE; InitKeyInfo(&info->dflt); - InitVModInfo(&info->vmods, xkb); + InitVModInfo(&info->vmods, keymap); info->action = NULL; info->aliases = NULL; } @@ -252,15 +299,12 @@ InitSymbolsInfo(SymbolsInfo * info, struct xkb_desc * xkb) static void FreeSymbolsInfo(SymbolsInfo * info) { - unsigned int i; + KeyInfo *key; free(info->name); - if (info->keys) - { - for (i = 0; i < info->nKeys; i++) - FreeKeyInfo(&info->keys[i]); - free(info->keys); - } + darray_foreach(key, info->keys) + FreeKeyInfo(key); + darray_free(info->keys); if (info->modMap) ClearCommonInfo(&info->modMap->defs); if (info->aliases) @@ -268,76 +312,111 @@ FreeSymbolsInfo(SymbolsInfo * info) 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, + key->sizeSyms[group], + sizeSyms, xkb_keysym_t); - if (!key->syms[group]) - return False; + 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 (((forceActions) && (tooSmall || (key->acts[group] == NULL))) || - (tooSmall && (key->acts[group] != NULL))) + 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) { - xkb_keysym_t *resultSyms; + xkb_keysym_t *resultSyms = NULL; + enum key_group_selector using = NONE; union xkb_action *resultActs; unsigned int resultWidth; - unsigned int i; - Bool report, clobber; + 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, xkb_keysym_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); @@ -346,51 +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)); - if (resultSyms != into->syms[group] && - resultSyms != from->syms[group]) - free(resultSyms); - return False; + return false; } - } - for (i = 0; i < resultWidth; i++) - { - xkb_keysym_t fromSym, toSym; - if (from->syms[group] && (i < from->numLevels[group])) - fromSym = from->syms[group][i]; - else - fromSym = XKB_KEYSYM_NO_SYMBOL; - if (into->syms[group] && (i < into->numLevels[group])) - toSym = into->syms[group][i]; - else - toSym = XKB_KEYSYM_NO_SYMBOL; - if ((fromSym == XKB_KEYSYM_NO_SYMBOL) || (fromSym == toSym)) - resultSyms[i] = toSym; - else if (toSym == XKB_KEYSYM_NO_SYMBOL) - resultSyms[i] = fromSym; - else - { - xkb_keysym_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); @@ -432,32 +469,145 @@ MergeKeyGroups(SymbolsInfo * info, } } } - if (resultSyms != into->syms[group]) - free(into->syms[group]); - if (resultSyms != from->syms[group]) - free(from->syms[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 (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) { int i; unsigned collide = 0; - Bool report; + bool report; if (from->defs.merge == MergeReplace) { @@ -471,7 +621,7 @@ MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) } *into = *from; memset(from, 0, sizeof(KeyInfo)); - return True; + return true; } report = ((warningLevel > 9) || ((into->defs.fileID == from->defs.fileID) @@ -484,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); @@ -528,8 +684,8 @@ 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] == XKB_ATOM_NONE)) @@ -570,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) { - unsigned 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) @@ -640,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)) @@ -665,7 +807,7 @@ AddModMapEntry(SymbolsInfo * info, ModMapEntry * new) XkbcModIndexText(ignore)); mm->modifier = use; } - return True; + return true; } } mm = uTypedAlloc(ModMapEntry); @@ -674,19 +816,19 @@ 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) { unsigned int i; KeyInfo *key; @@ -710,13 +852,15 @@ MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from, 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; @@ -735,32 +879,30 @@ MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from, into->errorCount++; } -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; memset(info, 0, sizeof(SymbolsInfo)); } - else if (ProcessIncludeFile(xkb->context, stmt, XkmSymbolsIndex, &rtrn, + 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) @@ -771,7 +913,7 @@ HandleIncludeSymbols(IncludeStmt * stmt, { included.explicit_group = info->explicit_group; } - (*hndlr) (rtrn, xkb, MergeOverride, &included); + HandleSymbolsFile(rtrn, keymap, MergeOverride, &included); if (stmt->stmt != NULL) { free(included.name); @@ -783,7 +925,7 @@ HandleIncludeSymbols(IncludeStmt * stmt, else { info->errorCount += 10; - return False; + return false; } if ((stmt->next != NULL) && (included.errorCount < 1)) { @@ -795,14 +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(xkb->context, next, XkmSymbolsIndex, + 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) @@ -813,23 +955,28 @@ 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); @@ -838,8 +985,8 @@ HandleIncludeSymbols(IncludeStmt * stmt, #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; @@ -864,113 +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 (!ExprResolveGroup(arrayNdx, &tmp)) + 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; + 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; + 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 + 1, longText(key->name)); - return False; + return false; } - if (key->syms[ndx] != NULL) + if (key->sizeSyms[ndx] != 0) { ERROR("Symbols for key %s, group %d already defined\n", longText(key->name), ndx + 1); ACTION("Ignoring duplicate definition\n"); - return False; + 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 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])) { - WARN("Could not resolve keysym %s for key %s, group %d (%s), level %d\n", - value->value.list.syms[i], longText(key->name), ndx + 1, - XkbcAtomText(info->groupNames[ndx]), nSyms); - key->syms[ndx][i] = XKB_KEYSYM_NO_SYMBOL; + 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 (j = key->numLevels[ndx] - 1; - (j >= 0) && (key->syms[ndx][j] == XKB_KEYSYM_NO_SYMBOL); j--) - { + 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) { 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++) { @@ -979,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); @@ -995,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)); @@ -1003,7 +1167,7 @@ AddActionsToKey(KeyInfo * key, } act = (ExprDef *) act->common.next; } - return True; + return true; } static const LookupEntry lockingEntries[] = { @@ -1028,19 +1192,17 @@ static const LookupEntry repeatEntries[] = { {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 (strcasecmp(field, "type") == 0) { ExprResult ndx; - if ((!ExprResolveString(value, &tmp)) + if ((!ExprResolveString(keymap->ctx, value, &tmp)) && (warningLevel > 0)) { WARN("The type field of a key symbol map must be a string\n"); @@ -1048,33 +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 (!ExprResolveGroup(arrayNdx, &ndx)) + 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; + 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 (strcasecmp(field, "symbols") == 0) - return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info); + return AddSymbolsToKey(key, keymap, arrayNdx, value, info); else if (strcasecmp(field, "actions") == 0) - return AddActionsToKey(key, xkb, field, arrayNdx, value, info); + return AddActionsToKey(key, keymap, arrayNdx, value, info); else if ((strcasecmp(field, "vmods") == 0) || (strcasecmp(field, "virtualmods") == 0) || (strcasecmp(field, "virtualmodifiers") == 0)) { - ok = ExprResolveVModMask(value, &tmp, xkb); + ok = ExprResolveVModMask(value, &tmp, keymap); if (ok) { key->vmodmap = (tmp.uval >> 8); @@ -1092,7 +1254,7 @@ SetSymbolsField(KeyInfo * key, (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; @@ -1103,7 +1265,7 @@ SetSymbolsField(KeyInfo * key, { ERROR("Radio groups not supported\n"); ACTION("Ignoring radio group specification for key %s\n", longText(key->name)); - return False; + return false; } else if (uStrCasePrefix("overlay", field) || uStrCasePrefix("permanentoverlay", field)) @@ -1115,13 +1277,13 @@ SetSymbolsField(KeyInfo * key, (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; @@ -1129,13 +1291,13 @@ SetSymbolsField(KeyInfo * key, else if ((strcasecmp(field, "groupswrap") == 0) || (strcasecmp(field, "wrapgroups") == 0)) { - ok = ExprResolveBoolean(value, &tmp); + 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; @@ -1146,13 +1308,13 @@ SetSymbolsField(KeyInfo * key, else if ((strcasecmp(field, "groupsclamp") == 0) || (strcasecmp(field, "clampgroups") == 0)) { - ok = ExprResolveBoolean(value, &tmp); + 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; @@ -1163,12 +1325,12 @@ SetSymbolsField(KeyInfo * key, else if ((strcasecmp(field, "groupsredirect") == 0) || (strcasecmp(field, "redirectgroups") == 0)) { - if (!ExprResolveGroup(value, &tmp)) + 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; + return false; } key->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1); @@ -1178,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; @@ -1192,108 +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 (!ExprResolveGroup(arrayNdx, &tmp)) + 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; + return false; } - if (!ExprResolveString(value, &name)) + 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 && (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) && ((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) && ((strcasecmp(field.str, "groupswrap") == 0) || (strcasecmp(field.str, "wrapgroups") == 0))) { - if (!ExprResolveBoolean(stmt->value, &tmp)) - { - 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) && ((strcasecmp(field.str, "groupsclamp") == 0) || (strcasecmp(field.str, "clampgroups") == 0))) { - if (!ExprResolveBoolean(stmt->value, &tmp)) - { - 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) && ((strcasecmp(field.str, "groupsredirect") == 0) || (strcasecmp(field.str, "redirectgroups") == 0))) { - if (!ExprResolveGroup(stmt->value, &tmp)) - { - ERROR("Illegal group index for global groupsRedirect\n"); - ACTION("Definition with non-integer group ignored\n"); - 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) && (strcasecmp(field.str, "allownone") == 0)) { ERROR("Radio groups not supported\n"); - ACTION("Ignoring \"allow none\" specification\n"); - ret = False; + 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); @@ -1301,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; @@ -1313,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 @@ -1329,10 +1464,11 @@ HandleSymbolsBody(VarDef * def, } 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); } @@ -1340,13 +1476,13 @@ HandleSymbolsBody(VarDef * def, 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) { @@ -1371,71 +1507,76 @@ SetExplicitGroup(SymbolsInfo * info, KeyInfo * key) key->numLevels[0] = 0; key->syms[group] = key->syms[0]; 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] = NULL; key->types[group] = key->types[0]; key->types[0] = 0; - return True; + 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, 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)) + else if (ExprResolveKeySym(keymap->ctx, key, &rtrn)) { - tmp.haveSymbol = True; + tmp.haveSymbol = true; tmp.u.keySym = rtrn.uval; } else @@ -1452,8 +1593,8 @@ 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; @@ -1465,20 +1606,19 @@ HandleSymbolsFile(XkbFile * file, 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, xkb, merge, &info->vmods)) + if (!HandleVModDef((VModDef *) stmt, keymap, merge, &info->vmods)) info->errorCount++; break; case StmtInterpDef: @@ -1492,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: @@ -1512,60 +1652,57 @@ HandleSymbolsFile(XkbFile * file, } } -static Bool -FindKeyForSymbol(struct xkb_desc * xkb, xkb_keysym_t sym, xkb_keycode_t *kc_rtrn) +static bool +FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym, + xkb_keycode_t *kc_rtrn) { - int i, j; - 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 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, xkb_atom_t atom, unsigned *type_rtrn) +static bool +FindNamedType(struct xkb_keymap *keymap, xkb_atom_t atom, unsigned *type_rtrn) { - unsigned n; - const char *name = XkbcAtomText(atom); + 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 (strcmp(xkb->map->types[n].name, name) == 0) - { + 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; } /** @@ -1582,33 +1719,33 @@ FindNamedType(struct xkb_desc * xkb, xkb_atom_t atom, 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, xkb_keysym_t * syms, xkb_atom_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) @@ -1616,14 +1753,15 @@ FindAutomaticType(int width, xkb_keysym_t * syms, xkb_atom_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)); @@ -1637,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 */ @@ -1676,12 +1814,34 @@ PrepareKeyDef(KeyInfo * key) 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, xkb_keysym_t); + key->syms[i] = uTypedCalloc(key->sizeSyms[0], xkb_keysym_t); if (key->syms[i] == NULL) continue; - memcpy(key->syms[i], key->syms[0], width * sizeof(xkb_keysym_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) @@ -1691,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 || + key->sizeSyms[i] != key->sizeSyms[0] || memcmp(key->syms[i], key->syms[0], - sizeof(xkb_keysym_t) * key->numLevels[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(key->acts[i], key->acts[0], sizeof(union xkb_action) * key->numLevels[0]))) { - identical = False; + identical = false; break; } } @@ -1724,6 +1902,11 @@ PrepareKeyDef(KeyInfo * key) key->numLevels[i] = 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; @@ -1739,33 +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) { unsigned int i; xkb_keycode_t kc; + unsigned int sizeSyms = 0; unsigned width, tmp, nGroups; struct xkb_key_type * type; - Bool haveActions, autoType, useAlias; - xkb_keysym_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 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) @@ -1773,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] == XKB_ATOM_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)) { } @@ -1791,36 +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", type->name, type->num_levels, - XkbcAtomText(key->name), key->numLevels[i]); + xkb_atom_text(keymap->ctx, key->name), key->numLevels[i]); ACTION("Ignoring extra symbols\n"); } key->numLevels[i] = type->num_levels; @@ -1829,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. @@ -1871,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] = XKB_KEYSYM_NO_SYMBOL; + { + 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]) @@ -1890,50 +2090,46 @@ 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; 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) { @@ -1942,10 +2138,10 @@ CopyModMapDef(struct xkb_desc * xkb, ModMapEntry *entry) 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) { @@ -1954,119 +2150,111 @@ CopyModMapDef(struct xkb_desc * xkb, ModMapEntry *entry) 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) { 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) { - FreeSymbolsInfo(&info); - return True; + HandleSymbolsFile(file, keymap, merge, &info); + + if (darray_empty(info.keys)) + goto err_info; + + 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 (info.errorCount == 0) - { - KeyInfo *key; + if (XkbcAllocClientMap(keymap, XkbKeySymsMask | XkbModifierMapMask, 0) + != Success) { + WSGO("Could not allocate client map in CompileSymbols\n"); + ACTION("Symbols not added\n"); + goto err_info; + } - /* alloc memory in the xkb struct */ - if (XkbcAllocNames(xkb, XkbGroupNamesMask, 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 (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]); } + } - /* now copy info into xkb. */ - if (info.aliases) - ApplyAliases(xkb, &info.aliases); - for (i = 0; i < XkbNumKbdGroups; i++) - { - if (info.groupNames[i] != XKB_ATOM_NONE) - { - free(UNCONSTIFY(xkb->names->groups[i])); - xkb->names->groups[i] = XkbcAtomGetString(info.groupNames[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); } } - /* 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)) + } + + 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; } - 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); - } - } - } - 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; - } - } - FreeSymbolsInfo(&info); - return True; } FreeSymbolsInfo(&info); - return False; + return true; + +err_info: + FreeSymbolsInfo(&info); + return false; }