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