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);
206 int is_debugger_attached()
216 int ppid = getppid();
217 if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0) {
218 waitpid(ppid, NULL, 0);
219 ptrace(PTRACE_CONT, NULL, NULL);
220 ptrace(PTRACE_DETACH, ppid, NULL, NULL);
227 waitpid(pid, &status, 0);
228 rc = WEXITSTATUS(status);
236 litest_list_tests(struct list *tests)
240 list_for_each(s, tests, node) {
242 printf("%s:\n", s->name);
243 list_for_each(t, &s->tests, node) {
244 printf(" %s\n", t->name);
249 static const struct option opts[] = {
250 { "list", 0, 0, 'l' },
255 litest_run(int argc, char **argv) {
256 struct suite *s, *snext;
260 if (in_debugger == -1) {
261 in_debugger = is_debugger_attached();
263 setenv("CK_FORK", "no", 0);
266 list_for_each(s, &all_tests, node) {
268 sr = srunner_create(s->suite);
270 srunner_add_suite(sr, s->suite);
275 int option_index = 0;
277 c = getopt_long(argc, argv, "", opts, &option_index);
282 litest_list_tests(&all_tests);
285 fprintf(stderr, "usage: %s [--list]\n", argv[0]);
291 srunner_run_all(sr, CK_NORMAL);
292 failed = srunner_ntests_failed(sr);
295 list_for_each_safe(s, snext, &all_tests, node) {
296 struct test *t, *tnext;
298 list_for_each_safe(t, tnext, &s->tests, node) {
300 list_remove(&t->node);
304 list_remove(&s->node);
313 open_restricted(const char *path, int flags, void *userdata)
315 return open(path, flags);
319 close_restricted(int fd, void *userdata)
324 const struct libinput_interface interface = {
325 .open_restricted = open_restricted,
326 .close_restricted = close_restricted,
330 static struct input_absinfo *
331 merge_absinfo(const struct input_absinfo *orig,
332 const struct input_absinfo *override)
334 struct input_absinfo *abs;
336 size_t sz = ABS_MAX + 1;
341 abs = calloc(sz, sizeof(*abs));
342 ck_assert(abs != NULL);
345 while (orig[nelem].value != -1) {
346 abs[nelem] = orig[nelem];
348 ck_assert_int_lt(nelem, sz);
351 /* just append, if the same axis is present twice, libevdev will
352 only use the last value anyway */
354 while (override && override[i].value != -1) {
355 abs[nelem++] = override[i++];
356 ck_assert_int_lt(nelem, sz);
359 ck_assert_int_lt(nelem, sz);
360 abs[nelem].value = -1;
366 merge_events(const int *orig, const int *override)
370 size_t sz = KEY_MAX * 3;
375 events = calloc(sz, sizeof(int));
376 ck_assert(events != NULL);
379 while (orig[nelem] != -1) {
380 events[nelem] = orig[nelem];
382 ck_assert_int_lt(nelem, sz);
385 /* just append, if the same axis is present twice, libevdev will
386 * ignore the double definition anyway */
388 while (override && override[i] != -1) {
389 events[nelem++] = override[i++];
390 ck_assert_int_le(nelem, sz);
393 ck_assert_int_lt(nelem, sz);
400 static struct litest_device *
401 litest_create(enum litest_device_type which,
402 const char *name_override,
403 struct input_id *id_override,
404 const struct input_absinfo *abs_override,
405 const int *events_override)
407 struct litest_device *d = NULL;
408 struct litest_test_device **dev;
410 const struct input_id *id;
411 struct input_absinfo *abs;
416 if ((*dev)->type == which)
422 ck_abort_msg("Invalid device type %d\n", which);
424 d = zalloc(sizeof(*d));
425 ck_assert(d != NULL);
427 /* device has custom create method */
428 if ((*dev)->create) {
430 if (abs_override || events_override)
431 ck_abort_msg("Custom create cannot"
437 abs = merge_absinfo((*dev)->absinfo, abs_override);
438 events = merge_events((*dev)->events, events_override);
439 name = name_override ? name_override : (*dev)->name;
440 id = id_override ? id_override : (*dev)->id;
442 d->uinput = litest_create_uinput_device_from_description(name,
446 d->interface = (*dev)->interface;
455 litest_create_context(void)
457 struct libinput *libinput =
458 libinput_path_create_context(&interface, NULL);
459 ck_assert_notnull(libinput);
463 struct litest_device *
464 litest_add_device_with_overrides(struct libinput *libinput,
465 enum litest_device_type which,
466 const char *name_override,
467 struct input_id *id_override,
468 const struct input_absinfo *abs_override,
469 const int *events_override)
471 struct litest_device *d;
476 d = litest_create(which,
482 path = libevdev_uinput_get_devnode(d->uinput);
483 ck_assert(path != NULL);
484 fd = open(path, O_RDWR|O_NONBLOCK);
485 ck_assert_int_ne(fd, -1);
487 rc = libevdev_new_from_fd(fd, &d->evdev);
488 ck_assert_int_eq(rc, 0);
490 d->libinput = libinput;
491 d->libinput_device = libinput_path_add_device(d->libinput, path);
492 ck_assert(d->libinput_device != NULL);
493 libinput_device_ref(d->libinput_device);
496 d->interface->min[ABS_X] = libevdev_get_abs_minimum(d->evdev, ABS_X);
497 d->interface->max[ABS_X] = libevdev_get_abs_maximum(d->evdev, ABS_X);
498 d->interface->min[ABS_Y] = libevdev_get_abs_minimum(d->evdev, ABS_Y);
499 d->interface->max[ABS_Y] = libevdev_get_abs_maximum(d->evdev, ABS_Y);
504 struct litest_device *
505 litest_create_device_with_overrides(enum litest_device_type which,
506 const char *name_override,
507 struct input_id *id_override,
508 const struct input_absinfo *abs_override,
509 const int *events_override)
511 struct litest_device *dev =
512 litest_add_device_with_overrides(litest_create_context(),
518 dev->owns_context = true;
522 struct litest_device *
523 litest_create_device(enum litest_device_type which)
525 return litest_create_device_with_overrides(which, NULL, NULL, NULL, NULL);
529 litest_handle_events(struct litest_device *d)
533 fd.fd = libinput_get_fd(d->libinput);
536 while (poll(&fd, 1, 1))
537 libinput_dispatch(d->libinput);
543 litest_delete_device(struct litest_device *d)
548 libinput_device_unref(d->libinput_device);
550 libinput_destroy(d->libinput);
551 libevdev_free(d->evdev);
552 libevdev_uinput_destroy(d->uinput);
553 memset(d,0, sizeof(*d));
558 litest_event(struct litest_device *d, unsigned int type,
559 unsigned int code, int value)
561 libevdev_uinput_write_event(d->uinput, type, code, value);
565 auto_assign_value(struct litest_device *d,
566 const struct input_event *ev,
567 int slot, int x, int y)
569 static int tracking_id;
570 int value = ev->value;
572 if (value != LITEST_AUTO_ASSIGN || ev->type != EV_ABS)
577 case ABS_MT_POSITION_X:
578 value = litest_scale(d, ABS_X, x);
581 case ABS_MT_POSITION_Y:
582 value = litest_scale(d, ABS_Y, y);
584 case ABS_MT_TRACKING_ID:
585 value = ++tracking_id;
597 litest_touch_down(struct litest_device *d, unsigned int slot, int x, int y)
599 struct input_event *ev;
601 if (d->interface->touch_down) {
602 d->interface->touch_down(d, slot, x, y);
606 ev = d->interface->touch_down_events;
607 while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
608 int value = auto_assign_value(d, ev, slot, x, y);
609 litest_event(d, ev->type, ev->code, value);
615 litest_touch_up(struct litest_device *d, unsigned int slot)
617 struct input_event *ev;
618 struct input_event up[] = {
619 { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
620 { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
621 { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
622 { .type = -1, .code = -1 }
625 if (d->interface->touch_up) {
626 d->interface->touch_up(d, slot);
628 } else if (d->interface->touch_up_events) {
629 ev = d->interface->touch_up_events;
633 while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
634 int value = auto_assign_value(d, ev, slot, 0, 0);
635 litest_event(d, ev->type, ev->code, value);
641 litest_touch_move(struct litest_device *d, unsigned int slot, int x, int y)
643 struct input_event *ev;
645 if (d->interface->touch_move) {
646 d->interface->touch_move(d, slot, x, y);
650 ev = d->interface->touch_move_events;
651 while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
652 int value = auto_assign_value(d, ev, slot, x, y);
653 litest_event(d, ev->type, ev->code, value);
659 litest_touch_move_to(struct litest_device *d,
661 int x_from, int y_from,
665 for (int i = 0; i < steps - 1; i++)
666 litest_touch_move(d, slot,
667 x_from + (x_to - x_from)/steps * i,
668 y_from + (y_to - y_from)/steps * i);
669 litest_touch_move(d, slot, x_to, y_to);
673 litest_button_click(struct litest_device *d, unsigned int button, bool is_press)
676 struct input_event *ev;
677 struct input_event click[] = {
678 { .type = EV_KEY, .code = button, .value = is_press ? 1 : 0 },
679 { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
682 ARRAY_FOR_EACH(click, ev)
683 litest_event(d, ev->type, ev->code, ev->value);
687 litest_keyboard_key(struct litest_device *d, unsigned int key, bool is_press)
689 litest_button_click(d, key, is_press);
692 int litest_scale(const struct litest_device *d, unsigned int axis, int val)
695 ck_assert_int_ge(val, 0);
696 ck_assert_int_le(val, 100);
697 ck_assert_int_le(axis, ABS_Y);
699 min = d->interface->min[axis];
700 max = d->interface->max[axis];
701 return (max - min) * val/100.0 + min;
705 litest_drain_events(struct libinput *li)
707 struct libinput_event *event;
709 libinput_dispatch(li);
710 while ((event = libinput_get_event(li))) {
711 libinput_event_destroy(event);
712 libinput_dispatch(li);
716 struct libevdev_uinput *
717 litest_create_uinput_device_from_description(const char *name,
718 const struct input_id *id,
719 const struct input_absinfo *abs,
722 struct libevdev_uinput *uinput;
723 struct libevdev *dev;
726 const struct input_absinfo default_abs = {
735 dev = libevdev_new();
736 ck_assert(dev != NULL);
738 libevdev_set_name(dev, name);
740 libevdev_set_id_bustype(dev, id->bustype);
741 libevdev_set_id_vendor(dev, id->vendor);
742 libevdev_set_id_product(dev, id->product);
745 while (abs && abs->value != -1) {
746 rc = libevdev_enable_event_code(dev, EV_ABS,
748 ck_assert_int_eq(rc, 0);
753 (type = *events++) != -1 &&
754 (code = *events++) != -1) {
755 if (type == INPUT_PROP_MAX) {
756 rc = libevdev_enable_property(dev, code);
759 ck_assert(!libevdev_has_event_code(dev, type, code));
760 rc = libevdev_enable_event_code(dev, type, code,
761 type == EV_ABS ? &default_abs : NULL);
763 ck_assert_int_eq(rc, 0);
766 rc = libevdev_uinput_create_from_device(dev,
767 LIBEVDEV_UINPUT_OPEN_MANAGED,
769 ck_assert_int_eq(rc, 0);
776 static struct libevdev_uinput *
777 litest_create_uinput_abs_device_v(const char *name,
779 const struct input_absinfo *abs,
782 int events[KEY_MAX * 2 + 2]; /* increase this if not sufficient */
786 while ((type = va_arg(args, int)) != -1 &&
787 (code = va_arg(args, int)) != -1) {
790 ck_assert(event < &events[ARRAY_LENGTH(events) - 2]);
796 return litest_create_uinput_device_from_description(name, id,
800 struct libevdev_uinput *
801 litest_create_uinput_abs_device(const char *name,
803 const struct input_absinfo *abs,
806 struct libevdev_uinput *uinput;
810 uinput = litest_create_uinput_abs_device_v(name, id, abs, args);
816 struct libevdev_uinput *
817 litest_create_uinput_device(const char *name, struct input_id *id, ...)
819 struct libevdev_uinput *uinput;
823 uinput = litest_create_uinput_abs_device_v(name, id, NULL, args);