[gnome-control-center/wip/carlosg/common-cleanup: 19/21] common: Unite GsdDeviceManager
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/carlosg/common-cleanup: 19/21] common: Unite GsdDeviceManager
- Date: Thu, 8 Aug 2019 15:18:27 +0000 (UTC)
commit 3600cb5a40db2128e8ec67a676f2d422ae665b38
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]