[PATCH libevdev 3/7] Add setters for an event or slot value

Peter Hutterer peter.hutterer at who-t.net
Tue Aug 13 17:50:50 PDT 2013


Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 libevdev/libevdev.c         |  47 ++++++++++++
 libevdev/libevdev.h         |  52 +++++++++++++
 test/test-libevdev-events.c | 180 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 279 insertions(+)

diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c
index 4603651..cade991 100644
--- a/libevdev/libevdev.c
+++ b/libevdev/libevdev.c
@@ -773,6 +773,29 @@ libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned
 	return value;
 }
 
+int libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int code, int value)
+{
+	int rc = 0;
+	struct input_event e;
+
+	if (!libevdev_has_event_type(dev, type) || !libevdev_has_event_code(dev, type, code))
+		return -1;
+
+	e.type = type;
+	e.code = code;
+	e.value = value;
+
+	switch(type) {
+		case EV_ABS: rc = update_abs_state(dev, &e); break;
+		case EV_KEY: rc = update_key_state(dev, &e); break;
+		default:
+			     rc = -1;
+			     break;
+	}
+
+	return rc;
+}
+
 int
 libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, unsigned int code, int *value)
 {
@@ -800,6 +823,30 @@ libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned
 }
 
 int
+libevdev_set_slot_value(struct libevdev *dev, unsigned int slot, unsigned int code, int value)
+{
+	if (!libevdev_has_event_type(dev, EV_ABS) || !libevdev_has_event_code(dev, EV_ABS, code))
+		return -1;
+
+	if (slot >= dev->num_slots || slot >= MAX_SLOTS)
+		return -1;
+
+	if (code > ABS_MT_MAX || code < ABS_MT_MIN)
+		return -1;
+
+	if (code == ABS_MT_SLOT) {
+		if (value < 0 || value >= libevdev_get_num_slots(dev))
+			return -1;
+		dev->current_slot = value;
+	}
+
+	dev->mt_slot_vals[slot][code - ABS_MT_MIN] = value;
+
+
+	return 0;
+}
+
+int
 libevdev_fetch_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code, int *value)
 {
 	if (libevdev_has_event_type(dev, EV_ABS) &&
diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h
index ccb2cc7..4c01847 100644
--- a/libevdev/libevdev.h
+++ b/libevdev/libevdev.h
@@ -814,6 +814,30 @@ const struct input_absinfo* libevdev_get_abs_info(const struct libevdev *dev, un
 int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsigned int code);
 
 /**
+ * @ingroup kernel
+ *
+ * Set the value for a given event type and code. This only makes sense for
+ * some event types, e.g. setting the value for EV_REL is pointless.
+ *
+ * This is a local modification only affecting only this representation of
+ * this device. A future call to libevdev_get_event_value() will return this
+ * value, unless the value was overwritten by an event.
+ *
+ * @param dev The evdev device, already initialized with libevdev_set_fd()
+ * @param type The event type for the code to query (EV_SYN, EV_REL, etc.)
+ * @param code The event code to set the value for, one of ABS_X, LED_NUML, etc.
+ * @param value The new value to set
+ *
+ * @return 0 on success, or -1 on failure.
+ * @retval -1 the device does not have the event type or code enabled, or the code is outside the
+ * allowed limits for the given type, or the type cannot be set.
+ *
+ * @see libevdev_set_slot_value
+ * @see libevdev_get_event_value
+ */
+int libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int code, int value);
+
+/**
  * @ingroup bits
  *
  * Fetch the current value of the event type. This is a shortcut for
@@ -863,6 +887,34 @@ int libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, un
 int libevdev_get_slot_value(const struct libevdev *dev, unsigned int slot, unsigned int code);
 
 /**
+ * @ingroup kernel
+ *
+ * Set the value for a given code for the given slot.
+ *
+ * This is a local modification only affecting only this representation of
+ * this device. A future call to libevdev_get_slot_value() will return this
+ * value, unless the value was overwritten by an event.
+ *
+ * This function does not set event values for axes outside the ABS_MT range,
+ * use libevdev_set_event_value() instead.
+ *
+ * @param dev The evdev device, already initialized with libevdev_set_fd()
+ * @param slot The numerical slot number, must be smaller than the total number
+ * of slots on this device
+ * @param code The event code to set the value for, one of ABS_MT_POSITION_X, etc.
+ * @param value The new value to set
+ *
+ * @return 0 on success, or -1 on failure.
+ * @retval -1 the device does not have the event code enabled, or the code is
+ * outside the allowed limits for multitouch events, or the slot number is outside
+ * the limits for this device, or the device does not support multitouch events.
+ *
+ * @see libevdev_set_event_value
+ * @see libevdev_get_slot_value
+ */
+int libevdev_set_slot_value(struct libevdev *dev, unsigned int slot, unsigned int code, int value);
+
+/**
  * @ingroup mt
  *
  * Fetch the current value of the code for the given slot. This is a shortcut for
diff --git a/test/test-libevdev-events.c b/test/test-libevdev-events.c
index 40f94dd..95105d1 100644
--- a/test/test-libevdev-events.c
+++ b/test/test-libevdev-events.c
@@ -806,6 +806,179 @@ START_TEST(test_mt_event_values_invalid)
 }
 END_TEST
 
+START_TEST(test_event_value_setters)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_absinfo abs[2];
+
+	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, SYN_REPORT,
+				    EV_REL, REL_X,
+				    EV_REL, REL_Y,
+				    EV_KEY, BTN_LEFT,
+				    EV_KEY, BTN_MIDDLE,
+				    EV_KEY, BTN_RIGHT,
+				    -1);
+	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_X), 0);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_REL, REL_Y), 0);
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_KEY, BTN_LEFT, 1), 0);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_KEY, BTN_RIGHT, 1), 0);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_LEFT), 1);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_KEY, BTN_RIGHT), 1);
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_X, 10), 0);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_Y, 20), 0);
+
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_X), 10);
+	ck_assert_int_eq(libevdev_get_event_value(dev, EV_ABS, ABS_Y), 20);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+
+}
+END_TEST
+
+START_TEST(test_event_value_setters_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_absinfo abs[2];
+
+	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, SYN_REPORT,
+				    EV_REL, REL_X,
+				    EV_REL, REL_Y,
+				    EV_KEY, BTN_LEFT,
+				    EV_KEY, BTN_MIDDLE,
+				    EV_KEY, BTN_RIGHT,
+				    -1);
+	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
+
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_REL, REL_X, 1), -1);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_SW, SW_DOCK, 1), -1);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_Z, 1), -1);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_MAX + 1, 0, 1), -1);
+	ck_assert_int_eq(libevdev_set_event_value(dev, EV_SYN, SYN_REPORT, 0), -1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+
+}
+END_TEST
+
+START_TEST(test_event_mt_value_setters)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_absinfo abs[5];
+
+	memset(abs, 0, sizeof(abs));
+	abs[0].value = ABS_X;
+	abs[0].maximum = 1000;
+	abs[1].value = ABS_MT_POSITION_X;
+	abs[1].maximum = 1000;
+
+	abs[2].value = ABS_Y;
+	abs[2].maximum = 1000;
+	abs[3].value = ABS_MT_POSITION_Y;
+	abs[3].maximum = 1000;
+
+	abs[4].value = ABS_MT_SLOT;
+	abs[4].maximum = 2;
+
+	rc = test_create_abs_device(&uidev, &dev,
+				    5, abs,
+				    EV_SYN, SYN_REPORT,
+				    -1);
+	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
+
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_POSITION_X, 1), 0);
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_POSITION_Y, 2), 0);
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_X, 3), 0);
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_Y, 4), 0);
+
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_X), 1);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_POSITION_Y), 2);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_X), 3);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 0, ABS_MT_POSITION_Y), 4);
+
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_SLOT, 1), 0);
+	ck_assert_int_eq(libevdev_get_slot_value(dev, 1, ABS_MT_SLOT), 1);
+	ck_assert_int_eq(libevdev_get_current_slot(dev), 1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
+START_TEST(test_event_mt_value_setters_invalid)
+{
+	struct uinput_device* uidev;
+	struct libevdev *dev;
+	int rc;
+	struct input_absinfo abs[5];
+
+	memset(abs, 0, sizeof(abs));
+	abs[0].value = ABS_X;
+	abs[0].maximum = 1000;
+	abs[1].value = ABS_MT_POSITION_X;
+	abs[1].maximum = 1000;
+
+	abs[2].value = ABS_Y;
+	abs[2].maximum = 1000;
+	abs[3].value = ABS_MT_POSITION_Y;
+	abs[3].maximum = 1000;
+
+	abs[4].value = ABS_MT_SLOT;
+	abs[4].maximum = 2;
+
+	rc = test_create_abs_device(&uidev, &dev,
+				    5, abs,
+				    EV_SYN, SYN_REPORT,
+				    -1);
+	ck_assert_msg(rc == 0, "Failed to create device: %s", strerror(-rc));
+
+	/* invalid axis */
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_Z, 1), -1);
+	/* valid, but non-mt axis */
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_X, 1), -1);
+	/* invalid mt axis */
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 1, ABS_MT_PRESSURE, 1), -1);
+	/* invalid slot no */
+	ck_assert_int_eq(libevdev_set_slot_value(dev, 4, ABS_X, 1), -1);
+
+	uinput_device_free(uidev);
+	libevdev_free(dev);
+}
+END_TEST
+
 Suite *
 libevdev_events(void)
 {
@@ -838,6 +1011,13 @@ libevdev_events(void)
 	tcase_add_test(tc, test_mt_event_values_invalid);
 	suite_add_tcase(s, tc);
 
+	tc = tcase_create("event value setters");
+	tcase_add_test(tc, test_event_value_setters);
+	tcase_add_test(tc, test_event_value_setters_invalid);
+	tcase_add_test(tc, test_event_mt_value_setters);
+	tcase_add_test(tc, test_event_mt_value_setters_invalid);
+	suite_add_tcase(s, tc);
+
 	return s;
 }
 
-- 
1.8.2.1



More information about the Input-tools mailing list