[PATCH libinput 3/9] test: Add seat slot tests

Jonas Ådahl jadahl at gmail.com
Wed Apr 9 12:02:10 PDT 2014


Add one test that checks uniqueness of seat slots when having multiple
devices with active touch points.

Add one test that checks that libinput drops touch points when it could
not represent them with a seat wide slot.

This commit also adds support for from a test case add test devices to
an existing libinput context. Only litest-genric-highres-touch supports
this so far and only generic artificial test devices should, in order to
keep emulated devices closer to their originals.

Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
---
 test/litest.c |  45 ++++++++++++---
 test/litest.h |  16 +++++
 test/touch.c  | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 235 insertions(+), 9 deletions(-)

diff --git a/test/litest.c b/test/litest.c
index af7fd39..495871c 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -451,12 +451,22 @@ litest_create(enum litest_device_type which,
 
 }
 
+struct libinput *
+litest_create_context(void)
+{
+	struct libinput *libinput =
+		libinput_path_create_context(&interface, NULL);
+	ck_assert_notnull(libinput);
+	return libinput;
+}
+
 struct litest_device *
-litest_create_device_with_overrides(enum litest_device_type which,
-				    const char *name_override,
-				    struct input_id *id_override,
-				    const struct input_absinfo *abs_override,
-				    const int *events_override)
+litest_add_device_with_overrides(struct libinput *libinput,
+				 enum litest_device_type which,
+				 const char *name_override,
+				 struct input_id *id_override,
+				 const struct input_absinfo *abs_override,
+				 const int *events_override)
 {
 	struct litest_device *d;
 	int fd;
@@ -477,9 +487,7 @@ litest_create_device_with_overrides(enum litest_device_type which,
 	rc = libevdev_new_from_fd(fd, &d->evdev);
 	ck_assert_int_eq(rc, 0);
 
-	d->libinput = libinput_path_create_context(&interface, NULL);
-	ck_assert(d->libinput != NULL);
-
+	d->libinput = libinput;
 	d->libinput_device = libinput_path_add_device(d->libinput, path);
 	ck_assert(d->libinput_device != NULL);
 	libinput_device_ref(d->libinput_device);
@@ -494,6 +502,24 @@ litest_create_device_with_overrides(enum litest_device_type which,
 }
 
 struct litest_device *
+litest_create_device_with_overrides(enum litest_device_type which,
+				    const char *name_override,
+				    struct input_id *id_override,
+				    const struct input_absinfo *abs_override,
+				    const int *events_override)
+{
+	struct litest_device *dev =
+		litest_add_device_with_overrides(litest_create_context(),
+						 which,
+						 name_override,
+						 id_override,
+						 abs_override,
+						 events_override);
+	dev->owns_context = true;
+	return dev;
+}
+
+struct litest_device *
 litest_create_device(enum litest_device_type which)
 {
 	return litest_create_device_with_overrides(which, NULL, NULL, NULL, NULL);
@@ -520,7 +546,8 @@ litest_delete_device(struct litest_device *d)
 		return;
 
 	libinput_device_unref(d->libinput_device);
-	libinput_destroy(d->libinput);
+	if (d->owns_context)
+		libinput_destroy(d->libinput);
 	libevdev_free(d->evdev);
 	libevdev_uinput_destroy(d->uinput);
 	memset(d,0, sizeof(*d));
diff --git a/test/litest.h b/test/litest.h
index 85748cc..1533287 100644
--- a/test/litest.h
+++ b/test/litest.h
@@ -61,10 +61,14 @@ struct litest_device {
 	struct libevdev *evdev;
 	struct libevdev_uinput *uinput;
 	struct libinput *libinput;
+	bool owns_context;
 	struct libinput_device *libinput_device;
 	struct litest_device_interface *interface;
+	int device_id;
 };
 
+struct libinput *litest_create_context(void);
+
 void litest_add(const char *name, void *func,
 		enum litest_device_feature required_feature,
 		enum litest_device_feature excluded_feature);
@@ -83,6 +87,14 @@ litest_create_device_with_overrides(enum litest_device_type which,
 				    struct input_id *id_override,
 				    const struct input_absinfo *abs_override,
 				    const int *events_override);
+struct litest_device *
+litest_add_device_with_overrides(struct libinput *libinput,
+				 enum litest_device_type which,
+				 const char *name_override,
+				 struct input_id *id_override,
+				 const struct input_absinfo *abs_override,
+				 const int *events_override);
+
 struct litest_device *litest_current_device(void);
 void litest_delete_device(struct litest_device *d);
 int litest_handle_events(struct litest_device *d);
@@ -118,4 +130,8 @@ struct libevdev_uinput * litest_create_uinput_abs_device(const char *name,
 							 const struct input_absinfo *abs,
 							 ...);
 
+#ifndef ck_assert_notnull
+#define ck_assert_notnull(ptr) ck_assert_ptr_ne(ptr, NULL)
+#endif
+
 #endif /* LITEST_H */
diff --git a/test/touch.c b/test/touch.c
index 27ed881..e1a8146 100644
--- a/test/touch.c
+++ b/test/touch.c
@@ -22,6 +22,7 @@
 
 #include <config.h>
 
+#include <stdio.h>
 #include <check.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -110,12 +111,194 @@ START_TEST(touch_abs_transform)
 }
 END_TEST
 
+START_TEST(touch_seat_slots)
+{
+
+	struct libinput *libinput;
+	struct litest_device *dev1;
+	struct litest_device *dev2;
+	struct libinput_event *ev;
+	struct libinput_event_touch *tev;
+	int32_t seat_slot;
+	int32_t last_seat_slot = -1;
+	bool has_last_seat_slot = false;
+
+	libinput = litest_create_context();
+
+	dev1 = litest_add_device_with_overrides(libinput,
+						LITEST_WACOM_TOUCH,
+						"Touch device (0)",
+						NULL, NULL, NULL);
+	dev2 = litest_add_device_with_overrides(libinput,
+						LITEST_WACOM_TOUCH,
+						"Touch device (1)",
+						NULL, NULL, NULL);
+
+	litest_touch_down(dev1, 0, 0, 0);
+	/* Use different coordinates to avoid kernel filter. */
+	litest_touch_down(dev2, 0, 0, 1);
+
+	libinput_dispatch(libinput);
+
+	/*
+	 * Read the two touch down events and ensure their seat slot are
+	 * unique.
+	 */
+	while ((ev = libinput_get_event(libinput))) {
+		if (libinput_event_get_type(ev) != LIBINPUT_EVENT_TOUCH_DOWN)
+			continue;
+
+		tev = libinput_event_get_touch_event(ev);
+
+		ck_assert_int_eq(libinput_event_touch_get_slot(tev), 0);
+		seat_slot = libinput_event_touch_get_seat_slot(tev);
+		ck_assert_int_ge(seat_slot, 0);
+
+		if (!has_last_seat_slot) {
+			has_last_seat_slot = true;
+			last_seat_slot = seat_slot;
+			continue;
+		}
+
+		ck_assert_int_ne(seat_slot, last_seat_slot);
+
+		libinput_dispatch(libinput);
+	}
+
+	ck_assert(has_last_seat_slot);
+	ck_assert_int_ne(seat_slot, last_seat_slot);
+
+	litest_delete_device(dev1);
+	litest_delete_device(dev2);
+
+	libinput_destroy(libinput);
+}
+END_TEST
+
+START_TEST(touch_seat_slot_drop)
+{
+	struct libinput *libinput;
+	struct litest_device *dev;
+	struct libinput_event *ev;
+	struct libinput_event_touch *tev;
+	const int num_devices = 10;
+	const int tps_per_device = 16;
+	const int num_tps = num_devices * tps_per_device;
+	struct litest_device *devices[num_devices];
+	int slot;
+	int seat_slot;
+	enum libinput_event_type type;
+	int found = 0;
+	int i;
+	int slot_count = 0;
+	int slot_max_count;
+	int32_t slots[num_tps];
+	char device_name[255];
+
+	libinput = litest_create_context();
+
+	struct input_absinfo abs[] = {
+		{ ABS_MT_SLOT, 0, tps_per_device, 0, 0, 0 },
+		{ .value = -1 },
+	};
+
+	/* Activate touch points from several devices in order to surpass per
+	 * device touch slot limit. */
+	for (i = 0; i < num_devices; ++i) {
+		sprintf(device_name, "Multi-touch device (%d)", i);
+		devices[i] =
+			litest_add_device_with_overrides(libinput,
+							 LITEST_WACOM_TOUCH,
+							 device_name,
+							 NULL, abs, NULL);
+	}
+
+	litest_drain_events(libinput);
+
+	/* Trigger touch down events */
+	for (i = 0; i < num_devices; ++i) {
+		dev = devices[i];
+		for (slot = 0; slot < num_tps; ++slot)
+			litest_touch_down(dev, slot, 0, 0);
+	}
+
+	libinput_dispatch(libinput);
+
+	/* Expect up to `num_tps`, but allow fewer. */
+	memset(slots, 0, sizeof slots);
+	while ((ev = libinput_get_event(libinput))) {
+		type = libinput_event_get_type(ev);
+		if (type == LIBINPUT_EVENT_TOUCH_FRAME)
+			continue;
+		ck_assert_int_eq(type, LIBINPUT_EVENT_TOUCH_DOWN);
+
+		tev = libinput_event_get_touch_event(ev);
+		seat_slot = libinput_event_touch_get_seat_slot(tev);
+
+		ck_assert_int_ge(seat_slot, 0);
+		ck_assert_int_lt(slot_count, num_tps);
+		ck_assert_int_eq(slots[slot_count], 0);
+
+		/* Assert uniqueness */
+		for (slot = 0; slot < slot_count; ++slot)
+			ck_assert_int_ne(seat_slot, slots[slot]);
+
+		slots[slot_count] = seat_slot;
+		++slot_count;
+
+		libinput_dispatch(libinput);
+	}
+
+	ck_assert_int_gt(slot_count, 0);
+
+	slot_max_count = slot_count;
+
+	/* Trigger touch up events */
+	for (i = 0; i < num_devices; ++i) {
+		dev = devices[i];
+		for (slot = 0; slot < num_tps; ++slot)
+			litest_touch_up(dev, slot);
+	}
+
+	libinput_dispatch(libinput);
+
+	/* Make sure order was not shuffled and we received up before all
+	 * down, and that we received as many up as down. */
+	while ((ev = libinput_get_event(libinput))) {
+		type = libinput_event_get_type(ev);
+		if (type == LIBINPUT_EVENT_TOUCH_FRAME)
+			continue;
+		ck_assert_int_eq(type, LIBINPUT_EVENT_TOUCH_UP);
+
+		tev = libinput_event_get_touch_event(ev);
+		seat_slot = libinput_event_touch_get_seat_slot(tev);
+
+		--slot_count;
+		found = 0;
+		for (slot = 0; slot < slot_max_count; ++slot)
+			if (slots[slot] == seat_slot)
+				++found;
+		ck_assert_int_eq(found, 1);
+
+		libinput_dispatch(libinput);
+	}
+
+	ck_assert_int_eq(slot_count, 0);
+
+	for (i = 0; i < num_devices; ++i)
+		litest_delete_device(devices[i]);
+
+	libinput_destroy(libinput);
+}
+END_TEST
 
 int
 main(int argc, char **argv)
 {
 	litest_add("touch:frame", touch_frame_events, LITEST_TOUCH, LITEST_ANY);
 	litest_add_no_device("touch:abs-transform", touch_abs_transform);
+	litest_add_no_device("touch:seat-slot", touch_seat_slots);
+	litest_add_no_device("touch:seat-slot-drop", touch_seat_slot_drop);
 
 	return litest_run(argc, argv);
 }
-- 
1.8.3.2



More information about the wayland-devel mailing list