• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2014-2015 Red Hat, Inc.
3  * Copyright © 2014 Lyude Paul
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 <errno.h>
29 #include <fcntl.h>
30 #include <libinput.h>
31 #include <unistd.h>
32 #include <stdbool.h>
33 #include <stdarg.h>
34 
35 #include "libinput-util.h"
36 #include "evdev-tablet.h"
37 #include "litest.h"
38 
39 static inline unsigned int
pick_stylus_or_btn0(struct litest_device * dev)40 pick_stylus_or_btn0(struct litest_device *dev)
41 {
42 	if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_STYLUS))
43 		return BTN_STYLUS;
44 
45 	if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_0))
46 		return BTN_0; /* totem */
47 
48 	abort();
49 }
50 
START_TEST(button_down_up)51 START_TEST(button_down_up)
52 {
53 	struct litest_device *dev = litest_current_device();
54 	struct libinput *li = dev->libinput;
55 	struct libinput_event *event;
56 	struct libinput_event_tablet_tool *tev;
57 	struct axis_replacement axes[] = {
58 		{ ABS_DISTANCE, 10 },
59 		{ ABS_PRESSURE, 0 },
60 		{ -1, -1 }
61 	};
62 	unsigned int button = pick_stylus_or_btn0(dev);
63 
64 	litest_tablet_proximity_in(dev, 10, 10, axes);
65 	litest_drain_events(li);
66 
67 	litest_button_click(dev, button, true);
68 	libinput_dispatch(li);
69 
70 	event = libinput_get_event(li);
71 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
72 	ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev),
73 			 button);
74 	ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev),
75 			 LIBINPUT_BUTTON_STATE_PRESSED);
76 	libinput_event_destroy(event);
77 	litest_assert_empty_queue(li);
78 
79 	litest_button_click(dev, button, false);
80 	libinput_dispatch(li);
81 
82 	event = libinput_get_event(li);
83 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
84 	ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev),
85 			 button);
86 	ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev),
87 			 LIBINPUT_BUTTON_STATE_RELEASED);
88 	libinput_event_destroy(event);
89 	litest_assert_empty_queue(li);
90 }
91 END_TEST
92 
START_TEST(button_seat_count)93 START_TEST(button_seat_count)
94 {
95 	struct litest_device *dev = litest_current_device();
96 	struct libinput *li = dev->libinput;
97 	struct libinput_event *event;
98 	struct libinput_event_tablet_tool *tev;
99 	struct litest_device *dev2;
100 	struct axis_replacement axes[] = {
101 		{ ABS_DISTANCE, 10 },
102 		{ ABS_PRESSURE, 0 },
103 		{ -1, -1 }
104 	};
105 	unsigned int button = pick_stylus_or_btn0(dev);
106 
107 	switch (button) {
108 	case BTN_STYLUS:
109 		dev2 = litest_add_device(li, LITEST_WACOM_CINTIQ_13HDT_PEN);
110 		break;
111 	case BTN_0:
112 		dev2 = litest_add_device(li, LITEST_DELL_CANVAS_TOTEM);
113 		break;
114 	default:
115 		ck_abort();
116 	}
117 
118 	litest_tablet_proximity_in(dev, 10, 10, axes);
119 	litest_tablet_proximity_in(dev2, 10, 10, axes);
120 	litest_drain_events(li);
121 
122 	litest_button_click(dev, button, true);
123 	litest_button_click(dev2, button, true);
124 	libinput_dispatch(li);
125 
126 	event = libinput_get_event(li);
127 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
128 	ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev), button);
129 	ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev),
130 			 LIBINPUT_BUTTON_STATE_PRESSED);
131 	ck_assert_int_eq(libinput_event_tablet_tool_get_seat_button_count(tev), 1);
132 	libinput_event_destroy(event);
133 
134 	event = libinput_get_event(li);
135 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
136 	ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev), button);
137 	ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev),
138 			 LIBINPUT_BUTTON_STATE_PRESSED);
139 	ck_assert_int_eq(libinput_event_tablet_tool_get_seat_button_count(tev), 2);
140 	libinput_event_destroy(event);
141 
142 	litest_assert_empty_queue(li);
143 
144 	litest_button_click(dev2, button, false);
145 	litest_button_click(dev, button, false);
146 	libinput_dispatch(li);
147 
148 	event = libinput_get_event(li);
149 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
150 	ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev),
151 			 LIBINPUT_BUTTON_STATE_RELEASED);
152 	ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev), button);
153 	ck_assert_int_eq(libinput_event_tablet_tool_get_seat_button_count(tev), 1);
154 	libinput_event_destroy(event);
155 
156 	event = libinput_get_event(li);
157 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
158 	ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev),
159 			 LIBINPUT_BUTTON_STATE_RELEASED);
160 	ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev), button);
161 	ck_assert_int_eq(libinput_event_tablet_tool_get_seat_button_count(tev), 0);
162 	libinput_event_destroy(event);
163 	litest_assert_empty_queue(li);
164 
165 	litest_delete_device(dev2);
166 }
167 END_TEST
168 
START_TEST(button_up_on_delete)169 START_TEST(button_up_on_delete)
170 {
171 	struct libinput *li = litest_create_context();
172 	struct litest_device *dev = litest_add_device(li, LITEST_WACOM_INTUOS);
173 	struct libevdev *evdev = libevdev_new();
174 	unsigned int code;
175 
176 	litest_tablet_proximity_in(dev, 10, 10, NULL);
177 	litest_drain_events(li);
178 
179 	for (code = BTN_LEFT; code <= BTN_TASK; code++) {
180 		if (!libevdev_has_event_code(dev->evdev, EV_KEY, code))
181 			continue;
182 
183 		libevdev_enable_event_code(evdev, EV_KEY, code, NULL);
184 		litest_event(dev, EV_KEY, code, 1);
185 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
186 		libinput_dispatch(li);
187 	}
188 
189 	litest_drain_events(li);
190 	litest_delete_device(dev);
191 	libinput_dispatch(li);
192 
193 	for (code = BTN_LEFT; code <= BTN_TASK; code++) {
194 		if (!libevdev_has_event_code(evdev, EV_KEY, code))
195 			continue;
196 
197 		litest_assert_tablet_button_event(li,
198 					  code,
199 					  LIBINPUT_BUTTON_STATE_RELEASED);
200 	}
201 
202 	litest_assert_tablet_proximity_event(li,
203 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
204 	libevdev_free(evdev);
205 	litest_destroy_context(li);
206 }
207 END_TEST
208 
START_TEST(tip_down_up)209 START_TEST(tip_down_up)
210 {
211 	struct litest_device *dev = litest_current_device();
212 	struct libinput *li = dev->libinput;
213 	struct libinput_event *event;
214 	struct libinput_event_tablet_tool *tablet_event;
215 	struct axis_replacement axes[] = {
216 		{ ABS_DISTANCE, 10 },
217 		{ ABS_PRESSURE, 0 },
218 		{ -1, -1 }
219 	};
220 
221 	litest_tablet_proximity_in(dev, 10, 10, axes);
222 	litest_drain_events(li);
223 
224 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
225 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
226 	litest_push_event_frame(dev);
227 	litest_tablet_motion(dev, 10, 10, axes);
228 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
229 	litest_pop_event_frame(dev);
230 
231 	libinput_dispatch(li);
232 
233 	event = libinput_get_event(li);
234 	tablet_event = litest_is_tablet_event(event,
235 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
236 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
237 			 LIBINPUT_TABLET_TOOL_TIP_DOWN);
238 	libinput_event_destroy(event);
239 	litest_assert_empty_queue(li);
240 
241 	litest_axis_set_value(axes, ABS_DISTANCE, 10);
242 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
243 	litest_push_event_frame(dev);
244 	litest_tablet_motion(dev, 10, 10, axes);
245 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
246 	litest_pop_event_frame(dev);
247 
248 	libinput_dispatch(li);
249 	event = libinput_get_event(li);
250 	tablet_event = litest_is_tablet_event(event,
251 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
252 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
253 			 LIBINPUT_TABLET_TOOL_TIP_UP);
254 	libinput_event_destroy(event);
255 
256 	litest_assert_empty_queue(li);
257 
258 }
259 END_TEST
260 
START_TEST(tip_down_prox_in)261 START_TEST(tip_down_prox_in)
262 {
263 	struct litest_device *dev = litest_current_device();
264 	struct libinput *li = dev->libinput;
265 	struct libinput_event *event;
266 	struct libinput_event_tablet_tool *tablet_event;
267 	struct axis_replacement axes[] = {
268 		{ ABS_DISTANCE, 0 },
269 		{ ABS_PRESSURE, 30 },
270 		{ -1, -1 }
271 	};
272 
273 	litest_drain_events(li);
274 
275 	litest_push_event_frame(dev);
276 	litest_tablet_proximity_in(dev, 10, 10, axes);
277 	litest_tablet_motion(dev, 10, 10, axes);
278 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
279 	litest_pop_event_frame(dev);
280 
281 	libinput_dispatch(li);
282 	event = libinput_get_event(li);
283 	tablet_event = litest_is_tablet_event(event,
284 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
285 	ck_assert_int_eq(libinput_event_tablet_tool_get_proximity_state(tablet_event),
286 			 LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
287 	libinput_event_destroy(event);
288 
289 	event = libinput_get_event(li);
290 	tablet_event = litest_is_tablet_event(event,
291 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
292 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
293 			 LIBINPUT_TABLET_TOOL_TIP_DOWN);
294 	libinput_event_destroy(event);
295 
296 	litest_assert_empty_queue(li);
297 
298 }
299 END_TEST
300 
START_TEST(tip_up_prox_out)301 START_TEST(tip_up_prox_out)
302 {
303 	struct litest_device *dev = litest_current_device();
304 	struct libinput *li = dev->libinput;
305 	struct libinput_event *event;
306 	struct libinput_event_tablet_tool *tablet_event;
307 	struct axis_replacement axes[] = {
308 		{ ABS_DISTANCE, 0 },
309 		{ ABS_PRESSURE, 30 },
310 		{ -1, -1 }
311 	};
312 
313 	litest_tablet_proximity_in(dev, 10, 10, axes);
314 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
315 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
316 	litest_drain_events(li);
317 
318 	litest_axis_set_value(axes, ABS_DISTANCE, 30);
319 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
320 	litest_push_event_frame(dev);
321 	litest_tablet_motion(dev, 10, 10, axes);
322 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
323 	litest_tablet_proximity_out(dev);
324 	litest_pop_event_frame(dev);
325 
326 	libinput_dispatch(li);
327 	event = libinput_get_event(li);
328 	tablet_event = litest_is_tablet_event(event,
329 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
330 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
331 			 LIBINPUT_TABLET_TOOL_TIP_UP);
332 	libinput_event_destroy(event);
333 
334 	litest_timeout_tablet_proxout();
335 	libinput_dispatch(li);
336 	event = libinput_get_event(li);
337 	tablet_event = litest_is_tablet_event(event,
338 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
339 	ck_assert_int_eq(libinput_event_tablet_tool_get_proximity_state(tablet_event),
340 			 LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
341 	libinput_event_destroy(event);
342 
343 	litest_assert_empty_queue(li);
344 
345 }
346 END_TEST
347 
START_TEST(tip_up_btn_change)348 START_TEST(tip_up_btn_change)
349 {
350 	struct litest_device *dev = litest_current_device();
351 	struct libinput *li = dev->libinput;
352 	struct libinput_event *event;
353 	struct libinput_event_tablet_tool *tablet_event;
354 	struct axis_replacement axes[] = {
355 		{ ABS_DISTANCE, 0 },
356 		{ ABS_PRESSURE, 30 },
357 		{ -1, -1 }
358 	};
359 
360 	litest_push_event_frame(dev);
361 	litest_tablet_proximity_in(dev, 10, 10, axes);
362 	litest_tablet_motion(dev, 10, 10, axes);
363 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
364 	litest_pop_event_frame(dev);
365 	litest_drain_events(li);
366 
367 	litest_axis_set_value(axes, ABS_DISTANCE, 30);
368 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
369 	litest_push_event_frame(dev);
370 	litest_tablet_motion(dev, 10, 20, axes);
371 	litest_event(dev, EV_KEY, BTN_STYLUS, 1);
372 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
373 	litest_pop_event_frame(dev);
374 
375 	libinput_dispatch(li);
376 
377 	event = libinput_get_event(li);
378 	tablet_event = litest_is_tablet_event(event,
379 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
380 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
381 			 LIBINPUT_TABLET_TOOL_TIP_UP);
382 	libinput_event_destroy(event);
383 
384 	event = libinput_get_event(li);
385 	tablet_event = litest_is_tablet_event(event,
386 					      LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
387 	ck_assert_int_eq(libinput_event_tablet_tool_get_button(tablet_event),
388 			 BTN_STYLUS);
389 	ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tablet_event),
390 			 LIBINPUT_BUTTON_STATE_PRESSED);
391 	libinput_event_destroy(event);
392 
393 	litest_assert_empty_queue(li);
394 
395 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
396 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
397 	litest_push_event_frame(dev);
398 	litest_tablet_motion(dev, 10, 10, axes);
399 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
400 	litest_pop_event_frame(dev);
401 	litest_drain_events(li);
402 
403 	/* same thing with a release at tip-up */
404 	litest_axis_set_value(axes, ABS_DISTANCE, 30);
405 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
406 	litest_push_event_frame(dev);
407 	litest_tablet_motion(dev, 10, 10, axes);
408 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
409 	litest_event(dev, EV_KEY, BTN_STYLUS, 0);
410 	litest_pop_event_frame(dev);
411 
412 	libinput_dispatch(li);
413 
414 	event = libinput_get_event(li);
415 	tablet_event = litest_is_tablet_event(event,
416 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
417 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
418 			 LIBINPUT_TABLET_TOOL_TIP_UP);
419 	libinput_event_destroy(event);
420 
421 	event = libinput_get_event(li);
422 	tablet_event = litest_is_tablet_event(event,
423 					      LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
424 	ck_assert_int_eq(libinput_event_tablet_tool_get_button(tablet_event),
425 			 BTN_STYLUS);
426 	ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tablet_event),
427 			 LIBINPUT_BUTTON_STATE_RELEASED);
428 	libinput_event_destroy(event);
429 
430 	litest_assert_empty_queue(li);
431 }
432 END_TEST
433 
START_TEST(tip_down_btn_change)434 START_TEST(tip_down_btn_change)
435 {
436 	struct litest_device *dev = litest_current_device();
437 	struct libinput *li = dev->libinput;
438 	struct libinput_event *event;
439 	struct libinput_event_tablet_tool *tablet_event;
440 	struct axis_replacement axes[] = {
441 		{ ABS_DISTANCE, 10 },
442 		{ ABS_PRESSURE, 0 },
443 		{ -1, -1 }
444 	};
445 
446 	litest_tablet_proximity_in(dev, 10, 10, axes);
447 	litest_drain_events(li);
448 
449 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
450 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
451 	litest_push_event_frame(dev);
452 	litest_tablet_motion(dev, 10, 20, axes);
453 	litest_event(dev, EV_KEY, BTN_STYLUS, 1);
454 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
455 	litest_pop_event_frame(dev);
456 
457 	libinput_dispatch(li);
458 
459 	event = libinput_get_event(li);
460 	tablet_event = litest_is_tablet_event(event,
461 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
462 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
463 			 LIBINPUT_TABLET_TOOL_TIP_DOWN);
464 	libinput_event_destroy(event);
465 
466 	libinput_dispatch(li);
467 	event = libinput_get_event(li);
468 	tablet_event = litest_is_tablet_event(event,
469 					      LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
470 	ck_assert_int_eq(libinput_event_tablet_tool_get_button(tablet_event),
471 			 BTN_STYLUS);
472 	ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tablet_event),
473 			 LIBINPUT_BUTTON_STATE_PRESSED);
474 	libinput_event_destroy(event);
475 
476 	litest_assert_empty_queue(li);
477 
478 	litest_axis_set_value(axes, ABS_DISTANCE, 30);
479 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
480 	litest_push_event_frame(dev);
481 	litest_tablet_motion(dev, 10, 20, axes);
482 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
483 	litest_pop_event_frame(dev);
484 	litest_drain_events(li);
485 
486 	/* same thing with a release at tip-down */
487 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
488 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
489 	litest_push_event_frame(dev);
490 	litest_tablet_motion(dev, 10, 20, axes);
491 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
492 	litest_event(dev, EV_KEY, BTN_STYLUS, 0);
493 	litest_pop_event_frame(dev);
494 
495 	libinput_dispatch(li);
496 
497 	event = libinput_get_event(li);
498 	tablet_event = litest_is_tablet_event(event,
499 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
500 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
501 			 LIBINPUT_TABLET_TOOL_TIP_DOWN);
502 	libinput_event_destroy(event);
503 
504 	libinput_dispatch(li);
505 	event = libinput_get_event(li);
506 	tablet_event = litest_is_tablet_event(event,
507 					      LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
508 	ck_assert_int_eq(libinput_event_tablet_tool_get_button(tablet_event),
509 			 BTN_STYLUS);
510 	ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tablet_event),
511 			 LIBINPUT_BUTTON_STATE_RELEASED);
512 	libinput_event_destroy(event);
513 
514 	litest_assert_empty_queue(li);
515 }
516 END_TEST
517 
START_TEST(tip_down_motion)518 START_TEST(tip_down_motion)
519 {
520 	struct litest_device *dev = litest_current_device();
521 	struct libinput *li = dev->libinput;
522 	struct libinput_event *event;
523 	struct libinput_event_tablet_tool *tablet_event;
524 	struct axis_replacement axes[] = {
525 		{ ABS_DISTANCE, 10 },
526 		{ ABS_PRESSURE, 0 },
527 		{ -1, -1 }
528 	};
529 	double x, y, last_x, last_y;
530 
531 	litest_drain_events(li);
532 
533 	litest_tablet_proximity_in(dev, 10, 10, axes);
534 	libinput_dispatch(li);
535 	event = libinput_get_event(li);
536 	tablet_event = litest_is_tablet_event(event,
537 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
538 	last_x = libinput_event_tablet_tool_get_x(tablet_event);
539 	last_y = libinput_event_tablet_tool_get_y(tablet_event);
540 	libinput_event_destroy(event);
541 
542 	/* move x/y on tip down, make sure x/y changed */
543 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
544 	litest_axis_set_value(axes, ABS_PRESSURE, 20);
545 	litest_push_event_frame(dev);
546 	litest_tablet_motion(dev, 70, 70, axes);
547 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
548 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
549 	litest_pop_event_frame(dev);
550 
551 	libinput_dispatch(li);
552 	event = libinput_get_event(li);
553 	tablet_event = litest_is_tablet_event(event,
554 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
555 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
556 			 LIBINPUT_TABLET_TOOL_TIP_DOWN);
557 	ck_assert(libinput_event_tablet_tool_x_has_changed(tablet_event));
558 	ck_assert(libinput_event_tablet_tool_y_has_changed(tablet_event));
559 	x = libinput_event_tablet_tool_get_x(tablet_event);
560 	y = libinput_event_tablet_tool_get_y(tablet_event);
561 	ck_assert_double_lt(last_x, x);
562 	ck_assert_double_lt(last_y, y);
563 	libinput_event_destroy(event);
564 
565 	litest_assert_empty_queue(li);
566 }
567 END_TEST
568 
START_TEST(tip_up_motion)569 START_TEST(tip_up_motion)
570 {
571 	struct litest_device *dev = litest_current_device();
572 	struct libinput *li = dev->libinput;
573 	struct libinput_event *event;
574 	struct libinput_event_tablet_tool *tablet_event;
575 	struct axis_replacement axes[] = {
576 		{ ABS_DISTANCE, 0 },
577 		{ ABS_PRESSURE, 0 },
578 		{ -1, -1 }
579 	};
580 	double x, y, last_x, last_y;
581 
582 	litest_tablet_proximity_in(dev, 10, 10, axes);
583 	litest_drain_events(li);
584 
585 	litest_axis_set_value(axes, ABS_PRESSURE, 20);
586 	litest_push_event_frame(dev);
587 	litest_tablet_motion(dev, 70, 70, axes);
588 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
589 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
590 	litest_pop_event_frame(dev);
591 
592 	libinput_dispatch(li);
593 	event = libinput_get_event(li);
594 	tablet_event = litest_is_tablet_event(event,
595 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
596 	last_x = libinput_event_tablet_tool_get_x(tablet_event);
597 	last_y = libinput_event_tablet_tool_get_y(tablet_event);
598 	libinput_event_destroy(event);
599 
600 	/* move x/y on tip up, make sure x/y changed */
601 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
602 	litest_push_event_frame(dev);
603 	litest_tablet_motion(dev, 40, 40, axes);
604 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
605 	litest_pop_event_frame(dev);
606 
607 	libinput_dispatch(li);
608 	event = libinput_get_event(li);
609 	tablet_event = litest_is_tablet_event(event,
610 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
611 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
612 			 LIBINPUT_TABLET_TOOL_TIP_UP);
613 	ck_assert(libinput_event_tablet_tool_x_has_changed(tablet_event));
614 	ck_assert(libinput_event_tablet_tool_y_has_changed(tablet_event));
615 	x = libinput_event_tablet_tool_get_x(tablet_event);
616 	y = libinput_event_tablet_tool_get_y(tablet_event);
617 	ck_assert_double_ne(last_x, x);
618 	ck_assert_double_ne(last_y, y);
619 	libinput_event_destroy(event);
620 
621 	litest_assert_empty_queue(li);
622 }
623 END_TEST
624 
START_TEST(tip_up_motion_one_axis)625 START_TEST(tip_up_motion_one_axis)
626 {
627 	struct litest_device *dev = litest_current_device();
628 	struct libinput *li = dev->libinput;
629 	struct libinput_event *event;
630 	struct libinput_event_tablet_tool *tablet_event;
631 	struct axis_replacement axes[] = {
632 		{ ABS_DISTANCE, 0 },
633 		{ ABS_PRESSURE, 0 },
634 		{ -1, -1 }
635 	};
636 	unsigned int axis = _i; /* ranged test */
637 	double x, y, last_x, last_y;
638 	double start_x = 20,
639 	       start_y = 20;
640 
641 	switch (axis) {
642 	case ABS_X:
643 		start_x = 15;
644 		start_y = 20;
645 		break;
646 	case ABS_Y:
647 		start_x = 20;
648 		start_y = 15;
649 		break;
650 	default:
651 		abort();
652 	}
653 
654 	/* generate enough events to fill the history and move alonge the
655 	 * current axis to avoid axis smoothing interference */
656 	litest_tablet_proximity_in(dev, start_x, start_y, axes);
657 	litest_axis_set_value(axes, ABS_PRESSURE, 20);
658 	for (int i = 0; i < 5; i++) {
659 		litest_push_event_frame(dev);
660 		litest_tablet_motion(dev, start_x, start_y, axes);
661 		litest_event(dev, EV_KEY, BTN_TOUCH, 1);
662 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
663 		litest_pop_event_frame(dev);
664 
665 		switch (axis) {
666 		case ABS_X:
667 			start_x++;
668 			break;
669 		case ABS_Y:
670 			start_y++;
671 			break;
672 		}
673 
674 	}
675 	litest_drain_events(li);
676 
677 	litest_tablet_motion(dev, 20, 20, axes);
678 	libinput_dispatch(li);
679 	event = libinput_get_event(li);
680 	tablet_event = litest_is_tablet_event(event,
681 					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
682 	last_x = libinput_event_tablet_tool_get_x(tablet_event);
683 	last_y = libinput_event_tablet_tool_get_y(tablet_event);
684 	libinput_event_destroy(event);
685 
686 	/* move x on tip up, make sure x/y changed */
687 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
688 	litest_push_event_frame(dev);
689 	switch (axis) {
690 	case ABS_X:
691 		litest_tablet_motion(dev, 40, 20, axes);
692 		break;
693 	case ABS_Y:
694 		litest_tablet_motion(dev, 20, 40, axes);
695 		break;
696 	}
697 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
698 	litest_pop_event_frame(dev);
699 
700 	libinput_dispatch(li);
701 	event = libinput_get_event(li);
702 	tablet_event = litest_is_tablet_event(event,
703 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
704 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
705 			 LIBINPUT_TABLET_TOOL_TIP_UP);
706 	x = libinput_event_tablet_tool_get_x(tablet_event);
707 	y = libinput_event_tablet_tool_get_y(tablet_event);
708 
709 	switch(axis) {
710 	case ABS_X:
711 		ck_assert(libinput_event_tablet_tool_x_has_changed(tablet_event));
712 		ck_assert(!libinput_event_tablet_tool_y_has_changed(tablet_event));
713 		ck_assert_double_ne(last_x, x);
714 		ck_assert_double_eq(last_y, y);
715 		break;
716 	case ABS_Y:
717 		ck_assert(!libinput_event_tablet_tool_x_has_changed(tablet_event));
718 		ck_assert(libinput_event_tablet_tool_y_has_changed(tablet_event));
719 		ck_assert_double_eq(last_x, x);
720 		ck_assert_double_ne(last_y, y);
721 		break;
722 	}
723 
724 	libinput_event_destroy(event);
725 
726 	litest_assert_empty_queue(li);
727 }
728 END_TEST
729 
START_TEST(tip_state_proximity)730 START_TEST(tip_state_proximity)
731 {
732 	struct litest_device *dev = litest_current_device();
733 	struct libinput *li = dev->libinput;
734 	struct libinput_event *event;
735 	struct libinput_event_tablet_tool *tablet_event;
736 	struct axis_replacement axes[] = {
737 		{ ABS_DISTANCE, 10 },
738 		{ ABS_PRESSURE, 0 },
739 		{ -1, -1 }
740 	};
741 
742 	litest_drain_events(li);
743 
744 	litest_tablet_proximity_in(dev, 10, 10, axes);
745 	libinput_dispatch(li);
746 
747 	event = libinput_get_event(li);
748 	tablet_event = litest_is_tablet_event(event,
749 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
750 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
751 			 LIBINPUT_TABLET_TOOL_TIP_UP);
752 	libinput_event_destroy(event);
753 
754 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
755 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
756 	litest_push_event_frame(dev);
757 	litest_tablet_motion(dev, 10, 10, axes);
758 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
759 	litest_pop_event_frame(dev);
760 
761 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
762 	litest_axis_set_value(axes, ABS_DISTANCE, 10);
763 	litest_push_event_frame(dev);
764 	litest_tablet_motion(dev, 10, 10, axes);
765 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
766 	litest_pop_event_frame(dev);
767 
768 	litest_drain_events(li);
769 
770 	litest_tablet_proximity_out(dev);
771 	libinput_dispatch(li);
772 
773 	litest_timeout_tablet_proxout();
774 	libinput_dispatch(li);
775 
776 	event = libinput_get_event(li);
777 	tablet_event = litest_is_tablet_event(event,
778 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
779 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
780 			 LIBINPUT_TABLET_TOOL_TIP_UP);
781 	libinput_event_destroy(event);
782 }
783 END_TEST
784 
START_TEST(tip_state_axis)785 START_TEST(tip_state_axis)
786 {
787 	struct litest_device *dev = litest_current_device();
788 	struct libinput *li = dev->libinput;
789 	struct libinput_event *event;
790 	struct libinput_event_tablet_tool *tablet_event;
791 	struct axis_replacement axes[] = {
792 		{ ABS_DISTANCE, 10 },
793 		{ ABS_PRESSURE, 0 },
794 		{ -1, -1 }
795 	};
796 
797 	litest_tablet_proximity_in(dev, 10, 10, axes);
798 	litest_drain_events(li);
799 
800 	litest_tablet_motion(dev, 70, 70, axes);
801 	libinput_dispatch(li);
802 
803 	event = libinput_get_event(li);
804 	tablet_event = litest_is_tablet_event(event,
805 					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
806 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
807 			 LIBINPUT_TABLET_TOOL_TIP_UP);
808 	libinput_event_destroy(event);
809 
810 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
811 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
812 	litest_push_event_frame(dev);
813 	litest_tablet_motion(dev, 40, 40, axes);
814 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
815 	litest_pop_event_frame(dev);
816 	litest_drain_events(li);
817 
818 	litest_tablet_motion(dev, 30, 30, axes);
819 	libinput_dispatch(li);
820 
821 	event = libinput_get_event(li);
822 	tablet_event = litest_is_tablet_event(event,
823 					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
824 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
825 			 LIBINPUT_TABLET_TOOL_TIP_DOWN);
826 	libinput_event_destroy(event);
827 
828 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
829 	litest_axis_set_value(axes, ABS_DISTANCE, 10);
830 	litest_push_event_frame(dev);
831 	litest_tablet_motion(dev, 40, 40, axes);
832 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
833 	litest_pop_event_frame(dev);
834 	litest_drain_events(li);
835 
836 	litest_tablet_motion(dev, 40, 80, axes);
837 	libinput_dispatch(li);
838 
839 	event = libinput_get_event(li);
840 	tablet_event = litest_is_tablet_event(event,
841 					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
842 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
843 			 LIBINPUT_TABLET_TOOL_TIP_UP);
844 	libinput_event_destroy(event);
845 
846 	litest_assert_empty_queue(li);
847 }
848 END_TEST
849 
START_TEST(tip_state_button)850 START_TEST(tip_state_button)
851 {
852 	struct litest_device *dev = litest_current_device();
853 	struct libinput *li = dev->libinput;
854 	struct libinput_event *event;
855 	struct libinput_event_tablet_tool *tablet_event;
856 	struct axis_replacement axes[] = {
857 		{ ABS_DISTANCE, 10 },
858 		{ ABS_PRESSURE, 0 },
859 		{ -1, -1 }
860 	};
861 	unsigned int button = pick_stylus_or_btn0(dev);
862 
863 	litest_tablet_proximity_in(dev, 10, 10, axes);
864 	litest_drain_events(li);
865 
866 	litest_button_click(dev, button, true);
867 	libinput_dispatch(li);
868 
869 	event = libinput_get_event(li);
870 	tablet_event = litest_is_tablet_event(event,
871 					      LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
872 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
873 			 LIBINPUT_TABLET_TOOL_TIP_UP);
874 	libinput_event_destroy(event);
875 
876 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
877 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
878 	litest_push_event_frame(dev);
879 	litest_tablet_motion(dev, 40, 40, axes);
880 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
881 	litest_pop_event_frame(dev);
882 	litest_drain_events(li);
883 
884 	litest_button_click(dev, button, false);
885 	libinput_dispatch(li);
886 
887 	event = libinput_get_event(li);
888 	tablet_event = litest_is_tablet_event(event,
889 					      LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
890 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
891 			 LIBINPUT_TABLET_TOOL_TIP_DOWN);
892 	libinput_event_destroy(event);
893 
894 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
895 	litest_axis_set_value(axes, ABS_DISTANCE, 10);
896 	litest_push_event_frame(dev);
897 	litest_tablet_motion(dev, 40, 40, axes);
898 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
899 	litest_pop_event_frame(dev);
900 	litest_drain_events(li);
901 
902 	litest_button_click(dev, button, true);
903 	libinput_dispatch(li);
904 
905 	event = libinput_get_event(li);
906 	tablet_event = litest_is_tablet_event(event,
907 					      LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
908 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
909 			 LIBINPUT_TABLET_TOOL_TIP_UP);
910 	libinput_event_destroy(event);
911 
912 	litest_button_click(dev, button, false);
913 	libinput_dispatch(li);
914 
915 	event = libinput_get_event(li);
916 	tablet_event = litest_is_tablet_event(event,
917 					      LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
918 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
919 			 LIBINPUT_TABLET_TOOL_TIP_UP);
920 	libinput_event_destroy(event);
921 
922 	litest_assert_empty_queue(li);
923 }
924 END_TEST
925 
START_TEST(tip_up_on_delete)926 START_TEST(tip_up_on_delete)
927 {
928 	struct libinput *li = litest_create_context();
929 	struct litest_device *dev = litest_add_device(li, LITEST_WACOM_INTUOS);
930 	struct libinput_event *event;
931 	struct libinput_event_tablet_tool *tablet_event;
932 	struct axis_replacement axes[] = {
933 		{ ABS_DISTANCE, 10 },
934 		{ ABS_PRESSURE, 0 },
935 		{ -1, -1 }
936 	};
937 
938 	litest_tablet_proximity_in(dev, 10, 10, axes);
939 	litest_drain_events(li);
940 
941 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
942 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
943 	litest_push_event_frame(dev);
944 	litest_tablet_motion(dev, 10, 10, axes);
945 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
946 	litest_pop_event_frame(dev);
947 
948 	litest_drain_events(li);
949 	litest_delete_device(dev);
950 	libinput_dispatch(li);
951 
952 	event = libinput_get_event(li);
953 	tablet_event = litest_is_tablet_event(event,
954 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
955 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
956 			 LIBINPUT_TABLET_TOOL_TIP_UP);
957 	libinput_event_destroy(event);
958 
959 	litest_destroy_context(li);
960 }
961 END_TEST
962 
START_TEST(proximity_in_out)963 START_TEST(proximity_in_out)
964 {
965 	struct litest_device *dev = litest_current_device();
966 	struct libinput *li = dev->libinput;
967 	struct libinput_event_tablet_tool *tablet_event;
968 	struct libinput_event *event;
969 	enum libinput_tablet_tool_type type;
970 	bool have_tool_update = false,
971 	     have_proximity_out = false;
972 
973 	struct axis_replacement axes[] = {
974 		{ ABS_DISTANCE, 10 },
975 		{ ABS_PRESSURE, 0 },
976 		{ -1, -1 }
977 	};
978 
979 	litest_drain_events(li);
980 
981 	switch (dev->which) {
982 	case LITEST_DELL_CANVAS_TOTEM:
983 		type = LIBINPUT_TABLET_TOOL_TYPE_TOTEM;
984 		break;
985 	default:
986 		type = LIBINPUT_TABLET_TOOL_TYPE_PEN;
987 		break;
988 	}
989 
990 	litest_tablet_proximity_in(dev, 10, 10, axes);
991 	libinput_dispatch(li);
992 
993 	while ((event = libinput_get_event(li))) {
994 		if (libinput_event_get_type(event) ==
995 		    LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY) {
996 			struct libinput_tablet_tool * tool;
997 
998 			ck_assert(!have_tool_update);
999 			have_tool_update = true;
1000 			tablet_event = libinput_event_get_tablet_tool_event(event);
1001 			tool = libinput_event_tablet_tool_get_tool(tablet_event);
1002 			ck_assert_int_eq(libinput_tablet_tool_get_type(tool), type);
1003 		}
1004 		libinput_event_destroy(event);
1005 	}
1006 	ck_assert(have_tool_update);
1007 
1008 	litest_tablet_proximity_out(dev);
1009 	libinput_dispatch(li);
1010 
1011 	litest_timeout_tablet_proxout();
1012 	libinput_dispatch(li);
1013 
1014 	while ((event = libinput_get_event(li))) {
1015 		if (libinput_event_get_type(event) ==
1016 		    LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY) {
1017 			struct libinput_event_tablet_tool *t =
1018 				libinput_event_get_tablet_tool_event(event);
1019 
1020 			if (libinput_event_tablet_tool_get_proximity_state(t) ==
1021 			    LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT)
1022 				have_proximity_out = true;
1023 		}
1024 
1025 		libinput_event_destroy(event);
1026 	}
1027 	ck_assert(have_proximity_out);
1028 
1029 	/* Proximity out must not emit axis events */
1030 	litest_assert_empty_queue(li);
1031 }
1032 END_TEST
1033 
START_TEST(proximity_in_button_down)1034 START_TEST(proximity_in_button_down)
1035 {
1036 	struct litest_device *dev = litest_current_device();
1037 	struct libinput *li = dev->libinput;
1038 	struct axis_replacement axes[] = {
1039 		{ ABS_DISTANCE, 10 },
1040 		{ ABS_PRESSURE, 0 },
1041 		{ -1, -1 }
1042 	};
1043 	unsigned int button = pick_stylus_or_btn0(dev);
1044 
1045 	litest_drain_events(li);
1046 
1047 	litest_push_event_frame(dev);
1048 	litest_tablet_proximity_in(dev, 10, 10, axes);
1049 	litest_event(dev, EV_KEY, button, 1);
1050 	litest_pop_event_frame(dev);
1051 	libinput_dispatch(li);
1052 
1053 	litest_assert_tablet_proximity_event(li,
1054 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
1055 	litest_drain_events_of_type(li, LIBINPUT_EVENT_TABLET_TOOL_TIP, -1);
1056 	litest_assert_tablet_button_event(li,
1057 					  button,
1058 					  LIBINPUT_BUTTON_STATE_PRESSED);
1059 	litest_assert_empty_queue(li);
1060 }
1061 END_TEST
1062 
START_TEST(proximity_out_button_up)1063 START_TEST(proximity_out_button_up)
1064 {
1065 	struct litest_device *dev = litest_current_device();
1066 	struct libinput *li = dev->libinput;
1067 	struct axis_replacement axes[] = {
1068 		{ ABS_DISTANCE, 10 },
1069 		{ ABS_PRESSURE, 0 },
1070 		{ -1, -1 }
1071 	};
1072 	unsigned int button = pick_stylus_or_btn0(dev);
1073 
1074 	litest_tablet_proximity_in(dev, 10, 10, axes);
1075 
1076 	litest_button_click(dev, button, true);
1077 	litest_drain_events(li);
1078 
1079 	litest_push_event_frame(dev);
1080 	litest_tablet_proximity_out(dev);
1081 	litest_event(dev, EV_KEY, button, 0);
1082 	litest_pop_event_frame(dev);
1083 	libinput_dispatch(li);
1084 
1085 	litest_timeout_tablet_proxout();
1086 	libinput_dispatch(li);
1087 
1088 	litest_assert_tablet_button_event(li,
1089 					  button,
1090 					  LIBINPUT_BUTTON_STATE_RELEASED);
1091 	litest_drain_events_of_type(li, LIBINPUT_EVENT_TABLET_TOOL_TIP, -1);
1092 	litest_assert_tablet_proximity_event(li,
1093 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1094 	litest_assert_empty_queue(li);
1095 }
1096 END_TEST
1097 
START_TEST(proximity_out_clear_buttons)1098 START_TEST(proximity_out_clear_buttons)
1099 {
1100 	struct litest_device *dev = litest_current_device();
1101 	struct libinput *li = dev->libinput;
1102 	struct libinput_event_tablet_tool *tablet_event;
1103 	struct libinput_event *event;
1104 	uint32_t button;
1105 	struct axis_replacement axes[] = {
1106 		{ ABS_DISTANCE, 10 },
1107 		{ ABS_PRESSURE, 0 },
1108 		{ -1, -1 }
1109 	};
1110 	bool have_proximity = false;
1111 	double x = 50, y = 50;
1112 
1113 	litest_drain_events(li);
1114 
1115 	/* Test that proximity out events send button releases for any currently
1116 	 * pressed stylus buttons
1117 	 */
1118 	for (button = BTN_STYLUS; button <= BTN_STYLUS2; button++) {
1119 		bool button_released = false;
1120 		uint32_t event_button = 0;
1121 		enum libinput_button_state state;
1122 
1123 		if (!libevdev_has_event_code(dev->evdev, EV_KEY, button))
1124 			continue;
1125 
1126 		litest_tablet_proximity_in(dev, x++, y++, axes);
1127 		litest_drain_events(li);
1128 
1129 		litest_event(dev, EV_KEY, button, 1);
1130 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
1131 		litest_tablet_proximity_out(dev);
1132 		libinput_dispatch(li);
1133 
1134 		event = libinput_get_event(li);
1135 		ck_assert_notnull(event);
1136 		do {
1137 			tablet_event = libinput_event_get_tablet_tool_event(event);
1138 
1139 			if (libinput_event_get_type(event) ==
1140 			    LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY) {
1141 				have_proximity = true;
1142 				libinput_event_destroy(event);
1143 				break;
1144 			}
1145 
1146 			if (libinput_event_get_type(event) ==
1147 			    LIBINPUT_EVENT_TABLET_TOOL_BUTTON) {
1148 
1149 				event_button = libinput_event_tablet_tool_get_button(tablet_event);
1150 				state = libinput_event_tablet_tool_get_button_state(tablet_event);
1151 
1152 				if (event_button == button &&
1153 				    state == LIBINPUT_BUTTON_STATE_RELEASED)
1154 					button_released = true;
1155 			}
1156 
1157 			libinput_event_destroy(event);
1158 		} while ((event = libinput_get_event(li)));
1159 
1160 		ck_assert_msg(button_released,
1161 			      "Button %s (%d) was not released.",
1162 			      libevdev_event_code_get_name(EV_KEY, button),
1163 			      event_button);
1164 		litest_assert(have_proximity);
1165 		litest_assert_empty_queue(li);
1166 	}
1167 }
1168 END_TEST
1169 
START_TEST(proximity_has_axes)1170 START_TEST(proximity_has_axes)
1171 {
1172 	struct litest_device *dev = litest_current_device();
1173 	struct libinput *li = dev->libinput;
1174 	struct libinput_event_tablet_tool *tablet_event;
1175 	struct libinput_event *event;
1176 	struct libinput_tablet_tool *tool;
1177 	double x, y,
1178 	       distance;
1179 	double last_x, last_y,
1180 	       last_distance = 0.0,
1181 	       last_tx = 0.0, last_ty = 0.0;
1182 
1183 	struct axis_replacement axes[] = {
1184 		{ ABS_DISTANCE, 10 },
1185 		{ ABS_PRESSURE, 0 },
1186 		{ ABS_TILT_X, 10 },
1187 		{ ABS_TILT_Y, 10 },
1188 		{ -1, -1}
1189 	};
1190 
1191 	litest_drain_events(li);
1192 
1193 	litest_tablet_proximity_in(dev, 10, 10, axes);
1194 	libinput_dispatch(li);
1195 
1196 	event = libinput_get_event(li);
1197 	tablet_event = litest_is_tablet_event(event,
1198 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1199 	tool = libinput_event_tablet_tool_get_tool(tablet_event);
1200 
1201 	ck_assert(libinput_event_tablet_tool_x_has_changed(tablet_event));
1202 	ck_assert(libinput_event_tablet_tool_y_has_changed(tablet_event));
1203 
1204 	x = libinput_event_tablet_tool_get_x(tablet_event);
1205 	y = libinput_event_tablet_tool_get_y(tablet_event);
1206 
1207 	litest_assert_double_ne(x, 0);
1208 	litest_assert_double_ne(y, 0);
1209 
1210 	if (libinput_tablet_tool_has_distance(tool)) {
1211 		ck_assert(libinput_event_tablet_tool_distance_has_changed(
1212 				tablet_event));
1213 
1214 		distance = libinput_event_tablet_tool_get_distance(tablet_event);
1215 		litest_assert_double_ne(distance, 0);
1216 	}
1217 
1218 	if (libinput_tablet_tool_has_tilt(tool)) {
1219 		ck_assert(libinput_event_tablet_tool_tilt_x_has_changed(
1220 				tablet_event));
1221 		ck_assert(libinput_event_tablet_tool_tilt_y_has_changed(
1222 				tablet_event));
1223 
1224 		x = libinput_event_tablet_tool_get_tilt_x(tablet_event);
1225 		y = libinput_event_tablet_tool_get_tilt_y(tablet_event);
1226 
1227 		litest_assert_double_ne(x, 0);
1228 		litest_assert_double_ne(y, 0);
1229 	}
1230 
1231 	litest_drain_events_of_type(li, LIBINPUT_EVENT_TABLET_TOOL_TIP, -1);
1232 
1233 	litest_assert_empty_queue(li);
1234 	libinput_event_destroy(event);
1235 
1236 	litest_axis_set_value(axes, ABS_DISTANCE, 20);
1237 	litest_axis_set_value(axes, ABS_TILT_X, 15);
1238 	litest_axis_set_value(axes, ABS_TILT_Y, 25);
1239 
1240 	/* work around axis smoothing */
1241 	litest_tablet_motion(dev, 20, 30, axes);
1242 	litest_tablet_motion(dev, 20, 29, axes);
1243 	litest_tablet_motion(dev, 20, 31, axes);
1244 	litest_drain_events(li);
1245 
1246 	litest_tablet_motion(dev, 20, 30, axes);
1247 	libinput_dispatch(li);
1248 	event = libinput_get_event(li);
1249 	tablet_event = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
1250 
1251 	last_x = libinput_event_tablet_tool_get_x(tablet_event);
1252 	last_y = libinput_event_tablet_tool_get_y(tablet_event);
1253 	if (libinput_tablet_tool_has_distance(tool))
1254 		last_distance = libinput_event_tablet_tool_get_distance(
1255 					     tablet_event);
1256 	if (libinput_tablet_tool_has_tilt(tool)) {
1257 		last_tx = libinput_event_tablet_tool_get_tilt_x(tablet_event);
1258 		last_ty = libinput_event_tablet_tool_get_tilt_y(tablet_event);
1259 	}
1260 
1261 	libinput_event_destroy(event);
1262 
1263 	/* Make sure that the axes are still present on proximity out */
1264 	litest_tablet_proximity_out(dev);
1265 	libinput_dispatch(li);
1266 
1267 	litest_timeout_tablet_proxout();
1268 	libinput_dispatch(li);
1269 
1270 	litest_drain_events_of_type(li, LIBINPUT_EVENT_TABLET_TOOL_TIP, -1);
1271 
1272 	event = libinput_get_event(li);
1273 	tablet_event = litest_is_tablet_event(event,
1274 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1275 	tool = libinput_event_tablet_tool_get_tool(tablet_event);
1276 
1277 	ck_assert(!libinput_event_tablet_tool_x_has_changed(tablet_event));
1278 	ck_assert(!libinput_event_tablet_tool_y_has_changed(tablet_event));
1279 
1280 	x = libinput_event_tablet_tool_get_x(tablet_event);
1281 	y = libinput_event_tablet_tool_get_y(tablet_event);
1282 	litest_assert_double_ge(x, last_x - 1);
1283 	litest_assert_double_le(x, last_x + 1);
1284 	litest_assert_double_ge(y, last_y - 1);
1285 	litest_assert_double_le(y, last_y + 1);
1286 
1287 	if (libinput_tablet_tool_has_distance(tool)) {
1288 		ck_assert(!libinput_event_tablet_tool_distance_has_changed(
1289 				tablet_event));
1290 
1291 		distance = libinput_event_tablet_tool_get_distance(
1292 						tablet_event);
1293 		litest_assert_double_eq(distance, last_distance);
1294 	}
1295 
1296 	if (libinput_tablet_tool_has_tilt(tool)) {
1297 		ck_assert(!libinput_event_tablet_tool_tilt_x_has_changed(
1298 				tablet_event));
1299 		ck_assert(!libinput_event_tablet_tool_tilt_y_has_changed(
1300 				tablet_event));
1301 
1302 		x = libinput_event_tablet_tool_get_tilt_x(tablet_event);
1303 		y = libinput_event_tablet_tool_get_tilt_y(tablet_event);
1304 
1305 		litest_assert_double_eq(x, last_tx);
1306 		litest_assert_double_eq(y, last_ty);
1307 	}
1308 
1309 	litest_assert_empty_queue(li);
1310 	libinput_event_destroy(event);
1311 }
1312 END_TEST
1313 
START_TEST(proximity_range_enter)1314 START_TEST(proximity_range_enter)
1315 {
1316 	struct litest_device *dev = litest_current_device();
1317 	struct libinput *li = dev->libinput;
1318 	struct axis_replacement axes[] = {
1319 		{ ABS_DISTANCE, 90 },
1320 		{ -1, -1 }
1321 	};
1322 
1323 	litest_drain_events(li);
1324 
1325 	litest_push_event_frame(dev);
1326 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
1327 	litest_tablet_proximity_in(dev, 10, 10, axes);
1328 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 1);
1329 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
1330 	litest_pop_event_frame(dev);
1331 	litest_assert_empty_queue(li);
1332 
1333 	litest_axis_set_value(axes, ABS_DISTANCE, 20);
1334 	litest_tablet_motion(dev, 10, 10, axes);
1335 	libinput_dispatch(li);
1336 
1337 	litest_assert_tablet_proximity_event(li,
1338 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
1339 
1340 	litest_axis_set_value(axes, ABS_DISTANCE, 90);
1341 	litest_tablet_motion(dev, 10, 10, axes);
1342 	libinput_dispatch(li);
1343 	litest_assert_tablet_proximity_event(li,
1344 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1345 
1346 	litest_push_event_frame(dev);
1347 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
1348 	litest_tablet_proximity_out(dev);
1349 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 0);
1350 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
1351 	litest_pop_event_frame(dev);
1352 	litest_assert_empty_queue(li);
1353 }
1354 END_TEST
1355 
START_TEST(proximity_range_in_out)1356 START_TEST(proximity_range_in_out)
1357 {
1358 	struct litest_device *dev = litest_current_device();
1359 	struct libinput *li = dev->libinput;
1360 	struct axis_replacement axes[] = {
1361 		{ ABS_DISTANCE, 20 },
1362 		{ -1, -1 }
1363 	};
1364 
1365 	litest_drain_events(li);
1366 
1367 	litest_push_event_frame(dev);
1368 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
1369 	litest_tablet_proximity_in(dev, 10, 10, axes);
1370 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 1);
1371 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
1372 	litest_pop_event_frame(dev);
1373 	libinput_dispatch(li);
1374 	litest_assert_tablet_proximity_event(li,
1375 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
1376 
1377 	litest_axis_set_value(axes, ABS_DISTANCE, 90);
1378 	litest_tablet_motion(dev, 10, 10, axes);
1379 	libinput_dispatch(li);
1380 	litest_assert_tablet_proximity_event(li,
1381 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1382 
1383 	litest_tablet_motion(dev, 30, 30, axes);
1384 	litest_assert_empty_queue(li);
1385 
1386 	litest_axis_set_value(axes, ABS_DISTANCE, 20);
1387 	litest_tablet_motion(dev, 10, 10, axes);
1388 	libinput_dispatch(li);
1389 	litest_assert_tablet_proximity_event(li,
1390 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
1391 
1392 	litest_push_event_frame(dev);
1393 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
1394 	litest_tablet_proximity_out(dev);
1395 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 0);
1396 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
1397 	litest_pop_event_frame(dev);
1398 	litest_assert_tablet_proximity_event(li,
1399 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1400 	litest_assert_empty_queue(li);
1401 }
1402 END_TEST
1403 
START_TEST(proximity_range_button_click)1404 START_TEST(proximity_range_button_click)
1405 {
1406 	struct litest_device *dev = litest_current_device();
1407 	struct libinput *li = dev->libinput;
1408 	struct axis_replacement axes[] = {
1409 		{ ABS_DISTANCE, 90 },
1410 		{ -1, -1 }
1411 	};
1412 
1413 	litest_drain_events(li);
1414 
1415 	litest_push_event_frame(dev);
1416 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
1417 	litest_tablet_proximity_in(dev, 10, 10, axes);
1418 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 1);
1419 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
1420 	litest_pop_event_frame(dev);
1421 	litest_drain_events(li);
1422 
1423 	litest_event(dev, EV_KEY, BTN_STYLUS, 1);
1424 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1425 	libinput_dispatch(li);
1426 	litest_event(dev, EV_KEY, BTN_STYLUS, 0);
1427 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1428 	libinput_dispatch(li);
1429 
1430 	litest_push_event_frame(dev);
1431 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
1432 	litest_tablet_proximity_out(dev);
1433 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 0);
1434 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
1435 	litest_pop_event_frame(dev);
1436 	litest_assert_empty_queue(li);
1437 }
1438 END_TEST
1439 
START_TEST(proximity_range_button_press)1440 START_TEST(proximity_range_button_press)
1441 {
1442 	struct litest_device *dev = litest_current_device();
1443 	struct libinput *li = dev->libinput;
1444 	struct axis_replacement axes[] = {
1445 		{ ABS_DISTANCE, 20 },
1446 		{ -1, -1 }
1447 	};
1448 
1449 	litest_push_event_frame(dev);
1450 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
1451 	litest_tablet_proximity_in(dev, 10, 10, axes);
1452 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 1);
1453 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
1454 	litest_pop_event_frame(dev);
1455 	litest_drain_events(li);
1456 
1457 	litest_event(dev, EV_KEY, BTN_STYLUS, 1);
1458 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1459 	libinput_dispatch(li);
1460 
1461 	litest_assert_tablet_button_event(li,
1462 					  BTN_STYLUS,
1463 					  LIBINPUT_BUTTON_STATE_PRESSED);
1464 
1465 	litest_axis_set_value(axes, ABS_DISTANCE, 90);
1466 	litest_tablet_motion(dev, 15, 15, axes);
1467 	libinput_dispatch(li);
1468 
1469 	/* expect fake button release */
1470 	litest_assert_tablet_button_event(li,
1471 					  BTN_STYLUS,
1472 					  LIBINPUT_BUTTON_STATE_RELEASED);
1473 	litest_assert_tablet_proximity_event(li,
1474 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1475 
1476 	litest_event(dev, EV_KEY, BTN_STYLUS, 0);
1477 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1478 	libinput_dispatch(li);
1479 
1480 	litest_push_event_frame(dev);
1481 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
1482 	litest_tablet_proximity_out(dev);
1483 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 0);
1484 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
1485 	litest_pop_event_frame(dev);
1486 	litest_assert_empty_queue(li);
1487 }
1488 END_TEST
1489 
START_TEST(proximity_range_button_release)1490 START_TEST(proximity_range_button_release)
1491 {
1492 	struct litest_device *dev = litest_current_device();
1493 	struct libinput *li = dev->libinput;
1494 	struct axis_replacement axes[] = {
1495 		{ ABS_DISTANCE, 90 },
1496 		{ -1, -1 }
1497 	};
1498 
1499 	litest_push_event_frame(dev);
1500 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
1501 	litest_tablet_proximity_in(dev, 10, 10, axes);
1502 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 1);
1503 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
1504 	litest_pop_event_frame(dev);
1505 	litest_drain_events(li);
1506 
1507 	litest_event(dev, EV_KEY, BTN_STYLUS, 1);
1508 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1509 	litest_assert_empty_queue(li);
1510 
1511 	litest_axis_set_value(axes, ABS_DISTANCE, 20);
1512 	litest_tablet_motion(dev, 15, 15, axes);
1513 	libinput_dispatch(li);
1514 
1515 	litest_assert_tablet_proximity_event(li,
1516 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
1517 	/* expect fake button press */
1518 	litest_assert_tablet_button_event(li,
1519 					  BTN_STYLUS,
1520 					  LIBINPUT_BUTTON_STATE_PRESSED);
1521 	litest_assert_empty_queue(li);
1522 
1523 	litest_event(dev, EV_KEY, BTN_STYLUS, 0);
1524 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1525 	libinput_dispatch(li);
1526 	litest_assert_tablet_button_event(li,
1527 					  BTN_STYLUS,
1528 					  LIBINPUT_BUTTON_STATE_RELEASED);
1529 
1530 	litest_push_event_frame(dev);
1531 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
1532 	litest_tablet_proximity_out(dev);
1533 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 0);
1534 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
1535 	litest_pop_event_frame(dev);
1536 	litest_assert_tablet_proximity_event(li,
1537 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1538 }
1539 END_TEST
1540 
START_TEST(proximity_out_slow_event)1541 START_TEST(proximity_out_slow_event)
1542 {
1543 	struct litest_device *dev = litest_current_device();
1544 	struct libinput *li = dev->libinput;
1545 	struct axis_replacement axes[] = {
1546 		{ ABS_DISTANCE, 90 },
1547 		{ -1, -1 }
1548 	};
1549 
1550 	litest_tablet_proximity_in(dev, 10, 10, axes);
1551 	litest_tablet_motion(dev, 12, 12, axes);
1552 	litest_drain_events(li);
1553 
1554 	litest_timeout_tablet_proxout();
1555 	libinput_dispatch(li);
1556 
1557 	/* The forced prox out */
1558 	litest_assert_tablet_proximity_event(li,
1559 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1560 	litest_assert_empty_queue(li);
1561 
1562 	litest_tablet_proximity_out(dev);
1563 	litest_assert_empty_queue(li);
1564 }
1565 END_TEST
1566 
START_TEST(proximity_out_not_during_contact)1567 START_TEST(proximity_out_not_during_contact)
1568 {
1569 	struct litest_device *dev = litest_current_device();
1570 	struct libinput *li = dev->libinput;
1571 	struct axis_replacement axes[] = {
1572 		{ ABS_DISTANCE, 0 },
1573 		{ ABS_PRESSURE, 10 },
1574 		{ -1, -1 }
1575 	};
1576 
1577 	litest_tablet_proximity_in(dev, 10, 10, axes);
1578 	litest_tablet_motion(dev, 12, 12, axes);
1579 	litest_drain_events(li);
1580 
1581 	litest_timeout_tablet_proxout();
1582 	libinput_dispatch(li);
1583 
1584 	/* No forced proxout yet */
1585 	litest_assert_empty_queue(li);
1586 
1587 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
1588 	litest_tablet_motion(dev, 14, 14, axes);
1589 	litest_drain_events(li);
1590 
1591 	litest_timeout_tablet_proxout();
1592 	libinput_dispatch(li);
1593 
1594 	/* The forced prox out */
1595 	litest_assert_tablet_proximity_event(li,
1596 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1597 
1598 	litest_tablet_proximity_out(dev);
1599 	litest_assert_empty_queue(li);
1600 }
1601 END_TEST
1602 
START_TEST(proximity_out_not_during_buttonpress)1603 START_TEST(proximity_out_not_during_buttonpress)
1604 {
1605 	struct litest_device *dev = litest_current_device();
1606 	struct libinput *li = dev->libinput;
1607 	struct axis_replacement axes[] = {
1608 		{ ABS_DISTANCE, 10 },
1609 		{ ABS_PRESSURE, 0 },
1610 		{ -1, -1 }
1611 	};
1612 
1613 	litest_tablet_proximity_in(dev, 10, 10, axes);
1614 	litest_tablet_motion(dev, 12, 12, axes);
1615 	litest_drain_events(li);
1616 
1617 	litest_event(dev, EV_KEY, BTN_STYLUS, 1);
1618 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1619 	libinput_dispatch(li);
1620 
1621 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
1622 
1623 	litest_timeout_tablet_proxout();
1624 	libinput_dispatch(li);
1625 
1626 	/* No forced proxout yet */
1627 	litest_assert_empty_queue(li);
1628 
1629 	litest_event(dev, EV_KEY, BTN_STYLUS, 0);
1630 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
1631 	libinput_dispatch(li);
1632 
1633 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
1634 
1635 	litest_timeout_tablet_proxout();
1636 	libinput_dispatch(li);
1637 
1638 	/* The forced prox out */
1639 	litest_assert_tablet_proximity_event(li,
1640 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1641 
1642 	litest_tablet_proximity_out(dev);
1643 	litest_assert_empty_queue(li);
1644 }
1645 END_TEST
1646 
START_TEST(proximity_out_disables_forced)1647 START_TEST(proximity_out_disables_forced)
1648 {
1649 	struct litest_device *dev = litest_current_device();
1650 	struct libinput *li = dev->libinput;
1651 	struct axis_replacement axes[] = {
1652 		{ ABS_DISTANCE, 10 },
1653 		{ ABS_PRESSURE, 0 },
1654 		{ -1, -1 }
1655 	};
1656 
1657 	/* A correct proximity out sequence from the device should disable
1658 	   the forced proximity out */
1659 	litest_tablet_proximity_in(dev, 10, 10, axes);
1660 	litest_tablet_proximity_out(dev);
1661 	litest_drain_events(li);
1662 
1663 	/* expect no timeout-based prox out */
1664 	litest_tablet_proximity_in(dev, 10, 10, axes);
1665 	litest_drain_events(li);
1666 
1667 	litest_timeout_tablet_proxout();
1668 	libinput_dispatch(li);
1669 
1670 	litest_assert_empty_queue(li);
1671 	litest_tablet_proximity_out(dev);
1672 	litest_assert_tablet_proximity_event(li,
1673 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1674 	libinput_dispatch(li);
1675 }
1676 END_TEST
1677 
START_TEST(proximity_out_disables_forced_after_forced)1678 START_TEST(proximity_out_disables_forced_after_forced)
1679 {
1680 	struct litest_device *dev = litest_current_device();
1681 	struct libinput *li = dev->libinput;
1682 	struct axis_replacement axes[] = {
1683 		{ ABS_DISTANCE, 10 },
1684 		{ ABS_PRESSURE, 0 },
1685 		{ -1, -1 }
1686 	};
1687 
1688 	/* A correct proximity out sequence from the device should disable
1689 	   the forced proximity out, even when we had a forced prox-out */
1690 	litest_tablet_proximity_in(dev, 10, 10, axes);
1691 	litest_drain_events(li);
1692 
1693 	/* timeout-based forced prox out */
1694 	litest_timeout_tablet_proxout();
1695 	libinput_dispatch(li);
1696 	litest_assert_tablet_proximity_event(li,
1697 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1698 	litest_assert_empty_queue(li);
1699 
1700 	/* now send the real prox out (we're already in proximity out) and
1701 	 * that should disable the proxout quirk */
1702 	litest_tablet_proximity_out(dev);
1703 	libinput_dispatch(li);
1704 	litest_assert_empty_queue(li);
1705 
1706 	/* same again, but this time we expect no timeout-based prox out */
1707 	litest_tablet_proximity_in(dev, 10, 10, axes);
1708 	litest_drain_events(li);
1709 
1710 	litest_timeout_tablet_proxout();
1711 	libinput_dispatch(li);
1712 
1713 	litest_assert_empty_queue(li);
1714 	litest_tablet_proximity_out(dev);
1715 	litest_assert_tablet_proximity_event(li,
1716 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1717 	libinput_dispatch(li);
1718 }
1719 END_TEST
1720 
START_TEST(proximity_out_on_delete)1721 START_TEST(proximity_out_on_delete)
1722 {
1723 	struct libinput *li = litest_create_context();
1724 	struct litest_device *dev = litest_add_device(li, LITEST_WACOM_INTUOS);
1725 
1726 	litest_tablet_proximity_in(dev, 10, 10, NULL);
1727 	litest_drain_events(li);
1728 
1729 	litest_delete_device(dev);
1730 	libinput_dispatch(li);
1731 
1732 	litest_assert_tablet_proximity_event(li,
1733 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
1734 	litest_destroy_context(li);
1735 }
1736 END_TEST
1737 
START_TEST(motion)1738 START_TEST(motion)
1739 {
1740 	struct litest_device *dev = litest_current_device();
1741 	struct libinput *li = dev->libinput;
1742 	struct libinput_event_tablet_tool *tablet_event;
1743 	struct libinput_event *event;
1744 	int test_x, test_y;
1745 	double last_reported_x = 0, last_reported_y = 0;
1746 	enum libinput_event_type type;
1747 	struct axis_replacement axes[] = {
1748 		{ ABS_DISTANCE, 10 },
1749 		{ ABS_PRESSURE, 0 },
1750 		{ -1, -1 }
1751 	};
1752 	bool x_changed, y_changed;
1753 	double reported_x, reported_y;
1754 
1755 	litest_drain_events(li);
1756 
1757 	litest_tablet_proximity_in(dev, 5, 100, axes);
1758 	libinput_dispatch(li);
1759 
1760 	event = libinput_get_event(li);
1761 	tablet_event = litest_is_tablet_event(event,
1762 				      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1763 	x_changed = libinput_event_tablet_tool_x_has_changed(tablet_event);
1764 	y_changed = libinput_event_tablet_tool_y_has_changed(tablet_event);
1765 	ck_assert(x_changed);
1766 	ck_assert(y_changed);
1767 
1768 	reported_x = libinput_event_tablet_tool_get_x(tablet_event);
1769 	reported_y = libinput_event_tablet_tool_get_y(tablet_event);
1770 
1771 	litest_assert_double_lt(reported_x, reported_y);
1772 
1773 	last_reported_x = reported_x;
1774 	last_reported_y = reported_y;
1775 
1776 	libinput_event_destroy(event);
1777 
1778 	for (test_x = 10, test_y = 90;
1779 	     test_x <= 100;
1780 	     test_x += 10, test_y -= 10) {
1781 		bool x_changed, y_changed;
1782 		double reported_x, reported_y;
1783 
1784 		litest_tablet_motion(dev, test_x, test_y, axes);
1785 		libinput_dispatch(li);
1786 
1787 		while ((event = libinput_get_event(li))) {
1788 			tablet_event = libinput_event_get_tablet_tool_event(event);
1789 			type = libinput_event_get_type(event);
1790 
1791 			if (type == LIBINPUT_EVENT_TABLET_TOOL_AXIS) {
1792 				x_changed = libinput_event_tablet_tool_x_has_changed(
1793 							    tablet_event);
1794 				y_changed = libinput_event_tablet_tool_y_has_changed(
1795 							    tablet_event);
1796 
1797 				ck_assert(x_changed);
1798 				ck_assert(y_changed);
1799 
1800 				reported_x = libinput_event_tablet_tool_get_x(
1801 								tablet_event);
1802 				reported_y = libinput_event_tablet_tool_get_y(
1803 								tablet_event);
1804 
1805 				litest_assert_double_gt(reported_x,
1806 							last_reported_x);
1807 				litest_assert_double_lt(reported_y,
1808 							last_reported_y);
1809 
1810 				last_reported_x = reported_x;
1811 				last_reported_y = reported_y;
1812 			}
1813 
1814 			libinput_event_destroy(event);
1815 		}
1816 	}
1817 }
1818 END_TEST
1819 
START_TEST(left_handed)1820 START_TEST(left_handed)
1821 {
1822 #if HAVE_LIBWACOM
1823 	struct litest_device *dev = litest_current_device();
1824 	struct libinput *li = dev->libinput;
1825 	struct libinput_event *event;
1826 	struct libinput_event_tablet_tool *tablet_event;
1827 	double libinput_max_x, libinput_max_y;
1828 	double last_x = -1.0, last_y = -1.0;
1829 	double x, y;
1830 	struct axis_replacement axes[] = {
1831 		{ ABS_DISTANCE, 10 },
1832 		{ ABS_PRESSURE, 0 },
1833 		{ -1, -1 }
1834 	};
1835 
1836 	litest_drain_events(li);
1837 
1838 	ck_assert(libinput_device_config_left_handed_is_available(dev->libinput_device));
1839 
1840 	libinput_device_get_size (dev->libinput_device,
1841 				  &libinput_max_x,
1842 				  &libinput_max_y);
1843 
1844 	/* Test that left-handed mode doesn't go into effect until the tool has
1845 	 * left proximity of the tablet. In order to test this, we have to bring
1846 	 * the tool into proximity and make sure libinput processes the
1847 	 * proximity events so that it updates it's internal tablet state, and
1848 	 * then try setting it to left-handed mode. */
1849 	litest_tablet_proximity_in(dev, 0, 100, axes);
1850 	libinput_dispatch(li);
1851 	libinput_device_config_left_handed_set(dev->libinput_device, 1);
1852 
1853 	event = libinput_get_event(li);
1854 	tablet_event = litest_is_tablet_event(event,
1855 				LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1856 
1857 	last_x = libinput_event_tablet_tool_get_x(tablet_event);
1858 	last_y = libinput_event_tablet_tool_get_y(tablet_event);
1859 
1860 	litest_assert_double_eq(last_x, 0);
1861 	litest_assert_double_eq(last_y, libinput_max_y);
1862 
1863 	libinput_event_destroy(event);
1864 
1865 	/* work around smoothing */
1866 	litest_axis_set_value(axes, ABS_DISTANCE, 9);
1867 	litest_tablet_motion(dev, 100, 0, axes);
1868 	litest_axis_set_value(axes, ABS_DISTANCE, 7);
1869 	litest_tablet_motion(dev, 100, 0, axes);
1870 	litest_axis_set_value(axes, ABS_DISTANCE, 10);
1871 	litest_tablet_motion(dev, 100, 0, axes);
1872 	litest_drain_events(li);
1873 
1874 	litest_axis_set_value(axes, ABS_DISTANCE, 5);
1875 	litest_tablet_motion(dev, 100, 0, axes);
1876 	libinput_dispatch(li);
1877 
1878 	event = libinput_get_event(li);
1879 	tablet_event = litest_is_tablet_event(event,
1880 					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
1881 
1882 	x = libinput_event_tablet_tool_get_x(tablet_event);
1883 	y = libinput_event_tablet_tool_get_y(tablet_event);
1884 
1885 	litest_assert_double_eq(x, libinput_max_x);
1886 	litest_assert_double_eq(y, 0);
1887 
1888 	litest_assert_double_gt(x, last_x);
1889 	litest_assert_double_lt(y, last_y);
1890 
1891 	libinput_event_destroy(event);
1892 
1893 	litest_tablet_proximity_out(dev);
1894 	litest_drain_events(li);
1895 
1896 	/* Since we've drained the events and libinput's aware the tool is out
1897 	 * of proximity, it should have finally transitioned into left-handed
1898 	 * mode, so the axes should be inverted once we bring it back into
1899 	 * proximity */
1900 	litest_tablet_proximity_in(dev, 0, 100, axes);
1901 	libinput_dispatch(li);
1902 
1903 	event = libinput_get_event(li);
1904 	tablet_event = litest_is_tablet_event(event,
1905 				LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1906 
1907 	last_x = libinput_event_tablet_tool_get_x(tablet_event);
1908 	last_y = libinput_event_tablet_tool_get_y(tablet_event);
1909 
1910 	litest_assert_double_eq(last_x, libinput_max_x);
1911 	litest_assert_double_eq(last_y, 0);
1912 
1913 	libinput_event_destroy(event);
1914 
1915 	/* work around smoothing */
1916 	litest_axis_set_value(axes, ABS_DISTANCE, 9);
1917 	litest_tablet_motion(dev, 100, 0, axes);
1918 	litest_axis_set_value(axes, ABS_DISTANCE, 7);
1919 	litest_tablet_motion(dev, 100, 0, axes);
1920 	litest_axis_set_value(axes, ABS_DISTANCE, 10);
1921 	litest_tablet_motion(dev, 100, 0, axes);
1922 	litest_drain_events(li);
1923 
1924 	litest_axis_set_value(axes, ABS_DISTANCE, 5);
1925 	litest_tablet_motion(dev, 100, 0, axes);
1926 	libinput_dispatch(li);
1927 
1928 	event = libinput_get_event(li);
1929 	tablet_event = litest_is_tablet_event(event,
1930 				LIBINPUT_EVENT_TABLET_TOOL_AXIS);
1931 
1932 	x = libinput_event_tablet_tool_get_x(tablet_event);
1933 	y = libinput_event_tablet_tool_get_y(tablet_event);
1934 
1935 	litest_assert_double_eq(x, 0);
1936 	litest_assert_double_eq(y, libinput_max_y);
1937 
1938 	litest_assert_double_lt(x, last_x);
1939 	litest_assert_double_gt(y, last_y);
1940 
1941 	libinput_event_destroy(event);
1942 #endif
1943 }
1944 END_TEST
1945 
START_TEST(no_left_handed)1946 START_TEST(no_left_handed)
1947 {
1948 	struct litest_device *dev = litest_current_device();
1949 
1950 	ck_assert(!libinput_device_config_left_handed_is_available(dev->libinput_device));
1951 }
1952 END_TEST
1953 
START_TEST(left_handed_tilt)1954 START_TEST(left_handed_tilt)
1955 {
1956 #if HAVE_LIBWACOM
1957 	struct litest_device *dev = litest_current_device();
1958 	struct libinput *li = dev->libinput;
1959 	struct libinput_event *event;
1960 	struct libinput_event_tablet_tool *tev;
1961 	enum libinput_config_status status;
1962 	struct axis_replacement axes[] = {
1963 		{ ABS_DISTANCE, 10 },
1964 		{ ABS_PRESSURE, 0 },
1965 		{ ABS_TILT_X, 90 },
1966 		{ ABS_TILT_Y, 10 },
1967 		{ -1, -1 }
1968 	};
1969 	double tx, ty;
1970 
1971 	status = libinput_device_config_left_handed_set(dev->libinput_device, 1);
1972 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1973 
1974 	litest_drain_events(li);
1975 
1976 	litest_tablet_proximity_in(dev, 10, 10, axes);
1977 	libinput_dispatch(li);
1978 	event = libinput_get_event(li);
1979 	tev = litest_is_tablet_event(event,
1980 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1981 	tx = libinput_event_tablet_tool_get_tilt_x(tev);
1982 	ty = libinput_event_tablet_tool_get_tilt_y(tev);
1983 
1984 	ck_assert_double_lt(tx, 0);
1985 	ck_assert_double_gt(ty, 0);
1986 
1987 	libinput_event_destroy(event);
1988 #endif
1989 }
1990 END_TEST
1991 
1992 static inline double
rotate_event(struct litest_device * dev,int angle_degrees)1993 rotate_event(struct litest_device *dev, int angle_degrees)
1994 {
1995 	struct libinput *li = dev->libinput;
1996 	struct libinput_event *event;
1997 	struct libinput_event_tablet_tool *tev;
1998 	const struct input_absinfo *abs;
1999 	double a = (angle_degrees - 90 - 175)/180.0 * M_PI;
2000 	double val;
2001 	int x, y;
2002 	int tilt_center_x, tilt_center_y;
2003 
2004 	abs = libevdev_get_abs_info(dev->evdev, ABS_TILT_X);
2005 	ck_assert_notnull(abs);
2006 	tilt_center_x = (abs->maximum - abs->minimum + 1) / 2;
2007 
2008 	abs = libevdev_get_abs_info(dev->evdev, ABS_TILT_Y);
2009 	ck_assert_notnull(abs);
2010 	tilt_center_y = (abs->maximum - abs->minimum + 1) / 2;
2011 
2012 	x = cos(a) * 20 + tilt_center_x;
2013 	y = sin(a) * 20 + tilt_center_y;
2014 
2015 	litest_event(dev, EV_ABS, ABS_TILT_X, x);
2016 	litest_event(dev, EV_ABS, ABS_TILT_Y, y);
2017 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2018 	libinput_dispatch(li);
2019 
2020 	event = libinput_get_event(li);
2021 	tev = litest_is_tablet_event(event,
2022 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
2023 	ck_assert(libinput_event_tablet_tool_rotation_has_changed(tev));
2024 	val = libinput_event_tablet_tool_get_rotation(tev);
2025 
2026 	libinput_event_destroy(event);
2027 	litest_assert_empty_queue(li);
2028 
2029 	return val;
2030 }
2031 
START_TEST(left_handed_mouse_rotation)2032 START_TEST(left_handed_mouse_rotation)
2033 {
2034 #if HAVE_LIBWACOM
2035 	struct litest_device *dev = litest_current_device();
2036 	struct libinput *li = dev->libinput;
2037 	enum libinput_config_status status;
2038 	int angle;
2039 	double val, old_val = 0;
2040 	struct axis_replacement axes[] = {
2041 		{ ABS_DISTANCE, 10 },
2042 		{ ABS_PRESSURE, 0 },
2043 		{ ABS_TILT_X, 0 },
2044 		{ ABS_TILT_Y, 0 },
2045 		{ -1, -1 }
2046 	};
2047 
2048 	status = libinput_device_config_left_handed_set(dev->libinput_device, 1);
2049 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
2050 
2051 	litest_drain_events(li);
2052 
2053 	litest_push_event_frame(dev);
2054 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
2055 	litest_tablet_proximity_in(dev, 10, 10, axes);
2056 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 1);
2057 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
2058 	litest_pop_event_frame(dev);
2059 
2060 	litest_drain_events(li);
2061 
2062 	/* cos/sin are 90 degrees offset from the north-is-zero that
2063 	   libinput uses. 175 is the CCW offset in the mouse HW */
2064 	for (angle = 185; angle < 540; angle += 5) {
2065 		int expected_angle = angle - 180;
2066 
2067 		val = rotate_event(dev, angle % 360);
2068 
2069 		/* rounding error galore, we can't test for anything more
2070 		   precise than these */
2071 		litest_assert_double_lt(val, 360.0);
2072 		litest_assert_double_gt(val, old_val);
2073 		litest_assert_double_lt(val, expected_angle + 5);
2074 
2075 		old_val = val;
2076 	}
2077 #endif
2078 }
2079 END_TEST
2080 
START_TEST(left_handed_artpen_rotation)2081 START_TEST(left_handed_artpen_rotation)
2082 {
2083 #if HAVE_LIBWACOM
2084 	struct litest_device *dev = litest_current_device();
2085 	struct libinput *li = dev->libinput;
2086 	struct libinput_event *event;
2087 	struct libinput_event_tablet_tool *tev;
2088 	const struct input_absinfo *abs;
2089 	enum libinput_config_status status;
2090 	double val;
2091 	double scale;
2092 	int angle;
2093 
2094 	if (!libevdev_has_event_code(dev->evdev,
2095 				    EV_ABS,
2096 				    ABS_Z))
2097 		return;
2098 
2099 	status = libinput_device_config_left_handed_set(dev->libinput_device, 1);
2100 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
2101 
2102 	litest_drain_events(li);
2103 
2104 	abs = libevdev_get_abs_info(dev->evdev, ABS_Z);
2105 	ck_assert_notnull(abs);
2106 	scale = (abs->maximum - abs->minimum + 1)/360.0;
2107 
2108 	litest_event(dev, EV_KEY, BTN_TOOL_BRUSH, 1);
2109 	litest_event(dev, EV_ABS, ABS_MISC, 0x804); /* Art Pen */
2110 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
2111 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2112 
2113 	litest_event(dev, EV_ABS, ABS_Z, abs->minimum);
2114 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2115 
2116 	litest_drain_events(li);
2117 
2118 	for (angle = 188; angle < 540; angle += 8) {
2119 		int a = angle * scale + abs->minimum;
2120 		int expected_angle = angle - 180;
2121 
2122 		litest_event(dev, EV_ABS, ABS_Z, a);
2123 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
2124 		libinput_dispatch(li);
2125 		event = libinput_get_event(li);
2126 		tev = litest_is_tablet_event(event,
2127 					     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
2128 		ck_assert(libinput_event_tablet_tool_rotation_has_changed(tev));
2129 		val = libinput_event_tablet_tool_get_rotation(tev);
2130 
2131 		/* artpen has a 90 deg offset cw */
2132 		ck_assert_int_eq(round(val), (expected_angle + 90) % 360);
2133 
2134 		libinput_event_destroy(event);
2135 		litest_assert_empty_queue(li);
2136 
2137 	}
2138 #endif
2139 }
2140 END_TEST
2141 
START_TEST(motion_event_state)2142 START_TEST(motion_event_state)
2143 {
2144 	struct litest_device *dev = litest_current_device();
2145 	struct libinput *li = dev->libinput;
2146 	struct libinput_event *event;
2147 	struct libinput_event_tablet_tool *tablet_event;
2148 	int test_x, test_y;
2149 	double last_x, last_y;
2150 	struct axis_replacement axes[] = {
2151 		{ ABS_DISTANCE, 10 },
2152 		{ ABS_PRESSURE, 0 },
2153 		{ -1, -1 }
2154 	};
2155 	unsigned int button = pick_stylus_or_btn0(dev);
2156 
2157 	litest_drain_events(li);
2158 	litest_tablet_proximity_in(dev, 5, 100, axes);
2159 	litest_drain_events(li);
2160 
2161 	/* couple of events that go left/bottom to right/top */
2162 	for (test_x = 0, test_y = 100; test_x < 100; test_x += 10, test_y -= 10)
2163 		litest_tablet_motion(dev, test_x, test_y, axes);
2164 
2165 	libinput_dispatch(li);
2166 
2167 	event = libinput_get_event(li);
2168 	tablet_event = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
2169 
2170 	last_x = libinput_event_tablet_tool_get_x(tablet_event);
2171 	last_y = libinput_event_tablet_tool_get_y(tablet_event);
2172 
2173 	/* mark with a button event, then go back to bottom/left */
2174 	litest_button_click(dev, button, true);
2175 
2176 	for (test_x = 100, test_y = 0; test_x > 0; test_x -= 10, test_y += 10)
2177 		litest_tablet_motion(dev, test_x, test_y, axes);
2178 
2179 	libinput_event_destroy(event);
2180 	libinput_dispatch(li);
2181 	ck_assert_int_eq(libinput_next_event_type(li),
2182 			 LIBINPUT_EVENT_TABLET_TOOL_AXIS);
2183 
2184 	/* we expect all events up to the button event to go from
2185 	   bottom/left to top/right */
2186 	while ((event = libinput_get_event(li))) {
2187 		double x, y;
2188 
2189 		if (libinput_event_get_type(event) != LIBINPUT_EVENT_TABLET_TOOL_AXIS)
2190 			break;
2191 
2192 		tablet_event = libinput_event_get_tablet_tool_event(event);
2193 		ck_assert_notnull(tablet_event);
2194 
2195 		x = libinput_event_tablet_tool_get_x(tablet_event);
2196 		y = libinput_event_tablet_tool_get_y(tablet_event);
2197 
2198 		ck_assert(x > last_x);
2199 		ck_assert(y < last_y);
2200 
2201 		last_x = x;
2202 		last_y = y;
2203 		libinput_event_destroy(event);
2204 	}
2205 
2206 	ck_assert_int_eq(libinput_event_get_type(event),
2207 			 LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
2208 	libinput_event_destroy(event);
2209 }
2210 END_TEST
2211 
START_TEST(motion_outside_bounds)2212 START_TEST(motion_outside_bounds)
2213 {
2214 	struct litest_device *dev = litest_current_device();
2215 	struct libinput *li = dev->libinput;
2216 	struct libinput_event *event;
2217 	struct libinput_event_tablet_tool *tablet_event;
2218 	double val;
2219 	int i;
2220 
2221 	struct axis_replacement axes[] = {
2222 		{ ABS_DISTANCE, 10 },
2223 		{ ABS_PRESSURE, 0 },
2224 		{ -1, -1 }
2225 	};
2226 
2227 	litest_tablet_proximity_in(dev, 50, 50, axes);
2228 	litest_drain_events(li);
2229 
2230 	/* Work around smoothing */
2231 	for (i = 5; i > 0; i--) {
2232 		litest_event(dev, EV_ABS, ABS_X, 0 + 5 * i);
2233 		litest_event(dev, EV_ABS, ABS_Y, 1000);
2234 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
2235 		libinput_dispatch(li);
2236 	}
2237 	litest_drain_events(li);
2238 
2239 	/* On the 24HD x/y of 0 is outside the limit */
2240 	litest_event(dev, EV_ABS, ABS_X, 0);
2241 	litest_event(dev, EV_ABS, ABS_Y, 1000);
2242 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2243 	libinput_dispatch(li);
2244 
2245 	event = libinput_get_event(li);
2246 	tablet_event = litest_is_tablet_event(event,
2247 					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
2248 	val = libinput_event_tablet_tool_get_x(tablet_event);
2249 	ck_assert_double_lt(val, 0.0);
2250 	val = libinput_event_tablet_tool_get_y(tablet_event);
2251 	ck_assert_double_gt(val, 0.0);
2252 
2253 	val = libinput_event_tablet_tool_get_x_transformed(tablet_event, 100);
2254 	ck_assert_double_lt(val, 0.0);
2255 
2256 	libinput_event_destroy(event);
2257 
2258 	/* Work around smoothing */
2259 	for (i = 5; i > 0; i--) {
2260 		litest_event(dev, EV_ABS, ABS_X, 1000);
2261 		litest_event(dev, EV_ABS, ABS_Y, 0 + 5 * i);
2262 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
2263 		libinput_dispatch(li);
2264 	}
2265 	litest_drain_events(li);
2266 
2267 	/* On the 24HD x/y of 0 is outside the limit */
2268 	litest_event(dev, EV_ABS, ABS_X, 1000);
2269 	litest_event(dev, EV_ABS, ABS_Y, 0);
2270 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2271 	libinput_dispatch(li);
2272 
2273 	event = libinput_get_event(li);
2274 	tablet_event = litest_is_tablet_event(event,
2275 					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
2276 	val = libinput_event_tablet_tool_get_x(tablet_event);
2277 	ck_assert_double_gt(val, 0.0);
2278 	val = libinput_event_tablet_tool_get_y(tablet_event);
2279 	ck_assert_double_lt(val, 0.0);
2280 
2281 	val = libinput_event_tablet_tool_get_y_transformed(tablet_event, 100);
2282 	ck_assert_double_lt(val, 0.0);
2283 
2284 	libinput_event_destroy(event);
2285 }
2286 END_TEST
2287 
START_TEST(bad_distance_events)2288 START_TEST(bad_distance_events)
2289 {
2290 	struct litest_device *dev = litest_current_device();
2291 	struct libinput *li = dev->libinput;
2292 	const struct input_absinfo *absinfo;
2293 	struct axis_replacement axes[] = {
2294 		{ -1, -1 },
2295 	};
2296 
2297 	litest_tablet_proximity_in(dev, 10, 10, axes);
2298 	litest_tablet_proximity_out(dev);
2299 	litest_drain_events(li);
2300 
2301 	absinfo = libevdev_get_abs_info(dev->evdev, ABS_DISTANCE);
2302 	ck_assert_notnull(absinfo);
2303 
2304 	litest_event(dev, EV_ABS, ABS_DISTANCE, absinfo->maximum);
2305 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2306 	litest_event(dev, EV_ABS, ABS_DISTANCE, absinfo->minimum);
2307 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2308 
2309 	litest_assert_empty_queue(li);
2310 }
2311 END_TEST
2312 
START_TEST(tool_unique)2313 START_TEST(tool_unique)
2314 {
2315 	struct litest_device *dev = litest_current_device();
2316 	struct libinput *li = dev->libinput;
2317 	struct libinput_event_tablet_tool *tablet_event;
2318 	struct libinput_event *event;
2319 	struct libinput_tablet_tool *tool;
2320 
2321 	litest_drain_events(li);
2322 
2323 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
2324 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
2325 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2326 
2327 	libinput_dispatch(li);
2328 	event = libinput_get_event(li);
2329 	tablet_event = litest_is_tablet_event(event,
2330 				LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2331 	tool = libinput_event_tablet_tool_get_tool(tablet_event);
2332 	ck_assert(libinput_tablet_tool_is_unique(tool));
2333 	libinput_event_destroy(event);
2334 }
2335 END_TEST
2336 
START_TEST(tool_serial)2337 START_TEST(tool_serial)
2338 {
2339 	struct litest_device *dev = litest_current_device();
2340 	struct libinput *li = dev->libinput;
2341 	struct libinput_event_tablet_tool *tablet_event;
2342 	struct libinput_event *event;
2343 	struct libinput_tablet_tool *tool;
2344 
2345 	litest_drain_events(li);
2346 
2347 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
2348 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
2349 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2350 	libinput_dispatch(li);
2351 
2352 	event = libinput_get_event(li);
2353 	tablet_event = litest_is_tablet_event(event,
2354 				LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2355 	tool = libinput_event_tablet_tool_get_tool(tablet_event);
2356 	ck_assert_uint_eq(libinput_tablet_tool_get_serial(tool), 1000);
2357 	libinput_event_destroy(event);
2358 }
2359 END_TEST
2360 
START_TEST(tool_id)2361 START_TEST(tool_id)
2362 {
2363 	struct litest_device *dev = litest_current_device();
2364 	struct libinput *li = dev->libinput;
2365 	struct libinput_event_tablet_tool *tablet_event;
2366 	struct libinput_event *event;
2367 	struct libinput_tablet_tool *tool;
2368 	uint64_t tool_id;
2369 
2370 	litest_drain_events(li);
2371 
2372 	litest_tablet_proximity_in(dev, 10, 10, NULL);
2373 	libinput_dispatch(li);
2374 
2375 	event = libinput_get_event(li);
2376 	tablet_event = litest_is_tablet_event(event,
2377 				LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2378 	tool = libinput_event_tablet_tool_get_tool(tablet_event);
2379 
2380 	ck_assert_int_eq(libinput_device_get_id_vendor(dev->libinput_device),
2381 			 VENDOR_ID_WACOM);
2382 
2383 	switch (libinput_device_get_id_product(dev->libinput_device)) {
2384 	case 0x27: /* Intuos 5 */
2385 		tool_id = 1050626;
2386 		break;
2387 	case 0xc6: /* Cintiq 12WX */
2388 	case 0xf4: /* Cintiq 24HD */
2389 	case 0x333: /* Cintiq 13HD */
2390 	case 0x350: /* Cintiq Pro 16 */
2391 		tool_id = 2083;
2392 		break;
2393 	default:
2394 		ck_abort();
2395 	}
2396 
2397 	ck_assert(tool_id == libinput_tablet_tool_get_tool_id(tool));
2398 	libinput_event_destroy(event);
2399 }
2400 END_TEST
2401 
START_TEST(serial_changes_tool)2402 START_TEST(serial_changes_tool)
2403 {
2404 	struct litest_device *dev = litest_current_device();
2405 	struct libinput *li = dev->libinput;
2406 	struct libinput_event_tablet_tool *tablet_event;
2407 	struct libinput_event *event;
2408 	struct libinput_tablet_tool *tool;
2409 
2410 	litest_drain_events(li);
2411 
2412 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
2413 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
2414 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2415 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
2416 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2417 	litest_drain_events(li);
2418 
2419 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
2420 	litest_event(dev, EV_MSC, MSC_SERIAL, 2000);
2421 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2422 	libinput_dispatch(li);
2423 
2424 	event = libinput_get_event(li);
2425 	tablet_event = litest_is_tablet_event(event,
2426 				LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2427 	tool = libinput_event_tablet_tool_get_tool(tablet_event);
2428 
2429 	ck_assert_uint_eq(libinput_tablet_tool_get_serial(tool), 2000);
2430 	libinput_event_destroy(event);
2431 }
2432 END_TEST
2433 
START_TEST(invalid_serials)2434 START_TEST(invalid_serials)
2435 {
2436 	struct litest_device *dev = litest_current_device();
2437 	struct libinput *li = dev->libinput;
2438 	struct libinput_event *event;
2439 	struct libinput_event_tablet_tool *tablet_event;
2440 	struct libinput_tablet_tool *tool;
2441 
2442 	litest_drain_events(li);
2443 
2444 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
2445 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
2446 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2447 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
2448 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2449 	litest_drain_events(li);
2450 
2451 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
2452 	litest_event(dev, EV_MSC, MSC_SERIAL, -1);
2453 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2454 
2455 	libinput_dispatch(li);
2456 	while ((event = libinput_get_event(li))) {
2457 		if (libinput_event_get_type(event) ==
2458 		    LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY) {
2459 			tablet_event = libinput_event_get_tablet_tool_event(event);
2460 			tool = libinput_event_tablet_tool_get_tool(tablet_event);
2461 
2462 			ck_assert_uint_eq(libinput_tablet_tool_get_serial(tool), 1000);
2463 		}
2464 
2465 		libinput_event_destroy(event);
2466 	}
2467 }
2468 END_TEST
2469 
START_TEST(tool_ref)2470 START_TEST(tool_ref)
2471 {
2472 	struct litest_device *dev = litest_current_device();
2473 	struct libinput *li = dev->libinput;
2474 	struct libinput_event_tablet_tool *tablet_event;
2475 	struct libinput_event *event;
2476 	struct libinput_tablet_tool *tool;
2477 
2478 	litest_drain_events(li);
2479 
2480 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
2481 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
2482 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2483 	libinput_dispatch(li);
2484 
2485 	event = libinput_get_event(li);
2486 	tablet_event = litest_is_tablet_event(event,
2487 				LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2488 	tool = libinput_event_tablet_tool_get_tool(tablet_event);
2489 
2490 	ck_assert_notnull(tool);
2491 	ck_assert(tool == libinput_tablet_tool_ref(tool));
2492 	ck_assert(tool == libinput_tablet_tool_unref(tool));
2493 	libinput_event_destroy(event);
2494 
2495 	ck_assert(libinput_tablet_tool_unref(tool) == NULL);
2496 }
2497 END_TEST
2498 
START_TEST(tool_user_data)2499 START_TEST(tool_user_data)
2500 {
2501 	struct litest_device *dev = litest_current_device();
2502 	struct libinput *li = dev->libinput;
2503 	struct libinput_event_tablet_tool *tablet_event;
2504 	struct libinput_event *event;
2505 	struct libinput_tablet_tool *tool;
2506 	void *userdata = &dev; /* not dereferenced */
2507 
2508 	litest_drain_events(li);
2509 
2510 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
2511 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
2512 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2513 	libinput_dispatch(li);
2514 
2515 	event = libinput_get_event(li);
2516 	tablet_event = litest_is_tablet_event(event,
2517 				LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2518 	tool = libinput_event_tablet_tool_get_tool(tablet_event);
2519 	ck_assert_notnull(tool);
2520 
2521 	ck_assert(libinput_tablet_tool_get_user_data(tool) == NULL);
2522 	libinput_tablet_tool_set_user_data(tool, userdata);
2523 	ck_assert(libinput_tablet_tool_get_user_data(tool) == userdata);
2524 	libinput_tablet_tool_set_user_data(tool, NULL);
2525 	ck_assert(libinput_tablet_tool_get_user_data(tool) == NULL);
2526 
2527 	libinput_event_destroy(event);
2528 }
2529 END_TEST
2530 
START_TEST(pad_buttons_ignored)2531 START_TEST(pad_buttons_ignored)
2532 {
2533 	struct litest_device *dev = litest_current_device();
2534 	struct libinput *li = dev->libinput;
2535 	struct axis_replacement axes[] = {
2536 		{ ABS_DISTANCE, 10 },
2537 		{ ABS_PRESSURE, 0 },
2538 		{ -1, -1 }
2539 	};
2540 	int button;
2541 
2542 	litest_drain_events(li);
2543 
2544 	for (button = BTN_0; button < BTN_MOUSE; button++) {
2545 		litest_event(dev, EV_KEY, button, 1);
2546 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
2547 		litest_event(dev, EV_KEY, button, 0);
2548 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
2549 		libinput_dispatch(li);
2550 	}
2551 
2552 	litest_assert_empty_queue(li);
2553 
2554 	/* same thing while in prox */
2555 	litest_tablet_proximity_in(dev, 10, 10, axes);
2556 	litest_drain_events(li);
2557 
2558 	for (button = BTN_0; button < BTN_MOUSE; button++)
2559 		litest_event(dev, EV_KEY, button, 1);
2560 
2561 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2562 	libinput_dispatch(li);
2563 
2564 	for (button = BTN_0; button < BTN_MOUSE; button++)
2565 		litest_event(dev, EV_KEY, button, 0);
2566 
2567 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2568 	libinput_dispatch(li);
2569 
2570 	litest_assert_empty_queue(li);
2571 }
2572 END_TEST
2573 
START_TEST(tools_with_serials)2574 START_TEST(tools_with_serials)
2575 {
2576 	struct libinput *li = litest_create_context();
2577 	struct litest_device *dev[2];
2578 	struct libinput_tablet_tool *tool[2] = {0};
2579 	struct libinput_event *event;
2580 	struct libinput_event_tablet_tool *tev;
2581 	int i;
2582 
2583 	for (i = 0; i < 2; i++) {
2584 		dev[i] = litest_add_device(li, LITEST_WACOM_INTUOS);
2585 		litest_drain_events(li);
2586 
2587 		/* WARNING: this test fails if UI_GET_SYSNAME isn't
2588 		 * available or isn't used by libevdev (1.3, commit 2ff45c73).
2589 		 * Put a sleep(1) here and that usually fixes it.
2590 		 */
2591 
2592 		litest_push_event_frame(dev[i]);
2593 		litest_tablet_proximity_in(dev[i], 10, 10, NULL);
2594 		litest_event(dev[i], EV_MSC, MSC_SERIAL, 100);
2595 		litest_pop_event_frame(dev[i]);
2596 
2597 		libinput_dispatch(li);
2598 		event = libinput_get_event(li);
2599 		tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2600 		tool[i] = libinput_event_tablet_tool_get_tool(tev);
2601 		libinput_event_destroy(event);
2602 	}
2603 
2604 	/* We should get the same object for both devices */
2605 	ck_assert_notnull(tool[0]);
2606 	ck_assert_notnull(tool[1]);
2607 	ck_assert_ptr_eq(tool[0], tool[1]);
2608 
2609 	litest_delete_device(dev[0]);
2610 	litest_delete_device(dev[1]);
2611 	litest_destroy_context(li);
2612 }
2613 END_TEST
2614 
START_TEST(tools_without_serials)2615 START_TEST(tools_without_serials)
2616 {
2617 	struct libinput *li = litest_create_context();
2618 	struct litest_device *dev[2];
2619 	struct libinput_tablet_tool *tool[2] = {0};
2620 	struct libinput_event *event;
2621 	struct libinput_event_tablet_tool *tev;
2622 	int i;
2623 
2624 	for (i = 0; i < 2; i++) {
2625 		dev[i] = litest_add_device_with_overrides(li,
2626 							  LITEST_WACOM_ISDV4,
2627 							  NULL,
2628 							  NULL,
2629 							  NULL,
2630 							  NULL);
2631 
2632 		litest_drain_events(li);
2633 
2634 		/* WARNING: this test fails if UI_GET_SYSNAME isn't
2635 		 * available or isn't used by libevdev (1.3, commit 2ff45c73).
2636 		 * Put a sleep(1) here and that usually fixes it.
2637 		 */
2638 
2639 		litest_tablet_proximity_in(dev[i], 10, 10, NULL);
2640 
2641 		libinput_dispatch(li);
2642 		event = libinput_get_event(li);
2643 		tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2644 		tool[i] = libinput_event_tablet_tool_get_tool(tev);
2645 		libinput_event_destroy(event);
2646 	}
2647 
2648 	/* We should get different tool objects for each device */
2649 	ck_assert_notnull(tool[0]);
2650 	ck_assert_notnull(tool[1]);
2651 	ck_assert_ptr_ne(tool[0], tool[1]);
2652 
2653 	litest_delete_device(dev[0]);
2654 	litest_delete_device(dev[1]);
2655 	litest_destroy_context(li);
2656 }
2657 END_TEST
2658 
START_TEST(tool_delayed_serial)2659 START_TEST(tool_delayed_serial)
2660 {
2661 	struct litest_device *dev = litest_current_device();
2662 	struct libinput *li = dev->libinput;
2663 	struct libinput_event *event;
2664 	struct libinput_event_tablet_tool *tev;
2665 	struct libinput_tablet_tool *tool;
2666 	unsigned int serial;
2667 
2668 	litest_drain_events(li);
2669 
2670 	litest_event(dev, EV_ABS, ABS_X, 4500);
2671 	litest_event(dev, EV_ABS, ABS_Y, 2000);
2672 	litest_event(dev, EV_MSC, MSC_SERIAL, 0);
2673 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
2674 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2675 	libinput_dispatch(li);
2676 
2677 	event = libinput_get_event(li);
2678 	tev = litest_is_tablet_event(event,
2679 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2680 	tool = libinput_event_tablet_tool_get_tool(tev);
2681 	serial = libinput_tablet_tool_get_serial(tool);
2682 	ck_assert_int_eq(serial, 0);
2683 	libinput_event_destroy(event);
2684 
2685 	for (int x = 4500; x < 8000; x += 1000) {
2686 		litest_event(dev, EV_ABS, ABS_X, x);
2687 		litest_event(dev, EV_ABS, ABS_Y, 2000);
2688 		litest_event(dev, EV_MSC, MSC_SERIAL, 0);
2689 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
2690 		libinput_dispatch(li);
2691 	}
2692 	litest_drain_events(li);
2693 
2694 	/* Now send the serial */
2695 	litest_event(dev, EV_ABS, ABS_X, 4500);
2696 	litest_event(dev, EV_ABS, ABS_Y, 2000);
2697 	litest_event(dev, EV_MSC, MSC_SERIAL, 1234566);
2698 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2699 	libinput_dispatch(li);
2700 
2701 	event = libinput_get_event(li);
2702 	tev = litest_is_tablet_event(event,
2703 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
2704 	tool = libinput_event_tablet_tool_get_tool(tev);
2705 	serial = libinput_tablet_tool_get_serial(tool);
2706 	ck_assert_int_eq(serial, 0);
2707 	libinput_event_destroy(event);
2708 
2709 	for (int x = 4500; x < 8000; x += 500) {
2710 		litest_event(dev, EV_ABS, ABS_X, x);
2711 		litest_event(dev, EV_ABS, ABS_Y, 2000);
2712 		litest_event(dev, EV_MSC, MSC_SERIAL, 1234566);
2713 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
2714 		libinput_dispatch(li);
2715 	}
2716 
2717 	event = libinput_get_event(li);
2718 	do {
2719 		tev = litest_is_tablet_event(event,
2720 					     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
2721 		tool = libinput_event_tablet_tool_get_tool(tev);
2722 		serial = libinput_tablet_tool_get_serial(tool);
2723 		ck_assert_int_eq(serial, 0);
2724 		libinput_event_destroy(event);
2725 		event = libinput_get_event(li);
2726 	} while (event != NULL);
2727 
2728 	/* Quirk: tool out event is a serial of 0 */
2729 	litest_event(dev, EV_ABS, ABS_X, 4500);
2730 	litest_event(dev, EV_ABS, ABS_Y, 2000);
2731 	litest_event(dev, EV_MSC, MSC_SERIAL, 0);
2732 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
2733 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2734 	libinput_dispatch(li);
2735 
2736 	event = libinput_get_event(li);
2737 	tev = litest_is_tablet_event(event,
2738 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2739 	tool = libinput_event_tablet_tool_get_tool(tev);
2740 	serial = libinput_tablet_tool_get_serial(tool);
2741 	ck_assert_int_eq(serial, 0);
2742 	libinput_event_destroy(event);
2743 }
2744 END_TEST
2745 
START_TEST(tool_capability)2746 START_TEST(tool_capability)
2747 {
2748 	struct litest_device *dev = litest_current_device();
2749 	struct libinput_device *device = dev->libinput_device;
2750 
2751 	ck_assert(libinput_device_has_capability(device,
2752 						 LIBINPUT_DEVICE_CAP_TABLET_TOOL));
2753 }
2754 END_TEST
2755 
START_TEST(tool_capabilities)2756 START_TEST(tool_capabilities)
2757 {
2758 	struct libinput *li = litest_create_context();
2759 	struct litest_device *intuos;
2760 	struct litest_device *bamboo;
2761 	struct libinput_event *event;
2762 	struct libinput_event_tablet_tool *t;
2763 	struct libinput_tablet_tool *tool;
2764 
2765 	/* The axis capabilities of a tool can differ depending on the type of
2766 	 * tablet the tool is being used with */
2767 	bamboo = litest_add_device(li, LITEST_WACOM_BAMBOO);
2768 	intuos = litest_add_device(li, LITEST_WACOM_INTUOS);
2769 	litest_drain_events(li);
2770 
2771 	litest_event(bamboo, EV_KEY, BTN_TOOL_PEN, 1);
2772 	litest_event(bamboo, EV_SYN, SYN_REPORT, 0);
2773 
2774 	libinput_dispatch(li);
2775 
2776 	event = libinput_get_event(li);
2777 	t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2778 	tool = libinput_event_tablet_tool_get_tool(t);
2779 
2780 	ck_assert(libinput_tablet_tool_has_pressure(tool));
2781 	ck_assert(libinput_tablet_tool_has_distance(tool));
2782 	ck_assert(!libinput_tablet_tool_has_tilt(tool));
2783 
2784 	libinput_event_destroy(event);
2785 	litest_assert_empty_queue(li);
2786 
2787 	litest_event(intuos, EV_KEY, BTN_TOOL_PEN, 1);
2788 	litest_event(intuos, EV_SYN, SYN_REPORT, 0);
2789 	libinput_dispatch(li);
2790 
2791 	event = libinput_get_event(li);
2792 	t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2793 	tool = libinput_event_tablet_tool_get_tool(t);
2794 
2795 	ck_assert(libinput_tablet_tool_has_pressure(tool));
2796 	ck_assert(libinput_tablet_tool_has_distance(tool));
2797 	ck_assert(libinput_tablet_tool_has_tilt(tool));
2798 
2799 	libinput_event_destroy(event);
2800 	litest_assert_empty_queue(li);
2801 
2802 	litest_delete_device(bamboo);
2803 	litest_delete_device(intuos);
2804 	litest_destroy_context(li);
2805 }
2806 END_TEST
2807 
2808 static inline bool
tablet_has_mouse(struct litest_device * dev)2809 tablet_has_mouse(struct litest_device *dev)
2810 {
2811 	return libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_MOUSE) &&
2812 	       libevdev_get_id_vendor(dev->evdev) == VENDOR_ID_WACOM;
2813 }
2814 
START_TEST(tool_type)2815 START_TEST(tool_type)
2816 {
2817 	struct litest_device *dev = litest_current_device();
2818 	struct libinput *li = dev->libinput;
2819 	struct libinput_event *event;
2820 	struct libinput_event_tablet_tool *t;
2821 	struct libinput_tablet_tool *tool;
2822 	struct axis_replacement axes[] = {
2823 		{ ABS_DISTANCE, 10 },
2824 		{ ABS_PRESSURE, 0 },
2825 		{ ABS_TILT_X, 0 },
2826 		{ ABS_TILT_Y, 0 },
2827 		{ -1, -1 }
2828 	};
2829 	struct tool_type_match {
2830 		int code;
2831 		enum libinput_tablet_tool_type type;
2832 	} types[] = {
2833 		{ BTN_TOOL_PEN, LIBINPUT_TABLET_TOOL_TYPE_PEN },
2834 		{ BTN_TOOL_RUBBER, LIBINPUT_TABLET_TOOL_TYPE_ERASER },
2835 		{ BTN_TOOL_BRUSH, LIBINPUT_TABLET_TOOL_TYPE_BRUSH },
2836 		{ BTN_TOOL_PENCIL, LIBINPUT_TABLET_TOOL_TYPE_PENCIL },
2837 		{ BTN_TOOL_AIRBRUSH, LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH },
2838 		{ BTN_TOOL_MOUSE, LIBINPUT_TABLET_TOOL_TYPE_MOUSE },
2839 		{ BTN_TOOL_LENS, LIBINPUT_TABLET_TOOL_TYPE_LENS },
2840 		{ -1, -1 }
2841 	};
2842 	struct tool_type_match *tt;
2843 	double x = 50, y = 50;
2844 
2845 	litest_drain_events(li);
2846 
2847 	for (tt = types; tt->code != -1; tt++) {
2848 		enum libinput_tablet_tool_type type;
2849 
2850 		if (!libevdev_has_event_code(dev->evdev,
2851 					     EV_KEY,
2852 					     tt->code))
2853 			continue;
2854 
2855 		if ((tt->code == BTN_TOOL_MOUSE || tt->code == BTN_TOOL_LENS) &&
2856 		    !tablet_has_mouse(dev))
2857 			continue;
2858 
2859 		litest_tablet_set_tool_type(dev, tt->code);
2860 		litest_tablet_proximity_in(dev, x, y, axes);
2861 		libinput_dispatch(li);
2862 
2863 		event = libinput_get_event(li);
2864 		t = litest_is_tablet_event(event,
2865 				   LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2866 		tool = libinput_event_tablet_tool_get_tool(t);
2867 		type = libinput_tablet_tool_get_type(tool);
2868 
2869 		/* Devices with doubled-up tool bits send the pen
2870 		 * in-prox and immediately out-of-prox before the real tool
2871 		 * type. Drop those two and continue with what we expect is
2872 		 * the real prox in event */
2873 		if (tt->type != LIBINPUT_TABLET_TOOL_TYPE_PEN &&
2874 		    type == LIBINPUT_TABLET_TOOL_TYPE_PEN) {
2875 			libinput_event_destroy(event);
2876 			event = libinput_get_event(li);
2877 			litest_is_tablet_event(event,
2878 					       LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2879 			libinput_event_destroy(event);
2880 			event = libinput_get_event(li);
2881 			t = litest_is_tablet_event(event,
2882 					   LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2883 			tool = libinput_event_tablet_tool_get_tool(t);
2884 			type = libinput_tablet_tool_get_type(tool);
2885 		}
2886 
2887 		ck_assert_int_eq(type, tt->type);
2888 
2889 		libinput_event_destroy(event);
2890 		litest_assert_empty_queue(li);
2891 
2892 		litest_tablet_proximity_out(dev);
2893 		litest_drain_events(li);
2894 
2895 		x++;
2896 		y++;
2897 	}
2898 }
2899 END_TEST
2900 
START_TEST(tool_in_prox_before_start)2901 START_TEST(tool_in_prox_before_start)
2902 {
2903 	struct libinput *li;
2904 	struct litest_device *dev = litest_current_device();
2905 	struct libinput_event *event;
2906 	struct libinput_event_tablet_tool *tev;
2907 	struct libinput_tablet_tool *tool;
2908 	struct axis_replacement axes[] = {
2909 		{ ABS_DISTANCE, 10 },
2910 		{ ABS_PRESSURE, 0 },
2911 		{ ABS_TILT_X, 0 },
2912 		{ ABS_TILT_Y, 0 },
2913 		{ -1, -1 }
2914 	};
2915 	const char *devnode;
2916 	unsigned int serial;
2917 
2918 	litest_tablet_proximity_in(dev, 10, 10, axes);
2919 
2920 	/* for simplicity, we create a new litest context */
2921 	devnode = libevdev_uinput_get_devnode(dev->uinput);
2922 	li = litest_create_context();
2923 	libinput_path_add_device(li, devnode);
2924 
2925 	litest_drain_events_of_type(li, LIBINPUT_EVENT_DEVICE_ADDED, -1);
2926 
2927 	litest_assert_empty_queue(li);
2928 
2929 	litest_tablet_motion(dev, 10, 20, axes);
2930 	libinput_dispatch(li);
2931 	event = libinput_get_event(li);
2932 	tev = litest_is_tablet_event(event,
2933 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2934 	tool = libinput_event_tablet_tool_get_tool(tev);
2935 	serial = libinput_tablet_tool_get_serial(tool);
2936 	libinput_event_destroy(event);
2937 
2938 	litest_drain_events_of_type(li, LIBINPUT_EVENT_TABLET_TOOL_TIP, -1);
2939 
2940 	litest_tablet_motion(dev, 30, 40, axes);
2941 	libinput_dispatch(li);
2942 	event = libinput_get_event(li);
2943 	tev = litest_is_tablet_event(event,
2944 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
2945 	tool = libinput_event_tablet_tool_get_tool(tev);
2946 	ck_assert_int_eq(serial,
2947 			 libinput_tablet_tool_get_serial(tool));
2948 	libinput_event_destroy(event);
2949 
2950 	litest_assert_empty_queue(li);
2951 	litest_button_click(dev, BTN_STYLUS, true);
2952 	litest_button_click(dev, BTN_STYLUS, false);
2953 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
2954 	litest_tablet_proximity_out(dev);
2955 	libinput_dispatch(li);
2956 
2957 	litest_timeout_tablet_proxout();
2958 	libinput_dispatch(li);
2959 
2960 	event = libinput_get_event(li);
2961 	litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2962 	libinput_event_destroy(event);
2963 
2964 	litest_destroy_context(li);
2965 }
2966 END_TEST
2967 
START_TEST(tool_direct_switch_skip_tool_update)2968 START_TEST(tool_direct_switch_skip_tool_update)
2969 {
2970 	struct litest_device *dev = litest_current_device();
2971 	struct libinput *li = dev->libinput;
2972 	struct libinput_event *event;
2973 	struct libinput_event_tablet_tool *tev;
2974 	struct libinput_tablet_tool *tool;
2975 	struct axis_replacement axes[] = {
2976 		{ ABS_DISTANCE, 10 },
2977 		{ ABS_PRESSURE, 0 },
2978 		{ -1, -1 }
2979 	};
2980 
2981 	if (!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_RUBBER))
2982 		return;
2983 
2984 	litest_drain_events(li);
2985 
2986 	litest_tablet_proximity_in(dev, 10, 10, axes);
2987 	libinput_dispatch(li);
2988 
2989 	event = libinput_get_event(li);
2990 	tev = litest_is_tablet_event(event,
2991 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
2992 	tool = libinput_event_tablet_tool_get_tool(tev);
2993 	libinput_tablet_tool_ref(tool);
2994 	libinput_event_destroy(event);
2995 
2996 	litest_event(dev, EV_KEY, BTN_TOOL_RUBBER, 1);
2997 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
2998 	libinput_dispatch(li);
2999 
3000 	event = libinput_get_event(li);
3001 	tev = litest_is_tablet_event(event,
3002 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3003 	ck_assert_int_eq(libinput_event_tablet_tool_get_proximity_state(tev),
3004 			 LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
3005 	ck_assert_ptr_eq(libinput_event_tablet_tool_get_tool(tev), tool);
3006 	libinput_event_destroy(event);
3007 
3008 	event = libinput_get_event(li);
3009 	tev = litest_is_tablet_event(event,
3010 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3011 	ck_assert_int_eq(libinput_event_tablet_tool_get_proximity_state(tev),
3012 			 LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
3013 	ck_assert_ptr_ne(libinput_event_tablet_tool_get_tool(tev), tool);
3014 	libinput_tablet_tool_unref(tool);
3015 	tool = libinput_event_tablet_tool_get_tool(tev);
3016 	libinput_tablet_tool_ref(tool);
3017 	libinput_event_destroy(event);
3018 
3019 	litest_tablet_motion(dev, 20, 30, axes);
3020 	libinput_dispatch(li);
3021 
3022 	event = libinput_get_event(li);
3023 	tev = litest_is_tablet_event(event,
3024 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3025 	ck_assert_ptr_eq(libinput_event_tablet_tool_get_tool(tev),
3026 			 tool);
3027 	libinput_event_destroy(event);
3028 
3029 	litest_event(dev, EV_KEY, BTN_TOOL_RUBBER, 0);
3030 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3031 	libinput_dispatch(li);
3032 
3033 	event = libinput_get_event(li);
3034 	tev = litest_is_tablet_event(event,
3035 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3036 	ck_assert_int_eq(libinput_event_tablet_tool_get_proximity_state(tev),
3037 			 LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
3038 	ck_assert_ptr_eq(libinput_event_tablet_tool_get_tool(tev),
3039 			 tool);
3040 	libinput_event_destroy(event);
3041 
3042 	litest_push_event_frame(dev);
3043 	litest_event(dev, EV_KEY, BTN_TOOL_RUBBER, 1);
3044 	litest_tablet_motion(dev, 30, 40, axes);
3045 	litest_pop_event_frame(dev);
3046 	libinput_dispatch(li);
3047 
3048 	event = libinput_get_event(li);
3049 	tev = litest_is_tablet_event(event,
3050 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3051 	ck_assert_int_eq(libinput_event_tablet_tool_get_proximity_state(tev),
3052 			 LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
3053 	ck_assert_ptr_eq(libinput_event_tablet_tool_get_tool(tev),
3054 			 tool);
3055 	libinput_event_destroy(event);
3056 
3057 	litest_tablet_motion(dev, 40, 30, axes);
3058 	libinput_dispatch(li);
3059 
3060 	event = libinput_get_event(li);
3061 	tev = litest_is_tablet_event(event,
3062 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3063 	ck_assert_ptr_eq(libinput_event_tablet_tool_get_tool(tev),
3064 			 tool);
3065 	libinput_event_destroy(event);
3066 
3067 	litest_push_event_frame(dev);
3068 	litest_event(dev, EV_KEY, BTN_TOOL_RUBBER, 0);
3069 	litest_tablet_proximity_out(dev);
3070 	litest_pop_event_frame(dev);
3071 	libinput_dispatch(li);
3072 	litest_timeout_tablet_proxout();
3073 	libinput_dispatch(li);
3074 
3075 	event = libinput_get_event(li);
3076 	tev = litest_is_tablet_event(event,
3077 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3078 	ck_assert_ptr_eq(libinput_event_tablet_tool_get_tool(tev),
3079 			 tool);
3080 	libinput_event_destroy(event);
3081 
3082 	litest_event(dev, EV_KEY, BTN_TOOL_RUBBER, 0);
3083 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3084 	litest_assert_empty_queue(li);
3085 
3086 	libinput_tablet_tool_unref(tool);
3087 }
3088 END_TEST
3089 
START_TEST(tool_direct_switch_with_forced_proxout)3090 START_TEST(tool_direct_switch_with_forced_proxout)
3091 {
3092 	struct litest_device *dev = litest_current_device();
3093 	struct libinput *li = dev->libinput;
3094 	struct libinput_event *event;
3095 	struct axis_replacement axes[] = {
3096 		{ ABS_DISTANCE, 10 },
3097 		{ ABS_PRESSURE, 0 },
3098 		{ -1, -1 }
3099 	};
3100 
3101 	if (!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_RUBBER))
3102 		return;
3103 
3104 	litest_drain_events(li);
3105 
3106 	/* This is a *very* specific event sequence to trigger a bug:
3107 	   - pen proximity in
3108 	   - pen proximity forced out
3109 	   - eraser proximity in without axis movement
3110 	   - eraser axis move
3111 	 */
3112 
3113 	/* pen prox in */
3114 	litest_tablet_proximity_in(dev, 10, 10, axes);
3115 	libinput_dispatch(li);
3116 	event = libinput_get_event(li);
3117 	litest_is_proximity_event(event,
3118 				  LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
3119 	libinput_event_destroy(event);
3120 
3121 	/* pen motion */
3122 	litest_tablet_motion(dev, 20, 30, axes);
3123 	libinput_dispatch(li);
3124 
3125 	event = libinput_get_event(li);
3126 	litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3127 	libinput_event_destroy(event);
3128 
3129 	/* pen forced prox out */
3130 	litest_timeout_tablet_proxout();
3131 	libinput_dispatch(li);
3132 
3133 	/* actual prox out for tablets that don't do forced prox out */
3134 	litest_tablet_proximity_out(dev);
3135 	libinput_dispatch(li);
3136 
3137 	event = libinput_get_event(li);
3138 	litest_is_proximity_event(event,
3139 				  LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
3140 	libinput_event_destroy(event);
3141 
3142 	/* eraser prox in without axes */
3143 	litest_event(dev, EV_KEY, BTN_TOOL_RUBBER, 1);
3144 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3145 	libinput_dispatch(li);
3146 	event = libinput_get_event(li);
3147 	litest_is_proximity_event(event,
3148 				  LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
3149 	libinput_event_destroy(event);
3150 
3151 	/* eraser motion */
3152 	litest_tablet_motion(dev, 30, 40, axes);
3153 	litest_tablet_motion(dev, 40, 50, axes);
3154 	libinput_dispatch(li);
3155 
3156 	event = libinput_get_event(li);
3157 	litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3158 	libinput_event_destroy(event);
3159 
3160 	event = libinput_get_event(li);
3161 	litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3162 	libinput_event_destroy(event);
3163 
3164 	litest_assert_empty_queue(li);
3165 }
3166 END_TEST
3167 
START_TEST(mouse_tool)3168 START_TEST(mouse_tool)
3169 {
3170 	struct litest_device *dev = litest_current_device();
3171 	struct libinput *li = dev->libinput;
3172 	struct libinput_event *event;
3173 	struct libinput_event_tablet_tool *tev;
3174 	struct libinput_tablet_tool *tool;
3175 
3176 	litest_drain_events(li);
3177 
3178 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 1);
3179 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
3180 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3181 	libinput_dispatch(li);
3182 
3183 	event = libinput_get_event(li);
3184 	tev = litest_is_tablet_event(event,
3185 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3186 	tool = libinput_event_tablet_tool_get_tool(tev);
3187 	ck_assert_notnull(tool);
3188 	ck_assert_int_eq(libinput_tablet_tool_get_type(tool),
3189 			 LIBINPUT_TABLET_TOOL_TYPE_MOUSE);
3190 
3191 	libinput_event_destroy(event);
3192 }
3193 END_TEST
3194 
START_TEST(mouse_buttons)3195 START_TEST(mouse_buttons)
3196 {
3197 	struct litest_device *dev = litest_current_device();
3198 	struct libinput *li = dev->libinput;
3199 	struct libinput_event *event;
3200 	struct libinput_event_tablet_tool *tev;
3201 	struct libinput_tablet_tool *tool;
3202 	int code;
3203 
3204 	litest_drain_events(li);
3205 
3206 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 1);
3207 	litest_event(dev, EV_ABS, ABS_MISC, 0x806); /* 5-button mouse tool_id */
3208 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
3209 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3210 	libinput_dispatch(li);
3211 
3212 	event = libinput_get_event(li);
3213 	tev = litest_is_tablet_event(event,
3214 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3215 	tool = libinput_event_tablet_tool_get_tool(tev);
3216 	ck_assert_notnull(tool);
3217 	libinput_tablet_tool_ref(tool);
3218 
3219 	libinput_event_destroy(event);
3220 
3221 	for (code = BTN_LEFT; code <= BTN_TASK; code++) {
3222 		bool has_button = libevdev_has_event_code(dev->evdev,
3223 							  EV_KEY,
3224 							  code);
3225 		ck_assert_int_eq(!!has_button,
3226 				 !!libinput_tablet_tool_has_button(tool, code));
3227 
3228 		if (!has_button)
3229 			continue;
3230 
3231 		litest_event(dev, EV_KEY, code, 1);
3232 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
3233 		libinput_dispatch(li);
3234 		litest_event(dev, EV_KEY, code, 0);
3235 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
3236 		libinput_dispatch(li);
3237 
3238 		litest_assert_tablet_button_event(li,
3239 					  code,
3240 					  LIBINPUT_BUTTON_STATE_PRESSED);
3241 		litest_assert_tablet_button_event(li,
3242 					  code,
3243 					  LIBINPUT_BUTTON_STATE_RELEASED);
3244 	}
3245 
3246 	libinput_tablet_tool_unref(tool);
3247 }
3248 END_TEST
3249 
START_TEST(mouse_rotation)3250 START_TEST(mouse_rotation)
3251 {
3252 	struct litest_device *dev = litest_current_device();
3253 	struct libinput *li = dev->libinput;
3254 	int angle;
3255 	double val, old_val = 0;
3256 
3257 	struct axis_replacement axes[] = {
3258 		{ ABS_DISTANCE, 10 },
3259 		{ ABS_PRESSURE, 0 },
3260 		{ ABS_TILT_X, 0 },
3261 		{ ABS_TILT_Y, 0 },
3262 		{ -1, -1 }
3263 	};
3264 
3265 	litest_drain_events(li);
3266 
3267 	litest_push_event_frame(dev);
3268 	litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN);
3269 	litest_tablet_proximity_in(dev, 10, 10, axes);
3270 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 1);
3271 	litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN);
3272 	litest_pop_event_frame(dev);
3273 
3274 	litest_drain_events(li);
3275 
3276 	/* cos/sin are 90 degrees offset from the north-is-zero that
3277 	   libinput uses. 175 is the CCW offset in the mouse HW */
3278 	for (angle = 5; angle < 360; angle += 5) {
3279 		val = rotate_event(dev, angle);
3280 
3281 		/* rounding error galore, we can't test for anything more
3282 		   precise than these */
3283 		litest_assert_double_lt(val, 360.0);
3284 		litest_assert_double_gt(val, old_val);
3285 		litest_assert_double_lt(val, angle + 5);
3286 
3287 		old_val = val;
3288 	}
3289 }
3290 END_TEST
3291 
START_TEST(mouse_wheel)3292 START_TEST(mouse_wheel)
3293 {
3294 	struct litest_device *dev = litest_current_device();
3295 	struct libinput *li = dev->libinput;
3296 	struct libinput_event *event;
3297 	struct libinput_event_tablet_tool *tev;
3298 	struct libinput_tablet_tool *tool;
3299 	const struct input_absinfo *abs;
3300 	double val;
3301 	int i;
3302 
3303 	if (!libevdev_has_event_code(dev->evdev,
3304 				     EV_REL,
3305 				     REL_WHEEL))
3306 		return;
3307 
3308 	litest_drain_events(li);
3309 
3310 	litest_event(dev, EV_KEY, BTN_TOOL_MOUSE, 1);
3311 	litest_event(dev, EV_ABS, ABS_MISC, 0x806); /* 5-button mouse tool_id */
3312 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
3313 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3314 	libinput_dispatch(li);
3315 
3316 	event = libinput_get_event(li);
3317 	tev = litest_is_tablet_event(event,
3318 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3319 	tool = libinput_event_tablet_tool_get_tool(tev);
3320 	ck_assert_notnull(tool);
3321 	libinput_tablet_tool_ref(tool);
3322 
3323 	libinput_event_destroy(event);
3324 
3325 	ck_assert(libinput_tablet_tool_has_wheel(tool));
3326 
3327 	for (i = 0; i < 3; i++) {
3328 		litest_event(dev, EV_REL, REL_WHEEL, -1);
3329 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
3330 		libinput_dispatch(li);
3331 
3332 		event = libinput_get_event(li);
3333 		tev = litest_is_tablet_event(event,
3334 					     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3335 		ck_assert(libinput_event_tablet_tool_wheel_has_changed(tev));
3336 
3337 		val = libinput_event_tablet_tool_get_wheel_delta(tev);
3338 		ck_assert_int_eq(val, 15);
3339 
3340 		val = libinput_event_tablet_tool_get_wheel_delta_discrete(tev);
3341 		ck_assert_int_eq(val, 1);
3342 
3343 		libinput_event_destroy(event);
3344 
3345 		litest_assert_empty_queue(li);
3346 	}
3347 
3348 	for (i = 2; i < 5; i++) {
3349 		/* send  x/y events to make sure we reset the wheel */
3350 		abs = libevdev_get_abs_info(dev->evdev, ABS_X);
3351 		litest_event(dev, EV_ABS, ABS_X, (abs->maximum - abs->minimum)/i);
3352 		abs = libevdev_get_abs_info(dev->evdev, ABS_Y);
3353 		litest_event(dev, EV_ABS, ABS_Y, (abs->maximum - abs->minimum)/i);
3354 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
3355 		libinput_dispatch(li);
3356 
3357 		event = libinput_get_event(li);
3358 		tev = litest_is_tablet_event(event,
3359 					     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3360 		ck_assert(!libinput_event_tablet_tool_wheel_has_changed(tev));
3361 
3362 		val = libinput_event_tablet_tool_get_wheel_delta(tev);
3363 		ck_assert_int_eq(val, 0);
3364 
3365 		val = libinput_event_tablet_tool_get_wheel_delta_discrete(tev);
3366 		ck_assert_int_eq(val, 0);
3367 
3368 		libinput_event_destroy(event);
3369 
3370 		litest_assert_empty_queue(li);
3371 	}
3372 
3373 	libinput_tablet_tool_unref(tool);
3374 }
3375 END_TEST
3376 
START_TEST(airbrush_tool)3377 START_TEST(airbrush_tool)
3378 {
3379 	struct litest_device *dev = litest_current_device();
3380 	struct libinput *li = dev->libinput;
3381 	struct libinput_event *event;
3382 	struct libinput_event_tablet_tool *tev;
3383 	struct libinput_tablet_tool *tool;
3384 
3385 	if (!libevdev_has_event_code(dev->evdev,
3386 				    EV_KEY,
3387 				    BTN_TOOL_AIRBRUSH))
3388 		return;
3389 
3390 	litest_drain_events(li);
3391 
3392 	litest_event(dev, EV_KEY, BTN_TOOL_AIRBRUSH, 1);
3393 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
3394 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3395 	libinput_dispatch(li);
3396 
3397 	event = libinput_get_event(li);
3398 	tev = litest_is_tablet_event(event,
3399 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3400 	tool = libinput_event_tablet_tool_get_tool(tev);
3401 
3402 	ck_assert_notnull(tool);
3403 	ck_assert_int_eq(libinput_tablet_tool_get_type(tool),
3404 			 LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH);
3405 
3406 	ck_assert(libinput_tablet_tool_has_slider(tool));
3407 
3408 	libinput_event_destroy(event);
3409 }
3410 END_TEST
3411 
START_TEST(airbrush_slider)3412 START_TEST(airbrush_slider)
3413 {
3414 	struct litest_device *dev = litest_current_device();
3415 	struct libinput *li = dev->libinput;
3416 	struct libinput_event *event;
3417 	struct libinput_event_tablet_tool *tev;
3418 	const struct input_absinfo *abs;
3419 	double val;
3420 	double scale;
3421 	double expected;
3422 	int v;
3423 
3424 	if (!libevdev_has_event_code(dev->evdev,
3425 				    EV_KEY,
3426 				    BTN_TOOL_AIRBRUSH))
3427 		return;
3428 
3429 	litest_drain_events(li);
3430 
3431 	abs = libevdev_get_abs_info(dev->evdev, ABS_WHEEL);
3432 	ck_assert_notnull(abs);
3433 
3434 	litest_event(dev, EV_KEY, BTN_TOOL_AIRBRUSH, 1);
3435 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
3436 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3437 
3438 	/* start with non-zero */
3439 	litest_event(dev, EV_ABS, ABS_WHEEL, 10);
3440 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3441 
3442 	litest_drain_events(li);
3443 
3444 	scale = abs->maximum - abs->minimum;
3445 	for (v = abs->minimum; v < abs->maximum; v += 8) {
3446 		litest_event(dev, EV_ABS, ABS_WHEEL, v);
3447 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
3448 		libinput_dispatch(li);
3449 		event = libinput_get_event(li);
3450 		tev = litest_is_tablet_event(event,
3451 					     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3452 		ck_assert(libinput_event_tablet_tool_slider_has_changed(tev));
3453 		val = libinput_event_tablet_tool_get_slider_position(tev);
3454 
3455 		expected = ((v - abs->minimum)/scale) * 2 - 1;
3456 		ck_assert_double_eq(val, expected);
3457 		ck_assert_double_ge(val, -1.0);
3458 		ck_assert_double_le(val, 1.0);
3459 		libinput_event_destroy(event);
3460 		litest_assert_empty_queue(li);
3461 	}
3462 }
3463 END_TEST
3464 
START_TEST(artpen_tool)3465 START_TEST(artpen_tool)
3466 {
3467 	struct litest_device *dev = litest_current_device();
3468 	struct libinput *li = dev->libinput;
3469 	struct libinput_event *event;
3470 	struct libinput_event_tablet_tool *tev;
3471 	struct libinput_tablet_tool *tool;
3472 
3473 	if (!libevdev_has_event_code(dev->evdev,
3474 				    EV_ABS,
3475 				    ABS_Z))
3476 		return;
3477 
3478 	litest_drain_events(li);
3479 
3480 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
3481 	litest_event(dev, EV_ABS, ABS_MISC, 0x804); /* Art Pen */
3482 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
3483 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3484 	libinput_dispatch(li);
3485 	event = libinput_get_event(li);
3486 	tev = litest_is_tablet_event(event,
3487 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3488 	tool = libinput_event_tablet_tool_get_tool(tev);
3489 	ck_assert_notnull(tool);
3490 	ck_assert_int_eq(libinput_tablet_tool_get_type(tool),
3491 			 LIBINPUT_TABLET_TOOL_TYPE_PEN);
3492 	ck_assert(libinput_tablet_tool_has_rotation(tool));
3493 
3494 	libinput_event_destroy(event);
3495 }
3496 END_TEST
3497 
START_TEST(artpen_rotation)3498 START_TEST(artpen_rotation)
3499 {
3500 	struct litest_device *dev = litest_current_device();
3501 	struct libinput *li = dev->libinput;
3502 	struct libinput_event *event;
3503 	struct libinput_event_tablet_tool *tev;
3504 	const struct input_absinfo *abs;
3505 	double val;
3506 	double scale;
3507 	int angle;
3508 
3509 	if (!libevdev_has_event_code(dev->evdev,
3510 				    EV_ABS,
3511 				    ABS_Z))
3512 		return;
3513 
3514 	litest_drain_events(li);
3515 
3516 	abs = libevdev_get_abs_info(dev->evdev, ABS_Z);
3517 	ck_assert_notnull(abs);
3518 	scale = (abs->maximum - abs->minimum + 1)/360.0;
3519 
3520 	litest_event(dev, EV_KEY, BTN_TOOL_BRUSH, 1);
3521 	litest_event(dev, EV_ABS, ABS_MISC, 0x804); /* Art Pen */
3522 	litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
3523 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3524 
3525 	litest_event(dev, EV_ABS, ABS_Z, abs->minimum);
3526 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
3527 
3528 	litest_drain_events(li);
3529 
3530 	for (angle = 8; angle < 360; angle += 8) {
3531 		int a = angle * scale + abs->minimum;
3532 
3533 		litest_event(dev, EV_ABS, ABS_Z, a);
3534 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
3535 		libinput_dispatch(li);
3536 		event = libinput_get_event(li);
3537 		tev = litest_is_tablet_event(event,
3538 					     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3539 		ck_assert(libinput_event_tablet_tool_rotation_has_changed(tev));
3540 		val = libinput_event_tablet_tool_get_rotation(tev);
3541 
3542 		/* artpen has a 90 deg offset cw */
3543 		ck_assert_int_eq(round(val), (angle + 90) % 360);
3544 
3545 		libinput_event_destroy(event);
3546 		litest_assert_empty_queue(li);
3547 
3548 	}
3549 }
3550 END_TEST
3551 
START_TEST(tablet_time_usec)3552 START_TEST(tablet_time_usec)
3553 {
3554 	struct litest_device *dev = litest_current_device();
3555 	struct libinput *li = dev->libinput;
3556 	struct libinput_event *event;
3557 	struct libinput_event_tablet_tool *tev;
3558 	struct axis_replacement axes[] = {
3559 		{ ABS_DISTANCE, 10 },
3560 		{ ABS_PRESSURE, 0 },
3561 		{ -1, -1 }
3562 	};
3563 	uint64_t time_usec;
3564 
3565 	litest_drain_events(li);
3566 
3567 	litest_tablet_proximity_in(dev, 5, 100, axes);
3568 	libinput_dispatch(li);
3569 
3570 	event = libinput_get_event(li);
3571 	tev = litest_is_tablet_event(event,
3572 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3573 	time_usec = libinput_event_tablet_tool_get_time_usec(tev);
3574 	ck_assert_int_eq(libinput_event_tablet_tool_get_time(tev),
3575 			 (uint32_t) (time_usec / 1000));
3576 	libinput_event_destroy(event);
3577 }
3578 END_TEST
3579 
START_TEST(tablet_pressure_distance_exclusive)3580 START_TEST(tablet_pressure_distance_exclusive)
3581 {
3582 	struct litest_device *dev = litest_current_device();
3583 	struct libinput *li = dev->libinput;
3584 	struct libinput_event *event;
3585 	struct libinput_event_tablet_tool *tev;
3586 	struct axis_replacement axes[] = {
3587 		{ ABS_DISTANCE, 10 },
3588 		{ ABS_PRESSURE, 0 },
3589 		{ -1, -1 },
3590 	};
3591 	double pressure, distance;
3592 
3593 	litest_tablet_proximity_in(dev, 5, 50, axes);
3594 	litest_drain_events(li);
3595 
3596 	/* We have pressure but we're still below the tip threshold */
3597 	litest_axis_set_value(axes, ABS_PRESSURE, 1);
3598 	litest_tablet_motion(dev, 70, 70, axes);
3599 	libinput_dispatch(li);
3600 
3601 	event = libinput_get_event(li);
3602 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3603 
3604 	pressure = libinput_event_tablet_tool_get_pressure(tev);
3605 	distance = libinput_event_tablet_tool_get_distance(tev);
3606 
3607 	ck_assert_double_eq(pressure, 0.0);
3608 	ck_assert_double_eq(distance, 0.0);
3609 	libinput_event_destroy(event);
3610 
3611 	/* We have pressure and we're above the threshold now */
3612 	litest_axis_set_value(axes, ABS_PRESSURE, 5.5);
3613 	litest_tablet_motion(dev, 70, 70, axes);
3614 	libinput_dispatch(li);
3615 
3616 	event = libinput_get_event(li);
3617 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_TIP);
3618 
3619 	pressure = libinput_event_tablet_tool_get_pressure(tev);
3620 	distance = libinput_event_tablet_tool_get_distance(tev);
3621 
3622 	ck_assert_double_gt(pressure, 0.0);
3623 	ck_assert_double_eq(distance, 0.0);
3624 
3625 	libinput_event_destroy(event);
3626 }
3627 END_TEST
3628 
START_TEST(tablet_calibration_has_matrix)3629 START_TEST(tablet_calibration_has_matrix)
3630 {
3631 	struct litest_device *dev = litest_current_device();
3632 	struct libinput_device *d = dev->libinput_device;
3633 	enum libinput_config_status status;
3634 	int rc;
3635 	float calibration[6] = {1, 0, 0, 0, 1, 0};
3636 	int has_calibration;
3637 
3638 	has_calibration = libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
3639 
3640 	rc = libinput_device_config_calibration_has_matrix(d);
3641 	ck_assert_int_eq(rc, has_calibration);
3642 	rc = libinput_device_config_calibration_get_matrix(d, calibration);
3643 	ck_assert_int_eq(rc, 0);
3644 	rc = libinput_device_config_calibration_get_default_matrix(d,
3645 								   calibration);
3646 	ck_assert_int_eq(rc, 0);
3647 
3648 	status = libinput_device_config_calibration_set_matrix(d,
3649 							       calibration);
3650 	if (has_calibration)
3651 		ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
3652 	else
3653 		ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
3654 }
3655 END_TEST
3656 
START_TEST(tablet_calibration_set_matrix_delta)3657 START_TEST(tablet_calibration_set_matrix_delta)
3658 {
3659 	struct litest_device *dev = litest_current_device();
3660 	struct libinput *li = dev->libinput;
3661 	struct libinput_device *d = dev->libinput_device;
3662 	enum libinput_config_status status;
3663 	float calibration[6] = {0.5, 0, 0, 0, 0.5, 0};
3664 	struct libinput_event *event;
3665 	struct libinput_event_tablet_tool *tablet_event;
3666 	struct axis_replacement axes[] = {
3667 		{ ABS_DISTANCE, 0 },
3668 		{ ABS_PRESSURE, 10 },
3669 		{ -1, -1 }
3670 	};
3671 	int has_calibration;
3672 	double x, y, dx, dy, mdx, mdy;
3673 
3674 	has_calibration = libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
3675 	if (!has_calibration)
3676 		return;
3677 
3678 	litest_drain_events(li);
3679 
3680 	litest_tablet_proximity_in(dev, 100, 100, axes);
3681 	libinput_dispatch(li);
3682 	event = libinput_get_event(li);
3683 	tablet_event = litest_is_tablet_event(event,
3684 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3685 	x = libinput_event_tablet_tool_get_x(tablet_event);
3686 	y = libinput_event_tablet_tool_get_y(tablet_event);
3687 	libinput_event_destroy(event);
3688 
3689 	event = libinput_get_event(li);
3690 	litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_TIP);
3691 	libinput_event_destroy(event);
3692 
3693 	litest_tablet_motion(dev, 80, 80, axes);
3694 	libinput_dispatch(li);
3695 
3696 	event = libinput_get_event(li);
3697 	tablet_event = litest_is_tablet_event(event,
3698 					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3699 
3700 	dx = libinput_event_tablet_tool_get_x(tablet_event) - x;
3701 	dy = libinput_event_tablet_tool_get_y(tablet_event) - y;
3702 	libinput_event_destroy(event);
3703 	litest_tablet_proximity_out(dev);
3704 	litest_drain_events(li);
3705 
3706 	status = libinput_device_config_calibration_set_matrix(d,
3707 							       calibration);
3708 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
3709 
3710 	litest_tablet_proximity_in(dev, 100, 100, axes);
3711 	libinput_dispatch(li);
3712 	event = libinput_get_event(li);
3713 	tablet_event = litest_is_tablet_event(event,
3714 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3715 	x = libinput_event_tablet_tool_get_x(tablet_event);
3716 	y = libinput_event_tablet_tool_get_y(tablet_event);
3717 	libinput_event_destroy(event);
3718 
3719 	event = libinput_get_event(li);
3720 	litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_TIP);
3721 	libinput_event_destroy(event);
3722 
3723 	litest_tablet_motion(dev, 80, 80, axes);
3724 	libinput_dispatch(li);
3725 
3726 	event = libinput_get_event(li);
3727 	tablet_event = litest_is_tablet_event(event,
3728 					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3729 
3730 	mdx = libinput_event_tablet_tool_get_x(tablet_event) - x;
3731 	mdy = libinput_event_tablet_tool_get_y(tablet_event) - y;
3732 	libinput_event_destroy(event);
3733 	litest_drain_events(li);
3734 
3735 	ck_assert_double_gt(dx, mdx * 2 - 1);
3736 	ck_assert_double_lt(dx, mdx * 2 + 1);
3737 	ck_assert_double_gt(dy, mdy * 2 - 1);
3738 	ck_assert_double_lt(dy, mdy * 2 + 1);
3739 }
3740 END_TEST
3741 
START_TEST(tablet_calibration_set_matrix)3742 START_TEST(tablet_calibration_set_matrix)
3743 {
3744 	struct litest_device *dev = litest_current_device();
3745 	struct libinput *li = dev->libinput;
3746 	struct libinput_device *d = dev->libinput_device;
3747 	enum libinput_config_status status;
3748 	float calibration[6] = {0.5, 0, 0, 0, 1, 0};
3749 	struct libinput_event *event;
3750 	struct libinput_event_tablet_tool *tablet_event;
3751 	struct axis_replacement axes[] = {
3752 		{ ABS_DISTANCE, 10 },
3753 		{ ABS_PRESSURE, 0 },
3754 		{ -1, -1 }
3755 	};
3756 	int has_calibration;
3757 	double x, y;
3758 
3759 	has_calibration = libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
3760 	if (!has_calibration)
3761 		return;
3762 
3763 	litest_drain_events(li);
3764 
3765 	status = libinput_device_config_calibration_set_matrix(d,
3766 							       calibration);
3767 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
3768 
3769 	litest_tablet_proximity_in(dev, 100, 100, axes);
3770 	libinput_dispatch(li);
3771 
3772 	event = libinput_get_event(li);
3773 	tablet_event = litest_is_tablet_event(event,
3774 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3775 	x = libinput_event_tablet_tool_get_x_transformed(tablet_event, 100);
3776 	y = libinput_event_tablet_tool_get_y_transformed(tablet_event, 100);
3777 	libinput_event_destroy(event);
3778 
3779 	ck_assert_double_gt(x, 49.0);
3780 	ck_assert_double_lt(x, 51.0);
3781 	ck_assert_double_gt(y, 99.0);
3782 	ck_assert_double_lt(y, 100.0);
3783 
3784 	litest_tablet_proximity_out(dev);
3785 	libinput_dispatch(li);
3786 	litest_tablet_proximity_in(dev, 50, 50, axes);
3787 	litest_tablet_proximity_out(dev);
3788 	litest_drain_events(li);
3789 
3790 	calibration[0] = 1;
3791 	calibration[4] = 0.5;
3792 	status = libinput_device_config_calibration_set_matrix(d,
3793 							       calibration);
3794 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
3795 
3796 	litest_tablet_proximity_in(dev, 100, 100, axes);
3797 	libinput_dispatch(li);
3798 
3799 	event = libinput_get_event(li);
3800 	tablet_event = litest_is_tablet_event(event,
3801 					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3802 	x = libinput_event_tablet_tool_get_x_transformed(tablet_event, 100);
3803 	y = libinput_event_tablet_tool_get_y_transformed(tablet_event, 100);
3804 	libinput_event_destroy(event);
3805 
3806 	ck_assert(x > 99.0);
3807 	ck_assert(x < 100.0);
3808 	ck_assert(y > 49.0);
3809 	ck_assert(y < 51.0);
3810 
3811 	litest_tablet_proximity_out(dev);
3812 }
3813 END_TEST
3814 
START_TEST(tablet_pressure_offset)3815 START_TEST(tablet_pressure_offset)
3816 {
3817 	struct litest_device *dev = litest_current_device();
3818 	struct libinput *li = dev->libinput;
3819 	struct libinput_event *event;
3820 	struct libinput_event_tablet_tool *tev;
3821 	struct axis_replacement axes[] = {
3822 		{ ABS_DISTANCE, 70 },
3823 		{ ABS_PRESSURE, 20 },
3824 		{ -1, -1 },
3825 	};
3826 	double pressure;
3827 
3828 	/* This activates the pressure thresholds */
3829 	litest_tablet_proximity_in(dev, 5, 100, axes);
3830 	litest_drain_events(li);
3831 
3832 	/* Put the pen down, with a pressure high enough to meet the
3833 	 * threshold */
3834 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
3835 	litest_axis_set_value(axes, ABS_PRESSURE, 25);
3836 
3837 	litest_push_event_frame(dev);
3838 	litest_tablet_motion(dev, 70, 70, axes);
3839 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
3840 	litest_pop_event_frame(dev);
3841 	libinput_dispatch(li);
3842 	litest_drain_events(li);
3843 
3844 	/* Reduce pressure to just a tick over the offset, otherwise we get
3845 	 * the tip up event again */
3846 	litest_axis_set_value(axes, ABS_PRESSURE, 20.1);
3847 	litest_tablet_motion(dev, 70, 70, axes);
3848 	libinput_dispatch(li);
3849 
3850 	event = libinput_get_event(li);
3851 	tev = litest_is_tablet_event(event,
3852 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3853 	pressure = libinput_event_tablet_tool_get_pressure(tev);
3854 
3855 	/* we can't actually get a real 0.0 because that would trigger a tip
3856 	   up. but it's close enough to zero. */
3857 	ck_assert_double_lt(pressure, 0.01);
3858 
3859 	libinput_event_destroy(event);
3860 	litest_drain_events(li);
3861 
3862 	litest_axis_set_value(axes, ABS_PRESSURE, 21);
3863 	litest_tablet_motion(dev, 70, 70, axes);
3864 
3865 	libinput_dispatch(li);
3866 	event = libinput_get_event(li);
3867 	tev = litest_is_tablet_event(event,
3868 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3869 
3870 	pressure = libinput_event_tablet_tool_get_pressure(tev);
3871 
3872 	ck_assert_double_lt(pressure, 0.015);
3873 	libinput_event_destroy(event);
3874 
3875 
3876 	/* Make sure we can reach the upper range too */
3877 	litest_axis_set_value(axes, ABS_PRESSURE, 100);
3878 	litest_tablet_motion(dev, 70, 70, axes);
3879 
3880 	libinput_dispatch(li);
3881 	event = libinput_get_event(li);
3882 	tev = litest_is_tablet_event(event,
3883 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3884 
3885 	pressure = libinput_event_tablet_tool_get_pressure(tev);
3886 
3887 	ck_assert_double_ge(pressure, 1.0);
3888 	libinput_event_destroy(event);
3889 
3890 }
3891 END_TEST
3892 
START_TEST(tablet_pressure_offset_decrease)3893 START_TEST(tablet_pressure_offset_decrease)
3894 {
3895 	struct litest_device *dev = litest_current_device();
3896 	struct libinput *li = dev->libinput;
3897 	struct libinput_event *event;
3898 	struct libinput_event_tablet_tool *tev;
3899 	struct axis_replacement axes[] = {
3900 		{ ABS_DISTANCE, 70 },
3901 		{ ABS_PRESSURE, 20 },
3902 		{ -1, -1 },
3903 	};
3904 	double pressure;
3905 
3906 	/* offset 20 on prox in */
3907 	litest_tablet_proximity_in(dev, 5, 100, axes);
3908 	litest_tablet_proximity_out(dev);
3909 	litest_drain_events(li);
3910 
3911 	/* a reduced pressure value must reduce the offset */
3912 	litest_axis_set_value(axes, ABS_PRESSURE, 10);
3913 	litest_tablet_proximity_in(dev, 5, 100, axes);
3914 	litest_tablet_proximity_out(dev);
3915 	litest_drain_events(li);
3916 
3917 	/* a higher pressure value leaves it as-is */
3918 	litest_tablet_proximity_in(dev, 5, 100, axes);
3919 	libinput_dispatch(li);
3920 	event = libinput_get_event(li);
3921 	tev = litest_is_tablet_event(event,
3922 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
3923 	pressure = libinput_event_tablet_tool_get_pressure(tev);
3924 	ck_assert_double_eq(pressure, 0.0);
3925 
3926 	libinput_event_destroy(event);
3927 	litest_drain_events(li);
3928 
3929 	/* trigger the pressure threshold */
3930 	litest_axis_set_value(axes, ABS_PRESSURE, 15);
3931 	litest_push_event_frame(dev);
3932 	litest_tablet_motion(dev, 70, 70, axes);
3933 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
3934 	litest_pop_event_frame(dev);
3935 	libinput_dispatch(li);
3936 
3937 	event = libinput_get_event(li);
3938 	tev = litest_is_tablet_event(event,
3939 				     LIBINPUT_EVENT_TABLET_TOOL_TIP);
3940 
3941 	pressure = libinput_event_tablet_tool_get_pressure(tev);
3942 
3943 	/* offset is 10, value is 15, so that's a around 5% of the
3944 	 * remaining range */
3945 	ck_assert_double_eq_tol(pressure, 0.05, 0.01);
3946 	libinput_event_destroy(event);
3947 }
3948 END_TEST
3949 
START_TEST(tablet_pressure_offset_increase)3950 START_TEST(tablet_pressure_offset_increase)
3951 {
3952 	struct litest_device *dev = litest_current_device();
3953 	struct libinput *li = dev->libinput;
3954 	struct libinput_event *event;
3955 	struct libinput_event_tablet_tool *tev;
3956 	struct axis_replacement axes[] = {
3957 		{ ABS_DISTANCE, 70 },
3958 		{ ABS_PRESSURE, 20 },
3959 		{ -1, -1 },
3960 	};
3961 	double pressure;
3962 
3963 	/* offset 20 on first prox in */
3964 	litest_tablet_proximity_in(dev, 5, 100, axes);
3965 	litest_tablet_proximity_out(dev);
3966 	litest_drain_events(li);
3967 
3968 	/* offset 30 on second prox in - must not change the offset */
3969 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
3970 	litest_tablet_proximity_in(dev, 5, 100, axes);
3971 	litest_drain_events(li);
3972 
3973 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
3974 	litest_axis_set_value(axes, ABS_PRESSURE, 31);
3975 	litest_push_event_frame(dev);
3976 	litest_tablet_motion(dev, 70, 70, axes);
3977 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
3978 	litest_pop_event_frame(dev);
3979 	libinput_dispatch(li);
3980 	litest_drain_events(li);
3981 
3982 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
3983 	litest_tablet_motion(dev, 70, 70, axes);
3984 	libinput_dispatch(li);
3985 
3986 	event = libinput_get_event(li);
3987 	tev = litest_is_tablet_event(event,
3988 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
3989 	pressure = libinput_event_tablet_tool_get_pressure(tev);
3990 	/* offset 20, value 30 leaves us with 12% of the remaining 90 range */
3991 	ck_assert_double_eq_tol(pressure, 0.12, 0.01);
3992 	libinput_event_destroy(event);
3993 
3994 	litest_drain_events(li);
3995 
3996 	litest_axis_set_value(axes, ABS_PRESSURE, 20);
3997 	litest_tablet_motion(dev, 70, 70, axes);
3998 	libinput_dispatch(li);
3999 
4000 	event = libinput_get_event(li);
4001 	tev = litest_is_tablet_event(event,
4002 				     LIBINPUT_EVENT_TABLET_TOOL_TIP);
4003 
4004 	pressure = libinput_event_tablet_tool_get_pressure(tev);
4005 
4006 	ck_assert_double_eq(pressure, 0.0);
4007 	libinput_event_destroy(event);
4008 }
4009 END_TEST
4010 
START_TEST(tablet_pressure_min_max)4011 START_TEST(tablet_pressure_min_max)
4012 {
4013 	struct litest_device *dev = litest_current_device();
4014 	struct libinput *li = dev->libinput;
4015 	struct libinput_event *event;
4016 	struct libinput_event_tablet_tool *tev;
4017 	struct axis_replacement axes[] = {
4018 		{ ABS_DISTANCE, 10 },
4019 		{ ABS_PRESSURE, 0 },
4020 		{ -1, -1 },
4021 	};
4022 	double p;
4023 
4024 	if (!libevdev_has_event_code(dev->evdev, EV_ABS, ABS_PRESSURE))
4025 		return;
4026 
4027 	litest_tablet_proximity_in(dev, 5, 50, axes);
4028 	litest_drain_events(li);
4029 	libinput_dispatch(li);
4030 
4031 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
4032 	litest_axis_set_value(axes, ABS_PRESSURE, 1);
4033 	litest_tablet_motion(dev, 5, 50, axes);
4034 	libinput_dispatch(li);
4035 	event = libinput_get_event(li);
4036 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4037 	ck_assert(libinput_event_tablet_tool_pressure_has_changed(tev));
4038 	p = libinput_event_tablet_tool_get_pressure(tev);
4039 	ck_assert_double_ge(p, 0.0);
4040 	libinput_event_destroy(event);
4041 
4042 	/* skip over pressure-based tip down */
4043 	litest_axis_set_value(axes, ABS_PRESSURE, 90);
4044 	litest_tablet_motion(dev, 5, 50, axes);
4045 	litest_drain_events(li);
4046 
4047 	/* need to fill the motion history */
4048 	litest_axis_set_value(axes, ABS_PRESSURE, 100);
4049 	litest_tablet_motion(dev, 5, 50, axes);
4050 	litest_tablet_motion(dev, 6, 50, axes);
4051 	litest_tablet_motion(dev, 7, 50, axes);
4052 	litest_tablet_motion(dev, 8, 50, axes);
4053 	litest_drain_events(li);
4054 
4055 	litest_tablet_motion(dev, 5, 50, axes);
4056 	libinput_dispatch(li);
4057 	event = libinput_get_event(li);
4058 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4059 	p = libinput_event_tablet_tool_get_pressure(tev);
4060 	ck_assert_double_ge(p, 1.0);
4061 	libinput_event_destroy(event);
4062 }
4063 END_TEST
4064 
START_TEST(tablet_pressure_range)4065 START_TEST(tablet_pressure_range)
4066 {
4067 	struct litest_device *dev = litest_current_device();
4068 	struct libinput *li = dev->libinput;
4069 	struct libinput_event *event;
4070 	struct libinput_event_tablet_tool *tev;
4071 	struct axis_replacement axes[] = {
4072 		{ ABS_DISTANCE, 0 },
4073 		{ ABS_PRESSURE, 10 },
4074 		{ -1, -1 },
4075 	};
4076 	int pressure;
4077 	double p;
4078 
4079 	litest_tablet_proximity_in(dev, 5, 100, axes);
4080 	litest_drain_events(li);
4081 	libinput_dispatch(li);
4082 
4083 	for (pressure = 10; pressure <= 100; pressure += 10) {
4084 		litest_axis_set_value(axes, ABS_PRESSURE, pressure);
4085 		litest_tablet_motion(dev, 70, 70, axes);
4086 		libinput_dispatch(li);
4087 
4088 		event = libinput_get_event(li);
4089 		tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4090 		p = libinput_event_tablet_tool_get_pressure(tev);
4091 		ck_assert_double_ge(p, 0.0);
4092 		ck_assert_double_le(p, 1.0);
4093 		libinput_event_destroy(event);
4094 	}
4095 }
4096 END_TEST
4097 
4098 static void
pressure_threshold_warning(struct libinput * libinput,enum libinput_log_priority priority,const char * format,va_list args)4099 pressure_threshold_warning(struct libinput *libinput,
4100 			   enum libinput_log_priority priority,
4101 			   const char *format,
4102 			   va_list args)
4103 {
4104 	struct litest_user_data *user_data = libinput_get_user_data(libinput);
4105 	int *warning_triggered = user_data->private;
4106 
4107 	if (priority == LIBINPUT_LOG_PRIORITY_ERROR &&
4108 	    strstr(format, "pressure offset greater"))
4109 		(*warning_triggered)++;
4110 }
4111 
START_TEST(tablet_pressure_offset_exceed_threshold)4112 START_TEST(tablet_pressure_offset_exceed_threshold)
4113 {
4114 	struct litest_device *dev = litest_current_device();
4115 	struct libinput *li = dev->libinput;
4116 	struct libinput_event *event;
4117 	struct libinput_event_tablet_tool *tev;
4118 	struct axis_replacement axes[] = {
4119 		{ ABS_DISTANCE, 70 },
4120 		{ ABS_PRESSURE, 30 },
4121 		{ -1, -1 },
4122 	};
4123 	double pressure;
4124 	int warning_triggered = 0;
4125 	struct litest_user_data *user_data = libinput_get_user_data(li);
4126 
4127 	litest_drain_events(li);
4128 
4129 	user_data->private = &warning_triggered;
4130 
4131 	libinput_log_set_handler(li, pressure_threshold_warning);
4132 	litest_tablet_proximity_in(dev, 5, 100, axes);
4133 	libinput_dispatch(li);
4134 	event = libinput_get_event(li);
4135 	tev = litest_is_tablet_event(event,
4136 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
4137 	pressure = libinput_event_tablet_tool_get_pressure(tev);
4138 	ck_assert_double_gt(pressure, 0.0);
4139 	libinput_event_destroy(event);
4140 
4141 	ck_assert_int_eq(warning_triggered, 1);
4142 	litest_restore_log_handler(li);
4143 }
4144 END_TEST
4145 
START_TEST(tablet_pressure_offset_none_for_zero_distance)4146 START_TEST(tablet_pressure_offset_none_for_zero_distance)
4147 {
4148 	struct litest_device *dev = litest_current_device();
4149 	struct libinput *li = dev->libinput;
4150 	struct libinput_event *event;
4151 	struct libinput_event_tablet_tool *tev;
4152 	struct axis_replacement axes[] = {
4153 		{ ABS_DISTANCE, 0 },
4154 		{ ABS_PRESSURE, 20 },
4155 		{ -1, -1 },
4156 	};
4157 	double pressure;
4158 
4159 	litest_drain_events(li);
4160 
4161 	/* we're going straight to touch on proximity, make sure we don't
4162 	 * offset the pressure here */
4163 	litest_push_event_frame(dev);
4164 	litest_tablet_proximity_in(dev, 5, 100, axes);
4165 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
4166 	litest_pop_event_frame(dev);
4167 	libinput_dispatch(li);
4168 
4169 	event = libinput_get_event(li);
4170 	tev = litest_is_tablet_event(event,
4171 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
4172 	pressure = libinput_event_tablet_tool_get_pressure(tev);
4173 	ck_assert_double_gt(pressure, 0.0);
4174 
4175 	libinput_event_destroy(event);
4176 }
4177 END_TEST
4178 
START_TEST(tablet_pressure_offset_none_for_small_distance)4179 START_TEST(tablet_pressure_offset_none_for_small_distance)
4180 {
4181 	struct litest_device *dev = litest_current_device();
4182 	struct libinput *li = dev->libinput;
4183 	struct libinput_event *event;
4184 	struct libinput_event_tablet_tool *tev;
4185 	struct axis_replacement axes[] = {
4186 		{ ABS_DISTANCE, 20 },
4187 		{ ABS_PRESSURE, 20 },
4188 		{ -1, -1 },
4189 	};
4190 	double pressure;
4191 
4192 	/* stylus too close to the tablet on the proximity in, ignore any
4193 	 * pressure offset */
4194 	litest_tablet_proximity_in(dev, 5, 100, axes);
4195 	litest_drain_events(li);
4196 	libinput_dispatch(li);
4197 
4198 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
4199 	litest_axis_set_value(axes, ABS_PRESSURE, 21);
4200 	litest_push_event_frame(dev);
4201 	litest_tablet_motion(dev, 70, 70, axes);
4202 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
4203 	litest_pop_event_frame(dev);
4204 	litest_drain_events(li);
4205 
4206 	litest_axis_set_value(axes, ABS_PRESSURE, 20);
4207 	litest_tablet_motion(dev, 70, 70, axes);
4208 	libinput_dispatch(li);
4209 
4210 	event = libinput_get_event(li);
4211 	tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4212 	pressure = libinput_event_tablet_tool_get_pressure(tev);
4213 	ck_assert_double_gt(pressure, 0.0);
4214 
4215 	libinput_event_destroy(event);
4216 }
4217 END_TEST
4218 
START_TEST(tablet_distance_range)4219 START_TEST(tablet_distance_range)
4220 {
4221 	struct litest_device *dev = litest_current_device();
4222 	struct libinput *li = dev->libinput;
4223 	struct libinput_event *event;
4224 	struct libinput_event_tablet_tool *tev;
4225 	struct axis_replacement axes[] = {
4226 		{ ABS_DISTANCE, 20 },
4227 		{ ABS_PRESSURE, 0 },
4228 		{ -1, -1 },
4229 	};
4230 	int distance;
4231 	double dist;
4232 
4233 	litest_tablet_proximity_in(dev, 5, 100, axes);
4234 	litest_drain_events(li);
4235 	libinput_dispatch(li);
4236 
4237 	for (distance = 0; distance <= 100; distance += 10) {
4238 		litest_axis_set_value(axes, ABS_DISTANCE, distance);
4239 		litest_tablet_motion(dev, 70, 70, axes);
4240 		libinput_dispatch(li);
4241 
4242 		event = libinput_get_event(li);
4243 		tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4244 		dist = libinput_event_tablet_tool_get_distance(tev);
4245 		ck_assert_double_ge(dist, 0.0);
4246 		ck_assert_double_le(dist, 1.0);
4247 		libinput_event_destroy(event);
4248 	}
4249 }
4250 END_TEST
4251 
START_TEST(tilt_available)4252 START_TEST(tilt_available)
4253 {
4254 	struct litest_device *dev = litest_current_device();
4255 	struct libinput *li = dev->libinput;
4256 	struct libinput_event *event;
4257 	struct libinput_event_tablet_tool *tev;
4258 	struct libinput_tablet_tool *tool;
4259 	struct axis_replacement axes[] = {
4260 		{ ABS_DISTANCE, 10 },
4261 		{ ABS_PRESSURE, 0 },
4262 		{ ABS_TILT_X, 80 },
4263 		{ ABS_TILT_Y, 20 },
4264 		{ -1, -1 }
4265 	};
4266 
4267 	litest_drain_events(li);
4268 
4269 	litest_tablet_proximity_in(dev, 10, 10, axes);
4270 	libinput_dispatch(li);
4271 	event = libinput_get_event(li);
4272 	tev = litest_is_tablet_event(event,
4273 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
4274 
4275 	tool = libinput_event_tablet_tool_get_tool(tev);
4276 	ck_assert(libinput_tablet_tool_has_tilt(tool));
4277 
4278 	libinput_event_destroy(event);
4279 }
4280 END_TEST
4281 
START_TEST(tilt_not_available)4282 START_TEST(tilt_not_available)
4283 {
4284 	struct litest_device *dev = litest_current_device();
4285 	struct libinput *li = dev->libinput;
4286 	struct libinput_event *event;
4287 	struct libinput_event_tablet_tool *tev;
4288 	struct libinput_tablet_tool *tool;
4289 	struct axis_replacement axes[] = {
4290 		{ ABS_DISTANCE, 10 },
4291 		{ ABS_PRESSURE, 0 },
4292 		{ ABS_TILT_X, 80 },
4293 		{ ABS_TILT_Y, 20 },
4294 		{ -1, -1 }
4295 	};
4296 
4297 	litest_drain_events(li);
4298 
4299 	litest_tablet_proximity_in(dev, 10, 10, axes);
4300 	libinput_dispatch(li);
4301 	event = libinput_get_event(li);
4302 	tev = litest_is_tablet_event(event,
4303 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
4304 
4305 	tool = libinput_event_tablet_tool_get_tool(tev);
4306 	ck_assert(!libinput_tablet_tool_has_tilt(tool));
4307 
4308 	libinput_event_destroy(event);
4309 }
4310 END_TEST
4311 
START_TEST(tilt_x)4312 START_TEST(tilt_x)
4313 {
4314 	struct litest_device *dev = litest_current_device();
4315 	struct libinput *li = dev->libinput;
4316 	struct libinput_event *event;
4317 	struct libinput_event_tablet_tool *tev;
4318 	struct axis_replacement axes[] = {
4319 		{ ABS_DISTANCE, 10 },
4320 		{ ABS_PRESSURE, 0 },
4321 		{ ABS_TILT_X, 10 },
4322 		{ ABS_TILT_Y, 0 },
4323 		{ -1, -1 }
4324 	};
4325 	double tx, ty;
4326 	int tilt;
4327 	double expected_tx;
4328 
4329 	litest_drain_events(li);
4330 
4331 	litest_tablet_proximity_in(dev, 10, 10, axes);
4332 	libinput_dispatch(li);
4333 	event = libinput_get_event(li);
4334 	tev = litest_is_tablet_event(event,
4335 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
4336 
4337 	/* 90% of the actual axis but mapped into a [-64, 64] tilt range, so
4338 	 * we expect 51 degrees ± rounding errors */
4339 	tx = libinput_event_tablet_tool_get_tilt_x(tev);
4340 	ck_assert_double_le(tx, -50);
4341 	ck_assert_double_ge(tx, -52);
4342 
4343 	ty = libinput_event_tablet_tool_get_tilt_y(tev);
4344 	ck_assert_double_ge(ty, -65);
4345 	ck_assert_double_lt(ty, -63);
4346 
4347 	libinput_event_destroy(event);
4348 
4349 	expected_tx = -64.0;
4350 
4351 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
4352 	litest_axis_set_value(axes, ABS_PRESSURE, 1);
4353 
4354 	for (tilt = 0; tilt <= 100; tilt += 5) {
4355 		litest_axis_set_value(axes, ABS_TILT_X, tilt);
4356 		/* work around smoothing */
4357 		litest_tablet_motion(dev, 10, 10, axes);
4358 		litest_tablet_motion(dev, 10, 11, axes);
4359 		litest_tablet_motion(dev, 10, 10, axes);
4360 		litest_drain_events(li);
4361 		litest_tablet_motion(dev, 10, 11, axes);
4362 		libinput_dispatch(li);
4363 		event = libinput_get_event(li);
4364 		tev = litest_is_tablet_event(event,
4365 					     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4366 
4367 		tx = libinput_event_tablet_tool_get_tilt_x(tev);
4368 		ck_assert_double_ge(tx, expected_tx - 2);
4369 		ck_assert_double_le(tx, expected_tx + 2);
4370 
4371 		ty = libinput_event_tablet_tool_get_tilt_y(tev);
4372 		ck_assert_double_ge(ty, -65);
4373 		ck_assert_double_lt(ty, -63);
4374 
4375 		libinput_event_destroy(event);
4376 
4377 		expected_tx = tx + 6.04;
4378 	}
4379 
4380 	/* the last event must reach the max */
4381 	ck_assert_double_ge(tx, 63.0);
4382 	ck_assert_double_le(tx, 64.0);
4383 }
4384 END_TEST
4385 
START_TEST(tilt_y)4386 START_TEST(tilt_y)
4387 {
4388 	struct litest_device *dev = litest_current_device();
4389 	struct libinput *li = dev->libinput;
4390 	struct libinput_event *event;
4391 	struct libinput_event_tablet_tool *tev;
4392 	struct axis_replacement axes[] = {
4393 		{ ABS_DISTANCE, 10 },
4394 		{ ABS_PRESSURE, 0 },
4395 		{ ABS_TILT_X, 0 },
4396 		{ ABS_TILT_Y, 10 },
4397 		{ -1, -1 }
4398 	};
4399 	double tx, ty;
4400 	int tilt;
4401 	double expected_ty;
4402 
4403 	litest_drain_events(li);
4404 
4405 	litest_tablet_proximity_in(dev, 10, 10, axes);
4406 	libinput_dispatch(li);
4407 	event = libinput_get_event(li);
4408 	tev = litest_is_tablet_event(event,
4409 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
4410 
4411 	/* 90% of the actual axis but mapped into a [-64, 64] tilt range, so
4412 	 * we expect 50 degrees ± rounding errors */
4413 	ty = libinput_event_tablet_tool_get_tilt_y(tev);
4414 	ck_assert_double_le(ty, -50);
4415 	ck_assert_double_ge(ty, -52);
4416 
4417 	tx = libinput_event_tablet_tool_get_tilt_x(tev);
4418 	ck_assert_double_ge(tx, -65);
4419 	ck_assert_double_lt(tx, -63);
4420 
4421 	libinput_event_destroy(event);
4422 
4423 	expected_ty = -64;
4424 
4425 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
4426 	litest_axis_set_value(axes, ABS_PRESSURE, 1);
4427 
4428 	for (tilt = 0; tilt <= 100; tilt += 5) {
4429 		litest_axis_set_value(axes, ABS_TILT_Y, tilt);
4430 		/* work around smoothing */
4431 		litest_tablet_motion(dev, 10, 11, axes);
4432 		litest_tablet_motion(dev, 10, 10, axes);
4433 		litest_tablet_motion(dev, 10, 11, axes);
4434 		litest_drain_events(li);
4435 		litest_tablet_motion(dev, 10, 10, axes);
4436 		libinput_dispatch(li);
4437 		event = libinput_get_event(li);
4438 		tev = litest_is_tablet_event(event,
4439 					     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4440 
4441 		ty = libinput_event_tablet_tool_get_tilt_y(tev);
4442 		ck_assert_double_ge(ty, expected_ty - 2);
4443 		ck_assert_double_le(ty, expected_ty + 2);
4444 
4445 		tx = libinput_event_tablet_tool_get_tilt_x(tev);
4446 		ck_assert_double_ge(tx, -65);
4447 		ck_assert_double_lt(tx, -63);
4448 
4449 		libinput_event_destroy(event);
4450 
4451 		expected_ty = ty + 6;
4452 	}
4453 
4454 	/* the last event must reach the max */
4455 	ck_assert_double_ge(ty, 63.0);
4456 	ck_assert_double_le(tx, 64.0);
4457 }
4458 END_TEST
4459 
START_TEST(relative_no_profile)4460 START_TEST(relative_no_profile)
4461 {
4462 	struct litest_device *dev = litest_current_device();
4463 	struct libinput_device *device = dev->libinput_device;
4464 	enum libinput_config_accel_profile profile;
4465 	enum libinput_config_status status;
4466 	uint32_t profiles;
4467 
4468 	ck_assert(libinput_device_config_accel_is_available(device));
4469 
4470 	profile = libinput_device_config_accel_get_default_profile(device);
4471 	ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
4472 
4473 	profile = libinput_device_config_accel_get_profile(device);
4474 	ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
4475 
4476 	profiles = libinput_device_config_accel_get_profiles(device);
4477 	ck_assert_int_eq(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE, 0);
4478 	ck_assert_int_eq(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT, 0);
4479 
4480 	status = libinput_device_config_accel_set_profile(device,
4481 							  LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
4482 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
4483 	profile = libinput_device_config_accel_get_profile(device);
4484 	ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
4485 
4486 	status = libinput_device_config_accel_set_profile(device,
4487 							  LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
4488 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
4489 	profile = libinput_device_config_accel_get_profile(device);
4490 	ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
4491 }
4492 END_TEST
4493 
START_TEST(relative_no_delta_prox_in)4494 START_TEST(relative_no_delta_prox_in)
4495 {
4496 	struct litest_device *dev = litest_current_device();
4497 	struct libinput *li = dev->libinput;
4498 	struct libinput_event *event;
4499 	struct libinput_event_tablet_tool *tev;
4500 	struct axis_replacement axes[] = {
4501 		{ ABS_DISTANCE, 10 },
4502 		{ ABS_PRESSURE, 0 },
4503 		{ -1, -1 }
4504 	};
4505 	double dx, dy;
4506 
4507 	litest_drain_events(li);
4508 
4509 	litest_tablet_proximity_in(dev, 10, 10, axes);
4510 	libinput_dispatch(li);
4511 	event = libinput_get_event(li);
4512 	tev = litest_is_tablet_event(event,
4513 				     LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
4514 	dx = libinput_event_tablet_tool_get_dx(tev);
4515 	dy = libinput_event_tablet_tool_get_dy(tev);
4516 	ck_assert(dx == 0.0);
4517 	ck_assert(dy == 0.0);
4518 
4519 	libinput_event_destroy(event);
4520 }
4521 END_TEST
4522 
START_TEST(relative_delta)4523 START_TEST(relative_delta)
4524 {
4525 	struct litest_device *dev = litest_current_device();
4526 	struct libinput *li = dev->libinput;
4527 	struct libinput_event *event;
4528 	struct libinput_event_tablet_tool *tev;
4529 	struct axis_replacement axes[] = {
4530 		{ ABS_DISTANCE, 10 },
4531 		{ ABS_PRESSURE, 0 },
4532 		{ -1, -1 }
4533 	};
4534 	double dx, dy;
4535 
4536 	litest_tablet_proximity_in(dev, 10, 10, axes);
4537 	litest_drain_events(li);
4538 
4539 	/* flush the motion history */
4540 	for (int i = 0; i < 5; i ++)
4541 		litest_tablet_motion(dev, 10 + i, 10, axes);
4542 	litest_drain_events(li);
4543 
4544 	litest_tablet_motion(dev, 20, 10, axes);
4545 	libinput_dispatch(li);
4546 
4547 	event = libinput_get_event(li);
4548 	tev = litest_is_tablet_event(event,
4549 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4550 	dx = libinput_event_tablet_tool_get_dx(tev);
4551 	dy = libinput_event_tablet_tool_get_dy(tev);
4552 	ck_assert(dx > 0.0);
4553 	ck_assert(dy == 0.0);
4554 	libinput_event_destroy(event);
4555 
4556 	/* flush the motion history */
4557 	for (int i = 0; i < 5; i ++)
4558 		litest_tablet_motion(dev, 20 - i, 10, axes);
4559 	litest_drain_events(li);
4560 
4561 	litest_tablet_motion(dev, 5, 10, axes);
4562 	libinput_dispatch(li);
4563 	event = libinput_get_event(li);
4564 	tev = litest_is_tablet_event(event,
4565 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4566 	dx = libinput_event_tablet_tool_get_dx(tev);
4567 	dy = libinput_event_tablet_tool_get_dy(tev);
4568 	ck_assert(dx < 0.0);
4569 	ck_assert(dy == 0.0);
4570 	libinput_event_destroy(event);
4571 
4572 	/* flush the motion history */
4573 	for (int i = 0; i < 5; i ++)
4574 		litest_tablet_motion(dev, 5, 10 + i, axes);
4575 	litest_drain_events(li);
4576 
4577 	litest_tablet_motion(dev, 5, 20, axes);
4578 	libinput_dispatch(li);
4579 	event = libinput_get_event(li);
4580 	tev = litest_is_tablet_event(event,
4581 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4582 	dx = libinput_event_tablet_tool_get_dx(tev);
4583 	dy = libinput_event_tablet_tool_get_dy(tev);
4584 	ck_assert(dx == 0.0);
4585 	ck_assert(dy > 0.0);
4586 	libinput_event_destroy(event);
4587 
4588 
4589 	/* flush the motion history */
4590 	for (int i = 0; i < 5; i ++)
4591 		litest_tablet_motion(dev, 5, 20 - i, axes);
4592 	litest_drain_events(li);
4593 
4594 	litest_tablet_motion(dev, 5, 10, axes);
4595 	libinput_dispatch(li);
4596 	event = libinput_get_event(li);
4597 	tev = litest_is_tablet_event(event,
4598 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4599 	dx = libinput_event_tablet_tool_get_dx(tev);
4600 	dy = libinput_event_tablet_tool_get_dy(tev);
4601 	ck_assert(dx == 0.0);
4602 	ck_assert(dy < 0.0);
4603 	libinput_event_destroy(event);
4604 }
4605 END_TEST
4606 
START_TEST(relative_no_delta_on_tip)4607 START_TEST(relative_no_delta_on_tip)
4608 {
4609 	struct litest_device *dev = litest_current_device();
4610 	struct libinput *li = dev->libinput;
4611 	struct libinput_event *event;
4612 	struct libinput_event_tablet_tool *tev;
4613 	struct axis_replacement axes[] = {
4614 		{ ABS_DISTANCE, 10 },
4615 		{ ABS_PRESSURE, 0 },
4616 		{ -1, -1 }
4617 	};
4618 	double dx, dy;
4619 
4620 	litest_tablet_proximity_in(dev, 10, 10, axes);
4621 	litest_drain_events(li);
4622 
4623 	litest_tablet_motion(dev, 20, 10, axes);
4624 	litest_drain_events(li);
4625 
4626 	/* tip down */
4627 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
4628 	litest_axis_set_value(axes, ABS_PRESSURE, 30);
4629 	litest_push_event_frame(dev);
4630 	litest_tablet_motion(dev, 30, 20, axes);
4631 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
4632 	litest_pop_event_frame(dev);
4633 
4634 	libinput_dispatch(li);
4635 	event = libinput_get_event(li);
4636 	tev = litest_is_tablet_event(event,
4637 				     LIBINPUT_EVENT_TABLET_TOOL_TIP);
4638 	ck_assert(libinput_event_tablet_tool_x_has_changed(tev));
4639 	ck_assert(libinput_event_tablet_tool_y_has_changed(tev));
4640 	dx = libinput_event_tablet_tool_get_dx(tev);
4641 	dy = libinput_event_tablet_tool_get_dy(tev);
4642 	ck_assert(dx == 0.0);
4643 	ck_assert(dy == 0.0);
4644 	libinput_event_destroy(event);
4645 
4646 	/* normal motion */
4647 	litest_tablet_motion(dev, 40, 30, axes);
4648 	libinput_dispatch(li);
4649 	event = libinput_get_event(li);
4650 	tev = litest_is_tablet_event(event,
4651 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4652 	dx = libinput_event_tablet_tool_get_dx(tev);
4653 	dy = libinput_event_tablet_tool_get_dy(tev);
4654 	ck_assert(dx > 0.0);
4655 	ck_assert(dy > 0.0);
4656 	libinput_event_destroy(event);
4657 
4658 	/* tip up */
4659 	litest_axis_set_value(axes, ABS_DISTANCE, 10);
4660 	litest_axis_set_value(axes, ABS_PRESSURE, 0);
4661 	litest_push_event_frame(dev);
4662 	litest_tablet_motion(dev, 50, 40, axes);
4663 	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
4664 	litest_pop_event_frame(dev);
4665 	libinput_dispatch(li);
4666 	event = libinput_get_event(li);
4667 	tev = litest_is_tablet_event(event,
4668 				     LIBINPUT_EVENT_TABLET_TOOL_TIP);
4669 	ck_assert(libinput_event_tablet_tool_x_has_changed(tev));
4670 	ck_assert(libinput_event_tablet_tool_y_has_changed(tev));
4671 	dx = libinput_event_tablet_tool_get_dx(tev);
4672 	dy = libinput_event_tablet_tool_get_dy(tev);
4673 	ck_assert(dx == 0.0);
4674 	ck_assert(dy == 0.0);
4675 	libinput_event_destroy(event);
4676 }
4677 END_TEST
4678 
START_TEST(relative_calibration)4679 START_TEST(relative_calibration)
4680 {
4681 	struct litest_device *dev = litest_current_device();
4682 	struct libinput *li = dev->libinput;
4683 	struct libinput_event *event;
4684 	struct libinput_event_tablet_tool *tev;
4685 	struct axis_replacement axes[] = {
4686 		{ ABS_DISTANCE, 10 },
4687 		{ ABS_PRESSURE, 0 },
4688 		{ -1, -1 }
4689 	};
4690 	double dx, dy;
4691 	float calibration[] = { -1, 0, 1, 0, -1, 1 };
4692 	enum libinput_config_status status;
4693 
4694 	if (!libinput_device_config_calibration_has_matrix(dev->libinput_device))
4695 		return;
4696 
4697 	status = libinput_device_config_calibration_set_matrix(
4698 							dev->libinput_device,
4699 							calibration);
4700 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
4701 
4702 	litest_tablet_proximity_in(dev, 10, 10, axes);
4703 	litest_drain_events(li);
4704 
4705 	litest_tablet_motion(dev, 20, 10, axes);
4706 	libinput_dispatch(li);
4707 
4708 	event = libinput_get_event(li);
4709 	tev = litest_is_tablet_event(event,
4710 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4711 	dx = libinput_event_tablet_tool_get_dx(tev);
4712 	dy = libinput_event_tablet_tool_get_dy(tev);
4713 	ck_assert(dx < 0.0);
4714 	ck_assert(dy == 0.0);
4715 	libinput_event_destroy(event);
4716 
4717 	/* work around axis smoothing */
4718 	litest_tablet_motion(dev, 19, 10, axes);
4719 	litest_tablet_motion(dev, 18, 10, axes);
4720 	litest_tablet_motion(dev, 17, 10, axes);
4721 	litest_drain_events(li);
4722 
4723 	litest_tablet_motion(dev, 5, 10, axes);
4724 	libinput_dispatch(li);
4725 	event = libinput_get_event(li);
4726 	tev = litest_is_tablet_event(event,
4727 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4728 	dx = libinput_event_tablet_tool_get_dx(tev);
4729 	dy = libinput_event_tablet_tool_get_dy(tev);
4730 	ck_assert(dx > 0.0);
4731 	ck_assert(dy == 0.0);
4732 	libinput_event_destroy(event);
4733 
4734 	/* work around axis smoothing */
4735 	litest_tablet_motion(dev, 5, 11, axes);
4736 	litest_tablet_motion(dev, 5, 12, axes);
4737 	litest_tablet_motion(dev, 5, 13, axes);
4738 	litest_drain_events(li);
4739 
4740 	litest_tablet_motion(dev, 5, 20, axes);
4741 	libinput_dispatch(li);
4742 	event = libinput_get_event(li);
4743 	tev = litest_is_tablet_event(event,
4744 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4745 	dx = libinput_event_tablet_tool_get_dx(tev);
4746 	dy = libinput_event_tablet_tool_get_dy(tev);
4747 	ck_assert(dx == 0.0);
4748 	ck_assert(dy < 0.0);
4749 	libinput_event_destroy(event);
4750 
4751 	/* work around axis smoothing */
4752 	litest_tablet_motion(dev, 5, 19, axes);
4753 	litest_tablet_motion(dev, 5, 18, axes);
4754 	litest_tablet_motion(dev, 5, 17, axes);
4755 	litest_drain_events(li);
4756 
4757 	litest_tablet_motion(dev, 5, 5, axes);
4758 	libinput_dispatch(li);
4759 	event = libinput_get_event(li);
4760 	tev = litest_is_tablet_event(event,
4761 				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4762 	dx = libinput_event_tablet_tool_get_dx(tev);
4763 	dy = libinput_event_tablet_tool_get_dy(tev);
4764 	ck_assert(dx == 0.0);
4765 	ck_assert(dy > 0.0);
4766 	libinput_event_destroy(event);
4767 }
4768 END_TEST
4769 
4770 static enum litest_device_type
paired_device(struct litest_device * dev)4771 paired_device(struct litest_device *dev)
4772 {
4773 	switch(dev->which) {
4774 	case LITEST_WACOM_INTUOS:
4775 		return LITEST_WACOM_FINGER;
4776 	case LITEST_WACOM_FINGER:
4777 		return LITEST_WACOM_INTUOS;
4778 	case LITEST_WACOM_CINTIQ_13HDT_PEN:
4779 		return LITEST_WACOM_CINTIQ_13HDT_FINGER;
4780 	case LITEST_WACOM_CINTIQ_13HDT_FINGER:
4781 		return LITEST_WACOM_CINTIQ_13HDT_PEN;
4782 	default:
4783 		return LITEST_NO_DEVICE;
4784 	}
4785 }
4786 
START_TEST(touch_arbitration)4787 START_TEST(touch_arbitration)
4788 {
4789 	struct litest_device *dev = litest_current_device();
4790 	enum litest_device_type other;
4791 	struct litest_device *finger;
4792 	struct libinput *li = dev->libinput;
4793 	struct axis_replacement axes[] = {
4794 		{ ABS_TILT_X, 80 },
4795 		{ ABS_TILT_Y, 80 },
4796 		{ ABS_DISTANCE, 10 },
4797 		{ ABS_PRESSURE, 0 },
4798 		{ -1, -1 }
4799 	};
4800 	bool is_touchpad;
4801 	double x, y;
4802 	double tx, ty;
4803 
4804 	other = paired_device(dev);
4805 	if (other == LITEST_NO_DEVICE)
4806 		return;
4807 
4808 	finger = litest_add_device(li, other);
4809 	litest_drain_events(li);
4810 
4811 	is_touchpad = !libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT);
4812 
4813 	if (is_touchpad)
4814 		litest_disable_hold_gestures(finger->libinput_device);
4815 
4816 	litest_tablet_proximity_in(dev, 10, 10, axes);
4817 	litest_tablet_motion(dev, 10, 10, axes);
4818 	litest_tablet_motion(dev, 20, 40, axes);
4819 	litest_drain_events(li);
4820 
4821 	tx = 20;
4822 	ty = 40;
4823 	x = 21;
4824 	y = 41;
4825 	litest_touch_down(finger, 0, x, y);
4826 
4827 	/* We need to intersperce the touch events with tablets so we don't
4828 	   trigger the tablet proximity timeout. */
4829 	for (int i = 0; i < 60; i += 5) {
4830 		litest_touch_move(finger, 0, x + i, y + i);
4831 		litest_tablet_motion(dev, tx + 0.1 * i, ty + 0.1 * i, axes);
4832 	}
4833 	litest_assert_only_typed_events(li,
4834 					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
4835 	litest_tablet_proximity_out(dev);
4836 	litest_assert_only_typed_events(li,
4837 					LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
4838 
4839 	litest_timeout_touch_arbitration();
4840 	libinput_dispatch(li);
4841 
4842 	/* finger still down */
4843 	litest_touch_move_to(finger, 0, 80, 80, 30, 30, 10);
4844 	litest_touch_up(finger, 0);
4845 	litest_assert_empty_queue(li);
4846 
4847 	litest_timeout_touch_arbitration();
4848 	libinput_dispatch(li);
4849 
4850 	/* lift finger, expect expect events */
4851 	litest_touch_down(finger, 0, 30, 30);
4852 	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10);
4853 	litest_touch_up(finger, 0);
4854 	libinput_dispatch(li);
4855 
4856 	if (is_touchpad)
4857 		litest_assert_only_typed_events(li,
4858 						LIBINPUT_EVENT_POINTER_MOTION);
4859 	else
4860 		litest_assert_touch_sequence(li);
4861 
4862 	litest_delete_device(finger);
4863 }
4864 END_TEST
4865 
START_TEST(touch_arbitration_outside_rect)4866 START_TEST(touch_arbitration_outside_rect)
4867 {
4868 	struct litest_device *dev = litest_current_device();
4869 	enum litest_device_type other;
4870 	struct litest_device *finger;
4871 	struct libinput *li = dev->libinput;
4872 	struct axis_replacement axes[] = {
4873 		{ ABS_TILT_X, 80 },
4874 		{ ABS_TILT_Y, 80 },
4875 		{ ABS_DISTANCE, 10 },
4876 		{ ABS_PRESSURE, 0 },
4877 		{ -1, -1 }
4878 	};
4879 	double x, y;
4880 	bool is_touchpad;
4881 
4882 	other = paired_device(dev);
4883 	if (other == LITEST_NO_DEVICE)
4884 		return;
4885 
4886 	finger = litest_add_device(li, other);
4887 	litest_drain_events(li);
4888 
4889 	is_touchpad = !libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT);
4890 	if (is_touchpad)
4891 		return;
4892 
4893 	x = 20;
4894 	y = 45;
4895 
4896 	/* disable prox-out timer quirk */
4897 	litest_tablet_proximity_in(dev, x, y - 1, axes);
4898 	litest_tablet_proximity_out(dev);
4899 
4900 	litest_tablet_proximity_in(dev, x, y - 1, axes);
4901 	litest_drain_events(li);
4902 
4903 	/* these are in percent, but the pen/finger have different
4904 	 * resolution and the rect works in mm, so the numbers below are
4905 	 * hand-picked for the test device */
4906 	litest_tablet_motion(dev, x, y, axes);
4907 	litest_drain_events(li);
4908 
4909 	/* left of rect */
4910 	litest_touch_sequence(finger, 0, x - 10, y + 2, x - 10, y + 20, 3);
4911 	libinput_dispatch(li);
4912 	litest_assert_touch_sequence(li);
4913 
4914 	/* above rect */
4915 	litest_touch_sequence(finger, 0, x + 2, y - 35, x + 20, y - 10, 3);
4916 	libinput_dispatch(li);
4917 	litest_assert_touch_sequence(li);
4918 
4919 	/* right of rect */
4920 	litest_touch_sequence(finger, 0, x + 80, y + 2, x + 20, y + 10, 3);
4921 	libinput_dispatch(li);
4922 	litest_assert_touch_sequence(li);
4923 
4924 #if 0
4925 	/* This *should* work but the Cintiq test devices is <200mm
4926 	   high, so we can't test for anything below the tip */
4927 	x = 20;
4928 	y = 10;
4929 	litest_tablet_proximity_out(dev);
4930 	litest_tablet_motion(dev, x, y, axes);
4931 	litest_tablet_proximity_in(dev, x, y - 1, axes);
4932 	litest_drain_events(li);
4933 
4934 	/* below rect */
4935 	litest_touch_sequence(finger, 0, x + 2, y + 80, x + 20, y + 20, 30);
4936 	libinput_dispatch(li);
4937 	litest_assert_touch_sequence(li);
4938 #endif
4939 
4940 	litest_delete_device(finger);
4941 }
4942 END_TEST
4943 
START_TEST(touch_arbitration_remove_after)4944 START_TEST(touch_arbitration_remove_after)
4945 {
4946 	struct litest_device *dev = litest_current_device();
4947 	enum litest_device_type other;
4948 	struct litest_device *finger;
4949 	struct libinput *li = dev->libinput;
4950 	struct axis_replacement axes[] = {
4951 		{ ABS_TILT_X, 80 },
4952 		{ ABS_TILT_Y, 80 },
4953 		{ ABS_DISTANCE, 10 },
4954 		{ ABS_PRESSURE, 0 },
4955 		{ -1, -1 }
4956 	};
4957 	bool is_touchpad;
4958 
4959 	other = paired_device(dev);
4960 	if (other == LITEST_NO_DEVICE)
4961 		return;
4962 
4963 	finger = litest_add_device(li, other);
4964 	litest_drain_events(li);
4965 
4966 	is_touchpad = !libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT);
4967 	if (is_touchpad)
4968 		return;
4969 
4970 	litest_tablet_proximity_in(dev, 50, 50, axes);
4971 	litest_drain_events(li);
4972 
4973 	litest_touch_down(finger, 0, 70, 70);
4974 	litest_drain_events(li);
4975 	litest_tablet_proximity_out(dev);
4976 	libinput_dispatch(li);
4977 
4978 	/* Delete the device immediately after the tablet goes out of prox.
4979 	 * This merely tests that the arbitration timer gets cleaned up */
4980 	litest_delete_device(finger);
4981 }
4982 END_TEST
4983 
START_TEST(touch_arbitration_stop_touch)4984 START_TEST(touch_arbitration_stop_touch)
4985 {
4986 	struct litest_device *dev = litest_current_device();
4987 	enum litest_device_type other;
4988 	struct litest_device *finger;
4989 	struct libinput *li = dev->libinput;
4990 	struct axis_replacement axes[] = {
4991 		{ ABS_DISTANCE, 10 },
4992 		{ ABS_PRESSURE, 0 },
4993 		{ -1, -1 }
4994 	};
4995 	bool is_touchpad;
4996 
4997 	other = paired_device(dev);
4998 	if (other == LITEST_NO_DEVICE)
4999 		return;
5000 
5001 	finger = litest_add_device(li, other);
5002 
5003 	is_touchpad = !libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT);
5004 
5005 	if (is_touchpad)
5006 		litest_disable_hold_gestures(finger->libinput_device);
5007 
5008 	/* disable prox-out timer quirk */
5009 	litest_tablet_proximity_in(dev, 30, 30, axes);
5010 	litest_tablet_proximity_out(dev);
5011 	litest_drain_events(li);
5012 
5013 	litest_touch_down(finger, 0, 30, 30);
5014 	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10);
5015 
5016 	litest_tablet_proximity_in(dev, 10, 10, axes);
5017 	litest_tablet_motion(dev, 10, 10, axes);
5018 	litest_tablet_motion(dev, 20, 40, axes);
5019 	litest_drain_events(li);
5020 
5021 	litest_touch_move_to(finger, 0, 80, 80, 30, 30, 10);
5022 	litest_assert_empty_queue(li);
5023 
5024 	/* tablet event so we don't time out for proximity */
5025 	litest_tablet_motion(dev, 30, 40, axes);
5026 	litest_drain_events(li);
5027 
5028 	/* start another finger to make sure that one doesn't send events
5029 	   either */
5030 	litest_touch_down(finger, 1, 30, 30);
5031 	litest_touch_move_to(finger, 1, 30, 30, 80, 80, 3);
5032 	litest_assert_empty_queue(li);
5033 
5034 	litest_tablet_motion(dev, 10, 10, axes);
5035 	litest_tablet_motion(dev, 20, 40, axes);
5036 	litest_assert_only_typed_events(li,
5037 					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
5038 	litest_tablet_proximity_out(dev);
5039 	litest_drain_events(li);
5040 
5041 	litest_timeout_tablet_proxout();
5042 	litest_drain_events(li);
5043 
5044 	/* Finger needs to be lifted for events to happen*/
5045 	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 3);
5046 	litest_assert_empty_queue(li);
5047 	litest_touch_move_to(finger, 1, 80, 80, 30, 30, 3);
5048 	litest_assert_empty_queue(li);
5049 	litest_touch_up(finger, 0);
5050 	litest_touch_move_to(finger, 1, 30, 30, 80, 80, 3);
5051 	litest_assert_empty_queue(li);
5052 	litest_touch_up(finger, 1);
5053 	libinput_dispatch(li);
5054 
5055 	litest_touch_down(finger, 0, 30, 30);
5056 	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 3);
5057 	litest_touch_up(finger, 0);
5058 	libinput_dispatch(li);
5059 
5060 	if (is_touchpad)
5061 		litest_assert_only_typed_events(li,
5062 						LIBINPUT_EVENT_POINTER_MOTION);
5063 	else
5064 		litest_assert_touch_sequence(li);
5065 
5066 	litest_delete_device(finger);
5067 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_REMOVED);
5068 }
5069 END_TEST
5070 
START_TEST(touch_arbitration_suspend_touch_device)5071 START_TEST(touch_arbitration_suspend_touch_device)
5072 {
5073 	struct litest_device *dev = litest_current_device();
5074 	enum litest_device_type other;
5075 	struct litest_device *tablet;
5076 	struct libinput *li = dev->libinput;
5077 	enum libinput_config_status status;
5078 	struct axis_replacement axes[] = {
5079 		{ ABS_DISTANCE, 10 },
5080 		{ ABS_PRESSURE, 0 },
5081 		{ -1, -1 }
5082 	};
5083 	bool is_touchpad;
5084 
5085 	other = paired_device(dev);
5086 	if (other == LITEST_NO_DEVICE)
5087 		return;
5088 
5089 	tablet = litest_add_device(li, other);
5090 
5091 	is_touchpad = !libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
5092 
5093 	if (is_touchpad)
5094 		litest_disable_hold_gestures(dev->libinput_device);
5095 
5096 	/* we can't force a device suspend, but we can at least make sure
5097 	   the device doesn't send events */
5098 	status = libinput_device_config_send_events_set_mode(
5099 			     dev->libinput_device,
5100 			     LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
5101 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
5102 
5103 	litest_drain_events(li);
5104 
5105 	litest_tablet_proximity_in(tablet, 10, 10, axes);
5106 	litest_tablet_motion(tablet, 10, 10, axes);
5107 	litest_tablet_motion(tablet, 20, 40, axes);
5108 	litest_drain_events(li);
5109 
5110 	litest_touch_down(dev, 0, 30, 30);
5111 	litest_touch_move_to(dev, 0, 30, 30, 80, 80, 10);
5112 	litest_touch_up(dev, 0);
5113 	litest_assert_empty_queue(li);
5114 
5115 	/* Remove tablet device to unpair, still disabled though */
5116 	litest_delete_device(tablet);
5117 	litest_assert_tablet_proximity_event(li,
5118 					     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
5119 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_REMOVED);
5120 
5121 	litest_timeout_touch_arbitration();
5122 	libinput_dispatch(li);
5123 
5124 	litest_touch_down(dev, 0, 30, 30);
5125 	litest_touch_move_to(dev, 0, 30, 30, 80, 80, 10);
5126 	litest_touch_up(dev, 0);
5127 	litest_assert_empty_queue(li);
5128 
5129 	/* Touch device is still disabled */
5130 	litest_touch_down(dev, 0, 30, 30);
5131 	litest_touch_move_to(dev, 0, 30, 30, 80, 80, 10);
5132 	litest_touch_up(dev, 0);
5133 	litest_assert_empty_queue(li);
5134 
5135 	status = libinput_device_config_send_events_set_mode(
5136 			     dev->libinput_device,
5137 			     LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
5138 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
5139 
5140 	litest_touch_down(dev, 0, 30, 30);
5141 	litest_touch_move_to(dev, 0, 30, 30, 80, 80, 10);
5142 	litest_touch_up(dev, 0);
5143 	libinput_dispatch(li);
5144 
5145 	if (is_touchpad)
5146 		litest_assert_only_typed_events(li,
5147 						LIBINPUT_EVENT_POINTER_MOTION);
5148 	else
5149 		litest_assert_touch_sequence(li);
5150 }
5151 END_TEST
5152 
START_TEST(touch_arbitration_remove_touch)5153 START_TEST(touch_arbitration_remove_touch)
5154 {
5155 	struct litest_device *dev = litest_current_device();
5156 	enum litest_device_type other;
5157 	struct litest_device *finger;
5158 	struct libinput *li = dev->libinput;
5159 	struct axis_replacement axes[] = {
5160 		{ ABS_DISTANCE, 10 },
5161 		{ ABS_PRESSURE, 0 },
5162 		{ -1, -1 }
5163 	};
5164 
5165 	other = paired_device(dev);
5166 	if (other == LITEST_NO_DEVICE)
5167 		return;
5168 
5169 	finger = litest_add_device(li, other);
5170 	litest_touch_down(finger, 0, 30, 30);
5171 	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10);
5172 
5173 	litest_tablet_proximity_in(dev, 10, 10, axes);
5174 	litest_drain_events(li);
5175 
5176 	litest_delete_device(finger);
5177 	libinput_dispatch(li);
5178 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_REMOVED);
5179 	litest_assert_empty_queue(li);
5180 
5181 	litest_tablet_motion(dev, 10, 10, axes);
5182 	litest_tablet_motion(dev, 20, 40, axes);
5183 	litest_assert_only_typed_events(li,
5184 					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
5185 }
5186 END_TEST
5187 
START_TEST(touch_arbitration_remove_tablet)5188 START_TEST(touch_arbitration_remove_tablet)
5189 {
5190 	struct litest_device *dev = litest_current_device();
5191 	enum litest_device_type other;
5192 	struct litest_device *tablet;
5193 	struct libinput *li = dev->libinput;
5194 	struct axis_replacement axes[] = {
5195 		{ ABS_DISTANCE, 10 },
5196 		{ ABS_PRESSURE, 0 },
5197 		{ -1, -1 }
5198 	};
5199 	bool is_touchpad;
5200 
5201 	other = paired_device(dev);
5202 	if (other == LITEST_NO_DEVICE)
5203 		return;
5204 
5205 	tablet = litest_add_device(li, other);
5206 
5207 	is_touchpad = !libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
5208 
5209 	if (is_touchpad)
5210 		litest_disable_hold_gestures(dev->libinput_device);
5211 
5212 	libinput_dispatch(li);
5213 	litest_tablet_proximity_in(tablet, 10, 10, axes);
5214 	litest_tablet_motion(tablet, 10, 10, axes);
5215 	litest_tablet_motion(tablet, 20, 40, axes);
5216 	litest_drain_events(li);
5217 
5218 	litest_touch_down(dev, 0, 30, 30);
5219 	litest_touch_move_to(dev, 0, 30, 30, 80, 80, 10);
5220 	litest_assert_empty_queue(li);
5221 
5222 	litest_delete_device(tablet);
5223 	litest_assert_tablet_proximity_event(li,
5224 			     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
5225 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_REMOVED);
5226 
5227 	litest_timeout_touch_arbitration();
5228 	libinput_dispatch(li);
5229 
5230 	/* Touch is still down, don't enable */
5231 	litest_touch_move_to(dev, 0, 80, 80, 30, 30, 10);
5232 	litest_touch_up(dev, 0);
5233 	litest_assert_empty_queue(li);
5234 
5235 	litest_touch_down(dev, 0, 30, 30);
5236 	litest_touch_move_to(dev, 0, 30, 30, 80, 80, 10);
5237 	litest_touch_up(dev, 0);
5238 	libinput_dispatch(li);
5239 
5240 	if (is_touchpad)
5241 		litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
5242 	else
5243 		litest_assert_touch_sequence(li);
5244 }
5245 END_TEST
5246 
START_TEST(touch_arbitration_keep_ignoring)5247 START_TEST(touch_arbitration_keep_ignoring)
5248 {
5249 	struct litest_device *tablet = litest_current_device();
5250 	enum litest_device_type other;
5251 	struct litest_device *finger;
5252 	struct libinput *li = tablet->libinput;
5253 	struct axis_replacement axes[] = {
5254 		{ ABS_DISTANCE, 10 },
5255 		{ ABS_PRESSURE, 0 },
5256 		{ -1, -1 }
5257 	};
5258 
5259 	other = paired_device(tablet);
5260 	if (other == LITEST_NO_DEVICE)
5261 		return;
5262 
5263 	finger = litest_add_device(li, other);
5264 	litest_tablet_proximity_in(tablet, 10, 10, axes);
5265 	litest_tablet_motion(tablet, 10, 10, axes);
5266 	litest_tablet_motion(tablet, 20, 40, axes);
5267 
5268 	litest_touch_down(finger, 0, 30, 30);
5269 	litest_drain_events(li);
5270 
5271 	litest_tablet_proximity_out(tablet);
5272 	litest_drain_events(li);
5273 
5274 	/* a touch during pen interaction stays a palm after the pen lifts.
5275 	 */
5276 	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10);
5277 	litest_touch_up(finger, 0);
5278 	libinput_dispatch(li);
5279 
5280 	litest_assert_empty_queue(li);
5281 
5282 	litest_delete_device(finger);
5283 }
5284 END_TEST
5285 
START_TEST(touch_arbitration_late_touch_lift)5286 START_TEST(touch_arbitration_late_touch_lift)
5287 {
5288 	struct litest_device *tablet = litest_current_device();
5289 	enum litest_device_type other;
5290 	struct litest_device *finger;
5291 	struct libinput *li = tablet->libinput;
5292 	struct axis_replacement axes[] = {
5293 		{ ABS_DISTANCE, 10 },
5294 		{ ABS_PRESSURE, 0 },
5295 		{ -1, -1 }
5296 	};
5297 	bool is_touchpad;
5298 
5299 	other = paired_device(tablet);
5300 	if (other == LITEST_NO_DEVICE)
5301 		return;
5302 
5303 	finger = litest_add_device(li, other);
5304 	is_touchpad = !libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT);
5305 	if (is_touchpad) {
5306 		litest_enable_tap(finger->libinput_device);
5307 		litest_disable_hold_gestures(finger->libinput_device);
5308 	}
5309 
5310 	litest_tablet_proximity_in(tablet, 10, 10, axes);
5311 	litest_tablet_motion(tablet, 10, 10, axes);
5312 	litest_tablet_motion(tablet, 20, 40, axes);
5313 	litest_drain_events(li);
5314 
5315 	litest_tablet_proximity_out(tablet);
5316 	litest_drain_events(li);
5317 
5318 	/* with kernel arbitration, a finger + stylus in prox only generates
5319 	 * stylus events. When a user lifts the hand with the stylus, the
5320 	 * stylus usually goes out of prox while the hand is still touching
5321 	 * the surface. This causes a touch down event now that the stylus
5322 	 * is out of proximity. A few ms later, the hand really lifts off
5323 	 * the surface, causing a touch down and thus a fake tap event.
5324 	 */
5325 	litest_touch_down(finger, 0, 30, 30);
5326 	litest_touch_up(finger, 0);
5327 	libinput_dispatch(li);
5328 	litest_timeout_tap();
5329 	libinput_dispatch(li);
5330 
5331 	litest_assert_empty_queue(li);
5332 
5333 	litest_delete_device(finger);
5334 }
5335 END_TEST
5336 
5337 static void
verify_left_handed_tablet_motion(struct litest_device * tablet,struct libinput * li,int x,int y,bool left_handed)5338 verify_left_handed_tablet_motion(struct litest_device *tablet,
5339 				 struct libinput *li,
5340 				 int x, int y,
5341 				 bool left_handed)
5342 {
5343 	struct libinput_event *event;
5344 	struct libinput_event_tablet_tool *t;
5345 
5346 	/* proximity in/out must be handled by caller */
5347 
5348 	for (int i = 5; i < 25; i += 5) {
5349 		litest_tablet_motion(tablet, x + i, y - i, NULL);
5350 		libinput_dispatch(li);
5351 	}
5352 
5353 	event = libinput_get_event(li);
5354 	t = litest_is_tablet_event(event,
5355 				   LIBINPUT_EVENT_TABLET_TOOL_AXIS);
5356 	x = libinput_event_tablet_tool_get_x(t);
5357 	y = libinput_event_tablet_tool_get_y(t);
5358 	libinput_event_destroy(event);
5359 
5360 	event = libinput_get_event(li);
5361 	litest_assert_ptr_notnull(event);
5362 
5363 	while (event) {
5364 		double last_x = x, last_y = y;
5365 
5366 		t = litest_is_tablet_event(event,
5367 					   LIBINPUT_EVENT_TABLET_TOOL_AXIS);
5368 		x = libinput_event_tablet_tool_get_x(t);
5369 		y = libinput_event_tablet_tool_get_y(t);
5370 
5371 		if (left_handed) {
5372 			litest_assert_double_lt(x, last_x);
5373 			litest_assert_double_gt(y, last_y);
5374 		} else {
5375 			litest_assert_double_gt(x, last_x);
5376 			litest_assert_double_lt(y, last_y);
5377 		}
5378 
5379 		libinput_event_destroy(event);
5380 		event = libinput_get_event(li);
5381 	}
5382 }
5383 
5384 static void
verify_left_handed_tablet_sequence(struct litest_device * tablet,struct libinput * li,bool left_handed)5385 verify_left_handed_tablet_sequence(struct litest_device *tablet,
5386 				   struct libinput *li,
5387 				   bool left_handed)
5388 {
5389 	double x, y;
5390 
5391 	/* verifies a whole sequence, including prox in/out and timeouts */
5392 	x = 60;
5393 	y = 60;
5394 	litest_tablet_proximity_in(tablet, x, y, NULL);
5395 	libinput_dispatch(li);
5396 	litest_drain_events(li);
5397 	verify_left_handed_tablet_motion(tablet, li, x, y, left_handed);
5398 	litest_tablet_proximity_out(tablet);
5399 	libinput_dispatch(li);
5400 	litest_timeout_tablet_proxout();
5401 	litest_drain_events(li);
5402 }
5403 
5404 static void
verify_left_handed_touch_motion(struct litest_device * finger,struct libinput * li,double x,double y,bool left_handed)5405 verify_left_handed_touch_motion(struct litest_device *finger,
5406 				struct libinput *li,
5407 				double x, double y,
5408 				bool left_handed)
5409 {
5410 	struct libinput_event *event;
5411 	struct libinput_event_pointer *p;
5412 
5413 	/* touch down/up must be handled by caller */
5414 
5415 	litest_touch_move_to(finger, 0, x + 1, y - 1, x + 20, y - 20, 10);
5416 	libinput_dispatch(li);
5417 
5418 	event = libinput_get_event(li);
5419 	ck_assert_notnull(event);
5420 
5421 	while (event) {
5422 		p = litest_is_motion_event(event);
5423 		x = libinput_event_pointer_get_dx(p);
5424 		y = libinput_event_pointer_get_dy(p);
5425 
5426 		if (left_handed) {
5427 			litest_assert_double_lt(x, 0);
5428 			litest_assert_double_gt(y, 0);
5429 		} else {
5430 			litest_assert_double_gt(x, 0);
5431 			litest_assert_double_lt(y, 0);
5432 		}
5433 
5434 		libinput_event_destroy(event);
5435 		event = libinput_get_event(li);
5436 	}
5437 }
5438 
5439 static void
verify_left_handed_touch_sequence(struct litest_device * finger,struct libinput * li,bool left_handed)5440 verify_left_handed_touch_sequence(struct litest_device *finger,
5441 				  struct libinput *li,
5442 				  bool left_handed)
5443 {
5444 	double x, y;
5445 
5446 	/* verifies a whole sequence, including prox in/out and timeouts */
5447 
5448 	x = 10;
5449 	y = 30;
5450 	litest_touch_down(finger, 0, x, y);
5451 	litest_drain_events(li);
5452 	verify_left_handed_touch_motion(finger, li, x, y, left_handed);
5453 	litest_touch_up(finger, 0);
5454 	libinput_dispatch(li);
5455 }
5456 
START_TEST(tablet_rotation_left_handed)5457 START_TEST(tablet_rotation_left_handed)
5458 {
5459 #if HAVE_LIBWACOM
5460 	struct litest_device *tablet = litest_current_device();
5461 	enum litest_device_type other;
5462 	struct litest_device *finger;
5463 	struct libinput *li = tablet->libinput;
5464 	unsigned int transition = _i; /* ranged test */
5465 	bool tablet_from, touch_from, tablet_to, touch_to;
5466 	bool enabled_from, enabled_to;
5467 
5468 	other = paired_device(tablet);
5469 	if (other == LITEST_NO_DEVICE)
5470 		return;
5471 
5472 	finger = litest_add_device(li, other);
5473 	litest_drain_events(li);
5474 
5475 	if (libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT))
5476 		goto out;
5477 
5478 	tablet_from = !!(transition & bit(0));
5479 	touch_from  = !!(transition & bit(1));
5480 	tablet_to   = !!(transition & bit(2));
5481 	touch_to    = !!(transition & bit(3));
5482 
5483 	enabled_from = tablet_from || touch_from;
5484 	enabled_to   = tablet_to   || touch_to;
5485 
5486 	libinput_device_config_left_handed_set(tablet->libinput_device,
5487 					       tablet_from);
5488 	libinput_device_config_left_handed_set(finger->libinput_device,
5489 					       touch_from);
5490 	verify_left_handed_tablet_sequence(tablet, li, enabled_from);
5491 	verify_left_handed_touch_sequence(finger, li, enabled_from);
5492 
5493 	libinput_device_config_left_handed_set(tablet->libinput_device,
5494 					       tablet_to);
5495 	libinput_device_config_left_handed_set(finger->libinput_device,
5496 					       touch_to);
5497 	verify_left_handed_tablet_sequence(tablet, li, enabled_to);
5498 	verify_left_handed_touch_sequence(finger, li, enabled_to);
5499 
5500 out:
5501 	litest_delete_device(finger);
5502 #endif
5503 }
5504 END_TEST
5505 
START_TEST(tablet_rotation_left_handed_configuration)5506 START_TEST(tablet_rotation_left_handed_configuration)
5507 {
5508 #if HAVE_LIBWACOM
5509 	struct litest_device *tablet = litest_current_device();
5510 	enum litest_device_type other;
5511 	struct litest_device *finger;
5512 	struct libinput *li = tablet->libinput;
5513 	unsigned int transition = _i; /* ranged test */
5514 	bool tablet_from, touch_from, tablet_to, touch_to;
5515 	bool tablet_enabled, touch_enabled;
5516 	struct libinput_device *tablet_dev, *touch_dev;
5517 
5518 	other = paired_device(tablet);
5519 	if (other == LITEST_NO_DEVICE)
5520 		return;
5521 
5522 	finger = litest_add_device(li, other);
5523 	litest_drain_events(li);
5524 
5525 	if (libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT))
5526 		goto out;
5527 
5528 	tablet_from = !!(transition & bit(0));
5529 	touch_from  = !!(transition & bit(1));
5530 	tablet_to   = !!(transition & bit(2));
5531 	touch_to    = !!(transition & bit(3));
5532 
5533 	tablet_dev = tablet->libinput_device;
5534 	touch_dev = finger->libinput_device;
5535 
5536 	/* Make sure that toggling one device doesn't toggle the other one */
5537 
5538 	libinput_device_config_left_handed_set(tablet_dev, tablet_from);
5539 	libinput_device_config_left_handed_set(touch_dev, touch_from);
5540 	libinput_dispatch(li);
5541 	tablet_enabled = libinput_device_config_left_handed_get(tablet_dev);
5542 	touch_enabled = libinput_device_config_left_handed_get(touch_dev);
5543 	ck_assert_int_eq(tablet_enabled, tablet_from);
5544 	ck_assert_int_eq(touch_enabled, touch_from);
5545 
5546 	libinput_device_config_left_handed_set(tablet_dev, tablet_to);
5547 	libinput_device_config_left_handed_set(touch_dev, touch_to);
5548 	libinput_dispatch(li);
5549 	tablet_enabled = libinput_device_config_left_handed_get(tablet_dev);
5550 	touch_enabled = libinput_device_config_left_handed_get(touch_dev);
5551 	ck_assert_int_eq(tablet_enabled, tablet_to);
5552 	ck_assert_int_eq(touch_enabled, touch_to);
5553 
5554 out:
5555 	litest_delete_device(finger);
5556 #endif
5557 }
5558 END_TEST
5559 
START_TEST(tablet_rotation_left_handed_while_in_prox)5560 START_TEST(tablet_rotation_left_handed_while_in_prox)
5561 {
5562 #if HAVE_LIBWACOM
5563 	struct litest_device *tablet = litest_current_device();
5564 	enum litest_device_type other;
5565 	struct litest_device *finger;
5566 	struct libinput *li = tablet->libinput;
5567 	unsigned int transition = _i; /* ranged test */
5568 	bool tablet_from, touch_from, tablet_to, touch_to;
5569 	bool enabled_from, enabled_to;
5570 	double x, y;
5571 	double tx, ty;
5572 
5573 	other = paired_device(tablet);
5574 	if (other == LITEST_NO_DEVICE)
5575 		return;
5576 
5577 	finger = litest_add_device(li, other);
5578 	litest_drain_events(li);
5579 
5580 	if (libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT))
5581 		goto out;
5582 
5583 	tablet_from = !!(transition & bit(0));
5584 	touch_from  = !!(transition & bit(1));
5585 	tablet_to   = !!(transition & bit(2));
5586 	touch_to    = !!(transition & bit(3));
5587 
5588 	enabled_from = tablet_from || touch_from;
5589 	enabled_to   = tablet_to   || touch_to;
5590 
5591 	libinput_device_config_left_handed_set(finger->libinput_device,
5592 					       touch_from);
5593 	libinput_device_config_left_handed_set(tablet->libinput_device,
5594 					       tablet_from);
5595 
5596 
5597 	/* Tablet in-prox when setting to left-handed */
5598 	tx = 60;
5599 	ty = 60;
5600 	litest_tablet_proximity_in(tablet, tx, ty, NULL);
5601 	libinput_dispatch(li);
5602 	litest_drain_events(li);
5603 
5604 	libinput_device_config_left_handed_set(tablet->libinput_device,
5605 					       tablet_to);
5606 	libinput_device_config_left_handed_set(finger->libinput_device,
5607 					       touch_to);
5608 
5609 	/* not yet neutral, so still whatever the original was */
5610 	verify_left_handed_tablet_motion(tablet, li, tx, ty, enabled_from);
5611 	litest_drain_events(li);
5612 
5613 	/* test pointer, should be left-handed already */
5614 #if 0
5615 	/* Touch arbitration discards events, so we can't check for the
5616 	   right behaviour here. */
5617 	verify_left_handed_touch_sequence(finger, li, enabled_to);
5618 #else
5619 	x = 10;
5620 	y = 30;
5621 	litest_touch_down(finger, 0, x, y);
5622 
5623 	/* We need to intersperce the touch events with tablets so we don't
5624 	   trigger the tablet proximity timeout. */
5625 	for (int i = 0; i < 10; i++) {
5626 		litest_touch_move(finger, 0, x + i, y - i);
5627 		litest_tablet_motion(tablet,
5628 				     tx + 0.1 * i, ty + 0.1 * i,
5629 				     NULL);
5630 	}
5631 
5632 	litest_touch_up(finger, 0);
5633 	libinput_dispatch(li);
5634 	/* this will fail once we have location-based touch arbitration on
5635 	 * touchpads */
5636 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
5637 #endif
5638 	litest_tablet_proximity_out(tablet);
5639 	libinput_dispatch(li);
5640 	litest_timeout_tablet_proxout();
5641 	litest_drain_events(li);
5642 
5643 	/* now both should've switched */
5644 	verify_left_handed_tablet_sequence(tablet, li, enabled_to);
5645 	verify_left_handed_touch_sequence(finger, li, enabled_to);
5646 
5647 out:
5648 	litest_delete_device(finger);
5649 #endif
5650 }
5651 END_TEST
5652 
START_TEST(tablet_rotation_left_handed_while_touch_down)5653 START_TEST(tablet_rotation_left_handed_while_touch_down)
5654 {
5655 #if HAVE_LIBWACOM
5656 	struct litest_device *tablet = litest_current_device();
5657 	enum litest_device_type other;
5658 	struct litest_device *finger;
5659 	struct libinput *li = tablet->libinput;
5660 	unsigned int transition = _i; /* ranged test */
5661 	bool tablet_from, touch_from, tablet_to, touch_to;
5662 	bool enabled_from, enabled_to;
5663 
5664 	double x, y;
5665 
5666 	other = paired_device(tablet);
5667 	if (other == LITEST_NO_DEVICE)
5668 		return;
5669 
5670 	finger = litest_add_device(li, other);
5671 	litest_drain_events(li);
5672 
5673 	if (libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT))
5674 		goto out;
5675 
5676 	tablet_from = !!(transition & bit(0));
5677 	touch_from  = !!(transition & bit(1));
5678 	tablet_to   = !!(transition & bit(2));
5679 	touch_to    = !!(transition & bit(3));
5680 
5681 	enabled_from = tablet_from || touch_from;
5682 	enabled_to   = tablet_to   || touch_to;
5683 
5684 	libinput_device_config_left_handed_set(finger->libinput_device,
5685 					       touch_from);
5686 	libinput_device_config_left_handed_set(tablet->libinput_device,
5687 					       tablet_from);
5688 
5689 	/* Touch down when setting to left-handed */
5690 	x = 10;
5691 	y = 30;
5692 	litest_touch_down(finger, 0, x, y);
5693 	libinput_dispatch(li);
5694 	litest_drain_events(li);
5695 
5696 	libinput_device_config_left_handed_set(tablet->libinput_device,
5697 					       tablet_to);
5698 	libinput_device_config_left_handed_set(finger->libinput_device,
5699 					       touch_to);
5700 
5701 	/* not yet neutral, so still whatever the original was */
5702 	verify_left_handed_touch_motion(finger, li, x, y, enabled_from);
5703 	litest_assert_empty_queue(li);
5704 
5705 	/* test tablet, should be left-handed already */
5706 	verify_left_handed_tablet_sequence(tablet, li, enabled_to);
5707 
5708 	litest_touch_up(finger, 0);
5709 	litest_drain_events(li);
5710 
5711 	/* now both should've switched */
5712 	verify_left_handed_tablet_sequence(tablet, li, enabled_to);
5713 	verify_left_handed_touch_sequence(finger, li, enabled_to);
5714 
5715 out:
5716 	litest_delete_device(finger);
5717 #endif
5718 }
5719 END_TEST
5720 
START_TEST(tablet_rotation_left_handed_add_touchpad)5721 START_TEST(tablet_rotation_left_handed_add_touchpad)
5722 {
5723 #if HAVE_LIBWACOM
5724 	struct litest_device *tablet = litest_current_device();
5725 	enum litest_device_type other;
5726 	struct litest_device *finger;
5727 	struct libinput *li = tablet->libinput;
5728 	unsigned int transition = _i; /* ranged test */
5729 	bool tablet_from, touch_from, tablet_to, touch_to;
5730 	bool enabled_from, enabled_to;
5731 
5732 	other = paired_device(tablet);
5733 	if (other == LITEST_NO_DEVICE)
5734 		return;
5735 
5736 	tablet_from = !!(transition & bit(0));
5737 	touch_from  = !!(transition & bit(1));
5738 	tablet_to   = !!(transition & bit(2));
5739 	touch_to    = !!(transition & bit(3));
5740 
5741 	enabled_from = tablet_from || touch_from;
5742 	enabled_to   = tablet_to   || touch_to;
5743 
5744 	/* change left-handed before touchpad appears */
5745 
5746 	libinput_device_config_left_handed_set(tablet->libinput_device,
5747 					       tablet_from);
5748 
5749 	finger = litest_add_device(li, other);
5750 	litest_drain_events(li);
5751 
5752 	if (libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT))
5753 		goto out;
5754 
5755 	libinput_device_config_left_handed_set(finger->libinput_device,
5756 					       touch_from);
5757 	litest_disable_hold_gestures(finger->libinput_device);
5758 
5759 	verify_left_handed_touch_sequence(finger, li, enabled_from);
5760 	verify_left_handed_tablet_sequence(tablet, li, enabled_from);
5761 
5762 	libinput_device_config_left_handed_set(tablet->libinput_device,
5763 					       tablet_to);
5764 	libinput_device_config_left_handed_set(finger->libinput_device,
5765 					       touch_to);
5766 
5767 	verify_left_handed_touch_sequence(finger, li, enabled_to);
5768 	verify_left_handed_tablet_sequence(tablet, li, enabled_to);
5769 
5770 out:
5771 	litest_delete_device(finger);
5772 #endif
5773 }
5774 END_TEST
5775 
START_TEST(tablet_rotation_left_handed_add_tablet)5776 START_TEST(tablet_rotation_left_handed_add_tablet)
5777 {
5778 #if HAVE_LIBWACOM
5779 	struct litest_device *finger = litest_current_device();
5780 	enum litest_device_type other;
5781 	struct litest_device *tablet;
5782 	struct libinput *li = finger->libinput;
5783 	unsigned int transition = _i; /* ranged test */
5784 	bool tablet_from, touch_from, tablet_to, touch_to;
5785 	bool enabled_from, enabled_to;
5786 
5787 	if (libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT))
5788 		return;
5789 
5790 	other = paired_device(finger);
5791 	if (other == LITEST_NO_DEVICE)
5792 		return;
5793 
5794 	tablet_from = !!(transition & bit(0));
5795 	touch_from  = !!(transition & bit(1));
5796 	tablet_to   = !!(transition & bit(2));
5797 	touch_to    = !!(transition & bit(3));
5798 
5799 	enabled_from = tablet_from || touch_from;
5800 	enabled_to   = tablet_to   || touch_to;
5801 
5802 	/* change left-handed before tablet appears */
5803 	libinput_device_config_left_handed_set(finger->libinput_device,
5804 					       touch_from);
5805 	litest_disable_hold_gestures(finger->libinput_device);
5806 
5807 	tablet = litest_add_device(li, other);
5808 	litest_drain_events(li);
5809 
5810 	libinput_device_config_left_handed_set(tablet->libinput_device,
5811 					       tablet_from);
5812 
5813 	verify_left_handed_touch_sequence(finger, li, enabled_from);
5814 	verify_left_handed_tablet_sequence(tablet, li, enabled_from);
5815 
5816 	libinput_device_config_left_handed_set(tablet->libinput_device,
5817 					       tablet_to);
5818 	libinput_device_config_left_handed_set(finger->libinput_device,
5819 					       touch_to);
5820 
5821 	verify_left_handed_touch_sequence(finger, li, enabled_to);
5822 	verify_left_handed_tablet_sequence(tablet, li, enabled_to);
5823 
5824 	litest_delete_device(tablet);
5825 #endif
5826 }
5827 END_TEST
5828 
START_TEST(huion_static_btn_tool_pen)5829 START_TEST(huion_static_btn_tool_pen)
5830 {
5831 	struct litest_device *dev = litest_current_device();
5832 	struct libinput *li = dev->libinput;
5833 	int i;
5834 
5835 	litest_drain_events(li);
5836 
5837 	litest_event(dev, EV_ABS, ABS_X, 20000);
5838 	litest_event(dev, EV_ABS, ABS_Y, 20000);
5839 	litest_event(dev, EV_ABS, ABS_PRESSURE, 100);
5840 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
5841 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
5842 	litest_drain_events(li);
5843 
5844 	for (i = 0; i < 10; i++) {
5845 		litest_event(dev, EV_ABS, ABS_X, 20000 + 10 * i);
5846 		litest_event(dev, EV_ABS, ABS_Y, 20000 - 10 * i);
5847 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
5848 		libinput_dispatch(li);
5849 	}
5850 	litest_assert_only_typed_events(li,
5851 					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
5852 
5853 	/* Wait past the timeout to expect a proximity out */
5854 	litest_timeout_tablet_proxout();
5855 	libinput_dispatch(li);
5856 	litest_assert_tablet_proximity_event(li,
5857 			     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
5858 	libinput_dispatch(li);
5859 
5860 	/* New events should fake a proximity in again */
5861 	litest_event(dev, EV_ABS, ABS_X, 20000);
5862 	litest_event(dev, EV_ABS, ABS_Y, 20000);
5863 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
5864 	libinput_dispatch(li);
5865 	litest_assert_tablet_proximity_event(li,
5866 			     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
5867 	libinput_dispatch(li);
5868 
5869 	for (i = 0; i < 10; i++) {
5870 		litest_event(dev, EV_ABS, ABS_X, 20000 + 10 * i);
5871 		litest_event(dev, EV_ABS, ABS_Y, 20000 - 10 * i);
5872 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
5873 		libinput_dispatch(li);
5874 	}
5875 	litest_assert_only_typed_events(li,
5876 					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
5877 	litest_timeout_tablet_proxout();
5878 	libinput_dispatch(li);
5879 	litest_assert_tablet_proximity_event(li,
5880 			     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
5881 	libinput_dispatch(li);
5882 
5883 	/* New events, just to ensure cleanup paths are correct */
5884 	litest_event(dev, EV_ABS, ABS_X, 20000);
5885 	litest_event(dev, EV_ABS, ABS_Y, 20000);
5886 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
5887 	libinput_dispatch(li);
5888 }
5889 END_TEST
5890 
START_TEST(huion_static_btn_tool_pen_no_timeout_during_usage)5891 START_TEST(huion_static_btn_tool_pen_no_timeout_during_usage)
5892 {
5893 	struct litest_device *dev = litest_current_device();
5894 	struct libinput *li = dev->libinput;
5895 	int i;
5896 
5897 	litest_drain_events(li);
5898 
5899 	litest_event(dev, EV_ABS, ABS_X, 20000);
5900 	litest_event(dev, EV_ABS, ABS_Y, 20000);
5901 	litest_event(dev, EV_ABS, ABS_PRESSURE, 100);
5902 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
5903 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
5904 	litest_drain_events(li);
5905 
5906 	/* take longer than the no-activity timeout */
5907 	for (i = 0; i < 50; i++) {
5908 		litest_event(dev, EV_ABS, ABS_X, 20000 + 10 * i);
5909 		litest_event(dev, EV_ABS, ABS_Y, 20000 - 10 * i);
5910 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
5911 		libinput_dispatch(li);
5912 		msleep(5);
5913 	}
5914 	litest_assert_only_typed_events(li,
5915 					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
5916 	litest_timeout_tablet_proxout();
5917 	libinput_dispatch(li);
5918 	litest_assert_tablet_proximity_event(li,
5919 			     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
5920 	libinput_dispatch(li);
5921 }
5922 END_TEST
5923 
START_TEST(huion_static_btn_tool_pen_disable_quirk_on_prox_out)5924 START_TEST(huion_static_btn_tool_pen_disable_quirk_on_prox_out)
5925 {
5926 	struct litest_device *dev = litest_current_device();
5927 	struct libinput *li = dev->libinput;
5928 	bool with_timeout = _i; /* ranged test */
5929 	int i;
5930 
5931 	/* test is run twice, once where the real BTN_TOOL_PEN is triggered
5932 	 * during proximity out, one where the real BTN_TOOL_PEN is
5933 	 * triggered after we already triggered the quirk timeout
5934 	 */
5935 
5936 	litest_drain_events(li);
5937 
5938 	litest_event(dev, EV_ABS, ABS_X, 20000);
5939 	litest_event(dev, EV_ABS, ABS_Y, 20000);
5940 	litest_event(dev, EV_ABS, ABS_PRESSURE, 100);
5941 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
5942 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
5943 	litest_drain_events(li);
5944 
5945 	for (i = 0; i < 10; i++) {
5946 		litest_event(dev, EV_ABS, ABS_X, 20000 + 10 * i);
5947 		litest_event(dev, EV_ABS, ABS_Y, 20000 - 10 * i);
5948 		litest_event(dev, EV_SYN, SYN_REPORT, 0);
5949 		libinput_dispatch(li);
5950 	}
5951 	litest_assert_only_typed_events(li,
5952 					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
5953 
5954 	/* Wait past the timeout to expect a proximity out */
5955 	if (with_timeout) {
5956 		litest_timeout_tablet_proxout();
5957 		libinput_dispatch(li);
5958 		litest_assert_tablet_proximity_event(li,
5959 						     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
5960 	}
5961 
5962 	/* Send a real prox out, expect quirk to be disabled */
5963 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
5964 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
5965 	libinput_dispatch(li);
5966 
5967 	if (with_timeout) {
5968 		/* we got the proximity event above already */
5969 		litest_assert_empty_queue(li);
5970 	} else {
5971 		litest_assert_tablet_proximity_event(li,
5972 						     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
5973 	}
5974 
5975 	litest_tablet_proximity_in(dev, 50, 50, NULL);
5976 	libinput_dispatch(li);
5977 	litest_assert_tablet_proximity_event(li,
5978 			     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
5979 
5980 	for (i = 0; i < 10; i++) {
5981 		litest_tablet_motion(dev, 50 + i, 50 + i, NULL);
5982 		libinput_dispatch(li);
5983 	}
5984 
5985 	litest_assert_only_typed_events(li,
5986 					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
5987 
5988 	libinput_dispatch(li);
5989 	litest_timeout_tablet_proxout();
5990 	libinput_dispatch(li);
5991 
5992 	litest_assert_empty_queue(li);
5993 
5994 	litest_push_event_frame(dev);
5995 	litest_tablet_proximity_out(dev);
5996 	litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
5997 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
5998 	litest_pop_event_frame(dev);
5999 	libinput_dispatch(li);
6000 
6001 	litest_assert_tablet_proximity_event(li,
6002 			     LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
6003 	litest_assert_empty_queue(li);
6004 }
6005 END_TEST
6006 
START_TEST(tablet_smoothing)6007 START_TEST(tablet_smoothing)
6008 {
6009 #if HAVE_LIBWACOM
6010 	struct litest_device *dev = litest_current_device();
6011 	struct libinput *li = dev->libinput;
6012 	double x, y;
6013 	struct point {
6014 		double x, y;
6015 	} coordinates[100] = {0};
6016 	size_t npoints = 0;
6017 	size_t idx = 0;
6018 	struct axis_replacement axes[] = {
6019 		{ ABS_DISTANCE, 10 },
6020 		{ ABS_PRESSURE, 0 },
6021 		{ -1, -1 }
6022 	};
6023 
6024 	litest_drain_events(li);
6025 
6026 	litest_tablet_proximity_in(dev, 10, 10, axes);
6027 	libinput_dispatch(li);
6028 	litest_drain_events(li);
6029 
6030 	/* Move in a straight line, collect the resulting points */
6031 	for (x = 11, y = 11; x < 50; x++, y++) {
6032 		struct libinput_event *event;
6033 		struct libinput_event_tablet_tool *tev;
6034 		struct point *p = &coordinates[npoints++];
6035 
6036 		litest_assert(npoints <= ARRAY_LENGTH(coordinates));
6037 
6038 		litest_tablet_motion(dev, x, y, axes);
6039 		libinput_dispatch(li);
6040 
6041 		event = libinput_get_event(li);
6042 		tev = litest_is_tablet_event(event,
6043 					     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
6044 		p->x = libinput_event_tablet_tool_get_x(tev);
6045 		p->y = libinput_event_tablet_tool_get_y(tev);
6046 
6047 		libinput_event_destroy(event);
6048 	}
6049 
6050 	litest_tablet_proximity_out(dev);
6051 	litest_tablet_proximity_in(dev, 10, 10, axes);
6052 	libinput_dispatch(li);
6053 	litest_drain_events(li);
6054 
6055 	/* Move in a wobbly line, collect every second point */
6056 	for (x = 11, y = 11; x < 50; x++, y++) {
6057 		struct libinput_event *event;
6058 		struct libinput_event_tablet_tool *tev;
6059 		double ex, ey;
6060 		struct point *p = &coordinates[idx++];
6061 
6062 		litest_assert(idx <= npoints);
6063 
6064 		/* point off position */
6065 		litest_tablet_motion(dev, x - 2, y + 1, axes);
6066 		libinput_dispatch(li);
6067 		event = libinput_get_event(li);
6068 		litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
6069 		libinput_event_destroy(event);
6070 
6071 		/* same position as before */
6072 		litest_tablet_motion(dev, x, y, axes);
6073 		libinput_dispatch(li);
6074 		event = libinput_get_event(li);
6075 		tev = litest_is_tablet_event(event,
6076 					     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
6077 		ex = libinput_event_tablet_tool_get_x(tev);
6078 		ey = libinput_event_tablet_tool_get_y(tev);
6079 
6080 		ck_assert_double_eq(ex, p->x);
6081 		ck_assert_double_eq(ey, p->y);
6082 
6083 		libinput_event_destroy(event);
6084 	}
6085 #endif
6086 }
6087 END_TEST
6088 
TEST_COLLECTION(tablet)6089 TEST_COLLECTION(tablet)
6090 {
6091 	struct range with_timeout = { 0, 2 };
6092 	struct range xyaxes = { ABS_X, ABS_Y + 1 };
6093 	struct range lh_transitions = {0, 16}; /* 2 bits for in, 2 bits for out */
6094 
6095 	litest_add(tool_ref, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
6096 	litest_add(tool_user_data, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
6097 	litest_add(tool_capability, LITEST_TABLET, LITEST_ANY);
6098 	litest_add_no_device(tool_capabilities);
6099 	litest_add(tool_type, LITEST_TABLET, LITEST_FORCED_PROXOUT);
6100 	litest_add(tool_in_prox_before_start, LITEST_TABLET, LITEST_TOTEM);
6101 	litest_add(tool_direct_switch_skip_tool_update, LITEST_TABLET, LITEST_ANY);
6102 	litest_add(tool_direct_switch_with_forced_proxout, LITEST_TABLET, LITEST_ANY);
6103 
6104 	/* Tablets hold back the proximity until the first event from the
6105 	 * kernel, the totem sends it immediately */
6106 	litest_add(tool_in_prox_before_start, LITEST_TABLET, LITEST_TOTEM);
6107 	litest_add(tool_unique, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
6108 	litest_add(tool_serial, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
6109 	litest_add(tool_id, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
6110 	litest_add(serial_changes_tool, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
6111 	litest_add(invalid_serials, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
6112 	litest_add_no_device(tools_with_serials);
6113 	litest_add_no_device(tools_without_serials);
6114 	litest_add_for_device(tool_delayed_serial, LITEST_WACOM_HID4800_PEN);
6115 	litest_add(proximity_out_clear_buttons, LITEST_TABLET, LITEST_FORCED_PROXOUT);
6116 	litest_add(proximity_in_out, LITEST_TABLET, LITEST_ANY);
6117 	litest_add(proximity_in_button_down, LITEST_TABLET, LITEST_ANY);
6118 	litest_add(proximity_out_button_up, LITEST_TABLET, LITEST_ANY);
6119 	litest_add(proximity_has_axes, LITEST_TABLET, LITEST_ANY);
6120 	litest_add(bad_distance_events, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY);
6121 	litest_add(proximity_range_enter, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
6122 	litest_add(proximity_range_in_out, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
6123 	litest_add(proximity_range_button_click, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
6124 	litest_add(proximity_range_button_press, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
6125 	litest_add(proximity_range_button_release, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
6126 	litest_add(proximity_out_slow_event, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY);
6127 	litest_add(proximity_out_not_during_contact, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY);
6128 	litest_add(proximity_out_not_during_buttonpress, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY);
6129 	litest_add(proximity_out_disables_forced, LITEST_TABLET, LITEST_FORCED_PROXOUT|LITEST_TOTEM);
6130 	litest_add(proximity_out_disables_forced_after_forced, LITEST_TABLET, LITEST_FORCED_PROXOUT|LITEST_TOTEM);
6131 	litest_add_no_device(proximity_out_on_delete);
6132 	litest_add(button_down_up, LITEST_TABLET, LITEST_ANY);
6133 	litest_add(button_seat_count, LITEST_TABLET, LITEST_ANY);
6134 	litest_add_no_device(button_up_on_delete);
6135 	litest_add(tip_down_up, LITEST_TABLET|LITEST_HOVER, LITEST_ANY);
6136 	litest_add(tip_down_prox_in, LITEST_TABLET, LITEST_ANY);
6137 	litest_add(tip_up_prox_out, LITEST_TABLET, LITEST_ANY);
6138 	litest_add(tip_down_btn_change, LITEST_TABLET|LITEST_HOVER, LITEST_ANY);
6139 	litest_add(tip_up_btn_change, LITEST_TABLET|LITEST_HOVER, LITEST_ANY);
6140 	litest_add(tip_down_motion, LITEST_TABLET|LITEST_HOVER, LITEST_ANY);
6141 	litest_add(tip_up_motion, LITEST_TABLET|LITEST_HOVER, LITEST_ANY);
6142 	litest_add_ranged(tip_up_motion_one_axis, LITEST_TABLET|LITEST_HOVER, LITEST_ANY, &xyaxes);
6143 	litest_add(tip_state_proximity, LITEST_TABLET|LITEST_HOVER, LITEST_ANY);
6144 	litest_add(tip_state_axis, LITEST_TABLET|LITEST_HOVER, LITEST_ANY);
6145 	litest_add(tip_state_button, LITEST_TABLET|LITEST_HOVER, LITEST_ANY);
6146 	litest_add_no_device(tip_up_on_delete);
6147 	litest_add(motion, LITEST_TABLET, LITEST_ANY);
6148 	litest_add(motion_event_state, LITEST_TABLET, LITEST_ANY);
6149 	litest_add_for_device(motion_outside_bounds, LITEST_WACOM_CINTIQ_24HD);
6150 	litest_add(tilt_available, LITEST_TABLET|LITEST_TILT, LITEST_ANY);
6151 	litest_add(tilt_not_available, LITEST_TABLET, LITEST_TILT);
6152 	litest_add(tilt_x, LITEST_TABLET|LITEST_TILT, LITEST_ANY);
6153 	litest_add(tilt_y, LITEST_TABLET|LITEST_TILT, LITEST_ANY);
6154 	litest_add_for_device(left_handed, LITEST_WACOM_INTUOS);
6155 	litest_add_for_device(left_handed_tilt, LITEST_WACOM_INTUOS);
6156 	litest_add_for_device(left_handed_mouse_rotation, LITEST_WACOM_INTUOS);
6157 	litest_add_for_device(left_handed_artpen_rotation, LITEST_WACOM_INTUOS);
6158 	litest_add_for_device(no_left_handed, LITEST_WACOM_CINTIQ);
6159 	litest_add(pad_buttons_ignored, LITEST_TABLET, LITEST_TOTEM);
6160 	litest_add(mouse_tool, LITEST_TABLET | LITEST_TOOL_MOUSE, LITEST_ANY);
6161 	litest_add(mouse_buttons, LITEST_TABLET | LITEST_TOOL_MOUSE, LITEST_ANY);
6162 	litest_add(mouse_rotation, LITEST_TABLET | LITEST_TOOL_MOUSE, LITEST_ANY);
6163 	litest_add(mouse_wheel, LITEST_TABLET | LITEST_TOOL_MOUSE, LITEST_WHEEL);
6164 	litest_add(airbrush_tool, LITEST_TABLET, LITEST_ANY);
6165 	litest_add(airbrush_slider, LITEST_TABLET, LITEST_ANY);
6166 	litest_add(artpen_tool, LITEST_TABLET, LITEST_ANY);
6167 	litest_add(artpen_rotation, LITEST_TABLET, LITEST_ANY);
6168 
6169 	litest_add(tablet_time_usec, LITEST_TABLET, LITEST_ANY);
6170 	litest_add(tablet_pressure_distance_exclusive, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY);
6171 
6172 	/* The totem doesn't need calibration */
6173 	litest_add(tablet_calibration_has_matrix, LITEST_TABLET, LITEST_TOTEM);
6174 	litest_add(tablet_calibration_set_matrix, LITEST_TABLET, LITEST_TOTEM);
6175 	litest_add(tablet_calibration_set_matrix_delta, LITEST_TABLET, LITEST_TOTEM);
6176 
6177 	litest_add(tablet_pressure_min_max, LITEST_TABLET, LITEST_ANY);
6178 	litest_add_for_device(tablet_pressure_range, LITEST_WACOM_INTUOS);
6179 	litest_add_for_device(tablet_pressure_offset, LITEST_WACOM_INTUOS);
6180 	litest_add_for_device(tablet_pressure_offset_decrease, LITEST_WACOM_INTUOS);
6181 	litest_add_for_device(tablet_pressure_offset_increase, LITEST_WACOM_INTUOS);
6182 	litest_add_for_device(tablet_pressure_offset_exceed_threshold, LITEST_WACOM_INTUOS);
6183 	litest_add_for_device(tablet_pressure_offset_none_for_zero_distance, LITEST_WACOM_INTUOS);
6184 	litest_add_for_device(tablet_pressure_offset_none_for_small_distance, LITEST_WACOM_INTUOS);
6185 	litest_add_for_device(tablet_distance_range, LITEST_WACOM_INTUOS);
6186 
6187 	litest_add(relative_no_profile, LITEST_TABLET, LITEST_ANY);
6188 	litest_add(relative_no_delta_prox_in, LITEST_TABLET, LITEST_ANY);
6189 	litest_add(relative_delta, LITEST_TABLET, LITEST_ANY);
6190 	litest_add(relative_no_delta_on_tip, LITEST_TABLET|LITEST_HOVER, LITEST_ANY);
6191 	litest_add(relative_calibration, LITEST_TABLET, LITEST_ANY);
6192 
6193 	litest_add(touch_arbitration, LITEST_TABLET, LITEST_ANY);
6194 	litest_add(touch_arbitration_stop_touch, LITEST_TABLET, LITEST_ANY);
6195 	litest_add(touch_arbitration_suspend_touch_device, LITEST_TOUCH, LITEST_ANY);
6196 	litest_add(touch_arbitration_remove_touch, LITEST_TABLET, LITEST_ANY);
6197 	litest_add(touch_arbitration_remove_tablet, LITEST_TOUCH, LITEST_ANY);
6198 	litest_add(touch_arbitration_keep_ignoring, LITEST_TABLET, LITEST_ANY);
6199 	litest_add(touch_arbitration_late_touch_lift, LITEST_TABLET, LITEST_ANY);
6200 	litest_add(touch_arbitration_outside_rect, LITEST_TABLET | LITEST_DIRECT, LITEST_ANY);
6201 	litest_add(touch_arbitration_remove_after, LITEST_TABLET | LITEST_DIRECT, LITEST_ANY);
6202 
6203 	litest_add_ranged(tablet_rotation_left_handed, LITEST_TABLET, LITEST_ANY, &lh_transitions);
6204 	litest_add_ranged(tablet_rotation_left_handed_configuration, LITEST_TABLET, LITEST_ANY, &lh_transitions);
6205 	litest_add_ranged(tablet_rotation_left_handed_while_in_prox, LITEST_TABLET, LITEST_ANY, &lh_transitions);
6206 	litest_add_ranged(tablet_rotation_left_handed_while_touch_down, LITEST_TABLET, LITEST_ANY, &lh_transitions);
6207 	litest_add_ranged(tablet_rotation_left_handed_add_touchpad, LITEST_TABLET, LITEST_ANY, &lh_transitions);
6208 	litest_add_ranged(tablet_rotation_left_handed_add_tablet, LITEST_TOUCHPAD, LITEST_ANY, &lh_transitions);
6209 
6210 	litest_add_for_device(huion_static_btn_tool_pen, LITEST_HUION_TABLET);
6211 	litest_add_for_device(huion_static_btn_tool_pen_no_timeout_during_usage, LITEST_HUION_TABLET);
6212 	litest_add_ranged_for_device(huion_static_btn_tool_pen_disable_quirk_on_prox_out, LITEST_HUION_TABLET, &with_timeout);
6213 
6214 	litest_add_for_device(tablet_smoothing, LITEST_WACOM_HID4800_PEN);
6215 }
6216