Modernize struct xkb_mods

Currently xkb_mods has the following members:
- uint8_t real_mods - 8 X11 core mods
- xkb_mod_mask_t vmods - 16 virtual mods, zero-based index
- xkb_mod_mask_t mask - the computed effective *real* modifier mask,
  basically a cache for the first two which is:
  real_mods | real mods computed from vmods

Our API acts on masks which combine the real_mods and vmods into a
single value, which is:
8 first bits real mods | 16 next bits virtual mods
(XkbNumModifiers = 8, XkbNumVirtualMods = 16). This is also the format
which ResolveVModMask uses (which is where all the modifier masks really
"come from", e.g. "Shift+Lock+Level5" -> xkb_mod_mask_t).

What the code does now after getting the mask from ResolveVModMask, is
to break it into real part and virtual part and store them seperately,
and then join them back together when the effective mask is calculated.

This is all pretty useless work. We change xkb_mods to the following:
- xkb_mod_mask_t mods - usually what ResolveVModMask returns
- xkb_mod_mask_t mask - the computed mask cache
And try to consistently use the word "mods" for the original,
non-effective mods and mask for the effective mods (which can only
contain real mods for now, because things break otherwise).

The separation is also made clearer. The effective masks are computed by
UpdateModifiersFromCompat after all the sections have been compiled;
before this the mask field is never touched; after this (i.e. map.c and
state.c) the original mods field is never touched. This single execption
to this rule is keymap-dump.c: it needs to print out only the original
modifiers, not computed ones. This is also the reason why we actually
keep two fields instead keeping one and modifying it in place.

The next logical step is probably to turn the real mods into vmods
themselves, and get rid of the distinction entirely (in a compatible
way).

Signed-off-by: Ran Benita <ran234@gmail.com>
master
Ran Benita 2012-08-09 02:33:51 +03:00
parent 45cd92b4d3
commit 07b18bde17
10 changed files with 158 additions and 238 deletions

View File

