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