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

Commit 633817107890cb3ad744e06cd3d687d7b5dc5e40
Parent: edef67e308b9c5d968c60c80458f65900d0ec5a0
Author: mcol <mcol@posteo.net>
Date: 2021-02-15 00:05:28 +0000
Committer: mcol <mcol@posteo.net>
Committed: 2021-02-15 00:05:28 +0000

add server-side IPC handler

src/main.c Modified

@@ -13,6 +13,7 @@
 #include "desk.h"
 #include "main.h"
 #include "input.h"
+#include "ipc.h"
 #include "layer_shell.h"
 #include "log.h"
 #include "output.h"
@@ -148,6 +149,12 @@
     wlr_renderer_init_wl_display(wimp.renderer, wimp.display);
     wlr_compositor_create(wimp.display, wimp.renderer);
 
+    const char *socket = wl_display_add_socket_auto(wimp.display);
+    if (!socket) {
+	wlr_log(WLR_INFO, "Could not create socket: %s.", socket);
+	return EXIT_FAILURE;
+    }
+
     // initialise
     wl_list_init(&wimp.desks);
     wl_list_init(&wimp.key_bindings);
@@ -166,19 +173,19 @@
     set_up_layer_shell();
 
     // start
-    const char *socket = wl_display_add_socket_auto(wimp.display);
-    if (!socket || !wlr_backend_start(wimp.backend)) {
+    if (!start_ipc(socket) || !wlr_backend_start(wimp.backend)) {
 	shutdown();
 	return EXIT_FAILURE;
     }
     setenv("WAYLAND_DISPLAY", socket, true);
-    wlr_log(WLR_INFO, "Starting with WAYLAND_DISPLAY=%s", socket);
     schedule_auto_start();
     centre_cursor();
+    wlr_log(WLR_INFO, "Starting with WAYLAND_DISPLAY=%s.", socket);
     wl_display_run(wimp.display);
 
     // stop
     wl_display_destroy_clients(wimp.display);
+    close_ipc(socket);
     shutdown();
     return EXIT_SUCCESS;
 }

src/ipc.h Added

@@ -0,0 +1,9 @@
+#ifndef WIMP_IPC_H
+#define WIMP_IPC_H
+
+#include "types.h"
+
+void close_ipc(const char *display);
+bool start_ipc(const char *display);
+
+#endif

src/ipc.c Added

@@ -0,0 +1,64 @@
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "config.h"
+#include "ipc.h"
+
+#define SOCKET_PATH "/tmp/wimpy-sock-%s"
+
+
+void close_ipc(const char *display) {
+    char path[1024];
+    snprintf(path, sizeof(path), SOCKET_PATH, display);
+    unlink(path);
+}
+
+
+static int dispatch(int sock, unsigned int mask, void *data) {
+    char buffer[1024];
+
+    if (mask & WL_EVENT_READABLE) {
+	int fd = accept(sock, NULL, NULL);
+	if (fd == -1) {
+	    wlr_log(WLR_ERROR, "Failed accept connection from client.");
+	    return 0;
+	}
+	ssize_t len = recv(fd, buffer, sizeof(buffer) - 1, 0);
+	if (len > 0) {
+	    buffer[len] = '\0';
+	    parse_message(buffer, len);
+	}
+	close(fd);
+    }
+
+    return 0;
+}
+
+
+bool start_ipc(const char *display) {
+    int sock;
+    if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+	wlr_log(WLR_ERROR, "Failed to create IPC socket.");
+	return false;
+    }
+
+    struct sockaddr_un addr;
+    snprintf(addr.sun_path, sizeof(addr.sun_path), SOCKET_PATH, display);
+    addr.sun_family = AF_UNIX;
+
+    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
+	wlr_log(WLR_ERROR, "Failed to bind IPC socket.");
+	return false;
+    }
+
+    if (listen(sock, SOMAXCONN) == -1) {
+	wlr_log(WLR_ERROR, "Failed to listen on IPC socket.");
+	return false;
+    }
+
+    struct wl_event_loop *event_loop = wl_display_get_event_loop(wimp.display);
+    wl_event_loop_add_fd(event_loop, sock, WL_EVENT_READABLE, &dispatch, NULL);
+
+    return true;
+}

src/config.h Modified

@@ -5,6 +5,7 @@
 
 void assign_colour(char *hex, float dest[4]);
 void schedule_auto_start();
+void parse_message(char *buffer, ssize_t len);
 void load_config();
 void locate_config();
 

src/config.c Modified

@@ -526,6 +526,11 @@
 }
 
 
+void parse_message(char *buffer, ssize_t len) {
+    printf("msg: %s\n", buffer);
+}
+
+
 static void parse_config(FILE *stream) {
     char *s;
     char linebuf[1024];