diff --git a/src/backends/native/meta-kms-connector.c b/src/backends/native/meta-kms-connector.c index 70d3336d3e28845555e0b89c4961714d1f069ef0..8eed112295ee84b8b8c3e73a73af433d7faeb57b 100644 --- a/src/backends/native/meta-kms-connector.c +++ b/src/backends/native/meta-kms-connector.c @@ -456,7 +456,7 @@ meta_kms_connector_read_state (MetaKmsConnector *connector, g_clear_pointer (&connector->current_state, meta_kms_connector_state_free); - if (drm_connector->connection != DRM_MODE_CONNECTED) + if (!drm_connector || drm_connector->connection != DRM_MODE_CONNECTED) return; state = meta_kms_connector_state_new (); @@ -490,6 +490,8 @@ meta_kms_connector_update_state (MetaKmsConnector *connector, meta_kms_connector_read_state (connector, impl_device, drm_connector, drm_resources); + if (drm_connector) + drmModeFreeConnector (drm_connector); } static void diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c index 2dd2b8da4c25804ba7338568134adb542ff259b4..2b0f5385a7a7302bb6b97df5af319349360e5588 100644 --- a/src/backends/native/meta-kms-crtc.c +++ b/src/backends/native/meta-kms-crtc.c @@ -110,17 +110,16 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc, MetaKmsImplDevice *impl_device, drmModeCrtc *drm_crtc) { - crtc->current_state = (MetaKmsCrtcState) { - .rect = { - .x = drm_crtc->x, - .y = drm_crtc->y, - .width = drm_crtc->width, - .height = drm_crtc->height, - }, - .is_drm_mode_valid = drm_crtc->mode_valid, - .drm_mode = drm_crtc->mode, + crtc->current_state.rect = (MetaRectangle) { + .x = drm_crtc->x, + .y = drm_crtc->y, + .width = drm_crtc->width, + .height = drm_crtc->height, }; + crtc->current_state.is_drm_mode_valid = drm_crtc->mode_valid; + crtc->current_state.drm_mode = drm_crtc->mode; + read_gamma_state (crtc, impl_device, drm_crtc); } @@ -133,6 +132,13 @@ meta_kms_crtc_update_state (MetaKmsCrtc *crtc) impl_device = meta_kms_device_get_impl_device (crtc->device); drm_crtc = drmModeGetCrtc (meta_kms_impl_device_get_fd (impl_device), crtc->id); + if (!drm_crtc) + { + crtc->current_state.rect = (MetaRectangle) { }; + crtc->current_state.is_drm_mode_valid = FALSE; + return; + } + meta_kms_crtc_read_state (crtc, impl_device, drm_crtc); drmModeFreeCrtc (drm_crtc); } diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h index 39a89a7518e988d0fccc1f52ecb3dcc8dcfab185..fa9938199227a5b77b9901d67247aa4357a6d0e7 100644 --- a/src/backends/native/meta-kms-crtc.h +++ b/src/backends/native/meta-kms-crtc.h @@ -33,10 +33,6 @@ typedef struct _MetaKmsCrtcState gboolean is_drm_mode_valid; drmModeModeInfo drm_mode; - uint32_t common_possible_crtcs; - uint32_t common_possible_clones; - uint32_t encoder_device_idxs; - struct { uint16_t *red; uint16_t *green; diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index 09114ea1782c9accd369096784b9677fb5ef3cdc..c46d746462a5898e187a3b34b442b1ba2f4ab8e5 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -209,6 +209,9 @@ init_connectors (MetaKmsImplDevice *impl_device, drm_connector = drmModeGetConnector (impl_device->fd, drm_resources->connectors[i]); + if (!drm_connector) + continue; + connector = meta_kms_connector_new (impl_device, drm_connector, drm_resources); drmModeFreeConnector (drm_connector); diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index 641aaa19826ab003d8cbc0a544247fc4ad5264e5..13dc396d33aeba46f043475ac7f107bb74c372bf 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -149,6 +149,7 @@ struct _MetaKms MetaBackend *backend; guint hotplug_handler_id; + guint removed_handler_id; MetaKmsImpl *impl; gboolean in_impl_task; @@ -474,8 +475,7 @@ meta_kms_update_states_sync (MetaKms *kms, } static void -on_udev_hotplug (MetaUdev *udev, - MetaKms *kms) +handle_hotplug_event (MetaKms *kms) { g_autoptr (GError) error = NULL; @@ -483,6 +483,21 @@ on_udev_hotplug (MetaUdev *udev, g_warning ("Updating KMS state failed: %s", error->message); } +static void +on_udev_hotplug (MetaUdev *udev, + MetaKms *kms) +{ + handle_hotplug_event (kms); +} + +static void +on_udev_device_removed (MetaUdev *udev, + GUdevDevice *device, + MetaKms *kms) +{ + handle_hotplug_event (kms); +} + MetaBackend * meta_kms_get_backend (MetaKms *kms) { @@ -525,6 +540,9 @@ meta_kms_new (MetaBackend *backend, kms->hotplug_handler_id = g_signal_connect (udev, "hotplug", G_CALLBACK (on_udev_hotplug), kms); + kms->removed_handler_id = + g_signal_connect (udev, "device-removed", + G_CALLBACK (on_udev_device_removed), kms); return kms; } @@ -548,6 +566,9 @@ meta_kms_finalize (GObject *object) if (kms->hotplug_handler_id) g_signal_handler_disconnect (udev, kms->hotplug_handler_id); + if (kms->removed_handler_id) + g_signal_handler_disconnect (udev, kms->removed_handler_id); + G_OBJECT_CLASS (meta_kms_parent_class)->finalize (object); } diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index 9bac13576423b09ca208cba8b3785b7fd5f2dfc0..26c2ddb61e25cf4a19bf27b9d9b027cb1f6ec2bc 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -76,6 +76,7 @@ struct _MetaMonitorManagerKms MetaMonitorManager parent_instance; guint hotplug_handler_id; + guint removed_handler_id; }; struct _MetaMonitorManagerKmsClass @@ -484,6 +485,14 @@ on_udev_hotplug (MetaUdev *udev, handle_hotplug_event (manager); } +static void +on_udev_device_removed (MetaUdev *udev, + GUdevDevice *device, + MetaMonitorManager *manager) +{ + handle_hotplug_event (manager); +} + static void meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager_kms) { @@ -494,6 +503,9 @@ meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager manager_kms->hotplug_handler_id = g_signal_connect_after (udev, "hotplug", G_CALLBACK (on_udev_hotplug), manager); + manager_kms->removed_handler_id = + g_signal_connect_after (udev, "device-removed", + G_CALLBACK (on_udev_device_removed), manager); } static void @@ -505,6 +517,8 @@ meta_monitor_manager_kms_disconnect_hotplug_handler (MetaMonitorManagerKms *mana g_signal_handler_disconnect (udev, manager_kms->hotplug_handler_id); manager_kms->hotplug_handler_id = 0; + g_signal_handler_disconnect (udev, manager_kms->removed_handler_id); + manager_kms->removed_handler_id = 0; } void diff --git a/src/backends/native/meta-udev.c b/src/backends/native/meta-udev.c index ee7cc3ad482295ae397950d8e8ca8e4c8ebe3b7a..7c8080a56e4d46dfa61a8e52c005105561f32415 100644 --- a/src/backends/native/meta-udev.c +++ b/src/backends/native/meta-udev.c @@ -31,6 +31,7 @@ enum { HOTPLUG, DEVICE_ADDED, + DEVICE_REMOVED, N_SIGNALS }; @@ -163,6 +164,8 @@ on_uevent (GUdevClient *client, if (g_str_equal (action, "add")) g_signal_emit (udev, signals[DEVICE_ADDED], 0, device); + else if (g_str_equal (action, "remove")) + g_signal_emit (udev, signals[DEVICE_REMOVED], 0, device); if (g_udev_device_get_property_as_boolean (device, "HOTPLUG")) g_signal_emit (udev, signals[HOTPLUG], 0); @@ -212,15 +215,20 @@ meta_udev_class_init (MetaUdevClass *klass) g_signal_new ("hotplug", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); 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, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_UDEV_TYPE_DEVICE); + signals[DEVICE_REMOVED] = + g_signal_new ("device-removed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_UDEV_TYPE_DEVICE); }