#include <string.h>
#include <unistd.h>
#include <linux/input.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
#include "wayland-server.h"
#include "compositor.h"
struct wl_listener panel_listener;
struct wlsc_surface *background;
struct wl_listener background_listener;
+
+ struct {
+ struct wlsc_process process;
+ struct wl_client *client;
+ } child;
};
struct wlsc_move_grab {
}
static void
+desktop_shell_sigchld(struct wlsc_process *process, int status)
+{
+ struct wl_shell *shell =
+ container_of(process, struct wl_shell, child.process);
+
+ shell->child.process.pid = 0;
+ shell->child.client = NULL; /* already destroyed by wayland */
+}
+
+static int
+launch_desktop_shell_process(struct wl_shell *shell)
+{
+ const char *shell_exe = "./clients/desktop-shell";
+ struct wlsc_compositor *compositor = shell->compositor;
+ char s[32];
+ int sv[2], flags;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
+ fprintf(stderr, "socketpair failed\n");
+ return -1;
+ }
+
+ shell->child.process.pid = fork();
+ shell->child.process.cleanup = desktop_shell_sigchld;
+
+ switch (shell->child.process.pid) {
+ case 0:
+ /* SOCK_CLOEXEC closes both ends, so we need to unset
+ * the flag on the client fd. */
+ flags = fcntl(sv[1], F_GETFD);
+ if (flags != -1)
+ fcntl(sv[1], F_SETFD, flags & ~FD_CLOEXEC);
+
+ snprintf(s, sizeof s, "%d", sv[1]);
+ setenv("WAYLAND_SOCKET", s, 1);
+ if (execl(shell_exe, shell_exe, NULL) < 0)
+ fprintf(stderr, "%s: running '%s' failed: %m\n",
+ __func__, shell_exe);
+ exit(-1);
+
+ default:
+ close(sv[1]);
+ shell->child.client =
+ wl_client_create(compositor->wl_display, sv[0]);
+ wlsc_watch_process(&shell->child.process);
+ break;
+
+ case -1:
+ fprintf(stderr, "%s: fork failed: %m\n", __func__);
+ return -1;
+ }
+ return 0;
+}
+
+static void
bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
{
struct wl_shell *shell = data;
shell, bind_desktop_shell) == NULL)
return -1;
+ if (launch_desktop_shell_process(shell) != 0)
+ return -1;
+
wlsc_compositor_add_binding(ec, 0, BTN_LEFT, MODIFIER_SUPER,
move_binding, shell);
wlsc_compositor_add_binding(ec, 0, BTN_MIDDLE, MODIFIER_SUPER,