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
Ran Benita 2012-10-03 12:57:53 +02:00
parent 8016c6f4f1
commit dd29b14e11
6 changed files with 62 additions and 108 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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",

View File

@ -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++) {

View File

@ -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;
}