@ -311,8 +311,7 @@ write_types(struct xkb_keymap *keymap, struct buf *buf)
write_buf(buf, "\t\ttype \"%s\" {\n",
xkb_atom_text(keymap->ctx, type->name));
write_buf(buf, "\t\t\tmodifiers= %s;\n",
VModMaskText(keymap, type->mods.real_mods,
type->mods.vmods));
VModMaskText(keymap, type->mods.mods));
for (j = 0; j < type->num_entries; j++) {
const char *str;
@ -322,21 +321,18 @@ write_types(struct xkb_keymap *keymap, struct buf *buf)
* Printing level 1 entries is redundant, it's the default,
* unless there's preserve info.
*/
if (entry->level == 0 && entry->preserve.mask == 0)
if (entry->level == 0 && entry->preserve.mods == 0)
continue;
str = VModMaskText(keymap, entry->mods.real_mods,
entry->mods.vmods);
str = VModMaskText(keymap, entry->mods.mods);
write_buf(buf, "\t\t\tmap[%s]= Level%d;\n",
str, entry->level + 1);
if (!entry->preserve.real_mods && !entry->preserve.vmods)
if (entry->preserve.mods == 0)
continue;
write_buf(buf, "\t\t\tpreserve[%s]= ", str);
write_buf(buf, "%s;\n",
VModMaskText(keymap, entry->preserve.real_mods,
entry->preserve.vmods));
write_buf(buf, "%s;\n", VModMaskText(keymap, entry->preserve.mods));
}
if (type->level_names) {
@ -377,8 +373,7 @@ write_indicator_map(struct xkb_keymap *keymap, struct buf *buf, int num)
get_indicator_state_text(led->which_mods));
}
write_buf(buf, "\t\t\tmodifiers= %s;\n",
VModMaskText(keymap, led->mods.real_mods,
led->mods.vmods));
VModMaskText(keymap, led->mods.mods));
}
if (led->ctrls) {
@ -411,8 +406,7 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
if (action->mods.flags & XkbSA_UseModMapMods)
args = "modMapMods";
else
args = VModMaskText(keymap, action->mods.real_mods,
action->mods.vmods);
args = VModMaskText(keymap, action->mods.mods.mods);
write_buf(buf, "%s%s(modifiers=%s%s%s)%s", prefix, type, args,
(action->any.type != XkbSA_LockGroup &&
(action->mods.flags & XkbSA_ClearLocks)) ?
@ -567,7 +561,7 @@ write_compat(struct xkb_keymap *keymap, struct buf *buf)
write_buf(buf, "\t\tinterpret %s+%s(%s) {\n",
keysym_name,
SIMatchText(interp->match),
VModMaskText(keymap, interp->mods, 0));
VModMaskText(keymap, interp->mods));
if (interp->virtual_mod != XkbNoModifier) {
write_buf(buf, "\t\t\tvirtualModifier= %s;\n",
@ -590,18 +584,17 @@ write_compat(struct xkb_keymap *keymap, struct buf *buf)
struct xkb_mods *gc;
gc = &keymap->groups[i];
if (gc->real_mods == 0 && gc->vmods == 0)
if (gc->mods == 0)
continue;
write_buf(buf, "\t\tgroup %d = %s;\n", i + 1,
VModMaskText(keymap, gc->real_mods, gc->vmods));
VModMaskText(keymap, gc->mods));
}
for (i = 0; i < XkbNumIndicators; i++) {
struct xkb_indicator_map *map = &keymap->indicators[i];
if (map->flags == 0 && map->which_groups == 0 &&
map->groups == 0 && map->which_mods == 0 &&
map->mods.real_mods == 0 && map->mods.vmods == 0 &&
map->ctrls == 0)
map->mods.mods == 0 && map->ctrls == 0)
continue;
write_indicator_map(keymap, buf, i);
}
@ -722,8 +715,9 @@ write_symbols(struct xkb_keymap *keymap, struct buf *buf)
}
if (key->vmodmap && (key->explicit & XkbExplicitVModMapMask)) {
/* XXX: vmodmap cmask? */
write_buf(buf, "\n\t\t\tvirtualMods= %s,",
VModMaskText(keymap, 0, key->vmodmap));
VModMaskText(keymap, key->vmodmap << XkbNumModifiers));
}
switch (key->out_of_range_group_action) {

View File

@ -262,9 +262,9 @@ xkb_filter_mod_set_func(struct xkb_filter *filter, xkb_keycode_t kc,
return 0;
}
filter->state->clear_mods = filter->action.mods.mask;
filter->state->clear_mods = filter->action.mods.mods.mask;
if (filter->action.mods.flags & XkbSA_ClearLocks)
filter->state->locked_mods &= ~filter->action.mods.mask;
filter->state->locked_mods &= ~filter->action.mods.mods.mask;
filter->func = NULL;
@ -283,7 +283,7 @@ xkb_filter_mod_set_new(struct xkb_state *state, xkb_keycode_t kc,
filter->func = xkb_filter_mod_set_func;
filter->action = *action;
filter->state->set_mods = action->mods.mask;
filter->state->set_mods = action->mods.mods.mask;
return 1;
}
@ -319,8 +319,8 @@ xkb_filter_mod_lock_new(struct xkb_state *state, xkb_keycode_t kc,
filter->kc = kc;
filter->func = xkb_filter_mod_lock_func;
filter->action = *action;
filter->priv = state->locked_mods & action->mods.mask;
state->locked_mods |= action->mods.mask;
filter->priv = state->locked_mods & action->mods.mods.mask;
state->locked_mods |= action->mods.mods.mask;
return 1;
}
@ -345,27 +345,27 @@ xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t kc,
union xkb_action *action = xkb_key_get_action(filter->state, kc);
if (action->type == XkbSA_LatchMods &&
action->mods.flags == filter->action.mods.flags &&
action->mods.mask == filter->action.mods.mask) {
action->mods.mods.mask == filter->action.mods.mods.mask) {
filter->action = *action;
if (filter->action.mods.flags & XkbSA_LatchToLock) {
filter->action.type = XkbSA_LockMods;
filter->func = xkb_filter_mod_lock_func;
filter->state->locked_mods |= filter->action.mods.mask;
filter->state->locked_mods |= filter->action.mods.mods.mask;
}
else {
filter->action.type = XkbSA_SetMods;
filter->func = xkb_filter_mod_set_func;
filter->state->set_mods = filter->action.mods.mask;
filter->state->set_mods = filter->action.mods.mods.mask;
}
filter->kc = kc;
filter->state->latched_mods &= ~filter->action.mods.mask;
filter->state->latched_mods &= ~filter->action.mods.mods.mask;
/* XXX beep beep! */
return 0;
}
else if (((1 << action->type) & XkbSA_BreakLatch)) {
/* XXX: This may be totally broken, we might need to break the
* latch in the next run after this press? */
filter->state->latched_mods &= ~filter->action.mods.mask;
filter->state->latched_mods &= ~filter->action.mods.mods.mask;
filter->func = NULL;
return 1;
}
@ -378,21 +378,21 @@ xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t kc,
* latched. */
if (latch == NO_LATCH ||
((filter->action.mods.flags & XkbSA_ClearLocks) &&
(filter->state->locked_mods & filter->action.mods.mask) ==
filter->action.mods.mask)) {
(filter->state->locked_mods & filter->action.mods.mods.mask) ==
filter->action.mods.mods.mask)) {
/* XXX: We might be a bit overenthusiastic about clearing
* mods other filters have set here? */
if (latch == LATCH_PENDING)
filter->state->latched_mods &= ~filter->action.mods.mask;
filter->state->latched_mods &= ~filter->action.mods.mods.mask;
else
filter->state->clear_mods = filter->action.mods.mask;
filter->state->locked_mods &= ~filter->action.mods.mask;
filter->state->clear_mods = filter->action.mods.mods.mask;
filter->state->locked_mods &= ~filter->action.mods.mods.mask;
filter->func = NULL;
}
else {
latch = LATCH_PENDING;
filter->state->clear_mods = filter->action.mods.mask;
filter->state->latched_mods |= filter->action.mods.mask;
filter->state->clear_mods = filter->action.mods.mods.mask;
filter->state->latched_mods |= filter->action.mods.mods.mask;
/* XXX beep beep! */
}
}
@ -423,7 +423,7 @@ xkb_filter_mod_latch_new(struct xkb_state *state, xkb_keycode_t kc,
filter->func = xkb_filter_mod_latch_func;
filter->action = *action;
filter->state->set_mods = action->mods.mask;
filter->state->set_mods = action->mods.mods.mask;
return 1;
}

