diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c index 160b8cb..f65d731 100644 --- a/src/libply-splash-core/ply-device-manager.c +++ b/src/libply-splash-core/ply-device-manager.c @@ -415,7 +415,7 @@ on_drm_udev_add_or_change (ply_device_manager_t *manager, } } -static bool +static void on_udev_event (ply_device_manager_t *manager) { struct udev_device *device; @@ -423,14 +423,14 @@ on_udev_event (ply_device_manager_t *manager) device = udev_monitor_receive_device (manager->udev_monitor); if (device == NULL) - return false; + return; action = udev_device_get_action (device); ply_trace ("got %s event for device %s", action, udev_device_get_sysname (device)); if (action == NULL) - return false; + return; if (strcmp (action, "add") == 0 || strcmp (action, "change") == 0) { const char *subsystem; @@ -450,14 +450,6 @@ on_udev_event (ply_device_manager_t *manager) } udev_device_unref (device); - return true; -} - -static void -on_udev_event_loop (ply_device_manager_t *manager) -{ - /* Call on_udev_event until all events are consumed */ - while (on_udev_event (manager)) {} } static void @@ -487,7 +479,7 @@ watch_for_udev_events (ply_device_manager_t *manager) fd, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, (ply_event_handler_t) - on_udev_event_loop, + on_udev_event, NULL, manager); } diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c index 1ef2802..4dbf8da 100644 --- a/src/plugins/renderers/drm/plugin.c +++ b/src/plugins/renderers/drm/plugin.c @@ -1333,6 +1333,34 @@ remove_output (ply_renderer_backend_t *backend, ply_output_t *output) ply_renderer_head_remove_connector (backend, head, output->connector_id); } +/* Check if an output has changed since we last enumerated it; and if + * it has changed remove it from the head it is part of. + */ +static bool +check_if_output_has_changed (ply_renderer_backend_t *backend, + ply_output_t *new_output) +{ + ply_output_t *old_output = NULL; + int i; + + for (i = 0; i < backend->outputs_len; i++) { + if (backend->outputs[i].connector_id == new_output->connector_id) { + old_output = &backend->outputs[i]; + break; + } + } + + if (!old_output || !old_output->controller_id) + return false; + + if (memcmp(old_output, new_output, sizeof(ply_output_t)) == 0) + return false; + + ply_trace ("Output for connector %u changed, removing", old_output->connector_id); + remove_output (backend, old_output); + return true; +} + /* Update our outputs array to match the hardware state and * create and/or remove heads as necessary. * Returns true if any heads were modified. @@ -1341,37 +1369,18 @@ static bool create_heads_for_active_connectors (ply_renderer_backend_t *backend, bool change) { int i, j, number_of_setup_outputs, outputs_len; - ply_output_t output, *outputs; + ply_output_t *outputs; bool changed = false; /* Step 1: - * Remove existing outputs from heads if they have changed. - */ - ply_trace ("Checking currently connected outputs for changes"); - for (i = 0; i < backend->outputs_len; i++) { - if (!backend->outputs[i].controller_id) - continue; - - get_output_info (backend, backend->outputs[i].connector_id, &output); - - if (memcmp(&backend->outputs[i], &output, sizeof(ply_output_t))) { - ply_trace ("Output for connector %u changed, removing", - backend->outputs[i].connector_id); - remove_output (backend, &backend->outputs[i]); - changed = true; - } - } - - /* Step 2: - * Now that we've removed changed connectors from the heads, we can - * simply rebuild the outputs array from scratch. For any unchanged - * outputs for which we already have a head, we will end up in - * ply_renderer_head_add_connector which will ignore the already - * added connector. + * Query all outputs and: + * 1.1 Remove currently connected outputs from their heads if changed. + * 1.2 Build a new outputs array from scratch. For any unchanged + * outputs for which we already have a head, we will end up in + * ply_renderer_head_add_connector which will ignore the already + * added connector. */ ply_trace ("(Re)enumerating all outputs"); - free (backend->outputs); - backend->outputs = NULL; outputs = calloc (backend->resources->count_connectors, sizeof(*outputs)); outputs_len = backend->resources->count_connectors; @@ -1379,10 +1388,21 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend, bool change backend->connected_count = 0; for (i = 0; i < outputs_len; i++) { get_output_info (backend, backend->resources->connectors[i], &outputs[i]); + + if (check_if_output_has_changed (backend, &outputs[i])) + changed = true; + if (outputs[i].connected) backend->connected_count++; } + /* Step 2: + * Free the old outputs array, now that we have checked for changes + * we no longer need it. + */ + free (backend->outputs); + backend->outputs = NULL; + /* Step 3: * Drop controllers for clones for which we've picked different modes. */