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

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to