xref: /third_party/libinput/test/litest.c (revision a46c0ec8)
1/*
2 * Copyright © 2013 Red Hat, Inc.
3 * Copyright © 2013 Marcin Slusarz <marcin.slusarz@gmail.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "config.h"
26
27#include <check.h>
28#include <dirent.h>
29#include <errno.h>
30#include <libgen.h>
31#include <fcntl.h>
32#include <fnmatch.h>
33#include <getopt.h>
34#include <poll.h>
35#include <signal.h>
36#include <stdint.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <stdarg.h>
40#include <time.h>
41#include <unistd.h>
42#include "linux/input.h"
43#include <sys/ptrace.h>
44#include <sys/resource.h>
45#include <sys/timerfd.h>
46#include <sys/wait.h>
47#include <sys/stat.h>
48#include <sys/types.h>
49#include <sys/sysinfo.h>
50#include <libudev.h>
51#if HAVE_LIBSYSTEMD
52#include <systemd/sd-bus.h>
53#endif
54#ifdef __FreeBSD__
55#include <termios.h>
56#endif
57
58#include <valgrind/valgrind.h>
59
60#include "litest.h"
61#include "litest-int.h"
62#include "libinput-util.h"
63#include "quirks.h"
64#include "builddir.h"
65
66#include <linux/kd.h>
67
68#define evbit(t, c) ((t) << 16U | (c & 0xffff))
69
70#define UDEV_RULES_D "/run/udev/rules.d"
71#define UDEV_FUZZ_OVERRIDE_RULE_FILE UDEV_RULES_D \
72	"/91-litest-fuzz-override-REMOVEME-XXXXXX.rules"
73#define UDEV_TEST_DEVICE_RULE_FILE UDEV_RULES_D \
74	"/91-litest-test-device-REMOVEME-XXXXXXX.rules"
75#define UDEV_DEVICE_GROUPS_FILE UDEV_RULES_D \
76	"/80-libinput-device-groups-litest-XXXXXX.rules"
77
78static int jobs;
79static bool in_debugger = false;
80static bool verbose = false;
81static bool run_deviceless = false;
82static bool use_system_rules_quirks = false;
83static const char *filter_test = NULL;
84static const char *filter_device = NULL;
85static const char *filter_group = NULL;
86static const char *xml_prefix = NULL;
87static struct quirks_context *quirks_context;
88
89struct created_file {
90	struct list link;
91	char *path;
92};
93
94static struct list created_files_list; /* list of all files to remove at the end
95					  of the test run */
96
97static void litest_init_udev_rules(struct list *created_files_list);
98static void litest_remove_udev_rules(struct list *created_files_list);
99
100enum quirks_setup_mode {
101	QUIRKS_SETUP_USE_SRCDIR,
102	QUIRKS_SETUP_ONLY_DEVICE,
103	QUIRKS_SETUP_FULL,
104};
105static void litest_setup_quirks(struct list *created_files_list,
106				enum quirks_setup_mode mode);
107
108/* defined for the litest selftest */
109#ifndef LITEST_DISABLE_BACKTRACE_LOGGING
110#define litest_log(...) fprintf(stderr, __VA_ARGS__)
111#define litest_vlog(format_, args_) vfprintf(stderr, format_, args_)
112#else
113#define litest_log(...) { /* __VA_ARGS__ */ }
114#define litest_vlog(...) { /* __VA_ARGS__ */ }
115#endif
116
117static void
118litest_backtrace(void)
119{
120#if HAVE_GSTACK
121	pid_t parent, child;
122	int pipefd[2];
123
124	if (RUNNING_ON_VALGRIND) {
125		litest_log("  Using valgrind, omitting backtrace\n");
126		return;
127	}
128
129	if (pipe(pipefd) == -1)
130		return;
131
132	parent = getpid();
133	child = fork();
134
135	if (child == 0) {
136		char pid[8];
137
138		close(pipefd[0]);
139		dup2(pipefd[1], STDOUT_FILENO);
140
141		sprintf(pid, "%d", parent);
142
143		execlp("gstack", "gstack", pid, NULL);
144		exit(errno);
145	}
146
147	/* parent */
148	char buf[1024];
149	int status, nread;
150
151	close(pipefd[1]);
152	waitpid(child, &status, 0);
153
154	status = WEXITSTATUS(status);
155	if (status != 0) {
156		litest_log("ERROR: gstack failed, no backtrace available: %s\n",
157			   strerror(status));
158	} else {
159		litest_log("\nBacktrace:\n");
160		while ((nread = read(pipefd[0], buf, sizeof(buf) - 1)) > 0) {
161			buf[nread] = '\0';
162			litest_log("%s", buf);
163		}
164		litest_log("\n");
165	}
166	close(pipefd[0]);
167#endif
168}
169
170LIBINPUT_ATTRIBUTE_PRINTF(5, 6)
171__attribute__((noreturn))
172void
173litest_fail_condition(const char *file,
174		      int line,
175		      const char *func,
176		      const char *condition,
177		      const char *message,
178		      ...)
179{
180	litest_log("FAILED: %s\n", condition);
181
182	if (message) {
183		va_list args;
184		va_start(args, message);
185		litest_vlog(message, args);
186		va_end(args);
187	}
188
189	litest_log("in %s() (%s:%d)\n", func, file, line);
190	litest_backtrace();
191	abort();
192}
193
194__attribute__((noreturn))
195void
196litest_fail_comparison_int(const char *file,
197			   int line,
198			   const char *func,
199			   const char *operator,
200			   int a,
201			   int b,
202			   const char *astr,
203			   const char *bstr)
204{
205	litest_log("FAILED COMPARISON: %s %s %s\n", astr, operator, bstr);
206	litest_log("Resolved to: %d %s %d\n", a, operator, b);
207	litest_log("in %s() (%s:%d)\n", func, file, line);
208	litest_backtrace();
209	abort();
210}
211
212__attribute__((noreturn))
213void
214litest_fail_comparison_double(const char *file,
215			      int line,
216			      const char *func,
217			      const char *operator,
218			      double a,
219			      double b,
220			      const char *astr,
221			      const char *bstr)
222{
223	litest_log("FAILED COMPARISON: %s %s %s\n", astr, operator, bstr);
224	litest_log("Resolved to: %.3f %s %.3f\n", a, operator, b);
225	litest_log("in %s() (%s:%d)\n", func, file, line);
226	litest_backtrace();
227	abort();
228}
229
230__attribute__((noreturn))
231void
232litest_fail_comparison_ptr(const char *file,
233			   int line,
234			   const char *func,
235			   const char *comparison)
236{
237	litest_log("FAILED COMPARISON: %s\n", comparison);
238	litest_log("in %s() (%s:%d)\n", func, file, line);
239	litest_backtrace();
240	abort();
241}
242
243struct test {
244	struct list node;
245	char *name;
246	char *devname;
247	const void *func;
248	void *setup;
249	void *teardown;
250
251	struct range range;
252	bool deviceless;
253};
254
255struct suite {
256	struct list node;
257	struct list tests;
258	char *name;
259};
260
261static struct litest_device *current_device;
262
263struct litest_device *litest_current_device(void)
264{
265	return current_device;
266}
267
268static void
269grab_device(struct litest_device *device, bool mode)
270{
271	struct libinput *li = libinput_device_get_context(device->libinput_device);
272	struct litest_context *ctx = libinput_get_user_data(li);
273	struct udev_device *udev_device;
274	const char *devnode;
275	struct path *p;
276
277	udev_device = libinput_device_get_udev_device(device->libinput_device);
278	litest_assert_ptr_notnull(udev_device);
279
280	devnode = udev_device_get_devnode(udev_device);
281
282	/* Note: in some tests we create multiple devices for the same path.
283	 * This will only grab the first device in the list but we're using
284	 * list_insert() so the first device is the latest that was
285	 * initialized, so we should be good.
286	 */
287	list_for_each(p, &ctx->paths, link) {
288		if (streq(p->path, devnode)) {
289			int rc = ioctl(p->fd, EVIOCGRAB, (void*)mode ? 1 : 0);
290			ck_assert_int_gt(rc, -1);
291			udev_device_unref(udev_device);
292			return;
293		}
294	}
295	litest_abort_msg("Failed to find device %s to %sgrab\n",
296			 devnode, mode ? "" : "un");
297}
298
299void
300litest_grab_device(struct litest_device *device)
301{
302	grab_device(device, true);
303}
304
305void
306litest_ungrab_device(struct litest_device *device)
307{
308	grab_device(device, false);
309}
310
311void litest_set_current_device(struct litest_device *device)
312{
313	current_device = device;
314}
315
316void litest_generic_device_teardown(void)
317{
318	litest_delete_device(current_device);
319	current_device = NULL;
320}
321
322static struct list devices;
323
324static struct list all_tests;
325
326static inline void
327litest_system(const char *command)
328{
329	int ret;
330
331	ret = system(command);
332
333	if (ret == -1) {
334		litest_abort_msg("Failed to execute: %s", command);
335	} else if (WIFEXITED(ret)) {
336		if (WEXITSTATUS(ret))
337			litest_abort_msg("'%s' failed with %d",
338					 command,
339					 WEXITSTATUS(ret));
340	} else if (WIFSIGNALED(ret)) {
341		litest_abort_msg("'%s' terminated with signal %d",
342				 command,
343				 WTERMSIG(ret));
344	}
345}
346
347static void
348litest_reload_udev_rules(void)
349{
350	litest_system("udevadm control --reload-rules");
351}
352
353static void
354litest_add_tcase_for_device(struct suite *suite,
355			    const char *funcname,
356			    const void *func,
357			    const struct litest_test_device *dev,
358			    const struct range *range)
359{
360	struct test *t;
361
362	t = zalloc(sizeof(*t));
363	t->name = safe_strdup(funcname);
364	t->devname = safe_strdup(dev->shortname);
365	t->func = func;
366	t->setup = dev->setup;
367	t->teardown = dev->teardown ?
368			dev->teardown : litest_generic_device_teardown;
369	if (range)
370		t->range = *range;
371
372	list_insert(&suite->tests, &t->node);
373}
374
375static void
376litest_add_tcase_no_device(struct suite *suite,
377			   const void *func,
378			   const char *funcname,
379			   const struct range *range)
380{
381	struct test *t;
382	const char *test_name = funcname;
383
384	if (filter_device &&
385	    strstr(test_name, filter_device) == NULL &&
386	    fnmatch(filter_device, test_name, 0) != 0)
387		return;
388
389	t = zalloc(sizeof(*t));
390	t->name = safe_strdup(test_name);
391	t->devname = safe_strdup("no device");
392	t->func = func;
393	if (range)
394		t->range = *range;
395	t->setup = NULL;
396	t->teardown = NULL;
397
398	list_insert(&suite->tests, &t->node);
399}
400
401static void
402litest_add_tcase_deviceless(struct suite *suite,
403			    const void *func,
404			    const char *funcname,
405			    const struct range *range)
406{
407	struct test *t;
408	const char *test_name = funcname;
409
410	if (filter_device &&
411	    strstr(test_name, filter_device) == NULL &&
412	    fnmatch(filter_device, test_name, 0) != 0)
413		return;
414
415	t = zalloc(sizeof(*t));
416	t->deviceless = true;
417	t->name = safe_strdup(test_name);
418	t->devname = safe_strdup("deviceless");
419	t->func = func;
420	if (range)
421		t->range = *range;
422	t->setup = NULL;
423	t->teardown = NULL;
424
425	list_insert(&suite->tests, &t->node);
426}
427
428static struct suite *
429get_suite(const char *name)
430{
431	struct suite *s;
432
433	list_for_each(s, &all_tests, node) {
434		if (streq(s->name, name))
435			return s;
436	}
437
438	s = zalloc(sizeof(*s));
439	s->name = safe_strdup(name);
440
441	list_init(&s->tests);
442	list_insert(&all_tests, &s->node);
443
444	return s;
445}
446
447static void
448create_suite_name(const char *filename, char suitename[64])
449{
450	char *trunk = trunkname(filename);
451	char *p = trunk;
452
453	/* strip the test- prefix */
454	if (strstartswith(trunk, "test-"))
455		p += 5;
456
457	snprintf(suitename, 64, "%s", p);
458	free(trunk);
459}
460
461static void
462litest_add_tcase(const char *filename,
463		 const char *funcname,
464		 const void *func,
465		 int64_t required,
466		 int64_t excluded,
467		 const struct range *range)
468{
469	char suite_name[65];
470	struct suite *suite;
471	bool added = false;
472
473	litest_assert(required >= LITEST_DEVICELESS);
474	litest_assert(excluded >= LITEST_DEVICELESS);
475
476	if (filter_test &&
477	    strstr(funcname, filter_test) == NULL &&
478	    fnmatch(filter_test, funcname, 0) != 0)
479		return;
480
481	create_suite_name(filename, suite_name);
482
483	if (filter_group && fnmatch(filter_group, suite_name, 0) != 0)
484		return;
485
486	suite = get_suite(suite_name);
487
488	if (required == LITEST_DEVICELESS &&
489	    excluded == LITEST_DEVICELESS) {
490		litest_add_tcase_deviceless(suite, func, funcname, range);
491		added = true;
492	} else if (required == LITEST_DISABLE_DEVICE &&
493	    excluded == LITEST_DISABLE_DEVICE) {
494		litest_add_tcase_no_device(suite, func, funcname, range);
495		added = true;
496	} else if (required != LITEST_ANY || excluded != LITEST_ANY) {
497		struct litest_test_device *dev;
498
499		list_for_each(dev, &devices, node) {
500			if (dev->features & LITEST_IGNORED)
501				continue;
502
503			if (filter_device &&
504			    strstr(dev->shortname, filter_device) == NULL &&
505			    fnmatch(filter_device, dev->shortname, 0) != 0)
506				continue;
507			if ((dev->features & required) != required ||
508			    (dev->features & excluded) != 0)
509				continue;
510
511			litest_add_tcase_for_device(suite,
512						    funcname,
513						    func,
514						    dev,
515						    range);
516			added = true;
517		}
518	} else {
519		struct litest_test_device *dev;
520
521		list_for_each(dev, &devices, node) {
522			if (dev->features & LITEST_IGNORED)
523				continue;
524
525			if (filter_device &&
526			    strstr(dev->shortname, filter_device) == NULL &&
527			    fnmatch(filter_device, dev->shortname, 0) != 0)
528				continue;
529
530			litest_add_tcase_for_device(suite,
531						    funcname,
532						    func,
533						    dev,
534						    range);
535			added = true;
536		}
537	}
538
539	if (!added &&
540	    filter_test == NULL &&
541	    filter_device == NULL &&
542	    filter_group == NULL) {
543		fprintf(stderr, "Test '%s' does not match any devices. Aborting.\n", funcname);
544		abort();
545	}
546}
547
548void
549_litest_add_no_device(const char *name, const char *funcname, const void *func)
550{
551	_litest_add(name, funcname, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
552}
553
554void
555_litest_add_ranged_no_device(const char *name,
556			     const char *funcname,
557			     const void *func,
558			     const struct range *range)
559{
560	_litest_add_ranged(name,
561			   funcname,
562			   func,
563			   LITEST_DISABLE_DEVICE,
564			   LITEST_DISABLE_DEVICE,
565			   range);
566}
567
568void
569_litest_add_deviceless(const char *name,
570		       const char *funcname,
571		       const void *func)
572{
573	_litest_add_ranged(name,
574			   funcname,
575			   func,
576			   LITEST_DEVICELESS,
577			   LITEST_DEVICELESS,
578			   NULL);
579}
580
581void
582_litest_add(const char *name,
583	    const char *funcname,
584	    const void *func,
585	    int64_t required,
586	    int64_t excluded)
587{
588	_litest_add_ranged(name,
589			   funcname,
590			   func,
591			   required,
592			   excluded,
593			   NULL);
594}
595
596void
597_litest_add_ranged(const char *name,
598		   const char *funcname,
599		   const void *func,
600		   int64_t required,
601		   int64_t excluded,
602		   const struct range *range)
603{
604	litest_add_tcase(name, funcname, func, required, excluded, range);
605}
606
607void
608_litest_add_for_device(const char *name,
609		       const char *funcname,
610		       const void *func,
611		       enum litest_device_type type)
612{
613	_litest_add_ranged_for_device(name, funcname, func, type, NULL);
614}
615
616void
617_litest_add_ranged_for_device(const char *filename,
618			      const char *funcname,
619			      const void *func,
620			      enum litest_device_type type,
621			      const struct range *range)
622{
623	struct suite *s;
624	struct litest_test_device *dev;
625	bool device_filtered = false;
626	char suite_name[64];
627
628	litest_assert(type < LITEST_NO_DEVICE);
629
630	if (filter_test &&
631	    strstr(funcname, filter_test) == NULL &&
632	    fnmatch(filter_test, funcname, 0) != 0)
633		return;
634
635	create_suite_name(filename, suite_name);
636	if (filter_group && fnmatch(filter_group, suite_name, 0) != 0)
637		return;
638
639	s = get_suite(suite_name);
640	list_for_each(dev, &devices, node) {
641		if (filter_device &&
642		    strstr(dev->shortname, filter_device) == NULL &&
643		    fnmatch(filter_device, dev->shortname, 0) != 0) {
644			device_filtered = true;
645			continue;
646		}
647
648		if (dev->type == type) {
649			litest_add_tcase_for_device(s,
650						    funcname,
651						    func,
652						    dev,
653						    range);
654			return;
655		}
656	}
657
658	/* only abort if no filter was set, that's a bug */
659	if (!device_filtered)
660		litest_abort_msg("Invalid test device type\n");
661}
662
663LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
664static void
665litest_log_handler(struct libinput *libinput,
666		   enum libinput_log_priority pri,
667		   const char *format,
668		   va_list args)
669{
670	static int is_tty = -1;
671	const char *priority = NULL;
672	const char *color;
673
674	if (is_tty == -1)
675		is_tty = isatty(STDERR_FILENO);
676
677	switch(pri) {
678	case LIBINPUT_LOG_PRIORITY_INFO:
679		priority =  "info ";
680		color = ANSI_HIGHLIGHT;
681		break;
682	case LIBINPUT_LOG_PRIORITY_ERROR:
683		priority = "error";
684		color = ANSI_BRIGHT_RED;
685		break;
686	case LIBINPUT_LOG_PRIORITY_DEBUG:
687		priority = "debug";
688		color = ANSI_NORMAL;
689		break;
690	default:
691		  abort();
692	}
693
694	if (!is_tty)
695		color = "";
696	else if (strstr(format, "tap:"))
697		color = ANSI_BLUE;
698	else if (strstr(format, "thumb state:"))
699		color = ANSI_YELLOW;
700	else if (strstr(format, "button state:"))
701		color = ANSI_MAGENTA;
702	else if (strstr(format, "touch-size:") ||
703		 strstr(format, "pressure:"))
704		color = ANSI_GREEN;
705	else if (strstr(format, "palm:") ||
706		 strstr(format, "thumb:"))
707		color = ANSI_CYAN;
708	else if (strstr(format, "edge-scroll:"))
709		color = ANSI_BRIGHT_GREEN;
710
711	fprintf(stderr, "%slitest %s ", color, priority);
712	vfprintf(stderr, format, args);
713	if (is_tty)
714		fprintf(stderr, ANSI_NORMAL);
715
716	if (strstr(format, "client bug: ") ||
717	    strstr(format, "libinput bug: ")) {
718		/* valgrind is too slow and some of our offsets are too
719		 * short, don't abort if during a valgrind run we get a
720		 * negative offset */
721		if ((RUNNING_ON_VALGRIND && in_debugger) ||
722		    !strstr(format, "scheduled expiry is in the past")) {
723			/* noop */
724		} else if (!strstr(format, "event processing lagging behind")) {
725			/* noop */
726		} else {
727			litest_abort_msg("libinput bug triggered, aborting.\n");
728		}
729	}
730
731	if (strstr(format, "Touch jump detected and discarded")) {
732		litest_abort_msg("libinput touch jump triggered, aborting.\n");
733	}
734}
735
736static void
737litest_init_device_udev_rules(struct litest_test_device *dev, FILE *f)
738{
739	const struct key_value_str *kv;
740	static int count;
741	bool need_keyboard_builtin = false;
742
743	if (dev->udev_properties[0].key == NULL)
744		return;
745
746	count++;
747
748	fprintf(f, "# %s\n", dev->shortname);
749	fprintf(f, "ACTION==\"remove\", GOTO=\"rule%d_end\"\n", count);
750	fprintf(f, "KERNEL!=\"event*\", GOTO=\"rule%d_end\"\n", count);
751
752	fprintf(f, "ATTRS{name}==\"litest %s*\"", dev->name);
753
754	kv = dev->udev_properties;
755	while (kv->key) {
756		fprintf(f, ", \\\n\tENV{%s}=\"%s\"", kv->key, kv->value);
757		if (strneq(kv->key, "EVDEV_ABS_", 10))
758			need_keyboard_builtin = true;
759		kv++;
760	}
761	fprintf(f, "\n");
762
763	/* Special case: the udev keyboard builtin is only run for hwdb
764	 * matches but we don't set any up in litest. So instead scan the
765	 * device's udev properties for any EVDEV_ABS properties and where
766	 * they exist, force a (re-)run of the keyboard builtin to set up
767	 * the evdev device correctly.
768	 * This needs to be done as separate rule apparently, otherwise the
769	 * ENV variables aren't set yet by the time the builtin runs.
770	 */
771	if (need_keyboard_builtin) {
772		fprintf(f, ""
773			"ATTRS{name}==\"litest %s*\","
774			" IMPORT{builtin}=\"keyboard\"\n",
775			dev->name);
776	}
777
778	fprintf(f, "LABEL=\"rule%d_end\"\n\n", count);;
779}
780
781static void
782litest_init_all_device_udev_rules(struct list *created_files)
783{
784	struct created_file *file = zalloc(sizeof(*file));
785	struct litest_test_device *dev;
786	char *path = NULL;
787	FILE *f;
788	int rc;
789	int fd;
790
791	rc = xasprintf(&path,
792		      "%s/99-litest-XXXXXX.rules",
793		      UDEV_RULES_D);
794	litest_assert_int_gt(rc, 0);
795
796	fd = mkstemps(path, 6);
797	litest_assert_int_ne(fd, -1);
798	f = fdopen(fd, "w");
799	litest_assert_notnull(f);
800
801	list_for_each(dev, &devices, node)
802		litest_init_device_udev_rules(dev, f);
803
804	fclose(f);
805
806	file->path = path;
807	list_insert(created_files, &file->link);
808}
809
810static int
811open_restricted(const char *path, int flags, void *userdata)
812{
813	const char prefix[] = "/dev/input/event";
814	struct litest_context *ctx = userdata;
815	struct path *p;
816	int fd;
817
818	litest_assert_ptr_notnull(ctx);
819
820	fd = open(path, flags);
821	if (fd < 0)
822		return -errno;
823
824	if (strneq(path, prefix, strlen(prefix))) {
825		p = zalloc(sizeof *p);
826		p->path = safe_strdup(path);
827		p->fd = fd;
828		/* We specifically insert here so that the most-recently
829		 * opened path is the first one in the list. This helps when
830		 * we have multiple test devices with the same device path,
831		 * the fd of the most recent device is the first one to get
832		 * grabbed
833		 */
834		list_insert(&ctx->paths, &p->link);
835	}
836
837	return fd;
838}
839
840static void
841close_restricted(int fd, void *userdata)
842{
843	struct litest_context *ctx = userdata;
844	struct path *p;
845
846	list_for_each_safe(p, &ctx->paths, link) {
847		if (p->fd != fd)
848			continue;
849		list_remove(&p->link);
850		free(p->path);
851		free(p);
852	}
853
854	close(fd);
855}
856
857static struct libinput_interface interface = {
858	.open_restricted = open_restricted,
859	.close_restricted = close_restricted,
860};
861
862static void
863litest_signal(int sig)
864{
865	struct created_file *f;
866
867	list_for_each_safe(f, &created_files_list, link) {
868		list_remove(&f->link);
869		unlink(f->path);
870		rmdir(f->path);
871		/* in the sighandler, we can't free */
872	}
873
874	if (fork() == 0) {
875		/* child, we can run system() */
876		litest_reload_udev_rules();
877		exit(0);
878	}
879
880	exit(1);
881}
882
883static inline void
884litest_setup_sighandler(int sig)
885{
886	struct sigaction act, oact;
887	int rc;
888
889	sigemptyset(&act.sa_mask);
890	sigaddset(&act.sa_mask, sig);
891	act.sa_flags = 0;
892	act.sa_handler = litest_signal;
893	rc = sigaction(sig, &act, &oact);
894	litest_assert_int_ne(rc, -1);
895}
896
897static void
898litest_free_test_list(struct list *tests)
899{
900	struct suite *s;
901
902	list_for_each_safe(s, tests, node) {
903		struct test *t;
904
905		list_for_each_safe(t, &s->tests, node) {
906			free(t->name);
907			free(t->devname);
908			list_remove(&t->node);
909			free(t);
910		}
911
912		list_remove(&s->node);
913		free(s->name);
914		free(s);
915	}
916}
917
918LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
919static inline void
920quirk_log_handler(struct libinput *unused,
921		  enum libinput_log_priority priority,
922		  const char *format,
923		  va_list args)
924{
925	if (priority < LIBINPUT_LOG_PRIORITY_ERROR)
926		return;
927
928	vfprintf(stderr, format, args);
929}
930
931static void
932litest_export_xml(SRunner *sr, const char *xml_prefix)
933{
934	TestResult **results;
935	int nresults, nfailed;
936	char *filename;
937	int fd;
938
939	/* This is the minimum-effort implementation here because its only
940	 * real purpose is to make test logs look pretty in the gitlab CI.
941	 *
942	 * Which means:
943	 * - there's no filename validation, if you supply a filename that
944	 *   mkstemps doesn't like, things go boom.
945	 * - every fork writes out a separate junit.xml file. gitlab is better
946	 *   at collecting lots of files than I am at writing code to collect
947	 *   this across forks to write out only one file.
948	 * - most of the content is pretty useless because libcheck only gives
949	 *   us minimal information. the libcheck XML file has more info like
950	 *   the duration of each test but it's more complicated to extract
951	 *   and we don't need it for now.
952	 */
953	filename = safe_strdup(xml_prefix);
954	fd = mkstemps(filename, 4);
955
956	results = srunner_results(sr);
957	nresults = srunner_ntests_run(sr);
958	nfailed = srunner_ntests_failed(sr);
959
960	dprintf(fd, "<?xml version=\"1.0\"?>\n");
961	dprintf(fd, "<testsuites id=\"%s\" tests=\"%d\" failures=\"%d\">\n",
962		filename,
963		nresults,
964		nfailed);
965	dprintf(fd, "  <testsuite>\n");
966	for (int i = 0; i < nresults; i++) {
967		TestResult *r = results[i];
968
969		dprintf(fd, "    <testcase id=\"%s\" name=\"%s\" %s>\n",
970			tr_tcname(r),
971			tr_tcname(r),
972			tr_rtype(r) == CK_PASS ? "/" : "");
973		if (tr_rtype(r) != CK_PASS) {
974			dprintf(fd, "      <failure message=\"%s:%d\">\n",
975				tr_lfile(r),
976				tr_lno(r));
977			dprintf(fd, "        %s:%d\n", tr_lfile(r), tr_lno(r));
978			dprintf(fd, "        %s\n", tr_tcname(r));
979			dprintf(fd, "\n");
980			dprintf(fd, "        %s\n", tr_msg(r));
981			dprintf(fd, "      </failure>\n");
982			dprintf(fd, "    </testcase>\n");
983		}
984	}
985	dprintf(fd, "  </testsuite>\n");
986	dprintf(fd, "</testsuites>\n");
987
988	free(results);
989	close(fd);
990	free(filename);
991}
992
993static int
994litest_run_suite(struct list *tests, int which, int max, int error_fd)
995{
996	int failed = 0;
997	SRunner *sr = NULL;
998	struct suite *s;
999	struct test *t;
1000	int count = -1;
1001	struct name {
1002		struct list node;
1003		char *name;
1004	};
1005	struct name *n;
1006	struct list testnames;
1007	const char *data_path;
1008
1009	data_path = getenv("LIBINPUT_QUIRKS_DIR");
1010	if (!data_path)
1011		data_path = LIBINPUT_QUIRKS_DIR;
1012
1013	quirks_context = quirks_init_subsystem(data_path,
1014					       NULL,
1015					       quirk_log_handler,
1016					       NULL,
1017					       QLOG_LIBINPUT_LOGGING);
1018
1019	/* Check just takes the suite/test name pointers but doesn't strdup
1020	 * them - we have to keep them around */
1021	list_init(&testnames);
1022
1023	/* For each test, create one test suite with one test case, then
1024	   add it to the test runner. The only benefit suites give us in
1025	   check is that we can filter them, but our test runner has a
1026	   --filter-group anyway. */
1027	list_for_each(s, tests, node) {
1028		list_for_each(t, &s->tests, node) {
1029			Suite *suite;
1030			TCase *tc;
1031			char *sname, *tname;
1032
1033			/* We run deviceless tests as part of the normal
1034			 * test suite runner, just in case. Filtering
1035			 * all the other ones out just for the case where
1036			 * we can't run the full runner.
1037			 */
1038			if (run_deviceless && !t->deviceless)
1039				continue;
1040
1041			count = (count + 1) % max;
1042			if (max != 1 && (count % max) != which)
1043				continue;
1044
1045			xasprintf(&sname,
1046				  "%s:%s:%s",
1047				  s->name,
1048				  t->name,
1049				  t->devname);
1050			litest_assert_ptr_notnull(sname);
1051			n = zalloc(sizeof(*n));
1052			n->name = sname;
1053			list_insert(&testnames, &n->node);
1054
1055			xasprintf(&tname,
1056				  "%s:%s",
1057				  t->name,
1058				  t->devname);
1059			litest_assert_ptr_notnull(tname);
1060			n = zalloc(sizeof(*n));
1061			n->name = tname;
1062			list_insert(&testnames, &n->node);
1063
1064			tc = tcase_create(tname);
1065			tcase_add_checked_fixture(tc,
1066						  t->setup,
1067						  t->teardown);
1068			if (t->range.upper != t->range.lower)
1069				tcase_add_loop_test(tc,
1070						    t->func,
1071						    t->range.lower,
1072						    t->range.upper);
1073			else
1074				tcase_add_test(tc, t->func);
1075
1076			suite = suite_create(sname);
1077			suite_add_tcase(suite, tc);
1078
1079			if (!sr)
1080				sr = srunner_create(suite);
1081			else
1082				srunner_add_suite(sr, suite);
1083		}
1084	}
1085
1086	if (!sr)
1087		goto out;
1088
1089	srunner_run_all(sr, CK_ENV);
1090	if (xml_prefix)
1091		litest_export_xml(sr, xml_prefix);
1092
1093
1094	failed = srunner_ntests_failed(sr);
1095	if (failed) {
1096		TestResult **trs;
1097
1098		trs = srunner_failures(sr);
1099		for (int i = 0; i < failed; i++) {
1100			char tname[256];
1101			char *c = tname;
1102
1103			/* tr_tcname is in the form "suite:testcase", let's
1104			 * convert this to "suite(testcase)" to make
1105			 * double-click selection in the terminal a bit
1106			 * easier. */
1107			snprintf(tname, sizeof(tname), "%s)", tr_tcname(trs[i]));
1108			if ((c = index(c, ':')))
1109				*c = '(';
1110
1111			dprintf(error_fd,
1112				":: Failure: %s:%d: %s\n",
1113				tr_lfile(trs[i]),
1114				tr_lno(trs[i]),
1115				tname);
1116		}
1117		free(trs);
1118	}
1119	srunner_free(sr);
1120out:
1121	list_for_each_safe(n, &testnames, node) {
1122		free(n->name);
1123		free(n);
1124	}
1125
1126	quirks_context_unref(quirks_context);
1127
1128	return failed;
1129}
1130
1131static int
1132litest_fork_subtests(struct list *tests, int max_forks)
1133{
1134	int failed = 0;
1135	int status;
1136	pid_t pid;
1137	int f;
1138	int pipes[max_forks];
1139
1140	for (f = 0; f < max_forks; f++) {
1141		int rc;
1142		int pipefd[2];
1143
1144		rc = pipe2(pipefd, O_NONBLOCK);
1145		assert(rc != -1);
1146
1147		pid = fork();
1148		if (pid == 0) {
1149			close(pipefd[0]);
1150			failed = litest_run_suite(tests,
1151						  f,
1152						  max_forks,
1153						  pipefd[1]);
1154
1155			litest_free_test_list(&all_tests);
1156			exit(failed);
1157			/* child always exits here */
1158		} else {
1159			pipes[f] = pipefd[0];
1160			close(pipefd[1]);
1161		}
1162	}
1163
1164	/* parent process only */
1165	while (wait(&status) != -1 && errno != ECHILD) {
1166		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
1167			failed = 1;
1168	}
1169
1170	for (f = 0; f < max_forks; f++) {
1171		char buf[1024] = {0};
1172		int rc;
1173
1174		while ((rc = read(pipes[f], buf, sizeof(buf) - 1)) > 0) {
1175			buf[rc] = '\0';
1176			fprintf(stderr, "%s", buf);
1177		}
1178
1179		close(pipes[f]);
1180	}
1181
1182	return failed;
1183}
1184
1185static inline int
1186inhibit(void)
1187{
1188	int lock_fd = -1;
1189#if HAVE_LIBSYSTEMD
1190	sd_bus_error error = SD_BUS_ERROR_NULL;
1191	sd_bus_message *m = NULL;
1192	sd_bus *bus = NULL;
1193	int rc;
1194
1195	if (run_deviceless)
1196		return -1;
1197
1198	rc = sd_bus_open_system(&bus);
1199	if (rc != 0) {
1200		fprintf(stderr, "Warning: inhibit failed: %s\n", strerror(-rc));
1201		goto out;
1202	}
1203
1204	rc = sd_bus_call_method(bus,
1205				"org.freedesktop.login1",
1206				"/org/freedesktop/login1",
1207				"org.freedesktop.login1.Manager",
1208				"Inhibit",
1209				&error,
1210				&m,
1211				"ssss",
1212				"sleep:shutdown:handle-lid-switch:handle-power-key:handle-suspend-key:handle-hibernate-key",
1213				"libinput test-suite runner",
1214				"testing in progress",
1215				"block");
1216	if (rc < 0) {
1217		fprintf(stderr, "Warning: inhibit failed: %s\n", error.message);
1218		goto out;
1219	}
1220
1221	rc = sd_bus_message_read(m, "h", &lock_fd);
1222	if (rc < 0) {
1223		fprintf(stderr, "Warning: inhibit failed: %s\n", strerror(-rc));
1224		goto out;
1225	}
1226
1227	lock_fd = dup(lock_fd);
1228out:
1229	sd_bus_error_free(&error);
1230	sd_bus_message_unref(m);
1231	sd_bus_close(bus);
1232	sd_bus_unref(bus);
1233#endif
1234	return lock_fd;
1235}
1236
1237static inline int
1238litest_run(int argc, char **argv)
1239{
1240	int failed = 0;
1241	int inhibit_lock_fd;
1242
1243	list_init(&created_files_list);
1244
1245	if (list_empty(&all_tests)) {
1246		fprintf(stderr,
1247			"Error: filters are too strict, no tests to run.\n");
1248		return 1;
1249	}
1250
1251	if (getenv("LITEST_VERBOSE"))
1252		verbose = true;
1253
1254	if (run_deviceless) {
1255		litest_setup_quirks(&created_files_list,
1256				    QUIRKS_SETUP_USE_SRCDIR);
1257	} else {
1258		enum quirks_setup_mode mode;
1259		litest_init_udev_rules(&created_files_list);
1260
1261
1262		mode = use_system_rules_quirks ?
1263				QUIRKS_SETUP_ONLY_DEVICE :
1264				QUIRKS_SETUP_FULL;
1265		litest_setup_quirks(&created_files_list, mode);
1266	}
1267
1268	litest_setup_sighandler(SIGINT);
1269
1270	inhibit_lock_fd = inhibit();
1271
1272	if (jobs == 1)
1273		failed = litest_run_suite(&all_tests, 1, 1, STDERR_FILENO);
1274	else
1275		failed = litest_fork_subtests(&all_tests, jobs);
1276
1277	close(inhibit_lock_fd);
1278
1279	litest_free_test_list(&all_tests);
1280
1281	litest_remove_udev_rules(&created_files_list);
1282
1283	return failed;
1284}
1285
1286static struct input_absinfo *
1287merge_absinfo(const struct input_absinfo *orig,
1288	      const struct input_absinfo *override)
1289{
1290	struct input_absinfo *abs;
1291	unsigned int nelem, i;
1292	size_t sz = ABS_MAX + 1;
1293
1294	if (!orig)
1295		return NULL;
1296
1297	abs = zalloc(sz * sizeof(*abs));
1298	litest_assert_ptr_notnull(abs);
1299
1300	nelem = 0;
1301	while (orig[nelem].value != -1) {
1302		abs[nelem] = orig[nelem];
1303		nelem++;
1304		litest_assert_int_lt(nelem, sz);
1305	}
1306
1307	/* just append, if the same axis is present twice, libevdev will
1308	   only use the last value anyway */
1309	i = 0;
1310	while (override && override[i].value != -1) {
1311		abs[nelem++] = override[i++];
1312		litest_assert_int_lt(nelem, sz);
1313	}
1314
1315	litest_assert_int_lt(nelem, sz);
1316	abs[nelem].value = -1;
1317
1318	return abs;
1319}
1320
1321static int*
1322merge_events(const int *orig, const int *override)
1323{
1324	int *events;
1325	unsigned int nelem, i;
1326	size_t sz = KEY_MAX * 3;
1327
1328	if (!orig)
1329		return NULL;
1330
1331	events = zalloc(sz * sizeof(int));
1332	litest_assert_ptr_notnull(events);
1333
1334	nelem = 0;
1335	while (orig[nelem] != -1) {
1336		events[nelem] = orig[nelem];
1337		nelem++;
1338		litest_assert_int_lt(nelem, sz);
1339	}
1340
1341	/* just append, if the same axis is present twice, libevdev will
1342	 * ignore the double definition anyway */
1343	i = 0;
1344	while (override && override[i] != -1) {
1345		events[nelem++] = override[i++];
1346		litest_assert_int_le(nelem, sz);
1347	}
1348
1349	litest_assert_int_lt(nelem, sz);
1350	events[nelem] = -1;
1351
1352	return events;
1353}
1354
1355static inline struct created_file *
1356litest_copy_file(const char *dest, const char *src, const char *header, bool is_file)
1357{
1358	int in, out, length;
1359	struct created_file *file;
1360
1361	file = zalloc(sizeof(*file));
1362	file->path = safe_strdup(dest);
1363
1364	if (strstr(dest, "XXXXXX")) {
1365		int suffixlen;
1366
1367		suffixlen = file->path +
1368				strlen(file->path) -
1369				rindex(file->path, '.');
1370		out = mkstemps(file->path, suffixlen);
1371	} else {
1372		out = open(file->path, O_CREAT|O_WRONLY, 0644);
1373	}
1374	if (out == -1)
1375		litest_abort_msg("Failed to write to file %s (%s)\n",
1376				 file->path,
1377				 strerror(errno));
1378	litest_assert_int_ne(chmod(file->path, 0644), -1);
1379
1380	if (header) {
1381		length = strlen(header);
1382		litest_assert_int_eq(write(out, header, length), length);
1383	}
1384
1385	if (is_file) {
1386		in = open(src, O_RDONLY);
1387		if (in == -1)
1388			litest_abort_msg("Failed to open file %s (%s)\n",
1389					 src,
1390					 strerror(errno));
1391		/* lazy, just check for error and empty file copy */
1392		litest_assert_int_gt(litest_send_file(out, in), 0);
1393		close(in);
1394	} else {
1395		size_t written = write(out, src, strlen(src));
1396		litest_assert_int_eq(written, strlen(src));
1397
1398	}
1399	close(out);
1400
1401	return file;
1402}
1403
1404static inline void
1405litest_install_model_quirks(struct list *created_files_list)
1406{
1407	const char *warning =
1408			 "#################################################################\n"
1409			 "# WARNING: REMOVE THIS FILE\n"
1410			 "# This is a run-time file for the libinput test suite and\n"
1411			 "# should be removed on exit. If the test-suite is not currently \n"
1412			 "# running, remove this file\n"
1413			 "#################################################################\n\n";
1414	struct created_file *file;
1415	const char *test_device_udev_rule = "KERNELS==\"*input*\", "
1416					    "ATTRS{name}==\"litest *\", "
1417					    "ENV{LIBINPUT_TEST_DEVICE}=\"1\"";
1418
1419	file = litest_copy_file(UDEV_TEST_DEVICE_RULE_FILE,
1420				test_device_udev_rule,
1421				warning,
1422				false);
1423	list_insert(created_files_list, &file->link);
1424
1425	/* Only install the litest device rule when we're running as system
1426	 * test suite, we expect the others to be in place already */
1427	if (use_system_rules_quirks)
1428		return;
1429
1430	file = litest_copy_file(UDEV_DEVICE_GROUPS_FILE,
1431				LIBINPUT_DEVICE_GROUPS_RULES_FILE,
1432				warning,
1433				true);
1434	list_insert(created_files_list, &file->link);
1435
1436	file = litest_copy_file(UDEV_FUZZ_OVERRIDE_RULE_FILE,
1437				LIBINPUT_FUZZ_OVERRIDE_UDEV_RULES_FILE,
1438				warning,
1439				true);
1440	list_insert(created_files_list, &file->link);
1441}
1442
1443static char *
1444litest_init_device_quirk_file(const char *data_dir,
1445			      struct litest_test_device *dev)
1446{
1447	int fd;
1448	FILE *f;
1449	char path[PATH_MAX];
1450	static int count;
1451
1452	if (!dev->quirk_file)
1453		return NULL;
1454
1455	snprintf(path, sizeof(path),
1456		 "%s/99-%03d-%s.quirks",
1457		 data_dir,
1458		 ++count,
1459		 dev->shortname);
1460	fd = open(path, O_CREAT|O_WRONLY, 0644);
1461	litest_assert_int_ne(fd, -1);
1462	f = fdopen(fd, "w");
1463	litest_assert_notnull(f);
1464	litest_assert_int_ge(fputs(dev->quirk_file, f), 0);
1465	fclose(f);
1466
1467	return safe_strdup(path);
1468}
1469
1470static int is_quirks_file(const struct dirent *dir) {
1471	return strendswith(dir->d_name, ".quirks");
1472}
1473
1474/**
1475 * Install the quirks from the quirks/ source directory.
1476 */
1477static void
1478litest_install_source_quirks(struct list *created_files_list,
1479			     const char *dirname)
1480{
1481	struct dirent **namelist;
1482	int ndev;
1483
1484	ndev = scandir(LIBINPUT_QUIRKS_SRCDIR,
1485		       &namelist,
1486		       is_quirks_file,
1487		       versionsort);
1488	litest_assert_int_ge(ndev, 0);
1489
1490	for (int idx = 0; idx < ndev; idx++) {
1491		struct created_file *file;
1492		char *filename;
1493		char dest[PATH_MAX];
1494		char src[PATH_MAX];
1495
1496		filename = namelist[idx]->d_name;
1497		snprintf(src, sizeof(src), "%s/%s",
1498			 LIBINPUT_QUIRKS_SRCDIR, filename);
1499		snprintf(dest, sizeof(dest), "%s/%s", dirname, filename);
1500		file = litest_copy_file(dest, src, NULL, true);
1501		list_append(created_files_list, &file->link);
1502		free(namelist[idx]);
1503	}
1504	free(namelist);
1505}
1506
1507/**
1508 * Install the quirks from the various litest test devices
1509 */
1510static void
1511litest_install_device_quirks(struct list *created_files_list,
1512			     const char *dirname)
1513{
1514	struct litest_test_device *dev;
1515
1516	list_for_each(dev, &devices, node) {
1517		char *path;
1518
1519		path = litest_init_device_quirk_file(dirname, dev);
1520		if (path) {
1521			struct created_file *file = zalloc(sizeof(*file));
1522			file->path = path;
1523			list_insert(created_files_list, &file->link);
1524		}
1525	}
1526}
1527
1528static void
1529litest_setup_quirks(struct list *created_files_list,
1530		    enum quirks_setup_mode mode)
1531{
1532	struct created_file *file = NULL;
1533	const char *dirname;
1534	char tmpdir[] = "/run/litest-XXXXXX";
1535
1536	switch (mode) {
1537	case QUIRKS_SETUP_USE_SRCDIR:
1538		dirname = LIBINPUT_QUIRKS_SRCDIR;
1539		break;
1540	case QUIRKS_SETUP_ONLY_DEVICE:
1541		dirname = LIBINPUT_QUIRKS_DIR;
1542		litest_install_device_quirks(created_files_list, dirname);
1543		break;
1544	case QUIRKS_SETUP_FULL:
1545		litest_assert_notnull(mkdtemp(tmpdir));
1546		litest_assert_int_ne(chmod(tmpdir, 0755), -1);
1547		file = zalloc(sizeof *file);
1548		file->path = safe_strdup(tmpdir);
1549		dirname = tmpdir;
1550
1551		litest_install_source_quirks(created_files_list, dirname);
1552		litest_install_device_quirks(created_files_list, dirname);
1553		list_append(created_files_list, &file->link);
1554		break;
1555	}
1556
1557	setenv("LIBINPUT_QUIRKS_DIR", dirname, 1);
1558}
1559
1560static inline void
1561mkdir_p(const char *dir)
1562{
1563	char *path, *parent;
1564	int rc;
1565
1566	if (streq(dir, "/"))
1567		return;
1568
1569	path = safe_strdup(dir);
1570	parent = dirname(path);
1571
1572	mkdir_p(parent);
1573	rc = mkdir(dir, 0755);
1574
1575	if (rc == -1 && errno != EEXIST) {
1576		litest_abort_msg("Failed to create directory %s (%s)\n",
1577				 dir,
1578				 strerror(errno));
1579	}
1580
1581	free(path);
1582}
1583
1584static inline void
1585litest_init_udev_rules(struct list *created_files)
1586{
1587	mkdir_p(UDEV_RULES_D);
1588
1589	litest_install_model_quirks(created_files);
1590	litest_init_all_device_udev_rules(created_files);
1591	litest_reload_udev_rules();
1592}
1593
1594static inline void
1595litest_remove_udev_rules(struct list *created_files_list)
1596{
1597	struct created_file *f;
1598	bool reload_udev;
1599
1600	reload_udev = !list_empty(created_files_list);
1601
1602	list_for_each_safe(f, created_files_list, link) {
1603		list_remove(&f->link);
1604		unlink(f->path);
1605		rmdir(f->path);
1606		free(f->path);
1607		free(f);
1608	}
1609
1610	if (reload_udev)
1611		litest_reload_udev_rules();
1612}
1613
1614/**
1615 * Creates a uinput device but does not add it to a libinput context
1616 */
1617struct litest_device *
1618litest_create(enum litest_device_type which,
1619	      const char *name_override,
1620	      struct input_id *id_override,
1621	      const struct input_absinfo *abs_override,
1622	      const int *events_override)
1623{
1624	struct litest_device *d = NULL;
1625	struct litest_test_device *dev;
1626	const char *name;
1627	const struct input_id *id;
1628	struct input_absinfo *abs;
1629	int *events, *e;
1630	const char *path;
1631	int fd, rc;
1632	bool found = false;
1633	bool create_device = true;
1634
1635	list_for_each(dev, &devices, node) {
1636		if (dev->type == which) {
1637			found = true;
1638			break;
1639		}
1640	}
1641
1642	if (!found)
1643		ck_abort_msg("Invalid device type %d\n", which);
1644
1645	d = zalloc(sizeof(*d));
1646	d->which = which;
1647
1648	/* device has custom create method */
1649	if (dev->create) {
1650		create_device = dev->create(d);
1651		if (abs_override || events_override) {
1652			litest_abort_msg("Custom create cannot be overridden");
1653		}
1654	}
1655
1656	abs = merge_absinfo(dev->absinfo, abs_override);
1657	events = merge_events(dev->events, events_override);
1658	name = name_override ? name_override : dev->name;
1659	id = id_override ? id_override : dev->id;
1660
1661	if (create_device) {
1662		d->uinput = litest_create_uinput_device_from_description(name,
1663									 id,
1664									 abs,
1665									 events);
1666		d->interface = dev->interface;
1667
1668		for (e = events; *e != -1; e += 2) {
1669			unsigned int type = *e,
1670				     code = *(e + 1);
1671
1672			if (type == INPUT_PROP_MAX &&
1673			    code == INPUT_PROP_SEMI_MT) {
1674				d->semi_mt.is_semi_mt = true;
1675				break;
1676			}
1677		}
1678	}
1679
1680	free(abs);
1681	free(events);
1682
1683	path = libevdev_uinput_get_devnode(d->uinput);
1684	litest_assert_ptr_notnull(path);
1685	fd = open(path, O_RDWR|O_NONBLOCK);
1686	litest_assert_int_ne(fd, -1);
1687
1688	rc = libevdev_new_from_fd(fd, &d->evdev);
1689	litest_assert_int_eq(rc, 0);
1690
1691	return d;
1692
1693}
1694
1695struct libinput *
1696litest_create_context(void)
1697{
1698	struct libinput *libinput;
1699	struct litest_context *ctx;
1700
1701	ctx = zalloc(sizeof *ctx);
1702	list_init(&ctx->paths);
1703
1704	libinput = libinput_path_create_context(&interface, ctx);
1705	litest_assert_notnull(libinput);
1706
1707	libinput_log_set_handler(libinput, litest_log_handler);
1708	if (verbose)
1709		libinput_log_set_priority(libinput, LIBINPUT_LOG_PRIORITY_DEBUG);
1710
1711	return libinput;
1712}
1713
1714void
1715litest_destroy_context(struct libinput *li)
1716{
1717	struct path *p;
1718	struct litest_context *ctx;
1719
1720
1721	ctx = libinput_get_user_data(li);
1722	litest_assert_ptr_notnull(ctx);
1723	libinput_unref(li);
1724
1725	list_for_each_safe(p, &ctx->paths, link) {
1726		litest_abort_msg("Device paths should be removed by now");
1727	}
1728	free(ctx);
1729}
1730
1731void
1732litest_disable_log_handler(struct libinput *libinput)
1733{
1734	libinput_log_set_handler(libinput, NULL);
1735}
1736
1737void
1738litest_restore_log_handler(struct libinput *libinput)
1739{
1740	libinput_log_set_handler(libinput, litest_log_handler);
1741	if (verbose)
1742		libinput_log_set_priority(libinput, LIBINPUT_LOG_PRIORITY_DEBUG);
1743}
1744
1745LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
1746static void
1747litest_bug_log_handler(struct libinput *libinput,
1748		       enum libinput_log_priority pri,
1749		       const char *format,
1750		       va_list args)
1751{
1752	if (strstr(format, "client bug: ") ||
1753	    strstr(format, "libinput bug: ") ||
1754	    strstr(format, "kernel bug: "))
1755		return;
1756
1757	litest_abort_msg("Expected bug statement in log msg, aborting.\n");
1758}
1759
1760void
1761litest_set_log_handler_bug(struct libinput *libinput)
1762{
1763	libinput_log_set_handler(libinput, litest_bug_log_handler);
1764}
1765
1766struct litest_device *
1767litest_add_device_with_overrides(struct libinput *libinput,
1768				 enum litest_device_type which,
1769				 const char *name_override,
1770				 struct input_id *id_override,
1771				 const struct input_absinfo *abs_override,
1772				 const int *events_override)
1773{
1774	struct udev_device *ud;
1775	struct litest_device *d;
1776	const char *path;
1777
1778	d = litest_create(which,
1779			  name_override,
1780			  id_override,
1781			  abs_override,
1782			  events_override);
1783
1784	path = libevdev_uinput_get_devnode(d->uinput);
1785	litest_assert_ptr_notnull(path);
1786
1787	d->libinput = libinput;
1788	d->libinput_device = libinput_path_add_device(d->libinput, path);
1789	litest_assert_ptr_notnull(d->libinput_device);
1790	ud = libinput_device_get_udev_device(d->libinput_device);
1791	d->quirks = quirks_fetch_for_device(quirks_context, ud);
1792	udev_device_unref(ud);
1793
1794	libinput_device_ref(d->libinput_device);
1795
1796	if (d->interface) {
1797		unsigned int code;
1798
1799		code = ABS_X;
1800		if (!libevdev_has_event_code(d->evdev, EV_ABS, code))
1801			code = ABS_MT_POSITION_X;
1802		if (libevdev_has_event_code(d->evdev, EV_ABS, code)) {
1803			d->interface->min[ABS_X] = libevdev_get_abs_minimum(d->evdev, code);
1804			d->interface->max[ABS_X] = libevdev_get_abs_maximum(d->evdev, code);
1805		}
1806
1807		code = ABS_Y;
1808		if (!libevdev_has_event_code(d->evdev, EV_ABS, code))
1809			code = ABS_MT_POSITION_Y;
1810		if (libevdev_has_event_code(d->evdev, EV_ABS, code)) {
1811			d->interface->min[ABS_Y] = libevdev_get_abs_minimum(d->evdev, code);
1812			d->interface->max[ABS_Y] = libevdev_get_abs_maximum(d->evdev, code);
1813		}
1814		d->interface->tool_type = BTN_TOOL_PEN;
1815	}
1816	return d;
1817}
1818
1819struct litest_device *
1820litest_add_device(struct libinput *libinput,
1821		  enum litest_device_type which)
1822{
1823	return litest_add_device_with_overrides(libinput,
1824						which,
1825						NULL,
1826						NULL,
1827						NULL,
1828						NULL);
1829}
1830
1831struct litest_device *
1832litest_create_device_with_overrides(enum litest_device_type which,
1833				    const char *name_override,
1834				    struct input_id *id_override,
1835				    const struct input_absinfo *abs_override,
1836				    const int *events_override)
1837{
1838	struct litest_device *dev =
1839		litest_add_device_with_overrides(litest_create_context(),
1840						 which,
1841						 name_override,
1842						 id_override,
1843						 abs_override,
1844						 events_override);
1845	dev->owns_context = true;
1846	return dev;
1847}
1848
1849struct litest_device *
1850litest_create_device(enum litest_device_type which)
1851{
1852	return litest_create_device_with_overrides(which, NULL, NULL, NULL, NULL);
1853}
1854
1855static struct udev_monitor *
1856udev_setup_monitor(void)
1857{
1858	struct udev *udev;
1859	struct udev_monitor *udev_monitor;
1860	int rc;
1861
1862	udev = udev_new();
1863	litest_assert_notnull(udev);
1864	udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
1865	litest_assert_notnull(udev_monitor);
1866	udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input",
1867							NULL);
1868
1869
1870	/* remove O_NONBLOCK */
1871	rc = fcntl(udev_monitor_get_fd(udev_monitor), F_SETFL, 0);
1872	litest_assert_int_ne(rc, -1);
1873	litest_assert_int_eq(udev_monitor_enable_receiving(udev_monitor),
1874			     0);
1875	udev_unref(udev);
1876
1877	return udev_monitor;
1878}
1879
1880static struct udev_device *
1881udev_wait_for_device_event(struct udev_monitor *udev_monitor,
1882			   const char *udev_event,
1883			   const char *syspath)
1884{
1885	struct udev_device *udev_device = NULL;
1886
1887	/* blocking, we don't want to continue until udev is ready */
1888	while (1) {
1889		const char *udev_syspath = NULL;
1890		const char *udev_action;
1891
1892		udev_device = udev_monitor_receive_device(udev_monitor);
1893		litest_assert_notnull(udev_device);
1894		udev_action = udev_device_get_action(udev_device);
1895		if (!udev_action || !streq(udev_action, udev_event)) {
1896			udev_device_unref(udev_device);
1897			continue;
1898		}
1899
1900		udev_syspath = udev_device_get_syspath(udev_device);
1901		if (udev_syspath && strstartswith(udev_syspath, syspath))
1902			break;
1903
1904		udev_device_unref(udev_device);
1905	}
1906
1907	return udev_device;
1908}
1909
1910void
1911litest_delete_device(struct litest_device *d)
1912{
1913
1914	struct udev_monitor *udev_monitor;
1915	struct udev_device *udev_device;
1916	char path[PATH_MAX];
1917
1918	if (!d)
1919		return;
1920
1921	udev_monitor = udev_setup_monitor();
1922	snprintf(path, sizeof(path),
1923		 "%s/event",
1924		 libevdev_uinput_get_syspath(d->uinput));
1925
1926	litest_assert_int_eq(d->skip_ev_syn, 0);
1927
1928	quirks_unref(d->quirks);
1929
1930	if (d->libinput_device) {
1931		libinput_path_remove_device(d->libinput_device);
1932		libinput_device_unref(d->libinput_device);
1933	}
1934	if (d->owns_context) {
1935		libinput_dispatch(d->libinput);
1936		litest_destroy_context(d->libinput);
1937	}
1938	close(libevdev_get_fd(d->evdev));
1939	libevdev_free(d->evdev);
1940	libevdev_uinput_destroy(d->uinput);
1941	free(d->private);
1942	memset(d,0, sizeof(*d));
1943	free(d);
1944
1945	udev_device = udev_wait_for_device_event(udev_monitor,
1946						 "remove",
1947						 path);
1948	udev_device_unref(udev_device);
1949	udev_monitor_unref(udev_monitor);
1950}
1951
1952void
1953litest_event(struct litest_device *d, unsigned int type,
1954	     unsigned int code, int value)
1955{
1956	int ret;
1957
1958	if (!libevdev_has_event_code(d->evdev, type, code))
1959		return;
1960
1961	if (d->skip_ev_syn && type == EV_SYN && code == SYN_REPORT)
1962		return;
1963
1964	ret = libevdev_uinput_write_event(d->uinput, type, code, value);
1965	litest_assert_int_eq(ret, 0);
1966}
1967
1968static bool
1969axis_replacement_value(struct litest_device *d,
1970		       struct axis_replacement *axes,
1971		       int32_t evcode,
1972		       int32_t *value)
1973{
1974	struct axis_replacement *axis = axes;
1975
1976	if (!axes)
1977		return false;
1978
1979	while (axis->evcode != -1) {
1980		if (axis->evcode == evcode) {
1981			switch (evcode) {
1982			case ABS_MT_SLOT:
1983			case ABS_MT_TRACKING_ID:
1984			case ABS_MT_TOOL_TYPE:
1985				*value = axis->value;
1986				break;
1987			default:
1988				*value = litest_scale(d, evcode, axis->value);
1989				break;
1990			}
1991			return true;
1992		}
1993		axis++;
1994	}
1995
1996	return false;
1997}
1998
1999int
2000litest_auto_assign_value(struct litest_device *d,
2001			 const struct input_event *ev,
2002			 int slot, double x, double y,
2003			 struct axis_replacement *axes,
2004			 bool touching)
2005{
2006	static int tracking_id;
2007	int value = ev->value;
2008
2009	if (value != LITEST_AUTO_ASSIGN || ev->type != EV_ABS)
2010		return value;
2011
2012	switch (ev->code) {
2013	case ABS_X:
2014	case ABS_MT_POSITION_X:
2015		value = litest_scale(d, ABS_X, x);
2016		break;
2017	case ABS_Y:
2018	case ABS_MT_POSITION_Y:
2019		value = litest_scale(d, ABS_Y, y);
2020		break;
2021	case ABS_MT_TRACKING_ID:
2022		value = ++tracking_id;
2023		break;
2024	case ABS_MT_SLOT:
2025		value = slot;
2026		break;
2027	case ABS_MT_DISTANCE:
2028		value = touching ? 0 : 1;
2029		break;
2030	case ABS_MT_TOOL_TYPE:
2031		if (!axis_replacement_value(d, axes, ev->code, &value))
2032			value = MT_TOOL_FINGER;
2033		break;
2034	default:
2035		if (!axis_replacement_value(d, axes, ev->code, &value) &&
2036		    d->interface->get_axis_default) {
2037			int error = d->interface->get_axis_default(d,
2038								   ev->code,
2039								   &value);
2040			if (error) {
2041				litest_abort_msg("Failed to get default axis value for %s (%d)\n",
2042						 libevdev_event_code_get_name(EV_ABS, ev->code),
2043						 ev->code);
2044			}
2045		}
2046		break;
2047	}
2048
2049	return value;
2050}
2051
2052static void
2053send_btntool(struct litest_device *d, bool hover)
2054{
2055	litest_event(d, EV_KEY, BTN_TOUCH, d->ntouches_down != 0 && !hover);
2056	litest_event(d, EV_KEY, BTN_TOOL_FINGER, d->ntouches_down == 1);
2057	litest_event(d, EV_KEY, BTN_TOOL_DOUBLETAP, d->ntouches_down == 2);
2058	litest_event(d, EV_KEY, BTN_TOOL_TRIPLETAP, d->ntouches_down == 3);
2059	litest_event(d, EV_KEY, BTN_TOOL_QUADTAP, d->ntouches_down == 4);
2060	litest_event(d, EV_KEY, BTN_TOOL_QUINTTAP, d->ntouches_down == 5);
2061}
2062
2063static void
2064slot_start(struct litest_device *d,
2065	   unsigned int slot,
2066	   double x,
2067	   double y,
2068	   struct axis_replacement *axes,
2069	   bool touching,
2070	   bool filter_abs_xy)
2071{
2072	struct input_event *ev;
2073
2074	litest_assert_int_ge(d->ntouches_down, 0);
2075	d->ntouches_down++;
2076
2077	send_btntool(d, !touching);
2078
2079	/* If the test device overrides touch_down and says it didn't
2080	 * handle the event, let's continue normally */
2081	if (d->interface->touch_down &&
2082	    d->interface->touch_down(d, slot, x, y))
2083	    return;
2084
2085	for (ev = d->interface->touch_down_events;
2086	     ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1;
2087	     ev++) {
2088		int value = litest_auto_assign_value(d,
2089						     ev,
2090						     slot,
2091						     x,
2092						     y,
2093						     axes,
2094						     touching);
2095		if (value == LITEST_AUTO_ASSIGN)
2096			continue;
2097
2098		if (filter_abs_xy && ev->type == EV_ABS &&
2099		    (ev->code == ABS_X || ev->code == ABS_Y))
2100			continue;
2101
2102		litest_event(d, ev->type, ev->code, value);
2103	}
2104}
2105
2106static void
2107slot_move(struct litest_device *d,
2108	  unsigned int slot,
2109	  double x,
2110	  double y,
2111	  struct axis_replacement *axes,
2112	  bool touching,
2113	  bool filter_abs_xy)
2114{
2115	struct input_event *ev;
2116
2117	if (d->interface->touch_move &&
2118	    d->interface->touch_move(d, slot, x, y))
2119		return;
2120
2121	for (ev = d->interface->touch_move_events;
2122	     ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1;
2123	     ev++) {
2124		int value = litest_auto_assign_value(d,
2125						     ev,
2126						     slot,
2127						     x,
2128						     y,
2129						     axes,
2130						     touching);
2131		if (value == LITEST_AUTO_ASSIGN)
2132			continue;
2133
2134		if (filter_abs_xy && ev->type == EV_ABS &&
2135		    (ev->code == ABS_X || ev->code == ABS_Y))
2136			continue;
2137
2138		litest_event(d, ev->type, ev->code, value);
2139	}
2140}
2141
2142static void
2143touch_up(struct litest_device *d, unsigned int slot)
2144{
2145	struct input_event *ev;
2146	struct input_event up[] = {
2147		{ .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
2148		{ .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
2149		{ .type = EV_ABS, .code = ABS_MT_PRESSURE, .value = 0 },
2150		{ .type = EV_ABS, .code = ABS_MT_TOUCH_MAJOR, .value = 0 },
2151		{ .type = EV_ABS, .code = ABS_MT_TOUCH_MINOR, .value = 0 },
2152		{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
2153		{ .type = -1, .code = -1 }
2154	};
2155
2156	litest_assert_int_gt(d->ntouches_down, 0);
2157	d->ntouches_down--;
2158
2159	send_btntool(d, false);
2160
2161	if (d->interface->touch_up &&
2162	    d->interface->touch_up(d, slot)) {
2163		return;
2164	} else if (d->interface->touch_up_events) {
2165		ev = d->interface->touch_up_events;
2166	} else
2167		ev = up;
2168
2169	for ( /* */;
2170	     ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1;
2171	     ev++) {
2172		int value = litest_auto_assign_value(d,
2173						     ev,
2174						     slot,
2175						     0,
2176						     0,
2177						     NULL,
2178						     false);
2179		litest_event(d, ev->type, ev->code, value);
2180	}
2181}
2182
2183static void
2184litest_slot_start(struct litest_device *d,
2185		  unsigned int slot,
2186		  double x,
2187		  double y,
2188		  struct axis_replacement *axes,
2189		  bool touching)
2190{
2191	double t, l, r = 0, b = 0; /* top, left, right, bottom */
2192	bool filter_abs_xy = false;
2193
2194	if (!d->semi_mt.is_semi_mt) {
2195		slot_start(d, slot, x, y, axes, touching, filter_abs_xy);
2196		return;
2197	}
2198
2199	if (d->ntouches_down >= 2 || slot > 1)
2200		return;
2201
2202	slot = d->ntouches_down;
2203
2204	if (d->ntouches_down == 0) {
2205		l = x;
2206		t = y;
2207	} else {
2208		int other = (slot + 1) % 2;
2209		l = min(x, d->semi_mt.touches[other].x);
2210		t = min(y, d->semi_mt.touches[other].y);
2211		r = max(x, d->semi_mt.touches[other].x);
2212		b = max(y, d->semi_mt.touches[other].y);
2213	}
2214
2215	litest_push_event_frame(d);
2216	if (d->ntouches_down == 0)
2217		slot_start(d, 0, l, t, axes, touching, filter_abs_xy);
2218	else
2219		slot_move(d, 0, l, t, axes, touching, filter_abs_xy);
2220
2221	if (slot == 1) {
2222		filter_abs_xy = true;
2223		slot_start(d, 1, r, b, axes, touching, filter_abs_xy);
2224	}
2225
2226	litest_pop_event_frame(d);
2227
2228	d->semi_mt.touches[slot].x = x;
2229	d->semi_mt.touches[slot].y = y;
2230}
2231
2232void
2233litest_touch_sequence(struct litest_device *d,
2234		      unsigned int slot,
2235		      double x_from,
2236		      double y_from,
2237		      double x_to,
2238		      double y_to,
2239		      int steps)
2240{
2241	litest_touch_down(d, slot, x_from, y_from);
2242	litest_touch_move_to(d, slot,
2243			     x_from, y_from,
2244			     x_to, y_to,
2245			     steps);
2246	litest_touch_up(d, slot);
2247}
2248
2249void
2250litest_touch_down(struct litest_device *d,
2251		  unsigned int slot,
2252		  double x,
2253		  double y)
2254{
2255	litest_slot_start(d, slot, x, y, NULL, true);
2256}
2257
2258void
2259litest_touch_down_extended(struct litest_device *d,
2260			   unsigned int slot,
2261			   double x,
2262			   double y,
2263			   struct axis_replacement *axes)
2264{
2265	litest_slot_start(d, slot, x, y, axes, true);
2266}
2267
2268static void
2269litest_slot_move(struct litest_device *d,
2270		 unsigned int slot,
2271		 double x,
2272		 double y,
2273		 struct axis_replacement *axes,
2274		 bool touching)
2275{
2276	double t, l, r = 0, b = 0; /* top, left, right, bottom */
2277	bool filter_abs_xy = false;
2278
2279	if (!d->semi_mt.is_semi_mt) {
2280		slot_move(d, slot, x, y, axes, touching, filter_abs_xy);
2281		return;
2282	}
2283
2284	if (d->ntouches_down > 2 || slot > 1)
2285		return;
2286
2287	if (d->ntouches_down == 1) {
2288		l = x;
2289		t = y;
2290	} else {
2291		int other = (slot + 1) % 2;
2292		l = min(x, d->semi_mt.touches[other].x);
2293		t = min(y, d->semi_mt.touches[other].y);
2294		r = max(x, d->semi_mt.touches[other].x);
2295		b = max(y, d->semi_mt.touches[other].y);
2296	}
2297
2298	litest_push_event_frame(d);
2299	slot_move(d, 0, l, t, axes, touching, filter_abs_xy);
2300
2301	if (d->ntouches_down == 2) {
2302		filter_abs_xy = true;
2303		slot_move(d, 1, r, b, axes, touching, filter_abs_xy);
2304	}
2305
2306	litest_pop_event_frame(d);
2307
2308	d->semi_mt.touches[slot].x = x;
2309	d->semi_mt.touches[slot].y = y;
2310}
2311
2312void
2313litest_touch_up(struct litest_device *d, unsigned int slot)
2314{
2315	if (!d->semi_mt.is_semi_mt) {
2316		touch_up(d, slot);
2317		return;
2318	}
2319
2320	if (d->ntouches_down > 2 || slot > 1)
2321		return;
2322
2323	litest_push_event_frame(d);
2324	touch_up(d, d->ntouches_down - 1);
2325
2326	/* if we have one finger left, send x/y coords for that finger left.
2327	   this is likely to happen with a real touchpad */
2328	if (d->ntouches_down == 1) {
2329		bool touching = true;
2330		bool filter_abs_xy = false;
2331
2332		int other = (slot + 1) % 2;
2333		slot_move(d,
2334			  0,
2335			  d->semi_mt.touches[other].x,
2336			  d->semi_mt.touches[other].y,
2337			  NULL,
2338			  touching,
2339			  filter_abs_xy);
2340	}
2341
2342	litest_pop_event_frame(d);
2343}
2344
2345void
2346litest_touch_move(struct litest_device *d,
2347		  unsigned int slot,
2348		  double x,
2349		  double y)
2350{
2351	litest_slot_move(d, slot, x, y, NULL, true);
2352}
2353
2354void
2355litest_touch_move_extended(struct litest_device *d,
2356			   unsigned int slot,
2357			   double x,
2358			   double y,
2359			   struct axis_replacement *axes)
2360{
2361	litest_slot_move(d, slot, x, y, axes, true);
2362}
2363
2364void
2365litest_touch_move_to(struct litest_device *d,
2366		     unsigned int slot,
2367		     double x_from, double y_from,
2368		     double x_to, double y_to,
2369		     int steps)
2370{
2371	litest_touch_move_to_extended(d, slot,
2372				      x_from, y_from,
2373				      x_to, y_to,
2374				      NULL,
2375				      steps);
2376}
2377
2378void
2379litest_touch_move_to_extended(struct litest_device *d,
2380			      unsigned int slot,
2381			      double x_from, double y_from,
2382			      double x_to, double y_to,
2383			      struct axis_replacement *axes,
2384			      int steps)
2385{
2386	int sleep_ms = 10;
2387
2388	for (int i = 1; i < steps; i++) {
2389		litest_touch_move_extended(d, slot,
2390					   x_from + (x_to - x_from)/steps * i,
2391					   y_from + (y_to - y_from)/steps * i,
2392					   axes);
2393		libinput_dispatch(d->libinput);
2394		msleep(sleep_ms);
2395		libinput_dispatch(d->libinput);
2396	}
2397	litest_touch_move_extended(d, slot, x_to, y_to, axes);
2398}
2399
2400static int
2401auto_assign_tablet_value(struct litest_device *d,
2402			 const struct input_event *ev,
2403			 int x, int y,
2404			 struct axis_replacement *axes)
2405{
2406	static int tracking_id;
2407	int value = ev->value;
2408
2409	if (value != LITEST_AUTO_ASSIGN || ev->type != EV_ABS)
2410		return value;
2411
2412	switch (ev->code) {
2413	case ABS_MT_TRACKING_ID:
2414		value = ++tracking_id;
2415		break;
2416	case ABS_X:
2417	case ABS_MT_POSITION_X:
2418		value = litest_scale(d, ABS_X, x);
2419		break;
2420	case ABS_Y:
2421	case ABS_MT_POSITION_Y:
2422		value = litest_scale(d, ABS_Y, y);
2423		break;
2424	default:
2425		if (!axis_replacement_value(d, axes, ev->code, &value) &&
2426		    d->interface->get_axis_default) {
2427			int error = d->interface->get_axis_default(d, ev->code, &value);
2428			if (error) {
2429				litest_abort_msg("Failed to get default axis value for %s (%d)\n",
2430						 libevdev_event_code_get_name(EV_ABS, ev->code),
2431						 ev->code);
2432			}
2433		}
2434		break;
2435	}
2436
2437	return value;
2438}
2439
2440static int
2441tablet_ignore_event(const struct input_event *ev, int value)
2442{
2443	return value == -1 && (ev->code == ABS_PRESSURE || ev->code == ABS_DISTANCE);
2444}
2445
2446void
2447litest_tablet_set_tool_type(struct litest_device *d, unsigned int code)
2448{
2449	switch (code) {
2450	case BTN_TOOL_PEN:
2451	case BTN_TOOL_RUBBER:
2452	case BTN_TOOL_BRUSH:
2453	case BTN_TOOL_PENCIL:
2454	case BTN_TOOL_AIRBRUSH:
2455	case BTN_TOOL_MOUSE:
2456	case BTN_TOOL_LENS:
2457		break;
2458	default:
2459		abort();
2460	}
2461
2462	d->interface->tool_type = code;
2463}
2464
2465static void
2466litest_tool_event(struct litest_device *d, int value)
2467{
2468	unsigned int tool = d->interface->tool_type;
2469
2470	litest_event(d, EV_KEY, tool, value);
2471}
2472
2473void
2474litest_tablet_proximity_in(struct litest_device *d,
2475			   double x, double y,
2476			   struct axis_replacement *axes)
2477{
2478	struct input_event *ev;
2479
2480	/* If the test device overrides proximity_in and says it didn't
2481	 * handle the event, let's continue normally */
2482	if (d->interface->tablet_proximity_in &&
2483	    d->interface->tablet_proximity_in(d, d->interface->tool_type, &x, &y, axes))
2484		return;
2485
2486	ev = d->interface->tablet_proximity_in_events;
2487	while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
2488		int value;
2489
2490		switch (evbit(ev->type, ev->code)) {
2491		case evbit(EV_KEY, LITEST_BTN_TOOL_AUTO):
2492			litest_tool_event(d, ev->value);
2493			break;
2494		default:
2495			value = auto_assign_tablet_value(d, ev, x, y, axes);
2496			if (!tablet_ignore_event(ev, value))
2497				litest_event(d, ev->type, ev->code, value);
2498		}
2499		ev++;
2500	}
2501}
2502
2503void
2504litest_tablet_proximity_out(struct litest_device *d)
2505{
2506	struct input_event *ev;
2507
2508	/* If the test device overrides proximity_out and says it didn't
2509	 * handle the event, let's continue normally */
2510	if (d->interface->tablet_proximity_out &&
2511	    d->interface->tablet_proximity_out(d, d->interface->tool_type))
2512		return;
2513
2514	ev = d->interface->tablet_proximity_out_events;
2515	while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
2516		int value;
2517
2518		switch (evbit(ev->type, ev->code)) {
2519		case evbit(EV_KEY, LITEST_BTN_TOOL_AUTO):
2520			litest_tool_event(d, ev->value);
2521			break;
2522		default:
2523			value = auto_assign_tablet_value(d, ev, -1, -1, NULL);
2524			if (!tablet_ignore_event(ev, value))
2525				litest_event(d, ev->type, ev->code, value);
2526			break;
2527		}
2528		ev++;
2529	}
2530}
2531
2532void
2533litest_tablet_motion(struct litest_device *d,
2534		     double x, double y,
2535		     struct axis_replacement *axes)
2536{
2537	struct input_event *ev;
2538
2539	/* If the test device overrides proximity_out and says it didn't
2540	 * handle the event, let's continue normally */
2541	if (d->interface->tablet_motion &&
2542	    d->interface->tablet_motion(d, &x, &y, axes))
2543		return;
2544
2545	ev = d->interface->tablet_motion_events;
2546	while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
2547		int value = auto_assign_tablet_value(d, ev, x, y, axes);
2548		if (!tablet_ignore_event(ev, value))
2549			litest_event(d, ev->type, ev->code, value);
2550		ev++;
2551	}
2552}
2553
2554void
2555litest_tablet_tip_down(struct litest_device *d,
2556		       double x, double y,
2557		       struct axis_replacement *axes)
2558{
2559	/* If the test device overrides tip_down and says it didn't
2560	 * handle the event, let's continue normally */
2561	if (d->interface->tablet_tip_down &&
2562	    d->interface->tablet_tip_down(d, &x, &y, axes))
2563		return;
2564
2565	litest_event(d, EV_KEY, BTN_TOUCH, 1);
2566	litest_tablet_motion(d, x, y, axes);
2567}
2568
2569void
2570litest_tablet_tip_up(struct litest_device *d,
2571		     double x, double y,
2572		     struct axis_replacement *axes)
2573{
2574	/* If the test device overrides tip_down and says it didn't
2575	 * handle the event, let's continue normally */
2576	if (d->interface->tablet_tip_up &&
2577	    d->interface->tablet_tip_up(d, &x, &y, axes))
2578		return;
2579
2580	litest_event(d, EV_KEY, BTN_TOUCH, 0);
2581	litest_tablet_motion(d, x, y, axes);
2582}
2583
2584void
2585litest_touch_move_two_touches(struct litest_device *d,
2586			      double x0, double y0,
2587			      double x1, double y1,
2588			      double dx, double dy,
2589			      int steps)
2590{
2591	int sleep_ms = 10;
2592
2593	for (int i = 1; i < steps; i++) {
2594		litest_push_event_frame(d);
2595		litest_touch_move(d, 0, x0 + dx / steps * i,
2596					y0 + dy / steps * i);
2597		litest_touch_move(d, 1, x1 + dx / steps * i,
2598					y1 + dy / steps * i);
2599		litest_pop_event_frame(d);
2600		libinput_dispatch(d->libinput);
2601		msleep(sleep_ms);
2602		libinput_dispatch(d->libinput);
2603	}
2604	litest_push_event_frame(d);
2605	litest_touch_move(d, 0, x0 + dx, y0 + dy);
2606	litest_touch_move(d, 1, x1 + dx, y1 + dy);
2607	litest_pop_event_frame(d);
2608}
2609
2610void
2611litest_touch_move_three_touches(struct litest_device *d,
2612				double x0, double y0,
2613				double x1, double y1,
2614				double x2, double y2,
2615				double dx, double dy,
2616				int steps)
2617{
2618	int sleep_ms = 10;
2619
2620	for (int i = 1; i <= steps; i++) {
2621		double step_x = dx / steps * i;
2622		double step_y = dy / steps * i;
2623
2624		litest_push_event_frame(d);
2625		litest_touch_move(d, 0, x0 + step_x, y0 + step_y);
2626		litest_touch_move(d, 1, x1 + step_x, y1 + step_y);
2627		litest_touch_move(d, 2, x2 + step_x, y2 + step_y);
2628		litest_pop_event_frame(d);
2629
2630		libinput_dispatch(d->libinput);
2631		msleep(sleep_ms);
2632	}
2633	libinput_dispatch(d->libinput);
2634}
2635
2636void
2637litest_hover_start(struct litest_device *d,
2638		   unsigned int slot,
2639		   double x,
2640		   double y)
2641{
2642	struct axis_replacement axes[] = {
2643		{ABS_MT_PRESSURE, 0 },
2644		{ABS_PRESSURE, 0 },
2645		{-1, -1 },
2646	};
2647
2648	litest_slot_start(d, slot, x, y, axes, 0);
2649}
2650
2651void
2652litest_hover_end(struct litest_device *d, unsigned int slot)
2653{
2654	struct input_event *ev;
2655	struct input_event up[] = {
2656		{ .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
2657		{ .type = EV_ABS, .code = ABS_MT_DISTANCE, .value = 1 },
2658		{ .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
2659		{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
2660		{ .type = -1, .code = -1 }
2661	};
2662
2663	litest_assert_int_gt(d->ntouches_down, 0);
2664	d->ntouches_down--;
2665
2666	send_btntool(d, true);
2667
2668	if (d->interface->touch_up) {
2669		d->interface->touch_up(d, slot);
2670		return;
2671	} else if (d->interface->touch_up_events) {
2672		ev = d->interface->touch_up_events;
2673	} else
2674		ev = up;
2675
2676	while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
2677		int value = litest_auto_assign_value(d, ev, slot, 0, 0, NULL, false);
2678		litest_event(d, ev->type, ev->code, value);
2679		ev++;
2680	}
2681}
2682
2683void
2684litest_hover_move(struct litest_device *d, unsigned int slot,
2685		  double x, double y)
2686{
2687	struct axis_replacement axes[] = {
2688		{ABS_MT_PRESSURE, 0 },
2689		{ABS_PRESSURE, 0 },
2690		{-1, -1 },
2691	};
2692
2693	litest_slot_move(d, slot, x, y, axes, false);
2694}
2695
2696void
2697litest_hover_move_to(struct litest_device *d,
2698		     unsigned int slot,
2699		     double x_from, double y_from,
2700		     double x_to, double y_to,
2701		     int steps)
2702{
2703	int sleep_ms = 10;
2704
2705	for (int i = 0; i < steps - 1; i++) {
2706		litest_hover_move(d, slot,
2707				  x_from + (x_to - x_from)/steps * i,
2708				  y_from + (y_to - y_from)/steps * i);
2709		libinput_dispatch(d->libinput);
2710		msleep(sleep_ms);
2711		libinput_dispatch(d->libinput);
2712	}
2713	litest_hover_move(d, slot, x_to, y_to);
2714}
2715
2716void
2717litest_hover_move_two_touches(struct litest_device *d,
2718			      double x0, double y0,
2719			      double x1, double y1,
2720			      double dx, double dy,
2721			      int steps)
2722{
2723	int sleep_ms = 10;
2724
2725	for (int i = 0; i < steps - 1; i++) {
2726		litest_push_event_frame(d);
2727		litest_hover_move(d, 0, x0 + dx / steps * i,
2728					y0 + dy / steps * i);
2729		litest_hover_move(d, 1, x1 + dx / steps * i,
2730					y1 + dy / steps * i);
2731		litest_pop_event_frame(d);
2732		libinput_dispatch(d->libinput);
2733		msleep(sleep_ms);
2734		libinput_dispatch(d->libinput);
2735	}
2736	litest_push_event_frame(d);
2737	litest_hover_move(d, 0, x0 + dx, y0 + dy);
2738	litest_hover_move(d, 1, x1 + dx, y1 + dy);
2739	litest_pop_event_frame(d);
2740}
2741
2742void
2743litest_button_click(struct litest_device *d,
2744		    unsigned int button,
2745		    bool is_press)
2746{
2747	struct input_event click[] = {
2748		{ .type = EV_KEY, .code = button, .value = is_press ? 1 : 0 },
2749		{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
2750	};
2751
2752	ARRAY_FOR_EACH(click, ev)
2753		litest_event(d, ev->type, ev->code, ev->value);
2754}
2755
2756void
2757litest_button_click_debounced(struct litest_device *d,
2758			      struct libinput *li,
2759			      unsigned int button,
2760			      bool is_press)
2761{
2762	litest_button_click(d, button, is_press);
2763
2764	libinput_dispatch(li);
2765	litest_timeout_debounce();
2766	libinput_dispatch(li);
2767}
2768
2769void
2770litest_button_scroll(struct litest_device *dev,
2771		     unsigned int button,
2772		     double dx, double dy)
2773{
2774	struct libinput *li = dev->libinput;
2775
2776	litest_button_click_debounced(dev, li, button, 1);
2777
2778	libinput_dispatch(li);
2779	litest_timeout_buttonscroll();
2780	libinput_dispatch(li);
2781
2782	litest_event(dev, EV_REL, REL_X, dx);
2783	litest_event(dev, EV_REL, REL_Y, dy);
2784	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2785
2786	litest_button_click_debounced(dev, li, button, 0);
2787
2788	libinput_dispatch(li);
2789}
2790
2791void
2792litest_button_scroll_locked(struct litest_device *dev,
2793			    unsigned int button,
2794			    double dx, double dy)
2795{
2796	struct libinput *li = dev->libinput;
2797
2798	litest_button_click_debounced(dev, li, button, 1);
2799	litest_button_click_debounced(dev, li, button, 0);
2800
2801	libinput_dispatch(li);
2802	litest_timeout_buttonscroll();
2803	libinput_dispatch(li);
2804
2805	litest_event(dev, EV_REL, REL_X, dx);
2806	litest_event(dev, EV_REL, REL_Y, dy);
2807	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2808
2809	libinput_dispatch(li);
2810}
2811
2812void
2813litest_keyboard_key(struct litest_device *d, unsigned int key, bool is_press)
2814{
2815	struct input_event click[] = {
2816		{ .type = EV_KEY, .code = key, .value = is_press ? 1 : 0 },
2817		{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
2818	};
2819
2820	ARRAY_FOR_EACH(click, ev)
2821		litest_event(d, ev->type, ev->code, ev->value);
2822}
2823
2824void
2825litest_switch_action(struct litest_device *dev,
2826		     enum libinput_switch sw,
2827		     enum libinput_switch_state state)
2828{
2829	unsigned int code;
2830
2831	switch (sw) {
2832	case LIBINPUT_SWITCH_LID:
2833		code = SW_LID;
2834		break;
2835	case LIBINPUT_SWITCH_TABLET_MODE:
2836		code = SW_TABLET_MODE;
2837		break;
2838	default:
2839		litest_abort_msg("Invalid switch %d", sw);
2840		break;
2841	}
2842	litest_event(dev, EV_SW, code, state);
2843	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2844}
2845
2846static int
2847litest_scale_axis(const struct litest_device *d,
2848		  unsigned int axis,
2849		  double val)
2850{
2851	const struct input_absinfo *abs;
2852
2853	litest_assert_double_ge(val, 0.0);
2854	/* major/minor must be able to beyond 100% for large fingers */
2855	if (axis != ABS_MT_TOUCH_MAJOR &&
2856	    axis != ABS_MT_TOUCH_MINOR) {
2857		litest_assert_double_le(val, 100.0);
2858	}
2859
2860	abs = libevdev_get_abs_info(d->evdev, axis);
2861	litest_assert_notnull(abs);
2862
2863	return (abs->maximum - abs->minimum) * val/100.0 + abs->minimum;
2864}
2865
2866static inline int
2867litest_scale_range(int min, int max, double val)
2868{
2869	litest_assert_int_ge((int)val, 0);
2870	litest_assert_int_le((int)val, 100);
2871
2872	return (max - min) * val/100.0 + min;
2873}
2874
2875int
2876litest_scale(const struct litest_device *d, unsigned int axis, double val)
2877{
2878	int min, max;
2879
2880	litest_assert_double_ge(val, 0.0);
2881	/* major/minor must be able to beyond 100% for large fingers */
2882	if (axis != ABS_MT_TOUCH_MAJOR &&
2883	    axis != ABS_MT_TOUCH_MINOR)
2884		litest_assert_double_le(val, 100.0);
2885
2886	if (axis <= ABS_Y) {
2887		min = d->interface->min[axis];
2888		max = d->interface->max[axis];
2889
2890		return litest_scale_range(min, max, val);
2891	} else {
2892		return litest_scale_axis(d, axis, val);
2893	}
2894}
2895
2896static inline int
2897auto_assign_pad_value(struct litest_device *dev,
2898		      struct input_event *ev,
2899		      double value)
2900{
2901	const struct input_absinfo *abs;
2902
2903	if (ev->value != LITEST_AUTO_ASSIGN ||
2904	    ev->type != EV_ABS)
2905		return value;
2906
2907	abs = libevdev_get_abs_info(dev->evdev, ev->code);
2908	litest_assert_notnull(abs);
2909
2910	if (ev->code == ABS_RX || ev->code == ABS_RY) {
2911		double min = abs->minimum != 0 ? log2(abs->minimum) : 0,
2912		       max = abs->maximum != 0 ? log2(abs->maximum) : 0;
2913
2914		/* Value 0 is reserved for finger up, so a value of 0% is
2915		 * actually 1 */
2916		if (value == 0.0) {
2917			return 1;
2918		} else {
2919			value = litest_scale_range(min, max, value);
2920			return pow(2, value);
2921		}
2922	} else {
2923		return litest_scale_range(abs->minimum, abs->maximum, value);
2924	}
2925}
2926
2927void
2928litest_pad_ring_start(struct litest_device *d, double value)
2929{
2930	struct input_event *ev;
2931
2932	ev = d->interface->pad_ring_start_events;
2933	while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
2934		value = auto_assign_pad_value(d, ev, value);
2935		litest_event(d, ev->type, ev->code, value);
2936		ev++;
2937	}
2938}
2939
2940void
2941litest_pad_ring_change(struct litest_device *d, double value)
2942{
2943	struct input_event *ev;
2944
2945	ev = d->interface->pad_ring_change_events;
2946	while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
2947		value = auto_assign_pad_value(d, ev, value);
2948		litest_event(d, ev->type, ev->code, value);
2949		ev++;
2950	}
2951}
2952
2953void
2954litest_pad_ring_end(struct litest_device *d)
2955{
2956	struct input_event *ev;
2957
2958	ev = d->interface->pad_ring_end_events;
2959	while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
2960		litest_event(d, ev->type, ev->code, ev->value);
2961		ev++;
2962	}
2963}
2964
2965void
2966litest_pad_strip_start(struct litest_device *d, double value)
2967{
2968	struct input_event *ev;
2969
2970	ev = d->interface->pad_strip_start_events;
2971	while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
2972		value = auto_assign_pad_value(d, ev, value);
2973		litest_event(d, ev->type, ev->code, value);
2974		ev++;
2975	}
2976}
2977
2978void
2979litest_pad_strip_change(struct litest_device *d, double value)
2980{
2981	struct input_event *ev;
2982
2983	ev = d->interface->pad_strip_change_events;
2984	while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
2985		value = auto_assign_pad_value(d, ev, value);
2986		litest_event(d, ev->type, ev->code, value);
2987		ev++;
2988	}
2989}
2990
2991void
2992litest_pad_strip_end(struct litest_device *d)
2993{
2994	struct input_event *ev;
2995
2996	ev = d->interface->pad_strip_end_events;
2997	while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
2998		litest_event(d, ev->type, ev->code, ev->value);
2999		ev++;
3000	}
3001}
3002
3003void
3004litest_wait_for_event(struct libinput *li)
3005{
3006	return litest_wait_for_event_of_type(li, -1);
3007}
3008
3009void
3010litest_wait_for_event_of_type(struct libinput *li, ...)
3011{
3012	va_list args;
3013	enum libinput_event_type types[32] = {LIBINPUT_EVENT_NONE};
3014	size_t ntypes = 0;
3015	enum libinput_event_type type;
3016	struct pollfd fds;
3017
3018	va_start(args, li);
3019	type = va_arg(args, int);
3020	while ((int)type != -1) {
3021		litest_assert_int_gt(type, 0U);
3022		litest_assert_int_lt(ntypes, ARRAY_LENGTH(types));
3023		types[ntypes++] = type;
3024		type = va_arg(args, int);
3025	}
3026	va_end(args);
3027
3028	fds.fd = libinput_get_fd(li);
3029	fds.events = POLLIN;
3030	fds.revents = 0;
3031
3032	while (1) {
3033		size_t i;
3034		struct libinput_event *event;
3035
3036		while ((type = libinput_next_event_type(li)) == LIBINPUT_EVENT_NONE) {
3037			int rc = poll(&fds, 1, 2000);
3038			litest_assert_int_gt(rc, 0);
3039			libinput_dispatch(li);
3040		}
3041
3042		/* no event mask means wait for any event */
3043		if (ntypes == 0)
3044			return;
3045
3046		for (i = 0; i < ntypes; i++) {
3047			if (type == types[i])
3048				return;
3049		}
3050
3051		event = libinput_get_event(li);
3052		libinput_event_destroy(event);
3053	}
3054}
3055
3056void
3057litest_drain_events(struct libinput *li)
3058{
3059	struct libinput_event *event;
3060
3061	libinput_dispatch(li);
3062	while ((event = libinput_get_event(li))) {
3063		libinput_event_destroy(event);
3064		libinput_dispatch(li);
3065	}
3066}
3067
3068
3069void
3070litest_drain_events_of_type(struct libinput *li, ...)
3071{
3072	enum libinput_event_type type;
3073	enum libinput_event_type types[32] = {LIBINPUT_EVENT_NONE};
3074	size_t ntypes = 0;
3075	va_list args;
3076
3077	va_start(args, li);
3078	type = va_arg(args, int);
3079	while ((int)type != -1) {
3080		litest_assert_int_gt(type, 0U);
3081		litest_assert_int_lt(ntypes, ARRAY_LENGTH(types));
3082		types[ntypes++] = type;
3083		type = va_arg(args, int);
3084	}
3085	va_end(args);
3086
3087	libinput_dispatch(li);
3088	type = libinput_next_event_type(li);
3089	while (type !=  LIBINPUT_EVENT_NONE) {
3090		struct libinput_event *event;
3091		bool found = false;
3092
3093		type = libinput_next_event_type(li);
3094
3095		for (size_t i = 0; i < ntypes; i++) {
3096			if (type == types[i]) {
3097				found = true;
3098				break;
3099			}
3100		}
3101		if (!found)
3102			return;
3103
3104		event = libinput_get_event(li);
3105		libinput_event_destroy(event);
3106		libinput_dispatch(li);
3107	}
3108}
3109
3110static const char *
3111litest_event_type_str(enum libinput_event_type type)
3112{
3113	const char *str = NULL;
3114
3115	switch (type) {
3116	case LIBINPUT_EVENT_NONE:
3117		abort();
3118	case LIBINPUT_EVENT_DEVICE_ADDED:
3119		str = "ADDED";
3120		break;
3121	case LIBINPUT_EVENT_DEVICE_REMOVED:
3122		str = "REMOVED";
3123		break;
3124	case LIBINPUT_EVENT_KEYBOARD_KEY:
3125		str = "KEY";
3126		break;
3127	case LIBINPUT_EVENT_POINTER_MOTION:
3128		str = "MOTION";
3129		break;
3130	case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
3131		str = "ABSOLUTE";
3132		break;
3133	case LIBINPUT_EVENT_POINTER_BUTTON:
3134		str = "BUTTON";
3135		break;
3136	case LIBINPUT_EVENT_POINTER_AXIS:
3137		str = "AXIS";
3138		break;
3139	case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
3140		str = "SCROLL_WHEEL";
3141		break;
3142	case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
3143		str = "SCROLL_FINGER";
3144		break;
3145	case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
3146		str = "SCROLL_CONTINUOUS";
3147		break;
3148	case LIBINPUT_EVENT_TOUCH_DOWN:
3149		str = "TOUCH DOWN";
3150		break;
3151	case LIBINPUT_EVENT_TOUCH_UP:
3152		str = "TOUCH UP";
3153		break;
3154	case LIBINPUT_EVENT_TOUCH_MOTION:
3155		str = "TOUCH MOTION";
3156		break;
3157	case LIBINPUT_EVENT_TOUCH_CANCEL:
3158		str = "TOUCH CANCEL";
3159		break;
3160	case LIBINPUT_EVENT_TOUCH_FRAME:
3161		str = "TOUCH FRAME";
3162		break;
3163	case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
3164		str = "GESTURE SWIPE BEGIN";
3165		break;
3166	case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
3167		str = "GESTURE SWIPE UPDATE";
3168		break;
3169	case LIBINPUT_EVENT_GESTURE_SWIPE_END:
3170		str = "GESTURE SWIPE END";
3171		break;
3172	case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
3173		str = "GESTURE PINCH BEGIN";
3174		break;
3175	case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
3176		str = "GESTURE PINCH UPDATE";
3177		break;
3178	case LIBINPUT_EVENT_GESTURE_PINCH_END:
3179		str = "GESTURE PINCH END";
3180		break;
3181	case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
3182		str = "GESTURE HOLD BEGIN";
3183		break;
3184	case LIBINPUT_EVENT_GESTURE_HOLD_END:
3185		str = "GESTURE HOLD END";
3186		break;
3187	case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
3188		str = "TABLET TOOL AXIS";
3189		break;
3190	case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
3191		str = "TABLET TOOL PROX";
3192		break;
3193	case LIBINPUT_EVENT_TABLET_TOOL_TIP:
3194		str = "TABLET TOOL TIP";
3195		break;
3196	case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
3197		str = "TABLET TOOL BUTTON";
3198		break;
3199	case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
3200		str = "TABLET PAD BUTTON";
3201		break;
3202	case LIBINPUT_EVENT_TABLET_PAD_RING:
3203		str = "TABLET PAD RING";
3204		break;
3205	case LIBINPUT_EVENT_TABLET_PAD_STRIP:
3206		str = "TABLET PAD STRIP";
3207		break;
3208	case LIBINPUT_EVENT_TABLET_PAD_KEY:
3209		str = "TABLET PAD KEY";
3210		break;
3211	case LIBINPUT_EVENT_SWITCH_TOGGLE:
3212		str = "SWITCH TOGGLE";
3213		break;
3214	}
3215	return str;
3216}
3217
3218static const char *
3219litest_event_get_type_str(struct libinput_event *event)
3220{
3221	return litest_event_type_str(libinput_event_get_type(event));
3222}
3223
3224static void
3225litest_print_event(struct libinput_event *event)
3226{
3227	struct libinput_event_pointer *p;
3228	struct libinput_event_tablet_tool *t;
3229	struct libinput_event_tablet_pad *pad;
3230	struct libinput_device *dev;
3231	enum libinput_event_type type;
3232	double x, y;
3233
3234	dev = libinput_event_get_device(event);
3235	type = libinput_event_get_type(event);
3236
3237	fprintf(stderr,
3238		"device %s (%s) type %s ",
3239		libinput_device_get_sysname(dev),
3240		libinput_device_get_name(dev),
3241		litest_event_get_type_str(event));
3242	switch (type) {
3243	case LIBINPUT_EVENT_POINTER_MOTION:
3244		p = libinput_event_get_pointer_event(event);
3245		x = libinput_event_pointer_get_dx(p);
3246		y = libinput_event_pointer_get_dy(p);
3247		fprintf(stderr, "%.2f/%.2f", x, y);
3248		break;
3249	case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
3250		p = libinput_event_get_pointer_event(event);
3251		x = libinput_event_pointer_get_absolute_x(p);
3252		y = libinput_event_pointer_get_absolute_y(p);
3253		fprintf(stderr, "%.2f/%.2f", x, y);
3254		break;
3255	case LIBINPUT_EVENT_POINTER_BUTTON:
3256		p = libinput_event_get_pointer_event(event);
3257		fprintf(stderr,
3258			"button %d state %d",
3259			libinput_event_pointer_get_button(p),
3260			libinput_event_pointer_get_button_state(p));
3261		break;
3262	case LIBINPUT_EVENT_POINTER_AXIS:
3263		p = libinput_event_get_pointer_event(event);
3264		x = 0.0;
3265		y = 0.0;
3266		if (libinput_event_pointer_has_axis(p,
3267				LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
3268			y = libinput_event_pointer_get_axis_value(p,
3269				LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
3270		if (libinput_event_pointer_has_axis(p,
3271				LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
3272			x = libinput_event_pointer_get_axis_value(p,
3273				LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
3274		fprintf(stderr, "vert %.2f horiz %.2f", y, x);
3275		break;
3276	case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
3277		t = libinput_event_get_tablet_tool_event(event);
3278		fprintf(stderr, "proximity %d",
3279			libinput_event_tablet_tool_get_proximity_state(t));
3280		break;
3281	case LIBINPUT_EVENT_TABLET_TOOL_TIP:
3282		t = libinput_event_get_tablet_tool_event(event);
3283		fprintf(stderr, "tip %d",
3284			libinput_event_tablet_tool_get_tip_state(t));
3285		break;
3286	case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
3287		t = libinput_event_get_tablet_tool_event(event);
3288		fprintf(stderr, "button %d state %d",
3289			libinput_event_tablet_tool_get_button(t),
3290			libinput_event_tablet_tool_get_button_state(t));
3291		break;
3292	case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
3293		pad = libinput_event_get_tablet_pad_event(event);
3294		fprintf(stderr, "button %d state %d",
3295			libinput_event_tablet_pad_get_button_number(pad),
3296			libinput_event_tablet_pad_get_button_state(pad));
3297		break;
3298	case LIBINPUT_EVENT_TABLET_PAD_RING:
3299		pad = libinput_event_get_tablet_pad_event(event);
3300		fprintf(stderr, "ring %d position %.2f source %d",
3301			libinput_event_tablet_pad_get_ring_number(pad),
3302			libinput_event_tablet_pad_get_ring_position(pad),
3303			libinput_event_tablet_pad_get_ring_source(pad));
3304		break;
3305	case LIBINPUT_EVENT_TABLET_PAD_STRIP:
3306		pad = libinput_event_get_tablet_pad_event(event);
3307		fprintf(stderr, "strip %d position %.2f source %d",
3308			libinput_event_tablet_pad_get_ring_number(pad),
3309			libinput_event_tablet_pad_get_ring_position(pad),
3310			libinput_event_tablet_pad_get_ring_source(pad));
3311		break;
3312	default:
3313		break;
3314	}
3315
3316	fprintf(stderr, "\n");
3317}
3318
3319#define litest_assert_event_type_is_one_of(...) \
3320    _litest_assert_event_type_is_one_of(__VA_ARGS__, -1)
3321
3322static void
3323_litest_assert_event_type_is_one_of(struct libinput_event *event, ...)
3324{
3325	va_list args;
3326	enum libinput_event_type expected_type;
3327	enum libinput_event_type actual_type = libinput_event_get_type(event);
3328	bool match = false;
3329
3330	va_start(args, event);
3331	expected_type = va_arg(args, int);
3332	while ((int)expected_type != -1 && !match) {
3333		match = (actual_type == expected_type);
3334		expected_type = va_arg(args, int);
3335	}
3336	va_end(args);
3337
3338	if (match)
3339		return;
3340
3341	fprintf(stderr,
3342		"FAILED EVENT TYPE: %s: have %s (%d) but want ",
3343		libinput_device_get_name(libinput_event_get_device(event)),
3344		litest_event_get_type_str(event),
3345		libinput_event_get_type(event));
3346
3347	va_start(args, event);
3348	expected_type = va_arg(args, int);
3349	while ((int)expected_type != -1) {
3350		fprintf(stderr,
3351			"%s (%d)",
3352			litest_event_type_str(expected_type),
3353			expected_type);
3354		expected_type = va_arg(args, int);
3355
3356		if ((int)expected_type != -1)
3357			fprintf(stderr, " || ");
3358	}
3359
3360	fprintf(stderr, "\nWrong event is: ");
3361	litest_print_event(event);
3362	litest_backtrace();
3363	abort();
3364}
3365
3366void
3367litest_assert_event_type(struct libinput_event *event,
3368			 enum libinput_event_type want)
3369{
3370	litest_assert_event_type_is_one_of(event, want);
3371}
3372
3373void
3374litest_assert_empty_queue(struct libinput *li)
3375{
3376	bool empty_queue = true;
3377	struct libinput_event *event;
3378
3379	libinput_dispatch(li);
3380	while ((event = libinput_get_event(li))) {
3381		empty_queue = false;
3382		fprintf(stderr,
3383			"Unexpected event: ");
3384		litest_print_event(event);
3385		libinput_event_destroy(event);
3386		libinput_dispatch(li);
3387	}
3388
3389	litest_assert(empty_queue);
3390}
3391
3392static struct libevdev_uinput *
3393litest_create_uinput(const char *name,
3394		     const struct input_id *id,
3395		     const struct input_absinfo *abs_info,
3396		     const int *events)
3397{
3398	struct libevdev_uinput *uinput;
3399	struct libevdev *dev;
3400	int type, code;
3401	int rc, fd;
3402	const struct input_absinfo *abs;
3403	const struct input_absinfo default_abs = {
3404		.value = 0,
3405		.minimum = 0,
3406		.maximum = 100,
3407		.fuzz = 0,
3408		.flat = 0,
3409		.resolution = 100
3410	};
3411	char buf[512];
3412	const char *devnode;
3413
3414	dev = libevdev_new();
3415	litest_assert_ptr_notnull(dev);
3416
3417	snprintf(buf, sizeof(buf), "litest %s", name);
3418	libevdev_set_name(dev, buf);
3419	if (id) {
3420		libevdev_set_id_bustype(dev, id->bustype);
3421		libevdev_set_id_vendor(dev, id->vendor);
3422		libevdev_set_id_product(dev, id->product);
3423		libevdev_set_id_version(dev, id->version);
3424	}
3425
3426	abs = abs_info;
3427	while (abs && abs->value != -1) {
3428		struct input_absinfo a = *abs;
3429
3430		/* abs_info->value is used for the code and may be outside
3431		   of [min, max] */
3432		a.value = abs->minimum;
3433		rc = libevdev_enable_event_code(dev, EV_ABS, abs->value, &a);
3434		litest_assert_int_eq(rc, 0);
3435		abs++;
3436	}
3437
3438	while (events &&
3439	       (type = *events++) != -1 &&
3440	       (code = *events++) != -1) {
3441		if (type == INPUT_PROP_MAX) {
3442			rc = libevdev_enable_property(dev, code);
3443		} else {
3444			rc = libevdev_enable_event_code(dev, type, code,
3445							type == EV_ABS ? &default_abs : NULL);
3446		}
3447		litest_assert_int_eq(rc, 0);
3448	}
3449
3450	rc = libevdev_uinput_create_from_device(dev,
3451					        LIBEVDEV_UINPUT_OPEN_MANAGED,
3452						&uinput);
3453	/* workaround for a bug in libevdev pre-1.3
3454	   http://cgit.freedesktop.org/libevdev/commit/?id=debe9b030c8069cdf78307888ef3b65830b25122 */
3455	if (rc == -EBADF)
3456		rc = -EACCES;
3457	litest_assert_msg(rc == 0, "Failed to create uinput device: %s\n", strerror(-rc));
3458
3459	libevdev_free(dev);
3460
3461	devnode = libevdev_uinput_get_devnode(uinput);
3462	litest_assert_notnull(devnode);
3463	fd = open(devnode, O_RDONLY);
3464	litest_assert_int_gt(fd, -1);
3465	rc = libevdev_new_from_fd(fd, &dev);
3466	litest_assert_int_eq(rc, 0);
3467
3468	/* uinput before kernel 4.5 + libevdev 1.5.0 does not support
3469	 * setting the resolution, so we set it afterwards. This is of
3470	 * course racy as hell but the way we _generally_ use this function
3471	 * by the time libinput uses the device, we're finished here.
3472	 *
3473	 * If you have kernel 4.5 and libevdev 1.5.0 or later, this code
3474	 * just keeps the room warm.
3475	 */
3476	abs = abs_info;
3477	while (abs && abs->value != -1) {
3478		if (abs->resolution != 0) {
3479			if (libevdev_get_abs_resolution(dev, abs->value) ==
3480			    abs->resolution)
3481				break;
3482
3483			rc = libevdev_kernel_set_abs_info(dev,
3484							  abs->value,
3485							  abs);
3486			litest_assert_int_eq(rc, 0);
3487		}
3488		abs++;
3489	}
3490	close(fd);
3491	libevdev_free(dev);
3492
3493	return uinput;
3494}
3495
3496struct libevdev_uinput *
3497litest_create_uinput_device_from_description(const char *name,
3498					     const struct input_id *id,
3499					     const struct input_absinfo *abs_info,
3500					     const int *events)
3501{
3502	struct libevdev_uinput *uinput;
3503	const char *syspath;
3504	char path[PATH_MAX];
3505
3506	struct udev_monitor *udev_monitor;
3507	struct udev_device *udev_device;
3508
3509	udev_monitor = udev_setup_monitor();
3510
3511	uinput = litest_create_uinput(name, id, abs_info, events);
3512
3513	syspath = libevdev_uinput_get_syspath(uinput);
3514	snprintf(path, sizeof(path), "%s/event", syspath);
3515
3516	udev_device = udev_wait_for_device_event(udev_monitor, "add", path);
3517
3518	litest_assert(udev_device_get_property_value(udev_device, "ID_INPUT"));
3519
3520	udev_device_unref(udev_device);
3521	udev_monitor_unref(udev_monitor);
3522
3523	return uinput;
3524}
3525
3526static struct libevdev_uinput *
3527litest_create_uinput_abs_device_v(const char *name,
3528				  struct input_id *id,
3529				  const struct input_absinfo *abs,
3530				  va_list args)
3531{
3532	int events[KEY_MAX * 2 + 2]; /* increase this if not sufficient */
3533	int *event = events;
3534	int type, code;
3535
3536	while ((type = va_arg(args, int)) != -1 &&
3537	       (code = va_arg(args, int)) != -1) {
3538		*event++ = type;
3539		*event++ = code;
3540		litest_assert(event < &events[ARRAY_LENGTH(events) - 2]);
3541	}
3542
3543	*event++ = -1;
3544	*event++ = -1;
3545
3546	return litest_create_uinput_device_from_description(name, id,
3547							    abs, events);
3548}
3549
3550struct libevdev_uinput *
3551litest_create_uinput_abs_device(const char *name,
3552				struct input_id *id,
3553				const struct input_absinfo *abs,
3554				...)
3555{
3556	struct libevdev_uinput *uinput;
3557	va_list args;
3558
3559	va_start(args, abs);
3560	uinput = litest_create_uinput_abs_device_v(name, id, abs, args);
3561	va_end(args);
3562
3563	return uinput;
3564}
3565
3566struct libevdev_uinput *
3567litest_create_uinput_device(const char *name, struct input_id *id, ...)
3568{
3569	struct libevdev_uinput *uinput;
3570	va_list args;
3571
3572	va_start(args, id);
3573	uinput = litest_create_uinput_abs_device_v(name, id, NULL, args);
3574	va_end(args);
3575
3576	return uinput;
3577}
3578
3579struct libinput_event_pointer*
3580litest_is_button_event(struct libinput_event *event,
3581		       unsigned int button,
3582		       enum libinput_button_state state)
3583{
3584	struct libinput_event_pointer *ptrev;
3585	enum libinput_event_type type = LIBINPUT_EVENT_POINTER_BUTTON;
3586
3587	litest_assert_ptr_notnull(event);
3588	litest_assert_event_type(event, type);
3589	ptrev = libinput_event_get_pointer_event(event);
3590	litest_assert_int_eq(libinput_event_pointer_get_button(ptrev),
3591			     button);
3592	litest_assert_int_eq(libinput_event_pointer_get_button_state(ptrev),
3593			     state);
3594
3595	return ptrev;
3596}
3597
3598struct libinput_event_pointer *
3599litest_is_axis_event(struct libinput_event *event,
3600		     enum libinput_event_type axis_type,
3601		     enum libinput_pointer_axis axis,
3602		     enum libinput_pointer_axis_source source)
3603{
3604	struct libinput_event_pointer *ptrev;
3605
3606	litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
3607		      axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
3608		      axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
3609
3610	litest_assert_ptr_notnull(event);
3611	litest_assert_event_type_is_one_of(event,
3612					   LIBINPUT_EVENT_POINTER_AXIS,
3613					   axis_type);
3614	ptrev = libinput_event_get_pointer_event(event);
3615	litest_assert(libinput_event_pointer_has_axis(ptrev, axis));
3616
3617	if (source != 0)
3618		litest_assert_int_eq(litest_event_pointer_get_axis_source(ptrev),
3619				     source);
3620
3621	return ptrev;
3622}
3623
3624bool
3625litest_is_high_res_axis_event(struct libinput_event *event)
3626{
3627	litest_assert_event_type_is_one_of(event,
3628					   LIBINPUT_EVENT_POINTER_AXIS,
3629					   LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
3630					   LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
3631					   LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
3632
3633	return (libinput_event_get_type(event) != LIBINPUT_EVENT_POINTER_AXIS);
3634}
3635
3636struct libinput_event_pointer *
3637litest_is_motion_event(struct libinput_event *event)
3638{
3639	struct libinput_event_pointer *ptrev;
3640	enum libinput_event_type type = LIBINPUT_EVENT_POINTER_MOTION;
3641	double x, y, ux, uy;
3642
3643	litest_assert_ptr_notnull(event);
3644	litest_assert_event_type(event, type);
3645	ptrev = libinput_event_get_pointer_event(event);
3646
3647	x = libinput_event_pointer_get_dx(ptrev);
3648	y = libinput_event_pointer_get_dy(ptrev);
3649	ux = libinput_event_pointer_get_dx_unaccelerated(ptrev);
3650	uy = libinput_event_pointer_get_dy_unaccelerated(ptrev);
3651
3652	/* No 0 delta motion events */
3653	litest_assert(x != 0.0 || y != 0.0 ||
3654		      ux != 0.0 || uy != 0.0);
3655
3656	return ptrev;
3657}
3658
3659void
3660litest_assert_key_event(struct libinput *li, unsigned int key,
3661			enum libinput_key_state state)
3662{
3663	struct libinput_event *event;
3664
3665	litest_wait_for_event(li);
3666	event = libinput_get_event(li);
3667
3668	litest_is_keyboard_event(event, key, state);
3669
3670	libinput_event_destroy(event);
3671}
3672
3673void
3674litest_assert_button_event(struct libinput *li, unsigned int button,
3675			   enum libinput_button_state state)
3676{
3677	struct libinput_event *event;
3678
3679	litest_wait_for_event(li);
3680	event = libinput_get_event(li);
3681
3682	litest_is_button_event(event, button, state);
3683
3684	libinput_event_destroy(event);
3685}
3686
3687struct libinput_event_touch *
3688litest_is_touch_event(struct libinput_event *event,
3689		      enum libinput_event_type type)
3690{
3691	struct libinput_event_touch *touch;
3692
3693	litest_assert_ptr_notnull(event);
3694
3695	if (type == 0)
3696		type = libinput_event_get_type(event);
3697
3698	switch (type) {
3699	case LIBINPUT_EVENT_TOUCH_DOWN:
3700	case LIBINPUT_EVENT_TOUCH_UP:
3701	case LIBINPUT_EVENT_TOUCH_MOTION:
3702	case LIBINPUT_EVENT_TOUCH_FRAME:
3703	case LIBINPUT_EVENT_TOUCH_CANCEL:
3704		litest_assert_event_type(event, type);
3705		break;
3706	default:
3707		ck_abort_msg("%s: invalid touch type %d\n", __func__, type);
3708	}
3709
3710	touch = libinput_event_get_touch_event(event);
3711
3712	return touch;
3713}
3714
3715struct libinput_event_keyboard *
3716litest_is_keyboard_event(struct libinput_event *event,
3717			 unsigned int key,
3718			 enum libinput_key_state state)
3719{
3720	struct libinput_event_keyboard *kevent;
3721	enum libinput_event_type type = LIBINPUT_EVENT_KEYBOARD_KEY;
3722
3723	litest_assert_ptr_notnull(event);
3724	litest_assert_event_type(event, type);
3725
3726	kevent = libinput_event_get_keyboard_event(event);
3727	litest_assert_ptr_notnull(kevent);
3728
3729	litest_assert_int_eq(libinput_event_keyboard_get_key(kevent), key);
3730	litest_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
3731			     state);
3732	return kevent;
3733}
3734
3735struct libinput_event_gesture *
3736litest_is_gesture_event(struct libinput_event *event,
3737			enum libinput_event_type type,
3738			int nfingers)
3739{
3740	struct libinput_event_gesture *gevent;
3741
3742	litest_assert_ptr_notnull(event);
3743	litest_assert_event_type(event, type);
3744
3745	gevent = libinput_event_get_gesture_event(event);
3746	litest_assert_ptr_notnull(gevent);
3747
3748	if (nfingers != -1)
3749		litest_assert_int_eq(libinput_event_gesture_get_finger_count(gevent),
3750				     nfingers);
3751	return gevent;
3752}
3753
3754void
3755litest_assert_gesture_event(struct libinput *li,
3756			    enum libinput_event_type type,
3757			    int nfingers)
3758{
3759	struct libinput_event *event;
3760
3761	litest_wait_for_event(li);
3762	event = libinput_get_event(li);
3763
3764	litest_is_gesture_event(event, type, nfingers);
3765	libinput_event_destroy(event);
3766}
3767
3768struct libinput_event_tablet_tool *
3769litest_is_tablet_event(struct libinput_event *event,
3770		       enum libinput_event_type type)
3771{
3772	struct libinput_event_tablet_tool *tevent;
3773
3774	litest_assert_ptr_notnull(event);
3775	litest_assert_event_type(event, type);
3776
3777	tevent = libinput_event_get_tablet_tool_event(event);
3778	litest_assert_ptr_notnull(tevent);
3779
3780	return tevent;
3781}
3782
3783void
3784litest_assert_tablet_button_event(struct libinput *li, unsigned int button,
3785				  enum libinput_button_state state)
3786{
3787	struct libinput_event *event;
3788	struct libinput_event_tablet_tool *tev;
3789	enum libinput_event_type type = LIBINPUT_EVENT_TABLET_TOOL_BUTTON;
3790
3791	litest_wait_for_event(li);
3792	event = libinput_get_event(li);
3793
3794	litest_assert_notnull(event);
3795	litest_assert_event_type(event, type);
3796	tev = libinput_event_get_tablet_tool_event(event);
3797	litest_assert_int_eq(libinput_event_tablet_tool_get_button(tev),
3798			     button);
3799	litest_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev),
3800			     state);
3801	libinput_event_destroy(event);
3802}
3803
3804
3805struct libinput_event_tablet_tool *
3806litest_is_proximity_event(struct libinput_event *event,
3807			  enum libinput_tablet_tool_proximity_state state)
3808{
3809	struct libinput_event_tablet_tool *tev;
3810	enum libinput_event_type type = LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY;
3811
3812	litest_assert_notnull(event);
3813	litest_assert_event_type(event, type);
3814	tev = libinput_event_get_tablet_tool_event(event);
3815	litest_assert_int_eq(libinput_event_tablet_tool_get_proximity_state(tev),
3816			     state);
3817	return tev;
3818}
3819
3820double
3821litest_event_pointer_get_value(struct libinput_event_pointer *ptrev,
3822			       enum libinput_pointer_axis axis)
3823{
3824	struct libinput_event *event;
3825	enum libinput_event_type type;
3826
3827	event = libinput_event_pointer_get_base_event(ptrev);
3828	type = libinput_event_get_type(event);
3829
3830	switch (type) {
3831	case LIBINPUT_EVENT_POINTER_AXIS:
3832		return libinput_event_pointer_get_axis_value(ptrev, axis);
3833	case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
3834		return libinput_event_pointer_get_scroll_value_v120(ptrev, axis);
3835	case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
3836	case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
3837		return libinput_event_pointer_get_scroll_value(ptrev, axis);
3838	default:
3839		abort();
3840	}
3841}
3842
3843enum libinput_pointer_axis_source
3844litest_event_pointer_get_axis_source(struct libinput_event_pointer *ptrev)
3845{
3846	struct libinput_event *event;
3847	enum libinput_event_type type;
3848
3849	event = libinput_event_pointer_get_base_event(ptrev);
3850	type = libinput_event_get_type(event);
3851
3852	if (type == LIBINPUT_EVENT_POINTER_AXIS)
3853		return libinput_event_pointer_get_axis_source(ptrev);
3854
3855	switch (type) {
3856	case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
3857		return LIBINPUT_POINTER_AXIS_SOURCE_WHEEL;
3858	case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
3859		return LIBINPUT_POINTER_AXIS_SOURCE_FINGER;
3860	case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
3861		return LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS;
3862	default:
3863		abort();
3864	}
3865}
3866
3867void litest_assert_tablet_proximity_event(struct libinput *li,
3868					  enum libinput_tablet_tool_proximity_state state)
3869{
3870	struct libinput_event *event;
3871
3872	litest_wait_for_event(li);
3873	event = libinput_get_event(li);
3874	litest_is_proximity_event(event, state);
3875	libinput_event_destroy(event);
3876}
3877
3878void litest_assert_tablet_tip_event(struct libinput *li,
3879				    enum libinput_tablet_tool_tip_state state)
3880{
3881	struct libinput_event *event;
3882	struct libinput_event_tablet_tool *tev;
3883	enum libinput_event_type type = LIBINPUT_EVENT_TABLET_TOOL_TIP;
3884
3885	litest_wait_for_event(li);
3886	event = libinput_get_event(li);
3887
3888	litest_assert_notnull(event);
3889	litest_assert_event_type(event, type);
3890	tev = libinput_event_get_tablet_tool_event(event);
3891	litest_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tev),
3892			     state);
3893	libinput_event_destroy(event);
3894}
3895
3896struct libinput_event_tablet_pad *
3897litest_is_pad_button_event(struct libinput_event *event,
3898			   unsigned int button,
3899			   enum libinput_button_state state)
3900{
3901	struct libinput_event_tablet_pad *p;
3902	enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_BUTTON;
3903
3904	litest_assert_ptr_notnull(event);
3905	litest_assert_event_type(event, type);
3906
3907	p = libinput_event_get_tablet_pad_event(event);
3908	litest_assert_ptr_notnull(p);
3909
3910	litest_assert_int_eq(libinput_event_tablet_pad_get_button_number(p),
3911			     button);
3912	litest_assert_int_eq(libinput_event_tablet_pad_get_button_state(p),
3913			     state);
3914
3915	return p;
3916}
3917
3918struct libinput_event_tablet_pad *
3919litest_is_pad_ring_event(struct libinput_event *event,
3920			 unsigned int number,
3921			 enum libinput_tablet_pad_ring_axis_source source)
3922{
3923	struct libinput_event_tablet_pad *p;
3924	enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_RING;
3925
3926	litest_assert_ptr_notnull(event);
3927	litest_assert_event_type(event, type);
3928	p = libinput_event_get_tablet_pad_event(event);
3929
3930	litest_assert_int_eq(libinput_event_tablet_pad_get_ring_number(p),
3931			     number);
3932	litest_assert_int_eq(libinput_event_tablet_pad_get_ring_source(p),
3933			     source);
3934
3935	return p;
3936}
3937
3938struct libinput_event_tablet_pad *
3939litest_is_pad_strip_event(struct libinput_event *event,
3940			  unsigned int number,
3941			  enum libinput_tablet_pad_strip_axis_source source)
3942{
3943	struct libinput_event_tablet_pad *p;
3944	enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_STRIP;
3945
3946	litest_assert_ptr_notnull(event);
3947	litest_assert_event_type(event, type);
3948	p = libinput_event_get_tablet_pad_event(event);
3949
3950	litest_assert_int_eq(libinput_event_tablet_pad_get_strip_number(p),
3951			     number);
3952	litest_assert_int_eq(libinput_event_tablet_pad_get_strip_source(p),
3953			     source);
3954
3955	return p;
3956}
3957
3958struct libinput_event_tablet_pad *
3959litest_is_pad_key_event(struct libinput_event *event,
3960			unsigned int key,
3961			enum libinput_key_state state)
3962{
3963	struct libinput_event_tablet_pad *p;
3964	enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_KEY;
3965
3966	litest_assert(event != NULL);
3967	litest_assert_event_type(event, type);
3968
3969	p = libinput_event_get_tablet_pad_event(event);
3970	litest_assert(p != NULL);
3971
3972	litest_assert_int_eq(libinput_event_tablet_pad_get_key(p), key);
3973	litest_assert_int_eq(libinput_event_tablet_pad_get_key_state(p),
3974			     state);
3975
3976	return p;
3977}
3978
3979struct libinput_event_switch *
3980litest_is_switch_event(struct libinput_event *event,
3981		       enum libinput_switch sw,
3982		       enum libinput_switch_state state)
3983{
3984	struct libinput_event_switch *swev;
3985	enum libinput_event_type type = LIBINPUT_EVENT_SWITCH_TOGGLE;
3986
3987	litest_assert_notnull(event);
3988	litest_assert_event_type(event, type);
3989	swev = libinput_event_get_switch_event(event);
3990
3991	litest_assert_int_eq(libinput_event_switch_get_switch(swev), sw);
3992	litest_assert_int_eq(libinput_event_switch_get_switch_state(swev),
3993			     state);
3994
3995	return swev;
3996}
3997
3998void
3999litest_assert_switch_event(struct libinput *li,
4000			   enum libinput_switch sw,
4001			   enum libinput_switch_state state)
4002{
4003	struct libinput_event *event;
4004
4005	litest_wait_for_event(li);
4006	event = libinput_get_event(li);
4007
4008	litest_is_switch_event(event, sw, state);
4009
4010	libinput_event_destroy(event);
4011}
4012
4013void
4014litest_assert_pad_button_event(struct libinput *li,
4015			       unsigned int button,
4016			       enum libinput_button_state state)
4017{
4018	struct libinput_event *event;
4019
4020	litest_wait_for_event(li);
4021	event = libinput_get_event(li);
4022
4023	litest_is_pad_button_event(event, button, state);
4024	libinput_event_destroy(event);
4025}
4026
4027void
4028litest_assert_pad_key_event(struct libinput *li,
4029			    unsigned int key,
4030			    enum libinput_key_state state)
4031{
4032	struct libinput_event *event;
4033
4034	litest_wait_for_event(li);
4035	event = libinput_get_event(li);
4036
4037	litest_is_pad_key_event(event, key, state);
4038	libinput_event_destroy(event);
4039}
4040
4041void
4042litest_assert_scroll(struct libinput *li,
4043		     enum libinput_event_type axis_type,
4044		     enum libinput_pointer_axis axis,
4045		     int minimum_movement)
4046{
4047	struct libinput_event *event;
4048	struct libinput_event_pointer *ptrev;
4049	bool last_hi_res_event_found, last_low_res_event_found;
4050	int value;
4051	int nevents = 0;
4052
4053	litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
4054		      axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
4055		      axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
4056
4057	last_hi_res_event_found = false;
4058	last_low_res_event_found = false;
4059	event = libinput_get_event(li);
4060	litest_assert_ptr_notnull(event);
4061
4062	while (event) {
4063		int min = minimum_movement;
4064
4065		ptrev = litest_is_axis_event(event, axis_type, axis, 0);
4066		nevents++;
4067
4068		/* Due to how the hysteresis works on touchpad
4069		 * events, the first event is reduced by the
4070		 * hysteresis margin that can cause the first event
4071		 * go under the minimum we expect for all other
4072		 * events */
4073		if (nevents == 1)
4074			min = minimum_movement/2;
4075
4076		value = litest_event_pointer_get_value(ptrev, axis);
4077		if (litest_is_high_res_axis_event(event)) {
4078			litest_assert(!last_hi_res_event_found);
4079
4080			if (axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL)
4081				min *= 120;
4082
4083			if (value == 0)
4084				last_hi_res_event_found = true;
4085		} else {
4086			litest_assert(!last_low_res_event_found);
4087
4088			if (value == 0)
4089				last_low_res_event_found = true;
4090		}
4091
4092		if (value != 0) {
4093			if (minimum_movement > 0)
4094				litest_assert_int_ge(value, min);
4095			else
4096				litest_assert_int_le(value, min);
4097		}
4098
4099		libinput_event_destroy(event);
4100		event = libinput_get_event(li);
4101	}
4102
4103	litest_assert(last_low_res_event_found);
4104	litest_assert(last_hi_res_event_found);
4105}
4106
4107void
4108litest_assert_axis_end_sequence(struct libinput *li,
4109				enum libinput_event_type axis_type,
4110				enum libinput_pointer_axis axis,
4111				enum libinput_pointer_axis_source source)
4112{
4113	struct libinput_event *event;
4114	struct libinput_event_pointer *ptrev;
4115	bool last_hi_res_event_found, last_low_res_event_found;
4116	double val;
4117	int i;
4118
4119	litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
4120		      axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
4121		      axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
4122
4123	last_hi_res_event_found = false;
4124	last_low_res_event_found = false;
4125
4126	/* both high and low scroll end events must be sent */
4127	for (i = 0; i < 2; i++) {
4128		event = libinput_get_event(li);
4129		ptrev = litest_is_axis_event(event, axis_type, axis, source);
4130		val = litest_event_pointer_get_value(ptrev, axis);
4131		ck_assert(val == 0.0);
4132
4133		if (litest_is_high_res_axis_event(event)) {
4134			litest_assert(!last_hi_res_event_found);
4135			last_hi_res_event_found = true;
4136		} else {
4137			litest_assert(!last_low_res_event_found);
4138			last_low_res_event_found = true;
4139		}
4140
4141		libinput_event_destroy(event);
4142	}
4143
4144	litest_assert(last_low_res_event_found);
4145	litest_assert(last_hi_res_event_found);
4146}
4147
4148void
4149litest_assert_only_typed_events(struct libinput *li,
4150				enum libinput_event_type type)
4151{
4152	struct libinput_event *event;
4153
4154	litest_assert(type != LIBINPUT_EVENT_NONE);
4155
4156	libinput_dispatch(li);
4157	event = libinput_get_event(li);
4158	litest_assert_notnull(event);
4159
4160	while (event) {
4161		litest_assert_event_type(event, type);
4162		libinput_event_destroy(event);
4163		libinput_dispatch(li);
4164		event = libinput_get_event(li);
4165	}
4166}
4167
4168void
4169litest_assert_only_axis_events(struct libinput *li,
4170			       enum libinput_event_type axis_type)
4171{
4172	struct libinput_event *event;
4173
4174	litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
4175		      axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
4176		      axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
4177
4178	libinput_dispatch(li);
4179	event = libinput_get_event(li);
4180	litest_assert_notnull(event);
4181
4182	while (event) {
4183		litest_assert_event_type_is_one_of(event,
4184						   LIBINPUT_EVENT_POINTER_AXIS,
4185						   axis_type);
4186		libinput_event_destroy(event);
4187		libinput_dispatch(li);
4188		event = libinput_get_event(li);
4189	}
4190}
4191
4192void
4193litest_assert_no_typed_events(struct libinput *li,
4194			      enum libinput_event_type type)
4195{
4196	struct libinput_event *event;
4197
4198	litest_assert(type != LIBINPUT_EVENT_NONE);
4199
4200	libinput_dispatch(li);
4201	event = libinput_get_event(li);
4202
4203	while (event) {
4204		litest_assert_int_ne(libinput_event_get_type(event),
4205                                     type);
4206		libinput_event_destroy(event);
4207		libinput_dispatch(li);
4208		event = libinput_get_event(li);
4209	}
4210}
4211
4212void
4213litest_assert_touch_sequence(struct libinput *li)
4214{
4215	struct libinput_event *event;
4216	struct libinput_event_touch *tev;
4217	int slot;
4218
4219	event = libinput_get_event(li);
4220	tev = litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_DOWN);
4221	slot = libinput_event_touch_get_slot(tev);
4222	libinput_event_destroy(event);
4223
4224	event = libinput_get_event(li);
4225	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
4226	libinput_event_destroy(event);
4227
4228	event = libinput_get_event(li);
4229	do {
4230		tev = litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_MOTION);
4231		litest_assert_int_eq(slot, libinput_event_touch_get_slot(tev));
4232		libinput_event_destroy(event);
4233
4234		event = libinput_get_event(li);
4235		litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
4236		libinput_event_destroy(event);
4237
4238		event = libinput_get_event(li);
4239		litest_assert_notnull(event);
4240	} while (libinput_event_get_type(event) != LIBINPUT_EVENT_TOUCH_UP);
4241
4242	tev = litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_UP);
4243	litest_assert_int_eq(slot, libinput_event_touch_get_slot(tev));
4244	libinput_event_destroy(event);
4245	event = libinput_get_event(li);
4246	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
4247	libinput_event_destroy(event);
4248}
4249
4250void
4251litest_assert_touch_motion_frame(struct libinput *li)
4252{
4253	struct libinput_event *event;
4254
4255	/* expect at least one, but maybe more */
4256	event = libinput_get_event(li);
4257	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_MOTION);
4258	libinput_event_destroy(event);
4259
4260	event = libinput_get_event(li);
4261	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
4262	libinput_event_destroy(event);
4263
4264	event = libinput_get_event(li);
4265	while (event) {
4266		litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_MOTION);
4267		libinput_event_destroy(event);
4268
4269		event = libinput_get_event(li);
4270		litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
4271		libinput_event_destroy(event);
4272
4273		event = libinput_get_event(li);
4274	}
4275}
4276
4277void
4278litest_assert_touch_down_frame(struct libinput *li)
4279{
4280	struct libinput_event *event;
4281
4282	event = libinput_get_event(li);
4283	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_DOWN);
4284	libinput_event_destroy(event);
4285
4286	event = libinput_get_event(li);
4287	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
4288	libinput_event_destroy(event);
4289}
4290
4291void
4292litest_assert_touch_up_frame(struct libinput *li)
4293{
4294	struct libinput_event *event;
4295
4296	event = libinput_get_event(li);
4297	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_UP);
4298	libinput_event_destroy(event);
4299
4300	event = libinput_get_event(li);
4301	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
4302	libinput_event_destroy(event);
4303}
4304
4305void
4306litest_assert_touch_cancel(struct libinput *li)
4307{
4308	struct libinput_event *event;
4309
4310	event = libinput_get_event(li);
4311	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_CANCEL);
4312	libinput_event_destroy(event);
4313
4314	event = libinput_get_event(li);
4315	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
4316	libinput_event_destroy(event);
4317}
4318
4319void
4320litest_timeout_tap(void)
4321{
4322	msleep(300);
4323}
4324
4325void
4326litest_timeout_tapndrag(void)
4327{
4328	msleep(520);
4329}
4330
4331void
4332litest_timeout_debounce(void)
4333{
4334	msleep(30);
4335}
4336
4337void
4338litest_timeout_softbuttons(void)
4339{
4340	msleep(300);
4341}
4342
4343void
4344litest_timeout_buttonscroll(void)
4345{
4346	msleep(300);
4347}
4348
4349void
4350litest_timeout_finger_switch(void)
4351{
4352	msleep(120);
4353}
4354
4355void
4356litest_timeout_wheel_scroll(void)
4357{
4358	msleep(600);
4359}
4360
4361void
4362litest_timeout_edgescroll(void)
4363{
4364	msleep(300);
4365}
4366
4367void
4368litest_timeout_middlebutton(void)
4369{
4370	msleep(70);
4371}
4372
4373void
4374litest_timeout_dwt_short(void)
4375{
4376	msleep(220);
4377}
4378
4379void
4380litest_timeout_dwt_long(void)
4381{
4382	msleep(520);
4383}
4384
4385void
4386litest_timeout_gesture(void)
4387{
4388	msleep(120);
4389}
4390
4391void
4392litest_timeout_gesture_scroll(void)
4393{
4394	msleep(180);
4395}
4396
4397void
4398litest_timeout_gesture_hold(void)
4399{
4400	msleep(300);
4401}
4402
4403void
4404litest_timeout_gesture_quick_hold(void)
4405{
4406	msleep(60);
4407}
4408
4409void
4410litest_timeout_trackpoint(void)
4411{
4412	msleep(320);
4413}
4414
4415void
4416litest_timeout_tablet_proxout(void)
4417{
4418	msleep(170);
4419}
4420
4421void
4422litest_timeout_touch_arbitration(void)
4423{
4424	msleep(100);
4425}
4426
4427void
4428litest_timeout_hysteresis(void)
4429{
4430	msleep(90);
4431}
4432
4433void
4434litest_push_event_frame(struct litest_device *dev)
4435{
4436	litest_assert_int_ge(dev->skip_ev_syn, 0);
4437	dev->skip_ev_syn++;
4438}
4439
4440void
4441litest_pop_event_frame(struct litest_device *dev)
4442{
4443	litest_assert_int_gt(dev->skip_ev_syn, 0);
4444	dev->skip_ev_syn--;
4445	if (dev->skip_ev_syn == 0)
4446		litest_event(dev, EV_SYN, SYN_REPORT, 0);
4447}
4448
4449void
4450litest_filter_event(struct litest_device *dev,
4451		    unsigned int type,
4452		    unsigned int code)
4453{
4454	libevdev_disable_event_code(dev->evdev, type, code);
4455}
4456
4457void
4458litest_unfilter_event(struct litest_device *dev,
4459		      unsigned int type,
4460		      unsigned int code)
4461{
4462	/* would need an non-NULL argument for re-enabling, so simply abort
4463	 * until we need to be more sophisticated */
4464	litest_assert_int_ne(type, (unsigned int)EV_ABS);
4465
4466	libevdev_enable_event_code(dev->evdev, type, code, NULL);
4467}
4468
4469static void
4470send_abs_xy(struct litest_device *d, double x, double y)
4471{
4472	struct input_event e;
4473	int val;
4474
4475	e.type = EV_ABS;
4476	e.code = ABS_X;
4477	e.value = LITEST_AUTO_ASSIGN;
4478	val = litest_auto_assign_value(d, &e, 0, x, y, NULL, true);
4479	litest_event(d, EV_ABS, ABS_X, val);
4480
4481	e.code = ABS_Y;
4482	val = litest_auto_assign_value(d, &e, 0, x, y, NULL, true);
4483	litest_event(d, EV_ABS, ABS_Y, val);
4484}
4485
4486static void
4487send_abs_mt_xy(struct litest_device *d, double x, double y)
4488{
4489	struct input_event e;
4490	int val;
4491
4492	e.type = EV_ABS;
4493	e.code = ABS_MT_POSITION_X;
4494	e.value = LITEST_AUTO_ASSIGN;
4495	val = litest_auto_assign_value(d, &e, 0, x, y, NULL, true);
4496	litest_event(d, EV_ABS, ABS_MT_POSITION_X, val);
4497
4498	e.code = ABS_MT_POSITION_Y;
4499	e.value = LITEST_AUTO_ASSIGN;
4500	val = litest_auto_assign_value(d, &e, 0, x, y, NULL, true);
4501	litest_event(d, EV_ABS, ABS_MT_POSITION_Y, val);
4502}
4503
4504void
4505litest_semi_mt_touch_down(struct litest_device *d,
4506			  struct litest_semi_mt *semi_mt,
4507			  unsigned int slot,
4508			  double x, double y)
4509{
4510	double t, l, r = 0, b = 0; /* top, left, right, bottom */
4511
4512	if (d->ntouches_down > 2 || slot > 1)
4513		return;
4514
4515	if (d->ntouches_down == 1) {
4516		l = x;
4517		t = y;
4518	} else {
4519		int other = (slot + 1) % 2;
4520		l = min(x, semi_mt->touches[other].x);
4521		t = min(y, semi_mt->touches[other].y);
4522		r = max(x, semi_mt->touches[other].x);
4523		b = max(y, semi_mt->touches[other].y);
4524	}
4525
4526	send_abs_xy(d, l, t);
4527
4528	litest_event(d, EV_ABS, ABS_MT_SLOT, 0);
4529
4530	if (d->ntouches_down == 1)
4531		litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, ++semi_mt->tracking_id);
4532
4533	send_abs_mt_xy(d, l, t);
4534
4535	if (d->ntouches_down == 2) {
4536		litest_event(d, EV_ABS, ABS_MT_SLOT, 1);
4537		litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, ++semi_mt->tracking_id);
4538
4539		send_abs_mt_xy(d, r, b);
4540	}
4541
4542	litest_event(d, EV_SYN, SYN_REPORT, 0);
4543
4544	semi_mt->touches[slot].x = x;
4545	semi_mt->touches[slot].y = y;
4546}
4547
4548void
4549litest_semi_mt_touch_move(struct litest_device *d,
4550			  struct litest_semi_mt *semi_mt,
4551			  unsigned int slot,
4552			  double x, double y)
4553{
4554	double t, l, r = 0, b = 0; /* top, left, right, bottom */
4555
4556	if (d->ntouches_down > 2 || slot > 1)
4557		return;
4558
4559	if (d->ntouches_down == 1) {
4560		l = x;
4561		t = y;
4562	} else {
4563		int other = (slot + 1) % 2;
4564		l = min(x, semi_mt->touches[other].x);
4565		t = min(y, semi_mt->touches[other].y);
4566		r = max(x, semi_mt->touches[other].x);
4567		b = max(y, semi_mt->touches[other].y);
4568	}
4569
4570	send_abs_xy(d, l, t);
4571
4572	litest_event(d, EV_ABS, ABS_MT_SLOT, 0);
4573	send_abs_mt_xy(d, l, t);
4574
4575	if (d->ntouches_down == 2) {
4576		litest_event(d, EV_ABS, ABS_MT_SLOT, 1);
4577		send_abs_mt_xy(d, r, b);
4578	}
4579
4580	litest_event(d, EV_SYN, SYN_REPORT, 0);
4581
4582	semi_mt->touches[slot].x = x;
4583	semi_mt->touches[slot].y = y;
4584}
4585
4586void
4587litest_semi_mt_touch_up(struct litest_device *d,
4588			struct litest_semi_mt *semi_mt,
4589			unsigned int slot)
4590{
4591	/* note: ntouches_down is decreased before we get here */
4592	if (d->ntouches_down >= 2 || slot > 1)
4593		return;
4594
4595	litest_event(d, EV_ABS, ABS_MT_SLOT, d->ntouches_down);
4596	litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, -1);
4597
4598	/* if we have one finger left, send x/y coords for that finger left.
4599	   this is likely to happen with a real touchpad */
4600	if (d->ntouches_down == 1) {
4601		int other = (slot + 1) % 2;
4602		send_abs_xy(d, semi_mt->touches[other].x, semi_mt->touches[other].y);
4603		litest_event(d, EV_ABS, ABS_MT_SLOT, 0);
4604		send_abs_mt_xy(d, semi_mt->touches[other].x, semi_mt->touches[other].y);
4605	}
4606
4607	litest_event(d, EV_SYN, SYN_REPORT, 0);
4608}
4609
4610enum litest_mode {
4611	LITEST_MODE_ERROR,
4612	LITEST_MODE_TEST,
4613	LITEST_MODE_LIST,
4614};
4615
4616static inline enum litest_mode
4617litest_parse_argv(int argc, char **argv)
4618{
4619	enum {
4620		OPT_FILTER_TEST,
4621		OPT_FILTER_DEVICE,
4622		OPT_FILTER_GROUP,
4623		OPT_FILTER_DEVICELESS,
4624		OPT_XML_PREFIX,
4625		OPT_JOBS,
4626		OPT_LIST,
4627		OPT_VERBOSE,
4628	};
4629	static const struct option opts[] = {
4630		{ "filter-test", 1, 0, OPT_FILTER_TEST },
4631		{ "filter-device", 1, 0, OPT_FILTER_DEVICE },
4632		{ "filter-group", 1, 0, OPT_FILTER_GROUP },
4633		{ "filter-deviceless", 0, 0, OPT_FILTER_DEVICELESS },
4634		{ "xml-output", 1, 0, OPT_XML_PREFIX },
4635		{ "jobs", 1, 0, OPT_JOBS },
4636		{ "list", 0, 0, OPT_LIST },
4637		{ "verbose", 0, 0, OPT_VERBOSE },
4638		{ "help", 0, 0, 'h'},
4639		{ 0, 0, 0, 0}
4640	};
4641	enum {
4642		JOBS_DEFAULT,
4643		JOBS_SINGLE,
4644		JOBS_CUSTOM
4645	} want_jobs = JOBS_DEFAULT;
4646	char *builddir;
4647	char *jobs_env;
4648
4649	/* If we are not running from the builddir, we assume we're running
4650	 * against the system as installed */
4651	builddir = builddir_lookup();
4652	if (!builddir)
4653		use_system_rules_quirks = true;
4654	free(builddir);
4655
4656	if (in_debugger)
4657		want_jobs = JOBS_SINGLE;
4658
4659	if ((jobs_env = getenv("LITEST_JOBS"))) {
4660		if (!safe_atoi(jobs_env, &jobs)) {
4661			fprintf(stderr, "LITEST_JOBS environment variable must be positive integer\n");
4662			exit(EXIT_FAILURE);
4663		}
4664	}
4665
4666	while(1) {
4667		int c;
4668		int option_index = 0;
4669
4670		c = getopt_long(argc, argv, "j:", opts, &option_index);
4671		if (c == -1)
4672			break;
4673		switch(c) {
4674		default:
4675		case 'h':
4676			printf("Usage: %s [--verbose] [--jobs] [--filter-...]\n"
4677			       "\n"
4678			       "Options:\n"
4679			       "    --filter-test=.... \n"
4680			       "          Glob to filter on test names\n"
4681			       "    --filter-device=.... \n"
4682			       "          Glob to filter on device names\n"
4683			       "    --filter-group=.... \n"
4684			       "          Glob to filter on test groups\n"
4685			       "    --filter-deviceless=.... \n"
4686			       "          Glob to filter on tests that do not create test devices\n"
4687			       "    --xml-output=/path/to/file-XXXXXXX.xml\n"
4688			       "          Write test output in libcheck's XML format\n"
4689			       "          to the given files. The file must match the format\n"
4690			       "          prefix-XXXXXX.xml and only the prefix is your choice.\n"
4691			       "    --verbose\n"
4692			       "          Enable verbose output\n"
4693			       "    --jobs 8\n"
4694			       "          Number of parallel test suites to run (default: 8).\n"
4695			       "	  This overrides the LITEST_JOBS environment variable.\n"
4696			       "    --list\n"
4697			       "          List all tests\n"
4698			       "\n"
4699			       "See the libinput-test-suite(1) man page for details.\n",
4700			       program_invocation_short_name);
4701			exit(c != 'h');
4702			break;
4703		case OPT_FILTER_TEST:
4704			filter_test = optarg;
4705			if (want_jobs == JOBS_DEFAULT)
4706				want_jobs = JOBS_SINGLE;
4707			break;
4708		case OPT_FILTER_DEVICE:
4709			filter_device = optarg;
4710			if (want_jobs == JOBS_DEFAULT)
4711				want_jobs = JOBS_SINGLE;
4712			break;
4713		case OPT_FILTER_GROUP:
4714			filter_group = optarg;
4715			break;
4716		case OPT_XML_PREFIX:
4717			xml_prefix = optarg;
4718			break;
4719		case 'j':
4720		case OPT_JOBS:
4721			jobs = atoi(optarg);
4722			want_jobs = JOBS_CUSTOM;
4723			break;
4724		case OPT_LIST:
4725			return LITEST_MODE_LIST;
4726		case OPT_VERBOSE:
4727			verbose = true;
4728			break;
4729		case OPT_FILTER_DEVICELESS:
4730			run_deviceless = true;
4731			break;
4732		}
4733	}
4734
4735	if (want_jobs == JOBS_SINGLE)
4736		jobs = 1;
4737
4738	return LITEST_MODE_TEST;
4739}
4740
4741#ifndef LITEST_NO_MAIN
4742static bool
4743is_debugger_attached(void)
4744{
4745	int status;
4746	bool rc;
4747	int pid = fork();
4748
4749	if (pid == -1)
4750		return 0;
4751
4752	if (pid == 0) {
4753		int ppid = getppid();
4754		if (ptrace(PTRACE_ATTACH, ppid, NULL, 0) == 0) {
4755			waitpid(ppid, NULL, 0);
4756			ptrace(PTRACE_CONT, ppid, NULL, 0);
4757			ptrace(PTRACE_DETACH, ppid, NULL, 0);
4758			rc = false;
4759		} else {
4760			rc = true;
4761		}
4762		_exit(rc);
4763	} else {
4764		waitpid(pid, &status, 0);
4765		rc = WEXITSTATUS(status);
4766	}
4767
4768	return !!rc;
4769}
4770
4771static void
4772litest_list_tests(struct list *tests)
4773{
4774	struct suite *s;
4775	const char *last_test_name = NULL;
4776
4777	list_for_each(s, tests, node) {
4778		struct test *t;
4779		printf("%s:\n", s->name);
4780		list_for_each(t, &s->tests, node) {
4781			if (!last_test_name ||
4782			    !streq(last_test_name, t->name))
4783				printf("	%s:\n", t->name);
4784
4785			last_test_name = t->name;
4786
4787			printf("		%s\n", t->devname);
4788		}
4789	}
4790}
4791
4792extern const struct test_device __start_test_section, __stop_test_section;
4793
4794static void
4795litest_init_test_devices(void)
4796{
4797	const struct test_device *t;
4798
4799	list_init(&devices);
4800
4801	for (t = &__start_test_section; t < &__stop_test_section; t++)
4802		list_append(&devices, &t->device->node);
4803}
4804
4805extern const struct test_collection __start_test_collection_section,
4806				    __stop_test_collection_section;
4807
4808static void
4809setup_tests(void)
4810{
4811	const struct test_collection *c;
4812
4813	for (c = &__start_test_collection_section;
4814	     c < &__stop_test_collection_section;
4815	     c++) {
4816		c->setup();
4817	}
4818}
4819
4820static int
4821check_device_access(void)
4822{
4823	if (getuid() != 0) {
4824		fprintf(stderr,
4825			"%s must be run as root.\n",
4826			program_invocation_short_name);
4827		return 77;
4828	}
4829
4830	if (access("/dev/uinput", F_OK) == -1 &&
4831	    access("/dev/input/uinput", F_OK) == -1) {
4832		fprintf(stderr,
4833			"uinput device is missing, skipping tests.\n");
4834		return 77;
4835	}
4836
4837	return 0;
4838}
4839
4840static int
4841disable_tty(void)
4842{
4843	int tty_mode = -1;
4844
4845	/* If we're running 'normally' on the VT, disable the keyboard to
4846	 * avoid messing up our host. But if we're inside gdb or running
4847	 * without forking, leave it as-is.
4848	 */
4849	if (!run_deviceless &&
4850	    jobs > 1 &&
4851	    !in_debugger &&
4852	    getenv("CK_FORK") == NULL &&
4853	    isatty(STDIN_FILENO) &&
4854	    ioctl(STDIN_FILENO, KDGKBMODE, &tty_mode) == 0) {
4855#ifdef __linux__
4856		ioctl(STDIN_FILENO, KDSKBMODE, K_OFF);
4857#elif __FreeBSD__
4858		ioctl(STDIN_FILENO, KDSKBMODE, K_RAW);
4859
4860		/* Put the tty into raw mode */
4861		struct termios tios;
4862		if (tcgetattr(STDIN_FILENO, &tios))
4863				fprintf(stderr, "Failed to get terminal attribute: %d - %s\n", errno, strerror(errno));
4864		cfmakeraw(&tios);
4865		if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios))
4866				fprintf(stderr, "Failed to set terminal attribute: %d - %s\n", errno, strerror(errno));
4867#endif
4868	}
4869
4870	return tty_mode;
4871}
4872
4873int
4874main(int argc, char **argv)
4875{
4876	const struct rlimit corelimit = { 0, 0 };
4877	enum litest_mode mode;
4878	int tty_mode = -1;
4879	int failed_tests;
4880	int rc;
4881	const char *meson_testthreads;
4882
4883	in_debugger = is_debugger_attached();
4884	if (in_debugger || RUNNING_ON_VALGRIND)
4885		setenv("CK_FORK", "no", 0);
4886
4887	if ((meson_testthreads = getenv("MESON_TESTTHREADS")) == NULL ||
4888	     !safe_atoi(meson_testthreads, &jobs)) {
4889		jobs = get_nprocs();
4890		if (!RUNNING_ON_VALGRIND)
4891			jobs *= 2;
4892	}
4893
4894	mode = litest_parse_argv(argc, argv);
4895	if (mode == LITEST_MODE_ERROR)
4896		return EXIT_FAILURE;
4897
4898	litest_init_test_devices();
4899	list_init(&all_tests);
4900	setup_tests();
4901	if (mode == LITEST_MODE_LIST) {
4902		litest_list_tests(&all_tests);
4903		return EXIT_SUCCESS;
4904	}
4905
4906	if (!run_deviceless && (rc = check_device_access()) != 0)
4907		return rc;
4908
4909	setenv("CK_DEFAULT_TIMEOUT", "30", 0);
4910	setenv("LIBINPUT_RUNNING_TEST_SUITE", "1", 1);
4911
4912	if (setrlimit(RLIMIT_CORE, &corelimit) != 0)
4913		perror("WARNING: Core dumps not disabled");
4914
4915	tty_mode = disable_tty();
4916
4917	failed_tests = litest_run(argc, argv);
4918
4919	if (tty_mode != -1) {
4920		ioctl(STDIN_FILENO, KDSKBMODE, tty_mode);
4921#ifdef __FreeBSD__
4922		/* Put the tty into "sane" mode */
4923		struct termios tios;
4924		if (tcgetattr(STDIN_FILENO, &tios))
4925				fprintf(stderr, "Failed to get terminal attribute: %d - %s\n", errno, strerror(errno));
4926		cfmakesane(&tios);
4927		if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios))
4928				fprintf(stderr, "Failed to set terminal attribute: %d - %s\n", errno, strerror(errno));
4929#endif
4930	}
4931
4932	return min(failed_tests, 255);
4933}
4934#endif
4935