[gnome-control-center/wip/carlosg/common-cleanup: 2/4] common: Unite GsdDeviceManager



commit a9b873f12591b24149d985f0716d6fa3c6ada7ac
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Jul 27 00:17:37 2019 +0200

    common: Unite GsdDeviceManager
    
    Drop the subtypes, and keep a single udev-based GsdDeviceManager,
    which will work on both backends, and should work on all platforms
    we care about (?).

 meson.build                             |  13 +-
 panels/common/gsd-device-manager-udev.c | 256 --------------------------------
 panels/common/gsd-device-manager-udev.h |  31 ----
 panels/common/gsd-device-manager-x11.c  | 215 ---------------------------
 panels/common/gsd-device-manager-x11.h  |  32 ----
 panels/common/gsd-device-manager.c      | 252 +++++++++++++++++++++++++++++--
 panels/common/meson.build               |  13 +-
 7 files changed, 241 insertions(+), 571 deletions(-)
---
diff --git a/meson.build b/meson.build
index 95f9b25ba..a6729bb62 100644
--- a/meson.build
+++ b/meson.build
@@ -129,6 +129,7 @@ polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.103')
 pulse_dep = dependency('libpulse', version: pulse_req_version)
 pulse_mainloop_dep = dependency('libpulse-mainloop-glib', version: pulse_req_version)
 upower_glib_dep = dependency('upower-glib', version: '>= 0.99.8')
+gudev_dep = dependency('gudev-1.0')
 x11_dep = dependency('x11')
 xi_dep = dependency('xi', version: '>= 1.2')
 
@@ -183,17 +184,6 @@ endif
 config_h.set('HAVE_IBUS', enable_ibus,
              description: 'Defined if IBus support is enabled')
 
