diff --git a/configure.ac b/configure.ac index df4dce152..c1a48ce91 100644 --- a/configure.ac +++ b/configure.ac @@ -201,7 +201,7 @@ AC_SUBST(XWAYLAND_PATH) PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES) -PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [clutter-egl-1.0 libdrm libsystemd libinput], [have_native_backend=yes], [have_native_backend=no]) +PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [clutter-egl-1.0 libdrm libsystemd libinput gudev-1.0], [have_native_backend=yes], [have_native_backend=no]) if test $have_native_backend = yes; then AC_DEFINE([HAVE_NATIVE_BACKEND],[1],[Define if you want to enable the native (KMS) backend based on systemd]) fi diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index ad37df6a0..4ee2681c7 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -24,6 +24,7 @@ #include "config.h" #include "meta-monitor-manager-kms.h" +#include "meta-monitor-config.h" #include #include @@ -40,6 +41,8 @@ #include #include "edid.h" +#include + typedef struct { drmModeConnector *connector; @@ -68,6 +71,8 @@ struct _MetaMonitorManagerKms unsigned int n_encoders; drmModeEncoder *current_encoder; + + GUdevClient *udev; }; struct _MetaMonitorManagerKmsClass @@ -893,6 +898,29 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager, drmModeCrtcSetGamma (manager_kms->fd, crtc->crtc_id, size, red, green, blue); } +static void +on_uevent (GUdevClient *client, + const char *action, + GUdevDevice *device, + gpointer user_data) +{ + MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (user_data); + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms); + + if (!g_udev_device_get_property_as_boolean (device, "HOTPLUG")) + return; + + meta_monitor_manager_read_current_config (manager); + + /* If this config matches our existing one, don't bother doing anything. */ + if (meta_monitor_config_match_current (manager->config, manager)) + return; + + /* This is a hotplug event, so try to make a configuration for our new + * set of outputs. */ + meta_monitor_manager_on_hotplug (manager); +} + static void meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms) { @@ -907,6 +935,21 @@ 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); + + const char *subsystems[2] = { "drm", NULL }; + manager_kms->udev = g_udev_client_new (subsystems); + g_signal_connect (manager_kms->udev, "uevent", + G_CALLBACK (on_uevent), manager_kms); +} + +static void +meta_monitor_manager_kms_dispose (GObject *object) +{ + MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object); + + g_clear_object (&manager_kms->udev); + + G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->dispose (object); } static void @@ -925,6 +968,7 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass) MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->dispose = meta_monitor_manager_kms_dispose; object_class->finalize = meta_monitor_manager_kms_finalize; manager_class->read_current = meta_monitor_manager_kms_read_current;