[PATCH libinput] Change sendevents configuration to use bitmasks

Peter Hutterer peter.hutterer at who-t.net
Sun Nov 2 21:53:19 PST 2014


In the future, we should allow multiple sendevent modes set simultanously.
Change the API to use a bitmask instead of a single return value.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad.c |  8 ++++++--
 src/evdev.c             |  5 ++---
 src/libinput.c          |  8 ++++----
 src/libinput.h          | 44 +++++++++++++++++++++++++++++---------------
 test/device.c           | 40 ++++++++++++++++++++++++++++++++++++++--
 5 files changed, 79 insertions(+), 26 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index a8d12e4..34ad151 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -988,8 +988,7 @@ static uint32_t
 tp_sendevents_get_modes(struct libinput_device *device)
 {
 	struct evdev_device *evdev = (struct evdev_device*)device;
-	uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED |
-			 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
+	uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
 
 	if (evdev->tags & EVDEV_TAG_INTERNAL_TOUCHPAD)
 		modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
@@ -1019,6 +1018,11 @@ tp_sendevents_set_mode(struct libinput_device *device,
 	struct evdev_device *evdev = (struct evdev_device*)device;
 	struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
 
+	/* DISABLED overrides any DISABLED_ON_ */
+	if ((mode & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED) &&
+	    (mode & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE))
+	    mode &= ~LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
+
 	if (mode == tp->sendevents.current_mode)
 		return LIBINPUT_CONFIG_STATUS_SUCCESS;
 
diff --git a/src/evdev.c b/src/evdev.c
index 3aa87a7..1e40a30 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -717,8 +717,7 @@ struct evdev_dispatch_interface fallback_interface = {
 static uint32_t
 evdev_sendevents_get_modes(struct libinput_device *device)
 {
-	return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED |
-	       LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
+	return LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
 }
 
 static enum libinput_config_status
@@ -738,7 +737,7 @@ evdev_sendevents_set_mode(struct libinput_device *device,
 	case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
 		evdev_device_suspend(evdev);
 		break;
-	default:
+	default: /* no support for combined modes yet */
 		return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
 	}
 
diff --git a/src/libinput.c b/src/libinput.c
index 5780a92..05e594e 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -1363,9 +1363,9 @@ libinput_device_config_send_events_get_modes(struct libinput_device *device)
 
 LIBINPUT_EXPORT enum libinput_config_status
 libinput_device_config_send_events_set_mode(struct libinput_device *device,
-					    enum libinput_config_send_events_mode mode)
+					    uint32_t mode)
 {
-	if ((libinput_device_config_send_events_get_modes(device) & mode) == 0)
+	if ((libinput_device_config_send_events_get_modes(device) & mode) != mode)
 		return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
 
 	if (device->config.sendevents)
@@ -1374,7 +1374,7 @@ libinput_device_config_send_events_set_mode(struct libinput_device *device,
 		return LIBINPUT_CONFIG_STATUS_SUCCESS;
 }
 
-LIBINPUT_EXPORT enum libinput_config_send_events_mode
+LIBINPUT_EXPORT uint32_t
 libinput_device_config_send_events_get_mode(struct libinput_device *device)
 {
 	if (device->config.sendevents)
@@ -1383,7 +1383,7 @@ libinput_device_config_send_events_get_mode(struct libinput_device *device)
 		return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
 }
 
-LIBINPUT_EXPORT enum libinput_config_send_events_mode
+LIBINPUT_EXPORT uint32_t
 libinput_device_config_send_events_get_default_mode(struct libinput_device *device)
 {
 	return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
diff --git a/src/libinput.h b/src/libinput.h
index de6bfc8..2c60233 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -1689,22 +1689,31 @@ libinput_device_config_calibration_get_default_matrix(struct libinput_device *de
  */
 enum libinput_config_send_events_mode {
 	/**
-	 * Send events from this device normally.
+	 * Send events from this device normally. This is a placeholder
+	 * mode only, any device detected by libinput can be enabled. Do not
+	 * test for this value as bitmask.
 	 */
-	LIBINPUT_CONFIG_SEND_EVENTS_ENABLED = (1 << 0),
+	LIBINPUT_CONFIG_SEND_EVENTS_ENABLED = 0,
 	/**
 	 * Do not send events through this device. Depending on the device,
 	 * this may close all file descriptors on the device or it may leave
 	 * the file descriptors open and route events through a different
 	 * device.
+	 *
+	 * If this bit field is set, other disable modes may be
+	 * ignored. For example, if both @ref
+	 * LIBINPUT_CONFIG_SEND_EVENTS_DISABLED and @ref
+	 * LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE are set,
+	 * the device remains disabled when all external pointer devices are
+	 * unplugged.
 	 */
-	LIBINPUT_CONFIG_SEND_EVENTS_DISABLED = (1 << 1),
+	LIBINPUT_CONFIG_SEND_EVENTS_DISABLED = (1 << 0),
 	/**
 	 * If an external pointer device is plugged in, do not send events
 	 * from this device. This option may be available on built-in
 	 * touchpads.
 	 */
-	LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE = (1 << 2),
+	LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE = (1 << 1),
 };
 
 /**
@@ -1734,18 +1743,17 @@ libinput_device_config_send_events_get_modes(struct libinput_device *device);
  * received and processed from this device are unaffected and will be passed
  * to the caller on the next call to libinput_get_event().
  *
- * If the mode is one of @ref LIBINPUT_CONFIG_SEND_EVENTS_DISABLED or
- * @ref LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE, the device
- * may wait for or generate events until it is in a neutral state.
- * For example, this may include waiting for or generating button release
- * events.
+ * If the mode is a bitmask of @ref libinput_config_send_events_mode,
+ * the device may wait for or generate events until it is in a neutral
+ * state. For example, this may include waiting for or generating button
+ * release events.
  *
  * If the device is already suspended, this function does nothing and
  * returns success. Changing the send-event mode on a device that has been
  * removed is permitted.
  *
  * @param device The device to configure
- * @param mode The send-event mode for this device.
+ * @param mode A bitmask of send-events modes
  *
  * @return A config status code.
  *
@@ -1755,7 +1763,7 @@ libinput_device_config_send_events_get_modes(struct libinput_device *device);
  */
 enum libinput_config_status
 libinput_device_config_send_events_set_mode(struct libinput_device *device,
-					    enum libinput_config_send_events_mode mode);
+					    uint32_t mode);
 
 /**
  * @ingroup config
@@ -1763,14 +1771,20 @@ libinput_device_config_send_events_set_mode(struct libinput_device *device,
  * Get the send-event mode for this device. The mode defines when the device
  * processes and sends events to the caller.
  *
+ * If a caller enables the bits for multiple modes, some of which are
+ * subsets of another mode libinput may drop the bits that are subsets. In
+ * other words, don't expect libinput_device_config_send_events_get_mode()
+ * to always return exactly the same bitmask as passed into
+ * libinput_device_config_send_events_set_mode().
+ *
  * @param device The device to configure
- * @return The current send-event mode for this device.
+ * @return The current bitmask of the send-event mode for this device.
  *
  * @see libinput_device_config_send_events_get_modes
  * @see libinput_device_config_send_events_set_mode
  * @see libinput_device_config_send_events_get_default_mode
  */
-enum libinput_config_send_events_mode
+uint32_t
 libinput_device_config_send_events_get_mode(struct libinput_device *device);
 
 /**
@@ -1780,13 +1794,13 @@ libinput_device_config_send_events_get_mode(struct libinput_device *device);
  * the device processes and sends events to the caller.
  *
  * @param device The device to configure
- * @return The default send-event mode for this device.
+ * @return The bitmask of the send-event mode for this device.
  *
  * @see libinput_device_config_send_events_get_modes
  * @see libinput_device_config_send_events_set_mode
  * @see libinput_device_config_send_events_get_default_mode
  */
-enum libinput_config_send_events_mode
+uint32_t
 libinput_device_config_send_events_get_default_mode(struct libinput_device *device);
 
 /**
diff --git a/test/device.c b/test/device.c
index 3061ebc..edc115f 100644
--- a/test/device.c
+++ b/test/device.c
@@ -42,11 +42,24 @@ START_TEST(device_sendevents_config)
 
 	modes = libinput_device_config_send_events_get_modes(device);
 	ck_assert_int_eq(modes,
-			 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED|
 			 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
 }
 END_TEST
 
+START_TEST(device_sendevents_config_invalid)
+{
+	struct litest_device *dev = litest_current_device();
+	struct libinput_device *device;
+	enum libinput_config_status status;
+
+	device = dev->libinput_device;
+
+	status = libinput_device_config_send_events_set_mode(device,
+			     LIBINPUT_CONFIG_SEND_EVENTS_DISABLED | (1 << 4));
+	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
+}
+END_TEST
+
 START_TEST(device_sendevents_config_touchpad)
 {
 	struct litest_device *dev = litest_current_device();
@@ -57,12 +70,33 @@ START_TEST(device_sendevents_config_touchpad)
 
 	modes = libinput_device_config_send_events_get_modes(device);
 	ck_assert_int_eq(modes,
-			 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED|
 			 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE|
 			 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
 }
 END_TEST
 
+START_TEST(device_sendevents_config_touchpad_superset)
+{
+	struct litest_device *dev = litest_current_device();
+	struct libinput_device *device;
+	enum libinput_config_status status;
+	uint32_t modes;
+
+	device = dev->libinput_device;
+
+	modes = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED |
+		LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
+
+	status = libinput_device_config_send_events_set_mode(device,
+							     modes);
+	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+	/* DISABLED supersedes the rest, expect the rest to be dropped */
+	modes = libinput_device_config_send_events_get_mode(device);
+	ck_assert_int_eq(modes, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
+}
+END_TEST
+
 START_TEST(device_sendevents_config_default)
 {
 	struct litest_device *dev = litest_current_device();
@@ -568,7 +602,9 @@ END_TEST
 int main (int argc, char **argv)
 {
 	litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, LITEST_TOUCHPAD);
+	litest_add("device:sendevents", device_sendevents_config_invalid, LITEST_ANY, LITEST_ANY);
 	litest_add("device:sendevents", device_sendevents_config_touchpad, LITEST_TOUCHPAD, LITEST_ANY);
+	litest_add("device:sendevents", device_sendevents_config_touchpad_superset, LITEST_TOUCHPAD, LITEST_ANY);
 	litest_add("device:sendevents", device_sendevents_config_default, LITEST_ANY, LITEST_ANY);
 	litest_add("device:sendevents", device_disable, LITEST_POINTER, LITEST_ANY);
 	litest_add("device:sendevents", device_disable_touchpad, LITEST_TOUCHPAD, LITEST_ANY);
-- 
2.1.0



More information about the wayland-devel mailing list