1 /*
2  * Copyright © 2016 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 <unistd.h>
31 #include <stdbool.h>
32 
33 #if HAVE_LIBWACOM
34 #include <libwacom/libwacom.h>
35 #endif
36 
37 #include "libinput-util.h"
38 #include "litest.h"
39 
START_TEST(pad_cap)40 START_TEST(pad_cap)
41 {
42 	struct litest_device *dev = litest_current_device();
43 	struct libinput_device *device = dev->libinput_device;
44 
45 	ck_assert(libinput_device_has_capability(device,
46 						 LIBINPUT_DEVICE_CAP_TABLET_PAD));
47 
48 }
49 END_TEST
50 
START_TEST(pad_no_cap)51 START_TEST(pad_no_cap)
52 {
53 	struct litest_device *dev = litest_current_device();
54 	struct libinput_device *device = dev->libinput_device;
55 
56 	ck_assert(!libinput_device_has_capability(device,
57 						  LIBINPUT_DEVICE_CAP_TABLET_PAD));
58 }
59 END_TEST
60 
START_TEST(pad_time)61 START_TEST(pad_time)
62 {
63 	struct litest_device *dev = litest_current_device();
64 	struct libinput *li = dev->libinput;
65 	struct libinput_event *ev;
66 	struct libinput_event_tablet_pad *pev;
67 	unsigned int code;
68 	uint64_t time, time_usec, oldtime;
69 
70 	litest_drain_events(li);
71 
72 	for (code = BTN_0; code < KEY_MAX; code++) {
73 		if (!libevdev_has_event_code(dev->evdev, EV_KEY, code))
74 			continue;
75 
76 		litest_button_click(dev, code, 1);
77 		litest_button_click(dev, code, 0);
78 		libinput_dispatch(li);
79 
80 		switch (code) {
81 		case BTN_STYLUS:
82 			litest_assert_empty_queue(li);
83 			continue;
84 		default:
85 			break;
86 		}
87 
88 		break;
89 	}
90 
91 	ev = libinput_get_event(li);
92 	ck_assert_int_eq(libinput_event_get_type(ev),
93 			 LIBINPUT_EVENT_TABLET_PAD_BUTTON);
94 	pev = libinput_event_get_tablet_pad_event(ev);
95 	time = libinput_event_tablet_pad_get_time(pev);
96 	time_usec = libinput_event_tablet_pad_get_time_usec(pev);
97 
98 	ck_assert(time != 0);
99 	ck_assert(time == time_usec/1000);
100 
101 	libinput_event_destroy(ev);
102 
103 	litest_drain_events(li);
104 	msleep(10);
105 
106 	litest_button_click(dev, code, 1);
107 	litest_button_click(dev, code, 0);
108 	libinput_dispatch(li);
109 
110 	ev = libinput_get_event(li);
111 	ck_assert_int_eq(libinput_event_get_type(ev),
112 			 LIBINPUT_EVENT_TABLET_PAD_BUTTON);
113 	pev = libinput_event_get_tablet_pad_event(ev);
114 
115 	oldtime = time;
116 	time = libinput_event_tablet_pad_get_time(pev);
117 	time_usec = libinput_event_tablet_pad_get_time_usec(pev);
118 
119 	ck_assert(time > oldtime);
120 	ck_assert(time != 0);
121 	ck_assert(time == time_usec/1000);
122 
123 	libinput_event_destroy(ev);
124 }
125 END_TEST
126 
START_TEST(pad_num_buttons_libwacom)127 START_TEST(pad_num_buttons_libwacom)
128 {
129 #if HAVE_LIBWACOM
130 	struct litest_device *dev = litest_current_device();
131 	struct libinput_device *device = dev->libinput_device;
132 	WacomDeviceDatabase *db = NULL;
133 	WacomDevice *wacom = NULL;
134 	unsigned int nb_lw, nb;
135 
136 	db = libwacom_database_new();
137 	ck_assert_notnull(db);
138 
139 	wacom = libwacom_new_from_usbid(db,
140 					libevdev_get_id_vendor(dev->evdev),
141 					libevdev_get_id_product(dev->evdev),
142 					NULL);
143 	ck_assert_notnull(wacom);
144 
145 	nb_lw = libwacom_get_num_buttons(wacom);
146 	nb = libinput_device_tablet_pad_get_num_buttons(device);
147 
148 	ck_assert_int_eq(nb, nb_lw);
149 
150 	libwacom_destroy(wacom);
151 	libwacom_database_destroy(db);
152 #endif
153 }
154 END_TEST
155 
START_TEST(pad_num_buttons)156 START_TEST(pad_num_buttons)
157 {
158 	struct litest_device *dev = litest_current_device();
159 	struct libinput_device *device = dev->libinput_device;
160 	unsigned int code;
161 	unsigned int nbuttons = 0;
162 
163 	for (code = BTN_0; code < KEY_MAX; code++) {
164 		/* BTN_STYLUS is set for compatibility reasons but not
165 		 * actually hooked up */
166 		if (code == BTN_STYLUS)
167 			continue;
168 
169 		if (libevdev_has_event_code(dev->evdev, EV_KEY, code))
170 			nbuttons++;
171 	}
172 
173 	ck_assert_int_eq(libinput_device_tablet_pad_get_num_buttons(device),
174 			 nbuttons);
175 }
176 END_TEST
177 
START_TEST(pad_button_intuos)178 START_TEST(pad_button_intuos)
179 {
180 #if !HAVE_LIBWACOM_GET_BUTTON_EVDEV_CODE
181 	struct litest_device *dev = litest_current_device();
182 	struct libinput *li = dev->libinput;
183 	unsigned int code;
184 	unsigned int expected_number = 0;
185 	struct libinput_event *ev;
186 	struct libinput_event_tablet_pad *pev;
187 	unsigned int count;
188 
189 	/* Intuos button mapping is sequential up from BTN_0 and continues
190 	 * with BTN_A */
191 	if (!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_0))
192 		return;
193 
194 	litest_drain_events(li);
195 
196 	for (code = BTN_0; code < BTN_DIGI; code++) {
197 		/* Skip over the BTN_MOUSE and BTN_JOYSTICK range */
198 		if ((code >= BTN_MOUSE && code < BTN_JOYSTICK) ||
199 		    (code >= BTN_DIGI)) {
200 			ck_assert(!libevdev_has_event_code(dev->evdev,
201 							   EV_KEY, code));
202 			continue;
203 		}
204 
205 		if (!libevdev_has_event_code(dev->evdev, EV_KEY, code))
206 			continue;
207 
208 		litest_button_click(dev, code, 1);
209 		litest_button_click(dev, code, 0);
210 		libinput_dispatch(li);
211 
212 		count++;
213 
214 		ev = libinput_get_event(li);
215 		pev = litest_is_pad_button_event(ev,
216 						 expected_number,
217 						 LIBINPUT_BUTTON_STATE_PRESSED);
218 		ev = libinput_event_tablet_pad_get_base_event(pev);
219 		libinput_event_destroy(ev);
220 
221 		ev = libinput_get_event(li);
222 		pev = litest_is_pad_button_event(ev,
223 						 expected_number,
224 						 LIBINPUT_BUTTON_STATE_RELEASED);
225 		ev = libinput_event_tablet_pad_get_base_event(pev);
226 		libinput_event_destroy(ev);
227 
228 		expected_number++;
229 	}
230 
231 	litest_assert_empty_queue(li);
232 
233 	ck_assert_int_gt(count, 3);
234 #endif
235 }
236 END_TEST
237 
START_TEST(pad_button_bamboo)238 START_TEST(pad_button_bamboo)
239 {
240 #if !HAVE_LIBWACOM_GET_BUTTON_EVDEV_CODE
241 	struct litest_device *dev = litest_current_device();
242 	struct libinput *li = dev->libinput;
243 	unsigned int code;
244 	unsigned int expected_number = 0;
245 	struct libinput_event *ev;
246 	struct libinput_event_tablet_pad *pev;
247 	unsigned int count;
248 
249 	if (!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_LEFT))
250 		return;
251 
252 	litest_drain_events(li);
253 
254 	for (code = BTN_LEFT; code < BTN_JOYSTICK; code++) {
255 		if (!libevdev_has_event_code(dev->evdev, EV_KEY, code))
256 			continue;
257 
258 		litest_button_click(dev, code, 1);
259 		litest_button_click(dev, code, 0);
260 		libinput_dispatch(li);
261 
262 		count++;
263 
264 		ev = libinput_get_event(li);
265 		pev = litest_is_pad_button_event(ev,
266 						 expected_number,
267 						 LIBINPUT_BUTTON_STATE_PRESSED);
268 		ev = libinput_event_tablet_pad_get_base_event(pev);
269 		libinput_event_destroy(ev);
270 
271 		ev = libinput_get_event(li);
272 		pev = litest_is_pad_button_event(ev,
273 						 expected_number,
274 						 LIBINPUT_BUTTON_STATE_RELEASED);
275 		ev = libinput_event_tablet_pad_get_base_event(pev);
276 		libinput_event_destroy(ev);
277 
278 		expected_number++;
279 	}
280 
281 	litest_assert_empty_queue(li);
282 
283 	ck_assert_int_gt(count, 3);
284 #endif
285 }
286 END_TEST
287 
START_TEST(pad_button_libwacom)288 START_TEST(pad_button_libwacom)
289 {
290 #if HAVE_LIBWACOM_GET_BUTTON_EVDEV_CODE
291 	struct litest_device *dev = litest_current_device();
292 	struct libinput *li = dev->libinput;
293 	WacomDeviceDatabase *db = NULL;
294 	WacomDevice *wacom = NULL;
295 
296 	db = libwacom_database_new();
297 	assert(db);
298 
299 	wacom = libwacom_new_from_usbid(db,
300 					libevdev_get_id_vendor(dev->evdev),
301 					libevdev_get_id_product(dev->evdev),
302 					NULL);
303 	assert(wacom);
304 
305 	litest_drain_events(li);
306 
307 	for (int i = 0; i < libwacom_get_num_buttons(wacom); i++) {
308 		unsigned int code;
309 
310 		code = libwacom_get_button_evdev_code(wacom, 'A' + i);
311 
312 		litest_button_click(dev, code, 1);
313 		litest_button_click(dev, code, 0);
314 		libinput_dispatch(li);
315 
316 		litest_assert_pad_button_event(li,
317 					       i,
318 					       LIBINPUT_BUTTON_STATE_PRESSED);
319 		litest_assert_pad_button_event(li,
320 					       i,
321 					       LIBINPUT_BUTTON_STATE_RELEASED);
322 	}
323 
324 	libwacom_destroy(wacom);
325 	libwacom_database_destroy(db);
326 #endif
327 }
328 END_TEST
329 
START_TEST(pad_button_mode_groups)330 START_TEST(pad_button_mode_groups)
331 {
332 	struct litest_device *dev = litest_current_device();
333 	struct libinput *li = dev->libinput;
334 	unsigned int code;
335 	unsigned int expected_number = 0;
336 	struct libinput_event *ev;
337 	struct libinput_event_tablet_pad *pev;
338 
339 	litest_drain_events(li);
340 
341 	for (code = BTN_0; code < KEY_MAX; code++) {
342 		unsigned int mode, index;
343 		struct libinput_tablet_pad_mode_group *group;
344 
345 		if (!libevdev_has_event_code(dev->evdev, EV_KEY, code))
346 			continue;
347 
348 		litest_button_click(dev, code, 1);
349 		litest_button_click(dev, code, 0);
350 		libinput_dispatch(li);
351 
352 		switch (code) {
353 		case BTN_STYLUS:
354 			litest_assert_empty_queue(li);
355 			continue;
356 		default:
357 			break;
358 		}
359 
360 		ev = libinput_get_event(li);
361 		ck_assert_int_eq(libinput_event_get_type(ev),
362 				 LIBINPUT_EVENT_TABLET_PAD_BUTTON);
363 		pev = libinput_event_get_tablet_pad_event(ev);
364 
365 		/* litest virtual devices don't have modes */
366 		mode = libinput_event_tablet_pad_get_mode(pev);
367 		ck_assert_int_eq(mode, 0);
368 		group = libinput_event_tablet_pad_get_mode_group(pev);
369 		index = libinput_tablet_pad_mode_group_get_index(group);
370 		ck_assert_int_eq(index, 0);
371 
372 		libinput_event_destroy(ev);
373 
374 		ev = libinput_get_event(li);
375 		ck_assert_int_eq(libinput_event_get_type(ev),
376 				 LIBINPUT_EVENT_TABLET_PAD_BUTTON);
377 		pev = libinput_event_get_tablet_pad_event(ev);
378 
379 		mode = libinput_event_tablet_pad_get_mode(pev);
380 		ck_assert_int_eq(mode, 0);
381 		group = libinput_event_tablet_pad_get_mode_group(pev);
382 		index = libinput_tablet_pad_mode_group_get_index(group);
383 		ck_assert_int_eq(index, 0);
384 		libinput_event_destroy(ev);
385 
386 		expected_number++;
387 	}
388 
389 	litest_assert_empty_queue(li);
390 }
391 END_TEST
392 
START_TEST(pad_has_ring)393 START_TEST(pad_has_ring)
394 {
395 	struct litest_device *dev = litest_current_device();
396 	struct libinput_device *device = dev->libinput_device;
397 	int nrings;
398 
399 	nrings = libinput_device_tablet_pad_get_num_rings(device);
400 	ck_assert_int_ge(nrings, 1);
401 }
402 END_TEST
403 
START_TEST(pad_ring)404 START_TEST(pad_ring)
405 {
406 	struct litest_device *dev = litest_current_device();
407 	struct libinput *li = dev->libinput;
408 	struct libinput_event *ev;
409 	struct libinput_event_tablet_pad *pev;
410 	int val;
411 	double degrees, expected;
412 	int min, max;
413 	int step_size;
414 	int nevents = 0;
415 
416 	litest_pad_ring_start(dev, 10);
417 
418 	litest_drain_events(li);
419 
420 	/* Wacom's 0 value is at 275 degrees */
421 	expected = 270;
422 
423 	min = libevdev_get_abs_minimum(dev->evdev, ABS_WHEEL);
424 	max = libevdev_get_abs_maximum(dev->evdev, ABS_WHEEL);
425 	step_size = 360/(max - min + 1);
426 
427 	/* This is a bit strange because we rely on kernel filtering here.
428 	   The litest_*() functions take a percentage, but mapping this to
429 	   the pads 72 or 36 range pad ranges is lossy and a bit
430 	   unpredictable. So instead we increase by a small percentage,
431 	   expecting *most* events to be filtered by the kernel because they
432 	   resolve to the same integer value as the previous event. Whenever
433 	   an event gets through, we expect that to be the next integer
434 	   value in the range and thus the next step on the circle.
435 	 */
436 	for (val = 0; val < 100.0; val += 1) {
437 		litest_pad_ring_change(dev, val);
438 		libinput_dispatch(li);
439 
440 		ev = libinput_get_event(li);
441 		if (!ev)
442 			continue;
443 
444 		nevents++;
445 		pev = litest_is_pad_ring_event(ev,
446 					       0,
447 					       LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER);
448 
449 		degrees = libinput_event_tablet_pad_get_ring_position(pev);
450 		ck_assert_double_ge(degrees, 0.0);
451 		ck_assert_double_lt(degrees, 360.0);
452 
453 		ck_assert_double_eq(degrees, expected);
454 
455 		libinput_event_destroy(ev);
456 		expected = fmod(degrees + step_size, 360);
457 	}
458 
459 	ck_assert_int_eq(nevents, 360/step_size - 1);
460 
461 	litest_pad_ring_end(dev);
462 }
463 END_TEST
464 
START_TEST(pad_ring_finger_up)465 START_TEST(pad_ring_finger_up)
466 {
467 	struct litest_device *dev = litest_current_device();
468 	struct libinput *li = dev->libinput;
469 	struct libinput_event *ev;
470 	struct libinput_event_tablet_pad *pev;
471 	double degrees;
472 
473 	litest_pad_ring_start(dev, 10);
474 
475 	litest_drain_events(li);
476 
477 	litest_pad_ring_end(dev);
478 	libinput_dispatch(li);
479 
480 	ev = libinput_get_event(li);
481 	pev = litest_is_pad_ring_event(ev,
482 				       0,
483 				       LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER);
484 
485 	degrees = libinput_event_tablet_pad_get_ring_position(pev);
486 	ck_assert_double_eq(degrees, -1.0);
487 	libinput_event_destroy(ev);
488 
489 	litest_assert_empty_queue(li);
490 }
491 END_TEST
492 
START_TEST(pad_has_strip)493 START_TEST(pad_has_strip)
494 {
495 	struct litest_device *dev = litest_current_device();
496 	struct libinput_device *device = dev->libinput_device;
497 	int nstrips;
498 
499 	nstrips = libinput_device_tablet_pad_get_num_strips(device);
500 	ck_assert_int_ge(nstrips, 1);
501 }
502 END_TEST
503 
START_TEST(pad_strip)504 START_TEST(pad_strip)
505 {
506 	struct litest_device *dev = litest_current_device();
507 	struct libinput *li = dev->libinput;
508 	struct libinput_event *ev;
509 	struct libinput_event_tablet_pad *pev;
510 	int val;
511 	double pos, expected;
512 
513 	litest_pad_strip_start(dev, 10);
514 
515 	litest_drain_events(li);
516 
517 	expected = 0;
518 
519 	/* 9.5 works with the generic axis scaling without jumping over a
520 	 * value. */
521 	for (val = 0; val < 100; val += 9.5) {
522 		litest_pad_strip_change(dev, val);
523 		libinput_dispatch(li);
524 
525 		ev = libinput_get_event(li);
526 		pev = litest_is_pad_strip_event(ev,
527 						0,
528 						LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER);
529 
530 		pos = libinput_event_tablet_pad_get_strip_position(pev);
531 		ck_assert_double_ge(pos, 0.0);
532 		ck_assert_double_lt(pos, 1.0);
533 
534 		/* rounding errors, mostly caused by small physical range */
535 		ck_assert_double_ge(pos, expected - 0.02);
536 		ck_assert_double_le(pos, expected + 0.02);
537 
538 		libinput_event_destroy(ev);
539 
540 		expected = pos + 0.08;
541 	}
542 
543 	litest_pad_strip_change(dev, 100);
544 	libinput_dispatch(li);
545 
546 	ev = libinput_get_event(li);
547 	pev = litest_is_pad_strip_event(ev,
548 					   0,
549 					   LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER);
550 	pos = libinput_event_tablet_pad_get_strip_position(pev);
551 	ck_assert_double_eq(pos, 1.0);
552 	libinput_event_destroy(ev);
553 
554 	litest_pad_strip_end(dev);
555 }
556 END_TEST
557 
START_TEST(pad_strip_finger_up)558 START_TEST(pad_strip_finger_up)
559 {
560 	struct litest_device *dev = litest_current_device();
561 	struct libinput *li = dev->libinput;
562 	struct libinput_event *ev;
563 	struct libinput_event_tablet_pad *pev;
564 	double pos;
565 
566 	litest_pad_strip_start(dev, 10);
567 	litest_drain_events(li);
568 
569 	litest_pad_strip_end(dev);
570 	libinput_dispatch(li);
571 
572 	ev = libinput_get_event(li);
573 	pev = litest_is_pad_strip_event(ev,
574 					0,
575 					LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER);
576 
577 	pos = libinput_event_tablet_pad_get_strip_position(pev);
578 	ck_assert_double_eq(pos, -1.0);
579 	libinput_event_destroy(ev);
580 
581 	litest_assert_empty_queue(li);
582 }
583 END_TEST
584 
START_TEST(pad_left_handed_default)585 START_TEST(pad_left_handed_default)
586 {
587 #if HAVE_LIBWACOM
588 	struct litest_device *dev = litest_current_device();
589 	struct libinput_device *device = dev->libinput_device;
590 	enum libinput_config_status status;
591 
592 	ck_assert(libinput_device_config_left_handed_is_available(device));
593 
594 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
595 			 0);
596 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
597 			 0);
598 
599 	status = libinput_device_config_left_handed_set(dev->libinput_device, 1);
600 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
601 
602 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
603 			 1);
604 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
605 			 0);
606 
607 	status = libinput_device_config_left_handed_set(dev->libinput_device, 0);
608 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
609 
610 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
611 			 0);
612 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
613 			 0);
614 
615 #endif
616 }
617 END_TEST
618 
START_TEST(pad_no_left_handed)619 START_TEST(pad_no_left_handed)
620 {
621 	struct litest_device *dev = litest_current_device();
622 	struct libinput_device *device = dev->libinput_device;
623 	enum libinput_config_status status;
624 
625 	ck_assert(!libinput_device_config_left_handed_is_available(device));
626 
627 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
628 			 0);
629 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
630 			 0);
631 
632 	status = libinput_device_config_left_handed_set(dev->libinput_device, 1);
633 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
634 
635 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
636 			 0);
637 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
638 			 0);
639 
640 	status = libinput_device_config_left_handed_set(dev->libinput_device, 0);
641 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
642 
643 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
644 			 0);
645 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
646 			 0);
647 }
648 END_TEST
649 
START_TEST(pad_left_handed_ring)650 START_TEST(pad_left_handed_ring)
651 {
652 #if HAVE_LIBWACOM
653 	struct litest_device *dev = litest_current_device();
654 	struct libinput *li = dev->libinput;
655 	struct libinput_event *ev;
656 	struct libinput_event_tablet_pad *pev;
657 	int val;
658 	double degrees, expected;
659 
660 	libinput_device_config_left_handed_set(dev->libinput_device, 1);
661 
662 	litest_pad_ring_start(dev, 10);
663 
664 	litest_drain_events(li);
665 
666 	/* Wacom's 0 value is at 275 degrees -> 90 in left-handed mode*/
667 	expected = 90;
668 
669 	for (val = 0; val < 100; val += 10) {
670 		litest_pad_ring_change(dev, val);
671 		libinput_dispatch(li);
672 
673 		ev = libinput_get_event(li);
674 		pev = litest_is_pad_ring_event(ev,
675 					       0,
676 					       LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER);
677 
678 		degrees = libinput_event_tablet_pad_get_ring_position(pev);
679 		ck_assert_double_ge(degrees, 0.0);
680 		ck_assert_double_lt(degrees, 360.0);
681 
682 		/* rounding errors, mostly caused by small physical range */
683 		ck_assert_double_ge(degrees, expected - 2);
684 		ck_assert_double_le(degrees, expected + 2);
685 
686 		libinput_event_destroy(ev);
687 
688 		expected = fmod(degrees + 36, 360);
689 	}
690 
691 	litest_pad_ring_end(dev);
692 #endif
693 }
694 END_TEST
695 
START_TEST(pad_mode_groups)696 START_TEST(pad_mode_groups)
697 {
698 	struct litest_device *dev = litest_current_device();
699 	struct libinput_device *device = dev->libinput_device;
700 	struct libinput_tablet_pad_mode_group *group;
701 	int ngroups;
702 	int i;
703 
704 	ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
705 	ck_assert_int_eq(ngroups, 1);
706 
707 	for (i = 0; i < ngroups; i++) {
708 		group = libinput_device_tablet_pad_get_mode_group(device, i);
709 		ck_assert_notnull(group);
710 		ck_assert_int_eq(libinput_tablet_pad_mode_group_get_index(group),
711 				 i);
712 	}
713 
714 	group = libinput_device_tablet_pad_get_mode_group(device, ngroups);
715 	ck_assert(group == NULL);
716 	group = libinput_device_tablet_pad_get_mode_group(device, ngroups + 1);
717 	ck_assert(group == NULL);
718 }
719 END_TEST
720 
START_TEST(pad_mode_groups_userdata)721 START_TEST(pad_mode_groups_userdata)
722 {
723 	struct litest_device *dev = litest_current_device();
724 	struct libinput_device *device = dev->libinput_device;
725 	struct libinput_tablet_pad_mode_group *group;
726 	int rc;
727 	void *userdata = &rc;
728 
729 	group = libinput_device_tablet_pad_get_mode_group(device, 0);
730 	ck_assert(libinput_tablet_pad_mode_group_get_user_data(group) ==
731 		  NULL);
732 	libinput_tablet_pad_mode_group_set_user_data(group, userdata);
733 	ck_assert(libinput_tablet_pad_mode_group_get_user_data(group) ==
734 		  &rc);
735 
736 	libinput_tablet_pad_mode_group_set_user_data(group, NULL);
737 	ck_assert(libinput_tablet_pad_mode_group_get_user_data(group) ==
738 		  NULL);
739 }
740 END_TEST
741 
START_TEST(pad_mode_groups_ref)742 START_TEST(pad_mode_groups_ref)
743 {
744 	struct litest_device *dev = litest_current_device();
745 	struct libinput_device *device = dev->libinput_device;
746 	struct libinput_tablet_pad_mode_group *group, *g;
747 
748 	group = libinput_device_tablet_pad_get_mode_group(device, 0);
749 	g = libinput_tablet_pad_mode_group_ref(group);
750 	ck_assert_ptr_eq(g, group);
751 
752 	/* We don't expect this to be freed. Any leaks should be caught by
753 	 * valgrind. */
754 	g = libinput_tablet_pad_mode_group_unref(group);
755 	ck_assert_ptr_eq(g, group);
756 }
757 END_TEST
758 
START_TEST(pad_mode_group_mode)759 START_TEST(pad_mode_group_mode)
760 {
761 	struct litest_device *dev = litest_current_device();
762 	struct libinput_device *device = dev->libinput_device;
763 	struct libinput_tablet_pad_mode_group *group;
764 	int ngroups;
765 	unsigned int nmodes, mode;
766 
767 	ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
768 	ck_assert_int_ge(ngroups, 1);
769 
770 	group = libinput_device_tablet_pad_get_mode_group(device, 0);
771 
772 	nmodes = libinput_tablet_pad_mode_group_get_num_modes(group);
773 	ck_assert_int_eq(nmodes, 1);
774 
775 	mode = libinput_tablet_pad_mode_group_get_mode(group);
776 	ck_assert_int_lt(mode, nmodes);
777 }
778 END_TEST
779 
START_TEST(pad_mode_group_has)780 START_TEST(pad_mode_group_has)
781 {
782 	struct litest_device *dev = litest_current_device();
783 	struct libinput_device *device = dev->libinput_device;
784 	struct libinput_tablet_pad_mode_group *group;
785 	int ngroups, nbuttons, nrings, nstrips;
786 	int i, b, r, s;
787 
788 	ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
789 	ck_assert_int_ge(ngroups, 1);
790 
791 	nbuttons = libinput_device_tablet_pad_get_num_buttons(device);
792 	nrings = libinput_device_tablet_pad_get_num_rings(device);
793 	nstrips = libinput_device_tablet_pad_get_num_strips(device);
794 
795 	for (b = 0; b < nbuttons; b++) {
796 		bool found = false;
797 		for (i = 0; i < ngroups; i++) {
798 			group = libinput_device_tablet_pad_get_mode_group(device,
799 									  i);
800 			if (libinput_tablet_pad_mode_group_has_button(group,
801 								      b)) {
802 				ck_assert(!found);
803 				found = true;
804 			}
805 		}
806 		ck_assert(found);
807 	}
808 
809 	for (s = 0; s < nstrips; s++) {
810 		bool found = false;
811 		for (i = 0; i < ngroups; i++) {
812 			group = libinput_device_tablet_pad_get_mode_group(device,
813 									  i);
814 			if (libinput_tablet_pad_mode_group_has_strip(group,
815 								     s)) {
816 				ck_assert(!found);
817 				found = true;
818 			}
819 		}
820 		ck_assert(found);
821 	}
822 
823 	for (r = 0; r < nrings; r++) {
824 		bool found = false;
825 		for (i = 0; i < ngroups; i++) {
826 			group = libinput_device_tablet_pad_get_mode_group(device,
827 									  i);
828 			if (libinput_tablet_pad_mode_group_has_ring(group,
829 								    r)) {
830 				ck_assert(!found);
831 				found = true;
832 			}
833 		}
834 		ck_assert(found);
835 	}
836 }
837 END_TEST
838 
START_TEST(pad_mode_group_has_invalid)839 START_TEST(pad_mode_group_has_invalid)
840 {
841 	struct litest_device *dev = litest_current_device();
842 	struct libinput_device *device = dev->libinput_device;
843 	struct libinput_tablet_pad_mode_group* group;
844 	int ngroups, nbuttons, nrings, nstrips;
845 	int i;
846 	int rc;
847 
848 	ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
849 	ck_assert_int_ge(ngroups, 1);
850 
851 	nbuttons = libinput_device_tablet_pad_get_num_buttons(device);
852 	nrings = libinput_device_tablet_pad_get_num_rings(device);
853 	nstrips = libinput_device_tablet_pad_get_num_strips(device);
854 
855 	for (i = 0; i < ngroups; i++) {
856 		group = libinput_device_tablet_pad_get_mode_group(device, i);
857 		rc = libinput_tablet_pad_mode_group_has_button(group,
858 							       nbuttons);
859 		ck_assert_int_eq(rc, 0);
860 		rc = libinput_tablet_pad_mode_group_has_button(group,
861 							       nbuttons + 1);
862 		ck_assert_int_eq(rc, 0);
863 		rc = libinput_tablet_pad_mode_group_has_button(group,
864 							       0x1000000);
865 		ck_assert_int_eq(rc, 0);
866 	}
867 
868 	for (i = 0; i < ngroups; i++) {
869 		group = libinput_device_tablet_pad_get_mode_group(device, i);
870 		rc = libinput_tablet_pad_mode_group_has_strip(group,
871 							      nstrips);
872 		ck_assert_int_eq(rc, 0);
873 		rc = libinput_tablet_pad_mode_group_has_strip(group,
874 							       nstrips + 1);
875 		ck_assert_int_eq(rc, 0);
876 		rc = libinput_tablet_pad_mode_group_has_strip(group,
877 							       0x1000000);
878 		ck_assert_int_eq(rc, 0);
879 	}
880 
881 	for (i = 0; i < ngroups; i++) {
882 		group = libinput_device_tablet_pad_get_mode_group(device, i);
883 		rc = libinput_tablet_pad_mode_group_has_ring(group,
884 							     nrings);
885 		ck_assert_int_eq(rc, 0);
886 		rc = libinput_tablet_pad_mode_group_has_ring(group,
887 							     nrings + 1);
888 		ck_assert_int_eq(rc, 0);
889 		rc = libinput_tablet_pad_mode_group_has_ring(group,
890 							     0x1000000);
891 		ck_assert_int_eq(rc, 0);
892 	}
893 }
894 END_TEST
895 
START_TEST(pad_mode_group_has_no_toggle)896 START_TEST(pad_mode_group_has_no_toggle)
897 {
898 	struct litest_device *dev = litest_current_device();
899 	struct libinput_device *device = dev->libinput_device;
900 	struct libinput_tablet_pad_mode_group* group;
901 	int ngroups, nbuttons;
902 	int i, b;
903 
904 	ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
905 	ck_assert_int_ge(ngroups, 1);
906 
907 	/* Button must not be toggle buttons */
908 	nbuttons = libinput_device_tablet_pad_get_num_buttons(device);
909 	for (i = 0; i < ngroups; i++) {
910 		group = libinput_device_tablet_pad_get_mode_group(device, i);
911 		for (b = 0; b < nbuttons; b++) {
912 			ck_assert(!libinput_tablet_pad_mode_group_button_is_toggle(
913 								    group,
914 								    b));
915 		}
916 	}
917 }
918 END_TEST
919 
TEST_COLLECTION(tablet_pad)920 TEST_COLLECTION(tablet_pad)
921 {
922 	litest_add("pad:cap", pad_cap, LITEST_TABLET_PAD, LITEST_ANY);
923 	litest_add("pad:cap", pad_no_cap, LITEST_ANY, LITEST_TABLET_PAD);
924 
925 	litest_add("pad:time", pad_time, LITEST_TABLET_PAD, LITEST_ANY);
926 
927 	litest_add("pad:button", pad_num_buttons, LITEST_TABLET_PAD, LITEST_ANY);
928 	litest_add("pad:button", pad_num_buttons_libwacom, LITEST_TABLET_PAD, LITEST_ANY);
929 	litest_add("pad:button", pad_button_intuos, LITEST_TABLET_PAD, LITEST_ANY);
930 	litest_add("pad:button", pad_button_bamboo, LITEST_TABLET_PAD, LITEST_ANY);
931 	litest_add("pad:button", pad_button_libwacom, LITEST_TABLET_PAD, LITEST_ANY);
932 	litest_add("pad:button", pad_button_mode_groups, LITEST_TABLET_PAD, LITEST_ANY);
933 
934 	litest_add("pad:ring", pad_has_ring, LITEST_RING, LITEST_ANY);
935 	litest_add("pad:ring", pad_ring, LITEST_RING, LITEST_ANY);
936 	litest_add("pad:ring", pad_ring_finger_up, LITEST_RING, LITEST_ANY);
937 
938 	litest_add("pad:strip", pad_has_strip, LITEST_STRIP, LITEST_ANY);
939 	litest_add("pad:strip", pad_strip, LITEST_STRIP, LITEST_ANY);
940 	litest_add("pad:strip", pad_strip_finger_up, LITEST_STRIP, LITEST_ANY);
941 
942 	litest_add_for_device("pad:left_handed", pad_left_handed_default, LITEST_WACOM_INTUOS5_PAD);
943 	litest_add_for_device("pad:left_handed", pad_no_left_handed, LITEST_WACOM_INTUOS3_PAD);
944 	litest_add_for_device("pad:left_handed", pad_left_handed_ring, LITEST_WACOM_INTUOS5_PAD);
945 	/* None of the current strip tablets are left-handed */
946 
947 	litest_add("pad:modes", pad_mode_groups, LITEST_TABLET_PAD, LITEST_ANY);
948 	litest_add("pad:modes", pad_mode_groups_userdata, LITEST_TABLET_PAD, LITEST_ANY);
949 	litest_add("pad:modes", pad_mode_groups_ref, LITEST_TABLET_PAD, LITEST_ANY);
950 	litest_add("pad:modes", pad_mode_group_mode, LITEST_TABLET_PAD, LITEST_ANY);
951 	litest_add("pad:modes", pad_mode_group_has, LITEST_TABLET_PAD, LITEST_ANY);
952 	litest_add("pad:modes", pad_mode_group_has_invalid, LITEST_TABLET_PAD, LITEST_ANY);
953 	litest_add("pad:modes", pad_mode_group_has_no_toggle, LITEST_TABLET_PAD, LITEST_ANY);
954 }
955