[PATCH libinput 14/24] tablet: handle button events
Peter Hutterer
peter.hutterer at who-t.net
Sun Apr 27 22:07:26 PDT 2014
On Mon, Apr 21, 2014 at 07:11:23PM +0200, Carlos Garnacho wrote:
> This works for stylus tap and primary/secondary button, and pad
> buttons.
>
> Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
> ---
> src/evdev-tablet.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> src/evdev-tablet.h | 3 ++
> 2 files changed, 107 insertions(+)
>
> diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> index fcd3396..0682563 100644
> --- a/src/evdev-tablet.c
> +++ b/src/evdev-tablet.c
> @@ -30,6 +30,11 @@
> #define tablet_unset_status(tablet,s) (tablet->status &= ~(s));
> #define tablet_has_status(tablet,s) (!!(tablet->status & s))
>
> +#define tablet_get_enabled_buttons(tablet,field) \
> + (tablet->state.field & ~(tablet->prev_state.field))
> +#define tablet_get_disabled_buttons(tablet,field) \
> + (tablet->prev_state.field & ~(tablet->state.field))
this is me being manic about type checks these days - I'd prefer these to be
inlines. Also: enabled and disabled, especially in a button context has
multiple meanings, can we use "down" and "up" instead?
> +
> static void
> tablet_process_absolute(struct tablet_dispatch *tablet,
> struct evdev_device *device,
> @@ -68,6 +73,31 @@ tablet_update_tool(struct tablet_dispatch *tablet,
> }
>
> static void
> +tablet_update_button(struct tablet_dispatch *tablet,
> + uint32_t evcode,
> + uint32_t enable)
> +{
> + uint32_t button, *flags;
> +
> + /* XXX: This really depends on the expected buttons fitting in the mask */
> + if (evcode >= BTN_MISC && evcode <= BTN_TASK) {
> + flags = &tablet->state.pad_buttons;
> + button = evcode - BTN_MISC;
> + } else if (evcode >= BTN_TOUCH && evcode <= BTN_STYLUS2) {
> + flags = &tablet->state.stylus_buttons;
> + button = evcode - BTN_TOUCH;
> + } else {
> + log_info("Unhandled button 0x%x\n", evcode);
best to use libevdev_event_code_get_name() here, together with the hex
code in case it's an undefined code.
> + return;
> + }
> +
> + if (enable)
> + (*flags) |= 1 << button;
> + else
> + (*flags) &= ~(1 << button);
> +}
> +
> +static void
> tablet_process_key(struct tablet_dispatch *tablet,
> struct evdev_device *device,
> struct input_event *e,
> @@ -85,7 +115,18 @@ tablet_process_key(struct tablet_dispatch *tablet,
> /* These codes have an equivalent libinput_tool value */
> tablet_update_tool(tablet, e->code, e->value);
> break;
> + case BTN_TOUCH:
> + if (e->value) {
> + tablet_set_status(tablet, TABLET_HAS_CONTACT);
> + } else {
> + tablet_unset_status(tablet, TABLET_HAS_CONTACT);
> + }
please don't use {} for single-line statements (provided both are
single-line)
> +
> + /* Fall through */
> + case BTN_STYLUS:
> + case BTN_STYLUS2:
> default:
> + tablet_update_button(tablet, e->code, e->value);
> break;
> }
> }
> @@ -131,6 +172,67 @@ tablet_check_notify_tool(struct tablet_dispatch *tablet,
> }
>
> static void
> +tablet_notify_button_mask(struct tablet_dispatch *tablet,
> + struct evdev_device *device,
> + uint32_t time,
> + uint32_t buttons,
> + uint32_t button_base,
> + enum libinput_pointer_button_state state)
> +{
> + struct libinput_device *base = &device->base;
> + int32_t num_button = 0;
> +
> + while (buttons) {
> + int enabled;
> +
> + num_button++;
> + enabled = (buttons & 1);
> + buttons >>= 1;
> +
> + if (!enabled)
> + continue;
> +
> + pointer_notify_button(base,
> + time,
> + num_button + button_base - 1,
> + state);
> + }
> +}
> +
> +static void
> +tablet_notify_buttons(struct tablet_dispatch *tablet,
> + struct evdev_device *device,
> + uint32_t time,
> + uint32_t post_check)
use bool for post_check
> +{
> + enum libinput_pointer_button_state state;
> + int32_t pad_buttons, stylus_buttons;
> +
> + if (tablet->state.pad_buttons == tablet->prev_state.pad_buttons &&
> + tablet->state.stylus_buttons == tablet->prev_state.stylus_buttons)
> + return;
> +
> + if (post_check) {
> + /* Only notify button releases */
> + state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
> + pad_buttons = tablet_get_disabled_buttons(tablet, pad_buttons);
> + stylus_buttons =
> + tablet_get_disabled_buttons(tablet, stylus_buttons);
> + } else {
> + /* Only notify button presses */
> + state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
> + pad_buttons = tablet_get_enabled_buttons(tablet, pad_buttons);
> + stylus_buttons =
> + tablet_get_enabled_buttons(tablet, stylus_buttons);
> + }
> +
> + tablet_notify_button_mask(
> + tablet, device, time, pad_buttons, BTN_MISC, state);
> + tablet_notify_button_mask(
> + tablet, device, time, stylus_buttons, BTN_TOUCH, state);
yikes. I really dislike this formatting style. We generally leave the first
parameter in the same line, with the rest indented to match.
For this case, you could group it like this:
tablet_notify_button_mask(tablet, device, time,
pad_buttons, BTN_MISC, state);
> +}
> +
> +static void
> tablet_flush(struct tablet_dispatch *tablet,
> struct evdev_device *device,
> uint32_t time)
> @@ -140,6 +242,7 @@ tablet_flush(struct tablet_dispatch *tablet,
>
> /* pre-update notifications */
> tablet_check_notify_tool(tablet, device, time, 0);
> + tablet_notify_buttons(tablet, device, time, 0);
>
> if (tablet->state.tool != LIBINPUT_TOOL_NONE) {
> if (tablet_has_status(tablet, TABLET_UPDATED)) {
> @@ -153,6 +256,7 @@ tablet_flush(struct tablet_dispatch *tablet,
> }
>
> /* post-update notifications */
> + tablet_notify_buttons(tablet, device, time, 1);
> tablet_check_notify_tool(tablet, device, time, 1);
>
> /* replace previous state */
> diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
> index 7b7b066..d81c878 100644
> --- a/src/evdev-tablet.h
> +++ b/src/evdev-tablet.h
> @@ -30,9 +30,12 @@ enum tablet_status {
> TABLET_NONE = 0,
> TABLET_UPDATED = 1 << 0,
> TABLET_INTERACTED = 1 << 1,
> + TABLET_HAS_CONTACT = 1 << 2,
this should be TABLET_STYLUS_IN_CONTACT, you don't get BTN_TOUCH for pure
button presses.
Cheers,
Peter
> };
>
> struct device_state {
> + uint32_t pad_buttons; /* bitmask of evcode - BTN_MISC */
> + uint32_t stylus_buttons; /* bitmask of evcode - BTN_TOUCH */
> enum libinput_tool tool;
> int32_t tool_serial;
> };
> --
> 1.9.0
More information about the wayland-devel
mailing list