• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2013 Red Hat, Inc.
4  */
5 
6 #include "config.h"
7 #include <errno.h>
8 #include <inttypes.h>
9 #include <unistd.h>
10 #include <time.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 
15 #include <libevdev/libevdev-uinput.h>
16 #include "test-common.h"
17 
START_TEST(test_new_device)18 START_TEST(test_new_device)
19 {
20 	struct libevdev *dev;
21 
22 	dev = libevdev_new();
23 	ck_assert(dev != NULL);
24 	libevdev_free(dev);
25 }
26 END_TEST
27 
START_TEST(test_free_device)28 START_TEST(test_free_device)
29 {
30 	libevdev_free(NULL);
31 }
32 END_TEST
33 
START_TEST(test_init_from_invalid_fd)34 START_TEST(test_init_from_invalid_fd)
35 {
36 	int rc;
37 	struct libevdev *dev = NULL;
38 
39 	rc = libevdev_new_from_fd(-1, &dev);
40 
41 	ck_assert(dev == NULL);
42 	ck_assert_int_eq(rc, -EBADF);
43 
44 	rc = libevdev_new_from_fd(STDIN_FILENO, &dev);
45 	ck_assert(dev == NULL);
46 	ck_assert_int_eq(rc, -ENOTTY);
47 }
48 END_TEST
49 
START_TEST(test_init_and_change_fd)50 START_TEST(test_init_and_change_fd)
51 {
52 	struct uinput_device* uidev;
53 	struct libevdev *dev;
54 	int rc;
55 
56 	dev = libevdev_new();
57 	ck_assert(dev != NULL);
58 	ck_assert_int_eq(libevdev_set_fd(dev, -1), -EBADF);
59 
60 	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
61 	ck_assert_int_eq(libevdev_change_fd(dev, -1), -1);
62 	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
63 
64 	rc = uinput_device_new_with_events(&uidev,
65 					   TEST_DEVICE_NAME, DEFAULT_IDS,
66 					   EV_SYN, SYN_REPORT,
67 					   EV_REL, REL_X,
68 					   EV_REL, REL_Y,
69 					   EV_REL, REL_WHEEL,
70 					   EV_KEY, BTN_LEFT,
71 					   EV_KEY, BTN_MIDDLE,
72 					   EV_KEY, BTN_RIGHT,
73 					   -1);
74 	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
75 	ck_assert_int_eq(libevdev_set_fd(dev, uinput_device_get_fd(uidev)), 0);
76 
77 	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
78 	ck_assert_int_eq(libevdev_set_fd(dev, 0), -EBADF);
79 	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
80 
81 	ck_assert_int_eq(libevdev_get_fd(dev), uinput_device_get_fd(uidev));
82 
83 	ck_assert_int_eq(libevdev_change_fd(dev, 0), 0);
84 	ck_assert_int_eq(libevdev_get_fd(dev), 0);
85 
86 	uinput_device_free(uidev);
87 	libevdev_free(dev);
88 }
89 END_TEST
90 
91 static int log_fn_called = 0;
92 static char *logdata = "test";
logfunc(enum libevdev_log_priority priority,void * data,const char * file,int line,const char * func,const char * f,va_list args)93 static void logfunc(enum libevdev_log_priority priority,
94 		    void *data,
95 		    const char *file, int line, const char *func,
96 		    const char *f, va_list args) {
97 	ck_assert_int_eq(strcmp(logdata, data), 0);
98 	log_fn_called++;
99 }
100 
START_TEST(test_log_init)101 START_TEST(test_log_init)
102 {
103 	struct libevdev *dev = NULL;
104 	enum libevdev_log_priority old;
105 
106 	old = libevdev_get_log_priority();
107 
108 	libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
109 
110 	libevdev_set_log_function(logfunc, NULL);
111 	libevdev_set_log_function(NULL, NULL);
112 
113 	dev = libevdev_new();
114 	ck_assert(dev != NULL);
115 
116 	libevdev_set_log_function(logfunc, logdata);
117 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
118 
119 	libevdev_set_log_function(NULL, NULL);
120 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
121 
122 	libevdev_set_log_function(logfunc, logdata);
123 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
124 
125 	/* libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL) should
126 	   trigger a log message. We called it three times, but only twice
127 	   with the logfunc set, thus, ensure we only called the logfunc
128 	   twice */
129 	ck_assert_int_eq(log_fn_called, 2);
130 
131 	libevdev_free(dev);
132 
133 	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
134 
135 	log_fn_called = 0;
136 
137 	libevdev_set_log_priority(old);
138 }
139 END_TEST
140 
START_TEST(test_log_default_priority)141 START_TEST(test_log_default_priority)
142 {
143 	ck_assert_int_eq(libevdev_get_log_priority(), LIBEVDEV_LOG_INFO);
144 }
145 END_TEST
146 
START_TEST(test_log_set_get_priority)147 START_TEST(test_log_set_get_priority)
148 {
149 	enum libevdev_log_priority pri;
150 	enum libevdev_log_priority old;
151 
152 	old = libevdev_get_log_priority();
153 
154 	pri = LIBEVDEV_LOG_DEBUG;
155 	libevdev_set_log_priority(pri);
156 	ck_assert_int_eq(libevdev_get_log_priority(), pri);
157 
158 	pri = LIBEVDEV_LOG_INFO;
159 	libevdev_set_log_priority(pri);
160 	ck_assert_int_eq(libevdev_get_log_priority(), pri);
161 
162 	pri = LIBEVDEV_LOG_ERROR;
163 	libevdev_set_log_priority(pri);
164 	ck_assert_int_eq(libevdev_get_log_priority(), pri);
165 
166 	/* debug and above is clamped */
167 	pri = LIBEVDEV_LOG_DEBUG + 1;
168 	libevdev_set_log_priority(pri);
169 	ck_assert_int_eq(libevdev_get_log_priority(), LIBEVDEV_LOG_DEBUG);
170 
171 	/*  error and below is not clamped, we need this for another test */
172 	pri = LIBEVDEV_LOG_ERROR - 1;
173 	libevdev_set_log_priority(pri);
174 	ck_assert_int_eq(libevdev_get_log_priority(), pri);
175 
176 	libevdev_set_log_priority(old);
177 }
178 END_TEST
179 
START_TEST(test_log_priority)180 START_TEST(test_log_priority)
181 {
182 	struct libevdev *dev = NULL;
183 	enum libevdev_log_priority old;
184 
185 	old = libevdev_get_log_priority();
186 
187 	libevdev_set_log_function(logfunc, logdata);
188 
189 	dev = libevdev_new();
190 	ck_assert(dev != NULL);
191 
192 	libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
193 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
194 	ck_assert_int_eq(log_fn_called, 1);
195 
196 	libevdev_set_log_priority(LIBEVDEV_LOG_INFO);
197 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
198 	ck_assert_int_eq(log_fn_called, 2);
199 
200 	libevdev_set_log_priority(LIBEVDEV_LOG_ERROR);
201 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
202 	ck_assert_int_eq(log_fn_called, 3);
203 
204 	/* we don't have any log msgs > ERROR at the moment, so test it by
205 	   setting an invalid priority. */
206 	libevdev_set_log_priority(LIBEVDEV_LOG_ERROR - 1);
207 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
208 	ck_assert_int_eq(log_fn_called, 3);
209 
210 	libevdev_free(dev);
211 
212 	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
213 
214 	log_fn_called = 0;
215 
216 	libevdev_set_log_priority(old);
217 }
218 END_TEST
219 
220 static char *logdata_1 = "foo";
221 static char *logdata_2 = "bar";
222 static int log_data_fn_called = 0;
logfunc_data(enum libevdev_log_priority priority,void * data,const char * file,int line,const char * func,const char * f,va_list args)223 static void logfunc_data(enum libevdev_log_priority priority,
224 			 void *data,
225 			 const char *file, int line, const char *func,
226 			 const char *f, va_list args) {
227 	switch(log_data_fn_called) {
228 		case 0: ck_assert(data == logdata_1); break;
229 		case 1: ck_assert(data == logdata_2); break;
230 		case 2: ck_assert(data == NULL); break;
231 		default:
232 			ck_abort();
233 	}
234 	log_data_fn_called++;
235 }
236 
START_TEST(test_log_data)237 START_TEST(test_log_data)
238 {
239 	struct libevdev *dev = NULL;
240 
241 	dev = libevdev_new();
242 	ck_assert(dev != NULL);
243 
244 	libevdev_set_log_function(logfunc_data, logdata_1);
245 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
246 
247 	libevdev_set_log_function(logfunc_data, logdata_2);
248 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
249 
250 	libevdev_set_log_function(logfunc_data, NULL);
251 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
252 
253 	libevdev_free(dev);
254 }
255 END_TEST
256 
257 struct libevdev *devlogdata;
258 static int dev_log_fn_called = 0;
devlogfunc(const struct libevdev * dev,enum libevdev_log_priority priority,void * data,const char * file,int line,const char * func,const char * f,va_list args)259 static void devlogfunc(const struct libevdev *dev,
260 		    enum libevdev_log_priority priority,
261 		    void *data,
262 		    const char *file, int line, const char *func,
263 		    const char *f, va_list args)
264 {
265 	ck_assert(dev == data);
266 	dev_log_fn_called++;
267 }
268 
START_TEST(test_device_log_init)269 START_TEST(test_device_log_init)
270 {
271 	struct libevdev *dev = NULL;
272 	enum libevdev_log_priority old;
273 
274 	old = libevdev_get_log_priority();
275 	libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
276 	libevdev_set_log_function(logfunc, logdata);
277 
278 	/* error for NULL device */
279 	libevdev_set_device_log_function(NULL, NULL,
280 					 LIBEVDEV_LOG_ERROR, NULL);
281 	ck_assert_int_eq(log_fn_called, 1);
282 
283 	/* error for NULL device */
284 	libevdev_set_device_log_function(NULL, devlogfunc,
285 					 LIBEVDEV_LOG_ERROR, NULL);
286 	ck_assert_int_eq(log_fn_called, 2);
287 
288 	log_fn_called = 0;
289 
290 	dev = libevdev_new();
291 	ck_assert(dev != NULL);
292 
293 	libevdev_set_device_log_function(dev, NULL,
294 					 LIBEVDEV_LOG_ERROR, NULL);
295 
296 	/* libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL) should
297 	   trigger a log message. */
298 
299 	/* expect global handler triggered */
300 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
301 	ck_assert_int_eq(log_fn_called, 1);
302 	ck_assert_int_eq(dev_log_fn_called, 0);
303 
304 	/* expect device handler triggered */
305 	libevdev_set_device_log_function(dev, devlogfunc,
306 					 LIBEVDEV_LOG_ERROR, dev);
307 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
308 	ck_assert_int_eq(log_fn_called, 1);
309 	ck_assert_int_eq(dev_log_fn_called, 1);
310 
311 	/* device handler set, but priority filters. don't expect any log
312 	   handler to be called.
313 	   we don't have any log msgs > ERROR at the moment, so test it by
314 	   setting an invalid priority. */
315 	libevdev_set_device_log_function(dev, devlogfunc,
316 					 LIBEVDEV_LOG_ERROR - 1, dev);
317 	libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
318 	ck_assert_int_eq(log_fn_called, 1);
319 	ck_assert_int_eq(dev_log_fn_called, 1);
320 
321 	libevdev_free(dev);
322 
323 	log_fn_called = 0;
324 	libevdev_set_log_priority(old);
325 	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
326 
327 }
328 END_TEST
329 
START_TEST(test_device_init)330 START_TEST(test_device_init)
331 {
332 	struct uinput_device* uidev;
333 	struct libevdev *dev;
334 	int rc;
335 
336 	rc = uinput_device_new_with_events(&uidev,
337 					   TEST_DEVICE_NAME, DEFAULT_IDS,
338 					   EV_SYN, SYN_REPORT,
339 					   EV_REL, REL_X,
340 					   EV_REL, REL_Y,
341 					   EV_REL, REL_WHEEL,
342 					   EV_KEY, BTN_LEFT,
343 					   EV_KEY, BTN_MIDDLE,
344 					   EV_KEY, BTN_RIGHT,
345 					   -1);
346 	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
347 
348 	dev = libevdev_new();
349 	ck_assert(dev != NULL);
350 	rc = libevdev_set_fd(dev, uinput_device_get_fd(uidev));
351 	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
352 
353 	uinput_device_free(uidev);
354 	libevdev_free(dev);
355 }
356 END_TEST
357 
START_TEST(test_device_init_from_fd)358 START_TEST(test_device_init_from_fd)
359 {
360 	struct uinput_device* uidev;
361 	struct libevdev *dev;
362 	int rc;
363 
364 	rc = uinput_device_new_with_events(&uidev,
365 					   TEST_DEVICE_NAME, DEFAULT_IDS,
366 					   EV_SYN, SYN_REPORT,
367 					   EV_REL, REL_X,
368 					   EV_REL, REL_Y,
369 					   EV_REL, REL_WHEEL,
370 					   EV_KEY, BTN_LEFT,
371 					   EV_KEY, BTN_MIDDLE,
372 					   EV_KEY, BTN_RIGHT,
373 					   -1);
374 	ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
375 
376 	rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
377 	ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
378 
379 	uinput_device_free(uidev);
380 	libevdev_free(dev);
381 }
382 END_TEST
383 
START_TEST(test_device_grab)384 START_TEST(test_device_grab)
385 {
386 	struct uinput_device* uidev;
387 	struct libevdev *dev;
388 	int rc;
389 
390 	test_create_device(&uidev, &dev,
391 			   EV_SYN, SYN_REPORT,
392 			   EV_REL, REL_X,
393 			   EV_REL, REL_Y,
394 			   EV_REL, REL_WHEEL,
395 			   EV_KEY, BTN_LEFT,
396 			   EV_KEY, BTN_MIDDLE,
397 			   EV_KEY, BTN_RIGHT,
398 			   -1);
399 
400 	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
401 	rc = libevdev_grab(dev, 0);
402 	ck_assert_int_eq(rc, -EINVAL);
403 	rc = libevdev_grab(dev, 1);
404 	ck_assert_int_eq(rc, -EINVAL);
405 	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
406 
407 	rc = libevdev_grab(dev, LIBEVDEV_UNGRAB);
408 	ck_assert_int_eq(rc, 0);
409 	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
410 	ck_assert_int_eq(rc, 0);
411 	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
412 	ck_assert_int_eq(rc, 0);
413 	rc = libevdev_grab(dev, LIBEVDEV_UNGRAB);
414 	ck_assert_int_eq(rc, 0);
415 
416 	uinput_device_free(uidev);
417 	libevdev_free(dev);
418 }
419 END_TEST
420 
START_TEST(test_device_grab_invalid_fd)421 START_TEST(test_device_grab_invalid_fd)
422 {
423 	struct uinput_device* uidev;
424 	struct libevdev *dev;
425 	int rc;
426 
427 	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
428 
429 	dev = libevdev_new();
430 	rc = libevdev_grab(dev, 0);
431 	ck_assert_int_eq(rc, -EBADF);
432 	libevdev_free(dev);
433 
434 	test_create_device(&uidev, &dev,
435 			   EV_SYN, SYN_REPORT,
436 			   EV_REL, REL_X,
437 			   EV_REL, REL_Y,
438 			   EV_REL, REL_WHEEL,
439 			   EV_KEY, BTN_LEFT,
440 			   EV_KEY, BTN_MIDDLE,
441 			   EV_KEY, BTN_RIGHT,
442 			   -1);
443 	libevdev_change_fd(dev, -2);
444 	rc = libevdev_grab(dev, 0);
445 	ck_assert_int_eq(rc, -EBADF);
446 
447 	libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
448 
449 	uinput_device_free(uidev);
450 	libevdev_free(dev);
451 }
452 END_TEST
453 
START_TEST(test_device_grab_change_fd)454 START_TEST(test_device_grab_change_fd)
455 {
456 	struct libevdev_uinput *uidev;
457 	struct libevdev *dev, *other;
458 	struct input_event e;
459 	int rc;
460 	int other_fd;
461 	int dev_fd;
462 
463 	dev = libevdev_new();
464 	libevdev_set_name(dev, "libevdev test device");
465 	libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
466 	libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
467 	libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
468 
469 	rc = libevdev_uinput_create_from_device(dev,
470 						LIBEVDEV_UINPUT_OPEN_MANAGED,
471 						&uidev);
472 	ck_assert_int_eq(rc, 0);
473 	libevdev_free(dev);
474 
475 	dev_fd = open(libevdev_uinput_get_devnode(uidev),
476 		      O_RDONLY|O_NONBLOCK);
477 	ck_assert_int_ne(dev_fd, -1);
478 	rc = libevdev_new_from_fd(dev_fd, &dev);
479 	ck_assert_int_eq(rc, 0);
480 
481 	other_fd = open(libevdev_uinput_get_devnode(uidev),
482 			O_RDONLY|O_NONBLOCK);
483 	ck_assert_int_ne(other_fd, -1);
484 	rc = libevdev_new_from_fd(other_fd, &other);
485 	ck_assert_int_eq(rc, 0);
486 
487 	/* check we're getting the events before the grab */
488 	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
489 	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
490 	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
491 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
492 	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
493 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
494 	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
495 	ck_assert_int_eq(rc, -EAGAIN);
496 
497 	/* no events after the grab */
498 	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
499 	ck_assert_int_eq(rc, 0);
500 	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
501 	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
502 	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
503 	ck_assert_int_eq(rc, 0);
504 	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
505 	ck_assert_int_eq(rc, -EAGAIN);
506 
507 	/* swapping the fd removes the grab */
508 	close(dev_fd);
509 	dev_fd = open(libevdev_uinput_get_devnode(uidev),
510 		      O_RDONLY|O_NONBLOCK);
511 	ck_assert_int_ne(dev_fd, -1);
512 	rc = libevdev_change_fd(dev, dev_fd);
513 	ck_assert_int_eq(rc, 0);
514 
515 	/* check we're getting the events again */
516 	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
517 	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
518 	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
519 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
520 	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
521 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
522 	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
523 	ck_assert_int_eq(rc, -EAGAIN);
524 
525 	/* no events after the grab */
526 	rc = libevdev_grab(dev, LIBEVDEV_GRAB);
527 	ck_assert_int_eq(rc, 0);
528 	libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
529 	libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
530 	rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
531 	ck_assert_int_eq(rc, -EAGAIN);
532 
533 	libevdev_uinput_destroy(uidev);
534 	libevdev_free(dev);
535 	libevdev_free(other);
536 	close(dev_fd);
537 	close(other_fd);
538 }
539 END_TEST
540 
START_TEST(test_set_clock_id)541 START_TEST(test_set_clock_id)
542 {
543 	struct uinput_device* uidev;
544 	struct libevdev *dev;
545 	int clockid;
546 	int rc;
547 
548 	test_create_device(&uidev, &dev,
549 			   EV_SYN, SYN_REPORT,
550 			   EV_REL, REL_X,
551 			   EV_REL, REL_Y,
552 			   EV_REL, REL_WHEEL,
553 			   EV_KEY, BTN_LEFT,
554 			   EV_KEY, BTN_MIDDLE,
555 			   EV_KEY, BTN_RIGHT,
556 			   -1);
557 
558 	rc = libevdev_set_clock_id(dev, CLOCK_REALTIME);
559 	ck_assert_int_eq(rc, 0);
560 
561 	rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
562 	ck_assert_int_eq(rc, 0);
563 
564 #ifdef __FreeBSD__
565 	clockid = CLOCK_MONOTONIC_FAST;
566 #else
567 	clockid = CLOCK_MONOTONIC_RAW;
568 #endif
569 
570 	rc = libevdev_set_clock_id(dev, clockid);
571 	ck_assert_int_eq(rc, -EINVAL);
572 
573 	uinput_device_free(uidev);
574 	libevdev_free(dev);
575 }
576 END_TEST
577 
START_TEST(test_set_clock_id_invalid_fd)578 START_TEST(test_set_clock_id_invalid_fd)
579 {
580 	struct uinput_device* uidev;
581 	struct libevdev *dev;
582 	int rc;
583 
584 	libevdev_set_log_function(test_logfunc_ignore_error, NULL);
585 
586 	dev = libevdev_new();
587 	rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
588 	ck_assert_int_eq(rc, -EBADF);
589 	libevdev_free(dev);
590 
591 	test_create_device(&uidev, &dev,
592 			   EV_SYN, SYN_REPORT,
593 			   EV_REL, REL_X,
594 			   EV_REL, REL_Y,
595 			   EV_REL, REL_WHEEL,
596 			   EV_KEY, BTN_LEFT,
597 			   EV_KEY, BTN_MIDDLE,
598 			   EV_KEY, BTN_RIGHT,
599 			   -1);
600 	libevdev_change_fd(dev, -2);
601 	rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
602 	ck_assert_int_eq(rc, -EBADF);
603 
604 	uinput_device_free(uidev);
605 	libevdev_free(dev);
606 }
607 END_TEST
608 
START_TEST(test_clock_id_events)609 START_TEST(test_clock_id_events)
610 {
611 	struct uinput_device* uidev;
612 	struct libevdev *dev, *dev2;
613 	int rc, fd;
614 	struct input_event ev1, ev2;
615 	struct timespec t1_real, t2_real;
616 	struct timespec t1_mono, t2_mono;
617 	int64_t t1, t2;
618 
619 	test_create_device(&uidev, &dev,
620 			   EV_SYN, SYN_REPORT,
621 			   EV_REL, REL_X,
622 			   EV_REL, REL_Y,
623 			   EV_REL, REL_WHEEL,
624 			   EV_KEY, BTN_LEFT,
625 			   EV_KEY, BTN_MIDDLE,
626 			   EV_KEY, BTN_RIGHT,
627 			   -1);
628 
629 	fd = open(uinput_device_get_devnode(uidev), O_RDONLY);
630 	ck_assert_int_gt(fd, -1);
631 
632 	rc = libevdev_new_from_fd(fd, &dev2);
633 	ck_assert_msg(rc == 0, "Failed to create second device: %s", strerror(-rc));
634 
635 	rc = libevdev_set_clock_id(dev2, CLOCK_MONOTONIC);
636 	ck_assert_int_eq(rc, 0);
637 
638 	clock_gettime(CLOCK_REALTIME, &t1_real);
639 	clock_gettime(CLOCK_MONOTONIC, &t1_mono);
640 	uinput_device_event(uidev, EV_REL, REL_X, 1);
641 	uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
642 	clock_gettime(CLOCK_REALTIME, &t2_real);
643 	clock_gettime(CLOCK_MONOTONIC, &t2_mono);
644 
645 	rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
646 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
647 
648 	rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
649 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
650 
651 	ck_assert_int_eq(ev1.type, ev2.type);
652 	ck_assert_int_eq(ev1.code, ev2.code);
653 	ck_assert_int_eq(ev1.value, ev2.value);
654 
655 	t1 = ev1.input_event_sec * 1000000LL + ev1.input_event_usec;
656 	t2 = ev2.input_event_sec * 1000000LL + ev2.input_event_usec;
657 	ck_assert_int_ne(t1, t2);
658 
659 	ck_assert_int_ge(ev1.input_event_sec, t1_real.tv_sec);
660 	ck_assert_int_ge(ev1.input_event_usec, t1_real.tv_nsec/1000);
661 	ck_assert_int_le(ev1.input_event_sec, t2_real.tv_sec);
662 	ck_assert_int_le(ev1.input_event_usec, t2_real.tv_nsec/1000);
663 
664 	ck_assert_int_ge(ev2.input_event_sec, t1_mono.tv_sec);
665 	ck_assert_int_ge(ev2.input_event_usec, t1_mono.tv_nsec/1000);
666 	ck_assert_int_le(ev2.input_event_sec, t2_mono.tv_sec);
667 	ck_assert_int_le(ev2.input_event_usec, t2_mono.tv_nsec/1000);
668 
669 	uinput_device_free(uidev);
670 	libevdev_free(dev);
671 	libevdev_free(dev2);
672 	close(fd);
673 }
674 END_TEST
675 
TEST_SUITE_ROOT_PRIVILEGES(libevdev_init_test)676 TEST_SUITE_ROOT_PRIVILEGES(libevdev_init_test)
677 {
678 	Suite *s = suite_create("libevdev init tests");
679 
680 	add_test(s, test_new_device);
681 	add_test(s, test_free_device);
682 	add_test(s, test_init_from_invalid_fd);
683 	add_test(s, test_init_and_change_fd);
684 
685 	add_test(s, test_log_init);
686 	add_test(s, test_log_priority);
687 	add_test(s, test_log_set_get_priority);
688 	add_test(s, test_log_default_priority);
689 	add_test(s, test_log_data);
690 	add_test(s, test_device_log_init);
691 
692 	add_test(s, test_device_init);
693 	add_test(s, test_device_init_from_fd);
694 
695 	add_test(s, test_device_grab);
696 	add_test(s, test_device_grab_invalid_fd);
697 	add_test(s, test_device_grab_change_fd);
698 
699 	add_test(s, test_set_clock_id);
700 	add_test(s, test_set_clock_id_invalid_fd);
701 	add_test(s, test_clock_id_events);
702 
703 	return s;
704 }
705