-# wayland
-enable_wayland = get_option('wayland')
-if enable_wayland
-  wayland_deps = [
-    dependency('gdk-wayland-3.0'),
-    dependency('gudev-1.0')
-  ]
-endif
-config_h.set('HAVE_WAYLAND', enable_wayland,
-             description: 'Define to 1 if Wayland is enabled')
-
 # thunderbolt
 config_h.set10('HAVE_FN_EXPLICIT_BZERO',
                cc.has_function('explicit_bzero', prefix: '''#include <string.h>'''),
@@ -293,6 +283,5 @@ output += '     Cheese (Users panel webcam support) ........ ' + enable_cheese.t
 output += '     IBus (Region panel IBus support) ........... ' + enable_ibus.to_string() + '\n'
 output += '     NetworkManager (Network panel) ............. ' + host_is_linux.to_string() + '\n'
 output += '     Wacom (Wacom tablet panel) ................. ' + host_is_linux_not_s390.to_string() + '\n'
-output += '     Wayland .................................... ' + enable_wayland.to_string() + '\n'
 
 message(output)
diff --git a/panels/common/gsd-device-manager.c b/panels/common/gsd-device-manager.c
index 8ea56c064..07f0d4fd8 100644
--- a/panels/common/gsd-device-manager.c
+++ b/panels/common/gsd-device-manager.c
@@ -22,11 +22,19 @@
 #include "config.h"
 
 #include <string.h>
+#include <gudev/gudev.h>
 
-#include "gsd-device-manager-x11.h"
-#include "gsd-device-manager-udev.h"
+#include "gsd-device-manager.h"
 #include "gsd-common-enums.h"
 #include "gnome-settings-bus.h"
+#include "gsd-input-helper.h"
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+#ifdef GDK_WINDOWING_WAYLAND
+#include <gdk/gdkwayland.h>
+#endif
 
 typedef struct
 {
@@ -41,6 +49,13 @@ typedef struct
 
 G_DEFINE_TYPE_WITH_PRIVATE (GsdDevice, gsd_device, G_TYPE_OBJECT)
 
+typedef struct
+{
+        GObject parent_instance;
+       GHashTable *devices;
+       GUdevClient *udev_client;
+} GsdDeviceManagerPrivate;
+
 enum {
        PROP_NAME = 1,
        PROP_DEVICE_FILE,
@@ -58,9 +73,19 @@ enum {
        N_SIGNALS
 };
 
+/* Index matches GsdDeviceType */
+const gchar *udev_ids[] = {
+       "ID_INPUT_MOUSE",
+       "ID_INPUT_KEYBOARD",
+       "ID_INPUT_TOUCHPAD",
+       "ID_INPUT_TABLET",
+       "ID_INPUT_TOUCHSCREEN",
+       "ID_INPUT_TABLET_PAD",
+};
+
 static guint signals[N_SIGNALS] = { 0 };
 
-G_DEFINE_TYPE (GsdDeviceManager, gsd_device_manager, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (GsdDeviceManager, gsd_device_manager, G_TYPE_OBJECT)
 
 static void
 gsd_device_init (GsdDevice *device)
@@ -225,9 +250,83 @@ gsd_device_class_init (GsdDeviceClass *klass)
                                                            G_PARAM_CONSTRUCT_ONLY));
 }
 
+static void
+gsd_device_manager_finalize (GObject *object)
+{
+       GsdDeviceManager *manager = GSD_DEVICE_MANAGER (object);
+        GsdDeviceManagerPrivate *priv = gsd_device_manager_get_instance_private (manager);
+
+       g_hash_table_destroy (priv->devices);
+       g_object_unref (priv->udev_client);
+
+       G_OBJECT_CLASS (gsd_device_manager_parent_class)->finalize (object);
+}
+
+static GList *
+gsd_device_manager_real_list_devices (GsdDeviceManager *manager,
+                                     GsdDeviceType     type)
+{
+        GsdDeviceManagerPrivate *priv = gsd_device_manager_get_instance_private (manager);
+       GsdDeviceType device_type;
+       GList *devices = NULL;
+       GHashTableIter iter;
+       GsdDevice *device;
+
+       g_hash_table_iter_init (&iter, priv->devices);
+
+       while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &device)) {
+               device_type = gsd_device_get_device_type (device);
+
+               if ((device_type & type) == type)
+                       devices = g_list_prepend (devices, device);
+       }
+
+       return devices;
+}
+
+static GsdDevice *
+gsd_device_manager_real_lookup_device (GsdDeviceManager *manager,
+                                       GdkDevice       *gdk_device)
+{
+       GsdDeviceManagerPrivate *priv = gsd_device_manager_get_instance_private (manager);
+       GdkDisplay *display = gdk_device_get_display (gdk_device);
+       const gchar *node_path = NULL;
+       GHashTableIter iter;
+       GsdDevice *device;
+
+#ifdef GDK_WINDOWING_X11
+       if (GDK_IS_X11_DISPLAY (display))
+               node_path = xdevice_get_device_node (gdk_x11_device_get_id (gdk_device));
+#endif
+#ifdef GDK_WINDOWING_WAYLAND
+       if (GDK_IS_WAYLAND_DISPLAY (display))
+               node_path = g_strdup (gdk_wayland_device_get_node_path (gdk_device));
+#endif
+       if (!node_path)
+               return NULL;
+
+       g_hash_table_iter_init (&iter, priv->devices);
+
+       while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &device)) {
+               if (g_strcmp0 (node_path,
+                              gsd_device_get_device_file (device)) == 0) {
+                       return device;
+               }
+       }
+
+       return NULL;
+}
+
 static void
 gsd_device_manager_class_init (GsdDeviceManagerClass *klass)
 {
+       GsdDeviceManagerClass *manager_class = GSD_DEVICE_MANAGER_CLASS (klass);
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->finalize = gsd_device_manager_finalize;
+       manager_class->list_devices = gsd_device_manager_real_list_devices;
+       manager_class->lookup_device = gsd_device_manager_real_lookup_device;
+
        signals[DEVICE_ADDED] =
                g_signal_new ("device-added",
                              GSD_TYPE_DEVICE_MANAGER,
@@ -256,9 +355,144 @@ gsd_device_manager_class_init (GsdDeviceManagerClass *klass)
                              GSD_TYPE_DEVICE | G_SIGNAL_TYPE_STATIC_SCOPE);
 }
 
