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