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