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

Commit 7216e9333e423fe6bf3a14396d31394e6e66f9be
Parent: 9c9e396f412c7a640613c68e8fb706c43bf11979
Author: mcol <mcol@posteo.net>
Date: 2020-11-05 23:00:36 +0000
Committer: mcol <mcol@posteo.net>
Committed: 2020-11-05 23:00:36 +0000

add basic rendering, based on tinywm

src/output.h Modified

@@ -12,6 +12,17 @@
 };
 
 
+struct render_data {
+    struct wlr_output *output;
+    struct wlr_renderer *renderer;
+    struct view *view;
+    struct timespec *when;
+};
+
+
+void render_surface(
+    struct wlr_surface *surface, int sx, int sy, void *data
+);
 void on_frame(struct wl_listener *listener, void *data);
 void on_new_output(struct wl_listener *listener, void *data);
 void set_up_outputs(struct server *server);

src/output.c Modified

@@ -1,22 +1,87 @@
+#include <time.h>
+#include <wlr/types/wlr_matrix.h>
 #include <wlr/types/wlr_output_layout.h>
 
 #include "output.h"
 #include "types.h"
 
 
+void render_surface(
+    struct wlr_surface *surface, int sx, int sy, void *data
+) {
+    struct render_data *rdata = data;
+    struct view *view = rdata->view;
+    struct wlr_output *output = rdata->output;
+
+    struct wlr_texture *texture = wlr_surface_get_texture(surface);
+    if (texture == NULL) {
+	return;
+    }
+
+    // get output-relative coordinates
+    double ox = 0, oy = 0;
+    wlr_output_layout_output_coords(
+	view->server->output_layout, output, &ox, &oy
+    );
+    ox += view->x + sx, oy += view->y + sy;
+
+    // scale for HiDPI
+    struct wlr_box box = {
+	.x = ox * output->scale,
+	.y = oy * output->scale,
+	.width = surface->current.width * output->scale,
+	.height = surface->current.height * output->scale,
+    };
+
+    // this is where any rendering magic might happen
+    float matrix[9];
+    enum wl_output_transform transform =
+	wlr_output_transform_invert(surface->current.transform);
+    wlr_matrix_project_box(matrix, &box, transform, 0,
+	output->transform_matrix);
+
+    wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1);
+    wlr_surface_send_frame_done(surface, rdata->when);
+}
+
+
 void on_frame(struct wl_listener *listener, void *data) {
-	struct output *output = wl_container_of(listener, output, frame_listener);
-	struct wlr_output *wlr_output = output->wlr_output;
+    struct output *output = wl_container_of(listener, output, frame_listener);
+    struct wlr_renderer *renderer = output->server->renderer;
+
+    struct timespec now;
+    clock_gettime(CLOCK_MONOTONIC, &now);
+
+    if (!wlr_output_attach_render(output->wlr_output, NULL)) {
+	return;
+    }
 
-	wlr_output_attach_render(wlr_output, NULL);
+    int width, height;
+    wlr_output_effective_resolution(output->wlr_output, &width, &height);
+    wlr_renderer_begin(renderer, width, height);
 
-	struct wlr_renderer *renderer =
-	    wlr_backend_get_renderer(wlr_output->backend);
+    float color[4] = {0.3, 0.05, 0.7, 1.0};  // background
+    wlr_renderer_clear(renderer, color);
+
+    struct view *view;
+    wl_list_for_each_reverse(view, &output->server->views, link) {
+	if (!view->is_mapped) {
+	    continue;
+	}
+	struct render_data rdata = {
+	    .output = output->wlr_output,
+	    .view = view,
+	    .renderer = renderer,
+	    .when = &now,
+	};
+	wlr_xdg_surface_for_each_surface(
+	    view->surface, render_surface, &rdata
+	);
+    }
 
-	wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
-	wlr_renderer_clear(renderer, (float[]){0, 0, 0, 1});
-	wlr_renderer_end(renderer);
-	wlr_output_commit(wlr_output);
+    wlr_output_render_software_cursors(output->wlr_output, NULL);  // no-op with HW cursors
+    wlr_renderer_end(renderer);
+    wlr_output_commit(output->wlr_output);
 }