1 /*
2 * Copyright © 2013 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <config.h>
25
26 #include <check.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <libinput.h>
30 #include <libevdev/libevdev.h>
31 #include <unistd.h>
32
33 #include "libinput-util.h"
34 #include "litest.h"
35
START_TEST(touch_frame_events)36 START_TEST(touch_frame_events)
37 {
38 struct litest_device *dev = litest_current_device();
39 struct libinput *li = dev->libinput;
40 struct libinput_event *event;
41 int have_frame_event = 0;
42
43 litest_drain_events(dev->libinput);
44
45 litest_touch_down(dev, 0, 10, 10);
46 libinput_dispatch(li);
47
48 while ((event = libinput_get_event(li))) {
49 if (libinput_event_get_type(event) == LIBINPUT_EVENT_TOUCH_FRAME)
50 have_frame_event++;
51 libinput_event_destroy(event);
52 }
53 ck_assert_int_eq(have_frame_event, 1);
54
55 litest_touch_down(dev, 1, 10, 10);
56 libinput_dispatch(li);
57
58 while ((event = libinput_get_event(li))) {
59 if (libinput_event_get_type(event) == LIBINPUT_EVENT_TOUCH_FRAME)
60 have_frame_event++;
61 libinput_event_destroy(event);
62 }
63 ck_assert_int_eq(have_frame_event, 2);
64 }
65 END_TEST
66
START_TEST(touch_downup_no_motion)67 START_TEST(touch_downup_no_motion)
68 {
69 struct litest_device *dev = litest_current_device();
70 struct libinput *li = dev->libinput;
71
72 litest_drain_events(li);
73
74 litest_touch_down(dev, 0, 10, 10);
75 libinput_dispatch(li);
76
77 litest_assert_touch_down_frame(li);
78
79 litest_touch_up(dev, 0);
80 libinput_dispatch(li);
81
82 litest_assert_touch_up_frame(li);
83 }
84 END_TEST
85
START_TEST(touch_abs_transform)86 START_TEST(touch_abs_transform)
87 {
88 struct litest_device *dev;
89 struct libinput *libinput;
90 struct libinput_event *ev;
91 struct libinput_event_touch *tev;
92 double fx, fy;
93 bool tested = false;
94
95 struct input_absinfo abs[] = {
96 { ABS_X, 0, 32767, 75, 0, 10 },
97 { ABS_Y, 0, 32767, 129, 0, 9 },
98 { ABS_MT_POSITION_X, 0, 32767, 0, 0, 10 },
99 { ABS_MT_POSITION_Y, 0, 32767, 0, 0, 9 },
100 { .value = -1 },
101 };
102
103 dev = litest_create_device_with_overrides(LITEST_WACOM_TOUCH,
104 "litest Highres touch device",
105 NULL, abs, NULL);
106
107 libinput = dev->libinput;
108
109 litest_touch_down(dev, 0, 100, 100);
110
111 libinput_dispatch(libinput);
112
113 while ((ev = libinput_get_event(libinput))) {
114 if (libinput_event_get_type(ev) != LIBINPUT_EVENT_TOUCH_DOWN) {
115 libinput_event_destroy(ev);
116 continue;
117 }
118
119 tev = libinput_event_get_touch_event(ev);
120 fx = libinput_event_touch_get_x_transformed(tev, 1920);
121 ck_assert_int_eq(fx, 1919.0);
122 fy = libinput_event_touch_get_y_transformed(tev, 720);
123 ck_assert_int_eq(fy, 719.0);
124
125 tested = true;
126
127 libinput_event_destroy(ev);
128 }
129
130 ck_assert(tested);
131
132 litest_delete_device(dev);
133 }
134 END_TEST
135
136 static inline void
touch_assert_seat_slot(struct libinput * li,enum libinput_event_type type,unsigned int slot,unsigned int seat_slot)137 touch_assert_seat_slot(struct libinput *li,
138 enum libinput_event_type type,
139 unsigned int slot,
140 unsigned int seat_slot)
141 {
142 struct libinput_event *ev;
143 struct libinput_event_touch *tev;
144
145 libinput_dispatch(li);
146 ev = libinput_get_event(li);
147 tev = litest_is_touch_event(ev, type);
148 slot = libinput_event_touch_get_slot(tev);
149 ck_assert_int_eq(slot, slot);
150 slot = libinput_event_touch_get_seat_slot(tev);
151 ck_assert_int_eq(slot, seat_slot);
152 libinput_event_destroy(ev);
153
154 ev = libinput_get_event(li);
155 litest_assert_event_type(ev, LIBINPUT_EVENT_TOUCH_FRAME);
156 libinput_event_destroy(ev);
157 }
158
START_TEST(touch_seat_slot)159 START_TEST(touch_seat_slot)
160 {
161 struct litest_device *dev1 = litest_current_device();
162 struct litest_device *dev2;
163 struct libinput *li = dev1->libinput;
164
165 dev2 = litest_add_device(li, LITEST_WACOM_TOUCH);
166
167 litest_drain_events(li);
168
169 litest_touch_down(dev1, 0, 50, 50);
170 touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_DOWN, 0, 0);
171
172 litest_touch_down(dev2, 0, 50, 50);
173 touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_DOWN, 0, 1);
174
175 litest_touch_down(dev2, 1, 60, 50);
176 touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_DOWN, 1, 2);
177
178 litest_touch_down(dev1, 1, 60, 50);
179 touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_DOWN, 1, 3);
180
181 litest_touch_move_to(dev1, 0, 50, 50, 60, 70, 10);
182 touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_MOTION, 0, 0);
183 litest_drain_events(li);
184
185 litest_touch_move_to(dev2, 1, 50, 50, 60, 70, 10);
186 touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_MOTION, 1, 2);
187 litest_drain_events(li);
188
189 litest_touch_up(dev1, 0);
190 touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_UP, 0, 0);
191
192 litest_touch_up(dev2, 0);
193 touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_UP, 0, 1);
194
195 litest_touch_up(dev2, 1);
196 touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_UP, 1, 2);
197
198 litest_touch_up(dev1, 1);
199 touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_UP, 1, 3);
200
201 litest_delete_device(dev2);
202 }
203 END_TEST
204
START_TEST(touch_many_slots)205 START_TEST(touch_many_slots)
206 {
207 struct libinput *libinput;
208 struct litest_device *dev;
209 struct libinput_event *ev;
210 int slot;
211 const int num_tps = 100;
212 int slot_count = 0;
213 enum libinput_event_type type;
214
215 struct input_absinfo abs[] = {
216 { ABS_MT_SLOT, 0, num_tps - 1, 0, 0, 0 },
217 { .value = -1 },
218 };
219
220 dev = litest_create_device_with_overrides(LITEST_WACOM_TOUCH,
221 "litest Multi-touch device",
222 NULL, abs, NULL);
223 libinput = dev->libinput;
224
225 for (slot = 0; slot < num_tps; ++slot)
226 litest_touch_down(dev, slot, 0, 0);
227 for (slot = 0; slot < num_tps; ++slot)
228 litest_touch_up(dev, slot);
229
230 libinput_dispatch(libinput);
231 while ((ev = libinput_get_event(libinput))) {
232 type = libinput_event_get_type(ev);
233
234 if (type == LIBINPUT_EVENT_TOUCH_DOWN)
235 slot_count++;
236 else if (type == LIBINPUT_EVENT_TOUCH_UP)
237 break;
238
239 libinput_event_destroy(ev);
240 libinput_dispatch(libinput);
241 }
242
243 ck_assert_notnull(ev);
244 ck_assert_int_gt(slot_count, 0);
245
246 libinput_dispatch(libinput);
247 do {
248 type = libinput_event_get_type(ev);
249 ck_assert_int_ne(type, LIBINPUT_EVENT_TOUCH_DOWN);
250 if (type == LIBINPUT_EVENT_TOUCH_UP)
251 slot_count--;
252
253 libinput_event_destroy(ev);
254 libinput_dispatch(libinput);
255 } while ((ev = libinput_get_event(libinput)));
256
257 ck_assert_int_eq(slot_count, 0);
258
259 litest_delete_device(dev);
260 }
261 END_TEST
262
START_TEST(touch_double_touch_down_up)263 START_TEST(touch_double_touch_down_up)
264 {
265 struct libinput *libinput;
266 struct litest_device *dev;
267 struct libinput_event *ev;
268 bool got_down = false;
269 bool got_up = false;
270
271 dev = litest_current_device();
272 libinput = dev->libinput;
273
274 litest_disable_log_handler(libinput);
275 /* note: this test is a false negative, libevdev will filter
276 * tracking IDs re-used in the same slot. */
277 litest_touch_down(dev, 0, 0, 0);
278 litest_touch_down(dev, 0, 0, 0);
279 litest_touch_up(dev, 0);
280 litest_touch_up(dev, 0);
281 libinput_dispatch(libinput);
282 litest_restore_log_handler(libinput);
283
284 while ((ev = libinput_get_event(libinput))) {
285 switch (libinput_event_get_type(ev)) {
286 case LIBINPUT_EVENT_TOUCH_DOWN:
287 ck_assert(!got_down);
288 got_down = true;
289 break;
290 case LIBINPUT_EVENT_TOUCH_UP:
291 ck_assert(got_down);
292 ck_assert(!got_up);
293 got_up = true;
294 break;
295 default:
296 break;
297 }
298
299 libinput_event_destroy(ev);
300 libinput_dispatch(libinput);
301 }
302
303 ck_assert(got_down);
304 ck_assert(got_up);
305 }
306 END_TEST
307
START_TEST(touch_calibration_scale)308 START_TEST(touch_calibration_scale)
309 {
310 struct libinput *li;
311 struct litest_device *dev;
312 struct libinput_event *ev;
313 struct libinput_event_touch *tev;
314 float matrix[6] = {
315 1, 0, 0,
316 0, 1, 0
317 };
318
319 float calibration;
320 double x, y;
321 const int width = 640, height = 480;
322
323 dev = litest_current_device();
324 li = dev->libinput;
325
326 for (calibration = 0.1; calibration < 1; calibration += 0.1) {
327 libinput_device_config_calibration_set_matrix(dev->libinput_device,
328 matrix);
329 litest_drain_events(li);
330
331 litest_touch_down(dev, 0, 100, 100);
332 litest_touch_up(dev, 0);
333 libinput_dispatch(li);
334
335 ev = libinput_get_event(li);
336 tev = litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_DOWN);
337
338 x = libinput_event_touch_get_x_transformed(tev, width);
339 y = libinput_event_touch_get_y_transformed(tev, height);
340
341 ck_assert_int_eq(round(x), round(width * matrix[0]));
342 ck_assert_int_eq(round(y), round(height * matrix[4]));
343
344 libinput_event_destroy(ev);
345 litest_drain_events(li);
346
347 matrix[0] = calibration;
348 matrix[4] = 1 - calibration;
349 }
350 }
351 END_TEST
352
START_TEST(touch_calibration_rotation)353 START_TEST(touch_calibration_rotation)
354 {
355 struct libinput *li;
356 struct litest_device *dev;
357 struct libinput_event *ev;
358 struct libinput_event_touch *tev;
359 float matrix[6];
360 int i;
361 double x, y;
362 int width = 1024, height = 480;
363
364 dev = litest_current_device();
365 li = dev->libinput;
366
367 for (i = 0; i < 4; i++) {
368 float angle = i * M_PI/2;
369
370 /* [ cos -sin tx ]
371 [ sin cos ty ]
372 [ 0 0 1 ] */
373 matrix[0] = cos(angle);
374 matrix[1] = -sin(angle);
375 matrix[3] = sin(angle);
376 matrix[4] = cos(angle);
377
378 switch(i) {
379 case 0: /* 0 deg */
380 matrix[2] = 0;
381 matrix[5] = 0;
382 break;
383 case 1: /* 90 deg cw */
384 matrix[2] = 1;
385 matrix[5] = 0;
386 break;
387 case 2: /* 180 deg cw */
388 matrix[2] = 1;
389 matrix[5] = 1;
390 break;
391 case 3: /* 270 deg cw */
392 matrix[2] = 0;
393 matrix[5] = 1;
394 break;
395 }
396
397 libinput_device_config_calibration_set_matrix(dev->libinput_device,
398 matrix);
399 litest_drain_events(li);
400
401 litest_touch_down(dev, 0, 80, 20);
402 litest_touch_up(dev, 0);
403 libinput_dispatch(li);
404 ev = libinput_get_event(li);
405 tev = litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_DOWN);
406
407 x = libinput_event_touch_get_x_transformed(tev, width);
408 y = libinput_event_touch_get_y_transformed(tev, height);
409
410 /* rounding errors... */
411 #define almost_equal(a_, b_) \
412 { ck_assert_int_ge((a_) + 0.5, (b_) - 1); \
413 ck_assert_int_le((a_) + 0.5, (b_) + 1); }
414 switch(i) {
415 case 0: /* 0 deg */
416 almost_equal(x, width * 0.8);
417 almost_equal(y, height * 0.2);
418 break;
419 case 1: /* 90 deg cw */
420 almost_equal(x, width * 0.8);
421 almost_equal(y, height * 0.8);
422 break;
423 case 2: /* 180 deg cw */
424 almost_equal(x, width * 0.2);
425 almost_equal(y, height * 0.8);
426 break;
427 case 3: /* 270 deg cw */
428 almost_equal(x, width * 0.2);
429 almost_equal(y, height * 0.2);
430 break;
431 }
432 #undef almost_equal
433
434 libinput_event_destroy(ev);
435 litest_drain_events(li);
436 }
437 }
438 END_TEST
439
START_TEST(touch_calibration_translation)440 START_TEST(touch_calibration_translation)
441 {
442 struct libinput *li;
443 struct litest_device *dev;
444 struct libinput_event *ev;
445 struct libinput_event_touch *tev;
446 float matrix[6] = {
447 1, 0, 0,
448 0, 1, 0
449 };
450
451 float translate;
452 double x, y;
453 const int width = 640, height = 480;
454
455 dev = litest_current_device();
456 li = dev->libinput;
457
458 /* translating from 0 up to 1 device width/height */
459 for (translate = 0.1; translate <= 1; translate += 0.1) {
460 libinput_device_config_calibration_set_matrix(dev->libinput_device,
461 matrix);
462 litest_drain_events(li);
463
464 litest_touch_down(dev, 0, 100, 100);
465 litest_touch_up(dev, 0);
466
467 libinput_dispatch(li);
468 ev = libinput_get_event(li);
469 tev = litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_DOWN);
470
471 x = libinput_event_touch_get_x_transformed(tev, width);
472 y = libinput_event_touch_get_y_transformed(tev, height);
473
474 /* sigh. rounding errors */
475 ck_assert_int_ge(round(x), width + round(width * matrix[2]) - 1);
476 ck_assert_int_ge(round(y), height + round(height * matrix[5]) - 1);
477 ck_assert_int_le(round(x), width + round(width * matrix[2]) + 1);
478 ck_assert_int_le(round(y), height + round(height * matrix[5]) + 1);
479
480 libinput_event_destroy(ev);
481 litest_drain_events(li);
482
483 matrix[2] = translate;
484 matrix[5] = 1 - translate;
485 }
486 }
487 END_TEST
488
START_TEST(touch_calibrated_screen_path)489 START_TEST(touch_calibrated_screen_path)
490 {
491 struct litest_device *dev = litest_current_device();
492 float matrix[6];
493 int rc;
494
495 rc = libinput_device_config_calibration_has_matrix(dev->libinput_device);
496 ck_assert_int_eq(rc, 1);
497
498 rc = libinput_device_config_calibration_get_matrix(dev->libinput_device,
499 matrix);
500 ck_assert_int_eq(rc, 1);
501
502 ck_assert_double_eq(matrix[0], 1.2);
503 ck_assert_double_eq(matrix[1], 3.4);
504 ck_assert_double_eq(matrix[2], 5.6);
505 ck_assert_double_eq(matrix[3], 7.8);
506 ck_assert_double_eq(matrix[4], 9.10);
507 ck_assert_double_eq(matrix[5], 11.12);
508 }
509 END_TEST
510
START_TEST(touch_calibration_config)511 START_TEST(touch_calibration_config)
512 {
513 struct litest_device *dev = litest_current_device();
514 float identity[6] = {1, 0, 0, 0, 1, 0};
515 float nonidentity[6] = {1, 2, 3, 4, 5, 6};
516 float matrix[6];
517 enum libinput_config_status status;
518 int rc;
519
520 rc = libinput_device_config_calibration_has_matrix(dev->libinput_device);
521 ck_assert_int_eq(rc, 1);
522
523 /* Twice so we have every to-fro combination */
524 for (int i = 0; i < 2; i++) {
525 status = libinput_device_config_calibration_set_matrix(dev->libinput_device, identity);
526 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
527 libinput_device_config_calibration_get_matrix(dev->libinput_device, matrix);
528 ck_assert_int_eq(memcmp(matrix, identity, sizeof(matrix)), 0);
529
530 status = libinput_device_config_calibration_set_matrix(dev->libinput_device, nonidentity);
531 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
532 libinput_device_config_calibration_get_matrix(dev->libinput_device, matrix);
533 ck_assert_int_eq(memcmp(matrix, nonidentity, sizeof(matrix)), 0);
534 }
535
536 }
537 END_TEST
538
open_restricted(const char * path,int flags,void * data)539 static int open_restricted(const char *path, int flags, void *data)
540 {
541 int fd;
542 fd = open(path, flags);
543 return fd < 0 ? -errno : fd;
544 }
close_restricted(int fd,void * data)545 static void close_restricted(int fd, void *data)
546 {
547 close(fd);
548 }
549
550 static const struct libinput_interface simple_interface = {
551 .open_restricted = open_restricted,
552 .close_restricted = close_restricted,
553 };
554
START_TEST(touch_calibrated_screen_udev)555 START_TEST(touch_calibrated_screen_udev)
556 {
557 struct libinput *li;
558 struct libinput_event *ev;
559 struct libinput_device *device = NULL;
560 struct udev *udev;
561 float matrix[6];
562 int rc;
563
564 udev = udev_new();
565 ck_assert_notnull(udev);
566
567 li = libinput_udev_create_context(&simple_interface, NULL, udev);
568 ck_assert_notnull(li);
569 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
570
571 libinput_dispatch(li);
572
573 while ((ev = libinput_get_event(li))) {
574 struct libinput_device *d;
575
576 if (libinput_event_get_type(ev) !=
577 LIBINPUT_EVENT_DEVICE_ADDED) {
578 libinput_event_destroy(ev);
579 continue;
580 }
581
582 d = libinput_event_get_device(ev);
583
584 if (libinput_device_get_id_vendor(d) == 0x22 &&
585 libinput_device_get_id_product(d) == 0x33) {
586 device = libinput_device_ref(d);
587 litest_drain_events(li);
588 }
589 libinput_event_destroy(ev);
590 }
591
592 litest_drain_events(li);
593
594 ck_assert_notnull(device);
595 rc = libinput_device_config_calibration_has_matrix(device);
596 ck_assert_int_eq(rc, 1);
597
598 rc = libinput_device_config_calibration_get_matrix(device, matrix);
599 ck_assert_int_eq(rc, 1);
600
601 ck_assert_double_eq(matrix[0], 1.2);
602 ck_assert_double_eq(matrix[1], 3.4);
603 ck_assert_double_eq(matrix[2], 5.6);
604 ck_assert_double_eq(matrix[3], 7.8);
605 ck_assert_double_eq(matrix[4], 9.10);
606 ck_assert_double_eq(matrix[5], 11.12);
607
608 libinput_device_unref(device);
609
610 libinput_unref(li);
611 udev_unref(udev);
612
613 }
614 END_TEST
615
START_TEST(touch_no_left_handed)616 START_TEST(touch_no_left_handed)
617 {
618 struct litest_device *dev = litest_current_device();
619 struct libinput_device *d = dev->libinput_device;
620 enum libinput_config_status status;
621 int rc;
622
623 rc = libinput_device_config_left_handed_is_available(d);
624 ck_assert_int_eq(rc, 0);
625
626 rc = libinput_device_config_left_handed_get(d);
627 ck_assert_int_eq(rc, 0);
628
629 rc = libinput_device_config_left_handed_get_default(d);
630 ck_assert_int_eq(rc, 0);
631
632 status = libinput_device_config_left_handed_set(d, 0);
633 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
634 }
635 END_TEST
636
START_TEST(fake_mt_exists)637 START_TEST(fake_mt_exists)
638 {
639 struct litest_device *dev = litest_current_device();
640 struct libinput *li = dev->libinput;
641 struct libinput_event *event;
642 struct libinput_device *device;
643
644 libinput_dispatch(li);
645
646 event = libinput_get_event(li);
647 device = libinput_event_get_device(event);
648
649 ck_assert(!libinput_device_has_capability(device,
650 LIBINPUT_DEVICE_CAP_TOUCH));
651
652 /* This test may need fixing if we add other fake-mt devices that
653 * have different capabilities */
654 ck_assert(libinput_device_has_capability(device,
655 LIBINPUT_DEVICE_CAP_POINTER));
656
657 libinput_event_destroy(event);
658 }
659 END_TEST
660
START_TEST(fake_mt_no_touch_events)661 START_TEST(fake_mt_no_touch_events)
662 {
663 struct litest_device *dev = litest_current_device();
664 struct libinput *li = dev->libinput;
665
666 litest_drain_events(li);
667
668 litest_touch_down(dev, 0, 50, 50);
669 litest_touch_move_to(dev, 0, 50, 50, 70, 70, 5);
670 litest_touch_up(dev, 0);
671
672 litest_touch_down(dev, 0, 50, 50);
673 litest_touch_down(dev, 1, 70, 70);
674 litest_touch_move_to(dev, 0, 50, 50, 90, 40, 10);
675 litest_touch_move_to(dev, 0, 70, 70, 40, 50, 10);
676 litest_touch_up(dev, 0);
677 litest_touch_up(dev, 1);
678
679 litest_assert_only_typed_events(li,
680 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
681 }
682 END_TEST
683
START_TEST(touch_protocol_a_init)684 START_TEST(touch_protocol_a_init)
685 {
686 struct litest_device *dev = litest_current_device();
687 struct libinput *li = dev->libinput;
688 struct libinput_device *device = dev->libinput_device;
689
690 ck_assert_int_ne(libinput_next_event_type(li),
691 LIBINPUT_EVENT_NONE);
692
693 ck_assert(libinput_device_has_capability(device,
694 LIBINPUT_DEVICE_CAP_TOUCH));
695 }
696 END_TEST
697
START_TEST(touch_protocol_a_touch)698 START_TEST(touch_protocol_a_touch)
699 {
700 struct litest_device *dev = litest_current_device();
701 struct libinput *li = dev->libinput;
702 struct libinput_event *ev;
703 struct libinput_event_touch *tev;
704 double x, y, oldx, oldy;
705
706 litest_drain_events(li);
707
708 litest_touch_down(dev, 0, 5, 95);
709 libinput_dispatch(li);
710
711 ev = libinput_get_event(li);
712 tev = litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_DOWN);
713
714 oldx = libinput_event_touch_get_x(tev);
715 oldy = libinput_event_touch_get_y(tev);
716
717 libinput_event_destroy(ev);
718
719 ev = libinput_get_event(li);
720 litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_FRAME);
721 libinput_event_destroy(ev);
722
723 litest_touch_move_to(dev, 0, 10, 90, 90, 10, 20);
724 libinput_dispatch(li);
725
726 while ((ev = libinput_get_event(li))) {
727 if (libinput_event_get_type(ev) ==
728 LIBINPUT_EVENT_TOUCH_FRAME) {
729 libinput_event_destroy(ev);
730 continue;
731 }
732 ck_assert_int_eq(libinput_event_get_type(ev),
733 LIBINPUT_EVENT_TOUCH_MOTION);
734
735 tev = libinput_event_get_touch_event(ev);
736 x = libinput_event_touch_get_x(tev);
737 y = libinput_event_touch_get_y(tev);
738
739 ck_assert_int_gt(x, oldx);
740 ck_assert_int_lt(y, oldy);
741
742 oldx = x;
743 oldy = y;
744
745 libinput_event_destroy(ev);
746 }
747
748 litest_touch_up(dev, 0);
749 libinput_dispatch(li);
750 ev = libinput_get_event(li);
751 litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_UP);
752 libinput_event_destroy(ev);
753 }
754 END_TEST
755
START_TEST(touch_protocol_a_2fg_touch)756 START_TEST(touch_protocol_a_2fg_touch)
757 {
758 struct litest_device *dev = litest_current_device();
759 struct libinput *li = dev->libinput;
760 struct libinput_event *ev;
761 struct libinput_event_touch *tev;
762 int pos;
763
764 litest_drain_events(li);
765
766 litest_touch_down(dev, 0, 5, 95);
767 litest_touch_down(dev, 1, 95, 5);
768
769 libinput_dispatch(li);
770 litest_assert_touch_down_frame(li);
771
772 ev = libinput_get_event(li);
773 litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_DOWN);
774 libinput_event_destroy(ev);
775
776 ev = libinput_get_event(li);
777 litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_FRAME);
778 libinput_event_destroy(ev);
779
780 for (pos = 10; pos < 100; pos += 10) {
781 litest_touch_move(dev, 0, pos, 100 - pos);
782 litest_touch_move(dev, 1, 100 - pos, pos);
783 libinput_dispatch(li);
784
785 ev = libinput_get_event(li);
786 tev = libinput_event_get_touch_event(ev);
787 ck_assert_int_eq(libinput_event_touch_get_slot(tev), 0);
788 libinput_event_destroy(ev);
789
790 ev = libinput_get_event(li);
791 litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_FRAME);
792 libinput_event_destroy(ev);
793
794 ev = libinput_get_event(li);
795 tev = libinput_event_get_touch_event(ev);
796 ck_assert_int_eq(libinput_event_touch_get_slot(tev), 1);
797 libinput_event_destroy(ev);
798
799 ev = libinput_get_event(li);
800 litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_FRAME);
801 libinput_event_destroy(ev);
802 }
803
804 litest_touch_up(dev, 0);
805 libinput_dispatch(li);
806 litest_assert_touch_up_frame(li);
807
808 litest_touch_up(dev, 1);
809 libinput_dispatch(li);
810 litest_assert_touch_up_frame(li);
811 }
812 END_TEST
813
START_TEST(touch_initial_state)814 START_TEST(touch_initial_state)
815 {
816 struct litest_device *dev;
817 struct libinput *libinput1, *libinput2;
818 struct libinput_event *ev1 = NULL;
819 struct libinput_event *ev2 = NULL;
820 struct libinput_event_touch *t1, *t2;
821 struct libinput_device *device1, *device2;
822 int axis = _i; /* looped test */
823
824 dev = litest_current_device();
825 device1 = dev->libinput_device;
826 libinput_device_config_tap_set_enabled(device1,
827 LIBINPUT_CONFIG_TAP_DISABLED);
828
829 libinput1 = dev->libinput;
830 litest_touch_down(dev, 0, 40, 60);
831 litest_touch_up(dev, 0);
832
833 /* device is now on some x/y value */
834 litest_drain_events(libinput1);
835
836 libinput2 = litest_create_context();
837 device2 = libinput_path_add_device(libinput2,
838 libevdev_uinput_get_devnode(
839 dev->uinput));
840 libinput_device_config_tap_set_enabled(device2,
841 LIBINPUT_CONFIG_TAP_DISABLED);
842 litest_drain_events(libinput2);
843
844 if (axis == ABS_X)
845 litest_touch_down(dev, 0, 40, 70);
846 else
847 litest_touch_down(dev, 0, 70, 60);
848 litest_touch_up(dev, 0);
849
850 libinput_dispatch(libinput1);
851 libinput_dispatch(libinput2);
852
853 while (libinput_next_event_type(libinput1)) {
854 ev1 = libinput_get_event(libinput1);
855 ev2 = libinput_get_event(libinput2);
856
857 t1 = litest_is_touch_event(ev1, 0);
858 t2 = litest_is_touch_event(ev2, 0);
859
860 ck_assert_int_eq(libinput_event_get_type(ev1),
861 libinput_event_get_type(ev2));
862
863 if (libinput_event_get_type(ev1) == LIBINPUT_EVENT_TOUCH_UP ||
864 libinput_event_get_type(ev1) == LIBINPUT_EVENT_TOUCH_FRAME)
865 break;
866
867 ck_assert_int_eq(libinput_event_touch_get_x(t1),
868 libinput_event_touch_get_x(t2));
869 ck_assert_int_eq(libinput_event_touch_get_y(t1),
870 libinput_event_touch_get_y(t2));
871
872 libinput_event_destroy(ev1);
873 libinput_event_destroy(ev2);
874 ev1 = NULL;
875 ev2 = NULL;
876 }
877
878 libinput_event_destroy(ev1);
879 libinput_event_destroy(ev2);
880
881 litest_destroy_context(libinput2);
882 }
883 END_TEST
884
START_TEST(touch_time_usec)885 START_TEST(touch_time_usec)
886 {
887 struct litest_device *dev = litest_current_device();
888 struct libinput *li = dev->libinput;
889 struct libinput_event *event;
890 struct libinput_event_touch *tev;
891 uint64_t time_usec;
892
893 litest_drain_events(dev->libinput);
894
895 litest_touch_down(dev, 0, 10, 10);
896 libinput_dispatch(li);
897
898 event = libinput_get_event(li);
899 tev = litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_DOWN);
900 time_usec = libinput_event_touch_get_time_usec(tev);
901 ck_assert_int_eq(libinput_event_touch_get_time(tev),
902 (uint32_t) (time_usec / 1000));
903 libinput_event_destroy(event);
904 }
905 END_TEST
906
START_TEST(touch_fuzz)907 START_TEST(touch_fuzz)
908 {
909 struct litest_device *dev = litest_current_device();
910 struct libinput *li = dev->libinput;
911 struct libinput_event *event;
912 int i;
913 int x = 700, y = 300;
914
915 litest_drain_events(dev->libinput);
916
917 litest_event(dev, EV_ABS, ABS_MT_TRACKING_ID, 30);
918 litest_event(dev, EV_ABS, ABS_MT_SLOT, 0);
919 litest_event(dev, EV_ABS, ABS_MT_POSITION_X, x);
920 litest_event(dev, EV_ABS, ABS_MT_POSITION_Y, y);
921 litest_event(dev, EV_KEY, BTN_TOUCH, 1);
922 litest_event(dev, EV_SYN, SYN_REPORT, 0);
923 libinput_dispatch(li);
924
925 event = libinput_get_event(li);
926 litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_DOWN);
927 libinput_event_destroy(event);
928 event = libinput_get_event(li);
929 litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
930 libinput_event_destroy(event);
931
932 litest_drain_events(li);
933
934 for (i = 0; i < 50; i++) {
935 if (i % 2) {
936 x++;
937 y--;
938 } else {
939 x--;
940 y++;
941 }
942 litest_event(dev, EV_ABS, ABS_MT_POSITION_X, x);
943 litest_event(dev, EV_ABS, ABS_MT_POSITION_Y, y);
944 litest_event(dev, EV_SYN, SYN_REPORT, 0);
945 libinput_dispatch(li);
946 litest_assert_empty_queue(li);
947 }
948 }
949 END_TEST
950
START_TEST(touch_fuzz_property)951 START_TEST(touch_fuzz_property)
952 {
953 struct litest_device *dev = litest_current_device();
954 struct udev_device *d;
955 const char *prop;
956 int fuzz;
957
958 ck_assert_int_eq(libevdev_get_abs_fuzz(dev->evdev, ABS_X), 0);
959 ck_assert_int_eq(libevdev_get_abs_fuzz(dev->evdev, ABS_Y), 0);
960
961 d = libinput_device_get_udev_device(dev->libinput_device);
962 prop = udev_device_get_property_value(d, "LIBINPUT_FUZZ_00");
963 ck_assert_notnull(prop);
964 ck_assert(safe_atoi(prop, &fuzz));
965 ck_assert_int_eq(fuzz, 10); /* device-specific */
966
967 prop = udev_device_get_property_value(d, "LIBINPUT_FUZZ_01");
968 ck_assert_notnull(prop);
969 ck_assert(safe_atoi(prop, &fuzz));
970 ck_assert_int_eq(fuzz, 12); /* device-specific */
971
972 udev_device_unref(d);
973 }
974 END_TEST
975
START_TEST(touch_release_on_unplug)976 START_TEST(touch_release_on_unplug)
977 {
978 struct litest_device *dev;
979 struct libinput *li;
980 struct libinput_event *ev;
981
982 li = litest_create_context();
983 dev = litest_add_device(li, LITEST_GENERIC_MULTITOUCH_SCREEN);
984 litest_drain_events(li);
985
986 litest_touch_down(dev, 0, 50, 50);
987 litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10);
988 litest_drain_events(li);
989
990 /* Touch is still down when device is removed, espect a release */
991 litest_delete_device(dev);
992 libinput_dispatch(li);
993
994 ev = libinput_get_event(li);
995 litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_CANCEL);
996 libinput_event_destroy(ev);
997
998 ev = libinput_get_event(li);
999 litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_FRAME);
1000 libinput_event_destroy(ev);
1001
1002 ev = libinput_get_event(li);
1003 litest_assert_event_type(ev, LIBINPUT_EVENT_DEVICE_REMOVED);
1004 libinput_event_destroy(ev);
1005
1006 litest_destroy_context(li);
1007 }
1008 END_TEST
1009
START_TEST(touch_invalid_range_over)1010 START_TEST(touch_invalid_range_over)
1011 {
1012 struct litest_device *dev = litest_current_device();
1013 struct libinput *li = dev->libinput;
1014 struct libinput_event *ev;
1015 struct libinput_event_touch *t;
1016 double x, y;
1017
1018 litest_drain_events(li);
1019
1020 /* Touch outside the valid area */
1021 litest_event(dev, EV_ABS, ABS_MT_SLOT, 0);
1022 litest_event(dev, EV_ABS, ABS_MT_TRACKING_ID, 1);
1023 litest_event(dev, EV_ABS, ABS_X, 4000);
1024 litest_event(dev, EV_ABS, ABS_Y, 5000);
1025 litest_event(dev, EV_ABS, ABS_MT_POSITION_X, 4000);
1026 litest_event(dev, EV_ABS, ABS_MT_POSITION_Y, 5000);
1027 litest_event(dev, EV_KEY, BTN_TOUCH, 1);
1028 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1029 libinput_dispatch(li);
1030
1031 /* Expect the mm to be correct regardless */
1032 ev = libinput_get_event(li);
1033 t = litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_DOWN);
1034 x = libinput_event_touch_get_x(t);
1035 y = libinput_event_touch_get_y(t);
1036 ck_assert_double_eq(x, 300); /* device has resolution 10 */
1037 ck_assert_double_eq(y, 300); /* device has resolution 10 */
1038
1039 /* Expect the percentage to be correct too, even if > 100% */
1040 x = libinput_event_touch_get_x_transformed(t, 100);
1041 y = libinput_event_touch_get_y_transformed(t, 100);
1042 ck_assert_double_eq(round(x), 200);
1043 ck_assert_double_eq(round(y), 120);
1044
1045 libinput_event_destroy(ev);
1046 }
1047 END_TEST
1048
START_TEST(touch_invalid_range_under)1049 START_TEST(touch_invalid_range_under)
1050 {
1051 struct litest_device *dev = litest_current_device();
1052 struct libinput *li = dev->libinput;
1053 struct libinput_event *ev;
1054 struct libinput_event_touch *t;
1055 double x, y;
1056
1057 litest_drain_events(li);
1058
1059 /* Touch outside the valid area */
1060 litest_event(dev, EV_ABS, ABS_MT_SLOT, 0);
1061 litest_event(dev, EV_ABS, ABS_MT_TRACKING_ID, 1);
1062 litest_event(dev, EV_ABS, ABS_X, -500);
1063 litest_event(dev, EV_ABS, ABS_Y, 1000);
1064 litest_event(dev, EV_ABS, ABS_MT_POSITION_X, -500);
1065 litest_event(dev, EV_ABS, ABS_MT_POSITION_Y, 1000);
1066 litest_event(dev, EV_KEY, BTN_TOUCH, 1);
1067 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1068 libinput_dispatch(li);
1069
1070 /* Expect the mm to be correct regardless */
1071 ev = libinput_get_event(li);
1072 t = litest_is_touch_event(ev, LIBINPUT_EVENT_TOUCH_DOWN);
1073 x = libinput_event_touch_get_x(t);
1074 y = libinput_event_touch_get_y(t);
1075 ck_assert_double_eq(x, -150); /* device has resolution 10 */
1076 ck_assert_double_eq(y, -100); /* device has resolution 10 */
1077
1078 /* Expect the percentage to be correct too, even if > 100% */
1079 x = libinput_event_touch_get_x_transformed(t, 100);
1080 y = libinput_event_touch_get_y_transformed(t, 100);
1081 ck_assert_double_eq(round(x), -100);
1082 ck_assert_double_eq(round(y), -40);
1083
1084 libinput_event_destroy(ev);
1085 }
1086 END_TEST
1087
START_TEST(touch_count_st)1088 START_TEST(touch_count_st)
1089 {
1090 struct litest_device *dev = litest_current_device();
1091 struct libinput_device *device = dev->libinput_device;
1092
1093 ck_assert_int_eq(libinput_device_touch_get_touch_count(device), 1);
1094 }
1095 END_TEST
1096
START_TEST(touch_count_mt)1097 START_TEST(touch_count_mt)
1098 {
1099 struct litest_device *dev = litest_current_device();
1100 struct libinput_device *device = dev->libinput_device;
1101 struct libevdev *evdev = dev->evdev;
1102
1103 ck_assert_int_eq(libinput_device_touch_get_touch_count(device),
1104 libevdev_get_num_slots(evdev));
1105 }
1106 END_TEST
1107
START_TEST(touch_count_unknown)1108 START_TEST(touch_count_unknown)
1109 {
1110 struct litest_device *dev = litest_current_device();
1111 struct libinput_device *device = dev->libinput_device;
1112
1113 ck_assert_int_eq(libinput_device_touch_get_touch_count(device), 0);
1114 }
1115 END_TEST
1116
START_TEST(touch_count_invalid)1117 START_TEST(touch_count_invalid)
1118 {
1119 struct litest_device *dev = litest_current_device();
1120 struct libinput_device *device = dev->libinput_device;
1121
1122 ck_assert_int_eq(libinput_device_touch_get_touch_count(device), -1);
1123 }
1124 END_TEST
1125
1126 static inline bool
touch_has_tool_palm(struct litest_device * dev)1127 touch_has_tool_palm(struct litest_device *dev)
1128 {
1129 return libevdev_has_event_code(dev->evdev, EV_ABS, ABS_MT_TOOL_TYPE);
1130 }
1131
START_TEST(touch_palm_detect_tool_palm)1132 START_TEST(touch_palm_detect_tool_palm)
1133 {
1134 struct litest_device *dev = litest_current_device();
1135 struct libinput *li = dev->libinput;
1136 struct axis_replacement axes[] = {
1137 { ABS_MT_TOOL_TYPE, MT_TOOL_PALM },
1138 { -1, 0 }
1139 };
1140
1141 if (!touch_has_tool_palm(dev))
1142 return;
1143
1144 litest_touch_down(dev, 0, 50, 50);
1145 litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10);
1146 litest_drain_events(li);
1147
1148 litest_touch_move_to_extended(dev, 0, 50, 50, 70, 70, axes, 10);
1149 libinput_dispatch(li);
1150 litest_assert_touch_cancel(li);
1151
1152 litest_touch_move_to(dev, 0, 70, 70, 50, 40, 10);
1153 litest_touch_up(dev, 0);
1154
1155 litest_assert_empty_queue(li);
1156 }
1157 END_TEST
1158
START_TEST(touch_palm_detect_tool_palm_on_off)1159 START_TEST(touch_palm_detect_tool_palm_on_off)
1160 {
1161 struct litest_device *dev = litest_current_device();
1162 struct libinput *li = dev->libinput;
1163 struct axis_replacement axes[] = {
1164 { ABS_MT_TOOL_TYPE, MT_TOOL_PALM },
1165 { -1, 0 }
1166 };
1167
1168 if (!touch_has_tool_palm(dev))
1169 return;
1170
1171 litest_touch_down(dev, 0, 50, 50);
1172 litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10);
1173 litest_drain_events(li);
1174
1175 litest_touch_move_to_extended(dev, 0, 50, 50, 70, 70, axes, 10);
1176 libinput_dispatch(li);
1177 litest_assert_touch_cancel(li);
1178
1179 litest_touch_move_to(dev, 0, 70, 70, 50, 40, 10);
1180 litest_assert_empty_queue(li);
1181
1182 litest_axis_set_value(axes, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
1183 litest_touch_move_to_extended(dev, 0, 50, 40, 70, 70, axes, 10);
1184 litest_touch_up(dev, 0);
1185
1186 litest_assert_empty_queue(li);
1187 }
1188 END_TEST
1189
START_TEST(touch_palm_detect_tool_palm_keep_type)1190 START_TEST(touch_palm_detect_tool_palm_keep_type)
1191 {
1192 struct litest_device *dev = litest_current_device();
1193 struct libinput *li = dev->libinput;
1194 struct axis_replacement axes[] = {
1195 { ABS_MT_TOOL_TYPE, MT_TOOL_PALM },
1196 { -1, 0 }
1197 };
1198
1199 if (!touch_has_tool_palm(dev))
1200 return;
1201
1202 litest_touch_down(dev, 0, 50, 50);
1203 litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10);
1204 litest_touch_move_to_extended(dev, 0, 50, 50, 70, 70, axes, 10);
1205 litest_touch_up(dev, 0);
1206 litest_drain_events(li);
1207
1208 /* ABS_MT_TOOL_TYPE never reset to finger, so a new touch
1209 should be ignored outright */
1210 litest_touch_down_extended(dev, 0, 50, 50, axes);
1211
1212 /* Test the revert to finger case too */
1213 litest_axis_set_value(axes, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
1214 litest_touch_move_to(dev, 0, 70, 70, 50, 40, 10);
1215 litest_touch_up(dev, 0);
1216
1217 litest_assert_empty_queue(li);
1218 }
1219 END_TEST
1220
START_TEST(touch_palm_detect_tool_palm_2fg)1221 START_TEST(touch_palm_detect_tool_palm_2fg)
1222 {
1223 struct litest_device *dev = litest_current_device();
1224 struct libinput *li = dev->libinput;
1225 struct axis_replacement axes[] = {
1226 { ABS_MT_TOOL_TYPE, MT_TOOL_PALM },
1227 { -1, 0 }
1228 };
1229
1230 if (!touch_has_tool_palm(dev))
1231 return;
1232
1233 litest_touch_down(dev, 0, 50, 50);
1234 litest_touch_down(dev, 1, 50, 50);
1235 litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10);
1236 litest_drain_events(li);
1237
1238 litest_touch_move_to_extended(dev, 0, 50, 50, 70, 70, axes, 10);
1239 libinput_dispatch(li);
1240 litest_assert_touch_cancel(li);
1241
1242 litest_touch_move_to(dev, 1, 50, 50, 70, 70, 10);
1243 libinput_dispatch(li);
1244 litest_assert_touch_motion_frame(li);
1245
1246 litest_touch_up(dev, 1);
1247 libinput_dispatch(li);
1248 litest_assert_touch_up_frame(li);
1249
1250 litest_touch_move_to(dev, 0, 70, 70, 50, 40, 10);
1251 litest_touch_up(dev, 0);
1252
1253 litest_assert_empty_queue(li);
1254 }
1255 END_TEST
1256
START_TEST(touch_palm_detect_tool_palm_on_off_2fg)1257 START_TEST(touch_palm_detect_tool_palm_on_off_2fg)
1258 {
1259 struct litest_device *dev = litest_current_device();
1260 struct libinput *li = dev->libinput;
1261 struct axis_replacement axes[] = {
1262 { ABS_MT_TOOL_TYPE, MT_TOOL_PALM },
1263 { -1, 0 }
1264 };
1265
1266 if (!touch_has_tool_palm(dev))
1267 return;
1268
1269 litest_touch_down(dev, 0, 50, 50);
1270 litest_touch_down(dev, 1, 50, 50);
1271 litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10);
1272 litest_drain_events(li);
1273
1274 litest_touch_move_to_extended(dev, 0, 50, 50, 70, 70, axes, 10);
1275 libinput_dispatch(li);
1276 litest_assert_touch_cancel(li);
1277
1278 litest_touch_move_to(dev, 1, 50, 50, 70, 70, 10);
1279 libinput_dispatch(li);
1280 litest_assert_touch_motion_frame(li);
1281
1282 litest_axis_set_value(axes, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
1283 litest_touch_move_to_extended(dev, 0, 50, 40, 70, 70, axes, 10);
1284 litest_assert_empty_queue(li);
1285
1286 litest_touch_move_to(dev, 1, 70, 70, 50, 40, 10);
1287 libinput_dispatch(li);
1288 litest_assert_touch_motion_frame(li);
1289
1290 litest_touch_up(dev, 1);
1291 libinput_dispatch(li);
1292 litest_assert_touch_up_frame(li);
1293
1294 litest_touch_move_to(dev, 0, 70, 70, 50, 40, 10);
1295 litest_touch_up(dev, 0);
1296
1297 litest_assert_empty_queue(li);
1298 }
1299 END_TEST
1300
START_TEST(touch_palm_detect_tool_palm_keep_type_2fg)1301 START_TEST(touch_palm_detect_tool_palm_keep_type_2fg)
1302 {
1303 struct litest_device *dev = litest_current_device();
1304 struct libinput *li = dev->libinput;
1305 struct axis_replacement axes[] = {
1306 { ABS_MT_TOOL_TYPE, MT_TOOL_PALM },
1307 { -1, 0 }
1308 };
1309
1310 if (!touch_has_tool_palm(dev))
1311 return;
1312
1313 litest_touch_down(dev, 0, 50, 50);
1314 litest_touch_down(dev, 1, 50, 50);
1315 litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10);
1316 litest_touch_move_to_extended(dev, 0, 50, 50, 70, 70, axes, 10);
1317 litest_touch_up(dev, 0);
1318 litest_drain_events(li);
1319
1320 litest_touch_move_to(dev, 1, 50, 50, 70, 70, 10);
1321 libinput_dispatch(li);
1322 litest_assert_touch_motion_frame(li);
1323
1324 /* ABS_MT_TOOL_TYPE never reset to finger, so a new touch
1325 should be ignored outright */
1326 litest_touch_down_extended(dev, 0, 50, 50, axes);
1327
1328 /* Test the revert to finger case too */
1329 litest_axis_set_value(axes, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
1330 litest_touch_move_to(dev, 0, 70, 70, 50, 40, 10);
1331 litest_touch_up(dev, 0);
1332
1333 litest_assert_empty_queue(li);
1334
1335 litest_touch_up(dev, 1);
1336 libinput_dispatch(li);
1337 litest_assert_touch_up_frame(li);
1338 }
1339 END_TEST
1340
TEST_COLLECTION(touch)1341 TEST_COLLECTION(touch)
1342 {
1343 struct range axes = { ABS_X, ABS_Y + 1};
1344
1345 litest_add("touch:frame", touch_frame_events, LITEST_TOUCH, LITEST_ANY);
1346 litest_add("touch:down", touch_downup_no_motion, LITEST_TOUCH, LITEST_ANY);
1347 litest_add("touch:down", touch_downup_no_motion, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1348 litest_add_no_device("touch:abs-transform", touch_abs_transform);
1349 litest_add("touch:slots", touch_seat_slot, LITEST_TOUCH, LITEST_TOUCHPAD);
1350 litest_add_no_device("touch:slots", touch_many_slots);
1351 litest_add("touch:double-touch-down-up", touch_double_touch_down_up, LITEST_TOUCH, LITEST_PROTOCOL_A);
1352 litest_add("touch:calibration", touch_calibration_scale, LITEST_TOUCH, LITEST_TOUCHPAD);
1353 litest_add("touch:calibration", touch_calibration_scale, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1354 litest_add("touch:calibration", touch_calibration_rotation, LITEST_TOUCH, LITEST_TOUCHPAD);
1355 litest_add("touch:calibration", touch_calibration_rotation, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1356 litest_add("touch:calibration", touch_calibration_translation, LITEST_TOUCH, LITEST_TOUCHPAD);
1357 litest_add("touch:calibration", touch_calibration_translation, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1358 litest_add_for_device("touch:calibration", touch_calibrated_screen_path, LITEST_CALIBRATED_TOUCHSCREEN);
1359 litest_add_for_device("touch:calibration", touch_calibrated_screen_udev, LITEST_CALIBRATED_TOUCHSCREEN);
1360 litest_add("touch:calibration", touch_calibration_config, LITEST_TOUCH, LITEST_ANY);
1361
1362 litest_add("touch:left-handed", touch_no_left_handed, LITEST_TOUCH, LITEST_ANY);
1363
1364 litest_add("touch:fake-mt", fake_mt_exists, LITEST_FAKE_MT, LITEST_ANY);
1365 litest_add("touch:fake-mt", fake_mt_no_touch_events, LITEST_FAKE_MT, LITEST_ANY);
1366
1367 litest_add("touch:protocol a", touch_protocol_a_init, LITEST_PROTOCOL_A, LITEST_ANY);
1368 litest_add("touch:protocol a", touch_protocol_a_touch, LITEST_PROTOCOL_A, LITEST_ANY);
1369 litest_add("touch:protocol a", touch_protocol_a_2fg_touch, LITEST_PROTOCOL_A, LITEST_ANY);
1370
1371 litest_add_ranged("touch:state", touch_initial_state, LITEST_TOUCH, LITEST_PROTOCOL_A, &axes);
1372
1373 litest_add("touch:time", touch_time_usec, LITEST_TOUCH, LITEST_TOUCHPAD);
1374
1375 litest_add_for_device("touch:fuzz", touch_fuzz, LITEST_MULTITOUCH_FUZZ_SCREEN);
1376 litest_add_for_device("touch:fuzz", touch_fuzz_property, LITEST_MULTITOUCH_FUZZ_SCREEN);
1377
1378 litest_add_no_device("touch:release", touch_release_on_unplug);
1379
1380 litest_add_for_device("touch:range", touch_invalid_range_over, LITEST_TOUCHSCREEN_INVALID_RANGE);
1381 litest_add_for_device("touch:range", touch_invalid_range_under, LITEST_TOUCHSCREEN_INVALID_RANGE);
1382
1383 litest_add("touch:count", touch_count_st, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1384 litest_add("touch:count", touch_count_mt, LITEST_TOUCH, LITEST_SINGLE_TOUCH|LITEST_PROTOCOL_A);
1385 litest_add("touch:count", touch_count_unknown, LITEST_PROTOCOL_A, LITEST_ANY);
1386 litest_add("touch:count", touch_count_invalid, LITEST_ANY, LITEST_TOUCH|LITEST_SINGLE_TOUCH|LITEST_PROTOCOL_A);
1387
1388 litest_add("touch:tool", touch_palm_detect_tool_palm, LITEST_TOUCH, LITEST_ANY);
1389 litest_add("touch:tool", touch_palm_detect_tool_palm_on_off, LITEST_TOUCH, LITEST_ANY);
1390 litest_add("touch:tool", touch_palm_detect_tool_palm_keep_type, LITEST_TOUCH, LITEST_ANY);
1391 litest_add("touch:tool", touch_palm_detect_tool_palm_2fg, LITEST_TOUCH, LITEST_SINGLE_TOUCH);
1392 litest_add("touch:tool", touch_palm_detect_tool_palm_on_off_2fg, LITEST_TOUCH, LITEST_SINGLE_TOUCH);
1393 litest_add("touch:tool", touch_palm_detect_tool_palm_keep_type_2fg, LITEST_TOUCH, LITEST_ANY);
1394 }
1395