[PATCH libinput 3/5] test: allow for description-based test devices

Peter Hutterer peter.hutterer at who-t.net
Mon Mar 31 20:47:07 PDT 2014


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);
+
 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,
-- 
1.9.0



More information about the wayland-devel mailing list