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

Commit 721004d5550c40cc7d544d5889d1e9e740e9e843
Parent: 
Author: mcol <mcol@posteo.net>
Date: 2020-11-04 00:11:36 +0000
Committer: mcol <mcol@posteo.net>
Committed: 2020-11-04 00:11:36 +0000

Init with basic project skeleton

Compilable starting point with file structure and makefile.

src/output.h Added

@@ -0,0 +1,15 @@
+#pragma once
+#include <wlr/types/wlr_output_layout.h>
+
+#include "deskwm.h"
+
+
+struct output {
+    struct wl_list link;
+    struct server *server;
+    struct wlr_output *wlr_output;
+    struct wl_listener frame_listener;
+};
+
+
+void on_new_output(struct wl_listener *listener, void *data);

src/output.c Added

@@ -0,0 +1,26 @@
+#include <wlr/types/wlr_output_layout.h>
+
+#include "output.h"
+
+
+void on_new_output(struct wl_listener *listener, void *data) {
+    struct server *server = wl_container_of(listener, server, new_output_listener);
+    struct wlr_output *wlr_output = data;
+
+    if (!wl_list_empty(&wlr_output->modes)) {
+	struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
+	wlr_output_set_mode(wlr_output, mode);
+	wlr_output_enable(wlr_output, true);
+	if (!wlr_output_commit(wlr_output)) {
+	    return;
+	}
+    }
+
+    struct output *output = calloc(1, sizeof(struct output));
+    output->wlr_output = wlr_output;
+    output->server = server;
+    output->frame_listener.notify = on_frame;
+    wl_signal_add(&wlr_output->events.frame, &output->frame_listener);
+    wl_list_insert(&server->outputs, &output->link);
+    wlr_output_layout_add_auto(server->output_layout, wlr_output);
+}

src/deskwm.h Added

@@ -0,0 +1,49 @@
+#pragma once
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <wlr/backend.h>
+#include <wlr/render/wlr_renderer.h>
+#include <wlr/types/wlr_compositor.h>
+#include <wlr/types/wlr_output_layout.h>
+#include <wlr/types/wlr_xdg_shell.h>
+#include <wlr/util/log.h>
+
+
+struct server {
+    struct wl_display *display;
+    struct wlr_backend *backend;
+    struct wlr_renderer *renderer;
+
+    struct wlr_output_layout *output_layout;
+    struct wl_list outputs;
+    struct wl_listener new_output_listener;
+
+    struct wlr_xdg_shell *shell;
+    struct wl_listener new_xdg_surface_listener;
+    struct wl_list views;
+};
+
+
+struct view {
+    struct wl_list link;
+    struct server *server;
+    struct wlr_xdg_surface *surface;
+    struct wl_listener map;
+    struct wl_listener unmap;
+    struct wl_listener destroy;
+    struct wl_listener request_move;
+    struct wl_listener request_resize;
+    bool is_mapped;
+    int x, y;
+};
+
+
+void on_frame(struct wl_listener *listener, void *data);
+void on_new_output(struct wl_listener *listener, void *data);
+void on_map(struct wl_listener *listener, void *data);
+void on_unmap(struct wl_listener *listener, void *data);
+void on_surface_destroy(struct wl_listener *listener, void *data);
+void on_request_move(struct wl_listener *listener, void *data);
+void on_request_resize(struct wl_listener *listener, void *data);
+void on_new_xdg_surface(struct wl_listener *listener, void *data);

src/deskwm.c Added

