[PATCH libxkbcommon 2/4] compose: add xkbcommon-compose - implementation

Ran Benita ran234 at gmail.com
Mon Sep 15 04:58:48 PDT 2014


On Mon, Sep 15, 2014 at 08:21:34AM +0200, David Herrmann wrote:
> Hi
> 
> On Sun, Sep 14, 2014 at 11:05 PM, Ran Benita <ran234 at gmail.com> wrote:
> > Signed-off-by: Ran Benita <ran234 at gmail.com>
> > ---
> 
> [snip]
> 
> > diff --git a/src/compose/state.c b/src/compose/state.c
> > new file mode 100644
> > index 0000000..06e4ce5
> > --- /dev/null
> > +++ b/src/compose/state.c
> > @@ -0,0 +1,196 @@
> > +/*
> > + * Copyright © 2013 Ran Benita <ran234 at gmail.com>
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> > + * DEALINGS IN THE SOFTWARE.
> > + */
> > +
> > +#include "table.h"
> > +#include "utils.h"
> > +#include "keysym.h"
> > +
> > +struct xkb_compose_state {
> > +    int refcnt;
> > +    enum xkb_compose_state_flags flags;
> > +    struct xkb_compose_table *table;
> > +
> > +    /*
> > +     * Offsets into xkb_compose_table::nodes.
> > +     *
> > +     * They maintain the current and previous position in the trie; see
> > +     * xkb_compose_state_feed().
> > +     *
> > +     * This is also sufficient for inferring the current status; see
> > +     * xkb_compose_state_get_status().
> > +     */
> > +    uint32_t prev_context;
> > +    uint32_t context;
> > +};
> > +
> > +XKB_EXPORT struct xkb_compose_state *
> > +xkb_compose_state_new(struct xkb_compose_table *table,
> > +                      enum xkb_compose_state_flags flags)
> > +{
> > +    struct xkb_compose_state *state;
> > +
> > +    state = calloc(1, sizeof(*state));
> > +    if (!state)
> > +        return NULL;
> > +
> > +    state->refcnt = 1;
> > +    state->table = xkb_compose_table_ref(table);
> > +
> > +    state->flags = flags;
> > +    state->prev_context = 0;
> > +    state->context = 0;
> > +
> > +    return state;
> > +}
> > +
> > +XKB_EXPORT struct xkb_compose_state *
> > +xkb_compose_state_ref(struct xkb_compose_state *state)
> > +{
> > +    state->refcnt++;
> > +    return state;
> > +}
> > +
> > +XKB_EXPORT void
> > +xkb_compose_state_unref(struct xkb_compose_state *state)
> > +{
> > +    if (!state || --state->refcnt > 0)
> > +        return;
> > +
> > +    xkb_compose_table_unref(state->table);
> > +    free(state);
> > +}
> > +
> > +XKB_EXPORT struct xkb_compose_table *
> > +xkb_compose_state_get_compose_table(struct xkb_compose_state *state)
> > +{
> > +    return state->table;
> > +}
> > +
> > +XKB_EXPORT enum xkb_compose_feed_result
> > +xkb_compose_state_feed(struct xkb_compose_state *state, xkb_keysym_t keysym)
> > +{
> > +    uint32_t context;
> > +    const struct compose_node *node;
> > +
> > +    /*
> > +     * Modifiers do not affect the sequence directly.  In particular,
> > +     * they do not cancel a sequence; otherwise it'd be impossible to
> > +     * have a sequence like <dead_acute><A> (needs Shift in the middle).
> > +     *
> > +     * The following test is not really accurate - in order to test if
> > +     * a key is "modifier key", we really need the keymap, but we don't
> > +     * have it here.  However, this is (approximately) what libX11 does
> > +     * as well.
> > +     */
> > +    if (xkb_keysym_is_modifier(keysym))
> > +        return XKB_COMPOSE_FEED_IGNORED;
> 
> Why don't we require a keymap in xkb_compose_state_new()? Should be
> easy to do and we can then track modifiers reliably.
> Ok, a keysym which is a modifier in one keymap should never be a
> normal key in another.. unlike keycodes. But I don't see why we need
> to rely on that when we can just take a keymap.

I prefer not adding a dependency on a keymap just for this one little
thing. That would preclude people who don't use xkbcommon keymaps from
using xkbcommon-compose (not likely, but maybe), and complicate the API
slightly. For not much gain..

Also, that's what the de facto specification here (Xlib) says, so it's not
a bug, it's a feature :)

> Otherwise, looks good (I didn't read through the parser, though).

Thanks again!
Ran

> Thanks
> David


More information about the wayland-devel mailing list