From 9843e21fffb183709cccc9289e2330e94e30c155 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 20 Mar 2019 23:18:30 +0100 Subject: [PATCH] backends: Use udev to determine absolute input devices' size Use the ID_INPUT_WIDTH_MM/ID_INPUT_HEIGHT_MM udev properties to figure out absolute input devices' physical size. This works across both backends, and requires less moving pieces to have it get the right results. Concretely, fixes size detection on X11/libinput, which makes touchscreen mapping go wrong. https://gitlab.gnome.org/GNOME/mutter/issues/514 --- src/backends/meta-input-mapper.c | 47 +++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/backends/meta-input-mapper.c b/src/backends/meta-input-mapper.c index 1a3cb2c7b..5227292dc 100644 --- a/src/backends/meta-input-mapper.c +++ b/src/backends/meta-input-mapper.c @@ -20,6 +20,10 @@ #include "config.h" +#ifdef HAVE_LIBGUDEV +#include +#endif + #include "meta-input-mapper-private.h" #include "meta-monitor-manager-private.h" #include "meta-logical-monitor.h" @@ -39,6 +43,9 @@ struct _MetaInputMapper ClutterDeviceManager *input_device_manager; GHashTable *input_devices; /* ClutterInputDevice -> MetaMapperInputInfo */ GHashTable *output_devices; /* MetaLogicalMonitor -> MetaMapperOutputInfo */ +#ifdef HAVE_LIBGUDEV + GUdevClient *udev_client; +#endif }; typedef enum @@ -270,6 +277,33 @@ match_edid (MetaMapperInputInfo *input, return TRUE; } +static gboolean +input_device_get_physical_size (MetaInputMapper *mapper, + ClutterInputDevice *device, + double *width, + double *height) +{ +#ifdef HAVE_LIBGUDEV + g_autoptr (GUdevDevice) udev_device = NULL; + const char *node; + + node = clutter_input_device_get_device_node (device); + udev_device = g_udev_client_query_by_device_file (mapper->udev_client, node); + + if (udev_device && + g_udev_device_has_property (udev_device, "ID_INPUT_WIDTH_MM")) + { + *width = g_udev_device_get_property_as_double (udev_device, + "ID_INPUT_WIDTH_MM"); + *height = g_udev_device_get_property_as_double (udev_device, + "ID_INPUT_HEIGHT_MM"); + return TRUE; + } +#endif + + return FALSE; +} + static gboolean find_size_match (MetaMapperInputInfo *input, GList *monitors, @@ -282,7 +316,8 @@ find_size_match (MetaMapperInputInfo *input, min_w_diff = min_h_diff = MAX_SIZE_MATCH_DIFF; - if (!clutter_input_device_get_physical_size (input->device, &i_width, &i_height)) + if (!input_device_get_physical_size (input->mapper, input->device, + &i_width, &i_height)) return FALSE; for (l = monitors; l; l = l->next) @@ -520,6 +555,9 @@ meta_input_mapper_finalize (GObject *object) g_hash_table_unref (mapper->input_devices); g_hash_table_unref (mapper->output_devices); +#ifdef HAVE_LIBGUDEV + g_clear_object (&mapper->udev_client); +#endif G_OBJECT_CLASS (meta_input_mapper_parent_class)->finalize (object); } @@ -527,11 +565,18 @@ meta_input_mapper_finalize (GObject *object) static void meta_input_mapper_constructed (GObject *object) { +#ifdef HAVE_LIBGUDEV + const char *udev_subsystems[] = { "input", NULL }; +#endif MetaInputMapper *mapper = META_INPUT_MAPPER (object); MetaBackend *backend; G_OBJECT_CLASS (meta_input_mapper_parent_class)->constructed (object); +#ifdef HAVE_LIBGUDEV + mapper->udev_client = g_udev_client_new (udev_subsystems); +#endif + mapper->input_device_manager = clutter_device_manager_get_default (); g_signal_connect (mapper->input_device_manager, "device-removed", G_CALLBACK (input_mapper_device_removed_cb), mapper);