View File

@ -47,6 +47,10 @@ GetBuffer(size_t size)
return rtrn;
}
/*
* Get a vmod name's text, where the vmod index is zero based
* (0..XkbNumVirtualMods-1).
*/
static const char *
VModIndexText(struct xkb_keymap *keymap, xkb_mod_index_t ndx)
{
@ -75,31 +79,35 @@ VModIndexText(struct xkb_keymap *keymap, xkb_mod_index_t ndx)
return rtrn;
}
/* Get a mod mask's text, where the mask is in rmods+vmods format. */
const char *
VModMaskText(struct xkb_keymap *keymap, xkb_mod_mask_t modMask,
xkb_mod_mask_t mask)
VModMaskText(struct xkb_keymap *keymap, xkb_mod_mask_t cmask)
{
xkb_mod_index_t i;
xkb_mod_mask_t bit;
xkb_mod_mask_t rmask, vmask;
int len, rem;
const char *mm = NULL;
char *rtrn, *str;
char buf[BUFFER_SIZE];
if (modMask == 0 && mask == 0)
rmask = cmask & 0xff;
vmask = cmask >> XkbNumModifiers;
if (rmask == 0 && vmask == 0)
return "none";
if (modMask != 0)
mm = ModMaskText(modMask, false);
if (rmask != 0)
mm = ModMaskText(rmask);
str = buf;
buf[0] = '\0';
rem = BUFFER_SIZE;
if (mask) {
if (vmask != 0) {
for (i = 0, bit = 1; i < XkbNumVirtualMods && rem > 1; i++, bit <<=
1) {
if (!(mask & bit))
if (!(vmask & bit))
continue;
len = snprintf(str, rem, "%s%s",
@ -185,18 +193,19 @@ ModIndexText(xkb_mod_index_t ndx)
return buf;
}
/* Gets the text for the real modifiers only. */
const char *
ModMaskText(xkb_mod_mask_t mask, bool cFormat)
ModMaskText(xkb_mod_mask_t mask)
{
int i, rem;
xkb_mod_index_t bit;
char *str, *buf;
if ((mask & 0xff) == 0xff)
return (cFormat ? "0xff" : "all");
return "all";
if ((mask & 0xff) == 0)
return (cFormat ? "0" : "none");
return "none";
rem = 64;
buf = GetBuffer(rem);
@ -208,10 +217,8 @@ ModMaskText(xkb_mod_mask_t mask, bool cFormat)
if (!(mask & bit))
continue;
len = snprintf(str, rem, "%s%s%s",
(str != buf) ? (cFormat ? "|" : "+") : "",
modNames[i],
cFormat ? "Mask" : "");
len = snprintf(str, rem, "%s%s",
(str != buf ? "+" : ""), modNames[i]);
rem -= len;
str += len;
}

View File

@ -30,8 +30,7 @@
#include "xkb-priv.h"
const char *
VModMaskText(struct xkb_keymap *keymap, xkb_mod_mask_t modMask,
xkb_mod_mask_t mask);
VModMaskText(struct xkb_keymap *keymap, xkb_mod_mask_t cmask);
xkb_mod_index_t
ModNameToIndex(const char *name);
@ -43,7 +42,7 @@ const char *
ModIndexText(xkb_mod_index_t ndx);
const char *
ModMaskText(xkb_mod_mask_t mask, bool cFormat);
ModMaskText(xkb_mod_mask_t mask);
const char *
FileTypeText(enum xkb_file_type type);

View File

@ -142,6 +142,11 @@ struct xkb_component_names {
char *symbols;
};
struct xkb_mods {
xkb_mod_mask_t mods; /* original real+virtual mods in definition */
xkb_mod_mask_t mask; /* computed effective mask */
};
struct xkb_any_action {
uint8_t type;
uint8_t data[7];
@ -150,9 +155,7 @@ struct xkb_any_action {
struct xkb_mod_action {
uint8_t type;
uint8_t flags;
uint8_t mask;
uint8_t real_mods;
uint16_t vmods;
struct xkb_mods mods;
};
struct xkb_group_action {
@ -164,11 +167,9 @@ struct xkb_group_action {
struct xkb_iso_action {
uint8_t type;
uint8_t flags;
uint8_t mask;
uint8_t real_mods;
struct xkb_mods mods;
int32_t group;
uint8_t affect;
uint16_t vmods;
};
struct xkb_controls_action {
@ -255,12 +256,6 @@ union xkb_action {
unsigned char type;
};
struct xkb_mods {
xkb_mod_mask_t mask; /* effective mods */
xkb_mod_mask_t vmods;
uint8_t real_mods;
};
struct xkb_kt_map_entry {
xkb_level_index_t level;
struct xkb_mods mods;

View File

@ -309,8 +309,7 @@ HandleSetLatchMods(struct xkb_keymap *keymap, struct xkb_any_action *action,
t1 = act->flags;
if (CheckModifierField(keymap, action->type, value, &t1, &t2)) {
act->flags = t1;
act->real_mods = act->mask = (t2 & 0xff);
act->vmods = (t2 >> XkbNumModifiers) & 0xffff;
act->mods.mods = t2;
return true;
}
return false;
@ -334,8 +333,7 @@ HandleLockMods(struct xkb_keymap *keymap, struct xkb_any_action *action,
t1 = act->flags;
if (CheckModifierField(keymap, action->type, value, &t1, &t2)) {
act->flags = t1;
act->real_mods = act->mask = (t2 & 0xff);
act->vmods = (t2 >> XkbNumModifiers) & 0xffff;
act->mods.mods = t2;
return true;
}
return false;
@ -658,8 +656,7 @@ HandleISOLock(struct xkb_keymap *keymap, struct xkb_any_action *action,
return false;
act->flags = flags & (~XkbSA_ISODfltIsGroup);
act->real_mods = mods & 0xff;
act->vmods = (mods >> XkbNumModifiers) & 0xffff;
act->mods.mods = mods;
return true;
}
else if (field == F_Group) {
@ -1166,7 +1163,7 @@ ApplyActionFactoryDefaults(union xkb_action * action)
action->dflt.value = 1;
}
else if (action->type == XkbSA_ISOLock) {
action->iso.real_mods = ModNameToIndex(XKB_MOD_NAME_CAPS);
action->iso.mods.mods = (1 << ModNameToIndex(XKB_MOD_NAME_CAPS));
}
}

View File

@ -66,8 +66,7 @@ typedef struct _LEDInfo {
xkb_led_index_t indicator;
unsigned char flags;
unsigned char which_mods;
unsigned char real_mods;
xkb_mod_mask_t vmods;
xkb_mod_mask_t mods;
unsigned char which_groups;
uint32_t groups;
unsigned int ctrls;
@ -77,8 +76,7 @@ typedef struct _GroupCompatInfo {
unsigned file_id;
enum merge_mode merge;
bool defined;
unsigned char real_mods;
xkb_atom_t vmods;
xkb_mod_mask_t mods;
} GroupCompatInfo;
typedef struct _CompatInfo {
@ -108,7 +106,7 @@ siText(SymInterpInfo * si, CompatInfo * info)
snprintf(buf, sizeof(buf), "%s+%s(%s)",
KeysymText(si->interp.sym),
SIMatchText(si->interp.match),
ModMaskText(si->interp.mods, false));
ModMaskText(si->interp.mods));
}
return buf;
}
@ -150,8 +148,9 @@ ClearIndicatorMapInfo(struct xkb_context *ctx, LEDInfo * info)
{
info->name = xkb_atom_intern(ctx, "default");
info->indicator = XKB_LED_INVALID;
info->flags = info->which_mods = info->real_mods = 0;
info->vmods = 0;
info->flags = 0;
info->which_mods = 0;
info->mods = 0;
info->which_groups = info->groups = 0;
info->ctrls = 0;
}
@ -348,7 +347,7 @@ AddGroupCompat(CompatInfo *info, xkb_group_index_t group, GroupCompatInfo *new)
int verbosity = xkb_get_log_verbosity(info->keymap->ctx);
gc = &info->groupCompat[group];
if (gc->real_mods == new->real_mods && gc->vmods == new->vmods)
if (gc->mods == new->mods)
return true;
if ((gc->file_id == new->file_id && verbosity > 0) || verbosity > 9)
@ -440,8 +439,7 @@ AddIndicatorMap(CompatInfo *info, LEDInfo *new)
list_foreach(old, &info->leds, entry) {
if (old->name == new->name) {
if ((old->real_mods == new->real_mods) &&
(old->vmods == new->vmods) &&
if ((old->mods == new->mods) &&
(old->groups == new->groups) &&
(old->ctrls == new->ctrls) &&
(old->which_mods == new->which_mods) &&
@ -472,8 +470,7 @@ AddIndicatorMap(CompatInfo *info, LEDInfo *new)
if (UseNewLEDField(LED_FIELD_MODS, old, new, verbosity,
&collide)) {
old->which_mods = new->which_mods;
old->real_mods = new->real_mods;
old->vmods = new->vmods;
old->mods = new->mods;
old->defined |= LED_FIELD_MODS;
}
if (UseNewLEDField(LED_FIELD_GROUPS, old, new, verbosity,
@ -758,16 +755,12 @@ SetIndicatorMapField(CompatInfo *info, LEDInfo *led,
struct xkb_keymap *keymap = info->keymap;
if (istreq(field, "modifiers") || istreq(field, "mods")) {
xkb_mod_mask_t mask;
if (arrayNdx)
return ReportIndicatorNotArray(info, led, field);
if (!ExprResolveVModMask(keymap, value, &mask))
if (!ExprResolveVModMask(keymap, value, &led->mods))
return ReportIndicatorBadType(info, led, field, "modifier mask");
led->real_mods = mask & 0xff;
led->vmods = (mask >> XkbNumModifiers) & 0xffff;
led->defined |= LED_FIELD_MODS;
}
else if (istreq(field, "groups")) {
@ -973,7 +966,6 @@ static int
HandleGroupCompatDef(CompatInfo *info, GroupCompatDef *def,
enum merge_mode merge)
{
xkb_mod_mask_t mask;
GroupCompatInfo tmp;
merge = (def->merge == MERGE_DEFAULT ? merge : def->merge);
@ -989,7 +981,7 @@ HandleGroupCompatDef(CompatInfo *info, GroupCompatDef *def,
tmp.file_id = info->file_id;
tmp.merge = merge;
if (!ExprResolveVModMask(info->keymap, def->def, &mask)) {
if (!ExprResolveVModMask(info->keymap, def->def, &tmp.mods)) {
log_err(info->keymap->ctx,
"Expected a modifier mask in group compatibility definition; "
"Ignoring illegal compatibility map for group %u\n",
@ -997,8 +989,6 @@ HandleGroupCompatDef(CompatInfo *info, GroupCompatDef *def,
return false;
}
tmp.real_mods = mask & 0xff;
tmp.vmods = (mask >> XkbNumModifiers) & 0xffff;
tmp.defined = true;
return AddGroupCompat(info, def->group - 1, &tmp);
}
@ -1177,9 +1167,7 @@ BindIndicators(CompatInfo *info, struct list *unbound_leds)
map->which_groups = led->which_groups;
map->groups = led->groups;
map->which_mods = led->which_mods;
map->mods.mask = led->real_mods;
map->mods.real_mods = led->real_mods;
map->mods.vmods = led->vmods;
map->mods.mods = led->mods;
map->ctrls = led->ctrls;
free(led);
}
@ -1201,7 +1189,7 @@ CopyIndicatorMapDefs(CompatInfo *info)
if (led->groups != 0 && led->which_groups == 0)
led->which_groups = XkbIM_UseEffective;
if (led->which_mods == 0 && (led->real_mods || led->vmods))
if (led->which_mods == 0 && led->mods)
led->which_mods = XkbIM_UseEffective;
if (led->indicator == XKB_LED_INVALID) {
@ -1214,9 +1202,7 @@ CopyIndicatorMapDefs(CompatInfo *info)
im->which_groups = led->which_groups;
im->groups = led->groups;
im->which_mods = led->which_mods;
im->mods.mask = led->real_mods;
im->mods.real_mods = led->real_mods;
im->mods.vmods = led->vmods;
im->mods.mods = led->mods;
im->ctrls = led->ctrls;
keymap->indicator_names[led->indicator - 1] =
xkb_atom_text(keymap->ctx, led->name);
@ -1265,11 +1251,8 @@ CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap,
for (i = 0, gcm = &info.groupCompat[0]; i < XkbNumKbdGroups;
i++, gcm++) {
if (gcm->file_id != 0 || gcm->real_mods != 0 || gcm->vmods != 0) {
keymap->groups[i].mask = gcm->real_mods;
keymap->groups[i].real_mods = gcm->real_mods;
keymap->groups[i].vmods = gcm->vmods;
}
if (gcm->file_id != 0 || gcm->mods != 0)
keymap->groups[i].mods = gcm->mods;
}
if (!CopyIndicatorMapDefs(&info))
@ -1283,48 +1266,52 @@ err_info:
return false;
}
xkb_mod_mask_t
VModsToReal(struct xkb_keymap *keymap, xkb_mod_mask_t vmodmask)
static void
ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods)
{
xkb_mod_mask_t ret = 0;
xkb_mod_index_t i;
xkb_mod_mask_t vmask = mods->mods >> XkbNumModifiers;
if (!vmodmask)
return 0;
/* The effective mask is only real mods for now. */
mods->mask = mods->mods & 0xff;
for (i = 0; i < XkbNumVirtualMods; i++) {
if (!(vmodmask & (1 << i)))
if (!(vmask & (1 << i)))
continue;
ret |= keymap->vmods[i];
mods->mask |= keymap->vmods[i];
}
return ret;
}
static void
UpdateActionMods(struct xkb_keymap *keymap, union xkb_action *act,
xkb_mod_mask_t rmodmask)
{
unsigned int flags;
struct xkb_mods *mods;
switch (act->type) {
case XkbSA_SetMods:
case XkbSA_LatchMods:
case XkbSA_LockMods:
if (act->mods.flags & XkbSA_UseModMapMods)
act->mods.real_mods = rmodmask;
act->mods.mask = act->mods.real_mods;
act->mods.mask |= VModsToReal(keymap, act->mods.vmods);
flags = act->mods.flags;
mods = &act->mods.mods;
break;
case XkbSA_ISOLock:
if (act->iso.flags & XkbSA_UseModMapMods)
act->iso.real_mods = rmodmask;
act->iso.mask = act->iso.real_mods;
act->iso.mask |= VModsToReal(keymap, act->iso.vmods);
flags = act->iso.flags;
mods = &act->iso.mods;
break;
default:
break;
return;
}
if (flags & XkbSA_UseModMapMods) {
/* XXX: what's that. */
mods->mods &= 0xff;
mods->mods |= rmodmask;
}
ComputeEffectiveMask(keymap, mods);
}
/**
@ -1475,7 +1462,6 @@ UpdateModifiersFromCompat(struct xkb_keymap *keymap)
xkb_led_index_t led;
unsigned int i, j;
struct xkb_key *key;
struct xkb_key_type *type;
/* Find all the interprets for the key and bind them to actions,
* which will also update the vmodmap. */
@ -1500,42 +1486,28 @@ UpdateModifiersFromCompat(struct xkb_keymap *keymap)
/* Now update the level masks for all the types to reflect the vmods. */
for (i = 0; i < keymap->num_types; i++) {
type = &keymap->types[i];
type->mods.mask = type->mods.real_mods;
type->mods.mask |= VModsToReal(keymap, type->mods.vmods);
ComputeEffectiveMask(keymap, &keymap->types[i].mods);
for (j = 0; j < type->num_entries; j++) {
struct xkb_kt_map_entry *entry = &type->map[j];
entry->mods.mask = entry->mods.real_mods;
entry->mods.mask |= VModsToReal(keymap, entry->mods.vmods);
entry->preserve.mask = entry->preserve.real_mods;
entry->preserve.mask |= VModsToReal(keymap, entry->preserve.vmods);
for (j = 0; j < keymap->types[i].num_entries; j++) {
ComputeEffectiveMask(keymap, &keymap->types[i].map[j].mods);
ComputeEffectiveMask(keymap, &keymap->types[i].map[j].preserve);
}
}
/* Update action modifiers. */
xkb_foreach_key(key, keymap) {
union xkb_action *acts = XkbKeyActionsPtr(keymap, key);
for (i = 0; i < XkbKeyNumActions(key); i++) {
if (acts[i].any.type == XkbSA_NoAction)
continue;
for (i = 0; i < XkbKeyNumActions(key); i++)
UpdateActionMods(keymap, &acts[i], key->modmap);
}
}
/* Update group modifiers. */
for (grp = 0; grp < XkbNumKbdGroups; grp++) {
struct xkb_mods *group = &keymap->groups[grp];
group->mask = group->real_mods | VModsToReal(keymap, group->vmods);
}
for (grp = 0; grp < XkbNumKbdGroups; grp++)
ComputeEffectiveMask(keymap, &keymap->groups[grp]);
/* Update vmod -> indicator maps. */
for (led = 0; led < XkbNumIndicators; led++) {
struct xkb_mods *mods = &keymap->indicators[led].mods;
mods->mask = mods->real_mods | VModsToReal(keymap, mods->vmods);
}
for (led = 0; led < XkbNumIndicators; led++)
ComputeEffectiveMask(keymap, &keymap->indicators[led].mods);
return true;
}

View File

@ -138,8 +138,7 @@ typedef struct _KeyTypeInfo {
struct list entry;
xkb_atom_t name;
xkb_mod_mask_t mask;
xkb_mod_mask_t vmask;
xkb_mod_mask_t mods;
xkb_level_index_t num_levels;
darray(struct xkb_kt_map_entry) entries;
darray(xkb_atom_t) level_names;
@ -160,8 +159,7 @@ typedef struct _KeyTypesInfo {
static inline const char *
MapEntryTxt(KeyTypesInfo *info, struct xkb_kt_map_entry *entry)
{
return VModMaskText(info->keymap, entry->mods.real_mods,
entry->mods.vmods);
return VModMaskText(info->keymap, entry->mods.mods);
}
static inline const char *
@ -173,7 +171,7 @@ TypeTxt(KeyTypesInfo *info, KeyTypeInfo *type)
static inline const char *
TypeMaskTxt(KeyTypesInfo *info, KeyTypeInfo *type)
{
return VModMaskText(info->keymap, type->mask, type->vmask);
return VModMaskText(info->keymap, type->mods);
}
static inline bool
@ -385,7 +383,7 @@ static bool
SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
ExprDef *value)
{
xkb_mod_mask_t mask, mods, vmods;
xkb_mod_mask_t mods;
if (arrayNdx)
log_warn(info->keymap->ctx,
@ -393,40 +391,36 @@ SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
"Illegal array subscript ignored\n");
/* get modifier mask for current type */
if (!ExprResolveVModMask(info->keymap, value, &mask)) {
if (!ExprResolveVModMask(info->keymap, value, &mods)) {
log_err(info->keymap->ctx,
"Key type mask field must be a modifier mask; "
"Key type definition ignored\n");
return false;
}
mods = mask & 0xff; /* core mods */
vmods = (mask >> XkbNumModifiers) & 0xffff; /* xkb virtual mods */
if (type->defined & TYPE_FIELD_MASK) {
log_warn(info->keymap->ctx,
"Multiple modifier mask definitions for key type %s; "
"Using %s, ignoring %s\n",
xkb_atom_text(info->keymap->ctx, type->name),
TypeMaskTxt(info, type),
VModMaskText(info->keymap, mods, vmods));
VModMaskText(info->keymap, mods));
return false;
}
type->mask = mods;
type->vmask = vmods;
type->mods = mods;
return true;
}
/***====================================================================***/
static struct xkb_kt_map_entry *
FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
FindMatchingMapEntry(KeyTypeInfo *type, xkb_mod_mask_t mods)
{
struct xkb_kt_map_entry *entry;
darray_foreach(entry, type->entries)
if (entry->mods.real_mods == mask && entry->mods.vmods == vmask)
if (entry->mods.mods == mods)
return entry;
return NULL;
@ -446,7 +440,7 @@ AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type,
{
struct xkb_kt_map_entry * old;
old = FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods);
old = FindMatchingMapEntry(type, new->mods.mods);
if (old) {
if (report && old->level != new->level) {
log_warn(info->keymap->ctx,
@ -485,29 +479,21 @@ SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
ExprDef *value)
{
struct xkb_kt_map_entry entry;
xkb_mod_mask_t mask;
if (arrayNdx == NULL)
return ReportTypeShouldBeArray(info, type, "map entry");
if (!ExprResolveVModMask(info->keymap, arrayNdx, &mask))
if (!ExprResolveVModMask(info->keymap, arrayNdx, &entry.mods.mods))
return ReportTypeBadType(info, type, "map entry", "modifier mask");
entry.mods.real_mods = mask & 0xff;
entry.mods.vmods = (mask >> XkbNumModifiers) & 0xffff;
if ((entry.mods.real_mods & (~type->mask)) ||
(entry.mods.vmods & (~type->vmask))) {
if (entry.mods.mods & (~type->mods)) {
log_lvl(info->keymap->ctx, 1,
"Map entry for unused modifiers in %s; "
"Using %s instead of %s\n",
TypeTxt(info, type),
VModMaskText(info->keymap,
entry.mods.real_mods & type->mask,
entry.mods.vmods & type->vmask),
VModMaskText(info->keymap, entry.mods.mods & type->mods),
MapEntryTxt(info, &entry));
entry.mods.real_mods &= type->mask;
entry.mods.vmods &= type->vmask;
entry.mods.mods &= type->mods;
}
if (!ExprResolveLevel(info->keymap->ctx, value, &entry.level)) {
@ -517,8 +503,7 @@ SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
return false;
}
entry.preserve.real_mods = 0;
entry.preserve.vmods = 0;
entry.preserve.mods = 0;
return AddMapEntry(info, type, &entry, true, true);
}
@ -527,38 +512,27 @@ SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
static bool
AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type,
xkb_mod_mask_t rmods, xkb_mod_mask_t vmods,
xkb_mod_mask_t preserve_rmods, xkb_mod_mask_t preserve_vmods)
xkb_mod_mask_t mods, xkb_mod_mask_t preserve_mods)
{
struct xkb_kt_map_entry *entry;
struct xkb_mods mods = {
.real_mods = rmods,
.vmods = vmods,
};
struct xkb_mods preserve = {
.real_mods = preserve_rmods,
.vmods = preserve_vmods,
};
struct xkb_kt_map_entry new;
darray_foreach(entry, type->entries) {
if (entry->mods.real_mods != mods.real_mods ||
entry->mods.vmods != mods.vmods)
if (entry->mods.mods != mods)
continue;
/* Map exists without previous preserve (or "None"); override. */
if (entry->preserve.real_mods == 0 && entry->preserve.vmods == 0) {
entry->preserve = preserve;
if (entry->preserve.mods == 0) {
entry->preserve.mods = preserve_mods;
return true;
}
/* Map exists with same preserve; do nothing. */
if (entry->preserve.real_mods == preserve.real_mods &&
entry->preserve.vmods == preserve.vmods) {
if (entry->preserve.mods == preserve_mods) {
log_lvl(info->keymap->ctx, 10,
"Identical definitions for preserve[%s] in %s; "
"Ignored\n",
VModMaskText(info->keymap, rmods, vmods),
VModMaskText(info->keymap, mods),
TypeTxt(info, type));
return true;
}
@ -567,16 +541,12 @@ AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type,
log_lvl(info->keymap->ctx, 1,
"Multiple definitions for preserve[%s] in %s; "
"Using %s, ignoring %s\n",
VModMaskText(info->keymap, mods.real_mods, mods.vmods),
VModMaskText(info->keymap, mods),
TypeTxt(info, type),
VModMaskText(info->keymap,
preserve.real_mods,
preserve.vmods),
VModMaskText(info->keymap,
entry->preserve.real_mods,
entry->preserve.vmods));
VModMaskText(info->keymap, preserve_mods),
VModMaskText(info->keymap, entry->preserve.mods));
entry->preserve = preserve;
entry->preserve.mods = preserve_mods;
return true;
}
@ -586,8 +556,8 @@ AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type,
* may be overriden later with an explicit map[] statement.
*/
new.level = 0;
new.mods = mods;
new.preserve = preserve;
new.mods.mods = mods;
new.preserve.mods = preserve_mods;
darray_append(type->entries, new);
return true;
}
@ -596,26 +566,21 @@ static bool
SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
ExprDef *value)
{
xkb_mod_mask_t mask;
xkb_mod_mask_t rmods, vmods, preserve_rmods, preserve_vmods;
xkb_mod_mask_t mods, preserve_mods;
if (arrayNdx == NULL)
return ReportTypeShouldBeArray(info, type, "preserve entry");
if (!ExprResolveVModMask(info->keymap, arrayNdx, &mask))
if (!ExprResolveVModMask(info->keymap, arrayNdx, &mods))
return ReportTypeBadType(info, type, "preserve entry",
"modifier mask");
rmods = mask & 0xff;
vmods = (mask >> XkbNumModifiers) & 0xffff;
if ((rmods & (~type->mask)) || (vmods & (~type->vmask))) {
if (mods & ~type->mods) {
const char *before, *after;
before = VModMaskText(info->keymap, rmods, vmods);
rmods &= type->mask;
vmods &= type->vmask;
after = VModMaskText(info->keymap, rmods, vmods);
before = VModMaskText(info->keymap, mods);
mods &= type->mods;
after = VModMaskText(info->keymap, mods);
log_lvl(info->keymap->ctx, 1,
"Preserve for modifiers not used by the %s type; "
@ -623,35 +588,30 @@ SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
TypeTxt(info, type), before, after);
}
if (!ExprResolveVModMask(info->keymap, value, &mask)) {
if (!ExprResolveVModMask(info->keymap, value, &preserve_mods)) {
log_err(info->keymap->ctx,
"Preserve value in a key type is not a modifier mask; "
"Ignoring preserve[%s] in type %s\n",
VModMaskText(info->keymap, rmods, vmods),
VModMaskText(info->keymap, mods),
TypeTxt(info, type));
return false;
}
preserve_rmods = mask & 0xff;
preserve_vmods = (mask >> XkbNumModifiers) & 0xffff;
if ((preserve_rmods & ~rmods) || (preserve_vmods & ~vmods)) {
if (preserve_mods & ~mods) {
const char *before, *after;
before = VModMaskText(info->keymap, preserve_rmods, preserve_vmods);
preserve_rmods &= rmods;
preserve_vmods &= vmods;
after = VModMaskText(info->keymap, preserve_rmods, preserve_vmods);
before = VModMaskText(info->keymap, preserve_mods);
preserve_mods &= mods;
after = VModMaskText(info->keymap, preserve_mods);
log_lvl(info->keymap->ctx, 1,
"Illegal value for preserve[%s] in type %s; "
"Converted %s to %s\n",
VModMaskText(info->keymap, rmods, vmods),
VModMaskText(info->keymap, mods),
TypeTxt(info, type), before, after);
}
return AddPreserve(info, type, rmods, vmods,
preserve_rmods, preserve_vmods);
return AddPreserve(info, type, mods, preserve_mods);
}
/***====================================================================***/
@ -802,7 +762,7 @@ HandleKeyTypeDef(KeyTypesInfo *info, KeyTypeDef *def, enum merge_mode merge)
.file_id = info->file_id,
.merge = (def->merge == MERGE_DEFAULT ? merge : def->merge),
.name = def->name,
.mask = 0, .vmask = 0,
.mods = 0,
.num_levels = 1,
.entries = darray_new(),
.level_names = darray_new(),
@ -880,8 +840,7 @@ static bool
CopyDefToKeyType(KeyTypesInfo *info, KeyTypeInfo *def,
struct xkb_key_type *type)
{
type->mods.real_mods = def->mask;
type->mods.vmods = def->vmask;
type->mods.mods = def->mods;
type->num_levels = def->num_levels;
type->map = darray_mem(def->entries, 0);
type->num_entries = darray_size(def->entries);
@ -925,7 +884,7 @@ CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
if (info.num_types == 0) {
KeyTypeInfo dflt = {
.name = xkb_atom_intern(keymap->ctx, "default"),
.mask = 0, .vmask = 0,
.mods = 0,
.num_levels = 1,
.entries = darray_new(),
.level_names = darray_new(),

View File

@ -100,10 +100,10 @@ HandleVModDef(VModDef *stmt, struct xkb_keymap *keymap,
if (mask == keymap->vmods[i])
return true;
str1 = ModMaskText(keymap->vmods[i], true);
str1 = ModMaskText(keymap->vmods[i]);
if (mergeMode == MERGE_OVERRIDE) {
str2 = str1;
str1 = ModMaskText(mask, true);
str1 = ModMaskText(mask);
}
log_warn(keymap->ctx,

View File

@ -46,9 +46,6 @@ FindKeyNameForAlias(struct xkb_keymap *keymap, unsigned long lname,
extern bool
UpdateModifiersFromCompat(struct xkb_keymap *keymap);
xkb_mod_mask_t
VModsToReal(struct xkb_keymap *keymap, xkb_mod_mask_t vmodmask);
const char *
StmtTypeToString(enum stmt_type type);