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[] = {
/***====================================================================***/
-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;
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
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;
-
- new = malloc(sizeof(*new));
- if (!new) {
- log_wsgo(keymap->ctx, "Couldn't allocate space for action default\n");
- goto err;
- }
+ unsigned action;
+ enum action_field action_field;
- if (!stringToAction(elem, &new->action))
- goto err;
+ if (!stringToAction(elem, &action))
+ return false;
- 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);
}
#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[];
LEDInfo ledDflt;
darray(LEDInfo) leds;
VModInfo vmods;
- ActionInfo *act;
+ ActionsInfo *actions;
struct xkb_keymap *keymap;
} CompatInfo;
}
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;
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);
}
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;
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);
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;
stmt->value);
else
ret = SetActionField(info->keymap, elem, field, ndx, stmt->value,
- &info->act);
+ info->actions);
return ret;
}
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;
goto err_info;
ClearCompatInfo(&info);
+ FreeActionsInfo(actions);
return true;
err_info:
ClearCompatInfo(&info);
+ FreeActionsInfo(actions);
return false;
}
darray(KeyInfo) keys;
KeyInfo dflt;
VModInfo vmods;
- ActionInfo *action;
+ ActionsInfo *actions;
xkb_atom_t groupNames[XkbNumKbdGroups];
struct list modMaps;
} 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;
info->groupNames[i] = XKB_ATOM_NONE;
InitKeyInfo(&info->dflt, file_id);
InitVModInfo(&info->vmods, keymap);
- info->action = NULL;
+ info->actions = actions;
info->keymap = keymap;
}
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;
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;
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",
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;
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);
info.errorCount++;
ClearSymbolsInfo(&info);
+ FreeActionsInfo(actions);
return true;
err_info:
+ FreeActionsInfo(actions);
ClearSymbolsInfo(&info);
return false;
}