From b3a5effef2be30c21d5a5cd7e60c9134af4948eb Mon Sep 17 00:00:00 2001 From: Josef Gajdusek Date: Mon, 20 May 2019 23:47:05 +0200 Subject: Implement wlr-output-management-v1 --- sway/desktop/output.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) (limited to 'sway/desktop/output.c') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 1636a58b..dccb2432 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -578,6 +578,30 @@ static void update_textures(struct sway_container *con, void *data) { container_update_marks_textures(con); } +static void update_output_manager_config(struct sway_server *server) { + struct wlr_output_configuration_v1 *config = + wlr_output_configuration_v1_create(); + + struct sway_output *output; + wl_list_for_each(output, &root->all_outputs, link) { + if (output == root->noop_output) { + continue; + } + struct wlr_output_configuration_head_v1 *config_head = + wlr_output_configuration_head_v1_create(config, output->wlr_output); + struct wlr_box *output_box = wlr_output_layout_get_box( + root->output_layout, output->wlr_output); + // We mark the output enabled even if it is switched off by DPMS + config_head->state.enabled = output->enabled; + if (output_box) { + config_head->state.x = output_box->x; + config_head->state.y = output_box->y; + } + } + + wlr_output_manager_v1_set_configuration(server->output_manager_v1, config); +} + static void handle_scale(struct wl_listener *listener, void *data) { struct sway_output *output = wl_container_of(listener, output, scale); if (!output->enabled || !output->configured) { @@ -651,4 +675,73 @@ void handle_new_output(struct wl_listener *listener, void *data) { } transaction_commit_dirty(); + + update_output_manager_config(server); +} + +void handle_output_manager_apply(struct wl_listener *listener, void *data) { + struct sway_server *server = + wl_container_of(listener, server, output_manager_apply); + struct wlr_output_configuration_v1 *config = data; + + struct wlr_output_configuration_head_v1 *config_head; + // First disable outputs we need to disable + bool ok = true; + wl_list_for_each(config_head, &config->heads, link) { + struct wlr_output *wlr_output = config_head->state.output; + struct sway_output *output = wlr_output->data; + if (!output->enabled || config_head->state.enabled) { + continue; + } + struct output_config *oc = new_output_config(output->wlr_output->name); + oc->enabled = false; + + oc = store_output_config(oc); + ok &= apply_output_config(oc, output); + } + + // Then enable outputs that need to + wl_list_for_each(config_head, &config->heads, link) { + struct wlr_output *wlr_output = config_head->state.output; + struct sway_output *output = wlr_output->data; + if (!config_head->state.enabled) { + continue; + } + struct output_config *oc = new_output_config(output->wlr_output->name); + oc->enabled = true; + if (config_head->state.mode != NULL) { + struct wlr_output_mode *mode = config_head->state.mode; + oc->width = mode->width; + oc->height = mode->height; + oc->refresh_rate = mode->refresh; + } else { + oc->width = config_head->state.custom_mode.width; + oc->height = config_head->state.custom_mode.height; + oc->refresh_rate = config_head->state.custom_mode.refresh; + } + oc->x = config_head->state.x; + oc->y = config_head->state.y; + oc->transform = config_head->state.transform; + oc->scale = config_head->state.scale; + + oc = store_output_config(oc); + ok &= apply_output_config(oc, output); + } + + if (ok) { + wlr_output_configuration_v1_send_succeeded(config); + } else { + wlr_output_configuration_v1_send_failed(config); + } + wlr_output_configuration_v1_destroy(config); + + update_output_manager_config(server); +} + +void handle_output_manager_test(struct wl_listener *listener, void *data) { + struct wlr_output_configuration_v1 *config = data; + + // TODO: implement test-only mode + wlr_output_configuration_v1_send_succeeded(config); + wlr_output_configuration_v1_destroy(config); } -- cgit v1.2.3-54-g00ecf