[PATCH libinput 2/2] udev: move the EKR into the parent's device group

Peter Hutterer peter.hutterer at who-t.net
Thu Aug 31 01:21:04 UTC 2017


If we find an EKR, search for the usb hub of the Cintiq, then find the Cintiq
Pen (or Touch) device and assume that device's product id. This way we end up
in the same device group as the Cintiq.

Co-authored-by: Jason Gerecke <jason.gerecke at wacom.com>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/libinput-util.h          |  1 +
 udev/libinput-device-group.c | 92 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 91 insertions(+), 2 deletions(-)

diff --git a/src/libinput-util.h b/src/libinput-util.h
index 139d6932..ab485c56 100644
--- a/src/libinput-util.h
+++ b/src/libinput-util.h
@@ -50,6 +50,7 @@
 #define PRODUCT_ID_APPLE_KBD_TOUCHPAD 0x273
 #define PRODUCT_ID_APPLE_APPLETOUCH 0x21a
 #define PRODUCT_ID_SYNAPTICS_SERIAL 0x007
+#define PRODUCT_ID_WACOM_EKR 0x0331
 
 /* The HW DPI rate we normalize to before calculating pointer acceleration */
 #define DEFAULT_MOUSE_DPI 1000
diff --git a/udev/libinput-device-group.c b/udev/libinput-device-group.c
index fa70e115..a9d69efd 100644
--- a/udev/libinput-device-group.c
+++ b/udev/libinput-device-group.c
@@ -64,6 +64,86 @@ out:
 }
 #endif
 
+static int
+find_tree_distance(struct udev_device *a, struct udev_device *b)
+{
+	struct udev_device *ancestor_a = a;
+	int dist_a = 0;
+
+	while (ancestor_a != NULL) {
+		const char *path_a = udev_device_get_syspath(ancestor_a);
+		struct udev_device *ancestor_b = b;
+		int dist_b = 0;
+
+		while (ancestor_b != NULL) {
+			const char *path_b = udev_device_get_syspath(ancestor_b);
+
+			if (streq(path_a, path_b))
+				return dist_a + dist_b;
+
+			dist_b++;
+			ancestor_b = udev_device_get_parent(ancestor_b);
+		}
+
+		dist_a++;
+		ancestor_a = udev_device_get_parent(ancestor_a);
+	}
+	return -1;
+}
+
+static void
+wacom_handle_ekr(struct udev_device *device,
+		 int *vendor_id,
+		 int *product_id)
+{
+	struct udev *udev;
+	struct udev_enumerate *e;
+	struct udev_list_entry *entry;
+	int best_dist = -1;
+
+	udev = udev_device_get_udev(device);
+	e = udev_enumerate_new(udev);
+	udev_enumerate_add_match_subsystem(e, "input");
+	udev_enumerate_add_match_sysname(e, "input*");
+	udev_enumerate_scan_devices(e);
+
+	udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
+		struct udev_device *d;
+		const char *path;
+		const char *pidstr, *vidstr;
+		int pid, vid, dist;
+
+		/* Find and use the closest Wacom device on the system,
+		 * relying on wacom_handle_paired() to fix our ID later
+		 * if needed.
+		 */
+		path = udev_list_entry_get_name(entry);
+		d = udev_device_new_from_syspath(udev, path);
+		if (!d)
+			continue;
+
+		vidstr = udev_device_get_property_value(d, "ID_VENDOR_ID");
+		pidstr = udev_device_get_property_value(d, "ID_MODEL_ID");
+
+		if (vidstr && pidstr &&
+		    safe_atoi_base(vidstr, &vid, 16) &&
+		    safe_atoi_base(pidstr, &pid, 16) &&
+		    vid == VENDOR_ID_WACOM &&
+		    pid != PRODUCT_ID_WACOM_EKR) {
+			dist = find_tree_distance(device, d);
+			if (dist > 0 && (dist < best_dist || best_dist < 0)) {
+				*vendor_id = vid;
+				*product_id = pid;
+				best_dist = dist;
+			}
+		}
+
+		udev_device_unref(d);
+	}
+
+	udev_enumerate_unref(e);
+}
+
 int main(int argc, char **argv)
 {
 	int rc = 1;
@@ -123,8 +203,16 @@ int main(int argc, char **argv)
 		snprintf(group, sizeof(group), "%s:%s", product, phys);
 	} else {
 #if HAVE_LIBWACOM_GET_PAIRED_DEVICE
-	    if (vendor_id == VENDOR_ID_WACOM)
-		    wacom_handle_paired(device, &vendor_id, &product_id);
+	    if (vendor_id == VENDOR_ID_WACOM) {
+		    if (product_id == PRODUCT_ID_WACOM_EKR)
+			    wacom_handle_ekr(device,
+					     &vendor_id,
+					     &product_id);
+		    /* This is called for the EKR as well */
+		    wacom_handle_paired(device,
+					&vendor_id,
+					&product_id);
+	    }
 #endif
 	    snprintf(group,
 		     sizeof(group),
-- 
2.13.5



More information about the wayland-devel mailing list