[PATCH libevdev 3/3] Add per-device log handlers
David Herrmann
dh.herrmann at gmail.com
Sun May 25 05:27:20 PDT 2014
Hi
On Mon, May 19, 2014 at 6:01 AM, Peter Hutterer
<peter.hutterer at who-t.net> wrote:
> The global log handler isn't a good choice for a low-level library. In the
> caser of the X server, both evdev and synaptics are now using the libevdev but
> are loaded from the same server process. Thus, there's only one log handler,
> but evdev and synaptics don't talk to each other (a bit childish, I know).
>
> Add a per-device log handler that overrides the global log handler, and fall
> back to the global log handler if no device log handler is set. The log
> macros take care of that automatically, especially as we can't do per-device
> log handlers for the uinput code.
>
> This also makes libevdev_new_from_fd() a bit less useful since we can't set
> the log handler beforehand.
Multi-function constructors have never been a good idea, imho. I a
constructor does more than just initialize memory, you always end up
with problematic log-handling and error-recovery. Therefore, I think
your patch is fine.
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
> Not really happy with this, but I'm yet to find a better solution. Comments
> appreciated.
>
> libevdev/libevdev-int.h | 31 +++++++--------
> libevdev/libevdev-uinput.c | 6 +--
> libevdev/libevdev.c | 85 +++++++++++++++++++++++++++++++----------
> libevdev/libevdev.h | 95 +++++++++++++++++++++++++++++++++++++++++++---
> libevdev/libevdev.sym | 8 ++++
> test/test-libevdev-init.c | 74 ++++++++++++++++++++++++++++++++++++
> 6 files changed, 255 insertions(+), 44 deletions(-)
>
> diff --git a/libevdev/libevdev-int.h b/libevdev/libevdev-int.h
> index f587e76..5b6d7de 100644
> --- a/libevdev/libevdev-int.h
> +++ b/libevdev/libevdev-int.h
> @@ -106,31 +106,32 @@ struct libevdev {
> unsigned long *tracking_id_changes;
> size_t tracking_id_changes_sz; /* in bytes */
> } mt_sync;
> -};
>
> -struct logdata {
> - enum libevdev_log_priority priority; /** minimum logging priority */
> - libevdev_log_func_t handler; /** handler function */
> - void *userdata; /** user-defined data pointer */
> + struct {
> + enum libevdev_log_priority priority; /** minimum logging priority */
> + libevdev_device_log_func_t handler; /** handler function */
> + void *userdata; /** user-defined data pointer */
> + } log;
> };
Why don't you keep "struct logdata" so we can add one to uinput-code,
too? For now uinput uses the global logger as it doesn't have a
libevdev object. If you directly pass "struct logdata" instead of the
libevdev object, we can use the same log-handlers for everything.
> -extern struct logdata log_data;
>
> -#define log_msg_cond(priority, ...) \
> +#define log_msg_cond(dev, priority, ...) \
> do { \
> - if (libevdev_get_log_priority() >= priority) \
> - log_msg(priority, log_data.userdata, __FILE__, __LINE__, __func__, __VA_ARGS__); \
> + if (log_priority(dev) >= priority) \
> + log_msg(dev, priority, __FILE__, __LINE__, __func__, __VA_ARGS__); \
> } while(0)
>
> -#define log_error(...) log_msg_cond(LIBEVDEV_LOG_ERROR, __VA_ARGS__)
> -#define log_info(...) log_msg_cond(LIBEVDEV_LOG_INFO, __VA_ARGS__)
> -#define log_dbg(...) log_msg_cond(LIBEVDEV_LOG_DEBUG, __VA_ARGS__)
> -#define log_bug(...) log_msg_cond(LIBEVDEV_LOG_ERROR, "BUG: "__VA_ARGS__)
> +#define log_error(dev, ...) log_msg_cond(dev, LIBEVDEV_LOG_ERROR, __VA_ARGS__)
> +#define log_info(dev, ...) log_msg_cond(dev, LIBEVDEV_LOG_INFO, __VA_ARGS__)
> +#define log_dbg(dev, ...) log_msg_cond(dev, LIBEVDEV_LOG_DEBUG, __VA_ARGS__)
> +#define log_bug(dev, ...) log_msg_cond(dev, LIBEVDEV_LOG_ERROR, "BUG: "__VA_ARGS__)
>
> extern void
> -log_msg(enum libevdev_log_priority priority,
> - void *data,
> +log_msg(const struct libevdev *dev,
> + enum libevdev_log_priority priority,
> const char *file, int line, const char *func,
> const char *format, ...) LIBEVDEV_ATTRIBUTE_PRINTF(6, 7);
> +extern enum libevdev_log_priority
> +log_priority(const struct libevdev *dev);
>
> /**
> * @return a pointer to the next element in the queue, or NULL if the queue
> diff --git a/libevdev/libevdev-uinput.c b/libevdev/libevdev-uinput.c
> index f176a00..e0ae31e 100644
> --- a/libevdev/libevdev-uinput.c
> +++ b/libevdev/libevdev-uinput.c
> @@ -236,7 +236,7 @@ fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
> if (strcmp(buf, uinput_dev->name) == 0) {
> if (uinput_dev->syspath) {
> /* FIXME: could descend into bit comparison here */
> - log_info("multiple identical devices found. syspath is unreliable\n");
> + log_info(NULL, "multiple identical devices found. syspath is unreliable\n");
> break;
> } else {
> strcpy(buf, SYS_INPUT_DIR);
> @@ -274,7 +274,7 @@ libevdev_uinput_create_from_device(const struct libevdev *dev, int fd, struct li
>
> new_device->fd_is_managed = 1;
> } else if (fd < 0) {
> - log_bug("Invalid fd %d\n", fd);
> + log_bug(NULL, "Invalid fd %d\n", fd);
> errno = EBADF;
> goto error;
> }
> @@ -317,7 +317,7 @@ libevdev_uinput_create_from_device(const struct libevdev *dev, int fd, struct li
> new_device->fd = fd;
>
> if (fetch_syspath_and_devnode(new_device) == -1) {
> - log_error("unable to fetch syspath or device node.\n");
> + log_error(NULL, "unable to fetch syspath or device node.\n");
> errno = ENODEV;
> goto error;
> }
> diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c
> index a316831..1e472a5 100644
> --- a/libevdev/libevdev.c
> +++ b/libevdev/libevdev.c
> @@ -36,6 +36,12 @@
>
> #define MAXEVENTS 64
>
> +struct logdata {
> + enum libevdev_log_priority priority; /** minimum logging priority */
> + libevdev_log_func_t handler; /** handler function */
> + void *userdata; /** user-defined data pointer */
> +};
Ehhh, what? You keep that structure for the global log-data, but use a
separate one for "struct libevdev"? Why don't you use the same for
both?
The log functions then get a "struct logdata*" pointer. If it's NULL,
they use the global log_data, if not, they use it directly. Or what am
I missing?
> +
> enum event_filter_status {
> EVENT_FILTER_NONE, /**< Event untouched by filters */
> EVENT_FILTER_MODIFIED, /**< Event was modified */
> @@ -48,11 +54,11 @@ static inline int*
> slot_value(const struct libevdev *dev, int slot, int axis)
> {
> if (unlikely(slot > dev->num_slots)) {
> - log_bug("Slot %d exceeds number of slots (%d)\n", slot, dev->num_slots);
> + log_bug(dev, "Slot %d exceeds number of slots (%d)\n", slot, dev->num_slots);
> slot = 0;
> }
> if (unlikely(axis < ABS_MT_MIN || axis > ABS_MT_MAX)) {
> - log_bug("MT axis %d is outside the valid range [%d,%d]\n",
> + log_bug(dev, "MT axis %d is outside the valid range [%d,%d]\n",
> axis, ABS_MT_MIN, ABS_MT_MAX);
> axis = ABS_MT_MIN;
> }
> @@ -136,24 +142,34 @@ struct logdata log_data = {
> };
>
> void
> -log_msg(enum libevdev_log_priority priority,
> - void *data,
> +log_msg(const struct libevdev *dev,
> + enum libevdev_log_priority priority,
> const char *file, int line, const char *func,
> const char *format, ...)
> {
> va_list args;
>
> - if (!log_data.handler || priority > log_data.priority)
> + if (dev && dev->log.handler) {
> + if (priority > dev->log.priority)
> + return;
> + } else if (!log_data.handler || priority > log_data.priority)
> return;
>
> +
> va_start(args, format);
> - log_data.handler(priority, data, file, line, func, format, args);
> + if (dev && dev->log.handler)
> + dev->log.handler(dev, priority, dev->log.userdata, file, line, func, format, args);
> + else
> + log_data.handler(priority, log_data.userdata, file, line, func, format, args);
> va_end(args);
> }
>
> static void
> libevdev_reset(struct libevdev *dev)
> {
> + enum libevdev_log_priority pri = dev->log.priority;
> + libevdev_device_log_func_t handler = dev->log.handler;
> +
> free(dev->name);
> free(dev->phys);
> free(dev->uniq);
> @@ -168,6 +184,8 @@ libevdev_reset(struct libevdev *dev)
> dev->current_slot = -1;
> dev->grabbed = LIBEVDEV_UNGRAB;
> dev->sync_state = SYNC_NONE;
> + dev->log.priority = pri;
> + dev->log.handler = handler;
> libevdev_enable_event_type(dev, EV_SYN);
> }
>
> @@ -235,11 +253,36 @@ libevdev_get_log_priority(void)
> return log_data.priority;
> }
>
> +LIBEVDEV_EXPORT void
> +libevdev_set_device_log_function(struct libevdev *dev,
> + libevdev_device_log_func_t logfunc,
> + enum libevdev_log_priority priority,
> + void *data)
> +{
> + if (!dev) {
> + log_bug(NULL, "device must not be NULL\n");
> + return;
> + }
> +
> + dev->log.priority = priority;
> + dev->log.handler = logfunc;
> + dev->log.userdata = data;
> +}
> +
> +enum libevdev_log_priority
> +log_priority(const struct libevdev *dev)
> +{
> + if (dev && dev->log.handler)
> + return dev->log.priority;
> + else
> + return libevdev_get_log_priority();
> +}
> +
> LIBEVDEV_EXPORT int
> libevdev_change_fd(struct libevdev *dev, int fd)
> {
> if (!dev->initialized) {
> - log_bug("device not initialized. call libevdev_set_fd() first\n");
> + log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
> return -1;
> }
> dev->fd = fd;
> @@ -254,7 +297,7 @@ libevdev_set_fd(struct libevdev* dev, int fd)
> char buf[256];
>
> if (dev->initialized) {
> - log_bug("device already initialized.\n");
> + log_bug(dev, "device already initialized.\n");
> return -EBADF;
> } else if (fd < 0)
> return -EBADF;
> @@ -743,7 +786,7 @@ drain_events(struct libevdev *dev)
> return;
>
> if (rc < 0) {
> - log_error("Failed to drain events before sync.\n");
> + log_error(dev, "Failed to drain events before sync.\n");
> return;
> }
>
> @@ -758,7 +801,7 @@ drain_events(struct libevdev *dev)
> we can drain them.
> */
> if (iterations >= max_iterations)
> - log_info("Unable to drain events, buffer size mismatch.\n");
> + log_info(dev, "Unable to drain events, buffer size mismatch.\n");
> }
>
> static int
> @@ -913,7 +956,7 @@ sanitize_event(const struct libevdev *dev,
> if (unlikely(dev->num_slots > -1 &&
> libevdev_event_is_code(ev, EV_ABS, ABS_MT_SLOT) &&
> (ev->value < 0 || ev->value >= dev->num_slots))) {
> - log_bug("Device \"%s\" received an invalid slot index %d."
> + log_bug(dev, "Device \"%s\" received an invalid slot index %d."
> "Capping to announced max slot number %d.\n",
> dev->name, ev->value, dev->num_slots - 1);
> ev->value = dev->num_slots - 1;
> @@ -930,7 +973,7 @@ sanitize_event(const struct libevdev *dev,
> *slot_value(dev, dev->current_slot, ABS_MT_TRACKING_ID) == -1) ||
> (ev->value != -1 &&
> *slot_value(dev, dev->current_slot, ABS_MT_TRACKING_ID) != -1)))) {
> - log_bug("Device \"%s\" received a double tracking ID %d in slot %d.\n",
> + log_bug(dev, "Device \"%s\" received a double tracking ID %d in slot %d.\n",
> dev->name, ev->value, dev->current_slot);
> return EVENT_FILTER_DISCARD;
> }
> @@ -945,13 +988,13 @@ libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event
> enum event_filter_status filter_status;
>
> if (!dev->initialized) {
> - log_bug("device not initialized. call libevdev_set_fd() first\n");
> + log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
> return -EBADF;
> } else if (dev->fd < 0)
> return -EBADF;
>
> if (!(flags & (LIBEVDEV_READ_FLAG_NORMAL|LIBEVDEV_READ_FLAG_SYNC|LIBEVDEV_READ_FLAG_FORCE_SYNC))) {
> - log_bug("invalid flags %#x\n.\n", flags);
> + log_bug(dev, "invalid flags %#x\n.\n", flags);
> return -EINVAL;
> }
>
> @@ -1029,7 +1072,7 @@ libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event
>
> if (queue_peek(dev, 0, &next) == 0 &&
> next.type == EV_SYN && next.code == SYN_DROPPED)
> - log_info("SYN_DROPPED received after finished "
> + log_info(dev, "SYN_DROPPED received after finished "
> "sync - you're not keeping up\n");
> }
> }
> @@ -1045,7 +1088,7 @@ libevdev_has_event_pending(struct libevdev *dev)
> int rc;
>
> if (!dev->initialized) {
> - log_bug("device not initialized. call libevdev_set_fd() first\n");
> + log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
> return -EBADF;
> } else if (dev->fd < 0)
> return -EBADF;
> @@ -1451,7 +1494,7 @@ libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const stru
> int rc;
>
> if (!dev->initialized) {
> - log_bug("device not initialized. call libevdev_set_fd() first\n");
> + log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
> return -EBADF;
> } else if (dev->fd < 0)
> return -EBADF;
> @@ -1474,13 +1517,13 @@ libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab)
> int rc = 0;
>
> if (!dev->initialized) {
> - log_bug("device not initialized. call libevdev_set_fd() first\n");
> + log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
> return -EBADF;
> } else if (dev->fd < 0)
> return -EBADF;
>
> if (grab != LIBEVDEV_GRAB && grab != LIBEVDEV_UNGRAB) {
> - log_bug("invalid grab parameter %#x\n", grab);
> + log_bug(dev, "invalid grab parameter %#x\n", grab);
> return -EINVAL;
> }
>
> @@ -1585,7 +1628,7 @@ libevdev_kernel_set_led_values(struct libevdev *dev, ...)
> size_t nleds = 0;
>
> if (!dev->initialized) {
> - log_bug("device not initialized. call libevdev_set_fd() first\n");
> + log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
> return -EBADF;
> } else if (dev->fd < 0)
> return -EBADF;
> @@ -1641,7 +1684,7 @@ LIBEVDEV_EXPORT int
> libevdev_set_clock_id(struct libevdev *dev, int clockid)
> {
> if (!dev->initialized) {
> - log_bug("device not initialized. call libevdev_set_fd() first\n");
> + log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
> return -EBADF;
> } else if (dev->fd < 0)
> return -EBADF;
> diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h
> index 2c46102..884303f 100644
> --- a/libevdev/libevdev.h
> +++ b/libevdev/libevdev.h
> @@ -619,6 +619,29 @@ extern "C" {
> */
>
> /**
> + * @defgroup logging Logging library logging facilities
> + *
> + * libevdev provides two methods of logging library-internal messages. The
> + * old method is to provide a global log handler in
> + * libevdev_set_log_function(). The new method is to provide a per-context
> + * log handler in libevdev_set_device_log_function(). Developers are encouraged
> + * to use the per-context logging facilities over the global log handler as
> + * it provides access to the libevdev instance that caused a message, and is
> + * more flexible when libevdev is used from within a shared library.
> + *
> + * If a caller sets both the global log handler and a per-context log
> + * handler, each device with a per-context log handler will only invoke that
> + * log handler.
> + *
> + * @note To set a context-specific log handler, a context is needed.
> + * Thus developers are discouraged from using libevdev_new_from_fd() as
> + * important messages from the device initialization process may get lost.
> + *
> + * @note A context-specific handler cannot be used for libevdev's uinput
> + * devices. @ref uinput must use the global log handler.
> + */
> +
> +/**
> * @defgroup bits Querying device capabilities
> *
> * Abstraction functions to handle device capabilities, specificially
> @@ -768,7 +791,7 @@ int libevdev_new_from_fd(int fd, struct libevdev **dev);
> void libevdev_free(struct libevdev *dev);
>
> /**
> - * @ingroup init
> + * @ingroup logging
> */
> enum libevdev_log_priority {
> LIBEVDEV_LOG_ERROR = 10, /**< critical errors and application bugs */
> @@ -777,7 +800,7 @@ enum libevdev_log_priority {
> };
>
> /**
> - * @ingroup init
> + * @ingroup logging
> *
> * Logging function called by library-internal logging.
> * This function is expected to treat its input like printf would.
> @@ -800,21 +823,27 @@ typedef void (*libevdev_log_func_t)(enum libevdev_log_priority priority,
> LIBEVDEV_ATTRIBUTE_PRINTF(6, 0);
>
> /**
> - * @ingroup init
> + * @ingroup logging
> *
> * Set a printf-style logging handler for library-internal logging. The default
> * logging function is to stdout.
> *
> + * @note The global log handler is only called if no context-specific log
> + * handler has been set with libevdev_set_device_log_function().
> + *
> * @param logfunc The logging function for this device. If NULL, the current
> * logging function is unset and no logging is performed.
> * @param data User-specific data passed to the log handler.
> *
> * @note This function may be called before libevdev_set_fd().
> + *
> + * @deprecated Use per-context logging instead, see
> + * libevdev_set_device_log_function().
> */
> void libevdev_set_log_function(libevdev_log_func_t logfunc, void *data);
>
> /**
> - * @ingroup init
> + * @ingroup logging
> *
> * Define the minimum level to be printed to the log handler.
> * Messages higher than this level are printed, others are discarded. This
> @@ -822,20 +851,76 @@ void libevdev_set_log_function(libevdev_log_func_t logfunc, void *data);
> *
> * @param priority Minimum priority to be printed to the log.
> *
> + * @deprecated Use per-context logging instead, see
> + * libevdev_set_device_log_function().
> */
> void libevdev_set_log_priority(enum libevdev_log_priority priority);
>
> /**
> - * @ingroup init
> + * @ingroup logging
> *
> * Return the current log priority level. Messages higher than this level
> * are printed, others are discarded. This is a global setting.
> *
> * @return the current log level
> + *
> + * @deprecated Use per-context logging instead, see
> + * libevdev_set_device_log_function().
> */
> enum libevdev_log_priority libevdev_get_log_priority(void);
>
> /**
> + * @ingroup logging
> + *
> + * Logging function called by library-internal logging for a specific
> + * libevdev context. This function is expected to treat its input like
> + * printf would.
> + *
> + * @param dev The evdev device
> + * @param priority Log priority of this message
> + * @param data User-supplied data pointer (see libevdev_set_log_function())
> + * @param file libevdev source code file generating this message
> + * @param line libevdev source code line generating this message
> + * @param func libevdev source code function generating this message
> + * @param format printf-style format string
> + * @param args List of arguments
> + *
> + * @see libevdev_set_log_function
> + */
> +typedef void (*libevdev_device_log_func_t)(const struct libevdev *dev,
> + enum libevdev_log_priority priority,
> + void *data,
> + const char *file, int line,
> + const char *func,
> + const char *format, va_list args)
> + LIBEVDEV_ATTRIBUTE_PRINTF(7, 0);
> +
> +/**
> + * @ingroup logging
> + *
> + * Set a printf-style logging handler for library-internal logging for this
> + * device context. The default logging function is NULL, i.e. the global log
> + * handler is invoked. If a context-specific log handler is set, the global
> + * log handler is not invoked for this device.
> + *
> + * @note This log function applies for this device context only, even if
> + * another context exists for the same fd.
> + *
> + * @param dev The evdev device
> + * @param logfunc The logging function for this device. If NULL, the current
> + * logging function is unset and logging falls back to the global log
> + * handler, if any.
> + * @param priority Minimum priority to be printed to the log.
> + * @param data User-specific data passed to the log handler.
> + *
> + * @note This function may be called before libevdev_set_fd().
> + */
> +void libevdev_set_device_log_function(struct libevdev *dev,
> + libevdev_device_log_func_t logfunc,
> + enum libevdev_log_priority priority,
> + void *data);
> +
I like this interface! (except for the things mentioned)
One thing: Please always keep the per-log 'data' field. In case we
ever add libevdev_set/get_data() helpers to set per-context data, we
should *not* mix this up with per-logging data. Otherwise,
log-forwarding is getting problematic.
So if you fix up the "struct logdata" mess, I can give you a
reviewed-by. So far:
Acked-by: David Herrmann <dh.herrmann at gmail.com>
Thanks
David
> +/**
> * @ingroup init
> */
> enum libevdev_grab_mode {
> diff --git a/libevdev/libevdev.sym b/libevdev/libevdev.sym
> index ef4f06b..228e555 100644
> --- a/libevdev/libevdev.sym
> +++ b/libevdev/libevdev.sym
> @@ -102,3 +102,11 @@ global:
> local:
> *;
> };
> +
> +LIBEVDEV_1_3 {
> +global:
> + libevdev_set_device_log_function;
> +
> +local:
> + *;
> +} LIBEVDEV_1;
> diff --git a/test/test-libevdev-init.c b/test/test-libevdev-init.c
> index 61fea4b..d45a319 100644
> --- a/test/test-libevdev-init.c
> +++ b/test/test-libevdev-init.c
> @@ -271,6 +271,79 @@ START_TEST(test_log_data)
> }
> END_TEST
>
> +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
> +
> START_TEST(test_device_init)
> {
> struct uinput_device* uidev;
> @@ -477,6 +550,7 @@ libevdev_init_test(void)
> tcase_add_test(tc, test_log_set_get_priority);
> tcase_add_test(tc, test_log_default_priority);
> tcase_add_test(tc, test_log_data);
> + tcase_add_test(tc, test_device_log_init);
> suite_add_tcase(s, tc);
>
> tc = tcase_create("device fd init");
> --
> 1.9.0
>
> _______________________________________________
> Input-tools mailing list
> Input-tools at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/input-tools
More information about the Input-tools
mailing list