diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2013-09-18 11:44:06 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2013-09-18 11:44:06 +1000 |
commit | bf322469572c95b731b8e9dceef4e6ac7c6ba552 (patch) | |
tree | 4c39f67127a9a641a04eaacf704f2974911e4777 | |
parent | ab2ab19ca304db6da914d98376be2749f71cca5c (diff) | |
parent | 1e81ac1e28b8e709b2e58a72605a1bdd54cd6758 (diff) |
Merge branch 'clockid'
-rw-r--r-- | libevdev/libevdev.c | 11 | ||||
-rw-r--r-- | libevdev/libevdev.h | 16 | ||||
-rw-r--r-- | test/test-common-uinput.c | 6 | ||||
-rw-r--r-- | test/test-common-uinput.h | 1 | ||||
-rw-r--r-- | test/test-libevdev-init.c | 108 |
5 files changed, 142 insertions, 0 deletions
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 c5e22f9..22d1e3d 100644 --- a/libevdev/libevdev.h +++ b/libevdev/libevdev.h @@ -1281,6 +1281,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-common-uinput.c b/test/test-common-uinput.c index 32ecb89..5f17fad 100644 --- a/test/test-common-uinput.c +++ b/test/test-common-uinput.c @@ -128,6 +128,12 @@ uinput_device_get_fd(const struct uinput_device *dev) return dev->dev_fd; } +const char* +uinput_device_get_devnode(const struct uinput_device *dev) +{ + return libevdev_uinput_get_devnode(dev->uidev); +} + int uinput_device_create(struct uinput_device* d) { diff --git a/test/test-common-uinput.h b/test/test-common-uinput.h index c1cd5a0..6273a6d 100644 --- a/test/test-common-uinput.h +++ b/test/test-common-uinput.h @@ -44,5 +44,6 @@ int uinput_device_event(const struct uinput_device* dev, unsigned int type, unsi int uinput_device_event_multiple(const struct uinput_device* dev, ...); int uinput_device_event_multiple_v(const struct uinput_device* dev, va_list args); int uinput_device_get_fd(const struct uinput_device *dev); +const char* uinput_device_get_devnode(const struct uinput_device *dev); char *uinput_devnode_from_syspath(const char *syspath); 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 <config.h> #include <errno.h> #include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <libevdev/libevdev-uinput.h> #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; } |