Add functions to enable axis on the device in the kernel
authorPeter Hutterer <peter.hutterer@who-t.net>
Tue, 4 Jun 2013 06:24:11 +0000 (16:24 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Tue, 4 Jun 2013 10:17:27 +0000 (20:17 +1000)
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
libevdev/libevdev.c
libevdev/libevdev.h

index 76973bc..3d5bbf6 100644 (file)
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <stdarg.h>
+#include <linux/uinput.h>
 
 #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;
index a693acd..49c34d9 100644 (file)
@@ -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/<code> axis to the value defined in the abs
  * parameter. This will be written to the kernel.