+static GsdDeviceType
+udev_device_get_device_type (GUdevDevice *device)
+{
+       GsdDeviceType type = 0;
+       gint i;
+
+       for (i = 0; i < G_N_ELEMENTS (udev_ids); i++) {
+               if (g_udev_device_get_property_as_boolean (device, udev_ids[i]))
+                       type |= (1 << i);
+       }
+
+       return type;
+}
+
+static gboolean
+device_is_evdev (GUdevDevice *device)
+{
+       const gchar *device_file;
+
+       device_file = g_udev_device_get_device_file (device);
+
+       if (!device_file || strstr (device_file, "/event") == NULL)
+               return FALSE;
+
+       return g_udev_device_get_property_as_boolean (device, "ID_INPUT");
+}
+
+static GsdDevice *
+create_device (GUdevDevice *udev_device)
+{
+       const gchar *vendor, *product, *name;
+       guint width, height;
+       g_autoptr(GUdevDevice) parent = NULL;
+
+       parent = g_udev_device_get_parent (udev_device);
+       g_assert (parent != NULL);
+
+       name = g_udev_device_get_sysfs_attr (parent, "name");
+       vendor = g_udev_device_get_property (udev_device, "ID_VENDOR_ID");
+       product = g_udev_device_get_property (udev_device, "ID_MODEL_ID");
+
+       if (!vendor || !product) {
+               vendor = g_udev_device_get_sysfs_attr (udev_device, "device/id/vendor");
+               product = g_udev_device_get_sysfs_attr (udev_device, "device/id/product");
+       }
+
+       width = g_udev_device_get_property_as_int (udev_device, "ID_INPUT_WIDTH_MM");
+       height = g_udev_device_get_property_as_int (udev_device, "ID_INPUT_HEIGHT_MM");
+
+       return g_object_new (GSD_TYPE_DEVICE,
+                            "name", name,
+                            "device-file", g_udev_device_get_device_file (udev_device),
+                            "type", udev_device_get_device_type (udev_device),
+                            "vendor-id", vendor,
+                            "product-id", product,
+                            "width", width,
+                            "height", height,
+                            NULL);
+}
+
+static void
+add_device (GsdDeviceManager *manager,
+           GUdevDevice      *udev_device)
+{
+        GsdDeviceManagerPrivate *priv = gsd_device_manager_get_instance_private (manager);
+       GUdevDevice *parent;
+       GsdDevice *device;
+
+       parent = g_udev_device_get_parent (udev_device);
+
+       if (!parent)
+               return;
+
+       device = create_device (udev_device);
+       g_hash_table_insert (priv->devices, g_object_ref (udev_device), device);
+       g_signal_emit_by_name (manager, "device-added", device);
+}
+
+static void
+remove_device (GsdDeviceManager *manager,
+              GUdevDevice      *udev_device)
+{
+        GsdDeviceManagerPrivate *priv = gsd_device_manager_get_instance_private (manager);
+       GsdDevice *device;
+
+       device = g_hash_table_lookup (priv->devices, udev_device);
+
+       if (!device)
+               return;
+
+       g_hash_table_steal (priv->devices, udev_device);
+       g_signal_emit_by_name (manager, "device-removed", device);
+
+       g_object_unref (device);
+       g_object_unref (udev_device);
+}
+
+static void
+udev_event_cb (GUdevClient     *client,
+              gchar            *action,
+              GUdevDevice      *device,
+              GsdDeviceManager *manager)
+{
+       if (!device_is_evdev (device))
+               return;
+
+       if (g_strcmp0 (action, "add") == 0) {
+               add_device (manager, device);
+       } else if (g_strcmp0 (action, "remove") == 0) {
+               remove_device (manager, device);
+       }
+}
+
 static void
 gsd_device_manager_init (GsdDeviceManager *manager)
 {
+        GsdDeviceManagerPrivate *priv = gsd_device_manager_get_instance_private (manager);
+       const gchar *subsystems[] = { "input", NULL };
+       g_autoptr(GList) devices = NULL;
+       GList *l;
+
+       priv->devices = g_hash_table_new_full (NULL, NULL,
+                                               (GDestroyNotify) g_object_unref,
+                                               (GDestroyNotify) g_object_unref);
+
+       priv->udev_client = g_udev_client_new (subsystems);
+       g_signal_connect (priv->udev_client, "uevent",
+                         G_CALLBACK (udev_event_cb), manager);
+
+       devices = g_udev_client_query_by_subsystem (priv->udev_client,
+                                                   subsystems[0]);
+
+       for (l = devices; l; l = l->next) {
+               g_autoptr(GUdevDevice) device = l->data;
+
+               if (device_is_evdev (device))
+                       add_device (manager, device);
+       }
 }
 
 GsdDeviceManager *
@@ -273,16 +507,8 @@ gsd_device_manager_get (void)
        manager = g_object_get_data (G_OBJECT (screen), "gsd-device-manager-data");
 
        if (!manager) {
-#ifdef HAVE_WAYLAND
-               if (gnome_settings_is_wayland ()) {
-                       manager = g_object_new (GSD_TYPE_UDEV_DEVICE_MANAGER,
-                                               NULL);
-               } else
-#endif /* HAVE_WAYLAND */
-               {
-                       manager = g_object_new (GSD_TYPE_X11_DEVICE_MANAGER,
-                                               NULL);
-               }
+                manager = g_object_new (GSD_TYPE_DEVICE_MANAGER,
+                                        NULL);
 
                g_object_set_data_full (G_OBJECT (screen), "gsd-device-manager-data",
                                        manager, (GDestroyNotify) g_object_unref);
diff --git a/panels/common/meson.build b/panels/common/meson.build
index d35dbd1ac..c0705f9ba 100644
--- a/panels/common/meson.build
+++ b/panels/common/meson.build
@@ -76,28 +76,17 @@ liblanguage_dep = declare_dependency(
 
 gsd_headers = [
   'gsd-device-manager.h',
-  'gsd-device-manager-udev.h',
-  'gsd-device-manager-x11.h',
   'gsd-input-helper.h'
 ]
 
-gsd_sources_udev = ['gsd-device-manager-udev.c']
-
 gsd_sources = [
   'gsd-device-manager.c',
-  'gsd-device-manager-x11.c',
   'gsd-input-helper.c'
 ]
 
 sources = common_sources + files(gsd_sources)
 
-deps = common_deps
-
-if enable_wayland
-  sources += files(gsd_sources_udev)
-
-  deps += wayland_deps
-endif
+deps = common_deps + [ gudev_dep ]
 
 libdevice = static_library(
   'device',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]