vmod: bring back support for direct vmod -> real mod mapping

This brings back the functionality that was removed in
b9c87eb710. Though it is not used in
xkeyboard-config, from our current perspective it can be quite useful to
be able to set the mappings directly, thus sidestepping the ugly and
legacy-ridden modifier_map statement.

Here's an example of how to get rid of modifier_map statements (though
that would break core-X11 applications, since they must have the
mappings through keysyms):
    virtual_modifiers NumLock = Mod2;
    virtual_modifiers Alt = Mod1;
    // Would be nice to map these to Alt, but that would be
    // incompatible with xkbcomp and somewhat complicated
    virtual_modifiers LAlt = Mod1;
    virtual_modifiers RAlt = Mod1;
    virtual_modifiers LevelThree = Mod5;
    virtual_modifiers RControl = Control;
    virtual_modifiers LControl = Control;
    virtual_modifiers Super = Mod4;
    virtual_modifiers Meta = Mod1;
    virtual_modifiers Hyper = Mod4;
    virtual_modifiers AltGr = Mod5;
    virtual_modifiers LShift = Shift;
    virtual_modifiers RShift = Shift;

Signed-off-by: Ran Benita <ran234@gmail.com>
master
Ran Benita 2012-11-27 10:42:15 +02:00
parent aed3469474
commit 5bd273a724
5 changed files with 55 additions and 17 deletions

View File

@ -768,7 +768,7 @@ HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge)
ok = HandleGlobalVar(info, (VarDef *) stmt); ok = HandleGlobalVar(info, (VarDef *) stmt);
break; break;
case STMT_VMOD: case STMT_VMOD:
ok = HandleVModDef(info->keymap, (VModDef *) stmt); ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge);
break; break;
default: default:
log_err(info->keymap->ctx, log_err(info->keymap->ctx,

View File

@ -1203,7 +1203,7 @@ HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge)
ok = HandleGlobalVar(info, (VarDef *) stmt); ok = HandleGlobalVar(info, (VarDef *) stmt);
break; break;
case STMT_VMOD: case STMT_VMOD:
ok = HandleVModDef(info->keymap, (VModDef *) stmt); ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge);
break; break;
case STMT_MODMAP: case STMT_MODMAP:
ok = HandleModMapDef(info, (ModMapDef *) stmt); ok = HandleModMapDef(info, (ModMapDef *) stmt);

View File

@ -639,7 +639,7 @@ HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
ok = true; ok = true;
break; break;
case STMT_VMOD: case STMT_VMOD:
ok = HandleVModDef(info->keymap, (VModDef *) stmt); ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge);
break; break;
default: default:
log_err(info->keymap->ctx, log_err(info->keymap->ctx,

View File

@ -30,27 +30,64 @@
#include "vmod.h" #include "vmod.h"
bool bool
HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt) HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt,
enum merge_mode merge)
{ {
xkb_mod_index_t i; xkb_mod_index_t i;
const struct xkb_mod *mod; struct xkb_mod *mod;
xkb_mod_mask_t mapping;
struct xkb_mod new; struct xkb_mod new;
if (stmt->value) merge = (merge == MERGE_DEFAULT ? stmt->merge : merge);
log_err(keymap->ctx,
"Support for setting a value in a virtual_modifiers statement has been removed; " if (stmt->value) {
"Value ignored\n"); /*
* 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(keymap, stmt->value, MOD_REAL, &mapping)) {
log_err(keymap->ctx,
"Declaration of %s ignored\n",
xkb_atom_text(keymap->ctx, stmt->name));
return false;
}
}
else {
mapping = 0;
}
darray_enumerate(i, mod, keymap->mods) { darray_enumerate(i, mod, keymap->mods) {
if (mod->name == stmt->name) { if (mod->name == stmt->name) {
if (mod->type == MOD_VIRT) if (mod->type != MOD_VIRT) {
log_err(keymap->ctx,
"Can't add a virtual modifier named \"%s\"; "
"there is already a non-virtual modifier with this name! Ignored\n",
xkb_atom_text(keymap->ctx, mod->name));
return false;
}
if (mod->mapping == mapping)
return true; return true;
log_err(keymap->ctx, if (mod->mapping != 0) {
"Can't add a virtual modifier named \"%s\"; " xkb_mod_mask_t use, ignore;
"there is already a non-virtual modifier with this name! Ignored\n",
xkb_atom_text(keymap->ctx, mod->name)); use = (merge == MERGE_OVERRIDE ? mapping : mod->mapping);
return false; ignore = (merge == MERGE_OVERRIDE ? mod->mapping : mapping);
log_warn(keymap->ctx,
"Virtual modifier %s defined multiple times; "
"Using %s, ignoring %s\n",
xkb_atom_text(keymap->ctx, stmt->name),
ModMaskText(keymap, use),
ModMaskText(keymap, ignore));
mapping = use;
}
mod->mapping = mapping;
return true;
} }
} }
@ -62,7 +99,7 @@ HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt)
} }
new.name = stmt->name; new.name = stmt->name;
new.mapping = 0; new.mapping = mapping;
new.type = MOD_VIRT; new.type = MOD_VIRT;
darray_append(keymap->mods, new); darray_append(keymap->mods, new);
return true; return true;

View File

@ -28,6 +28,7 @@
#define XKBCOMP_VMOD_H #define XKBCOMP_VMOD_H
bool bool
HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt); HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt,
enum merge_mode merge);
#endif #endif