xref: /third_party/libinput/test/test-device.c (revision a46c0ec8)
1/*
2 * Copyright © 2014 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include <config.h>
25
26#include <check.h>
27#include <errno.h>
28#include <fcntl.h>
29#include <libinput.h>
30#include <libudev.h>
31#include <unistd.h>
32
33#include "litest.h"
34#include "libinput-util.h"
35
36START_TEST(device_sendevents_config)
37{
38	struct litest_device *dev = litest_current_device();
39	struct libinput_device *device;
40	uint32_t modes;
41
42	device = dev->libinput_device;
43
44	modes = libinput_device_config_send_events_get_modes(device);
45	ck_assert_int_eq(modes,
46			 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
47}
48END_TEST
49
50START_TEST(device_sendevents_config_invalid)
51{
52	struct litest_device *dev = litest_current_device();
53	struct libinput_device *device;
54	enum libinput_config_status status;
55
56	device = dev->libinput_device;
57
58	status = libinput_device_config_send_events_set_mode(device,
59			     LIBINPUT_CONFIG_SEND_EVENTS_DISABLED | bit(4));
60	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
61}
62END_TEST
63
64START_TEST(device_sendevents_config_touchpad)
65{
66	struct litest_device *dev = litest_current_device();
67	struct libinput_device *device;
68	uint32_t modes, expected;
69
70	expected = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
71
72	/* The wacom devices in the test suite are external */
73	if (libevdev_get_id_vendor(dev->evdev) != VENDOR_ID_WACOM &&
74	    !litest_touchpad_is_external(dev))
75		expected |=
76			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
77
78	device = dev->libinput_device;
79
80	modes = libinput_device_config_send_events_get_modes(device);
81	ck_assert_int_eq(modes, expected);
82}
83END_TEST
84
85START_TEST(device_sendevents_config_touchpad_superset)
86{
87	struct litest_device *dev = litest_current_device();
88	struct libinput_device *device;
89	enum libinput_config_status status;
90	uint32_t modes;
91
92	/* The wacom devices in the test suite are external */
93	if (libevdev_get_id_vendor(dev->evdev) == VENDOR_ID_WACOM ||
94	    litest_touchpad_is_external(dev))
95		return;
96
97	device = dev->libinput_device;
98
99	modes = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED |
100		LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
101
102	status = libinput_device_config_send_events_set_mode(device,
103							     modes);
104	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
105
106	/* DISABLED supersedes the rest, expect the rest to be dropped */
107	modes = libinput_device_config_send_events_get_mode(device);
108	ck_assert_int_eq(modes, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
109}
110END_TEST
111
112START_TEST(device_sendevents_config_default)
113{
114	struct litest_device *dev = litest_current_device();
115	struct libinput_device *device;
116	uint32_t mode;
117
118	device = dev->libinput_device;
119
120	mode = libinput_device_config_send_events_get_mode(device);
121	ck_assert_int_eq(mode,
122			 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
123
124	mode = libinput_device_config_send_events_get_default_mode(device);
125	ck_assert_int_eq(mode,
126			 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
127}
128END_TEST
129
130START_TEST(device_disable)
131{
132	struct litest_device *dev = litest_current_device();
133	struct libinput *li = dev->libinput;
134	struct libinput_device *device;
135	enum libinput_config_status status;
136	struct libinput_event *event;
137	struct litest_device *tmp;
138
139	device = dev->libinput_device;
140
141	litest_drain_events(li);
142
143	status = libinput_device_config_send_events_set_mode(device,
144			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
145	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
146
147	/* no event from disabling */
148	litest_assert_empty_queue(li);
149
150	/* no event from disabled device */
151	litest_event(dev, EV_REL, REL_X, 10);
152	litest_event(dev, EV_SYN, SYN_REPORT, 0);
153	litest_assert_empty_queue(li);
154
155	/* create a new device so the resumed fd isn't the same as the
156	   suspended one */
157	tmp = litest_add_device(li, LITEST_KEYBOARD);
158	ck_assert_notnull(tmp);
159	litest_drain_events(li);
160
161	/* no event from resuming */
162	status = libinput_device_config_send_events_set_mode(device,
163			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
164	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
165	litest_assert_empty_queue(li);
166
167	/* event from re-enabled device */
168	litest_event(dev, EV_REL, REL_X, 10);
169	litest_event(dev, EV_SYN, SYN_REPORT, 0);
170
171	libinput_dispatch(li);
172	event = libinput_get_event(li);
173	ck_assert_notnull(event);
174	ck_assert_int_eq(libinput_event_get_type(event),
175			 LIBINPUT_EVENT_POINTER_MOTION);
176	libinput_event_destroy(event);
177
178	litest_delete_device(tmp);
179}
180END_TEST
181
182START_TEST(device_disable_tablet)
183{
184	struct litest_device *dev = litest_current_device();
185	struct libinput *li = dev->libinput;
186	struct libinput_device *device;
187	enum libinput_config_status status;
188	struct axis_replacement axes[] = {
189		{ ABS_DISTANCE, 10 },
190		{ ABS_PRESSURE, 0 },
191		{ -1, -1 }
192	};
193
194	device = dev->libinput_device;
195
196	litest_drain_events(li);
197
198	status = libinput_device_config_send_events_set_mode(device,
199			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
200	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
201
202	/* no event from disabling */
203	litest_assert_empty_queue(li);
204
205	litest_tablet_proximity_in(dev, 60, 60, axes);
206	for (int i = 60; i < 70; i++) {
207		litest_tablet_motion(dev, i, i, axes);
208		libinput_dispatch(li);
209	}
210	litest_tablet_proximity_out(dev);
211
212	litest_assert_empty_queue(li);
213
214	/* no event from resuming */
215	status = libinput_device_config_send_events_set_mode(device,
216			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
217	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
218	litest_assert_empty_queue(li);
219}
220END_TEST
221
222START_TEST(device_disable_touchpad)
223{
224	struct litest_device *dev = litest_current_device();
225	struct libinput *li = dev->libinput;
226	struct libinput_device *device;
227	enum libinput_config_status status;
228
229	device = dev->libinput_device;
230
231	litest_drain_events(li);
232
233	status = libinput_device_config_send_events_set_mode(device,
234			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
235	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
236
237	/* no event from disabling */
238	litest_assert_empty_queue(li);
239
240	litest_touch_down(dev, 0, 50, 50);
241	litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10);
242	litest_touch_up(dev, 0);
243
244	litest_assert_empty_queue(li);
245
246	/* no event from resuming */
247	status = libinput_device_config_send_events_set_mode(device,
248			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
249	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
250	litest_assert_empty_queue(li);
251}
252END_TEST
253
254START_TEST(device_disable_touch)
255{
256	struct litest_device *dev = litest_current_device();
257	struct libinput *li = dev->libinput;
258	struct libinput_device *device;
259	enum libinput_config_status status;
260
261	device = dev->libinput_device;
262
263	litest_drain_events(li);
264
265	status = libinput_device_config_send_events_set_mode(device,
266			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
267	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
268
269	/* no event from disabling */
270	litest_assert_empty_queue(li);
271
272	litest_touch_down(dev, 0, 50, 50);
273	litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10);
274	litest_touch_up(dev, 0);
275
276	litest_assert_empty_queue(li);
277
278	/* no event from resuming */
279	status = libinput_device_config_send_events_set_mode(device,
280			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
281	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
282	litest_assert_empty_queue(li);
283}
284END_TEST
285
286START_TEST(device_disable_touch_during_touch)
287{
288	struct litest_device *dev = litest_current_device();
289	struct libinput *li = dev->libinput;
290	struct libinput_device *device;
291	enum libinput_config_status status;
292	struct libinput_event *event;
293
294	device = dev->libinput_device;
295
296	litest_touch_down(dev, 0, 50, 50);
297	litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10);
298	litest_drain_events(li);
299
300	status = libinput_device_config_send_events_set_mode(device,
301			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
302	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
303
304	/* after disabling sendevents we require a touch up */
305	libinput_dispatch(li);
306	event = libinput_get_event(li);
307	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_CANCEL);
308	libinput_event_destroy(event);
309
310	event = libinput_get_event(li);
311	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
312	libinput_event_destroy(event);
313
314	litest_assert_empty_queue(li);
315
316	litest_touch_move_to(dev, 0, 90, 90, 50, 50, 10);
317	litest_touch_up(dev, 0);
318
319	litest_touch_down(dev, 0, 50, 50);
320	litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10);
321	litest_touch_up(dev, 0);
322
323	litest_assert_empty_queue(li);
324
325	/* no event from resuming */
326	status = libinput_device_config_send_events_set_mode(device,
327			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
328	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
329	litest_assert_empty_queue(li);
330}
331END_TEST
332
333START_TEST(device_disable_events_pending)
334{
335	struct litest_device *dev = litest_current_device();
336	struct libinput *li = dev->libinput;
337	struct libinput_device *device;
338	enum libinput_config_status status;
339	struct libinput_event *event;
340	int i;
341
342	device = dev->libinput_device;
343
344	litest_drain_events(li);
345
346	/* put a couple of events in the queue, enough to
347	   feed the ptraccel trackers */
348	for (i = 0; i < 10; i++) {
349		litest_event(dev, EV_REL, REL_X, 10);
350		litest_event(dev, EV_SYN, SYN_REPORT, 0);
351	}
352	libinput_dispatch(li);
353
354	status = libinput_device_config_send_events_set_mode(device,
355			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
356	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
357
358	/* expect above events */
359	litest_wait_for_event(li);
360	while ((event = libinput_get_event(li)) != NULL) {
361	       ck_assert_int_eq(libinput_event_get_type(event),
362				LIBINPUT_EVENT_POINTER_MOTION);
363	       libinput_event_destroy(event);
364       }
365}
366END_TEST
367
368START_TEST(device_double_disable)
369{
370	struct litest_device *dev = litest_current_device();
371	struct libinput *li = dev->libinput;
372	struct libinput_device *device;
373	enum libinput_config_status status;
374
375	device = dev->libinput_device;
376
377	litest_drain_events(li);
378
379	status = libinput_device_config_send_events_set_mode(device,
380			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
381	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
382
383	status = libinput_device_config_send_events_set_mode(device,
384			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
385	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
386
387	litest_assert_empty_queue(li);
388}
389END_TEST
390
391START_TEST(device_double_enable)
392{
393	struct litest_device *dev = litest_current_device();
394	struct libinput *li = dev->libinput;
395	struct libinput_device *device;
396	enum libinput_config_status status;
397
398	device = dev->libinput_device;
399
400	litest_drain_events(li);
401
402	status = libinput_device_config_send_events_set_mode(device,
403			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
404	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
405
406	status = libinput_device_config_send_events_set_mode(device,
407			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
408	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
409
410	litest_assert_empty_queue(li);
411}
412END_TEST
413
414START_TEST(device_reenable_syspath_changed)
415{
416	struct libinput *li;
417	struct litest_device *litest_device;
418	struct libinput_device *device1;
419	enum libinput_config_status status;
420	struct libinput_event *event;
421
422	li = litest_create_context();
423	litest_device = litest_add_device(li, LITEST_MOUSE);
424	device1 = litest_device->libinput_device;
425
426	libinput_device_ref(device1);
427	status = libinput_device_config_send_events_set_mode(device1,
428			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
429	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
430
431	litest_drain_events(li);
432
433	litest_delete_device(litest_device);
434	litest_drain_events(li);
435
436	litest_device = litest_add_device(li, LITEST_MOUSE);
437
438	status = libinput_device_config_send_events_set_mode(device1,
439			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
440	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
441
442	/* can't really check for much here, other than that if we pump
443	   events through libinput, none of them should be from the first
444	   device */
445	litest_event(litest_device, EV_REL, REL_X, 1);
446	litest_event(litest_device, EV_REL, REL_Y, 1);
447	litest_event(litest_device, EV_SYN, SYN_REPORT, 0);
448
449	libinput_dispatch(li);
450	while ((event = libinput_get_event(li))) {
451		ck_assert(libinput_event_get_device(event) != device1);
452		libinput_event_destroy(event);
453	}
454
455	litest_delete_device(litest_device);
456	libinput_device_unref(device1);
457	litest_destroy_context(li);
458}
459END_TEST
460
461START_TEST(device_reenable_device_removed)
462{
463	struct libinput *li;
464	struct litest_device *litest_device;
465	struct libinput_device *device;
466	enum libinput_config_status status;
467
468	li = litest_create_context();
469	litest_device = litest_add_device(li, LITEST_MOUSE);
470	device = litest_device->libinput_device;
471
472	libinput_device_ref(device);
473	status = libinput_device_config_send_events_set_mode(device,
474			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
475	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
476
477	litest_drain_events(li);
478
479	litest_delete_device(litest_device);
480	litest_drain_events(li);
481
482	status = libinput_device_config_send_events_set_mode(device,
483			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
484	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
485
486	/* can't really check for much here, this really just exercises the
487	   code path. */
488	litest_assert_empty_queue(li);
489
490	libinput_device_unref(device);
491	litest_destroy_context(li);
492}
493END_TEST
494
495START_TEST(device_disable_release_buttons)
496{
497	struct litest_device *dev = litest_current_device();
498	struct libinput *li = dev->libinput;
499	struct libinput_device *device;
500	struct libinput_event *event;
501	struct libinput_event_pointer *ptrevent;
502	enum libinput_config_status status;
503
504	device = dev->libinput_device;
505
506	litest_button_click_debounced(dev, li, BTN_LEFT, true);
507	litest_drain_events(li);
508
509	status = libinput_device_config_send_events_set_mode(device,
510			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
511	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
512
513	litest_wait_for_event(li);
514	event = libinput_get_event(li);
515
516	ck_assert_int_eq(libinput_event_get_type(event),
517			 LIBINPUT_EVENT_POINTER_BUTTON);
518	ptrevent = libinput_event_get_pointer_event(event);
519	ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent),
520			 BTN_LEFT);
521	ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent),
522			 LIBINPUT_BUTTON_STATE_RELEASED);
523
524	libinput_event_destroy(event);
525	litest_assert_empty_queue(li);
526}
527END_TEST
528
529START_TEST(device_disable_release_keys)
530{
531	struct litest_device *dev = litest_current_device();
532	struct libinput *li = dev->libinput;
533	struct libinput_device *device;
534	struct libinput_event *event;
535	struct libinput_event_keyboard *kbdevent;
536	enum libinput_config_status status;
537
538	device = dev->libinput_device;
539
540	litest_keyboard_key(dev, KEY_A, true);
541	litest_drain_events(li);
542
543	status = libinput_device_config_send_events_set_mode(device,
544			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
545	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
546
547	litest_wait_for_event(li);
548	event = libinput_get_event(li);
549
550	ck_assert_int_eq(libinput_event_get_type(event),
551			 LIBINPUT_EVENT_KEYBOARD_KEY);
552	kbdevent = libinput_event_get_keyboard_event(event);
553	ck_assert_int_eq(libinput_event_keyboard_get_key(kbdevent),
554			 KEY_A);
555	ck_assert_int_eq(libinput_event_keyboard_get_key_state(kbdevent),
556			 LIBINPUT_KEY_STATE_RELEASED);
557
558	libinput_event_destroy(event);
559	litest_assert_empty_queue(li);
560}
561END_TEST
562
563START_TEST(device_disable_release_tap)
564{
565	struct litest_device *dev = litest_current_device();
566	struct libinput *li = dev->libinput;
567	struct libinput_device *device;
568	enum libinput_config_status status;
569
570	device = dev->libinput_device;
571
572	libinput_device_config_tap_set_enabled(device,
573					       LIBINPUT_CONFIG_TAP_ENABLED);
574
575	litest_drain_events(li);
576
577	litest_touch_down(dev, 0, 50, 50);
578	litest_touch_up(dev, 0);
579
580	libinput_dispatch(li);
581
582	status = libinput_device_config_send_events_set_mode(device,
583			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
584	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
585	/* tap happened before suspending, so we still expect the event */
586
587	litest_timeout_tap();
588
589	litest_assert_button_event(li,
590				   BTN_LEFT,
591				   LIBINPUT_BUTTON_STATE_PRESSED);
592	litest_assert_button_event(li,
593				   BTN_LEFT,
594				   LIBINPUT_BUTTON_STATE_RELEASED);
595
596	litest_assert_empty_queue(li);
597
598	/* resume, make sure we don't get anything */
599	status = libinput_device_config_send_events_set_mode(device,
600			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
601	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
602	libinput_dispatch(li);
603	litest_assert_empty_queue(li);
604
605}
606END_TEST
607
608START_TEST(device_disable_release_tap_n_drag)
609{
610	struct litest_device *dev = litest_current_device();
611	struct libinput *li = dev->libinput;
612	struct libinput_device *device;
613	enum libinput_config_status status;
614
615	device = dev->libinput_device;
616
617	libinput_device_config_tap_set_enabled(device,
618					       LIBINPUT_CONFIG_TAP_ENABLED);
619
620	litest_drain_events(li);
621
622	litest_touch_down(dev, 0, 50, 50);
623	litest_touch_up(dev, 0);
624	litest_touch_down(dev, 0, 50, 50);
625	libinput_dispatch(li);
626	litest_timeout_tap();
627	libinput_dispatch(li);
628
629	status = libinput_device_config_send_events_set_mode(device,
630			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
631	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
632
633	libinput_dispatch(li);
634	litest_touch_up(dev, 0);
635
636	litest_assert_button_event(li,
637				   BTN_LEFT,
638				   LIBINPUT_BUTTON_STATE_PRESSED);
639	litest_assert_button_event(li,
640				   BTN_LEFT,
641				   LIBINPUT_BUTTON_STATE_RELEASED);
642
643	litest_assert_empty_queue(li);
644}
645END_TEST
646
647START_TEST(device_disable_release_softbutton)
648{
649	struct litest_device *dev = litest_current_device();
650	struct libinput *li = dev->libinput;
651	struct libinput_device *device;
652	enum libinput_config_status status;
653
654	device = dev->libinput_device;
655
656	litest_drain_events(li);
657
658	litest_touch_down(dev, 0, 90, 90);
659	litest_button_click_debounced(dev, li, BTN_LEFT, true);
660
661	/* make sure softbutton works */
662	litest_assert_button_event(li,
663				   BTN_RIGHT,
664				   LIBINPUT_BUTTON_STATE_PRESSED);
665	/* disable */
666	status = libinput_device_config_send_events_set_mode(device,
667			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
668	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
669
670	litest_assert_button_event(li,
671				   BTN_RIGHT,
672				   LIBINPUT_BUTTON_STATE_RELEASED);
673
674	litest_assert_empty_queue(li);
675
676	litest_button_click_debounced(dev, li, BTN_LEFT, false);
677	litest_touch_up(dev, 0);
678
679	litest_assert_empty_queue(li);
680
681	/* resume, make sure we don't get anything */
682	status = libinput_device_config_send_events_set_mode(device,
683			LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
684	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
685	libinput_dispatch(li);
686	litest_assert_empty_queue(li);
687
688}
689END_TEST
690
691START_TEST(device_disable_topsoftbutton)
692{
693	struct litest_device *dev = litest_current_device();
694	struct litest_device *trackpoint;
695	struct libinput *li = dev->libinput;
696	struct libinput_device *device;
697	enum libinput_config_status status;
698
699	struct libinput_event *event;
700	struct libinput_event_pointer *ptrevent;
701
702	device = dev->libinput_device;
703
704	trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
705
706	status = libinput_device_config_send_events_set_mode(device,
707			LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
708	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
709	litest_drain_events(li);
710
711	litest_touch_down(dev, 0, 90, 10);
712	litest_button_click_debounced(dev, li, BTN_LEFT, true);
713	litest_button_click_debounced(dev, li, BTN_LEFT, false);
714	litest_touch_up(dev, 0);
715
716	litest_wait_for_event(li);
717	event = libinput_get_event(li);
718	ck_assert_int_eq(libinput_event_get_type(event),
719			 LIBINPUT_EVENT_POINTER_BUTTON);
720	ck_assert_ptr_eq(libinput_event_get_device(event),
721			 trackpoint->libinput_device);
722	ptrevent = libinput_event_get_pointer_event(event);
723	ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent),
724			 BTN_RIGHT);
725	ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent),
726			 LIBINPUT_BUTTON_STATE_PRESSED);
727	libinput_event_destroy(event);
728
729	event = libinput_get_event(li);
730	ck_assert_int_eq(libinput_event_get_type(event),
731			 LIBINPUT_EVENT_POINTER_BUTTON);
732	ck_assert_ptr_eq(libinput_event_get_device(event),
733			 trackpoint->libinput_device);
734	ptrevent = libinput_event_get_pointer_event(event);
735	ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent),
736			 BTN_RIGHT);
737	ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent),
738			 LIBINPUT_BUTTON_STATE_RELEASED);
739	libinput_event_destroy(event);
740
741	litest_assert_empty_queue(li);
742
743	litest_delete_device(trackpoint);
744}
745END_TEST
746
747START_TEST(device_ids)
748{
749	struct litest_device *dev = litest_current_device();
750	const char *name;
751	unsigned int pid, vid;
752
753	name = libevdev_get_name(dev->evdev);
754	pid = libevdev_get_id_product(dev->evdev);
755	vid = libevdev_get_id_vendor(dev->evdev);
756
757	ck_assert_str_eq(name,
758			 libinput_device_get_name(dev->libinput_device));
759	ck_assert_int_eq(pid,
760			 libinput_device_get_id_product(dev->libinput_device));
761	ck_assert_int_eq(vid,
762			 libinput_device_get_id_vendor(dev->libinput_device));
763}
764END_TEST
765
766START_TEST(device_get_udev_handle)
767{
768	struct litest_device *dev = litest_current_device();
769	struct udev_device *udev_device;
770
771	udev_device = libinput_device_get_udev_device(dev->libinput_device);
772	ck_assert_notnull(udev_device);
773	udev_device_unref(udev_device);
774}
775END_TEST
776
777START_TEST(device_context)
778{
779	struct litest_device *dev = litest_current_device();
780	struct libinput_seat *seat;
781
782	ck_assert(dev->libinput == libinput_device_get_context(dev->libinput_device));
783	seat = libinput_device_get_seat(dev->libinput_device);
784	ck_assert(dev->libinput == libinput_seat_get_context(seat));
785}
786END_TEST
787
788START_TEST(device_user_data)
789{
790	struct litest_device *dev = litest_current_device();
791	struct libinput_device *device = dev->libinput_device;
792	void *userdata = &dev; /* not referenced */
793
794	ck_assert(libinput_device_get_user_data(device) == NULL);
795	libinput_device_set_user_data(device, userdata);
796	ck_assert_ptr_eq(libinput_device_get_user_data(device), userdata);
797	libinput_device_set_user_data(device, NULL);
798	ck_assert(libinput_device_get_user_data(device) == NULL);
799}
800END_TEST
801
802START_TEST(device_group_get)
803{
804	struct litest_device *dev = litest_current_device();
805	struct libinput_device_group *group;
806
807	int userdata = 10;
808
809	group = libinput_device_get_device_group(dev->libinput_device);
810	ck_assert_notnull(group);
811
812	libinput_device_group_ref(group);
813
814	libinput_device_group_set_user_data(group, &userdata);
815	ck_assert_ptr_eq(&userdata,
816			 libinput_device_group_get_user_data(group));
817
818	libinput_device_group_unref(group);
819}
820END_TEST
821
822START_TEST(device_group_ref)
823{
824	struct libinput *li = litest_create_context();
825	struct litest_device *dev = litest_add_device(li,
826						      LITEST_MOUSE);
827	struct libinput_device *device = dev->libinput_device;
828	struct libinput_device_group *group;
829
830	group = libinput_device_get_device_group(device);
831	ck_assert_notnull(group);
832	libinput_device_group_ref(group);
833
834	libinput_device_ref(device);
835	litest_drain_events(li);
836	litest_delete_device(dev);
837	litest_drain_events(li);
838
839	/* make sure the device is dead but the group is still around */
840	ck_assert(libinput_device_unref(device) == NULL);
841
842	libinput_device_group_ref(group);
843	ck_assert_notnull(libinput_device_group_unref(group));
844	ck_assert(libinput_device_group_unref(group) == NULL);
845
846	litest_destroy_context(li);
847}
848END_TEST
849
850START_TEST(device_group_leak)
851{
852	struct libinput *li;
853	struct libinput_device *device;
854	struct libevdev_uinput *uinput;
855	struct libinput_device_group *group;
856
857	uinput = litest_create_uinput_device("test device", NULL,
858					     EV_KEY, BTN_LEFT,
859					     EV_KEY, BTN_RIGHT,
860					     EV_REL, REL_X,
861					     EV_REL, REL_Y,
862					     -1);
863
864	li = litest_create_context();
865	device = libinput_path_add_device(li,
866					  libevdev_uinput_get_devnode(uinput));
867
868	group = libinput_device_get_device_group(device);
869	libinput_device_group_ref(group);
870
871	libinput_path_remove_device(device);
872
873	libevdev_uinput_destroy(uinput);
874	litest_destroy_context(li);
875
876	/* the device group leaks, check valgrind */
877}
878END_TEST
879
880START_TEST(abs_device_no_absx)
881{
882	struct libevdev_uinput *uinput;
883	struct libinput *li;
884	struct libinput_device *device;
885
886	uinput = litest_create_uinput_device("test device", NULL,
887					     EV_KEY, BTN_LEFT,
888					     EV_KEY, BTN_RIGHT,
889					     EV_ABS, ABS_Y,
890					     -1);
891	li = litest_create_context();
892	litest_disable_log_handler(li);
893	device = libinput_path_add_device(li,
894					  libevdev_uinput_get_devnode(uinput));
895	litest_restore_log_handler(li);
896	ck_assert(device == NULL);
897	litest_destroy_context(li);
898
899	libevdev_uinput_destroy(uinput);
900}
901END_TEST
902
903START_TEST(abs_device_no_absy)
904{
905	struct libevdev_uinput *uinput;
906	struct libinput *li;
907	struct libinput_device *device;
908
909	uinput = litest_create_uinput_device("test device", NULL,
910					     EV_KEY, BTN_LEFT,
911					     EV_KEY, BTN_RIGHT,
912					     EV_ABS, ABS_X,
913					     -1);
914	li = litest_create_context();
915	litest_disable_log_handler(li);
916	device = libinput_path_add_device(li,
917					  libevdev_uinput_get_devnode(uinput));
918	litest_restore_log_handler(li);
919	ck_assert(device == NULL);
920	litest_destroy_context(li);
921
922	libevdev_uinput_destroy(uinput);
923}
924END_TEST
925
926START_TEST(abs_mt_device_no_absy)
927{
928	struct libevdev_uinput *uinput;
929	struct libinput *li;
930	struct libinput_device *device;
931
932	uinput = litest_create_uinput_device("test device", NULL,
933					     EV_KEY, BTN_LEFT,
934					     EV_KEY, BTN_RIGHT,
935					     EV_ABS, ABS_X,
936					     EV_ABS, ABS_Y,
937					     EV_ABS, ABS_MT_SLOT,
938					     EV_ABS, ABS_MT_POSITION_X,
939					     -1);
940	li = litest_create_context();
941	litest_disable_log_handler(li);
942	device = libinput_path_add_device(li,
943					  libevdev_uinput_get_devnode(uinput));
944	litest_restore_log_handler(li);
945	ck_assert(device == NULL);
946	litest_destroy_context(li);
947
948	libevdev_uinput_destroy(uinput);
949}
950END_TEST
951
952START_TEST(abs_mt_device_no_absx)
953{
954	struct libevdev_uinput *uinput;
955	struct libinput *li;
956	struct libinput_device *device;
957
958	uinput = litest_create_uinput_device("test device", NULL,
959					     EV_KEY, BTN_LEFT,
960					     EV_KEY, BTN_RIGHT,
961					     EV_ABS, ABS_X,
962					     EV_ABS, ABS_Y,
963					     EV_ABS, ABS_MT_SLOT,
964					     EV_ABS, ABS_MT_POSITION_Y,
965					     -1);
966	li = litest_create_context();
967	litest_disable_log_handler(li);
968	device = libinput_path_add_device(li,
969					  libevdev_uinput_get_devnode(uinput));
970	litest_restore_log_handler(li);
971	ck_assert(device == NULL);
972	litest_destroy_context(li);
973
974	libevdev_uinput_destroy(uinput);
975}
976END_TEST
977
978static void
979assert_device_ignored(struct libinput *li, struct input_absinfo *absinfo)
980{
981	struct libevdev_uinput *uinput;
982	struct libinput_device *device;
983
984	uinput = litest_create_uinput_abs_device("test device", NULL,
985						 absinfo,
986						 EV_KEY, BTN_LEFT,
987						 EV_KEY, BTN_RIGHT,
988						 -1);
989	device = libinput_path_add_device(li,
990					  libevdev_uinput_get_devnode(uinput));
991	litest_assert_ptr_null(device);
992	libevdev_uinput_destroy(uinput);
993}
994
995START_TEST(abs_device_no_range)
996{
997	struct libinput *li;
998	int code = _i; /* looped test */
999	/* set x/y so libinput doesn't just reject for missing axes */
1000	struct input_absinfo absinfo[] = {
1001		{ ABS_X, 0, 10, 0, 0, 0 },
1002		{ ABS_Y, 0, 10, 0, 0, 0 },
1003		{ code, 0, 0, 0, 0, 0 },
1004		{ -1, -1, -1, -1, -1, -1 }
1005	};
1006
1007	li = litest_create_context();
1008	litest_disable_log_handler(li);
1009
1010	assert_device_ignored(li, absinfo);
1011
1012	litest_restore_log_handler(li);
1013	litest_destroy_context(li);
1014}
1015END_TEST
1016
1017START_TEST(abs_mt_device_no_range)
1018{
1019	struct libinput *li;
1020	int code = _i; /* looped test */
1021	/* set x/y so libinput doesn't just reject for missing axes */
1022	struct input_absinfo absinfo[] = {
1023		{ ABS_X, 0, 10, 0, 0, 0 },
1024		{ ABS_Y, 0, 10, 0, 0, 0 },
1025		{ ABS_MT_SLOT, 0, 10, 0, 0, 0 },
1026		{ ABS_MT_TRACKING_ID, 0, 255, 0, 0, 0 },
1027		{ ABS_MT_POSITION_X, 0, 10, 0, 0, 0 },
1028		{ ABS_MT_POSITION_Y, 0, 10, 0, 0, 0 },
1029		{ code, 0, 0, 0, 0, 0 },
1030		{ -1, -1, -1, -1, -1, -1 }
1031	};
1032
1033	li = litest_create_context();
1034	litest_disable_log_handler(li);
1035
1036	if (code != ABS_MT_TOOL_TYPE &&
1037	    code != ABS_MT_TRACKING_ID) /* kernel overrides it */
1038		assert_device_ignored(li, absinfo);
1039
1040	litest_restore_log_handler(li);
1041	litest_destroy_context(li);
1042}
1043END_TEST
1044
1045START_TEST(abs_device_missing_res)
1046{
1047	struct libinput *li;
1048	struct input_absinfo absinfo[] = {
1049		{ ABS_X, 0, 10, 0, 0, 10 },
1050		{ ABS_Y, 0, 10, 0, 0, 0 },
1051		{ -1, -1, -1, -1, -1, -1 }
1052	};
1053
1054	li = litest_create_context();
1055	litest_disable_log_handler(li);
1056
1057	assert_device_ignored(li, absinfo);
1058
1059	absinfo[0].resolution = 0;
1060	absinfo[1].resolution = 20;
1061
1062	assert_device_ignored(li, absinfo);
1063
1064	litest_restore_log_handler(li);
1065	litest_destroy_context(li);
1066}
1067END_TEST
1068
1069START_TEST(abs_mt_device_missing_res)
1070{
1071	struct libinput *li;
1072	struct input_absinfo absinfo[] = {
1073		{ ABS_X, 0, 10, 0, 0, 10 },
1074		{ ABS_Y, 0, 10, 0, 0, 10 },
1075		{ ABS_MT_SLOT, 0, 2, 0, 0, 0 },
1076		{ ABS_MT_TRACKING_ID, 0, 255, 0, 0, 0 },
1077		{ ABS_MT_POSITION_X, 0, 10, 0, 0, 10 },
1078		{ ABS_MT_POSITION_Y, 0, 10, 0, 0, 0 },
1079		{ -1, -1, -1, -1, -1, -1 }
1080	};
1081
1082	li = litest_create_context();
1083	litest_disable_log_handler(li);
1084	assert_device_ignored(li, absinfo);
1085
1086	absinfo[4].resolution = 0;
1087	absinfo[5].resolution = 20;
1088
1089	assert_device_ignored(li, absinfo);
1090
1091	litest_restore_log_handler(li);
1092	litest_destroy_context(li);
1093
1094}
1095END_TEST
1096
1097START_TEST(ignore_joystick)
1098{
1099	struct libinput *li;
1100	struct libevdev_uinput *uinput;
1101	struct libinput_device *device;
1102	struct input_absinfo absinfo[] = {
1103		{ ABS_X, 0, 10, 0, 0, 10 },
1104		{ ABS_Y, 0, 10, 0, 0, 10 },
1105		{ ABS_RX, 0, 10, 0, 0, 10 },
1106		{ ABS_RY, 0, 10, 0, 0, 10 },
1107		{ ABS_THROTTLE, 0, 2, 0, 0, 0 },
1108		{ ABS_RUDDER, 0, 255, 0, 0, 0 },
1109		{ -1, -1, -1, -1, -1, -1 }
1110	};
1111
1112	li = litest_create_context();
1113	litest_disable_log_handler(li);
1114	litest_drain_events(li);
1115
1116	uinput = litest_create_uinput_abs_device("joystick test device", NULL,
1117						 absinfo,
1118						 EV_KEY, BTN_TRIGGER,
1119						 EV_KEY, BTN_A,
1120						 -1);
1121	device = libinput_path_add_device(li,
1122					  libevdev_uinput_get_devnode(uinput));
1123	litest_assert_ptr_null(device);
1124	libevdev_uinput_destroy(uinput);
1125	litest_restore_log_handler(li);
1126	litest_destroy_context(li);
1127}
1128END_TEST
1129
1130START_TEST(device_wheel_only)
1131{
1132	struct litest_device *dev = litest_current_device();
1133	struct libinput_device *device = dev->libinput_device;
1134
1135	ck_assert(libinput_device_has_capability(device,
1136						 LIBINPUT_DEVICE_CAP_POINTER));
1137}
1138END_TEST
1139
1140START_TEST(device_accelerometer)
1141{
1142	struct libinput *li;
1143	struct libevdev_uinput *uinput;
1144	struct libinput_device *device;
1145
1146	struct input_absinfo absinfo[] = {
1147		{ ABS_X, 0, 10, 0, 0, 10 },
1148		{ ABS_Y, 0, 10, 0, 0, 10 },
1149		{ ABS_Z, 0, 10, 0, 0, 10 },
1150		{ -1, -1, -1, -1, -1, -1 }
1151	};
1152
1153	li = litest_create_context();
1154	litest_disable_log_handler(li);
1155
1156	uinput = litest_create_uinput_abs_device("test device", NULL,
1157						 absinfo,
1158						 -1);
1159	device = libinput_path_add_device(li,
1160					  libevdev_uinput_get_devnode(uinput));
1161	litest_assert_ptr_null(device);
1162	libevdev_uinput_destroy(uinput);
1163	litest_restore_log_handler(li);
1164	litest_destroy_context(li);
1165}
1166END_TEST
1167
1168START_TEST(device_udev_tag_wacom_tablet)
1169{
1170	struct litest_device *dev = litest_current_device();
1171	struct libinput_device *device = dev->libinput_device;
1172	struct udev_device *d;
1173	const char *prop;
1174
1175	d = libinput_device_get_udev_device(device);
1176	prop = udev_device_get_property_value(d,
1177					      "ID_INPUT_TABLET");
1178
1179	ck_assert_notnull(prop);
1180	udev_device_unref(d);
1181}
1182END_TEST
1183
1184START_TEST(device_nonpointer_rel)
1185{
1186	struct libevdev_uinput *uinput;
1187	struct libinput *li;
1188	struct libinput_device *device;
1189	int i;
1190
1191	uinput = litest_create_uinput_device("test device",
1192					     NULL,
1193					     EV_KEY, KEY_A,
1194					     EV_KEY, KEY_B,
1195					     EV_REL, REL_X,
1196					     EV_REL, REL_Y,
1197					     -1);
1198	li = litest_create_context();
1199	device = libinput_path_add_device(li,
1200					  libevdev_uinput_get_devnode(uinput));
1201	ck_assert_notnull(device);
1202
1203	litest_disable_log_handler(li);
1204	for (i = 0; i < 100; i++) {
1205		libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1);
1206		libevdev_uinput_write_event(uinput, EV_REL, REL_Y, -1);
1207		libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
1208		libinput_dispatch(li);
1209	}
1210	litest_restore_log_handler(li);
1211
1212	litest_destroy_context(li);
1213	libevdev_uinput_destroy(uinput);
1214}
1215END_TEST
1216
1217START_TEST(device_touchpad_rel)
1218{
1219	struct libevdev_uinput *uinput;
1220	struct libinput *li;
1221	struct libinput_device *device;
1222	const struct input_absinfo abs[] = {
1223		{ ABS_X, 0, 10, 0, 0, 10 },
1224		{ ABS_Y, 0, 10, 0, 0, 10 },
1225		{ ABS_MT_SLOT, 0, 2, 0, 0, 0 },
1226		{ ABS_MT_TRACKING_ID, 0, 255, 0, 0, 0 },
1227		{ ABS_MT_POSITION_X, 0, 10, 0, 0, 10 },
1228		{ ABS_MT_POSITION_Y, 0, 10, 0, 0, 10 },
1229		{ -1, -1, -1, -1, -1, -1 }
1230	};
1231	int i;
1232
1233	uinput = litest_create_uinput_abs_device("test device",
1234						 NULL, abs,
1235						 EV_KEY, BTN_TOOL_FINGER,
1236						 EV_KEY, BTN_TOUCH,
1237						 EV_REL, REL_X,
1238						 EV_REL, REL_Y,
1239						 -1);
1240	li = litest_create_context();
1241	device = libinput_path_add_device(li,
1242					  libevdev_uinput_get_devnode(uinput));
1243	ck_assert_notnull(device);
1244
1245	for (i = 0; i < 100; i++) {
1246		libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1);
1247		libevdev_uinput_write_event(uinput, EV_REL, REL_Y, -1);
1248		libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
1249		libinput_dispatch(li);
1250	}
1251
1252	litest_destroy_context(li);
1253	libevdev_uinput_destroy(uinput);
1254}
1255END_TEST
1256
1257START_TEST(device_touch_rel)
1258{
1259	struct libevdev_uinput *uinput;
1260	struct libinput *li;
1261	struct libinput_device *device;
1262	const struct input_absinfo abs[] = {
1263		{ ABS_X, 0, 10, 0, 0, 10 },
1264		{ ABS_Y, 0, 10, 0, 0, 10 },
1265		{ ABS_MT_SLOT, 0, 2, 0, 0, 0 },
1266		{ ABS_MT_TRACKING_ID, 0, 255, 0, 0, 0 },
1267		{ ABS_MT_POSITION_X, 0, 10, 0, 0, 10 },
1268		{ ABS_MT_POSITION_Y, 0, 10, 0, 0, 10 },
1269		{ -1, -1, -1, -1, -1, -1 }
1270	};
1271	int i;
1272
1273	uinput = litest_create_uinput_abs_device("test device",
1274						 NULL, abs,
1275						 EV_KEY, BTN_TOUCH,
1276						 EV_REL, REL_X,
1277						 EV_REL, REL_Y,
1278						 -1);
1279	li = litest_create_context();
1280	device = libinput_path_add_device(li,
1281					  libevdev_uinput_get_devnode(uinput));
1282	ck_assert_notnull(device);
1283
1284	litest_disable_log_handler(li);
1285	for (i = 0; i < 100; i++) {
1286		libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1);
1287		libevdev_uinput_write_event(uinput, EV_REL, REL_Y, -1);
1288		libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
1289		libinput_dispatch(li);
1290	}
1291	litest_restore_log_handler(li);
1292
1293	litest_destroy_context(li);
1294	libevdev_uinput_destroy(uinput);
1295}
1296END_TEST
1297
1298START_TEST(device_abs_rel)
1299{
1300	struct libevdev_uinput *uinput;
1301	struct libinput *li;
1302	struct libinput_device *device;
1303	const struct input_absinfo abs[] = {
1304		{ ABS_X, 0, 10, 0, 0, 10 },
1305		{ ABS_Y, 0, 10, 0, 0, 10 },
1306		{ -1, -1, -1, -1, -1, -1 }
1307	};
1308	int i;
1309
1310	uinput = litest_create_uinput_abs_device("test device",
1311						 NULL, abs,
1312						 EV_KEY, BTN_TOUCH,
1313						 EV_KEY, BTN_LEFT,
1314						 EV_REL, REL_X,
1315						 EV_REL, REL_Y,
1316						 -1);
1317	li = litest_create_context();
1318	device = libinput_path_add_device(li,
1319					  libevdev_uinput_get_devnode(uinput));
1320	ck_assert_notnull(device);
1321
1322	for (i = 0; i < 100; i++) {
1323		libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1);
1324		libevdev_uinput_write_event(uinput, EV_REL, REL_Y, -1);
1325		libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
1326		libinput_dispatch(li);
1327	}
1328
1329	litest_destroy_context(li);
1330	libevdev_uinput_destroy(uinput);
1331}
1332END_TEST
1333
1334START_TEST(device_quirks_no_abs_mt_y)
1335{
1336	struct litest_device *dev = litest_current_device();
1337	struct libinput *li = dev->libinput;
1338	struct libinput_event *event;
1339	struct libinput_event_pointer *pev;
1340	bool hi_res_event_found, low_res_event_found;
1341	int code, i;
1342
1343	hi_res_event_found = false;
1344	low_res_event_found = false;
1345
1346	litest_drain_events(li);
1347
1348	litest_event(dev, EV_REL, REL_HWHEEL, 1);
1349	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1350	libinput_dispatch(li);
1351
1352	/* both high and low scroll end events must be sent */
1353	for (i = 0; i < 2; i++) {
1354		event = libinput_get_event(li);
1355		pev = litest_is_axis_event(event,
1356					   LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
1357					   LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
1358					   LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
1359
1360		if (litest_is_high_res_axis_event(event)) {
1361			litest_assert(!hi_res_event_found);
1362			hi_res_event_found = true;
1363		} else {
1364			litest_assert(!low_res_event_found);
1365			low_res_event_found = true;
1366		}
1367
1368		libinput_event_destroy(libinput_event_pointer_get_base_event(pev));
1369	}
1370
1371	litest_assert(low_res_event_found);
1372	litest_assert(hi_res_event_found);
1373
1374	for (code = ABS_MISC + 1; code < ABS_MAX; code++) {
1375		litest_event(dev, EV_ABS, code, 1);
1376		litest_event(dev, EV_SYN, SYN_REPORT, 0);
1377		litest_assert_empty_queue(li);
1378	}
1379
1380}
1381END_TEST
1382
1383START_TEST(device_quirks_cyborg_rat_mode_button)
1384{
1385	struct litest_device *dev = litest_current_device();
1386	struct libinput_device *device = dev->libinput_device;
1387	struct libinput *li = dev->libinput;
1388
1389	ck_assert(!libinput_device_pointer_has_button(device, 0x118));
1390	ck_assert(!libinput_device_pointer_has_button(device, 0x119));
1391	ck_assert(!libinput_device_pointer_has_button(device, 0x11a));
1392
1393	litest_drain_events(li);
1394
1395	litest_event(dev, EV_KEY, 0x118, 0);
1396	litest_event(dev, EV_KEY, 0x119, 1);
1397	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1398
1399	litest_assert_empty_queue(li);
1400
1401	litest_event(dev, EV_KEY, 0x119, 0);
1402	litest_event(dev, EV_KEY, 0x11a, 1);
1403	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1404
1405	litest_assert_empty_queue(li);
1406
1407	litest_event(dev, EV_KEY, 0x11a, 0);
1408	litest_event(dev, EV_KEY, 0x118, 1);
1409	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1410
1411	litest_assert_empty_queue(li);
1412}
1413END_TEST
1414
1415START_TEST(device_quirks_apple_magicmouse)
1416{
1417	struct litest_device *dev = litest_current_device();
1418	struct libinput *li = dev->libinput;
1419
1420	litest_drain_events(li);
1421
1422	/* ensure we get no events from the touch */
1423	litest_touch_down(dev, 0, 50, 50);
1424	litest_touch_move_to(dev, 0, 50, 50, 80, 80, 10);
1425	litest_touch_up(dev, 0);
1426	litest_assert_empty_queue(li);
1427}
1428END_TEST
1429
1430START_TEST(device_quirks_logitech_marble_mouse)
1431{
1432	struct litest_device *dev = litest_current_device();
1433	struct libinput *li = dev->libinput;
1434
1435	litest_drain_events(li);
1436
1437	ck_assert(!libinput_device_pointer_has_button(dev->libinput_device,
1438						      BTN_MIDDLE));
1439}
1440END_TEST
1441
1442char *debug_messages[64] = { NULL };
1443
1444LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
1445static void
1446debug_log_handler(struct libinput *libinput,
1447		  enum libinput_log_priority priority,
1448		  const char *format,
1449		  va_list args)
1450{
1451	char *message;
1452	int n;
1453
1454	if (priority != LIBINPUT_LOG_PRIORITY_DEBUG)
1455		return;
1456
1457	n = xvasprintf(&message, format, args);
1458	litest_assert_int_gt(n, 0);
1459
1460	ARRAY_FOR_EACH(debug_messages, dmsg) {
1461		if (*dmsg == NULL) {
1462			*dmsg = message;
1463			return;
1464		}
1465	}
1466
1467	litest_abort_msg("Out of space for debug messages");
1468}
1469
1470START_TEST(device_quirks)
1471{
1472	struct libinput *li;
1473	struct litest_device *dev;
1474	struct libinput_device *device;
1475	char **message;
1476	bool disable_key_f1 = false,
1477	     enable_btn_left = false;
1478#if HAVE_LIBEVDEV_DISABLE_PROPERTY
1479	bool disable_pointingstick = false,
1480	     enable_buttonpad = false,
1481	     enable_direct = false,
1482	     disable_direct = false,
1483	     enable_semi_mt = false,
1484	     disable_semi_mt = false;
1485#endif
1486
1487	li = litest_create_context();
1488	libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG);
1489	libinput_log_set_handler(li, debug_log_handler);
1490	dev = litest_add_device(li, LITEST_KEYBOARD_QUIRKED);
1491	device = dev->libinput_device;
1492
1493	ck_assert(libinput_device_pointer_has_button(device,
1494						     BTN_LEFT));
1495	ck_assert(libinput_device_pointer_has_button(dev->libinput_device,
1496						     BTN_RIGHT));
1497	ck_assert(!libinput_device_pointer_has_button(device,
1498						      BTN_MIDDLE));
1499	ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
1500						    KEY_F1));
1501	ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
1502						    KEY_F2));
1503	ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
1504						    KEY_F3));
1505
1506	/* Scrape the debug messages for confirmation that our quirks are
1507	 * triggered, the above checks cannot work non-key codes */
1508	message = debug_messages;
1509	while (*message) {
1510		if (strstr(*message, "disabling EV_KEY KEY_F1"))
1511			disable_key_f1 = true;
1512		if (strstr(*message, "enabling EV_KEY BTN_LEFT"))
1513			enable_btn_left = true;
1514#if HAVE_LIBEVDEV_DISABLE_PROPERTY
1515		if (strstr(*message, "enabling INPUT_PROP_BUTTONPAD"))
1516			enable_buttonpad = true;
1517		if (strstr(*message, "disabling INPUT_PROP_POINTING_STICK"))
1518			disable_pointingstick = true;
1519		if (strstr(*message, "enabling INPUT_PROP_DIRECT")) {
1520			ck_assert(!disable_direct);
1521			enable_direct = true;
1522		}
1523		if (strstr(*message, "disabling INPUT_PROP_DIRECT")) {
1524			ck_assert(enable_direct);
1525			disable_direct = true;
1526		}
1527		if (strstr(*message, "enabling INPUT_PROP_SEMI_MT")) {
1528			ck_assert(disable_semi_mt);
1529			enable_semi_mt = true;
1530		}
1531		if (strstr(*message, "disabling INPUT_PROP_SEMI_MT")) {
1532			ck_assert(!enable_semi_mt);
1533			disable_semi_mt = true;
1534		}
1535#endif
1536		free(*message);
1537		message++;
1538	}
1539
1540	ck_assert(disable_key_f1);
1541	ck_assert(enable_btn_left);
1542#if HAVE_LIBEVDEV_DISABLE_PROPERTY
1543	ck_assert(enable_buttonpad);
1544	ck_assert(disable_pointingstick);
1545	ck_assert(enable_direct);
1546	ck_assert(disable_direct);
1547	ck_assert(enable_semi_mt);
1548	ck_assert(disable_semi_mt);
1549#endif
1550
1551	litest_disable_log_handler(li);
1552
1553	litest_delete_device(dev);
1554	litest_destroy_context(li);
1555}
1556END_TEST
1557
1558START_TEST(device_capability_at_least_one)
1559{
1560	struct litest_device *dev = litest_current_device();
1561	struct libinput_device *device = dev->libinput_device;
1562	enum libinput_device_capability caps[] = {
1563		LIBINPUT_DEVICE_CAP_KEYBOARD,
1564		LIBINPUT_DEVICE_CAP_POINTER,
1565		LIBINPUT_DEVICE_CAP_TOUCH,
1566		LIBINPUT_DEVICE_CAP_TABLET_TOOL,
1567		LIBINPUT_DEVICE_CAP_TABLET_PAD,
1568		LIBINPUT_DEVICE_CAP_GESTURE,
1569		LIBINPUT_DEVICE_CAP_SWITCH,
1570	};
1571	int ncaps = 0;
1572
1573	ARRAY_FOR_EACH(caps, cap) {
1574		if (libinput_device_has_capability(device, *cap))
1575			ncaps++;
1576	}
1577	ck_assert_int_gt(ncaps, 0);
1578
1579}
1580END_TEST
1581
1582START_TEST(device_capability_check_invalid)
1583{
1584	struct litest_device *dev = litest_current_device();
1585	struct libinput_device *device = dev->libinput_device;
1586
1587	ck_assert(!libinput_device_has_capability(device, -1));
1588	ck_assert(!libinput_device_has_capability(device, 7));
1589	ck_assert(!libinput_device_has_capability(device, 0xffff));
1590
1591}
1592END_TEST
1593
1594START_TEST(device_capability_nocaps_ignored)
1595{
1596	struct libevdev_uinput *uinput;
1597	struct libinput *li;
1598	struct libinput_device *device;
1599
1600	/* SW_PEN_INSERTED isn't handled in libinput so the device is
1601	 * processed but ends up without seat capabilities and is ignored.
1602	 */
1603	uinput = litest_create_uinput_device("test device", NULL,
1604					     EV_SW, SW_PEN_INSERTED,
1605					     -1);
1606	li = litest_create_context();
1607	device = libinput_path_add_device(li,
1608					  libevdev_uinput_get_devnode(uinput));
1609	litest_assert_ptr_null(device);
1610
1611	litest_destroy_context(li);
1612	libevdev_uinput_destroy(uinput);
1613}
1614END_TEST
1615
1616START_TEST(device_has_size)
1617{
1618	struct litest_device *dev = litest_current_device();
1619	struct libinput_device *device = dev->libinput_device;
1620	double w, h;
1621	int rc;
1622
1623	rc = libinput_device_get_size(device, &w, &h);
1624	ck_assert_int_eq(rc, 0);
1625	/* This matches the current set of test devices but may fail if
1626	 * newer ones are added */
1627	ck_assert_double_gt(w, 30);
1628	ck_assert_double_gt(h, 20);
1629}
1630END_TEST
1631
1632START_TEST(device_has_no_size)
1633{
1634	struct litest_device *dev = litest_current_device();
1635	struct libinput_device *device = dev->libinput_device;
1636	double w = 45, h = 67;
1637	int rc;
1638
1639	rc = libinput_device_get_size(device, &w, &h);
1640	ck_assert_int_eq(rc, -1);
1641	ck_assert_double_eq(w, 45);
1642	ck_assert_double_eq(h, 67);
1643}
1644END_TEST
1645
1646START_TEST(device_get_output)
1647{
1648	struct litest_device *dev = litest_current_device();
1649	struct libinput_device *device = dev->libinput_device;
1650	const char *output_name;
1651
1652	output_name = libinput_device_get_output_name(device);
1653	ck_assert_str_eq(output_name, "myOutput");
1654}
1655END_TEST
1656
1657START_TEST(device_no_output)
1658{
1659	struct litest_device *dev = litest_current_device();
1660	struct libinput_device *device = dev->libinput_device;
1661	const char *output_name;
1662
1663	output_name = libinput_device_get_output_name(device);
1664	ck_assert(output_name == NULL);
1665}
1666END_TEST
1667
1668START_TEST(device_seat_phys_name)
1669{
1670	struct litest_device *dev = litest_current_device();
1671	struct libinput_device *device = dev->libinput_device;
1672	struct libinput_seat *seat = libinput_device_get_seat(device);
1673	const char *seat_name;
1674
1675	seat_name = libinput_seat_get_physical_name(seat);
1676	ck_assert(streq(seat_name, "seat0"));
1677}
1678END_TEST
1679
1680START_TEST(device_button_down_remove)
1681{
1682	struct litest_device *lidev = litest_current_device();
1683	struct litest_device *dev;
1684	struct libinput *li;
1685
1686	for (int code = 0; code < KEY_MAX; code++) {
1687		struct libinput_event *event;
1688		struct libinput_event_pointer *p;
1689		bool have_down = false,
1690		     have_up = false;
1691		const char *keyname;
1692		int button_down = 0, button_up = 0;
1693
1694		keyname = libevdev_event_code_get_name(EV_KEY, code);
1695		if (!keyname ||
1696		    !strneq(keyname, "BTN_", 4) ||
1697		    strneq(keyname, "BTN_TOOL_", 9))
1698			continue;
1699
1700		if (!libevdev_has_event_code(lidev->evdev, EV_KEY, code))
1701			continue;
1702
1703		li = litest_create_context();
1704		dev = litest_add_device(li, lidev->which);
1705		litest_drain_events(li);
1706
1707		/* Clickpads require a touch down to trigger the button
1708		 * press */
1709		if (libevdev_has_property(lidev->evdev, INPUT_PROP_BUTTONPAD)) {
1710			litest_touch_down(dev, 0, 20, 90);
1711			libinput_dispatch(li);
1712		}
1713
1714		litest_event(dev, EV_KEY, code, 1);
1715		litest_event(dev, EV_SYN, SYN_REPORT, 0);
1716		libinput_dispatch(li);
1717
1718		litest_delete_device(dev);
1719		libinput_dispatch(li);
1720
1721		while ((event = libinput_get_event(li))) {
1722			if (libinput_event_get_type(event) !=
1723			    LIBINPUT_EVENT_POINTER_BUTTON) {
1724				libinput_event_destroy(event);
1725				continue;
1726			}
1727
1728			p = libinput_event_get_pointer_event(event);
1729			if (libinput_event_pointer_get_button_state(p)) {
1730				ck_assert(button_down == 0);
1731				button_down = libinput_event_pointer_get_button(p);
1732			} else {
1733				ck_assert(button_up == 0);
1734				button_up = libinput_event_pointer_get_button(p);
1735				ck_assert_int_eq(button_down, button_up);
1736			}
1737			libinput_event_destroy(event);
1738		}
1739
1740		litest_destroy_context(li);
1741		ck_assert_int_eq(have_down, have_up);
1742	}
1743}
1744END_TEST
1745
1746TEST_COLLECTION(device)
1747{
1748	struct range abs_range = { 0, ABS_MISC };
1749	struct range abs_mt_range = { ABS_MT_SLOT + 1, ABS_CNT };
1750
1751	litest_add(device_sendevents_config, LITEST_ANY, LITEST_TOUCHPAD|LITEST_TABLET);
1752	litest_add(device_sendevents_config_invalid, LITEST_ANY, LITEST_TABLET);
1753	litest_add(device_sendevents_config_touchpad, LITEST_TOUCHPAD, LITEST_TABLET);
1754	litest_add(device_sendevents_config_touchpad_superset, LITEST_TOUCHPAD, LITEST_TABLET);
1755	litest_add(device_sendevents_config_default, LITEST_ANY, LITEST_TABLET);
1756	litest_add(device_disable, LITEST_RELATIVE, LITEST_TABLET);
1757	litest_add(device_disable_tablet, LITEST_TABLET, LITEST_ANY);
1758	litest_add(device_disable_touchpad, LITEST_TOUCHPAD, LITEST_TABLET);
1759	litest_add(device_disable_touch, LITEST_TOUCH, LITEST_ANY);
1760	litest_add(device_disable_touch_during_touch, LITEST_TOUCH, LITEST_ANY);
1761	litest_add(device_disable_touch, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1762	litest_add(device_disable_touch_during_touch, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1763	litest_add(device_disable_events_pending, LITEST_RELATIVE, LITEST_TOUCHPAD|LITEST_TABLET);
1764	litest_add(device_double_disable, LITEST_ANY, LITEST_TABLET);
1765	litest_add(device_double_enable, LITEST_ANY, LITEST_TABLET);
1766	litest_add_no_device(device_reenable_syspath_changed);
1767	litest_add_no_device(device_reenable_device_removed);
1768	litest_add_for_device(device_disable_release_buttons, LITEST_MOUSE);
1769	litest_add_for_device(device_disable_release_keys, LITEST_KEYBOARD);
1770	litest_add(device_disable_release_tap, LITEST_TOUCHPAD, LITEST_ANY);
1771	litest_add(device_disable_release_tap_n_drag, LITEST_TOUCHPAD, LITEST_ANY);
1772	litest_add(device_disable_release_softbutton, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
1773	litest_add(device_disable_topsoftbutton, LITEST_TOPBUTTONPAD, LITEST_ANY);
1774	litest_add(device_ids, LITEST_ANY, LITEST_ANY);
1775	litest_add_for_device(device_context, LITEST_SYNAPTICS_CLICKPAD_X220);
1776	litest_add_for_device(device_user_data, LITEST_SYNAPTICS_CLICKPAD_X220);
1777
1778	litest_add(device_get_udev_handle, LITEST_ANY, LITEST_ANY);
1779
1780	litest_add(device_group_get, LITEST_ANY, LITEST_ANY);
1781	litest_add_no_device(device_group_ref);
1782	litest_add_no_device(device_group_leak);
1783
1784	litest_add_no_device(abs_device_no_absx);
1785	litest_add_no_device(abs_device_no_absy);
1786	litest_add_no_device(abs_mt_device_no_absx);
1787	litest_add_no_device(abs_mt_device_no_absy);
1788	litest_add_ranged_no_device(abs_device_no_range, &abs_range);
1789	litest_add_ranged_no_device(abs_mt_device_no_range, &abs_mt_range);
1790	litest_add_no_device(abs_device_missing_res);
1791	litest_add_no_device(abs_mt_device_missing_res);
1792	litest_add_no_device(ignore_joystick);
1793
1794	litest_add(device_wheel_only, LITEST_WHEEL, LITEST_RELATIVE|LITEST_ABSOLUTE|LITEST_TABLET);
1795	litest_add_no_device(device_accelerometer);
1796
1797	litest_add(device_udev_tag_wacom_tablet, LITEST_TABLET, LITEST_TOTEM);
1798
1799	litest_add_no_device(device_nonpointer_rel);
1800	litest_add_no_device(device_touchpad_rel);
1801	litest_add_no_device(device_touch_rel);
1802	litest_add_no_device(device_abs_rel);
1803
1804	litest_add_for_device(device_quirks_no_abs_mt_y, LITEST_ANKER_MOUSE_KBD);
1805	litest_add_for_device(device_quirks_cyborg_rat_mode_button, LITEST_CYBORG_RAT);
1806	litest_add_for_device(device_quirks_apple_magicmouse, LITEST_MAGICMOUSE);
1807	litest_add_for_device(device_quirks_logitech_marble_mouse, LITEST_LOGITECH_TRACKBALL);
1808	litest_add_no_device(device_quirks);
1809
1810	litest_add(device_capability_at_least_one, LITEST_ANY, LITEST_ANY);
1811	litest_add(device_capability_check_invalid, LITEST_ANY, LITEST_ANY);
1812	litest_add_no_device(device_capability_nocaps_ignored);
1813
1814	litest_add(device_has_size, LITEST_TOUCHPAD, LITEST_ANY);
1815	litest_add(device_has_size, LITEST_TABLET, LITEST_ANY);
1816	litest_add(device_has_no_size, LITEST_ANY,
1817		   LITEST_TOUCHPAD|LITEST_TABLET|LITEST_TOUCH|LITEST_ABSOLUTE|LITEST_SINGLE_TOUCH|LITEST_TOTEM);
1818
1819	litest_add_for_device(device_get_output, LITEST_CALIBRATED_TOUCHSCREEN);
1820	litest_add(device_no_output, LITEST_RELATIVE, LITEST_ANY);
1821	litest_add(device_no_output, LITEST_KEYS, LITEST_ANY);
1822
1823	litest_add(device_seat_phys_name, LITEST_ANY, LITEST_ANY);
1824
1825	litest_add(device_button_down_remove, LITEST_BUTTON, LITEST_ANY);
1826}
1827