X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fxkbcomp%2Fexpr.c;h=558fef3ef51849c5f419076034c84e3c811e36a4;hb=eafd3aceca97d4984070115ec67f639b045b0d65;hp=a66729bb93e7cfb0954ef88a4451ad48cb46ea12;hpb=6974e1f9acc42a946203a48c3a57d8bbb19e3316;p=platform%2Fupstream%2Flibxkbcommon.git diff --git a/src/xkbcomp/expr.c b/src/xkbcomp/expr.c index a66729b..558fef3 100644 --- a/src/xkbcomp/expr.c +++ b/src/xkbcomp/expr.c @@ -24,9 +24,12 @@ * ********************************************************/ +#include "config.h" + #include "xkbcomp-priv.h" #include "text.h" #include "expr.h" +#include "keysym.h" typedef bool (*IdentLookupFunc)(struct xkb_context *ctx, const void *priv, xkb_atom_t field, enum expr_value_type type, @@ -37,26 +40,30 @@ ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr, const char **elem_rtrn, const char **field_rtrn, ExprDef **index_rtrn) { - switch (expr->op) { + switch (expr->expr.op) { case EXPR_IDENT: *elem_rtrn = NULL; - *field_rtrn = xkb_atom_text(ctx, expr->value.str); + *field_rtrn = xkb_atom_text(ctx, expr->ident.ident); *index_rtrn = NULL; - return true; + return (*field_rtrn != NULL); case EXPR_FIELD_REF: - *elem_rtrn = xkb_atom_text(ctx, expr->value.field.element); - *field_rtrn = xkb_atom_text(ctx, expr->value.field.field); + *elem_rtrn = xkb_atom_text(ctx, expr->field_ref.element); + *field_rtrn = xkb_atom_text(ctx, expr->field_ref.field); *index_rtrn = NULL; - return true; + return (*elem_rtrn != NULL && *field_rtrn != NULL); case EXPR_ARRAY_REF: - *elem_rtrn = xkb_atom_text(ctx, expr->value.array.element); - *field_rtrn = xkb_atom_text(ctx, expr->value.array.field); - *index_rtrn = expr->value.array.entry; + *elem_rtrn = xkb_atom_text(ctx, expr->array_ref.element); + *field_rtrn = xkb_atom_text(ctx, expr->array_ref.field); + *index_rtrn = expr->array_ref.entry; + if (expr->array_ref.element != XKB_ATOM_NONE && *elem_rtrn == NULL) + return false; + if (*field_rtrn == NULL) + return false; return true; default: break; } - log_wsgo(ctx, "Unexpected operator %d in ResolveLhs\n", expr->op); + log_wsgo(ctx, "Unexpected operator %d in ResolveLhs\n", expr->expr.op); return false; } @@ -81,14 +88,11 @@ SimpleLookup(struct xkb_context *ctx, const void *priv, xkb_atom_t field, return false; } -static bool -LookupModIndex(struct xkb_context *ctx, const void *priv, xkb_atom_t field, - enum expr_value_type type, xkb_mod_index_t *val_rtrn) -{ - const char *name = xkb_atom_text(ctx, field); - *val_rtrn = ModNameToIndex(name); - return (*val_rtrn != XKB_MOD_INVALID); -} +/* Data passed in the *priv argument for LookupModMask. */ +typedef struct { + const struct xkb_mod_set *mods; + enum mod_type mod_type; +} LookupModMaskPriv; static bool LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field, @@ -96,21 +100,32 @@ LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field, { const char *str; xkb_mod_index_t ndx; + const LookupModMaskPriv *arg = priv; + const struct xkb_mod_set *mods = arg->mods; + enum mod_type mod_type = arg->mod_type; if (type != EXPR_TYPE_INT) return false; str = xkb_atom_text(ctx, field); + if (!str) + return false; + + if (istreq(str, "all")) { + *val_rtrn = MOD_REAL_MASK_ALL; + return true; + } - if (istreq(str, "all")) - *val_rtrn = 0xff; - else if (istreq(str, "none")) + if (istreq(str, "none")) { *val_rtrn = 0; - else if (LookupModIndex(ctx, priv, field, type, &ndx)) - *val_rtrn = (1 << ndx); - else + return true; + } + + ndx = XkbModNameToIndex(mods, field, mod_type); + if (ndx == XKB_MOD_INVALID) return false; + *val_rtrn = (1u << ndx); return true; } @@ -121,19 +136,19 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr, bool ok = false; const char *ident; - switch (expr->op) { + switch (expr->expr.op) { case EXPR_VALUE: - if (expr->value_type != EXPR_TYPE_BOOLEAN) { + if (expr->expr.value_type != EXPR_TYPE_BOOLEAN) { log_err(ctx, "Found constant of type %s where boolean was expected\n", - expr_value_type_to_string(expr->value_type)); + expr_value_type_to_string(expr->expr.value_type)); return false; } - *set_rtrn = !!expr->value.ival; + *set_rtrn = expr->boolean.set; return true; case EXPR_IDENT: - ident = xkb_atom_text(ctx, expr->value.str); + ident = xkb_atom_text(ctx, expr->ident.ident); if (ident) { if (istreq(ident, "true") || istreq(ident, "yes") || @@ -148,19 +163,18 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr, return true; } } - log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n", - xkb_atom_text(ctx, expr->value.str)); + log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n", ident); return false; case EXPR_FIELD_REF: log_err(ctx, "Default \"%s.%s\" of type boolean is unknown\n", - xkb_atom_text(ctx, expr->value.field.element), - xkb_atom_text(ctx, expr->value.field.field)); + xkb_atom_text(ctx, expr->field_ref.element), + xkb_atom_text(ctx, expr->field_ref.field)); return false; case EXPR_INVERT: case EXPR_NOT: - ok = ExprResolveBoolean(ctx, expr, set_rtrn); + ok = ExprResolveBoolean(ctx, expr->unary.child, set_rtrn); if (ok) *set_rtrn = !*set_rtrn; return ok; @@ -171,12 +185,16 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr, case EXPR_ASSIGN: case EXPR_NEGATE: case EXPR_UNARY_PLUS: + case EXPR_ACTION_DECL: + case EXPR_ACTION_LIST: + case EXPR_KEYSYM_LIST: log_err(ctx, "%s of boolean values not permitted\n", - expr_op_type_to_string(expr->op)); + expr_op_type_to_string(expr->expr.op)); break; default: - log_wsgo(ctx, "Unknown operator %d in ResolveBoolean\n", expr->op); + log_wsgo(ctx, "Unknown operator %d in ResolveBoolean\n", + expr->expr.op); break; } @@ -188,32 +206,28 @@ ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr, xkb_keycode_t *kc) { xkb_keycode_t leftRtrn, rightRtrn; - ExprDef *left, *right; - switch (expr->op) { + switch (expr->expr.op) { case EXPR_VALUE: - if (expr->value_type != EXPR_TYPE_INT) { + if (expr->expr.value_type != EXPR_TYPE_INT) { log_err(ctx, "Found constant of type %s where an int was expected\n", - expr_value_type_to_string(expr->value_type)); + expr_value_type_to_string(expr->expr.value_type)); return false; } - *kc = expr->value.uval; + *kc = (xkb_keycode_t) expr->integer.ival; return true; case EXPR_ADD: case EXPR_SUBTRACT: case EXPR_MULTIPLY: case EXPR_DIVIDE: - left = expr->value.binary.left; - right = expr->value.binary.right; - - if (!ExprResolveKeyCode(ctx, left, &leftRtrn) || - !ExprResolveKeyCode(ctx, right, &rightRtrn)) + if (!ExprResolveKeyCode(ctx, expr->binary.left, &leftRtrn) || + !ExprResolveKeyCode(ctx, expr->binary.right, &rightRtrn)) return false; - switch (expr->op) { + switch (expr->expr.op) { case EXPR_ADD: *kc = leftRtrn + rightRtrn; break; @@ -239,19 +253,18 @@ ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr, return true; case EXPR_NEGATE: - left = expr->value.child; - if (!ExprResolveKeyCode(ctx, left, &leftRtrn)) + if (!ExprResolveKeyCode(ctx, expr->unary.child, &leftRtrn)) return false; *kc = ~leftRtrn; return true; case EXPR_UNARY_PLUS: - left = expr->value.child; - return ExprResolveKeyCode(ctx, left, kc); + return ExprResolveKeyCode(ctx, expr->unary.child, kc); default: - log_wsgo(ctx, "Unknown operator %d in ResolveKeyCode\n", expr->op); + log_wsgo(ctx, "Unknown operator %d in ResolveKeyCode\n", + expr->expr.op); break; } @@ -278,25 +291,25 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr, unsigned u; ExprDef *left, *right; - switch (expr->op) { + switch (expr->expr.op) { case EXPR_VALUE: - if (expr->value_type != EXPR_TYPE_INT) { + if (expr->expr.value_type != EXPR_TYPE_INT) { log_err(ctx, "Found constant of type %s where an int was expected\n", - expr_value_type_to_string(expr->value_type)); + expr_value_type_to_string(expr->expr.value_type)); return false; } - *val_rtrn = expr->value.ival; + *val_rtrn = expr->integer.ival; return true; case EXPR_IDENT: if (lookup) - ok = lookup(ctx, lookupPriv, expr->value.str, EXPR_TYPE_INT, &u); + ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT, &u); if (!ok) log_err(ctx, "Identifier \"%s\" of type int is unknown\n", - xkb_atom_text(ctx, expr->value.str)); + xkb_atom_text(ctx, expr->ident.ident)); else *val_rtrn = (int) u; @@ -304,21 +317,21 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr, case EXPR_FIELD_REF: log_err(ctx, "Default \"%s.%s\" of type int is unknown\n", - xkb_atom_text(ctx, expr->value.field.element), - xkb_atom_text(ctx, expr->value.field.field)); + xkb_atom_text(ctx, expr->field_ref.element), + xkb_atom_text(ctx, expr->field_ref.field)); return false; case EXPR_ADD: case EXPR_SUBTRACT: case EXPR_MULTIPLY: case EXPR_DIVIDE: - left = expr->value.binary.left; - right = expr->value.binary.right; + left = expr->binary.left; + right = expr->binary.right; if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv) || !ExprResolveIntegerLookup(ctx, right, &r, lookup, lookupPriv)) return false; - switch (expr->op) { + switch (expr->expr.op) { case EXPR_ADD: *val_rtrn = l + r; break; @@ -336,7 +349,9 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr, *val_rtrn = l / r; break; default: - break; + log_err(ctx, "%s of integers not permitted\n", + expr_op_type_to_string(expr->expr.op)); + return false; } return true; @@ -351,20 +366,21 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr, case EXPR_INVERT: case EXPR_NEGATE: - left = expr->value.child; + left = expr->unary.child; if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv)) return false; - *val_rtrn = (expr->op == EXPR_NEGATE ? -l : ~l); + *val_rtrn = (expr->expr.op == EXPR_NEGATE ? -l : ~l); return true; case EXPR_UNARY_PLUS: - left = expr->value.child; + left = expr->unary.child; return ExprResolveIntegerLookup(ctx, left, val_rtrn, lookup, lookupPriv); default: - log_wsgo(ctx, "Unknown operator %d in ResolveInteger\n", expr->op); + log_wsgo(ctx, "Unknown operator %d in ResolveInteger\n", + expr->expr.op); break; } @@ -390,9 +406,10 @@ ExprResolveGroup(struct xkb_context *ctx, const ExprDef *expr, if (!ok) return false; - if (result <= 0 || result > XKB_NUM_GROUPS) { - log_err(ctx, "Group index %u is out of range (1..%d)\n", - result, XKB_NUM_GROUPS); + if (result <= 0 || result > XKB_MAX_GROUPS) { + log_err_with_code(ctx, XKB_ERROR_UNSUPPORTED_GROUP_INDEX, + "Group index %u is out of range (1..%d)\n", + result, XKB_MAX_GROUPS); return false; } @@ -413,7 +430,8 @@ ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr, return false; if (result < 1) { - log_err(ctx, "Shift level %d is out of range\n", result); + log_err_with_code(ctx, XKB_ERROR_UNSUPPORTED_SHIFT_LEVEL, + "Shift level %d is out of range\n", result); return false; } @@ -425,40 +443,34 @@ ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr, bool ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, int *btn_rtrn) { - int result; - - if (!ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup, - buttonNames)) - return false; - - *btn_rtrn = result; - return true; + return ExprResolveIntegerLookup(ctx, expr, btn_rtrn, SimpleLookup, + buttonNames); } bool ExprResolveString(struct xkb_context *ctx, const ExprDef *expr, xkb_atom_t *val_rtrn) { - switch (expr->op) { + switch (expr->expr.op) { case EXPR_VALUE: - if (expr->value_type != EXPR_TYPE_STRING) { + if (expr->expr.value_type != EXPR_TYPE_STRING) { log_err(ctx, "Found constant of type %s, expected a string\n", - expr_value_type_to_string(expr->value_type)); + expr_value_type_to_string(expr->expr.value_type)); return false; } - *val_rtrn = expr->value.str; + *val_rtrn = expr->string.str; return true; case EXPR_IDENT: log_err(ctx, "Identifier \"%s\" of type string not found\n", - xkb_atom_text(ctx, expr->value.str)); + xkb_atom_text(ctx, expr->ident.ident)); return false; case EXPR_FIELD_REF: log_err(ctx, "Default \"%s.%s\" of type string not found\n", - xkb_atom_text(ctx, expr->value.field.element), - xkb_atom_text(ctx, expr->value.field.field)); + xkb_atom_text(ctx, expr->field_ref.element), + xkb_atom_text(ctx, expr->field_ref.field)); return false; case EXPR_ADD: @@ -470,12 +482,16 @@ ExprResolveString(struct xkb_context *ctx, const ExprDef *expr, case EXPR_INVERT: case EXPR_NOT: case EXPR_UNARY_PLUS: + case EXPR_ACTION_DECL: + case EXPR_ACTION_LIST: + case EXPR_KEYSYM_LIST: log_err(ctx, "%s of strings not permitted\n", - expr_op_type_to_string(expr->op)); + expr_op_type_to_string(expr->expr.op)); return false; default: - log_wsgo(ctx, "Unknown operator %d in ResolveString\n", expr->op); + log_wsgo(ctx, "Unknown operator %d in ResolveString\n", + expr->expr.op); break; } return false; @@ -485,16 +501,16 @@ bool ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr, unsigned int *val_rtrn, const LookupEntry *values) { - if (expr->op != EXPR_IDENT) { + if (expr->expr.op != EXPR_IDENT) { log_err(ctx, "Found a %s where an enumerated value was expected\n", - expr_op_type_to_string(expr->op)); + expr_op_type_to_string(expr->expr.op)); return false; } - if (!SimpleLookup(ctx, values, expr->value.str, EXPR_TYPE_INT, + if (!SimpleLookup(ctx, values, expr->ident.ident, EXPR_TYPE_INT, val_rtrn)) { log_err(ctx, "Illegal identifier %s; expected one of:\n", - xkb_atom_text(ctx, expr->value.str)); + xkb_atom_text(ctx, expr->ident.ident)); while (values && values->name) { log_err(ctx, "\t%s\n", values->name); @@ -511,40 +527,40 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr, unsigned int *val_rtrn, IdentLookupFunc lookup, const void *lookupPriv) { - bool ok = 0; - unsigned int l, r; + bool ok = false; + unsigned int l = 0, r = 0; int v; ExprDef *left, *right; const char *bogus = NULL; - switch (expr->op) { + switch (expr->expr.op) { case EXPR_VALUE: - if (expr->value_type != EXPR_TYPE_INT) { + if (expr->expr.value_type != EXPR_TYPE_INT) { log_err(ctx, "Found constant of type %s where a mask was expected\n", - expr_value_type_to_string(expr->value_type)); + expr_value_type_to_string(expr->expr.value_type)); return false; } - *val_rtrn = (unsigned int) expr->value.ival; + *val_rtrn = (unsigned int) expr->integer.ival; return true; case EXPR_IDENT: - ok = lookup(ctx, lookupPriv, expr->value.str, EXPR_TYPE_INT, + ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT, val_rtrn); if (!ok) log_err(ctx, "Identifier \"%s\" of type int is unknown\n", - xkb_atom_text(ctx, expr->value.str)); + xkb_atom_text(ctx, expr->ident.ident)); return ok; case EXPR_FIELD_REF: log_err(ctx, "Default \"%s.%s\" of type int is unknown\n", - xkb_atom_text(ctx, expr->value.field.element), - xkb_atom_text(ctx, expr->value.field.field)); + xkb_atom_text(ctx, expr->field_ref.element), + xkb_atom_text(ctx, expr->field_ref.field)); return false; case EXPR_ARRAY_REF: bogus = "array reference"; - + /* fallthrough */ case EXPR_ACTION_DECL: if (bogus == NULL) bogus = "function use"; @@ -557,13 +573,13 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr, case EXPR_SUBTRACT: case EXPR_MULTIPLY: case EXPR_DIVIDE: - left = expr->value.binary.left; - right = expr->value.binary.right; + left = expr->binary.left; + right = expr->binary.right; if (!ExprResolveMaskLookup(ctx, left, &l, lookup, lookupPriv) || !ExprResolveMaskLookup(ctx, right, &r, lookup, lookupPriv)) return false; - switch (expr->op) { + switch (expr->expr.op) { case EXPR_ADD: *val_rtrn = l | r; break; @@ -573,7 +589,7 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr, case EXPR_MULTIPLY: case EXPR_DIVIDE: log_err(ctx, "Cannot %s masks; Illegal operation ignored\n", - (expr->op == EXPR_DIVIDE ? "divide" : "multiply")); + (expr->expr.op == EXPR_DIVIDE ? "divide" : "multiply")); return false; default: break; @@ -586,7 +602,7 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr, break; case EXPR_INVERT: - left = expr->value.child; + left = expr->unary.child; if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv)) return false; @@ -596,14 +612,15 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr, case EXPR_UNARY_PLUS: case EXPR_NEGATE: case EXPR_NOT: - left = expr->value.child; + left = expr->unary.child; if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv)) log_err(ctx, "The %s operator cannot be used with a mask\n", - (expr->op == EXPR_NEGATE ? "-" : "!")); + (expr->expr.op == EXPR_NEGATE ? "-" : "!")); return false; default: - log_wsgo(ctx, "Unknown operator %d in ResolveMask\n", expr->op); + log_wsgo(ctx, "Unknown operator %d in ResolveMask\n", + expr->expr.op); break; } @@ -619,55 +636,11 @@ ExprResolveMask(struct xkb_context *ctx, const ExprDef *expr, bool ExprResolveModMask(struct xkb_context *ctx, const ExprDef *expr, + enum mod_type mod_type, const struct xkb_mod_set *mods, xkb_mod_mask_t *mask_rtrn) { - return ExprResolveMaskLookup(ctx, expr, mask_rtrn, LookupModMask, NULL); -} - -static bool -LookupVModIndex(const struct xkb_keymap *keymap, xkb_atom_t field, - enum expr_value_type type, xkb_mod_index_t *val_rtrn) -{ - const struct xkb_vmod *vmod; - xkb_mod_index_t i; - - if (type != EXPR_TYPE_INT) - return false; - - darray_enumerate(i, vmod, keymap->vmods) { - if (vmod->name == field) { - *val_rtrn = i; - return true; - } - } - - return false; -} - -static bool -LookupVModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field, - enum expr_value_type type, xkb_mod_mask_t *val_rtrn) -{ - xkb_mod_index_t ndx; - - if (LookupModMask(ctx, NULL, field, type, val_rtrn)) { - return true; - } - else if (LookupVModIndex(priv, field, type, &ndx)) { - *val_rtrn = (1 << (XKB_NUM_CORE_MODS + ndx)); - return true; - } - - return false; -} - - -bool -ExprResolveVModMask(struct xkb_keymap *keymap, const ExprDef *expr, - xkb_mod_mask_t *mask_rtrn) -{ - return ExprResolveMaskLookup(keymap->ctx, expr, mask_rtrn, LookupVModMask, - keymap); + LookupModMaskPriv priv = { .mods = mods, .mod_type = mod_type }; + return ExprResolveMaskLookup(ctx, expr, mask_rtrn, LookupModMask, &priv); } bool @@ -676,10 +649,9 @@ ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr, { int val; - if (expr->op == EXPR_IDENT) { - const char *str; - str = xkb_atom_text(ctx, expr->value.str); - *sym_rtrn = xkb_keysym_from_name(str); + if (expr->expr.op == EXPR_IDENT) { + const char *str = xkb_atom_text(ctx, expr->ident.ident); + *sym_rtrn = xkb_keysym_from_name(str, 0); if (*sym_rtrn != XKB_KEY_NoSymbol) return true; } @@ -687,39 +659,60 @@ ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr, if (!ExprResolveInteger(ctx, expr, &val)) return false; - if (val < 0 || val >= 10) + if (val < XKB_KEYSYM_MIN) { + log_warn_with_code(ctx, XKB_WARNING_UNRECOGNIZED_KEYSYM, + "unrecognized keysym \"-0x%x\" (%d)\n", + (unsigned int) -val, val); return false; + } + + /* Special case for digits 0..9 */ + if (val < 10) { + *sym_rtrn = XKB_KEY_0 + (xkb_keysym_t) val; + return true; + } + + if (val <= XKB_KEYSYM_MAX) { + log_warn_with_code(ctx, XKB_WARNING_NUMERIC_KEYSYM, + "numeric keysym \"0x%x\" (%d)", + (unsigned int) val, val); + *sym_rtrn = (xkb_keysym_t) val; + return true; + } + + log_warn_with_code(ctx, XKB_WARNING_UNRECOGNIZED_KEYSYM, + "unrecognized keysym \"0x%x\" (%d)\n", + (unsigned int) val, val); + return false; - *sym_rtrn = ((xkb_keysym_t) val) + '0'; - return true; } bool -ExprResolveVMod(struct xkb_keymap *keymap, const ExprDef *def, - xkb_mod_index_t *ndx_rtrn) +ExprResolveMod(struct xkb_context *ctx, const ExprDef *def, + enum mod_type mod_type, const struct xkb_mod_set *mods, + xkb_mod_index_t *ndx_rtrn) { - const struct xkb_vmod *vmod; - xkb_mod_index_t i; - xkb_atom_t name = def->value.str; + xkb_mod_index_t ndx; + xkb_atom_t name; - if (def->op != EXPR_IDENT) { - log_err(keymap->ctx, + if (def->expr.op != EXPR_IDENT) { + log_err(ctx, "Cannot resolve virtual modifier: " "found %s where a virtual modifier name was expected\n", - expr_op_type_to_string(def->op)); + expr_op_type_to_string(def->expr.op)); return false; } - darray_enumerate(i, vmod, keymap->vmods) { - if (vmod->name == name) { - *ndx_rtrn = i; - return true; - } + name = def->ident.ident; + ndx = XkbModNameToIndex(mods, name, mod_type); + if (ndx == XKB_MOD_INVALID) { + log_err(ctx, + "Cannot resolve virtual modifier: " + "\"%s\" was not previously declared\n", + xkb_atom_text(ctx, name)); + return false; } - log_err(keymap->ctx, - "Cannot resolve virtual modifier: " - "\"%s\" was not previously declared\n", - xkb_atom_text(keymap->ctx, name)); - return false; + *ndx_rtrn = ndx; + return true; }