style fix: Remove duplicate empty lines
[platform/upstream/libinput.git] / test / litest.c
1 /*
2  * Copyright © 2013 Red Hat, Inc.
3  *
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.
13  *
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
20  * OF THIS SOFTWARE.
21  */
22
23 #if HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <check.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <getopt.h>
31 #include <poll.h>
32 #include <stdint.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <time.h>
36 #include <unistd.h>
37 #include "linux/input.h"
38 #include <sys/ptrace.h>
39 #include <sys/timerfd.h>
40 #include <sys/wait.h>
41
42 #include "litest.h"
43 #include "litest-int.h"
44 #include "libinput-util.h"
45
46 static int in_debugger = -1;
47 static int verbose = 0;
48
49 struct test {
50         struct list node;
51         char *name;
52         TCase *tc;
53         enum litest_device_type devices;
54 };
55
56 struct suite {
57         struct list node;
58         struct list tests;
59         char *name;
60         Suite *suite;
61 };
62
63 static struct litest_device *current_device;
64
65 struct litest_device *litest_current_device(void) {
66         return current_device;
67 }
68
69 void litest_set_current_device(struct litest_device *device) {
70         current_device = device;
71 }
72
73 void litest_generic_device_teardown(void)
74 {
75         litest_delete_device(current_device);
76         current_device = NULL;
77 }
78
79 extern struct litest_test_device litest_keyboard_device;
80 extern struct litest_test_device litest_synaptics_clickpad_device;
81 extern struct litest_test_device litest_synaptics_touchpad_device;
82 extern struct litest_test_device litest_synaptics_t440_device;
83 extern struct litest_test_device litest_trackpoint_device;
84 extern struct litest_test_device litest_bcm5974_device;
85 extern struct litest_test_device litest_mouse_device;
86 extern struct litest_test_device litest_wacom_touch_device;
87
88 struct litest_test_device* devices[] = {
89         &litest_synaptics_clickpad_device,
90         &litest_synaptics_touchpad_device,
91         &litest_synaptics_t440_device,
92         &litest_keyboard_device,
93         &litest_trackpoint_device,
94         &litest_bcm5974_device,
95         &litest_mouse_device,
96         &litest_wacom_touch_device,
97         NULL,
98 };
99
100 static struct list all_tests;
101
102 static void
103 litest_add_tcase_for_device(struct suite *suite,
104                             void *func,
105                             const struct litest_test_device *dev)
106 {
107         struct test *t;
108         const char *test_name = dev->shortname;
109
110         list_for_each(t, &suite->tests, node) {
111                 if (strcmp(t->name, test_name) != 0)
112                         continue;
113
114                 tcase_add_test(t->tc, func);
115                 return;
116         }
117
118         t = zalloc(sizeof(*t));
119         t->name = strdup(test_name);
120         t->tc = tcase_create(test_name);
121         list_insert(&suite->tests, &t->node);
122         tcase_add_checked_fixture(t->tc, dev->setup,
123                                   dev->teardown ? dev->teardown : litest_generic_device_teardown);
124         tcase_add_test(t->tc, func);
125         suite_add_tcase(suite->suite, t->tc);
126 }
127
128 static void
129 litest_add_tcase_no_device(struct suite *suite, void *func)
130 {
131         struct test *t;
132         const char *test_name = "no device";
133
134         list_for_each(t, &suite->tests, node) {
135                 if (strcmp(t->name, test_name) != 0)
136                         continue;
137
138                 tcase_add_test(t->tc, func);
139                 return;
140         }
141
142         t = zalloc(sizeof(*t));
143         t->name = strdup(test_name);
144         t->tc = tcase_create(test_name);
145         list_insert(&suite->tests, &t->node);
146         tcase_add_test(t->tc, func);
147         suite_add_tcase(suite->suite, t->tc);
148 }
149
150 static void
151 litest_add_tcase(struct suite *suite, void *func,
152                  enum litest_device_feature required,
153                  enum litest_device_feature excluded)
154 {
155         struct litest_test_device **dev = devices;
156
157         if (required == LITEST_DISABLE_DEVICE &&
158             excluded == LITEST_DISABLE_DEVICE) {
159                 litest_add_tcase_no_device(suite, func);
160         } else if (required != LITEST_ANY || excluded != LITEST_ANY) {
161                 while (*dev) {
162                         if (((*dev)->features & required) == required &&
163                             ((*dev)->features & excluded) == 0)
164                                 litest_add_tcase_for_device(suite, func, *dev);
165                         dev++;
166                 }
167         } else {
168                 while (*dev) {
169                         litest_add_tcase_for_device(suite, func, *dev);
170                         dev++;
171                 }
172         }
173 }
174
175 void
176 litest_add_no_device(const char *name, void *func)
177 {
178         litest_add(name, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
179 }
180
181 void
182 litest_add(const char *name,
183            void *func,
184            enum litest_device_feature required,
185            enum litest_device_feature excluded)
186 {
187         struct suite *s;
188
189         if (all_tests.next == NULL && all_tests.prev == NULL)
190                 list_init(&all_tests);
191
192         list_for_each(s, &all_tests, node) {
193                 if (strcmp(s->name, name) == 0) {
194                         litest_add_tcase(s, func, required, excluded);
195                         return;
196                 }
197         }
198
199         s = zalloc(sizeof(*s));
200         s->name = strdup(name);
201         s->suite = suite_create(s->name);
202
203         list_init(&s->tests);
204         list_insert(&all_tests, &s->node);
205         litest_add_tcase(s, func, required, excluded);
206 }
207
208 static int
209 is_debugger_attached(void)
210 {
211         int status;
212         int rc;
213         int pid = fork();
214
215         if (pid == -1)
216                 return 0;
217
218         if (pid == 0) {
219                 int ppid = getppid();
220                 if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0) {
221                         waitpid(ppid, NULL, 0);
222                         ptrace(PTRACE_CONT, NULL, NULL);
223                         ptrace(PTRACE_DETACH, ppid, NULL, NULL);
224                         rc = 0;
225                 } else {
226                         rc = 1;
227                 }
228                 _exit(rc);
229         } else {
230                 waitpid(pid, &status, 0);
231                 rc = WEXITSTATUS(status);
232         }
233
234         return rc;
235 }
236
237 static void
238 litest_list_tests(struct list *tests)
239 {
240         struct suite *s;
241
242         list_for_each(s, tests, node) {
243                 struct test *t;
244                 printf("%s:\n", s->name);
245                 list_for_each(t, &s->tests, node) {
246                         printf("        %s\n", t->name);
247                 }
248         }
249 }
250
251 static void
252 litest_log_handler(struct libinput *libinput,
253                    enum libinput_log_priority pri,
254                    const char *format,
255                    va_list args)
256 {
257         const char *priority = NULL;
258
259         switch(pri) {
260         case LIBINPUT_LOG_PRIORITY_INFO: priority = "info"; break;
261         case LIBINPUT_LOG_PRIORITY_ERROR: priority = "error"; break;
262         case LIBINPUT_LOG_PRIORITY_DEBUG: priority = "debug"; break;
263         }
264
265         fprintf(stderr, "litest %s: ", priority);
266         vfprintf(stderr, format, args);
267 }
268
269 static int
270 open_restricted(const char *path, int flags, void *userdata)
271 {
272         return open(path, flags);
273 }
274
275 static void
276 close_restricted(int fd, void *userdata)
277 {
278         close(fd);
279 }
280
281 struct libinput_interface interface = {
282         .open_restricted = open_restricted,
283         .close_restricted = close_restricted,
284 };
285
286 static const struct option opts[] = {
287         { "list", 0, 0, 'l' },
288         { "verbose", 0, 0, 'v' },
289         { 0, 0, 0, 0}
290 };
291
292 int
293 litest_run(int argc, char **argv) {
294         struct suite *s, *snext;
295         int failed;
296         SRunner *sr = NULL;
297
298         if (in_debugger == -1) {
299                 in_debugger = is_debugger_attached();
300                 if (in_debugger)
301                         setenv("CK_FORK", "no", 0);
302         }
303
304         list_for_each(s, &all_tests, node) {
305                 if (!sr)
306                         sr = srunner_create(s->suite);
307                 else
308                         srunner_add_suite(sr, s->suite);
309         }
310
311         while(1) {
312                 int c;
313                 int option_index = 0;
314
315                 c = getopt_long(argc, argv, "", opts, &option_index);
316                 if (c == -1)
317                         break;
318                 switch(c) {
319                         case 'l':
320                                 litest_list_tests(&all_tests);
321                                 return 0;
322                         case 'v':
323                                 verbose = 1;
324                                 break;
325                         default:
326                                 fprintf(stderr, "usage: %s [--list]\n", argv[0]);
327                                 return 1;
328
329                 }
330         }
331
332         srunner_run_all(sr, CK_NORMAL);
333         failed = srunner_ntests_failed(sr);
334         srunner_free(sr);
335
336         list_for_each_safe(s, snext, &all_tests, node) {
337                 struct test *t, *tnext;
338
339                 list_for_each_safe(t, tnext, &s->tests, node) {
340                         free(t->name);
341                         list_remove(&t->node);
342                         free(t);
343                 }
344
345                 list_remove(&s->node);
346                 free(s->name);
347                 free(s);
348         }
349
350         return failed;
351 }
352
353 static struct input_absinfo *
354 merge_absinfo(const struct input_absinfo *orig,
355               const struct input_absinfo *override)
356 {
357         struct input_absinfo *abs;
358         unsigned int nelem, i;
359         size_t sz = ABS_MAX + 1;
360
361         if (!orig)
362                 return NULL;
363
364         abs = calloc(sz, sizeof(*abs));
365         ck_assert(abs != NULL);
366
367         nelem = 0;
368         while (orig[nelem].value != -1) {
369                 abs[nelem] = orig[nelem];
370                 nelem++;
371                 ck_assert_int_lt(nelem, sz);
372         }
373
374         /* just append, if the same axis is present twice, libevdev will
375            only use the last value anyway */
376         i = 0;
377         while (override && override[i].value != -1) {
378                 abs[nelem++] = override[i++];
379                 ck_assert_int_lt(nelem, sz);
380         }
381
382         ck_assert_int_lt(nelem, sz);
383         abs[nelem].value = -1;
384
385         return abs;
386 }
387
388 static int*
389 merge_events(const int *orig, const int *override)
390 {
391         int *events;
392         unsigned int nelem, i;
393         size_t sz = KEY_MAX * 3;
394
395         if (!orig)
396                 return NULL;
397
398         events = calloc(sz, sizeof(int));
399         ck_assert(events != NULL);
400
401         nelem = 0;
402         while (orig[nelem] != -1) {
403                 events[nelem] = orig[nelem];
404                 nelem++;
405                 ck_assert_int_lt(nelem, sz);
406         }
407
408         /* just append, if the same axis is present twice, libevdev will
409          * ignore the double definition anyway */
410         i = 0;
411         while (override && override[i] != -1) {
412                 events[nelem++] = override[i++];
413                 ck_assert_int_le(nelem, sz);
414         }
415
416         ck_assert_int_lt(nelem, sz);
417         events[nelem] = -1;
418
419         return events;
420 }
421
422 static struct litest_device *
423 litest_create(enum litest_device_type which,
424               const char *name_override,
425               struct input_id *id_override,
426               const struct input_absinfo *abs_override,
427               const int *events_override)
428 {
429         struct litest_device *d = NULL;
430         struct litest_test_device **dev;
431         const char *name;
432         const struct input_id *id;
433         struct input_absinfo *abs;
434         int *events;
435
436         dev = devices;
437         while (*dev) {
438                 if ((*dev)->type == which)
439                         break;
440                 dev++;
441         }
442
443         if (!*dev)
444                 ck_abort_msg("Invalid device type %d\n", which);
445
446         d = zalloc(sizeof(*d));
447         ck_assert(d != NULL);
448
449         /* device has custom create method */
450         if ((*dev)->create) {
451                 (*dev)->create(d);
452                 if (abs_override || events_override)
453                         ck_abort_msg("Custom create cannot"
454                                      "be overridden");
455
456                 return d;
457         }
458
459         abs = merge_absinfo((*dev)->absinfo, abs_override);
460         events = merge_events((*dev)->events, events_override);
461         name = name_override ? name_override : (*dev)->name;
462         id = id_override ? id_override : (*dev)->id;
463
464         d->uinput = litest_create_uinput_device_from_description(name,
465                                                                  id,
466                                                                  abs,
467                                                                  events);
468         d->interface = (*dev)->interface;
469         free(abs);
470         free(events);
471
472         return d;
473
474 }
475
476 struct libinput *
477 litest_create_context(void)
478 {
479         struct libinput *libinput =
480                 libinput_path_create_context(&interface, NULL);
481         ck_assert_notnull(libinput);
482
483         libinput_log_set_handler(libinput, litest_log_handler);
484         if (verbose)
485                 libinput_log_set_priority(libinput, LIBINPUT_LOG_PRIORITY_DEBUG);
486
487         return libinput;
488 }
489
490 struct litest_device *
491 litest_add_device_with_overrides(struct libinput *libinput,
492                                  enum litest_device_type which,
493                                  const char *name_override,
494                                  struct input_id *id_override,
495                                  const struct input_absinfo *abs_override,
496                                  const int *events_override)
497 {
498         struct litest_device *d;
499         int fd;
500         int rc;
501         const char *path;
502
503         d = litest_create(which,
504                           name_override,
505                           id_override,
506                           abs_override,
507                           events_override);
508
509         path = libevdev_uinput_get_devnode(d->uinput);
510         ck_assert(path != NULL);
511         fd = open(path, O_RDWR|O_NONBLOCK);
512         ck_assert_int_ne(fd, -1);
513
514         rc = libevdev_new_from_fd(fd, &d->evdev);
515         ck_assert_int_eq(rc, 0);
516
517         d->libinput = libinput;
518         d->libinput_device = libinput_path_add_device(d->libinput, path);
519         ck_assert(d->libinput_device != NULL);
520         libinput_device_ref(d->libinput_device);
521
522         if (d->interface) {
523                 d->interface->min[ABS_X] = libevdev_get_abs_minimum(d->evdev, ABS_X);
524                 d->interface->max[ABS_X] = libevdev_get_abs_maximum(d->evdev, ABS_X);
525                 d->interface->min[ABS_Y] = libevdev_get_abs_minimum(d->evdev, ABS_Y);
526                 d->interface->max[ABS_Y] = libevdev_get_abs_maximum(d->evdev, ABS_Y);
527         }
528         return d;
529 }
530
531 struct litest_device *
532 litest_create_device_with_overrides(enum litest_device_type which,
533                                     const char *name_override,
534                                     struct input_id *id_override,
535                                     const struct input_absinfo *abs_override,
536                                     const int *events_override)
537 {
538         struct litest_device *dev =
539                 litest_add_device_with_overrides(litest_create_context(),
540                                                  which,
541                                                  name_override,
542                                                  id_override,
543                                                  abs_override,
544                                                  events_override);
545         dev->owns_context = true;
546         return dev;
547 }
548
549 struct litest_device *
550 litest_create_device(enum litest_device_type which)
551 {
552         return litest_create_device_with_overrides(which, NULL, NULL, NULL, NULL);
553 }
554
555 int
556 litest_handle_events(struct litest_device *d)
557 {
558         struct pollfd fd;
559
560         fd.fd = libinput_get_fd(d->libinput);
561         fd.events = POLLIN;
562
563         while (poll(&fd, 1, 1))
564                 libinput_dispatch(d->libinput);
565
566         return 0;
567 }
568
569 void
570 litest_delete_device(struct litest_device *d)
571 {
572         if (!d)
573                 return;
574
575         libinput_device_unref(d->libinput_device);
576         if (d->owns_context)
577                 libinput_unref(d->libinput);
578         libevdev_free(d->evdev);
579         libevdev_uinput_destroy(d->uinput);
580         memset(d,0, sizeof(*d));
581         free(d);
582 }
583
584 void
585 litest_event(struct litest_device *d, unsigned int type,
586              unsigned int code, int value)
587 {
588         int ret = libevdev_uinput_write_event(d->uinput, type, code, value);
589         ck_assert_int_eq(ret, 0);
590 }
591
592 static int
593 auto_assign_value(struct litest_device *d,
594                   const struct input_event *ev,
595                   int slot, double x, double y)
596 {
597         static int tracking_id;
598         int value = ev->value;
599
600         if (value != LITEST_AUTO_ASSIGN || ev->type != EV_ABS)
601                 return value;
602
603         switch (ev->code) {
604         case ABS_X:
605         case ABS_MT_POSITION_X:
606                 value = litest_scale(d, ABS_X, x);
607                 break;
608         case ABS_Y:
609         case ABS_MT_POSITION_Y:
610                 value = litest_scale(d, ABS_Y, y);
611                 break;
612         case ABS_MT_TRACKING_ID:
613                 value = ++tracking_id;
614                 break;
615         case ABS_MT_SLOT:
616                 value = slot;
617                 break;
618         }
619
620         return value;
621 }
622
623
624 void
625 litest_touch_down(struct litest_device *d, unsigned int slot,
626                   double x, double y)
627 {
628         struct input_event *ev;
629
630         if (d->interface->touch_down) {
631                 d->interface->touch_down(d, slot, x, y);
632                 return;
633         }
634
635         ev = d->interface->touch_down_events;
636         while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
637                 int value = auto_assign_value(d, ev, slot, x, y);
638                 litest_event(d, ev->type, ev->code, value);
639                 ev++;
640         }
641 }
642
643 void
644 litest_touch_up(struct litest_device *d, unsigned int slot)
645 {
646         struct input_event *ev;
647         struct input_event up[] = {
648                 { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
649                 { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
650                 { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
651                 { .type = -1, .code = -1 }
652         };
653
654         if (d->interface->touch_up) {
655                 d->interface->touch_up(d, slot);
656                 return;
657         } else if (d->interface->touch_up_events) {
658                 ev = d->interface->touch_up_events;
659         } else
660                 ev = up;
661
662         while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
663                 int value = auto_assign_value(d, ev, slot, 0, 0);
664                 litest_event(d, ev->type, ev->code, value);
665                 ev++;
666         }
667 }
668
669 void
670 litest_touch_move(struct litest_device *d, unsigned int slot,
671                   double x, double y)
672 {
673         struct input_event *ev;
674
675         if (d->interface->touch_move) {
676                 d->interface->touch_move(d, slot, x, y);
677                 return;
678         }
679
680         ev = d->interface->touch_move_events;
681         while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
682                 int value = auto_assign_value(d, ev, slot, x, y);
683                 litest_event(d, ev->type, ev->code, value);
684                 ev++;
685         }
686 }
687
688 void
689 litest_touch_move_to(struct litest_device *d,
690                      unsigned int slot,
691                      double x_from, double y_from,
692                      double x_to, double y_to,
693                      int steps)
694 {
695         for (int i = 0; i < steps - 1; i++)
696                 litest_touch_move(d, slot,
697                                   x_from + (x_to - x_from)/steps * i,
698                                   y_from + (y_to - y_from)/steps * i);
699         litest_touch_move(d, slot, x_to, y_to);
700 }
701
702 void
703 litest_button_click(struct litest_device *d, unsigned int button, bool is_press)
704 {
705
706         struct input_event *ev;
707         struct input_event click[] = {
708                 { .type = EV_KEY, .code = button, .value = is_press ? 1 : 0 },
709                 { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
710         };
711
712         ARRAY_FOR_EACH(click, ev)
713                 litest_event(d, ev->type, ev->code, ev->value);
714 }
715
716 void
717 litest_keyboard_key(struct litest_device *d, unsigned int key, bool is_press)
718 {
719         litest_button_click(d, key, is_press);
720 }
721
722 int
723 litest_scale(const struct litest_device *d, unsigned int axis, double val)
724 {
725         int min, max;
726         ck_assert_int_ge(val, 0);
727         ck_assert_int_le(val, 100);
728         ck_assert_int_le(axis, ABS_Y);
729
730         min = d->interface->min[axis];
731         max = d->interface->max[axis];
732         return (max - min) * val/100.0 + min;
733 }
734
735 void
736 litest_drain_events(struct libinput *li)
737 {
738         struct libinput_event *event;
739
740         libinput_dispatch(li);
741         while ((event = libinput_get_event(li))) {
742                 libinput_event_destroy(event);
743                 libinput_dispatch(li);
744         }
745 }
746
747 static void
748 litest_print_event(struct libinput_event *event)
749 {
750         struct libinput_event_pointer *p;
751         struct libinput_device *dev;
752         enum libinput_event_type type;
753         double x, y;
754
755         dev = libinput_event_get_device(event);
756         type = libinput_event_get_type(event);
757
758         fprintf(stderr,
759                 "device %s type %d ",
760                 libinput_device_get_sysname(dev),
761                 type);
762         switch (type) {
763         case LIBINPUT_EVENT_POINTER_MOTION:
764                 p = libinput_event_get_pointer_event(event);
765                 x = libinput_event_pointer_get_dx(p);
766                 y = libinput_event_pointer_get_dy(p);
767                 fprintf(stderr, "motion: %.2f/%.2f", x, y);
768                 break;
769         case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
770                 p = libinput_event_get_pointer_event(event);
771                 x = libinput_event_pointer_get_absolute_x(p);
772                 y = libinput_event_pointer_get_absolute_y(p);
773                 fprintf(stderr, "motion: %.2f/%.2f", x, y);
774                 break;
775         case LIBINPUT_EVENT_POINTER_BUTTON:
776                 p = libinput_event_get_pointer_event(event);
777                 fprintf(stderr,
778                         "button: %d state %d",
779                         libinput_event_pointer_get_button(p),
780                         libinput_event_pointer_get_button_state(p));
781                 break;
782         default:
783                 break;
784         }
785
786         fprintf(stderr, "\n");
787 }
788
789 void
790 litest_assert_empty_queue(struct libinput *li)
791 {
792         bool empty_queue = true;
793         struct libinput_event *event;
794
795         libinput_dispatch(li);
796         while ((event = libinput_get_event(li))) {
797                 empty_queue = false;
798                 fprintf(stderr,
799                         "Unexpected event: ");
800                 litest_print_event(event);
801                 libinput_event_destroy(event);
802                 libinput_dispatch(li);
803         }
804
805         ck_assert(empty_queue);
806 }
807
808 struct libevdev_uinput *
809 litest_create_uinput_device_from_description(const char *name,
810                                              const struct input_id *id,
811                                              const struct input_absinfo *abs_info,
812                                              const int *events)
813 {
814         struct libevdev_uinput *uinput;
815         struct libevdev *dev;
816         int type, code;
817         int rc, fd;
818         const struct input_absinfo *abs;
819         const struct input_absinfo default_abs = {
820                 .value = 0,
821                 .minimum = 0,
822                 .maximum = 0xffff,
823                 .fuzz = 0,
824                 .flat = 0,
825                 .resolution = 100
826         };
827         char buf[512];
828         const char *devnode;
829
830         dev = libevdev_new();
831         ck_assert(dev != NULL);
832
833         snprintf(buf, sizeof(buf), "litest %s", name);
834         libevdev_set_name(dev, buf);
835         if (id) {
836                 libevdev_set_id_bustype(dev, id->bustype);
837                 libevdev_set_id_vendor(dev, id->vendor);
838                 libevdev_set_id_product(dev, id->product);
839         }
840
841         abs = abs_info;
842         while (abs && abs->value != -1) {
843                 rc = libevdev_enable_event_code(dev, EV_ABS,
844                                                 abs->value, abs);
845                 ck_assert_int_eq(rc, 0);
846                 abs++;
847         }
848
849         while (events &&
850                (type = *events++) != -1 &&
851                (code = *events++) != -1) {
852                 if (type == INPUT_PROP_MAX) {
853                         rc = libevdev_enable_property(dev, code);
854                 } else {
855                         if (type != EV_SYN)
856                                 ck_assert(!libevdev_has_event_code(dev, type, code));
857                         rc = libevdev_enable_event_code(dev, type, code,
858                                                         type == EV_ABS ? &default_abs : NULL);
859                 }
860                 ck_assert_int_eq(rc, 0);
861         }
862
863         rc = libevdev_uinput_create_from_device(dev,
864                                                 LIBEVDEV_UINPUT_OPEN_MANAGED,
865                                                 &uinput);
866         ck_assert_int_eq(rc, 0);
867
868         libevdev_free(dev);
869
870         /* uinput does not yet support setting the resolution, so we set it
871          * afterwards. This is of course racy as hell but the way we
872          * _generally_ use this function by the time libinput uses the
873          * device, we're finished here */
874
875         devnode = libevdev_uinput_get_devnode(uinput);
876         ck_assert_notnull(devnode);
877         fd = open(devnode, O_RDONLY);
878         ck_assert_int_gt(fd, -1);
879         rc = libevdev_new_from_fd(fd, &dev);
880         ck_assert_int_eq(rc, 0);
881
882         abs = abs_info;
883         while (abs && abs->value != -1) {
884                 if (abs->resolution != 0) {
885                         rc = libevdev_kernel_set_abs_info(dev,
886                                                           abs->value,
887                                                           abs);
888                         ck_assert_int_eq(rc, 0);
889                 }
890                 abs++;
891         }
892         close(fd);
893         libevdev_free(dev);
894
895         return uinput;
896 }
897
898 static struct libevdev_uinput *
899 litest_create_uinput_abs_device_v(const char *name,
900                                   struct input_id *id,
901                                   const struct input_absinfo *abs,
902                                   va_list args)
903 {
904         int events[KEY_MAX * 2 + 2]; /* increase this if not sufficient */
905         int *event = events;
906         int type, code;
907
908         while ((type = va_arg(args, int)) != -1 &&
909                (code = va_arg(args, int)) != -1) {
910                 *event++ = type;
911                 *event++ = code;
912                 ck_assert(event < &events[ARRAY_LENGTH(events) - 2]);
913         }
914
915         *event++ = -1;
916         *event++ = -1;
917
918         return litest_create_uinput_device_from_description(name, id,
919                                                             abs, events);
920 }
921
922 struct libevdev_uinput *
923 litest_create_uinput_abs_device(const char *name,
924                                 struct input_id *id,
925                                 const struct input_absinfo *abs,
926                                 ...)
927 {
928         struct libevdev_uinput *uinput;
929         va_list args;
930
931         va_start(args, abs);
932         uinput = litest_create_uinput_abs_device_v(name, id, abs, args);
933         va_end(args);
934
935         return uinput;
936 }
937
938 struct libevdev_uinput *
939 litest_create_uinput_device(const char *name, struct input_id *id, ...)
940 {
941         struct libevdev_uinput *uinput;
942         va_list args;
943
944         va_start(args, id);
945         uinput = litest_create_uinput_abs_device_v(name, id, NULL, args);
946         va_end(args);
947
948         return uinput;
949 }