[PATCH libinput 3/5] touchpad: implement conditional disabling

Peter Hutterer peter.hutterer at who-t.net
Wed Sep 3 23:31:57 PDT 2014


Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++---
 test/device.c           | 19 ++++++++++-
 2 files changed, 102 insertions(+), 6 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 076b32a..adb3d02 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -676,12 +676,67 @@ tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
 	evdev_device_resume(device);
 }
 
+static void
+tp_device_added(struct evdev_device *device,
+		struct evdev_device *added_device)
+{
+	struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
+
+	if (tp->sendevents.current_mode !=
+	    LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
+		return;
+
+	if (added_device->tags & EVDEV_TAG_EXTERNAL_MOUSE)
+		tp_suspend(tp, device);
+}
+
+static void
+tp_device_removed(struct evdev_device *device,
+		  struct evdev_device *removed_device)
+{
+	struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
+	struct libinput_device *dev;
+
+	if (tp->sendevents.current_mode !=
+	    LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
+		return;
+
+	list_for_each(dev, &device->base.seat->devices_list, link) {
+		struct evdev_device *d = (struct evdev_device*)dev;
+		if (d != removed_device &&
+		    (d->tags & EVDEV_TAG_EXTERNAL_MOUSE)) {
+			return;
+		}
+	}
+
+	tp_resume(tp, device);
+}
+
+static void
+tp_tag_device(struct evdev_device *device,
+	      struct udev_device *udev_device)
+{
+	int bustype;
+
+	/* simple approach: touchpads on USB or Bluetooth are considered
+	 * external, anything else is internal. Exception is Apple -
+	 * internal touchpads are connected over USB and it doesn't have
+	 * external USB touchpads anyway.
+	 */
+	bustype = libevdev_get_id_bustype(device->evdev);
+	if (bustype == BUS_USB) {
+		 if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_APPLE)
+			 device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
+	} else if (bustype != BUS_BLUETOOTH)
+		device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
+}
+
 static struct evdev_dispatch_interface tp_interface = {
 	tp_process,
 	tp_destroy,
-	NULL, /* device_added */
-	NULL, /* device_removed */
-	NULL, /* tag_device */
+	tp_device_added,
+	tp_device_removed,
+	tp_tag_device,
 };
 
 static void
@@ -877,8 +932,29 @@ tp_init(struct tp_dispatch *tp,
 static uint32_t
 tp_sendevents_get_modes(struct libinput_device *device)
 {
-	return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED |
-	       LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
+	struct evdev_device *evdev = (struct evdev_device*)device;
+	uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED |
+			 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
+
+	if (evdev->tags & EVDEV_TAG_INTERNAL_TOUCHPAD)
+		modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
+
+	return modes;
+}
+
+static void
+tp_suspend_conditional(struct tp_dispatch *tp,
+		       struct evdev_device *device)
+{
+	struct libinput_device *dev;
+
+	list_for_each(dev, &device->base.seat->devices_list, link) {
+		struct evdev_device *d = (struct evdev_device*)dev;
+		if (d->tags & EVDEV_TAG_EXTERNAL_MOUSE) {
+			tp_suspend(tp, device);
+			return;
+		}
+	}
 }
 
 static enum libinput_config_status
@@ -898,6 +974,9 @@ tp_sendevents_set_mode(struct libinput_device *device,
 	case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
 		tp_suspend(tp, evdev);
 		break;
+	case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
+		tp_suspend_conditional(tp, evdev);
+		break;
 	default:
 		return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
 	}
diff --git a/test/device.c b/test/device.c
index cf20632..3f7ec4c 100644
--- a/test/device.c
+++ b/test/device.c
@@ -47,6 +47,22 @@ START_TEST(device_sendevents_config)
 }
 END_TEST
 
+START_TEST(device_sendevents_config_touchpad)
+{
+	struct litest_device *dev = litest_current_device();
+	struct libinput_device *device;
+	uint32_t modes;
+
+	device = dev->libinput_device;
+
+	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_default)
 {
 	struct litest_device *dev = litest_current_device();
@@ -495,7 +511,8 @@ END_TEST
 
 int main (int argc, char **argv)
 {
-	litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, LITEST_ANY);
+	litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, LITEST_TOUCHPAD);
+	litest_add("device:sendevents", device_sendevents_config_touchpad, 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);
-- 
1.9.3



More information about the wayland-devel mailing list