action: keep array of default actions, instead of list of changes
The implementation of changing the default properties of actions, e.g. a statements such as (from test/data/compat/basic): setMods.clearLocks= True; latchMods.clearLocks= True; latchMods.latchToLock= True; works by keeping a list of ActionInfo's, each containing the neccesary info from each statement, and then when some action comes up (e.g. in an interpret statment) it goes through the list, and applies the relevent ActionInfo's to the newly-constructed xkb_action. Instead of doing this, we add a struct ActionsInfo, which contains an array of xkb_actions, one for each type. When a default changing statement appears, we change the action in the array; when a new action comes up, we just copy from the array. This is simpler to figure out, and pretty straightforward. Signed-off-by: Ran Benita <ran234@gmail.com>master
parent
4ca85c7b3b
commit
87bfd97333
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!stringToField(field, &new->field)) {
|
||||
log_err(keymap->ctx, "\"%s\" is not a legal field name\n", field);
|
||||
goto err;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!stringToField(field, &action_field)) {
|
||||
log_err(keymap->ctx, "\"%s\" is not a legal field name\n", field);
|
||||
return false;
|
||||
}
|
||||
|
||||
return handleAction[action](keymap, &info->actions[action],
|
||||
action_field, array_ndx, value);
|
||||
}
|
||||
|
|
|
@ -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[];
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue