touchpad: normalize the touchpad resolution to 400dpi, not 10 units/mm
[platform/upstream/libinput.git] / test / udev.c
1 /*
2  * Copyright © 2013 Red Hat, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include <config.h>
24
25 #include <check.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <libinput.h>
29 #include <libudev.h>
30 #include <unistd.h>
31
32 #include "litest.h"
33
34 static int open_restricted(const char *path, int flags, void *data)
35 {
36         int fd;
37         fd = open(path, flags);
38         return fd < 0 ? -errno : fd;
39 }
40 static void close_restricted(int fd, void *data)
41 {
42         close(fd);
43 }
44
45 const struct libinput_interface simple_interface = {
46         .open_restricted = open_restricted,
47         .close_restricted = close_restricted,
48 };
49
50
51 START_TEST(udev_create_NULL)
52 {
53         struct libinput *li;
54         const struct libinput_interface interface;
55         struct udev *udev;
56
57         udev = udev_new();
58
59         li = libinput_udev_create_context(NULL, NULL, NULL);
60         ck_assert(li == NULL);
61
62         li = libinput_udev_create_context(&interface, NULL, NULL);
63         ck_assert(li == NULL);
64
65         li = libinput_udev_create_context(NULL, NULL, udev);
66         ck_assert(li == NULL);
67
68         li = libinput_udev_create_context(&interface, NULL, udev);
69         ck_assert(li != NULL);
70         ck_assert_int_eq(libinput_udev_assign_seat(li, NULL), -1);
71
72         libinput_unref(li);
73         udev_unref(udev);
74 }
75 END_TEST
76
77 START_TEST(udev_create_seat0)
78 {
79         struct libinput *li;
80         struct libinput_event *event;
81         struct udev *udev;
82         int fd;
83
84         udev = udev_new();
85         ck_assert(udev != NULL);
86
87         li = libinput_udev_create_context(&simple_interface, NULL, udev);
88         ck_assert(li != NULL);
89         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
90
91         fd = libinput_get_fd(li);
92         ck_assert_int_ge(fd, 0);
93
94         /* expect at least one event */
95         libinput_dispatch(li);
96         event = libinput_get_event(li);
97         ck_assert(event != NULL);
98
99         libinput_event_destroy(event);
100         libinput_unref(li);
101         udev_unref(udev);
102 }
103 END_TEST
104
105 START_TEST(udev_create_empty_seat)
106 {
107         struct libinput *li;
108         struct libinput_event *event;
109         struct udev *udev;
110         int fd;
111
112         udev = udev_new();
113         ck_assert(udev != NULL);
114
115         /* expect a libinput reference, but no events */
116         li = libinput_udev_create_context(&simple_interface, NULL, udev);
117         ck_assert(li != NULL);
118         ck_assert_int_eq(libinput_udev_assign_seat(li, "seatdoesntexist"), 0);
119
120         fd = libinput_get_fd(li);
121         ck_assert_int_ge(fd, 0);
122
123         libinput_dispatch(li);
124         event = libinput_get_event(li);
125         ck_assert(event == NULL);
126
127         libinput_event_destroy(event);
128         libinput_unref(li);
129         udev_unref(udev);
130 }
131 END_TEST
132
133 /**
134  * This test only works if there's at least one device in the system that is
135  * assigned the default seat. Should cover the 99% case.
136  */
137 START_TEST(udev_added_seat_default)
138 {
139         struct libinput *li;
140         struct libinput_event *event;
141         struct udev *udev;
142         struct libinput_device *device;
143         struct libinput_seat *seat;
144         const char *seat_name;
145         enum libinput_event_type type;
146         int default_seat_found = 0;
147
148         udev = udev_new();
149         ck_assert(udev != NULL);
150
151         li = libinput_udev_create_context(&simple_interface, NULL, udev);
152         ck_assert(li != NULL);
153         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
154         libinput_dispatch(li);
155
156         while (!default_seat_found && (event = libinput_get_event(li))) {
157                 type = libinput_event_get_type(event);
158                 if (type != LIBINPUT_EVENT_DEVICE_ADDED) {
159                         libinput_event_destroy(event);
160                         continue;
161                 }
162
163                 device = libinput_event_get_device(event);
164                 seat = libinput_device_get_seat(device);
165                 ck_assert(seat != NULL);
166
167                 seat_name = libinput_seat_get_logical_name(seat);
168                 default_seat_found = !strcmp(seat_name, "default");
169                 libinput_event_destroy(event);
170         }
171
172         ck_assert(default_seat_found);
173
174         libinput_unref(li);
175         udev_unref(udev);
176 }
177 END_TEST
178
179 START_TEST(udev_double_suspend)
180 {
181         struct libinput *li;
182         struct libinput_event *event;
183         struct udev *udev;
184         int fd;
185
186         udev = udev_new();
187         ck_assert(udev != NULL);
188
189         li = libinput_udev_create_context(&simple_interface, NULL, udev);
190         ck_assert(li != NULL);
191         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
192
193         fd = libinput_get_fd(li);
194         ck_assert_int_ge(fd, 0);
195
196         /* expect at least one event */
197         ck_assert_int_ge(libinput_dispatch(li), 0);
198         event = libinput_get_event(li);
199         ck_assert(event != NULL);
200
201         libinput_suspend(li);
202         libinput_suspend(li);
203         libinput_resume(li);
204
205         libinput_event_destroy(event);
206         libinput_unref(li);
207         udev_unref(udev);
208 }
209 END_TEST
210
211 START_TEST(udev_double_resume)
212 {
213         struct libinput *li;
214         struct libinput_event *event;
215         struct udev *udev;
216         int fd;
217
218         udev = udev_new();
219         ck_assert(udev != NULL);
220
221         li = libinput_udev_create_context(&simple_interface, NULL, udev);
222         ck_assert(li != NULL);
223         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
224
225         fd = libinput_get_fd(li);
226         ck_assert_int_ge(fd, 0);
227
228         /* expect at least one event */
229         ck_assert_int_ge(libinput_dispatch(li), 0);
230         event = libinput_get_event(li);
231         ck_assert(event != NULL);
232
233         libinput_suspend(li);
234         libinput_resume(li);
235         libinput_resume(li);
236
237         libinput_event_destroy(event);
238         libinput_unref(li);
239         udev_unref(udev);
240 }
241 END_TEST
242
243 static void
244 process_events_count_devices(struct libinput *li, int *device_count)
245 {
246         struct libinput_event *event;
247
248         while ((event = libinput_get_event(li))) {
249                 switch (libinput_event_get_type(event)) {
250                 case LIBINPUT_EVENT_DEVICE_ADDED:
251                         (*device_count)++;
252                         break;
253                 case LIBINPUT_EVENT_DEVICE_REMOVED:
254                         (*device_count)--;
255                         break;
256                 default:
257                         break;
258                 }
259                 libinput_event_destroy(event);
260         }
261 }
262
263 START_TEST(udev_suspend_resume)
264 {
265         struct libinput *li;
266         struct udev *udev;
267         int fd;
268         int num_devices = 0;
269
270         udev = udev_new();
271         ck_assert(udev != NULL);
272
273         li = libinput_udev_create_context(&simple_interface, NULL, udev);
274         ck_assert(li != NULL);
275         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
276
277         fd = libinput_get_fd(li);
278         ck_assert_int_ge(fd, 0);
279
280         /* Check that at least one device was discovered after creation. */
281         ck_assert_int_ge(libinput_dispatch(li), 0);
282         process_events_count_devices(li, &num_devices);
283         ck_assert_int_gt(num_devices, 0);
284
285         /* Check that after a suspend, no devices are left. */
286         libinput_suspend(li);
287         ck_assert_int_ge(libinput_dispatch(li), 0);
288         process_events_count_devices(li, &num_devices);
289         ck_assert_int_eq(num_devices, 0);
290
291         /* Check that after a resume, at least one device is discovered. */
292         libinput_resume(li);
293         ck_assert_int_ge(libinput_dispatch(li), 0);
294         process_events_count_devices(li, &num_devices);
295         ck_assert_int_gt(num_devices, 0);
296
297         libinput_unref(li);
298         udev_unref(udev);
299 }
300 END_TEST
301
302 START_TEST(udev_device_sysname)
303 {
304         struct libinput *li;
305         struct libinput_event *ev;
306         struct libinput_device *device;
307         const char *sysname;
308         struct udev *udev;
309
310         udev = udev_new();
311         ck_assert(udev != NULL);
312
313         li = libinput_udev_create_context(&simple_interface, NULL, udev);
314         ck_assert(li != NULL);
315         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
316
317         libinput_dispatch(li);
318
319         while ((ev = libinput_get_event(li))) {
320                 if (libinput_event_get_type(ev) != LIBINPUT_EVENT_DEVICE_ADDED)
321                         continue;
322
323                 device = libinput_event_get_device(ev);
324                 sysname = libinput_device_get_sysname(device);
325                 ck_assert(sysname != NULL && strlen(sysname) > 1);
326                 ck_assert(strchr(sysname, '/') == NULL);
327                 ck_assert_int_eq(strncmp(sysname, "event", 5), 0);
328                 libinput_event_destroy(ev);
329         }
330
331         libinput_unref(li);
332         udev_unref(udev);
333 }
334 END_TEST
335
336 START_TEST(udev_seat_recycle)
337 {
338         struct udev *udev;
339         struct libinput *li;
340         struct libinput_event *ev;
341         struct libinput_device *device;
342         struct libinput_seat *saved_seat = NULL;
343         struct libinput_seat *seat;
344         int data = 0;
345         int found = 0;
346         void *user_data;
347
348         udev = udev_new();
349         ck_assert(udev != NULL);
350
351         li = libinput_udev_create_context(&simple_interface, NULL, udev);
352         ck_assert(li != NULL);
353         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
354
355         libinput_dispatch(li);
356         while ((ev = libinput_get_event(li))) {
357                 switch (libinput_event_get_type(ev)) {
358                 case LIBINPUT_EVENT_DEVICE_ADDED:
359                         if (saved_seat)
360                                 break;
361
362                         device = libinput_event_get_device(ev);
363                         ck_assert(device != NULL);
364                         saved_seat = libinput_device_get_seat(device);
365                         libinput_seat_set_user_data(saved_seat, &data);
366                         libinput_seat_ref(saved_seat);
367                         break;
368                 default:
369                         break;
370                 }
371
372                 libinput_event_destroy(ev);
373         }
374
375         ck_assert(saved_seat != NULL);
376
377         libinput_suspend(li);
378
379         litest_drain_events(li);
380
381         libinput_resume(li);
382
383         libinput_dispatch(li);
384         while ((ev = libinput_get_event(li))) {
385                 switch (libinput_event_get_type(ev)) {
386                 case LIBINPUT_EVENT_DEVICE_ADDED:
387                         device = libinput_event_get_device(ev);
388                         ck_assert(device != NULL);
389
390                         seat = libinput_device_get_seat(device);
391                         user_data = libinput_seat_get_user_data(seat);
392                         if (user_data == &data) {
393                                 found = 1;
394                                 ck_assert(seat == saved_seat);
395                         }
396                         break;
397                 default:
398                         break;
399                 }
400
401                 libinput_event_destroy(ev);
402         }
403
404         ck_assert(found == 1);
405
406         libinput_unref(li);
407         udev_unref(udev);
408 }
409 END_TEST
410
411 int main (int argc, char **argv) {
412
413         litest_add_no_device("udev:create", udev_create_NULL);
414         litest_add_no_device("udev:create", udev_create_seat0);
415         litest_add_no_device("udev:create", udev_create_empty_seat);
416
417         litest_add_no_device("udev:seat events", udev_added_seat_default);
418
419         litest_add("udev:suspend", udev_double_suspend, LITEST_ANY, LITEST_ANY);
420         litest_add("udev:suspend", udev_double_resume, LITEST_ANY, LITEST_ANY);
421         litest_add("udev:suspend", udev_suspend_resume, LITEST_ANY, LITEST_ANY);
422         litest_add("udev:device events", udev_device_sysname, LITEST_ANY, LITEST_ANY);
423         litest_add("udev:seat", udev_seat_recycle, LITEST_ANY, LITEST_ANY);
424
425         return litest_run(argc, argv);
426 }