summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2022-09-06 09:48:09 +0200
committerMarge Bot <marge-bot@gnome.org>2022-11-09 10:46:55 +0000
commit5471b866b3c6aa627aae78de95f20ac635183a10 (patch)
tree7fdf6dd20803a40a36ca2609ad6cb6b65ea52d03 /src
parentd274d4359fcc1d689932082eba0f5d419578b402 (diff)
downloadmutter-5471b866b3c6aa627aae78de95f20ac635183a10.tar.gz
backends/x11: Set trackball/trackpoint capabilities
Use gudev to detect these capabilities in input devices. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2617>
Diffstat (limited to 'src')
-rw-r--r--src/backends/x11/meta-seat-x11.c133
1 files changed, 114 insertions, 19 deletions
diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c
index e972c80c6..e99a4a871 100644
--- a/src/backends/x11/meta-seat-x11.c
+++ b/src/backends/x11/meta-seat-x11.c
@@ -22,6 +22,10 @@
#include <X11/extensions/XInput2.h>
#include <X11/extensions/XKB.h>
+#ifdef HAVE_LIBGUDEV
+#include <gudev/gudev.h>
+#endif
+
#include "backends/meta-input-settings-private.h"
#include "backends/x11/meta-backend-x11.h"
#include "backends/x11/meta-clutter-backend-x11.h"
@@ -72,6 +76,10 @@ struct _MetaSeatX11
GHashTable *touch_coords;
MetaKeymapX11 *keymap;
+#ifdef HAVE_LIBGUDEV
+ GUdevClient *udev_client;
+#endif
+
int pointer_id;
int keyboard_id;
int opcode;
@@ -234,10 +242,11 @@ translate_device_classes (Display *xdisplay,
}
static gboolean
-is_touch_device (XIAnyClassInfo **classes,
- int n_classes,
- ClutterInputDeviceType *device_type,
- uint32_t *n_touch_points)
+is_touch_device (XIAnyClassInfo **classes,
+ int n_classes,
+ ClutterInputDeviceType *device_type,
+ ClutterInputCapabilities *capabilities,
+ uint32_t *n_touch_points)
{
int i;
@@ -251,11 +260,21 @@ is_touch_device (XIAnyClassInfo **classes,
if (class->num_touches > 0)
{
if (class->mode == XIDirectTouch)
- *device_type = CLUTTER_TOUCHSCREEN_DEVICE;
+ {
+ *device_type = CLUTTER_TOUCHSCREEN_DEVICE;
+ *capabilities = CLUTTER_INPUT_CAPABILITY_TOUCH;
+ }
else if (class->mode == XIDependentTouch)
- *device_type = CLUTTER_TOUCHPAD_DEVICE;
+ {
+ *device_type = CLUTTER_TOUCHPAD_DEVICE;
+ *capabilities =
+ CLUTTER_INPUT_CAPABILITY_POINTER |
+ CLUTTER_INPUT_CAPABILITY_TOUCHPAD;
+ }
else
- continue;
+ {
+ continue;
+ }
*n_touch_points = class->num_touches;
@@ -405,9 +424,10 @@ get_pad_features (XIDeviceInfo *info,
/* 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 (MetaSeatX11 *seat_x11,
- XIDeviceInfo *info,
- ClutterInputDeviceType *source_out)
+guess_source_from_wacom_type (MetaSeatX11 *seat_x11,
+ XIDeviceInfo *info,
+ ClutterInputDeviceType *source_out,
+ ClutterInputCapabilities *capabilities_out)
{
Display *xdisplay = xdisplay_from_seat (seat_x11);
gulong nitems, bytes_after;
@@ -453,26 +473,33 @@ guess_source_from_wacom_type (MetaSeatX11 *seat_x11,
if (device_type == types[WACOM_TYPE_STYLUS])
{
*source_out = CLUTTER_PEN_DEVICE;
+ *capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
}
else if (device_type == types[WACOM_TYPE_CURSOR])
{
*source_out = CLUTTER_CURSOR_DEVICE;
+ *capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
}
else if (device_type == types[WACOM_TYPE_ERASER])
{
*source_out = CLUTTER_ERASER_DEVICE;
+ *capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
}
else if (device_type == types[WACOM_TYPE_PAD])
{
*source_out = CLUTTER_PAD_DEVICE;
+ *capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_PAD;
}
else if (device_type == types[WACOM_TYPE_TOUCH])
{
uint32_t num_touches = 0;
if (!is_touch_device (info->classes, info->num_classes,
- source_out, &num_touches))
+ source_out, capabilities_out, &num_touches))
+ {
*source_out = CLUTTER_TOUCHSCREEN_DEVICE;
+ *capabilities_out = CLUTTER_INPUT_CAPABILITY_TOUCH;
+ }
}
else
{
@@ -482,6 +509,25 @@ guess_source_from_wacom_type (MetaSeatX11 *seat_x11,
return TRUE;
}
+#ifdef HAVE_LIBGUDEV
+static gboolean
+has_udev_property (GUdevDevice *udev_device,
+ const char *property_name)
+{
+ g_autoptr (GUdevDevice) parent_udev_device = NULL;
+
+ if (NULL != g_udev_device_get_property (udev_device, property_name))
+ return TRUE;
+
+ parent_udev_device = g_udev_device_get_parent (udev_device);
+
+ if (!parent_udev_device)
+ return FALSE;
+
+ return g_udev_device_get_property (parent_udev_device, property_name) != NULL;
+}
+#endif
+
static ClutterInputDevice *
create_device (MetaSeatX11 *seat_x11,
ClutterBackend *clutter_backend,
@@ -489,6 +535,7 @@ create_device (MetaSeatX11 *seat_x11,
{
Display *xdisplay = xdisplay_from_seat (seat_x11);
ClutterInputDeviceType source, touch_source;
+ ClutterInputCapabilities capabilities = 0;
ClutterInputDevice *retval;
ClutterInputMode mode;
uint32_t num_touches = 0, num_rings = 0, num_strips = 0;
@@ -497,6 +544,7 @@ create_device (MetaSeatX11 *seat_x11,
if (info->use == XIMasterKeyboard || info->use == XISlaveKeyboard)
{
source = CLUTTER_KEYBOARD_DEVICE;
+ capabilities = CLUTTER_INPUT_CAPABILITY_KEYBOARD;
}
else if (is_touchpad_device (seat_x11, info))
{
@@ -504,29 +552,49 @@ create_device (MetaSeatX11 *seat_x11,
}
else if (info->use == XISlavePointer &&
is_touch_device (info->classes, info->num_classes,
- &touch_source,
+ &touch_source, &capabilities,
&num_touches))
{
source = touch_source;
}
- else if (!guess_source_from_wacom_type (seat_x11, info, &source))
+ else if (!guess_source_from_wacom_type (seat_x11, info, &source, &capabilities))
{
char *name;
name = g_ascii_strdown (info->name, -1);
if (strstr (name, "eraser") != NULL)
- source = CLUTTER_ERASER_DEVICE;
+ {
+ source = CLUTTER_ERASER_DEVICE;
+ capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
+ }
else if (strstr (name, "cursor") != NULL)
- source = CLUTTER_CURSOR_DEVICE;
+ {
+ source = CLUTTER_CURSOR_DEVICE;
+ capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
+ }
else if (strstr (name, " pad") != NULL)
- source = CLUTTER_PAD_DEVICE;
+ {
+ source = CLUTTER_PAD_DEVICE;
+ capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_PAD;
+ }
else if (strstr (name, "wacom") != NULL || strstr (name, "pen") != NULL)
- source = CLUTTER_PEN_DEVICE;
+ {
+ source = CLUTTER_PEN_DEVICE;
+ capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
+ }
else if (strstr (name, "touchpad") != NULL)
- source = CLUTTER_TOUCHPAD_DEVICE;
+ {
+ source = CLUTTER_TOUCHPAD_DEVICE;
+ capabilities =
+ CLUTTER_INPUT_CAPABILITY_POINTER |
+ CLUTTER_INPUT_CAPABILITY_TOUCHPAD;
+ }
else
- source = CLUTTER_POINTER_DEVICE;
+ {
+ source = CLUTTER_POINTER_DEVICE;
+ capabilities = CLUTTER_INPUT_CAPABILITY_POINTER;
+ }
g_free (name);
}
@@ -556,6 +624,23 @@ create_device (MetaSeatX11 *seat_x11,
node_path = get_device_node_path (seat_x11, info);
}
+#ifdef HAVE_LIBGUDEV
+ if (node_path)
+ {
+ g_autoptr (GUdevDevice) udev_device = NULL;
+
+ udev_device = g_udev_client_query_by_device_file (seat_x11->udev_client,
+ node_path);
+ if (udev_device)
+ {
+ if (has_udev_property (udev_device, "ID_INPUT_TRACKBALL"))
+ capabilities |= CLUTTER_INPUT_CAPABILITY_TRACKBALL;
+ if (has_udev_property (udev_device, "ID_INPUT_POINTINGSTICK"))
+ capabilities |= CLUTTER_INPUT_CAPABILITY_TRACKPOINT;
+ }
+ }
+#endif
+
if (source == CLUTTER_PAD_DEVICE)
get_pad_features (info, &num_rings, &num_strips);
@@ -564,6 +649,7 @@ create_device (MetaSeatX11 *seat_x11,
"id", info->deviceid,
"has-cursor", (info->use == XIMasterPointer),
"device-type", source,
+ "capabilities", capabilities,
"device-mode", mode,
"backend", clutter_backend,
"vendor-id", vendor_id,
@@ -1410,6 +1496,11 @@ meta_seat_x11_constructed (GObject *object)
XIEventMask event_mask;
unsigned char mask[XIMaskLen(XI_LASTEVENT)] = { 0, };
int n_devices, i;
+#ifdef HAVE_LIBGUDEV
+ const char *udev_subsystems[] = { "input", NULL };
+
+ seat_x11->udev_client = g_udev_client_new (udev_subsystems);
+#endif
info = XIQueryDevice (xdisplay, XIAllDevices, &n_devices);
@@ -1475,6 +1566,10 @@ meta_seat_x11_finalize (GObject *object)
{
MetaSeatX11 *seat_x11 = META_SEAT_X11 (object);
+#ifdef HAVE_LIBGUDEV
+ g_clear_object (&seat_x11->udev_client);
+#endif
+
g_hash_table_unref (seat_x11->devices_by_id);
g_hash_table_unref (seat_x11->tools_by_serial);
g_hash_table_unref (seat_x11->touch_coords);