diff --git a/src/xkbcomp/action.c b/src/xkbcomp/action.c index 36a18dc..8a3677e 100644 --- a/src/xkbcomp/action.c +++ b/src/xkbcomp/action.c @@ -72,23 +72,37 @@ enum action_field { ACTION_FIELD_MODS_TO_CLEAR, }; -struct _ActionInfo { - unsigned action; - enum action_field field; - ExprDef *array_ndx; - ExprDef *value; - struct _ActionInfo *next; -}; +ActionsInfo * +NewActionsInfo(void) +{ + unsigned type; + ActionsInfo *info; + + info = calloc(1, sizeof(*info)); + if (!info) + return NULL; + + /* This includes PrivateAction. */ + for (type = 0; type < XkbSA_NumActions + 1; type++) + info->actions[type].type = type; + + /* Apply some "factory defaults". */ + + /* Increment default button. */ + info->actions[XkbSA_SetPtrDflt].dflt.affect = XkbSA_AffectDfltBtn; + info->actions[XkbSA_SetPtrDflt].dflt.flags = 0; + info->actions[XkbSA_SetPtrDflt].dflt.value = 1; + + info->actions[XkbSA_ISOLock].iso.mods.mods = + (1 << ModNameToIndex(XKB_MOD_NAME_CAPS)); + + return info; +} void -FreeActionInfo(ActionInfo *info) +FreeActionsInfo(ActionsInfo *info) { - ActionInfo *next; - while (info) { - next = info->next; - free(info); - info = next; - } + free(info); } static const LookupEntry actionStrings[] = { @@ -1224,23 +1238,9 @@ static const actionHandler handleAction[XkbSA_NumActions + 1] = { /***====================================================================***/ -static void -ApplyActionFactoryDefaults(union xkb_action *action) -{ - if (action->type == XkbSA_SetPtrDflt) { - /* Increment default button. */ - action->dflt.affect = XkbSA_AffectDfltBtn; - action->dflt.flags = 0; - action->dflt.value = 1; - } - else if (action->type == XkbSA_ISOLock) { - action->iso.mods.mods = (1 << ModNameToIndex(XKB_MOD_NAME_CAPS)); - } -} - bool HandleActionDef(ExprDef *def, struct xkb_keymap *keymap, - union xkb_action *action, ActionInfo *info) + union xkb_action *action, ActionsInfo *info) { ExprDef *arg; const char *str; @@ -1258,27 +1258,12 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap, return false; } - action->type = hndlrType; - /* - * Go through all of the ActionInfo's which change the default values - * for this action->type and apply them to this action, e.g. if the - * action is latchMods, and a statement such as this: + * Get the default values for this action type, as modified by + * statements such as: * latchMods.clearLocks = True; - * appears in the section before, then we apply it. */ - if (action->type != XkbSA_NoAction) { - ApplyActionFactoryDefaults(action); - - for (; info; info = info->next) { - if (info->action != hndlrType) - continue; - - if (!handleAction[hndlrType](keymap, action, info->field, - info->array_ndx, info->value)) - return false; - } - } + *action = info->actions[hndlrType]; /* * Now change the action properties as specified for this @@ -1330,48 +1315,29 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap, return true; } + bool SetActionField(struct xkb_keymap *keymap, const char *elem, const char *field, - ExprDef *array_ndx, ExprDef *value, ActionInfo **info_rtrn) + ExprDef *array_ndx, ExprDef *value, ActionsInfo *info) { - ActionInfo *new, *old; + unsigned action; + enum action_field action_field; - new = malloc(sizeof(*new)); - if (!new) { - log_wsgo(keymap->ctx, "Couldn't allocate space for action default\n"); - goto err; - } + if (!stringToAction(elem, &action)) + return false; - if (!stringToAction(elem, &new->action)) - goto err; - - if (new->action == XkbSA_NoAction) { + if (action == XkbSA_NoAction) { log_err(keymap->ctx, "\"%s\" is not a valid field in a NoAction action\n", field); - goto err; + return false; } - if (!stringToField(field, &new->field)) { + if (!stringToField(field, &action_field)) { log_err(keymap->ctx, "\"%s\" is not a legal field name\n", field); - goto err; + return false; } - new->array_ndx = array_ndx; - new->value = value; - - new->next = NULL; - old = *info_rtrn; - while (old && old->next) - old = old->next; - if (!old) - *info_rtrn = new; - else - old->next = new; - - return true; - -err: - free(new); - return false; + return handleAction[action](keymap, &info->actions[action], + action_field, array_ndx, value); } diff --git a/src/xkbcomp/action.h b/src/xkbcomp/action.h index 81b2426..8ec8386 100644 --- a/src/xkbcomp/action.h +++ b/src/xkbcomp/action.h @@ -27,18 +27,28 @@ #ifndef XKBCOMP_ACTION_H #define XKBCOMP_ACTION_H -typedef struct _ActionInfo ActionInfo; +/* + * This struct contains the default values which every new action + * (e.g. in an interpret statement) starts off with. It can be + * modified within the files (see calls to SetActionField). + */ +typedef struct { + union xkb_action actions[XkbSA_NumActions + 1]; +} ActionsInfo; + +ActionsInfo * +NewActionsInfo(void); void -FreeActionInfo(ActionInfo *info); +FreeActionsInfo(ActionsInfo *info); bool HandleActionDef(ExprDef *def, struct xkb_keymap *keymap, - union xkb_action *action, ActionInfo *info); + union xkb_action *action, ActionsInfo *info); bool SetActionField(struct xkb_keymap *keymap, const char *elem, const char *field, - ExprDef *index, ExprDef *value, ActionInfo **info_rtrn); + ExprDef *array_ndx, ExprDef *value, ActionsInfo *info); extern const LookupEntry ctrlNames[]; diff --git a/src/xkbcomp/compat.c b/src/xkbcomp/compat.c index b6d15d7..1919a97 100644 --- a/src/xkbcomp/compat.c +++ b/src/xkbcomp/compat.c @@ -178,7 +178,7 @@ typedef struct _CompatInfo { LEDInfo ledDflt; darray(LEDInfo) leds; VModInfo vmods; - ActionInfo *act; + ActionsInfo *actions; struct xkb_keymap *keymap; } CompatInfo; @@ -240,14 +240,15 @@ ClearIndicatorMapInfo(struct xkb_context *ctx, LEDInfo *info) } static void -InitCompatInfo(CompatInfo *info, struct xkb_keymap *keymap, unsigned file_id) +InitCompatInfo(CompatInfo *info, struct xkb_keymap *keymap, unsigned file_id, + ActionsInfo *actions) { info->keymap = keymap; info->name = NULL; info->file_id = file_id; info->errorCount = 0; darray_init(info->interps); - info->act = NULL; + info->actions = actions; info->dflt.file_id = file_id; info->dflt.defined = 0; info->dflt.merge = MERGE_OVERRIDE; @@ -279,8 +280,7 @@ ClearCompatInfo(CompatInfo *info) ClearIndicatorMapInfo(keymap->ctx, &info->ledDflt); darray_free(info->interps); darray_free(info->leds); - FreeActionInfo(info->act); - info->act = NULL; + info->actions = NULL; info->keymap = NULL; ClearVModInfo(&info->vmods); } @@ -551,7 +551,7 @@ HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *stmt) XkbFile *rtrn; CompatInfo included, next_incl; - InitCompatInfo(&included, info->keymap, info->file_id); + InitCompatInfo(&included, info->keymap, info->file_id, info->actions); if (stmt->stmt) { free(included.name); included.name = stmt->stmt; @@ -566,20 +566,17 @@ HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *stmt) return false; } - InitCompatInfo(&next_incl, info->keymap, rtrn->id); + InitCompatInfo(&next_incl, info->keymap, rtrn->id, info->actions); next_incl.file_id = rtrn->id; next_incl.dflt = info->dflt; next_incl.dflt.file_id = rtrn->id; next_incl.dflt.merge = merge; next_incl.ledDflt.file_id = rtrn->id; next_incl.ledDflt.merge = merge; - next_incl.act = info->act; HandleCompatMapFile(&next_incl, rtrn, MERGE_OVERRIDE); MergeIncludedCompatMaps(&included, &next_incl, merge); - if (info->act) - next_incl.act = NULL; ClearCompatInfo(&next_incl); FreeXkbFile(rtrn); @@ -610,7 +607,7 @@ SetInterpField(CompatInfo *info, SymInterpInfo *si, const char *field, if (arrayNdx) return ReportSINotArray(info, si, field); - if (!HandleActionDef(value, keymap, &si->interp.act, info->act)) + if (!HandleActionDef(value, keymap, &si->interp.act, info->actions)) return false; si->defined |= SI_FIELD_ACTION; @@ -821,7 +818,7 @@ HandleGlobalVar(CompatInfo *info, VarDef *stmt) stmt->value); else ret = SetActionField(info->keymap, elem, field, ndx, stmt->value, - &info->act); + info->actions); return ret; } @@ -1095,8 +1092,13 @@ CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge) { CompatInfo info; + ActionsInfo *actions; - InitCompatInfo(&info, keymap, file->id); + actions = NewActionsInfo(); + if (!actions) + return false; + + InitCompatInfo(&info, keymap, file->id, actions); info.dflt.merge = merge; info.ledDflt.merge = merge; @@ -1108,9 +1110,11 @@ CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap, goto err_info; ClearCompatInfo(&info); + FreeActionsInfo(actions); return true; err_info: ClearCompatInfo(&info); + FreeActionsInfo(actions); return false; } diff --git a/src/xkbcomp/symbols.c b/src/xkbcomp/symbols.c index 1741246..09def70 100644 --- a/src/xkbcomp/symbols.c +++ b/src/xkbcomp/symbols.c @@ -188,7 +188,7 @@ typedef struct _SymbolsInfo { darray(KeyInfo) keys; KeyInfo dflt; VModInfo vmods; - ActionInfo *action; + ActionsInfo *actions; xkb_atom_t groupNames[XkbNumKbdGroups]; struct list modMaps; @@ -197,8 +197,8 @@ typedef struct _SymbolsInfo { } SymbolsInfo; static void -InitSymbolsInfo(SymbolsInfo * info, struct xkb_keymap *keymap, - unsigned file_id) +InitSymbolsInfo(SymbolsInfo *info, struct xkb_keymap *keymap, + unsigned file_id, ActionsInfo *actions) { xkb_group_index_t i; @@ -214,7 +214,7 @@ InitSymbolsInfo(SymbolsInfo * info, struct xkb_keymap *keymap, info->groupNames[i] = XKB_ATOM_NONE; InitKeyInfo(&info->dflt, file_id); InitVModInfo(&info->vmods, keymap); - info->action = NULL; + info->actions = actions; info->keymap = keymap; } @@ -745,7 +745,7 @@ HandleIncludeSymbols(SymbolsInfo *info, IncludeStmt *stmt) XkbFile *rtrn; SymbolsInfo included, next_incl; - InitSymbolsInfo(&included, info->keymap, info->file_id); + InitSymbolsInfo(&included, info->keymap, info->file_id, info->actions); if (stmt->stmt) { free(included.name); included.name = stmt->stmt; @@ -760,7 +760,7 @@ HandleIncludeSymbols(SymbolsInfo *info, IncludeStmt *stmt) return false; } - InitSymbolsInfo(&next_incl, info->keymap, rtrn->id); + InitSymbolsInfo(&next_incl, info->keymap, rtrn->id, info->actions); next_incl.merge = next_incl.dflt.merge = MERGE_OVERRIDE; if (stmt->modifier) next_incl.explicit_group = atoi(stmt->modifier) - 1; @@ -998,7 +998,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, toAct = darray_mem(keyi->acts[ndx], 0); act = value->value.child; for (i = 0; i < nActs; i++, toAct++) { - if (!HandleActionDef(act, info->keymap, toAct, info->action)) { + if (!HandleActionDef(act, info->keymap, toAct, info->actions)) { log_err(info->keymap->ctx, "Illegal action definition for %s; " "Action for group %u/level %zu ignored\n", @@ -1256,8 +1256,8 @@ HandleSymbolsVar(SymbolsInfo *info, VarDef *stmt) ret = true; } else { - ret = SetActionField(info->keymap, elem, field, arrayNdx, - stmt->value, &info->action); + ret = SetActionField(info->keymap, elem, field, arrayNdx, stmt->value, + info->actions); } return ret; @@ -1913,10 +1913,15 @@ CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, xkb_group_index_t i; struct xkb_key *key; SymbolsInfo info; + ActionsInfo *actions; KeyInfo *keyi; ModMapEntry *mm; - InitSymbolsInfo(&info, keymap, file->id); + actions = NewActionsInfo(); + if (!actions) + return false; + + InitSymbolsInfo(&info, keymap, file->id, actions); info.dflt.merge = merge; HandleSymbolsFile(&info, file, merge); @@ -1964,9 +1969,11 @@ CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, info.errorCount++; ClearSymbolsInfo(&info); + FreeActionsInfo(actions); return true; err_info: + FreeActionsInfo(actions); ClearSymbolsInfo(&info); return false; }