1 /*
2 * Copyright © 2015 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 <libinput.h>
28
29 #include "libinput-util.h"
30 #include "litest.h"
31
32 enum cardinal {
33 N, NE, E, SE, S, SW, W, NW, NCARDINALS
34 };
35
START_TEST(gestures_cap)36 START_TEST(gestures_cap)
37 {
38 struct litest_device *dev = litest_current_device();
39 struct libinput_device *device = dev->libinput_device;
40
41 if (libevdev_has_property(dev->evdev, INPUT_PROP_SEMI_MT))
42 ck_assert(!libinput_device_has_capability(device,
43 LIBINPUT_DEVICE_CAP_GESTURE));
44 else
45 ck_assert(libinput_device_has_capability(device,
46 LIBINPUT_DEVICE_CAP_GESTURE));
47 }
48 END_TEST
49
START_TEST(gestures_nocap)50 START_TEST(gestures_nocap)
51 {
52 struct litest_device *dev = litest_current_device();
53 struct libinput_device *device = dev->libinput_device;
54
55 ck_assert(!libinput_device_has_capability(device,
56 LIBINPUT_DEVICE_CAP_GESTURE));
57 }
58 END_TEST
59
START_TEST(gestures_swipe_3fg)60 START_TEST(gestures_swipe_3fg)
61 {
62 struct litest_device *dev = litest_current_device();
63 struct libinput *li = dev->libinput;
64 struct libinput_event *event;
65 struct libinput_event_gesture *gevent;
66 double dx, dy;
67 int cardinal = _i; /* ranged test */
68 double dir_x, dir_y;
69 int cardinals[NCARDINALS][2] = {
70 { 0, 30 },
71 { 30, 30 },
72 { 30, 0 },
73 { 30, -30 },
74 { 0, -30 },
75 { -30, -30 },
76 { -30, 0 },
77 { -30, 30 },
78 };
79
80 if (litest_slot_count(dev) < 3)
81 return;
82
83 dir_x = cardinals[cardinal][0];
84 dir_y = cardinals[cardinal][1];
85
86 litest_drain_events(li);
87
88 litest_touch_down(dev, 0, 40, 40);
89 litest_touch_down(dev, 1, 50, 40);
90 litest_touch_down(dev, 2, 60, 40);
91 libinput_dispatch(li);
92 litest_touch_move_three_touches(dev, 40, 40, 50, 40, 60, 40, dir_x,
93 dir_y, 10);
94 libinput_dispatch(li);
95
96 event = libinput_get_event(li);
97 gevent = litest_is_gesture_event(event,
98 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
99 3);
100 dx = libinput_event_gesture_get_dx(gevent);
101 dy = libinput_event_gesture_get_dy(gevent);
102 ck_assert(dx == 0.0);
103 ck_assert(dy == 0.0);
104 libinput_event_destroy(event);
105
106 while ((event = libinput_get_event(li)) != NULL) {
107 gevent = litest_is_gesture_event(event,
108 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
109 3);
110
111 dx = libinput_event_gesture_get_dx(gevent);
112 dy = libinput_event_gesture_get_dy(gevent);
113 if (dir_x == 0.0)
114 ck_assert(dx == 0.0);
115 else if (dir_x < 0.0)
116 ck_assert(dx < 0.0);
117 else if (dir_x > 0.0)
118 ck_assert(dx > 0.0);
119
120 if (dir_y == 0.0)
121 ck_assert(dy == 0.0);
122 else if (dir_y < 0.0)
123 ck_assert(dy < 0.0);
124 else if (dir_y > 0.0)
125 ck_assert(dy > 0.0);
126
127 dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
128 dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
129 if (dir_x == 0.0)
130 ck_assert(dx == 0.0);
131 else if (dir_x < 0.0)
132 ck_assert(dx < 0.0);
133 else if (dir_x > 0.0)
134 ck_assert(dx > 0.0);
135
136 if (dir_y == 0.0)
137 ck_assert(dy == 0.0);
138 else if (dir_y < 0.0)
139 ck_assert(dy < 0.0);
140 else if (dir_y > 0.0)
141 ck_assert(dy > 0.0);
142
143 libinput_event_destroy(event);
144 }
145
146 litest_touch_up(dev, 0);
147 litest_touch_up(dev, 1);
148 litest_touch_up(dev, 2);
149 libinput_dispatch(li);
150 event = libinput_get_event(li);
151 gevent = litest_is_gesture_event(event,
152 LIBINPUT_EVENT_GESTURE_SWIPE_END,
153 3);
154 ck_assert(!libinput_event_gesture_get_cancelled(gevent));
155 libinput_event_destroy(event);
156 }
157 END_TEST
158
START_TEST(gestures_swipe_3fg_btntool)159 START_TEST(gestures_swipe_3fg_btntool)
160 {
161 struct litest_device *dev = litest_current_device();
162 struct libinput *li = dev->libinput;
163 struct libinput_event *event;
164 struct libinput_event_gesture *gevent;
165 double dx, dy;
166 int cardinal = _i; /* ranged test */
167 double dir_x, dir_y;
168 int cardinals[NCARDINALS][2] = {
169 { 0, 30 },
170 { 30, 30 },
171 { 30, 0 },
172 { 30, -30 },
173 { 0, -30 },
174 { -30, -30 },
175 { -30, 0 },
176 { -30, 30 },
177 };
178
179 if (litest_slot_count(dev) > 2 ||
180 !libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP) ||
181 !libinput_device_has_capability(dev->libinput_device,
182 LIBINPUT_DEVICE_CAP_GESTURE))
183 return;
184
185 dir_x = cardinals[cardinal][0];
186 dir_y = cardinals[cardinal][1];
187
188 litest_drain_events(li);
189
190 litest_touch_down(dev, 0, 40, 40);
191 litest_touch_down(dev, 1, 50, 40);
192 litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
193 litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
194 litest_event(dev, EV_SYN, SYN_REPORT, 0);
195
196 libinput_dispatch(li);
197 litest_touch_move_two_touches(dev, 40, 40, 50, 40, dir_x, dir_y, 10);
198 libinput_dispatch(li);
199
200 event = libinput_get_event(li);
201 gevent = litest_is_gesture_event(event,
202 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
203 3);
204 dx = libinput_event_gesture_get_dx(gevent);
205 dy = libinput_event_gesture_get_dy(gevent);
206 ck_assert(dx == 0.0);
207 ck_assert(dy == 0.0);
208 libinput_event_destroy(event);
209
210 while ((event = libinput_get_event(li)) != NULL) {
211 gevent = litest_is_gesture_event(event,
212 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
213 3);
214
215 dx = libinput_event_gesture_get_dx(gevent);
216 dy = libinput_event_gesture_get_dy(gevent);
217 if (dir_x == 0.0)
218 ck_assert(dx == 0.0);
219 else if (dir_x < 0.0)
220 ck_assert(dx < 0.0);
221 else if (dir_x > 0.0)
222 ck_assert(dx > 0.0);
223
224 if (dir_y == 0.0)
225 ck_assert(dy == 0.0);
226 else if (dir_y < 0.0)
227 ck_assert(dy < 0.0);
228 else if (dir_y > 0.0)
229 ck_assert(dy > 0.0);
230
231 dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
232 dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
233 if (dir_x == 0.0)
234 ck_assert(dx == 0.0);
235 else if (dir_x < 0.0)
236 ck_assert(dx < 0.0);
237 else if (dir_x > 0.0)
238 ck_assert(dx > 0.0);
239
240 if (dir_y == 0.0)
241 ck_assert(dy == 0.0);
242 else if (dir_y < 0.0)
243 ck_assert(dy < 0.0);
244 else if (dir_y > 0.0)
245 ck_assert(dy > 0.0);
246
247 libinput_event_destroy(event);
248 }
249
250 litest_touch_up(dev, 0);
251 litest_touch_up(dev, 1);
252 libinput_dispatch(li);
253 event = libinput_get_event(li);
254 gevent = litest_is_gesture_event(event,
255 LIBINPUT_EVENT_GESTURE_SWIPE_END,
256 3);
257 ck_assert(!libinput_event_gesture_get_cancelled(gevent));
258 libinput_event_destroy(event);
259 }
260 END_TEST
261
START_TEST(gestures_swipe_3fg_btntool_pinch_like)262 START_TEST(gestures_swipe_3fg_btntool_pinch_like)
263 {
264 struct litest_device *dev = litest_current_device();
265 struct libinput *li = dev->libinput;
266 struct libinput_event *event;
267 struct libinput_event_gesture *gevent;
268
269 if (litest_slot_count(dev) > 2 ||
270 !libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP) ||
271 !libinput_device_has_capability(dev->libinput_device,
272 LIBINPUT_DEVICE_CAP_GESTURE))
273 return;
274
275 litest_drain_events(li);
276
277 /* Technically a pinch position + pinch movement, but expect swipe
278 * for nfingers > nslots */
279 litest_touch_down(dev, 0, 20, 60);
280 litest_touch_down(dev, 1, 50, 20);
281 litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
282 litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
283 litest_event(dev, EV_SYN, SYN_REPORT, 0);
284
285 libinput_dispatch(li);
286 litest_touch_move_to(dev, 0, 20, 60, 10, 80, 20);
287 libinput_dispatch(li);
288
289 event = libinput_get_event(li);
290 litest_is_gesture_event(event, LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 3);
291 libinput_event_destroy(event);
292
293 while ((event = libinput_get_event(li)) != NULL) {
294 litest_is_gesture_event(event,
295 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
296 3);
297 libinput_event_destroy(event);
298 }
299
300 litest_touch_up(dev, 0);
301 litest_touch_up(dev, 1);
302 libinput_dispatch(li);
303 event = libinput_get_event(li);
304 gevent = litest_is_gesture_event(event,
305 LIBINPUT_EVENT_GESTURE_SWIPE_END,
306 3);
307 ck_assert(!libinput_event_gesture_get_cancelled(gevent));
308 libinput_event_destroy(event);
309 }
310 END_TEST
311
START_TEST(gestures_swipe_4fg)312 START_TEST(gestures_swipe_4fg)
313 {
314 struct litest_device *dev = litest_current_device();
315 struct libinput *li = dev->libinput;
316 struct libinput_event *event;
317 struct libinput_event_gesture *gevent;
318 double dx, dy;
319 int cardinal = _i; /* ranged test */
320 double dir_x, dir_y;
321 int cardinals[NCARDINALS][2] = {
322 { 0, 3 },
323 { 3, 3 },
324 { 3, 0 },
325 { 3, -3 },
326 { 0, -3 },
327 { -3, -3 },
328 { -3, 0 },
329 { -3, 3 },
330 };
331 int i;
332
333 if (litest_slot_count(dev) < 4)
334 return;
335
336 dir_x = cardinals[cardinal][0];
337 dir_y = cardinals[cardinal][1];
338
339 litest_drain_events(li);
340
341 litest_touch_down(dev, 0, 40, 40);
342 litest_touch_down(dev, 1, 50, 40);
343 litest_touch_down(dev, 2, 60, 40);
344 litest_touch_down(dev, 3, 70, 40);
345 libinput_dispatch(li);
346
347 for (i = 0; i < 8; i++) {
348 litest_push_event_frame(dev);
349
350 dir_x += cardinals[cardinal][0];
351 dir_y += cardinals[cardinal][1];
352
353 litest_touch_move(dev,
354 0,
355 40 + dir_x,
356 40 + dir_y);
357 litest_touch_move(dev,
358 1,
359 50 + dir_x,
360 40 + dir_y);
361 litest_touch_move(dev,
362 2,
363 60 + dir_x,
364 40 + dir_y);
365 litest_touch_move(dev,
366 3,
367 70 + dir_x,
368 40 + dir_y);
369 litest_pop_event_frame(dev);
370 libinput_dispatch(li);
371 }
372
373 libinput_dispatch(li);
374
375 event = libinput_get_event(li);
376 gevent = litest_is_gesture_event(event,
377 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
378 4);
379 dx = libinput_event_gesture_get_dx(gevent);
380 dy = libinput_event_gesture_get_dy(gevent);
381 ck_assert(dx == 0.0);
382 ck_assert(dy == 0.0);
383 libinput_event_destroy(event);
384
385 while ((event = libinput_get_event(li)) != NULL) {
386 gevent = litest_is_gesture_event(event,
387 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
388 4);
389
390 dx = libinput_event_gesture_get_dx(gevent);
391 dy = libinput_event_gesture_get_dy(gevent);
392 if (dir_x == 0.0)
393 ck_assert(dx == 0.0);
394 else if (dir_x < 0.0)
395 ck_assert(dx < 0.0);
396 else if (dir_x > 0.0)
397 ck_assert(dx > 0.0);
398
399 if (dir_y == 0.0)
400 ck_assert(dy == 0.0);
401 else if (dir_y < 0.0)
402 ck_assert(dy < 0.0);
403 else if (dir_y > 0.0)
404 ck_assert(dy > 0.0);
405
406 dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
407 dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
408 if (dir_x == 0.0)
409 ck_assert(dx == 0.0);
410 else if (dir_x < 0.0)
411 ck_assert(dx < 0.0);
412 else if (dir_x > 0.0)
413 ck_assert(dx > 0.0);
414
415 if (dir_y == 0.0)
416 ck_assert(dy == 0.0);
417 else if (dir_y < 0.0)
418 ck_assert(dy < 0.0);
419 else if (dir_y > 0.0)
420 ck_assert(dy > 0.0);
421
422 libinput_event_destroy(event);
423 }
424
425 litest_touch_up(dev, 0);
426 litest_touch_up(dev, 1);
427 litest_touch_up(dev, 2);
428 litest_touch_up(dev, 3);
429 libinput_dispatch(li);
430 event = libinput_get_event(li);
431 gevent = litest_is_gesture_event(event,
432 LIBINPUT_EVENT_GESTURE_SWIPE_END,
433 4);
434 ck_assert(!libinput_event_gesture_get_cancelled(gevent));
435 libinput_event_destroy(event);
436 }
437 END_TEST
438
START_TEST(gestures_swipe_4fg_btntool)439 START_TEST(gestures_swipe_4fg_btntool)
440 {
441 struct litest_device *dev = litest_current_device();
442 struct libinput *li = dev->libinput;
443 struct libinput_event *event;
444 struct libinput_event_gesture *gevent;
445 double dx, dy;
446 int cardinal = _i; /* ranged test */
447 double dir_x, dir_y;
448 int cardinals[NCARDINALS][2] = {
449 { 0, 30 },
450 { 30, 30 },
451 { 30, 0 },
452 { 30, -30 },
453 { 0, -30 },
454 { -30, -30 },
455 { -30, 0 },
456 { -30, 30 },
457 };
458
459 if (litest_slot_count(dev) > 2 ||
460 !libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_QUADTAP) ||
461 !libinput_device_has_capability(dev->libinput_device,
462 LIBINPUT_DEVICE_CAP_GESTURE))
463 return;
464
465 dir_x = cardinals[cardinal][0];
466 dir_y = cardinals[cardinal][1];
467
468 litest_drain_events(li);
469
470 litest_touch_down(dev, 0, 40, 40);
471 litest_touch_down(dev, 1, 50, 40);
472 litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
473 litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 1);
474 litest_event(dev, EV_SYN, SYN_REPORT, 0);
475
476 libinput_dispatch(li);
477 litest_touch_move_two_touches(dev, 40, 40, 50, 40, dir_x, dir_y, 10);
478 libinput_dispatch(li);
479
480 event = libinput_get_event(li);
481 gevent = litest_is_gesture_event(event,
482 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
483 4);
484 dx = libinput_event_gesture_get_dx(gevent);
485 dy = libinput_event_gesture_get_dy(gevent);
486 ck_assert(dx == 0.0);
487 ck_assert(dy == 0.0);
488 libinput_event_destroy(event);
489
490 while ((event = libinput_get_event(li)) != NULL) {
491 gevent = litest_is_gesture_event(event,
492 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
493 4);
494
495 dx = libinput_event_gesture_get_dx(gevent);
496 dy = libinput_event_gesture_get_dy(gevent);
497 if (dir_x == 0.0)
498 ck_assert(dx == 0.0);
499 else if (dir_x < 0.0)
500 ck_assert(dx < 0.0);
501 else if (dir_x > 0.0)
502 ck_assert(dx > 0.0);
503
504 if (dir_y == 0.0)
505 ck_assert(dy == 0.0);
506 else if (dir_y < 0.0)
507 ck_assert(dy < 0.0);
508 else if (dir_y > 0.0)
509 ck_assert(dy > 0.0);
510
511 dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
512 dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
513 if (dir_x == 0.0)
514 ck_assert(dx == 0.0);
515 else if (dir_x < 0.0)
516 ck_assert(dx < 0.0);
517 else if (dir_x > 0.0)
518 ck_assert(dx > 0.0);
519
520 if (dir_y == 0.0)
521 ck_assert(dy == 0.0);
522 else if (dir_y < 0.0)
523 ck_assert(dy < 0.0);
524 else if (dir_y > 0.0)
525 ck_assert(dy > 0.0);
526
527 libinput_event_destroy(event);
528 }
529
530 litest_touch_up(dev, 0);
531 litest_touch_up(dev, 1);
532 libinput_dispatch(li);
533 event = libinput_get_event(li);
534 gevent = litest_is_gesture_event(event,
535 LIBINPUT_EVENT_GESTURE_SWIPE_END,
536 4);
537 ck_assert(!libinput_event_gesture_get_cancelled(gevent));
538 libinput_event_destroy(event);
539 }
540 END_TEST
541
START_TEST(gestures_pinch)542 START_TEST(gestures_pinch)
543 {
544 struct litest_device *dev = litest_current_device();
545 struct libinput *li = dev->libinput;
546 struct libinput_event *event;
547 struct libinput_event_gesture *gevent;
548 double dx, dy;
549 int cardinal = _i; /* ranged test */
550 double dir_x, dir_y;
551 int i;
552 double scale, oldscale;
553 double angle;
554 int cardinals[NCARDINALS][2] = {
555 { 0, 30 },
556 { 30, 30 },
557 { 30, 0 },
558 { 30, -30 },
559 { 0, -30 },
560 { -30, -30 },
561 { -30, 0 },
562 { -30, 30 },
563 };
564
565 if (litest_slot_count(dev) < 2 ||
566 !libinput_device_has_capability(dev->libinput_device,
567 LIBINPUT_DEVICE_CAP_GESTURE))
568 return;
569
570 /* If the device is too small to provide a finger spread wide enough
571 * to avoid the scroll bias, skip the test */
572 if (cardinal == E || cardinal == W) {
573 double w = 0, h = 0;
574 libinput_device_get_size(dev->libinput_device, &w, &h);
575 /* 0.6 because the code below gives us points like 20/y and
576 * 80/y. 45 because the threshold in the code is 40mm */
577 if (w * 0.6 < 45)
578 return;
579 }
580
581 dir_x = cardinals[cardinal][0];
582 dir_y = cardinals[cardinal][1];
583
584 litest_drain_events(li);
585
586 litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
587 litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
588 libinput_dispatch(li);
589
590 for (i = 0; i < 8; i++) {
591 litest_push_event_frame(dev);
592 if (dir_x > 0.0)
593 dir_x -= 2;
594 else if (dir_x < 0.0)
595 dir_x += 2;
596 if (dir_y > 0.0)
597 dir_y -= 2;
598 else if (dir_y < 0.0)
599 dir_y += 2;
600 litest_touch_move(dev,
601 0,
602 50 + dir_x,
603 50 + dir_y);
604 litest_touch_move(dev,
605 1,
606 50 - dir_x,
607 50 - dir_y);
608 litest_pop_event_frame(dev);
609 libinput_dispatch(li);
610 }
611
612 event = libinput_get_event(li);
613 gevent = litest_is_gesture_event(event,
614 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
615 2);
616 dx = libinput_event_gesture_get_dx(gevent);
617 dy = libinput_event_gesture_get_dy(gevent);
618 scale = libinput_event_gesture_get_scale(gevent);
619 ck_assert(dx == 0.0);
620 ck_assert(dy == 0.0);
621 ck_assert(scale == 1.0);
622
623 libinput_event_destroy(event);
624
625 while ((event = libinput_get_event(li)) != NULL) {
626 gevent = litest_is_gesture_event(event,
627 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
628 2);
629
630 oldscale = scale;
631 scale = libinput_event_gesture_get_scale(gevent);
632
633 ck_assert(scale < oldscale);
634
635 angle = libinput_event_gesture_get_angle_delta(gevent);
636 ck_assert_double_le(fabs(angle), 1.0);
637
638 libinput_event_destroy(event);
639 libinput_dispatch(li);
640 }
641
642 litest_touch_up(dev, 0);
643 litest_touch_up(dev, 1);
644 libinput_dispatch(li);
645 event = libinput_get_event(li);
646 gevent = litest_is_gesture_event(event,
647 LIBINPUT_EVENT_GESTURE_PINCH_END,
648 2);
649 ck_assert(!libinput_event_gesture_get_cancelled(gevent));
650 libinput_event_destroy(event);
651 }
652 END_TEST
653
START_TEST(gestures_pinch_3fg)654 START_TEST(gestures_pinch_3fg)
655 {
656 struct litest_device *dev = litest_current_device();
657 struct libinput *li = dev->libinput;
658 struct libinput_event *event;
659 struct libinput_event_gesture *gevent;
660 double dx, dy;
661 int cardinal = _i; /* ranged test */
662 double dir_x, dir_y;
663 int i;
664 double scale, oldscale;
665 double angle;
666 int cardinals[NCARDINALS][2] = {
667 { 0, 30 },
668 { 30, 30 },
669 { 30, 0 },
670 { 30, -30 },
671 { 0, -30 },
672 { -30, -30 },
673 { -30, 0 },
674 { -30, 30 },
675 };
676
677 if (litest_slot_count(dev) < 3)
678 return;
679
680 dir_x = cardinals[cardinal][0];
681 dir_y = cardinals[cardinal][1];
682
683 litest_drain_events(li);
684
685 litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
686 litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
687 litest_touch_down(dev, 2, 51 - dir_x, 51 - dir_y);
688 libinput_dispatch(li);
689
690 for (i = 0; i < 8; i++) {
691 litest_push_event_frame(dev);
692 if (dir_x > 0.0)
693 dir_x -= 2;
694 else if (dir_x < 0.0)
695 dir_x += 2;
696 if (dir_y > 0.0)
697 dir_y -= 2;
698 else if (dir_y < 0.0)
699 dir_y += 2;
700 litest_touch_move(dev,
701 0,
702 50 + dir_x,
703 50 + dir_y);
704 litest_touch_move(dev,
705 1,
706 50 - dir_x,
707 50 - dir_y);
708 litest_touch_move(dev,
709 2,
710 51 - dir_x,
711 51 - dir_y);
712 litest_pop_event_frame(dev);
713 libinput_dispatch(li);
714 }
715
716 event = libinput_get_event(li);
717 gevent = litest_is_gesture_event(event,
718 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
719 3);
720 dx = libinput_event_gesture_get_dx(gevent);
721 dy = libinput_event_gesture_get_dy(gevent);
722 scale = libinput_event_gesture_get_scale(gevent);
723 ck_assert(dx == 0.0);
724 ck_assert(dy == 0.0);
725 ck_assert(scale == 1.0);
726
727 libinput_event_destroy(event);
728
729 while ((event = libinput_get_event(li)) != NULL) {
730 gevent = litest_is_gesture_event(event,
731 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
732 3);
733
734 oldscale = scale;
735 scale = libinput_event_gesture_get_scale(gevent);
736
737 ck_assert(scale < oldscale);
738
739 angle = libinput_event_gesture_get_angle_delta(gevent);
740 ck_assert_double_le(fabs(angle), 1.0);
741
742 libinput_event_destroy(event);
743 libinput_dispatch(li);
744 }
745
746 litest_touch_up(dev, 0);
747 litest_touch_up(dev, 1);
748 litest_touch_up(dev, 2);
749 libinput_dispatch(li);
750 event = libinput_get_event(li);
751 gevent = litest_is_gesture_event(event,
752 LIBINPUT_EVENT_GESTURE_PINCH_END,
753 3);
754 ck_assert(!libinput_event_gesture_get_cancelled(gevent));
755 libinput_event_destroy(event);
756 }
757 END_TEST
758
START_TEST(gestures_pinch_4fg)759 START_TEST(gestures_pinch_4fg)
760 {
761 struct litest_device *dev = litest_current_device();
762 struct libinput *li = dev->libinput;
763 struct libinput_event *event;
764 struct libinput_event_gesture *gevent;
765 double dx, dy;
766 int cardinal = _i; /* ranged test */
767 double dir_x, dir_y;
768 int i;
769 double scale, oldscale;
770 double angle;
771 int cardinals[NCARDINALS][2] = {
772 { 0, 30 },
773 { 30, 30 },
774 { 30, 0 },
775 { 30, -30 },
776 { 0, -30 },
777 { -30, -30 },
778 { -30, 0 },
779 { -30, 30 },
780 };
781
782 if (litest_slot_count(dev) < 4)
783 return;
784
785 dir_x = cardinals[cardinal][0];
786 dir_y = cardinals[cardinal][1];
787
788 litest_drain_events(li);
789
790 litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
791 litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
792 litest_touch_down(dev, 2, 51 - dir_x, 51 - dir_y);
793 litest_touch_down(dev, 3, 52 - dir_x, 52 - dir_y);
794 libinput_dispatch(li);
795
796 for (i = 0; i < 7; i++) {
797 litest_push_event_frame(dev);
798 if (dir_x > 0.0)
799 dir_x -= 2;
800 else if (dir_x < 0.0)
801 dir_x += 2;
802 if (dir_y > 0.0)
803 dir_y -= 2;
804 else if (dir_y < 0.0)
805 dir_y += 2;
806 litest_touch_move(dev,
807 0,
808 50 + dir_x,
809 50 + dir_y);
810 litest_touch_move(dev,
811 1,
812 50 - dir_x,
813 50 - dir_y);
814 litest_touch_move(dev,
815 2,
816 51 - dir_x,
817 51 - dir_y);
818 litest_touch_move(dev,
819 3,
820 52 - dir_x,
821 52 - dir_y);
822 litest_pop_event_frame(dev);
823 libinput_dispatch(li);
824 }
825
826 event = libinput_get_event(li);
827 gevent = litest_is_gesture_event(event,
828 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
829 4);
830 dx = libinput_event_gesture_get_dx(gevent);
831 dy = libinput_event_gesture_get_dy(gevent);
832 scale = libinput_event_gesture_get_scale(gevent);
833 ck_assert(dx == 0.0);
834 ck_assert(dy == 0.0);
835 ck_assert(scale == 1.0);
836
837 libinput_event_destroy(event);
838
839 while ((event = libinput_get_event(li)) != NULL) {
840 gevent = litest_is_gesture_event(event,
841 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
842 4);
843
844 oldscale = scale;
845 scale = libinput_event_gesture_get_scale(gevent);
846
847 ck_assert(scale < oldscale);
848
849 angle = libinput_event_gesture_get_angle_delta(gevent);
850 ck_assert_double_le(fabs(angle), 1.0);
851
852 libinput_event_destroy(event);
853 libinput_dispatch(li);
854 }
855
856 litest_touch_up(dev, 0);
857 litest_touch_up(dev, 1);
858 litest_touch_up(dev, 2);
859 litest_touch_up(dev, 3);
860 libinput_dispatch(li);
861 event = libinput_get_event(li);
862 gevent = litest_is_gesture_event(event,
863 LIBINPUT_EVENT_GESTURE_PINCH_END,
864 4);
865 ck_assert(!libinput_event_gesture_get_cancelled(gevent));
866 libinput_event_destroy(event);
867 }
868 END_TEST
869
START_TEST(gestures_spread)870 START_TEST(gestures_spread)
871 {
872 struct litest_device *dev = litest_current_device();
873 struct libinput *li = dev->libinput;
874 struct libinput_event *event;
875 struct libinput_event_gesture *gevent;
876 double dx, dy;
877 int cardinal = _i; /* ranged test */
878 double dir_x, dir_y;
879 int i;
880 double scale, oldscale;
881 double angle;
882 int cardinals[NCARDINALS][2] = {
883 { 0, 30 },
884 { 30, 30 },
885 { 30, 0 },
886 { 30, -30 },
887 { 0, -30 },
888 { -30, -30 },
889 { -30, 0 },
890 { -30, 30 },
891 };
892
893 if (litest_slot_count(dev) < 2 ||
894 !libinput_device_has_capability(dev->libinput_device,
895 LIBINPUT_DEVICE_CAP_GESTURE))
896 return;
897
898 /* If the device is too small to provide a finger spread wide enough
899 * to avoid the scroll bias, skip the test */
900 if (cardinal == E || cardinal == W) {
901 double w = 0, h = 0;
902 libinput_device_get_size(dev->libinput_device, &w, &h);
903 /* 0.6 because the code below gives us points like 20/y and
904 * 80/y. 45 because the threshold in the code is 40mm */
905 if (w * 0.6 < 45)
906 return;
907 }
908
909 dir_x = cardinals[cardinal][0];
910 dir_y = cardinals[cardinal][1];
911
912 litest_drain_events(li);
913
914 litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
915 litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
916 libinput_dispatch(li);
917
918 for (i = 0; i < 15; i++) {
919 litest_push_event_frame(dev);
920 if (dir_x > 0.0)
921 dir_x += 1;
922 else if (dir_x < 0.0)
923 dir_x -= 1;
924 if (dir_y > 0.0)
925 dir_y += 1;
926 else if (dir_y < 0.0)
927 dir_y -= 1;
928 litest_touch_move(dev,
929 0,
930 50 + dir_x,
931 50 + dir_y);
932 litest_touch_move(dev,
933 1,
934 50 - dir_x,
935 50 - dir_y);
936 litest_pop_event_frame(dev);
937 libinput_dispatch(li);
938 }
939
940 event = libinput_get_event(li);
941 gevent = litest_is_gesture_event(event,
942 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
943 2);
944 dx = libinput_event_gesture_get_dx(gevent);
945 dy = libinput_event_gesture_get_dy(gevent);
946 scale = libinput_event_gesture_get_scale(gevent);
947 ck_assert(dx == 0.0);
948 ck_assert(dy == 0.0);
949 ck_assert(scale == 1.0);
950
951 libinput_event_destroy(event);
952
953 while ((event = libinput_get_event(li)) != NULL) {
954 gevent = litest_is_gesture_event(event,
955 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
956 2);
957 oldscale = scale;
958 scale = libinput_event_gesture_get_scale(gevent);
959 ck_assert(scale > oldscale);
960
961 angle = libinput_event_gesture_get_angle_delta(gevent);
962 ck_assert_double_le(fabs(angle), 1.0);
963
964 libinput_event_destroy(event);
965 libinput_dispatch(li);
966 }
967
968 litest_touch_up(dev, 0);
969 litest_touch_up(dev, 1);
970 libinput_dispatch(li);
971 event = libinput_get_event(li);
972 gevent = litest_is_gesture_event(event,
973 LIBINPUT_EVENT_GESTURE_PINCH_END,
974 2);
975 ck_assert(!libinput_event_gesture_get_cancelled(gevent));
976 libinput_event_destroy(event);
977 }
978 END_TEST
979
START_TEST(gestures_time_usec)980 START_TEST(gestures_time_usec)
981 {
982 struct litest_device *dev = litest_current_device();
983 struct libinput *li = dev->libinput;
984 struct libinput_event *event;
985 struct libinput_event_gesture *gevent;
986 uint64_t time_usec;
987
988 if (litest_slot_count(dev) < 3)
989 return;
990
991 litest_drain_events(li);
992
993 litest_touch_down(dev, 0, 40, 40);
994 litest_touch_down(dev, 1, 50, 40);
995 litest_touch_down(dev, 2, 60, 40);
996 libinput_dispatch(li);
997 litest_touch_move_three_touches(dev, 40, 40, 50, 40, 60, 40, 0, 30,
998 30);
999
1000 libinput_dispatch(li);
1001 event = libinput_get_event(li);
1002 gevent = litest_is_gesture_event(event,
1003 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
1004 3);
1005 time_usec = libinput_event_gesture_get_time_usec(gevent);
1006 ck_assert_int_eq(libinput_event_gesture_get_time(gevent),
1007 (uint32_t) (time_usec / 1000));
1008 libinput_event_destroy(event);
1009 }
1010 END_TEST
1011
START_TEST(gestures_3fg_buttonarea_scroll)1012 START_TEST(gestures_3fg_buttonarea_scroll)
1013 {
1014 struct litest_device *dev = litest_current_device();
1015 struct libinput *li = dev->libinput;
1016
1017 if (litest_slot_count(dev) < 3)
1018 return;
1019
1020 litest_enable_buttonareas(dev);
1021 litest_enable_2fg_scroll(dev);
1022 litest_drain_events(li);
1023
1024 litest_touch_down(dev, 0, 40, 20);
1025 litest_touch_down(dev, 1, 30, 20);
1026 /* third finger in btnarea */
1027 litest_touch_down(dev, 2, 50, 99);
1028 libinput_dispatch(li);
1029 litest_touch_move_two_touches(dev, 40, 20, 30, 20, 0, 40, 10);
1030
1031 litest_touch_up(dev, 0);
1032 litest_touch_up(dev, 1);
1033 libinput_dispatch(li);
1034 litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
1035 }
1036 END_TEST
1037
START_TEST(gestures_3fg_buttonarea_scroll_btntool)1038 START_TEST(gestures_3fg_buttonarea_scroll_btntool)
1039 {
1040 struct litest_device *dev = litest_current_device();
1041 struct libinput *li = dev->libinput;
1042
1043 if (litest_slot_count(dev) > 2)
1044 return;
1045
1046 litest_enable_buttonareas(dev);
1047 litest_enable_2fg_scroll(dev);
1048 litest_drain_events(li);
1049
1050 /* first finger in btnarea */
1051 litest_touch_down(dev, 0, 20, 99);
1052 litest_touch_down(dev, 1, 30, 20);
1053 litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
1054 litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
1055 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1056 libinput_dispatch(li);
1057 litest_touch_move_to(dev, 1, 30, 20, 30, 70, 10);
1058
1059 litest_touch_up(dev, 1);
1060 libinput_dispatch(li);
1061 litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
1062 }
1063 END_TEST
1064
TEST_COLLECTION(gestures)1065 TEST_COLLECTION(gestures)
1066 {
1067 struct range cardinals = { N, N + NCARDINALS };
1068
1069 litest_add("gestures:cap", gestures_cap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
1070 litest_add("gestures:cap", gestures_nocap, LITEST_ANY, LITEST_TOUCHPAD);
1071
1072 litest_add_ranged("gestures:swipe", gestures_swipe_3fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
1073 litest_add_ranged("gestures:swipe", gestures_swipe_3fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
1074 litest_add("gestures:swipe", gestures_swipe_3fg_btntool_pinch_like, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
1075 litest_add_ranged("gestures:swipe", gestures_swipe_4fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
1076 litest_add_ranged("gestures:swipe", gestures_swipe_4fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
1077 litest_add_ranged("gestures:pinch", gestures_pinch, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
1078 litest_add_ranged("gestures:pinch", gestures_pinch_3fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
1079 litest_add_ranged("gestures:pinch", gestures_pinch_4fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
1080 litest_add_ranged("gestures:pinch", gestures_spread, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
1081
1082 litest_add("gestures:swipe", gestures_3fg_buttonarea_scroll, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH);
1083 litest_add("gestures:swipe", gestures_3fg_buttonarea_scroll_btntool, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH);
1084
1085 litest_add("gestures:time", gestures_time_usec, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
1086 }
1087