@@ -0,0 +1,113 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <wlr/backend.h>
+#include <wlr/render/wlr_renderer.h>
+#include <wlr/types/wlr_compositor.h>
+#include <wlr/types/wlr_output_layout.h>
+#include <wlr/types/wlr_xdg_shell.h>
+#include <wlr/util/log.h>
+
+#include "deskwm.h"
+#include "output.h"
+
+
+void on_frame(struct wl_listener *listener, void *data) {
+    return;
+}
+
+
+void on_map(struct wl_listener *listener, void *data) {
+    return;
+}
+
+
+void on_unmap(struct wl_listener *listener, void *data) {
+    return;
+}
+
+
+void on_surface_destroy(struct wl_listener *listener, void *data) {
+    return;
+}
+
+
+void on_request_move(struct wl_listener *listener, void *data) {
+    return;
+}
+
+
+void on_request_resize(struct wl_listener *listener, void *data) {
+    return;
+}
+
+
+void on_new_xdg_surface(struct wl_listener *listener, void *data) {
+	struct server *server = wl_container_of(listener, server, new_xdg_surface_listener);
+	struct wlr_xdg_surface *surface = data;
+	if (surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
+		return;
+	}
+
+	struct view *view = calloc(1, sizeof(struct view));
+	view->server = server;
+	view->surface = surface;
+
+	view->map.notify = on_map;
+	wl_signal_add(&surface->events.map, &view->map);
+	view->unmap.notify = on_unmap;
+	wl_signal_add(&surface->events.unmap, &view->unmap);
+	view->destroy.notify = on_surface_destroy;
+	wl_signal_add(&surface->events.destroy, &view->destroy);
+
+	struct wlr_xdg_toplevel *toplevel = surface->toplevel;
+	view->request_move.notify = on_request_move;
+	wl_signal_add(&toplevel->events.request_move, &view->request_move);
+	view->request_resize.notify = on_request_resize;
+	wl_signal_add(&toplevel->events.request_resize, &view->request_resize);
+
+	wl_list_insert(&server->views, &view->link);
+}
+
+
+int main(int argc, char *argv[]) {
+    wlr_log_init(WLR_ERROR, NULL);
+
+    int opt;
+    while ((opt = getopt(argc, argv, "d")) != -1) {
+        switch (opt) {
+	    case 'd':
+		wlr_log_init(WLR_DEBUG, NULL);
+        }
+    }
+
+    // create compositor
+    struct server server;
+    server.display = wl_display_create();
+    server.backend = wlr_backend_autocreate(server.display, NULL);
+    server.renderer = wlr_backend_get_renderer(server.backend);
+    wlr_renderer_init_wl_display(server.renderer, server.display);
+    wlr_compositor_create(server.display, server.renderer);
+
+    // set up outputs
+    server.output_layout = wlr_output_layout_create();
+    wl_list_init(&server.outputs);
+    server.new_output_listener.notify = on_new_output;
+    wl_signal_add(&server.backend->events.new_output, &server.new_output_listener);
+
+    // set up shell
+    wl_list_init(&server.views);
+    server.shell = wlr_xdg_shell_create(server.display);
+    server.new_xdg_surface_listener.notify = on_new_xdg_surface;
+    wl_signal_add(&server.shell->events.new_surface, &server.new_xdg_surface_listener);
+
+
+
+
+    // begin session
+    wl_display_run(server.display);
+
+    // shutdown
+    wlr_backend_destroy(server.backend);
+    wl_display_destroy(server.display);
+    return 0;
+}

Makefile Added

@@ -0,0 +1,29 @@
+OUT	= deskwm
+SOURCES	= $(wildcard src/*.c)
+OBJECTS	= $(SOURCES:.c=.o)
+CFLAGS  += -g -I. -DWLR_USE_UNSTABLE
+#CFLAGS  += -g -I. -DWLR_USE_UNSTABLE -Wall -Wextra -pedantic
+LDFLAGS	+= $(shell pkg-config --cflags --libs wlroots) \
+	    $(shell pkg-config --cflags --libs wayland-server) \
+	    $(shell pkg-config --cflags --libs xkbcommon)
+
+${OUT}: xdg-shell-protocol.h xdg-shell-protocol.c ${OBJECTS}
+	@$(CC) -o ${OUT} $(OBJECTS) $(LDFLAGS)
+
+%.o: %.c %.h
+	@$(CC) $(CFLAGS) -c -o $@ $< ${LDFLAGS}
+
+WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
+WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner)
+
+xdg-shell-protocol.h:
+	@$(WAYLAND_SCANNER) server-header $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
+
+xdg-shell-protocol.c: xdg-shell-protocol.h
+	@$(WAYLAND_SCANNER) private-code $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
+
+clean:
+	rm -f ${OUT} xdg-shell-protocol.h xdg-shell-protocol.c ${OBJECTS}
+
+.DEFAULT_GOAL=${OUT}
+.PHONY: clean

.gitignore Added

@@ -0,0 +1,4 @@
+deskwm
+src/*.o
+*-protocol.c
+*-protocol.h