[PATCH libinput 3/3] touchpad: add support for per-finger hovering information
Peter Hutterer
peter.hutterer at who-t.net
Tue May 5 22:08:09 PDT 2015
On Thu, Apr 30, 2015 at 04:30:25PM -0400, Benjamin Tissoires wrote:
> From: Benjamin Tissoires <benjamin.tissoires at redhat.com>
>
> When the device supports true hovering, it reports this
> information through ABS_MT_DISTANCE.
> When this axis is available, we should rely on it to
> (un)hover the touches as BTN_TOUCH is most of the time
> unreliable (generated by the mouse emulation in the kernel).
>
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>
> ---
> src/evdev-mt-touchpad.c | 40 +++++++++++-
> src/evdev-mt-touchpad.h | 2 +
> test/Makefile.am | 1 +
> test/litest-atmel-hover.c | 149 ++++++++++++++++++++++++++++++++++++++++
> test/litest.c | 153 +++++++++++++++++++++++++++++++++++++-----
> test/litest.h | 26 +++++++-
> test/touchpad.c | 166 +++++++++++++++++++++++++++++++++++++++++++++
> 7 files changed, 519 insertions(+), 18 deletions(-)
> create mode 100644 test/litest-atmel-hover.c
>
> diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
> index d5ce880..5b7f291 100644
> --- a/src/evdev-mt-touchpad.c
> +++ b/src/evdev-mt-touchpad.c
> @@ -300,6 +300,9 @@ tp_process_absolute(struct tp_dispatch *tp,
> case ABS_MT_SLOT:
> tp->slot = e->value;
> break;
> + case ABS_MT_DISTANCE:
> + t->distance = e->value;
> + break;
> case ABS_MT_TRACKING_ID:
> if (e->value != -1)
> tp_new_touch(tp, t, time);
> @@ -520,7 +523,29 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
> }
>
> static void
> -tp_unhover_touches(struct tp_dispatch *tp, uint64_t time)
> +tp_unhover_abs_distance(struct tp_dispatch *tp, uint64_t time)
> +{
> + struct tp_touch *t;
> + int i;
> +
> + for (i = 0; i < (int)tp->ntouches; i++) {
> + t = tp_get_touch(tp, i);
maybe a leftover, but can't we make i an unsigned int to save the cast?
> +
> + if (t->state == TOUCH_HOVERING) {
> + if (t->distance == 0) {
> + /* avoid jumps when landing a finger */
> + tp_motion_history_reset(t);
> + tp_begin_touch(tp, t, time);
> + }
> + } else {
> + if (t->distance > 0)
> + tp_end_touch(tp, t, time);
> + }
> + }
> +}
> +
> +static void
> +tp_unhover_fake_touches(struct tp_dispatch *tp, uint64_t time)
> {
> struct tp_touch *t;
> unsigned int nfake_touches;
> @@ -579,6 +604,16 @@ tp_unhover_touches(struct tp_dispatch *tp, uint64_t time)
> }
>
> static void
> +tp_unhover_touches(struct tp_dispatch *tp, uint64_t time)
> +{
> + if (tp->reports_distance)
> + tp_unhover_abs_distance(tp, time);
> + else
> + tp_unhover_fake_touches(tp, time);
> +
> +}
> +
> +static void
> tp_process_state(struct tp_dispatch *tp, uint64_t time)
> {
> struct tp_touch *t;
> @@ -1184,6 +1219,9 @@ tp_init(struct tp_dispatch *tp,
> device->abs.absinfo_y->minimum);
> diagonal = sqrt(width*width + height*height);
>
> + tp->reports_distance = libevdev_has_event_code(device->evdev, EV_ABS,
> + ABS_MT_DISTANCE);
nitpick: if the line break is needed, one arg per line (i.e. EV_ABS goes on
its own line)
> +
> tp->hysteresis_margin.x =
> diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
> tp->hysteresis_margin.y =
> diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
> index 97b17cd..ebba9df 100644
> --- a/src/evdev-mt-touchpad.h
> +++ b/src/evdev-mt-touchpad.h
> @@ -129,6 +129,7 @@ struct tp_touch {
> bool dirty;
> struct device_coords point;
> uint64_t millis;
> + int distance; /* distance == 0 means touch */
>
> struct {
> struct device_coords samples[TOUCHPAD_HISTORY_LENGTH];
> @@ -183,6 +184,7 @@ struct tp_dispatch {
> unsigned int slot; /* current slot */
> bool has_mt;
> bool semi_mt;
> + bool reports_distance; /* does the device supports true hovering */
> enum touchpad_model model;
>
> unsigned int num_slots; /* number of slots */
> diff --git a/test/Makefile.am b/test/Makefile.am
> index be0c5d9..a90fa78 100644
> --- a/test/Makefile.am
> +++ b/test/Makefile.am
> @@ -14,6 +14,7 @@ liblitest_la_SOURCES = \
> litest.h \
> litest-int.h \
> litest-alps-semi-mt.c \
> + litest-atmel-hover.c \
> litest-bcm5974.c \
> litest-generic-singletouch.c \
> litest-keyboard.c \
> diff --git a/test/litest-atmel-hover.c b/test/litest-atmel-hover.c
> new file mode 100644
> index 0000000..7da0901
> --- /dev/null
> +++ b/test/litest-atmel-hover.c
> @@ -0,0 +1,149 @@
> +/*
> + * Copyright ?? 2015 Red Hat, Inc.
> + *
> + * Permission to use, copy, modify, distribute, and sell this software and its
> + * documentation for any purpose is hereby granted without fee, provided that
> + * the above copyright notice appear in all copies and that both that copyright
> + * notice and this permission notice appear in supporting documentation, and
> + * that the name of the copyright holders not be used in advertising or
> + * publicity pertaining to distribution of the software without specific,
> + * written prior permission. The copyright holders make no representations
> + * about the suitability of this software for any purpose. It is provided "as
> + * is" without express or implied warranty.
> + *
> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
> + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
> + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
> + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
> + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
> + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
> + * OF THIS SOFTWARE.
> + */
> +
> +#if HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <assert.h>
> +
> +#include "libinput-util.h"
> +
> +#include "litest.h"
> +#include "litest-int.h"
> +
> +static void
> +atmel_hover_create(struct litest_device *d);
> +
> +static void
> +litest_atmel_hover_setup(void)
> +{
> + struct litest_device *d = litest_create_device(LITEST_ATMEL_HOVER);
> + litest_set_current_device(d);
> +}
> +
> +static struct input_event down[] = {
> + { .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_PRESSURE, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_DISTANCE, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_PRESSURE, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
> + { .type = -1, .code = -1 },
> +};
> +
> +static struct input_event move[] = {
> + { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_PRESSURE, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_DISTANCE, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_PRESSURE, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
> + { .type = -1, .code = -1 },
> +};
> +
> +static struct input_event up[] = {
> + { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
> + { .type = EV_ABS, .code = ABS_MT_DISTANCE, .value = 1 },
> + { .type = EV_ABS, .code = ABS_MT_PRESSURE, .value = 0 },
> + { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
> + { .type = -1, .code = -1 },
> +};
> +
> +static struct litest_device_interface interface = {
> + .touch_down_events = down,
> + .touch_move_events = move,
> + .touch_up_events = up,
> +};
> +
> +static struct input_id input_id = {
> + .bustype = 0x18,
> + .vendor = 0x0,
> + .product = 0x0,
> +};
> +
> +static int events[] = {
> + EV_KEY, BTN_LEFT,
> + EV_KEY, BTN_TOOL_FINGER,
> + EV_KEY, BTN_TOUCH,
> + EV_KEY, BTN_TOOL_DOUBLETAP,
> + EV_KEY, BTN_TOOL_TRIPLETAP,
> + EV_KEY, BTN_TOOL_QUADTAP,
> + EV_KEY, BTN_TOOL_QUINTTAP,
> + INPUT_PROP_MAX, INPUT_PROP_POINTER,
> + INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
> + -1, -1,
> +};
> +
> +static struct input_absinfo absinfo[] = {
> + { ABS_X, 0, 960, 0, 0, 10 },
> + { ABS_Y, 0, 540, 0, 0, 10 },
> + { ABS_PRESSURE, 0, 255, 0, 0, 0 },
> + { ABS_MT_SLOT, 0, 9, 0, 0, 0 },
> + { ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0, 0 },
> + { ABS_MT_ORIENTATION, 0, 255, 0, 0, 0 },
> + { ABS_MT_POSITION_X, 0, 960, 0, 0, 10 },
> + { ABS_MT_POSITION_Y, 0, 540, 0, 0, 10 },
> + { ABS_MT_TOOL_TYPE, 0, 2, 0, 0, 0 },
> + { ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 },
> + { ABS_MT_PRESSURE, 0, 255, 0, 0, 0 },
> + { ABS_MT_DISTANCE, 0, 1, 0, 0, 0 },
> + { .value = -1 }
> +};
> +
> +struct litest_test_device litest_atmel_hover_device = {
> + .type = LITEST_ATMEL_HOVER,
> + .features = LITEST_TOUCHPAD | LITEST_BUTTON | LITEST_CLICKPAD | LITEST_HOVER,
> + .shortname = "atmel hover",
> + .setup = litest_atmel_hover_setup,
> + .interface = &interface,
> + .create = atmel_hover_create,
> +
> + .name = "Atmel maXTouch Touchpad",
> + .id = &input_id,
> + .events = events,
> + .absinfo = absinfo,
> +};
> +
> +static void
> +atmel_hover_create(struct litest_device *d)
> +{
> + struct litest_semi_mt *semi_mt = zalloc(sizeof(*semi_mt));
> + assert(semi_mt);
> +
> + d->private = semi_mt;
> +
> + d->uinput = litest_create_uinput_device_from_description(
> + litest_atmel_hover_device.name,
> + litest_atmel_hover_device.id,
> + absinfo,
> + events);
> + d->interface = &interface;
> +}
> diff --git a/test/litest.c b/test/litest.c
> index 15fc87e..fa5095b 100644
> --- a/test/litest.c
> +++ b/test/litest.c
> @@ -103,6 +103,7 @@ extern struct litest_test_device litest_wheel_only_device;
> extern struct litest_test_device litest_mouse_roccat_device;
> extern struct litest_test_device litest_ms_surface_cover_device;
> extern struct litest_test_device litest_logitech_trackball_device;
> +extern struct litest_test_device litest_atmel_hover_device;
>
> struct litest_test_device* devices[] = {
> &litest_synaptics_clickpad_device,
> @@ -127,6 +128,7 @@ struct litest_test_device* devices[] = {
> &litest_mouse_roccat_device,
> &litest_ms_surface_cover_device,
> &litest_logitech_trackball_device,
> + &litest_atmel_hover_device,
> NULL,
> };
>
> @@ -794,7 +796,8 @@ litest_event(struct litest_device *d, unsigned int type,
> int
> litest_auto_assign_value(struct litest_device *d,
> const struct input_event *ev,
> - int slot, double x, double y)
> + int slot, double x, double y,
> + int touching)
> {
> static int tracking_id;
> int value = ev->value;
> @@ -817,6 +820,9 @@ litest_auto_assign_value(struct litest_device *d,
> case ABS_MT_SLOT:
> value = slot;
> break;
> + case ABS_MT_DISTANCE:
> + value = touching ? 0 : 1;
> + break;
> }
>
> return value;
> @@ -833,9 +839,17 @@ send_btntool(struct litest_device *d)
> litest_event(d, EV_KEY, BTN_TOOL_QUINTTAP, d->ntouches_down == 5);
> }
>
> -void
> -litest_touch_down(struct litest_device *d, unsigned int slot,
> - double x, double y)
> +static inline int
> +litest_validate_event(struct input_event *ev, int send_ev_syn)
> +{
> + return !((int16_t)ev->type == EV_SYN &&
> + (int16_t)ev->code == SYN_REPORT &&
are those casts needed?
also, this function is a bit awkwardly named: it doesn't validate as such,
it just tells us when to filter syn events.
and that brings us to the next bit: I think you can use
litest_push_event_frame()/litest_pop_event_frame() instead of passing a
parameter around. more on that in the tests below.
> + !send_ev_syn);
> +}
> +
> +static void
> +litest_slot_start(struct litest_device *d, unsigned int slot,
> + double x, double y, int touching, int sync)
> {
> struct input_event *ev;
>
> @@ -851,13 +865,22 @@ litest_touch_down(struct litest_device *d, unsigned int slot,
>
> ev = d->interface->touch_down_events;
> while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
> - int value = litest_auto_assign_value(d, ev, slot, x, y);
> - litest_event(d, ev->type, ev->code, value);
> + int value = litest_auto_assign_value(d, ev, slot, x, y, touching);
> +
> + if (litest_validate_event(ev, sync))
> + litest_event(d, ev->type, ev->code, value);
> ev++;
> }
> }
>
> void
> +litest_touch_down(struct litest_device *d, unsigned int slot,
> + double x, double y)
> +{
> + litest_slot_start(d, slot, x, y, 1, 1);
> +}
> +
> +void
> litest_touch_up(struct litest_device *d, unsigned int slot)
> {
> struct input_event *ev;
> @@ -882,15 +905,15 @@ litest_touch_up(struct litest_device *d, unsigned int slot)
> ev = up;
>
> while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
> - int value = litest_auto_assign_value(d, ev, slot, 0, 0);
> + int value = litest_auto_assign_value(d, ev, slot, 0, 0, 0);
> litest_event(d, ev->type, ev->code, value);
> ev++;
> }
> }
>
> -void
> -litest_touch_move(struct litest_device *d, unsigned int slot,
> - double x, double y)
> +static void
> +litest_slot_move(struct litest_device *d, unsigned int slot,
> + double x, double y, int touching, int sync)
> {
> struct input_event *ev;
>
> @@ -901,13 +924,21 @@ litest_touch_move(struct litest_device *d, unsigned int slot,
>
> ev = d->interface->touch_move_events;
> while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
> - int value = litest_auto_assign_value(d, ev, slot, x, y);
> - litest_event(d, ev->type, ev->code, value);
> + int value = litest_auto_assign_value(d, ev, slot, x, y, touching);
> + if (litest_validate_event(ev, sync))
> + litest_event(d, ev->type, ev->code, value);
> ev++;
> }
> }
>
> void
> +litest_touch_move(struct litest_device *d, unsigned int slot,
> + double x, double y)
> +{
> + litest_slot_move(d, slot, x, y, 1, 1);
> +}
> +
> +void
> litest_touch_move_to(struct litest_device *d,
> unsigned int slot,
> double x_from, double y_from,
> @@ -950,6 +981,96 @@ litest_touch_move_two_touches(struct litest_device *d,
> }
>
> void
> +litest_hover_start(struct litest_device *d, unsigned int slot,
> + double x, double y, int sync)
> +{
> + litest_slot_start(d, slot, x, y, 0, sync);
> +}
> +
> +void
> +litest_hover_end(struct litest_device *d, unsigned int slot, int sync)
> +{
> + struct input_event *ev;
> + struct input_event up[] = {
> + { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_DISTANCE, .value = 1 },
> + { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
> + { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
> + { .type = -1, .code = -1 }
> + };
> +
> + assert(d->ntouches_down > 0);
> + d->ntouches_down--;
> +
> + send_btntool(d);
> +
> + if (d->interface->touch_up) {
> + d->interface->touch_up(d, slot);
> + return;
> + } else if (d->interface->touch_up_events) {
> + ev = d->interface->touch_up_events;
> + } else
> + ev = up;
> +
> + while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
> + int value = litest_auto_assign_value(d, ev, slot, 0, 0, 0);
> + if (litest_validate_event(ev, sync))
> + litest_event(d, ev->type, ev->code, value);
> + ev++;
> + }
> +}
> +
> +void
> +litest_hover_move(struct litest_device *d, unsigned int slot,
> + double x, double y, int sync)
> +{
> + litest_slot_move(d, slot, x, y, 0, sync);
> +}
> +
> +void
> +litest_hover_move_to(struct litest_device *d,
> + unsigned int slot,
> + double x_from, double y_from,
> + double x_to, double y_to,
> + int steps, int sleep_ms, int sync)
> +{
> + for (int i = 0; i < steps - 1; i++) {
> + litest_hover_move(d, slot,
> + x_from + (x_to - x_from)/steps * i,
> + y_from + (y_to - y_from)/steps * i,
> + sync);
> + if (sleep_ms) {
> + libinput_dispatch(d->libinput);
> + msleep(sleep_ms);
> + libinput_dispatch(d->libinput);
> + }
> + }
> + litest_hover_move(d, slot, x_to, y_to, sync);
> +}
> +
> +void
> +litest_hover_move_two_touches(struct litest_device *d,
> + double x0, double y0,
> + double x1, double y1,
> + double dx, double dy,
> + int steps, int sleep_ms)
> +{
> + for (int i = 0; i < steps - 1; i++) {
> + litest_hover_move(d, 0, x0 + dx / steps * i,
> + y0 + dy / steps * i, 0);
> + litest_hover_move(d, 1, x1 + dx / steps * i,
> + y1 + dy / steps * i, 1);
> + if (sleep_ms) {
> + libinput_dispatch(d->libinput);
> + msleep(sleep_ms);
> + libinput_dispatch(d->libinput);
> + }
> + }
> + litest_hover_move(d, 0, x0 + dx, y0 + dy, 0);
> + litest_hover_move(d, 1, x1 + dx, y1 + dy, 1);
> +}
> +
> +void
> litest_button_click(struct litest_device *d, unsigned int button, bool is_press)
> {
>
> @@ -1484,11 +1605,11 @@ send_abs_xy(struct litest_device *d, double x, double y)
> e.type = EV_ABS;
> e.code = ABS_X;
> e.value = LITEST_AUTO_ASSIGN;
> - val = litest_auto_assign_value(d, &e, 0, x, y);
> + val = litest_auto_assign_value(d, &e, 0, x, y, 1);
> litest_event(d, EV_ABS, ABS_X, val);
>
> e.code = ABS_Y;
> - val = litest_auto_assign_value(d, &e, 0, x, y);
> + val = litest_auto_assign_value(d, &e, 0, x, y, 1);
> litest_event(d, EV_ABS, ABS_Y, val);
> }
>
> @@ -1501,12 +1622,12 @@ send_abs_mt_xy(struct litest_device *d, double x, double y)
> e.type = EV_ABS;
> e.code = ABS_MT_POSITION_X;
> e.value = LITEST_AUTO_ASSIGN;
> - val = litest_auto_assign_value(d, &e, 0, x, y);
> + val = litest_auto_assign_value(d, &e, 0, x, y, 1);
> litest_event(d, EV_ABS, ABS_MT_POSITION_X, val);
>
> e.code = ABS_MT_POSITION_Y;
> e.value = LITEST_AUTO_ASSIGN;
> - val = litest_auto_assign_value(d, &e, 0, x, y);
> + val = litest_auto_assign_value(d, &e, 0, x, y, 1);
> litest_event(d, EV_ABS, ABS_MT_POSITION_Y, val);
> }
>
> diff --git a/test/litest.h b/test/litest.h
> index 611cdf7..bb9ba03 100644
> --- a/test/litest.h
> +++ b/test/litest.h
> @@ -57,6 +57,7 @@ enum litest_device_type {
> LITEST_WHEEL_ONLY = -21,
> LITEST_MOUSE_ROCCAT = -22,
> LITEST_LOGITECH_TRACKBALL = -23,
> + LITEST_ATMEL_HOVER = -24,
> };
>
> enum litest_device_feature {
> @@ -77,6 +78,7 @@ enum litest_device_feature {
> LITEST_FAKE_MT = 1 << 12,
> LITEST_ABSOLUTE = 1 << 13,
> LITEST_PROTOCOL_A = 1 << 14,
> + LITEST_HOVER = 1 << 15,
> };
>
> struct litest_device {
> @@ -141,7 +143,8 @@ void litest_event(struct litest_device *t,
> int value);
> int litest_auto_assign_value(struct litest_device *d,
> const struct input_event *ev,
> - int slot, double x, double y);
> + int slot, double x, double y,
> + int touching);
> void litest_touch_up(struct litest_device *d, unsigned int slot);
> void litest_touch_move(struct litest_device *d,
> unsigned int slot,
> @@ -161,6 +164,27 @@ void litest_touch_move_two_touches(struct litest_device *d,
> double x1, double y1,
> double dx, double dy,
> int steps, int sleep_ms);
> +void litest_hover_start(struct litest_device *d,
> + unsigned int slot,
> + double x,
> + double y,
> + int sync);
> +void litest_hover_end(struct litest_device *d, unsigned int slot, int sync);
> +void litest_hover_move(struct litest_device *d,
> + unsigned int slot,
> + double x,
> + double y,
> + int sync);
> +void litest_hover_move_to(struct litest_device *d,
> + unsigned int slot,
> + double x_from, double y_from,
> + double x_to, double y_to,
> + int steps, int sleep_ms, int sync);
> +void litest_hover_move_two_touches(struct litest_device *d,
> + double x0, double y0,
> + double x1, double y1,
> + double dx, double dy,
> + int steps, int sleep_ms);
> void litest_button_click(struct litest_device *d,
> unsigned int button,
> bool is_press);
> diff --git a/test/touchpad.c b/test/touchpad.c
> index 49f5023..f0be6d9 100644
> --- a/test/touchpad.c
> +++ b/test/touchpad.c
> @@ -3834,6 +3834,165 @@ START_TEST(touchpad_semi_mt_hover_2fg_1fg_down)
> }
> END_TEST
>
> +START_TEST(touchpad_hover_noevent)
> +{
> + struct litest_device *dev = litest_current_device();
> + struct libinput *li = dev->libinput;
> +
> + litest_drain_events(li);
> +
> + litest_hover_start(dev, 0, 50, 50, 1);
> + litest_hover_move_to(dev, 0, 50, 50, 70, 70, 10, 10, 1);
> + litest_hover_end(dev, 0, 1);
> +
> + litest_assert_empty_queue(li);
> +}
> +END_TEST
> +
> +START_TEST(touchpad_hover_down)
> +{
> + struct litest_device *dev = litest_current_device();
> + struct libinput *li = dev->libinput;
> +
> + litest_drain_events(li);
> +
> + /* hover the finger */
> + litest_hover_start(dev, 0, 50, 50, 1);
> +
> + litest_hover_move_to(dev, 0, 50, 50, 70, 70, 10, 10, 1);
> +
> + litest_assert_empty_queue(li);
> +
> + /* touch the finger on the sensor */
> + litest_touch_move_to(dev, 0, 70, 70, 50, 50, 10, 10);
> +
> + libinput_dispatch(li);
> +
> + litest_assert_only_typed_events(li,
> + LIBINPUT_EVENT_POINTER_MOTION);
> +
> + /* go back to hover */
> + litest_hover_move_to(dev, 0, 50, 50, 70, 70, 10, 10, 1);
> + litest_hover_end(dev, 0, 1);
> +
> + litest_assert_empty_queue(li);
> +}
> +END_TEST
> +
> +START_TEST(touchpad_hover_down_hover_down)
> +{
> + struct litest_device *dev = litest_current_device();
> + struct libinput *li = dev->libinput;
> + int i;
> +
> + litest_drain_events(li);
> +
> + litest_hover_start(dev, 0, 50, 50, 1);
> +
> + for (i = 0; i < 3; i++) {
> +
> + /* hover the finger */
> + litest_hover_move_to(dev, 0, 50, 50, 70, 70, 10, 10, 1);
> +
> + litest_assert_empty_queue(li);
> +
> + /* touch the finger */
> + litest_touch_move_to(dev, 0, 70, 70, 50, 50, 10, 10);
pls add a touch_down() call before each touch_move_to, it makes it a lot
more obvious that the finger is down now (goes for all tests).
> +
> + libinput_dispatch(li);
> +
> + litest_assert_only_typed_events(li,
> + LIBINPUT_EVENT_POINTER_MOTION);
> + }
> +
> + litest_hover_end(dev, 0, 1);
> +
> + /* start a new touch to be sure */
> + litest_touch_down(dev, 0, 50, 50);
> + litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10, 10);
> + litest_touch_up(dev, 0);
> +
> + litest_assert_only_typed_events(li,
> + LIBINPUT_EVENT_POINTER_MOTION);
> +}
> +END_TEST
> +
> +START_TEST(touchpad_hover_down_up)
> +{
> + struct litest_device *dev = litest_current_device();
> + struct libinput *li = dev->libinput;
> +
> + litest_drain_events(li);
> +
> + /* hover two fingers, and a touch */
ok, here's where I think using the push/pop pairs will do the same job but
be slightly nicer in terms of API.
litest_push_event_frame();
> + litest_hover_start(dev, 0, 50, 50, 0);
> + litest_hover_start(dev, 1, 50, 50, 0);
> + litest_touch_down(dev, 2, 50, 50);
litest_pop_event_frame();
> +
> + litest_assert_empty_queue(li);
> +
> + /* hover first finger, end second and third in same frame */
litest_push_event_frame();
> + litest_hover_move(dev, 0, 70, 70, 0);
> + litest_hover_end(dev, 1, 0);
> + litest_touch_up(dev, 2);
litest_push_event_frame();
> +
> + litest_assert_empty_queue(li);
> +
> + /* now move the finger */
> + litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10, 10);
> +
> + litest_touch_up(dev, 0);
> +
> + litest_assert_only_typed_events(li,
> + LIBINPUT_EVENT_POINTER_MOTION);
> +}
> +END_TEST
> +
> +START_TEST(touchpad_hover_2fg_noevent)
> +{
> + struct litest_device *dev = litest_current_device();
> + struct libinput *li = dev->libinput;
> +
> + litest_drain_events(li);
> +
> + /* hover two fingers */
litest_push_event_frame();
> + litest_hover_start(dev, 0, 25, 25, 0);
> + litest_hover_start(dev, 1, 50, 50, 1);
> +
litest_pop_event_frame();
> + litest_hover_move_two_touches(dev, 25, 25, 50, 50, 50, 50, 10, 0);
> +
litest_push_event_frame();
> + litest_hover_end(dev, 0, 0);
> + litest_hover_end(dev, 1, 1);
litest_pop_event_frame();
> +
> + litest_assert_empty_queue(li);
> +}
> +END_TEST
> +
> +START_TEST(touchpad_hover_2fg_1fg_down)
> +{
> + struct litest_device *dev = litest_current_device();
> + struct libinput *li = dev->libinput;
> + int i;
> +
> + litest_drain_events(li);
> +
> + /* hover two fingers */
litest_push_event_frame();
> + litest_hover_start(dev, 0, 25, 25, 0);
> + litest_touch_down(dev, 1, 50, 50);
litest_pop_event_frame();
> +
> + for (i = 0; i < 10; i++) {
litest_push_event_frame();
> + litest_hover_move(dev, 0, 25 + 5 * i, 25 + 5 * i, 0);
> + litest_touch_move(dev, 1, 50 + 5 * i, 50 - 5 * i);
litest_pop_event_frame();
> + }
> +
litest_push_event_frame();
> + litest_hover_end(dev, 0, 0);
> + litest_touch_up(dev, 1);
litest_pop_event_frame();
right, so after adding these I think this should work. you can drop the
extra parameter and just use the push/pop instead.
Cheers,
Peter
> +
> + litest_assert_only_typed_events(li,
> + LIBINPUT_EVENT_POINTER_MOTION);
> +}
> +END_TEST
> +
> static void
> assert_btnevent_from_device(struct litest_device *device,
> unsigned int button,
> @@ -4241,6 +4400,13 @@ int main(int argc, char **argv) {
> litest_add_for_device("touchpad:semi-mt-hover", touchpad_semi_mt_hover_2fg_noevent, LITEST_SYNAPTICS_HOVER_SEMI_MT);
> litest_add_for_device("touchpad:semi-mt-hover", touchpad_semi_mt_hover_2fg_1fg_down, LITEST_SYNAPTICS_HOVER_SEMI_MT);
>
> + litest_add("touchpad:hover", touchpad_hover_noevent, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY);
> + litest_add("touchpad:hover", touchpad_hover_down, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY);
> + litest_add("touchpad:hover", touchpad_hover_down_up, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY);
> + litest_add("touchpad:hover", touchpad_hover_down_hover_down, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY);
> + litest_add("touchpad:hover", touchpad_hover_2fg_noevent, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY);
> + litest_add("touchpad:hover", touchpad_hover_2fg_1fg_down, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY);
> +
> litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_buttons, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
> litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_mb_scroll, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
> litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_mb_click, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
> --
> 1.7.1
>
> _______________________________________________
> 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