From: Peter Hutterer Date: Thu, 12 Sep 2013 03:42:24 +0000 (+1000) Subject: wrap EVIOCSCLOCKID into an API call X-Git-Tag: libevdev-0.4~2^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1e81ac1e28b8e709b2e58a72605a1bdd54cd6758;p=platform%2Fupstream%2Flibevdev.git wrap EVIOCSCLOCKID into an API call Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c index 6f7e2a6..e1bb6d0 100644 --- a/libevdev/libevdev.c +++ b/libevdev/libevdev.c @@ -1422,3 +1422,14 @@ libevdev_kernel_set_led_values(struct libevdev *dev, ...) return rc; } + +LIBEVDEV_EXPORT int +libevdev_set_clock_id(struct libevdev *dev, int clockid) +{ + if (dev->fd < 0) { + log_bug("device not initialized. call libevdev_set_fd() first\n"); + return -EBADF; + } + + return ioctl(dev->fd, EVIOCSCLOCKID, &clockid) ? -errno : 0; +} diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h index 704f85e..bfb0f37 100644 --- a/libevdev/libevdev.h +++ b/libevdev/libevdev.h @@ -1278,6 +1278,22 @@ int libevdev_kernel_set_led_value(struct libevdev *dev, unsigned int code, enum int libevdev_kernel_set_led_values(struct libevdev *dev, ...); /** + * @ingroup kernel + * + * Set the clock ID to be used for timestamps. Further events from this device + * will report an event time based on the given clock. + * + * This is a modification only affecting this representation of + * this device. + * + * @param dev The evdev device, already initialized with libevdev_set_fd() + * @param clockid The clock to use for future events. Permitted values + * are CLOCK_MONOTONIC and CLOCK_REALTIME (the default). + * @return zero on success, or a negative errno on failure + */ +int libevdev_set_clock_id(struct libevdev *dev, int clockid); + +/** * @ingroup misc * * Helper function to check if an event is of a specific type. This is diff --git a/test/test-libevdev-init.c b/test/test-libevdev-init.c index 243da23..7d4376d 100644 --- a/test/test-libevdev-init.c +++ b/test/test-libevdev-init.c @@ -23,7 +23,12 @@ #include #include #include +#include +#include +#include +#include +#include #include "test-common.h" START_TEST(test_new_device) @@ -260,6 +265,104 @@ START_TEST(test_device_grab) } END_TEST +START_TEST(test_set_clock_id) +{ + struct uinput_device* uidev; + struct libevdev *dev; + int rc; + + rc = test_create_device(&uidev, &dev, + EV_SYN, SYN_REPORT, + EV_REL, REL_X, + EV_REL, REL_Y, + EV_REL, REL_WHEEL, + EV_KEY, BTN_LEFT, + EV_KEY, BTN_MIDDLE, + EV_KEY, BTN_RIGHT, + -1); + ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc)); + + rc = libevdev_set_clock_id(dev, CLOCK_REALTIME); + ck_assert_int_eq(rc, 0); + + rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC); + ck_assert_int_eq(rc, 0); + + rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC_RAW); + ck_assert_int_eq(rc, -EINVAL); + + uinput_device_free(uidev); + libevdev_free(dev); +} +END_TEST + +START_TEST(test_clock_id_events) +{ + struct uinput_device* uidev; + struct libevdev *dev, *dev2; + int rc, fd; + struct input_event ev1, ev2; + struct timespec t1_real, t2_real; + struct timespec t1_mono, t2_mono; + + rc = test_create_device(&uidev, &dev, + EV_SYN, SYN_REPORT, + EV_REL, REL_X, + EV_REL, REL_Y, + EV_REL, REL_WHEEL, + EV_KEY, BTN_LEFT, + EV_KEY, BTN_MIDDLE, + EV_KEY, BTN_RIGHT, + -1); + ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc)); + + fd = open(uinput_device_get_devnode(uidev), O_RDONLY); + ck_assert_int_gt(fd, -1); + + rc = libevdev_new_from_fd(fd, &dev2); + ck_assert_msg(rc == 0, "Failed to create second device: %s", strerror(-rc)); + + rc = libevdev_set_clock_id(dev2, CLOCK_MONOTONIC); + ck_assert_int_eq(rc, 0); + + clock_gettime(CLOCK_REALTIME, &t1_real); + clock_gettime(CLOCK_MONOTONIC, &t1_mono); + uinput_device_event(uidev, EV_REL, REL_X, 1); + uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0); + clock_gettime(CLOCK_REALTIME, &t2_real); + clock_gettime(CLOCK_MONOTONIC, &t2_mono); + + rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1); + ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS); + + rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2); + ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS); + + ck_assert_int_eq(ev1.type, ev2.type); + ck_assert_int_eq(ev1.code, ev2.code); + ck_assert_int_eq(ev1.value, ev2.value); + + ck_assert_int_ne(ev1.time.tv_sec, ev2.time.tv_sec); + ck_assert_int_ne(ev1.time.tv_usec, ev2.time.tv_usec); + + ck_assert_int_ge(ev1.time.tv_sec, t1_real.tv_sec); + ck_assert_int_ge(ev1.time.tv_usec, t1_real.tv_nsec/1000); + ck_assert_int_le(ev1.time.tv_sec, t2_real.tv_sec); + ck_assert_int_le(ev1.time.tv_usec, t2_real.tv_nsec/1000); + + ck_assert_int_ge(ev2.time.tv_sec, t1_mono.tv_sec); + ck_assert_int_ge(ev2.time.tv_usec, t1_mono.tv_nsec/1000); + ck_assert_int_le(ev2.time.tv_sec, t2_mono.tv_sec); + ck_assert_int_le(ev2.time.tv_usec, t2_mono.tv_nsec/1000); + + uinput_device_free(uidev); + libevdev_free(dev); + libevdev_free(dev2); + close(fd); +} +END_TEST + + Suite * libevdev_init_test(void) { @@ -286,5 +389,10 @@ libevdev_init_test(void) tcase_add_test(tc, test_device_grab); suite_add_tcase(s, tc); + tc = tcase_create("clock id"); + tcase_add_test(tc, test_set_clock_id); + tcase_add_test(tc, test_clock_id_events); + suite_add_tcase(s, tc); + return s; }