evdev: add internal tagging system
authorPeter Hutterer <peter.hutterer@who-t.net>
Wed, 3 Sep 2014 05:50:28 +0000 (15:50 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Thu, 18 Sep 2014 03:29:42 +0000 (13:29 +1000)
For conditional touchpad disabling we need two pieces of knowledge: is the
device an internal touchpad and is another device an external mouse-like
device. For that use-case it's enough to tag any device that's on USB and
Bluetooth with pointer capabilities as external mouse. A more complex can be
done when needed.

The tag function is part of the dispatch interface (to save on udev code) and
called before the caller is notified about the new device, i.e. the device is
fully configured by the time it needs to be tagged, and other devices can rely
on the tags being assigned by the time they get notified about the new device.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
src/evdev-mt-touchpad.c
src/evdev.c
src/evdev.h

index 62becbaaa479d2e10ba615432e2f74db975af751..c6bfd1d90f4fee301bc511d39d893345bf5ec13d 100644 (file)
@@ -681,6 +681,7 @@ static struct evdev_dispatch_interface tp_interface = {
        tp_destroy,
        NULL, /* device_added */
        NULL, /* device_removed */
+       NULL, /* tag_device */
 };
 
 static void
index 638493fbb549368ed96f9de788d6e2b50234828b..f7fd2b4ff897b00fdf05fc0e786a30e80b7b72f0 100644 (file)
@@ -24,6 +24,7 @@
 #include "config.h"
 
 #include <errno.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 #include "linux/input.h"
@@ -545,6 +546,19 @@ evdev_need_touch_frame(struct evdev_device *device)
        return 0;
 }
 
+static void
+evdev_tag_external_mouse(struct evdev_device *device,
+                        struct udev_device *udev_device)
+{
+       int bustype;
+
+       bustype = libevdev_get_id_bustype(device->evdev);
+       if (bustype == BUS_USB || bustype == BUS_BLUETOOTH) {
+               if (device->seat_caps & EVDEV_DEVICE_POINTER)
+                       device->tags |= EVDEV_TAG_EXTERNAL_MOUSE;
+       }
+}
+
 static void
 fallback_process(struct evdev_dispatch *dispatch,
                 struct evdev_device *device,
@@ -578,6 +592,13 @@ fallback_destroy(struct evdev_dispatch *dispatch)
        free(dispatch);
 }
 
+static void
+fallback_tag_device(struct evdev_device *device,
+                   struct udev_device *udev_device)
+{
+       evdev_tag_external_mouse(device, udev_device);
+}
+
 static int
 evdev_calibration_has_matrix(struct libinput_device *libinput_device)
 {
@@ -624,6 +645,7 @@ struct evdev_dispatch_interface fallback_interface = {
        fallback_destroy,
        NULL, /* device_added */
        NULL, /* device_removed */
+       fallback_tag_device,
 };
 
 static uint32_t
@@ -792,6 +814,7 @@ configure_pointer_acceleration(struct evdev_device *device)
        return 0;
 }
 
+
 static inline int
 evdev_need_mtdev(struct evdev_device *device)
 {
@@ -802,6 +825,25 @@ evdev_need_mtdev(struct evdev_device *device)
                !libevdev_has_event_code(evdev, EV_ABS, ABS_MT_SLOT));
 }
 
+static void
+evdev_tag_device(struct evdev_device *device)
+{
+       struct udev *udev;
+       struct udev_device *udev_device = NULL;
+
+       udev = udev_new();
+       if (!udev)
+               return;
+
+       udev_device = udev_device_new_from_syspath(udev, device->syspath);
+       if (udev_device) {
+               if (device->dispatch->interface->tag_device)
+                       device->dispatch->interface->tag_device(device, udev_device);
+               udev_device_unref(udev_device);
+       }
+       udev_unref(udev);
+}
+
 static int
 evdev_configure_device(struct evdev_device *device)
 {
@@ -1064,6 +1106,8 @@ evdev_device_create(struct libinput_seat *seat,
                goto err;
 
        list_insert(seat->devices_list.prev, &device->base.link);
+
+       evdev_tag_device(device);
        evdev_notify_added_device(device);
 
        return device;
index 74053c5d4219778ef8f729dbddebeb664594e998..f5345fa33ec00bd0bc701e4665cd3e3e25a5af95 100644 (file)
@@ -48,6 +48,11 @@ enum evdev_device_seat_capability {
        EVDEV_DEVICE_TOUCH = (1 << 2)
 };
 
+enum evdev_device_tags {
+       EVDEV_TAG_EXTERNAL_MOUSE = (1 << 0),
+       EVDEV_TAG_INTERNAL_TOUCHPAD = (1 << 1),
+};
+
 struct mt_slot {
        int32_t seat_slot;
        int32_t x, y;
@@ -92,6 +97,7 @@ struct evdev_device {
 
        enum evdev_event_type pending_event;
        enum evdev_device_seat_capability seat_caps;
+       enum evdev_device_tags tags;
 
        int is_mt;
 
@@ -128,6 +134,10 @@ struct evdev_dispatch_interface {
        /* A device was removed */
        void (*device_removed)(struct evdev_device *device,
                               struct evdev_device *removed_device);
+
+       /* Tag device with one of EVDEV_TAG */
+       void (*tag_device)(struct evdev_device *device,
+                          struct udev_device *udev_device);
 };
 
 struct evdev_dispatch {