touchpad: implement conditional disabling

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Peter Hutterer 2014-09-03 15:45:57 +10:00
parent cc44e747c7
commit 490ec84e73
2 changed files with 102 additions and 6 deletions

View file

@ -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;
}

View file

@ -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);