Add abs setters for changing a single value on an abs axis
authorPeter Hutterer <peter.hutterer@who-t.net>
Wed, 24 Jul 2013 05:52:02 +0000 (15:52 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Thu, 1 Aug 2013 03:53:05 +0000 (13:53 +1000)
Changing a single value on an abs axis is slightly more common than
having to enable that axis outright. Provide a set of accessors for
doing so.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
libevdev/libevdev.c
libevdev/libevdev.h
test/test-libevdev-has-event.c

index cdf338b..a17e388 100644 (file)
@@ -821,6 +821,28 @@ ABS_GETTER(fuzz, fuzz)
 ABS_GETTER(flat, flat)
 ABS_GETTER(resolution, resolution)
 
+#define ABS_SETTER(field) \
+void libevdev_set_abs_##field(struct libevdev *dev, unsigned int code, int val) \
+{ \
+       if (!libevdev_has_event_code(dev, EV_ABS, code)) \
+               return; \
+       dev->abs_info[code].field = val; \
+}
+
+ABS_SETTER(maximum)
+ABS_SETTER(minimum)
+ABS_SETTER(fuzz)
+ABS_SETTER(flat)
+ABS_SETTER(resolution)
+
+void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs)
+{
+       if (!libevdev_has_event_code(dev, EV_ABS, code))
+               return;
+
+       dev->abs_info[code] = *abs;
+}
+
 int
 libevdev_enable_event_type(struct libevdev *dev, unsigned int type)
 {
index c8159ca..427bf39 100644 (file)
@@ -845,6 +845,60 @@ int libevdev_get_current_slot(const struct libevdev *dev);
 /**
  * @ingroup kernel
  *
+ * Change the minimum for the given EV_ABS event code, if the code exists.
+ * This function has no effect if libevdev_has_event_code() returns false for
+ * this code.
+ */
+void libevdev_set_abs_minimum(struct libevdev *dev, unsigned int code, int min);
+
+/**
+ * @ingroup kernel
+ *
+ * Change the maximum for the given EV_ABS event code, if the code exists.
+ * This function has no effect if libevdev_has_event_code() returns false for
+ * this code.
+ */
+void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int max);
+
+/**
+ * @ingroup kernel
+ *
+ * Change the fuzz for the given EV_ABS event code, if the code exists.
+ * This function has no effect if libevdev_has_event_code() returns false for
+ * this code.
+ */
+void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int fuzz);
+
+/**
+ * @ingroup kernel
+ *
+ * Change the flat for the given EV_ABS event code, if the code exists.
+ * This function has no effect if libevdev_has_event_code() returns false for
+ * this code.
+ */
+void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int flat);
+
+/**
+ * @ingroup kernel
+ *
+ * Change the resolution for the given EV_ABS event code, if the code exists.
+ * This function has no effect if libevdev_has_event_code() returns false for
+ * this code.
+ */
+void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int resolution);
+
+/**
+ * @ingroup kernel
+ *
+ * Change the abs info for the given EV_ABS event code, if the code exists.
+ * This function has no effect if libevdev_has_event_code() returns false for
+ * this code.
+ */
+void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs);
+
+/**
+ * @ingroup kernel
+ *
  * 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_type().
index 1d2266c..a39cb3f 100644 (file)
@@ -543,6 +543,70 @@ START_TEST(test_device_get_abs_info)
 }
 END_TEST
 
+START_TEST(test_device_set_abs)
+{
+       struct uinput_device* uidev;
+       struct libevdev *dev;
+       struct input_absinfo abs[2];
+       struct input_absinfo a;
+       int rc;
+
+       memset(abs, 0, sizeof(abs));
+       abs[0].value = ABS_X;
+       abs[0].maximum = 1000;
+
+       abs[1].value = ABS_Y;
+       abs[1].maximum = 1000;
+
+       rc = test_create_abs_device(&uidev, &dev,
+                                   2, abs,
+                                   EV_SYN,
+                                   -1);
+       ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
+
+       libevdev_set_abs_minimum(dev, ABS_X, 1);
+       libevdev_set_abs_minimum(dev, ABS_Y, 5);
+       ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_X),  1);
+       ck_assert_int_eq(libevdev_get_abs_minimum(dev, ABS_Y),  5);
+
+       libevdev_set_abs_maximum(dev, ABS_X, 3000);
+       libevdev_set_abs_maximum(dev, ABS_Y, 5000);
+       ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_X),  3000);
+       ck_assert_int_eq(libevdev_get_abs_maximum(dev, ABS_Y),  5000);
+
+       libevdev_set_abs_fuzz(dev, ABS_X, 3);
+       libevdev_set_abs_fuzz(dev, ABS_Y, 5);
+       ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_X),  3);
+       ck_assert_int_eq(libevdev_get_abs_fuzz(dev, ABS_Y),  5);
+
+       libevdev_set_abs_flat(dev, ABS_X, 8);
+       libevdev_set_abs_flat(dev, ABS_Y, 15);
+       ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_X),  8);
+       ck_assert_int_eq(libevdev_get_abs_flat(dev, ABS_Y),  15);
+
+       libevdev_set_abs_resolution(dev, ABS_X, 80);
+       libevdev_set_abs_resolution(dev, ABS_Y, 150);
+       ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_X),  80);
+       ck_assert_int_eq(libevdev_get_abs_resolution(dev, ABS_Y),  150);
+
+       a.minimum = 10;
+       a.maximum = 100;
+       a.fuzz = 13;
+       a.flat = 1;
+       a.resolution = 16;
+
+       libevdev_set_abs_info(dev, ABS_X, &a);
+       ck_assert_int_eq(memcmp(&a, libevdev_get_abs_info(dev, ABS_X), sizeof(a)), 0);
+
+       libevdev_set_abs_minimum(dev, ABS_Z, 10);
+       ck_assert_int_eq(libevdev_has_event_code(dev, EV_ABS, ABS_Z),  0);
+
+       uinput_device_free(uidev);
+       libevdev_free(dev);
+}
+END_TEST
+
+
 START_TEST(test_device_enable_bit)
 {
        struct uinput_device* uidev;
@@ -816,6 +880,7 @@ libevdev_has_event_test(void)
        suite_add_tcase(s, tc);
 
        tc = tcase_create("device bit manipulation");
+       tcase_add_test(tc, test_device_set_abs);
        tcase_add_test(tc, test_device_enable_bit);
        tcase_add_test(tc, test_device_enable_bit_invalid);
        tcase_add_test(tc, test_device_disable_bit);