gimp but for windows: a wayland compositor
git clone https://github.com/m-col/wimp
Files | Refs | Readme

Commit da7a19f94fd2bb82e51b67e3f32254f9d776f015
Parent: 9c760692e7c7c004aa1bddd2f1eeecc452ab8567
Author: mcol <mcol@posteo.net>
Date: 2021-02-07 17:56:34 +0000
Committer: mcol <mcol@posteo.net>
Committed: 2021-02-07 17:56:34 +0000

Add early stage output manager

src/types.h Modified

@@ -43,8 +43,12 @@
     char *auto_start;
 
     struct wlr_output_layout *output_layout;
+    struct wl_listener output_layout_change_listener;
     struct wl_list outputs;
     struct wl_listener new_output_listener;
+    struct wlr_output_manager_v1 *output_manager;
+    struct wl_listener output_manager_apply_listener;
+    struct wl_listener output_manager_test_listener;
 
     struct wlr_xdg_shell *shell;
     struct wl_listener new_xdg_surface_listener;

src/output.c Modified

@@ -3,6 +3,7 @@
 #include <wlr/types/wlr_layer_shell_v1.h>
 #include <wlr/types/wlr_matrix.h>
 #include <wlr/types/wlr_output_layout.h>
+#include <wlr/types/wlr_output_management_v1.h>
 #include <wlr/types/wlr_xdg_output_v1.h>
 
 #include "output.h"
@@ -258,12 +259,103 @@
 }
 
 
+static void output_manager_reconfigure(
+    struct wlr_output_configuration_v1 *config, bool commit
+) {
+    struct wlr_output_configuration_head_v1 *config_head;
+    bool ok = 1;
+
+    wl_list_for_each(config_head, &config->heads, link) {
+        struct wlr_output *wlr_output = config_head->state.output;
+
+        wlr_output_enable(wlr_output, config_head->state.enabled);
+        if (config_head->state.enabled) {
+            if (config_head->state.mode) {
+                wlr_output_set_mode(wlr_output, config_head->state.mode);
+	    } else {
+                wlr_output_set_custom_mode(
+		    wlr_output,
+		    config_head->state.custom_mode.width,
+		    config_head->state.custom_mode.height,
+		    config_head->state.custom_mode.refresh
+		);
+	    }
+
+            wlr_output_layout_move(
+		wimp.output_layout, wlr_output, config_head->state.x, config_head->state.y
+	    );
+            wlr_output_set_transform(wlr_output, config_head->state.transform);
+            wlr_output_set_scale(wlr_output, config_head->state.scale);
+        }
+
+        ok = wlr_output_test(wlr_output);
+        if (!ok) {
+            break;
+	}
+    }
+
+    wl_list_for_each(config_head, &config->heads, link) {
+        if (ok && commit) {
+            wlr_output_commit(config_head->state.output);
+	} else {
+            wlr_output_rollback(config_head->state.output);
+	}
+    }
+
+    if (ok) {
+        wlr_output_configuration_v1_send_succeeded(config);
+    } else {
+        wlr_output_configuration_v1_send_failed(config);
+    }
+    wlr_output_configuration_v1_destroy(config);
+}
+
+
+static void on_output_manager_apply(struct wl_listener *listener, void *data) {
+    output_manager_reconfigure(data, true);
+}
+
+
+static void on_output_manager_test(struct wl_listener *listener, void *data) {
+    output_manager_reconfigure(data, false);
+}
+
+
+static void on_output_layout_change(struct wl_listener *listener, void *data) {
+    struct wlr_output_configuration_v1 *config = wlr_output_configuration_v1_create();
+
+    struct output *output;
+    wl_list_for_each(output, &wimp.outputs, link) {
+	struct wlr_output_configuration_head_v1 *config_head =
+	    wlr_output_configuration_head_v1_create(config, output->wlr_output);
+
+	struct wlr_box *box = wlr_output_layout_get_box(wimp.output_layout, output->wlr_output);
+	config_head->state.x = box->x;
+	config_head->state.y = box->y;
+	config_head->state.enabled = output->wlr_output->enabled;
+	config_head->state.mode = output->wlr_output->current_mode;
+    }
+
+    wlr_output_manager_v1_set_configuration(wimp.output_manager, config);
+}
+
+
 void set_up_outputs() {
     wimp.output_layout = wlr_output_layout_create();
+    wimp.output_layout_change_listener.notify = on_output_layout_change;
+    wl_signal_add(&wimp.output_layout->events.change, &wimp.output_layout_change_listener);
+
     wl_list_init(&wimp.outputs);
     wimp.new_output_listener.notify = on_new_output;
     wl_signal_add(&wimp.backend->events.new_output, &wimp.new_output_listener);
 
     wlr_xdg_output_manager_v1_create(wimp.display, wimp.output_layout);
+
+    wimp.output_manager = wlr_output_manager_v1_create(wimp.display);
+    wimp.output_manager_apply_listener.notify = on_output_manager_apply;
+    wimp.output_manager_test_listener.notify = on_output_manager_test;
+    wl_signal_add(&wimp.output_manager->events.apply, &wimp.output_manager_apply_listener);
+    wl_signal_add(&wimp.output_manager->events.test, &wimp.output_manager_test_listener);
+
     wlr_gamma_control_manager_v1_create(wimp.display);
 }