- register int i;
-
- if (XkbcAllocNames(xkb, XkbVirtualModNamesMask, 0, 0) != Success)
- return;
- if (XkbcAllocServerMap(xkb, XkbVirtualModsMask, 0) != Success)
- return;
- info->xkb = xkb;
- info->newlyDefined = info->defined = info->available = 0;
- if (xkb && xkb->names)
- {
- register int bit;
- for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1)
- {
- if (xkb->names->vmods[i] != None)
- info->defined |= bit;
- }
- }
- return;
-}
-
-/***====================================================================***/
-
-/**
- * Handle one entry in the virtualModifiers line (e.g. NumLock).
- * If the entry is e.g. NumLock=Mod1, stmt->value is not NULL, and the
- * XkbServerMap's vmod is set to the given modifier. Otherwise, the vmod is 0.
- *
- * @param stmt The statement specifying the name and (if any the value).
- * @param mergeMode Merge strategy (e.g. MergeOverride)
- */
-Bool
-HandleVModDef(VModDef * stmt, struct xkb_desc *xkb, unsigned mergeMode,
- VModInfo * info)
-{
- register int i, bit, nextFree;
- ExprResult mod;
- struct xkb_server_map * srv;
- struct xkb_names * names;
-
- srv = xkb->server;
- names = xkb->names;
- for (i = 0, bit = 1, nextFree = -1; i < XkbNumVirtualMods; i++, bit <<= 1)
- {
- if (info->defined & bit)
- {
- if (names->vmods[i] == stmt->name)
- { /* already defined */
- info->available |= bit;
- if (stmt->value == NULL)
- return True;
- else
- {
- const char *str1;
- const char *str2 = "";
- if (!ExprResolveModMask(stmt->value, &mod))
- {
- str1 = XkbcAtomText(stmt->name);
- ACTION("Declaration of %s ignored\n", str1);
- return False;
- }
- if (mod.uval == srv->vmods[i])
- return True;
-
- str1 = XkbcAtomText(stmt->name);
- WARN("Virtual modifier %s multiply defined\n", str1);
- str1 = XkbcModMaskText(srv->vmods[i], True);
- if (mergeMode == MergeOverride)
- {
- str2 = str1;
- str1 = XkbcModMaskText(mod.uval, True);
- }
- ACTION("Using %s, ignoring %s\n", str1, str2);
- if (mergeMode == MergeOverride)
- srv->vmods[i] = mod.uval;
- return True;
- }
- }
+ xkb_mod_index_t i;
+ struct xkb_mod *mod;
+ xkb_mod_mask_t mapping;
+
+ merge = (merge == MERGE_DEFAULT ? stmt->merge : merge);
+
+ if (stmt->value) {
+ /*
+ * This is a statement such as 'virtualModifiers NumLock = Mod1';
+ * it sets the vmod-to-real-mod[s] mapping directly instead of going
+ * through modifier_map or some such.
+ */
+ if (!ExprResolveModMask(ctx, stmt->value, MOD_REAL, mods, &mapping)) {
+ log_err(ctx,
+ "Declaration of %s ignored\n",
+ xkb_atom_text(ctx, stmt->name));
+ return false;