From 1f3e9176fcaffeb70bc38fb90cf3906e443ea733 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 4 Oct 2018 14:27:45 +1000 Subject: [PATCH] clutter/x11: detect tablet type from the Wacom property The xf86-input-wacom driver exports a property with the tool type as known by the driver. This is a more reliable choice than guessing based on the device name. In the touchscreen case, we simply use is_touch_device() to guess which one of the two options it is. Note that this code should never be hit anyway as we would've succeeded earlier with a previous is_touch_device() call. --- .../clutter/x11/clutter-device-manager-xi2.c | 99 ++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c index fb60cc8d9..915106803 100644 --- a/clutter/clutter/x11/clutter-device-manager-xi2.c +++ b/clutter/clutter/x11/clutter-device-manager-xi2.c @@ -67,6 +67,23 @@ static const char *clutter_input_axis_atom_names[] = { #define N_AXIS_ATOMS G_N_ELEMENTS (clutter_input_axis_atom_names) +static const char *wacom_type_atoms[] = { + "STYLUS", + "CURSOR", + "ERASER", + "PAD", + "TOUCH" +}; +#define N_WACOM_TYPE_ATOMS G_N_ELEMENTS (wacom_type_atoms) + +enum { + WACOM_TYPE_STYLUS, + WACOM_TYPE_CURSOR, + WACOM_TYPE_ERASER, + WACOM_TYPE_PAD, + WACOM_TYPE_TOUCH, +}; + enum { PAD_AXIS_FIRST = 3, /* First axes are always x/y/pressure, ignored in pads */ PAD_AXIS_STRIP1 = PAD_AXIS_FIRST, @@ -394,6 +411,86 @@ get_pad_features (XIDeviceInfo *info, *n_strips = strips; } +/* The Wacom driver exports the tool type as property. Use that over + guessing based on the device name */ +static gboolean +guess_source_from_wacom_type (ClutterBackendX11 *backend_x11, + XIDeviceInfo *info, + ClutterInputDeviceType *source_out) +{ + gulong nitems, bytes_after; + guint32 *data = NULL; + int rc, format; + Atom type; + Atom prop; + Atom device_type; + Atom types[N_WACOM_TYPE_ATOMS]; + + prop = XInternAtom (backend_x11->xdpy, "Wacom Tool Type", True); + if (prop == None) + return FALSE; + + clutter_x11_trap_x_errors (); + rc = XIGetProperty (backend_x11->xdpy, + info->deviceid, + prop, + 0, 1, False, XA_ATOM, &type, &format, &nitems, &bytes_after, + (guchar **) &data); + clutter_x11_untrap_x_errors (); + + + if (rc != Success || type != XA_ATOM || format != 32 || nitems != 1) + { + XFree (data); + return FALSE; + } + + device_type = *data; + XFree (data); + + if (device_type == 0) + return FALSE; + + rc = XInternAtoms (backend_x11->xdpy, + (char **)wacom_type_atoms, + N_WACOM_TYPE_ATOMS, + False, + types); + if (rc == 0) + return FALSE; + + if (device_type == types[WACOM_TYPE_STYLUS]) + { + *source_out = CLUTTER_PEN_DEVICE; + } + else if (device_type == types[WACOM_TYPE_CURSOR]) + { + *source_out = CLUTTER_CURSOR_DEVICE; + } + else if (device_type == types[WACOM_TYPE_ERASER]) + { + *source_out = CLUTTER_ERASER_DEVICE; + } + else if (device_type == types[WACOM_TYPE_PAD]) + { + *source_out = CLUTTER_PAD_DEVICE; + } + else if (device_type == types[WACOM_TYPE_TOUCH]) + { + guint num_touches = 0; + + if (!is_touch_device (info->classes, info->num_classes, + source_out, &num_touches)) + *source_out = CLUTTER_TOUCHSCREEN_DEVICE; + } + else + { + return FALSE; + } + + return TRUE; +} + static ClutterInputDevice * create_device (ClutterDeviceManagerXI2 *manager_xi2, ClutterBackendX11 *backend_x11, @@ -421,7 +518,7 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2, { source = touch_source; } - else + else if (!guess_source_from_wacom_type (backend_x11, info, &source)) { gchar *name;