• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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