[PATCH libinput 3/3] touchpad: add support for per-finger hovering information
Benjamin Tissoires
benjamin.tissoires at gmail.com
Wed May 6 07:45:20 PDT 2015
On Wed, May 6, 2015 at 1:08 AM, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> 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?
Sure, will amend.
>
>> +
>> + 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)
OK
>
>> +
>> 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?
Maybe not...
>
> 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.
>
... but that is moot given that it will be removed by the use of push/pop :)
Speaking of which. I think the name is awful :) I had to refer to the
code to understand what that means. Maybe I am too biased by my OpenGL
background where push/pop meant "push/restore the current state of the
graphic pipeline". Here it is just: "prevent the syn event to be
sent"/"OK, now send it".
>
>> + !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).
Unfortunatelly, that is not possible (at least without making my brain
smoke due to overheat).
touch_down/hover_down are sent when a new slot has to be allocated. So
if we send a touch_down after a hover_start, we will receive a new
tracking ID and this is bad.
I'll try to think if I can do something better...
>
>> +
>> + 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.
OK, thanks. Will do.
Cheers,
Benjamin
>
> 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