Remove the XKB_NUM_VIRTUAL_MODIFIERS limit
Turn the virtual modifiers arrays in the keymap to a single darray, which doesn't use this limit. The number of virtual modifiers is still limited by the size of xkb_mod_mask_t, so we make sure not to go over that. Signed-off-by: Ran Benita <ran234@gmail.com>master
parent
8016c6f4f1
commit
dd29b14e11
|
@ -127,17 +127,15 @@ err:
|
|||
static bool
|
||||
write_vmods(struct xkb_keymap *keymap, struct buf *buf)
|
||||
{
|
||||
xkb_mod_index_t i, num_vmods = 0;
|
||||
const struct xkb_vmod *vmod;
|
||||
xkb_mod_index_t num_vmods = 0;
|
||||
|
||||
for (i = 0; i < XKB_NUM_VIRTUAL_MODS; i++) {
|
||||
if (!keymap->vmod_names[i])
|
||||
continue;
|
||||
darray_foreach(vmod, keymap->vmods) {
|
||||
if (num_vmods == 0)
|
||||
write_buf(buf, "\t\tvirtual_modifiers ");
|
||||
else
|
||||
write_buf(buf, ",");
|
||||
write_buf(buf, "%s",
|
||||
xkb_atom_text(keymap->ctx, keymap->vmod_names[i]));
|
||||
write_buf(buf, "%s", xkb_atom_text(keymap->ctx, vmod->name));
|
||||
num_vmods++;
|
||||
}
|
||||
|
||||
|
@ -527,7 +525,8 @@ write_compat(struct xkb_keymap *keymap, struct buf *buf)
|
|||
if (interp->virtual_mod != XKB_MOD_INVALID) {
|
||||
write_buf(buf, "\t\t\tvirtualModifier= %s;\n",
|
||||
xkb_atom_text(keymap->ctx,
|
||||
keymap->vmod_names[interp->virtual_mod]));
|
||||
darray_item(keymap->vmods,
|
||||
interp->virtual_mod).name));
|
||||
}
|
||||
|
||||
if (interp->match & MATCH_LEVEL_ONE_ONLY)
|
||||
|
|
26
src/keymap.c
26
src/keymap.c
|
@ -107,6 +107,7 @@ xkb_keymap_unref(struct xkb_keymap *keymap)
|
|||
darray_free(keymap->sym_interpret);
|
||||
darray_free(keymap->key_aliases);
|
||||
darray_free(keymap->group_names);
|
||||
darray_free(keymap->vmods);
|
||||
free(keymap->keycodes_section_name);
|
||||
free(keymap->symbols_section_name);
|
||||
free(keymap->types_section_name);
|
||||
|
@ -121,15 +122,9 @@ xkb_keymap_unref(struct xkb_keymap *keymap)
|
|||
XKB_EXPORT xkb_mod_index_t
|
||||
xkb_keymap_num_mods(struct xkb_keymap *keymap)
|
||||
{
|
||||
xkb_mod_index_t i;
|
||||
|
||||
for (i = 0; i < XKB_NUM_VIRTUAL_MODS; i++)
|
||||
if (!keymap->vmod_names[i])
|
||||
break;
|
||||
|
||||
/* We always have all the core modifiers (for now), plus any virtual
|
||||
* modifiers we may have defined. */
|
||||
return i + XKB_NUM_CORE_MODS;
|
||||
return XKB_NUM_CORE_MODS + darray_size(keymap->vmods);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,6 +134,7 @@ XKB_EXPORT const char *
|
|||
xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx)
|
||||
{
|
||||
const char *name;
|
||||
const struct xkb_vmod *vmod;
|
||||
|
||||
if (idx >= xkb_keymap_num_mods(keymap))
|
||||
return NULL;
|
||||
|
@ -146,11 +142,11 @@ xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx)
|
|||
/* First try to find a legacy modifier name. If that fails, try to
|
||||
* find a virtual mod name. */
|
||||
name = ModIndexToName(idx);
|
||||
if (!name)
|
||||
name = xkb_atom_text(keymap->ctx,
|
||||
keymap->vmod_names[idx - XKB_NUM_CORE_MODS]);
|
||||
if (name)
|
||||
return name;
|
||||
|
||||
return name;
|
||||
vmod = &darray_item(keymap->vmods, idx - XKB_NUM_CORE_MODS);
|
||||
return xkb_atom_text(keymap->ctx, vmod->name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,6 +157,7 @@ xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name)
|
|||
{
|
||||
xkb_mod_index_t i;
|
||||
xkb_atom_t atom;
|
||||
const struct xkb_vmod *vmod;
|
||||
|
||||
i = ModNameToIndex(name);
|
||||
if (i != XKB_MOD_INVALID)
|
||||
|
@ -170,12 +167,9 @@ xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name)
|
|||
if (atom == XKB_ATOM_NONE)
|
||||
return XKB_MOD_INVALID;
|
||||
|
||||
for (i = 0; i < XKB_NUM_VIRTUAL_MODS; i++) {
|
||||
if (keymap->vmod_names[i] == XKB_ATOM_NONE)
|
||||
break;
|
||||
if (keymap->vmod_names[i] == atom)
|
||||
darray_enumerate(i, vmod, keymap->vmods)
|
||||
if (vmod->name == atom)
|
||||
return i + XKB_NUM_CORE_MODS;
|
||||
}
|
||||
|
||||
return XKB_MOD_INVALID;
|
||||
}
|
||||
|
|
14
src/keymap.h
14
src/keymap.h
|
@ -103,9 +103,12 @@
|
|||
*/
|
||||
#define XKB_NUM_GROUPS 4
|
||||
|
||||
/* Don't allow more vmods than we can hold in xkb_mod_mask_t. */
|
||||
#define XKB_MAX_VIRTUAL_MODS \
|
||||
((xkb_mod_index_t) (sizeof(xkb_mod_mask_t) * 8 - XKB_NUM_CORE_MODS))
|
||||
|
||||
/* These should all be dynamic. */
|
||||
#define XKB_NUM_INDICATORS 32
|
||||
#define XKB_NUM_VIRTUAL_MODS 16
|
||||
#define XKB_NUM_CORE_MODS 8
|
||||
|
||||
enum xkb_action_type {
|
||||
|
@ -355,6 +358,11 @@ struct xkb_key {
|
|||
|
||||
typedef darray(xkb_atom_t) darray_xkb_atom_t;
|
||||
|
||||
struct xkb_vmod {
|
||||
xkb_atom_t name;
|
||||
xkb_mod_mask_t mapping; /* vmod -> real mod mapping */
|
||||
};
|
||||
|
||||
/* Common keyboard description structure */
|
||||
struct xkb_keymap {
|
||||
struct xkb_context *ctx;
|
||||
|
@ -378,9 +386,7 @@ struct xkb_keymap {
|
|||
|
||||
darray(struct xkb_sym_interpret) sym_interpret;
|
||||
|
||||
/* vmod -> mod mapping */
|
||||
xkb_mod_mask_t vmods[XKB_NUM_VIRTUAL_MODS];
|
||||
xkb_atom_t vmod_names[XKB_NUM_VIRTUAL_MODS];
|
||||
darray(struct xkb_vmod) vmods;
|
||||
|
||||
/* Number of groups in the key with the most groups. */
|
||||
xkb_layout_index_t num_groups;
|
||||
|
|
38
src/text.c
38
src/text.c
|
@ -231,36 +231,14 @@ GetBuffer(size_t size)
|
|||
return rtrn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a vmod name's text, where the vmod index is zero based
|
||||
* (0..XKB_NUM_VIRTUAL_MODS-1).
|
||||
*/
|
||||
/* Get a vmod name's text, where the vmod index is zero based. */
|
||||
static const char *
|
||||
VModIndexText(struct xkb_keymap *keymap, xkb_mod_index_t ndx)
|
||||
{
|
||||
int len;
|
||||
char *rtrn;
|
||||
const char *tmp = NULL;
|
||||
char buf[20];
|
||||
|
||||
if (ndx >= XKB_NUM_VIRTUAL_MODS)
|
||||
tmp = "illegal";
|
||||
else
|
||||
tmp = xkb_atom_text(keymap->ctx, keymap->vmod_names[ndx]);
|
||||
|
||||
if (!tmp) {
|
||||
snprintf(buf, sizeof(buf) - 1, "%d", ndx);
|
||||
tmp = buf;
|
||||
}
|
||||
|
||||
len = strlen(tmp) + 1;
|
||||
if (len >= BUFFER_SIZE)
|
||||
len = BUFFER_SIZE - 1;
|
||||
|
||||
rtrn = GetBuffer(len);
|
||||
strncpy(rtrn, tmp, len);
|
||||
|
||||
return rtrn;
|
||||
if (ndx >= darray_size(keymap->vmods))
|
||||
return "illegal";
|
||||
return xkb_atom_text(keymap->ctx,
|
||||
darray_item(keymap->vmods, ndx).name);
|
||||
}
|
||||
|
||||
/* Get a mod mask's text, where the mask is in rmods+vmods format. */
|
||||
|
@ -268,7 +246,6 @@ const char *
|
|||
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;
|
||||
|
@ -289,9 +266,8 @@ VModMaskText(struct xkb_keymap *keymap, xkb_mod_mask_t cmask)
|
|||
rem = BUFFER_SIZE;
|
||||
|
||||
if (vmask != 0) {
|
||||
for (i = 0, bit = 1; i < XKB_NUM_VIRTUAL_MODS && rem > 1; i++, bit <<=
|
||||
1) {
|
||||
if (!(vmask & bit))
|
||||
for (i = 0; i < darray_size(keymap->vmods) && rem > 1; i++) {
|
||||
if (!(vmask & (1 << i)))
|
||||
continue;
|
||||
|
||||
len = snprintf(str, rem, "%s%s",
|
||||
|
|
|
@ -32,17 +32,16 @@
|
|||
static void
|
||||
ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods)
|
||||
{
|
||||
const struct xkb_vmod *vmod;
|
||||
xkb_mod_index_t i;
|
||||
xkb_mod_mask_t vmask = mods->mods >> XKB_NUM_CORE_MODS;
|
||||
|
||||
/* The effective mask is only real mods for now. */
|
||||
mods->mask = mods->mods & 0xff;
|
||||
|
||||
for (i = 0; i < XKB_NUM_VIRTUAL_MODS; i++) {
|
||||
if (!(vmask & (1 << i)))
|
||||
continue;
|
||||
mods->mask |= keymap->vmods[i];
|
||||
}
|
||||
darray_enumerate(i, vmod, keymap->vmods)
|
||||
if (vmask & (1 << i))
|
||||
mods->mask |= vmod->mapping;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -186,7 +185,7 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key)
|
|||
static bool
|
||||
UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
|
||||
{
|
||||
xkb_mod_index_t vmod;
|
||||
struct xkb_vmod *vmod;
|
||||
xkb_led_index_t led;
|
||||
unsigned int i, j;
|
||||
struct xkb_key *key;
|
||||
|
@ -198,19 +197,10 @@ UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
|
|||
return false;
|
||||
|
||||
/* Update keymap->vmods, the virtual -> real mod mapping. */
|
||||
for (vmod = 0; vmod < XKB_NUM_VIRTUAL_MODS; vmod++)
|
||||
keymap->vmods[vmod] = 0;
|
||||
|
||||
xkb_foreach_key(key, keymap) {
|
||||
if (!key->vmodmap)
|
||||
continue;
|
||||
|
||||
for (vmod = 0; vmod < XKB_NUM_VIRTUAL_MODS; vmod++) {
|
||||
if (!(key->vmodmap & (1 << vmod)))
|
||||
continue;
|
||||
keymap->vmods[vmod] |= key->modmap;
|
||||
}
|
||||
}
|
||||
xkb_foreach_key(key, keymap)
|
||||
darray_enumerate(i, vmod, keymap->vmods)
|
||||
if (key->vmodmap & (1 << i))
|
||||
vmod->mapping |= key->modmap;
|
||||
|
||||
/* Now update the level masks for all the types to reflect the vmods. */
|
||||
for (i = 0; i < keymap->num_types; i++) {
|
||||
|
|
|
@ -35,9 +35,8 @@ InitVModInfo(VModInfo *info, struct xkb_keymap *keymap)
|
|||
xkb_mod_index_t i;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
for (i = 0; i < XKB_NUM_VIRTUAL_MODS; i++)
|
||||
if (keymap->vmod_names[i])
|
||||
info->defined |= (1 << i);
|
||||
for (i = 0; i < darray_size(keymap->vmods); i++)
|
||||
info->defined |= (1 << i);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -45,44 +44,32 @@ HandleVModDef(VModDef *stmt, struct xkb_keymap *keymap,
|
|||
enum merge_mode mergeMode, VModInfo *info)
|
||||
{
|
||||
xkb_mod_index_t i;
|
||||
int nextFree;
|
||||
xkb_mod_mask_t bit;
|
||||
const struct xkb_vmod *vmod;
|
||||
struct xkb_vmod new;
|
||||
|
||||
if (stmt->value)
|
||||
log_err(keymap->ctx,
|
||||
"Support for setting a value in a virtual_modifiers statement has been removed; "
|
||||
"Value ignored\n");
|
||||
|
||||
nextFree = -1;
|
||||
for (i = 0, bit = 1; i < XKB_NUM_VIRTUAL_MODS; i++, bit <<= 1) {
|
||||
if (!(info->defined & bit)) {
|
||||
if (nextFree < 0)
|
||||
nextFree = i;
|
||||
continue;
|
||||
darray_enumerate(i, vmod, keymap->vmods) {
|
||||
if (vmod->name == stmt->name) {
|
||||
info->available |= 1 << i;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Already defined. */
|
||||
if (!keymap->vmod_names[i])
|
||||
continue;
|
||||
|
||||
if (keymap->vmod_names[i] != stmt->name)
|
||||
continue;
|
||||
|
||||
info->available |= bit;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nextFree < 0) {
|
||||
if (darray_size(keymap->vmods) >= XKB_MAX_VIRTUAL_MODS) {
|
||||
log_err(keymap->ctx,
|
||||
"Too many virtual modifiers defined (maximum %d)\n",
|
||||
XKB_NUM_VIRTUAL_MODS);
|
||||
XKB_MAX_VIRTUAL_MODS);
|
||||
return false;
|
||||
}
|
||||
|
||||
info->defined |= (1 << nextFree);
|
||||
info->available |= (1 << nextFree);
|
||||
|
||||
keymap->vmod_names[nextFree] = stmt->name;
|
||||
new.name = stmt->name;
|
||||
new.mapping = 0;
|
||||
darray_append(keymap->vmods, new);
|
||||
info->available |= (1 << (darray_size(keymap->vmods) - 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -90,13 +77,14 @@ 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;
|
||||
|
||||
for (i = 0; i < XKB_NUM_VIRTUAL_MODS; i++) {
|
||||
if (keymap->vmod_names[i] == field) {
|
||||
darray_enumerate(i, vmod, keymap->vmods) {
|
||||
if (vmod->name == field) {
|
||||
*val_rtrn = i;
|
||||
return true;
|
||||
}
|
||||
|
@ -126,6 +114,7 @@ bool
|
|||
ResolveVirtualModifier(ExprDef *def, struct xkb_keymap *keymap,
|
||||
xkb_mod_index_t *ndx_rtrn, VModInfo *info)
|
||||
{
|
||||
const struct xkb_vmod *vmod;
|
||||
xkb_mod_index_t i;
|
||||
xkb_atom_t name = def->value.str;
|
||||
|
||||
|
@ -137,8 +126,8 @@ ResolveVirtualModifier(ExprDef *def, struct xkb_keymap *keymap,
|
|||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < XKB_NUM_VIRTUAL_MODS; i++) {
|
||||
if ((info->available & (1 << i)) && keymap->vmod_names[i] == name) {
|
||||
darray_enumerate(i, vmod, keymap->vmods) {
|
||||
if ((info->available & (1 << i)) && vmod->name == name) {
|
||||
*ndx_rtrn = i;
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue