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
38 #include "linux/input.h"
39 #include <sys/ptrace.h>
40 #include <sys/timerfd.h>
44 #include "litest-int.h"
45 #include "libinput-util.h"
47 static int in_debugger = -1;
48 static int verbose = 0;
54 enum litest_device_type devices;
64 static struct litest_device *current_device;
66 struct litest_device *litest_current_device(void) {
67 return current_device;
70 void litest_set_current_device(struct litest_device *device) {
71 current_device = device;
74 void litest_generic_device_teardown(void)
76 litest_delete_device(current_device);
77 current_device = NULL;
80 extern struct litest_test_device litest_keyboard_device;
81 extern struct litest_test_device litest_synaptics_clickpad_device;
82 extern struct litest_test_device litest_synaptics_touchpad_device;
83 extern struct litest_test_device litest_synaptics_t440_device;
84 extern struct litest_test_device litest_trackpoint_device;
85 extern struct litest_test_device litest_bcm5974_device;
86 extern struct litest_test_device litest_mouse_device;
87 extern struct litest_test_device litest_wacom_touch_device;
88 extern struct litest_test_device litest_alps_device;
90 struct litest_test_device* devices[] = {
91 &litest_synaptics_clickpad_device,
92 &litest_synaptics_touchpad_device,
93 &litest_synaptics_t440_device,
94 &litest_keyboard_device,
95 &litest_trackpoint_device,
96 &litest_bcm5974_device,
98 &litest_wacom_touch_device,
103 static struct list all_tests;
106 litest_add_tcase_for_device(struct suite *suite,
108 const struct litest_test_device *dev)
111 const char *test_name = dev->shortname;
113 list_for_each(t, &suite->tests, node) {
114 if (strcmp(t->name, test_name) != 0)
117 tcase_add_test(t->tc, func);
121 t = zalloc(sizeof(*t));
122 t->name = strdup(test_name);
123 t->tc = tcase_create(test_name);
124 list_insert(&suite->tests, &t->node);
125 tcase_add_checked_fixture(t->tc, dev->setup,
126 dev->teardown ? dev->teardown : litest_generic_device_teardown);
127 tcase_add_test(t->tc, func);
128 suite_add_tcase(suite->suite, t->tc);
132 litest_add_tcase_no_device(struct suite *suite, void *func)
135 const char *test_name = "no device";
137 list_for_each(t, &suite->tests, node) {
138 if (strcmp(t->name, test_name) != 0)
141 tcase_add_test(t->tc, func);
145 t = zalloc(sizeof(*t));
146 t->name = strdup(test_name);
147 t->tc = tcase_create(test_name);
148 list_insert(&suite->tests, &t->node);
149 tcase_add_test(t->tc, func);
150 suite_add_tcase(suite->suite, t->tc);
154 litest_add_tcase(struct suite *suite, void *func,
155 enum litest_device_feature required,
156 enum litest_device_feature excluded)
158 struct litest_test_device **dev = devices;
160 if (required == LITEST_DISABLE_DEVICE &&
161 excluded == LITEST_DISABLE_DEVICE) {
162 litest_add_tcase_no_device(suite, func);
163 } else if (required != LITEST_ANY || excluded != LITEST_ANY) {
165 if (((*dev)->features & required) == required &&
166 ((*dev)->features & excluded) == 0)
167 litest_add_tcase_for_device(suite, func, *dev);
172 litest_add_tcase_for_device(suite, func, *dev);
179 litest_add_no_device(const char *name, void *func)
181 litest_add(name, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
184 static struct suite *
185 get_suite(const char *name)
189 if (all_tests.next == NULL && all_tests.prev == NULL)
190 list_init(&all_tests);
192 list_for_each(s, &all_tests, node) {
193 if (strcmp(s->name, name) == 0)
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);
208 litest_add(const char *name,
210 enum litest_device_feature required,
211 enum litest_device_feature excluded)
213 litest_add_tcase(get_suite(name), func, required, excluded);
217 litest_add_for_device(const char *name,
219 enum litest_device_type type)
222 struct litest_test_device **dev = devices;
226 if ((*dev)->type == type) {
227 litest_add_tcase_for_device(s, func, *dev);
233 ck_abort_msg("Invalid test device type");
237 is_debugger_attached(void)
247 int ppid = getppid();
248 if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0) {
249 waitpid(ppid, NULL, 0);
250 ptrace(PTRACE_CONT, NULL, NULL);
251 ptrace(PTRACE_DETACH, ppid, NULL, NULL);
258 waitpid(pid, &status, 0);
259 rc = WEXITSTATUS(status);
266 litest_list_tests(struct list *tests)
270 list_for_each(s, tests, node) {
272 printf("%s:\n", s->name);
273 list_for_each(t, &s->tests, node) {
274 printf(" %s\n", t->name);
280 litest_log_handler(struct libinput *libinput,
281 enum libinput_log_priority pri,
285 const char *priority = NULL;
288 case LIBINPUT_LOG_PRIORITY_INFO: priority = "info"; break;
289 case LIBINPUT_LOG_PRIORITY_ERROR: priority = "error"; break;
290 case LIBINPUT_LOG_PRIORITY_DEBUG: priority = "debug"; break;
293 fprintf(stderr, "litest %s: ", priority);
294 vfprintf(stderr, format, args);
298 open_restricted(const char *path, int flags, void *userdata)
300 return open(path, flags);
304 close_restricted(int fd, void *userdata)
309 struct libinput_interface interface = {
310 .open_restricted = open_restricted,
311 .close_restricted = close_restricted,
314 static const struct option opts[] = {
315 { "list", 0, 0, 'l' },
316 { "verbose", 0, 0, 'v' },
321 litest_run(int argc, char **argv) {
322 struct suite *s, *snext;
326 if (in_debugger == -1) {
327 in_debugger = is_debugger_attached();
329 setenv("CK_FORK", "no", 0);
332 list_for_each(s, &all_tests, node) {
334 sr = srunner_create(s->suite);
336 srunner_add_suite(sr, s->suite);
341 int option_index = 0;
343 c = getopt_long(argc, argv, "", opts, &option_index);
348 litest_list_tests(&all_tests);
354 fprintf(stderr, "usage: %s [--list]\n", argv[0]);
360 srunner_run_all(sr, CK_NORMAL);
361 failed = srunner_ntests_failed(sr);
364 list_for_each_safe(s, snext, &all_tests, node) {
365 struct test *t, *tnext;
367 list_for_each_safe(t, tnext, &s->tests, node) {
369 list_remove(&t->node);
373 list_remove(&s->node);
381 static struct input_absinfo *
382 merge_absinfo(const struct input_absinfo *orig,
383 const struct input_absinfo *override)
385 struct input_absinfo *abs;
386 unsigned int nelem, i;
387 size_t sz = ABS_MAX + 1;
392 abs = calloc(sz, sizeof(*abs));
393 ck_assert(abs != NULL);
396 while (orig[nelem].value != -1) {
397 abs[nelem] = orig[nelem];
399 ck_assert_int_lt(nelem, sz);
402 /* just append, if the same axis is present twice, libevdev will
403 only use the last value anyway */
405 while (override && override[i].value != -1) {
406 abs[nelem++] = override[i++];
407 ck_assert_int_lt(nelem, sz);
410 ck_assert_int_lt(nelem, sz);
411 abs[nelem].value = -1;
417 merge_events(const int *orig, const int *override)
420 unsigned int nelem, i;
421 size_t sz = KEY_MAX * 3;
426 events = calloc(sz, sizeof(int));
427 ck_assert(events != NULL);
430 while (orig[nelem] != -1) {
431 events[nelem] = orig[nelem];
433 ck_assert_int_lt(nelem, sz);
436 /* just append, if the same axis is present twice, libevdev will
437 * ignore the double definition anyway */
439 while (override && override[i] != -1) {
440 events[nelem++] = override[i++];
441 ck_assert_int_le(nelem, sz);
444 ck_assert_int_lt(nelem, sz);
450 static struct litest_device *
451 litest_create(enum litest_device_type which,
452 const char *name_override,
453 struct input_id *id_override,
454 const struct input_absinfo *abs_override,
455 const int *events_override)
457 struct litest_device *d = NULL;
458 struct litest_test_device **dev;
460 const struct input_id *id;
461 struct input_absinfo *abs;
466 if ((*dev)->type == which)
472 ck_abort_msg("Invalid device type %d\n", which);
474 d = zalloc(sizeof(*d));
475 ck_assert(d != NULL);
477 /* device has custom create method */
478 if ((*dev)->create) {
480 if (abs_override || events_override)
481 ck_abort_msg("Custom create cannot"
487 abs = merge_absinfo((*dev)->absinfo, abs_override);
488 events = merge_events((*dev)->events, events_override);
489 name = name_override ? name_override : (*dev)->name;
490 id = id_override ? id_override : (*dev)->id;
492 d->uinput = litest_create_uinput_device_from_description(name,
496 d->interface = (*dev)->interface;
505 litest_create_context(void)
507 struct libinput *libinput =
508 libinput_path_create_context(&interface, NULL);
509 ck_assert_notnull(libinput);
511 libinput_log_set_handler(libinput, litest_log_handler);
513 libinput_log_set_priority(libinput, LIBINPUT_LOG_PRIORITY_DEBUG);
518 struct litest_device *
519 litest_add_device_with_overrides(struct libinput *libinput,
520 enum litest_device_type which,
521 const char *name_override,
522 struct input_id *id_override,
523 const struct input_absinfo *abs_override,
524 const int *events_override)
526 struct litest_device *d;
531 d = litest_create(which,
537 path = libevdev_uinput_get_devnode(d->uinput);
538 ck_assert(path != NULL);
539 fd = open(path, O_RDWR|O_NONBLOCK);
540 ck_assert_int_ne(fd, -1);
542 rc = libevdev_new_from_fd(fd, &d->evdev);
543 ck_assert_int_eq(rc, 0);
545 d->libinput = libinput;
546 d->libinput_device = libinput_path_add_device(d->libinput, path);
547 ck_assert(d->libinput_device != NULL);
548 libinput_device_ref(d->libinput_device);
551 d->interface->min[ABS_X] = libevdev_get_abs_minimum(d->evdev, ABS_X);
552 d->interface->max[ABS_X] = libevdev_get_abs_maximum(d->evdev, ABS_X);
553 d->interface->min[ABS_Y] = libevdev_get_abs_minimum(d->evdev, ABS_Y);
554 d->interface->max[ABS_Y] = libevdev_get_abs_maximum(d->evdev, ABS_Y);
559 struct litest_device *
560 litest_create_device_with_overrides(enum litest_device_type which,
561 const char *name_override,
562 struct input_id *id_override,
563 const struct input_absinfo *abs_override,
564 const int *events_override)
566 struct litest_device *dev =
567 litest_add_device_with_overrides(litest_create_context(),
573 dev->owns_context = true;
577 struct litest_device *
578 litest_create_device(enum litest_device_type which)
580 return litest_create_device_with_overrides(which, NULL, NULL, NULL, NULL);
584 litest_handle_events(struct litest_device *d)
588 fd.fd = libinput_get_fd(d->libinput);
591 while (poll(&fd, 1, 1))
592 libinput_dispatch(d->libinput);
598 litest_delete_device(struct litest_device *d)
603 libinput_device_unref(d->libinput_device);
604 libinput_path_remove_device(d->libinput_device);
606 libinput_unref(d->libinput);
607 libevdev_free(d->evdev);
608 libevdev_uinput_destroy(d->uinput);
610 memset(d,0, sizeof(*d));
615 litest_event(struct litest_device *d, unsigned int type,
616 unsigned int code, int value)
618 int ret = libevdev_uinput_write_event(d->uinput, type, code, value);
619 ck_assert_int_eq(ret, 0);
623 litest_auto_assign_value(struct litest_device *d,
624 const struct input_event *ev,
625 int slot, double x, double y)
627 static int tracking_id;
628 int value = ev->value;
630 if (value != LITEST_AUTO_ASSIGN || ev->type != EV_ABS)
635 case ABS_MT_POSITION_X:
636 value = litest_scale(d, ABS_X, x);
639 case ABS_MT_POSITION_Y:
640 value = litest_scale(d, ABS_Y, y);
642 case ABS_MT_TRACKING_ID:
643 value = ++tracking_id;
654 send_btntool(struct litest_device *d)
656 litest_event(d, EV_KEY, BTN_TOUCH, d->ntouches_down != 0);
657 litest_event(d, EV_KEY, BTN_TOOL_FINGER, d->ntouches_down == 1);
658 litest_event(d, EV_KEY, BTN_TOOL_DOUBLETAP, d->ntouches_down == 2);
659 litest_event(d, EV_KEY, BTN_TOOL_TRIPLETAP, d->ntouches_down == 3);
660 litest_event(d, EV_KEY, BTN_TOOL_QUADTAP, d->ntouches_down == 4);
661 litest_event(d, EV_KEY, BTN_TOOL_QUINTTAP, d->ntouches_down == 5);
665 litest_touch_down(struct litest_device *d, unsigned int slot,
668 struct input_event *ev;
670 assert(++d->ntouches_down > 0);
674 if (d->interface->touch_down) {
675 d->interface->touch_down(d, slot, x, y);
679 ev = d->interface->touch_down_events;
680 while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
681 int value = litest_auto_assign_value(d, ev, slot, x, y);
682 litest_event(d, ev->type, ev->code, value);
688 litest_touch_up(struct litest_device *d, unsigned int slot)
690 struct input_event *ev;
691 struct input_event up[] = {
692 { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
693 { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
694 { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
695 { .type = -1, .code = -1 }
698 assert(--d->ntouches_down >= 0);
702 if (d->interface->touch_up) {
703 d->interface->touch_up(d, slot);
705 } else if (d->interface->touch_up_events) {
706 ev = d->interface->touch_up_events;
710 while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
711 int value = litest_auto_assign_value(d, ev, slot, 0, 0);
712 litest_event(d, ev->type, ev->code, value);
718 litest_touch_move(struct litest_device *d, unsigned int slot,
721 struct input_event *ev;
723 if (d->interface->touch_move) {
724 d->interface->touch_move(d, slot, x, y);
728 ev = d->interface->touch_move_events;
729 while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
730 int value = litest_auto_assign_value(d, ev, slot, x, y);
731 litest_event(d, ev->type, ev->code, value);
737 litest_touch_move_to(struct litest_device *d,
739 double x_from, double y_from,
740 double x_to, double y_to,
743 for (int i = 0; i < steps - 1; i++)
744 litest_touch_move(d, slot,
745 x_from + (x_to - x_from)/steps * i,
746 y_from + (y_to - y_from)/steps * i);
747 litest_touch_move(d, slot, x_to, y_to);
751 litest_button_click(struct litest_device *d, unsigned int button, bool is_press)
754 struct input_event *ev;
755 struct input_event click[] = {
756 { .type = EV_KEY, .code = button, .value = is_press ? 1 : 0 },
757 { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
760 ARRAY_FOR_EACH(click, ev)
761 litest_event(d, ev->type, ev->code, ev->value);
765 litest_keyboard_key(struct litest_device *d, unsigned int key, bool is_press)
767 litest_button_click(d, key, is_press);
771 litest_scale(const struct litest_device *d, unsigned int axis, double val)
774 ck_assert_int_ge(val, 0);
775 ck_assert_int_le(val, 100);
776 ck_assert_int_le(axis, ABS_Y);
778 min = d->interface->min[axis];
779 max = d->interface->max[axis];
780 return (max - min) * val/100.0 + min;
784 litest_drain_events(struct libinput *li)
786 struct libinput_event *event;
788 libinput_dispatch(li);
789 while ((event = libinput_get_event(li))) {
790 libinput_event_destroy(event);
791 libinput_dispatch(li);
796 litest_print_event(struct libinput_event *event)
798 struct libinput_event_pointer *p;
799 struct libinput_device *dev;
800 enum libinput_event_type type;
803 dev = libinput_event_get_device(event);
804 type = libinput_event_get_type(event);
807 "device %s type %d ",
808 libinput_device_get_sysname(dev),
811 case LIBINPUT_EVENT_POINTER_MOTION:
812 p = libinput_event_get_pointer_event(event);
813 x = libinput_event_pointer_get_dx(p);
814 y = libinput_event_pointer_get_dy(p);
815 fprintf(stderr, "motion: %.2f/%.2f", x, y);
817 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
818 p = libinput_event_get_pointer_event(event);
819 x = libinput_event_pointer_get_absolute_x(p);
820 y = libinput_event_pointer_get_absolute_y(p);
821 fprintf(stderr, "motion: %.2f/%.2f", x, y);
823 case LIBINPUT_EVENT_POINTER_BUTTON:
824 p = libinput_event_get_pointer_event(event);
826 "button: %d state %d",
827 libinput_event_pointer_get_button(p),
828 libinput_event_pointer_get_button_state(p));
834 fprintf(stderr, "\n");
838 litest_assert_empty_queue(struct libinput *li)
840 bool empty_queue = true;
841 struct libinput_event *event;
843 libinput_dispatch(li);
844 while ((event = libinput_get_event(li))) {
847 "Unexpected event: ");
848 litest_print_event(event);
849 libinput_event_destroy(event);
850 libinput_dispatch(li);
853 ck_assert(empty_queue);
856 struct libevdev_uinput *
857 litest_create_uinput_device_from_description(const char *name,
858 const struct input_id *id,
859 const struct input_absinfo *abs_info,
862 struct libevdev_uinput *uinput;
863 struct libevdev *dev;
866 const struct input_absinfo *abs;
867 const struct input_absinfo default_abs = {
878 dev = libevdev_new();
879 ck_assert(dev != NULL);
881 snprintf(buf, sizeof(buf), "litest %s", name);
882 libevdev_set_name(dev, buf);
884 libevdev_set_id_bustype(dev, id->bustype);
885 libevdev_set_id_vendor(dev, id->vendor);
886 libevdev_set_id_product(dev, id->product);
890 while (abs && abs->value != -1) {
891 rc = libevdev_enable_event_code(dev, EV_ABS,
893 ck_assert_int_eq(rc, 0);
898 (type = *events++) != -1 &&
899 (code = *events++) != -1) {
900 if (type == INPUT_PROP_MAX) {
901 rc = libevdev_enable_property(dev, code);
903 rc = libevdev_enable_event_code(dev, type, code,
904 type == EV_ABS ? &default_abs : NULL);
906 ck_assert_int_eq(rc, 0);
909 rc = libevdev_uinput_create_from_device(dev,
910 LIBEVDEV_UINPUT_OPEN_MANAGED,
912 ck_assert_int_eq(rc, 0);
916 /* uinput does not yet support setting the resolution, so we set it
917 * afterwards. This is of course racy as hell but the way we
918 * _generally_ use this function by the time libinput uses the
919 * device, we're finished here */
921 devnode = libevdev_uinput_get_devnode(uinput);
922 ck_assert_notnull(devnode);
923 fd = open(devnode, O_RDONLY);
924 ck_assert_int_gt(fd, -1);
925 rc = libevdev_new_from_fd(fd, &dev);
926 ck_assert_int_eq(rc, 0);
929 while (abs && abs->value != -1) {
930 if (abs->resolution != 0) {
931 rc = libevdev_kernel_set_abs_info(dev,
934 ck_assert_int_eq(rc, 0);
944 static struct libevdev_uinput *
945 litest_create_uinput_abs_device_v(const char *name,
947 const struct input_absinfo *abs,
950 int events[KEY_MAX * 2 + 2]; /* increase this if not sufficient */
954 while ((type = va_arg(args, int)) != -1 &&
955 (code = va_arg(args, int)) != -1) {
958 ck_assert(event < &events[ARRAY_LENGTH(events) - 2]);
964 return litest_create_uinput_device_from_description(name, id,
968 struct libevdev_uinput *
969 litest_create_uinput_abs_device(const char *name,
971 const struct input_absinfo *abs,
974 struct libevdev_uinput *uinput;
978 uinput = litest_create_uinput_abs_device_v(name, id, abs, args);
984 struct libevdev_uinput *
985 litest_create_uinput_device(const char *name, struct input_id *id, ...)
987 struct libevdev_uinput *uinput;
991 uinput = litest_create_uinput_abs_device_v(name, id, NULL, args);