[PATCH libinput 3/5] test: allow for description-based test devices
Hans de Goede
hdegoede at redhat.com
Tue Apr 1 02:42:08 PDT 2014
Hi,
On 04/01/2014 05:47 AM, Peter Hutterer wrote:
> Most of the test devices now are static descriptions anyway, make them fully
> static now, including for touch events.
>
> Switch the synaptics device now as example, the rest comes later for easier
> patch review.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
> test/litest-int.h | 47 ++++++++++++++-
> test/litest-synaptics.c | 151 ++++++++++++++++++++----------------------------
> test/litest.c | 141 ++++++++++++++++++++++++++++++++++++++------
> 3 files changed, 231 insertions(+), 108 deletions(-)
>
> diff --git a/test/litest-int.h b/test/litest-int.h
> index b515b6c..19e6e68 100644
> --- a/test/litest-int.h
> +++ b/test/litest-int.h
> @@ -23,19 +23,52 @@
> #if HAVE_CONFIG_H
> #include "config.h"
> #endif
> +#include <limits.h>
>
> #ifndef LITEST_INT_H
> #define LITEST_INT_H
> #include "litest.h"
>
> +/* Use as designater for litest to change the value */
> +#define LITEST_AUTO_ASSIGN INT_MIN
> +
> struct litest_test_device {
> enum litest_device_type type;
> enum litest_device_feature features;
> const char *shortname;
> void (*setup)(void); /* test fixture, used by check */
> void (*teardown)(void); /* test fixture, used by check */
> -
> + /**
> + * If create is non-NULL it will be called to initialize the device.
> + * For such devices, no overrides are possible. If create is NULL,
> + * the information in name, id, events, absinfo is used to
> + * create the device instead.
> + */
> void (*create)(struct litest_device *d);
> +
> + /**
> + * The device name. Only used when create is NULL.
> + */
> + const char *name;
> + /**
> + * The device id. Only used when create is NULL.
> + */
> + const struct input_id *id;
> + /**
> + * List of event type/code tuples, terminated with -1, e.g.
> + * EV_REL, REL_X, EV_KEY, BTN_LEFT, -1
> + * Special tuple is INPUT_PROP_MAX, <actual property> to set.
> + *
> + * Any EV_ABS codes in this list will be initialized with a default
> + * axis range.
> + */
> + int *events;
> + /**
> + * List of abs codes to enable, with absinfo.value determining the
> + * code to set. List must be terminated with absinfo.value -1
> + */
> + struct input_absinfo *absinfo;
> + struct litest_device_interface *interface;
> };
>
> struct litest_device_interface {
> @@ -43,6 +76,18 @@ struct litest_device_interface {
> void (*touch_move)(struct litest_device *d, unsigned int slot, int x, int y);
> void (*touch_up)(struct litest_device *d, unsigned int slot);
>
> + /**
> + * Set of of events to execute on touch down, terminated by a .type
> + * and .code value of -1. If the event value is LITEST_AUTO_ASSIGN,
> + * it will be automatically assigned by the framework (valid for x,
> + * y, tracking id and slot).
> + *
> + * These events are only used if touch_down is NULL.
> + */
> + struct input_event *touch_down_events;
> + struct input_event *touch_move_events;
> + struct input_event *touch_up_events;
> +
> int min[2];
> int max[2];
> };
> diff --git a/test/litest-synaptics.c b/test/litest-synaptics.c
> index c960db2..f220858 100644
> --- a/test/litest-synaptics.c
> +++ b/test/litest-synaptics.c
> @@ -34,105 +34,78 @@ void litest_synaptics_clickpad_setup(void)
> litest_set_current_device(d);
> }
>
> -void
> -litest_synaptics_clickpad_touch_down(struct litest_device *d,
> - unsigned int slot,
> - int x, int y)
> -{
> - static int tracking_id;
> - struct input_event *ev;
> - struct input_event down[] = {
> - { .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 },
> - { .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
> - { .type = EV_ABS, .code = ABS_X, .value = x },
> - { .type = EV_ABS, .code = ABS_Y, .value = y },
> - { .type = EV_ABS, .code = ABS_PRESSURE, .value = 30 },
> - { .type = EV_ABS, .code = ABS_MT_SLOT, .value = slot },
> - { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = ++tracking_id },
> - { .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = x },
> - { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = y },
> - { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
> - };
> +static struct input_event down[] = {
> + { .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 },
> + { .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
> + { .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 = 30 },
> + { .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_SYN, .code = SYN_REPORT, .value = 0 },
> + { .type = -1, .code = -1 },
> +};
>
> - down[2].value = litest_scale(d, ABS_X, x);
> - down[3].value = litest_scale(d, ABS_Y, y);
> - down[7].value = litest_scale(d, ABS_X, x);
> - down[8].value = litest_scale(d, ABS_Y, y);
> -
> - ARRAY_FOR_EACH(down, ev)
> - litest_event(d, ev->type, ev->code, ev->value);
> -}
> -
> -void
> -litest_synaptics_clickpad_move(struct litest_device *d,
> - unsigned int slot,
> - int x, int y)
> -{
> - struct input_event *ev;
> - struct input_event move[] = {
> - { .type = EV_ABS, .code = ABS_MT_SLOT, .value = slot },
> - { .type = EV_ABS, .code = ABS_X, .value = x },
> - { .type = EV_ABS, .code = ABS_Y, .value = y },
> - { .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = x },
> - { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = y },
> - { .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 },
> - { .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
> - { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
> - };
> -
> - move[1].value = litest_scale(d, ABS_X, x);
> - move[2].value = litest_scale(d, ABS_Y, y);
> - move[3].value = litest_scale(d, ABS_X, x);
> - move[4].value = litest_scale(d, ABS_Y, y);
> -
> - ARRAY_FOR_EACH(move, ev)
> - litest_event(d, ev->type, ev->code, ev->value);
> -}
> +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_MT_POSITION_X, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = LITEST_AUTO_ASSIGN },
> + { .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 },
> + { .type = EV_KEY, .code = BTN_TOUCH, .value = 1 },
> + { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
> + { .type = -1, .code = -1 },
> +};
>
> static struct litest_device_interface interface = {
> - .touch_down = litest_synaptics_clickpad_touch_down,
> - .touch_move = litest_synaptics_clickpad_move,
> + .touch_down_events = down,
> + .touch_move_events = move,
> };
>
> -void
> -litest_create_synaptics_clickpad(struct litest_device *d)
> -{
> - struct input_absinfo abs[] = {
> - { ABS_X, 1472, 5472, 75 },
> - { ABS_Y, 1408, 4448, 129 },
> - { ABS_PRESSURE, 0, 255, 0 },
> - { ABS_TOOL_WIDTH, 0, 15, 0 },
> - { ABS_MT_SLOT, 0, 1, 0 },
> - { ABS_MT_POSITION_X, 1472, 5472, 75 },
> - { ABS_MT_POSITION_Y, 1408, 4448, 129 },
> - { ABS_MT_TRACKING_ID, 0, 65535, 0 },
> - { ABS_MT_PRESSURE, 0, 255, 0 },
> - { .value = -1 },
> - };
> - struct input_id id = {
> - .bustype = 0x11,
> - .vendor = 0x2,
> - .product = 0x11,
> - };
> +static struct input_id input_id = {
> + .bustype = 0x11,
> + .vendor = 0x2,
> + .product = 0x11,
> +};
> +
> +static int events[] = {
> + EV_KEY, BTN_LEFT,
> + EV_KEY, BTN_TOOL_FINGER,
> + EV_KEY, BTN_TOOL_QUINTTAP,
> + EV_KEY, BTN_TOUCH,
> + EV_KEY, BTN_TOOL_DOUBLETAP,
> + EV_KEY, BTN_TOOL_TRIPLETAP,
> + EV_KEY, BTN_TOOL_QUADTAP,
> + -1, -1,
> +};
>
> - d->interface = &interface;
> - d->uinput = litest_create_uinput_abs_device("SynPS/2 Synaptics TouchPad", &id,
> - abs,
> - EV_KEY, BTN_LEFT,
> - EV_KEY, BTN_TOOL_FINGER,
> - EV_KEY, BTN_TOOL_QUINTTAP,
> - EV_KEY, BTN_TOUCH,
> - EV_KEY, BTN_TOOL_DOUBLETAP,
> - EV_KEY, BTN_TOOL_TRIPLETAP,
> - EV_KEY, BTN_TOOL_QUADTAP,
> - -1, -1);
> -}
> +static struct input_absinfo absinfo[] = {
> + { ABS_X, 1472, 5472, 75 },
> + { ABS_Y, 1408, 4448, 129 },
> + { ABS_PRESSURE, 0, 255, 0 },
> + { ABS_TOOL_WIDTH, 0, 15, 0 },
> + { ABS_MT_SLOT, 0, 1, 0 },
> + { ABS_MT_POSITION_X, 1472, 5472, 75 },
> + { ABS_MT_POSITION_Y, 1408, 4448, 129 },
> + { ABS_MT_TRACKING_ID, 0, 65535, 0 },
> + { ABS_MT_PRESSURE, 0, 255, 0 },
> + { .value = -1 }
> +};
>
> struct litest_test_device litest_synaptics_clickpad_device = {
> .type = LITEST_SYNAPTICS_CLICKPAD,
> .features = LITEST_TOUCHPAD | LITEST_CLICKPAD | LITEST_BUTTON,
> .shortname = "synaptics",
> .setup = litest_synaptics_clickpad_setup,
> - .teardown = litest_generic_device_teardown,
> - .create = litest_create_synaptics_clickpad,
> + .teardown = NULL,
> + .create = NULL,
> + .interface = &interface,
> +
> + .name = "SynPS/2 Synaptics TouchPad",
> + .id = &input_id,
> + .events = events,
> + .absinfo = absinfo,
> };
> diff --git a/test/litest.c b/test/litest.c
> index 6767952..23ba76b 100644
> --- a/test/litest.c
> +++ b/test/litest.c
> @@ -61,6 +61,12 @@ struct suite {
>
> static struct litest_device *current_device;
>
> +struct libevdev_uinput *
> +litest_create_uinput_device_from_description(const char *name,
> + struct input_id *id,
> + const struct input_absinfo *abs,
> + const int *events);
> +
Hmm, shouldn't this be either static, or in a header file ?
Other then that, this patch looks good:
Reviewed-by: Hans de Goede <hdegoede at redhat.com>
Regards,
Hans
> struct litest_device *litest_current_device(void) {
> return current_device;
> }
> @@ -342,7 +348,15 @@ litest_create_device(enum litest_device_type which)
> dev = devices;
> while (*dev) {
> if ((*dev)->type == which) {
> - (*dev)->create(d);
> + if ((*dev)->create)
> + (*dev)->create(d);
> + else {
> + d->uinput = litest_create_uinput_device_from_description((*dev)->name,
> + (*dev)->id,
> + (*dev)->absinfo,
> + (*dev)->events);
> + d->interface = (*dev)->interface;
> + }
> break;
> }
> dev++;
> @@ -368,10 +382,12 @@ litest_create_device(enum litest_device_type which)
> ck_assert(d->libinput_device != NULL);
> libinput_device_ref(d->libinput_device);
>
> - d->interface->min[ABS_X] = libevdev_get_abs_minimum(d->evdev, ABS_X);
> - d->interface->max[ABS_X] = libevdev_get_abs_maximum(d->evdev, ABS_X);
> - d->interface->min[ABS_Y] = libevdev_get_abs_minimum(d->evdev, ABS_Y);
> - d->interface->max[ABS_Y] = libevdev_get_abs_maximum(d->evdev, ABS_Y);
> + if (d->interface) {
> + d->interface->min[ABS_X] = libevdev_get_abs_minimum(d->evdev, ABS_X);
> + d->interface->max[ABS_X] = libevdev_get_abs_maximum(d->evdev, ABS_X);
> + d->interface->min[ABS_Y] = libevdev_get_abs_minimum(d->evdev, ABS_Y);
> + d->interface->max[ABS_Y] = libevdev_get_abs_maximum(d->evdev, ABS_Y);
> + }
> return d;
> }
>
> @@ -410,10 +426,54 @@ litest_event(struct litest_device *d, unsigned int type,
> libevdev_uinput_write_event(d->uinput, type, code, value);
> }
>
> +static int
> +auto_assign_value(struct litest_device *d,
> + const struct input_event *ev,
> + int slot, int x, int y)
> +{
> + static int tracking_id;
> + int value = ev->value;
> +
> + if (value != LITEST_AUTO_ASSIGN || ev->type != EV_ABS)
> + return value;
> +
> + switch (ev->code) {
> + case ABS_X:
> + case ABS_MT_POSITION_X:
> + value = litest_scale(d, ABS_X, x);
> + break;
> + case ABS_Y:
> + case ABS_MT_POSITION_Y:
> + value = litest_scale(d, ABS_Y, y);
> + break;
> + case ABS_MT_TRACKING_ID:
> + value = ++tracking_id;
> + break;
> + case ABS_MT_SLOT:
> + value = slot;
> + break;
> + }
> +
> + return value;
> +}
> +
> +
> void
> litest_touch_down(struct litest_device *d, unsigned int slot, int x, int y)
> {
> - d->interface->touch_down(d, slot, x, y);
> + struct input_event *ev;
> +
> + if (d->interface->touch_down) {
> + d->interface->touch_down(d, slot, x, y);
> + return;
> + }
> +
> + ev = d->interface->touch_down_events;
> + while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
> + int value = auto_assign_value(d, ev, slot, x, y);
> + litest_event(d, ev->type, ev->code, value);
> + ev++;
> + }
> }
>
> void
> @@ -421,23 +481,43 @@ litest_touch_up(struct litest_device *d, unsigned int slot)
> {
> struct input_event *ev;
> struct input_event up[] = {
> - { .type = EV_ABS, .code = ABS_MT_SLOT, .value = slot },
> + { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
> { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
> { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
> + { .type = -1, .code = -1 }
> };
>
> if (d->interface->touch_up) {
> d->interface->touch_up(d, slot);
> - } else {
> - ARRAY_FOR_EACH(up, ev)
> - litest_event(d, ev->type, ev->code, ev->value);
> + 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 = auto_assign_value(d, ev, slot, 0, 0);
> + litest_event(d, ev->type, ev->code, value);
> + ev++;
> }
> }
>
> void
> litest_touch_move(struct litest_device *d, unsigned int slot, int x, int y)
> {
> - d->interface->touch_move(d, slot, x, y);
> + struct input_event *ev;
> +
> + if (d->interface->touch_move) {
> + d->interface->touch_move(d, slot, x, y);
> + return;
> + }
> +
> + ev = d->interface->touch_move_events;
> + while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
> + int value = auto_assign_value(d, ev, slot, x, y);
> + litest_event(d, ev->type, ev->code, value);
> + ev++;
> + }
> }
>
> void
> @@ -492,11 +572,11 @@ litest_drain_events(struct libinput *li)
> }
> }
>
> -static struct libevdev_uinput *
> -litest_create_uinput_abs_device_v(const char *name,
> - struct input_id *id,
> - const struct input_absinfo *abs,
> - va_list args)
> +struct libevdev_uinput *
> +litest_create_uinput_device_from_description(const char *name,
> + struct input_id *id,
> + const struct input_absinfo *abs,
> + const int *events)
> {
> struct libevdev_uinput *uinput;
> struct libevdev *dev;
> @@ -528,8 +608,9 @@ litest_create_uinput_abs_device_v(const char *name,
> abs++;
> }
>
> - while ((type = va_arg(args, int)) != -1 &&
> - (code = va_arg(args, int)) != -1) {
> + while (events &&
> + (type = *events++) != -1 &&
> + (code = *events++) != -1) {
> if (type == INPUT_PROP_MAX) {
> rc = libevdev_enable_property(dev, code);
> } else {
> @@ -551,6 +632,30 @@ litest_create_uinput_abs_device_v(const char *name,
> return uinput;
> }
>
> +static struct libevdev_uinput *
> +litest_create_uinput_abs_device_v(const char *name,
> + struct input_id *id,
> + const struct input_absinfo *abs,
> + va_list args)
> +{
> + int events[KEY_MAX * 2 + 2]; /* increase this if not sufficient */
> + int *event = events;
> + int type, code;
> +
> + while ((type = va_arg(args, int)) != -1 &&
> + (code = va_arg(args, int)) != -1) {
> + *event++ = type;
> + *event++ = code;
> + ck_assert(event < &events[ARRAY_LENGTH(events) - 2]);
> + }
> +
> + *event++ = -1;
> + *event++ = -1;
> +
> + return litest_create_uinput_device_from_description(name, id,
> + abs, events);
> +}
> +
> struct libevdev_uinput *
> litest_create_uinput_abs_device(const char *name,
> struct input_id *id,
>
More information about the wayland-devel
mailing list