From 0e9ef8a22d16c327af1a060d058b7cf746298c98 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 4 Jun 2013 16:24:11 +1000 Subject: [PATCH] Add functions to enable axis on the device in the kernel Signed-off-by: Peter Hutterer --- libevdev/libevdev.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-------- libevdev/libevdev.h | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c index 76973bc..3d5bbf6 100644 --- a/libevdev/libevdev.c +++ b/libevdev/libevdev.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "libevdev.h" #include "libevdev-int.h" @@ -753,8 +754,6 @@ libevdev_enable_event_type(struct libevdev *dev, unsigned int type) set_bit(dev->bits, type); - /* FIXME: pass through to kernel */ - return 0; } @@ -766,8 +765,6 @@ libevdev_disable_event_type(struct libevdev *dev, unsigned int type) clear_bit(dev->bits, type); - /* FIXME: pass through to kernel */ - return 0; } @@ -793,8 +790,6 @@ libevdev_enable_event_code(struct libevdev *dev, unsigned int type, dev->abs_info[code] = *abs; } - /* FIXME: pass through to kernel */ - return 0; } @@ -814,12 +809,59 @@ libevdev_disable_event_code(struct libevdev *dev, unsigned int type, unsigned in clear_bit(mask, code); - /* FIXME: pass through to kernel */ - return 0; } int +libevdev_kernel_enable_event_type(struct libevdev *dev, unsigned int type) +{ + int rc; + + if (type > EV_MAX) + return -1; + + rc = ioctl(dev->fd, UI_SET_EVBIT, type); + if (rc != -1) + libevdev_enable_event_type(dev, type); + + return (rc != -1) ? 0 : -errno; +} + +int +libevdev_kernel_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code) +{ + int rc; + int uinput_bit; + int max; + const unsigned long *mask; + + rc = libevdev_kernel_enable_event_type(dev, type); + if (rc != 0) + return rc; + + max = type_to_mask_const(dev, type, &mask); + if (code > max) + return -EINVAL; + + switch(type) { + case EV_KEY: uinput_bit = UI_SET_KEYBIT; break; + case EV_REL: uinput_bit = UI_SET_RELBIT; break; + case EV_ABS: uinput_bit = UI_SET_ABSBIT; break; + case EV_MSC: uinput_bit = UI_SET_MSCBIT; break; + case EV_LED: uinput_bit = UI_SET_LEDBIT; break; + case EV_SND: uinput_bit = UI_SET_SNDBIT; break; + case EV_FF: uinput_bit = UI_SET_FFBIT; break; + case EV_SW: uinput_bit = UI_SET_SWBIT; break; + } + + rc = ioctl(dev->fd, uinput_bit, type); + if (rc != -1) + libevdev_enable_event_type(dev, type); + + return (rc != -1) ? 0 : -errno; +} + +int libevdev_kernel_set_abs_value(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs) { int rc; diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h index a693acd..49c34d9 100644 --- a/libevdev/libevdev.h +++ b/libevdev/libevdev.h @@ -454,6 +454,41 @@ int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned */ int libevdev_disable_event_code(struct libevdev *dev, unsigned int type, unsigned int code); + +/** + * Forcibly enable an event type on this device, even if the underlying + * device does not support it. While this cannot make the device actually + * report such events, it will now return true for libevdev_has_event_code. + * + * This will be written to the kernel. + * + * This cannot be undone, the kernel only allows to enable axes, not disable + * them. + * + * This function calls libevdev_kernel_enable_event_type if necessary. + * + * @param type The event type to enable (EV_ABS, EV_KEY, ...) + * @param code The event code to enable (ABS_X, REL_X, etc.) + */ +int libevdev_kernel_enable_event_type(struct libevdev *dev, unsigned int type); + +/** + * Forcibly enable an event code on this device, even if the underlying + * device does not support it. While this cannot make the device actually + * report such events, it will now return true for libevdev_has_event_code. + * + * This will be written to the kernel. + * + * This cannot be undone, the kernel only allows to enable axes, not disable + * them. + * + * This function calls libevdev_kernel_enable_event_type if necessary. + * + * @param type The event type to enable (EV_ABS, EV_KEY, ...) + * @param code The event code to enable (ABS_X, REL_X, etc.) + */ +int libevdev_kernel_enable_event_code(struct libevdev *dev, unsigned int type, unsigned int code); + /** * Set the device's EV_ABS/ axis to the value defined in the abs * parameter. This will be written to the kernel. -- 2.7.4