Remove the XKB_NUM_INDICATORS limit

Use a darray instead of a static array of size 32.
We still enforce XKB_MAX_LEDS because of the size of xkb_led_mask_t.

Signed-off-by: Ran Benita <ran234@gmail.com>
master
Ran Benita 2012-10-10 19:08:01 +02:00
parent f3732d8349
commit 9197eb0fb3
7 changed files with 75 additions and 69 deletions

View File

@ -227,6 +227,7 @@ write_keycodes(struct xkb_keymap *keymap, struct buf *buf)
struct xkb_key *key;
struct xkb_key_alias *alias;
xkb_led_index_t i;
const struct xkb_indicator_map *im;
if (keymap->keycodes_section_name)
write_buf(buf, "\txkb_keycodes \"%s\" {\n",
@ -242,12 +243,10 @@ write_keycodes(struct xkb_keymap *keymap, struct buf *buf)
KeyNameText(keymap->ctx, key->name), key->keycode);
}
for (i = 0; i < XKB_NUM_INDICATORS; i++) {
if (keymap->indicators[i].name == XKB_ATOM_NONE)
continue;
write_buf(buf, "\t\tindicator %d = \"%s\";\n", i + 1,
xkb_atom_text(keymap->ctx, keymap->indicators[i].name));
}
darray_enumerate(i, im, keymap->indicators)
if (im->name != XKB_ATOM_NONE)
write_buf(buf, "\t\tindicator %d = \"%s\";\n",
i + 1, xkb_atom_text(keymap->ctx, im->name));
darray_foreach(alias, keymap->key_aliases)
@ -322,12 +321,11 @@ write_types(struct xkb_keymap *keymap, struct buf *buf)
}
static bool
write_indicator_map(struct xkb_keymap *keymap, struct buf *buf, int num)
write_indicator_map(struct xkb_keymap *keymap, struct buf *buf,
const struct xkb_indicator_map *led)
{
struct xkb_indicator_map *led = &keymap->indicators[num];
write_buf(buf, "\t\tindicator \"%s\" {\n",
xkb_atom_text(keymap->ctx, keymap->indicators[num].name));
xkb_atom_text(keymap->ctx, led->name));
if (led->which_groups) {
if (led->which_groups != XKB_STATE_EFFECTIVE) {
@ -499,8 +497,8 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
static bool
write_compat(struct xkb_keymap *keymap, struct buf *buf)
{
int i;
struct xkb_sym_interpret *interp;
const struct xkb_indicator_map *led;
if (keymap->compat_section_name)
write_buf(buf, "\txkb_compatibility \"%s\" {\n\n",
@ -539,14 +537,10 @@ write_compat(struct xkb_keymap *keymap, struct buf *buf)
write_buf(buf, "\t\t};\n");
}
for (i = 0; i < XKB_NUM_INDICATORS; i++) {
struct xkb_indicator_map *map = &keymap->indicators[i];
if (map->which_groups == 0 && map->groups == 0 &&
map->which_mods == 0 && map->mods.mods == 0 &&
map->ctrls == 0)
continue;
write_indicator_map(keymap, buf, i);
}
darray_foreach(led, keymap->indicators)
if (led->which_groups || led->groups || led->which_mods ||
led->mods.mods || led->ctrls)
write_indicator_map(keymap, buf, led);
write_buf(buf, "\t};\n\n");

View File

@ -110,6 +110,7 @@ xkb_keymap_unref(struct xkb_keymap *keymap)
darray_free(keymap->key_aliases);
darray_free(keymap->group_names);
darray_free(keymap->mods);
darray_free(keymap->indicators);
free(keymap->keycodes_section_name);
free(keymap->symbols_section_name);
free(keymap->types_section_name);
@ -237,13 +238,12 @@ xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc,
XKB_EXPORT xkb_led_index_t
xkb_keymap_num_leds(struct xkb_keymap *keymap)
{
const struct xkb_indicator_map *led;
xkb_led_index_t ret = 0;
xkb_led_index_t i;
for (i = 0; i < XKB_NUM_INDICATORS; i++)
if (keymap->indicators[i].which_groups ||
keymap->indicators[i].which_mods ||
keymap->indicators[i].ctrls)
darray_foreach(led, keymap->indicators)
if (led->which_groups || led->groups || led->which_mods ||
led->mods.mods || led->ctrls)
ret++;
return ret;
@ -255,26 +255,28 @@ xkb_keymap_num_leds(struct xkb_keymap *keymap)
XKB_EXPORT const char *
xkb_keymap_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx)
{
if (idx >= XKB_NUM_INDICATORS)
if (idx >= darray_size(keymap->indicators))
return NULL;
return xkb_atom_text(keymap->ctx, keymap->indicators[idx].name);
return xkb_atom_text(keymap->ctx,
darray_item(keymap->indicators, idx).name);
}
/**
* Returns the index for a named group.
*/
XKB_EXPORT xkb_layout_index_t
XKB_EXPORT xkb_led_index_t
xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name)
{
xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
xkb_led_index_t i;
const struct xkb_indicator_map *led;
if (atom == XKB_ATOM_NONE)
return XKB_LED_INVALID;
for (i = 0; i < XKB_NUM_INDICATORS; i++)
if (keymap->indicators[i].name == atom)
darray_enumerate(i, led, keymap->indicators)
if (led->name == atom)
return i;
return XKB_LED_INVALID;

View File

@ -106,15 +106,15 @@
/* Don't allow more modifiers than we can hold in xkb_mod_mask_t. */
#define XKB_MAX_MODS ((xkb_mod_index_t) (sizeof(xkb_mod_mask_t) * 8))
/* These should all be dynamic. */
#define XKB_NUM_INDICATORS 32
/* Don't allow more leds than we can hold in xkb_led_mask_t. */
#define XKB_MAX_LEDS ((xkb_led_index_t) (sizeof(xkb_led_mask_t) * 8))
/* These should all go away. */
enum mod_type {
MOD_REAL = (1 << 0),
MOD_VIRT = (1 << 1),
MOD_BOTH = (MOD_REAL | MOD_VIRT),
};
#define MOD_REAL_MASK_ALL ((xkb_mod_mask_t) 0x000000ff)
enum xkb_action_type {
@ -398,7 +398,7 @@ struct xkb_keymap {
xkb_layout_index_t num_groups;
darray_xkb_atom_t group_names;
struct xkb_indicator_map indicators[XKB_NUM_INDICATORS];
darray(struct xkb_indicator_map) indicators;
char *keycodes_section_name;
char *symbols_section_name;

View File

@ -590,11 +590,11 @@ static void
xkb_state_led_update_all(struct xkb_state *state)
{
xkb_led_index_t led;
const struct xkb_indicator_map *map;
state->leds = 0;
for (led = 0; led < XKB_NUM_INDICATORS; led++) {
struct xkb_indicator_map *map = &state->keymap->indicators[led];
darray_enumerate(led, map, state->keymap->indicators) {
xkb_mod_mask_t mod_mask = 0;
xkb_layout_mask_t group_mask = 0;
@ -996,8 +996,8 @@ xkb_state_layout_name_is_active(struct xkb_state *state, const char *name,
XKB_EXPORT int
xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
{
if (idx >= XKB_NUM_INDICATORS ||
state->keymap->indicators[idx].name == XKB_ATOM_NONE)
if (idx >= darray_size(state->keymap->indicators) ||
darray_item(state->keymap->indicators, idx).name == XKB_ATOM_NONE)
return -1;
return !!(state->leds & (1 << idx));

View File

@ -945,34 +945,38 @@ CopyIndicatorMapDefs(CompatInfo *info)
* Find the indicator with the given name, if it was already
* declared in keycodes.
*/
for (i = 0; i < XKB_NUM_INDICATORS; i++)
if (keymap->indicators[i].name == led->im.name)
darray_enumerate(i, im, keymap->indicators)
if (im->name == led->im.name)
break;
/* Not previously declared; create it with next free index. */
if (i >= XKB_NUM_INDICATORS) {
if (i >= darray_size(keymap->indicators)) {
log_dbg(keymap->ctx,
"Indicator name \"%s\" was not declared in the keycodes section; "
"Adding new indicator\n",
xkb_atom_text(keymap->ctx, led->im.name));
for (i = 0; i < XKB_NUM_INDICATORS; i++)
if (keymap->indicators[i].name == XKB_ATOM_NONE)
darray_enumerate(i, im, keymap->indicators)
if (im->name == XKB_ATOM_NONE)
break;
/* Not place to put it; ignore. */
if (i >= XKB_NUM_INDICATORS) {
log_err(keymap->ctx,
"Too many indicators (maximum is %d); "
"Indicator name \"%s\" ignored\n",
XKB_NUM_INDICATORS,
xkb_atom_text(keymap->ctx, led->im.name));
continue;
if (i >= darray_size(keymap->indicators)) {
/* Not place to put it; ignore. */
if (i >= XKB_MAX_LEDS) {
log_err(keymap->ctx,
"Too many indicators (maximum is %d); "
"Indicator name \"%s\" ignored\n",
XKB_MAX_LEDS,
xkb_atom_text(keymap->ctx, led->im.name));
continue;
}
/* Add a new indicator. */
darray_resize(keymap->indicators, i + 1);
im = &darray_item(keymap->indicators, i);
}
}
im = &keymap->indicators[i];
*im = led->im;
*im = led->im;
if (im->groups != 0 && im->which_groups == 0)
im->which_groups = XKB_STATE_EFFECTIVE;
if (im->mods.mods != 0 && im->which_mods == 0)

View File

@ -132,7 +132,7 @@ typedef struct {
xkb_keycode_t min_key_code;
xkb_keycode_t max_key_code;
darray(KeyNameInfo) key_names;
IndicatorNameInfo indicator_names[XKB_NUM_INDICATORS];
darray(IndicatorNameInfo) indicator_names;
darray(AliasInfo) aliases;
struct xkb_context *ctx;
@ -153,12 +153,13 @@ static IndicatorNameInfo *
FindIndicatorByName(KeyNamesInfo *info, xkb_atom_t name,
xkb_led_index_t *idx_out)
{
IndicatorNameInfo *led;
xkb_led_index_t idx;
for (idx = 0; idx < XKB_NUM_INDICATORS; idx++) {
if (info->indicator_names[idx].name == name) {
darray_enumerate(idx, led, info->indicator_names) {
if (led->name == name) {
*idx_out = idx;
return &info->indicator_names[idx];
return led;
}
}
@ -204,8 +205,11 @@ AddIndicatorName(KeyNamesInfo *info, enum merge_mode merge,
return true;
}
if (new_idx >= darray_size(info->indicator_names))
darray_resize0(info->indicator_names, new_idx + 1);
/* Inidicator with the same index already exists. */
old = &info->indicator_names[new_idx];
old = &darray_item(info->indicator_names, new_idx);
if (old->name != XKB_ATOM_NONE) {
bool report = ((old->file_id == new->file_id && verbosity > 0) ||
verbosity > 9);
@ -227,7 +231,7 @@ AddIndicatorName(KeyNamesInfo *info, enum merge_mode merge,
return true;
}
info->indicator_names[new_idx] = *new;
darray_item(info->indicator_names, new_idx) = *new;
return true;
}
@ -237,6 +241,7 @@ ClearKeyNamesInfo(KeyNamesInfo *info)
free(info->name);
darray_free(info->key_names);
darray_free(info->aliases);
darray_free(info->indicator_names);
}
static void
@ -377,6 +382,7 @@ MergeIncludedKeycodes(KeyNamesInfo *into, KeyNamesInfo *from,
{
xkb_keycode_t i;
xkb_led_index_t idx;
IndicatorNameInfo *led;
if (from->errorCount > 0) {
into->errorCount += from->errorCount;
@ -400,8 +406,7 @@ MergeIncludedKeycodes(KeyNamesInfo *into, KeyNamesInfo *from,
into->errorCount++;
}
for (idx = 0; idx < XKB_NUM_INDICATORS; idx++) {
IndicatorNameInfo *led = &from->indicator_names[idx];
darray_enumerate(idx, led, from->indicator_names) {
if (led->name == XKB_ATOM_NONE)
continue;
@ -561,11 +566,11 @@ HandleIndicatorNameDef(KeyNamesInfo *info, IndicatorNameDef *def,
IndicatorNameInfo ii;
xkb_atom_t name;
if (def->ndx < 1 || def->ndx > XKB_NUM_INDICATORS) {
if (def->ndx < 1 || def->ndx > XKB_MAX_LEDS) {
info->errorCount++;
log_err(info->ctx,
"Name specified for illegal indicator index %d\n; Ignored\n",
def->ndx);
"Illegal indicator index (%d) specified; must be between 1 .. %d; "
"Ignored\n", def->ndx, XKB_MAX_LEDS);
return false;
}
@ -689,6 +694,7 @@ CopyKeyNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info)
{
xkb_keycode_t kc;
xkb_led_index_t idx;
IndicatorNameInfo *led;
keymap->keys = calloc(info->max_key_code + 1, sizeof(*keymap->keys));
if (!keymap->keys)
@ -704,12 +710,12 @@ CopyKeyNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info)
keymap->keycodes_section_name = strdup_safe(info->name);
for (idx = 0; idx < XKB_NUM_INDICATORS; idx++) {
IndicatorNameInfo *led = &info->indicator_names[idx];
darray_resize0(keymap->indicators, darray_size(info->indicator_names));
darray_enumerate(idx, led, info->indicator_names) {
if (led->name == XKB_ATOM_NONE)
continue;
keymap->indicators[idx].name = led->name;
darray_item(keymap->indicators, idx).name = led->name;
}
ApplyAliases(info, keymap);

View File

@ -185,7 +185,7 @@ static bool
UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
{
struct xkb_mod *mod;
xkb_led_index_t led;
struct xkb_indicator_map *im;
unsigned int i, j;
struct xkb_key *key;
@ -219,8 +219,8 @@ UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
key->modmap);
/* Update vmod -> indicator maps. */
for (led = 0; led < XKB_NUM_INDICATORS; led++)
ComputeEffectiveMask(keymap, &keymap->indicators[led].mods);
darray_foreach(im, keymap->indicators)
ComputeEffectiveMask(keymap, &im->mods);
/* Find maximum number of groups out of all keys in the keymap. */
xkb_foreach_key(key, keymap)