• 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 = 0;
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 = 0;
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 	struct libinput_event *ev;
335 	struct libinput_event_tablet_pad *pev;
336 
337 	litest_drain_events(li);
338 
339 	for (code = BTN_0; code < KEY_OK; code++) {
340 		unsigned int mode, index;
341 		struct libinput_tablet_pad_mode_group *group;
342 
343 		if (!libevdev_has_event_code(dev->evdev, EV_KEY, code))
344 			continue;
345 
346 		litest_button_click(dev, code, 1);
347 		litest_button_click(dev, code, 0);
348 		libinput_dispatch(li);
349 
350 		switch (code) {
351 		case BTN_STYLUS:
352 			litest_assert_empty_queue(li);
353 			continue;
354 		default:
355 			break;
356 		}
357 
358 		ev = libinput_get_event(li);
359 		ck_assert_int_eq(libinput_event_get_type(ev),
360 				 LIBINPUT_EVENT_TABLET_PAD_BUTTON);
361 		pev = libinput_event_get_tablet_pad_event(ev);
362 
363 		/* litest virtual devices don't have modes */
364 		mode = libinput_event_tablet_pad_get_mode(pev);
365 		ck_assert_int_eq(mode, 0);
366 		group = libinput_event_tablet_pad_get_mode_group(pev);
367 		index = libinput_tablet_pad_mode_group_get_index(group);
368 		ck_assert_int_eq(index, 0);
369 
370 		libinput_event_destroy(ev);
371 
372 		ev = libinput_get_event(li);
373 		ck_assert_int_eq(libinput_event_get_type(ev),
374 				 LIBINPUT_EVENT_TABLET_PAD_BUTTON);
375 		pev = libinput_event_get_tablet_pad_event(ev);
376 
377 		mode = libinput_event_tablet_pad_get_mode(pev);
378 		ck_assert_int_eq(mode, 0);
379 		group = libinput_event_tablet_pad_get_mode_group(pev);
380 		index = libinput_tablet_pad_mode_group_get_index(group);
381 		ck_assert_int_eq(index, 0);
382 		libinput_event_destroy(ev);
383 	}
384 
385 	litest_assert_empty_queue(li);
386 }
387 END_TEST
388 
START_TEST(pad_has_ring)389 START_TEST(pad_has_ring)
390 {
391 	struct litest_device *dev = litest_current_device();
392 	struct libinput_device *device = dev->libinput_device;
393 	int nrings;
394 
395 	nrings = libinput_device_tablet_pad_get_num_rings(device);
396 	ck_assert_int_ge(nrings, 1);
397 }
398 END_TEST
399 
START_TEST(pad_ring)400 START_TEST(pad_ring)
401 {
402 	struct litest_device *dev = litest_current_device();
403 	struct libinput *li = dev->libinput;
404 	struct libinput_event *ev;
405 	struct libinput_event_tablet_pad *pev;
406 	int val;
407 	double degrees, expected;
408 	int min, max;
409 	int step_size;
410 	int nevents = 0;
411 
412 	litest_pad_ring_start(dev, 10);
413 
414 	litest_drain_events(li);
415 
416 	/* Wacom's 0 value is at 275 degrees */
417 	expected = 270;
418 
419 	min = libevdev_get_abs_minimum(dev->evdev, ABS_WHEEL);
420 	max = libevdev_get_abs_maximum(dev->evdev, ABS_WHEEL);
421 	step_size = 360/(max - min + 1);
422 
423 	/* This is a bit strange because we rely on kernel filtering here.
424 	   The litest_*() functions take a percentage, but mapping this to
425 	   the pads 72 or 36 range pad ranges is lossy and a bit
426 	   unpredictable. So instead we increase by a small percentage,
427 	   expecting *most* events to be filtered by the kernel because they
428 	   resolve to the same integer value as the previous event. Whenever
429 	   an event gets through, we expect that to be the next integer
430 	   value in the range and thus the next step on the circle.
431 	 */
432 	for (val = 0; val < 100.0; val += 1) {
433 		litest_pad_ring_change(dev, val);
434 		libinput_dispatch(li);
435 
436 		ev = libinput_get_event(li);
437 		if (!ev)
438 			continue;
439 
440 		nevents++;
441 		pev = litest_is_pad_ring_event(ev,
442 					       0,
443 					       LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER);
444 
445 		degrees = libinput_event_tablet_pad_get_ring_position(pev);
446 		ck_assert_double_ge(degrees, 0.0);
447 		ck_assert_double_lt(degrees, 360.0);
448 
449 		ck_assert_double_eq(degrees, expected);
450 
451 		libinput_event_destroy(ev);
452 		expected = fmod(degrees + step_size, 360);
453 	}
454 
455 	ck_assert_int_eq(nevents, 360/step_size - 1);
456 
457 	litest_pad_ring_end(dev);
458 }
459 END_TEST
460 
START_TEST(pad_ring_finger_up)461 START_TEST(pad_ring_finger_up)
462 {
463 	struct litest_device *dev = litest_current_device();
464 	struct libinput *li = dev->libinput;
465 	struct libinput_event *ev;
466 	struct libinput_event_tablet_pad *pev;
467 	double degrees;
468 
469 	litest_pad_ring_start(dev, 10);
470 
471 	litest_drain_events(li);
472 
473 	litest_pad_ring_end(dev);
474 	libinput_dispatch(li);
475 
476 	ev = libinput_get_event(li);
477 	pev = litest_is_pad_ring_event(ev,
478 				       0,
479 				       LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER);
480 
481 	degrees = libinput_event_tablet_pad_get_ring_position(pev);
482 	ck_assert_double_eq(degrees, -1.0);
483 	libinput_event_destroy(ev);
484 
485 	litest_assert_empty_queue(li);
486 }
487 END_TEST
488 
START_TEST(pad_has_strip)489 START_TEST(pad_has_strip)
490 {
491 	struct litest_device *dev = litest_current_device();
492 	struct libinput_device *device = dev->libinput_device;
493 	int nstrips;
494 
495 	nstrips = libinput_device_tablet_pad_get_num_strips(device);
496 	ck_assert_int_ge(nstrips, 1);
497 }
498 END_TEST
499 
START_TEST(pad_strip)500 START_TEST(pad_strip)
501 {
502 	struct litest_device *dev = litest_current_device();
503 	struct libinput *li = dev->libinput;
504 	struct libinput_event *ev;
505 	struct libinput_event_tablet_pad *pev;
506 	int val;
507 	double pos, expected;
508 
509 	litest_pad_strip_start(dev, 10);
510 
511 	litest_drain_events(li);
512 
513 	expected = 0;
514 
515 	/* 9.5 works with the generic axis scaling without jumping over a
516 	 * value. */
517 	for (val = 0; val < 100; val += 9.5) {
518 		litest_pad_strip_change(dev, val);
519 		libinput_dispatch(li);
520 
521 		ev = libinput_get_event(li);
522 		pev = litest_is_pad_strip_event(ev,
523 						0,
524 						LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER);
525 
526 		pos = libinput_event_tablet_pad_get_strip_position(pev);
527 		ck_assert_double_ge(pos, 0.0);
528 		ck_assert_double_lt(pos, 1.0);
529 
530 		/* rounding errors, mostly caused by small physical range */
531 		ck_assert_double_ge(pos, expected - 0.02);
532 		ck_assert_double_le(pos, expected + 0.02);
533 
534 		libinput_event_destroy(ev);
535 
536 		expected = pos + 0.08;
537 	}
538 
539 	litest_pad_strip_change(dev, 100);
540 	libinput_dispatch(li);
541 
542 	ev = libinput_get_event(li);
543 	pev = litest_is_pad_strip_event(ev,
544 					   0,
545 					   LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER);
546 	pos = libinput_event_tablet_pad_get_strip_position(pev);
547 	ck_assert_double_eq(pos, 1.0);
548 	libinput_event_destroy(ev);
549 
550 	litest_pad_strip_end(dev);
551 }
552 END_TEST
553 
START_TEST(pad_strip_finger_up)554 START_TEST(pad_strip_finger_up)
555 {
556 	struct litest_device *dev = litest_current_device();
557 	struct libinput *li = dev->libinput;
558 	struct libinput_event *ev;
559 	struct libinput_event_tablet_pad *pev;
560 	double pos;
561 
562 	litest_pad_strip_start(dev, 10);
563 	litest_drain_events(li);
564 
565 	litest_pad_strip_end(dev);
566 	libinput_dispatch(li);
567 
568 	ev = libinput_get_event(li);
569 	pev = litest_is_pad_strip_event(ev,
570 					0,
571 					LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER);
572 
573 	pos = libinput_event_tablet_pad_get_strip_position(pev);
574 	ck_assert_double_eq(pos, -1.0);
575 	libinput_event_destroy(ev);
576 
577 	litest_assert_empty_queue(li);
578 }
579 END_TEST
580 
START_TEST(pad_left_handed_default)581 START_TEST(pad_left_handed_default)
582 {
583 #if HAVE_LIBWACOM
584 	struct litest_device *dev = litest_current_device();
585 	struct libinput_device *device = dev->libinput_device;
586 	enum libinput_config_status status;
587 
588 	ck_assert(libinput_device_config_left_handed_is_available(device));
589 
590 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
591 			 0);
592 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
593 			 0);
594 
595 	status = libinput_device_config_left_handed_set(dev->libinput_device, 1);
596 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
597 
598 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
599 			 1);
600 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
601 			 0);
602 
603 	status = libinput_device_config_left_handed_set(dev->libinput_device, 0);
604 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
605 
606 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
607 			 0);
608 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
609 			 0);
610 
611 #endif
612 }
613 END_TEST
614 
START_TEST(pad_no_left_handed)615 START_TEST(pad_no_left_handed)
616 {
617 	struct litest_device *dev = litest_current_device();
618 	struct libinput_device *device = dev->libinput_device;
619 	enum libinput_config_status status;
620 
621 	/* Without libwacom we default to left-handed being available */
622 #if HAVE_LIBWACOM
623 	ck_assert(!libinput_device_config_left_handed_is_available(device));
624 #else
625 	ck_assert(libinput_device_config_left_handed_is_available(device));
626 #endif
627 
628 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
629 			 0);
630 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
631 			 0);
632 
633 #if HAVE_LIBWACOM
634 	status = libinput_device_config_left_handed_set(dev->libinput_device, 1);
635 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
636 
637 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
638 			 0);
639 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
640 			 0);
641 
642 	status = libinput_device_config_left_handed_set(dev->libinput_device, 0);
643 	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
644 
645 	ck_assert_int_eq(libinput_device_config_left_handed_get(device),
646 			 0);
647 	ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
648 			 0);
649 #endif
650 }
651 END_TEST
652 
START_TEST(pad_left_handed_ring)653 START_TEST(pad_left_handed_ring)
654 {
655 #if HAVE_LIBWACOM
656 	struct litest_device *dev = litest_current_device();
657 	struct libinput *li = dev->libinput;
658 	struct libinput_event *ev;
659 	struct libinput_event_tablet_pad *pev;
660 	int val;
661 	double degrees, expected;
662 
663 	libinput_device_config_left_handed_set(dev->libinput_device, 1);
664 
665 	litest_pad_ring_start(dev, 10);
666 
667 	litest_drain_events(li);
668 
669 	/* Wacom's 0 value is at 275 degrees -> 90 in left-handed mode*/
670 	expected = 90;
671 
672 	for (val = 0; val < 100; val += 10) {
673 		litest_pad_ring_change(dev, val);
674 		libinput_dispatch(li);
675 
676 		ev = libinput_get_event(li);
677 		pev = litest_is_pad_ring_event(ev,
678 					       0,
679 					       LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER);
680 
681 		degrees = libinput_event_tablet_pad_get_ring_position(pev);
682 		ck_assert_double_ge(degrees, 0.0);
683 		ck_assert_double_lt(degrees, 360.0);
684 
685 		/* rounding errors, mostly caused by small physical range */
686 		ck_assert_double_ge(degrees, expected - 2);
687 		ck_assert_double_le(degrees, expected + 2);
688 
689 		libinput_event_destroy(ev);
690 
691 		expected = fmod(degrees + 36, 360);
692 	}
693 
694 	litest_pad_ring_end(dev);
695 #endif
696 }
697 END_TEST
698 
START_TEST(pad_mode_groups)699 START_TEST(pad_mode_groups)
700 {
701 	struct litest_device *dev = litest_current_device();
702 	struct libinput_device *device = dev->libinput_device;
703 	struct libinput_tablet_pad_mode_group *group;
704 	int ngroups;
705 	int i;
706 
707 	ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
708 	ck_assert_int_eq(ngroups, 1);
709 
710 	for (i = 0; i < ngroups; i++) {
711 		group = libinput_device_tablet_pad_get_mode_group(device, i);
712 		ck_assert_notnull(group);
713 		ck_assert_int_eq(libinput_tablet_pad_mode_group_get_index(group),
714 				 i);
715 	}
716 
717 	group = libinput_device_tablet_pad_get_mode_group(device, ngroups);
718 	ck_assert(group == NULL);
719 	group = libinput_device_tablet_pad_get_mode_group(device, ngroups + 1);
720 	ck_assert(group == NULL);
721 }
722 END_TEST
723 
START_TEST(pad_mode_groups_userdata)724 START_TEST(pad_mode_groups_userdata)
725 {
726 	struct litest_device *dev = litest_current_device();
727 	struct libinput_device *device = dev->libinput_device;
728 	struct libinput_tablet_pad_mode_group *group;
729 	int rc;
730 	void *userdata = &rc;
731 
732 	group = libinput_device_tablet_pad_get_mode_group(device, 0);
733 	ck_assert(libinput_tablet_pad_mode_group_get_user_data(group) ==
734 		  NULL);
735 	libinput_tablet_pad_mode_group_set_user_data(group, userdata);
736 	ck_assert(libinput_tablet_pad_mode_group_get_user_data(group) ==
737 		  &rc);
738 
739 	libinput_tablet_pad_mode_group_set_user_data(group, NULL);
740 	ck_assert(libinput_tablet_pad_mode_group_get_user_data(group) ==
741 		  NULL);
742 }
743 END_TEST
744 
START_TEST(pad_mode_groups_ref)745 START_TEST(pad_mode_groups_ref)
746 {
747 	struct litest_device *dev = litest_current_device();
748 	struct libinput_device *device = dev->libinput_device;
749 	struct libinput_tablet_pad_mode_group *group, *g;
750 
751 	group = libinput_device_tablet_pad_get_mode_group(device, 0);
752 	g = libinput_tablet_pad_mode_group_ref(group);
753 	ck_assert_ptr_eq(g, group);
754 
755 	/* We don't expect this to be freed. Any leaks should be caught by
756 	 * valgrind. */
757 	g = libinput_tablet_pad_mode_group_unref(group);
758 	ck_assert_ptr_eq(g, group);
759 }
760 END_TEST
761 
START_TEST(pad_mode_group_mode)762 START_TEST(pad_mode_group_mode)
763 {
764 	struct litest_device *dev = litest_current_device();
765 	struct libinput_device *device = dev->libinput_device;
766 	struct libinput_tablet_pad_mode_group *group;
767 	int ngroups;
768 	unsigned int nmodes, mode;
769 
770 	ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
771 	ck_assert_int_ge(ngroups, 1);
772 
773 	group = libinput_device_tablet_pad_get_mode_group(device, 0);
774 
775 	nmodes = libinput_tablet_pad_mode_group_get_num_modes(group);
776 	ck_assert_int_eq(nmodes, 1);
777 
778 	mode = libinput_tablet_pad_mode_group_get_mode(group);
779 	ck_assert_int_lt(mode, nmodes);
780 }
781 END_TEST
782 
START_TEST(pad_mode_group_has)783 START_TEST(pad_mode_group_has)
784 {
785 	struct litest_device *dev = litest_current_device();
786 	struct libinput_device *device = dev->libinput_device;
787 	struct libinput_tablet_pad_mode_group *group;
788 	int ngroups, nbuttons, nrings, nstrips;
789 	int i, b, r, s;
790 
791 	ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
792 	ck_assert_int_ge(ngroups, 1);
793 
794 	nbuttons = libinput_device_tablet_pad_get_num_buttons(device);
795 	nrings = libinput_device_tablet_pad_get_num_rings(device);
796 	nstrips = libinput_device_tablet_pad_get_num_strips(device);
797 
798 	for (b = 0; b < nbuttons; b++) {
799 		bool found = false;
800 		for (i = 0; i < ngroups; i++) {
801 			group = libinput_device_tablet_pad_get_mode_group(device,
802 									  i);
803 			if (libinput_tablet_pad_mode_group_has_button(group,
804 								      b)) {
805 				ck_assert(!found);
806 				found = true;
807 			}
808 		}
809 		ck_assert(found);
810 	}
811 
812 	for (s = 0; s < nstrips; s++) {
813 		bool found = false;
814 		for (i = 0; i < ngroups; i++) {
815 			group = libinput_device_tablet_pad_get_mode_group(device,
816 									  i);
817 			if (libinput_tablet_pad_mode_group_has_strip(group,
818 								     s)) {
819 				ck_assert(!found);
820 				found = true;
821 			}
822 		}
823 		ck_assert(found);
824 	}
825 
826 	for (r = 0; r < nrings; r++) {
827 		bool found = false;
828 		for (i = 0; i < ngroups; i++) {
829 			group = libinput_device_tablet_pad_get_mode_group(device,
830 									  i);
831 			if (libinput_tablet_pad_mode_group_has_ring(group,
832 								    r)) {
833 				ck_assert(!found);
834 				found = true;
835 			}
836 		}
837 		ck_assert(found);
838 	}
839 }
840 END_TEST
841 
START_TEST(pad_mode_group_has_invalid)842 START_TEST(pad_mode_group_has_invalid)
843 {
844 	struct litest_device *dev = litest_current_device();
845 	struct libinput_device *device = dev->libinput_device;
846 	struct libinput_tablet_pad_mode_group* group;
847 	int ngroups, nbuttons, nrings, nstrips;
848 	int i;
849 	int rc;
850 
851 	ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
852 	ck_assert_int_ge(ngroups, 1);
853 
854 	nbuttons = libinput_device_tablet_pad_get_num_buttons(device);
855 	nrings = libinput_device_tablet_pad_get_num_rings(device);
856 	nstrips = libinput_device_tablet_pad_get_num_strips(device);
857 
858 	for (i = 0; i < ngroups; i++) {
859 		group = libinput_device_tablet_pad_get_mode_group(device, i);
860 		rc = libinput_tablet_pad_mode_group_has_button(group,
861 							       nbuttons);
862 		ck_assert_int_eq(rc, 0);
863 		rc = libinput_tablet_pad_mode_group_has_button(group,
864 							       nbuttons + 1);
865 		ck_assert_int_eq(rc, 0);
866 		rc = libinput_tablet_pad_mode_group_has_button(group,
867 							       0x1000000);
868 		ck_assert_int_eq(rc, 0);
869 	}
870 
871 	for (i = 0; i < ngroups; i++) {
872 		group = libinput_device_tablet_pad_get_mode_group(device, i);
873 		rc = libinput_tablet_pad_mode_group_has_strip(group,
874 							      nstrips);
875 		ck_assert_int_eq(rc, 0);
876 		rc = libinput_tablet_pad_mode_group_has_strip(group,
877 							       nstrips + 1);
878 		ck_assert_int_eq(rc, 0);
879 		rc = libinput_tablet_pad_mode_group_has_strip(group,
880 							       0x1000000);
881 		ck_assert_int_eq(rc, 0);
882 	}
883 
884 	for (i = 0; i < ngroups; i++) {
885 		group = libinput_device_tablet_pad_get_mode_group(device, i);
886 		rc = libinput_tablet_pad_mode_group_has_ring(group,
887 							     nrings);
888 		ck_assert_int_eq(rc, 0);
889 		rc = libinput_tablet_pad_mode_group_has_ring(group,
890 							     nrings + 1);
891 		ck_assert_int_eq(rc, 0);
892 		rc = libinput_tablet_pad_mode_group_has_ring(group,
893 							     0x1000000);
894 		ck_assert_int_eq(rc, 0);
895 	}
896 }
897 END_TEST
898 
START_TEST(pad_mode_group_has_no_toggle)899 START_TEST(pad_mode_group_has_no_toggle)
900 {
901 	struct litest_device *dev = litest_current_device();
902 	struct libinput_device *device = dev->libinput_device;
903 	struct libinput_tablet_pad_mode_group* group;
904 	int ngroups, nbuttons;
905 	int i, b;
906 
907 	ngroups = libinput_device_tablet_pad_get_num_mode_groups(device);
908 	ck_assert_int_ge(ngroups, 1);
909 
910 	/* Button must not be toggle buttons */
911 	nbuttons = libinput_device_tablet_pad_get_num_buttons(device);
912 	for (i = 0; i < ngroups; i++) {
913 		group = libinput_device_tablet_pad_get_mode_group(device, i);
914 		for (b = 0; b < nbuttons; b++) {
915 			ck_assert(!libinput_tablet_pad_mode_group_button_is_toggle(
916 								    group,
917 								    b));
918 		}
919 	}
920 }
921 END_TEST
922 
923 static bool
pad_has_keys(struct litest_device * dev)924 pad_has_keys(struct litest_device *dev)
925 {
926 	struct libevdev *evdev = dev->evdev;
927 
928 	return (libevdev_has_event_code(evdev, EV_KEY, KEY_BUTTONCONFIG) ||
929 		libevdev_has_event_code(evdev, EV_KEY, KEY_ONSCREEN_KEYBOARD) ||
930 	        libevdev_has_event_code(evdev, EV_KEY, KEY_CONTROLPANEL));
931 }
932 
933 static void
pad_key_down(struct litest_device * dev,unsigned int which)934 pad_key_down(struct litest_device *dev, unsigned int which)
935 {
936 	litest_event(dev, EV_ABS, ABS_MISC, 15);
937 	litest_event(dev, EV_KEY, which, 1);
938 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
939 }
940 
941 static void
pad_key_up(struct litest_device * dev,unsigned int which)942 pad_key_up(struct litest_device *dev, unsigned int which)
943 {
944 	litest_event(dev, EV_ABS, ABS_MISC, 0);
945 	litest_event(dev, EV_KEY, which, 0);
946 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
947 }
948 
START_TEST(pad_keys)949 START_TEST(pad_keys)
950 {
951 	struct litest_device *dev = litest_current_device();
952 	struct libinput *li = dev->libinput;
953 	unsigned int key;
954 
955 	if (!pad_has_keys(dev))
956 		return;
957 
958 	litest_drain_events(li);
959 
960 	key = KEY_BUTTONCONFIG;
961 	pad_key_down(dev, key);
962 	libinput_dispatch(li);
963 	litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_PRESSED);
964 
965 	pad_key_up(dev, key);
966 	libinput_dispatch(li);
967 	litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_RELEASED);
968 
969 	key = KEY_ONSCREEN_KEYBOARD;
970 	pad_key_down(dev, key);
971 	libinput_dispatch(li);
972 	litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_PRESSED);
973 
974 	pad_key_up(dev, key);
975 	libinput_dispatch(li);
976 	litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_RELEASED);
977 
978 	key = KEY_CONTROLPANEL;
979 	pad_key_down(dev, key);
980 	libinput_dispatch(li);
981 	litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_PRESSED);
982 
983 	pad_key_up(dev, key);
984 	libinput_dispatch(li);
985 	litest_assert_pad_key_event(li, key, LIBINPUT_KEY_STATE_RELEASED);
986 }
987 END_TEST
988 
TEST_COLLECTION(tablet_pad)989 TEST_COLLECTION(tablet_pad)
990 {
991 	litest_add(pad_cap, LITEST_TABLET_PAD, LITEST_ANY);
992 	litest_add(pad_no_cap, LITEST_ANY, LITEST_TABLET_PAD);
993 
994 	litest_add(pad_time, LITEST_TABLET_PAD, LITEST_ANY);
995 
996 	litest_add(pad_num_buttons, LITEST_TABLET_PAD, LITEST_ANY);
997 	litest_add(pad_num_buttons_libwacom, LITEST_TABLET_PAD, LITEST_ANY);
998 	litest_add(pad_button_intuos, LITEST_TABLET_PAD, LITEST_ANY);
999 	litest_add(pad_button_bamboo, LITEST_TABLET_PAD, LITEST_ANY);
1000 	litest_add(pad_button_libwacom, LITEST_TABLET_PAD, LITEST_ANY);
1001 	litest_add(pad_button_mode_groups, LITEST_TABLET_PAD, LITEST_ANY);
1002 
1003 	litest_add(pad_has_ring, LITEST_RING, LITEST_ANY);
1004 	litest_add(pad_ring, LITEST_RING, LITEST_ANY);
1005 	litest_add(pad_ring_finger_up, LITEST_RING, LITEST_ANY);
1006 
1007 	litest_add(pad_has_strip, LITEST_STRIP, LITEST_ANY);
1008 	litest_add(pad_strip, LITEST_STRIP, LITEST_ANY);
1009 	litest_add(pad_strip_finger_up, LITEST_STRIP, LITEST_ANY);
1010 
1011 	litest_add_for_device(pad_left_handed_default, LITEST_WACOM_INTUOS5_PAD);
1012 	litest_add_for_device(pad_no_left_handed, LITEST_WACOM_INTUOS3_PAD);
1013 	litest_add_for_device(pad_left_handed_ring, LITEST_WACOM_INTUOS5_PAD);
1014 	/* None of the current strip tablets are left-handed */
1015 
1016 	litest_add(pad_mode_groups, LITEST_TABLET_PAD, LITEST_ANY);
1017 	litest_add(pad_mode_groups_userdata, LITEST_TABLET_PAD, LITEST_ANY);
1018 	litest_add(pad_mode_groups_ref, LITEST_TABLET_PAD, LITEST_ANY);
1019 	litest_add(pad_mode_group_mode, LITEST_TABLET_PAD, LITEST_ANY);
1020 	litest_add(pad_mode_group_has, LITEST_TABLET_PAD, LITEST_ANY);
1021 	litest_add(pad_mode_group_has_invalid, LITEST_TABLET_PAD, LITEST_ANY);
1022 	litest_add(pad_mode_group_has_no_toggle, LITEST_TABLET_PAD, LITEST_ANY);
1023 
1024 	litest_add(pad_keys, LITEST_TABLET_PAD, LITEST_ANY);
1025 }
1026