From: Ran Benita Date: Mon, 22 Oct 2012 19:00:57 +0000 (+0200) Subject: Report which components of the state have changed X-Git-Tag: xkbcommon-0.2.0~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4b81c9f3e31a5128d4c9f55696f684948e5ad3f1;p=platform%2Fupstream%2Flibxkbcommon.git Report which components of the state have changed We add a return value to the xkb_state_update_key and xkb_state_update_mask, which reports to the caller which of the state components have changed as a result. This restores the XKB functionality of the XkbStateNotify and XkbIndicatorsStateNotify events. See: http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Events It is quite useful in some situations. For example, it allows an application to avoid doing some work if nothing of relevance in the state has changed. Say, a keyboard layout applet. Also useful for debugging. The deltas themselves are not provided, because I can't see a use case. If needed, it should be possible to add some API for that. In xkbcommon, keymaps are immutable, so all of the other *Notify events from XKB are irrelevant. Signed-off-by: Ran Benita --- diff --git a/src/state.c b/src/state.c index 56a8667..c8e3147 100644 --- a/src/state.c +++ b/src/state.c @@ -88,7 +88,11 @@ struct state_components { }; struct xkb_state { - struct state_components cur; + /* + * Before updating the state, we keep a copy. This allows us to report + * which components of the state have changed. + */ + struct state_components cur, prev; /* * At each event, we accumulate all the needed modifications to the base @@ -96,6 +100,7 @@ struct xkb_state { */ xkb_mod_mask_t set_mods; xkb_mod_mask_t clear_mods; + /* * We mustn't clear a base modifier if there's another depressed key * which affects it, e.g. given this sequence @@ -657,11 +662,39 @@ xkb_state_update_derived(struct xkb_state *state) xkb_state_led_update_all(state); } +static enum xkb_state_component +get_state_component_changes(const struct state_components *a, + const struct state_components *b) +{ + xkb_mod_mask_t mask = 0; + + if (a->group != b->group) + mask |= XKB_STATE_LAYOUT_EFFECTIVE; + if (a->base_group != b->base_group) + mask |= XKB_STATE_LAYOUT_DEPRESSED; + if (a->latched_group != b->latched_group) + mask |= XKB_STATE_LAYOUT_LATCHED; + if (a->locked_group != b->locked_group) + mask |= XKB_STATE_LAYOUT_LOCKED; + if (a->mods != b->mods) + mask |= XKB_STATE_MODS_EFFECTIVE; + if (a->base_mods != b->base_mods) + mask |= XKB_STATE_MODS_DEPRESSED; + if (a->latched_mods != b->latched_mods) + mask |= XKB_STATE_MODS_LATCHED; + if (a->locked_mods != b->locked_mods) + mask |= XKB_STATE_MODS_LOCKED; + if (a->leds != b->leds) + mask |= XKB_STATE_LEDS; + + return mask; +} + /** * Given a particular key event, updates the state structure to reflect the * new modifiers. */ -XKB_EXPORT void +XKB_EXPORT enum xkb_state_component xkb_state_update_key(struct xkb_state *state, xkb_keycode_t kc, enum xkb_key_direction direction) { @@ -670,7 +703,9 @@ xkb_state_update_key(struct xkb_state *state, xkb_keycode_t kc, const struct xkb_key *key = XkbKey(state->keymap, kc); if (!key) - return; + return 0; + + state->prev = state->cur; state->set_mods = 0; state->clear_mods = 0; @@ -697,6 +732,8 @@ xkb_state_update_key(struct xkb_state *state, xkb_keycode_t kc, } xkb_state_update_derived(state); + + return get_state_component_changes(&state->prev, &state->cur); } /** @@ -706,7 +743,7 @@ xkb_state_update_key(struct xkb_state *state, xkb_keycode_t kc, * lossy, and should only be used to update a slave state mirroring the * master, e.g. in a client/server window system. */ -XKB_EXPORT void +XKB_EXPORT enum xkb_state_component xkb_state_update_mask(struct xkb_state *state, xkb_mod_mask_t base_mods, xkb_mod_mask_t latched_mods, @@ -718,6 +755,8 @@ xkb_state_update_mask(struct xkb_state *state, xkb_mod_index_t num_mods; xkb_mod_index_t idx; + state->cur = state->prev; + state->cur.base_mods = 0; state->cur.latched_mods = 0; state->cur.locked_mods = 0; @@ -738,6 +777,8 @@ xkb_state_update_mask(struct xkb_state *state, state->cur.locked_group = locked_group; xkb_state_update_derived(state); + + return get_state_component_changes(&state->prev, &state->cur); } /** diff --git a/xkbcommon/xkbcommon.h b/xkbcommon/xkbcommon.h index 846b619..e9b324f 100644 --- a/xkbcommon/xkbcommon.h +++ b/xkbcommon/xkbcommon.h @@ -965,14 +965,49 @@ enum xkb_key_direction { }; /** + * Modifier and layout types for state objects. This enum is bitmaskable, + * e.g. (XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED) is valid to + * exclude locked modifiers. + * + * In XKB, the DEPRESSED states are also known as 'base'. + */ +enum xkb_state_component { + /** Depressed modifiers, i.e. a key is physically holding them. */ + XKB_STATE_MODS_DEPRESSED = (1 << 0), + /** Latched modifiers, i.e. will be unset after the next non-modifier + * key press. */ + XKB_STATE_MODS_LATCHED = (1 << 1), + /** Locked modifiers, i.e. will be unset after the key provoking the + * lock has been pressed again. */ + XKB_STATE_MODS_LOCKED = (1 << 2), + /** Effective modifiers, i.e. currently active and affect key + * processing (derived from the other state components). */ + XKB_STATE_MODS_EFFECTIVE = (1 << 3), + /** Depressed layout, i.e. a key is physically holding it. */ + XKB_STATE_LAYOUT_DEPRESSED = (1 << 4), + /** Latched layout, i.e. will be unset after the next non-modifier + * key press. */ + XKB_STATE_LAYOUT_LATCHED = (1 << 5), + /** Locked layout, i.e. will be unset after the key provoking the lock + * has been pressed again. */ + XKB_STATE_LAYOUT_LOCKED = (1 << 6), + /** Effective layout, i.e. currently active and affects key processing + * (derived from the other state components). */ + XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7), + /** LEDs (derived from the other state components). */ + XKB_STATE_LEDS = (1 << 8), +}; + +/** * Update the keyboard state to reflect a given key being pressed or * released. * - * @todo Explain. + * @returns A mask of state components that have changed as a result of + * the update. If nothing in the state has changed, returns 0. * * @memberof xkb_state */ -void +enum xkb_state_component xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key, enum xkb_key_direction direction); @@ -1101,40 +1136,6 @@ xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap, const xkb_keysym_t **syms_out); /** - * Modifier and layout types for state objects. This enum is bitmaskable, - * e.g. (XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED) is valid to - * exclude locked modifiers. - * - * In XKB, the DEPRESSED states are also known as 'base'. - */ -enum xkb_state_component { - /** Depressed modifiers, i.e. a key is physically holding them. */ - XKB_STATE_MODS_DEPRESSED = (1 << 0), - /** Latched modifiers, i.e. will be unset after the next non-modifier - * key press. */ - XKB_STATE_MODS_LATCHED = (1 << 1), - /** Locked modifiers, i.e. will be unset after the key provoking the - * lock has been pressed again. */ - XKB_STATE_MODS_LOCKED = (1 << 2), - /** Effective modifiers, i.e. currently active and affect key - * processing (derived from the other state components). */ - XKB_STATE_MODS_EFFECTIVE = (1 << 3), - /** Depressed layout, i.e. a key is physically holding it. */ - XKB_STATE_LAYOUT_DEPRESSED = (1 << 4), - /** Latched layout, i.e. will be unset after the next non-modifier - * key press. */ - XKB_STATE_LAYOUT_LATCHED = (1 << 5), - /** Locked layout, i.e. will be unset after the key provoking the lock - * has been pressed again. */ - XKB_STATE_LAYOUT_LOCKED = (1 << 6), - /** Effective layout, i.e. currently active and affects key processing - * (derived from the other state components). */ - XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7), - /** LEDs (derived from the other state components). */ - XKB_STATE_LEDS = (1 << 8), -}; - -/** * Match flags for xkb_state_mod_indices_are_active and * xkb_state_mod_names_are_active, specifying how the conditions for a * successful match. XKB_STATE_MATCH_NON_EXCLUSIVE is bitmaskable with @@ -1167,11 +1168,16 @@ enum xkb_state_match { * * Please do not use this unless you fit the description above. * + * @returns A mask of state components that have changed as a result of + * the update. If nothing in the state has changed, returns 0. + * * @memberof xkb_state */ -void -xkb_state_update_mask(struct xkb_state *state, xkb_mod_mask_t base_mods, - xkb_mod_mask_t latched_mods, xkb_mod_mask_t locked_mods, +enum xkb_state_component +xkb_state_update_mask(struct xkb_state *state, + xkb_mod_mask_t base_mods, + xkb_mod_mask_t latched_mods, + xkb_mod_mask_t locked_mods, xkb_layout_index_t base_layout, xkb_layout_index_t latched_layout, xkb_layout_index_t locked_layout);