X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fkeymap.c;h=0291aedbb11c3c7c173aa04d25b26924b7c9360b;hb=ef81d04eef4b1a60ff42bd9ccbe2918b0a5420ec;hp=abf1387b37c1cc16b7d5ff20cc1644850848d35a;hpb=973b8fd47e885f1c80c715b317fa896f8d31a7a4;p=platform%2Fupstream%2Flibxkbcommon.git diff --git a/src/keymap.c b/src/keymap.c index abf1387..0291aed 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -50,6 +50,8 @@ * * ********************************************************/ +#include "config.h" + #include "keymap.h" #include "text.h" @@ -68,11 +70,11 @@ xkb_keymap_unref(struct xkb_keymap *keymap) if (keymap->keys) { struct xkb_key *key; - xkb_foreach_key(key, keymap) { + xkb_keys_foreach(key, keymap) { if (key->groups) { for (unsigned i = 0; i < key->num_groups; i++) { if (key->groups[i].levels) { - for (unsigned j = 0; j < XkbKeyGroupWidth(key, i); j++) + for (unsigned j = 0; j < XkbKeyNumLevels(key, i); j++) if (key->groups[i].levels[j].num_syms > 1) free(key->groups[i].levels[j].u.syms); free(key->groups[i].levels); @@ -93,8 +95,6 @@ xkb_keymap_unref(struct xkb_keymap *keymap) free(keymap->sym_interprets); free(keymap->key_aliases); free(keymap->group_names); - darray_free(keymap->mods); - darray_free(keymap->leds); free(keymap->keycodes_section_name); free(keymap->symbols_section_name); free(keymap->types_section_name); @@ -137,28 +137,15 @@ xkb_keymap_new_from_names(struct xkb_context *ctx, return NULL; } + keymap = xkb_keymap_new(ctx, format, flags); + if (!keymap) + return NULL; + if (rmlvo_in) rmlvo = *rmlvo_in; else memset(&rmlvo, 0, sizeof(rmlvo)); - - if (isempty(rmlvo.rules)) - rmlvo.rules = xkb_context_get_default_rules(ctx); - if (isempty(rmlvo.model)) - rmlvo.model = xkb_context_get_default_model(ctx); - /* Layout and variant are tied together, so don't try to use one from - * the caller and one from the environment. */ - if (isempty(rmlvo.layout)) { - rmlvo.layout = xkb_context_get_default_layout(ctx); - rmlvo.variant = xkb_context_get_default_variant(ctx); - } - /* Options can be empty, so respect that if passed in. */ - if (rmlvo.options == NULL) - rmlvo.options = xkb_context_get_default_options(ctx); - - keymap = xkb_keymap_new(ctx, format, flags); - if (!keymap) - return NULL; + xkb_context_sanitize_rule_names(ctx, &rmlvo); if (!ops->keymap_new_from_names(keymap, &rmlvo)) { xkb_keymap_unref(keymap); @@ -207,6 +194,10 @@ xkb_keymap_new_from_buffer(struct xkb_context *ctx, if (!keymap) return NULL; + /* Allow a zero-terminated string as a buffer */ + if (length > 0 && buffer[length - 1] == '\0') + length--; + if (!ops->keymap_new_from_string(keymap, buffer, length)) { xkb_keymap_unref(keymap); return NULL; @@ -276,7 +267,7 @@ xkb_keymap_get_as_string(struct xkb_keymap *keymap, XKB_EXPORT xkb_mod_index_t xkb_keymap_num_mods(struct xkb_keymap *keymap) { - return darray_size(keymap->mods); + return keymap->mods.num_mods; } /** @@ -285,10 +276,10 @@ xkb_keymap_num_mods(struct xkb_keymap *keymap) XKB_EXPORT const char * xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx) { - if (idx >= darray_size(keymap->mods)) + if (idx >= keymap->mods.num_mods) return NULL; - return xkb_atom_text(keymap->ctx, darray_item(keymap->mods, idx).name); + return xkb_atom_text(keymap->ctx, keymap->mods.mods[idx].name); } /** @@ -297,19 +288,13 @@ xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx) XKB_EXPORT xkb_mod_index_t xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name) { - xkb_mod_index_t i; xkb_atom_t atom; - const struct xkb_mod *mod; atom = xkb_atom_lookup(keymap->ctx, name); if (atom == XKB_ATOM_NONE) return XKB_MOD_INVALID; - darray_enumerate(i, mod, keymap->mods) - if (mod->name == atom) - return i; - - return XKB_MOD_INVALID; + return XkbModNameToIndex(&keymap->mods, atom, MOD_BOTH); } /** @@ -378,13 +363,13 @@ xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc, if (!key) return 0; - layout = wrap_group_into_range(layout, key->num_groups, + layout = XkbWrapGroupIntoRange(layout, key->num_groups, key->out_of_range_group_action, key->out_of_range_group_number); if (layout == XKB_LAYOUT_INVALID) return 0; - return XkbKeyGroupWidth(key, layout); + return XkbKeyNumLevels(key, layout); } /** @@ -393,7 +378,7 @@ 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) { - return darray_size(keymap->leds); + return keymap->num_leds; } /** @@ -402,10 +387,10 @@ 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 >= darray_size(keymap->leds)) + if (idx >= keymap->num_leds) return NULL; - return xkb_atom_text(keymap->ctx, darray_item(keymap->leds, idx).name); + return xkb_atom_text(keymap->ctx, keymap->leds[idx].name); } /** @@ -421,13 +406,73 @@ xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name) if (atom == XKB_ATOM_NONE) return XKB_LED_INVALID; - darray_enumerate(i, led, keymap->leds) + xkb_leds_enumerate(i, led, keymap) if (led->name == atom) return i; return XKB_LED_INVALID; } +XKB_EXPORT size_t +xkb_keymap_key_get_mods_for_level(struct xkb_keymap *keymap, + xkb_keycode_t kc, + xkb_layout_index_t layout, + xkb_level_index_t level, + xkb_mod_mask_t *masks_out, + size_t masks_size) +{ + const struct xkb_key *key = XkbKey(keymap, kc); + if (!key) + return 0; + + layout = XkbWrapGroupIntoRange(layout, key->num_groups, + key->out_of_range_group_action, + key->out_of_range_group_number); + if (layout == XKB_LAYOUT_INVALID) + return 0; + + if (level >= XkbKeyNumLevels(key, layout)) + return 0; + + const struct xkb_key_type *type = key->groups[layout].type; + + size_t count = 0; + + /* + * If the active set of modifiers doesn't match any explicit entry of + * the key type, the resulting level is 0 (i.e. Level 1). + * So, if we are asked to find the modifiers for level==0, we can offer + * an ~infinite supply, which is not very workable. + * What we do instead, is special case the empty set of modifiers for + * this purpose. If the empty set isn't explicit mapped to a level, we + * take it to map to Level 1. + * This is almost always what we want. If applicable, given it priority + * over other ways to generate the level. + */ + if (level == 0) { + bool empty_mapped = false; + for (unsigned i = 0; i < type->num_entries && count < masks_size; i++) + if (entry_is_active(&type->entries[i]) && + type->entries[i].mods.mask == 0) { + empty_mapped = true; + break; + } + if (!empty_mapped && count < masks_size) { + masks_out[count++] = 0; + } + } + + /* Now search explicit mappings. */ + for (unsigned i = 0; i < type->num_entries && count < masks_size; i++) { + if (entry_is_active(&type->entries[i]) && + type->entries[i].level == level) { + masks_out[count++] = type->entries[i].mods.mask; + } + } + + return count; +} + /** * As below, but takes an explicit layout/level rather than state. */ @@ -444,13 +489,13 @@ xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap, if (!key) goto err; - layout = wrap_group_into_range(layout, key->num_groups, + layout = XkbWrapGroupIntoRange(layout, key->num_groups, key->out_of_range_group_action, key->out_of_range_group_number); if (layout == XKB_LAYOUT_INVALID) goto err; - if (level >= XkbKeyGroupWidth(key, layout)) + if (level >= XkbKeyNumLevels(key, layout)) goto err; num_syms = key->groups[layout].levels[level].num_syms; @@ -487,10 +532,44 @@ xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter, { struct xkb_key *key; - xkb_foreach_key(key, keymap) + xkb_keys_foreach(key, keymap) iter(keymap, key->keycode, data); } +XKB_EXPORT const char * +xkb_keymap_key_get_name(struct xkb_keymap *keymap, xkb_keycode_t kc) +{ + const struct xkb_key *key = XkbKey(keymap, kc); + + if (!key) + return NULL; + + return xkb_atom_text(keymap->ctx, key->name); +} + +XKB_EXPORT xkb_keycode_t +xkb_keymap_key_by_name(struct xkb_keymap *keymap, const char *name) +{ + struct xkb_key *key; + xkb_atom_t atom; + + atom = xkb_atom_lookup(keymap->ctx, name); + if (atom) { + xkb_atom_t ratom = XkbResolveKeyAlias(keymap, atom); + if (ratom) + atom = ratom; + } + if (!atom) + return XKB_KEYCODE_INVALID; + + xkb_keys_foreach(key, keymap) { + if (key->name == atom) + return key->keycode; + } + + return XKB_KEYCODE_INVALID; +} + /** * Simple boolean specifying whether or not the key should repeat. */