#include <assert.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>
}
static void
+child_client_exec(int sockfd, const char *path)
+{
+ int flags;
+ char s[32];
+
+ /* SOCK_CLOEXEC closes both ends, so we need to unset
+ * the flag on the client fd. */
+ flags = fcntl(sockfd, F_GETFD);
+ if (flags != -1)
+ fcntl(sockfd, F_SETFD, flags & ~FD_CLOEXEC);
+
+ snprintf(s, sizeof s, "%d", sockfd);
+ setenv("WAYLAND_SOCKET", s, 1);
+
+ if (execl(path, path, NULL) < 0)
+ fprintf(stderr, "compositor: executing '%s' failed: %m\n",
+ path);
+}
+
+WL_EXPORT struct wl_client *
+wlsc_client_launch(struct wlsc_compositor *compositor,
+ struct wlsc_process *proc,
+ const char *path,
+ wlsc_process_cleanup_func_t cleanup)
+{
+ int sv[2];
+ pid_t pid;
+ struct wl_client *client;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
+ fprintf(stderr, "wlsc_client_launch: "
+ "socketpair failed while launching '%s': %m\n",
+ path);
+ return NULL;
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ close(sv[0]);
+ close(sv[1]);
+ fprintf(stderr, "wlsc_client_launch: "
+ "fork failed while launching '%s': %m\n", path);
+ return NULL;
+ }
+
+ if (pid == 0) {
+ child_client_exec(sv[1], path);
+ exit(-1);
+ }
+
+ close(sv[1]);
+
+ client = wl_client_create(compositor->wl_display, sv[0]);
+ if (!client) {
+ close(sv[0]);
+ fprintf(stderr, "wlsc_client_launch: "
+ "wl_client_create failed while launching '%s'.\n",
+ path);
+ return NULL;
+ }
+
+ proc->pid = pid;
+ proc->cleanup = cleanup;
+ wlsc_watch_process(proc);
+
+ return client;
+}
+
+static void
surface_handle_buffer_destroy(struct wl_listener *listener,
struct wl_resource *resource, uint32_t time)
{
wlsc_load_image(const char *filename,
int32_t *width_arg, int32_t *height_arg, uint32_t *stride_arg);
+struct wlsc_process;
+typedef void (*wlsc_process_cleanup_func_t)(struct wlsc_process *process,
+ int status);
+
struct wlsc_process {
pid_t pid;
- void (*cleanup)(struct wlsc_process *process, int status);
+ wlsc_process_cleanup_func_t cleanup;
struct wl_list link;
};
+struct wl_client *
+wlsc_client_launch(struct wlsc_compositor *compositor,
+ struct wlsc_process *proc,
+ const char *path,
+ wlsc_process_cleanup_func_t cleanup);
+
int
wlsc_data_device_manager_init(struct wlsc_compositor *compositor);
void
#include <string.h>
#include <unistd.h>
#include <linux/input.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <fcntl.h>
#include <assert.h>
#include <wayland-server.h>
launch_desktop_shell_process(struct wl_shell *shell)
{
const char *shell_exe = LIBEXECDIR "/wayland-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);
+ shell->child.client = wlsc_client_launch(shell->compositor,
+ &shell->child.process,
+ shell_exe,
+ desktop_shell_sigchld);
- 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__);
+ if (!shell->child.client)
return -1;
- }
return 0;
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <fcntl.h>
#include <linux/input.h>
#include "compositor.h"
launch_ux_daemon(struct tablet_shell *shell)
{
const char *shell_exe = LIBEXECDIR "/wayland-tablet-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;
- }
-
- shell->process.pid = fork();
- shell->process.cleanup = tablet_shell_sigchld;
-
- switch (shell->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, "exec failed: %m\n");
- exit(-1);
-
- default:
- close(sv[1]);
- shell->client =
- wl_client_create(compositor->wl_display, sv[0]);
- wlsc_watch_process(&shell->process);
- break;
-
- case -1:
- fprintf(stderr, "failed to fork\n");
- break;
- }
+ shell->client = wlsc_client_launch(shell->compositor,
+ &shell->process,
+ shell_exe, tablet_shell_sigchld);
}
static void