[PATCH libinput 5/8] touchpad: Route top softbuttons through the trackstick if we've one
Peter Hutterer
peter.hutterer at who-t.net
Wed Sep 17 20:17:29 PDT 2014
On Tue, Sep 16, 2014 at 04:22:39PM +0200, Hans de Goede wrote:
> The touchpad top softbuttons such as found on the Lenove T440 are intended for
> use with the trackstick. Route their events through the trackstick, so that
> they can be used for e.g. middle button scrolling with the trackstick.
>
> Note that sending top button events to a disabled trackpoint makes no sense
> (and will mess up internal state). Likely a user with a disabled trackpoint
> will still expect the top buttons to work, so rather than not sending events
> in that case, simply treat a suspendeded trackpoint as not being there, and
> send the events directly from the touchpad device.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
but see the notes below
> ---
> doc/touchpad-softbutton-state-machine.svg | 200 +++++++++++++++++-------------
> src/evdev-mt-touchpad-buttons.c | 45 +++++--
> src/evdev-mt-touchpad.c | 17 ++-
> src/evdev-mt-touchpad.h | 1 +
> 4 files changed, 163 insertions(+), 100 deletions(-)
>
> diff --git a/doc/touchpad-softbutton-state-machine.svg b/doc/touchpad-softbutton-state-machine.svg
> index 1d569bf..ffa17a2 100644
> --- a/doc/touchpad-softbutton-state-machine.svg
> +++ b/doc/touchpad-softbutton-state-machine.svg
[...]
> diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
> index 02d3205..0fdabde 100644
> --- a/src/evdev-mt-touchpad-buttons.c
> +++ b/src/evdev-mt-touchpad-buttons.c
> @@ -675,16 +675,40 @@ tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
> return 0;
> }
>
> +static void
> +tp_notify_softbutton(struct tp_dispatch *tp,
> + uint64_t time,
> + uint32_t button,
> + uint32_t is_top,
just because I prefer it: I replaced this with is_topbutton, and
active_is_top with active_is_topbutton (simple sed, both times)
> + enum libinput_button_state state)
> +{
> + /* If we've a trackpoint, send top buttons through the trackpoint */
> + if (is_top && tp->buttons.trackpoint) {
> + struct evdev_dispatch *dispatch = tp->buttons.trackpoint->dispatch;
> + struct input_event event;
> +
> + event.type = EV_KEY,
> + event.code = button,
I'm going to assume you meant ; here instead of ',' so I've replaced those
after applying.
> + event.value = (state == LIBINPUT_BUTTON_STATE_PRESSED) ? 1 : 0;
for correctness, we should set the time here too, I've added
+ event.time.tv_sec = time/1000;
+ event.time.tv_usec = (time % 1000) * 1000;
patch coming up, just double-check it please.
Cheers,
Peter
> + dispatch->interface->process(dispatch, tp->buttons.trackpoint,
> + &event, time);
> + return;
> + }
> +
> + evdev_pointer_notify_button(tp->device, time, button, state);
> +}
> +
> static int
> tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
> {
> - uint32_t current, old, button;
> + uint32_t current, old, button, is_top;
> enum libinput_button_state state;
> enum { AREA = 0x01, LEFT = 0x02, MIDDLE = 0x04, RIGHT = 0x08 };
>
> current = tp->buttons.state;
> old = tp->buttons.old_state;
> button = 0;
> + is_top = 0;
>
> if (!tp->buttons.click_pending && current == old)
> return 0;
> @@ -697,15 +721,18 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
> case BUTTON_EVENT_IN_AREA:
> button |= AREA;
> break;
> - case BUTTON_EVENT_IN_BOTTOM_L:
> case BUTTON_EVENT_IN_TOP_L:
> + is_top = 1;
> + case BUTTON_EVENT_IN_BOTTOM_L:
> button |= LEFT;
> break;
> case BUTTON_EVENT_IN_TOP_M:
> + is_top = 1;
> button |= MIDDLE;
> break;
> - case BUTTON_EVENT_IN_BOTTOM_R:
> case BUTTON_EVENT_IN_TOP_R:
> + is_top = 1;
> + case BUTTON_EVENT_IN_BOTTOM_R:
> button |= RIGHT;
> break;
> default:
> @@ -727,21 +754,21 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
> button = BTN_LEFT;
>
> tp->buttons.active = button;
> + tp->buttons.active_is_top = is_top;
> state = LIBINPUT_BUTTON_STATE_PRESSED;
> } else {
> button = tp->buttons.active;
> + is_top = tp->buttons.active_is_top;
> tp->buttons.active = 0;
> + tp->buttons.active_is_top = 0;
> state = LIBINPUT_BUTTON_STATE_RELEASED;
> }
>
> tp->buttons.click_pending = false;
>
> - if (button) {
> - evdev_pointer_notify_button(tp->device,
> - time,
> - button,
> - state);
> - }
> + if (button)
> + tp_notify_softbutton(tp, time, button, is_top, state);
> +
> return 1;
> }
>
> diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
> index a0ad8db..73e08c1 100644
> --- a/src/evdev-mt-touchpad.c
> +++ b/src/evdev-mt-touchpad.c
> @@ -643,8 +643,11 @@ tp_device_added(struct evdev_device *device,
> struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
>
> if (tp->buttons.trackpoint == NULL &&
> - (added_device->tags & EVDEV_TAG_TRACKPOINT))
> + (added_device->tags & EVDEV_TAG_TRACKPOINT)) {
> + /* Don't send any pending releases to the new trackpoint */
> + tp->buttons.active_is_top = 0;
> tp->buttons.trackpoint = added_device;
> + }
>
> if (tp->sendevents.current_mode !=
> LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
> @@ -661,8 +664,14 @@ tp_device_removed(struct evdev_device *device,
> struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
> struct libinput_device *dev;
>
> - if (removed_device == tp->buttons.trackpoint)
> + if (removed_device == tp->buttons.trackpoint) {
> + /* Clear any pending releases for the trackpoint */
> + if (tp->buttons.active && tp->buttons.active_is_top) {
> + tp->buttons.active = 0;
> + tp->buttons.active_is_top = 0;
> + }
> tp->buttons.trackpoint = NULL;
> + }
>
> if (tp->sendevents.current_mode !=
> LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
> @@ -703,8 +712,8 @@ static struct evdev_dispatch_interface tp_interface = {
> tp_destroy,
> tp_device_added,
> tp_device_removed,
> - NULL, /* device_suspended */
> - NULL, /* device_resumed */
> + tp_device_removed, /* device_suspended, treat as remove */
> + tp_device_added, /* device_resumed, treat as add */
> tp_tag_device,
> };
>
> diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
> index 4a16db9..15cca76 100644
> --- a/src/evdev-mt-touchpad.h
> +++ b/src/evdev-mt-touchpad.h
> @@ -183,6 +183,7 @@ struct tp_dispatch {
> uint32_t old_state;
> uint32_t motion_dist; /* for pinned touches */
> unsigned int active; /* currently active button, for release event */
> + unsigned int active_is_top; /* is active a top button? */
>
> /* Only used for clickpads. The software button areas are
> * always 2 horizontal stripes across the touchpad.
> --
> 2.1.0
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
More information about the wayland-devel
mailing list