From 73e8127d5d8ecc7dc7aa62fdc72dbf6b5d931f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 10 Jan 2019 11:30:02 +0100 Subject: [PATCH] backends/native: Add udev abstraction layer To be used to signal devices added, hotplugs and other udev events. Currently the only event emitted is when a device is added. https://gitlab.gnome.org/GNOME/mutter/issues/548 https://gitlab.gnome.org/GNOME/mutter/merge_requests/525 --- src/backends/native/meta-backend-native.c | 12 +++ src/backends/native/meta-backend-native.h | 3 + src/backends/native/meta-udev.c | 109 ++++++++++++++++++++++ src/backends/native/meta-udev.h | 33 +++++++ src/meson.build | 2 + 5 files changed, 159 insertions(+) create mode 100644 src/backends/native/meta-udev.c create mode 100644 src/backends/native/meta-udev.h diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index e4e9be225..50eb7bfc6 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -64,6 +64,7 @@ struct _MetaBackendNative MetaBackend parent; MetaLauncher *launcher; + MetaUdev *udev; MetaBarrierManagerNative *barrier_manager; }; @@ -81,6 +82,7 @@ meta_backend_native_finalize (GObject *object) { MetaBackendNative *native = META_BACKEND_NATIVE (object); + g_clear_object (&native->udev); meta_launcher_free (native->launcher); G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object); @@ -516,6 +518,8 @@ meta_backend_native_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { + MetaBackendNative *native = META_BACKEND_NATIVE (initable); + if (!meta_is_stage_views_enabled ()) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -523,6 +527,8 @@ meta_backend_native_initable_init (GInitable *initable, return FALSE; } + native->udev = meta_udev_new (); + return initable_parent_iface->init (initable, cancellable, error); } @@ -585,6 +591,12 @@ meta_backend_native_get_launcher (MetaBackendNative *native) return native->launcher; } +MetaUdev * +meta_backend_native_get_udev (MetaBackendNative *native) +{ + return native->udev; +} + gboolean meta_activate_vt (int vt, GError **error) { diff --git a/src/backends/native/meta-backend-native.h b/src/backends/native/meta-backend-native.h index d69fbe057..28b0856a3 100644 --- a/src/backends/native/meta-backend-native.h +++ b/src/backends/native/meta-backend-native.h @@ -28,6 +28,7 @@ #include "backends/meta-backend-private.h" #include "backends/native/meta-clutter-backend-native.h" #include "backends/native/meta-launcher.h" +#include "backends/native/meta-udev.h" #define META_TYPE_BACKEND_NATIVE (meta_backend_native_get_type ()) G_DECLARE_FINAL_TYPE (MetaBackendNative, meta_backend_native, @@ -41,4 +42,6 @@ void meta_backend_native_resume (MetaBackendNative *backend_native); MetaLauncher * meta_backend_native_get_launcher (MetaBackendNative *native); +MetaUdev * meta_backend_native_get_udev (MetaBackendNative *native); + #endif /* META_BACKEND_NATIVE_H */ diff --git a/src/backends/native/meta-udev.c b/src/backends/native/meta-udev.c new file mode 100644 index 000000000..e308e99d9 --- /dev/null +++ b/src/backends/native/meta-udev.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/native/meta-udev.h" + +enum +{ + DEVICE_ADDED, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +struct _MetaUdev +{ + GObject parent; + + GUdevClient *gudev_client; + + guint uevent_handler_id; +}; + +G_DEFINE_TYPE (MetaUdev, meta_udev, G_TYPE_OBJECT) + +static void +on_uevent (GUdevClient *client, + const char *action, + GUdevDevice *device, + gpointer user_data) +{ + MetaUdev *udev = META_UDEV (user_data); + + if (!g_udev_device_get_device_file (device)) + return; + + if (g_str_equal (action, "add")) + g_signal_emit (udev, signals[DEVICE_ADDED], 0, device); +} + +GUdevClient * +meta_udev_get_gudev_client (MetaUdev *udev) +{ + return udev->gudev_client; +} + +MetaUdev * +meta_udev_new (void) +{ + return g_object_new (META_TYPE_UDEV, NULL); +} + +static void +meta_udev_finalize (GObject *object) +{ + MetaUdev *udev = META_UDEV (object); + + g_signal_handler_disconnect (udev->gudev_client, udev->uevent_handler_id); + g_clear_object (&udev->gudev_client); + + G_OBJECT_CLASS (meta_udev_parent_class)->finalize (object); +} + +static void +meta_udev_init (MetaUdev *udev) +{ + const char *subsystems[] = { "drm", NULL }; + + udev->gudev_client = g_udev_client_new (subsystems); + udev->uevent_handler_id = g_signal_connect (udev->gudev_client, + "uevent", + G_CALLBACK (on_uevent), udev); +} + +static void +meta_udev_class_init (MetaUdevClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_udev_finalize; + + signals[DEVICE_ADDED] = + g_signal_new ("device-added", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 1, + G_UDEV_TYPE_DEVICE); +} diff --git a/src/backends/native/meta-udev.h b/src/backends/native/meta-udev.h new file mode 100644 index 000000000..c407997ed --- /dev/null +++ b/src/backends/native/meta-udev.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_UDEV_H +#define META_UDEV_H + +#include + +#define META_TYPE_UDEV (meta_udev_get_type ()) +G_DECLARE_FINAL_TYPE (MetaUdev, meta_udev, META, UDEV, GObject) + +GUdevClient * meta_udev_get_gudev_client (MetaUdev *udev); + +MetaUdev * meta_udev_new (void); + +#endif /* META_UDEV_H */ diff --git a/src/meson.build b/src/meson.build index 805b9a20e..4341d347f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -599,6 +599,8 @@ if have_native_backend 'backends/native/meta-renderer-native.h', 'backends/native/meta-stage-native.c', 'backends/native/meta-stage-native.h', + 'backends/native/meta-udev.c', + 'backends/native/meta-udev.h', ] endif