diff options
-rw-r--r-- | include/sway/output.h | 4 | ||||
-rw-r--r-- | include/sway/server.h | 5 | ||||
-rw-r--r-- | sway/desktop/output.c | 93 | ||||
-rw-r--r-- | sway/server.c | 9 |
4 files changed, 111 insertions, 0 deletions
diff --git a/include/sway/output.h b/include/sway/output.h index d4438c0e..3d430ea2 100644 --- a/include/sway/output.h +++ b/include/sway/output.h | |||
@@ -154,4 +154,8 @@ void scale_box(struct wlr_box *box, float scale); | |||
154 | 154 | ||
155 | enum wlr_direction opposite_direction(enum wlr_direction d); | 155 | enum wlr_direction opposite_direction(enum wlr_direction d); |
156 | 156 | ||
157 | void handle_output_manager_apply(struct wl_listener *listener, void *data); | ||
158 | |||
159 | void handle_output_manager_test(struct wl_listener *listener, void *data); | ||
160 | |||
157 | #endif | 161 | #endif |
diff --git a/include/sway/server.h b/include/sway/server.h index 39cf4f18..fd613bb6 100644 --- a/include/sway/server.h +++ b/include/sway/server.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <wlr/types/wlr_compositor.h> | 8 | #include <wlr/types/wlr_compositor.h> |
9 | #include <wlr/types/wlr_data_device.h> | 9 | #include <wlr/types/wlr_data_device.h> |
10 | #include <wlr/types/wlr_layer_shell_v1.h> | 10 | #include <wlr/types/wlr_layer_shell_v1.h> |
11 | #include <wlr/types/wlr_output_management_v1.h> | ||
11 | #include <wlr/types/wlr_presentation_time.h> | 12 | #include <wlr/types/wlr_presentation_time.h> |
12 | #include <wlr/types/wlr_relative_pointer_v1.h> | 13 | #include <wlr/types/wlr_relative_pointer_v1.h> |
13 | #include <wlr/types/wlr_server_decoration.h> | 14 | #include <wlr/types/wlr_server_decoration.h> |
@@ -67,6 +68,10 @@ struct sway_server { | |||
67 | struct wlr_pointer_constraints_v1 *pointer_constraints; | 68 | struct wlr_pointer_constraints_v1 *pointer_constraints; |
68 | struct wl_listener pointer_constraint; | 69 | struct wl_listener pointer_constraint; |
69 | 70 | ||
71 | struct wlr_output_manager_v1 *output_manager_v1; | ||
72 | struct wl_listener output_manager_apply; | ||
73 | struct wl_listener output_manager_test; | ||
74 | |||
70 | size_t txn_timeout_ms; | 75 | size_t txn_timeout_ms; |
71 | list_t *transactions; | 76 | list_t *transactions; |
72 | list_t *dirty_nodes; | 77 | list_t *dirty_nodes; |
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) { | |||
578 | container_update_marks_textures(con); | 578 | container_update_marks_textures(con); |
579 | } | 579 | } |
580 | 580 | ||
581 | static void update_output_manager_config(struct sway_server *server) { | ||
582 | struct wlr_output_configuration_v1 *config = | ||
583 | wlr_output_configuration_v1_create(); | ||
584 | |||
585 | struct sway_output *output; | ||
586 | wl_list_for_each(output, &root->all_outputs, link) { | ||
587 | if (output == root->noop_output) { | ||
588 | continue; | ||
589 | } | ||
590 | struct wlr_output_configuration_head_v1 *config_head = | ||
591 | wlr_output_configuration_head_v1_create(config, output->wlr_output); | ||
592 | struct wlr_box *output_box = wlr_output_layout_get_box( | ||
593 | root->output_layout, output->wlr_output); | ||
594 | // We mark the output enabled even if it is switched off by DPMS | ||
595 | config_head->state.enabled = output->enabled; | ||
596 | if (output_box) { | ||
597 | config_head->state.x = output_box->x; | ||
598 | config_head->state.y = output_box->y; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | wlr_output_manager_v1_set_configuration(server->output_manager_v1, config); | ||
603 | } | ||
604 | |||
581 | static void handle_scale(struct wl_listener *listener, void *data) { | 605 | static void handle_scale(struct wl_listener *listener, void *data) { |
582 | struct sway_output *output = wl_container_of(listener, output, scale); | 606 | struct sway_output *output = wl_container_of(listener, output, scale); |
583 | if (!output->enabled || !output->configured) { | 607 | if (!output->enabled || !output->configured) { |
@@ -651,4 +675,73 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
651 | } | 675 | } |
652 | 676 | ||
653 | transaction_commit_dirty(); | 677 | transaction_commit_dirty(); |
678 | |||
679 | update_output_manager_config(server); | ||
680 | } | ||
681 | |||
682 | void handle_output_manager_apply(struct wl_listener *listener, void *data) { | ||
683 | struct sway_server *server = | ||
684 | wl_container_of(listener, server, output_manager_apply); | ||
685 | struct wlr_output_configuration_v1 *config = data; | ||
686 | |||
687 | struct wlr_output_configuration_head_v1 *config_head; | ||
688 | // First disable outputs we need to disable | ||
689 | bool ok = true; | ||
690 | wl_list_for_each(config_head, &config->heads, link) { | ||
691 | struct wlr_output *wlr_output = config_head->state.output; | ||
692 | struct sway_output *output = wlr_output->data; | ||
693 | if (!output->enabled || config_head->state.enabled) { | ||
694 | continue; | ||
695 | } | ||
696 | struct output_config *oc = new_output_config(output->wlr_output->name); | ||
697 | oc->enabled = false; | ||
698 | |||
699 | oc = store_output_config(oc); | ||
700 | ok &= apply_output_config(oc, output); | ||
701 | } | ||
702 | |||
703 | // Then enable outputs that need to | ||
704 | wl_list_for_each(config_head, &config->heads, link) { | ||
705 | struct wlr_output *wlr_output = config_head->state.output; | ||
706 | struct sway_output *output = wlr_output->data; | ||
707 | if (!config_head->state.enabled) { | ||
708 | continue; | ||
709 | } | ||
710 | struct output_config *oc = new_output_config(output->wlr_output->name); | ||
711 | oc->enabled = true; | ||
712 | if (config_head->state.mode != NULL) { | ||
713 | struct wlr_output_mode *mode = config_head->state.mode; | ||
714 | oc->width = mode->width; | ||
715 | oc->height = mode->height; | ||
716 | oc->refresh_rate = mode->refresh; | ||
717 | } else { | ||
718 | oc->width = config_head->state.custom_mode.width; | ||
719 | oc->height = config_head->state.custom_mode.height; | ||
720 | oc->refresh_rate = config_head->state.custom_mode.refresh; | ||
721 | } | ||
722 | oc->x = config_head->state.x; | ||
723 | oc->y = config_head->state.y; | ||
724 | oc->transform = config_head->state.transform; | ||
725 | oc->scale = config_head->state.scale; | ||
726 | |||
727 | oc = store_output_config(oc); | ||
728 | ok &= apply_output_config(oc, output); | ||
729 | } | ||
730 | |||
731 | if (ok) { | ||
732 | wlr_output_configuration_v1_send_succeeded(config); | ||
733 | } else { | ||
734 | wlr_output_configuration_v1_send_failed(config); | ||
735 | } | ||
736 | wlr_output_configuration_v1_destroy(config); | ||
737 | |||
738 | update_output_manager_config(server); | ||
739 | } | ||
740 | |||
741 | void handle_output_manager_test(struct wl_listener *listener, void *data) { | ||
742 | struct wlr_output_configuration_v1 *config = data; | ||
743 | |||
744 | // TODO: implement test-only mode | ||
745 | wlr_output_configuration_v1_send_succeeded(config); | ||
746 | wlr_output_configuration_v1_destroy(config); | ||
654 | } | 747 | } |
diff --git a/sway/server.c b/sway/server.c index b24cc1dc..e5200d59 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -120,6 +120,15 @@ bool server_init(struct sway_server *server) { | |||
120 | server->presentation = | 120 | server->presentation = |
121 | wlr_presentation_create(server->wl_display, server->backend); | 121 | wlr_presentation_create(server->wl_display, server->backend); |
122 | 122 | ||
123 | server->output_manager_v1 = | ||
124 | wlr_output_manager_v1_create(server->wl_display); | ||
125 | server->output_manager_apply.notify = handle_output_manager_apply; | ||
126 | wl_signal_add(&server->output_manager_v1->events.apply, | ||
127 | &server->output_manager_apply); | ||
128 | server->output_manager_test.notify = handle_output_manager_test; | ||
129 | wl_signal_add(&server->output_manager_v1->events.test, | ||
130 | &server->output_manager_test); | ||
131 | |||
123 | wlr_export_dmabuf_manager_v1_create(server->wl_display); | 132 | wlr_export_dmabuf_manager_v1_create(server->wl_display); |
124 | wlr_screencopy_manager_v1_create(server->wl_display); | 133 | wlr_screencopy_manager_v1_create(server->wl_display); |
125 | wlr_data_control_manager_v1_create(server->wl_display); | 134 | wlr_data_control_manager_v1_create(server->wl_display); |