Signed-off-by: Peter Hutterer <peter.hutte...@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 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel