[PATCH weston 15/15] libweston: libweston-ify xwayland
Giulio Camuffo
giuliocamuffo at gmail.com
Thu Nov 6 12:41:34 PST 2014
This creates a new library, libweston-xwayland.so with the entry point
to easily spawn a xwayland server. The xwayland module now links to that
library.
---
Makefile.am | 40 ++++++++--
xwayland/launcher.c | 157 ++++++++------------------------------
xwayland/xwayland-module.c | 185 +++++++++++++++++++++++++++++++++++++++++++++
xwayland/xwayland.h | 26 ++++++-
4 files changed, 273 insertions(+), 135 deletions(-)
create mode 100644 xwayland/xwayland-module.c
diff --git a/Makefile.am b/Makefile.am
index dcc0488..ef0a892 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -175,7 +175,8 @@ westoninclude_HEADERS = \
src/weston-launcher.h \
shared/matrix.h \
shared/config-parser.h \
- shared/zalloc.h
+ shared/zalloc.h \
+ xwayland/xwayland.h
if ENABLE_EGL
module_LTLIBRARIES += gl-renderer.la
@@ -780,9 +781,9 @@ endif
if ENABLE_XWAYLAND
-module_LTLIBRARIES += xwayland.la
+lib_LTLIBRARIES += libweston-xwayland.la
-xwayland_la_CPPFLAGS = \
+libweston_xwayland_la_CPPFLAGS = \
-I$(top_builddir)/protocol \
-I$(top_srcdir)/shared \
-I$(top_srcdir)/src \
@@ -792,17 +793,16 @@ xwayland_la_CPPFLAGS = \
-DMODULEDIR='"$(moduledir)"' \
-DLIBEXECDIR='"$(libexecdir)"' \
-DXSERVER_PATH='"@XSERVER_PATH@"'
-
-xwayland_la_LDFLAGS = -module -avoid-version
-xwayland_la_LIBADD = \
+libweston_xwayland_la_LIBADD = \
$(XWAYLAND_LIBS) \
+ libweston.la \
$(top_builddir)/libshared-cairo.la
-xwayland_la_CFLAGS = \
+libweston_xwayland_la_CFLAGS = \
$(GCC_CFLAGS) \
$(COMPOSITOR_CFLAGS) \
$(PIXMAN_CFLAGS) \
$(CAIRO_CFLAGS)
-xwayland_la_SOURCES = \
+libweston_xwayland_la_SOURCES = \
xwayland/xwayland.h \
xwayland/window-manager.c \
xwayland/selection.c \
@@ -810,6 +810,30 @@ xwayland_la_SOURCES = \
xwayland/launcher.c \
xwayland/hash.c \
xwayland/hash.h
+
+module_LTLIBRARIES += xwayland.la
+
+xwayland_la_CPPFLAGS = \
+ -I$(top_builddir)/protocol \
+ -I$(top_srcdir)/shared \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ -I$(top_builddir)/xwayland \
+ -DDATADIR='"$(datadir)"' \
+ -DMODULEDIR='"$(moduledir)"' \
+ -DLIBEXECDIR='"$(libexecdir)"' \
+ -DXSERVER_PATH='"@XSERVER_PATH@"'
+
+xwayland_la_LDFLAGS = -module -avoid-version
+xwayland_la_LIBADD = \
+ libweston-xwayland.la
+xwayland_la_CFLAGS = \
+ $(GCC_CFLAGS) \
+ $(COMPOSITOR_CFLAGS) \
+ $(PIXMAN_CFLAGS) \
+ $(CAIRO_CFLAGS)
+xwayland_la_SOURCES = \
+ xwayland/xwayland-module.c
endif
diff --git a/xwayland/launcher.c b/xwayland/launcher.c
index 2a76ee3..54cff78 100644
--- a/xwayland/launcher.c
+++ b/xwayland/launcher.c
@@ -53,97 +53,17 @@ static int
weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
{
struct weston_xserver *wxs = data;
- char display[8], s[8], abstract_fd[8], unix_fd[8], wm_fd[8];
- int sv[2], wm[2], fd;
- char *xserver = NULL;
- struct weston_config_section *section;
-
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
- weston_log("wl connection socketpair failed\n");
- return 1;
- }
+ wxs->pid = wxs->spawn_xserver(wxs);
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wm) < 0) {
- weston_log("X wm connection socketpair failed\n");
- return 1;
+ if (wxs->pid == -1) {
+ weston_log( "failed to fork\n");
+ return -1;
}
- wxs->process.pid = fork();
- switch (wxs->process.pid) {
- case 0:
- /* SOCK_CLOEXEC closes both ends, so we need to unset
- * the flag on the client fd. */
- fd = dup(sv[1]);
- if (fd < 0)
- goto fail;
- snprintf(s, sizeof s, "%d", fd);
- setenv("WAYLAND_SOCKET", s, 1);
-
- snprintf(display, sizeof display, ":%d", wxs->display);
-
- fd = dup(wxs->abstract_fd);
- if (fd < 0)
- goto fail;
- snprintf(abstract_fd, sizeof abstract_fd, "%d", fd);
- fd = dup(wxs->unix_fd);
- if (fd < 0)
- goto fail;
- snprintf(unix_fd, sizeof unix_fd, "%d", fd);
- fd = dup(wm[1]);
- if (fd < 0)
- goto fail;
- snprintf(wm_fd, sizeof wm_fd, "%d", fd);
-
- section = weston_config_get_section(wxs->config,
- "xwayland", NULL, NULL);
- weston_config_section_get_string(section, "path",
- &xserver, XSERVER_PATH);
-
- /* Ignore SIGUSR1 in the child, which will make the X
- * server send SIGUSR1 to the parent (weston) when
- * it's done with initialization. During
- * initialization the X server will round trip and
- * block on the wayland compositor, so avoid making
- * blocking requests (like xcb_connect_to_fd) until
- * it's done with that. */
- signal(SIGUSR1, SIG_IGN);
-
- if (execl(xserver,
- xserver,
- display,
- "-rootless",
- "-listen", abstract_fd,
- "-listen", unix_fd,
- "-wm", wm_fd,
- "-terminate",
- NULL) < 0)
- weston_log("exec of '%s %s -rootless "
- "-listen %s -listen %s -wm %s "
- "-terminate' failed: %m\n",
- xserver, display,
- abstract_fd, unix_fd, wm_fd);
- fail:
- _exit(EXIT_FAILURE);
-
- default:
- weston_log("forked X server, pid %d\n", wxs->process.pid);
-
- close(sv[1]);
- wxs->client = wl_client_create(wxs->wl_display, sv[0]);
-
- close(wm[1]);
- wxs->wm_fd = wm[0];
-
- weston_watch_process(&wxs->process);
-
- wl_event_source_remove(wxs->abstract_source);
- wl_event_source_remove(wxs->unix_source);
- break;
+ weston_log("forked X server, pid %d\n", wxs->pid);
- case -1:
- weston_log( "failed to fork\n");
- break;
- }
+ wl_event_source_remove(wxs->abstract_source);
+ wl_event_source_remove(wxs->unix_source);
return 1;
}
@@ -157,7 +77,7 @@ weston_xserver_shutdown(struct weston_xserver *wxs)
unlink(path);
snprintf(path, sizeof path, "/tmp/.X11-unix/X%d", wxs->display);
unlink(path);
- if (wxs->process.pid == 0) {
+ if (wxs->pid == 0) {
wl_event_source_remove(wxs->abstract_source);
wl_event_source_remove(wxs->unix_source);
}
@@ -170,13 +90,10 @@ weston_xserver_shutdown(struct weston_xserver *wxs)
wxs->loop = NULL;
}
-static void
-weston_xserver_cleanup(struct weston_process *process, int status)
+WL_EXPORT void
+weston_xserver_exited(struct weston_xserver *wxs, int status)
{
- struct weston_xserver *wxs =
- container_of(process, struct weston_xserver, process);
-
- wxs->process.pid = 0;
+ wxs->pid = 0;
wxs->client = NULL;
wxs->resource = NULL;
@@ -329,41 +246,24 @@ create_lockfile(int display, char *lockfile, size_t lsize)
return 0;
}
-static void
-weston_xserver_destroy(struct wl_listener *l, void *data)
-{
- struct weston_xserver *wxs =
- container_of(l, struct weston_xserver, destroy_listener);
-
- if (!wxs)
- return;
-
- if (wxs->loop)
- weston_xserver_shutdown(wxs);
-
- free(wxs);
-}
-
-WL_EXPORT int
-module_init(struct weston_compositor *compositor,
- int *argc, char *argv[],
- struct weston_config *config)
-
+WL_EXPORT struct weston_xserver *
+weston_xserver_create(struct weston_compositor *c, const char *xserver)
{
- struct wl_display *display = compositor->wl_display;
+ struct wl_display *display = c->wl_display;
struct weston_xserver *wxs;
char lockfile[256], display_name[8];
wxs = zalloc(sizeof *wxs);
if (wxs == NULL)
- return -1;
- wxs->process.cleanup = weston_xserver_cleanup;
+ return NULL;
wxs->wl_display = display;
- wxs->compositor = compositor;
+ wxs->compositor = c;
+ wxs->spawn_xserver = NULL;
+ wxs->xserver_path = strdup(xserver);
wxs->display = 0;
- retry:
+retry:
if (create_lockfile(wxs->display, lockfile, sizeof lockfile) < 0) {
if (errno == EAGAIN) {
goto retry;
@@ -372,7 +272,7 @@ module_init(struct weston_compositor *compositor,
goto retry;
} else {
free(wxs);
- return -1;
+ return NULL;
}
}
@@ -388,14 +288,13 @@ module_init(struct weston_compositor *compositor,
unlink(lockfile);
close(wxs->abstract_fd);
free(wxs);
- return -1;
+ return NULL;
}
snprintf(display_name, sizeof display_name, ":%d", wxs->display);
weston_log("xserver listening on display %s\n", display_name);
setenv("DISPLAY", display_name, 1);
- wxs->config = config;
wxs->loop = wl_display_get_event_loop(display);
wxs->abstract_source =
wl_event_loop_add_fd(wxs->loop, wxs->abstract_fd,
@@ -408,8 +307,16 @@ module_init(struct weston_compositor *compositor,
wxs->sigusr1_source = wl_event_loop_add_signal(wxs->loop, SIGUSR1,
handle_sigusr1, wxs);
- wxs->destroy_listener.notify = weston_xserver_destroy;
- wl_signal_add(&compositor->destroy_signal, &wxs->destroy_listener);
- return 0;
+ return wxs;
+}
+
+WL_EXPORT void
+weston_xserver_destroy(struct weston_xserver *wxs)
+{
+ if (wxs->loop)
+ weston_xserver_shutdown(wxs);
+
+ free(wxs->xserver_path);
+ free(wxs);
}
diff --git a/xwayland/xwayland-module.c b/xwayland/xwayland-module.c
new file mode 100644
index 0000000..39bac87
--- /dev/null
+++ b/xwayland/xwayland-module.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include "xwayland.h"
+#include "compositor.h"
+
+struct xserver {
+ struct wl_listener destroy_listener;
+ struct weston_xserver *weston_xserver;
+ struct weston_process process;
+};
+
+static void
+xserver_destroy(struct wl_listener *l, void *data)
+{
+ struct xserver *xs =
+ container_of(l, struct xserver, destroy_listener);
+
+ if (!xs || !xs->weston_xserver)
+ return;
+
+ weston_xserver_destroy(xs->weston_xserver);
+ free(xs);
+}
+
+static pid_t
+xserver_spawn(struct weston_xserver *wxs)
+{
+ struct wl_listener *l = wl_signal_get(&wxs->compositor->destroy_signal,
+ xserver_destroy);
+ struct xserver *xs = container_of(l, struct xserver, destroy_listener);
+
+ pid_t pid;
+ char display[8], s[8], abstract_fd[8], unix_fd[8], wm_fd[8];
+ int sv[2], wm[2], fd;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
+ weston_log("wl connection socketpair failed\n");
+ return 1;
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wm) < 0) {
+ weston_log("X wm connection socketpair failed\n");
+ return 1;
+ }
+
+ pid = fork();
+ switch (pid) {
+ case 0:
+ /* SOCK_CLOEXEC closes both ends, so we need to unset
+ * the flag on the client fd. */
+ fd = dup(sv[1]);
+ if (fd < 0)
+ goto fail;
+ snprintf(s, sizeof s, "%d", fd);
+ setenv("WAYLAND_SOCKET", s, 1);
+
+ snprintf(display, sizeof display, ":%d", wxs->display);
+
+ fd = dup(wxs->abstract_fd);
+ if (fd < 0)
+ goto fail;
+ snprintf(abstract_fd, sizeof abstract_fd, "%d", fd);
+ fd = dup(wxs->unix_fd);
+ if (fd < 0)
+ goto fail;
+ snprintf(unix_fd, sizeof unix_fd, "%d", fd);
+ fd = dup(wm[1]);
+ if (fd < 0)
+ goto fail;
+ snprintf(wm_fd, sizeof wm_fd, "%d", fd);
+
+ /* Ignore SIGUSR1 in the child, which will make the X
+ * server send SIGUSR1 to the parent (weston) when
+ * it's done with initialization. During
+ * initialization the X server will round trip and
+ * block on the wayland compositor, so avoid making
+ * blocking requests (like xcb_connect_to_fd) until
+ * it's done with that. */
+ signal(SIGUSR1, SIG_IGN);
+
+ if (execl(wxs->xserver_path,
+ wxs->xserver_path,
+ display,
+ "-rootless",
+ "-listen", abstract_fd,
+ "-listen", unix_fd,
+ "-wm", wm_fd,
+ "-terminate",
+ NULL) < 0)
+ weston_log("exec of '%s %s -rootless "
+ "-listen %s -listen %s -wm %s "
+ "-terminate' failed: %m\n",
+ wxs->xserver_path, display,
+ abstract_fd, unix_fd, wm_fd);
+ fail:
+ _exit(EXIT_FAILURE);
+
+ default:
+ close(sv[1]);
+ wxs->client = wl_client_create(wxs->wl_display, sv[0]);
+
+ close(wm[1]);
+ wxs->wm_fd = wm[0];
+
+ xs->process.pid = pid;
+ weston_watch_process(&xs->process);
+ break;
+
+ case -1:
+ weston_log( "failed to fork\n");
+ break;
+ }
+
+ return pid;
+}
+
+static void
+xserver_cleanup(struct weston_process *process, int status)
+{
+ struct xserver *xs =
+ container_of(process, struct xserver, process);
+ weston_xserver_exited(xs->weston_xserver, status);
+}
+
+WL_EXPORT int
+module_init(struct weston_compositor *compositor,
+ int *argc, char *argv[], struct weston_config *config)
+
+{
+ struct xserver *xs;
+ struct weston_config_section *section;
+ char *xserver = NULL;
+
+ section = weston_config_get_section(config,
+ "xwayland", NULL, NULL);
+ weston_config_section_get_string(section, "path",
+ &xserver, XSERVER_PATH);
+
+ xs = zalloc(sizeof *xs);
+ if (!xs)
+ return -1;
+
+ xs->weston_xserver = weston_xserver_create(compositor, xserver);
+ if (!xs->weston_xserver)
+ return -1;
+
+ xs->process.cleanup = xserver_cleanup;
+ xs->weston_xserver->spawn_xserver = xserver_spawn;
+ xs->destroy_listener.notify = xserver_destroy;
+ wl_signal_add(&compositor->destroy_signal, &xs->destroy_listener);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/xwayland/xwayland.h b/xwayland/xwayland.h
index 161615f..4f3972a 100644
--- a/xwayland/xwayland.h
+++ b/xwayland/xwayland.h
@@ -20,6 +20,13 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifndef _WESTON_XWAYLAND_H_
+#define _WESTON_XWAYLAND_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <wayland-server.h>
#include <xcb/xcb.h>
#include <xcb/xfixes.h>
@@ -41,14 +48,16 @@ struct weston_xserver {
struct wl_event_source *unix_source;
int wm_fd;
int display;
+ char *xserver_path;
struct wl_event_source *sigusr1_source;
- struct weston_process process;
+ pid_t pid;
struct wl_resource *resource;
struct wl_client *client;
struct weston_compositor *compositor;
struct weston_wm *wm;
- struct weston_config *config;
struct wl_listener destroy_listener;
+
+ pid_t (*spawn_xserver)(struct weston_xserver *wxs);
};
struct weston_wm {
@@ -151,6 +160,13 @@ struct weston_wm {
} atom;
};
+struct weston_xserver *
+weston_xserver_create(struct weston_compositor *c, const char *xserver);
+void
+weston_xserver_destroy(struct weston_xserver *wxs);
+void
+weston_xserver_exited(struct weston_xserver *wxs, int status);
+
void
dump_property(struct weston_wm *wm, xcb_atom_t property,
xcb_get_property_reply_t *reply);
@@ -177,3 +193,9 @@ weston_wm_handle_dnd_event(struct weston_wm *wm,
xcb_generic_event_t *event);
void
weston_wm_dnd_init(struct weston_wm *wm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--
2.1.3
More information about the wayland-devel
mailing list