diff --git a/src/keymap-dump.c b/src/keymap-dump.c index 920a846..fc9b7bf 100644 --- a/src/keymap-dump.c +++ b/src/keymap-dump.c @@ -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"); diff --git a/src/keymap.c b/src/keymap.c index 7761858..df215b5 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -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; diff --git a/src/keymap.h b/src/keymap.h index 74efe78..11fa743 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -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; diff --git a/src/state.c b/src/state.c index f54a607..1511342 100644 --- a/src/state.c +++ b/src/state.c @@ -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)); diff --git a/src/xkbcomp/compat.c b/src/xkbcomp/compat.c index e6905ae..d19b9cc 100644 --- a/src/xkbcomp/compat.c +++ b/src/xkbcomp/compat.c @@ -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) diff --git a/src/xkbcomp/keycodes.c b/src/xkbcomp/keycodes.c index 89a2524..f2a5e09 100644 --- a/src/xkbcomp/keycodes.c +++ b/src/xkbcomp/keycodes.c @@ -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); diff --git a/src/xkbcomp/keymap.c b/src/xkbcomp/keymap.c index 90ee7d7..78ba966 100644 --- a/src/xkbcomp/keymap.c +++ b/src/xkbcomp/keymap.c @@ -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)