[mutter/wip/wayland-work: 41/42] MonitorKms: add hotplug support
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/wayland-work: 41/42] MonitorKms: add hotplug support
- Date: Thu, 26 Sep 2013 08:50:07 +0000 (UTC)
commit b86471458a34e55397c9293d9cddf5054cc175d0
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Sat Sep 14 17:55:18 2013 +0200
MonitorKms: add hotplug support
Use GUdev to listen to the kernel events which are emitted when
monitors are hotplugged and hotunplugged.
https://bugzilla.gnome.org/show_bug.cgi?id=706308
configure.ac | 1 +
src/core/monitor-kms.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4829295..f74bf10 100644
--- a/configure.ac
+++ b/configure.ac
@@ -81,6 +81,7 @@ MUTTER_PC_MODULES="
cogl-1.0 >= 1.13.3
upower-glib > 0.9.11
gnome-desktop-3.0
+ gudev-1.0
"
GLIB_GSETTINGS
diff --git a/src/core/monitor-kms.c b/src/core/monitor-kms.c
index 9a1cb50..e7197fa 100644
--- a/src/core/monitor-kms.c
+++ b/src/core/monitor-kms.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <stdlib.h>
#include <clutter/clutter.h>
+#include <gudev/gudev.h>
#include <errno.h>
#include <sys/ioctl.h>
@@ -61,6 +62,7 @@ struct _MetaMonitorManagerKms
MetaMonitorManager parent_instance;
int fd;
+ GUdevClient *udev;
drmModeConnector **connectors;
unsigned int n_connectors;
@@ -896,12 +898,60 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
}
static void
+on_uevent (GUdevClient *client,
+ const char *action,
+ GUdevDevice *device,
+ MetaMonitorManager *manager)
+{
+ MetaOutput *old_outputs;
+ MetaCRTC *old_crtcs;
+ MetaMonitorMode *old_modes;
+ unsigned int n_old_outputs, n_old_modes;
+
+ /* This is similar to MetaMonitorManagerXRandR->handle_xevent(), except
+ that we only get here for actual HW changes - reconfigurations
+ from other clients must go through our DBus API, and we don't
+ need to fiddle with timestamps.
+ */
+
+ /* Save the old structures, so they stay valid during the update */
+ old_outputs = manager->outputs;
+ n_old_outputs = manager->n_outputs;
+ old_modes = manager->modes;
+ n_old_modes = manager->n_modes;
+ old_crtcs = manager->crtcs;
+
+ manager->serial++;
+ meta_monitor_manager_kms_read_current (manager);
+
+ /* Check if an hotplug actually happened (maybe the uevent was for
+ something we don't care about, like a new card). If not,
+ just update our data structures (which should not be changed anyway)
+ and emit the signal. */
+ if (meta_monitor_config_match_current (manager->config, manager))
+ {
+ meta_monitor_config_update_current (manager->config, manager);
+ meta_monitor_manager_rebuild_derived (manager);
+ }
+ else
+ {
+ if (!meta_monitor_config_apply_stored (manager->config, manager))
+ meta_monitor_config_make_default (manager->config, manager);
+ }
+
+ meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
+ meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
+ g_free (old_crtcs);
+}
+
+static void
meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
{
ClutterBackend *backend;
CoglContext *cogl_context;
CoglDisplay *cogl_display;
CoglRenderer *cogl_renderer;
+ static const char *subsystems[] = { "drm/drm_minor", NULL };
backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (backend);
@@ -909,6 +959,10 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
cogl_renderer = cogl_display_get_renderer (cogl_display);
manager_kms->fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
+
+ manager_kms->udev = g_udev_client_new (subsystems);
+ g_signal_connect (manager_kms->udev, "uevent",
+ G_CALLBACK (on_uevent), manager_kms);
}
static void
@@ -917,6 +971,7 @@ meta_monitor_manager_kms_finalize (GObject *object)
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
free_resources (manager_kms);
+ g_clear_object (&manager_kms->udev);
G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]