2013-06-05 11:17:11 +10:00
|
|
|
/*
|
|
|
|
|
* Copyright © 2013 Red Hat, Inc.
|
|
|
|
|
*
|
|
|
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
|
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
|
|
|
* the above copyright notice appear in all copies and that both that copyright
|
|
|
|
|
* notice and this permission notice appear in supporting documentation, and
|
|
|
|
|
* that the name of the copyright holders not be used in advertising or
|
|
|
|
|
* publicity pertaining to distribution of the software without specific,
|
|
|
|
|
* written prior permission. The copyright holders make no representations
|
|
|
|
|
* about the suitability of this software for any purpose. It is provided "as
|
|
|
|
|
* is" without express or implied warranty.
|
|
|
|
|
*
|
|
|
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
|
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
|
|
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
|
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
|
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
|
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
|
|
|
* OF THIS SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
2020-02-14 10:13:18 +10:00
|
|
|
#include "config.h"
|
2013-06-05 11:17:11 +10:00
|
|
|
#include <errno.h>
|
2013-10-28 17:16:43 +01:00
|
|
|
#include <inttypes.h>
|
2013-06-05 11:17:11 +10:00
|
|
|
#include <unistd.h>
|
2013-09-12 13:42:24 +10:00
|
|
|
#include <time.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <fcntl.h>
|
2013-06-05 11:17:11 +10:00
|
|
|
|
2013-09-12 13:42:24 +10:00
|
|
|
#include <libevdev/libevdev-uinput.h>
|
2013-06-29 17:57:31 +10:00
|
|
|
#include "test-common.h"
|
2013-06-05 11:17:11 +10:00
|
|
|
|
|
|
|
|
START_TEST(test_new_device)
|
|
|
|
|
{
|
|
|
|
|
struct libevdev *dev;
|
|
|
|
|
|
|
|
|
|
dev = libevdev_new();
|
|
|
|
|
ck_assert(dev != NULL);
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
|
|
|
|
START_TEST(test_free_device)
|
|
|
|
|
{
|
|
|
|
|
libevdev_free(NULL);
|
|
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
|
|
|
|
START_TEST(test_init_from_invalid_fd)
|
|
|
|
|
{
|
|
|
|
|
int rc;
|
|
|
|
|
struct libevdev *dev = NULL;
|
|
|
|
|
|
|
|
|
|
rc = libevdev_new_from_fd(-1, &dev);
|
|
|
|
|
|
|
|
|
|
ck_assert(dev == NULL);
|
|
|
|
|
ck_assert_int_eq(rc, -EBADF);
|
|
|
|
|
|
|
|
|
|
rc = libevdev_new_from_fd(STDIN_FILENO, &dev);
|
|
|
|
|
ck_assert(dev == NULL);
|
|
|
|
|
ck_assert_int_eq(rc, -ENOTTY);
|
|
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
|
|
|
|
START_TEST(test_init_and_change_fd)
|
|
|
|
|
{
|
|
|
|
|
struct uinput_device* uidev;
|
|
|
|
|
struct libevdev *dev;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
dev = libevdev_new();
|
|
|
|
|
ck_assert(dev != NULL);
|
|
|
|
|
ck_assert_int_eq(libevdev_set_fd(dev, -1), -EBADF);
|
2014-01-17 10:21:48 +10:00
|
|
|
|
|
|
|
|
libevdev_set_log_function(test_logfunc_ignore_error, NULL);
|
2013-06-05 11:17:11 +10:00
|
|
|
ck_assert_int_eq(libevdev_change_fd(dev, -1), -1);
|
2014-01-17 10:21:48 +10:00
|
|
|
libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
|
2013-06-05 11:17:11 +10:00
|
|
|
|
|
|
|
|
rc = uinput_device_new_with_events(&uidev,
|
2013-07-05 09:08:04 +10:00
|
|
|
TEST_DEVICE_NAME, DEFAULT_IDS,
|
2013-06-05 11:17:11 +10:00
|
|
|
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 uinput device: %s", strerror(-rc));
|
|
|
|
|
ck_assert_int_eq(libevdev_set_fd(dev, uinput_device_get_fd(uidev)), 0);
|
2014-01-17 10:21:48 +10:00
|
|
|
|
|
|
|
|
libevdev_set_log_function(test_logfunc_ignore_error, NULL);
|
2013-06-05 11:17:11 +10:00
|
|
|
ck_assert_int_eq(libevdev_set_fd(dev, 0), -EBADF);
|
2014-01-17 10:21:48 +10:00
|
|
|
libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
|
2013-06-05 11:17:11 +10:00
|
|
|
|
|
|
|
|
ck_assert_int_eq(libevdev_get_fd(dev), uinput_device_get_fd(uidev));
|
|
|
|
|
|
|
|
|
|
ck_assert_int_eq(libevdev_change_fd(dev, 0), 0);
|
|
|
|
|
ck_assert_int_eq(libevdev_get_fd(dev), 0);
|
|
|
|
|
|
|
|
|
|
uinput_device_free(uidev);
|
2013-06-28 13:13:55 +10:00
|
|
|
libevdev_free(dev);
|
2013-06-05 11:17:11 +10:00
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
2013-09-03 16:54:44 +10:00
|
|
|
static int log_fn_called = 0;
|
|
|
|
|
static char *logdata = "test";
|
2013-08-26 13:24:26 +10:00
|
|
|
static void logfunc(enum libevdev_log_priority priority,
|
|
|
|
|
void *data,
|
|
|
|
|
const char *file, int line, const char *func,
|
2013-09-03 16:54:44 +10:00
|
|
|
const char *f, va_list args) {
|
|
|
|
|
ck_assert_int_eq(strcmp(logdata, data), 0);
|
|
|
|
|
log_fn_called++;
|
|
|
|
|
}
|
2013-06-05 11:17:11 +10:00
|
|
|
|
|
|
|
|
START_TEST(test_log_init)
|
|
|
|
|
{
|
|
|
|
|
struct libevdev *dev = NULL;
|
2014-04-04 10:04:56 +10:00
|
|
|
enum libevdev_log_priority old;
|
|
|
|
|
|
|
|
|
|
old = libevdev_get_log_priority();
|
2013-06-05 11:17:11 +10:00
|
|
|
|
2014-02-12 14:54:13 +10:00
|
|
|
libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
|
|
|
|
|
|
2013-08-26 13:24:26 +10:00
|
|
|
libevdev_set_log_function(logfunc, NULL);
|
|
|
|
|
libevdev_set_log_function(NULL, NULL);
|
2013-06-05 11:17:11 +10:00
|
|
|
|
|
|
|
|
dev = libevdev_new();
|
|
|
|
|
ck_assert(dev != NULL);
|
|
|
|
|
|
2013-09-03 16:54:44 +10:00
|
|
|
libevdev_set_log_function(logfunc, logdata);
|
2013-09-11 11:04:54 +10:00
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
2013-09-03 16:54:44 +10:00
|
|
|
|
2013-08-26 13:24:26 +10:00
|
|
|
libevdev_set_log_function(NULL, NULL);
|
2013-09-11 11:04:54 +10:00
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
2013-06-05 11:17:11 +10:00
|
|
|
|
2013-09-03 16:54:44 +10:00
|
|
|
libevdev_set_log_function(logfunc, logdata);
|
2013-09-11 11:04:54 +10:00
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
2013-09-03 16:54:44 +10:00
|
|
|
|
2013-09-11 11:04:54 +10:00
|
|
|
/* libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL) should
|
2013-09-03 16:54:44 +10:00
|
|
|
trigger a log message. We called it three times, but only twice
|
|
|
|
|
with the logfunc set, thus, ensure we only called the logfunc
|
|
|
|
|
twice */
|
|
|
|
|
ck_assert_int_eq(log_fn_called, 2);
|
|
|
|
|
|
|
|
|
|
libevdev_free(dev);
|
2014-01-17 10:21:48 +10:00
|
|
|
|
|
|
|
|
libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
|
2014-02-12 14:54:13 +10:00
|
|
|
|
|
|
|
|
log_fn_called = 0;
|
2014-04-04 10:04:56 +10:00
|
|
|
|
|
|
|
|
libevdev_set_log_priority(old);
|
2014-02-12 14:54:13 +10:00
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
|
|
|
|
START_TEST(test_log_default_priority)
|
|
|
|
|
{
|
|
|
|
|
ck_assert_int_eq(libevdev_get_log_priority(), LIBEVDEV_LOG_INFO);
|
|
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
|
|
|
|
START_TEST(test_log_set_get_priority)
|
|
|
|
|
{
|
|
|
|
|
enum libevdev_log_priority pri;
|
2014-04-04 10:04:56 +10:00
|
|
|
enum libevdev_log_priority old;
|
|
|
|
|
|
|
|
|
|
old = libevdev_get_log_priority();
|
2014-02-12 14:54:13 +10:00
|
|
|
|
|
|
|
|
pri = LIBEVDEV_LOG_DEBUG;
|
|
|
|
|
libevdev_set_log_priority(pri);
|
|
|
|
|
ck_assert_int_eq(libevdev_get_log_priority(), pri);
|
|
|
|
|
|
|
|
|
|
pri = LIBEVDEV_LOG_INFO;
|
|
|
|
|
libevdev_set_log_priority(pri);
|
|
|
|
|
ck_assert_int_eq(libevdev_get_log_priority(), pri);
|
|
|
|
|
|
|
|
|
|
pri = LIBEVDEV_LOG_ERROR;
|
|
|
|
|
libevdev_set_log_priority(pri);
|
|
|
|
|
ck_assert_int_eq(libevdev_get_log_priority(), pri);
|
|
|
|
|
|
|
|
|
|
/* debug and above is clamped */
|
|
|
|
|
pri = LIBEVDEV_LOG_DEBUG + 1;
|
|
|
|
|
libevdev_set_log_priority(pri);
|
|
|
|
|
ck_assert_int_eq(libevdev_get_log_priority(), LIBEVDEV_LOG_DEBUG);
|
|
|
|
|
|
|
|
|
|
/* error and below is not clamped, we need this for another test */
|
|
|
|
|
pri = LIBEVDEV_LOG_ERROR - 1;
|
|
|
|
|
libevdev_set_log_priority(pri);
|
|
|
|
|
ck_assert_int_eq(libevdev_get_log_priority(), pri);
|
2014-04-04 10:04:56 +10:00
|
|
|
|
|
|
|
|
libevdev_set_log_priority(old);
|
2014-02-12 14:54:13 +10:00
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
|
|
|
|
START_TEST(test_log_priority)
|
|
|
|
|
{
|
|
|
|
|
struct libevdev *dev = NULL;
|
2014-04-04 10:04:56 +10:00
|
|
|
enum libevdev_log_priority old;
|
|
|
|
|
|
|
|
|
|
old = libevdev_get_log_priority();
|
2014-02-12 14:54:13 +10:00
|
|
|
|
|
|
|
|
libevdev_set_log_function(logfunc, logdata);
|
|
|
|
|
|
|
|
|
|
dev = libevdev_new();
|
|
|
|
|
ck_assert(dev != NULL);
|
|
|
|
|
|
|
|
|
|
libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
|
|
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
|
|
|
|
ck_assert_int_eq(log_fn_called, 1);
|
|
|
|
|
|
|
|
|
|
libevdev_set_log_priority(LIBEVDEV_LOG_INFO);
|
|
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
|
|
|
|
ck_assert_int_eq(log_fn_called, 2);
|
|
|
|
|
|
|
|
|
|
libevdev_set_log_priority(LIBEVDEV_LOG_ERROR);
|
|
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
|
|
|
|
ck_assert_int_eq(log_fn_called, 3);
|
|
|
|
|
|
|
|
|
|
/* we don't have any log msgs > ERROR at the moment, so test it by
|
|
|
|
|
setting an invalid priority. */
|
|
|
|
|
libevdev_set_log_priority(LIBEVDEV_LOG_ERROR - 1);
|
|
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
|
|
|
|
ck_assert_int_eq(log_fn_called, 3);
|
|
|
|
|
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
|
|
|
|
|
libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
|
|
|
|
|
|
|
|
|
|
log_fn_called = 0;
|
2014-04-04 10:04:56 +10:00
|
|
|
|
|
|
|
|
libevdev_set_log_priority(old);
|
2013-06-05 11:17:11 +10:00
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
2013-09-12 14:27:28 +10:00
|
|
|
static char *logdata_1 = "foo";
|
|
|
|
|
static char *logdata_2 = "bar";
|
|
|
|
|
static int log_data_fn_called = 0;
|
|
|
|
|
static void logfunc_data(enum libevdev_log_priority priority,
|
|
|
|
|
void *data,
|
|
|
|
|
const char *file, int line, const char *func,
|
|
|
|
|
const char *f, va_list args) {
|
|
|
|
|
switch(log_data_fn_called) {
|
|
|
|
|
case 0: ck_assert(data == logdata_1); break;
|
|
|
|
|
case 1: ck_assert(data == logdata_2); break;
|
|
|
|
|
case 2: ck_assert(data == NULL); break;
|
|
|
|
|
default:
|
|
|
|
|
ck_abort();
|
|
|
|
|
}
|
|
|
|
|
log_data_fn_called++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
START_TEST(test_log_data)
|
|
|
|
|
{
|
|
|
|
|
struct libevdev *dev = NULL;
|
|
|
|
|
|
|
|
|
|
dev = libevdev_new();
|
|
|
|
|
ck_assert(dev != NULL);
|
|
|
|
|
|
|
|
|
|
libevdev_set_log_function(logfunc_data, logdata_1);
|
|
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
|
|
|
|
|
|
|
|
|
libevdev_set_log_function(logfunc_data, logdata_2);
|
|
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
|
|
|
|
|
|
|
|
|
libevdev_set_log_function(logfunc_data, NULL);
|
|
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
|
|
|
|
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
2014-05-14 16:36:49 +10:00
|
|
|
struct libevdev *devlogdata;
|
|
|
|
|
static int dev_log_fn_called = 0;
|
|
|
|
|
static void 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)
|
|
|
|
|
{
|
|
|
|
|
ck_assert(dev == data);
|
|
|
|
|
dev_log_fn_called++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
START_TEST(test_device_log_init)
|
|
|
|
|
{
|
|
|
|
|
struct libevdev *dev = NULL;
|
|
|
|
|
enum libevdev_log_priority old;
|
|
|
|
|
|
|
|
|
|
old = libevdev_get_log_priority();
|
|
|
|
|
libevdev_set_log_priority(LIBEVDEV_LOG_DEBUG);
|
|
|
|
|
libevdev_set_log_function(logfunc, logdata);
|
|
|
|
|
|
|
|
|
|
/* error for NULL device */
|
|
|
|
|
libevdev_set_device_log_function(NULL, NULL,
|
|
|
|
|
LIBEVDEV_LOG_ERROR, NULL);
|
|
|
|
|
ck_assert_int_eq(log_fn_called, 1);
|
|
|
|
|
|
|
|
|
|
/* error for NULL device */
|
|
|
|
|
libevdev_set_device_log_function(NULL, devlogfunc,
|
|
|
|
|
LIBEVDEV_LOG_ERROR, NULL);
|
|
|
|
|
ck_assert_int_eq(log_fn_called, 2);
|
|
|
|
|
|
|
|
|
|
log_fn_called = 0;
|
|
|
|
|
|
|
|
|
|
dev = libevdev_new();
|
|
|
|
|
ck_assert(dev != NULL);
|
|
|
|
|
|
|
|
|
|
libevdev_set_device_log_function(dev, NULL,
|
|
|
|
|
LIBEVDEV_LOG_ERROR, NULL);
|
|
|
|
|
|
|
|
|
|
/* libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL) should
|
|
|
|
|
trigger a log message. */
|
|
|
|
|
|
|
|
|
|
/* expect global handler triggered */
|
|
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
|
|
|
|
ck_assert_int_eq(log_fn_called, 1);
|
|
|
|
|
ck_assert_int_eq(dev_log_fn_called, 0);
|
|
|
|
|
|
|
|
|
|
/* expect device handler triggered */
|
|
|
|
|
libevdev_set_device_log_function(dev, devlogfunc,
|
|
|
|
|
LIBEVDEV_LOG_ERROR, dev);
|
|
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
|
|
|
|
ck_assert_int_eq(log_fn_called, 1);
|
|
|
|
|
ck_assert_int_eq(dev_log_fn_called, 1);
|
|
|
|
|
|
|
|
|
|
/* device handler set, but priority filters. don't expect any log
|
|
|
|
|
handler to be called.
|
|
|
|
|
we don't have any log msgs > ERROR at the moment, so test it by
|
|
|
|
|
setting an invalid priority. */
|
|
|
|
|
libevdev_set_device_log_function(dev, devlogfunc,
|
|
|
|
|
LIBEVDEV_LOG_ERROR - 1, dev);
|
|
|
|
|
libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, NULL);
|
|
|
|
|
ck_assert_int_eq(log_fn_called, 1);
|
|
|
|
|
ck_assert_int_eq(dev_log_fn_called, 1);
|
|
|
|
|
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
|
|
|
|
|
log_fn_called = 0;
|
|
|
|
|
libevdev_set_log_priority(old);
|
|
|
|
|
libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
2013-06-05 11:17:11 +10:00
|
|
|
START_TEST(test_device_init)
|
|
|
|
|
{
|
|
|
|
|
struct uinput_device* uidev;
|
|
|
|
|
struct libevdev *dev;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
rc = uinput_device_new_with_events(&uidev,
|
2013-07-05 09:08:04 +10:00
|
|
|
TEST_DEVICE_NAME, DEFAULT_IDS,
|
2013-06-05 11:17:11 +10:00
|
|
|
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 uinput device: %s", strerror(-rc));
|
|
|
|
|
|
|
|
|
|
dev = libevdev_new();
|
|
|
|
|
ck_assert(dev != NULL);
|
|
|
|
|
rc = libevdev_set_fd(dev, uinput_device_get_fd(uidev));
|
|
|
|
|
ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
|
|
|
|
|
|
|
|
|
|
uinput_device_free(uidev);
|
2013-06-28 13:13:55 +10:00
|
|
|
libevdev_free(dev);
|
2013-06-05 11:17:11 +10:00
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
|
|
|
|
START_TEST(test_device_init_from_fd)
|
|
|
|
|
{
|
|
|
|
|
struct uinput_device* uidev;
|
|
|
|
|
struct libevdev *dev;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
rc = uinput_device_new_with_events(&uidev,
|
2013-07-05 09:08:04 +10:00
|
|
|
TEST_DEVICE_NAME, DEFAULT_IDS,
|
2013-06-05 11:17:11 +10:00
|
|
|
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 uinput device: %s", strerror(-rc));
|
|
|
|
|
|
|
|
|
|
rc = libevdev_new_from_fd(uinput_device_get_fd(uidev), &dev);
|
|
|
|
|
ck_assert_msg(rc == 0, "Failed to init device: %s", strerror(-rc));;
|
|
|
|
|
|
|
|
|
|
uinput_device_free(uidev);
|
2013-06-28 13:13:55 +10:00
|
|
|
libevdev_free(dev);
|
2013-06-05 11:17:11 +10:00
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
2013-06-27 10:23:23 +10:00
|
|
|
START_TEST(test_device_grab)
|
|
|
|
|
{
|
|
|
|
|
struct uinput_device* uidev;
|
|
|
|
|
struct libevdev *dev;
|
|
|
|
|
int rc;
|
|
|
|
|
|
2014-04-02 11:12:42 +10:00
|
|
|
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);
|
2013-06-27 10:23:23 +10:00
|
|
|
|
2014-01-17 10:21:48 +10:00
|
|
|
libevdev_set_log_function(test_logfunc_ignore_error, NULL);
|
2013-06-27 10:23:23 +10:00
|
|
|
rc = libevdev_grab(dev, 0);
|
|
|
|
|
ck_assert_int_eq(rc, -EINVAL);
|
|
|
|
|
rc = libevdev_grab(dev, 1);
|
|
|
|
|
ck_assert_int_eq(rc, -EINVAL);
|
2014-01-17 10:21:48 +10:00
|
|
|
libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
|
2013-06-27 10:23:23 +10:00
|
|
|
|
|
|
|
|
rc = libevdev_grab(dev, LIBEVDEV_UNGRAB);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
rc = libevdev_grab(dev, LIBEVDEV_GRAB);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
rc = libevdev_grab(dev, LIBEVDEV_GRAB);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
rc = libevdev_grab(dev, LIBEVDEV_UNGRAB);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
|
|
|
|
|
uinput_device_free(uidev);
|
2013-06-28 13:13:55 +10:00
|
|
|
libevdev_free(dev);
|
2013-06-27 10:23:23 +10:00
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
2014-11-17 11:54:04 +10:00
|
|
|
START_TEST(test_device_grab_invalid_fd)
|
|
|
|
|
{
|
|
|
|
|
struct uinput_device* uidev;
|
|
|
|
|
struct libevdev *dev;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
libevdev_set_log_function(test_logfunc_ignore_error, NULL);
|
|
|
|
|
|
|
|
|
|
dev = libevdev_new();
|
|
|
|
|
rc = libevdev_grab(dev, 0);
|
|
|
|
|
ck_assert_int_eq(rc, -EBADF);
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
libevdev_change_fd(dev, -2);
|
|
|
|
|
rc = libevdev_grab(dev, 0);
|
|
|
|
|
ck_assert_int_eq(rc, -EBADF);
|
|
|
|
|
|
|
|
|
|
libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
|
|
|
|
|
|
|
|
|
|
uinput_device_free(uidev);
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
2017-12-13 09:20:55 +10:00
|
|
|
START_TEST(test_device_grab_change_fd)
|
|
|
|
|
{
|
|
|
|
|
struct libevdev_uinput *uidev;
|
|
|
|
|
struct libevdev *dev, *other;
|
|
|
|
|
struct input_event e;
|
|
|
|
|
int rc;
|
|
|
|
|
int other_fd;
|
|
|
|
|
int dev_fd;
|
|
|
|
|
|
|
|
|
|
dev = libevdev_new();
|
|
|
|
|
libevdev_set_name(dev, "libevdev test device");
|
|
|
|
|
libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
|
|
|
|
|
libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
|
|
|
|
|
libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
|
|
|
|
|
|
|
|
|
|
rc = libevdev_uinput_create_from_device(dev,
|
|
|
|
|
LIBEVDEV_UINPUT_OPEN_MANAGED,
|
|
|
|
|
&uidev);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
|
|
|
|
|
dev_fd = open(libevdev_uinput_get_devnode(uidev),
|
|
|
|
|
O_RDONLY|O_NONBLOCK);
|
|
|
|
|
ck_assert_int_ne(dev_fd, -1);
|
|
|
|
|
rc = libevdev_new_from_fd(dev_fd, &dev);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
|
|
|
|
|
other_fd = open(libevdev_uinput_get_devnode(uidev),
|
|
|
|
|
O_RDONLY|O_NONBLOCK);
|
|
|
|
|
ck_assert_int_ne(other_fd, -1);
|
|
|
|
|
rc = libevdev_new_from_fd(other_fd, &other);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
|
|
|
|
|
/* check we're getting the events before the grab */
|
|
|
|
|
libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
|
|
|
|
|
libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
|
|
|
|
|
rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
|
|
|
|
|
ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
|
|
|
|
|
rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
|
|
|
|
|
ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
|
|
|
|
|
rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
|
|
|
|
|
ck_assert_int_eq(rc, -EAGAIN);
|
|
|
|
|
|
|
|
|
|
/* no events after the grab */
|
|
|
|
|
rc = libevdev_grab(dev, LIBEVDEV_GRAB);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
|
|
|
|
|
libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
|
|
|
|
|
rc = libevdev_grab(dev, LIBEVDEV_GRAB);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
|
|
|
|
|
ck_assert_int_eq(rc, -EAGAIN);
|
|
|
|
|
|
|
|
|
|
/* swapping the fd removes the grab */
|
|
|
|
|
close(dev_fd);
|
|
|
|
|
dev_fd = open(libevdev_uinput_get_devnode(uidev),
|
|
|
|
|
O_RDONLY|O_NONBLOCK);
|
|
|
|
|
ck_assert_int_ne(dev_fd, -1);
|
|
|
|
|
rc = libevdev_change_fd(dev, dev_fd);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
|
|
|
|
|
/* check we're getting the events again */
|
|
|
|
|
libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
|
|
|
|
|
libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
|
|
|
|
|
rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
|
|
|
|
|
ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
|
|
|
|
|
rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
|
|
|
|
|
ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
|
|
|
|
|
rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
|
|
|
|
|
ck_assert_int_eq(rc, -EAGAIN);
|
|
|
|
|
|
|
|
|
|
/* no events after the grab */
|
|
|
|
|
rc = libevdev_grab(dev, LIBEVDEV_GRAB);
|
|
|
|
|
ck_assert_int_eq(rc, 0);
|
|
|
|
|
libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
|
|
|
|
|
libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
|
|
|
|
|
rc = libevdev_next_event(other, LIBEVDEV_READ_FLAG_NORMAL, &e);
|
|
|
|
|
ck_assert_int_eq(rc, -EAGAIN);
|
|
|
|
|
|
|
|
|
|
libevdev_uinput_destroy(uidev);
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
libevdev_free(other);
|
|
|
|
|
close(dev_fd);
|
|
|
|
|
close(other_fd);
|
|
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
2013-09-12 13:42:24 +10:00
|
|
|
START_TEST(test_set_clock_id)
|
|
|
|
|
{
|
|
|
|
|
struct uinput_device* uidev;
|
|
|
|
|
struct libevdev *dev;
|
|
|
|
|
int rc;
|
|
|
|
|
|
2014-04-02 11:12:42 +10:00
|
|
|
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);
|
2013-09-12 13:42:24 +10:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2014-11-17 12:06:46 +10:00
|
|
|
START_TEST(test_set_clock_id_invalid_fd)
|
|
|
|
|
{
|
|
|
|
|
struct uinput_device* uidev;
|
|
|
|
|
struct libevdev *dev;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
libevdev_set_log_function(test_logfunc_ignore_error, NULL);
|
|
|
|
|
|
|
|
|
|
dev = libevdev_new();
|
|
|
|
|
rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
|
|
|
|
|
ck_assert_int_eq(rc, -EBADF);
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
libevdev_change_fd(dev, -2);
|
|
|
|
|
rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
|
|
|
|
|
ck_assert_int_eq(rc, -EBADF);
|
|
|
|
|
|
|
|
|
|
uinput_device_free(uidev);
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
2013-09-12 13:42:24 +10:00
|
|
|
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;
|
2013-10-28 17:16:43 +01:00
|
|
|
int64_t t1, t2;
|
2013-09-12 13:42:24 +10:00
|
|
|
|
2014-04-02 11:12:42 +10:00
|
|
|
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);
|
2013-09-12 13:42:24 +10:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
2018-01-15 16:21:08 -08:00
|
|
|
t1 = ev1.input_event_sec * 1000000LL + ev1.input_event_usec;
|
|
|
|
|
t2 = ev2.input_event_sec * 1000000LL + ev2.input_event_usec;
|
2013-10-28 17:16:43 +01:00
|
|
|
ck_assert_int_ne(t1, t2);
|
2013-09-12 13:42:24 +10:00
|
|
|
|
2018-01-15 16:21:08 -08:00
|
|
|
ck_assert_int_ge(ev1.input_event_sec, t1_real.tv_sec);
|
|
|
|
|
ck_assert_int_ge(ev1.input_event_usec, t1_real.tv_nsec/1000);
|
|
|
|
|
ck_assert_int_le(ev1.input_event_sec, t2_real.tv_sec);
|
|
|
|
|
ck_assert_int_le(ev1.input_event_usec, t2_real.tv_nsec/1000);
|
2013-09-12 13:42:24 +10:00
|
|
|
|
2018-01-15 16:21:08 -08:00
|
|
|
ck_assert_int_ge(ev2.input_event_sec, t1_mono.tv_sec);
|
|
|
|
|
ck_assert_int_ge(ev2.input_event_usec, t1_mono.tv_nsec/1000);
|
|
|
|
|
ck_assert_int_le(ev2.input_event_sec, t2_mono.tv_sec);
|
|
|
|
|
ck_assert_int_le(ev2.input_event_usec, t2_mono.tv_nsec/1000);
|
2013-09-12 13:42:24 +10:00
|
|
|
|
|
|
|
|
uinput_device_free(uidev);
|
|
|
|
|
libevdev_free(dev);
|
|
|
|
|
libevdev_free(dev2);
|
|
|
|
|
close(fd);
|
|
|
|
|
}
|
|
|
|
|
END_TEST
|
|
|
|
|
|
2018-06-15 14:51:19 +10:00
|
|
|
TEST_SUITE_ROOT_PRIVILEGES(libevdev_init_test)
|
2013-06-05 11:17:11 +10:00
|
|
|
{
|
|
|
|
|
Suite *s = suite_create("libevdev init tests");
|
|
|
|
|
|
2020-02-11 20:37:01 +10:00
|
|
|
add_test(s, test_new_device);
|
|
|
|
|
add_test(s, test_free_device);
|
|
|
|
|
add_test(s, test_init_from_invalid_fd);
|
|
|
|
|
add_test(s, test_init_and_change_fd);
|
|
|
|
|
|
|
|
|
|
add_test(s, test_log_init);
|
|
|
|
|
add_test(s, test_log_priority);
|
|
|
|
|
add_test(s, test_log_set_get_priority);
|
|
|
|
|
add_test(s, test_log_default_priority);
|
|
|
|
|
add_test(s, test_log_data);
|
|
|
|
|
add_test(s, test_device_log_init);
|
|
|
|
|
|
|
|
|
|
add_test(s, test_device_init);
|
|
|
|
|
add_test(s, test_device_init_from_fd);
|
|
|
|
|
|
|
|
|
|
add_test(s, test_device_grab);
|
|
|
|
|
add_test(s, test_device_grab_invalid_fd);
|
|
|
|
|
add_test(s, test_device_grab_change_fd);
|
|
|
|
|
|
|
|
|
|
add_test(s, test_set_clock_id);
|
|
|
|
|
add_test(s, test_set_clock_id_invalid_fd);
|
|
|
|
|
add_test(s, test_clock_id_events);
|
2013-09-12 13:42:24 +10:00
|
|
|
|
2013-06-05 11:17:11 +10:00
|
|
|
return s;
|
|
|
|
|
}
|