2 * Copyright © 2013 Red Hat, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
37 #include "linux/input.h"
38 #include <sys/ptrace.h>
39 #include <sys/timerfd.h>
43 #include "litest-int.h"
44 #include "libinput-util.h"
46 static int in_debugger = -1;
52 enum litest_device_type devices;
62 static struct litest_device *current_device;
64 struct litest_device *litest_current_device(void) {
65 return current_device;
68 void litest_set_current_device(struct litest_device *device) {
69 current_device = device;
72 void litest_generic_device_teardown(void)
74 litest_delete_device(current_device);
75 current_device = NULL;
78 extern struct litest_test_device litest_keyboard_device;
79 extern struct litest_test_device litest_synaptics_clickpad_device;
80 extern struct litest_test_device litest_synaptics_touchpad_device;
81 extern struct litest_test_device litest_trackpoint_device;
82 extern struct litest_test_device litest_bcm5974_device;
83 extern struct litest_test_device litest_mouse_device;
84 extern struct litest_test_device litest_wacom_touch_device;
86 struct litest_test_device* devices[] = {
87 &litest_synaptics_clickpad_device,
88 &litest_synaptics_touchpad_device,
89 &litest_keyboard_device,
90 &litest_trackpoint_device,
91 &litest_bcm5974_device,
93 &litest_wacom_touch_device,
98 static struct list all_tests;
101 litest_add_tcase_for_device(struct suite *suite,
103 const struct litest_test_device *dev)
106 const char *test_name = dev->shortname;
108 list_for_each(t, &suite->tests, node) {
109 if (strcmp(t->name, test_name) != 0)
112 tcase_add_test(t->tc, func);
116 t = zalloc(sizeof(*t));
117 t->name = strdup(test_name);
118 t->tc = tcase_create(test_name);
119 list_insert(&suite->tests, &t->node);
120 tcase_add_checked_fixture(t->tc, dev->setup,
121 dev->teardown ? dev->teardown : litest_generic_device_teardown);
122 tcase_add_test(t->tc, func);
123 suite_add_tcase(suite->suite, t->tc);
127 litest_add_tcase_no_device(struct suite *suite, void *func)
130 const char *test_name = "no device";
132 list_for_each(t, &suite->tests, node) {
133 if (strcmp(t->name, test_name) != 0)
136 tcase_add_test(t->tc, func);
140 t = zalloc(sizeof(*t));
141 t->name = strdup(test_name);
142 t->tc = tcase_create(test_name);
143 list_insert(&suite->tests, &t->node);
144 tcase_add_test(t->tc, func);
145 suite_add_tcase(suite->suite, t->tc);
149 litest_add_tcase(struct suite *suite, void *func,
150 enum litest_device_feature required,
151 enum litest_device_feature excluded)
153 struct litest_test_device **dev = devices;
155 if (required == LITEST_DISABLE_DEVICE &&
156 excluded == LITEST_DISABLE_DEVICE) {
157 litest_add_tcase_no_device(suite, func);
158 } else if (required != LITEST_ANY || excluded != LITEST_ANY) {
160 if (((*dev)->features & required) == required &&
161 ((*dev)->features & excluded) == 0)
162 litest_add_tcase_for_device(suite, func, *dev);
167 litest_add_tcase_for_device(suite, func, *dev);
174 litest_add_no_device(const char *name, void *func)
176 litest_add(name, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
180 litest_add(const char *name,
182 enum litest_device_feature required,
183 enum litest_device_feature excluded)
187 if (all_tests.next == NULL && all_tests.prev == NULL)
188 list_init(&all_tests);
190 list_for_each(s, &all_tests, node) {
191 if (strcmp(s->name, name) == 0) {
192 litest_add_tcase(s, func, required, excluded);
197 s = zalloc(sizeof(*s));
198 s->name = strdup(name);
199 s->suite = suite_create(s->name);
201 list_init(&s->tests);
202 list_insert(&all_tests, &s->node);
203 litest_add_tcase(s, func, required, excluded);
207 is_debugger_attached(void)
217 int ppid = getppid();
218 if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0) {
219 waitpid(ppid, NULL, 0);
220 ptrace(PTRACE_CONT, NULL, NULL);
221 ptrace(PTRACE_DETACH, ppid, NULL, NULL);
228 waitpid(pid, &status, 0);
229 rc = WEXITSTATUS(status);
237 litest_list_tests(struct list *tests)
241 list_for_each(s, tests, node) {
243 printf("%s:\n", s->name);
244 list_for_each(t, &s->tests, node) {
245 printf(" %s\n", t->name);
251 litest_log_handler(enum libinput_log_priority pri,
256 const char *priority = NULL;
259 case LIBINPUT_LOG_PRIORITY_INFO: priority = "info"; break;
260 case LIBINPUT_LOG_PRIORITY_ERROR: priority = "error"; break;
261 case LIBINPUT_LOG_PRIORITY_DEBUG: priority = "debug"; break;
264 fprintf(stderr, "litest %s: ", priority);
265 vfprintf(stderr, format, args);
268 static const struct option opts[] = {
269 { "list", 0, 0, 'l' },
270 { "verbose", 0, 0, 'v' },
275 litest_run(int argc, char **argv) {
276 struct suite *s, *snext;
280 if (in_debugger == -1) {
281 in_debugger = is_debugger_attached();
283 setenv("CK_FORK", "no", 0);
286 list_for_each(s, &all_tests, node) {
288 sr = srunner_create(s->suite);
290 srunner_add_suite(sr, s->suite);
295 int option_index = 0;
297 c = getopt_long(argc, argv, "", opts, &option_index);
302 litest_list_tests(&all_tests);
305 libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG);
306 libinput_log_set_handler(litest_log_handler, NULL);
309 fprintf(stderr, "usage: %s [--list]\n", argv[0]);
315 srunner_run_all(sr, CK_NORMAL);
316 failed = srunner_ntests_failed(sr);
319 list_for_each_safe(s, snext, &all_tests, node) {
320 struct test *t, *tnext;
322 list_for_each_safe(t, tnext, &s->tests, node) {
324 list_remove(&t->node);
328 list_remove(&s->node);
337 open_restricted(const char *path, int flags, void *userdata)
339 return open(path, flags);
343 close_restricted(int fd, void *userdata)
348 const struct libinput_interface interface = {
349 .open_restricted = open_restricted,
350 .close_restricted = close_restricted,
354 static struct input_absinfo *
355 merge_absinfo(const struct input_absinfo *orig,
356 const struct input_absinfo *override)
358 struct input_absinfo *abs;
360 size_t sz = ABS_MAX + 1;
365 abs = calloc(sz, sizeof(*abs));
366 ck_assert(abs != NULL);
369 while (orig[nelem].value != -1) {
370 abs[nelem] = orig[nelem];
372 ck_assert_int_lt(nelem, sz);
375 /* just append, if the same axis is present twice, libevdev will
376 only use the last value anyway */
378 while (override && override[i].value != -1) {
379 abs[nelem++] = override[i++];
380 ck_assert_int_lt(nelem, sz);
383 ck_assert_int_lt(nelem, sz);
384 abs[nelem].value = -1;
390 merge_events(const int *orig, const int *override)
394 size_t sz = KEY_MAX * 3;
399 events = calloc(sz, sizeof(int));
400 ck_assert(events != NULL);
403 while (orig[nelem] != -1) {
404 events[nelem] = orig[nelem];
406 ck_assert_int_lt(nelem, sz);
409 /* just append, if the same axis is present twice, libevdev will
410 * ignore the double definition anyway */
412 while (override && override[i] != -1) {
413 events[nelem++] = override[i++];
414 ck_assert_int_le(nelem, sz);
417 ck_assert_int_lt(nelem, sz);
424 static struct litest_device *
425 litest_create(enum litest_device_type which,
426 const char *name_override,
427 struct input_id *id_override,
428 const struct input_absinfo *abs_override,
429 const int *events_override)
431 struct litest_device *d = NULL;
432 struct litest_test_device **dev;
434 const struct input_id *id;
435 struct input_absinfo *abs;
440 if ((*dev)->type == which)
446 ck_abort_msg("Invalid device type %d\n", which);
448 d = zalloc(sizeof(*d));
449 ck_assert(d != NULL);
451 /* device has custom create method */
452 if ((*dev)->create) {
454 if (abs_override || events_override)
455 ck_abort_msg("Custom create cannot"
461 abs = merge_absinfo((*dev)->absinfo, abs_override);
462 events = merge_events((*dev)->events, events_override);
463 name = name_override ? name_override : (*dev)->name;
464 id = id_override ? id_override : (*dev)->id;
466 d->uinput = litest_create_uinput_device_from_description(name,
470 d->interface = (*dev)->interface;
479 litest_create_context(void)
481 struct libinput *libinput =
482 libinput_path_create_context(&interface, NULL);
483 ck_assert_notnull(libinput);
487 struct litest_device *
488 litest_add_device_with_overrides(struct libinput *libinput,
489 enum litest_device_type which,
490 const char *name_override,
491 struct input_id *id_override,
492 const struct input_absinfo *abs_override,
493 const int *events_override)
495 struct litest_device *d;
500 d = litest_create(which,
506 path = libevdev_uinput_get_devnode(d->uinput);
507 ck_assert(path != NULL);
508 fd = open(path, O_RDWR|O_NONBLOCK);
509 ck_assert_int_ne(fd, -1);
511 rc = libevdev_new_from_fd(fd, &d->evdev);
512 ck_assert_int_eq(rc, 0);
514 d->libinput = libinput;
515 d->libinput_device = libinput_path_add_device(d->libinput, path);
516 ck_assert(d->libinput_device != NULL);
517 libinput_device_ref(d->libinput_device);
520 d->interface->min[ABS_X] = libevdev_get_abs_minimum(d->evdev, ABS_X);
521 d->interface->max[ABS_X] = libevdev_get_abs_maximum(d->evdev, ABS_X);
522 d->interface->min[ABS_Y] = libevdev_get_abs_minimum(d->evdev, ABS_Y);
523 d->interface->max[ABS_Y] = libevdev_get_abs_maximum(d->evdev, ABS_Y);
528 struct litest_device *
529 litest_create_device_with_overrides(enum litest_device_type which,
530 const char *name_override,
531 struct input_id *id_override,
532 const struct input_absinfo *abs_override,
533 const int *events_override)
535 struct litest_device *dev =
536 litest_add_device_with_overrides(litest_create_context(),
542 dev->owns_context = true;
546 struct litest_device *
547 litest_create_device(enum litest_device_type which)
549 return litest_create_device_with_overrides(which, NULL, NULL, NULL, NULL);
553 litest_handle_events(struct litest_device *d)
557 fd.fd = libinput_get_fd(d->libinput);
560 while (poll(&fd, 1, 1))
561 libinput_dispatch(d->libinput);
567 litest_delete_device(struct litest_device *d)
572 libinput_device_unref(d->libinput_device);
574 libinput_destroy(d->libinput);
575 libevdev_free(d->evdev);
576 libevdev_uinput_destroy(d->uinput);
577 memset(d,0, sizeof(*d));
582 litest_event(struct litest_device *d, unsigned int type,
583 unsigned int code, int value)
585 libevdev_uinput_write_event(d->uinput, type, code, value);
589 auto_assign_value(struct litest_device *d,
590 const struct input_event *ev,
591 int slot, int x, int y)
593 static int tracking_id;
594 int value = ev->value;
596 if (value != LITEST_AUTO_ASSIGN || ev->type != EV_ABS)
601 case ABS_MT_POSITION_X:
602 value = litest_scale(d, ABS_X, x);
605 case ABS_MT_POSITION_Y:
606 value = litest_scale(d, ABS_Y, y);
608 case ABS_MT_TRACKING_ID:
609 value = ++tracking_id;
621 litest_touch_down(struct litest_device *d, unsigned int slot, int x, int y)
623 struct input_event *ev;
625 if (d->interface->touch_down) {
626 d->interface->touch_down(d, slot, x, y);
630 ev = d->interface->touch_down_events;
631 while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
632 int value = auto_assign_value(d, ev, slot, x, y);
633 litest_event(d, ev->type, ev->code, value);
639 litest_touch_up(struct litest_device *d, unsigned int slot)
641 struct input_event *ev;
642 struct input_event up[] = {
643 { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
644 { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
645 { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
646 { .type = -1, .code = -1 }
649 if (d->interface->touch_up) {
650 d->interface->touch_up(d, slot);
652 } else if (d->interface->touch_up_events) {
653 ev = d->interface->touch_up_events;
657 while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
658 int value = auto_assign_value(d, ev, slot, 0, 0);
659 litest_event(d, ev->type, ev->code, value);
665 litest_touch_move(struct litest_device *d, unsigned int slot, int x, int y)
667 struct input_event *ev;
669 if (d->interface->touch_move) {
670 d->interface->touch_move(d, slot, x, y);
674 ev = d->interface->touch_move_events;
675 while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
676 int value = auto_assign_value(d, ev, slot, x, y);
677 litest_event(d, ev->type, ev->code, value);
683 litest_touch_move_to(struct litest_device *d,
685 int x_from, int y_from,
689 for (int i = 0; i < steps - 1; i++)
690 litest_touch_move(d, slot,
691 x_from + (x_to - x_from)/steps * i,
692 y_from + (y_to - y_from)/steps * i);
693 litest_touch_move(d, slot, x_to, y_to);
697 litest_button_click(struct litest_device *d, unsigned int button, bool is_press)
700 struct input_event *ev;
701 struct input_event click[] = {
702 { .type = EV_KEY, .code = button, .value = is_press ? 1 : 0 },
703 { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
706 ARRAY_FOR_EACH(click, ev)
707 litest_event(d, ev->type, ev->code, ev->value);
711 litest_keyboard_key(struct litest_device *d, unsigned int key, bool is_press)
713 litest_button_click(d, key, is_press);
716 int litest_scale(const struct litest_device *d, unsigned int axis, int val)
719 ck_assert_int_ge(val, 0);
720 ck_assert_int_le(val, 100);
721 ck_assert_int_le(axis, ABS_Y);
723 min = d->interface->min[axis];
724 max = d->interface->max[axis];
725 return (max - min) * val/100.0 + min;
729 litest_drain_events(struct libinput *li)
731 struct libinput_event *event;
733 libinput_dispatch(li);
734 while ((event = libinput_get_event(li))) {
735 libinput_event_destroy(event);
736 libinput_dispatch(li);
741 litest_print_event(struct libinput_event *event)
743 struct libinput_event_pointer *p;
744 struct libinput_device *dev;
745 enum libinput_event_type type;
748 dev = libinput_event_get_device(event);
749 type = libinput_event_get_type(event);
752 "device %s type %d ",
753 libinput_device_get_sysname(dev),
756 case LIBINPUT_EVENT_POINTER_MOTION:
757 p = libinput_event_get_pointer_event(event);
758 x = libinput_event_pointer_get_dx(p);
759 y = libinput_event_pointer_get_dy(p);
760 fprintf(stderr, "motion: %.2f/%.2f", x, y);
762 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
763 p = libinput_event_get_pointer_event(event);
764 x = libinput_event_pointer_get_absolute_x(p);
765 y = libinput_event_pointer_get_absolute_y(p);
766 fprintf(stderr, "motion: %.2f/%.2f", x, y);
768 case LIBINPUT_EVENT_POINTER_BUTTON:
769 p = libinput_event_get_pointer_event(event);
771 "button: %d state %d",
772 libinput_event_pointer_get_button(p),
773 libinput_event_pointer_get_button_state(p));
779 fprintf(stderr, "\n");
783 litest_assert_empty_queue(struct libinput *li)
785 bool empty_queue = true;
786 struct libinput_event *event;
788 libinput_dispatch(li);
789 while ((event = libinput_get_event(li))) {
792 "Unexpected event: ");
793 litest_print_event(event);
794 libinput_event_destroy(event);
795 libinput_dispatch(li);
798 ck_assert(empty_queue);
801 struct libevdev_uinput *
802 litest_create_uinput_device_from_description(const char *name,
803 const struct input_id *id,
804 const struct input_absinfo *abs,
807 struct libevdev_uinput *uinput;
808 struct libevdev *dev;
811 const struct input_absinfo default_abs = {
820 dev = libevdev_new();
821 ck_assert(dev != NULL);
823 libevdev_set_name(dev, name);
825 libevdev_set_id_bustype(dev, id->bustype);
826 libevdev_set_id_vendor(dev, id->vendor);
827 libevdev_set_id_product(dev, id->product);
830 while (abs && abs->value != -1) {
831 rc = libevdev_enable_event_code(dev, EV_ABS,
833 ck_assert_int_eq(rc, 0);
838 (type = *events++) != -1 &&
839 (code = *events++) != -1) {
840 if (type == INPUT_PROP_MAX) {
841 rc = libevdev_enable_property(dev, code);
844 ck_assert(!libevdev_has_event_code(dev, type, code));
845 rc = libevdev_enable_event_code(dev, type, code,
846 type == EV_ABS ? &default_abs : NULL);
848 ck_assert_int_eq(rc, 0);
851 rc = libevdev_uinput_create_from_device(dev,
852 LIBEVDEV_UINPUT_OPEN_MANAGED,
854 ck_assert_int_eq(rc, 0);
861 static struct libevdev_uinput *
862 litest_create_uinput_abs_device_v(const char *name,
864 const struct input_absinfo *abs,
867 int events[KEY_MAX * 2 + 2]; /* increase this if not sufficient */
871 while ((type = va_arg(args, int)) != -1 &&
872 (code = va_arg(args, int)) != -1) {
875 ck_assert(event < &events[ARRAY_LENGTH(events) - 2]);
881 return litest_create_uinput_device_from_description(name, id,
885 struct libevdev_uinput *
886 litest_create_uinput_abs_device(const char *name,
888 const struct input_absinfo *abs,
891 struct libevdev_uinput *uinput;
895 uinput = litest_create_uinput_abs_device_v(name, id, abs, args);
901 struct libevdev_uinput *
902 litest_create_uinput_device(const char *name, struct input_id *id, ...)
904 struct libevdev_uinput *uinput;
908 uinput = litest_create_uinput_abs_device_v(name, id, NULL, args);